RPC 语义、消息投递与顺序(gRPC/Thrift/消息队列/WebTransport)

共 47 题
#

1. 客户端重试在请求已执行但响应丢失时会造成什么语义,幂等键应保存哪些状态?

A 客户端超时后请求一定尚未在服务端执行
B 幂等键机制要求服务端保存键、请求摘要与首次执行结果,重复请求直接返回首次结果 ✓ 正确答案
C 重试时必须更换新的幂等键才能保证正确性
D 幂等键状态无需过期,应永久保存
#

2. gRPC 的四种调用方式(一元、服务端流、客户端流、双向流)在消息边界、错误传播和流控上有何差异?

A 四种调用方式中只有一元调用使用 HTTP/2 帧传输消息
B 双向流中客户端与服务端可同时互发消息,各自独立半关闭,错误可在流中随时终止 ✓ 正确答案
C 客户端流调用中服务端必须等客户端关闭后才会返回任何响应头
D 服务端流调用无法在消息流中间传播错误
#

3. FlatBuffers、Cap'n Proto、MessagePack 在零拷贝与随机访问字段上的取舍,RPC 框架集成时各有何坑?

A FlatBuffers 通过指针偏移表布局支持零拷贝与随机字段访问,但生成代码与对齐处理更复杂 ✓ 正确答案
B MessagePack 支持随机访问任意字段,无需顺序解码
C Cap'n Proto 与 Protobuf 使用完全相同的 .proto 生态与工具链
D FlatBuffers 的消息体积一定小于 MessagePack
#

4. gRPC 双向流的消息级背压如何映射到 HTTP/2 流控,消费者停读时会发生什么?

A gRPC 双向流每条消息使用独立的 HTTP/2 流,互不影响
B 背压传导只能靠业务层自定义暂停消息实现
C HTTP/2 流控窗口由发送方主动扩大,与接收方无关
D 消费者停止读取时接收方停止发送 WINDOW_UPDATE,窗口耗尽后发送端阻塞,实现背压传导 ✓ 正确答案
#

5. gRPC-Web 与原生 gRPC 在传输、Header 帧和 Trailer 帧上的差异,前端浏览器为何必须经由 envoy proxy?

A gRPC-Web 直接把原生 HTTP/2 帧透传给浏览器
B 原生 gRPC 的 grpc-status 位于 Trailer-Headers 帧,浏览器 API 无法直接读取,因此需要 Envoy 等代理翻译 ✓ 正确答案
C gRPC-Web 与原生 gRPC 在消息帧格式上完全相同
D 浏览器可以绕过代理直接发起原生 gRPC 调用
#

6. gRPC 的 metadata 与 HTTP/2 header 映射关系,x-envoy-* 与 x-request-id 注入如何影响分布式追踪?

A gRPC metadata 不经过 HTTP/2 头帧传输,走独立通道
B 代理注入新 x-request-id 不会影响分布式追踪的链路拼接
C 以 -bin 结尾的 metadata 键按 base64 编码映射为 HTTP/2 头值 ✓ 正确答案
D grpc-timeout 属于 HTTP/2 伪头,不参与 metadata 映射
#

7. RPC 框架(gRPC、Thrift、bRPC、tRPC)的负载均衡策略(round_robin、least_loaded、consistent hashing)实现位置差异?

A gRPC 的负载均衡只能在代理层实现,客户端无法参与选路
B Thrift 所有实现都强制使用客户端负载均衡
C round_robin 能感知实例实时负载并按负载加权
D 一致性哈希保证相同 key 的请求落到同一实例,适合有状态调用,但实例变更只影响部分 key ✓ 正确答案
#

8. 当服务端返回 OUT_OF_RANGE、INVALID_ARGUMENT 等标准 gRPC 状态码时,客户端如何转换成业务异常,避免信息丢失?

