操作符详解(C 语言)
目录
- 一、操作符的分类
- 二、算数操作符
- 1. 除法操作符
- 2. 取余操作符
- 三、位移操作符
- 1. 进制
- 2. 原码、反码和补码
- 3. 左移操作符(<<)和右移操作符(>>)
- 四、位操作符
- 1. 按位与 &
- 2. 按位或 |
- 3. 按位异或 ^
- 4. 按位取反 ~
- 五、单目操作符
- 1. 逻辑非(!)
- 2. 自增操作符(++)
- 3. 自减操作符(--)
- 4. 取地址操作符(&)
- 5. 解引用操作符(\*)
- 6. 正号(+)和负号(-)
- 7. sizeof 操作符
- 8. 强制类型转换操作符——(类型)
- 六、逗号表达式
- 七、下标引用操作符([])和函数调用操作符(())
- 八、结构成员访问操作符(.)
- 1. 结构体简介
- 2. 使用结构体成员访问操作符对结构体变量进行访问
- 九、操作符的优先级和结合性
- 十、表达式求值
- 1. 整型提升
- 2. 算数转换
- 3. 问题表达式解析
一、操作符的分类
• 算术操作符: + 、- 、* 、/ 、%
• 移位操作符: << 、>>
• 位操作符: & 、| 、^
• 赋值操作符:= 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
• 单⽬操作符: !、++、–、&、*、+、-、~ 、sizeof、(类型)
• 关系操作符: > 、>= 、< 、<= 、 == 、 !=
• 逻辑操作符: && 、||
• 条件操作符: ? :
• 逗号表达式: ,
• 下标引⽤: []
• 函数调⽤: ()
以上操作符有些初始 C 语言的时候已经介绍过了,这次复习一下。
二、算数操作符
加法、减法和乘法操作符就不过多叙述,这里主要介绍除法和取余操作符。
1. 除法操作符
当两个操作对象有一个是浮点数时,执行浮点数的除法,也就是带小数的。当两个操作对象都是整数时,结果为商舍弃余数。如:5 / 3 = 1,余数 2 舍弃;而 5.0 / 3 = 1.6666。如下代码:
2. 取余操作符
首先,取余操作符的两个操作对象必须为整数,然后其运算结果为第一个操作对象除以第二个操作对象的余数。如:5 % 3 = 2,本来是商 1 余 2,这里只取余数。如下代码:
三、位移操作符
位移操作符是作用于整数的二进制位数的。在对操作符进行说明之前,需要补充一下进制和原码、反码、补码的相关知识。
1. 进制
我们日常生活中使用的数都是采用十进制,如:10、20、99等。但是在计算机中,数据都是采用二进制进行存储的。其实不同的进制之间除了表达方式不同,其实质并没有差异。如:二进制 1111 和十进制 15,都表示数值 15,就是表达形式不同。
(1)其他进制转十进制
其他进制转 10 进制,只要每位乘以相应的权重即可,如:二进制 1111 转十进制
(2)十进制转其他进制
除以相应进制数取余,然后逆序输出。如:十进制 15 转二进制,
15 / 2 商 7 余 1
7 / 2 商 3 余 1
3 / 2 商 1 余 1
1 / 2 商 0 余1
然后倒着输出余数,就是二进制 1111。如下是一个函数,接受一个整数输出其二进制数:
// 输出整数的二进制
// 采用递归的方法
void binary(int n)
{if (n > 0){int remain = n % 2;binary(n / 2);printf("%d", remain);}
}
采用尾递归的方法更加方便逆序输出。
2. 原码、反码和补码
计算机中数据的存储都是采用二进制的形式,而二进制又分为原码,反码和补码。而正整数的这三种形式相同,如:int a = 10
原码:00000000000000000000000000001010
反码:00000000000000000000000000001010
补码:00000000000000000000000000001010
而负整数的反码和补码需要计算,反码是原码符号位不变,其余位取反;而补码是反码加 1,如:int b = -10;
原码:10000000000000000000000000001010
反码:111111111111111111111111111111110101
补码:111111111111111111111111111111110110
从上述 10 和 -10 的原码,不难得出最高位为符号位,且 1 表示负数,0 表示非负数。当然这是有符号整数,无符号整数的最高位仍参与计算,因为无符号整数没有负数。现在的 int 类型大多为 32 位,所需上述使用的是 32 为二进制数。
3. 左移操作符(<<)和右移操作符(>>)
顾名思义,左移操作符把被操作对象的二进制数左移,右移操作符把被操作对象的二进制数右移。且左移和右移操作符均针对整数的二进制补码进行操作。
(1)左移操作符(<<)
表达式 5<<1 的意思是把整数 5 的二进制数左移一位,如下:
左边超出的位数去掉,右边缺少的位数补 0,则左移一位后的结果为:
00000000000000000000000000001010
结果为十进制的 10,相当于原来的两倍。其实也很好理解,如:十进制 10 向左移动一位结果为 100,是原来的 10 倍。所以得出结论,当该正整数左移 n 位结果不超过该类型的范围时,其结果为原来的 2 的 n 次方倍。
左移负整数时,移动的是该负整数的补码,但是所得结果是该负整数的原码,这时就要进行计算。如:-5<<1
原码:10000000000000000000000000000101
反码:111111111111111111111111111111111010
补码:111111111111111111111111111111111011
左移一位:11111111111111111111111111110110
上述左移一位的结果仍是补码,这里要通过补码计算出原码,有两种方法:
(1)补码取反加 1
(2)补码减 1 取反
得出结果的原码:10000000000000000000000000001010,也就是 10 进制的 -10。
结论:当一个正整数左移 n 位时,其结果若不超出该类型的范围,那么结果是原数的 2 的 n 次方倍。但是对于负整数来说不一定。
(2)右移操作符(>>)
右移操作符和左移操作符类似,但是右移操作符分为:算数右移和逻辑右移。算数右移右边丢弃,左边补符号位;而逻辑右移左边补 0。但是大多情况下编译器使用的都是算数右移。
如:5>>1
补码:00000000000000000000000000000101
右移:00000000000000000000000000000010
结果:2
如:-5>>1
原码:10000000000000000000000000000101
反码:111111111111111111111111111111111010
补码:111111111111111111111111111111111011
右移:111111111111111111111111111111111101
原码:10000000000000000000000000000011
结果:-3
结论:对于正整数来说,右移 n 位,相当于除以 2 的 n 次方(取整数部分)。对于负整数来说不一定。
四、位操作符
位操作符有:
(1)按位与 &
(2)按位或 |
(3)按位异或 ^
(4)按位取反 ~
它们也是作用于整数的二进制数。
1. 按位与 &
如表达式 5 & 8 就是把两个数的 32 为二进制展开,一一对应,对应位均为 1 则为 1,否则为 0。如:
8:00000000000000000000000000001000
5:00000000000000000000000000000101
00000000000000000000000000000000
结果为 0。
2. 按位或 |
和按位与类似,但是对应位上只要有 1 则为 1,否则为 0。如: 5 | 8
8:00000000000000000000000000001000
5:00000000000000000000000000000101
00000000000000000000000000001101
结果为 13。
3. 按位异或 ^
按位异或是对应位上相同为 0,相异为 1。如:5 ^ 8
8:00000000000000000000000000001000
5:00000000000000000000000000000101
00000000000000000000000000001101
结果为 13。
4. 按位取反 ~
按位取反是把操作数的每一个二进制数都取反,包括符号位。如:~5
补码:00000000000000000000000000000101
取反:11111111111111111111111111111010
去反后得到的是补码,计算结果需要原码,所以进行计算:
原码:10000000000000000000000000000110,结果为 -6
五、单目操作符
单⽬操作符有这些:
!、++、–、&、*、+、-、~ 、sizeof、(类型)
1. 逻辑非(!)
把操作对象的逻辑取反,真变假,假变真。如:
2. 自增操作符(++)
自增操作符分为前置和后置。前置自增操作符先对操作数加 1,再使用。而后置自增操作符先使用操作数,然后再对操作数假 1。如:
前置:
int a = 5;
int b = ++a;
相当于
int a = 5;
a = a + 1;
int b = a;
后置:
int a = 5;
int b = a++;
相当于
int a = 5;
int b = a;
a = a + 1;
3. 自减操作符(–)
和自增操作符类似。前置自减操作符先对操作数减 1,然后使用。后置自减操作符,先使用操作数,然后再让操作数加 1。
4. 取地址操作符(&)
取出操作对象的地址,使用格式 %p 进行输出。如:
当然也可以使用指针变量。
5. 解引用操作符(*)
解引用操作符作用于指针变量,对该指针进行解引用找到其指向的对象。被解引用的指针必须是有效的,否则可能导致程序崩溃。
6. 正号(+)和负号(-)
正号几乎不使用,没啥用。符号就是把操作数取负,正数变负数,负数变正数。
7. sizeof 操作符
sizeof 操作符计算操作对象的大小,单位字节。当计算对象是类型时,必须加括号,当计算类型是一个变量时,括号可加可不加。如下:
对变量和对该变量的类型使用 sizeof 操作符的结果是一样的。
8. 强制类型转换操作符——(类型)
强制类型转换操作符把操作对象强制转换为需要的类型,如:int a = (int)3.14,该表达式把 double 值 3.14 强制类型转换为 int 值。在编写程序的过程中应该尽量不要使用强制类型转换。
六、逗号表达式
逗号表达式是用逗号隔开的多个表达式:
expr1, expr2, expr3, …, exprn
逗号表达式从左向右求值依次对每个表达式进行求值,但逗号表达式的最终结果为最右边表达式的值。如下代码:
int a = 2, b = 3;
int c = (a++, ++b);
由于赋值运算符的优先级要高于逗号表达式,所以在使用时需要加上括号。先计算a++,a 的值为 3,然后计算++b,b 的值为 4,所以逗号表达式的值为 4,赋值给 c。
七、下标引用操作符([])和函数调用操作符(())
下标引用操作符主要是给数组使用的,其有两个操作对象 —— 数组名和下标。作用为:获取该数组的该下标处的元素。
函数调用操作的操作对象至少有一个,即函数名和任意参数。其作用为调用该函数。
八、结构成员访问操作符(.)
1. 结构体简介
结构体是一种自定义类型,它可以包含多种不同类型。比如我们想要记录一个学生的信息:姓名、性别、年龄。就可以声明如下结构类型:
// 学生结构体声明
struct Stu {char name[20]; // 姓名char sex[5]; // 性别int age; // 年龄
};
上述代码只是一个类型的声明,就是告诉编译器有这么一个类型,它里面包含什么信息。然后我们就可以像创建 int 变量一样创建该类型的变量。
// 创建 stuct Stu 变量并初始化
struct Stu Lihua = { "李华", "男", 18 };
前面的 struct 不能省略。如果声明放在一个函数中,那么该结构体就是局部结构体,只能在该函数中创建该结构体变量。如果在所有函数之外声明该结构体,那么该结构体就是全局结构体,可以在全局创建该结构体变量。
2. 使用结构体成员访问操作符对结构体变量进行访问
我们可以直接使用成员访问运算符来访问上述创建的 Lihua 变量的每个成员,如:
Lihua.name
Lihua.sex
Lihua.age
使用它们就和使用原来的类型一样,下面使用 printf() 函数显示其信息:
也可以定义一个打印函数,这样每次需要打印信息的时候调用一下该函数就好了,参数传递有两种形式,值传递和址传递。如下:
// 打印结构体 struct Stu
void PrintStu1(struct Stu s); // 值传递
void PrintStu2(struct Stu* ps); // 址传递
值传递:被调函数中的形参是主调函数中实参的副本(也就是重新创建了一个结构体变量,把实参的值拷贝过来了而已)。其缺点是,当结构体所占空间较大时,会造成时间和空间的损失;优点是不会修改实参。
址传递:把结构体的地址传递给了被调函数,被调函数通过该指针使用指向结构体成员运算符(->)来对主调函数的实参进行访问。这样只传递了一个指针,大大提高了运行效率。缺点是:可以修改实参(可以加上 const 防止被修改)。
下面是两个函数的函数定义:
// 打印结构体 struct Stu
void PrintStu1(struct Stu s) // 值传递
{printf("姓名:%s\n", s.name);printf("性别:%s\n", s.sex);printf("年龄:%d\n", s.age);
}void PrintStu2(struct Stu* ps) // 址传递
{printf("姓名:%s\n", ps->name);printf("性别:%s\n", ps->sex);printf("年龄:%d\n", ps->age);
}
九、操作符的优先级和结合性
众所周知先乘除后加减,这是因为乘除的优先级比加减高,所以在同一个表达式中出现不同的操作符时,根据优先级进行先后计算。但是当优先级相同时,就需要根据操作符的结合型进行计算。如:3+4*5+10+6
上述表达式先计算 4*5,因为乘法的优先级高于加法,然后计算 3 + 4*5,因为加法操作符的结合性是从左到右,然后 + 10,再 + 6。
下面是常用操作符的优先级表:
上面这张图是比特 C 语言课程的课件哈,有兴趣的小伙伴可以了解一下比特,作者并没有打广告,个人觉得比特 C 语言的课程讲的很好。
十、表达式求值
1. 整型提升
当 char、short等短整型进行算数运算时,它们的值就会被提升为 int 类型,然后参与算数运算,该行为被称为整型提升。
整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执⾏,CPU内整型运算器(ALU)的操作数的字节⻓度⼀般就是int的字节⻓度,同时也是CPU的通⽤寄存器的⻓度。因此,即使两个char类型的相加,在CPU执⾏时实际上也要先转换为CPU内整型操作数的标准⻓度。通⽤CPU(general-purpose CPU)是难以直接实现两个8⽐特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种⻓度可能⼩于int⻓度的整型值,都必须先转换为int或unsigned int,然后才能送⼊CPU去执⾏运算。
整型提升的规则:有符号整型提升补符号位,无符号整型提升补 0。
如:
char a = -1;
short b = 2;
a + b;
进行 a + b 时,先对 a 和 b 进行整形提升
a:11111111
提升:111111111111111111111111111111111 结果为 -1
b:0000000000000010
提升:00000000000000000000000000000010 结果为 2
提升后相加:1
2. 算数转换
当操作符来两边出现不同类型的对象时,那么其中一个操作数就需要转换为另一个操作数的类型,否则无法进行计算。一般按照下面的顺序由低向高转换:
(1)long double
(2)double
(3)float
(4)unsigned long
(5)long
(6)unsigned
(7)int
3. 问题表达式解析
虽然我们已经学习了以上种种与表达式求值有关的知识,但是仍然有不少表达式我们是无法求出确切的值,而且我们在编写代码的时候也尽量不要编写这些代码。
(1)类型1
int i = 1;
(i++) + (i++) + (i++);
该表达式只能确定后置递增运算符在加法之前,但是不能确定先算计算几个递增运算符,我可以先计算三个 i++,然后 i 的值为 4,然后相加得出表达式的结果为 12,;我也可以先计算前面两个 i++ 然后 i 的值为 3,前面两个 i 相加得 6,再加最后一个 i++,表达式结果为 9,i 的值最终为 4。
所以尽量不要编写上述类型的代码。
(2)类型2
#include <stdio.h>
int fun()
{static int count = 1;return ++count;
}
int main()
{int answer;answer = fun() - fun() * fun();printf( "%d\n", answer);//输出多少? return 0;
}
虽然大多数编译器上面求得该表达式的结果相同,但是我们只能确定乘法在加法之前,但是却不能得出三个函数的调用顺序,我可以先调用第一个函数,也可以先调用第二个。
相关文章:

