Skip to content

面试题汇总


题目:请解释什么是 Kafka?它和传统的消息队列有什么区别?

  • Kafka 的基本概念(Topic、Partition、Broker、Producer、Consumer)
  • Kafka 与传统 MQ 的核心区别(日志 vs 队列、顺序写、页缓存、零拷贝)
  • Kafka 的典型使用场景

Kafka 是什么: Kafka 是一个分布式、可持久化、高吞吐量的消息队列系统,核心设计思想是「分布式日志」,而非传统的「队列」。

核心概念

  • Topic:消息的分类主题
  • Partition:Topic 的物理分片,也是并行度基本单位
  • Broker:Kafka 服务节点
  • Producer:消息生产者
  • Consumer:消息消费者
  • Consumer Group:消费者组,同组内共享消费,一个分区只被一个消费者消费

与传统 MQ 的区别

特性KafkaRabbitMQ / ActiveMQ
核心设计日志(顺序写)队列(内存/数据库)
消息堆积极强(磁盘存储)较弱(内存为主)
吞吐量百万/秒万/秒
持久化强制持久化可选
消费模式Pull(拉)Push(推)
顺序保证分区内有序队列内有序
多消费者Consumer Group 广播消息消费后删除
  • 及格:能说出 Topic、Partition、Broker 等基本概念,了解 Kafka 是分布式日志系统
  • 良好:能清晰对比 Kafka 和传统 MQ 的区别,说明 Kafka 的高吞吐来源
  • 优秀:能结合具体场景(如日志收集、流处理)说明 Kafka 的优势,以及为什么这些场景不适合用传统 MQ

题目:你在项目中是怎么使用 Kafka 的?如何保证消息不丢失?

  • Producer 配置(acks、retries、幂等性)
  • Broker 配置(副本数、min.insync.replicas)
  • Consumer 配置(手动提交 offset)
  • 常见丢消息场景及应对

项目中如何使用: 在我们的订单系统中,使用 Kafka 实现订单创建后的异步通知:

  1. 订单服务创建订单后,向 Kafka 发送消息
  2. 库存服务、积分服务、通知服务各自从 Kafka 消费消息,独立处理

如何保证消息不丢失(从 Producer/Broker/Consumer 三端说明)

Producer 端

// 1. acks=all:等待 ISR 全部副本确认
// 2. retries=MAX_INT:失败重试
// 3. enable.idempotence=true:幂等性,防止重试导致重复
Properties props = new Properties();
props.put("acks", "all");
props.put("retries", "2147483647");
props.put("enable.idempotence", "true");

Broker 端

# 副本数 = 3
replication.factor=3
# ISR 至少 2 个副本才能写入
min.insync.replicas=2
# 不允许 out-of-sync 副本成为 Leader
unclean.leader.election.enable=false

Consumer 端

// 1. 手动提交 offset,不依赖自动提交
props.put("enable.auto.commit", "false");
// 2. 先处理消息,再提交 offset
while (true) {
ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord record : records) {
processMessage(record); // 先处理
}
consumer.commitSync(); // 处理成功后再提交
}

完整链路

Producer 发送 → acks=all → ISR 全部确认 → 持久化多副本
Consumer 消费 → 手动提交 offset → 提交成功 → 处理下一批
  • 及格:能说出需要配置 acks=all、retries 等参数
  • 良好:能从 Producer、Broker、Consumer 三端完整说明,能说明每端的作用
  • 优秀:能说明完整链路,并指出可能丢消息的极端场景(如磁盘损坏、页缓存未刷盘),以及如何预防

题目:Kafka 的副本同步机制是什么?ISR 是如何动态调整的?

  • ISR(In-Sync Replicas)概念
  • LEO(Log End Offset)与 HW(High Watermark)
  • 副本同步流程
  • ISR 动态收缩与扩展

副本同步机制: 每个 Partition 有多个副本,分布在不同 Broker 上:

  • Leader:处理所有读写请求
  • Follower:只负责同步数据,不处理客户端请求

ISR(In-Sync Replicas): ISR 是与 Leader 保持同步的副本集合,包含 Leader 本身。

ISR 动态调整

