i007.cc

i007.cc

优先队列-降维打击

05.价值资料

Day 2 网络协议 — 面试备考手册

 1. TCP 三次握手 / 四次挥手

三次握手(建立连接)

Client                    Server
  |  ── SYN, seq=X ──▶  |    第一次:我想连你,我的序号是X
  |  ◀─ SYN+ACK, seq=Y ─|    第二次:收到,我的序号是Y,确认你的X
  |  ── ACK ──────────▶  |    第三次:收到,连接建立

 

为什么必须三次,不能两次?

两次握手后 Client 已经确认双向通信正常,但 Server 不知道自己的发送是否有效

第三次握手就是 Client 告诉 Server “你发的我收到了”。三次握手确保双方都能正常收发。

还有一个原因:防止网络中延迟的旧 SYN 包被误认为新连接请求,造成资源浪费。


四次挥手(断开连接)

Client                    Server
  |  ── FIN ───────────▶ |    我发完了,想断开
  |  ◀─ ACK ─────────── |    收到,但我还有数据没发完
  |  ◀─ FIN ─────────── |    我也发完了
  |  ── ACK ───────────▶ |    好的,再见

 

为什么挥手要四次?
TCP 是全双工的,Client 和 Server 各自有一个发送通道,必须分别关闭。Server 收到 FIN 后可能还有数据没发完,所以 ACK 和 FIN 必须分开,不能合并成三次。

TIME_WAIT 状态: Client 发出最后的 ACK 后,要等 2×MSL(约 2 分钟)才真正关闭,防止最后的 ACK 丢失后 Server 重发 FIN 时无人响应。


2. HTTP vs HTTPS / TLS 握手 / 证书链

HTTP vs HTTPS

HTTP 是明文传输,没有加密、没有身份验证。HTTPS = HTTP + TLS,解决了三个问题:

  • 加密:传输内容不被窃听
  • 认证:确认你访问的是真正的服务器
  • 完整性:内容没被篡改

TLS 握手过程(面试只需记住这个流程)

Client                          Server
  |  ── Client Hello ─────────▶ |   发送:支持的加密算法、随机数A
  |  ◀─ Server Hello ────────── |   回复:选择的加密算法、随机数B、数字证书
  |   验证证书(证书链)           |
  |  ── Pre-Master Secret ─────▶|   用服务器公钥加密后发送
  |   双方各自生成对称密钥          |   用 随机数A + 随机数B + Pre-Master Secret 推导
  |  ◀══════ 加密通信开始 ══════▶ |

 

TLS 1.3 的改进: 握手从 2-RTT 缩短到 1-RTT,重连可以 0-RTT,废弃了老旧不安全的加密套件。


证书链

Root CA(根证书,浏览器内置信任)
  └── Intermediate CA(中间证书)
        └── End Entity Certificate(你的网站证书)

 

验证过程:从网站证书往上逐级验签,直到找到浏览器内置信任的根证书。验证内容包括:有效期、域名是否匹配、签名是否正确。


3. DNS 解析全流程

用户输入 www.example.com,发生了什么:

1. 浏览器缓存  →  命中就返回
2. 操作系统缓存 / hosts 文件  →  命中就返回
3. 本地 DNS 解析器(路由器/ISP)  →  缓存未命中,开始向外查询
4. → 根域名服务器:".com 的 TLD 服务器在哪?"
5. → .com TLD 服务器:"example.com 的权威 DNS 在哪?"
6. → example.com 权威 DNS:"www.example.com 的 IP 是什么?"
7. ← 返回 IP 地址,本地 DNS 缓存(按 TTL),返回给浏览器

 

关键概念:

  • TTL:DNS 记录的缓存有效时间,越小更新越快但查询越频繁
  • 迭代查询:本地 DNS 自己一步步问(上面的流程)
  • 递归查询:浏览器问本地 DNS,本地 DNS 全权代劳
  • DoH / DoT:DNS over HTTPS / TLS,防止 DNS 查询被监听篡改

4. HTTP/1.1 vs HTTP/2 vs HTTP/3

核心问题与演进

问题 HTTP/1.1 HTTP/2 HTTP/3
并发请求 每域名 6 个 TCP 连接 单连接多路复用 单连接多路复用
队头阻塞 有(应用层) 解决了应用层,TCP 层仍有 彻底解决
Header 每次完整发送,冗余大 HPACK 压缩 QPACK 压缩
传输格式 文本 二进制分帧 二进制
底层协议 TCP TCP QUIC(基于 UDP)
连接建立 TCP + TLS 共 3-RTT 同左 1-RTT,重连 0-RTT
网络切换 断连 断连 不断连(Connection ID)

记住一句话: HTTP/2 解决了应用层的队头阻塞,但 TCP 丢包时整个连接都要等重传;HTTP/3 换成 QUIC(UDP),每个 stream 独立,丢包只影响那一个流。


5. REST vs gRPC

一句话区别

REST 是给人和浏览器用的,gRPC 是给服务和服务用的。

详细对比

维度 REST gRPC
协议 HTTP/1.1 或 HTTP/2 HTTP/2
数据格式 JSON(文本,可读) Protocol Buffers(二进制,高效)
类型安全 无强制约束 .proto 文件定义,强类型
通信模式 请求-响应 支持双向流式通信
性能 中等 高(序列化快约 5-10 倍)
浏览器支持 完美 有限(需要 grpc-web)
调试 容易(curl/Postman) 相对复杂

什么时候用 REST: 公开 API、需要浏览器直接访问、简单 CRUD、对外接口。

什么时候用 gRPC: 微服务之间内部调用、需要高吞吐低延迟、需要流式传输(如实时日志、视频流)、多语言系统(.proto 自动生成各语言代码)。


6. WebSocket vs Long Polling

三种”实时”方案对比

短轮询(Short Polling):
客户端每隔 N 秒问一次”有新消息吗?”。简单粗暴,浪费资源,不算实时。

长轮询(Long Polling):

Client ──请求──▶ Server(挂起,等数据)
                 有数据了!
Client ◀──响应── Server
Client ──立刻再请求──▶ Server(继续挂起)

 

比短轮询实时,但本质还是 HTTP 请求-响应,每次有消息都要重建连接,高并发时服务器连接数压力大。

WebSocket:

Client ──HTTP Upgrade──▶ Server   一次握手升级
Client ◀══ 持久双向连接 ══▶ Server  之后随时互发消息

 

真正的全双工实时通信,服务器可以主动推送,延迟最低,适合聊天、游戏、实时数据面板。代价是需要服务器维护长连接状态,水平扩展需要处理连接路由问题(比如用 Redis Pub/Sub 做跨节点广播)。

选择原则:

  • 只需服务器推送 → SSE(Server-Sent Events,更简单)
  • 需要双向实时 → WebSocket
  • 改造成本高、偶发推送 → Long Polling 也够用

高频追问备忘

  • TCP 和 UDP 的区别? TCP 可靠有序,UDP 快但不保证到达,适合视频/游戏/DNS
  • HTTPS 一定安全吗? 证书可以被伪造(中间人攻击),需要 HSTS + 证书透明度日志
  • HTTP/2 的多路复用为什么解决不了 TCP 的队头阻塞? TCP 是字节流,丢一个包整个连接的所有 stream 都要等重传,HTTP/2 的 stream 只是应用层抽象
  • gRPC 的四种通信模式? Unary(一请求一响应)、Server Streaming、Client Streaming、Bidirectional Streaming

发表回复