偏头痛杨的程序员应该知道的一些计算机&开发&网络基础知识

文章目录


前戏

目前有很多初&中级程序员对计算机一些基础知识掌握的非常薄弱,会闹出很多笑话。
比如分不清什么是RAM和ROM,什么是内网和外网?什么是字节?什么是服务器?
域名和IP地址的关系,为什么要有端口?端口又分为UDP和TCP?什么是通讯协议?
甚至是科班出身的计算机专业的学生。。。
大学四年大部分同学学完的知识都还给了老师。

对于这些基础知识掌握的不牢固,会造成后续进阶时的捉襟见肘,这是我们不愿意看到的。
例如你不明白内存、CPU、硬盘,那等你进阶到并发编程和JVM的时候就会被卡住。

因此我总结出了一些计算机基础知识,用一些言简意赅,通俗易懂的话来呈现,
希望大家可以在日常工作中更得心应手,而不是捉襟见肘。
计算机科学是一门非常庞大且复杂的知识体系,越往高走越难,我们要有敬畏之心。


字节(byte)

字节是计算机中用于【存储】和【传输】的一种计量单位,
1个字节等于8位的二进制数(0或1),1个字节=8个比特,1byte=8bit。

例如:
我们家现在的网速是200kb/s,这个图片的大小为800kb,
这个程序在内存中占用了350kb的内存。

换算:2的10次方=1024。
注意区分大B和小b,大B表示byte,小b表示bit,1B=8b。

1KB(kilobyte 千字节) = 1024B;
1MB(megabyte 兆字节) = 1024KB,简称兆;
1GB(gigabyte 吉字节) = 1024MB,简称千兆;
1TB(trillonbyte 万亿字节) = 1024GB,简称太字节;
1PB(petabyte,千万亿字节) = 1024TB,简称拍字节;


二进制(binary)

在计算机的世界中,所有的数据在存储和运算时在底层都要使用二进制数表示,
包括你现在看到的文章,听的歌,看的电影等等等等,其底层都是一串串的0和1。

在计算机底层世界中全部都是一串密密麻麻的1010二进制串。
1和0对应电子元件的开和关,1代表开,0代表关。
计算机用高电平和低电平分别表示1和0,计算机只能识别二进制码代表的程序和数据。
1和0是组成计算机世界的最基本元素。

早期的计算机使用穿孔纸袋来进行计算,有空代表1,没空代表0。
计算机吞下一堆纸袋后才开始计算,
之后再把计算结果用纸袋吐出来或者用一排排信号灯来告诉人类计算结果。

二进制奉行逢二进一,十进制奉行逢十进一。
一个1或0表示1位,四个1或0就是4位,八个1或0就是8位,以此类推。
4位二进制码:0001
8位二进制码:00000001
16位二进制码:00000000 00000001
32位二进制码:00000000 00000000 00000000 00000001

例如:对于一个十进制数字5,
4位的表达方式是:0101,8位的表达方式是:00000101。

以00000101为例,最左侧的0是高位,最右侧的1是低位。
这里有个高位补0的概念,如果当前二进制码不够要求的长度,就要高位补0。

例如在java中的int类型,int是占4个字节(32位,4 * 8=32)
int a = 2;
二进制表示是:
00000000 00000000 00000000 00000010

二进制与十进制只是长得不一样,但表达的含义是一样的,十进制给人看,二进制给计算机看。

十进制 二进制
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001

二进制的缺点就是位数太长,人们常用八进制和十六进制作为二进制的缩写方式。
在计算机内部使用二进制,而输出与输出则采用十进制,计算机自己完成转换工作。

二进制串如何变成数据文件

一串串貌似无规则的1010二进制串,如何变成一个数据文件呢?
科学家们已经帮我们制定好了规则,下面以图片文件来举例。

假设现在有一串很长的二进制码,开头的16位表示文件格式标识,表示当前文件是什么格式,
后面的几串二进制表示文件的基本信息,包括图像的长宽高、颜色深度等等。

众所周知,图片是由一个个非常小的像素点构成,假如当前图片的颜色深度是24位,
则表示每个像素点的颜色都是由24个1或0的数据来组成的,后面的二进制串则是图像数据的本体。

之后的第一个24位二进制串表示第一个像素点的颜色,把这24位拆成3组,
分别是3串8位的二进制,这三串分别表示三个基准颜色:红、绿、蓝。
每组二进制串的不同,可以组合成各种各样的颜色,例如:

像素1:11111111 11111111 11111111 组成白色(红+绿+蓝)
像素2:11111111 00000000 00000000 组成红色
像素3:11111111 11111111 00000000 组成黄色(红+绿)
以此类推,如果是千万像素级别的照片,那就要这样计算千万次,最后呈现出图片的样子。

系统根据文件的扩展名不同,来识别文件中的二进制串的规则也就不同,打开呈现的方式也不同了。

二进制与十进制的转换

十进制转二进制

使用除2取余法,把10进制数不断的除2,得到的余数就形成了二进制数。
例如:
十进制数9
9除以2 = 4余1(低位)
4除以2 = 2余0
2除以2 = 1余0
1除以2 = 0余1(高位)
1001

十进制数8
8除以2 = 4余0(低位)
4除以2 = 2余0
2除以2 = 1余0
1除以2 = 0余1(高位)
1000

十进制数7
7除以2 = 3余1(低位)
3除以2 = 1余1
1除以2 = 0余1(高位)
0111(高位补0)

二进制转十进制

把一串二进制码从右往左看,把最右边的数乘以2的0次方,然后依次往左,
右边第二个数乘以2的1次方,右边第三个数乘以2的2次方,以此类推,最后把这些数累加,
就形成了十进制数。

例如:

0011
1*2^0 + 1*2^1 + 0*2^2 + 0*2^3  
1 + 2 + 0 + 0 = 3

0111
1*2^0 + 1*2^1 + 1*2^2 + 0*2^3  
1 + 2 + 4 + 0 = 7

二进制的算术运算

