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
148 lines
10 KiB
JSON
148 lines
10 KiB
JSON
{
|
||
"topic": "distributed-microservice",
|
||
"type": "true_false",
|
||
"schema_version": "1.0.0",
|
||
"generated": "2026-09-09T00:00:00+08:00",
|
||
"questions": [
|
||
{
|
||
"id": "tf-001",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"microservice",
|
||
"service-discovery"
|
||
],
|
||
"question": "在 CAP 定理中,ZooKeeper 属于 CP 系统,在网络分区时会牺牲可用性以保证一致性。",
|
||
"answer": true,
|
||
"explanation": "ZooKeeper 采用 ZAB(ZooKeeper Atomic Broadcast)协议,保证强一致性(CP)。当发生网络分区时,少数派分区的节点无法选举出 Leader,会拒绝写入请求,从而牺牲了可用性(A)。相比之下,Nacos 支持 AP/CP 模式切换,Consul 默认也是 CP 模式(支持最终一致性的 Consistency Mode)。这也是为什么在服务发现场景中,部分团队倾向于使用支持 AP 模式的注册中心。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-002",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"service-discovery"
|
||
],
|
||
"question": "Nacos 同时支持 CP 和 AP 两种模式,默认使用 AP 模式来保证服务注册的高可用性。",
|
||
"answer": false,
|
||
"explanation": "Nacos 确实支持 CP 和 AP 两种模式的切换(通过 Distro 协议实现 AP,Raft 协议实现 CP),但其默认模式并非 AP。在 Nacos 1.x 中,临时实例(ephemeral=true,默认)使用 AP 模式的 Distro 协议,而永久实例使用 CP 模式的 Raft 协议。在 Nacos 2.x 中,服务注册默认走 gRPC 长连接的临时实例模式,本质上是 AP 行为。所以说「默认 AP」需要区分版本和实例类型,但更准确的说法是 Nacos 的临时实例默认使用 AP 模式,永久实例使用 CP 模式。严格来说,该陈述过于简化,判定为错误。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-003",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"microservice",
|
||
"load-balancing"
|
||
],
|
||
"question": "一致性哈希算法在节点增减时,只需要重新映射约 1/n 的数据(n 为节点数),非常适合有状态服务的负载均衡。",
|
||
"answer": true,
|
||
"explanation": "一致性哈希(Consistent Hashing)将节点和数据映射到同一个哈希环上。当新增或移除一个节点时,只有该节点与逆时针方向相邻节点之间的数据需要重新分配,平均影响约 1/n 的数据量。这大大减少了传统哈希取模在节点变化时导致的大规模数据迁移。在微服务架构中,一致性哈希常用于有状态服务(如分布式缓存、会话管理)的负载均衡。实践中通常引入虚拟节点(Virtual Nodes)来解决数据倾斜问题,使负载更均匀。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-004",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"rate-limiting"
|
||
],
|
||
"question": "漏桶算法和令牌桶算法的主要区别在于:漏桶算法允许突发流量以固定速率处理,而令牌桶算法则以恒定速率匀速处理请求。",
|
||
"answer": false,
|
||
"explanation": "该陈述将两种算法的特性说反了。令牌桶(Token Bucket)以恒定速率向桶中添加令牌,请求需要消耗令牌才能通过,桶中可以积累令牌,因此允许一定程度的突发流量(突发时消耗积累的令牌)。漏桶(Leaky Bucket)以固定速率处理(漏出)请求,无论输入速率多高,输出速率始终恒定,起到「削峰填谷」的作用。简言之:令牌桶允许突发,漏桶强制平滑。Sentinel 等框架中常用的滑动窗口计数器则结合了时间窗口统计的优势,更适合精确限流场景。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-005",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"circuit-breaker"
|
||
],
|
||
"question": "Circuit Breaker(熔断器)的三种状态中,Half-Open 状态允许少量请求通过以探测下游服务是否恢复,这是熔断器从 Open 转为 Closed 的必要中间状态。",
|
||
"answer": true,
|
||
"explanation": "Circuit Breaker 的标准状态机为:Closed(正常)→ Open(熔断,拒绝所有请求)→ Half-Open(半开,允许少量探测请求通过)→ Closed(恢复)或 Open(继续熔断)。当熔断发生后,经过一段超时时间,熔断器进入 Half-Open 状态,放行有限数量的试探请求。如果试探请求成功率恢复到阈值以上,则回到 Closed 状态;否则重新回到 Open 状态。这个机制避免了服务刚恢复时因大量请求涌入而再次崩溃。Hystrix、Resilience4j、Sentinel 均实现了此模式。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-006",
|
||
"type": "true_false",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"microservice",
|
||
"config-center"
|
||
],
|
||
"question": "Apollo 配置中心通过长轮询(Long Polling)机制实现配置的实时推送,而 Nacos 则采用 WebSocket 推送配置变更通知。",
|
||
"answer": true,
|
||
"explanation": "Apollo(携程开源)采用 HTTP 长轮询机制:客户端发起一个 HTTP 请求后,服务端会 hold 住该连接一段时间(如 60 秒),期间若有配置变更则立即返回,超时后客户端重新发起轮询。这种方式兼容性好,不依赖特定协议。Nacos 1.x 配置推送基于长轮询,但在 Nacos 2.x 中,配置变更通知已结合 gRPC 长连接实现更实时的推送。两者都支持配置热更新——客户端监听配置变更后可以不重启应用就生效新配置。Apollo 还提供了命名空间(Namespace)隔离和灰度发布能力。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-007",
|
||
"type": "true_false",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"microservice",
|
||
"idempotent"
|
||
],
|
||
"question": "实现接口幂等性的 Token 机制要求客户端在调用业务接口前先获取一个全局唯一的 Token,业务接口在执行成功后必须删除该 Token,以防止重复提交。",
|
||
"answer": true,
|
||
"explanation": "Token 机制是实现幂等控制的经典方案:1)客户端先向服务端请求一个全局唯一 Token(如 UUID);2)将 Token 随业务请求一起发送;3)服务端验证 Token 是否存在,存在则执行业务逻辑并删除 Token,不存在则拒绝请求(说明是重复提交)。该机制的关键在于 Token 的原子性校验和删除(通常使用 Redis 的 SET NX + DEL 或 Lua 脚本保证原子性)。幂等键(如业务唯一 ID + 去重表)是另一种常用方案,适用于无法预先获取 Token 的场景。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-008",
|
||
"type": "true_false",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"microservice",
|
||
"distributed-lock"
|
||
],
|
||
"question": "Redis 的 RedLock 算法通过向多个独立的 Redis 实例加锁,只要多数(N/2+1)节点加锁成功即视为获取锁成功,因此可以完全替代 ZooKeeper 在分布式锁场景中的使用。",
|
||
"answer": false,
|
||
"explanation": "RedLock 算法的核心思路是正确的:向 N 个独立 Redis 实例请求加锁,超过半数成功且总耗时未超过锁的有效期则获取成功。但 RedLock 在学术界和工程界存在广泛争议(Martin Kleppmann 的著名批评文章《How to do distributed locking》)。主要问题包括:1)时钟漂移可能导致锁安全性失效;2)GC 暂停或网络延迟可能导致客户端认为自己持有锁但实际已过期;3)RedLock 不具备 ZooKeeper 那样的强一致性和顺序保证。在对一致性要求极高的场景(如金融交易),ZooKeeper 或 etcd 的分布式锁仍是更可靠的选择。RedLock 适合对性能要求高、可容忍极小概率不一致的场景。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-009",
|
||
"type": "true_false",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"distributed-lock"
|
||
],
|
||
"question": "基于 ZooKeeper 的分布式锁天然支持锁续期机制,客户端无需额外处理即可防止锁在业务未完成时过期。",
|
||
"answer": false,
|
||
"explanation": "基于 ZooKeeper 的分布式锁使用临时顺序节点(Ephemeral Sequential Node)实现:客户端创建临时节点并监听前一个节点,当前序节点删除时获取锁。临时节点的生命周期与客户端会话(Session)绑定——如果客户端与 ZooKeeper 断开连接,Session 超时后临时节点会自动删除,从而释放锁。但这并不等同于「锁续期」:1)如果客户端发生长时间 GC 或网络分区但未断开 Session,锁不会自动释放(这可能造成死锁);2)ZooKeeper 本身没有提供类似 Redis 的 TTL 续期 API。锁续期(Watchdog 机制)是 Redisson 等 Redis 分布式锁客户端提供的能力,通过后台线程定期延长锁的过期时间。在 ZooKeeper 场景中,需要应用层自行实现类似的续约逻辑来应对长时间任务。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "tf-010",
|
||
"type": "true_false",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"microservice",
|
||
"distributed-transaction"
|
||
],
|
||
"question": "TCC(Try-Confirm-Cancel)分布式事务方案中,Try 阶段需要预留业务资源,如果 Try 阶段部分参与者失败,则需要对所有已成功执行 Try 的参与者执行 Cancel 操作进行回滚。",
|
||
"answer": true,
|
||
"explanation": "TCC 是一种业务层面的分布式事务解决方案,将每个参与者拆分为三个阶段:Try(资源检查与预留)、Confirm(确认执行,使用预留资源完成业务)、Cancel(取消,释放预留资源)。其核心要求是 Confirm 和 Cancel 操作必须是幂等的。当 Try 阶段有参与者失败时,事务协调器(或框架如 Seata 的 TCC 模式)会对所有已完成 Try 的参与者发起 Cancel 调用,释放冻结的资源。这与 2PC 的回滚机制类似,但 TCC 的优势在于将锁粒度从数据库层面提升到业务层面(如冻结金额而非锁定行),提高了并发性能。代价是业务侵入性强,每个操作需要实现三个接口。",
|
||
"source": null,
|
||
"related": []
|
||
}
|
||
]
|
||
} |