面试知识

架构师高频追问题库

92-架构师高频追问题库 面试知识整理。

架构师高频追问题库

1. 使用方式

本文件用于架构师面试前快速自测。每个问题都建议按下面结构回答:

结论 -> 背景 -> 方案 -> 取舍 -> 风险 -> 兜底 -> 项目例子

2. 架构思维类

2.1 你怎么理解架构师职责?

  • 考点:业务目标、系统边界、技术取舍、落地推进。
  • 回答思路:架构师不是只画图,而是把业务目标转成可落地的技术方案,控制复杂度、风险、成本和演进路径。
  • 进阶追问:架构师如何平衡短期交付和长期架构?

2.2 你如何判断一个架构是否合理?

  • 考点:质量属性、约束匹配、可演进。
  • 回答思路:看是否满足业务目标,是否匹配规模和团队能力,是否有异常链路和可观测性,是否能分阶段演进。
  • 进阶追问:如果方案上线后效果不好,如何复盘?

2.3 你如何避免过度设计?

  • 考点:YAGNI(你不会需要它原则)、阶段性架构、成本。
  • 回答思路:按当前业务规模和未来可预见增长设计,不为不确定需求引入过重组件;保留演进接口。
  • 进阶追问:什么时候应该提前设计扩展点?

3. 技术选型类

3.1 MySQL(关系型数据库)和 MongoDB(文档数据库)怎么选?

  • 回答思路:强事务、结构化关系、审计选 MySQL(关系型数据库);文档结构变化快、弱事务查询选 MongoDB(文档数据库)。
  • 项目例子:订单和支付主数据放 MySQL(关系型数据库),物流轨迹扩展字段可考虑文档存储或搜索侧同步。

3.2 Redis(远程字典服务)缓存和本地缓存怎么选?

  • 回答思路:本地缓存延迟低但多实例一致性差,适合配置和低频热点;Redis(远程字典服务)适合跨实例共享和集中治理。
  • 追问:缓存击穿、热点 key(键)、一致性如何处理?

3.3 Kafka(分布式日志消息系统)、RocketMQ(分布式消息队列)、RabbitMQ(消息队列)怎么选?

  • 回答思路:Kafka(分布式日志消息系统)偏高吞吐日志流,RocketMQ(分布式消息队列)偏交易消息和事务消息,RabbitMQ(消息队列)偏灵活路由和传统集成。
  • 追问:顺序消息、重复消费、消息丢失怎么处理?

4. 高并发与高可用类

4.1 如何设计一个秒杀系统?

  • 回答结构
    1. 前端限流和按钮防抖。
    2. Gateway(网关)限流和黑名单。
    3. Redis(远程字典服务)预扣库存。
    4. MQ(消息队列)削峰异步下单。
    5. MySQL(关系型数据库)条件更新兜底。
    6. 幂等、补偿、对账。
  • 追问:Redis(远程字典服务)库存和数据库库存不一致怎么办?

4.2 如何防止系统雪崩?

  • 回答结构:超时、限流、熔断、降级、隔离、重试退避、缓存兜底、监控告警。
  • 追问:为什么重试可能放大故障?

4.3 如何做多活架构?

  • 回答结构:先区分同城双活、异地多活;核心难点是数据一致性、流量调度、故障切换、冲突处理。
  • 追问:支付系统适合直接异地多写吗?

5. 数据一致性类

5.1 分布式事务怎么选?

  • 回答结构
    • 本地事务优先。
    • 跨服务可用可靠消息最终一致性。
    • 强一致业务可考虑 TCC(Try Confirm Cancel,尝试确认取消)。
    • 外部通道用最大努力通知和对账。
  • 追问:Seata(分布式事务框架)适合所有场景吗?

5.2 支付回调如何保证幂等?

  • 回答结构:验签、防重放、通道事件 ID(标识)唯一、状态机、数据库唯一索引、重复请求直接返回成功。
  • 追问:回调先到、主动查询后到,状态如何合并?

5.3 库存扣减如何保证不超卖?

  • 回答结构:幂等请求、Redis(远程字典服务)预扣、数据库条件更新、冻结库存、超时释放、对账补偿。
  • 追问:库存冻结成功但支付失败怎么办?

6. 服务治理类

6.1 微服务拆分依据是什么?

  • 回答结构:业务边界、数据所有权、变化频率、团队协作、扩展需求。
  • 追问:服务拆太细怎么办?

6.2 如何做灰度发布?

  • 回答结构:按用户/租户/仓库/版本灰度,网关路由,配置开关,指标观察,异常自动回滚。
  • 追问:灰度期间数据结构变化怎么兼容?

6.3 如何排查微服务慢请求?

  • 回答结构:TraceId(链路标识)串联 Gateway(网关)、服务、数据库、缓存、外部接口;结合 Metrics(指标)定位瓶颈。
  • 追问:如果没有 Trace(链路追踪)怎么办?

7. 团队与治理类

7.1 架构师如何推动规范落地?

  • 回答结构:制定规范、沉淀模板、代码评审、脚手架、治理平台、指标验证。
  • 追问:团队不愿意遵守规范怎么办?

