Skip to content

第10讲:面试高频题与项目实战

核心结论(5条必记)

  1. 微服务面试考察深度和广度 -- 架构设计、RPC通信、服务治理、数据一致性、可观测性、容器化都会问到
  2. 准备3个完整的微服务项目案例 -- 从背景、架构、技术选型、踩坑、优化、复盘能完整讲出来
  3. 画架构图是必备能力 -- 能画出完整的微服务架构图,标注关键组件和数据流向
  4. 要能说清楚"为什么这样设计" -- 不是背诵方案,而是解释决策过程和权衡取舍
  5. 实战经验 > 理论知识 -- 面试官更关心你实际遇到过什么问题,怎么解决的

一、架构设计类

1. 什么是微服务?和单体架构有什么区别?

核心回答:

单体架构:
  - 所有功能在一个进程中
  - 共享同一个数据库
  - 代码量大,部署慢
  - 技术栈统一

微服务架构:
  - 按业务拆分成多个独立服务
  - 每个服务独立部署、独立数据库
  - 服务间通过RPC或HTTP通信
  - 技术栈异构

微服务的优势:

  • 独立部署:一个服务变更不影响其他服务
  • 技术异构:不同服务可用不同技术栈
  • 弹性伸缩:按需扩容瓶颈服务
  • 团队自治:小团队负责一个服务

微服务的代价:

  • 运维复杂:需要管理多个服务
  • 分布式难题:数据一致性、服务调用
  • 接口兼容:服务升级需要考虑兼容性
  • 调试困难:问题可能涉及多个服务

2. 微服务怎么拆分?有什么原则?

拆分原则:

  1. 高内聚低耦合:服务内部紧密相关,服务间依赖最少
  2. 按业务能力拆分:用户服务、订单服务、商品服务
  3. DDD领域驱动:每个服务对应一个限界上下文
  4. 数据库分离:每个服务独立数据库
  5. 三个火枪手:一个服务由3个人负责

拆分步骤:

1. 识别业务领域:电商系统(用户、商品、订单、支付...)
2. 划定服务边界:哪些功能归哪个服务
3. 定义服务接口:服务间怎么通信
4. 数据库设计:每个服务独立数据库
5. 灰度迁移:先拆非核心,验证后逐步拆分

3. 什么是分布式单体?怎么避免?

什么是分布式单体:

多个微服务,但:
- 共享同一个数据库
- 服务间同步调用链路过长
- 一个服务挂了,所有服务都受影响

如何避免:

  1. 每个服务独立数据库:通过API交换数据,不直接访问其他服务数据库
  2. 服务间异步解耦:能用消息队列就用,减少同步调用
  3. 服务自治:服务能独立部署、独立运行
  4. 合理的服务粒度:不要拆得太细

二、RPC与通信类

1. RPC和HTTP有什么区别?

维度HTTP RESTRPC (gRPC/Dubbo)
协议HTTP/1.1HTTP/2或TCP
序列化JSONProtobuf/Hessian
性能较低较高
通用性好,跨语言差,需生成代码
易用性好,调试方便差,需要工具

选型建议:

  • 外部接口:HTTP REST,通用、易调试
  • 内部服务间:gRPC,高性能、类型安全
  • 跨语言:HTTP REST或Protobuf

2. Dubbo的架构是什么?

核心组件:

Container:服务容器
Provider:服务提供者
Consumer:服务消费者
Registry:注册中心(Zookeeper/Nacos)
Monitor:监控中心

调用流程:

1. Provider启动时向Registry注册
2. Consumer从Registry订阅服务列表
3. Registry通知Consumer服务列表变化
4. Consumer直接调用Provider(点对点)
5. 调用统计上报到Monitor

3. 同步调用和异步消息各自适合什么场景?

同步调用(RPC/HTTP):

  • 需要立即返回结果
  • 简单的请求-响应模式
  • 场景:查询用户信息、创建订单

异步消息(MQ):

  • 不需要立即返回结果
  • 削峰填谷
  • 解耦服务
  • 场景:发送通知、数据同步、异步处理

三、服务注册发现类

1. 注册中心的作用是什么?

核心功能:

  1. 服务注册:服务启动时注册地址
  2. 服务发现:调用方查询可用服务地址
  3. 健康检查:剔除不健康的服务实例
  4. 变更通知:服务列表变化时通知调用方

