面试一周目——我的面筋

276 阅读11分钟

最近也是开始面试了,还是得背八股,常问的问题就是:Http 的版本区别、TCP 和 UDP 的对比、三次握手四次挥手、以及“从 URL 输入到页面展示”的全过程。
但是我自己在复盘的时候发现,如果只停留在一问一答的层面,很难打动面试官。真正能加分的地方,是你能把问题往自己熟悉的方向延展,表现出“理解底层 + 注重实践”的能力。

我就按照这几个题目,分享一下当时的回答和我的思考。


Http 1.0、1.1、2.0 的区别与演进

当面试官问这个问题时,回答大概是:“1.0 每次连接一次,1.1 支持 keep-alive,2.0 有多路复用”。
这种回答没错,但有点浅了。

HTTP 0.9 的出现

  • 版本支持:最早的版本,只支持GET请求,响应只有HTML文本,没有header
  • 局限性:只能传输见到那网页,连图片、css、js 都不能传输

👉 主要用于在网络之间传递HTML超文本的内容。当时,它的设计目的很简单,就是为了方便科研人员之间学术交流。

Http 1.0 的局限

  • 无状态:每次请求都得带完整的 header,浪费带宽。
  • 短连接:每次请求都要建立和释放 TCP 连接,握手开销大。
  • 没有完善的缓存机制:只能用 Expires,不够灵活。

👉 在早期网页只是文本+少量图片时,这些问题还不明显。但随着页面越来越复杂,用户越来越多,1.0 的效率就成了瓶颈。

Http 1.1 的改进

  • 持久连接:默认启用 keep-alive,一个 TCP 连接可以发送多个请求,但是响应必须按顺序返回(管道化)。
  • 更强的缓存控制Cache-ControlETagLast-Modified 等。
  • Host 头:支持虚拟主机,在一台服务器上跑多个站点。
  • 存在问题:没有能真正并发,TCP 安全 响应时还是顺序的传输。队头阻塞,如果排在前面的资源传输慢,后面的就没有办法传输。

👉 但 1.1 的管道化并没有解决“队头阻塞”,因为返回还是要按顺序,一个请求卡住,后面都得等。也可以谈一谈你对版本理解,1.1只是小版本更新,为了应付某个需求而产出的某个功能,或是修复一些紧急的bug,或是一些性能优化之类的。

Http 2.0 的突破

  • 二进制分帧:所有请求和响应都拆成小数据帧,相比文本协议,更高效。
  • 多路复用:多个请求在一个连接中并行,不会互相阻塞。
  • 头部压缩:减少重复 header传输。
  • 服务端推送:首屏还依赖css、js等,为了减少首轮返回,服务器会主动的push这些资源。

👉 但 2.0 还是跑在 TCP 上,依旧会受到 TCP 队头阻塞的影响,所以后来才有了 Http/3 基于 QUIC(UDP)的尝试。注意Http 本身用二进制分帧解决了队头阻塞,每个帧带有编号,指定是哪个文件,客户端和服务器端可以根据编号重组,无需排队,谁先准备好谁就先发。

延展补充

“前端性能优化里面很多场景,其实都是 Http 版本演进带来的红利。比如资源合并(雪碧图、JS 合并)在 Http 1.x 是必须的,但在 Http/2 多路复用下就没必要了,反而可能增加首屏时间。这也是为什么性能优化策略要结合实际网络环境去看。”


TCP 和 UDP 的区别

这个问题表面上很基础,但可以往“可靠性 vs 实时性”的角度扩展。

TCP

  • 面向连接(三次握手)
  • 可靠(保证不丢包、不乱序)
  • 有流量控制、拥塞控制
  • 应用:网页、文件下载、邮件

UDP

  • 无连接(发包就完事,不管对方在不在)
  • 不可靠(可能丢包、乱序)
  • 轻量级,开销小
  • 应用:直播、游戏、视频会议

http 3.0用的基于QUIC 协议,改用UDP 代替TCP 作为传输层

延展补充

“比如微信语音和视频聊天,其实走的是 UDP,因为允许有少量丢包但要保证实时性;而文件传输、聊天记录同步则是 TCP,因为必须保证不丢失。”

面试官继续追问:“那 Http/3 为什么要基于 UDP?”
我就接上:

“因为 TCP 的队头阻塞在多路复用场景下依旧存在,QUIC 在 UDP 上自己实现了可靠传输,绕开了 TCP 内核协议栈的限制,这样可以更快地迭代和优化。”


