🏗️ 计算机网络
I. OSI 七层模型与 TCP/IP 四层模型
1. OSI 七层模型
从上到下依次为:
- 应用层:为应用程序提供服务(HTTP、FTP、SMTP)
- 表示层:数据格式化、加密解密
- 会话层:建立、管理、维护会话
- 传输层:端到端通信(TCP、UDP)
- 网络层:路由选择、逻辑地址(IP)
- 数据链路层:成帧、MAC 地址(以太网、WiFi)
- 物理层:比特流传输
2. TCP/IP 四层模型(实际应用)
- 应用层:对应 OSI 应用层、表示层、会话层(HTTP、DNS、SSH)
- 传输层:TCP、UDP
- 网络层:IP、ICMP、ARP
- 网络接口层:对应 OSI 数据链路层、物理层
II. TCP 与 UDP
1. 对比
| 特性 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 可靠传输(确认、重传) | 不可靠,可能丢包 |
| 顺序 | 保证有序 | 不保证 |
| 速度 | 较慢 | 快 |
| 资源消耗 | 高 | 低 |
| 首部开销 | 20-60 字节 | 8 字节 |
| 应用场景 | 文件传输、邮件、网页 | 视频流、游戏、DNS |
2. TCP 三次握手
目的:建立连接,同步双方的序列号和确认号
客户端 -> 服务端: SYN=1, seq=x (SYN_SENT)
服务端 -> 客户端: SYN=1, ACK=1, seq=y, ack=x+1 (SYN_RCVD)
客户端 -> 服务端: ACK=1, seq=x+1, ack=y+1 (ESTABLISHED)为什么是三次?
- 防止失效的连接请求报文段被服务端接收,造成错误
- 确认双方的收发能力都正常
3. TCP 四次挥手
目的:断开连接
客户端 -> 服务端: FIN=1, seq=u (FIN_WAIT_1)
服务端 -> 客户端: ACK=1, seq=v, ack=u+1 (CLOSE_WAIT)
客户端 -> 服务端: (确认收到,进入 FIN_WAIT_2)
服务端 -> 客户端: FIN=1, ACK=1, seq=w, ack=u+1 (LAST_ACK)
客户端 -> 服务端: ACK=1, seq=u+1, ack=w+1 (TIME_WAIT,等待 2MSL 后关闭)为什么需要 TIME_WAIT?
- 确保最后一个 ACK 能到达服务端(如果丢失,服务端会重传 FIN)
- 等待 2MSL(最大报文生存时间),让旧报文在网络中消失
为什么是四次?
- 服务端收到 FIN 后可能还有数据要发送,所以 ACK 和 FIN 分开发送
4. TCP 可靠传输机制
- 序列号:对数据字节进行编号
- 确认应答(ACK):接收方收到数据后回复 ACK
- 超时重传:发送方未收到 ACK 则重传
- 快速重传:收到 3 个重复 ACK 立即重传
- 滑动窗口:流量控制,接收方告知窗口大小
- 拥塞控制:慢启动、拥塞避免、快重传、快恢复
5. TCP 滑动窗口与流量控制
滑动窗口:
- 发送方根据接收方的通告窗口大小控制发送速率
- 窗口大小 = 接收缓冲区剩余空间
流量控制:
- 防止发送方发太快导致接收方缓冲区溢出
- 接收方在 ACK 中通告窗口大小(为 0 时停止发送)
6. TCP 拥塞控制
- 慢启动:cwnd 从 1 开始,每 RTT 翻倍(指数增长)
- 拥塞避免:cwnd 达到阈值后,每 RTT 加 1(线性增长)
- 快重传:收到 3 个重复 ACK,立即重传
- 快恢复:快重传后,cwnd 减半,直接进入拥塞避免
III. HTTP 与 HTTPS
1. HTTP 常见状态码
- 1xx:信息性(100 Continue)
- 2xx:成功(200 OK、201 Created、204 No Content)
- 3xx:重定向(301 Moved Permanently、302 Found、304 Not Modified)
- 4xx:客户端错误(400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found)
- 5xx:服务器错误(500 Internal Server Error、502 Bad Gateway、503 Service Unavailable)
2. HTTP 与 HTTPS 的区别
| 特性 | HTTP | HTTPS |
|---|---|---|
| 协议 | 运行在 TCP 之上 | 运行在 SSL/TLS 之上 |
| 端口 | 80 | 443 |
| 安全性 | 明文传输,易被窃听 | 加密传输,防窃听、篡改 |
| 证书 | 不需要 | 需要 CA 证书 |
| 性能 | 快 | 慢(SSL 握手开销) |
3. HTTPS 加密流程
- 客户端发送 ClientHello:支持的加密套件、随机数
- 服务端返回 ServerHello:选择的加密套件、随机数、证书
- 客户端验证证书:检查 CA 签名、有效期、域名
- 客户端生成 premaster secret:用服务端证书的公钥加密发送
- 双方生成 master secret:用客户端随机数、服务端随机数、premaster secret 生成
- 双方生成会话密钥:用于对称加密通信
4. HTTP 1.0 / 1.1 / 2.0 的区别
HTTP 1.0:
- 每个请求都需要新连接(短连接)
- 无 Host 头,无法虚拟主机
HTTP 1.1:
- 长连接(Connection: keep-alive),默认开启
- 管道化(Pipelining):可并行发送请求,但需按顺序响应
- 分块传输编码(Transfer-Encoding: chunked)
- 增加 Host 头、缓存控制
HTTP 2.0:
- 多路复用:一个连接并发多个请求,解决队头阻塞
- 二进制分帧:改用二进制格式,解析更高效
- 头部压缩(HPACK):减少重复头部传输
- 服务端推送(Server Push):主动推送资源
5. HTTP 与 WebSocket 的区别
| 特性 | HTTP | WebSocket |
|---|---|---|
| 通信模式 | 半双工(请求-响应) | 全双工 |
| 连接 | 短连接/长连接 | 持久连接 |
| 状态 | 无状态 | 有状态 |
| 推送 | 轮询/长轮询 | 服务端主动推送 |
| 应用 | 网页、API | 即时通讯、游戏 |
WebSocket 握手:
客户端请求:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
服务端响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=IV. DNS
1. DNS 解析过程
- 检查浏览器缓存:是否有域名对应的 IP
- 检查系统缓存(hosts 文件)
- 检查本地 DNS 服务器(运营商 DNS)
- 递归查询:
- 本地 DNS 向根域名服务器查询(.)
- 根服务器返回顶级域名服务器地址(.com)
- 向顶级域名服务器查询,返回权威域名服务器地址
- 向权威域名服务器查询,返回最终 IP
2. DNS 记录类型
- A 记录:域名 -> IPv4 地址
- AAAA 记录:域名 -> IPv6 地址
- CNAME:域名别名(如 www.example.com -> example.com)
- MX 记录:邮件服务器
- TXT 记录:文本信息(如 SPF、DKIM)
- NS 记录:指定 DNS 服务器
V. ARP 协议
1. 作用
将 IP 地址解析为 MAC 地址(网络层到数据链路层)
2. 工作流程
- 主机 A 想发送数据给主机 B(已知 B 的 IP)
- 主机 A 广播 ARP 请求:"谁的 IP 是 192.168.1.2?"
- 主机 B 收到后回复 ARP 响应:"我的 MAC 是 aa:bb:cc:dd:ee:ff"
- 主机 A 将 B 的 IP-MAC 映射缓存到 ARP 表
3. ARP 缓存
- 查看缓存:
arp -a(Windows)、arp -n(Linux) - 缓存超时:一般 20 分钟
- 免费 ARP:主机启动时广播自己的 IP,检测冲突
VI. Socket 编程
1. TCP Socket 示例
服务端:
java
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept(); // 阻塞等待连接
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
// 读写数据...
socket.close();客户端:
java
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
// 读写数据...
socket.close();2. UDP Socket 示例
发送方:
java
DatagramSocket socket = new DatagramSocket();
byte[] data = "Hello".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length,
InetAddress.getByName("127.0.0.1"), 8080);
socket.send(packet);接收方:
java
DatagramSocket socket = new DatagramSocket(8080);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet); // 阻塞等待
String msg = new String(packet.getData(), 0, packet.getLength());VII. 常见面试题
1. 在浏览器输入 URL 后发生了什么?
- DNS 解析:域名 -> IP 地址
- TCP 连接:三次握手建立连接
- HTTP 请求:发送 GET 请求
- 服务器处理:路由、业务逻辑、查询数据库
- HTTP 响应:返回 HTML/CSS/JS
- 浏览器渲染:
- 解析 HTML 构建 DOM 树
- 解析 CSS 构建 CSSOM 树
- 合并生成渲染树
- 布局(Layout)
- 绘制(Paint)
- TCP 断开:四次挥手关闭连接
2. TCP 粘包/拆包问题
原因:
- TCP 是字节流,无消息边界保护
- Nagle 算法合并小包
- 接收方缓冲区不足
解决方案:
- 固定长度:消息长度固定
- 分隔符:如换行符
\n - 长度字段:消息头包含消息体长度(Netty 的 LengthFieldBasedFrameDecoder)
3. 介绍 Cookie 和 Session
| 特性 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端(浏览器) | 服务端(内存/Redis) |
| 安全性 | 较低(可篡改) | 较高 |
| 大小限制 | 4KB | 无限制 |
| 有效期 | 可设置持久化 | 默认会话结束失效 |
Session 工作流程:
- 客户端首次请求,服务端创建 Session,生成 SessionID
- 服务端通过 Set-Cookie 头将 SessionID 返回客户端
- 客户端后续请求携带 Cookie(包含 SessionID)
- 服务端根据 SessionID 查找 Session
分布式 Session:
- Session Sticky(Nginx ip_hash)
- Session Replication(集群同步)
- Session 存储到 Redis(推荐)
4. GET 与 POST 的区别
| 特性 | GET | POST |
|---|---|---|
| 参数位置 | URL 中 | 请求体中 |
| 缓存 | 可缓存 | 默认不缓存 |
| 安全性 | 参数可见,相对不安全 | 参数在 body 中,较安全 |
| 数据大小 | 受 URL 长度限制(2KB) | 无限制 |
| 幂等性 | 幂等 | 非幂等 |
| 用途 | 查询资源 | 提交数据 |
5. 什么是跨域?如何解决?
原因:浏览器的同源策略(协议、域名、端口都相同)
解决方案:
- CORS(Cross-Origin Resource Sharing):服务端设置
Access-Control-Allow-Origin - JSONP:利用
<script>标签不受同源限制,仅支持 GET - 反向代理:Nginx 代理转发,使前后端同域
- WebSocket:不受同源策略限制
6. 输入 www.baidu.com 到页面展示的全过程
详见"浏览器输入 URL 后发生了什么",额外补充:
- CDN 加速:DNS 解析可能返回 CDN 节点 IP
- 负载均衡:Nginx 反向代理到后端服务器
- 静态资源:HTML 中的 CSS/JS/Image 等会并发请求
- HTTP 缓存:强缓存(Cache-Control)与协商缓存(ETag、Last-Modified)
7. 什么是长连接与短连接?
| 特性 | 短连接 | 长连接 |
|---|---|---|
| 连接方式 | 每次请求新建连接 | 一次连接多次请求 |
| 性能 | 频繁握手,性能低 | 减少握手,性能高 |
| 资源占用 | 低 | 高(需维护连接) |
| HTTP | HTTP/1.0 默认 | HTTP/1.1 默认(keep-alive) |
| 数据库 | 传统模式 | 连接池 |
8. 常见的 HTTP 请求头与响应头
请求头:
Host:目标域名(虚拟主机必需)User-Agent:浏览器信息Accept:接受的内容类型(如application/json)Content-Type:请求体的内容类型(如application/x-www-form-urlencoded)Authorization:认证信息(如 JWT)Cookie:携带 CookieReferer:来源页面
响应头:
Content-Type:响应的内容类型(如text/html; charset=utf-8)Content-Length:响应体长度Content-Encoding:压缩方式(如 gzip)Cache-Control:缓存策略(如max-age=3600)Set-Cookie:设置 CookieLocation:重定向目标 URLETag:资源版本标识Server:服务器信息
VIII. 性能优化
1. CDN(内容分发网络)
- 原理:将静态资源缓存到全球边缘节点,用户就近访问
- 优势:减少延迟、降低源站压力、节省带宽
- 适用:静态资源(图片、CSS、JS、视频)
2. HTTP 缓存
强缓存:
Cache-Control: max-age=3600:缓存 1 小时Expires:HTTP/1.0,已不推荐
协商缓存:
Last-Modified / If-Modified-Since:最后修改时间ETag / If-None-Match:资源指纹(优先级更高)
缓存流程:
- 第一次请求:200 返回资源,携带 Cache-Control/ETag
- 再次请求:带 If-None-Match
- 服务端对比 ETag:
- 未变化:304 Not Modified(使用缓存)
- 已变化:200 返回新资源
3. 连接池
- 数据库连接池(Druid、HikariCP):复用连接,减少创建开销
- HTTP 连接池(HttpClient、OkHttp):复用 TCP 连接
参考资料
- 《计算机网络(第 7 版)》- 谢希仁
- 《图解 TCP/IP》
- 《图解 HTTP》
- RFC 2616(HTTP/1.1)、RFC 7231(HTTP/1.1 修订)
- Wireshark 抓包实践