基础原理
Network
网络协议与传输链路。核心能力:HTTP 演进、TCP/UDP、缓存策略、WebSocket、跨域方案。
网络题常考"为什么这样设计"——比如三次握手为什么不是两次,HTTP/2 为什么还有队头阻塞。把协议设计的 trade-off 讲清楚是关键。
HTTP 演进
HTTP/1.1(1997)
- 默认 Keep-Alive 持久连接
- 同一连接串行请求 → 队头阻塞
- 纯文本头部,重复传输
- 并发策略:浏览器对同域名开 6~8 个 TCP 连接
HTTP/2(2015)
- 多路复用:单连接并发多个流
- 二进制分帧:HEADERS + DATA 帧
- HPACK 头部压缩:静态/动态表
- 服务端推送(实际使用少)
- 局限:TCP 层队头阻塞仍存在
HTTP/3(2022)
- 基于 QUIC(UDP),不再用 TCP
- 彻底解决队头阻塞(每流独立)
- 0-RTT / 1-RTT 握手(TLS 1.3 集成)
- 连接迁移:Connection ID 标识,Wi-Fi 切 4G 不断连
对比总表
| 特性 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 传输协议 | TCP | TCP | QUIC (UDP) |
| 队头阻塞 | 应用层 + 传输层 | 传输层 (TCP) | 无 |
| 头部压缩 | 无 | HPACK | QPACK |
| 连接迁移 | 不支持 | 不支持 | 支持 |
| 建连延迟 | TCP 3-RTT + TLS | TCP + TLS ≈ 2-3 RTT | 1-RTT / 0-RTT |
TCP vs UDP
| 维度 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 可靠(确认重传) | 不可靠 |
| 顺序 | 按序到达 | 可能乱序 |
| 流量控制 | 滑动窗口 | 无 |
| 拥塞控制 | 有 | 无 |
| 速度 | 慢 | 快 |
| 头部 | 20 字节 | 8 字节 |
选择策略
- 数据重要 → TCP;丢了也行 → UDP
- 实时性高 → UDP;否则 → TCP
三次握手与四次挥手
三次握手(建立连接)
Client Server
|── SYN (seq=x) ──────────────>| 我要连接
|<── SYN+ACK (seq=y,ack=x+1) ──| 同意 + 确认
|── ACK (ack=y+1) ────────────>| 确认,连接建立为什么不是两次? 两次握手下,服务端无法确认客户端收到了 SYN+ACK,可能建立无效连接浪费资源。
四次挥手(断开连接)
Client Server
|── FIN ──────────────────────>| 我不再发数据
|<── ACK ──────────────────────| 收到(服务端可能还有数据)
|<── FIN ──────────────────────| 我也不再发了
|── ACK ──────────────────────>| 收到,进入 TIME_WAIT为什么不是三次? TCP 全双工,双方需独立关闭。中间的 ACK 和 FIN 不能合并,因为服务端可能还有数据要发。
HTTP 缓存
强缓存
不发请求,直接使用本地缓存。
| 头部 | 说明 |
|---|---|
Cache-Control | max-age=3600 / no-cache / no-store |
Expires | HTTP/1.0 绝对时间(已过时) |
协商缓存
发请求验证资源是否过期。
| 请求头 | 响应头 | 说明 |
|---|---|---|
If-None-Match | ETag | 内容哈希 |
If-Modified-Since | Last-Modified | 最后修改时间 |
缓存流程
请求资源 → 有缓存?
├─ 强缓存有效 → 直接使用
└─ 强缓存过期 → 协商验证
├─ 304 → 使用旧缓存
└─ 200 → 使用新资源 + 更新缓存实战配置
# HTML:每次验证
location / {
add_header Cache-Control "no-cache, must-revalidate";
}
# 带 hash 静态资源:长期缓存
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}HTTP 状态码
| 范围 | 类别 | 常见码 |
|---|---|---|
| 2xx | 成功 | 200 OK |
| 3xx | 重定向 | 301 永久 / 302 临时 / 304 缓存 |
| 4xx | 客户端错 | 400 参数错 / 401 未认证 / 403 无权限 / 404 未找到 |
| 5xx | 服务端错 | 500 内部错 / 502 网关错 / 503 过载 / 504 超时 |
GET vs POST
| 维度 | GET | POST |
|---|---|---|
| 语义 | 获取资源 | 提交数据 |
| 参数位置 | URL | 请求体 |
| 幂等性 | 幂等 | 非幂等 |
| 缓存 | 可缓存 | 不缓存 |
| 安全性 | 参数暴露在 URL | 相对更安全 |
| 长度限制 | URL 有长度限制 | 无限制 |
WebSocket
| 特性 | HTTP | WebSocket |
|---|---|---|
| 通信模式 | 请求-响应 | 全双工 |
| 连接 | 短连接 | 持久连接 |
| 协议 | HTTP/1.1 / 2 | ws:// / wss:// |
| 握手 | — | HTTP 101 升级 |
| 适用 | 普通请求 | 实时通信 |
DNS 解析
- 浏览器 DNS 缓存 → 系统缓存 → 路由器缓存
- ISP 的 DNS 服务器 → 递归查询
- 根 DNS → 顶级域 DNS → 权威 DNS
优化
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="//api.example.com" />
<!-- 预连接(DNS + TCP + TLS) -->
<link rel="preconnect" href="https://api.example.com" />CDN
- 内容分发网络,将资源缓存到离用户最近的边缘节点
- 静态资源(JS/CSS/图片/字体)放 CDN
- 配合
Cache-Control和文件名 hash 实现长期缓存 + 即时更新
网络安全
HTTPS
- TLS 握手:身份认证 + 密钥协商 + 数据加密
- TLS 1.3:1-RTT 握手,0-RTT 重连
运营商劫持
- DNS 劫持:伪造 DNS 响应,指向广告页面
- HTTP 劫持:在响应中注入广告 JS/iframe
- 防御:全站 HTTPS + HSTS + DNSSEC