计算机网络八股学习日记
记录日期:2026-09-03 学习方式:以一篇 33 问的网络八股总结为底稿,按「分层模型 → 传输层 TCP → 应用层 HTTP/HTTPS/DNS → 综合场景题」的主线重新梳理,每节末尾附「可能的考法」,最后用自测清单检验掌握程度。
计算机网络面试题看似零散,其实全部挂在一条主线上:分层模型。传输层考 TCP/UDP(占了 33 问里的近一半),应用层考 HTTP/HTTPS/DNS,再拿一道”输入 URL 到页面显示”串联全局。本篇按这个框架展开。
1. 地基:OSI 七层模型与协议分布
所有网络题的第一张图,建议默画:
| 层次 | 功能 | 典型协议/设备 |
|---|---|---|
| 应用层 | 为应用程序提供服务 | HTTP、FTP、SMTP、DNS |
| 表示层 | 数据格式转换、加密解密、压缩 | — |
| 会话层 | 建立、管理、终止会话 | — |
| 传输层 | 端到端的可靠/不可靠传输 | TCP、UDP |
| 网络层 | 路由选择、逻辑寻址 | IP、ICMP、IGMP |
| 数据链路层 | 成帧、差错检测、MAC 寻址 | ARP、PPP |
| 物理层 | 比特流传输 | RJ45、802.3、集线器 |
记忆口诀:物理链路网输会示应(自下而上)。
追问点:数据发送时自上而下逐层加首部(封装),接收时自下而上逐层拆首部(解封装)。TCP/IP 四层模型是把上三层合并成应用层——实际工程里说”四层/五层”更常见,但面试先答七层再补充即可。
2. TCP 与 UDP 的区别
传输层两大协议,对比题的标准答法(背熟五条):
| 维度 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(先握手) | 无连接(直接发) |
| 通信方式 | 只能一对一 | 一对一、一对多、多对一、多对多 |
| 数据单位 | 面向字节流 | 面向报文(保留报文边界) |
| 可靠性 | 可靠,不丢不重不乱序 | 尽最大努力交付,可能丢包乱序 |
| 机制 | 有流量控制、拥塞控制 | 无, overhead 小、实时性好 |
- TCP 场景:文件传输(FTP)、邮件(SMTP)、网页(HTTP)——对完整性敏感。
- UDP 场景:即时通讯、视频会议、域名解析(DNS)、广播——对实时性敏感,丢一帧无所谓。
追问点:UDP 一定丢包吗?→ 不一定,只是不保证不丢。TCP 一定可靠吗?→ 只保证”传输层可靠”,应用层 bug 照样丢数据。为什么 DNS 用 UDP?→ 查询报文小、追求低延迟,一次往返搞定。
📌 考法:直接对比题;“为什么视频直播选 UDP”;“TCP 面向字节流是什么意思”(引出第 11 节粘包拆包)。
3. TCP 连接管理(上):三次握手
3.1 握手机制
- 第一次:客户端发
SYN=1, seq=x,进入SYN-SENT。 - 第二次:服务端回
SYN=1, ACK=1, seq=y, ack=x+1,进入SYN-RCVD。 - 第三次:客户端回
ACK=1, ack=y+1,双方进入ESTABLISHED。
3.2 为什么是三次,不是两次/四次
核心目的有两个:确认双方的收发能力 + 同步初始序列号。
- 两次的问题一:服务端无法确认”客户端能收到我的包”(客户端接收能力未验证)。
- 两次的问题二:网络里滞留的失效 SYN 迟到抵达,服务端回 ACK 就建立连接、白白占用资源;三次让客户端可以用一个 RST 拒绝这种历史连接。
- 四次没必要:第二次握手里
SYN+ACK可以合并发送,不必拆成两步。
3.3 每一次握手丢包了会怎样
| 丢失的报文 | 谁重传 | 行为 |
|---|---|---|
| 第一次(SYN) | 客户端 | 超时重传 SYN,间隔指数退避(1s、2s、4s……),次数达上限放弃 |
| 第二次(SYN+ACK) | 双方都重传 | 客户端收不到会重传 SYN,服务端也会超时重传 SYN+ACK |
| 第三次(ACK) | 服务端 | 服务端收不到 ACK 会重传 SYN+ACK;此时客户端已 ESTABLISHED,收到后补 ACK 即可 |
3.4 两个高频追问
- 第二次握手为什么 ACK 还要带 SYN? ACK 是确认收到了客户端的 SYN(确认它的初始序列号 x);SYN 是把服务端自己的初始序列号 y 同步给客户端。两个方向各有一个序列号要同步,缺一不可。
- 第三次握手可以携带数据吗? 可以。前两次不行——此时连接未确认,任何人都能伪造 SYN 发给服务端,若允许携带数据会放大 SYN 洪泛攻击的代价;第三次说明客户端已被服务端确认,带数据是安全的。
📌 考法:画时序图说状态变迁;“两次行不行/四次行不行”;“第三次握手的 ACK 丢了,此时客户端发数据会怎样”(服务端还在 SYN-RCVD,收到数据包可视为确认,直接进入 ESTABLISHED)。
4. TCP 连接管理(下):四次挥手
4.1 挥手过程
假设客户端主动关闭:
- 客户端发
FIN=1, seq=u,进入FIN-WAIT-1。 - 服务端回
ACK=1, ack=u+1,进入CLOSE-WAIT;客户端收到后进入FIN-WAIT-2。此时服务端→客户端方向还能继续传数据(半关闭)。 - 服务端数据发完,发
FIN=1, seq=w,进入LAST-ACK。 - 客户端回
ACK=1, ack=w+1,进入TIME-WAIT,等待 2MSL 后才真正CLOSED;服务端收到 ACK 立即关闭。
4.2 为什么握手三次、挥手却要四次
握手时服务端可以把 SYN+ACK 合并发送;挥手时服务端收到 FIN 后可能还有数据没发完,所以 ACK 先单独回一次(“我知道你要断了”),等数据发完再发自己的 FIN。中间这段”还有话没说完”的窗口就是 CLOSE-WAIT 存在的意义。
4.3 两个重要状态
- TIME-WAIT(等 2MSL):① 保证最后一个 ACK 能到达——若 ACK 丢失,服务端会重传 FIN,客户端还能重发 ACK;② 让本连接的旧报文在网络中自然消亡,避免污染下一个复用同四元组的新连接。
- CLOSE-WAIT 堆积:收到对方 FIN 后,等待本端应用程序调用 close()。线上出现大量 CLOSE-WAIT,几乎都是代码 bug——忘了关闭连接(如异常分支没释放资源),跟网络无关。反过来,大量 TIME_WAIT 通常是本机主动断开的短连接太多。
4.4 保活计时器(keep-alive timer)
服务器每收到一次客户数据就重置保活计时器(通常 2 小时)。2 小时内没收到任何数据,就每隔 75 秒发一个探测报文,连发 9~10 次仍无响应,判定客户端故障,主动关闭连接。
📌 考法:“为什么 TIME-WAIT 要等 2MSL 而不是立即关闭”;“服务器上几万个 CLOSE-WAIT 怎么排查”(先查代码,不是查网络);“TCP keep-alive 和 HTTP keep-alive 是一回事吗”(不是!前者是传输层探活机制,后者是应用层连接复用,见第 8 节)。
5. TCP 报文首部
考”首部有哪些字段”,按顺序背:
| 字段 | 位数 | 作用 |
|---|---|---|
| 源端口 / 目的端口 | 各 16 | 标识应用进程,和 IP 地址组成套接字 |
| 序号 seq | 32 | 字节流中第一个字节的编号,可靠性的基石 |
| 确认号 ack | 32 | 期望收到对方下一个字节的编号 |
| 数据偏移(首部长度) | 4 | 首部占多少个 4 字节,最大 60 字节 |
| 保留 + 标志位 | 6+6 | URG / ACK / PSH / RST / SYN / FIN |
| 窗口 | 16 | 接收窗口 rwnd,流量控制的依据 |
| 检验和 | 16 | 差错检测 |
| 紧急指针 | 16 | URG=1 时有效,指出紧急数据位置 |
| 选项 | 可变 | MSS、窗口扩大、时间戳等 |
追问点:为什么有 TCP 还要有端口号,IP 不是能找到主机吗?→ IP 只定位主机,端口定位主机上的进程,才能实现复用/分用。
6. TCP 如何保证可靠性(总纲题)
标准答题框架,七条:
- 连接管理:三次握手同步序列号、四次挥手优雅断开。
- 序号机制:每个字节编号,接收端可排序、可去重。
- 确认应答(ACK):收到数据回 ACK,累计确认。
- 校验和:首部 + 数据全量校验,出错直接丢弃。
- 超时重传 + 快速重传:丢包兜底(详见第 9 节)。
- 流量控制:滑动窗口,别把接收方撑死(详见第 7 节)。
- 拥塞控制:慢启动等算法,别把网络压垮(详见第 8 节)。
📌 考法:这是道”目录题”——面试官借此决定后续追问方向,每一条都要能展开讲两分钟。
7. 流量控制与滑动窗口
7.1 流量控制
本质:接收方通过 rwnd 字段告诉发送方”我还能收多少”,防止接收缓存被填满丢包。接收方在每个 ACK 里携带最新的窗口值,动态调整。
- 窗口为 0 时发送方暂停发送,但会定期发 零窗口探测报文,防止随后窗口更新报文丢失导致双方互相死等(死锁)。
7.2 滑动窗口
- 发送窗口:无需等待 ACK 就能连续发送的字节范围,收到 ACK 后窗口向前滑动——本质是把”停等协议”改成”连续 ARQ”,大幅提高信道利用率。
- 接收窗口:允许接收、暂存乱序到达的报文,等缺口补齐后一次性向上交付并回累计 ACK。
追问点:流量控制 vs 拥塞控制的对象?→ 前者保护接收端,后者保护网络;发送窗口 = min(rwnd, cwnd)。
8. 拥塞控制
四个算法一条主线——cwnd(拥塞窗口)随时间变化的曲线要会画:
- 慢启动:cwnd 从 1 MSS 起,每收到一个 ACK 加 1,每轮翻倍(指数增长),直到 ssthresh。
- 拥塞避免:超过 ssthresh 后,每轮 RTT 只 +1(线性增长)。
- 快重传:接收方收到失序报文立即重复确认;发送方收到 3 个重复 ACK 就立刻重传丢失段,不等超时。
- 快恢复(配合快重传):判定为”轻度拥塞”,
ssthresh = cwnd/2,cwnd = ssthresh,直接进入拥塞避免(不回到慢启动);只有超时重传这种重度拥塞才把 cwnd 打回 1 重新慢启动。
cwnd │ /│ │ / │ ___─── 拥塞避免(线性) │ / │ __/ │ / └──╱ 快恢复后线性 │ / ssthresh │ / 慢启动(指数) └──────────────────── RTT📌 考法:“画拥塞控制曲线,标注四阶段”;“快重传为什么是 3 个重复 ACK”(1~2 个可能只是乱序,3 个大概率丢包,是时延和误判的折中)。
9. TCP 重传机制
- 超时重传:发送数据后启动计时器,RTO 内没收到 ACK 就重传。RTO 根据往返时间 RTT 动态计算(加权平均 + 安全余量):RTT 估计不准时,RTO 设小了会误重传,设大了丢包响应慢。
- 快速重传:不等超时,收到 3 个重复 ACK 立即重传(见上节),配合快恢复,是”个别包丢失”的高效兜底。
10. TCP 粘包与拆包
现象:TCP 是字节流协议,没有”消息边界”,应用层一次 send 的数据可能被合并成一个包(粘包)或拆成多个包(拆包)发出,接收端 read 的次数和内容与 send 不一一对应。
原因:
- 发送端:Nagle 算法会把多个小报文合并再发(省带宽)。
- 接收端:应用读取不及时,多个报文在接收缓存里堆在一起。
UDP 有这个问题吗? 没有——UDP 面向报文、保留边界,一次 sendto 对应一次 recvfrom。
解决方案(本质全是”应用层自己定义边界”):
- 固定长度:每条消息定长,不足补齐(浪费带宽)。
- 分隔符:如
\r\n(消息体里不能出现分隔符,需转义)。 - 长度字段(最常用):头部先写 body 长度,接收端按长度读取,如
len(4B) + body。
追问点:Netty 的解码器(FixedLengthFrameDecoder / DelimiterBasedFrameDecoder / LengthFieldBasedFrameDecoder)就分别对应这三种方案。
11. HTTP 基础
11.1 如何理解 HTTP 是无状态的
协议对事务处理没有记忆能力:服务器不记得”上一个请求是不是同一个客户端发的”,每个请求相互独立。好处是简单、易做负载均衡;代价是”登录态”没法维持——所以工程上用 Cookie/Session 在应用层补状态(见 11.5)。
11.2 HTTP 请求的过程与原理
- URL 解析 → DNS 解析出 IP(见第 14 节)。
- 与服务器建立 TCP 连接(三次握手)。
- 发送 HTTP 请求报文:请求行(方法 URL 版本)+ 请求头 + 空行 + 请求体。
- 服务器解析请求、处理、返回响应报文:状态行 + 响应头 + 响应体。
- 释放连接或保持连接(keep-alive)。
- 浏览器解析 HTML,遇到 CSS/JS/图片再发请求,最终渲染。
11.3 GET 与 POST 的区别
| 维度 | GET | POST |
|---|---|---|
| 参数位置 | URL 中 | 请求体中 |
| 安全性 | 参数暴露在 URL、会被浏览器历史/日志记录 | 相对不暴露(但都是明文,HTTPS 才是真加密) |
| 长度 | 受浏览器 URL 长度限制(HTTP 协议本身不限) | 理论上无限制 |
| 编码类型 | application/x-www-form-urlencoded | 多种(form-data 等,可传文件) |
| 浏览器行为 | 可缓存、可收藏、可留历史 | 不可缓存 |
| 幂等性 | 幂等(多次执行结果一致) | 不幂等 |
追问点:“GET 和 POST 就安全而言差多少?“——POST 只是”不直观可见”,抓包全透明;“GET 可以带 body 吗?“——RFC 不建议但部分服务器支持。
11.4 状态码与 301/302
| 分类 | 含义 | 常见 |
|---|---|---|
| 1xx | 信息,接收到请求继续处理 | 100、101 |
| 2xx | 成功 | 200、204(无内容)、206(范围请求/断点续传) |
| 3xx | 重定向 | 301、302、304(缓存有效) |
| 4xx | 客户端错误 | 400、401、403、404、405 |
| 5xx | 服务端错误 | 500、502、503、504 |
- 301 永久重定向:资源永久搬家,搜索引擎会用新 URL 替换旧地址(换域名场景)。
- 302 临时重定向:资源临时在别处,搜索引擎保留旧地址(临时活动页、登录跳转)。
11.5 Cookie 与 Session
| 维度 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端(浏览器) | 服务端 |
| 安全性 | 可被查看/篡改,较不安全 | 较安全 |
| 大小限制 | 单条约 4KB,数量受限 | 无特殊限制 |
| 服务器负担 | 无 | 每个会话占服务器资源,分布式下需共享 |
协作方式:登录后服务端创建 Session 并把 SessionID 写入 Cookie,之后每次请求自动携带,服务器据此找回会话。Cookie 被禁用时用 URL 重写(SessionID 拼在 URL 上)兜底。
11.6 forward 与 redirect
| 维度 | forward(转发) | redirect(重定向) |
|---|---|---|
| 谁发起跳转 | 服务器内部 | 服务器返回 302,由浏览器再次发请求 |
| 请求数 | 1 次 | 2 次 |
| 地址栏 | 不变 | 变为新地址 |
| 数据共享 | 共享同一个 request 域 | 两次独立请求,不共享 |
11.7 长连接与 HTTP 版本演进
HTTP 如何实现长连接?
- HTTP/1.0:
Connection: keep-alive请求头开启,默认关闭。 - HTTP/1.1:默认持久连接,一个 TCP 连接可发多个请求,省去反复三次握手/四次挥手的开销(此即 HTTP keep-alive,与 TCP 层探活的 keep-alive 同名不同物)。
1.0 / 1.1 / 2.0 的区别:
| 版本 | 核心特性 |
|---|---|
| 1.0 | 每个请求都要新建 TCP 连接,完了就断,开销大 |
| 1.1 | 默认长连接;管线化(pipeline,串行响应,鸡肋);更强的缓存控制(Cache-Control、ETag);断点续传(Range/206) |
| 2.0 | 二进制分帧(不再是文本协议);多路复用(一个连接并发多个流,解决 1.1 的队头阻塞);头部压缩 HPACK;服务器推送 |
📌 考法:“HTTP/1.1 的队头阻塞是什么、2.0 解决了吗”(1.1 是 TCP 上的串行响应阻塞;2.0 解决了应用层队头阻塞,但 TCP 层丢包仍会阻塞所有流,彻底解决要看 3.0 的 QUIC);“长连接了为什么还有 2.0 多路复用”(长连接只是复用连接,请求仍需按序排队)。
12. HTTPS 与网络安全
12.1 对称加密 vs 非对称加密
| 维度 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥 | 加解密同一把密钥 | 公钥加密、私钥解密 |
| 性能 | 快,适合大数据量 | 慢几个数量级,只适合小数据 |
| 难点 | 密钥如何安全地发给对方? | 无此问题,公钥可公开 |
| 算法 | DES、3DES、AES | RSA、ECC |
HTTPS 的答案:两者结合——非对称加密解决”密钥交换”,对称加密负责”数据传输”,各取所长。
12.2 数字签名与数字证书
- 数字签名:发送方对报文算哈希得到摘要,用自己的私钥加密摘要,附在报文后。接收方用发送方公钥解出摘要再自行哈希比对——防伪造、防篡改、可抵赖不了(只有私钥持有者能签)。
- 数字证书:由 CA 签发,把”服务器身份 + 服务器公钥”绑定在一起并用 CA 的私钥签名。解决的问题是:非对称加密里你怎么确定”这把公钥真的是服务器的”?没有证书,中间人可以偷换公钥实施中间人攻击(MITM)。
12.3 HTTPS 的工作流程(TLS 握手简化版)
- 客户端发
Client Hello:支持的 TLS 版本、加密套件、随机数 C。 - 服务端发
Server Hello+ 数字证书(含服务端公钥)+ 随机数 S。 - 客户端验证证书(CA 链、域名、有效期),通过后生成预主密钥,用服务端公钥加密后发出。
- 双方用(随机数 C + 随机数 S + 预主密钥)算出相同的会话密钥,此后全部用会话密钥做对称加密通信。
12.4 HTTP 与 HTTPS 的区别
| 维度 | HTTP | HTTPS |
|---|---|---|
| 传输 | 明文 | SSL/TLS 加密 |
| 端口 | 80 | 443 |
| 证书 | 不需要 | 需要 CA 证书 |
| 安全性 | 可被窃听、篡改、劫持 | 防窃听、防篡改、防冒充 |
| 性能 | 快 | 握手 + 加解密有开销 |
📌 考法:“HTTPS 既用对称又用非对称,为什么”(性能);“证书验证失败浏览器会怎样”;“三次随机数的作用”(保证密钥不可预测、双方都有贡献)。
13. DNS 解析过程
一条完整链路(查 www.example.com):
- 依次查本地缓存:浏览器缓存 → 系统缓存 → hosts 文件 → 本地域名服务器。
- 本地 DNS 没有,替你开始迭代查询:问根域名服务器(“.com 在谁那?”)→ 问顶级域名服务器 .com(“example.com 在谁那?”)→ 问权威域名服务器(给出最终 IP)。
- 本地 DNS 把结果返回客户端并缓存。
两类查询的区别:
- 递归查询:客户端 → 本地 DNS。“你必须给我最终答案”(客户端只问一次)。
- 迭代查询:本地 DNS → 根/顶级/权威。“不知道就去问别人”(本地 DNS 自己跑多趟)。
追问点:“DNS 为什么用 UDP 又说有 TCP?“(查询报文小走 UDP 53;区域传送和超大响应走 TCP);“怎么劫持 DNS”(改 hosts、污染、劫持本地 DNS)。
14. WebSocket 与 Socket
- WebSocket:应用层协议,借 HTTP 完成一次握手后升级为全双工长连接,服务器可主动推送,解决了 HTTP “请求—响应”模式下服务器不能主动发数据的痛点(实时聊天、行情推送)。
- Socket:不是协议,是操作系统提供给应用程序使用 TCP/UDP 进行网络通信的 API 抽象(套接字 = IP + 端口),处于传输层之上、应用层之下的编程接口。
一句话:WebSocket 是协议,Socket 是接口,名字像但不是一个层面的东西。
15. 综合大题:从输入 URL 到页面显示
把前面所有知识串成一条线,这是必考的压轴题,按七步答:
- URL 解析:检查合法性、补全协议。
- DNS 解析:缓存 → 本地 DNS → 递归/迭代拿到 IP(第 13 节)。
- 建立 TCP 连接:三次握手(第 3 节)。
- (若是 HTTPS)TLS 握手:证书验证 + 密钥协商(第 12 节)。
- 发送 HTTP 请求,服务器处理后返回响应(第 11 节)。
- 浏览器解析渲染:解析 HTML 构建 DOM、解析 CSS 构建 CSSOM、合成渲染树、布局、绘制;遇到 JS/图片等子资源继续发起请求。
- 连接处理:keep-alive 复用或四次挥手断开(第 4 节)。
答题技巧:先报”七步框架”,再等面试官挑某一步深挖——这一题本质是面试官的”目录”,用来决定后续追问。
16. 高频面试题自测清单
每题先自己说 30 秒再看要点(按出现频率排序):
- TCP 和 UDP 的区别? 五条对比 + 各自典型场景。
- 三次握手过程?为什么不是两次/四次? 确认双方收发能力 + 同步序列号;防历史失效 SYN;SYN+ACK 可合并不用四次。
- 四次挥手过程?为什么不是三次? 全双工两个方向独立关闭;服务端收到 FIN 后可能还有数据,ACK 与 FIN 分开发。
- TIME_WAIT 为什么要等 2MSL?CLOSE-WAIT 堆积说明什么? 保 ACK 到达 + 旧报文消亡;CLOSE-WAIT 堆积查代码没 close。
- 第三次握手能带数据吗? 能;前两次不能,防 SYN 洪泛放大攻击。
- TCP 怎么保证可靠? 七条总纲(连接管理/序号/确认/校验和/重传/流控/拥塞控制)。
- 流量控制和拥塞控制的区别?滑动窗口原理? 保护接收端 vs 保护网络;rwnd 连续 ARQ、零窗口探测;cwnd 四算法曲线。
- 慢启动、拥塞避免、快重传、快恢复? 指数→线性→3 个重复 ACK→cwnd 减半线性续。
- 粘包拆包是什么?怎么解决? 字节流无边界;定长/分隔符/长度字段。
- GET 和 POST 的区别? 位置/安全/长度/缓存/幂等六条。
- 301 和 302 的区别? 永久 vs 临时重定向,搜索引擎对旧地址的处理不同。
- Cookie 和 Session? 客户端 vs 服务端、SessionID 通过 Cookie 传递。
- HTTP 1.0/1.1/2.0 演进? 短连接→长连接/缓存/断点续传→二进制分帧/多路复用/头部压缩/推送。
- HTTPS 加密流程?为什么混合加密? 非对称换密钥、对称传数据(性能);三随机数 + 证书防 MITM。
- 对称/非对称加密?数字签名和证书? 快 vs 可公开分发;私钥签名防篡改、CA 证书绑定身份与公钥。
- DNS 解析过程?递归和迭代? 缓存→本地→根→顶级→权威;客户端递归、DNS 迭代。
- 从输入 URL 到显示主页? 七步框架串联全篇。
- WebSocket 和 Socket 的区别? 应用层全双工协议 vs 编程 API。
17. 收尾总结
计算机网络八股的三条主线:传输层围绕 TCP 的”连接—可靠—不撑死接收方—不压垮网络”四大机制展开(三次握手、重传、流控、拥塞控制);应用层围绕 HTTP 的”演进—状态保持—安全升级”展开(版本演进、Cookie/Session、HTTPS 混合加密);全局用一道 URL 访问综合题串联所有模块。答题套路和 Redis 篇一致:先给结论/对比表,再讲原理,最后补一个加分点(队头阻塞在 2.0/3.0 的延续、TIME_WAIT 与连接复用、快恢复不回慢启动的原因)。33 问看着多,挂到分层模型这棵树上,就只剩三根主枝。