7.2 如何治理技术债?

  • 回答结构:识别影响面、分级排序、业务价值绑定、渐进式重构、监控收益。
  • 追问:重构和业务需求冲突怎么办?

7.3 如何做架构复盘?

  • 回答结构:事实时间线、影响范围、根因、短期止血、长期修复、机制改进。
  • 追问:如何避免复盘变成追责?

8. 必背 20 题清单

  1. 如何从 0 设计一个订单系统?
  2. 如何设计库存防超卖?
  3. 如何设计支付资金一致性?
  4. 如何设计跨境物流履约系统?
  5. 如何设计 IoT(物联网)报警治理系统?
  6. 如何做技术选型?
  7. 如何设计高可用系统?
  8. 如何处理分布式事务?
  9. 如何设计幂等?
  10. 如何设计补偿机制?
  11. 如何防止雪崩?
  12. 如何做灰度发布?
  13. 如何治理慢 SQL(结构化查询语言)?
  14. 如何治理消息堆积?
  15. 如何做分库分表迁移?
  16. 如何做缓存一致性?
  17. 如何做链路追踪?
  18. 如何评估架构成本?
  19. 如何推动技术方案落地?
  20. 如何证明你具备架构师思维?

9. 核心 10 题口述答案

9.1 如何从 0 设计一个订单系统?

30 秒简答版

我会先澄清业务边界和规模,再设计订单主链路。订单系统核心不是简单保存订单,而是要管理订单状态、库存、支付、履约、取消、退款和售后。架构上我会用订单服务作为主状态入口,库存、支付、物流等能力通过领域服务或事件解耦,核心状态落 MySQL(关系型数据库),热点查询走缓存,跨服务协作用 MQ(消息队列)和补偿保证最终一致性。

2 分钟标准版

如果从 0 设计订单系统,我会先问清楚几个问题:订单类型是什么,是普通电商订单、WMS(仓储管理系统)出入库订单,还是跨境物流履约订单;峰值 QPS(每秒查询率)是多少;是否要求强库存一致;支付是否接第三方通道;订单状态是否复杂。

核心设计上,我会先把订单作为主聚合,订单服务负责订单创建、状态流转和对外查询。库存扣减不直接写库存表,而是调用库存服务冻结库存;支付走支付服务,支付成功后通过 MQ(消息队列)通知订单服务推进状态;物流履约可以异步创建履约任务。这样订单服务不直接承担所有外部系统耦合。

数据层面,订单主表用 MySQL(关系型数据库)承载,因为订单需要事务、状态机、审计和查询。订单明细、支付流水、操作日志分表存储。高频查询可以使用 Redis(远程字典服务)缓存订单摘要,但缓存不是事实来源。订单状态流转必须有状态机限制,比如待支付只能变成已支付或已取消,不能直接变成已签收。

异常处理上,要考虑重复下单、库存冻结失败、支付回调重复、MQ(消息队列)消息延迟、物流创建失败等情况。所以必须有幂等键、唯一索引、状态机、补偿任务、对账任务和 TraceId(链路标识)贯穿链路。

5 分钟深挖版

更完整地讲,我会分阶段设计。

第一阶段是业务建模。订单系统至少包含订单主数据、订单明细、订单状态、支付信息、库存冻结记录、履约记录和操作日志。这里最重要的是识别谁是事实来源:订单状态以订单服务为准,支付结果以支付流水和通道回调为准,库存可售数量以库存服务和数据库条件更新为准。

第二阶段是主链路。创建订单时,先做请求幂等,防止用户重复提交。然后校验商品、价格、地址等信息,再冻结库存。库存冻结成功后创建订单并生成待支付状态。支付成功后,订单状态从待支付流转到已支付,再触发履约或出库。每一步都要有状态机约束,避免乱序事件把订单推进到非法状态。

第三阶段是一致性设计。单体阶段可以用本地事务覆盖订单和库存,但微服务后不能跨服务随便用强事务。我的倾向是库存冻结和订单创建保持短事务,跨服务用可靠消息最终一致性。支付成功后发送领域事件,下游库存、履约、通知各自消费。消费者必须幂等,失败进入重试和死信。

第四阶段是性能和可用性。订单主链路要短,外部物流、短信、邮件这类调用不能阻塞主链路。读多的订单列表可以做缓存或读模型,但订单详情和资金相关字段要回源数据库。高峰期用 Gateway(网关)限流、线程池隔离、MQ(消息队列)削峰,保护订单核心写链路。

第五阶段是可观测和运维。每笔订单必须能按 orderNo(订单号)和 TraceId(链路标识)追踪完整链路。指标上看下单成功率、库存冻结失败率、支付回调延迟、履约创建失败率、MQ(消息队列)积压量。出现故障时,可以通过补偿任务重新推进状态。

项目结合版

结合 WMS(仓储管理系统)和跨境物流,我会把订单链路拆成订单、库存、履约、物流、支付几个边界。比如跨境订单支付成功后,不是同步调用所有物流渠道,而是先落订单状态,再发履约事件。面单拉取、轨迹同步、清关状态回传都走异步任务和 MQ(消息队列),避免第三方接口慢导致订单主链路超时。库存侧通过冻结库存和超时释放保证不超卖,支付侧通过 Webhook(回调通知)幂等和对账保证资金正确。