二进制加法

跟十进制加法类似,只不过是逢二进一,从右向左每位依次相加。
例如我们将:0111+0010 (十进制的7+2=9)

0111
0010

----
1001

二进制减法

跟十进制减法类似,低位数不够减时需要向高位数借位,借1当2,从右向左每位依次相减。
例如我们将:1001-0111 (十进制的9-7=2)

1001
0111

----
0010

二进制乘法

跟十进制减法类似,从右向左每位依次相乘,之后再每位相加。
例如我们将:0010乘以0100 (十进制的2乘以4=8)

   0010
   0100

--------
   0000
  0000
 0010
0000
   1000

二进制除法

1001
0011
(后续补充)

二进制的逻辑运算

二进制“或”

一个数为1,一个数为0,则运算结果为1;
两个数都为1,则运算结果为1;
两个数都是0,则运算结果为0;

1001
0011

----
1011

二进制“与”

一个数为1,一个数为0,则运算结果为0;
两个数都为1,则运算结果为1;
两个数都是0,则运算结果为0;

1001
0011

----
0001

二进制“非”

也可以称为取反操作,并不是2个值的运算。
0=1
1=0

1001

----
0110

二进制“异或”

一个数为1,一个数为0,则运算结果为1;
两个数都为1,则运算结果为0;
两个数都是0,则运算结果为0;

1001
0011

----
1010

二进制的负数

这里只说在程序中的二级制负数机制,需要涉及到原码、反码、补码等知识。
int a = 5;
由于int是4字节32位,所以5在程序中的表达方式为:
00000000 00000000 00000000 00000101
前面的一堆0是需要高位补0。

那么-5如何来表示呢?
负数默认以补码来表示,说到补码,需要先从原码和反码开始说起。

无符号:无符号位的最高位不是符号位,而是数值的一部分。
有符号:最高位为符号位,符号为0表示正数,符号为1表示负数。
除非特别声明,带符号数都默认由补码表示。

原码

一个二进制数同时包含符合和数值两部分,用最高位表示符号位,其余位表示数值,
这种表示带符号数的方法为原码表示法。

5的原码
00000000 00000000 00000000 00000101
-5的原码
10000000 00000000 00000000 00000101

反码

对于正数,其反码与原码相同。
对于负数,除了符号位外,其余各位按位取反,即1都换成0,0都换成1。

5的反码
00000000 00000000 00000000 00000101
-5的反码
11111111 11111111 11111111 11111010

补码

对于正数,补码与原码相同。
对于负数,则其补码为反码+1(低位+1)。

5的补码
00000000 00000000 00000000 00000101
-5的补码
11111111 11111111 11111111 11111011

所以-5的二进制码为:
11111111 11111111 11111111 11111011


CPU

CPU(Central Processing Unit)又叫*处理器,
是一台计算机的运算和控制核心,CPU是计算机中运行速度最快的核心组件。

CPU的功能

  1. 周而复始的执行一条条的指令,包括:读取指令、分析指令(解码)、执行指令;
  2. 实现数据的算术与逻辑运算;
  3. 实现异常及中断处理,例如:断电、运算溢出、设备故障等;

CPU的构成

  1. 运算器组件
    1.1 ALU(Arithmetic Logical Unit)算术逻辑单元
    1.2 多路选择器(M1~M3)
    1.3 通用寄存器(R1~R4)
    1.4 标志寄存器(FR:Flag Register)
    1.5 数据总线(Data Bus)与控制总线(Control Bus)
  2. 控制器组件
    2.1 指令部件
    2.1.1 程序计数器(PC:Program Counter)
    程序计数器用来存放即将要执行的指令地址,每提取并执行一条指令,计数器自加1并指向下一条要执行的指令地址。
    2.1.2 指令寄存器(IR:Instruction Register)
    2.1.3 指令编译码(ID:Instruction Decoder)
    2.2 时序部件
    2.3 微操作控制部件(MOCU:Micro Operation Control Unit)

CPU的运行速度非常快但存储空间十分有限,
只能依靠几个寄存器来暂时保存指令、数据、地址。
CPU没有办法永久保存指令,指令都在内存中存放,CPU需要读取内存中的指令,
一旦断电后,CPU和内存中存储的数据全部消失。

CPU缓存

CPU每次执行指令需要对数据进行读写操作,CPU只能访问内存中的数据和指令,
但CPU的速度要远远高于内存,如果CPU每次运行时都从内存中读取数据则会把CPU拖死。

于是在CPU和内存中间就加入了缓存,在运算过程中,
计算机将运算需要的数据从内存中复制一份到缓存,
CPU在进行计算时直接对缓存中的数据进行读写,之后数据再被刷回到内存中。
在多核CPU时代,每个核都会有对应的CPU缓存跟着。

一般情况下,CPU访问内存中的地址会有重复的情况,
以及当前地址附近的地址也会很快被访问(局部性原理),
因此可以把这些地址放到缓存中,如果缓存能命中就直接走缓存,
缓存不命中再从内存中拿,这样可以极大的提升运行效率。

但是由于CPU芯片面积和成本的因素来考虑,缓存都很小。
CPU缓存的运行频率极高,一般是和处理器同频运作。

CPU缓存由很多个Cache Line(最小缓存单位)构成,常见的Cache line大小为64字节。

CPU<-->寄存器<-->一级缓存<-->二级缓存<-->三级缓存<-->内存;
容量:一级缓存<二级缓存<三级缓存
性能:一级缓存>二级缓存>三级缓存
(注意:CPU寄存器与CPU一级缓存不是一个东西,千万不要混淆。)

L1 Cache(一级缓存)

CPU第一层高速缓存,分为数据缓存(L1i)和指令缓存(L1d)。
与CPU同材质构成,与CPU一样快,所以数据读写无延迟。

L2 Cache(二级缓存)

