跳到主内容
17 分钟阅读

计算机网络

从分层模型、TCP 与 HTTP,到缓存、DNS 和页面加载,串起前端面试中常见的计算机网络问题。

网络题最怕背成一组互不相干的名词。面试官从状态码问到缓存,再从缓存追到 CDN、DNS 和 TCP,本质上都在检查同一件事:一次请求究竟经过了哪些层,每一层解决什么问题。

OSI 与 TCP/IP 分层模型

分层不是为了画图,而是为了隔离变化。应用层不用关心数据怎样变成电信号,路由器也不用理解 JSON。实际工程更常用 TCP/IP 模型,OSI 七层则适合帮助定位问题。

OSI 层TCP/IP 视角常见协议或设备主要职责
应用层、表示层、会话层应用层HTTP、DNS、WebSocket、TLS应用语义、数据表示、会话与加密
传输层传输层TCP、UDP、QUIC端到端传输、可靠性、拥塞控制
网络层网际层IP、ICMP、路由器寻址与跨网络路由
数据链路层、物理层网络接入层Ethernet、Wi-Fi、交换机局域网传输、帧与物理信号

“某协议属于哪一层”并不总有唯一答案。例如 TLS 通常放在应用层与传输层之间,QUIC 则基于 UDP,在用户态实现了可靠传输、拥塞控制和 TLS 1.3。重点是能说明它依赖谁、向上提供什么能力。

TCP 与 UDP

TCP 面向连接,提供有序、可靠的字节流;UDP 面向数据报,只尽力交付,不保证到达、顺序或去重。

维度TCPUDP
数据边界字节流,没有消息边界每个数据报保留边界
可靠性序号、确认、重传、流量控制协议本身不提供
顺序按序交付;丢包可能阻塞后续数据到达顺序不确定
连接成本建连并维护连接状态无连接,首包成本低
常见场景HTTP/1.1、HTTP/2、SSHDNS、实时音视频、QUIC

UDP 并不等于“不可靠的业务”。应用可以在 UDP 之上按需要实现确认和重传,QUIC 就是典型例子。实时通话则可能宁愿丢掉一个过期音频包,也不愿等待重传。

三次握手

假设客户端初始序号为 x,服务端初始序号为 y

  1. 客户端发送 SYN, seq=x,进入 SYN-SENT
  2. 服务端回复 SYN + ACK, seq=y, ack=x+1,进入 SYN-RECEIVED
  3. 客户端发送 ACK, ack=y+1,双方进入 ESTABLISHED

第三次不能随意省掉。服务端收到最后一个 ACK 后,才确认自己的 SYN 已被客户端接收,也能排除失效的旧连接请求直接占用连接资源。握手还会协商 MSS、窗口扩大、SACK 等 TCP 选项,不只是“确认双方能收发”。

四次挥手

TCP 是全双工连接,两个方向需要分别关闭:

  1. 主动关闭方发送 FIN,表示自己不再发送数据。
  2. 被动关闭方回复 ACK;此时仍可以发送剩余数据。
  3. 被动关闭方发送自己的 FIN
  4. 主动关闭方回复 ACK,并通常进入 TIME_WAIT

“四次”是便于理解的典型过程。若被动方没有剩余数据,ACK 与 FIN 可以合并,所以抓包未必总能看到四个独立报文。

TIME_WAIT 通常由主动关闭方承担,主要作用是让旧报文在网络中消失,并在最后一个 ACK 丢失时还能重发。大量短连接会造成较多 TIME_WAIT,优先考虑连接复用、合理的 keep-alive 和服务架构,而不是直接粗暴修改内核参数。

TCP 怎样保证可靠性

  • 序列号与确认号识别丢失、重复和乱序数据。
  • 超时重传和快速重传负责补包。
  • 接收窗口进行流量控制,避免发送端压垮接收端。
  • 拥塞窗口与慢启动、拥塞避免等算法保护网络。
  • 校验和发现传输中的位错误。

流量控制关注“接收方还能接多少”,拥塞控制关注“网络还能承受多少”,两者不要混为一谈。

HTTP 与 HTTPS

HTTP 是应用层语义:请求方法、资源标识、头字段、状态码和消息内容。HTTPS 则是 HTTP 运行在 TLS 保护的通道之上,提供:

  • 机密性:中间节点难以读到明文内容。
  • 完整性:传输内容被篡改可以被发现。
  • 身份认证:客户端通过证书链与主机名校验服务端身份。