操作符详解(C 语言)
目录 一、操作符的分类二、算数操作符1. 除法操作符2. 取余操作符 三、位移操作符1. 进制2. 原码、反码和补码3. 左移操作符(<<)和右移操作符(>>) 四、位操作符1. 按位与 &2. 按位或 |3. 按位异或 ^4. 按位取反 ~…...
自动化测试数据:如何正确地选择不同格式文件「详细介绍」?
自动化测试数据:如何正确地选择不同格式文件「详细介绍」? 前言1. 不同的格式文件对比2. 读取文件2.1 读取Excel文件2.2 读取CSV文件2.3 读取YAML文件2.3.1 字典2.3.2 列表2.3.3 混合类型2.3.4 包含列表的字典2.3.5 包含字典的列表2.3.6 复杂嵌套 2.4 读…...

OceanBase中扩容OCP节点step by step
许多用户在开始使用OceanBase时部署OCP,通常选择单节点部署。但随着后续业务规模的不断扩大,会开始担忧单节点OCP在面对故障时可能丧失对集群运维管控的连续性。鉴于此,会将现有的单节点OCP扩展至多节点部署,以此来确保OCP服务的高…...

国家人工智能创新应用先导区数据及城市人工智能先导区准自然实验数据(2006-2023年)
一、测算方式:参考C刊《当代财经》冯婉昕(2024)老师的做法,本文的核心解释变量为国家人工智能创新应用先导区政策 (AI)。企业的金融资产配置是企业生产经营的内生变量,因此,如果选择…...
搜维尔科技:感受、握持、推动、连接和挤压虚拟物体,SenseGlove触觉反馈手套拥有先进的触觉技术、一流的可用性和功能
感受、握持、推动、连接和挤压虚拟物体,SenseGlove触觉反馈手套拥有先进的触觉技术、一流的可用性和功能 感受、握持、推动、连接和挤压虚拟物体,SenseGlove触觉反馈手套拥有先进的触觉技术、一流的可用性和功能...