防守追问

  • 追问:为什么不用一个大事务把订单、库存、支付都包起来? 因为支付通道和物流系统是外部系统,不受本地事务控制。强行包大事务会导致长事务、锁等待和可用性下降。更合理的是核心状态本地事务保证,跨服务通过可靠消息、幂等和补偿保证最终一致。

  • 追问:订单状态乱序怎么办? 用状态机限制流转,事件里带版本号或状态前置条件。比如已取消订单收到支付成功事件时不能直接改为已支付,需要进入异常补偿或人工处理。

  • 追问:订单查询很慢怎么办? 先看 SQL(结构化查询语言)和索引,再看分页方式、冷热数据、读写分离和搜索读模型。不能一上来就分库分表。

9.2 如何设计库存防超卖?

30 秒简答版

库存防超卖我会分成性能层和正确性层。Redis(远程字典服务)可以做热点库存预扣和削峰,但 MySQL(关系型数据库)条件更新必须作为最终兜底,保证库存不会扣成负数。同时要有请求幂等、库存冻结、支付超时释放、MQ(消息队列)补偿和库存对账。

2 分钟标准版

库存防超卖的核心目标有三个:不超卖、扛峰值、可恢复。单纯用 synchronized(同步锁)或 Redis(远程字典服务)锁都不够,因为系统可能多实例部署,锁可能过期,服务可能重启,消息可能延迟。

我的设计通常是:入口层先做限流和幂等,避免重复提交。库存热点比较明显时,可以用 Redis(远程字典服务)做预扣,利用 Lua(脚本语言)脚本保证判断和扣减的原子性。但 Redis(远程字典服务)不是最终事实来源,真正落库时,MySQL(关系型数据库)要使用条件更新,比如 available_stock >= count 才允许冻结库存。

下单时不是直接扣真实库存,而是冻结库存。支付成功后确认扣减,支付超时或订单取消后释放冻结库存。这样可以把下单和支付之间的不确定性管理起来。

异常方面,如果 Redis(远程字典服务)扣成功但数据库冻结失败,要回滚 Redis(远程字典服务)预扣或进入补偿;如果订单创建成功但支付超时,要释放冻结;如果 MQ(消息队列)通知失败,要靠本地消息表或补偿任务重发。最后通过库存对账校验 Redis(远程字典服务)库存、数据库可售库存、冻结库存和订单状态是否一致。

5 分钟深挖版

库存防超卖不能只看扣减那一行代码,要看完整生命周期。

第一,库存模型要清楚。通常至少有总库存、可售库存、冻结库存、已售库存。下单时从可售转冻结,支付成功从冻结转已售,取消或超时从冻结退回可售。这样状态清楚,异常可补偿。

第二,并发扣减要有底线。数据库层用条件更新是最后防线,例如 update stock set available = available - ?, frozen = frozen + ? where sku_id = ? and available >= ?。这能保证即使上层缓存或锁失效,数据库也不会扣成负数。

第三,Redis(远程字典服务)解决的是性能问题,不是唯一正确性来源。热点 SKU(库存单位)下,所有请求直接打数据库会造成锁竞争,所以用 Redis(远程字典服务)预扣削峰。但要考虑 Redis(远程字典服务)和数据库不一致,所以必须有对账和补偿。

第四,幂等非常重要。用户重复点击、接口重试、MQ(消息队列)重复消费都会导致重复扣减风险。每个库存冻结请求要有业务唯一键,比如 orderNo(订单号)和 skuId(库存单位标识)组合,重复请求直接返回已有结果。

第五,失败路径要完整。库存冻结成功但订单创建失败,要释放冻结;订单创建成功但支付失败,要超时释放;支付成功但库存确认失败,要进入异常状态并告警;补偿任务必须可重入,不能补偿一次失败就丢。

项目结合版

在 WMS(仓储管理系统)里,多仓库存比单仓更复杂。架构上我会以 skuId(库存单位标识) + warehouseId(仓库标识) 作为库存维度,库存服务统一对外提供冻结、确认、释放接口。跨境物流订单如果涉及多个仓库,还要在订单层先确定履约仓,再冻结对应仓库库存。库存变更都写操作流水,方便对账和问题追踪。

防守追问

  • 追问:只用 Redis(远程字典服务)扣库存可以吗? 不建议。Redis(远程字典服务)适合挡流量,但核心库存要可审计、可恢复,最终事实来源应在数据库或库存中心。

  • 追问:数据库条件更新会不会扛不住? 热点场景会有压力,所以用 Redis(远程字典服务)预扣、限流、队列削峰减少数据库写压力。但数据库条件更新仍然是最终正确性兜底。

  • 追问:如何发现库存不一致? 通过库存流水、订单状态、冻结记录、Redis(远程字典服务)缓存和数据库库存做定时对账,发现差异后自动补偿或人工介入。

9.3 如何设计支付资金一致性?

30 秒简答版

