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
220 lines
12 KiB
JSON
220 lines
12 KiB
JSON
{
|
||
"topic": "distributed-microservice",
|
||
"type": "fill_blank",
|
||
"schema_version": "1.0.0",
|
||
"generated": "2026-09-09T00:00:00+08:00",
|
||
"questions": [
|
||
{
|
||
"id": "fb-001",
|
||
"type": "fill_blank",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"microservice",
|
||
"service-discovery"
|
||
],
|
||
"question": "在 CAP 定理中,Consul 和 ZooKeeper 都属于 ______ 型系统,即在分区容错性的前提下优先保证一致性和可用性中的______。",
|
||
"answer": [
|
||
"CP",
|
||
"一致",
|
||
"一致性",
|
||
"C",
|
||
"consistency"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "Consul 和 ZooKeeper 都遵循 CP 模型:在网络分区发生时优先保证一致性(Consistency),牺牲部分可用性。Consul 使用 Raft 协议实现一致性,ZooKeeper 使用 ZAB 协议。与之相对,Nacos 同时支持 AP 和 CP 模式(默认 AP),而 etcd 也是 CP 型系统。CP 系统在 Leader 选举期间会短暂不可用,但能保证所有节点读到的数据是一致的。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-002",
|
||
"type": "fill_blank",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"load-balancing"
|
||
],
|
||
"question": "在一致性哈希算法中,为了解决节点较少时数据倾斜的问题,通常引入______节点,即为每个真实节点创建多个虚拟节点映射到哈希环上。",
|
||
"answer": [
|
||
"虚拟",
|
||
"Virtual",
|
||
"vnode",
|
||
"虚拟节点"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "一致性哈希(Consistent Hashing)将节点和数据都映射到一个哈希环上,数据存储在顺时针方向遇到的第一个节点。当节点数量较少时,数据在环上的分布可能非常不均匀。引入虚拟节点(Virtual Node)后,每个物理节点对应环上的多个虚拟点,大幅改善了数据分布的均衡性。典型的实现如 Nginx 的一致性哈希模块、Redis Cluster 的槽分配都使用了这一技术。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-003",
|
||
"type": "fill_blank",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"microservice",
|
||
"rate-limiting"
|
||
],
|
||
"question": "令牌桶算法的工作原理是:系统以固定速率向桶中添加令牌,桶有最大容量限制,每次请求需要从桶中获取一个______才能通过,桶空时请求被拒绝。",
|
||
"answer": [
|
||
"令牌",
|
||
"token",
|
||
"Token"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "令牌桶(Token Bucket)算法的核心思想是:令牌以恒定速率(如每秒100个)持续注入桶中,桶容量(Burst Size)限制了突发流量的上限。每个请求到达时需取走一个令牌,桶中有令牌则放行,桶空则拒绝或排队。与漏桶(Leaky Bucket)算法的区别在于:令牌桶允许一定程度的突发流量(桶内积攒的令牌),而漏桶则强制以固定速率处理请求。Google Guava 的 RateLimiter 就是经典的令牌桶实现。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-004",
|
||
"type": "fill_blank",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"circuit-breaker"
|
||
],
|
||
"question": "熔断器(Circuit Breaker)有三种状态:正常放行请求的______状态、完全拒绝请求的______状态、以及尝试恢复的______状态。",
|
||
"answer": [
|
||
"Closed",
|
||
"Open",
|
||
"Half-Open",
|
||
"关闭",
|
||
"打开",
|
||
"半开"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "Circuit Breaker 模式包含三种状态:①Closed(关闭):正常状态,请求正常通过,同时统计失败率;②Open(打开):当失败率超过阈值,熔断器打开,所有请求直接被拒绝而不调用下游服务;③Half-Open(半开):经过一段超时时间后,允许少量探测请求通过,如果探测成功则回到 Closed 状态,失败则回到 Open 状态。Hystrix、Resilience4j 和 Sentinel 都实现了这一状态机,是微服务容错的核心机制。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-005",
|
||
"type": "fill_blank",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"config-center"
|
||
],
|
||
"question": "Apollo 配置中心通过______机制实现配置的实时推送,客户端监听长轮询(Long Polling)端点,配置变更后服务端主动通知客户端拉取最新配置,从而实现配置热更新。",
|
||
"answer": [
|
||
"长轮询",
|
||
"Long Polling",
|
||
"long polling",
|
||
"long-polling"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "Apollo 配置中心的配置热更新流程为:①客户端启动时拉取配置并缓存到本地;②客户端对 Config Service 发起长轮询(Long Polling)请求,该请求不会立即返回;③当配置发生变更时,Config Service 立即结束长轮询并返回变更通知;④客户端收到通知后重新拉取最新配置并更新本地缓存和内存。这种方式避免了客户端频繁轮询带来的性能损耗,同时保证了配置变更的实时性。与之对比,Nacos 使用 UDP Push + 长轮询的混合推送模式,etcd 则基于 Watch 机制实现。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-006",
|
||
"type": "fill_blank",
|
||
"difficulty": 2,
|
||
"tags": [
|
||
"microservice",
|
||
"idempotent"
|
||
],
|
||
"question": "为了保证接口的幂等性,常用的一种方案是:客户端在请求前先从服务端获取一个唯一的______,随请求一起提交,服务端在处理请求前检查该令牌是否已被使用。",
|
||
"answer": [
|
||
"Token",
|
||
"token",
|
||
"令牌"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "Token 机制是实现接口幂等的常用方案:①客户端在发起操作前,先调用获取 Token 的接口,服务端生成唯一 Token 存入 Redis/数据库并返回;②客户端将该 Token 放在请求参数或 Header 中提交;③服务端收到请求后检查 Token 是否存在,存在则删除 Token 并执行业务逻辑,不存在则说明是重复请求,拒绝处理。这种方案适用于创建类操作。其他幂等方案还包括:幂等键(基于业务唯一 ID 去重)、去重表(数据库唯一索引约束)等。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-007",
|
||
"type": "fill_blank",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"microservice",
|
||
"distributed-lock"
|
||
],
|
||
"question": "Redis 的分布式锁使用 SET key value NX PX timeout 命令实现,其中 NX 表示仅当 key______时才设置,PX 表示以______为单位设置过期时间。为了解决锁过期但业务未完成的问题,需要引入______机制(如 Redisson 的 WatchDog)来自动续期。",
|
||
"answer": [
|
||
"不存在",
|
||
"not exists",
|
||
"毫秒",
|
||
"ms",
|
||
"millisecond",
|
||
"锁续期",
|
||
"看门狗",
|
||
"WatchDog",
|
||
"watchdog"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "Redis 分布式锁的核心实现要点:①SET NX 保证互斥性——只有 key 不存在时才能设置成功;②PX(毫秒)/ EX(秒)设置过期时间,防止持有锁的进程崩溃导致死锁;③锁续期(WatchDog)机制:Redisson 的 WatchDog 在锁的过期时间到达前 1/3 时自动续期,默认续期到 30 秒。如果业务执行时间超过最大锁持有时间(默认 30 秒),WatchDog 停止续期,锁自动释放。这解决了「锁提前过期」的经典问题。注意:使用 value(如 UUID+线程ID)来标识锁持有者,释放锁时需验证身份,避免误删他人的锁。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-008",
|
||
"type": "fill_blank",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"microservice",
|
||
"distributed-transaction"
|
||
],
|
||
"question": "TCC(Try-Confirm-Cancel)分布式事务模式中,分为三个阶段:Try 阶段进行资源的______和校验;Confirm 阶段执行真正的业务操作;Cancel 阶段______预留的资源。",
|
||
"answer": [
|
||
"预留",
|
||
"冻结",
|
||
"检查",
|
||
"reservation",
|
||
"预留资源"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "TCC 模式将每个服务的业务逻辑拆分为三个步骤:①Try:对业务资源进行检查和预留(如冻结库存、冻结账户余额),但不执行真正的业务逻辑;②Confirm:如果所有服务的 Try 都成功,执行确认操作,真正扣减库存和金额;③Cancel:如果任何一个 Try 失败,执行补偿操作,释放所有已预留的资源。TCC 是强一致性方案,性能优于 2PC,但对业务侵入性较高(需要实现三个接口)。典型的框架包括 Seata 的 TCC 模式、Hmily 等。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-009",
|
||
"type": "fill_blank",
|
||
"difficulty": 3,
|
||
"tags": [
|
||
"microservice",
|
||
"service-discovery"
|
||
],
|
||
"question": "服务注册与发现的健康检查中,______模式是指服务主动向注册中心发送心跳报文以证明自己存活;______模式是指注册中心主动向服务实例发起探测(如 HTTP GET /health)来判断服务状态。",
|
||
"answer": [
|
||
"客户端心跳",
|
||
"Client Heartbeat",
|
||
"心跳",
|
||
"Heartbeat",
|
||
"服务端主动探测",
|
||
"Server-side Probe",
|
||
"主动探测",
|
||
"Push"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "健康检查的两种主要模式:①Push 模式(客户端心跳):服务实例定期向注册中心发送心跳包,注册中心在一定时间内未收到心跳则将实例标记为不健康。Consul 支持 TTL 心跳模式,Eureka 默认使用心跳续约;②Pull 模式(服务端主动探测):注册中心按配置间隔主动探测服务实例的健康端点。Consul 支持 HTTP/TCP/gRPC/Script 等多种探测方式,Kubernetes 使用 liveness/readiness Probe。实际生产中,很多系统同时使用两种模式以提高可靠性。",
|
||
"source": null,
|
||
"related": []
|
||
},
|
||
{
|
||
"id": "fb-010",
|
||
"type": "fill_blank",
|
||
"difficulty": 4,
|
||
"tags": [
|
||
"microservice",
|
||
"distributed-transaction"
|
||
],
|
||
"question": "在基于消息队列的分布式事务方案中,______模式是指在本地事务中同时执行业务操作和写入消息表,然后由后台任务扫描消息表将消息发送到消息队列;而 RocketMQ 的______事务消息方案则利用 Half Message(预消息)实现,先发送半消息,在本地事务执行成功后再提交或回滚消息。",
|
||
"answer": [
|
||
"本地消息表",
|
||
"Outbox",
|
||
"outbox",
|
||
"Transactional Message",
|
||
"事务消息"
|
||
],
|
||
"answer_rule": "any",
|
||
"explanation": "两种基于消息的最终一致性方案:①本地消息表(Transactional Outbox):业务操作和消息写入在同一个本地事务中,保证原子性;后台轮询线程扫描未发送的消息并投递到 MQ,消费端消费后回调确认。实现简单但依赖轮询频率,有一定延迟。②RocketMQ 事务消息:①生产者发送 Half Message(预消息)到 Broker,消费者此时不可见;②生产者执行本地事务;③根据本地事务结果向 Broker 发送 Commit(消费者可见)或 Rollback(删除消息);④如果 Broker 长时间未收到确认,会主动回查生产者的本地事务状态。事务消息方案更优雅,延迟更低,但依赖 MQ 的事务支持能力。",
|
||
"source": null,
|
||
"related": []
|
||
}
|
||
]
|
||
} |