Java工程师面试计算机网络八股文面试题集合
1. OSI七层模型
理论标准,指导协议设计
层名 | 核心作用 | 功能 | 典型协议/设备 |
---|---|---|---|
物理层 | 传输原始比特流(0/1) | 定义物理介质特性(电压、光信号、接口形状等);控制数据传输速率、同步、信号衰减补偿 | 双绞线、光纤、WI-FI无线电波、集线器(Hub)、中继器(Repeater) |
数据链路层 | 确保同一局域网(LAN)内节点之间的可靠传输 | 成帧(封装比特为帧,添加MAC地址头尾标识);差错控制(CRC校验);流量控制(滑动窗口) | MAC地址、以太网、交换机、PPP协议 |
网络层 | 跨网络(如互联网)的端到端数据路由 | 逻辑寻址(IP地址);路由选择(路由器);分片与重组(适应不同网络MTU) | IP协议、ICMP(ping)、路由器、OSPF/BGP路由协议 |
传输层 | 确保端到端(应用程序之间)的可靠/不可靠传输 | 端寻址(端口标识应用,如HTTP=80);流量控制(TCP滑动窗口);可靠性保障(重传、确认、排序) | TCP(可靠)、UDP(不可靠)、滑动窗口协议 |
会话层 | 管理通信会话(建立、维护、终止) | 会话控制(全双工/半双工模式,如RPC);断点恢复(断点续传,如文件下载工具) | NetBIOS、RPC(远程过程调用)、PPTP(VPN) |
表示层 | 数据格式转换与安全处理 | 数据编码(ASCII/Unicode、JPEG);加密/解密(SSL/TLS);压缩/解压(GZIP) | SSL/TLS、MIME(邮件编码)、ASCII/JSON/XML |
应用层 | 为应用程序提供网络服务接口 | 定义用户可见协议(HTTP访问网页、SMTP发邮件);用户身份验证(OAuth);服务请求/响应 | HTTP、FTP、DNS、SMTP、SSH、MQTT |
2. TCP/IP四层模型
工程实践,驱动互联网发展
TCP/IP层名 | 功能描述 | 对应OSI层 |
---|---|---|
应用层 | 为应用程序提供网络服务(如HTTP、FTP、SMTP) | 会话层、表示层、应用层 |
传输层 | 端到端可靠/不可靠传输(TCP/UDP) | 传输层 |
互联网层 | 跨网络路由与逻辑寻址(IP协议、路由选择) | 网络层 |
网络接口层 | 物理介质传输与数据链路控制(以太网、WiFi、MAC地址) | 物理层、数据链路层 |
3. TCP与UDP的区别及使用场景
特性 | TCP | UDP |
---|---|---|
连接性 | 面向连接(三次握手) | 无连接 |
可靠性 | 可靠(校验和、重传、拥塞控制) | 不可靠(无重传机制) |
头部开销 | 20字节(固定首部) | 8字节(仅基础字段) |
典型应用 | HTTP/HTTPS、FTP、SMTP | DNS、视频流、实时游戏 |
4. TCP三次握手与四次挥手流程
三次握手: 可靠传输,同步双方序列号,避免旧连接干扰。
- 客户端发送
SYN
(seq=x)。 - 服务器回复
SYN+ACK
(seq=y, ack=x+1)。 - 客户端发送
ACK
(seq=x+1, ack=y+1)。
- 客户端发送
四次挥手: TCP半关闭特性,允许一方发送完数据后继续接收。
- 客户端发送
FIN
。 - 服务器回复
ACK
。 - 服务器发送
FIN
。
服务端启动重传定时器(初始超时时间通常为
RTO
,Retransmission Timeout,默认值约为 1~3 秒,具体取决于系统实现)一般远小于1MSL。如果服务端在
RTO
时间内收到客户端的ACK
(ACK=1, ack=y+1
),则立即进入CLOSED
状态,连接释放。如果未收到
ACK
**(即ACK
丢失或延迟),服务端会 **重传FIN
,并重新启动定时器(超时时间通常按指数退避策略递增,如 2×RTO、4×RTO 等)。4.客户端回复
ACK
。回复ACK后客户端连接依旧保留两个周期(2MSL,Maximum Segment Lifetime),原因如下
(1) 确保最后一个
ACK
到达服务器- 网络中可能存在丢包或乱序问题。如果客户端的最后一个
ACK
丢失,服务器会因未收到确认而重传FIN
。 - 客户端在
TIME_WAIT
期间保持连接状态,可以重新发送ACK
,确保服务器最终能收到确认并关闭连接。 - MSL 是报文在网络中的最大生存时间,2MSL 覆盖了
ACK
和可能的FIN
重传的往返时间(RTT)。
(2) 防止旧连接的报文干扰新连接
- TCP 连接由四元组(源 IP、源端口、目标 IP、目标端口)唯一标识。如果客户端立即关闭并复用端口,新连接可能与旧连接的残留报文冲突。
- 例如:
- 客户端在
TIME_WAIT
前发送的某个数据段(如seq=z
)因网络延迟滞留,在 2MSL 后才到达服务器。 - 如果此时客户端已用相同端口建立新连接,旧数据段可能被误认为新连接的数据,导致协议错误。
- 客户端在
- 2MSL 确保所有旧报文在网络中过期,避免干扰后续连接。
为什么是 2MSL 而不是 1MSL?
- 1MSL:报文从客户端到服务器(或反向)的最大生存时间。
- 2MSL:覆盖报文的往返时间(RTT),包括:
- 客户端的最后一个
ACK
到达服务器(1MSL)。 - 如果
ACK
丢失,服务器的FIN
重传到达客户端(再 1MSL)。
- 客户端的最后一个
- 因此,2MSL 是理论上的最小安全时间,确保所有可能的重传和延迟报文都能被处理。
- 客户端发送
5. HTTP与HTTPS
- 安全性:HTTPS通过SSL/TLS加密传输,防止数据窃听。
- 端口:HTTP(80),HTTPS(443)。
- 性能:HTTPS有额外握手开销,但HTTP/2优化后性能接近HTTP。
HTTP请求方法及状态码
- 常见方法:
GET
:获取资源(幂等)。POST
:提交数据(非幂等)。PUT
:更新资源(幂等)。DELETE
:删除资源。
- 状态码:
200 OK
:请求成功。301 Moved Permanently
:永久重定向。404 Not Found
:资源不存在。500 Internal Server Error
:服务器内部错误。
6. websocket代码实现
服务端
const WebSocket = require("ws");
const fs = require("fs");
const path = require("path");
const wss = new WebSocket.Server({ port: 8080 });
// 模拟流式数据(如视频帧、传感器数据)
let counter = 0;
setInterval(() => {
const data = `数据块 ${counter++} - ${new Date().toISOString()}\n`;
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
}, 1000); // 每秒发送一次
console.log("WebSocket 服务器运行在 ws://localhost:8080");
客户端
<body>
<h1>实时数据流</h1>
<pre id="output"></pre>
<script>
const output = document.getElementById("output");
const ws = new WebSocket("ws://localhost:8080");
ws.onmessage = (event) => {
output.textContent += event.data;
};
ws.onclose = () => {
console.log("WebSocket 连接关闭");
};
</script>
</body>
7. DNS解析过程
- 本地缓存查询:浏览器→操作系统→本地DNS服务器。
- 递归查询:本地DNS服务器向根服务器、顶级域名服务器、权威服务器逐级查询。
- 迭代查询:服务器返回下一级地址,客户端自行查询。
最终:获取IP地址并缓存。
8. Java Socket编程步骤
- 服务器端:
ServerSocket serverSocket = new ServerSocket(8080); Socket clientSocket = serverSocket.accept(); // 读写数据 clientSocket.close();
- 客户端:
Socket socket = new Socket("localhost", 8080); // 读写数据 socket.close();
9. TCP粘包/拆包问题及解决方案
**粘包(Sticky Packet):**一个消息被拆分为多个数据包接收。如发送方发送 "HelloWorld"
(10字节),接收方可能先收到 "Hello"
,再收到 "World"
。
**拆包(Fragmented Packet):**一个消息被拆分为多个数据包接收。发送方发送 "HelloWorld"
(10字节),接收方可能先收到 "Hello"
,再收到 "World"
。
触发场景:
- Nagle算法:TCP默认启用Nagle算法,合并小数据包以减少网络拥塞。
- MSS(最大分段大小):TCP分段时可能将大消息拆分为多个段。
- 接收缓冲区:接收方未及时读取数据,导致缓冲区堆积,后续数据覆盖前序数据边界。
解决方案:
分隔符(Delimiter)
- 原理:
在消息末尾添加特殊分隔符(如\n
、\0
或自定义符号),接收方通过分隔符拆分消息。 - 实现步骤:
- 发送方:
- 在每条消息末尾追加分隔符(如
"Hello\n"
)。
- 在每条消息末尾追加分隔符(如
- 接收方:
- 读取数据直到遇到分隔符,将分隔符前的部分作为完整消息。
- 需处理缓冲区中可能存在的部分消息(如上一次读取到
"Hel"
,本次读取到"lo\nWorld"
,需合并后拆分)。
- 发送方:
- 优点:
- 无需记录消息长度,适合文本协议(如HTTP头部以
\r\n
分隔)。
- 无需记录消息长度,适合文本协议(如HTTP头部以
- 缺点:
- 分隔符不能出现在消息内容中(需转义,如将
\n
替换为\\n
)。 - 二进制数据需额外编码(如Base64),增加复杂度。
- 分隔符不能出现在消息内容中(需转义,如将
消息头+长度字段(Header + Length Field)
- 原理:
在消息头部定义长度字段(如4字节),接收方先读取头部获取长度,再读取完整数据。 - 实现步骤:
- 消息格式:
[长度字段(4字节)][数据体(N字节)]
- 示例:发送
"Hello"
时,构造消息[0x00, 0x00, 0x00, 0x05][H,e,l,l,o]
。
- 发送方:
- 计算数据体长度,填充到头部。
- 发送完整消息(头部+数据体)。
- 接收方:
- 读取4字节头部,解析出数据体长度。
- 根据长度读取数据体,确保完整性。
- 消息格式:
- 优点:
- 灵活支持任意长度数据,带宽利用率高。
- 广泛用于二进制协议(如Protobuf、gRPC)。
- 缺点:
- 实现稍复杂,需处理字节序(如网络字节序为大端)。
- 需处理消息过长时的缓冲区分配问题(如动态扩容)。
10. BIO、NIO、AIO的区别
模式 | 特点 |
---|---|
BIO | 同步阻塞,适合连接数少的场景(如传统Web服务器)。 |
NIO | 同步非阻塞,通过Selector 多路复用,适合高并发(如Netty框架)。 |
AIO | 异步非阻塞,基于事件和回调,适合I/O密集型场景(如文件处理)。 |
11. HTTP/1.1与HTTP/2的主要区别
- HTTP/1.1:
- 长连接(
Keep-Alive
)。 - 管线化(Pipelining,但存在队头阻塞)。
- 长连接(
- HTTP/2:
- 多路复用(单连接并行请求)。
- 头部压缩(HPACK算法)。
- 二进制分帧(提高传输效率)。
12. TCP拥塞控制算法
- 慢启动:初始发送速率低,指数增长。
- 拥塞避免:达到阈值后线性增长。
- 快速重传/恢复:检测到丢包时快速重传,避免网络拥塞。
- 算法:Reno(经典)、Cubic(Linux默认)、BBR(谷歌优化)。
13. ARP协议的作用
- 功能:将IP地址解析为MAC地址。
- 流程:主机发送ARP请求广播,目标主机回复ARP响应,缓存映射关系。
14. 浏览器输入URL到页面加载完成的流程
- DNS解析 → 2. TCP三次握手 → 3. HTTP请求 → 4. 服务器处理 → 5. 响应渲染 → 6. 四次挥手断开连接。
15. 如何设计一个高并发网络服务?
- 连接池管理:复用TCP连接,减少握手开销。
- 异步处理:使用NIO/AIO避免阻塞。
- 负载均衡:分发请求到多台服务器(如Nginx)。
- 缓存机制:Redis缓存热点数据。
- CDN加速:静态资源就近访问。
16. 长连接与短连接的选择依据
- 长连接:实时性要求高(如直播、游戏),减少频繁握手开销。
- 短连接:偶发性请求(如网页浏览),避免资源占用。