A gRPC 错误只能通过 HTTP 状态码表达,无独立错误模型
B grpc-message 的文本信息在转换业务异常时可以安全丢弃
C OUT_OF_RANGE 表示服务端内部错误,客户端应无限重试
D 客户端应将 UNAVAILABLE 等可重试状态码与 INVALID_ARGUMENT 等语义错误分层转换,并保留 details 与原始状态码 ✓ 正确答案
#

9. RocketMQ 的顺序消息如何依赖 MessageQueue 选择与生产者本地锁,多机房主备切换时如何恢复顺序?

A RocketMQ 顺序消息保证全局全序,任意 key 之间也严格有序
B 顺序消息消费端可以任意并发消费队列内消息
C 主备切换不影响顺序消息的位点与队列映射
D 顺序消息通过 MessageQueueSelector 将同 key 消息路由到同一队列,并用生产者本地锁串行化发送 ✓ 正确答案
#

10. RabbitMQ 的 mandatory、immediate 标志与 publisher confirm/return 回调在不可路由时的语义差异?

A mandatory 标志开启后,消息不可路由时 Broker 会通过 basic.return 退回并触发 return 回调 ✓ 正确答案
B immediate 标志在 RabbitMQ 3.0 后仍是推荐的生产实践
C publisher confirm 的 ack 表示消息已被消费者成功处理
D 开启 confirm 后无需 mandatory 即可感知不可路由
#

11. 事务型 outbox 如何避免数据库提交与消息发送之间的双写不一致?

A 事务型 outbox 完全不需要投递组件,消息由业务事务自动发送
B outbox 投递天然保证恰好一次投递,消费端无需幂等
C outbox 模式要求业务数据与 outbox 记录在同一个数据库事务中提交 ✓ 正确答案
D outbox 模式只适用于 Kafka,不适用于其他消息中间件
#

12. 当 Kafka broker 因 ISR 收缩丢失 ack 时,生产者 idempotent producer 与事务如何确保不重复不丢失?

A acks=all 时 ISR 收缩不会造成任何消息重复风险
B 开启幂等生产后,生产者重启产生新 PID 也不影响去重效果
C Kafka 事务可以保证与外部数据库操作的原子性
D idempotent producer 通过(PID、分区、序号)去重,Broker 拒绝乱序或重复序号的消息 ✓ 正确答案
#

13. Thrift 的 TBinaryProtocol、TCompactProtocol、TTupleProtocol 在序列化大小与解析性能上的取舍是什么?

A TCompactProtocol 的体积通常大于 TBinaryProtocol
B TTupleProtocol 不写字段标识,体积最小,但要求双端字段顺序与 schema 完全一致 ✓ 正确答案
C TBinaryProtocol 对每个整数都用变长编码以压缩体积
D 三种协议在字段级兼容性上完全等价
#

14. gRPC-Web 在浏览器与 backend gRPC server 通过 envoy proxy 转发 HTTP/2 的工程价值?

A gRPC-Web 只能用于一元调用,无法表达流式数据
B gRPC-Web 直接以原生 gRPC 帧与浏览器通信,无需代理
C gRPC-Web 支持二进制 metadata 与自定义 trailer
D Envoy 将 gRPC-Web 请求翻译为原生 HTTP/2 gRPC 转发后端,并反向翻译 trailer 响应 ✓ 正确答案
#

15. Connect-RPC(Connect protocol, Buf.build)相对 gRPC 在 wire compat 与 client protocol 的工程价值?

A Connect 的错误模型使用自定义二进制格式,无法被通用网关解析
B Connect 协议必须运行在 HTTP/2 且无法兼容原生 gRPC 客户端
C Connect-RPC 同一服务可同时支持 gRPC、gRPC-Web 与 Connect 协议,按 Content-Type 自动路由 ✓ 正确答案
D Connect-RPC 需要单独的 IDL 语言,与 Protobuf 不兼容
#

16. gRPC-Web 在 client-streaming / bidi-streaming vs unary 的工程限制?

