2.1 信息存储

1字节(byte)= 8位(bit)

2.1.1 十六进制表示法

十六进制(简写为"hex")使用数字 '0' ~ '9' 以及字符 'A' ~ 'F' 来表示。

1 个十六进制数表示 4 个二进制数。

当 x=2n 时,很容易将 x 写成十六进制形式,x 的二进制表示就是 1 后面跟 n 个 0 。十六进制数字 0 代表 4 个二进制 0。所以,当 n 表示成 i+4j 的形式,其中 0 ≦ i ≦ 3,x 开头十六进制为1(i=0)、2(i=1)、4(i=2)、8(i=3),后面跟随 j 个十六进制的 0。

2.1.2 字数据大小

C声明

C声明

字节数

字节数

有符号

无符号

32位

64位

[signed] char

unsigned char

1

1

short

unsigned short

2

2

int

unsigned

4

4

long

unsigned long

4

8

int32_t

uint32_t

4

4

int64_t

uint64_t

8

8

char *

4

8

float

4

4

double

8

8

2.1.3 寻址和字节顺序

最低有效字节在最前面的方式,为小端法(little endian)。

最高有效字节在最前面的方式,为大端法(big endian)——与书写习惯一致。

假设变量 x 的类型为 int,位于地址 0x100 处,它的十六进制值为 0x01234567。地址范围 0x100〜0x103 的字节顺序依赖于机器的类型:

注意,在字 0x01234567 中,高位字节的十六进制值为 0x01,而低位字节值为 0x67。

// 判断大小端

int is_little_endian(void) {

int i = 0xff;

unsigned char *p = &i;

return p[0] == 0xff;

}

2.1.4 表示字符串

C语言中字符串被编码为一个以null(其值为0)字符结尾的字符数组。

字母 'a' ~ 'z' 的 ASCII 码为 0x61 ~ 0x7A。

2.1.5 表示代码

不同的机器类型使用不同的且不兼容的指令和编码方式。

2.1.6 布尔代数简介

1 为 true(真)

0 为 false(假)

图2-7↓ 布尔代数的运算。二进制值 1 和 0 表示逻辑值 TRUE 或者 FALSE ,而运算符 〜、&、丨和 ^ 分别表示逻辑运算 NOT、 AND、OR 和 EXCLUSIVE-OR

可以将上述 4 个布尔运算扩展到位向量的运算,位向量就是固定长度为 W 、由 0 和 1 组成的串。位向量的运算可以定义成参数的每个对应元素之间的运算。

举个例子,假设 w=4 ,参数 a = [0110] ,b=[1100]。那么 4 种运算a&b、a|b、a^b 和〜b 分别得到以下结果:

关于布尔代数和布尔环的更多内容

布尔运算 & 对 | 的分配律,写为 a & (b | c) = (a & b) | (a & c)。

布尔运算 | 对 & 的分配律,写为 a | (b & c) = (a | b) & (a | c)。

对于任何值 a 来说,a ^ a = 0。

(a ^ b) ^ a = b。

2.1.7 C语言中的位级运算

C的表达式

二进制表达式

二进制结果

十六进制结果

~0x41

~[0100 0001]

[1011 1110]

0xBE

~0x00

~[0000 0000]

[1111 1111]

0xFF

0x69&0x55

[0110 1001]&[0101 0101]

[0100 0001]

0x41

0x69|0x55

[0110 1001]|[0101 0101]

[0111 1101]

0x7D

位级运算的一个常见用法就是实现掩码运算,这里掩码是一个为模式,表示从一个字中选出的位的集合。

如:x = 0x89ABCDEF,x&0xFF = 0x000000EF

表达式 ~0 将生成一个全 1 的掩码,不管机器的字大小是多少。

2.1.8 C语言中的逻辑运算

|| OR 或

&& AND 与

! NOT 非

表达式

结果

!0x41

0x00

!0x00

0x01

!!0x41

0x01

0x69&&0x55

0x01

0x69||0x55

0x01

如果对第一个参数求值就能确定表达式的结果,那么逻辑运算符就不会对第二个参数求值。

2.1.9 C语言中的位移运算

左移:x<

逻辑右移:x>>k,在左端补k个0。

算术右移:x>>k,在左端补k个最高有效位的值。

2.2 整数表示

数学术语

下标w表示数据表示中的位数

符号

类型

含义

函数