三次握手与四次挥手

面试官喜欢考这道题,因为很多人只记得“3 次和 4 次”,却解释不清楚为什么要这样设计。

三次握手

  1. 客户端:发送 SYN(我想和你建立连接)
  2. 服务端:返回 SYN+ACK(我收到了,咱们连吧)
  3. 客户端:发送 ACK(确认收到,正式开始)

四次挥手

  1. 客户端:发送 FIN(我要断开了)
  2. 服务端:发送 ACK(我知道了)
  3. 服务端:等数据传完,发送 FIN(我也断开了)
  4. 客户端:返回 ACK(确认断开)

接下来他又追着打了,为什么 TCP 是三次握手?为什么是四次挥手?

两次握手的问题

如果只用两次:

  • 客户端发送 SYN,服务端回 ACK,就算连接成功。
  • 但是如果这个 SYN 是一个延迟的、过期的报文(所谓“历史报文”),服务端仍然会认为有个客户端要连,结果白白浪费资源,甚至可能被攻击者利用(SYN Flood)。

三次握手的价值

  • 第三次 ACK 可以确认客户端是真的存在,并且能接收数据。
  • 三次握手是最小成本下的安全保障。

延展补充

从安全角度看,三次握手防止了历史报文带来的错误连接,同时也是抵御 SYN 攻击的基础手段。

为什么断开是四次挥手而不是三次?

1. 关闭连接是双向的

  • 建立连接时,双方都还没有数据,就一起来“说好”。
  • 断开连接时,双方可能还在发送数据,不能同时关。

所以:

  • 一方(主动关闭方)要先说“我不发了”(FIN)。
  • 另一方收到后可能还没发完,就先回复“我知道了”(ACK),但是连接还不能断
  • 等他数据发完,再发自己的“我也不发了”(FIN)。
  • 最后再确认一次(ACK)。

这样就多出来一个来回,总共 4 次


2. 为什么不能把 ACK 和 FIN 合并?

那为什么服务端不能在收到 FIN 时,直接同时回 FIN+ACK,就三次搞定?

问题在于:

  • 服务端可能还有数据没发完。

  • 如果立刻发 FIN,就意味着“我也不发了”,但这和实际状态不符(服务端数据还没发完)。

  • TCP 要保证数据 可靠传输,所以必须分开两个阶段:

    • 先告诉对方“我知道你要断了,但我这边还没断”(ACK)。
    • 等自己真的准备好了,才发 FIN

3. 本质区别:

  • 建立连接(三次握手) :双方都没负担 → 可以同时确认,一起建。
  • 释放连接(四次挥手) :双方可能有剩余数据 → 必须分两段确认,保证不丢数据。

总结一句面试回答:

三次握手是为了确认双方的发送和接收能力,确保不存在历史报文;四次挥手是因为关闭连接时双方数据传输不同步,ACK 和 FIN 不能合并,必须分两次完成。


从 URL 输入到页面展示

一开始我就是简单回答,草草了事了,后面回顾这个问题,发现这个问题可以有很多地方展示肌肉。我以自己的理解拆分一下流程。

1. 用户输入 URL

  • 浏览器会先判断这是搜索关键字还是 URL。
  • 如果没有写协议,现代浏览器默认会补上 https://(而不是 http://,因为 HTTPS 已经成了标配)。

👉 延展:
这里可以提到输入www.baidu.com/ ,他会307临时重定向到www.baidu.com/ ,这里就看面试官追不追问重定向了,但是我们也要准备:

状态码永久/临时方法是否可能改变常见场景
301永久其他方法 → GET域名迁移,旧页面废弃
302临时其他方法 → GET登录跳转,临时维护页
307临时方法保持不变临时 API 转发,确保 POST 不丢
308永久方法保持不变API/HTTPS 永久迁移
或者他又问:“为什么有 307/308,还要有 302/301?”

你可以回答:

因为早期 HTTP/1.0 的 301/302 实现上存在浏览器把 POST 改为 GET 的“约定俗成”行为,后来 HTTP/1.1 标准才引入 307/308,严格规定方法不变,保证安全性。


2. DNS 解析

  • 浏览器缓存
  • 系统缓存
  • 本地 hosts 文件
  • DNS 服务器递归查询

👉 延展:

  • DNS 解析耗时往往被低估,但它是首屏性能的关键点之一。

  • 优化手段

    • DNS Prefetch(提前解析域名)
    • CDN(就近访问,减少 RTT)

