Files
interview/questions/network-tcpip.md
yasinshaw fe2e6dc2f2 feat: add 50 backend interview questions and answers
Generated comprehensive interview preparation materials covering:
- Distributed systems (transactions, locks, ID generation, consistency)
- Database (indexing, sharding, replication, transactions)
- Caching (Redis, cache problems, distributed lock)
- Message queues (RocketMQ, Kafka)
- Concurrency (ThreadLocal, ConcurrentHashMap, thread pools)
- JVM (GC, memory, tuning)
- System design (seckill, short URL, IM, feed, LBS)
- Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel)
- Network (TCP/IP, HTTP/HTTPS)
- Security (encryption, SQL injection, XSS)
- Performance tuning
- Design patterns
- Microservices (Spring Boot, Gateway, Service Mesh)
- Container orchestration (Kubernetes, Docker)
- CI/CD, observability

Each file includes:
- Detailed questions
- Comprehensive answers
- Code examples
- Real project experience
- Alibaba P7 level requirements

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:09:50 +08:00

578 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TCP/IP 网络协议
## 问题
1. TCP 和 UDP 的区别是什么?
2. TCP 三次握手和四次挥手的流程是什么?为什么需要三次握手?
3. TCP 如何保证可靠传输?
4. 什么是 SYN 洪水攻击?如何防范?
5. HTTP 和 HTTPS 的区别是什么?
6. HTTP 1.1、2.0、3.0 的演进历程和主要特性
7. 什么是粘包和拆包?如何解决?
8. 在实际项目中遇到过哪些网络问题?
---
## 标准答案
### 1. TCP vs UDP
#### **对比表**
| 特性 | TCP | UDP |
|------|-----|-----|
| **连接性** | 面向连接 | 无连接 |
| **可靠性** | 可靠传输 | 不可靠 |
| **顺序** | 保证顺序 | 不保证顺序 |
| **速度** | 较慢 | 快 |
| **流量控制** | 有(滑动窗口) | 无 |
| **拥塞控制** | 有 | 无 |
| **首部开销** | 20-60 字节 | 8 字节 |
| **应用场景** | 文件传输、邮件、HTTP | 视频流、直播、DNS |
---
#### **TCP 特性**
**面向连接**
```
客户端 服务器
│ │
│─────── SYN ───────────────→│ 建立连接
│←────── SYN+ACK ────────────│
│─────── ACK ───────────────→│
│ │
│─────── 数据 ───────────────→│
│←─────── ACK ───────────────│
│ │
│─────── FIN ───────────────→│ 断开连接
│←─────── ACK ───────────────│
│←────── FIN ────────────────│
│─────── ACK ───────────────→│
```
**可靠传输**
- 确认应答ACK
- 超时重传
- 校验和
- 序列号
**流量控制**
- 滑动窗口协议
- 动态调整窗口大小
---
#### **UDP 特性**
**无连接、不可靠**
```
客户端 服务器
│ │
│─────── 数据报 ─────────────→│ (可能丢失)
│─────── 数据报 ─────────────→│ (可能乱序)
│ │
│ │
```
**优点**
- 速度快(无连接、无确认)
- 开销小(首部 8 字节)
- 支持一对一、一对多、多对多
**应用场景**
- 视频直播(可容忍丢帧)
- 在线游戏(实时性要求高)
- DNS 查询(请求响应快)
- VoIP语音通话
---
### 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
│ ESTABLISHED │
```
**状态变化**
```
客户端CLOSED → SYN_SENT → ESTABLISHED
服务器CLOSED → LISTEN → SYN_RCVD → ESTABLISHED
```
---
#### **为什么需要三次握手?**
**目的**
1. **确认双方收发能力**
- 第一次握手:服务端确认客户端能发
- 第二次握手:客户端确认服务端能收能发
- 第三次握手:服务端确认客户端能收
2. **防止已失效的连接请求突然又传送到服务端**
```
场景:客户端发送的第一个连接请求在网络中滞留
结果:客户端超时重发,建立连接后,滞留的请求到达
如果只有两次握手:
─ 客户端发送 SYN
─ 服务器收到,建立连接,等待数据
─ 滞留的 SYN 到达,服务器又建立连接(错误!)
三次握手避免:
─ 服务器收到滞留的 SYN回复 SYN+ACK
─ 客户端发现 ack 不对,丢弃(不建立连接)
```
3. **同步初始序列号ISN**
- 双方协商好初始序列号
- 保证数据的顺序和去重
---
#### **四次挥手**
**流程**
```
客户端 服务器
│ │
│─────── FIN=1, seq=u ──────→│ FIN_WAIT1
│ │ CLOSE_WAIT
│←─────── ACK=1, seq=v, ack=u+1 ───│
│ FIN_WAIT2 │
│ │
│←─────── FIN=1, ACK=1, seq=w, ack=u+1 ───│
│ TIME_WAIT │ LAST_ACK
│ │
│─────── ACK=1, seq=u+1, ack=w+1 ────→│ CLOSED
│ (等待 2MSL) │
```
**状态变化**
```
客户端ESTABLISHED → FIN_WAIT1 → FIN_WAIT2 → TIME_WAIT → CLOSED
服务器ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
```
---
#### **为什么需要四次挥手?**
**原因**
- TCP 是**全双工**协议(双向传输)
- 双方都需要关闭发送方向
**流程**
1. 客户端发送 FIN关闭客户端→服务器方向
2. 服务器确认 ACK但服务器可能还有数据要发送
3. 服务器发送 FIN关闭服务器→客户端方向
4. 客户端确认 ACK
---
#### **为什么 TIME_WAIT 状态需要等待 2MSL**
**MSLMaximum Segment Lifetime**
- 报文最大生存时间(通常 30 秒 - 2 分钟)
- 2MSL = 1 分钟 - 4 分钟
**目的**
1. **确保最后一个 ACK 能到达**
- 如果 ACK 丢失,服务器会重传 FIN
- 客户端等待 2MSL可以重传 ACK
2. **让旧连接的报文自然消失**
- 防止旧连接的报文干扰新连接
- 确保网络中所有旧报文都已消失
**问题**
- 大量 TIME_WAIT 会导致端口资源耗尽
- 解决:调低 `TIME_WAIT` 时间或端口复用
```bash
# Linux 调整
net.ipv4.tcp_tw_reuse = 1 # 端口复用
net.ipv4.tcp_tw_recycle = 0 # 关闭快速回收(有坑)
```
---
### 3. TCP 可靠传输机制
#### **核心机制**
1. **序列号Sequence Number**
- 每个字节都有编号
- 用于排序和去重
2. **确认应答ACK**
- 接收方确认收到的数据
- ACK = 下一个期望接收的字节序号
```
发送方seq=1000, len=100
接收方ack=1100期待下一个字节
```
3. **超时重传RTO**
- 发送方启动定时器
- 超时未收到 ACK重传数据
4. **快速重传**
- 收到 3 个重复 ACK立即重传
- 无需等待超时
```
发送方seq=1000, len=100
接收方:期望 1100但收到 1200乱序
接收方:连续发送 ack=11003 次)
发送方:收到 3 个重复 ack快速重传
```
5. **滑动窗口**
- 流量控制
- 动态调整发送速率
6. **拥塞控制**
- 慢启动、拥塞避免、快重传、快恢复
---
### 4. SYN 洪水攻击
#### **攻击原理**
**场景**:攻击者发送大量 SYN 包,但不完成三次握手。
```
攻击者 服务器
│ │
├─── SYN ─────────────────────→│ 分配资源
├─── SYN ─────────────────────→│ 分配资源
├─── SYN ─────────────────────→│ 分配资源
├─── SYN ─────────────────────→│ 分配资源
│ (不回复 ACK) │ 资源耗尽
│ │ 无法服务正常用户
```
**后果**
- 服务器维护大量 `SYN_RCVD` 连接
- 内存资源耗尽
- 无法响应正常用户的连接请求
---
#### **防范措施**
**1. SYN Cookies**
```bash
# 开启 SYN Cookies
net.ipv4.tcp_syncookies = 1
```
**原理**
- 不分配资源
- 计算 Cookie 并编码在 SYN+ACK 的初始序列号中
- 客户端回复 ACK 时验证 Cookie
**2. 增加 SYN 队列**
```bash
net.ipv4.tcp_max_syn_backlog = 8192
```
**3. 缩短超时时间**
```bash
net.ipv4.tcp_synack_retries = 2
```
**4. 防火墙**
- 限制单个 IP 的连接数
- 检测异常流量并拦截
---
### 5. HTTP vs HTTPS
#### **对比**
| 特性 | HTTP | HTTPS |
|------|------|-------|
| **协议** | 应用层 | 应用层 + 安全层SSL/TLS |
| **端口** | 80 | 443 |
| **加密** | 明文传输 | 加密传输 |
| **证书** | 不需要 | 需要 CA 证书 |
| **性能** | 快 | 较慢TLS 握手) |
| **SEO** | 无优惠 | 搜索引擎优先排名 |
---
#### **HTTPS 工作流程**
```
客户端 服务器
│ │
│─────── ClientHello ────────────→│ (支持的加密套件)
│ │
│←────── ServerHello ─────────────│ (选择的加密套件 + 证书)
│←────── Certificate ─────────────│
│ │
│─────── ClientKeyExchange ─────→│ (生成随机数)
│─────── ChangeCipherSpec ───────→│ (之后消息加密)
│─────── Finished ───────────────→│
│ │
│←────── ChangeCipherSpec ────────│
│←────── Finished ────────────────│
│ │
│══════ 加密通信 ══════════════════│
```
---
#### **HTTPS 的安全性**
1. **数据加密**:防止中间人窃听
2. **数据完整性**:防止数据被篡改
3. **身份认证**:防止钓鱼网站
---
### 6. HTTP 版本演进
#### **HTTP/1.0**
**特点**
- 每个请求都需要新的 TCP 连接
- 无状态、无连接
**问题**
- 性能差(频繁建立连接)
- 队头阻塞
---
#### **HTTP/1.1**
**改进**
1. **持久连接**`Connection: keep-alive`
2. **管道化Pipelining**:可发送多个请求
3. **分块传输**`Transfer-Encoding: chunked`
4. **缓存**:更强的缓存控制
**问题**
- 队头阻塞仍然存在
- 请求串行执行
---
#### **HTTP/2.0**
**改进**
1. **二进制协议**:不再是纯文本
2. **多路复用**:一个 TCP 连接并发多个请求
3. **头部压缩**HPACK 算法
4. **服务端推送**Server Push
**多路复用**
```
HTTP/1.1
请求1 → ━━━ 连接1 ━━━ → 响应1
请求2 → ━━━ 连接2 ━━━ → 响应2
请求3 → ━━━ 连接3 ━━━ → 响应3
HTTP/2.0
请求1 ┓
请求2 ┣━━━━ 单连接 ━━━→ ┳ 响应1
请求3 ┛ ┻ 响应2
响应3
```
---
#### **HTTP/3.0QUIC**
**改进**
1. **基于 UDP**:不再是 TCP
2. **解决队头阻塞**:流级别隔离
3. **更快握手**0-RTT
4. **连接迁移**IP 变化不影响连接
**架构**
```
HTTP/3.0
QUICUDP
加密、可靠传输、流控制
```
---
### 7. 粘包和拆包
#### **问题**
**TCP 是字节流协议**,无消息边界:
```
发送方发送两个包:
┌──────┐ ┌──────┐
│ 包1 │ │ 包2 │
└──────┘ └──────┘
接收方可能收到:
1. 正常:┌──────┐┌──────┐
2. 粘包:┌──────┐┌──────┐(两个包粘在一起)
3. 拆包:┌────┐ ┌──┐┌──┐┌────┐(包被拆散)
```
---
#### **解决方案**
**1. 固定长度**
```
每个包固定 100 字节
优点:简单
缺点:浪费空间(短消息)
```
**2. 分隔符**
```
每个包以 \n 结束
优点:实现简单
缺点:内容中不能有分隔符
```
**3. 长度字段(推荐)**
```
┌────┬──────────┐
│长度│ 数据 │
└────┴──────────┘
实现Netty 的 LengthFieldBasedFrameDecoder
```
**Netty 示例**
```java
// 服务端
public class Server {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
// 解决粘包拆包:长度字段解码器
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(
1024 * 1024, // 最大帧长度
4, // 长度字段偏移量
4, // 长度字段长度
0, // 长度调整值
4 // 剥离的字节数
));
ch.pipeline().addLast(new MessageHandler());
}
});
bootstrap.bind(8080).sync().channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
// 消息编解码
public class MessageEncoder extends MessageToByteEncoder<Message> {
@Override
protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) {
byte[] data = msg.getBody().getBytes();
out.writeInt(data.length); // 长度字段
out.writeBytes(data); // 数据字段
}
}
```
---
### 8. 实际项目经验
#### **案例 1TCP 长连接异常断开**
**问题**
- 客户端崩溃,服务器未收到 FIN
- 服务器维护大量死连接
**解决**
```java
// 启用 TCP Keep-Alive
socket.setKeepAlive(true);
// 应用层心跳
@Scheduled(fixedRate = 30000)
public void sendHeartbeat() {
channel.writeAndFlush(new HeartbeatMessage());
}
// 超时断开
ch.pipeline().addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS));
ch.pipeline().addLast(new HeartbeatHandler());
```
---
#### **案例 2HTTPS 性能优化**
**问题**
- HTTPS 握手耗时 200ms+
- 高并发下性能差
**解决**
1. **HTTP/2 多路复用**
2. **TLS False Start**:减少 1 个 RTT
3. **Session Resumption**:恢复会话
4. **HSTS**:强制 HTTPS避免重定向
---
### 9. 阿里 P7 加分项
**深度理解**
- 理解 TCP 的拥塞控制算法( Reno、Cubic、BBR
- 理解 QUIC 协议的设计原理
- 理解 TLS 1.3 的改进0-RTT、加密握手
**实战经验**
- 有处理网络抖动导致的连接不稳定问题
- 有 TCP 参数调优经验
- 有 HTTPS 性能优化经验
**架构能力**
- 能设计高性能的网络通信框架
- 能设计跨地域的网络架构
- 有网络监控和故障排查经验
**技术选型**
- 了解 gRPC、Thrift 等 RPC 框架
- 了解 Netty、Mina 等网络框架
- 能根据业务特点选择合适的协议