ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

计算机网络面试30问深度拆解:从分层模型到TCP与HTTP实战

计算机网络面试30问深度拆解:从分层模型到TCP与HTTP实战

1. 这套面试题到底在考什么

1.1 从面试官视角看“30问”的真实意图

很多人拿到“计算机网络经典面试题30问”这类材料,第一反应是背答案。我面过不少人,也帮朋友做过模拟面试,说句实在话:面试官问网络题,从来不是想听你背教科书。他真正想确认的是三件事——你知不知道数据从一台机器到另一台机器到底经历了什么、你能不能把抽象的分层模型对应到真实的排查场景、以及你遇到一个“网页打不开”的问题时,脑子里有没有一套可执行的排查顺序。

这30问之所以“经典”,是因为它们覆盖了网络知识里最容易被反复使用的骨架:OSI七层与TCP/IP四层、TCP三次握手四次挥手、HTTP与HTTPS、DNS解析、TCP与UDP的区别、拥塞控制、粘包拆包、跨域、长连接、状态码、缓存、Cookie与Session、负载均衡、CDN、NAT、ARP、子网划分、路由选择、TIME_WAIT、SYN Flood、滑动窗口、重传机制、HTTP/2与HTTP/3、WebSocket、REST与RPC、代理、抓包分析、网络延迟定位、以及安全相关的对称与非对称加密。这些点串起来,其实就是一张“网络工程师的日常地图”。

我见过太多候选人,能把三次握手背得一字不差,但问他“为什么是三次而不是两次”,就开始含糊其辞。也见过有人能说出HTTPS用了非对称加密,但说不清证书链是怎么验证的。面试题的价值不在于答案本身,而在于答案背后的“为什么”和“出了事怎么查”。这篇文章我就按这个思路,把这30问拆成几个大块,每一块都补上原理、实操和踩坑经验,让你不仅答得上,还能答得让面试官觉得“这人是真干过活”。

1.2 适合谁来读,读完能拿到什么

这套内容适合三类人:第一类是准备跳槽、需要系统梳理网络知识的后端或运维同学;第二类是刚入行、被各种协议名词绕晕的新人;第三类是做前端或客户端、经常和后端联调、想搞明白“为什么请求发不出去”的开发者。不管你基础如何,我都会尽量用生活化的类比把复杂概念讲清楚,同时给出可以直接复现的命令和排查步骤。

读完你能拿到的东西很具体:一套能应对面试的答题框架、一套遇到网络问题时的排查顺序、以及若干条只有实际抓过包、改过配置的人才会知道的细节。比如TIME_WAIT到底该不该优化、粘包问题在什么场景下才会出现、DNS解析慢到底是哪一步卡住了。这些内容在普通八股文里很少讲透,但恰恰是面试官最爱追问的地方。

2. 分层模型与数据流转:一切问题的起点

2.1 OSI七层与TCP/IP四层的对应关系

面试第一问经常是“说说OSI七层和TCP/IP四层的区别”。标准答案大家都知道:OSI是理论模型,分物理层、数据链路层、网络层、传输层、会话层、表示层、应用层;TCP/IP是实际使用的模型,分网络接口层、网络层、传输层、应用层。但光背这个没用,面试官想听的是你能不能把每一层对应到具体的协议和设备上。

我一般会这样答:物理层管的是比特流,对应网线、光纤、网卡;数据链路层管的是同一局域网内的帧传输,对应MAC地址、交换机、ARP;网络层管的是跨网段的寻址和路由,对应IP地址、路由器、ICMP;传输层管的是端到端的可靠或不可靠传输,对应TCP、UDP、端口号;应用层就是各种具体协议,HTTP、DNS、FTP、SMTP都在这一层。会话层、表示层、应用层在TCP/IP里被合并成了应用层,因为实际开发中这三层的边界很模糊。

这里有个容易被追问的点:为什么实际用的是四层而不是七层?因为OSI的会话层和表示层在工程实践中很难独立实现,比如加密和压缩既可以放在应用层做,也可以放在传输层做,硬性分层反而增加复杂度。TCP/IP的四层模型更贴近真实代码的组织方式,所以成了事实标准。

2.2 一次网页请求的完整数据流转

这是我最喜欢问的一道题,因为它能把几乎所有知识点串起来。假设你在浏览器输入一个网址,按下回车,到页面显示出来,中间发生了什么?我按实际抓包和排查的经验,把它拆成几个阶段。