CPU的第二层高速缓存,分内部和外部两种芯片。
内部的芯片二级缓存运行速度与主频相同,而外部的二级缓存则只有主频的一半。
L2高速缓存容量也会影响CPU的性能,原则是越大越好,
二级缓存就是一级缓存的缓冲器:一级缓存制造成本很高因此它的容量有限,
二级缓存的作用就是存储那些CPU处理时需要用到、一级缓存又无法存储的数据。

L3 Cache(三级缓存)

三级缓存和内存可以看作是二级缓存的缓冲器,它们的容量递增,但单位制造成本却递减。
需要注意的是,无论是二级缓存、三级缓存还是内存都不能存储处理器操作的原始指令,
这些指令只能存储在CPU的一级指令缓存中,
而余下的二级缓存、三级缓存和内存仅用于存储CPU所需数据。

CPU与其他组件的关系

计算机开机后,电流接通CPU,CPU开始工作,CPU主要的工作内容就是执行指令。
CPU要运行的第一个指令地址是内存最顶端的0xFFFFFFF0。

CPU通过系统总线(system bus)连接到I/O桥(I/O bridge),
通过I/O桥进行转接,再通过存储总线(memory bus)调用到内存。

从内存中读取指令,内存会很慢的将地址上存储的指令返回给CPU,
这是一条跳转指令,CPU将会运行BIOS的一堆指令。

BIOS进行一些列操作,包括:系统自检、查看内存、硬盘、显卡、
主板等组件是否有故障,有故障则需要报警。

BIOS运行完毕后,返回给CPU一堆新的指令,CPU接着执行,
CPU把操作系统加载到内存中,这些指令将启动硬盘中的操作系统。

操作系统启动成功后,会成为计算机的老大,各个组件都要听他调度和指挥,包括CPU。
之后偏头痛杨想执行一个硬盘中的java程序,于是告诉给了操作系统,
操作系统通知CPU,CPU通过系统总线->I/O桥->I/O总线通知到硬盘,
CPU让硬盘把相关的数据加载到内存中。

硬盘加载到内存的速度相对于CPU来说慢的很,此时CPU可以去干一些别的事情,
等加载完毕后,通知CPU一下,让CPU来执行内存中的程序指令。
(参考自刘欣老师的码农翻身)
偏头痛杨的程序员应该知道的一些计算机&开发&网络基础知识


RAM、ROM、硬盘

RAM(内存)和硬盘(磁盘)都是计算机的存储器,用于数据的读写。
内存是半导体材料制作,硬盘是磁性材料制作。
内存的存取速度比硬盘要快的多,但是断电后数据消失,内存的容量比硬盘小。
硬盘的存取速度比内存要慢的多,但是断电后数据保留,硬盘的容量比内存大。

内存

RAM:Ramdom Access Memory(随机存取存储器)
计算机的内存储器,也就是内存(也称主存main memory),读写速度远超于硬盘。
内存是与CPU直接交换数据的内部存储器,它可以随时高速读写,
但计算机一断电or关机,数据就丢失,不能保存,内存只是一个暂存的空间。

RAM存放的都是程序运行时所需要的数据,这些数据等待&正在被CPU处理。
RAM是CPU与硬盘之前沟通的桥梁,内存中临时存储着硬盘中即将要交给CPU处理的数据。

你按CTRL+C复制的文件,也是被存储在内存中。
内存通常作为操作系统或其他正在运行中的程序的临时数据存储媒介。

硬盘上的信息永远是暂时不用的,要用吗?请装入内存!
CPU与硬盘不发生直接的数据交换,硬盘上的信息只有在装入内存后才能被处理。
内存就是存储程序以及数据的地方,比如当我们在使用world处理文稿时,当你在键盘上敲入字符时,
它就被存入内存中,当你选择存盘时,内存中的数据才会被存入硬盘。

存储机制

内存由若许多存储单元(Memory Location)组成,每个存储单元都有一个编号,这个编号被称为地址。
每个存储单元包括若干个存储元件(Memory Cell),每个存储元件可以存储一位二进制数(1或0)。

计算机的数据和指令是按内存地址存放在存储体的各个存储单元中,
通常一个存储单元由8个存储元件组成,可以存放一个字节(8位二进制数)的数据。

随机访问

随机访问是当存储器中的信息被读取或写入时,所需要的时间与这段信息所在的位置无关。
相对的,存取顺序访问(Sequential Access)存储设备中的信息时,
其所需要的时间与位置就会有关系,例如磁带。

电脑休眠

如果在关闭电源以后RAM中的数据也不丢失就好了,
这样就可以在每一次开机时都保证电脑处于上一次关机的状态,而不必每次都重新启动电脑,
重新打开应用程序了。但是RAM要求不断的电源供应,那有没有办法解决这个问题呢?
随着技术的进步,人们想到了一个办法,即给RAM供应少量的电源保持RAM的数据不丢失,
这就是电脑的休眠功能。

虚拟内存

许多计算机支持虚拟内存机制,该机制使计算机可以运行大于物理内存的程序,
方法是将正在使用的程序放入内存取执行,而暂时不需要执行的程序放到磁盘的某块地方,
这块地方成为虚拟内存,在linux中称为SWAP,这种机制的核心在于快速地映射内存地址,
由CPU中的一个部件负责,称为存储器管理单元(Memory Management Unit MMU)。

硬盘(Hard Disk Drive)

硬盘是电脑主要的存储媒介之一,用于计算机存储数据,计算机断电&关机后,数据也能继续保存。
硬盘可以安装不同的软件、程序、游戏等等,还可以存储照片、电影、文本等等。
硬盘和磁盘在我这里可以理解成是一个东西(差异性可以忽略不计),
硬盘是长时间存储数据的设备,其读写速度虽然比内存慢得多,但容量大。
硬盘也可以作为虚拟内存使用。

ROM:Read Only Memory(只读存储器 )

是一种只能读出事先所存数据的固态半导体存储器,
其特性是一旦储存资料就无法再将之改变或删除。
断电后信息不丢失,存取速度很低(较RAM而言)。
它只能读出信息,不能写入信息,由于不能改写信息,不能升级。
一般用它存储固定的系统软件和字库与计算机启动用的BIOS芯片,计算机启动的引导程序等。