支付系统我会把资金正确性放在第一优先级。核心设计是支付流水唯一、Webhook(回调通知)验签、防重放、通道事件 ID(标识)幂等、状态机流转、MQ(消息队列)通知下游,以及对账和补偿兜底。

2 分钟标准版

支付一致性不能只依赖第三方回调成功。第三方支付通道可能重复回调、延迟回调、乱序回调,也可能主动查询和回调结果同时到达。所以我会先设计支付流水表,每次支付请求生成唯一支付流水号,记录订单号、金额、币种、通道、状态和请求响应。

回调进来后,第一步验签,确认消息确实来自支付通道;第二步防重放,检查时间戳和随机串;第三步做幂等,用通道事件 ID(标识)或支付流水号加唯一索引,重复回调直接返回成功;第四步按状态机推进支付状态,比如待支付只能变为支付成功或支付失败。

支付成功后,不建议同步调用库存、订单、账务所有系统,而是先在本地事务里更新支付流水和订单支付状态,再发 MQ(消息队列)事件,下游各自消费。消费者必须幂等,失败进入重试和死信。

最后一定要有对账。因为外部支付通道不可控,回调丢失或延迟时,只靠回调会漏单。每日或定时拉取通道账单,对比本地支付流水,发现差异后生成补偿任务。

5 分钟深挖版

支付资金一致性可以分成三层。

第一层是请求一致性。支付发起时要保证同一订单不会重复创建多个有效支付单。可以通过订单号和支付场景生成幂等键,如果用户重复点击支付,返回同一笔待支付流水,而不是重复下单。

第二层是回调一致性。Webhook(回调通知)必须验签、防重放和幂等。验签保证来源可信,防重放避免旧消息被再次提交,幂等保证重复回调不会重复推进业务。状态机是关键,比如已成功的支付不能被失败回调覆盖,退款状态也不能随意回退。

第三层是跨系统一致性。支付成功后,订单、库存、账务、通知都要感知。但这里不适合长事务。更合理的是本地事务更新支付状态,并写本地消息表或发送可靠消息。下游消费时按业务键幂等,失败重试,超过次数进入死信和人工处理。

对账是最终防线。资金系统一定要承认“回调不可靠”。对账会比较通道账单、本地支付流水、订单状态和账务记录。差异分几类:通道成功本地失败、本地成功通道失败、金额不一致、重复记录。每类差异都有补偿策略和审计记录。

项目结合版

如果是跨境支付,还会有 Stripe(国际支付网关)、PayPal(国际支付平台)、Airwallex(空中云汇)等多个通道。架构上我会抽象统一支付单和通道适配层,每个通道的 Webhook(回调通知)验签逻辑独立,但最终都转换成统一支付事件。账务侧不直接相信回调,而是以支付流水和对账结果为准。

防守追问

  • 追问:为什么重复回调要返回成功? 因为对支付通道来说,只要我们已经处理过这条事件,就应该返回成功,避免通道继续重试造成压力。但内部不能重复执行业务。

  • 追问:回调成功但 MQ(消息队列)发送失败怎么办? 用本地消息表或 Outbox Pattern(发件箱模式),本地事务先保存待发送事件,再由后台任务可靠投递。

  • 追问:对账发现通道成功但本地失败怎么办? 生成补偿任务,重新推进本地支付状态和下游事件,同时保留审计日志。

9.4 如何设计跨境物流履约系统?

30 秒简答版

跨境物流履约系统要把外部不稳定性隔离出去。订单主链路只创建履约任务,面单拉取、轨迹同步、清关状态、签收回传都异步处理。核心是状态机、幂等、重试退避、死信补偿和全链路 TraceId(链路标识)。

2 分钟标准版

跨境物流的特点是链路长、外部系统多、接口不稳定、状态延迟明显。所以我不会把物流接口都同步放在订单主链路里。订单支付成功后,订单服务发送履约事件,履约服务创建履约单,再异步调用物流渠道生成面单。

面单拉取这种外部调用要有独立线程池、超时、限流和重试退避,避免某个物流渠道慢把整个系统拖垮。轨迹同步可以接收外部推送,也可以定时拉取,进入 MQ(消息队列)后由消费者幂等写入。轨迹状态必须有状态机,比如已签收后不能再回到运输中,乱序轨迹要能合并。

查询侧可以把物流轨迹同步到 Elasticsearch(搜索引擎)提升搜索体验,但物流主状态还是以数据库记录为准。异常件、清关失败、面单失败要进入可视化补偿队列,让运营可以介入。

5 分钟深挖版

我会把跨境物流履约拆成几个子域:履约单、面单、轨迹、异常件、渠道适配、通知。

履约单是内部状态核心,记录订单、仓库、物流渠道、履约状态和异常原因。面单服务负责和外部渠道交互,但通过适配器隔离不同渠道差异。轨迹服务负责接收推送、拉取轨迹、去重和状态合并。异常件服务负责清关失败、地址异常、退件等人工介入流程。

数据一致性上,订单支付成功到履约创建可以用 MQ(消息队列)最终一致性,履约创建失败可以重试。面单生成失败不能让订单状态丢失,而是让履约单进入待重试或异常状态。轨迹重复和乱序通过业务唯一键和状态机解决。