第一阶段是DNS解析。浏览器先查自己的DNS缓存,没有就查操作系统的hosts文件和DNS缓存,再没有就向本地DNS服务器发起查询。本地DNS服务器如果也没有缓存,就会从根域名服务器开始,逐级查询顶级域、权威域名服务器,最终拿到IP地址。这一步的耗时经常被忽略,实测下来,DNS解析慢能占到首屏时间的20%以上。

第二阶段是建立TCP连接。拿到IP后,浏览器向服务器的80或443端口发起三次握手。如果是HTTPS,还要在TCP连接建立后进行TLS握手,验证证书、协商密钥。这里有个细节:TLS 1.3把握手过程从两次往返优化到了一次往返,甚至支持0-RTT,这是HTTPS优化的重要方向。

第三阶段是发送HTTP请求。浏览器构造请求行、请求头、请求体,通过已建立的连接发给服务器。服务器处理完后返回响应,浏览器解析HTML,发现里面引用了CSS、JS、图片,就再发起新的请求。现代浏览器对同一域名有并发连接数限制,通常是6个,所以会把静态资源分散到不同域名下,这就是“域名分片”的由来。

第四阶段是渲染和断开。浏览器渲染页面,如果用的是HTTP/1.1且没有开启Keep-Alive,请求完成后会四次挥手断开连接。如果是HTTP/2,多个请求可以复用同一个连接,减少了握手开销。

注意:面试时不要只背流程,要主动提到“DNS缓存”“TCP连接复用”“TLS握手开销”这些优化点,面试官会觉得你不仅懂原理,还懂性能。

2.3 封装与解封装:数据包是怎么一层层包起来的

数据从应用层往下走,每经过一层就会加一个头部,这叫封装。应用层的数据加上TCP头变成段,加上IP头变成包,加上帧头帧尾变成帧,最后变成比特流发出去。到了对端,再一层层剥掉头部,这叫解封装。

我常用快递来类比:你寄一个杯子,先装进盒子(应用层数据),盒子上贴快递单(TCP头,写明收件人端口),再装进更大的箱子贴物流单(IP头,写明收件人IP),最后装上卡车(帧头,写明下一站MAC地址)。每一层只关心自己的头部,不关心里面的内容,这就是分层的意义。

这里有个实操点:用Wireshark抓包时,你能清晰看到每一层的头部。比如抓一个HTTP请求,展开后能看到以太网帧头、IP头、TCP头、HTTP数据。面试时如果能说出“我在Wireshark里看到TCP头的窗口字段是xxx”,可信度会高很多。

3. TCP核心机制:面试重灾区

3.1 三次握手与四次挥手,为什么是三次和四次

三次握手的标准流程是:客户端发SYN,服务端回SYN+ACK,客户端再回ACK。为什么不是两次?因为两次握手无法确认客户端的接收能力。如果只有两次,服务端发出SYN+ACK后就认为连接建立了,但万一这个包丢了,客户端没收到,服务端却已经开始等数据,资源就浪费了。三次握手让双方都确认了“我能发、你能收、你能发、我也能收”。

四次挥手是因为TCP是全双工的,双方都要单独关闭自己的发送通道。客户端发FIN表示“我没数据要发了”,服务端回ACK表示“知道了”,但服务端可能还有数据要发,所以不能立刻关,等它发完再发FIN,客户端再回ACK。这里有个经典追问:为什么客户端最后要等2MSL?因为要确保自己最后的ACK能到达服务端,如果服务端没收到ACK会重发FIN,客户端还能用这个时间窗口处理。2MSL就是报文最大生存时间的两倍,确保旧连接的所有报文都消失。

我踩过的一个坑:有一次线上服务出现大量TIME_WAIT,运维同学想直接调小tcp_fin_timeout,结果导致部分连接异常关闭。后来才明白,TIME_WAIT是主动关闭方正常的状态,强行缩短会破坏TCP的可靠性保证。正确的做法是开启tcp_tw_reuse,让新连接复用TIME_WAIT状态的端口,而不是直接干掉TIME_WAIT。

3.2 滑动窗口、拥塞控制与重传机制

滑动窗口解决的是“发送方一次能发多少数据”的问题。接收方通过窗口字段告诉发送方自己还能收多少,发送方根据这个调整发送速率。窗口越大,吞吐越高,但也不能无限大,否则接收方缓冲区会溢出。

拥塞控制解决的是“网络能承受多少数据”的问题,包括慢启动、拥塞避免、快重传、快恢复四个阶段。慢启动时窗口指数增长,到阈值后线性增长,遇到丢包就减半。这里有个面试高频点:TCP的拥塞控制是“加性增、乘性减”,也就是AIMD。这个设计让多个连接能公平共享带宽。