注意事项

  1. 计算机中,ROM和硬盘是两个完全不用的概念,有很多人混淆概念,认为ROM就是硬盘。
  2. ROM是内存的一种,ROM只是很小的一部分。
  3. 内存一般采用半导体存储单元,包括随机存储器(RAM),只读存储器(ROM),以及高速缓存(CACHE)
  4. ROM一般用来在计算机通电后启动电脑。
  5. 手机中的ROM和计算机中的ROM的概念也不一样!

什么是手机&平板电脑中的RAM与ROM?

运行内存=RAM,它可以随时读写,而且速度很快,
通常作为操作系统或其他正在运行中程序的临时数据存储媒介(相当于电脑内存)。

手机内存=ROM,ROM的功能用于长时间存储资料和媒体文件,
安装手机系统和一些应用程序等(相当于电脑硬盘)。
现在手机或平板电脑厂商内置的ROM存储空间很快会被用户的缓存的大量视频、照片和音乐占满。

所以我们看到iPhone 6S内置2GB RAM才是正确说法,而不是2GB ROM。
方法是将正在使用的程序放入内存取执行,而暂时不需要执行的程序放到磁盘的某块地方,
手机ROM指机身存储内存,iPhone 6S的起步内存容量是16GB ROM。


网卡

网卡是计算机网络中最重要的连接设备,计算机主要通过网卡连接网络。
网卡是工作在数据链路层的网络组件(后面有讲什么是链路层),
是网络中连接计算机和传输介质的接口。

网卡不仅能实现与网络传输介质之间的物理连接和电信号匹配,
还涉及帧的发送与接收、帧的封装与拆封、介质访问控制、
数据的编码与解码以及数据缓存的功能等。

市面上有千兆网卡,万兆网卡,不同类型的网卡的带宽也限制了计算机的网络吞吐量。

网卡的主要作用

  1. 将计算机的数据封装为帧,并通过网线或WIFI将数据发送到网络上去;(后面会讲到帧)
  2. 接收网络上传过来的帧,并将帧重新组合成数据,发送到所在的计算机中;

网卡的MAC地址

每个网卡都有一个全球唯一的地址,类似于F2-A9-63-32-DE-01。
当一台计算机不止有一个网卡时,MAC地址就不能唯一对应一台计算机了。
例如:一台计算机装了2个网卡,一个是用于该计算机与外界通信,
而第二个网卡则用来公司内部局域网通信。
这时候虽然有两个MAC地址,但是其实是同一台计算机。

ping命令

ping命令可以检查网卡工作
ping本机IP,ping不通,则表示网卡有故障。
ping远程IP,ping不通,可能是网线&网络问题,或对方已经关机,或防火墙禁止ICMP协议等。
ping域名,查看域名对应的IP地址,即解析DNS服务以及响应时间。


操作系统

操作系统也是程序的一种,如果没有操作系统,我们将无法真正意义上的使用计算机。
操作系统用来管理计算机硬件与软件资源,
如:内存、硬盘、网络、进程、安全、驱动、资源优先级、输入输出设备、文件系统等等。

常见的操作系统有:Windows、Linux、Mac。

编程语言&硬件&操作系统的关系

编程语言是让计算机能识别的语言,编程语言也是程序员与计算机沟通的桥梁。

当已经在计算机上安装了操作系统后,那么就不需要考虑控制计算机的硬件了,
只考虑用户软件与操作系统之间是否兼容。

当软件安装到永久保存的硬盘上面,
运行软件时,会先从硬盘中找到这个软件的启动文件,然后CPU通过内存来从硬盘中读写程序。

用编程语言来编写应用程序的,但计算机的硬件却是按照机器码指令来执行操作的。
用户如何才能用高级语言来指示一台只能识别机器码指令的机器来工作?
显然,在高级语言程序和机器硬仵之间,
必须有一个中介来完成高级语言与低级语言的对接工作,这个中介就是操作系统。

高级编程语言不会操作硬件,而是通过操作系统来操作硬件,不然程序员就会累死。
因为程序员需要了解所有的硬件知识,否则不能进行编程,编程的难度会陡增。


网络协议

网络协议是通信计算机双方必须共同遵从的一组约定。
例如怎么样建立连接、怎么样互相识别等,只有遵守这个约定,计算机之间才能相互通信交流。

网络是一个信息交换的场所,
所有接入网络的计算机都可以通过彼此之间的物理连设备进行信息交换,
这种物理设备包括最常见的电缆、光缆、无线WAP和微波等。

但是单纯拥有这些物理设备并不能实现信息的交换,信息交换还要具备软件环境,
这种“软件环境”是人类事先规定好的一些规则,被称作“协议”,
有了协议,不同的电脑可以遵照相同的协议使用物理设备,并且不会造成相互之间的“不理解”。

传送协议也存在于计算机的其他形式通信,例如:面向对象编程里面对象之间的通信;
操作系统内不同程序之间的消息,都需要有一个传送协议,以确保传信双方能够沟通无间。
例如分布式架构的RPC协议。

最常见的协议就是TCP/IP协议了,作为互联网的基础协议,没有它就根本不可能上网。

HTTP协议

HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。
HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传送协议,
它可以使浏览器更加高效,使网络传输减少。

HTTP是一个应用层协议,基于请求/响应范式,是一个标准的客户端-服务器模型。

大家访问的baidu.com就是向baidu的服务器发送了一个http请求,http协议是一个高层协议,
由下面的tcp/ip协议等负责去路由+握手+传输数据。

baidu的服务器得到了这个请求后,会进行一系列的逻辑,最后返回给浏览器一个应答,
浏览器会将应答信息翻译成大家能看到的页面。

TCP协议

TCP协议是传输层协议,主要解决数据如何在网络中传输,
而HTTP是应用层协议,主要解决如何包装数据。