HTTPS 不保证网站业务可信,也不隐藏全部元数据。对手仍可能看到 IP、流量大小与时序;域名能否隐藏还与 DNS、TLS 版本及 ECH 等部署情况有关。

TLS 握手在做什么

以 TLS 1.3 为例,客户端发送支持的版本、密码套件和密钥参数;服务端选择参数、返回证书并证明持有对应私钥。双方通过密钥交换得到共享秘密,再派生会话密钥。之后 HTTP 内容使用对称加密传输,因为它比非对称加密更适合大量数据。

证书本身不是“用私钥加密整个网页”。非对称密码主要用于身份认证与密钥协商,正文通常由协商出的对称密钥保护。

常见的状态码

状态码表达服务器对当前请求的处理结果。客户端还要结合方法、响应头和正文判断下一步,不能只看三位数字。

1xx:信息响应

  • 100 Continue:服务端允许客户端继续发送请求体,常与 Expect: 100-continue 配合。
  • 101 Switching Protocols:同意切换协议,传统 WebSocket 握手会用到。
  • 103 Early Hints:最终响应前给出提示,客户端可提前预连接或加载资源;是否使用取决于链路支持。

2xx:成功

  • 200 OK:请求成功,语义随方法变化。
  • 201 Created:已创建资源,通常通过 Location 指出新资源地址。
  • 204 No Content:成功但没有响应内容,响应不能包含消息内容。
  • 206 Partial Content:成功返回范围请求的一部分,下载续传和媒体播放常见。

3xx:重定向与缓存

  • 301 Moved Permanently:资源永久迁移。历史客户端可能把 POST 改成 GET;若必须保留方法,使用 308 更明确。
  • 302 Found:临时重定向,也存在把 POST 改成 GET 的兼容行为。
  • 303 See Other:明确让客户端使用 GET 获取另一个资源,表单提交后跳转常用。
  • 304 Not Modified:条件请求命中,客户端继续使用本地缓存;它不是普通重定向,也不携带新的完整响应体。
  • 307 Temporary Redirect:临时重定向并保留请求方法和请求体。
  • 308 Permanent Redirect:永久重定向并保留请求方法和请求体。

4xx:客户端侧请求问题

  • 400 Bad Request:请求语法或参数无法处理,适合一般的输入错误。
  • 401 Unauthorized:名称容易误导,实际表示“未通过身份认证”,响应通常带 WWW-Authenticate
  • 403 Forbidden:服务端理解请求,也知道来访者是谁,但拒绝授权;重新登录不一定有用。
  • 404 Not Found:资源不存在,服务端也可出于安全考虑用它隐藏资源是否存在。
  • 405 Method Not Allowed:资源存在,但不支持当前方法,应通过 Allow 告知支持的方法。
  • 409 Conflict:请求与资源当前状态冲突,例如版本冲突或重复创建。
  • 410 Gone:资源明确永久消失,比 404 信息更强。
  • 413 Content Too Large:请求内容超过服务端限制。
  • 415 Unsupported Media Type:请求体媒体类型不受支持,例如接口只接受 JSON。
  • 422 Unprocessable Content:语法和媒体类型正确,但业务语义校验失败。
  • 429 Too Many Requests:触发限流,可结合 Retry-After 告知重试时间。

5xx:服务端或上游问题

  • 500 Internal Server Error:服务端未能处理的通用错误,不应把内部堆栈直接返回给用户。
  • 501 Not Implemented:服务端不支持完成请求所需的功能,和暂时故障不同。
  • 502 Bad Gateway:网关或代理从上游拿到了无效响应。
  • 503 Service Unavailable:过载或维护导致暂时不可用,可带 Retry-After
  • 504 Gateway Timeout:网关等待上游响应超时。

502 是“上游响应无效”,504 是“等待上游超时”,503 更偏向当前服务明确不可用。线上排查仍要结合代理日志、链路追踪和超时配置。

HTTP 缓存

先判断响应是否仍然新鲜;不新鲜时,再决定能否向服务端验证。把所有缓存都叫作“强缓存”和“协商缓存”便于入门,但 RFC 使用的是 freshness(新鲜度)与 validation(验证)。

新鲜度

常见响应头:

Cache-Control: public, max-age=60, stale-while-revalidate=30
  • max-age=60:响应生成后 60 秒内可视为新鲜。
  • s-maxage:用于共享缓存,并覆盖共享缓存中的 max-age
  • public:允许共享缓存存储;private:只允许私有缓存存储。
  • no-store:不要存储响应。
  • no-cache:可以存储,但复用前必须验证。它不是“不缓存”。
  • immutable:新鲜期间内容不会改变,适合带内容哈希的静态资源。

Expires 也能表示过期时间,但依赖绝对时间;现代项目通常优先使用 Cache-Control。带哈希的 JS/CSS 可以设置很长的 max-age,HTML 则应采用较短缓存或每次验证,避免入口长期指向旧资源。

条件请求

缓存过期后,客户端可以带验证器:

If-None-Match: "asset-v3"
If-Modified-Since: Fri, 07 Aug 2026 08:00:00 GMT

服务端确认内容未变时返回 304 Not ModifiedETag 是资源的实体标签,精度和语义通常比基于秒级时间的 Last-Modified 更可靠。强 ETag 要求表示逐字节相同,弱 ETag(如 W/"v3")只表示语义等价,不能用于所有需要字节级一致的场景。

Vary 决定缓存键还受哪些请求头影响。例如 Vary: Accept-Encoding 让 gzip 和 br 响应分开存储。随意写 Vary: * 或把高基数字段放进去,会显著降低命中率。

Cookie、Session 与 Token

这三个词不在同一维度:

  • Cookie 是浏览器保存并按规则随请求发送的小段数据,是传输和存储机制。
  • Session 通常指服务端保存的会话状态,浏览器 Cookie 里只放随机会话标识。
  • Token 是凭证格式或字符串,可以放在 Cookie,也可以由应用放进 Authorization 请求头。

典型 Session 流程是:登录成功后服务端创建会话,返回 Set-Cookie: sid=...;浏览器后续自动携带 sid;服务端查会话存储。JWT 则可以把声明和签名放进 token,但“可验证”不等于“已加密”,载荷默认可以被读取,也仍要考虑撤销、过期、密钥轮换与权限变化。

常用 Cookie 属性:

  • Secure:只通过安全连接发送。
  • HttpOnly:禁止 JavaScript 读取,降低凭证被 XSS 直接窃取的风险,但不能消除 XSS。
  • SameSite:限制跨站请求携带 Cookie,是缓解 CSRF 的重要手段。
  • DomainPath:限定发送范围,不是可靠的权限边界。
  • Max-AgeExpires:控制持久时间;都没有时通常是会话 Cookie。

把 token 放进 localStorage 可以避免浏览器自动附带导致的传统 CSRF 路径,但一旦发生 XSS,脚本可直接读取。放在 HttpOnly Cookie 能避免脚本读取,却要认真配置 SameSite、来源校验或 CSRF token。选择取决于威胁模型,不存在“一律最安全”的存储位置。

DNS 解析

DNS 把域名映射为地址或其他记录。一次常见解析过程是:

  1. 浏览器、操作系统和本地网络缓存依次查找。
  2. Stub resolver 把问题交给递归解析器,通常由运营商、企业或公共 DNS 提供。
  3. 递归解析器若无缓存,会从根服务器得到顶级域指引,再询问权威服务器。
  4. 权威服务器返回 A、AAAA、CNAME 等记录,结果按 TTL 缓存。

递归解析器替客户端跑完整流程;权威服务器负责某个 DNS 区域的最终数据。CNAME 是别名,不是 HTTP 重定向,浏览器地址栏不会因此变化。

传统 DNS 常用 UDP 53 端口,响应过大、需要可靠传输或区域传送时也会使用 TCP。DoH 和 DoT 保护的是客户端到解析器之间的 DNS 通信,并不会让权威解析链路自动全部加密。

从输入 URL 到页面可交互

可以按依赖顺序回答,而不是一口气背二十步:

  1. 浏览器解析 URL,判断协议、主机、端口和路径,并检查 HSTS、缓存、Service Worker 等本地规则。
  2. 解析 DNS,得到可连接的地址。
  3. 建立传输连接:TCP 上通常还要进行 TLS;HTTP/3 则在 QUIC 握手中集成 TLS。
  4. 浏览器发送 HTTP 请求,Cookie 是否携带取决于域、路径、SameSite、Secure 等规则。
  5. 请求可能经过 CDN、负载均衡和反向代理,再到应用服务与数据存储。
  6. 浏览器处理状态码、响应头和响应体;HTML 可流式解析,遇到外部资源会继续发起请求。
  7. 构建 DOM 与 CSSOM,生成渲染树,进行布局、绘制和合成。
  8. JavaScript 注册事件、更新状态或发起更多请求,页面逐步达到可交互状态。