稳定性上,每个物流渠道都要单独限流、熔断和降级。比如某渠道 RT(响应时间)突然变高,只影响该渠道任务,不影响其他渠道。线程池也按渠道或任务类型隔离。

可观测性上,每个履约单要能看到订单、面单请求、渠道响应、轨迹节点、失败重试和人工处理记录。否则跨境物流问题排查会非常困难。

项目结合版

结合跨境物流项目,我会强调“外部系统不可靠是常态”。所以方案不是追求一次调用成功,而是设计可重试、可补偿、可追踪的履约链路。面单拉取失败不影响订单主状态,轨迹延迟不影响支付状态,清关异常进入运营处理队列。

防守追问

  • 追问:物流轨迹乱序怎么办? 用状态机和轨迹时间排序,低优先级旧状态不能覆盖高优先级新状态,同时保留原始轨迹用于审计。

  • 追问:某个物流渠道大面积超时怎么办? 对该渠道熔断和限流,任务进入延迟重试,必要时切换备用渠道或人工处理,不让它拖垮全局线程池。

  • 追问:为什么要引入 MQ(消息队列)? 因为履约链路长且外部不稳定,MQ(消息队列)可以削峰、解耦、重试和承载最终一致性。

9.5 如何设计 IoT(物联网)报警治理系统?

30 秒简答版

IoT(物联网)报警治理的核心不是简单限流,而是降噪同时保留重要报警。架构上接入层限流,MQ(消息队列)削峰,处理层按设备、报警类型和时间窗口聚合,Redis(远程字典服务)做短期计数和去重,严重报警穿透通知,普通重复报警降噪。

2 分钟标准版

IoT(物联网)报警风暴一般发生在设备异常、网络抖动或规则配置错误时,短时间内大量重复报警会打爆消息队列和通知渠道。设计时我会先区分报警等级:严重报警不能丢,普通报警可以聚合和降噪。

接入层做基础限流和格式校验,避免脏数据进入系统。然后通过 MQ(消息队列)削峰,让处理服务按能力消费。处理层按 deviceId(设备标识) + alarmCode(报警编码) + window(时间窗口) 做聚合 key(键),Redis(远程字典服务)保存窗口计数、首次报警时间和最近报警时间。

通知层按等级路由。严重报警可以短信、电话或企业微信多渠道通知;普通重复报警只更新计数,不重复刷屏。数据库保存最终报警事件和聚合结果,便于后续复盘。

5 分钟深挖版

报警治理要同时解决实时性、准确性和噪声控制。

第一,接入层要做限流和鉴权,防止单设备或异常网关打爆系统。限流不能一刀切,严重报警要有更高优先级。

第二,处理层要有聚合模型。单条报警事件是原始事实,聚合报警是面向人的处理对象。比如 1 分钟内同一设备同一报警上报 100 次,系统不应该通知 100 次,而是生成一个聚合报警,记录次数、首次时间、最后时间和影响范围。

第三,规则层要支持分级和抑制。比如同一设备离线后,后续传感器异常可能都是派生报警,可以被抑制或合并,避免报警风暴。

第四,存储层要区分热数据和历史数据。近期报警用于实时处置,历史报警用于报表和模型优化。

第五,可观测性非常重要。要监控报警接入量、丢弃量、聚合率、通知成功率、MQ(消息队列)积压、Redis(远程字典服务)命中和处理延迟。

项目结合版

结合 IoT(物联网)报警风暴治理,我会说重点不是“把报警挡掉”,而是保证关键报警到人、重复报警降噪、异常高峰系统不崩。架构上用 MQ(消息队列)削峰,用 Redis(远程字典服务)做窗口聚合,用规则引擎做分级抑制,用告警指标判断是否发生风暴。

防守追问

  • 追问:限流会不会丢掉重要报警? 所以要分级限流。高等级报警走优先通道,低等级重复报警才聚合或降噪。

  • 追问:Redis(远程字典服务)宕机怎么办? Redis(远程字典服务)用于短期聚合状态,不是最终事实来源。宕机时可以退化为直接落库和降低通知频率,恢复后继续聚合。

  • 追问:如何衡量治理效果? 看报警聚合率、重复通知下降比例、严重报警到达率、处理时延和人工误报反馈。

9.6 如何做技术选型?

30 秒简答版

技术选型我不会从技术偏好出发,而是从业务目标、数据规模、一致性、性能、可用性、成本、团队能力和演进风险做判断。好的选型不是最先进,而是当前阶段最合适、团队能掌控、未来能演进。

2 分钟标准版

我做技术选型会先明确业务问题。比如是交易一致性问题、查询性能问题、削峰解耦问题,还是可观测性问题。然后看规模和约束:数据量多大、峰值多少、是否强一致、团队是否有运维经验、上线周期多紧。

然后列候选方案做对比。比如订单主数据,MySQL(关系型数据库)适合,因为有事务、约束和审计;Elasticsearch(搜索引擎)适合搜索,但不适合做交易主库。再比如消息队列,Kafka(分布式日志消息系统)适合高吞吐日志流,RocketMQ(分布式消息队列)更适合交易消息和事务消息。