我们在传输数据时,可以只使用(传输层)TCP协议,但是那样的话,如果没有应用层,
便无法识别数据内容。
TCP协议常与IP协议一起使用,TCP负责传输,IP负责路由。

如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,
比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。

传输层主要有2种协议:
TCP协议:送信息以后,有机制确认信息是否安全到达,速度较慢;
UDP协议:发送以后就不管了,不去确认信息是否到达,速度较快;

IP协议与IP地址

IP协议为计算机网络相互连接进行通信而设计的协议,主要负责路由和连接。
它是能使连接到网上的所有计算机网络实现相互通信的一套规则,
规定了计算机在因特网上进行通信时应当遵守的规则。
任何厂家生产的计算机系统,只要遵守IP协议就可以与因特网互连互通 。

IP地址是指互联网协议地址(Internet Protocol Address,又译为网际协议地址),
是IP Address的缩写。

IP地址是IP协议提供的一种统一的地址格式,
它为互联网上的每一个网络和每一台主机分配一个逻辑地址,

IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。
IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。
例:点分十进IP地址(100.4.5.6),

实际上是32位二进制数(01100100.00000100.00000101.00000110)。
IP地址又称为软件地址, 存储在计算机的存储器上, IPv4地址为32位, IPv6地址为128位。

IP地址&MAC地址

网络层及以上使用IP地址,数据链路层及以下使用MAC地址。
IP地址是逻辑地址,MAC地址是物理地址。

内网IP&外网IP

内网IP指局域网中的IP,通过内网IP,同在一个局域网内的计算机可以进行通信,
一般在网络应用的服务器中,都是使用内网IP进行通信,网络阻塞较小。

外网IP则是广域网因特网上的IP,可以让连接因特网上的计算机进行通信。
一般家里或单位会有一个路由器供许多设备上网,那么这些设备所共享一个外网IP,
但每个设备都会有自己的内网IP。

端口

"端口"是英文port的意译,可以认为是设备与外界通讯交流的出口。
(这里不说物理端口,只说虚拟端口)
虚拟端口指计算机内部或交换机路由器内的端口,是不可见的。

如果把IP地址比作一间大房子的地址,端口就是出入这间房子的门,
这个大房子最多可以有65536个门(即:2^16,范围是从0到65535),端口是通过端口号来标记的,
端口号只有正整数,0-1024一般是被系统使用。

例如:80端口是http默认,443是https默认,3306是mysql默认,8080是tomcat默认等等。

在Internet上,各主机间通过TCP/IP协议发送和接收数据包,
各个数据包根据其目标主机的IP地址来进行互联网络中的路由选择(请求到哪里),把数据包顺利的传送到目的主机。
操作系统都支持多程序(进程)同时运行,
那么目的主机应该把接收到的数据包传送给众多同时运行的进程中的哪一个呢?
我们需要端口来辨识。

操作系统会给那些有需求(需要被访问)的进程分配协议端口,
进程和端口是一一对应的关系,但并不是所有的进程都有端口。

当目标主机接收到数据包后,将根据报文首部的目标端口号,把数据发送到相应端口,
而与此端口相对应的那个进程将会领取数据并等待下一组数据的到来。

不光接受数据包的进程需要开启它自己的端口,发送数据包的进程也需要开启端口,
这样,数据包中将会标识端口,以便接受方能顺利地回传数据包到这个端口。

例如:
我现在有一台服务器的外网IP为:10.10.10.88,我在这台服务器上开启了2个程序。
一个是mysql数据库,端口号为3306,
一个是nginx服务器,端口号为80。

那么我的用户可以通过:
10.10.10.88:80来访问我的nginx服务器,
10.10.10.88:3306来访问我的mysql数据库。

尽量的关闭不需要开放的端口,防止攻击者扫描端口,寻找漏洞攻击。
根据提供服务类型的不同,端口一般分为两种,一种是TCP端口,一种是UDP端口。

常见端口与协议

协议名(应用层) 类型(传输层) 端口号 描述
ssh tcp 22 secure shell,安全登录
telnet tcp 23 远程登录
ftp tcp 20/21 文件传输协议,file transfer protocol,用于文件的上传和下载
dns udp 53 域名解析服务,客户端进行域名查询
smtp tcp 25 简单邮件传输协议,simple mail transfer protocol,邮件的传输
http tcp 80 超文本传输协议,hypertext transfer protocol,访问web网站
https tcp 443 安全超文本传输协议,secure hypertext transfer protocol,以加密方式访问web网站

ISO/OSI协议模型

(ISO协议模型因为比较复杂因此本章只为抛砖引玉。)
国际标准化组织(ISO)为了规范协议层次的划分制定了开发系统互联模型,即ISO/OSI参考模型。
(OSI,Open Systems Interconnection),此模型根据网络功能制定出7层网络协议结构,
由低到高分别为物理层->数据链路层->网络层->传输层->会话层->表示层->应用层。
只要遵守这个OSI标准, 任何两个系统都能进行通信。

将通信功能分为若干个层次,每一层完成一部分功能,实现相对独立的功能,
各个层次相互配合共同完成通信的功能。

每一层只和直接相邻的两层打交道,它利用下一层提供的功能,向高一层提供本层所能完成的服务。
每一层是独立的,每一层都可以采用最适合的技术来实现,每一层次可以单独进行开发和测试。

将网络体系进行分层就是把复杂的通信网络协调问题进行分解,再分别处理,使复杂的问题简化,
以便于网络的理解及各部分的设计和实现。

模拟数据&信息会在各个层中流动:
偏头痛杨的程序员应该知道的一些计算机&开发&网络基础知识
注意事项

  1. TCP/IP协议并不完全符合OSI标准定制的7层参考模型,它采用了4层的层级结构。
  2. 对于程序员来说,关心最多的应该是最高的应用层,能给用户直接使用的网络应用程序。
  3. FTP、SMTP、TELNET、HTTP这些协议都需要传输层的TCP协议来进行传输数据,
    上层协议需要遵守底层协议的规范。
    偏头痛杨的程序员应该知道的一些计算机&开发&网络基础知识
    ISO/OSI协议模型与TCPI/IP的对应关系