A gRPC-Web 协议支持双向流,只是浏览器性能受限
B gRPC-Web 只能支持一元调用,服务端流也不被支持
C gRPC-Web 在 HTTP/2 传输下可以完整表达双向流语义
D gRPC-Web 不支持客户端流与双向流,客户端流需求常用批量上传或单向流加控制通道替代 ✓ 正确答案
#

17. gRPC-Web 在 HTTP/1.1 + HTTP/2 与 gRPC 在 HTTP/2 only 的工程边界?

A gRPC-Web 在代理处不需要任何翻译即可直通 gRPC server
B gRPC-Web 与原生 gRPC 都能在 HTTP/1.1 上原生运行
C 原生 gRPC 依赖 HTTP/2 的伪头与帧语义,只能在 HTTP/2 上运行 ✓ 正确答案
D gRPC-Web 保留了完整的双向流与二进制 metadata 能力
#

18. Protobuf 字段号、unknown fields、oneof 与 reserved 如何支持前后向兼容?

A Protobuf 序列化包含字段名,字段名修改会破坏兼容
B 已废弃的字段号可以直接分配给新字段使用
C 旧版本反序列化时未知字段存入 unknown fields 并在重新序列化时透传,实现前后向兼容 ✓ 正确答案
D oneof 内新增成员不会影响旧版本的解析语义
#

19. Protobuf 字段编号一旦分配就不能重用,reserved 关键字与未来扩展字段的命名约定是什么?

A reserved 声明的字段号与字段名在编译期即禁止使用,防止复用事故 ✓ 正确答案
B 字段号复用只影响新版本,旧版本数据不受影响
C 新字段应尽量使用 20000 以上的大字段号以节省空间
D 字段名可以随意改动,不影响二进制兼容性
#

20. Kafka 分区内顺序为何不能扩展为跨分区全序,键选择如何影响并行度与热点?

A Kafka 可以同时保证跨分区全序与高消费并行度
B 热点 key 加盐拆分不影响任何顺序语义,可无条件使用
C 相同 key 的消息哈希到同一分区内有序,跨分区并行,键分布不均会产生热点分区 ✓ 正确答案
D 分区数越多,每个分区的顺序保证越弱
#

21. Kafka 的 ISR 与 acks=all 配合 min.insync.replicas 如何界定消息持久性保证的边界?

A acks=all 表示 Leader 写本地即返回成功,与副本无关
B ISR 中的副本永远不可能丢失消息
C min.insync.replicas 规定写入时 ISR 的最小规模,低于阈值时分区拒绝写入 ✓ 正确答案
D min.insync.replicas 设置越小,持久性越强
#

22. Pulsar 的分片流(Stream)与主题(Topic)在存储模型与消费位点管理上的根本差异是什么?

A Pulsar Topic 的数据存储在无状态的 Broker 内存中,重启即丢失
B Topic 管理独立的订阅与位点,支持多订阅独立推进与重放;Stream 是构建在 Topic 之上的处理视角 ✓ 正确答案
C Pulsar 的每个 Topic 只能有一个消费者订阅
D Pulsar 位点只能前进,无法重置回溯
#

23. Kafka 消费者 offset 提交策略(auto commit、commitSync、commitAsync)在崩溃恢复时的可见性副作用是什么?

A auto commit 在消息处理完成后再提交 offset,不会丢消息
B commitAsync 的提交顺序严格保证与处理顺序一致
C commitSync 保证已处理消息在崩溃后可能被重复消费,属 at-least-once 语义 ✓ 正确答案
D offset 提交越早,崩溃恢复后重复消费越多
#

24. 消费位点 lag 监控指标的累积滞后与速率滞后在 SLA 告警上的差异,二者结合为何能提前发现下游退化?

A lag 增长只可能由生产突增引起,与消费速率无关
B 累积 lag 反映积压量,速率 lag 反映积压增长速度,两者结合可提前发现消费退化趋势 ✓ 正确答案
C 速率滞后指标在 lag 绝对值很小时无任何意义
D 累积 lag 是唯一可用于 SLA 告警的指标
#