最后我会给出阶段性方案。早期不要过度设计,先用简单可靠方案;等规模和复杂度上来,再演进到分库分表、搜索读模型或事件驱动架构。

5 分钟深挖版

技术选型本质是约束下的决策。

第一维是业务匹配。比如支付资金状态必须可审计,所以优先数据库事务和对账,而不是只放缓存。

第二维是数据规模。百万级数据和百亿级数据的存储方案不同,日写入 1 万和日写入 1 亿的消息系统也不同。

第三维是一致性。强一致场景要谨慎引入异步,最终一致场景可以用 MQ(消息队列)提高可用性和吞吐。

第四维是团队能力。团队没有 Kubernetes(容器编排平台)经验时,不一定要一上来做复杂云原生架构;否则故障时没人能救。

第五维是迁移风险。架构师要考虑从当前方案迁移到未来方案的路径,比如先单库,后续按租户或订单号分片;先 MySQL(关系型数据库)查询,后续同步 Elasticsearch(搜索引擎)做搜索。

项目结合版

在跨境物流系统里,我不会把所有轨迹都塞进订单表。订单主状态用 MySQL(关系型数据库),轨迹检索可以同步 Elasticsearch(搜索引擎),大规模报表可以进 ClickHouse(列式数据库)。这不是为了堆技术,而是因为主交易、搜索、分析的访问模式不同。

防守追问

  • 追问:为什么不用最新技术? 技术新不等于适合。架构师要对稳定性、团队能力和运维成本负责。

  • 追问:选型错了怎么办? 先控制影响范围,保留数据迁移和接口抽象,分阶段切换,用灰度验证新方案。

  • 追问:如何说服团队接受选型? 用数据和对比矩阵说明收益、风险和落地成本,而不是靠个人偏好。

9.7 如何设计高可用系统?

30 秒简答版

高可用不是只做多副本,而是从入口限流、服务隔离、超时重试、熔断降级、数据容灾、消息削峰、监控告警和应急预案形成体系。核心目标是局部失败不扩散,关键链路可恢复。

2 分钟标准版

设计高可用系统,我会先识别核心链路和非核心链路。比如订单创建、库存扣减、支付状态是核心链路,通知、报表、推荐可以降级。然后在入口层做限流和鉴权,服务层做线程池隔离和熔断,调用层设置超时和重试退避,数据层做主从、备份和容量治理,异步层用 MQ(消息队列)削峰。

高可用还要设计失败路径。下游接口慢时不能无限等待,缓存不可用时要能回源或降级,MQ(消息队列)积压时要限速和扩容,数据库压力高时要保护核心写链路。

最后必须有可观测性。没有 Log(日志)、Metrics(指标)、Trace(链路追踪)和告警,高可用只停留在架构图上。

5 分钟深挖版

高可用可以分为预防、隔离、恢复三个层次。

预防层包括容量评估、压测、限流、缓存、异步化和代码质量。比如上线前要知道核心接口峰值 QPS(每秒查询率)、线程池容量、数据库连接池上限。

隔离层包括服务隔离、线程池隔离、数据隔离和故障域隔离。一个物流渠道慢,不应该拖垮所有渠道;一个报表任务慢,不应该影响支付回调。

恢复层包括熔断、降级、重试退避、补偿、灰度回滚和应急开关。重试要谨慎,立即重试可能放大故障,所以要指数退避和最大次数。

数据层高可用还要看一致性。读多场景可以读写分离,但支付和库存的核心写必须保证正确性。跨机房多活更复杂,要考虑数据冲突和流量切换。

项目结合版

在 WMS(仓储管理系统)和跨境物流里,我会把订单、支付、库存放在核心保护层;轨迹同步、通知、报表放在可降级层。外部物流渠道用独立线程池和熔断策略,失败任务进入补偿队列。这样外部系统故障不会拖垮核心交易链路。

防守追问

  • 追问:多副本是不是就高可用? 不是。多副本解决实例故障,但不能解决慢依赖、重试风暴、数据库瓶颈和数据不一致。

  • 追问:降级会不会影响用户体验? 会影响部分体验,但比全站不可用更好。关键是明确哪些可降级,哪些不能降级。

  • 追问:如何验证高可用设计有效? 通过压测、故障演练、灰度发布、监控指标和复盘验证。

9.8 如何处理分布式事务?

30 秒简答版

分布式事务我会先判断是否真的需要强一致。单服务优先本地事务;跨服务但能接受最终一致,用可靠消息和补偿;强一致且业务允许复杂度时,才考虑 TCC(Try Confirm Cancel,尝试确认取消)或事务框架;外部支付这类不可控系统最终靠对账兜底。

2 分钟标准版

处理分布式事务不能只说用 Seata(分布式事务框架)。我会先看业务一致性要求。如果订单和订单明细在同一个服务内,用本地事务最简单可靠。如果订单、库存、支付拆成多个服务,就要避免长事务。

常见方案有几类:可靠消息最终一致性适合订单支付成功后通知库存、履约、积分;TCC(Try Confirm Cancel,尝试确认取消)适合强一致资源预留,比如库存冻结;最大努力通知适合外部支付回调;SAGA(长事务模式)适合长流程业务,每一步都有补偿。