层级 ISO/OSI协议模型 TCP/IP
高层 应用层:http,smtp,ftp,telnet,ssh,xmpp,whois,dns 应用层
表示层:asn.1,smb,afp,ncp
会话层:tls,rpc
中层 传输层:tcp,udp 传输层
网络层:ip,arp,icmp,igmp,bgp,ipx 网络层
底层 数据链路层:以太网(ethernet),isdn,ppp(点对点),IEEE 802.11 数据链路层
物理层

封装&解封

把来自高层的数据根据本层的需要附加上特定信息(一般是添加头部与尾部)形成本层的封装单位,
然后向低层传递,同时把来自低层的数据解封装后向高层传递。
向下传递:封装;
向上传递:解封;

1.物理层(Physical Layer),单位是比特

无论是存储还是传输,都是一大串0和1的组合(比特流,让我想起了黑客帝国的画面)。
信息的传递需要一些物理媒介(不在OSI协议模型7层里),例如:同轴电缆、双纽线等。
但是\=比特流不能在真实的物理介质中传输的,而需要把它转换为光信号或者电信号。

若生产相互连接的两个设备的两个厂商都遵循相同物理层规范,则二者必定能被连接在一起,
并能接收对方发来的电、光或其他的物理信号,
而且能正确地将这些物理信号理解为二进制的0和1序列。

向上:提供给【数据链路层】比特流。
自己:进行光电信号与比特流之间的转换。
向下:提供给【物理媒介】光电信号,用于物理上的传输,只负责正确地发送比特流,并不关心这些比特的具体含义。

2.数据链路层(Data Link Layer),单位是帧

数据在这一层不再是以比特流的形式存在,而是分割成一个一个的帧再进行传输。
它依赖物理层提供的比特流把数据组织成为有边界的传输单位,称为帧。
帧使无头无尾的比特流变成容易控制的有界单位。

由于数据在这层要被分割成一个一个的帧,由于不同的链路规定了不同的最大帧长,
即MTU(最大传输单元),凡是超出这个MTU的帧都必须被分块。
例如一台货车一次能运输5吨的货物, 而有条公路限载重2吨, 那么你只好分3次运输。

前面提到的网卡在这里出场。

向上:提供给【网络层】帧。
自己:1.把【物理层】的比特流解封成帧。2.把【数据链路层】的帧封装成比特流。
向下:提供给【物理层】比特流,再通过【物理层】转换成光电信号向外发送。

3.网络层(Network Layer),单位:包(数据包&数据报)

网络层用特定的网络层地址来标识整个网络中的一个节点,
并负责使来自传输层的应该到达某个网络层地址的数据能够被送达这个网络层地址所对应的网络节点。

在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,
也可能还要经过很多通信子网。
网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送。

最典型的的网络层协议就是目前在Internet中使用的IP协议,
它使用IP地址唯一地标识Internet中的一台主机,
路由设备根据IP包中的目的IP地址将IP包一步步转发至目的主机。

向上:提供给【传输层】包。
自己:1.把【数据链路层】的帧解封成包。2.把【网络层】的包封装成帧。
向下:提供给【数据链路层】帧,再通过【数据链路层】封装为比特流,再通过【物理层】转换成光电信号发出去。

4.传输层(Transport Layer),单位:报文

本层主要是TCP与UDP协议作传输,以可靠和经济的方式,
为两个端系统(也就是源站和目的站)的会话层之间,提供建立、维护和取消传输连接的功能,
负责传输数据。

传输层向上层提供屏蔽了传输细节的数据传输,
服务将来自高层的数据进行分段并将来自低层的数据重组,
对数据传输进行差错恢复和流量控制。通过对每个网络节点的多个进程进行标识,
传输层可以实现对网络层的多路复用。

向上:提供给【会话层】报文。
自己:1.把【网络层】的包解封成报文。2.把【传输层】的报文封装成包。
向下:提供给【网络层】包,再通过【网络层】封装成帧,再通过【数据链路层】封装为比特流,再通过【物理层】转换成光电信号发出去。

5.会话层(Session Layer),单位:报文

会话层用于建立和管理不同主机的两个进程之间的对话。会话层可以管理对话,
可允许对话在两个方向上同时进行,也可以强制对话同时只在一个方向上进行。
在后一种情况下,会话层可以提供会话令牌来控制某时刻哪一方可以发生数据。
会话层还可以提供同步服务,它可以在数据流中插入同步点,
每当因网络出现故障而造成大量数据传输中断时,
通过同步点机制可以使两个进程之间的数据传输不需要从头开始,
而是从最后一个同步点开始继续传输。

会话层不参与具体的传输,它提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。
如服务器验证用户登录便是由会话层完成的。

6.表示层(Presentation Layer),单位:报文

表示层协议规定对来自应用层的数据如何进行表达,
例如采用什么样的文字编码、是否及如何进行压缩、是否及如何加密等。

这一层主要解决拥护信息的语法表示问题。它将欲交换的数据从适合于某一用户的抽象语法,
转换为适合于OSI系统内部使用的传送语法。即提供格式化的表示和转换数据服务。
数据的压缩和解压缩, 加密和解密等工作都由表示层负责。

7.应用层(Application Layer),单位:报文

应用层是ISO/OSI模型中最靠近用户的一层,应用层协议直接面对用户的需求,
例如:与发送邮件相关的应用层协议可以规定诸如邮件地址的格式、邮件内容的段落表示、
客户与服务器进行交互的命令串等。


域名

域名解析

域名解析是把域名指向网站服务器的外网IP地址。
202.108.9.16->www.163.com

让人们通过域名可以方便地访问到网站服务器一种服务。
说得简单点就是将好记的域名解析成IP,域名的解析工作由DNS服务器完成。

