一、TCP/IP 五层模型(字节跳动 / 腾讯高频题)
面试真题 1:TCP/IP 五层模型与 OSI 七层模型的区别是什么?各层的核心协议有哪些?
常见错误:混淆五层模型与七层模型的层次对应,遗漏关键协议(如网络层的 ARP/ICMP)
高分答案:
层次 | TCP/IP 五层 | OSI 七层对应 | 核心功能 | 典型协议 |
---|---|---|---|---|
应用层 | 应用层 | 应用层 + 表示层 + 会话层 | 为应用程序提供接口(如数据格式转换、加密、会话管理) | HTTP/HTTPS、FTP、SMTP、DNS、WebSocket、gRPC |
传输层 | 传输层 | 传输层 | 端到端可靠 / 不可靠通信,分割 / 重组数据 | TCP(可靠连接)、UDP(无连接) |
网络层 | 网络层 | 网络层 | 跨网络路由与寻址,处理数据包分片 / 重组 | IP、ARP(地址解析)、ICMP(错误报告)、IGMP(组播管理) |
数据链路层 | 数据链路层 | 数据链路层 | 相邻节点间帧传输,错误检测与介质访问控制(MAC 地址管理) | Ethernet(以太网)、PPP(拨号)、802.11(Wi-Fi)、VLAN、交换机转发 |
物理层 | 物理层 | 物理层 | 二进制比特流传输,定义物理介质(电缆 / 光纤)和接口标准(RJ45/USB) | RJ45、光纤、Wi-Fi 信号、集线器、中继器 |
大厂追问:
- “ARP 协议为什么属于网络层?”
答:ARP(地址解析协议)用于将 IP 地址映射到 MAC 地址,是网络层(IP)与数据链路层(MAC)的桥梁,需通过网络层封装成 IP 数据包传输。 - “DNS 工作在哪个层次?”
答:DNS(域名系统)属于应用层,基于 UDP 53 端口(查询)和 TCP 53 端口(区域传输),用于域名到 IP 地址的解析。
二、HTTP vs HTTPS(阿里 / 美团必问题)
面试真题 2:HTTPS 如何保证数据安全?SSL/TLS 握手过程是怎样的?
常见错误:仅回答 “加密传输”,未详细描述 TLS 握手步骤及加密算法组合
高分答案(附 TLS 1.3 握手流程图):
HTTPS 安全三要素:
- 加密传输:通过 TLS/SSL 对数据加密(对称加密 AES/DES + 非对称加密 RSA/ECC),防止中间人窃听
- 身份验证:客户端验证服务器证书(CA 签名),确保连接到合法服务器
- 完整性校验:通过 HMAC 或 SHA 哈希算法,检测数据是否被篡改
TLS 握手过程(以 TLS 1.2 为例):
客户端 → 服务器:ClientHello(随机数、支持的加密套件) 服务器 → 客户端:ServerHello(选择的加密套件)+ 证书(公钥)+ ServerKeyExchange(可选)+ ServerHelloDone 客户端 → 服务器:客户端证书(可选)+ ClientKeyExchange(生成预主密钥,用服务器公钥加密)+ ChangeCipherSpec(切换加密)+ 握手数据加密 服务器 → 客户端:ChangeCipherSpec(切换加密)+ 握手数据加密
关键步骤:
- 服务器发送的证书包含公钥,客户端通过 CA 根证书验证其合法性
- 客户端生成对称加密密钥(会话密钥),用服务器公钥加密后传输(非对称加密仅用于交换会话密钥)
性能影响与优化:
- 握手延迟:增加 1-RTT(TLS 1.3)~2-RTT(TLS 1.2),可通过 TLS 会话重用(Session ID/Session Ticket)减少延迟
- 计算开销:加密解密消耗 CPU,移动端建议使用 ECDHE(椭圆曲线)替代 RSA,减少计算量
大厂实战:
某电商 APP 启用 HTTPS 后,页面加载延迟增加 80ms,通过以下优化降低影响:
- 启用 TLS 1.3(握手 RTT 从 2→1)
- 优化证书链(减少证书层级,使用 OCSP Stapling)
- 压缩证书大小(从 1.2KB→800B)
三、TCP 三次握手与四次挥手(百度 / 华为高频坑题)
面试真题 3:为什么 TCP 建立连接需要三次握手?两次握手有什么风险?
常见错误:回答 “确保双方可达”,未提及 SYN 洪泛攻击和半连接风险
高分答案:
三次握手核心目的:
- 同步序列号:客户端(C)和服务器(S)各自生成初始序列号(ISN),确保数据按序传输
- 避免历史连接:防止旧连接的重复 SYN 报文导致错误连接(如网络延迟的旧 SYN 到达服务器)
- 双向可达确认:
- C→S:SYN=1,Seq=C_ISN(客户端请求连接)
- S→C:SYN=1,Seq=S_ISN,ACK=C_ISN+1(服务器确认并请求连接)
- C→S:ACK=S_ISN+1(客户端确认服务器的连接请求)
两次握手的风险(假设省略第三次 ACK):
- 服务器收到 SYN 后进入
SYN_RCVD
状态,若客户端未发送最终 ACK,服务器会重试(默认 5 次,间隔指数增长) - 易受SYN 洪泛攻击:攻击者伪造大量 SYN 报文,耗尽服务器的半连接队列(
tcp_syncookies
机制可缓解)
- 服务器收到 SYN 后进入
四次挥手为什么需要 TIME_WAIT 状态?
- 确保最后一个 ACK 到达服务器:若服务器未收到 ACK,会重发 FIN,客户端需在 TIME_WAIT 状态等待 2MSL(最大段生命周期)
- 避免旧连接数据干扰新连接:同一 IP + 端口的新连接可能收到旧连接的延迟数据,TIME_WAIT 确保旧数据已过期
大厂追问:
- “TIME_WAIT 状态过多会导致什么问题?如何优化?”
答:导致端口资源占用(每个 TIME_WAIT 连接占用一个端口,默认持续 2MSL≈4 分钟)。优化方法:- 服务器端设置
SO_REUSEADDR
选项,允许重用处于 TIME_WAIT 的端口 - 缩短 MSL 时间(需谨慎,可能导致旧数据被新连接接收)
- 服务器端设置
四、HTTP 请求响应结构(Google / 字节深挖题)
面试真题 4:HTTP 请求头中常见的 Cache-Control 字段有哪些值?如何实现协商缓存?
常见错误:混淆强制缓存与协商缓存,未正确解释 ETag/Last-Modified 的使用场景
高分答案:
HTTP 请求 / 响应核心字段:
- 请求头关键字段:
Cache-Control
:控制缓存策略(如max-age=60
强制缓存 60 秒,no-cache
需验证缓存有效性)If-None-Match
:携带 ETag 值,用于协商缓存验证(对应响应头ETag
)If-Modified-Since
:携带 Last-Modified 时间,对应响应头Last-Modified
- 响应头关键字段:
Content-Encoding
:数据压缩格式(gzip/brotli),客户端需用Accept-Encoding
声明支持格式Set-Cookie
:服务器向客户端写入 Cookie,客户端后续请求携带Cookie
头Connection
:keep-alive
启用长连接(HTTP/1.1 默认),减少 TCP 握手开销
- 请求头关键字段:
协商缓存实现流程:
客户端请求 → 检查本地缓存是否有ETag/Last-Modified ↓ 有 → 发送请求头`If-None-Match: "etag值"` 和 `If-Modified-Since: 时间` ↓ 服务器验证 → 若内容未变,返回304 Not Modified(无响应体),客户端使用本地缓存 ↓ 若内容变更,返回200 OK + 新数据
ETag vs Last-Modified:
- ETag(文件内容指纹)更精确,可检测字节级变更
- Last-Modified(文件修改时间)存在秒级精度限制,且无法检测内容不变但修改时间变化的情况
HTTP/2 新特性(大厂必问)
- 多路复用:一个 TCP 连接处理多个请求,解决 HTTP/1.1 的队头阻塞(Head-of-Line Blocking)
- 头部压缩:使用 HPACK 算法压缩请求 / 响应头,减少传输数据量(典型头部大小从 800B→100B)
- 服务器推送:服务器主动推送资源(如 HTML 引用的 CSS/JS),减少客户端二次请求
五、Android 网络优化(美团 / 滴滴实战题)
面试真题 5:如何优化 OkHttp 的网络请求性能?请对比 HTTP/1.1 与 HTTP/2 的实际效果
常见错误:仅回答 “使用连接池”,未涉及连接池参数配置及 HTTP/2 的具体优化点
高分答案:
OkHttp 核心优化策略:
- 连接池配置:
OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES)) // 5个空闲连接,存活5分钟 .build();
- 连接池默认保持 5 个空闲连接,适用于高频短连接场景(如接口调用)
- 数据压缩:
Interceptor compressionInterceptor = chain -> { Request request = chain.request(); if (request.body() != null && !request.header("Content-Encoding").equals("gzip")) { Request compressedRequest = request.newBuilder() .header("Accept-Encoding", "gzip") .build(); Response response = chain.proceed(compressedRequest); if (response.header("Content-Encoding").equals("gzip")) { // 解压缩响应体 } return response; } return chain.proceed(request); };
- 请求优先级:通过 OkHttp 的
Dispatcher
控制线程池优先级,确保关键请求(如用户登录)优先执行
- 连接池配置:
HTTP/2 vs HTTP/1.1 性能对比(某社交 APP 实测):
指标 HTTP/1.1 HTTP/2 优化效果 页面加载时间 1.2s 0.8s ↓33% 网络请求次数 23 次 8 次 ↓65% 流量消耗 120KB 80KB ↓33% TCP 连接数 5 个 1 个 ↓80% 实战避坑:
- HTTPS 握手优化:启用 TLS 会话重用(
sessionIdContext
),减少重复证书验证 - 大文件分片传输:超过 1MB 的数据使用分块编码(Chunked Transfer Encoding),避免
TransactionTooLargeException
- 流量监控:集成
NetworkMonitorInterceptor
记录每个请求的耗时、流量、错误码,定位慢请求
- HTTPS 握手优化:启用 TLS 会话重用(