C++中的引用详解
C中的引用详解 什么是引用 引用是一种取别名的机制,用于为变量提供一个新的名字。在C中,引用的语法使用&符号。引用允许我们以一种更安全和直观的方式来操作变量。 为什么要使用指针 在C中,虽然引用提供了一些优势,但指针仍…...
软考中级 - 软件设计师学习笔记 - 1.3 计算机安全
1.3.1 安全威胁 计算安全:指的是计算机资产安全,是要保证这些计算机资产不受自然和人为的有害因素的威胁和危害。 1.3.2 加密技术和认证技术 加密技术:对称加密(私有密钥加密)、非对称加密(公开密钥加密)。对称加密(私钥/私有密…...

Unity3D相关知识点总结
Unity3D使用的是笛卡尔三维坐标系,并且是以左手坐标系进行展示的。 1.全局坐标系(global) 全局坐标系描述的是游戏对象在整个世界(场景)中的相对于坐标原点(0,0,0)的位置…...

牛顿迭代多维+原理推导
这是两个函数了两个变量的情况,对于三个函数两个变量,牛顿迭代的雅可比矩阵不能求逆, 右边的增量的求解就不能用这个公式了呢。对于有逆矩阵但不能求逆的公式,这个逆矩阵是求解线性方程时出现的,就可用不求逆的方法解…...

[自然语言处理]RNN
1 传统RNN模型与LSTM import torch import torch.nn as nntorch.manual_seed(6)# todo:基础RNN模型 def dem01():参数1:input_size 每个词的词向量维度(输入层神经元的个数)参数2:hidden_size 隐藏层神经元的个数参数3:…...

MySQL(B站CodeWithMosh)——2024.10.11(14)
ZZZZZZ目的ZZZZZZ代码ZZZZZZ重点ZZZZZZ操作(非代码,需要自己手动) 8- CASE运算符The CASE Operator_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1UE41147KC?p62&vd_sourceeaeec77dfceb13d96cce76cc299fdd08 在sql_store中&am…...
Transformer的预训练模型
Transformer的预训练模型有很多,其中一些在自然语言处理(NLP)和计算机视觉等领域取得了巨大成功。以下是一些主要的Transformer预训练模型: 1. BERT (Bidirectional Encoder Representations from Transformers) 简介: BERT 是谷歌推出的双向Transformer模型,专注于编码器…...
手撕单例模式
在Go语言中实现单例模式,通常需要确保一个类只有一个实例,并且提供一个全局访问点。Go语言本身没有类的概念,但可以通过结构体和函数来模拟这种行为。下面是一个简单的手撕单例模式的实现示例: 懒汉式(延迟初始化&…...

UE4 材质学习笔记06(布料着色器/体积冰着色器)
一.布料着色器 要编写一个着色器首先是看一些参考图片,我们需要找出一些布料特有的特征,下面是一个棉织物,可以看到布料边缘的纤维可以捕捉光线使得边缘看起来更亮 下面是缎子和丝绸的图片,与棉织物有几乎相反的效果,…...
人工智能学习框架
人工智能学习框架是指用于开发和训练机器学习和深度学习模型的软件库和工具集。这些框架帮助开发者更高效地构建、训练和部署模型,加速人工智能应用的开发进程。 常见的人工智能学习框架 TensorFlow 由Google开发,是一个开源的深度学习框架,…...
GEE 教程:Landsat TOA数据计算地表温度(LST)
目录 简介 函数 expression(expression, map) Arguments: Returns: Image reduceRegion(reducer, geometry, scale, crs, crsTransform, bestEffort, maxPixels, tileScale) Arguments: Returns: Dictionary 代码 结果 简介 地表温度(Land Surface Temperature,LS…...

Web编程---配置Tomcat
文章目录 一、目的二、原理三、过程1. 解压“apache-tomcat-10.0.27-windows-x64.zip”文件到指定文件夹。2. 配置环境变量3.修改编码方式,防止 Tomcat 控制台出现乱码。4.启动 Tmocat5.打开浏览器,地址栏输入 http://localhost:8080 ,如果看…...
物联网5G模块WIFI模块调式记录(Pico)
调试环境 MCU:Pico1(无wifi版)5G模块:EC800K(iot专用4g卡)WIFI模块:ESP01s(Esp8266芯片)、DX-WF24开发环境:MacBook Pro Sonoma 14.5开发工具:Th…...
中国平安蝉联2024“金融业先锋30”第一名 获金融业ESG最高五星评级
2024年10月15日,中央广播电视总台正式对外发布《金融业ESG行动报告(2024)》(以下简称"《报告》"),并公布了"中国ESG上市公司金融业先锋30"榜单。中国平安凭借在绿色金融、普惠金融、养…...

[图解]题目解析:财务人员最有可能成为业务执行者的是
1 00:00:00,420 --> 00:00:04,760 接下来,是第3章自测题第1部分的第8题 2 00:00:05,090 --> 00:00:08,120 单选,针对以下研究对象 3 00:00:08,900 --> 00:00:11,530 财务人员最有可能成为业务执行者的是 4 00:00:12,800 --> 00:00:15,280…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...