使用IP地址也可以访问服务器,但是没有人能记得住xx.xx.xx.xx的形式,为了简单好记,
采用域名来代替IP地址标识站点地址。

域名需要去域名运营商申请购买,国内最大是万网(已被阿里云收购),美国最大的是godaddy。
购买完成后,需要进入域名管理平台去设置A记录或CNAME等,这样域名才能被真正使用。

DNS

域名管理系统DNS(Domain Name System)是域名解析服务器的意思。
它在互联网的作用是:把域名转换成网络可以识别的IP地址,在通过IP地址访问主机。
之前有新闻报道黑客黑了DNS服务器,导致大面积的域名无法访问。

A记录

A(Address)记录是域名到ip的映射,即为ip起别名 ,同时也可以设置您域名的二级域名。
例如:
202.108.9.16->speakhi.com
202.108.9.22->test.speakhi.com

CNAME

也被称为规范名字/别名记录,可以理解成域名别名到域名的映射,即为域名起别名,
这种记录允许多个名字映射到同一台服务器。
例如:
test.speakhi.com->baidu.com
test2.speakhi.com->baidu.com

MX记录

与邮件相关的,MX记录记录了发送电子邮件时域名对应的服务器地址。

泛域名解析

泛域名解析定义为: 用户的域名aaa.com,之下所设的*.aaa.com全部解析到同一个IP地址上去。
比如客户设mail.aaa.com就会自已自动解析到与aaa.com同一个IP地址上去。


服务器

服务器分为硬件服务器,软件服务器两个维度,需要分别说明。

硬件服务器

简单的说任何一台电脑都可以成为一台硬件服务器,甚至我们的笔记本电脑也可以,
但是性能很低(cpu/内存/io/硬盘/带宽),无法承载大量的访问,
所以专业网站的服务器基本都是配置较高(根据业务的增长来判断),
并将多台服务器组合成若干个集群,并使用负载均衡来把访问压力分摊到不同的服务器上。
(也可以将不同的服务放到不同的集群中,鸡蛋不要装在一个篮子里)

软件服务器

在硬件服务器的基础上,搭建操作系统(windows/linux等),
在操作系统上搭建软件服务器(IIS/apache/tomcat/nginx/resin等),
在软件服务器上安装程序(java/php/.net等),我们的网站就是部署在软件服务器上,
之后开启软件服务器,对外提供服务,让成千上万的用户来访问。
用户的访问请求,就是请求到了我们的软件服务器中,软件服务器通过程序返回给用户应答。

软件服务器的类型

  1. web服务器/前端服务器
    主要用于解析网站中的html(静态网页),js(网页脚本),css(网页样式),
    图片,字体等文件,动态的资源请求则交给身后的tomcat集群,我们目前使用nginx,
    大幅度缓解后端服务器的压力。

  2. 应用服务器/后端服务器
    主要用于解析网站中的动态请求,需要后端程序或者数据库操作的请求,
    可以解析java程序,jsp动态页面,缓存,消息队列等等服务,是网站的核心,
    我们目前使用的是tomcat。

  3. 数据库服务器
    将业务数据保存在我们的数据库中,供程序来使用。比如用户的一次预约,
    就在在数据库的预约表中生成一条预约数据,我们在数据库中设计出表,列,库的概念,
    将业务逻辑拆分成不同的逻辑单元,我们目前使用的是mysql。

  4. 文件服务器
    负责存储图片,ppt,pdf,word文档,常用软件等文件,我们目前使用的是阿里云的oss。

  5. 缓存服务器
    将一些热点数据放到缓存中,让程序直接从缓存中获取,增加性能,减少数据库压力,
    我们目前使用的是阿里云的memcached。缓存是走内存层面,数据库是走读写硬盘。

  6. 消息队列服务器
    异步操作,分为生产者,消息队列,消费者三个概念,可以分担服务器的压力,
    为什么支付宝转账那么快,就是先把钱转给你再说,在其他的服务器集群中进行大量的运算,
    保证这次转账是正确的,以及进行大数据分析,如果转账这个操作是同步的话,
    那将会非常的慢严重降低用户体验。


分布式系统&架构

首先,我们需要明确一个概念:节点。
节点是一个笼统的概念,指服务器&虚拟机&docker容器&jvm进程,可以理解成运行程序的地方。

所谓的分布式系统,就是从很久以前把程序部署到单个节点转换成了部署在多个节点上。
随着访问量的增长,原始的ALL IN ONE的部署方式已经无法满足互联网产品的三高特性。
那我们就需要做架构层面的优化,从数据库层面,从业务层面,从运维方面,从产品层面做拆分。
盘子越大,拆的越多,这样满足三高才成为可能。

最开始的程序是所有的代码,数据库,文件等都扔在了一个节点上,
随着流量的上升需要考虑高并发,高可用。

那秉承着不要把鸡蛋放到一个篮子里,以及单机是有性能瓶颈的概念,
于是我们要把原来放在一起的东西拆出来,分门别类的部署在多个节点上,
这里还会延伸出负载均衡和集群的概念出来。

例如:有专门的数据库服务器集群,分布式缓存集群,分布式文件服务器,业务也可以拆分成多个,并部署在不同的节点上,想想当前流行的微服务。

原来的Controller,Sevice,DAO这三层都可以拆,然后部署在多个节点上。
综上所述,把程序各种拆,这就是分布式系统。

以前AController调用AService是在一个JVM进程里,使用分布式系统后,就要跨进程调用,
利用类似于RPC或HTTP REST的方式调用,需要使用类似于Dubbo或Spring Cloud这种框架。


软件环境

开发环境

供前后端工程师进行编码时使用的环境,一般都是使用自己的电脑,配置较低,
只为将开发出的代码能看到效果,这里是最新的版本。

测试环境

供测试工程师使用,内部演示以及内部员工测试使用的平台,性能较低,
测试环境的配置更接近于生产环境,
防止有些bug在开发环境中测试不出来的窘境,这里的版本要比开发环境低。

预上线环境/仿真环境

