http2 是什么?比http
1️⃣ 考察意图
这道题看似基础,但面试官真正想看的不是背定义,而是区分“知道”和“理解”。考察类型是工程取舍与协议设计。刁钻点在于:很多人只记得“多路复用”这个名词,却说不清它解决了什么、带来了什么新问题(如TCP层面的队头阻塞)。答好了能展示你对网络协议栈的底层理解、对性能瓶颈的直觉,以及是否真正做过高并发场景下的优化。面试官会通过追问“为什么HTTP/2没有完全取代HTTP/1.1”来验证你的深度。
2️⃣ 标准答
HTTP/2 是 HTTP 协议的第二个主要版本,基于 Google 的 SPDY 协议,核心目标是通过减少延迟和提高连接利用率来加速 Web 性能。它没有改变 HTTP 的语义(方法、状态码、头部字段等),但彻底改变了传输方式。
核心特性与工程取舍:
- 二进制分帧(Binary Framing):HTTP/1.1 是文本协议,解析效率低且容易出错。HTTP/2 将所有数据拆分为更小的帧(Frame),如 HEADERS 帧、DATA 帧、SETTINGS 帧。帧是二进制格式,解析速度更快,且支持流(Stream)级别的控制。取舍:二进制协议对开发者不友好,无法直接用 telnet 调试,但换来了更高的解析效率和更低的 CPU 开销。
- 多路复用(Multiplexing):这是最关键的改进。HTTP/1.1 的队头阻塞(Head-of-Line Blocking)问题在于:一个连接上只能串行处理请求,前一个请求的响应没到,后面的请求就得等。HTTP/2 允许在一个 TCP 连接上同时交错发送多个请求和响应,每个请求/响应对应一个流(Stream),流之间独立。实际落地的坑:虽然 HTTP/2 解决了应用层的队头阻塞,但 TCP 层面仍然存在队头阻塞——如果一个 TCP 包丢失,所有流都得等待重传。这是 HTTP/3 用 QUIC(基于 UDP)解决的核心问题。
- 头部压缩(HPACK):HTTP/1.1 的头部是纯文本,每次请求都会重复发送大量冗余字段(如 Cookie、User-Agent)。HPACK 使用静态表(预定义常见头部)、动态表(动态更新)和Huffman 编码来压缩头部。为什么这么做:一个典型 HTTP/1.1 请求头部可能有 800 字节,压缩后可能只剩 30 字节。对于 API 密集型的应用(如微服务间调用),头部压缩能显著降低延迟。取舍:HPACK 需要维护动态表状态,增加了服务器内存开销,且对中间代理(如 CDN)的兼容性有要求。
- 服务器推送(Server Push):服务器可以主动向客户端推送资源(如 CSS、JS),无需客户端显式请求。实际落地的坑:推送的资源可能已经被客户端缓存,导致带宽浪费。更糟糕的是,如果推送了客户端不需要的资源(如移动端推送桌面端的大图),反而会拖慢页面加载。实践中,很多团队选择关闭服务器推送,改用
103 Early Hints状态码或预加载链接(<link rel="preload">)来替代。
与 HTTP/1.1 的性能对比:
- 连接数:HTTP/1.1 通常需要 6-8 个并行连接来提升性能;HTTP/2 只需 1 个连接,减少了 TCP 握手和 TLS 握手的开销。
- 延迟:多路复用 + 头部压缩,在资源密集型页面(如 100+ 个资源)下,加载时间可减少 30%-50%(具体取决于网络条件)。
- 适用场景:高并发、资源密集型的 Web 应用(如电商首页、社交 Feed)收益最大;对于 API 调用(请求少、头部小),收益有限。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一,HTTP/2 的核心改进是二进制分帧、多路复用、头部压缩和服务器推送;第二,它解决了 HTTP/1.1 的队头阻塞和冗余头部问题,但引入了 TCP 层面的新队头阻塞;第三,实际落地中,服务器推送有缓存浪费的坑,很多团队选择关闭它。总结一句:HTTP/2 是 HTTP/1.1 的传输层升级,不是语义层革命,且已被 HTTP/3 部分取代。”
4️⃣ 高频追问 & 应对
追问 1:HTTP/2 的多路复用和 HTTP/1.1 的管道化(Pipelining)有什么区别?
应对策略:管道化虽然允许连续发送多个请求,但响应必须按顺序返回(FIFO),队头阻塞依然存在。多路复用允许响应乱序到达,流之间完全独立。管道化在实际中几乎被禁用,因为中间代理和服务器支持很差。多路复用是二进制分帧的产物,每个帧携带流 ID,可以交错传输。
追问 2:为什么 HTTP/2 没有完全取代 HTTP/1.1?什么场景下 HTTP/1.1 反而更好?
应对策略:三个原因:1)TCP 队头阻塞问题未解决,弱网环境下(如丢包率 > 2%)HTTP/2 性能可能比 HTTP/1.1 还差,因为多个流共享一个 TCP 连接,一个丢包影响所有流;2)服务器推送的坑导致很多团队放弃;3)HTTP/2 需要 TLS(虽然标准不强制,但浏览器强制),增加了握手延迟。对于低资源、低并发的场景(如简单的 REST API),HTTP/1.1 的简单性反而更优。
追问 3:如何检测一个网站是否使用了 HTTP/2?如何从 HTTP/1.1 迁移到 HTTP/2?
应对策略:检测:用
curl -I --http2 https://example.com查看响应头中的X-Firefox-Spdy或Alt-Svc字段;或用 Chrome DevTools 的 Protocol 列。迁移:1)确保服务器支持 ALPN(Application-Layer Protocol Negotiation),如 Nginx 1.9.5+、Caddy;2)检查是否有依赖 HTTP/1.1 特性的中间件(如某些代理不支持多路复用);3)关闭服务器推送,改用预加载;4)测试性能,重点关注弱网环境下的 TCP 队头阻塞影响。
5️⃣ 避坑 · 常见错误答法
- ❌ 说“HTTP/2 比 HTTP/1.1 快很多,所以应该全面替换 HTTP/1.1” → ✅ 正确切入:HTTP/2 在弱网环境下可能更慢,且迁移成本高(需要 TLS、中间件兼容性),很多场景下 HTTP/1.1 仍然适用。
- ❌ 说“多路复用解决了所有队头阻塞问题” → ✅ 正确切入:只解决了应用层队头阻塞,TCP 层队头阻塞仍然存在,这是 HTTP/3 用 QUIC 解决的核心问题。
- ❌ 说“服务器推送可以明显提升性能,应该默认开启” → ✅ 正确切入:服务器推送有缓存浪费和带宽浪费的坑,实践中很多团队选择关闭,改用
103 Early Hints或预加载。
6️⃣ 简历呼应
- 如果你有 Web 性能优化项目:从“实际对比 HTTP/1.1 和 HTTP/2 的加载时间”切入,给出具体数据(如资源数、延迟、丢包率),并说明你如何通过关闭服务器推送或调整 HPACK 动态表大小来优化。
- 如果你只做过后端 API 开发:用“微服务间调用”类比,说明 HTTP/2 的头部压缩对 API 网关的收益,以及为什么在内部 RPC 场景下 gRPC(基于 HTTP/2)比 REST 更高效。
- 如果你是校招无项目:聚焦“HTTP/2 与 HTTP/3 的对比”,展示你对协议演进的理解,并提及你搭建过 Nginx 服务器对比测试(即使只是 demo)。
- 《HTTP/2 in Action》by Barry Pollard
- RFC 7540 - HTTP/2 官方规范
- 《High Performance Browser Networking》by Ilya Grigorik(第 12-14 章)
- Nginx 官方文档:HTTP/2 配置与性能调优
- “HTTP/2 的队头阻塞问题” - Cloudflare 博客