25. RPC 超时预算如何沿调用链递减,为什么每一跳独立设置相同超时会放大资源占用?

A 超时预算应沿调用链递减,通过 deadline 元数据传递剩余预算,避免下游悬挂在无效调用上 ✓ 正确答案
B 每一跳独立设置相同超时不会影响端到端延迟
C 子调用的超时可以大于父调用剩余时间
D 超时后到达的响应仍应正常处理以提升成功率
#

26. at-most-once、at-least-once 与 effectively-once 分别要求生产者、代理和消费者保存什么状态?

A at-most-once 要求消费者幂等以吸收重复
B 三种语义对生产者没有任何状态要求
C at-least-once 不需要代理持久化消息
D effectively-once 需要代理侧去重状态与事务协调,并要求消费者把位点与处理结果原子提交 ✓ 正确答案
#

27. NATS JetStream 的 at-least-once、at-most-once、exactly-once 三档投递策略分别要求哪些服务端/客户端约束?

A JetStream 所有投递策略都不需要服务端持久化
B JetStream 的 at-most-once 也要求客户端 Ack 并支持重投
C JetStream 的 exactly-once 可保证与外部数据库操作的整体原子性
D JetStream 的 at-least-once 要求客户端处理成功后显式 Ack,未 Ack 的消息会被重新投递 ✓ 正确答案
#

28. 消费者组 rebalance 风暴的成因是什么,cooperative sticky assignor 如何缓解全量再平衡?

A rebalance 期间所有消费者继续消费,不影响吞吐
B cooperative sticky assignor 通过增量再平衡与粘性分配减少全量停止与分区迁移 ✓ 正确答案
C 消费者处理过慢不会触发 rebalance
D 启用 static membership 会加剧 rebalance 风暴
#

29. gRPC 的 5 字节消息帧(1 字节压缩标志 + 4 字节长度)如何界定消息边界,未压缩标志位与长度字段的字节序约定是什么?

A gRPC 消息帧头为 5 字节:1 字节压缩标志 + 4 字节大端长度 ✓ 正确答案
B gRPC 消息必须恰好占满一个 HTTP/2 DATA 帧
C 长度字段使用小端字节序编码
D 压缩标志为 0 表示消息体已用 gzip 压缩
#

30. HTTP/2 流的生命周期(idle→open→half-closed→closed)如何由 HEADERS、DATA、RST_STREAM、END_STREAM 标志驱动,错误帧如何终止流?

A 任一端发送带 END_STREAM 标志的帧后,该方向关闭,流进入 half-closed 状态 ✓ 正确答案
B RST_STREAM 只能由服务端发送,客户端无法终止流
C 进入 closed 状态后流内仍可继续发送 DATA 帧
D GOAWAY 帧只终止单条流,不影响连接上的其他流
#

31. HTTP/2 连接级与流级流量控制如何分层生效,WINDOW_UPDATE 必须由接收方主动发送,初始窗口 65535 字节对高带宽延迟积有何影响?

A WINDOW_UPDATE 由发送方在发送数据后主动发送以补充信用
B 连接级窗口限制整条连接所有流的在途字节总量,流级窗口限制单流在途量 ✓ 正确答案
C 初始窗口 65535 字节在高 BDP 链路上足以跑满带宽
D 流控窗口只影响连接建立阶段,不参与数据传输
#

32. gRPC 一元的完整 HTTP/2 帧序列,客户端如何用 HEADERS 携带路径与元数据,服务端如何用 HEADERS 与 Trailer-Headers 返回消息和 grpc-status?

A grpc-status 携带在响应首部 HEADERS 帧中,客户端读到即知结果
B 一元调用中客户端 HEADERS 帧携带伪头路径与 metadata,服务端以 Trailer-Headers 帧返回 grpc-status 与 trailer ✓ 正确答案
C 一元调用不需要任何 DATA 帧传输消息体
D 客户端只需读取响应 HEADERS 帧即可确定调用成功
#