离开 ISR 的条件(被踢出):
- Follower 超过 replica.lag.time.max.ms(默认30秒)没有向 Leader 发送 Fetch 请求
- 实际上反映了 Follower 的 LEO 落后 Leader 太多
重新加入 ISR 的条件:
- Follower 追上 Leader 的 LEO(完全同步)

LEO 与 HW

LEO(Log End Offset):
该副本下一条待写入消息的 offset
即当前最新消息的 offset + 1
HW(High Watermark):
ISR 中所有副本 LEO 的最小值
Consumer 只能消费 offset < HW 的消息
代表已被所有同步副本确认的最高 offset

同步流程示例

1. Producer 发送消息到 Leader(offset=5,6,7)
Leader: LEO=8, HW=5
2. Follower1 发起 Fetch,获取消息
Follower1: LEO=8
3. Follower2 发起 Fetch,获取消息
Follower2: LEO=8
4. Leader 收到所有 ISR 副本的 LEO 汇报
HW = min(8, 8, 8) = 8
Leader 更新 HW=8,返回给各 Follower
5. Consumer 可消费 offset 0~7(< HW=8)
  • 及格:能说出 ISR 是同步副本集合,能说明 LEO 和 HW 的大致含义
  • 良好:能详细说明 ISR 动态调整的触发条件,能解释 HW 的推进流程
  • 优秀:能结合具体时序图说明同步过程,能指出 HW 推进的延迟问题,以及 Leader Epoch 解决方案

题目:如果 Kafka 出现消息积压,怎么排查和解决?

  • 消息积压的原因分析
  • 监控指标(Lag)
  • 问题排查思路
  • 解决方案

排查步骤

Terminal window
# 1. 查看积压情况
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group my-group --describe
# 输出示例:
# TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
# orders 0 1000 5000 4000
# orders 1 1200 5200 4000

原因分析

原因现象排查方向
消费者数量不足Lag 持续增长消费者数 < 分区数
消费速度慢Lag 增长缓慢业务处理耗时
消费失败Lag 波动异常日志
生产者突增Lag 突然增长Producer 日志
RebalanceLag 抖动Rebalance 日志
网络问题消费超时网络延迟

解决方案

1. 临时扩容
- 增加消费者实例(不超过分区数)
- 如果分区数不足,先增加分区数
2. 消费端优化
- 减少 max.poll.records,提高处理速度
- 增加 max.poll.interval.ms,避免超时 Rebalance
- 使用批量处理(批量写 DB)
3. 消费失败处理
- 快速失败:发送到死信队列(DLQ)
- 不阻塞主流程
4. 跳过历史数据(紧急情况)
kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group my-group --topic my-topic \
--reset-offsets --to-latest --execute
  • 及格:知道用 kafka-consumer-groups.sh 查看 Lag,能说出增加消费者的方法
  • 良好:能系统分析积压原因,能区分不同场景并给出不同解决方案
  • 优秀:能给出完整的排查链路图,能说明如何预防积压(监控告警),能说明不同解决方案的 Trade-off

题目:请分析 Kafka Producer 的幂等性是如何实现的?

  • 幂等性原理
  • PID(Producer ID)与 Sequence Number
  • Broker 端去重逻辑
  • 幂等性的局限性

幂等性解决的问题

场景:网络抖动,ACK 未收到,Producer 重试发送
Producer 发送 msg-A → Broker 写入成功 → 网络故障,ACK 未收到
Producer 重试 → 再次写入 msg-A
→ 消息重复(两条 msg-A)
幂等性:防止因重试导致的重复写入

实现原理

1. Producer 初始化时,从 Broker 获取一个唯一的 PID(Producer ID)
2. 每条消息携带:
- PID:Producer 唯一标识
- Sequence Number:该 Producer 向该分区发送的第 N 条消息(从 0 开始递增)
3. Broker 端维护:
- 每个 (PID, Partition) 对应的最新 Sequence Number
4. 收到消息时的处理逻辑(kafka.server.ReplicaManager):
if (sequence == expectedSeq) {
写入消息,expectedSeq++
} else if (sequence < expectedSeq) {
// 重复消息,直接丢弃
return SUCCESS
} else if (sequence > expectedSeq + 1) {
// 乱序,说明丢消息了,返回异常
throw OutOfOrderSequenceException
}

