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

15 KiB
Raw Blame History

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 时间或端口复用
# 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期待下一个字节
  1. 超时重传RTO

    • 发送方启动定时器
    • 超时未收到 ACK重传数据
  2. 快速重传

    • 收到 3 个重复 ACK立即重传
    • 无需等待超时
发送方seq=1000, len=100
接收方:期望 1100但收到 1200乱序
接收方:连续发送 ack=11003 次)
发送方:收到 3 个重复 ack快速重传
  1. 滑动窗口

    • 流量控制
    • 动态调整发送速率
  2. 拥塞控制

    • 慢启动、拥塞避免、快重传、快恢复

4. SYN 洪水攻击

攻击原理

场景:攻击者发送大量 SYN 包,但不完成三次握手。

攻击者                         服务器
  │                              │
  ├─── SYN ─────────────────────→│  分配资源
  ├─── SYN ─────────────────────→│  分配资源
  ├─── SYN ─────────────────────→│  分配资源
  ├─── SYN ─────────────────────→│  分配资源
  │  (不回复 ACK)                │  资源耗尽
  │                              │  无法服务正常用户

后果

  • 服务器维护大量 SYN_RCVD 连接
  • 内存资源耗尽
  • 无法响应正常用户的连接请求

防范措施

1. SYN Cookies

# 开启 SYN Cookies
net.ipv4.tcp_syncookies = 1

原理

  • 不分配资源
  • 计算 Cookie 并编码在 SYN+ACK 的初始序列号中
  • 客户端回复 ACK 时验证 Cookie

2. 增加 SYN 队列

net.ipv4.tcp_max_syn_backlog = 8192

3. 缩短超时时间

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 示例

// 服务端
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
  • 服务器维护大量死连接

解决

// 启用 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 等网络框架
  • 能根据业务特点选择合适的协议