我更关注失败路径。消息发送失败怎么办,消费者重复消费怎么办,Confirm(确认)成功 Cancel(取消)又来了怎么办,补偿失败怎么办。这些问题不解决,选什么框架都不稳。

5 分钟深挖版

分布式事务的核心是跨边界状态一致。越过服务、数据库或外部系统边界后,本地 ACID(原子性、一致性、隔离性、持久性)事务就不够了。

可靠消息最终一致性的关键是本地事务和消息投递绑定。可以用本地消息表或 Outbox Pattern(发件箱模式):业务数据和待发送消息在同一个本地事务里落库,后台任务再可靠投递 MQ(消息队列)。消费者幂等处理,失败重试,最终通过死信和补偿兜底。

TCC(Try Confirm Cancel,尝试确认取消)的关键是资源预留。Try(尝试)阶段冻结资源,Confirm(确认)阶段确认使用,Cancel(取消)阶段释放资源。它一致性强,但开发成本高,每个参与方都要实现三套接口,还要处理空回滚、悬挂和幂等。

SAGA(长事务模式)适合长链路流程,比如跨境物流履约,每一步完成后提交,失败后按反向补偿。但它是业务补偿,不是数据库回滚。

外部支付系统无法纳入本地事务,因此必须用回调幂等、主动查询、对账和补偿保证最终正确。

项目结合版

在支付资金一致性里,我不会把支付通道、订单、库存放进一个强事务。支付流水本地事务先保证正确,支付成功事件通过 MQ(消息队列)通知订单和库存。库存冻结适合 TCC(Try Confirm Cancel,尝试确认取消)的思想,支付通道适合最大努力通知和对账。

防守追问

  • 追问:Seata(分布式事务框架)能解决所有问题吗? 不能。它有适用边界,引入后也有性能、锁、回滚和运维复杂度。外部支付通道这类系统也不受它控制。

  • 追问:最终一致性会不会丢数据? 设计正确不会。关键是本地消息表、消费者幂等、重试死信、补偿和对账。

  • 追问:如何处理补偿失败? 补偿任务要有状态、重试次数、告警和人工介入入口,不能静默失败。

9.9 如何做灰度发布?

30 秒简答版

灰度发布的核心是控制影响范围。可以按用户、租户、仓库、版本或流量比例灰度,通过 Gateway(网关)、配置中心和服务路由控制入口,同时观察错误率、RT(响应时间)、QPS(每秒查询率)和业务指标,异常时快速回滚。

2 分钟标准版

我做灰度发布会先明确灰度对象和回滚策略。比如按内部账号、指定租户、指定仓库或 1% 流量开始。入口层可以通过 Gateway(网关)识别用户或租户标签,把流量路由到新版本。配置类功能可以通过 Config Center(配置中心)开关控制。

灰度期间要重点看技术指标和业务指标。技术指标包括错误率、RT(响应时间)、CPU(中央处理器)、内存、线程池、数据库慢 SQL(结构化查询语言)。业务指标包括下单成功率、支付成功率、库存冻结失败率、履约任务失败率。

数据库变更要特别谨慎。涉及表结构变化时,要兼容新老版本,通常先加字段、双写或兼容读,再切流量,最后清理旧逻辑,不能让新老版本互相不兼容。

5 分钟深挖版

灰度发布可以分为发布前、发布中、发布后三个阶段。

发布前,要做风险评估和回滚预案。哪些接口受影响,是否有数据库变更,是否有消息格式变更,是否影响第三方接口。高风险变更要加开关。

发布中,先小范围验证。比如内部用户、单个租户、单个仓库或少量流量。灰度规则要可配置,不能写死在代码里。监控要实时看,发现异常自动或人工暂停。

发布后,不是马上全量,而是逐步扩大范围。每一步都要观察一段时间。全量后仍要保留回滚窗口。

最难的是有状态变更,比如订单状态机、支付流程、消息格式和数据库结构。这类变更要遵循向前兼容和向后兼容。比如先发布兼容旧字段和新字段的代码,再做数据迁移,最后移除旧字段。

项目结合版

在 WMS(仓储管理系统)里,灰度可以按仓库维度做,比如先让一个非核心仓库使用新的库存冻结逻辑,观察库存冻结成功率、订单取消率、人工补偿数量。跨境物流可以按渠道灰度,先切一个物流渠道或一个国家线路,避免影响全部订单。

防守追问

  • 追问:灰度期间数据结构不兼容怎么办? 做双版本兼容。先加字段,不删字段;新老代码都能读写;确认稳定后再清理。

  • 追问:如何自动判断要不要回滚? 设定错误率、RT(响应时间)、核心业务成功率阈值,超过阈值自动暂停或回滚。

  • 追问:配置灰度和流量灰度有什么区别? 配置灰度控制功能开关,流量灰度控制请求路由,实际项目常组合使用。

9.10 如何证明你具备架构师思维?

30 秒简答版