源码位置

kafka.coordinator.transaction.TransactionCoordinator
// ProducerStateManager.put()
// kafka.server.ReplicaManager.appendRecords()
// → validateSequenceNumber()

局限性

  • 只能保证单个 Producer 实例、单个分区内幂等
  • 跨分区(多分区写入)无法保证原子性
  • Producer 重启后 PID 变化,无法识别重启前的重复
  • 需要配合事务才能实现跨分区、跨会话的 Exactly Once
  • 及格:能说出 PID + Sequence Number 的基本概念
  • 良好:能详细说明 Broker 端的去重逻辑(三种 case),能说明幂等性的局限
  • 优秀:能准确指出源码位置,能结合源码说明处理流程,能对比幂等性和事务的区别

题目:在高频交易系统中,如何设计 Kafka 方案保证低延迟?

  • 低延迟场景的需求分析
  • Kafka 的性能优化方向
  • 硬件与网络优化
  • 架构设计

需求分析

  • 延迟要求:< 10ms(从发到收)
  • 吞吐量:十万级/秒
  • 可靠性:必须保证消息不丢失
  • 顺序:部分有序(同股票的交易)

设计方案

1. 集群配置
- 使用高性能 SSD(NVMe)
- 10Gbps+ 网络
- 32GB+ 内存(留足页缓存)
- 3 副本,min.insync.replicas=2
2. Producer 优化
- acks=1(单副本确认,减少延迟)
- linger.ms=0(不等待,立即发送)
- batch.size 调小(减少等待)
- 压缩设为空(避免 CPU 开销)
- 幂等性:根据业务权衡(延迟 vs 可靠性)
3. Consumer 优化
- fetch.min.bytes=1(立即返回)
- max.poll.records 调小(减少处理延迟)
- 使用消费者端本地缓存
4. Broker 优化
- num.network.threads 调高
- log.flush.interval.ms=1(频繁刷盘,降低延迟风险)
- 关闭自动创建 Topic(预创建)
5. 架构设计
- 按股票分区:相同股票进同一分区,保证该股票的交易有序
- 多 Topic:不同股票族用不同 Topic,减少锁竞争
- 就近消费:消费者部署在同机房

延迟优化总结

优化点方法收益
网络低延迟网卡、RDMA-5ms
磁盘NVMe SSD-2ms
批处理小 batch、低延迟-3ms
压缩关闭或轻量压缩-2ms
消费者本地缓存-5ms
  • 及能:能说出几个配置参数的调整
  • 良好:能从 Producer、Consumer、Broker、硬件多个层面系统说明
  • 优秀:能给出完整的架构设计,能说明 Trade-off(如可靠性 vs 延迟),能根据业务场景做出权衡

题目:如果让你设计一个日均亿级消息的消息队列系统,你会怎么考虑?

  • 系统设计能力
  • 分布式系统核心问题
  • 性能与可靠性的平衡
  • 扩展性设计

设计目标

  • 日均 1 亿条消息
  • 峰值 10 万/秒
  • 延迟 < 100ms
  • 数据不丢失
  • 可扩展

核心设计

1. 存储设计
- 顺序写磁盘(追加日志)
- 稀疏索引(按 offset 查找)
- 内存缓存(热点数据)
- 冷热分离(分层存储)
2. 分区与副本
- 分区数 = 峰值吞吐 / 单分区吞吐
- 单分区吞吐约 10MB/s
- 需要约 10 个分区
- 3 副本(允许 2 台机器故障)
3. 高可用
- Leader/Follower 机制
- ISR 动态调整
- Controller 管理元数据
- ZooKeeper / Raft 选主
4. 网络通信
- 零拷贝(sendfile)
- 批量发送
- 压缩传输
- 高性能 Selector
5. 核心挑战与解决方案
- 消息顺序:按分区保证,单分区内有序
- 消息重复:幂等 Producer
- 消息丢失:多副本 + ACK
- 水平扩展:增加分区和 Broker
- 容量规划:监控 + 动态扩容