2. Nacos和Zookeeper有什么区别?

维度NacosZookeeper
CAPAP/CP可切换CP
一致性最终一致/强一致强一致
可用性选举期间不可用
功能注册+配置中心注册中心
部署简单复杂

选型建议:

  • 大多数场景:Nacos(AP),可用性优先
  • 强一致要求:Zookeeper(CP)

3. 注册中心选CP还是AP?

CP(一致性优先):

  • 适用:金融系统,强一致性要求
  • 问题:注册中心故障期间服务不可发现

AP(可用性优先):

  • 适用:大多数互联网应用
  • 优点:注册中心短暂故障不影响已有调用
  • 原理:本地缓存兜底

四、服务治理类

1. 限流算法有哪些?各自优缺点?

算法优点缺点适用场景
固定窗口简单边界突发基础限流
滑动窗口平滑实现复杂精确限流
令牌桶允许突发参数调优通用限流
漏桶完全平滑无突发削峰填谷

2. 什么是服务熔断?熔断器的状态机?

什么是熔断: 下游服务异常时,快速失败,避免拖垮上游。

熔断器状态机:

关闭 -> 打开 -> 半开 -> 关闭
正常   熔断   探测   恢复
  • 关闭:正常请求通过
  • 打开:直接拒绝请求
  • 半开:放行少量请求探测

3. 重试有什么风险?怎么避免?

风险:

  • 重复消费:重复下单、重复扣款
  • 重试风暴:大量请求同时重试

避免方法:

  1. 先做幂等,再加重试
  2. 幂等手段:唯一请求ID、数据库唯一索引、状态机
  3. 控制重试次数:最多3次
  4. 指数退避:1s, 2s, 4s

五、数据一致性类

1. CAP定理是什么?

分布式系统不能同时满足:

  • C(一致性):所有节点同时看到相同数据
  • A(可用性):每个请求都能得到响应
  • P(分区容错性):网络分区时仍能运行

实际选择:

  • CP:强一致,如银行系统
  • AP:高可用,如社交应用

2. 分布式事务有哪些方案?

方案一致性复杂度适用场景
2PC强一致传统数据库
TCC强一致资金类
Saga最终一致长流程
本地消息表最终一致大多数业务
事务消息最终一致有MQ

3. 怎么保证接口幂等?

方案:

  1. 唯一ID:每个请求有唯一标识
  2. 数据库唯一索引:插入时冲突则忽略
  3. Token机制:Token使用后失效
  4. 状态机:只有特定状态转换才允许

六、可观测性类

1. TraceID怎么在服务间传递?

传递方式:

  • HTTP Header:X-Trace-Id
  • gRPC Metadata
  • MDC(线程上下文)

实现:

python
import uuid
import logging

# 网关生成TraceID
trace_id = str(uuid.uuid4())
# 使用 logging 的 extra 或 contextvars 传递上下文
logger = logging.getLogger(__name__)

# RPC调用时传递(在请求头中携带)
headers = {"X-Trace-Id": trace_id}

# 后续服务从Header获取
trace_id = request.headers.get("X-Trace-Id")

2. 怎么定位"某个服务偶尔超时"?

排查步骤:

  1. 通过TraceID关联所有日志
  2. 分析调用链,定位慢的环节
  3. 查看该服务的监控指标
  4. 定位原因:数据库慢?锁竞争?GC?网络?

七、容器化与部署类

1. Docker和虚拟机的区别?

维度Docker虚拟机
内核共享宿主机独立OS
启动速度秒级分钟级
资源占用
隔离性进程级系统级

2. Kubernetes核心概念有哪些?

  • Pod:最小部署单元
  • Deployment:管理Pod副本
  • Service:负载均衡和服务发现
  • Ingress:HTTP路由
  • ConfigMap:配置管理
  • Secret:敏感信息
  • HPA:弹性伸缩

八、项目实战案例

电商微服务系统

背景:

  • 初期单体架构,业务快速增长
  • 团队10人,需要独立交付
  • 高峰期流量大,需要弹性伸缩

拆分方案:

用户服务:用户注册、登录、信息管理
商品服务:商品管理、库存管理
订单服务:订单创建、查询、状态流转
支付服务:支付对接、退款
营销服务:优惠券、活动

