{ "topic": "distributed-microservice", "type": "single_choice", "schema_version": "1.0.0", "generated": "2026-09-09T00:00:00+08:00", "questions": [ { "id": "sc-001", "type": "single_choice", "difficulty": 2, "tags": [ "microservice", "service-discovery" ], "question": "在微服务架构中,服务注册与发现的核心作用是什么?", "options": { "A": "加密服务间的通信数据", "B": "让服务消费者能够动态地找到服务提供者的网络地址", "C": "限制单个服务的并发访问量", "D": "自动为服务分配数据库连接" }, "answer": "B", "explanation": "服务注册与发现的核心作用是维护一个服务实例的注册表,使服务消费者无需硬编码地址即可动态找到可用的服务提供者实例,实现服务间的解耦和弹性伸缩。", "source": null, "related": [] }, { "id": "sc-002", "type": "single_choice", "difficulty": 3, "tags": [ "microservice", "service-discovery" ], "question": "以下关于服务注册中心的说法,哪一项是错误的?", "options": { "A": "Eureka 采用 AP 模型,支持自我保护机制,在网络分区时优先保证可用性", "B": "Consul 支持健康检查,同时提供键值存储能力", "C": "ZooKeeper 采用 CP 模型,在 leader 选举期间服务注册可能短暂不可用", "D": "Nacos 默认采用 AP 模型,不支持配置中心功能" }, "answer": "D", "explanation": "Nacos 默认采用 AP 模式(Distro 协议),但同时支持 CP 模式(Raft 协议)的切换,且 Nacos 本身就内置了配置中心功能,因此「Nacos 不支持配置中心功能」这一说法是错误的。", "source": null, "related": [] }, { "id": "sc-003", "type": "single_choice", "difficulty": 2, "tags": [ "microservice", "load-balancing" ], "question": "负载均衡策略中,「加权轮询」与「简单轮询」的主要区别是什么?", "options": { "A": "加权轮询会优先将请求发送到响应时间最短的节点", "B": "加权轮询根据各节点的权重按比例分配请求,权重高的节点获得更多流量", "C": "简单轮询不记录请求分配的历史", "D": "加权轮询不适用于异构服务器集群" }, "answer": "B", "explanation": "加权轮询在简单轮询的基础上引入了权重的概念,根据每台服务器的处理能力(如 CPU、内存)分配不同的权重值,权重越高的节点按比例承担更多请求。而简单轮询是均等分配,不考虑节点差异。", "source": null, "related": [] }, { "id": "sc-004", "type": "single_choice", "difficulty": 4, "tags": [ "microservice", "load-balancing" ], "question": "在 Ribbon/LoadBalancer 的负载均衡策略中,「最少连接数」策略的适用场景是?", "options": { "A": "请求处理时间均匀且服务节点性能一致的场景", "B": "请求处理时间差异大、后端节点性能不一致的场景", "C": "所有请求必须严格按顺序处理的场景", "D": "服务节点数量固定且网络延迟恒定的场景" }, "answer": "B", "explanation": "最少连接数策略会将新请求分配给当前活跃连接数最少的节点,这在请求处理时间差异大、节点性能不一致时特别有效,因为连接数少并不代表负载低(可能刚分配了一个耗时长的请求),但总体上能更好地平衡实际负载。", "source": null, "related": [] }, { "id": "sc-005", "type": "single_choice", "difficulty": 3, "tags": [ "microservice", "rate-limiting" ], "question": "令牌桶算法与漏桶算法的核心区别是什么?", "options": { "A": "令牌桶只能限制总请求数,漏桶可以控制请求速率", "B": "令牌桶允许一定程度的突发流量,漏桶以固定速率匀速处理请求", "C": "漏桶算法比令牌桶更节省内存", "D": "令牌桶适用于出站流量控制,漏桶适用于入站流量控制" }, "answer": "B", "explanation": "漏桶算法以固定的速率匀速处理请求,任何超出桶容量的请求都会被丢弃或排队;令牌桶算法以固定速率向桶中放入令牌,桶满时丢弃令牌,但允许积攒令牌以应对突发流量,因此能更好地容忍短时间的流量突增。", "source": null, "related": [] }, { "id": "sc-006", "type": "single_choice", "difficulty": 3, "tags": [ "microservice", "rate-limiting" ], "question": "在分布式限流方案中,Redis + Lua 脚本实现滑动窗口限流的主要优势是?", "options": { "A": "避免了每次请求都需要多次 Redis 通信的网络开销,通过 Lua 脚本保证操作的原子性", "B": "完全不需要 Redis,纯本地内存即可实现", "C": "只能实现单机限流,不支持分布式场景", "D": "滑动窗口不需要占用额外存储空间" }, "answer": "A", "explanation": "Redis 执行 Lua 脚本时是原子性的(单线程执行),可以将滑动窗口的「查询-判断-更新」多个步骤合并为一次网络往返,既保证了原子性避免竞态条件,又减少了 Redis 的网络通信次数,提高了性能。", "source": null, "related": [] }, { "id": "sc-007", "type": "single_choice", "difficulty": 2, "tags": [ "microservice", "circuit-breaker" ], "question": "熔断器模式中,从「关闭状态」切换到「打开状态」的触发条件通常是?", "options": { "A": "服务响应时间超过 1 秒", "B": "在设定的时间窗口内,失败率或慢调用比例超过阈值", "C": "服务实例数量少于 3 个", "D": "服务的 CPU 使用率超过 80%" }, "answer": "B", "explanation": "熔断器从关闭状态切换到打开状态的典型条件是在一个统计时间窗口内,错误率(如 5xx 比例)或慢调用比例超过了预设阈值(如 Hystrix 默认 50% 错误率)。这保护了调用方不被持续的失败拖垮。", "source": null, "related": [] }, { "id": "sc-008", "type": "single_choice", "difficulty": 4, "tags": [ "microservice", "circuit-breaker" ], "question": "Resilience4j 与 Hystrix 相比,以下哪项描述是正确的?", "options": { "A": "Resilience4j 依赖 Netflix 的 Archaius 配置库进行运行时动态配置", "B": "Resilience4j 采用函数式编程风格,基于 Vavr 库,不依赖线程池隔离", "C": "Hystrix 仍处于活跃维护状态,推荐新项目使用", "D": "Resilience4j 不支持 RateLimiter 功能,只能做熔断" }, "answer": "B", "explanation": "Resilience4j 采用轻量级的函数式设计,依赖 Vavr 函数式库,不强制使用线程池隔离(可选 Semaphore 或 ThreadPool 两种隔离策略),体积更小。而 Hystrix 已停止维护,Resilience4j 支持熔断、限流、重试、隔离等多种功能。", "source": null, "related": [] }, { "id": "sc-009", "type": "single_choice", "difficulty": 3, "tags": [ "microservice", "config-center" ], "question": "配置中心实现「配置热更新」的核心机制是什么?", "options": { "A": "每次请求配置时重新启动服务实例", "B": "通过长轮询或发布订阅机制,在配置变更时主动推送通知给客户端", "C": "将配置写入数据库,客户端每次查询后缓存", "D": "通过定时任务每 5 分钟从远程拉取一次配置" }, "answer": "B", "explanation": "配置热更新的核心是「变更推送」机制:客户端建立长轮询(如 Nacos 的 Long Polling)或订阅通道(如 Spring Cloud Config + Bus),当配置变更时由配置中心主动通知客户端刷新本地配置,无需重启服务即可生效。", "source": null, "related": [] }, { "id": "sc-010", "type": "single_choice", "difficulty": 4, "tags": [ "microservice", "config-center" ], "question": "在 Spring Cloud 中,当配置中心不可用时,服务启动会使用本地缓存的配置文件。这种设计体现了什么原则?", "options": { "A": "单一职责原则", "B": "服务降级与容错设计——在外部依赖不可用时仍能保证服务基本可用", "C": "开闭原则", "D": "依赖倒置原则" }, "answer": "B", "explanation": "这体现了服务降级与容错的设计思想:配置中心作为外部依赖,一旦不可用不应阻塞服务的启动和运行。通过本地配置文件作为 fallback(降级方案),保证服务仍能以最后已知的有效配置正常工作,提高系统的可用性和韧性。", "source": null, "related": [] }, { "id": "sc-011", "type": "single_choice", "difficulty": 2, "tags": [ "microservice", "idempotent" ], "question": "在分布式系统中,以下哪种请求天然具有幂等性?", "options": { "A": "POST 创建订单", "B": "PUT 更新用户资料为指定值", "C": "POST 支付扣款(累加金额)", "D": "POST 点赞(累加计数)" }, "answer": "B", "explanation": "幂等性是指同一个请求执行多次与执行一次的效果相同。PUT 操作是「设置为指定值」,无论执行多少次结果都是相同的。而 POST 创建订单会产生多个订单,累加扣款和累加计数多次执行会导致金额或次数不正确。", "source": null, "related": [] }, { "id": "sc-012", "type": "single_choice", "difficulty": 4, "tags": [ "microservice", "idempotent" ], "question": "使用「幂等键 + Redis SETNX」实现接口幂等控制时,如何处理以下场景:请求 A 获取锁后处理失败(未释放锁),此时请求 B 携带相同幂等键到达,该如何处理?", "options": { "A": "直接拒绝请求 B,返回处理中", "B": "立即删除请求 A 的幂等键,让请求 B 重新执行", "C": "等待请求 A 完成后自动释放锁", "D": "使用无锁的数据库唯一索引方案替代 Redis SETNX" }, "answer": "A", "explanation": "在幂等控制中,如果请求 A 已获取幂等键但处理失败(未释放),请求 B 携带相同幂等键到达时,应当返回「处理中」或拒绝重复提交。正确的做法是给幂等键设置合理的过期时间(TTL),超时后自动释放,同时配合人工重试机制。直接删除其他请求的幂等键会导致并发安全问题。", "source": null, "related": [] }, { "id": "sc-013", "type": "single_choice", "difficulty": 3, "tags": [ "microservice", "distributed-lock" ], "question": "Redis 分布式锁中,设置锁的过期时间(TTL)的主要目的是什么?", "options": { "A": "提高锁的获取性能", "B": "防止持锁进程崩溃后无法释放锁,导致其他进程永远无法获取锁", "C": "减少 Redis 的内存占用", "D": "保证锁的互斥性" }, "answer": "B", "explanation": "设置过期时间是防止「死锁」的关键措施:如果持有锁的进程在执行过程中崩溃或宕机,无法主动释放锁,其他进程将永远等待。TTL 作为安全兜底,确保锁最终会被释放。这也是 Redlock 和 Redisson 分布式锁的重要组成部分。", "source": null, "related": [] }, { "id": "sc-014", "type": "single_choice", "difficulty": 5, "tags": [ "microservice", "distributed-lock" ], "question": "Redlock 算法要求在 N 个独立的 Redis 主节点上获取锁,成功条件是什么?", "options": { "A": "在任意 1 个节点上获取锁即可", "B": "在超过 N/2 个节点上获取锁,且总耗时小于锁的 TTL", "C": "在所有 N 个节点上都获取锁", "D": "在主节点和所有从节点上都获取锁" }, "answer": "B", "explanation": "Redlock 算法要求在 N 个(通常为 5 个)独立 Redis 主节点上尝试获取锁,当在超过半数(>N/2)节点上成功获取锁,且获取锁的总耗时小于锁的 TTL 时,才算成功获取分布式锁。这样即使部分节点故障,锁的安全性仍有保障。", "source": null, "related": [] }, { "id": "sc-015", "type": "single_choice", "difficulty": 4, "tags": [ "microservice", "distributed-transaction" ], "question": "在 Saga 模式中,当某一步操作失败时,需要执行「补偿事务」来回滚。以下关于 Saga 的说法,哪一项是正确的?", "options": { "A": "补偿事务必须使用与正向操作完全相同的逻辑,只是反向执行", "B": "Saga 的补偿事务是最终一致性方案,每个补偿操作本身也应该是幂等的", "C": "Saga 模式能保证像数据库事务那样的强一致性", "D": "Saga 中的补偿事务只在网络故障时才需要执行" }, "answer": "B", "explanation": "Saga 是一种最终一致性方案,每个正向操作对应一个补偿操作。由于补偿操作可能因网络等原因被重复执行,因此每个补偿操作必须设计为幂等的。补偿事务的逻辑不一定是正向操作的简单反转,而是根据业务语义设计的(如库存不足时的补偿可能是取消预留而非简单加回)。Saga 不提供强一致性保证。", "source": null, "related": [] } ] }