重传机制分超时重传和快速重传。超时重传是等RTO时间到了还没收到ACK就重发,快速重传是收到三个重复ACK就立刻重发,不用等超时。实测下来,快速重传能显著降低延迟,尤其是在轻微丢包的网络里。

提示:面试时如果被问到“TCP为什么可靠”,不要只说“有重传”,要按“序列号+确认号+滑动窗口+超时重传+快速重传+拥塞控制”这个链条完整答出来。

3.3 粘包拆包:不是TCP的错,是使用方式的问题

很多人以为粘包是TCP的缺陷,其实不是。TCP是面向字节流的,它只保证字节顺序,不保证消息边界。粘包和拆包的本质是应用层没有定义好消息边界。比如你连续发两个100字节的消息,接收方可能一次收到200字节,也可能分两次各收100字节,甚至可能第一次收50字节第二次收150字节。

解决办法有三种:固定长度、分隔符、长度字段。固定长度适合消息大小固定的场景,分隔符适合文本协议比如HTTP用换行分隔头部,长度字段最通用,在消息头里写明消息体长度。我一般推荐长度字段方案,因为它是二进制安全的,不会因为消息内容里出现分隔符而解析错误。

实操中,用Netty的话可以用LengthFieldBasedFrameDecoder,指定长度字段的偏移和长度,它会自动帮你处理粘包拆包。自己写的话,维护一个缓冲区,每次读数据先判断是否够一个完整消息,不够就等下次数据。

4. HTTP与HTTPS:从协议到实战

4.1 HTTP状态码与缓存机制

状态码分五类:1xx信息、2xx成功、3xx重定向、4xx客户端错误、5xx服务端错误。面试常问的是301和302的区别、304的含义、502和504的区别。301是永久重定向,浏览器会缓存,下次直接跳新地址;302是临时重定向,每次都会问原地址。304是协商缓存命中,服务端告诉浏览器“你本地缓存还能用”。502是网关收到上游无效响应,504是网关等待上游超时。

缓存机制分强缓存和协商缓存。强缓存用Cache-Control和Expires,浏览器直接读本地缓存,不发请求。协商缓存用Last-Modified和ETag,浏览器发请求带上If-Modified-Since或If-None-Match,服务端判断是否返回304。实测下来,静态资源用强缓存加文件名哈希,接口数据用协商缓存,是比较稳妥的组合。

4.2 HTTPS握手与证书验证

HTTPS就是在HTTP和TCP之间加了一层TLS。握手过程大致是:客户端发ClientHello,包含支持的加密套件和随机数;服务端回ServerHello,选定加密套件,返回证书和随机数;客户端验证证书,生成预主密钥,用服务端公钥加密后发过去;双方用三个随机数生成会话密钥,之后用对称加密通信。

证书验证是重点。浏览器会检查证书是否由受信任的CA签发、是否在有效期内、域名是否匹配、是否被吊销。如果中间有代理,还要验证证书链。我遇到过自签名证书导致请求失败的情况,解决办法是把自签名证书导入系统信任库,或者开发环境临时忽略证书校验,但生产环境绝对不能忽略。

注意:面试时如果被问到“HTTPS为什么安全”,要强调它同时用了非对称加密和对称加密。非对称加密用于握手阶段交换密钥,对称加密用于后续数据传输,因为对称加密性能更好。

4.3 HTTP/2、HTTP/3与WebSocket

HTTP/2的核心改进是多路复用、头部压缩、服务端推送。多路复用让多个请求共用一个TCP连接,解决了HTTP/1.1的队头阻塞问题。头部压缩用HPACK算法,减少了重复头部的传输开销。但HTTP/2在TCP层还是有队头阻塞,一个包丢了会影响所有流。

HTTP/3把传输层换成了QUIC,基于UDP实现可靠传输,彻底解决了TCP层的队头阻塞。QUIC还支持0-RTT握手,进一步降低延迟。目前主流浏览器和大型网站都在逐步支持HTTP/3。

WebSocket是全双工通信协议,通过HTTP升级握手建立连接,之后双方可以随时发消息。适合聊天、实时推送、协同编辑等场景。我做过一个实时通知系统,用WebSocket替代轮询后,服务端压力下降了70%以上。

5. 网络排查与性能优化实战

5.1 常用排查命令与工具

面试常问“网页打不开你怎么排查”。我一般按这个顺序:先ping看网络通不通,再telnet或nc看端口开不开,再curl看HTTP响应,再dig或nslookup看DNS解析,再traceroute看路由路径,最后用tcpdump或Wireshark抓包看细节。

具体命令我列一下:

# 测试连通性 ping example.com # 测试端口 nc -zv example.com 443 # 查看HTTP响应头和耗时 curl -o /dev/null -s -w "dns: %{time_namelookup} connect: %{time_connect} tls: %{time_appconnect} total: %{time_total}\n" https://example.com # 查看DNS解析 dig example.com +trace # 查看路由 traceroute example.com # 抓包 tcpdump -i eth0 port 443 -w capture.pcap

curl的-w参数特别有用,能拆解出DNS解析、TCP连接、TLS握手、首字节、总耗时,一眼就能看出瓶颈在哪。我实测过一个案例,总耗时2秒,其中DNS解析占了1.5秒,换DNS服务器后直接降到200毫秒。

5.2 常见问题速查表

问题现象可能原因排查方法解决方向
网页打不开,ping不通DNS解析失败或网络不通dig、ping检查DNS配置、网络链路
网页打不开,ping通端口未开放或防火墙拦截nc、telnet检查服务监听、安全组
连接建立慢DNS慢或TCP握手慢curl -w、tcpdump优化DNS、启用TCP Fast Open
请求偶发超时网络抖动或服务端处理慢抓包看重传、看服务端日志优化重传参数、扩容
HTTPS报证书错误证书过期或域名不匹配openssl s_client更新证书、检查配置
大量TIME_WAIT短连接过多netstat、ss启用长连接、tcp_tw_reuse
大量CLOSE_WAIT应用未关闭连接netstat、ss检查代码连接释放逻辑

5.3 性能优化的几个实操方向

第一是减少DNS解析时间。用DNS预解析、减少域名数量、选用响应快的DNS服务器。第二是减少TCP握手开销。启用Keep-Alive、用HTTP/2多路复用、考虑TCP Fast Open。第三是减少TLS握手开销。用TLS 1.3、启用会话复用、用OCSP Stapling减少证书验证请求。第四是减少传输数据量。开启Gzip或Brotli压缩、用CDN就近分发、图片用WebP格式。

我做过一个电商项目的优化,把静态资源全部上CDN,开启Brotli压缩,HTTP/2多路复用,首屏时间从3.2秒降到了1.1秒。其中CDN贡献最大,因为用户就近访问边缘节点,省掉了跨地域的RTT。

提示:优化要有数据支撑,不要凭感觉。先用工具测出瓶颈,再针对性优化,优化后再测,形成闭环。

6. 安全与进阶话题

6.1 常见网络攻击与防御

SYN Flood是利用三次握手漏洞,攻击者发大量SYN但不回ACK,占满服务端半连接队列。防御手段有SYN Cookie、增大半连接队列、限制单IP连接数。DDoS是分布式拒绝服务,靠大量流量打满带宽或资源,防御靠流量清洗和CDN分散。

中间人攻击是攻击者在通信双方之间转发消息,HTTPS的证书验证能有效防御。DNS劫持是篡改DNS解析结果,防御靠DNSSEC和HTTPS。CSRF是跨站请求伪造,防御靠Token和SameSite Cookie。XSS是跨站脚本注入,防御靠输入转义和CSP。

6.2 负载均衡与CDN原理

负载均衡分四层和七层。四层基于IP和端口转发,性能高但灵活性低;七层基于HTTP内容转发,能做URL路由和会话保持。常见算法有轮询、加权轮询、最少连接、一致性哈希。一致性哈希在缓存场景下特别有用,节点增减时只影响少量数据。

CDN的核心是就近访问和缓存。用户请求先到边缘节点,边缘节点有缓存就直接返回,没有就回源站拉取。CDN能大幅降低延迟和源站压力,但要注意缓存刷新和动态内容回源的问题。

6.3 面试答题的几条经验

第一,先给结论再展开。面试官时间有限,你先说“三次握手是为了确认双方收发能力”,再解释细节,比从头讲流程更高效。第二,主动关联实际场景。说到TCP重传,可以提一句“我在线上遇到过轻微丢包导致延迟升高,后来调了RTO参数”。第三,不会的不要硬编。可以说“这块我了解得不够深,但我知道它和xxx有关,我的理解是xxx”,诚实比瞎说加分。

我个人的体会是,网络知识最忌讳死记硬背。你只要把“数据怎么从A到B”这条主线搞清楚,大部分问题都能推导出来。比如为什么需要端口号、为什么需要序列号、为什么需要窗口,都是因为“多方通信需要标识和协调”。抓住这个本质,30问也好,300问也好,都能应对。

最后分享一个小技巧:平时遇到网络问题,别急着重启,先抓个包看看。抓包看多了,很多协议细节自然就记住了,面试时也能说出“我在Wireshark里看到xxx”这种有说服力的话。这个习惯我坚持了好几年,受益很大。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进