前言
本文是我学习《xiaolin coding 的图解计算机网络》,并在事后做题模拟面试,记录ai对我问的问题和我回答问题以及复盘的过程。说实话就是个错题本。
2.1.TCP/IP网络模型有哪几层
问题
- TCP/IP 网络模型的四层结构分别是什么?请依次说明每一层的核心职责,以及该层对应的典型协议或技术(至少列举 1 个 / 层)。
- 传输层的 TCP 和 UDP 协议存在哪些关键差异?TCP 协议的 “流量控制”“超时重传”“拥塞控制” 这三个特性,分别是为了解决数据传输中的什么问题?
- 什么是 MSS(TCP 最大报文段长度)和 MTU(最大传输单元)?TCP 分段和 IP 分片分别在什么场景下触发?二者的本质区别是什么?
- 端口在 TCP/IP 通信中起到什么核心作用?请举例说明 2 个常见的 “知名端口” 及其对应的应用场景,客户端进程的端口是如何分配的?
- 已知某设备的 IP 地址为 10.0.2.89,子网掩码为 255.255.255.224(或 CIDR 表示为 /27),请写出计算该 IP 所属 “网络号” 和 “主机号” 的具体过程,网络号和主机号各自的作用是什么?
- 网络层的 IP 协议主要负责什么功能?文章中提到 “IP 寻址像导航,路由像操作方向盘”,请结合这个比喻,说明 IP 寻址和路由在数据传输中的具体角色及关系。
- 网络接口层为什么需要 MAC 地址?ARP 协议的核心作用是什么?同一局域网内的设备 A(IP:192.168.1.10)首次向设备 B(IP:192.168.1.20)发送数据时,ARP 协议会如何工作?
- 请描述一份 HTTP 请求数据(应用层)从发送端到接收端,在 TCP/IP 各层中的 “封装过程”—— 包括每一层会添加什么类型的头部、最终形成的传输单位是什么。
我的回答&纠错
第 1 题:TCP/IP 四层结构、职责及协议
你的回答:
应用层:拿到应用的数据后打包交给传输层(HTTP)传输层:为应用层传过来的数据提供网络支持(TCP、UDP)网络层:负责把数据从一个设备传输到另一个设备(IP)网络接口层:在网卡层面工作,通过 MAC 标识设备,将数据送到相应设备的位置(MAC)
评判与讲解:
部分正确
:四层划分和对应核心协议(HTTP、TCP/UDP、IP、MAC)无错,但职责描述过于简略,遗漏原文关键细节,需补充:
- 应用层:原文明确 “应用层专注于「提供用户功能」”(如 HTTP 处理浏览器与服务器的请求交互、DNS 解析域名),“打包交给传输层” 是 “数据封装” 的动作,而非核心职责 —— 核心是 “定义应用间通信的规则”(比如 HTTP 的请求行、响应头格式)。
- 传输层:原文强调 “传输层负责「端到端的通信」”(即从发送方进程到接收方进程),“提供网络支持” 太笼统,具体是 “提供可靠性(TCP)或实时性(UDP)保障”,并通过 “端口” 区分同一设备上的不同进程。
- 网络层:原文提到 “网络层负责「路由选择」和「IP 寻址」”,“从一个设备传到另一个设备” 是结果,过程中关键是 “通过 IP 地址确定目标设备的网络位置,并选择数据传输的路径(路由)”。
- 网络接口层:原文指出 “网络接口层是「数据链路层 + 物理层」的结合”,除了 “通过 MAC 标识设备”,还负责 “将 IP 数据包封装成「帧」(添加帧头帧尾),并通过物理介质(如网线、WiFi)传输”——“MAC” 是该层的标识技术,“帧” 是该层的传输单位,不能只提 MAC。
第 2 题:TCP/UDP 差异及 TCP 核心特性
你的回答:
TCP 是从发送到接收负责到底,保证对面收到了流程才会结束,UDP 是只管发送,不管对面收到没;流量控制是为了防止数据量过大,导致数据有干扰,而超时重传是一种对于数据传输失败的补救机制,拥塞控制我不清楚。
评判与讲解:
TCP/UDP 差异:部分正确
你说的 “TCP 保证接收、UDP 不保证” 是核心差异(可靠性),但原文还提到两个关键差异未提及:
- 连接性:TCP 是「面向连接」(需三次握手建立连接),UDP 是「无连接」(直接发送);
- 数据格式:TCP 是「面向流」(无数据边界,需应用层处理粘包),UDP 是「面向报文」(每个报文独立,有边界)。
TCP 特性:部分正确,存在错误
- 流量控制:你的 “防止数据量过大导致干扰” 错误,原文明确 “流量控制是「控制发送方的发送速率,匹配接收方的处理能力」”—— 比如接收方缓冲区快满时,会通过 TCP 头部的 “窗口大小” 告诉发送方放慢速度,避免接收方来不及处理而丢包,和 “干扰” 无关。
- 超时重传:你的 “传输失败的补救” 正确,原文补充细节:“TCP 会给每个发送的段设定超时时间,若超时未收到确认(ACK),则重传该段”,本质是解决 “网络丢包” 问题。
- 拥塞控制:原文解释 “拥塞控制是「防止发送方发送过快,导致整个网络拥堵」”(比如网络中路由器缓存满了会丢包),核心机制是 “慢启动、拥塞避免”—— 比如 TCP 刚建立连接时,先慢速发送,逐渐增加速率,若检测到丢包(网络拥堵信号),则降低速率。
第 3 题:MSS/MTU、TCP 分段与 IP 分片
你的回答:
MSS 是 TCP 协议的一种对数据的分片机制,便于在部分数据传输失败时直接重传片,不需要全部重新传;MTU 是对于超出 1500 字节大小限制的,已经打包好的 IP 报文进行分隔,以便更好的进行传输;TCP 分段在数据大小超出 MSS 时触发,IP 分片在数据大小超出 MTU 时触发,区别不清楚。
评判与讲解:
MSS/MTU 定义:错误,混淆核心概念
- MSS:原文明确 “MSS 是「TCP 最大报文段长度」,指 TCP 段中「数据部分的最大长度」(不含 TCP 头部)”——MSS 不是 “分片机制”,而是 “分片的依据”;且 “部分重传” 是 TCP 分段的优势,不是 MSS 的定义本身。
- MTU:原文指出 “MTU 是「数据链路层帧的最大数据部分长度」(不含帧头帧尾),默认 1500 字节”——MTU 限制的是 “帧的数据部分”,而 “IP 报文” 是网络层的单位,IP 报文若超过 MTU,才会被分片(分片后的 IP 报文需小于等于 MTU),你的 “对 IP 报文分隔” 描述准确,但 MTU 的定义对象错误。
TCP 分段与 IP 分片:触发条件正确,区别遗漏
触发条件(超 MSS 分段、超 MTU 分片)正确,但原文明确二者 3 个核心区别:
| 对比维度 | TCP 分段(传输层) | IP 分片(网络层) |
| -------- | ---------------------------------- | ---------------------------------- |
| 处理位置 | 发送端 TCP 协议栈 | 发送端 / 中间路由器(网络层) |
| 重组位置 | 接收端 TCP 协议栈 | 目标主机网络层(中间路由器不重组) |
| 重传单位 | 重传单个分段(因 TCP 有 ACK 确认) | 重传整个 IP 报文(IP 无确认机制) |
第 4 题:端口的作用、知名端口与分配
你的回答:
端口用于给同一台设备上不同的应用分配通信的信道;80:HTTP 端口,22:SSH 远控端口;端口是由操作系统给应用分配的。
评判与讲解:
部分正确,细节遗漏
- 端口作用:你的 “分配通信信道” 正确,原文补充更精准的描述:“端口是「标识同一设备上的「应用进程」」,让传输层(TCP/UDP)能将数据准确交给对应进程”(比如 80 端口对应 HTTP 服务进程,22 对应 SSH 进程)。
- 知名端口:你举的 80(HTTP)、22(SSH)正确,原文补充 “知名端口范围是 0-1023,由 IANA(互联网号码分配机构)统一分配,用于标准服务”。
端口分配:你的 “操作系统分配” 正确,但原文区分了两类端口的分配逻辑:
- 服务器端:使用「知名端口」(如 HTTP 用 80),由开发者在代码中指定(需操作系统权限);
- 客户端:使用「临时端口」(1024-65535),由操作系统在客户端发起连接时 “动态随机分配”(比如浏览器访问百度时,操作系统给浏览器分配一个临时端口,用于和百度的 80 端口通信)。
第 5 题:IP 与子网掩码计算网络号 / 主机号
你的回答:
将 IP 地址和子网掩码转换成二进制后按位与计算后,算出网络号;将子网掩码按位取反后和 IP 地址按位与计算算出主机号;网络号是为了找到主机所处的子网的位置,而主机号是区分同个子网中的不同主机用的。
评判与讲解:
完全正确(方法 + 作用),但缺少「具体计算过程」
原文强调 “计算网络号需结合二进制按位与”,你的方法正确,但题目要求 “写出具体过程”,需补充:
- IP 地址 10.0.2.89 转二进制:00001010.00000000.00000010.01011001
- 子网掩码 255.255.255.224(/27)转二进制:11111111.11111111.11111111.11100000
- 按位与计算网络号:00001010.00000000.00000010.01000000 → 十进制 10.0.2.64;
子网掩码取反(00000000.00000000.00000000.00011111)与 IP 按位与:00000000.00000000.00000000.00011001 → 十进制 25;
作用描述完全正确,符合原文 “网络号找子网,主机号分子网内主机” 的逻辑。
第 6 题:IP 协议功能、IP 寻址与路由
你的回答:
IP 协议是为了在复杂的路由网络中找到目标设备所处的位置的;IP 寻址就像门牌号一样,是给路由看的目的地地址,而路由可以根据这个地址,将其送往正确的下一个路由,如此往复,直到到达目的地。
评判与讲解:
部分正确,IP 协议功能遗漏
IP 协议功能:你的 “找目标设备位置” 仅覆盖 “IP 寻址”,原文明确 IP 协议有 3 个核心功能:
- 寻址:通过 IP 地址确定目标设备的网络位置;
- 路由:选择数据从源到目标的传输路径(依赖路由表);
- 封装 / 解封装:将传输层的 “段” 封装成 “IP 数据包”(加 IP 头部),目标主机收到后解封装,交给传输层。
- IP 寻址与路由:你的比喻(门牌号、送下一个路由)正确,原文补充细节:“IP 寻址是「确定最终目的地的 IP 地址」(如门牌号),路由是「每一跳路由器根据目标 IP 和路由表,决定下一跳的位置」(如快递站根据门牌号决定送往下一个站点)”—— 二者是 “目标指引” 和 “路径执行” 的关系,缺一不可。
第 7 题:MAC 地址作用与 ARP 协议
你的回答:
MAC 是局域网中的设备之间通信用的标识符;ARP 协议的作用是获取局域网中某 IP 地址的设备的 MAC 地址;首次发送数据时,ARP 协议会获取双方的 MAC 地址并告诉对方。
评判与讲解:
- MAC 地址作用:正确,符合原文 “MAC 地址是「数据链路层的设备唯一标识」,用于局域网内设备间的直接通信(比如同一 WiFi 下的手机和电脑)”。
ARP 协议作用:正确,但工作过程错误
原文明确 “ARP 的工作过程是「单播响应 + 广播请求」”,以 A(192.168.1.10)首次向 B(192.168.1.20)发送数据为例:
- A 知道 B 的 IP,但不知道 MAC,于是在局域网内「广播」ARP 请求(“谁是 192.168.1.20?请告诉我你的 MAC”);
- 局域网内所有设备收到请求,只有 B(IP 匹配)会「单播」ARP 响应(“我是 192.168.1.20,我的 MAC 是 XX:XX:XX:XX:XX:XX”);
A 收到响应后,将 B 的 “IP-MAC 映射” 缓存到 ARP 表中,后续通信直接用缓存,无需再广播;
你的 “获取双方 MAC 并告诉对方” 错误 ——ARP 只需要 A 获取 B 的 MAC,B 不需要主动获取 A 的 MAC(A 的 MAC 会在 ARP 请求的帧头中携带,B 能直接拿到)。
第 8 题:HTTP 请求的 TCP/IP 封装过程
你的回答:
在传输层添加 TCP 头部,网络层添加 IP 头部和 MAC 头部,最后在网络接口层添加帧头帧尾,以帧的形式发出。
评判与讲解:
错误,核心问题是「封装顺序颠倒」和「头部归属错误」
原文明确 “TCP/IP 封装是「从上层到下层,逐层添加头部」”,HTTP 请求的完整封装流程(按原文逻辑):
- 应用层:生成 HTTP 请求数据(如 “GET /index.html HTTP/1.1\r\nHost: xiaolincoding.com\r\n...”),无头部添加,传输单位是 “应用数据”;
- 传输层(TCP):给应用数据添加「TCP 头部」(包含源端口、目的端口、序号、确认号等),形成 “TCP 段”;
- 网络层(IP):给 TCP 段添加「IP 头部」(包含源 IP、目的 IP、TTL 等),形成 “IP 数据包”;
- 网络接口层:给 IP 数据包添加「帧头」(包含源 MAC、目的 MAC)和「帧尾」(校验和),形成 “数据帧”;
数据帧通过物理介质(如网线)传输到接收端,接收端再从下层到上层逐层解封装,最终将 HTTP 请求交给应用层。
你的错误点:
- 顺序颠倒:应先加 TCP 头部,再加 IP 头部,最后加帧头帧尾(你把 IP 和 MAC 头部的添加顺序搞反了);
- 头部归属错误:MAC 头部属于 “网络接口层的帧头”,不是网络层的头部,网络层只添加 IP 头部。
整体总结
你的回答 掌握了 TCP/IP 的基础框架(四层划分、核心协议),但存在 3 类典型问题:
- 细节遗漏:如传输层的 “端到端”、IP 协议的 “封装 / 解封装”、端口的 “临时端口范围”;
- 概念混淆:如 MSS 与 “分片机制” 的区别、MTU 的定义对象、封装的层间顺序;
- 流程错误:如 ARP 的 “广播请求 + 单播响应”、封装的上层到下层顺序。
建议后续结合原文,重点关注 “每层的传输单位(应用数据 / 段 / 数据包 / 帧)”“协议的具体工作流程(如 ARP、三次握手)”“上下层的交互逻辑(如封装 / 解封装)”,这些是计网面试的核心考点,也是原文反复强调的内容。
2.2.键入网址到网页显示,期间发生了什么?
一、整体流程梳理(考察框架性理解)
请完整描述:当你在浏览器地址栏输入这个 URL(
https://xiaolincoding.com/network/1_base/what_happen_url.htm)并按下回车后,从计网层面看,直到页面开始渲染前,会依次发生哪些核心步骤?(提示:从 DNS 到 TCP、HTTP、响应处理等环节)答:首先浏览器解析这个url的dns地址,找到地址后,再调用协议栈,进行tcp三次握手建立连接。连接后,发送http请求,服务器收到请求后响应请求,返回数据,然后浏览器处理数据,将其显示出来。
在你刚才梳理的流程中,哪些环节是 “客户端主动发起”,哪些是 “服务端被动响应”?有没有双向交互的环节?
答:
二、DNS 解析环节(考察域名映射核心逻辑)
浏览器要向
xiaolincoding.com发送请求,首先需要知道它的 IP 地址 —— 这个 “域名转 IP” 的 DNS 解析流程是怎样的?请说明 “递归查询” 和 “迭代查询” 在其中的角色(比如浏览器→本地 DNS 服务器是递归,本地 DNS→根 / 顶级域服务器是迭代)。答:(1)客户端会先问本地dns服务器有没有存这个域名的ip地址,如果有就直接拿来用,流程结束;否则继续。然后,客户端会问顶级dns服务器,然后顶级dns服务器会返回
.com,表明这个域名在它所管辖的区域下。然后客户端去问.com服务器,.com服务器返回管xiaolingcoding.com的dns服务器的地址。最后,客户端问这个服务器,它直接管辖这个域名,最终返回ip地址。(2)浏览器会先看自己有没有存这个域名的缓存,如果有就直接返回,否则去问操作系统有没有,直到没有,再去问外面的dns服务器。在这一过程中,本地dns服务器要么返回ip,要么返回找不到ip的错误,不会返回部分信息,这就是递归的体现。而去问外面的顶级域服务器,它会每次返回一部分信息,让你去找下一级的服务器,将信息一点一点拼起来就是最终的ip地址。这就是迭代的体现。
为了提高 DNS 解析效率,会有哪些层级的缓存?比如浏览器缓存、操作系统缓存、路由器缓存,这些缓存的有效期由什么决定?如果我修改了本地
hosts文件配置xiaolincoding.com的 IP,会优先使用hosts配置还是 DNS 解析结果?答:(1)会有浏览器缓存、操作系统缓存、路由器缓存。
(2)由TTL进行决定。这个是这个网站的管理员在权威dns服务器上面设置的。
(3)会优先使用hosts。
如果 DNS 解析失败(比如域名不存在),浏览器会返回什么提示?从计网角度看,此时是否会建立 TCP 连接?为什么?
答:(1)差不多就是提示“无法找到服务器地址”。
(2)不会。(3)因为tcp连接是使用ip连接的,没有ip,就找不到位置,怎么连接?
三、TCP 连接环节(考察可靠性传输基础)
解析出
xiaolincoding.com的 IP 后,浏览器要和服务器建立 TCP 连接,这个 “三次握手” 的过程是怎样的?请说明每次握手的关键字段(SYN、ACK 标志位,序列号 seq)和作用。答:(1)第一次握手是客户端向服务器主动发送的syn,然后进入syn-sent状态。然后第二次握手:服务器监听到之后会返回syn并且ack这个syn,同时处于syn-rcvn状态。第三次握手:客户端接收到之后会向服务器发送确认syn的ack,之后进入established状态。服务器接收到这个ack后,也进入established状态。(2)syn用于请求连接,ack用于确认连接,seq用于告诉彼此我要发送的数据从哪个字节开始。
为什么 TCP 需要三次握手,而不是两次?如果只握两次手,会出现什么问题(比如 “半连接” 或 “无效连接请求”)?
答:三次握手是为了确保双方都有收发数据的能力。如果只握两次手,举个例子,客户端只能发送不能接收数据,服务端可发可收,然后第一次握手,客户端发送syn给服务端,然后第二次握手服务端直接发送这个syn的ack,以为自己连接成功了,实则客户端无法接收数据,出现半连接的情况,使得后续出现问题。
假设
xiaolincoding.com的服务器端口是 443(HTTPS 默认端口),三次握手过程中,客户端的源端口是如何确定的?如果客户端和服务器之间有防火墙,防火墙会对 TCP 握手的报文做什么处理?答:(1)客户端的源端口是系统在可用端口范围内(1-65536)随机分配的。
(2)第一次握手:防火墙会先检查客户端访问的443端口是否在白名单内。第二次握手:防火墙会检查服务器回复的是否是它刚刚放行的连接。第三次握手:客户端再次ack服务端,防火墙也确定这个连接合法。
三次握手后,如果长时间没有数据传输,TCP 连接会断开吗?这涉及到 TCP 的什么机制(比如保活计时器)?
答:(1)不会。(2)如果启用了保活计时器,客户端或者服务端会发空的ack包,询问对方是否还在。如果多次确认后不在,一方会直接断开连接。如果没启用,那就会一直连接,直到一方断开连接。
四、HTTP/HTTPS 请求环节(考察应用层协议细节)
这个 URL 的协议是 HTTPS,它和 HTTP 的核心区别是什么?HTTPS 的 “TLS 握手” 过程是在 TCP 三次握手之前还是之后?TLS 握手的核心目的(身份验证、密钥协商)是如何实现的?
答:
请描述一个完整的 HTTPS 请求报文结构(请求行、请求头、请求体)。比如:请求行中的 “方法” 可能是 GET,它和 POST 的核心区别是什么(从参数位置、缓存性、数据大小限制等角度说)?
答:
请求头中,有哪些字段和 “资源缓存” 相关?比如
Cache-Control、If-Modified-Since,它们分别对应 HTTP 的 “强缓存” 还是 “协商缓存”?如果这个 URL 对应的是一个静态 HTML 文件,服务器如何通过响应头告诉浏览器 “缓存 1 小时”?答:
如果服务器返回的 HTTP 状态码是 302,这代表什么含义?浏览器收到 302 后会做什么操作?和 301 状态码的区别是什么?如果返回 404,可能的计网层面原因有哪些(除了 “资源不存在”)?
答:
五、TCP 断开与资源加载(考察流程收尾与异常场景)
当浏览器接收到完整的 HTML 响应后,需要关闭 TCP 连接,这个 “四次挥手” 的过程是怎样的?为什么需要四次挥手,而不是三次?
答:客户端发送FIN包,请示服务器我要断开连接了;服务器收到后,发送ACK;服务器开始断开连接;客户端收到ack后,也断开连接。
四次挥手过程中,有一个 “TIME_WAIT” 状态,它的作用是什么?如果服务器出现大量
TIME_WAIT连接,会有什么问题?如何优化(从内核参数或协议角度)?答:
假设这个 URL 对应的页面还引用了 CSS、JS 等静态资源,浏览器会为每个资源单独建立 TCP 连接吗?这和 HTTP 版本(HTTP/1.1、HTTP/2)有什么关系(比如 HTTP/1.1 的 “持久连接”、HTTP/2 的 “多路复用”)?
答:
如果输入 URL 后,页面长时间空白,但浏览器没有报 “无法访问”,可能的计网层面原因有哪些?(比如 DNS 解析慢、TCP 握手超时、HTTP 请求被代理拦截、响应数据丢包)你会如何排查这些问题?
答:
2.3 Linux 系统是如何收发网络包的?
为了节省时间,本次只回答中高频题。
以下为按“题目 + 我的回答 + 判定 + 正确答案(如需)+ 纠错”给出的反馈。
题目:[高频] 简述 OSI 七层模型与 TCP/IP 四层模型的区别,各层职责分别是什么?为什么业界更常用 TCP/IP 模型?
我的回答:OSI七层模型有应用层(给应用程序提供联网接口)、表示层(把数据转换成另一个系统能识别的格式)、会话层(负责管理表示层的实体之间的通信会话)、传输层(负责端到端数据传输)、网络层(负责数据的路由、转发、分片)、数据链路层(负责数据的封帧和差错检测、mac寻址)、物理层(负责在物理网络中用电信号传递数据);而tcpip只有4层:应用层(给系统中的软件提供网络传输的协议接口,例如http等)、传输层(负责端到端的通信,例如tcp udp)、网络层(负责网络包的封装、分片、路由)、网络接口层(负责网络包在物理网络中的传输、mac寻址、差错检测、传递网络帧等)。因为七层过于理论,比较难以实现,所以我们才会用四层。
判定:基本正确
纠错:- 细化:TCP/IP 的“网络接口层”通常对应 OSI 的数据链路层+物理层的合并;OSI 的表示层/会话层在实践中多被折叠到应用层或由库实现。
- 措辞:物理层传输的是比特流而非“数据帧”(帧属于数据链路层)。
题目:[高频] 结合 Linux 协议栈,描述一次网络包从网卡接收到最终到达应用进程的完整路径与关键环节。
我的回答:从网卡出来后,会先通过dma直接写入内存中,进入ringbuffer;然后再到网络接口层,检查报文合法性,否则丢弃;摘掉帧头和帧尾后进入网络层,取出ip包判断网络下一步的走向,看ip确定是本机后去ip头里面看上一层的协议是tcp还是udp,然后摘掉ip头;进入传输层,取出tcp或者udp头,根据源ip,端口,目的ip,端口作为标识,取出对应的Socket,将数据放到Socket的接受缓存区;然后应用层调用socket接口,将socket缓冲区的数据拷贝到应用层的缓冲区,然后唤醒用户进程。
判定:部分正确(缺少中断/NAPI/软中断等关键环节)
正确答案(简要要点):- 网卡接收:NIC 通过 DMA 将数据写入 RX Ring Buffer。
- 硬中断:触发硬中断;中断服务程序(ISR)确认/暂时屏蔽后续中断(NAPI),调度 NET_RX 软中断。
- 软中断/NAPI 轮询:ksoftirqd 或软中断上下文运行驱动的 poll,批量从 ring 取包,组装为 sk_buff。
协议栈:
- L2:校验、去帧头/尾,识别上层协议类型(IPv4/IPv6)。
- L3:路由判定,若为本机则去 IP 头,识别上层(TCP/UDP/ICMP)。
- L4:按四元组查找 Socket,将数据放入 socket 接收队列。
- 递送到应用:唤醒等待队列;应用 recv/Read 触发从内核缓冲区拷贝到用户缓冲区。
纠错:补充硬/软中断与 NAPI 的触发与分工,说明“接收缓冲区”在传输层是 socket receive queue,并由应用主动调用系统调用取走。
题目:[高频] 什么是 MTU?为什么会有 IP 分片?分片对吞吐与性能有什么影响,如何避免或缓解?
我的回答:MTU是最大单次传输单元。因为受物理链路的限制,有些数据包太大了无法传送,得利用ip分片分成一批一批的传送。分片越多,吞吐性能越差,要根据网络环境设置合理的mtu值。
判定:基本正确
纠错(补充优化手段与影响):- 影响:分片增加 CPU/内存开销,丢任一片需重传整报文,放大丢包影响;路径异构 MTU 易导致黑洞。
- 缓解:启用/依赖 PMTUD(DF 置位)、合理设置 TCP MSS、在可控环境使用 Jumbo Frames(统一更大 MTU)、尽量避免 IP 层分片(让传输层分段/GSO/TSO 处理)。
题目:[中高频] 什么是 NAPI?为何引入“中断+轮询”的混合机制?它如何缓解高并发网络下的中断风暴问题?
我的回答:它不采用中断的方式读取数据,而是首先采用中断唤醒接收数据的服务程序,然后再使用poll的方法来轮询数据。这样可以避免频繁中断cpu,从而影响系统整体的效率。
判定:基本正确
纠错(补充关键点):- 忙时轮询、闲时中断:高负载时禁中断改批量轮询;低负载保持中断,兼顾延迟与吞吐。
- 预算控制:NAPI 有预算(budget)限制单次处理包数,避免饿死其他任务。
题目:[中高频] 硬中断与软中断在网络收发中的分工分别是什么?ksoftirqd 的作用是什么?
我的回答:内核中的ksoftirqd负责软中断,硬中断是直接使cpu停止手上的工作。它的作用是从ringbuffer里面获取一个数据帧,用sk_buff表示,作为网络包交给网络协议栈进行逐层处理。
判定:部分正确(表述不完整)
正确答案(简要要点):- 硬中断(ISR):确认事件、必要时禁用 NIC 中断(NAPI)、将处理延后到软中断,尽量短小。
- 软中断(NET_RX/NET_TX):执行实际的收发处理(驱动 poll 批量取包、协议栈入栈、TX 完成回收等)。
- ksoftirqd:当软中断积压或需在进程上下文运行时,由每 CPU 的 ksoftirqd 线程执行 pending 的软中断,避免长时间占用中断上下文。
纠错:强调 ISR 不直接“取帧并上送协议栈”;ksoftirqd 是软中断的一种承载执行机制,不是“唯一负责者”,软中断也可直接在中断返回路径运行。
题目:[中高频] 什么是 sk_buff?为何 Linux 用一个数据结构贯穿各层?发送与接收路径中 skb->data 指针如何移动以避免多次拷贝?
我的回答:skbuff是内核态的内存,存储用户待发送的数据。是为了避免在层与层之间传输时发生多次拷贝,从而降低cpu效率。就像进栈出栈一样移动指针,避免了无效的复制。
判定:部分正确(概念不准、细节缺失)
正确答案(简要要点):- 定义:sk_buff 是内核用于描述网络包的通用数据结构,包含指向数据缓冲区的指针(head/data/tail/end)、协议头偏移、校验/路由/时间戳等大量元数据;用于收包与发包。
- 统一结构的意义:跨层传递只调整指针与元数据,避免层间复制,提高效率。
指针移动:
- 接收路径:随层级上送,逐步“消费”头部,表现为增加 skb->data 指针(剥离 L2/L3/L4 首部)。
- 发送路径:预留 headroom,逐层“前推”头部,使用 skb_reserve 预留、skb_push 下降 data 指针填充 L2/L3/L4 首部。
纠错:sk_buff 不是“仅存储待发送数据的内存”,而是“包描述符+数据缓冲”的抽象;需明确接收时 data++、发送时 skb_push 方向。
题目:[中高频] 发送 TCP 数据时为何会克隆一个 sk_buff 副本?ACK 到达前后内存释放的时机与原因是什么?
我的回答:因为tcp有失败重传机制,克隆一个副本发送出去,等收到对方的ack再真正删除。ack到达前,只要到了网卡被发送出去,skbuff副本就会被释放掉;而收到ack后,才会释放真正的skbuff。这样是为了满足tcp的失败重传机制。
判定:正确
纠错(可选补充):- 发送路径中交给设备队列的是副本/分片;原始 skb 留在 TCP 发送队列/重传队列里直到被 ACK 掉。
- TX 完成(网卡发送完成中断)释放的是设备侧副本;接收 ACK 后释放原始 skb,保证可重传。
- 实际实现还会结合 GSO/TSO、skb_clone/copy 的策略。
题目:[中高频] 传输层如何根据四元组(源 IP/源端口/目的 IP/目的端口)定位到对应的 Socket?这对连接复用与并发有何意义?
我的回答:应该是在发送数据包时经过传输层时会有记录,然后在数据传回来时就能通过这个记录找到对应的Socket。这样可以实现并发时数据包的有效管理。
判定:不完整
正确答案(简要要点):查找机制(以 TCP 为例):
- LISTEN 阶段:按目标端口在监听哈希表中命中监听 socket。
- ESTABLISHED:按四元组在 ehash(已建立连接哈希)中定位具体连接 socket。
- 绑定/端口复用:bind hash 管理本地绑定;UDP 可按 2 元组或 4 元组匹配,SO_REUSEPORT 支持多 socket 负载分担。
意义:
- 同一服务端口可承载大量并发连接(区分在四元组层面)。
- 高并发下依赖高效哈希与无锁/细粒度锁提升扩展性;SO_REUSEPORT 实现多进程/多线程分流。
纠错:补充具体的哈希查找与不同阶段的表项区分,明确并发扩展点(哈希桶大小、接收队列、accept 队列等)。
- [中频] 网络接口层的主要工作有哪些?封帧、MAC 寻址、差错检测如何体现?ARP 在发送路径中起什么作用?
- [中频] IP 层在发送路径会做哪些工作?包括路由选择、填充 IP 头、netfilter 过滤以及分片的时机与条件。
- [中频] 网卡接收数据时,DMA 与 Ring Buffer 分别做什么?为何需要它们?
- [中频] 网络接收路径中,为何硬中断处理函数要“暂时屏蔽中断”,随后再触发软中断?这样设计的收益与取舍是什么?
- [中频] 请列举发送网络数据时涉及的内存拷贝次数,并说明每次拷贝发生的原因与场景(用户态->内核态、TCP 克隆、IP 分片)。
- [中频] 当报文超过 MTU 被分片后,接收端的重组发生在哪一层?重组失败会带来哪些影响?
- [偏低频] 请对比应用层常用协议(如 HTTP、DNS、FTP)与其在 TCP/IP 模型中的位置,说明对后端服务设计与调优的影响点。
- [偏低频] 链路层的差错检测(如帧校验)与 IP/TCP 的校验分别解决什么问题?为何需要分层次的校验机制?
- [偏低频] 在高 QPS 场景下,频繁中断对 CPU 的影响体现在哪?除了 NAPI,还有哪些思路可以进一步降低中断开销(方向性回答即可)?
- [偏低频] sk_buff 在不同层常用的称谓(segment/packet/frame)有什么区别?这些称谓反映了哪些封装/解封装的边界?
- [偏低频] 结合发送路径,为什么需要将数据包放入网卡发送队列?发送完成后的硬中断释放了哪些资源,为什么必须这样做?
- [偏低频] netfilter 处在协议栈的哪个阶段?它可能对应用请求的时延与吞吐产生什么影响?
3.1 HTTP常见面试题
HTTP是什么?
全称 HyperText Transfer Protocol,即超文本传输协议。
浓缩成一句话:HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
超文本的解释:
我们先来理解「文本」,在互联网早期的时候只是简单的字符文字,但现在「文本」的涵义已经可以扩展为图片、视频、压缩包等,在 HTTP 眼里这些都算作「文本」。
再来理解「超文本」,它就是超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键有超链接,能从一个超文本跳转到另外一个超文本。
HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,再经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了。
HTTP常见的状态码有哪些?

摘录:
1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。
2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。
- 「200 OK」是最常见的成功状态码,表示一切正常。如果是非
HEAD请求,服务器返回的响应头都会有 body 数据。 - 「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
- 「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
3xx 类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。
- 「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
- 「302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
- 「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
4xx 类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
- 「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
- 「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
- 「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
- 「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
- 「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
- 「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
- 「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
HTTP 常见字段有哪些?
1.Host:用于指定服务器域名。用于将请求发往「同一台」服务器上的不同网站。
2.Content-Length:服务器在返回数据时用于表明本次回应的数据长度。
3.Connection:用于客户端要求服务器使用「HTTP 长连接」。HTTP/1.1版本默认连接都是长连接,所以这里一般指定为Connection: Keep-Alive,用于兼容HTTP老版本。
长连接的定义:只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
4.Content-Type:服务器告诉客户端本次回应的数据格式。例:
Content-Type: text/html; Charset=utf-8客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式。
Accept: */*上面代码中,客户端声明自己可以接受任何格式的数据。
5.Content-Encoding:服务器告诉客户端本次回应的数据的压缩方法。
例:
Content-Encoding: gzip上面表示服务器返回的数据采用了 gzip 方式压缩,告知客户端需要用此方式解压。
客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法。
Accept-Encoding: gzip, deflateGET与POST
GET和POST有啥区别?
GET:从服务器获取指定资源。
POST:根据客户端的请求对指定资源作出处理。
GET 和 POST 方法都是安全和幂等的吗?
先说明下安全和幂等的概念:
- 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
- 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。
如果从RFC规范定义的语义来看:
- GET方法是安全且幂等的。因为它是只读操作,不会对服务器上的数据产生任何影响。
- POST是不安全且不幂等的。因为它属于新增/提交数据的操作,会修改服务器上的资源。正因为重复执行会产生不同的结果,所以浏览器一般不会缓存POST请求,也不能将其保存为书签。
但是实际过程中,开发者不一定会按照 RFC 规范定义的语义来实现 GET 和 POST 方法。比如:
- 可以用 GET 方法实现新增或删除数据的请求,这样实现的 GET 方法自然就不是安全和幂等。
- 可以用 POST 方法实现查询数据的请求,这样实现的 POST 方法自然就是安全和幂等。
总结:GET和POST只是个标识符,并不是强制我只能“get”数据和“post”数据。当然,开发时还是遵循规范为好。
HTTP 缓存技术
HTTP 缓存有哪些实现方式?
缓存:将「请求-响应」的数据缓存在本地,这样下次请求就能直接读取本地的数据。
方式:强制缓存和协商缓存。
什么是强制缓存?
强缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边。
强缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们都用来表示资源在客户端缓存的有效期:
Cache-Control, 是一个相对时间;Expires,是一个绝对时间;
如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话,Cache-Control 的优先级高于 Expires 。
Cache-control 选项更多一些,设置更加精细,所以建议使用 Cache-Control 来实现强缓存。具体的实现流程如下:
- 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control,Cache-Control 中设置了过期时间大小;
- 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器;
- 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control。
总结表格:
| 项目 | Expires | Cache-Control |
|---|---|---|
| 类型 | 绝对时间(固定时间点) | 相对时间(相对当前时间间隔) |
| 示例 | Expires: Wed, 23 Oct 2025 10:00:00 GMT | Cache-Control: max-age=86400(24小时) |
| 精度 | 依赖于客户端和服务器时间是否一致 | 不依赖时钟同步,更准确 |
| 优先级 | 被Cache-Control 覆盖 | 优先级更高 |
| 出现版本 | HTTP/1.0 | HTTP/1.1 |
什么是协商缓存?
协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存。
注意:在协商缓存之前,浏览器一定会先经过强制缓存的流程(下图所示)。协商缓存是强制缓存过期后,客户端去问服务器我的资源还能不能继续用的过程。

http协商缓存主要靠下面的两对字段:
| 浏览器请求(Request) | 服务器响应(Response) | 说明 |
|---|---|---|
If-Modified-Since | Last-Modified | 比较资源最后修改时间 |
If-None-Match | ETag | 比较资源唯一标识(标签) |
第一对字段是靠文件修改时间判断文件是否修改过的。例子如下:
浏览器第一次请求:
GET /logo.png服务器响应:
HTTP/1.1 200 OK
Last-Modified: Wed, 23 Oct 2024 10:00:00 GMT浏览器记下这个时间。
下一次请求(缓存过期后):
GET /logo.png
If-Modified-Since: Wed, 23 Oct 2024 10:00:00 GMT如果服务器检查后发现文件没改过,就返回:
HTTP/1.1 304 Not Modified✅ 表示“没变,你可以继续用你的旧缓存”。
第二对字段是靠文件的“指纹”ETag判断服务器和客户端是否是同一个文件。例子如下:
浏览器第一次请求:
GET /data.json服务器响应:
HTTP/1.1 200 OK ETag: "abc123"浏览器保存这个标签。
再次请求:
GET /data.json If-None-Match: "abc123"如果服务器计算后发现资源没变:
HTTP/1.1 304 Not Modified✅ 浏览器直接使用缓存文件。
如果变了,则返回新的内容(200 OK+ 新的ETag)。
协商缓存总结:
第一次访问:服务器返回资源 + 校验标识(ETag 或 Last-Modified);
再次访问:
- 浏览器带上标识问服务器;
- 如果资源没变 → 返回 304,浏览器用缓存;
- 如果变了 → 返回新资源 + 新标识。
HTTP特性
HTTP/1.1 的优点有哪些?
HTTP 最突出的优点是「简单、灵活和易于扩展、应用广泛和跨平台」。
摘录:
1. 简单
HTTP 基本的报文格式就是 header + body,头部信息也是 key-value 简单文本的形式,易于理解,降低了学习和使用的门槛。
2. 灵活和易于扩展
HTTP 协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充。
同时 HTTP 由于是工作在应用层( OSI 第七层),则它下层可以随意变化,比如:
- HTTPS 就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层;
- HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议,而到了 HTTP/3.0 传输协议改用了 UDP 协议。
3. 应用广泛和跨平台
互联网发展至今,HTTP 的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用遍地开花,同时天然具有跨平台的优越性。
HTTP/1.1 的缺点有哪些?
1.无状态。这是一把双刃剑。每次交互,服务器不会记录http的状态。
好处:减轻服务器负担。
坏处:在一系列需要鉴权的流程上,每次都得反复验证。这一般使用cookies解决。
相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了了。
2.明文传输。依旧双刃剑。
好处:方便开发人员进行调试。
坏处:信息裸奔。
3.不安全。
首先,它使用明文通信。
其次,它不验证通信方的身份。
最后,它无法证明报文的完整性,传输的内容容易被篡改。
当然,这些问题将会用https解决。
HTTP/1.1 的性能如何?
HTTP 协议是基于 TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里。
1.长连接
只要双方没人说要断开,就一直连着,除非过了一定时间才会断开。这样可以避免每次都要三次tcp握手建立连接,然后又马上四次tcp挥手断开连接,这样很浪费时间。

2.管道网络传输
这是http/1.1可以实现的功能,但是这并不是默认开启的,而且浏览器基本也没支持。
管道传输的定义:即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。
这样看起来很快,对吧?
但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应。
如果服务端在处理 A 请求时耗时比较长,那么后续的请求的处理都会被阻塞住,这称为「队头堵塞」。
所以,HTTP/1.1 管道解决了请求的队头阻塞,但是没有解决响应的队头阻塞。
3.队头阻塞
即使不启用上面的管道网络传输,也是会存在队头阻塞的问题。因为客户端必须在收到服务器的回应后才会再次发送请求。
当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这也就是「队头阻塞」,好比上班的路上塞车。
总之 HTTP/1.1 的性能一般般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。
HTTP 与 HTTPS
HTTP 与 HTTPS 有哪些区别?
- HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
- HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
- 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
- HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
HTTPS 解决了 HTTP 的哪些问题?
- 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
- 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
- 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。
- 混合加密的方式实现信息的机密性,解决了窃听的风险。
- 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
- 将服务器公钥放入到数字证书中,解决了冒充的风险。
Example:
既然伪造公私钥那么随意,所以你爸把他的公钥注册到警察局,警察局用他们自己的私钥对你父亲的公钥做了个数字签名,然后把你爸爸的「个人信息 + 公钥 + 数字签名」打包成一个数字证书,也就是说这个数字证书包含你爸爸的公钥。
这样,你爸爸如果因为家里确实有事要向老师帮你请假的时候,不仅会用自己的私钥对内容进行签名,还会把数字证书给到老师。
老师拿到了数字证书后,首先会去警察局验证这个数字证书是否合法,因为数字证书里有警察局的数字签名,警察局要验证证书合法性的时候,用自己的公钥解密,如果能解密成功,就说明这个数字证书是在警察局注册过的,就认为该数字证书是合法的,然后就会把数字证书里头的公钥(你爸爸的)给到老师。
由于通过警察局验证了数字证书是合法的,那么就能证明这个公钥就是你父亲的,于是老师就可以安心的用这个公钥解密出请假条,如果能解密出,就证明是你爸爸写的请假条。
正是通过了一个权威的机构来证明你爸爸的身份,所以你的伪造公私钥这个小伎俩就没用了。
在计算机里,这个权威的机构就是 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。
HTTPS 是如何建立连接的?其间交互了什么?
SSL/TLS 协议基本流程:
- 客户端向服务器索要并验证服务器的公钥。
- 双方协商生产「会话秘钥」。
- 双方采用「会话秘钥」进行加密通信。

下图是客户端逐层校验证书的流程图:


HTTPS 的应用数据是如何保证完整性的?
TLS 在实现上分为握手协议和记录协议两层:
- TLS 握手协议就是我们前面说的 TLS 四次握手的过程,负责协商加密算法和生成对称密钥,后续用此密钥来保护应用程序数据(即 HTTP 数据);
- TLS 记录协议负责保护应用程序数据并验证其完整性和来源,所以对 HTTP 数据加密是使用记录协议;
TLS 记录协议主要负责消息(HTTP 数据)的压缩,加密及数据的认证,过程如下图:

具体过程如下:
- 首先,消息被分割成多个较短的片段,然后分别对每个片段进行压缩。
- 接下来,经过压缩的片段会被加上消息认证码(MAC 值,这个是通过哈希算法生成的),这是为了保证完整性,并进行数据的认证。通过附加消息认证码的 MAC 值,可以识别出篡改。与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编码。
- 再接下来,经过压缩的片段再加上消息认证码会一起通过对称密码进行加密。
- 最后,上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据。
记录协议完成后,最终的报文数据将传递到传输控制协议 (TCP) 层进行传输。
HTTPS 一定安全可靠吗?
之前有读者在字节面试的时候,被问到:HTTPS 一定安全可靠吗?
这个问题的场景是这样的:客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。

从客户端的角度看,其实并不知道网络中存在中间人服务器这个角色。那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于,中间人能够 “偷看” 浏览器与服务端之间的 HTTPS 请求和响应的数据。
但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书。
中间人服务器与客户端在 TLS 握手过程中,实际上发送了自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器(客户端)识别出是非法的,于是就会提醒用户该证书存在问题。
所以,HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全。
那为啥抓包工具能获取到https的数据呢?它是通过自己签发证书,且被浏览器信任的方式。抓包工具能够抓包的关键是客户端会往系统受信任的根证书列表中导入抓包工具生成的证书,而这个证书会被浏览器信任,也就是抓包工具给自己创建了一个认证中心 CA,客户端拿着中间人签发的证书去中间人自己的 CA 去认证,当然认为这个证书是有效的。
那么我们要如何避免被中间人抓取数据呢?这时候就需要HTTPS 双向认证出场了:不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。服务端一旦验证到请求自己的客户端为不可信任的,服务端就拒绝继续通信,客户端如果发现服务端为不可信任的,那么也中止通信。
HTTP/1.1、HTTP/2、HTTP/3 演变
HTTP/1.1 相比 HTTP/1.0 提高了什么性能?
HTTP/1.1 相比 HTTP/1.0 性能上的改进:
- 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
- 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。
但 HTTP/1.1 还是有性能瓶颈:
- 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩
Body的部分; - 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
- 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
- 没有请求优先级控制;
- 请求只能从客户端开始,服务器只能被动响应。
HTTP/2 做了什么优化?
🌐 HTTP/2 概述
- 基于 HTTPS(TLS),安全性有保障。
- 是对 HTTP/1.1 的重大性能改进。
⚡ 性能提升的四大关键特性
1️⃣ 头部压缩(HPACK)
- HTTP/2 使用 HPACK 算法 压缩请求头。
- 客户端和服务端维护一张 头部表,相同或相似的头字段只发送索引号,减少冗余传输。
- 提高传输效率、节省带宽。
2️⃣ 二进制帧格式
- HTTP/1.1 使用 纯文本报文;HTTP/2 改为 二进制帧(frame)。
包括:
- Header Frame(头帧)
- Data Frame(数据帧)
- 计算机解析更快,无需转换为二进制。
- 示例:状态码
200在 HTTP/1.1 占 3 字节,而在 HTTP/2 中仅需 1 字节。

3️⃣ 并发传输(多路复用)
- HTTP/1.1:同一连接只能串行处理请求 → 存在队头阻塞。
HTTP/2:引入 Stream 概念,多个 Stream 共享一个 TCP 连接。
- 每个 Stream 有唯一的 Stream ID。
- 可乱序发送帧,接收端根据 ID 组装。
- 实现真正的并发传输,提升连接利用率。

4️⃣ 服务器推送(Server Push)
- 服务器可主动推送资源,减少往返延迟。
规则:
- 客户端创建的 Stream → 奇数 ID
- 服务端创建的 Stream → 偶数 ID
- 示例:客户端请求 HTML 时,服务器可主动推送相关 CSS 文件。

⚠️ HTTP/2 的缺陷:TCP 队头阻塞(HOL Blocking)
- HTTP/2 虽解决了 HTTP 层的队头阻塞,但仍受 TCP 的顺序传输限制。
TCP 是字节流协议,必须保证数据连续:
- 若某个包(如 packet 3)丢失,即使 packet 4-6 已到达,也无法交付应用层。
- 直到丢失包重传成功,后续数据才能被读取。
- 结果:一个包丢失会阻塞整个连接上的所有请求。

HTTP/3 做了哪些优化?
🧱 队头阻塞问题对比
| 协议 | 阻塞层面 | 原因 | 结果 |
|---|---|---|---|
| HTTP/1.1 | HTTP 层 | 响应必须按顺序返回 | 某请求慢会卡后续请求 |
| HTTP/2 | TCP 层 | TCP 必须按序传输字节流,丢包阻塞全部流 | 一包丢,全体等 |
| HTTP/3 | —— | 改用 UDP + QUIC,无顺序依赖 | 无队头阻塞 |
⚡ QUIC 协议三大优势
1️⃣ 无队头阻塞
- QUIC 在 UDP 上实现可靠传输。
- 多个 Stream 独立传输,某个流丢包不会影响其他流。
- 彻底解决 HTTP/2 的 TCP 层阻塞问题。

2️⃣ 更快的连接建立
- HTTP/1 & 2:TCP 握手 + TLS 握手 → 多个 RTT。
HTTP/3 (QUIC):整合了 TLS 1.3,握手仅需 1 RTT,
- 恢复连接时甚至可实现 0 RTT(连接与数据同步发送)。
- 握手更少 → 建连更快。

3️⃣ 连接迁移(Connection Migration)
- TCP 连接依赖四元组(IP+端口),网络切换(如 4G→WiFi)必须重连。
QUIC 通过 Connection ID 标识连接,
- 即使 IP 改变也能复用原连接,
- 实现无缝迁移、不掉线。
⚠️ 限制与现状
- QUIC 是新协议,部分网络设备无法识别,会把 QUIC 当普通 UDP 包丢弃。
- 因此 HTTP/3 普及仍较慢,但具备取代 TCP 的潜力。