技术栈:

  • 注册中心:Nacos
  • RPC:Dubbo
  • 网关:Spring Cloud Gateway
  • 缓存:Redis
  • MQ:RocketMQ
  • 数据库:MySQL(分库分表)

踩坑和优化:

  1. 分布式事务:最初用Seata,性能差 → 改为本地消息表
  2. 服务雪崩:加熔断降级,Sentinel配置
  3. 缓存穿透:布隆过滤器 + 缓存空值
  4. 分库分表:ShardingSphere,按用户ID分片

效果:

  • 支撑10万QPS
  • 核心接口P99延迟<200ms
  • 团队独立并行开发

九、面试准备清单

理论知识(必背)

  • [ ] 微服务架构设计(拆分原则、DDD)
  • [ ] RPC原理(Dubbo/gRPC)
  • [ ] 服务注册发现(Nacos原理)
  • [ ] 服务治理(限流、熔断、降级算法)
  • [ ] 分布式事务(CAP、方案对比)
  • [ ] 幂等性设计
  • [ ] 全链路追踪原理
  • [ ] Docker/K8s核心概念

实战经验(准备3个项目)

每个项目准备:

  1. 背景:为什么做微服务拆分
  2. 架构图:能画出完整架构
  3. 技术选型:为什么选这个技术栈
  4. 踩坑:遇到什么问题,怎么解决
  5. 优化:做过哪些优化,效果如何
  6. 复盘:如果重来,会怎么改进

画图能力

  • [ ] 微服务整体架构图
  • [ ] 服务调用时序图
  • [ ] 数据流转图
  • [ ] 部署架构图

十、面试技巧

回答问题的"STAR"法则

Situation(背景): "我们公司的电商系统最初是单体架构,随着业务增长..."

Task(任务): "需要支撑双11大促,峰值10万QPS,同时支持多团队并行开发..."

Action(行动): "我负责架构设计,将系统拆分为用户、商品、订单、支付等6个服务,技术栈选了..."

Result(结果): "最终支撑了15万QPS,核心接口P99延迟150ms,团队并行开发效率提升50%..."

关键表达

体现深度:

  • "我们考虑了A、B、C三种方案,权衡后选择了A,因为..."
  • "这个设计有X、Y、Z几个trade-off,我们选择了..."

体现经验:

  • "我们遇到过这个问题,原因是...,最后通过...解决"
  • "上线后发现...,我们优化了...,效果是..."

十一、练习与模拟

自我检查

能清晰回答的问题:

  • 为什么选择微服务而不是单体?
  • 微服务拆分的具体步骤是什么?
  • 你们的服务是怎么通信的?
  • 分布式事务怎么解决的?
  • 怎么保证服务的高可用?

需要加强的点:

  • 架构设计决策的权衡
  • 实际踩坑和解决方案
  • 数据和效果的量化

模拟面试

准备30分钟自我介绍:

  1. 教育背景和工作经历
  2. 最有挑战的项目
  3. 技术栈和擅长领域
  4. 为什么选择这个方向

结语

微服务面试核心是:

  1. 理论基础扎实:能说清楚原理
  2. 实战经验丰富:能讲出踩坑和优化
  3. 架构思维清晰:能画出完整的架构图
  4. 决策有理有据:能解释为什么这样设计

最后建议:

  • 理论结合实践,不要只背概念
  • 准备3个完整的项目案例
  • 多画图,架构图、流程图、时序图
  • 体现思考和权衡,而不是标准答案

全书总结

微服务学习路线:

  1. 架构认知:L1-L2,理解为什么需要微服务
  2. 通信机制:L3-L5,服务怎么通信和治理
  3. 数据一致:L6,分布式事务和幂等
  4. 可观测性:L7,监控、日志、追踪
  5. 容器化:L8-L9,Docker、K8s、Service Mesh
  6. 实战能力:L10,面试和项目

核心能力图谱:

  • ✅ 微服务架构设计
  • ✅ RPC通信
  • ✅ 服务注册发现
  • ✅ 服务治理
  • ✅ 分布式数据一致性
  • ✅ 可观测性
  • ✅ 容器化
  • ✅ 幂等性设计

继续加油,微服务架构师之路!

基于 VitePress 构建