与 Kafka 对比

如果让我设计,我会参考 Kafka 的核心思想:
- 日志追加(顺序写)
- 稀疏索引(快速查找)
- 副本机制(高可用)
- 零拷贝(高性能)
但可能有不同的优化方向:
- 元数据管理:用 Raft 替代 ZooKeeper(类似 KRaft)
- 存储格式:自研更高效的日志格式
- 网络协议:QUIC 等低延迟协议
  • 及格:能说出一些关键组件(存储、副本、选举)
  • 良好:能从存储、网络、架构多个维度系统说明,能指出核心挑战和解决方案
  • 优秀:能结合具体数字做容量规划,能深入分析 Trade-off,能对比业界方案

题目:Kafka 有哪些局限性和改进方向?RocketMQ 有哪些优势?

  • 对 Kafka 的深度理解
  • 竞品分析能力
  • 技术选型能力

Kafka 的局限性

局限说明
不支持消息路由只有 Topic/Partition,无法按消息属性路由
消息堆积时性能下降堆积越多,查询越慢
不支持延迟消息没有 RocketMQ 的延迟队列
不支持消息查询无法根据 ID 查询消息
事务是 Kafka 内不支持「业务 DB + Kafka」的原子性
运维复杂分区、副本、ISR 管理复杂

RocketMQ 的优势

特性RocketMQKafka
延迟消息✅ 支持(定时/延迟)❌ 不支持
消息查询✅ 支持(根据 ID 查询)❌ 不支持
事务消息✅ 支持(Half Message)⚠️ 仅支持 Kafka 内
顺序消息✅ 全局有序⚠️ 分区有序
消息路由✅ 支持(Tag/SQL92)❌ 不支持
DLQ✅ 原生支持❌ 需要自行实现
运维简单✅ 管理界面友好⚠️ 需要额外工具

业务场景选择

适合用 Kafka:
- 日志收集、大数据管道
- 流处理(Kafka Streams、Flink)
- 高吞吐场景
- 消息不强调顺序、不需要延迟
适合用 RocketMQ:
- 订单交易系统(需要事务消息)
- 需要延迟消息(定时任务)
- 需要消息查询(故障排查)
- 需要全局有序

Kafka 的改进方向

1. KRaft:去掉 ZooKeeper,减少依赖
2. 分层存储:冷热数据分离
3. 消息查询:增强消息追踪能力
4. 延迟消息:支持延迟队列
5. 性能优化:更低的端到端延迟
  • 及格:能说出 Kafka 的一两个局限性
  • 良好:能系统对比 Kafka 和 RocketMQ,能说明不同场景的选型建议
  • 优秀:能深入分析局限性背后的设计权衡,能说明 Kafka 社区的改进方向(如 KIP),能给出技术选型的决策框架

题号级别核心考察及格线良好线优秀线
1入门概念理解基本概念清晰对比结合场景
2初级使用经验知道配置完整链路极端场景
3中级原理理解知道概念详细流程深度问题
4中级问题分析会查 Lag系统分析完整方案
5高级源码深度知道原理详细逻辑源码位置
6高级场景实战参数调整多层优化架构设计
7资深系统设计组件说明系统维度容量规划
8专家综合能力局限性竞品对比选型决策

1. Kafka 为什么快?→ 顺序写 + 页缓存 + 零拷贝
2. ISR 是什么?→ 同步副本集合
3. HW/LEO 是什么?→ 已确认 offset / 下一条 offset
4. 如何保证不丢消息?→ acks=all + min.insync.replicas=2 + 手动提交 offset
5. 幂等性原理?→ PID + Sequence Number
6. Exactly Once 是什么?→ 幂等 + 事务 + 消费端原子提交
7. Rebalance 是什么?→ 分区重分配,会停止消费
8. 分区数如何规划?→ max(生产吞吐, 消费吞吐) / 单分区吞吐
9. Kafka 和 RocketMQ 区别?→ Kafka 高吞吐,RocketMQ 事务/延迟/路由
10. Leader Epoch 解决什么问题?→ HW 截断导致的数据丢失