1. 前言
本篇在知识覆盖完整度上可能不如网上一些高质量的面试题整理,但是可以保证解答文本的简明扼要,容易理解记忆,可以结合较全的整理使用。
2. OSI 7层协议栈
名称 | 描述 | 常见协议 | 标识方法 | 报文 |
---|---|---|---|---|
应用层 | 应用间的通信 | HTTP SMTP FTP DNS | / | HTTP请求/响应报文 |
表示层 | 数据的编解码,加解密 | JPEG,MPEG | / | |
会话层 | 会话的创建、管理与终止 | SQL | / | |
传输层 | 提供端到端(忽略中间过程)的通信 | TCP UDP | 端口号 | TCP/UDP报文 |
网络层 | 提供主机到主机的通信;路由选择 | IP、ICMP;RIP路由选择协议;ARP地址解析协议 | IP地址 | IP数据包 |
链路层 | 提供网络相邻节点间的通信 | PPP | MAC地址 | 帧 |
物理层 | 比特流的传输 | / | / | / |
3. DNS
3.1. 域名服务器层次
从上到下分别是:
- 根域名服务器:知道所有顶级域名服务器的域名和ip
- 顶级域名服务器:.cn .org .com等顶级域名,知道在该服务器注册的所有二级域名和ip
- 权限(二级)域名服务器:管理二级域名下的域名和IP
- 本地域名服务器:ISP、大学等都有自己的本地域名服务器
3.2. DNS查询
3.2.1. 递归查询与迭代查询
这个概念不是非常重要,不一定需要记住这些名词。结合下一小节的详细查询过程便能体会这两种查询的定义。
DNS查询分为递归查询与迭代查询两种。递归查询即服务器层层向下查询,再层层向上返回,查询者只需要一次请求;迭代查询指查询的服务器返回的结果既可能是域名映射关系,也可能是知道该域名映射关系的另一个DNS服务器,需要查询者再次向另一个服务器发送请求,直到查询到结果为止。
一般而言,客户端设置使用的DNS服务器都是递归查询;而DNS服务器之间的查询是迭代查询。
3.2.2. DNS查询过程
浏览器输入网页后,DNS查询的顺序如下:
查询本地host文件 -> 本地DNS缓存 -> 设置的首选DNS服务器,即本地DNS服务器 ->
本地DNS服务器若负责解析该域名,或是已缓存了该域名则直接返回ip;否则需要开始向其他DNS服务器查询。到这一步骤时,本地DNS服务器的行为会根据设置分为转发模式和非转发模式两种。
- 非转发模式:本地DNS直接查询根DNS服务器,根服务器返回对应的顶级域名服务器地址;本地查顶级域名服务器获取权限域名服务器地址;本地最后查权限域名服务器获取IP,即层层向下查询
- 转发模式:本地DNS服务器向上一级DNS服务器查询,若无法解析则层层向上查询,一直到根DNS服务器;
最后,本地DNS服务器将得到的IP地址返回给客户端。
4. HTTP报文结构
4.1. 请求报文结构
请求方法、URL、协议版本、头部字段、请求体
4.2. 响应报文结构
协议版本、状态码、状态码描述、头部字段、响应体
5. HTTP状态码
状态码 | 描述 |
---|---|
100 | Continue(http1.1 以后限定) |
200 | Success 成功 |
301 | 永久重定向。新的URL在响应报文的头部字段location给出,浏览器应当自动访问新的URL |
302 | 临时重定向 |
400 | Bad Request 请求语法错误 |
401 | Unauthorized 未经授权访问受密码保护的页面,响应报文会包括一个填写用户密码的头部字段 |
403 | Forbbiden 拒绝对资源的访问 |
404 | Not Found 找不到资源 |
500 | Internal Error 服务器内部错误 |
502 | Bad gateway 服务器作为网关或反向代理,从远程服务器收到无效效应 |
503 | Service Unavailable 服务器超载或停机 |
504 | Gateway Timeout 服务器作为网关或反向代理,远程服务器应答超时 |
6. HTTP1.0和1.1区别
- 长连接:
HTTP1.1默认TCP长连接,1.0默认短连接 - Host字段:
1.1添加host头部字段且默认必须使用(否则400 Bad Request),用于处理一台服务器部署多个虚拟主机作为不同的web server,而他们公用同一个IP的情况。 - 状态码100:
1.1允许客户端发送一个不带请求体(request body)的HTTP请求包作为试探,服务器收到后若允许则返回100continue,此时客户端再发送(request body),用于减少带宽;若不允许则返回401 Unauthorized ,要求客户端进行身份验证
7. HTTP 2的区别
- 多路复用:
HTTP 1.x 的一次连接里,在收到本次请求的响应之前不能够发出新的请求。如果想并发多个请求,则必须使用多个TCP连接(且一般情况下,浏览器为了控制资源使用,会对单个域名有6-8个的TCP连接请求限制);HTTP2.0中引入了流这一概念,在一个连接上建立多个虚拟信道,每个信道作为流,代表一次完整的请求-响应过程,这样就可以允许同时通过单一连接发起多重请求-响应。每个流有唯一的整数ID作为相互区分,流内的通信单位是帧。 - 二进制分帧:
不再以文本方式发送报文,而是以二进制编码方式,解析更高效。帧的首部字段会记录所属的流,所以即使发送的帧是无序的,接收方收到数据以后也可以根据流标识进行重组 - 首部压缩:
支持压缩算法,压缩请求头,减小报文大小 - 服务器推送:
服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。
https://zhuanlan.zhihu.com/p/26559480
https://zh.wikipedia.org/zh-hans/HTTP/2
8. HTTPS
8.1. HTTP和HTTPS区别
- 端口:HTTP是80,HTTPS是443
- 安全性:HTTP无加密,是明文;HTTPS有基于非对称和对称加密机制,保证安全
- 性能:HTTPS比HTTP要占用更多的资源
8.2. HTTPS握手过程
首先进行正常的TCP三次握手;
在三次握手的最后一次握手(即Client->Server ACK)的payload中,客户端将支持的加密算法发送给服务端;
服务端选择一套客户端支持的加密算法,将CA签发的证书传递给客户端,此证书包括了服务器信息、服务器公钥和数字签名(摘要),且经过CA的私钥加密;
客户端验证CA证书是否被本地保存过的CA根证书信任。若否,弹出警告;
若是,则使用对应的CA根证书中的CA公钥对服务端发来的证书进行解密,获得服务器公钥和数字签名;使用解密得到的服务器公钥对明文部分进行哈希,将结果和数字签名进行比较。若一致,则证明证书未经篡改;
客户端生成一个对称加密用的随机秘钥,用服务器公钥加密发送给服务端。
服务端拿到报文,用私钥解密,获得对称加密用的随机秘钥。
服务端用随机秘钥发送握手结束信息给客户端。
到此正式建立连接,双方开始用随机秘钥进行对称加密的数据传输。
9. GET和POST区别
- 功能:GET是获取资源,POST是提交数据修改
- 参数的位置:GET的参数在URL中,POST的则在HTTP请求报文的请求体request body中。
- 长度限制:GET收到URL长度的限制;POST无限制
- 幂等:GET幂等;POST不幂等,在浏览器返回时,会再次提交
- 历史记录:GET由于参数在URL,会被浏览器记录;POST不会
- 缓存:GET的内容可以被浏览器缓存,POST不行
10. 短连接和长连接区别
- 短连接:CS之间每进行一次通信都建立一次连接,完成后关闭。请求频繁时,连接建立和关闭浪费大量时间。适用于WEB网站。
- 长连接:CS之间不立刻断开连接。适用于数据库,游戏服务器。
11. cookie和session
11.1. 区别
- 位置:cookie在客户端;Session在服务端
- 存储:cookie是文件的方式存储;Session是内存中存储,可以持久化到硬盘
- 持续时间:cookie过期前持续存在,有效期很长;Session一般用户关闭浏览器后就释放
- 安全性:cookie由于文件的性质,可以被其他程序读取和修改,不够安全;Session安全
11.2. 二者机制的配合
二者配合在一起可以实现在服务端和客户端保存状态。当一个新客户访问到服务端时,服务端启动session机制,生成一个sid,并在响应报文中的头部字段加入set-cookie:[sid内容],将sid传递给客户端。客户端将sid存在cookie中。在cookie有效期内,客户端再发起请求时,会在请求报文的头部字段加入cookie字段,其中就包括了sid。
11.3. 禁用cookie?
客户端禁用cookie后可以通过URL重写的方式,即在URL中加入sid=xxxx。在这种方式下,即使禁用了cookie也仍可以使用session机制保存会话状态
12. TCP和UDP区别
- 连接:TCP有连接;UDP无连接
- 可靠性:TCP有可靠性机制,无差错和丢失按序交付;UDP无,只尽力交付
- 端点数量:TCP必须一对一;UDP可以一对多(组播、广播),多对一,多对多
- 拥塞控制:TCP提供拥塞控制;UDP无
- 字节流:TCP面向字节流,有报文的最小长度单位,所以会对报文进行切分,有粘包拆包问题;UDP是面向报文的,一个UDP数据包就是一个完整的包,不存在拆分
- 双工:TCP属于全双工;UDP一般不进行双工性质的讨论,如果非要说的话也是满足全双工定义的。
此外,二者报文头长度不同。
13. TCP的握手和挥手
13.1. 三次握手
略
13.2. 初始序列号的选择
用一种哈希算法随机生成,随机因子包括时间、双方的ip、双方的端口号。随机的原因是如果网络波动,上一次连接的包延时到达下一次连接中,会导致乱套
13.3. 为什么不能是两次握手
在两次握手下,若第一次C->S的连接建立请求因为网络延迟未到达,此时C重发连接建立请求,双方完成通信后断开连接,此时第一个延迟的建立请求到达,则S会建立连接,而此连接就造成了资源的浪费
13.4. 四次挥手
略,注意分清TIME_WAIT和CLOSE_WAIT
13.5. 为什么不能是两次挥手、三次挥手?
不能是两次挥手:被动端可能还需要发数据
不能是三次挥手:若S->C的FIN+ACK包丢失,C就只能一直等,但是S已经关闭了连接。四次挥手下,若S->C的FIN+ACK丢包,S在等不到最后一个ACK包的情况下会主动重发FIN+ACK包
13.6. 为什么等待2MSL才正式关闭连接?
最主要的原因:如果C->S的最后一个ACK丢包,S会重传,此重传包的时延不超过2MSL。
次要:2MSL后此TCP连接的所有报文都会失效,防止本次会话对下次造成干扰;
14. 大量TIME_WAIT的处理方法
可以调整内核参数,允许将TIME_WAIT的socket用于建立新的连接。
15. DDoS相关
15.1. 常见DDoS分类
大量SYN(SYN FLOOD):属于传输层DDoS,挤爆服务器的半连接队列
大量长连接:属于连接型DDoS,耗尽服务器的连接队列
连接立刻关闭,再立刻开
https://help.aliyun.com/document_detail/28401.html?utm_content=g_1000230851&spm=5176.20966629.toubu.3.f2991ddcpxxvD1#title-xnq-03p-8tr
15.2. SYN Cookie
简化服务端接受SYN后的初始化连接的状态,不分配资源,推迟全状态的实例化;
以时间戳、客户端的信息做哈希得到cookie,将结果设置为S->C的SYN+ACK包的seq;
接收到C->S的ACK后,通过检查包的ACK验证cookie的正确性。若正确,再分配资源
https://baike.baidu.com/item/syn%20cookie/6898884?fr=aladdin
15.3. SYN FLOOD DDOS下,server在SYN_RECV状态下持续多久?
在TCP默认规则下,是重传5次SYN+ACK包仍无法收到ACK后关闭连接
16. TCP如何确保可靠
- 滑动窗口:构造发送和接受窗口,解决数据不按序到达的问题;发送方窗口不得大于接收方窗口,可以控制流量;接收方在窗口内采用累计确认机制;
- 超时重传机制
- 拥塞控制机制
17. TCP拥塞控制算法
17.1. 经典Reno方案
- 慢启动:窗口从1个MSS开始,指数增长
- 拥塞避免:达到cwnd以后变成加性增长
- 快速重传:发送方收到连续三次相同ACK则认为发生拥塞,立刻重传,不等超时
- 快速恢复:发生拥塞后cwnd设置为当前的一半,随后窗口设置为新的cwnd,直接进入拥塞避免阶段
传输超时时仍然采用慢启动和拥塞避免。三个连续相同ACK才使用快速重传和快速恢复
17.2. 当前linux内核默认方案
内核2.6.19(2006)版本后是Cubic。Cubic的设计背景是网络基建已经高度发达,网络带宽相比过去大幅增加,此时Reno方案中的加性增长策略就显得过于保守,在偶然的拥塞后触发拥塞避免机制,此后的发送速率增长都非常缓慢,并不能有效地利用带宽。Cubic的cwnd曲线类似三次函数,增长先慢后快,cwnd在确保脱离拥塞点后可以快速增大,更快地找到最适合当前网络环境的cwnd大小。
内核4.9(2016.2)以后是google bbr
https://cloud.tencent.com/developer/article/1482633
18. TCP定时器
常用的有这些:
连接建立定时器:c->s的SYN包时设置此定时器,默认3秒,若没有收到SYN+ACK,则重发SYN包。
重传定时器:用于超时重传
FIN_WAIT_2定时器:主动关闭一方在发送FIN、收到针对FIN包的ACK后,进入等待服务器发送最后一批数据的状态,此时启动FIN_WAIT_2定时器,用于处理网络突然崩溃等故障导致服务器无法发送FIN包的情况。超时后直接关闭连接、释放资源。
TIME_WAIT定时器:略
19. TCP的粘包拆包
19.1. 发生原因
TCP是无边界的面向字节流协议,运行时将数据放入缓冲区,缓冲满以后发送。若一个数据小于缓冲区,则会与其他数据一起发出。
19.2. 解决方案
约定数据的前X位是数据的长度;设置固定的开始/结束符。
19.3. 为什么UDP不会粘包
UDP是面向消息传输而非面向字节流,每一次发送/接受的报文都是一个完整的消息,且包含消息头(来源ip、端口等信息)作为消息的边界,所以不存在粘包问题
https://zhuanlan.zhihu.com/p/41709589
20. UDP如何实现可靠
参考TCP,发送方加入序列号;接收方会发送确认信息,采用滑动窗口、累计确认;发送方会超时重传
21. IP地址分类
- A类地址:网络号占1个字节,只有7位可用(第一位固定为0),可指派的网络号是126个:网络号全0表示本网络,网络号127保留作为本地软件环回测试。
- B类地址:网络号占2个字节,前面两位固定为10。
- C类地址:网络号占3个字节,前面三位为110。
- D类地址;前4位为1110。
22. MSS和MTU
MTU:IP数据报大小,属于网络层。其值受到链路层的条件限制,在以太网下一般是1500Bytes。
MSS:TCP最大报文长度,属于传输层,在TCP握手时协商(SYN报文中)。注意MSS是指载荷payload的大小,故一般是1500 - 40(TCP报文头最大40)=1460Bytes
23. 路由选择算法
RIP路由选择协议:临近路由器之间交换路由表,若发现相邻路由器到某目标网段跃点数更小,则将路由目标替换为该路由器,跃点数设置为该路由器传递的路由表中对应项的跃点数+1.
局限性:好消息传播快,坏消息(节点故障)传播慢
https://zhuanlan.zhihu.com/p/488001974
24. ICMP
因特网控制报文协议(Internet Control Message Protocol,ICMP),是TCP/IP协议簇的一个子协议,其报文作为IP数据报的payload。ICMP用来判断网络可达性和进行链路追踪,常用的ping命令就是基于ICMP实现的,还有进行链路追踪的traceroute命令(打印出到达目标主机之前经过了哪些路由器)。
在ping命令下,源主机向目标主机发送ping请求报文,若能够在一定时间内收到ping应答报文,则判断目标可达。
https://blog.51cto.com/u_14607063/4672033
https://blog.csdn.net/qq_34816080/article/details/90734231
25. ARP地址解析协议
介于网络层和链路层之间,实现IP地址到MAC地址的转译。各机器本地有ARP缓存,若缓存没有所需的转换,则在局域网内广播,收到广播信号的目的主机发送应答报文。
26. 输入网址到看到网页的全过程
DNS解析(host->本地DNS缓存->本地域名服务器->根域名服务器->顶级域名服务器->二级域名服务器)
建立TCP连接,三次握手
HTTP request作为握手的C->S ACK报文发出
获得响应报文,本地渲染网页
27. 反向代理服务器与网关服务器
反向代理服务器和网关服务器(更准确地,指API网关服务器)作为一个统一的入口,接收来自客户端的请求,并将不同的请求发送到不同的应用服务器上;应用服务器处理完后,将响应通过反代/网关服务器发送给客户。设立反向代理/网关的好处主要分为以下几种:
- 隔离:外部无法直接访问内网服务器;
- 解耦:各个应用服务器处理各自的业务;此外,还可把需要承载高并发、高性能任务的网络服务独立出来;
- 健壮:一个应用服务挂了不影响其他;
- 负载均衡:在有应用集群的情况下,可以把请求发往负载低的服务器。
至于二者的区别,可以参考这个解答。简而言之,API网关可以视为反向代理服务器的扩充版本。
业界常见的例子有:NGINX流行的代理或反向代理服务器;Zuul,流行的API网关服务器,广泛用于各种微服务架构。
题外话引申:HTTP状态码502 bad gateway,反代/网关返回了无效信息;504 gateway timeout 反代/网关响应超时
28. 单台服务器可以维护多少连接?
端口号范围是0~65535,但是0~1023是系统保留端口,所以理论上是65536 - 1024个
29. http keep-alive/ tcp keep-alive有什么区别?
http keep-alive,服务端和客户端协商好,连接不关闭,可以继续使用。
tcp keep-alive,由操作系统自己去维活,超过一段时间回收。