3. 建立 TCP 连接(+ TLS 握手)

  • TCP 三次握手(SYN → SYN+ACK → ACK)

  • 如果是 HTTPS,还需要 TLS 握手:

    • 证书验证(公钥/私钥交换)
    • 对称加密密钥协商

👉 延展:

  • TLS 握手增加了 1~2 个 RTT,所以 HTTP/2 + TLS Session Resume 可以显著优化连接建立速度。
  • 如果面试官问 “为什么 HTTPS 这么重要?” :可以回答“保证了三要素:机密性、完整性、身份认证”。

HTTPS 加密全过程,要有一个机构帮助你加密公钥,主要防止中间人公鸡:

image.png


4. 浏览器发送 HTTP 请求

请求报文包括:

  • 请求行:GET /index.html HTTP/1.1
  • 请求头:Host、User-Agent、Cookie、Accept-Encoding...
  • 请求体:POST/PUT 时才有

👉 延展:

  • 可以提到 Cookie、Session、Token、JWT 的鉴权机制。
  • 可以提到 缓存策略(强缓存 vs 协商缓存)。

5. 服务器处理请求

  • CDN 静态资源 → 就近返回
  • 动态请求 → 进入应用服务器(Node.js、Java、Go 等)
  • 查询数据库 → 生成 HTML → 返回响应

👉 延展:

  • 面试官可能会追问: “为什么要用 CDN?”

    • 答:减少跨地域延迟,提升缓存命中率,降低源站压力。

6. 浏览器接收响应并解析

浏览器拿到 HTML 响应后,开始一边解析一边渲染:

  1. 构建 DOM 树:解析 HTML 标签。
  2. 构建 CSSOM:解析 CSS 样式。
  3. 合成渲染树:DOM + CSSOM。
  4. 遇到 JS 文件:会阻塞解析,除非加了 asyncdefer

👉 延展:

  • 可以提到 Critical Rendering Path(关键渲染路径)
  • 可以提到 首屏优化:减少阻塞脚本、内联关键 CSS、使用骨架屏。

7. 渲染阶段

  • 布局(Layout) :计算元素大小和位置。
  • 分层(Layering) :比如有 position: fixedtransform 的元素会单独成层。
  • 绘制(Paint) :把每个层绘制成位图。
  • 合成(Composite) :GPU 合成多个图层,显示在屏幕上。

👉 延展:

  • Reflow vs Repaint:布局变化会触发回流(代价更大),单纯颜色变化只会重绘。
  • 优化手段:减少不必要的回流,使用 will-change 触发 GPU 加速。

8. 用户看到页面

这时候页面已经可见,但并不是“结束”:

  • 图片可能还在懒加载
  • JS 可能还在请求接口更新内容
  • Service Worker 可能在做缓存

👉 延展:

  • 可以提到 懒加载、预加载、预渲染 等优化策略。

全流程总结图(脑海里要能画出来)

输入 URL 
 → DNS 解析 
 → TCP/TLS 握手 
 → 发送 HTTP 请求 
 → 服务器处理返回响应 
 → 浏览器解析(DOM + CSSOM + JS) 
 → 渲染(Layout、Paint、Composite) 
 → 用户看到页面

面试发挥技巧

以我的理解,面试的加分点不是答对,而是 “答到你熟悉的领域”
比如:

  • 如果你熟悉网络优化,可以延展到 DNS Prefetch、CDN、Http/2。
  • 如果你熟悉安全,可以延展到 HTTPS、TLS 握手、HSTS、CSRF。
  • 如果你熟悉前端性能,可以延展到关键渲染路径、首屏优化、懒加载。

面试官真正想看的是:你有没有理解背后的原理,而不是只会背流程。


结语

“从 URL 输入到页面展示”是一道能看出深度的题。

  • 表面是流程题
  • 实际是考察你对网络、浏览器、安全、性能的综合理解

我觉得最好的答法是:先讲清楚大流程,然后根据自己擅长的方向往下挖。
这样既显得全面,又能展示亮点。


总结

如果你在面试时只停留在“死记硬背的八股”,可能得到的就是今天的面试就到这吧,或是我感觉你像背出来的等尴尬场景。多从原理、优化、场景、历史入手,可能能打出几倍效果,而且,时间拉长了,面试官问的就少了,遇到你不会的题目也就少了。

以上回答皆是我个人观点,如有不对,还请雅正,谢谢各位大佬的观看。