计算机网络作为程序员面试的基本题目,在回答面试官问题的时候不仅要抓住重点,还要回答出面试官的扩展问题。参考程序员(尤其是后端程序员)各大佬分享的面经,我们可以发现计算机网络的考查点主要分布在应用层、传输层以及网络层,因此本文主要围绕这三层中的协议进行总结。
本文参考了大量的文章,形成了自己对计算机网络常见重要知识点的理解,这也是我写本文的初衷。如有表述不当之处,欢迎指正。
1、网络分层模型篇
1.1计算机网络可以划分成几层,各层的作用是什么。
计算机网络的模型有三种:7层架构的OSI模型,4层架构的TCP/IP模型,以及融合OSI模型与TCP/IP模型特点的网络5层模型。
经常使用的是5层模型,各层从上到下分别为应用层、传输层、网络层、数据链路层和物理层。
应用层:通过应用进程之间的传输报文
传输层:通过进程ID在进程之间的传输报文段
网络层:通过IP地址在客户端和服务端之间的传输IP数据报
数据链路层:通过MAC地址在两个确定的物理主机之间传输数据帧
物理层:传输比特流
1.2URI与URL的区别
URI:统一资源标志符,用于唯一标识一个网络资源
URL:同一资源定位符,标识一个资源的访问路径
1.3在浏览器中输入URL到显示网页的过程
浏览器先去本机中查找URL对应的IP地址,如果没有则发送DNS请求去DNS服务器中寻找对应的IP地址,得到IP地址后进行TCP三次握手建立连接,连接建立完成后,浏览器向服务器发送http请求,服务器收到之后返回http响应,浏览器收到之后就显示出对应的资源页面。
本题还可以从5层模型的角度去详细解答,本文已经形成了一个大致的回答思路。
2、应用层篇
应用层常考的协议有HTTP、HTTPS、DNS等,其他应用层协议有FTP、DHCP等。
2.1HTTP0.9、HTPP1.0、HTTP1.1与HTTP2.0的发展历程
HTTP0.9:
只有get请求
服务端只能返回html页面
请求处理完毕就自动释放TCP连接
HTTP1.0:
新增了POST、PUT等请求方式
支持图片、视频、文字等富文本传输
新增了缓存功能,HTTP请求先进入缓存中再依次被服务端响应
新增了HTTP header、状态码等功能
仍然是请求处理完毕就自动释放TCP连接
HTTP1.1:
增加了多种缓存机制
增加了状态码与请求方式
在header中引入rang域,支持只请求某资源的一部分,这样便于充分利用带宽和连接。
新增了connection: keep-alive,支持一个TCP连接处理多个HTTP请求,当要关闭TCP连接时,客户端向服务端发送一个connection: close即可。同一个域上长连接维持的请求个数是有限制的。
请求无法并行发送,由于HTTP是一种无状态协议,它无法知道某一个响应究竟对应了哪一个请求,因此建立了长连接之后必须要等待上一个请求的响应结束才能发送一个新的请求(不能无序传输)。解决方法:HTTP请求有序传输,但是可能会造成首行阻塞(第一个HTTP请求响应时间过长的话就会将后面的请求阻塞住)可能引起缓存溢出。
HTTP2.0:
二进制传输数据。在1.X时header中采用文本传输,body中采用文本或二进制传输,为了更好的扩展性和提高性能,2.0中全部采用二进制传输。
多路复用,搭配数据流真正实现了请求和响应并行发送
头部压缩,客户端和服务端分别维护一张表,实现已经发送过的头部信息不用再次发送
服务端主动推送,服务器收到请求后可以将与请求相关的响应资源发给浏览器,减少了HTTP通信的次数。只对第一次访问网站的用户开启服务器推送,以避免本地缓存中已经存在引起带宽浪费。
数据流(帧),可以标记请求与响应之间的对应关系,因此可以无序传输
2.3HTTP中get请求与post请求的区别
get请求会将请求参数直接添加到URL的后面,对用户直接可见;而post请求是将参数放到请求体中。浏览器一般会限制URL的长度,因此可能会对get请求造成影响。
get请求会被浏览器主动缓存,而post不会
get请求是发送一个TCP数据包,而post请求是将header和body分别当成一个tcp数据包发送。
扩展问题:put请求与post请求的区别
使用put请求,在遇到两个相同的请求时(两次发送的是同一个请求),后一个请求会把前一个请求覆盖掉;而使用post时不会进行覆盖。
2.4Cookie、Session、Token、JWT的区别
Cookie由服务器生成,发送给浏览器,浏览器把Cookie以K-V的形式保存到某个目录下的文本文件内,cookie中可以包含用户访问网站的身份信息等,下一次请求同一网站时会把cookie附加到header中发送给服务器,服务器拿到cookie之后就会直接给浏览器返回身份验证之后的网页。
Session,在用户第一次访问服务器时,服务器就使用session把用户信息临时保存在了服务器上,并给浏览器返回一个sessionID,浏览器拿到这个sessionID后,会将一个键值(tomcat中默认是"JSESSIONID")与这个sessionID值封装成cookie的键值对(这是保存在浏览器的临时内存中的,而非硬盘),当用户再次发送一个请求时会将这个cookie附带在header中,服务器通过提取cookie中的sessionID进行比对就能知道这个用户是不是同一个用户。服务器session超时或者用户离开网站后session会被销毁(如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失)(如果浏览器禁用了cookie,则可以通过重写URL来使用session)
Token,用户第一次访问服务器时,服务器会将用户信息做成不重复的字符串作为token,并将它返回给浏览器,服务器也会保留一份到redis中,浏览器拿到token后将它保存到本地,下一次访问服务器时再header中携带上token,服务器拿到token之后,就去redis中查找是否存在这个token,如果存在则身份验证成功,用户信息是保存在Token中的。
JWT,它由Token和数字签名组成,用户第一次访问服务器时,服务器将用户信息进行加密得到一个字符串token,并将这个Token用公钥进行加密得到一个数字签名signature,将Token和signature一起返回给浏览器,浏览器将它们保存到本地,再次访问时就将他们附带在请求报文中,服务器接收到请求后用私钥来解密这个Token,并将解密得到的签名与请求报文中的数字签名signature进行对比,如果有效则验证成功。(加密Token使用到了非对称加密)
Cookie与Session的区别
cookie是保存在客户端中,而session是保存在服务器内存中的
单个cookie中保存的数据不能超过4kb,而session可保存的数据远高于cookie
cookie只支持字符串类型的数据,而session可以存任意类型的数据
cookie可以一直保存在客户端中,而session是有有效期的
2.5HTTPS与HTTP的区别
HTTPS是基于SSL/TLS的HTTP协议,它通过对传输过程进行加密实现安全传输,而HTTP是明文传输的,容易受到中间人攻击。
HTTPS的默认端口是443,HTTP的默认端口是80。
2.6介绍非对称加密与对称加密
对称加密:加密和解密都采用公钥
非对称加密:加密采用公钥,解密采用私钥
2.7HTTPS是怎么保证安全传输的
对称加密算法适用于加密数据量偏大的内容,而非对称加密算法适用于小数据量的内容,所以使用对称加密算法加密传输内容,并使用非对称加密算法加密传输内容的秘钥。
需要通过HTTPS访问的进程所在的服务器中保存了由数字认证中心(CA)颁发的数字证书以及对应的私钥,数字证书中包含了公钥和数字签名签名,如果数字签名发生了改变就意味着证书遭到了篡改。
加解密过程如下:
1)浏览器向服务器发送请求时,服务器会给浏览器发送它的证书(私钥是保存在服务器中的,不下发)。
2)浏览器拿到证书后,进行验证,验证成功后就会用公钥生成一个秘钥X,然后将秘钥X发送给服务器。
3)服务器拿到秘钥X后,会用私钥去解密传过来的秘钥X,通信双方都采用秘钥X对传输内容进行加解密就实现了安全通信。
如果有中间人攻击,由于中间人拿不到私钥,就无法得到有公钥生成的秘钥X,进而无法对传输内容进行解密。
这里可能存在的情况是如果证书不可信的话,仍然存在安全问题。中间人拿到公钥A后,把伪造的公钥B传给浏览器,浏览器生成一个秘钥X,中间人用公钥B对应的私钥来得到秘钥X,再把秘钥X用截取到的公钥A加密并传给服务器。这样中间人就得到了秘钥X,因此必要要验证证书可信,在此不做赘述。
参考:https://zhuanlan.zhihu.com/p/43789231
2.8DNS的IP解析过程简介
域名服务器按层级划分为根域名服务器、顶级域名服务器、权限域名服务器。
在浏览器中输入域名后,客户端会先去本地域名服务器中寻找对应的IP地址,如果本地域名服务器中没有,则依次去根域名服务器、顶级域名服务器、权限域名服务器中寻找。
或者委托上层域名服务器去下层域名服务器中寻找,找到之后再依次返回到客户端。
2.8DHCP的作用
IP地址可以划分为动态IP和静态IP,对于具有特定功能的服务器而言常采用静态IP,即IP地址固定不变,通常情况下网络设备都是动态IP地址。
DHCP服务器就是用来为进入对应网段的网络设备分配动态IP的,他采用的DHCP协议是一种基于UDP的应用层协议。
3、传输层篇
3.1UDP与TCP的区别
是否面向连接 | 是否可靠 | 传输形式 | 适用场景 | |
---|---|---|---|---|
TCP | 面向连接(一对一) | 可靠 | 面向字节流 | 有可靠性要求的场景,如文件传输 |
UDP | 无连接(一对多,多对多,一对一) | 不可靠 | 面向报文 | 实时通信的场景,如视频会议、直播等 |
是否面向连接:在发送数据前是否要先建立连接,TCP在数据传输前要进行三次握手,而UDP没有,即采用UDP通信的发送方会向接收方发送数据,即使发送方发送的数据发生了丢失也没有关系。
是否可靠:是否会发生数据丢失现象。UDP是没有流量控制的,当接收方缓存区已经满了,而发送方还要继续发送数据的话,就会造成数据丢失。
传输形式:TCP是将应用层报文划分成报文段进行传输,接收方会按照编号对报文段进行排序,而UDP是直接传输整个报文。
3.2TCP三次握手及状态
在客户端与服务端建立连接之前,服务端一直处于LISTENING状态,监听TCP连接请求。
第一次握手:客户端向服务端发送一个SYN寻求建立连接,发送之后客户端处于SYN_SENT状态。
第二次握手:服务端收到SYN后,向客户端发送ACK(确认建立连接)和SYN(连接请求),发送之后,服务端处于SYN_RECV状态。第二次握手之后服务器为TCP分配资源(单向连接已完成)。
第三次握手:客户端收到服务端发送过来的SYN和ACK后,向服务端发送一个ACK,此时客户端状态变为ESTABLISHED。服务端没有收到客户端返回的ACK的话服务端就继续向服务端发送SYN和ACK,直到服务端收到了ACK,服务端的状态才变为ESTABLISHED。第三次握手完成之后客户端为TCP分配资源。
3.3SYN攻击及解决方法
SYN攻击:攻击人用伪造的IP地址给服务端发送一个SYN,服务端收到之后返回一个SYN和ACK,并为TCP连接分配资源,但是在第三次握手中由于IP地址都是伪造的客户端根本就返回不了ACK,使得TCP处于半连接状态,服务端收不到客户端发送的ACK还会继续向客户端发送SYN和ACK。如果这种半连接的状态过多,就会造成很大的资源浪费。
SYN解决方法:在服务器端监控处于半连接的TCP,超过一定时间后直接释放资源。或者当TCP三次握手完成后才为服务器端分配资源(SYN Cookie和SYN Cache)
3.4TCP四次挥手及状态
(以客户端首先先服务端发出关闭连接的请求为例)
第一次挥手:客户端发送一个FIN给服务端,客户端进入FIN_WAIT_1状态
第二次挥手:服务端收到FIN之后发送一个ACK给客户端,服务端进入CLOSE_WAIT状态,客户端接收到ACK后进入FIN_WAIT_2状态。(半关闭状态)
第三次挥手:服务端发送一个FIN给客户端请求关闭连接,服务端进入LAST_ACK状态。
第四次挥手:客户端收到FIN后,给服务端返回一个ACK,客户端进入TIME_WAIT状态。服务端接收到ACK后进入CLOSED状态,TIME_WAIT结束后客户端也进入CLOSED状态(如果服务端重新给客户端发送了FIN,客户端收到后会重新进入TIME_WAIT状态)
3.5最后一次挥手后为什么要等待2MSL之后主动关闭方才释放资源
MSL指报文在网络内的最大生存时间,超过这个时间网络中的报文将被丢弃。
第四次挥手中如果客户端向服务端发送的ACK丢失了,超过一定时间后服务端还是收不到ACK就会重新向客户端发送FIN,如果此时客户端已经释放了资源那么就无法给服务端返回ACK了,因此客户端要等待一定时间后才释放资源。
第四次挥手中如果客户端向服务端发送的ACK丢失了,超过一定时间后服务端还是收不到ACK就会重新向客户端发送FIN,如果此时客户端已经释放了资源那么就无法给服务端返回ACK了,因此客户端要等待一定时间后才释放资源。
2MSL是第四次挥手中ACK从客户端到达服务端,然后第三次挥手中FIN从服务端到达客户端的最大时间。
3.6TCP是怎么保证可靠传输的
TCP是一种可靠的传输层协议,它主要通过四个方面来保证可靠传输:校验和、序号、确认、重传。
校验和:计算首部校验和是否相同以判断报文段是否发生了变动,由发送端计算然后接收端验证,如果验证不同则直接丢弃该报文段。
序号seq:用于标识报文段的编号
确认号ack:接收方接收到报文段之后会返回一个确认号ack=seq+1,发送方收到ack后就可以把ack之前的报文段从发送缓存窗口中删除。发送方接收到的ack说明接收方已经接收到了ack之前的所有数据。
TCP采用累积确认机制,发送方发送报文段的时候不必等到上一个报文段的确认号收到之后才发送,即可以连续发送。如果接收方没有接收到某一个报文段,就返回该报文段的ack,这个ack是从第一个报文段开始没有被接收到的报文段的ack。
重传机制:超时重传,如果发送方超过一定时间还没有接收到接收方的确认就重新发送该报文段,TCP采用自适应算法动态改变重传时间RTTS(加权平均往返时间)。快速重传,在超时时间之前就重传的机载(冗余ack),发送方如果收到了3个冗余的ack就重新发送该ack对应的报文段。
参考资料:https://www.bilibili.com/video/BV19E411D78Q?p=67&spm_id_from=pageDriver
3.7TCP是怎么实现流量控制的
TCP采用滑动窗口实现流量控制,接收方根据自己接收缓存的大小动态调整发送方的发送窗口大小,当接收方向发送方发送确认信息时同时也会将一个窗口值rwnd返回给发送方,发送方就会根据这个返回的窗口值调整发送窗口的大小。如果收到的rwnd为0则说明发送方停止发送数据。
可以将rwnd的值理解成接收方返回确认报文时接收缓存的剩余大小。
扩展问题:发送方收到的rwnd为0后,接收方再次给发送方发送了一个rwnd不为0的确认报文,如果这个确认报文丢失了就可能导致类似与死锁的情况,解决方法如下:
当rwnd为0时,发送方会设定一个计时器,当计时器值减小到0时则给接收方发送一个探测报文,然后判断返回报文中rwnd是否还是0,如果是0则刷新计时器重新计时,如果不是0则按照当前窗口的大小发送报文段。
参考资料:https://www.cnblogs.com/kubidemanong/p/9987810.html
3.8TCP是怎么实现拥塞控制的
拥塞控制不同于流量控制的是拥塞控制是全局性的控制,防止过多的数据注入到网络中引入网络堵塞,而流量控制是点到点的问题,是指发送方发送过快而接收方来不及接收导致丢包。
拥塞控制通过四种算法来实现:慢开始和拥塞避免、快重传和快恢复
慢开始和拥塞避免:慢开始阶段,拥塞窗口从1开始随着传输轮次呈指数规律增长,直到增长到了慢开始门限值就进入到拥塞避免阶段,呈加法增大,直到出现了网络拥塞,重新进入慢开始阶段,同时更新慢开始门限为网络拥塞时窗口大小的一半。
快重传和快恢复:收到3个冗余的ack时就执行快重传算法。执行步骤仍然为慢开始阶段、拥塞避免阶段,不同的是产生网络拥塞时窗口大小降低为新的慢开始门限值(拥塞时窗口大小的一半)。
什么时候更改拥塞窗口:发送方只要收到了确认ACK报文就更新拥塞窗口大小。值得注意的是发送方的发送窗口大小取决于接收窗口与拥塞窗口大小中的最小值。接收窗口是反映了接收方容量,而拥塞窗口反映了网络当前的容量。
传输轮次:发送方发送一批拥塞窗口内的报文段直到开始发送下一批拥塞窗口内的报文段所经过的时间。
4、网络层篇
4.1数据交换方式
网络层的数据交换方式可以分为电路交换、报文交换和分组交换,以太网技术的数据交换方式就是分组交换。
这里重点介绍分组交换,其他的数据交换方式暂且不论。
分组交换是将传输层的报文段划分成IP数据报(分组),每个分组包含了数据部分与IP首部,首部中就包含了源IP地址与目的IP地址。分组交换与报文交换(传输整个报文段)都采用了存储转发技术,每个分组在路由器节点中按照转发表选择下一跳节点。
4.2介绍常见的路由协议及其作用
因特网中使用的是分层次的路由选择协议,将路由选择协议分成内部网关协议IGP(一个AS内使用的)和外部网关协议EGP(AS之间使用的)。AS是指一个自治系统。
路由算法:路由器在使用路由协议时会根据路由算法选择出最佳路由(相对某一种特殊情况来说是最佳的),并将它填入路由表中。常说的路由算法都是指自适应路由算法,路由器之间可以彼此交换信息,并按照路由算法来动态优化路由表项。
一种常用的内部网关协议IGP是OSPF和RIP,一种常用的外部网关协议EGP是BGP。
4.3介绍ARP协议
ARP协议是通过接收端IP地址得到接收端MAC地址,这个MAC地址将被添加到数据链路层的数据帧中。
数据链路层中封装数据帧时会先从ARP高速缓存中寻找该IP地址是否有对应的MAC地址,有的话就可以直接使用,没有的话就使用ARP协议去获得对应的MAC地址。发送端会向网络中广播信息要获取某个IP地址主机的MAC地址,对应主机收到该广播信息后就向发送端返回自己的MAC地址和IP地址,如果该主机不和发送端在同一个网段内,则返回默认网关的MAC地址和IP地址,并将这个默认网关作为数据传输的下一个节点。
4.4介绍ICMP协议
ICMP协议是网络控制报文协议,主要用于当路由器接收到的IP数据报数据部分(而校验和是针对IP首部的)发生错误时向主机返回差错报告报文,比如终点不可达报文,时间超过报文(IP数据报的生存时间TTL为0),改变路由报文等。
ICMP另一种报文是询问报文,主机或路由器向特定的主机发出询问,收到此报文的主机必须返回ICMP回送回答报文。这种报文主要用来测试目的主机是否可达并了解其相关的状态。Ping命令就是基于ICMP询问报文实现的。
4.5介绍ping命令的过程
(这个过程是在网络层及以下进行的)
先封装一个ICMP请求数据报文
在ICMP报文的基础上添加IP地址封装成IP数据报
在ARP高速缓存中获取目的主机的MAC地址或者使用ARP协议获取MAC地址
获得MAC地址构建一个数据帧,并将数据发送出去
目的主机接收到数据帧后,从中提取出IP数据报,再将IP数据报中的ICMP请求报文交给ICMP协议处理并构建出一个ICMP应答报文,再返回给源主机。
参考资料:https://blog.csdn.net/guoweimelon/article/details/50859658