二进制转补码

函数

二进制转无符号数

函数

无符号数转二进制

函数

无符号转补码

函数

补码转二进制

函数

补码转无符号数

常数

最小补码值

常数

最大补码值

常数

最大无符号数

操作

补码加法

操作

无符号数加法

操作

补码乘法

操作

无符号数乘法

操作

补码取反

操作

无符号数取反

2.2.1 整型数据类型

32位程序上C语言整型数据类型的典型取值范围

C数据类型

最小值

最大值

[signed]char

-128

127

unsigned char

0

255

short

-32 768

32 767

unsigned short

0

65 535

int

-2 147 483 648

2 147 483 647

unsigned

0

4 294 967 295

long

-2 147 483 648

2 147 483 647

unsigned long

0

4 294 967 295

int32_t

-2 147 483 648

2 147 483 647

uint32_t

0

4 294 967 295

int64_t

-9 223 372 036 854 775 808

9 223 372 036 854 775 807

uint_64_t

0

18 446 744 073 709 551 615

64位程序上C语言整型数据类型的典型取值范围

C数据类型

最小值

最大值

[signed]char

-128

127

unsigned char

0

255

short

-32 768

32 767

unsigned short

0

65 535

int

-2 147 483 648

2 147 483 647

unsigned

0

4 294 967 295

long

-9 223 372 036 854 775 808

9 223 372 036 854 775 807

unsigned long

0

18 446 744 073 709 551 615

int32_t

-2 147 483 648

2 147 483 647

uint32_t

0

4 294 967 295

int64_t

-9 223 372 036 854 775 808

9 223 372 036 854 775 807

uint_64_t

0

18 446 744 073 709 551 615

C语言的整型数据类型的保证的取值范围

C数据类型

最小值

最大值

[signed]char

-127

127

unsigned char

0

255

short

-32 767

32 767

unsigned short

0

65 535

int

-32 767

32 767

unsigned

0

65 535

long

-2 147 483 647

2 147 483 647

unsigned long

0

4 294 967 295

int32_t

-2 147 483 648

2 147 483 647

uint32_t

0

4 294 967 295

int64_t

-9 223 372 036 854 775 808

9 223 372 036 854 775 807

uint_64_t

0

18 446 744 073 709 551 615

2.2.2 无符号数的编码

无符号数编码的定义

对向量

最大值是用位向量[11...1]表示

以4位情况为例,

2.2.3 补码编码

补码编码的定义

对向量

最小值是用位向量[10...0]表示

(也就是设置这个位为负权,但是清除其他所有的位)

以4位情况为例,

最大值是用位向量[01...1]表示

(清除具有负权的位,而设置其他所有的位)

以4位情况为例,

注意:

1、补码的范围是不对称的:|TMin| = |TMax| + 1 ,也就是说,TMin没有与之对应的正数。

2、最大的无符号数值刚好比补码的最大值的两倍大一点:

3、-1 和 UMax 有同样的位表示——一个全 1 的串,数值 0 在两种表示方式中都是全 0 的串。

2.2.4 有符号数和无符号数之间的转换

补码转换为无符号数

对满足

有:

比如,

,同时

推导:补码转换为无符号数

根据上个公式的两种情况,在

的补码表示中,位

决定了

是否为负。

无符号数转换为补码

对满足

有:

推导:无符号数转换为补码

在u的无符号表示中,对上个公式的两种情况来说,位

决定了 u 是否大于

2.2.5 C语言中的有符号数与无符号数

C语言支持所有整型数据类型的有符号和无符号运算。尽管C语言标准没有指定有符号数要采用某种表示,但是几乎所有机器都使用补码。通常,大多数数字都默认为是有符号的。要创建一个无符号常量,必须加上后缀字符 'U' 或者 'u' 。

C语言无符号数和有符号数之间的转换,一般原则是底层的位表示保持不变。

当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式地将有符号参数强制类型转换为无符号数,并假设这两个数都是非负的,来执行这个运算。

C语言中TMin的写法

定义在头文件 limits.h 中

#define INT_MAX 2147483647

#define INT_MIN (-INT_MAX - 1)

2.2.6 扩展一个数字的位表示

要将一个无符号数转换为一个更大的数据类型,在开头添加0,这种运算被称为零扩展(zero extension)。

要将一个补码数字转换为一个更大的数据类型,可以执行一个符号扩展(sign extension),在表示中添加最高有效位的值。