在测试工程师测试完毕后,产品经理需要在该环境上验收,以及测试工程师做冒烟测试。
数据全部使用生产环境的数据,性能较低,比测试环境更接近生产环境,除了性能以外。
也可以没有这个环境,直接从测试环境跳到生产环境。

生产环境

所谓生产,就是生产业务数据,开放给真实用户的真实环境,
生产环境下的服务器各项配置与资源分配都比前三个环境要高很多,这里的版本要比测试环境低。


PV、UV、IP

这三个概念均为衡量一个互联网产品规模的指标,也是找投资拉风投的一个point。
例如google的日均pv可以高达130亿左右,而百度的日均pv则是20亿左右,可见两者的规模差距。

PV

page view,浏览量。页面的浏览次数,衡量网站用户访问的网页数量,
用户每打开/刷新一次页面就记录一次,多次打开会累计。

UV

unique visitor,独立访问者。00:00——23:59,
也即1天内某站点的访问人数(以cookie为依据)。
一天内同一个访客的多次访问只记为1个UV。

IP

独立ip地址,指1天内使用不同ip地址的用户访问网站的数量,同一IP无论访问几个页面,
独立IP都只记为1。
说明:一个访客(使用一个账号)使用多个设备(网络)访问会算为多个IP,
同一个IP使用不同账号会算为多个UV。
IP侧重于反应网络地址的差异,UV侧重于反应访问者的差异。


单点登录

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。
SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

当用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系统中进行登录;
根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,
应该返回给用户一个认证的凭据token;

用户再访问别的应用的时候,就会将这个token带上,作为自己认证的凭据,
应用系统接受到请求之后会把token送到认证系统进行校验,检查token的合法性。
如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。


进程、线程

每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。
进程也可能是整个程序或者是部分程序的动态执行。
线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。
也可以把它理解为代码运行的上下文。

所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。
通常由操作系统负责多个线程的调度和执行。

多线程是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率。
线程是在同一时间需要完成多项任务的时候被实现的。


Cookie&Session

Cookie和Session都为了用来保存状态信息,都是保存状态的机制,
它们都是为了解决HTTP无状态的问题而所做的努力。

Cookie和Session的不同点

  1. Cookie将状态保存在客户端(默认在本地的硬盘里),Session将状态保存在服务器端;
    (默认在tomcat的内存中,当然tomcat自己也有机制会往硬盘里放,session.ser。
    也有童鞋使用组件放到分布式缓存里的)

  2. 网络服务器用HTTP头向客户端set-cookie,在客户终端,浏览器解析这些cookie并将它们保存为一个本地文件,
    保存在客户端本机的硬盘里,它会自动将同一服务器的任何请求缚上这些cookie。

  3. Session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪个用户session变量。

  4. session比cookie更安全些。

Session的实现方式有两种

1.使用Cookie来实现
1.1浏览器第一次请求是不带sessionId的。

1.2第一次请求成功后,tomcat首先检查这个请求里是否已包含了JSESSIONID,
如果已包含一个JSESSIONID则说明以前已经为此浏览器创建过session,
tomcat就按照JSESSIONID把这个session检索出来使用(如果检索不到,可能会新建一个),
如果客户端请求不包含JSESSIONID,
则tomcat自动为此客户端创建一个session并且生成一个与此session相关联的JSESSIONID,
tomcat会把session信息存储在内存中。
tomcat自动在响应消息中用Set-Cookie头将cookie的内容回送给浏览器,
浏览器把JSESSIONID保存cookie中(本地磁盘)。
(JSESSIONID的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串)

1.3浏览器自动在后面新的请求中将刚才的JSESSIONID携带在Cookie头中发送给tomcat,
tomcat通过JSESSIONID在内存中找到这个客户端对应的Session内容,从而实现会话的保持。
偏头痛杨的程序员应该知道的一些计算机&开发&网络基础知识

2.使用URL回显来实现
URL回写是指tomcat在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,
这样客户端点击任何一个链接都会把JSESSIONID带回tomcat。如果直接在浏览器输入服务端资源的url来请求该资源,
那么Session是匹配不到的。

tomcat对Session的实现,是一开始同时使用Cookie和URL回写机制,如果发现客户端支持Cookie,
就继续使用Cookie,停止使用URL回写。如果发现Cookie被禁用,就一直使用URL回写。


云服务&云计算供应商

BAT的百度云,阿里云,腾讯云,微软的Azure,亚马逊的AWS等等。

阿里云,阿里巴巴集团旗下云计算品牌,全球卓越的云计算技术和服务提供商。
阿里云致力于为企业、*等组织机构,提供最安全、可靠的计算和数据处理能力,
让计算成为普惠科技和公共服务,为万物互联的DT世界,提供源源不断的新能源。

我们现在所有的服务器产品都是购买自阿里云,阿里云提供了一整套web应用的解决方案,
大幅度减轻我们自建服务器的工作量。


其他术语

bug

非正常现象,功能缺陷,问题,有些bug会死人,有些bug不痛不痒,允许带bug上线。

单元测试

将自己写的功能,自己跑一遍,不参杂别人的业务逻辑。

版本

每次发布到线上的东西,都会增加版本号以便于管理版本,以及版本回退。

迭代

第一版会很low,第二版比第一版强,第三版比第二版强。

负载均衡

在互联网高速发展的时代,大数据量、高并发等是互联网网站提及最多的。
如何处理高并发带来的系统性能问题,
最终大家都会使用负载均衡机制。它是根据某种负载策略把请求分发到集群中的每一台服务器上,
让整个服务器群来处理网站的请求。

集群

用N台服务器构成一个松耦合的多处理器系统(对外来说,他们就是一个服务器),
它们之间通过网络(内网)实现通信。让N台服务器之间相互协作,共同承载一个网站的请求压力。


总结

我们聊了包括计算机硬件的一些基础,以及网络方面的一些知识,
希望大家可以即时总结复盘自己的知识体系,让自己在web的路上越走越远。