计算机网络 · 最高频面试 20 题(含答案解析)
配套文件:
计算机网络最高频150道选择题(含答案解析).md(选择题笔试专用)、计算机网络·选择题高频缺口补题(16道·含答案解析).md(缺口补题) 本题定位: 互联网技术岗面试问答(八股)专用,与选择题库互补、不重叠。 排序依据: 八股精 2025–2026 年约 6975 条真实面试记录的网络考点热度统计,按热度降序取前 20。 说明: 面试考的是「原理 + 场景 + 异常处理」三位一体。本版在原有 Q/A 骨架上深化为完整口述/学习深度:每题含完整过程(报文/状态机/时序)、设计动机、常见追问、易错点、选择题对照、工程/抓包背景。题号与热度标注不变,技术结论以深化表述为准。 热度对照: 核心必考(>500)|高频选考(300–500)|进阶(<300) 结构约定: 每题统一为 → Q / A(过程·动机)→ 常见追问 → 易错点 → 与选择题对照 → 工程/抓包背景
1. TCP 三次握手(热度 654 · 核心必考)
Q: 描述 TCP 三次握手过程。为什么是三次而不是两次或四次?
A:
完整过程(报文 + 状态机)
客户端(C) 服务器(S)
| CLOSED | LISTEN
| |
|--- SYN=1, seq=x ------------->| (服务器收到 SYN)
| SYN-SENT | SYN-RCVD
|<-- SYN=1, ACK=1, seq=y, ack=x+1
| |
|--- ACK=1, seq=x+1, ack=y+1 -->| ESTABLISHED
| ESTABLISHED |- 第一次握手(SYN): 客户端
SYN=1, seq=x(x 为客户端 ISN,随机生成)。SYN 报文段不携带数据,但要消耗一个序号。客户端进入SYN-SENT。 - 第二次握手(SYN+ACK): 服务器收到后回
SYN=1, ACK=1, seq=y, ack=x+1。ack=x+1表示「我期望下次收到 x+1」。服务器进入SYN-RCVD。该报文同样不携带数据,消耗一个序号。 - 第三次握手(ACK): 客户端回
ACK=1, seq=x+1, ack=y+1。第三次可以携带数据(一旦携带,seq 从 x+1 起算;不携带则下一个数据段 seq 仍是 x+1)。双方进入ESTABLISHED。
半连接/全连接队列: 服务器收到 SYN 后为它建一个 request sock 放进半连接队列(SYN queue,长度受 tcp_max_syn_backlog 限制),回 SYN+ACK;收到第三次 ACK 后,把完成握手的 established sock 迁移到全连接队列(accept queue,长度取 min(somaxconn, backlog)),等待应用 accept() 取走。两条队列是相互独立的(半连接队列不是 accept queue 的"前半段"),SYN Flood 正是打满半连接队列。
设计动机:为什么是三次?
- 同步双方 ISN: 双方都要确认「自己的发送能力」和「对方的接收能力」。一次不行(服务器不知道客户端是否收到自己的 SYN);两次时客户端知道服务器收到了,但服务器无法确认客户端收到了自己的 SYN+ACK。
- 防止历史连接 / 旧 SYN 复活: 若只有两次,一个滞留在网络中的旧 SYN 到达服务器后,服务器单方面建立连接并分配资源,而客户端并不认这条连接——资源被白白占用。第三次 ACK 让服务器确认「客户端确实要建这条连接」。
- 可靠信道建立的本质: 在不可靠信道上双向同步序号,最少需要「A→B、B→A、A→B」三个方向确认,使双方对「连接已建立」达成共识。
为什么不是四次?
服务器把 SYN 和 ACK 合并成一个报文(第二次)。SYN 表示「我也要同步我的序号」,ACK 表示「我收到了你的 SYN」——两者语义上可合并,所以 3 次足够。对照挥手:被动方的 ACK 与 FIN 不能合并(可能还有数据要发),所以挥手是 4 次。
加分点
- 第三次握手可以携带数据,但业界较少用:此时服务器尚未收到这个 ACK,仍在 SYN-RCVD,连接对服务器而言还没完全建立。若第三次 ACK 丢失,服务器会超时重传 SYN+ACK(受
tcp_synack_retries限制);客户端发完 ACK 已进入 ESTABLISHED,不会重传 SYN,它后续写数据时要么收到服务器的 RST,要么再回一个 ACK 把服务器拽回 ESTABLISHED。 - SYN Flood:大量伪造源 IP 发 SYN 且不回第三次 ACK,半连接队列被占满。防御:
tcp_syncookies=1、调小tcp_synack_retries、增大tcp_max_syn_backlog、SYN Proxy。 - 可提:TFO(TCP Fast Open)允许在 SYN 中携带 Cookie+数据,减少 1-RTT,但需两端支持。
常见追问
追问 1:SYN Flood 的原理与防御?
- 答题要点: 原理——攻击者只发 SYN,不完成第三次握手,服务器半连接队列/资源被耗尽,合法连接进不来。防御——① syncookies(不占队列,把状态编码进 SYN+ACK 序号,收到合法第三次 ACK 再建连);② 增大半连接队列、缩短 SYN-RCVD 超时;③ 防火墙限速、过滤伪造源 IP;④ 上游清洗。
追问 2:如果第三次握手丢了会怎样?
- 答题要点: 客户端认为连接可能已建立(发完 ACK 后 ESTABLISHED),但服务器仍在 SYN-RCVD,会重传 SYN+ACK(超时重传,受
tcp_synack_retries限制)。客户端收到重复 SYN+ACK 后再次回 ACK。若始终收不到,服务器放弃,客户端连接在发数据时才发现异常(RST 或超时)。
追问 3:ISN 为什么是随机的?可以是 0 吗?
- 答题要点: 随机 ISN 防止「序号预测攻击」和「旧连接报文干扰新连接」——若 ISN 固定为 0,网络中滞留的旧报文 seq 恰好落在新连接窗口内,会被误收。现代实现还加入时间戳与加密随机数(RFC 6528)。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「三次握手是为了可靠传输数据」 | 握手阶段主要目的是同步序号、双方确认能力;数据可靠传输靠 seq/ack/重传等机制 |
| 「前两次都能携带数据」 | SYN 报文段规范上不携带数据;第三次才可以 |
| 「两次握手完全不可用」 | 若信道绝对可靠且无历史报文问题,两次理论上可行;现实是丢包/延迟/重复网络,两次会留下历史连接漏洞 |
| 「SYN-RCVD 就是 ESTABLISHED」 | 服务器在 SYN-RCVD 仍等待第三次 ACK;ESTABLISHED 以收到第三次 ACK(或 syncookie 验证成功)为准 |
| 「ack=x 是确认收到 SYN」 | 应是 ack=x+1——确认的是「期望的下一个序号」,比已收序号大 1 |
与选择题对照
- 主库 150: 第 60 题(握手/挥手次数)、第 61 题(第二次握手 SYN=1, ACK=1)、第 117 题(SYN Flood 针对建连过程)、第 59 题(端到端可靠传输层)、第 124 题(协议顺序中 TCP 在 TLS 前)。
- 补题 16: 补-12(三次握手而不是两次的最主要原因)、补-11(TCP 首部标志位 URG/ACK/PSH/RST/SYN/FIN)。
- 口述联动: 面试展开时可回扣「补-12 考的是历史连接与资源浪费,不是『能不能传数据』」。
工程 / 抓包背景
- Wireshark 过滤:
tcp.flags.syn==1 && tcp.flags.ack==0看第一次;tcp.flags.syn==1 && tcp.flags.ack==1看第二次;完整握手可看tcp.flags.syn==1 || tcp.flags.ack==1前三包。 - 观察半连接: Linux
ss -tn state syn-recv/netstat -ant | grep SYN_RECV;cat /proc/net/sockstat看TCP: inuse/tw/orphan与 syn 队列。 - sysctl 相关:
net.ipv4.tcp_syncookies、net.ipv4.tcp_max_syn_backlog、net.ipv4.tcp_synack_retries。 - curl 侧:
curl -v --connect-timeout 3 https://example.com;若 SYN 无响应,表现 connect 超时;若被 RST,表现 connection refused。
2. TCP 四次挥手与 TIME_WAIT(热度 654 · 核心必考)
Q: 描述四次挥手过程。为什么是四次?TIME_WAIT 为什么要等 2MSL?
A:
完整过程(报文 + 状态机)
主动关闭方(A) 被动关闭方(B)
| ESTABLISHED | ESTABLISHED
|--- FIN=1, seq=u ------------->| CLOSE-WAIT
| FIN-WAIT-1 | (应用仍可发数据)
|<-- ACK=1, ack=u+1, seq=v -----|
| FIN-WAIT-2 |
| (B 继续发送剩余数据) |
|<-- FIN=1, seq=w --------------| LAST-ACK
|--- ACK=1, ack=w+1 ----------->|
| TIME-WAIT(等2MSL) | CLOSED(收到ACK后)
| → CLOSED |- A→B:FIN=1, seq=u:A 告诉 B「我没有数据要发了」(半关闭:仍可接收)。A 进入
FIN-WAIT-1。 - B→A:ACK=1, ack=u+1:B 确认。B 进入
CLOSE-WAIT。此时 B 应用层可能还有数据要发完。 - B→A:FIN=1, seq=w:B 数据发完,也发 FIN。B 进入
LAST-ACK。 - A→B:ACK=1, ack=w+1:A 确认,进入
TIME-WAIT,等待 2MSL 后进入CLOSED。B 收到 ACK 后CLOSED。
补充状态: 若 A 在 FIN-WAIT-1 收到 FIN(B 也立刻关),可同时确认,进入 CLOSING,再收 ACK 后 TIME-WAIT;或 B 的 ACK 与 FIN 一起到,A 直接从 FIN-WAIT-1 进 TIME-WAIT。
设计动机:为什么是四次?
- TCP 全双工,每个方向要单独关闭。 FIN 只表示「这个方向我不再发送」。
- 被动方收到 FIN 后可能还有数据要发,所以 ACK(确认你的 FIN)和 FIN(我也关了)不能合并——这正是不像握手能省一次的原因。
- 半关闭(half-close)有实际价值: 如客户端发完请求后 shutdown write,服务器仍能把剩余响应发完再关。
TIME_WAIT 等 2MSL 的原因
MSL(Maximum Segment Lifetime)是报文最大生存时间。
- 保证最后一个 ACK 能到达: 若最后的 ACK 丢失,被动方会重传 FIN;主动方仍在 TIME-WAIT 才能再发 ACK。若主动方立刻消失,被动方会卡在 LAST-ACK。
- 让本次连接的旧报文在网络中自然消亡: 等待超过「报文最长寿命」后,相同四元组(源IP、源端口、目的IP、目的端口)的新连接不会误收旧报文。
Linux 实际: Linux 的 TIME-WAIT 时长是内核常量 TCP_TIMEWAIT_LEN = 60 秒,写死在 include/net/tcp.h 里,不可通过 sysctl 调整,也与 tcp_fin_timeout 无关(tcp_fin_timeout 管的是没有文件描述符引用的孤儿连接在 FIN-WAIT-2 的停留时间,默认 60s——两者常被混为一谈)。RFC 793 定义的 MSL = 2 分钟,按 2MSL 算应是 4 分钟;教材常写 2MSL(谢希仁第8版取 MSL=2 min ⇒ 4 min),Linux 用 60s 是工程折中(内核 tcp.h 里它就是个写死的常数,注释并未按 2×MSL 推导;RFC 793 的 MSL=2 min 若要 2MSL 应是 4 min。别临时编一个「报文最大存活 30s」去调和这两个数——那没有出处)。答题口径:规范是 2MSL,Linux 实现固定 60s。
加分点
- 高并发短连接服务器大量 TIME_WAIT:优化
tcp_tw_reuse(安全前提下复用)、tcp_max_tw_buckets、连接池/长连接。TIME_WAIT 是正常现象;CLOSE_WAIT 堆积才是 bug(见第 18 题)。 - 主动关闭方才会 TIME-WAIT:「谁 TIME_WAIT 谁主动关」——排查时看 TIME_WAIT 出现在服务端还是客户端。
tcp_tw_recycle因在 NAT 环境下时间戳不一致会误杀新连接,Linux 4.12 起已彻底删除(不是"不推荐",而是新版本根本没有这个开关);tcp_tw_reuse仍在,取值 0/1/2(0=关闭;1=全局启用;2=只对回环流量启用,内核ip-sysctl.rst原文为 "1 - global enable / 2 - enable for loopback traffic only")。默认值可核:Linux 4.17 及以前是 0/1 两值、默认 0;4.18 起默认 2(本机 7.0.0 内核sysctl net.ipv4.tcp_tw_reuse实测为 2)。可见默认值只允许复用回环连接的 TIME_WAIT 套接字,要让出站公网连接也复用需显式设成 1;另外复用还要求对端启用了时间戳、且距上次时间戳更新超过tcp_tw_reuse_delay(默认 1000 ms)。
常见追问
追问 1:为什么握手 3 次、挥手 4 次?
- 答题要点: 握手时服务器 SYN+ACK 可合并;挥手时被动方 ACK 与 FIN 必须分开——收到 FIN 只代表「对方不发了」,本方可能还有数据。合并会强迫本方立刻停止发送,破坏全双工。
追问 2:大量 TIME_WAIT 怎么处理?一定是问题吗?
- 答题要点: 不一定是问题,是主动关闭方短连接多的正常结果。问题在于耗尽本地端口/Ephemeral port 或文件描述符相关资源。处理:① 应用层连接池/HTTP keep-alive;②
net.ipv4.tcp_tw_reuse=1(允许对出站连接复用 TIME_WAIT);③ 调大端口范围ip_local_port_range;④ 一般不盲目tcp_tw_recycle。先用ss -tan state time-wait确认分布。
追问 3:如果服务器出现大量 CLOSE_WAIT,和 TIME_WAIT 有什么本质区别?
- 答题要点: TIME_WAIT 多 = 主动关闭方短连接多(可优化,不一定有 bug)。CLOSE_WAIT 多 = 本端收到了对端 FIN,但应用层迟迟没调用 close()——典型代码 bug(连接泄漏、异常未捕获、线程阻塞、连接池未归还)。见第 18 题。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「TIME_WAIT 出现在被动关闭方」 | 出现在主动关闭方;被动方是 CLOSE_WAIT → LAST_ACK |
| 「2MSL 是为了让数据传完」 | 数据在 FIN/ACK 阶段已谈完发送方向;2MSL 为 ACK 可达性 + 旧报文消亡 |
| 「TIME_WAIT 很多说明网络故障」 | 多数情况是短连接负载高,属正常;故障信号更多是 CLOSE_WAIT/SYN_RECV 异常 |
| 「四次挥手是因为 TCP 不可靠」 | 四次源于全双工 + 半关闭语义,与可靠重传机制不是同一层原因 |
| 「服务器 TIME_WAIT 一定该关掉」 | 不能用内核 hack 一味清 TIME_WAIT;优先改连接模型 |
与选择题对照
- 主库 150: 第 60 题(挥手次数)、第 62 题(主动关闭方最后一个报文=ACK)、第 63 题(TIME_WAIT 时长)、第 138 题(大量 CLOSE_WAIT 含义)。
- 补题 16: 补-11(TCP 标志位,FIN/ACK 等);与补-12 形成「建连/释放」对照。
- 口述联动: 选择题侧重「次数/标志位/时长」,面试侧重「为什么 4 次、2MSL 两个原因、TIME_WAIT vs CLOSE_WAIT」。
工程 / 抓包背景
- ss 命令:
ss -tan state time-wait | wc -lss -tan state close-waitss -tan sport = :80 or dport = :80
- Wireshark: 过滤
tcp.flags.fin==1;观察 FIN/ACK 时序;tcp.analysis.flags可看重传。 - sysctl:
net.ipv4.tcp_fin_timeout、net.ipv4.tcp_tw_reuse、net.ipv4.tcp_max_tw_buckets、net.ipv4.ip_local_port_range。 - Nginx:
keepalive_timeout、keepalive_requests;上游proxy_http_version 1.1; proxy_set_header Connection "";以复用上游连接,减少服务端主动关闭。
3. TCP 与 UDP 的区别及适用场景(热度 780 / 352 · 核心必考)
Q: TCP 和 UDP 有什么区别?各自适用什么场景?
A:
本质差异(先说结论)
TCP 面向字节流,UDP 面向数据报。 字节流不保留边界(因此有粘包问题);数据报保留边界(一次收一个完整报文)。其余区别都是这一本质 + 设计目标的延伸。
完整对照
| 维度 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(握手/挥手) | 无连接 |
| 可靠性 | 可靠(序号、确认、重传、校验) | 不可靠(尽最大努力) |
| 有序性 | 有序(接收端按序交付) | 无序(可能乱序/重复/丢失) |
| 首部 | 20–60 字节(可变选项) | 8 字节(固定) |
| 流量控制 | 有(rwnd 滑动窗口) | 无 |
| 拥塞控制 | 有(cwnd,慢开始等) | 无(发送方想发就发) |
| 传输方式 | 一对一 | 一对一 / 一对多 / 多对多 / 广播 |
| 速度 | 相对慢、开销大 | 快、开销小 |
| 应用标识 | 端口号 | 端口号(与 TCP 端口独立命名空间) |
| 边界 | 字节流,需应用层定界 | 数据报,天然有边界 |
设计动机
- UDP 为何「简单」: 网络层 IP 已是不可靠的;UDP 只做复用/分用 + 可选校验,把控制权交给应用。符合端到端原则:需要什么可靠性由应用定制(或干脆不需要)。
- TCP 为何「复杂」: 大多数应用(文件、网页、邮件)需要可靠有序字节流;由操作系统统一实现,应用不必各自造轮子。
- TCP 无 UDP 端口冲突: 内核用「协议号 + 端口」区分,TCP 53 与 UDP 53 可并存。
适用场景
- TCP: HTTP/HTTPS、FTP、SMTP/POP3/IMAP、数据库连接、SSH、Redis/MySQL 客户端等——要求可靠、有序、字节流语义。
- UDP: DNS(查询小、一问一答)、DHCP(广播)、SNMP、音视频/直播、实时游戏、QUIC(HTTP/3)、NTP 等——低延迟优先,或可自行实现可靠性。
- 选型规律: ① 请求-响应、报文小 → UDP(DNS);② 能容忍丢失、重传反而更糟 → UDP(实时音视频);③ 需要广播/多播 → UDP(DHCP Discover);④ 数据完整有序不可缺 → TCP。
加分点
- 弱网下 UDP 更优:无队头阻塞,重传策略可由应用层定制(只重传关键帧/关键包)。
- HTTP/3(QUIC)选 UDP 正是为了绕开 TCP 层队头阻塞,并在用户态实现可靠传输、流控、加密、连接迁移。
- 「UDP 不可靠」≠「UDP 应用都不可靠」:QUIC/RTCP/WebRTC 自建选择重传与 FEC。
常见追问
追问 1:UDP 没有拥塞控制会怎样?
- 答题要点: 发送方可打满链路,挤垮同路径其他流(公平性差)。所以现代 UDP 应用(QUIC、WebRTC、BBR over UDP)都自带拥塞控制,只是实现位置在用户态/应用层。
追问 2:UDP 校验和与伪首部是什么?
- 答题要点: UDP 校验和覆盖「伪首部(源/目的 IP、协议号、UDP 长度)+ UDP 首部 + 数据」。伪首部不是 UDP 真正首部,仅用于校验,防止 IP 层把报文送错主机/送错协议。IPv6 中 UDP 校验和必选(因 IPv6 首部无校验和)。
追问 3:TCP 和 UDP 端口号会不会冲突?
- 答题要点: 不会。五元组/内核 socket 以「协议 + 本地地址 + 本地端口 + 对端」区分。DNS 同时使用 TCP 53 与 UDP 53,互不干扰。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「UDP 不可靠所以不能传文件」 | 可以,只要应用层自建可靠性(TFTP、QUIC);代价是重复造轮子 |
| 「TCP 面向连接=有一条专线」 | 连接是逻辑的端状态与资源分配,底层仍是 IP 分组转发 |
| 「UDP 首部有确认号」 | UDP 首部仅:源端口、目的端口、长度、校验和,共 8 字节 |
| 「HTTP/3 仍基于 TCP」 | HTTP/3 基于 QUIC,传输在 UDP 之上 |
| 「TCP 一定比 UDP 慢」 | 在可靠传输需求下 TCP 往往更合适;「慢」指控制开销与队头阻塞等,不是绝对延迟排序 |
与选择题对照
- 主库 150: 第 121 题(TCP/UDP 对比正确项)、第 64 题(UDP 特点)、第 65 题(哪些应用用 UDP)、第 72 题(端口号关系)、第 59 题(端到端可靠传输层)、第 40 题(IP 尽最大努力)、第 12 题(分组交换)。
- 补题 16: 补-13(UDP 叙述错误项,考伪首部与校验;该题未涉及多播)、补-14(邮件协议用 TCP,与 UDP 场景对照)。
- 口述联动: 选择题常考「哪个协议用 UDP」;面试要补上为什么选 UDP(延迟/广播/可定制可靠性)。
工程 / 抓包背景
- Wireshark:
udp、dns;对比tcp.stream看字节流,UDP 每包独立。 - ss:
ss -uanp看 UDP socket;ss -tanp看 TCP。 - curl:
curl --http3 https://example.com(需编译支持)可观察 UDP 443 上的 QUIC。 - Nginx: HTTP/3 需
listen 443 quic reuseport;与add_header Alt-Svc;DNS 服务器常用 UDP 53,区域传送 zone transfer 用 TCP 53。
4. TCP 如何保证可靠传输(热度 310 · 高频选考)
Q: TCP 靠什么机制保证可靠?
A:
机制全景(四件套 + 两把窗口)
可靠性目标:数据无差错、不丢失、不重复、按序到达。
序号与确认(seq/ack)
- 每个字节都有序号;报文段首部
Sequence Number是本报文数据的首字节序号。 - 接收方用累积确认:
ack=N表示「N 之前的所有字节都已正确收到,期望下次从 N 开始」。 - TCP 对数据字节编号,不是「第几个包」。
- 每个字节都有序号;报文段首部
超时重传(Retransmission Timeout)
- 每个报文段有关联 RTO 定时器;超时未确认则重传。
- RTO 由 RTT 动态估算:
SRTT ← (1-α)SRTT + α*SampleRTT,RTO = SRTT + 4*RTTVAR。 - Karn 算法: 重传的 RTT 样本不可信(无法区分是对原包还是重传包的确认),要排除;RTO 退避(倍增)。
快速重传
- 连续收到 3 个重复 ACK 立即重传丢失段,不等超时。
- 省下的是整个 RTO 等待,不是"一个 RTT":凑齐 3 个重复 ACK 本身约要 1 个 RTT,而走超时路径要等 RTO —— 本机内核
include/net/tcp.h里TCP_RTO_MIN = HZ/5(CONFIG_HZ=1000→ 200ms 下界),初始 RTOTCP_TIMEOUT_INIT = 1*HZ(1s,RFC 6298 §2.1 的初始值 1s),上界TCP_RTO_MAX = 120*HZ(120s)。所以快重传把重传时延从数百毫秒~秒级压到 RTT 级,这才是它的收益量级。 - 重复 ACK 的含义:「我期望序号 X,但收到了 X 之后的数据」——中间有洞。
校验和
- 首部 + 数据的 16 位校验(含伪首部),检出比特错误则丢弃(等待重传)。
流量控制(rwnd)——面向接收方
- 接收方在 ACK 中通告窗口字段:「我还能收多少字节」。
- 接收缓冲区满 → 通告 0 窗口;发送方启动零窗口探测定时器。
拥塞控制(cwnd)——面向网络
- 根据网络拥塞程度调整发送速率(见第 6 题)。
- 实际发送窗口 = min(rwnd, cwnd)。
补充机制(深化)
- 乱序缓存: TCP 收到乱序段不丢弃,缓存并回重复 ACK 催缺口(更像 SR 而非 GBN)。
- 去重: 接收端按序号去重。
- 保活与 RST: 异常时用 RST 复位连接。
设计动机
- 为什么用累积确认而不是每包单独确认? 减少 ACK 数量、简化实现;配合快速重传与 SACK 可减轻「累计确认带来的模糊性」。
- 为什么快速重传门限是 3? 1 个重复 ACK 可能是乱序;连续 3 个说明后续多个包都到了但中间缺一块,更确信是丢包。
- 区分「可靠传输」与「拥塞控制」: 可靠面向接收方交付正确性;拥塞面向网络不被打垮。两者机制独立、最终窗口取 min。
常见追问
追问 1:TCP 收到乱序包会丢弃吗?和 GBN 什么关系?
- 答题要点: 不丢弃,缓存乱序段并发送重复 ACK,促使发送方快速重传缺口。更像选择重传 SR,而不是「丢弃一切乱序」的 GBN。笔试若问 GBN/SR 窗口上限是另一套题(补-03/04)。
追问 2:SACK 是什么?解决什么问题?
- 答题要点: Selective Acknowledgment,TCP 选项。接收方在 ACK 中告诉发送方「哪些非连续块已收到」,发送方只重传缺失段,避免累计确认导致的重复发送。需要双方协商开启。
追问 3:可靠传输 = 100% 不丢数据吗?
- 答题要点: TCP 提供的是在连接存续期间、网络最终能恢复的前提下的可靠字节流。若网络长期中断、应用崩溃、连接被 RST,仍可能失败。可靠性是传输层协议语义,不是分布式系统级的端到端 exactly-once。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「ACK 确认的是包不是字节」 | TCP 对字节编号,ACK 是期望序号(累积) |
| 「可靠传输=拥塞控制」 | 可靠侧重序号/重传/校验;拥塞控制侧重网络速率,发送窗口取两者 min |
| 「超时与快速重传窗口变化一样」 | 超时:cwnd 回 1 重新慢开始;快速重传触发快恢复:cwnd 降到约一半 |
| 「TCP 从不缓存乱序」 | 会缓存,配合重复 ACK / SACK |
| 「校验和能纠错」 | 只检错;纠错靠重传 |
与选择题对照
- 主库 150: 第 59 题(端到端可靠传输)、第 66 题(流量控制目的)、第 67 题(发送窗口取决于)、第 68 题(3 个重复 ACK)、第 69 题(超时重传后 cwnd)、第 78 题(乱序报文段处理)、第 121 题(TCP/UDP 对比)。
- 补题 16: 补-03(GBN 窗口上限)、补-04(SR 窗口上限)、补-11(TCP 首部)。
- 口述联动: 选择题「乱序会怎样」答「缓存+重复 ACK」,与本题可靠传输机制直接衔接。
工程 / 抓包背景
- Wireshark:
tcp.analysis.duplicate_ack、tcp.analysis.retransmission、tcp.analysis.out_of_order、tcp.options.sack。 - ss:
ss -tin可看到rtt、cwnd、retrans、snd_wnd等 TCP 内部信息;注意 iproute2 没有名为rwnd的字段——「对端通告的接收窗口」在这里叫snd_wnd(uapitcpi_snd_wnd注释即 "peer's advertised receive window after scaling"),本端接收侧则是rcv_space/rcv_ssthresh;当发送被对端窗口卡住时还会多一个rwnd_limited:<ms>。 - sysctl:
net.ipv4.tcp_sack、net.ipv4.tcp_timestamps、net.ipv4.tcp_rmem/tcp_wmem。 - 现象: 大量 retransmission + RTT 抖动 → 网络丢包/缓冲膨胀;SACK 块多 → 非连续丢包;零窗口 → 接收方处理不过来(应用层消费慢)。
5. 流量控制与拥塞控制的区别(热度 310 · 高频选考)
Q: 流量控制和拥塞控制有什么区别?
A:
对照表
| 维度 | 流量控制 | 拥塞控制 |
|---|---|---|
| 目的 | 防止发送方压垮接收方 | 防止发送方压垮网络 |
| 依据 | 接收方通告的 rwnd | 发送方探测的 cwnd |
| 手段 | 滑动窗口、零窗口探测、糊涂窗口综合症(SWS)处理 | 慢开始、拥塞避免、快重传、快恢复 |
| 作用域 | 端到端(发送方↔接收方) | 全局(涉及所有主机与路由器) |
| 谁维护 | 接收方计算并通告;发送方遵守 | 发送方本地计算与调整 |
| 反馈信号 | TCP 首部 Window 字段 | 丢包/重复 ACK/超时(传统);时延/带宽(BBR) |
核心公式: 实际发送窗口 = min(rwnd, cwnd)
流量控制细节
- 滑动窗口: 发送窗口内可连续发送未确认数据;收到 ACK 后窗口滑动。
- 零窗口: 接收缓冲满 → 通告 rwnd=0。发送方启动持续定时器(persist timer),周期性发送零窗口探测段(1 字节或序号探测),避免「ACK 丢失导致死锁」。
- 糊涂窗口综合症(SWS): 接收方每次只腾出几个字节就通告小窗口,导致大量小包。处理:接收端用 Clark 算法——延迟窗口更新,等到缓冲足够(能容纳一个完整 MSS,或达到接收缓冲的一半)再通告非零窗口;发送端则用 Nagle 算法合并小包(见下条)。两者常被并列为 SWS 的两端对策,但Nagle 是发送端算法,不能写成接收方的对策。
- Nagle 算法: 发送端合并小包(在有未确认数据时暂缓发送更小段),与 SWS 对策呼应。
拥塞控制细节(见第 6 题展开)
- 信号:超时或多个重复 ACK 被认为网络可能拥塞。
- 目标:探测「路径容量」而不引发丢包雪崩。
设计动机:为什么必须两个都做?
- 接收方不等于网络。 接收方可能很快但路径很窄,或路径很宽但接收方处理慢——只控制一个维度仍会丢包或崩溃。
- 信息局部性: 接收方最清楚自己缓冲;网络拥塞只有发送方通过「丢包/时延」侧面探测。职责分离符合端到端原则与信息就近原则。
- min 取小: 谁的限制更紧就听谁的,保证两个约束同时满足。
常见追问
追问 1:rwnd 和 cwnd 分别由谁维护?发送窗口怎么算?
- 答题要点: rwnd 由接收方在 TCP 首部 Window 字段通告;cwnd 由发送方拥塞算法本地维护;实际发送窗口 = min(rwnd, cwnd)。
追问 2:接收窗口为 0 怎么办?会死锁吗?
- 答题要点: 发送方不发送新数据,启动持续定时器发送零窗口探测。接收方处理完缓冲后回非零窗口。若探测 ACK 丢失,定时器会再试,避免永久死锁。
追问 3:为什么有了流量控制还需要拥塞控制?举反例。
- 答题要点: 反例:接收方 rwnd 很大(内存充足),1000 个发送方同时向它发送,链路和中间路由器仍会拥塞丢包。流量控制保护不了「共享网络」;必须有拥塞控制限制对网络的注入速率。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「流量控制=拥塞控制」 | 目标不同:接收方 vs 网络 |
| 「发送窗口=rwnd」 | 是 min(rwnd, cwnd) |
| 「零窗口后连接断开」 | 只是暂停发送;用探测机制恢复 |
| 「cwnd 由接收方通告」 | cwnd 是发送方算法本地值;接收方只通告 rwnd |
| 「Nagle 用于流量控制」 | Nagle 主要影响发送侧小包合并,与接收窗口/拥塞控制都不同,但是 TCP 性能优化相关 |
与选择题对照
- 主库 150: 第 66 题(流量控制目的)、第 67 题(发送窗口取决于 min(rwnd,cwnd))、第 68–71 题(拥塞控制簇)、第 144 题(端到端原则)。
- 补题 16: 补-03、补-04(可靠传输窗口理论,对照 TCP 窗口)。
- 口述联动: 选择题直接考「目的/依据/min」;面试加分在零窗口探测、SWS、以及「两个维度缺一不可」的反例。
工程 / 抓包背景
- Wireshark: 查看 ACK 中的
Window size value;tcp.analysis.zero_window、tcp.analysis.window_update。 - ss -ti: 同时显示
cwnd与snd_wnd(对端通告的接收窗口,即协议里的 rwnd;输出中没有rwnd这个字段名),本端接收侧看rcv_space/rcv_ssthresh,被对端窗口卡住时会给出rwnd_limited:<ms>,便于对照谁是瓶颈。 - 调优: 接收缓冲
net.ipv4.tcp_rmem;窗口缩放net.ipv4.tcp_window_scaling(长肥管道必需)。 - 现象: 抓包见 ZeroWindow → 接收方应用消费慢或缓冲小;cwnd 很小且 RTT 高 → 拥塞控制在限制。
6. TCP 拥塞控制的四个算法(热度 310 · 高频选考)
Q: 描述慢开始、拥塞避免、快重传、快恢复。
A:
四个算法完整展开
1. 慢开始: cwnd 从约 1 MSS 起(概念题从 1 讲起),每 ACK cwnd += 1 MSS → 一个 RTT 内大约翻倍,直到 cwnd ≥ ssthresh。动机:「慢」指起点低先探测,不是增长慢。 2. 拥塞避免: cwnd ≥ ssthresh 后,每个 RTT cwnd += 1 MSS(线性/加性增长),即 AIMD 中的 AI。 3. 快重传: 连续收到 3 个重复 ACK 立即重传丢失段,不等 RTO。为何是 3:1 个可能是乱序;3 个说明后续包已到而中间有洞。 4. 快恢复: 快重传后 ssthresh = cwnd/2,cwnd = ssthresh(或 ssthresh+3 变体),直接进入拥塞避免而不是回 1。动机:仍有后续 ACK,网络未严重瘫痪。
与超时重传的对照(高频)
| 事件 | ssthresh | cwnd | 之后阶段 |
|---|---|---|---|
| 超时重传 | cwnd/2 | 1 | 重新慢开始(认为网络严重拥塞) |
| 快重传+快恢复 | cwnd/2 | ≈ssthresh | 拥塞避免(网络仍有一定交付能力) |
状态机示意
cwnd=1 → 慢开始指数涨 → cwnd≥ssthresh → 拥塞避免线性涨
↑ │
│ 超时:ssthresh=cwnd/2, cwnd=1
│ │
└──────────────────────────────┘
3重复ACK:ssthresh=cwnd/2, cwnd=ssthresh → 拥塞避免加分点:现代算法
- CUBIC(Linux 默认): 用三次函数窗口增长替代 Reno 线性增长,高带宽时延积网络收敛更快;以「距离上次拥塞事件的时间」为函数自变量。
- BBR(Google): 基于带宽时延积(BDP)建模,测量瓶颈带宽与 RTT,不把丢包作为唯一拥塞信号;解决缓冲膨胀(bufferbloat)。部署上以 Google 自家服务与其自建网关(YouTube、Google 骨干等)最常见;Linux 发行版默认不启用,需先加载模块再切换:
modprobe tcp_bbr→sysctl -w net.ipv4.tcp_congestion_control=bbr(未加载时tcp_available_congestion_control里根本看不到 bbr,本机实测只有reno cubic)。手机系统默认仍是 CUBIC;WebRTC 走的是 GCC + transport-cc(发送端自估时延梯度)而非内核 BBR,别把这两类当成 BBR 的普及证据。 sysctl net.ipv4.tcp_congestion_control/sysctl net.ipv4.tcp_available_congestion_control可查看与切换。
常见追问
追问 1:慢开始为什么叫「慢」?增长是不是很慢?
- 答题要点: 名称源于「起点低、先小心试探」,不是增长慢;指数增长其实很快。对比「一开始就全速发送」,它在起点上「慢」。
追问 2:快重传和超时重传后窗口调整有何不同?为什么?
- 答题要点: 超时 → cwnd=1 重新慢开始(长时间无确认,可能严重拥塞);3 重复 ACK → 快恢复,cwnd 降到约一半后线性增长(仍有 ACK 流,网络未完全瘫痪)。区别体现对拥塞严重程度的分级响应。
追问 3:BDP 是什么?和 TCP 窗口有什么关系?
- 答题要点: 带宽时延积 = 带宽 × RTT,表示「管道中能容纳的最大数据量」。发送窗口(尤其 min(rwnd,cwnd))应 ≥ BDP 才能填满高带宽长延迟链路,否则链路空闲。BBR 正是围绕 BDP 建模。对应主库第 127 题。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「慢开始增长慢」 | 起点低,但是指数增长 |
| 「3 个重复 ACK 后 cwnd=1」 | 那是超时;3 重复 ACK 走快恢复,cwnd≈cwnd/2 |
| 「拥塞避免阶段指数增长」 | 是每 RTT +1 MSS 的线性增长 |
| 「Linux 默认 Reno」 | 现行默认多为 CUBIC;Reno 是教材经典参照 |
| 「丢包一定表示拥塞」 | 传统算法这么假设;无线随机丢包、BBR 则不这么等同 |
与选择题对照
- 主库 150: 第 68 题(3 个重复 ACK 通常快速重传)、第 69 题(超时重传后 cwnd)、第 70 题(拥塞控制错误叙述)、第 71 题(快恢复结束后进入拥塞避免)、第 127 题(BDP)。
- 补题 16: 补-03/补-04(GBN/SR——「3 重复 ACK」思想的理论渊源,但 TCP 实现更接近 SR)。
- 口述联动: 选择题考「超时 vs 快恢复后 cwnd 怎么变」;面试要把「为什么分级」和 CUBIC/BBR 说清。
工程 / 抓包背景
- ss -ti: 观察
cwnd、ssthresh(若内核导出)、retrans。 - Wireshark: 看重复 ACK 数量、重传段;
tcp.analysis.fast_retransmission。 - iperf3 / netperf: 打流观察吞吐与丢包。
- Nginx: 对上游 TCP 一般不直接调拥塞算法;系统级可
sysctl -w net.ipv4.tcp_congestion_control=bbr(需内核模块)。 - curl: 对比不同网络环境(高 RTT)下加载时间,可感知窗口与 BDP 问题。
7. 从输入 URL 到页面展示的完整过程(热度 609 · 核心必考)
Q: 浏览器输入 https://www.example.com 回车后,到页面渲染完成,经历了什么?
A:
分层时序(完整链)
URL 解析与导航判断: 判断搜索词还是 URL;补全协议与端口。若 HSTS 命中,http 也会强制升 https。
DNS 解析: 浏览器缓存 → OS 缓存/hosts → LDNS → 根/顶级/权威(递归+迭代),拿到 A/AAAA(CNAME 可能多跳)。可能
dns-prefetch并行解析。详见第 8 题。建立 TCP 连接: 向 IP:443 发 SYN,协商 ISN/MSS/窗口缩放/SACK/时间戳等;路径可能经 NAT、代理、CDN。
TLS 握手(HTTPS): ClientHello(版本、套件、随机数、SNI)→ ServerHello+证书 → 校验 → 密钥协商 → Finished。TLS1.2 约 2-RTT,1.3 为 1-RTT/0-RTT。DNS 在 TCP 之前,TLS 在 TCP 之后、HTTP 之前。详见第 11、12 题。
发送 HTTP 请求: 请求行+头+(可选)body;可能带 Cookie、
If-None-Match/If-Modified-Since。HTTP/2 同连接多流;HTTP/3 走 QUIC。服务器处理并返回响应: 反向代理(Nginx)→ 应用 → 依赖服务;返回状态码+头+体(200/304/301/404/502/504),可能跟踪
Location重定向。浏览器渲染: HTML→DOM,CSS→CSSOM,合成渲染树;Layout→Paint→Composite。并发拉取静态资源并执行 JS(可能重排重绘);注意 CSS 阻塞渲染、JS 默认阻塞解析,可用
async/defer/preload。连接处置:
Connection: keep-alive(HTTP/1.1 默认)则复用,否则四次挥手关闭;HTTP/2/3 长期复用同一条连接。
设计动机
- 为什么 DNS 必须最先: IP 网络按地址转发,不知 IP 无法建 TCP。
- 为什么 TLS 在 TCP 之后: TLS 报文本身需要可靠字节流承载(HTTP/3 例外:QUIC 内置加密)。
- 为什么渲染要分树: 关注点分离——结构(DOM)与样式(CSSOM)分离后才能计算「哪些节点可见、几何位置如何」。
常见追问
追问 1:DNS、TCP、TLS、HTTP 的顺序能调换吗?
- 答题要点: 不能随意调换。DNS → 拿到 IP;TCP → 可靠信道;TLS → 在可靠信道上安全;HTTP → 业务请求。HTTP/3 将 TCP+TLS+HTTP 用 QUIC 融合,但逻辑上仍是「地址 → 安全多路传输 → 应用协议」。
追问 2:页面很慢,你怎么从网络层排查?
- 答题要点: ①
curl -w/Chrome DevTools Network 看 DNS/TCP/TLS/TTFB 各段耗时;②dig/nslookup查 DNS;③ping/mtr/traceroute看可达与路径;④ Wireshark 看握手、重传、证书;⑤ 服务器侧ss、Nginx access log($request_time、$upstream_response_time)。
追问 3:HTTP/2 多路复用如何优化「并发请求」环节?
- 答题要点: HTTP/1.1 浏览器对同域并发 6~8 条 TCP,仍可能应用层队头阻塞;HTTP/2 单连接多流并发,头部 HPACK 压缩,减少连接数与冗余。但 TCP 层丢包仍阻塞所有流(HTTP/3 用 QUIC 解决)。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「先 TCP 后 DNS」 | 必须先 DNS 得到 IP |
| 「TLS 在 DNS 之前」 | TLS 在 TCP 握手之后 |
| 「HTTPS 请求明文」 | 证书验证后业务数据走对称加密 |
| 「解析 HTML 完再请求 CSS/JS」 | 预解析可并行发现资源;CSS/JS 可能阻塞渲染 |
| 「keep-alive 是 HTTP/2 发明」 | HTTP/1.1 已默认持久连接 |
与选择题对照
- 主库 150: 第 90 题(访问 https 基本流程)、第 94 题(输入 URL 最先=DNS)、第 124 题(协议顺序 DNS→TCP→TLS→HTTP)、第 74/91 题(HTTPS 443)、第 38/39/136/137 题(ping/tracert 排障)。
- 补题 16: 无 1:1 直接题;补-12(建连必要性)支撑「TCP 握手」环节。
- 口述联动: 选择题考「最先是什么/顺序」;面试必须能讲完 8 步并主动提 HTTP/2、渲染树、TTFB。
工程 / 抓包背景
- curl:bash
curl -w "dns:%{time_namelookup} tcp:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" -o /dev/null -s https://www.example.com - DevTools: Network 面板 Waterfall 看各阶段;Performance 看渲染。
- dig/nslookup/nslookup -type=CNAME;
openssl s_client -connect host:443 -servername host看证书与 TLS 版本。 - mtr/traceroute;服务端 Nginx
$request_timevs$upstream_response_time区分网关与后端耗时。 - ss: 观察 ESTABLISHED/TIME_WAIT 数量,判断连接复用是否生效。
8. DNS 解析过程与缓存(热度 318 · 高频选考)
Q: 域名是怎么解析成 IP 的?递归查询和迭代查询有什么区别?
A:
查询链(完整)
浏览器缓存 → OS 缓存 / hosts → 本地域名服务器 LDNS
→ (迭代)根服务器 → 顶级域服务器(TLD, 如 .com)
→ 权威域名服务器 → 返回 IP/A/AAAA/CNAME- 浏览器缓存: Chrome 等有内置 DNS 缓存。
- 操作系统缓存 / hosts: nscd、systemd-resolved、Windows DNS Client;hosts 静态优先。
- 本地域名服务器(LDNS): 常是运营商或企业 DNS;对主机通常是递归服务器。
- 根域名服务器: 返回 TLD 服务器地址(不直接给 IP)。
- 顶级域服务器: 如
.com返回该域名权威 NS 地址。 - 权威域名服务器: 返回最终记录(A/AAAA/CNAME 等)。
- 逐级缓存: 每一跳按 TTL 缓存(浏览器→系统→LDNS→…)。
递归 vs 迭代
| 递归查询 | 迭代查询 | |
|---|---|---|
| 含义 | 「你帮我查到底,给我最终结果」 | 「你告诉我下一步该问谁」 |
| 常见位置 | 主机 → LDNS | LDNS → 根/TLD/权威 |
| 负担 | 查询代理承担完整查询 | 每级只回答线索,LDNS 自己继续问 |
| 为什么不全程递归 | 根/TLD 若替全世界递归将无法扩展 | 用迭代分散负担 |
记录类型
| 类型 | 作用 |
|---|---|
| A | 域名 → IPv4 |
| AAAA | 域名 → IPv6 |
| CNAME | 别名 → 另一个域名(CDN 常用) |
| MX | 邮件交换服务器 |
| NS | 域名服务器 |
| TXT | 文本(SPF、验证等) |
| PTR | IP → 域名(反向解析) |
设计动机
- 为什么分布式数据库: 单点无法承受全球查询;分层+缓存把负载摊到边缘。
- 为什么 TTL: 缓存权衡:太久更新不及时,太短增加权威负载与延迟。
- 为什么 UDP 53: 查询报文小、一问一答、要低延迟;超时由应用重传兜底。
- 何时 TCP: 区域传送(AXFR/IXFR)、响应过大(>512 字节 EDNS 或回退)、DNSSEC 较大记录。
加分点
- DNS 预解析 / HTTPDNS: 移动端弱网下传统 DNS 劫持/调度不准,可用 HTTPDNS 或 DoH/DoT。
- CNAME 与 CDN: 站点域名 CNAME 到 CDN 调度域名,由 CDN 权威返回边缘节点 IP。
- 根服务器: 逻辑 13 组标识(A–M),实际由全球上千个 anycast 实例承载(数量随年份增长,公开统计已逾 1500,答题按「十几台逻辑机构、上千物理实例」表述)。
- 与 URL 过程联动: DNS 解析失败 vs 连接超时 vs TLS 失败,排查命令不同。
常见追问
追问 1:递归查询和迭代查询的区别是什么?主机到 LDNS 是哪种?
- 答题要点: 递归=受托方必须查到最终结果;迭代=返回「下一步问谁」。主机→LDNS 通常是递归;LDNS→根/TLD/权威通常是迭代。
追问 2:DNS 用 UDP 还是 TCP?为什么?
- 答题要点: 默认 UDP 53(小查询、低延迟);区域传送或大响应用 TCP 53。防火墙需两者都考虑。
追问 3:DNS 缓存命中还会有网络 RTT 吗?各级 TTL 如何影响更新?
- 答题要点: 浏览器/系统/LDNS 命中则不走权威,延迟极低。TTL 到期后向上重新查询;运维改记录后需等各层缓存过期,或调低 TTL 预热变更。可
dig +trace观察链。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「根服务器直接返回 IP」 | 根返回 TLD 服务器地址;权威才给记录 |
| 「递归都在全链路」 | 主机→LDNS 递归,其后多为迭代 |
| 「DNS 只有 UDP」 | 大响应/区域传送用 TCP |
| 「hosts 优先级最低」 | 本机 hosts 通常优先于向 LDNS 发起的查询(视 OS) |
| 「CNAME 返回 IP」 | CNAME 返回另一个域名,还要继续解析 |
与选择题对照
- 主库 150: 第 79 题(DNS 主要功能)、第 80 题(DNS 错误叙述)、第 81 题(域名层次最高)、第 82 题(迭代查询中 LDNS 行为)、第 83 题(A 记录)、第 94 题(URL 最先 DNS)、第 65 题(DNS 用 UDP)。
- 补题 16: 无直接 DNS 题;应用层对照见补-14(邮件协议,非 DNS)。
- 口述联动: 选择题考功能/层次/迭代;面试要完整讲查询链 + UDP/TCP + 缓存/TTL + 排障。
工程 / 抓包背景
- 命令:
dig +trace example.com、dig example.com A、nslookup、host、cat /etc/resolv.conf、ipconfig /displaydns(Windows)、systemd-resolve --statistics。 - Wireshark: 过滤
dns;看 Query/Response、TTL、CNAME 链。 - curl:
curl --resolve example.com:443:1.2.3.4 https://example.com绕过 DNS 测源站;curl -v可显示解析到的 IP。 - Nginx:
resolver 8.8.8.8 valid=30s;动态解析 upstream 域名;proxy_pass 变量时需要 resolver。
9. HTTP 常见状态码(热度 280 · 进阶)
Q: 说出常见 HTTP 状态码及含义。
A:
分类与常见码
1xx 信息: 100 Continue(请继续传 body);101 Switching Protocols(协议升级,如 WebSocket)。
2xx 成功: 200 OK;201 Created(常配 Location);204 No Content(无 body,DELETE 常用);206 Partial Content(Range/断点续传)。
3xx 重定向: 301 永久(浏览器会缓存 Location);302/303 临时(历史客户端可能改 GET);304 Not Modified(协商缓存命中,无响应体);307 临时且保持方法;308 永久且保持方法。
4xx 客户端错误: 400 语法/参数错;401 未认证;403 无权限/策略拒绝;404 不存在;405 方法不允许;408 请求超时;409 冲突;413 体过大;429 限流(可带 Retry-After)。
5xx 服务端错误: 500 内部错误;502 网关从上游收到非法响应;503 暂不可用;504 网关等待上游超时。
设计动机
- 状态码让客户端可编程处理: 缓存、重试、认证、降级逻辑都依赖语义化的码,而不是解析错误文案。
- 401 vs 403: 401=不知道你是谁(请认证);403=知道你是谁但不允许。
- 502 vs 504: 502 侧重「上游返回了不可用响应」;504 侧重「等待上游超时」。中间层(Nginx)语义非常关键。
常见追问
追问 1:301 和 302/307 的缓存与方法语义差异?
- 答题要点: 301 永久,客户端可缓存重定向目标;302 临时不长期缓存;307 临时且强制保持方法与 body;301/302 在历史客户端上可能把 POST 改成 GET,要保持方法应使用 307/308。
追问 2:401 和 403 有什么区别?
- 答题要点: 401 未认证——应引导登录/带 Authorization;403 已认证但无权限或策略禁止——重新登录通常无效。
追问 3:502 和 504 排查方向?
- 答题要点: 502——看后端进程是否存活、端口是否监听、上游是否返回非 HTTP/畸形响应(Nginx error log)。504——看后端处理是否过慢、代理
proxy_read_timeout是否过短、依赖(DB/下游)是否卡死。先比对 Nginx$upstream_status与应用日志。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「304 服务器返回了新内容」 | 304 表示未修改,无 body,用本地缓存 |
| 「404 一定是前端路径写错」 | 也可能是权限隐藏、API 路径、部署版本问题 |
| 「500 和 502 一样」 | 500 应用内部错误;502 多是代理与上游之间 |
| 「401 是没权限」 | 401 是未认证;没权限更多是 403 |
| 「HTTPS 成功就一定是 200」 | 还可能是 301/302/304/4xx/5xx |
与选择题对照
- 主库 150: 第 86 题(404)、第 87 题(301)、第 84 题(HTTP 特点)、第 146 题(ETag/协商缓存与 304)、第 145 题(keep-alive,连接层与状态码层区分)。
- 补题 16: 无直接状态码选择题;面试向更深。
- 口述联动: 选择题考单个码;面试常考 301 vs 302、401 vs 403、502 vs 504 三组辨析 + 排障。
工程 / 抓包背景
- curl:bash
curl -I https://example.com curl -i https://api.example.com/health curl -v -H "If-None-Match: \"etag\"" https://example.com/ # 期待 304 - Nginx: access log 记录 status;error log 看 upstream 502/504;
proxy_next_upstream决定重试策略。 - 浏览器: Network 面板看 status、From disk cache / memory cache 与 304。
- Wireshark:
http.response.code == 304等过滤。 - 网关排查口诀: 502 看进程与协议;504 看超时与依赖。
10. HTTP/1.1 → HTTP/2 → HTTP/3 的演进(热度 297 / 284 · 进阶)
Q: HTTP/2 相比 1.1 有哪些改进?HTTP/3 为什么改用 UDP?
A:
HTTP/1.1 的限制
持久连接(keep-alive 默认)+ 管线化(实践中少用);同一连接上请求/响应串行,存在应用层队头阻塞;浏览器对同域名开多条 TCP(如 6 条)缓解;头部冗余。雪碧图、域名分片等优化本质是在绕协议限制。
HTTP/2(基于 TCP)
① 二进制分帧;② 多路复用(一条连接并发 stream,流 ID 区分);③ 头部压缩 HPACK;④ 服务器推送(实践支持度下降)。
仍存在 TCP 层队头阻塞: 任一 TCP 段丢失,后续字节必须重传等待,所有 HTTP/2 流一起被阻塞。
HTTP/3(基于 QUIC/UDP)
可靠性与流控下移到 QUIC,按流独立,彻底解决传输层队头阻塞;0-RTT/1-RTT 建连(与 TLS1.3 融合);连接迁移(CID 标识连接,换网不断);用户态协议栈迭代更快。
层次差异:HTTP/2 解决应用层队头阻塞;HTTP/3 才解决传输层队头阻塞。
为何在 UDP 上自研: TCP 在内核、中间设备干扰多、OS 更新慢;UDP 443 已广泛放行,部署可行。HTTP 语义(方法/状态码/头部)保持不变以降低迁移成本。
常见追问
追问 1:HTTP/2 解决了队头阻塞,为什么还不够?
- 答题要点: HTTP/2 多路复用只在应用层把请求交织到一条 TCP;TCP 仍保证单一有序字节流,底层丢包时所有流共命运。要按流独立重传/交付,需要 QUIC 那样的流层可靠性。
追问 2:HTTP/3 为什么用 UDP 而不是新传输协议号?
- 答题要点: 新 IP 协议号中间设备兼容性差、防火墙/NAT 易丢弃;UDP 443 已广泛放行,QUIC 在其上用包头显式声明自身,部署可行。
追问 3:如何知道服务器是否支持 HTTP/2 或 HTTP/3?
- 答题要点:
curl -I --http2 https://example.com或看响应头alt-svc: h3=":443"; ma=...;Wireshark/TLS ALPN(h2/h3);Chrome 开发者工具 Protocol 列。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「HTTP/2 底层是 UDP」 | HTTP/2 基于 TCP+TLS |
| 「HTTP/2 已无队头阻塞」 | 应用层队头阻塞解决,TCP 层仍在 |
| 「HTTP/3 只是 HTTP/2 换端口」 | 传输层变成 QUIC/UDP,多路与握手模型都变了 |
| 「keep-alive 是 HTTP/2 多路复用」 | keep-alive 只是复用连接;多路复用是并发交错的流 |
| 「HPACK 可有可无」 | 头部压缩是 HTTP/2 正式特性,对性能很重要 |
与选择题对照
- 主库 150: 第 92 题(1.1/2/3 正确叙述)、第 84 题(HTTP 特点)、第 145 题(keep-alive)、第 91 题(HTTPS/端口)、第 65 题(HTTP/3 相关 UDP 应用思路)。
- 补题 16: 补-13(UDP 相关,支撑 HTTP/3 底层)。
- 口述联动: 选择题可能考「谁基于 UDP/谁有多路复用」;面试必须能分层讲「应用层队头阻塞 vs 传输层队头阻塞」。
工程 / 抓包背景
- curl:
curl --http2 -I、curl --http3 -I(构建支持时)。 - Nginx: HTTP/2 在 Nginx ≤1.24 写
listen 443 ssl http2;,1.25.1 起该参数被标记 deprecated(官方文档至今只说"已废弃、应改用http2指令",并未声明在任何版本移除,旧写法仍可解析),新配置应写成listen 443 ssl;+http2 on;;HTTP/3 需 quic 指令与Alt-Svc头。 - Wireshark: ALPN 显示 h2;HTTP/3 是 QUIC 加密,可用密钥日志(
SSLKEYLOGFILE)解密部分信息。 - 浏览器: Network → Protocol 列显示 h2/h3。
- 运维注意: 升级 HTTP/2 后单连接放大,需调
worker_connections、关注 TCP 缓冲与队头阻塞相关时延。
11. HTTPS 握手与混合加密(热度 451 / 336 · 高频选考)
Q: HTTPS 的握手过程?为什么用混合加密?
A:
握手过程(以 TLS 1.2 为主,能提 1.3 更好)
Client Server
|--- ClientHello ------------------>| 版本、密码套件、客户端随机数、SNI
| | 扩展(ALPN、supported_versions…)
|<-- ServerHello + Certificate -----| 选定套件、服务器随机数、证书(含公钥)
|<-- ServerKeyExchange (ECDHE) -----|
|<-- ServerHelloDone ----------------|
| [客户端校验证书链] |
|--- ClientKeyExchange ------------>| RSA:用服务器公钥加密 pre-master
| | ECDHE:双方各自算出共享密钥
|--- ChangeCipherSpec + Finished -->|
|<-- ChangeCipherSpec + Finished ---|
| 此后应用数据走对称加密(AES-GCM等)|- Client Hello: TLS 版本、加密套件列表、客户端随机数、扩展(SNI、ALPN=h2/h3 等)。
- Server Hello + 证书: 选定套件,返回服务器随机数与数字证书(含公钥,可能附中间证书)。
- 证书校验: 客户端验证证书链、有效期、域名(CN/SAN)、吊销状态(见第 12 题)。
- 密钥交换: RSA 套件——客户端生成 pre-master secret,用服务器公钥加密发送;ECDHE——双方交换 DH/ECC 参数各自算出共享密钥(前向安全)。
- 生成会话密钥: 用「客户端随机数 + 服务器随机数 + pre-master」经 PRF 推导对称密钥。随机数用于防重放并保证会话密钥唯一。
- Finished: 双方用会话密钥加密握手摘要校验;此后应用数据走对称加密(如 AES-GCM)。
TLS 1.3 要点(加分)
- 握手压缩到 1-RTT(会话恢复可 0-RTT,但 0-RTT 有重放风险,仅幂等请求适用)。
- 废弃 RSA 密钥交换,强制前向安全(ECDHE)。
- 加密握手后半段:证书等也加密,减少明文元数据暴露。
- 套件大幅精简(AEAD only:AES-GCM、ChaCha20-Poly1305 等)。
为什么混合加密?
| 机制 | 作用 | 原因 |
|---|---|---|
| 非对称加密 / 密钥协商(RSA 加密 pre-master;ECDHE 做 DH 协商) | 安全交换密钥、身份认证 | 安全但性能差(慢几个数量级),不适合加密整段流量。注意 ECDHE 本身不加密业务数据,它是密钥协商算法(DH 的椭圆曲线 ephemeral 变体),只提供前向安全;能"加密"的非对称算法是 RSA |
| 对称加密(AES-GCM 等) | 加密应用数据 | 性能好,可硬件加速(AES-NI) |
| 哈希/签名(SHA-256 等) | 完整性、证书签名 | 防篡改、防冒充 |
设计动机:让昂贵的非对称只做「一次性的密钥协商与认证」,让便宜的对称扛「持续的数据传输」——兼顾安全与性能。
常见追问
追问 1:HTTPS 为什么中间还要随机数?只靠证书公钥不行吗?
- 答题要点: 若只用固定公钥加密,相同明文可能得到相同密文,且易被重放。引入客户端/服务器随机数使每次会话密钥不同;再配合 Finished 校验,双方确认握手未被篡改。
追问 2:TLS 1.3 相比 1.2 快在哪里?安全增强是什么?
- 答题要点: 1-RTT/0-RTT 减少往返;握手消息加密;去掉 RSA 密钥交换等不安全选项,强制 PFS。注意 0-RTT 数据可被重放,只应用于安全的幂等请求。
追问 3:证书校验通过了,还会不会被中间人?
- 答题要点: 可能。前提是用户信任了恶意根证书(企业中间人代理、恶意 CA、被入侵的信任库),或客户端未真正校验证书(
verify=False)。防御:严格校验链、HSTS、证书透明(CT)、可选 Certificate Pinning。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「HTTPS 全程非对称加密」 | 只有握手/密钥协商用非对称;数据用对称 |
| 「TLS 在 DNS 之前」 | 先 DNS → TCP → TLS |
| 「证书里有服务器私钥」 | 证书含公钥;私钥仅服务器持有 |
| 「会话密钥用服务器公钥加密传输=唯一方式」 | RSA 套件是这样;ECDHE 是双方各算共享密钥 |
| 「TLS 1.3 仍 2-RTT」 | 默认 1-RTT,恢复可 0-RTT |
与选择题对照
- 主库 150: 第 90 题(https 访问流程)、第 91 题(HTTPS 端口与组成)、第 99 题(对称/非对称)、第 100 题(非对称算法)、第 113 题(对称 vs 非对称性能)、第 114 题(SSL/TLS 工作层)、第 115 题(TLS 握手目的)、第 124 题(协议顺序)。
- 补题 16: 无直接 TLS 选择题;应用层对照见补-14(邮件协议常用 TLS 加密端口)。
- 口述联动: 选择题考「混合加密原因/工作层」;面试要完整报文级时序 + 1.3 差异 + 前向安全。
工程 / 抓包背景
- openssl:bash
openssl s_client -connect example.com:443 -servername example.com -tls1_2 openssl s_client -connect example.com:443 -servername example.com -tls1_3 openssl x509 -in cert.pem -noout -text - Wireshark: ClientHello/ServerHello;
tls.handshake.extensions_alpn_str == "h2";SSLKEYLOGFILE 可解密应用数据。 - curl:
curl -v https://example.com看 TLS 版本、证书主体、ALPN。 - Nginx:
ssl_protocols TLSv1.2 TLSv1.3;、ssl_certificate/ssl_certificate_key、ssl_session_cache。 - 浏览器: 安全标识、证书链、Connection 是否
h2/http/1.1。
12. 浏览器如何校验证书(热度 432 · 高频选考)
Q: 浏览器怎么验证 HTTPS 证书是否合法?验证失败有哪些原因?
A:
校验内容(完整清单)
- 证书链: 从叶子证书逐级向上到受信任根 CA(系统/浏览器内置信任库)。中间证书应由服务器下发(fullchain)。
- 签名完整性: 用上级 CA 公钥验证本级证书签名,确保证书未被篡改。
- 有效期: 当前时间是否在
notBefore/notAfter之间。 - 域名匹配: CN/SAN 是否覆盖当前域名(通配符
*.example.com不跨多级)。 - 吊销状态: CRL 或 OCSP;生产常用 OCSP Stapling 降延迟。
- 策略: 密钥长度/签名算法是否仍在信任策略内;扩展约束(CA 位、EKU)。
证书里有什么: 域名/SAN、公钥、有效期、签发者、序列号、签名算法、CA 签名。不含私钥。
常见失败原因
证书过期(ERR_CERT_DATE_INVALID);域名不匹配(SAN/CN);自签名未受信任;中间证书缺失(fullchain 事故高发);系统时间错误;根证书不在信任库;证书被吊销;弱算法/过短密钥。
HTTPS 站点仍提示「不安全」的深层原因: 混合内容(页面混入 HTTP 资源)、弱套件、吊销信息不可用时的策略差异等。
加分: OCSP Stapling——服务器代查吊销状态并装订在握手里,降低客户端实时 OCSP 的延迟与隐私泄露;CAA DNS 记录限制可签发的 CA。
常见追问
追问 1:证书链具体怎么验证?根证书谁来信任?
- 答题要点: 叶子 → 中间 CA → 根 CA。根 CA 不通过「再往上签」验证,而是命中操作系统/浏览器内置信任锚(trust store)。中间证书缺失是生产事故高频原因——应用必须配置 fullchain。
追问 2:证书过期和域名不匹配,客户端表现一样吗?
- 答题要点: 都会导致连接警告/失败,但错误码与文案不同(日期无效 vs 域名不匹配)。排障先看证书
notAfter与 SAN 列表。
追问 3:CRL 和 OCSP 有什么区别?为什么还要 Stapling?
- 答题要点: CRL 是整份吊销列表,体积大、更新粒度粗;OCSP 按证书单次查询。OCSP 实时查询增加 RTT 且泄露「谁访问了哪站」;Stapling 让服务器代查并装订,客户端一次握手拿到吊销证明。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「证书链到服务器私钥」 | 链验证公钥与 CA 签名,不涉及传输私钥 |
| 「浏览器只看域名」 | 还要链、有效期、吊销、信任库 |
| 「自签证书=加密失效」 | 仍可加密,但身份认证失败,公共站点不可用 |
| 「有 HTTPS 就一定锁标」 | 混合内容/无效证书可能锁标打叉或「不安全」 |
| 「SAN 不重要,有 CN 就行」 | 现代浏览器以 SAN 为准 |
与选择题对照
- 主库 150: 第 116 题(数字证书正确叙述)、第 101/102 题(数字签名)、第 114/115 题(TLS/握手)、第 99/100 题(非对称)、第 98/103/104/105 题(安全威胁与中间人)。
- 补题 16: 无直接证书选择题。
- 口述联动: 选择题考「证书里有什么/签名用什么钥」;面试要讲清校验五步 + 失败原因 + OCSP Stapling。
工程 / 抓包背景
- 命令行:bash
openssl s_client -connect example.com:443 -servername example.com -showcerts openssl x509 -noout -subject -issuer -dates -ext subjectAltName - curl:
curl -v看SSL certificate problem;测试时勿在生产关闭校验(-k仅排障)。 - Nginx: 必须
ssl_certificate指向包含叶子+中间的 fullchain;日志见 SSL handshake failure。 - Wireshark: Certificate 消息中的链长度;Alert 协议可见 handshake_failure。
- 线上事故模式: 上线忘续期、只部署了叶子证书、SNI 与证书不一致、CDN 回源证书错误。
13. HTTP 与 HTTPS 的区别(热度 451 · 高频选考)
Q: HTTP 和 HTTPS 有什么区别?
A:
对照表
| 维度 | HTTP | HTTPS |
|---|---|---|
| 协议 | 应用层明文 | HTTP + TLS/SSL |
| 端口 | 80 | 443(默认,可配置其他) |
| 安全性 | 明文,可窃听/篡改/冒充 | 加密 + 完整性校验 + 身份认证 |
| 证书 | 无 | 需 CA 签发证书(及私钥) |
| 性能 | 无加密开销 | 有握手与加解密开销(会话复用、HTTP/2、TLS1.3、AES-NI 缓解) |
| SEO | 无优势 | 搜索引擎加权 |
| 浏览器标识 | 涉及密码/卡片时常提示不安全 | 安全锁标 |
HTTPS 解决什么?(三类威胁)
| 威胁 | 攻击 | HTTPS 对策 |
|---|---|---|
| 窃听 | 截获明文 | 加密(对称会话密钥) |
| 篡改 | 中途改报文 | 完整性校验(MAC/AEAD、握手摘要) |
| 冒充 | 伪造服务器 | 身份认证(证书 + 非对称签名) |
HTTPS = HTTP over TLS。 语义与 HTTP 基本相同,差别在 socket 之上多了 TLS 记录层。握手增加 1~2 个 RTT(TLS1.3 更少);同连接可复用会话/票据;CPU 开销在 AES-NI 下可接受。迁移:301、HSTS、全站资源 HTTPS、证书自动续期(ACME)。
常见追问
追问 1:HTTPS 一定更安全吗?会不会仍有风险?
- 答题要点: 相对明文 HTTP 大幅提升机密性/完整性/身份认证,但仍可能:证书链被恶意根伪造、客户端关闭校验、应用层漏洞(XSS/CSRF/越权)、混合内容降级、用户忽略警告。HTTPS 不是「应用绝对安全」。
追问 2:端口 443 是安全的来源吗?
- 答题要点: 不是。安全来自 TLS 证书校验与密码学;443 只是默认约定。HTTPS 也可监听其他端口,HTTP 也可被错误地用在 443。
追问 3:为什么搜索引擎偏好 HTTPS?
- 答题要点: 保护用户隐私、减少中间人注入广告/劫持,提升整体生态信任;工程上也与 HTTP/2 部署习惯相关。SEO 是结果之一,不是协议安全机制本身。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「HTTPS=HTTP 加个端口」 | 核心是 TLS:加密+完整性+认证 |
| 「HTTPS 完全防 XSS/SQL 注入」 | 传输层安全不替代应用安全 |
| 「HTTPS 太慢不能上」 | 现代优化后开销可接受,且是基本合规要求 |
| 「没有证书也能 HTTPS」 | 公共 HTTPS 需要可信证书;自签仅限实验 |
| 「80 和 443 混用无影响」 | 会影响 Cookie Secure、HSTS、中间设备策略 |
与选择题对照
- 主库 150: 第 74/91 题(443/HTTPS 组成)、第 84 题(HTTP 特点)、第 98/103/104/105 题(安全威胁)、第 99/113/114/115 题(加密与 TLS)、第 124 题(访问顺序)。
- 补题 16: 补-14(邮件明文/加密端口对照,可类比 HTTP/HTTPS)。
- 口述联动: 选择题考端口与组成;面试要落到「三类威胁 ↔ 三类安全属性」以及性能与迁移。
工程 / 抓包背景
- 对比抓包: Wireshark 中
tcp.port==80可直接读明文 HTTP;tcp.port==443应用数据加密(未配置密钥日志时)。 - curl:
curl -v http://example.com与curl -v https://example.com;观察SSL connection using...。 - Nginx:nginx
listen 80; return 301 https://$host$request_uri; listen 443 ssl; # ≤1.24 可在本行尾加 http2;1.25.1 起该参数标记为 deprecated(尚未移除) http2 on; # 1.25.1+ 推荐写法 ssl_certificate fullchain.pem; ssl_certificate_key privkey.pem; - HSTS:
Strict-Transport-Security: max-age=31536000; includeSubDomains强制 HTTPS。 - 排障:
openssl s_client验证书;curl -I看跳转链是否全 HTTPS。
14. WebSocket 原理及与 SSE、轮询的对比(热度 572 / 365 · 核心必考)
Q: WebSocket 的原理?和 SSE、HTTP 轮询有什么区别?实时聊天为什么选 WebSocket?
A:
WebSocket 原理(握手 + 帧)
- HTTP 升级握手: 客户端带
Upgrade: websocket、Connection: Upgrade、Sec-WebSocket-Key、Sec-WebSocket-Version: 13;服务器回 101 Switching Protocols 与Sec-WebSocket-Accept(由 Key 与固定 GUID 计算)。 - 协议切换: 此后在同一 TCP 上走 WebSocket 帧协议,不再是 HTTP 请求/响应模型。
- 帧与语义: 文本/二进制/Close/Ping/Pong/连续帧;客户端→服务器帧必须掩码,服务器→客户端不掩码;支持分片与扩展(如 permessage-deflate)。
- 保活与关闭: Ping/Pong 心跳;Close 帧携带状态码。
- 安全: 生产常用
wss://(WebSocket over TLS,对应 443)。
与 SSE、轮询对比
| 方案 | 方向 | 协议基础 | 开销 | 适用 |
|---|---|---|---|---|
| 短轮询 | 客户端拉 | HTTP 定时请求 | 高(大量空请求) | 低频、简单 |
| 长轮询 | 客户端拉 | HTTP 挂起直到有数据 | 中 | 准实时、兼容要求高 |
| SSE | 服务器单向推 | HTTP text/event-stream | 低 | AI 流式输出、进度、行情 |
| WebSocket | 双向全双工 | 独立帧(HTTP 升级) | 最低(长连接) | 聊天、协同编辑、游戏 |
为何聊天选 WebSocket: 需要双向高频(消息、回执、在线状态);轮询延迟高浪费连接;SSE 单向上行仍要另发 HTTP。WS 一条长连接双向即发即达。
设计动机: 先走 HTTP 可复用 80/443、穿透代理并利用 TLS;SSE 天然 HTTP、自动重连但单向;WebSocket 为高效双向帧而离开 HTTP 模型。
常见追问
追问 1:WebSocket 和 SSE 怎么选?
- 答题要点: 只要服务器→客户端单向流(LLM token、进度、通知)→ SSE 更简单、HTTP 生态好;要双向、高频、低延迟(聊天、协同、游戏)→ WebSocket。很多产品上行 REST/下行 SSE。
追问 2:WebSocket 如何保活?断线怎么办?
- 答题要点: 协议层 Ping/Pong 或应用层心跳;断线后客户端指数退避重连,服务端需会话恢复(uid/token、消息序号、补拉离线)。
追问 3:负载均衡/LB 对 WebSocket 有什么影响?
- 答题要点: 需支持长连接与 HTTP Upgrade;粘性会话(IP hash 或连接级)有助于避免会话被打散;注意超时配置(idle timeout)要大于心跳周期;nginx
proxy_read_timeout等需调大。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「WebSocket 每次还是 HTTP 请求」 | 仅握手是 HTTP;之后是 WebSocket 帧 |
| 「SSE 是双向的」 | SSE 是服务器→客户端单向 |
| 「WebSocket 不走 TLS」 | wss:// 走 TLS,生产几乎必备 |
| 「轮询比 WebSocket 简单就一定更优」 | 高实时场景轮询成本与延迟都差 |
| 「101 就是成功业务响应」 | 101 仅表示协议升级成功,不是业务状态码 |
与选择题对照
- 主库 150: 第 84 题(HTTP 特点与方法)、第 92 题(HTTP 演进,对比实时方案)、第 145 题(keep-alive/长连接)、第 93 题(应用层协议归属)。选择题库对 WebSocket 覆盖较少——本考点以面试为主。
- 补题 16: 无直接 WebSocket/SSE 题。
- 口述联动: 若被问「101 是什么」,回扣状态码题(第 9 题)+ 本题协议升级。
工程 / 抓包背景
- Wireshark: 过滤
websocket;握手可见Upgrade: websocket与 101。 - 浏览器: DevTools → Network → WS 帧(发送/接收/握手头)。
- Nginx 反代 WebSocket:nginx
location /ws/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; } - curl 测握手: 带 Upgrade 头发请求,观察是否 101(完整帧测试需 wscat 等工具)。
- SSE:
curl -N https://api.example.com/stream;响应Content-Type: text/event-stream。
15. 长连接与短连接 / keep-alive(热度 221 · 进阶)
Q: HTTP 长连接和短连接是什么?Connection: keep-alive 有什么行为?
A:
概念与行为
- 短连接: 每个请求建一次 TCP(三次握手),响应后关闭(四次挥手)。HTTP/1.0 默认。
- 长连接: 同一 TCP 上串行复用多个 HTTP 请求/响应。HTTP/1.1 默认 keep-alive(除非显式
Connection: close);HTTP/1.0 需双方显式开启。 - HTTP/2/3: 连接更持久,且多路复用/独立流,keep-alive 并入连接生命周期管理。
行为细节
- 空闲超时与最大请求数:
Keep-Alive: timeout=N, max=M;Nginx 对应keepalive_timeout、keepalive_requests。 - 谁关闭: 达到 timeout/max、错误或显式 close 时,通常由服务器发起关闭。
- 竞态: 服务端关闭时客户端可能正在发下一条请求 → 可能失败;HTTP 允许对幂等方法重试。
- TIME_WAIT 分布: 谁主动关闭谁 TIME_WAIT;长连接可显著减少服务端 TIME_WAIT。
设计动机
- 减少建连开销: 每个短连接 1 RTT(TCP)+ 可能的 TLS 握手;页面数十资源时代价巨大。
- 减少 TIME_WAIT/端口压力: 高 QPS 服务端尤其实惠。
- 为何仍不能解决队头阻塞: HTTP/1.1 长连接上请求仍需串行/有限并发,应用层队头阻塞仍在;HTTP/2 多路复用才是根治(传输层见 HTTP/3)。
常见追问
追问 1:keep-alive 省了什么?没省什么?
- 答题要点: 省了重复 TCP(及 TLS)握手 RTT 与状态维护成本;没省单次请求的服务端处理时间,也没解决 HTTP/1.1 应用层队头阻塞。
追问 2:长连接会不会耗尽服务器资源?
- 答题要点: 会。空闲连接占 fd/内存;需 timeout、max requests、连接数限制、LB 超时对齐。大量 CLOSE_WAIT 则是应用没关 socket 的 bug(见第 18 题)。
追问 3:客户端如何配合长连接?
- 答题要点: 连接池复用、不要每请求新建;尊重
Connection: close;对连接被服务端关断的请求做幂等重试;监控连接错误率。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「keep-alive 是 HTTP/2 新特性」 | HTTP/1.1 已默认;1.0 需显式开启 |
| 「长连接=WebSocket」 | 不同:长连接仍是 HTTP 请求-响应复用;WS 是全双工帧协议 |
| 「长连接一定更快」 | 有首字节慢/阻塞时仍可能排队;资源未复用时收益有限 |
| 「TIME_WAIT 多就关 keep-alive」 | 通常应加强连接复用,而不是更碎地开关连接 |
| 「Connection 头对 HTTP/2 语义完全相同」 | HTTP/2 连接管理不同,hop-by-hop 头处理有专门规则 |
与选择题对照
- 主库 150: 第 145 题(
Connection: keep-alive含义)、第 84 题(HTTP 特点含持久连接)、第 92 题(HTTP 演进)、第 60/62/63/138 题(挥手与状态,长连接影响 TIME_WAIT/CLOSE_WAIT)。 - 补题 16: 无直接 keep-alive 题。
- 口述联动: 选择题直接考头字段含义;面试要连接池、超时竞态、与多路复用的关系。
工程 / 抓包背景
- Nginx:nginx
keepalive_timeout 65s; keepalive_requests 1000; # 上游连接池 upstream backend { server 127.0.0.1:8080; keepalive 32; } location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; } - curl: 多次请求看是否复用连接(
-w计时;verbose 可见Re-using existing connection)。 - ss: 对比
ss -tan中 ESTABLISHED 与 TIME_WAIT 数量变化。 - Wireshark: 观察多条 HTTP 请求是否在同一 TCP stream(
tcp.stream eq N)。 - 客户端: OkHttp/Go http.Client/Java HttpClient 连接池默认行为不同,需统一超时。
16. TCP 粘包与拆包(热度 182 · 进阶)
Q: 什么是 TCP 粘包?为什么会产生?怎么解决?
A:
本质
TCP 面向字节流,不保留消息边界。 两次 write 可能被合并到一个报文段(粘包),一条消息也可能被拆到多个段(拆包)。这不是 TCP 的 bug,而是字节流的固有特性。 UDP 是数据报,天然有边界,不会粘包。
产生原因
Nagle 等发送端优化合并小包;接收缓冲一次 read 读到多段;MSS/MTU 分片;应用读写节奏不匹配。TCP 只保证顺序与可靠,不知道应用层「一条消息」的边界。
解决方案
| 方案 | 做法 | 优缺点 |
|---|---|---|
| 定长消息 | 每条固定 N 字节 | 简单;短消息浪费填充 |
| 分隔符 | 如 \r\n | 直观;需转义,防恶意分隔符/长度攻击 |
| 长度字段(最通用) | 包头写 body 长度,先读头再按长度读体 | 灵活;必须校验最大长度与字节序 |
| 协议自带边界 | HTTP Content-Length/分块、Protobuf 长度前缀、gRPC | 生态成熟 |
长度头方案工程要点:
- 约定字节序(网络序 big-endian)。
- 限制
max_body_size,防止恶意超长包头导致 OOM。 - 处理半包:循环缓冲直到收满一条。
- 可加魔数/CRC 提升健壮性。
设计动机
- 为何 TCP 不提供消息边界: 字节流模型对文件、管道类应用最自然;消息边界属于应用语义,协议无法替所有应用决定。
- 为何 UDP 提供边界: 数据报模型本身就是“一次发送一次接收”,代价是不可靠/大小限制。
常见追问
追问 1:粘包是 TCP 的 bug 吗?
- 答题要点: 不是。是字节流的固有特性;应用层负责定义并解析消息边界。UDP 无此问题是因为数据报模型。
追问 2:关掉 Nagle 能彻底解决粘包吗?
- 答题要点: 不能。只能降低小包合并概率;接收缓冲一次读多段、网络聚合等仍会造成“多条消息一次读到”。根本解决靠应用层协议。
追问 3:HTTP 是怎么解决的?
- 答题要点:
Content-Length定长 body;或Transfer-Encoding: chunked分块边界;响应读到长度满足即一条消息结束。HTTP 头部以空行结束,也是一种边界约定。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「粘包只在长连接出现」 | 短连接也可能,只是边界被连接关闭掩盖 |
| 「UDP 也会粘包」 | UDP 保留数据报边界 |
| 「固定 read(n) 就一定对」 | 仍可能半包;必须按协议状态机拼包 |
| 「长度头可以无上限」 | 必须限制并校验,防内存攻击 |
| 「序列化格式自动解决粘包」 | Protobuf/gRPC 仍要在传输层加长度前缀或帧 |
与选择题对照
- 主库 150: 第 122 题(TCP 面向字节流的含义)、第 123 题(粘包主要原因)、第 121 题(TCP/UDP 对比)、第 64 题(UDP 特点)。
- 补题 16: 补-13(UDP 叙述,边界/校验相关对照)。
- 口述联动: 选择题考“原因与含义”;面试要解决方案细节与安全长度限制。
工程 / 抓包背景
- Wireshark: 同一
tcp.stream中观察多个应用消息是否同段/被拆;“TCP segment of a reassembled PDU”。 - 服务端: Java Netty
LengthFieldBasedFrameDecoder;Go 手写bufio按长度读;Pythonstruct.unpack读长度。 - Nginx: HTTP 层已帮你定界;自定义 TCP 协议需自行处理。
- 压测: 发小包高频 write 粘包更明显;可
tcpdump对照发送时序与到达段。 - 性能相关:
TCP_NODELAY关 Nagle,用于低延迟小消息(交互式协议)。
17. TCP/IP 协议栈分层与各层协议(热度 590 · 核心必考)
Q: 画出 TCP/IP 模型,说明各层功能和代表协议。
A:
模型对照(表)
| 层 | 功能 | 代表协议 | 数据单元 |
|---|---|---|---|
| 应用层 | 为用户提供网络服务 | HTTP/HTTPS、DNS、FTP、SMTP/POP3/IMAP、DHCP、SNMP、SSH、WebSocket | 报文 |
| 传输层 | 端到端(进程到进程)通信 | TCP、UDP | 报文段/用户数据报 |
| 网际层 | 主机到主机、路由与转发 | IP、ICMP、ARP*、IGMP、RIP/OSPF/BGP | 分组/数据报 |
| 网络接口层 | 相邻节点成帧与物理传输 | 以太网、PPP、Wi-Fi;ARP 常被讨论在 2.5 层 | 帧/比特 |
* ARP 国内教材常归网络层,也有说法是介于网络层与数据链路层之间。
TCP/IP 应用层 ↔ OSI 会话+表示+应用;传输层 ↔ 传输层;网际层 ↔ 网络层;网络接口层 ↔ 数据链路+物理。教材常用五层是教学折中,不是第三个国际标准模型。
设计动机:为什么分层?
关注点分离;各层独立演进(换介质不必改 HTTP);封装与同层对等通信;IP over everything / Everything over IP——网络接口层不规定唯一技术,应用层百花齐放,IP 做“细腰”。
封装与解封装
HTTP 报文 → TCP 首部+报文 → IP 首部+段 → 帧首尾 → 比特流。接收端自下而上拆首部,由同层实体读出;路由器通常只读到网络层。
常见追问
追问 1:为什么教材常用五层而不是四层?
- 答题要点: 五层把网络接口层拆成物理层与数据链路层,便于单独讲以太网、编码、成帧;是教学折中,TCP/IP 标准四层与 OSI 七层才是常见模型。
追问 2:路由器/交换机/集线器分别工作在哪一层?
- 答题要点: 集线器物理层(再生广播);交换机数据链路层(按 MAC 转发,隔离冲突域);路由器网络层(按 IP 查表转发,隔离广播域)。见主库第 20、129 题。
追问 3:ARP 属于哪一层?为什么有争议?
- 答题要点: 功能是 IP→MAC,服务网络层寻址,但报文在局域网以太网帧传输、不经过路由器转发到远端,故常归网络层或称“介于两层之间”。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「TCP/IP 就是 OSI」 | 层数、产生顺序、归并方式不同 |
| 「HTTP 工作在传输层」 | HTTP 在应用层;传输层是 TCP/UDP |
| 「IP 保证可靠交付」 | IP 尽最大努力,不可靠不有序 |
| 「端口号在网络层」 | 端口在传输层,用于进程分用 |
| 「封装时下层改上层首部」 | 一般只封装本层首部;路由器改 TTL/校验和是网络层自己的事 |
与选择题对照
- 主库 150: 第 2 题(OSI 七层/TCP-IP 四层)、第 3 题(网络层功能)、第 4 题(TCP/IP 与 OSI 对应)、第 6 题(对等层读首部)、第 7 题(两模型比较)、第 20 题(隔离广播域设备)、第 34 题(ARP)、第 46 题(路由器重新封装)、第 93 题(不属于应用层协议)、第 129 题(设备工作层次)。
- 补题 16: 补-02(以太网帧格式,数据链路层实例)、补-05(PPP)、补-10(冲突域/广播域与设备)。
- 口述联动: 选择题考层数/对应/设备;面试要能画层+封装链+分层动机。
工程 / 抓包背景
Wireshark 的 Frame/Ethernet/IPv4/TCP/HTTP 即封装视图。ping(ICMP)、traceroute(IP/TTL)、ss/netstat(传输层 socket)、curl(应用层)、tcpdump(帧/分组)。设备侧:交换机 show mac address-table,路由器 show ip route(最长前缀匹配)。排障口诀:链路 → IP(ping)→ 端口(ss/telnet)→ 应用(curl/日志)。
18. 套接字通信与线上状态排查(热度 193 · 进阶)
Q: 服务端大量 TIME_WAIT / CLOSE_WAIT 分别说明什么?怎么排查?
A:
状态含义
TIME_WAIT 多
- 出现在主动关闭方。
- 说明该侧在大量主动关闭连接,典型:未开 keep-alive 的 HTTP 服务、反向代理主动断开、短连接客户端/服务端模型。
- 通常是正常现象,但过多会:
- 耗尽本地 ephemeral 端口;
- 占用内存(
tcp_max_tw_buckets)。
- 优化:开启连接池/长连接、
net.ipv4.tcp_tw_reuse、调整ip_local_port_range、tcp_max_tw_buckets;tcp_tw_recycle(NAT 下有坑)自 Linux 4.12 起已删除,本机/proc/sys/net/ipv4/tcp_tw_recycle已不存在,新内核上无从调起。
CLOSE_WAIT 多
- 本端已收到对端 FIN,TCP 栈已进入 CLOSE_WAIT,但应用层迟迟没有调用 close()/shutdown。
- 典型是代码 bug:
- 连接未释放;
- 线程阻塞在读/锁;
- 异常路径未关闭;
- 连接池泄漏;
- 框架/HTTP 客户端未归还连接。
- 后果:fd 与内存持续增长,最终
too many open files、accept 失败、雪崩。
口诀:
大量 CLOSE_WAIT = 应用没关 socket(代码问题);大量 TIME_WAIT = 主动关闭方短连接多(可优化)。 不看代码也能通过「谁处于 TIME_WAIT」判断谁主动断开。
设计动机 / 深层
- TCP 状态机由内核维护;应用不调用 close,内核不能擅自把 CLOSE_WAIT 变成 LAST_ACK——必须由应用确认结束。
- TIME_WAIT 属于主动关闭方的保护性状态(见第 2 题 2MSL),不应视作纯垃圾状态。
常见追问
追问 1:TIME_WAIT 多一定是故障吗?怎么优化?
- 答题要点: 通常是短连接负载高的正常结果,不是故障本身;故障信号是端口耗尽、性能下降。优化连接复用与 keep-alive,而不是简单清状态。
追问 2:CLOSE_WAIT 的修复方向?
- 答题要点: 修代码——确保所有出口关闭连接;读完 body 再还池;设置连接/读写超时;监控 fd;对下游慢响应做隔离降级,避免线程占满导致关不掉。
追问 3:还有哪些 TCP 状态值得关注?
- 答题要点:
SYN_RECV多可能 SYN 队列攻击/半连接堆积;FIN_WAIT_2异常多可能对端不回 FIN;LAST_ACK多配合 CLOSE_WAIT 反映关闭流程卡住;ESTABLISHED暴涨看连接泄漏或流量上涨。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「TIME_WAIT 和 CLOSE_WAIT 都是网络问题」 | CLOSE_WAIT 多为应用 bug |
| 「CLOSE_WAIT 在主动关闭方」 | 在被动关闭方(收到 FIN 未 close) |
| 「ss/netstat 看不到进程」 | 需权限 -p,且有时需 root |
| 「把 TIME_WAIT 强行清空就没事」 | 可能丢保护、掩盖连接模型问题 |
| 「fd 多一定是泄漏」 | 也可能是正常高并发;看增长斜率与是否回收 |
与选择题对照
- 主库 150: 第 138 题(大量 CLOSE_WAIT 通常说明)、第 62/63 题(挥手与 TIME_WAIT)、第 136/137 题(ping 连通与网关)、第 38/39 题(ICMP 排障)、第 59 题(端到端)。
- 补题 16: 补-11(TCP 标志位,FIN/ACK 状态理解)。
- 口述联动: 选择题直接问 CLOSE_WAIT 含义;面试必须给排查命令与优化,而不是只背定义。
工程 / 抓包背景
- ss 系列:bash
ss -s ss -tanp ss -tan state close-wait '( sport = :443 )' ss -ti # rtt/cwnd 等 - sysctl:
tcp_tw_reuse、tcp_max_tw_buckets、ip_local_port_range、somaxconn、应用层 backlog。 - Nginx:
worker_connections、keepalive上游、proxy_ignore_client_abort等与连接生命周期相关。 - 排查顺序(口诀化):
ss -tan按状态计数 →ss -tan state close-wait/state time-wait定位是哪一侧 →ss -tanp/lsof -p <pid>看 fd 是否单调上涨 → 抓包确认 FIN/ACK 时序(谁先关)→ 查代码 close/连接池归还/超时设置 → 检查ulimit -n与 backlog、sysctl。 - curl 复现: 高并发短连接压测观察 TIME_WAIT 上涨;故意不读响应/中止客户端看服务端状态。
- Java/Go 常见坑: 响应 body 未 close、连接池
borrow未return、HTTP 客户端全局连接数过小导致排队。
19. HTTP 请求方法与 GET/POST 区别(热度 190 · 进阶)
Q: 常见 HTTP 方法有哪些?GET 和 POST 有什么区别?什么是 OPTIONS 预检?
A:
常见方法
| 方法 | 语义 | 幂等 | 安全 | 典型 |
|---|---|---|---|---|
| GET | 读取资源 | 是 | 是 | 列表/详情 |
| POST | 提交/创建(非绝对) | 否 | 否 | 表单、下单 |
| PUT | 全量替换 | 是 | 否 | 更新整个资源 |
| PATCH | 部分更新 | 可设计为是 | 否 | 改单个字段 |
| DELETE | 删除 | 是 | 否 | 删除资源 |
| HEAD | 只取响应头 | 是 | 是 | 探活、查元数据 |
| OPTIONS | 探测支持的方法 / CORS 预检 | 是 | 是 | 跨域预检 |
(“安全”指不应改变服务器状态;幂等指同一请求多次与一次效果相同。)
GET vs POST(语义层面,非绝对)
| 维度 | GET | POST |
|---|---|---|
| 语义 | 获取 | 提交/处理 |
| 参数位置 | URL query | 请求体(也可 query,但不推荐混用语义) |
| 缓存 | 可缓存 | 默认不缓存(可显式) |
| 幂等 | 是 | 默认否 |
| 书签/历史 | 可 | 一般不可 |
| 长度限制 | 协议不限制,实现/浏览器/服务器常有限制 | 一般可更大 |
| 安全 | 均不提供机密性;参数在 URL 可能进日志/Referer | body 相对不易进 URL 日志,但仍需 HTTPS |
| 编码 | application/x-www-form-urlencoded 等 | 多种:json、multipart/form-data 等 |
重要澄清: 传输层两者都可以用 TCP,都可以有 body(GET 有 body 少见且许多实现忽略),差别主要在语义、缓存、幂等与生态约定,不是“一个加密一个不加密”。
OPTIONS 与 CORS 预检
- 跨域是浏览器同源策略行为,服务端之间无“跨域”。
- 当请求 跨域且非简单请求 时,浏览器先发 OPTIONS 预检:
- 非简单请求典型:自定义头(如
X-Token)、Content-Type: application/json、方法 PUT/DELETE/PATCH 等。
- 非简单请求典型:自定义头(如
- 请求头常含:
OriginAccess-Control-Request-MethodAccess-Control-Request-Headers
- 服务器应答:
Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers- 可选
Access-Control-Max-Age(预检结果缓存秒数) - 涉及 Cookie 时
Access-Control-Allow-Credentials: true,且 Origin 不能是*
- 简单请求(GET/POST + 简单头 + 限定 Content-Type)不触发预检,但仍可能有 CORS 响应头要求。
常见追问
追问 1:GET 和 POST 的本质区别?GET 参数有长度限制吗?
- 答题要点: 本质是语义(读 vs 写)、幂等与缓存差异;不是“一个安全一个不安全”。协议层对 URL/Body 无绝对长度上限,限制来自浏览器、服务器(如 Nginx
large_client_header_buffers)、负载均衡等实现。
追问 2:为什么 JSON 跨域容易触发 OPTIONS?
- 答题要点:
Content-Type: application/json不在“简单类型”白名单(简单多为 text/plain、multipart/form-data、application/x-www-form-urlencoded),且常配自定义头/非 GET-POST 语义,故预检。
追问 3:预检失败常见原因?
- 答题要点: 未返回正确的
Access-Control-Allow-*;方法/头不在允许列表;带凭证却Allow-Origin: *;缓存过期;网关剥了 CORS 头;OPTIONS 被 WAF/框架路由拦下。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「GET 一定没有 Body」 | 可以有,但许多实现忽略;语义上应避免 |
| 「POST 一定安全」 | 与 HTTPS 无关;明文 POST 仍可被窃听 |
| 「POST 不能缓存」 | 可配置缓存,但默认少缓存 |
| 「OPTIONS 是业务查询接口」 | CORS 预检中主要是预检探询,可与 API 文档方法探测共用,注意路由 |
| 「跨域要改前端就能解决」 | 需服务器配合 CORS 头或同源/网关方案 |
与选择题对照
- 主库 150: 第 85 题(GET 获取资源)、第 84 题(HTTP 方法列表含 OPTIONS)、第 86/87 题(状态码,方法失败语义)、第 91/90 题(HTTPS 请求流程)。
- 补题 16: 无直接 OPTIONS 选择题;面试与前端联调高频。
- 口述联动: 选择题考方法语义;面试要幂等/缓存/CORS 预检与“跨域是浏览器行为”。
工程 / 抓包背景
- curl:bash
curl -X OPTIONS -H "Origin: https://app.example.com" \ -H "Access-Control-Request-Method: POST" \ -H "Access-Control-Request-Headers: content-type,x-token" \ -i https://api.example.com/v1/orders curl -I -X OPTIONS https://api.example.com/v1/orders - 浏览器: DevTools Network 过滤
preflight/OPTIONS;查看 CORS 报错文案。 - Nginx:nginx
add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS" always; add_header Access-Control-Allow-Headers "Authorization,Content-Type" always; if ($request_method = OPTIONS) { return 204; } - Wireshark:
http.request.method == "OPTIONS";观察预检是否先于真实请求。 - API 设计: 用 GET 查询、POST 创建、PUT/PATCH 更新、DELETE 删除;避免用 POST 仅因为“能传参”。
20. 应用层协议族与默认端口(热度 291 / 280 · 进阶)
Q: 列举常见应用层协议、作用与默认端口。
A:
协议与端口总表
| 协议 | 作用 | 传输层 | 端口 |
|---|---|---|---|
| HTTP | 网页传输 | TCP | 80 |
| HTTPS | 加密网页传输 | TCP(HTTP/3 为 UDP/QUIC) | 443 |
| DNS | 域名解析 | UDP(大响应/区域传送 TCP) | 53 |
| FTP | 文件传输(控制/数据双连接) | TCP | 21(控制)/20(主动数据) |
| SSH | 安全远程登录 | TCP | 22 |
| SMTP | 发送邮件 | TCP | 25 / 587(提交) |
| POP3 | 收邮件(下载后本地管理) | TCP | 110 |
| IMAP | 收邮件(服务器端管理/多端同步) | TCP | 143 |
| DHCP | 动态分配 IP | UDP | 67(服务端)/68(客户端) |
| SNMP | 网络管理 | UDP | 161 / 162(Trap) |
| Telnet | 远程登录(明文,已淘汰) | TCP | 23 |
| 相关加密版 | SMTPS/POP3S/IMAPS 等 | TCP | 465/995/993 等 |
补充:NTP 123/UDP、Redis 6379、MySQL 3306、PostgreSQL 5432、Kafka 9092;HTTP/3 仍常用 443 但走 UDP/QUIC。
协议细节加分
FTP 主动 vs 被动
- 主动模式: 客户端连接 21 建控制连接;传输时服务器用 20 端口主动连接客户端的数据端口。NAT/防火墙后常失败(外部主动入站被拦)。
- 被动模式(PASV): 服务器告知一个随机高端口,客户端主动连过去。更适合 NAT/防火墙,现代客户端默认更常见。
- 控制连接始终在线传命令;数据连接单独建立传文件/目录列表。
DHCP 四步(DORA)
- Discover(客户端广播,尚无 IP,目的 255.255.255.255)
- Offer(服务器提供 IP 等)
- Request(客户端请求选用)
- ACK(服务器确认)
DNS: 查询默认 UDP 53;区域传送 AXFR/IXFR 用 TCP 53。
邮件三件套: SMTP 发;POP3 拉到本地;IMAP 留在服务器多端同步。企业环境常见 TLS 变体端口。
设计动机
- 知名端口(0–1023): 客户端无需事先约定即可找到标准服务。
- 注册端口(1024–49151)与动态/私有端口(49152–65535): 应用注册与客户端临时源端口。
- 控制/数据分离(FTP): 命令通道稳定,数据通道可按需建立、支持多文件与目录。
- UDP 选择(DNS/DHCP/SNMP): 小消息、广播/查询-响应、低延迟;重要大传输再升级 TCP。
常见追问
追问 1:FTP 为什么两个连接?主动被动区别?为何 NAT 下被动更好?
- 答题要点: 控制/数据分离便于命令与传输并行、多文件。主动是服务器连客户端(入站难);被动是客户端连服务器协商端口(出站易通过 NAT/防火墙)。
追问 2:TCP 53 和 UDP 53 会冲突吗?
- 答题要点: 不会。内核 socket 以协议+端口等区分,可并存。对应主库第 72 题。
追问 3:DHCP 客户端还没 IP,怎么发 Discover?
- 答题要点: 使用源 0.0.0.0、目的 255.255.255.255 的广播;服务器 Offer 后经 DORA 完成配置。跨网段靠 DHCP 中继(giaddr)。
易错点
| 易错说法 | 纠正 |
|---|---|
| 「HTTPS 端口不是 443」 | 默认 443;HTTP/3 仍是 443 但传输 UDP |
| 「FTP 数据固定 20」 | 主动模式常见 20;被动模式是协商高端口 |
| 「DNS 只有 UDP」 | 大响应/区域传送 TCP |
| 「SSH 和 Telnet 差不多」 | SSH 加密认证,Telnet 明文已淘汰 |
| 「端口号决定安全性」 | 端口是约定;安全靠协议本身(TLS/SSH) |
与选择题对照
- 主库 150: 第 72–77 题(端口与 FTP 模式)、第 65 题(用 UDP 的应用)、第 57 题(DHCPDISCOVER 目的地址)、第 79–83 题(DNS)、第 74/91 题(HTTP/HTTPS)、第 134 题(SNMP)、第 75 题(SMTP/POP3 端口)。
- 补题 16: 补-14(SMTP/POP3/IMAP 功能与端口)、补-15(广域网 ATM 53 字节信元,对比分组概念)、补-16(网管 FCAPS,SNMP 背景)。
- 口述联动: 选择题背端口数字;面试要能讲 FTP 主动/被动、DHCP DORA、DNS TCP/UDP 切换。
工程 / 抓包背景
- 探测端口:bash
ss -lntup telnet example.com 443 # 或 nc -vz host port curl -v telnet://127.0.0.1:22 - 抓包: Wireshark 过滤
dns、ftp、ftp-data、dhcp、ssl/tls、ssh。 - Nginx: 80/443 监听;stream 模块可代理非 HTTP(如 TCP 代理)。
- curl:
curl -v ftp://...(支持 FTP)、curl -v https://...;dig +short查 DNS。 - 安全检查: 线上不要暴露 Telnet/FTP 明文;管理端口限制来源 IP;DNS 用 DoH/DoT 时关注 443 上的名称解析流量。
附:热度排序总表(数据来源:八股精 6975 条真实面经,2025–2026)
| 排名 | 考点 | 热度 | 梯队 | 对应题号 |
|---|---|---|---|---|
| 1 | TCP 协议 | 780 | 核心必考 | 3、4 |
| 2 | TCP 三次握手 | 654 | 核心必考 | 1 |
| 3 | TCP 四次挥手 / TIME_WAIT | 654 | 核心必考 | 2 |
| 4 | HTTP 请求过程 | 609 | 核心必考 | 7 |
| 5 | TCP/IP 协议栈 | 590 | 核心必考 | 17 |
| 6 | WebSocket | 572 | 核心必考 | 14 |
| 7 | HTTPS | 451 | 高频选考 | 11、13 |
| 8 | SSL/TLS | 432 | 高频选考 | 12 |
| 9 | SSE | 365 | 高频选考 | 14 |
| 10 | UDP 协议 | 352 | 高频选考 | 3 |
| 11 | 密钥协商 | 336 | 高频选考 | 11 |
| 12 | DNS | 318 | 高频选考 | 8 |
| 13 | 可靠传输 | 310 | 高频选考 | 4、5、6 |
| 14 | HTTP/2 | 297 | 进阶 | 10 |
| 15 | 应用层协议 | 291 | 进阶 | 20 |
| 16 | HTTP/3 | 284 | 进阶 | 10 |
| 17 | HTTP 协议 | 280 | 进阶 | 9、13、19 |
| 18 | 长连接 | 221 | 进阶 | 15 |
| 19 | 套接字通信 | 193 | 进阶 | 18 |
| 20 | HTTP 请求方法 | 190 | 进阶 | 19 |
| 21 | TCP 粘包 | 182 | 进阶 | 16 |
数据说明:热度为真实面试记录中的出现频次统计,仅作复习优先级参考;不同公司/岗位(后端、前端、运维、客户端)偏好略有差异。本表按「考点」列 21 行,覆盖正文 20 题——这张表按「考点」分行,不是按题号分行:一行可对应多个题号(如「3、4」「4、5、6」「9、13、19」),一个题号也可能出现在多行,所以 21 行 ≠ 20 题,别按「每题占几行」去数。
选择题对照索引(速查):
- 主库高频簇:60–71(TCP 连接与拥塞)、79–83(DNS)、84–87/90–92/145–146(HTTP)、99–116(安全与 TLS)、121–124(TCP/UDP 与访问顺序)、127(BDP)、129(设备层次)、136–138(排障)。
- 补题对应:补-03/04(可靠传输窗口)、补-11/12/13(TCP/UDP)、补-14(邮件协议)、补-02/05/10(分层与链路)、补-15/16(广域网与网管,面试第 20 题扩展背景)。
本版结构校验: 全文保持 20 组 Q/A;每题含完整过程/机制(多数题另有「设计动机」小节)、常见追问(每题 3 条)、易错点、选择题对照(主库+补题)、工程/抓包背景(该小节统一置于每题末尾、且只出现一次);题号与热度标注未改。