2.2.7 截断数字

无符号数的截断结果是:

补码数字的截断结果是:

2.2.8 关于有符号数与无符号数的建议

有符号数到无符号数的隐式转换,是会导致错误或者漏洞的方式,避免这类错误的一种方法就是绝不使用无符号数。

2.3 整数运算

2.3.1 无符号加法

将操作

描述为无符号数加法

对满足

有:

检测无符号数加法中的溢出

对在范围

中的

,令

。则对计算

,当且仅当

(或者等价地

)时,发生了溢出。

阿贝尔群

每个元素有一个加法逆元。考虑 w 位的无符号数的集合,执行加法运算

。对于每个值 x,必然有某个值

满足

无符号数求反

对满足

的任意

,其

位的无符号逆元

由下式给出:

2.3.2 补码加法

对满足

之内的整数

,有:

两个数的

位补码之和有完全相同的位级表示。我们可以按如下步骤表示运算

:将其参数转换为无符号数,执行无符号数加法,再将结果转换为补码:

检测补码加法中的溢出

对满足

,令

。当且仅当

,但

时,计算

发生了正溢出。当且仅当

,但

时,计算

发生了负溢出。

2.3.3 补码的非

可以看到范围在

中的每个数字

都有

下的加法逆元,我们将

表示如下:

对满足

,其补码的非

由下式给出

也就是说,对

位的补码加法来说,

是自己的加法的逆,而对其他任何数值

都有

作为其加法的逆。

补码非的位级表示

计算一个位级表示的值的补码非有几种聪明的方法。

1、执行位级补码非的第一种方法是对每一位求补,再对结果加1。在C语言中,我们可以说,对于任意整数值 x ,计算表达式 -x 和 ~x+1 得到的结果完全一样。

2、计算一个数 x 的补码非的第二种方法是建立在将位向量分为两部分的基础之上的。假设

是最右边的 1 的位置,因而

的位级表示形如

。(只要

就能够找到这样的

。)这个值的非写成二进制格式就是

。也就是,我们对位

左边的所有位取反。

2.3.4 无符号乘法

对满足

有:

2.3.5 补码乘法

对满足

有:

对于无符号和补码乘法来说,乘法运算的位级表示都是一样的。

2.3.6 乘以常数

乘以 2 的幂

为位模式

表示的无符号整数。那么,对于任何

,我们都认为

给出了

位的无符号表示,这里右边增加了

个 0 。

与 2 的幂相乘的无符号乘法

C 变量 x 和 k 有无符号数值

,且

,则 C 表达式 x<

与 2 的幂相乘的补码乘法

C 变量 x 和 k 有补码值

和 无符号数值

,且

,则 C 表达式 x<

由于整数乘法比移位和加法的代价要大得多,许多 C 语言编译器试图以移位、加法和减法的组合来消除很多整数乘以常数的情况。

对于某个常数 K 的表达式 x * K 生成代码。编译器会将 K 的二进制表示表达为一组 0 和 1 交替的序列:

考虑一组从位位置 n 到位位置 m 的连续的 1(n

m)。我们可以用下面两种不同形式中的一种来计算这些位对乘积的影响:

形式A:(x<

形式B:(x<

把每个这样连续的 1 的结果加起来,不用做任何乘法,我们就能计算出 x * K 。

2.3.7 除以 2 的幂

整数除法要比整数乘法更慢。除以 2 的幂也可以用移位运算来实现。无符号和补码数分别使用逻辑移位和算术移位来达到目的。

整数除法总是舍入到零。它将

向下

舍入一个正值,而

向上

舍入一个负值。

除以 2 的幂的无符号除法

C 变量 x 和 k 有无符号数值

,且

,则 C 表达式 x >> k 产生数值

除以 2 的幂的补码除法,向下舍入

C 变量 x 和 k 有补码值

和 无符号数值

,且

,则当执行算术位移时, C 表达式 x >> k 产生数值

对于负数来说,向下舍入结果会有偏差。

除以 2 的幂的补码除法,向上舍入

C 变量 x 和 k 有补码值

和 无符号数值

,且

,则当执行算术位移时, C 表达式 (x+(1<> k 产生数值

2.3.8 关于整数运算的最后思考

计算机执行的“整数”运算实际上是一种模运算形式。

表示数字的有限字长限制了可能的值的取值范围,结果运算可能溢出。

补码表示提供了一种既能表示负数也能表示正数的灵活方法,同时使用了与执行无符号算术相同的位级实现。

无论运算数是以无符号形式还是以补码形式表示的,都有完全一样或者类似的位级行为。

2.4 浮点数

浮点表示对形如

的有理数进行编码。它对执行涉及非常大的数字(|V|>>0)、非常接近于0(|V|<<1)的数字,以及更普遍地作为实数运算的近似值的计算,是很有用的。

2.4.1 二进制小数

形如

的表示法,其中每个二进制数字,或者称为位,

的取值范围是 0 和 1 ,这种表示方法表示的数 b 定义如下:

点左边的位的权是 2 的正幂,点右边的位的权是 2 的负幂。

例如,

表示数字

=

形如

的数表示的是刚好小于 1 的数。例如,

表示

,我们将用简单的表达法

来表示这样的数值。

定点表示法不能很有效的表示非常大的数字。

2.4.2 IEEE 浮点表示

IEEE浮点标准用

的形式来表示一个数:

符号(sign)

决定这数是负数(

)还是正数(

),而对于数值

的符号位解释作为特殊情况处理。

尾数(significand)

是一个二进制小数,它的范围是

,或者是

阶码(exponent)

的作用是对浮点数加权,这个权重是

次幂(可能是负数)。

将浮点数的位表示划分为三个字段,分别对这些值进行编码:

一个单独的符号位

直接编码符号

位的阶码字段

编码阶码

位小数字段

编码尾数

,但是编码出来的值也依赖于阶码字段的值是否等于 0 。

在单精度浮点格式(C 语言中的 float)中,s、exp 和 frac 字段分别为

位、

位和

位,得到一个 32 位的表示。

在双精度浮点格式(C 语言中的 double)中,s、exp 和 frac 字段分别为

位、

位和

位,得到一个 64 位的表示。

给定位表示,根据 exp 的值,被编码的值可以分成三种不同的情况(最后一种情况有两个变种)。图 2-33 说明了对单精度格式的情况。

情况1:规格化的值

当 exp 阶码域的位模式既不全为 0,也不全为 1 时。

阶码字段被解释为以偏置(biased)形式表示的有符号整数。阶码的值是 ,其中 e 是无符号数,Bias 是一个等于 (单精度是127,双精度是1023)的偏置值。

小数字段 frac 被解释为描述小数值 ,其中 ,其二进制表示为 ,也就是二进制小数点在最高有效位的左边。

尾数定义为 。这种方式叫做隐含的以 1 开头的(implied leading 1)表示,因为可以把 看成一个二进制表达式为 的数字。

情况2:非规格化的值

当 exp 阶码域为全 0 时,所表示的数是非规格化形式。

阶码值是

尾数的值是

,也就是小数字段的值,不包含隐含的开头的1。

非规格化数有两个用途:

1.提供了一种表示数值 0 的方法。

2.表示那些非常接近于 0.0 的数。

情况3:特殊值

当 exp 阶码域全为 1时,表示特殊值。

当小数域全为 0 时,得到的值表示无穷。当 s=0 时是

,或者当 s=1 时是

当小数域为非零时,结果值被称为 “NaN”,即“不是一个数(Not a Number)”的缩写。

2.4.3 数字示例

图 2-35 展示了假定的 8 位浮点格式的示例,其中有

的阶码位和

的小数位。偏置量是

可以观察到最大非规格化数 和最小规格化数 之间的平滑转变。这种平滑性归功于我们对非规格化数的 E 的定义。通过将 E 定义为 1 - Bias ,而不是 -Bias ,我们可以补偿非规格化数的尾数没有隐含的开头的 1。

假如我们将图 2-35 中的值的位表达式解释为无符号整数,它们就是按升序排列的,就像它们表示的浮点数一样。这不是偶然的——IEEE格式如此设计就是为了浮点数能够使用整数排序函数来进行排序。

图 2-36 展示了一些重要的单精度和双精度浮点数的表示和数字值。依据图 2-35 中展示的 8 位格式,我们能够看出有 k 位阶码和 n 位小数的浮点表示的一般属性。

值 +0.0 总有一个全为 0 的位表示。

最小的正非规格化值的位表示,是由最低有效位为 1 而其他所有位为 0 构成的。它具有小数(和尾数)值

和阶码值

。因此它的数字值是

最大的非规格化值的位模式是由全为 0 的阶码字段和全为 1 的小数字段组成的。它有小数(和尾数)值

(我们写成

)和阶码值

。因此,数值

,这仅比最小的规格化值小一点。

最小的正规格化值的位模式的阶码字段的最低有效位为 1 ,其他位全为 0 。它的尾数值

,而阶码值

。因此,数值

值 1.0 的位表示的阶码字段除了最高有效位等于 0 以外,其他位都等于 1。它的尾数值是

,而它的阶码值是

最大的规格化值的位表示的符号位为 0,阶码的最低有效位等于 0,其他位等于 1。它的小数值

,尾数

(我们写作

)。它的阶码值

,得到数值

整数值转换成浮点形式,相关的区域对应于整数的低位,刚好在等于 1 的最高有效位之前停止(这个位就是隐含的开头的位 1),和浮点表示的小数部分的高位是相匹配的。

2.4.4 舍入

因为表示方法限制了浮点数的范围和精度,所以浮点运算只能近似地表示实数运算。因此,对于值x,能够找到“最接近的”匹配值x',它可以用期望的浮点形式表示出来。这就是舍入(rounding)运算的任务。

舍入方式有四种:

方式

1.40

1.60

1.50

2.50

-1.50

向偶数舍入

1

2

2

2

-2

向零舍入

1

1

1

2

-1

向下舍入

1

1

1

2

-2

向上舍入

2

2

2

3

-1

向偶数舍入是舍入到一个最接近的值。

2.4.5 浮点运算

浮点加法不具有结合性,例如,使用单精度浮点,表达式 (3.14+1e10)-1e10 求值得到 0.0 —— 因为舍入,值 3.14 会丢失。表达式 3.14+(1e10-1e10) 得出值 3.14。

浮点加法满足了单调性属性:如果

,那么对于任何 a、b 以及 x 的值,除了 NaN,都有

。无符号或补码加法不具有这个实数(和整数)加法的属性。

浮点乘法不具有结合性。例如,单精度浮点情况下,表达式 (1e201e20)1e-20 求值为

,而 1e20(1e201e-20) 将得出 1e20。

浮点乘法在加法上不具备分配性。例如,单精度浮点情况下,表达式 1e20(1e20-1e20)求值为 0.0,而 1e201e20-1e20*1e20 会得出 NaN。

对于任何a、b和c,并且a、b和c都不等于 NaN,浮点乘法满足下列单调性:

只要

,就有

2.4.6 C 语言中的浮点数

所有的 C 语言版本提供了两种不同的浮点数据类型:float 和 double。

当程序文件中出现下列句子时,GUN 编译器 GCC 会定义程序常数 INFINITY(表示

)和 NAN(表示 NaN):

#define _GUN_SOURCE 1

#include

当在 int、float 和 double 格式之间进行强制类型转换时,程序改变数值和位模式的原则如下(假设 int 是 32 位的):

从 int 转换成 float,数字不会溢出,但是可能被舍入。

从 int 或 float 转换成 double,因为 double 有更大的范围(也就是可表示值的范围),也有更高的精度(也就是有效位数),所以能够保留精确的数值。

从 double 转换成 float,因为范围要小一些,所以值可能溢出成

。另外,由于精确度较小,它还可能被舍入。

从 float 或者 double 转换成 int,值将会向零舍入。例如,1.999 将被转换成 1,而 -1.999 将被转换成 -1。

深入理解计算机系统 2.1 节信息存储,深入理解计算机系统(原书第3版)- 第2章 信息的表示和处理 笔记...相关推荐

  1. 《计算机系统:核心概念及软硬件实现(原书第4版)》——1.4数据库系统

    本节书摘来自华章计算机<计算机系统:核心概念及软硬件实现(原书第4版)>一书中的第1章,第1.4节,作者:[美] J. 斯坦利·沃法德(J. Stanley Warford)著, 更多章节 ...

  2. 《计算机系统:核心概念及软硬件实现(原书第4版)》——1.2 硬件

    本节书摘来自华章计算机<计算机系统:核心概念及软硬件实现(原书第4版)>一书中的第1章,第1.2节,作者:[美] J. 斯坦利·沃法德(J. Stanley Warford)著, 更多章节 ...

  3. 虚拟内存(深入理解计算机系统原书第3版9节读书笔记)

    深入理解计算机系统(原书第3版)读书笔记,其实就是嚼碎了原文然后把一部分挑了出来摘要,免得读着读着忘了 文章目录 前言 一.物理和虚拟寻址 二.地址空间 三.虚拟内存作为缓存的工具 1.DRAM缓存的 ...

  4. 《深入理解Elasticsearch(原书第2版)》——第2章 查询DSL进阶 2.1 Apache Lucene默认评分公式解释...

    本节书摘来自华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第2章,第2.1节,作者 [美]拉斐尔·酷奇(Rafal Ku)马雷克·罗戈任斯基(Marek Rogoz ...

  5. 《深入理解Hadoop(原书第2版)》——1.3大数据的编程模型

    本节书摘来自华章计算机<深入理解Hadoop(原书第2版)>一书中的第1章,第1.3节,作者 [美]萨米尔·瓦德卡(Sameer Wadkar),马杜·西德林埃(Madhu Siddali ...

  6. 《深入理解Elasticsearch(原书第2版)》——1.4 小结

    本节书摘来自华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第1章,第1.4节,作者 [美]拉斐尔·酷奇(Rafal Ku)马雷克·罗戈任斯基(Marek Rogoz ...

  7. 《深入理解Elasticsearch(原书第2版)》一1.3 在线书店示例

    本节书摘来自华章出版社<深入理解Elasticsearch(原书第2版)>一书中的第1章,第1.3节,作者[美]拉斐尔·酷奇(Rafal Ku) 马雷克·罗戈任斯基(Marek Rogoz ...

  8. 《机器学习与R语言(原书第2版)》一2.3 探索和理解数据

    本节书摘来自华章出版社<机器学习与R语言(原书第2版)>一书中的第2章,第2.3节,美] 布雷特·兰茨(Brett Lantz) 著,李洪成 许金炜 李舰 译更多章节内容可以访问云栖社区& ...

  9. 《深入理解Hadoop(原书第2版)》——2.3Hadoop系统的组成

    本节书摘来自华章计算机<深入理解Hadoop(原书第2版)>一书中的第2章,第2.3节,作者 [美]萨米尔·瓦德卡(Sameer Wadkar),马杜·西德林埃(Madhu Siddali ...

最新文章

  1. slf4j的jar包冲突:LoggerFactory is not a Logback LoggerContext but Logback is on the classpath
  2. Python学习笔记__5章 模块
  3. UI进阶--Quartz2D和触摸事件的简单使用:简易涂鸦板
  4. C之memset、memcpy、strcpy、strncpy区别
  5. PVS 6.1 Configuring Services Failed
  6. Source Map调试压缩后代码
  7. CAD图纸上面缺失的线条如何将其进行补充?
  8. CCF NOI1064 计算斐波那契第n项
  9. select不能触发change_SQL之警觉触发
  10. 极客大学架构师训练营 系统架构 消息队列 负载均衡 数据库备份 第10课 听课总结
  11. 构建WebIM聊天程序
  12. 冰箱android10,智能手机 篇十:手机冻冰箱总共分几步?AGM推出金嗓子手机H2,超大声音超长待机...
  13. 【与时俱进,智慧社区应运而生】
  14. 台式计算机有乱码如何解决,电脑乱码怎么办,开机乱码解决方法
  15. Linux(Debian11)安装百度网盘
  16. Mac终端常用命令及报错处理
  17. 从四大造字法看文字所承载的文化_从造字法看体验文化
  18. linux--挂载,解挂
  19. 2016年8月15日 星期一 --出埃及记 Exodus 16:16
  20. 解Error:(3, 32) java: 无法访问org.springframework.boot.SpringApplication 错误的类文件: /D:/Program/maven-repos

热门文章

  1. 2016届阿里实习生java研发岗一面二面三面四面经验分享
  2. Tableau学习Step2一数据文件的读取与统计图、表的概述
  3. js实现返回上一页(页面刷新与不刷新)
  4. win10系统使用蓝牙鼠标时自动断开连接?
  5. scikit-image图像处理入门
  6. 思科开源软交换机vpp环境搭建
  7. 跟着明星在元宇宙炒房,靠谱吗?
  8. 犀利姐—林家小妹:将犀利进行到底!
  9. 玩转阿里云:从零到一上手玩转云服务器学习报告
  10. 我得了一种很奇怪的病...