我会从三个方面证明:第一,我能从业务目标和约束出发设计方案;第二,我能讲清技术取舍、风险和兜底;第三,我能推动方案落地,并通过指标、灰度和复盘持续演进。

2 分钟标准版

我理解架构师思维不是会很多技术名词,而是能把复杂业务问题拆成可落地的技术方案。比如面对库存防超卖,我不会只说用 Redis(远程字典服务)锁,而是先明确目标是不超卖、扛峰值、可恢复,然后设计 Redis(远程字典服务)预扣、MySQL(关系型数据库)条件更新、库存冻结、幂等、补偿和对账。

第二,我会主动讲取舍。比如微服务能提升独立部署和扩展能力,但会带来分布式事务、链路追踪和运维复杂度;MQ(消息队列)能削峰解耦,但会带来重复消费、顺序和积压问题。

第三,我会考虑落地。方案不只是图,还包括阶段计划、接口契约、监控指标、灰度发布、回滚预案和复盘机制。

5 分钟深挖版

架构师思维可以体现在四个层次。

第一是问题定义能力。很多技术问题表面上是性能或并发,背后可能是业务流程、数据模型或团队协作问题。架构师要先把问题定义清楚。

第二是系统性设计能力。方案要覆盖主链路、异常链路、补偿链路和运维链路。比如支付系统不仅要处理成功,还要处理重复回调、延迟回调、退款、对账差异和人工补偿。

第三是取舍能力。没有绝对完美方案。强一致会增加复杂度,高可用可能牺牲一致性,低成本可能限制扩展性。架构师要讲清为什么当前阶段这么选,以及未来怎么演进。

第四是落地和治理能力。架构师要能推动团队执行,通过规范、评审、监控、灰度和复盘让方案持续有效,而不是写完设计文档就结束。

项目结合版

我可以用三个项目证明:库存防超卖体现一致性和高并发取舍;支付资金一致性体现幂等、状态机、对账和审计;IoT(物联网)报警风暴治理体现削峰、降噪、分级和可观测性。这些不是单点技术,而是从业务风险出发设计完整闭环。

防守追问

  • 追问:你是不是只是高级开发,还不是架构师? 我会承认架构师能力是持续演进的,但我已经在项目中承担过方案设计、技术选型、风险兜底和跨模块协作,不只是完成单个功能开发。

  • 追问:你做过最大的架构取舍是什么? 可以回答库存或支付场景:没有追求全链路强一致,而是把核心正确性放在数据库和状态机,其他链路用最终一致和补偿,平衡了性能和可靠性。

  • 追问:如何衡量架构方案成功? 看业务指标和技术指标是否改善,比如成功率、故障率、RT(响应时间)、人工补偿量、成本和交付效率。

10. 精通级分册入口与学习路线

本节为新增导航入口,旧根上方内容完整保留。新增分册负责把旧题扩展为“约束、反例、容量、成本、恢复、组织治理”的深度追问,不替代旧根快速复习。

10.1 分册索引

顺序分册核心训练正式图
00旧资产映射与架构追问路线映射旧根题目、事实等级、追问路线和学习顺序PlantUML(开源建模工具) / PNG(便携式网络图形)
01需求约束边界与反例追问把模糊需求拆成对象、动作、范围、量级、不变量和反例PlantUML(开源建模工具) / PNG(便携式网络图形)
02一致性、可用性、容量与成本权衡追问训练 CAP(一致性、可用性、分区容错)、BASE(基本可用、软状态、最终一致)、容量、预算和失败成本PlantUML(开源建模工具) / PNG(便携式网络图形)
03故障域恢复演练与演进追问训练 RPO(恢复点目标)、RTO(恢复时间目标)、容灾、恢复门禁和事故复盘PlantUML(开源建模工具) / PNG(便携式网络图形)
04项目架构评审口述与交叉追问把 WMS(仓储管理系统)、支付、履约、导出、Runner(执行器)、IoT(物联网)和跨境物流串成评审口述PlantUML(开源建模工具) / PNG(便携式网络图形)

10.2 使用顺序

第一轮按 00 -> 01 -> 02 -> 03 -> 04 学习:先建立旧题映射和事实边界,再训练需求反例,然后进入一致性、容量、成本、故障恢复,最后把项目串讲成架构评审表达。

第二轮按面试题倒推:

  • 问“怎么做架构设计”:读 0104
  • 问“为什么这样取舍”:读 02
  • 问“出故障怎么恢复”:读 03
  • 问“你是否真做过”:先回到 90/00 事实卡,再选项目分册。

10.3 事实边界

回答时统一使用 E1(直接证据)、E2(已有材料映射)、E3(演练设计)、E0(待核对)标注事实强度。没有源码、监控、账单、工单或简历直接证据时,不把容量、收益、事故结果和上线范围说成生产事实。

10.4 自检清单

  • 能把每个架构题拆成业务目标、硬约束、软约束、偏好和不可做清单。
  • 能用反例验证方案,而不是只画正常链路。
  • 能同时比较建设成本、运行成本、失败成本和退出成本。
  • 能说明何时回滚、何时前向修复、何时停止演进。
  • 能把项目事实和 E3(演练设计)数字分开表达。