0f68a64829
Deploy Examination / deploy (push) Successful in 10s
Subtopics: - distributed-microservice: 45 questions (分布式微服务架构) - message-queue: 45 questions (消息队列) - k8s-observability: 45 questions (K8s与可观测性) - go-java-concurrency: 45 questions (Go/Java并发模型) - database-advanced: 35 questions (数据库进阶) - ai-engineering: 35 questions (AI工程实践) Question types: single_choice, true_false, fill_blank, short_answer, code_reading
160 lines
9.9 KiB
JSON
160 lines
9.9 KiB
JSON
{
|
||
"topic": "message-queue",
|
||
"type": "true_false",
|
||
"schema_version": "1.0.0",
|
||
"generated": "2026-09-09T15:30:00+08:00",
|
||
"questions": [
|
||
{
|
||
"id": "tf-001",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"kafka",
|
||
"零拷贝",
|
||
"持久化"
|
||
],
|
||
"question": "Kafka 的零拷贝(Zero-Copy)技术依赖于 Linux 操作系统的 sendfile 系统调用,Java 层面通过 FileChannel.transferTo() 方法触发,其核心优势是避免了数据在用户态和内核态之间的拷贝。",
|
||
"answer": true,
|
||
"explanation": "正确。Kafka 在将磁盘文件数据发送到网络 Socket 时,使用了操作系统的 sendfile 系统调用(通过 Java NIO 的 FileChannel.transferTo() 触发)。sendfile 直接在内核空间完成文件数据到网卡缓冲区的传输,无需将数据拷贝到用户态再写回内核态,显著减少了 CPU 开销和内存拷贝次数,是 Kafka 高吞吐量的关键优化之一。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-002",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"rocketmq",
|
||
"事务消息",
|
||
"半消息"
|
||
],
|
||
"question": "RocketMQ 的事务消息机制依赖于半消息(Half Message)实现:Producer 先发送半消息到 Broker,执行本地事务后再根据结果 commit 或 rollback,Broker 对消费者隐藏未确认的半消息。",
|
||
"answer": true,
|
||
"explanation": "正确。这是 RocketMQ 事务消息的核心机制。Producer 发送半消息后,Broker 会将其存储在内部的 Half Topic 中,此时消费者无法消费该消息。Producer 执行本地事务后,根据结果向 Broker 发送 commit 或 rollback 指令。commit 后消息进入真正的 Topic 可被消费;rollback 后消息被丢弃。若 Broker 未收到确认,会定时回查 Producer 的本地事务状态。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-003",
|
||
"type": "true_false",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"pulsar",
|
||
"架构",
|
||
"计算存储分离"
|
||
],
|
||
"question": "Apache Pulsar 采用计算存储分离架构,Broker 节点是无状态的,消息数据持久化在 Apache BookKeeper 中;而 Kafka 的 Broker 节点同时承担计算和存储职责,消息数据直接存储在 Broker 本地磁盘上。",
|
||
"answer": true,
|
||
"explanation": "正确。这是 Pulsar 和 Kafka 架构的根本区别。Pulsar 的 Broker 不存储数据,仅负责协议处理和读写路由,实际数据写入 BookKeeper 的 Bookie 节点;而 Kafka 的 Broker 既处理客户端请求(计算),又将数据存储在本地磁盘的日志段中(存储)。这种分离使得 Pulsar 在 Broker 扩缩容时无需数据迁移,而 Kafka 扩容 Broker 后需要进行分区重分配(rebalance)。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-004",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"rocketmq",
|
||
"推拉模式",
|
||
"长轮询"
|
||
],
|
||
"question": "RocketMQ 的 Consumer 采用 Push(推)模式消费消息,即 Broker 主动将消息推送给消费者;而 Kafka 的 Consumer 始终采用 Pull(拉)模式,由消费者主动向 Broker 拉取消息。",
|
||
"answer": false,
|
||
"explanation": "错误。虽然 RocketMQ 的 Consumer API 是 Push 模式(注册 MessageListener 回调),但底层实现实际上是基于长轮询(Long Polling)的 Pull 模式。Consumer 向 Broker 发起长轮询请求,Broker 在有新消息时立即响应,无消息时保持连接等待。Kafka 的 Consumer 确实是 Pull 模式。因此 RocketMQ 并非真正的 Broker 主动推送,而是通过长轮询模拟了 Push 的实时性。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-005",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"kafka",
|
||
"集群",
|
||
"ISR",
|
||
"选举"
|
||
],
|
||
"question": "Kafka 的 ISR(In-Sync Replicas)机制仅用于控制 follower 副本从 leader 副本同步数据的时延阈值(replica.lag.time.max.ms),与数据一致性和容灾选举无关。",
|
||
"answer": false,
|
||
"explanation": "错误。ISR 是 Kafka 保障数据一致性和可用性的核心机制,绝不仅仅控制同步延迟。ISR 维护的是与 Leader 保持同步的副本集合:当 follower 副本落后超过 replica.lag.time.max.ms 时会被踢出 ISR。ISR 的作用包括:1)acks=all 时只有 ISR 中所有副本确认才算写入成功,保障数据一致性;2)Leader 宕机时,Controller 优先从 ISR 中选举新 Leader,保障可用性和数据完整性。ISR 是数据一致性和容灾选举的关键枢纽。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-006",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"kafka",
|
||
"事务消息",
|
||
"exactly-once"
|
||
],
|
||
"question": "Kafka 的事务消息机制允许 Producer 在一个事务内跨多个分区原子性地写入消息,配合 Consumer 的 isolation.level=read_committed 配置,可实现端到端的 Exactly-Once 语义。",
|
||
"answer": true,
|
||
"explanation": "正确。Kafka 从 0.11 版本引入事务支持。Producer 通过 initTransactions()、beginTransaction()、commitTransaction() 等 API 在一个事务内跨分区写入消息,由 TxnCoordinator 协调事务状态。Consumer 设置 isolation.level=read_committed 后,只能读取已提交事务的消息。结合幂等 Producer(enable.idempotence=true),Kafka 可在 Producer→Broker→Consumer 链路上实现 Exactly-Once 语义。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-007",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"消息模型",
|
||
"广播",
|
||
"consumer-group"
|
||
],
|
||
"question": "在 RocketMQ 中,广播消费(BROADCASTING)模式下,同一个 Consumer Group 中的每个 Consumer 实例都会收到全量消息的副本;而集群消费(CLUSTERING)模式下,同组内只有一个实例收到某条消息。",
|
||
"answer": true,
|
||
"explanation": "正确。RocketMQ 支持两种消费模式:广播消费(BROADCASTING)下,消息会投递给 Consumer Group 中的每一个实例,每个实例独立消费全量消息,适用于通知、配置更新等场景;集群消费(CLUSTERING)下,同组内的消息被负载均衡分配给其中一个实例处理,适用于任务分发场景。注意:广播消费模式下 rebalance 不生效,因为每个实例都需要消费所有消息。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-008",
|
||
"type": "true_false",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"死信队列",
|
||
"重试策略",
|
||
"消息可靠性"
|
||
],
|
||
"question": "在 RocketMQ 中,当消费端处理消息失败后,消息会自动进入重试队列进行多次重试;超过最大重试次数后,消息会被自动路由到死信队列(DLQ),无需开发者额外配置死信队列的消费逻辑即可完成消息回溯。",
|
||
"answer": false,
|
||
"explanation": "错误。前半句正确——RocketMQ 确实会在消费失败后将消息放入重试 Topic(%RETRY%)进行重试,达到最大重试次数后自动转入死信队列(%DLQ%)。但后半句错误:死信队列中的消息不会自动被消费或回溯。开发者必须编写专门的消费者订阅死信队列 Topic 进行处理(如告警、人工干预或写入落库)。如果不对死信队列进行消费,消息将永久滞留在 DLQ 中,造成消息丢失。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-009",
|
||
"type": "true_false",
|
||
"difficulty": 5,
|
||
"tags": [
|
||
"kafka",
|
||
"消费者",
|
||
"offset",
|
||
"exactly-once"
|
||
],
|
||
"question": "Kafka 消费者在处理完消息后立即提交 offset(即 process-then-commit 模式),配合自动提交机制,即可实现 Exactly-Once 消费语义,无需额外的幂等处理。",
|
||
"answer": false,
|
||
"explanation": "错误。这里存在两个陷阱:1)「自动提交」(enable.auto.commit=true)是在 poll() 调用时自动提交上次的 offset,而非在消息处理完成后提交,这意味着如果消费者在处理消息过程中崩溃,已提交的 offset 对应的消息实际上未被处理,导致消息丢失(At-Most-Once);2)即使手动在处理完成后提交 offset(At-Least-Once),也只是保证消息至少被处理一次,仍可能出现重复消费。要实现 Exactly-Once,需要结合幂等消费(如数据库唯一键去重)或使用 Kafka 事务将 offset 提交与消息处理绑定在同一事务中。process-then-commit + 自动提交不能实现 Exactly-Once。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-010",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"pulsar",
|
||
"消息模型",
|
||
"确认机制"
|
||
],
|
||
"question": "Pulsar 同时支持累积确认(Cumulative Acknowledgment)和单条确认(Individual Acknowledgment)两种消费确认模式,而 Kafka Consumer 仅支持对 poll() 批次内已处理消息的批量提交,不支持选择性确认单条消息。",
|
||
"answer": false,
|
||
"explanation": "错误。后半句关于 Kafka 的描述不准确。Kafka 从 0.11 版本起支持通过 ConsumerRecord 记录每条消息的 offset,开发者可以使用 consumer.commitSync(Collection<ConsumerPartitionOffsetMetadata>) 方法选择性地提交特定分区和 offset 的确认,实现类似「单条确认」的效果。此外,Kafka 还支持通过 ConsumerRebalanceListener 在 rebalance 时精确控制 offset 提交。Pulsar 确实原生支持累积确认和单条确认两种模式,但说 Kafka 不支持选择性确认是错误的。",
|
||
"source": null,
|
||
"related": []
|
||
}
|
||
]
|
||
} |