33. HPACK 动态表如何跨请求复用头部,为什么带敏感信息的字段(如 Authorization)应使用 never-indexed 表示,索引表溢出如何淘汰?

A HPACK 动态表溢出后按先进先出(FIFO)淘汰,先插入的先删除
B 动态表容量由解码器临时决定,无需通过 SETTINGS 协商
C HPACK 动态表在请求结束后立即清空,无法跨请求复用
D never-indexed 让敏感字段以字面量传输、不进入动态表,避免其值被索引间接观察 ✓ 正确答案
#

34. gRPC 的 deadline 如何通过 grpc-timeout 元数据逐跳传播,服务端剩余时间如何计算,超时后客户端与服务端各自如何终止流?

A grpc-timeout 携带绝对截止时刻,要求各跳时钟严格同步
B 超时后客户端会继续等待迟到响应并正常处理
C grpc-timeout 携带相对剩余时间,逐跳递减传播,服务端按接收时刻计算剩余预算 ✓ 正确答案
D 服务端超时后无需停止执行,继续处理即可
#

35. WebTransport 的流(stream)与数据报(datagram)两种模式分别提供什么可靠性语义,游戏帧与信令各应选择哪种?

A WebTransport 流模式提供无序尽力而为的传输
B 流模式与数据报模式不能在同一连接上共存
C 数据报模式保证消息不丢失且按序到达
D 游戏状态帧时效性强、可容忍丢失,适合数据报模式;信令需可靠有序,应使用流模式 ✓ 正确答案
#

36. gRPC 客户端负载均衡与 HTTP/2 连接复用如何交互,为什么一个后端只维持少量连接,RPC 分布如何影响负载均衡效果?

A gRPC 每个 RPC 都新建一条独立 TCP 连接
B 连接的 keepalive 与子通道管理由服务端控制
C 客户端负载均衡在后端地址确定后就不再参与 RPC 选路
D 一条 HTTP/2 连接可多路复用大量 RPC 流,因此一个后端只需维持少量连接 ✓ 正确答案
#

37. HTTP/2 多路复用为何仍受 TCP 队头阻塞影响,与 HTTP/1.1 的队头阻塞有何本质区别,HTTP/3 如何用 QUIC 流消除?

A HTTP/2 多路复用同时消除了应用层与传输层队头阻塞
B QUIC 流仍然共享确认与重传机制
C HTTP/2 仍受 TCP 队头阻塞影响:TCP 丢包重传期间所有流都阻塞,HTTP/3 用 QUIC 独立流消除 ✓ 正确答案
D HTTP/1.1 的队头阻塞发生在传输层
#

38. gRPC-Web 如何在 HTTP/1.1 上模拟双向流,base64 编码的帧与 trailer 如何还原 gRPC 语义,为何浏览器需要代理转发?

A gRPC-Web 在 HTTP/1.1 上以"帧类型 + 长度 + base64 载荷"封装消息,trailer 帧承载 grpc-status ✓ 正确答案
B gRPC-Web 可以直接读取浏览器响应中的 HTTP/2 trailer
C gRPC-Web 支持完整的客户端流与双向流
D 原生 gRPC 可以不经代理直接兼容 HTTP/1.1 客户端
#

39. HTTP/2 server push 为何被 Chrome 弃用而 WebTransport 仍保留,两者在主动推送与双向通信上的能力差异是什么?

A server push 无法感知浏览器缓存且受优先级与代理缓存交互干扰,被弃用;WebTransport 是双向传输通道,主动推送只是其能力之一 ✓ 正确答案
B server push 与 WebTransport 都是 HTTP 响应加速手段,定位相同
C WebTransport 只能由客户端向服务端单向发送
D server push 推送的内容可以任意被 CDN 共享缓存复用
#