真实浏览器会并行、缓存、预加载和推测执行,以上是因果链,不是每一步都严格串行。若面试官继续追问性能,可从 DNS、连接、TTFB、资源优先级、主线程长任务和渲染稳定性分别定位,而不是笼统说“加 CDN”。

WebSocket

WebSocket 为浏览器与服务端提供持久、全双工、面向消息的连接。HTTP/1.1 场景通常先发起 Upgrade 握手,服务端返回 101 后切换协议;HTTP/2 和后续版本存在扩展连接方式,因此“永远先升级成 101”并不严谨。

连接建立后,数据使用 WebSocket 帧传输,不再为每条消息携带完整 HTTP 头。它适合聊天、协同编辑和实时行情,但应用仍要自行处理:

  • 身份认证与权限更新;浏览器 WebSocket API 不能像普通 fetch 那样随意设置请求头。
  • 心跳、空闲断开与代理超时。
  • 断线重连、指数退避、消息去重和顺序。
  • 背压。发送速度长期大于网络和接收端处理速度时,内存会增长。
  • 多实例广播与会话迁移。

若服务端只需单向推送文本事件,SSE 基于 HTTP、自动重连且链路更简单;若客户端只是偶尔查询,轮询可能已经足够。技术选择应由通信方向、频率和基础设施决定。

HTTP/1.1、HTTP/2 与 HTTP/3

HTTP/1.1

默认持久连接,可复用 TCP 连接,但同一连接上的响应按顺序返回。浏览器通常并行建立若干连接缓解队头阻塞,代价是更多握手和拥塞状态。

HTTP/2

把 HTTP 消息拆成二进制帧,在单个 TCP 连接上多路复用,并用 HPACK 压缩头部。不同流可以交错传输,解决了 HTTP/1.1 应用层排队问题;但底层 TCP 丢包时,后续字节仍需等待重传,所有流都可能受影响。

HTTP/3

HTTP/3 运行在 QUIC 之上。QUIC 基于 UDP,把加密、可靠传输和多路复用集成到用户态;一个流丢包通常不会阻塞其他流的数据交付。它还改善了连接建立与网络切换场景,但并不意味着任何网络下都必然更快,UDP 可达性、服务器实现和拥塞情况都会影响结果。

三代 HTTP 的核心语义大体延续,主要变化在传输和编码。GET、状态码、缓存字段不会因为换成 HTTP/3 就失效。

典型追问

GET 和 POST 的本质区别是什么?

HTTP 语义上,GET 用于获取资源,应当安全且幂等;POST 让资源按自身语义处理请求内容,通常不保证幂等。URL 长度限制主要来自浏览器、服务器和中间件实现,不是 HTTP 给 GET 规定了一个统一的 2 KB 上限。请求是否加密只取决于是否使用 TLS,与 GET/POST 无关。

幂等是什么意思?

同一个请求执行一次或多次,对服务端预期状态的影响相同。GET、PUT、DELETE 在规范语义上是幂等的,但响应内容可以不同;POST 默认不幂等。支付接口若要安全重试,常通过幂等键在业务层实现去重。

为什么 HTTP/2 不再推荐雪碧图和域名分片?

多路复用降低了大量小请求的连接成本。域名分片反而建立更多连接、重复 TLS 与拥塞控制;雪碧图也会增加无关下载和缓存失效范围。不过小图是否内联、资源如何打包,仍应由实际测量决定。

连接超时、读取超时和 504 有什么区别?

连接超时发生在与目标建立连接阶段;读取超时是连接已建立但迟迟收不到期望数据;504 是网关向客户端报告等待上游超时。客户端自身超时可能先发生,此时甚至看不到服务端返回的 504

CDN 缓存和浏览器缓存有什么不同?

浏览器缓存是单用户私有缓存;CDN 是靠近用户的共享缓存。两者都遵循 HTTP 缓存语义,但共享缓存要谨慎处理鉴权响应、Cookie、privates-maxageVary,避免把个性化内容返回给其他用户。

参考资料

计算机网络

https://setobox.me/blog/2026/computer-network-interview
作者
Setobox(姬顶盒)
发布于
许可协议
CC BY-NC-SA 4.0