所有数据,字符串,整数等一切事物在计算机里,都是通过 0 和 1 来组成,也就是用二进制表示。二进制的特点就是「逢二进一」。

同时为了应对负数,采用了补码表示法,即第一位既作为符号位,同时也参与运算。比如 4 位二进制数,从 1000 到 0111,表示的范围在 -8 到 7 之间的 16 个数,不会浪费任何一个位。

有了补码表示负数,整数相加也变得很容易,不需要做任何特殊处理,只是把它当成普通的二进制相加,就能得到正确的结果。

二进制编码

最早计算机只需要使用英文字符,加上数字和一些特殊符号,然后用 8 位的二进制,就能表示我们日常需要的所有字符了,这个就是我们常常说的 ASCII 码。

ASCII 码

8 位二进制能表示 128 个不同的数,然后映射到 128 个不同的字符里。ASCII 编码就相当于一本字典,存放二进制值与对应字符的映射关系。

多数中间件在序列化时,会直接用二进制来序列化,你知道为什么吗?

假设我们要序列化一个数字 15,如果采用 json 或者 csv 等文本格式存储起来在序列化,那么 15 就需要通过连续两个字符 1 和 5 来表示,对照 ASCII 码表,即 0011 0001 和 0011 0101,需要用两个 8 位来表示。

而如果直接用二进制来序列化,15 只需一个 8 位二进制码表示,同样的值,序列化方式不同,存储上就多了一位,如果这个不够明显,你可以想想 int 类型的最大值,二进制表示就 32 位,但换成字符串,每个字符 8 位,10 个字符得 80 位,整整 2.5 倍,所以采用二进制序列化会比存储文本省下不少空间。

随着越来越多的不同国家的人都用上了计算机,ASCII 码不够用了,比如中文怎么表示?

这时各个国家工程师开始各显神通,给自己国家创建字符集和字符编码。

字符集:字符的一个集合。比如所有中文汉字就是一个字符集。日常说的 Unicode,也是一个字符集,包含了 150 种语言的 14 万个不同的字符。

字符编码:对于字符集里的这些字符,怎么一一用二进制表示出来的一个字典。上面说的 Unicode,就可以用 UTF-8、UTF-16,乃至 UTF-32 来进行编码,存储成二进制。

有了字符集和字符编码,我们各个国家就知道计算机里传递的这些二进制究竟是什么数据了。

不过这只是逻辑上的对应关系,在硬件层面,这些二进制数值和我们的晶体管和电路怎么关联的呢。

电路

古代信号传递,通过烽火台和灯塔,后来有了电报,现在有了电路。所以电路就是用来传递数据的。

电路通信一般是拉一条电线,连成通路,但这里有个问题,比如北京到上海,电线太长,电压不够,导致信号衰弱,无法传递。

为解决这个问题,我们可以每隔一小段距离铺设一个线路,或者一个电驿站,将上一段线路发送过来的信息信号增强一下,发到下一个电站去,实现接力传输,这就是继电器

继电器类应用非常广。比如家里 WIFI 信号不足,可在增加一个路由器,接受原来 WIFI 信号,增强后在传输出去。再比如我们的光纤,都是每隔一段距离,增加一个放大原有信号的中继。

信号输出端,除了供人观察信号,还可以作为后续线路的输入信号,我们通过各种开关的组合(与或非等),形成我们需要的逻辑。

这就是门电路。一方面,我们可以通过继电器或者中继,进行长距离的信号传输。另一方面,我们也可以通过设置不同的线路和开关状态,实现更多不同的信号表示和处理方式,这些线路的连接方式其实就是我们在数字电路中所说的门电路。

而这些门电路,也是我们创建 CPU 和内存的基本逻辑单元。我们的各种对于计算机二进制的“0”和“1”的操作,其实就是来自于门电路,叫作组合逻辑电路。

在计算机里,即通过千万的晶体管组合,从而去指挥计算机干什么。