40. WebTransport 会话如何通过 HTTP/3 的 CONNECT 请求升级建立,与普通 HTTP 请求在流与安全上下文上有何不同?

A WebTransport 会话建立后只能使用一条固定流
B WebTransport 会话不需要 TLS,可在明文 UDP 上运行
C WebTransport 通过扩展 CONNECT 请求(:protocol=webtransport)建立,2xx 后升级为可双向开流与会话级通信的信道 ✓ 正确答案
D WebTransport 与普通 HTTP 请求的生命周期完全相同
#

41. gRPC 双向流的背压如何传导,消费者停止读取时 HTTP/2 流控窗口如何收紧,生产者端如何感知并暂停发送?

A 发送端可自行扩大窗口绕过背压,无需等待接收方
B 消费者停止读取时,接收方不再发送 WINDOW_UPDATE,窗口耗尽后发送端写入阻塞 ✓ 正确答案
C 背压只影响流建立阶段,数据发送阶段不受窗口限制
D 消费者恢复读取后,发送端需要业务层显式通知才能继续发送
#

42. 死信队列(DLQ)与毒丸消息(poison pill)的标准处理模式是什么,如何避免无限重试?

A 毒丸消息应在主队列中无限重试直到成功
B DLQ 中的消息会再次回到主队列循环处理
C 标准模式是有限重试后转入死信队列隔离,并分类可重试/不可重试错误,避免无限重试阻塞队列 ✓ 正确答案
D 毒丸消息只会导致单条消息处理失败,不影响其他消息
#

43. 消费者积压增长时,如何区分生产突增、下游变慢、分区不均与毒丸消息?

A 生产突增的特征是消费速率下降、生产速率不变
B 下游变慢时生产速率同步上升
C 毒丸消息会导致所有分区的 lag 同步均匀增长
D 分区不均表现为个别分区 lag 高而其他分区正常,需结合分区维度定位 ✓ 正确答案
#

44. 消息中间件的 compaction(key compaction)与 deletion retention 的取舍,业务事件流与 changelog 流的取舍点是什么?

A compaction 对 null key 的消息同样生效
B compaction 会立即同步删除旧消息,无任何延迟
C 事件流场景应优先使用 compaction 以保存最新状态
D compaction 策略为每个 key 保留最新消息,适合 changelog 流;deletion retention 按时间/大小删除,适合近期事件流 ✓ 正确答案
#

45. HTTP/2 的 SETTINGS_MAX_CONCURRENT_STREAMS 如何限制并发流数量,超限后的新请求是排队还是报错,客户端应如何处理?

A SETTINGS_MAX_CONCURRENT_STREAMS 由发送方单方面决定并发流上限
B 流数上限只对接收方生效,发送方不受任何约束
C 并发流达到上限后新请求排队等待,实现层不会报错,超时未获配额时客户端应熔断降级 ✓ 正确答案
D 达到流数上限时服务端立即返回 503 拒绝请求
#

46. gRPC channel 与 stream 的关系,为什么一个 channel 可并发承载多个 stream,连接复用、keepalive 与连接池如何协同?

A gRPC 的每条 RPC 都必须新建一条独立连接
B keepalive 用于在每次 RPC 前重建连接
C channel 与 stream 是一对一关系,一个 channel 只能承载一个 RPC
D channel 内部维持少量 HTTP/2 长连接,通过多路复用承载大量并发 stream,keepalive 用 PING 探测连接健康 ✓ 正确答案
#

47. WebTransport 数据报的大小限制由什么决定,超过 QUIC max_datagram_frame_size 时发送失败,应用应如何分片或改用流?

A 数据报大小上限由路径 MTU 与对端 max_datagram_frame_size 共同决定,超过上限的发送直接失败 ✓ 正确答案
B 超大数据报会被 QUIC 自动分片跨多个 UDP 包发送
C 数据报与流模式在大小限制与可靠性上完全相同
D 数据报大小限制只由发送端自身决定