架构模式与系统设计方法论

共 86 题
📑 题目列表 86 题
#
★★★

1. ACID 与 BASE 的取舍

请说明 ACID 与 BASE 的取舍?

  • ACID 的强一致性
  • BASE 的最终一致性
  • 取舍

ACID(原子性、一致性、隔离性、持久性)保证数据库事务的强一致性,适合对一致性要求高的场景(金融、账务);BASE(基本可用、软状态、最终一致性)放宽一致性,追求可用性与性能,适合分布式、高并发场景(社交、缓存)。取舍:ACID 强一致但性能与扩展性受限;BASE 高可用、可扩展但允许短暂不一致。按业务对一致性与可用性的要求选择,关键业务用 ACID,非关键高并发用 BASE。

ACID 与 BASE 是"强一致 vs 最终一致"的权衡。一致性要求与可用性/性能的平衡决定取舍。

#
★★★

2. Bulkhead 模式与 Resilience4j 线程池隔离在多租户 SaaS 平台的资源配额设计

请说明 Bulkhead 模式与 Resilience4j 线程池隔离在多租户 SaaS 平台的资源配额设计?

  • Bulkhead 隔离
  • 线程池隔离
  • 多租户配额

Bulkhead(舱壁)模式把资源按场景隔离,避免单一故障拖垮整体。Resilience4j 的线程池隔离(ThreadPoolBulkhead)为不同调用分配独立线程池,隔离故障域。多租户 SaaS 中,用 Bulkhead 为每个租户/关键路径分配独立线程池与隔离,实现资源配额:一个租户的慢调用/高负载不影响其他租户。设计时按租户的配额(QPS、并发)分配隔离容量,超配的租户被隔离限流,保证公平与可用性。

Bulkhead 隔离是"故障域隔离",多租户用隔离实现配额与公平。线程池隔离是其中一个实现。

#
★★★

3. Bulkhead 模式在 Resilience4j 与 Spring Cloud Gateway 中的线程池隔离与信号量隔离选型

请说明 Bulkhead 模式在 Resilience4j 与 Spring Cloud Gateway 中线程池隔离与信号量隔离的选型?

  • 线程池隔离
  • 信号量隔离
  • 选型

Resilience4j 与 Spring Cloud Gateway 的 Bulkhead 支持两种隔离:线程池隔离(ThreadPoolBulkhead)为每个调用分配独立线程池,隔离彻底但开销大(线程);信号量隔离(SemaphoreBulkhead)限制并发数,不换线程,开销小但隔离不彻底(共享线程池)。选型:对"慢调用、耗时不确定"的调用用线程池隔离(彻底隔离);对"快速、并发受限"的调用用信号量隔离(轻量)。Spring Cloud Gateway 的 filter 通常用信号量隔离,因其请求处理轻量。

线程池隔离彻底但重,信号量隔离轻但弱。按调用耗时与隔离需求选型。

#
★★★

4. CAP 定理与 BASE 理论

请说明 CAP 定理与 BASE 理论?

  • CAP 的 C/A/P
  • 分区下的取舍
  • BASE 的最终一致

CAP 定理指出分布式系统在分区(P)发生时,只能在一致性(C)与可用性(A)之间二选一。BASE 理论(基本可用、软状态、最终一致)是 CAP 在实践中的取向:优先可用性,允许短暂不一致,最终达到一致。工程上,多数分布式系统在分区时选择 AP(可用性优先),通过最终一致性(事件、补偿)收敛。CAP 是"分区时二选一"的约束,BASE 是"最终一致"的工程策略。

CAP 是分布式一致性的边界,BASE 是"最终一致"的策略。理解"分区时 C/A 二选一"是核心。

#
★★★

5. CQRS + Event Sourcing 在金融交易系统中的读写模型分离与最终一致性权衡

请说明 CQRS + Event Sourcing 在金融交易系统中的读写模型分离与最终一致性权衡?

  • CQRS 读写分离
  • Event Sourcing 事件溯源
  • 最终一致性

金融系统用 CQRS + Event Sourcing:写模型处理命令(交易),读模型提供查询(报表、余额),读写模型分离。Event Sourcing 用事件记录交易变化,可重放、可审计。权衡:写模型与读模型最终一致(读模型异步更新),存在短暂不一致窗口;金融对一致性要求高,需通过事件回放、幂等、补偿保证最终一致,并权衡"读模型延迟"与"强一致需求"。关键交易(扣款)用强一致,报表查询用最终一致。

CQRS 分离读写,Event Sourcing 提供可审计事件,最终一致是权衡点。金融关键操作需补偿与幂等。

#
★★★

6. CQRS 分离读写模型后会引入多长的最终一致窗口,产品体验与监控应如何表达这种延迟

CQRS 分离读写模型后会引入多长的最终一致窗口,产品体验与监控应如何表达这种延迟?

  • 最终一致窗口
  • 产品体验
  • 监控

CQRS 分离读写后,读模型通过事件异步更新,引入"最终一致窗口"(写生效到读可见的延迟),其长度取决于事件传播、处理与存储延迟。产品体验上应表达这种延迟:向用户提示"操作已提交,稍后可见",或提供"读己之写"(读操作优先读写模型或带版本校验)。监控上应度量读模型滞后(lag),用指标(读模型延迟、未同步事件数)监控,超过阈值告警。明确表达一致窗口,避免用户困惑。

一致窗口是异步读模型的固有延迟,需产品提示与监控度量滞后,避免体验与数据误解。

#
★★★

7. CQRS 架构中读模型与写模型的最终一致性在 Kafka 事件溯源下的延迟补偿策略

请说明 CQRS 架构中读模型与写模型的最终一致性在 Kafka 事件溯源下的延迟补偿策略?

  • Kafka 事件溯源
  • 读模型构建
  • 延迟补偿

CQRS 中读写模型通过 Kafka 事件同步:写模型把事件写入 Kafka,读模型消费事件构建查询视图。延迟补偿策略:用 Kafka 的消费组保证事件顺序与偏移管理,读模型落后时通过增量同步追上;消费失败用重试/死信队列补偿;对读模型滞后,可用"读己之写"(读模型消费时记录版本,读请求校验)或临时呈现写模型结果。核心是保证事件不丢失、顺序一致、追上滞后,维持最终一致。

Kafka 事件溯源下,读模型滞后用增量追上、重试/死信补偿、读己之写缓解,保证最终一致。

#
★★★

8. CQRS 的读写模型分离边界

请说明 CQRS 的读写模型分离边界?

  • 读写模型分离
  • 边界
  • 适用场景

CQRS 的读写模型分离边界:写模型处理命令(Update),负责业务规则与一致性;读模型处理查询(Query),针对查询优化(不同表结构、投影、缓存)。边界在于"读写访问路径与数据模型分离"——写按业务建模,读按查询建模。分离的边界是"命令与查询的访问方式不同",而非简单拆两个表。适用场景:读多写少、读写复杂度差异大、查询需求多变。简单 CRUD 不必用 CQRS(过度设计)。

CQRS 边界是"读写访问路径与模型分离",按查询需求优化读模型。简单 CRUD 不需 CQRS。

#
★★★

9. CQRS(命令查询职责分离)与 Event Sourcing

请说明 CQRS(命令查询职责分离)与 Event Sourcing 的关系?

  • CQRS 读写分离
  • Event Sourcing 事件溯源
  • 组合

CQRS 是命令查询职责分离:把写操作(命令)与读操作(查询)分离为不同模型与路径。Event Sourcing 是事件溯源:用事件序列表达状态变化,状态由事件重放得出。二者常组合:CQRS 的写模型接收命令、产生事件,Event Sourcing 存储事件,读模型从事件构建查询视图。CQRS 关注"读写分离"结构,Event Sourcing 关注"状态由事件表达",组合后写侧事件溯源、读侧投影,可扩展、可审计。二者可独立使用,但组合更常见。

CQRS 管"读写分离",ES 管"事件表达状态",组合实现可审计、可扩展的架构。

#
★★★

10. Cell-based Architecture 如何限制故障爆炸半径,租户路由与跨 Cell 数据访问怎样设计

请说明 Cell-based Architecture 如何限制故障爆炸半径,租户路由与跨 Cell 数据访问怎样设计?

  • Cell 架构
  • 故障爆炸半径
  • 租户路由与跨 Cell

Cell-based Architecture 把系统划分为多个独立 Cell(单元),每个 Cell 是自包含的(计算、存储、基础设施),故障隔离在单个 Cell 内,限制爆炸半径。租户路由:按租户 ID 哈希/映射到特定 Cell,一个租户只路由到所属 Cell,保证数据隔离。跨 Cell 数据访问应避免——设计上每个 Cell 处理自己的租户,跨 Cell 访问会破坏隔离,需要时用全局服务或事件同步。目标是让单个 Cell 故障不影响其他租户。

Cell 架构的核心是"故障隔离 + 租户隔离"。租户路由保证 Cell 自治,跨 Cell 访问是隔离的破坏点。

#
★★★

11. EDA 事件驱动架构在 Outbox 模式、Change Data Capture 与消息中间件协同时的最终一致性工程要点

请说明 EDA 事件驱动架构在 Outbox 模式、Change Data Capture 与消息中间件协同时的最终一致性工程要点?

  • Outbox 模式
  • Change Data Capture
  • 消息中间件协同

EDA 的最终一致性工程要点:Outbox 模式把领域事件与业务变更在同一个本地事务写入 outbox 表,保证"业务变更与事件"原子一致,再由发布器把事件发到消息中间件;Change Data Capture(CDC)通过监听数据库 binlog 捕捉变更,把数据变更转化为事件;二者协同保障事件不丢失、不重复(幂等)。事务出发箱保证原子性,CDC/发布器保证可靠投递,消息中间件保证解耦与最终一致。要点是"本地事务 + 可靠投递 + 幂等消费"。

Outbox 保证原子性,CDC 捕获变更,消息中间件解耦,三者协同支撑最终一致。

#
★★★

12. Outbox Pattern 在 Spring Boot 中与 Debezium CDC 协同的事务一致性保障

请说明 Outbox Pattern 在 Spring Boot 中与 Debezium CDC 协同的事务一致性保障?

  • Outbox 模式
  • Debezium CDC
  • 事务一致性

Outbox Pattern 在 Spring Boot 中:业务事务里同时写入业务表与 outbox 表(事件),保证"业务变更 + 事件"原子提交(同一事务)。Debezium CDC 监听数据库 binlog,捕获 outbox 表的新增事件,把事件转发到 Kafka。协同保障:业务变更与事件要么都成功(本地事务),要么都失败;CDC 保证事件被可靠地捕获并投递,消费端幂等处理。这解决了"双写不一致"(业务与消息中间件无法原子提交)的问题。

Outbox 用本地事务解决"业务+事件原子",Debezium 捕获 outbox 事件投递,保证一致。

#
★★★

13. SOA(面向服务架构)与微服务的差异

请说明 SOA(面向服务架构)与微服务的差异?

  • SOA 的服务粒度
  • 微服务的独立部署
  • 差异

SOA(面向服务架构)强调服务复用与松耦合,通过 ESB(企业服务总线)集成,服务粒度较大、常共享数据库、部署较集中;微服务强调小型、独立部署、按业务能力划分、独立数据库、去中心化。差异:SOA 服务粒度大、依赖 ESB、共享数据;微服务粒度小、独立部署、独立数据、自治。微服务可视为 SOA 的精细化演进,但更强调独立部署与去中心化治理。

SOA 靠 ESB 集成、粒度大,微服务独立部署、自治。粒度与治理模式是核心差异。

#
★★★

14. Saga 与 TCC 的适用边界如何划分,长事务、资源预留成本与补偿可行性如何影响选型

请说明 Saga 与 TCC 的适用边界如何划分,长事务、资源预留成本与补偿可行性如何影响选型?

  • Saga 的补偿
  • TCC 的预留
  • 选型边界

Saga 通过"顺序执行 + 补偿"处理跨服务事务,适合长事务、业务天然可补偿的场景(compensation);TCC 通过 Try/Confirm/Cancel 预留资源,适合需要强资源预留、短事务的场景。选型边界:长事务(耗时、跨服务多)用 Saga,因为补偿灵活;资源预留成本高(如库存、资金)且需保证可用性用 TCC(预留保证不超卖);补偿可行性(业务能否补偿)决定 Saga 是否可行。TCC 预留成本高、实现复杂,Saga 补偿简单但一致性弱。

Saga 适合长事务可补偿,TCC 适合短事务需预留。按事务时长、预留成本、补偿可行性选型。

#
★★

15. CQRS 架构中读写模型分离时,跨模型数据一致性、回填链路与查询性能折衷如何在 Spring/Quarkus 中落地

CQRS 架构中读写模型分离时,跨模型数据一致性、回填链路与查询性能折衷如何在 Spring/Quarkus 中落地?

  • 跨模型一致性
  • 回填链路
  • 查询性能折衷

CQRS 读写分离在 Spring/Quarkus 中落地:跨模型一致性通过事件(命令产生事件 → 读模型消费更新)保证,用 Kafka/事件总线实现;回填链路指读模型重建(从写模型或事件源全量/增量回填),需要幂等与版本管理;查询性能折衷:读模型针对查询优化(物化视图、冗余字段、缓存),牺牲写模型一致性换取查询性能,用最终一致与补偿平衡。Spring 用 @TransactionalEventListener、Quarkus 用 reactive 事件等实现。

跨模型一致性靠事件,回填用幂等重建,查询性能靠读模型优化,最终一致是折衷。

#
★★

16. Saga 模式与分布式事务

请说明 Saga 模式与分布式事务的关系?

  • Saga 的本地事务 + 补偿
  • 分布式事务
  • 替代 2PC

Saga 模式是分布式事务的一种实现:把一个跨服务的大事务拆分为多个本地事务,每个本地事务完成后提交,若某个失败,通过执行补偿事务回滚已完成的步骤。它避免了 2PC 的全局锁与阻塞,通过补偿实现最终一致。Saga 是"无全局锁的分布式事务",适合长事务与最终一致场景。形式有编排式(central orchestrator)与协同式(choreography,事件驱动)。Saga 是分布式事务的最终一致替代方案。

Saga 用"本地事务 + 补偿"实现分布式事务的最终一致,避免 2PC 阻塞。

#
★★

17. Saga 的编排式与协同式实现如何权衡可见性和耦合,补偿失败由谁持续推进

Saga 的编排式与协同式实现如何权衡可见性和耦合,补偿失败由谁持续推进?

  • 编排式的可见性
  • 协同式的耦合
  • 补偿失败推进

Saga 编排式(orchestration)用中央协调器(orchestrator)控制各步骤,可见性好(集中编排、可追踪)、耦合较低(各服务只与协调器交互),但协调器是单点;协同式(choreography)用事件驱动各服务自行响应,耦合低(无中央协调)、但可见性差(流程分散)。补偿失败时:编排式由协调器集中推进补偿(重试协调器);协同式由各服务监听事件、自行补偿,失败推进依赖事件重试与死信处理。选型权衡可见性与耦合。

编排式集中可见性但单点,协同式分散解耦但难追踪。补偿失败靠协调器或事件重试推进。

#
★★

18. Saga 编排式与协调式在 Spring Cloud Alibaba Seata 中的事务回滚与补偿机制实现

请说明 Saga 编排式与协调式在 Spring Cloud Alibaba Seata 中的事务回滚与补偿机制实现?

  • Seata 的 Saga
  • 编排/协调
  • 回滚与补偿

Seata(Spring Cloud Alibaba)提供 Saga 模式,支持编排式与协同式:编排式用状态机(StateMachine)定义 Saga 流程,Seata 的 Saga 引擎按状态机执行,失败时按定义执行补偿;协同式通过事件驱动服务间协作。Seata 的 Saga 回滚/补偿机制:状态机记录执行状态,失败时回溯执行补偿动作(Cancel),通过全局事务(GlobalTransaction)管理。Seata 还提供 AT、TCC 模式,Saga 是其中的补偿式实现。

Seata Saga 用状态机编排,失败时执行补偿动作,实现分布式事务的最终一致。

#
★★

19. Seata AT 模式如何基于本地事务与 undo log 实现自动补偿,与 TCC 模式在侵入性、隔离性与性能上的实现差异

请说明 Seata AT 模式如何基于本地事务与 undo log 实现自动补偿,与 TCC 模式在侵入性、隔离性与性能上的实现差异?

  • AT 模式的 undo log
  • 自动补偿
  • 与 TCC 差异

Seata AT 模式基于本地事务:业务在本地事务内执行 SQL,Seata 拦截 SQL 生成 undo log(记录前后镜像),全局事务提交时删除 undo log,回滚时用 undo log 反向 SQL 恢复数据,实现自动补偿。侵入性低(无需改业务代码)。与 TCC 差异:AT 侵入性低(自动生成镜像),TCC 侵入性高(需手写 Try/Confirm/Cancel);隔离性:AT 用全局锁保证写隔离,TCC 靠预留(Try)保证隔离;性能:AT 有 undo log 与全局锁开销,TCC 预留资源可能更慢。AT 适合侵入性要求低的场景,TCC 适合需强预留的场景。

AT 用 undo log 自动补偿(侵入低),TCC 手写预留(侵入高)。隔离与性能各有取舍。

#
★★

20. Service Mesh 在 Spring Cloud 微服务中与传统 SDK(OpenFeign + Hystrix)

请说明 Service Mesh 在 Spring Cloud 微服务中与传统 SDK(OpenFeign + Hystrix)的对比?

  • Service Mesh 的代理
  • 传统 SDK 的嵌入
  • 差异

传统 Spring Cloud 用 SDK(OpenFeign 调用、Hystrix 熔断)在应用内实现服务治理,侵入应用、语言绑定、升级需改代码;Service Mesh 把网络治理(负载均衡、熔断、限流、可观测)下沉到 Sidecar 代理(如 Istio),应用无侵入、语言无关,由数据面代理处理。对比:SDK 直接、可控但侵入、绑定语言;Service Mesh 解耦、跨语言、无侵入但引入代理开销与复杂度。工程上可混用,或用 Mesh 治理网络、SDK 处理业务。

SDK 嵌入应用实现治理(侵入),Mesh 用代理下沉治理(无侵入)。按侵入性与运维复杂度权衡。

#
★★

21. Strangler Fig 模式在 Spring Boot 单体应用逐步拆分微服务时的数据双写与切换策略

请说明 Strangler Fig 模式在 Spring Boot 单体应用逐步拆分微服务时的数据双写与切换策略?

  • Strangler Fig 渐进拆分
  • 数据双写
  • 切换

Strangler Fig(绞杀者)模式渐进拆分单体:新功能用微服务实现,旧功能保留在单体,通过路由把部分流量切到新服务,逐步替换。数据双写:新旧系统同时写数据(双写),保证一致性,用事件/日志同步;切换策略:先小流量灰度到新服务,验证后逐步放大,最后移除单体功能。数据双写需处理一致性与回滚(切换失败回退)。按"功能级渐进替换 + 数据双写 + 流量切换"演进。

Strangler Fig 渐进替换,数据双写保证切换时一致,流量切换灰度推进,失败可回退。

#
★★

22. TCC 模式的 Try/Confirm/Cancel 如何保证业务最终一致,空回滚、幂等与悬挂问题分别如何产生与防范

请说明 TCC 模式的 Try/Confirm/Cancel 如何保证业务最终一致,以及空回滚、幂等与悬挂问题如何产生与防范?

  • TCC 三阶段
  • 空回滚
  • 幂等与悬挂

TCC 的 Try 预留资源、Confirm 确认提交、Cancel 取消,三者配合保证最终一致。问题与防范:空回滚(Try 未执行就 Cancel,如网络超时)——Cancel 需判断是否已 Try,未 Try 则不执行,用事务/状态记录判断;幂等(Confirm/Cancel 重复调用)——用唯一事务 ID 去重,同一操作只执行一次;悬挂(Cancel 先于 Try 执行,导致 Try 被挂起)——用状态机/锁保证 Try 与 Cancel 顺序。TCC 实现需保证各阶段幂等、防空回滚、防悬挂。

TCC 的最终一致靠三阶段,但空回滚、幂等、悬挂是实现的三大坑,需状态与幂等控制。

#
★★

23. 三阶段提交(3PC)引入 CanCommit 阶段与超时机制如何缓解 2PC 的阻塞问题,为何仍无法在分区下保证一致性

三阶段提交(3PC)引入 CanCommit 阶段与超时机制如何缓解 2PC 的阻塞问题,为何仍无法在分区下保证一致性?

  • 3PC 的 CanCommit/PreCommit/DoCommit
  • 超时机制缓解阻塞
  • 分区下的一致性局限

3PC 在 2PC 基础上引入 CanCommit(询问是否可提交)与超时机制,参与者在超时后主动决定(补偿),缓解了 2PC 中协调者故障导致的阻塞(参与者无限等待)。但 3PC 仍无法在分区下保证一致性:因为分区导致协调者与参与者无法通信,CanCommit 的投票结果可能不一致,部分参与者可能提交、部分回滚,无法原子提交。3PC 减少了阻塞概率,但 CAP 定理下分区时无法同时保证一致性与可用性,3PC 也不例外。

3PC 缓解阻塞但引入新的不一致窗口,分区下仍无法原子一致。CAP 限制其极限。

#
★★

24. 业务驱动的架构(DDD)与技术架构的协同

请说明业务驱动的架构(DDD)与技术架构的协同?

  • DDD 领域驱动
  • 技术架构
  • 协同

DDD(领域驱动设计)以业务领域为核心建模(领域模型、限界上下文、聚合),技术架构(分层、微服务、基础设施)为领域服务。协同:DDD 定义业务边界(限界上下文对应服务边界),技术架构实现领域模型(仓储、事务、依赖注入);领域层不依赖基础设施(依赖倒置),技术细节被适配器封装。DDD 让架构围绕业务演进,技术架构提供支撑,二者结合实现"业务驱动、技术实现"。

DDD 定业务边界,技术架构实现。领域层依赖抽象、基础设施适配,是协同关键。

#
★★

25. 两阶段提交(2PC)的准备与提交阶段如何工作,协调者单点、同步阻塞与数据不一致缺陷为何难以根除

请说明两阶段提交(2PC)的准备与提交阶段如何工作,以及协调者单点、同步阻塞与数据不一致缺陷为何难以根除?

  • 2PC 的 prepare/commit
  • 协调者单点
  • 阻塞与不一致

2PC 分两阶段:准备阶段(prepare)协调者询问所有参与者能否提交,参与者执行并返回失败/成功;提交阶段(commit)协调者根据投票统一提交或回滚。缺陷:协调者单点(协调者故障则无法决策,参与者阻塞);同步阻塞(参与者锁定资源等待协调者,阻塞期间资源占用);数据不一致(提交阶段协调者失败,部分参与者已提交、部分未提交)。这些缺陷难以根除,因为 2PC 是"全有或全无"的原子协议,协调者故障或网络分区时无法保证原子,且 CAP 定理限制。

2PC 靠协调者保证原子,但协调者单点、阻塞、分区不一致是其固有缺陷,CAP 限制无法根除。

#
★★

26. 事件溯源(Event Sourcing)架构下,事件 schema 演进与老事件重放之间的兼容策略有哪些工程范式

请说明事件溯源(Event Sourcing)架构下,事件 schema 演进与老事件重放之间的兼容策略有哪些工程范式?

  • 事件 schema 演进
  • 老事件重放
  • 兼容范式

事件溯源下事件 schema 演进与老事件重放兼容的范式:向后兼容(新代码能读老事件,只增字段不删改);版本化(事件带版本号,按版本解析);迁移/升级(事件升级器把老事件转为新格式);事件转换器(重放时按版本转换)。重放时用这些机制保证老事件能被当前代码正确解析。工程范式:只增不改、版本化、升级器、转换器,保证事件流可长期重放。

事件溯源 schema 演进靠"只增 + 版本 + 升级器",让老事件可被新代码重放。

#
★★

27. 事件溯源(Event Sourcing)的存储策略

请说明事件溯源(Event Sourcing)的存储策略?

  • 事件存储
  • 快照
  • 聚合重建

事件溯源的存储策略:事件以追加方式存储(append-only),记录聚合的所有状态变化;为提升重建性能,定期保存快照(snapshot),重建时从快照 + 后续事件重放,避免每次都从首个事件重放。事件存储需保证顺序与持久化(事件追加、幂等)。读模型从事件投影构建。存储可用专属事件库(EventStoreDB)或数据库 + 事件表。策略:事件持久化 + 快照加速 + 投影建读模型。

事件存储是 append-only + 快照加速 + 投影。快照平衡存储与重建成本。

#
★★

28. 事件驱动架构采用至少一次投递时,消费者幂等、事件顺序和模式演进应如何共同设计

事件驱动架构采用至少一次投递时,消费者幂等、事件顺序和模式演进应如何共同设计?

  • 至少一次投递
  • 消费者幂等
  • 事件顺序与模式演进

至少一次投递(at-least-once)可能重复投递,消费者必须幂等(用事件 ID/业务键去重,重复处理不产生重复副作用);事件顺序需保证(同一聚合/键的事件按序处理,用分区键/序列号);模式演进需兼容(新消费者读旧事件)。三者共同设计:幂等处理重复,分区保证顺序,版本化兼容演进。这样 at-least-once 下系统仍正确。

at-least-once 下,幂等去重、顺序保证、版本兼容三者缺一不可,共同保证正确性。

#
★★

29. 事件驱动架构(EDA)在 Kafka 4.x + Spring Cloud Stream 下的 Exactly-Once 语义保障

请说明事件驱动架构(EDA)在 Kafka 4.x + Spring Cloud Stream 下的 Exactly-Once 语义保障?

  • Kafka 的 Exactly-Once
  • Spring Cloud Stream
  • 幂等与事务

Kafka 的 Exactly-Once 语义(EOS)通过事务(幂等生产者 + 事务协调 + 消费端隔离)实现,保证"生产-消费"的精确一次。在 Spring Cloud Stream 中启用 EOS:配置事务性生产者(spring.cloud.stream.kafka.bindings...producer.transactional),消费端配合幂等(消费端幂等消费,因为 EOS 主要保证生产端)。但 EOS 有性能开销与跨系统限制(只保证 Kafka 内),跨系统(Kafka + 数据库)仍需业务幂等。EOS 是"尽力精确一次",工程上常配合幂等消费。

Kafka EOS 靠事务实现,但只保证 Kafka 内,跨系统需业务幂等。Spring Cloud Stream 配置事务性生产者。

#
★★

30. 事务发件箱如何原子记录领域变化与待发事件,发布成功后的清理和重复投递怎样处理

事务发件箱(Outbox)如何原子记录领域变化与待发事件,发布成功后的清理和重复投递怎样处理?

  • 发件箱表
  • 原子记录
  • 清理与重复投递

事务发件箱(Outbox)在业务事务中把"领域变化 + 待发事件"一起写入数据库(同一事务),保证二者原子(要么都成功,要么都失败)。发布器读取 outbox 表把事件发布到消息中间件。发布成功后的清理:删除或标记已发布的事件(避免重复发布);重复投递处理:消费者幂等(事件 ID 去重),因为发布可能因意外重复。清理与幂等配合保证"可靠投递 + 不重复副作用"。

Outbox 用本地事务保证原子,发布后标记清理,消费者幂等处理重复投递。

#
★★

31. 云原生时代的 12-Factor App 与 Spring Boot 4.0 默认配置的兼容性差异点

请说明云原生时代的 12-Factor App 与 Spring Boot 4.0 默认配置的兼容性差异点?

  • 12-Factor 原则
  • Spring Boot 默认配置
  • 差异点

12-Factor App 原则(声明式配置、环境化配置、无状态、日志输出到 stdout、进程无本地状态等)与 Spring Boot 4.0 默认配置的兼容性差异:Spring Boot 默认支持外部化配置(环境变量、配置中心)符合 12-Factor;但 Spring Boot 默认有本地状态能力(如内存会话、本地缓存),需注意无状态原则;日志默认输出到 console(符合 stdout),但 Spring Boot 也支持文件日志。差异点:需显式配置环境化配置、无状态化(会话外置)、日志结构化,云原生部署需对齐 12-Factor(如配置注入、健康检查、优雅停机)。

Spring Boot 大体符合 12-Factor,但需注意无状态化、环境配置、健康/优雅停机等云原生对齐点。

#
★★

32. 从模块化单体拆微服务时,应依据数据所有权和独立变更率还是代码行数确定服务边界

从模块化单体拆微服务时,应依据数据所有权和独立变更率还是代码行数确定服务边界?

  • 服务边界依据
  • 数据所有权
  • 独立变更率

拆微服务应依据数据所有权和独立变更率决定服务边界,而非代码行数:数据所有权(服务拥有自己的数据,避免跨服务共享数据库)决定职责边界;独立变更率(功能独立演化、独立部署的频率)决定是否值得拆分。代码行数不是边界依据(大模块未必独立、小模块未必该拆)。正确依据:数据归属清晰 + 独立变更需求 → 拆成服务;否则留在模块化单体。

服务边界由"数据所有权 + 独立变更率"驱动,代码行数是误导。DDD 限界上下文是依据。

#
★★

33. 六边形架构如何让领域核心只依赖端口,数据库适配器与消息适配器的事务边界应放在哪里

六边形架构如何让领域核心只依赖端口,数据库适配器与消息适配器的事务边界应放在哪里?

  • 六边形架构的端口
  • 适配器
  • 事务边界

六边形架构(Ports & Adapters)让领域核心只依赖端口(接口),外部(数据库、消息、UI)通过适配器实现端口,领域不依赖外部技术。事务边界放在适配器层:数据库适配器在持久化时管理事务(@Transactional 在适配器/应用层),消息适配器在消费消息时管理事务。领域核心不直接管理事务(事务是基础设施关注点),由应用层或适配器编排,保证事务边界清晰且与领域解耦。

六边形让领域依赖端口,事务边界放适配器/应用层,领域保持纯业务逻辑。

#
★★

34. 六边形架构(Ports & Adapters)在 Spring Boot 3.x 下的边界划分、依赖倒置与单元测试友好的具体实践

请说明六边形架构(Ports & Adapters)在 Spring Boot 3.x 下的边界划分、依赖倒置与单元测试友好的具体实践?

  • 端口与适配器
  • 依赖倒置
  • 单元测试

六边形架构在 Spring Boot 3.x 的实践:领域层定义端口(接口,如 Repository、MessagePublisher),适配器(JPA Repository 实现、Kafka 生产者)实现端口;依赖倒置让领域依赖接口而非具体实现;Spring 用 @Component 注入适配器。单元测试友好:领域逻辑测试用内存/桩适配器(mock 端口),不依赖数据库或消息,测试快、隔离好。边界划分:domain 只有业务,application 编排用例,infrastructure 实现适配器。

端口抽象 + 适配器实现 + 依赖倒置,让领域测试用桩适配器,测试友好。

#
★★

35. 分层架构(Layered)中表现层调用领域服务的边界在 Spring Boot 4.0 模块化下如何重构

分层架构(Layered)中表现层调用领域服务的边界在 Spring Boot 4.0 模块化下如何重构?

  • 分层架构
  • 表现层与领域服务边界
  • 模块化重构

分层架构中表现层调用领域服务,边界是"表现层只通过应用服务(用例)调用领域,不直接访问领域内部"。在 Spring Boot 4.0 模块化下重构:用模块化(Spring Modulith)定义模块边界,表现层与领域服务分属不同模块,模块间通过公开接口(端口)通信,降低耦合;应用服务作为表现层与领域的桥梁,领域内部不暴露给表现层。重构目标:表现层依赖应用层接口,领域模块封装业务,模块边界清晰。

表现层通过应用服务调用领域,模块化后边界更清晰,领域不暴露内部。

#
★★

36. 在 Spring Boot 4.0 中实现 Choreography Saga 时各模块通过 Kafka 事件解耦的版本兼容策略

在 Spring Boot 4.0 中实现 Choreography Saga 时各模块通过 Kafka 事件解耦的版本兼容策略是什么?

  • Choreography Saga
  • Kafka 事件解耦
  • 版本兼容

Choreography Saga 用事件驱动各服务协作,Spring Boot 4.0 中通过 Kafka 事件解耦。版本兼容策略:事件 schema 版本化(只增不改、事件带版本);兼容演进(新消费端能读旧事件);事件契约管理(共享事件 schema 仓库);消费端向后兼容(容忍未知字段)。由于各模块独立发布,事件版本兼容保证新旧服务共存时协作正确。用版本化 + 只增 + 契约管理实现。

协同式 Saga 依赖事件契约,版本兼容保证各服务独立演进时事件协作正确。

#
★★

37. 在 Spring Boot 4.0 中实现 Sidecar 模式与 K8s Native Sidecar 在跨语言服务协同中的取舍

请说明在 Spring Boot 4.0 中实现 Sidecar 模式与 K8s Native Sidecar 在跨语言服务协同中的取舍?

  • Sidecar 模式
  • K8s Native Sidecar
  • 跨语言协同

Sidecar 模式把辅助能力(日志、代理、监控)放进伴随容器,Spring Boot 4.0 应用可与 Sidecar 协作。K8s Native Sidecar 是 K8s 原生支持的 Sidecar(生命周期管理、自动启动),两者在跨语言服务协同中的取舍:应用内 Sidecar(自己实现)直接但侵入、绑定语言;K8s Native Sidecar 由 K8s 管理、语言无关、可复用,适合代理/日志等通用能力。取舍:跨语言、通用能力用 K8s Native Sidecar(无侵入、可复用);应用特定、需深度集成用应用内实现。K8s Native Sidecar 更符合云原生跨语言协同。

K8s Native Sidecar 语言无关、无侵入,适合跨语言通用能力;应用内 Sidecar 侵入但可深度定制。

#
★★

38. 干净架构(Clean Architecture)的同心圆分层在 Spring Boot 4.0 模块化中的依赖管理

请说明干净架构(Clean Architecture)的同心圆分层在 Spring Boot 4.0 模块化中的依赖管理?

  • 干净架构的同心圆
  • 依赖方向
  • 模块化依赖管理

干净架构用同心圆分层(内层:实体/领域,中层:用例,外层:接口/框架/基础设施),依赖方向指向内层(内层不依赖外层)。Spring Boot 4.0 模块化中落地:用模块定义各层,依赖规则用模块边界(Spring Modulith 验证依赖方向)强制,内层模块不依赖外层模块,通过接口/端口实现依赖倒置。依赖管理:内层模块无框架依赖(纯领域),外层模块实现接口,依赖方向由内而外,保证架构不被框架污染。

干净架构依赖指向内层,模块化用依赖规则强制,内层纯净、外层适配。

#
★★

39. 微内核加载第三方插件时,如何隔离类加载器、权限、资源配额和插件版本依赖

微内核加载第三方插件时,如何隔离类加载器、权限、资源配额和插件版本依赖?

  • 类加载器隔离
  • 权限隔离
  • 资源配额与版本依赖

微内核加载第三方插件需隔离:类加载器隔离(每个插件用独立类加载器,避免类冲突);权限隔离(SecurityManager/权限上下文限制插件权限,防止恶意操作);资源配额(限制插件 CPU/内存/线程,防资源耗尽);插件版本依赖(插件与内核及插件间的版本独立,避免依赖冲突)。用独立类加载器 + 权限沙箱 + 资源限制 + 版本管理实现插件隔离,保证插件不破坏内核。

插件隔离是"类加载 + 权限 + 资源 + 版本"四维隔离,保证第三方插件安全独立运行。

#
★★

40. 微内核架构(Microkernel)在 Spring Boot Plugin SPI 与 Java ServiceLoader 中的实现差异

请说明微内核架构(Microkernel)在 Spring Boot Plugin SPI 与 Java ServiceLoader 中的实现差异?

  • 微内核架构
  • Spring Boot Plugin SPI
  • Java ServiceLoader

微内核架构(Microkernel)核心是"核心系统 + 可插拔插件"。Java ServiceLoader 是标准 SPI:META-INF/services 声明服务实现,ServiceLoader.load 加载,核心与插件通过接口解耦;Spring Boot Plugin SPI 用 Spring 机制(SpringFactoriesLoader@EnableAutoConfigurationAutoConfiguration.imports)加载插件,插件是 Spring Bean,可依赖注入、条件装配。差异:ServiceLoader 轻量、标准、无 Spring 依赖;Spring Boot SPI 集成 Spring 生态(DI、条件装配、配置),更强大但依赖 Spring。按是否需要 Spring 集成选择。

ServiceLoader 是标准轻量 SPI,Spring Boot SPI 集成 Spring 生态。插件机制按生态需求选择。

#
★★

41. 微服务架构与模块化单体(Modular Monolith)

请说明微服务架构与模块化单体(Modular Monolith)的关系?

  • 微服务
  • 模块化单体
  • 取舍

模块化单体(Modular Monolith)是"一个部署单元 + 强模块边界":代码按模块划分,但作为一个应用部署,保留领域边界与模块解耦。微服务是"多个独立部署单元"。二者关系:模块化单体是微服务的"前置形态"——先用模块边界梳理,必要时把模块拆为独立服务。取舍:模块化单体部署简单、事务简单、运维成本低,适合中小规模;微服务独立部署、可扩展、技术异构,但分布式复杂。按规模与团队权衡,模块化单体是保守且可演进的选择。

模块化单体保留模块边界但单部署,是微服务的前置。复杂与规模决定是否拆。

#
★★

42. 微服务架构(Microservices)的边界设计

请说明微服务架构(Microservices)的边界设计?

  • 服务边界
  • 数据边界
  • 限界上下文

微服务边界设计:按业务能力与限界上下文划分服务(DDD),每个服务有自己的数据边界(独立数据库,不跨服务共享),服务间通过 API/事件通信。边界设计原则:高内聚(一个服务承载一个业务能力)、低耦合(服务间依赖少)、数据自治(服务拥有自己的数据)。边界由业务能力与数据所有权决定,避免按技术层切分(如把数据访问拆成服务)。清晰边界保证服务独立演进与部署。

微服务边界由业务能力与数据所有权决定,数据自治与限界上下文是核心。

#
★★

43. 洋葱架构(Onion Architecture)的依赖方向

请说明洋葱架构(Onion Architecture)的依赖方向?

  • 洋葱架构的分层
  • 依赖方向
  • 依赖倒置

洋葱架构分层:内层领域模型,中层领域服务/应用服务,外层基础设施(数据库、UI、框架)。依赖方向指向内层:内层不依赖外层,外层依赖内层。通过接口实现依赖倒置——内层定义接口,外层实现,内层依赖接口而非具体实现。洋葱架构与干净架构、六边形类似,核心是"依赖指向内层"与"领域核心不依赖基础设施"。保证领域独立、可测试。

洋葱架构依赖指向内层,用接口实现依赖倒置,领域不依赖基础设施。

#
★★

44. 线程池、信号量与连接池的隔离粒度与故障域爆炸半径如何权衡

线程池、信号量与连接池的隔离粒度与故障域爆炸半径如何权衡?

  • 隔离粒度
  • 故障域爆炸半径
  • 权衡

线程池、信号量、连接池都是资源隔离手段,隔离粒度不同:线程池隔离(每个场景独立线程池)粒度粗、隔离彻底、故障域名分散,但资源开销大;信号量隔离(限制并发数)粒度细、轻量,但共享线程池、隔离较弱;连接池隔离(每场景独立连接池)隔离数据库连接。权衡:隔离粒度越细,故障爆炸半径越小(隔离更彻底),但资源开销越大。按"故障影响 + 资源成本"平衡:关键路径用强隔离(独立线程池),一般路径用轻量隔离(信号量)。

隔离粒度与故障域半径成反比、与资源开销成正比。按关键路径与资源成本权衡。

#
★★

45. ADR(架构决策记录)在企业架构治理中的版本化与审查流程

请说明 ADR(架构决策记录)在企业架构治理中的版本化与审查流程?

  • ADR 的内容
  • 版本化
  • 审查流程

ADR(Architecture Decision Record)记录架构决策(背景、决策、理由、替代方案、后果)。企业治理中,ADR 需版本化(随时间演进,记录决策变更)与审查流程(决策经评审、记录在案、可追溯)。审查流程:提出决策 → 评审(评估约束、替代方案)→ 批准 → 记录 ADR → 后续按需复议。版本化保证决策历史可追溯,审查流程保证决策质量与一致性。ADR 是架构治理的"文档化决策库"。

ADR 版本化记录决策演进,审查流程保证决策质量,是企业架构治理的资产。

#
★★

46. BFF 按客户端拆分接口可减少前端编排,但多个 BFF 复制业务规则时如何治理

BFF 按客户端拆分接口可减少前端编排,但多个 BFF 复制业务规则时如何治理?

  • BFF 拆分
  • 业务规则复制
  • 治理

BFF(Backend for Frontend)按客户端(Web/移动/小程序)拆分接口,减少前端编排,但多个 BFF 可能复制业务规则(如权限、校验、聚合逻辑),导致重复与不一致。治理方法:把通用业务规则下沉到共享服务/领域层,BFF 只做编排与裁剪,不承载业务规则;用共享库/契约(OpenAPI)规范化;BFF 薄化(只做聚合与格式转换),业务规则集中在后端服务。这样避免 BFF 复制规则,保持一致性。

BFF 薄化、业务规则下沉共享服务,避免多 BFF 复制规则。BFF 只做编排与适配。

#
★★

47. Backend for Frontend(BFF)的边界

请说明 Backend for Frontend(BFF)的边界?

  • BFF 的职责
  • 边界
  • 适用场景

BFF(Backend for Frontend)是面向特定前端(Web/移动等)的后端边界,职责是:聚合多个后端服务的接口、按客户端需求裁剪/格式化数据、处理客户端特定的逻辑(认证、编排)。边界在于"BFF 只做前端适配与编排,不承载业务规则与数据权限",业务逻辑在后端领域服务。BFF 让前端无需编排多个接口,但应保持薄、无状态、可复用。适用场景:多客户端、接口差异大、需前端聚合。

BFF 边界是"前端适配/编排",业务规则下沉。薄化、无状态是 BFF 的设计原则。

#
★★

48. Bulkhead 模式与故障隔离

请说明 Bulkhead 模式与故障隔离?

  • Bulkhead 隔离
  • 故障域
  • 防扩散

Bulkhead(舱壁)模式把系统资源按场景隔离,避免一个故障扩散到整体。类似船只的舱壁——一个舱进水不沉整船。实现方式:线程池隔离(每场景独立线程池)、信号量隔离(限制并发)、连接池隔离。故障隔离的价值:慢调用/高负载被隔离在各自舱壁,不影响其他场景,控制故障爆炸半径。Bulkhead 常与熔断、限流配合,构成容错体系。

Bulkhead 是"故障域隔离",按场景分舱壁,防故障扩散。与熔断、限流协同。

#
★★

49. Circuit Breaker 模式与 Resilience4j

请说明 Circuit Breaker 模式与 Resilience4j?

  • 熔断器
  • 状态转移
  • Resilience4j

Circuit Breaker(熔断器)模式:当调用失败率达到阈值,熔断器打开(open),后续请求直接失败(不调用下游),冷却后半开(half-open)尝试部分请求,成功则关闭(closed)。Resilience4j 实现熔断器,可配置失败率阈值、滑窗、冷却时间。熔断防止下游故障把调用方拖垮(快速失败),保护下游与调用方。Resilience4j 的 CircuitBreaker 支持基于滑动窗口的失败率统计。

熔断器三态(关闭/打开/半开),防故障级联。Resilience4j 用滑窗统计失败率。

#
★★

50. EDA(事件驱动架构)与 EDA 2.0 的演进

请说明 EDA(事件驱动架构)与 EDA 2.0 的演进?

  • EDA 基础
  • EDA 2.0
  • 演进

EDA(事件驱动架构)用事件驱动系统间通信,解耦、异步、可扩展。EDA 2.0 的演进强调:场景驱动(事件建模)、事件契约管理(schema 治理)、事件溯源(事件作为数据)、流式处理(实时)、支撑业务流程(事件编排)、跨服务事件共享。EDA 2.0 从"消息解耦"演进到"以事件为中心"的架构(事件建模、事件溯源、事件驱动业务),强调事件的语义化与治理。演进方向:事件从传输载体升级为业务资产。

EDA 2.0 把事件从"通信载体"升级为"业务资产",强调事件建模、契约与溯源。

#
★★

51. Microkernel 架构(插件化)的工程应用

请说明 Microkernel 架构(插件化)的工程应用?

  • 微内核
  • 插件化
  • 应用

Microkernel(微内核)架构由一个核心系统(core)和一组可插拔插件组成,核心提供基础功能,插件通过扩展点扩展能力。工程应用:IDE(Eclipse 插件)、浏览器(扩展)、日志框架(Appender)、规则引擎(规则插件)。Spring Boot 的自动配置也可视为微内核的变体(核心 + 条件装配的启动器)。价值:核心稳定、功能可扩展、插件可独立开发/部署。设计需定义清晰的扩展点(SPI)。

微内核是"核心 + 插件",扩展点(SPI)是核心。插件可插拔、独立扩展。

#
★★

52. Monorepo 与 Polyrepo 的架构影响

请说明 Monorepo 与 Polyrepo 的架构影响?

  • Monorepo 单仓库
  • Polyrepo 多仓库
  • 影响

Monorepo(单仓库)把所有项目放在一个仓库,优点:统一构建、依赖统一、跨项目重构容易、代码共享;缺点:仓库大、权限粒度粗、构建复杂。Polyrepo(多仓库)每项目独立仓库,优点:独立版本、独立权限、独立构建;缺点:依赖管理复杂、跨项目协作难、代码复用难。架构影响:Monorepo 利于大团队统一协作与一致依赖,Polyrepo 利于独立团队与独立发布。按团队规模与工程协作方式选择。

Monorepo 统一协作但仓库大,Polyrepo 独立自治但跨项目难。按团队规模与治理权衡。

#
★★

53. Pipeline 架构与责任链模式在订单处理链中的可观测性与超时传播设计

请说明 Pipeline 架构与责任链模式在订单处理链中的可观测性与超时传播设计?

  • Pipeline 架构
  • 责任链
  • 可观测性与超时

Pipeline 架构与责任链都用于"按序处理"的链路(订单处理:校验 → 价格 → 库存 → 支付)。在订单处理链中,可观测性设计:每个阶段记录处理时间、状态、结果(trace/日志),用 trace 串联整条链路,定位瓶颈;超时传播设计:每个阶段有余量超时,整体有总时限,超时沿链传播(阶段超时则终止链),避免无限等待。用 trace 观测各阶段,用超时控制链的总时限,保证链路可观测与可控。

可观测性靠 trace 串联各阶段,超时靠"阶段超时 + 总时限"控制,中止慢链。

#
★★

54. Pipeline 架构与责任链的差异

请说明 Pipeline 架构与责任链模式的差异?

  • Pipeline 的流水线
  • 责任链的链
  • 差异

Pipeline 架构与责任链模式都组织"按序处理",但差异:Pipeline 强调的是"流水线处理",每个阶段处理并传递结果(数据流),通常所有阶段都执行(如数据处理管道);责任链强调"按序处理可短路",每个节点可处理或终止(如鉴权链,一个节点失败即终止)。Pipeline 关注"数据流经各阶段",责任链关注"分发/拦截"。Pipeline 是"加工流水线",责任链是"判断/拦截链"。

Pipeline 是"数据加工流水线"(全阶段执行),责任链是"拦截/分发链"(可短路)。目的不同。

#
★★

55. Sidecar 把网络治理移出应用后会增加哪些延迟与资源开销,无代理服务网格又改变什么

Sidecar 把网络治理移出应用后会增加哪些延迟与资源开销,无代理服务网格又改变什么?

  • Sidecar 的延迟与开销
  • 无代理服务网格
  • 改变

Sidecar 把网络治理(负载均衡、熔断、限流)移出应用到代理,增加延迟(多一跳代理转发)与资源开销(每 Pod 一个代理容器,CPU/内存)。无代理服务网格(如 gRPC/内核级)用应用内 SDK 或内核能力实现治理,减少代理跳数与资源开销,但引入应用侵入或依赖内核。无代理改变:降低延迟与资源、提高性能,但牺牲"无侵入、跨语言"的代理优点。权衡代理的隔离性 vs 无代理的性能。

Sidecar 代理有延迟与资源开销,无代理用 SDK/内核减少开销但牺牲无侵入。按性能与隔离权衡。

#
★★

56. Sidecar 模式与 Service Mesh

请说明 Sidecar 模式与 Service Mesh 的关系?

  • Sidecar 模式
  • Service Mesh
  • 关系

Sidecar 模式是"伴随主容器的辅助容器"部署模式,Service Mesh 是"服务间通信治理"的架构,其核心实现就是 Sidecar:每个服务实例旁部署一个 Sidecar 代理(数据面),负责服务间通信的治理(负载均衡、熔断、TLS、可观测),控制面(如 Istio)管理配置。Sidecar 是 Service Mesh 的实现载体,Service Mesh 用 Sidecar 把网络治理从应用下沉到代理。二者关系:Sidecar 是模式,Service Mesh 是架构。

Sidecar 是部署模式,Service Mesh 用 Sidecar 实现治理。Sidecar 是 Service Mesh 数据面的载体。

#
★★

57. Strangler Fig Pattern 在遗留系统迁移到微服务时的渐进式重构路径与风险

请说明 Strangler Fig Pattern 在遗留系统迁移到微服务时的渐进式重构路径与风险?

  • 渐进式重构
  • 路径
  • 风险

Strangler Fig(绞杀者)渐进重构路径:先加一层 Facade/路由,把功能按优先级逐步迁移到新微服务,路由把流量切换到新服务,旧功能逐步被"绞杀",最终完全替换。风险:数据双写一致性(新旧数据同步)、功能切换的兼容性、长尾依赖(旧系统难彻底移除)、迁移期间双系统维护成本。控制风险:按功能/数据边界小步迁移、灰度切换、双写校验、回退机制。

绞杀者渐进迁移,风险在数据双写、兼容、长尾。小步迁移与灰度回退控制风险。

#
★★

58. 事件驱动架构(Event-Driven)的事件契约版本管理与死信处理,如何避免事件风暴与隐式依赖

请说明事件驱动架构(Event-Driven)的事件契约版本管理与死信处理,如何避免事件风暴与隐式依赖?

  • 事件契约版本管理
  • 死信处理
  • 避免事件风暴与隐式依赖

事件驱动架构的事件契约版本管理:事件 schema 版本化、只增不改、兼容演进,用契约仓库统一管理;死信处理:无法消费的事件进死信队列(DLQ),记录并人工/自动重试,避免阻塞。避免事件风暴(事件激增、循环触发):限制事件数量、用事件强度控制、避免循环订阅;避免隐式依赖:事件显式化契约、事件间依赖显式化,避免隐式时序依赖。用契约 + 死信 + 风暴控制 + 显式依赖治理事件架构。

事件架构治理靠版本契约、死信、风暴控制与显式依赖,防止事件失控。

#
★★

59. 六边形架构(Hexagonal/Ports and Adapters)

请说明六边形架构(Hexagonal/Ports and Adapters)?

  • 六边形架构
  • 端口与适配器
  • 依赖方向

六边形架构(Hexagonal/Ports and Adapters)把系统核心(领域)放在中间,通过端口(端口接口)与外部(数据库、消息、UI、API)交互,外部用适配器实现端口。依赖方向指向核心:核心不依赖外部技术,通过端口抽象。适配器把外部技术适配到端口,核心保持技术无关。优点:核心可测试(用桩适配器)、可替换(换适配器)、技术解耦。是端口-适配器思想的架构落地。

六边形让核心依赖端口抽象,适配器接外部,核心技术无关、可测试。

#
★★

60. 分层架构(Layered)的工程取舍

请说明分层架构(Layered)的工程取舍?

  • 分层架构
  • 优点
  • 取舍

分层架构(Layered)按层(表现层、业务层、数据层)组织,优点:职责清晰、关注点分离、易测试(每层独立)、易维护。取舍:严格分层会导致"穿透"(跨层调用)与性能损耗(每层传递);层次过深增加复杂度;数据库关系型实体的层间模型映射成本。工程取舍:按需分层(不必严格四层)、允许合理的跨层(如表现层直接访问部分服务)、用接口隔层解耦。分层适合大多数业务系统,但需平衡层次与简化。

分层清晰但需防穿透与过度分层。按需分层、接口解耦、平衡简化。

#
★★

61. 在 Spring Cloud Gateway 中实现 Backend For Frontend(BFF)

请说明在 Spring Cloud Gateway 中实现 Backend For Frontend(BFF)?

  • Spring Cloud Gateway
  • BFF
  • 路由与聚合

在 Spring Cloud Gateway 中实现 BFF:网关作为 BFF 层,用路由(Route)把前端的请求路由到后端服务,用过滤器(Filter)实现认证、聚合、裁剪、格式转换。BFF 在网关层为前端聚合多个后端接口、裁剪字段、适配格式,减少前端编排。Spring Cloud Gateway 的 Route + Filter 实现 BFF 的编排与适配,但需注意网关保持薄(不承载业务规则),业务逻辑在后端。BFF 网关是前端与后端的适配层。

Spring Cloud Gateway 用路由与过滤器实现 BFF 的聚合与适配,网关保持薄、无业务规则。

#
★★

62. 如何把模块依赖、延迟预算和恢复目标转化为自动化架构适应度函数并纳入流水线

如何把模块依赖、延迟预算和恢复目标转化为自动化架构适应度函数并纳入流水线?

  • 架构适应度函数
  • 自动化验证
  • 纳入流水线

架构适应度函数(Architecture Fitness Function)把架构约束转化为可自动验证的检查:模块依赖(用 ArchUnit 检查依赖方向/无环)、延迟预算(用基准测试/压测验证 P99 在预算内)、恢复目标(用故障演练验证 RTO/RPO)。把这些检查作为 CI 流水线阶段,自动执行并设置门禁,不达标则失败。这样架构约束"代码化、自动化、可验证",纳入流水线持续守护架构质量。

架构适应度函数用 ArchUnit/压测/演练自动化验证架构约束,纳入流水线作为门禁。

#
★★

63. 容量预估(QPS/带宽/存储)的工程方法

请说明容量预估(QPS/带宽/存储)的工程方法?

  • QPS 预估
  • 带宽与存储
  • 工程方法

容量预估的工程方法:基于业务指标(用户量、转化率、请求频率)估算 QPS(峰值 = 平均 × 峰值系数);带宽按请求大小与 QPS 估算(如文本 1KB × 1000 QPS = 8Gbps);存储按数据量、留存、增长估算(如每日增量 × 保留期)。用"峰值系数 + 冗余(预留缓冲)"给出容量,并配合压测验证。预估需结合业务模型与增长预期,留有冗余,避免过度或不足。

容量预估基于业务指标推算 QPS/带宽/存储,乘以峰值系数与冗余,压测验证。

#
★★

64. 技术选型的多维度评估(性能/团队/成本/生态)

请说明技术选型的多维度评估(性能/团队/成本/生态)?

  • 性能
  • 团队
  • 成本与生态

技术选型需多维度评估:性能(是否满足吞吐/延迟要求)、团队(团队熟悉度、学习成本)、成本(许可证、运维、人力资源)、生态(社区活跃度、文档、第三方库、长期维护)。此外考虑兼容性、可迁移性、可观测性。权重按项目需求:性能敏感偏性能,团队决定偏易用,长期项目偏生态。用 PoC 验证关键指标,避免单一维度(如只看性能)选型。

选型是"性能/团队/成本/生态"等多维权衡,按项目需求定权重,PoC 验证。

#
★★

65. 整洁架构要求依赖指向内层,但 DTO、注解和框架异常跨层传播时如何防止实现细节泄漏

整洁架构要求依赖指向内层,但 DTO、注解和框架异常跨层传播时如何防止实现细节泄漏?

  • 依赖指向内层
  • DTO/注解/异常跨层
  • 防泄漏

整洁架构要求依赖指向内层,但 DTO、注解、框架异常可能跨层传播导致实现细节泄漏。防泄漏:DTO 用独立的传输对象(领域与外部用不同 DTO 映射,避免领域对象直接暴露);注解避免跨层(领域层不用框架注解,框架注解在适配层);异常转换(领域抛领域异常,适配层把框架异常转换为领域/应用异常,避免框架异常泄漏到内层)。用映射边界与异常边界隔离实现细节,内层保持纯净。

防泄漏靠 DTO 映射、注解隔离、异常转换,让内层不依赖外部框架细节。

#
★★

66. 架构债务(Technical Debt)的治理

请说明架构债务(Technical Debt)的治理?

  • 架构债务
  • 治理
  • 偿还

架构债务(Technical Debt)是"为快速交付而牺牲的架构质量",如硬编码、绕过分层、重复逻辑、坏依赖。治理:识别(代码审查、架构适应度函数、依赖分析)、记录(债务清单、优先级)、偿还(有计划地重构、按债还)、预防(架构规范、门禁、自动化检查)。债务需"可见、可量化、有计划偿还",避免无限累积导致架构腐化。治理是持续改进的一部分。

架构债务治理是"识别-记录-偿还-预防"闭环,债务可见且有计划偿还,防腐化。

#
★★

67. 架构决策记录如何包含约束、替代方案和退出条件,何时应重新评估而不是永久沿用

架构决策记录如何包含约束、替代方案和退出条件,何时应重新评估而不是永久沿用?

  • ADR 的约束
  • 替代方案
  • 退出条件与重新评估

架构决策记录(ADR)应包含:背景、决策、约束(技术/业务约束)、替代方案(对比过的方案)、退出条件(何时该撤销/替换该决策)。退出条件让决策"有生命周期"而非永久沿用。重新评估时机:约束变化、退出条件触发、新替代方案出现、业务需求变化、技术演进。当决策的假设不再成立,应重新评估而非固守。ADR 作为"可最大化"的决策库,记录假设与退出条件,支持理性演进。

ADR 含约束、替代、退出条件,触发条件或假设变化时重新评估,避免决策僵化。

#
★★

68. 架构决策记录(ADR)的工程实践

请说明架构决策记录(ADR)的工程实践?

  • ADR 的格式
  • 存储与版本
  • 实践

ADR 的工程实践:遵循 ADR 模板(标题、状态、背景、决策、理由、后果、替代方案);ADR 作为代码/文档存入仓库(版本化、可检索);新决策经评审后记录;ADR 状态(提议/已接受/已取代)管理;定期回顾 ADR,评估是否过时。实践核心:ADR 轻量、及时、可追溯,避免"无记录的心智决策"。用 ADR 把架构决策显性化、治理化。

ADR 实践是"模板化 + 入库 + 评审 + 状态管理 + 回顾",让架构决策显性可追溯。

#
★★

69. 架构原则(Architecture Principles)如何转化为可执行的架构适应度函数并防止被空泛化

架构原则(Architecture Principles)如何转化为可执行的架构适应度函数并防止被空泛化?

  • 架构原则
  • 适应度函数
  • 防空泛化

架构原则(如"依赖单向""禁止循环依赖""延迟可控")要可执行,需转化为架构适应度函数:把原则转化为可自动检查的规则(ArchUnit 检查依赖、压测检查延迟、静态检查规范),持续验证。防空泛化:原则要具体可度量("低延迟"→"P99 < 100ms")、有自动化检查、有门禁(不达标失败)。原则"可执行、可度量、可验证"才不空泛。用适应度函数把原则落实为自动化守护。

原则转适应度函数(可度量、自动检查、门禁),防空泛化,落地为可执行规则。

#

70. 架构图(C4/4+1)的画法

请说明架构图(C4/4+1)的画法?

  • C4 模型
  • 4+1 视图
  • 画法

C4 模型用四层视角画架构:Context(系统与外部关系)、Container(容器/应用)、Component(组件)、Code(类)。4+1 视图用逻辑、进程、物理、开发加上场景(用例)多视角描述架构。画法要点:按目标读者选层级(高管看 Context,开发者看 Component/Code);用标准符号、标注依赖与数据流;保持简洁、可读。C4 适合快速沟通,4+1 适合完整架构描述。架构图是沟通工具,需分层、清晰、可演进。

C4 分层画(Context→Container→Component→Code),4+1 多视角(逻辑/进程/物理/开发/场景)。

#

71. 架构演进的版本管理如何做(兼容策略/迁移路径/废弃周期),破坏性变更如何协调各方?

架构演进的版本管理如何做(兼容策略/迁移路径/废弃周期),破坏性变更如何协调各方?

  • 兼容策略
  • 迁移路径
  • 废弃周期与协调

架构演进的版本管理:兼容策略(向后兼容优先,只增不改,旧版本可读);迁移路径(提供平滑迁移步骤,新老并存过渡);废弃周期(明确废弃时间线:deprecated → 移除,给过渡期)。破坏性变更协调:提前公告、提供迁移指南、分阶段(先兼容后废弃)、与各方(团队、消费者)协调节奏、提供回退。用"兼容 + 迁移 + 废弃周期 + 协调"管理演进,减少破坏性变更的影响。

版本管理靠兼容、迁移路径、废弃周期,破坏性变更提前公告并分阶段协调。

#

72. 架构评审(Architecture Review)的工程实践

请说明架构评审(Architecture Review)的工程实践?

  • 架构评审
  • 流程
  • 实践

架构评审的工程实践:评审时机(重大架构变更、新项目、技术选型);评审内容(依赖、边界、扩展性、性能、安全、可维护性);评审形式(评审会、ADR 评审、架构适应度函数自动检查);评审记录(ADR、决策、问题清单)。实践要点:评审以"问题和风险"为导向而非评审喜好;用 ADR 记录决策;结合自动化检查减少人工评审负担。评审保障架构质量与一致性。

架构评审是"时机+内容+形式+记录"的实践,以问题为导向,结合 ADR 与自动化。

#

73. 模块化单体如何用 Spring Modulith 验证模块依赖、测试边界并观察跨模块事件

模块化单体如何用 Spring Modulith 验证模块依赖、测试边界并观察跨模块事件?

  • Spring Modulith
  • 模块依赖验证
  • 事件观察

Spring Modulith 验证模块化单体的模块边界:ApplicationModules 验证模块依赖(无循环、依赖方向合规、禁止未声明依赖);@ApplicationModuleTest 测试模块边界(模块内测试隔离);模块事件通过 @ApplicationModuleListener 观察跨模块事件,Modulith 记录事件发布且支持事件回放。用 Modulith 的模块结构、依赖验证、事件测试,保证模块化边界不被破坏、跨模块协作可观测。

Spring Modulith 用模块校验(依赖)、模块测试(边界)、事件观察(跨模块)守护模块化。

#

74. 系统瓶颈快速定位的思路是什么,从指标-日志-追踪的排障顺序到压测验证如何闭环?

系统瓶颈快速定位的思路是什么:从指标-日志-追踪的排障顺序到压测验证如何闭环?

  • 指标-日志-追踪
  • 排障顺序
  • 压测闭环

系统瓶颈定位闭环:先看指标(CPU、内存、延迟、错误率、TP99)定位瓶颈层(应用/数据库/网络);再看日志(错误、慢日志)定位具体原因;用追踪(trace)串联调用链定位慢环节。假设根因后,用压测验证(复现、隔离变量、验证优化效果),形成"指标 → 日志 → 追踪 → 压测验证"的闭环。排障顺序是"先粗后细、先外后内、假设验证"。

排障闭环:指标定位层、日志定位因、追踪定位链路、压测验证。假设驱动、验证闭环。

#

75. 系统设计的"4S"方法(Scenario/Service/Storage/Scalability)

请说明系统设计的"4S"方法(Scenario/Service/Storage/Scalability)?

  • 4S 方法
  • 场景/服务/存储/扩展
  • 设计流程

4S 方法用于系统设计:Scenario(场景,明确需求与用例)、Service(服务,划分系统功能与模块)、Storage(存储,设计数据模型与存储方案)、Scalability(扩展,设计扩展与性能)。按 4S 展开:先明确场景与需求,再划分服务,设计存储,最后考虑扩展性(分片、缓存、异步)。4S 提供系统设计的结构化方法,覆盖需求到实现的关键维度。

4S 是"场景-服务-存储-扩展"的系统设计框架,用结构化流程覆盖需求与实现。

#

76. 系统设计的非功能性需求(NFR),包括性能/可用/扩展/安全

请说明系统设计的非功能性需求(NFR:性能/可用/扩展/安全)?

  • NFR 的分类
  • 性能/可用/扩展/安全
  • 设计

非功能性需求(NFR)是系统质量属性,关键维度:性能(吞吐、延迟、并发)、可用性(SLA、故障恢复、容错)、扩展性(水平/垂直扩展、可维护)、安全(认证、授权、加密、合规)。NFR 设计需量化(如 P99 < 200ms、可用性 99.99%)、在架构中体现(缓存、冗余、分片、安全设计)、可验证(压测、演练)。NFR 与功能性需求同等重要,决定架构取舍。

NFR 是性能/可用/扩展/安全等质量属性,需量化、落地架构、可验证。

#

77. 设计文档(Design Doc)的模板

请说明设计文档(Design Doc)的模板?

  • 设计文档结构
  • 背景/目标/方案
  • 模板要素

设计文档(Design Doc)模板通常包含:背景与动机(为什么做)、目标/非目标(明确范围)、设计方案(架构、关键决策、数据模型)、替代方案(对比过的方案)、风险与取舍、演进与里程碑、测试与验证。模板要素:清晰的目标、可评估的方案、权衡明确、风险可见。设计文档用于评审与记录,让设计决策有据可依、可追溯。

设计文档模板覆盖背景、目标、方案、替代、风险、演进,是评审与记录的载体。

#

78. 跨地域主动主动架构如何处理写入归属、冲突解决和读己之写,哪些业务不适合多主

跨地域主动主动架构如何处理写入归属、冲突解决和读己之写,哪些业务不适合多主?

  • 主动主动
  • 写入归属与冲突
  • 读己之写

跨地域主动主动(active-active)架构:每个地域可读写,需处理写入归属(按地域/用户分片,避免写冲突)、冲突解决(多主写入冲突的合并/版本/LWW)、读己之写(用户的写立即读,用就近路由或版本保证)。不适合多主的业务:强一致性要求高(金融账务)、写冲突频繁、事务跨地域、顺序强依赖的业务。主动主动适合读多写少、可接受最终一致、地域分布的业务。

主动主动需处理写入归属、冲突解决、读己之写,强一致/写冲突多的业务不适合多主。

#

79. 风险评估与 PoC(概念验证)

请说明风险评估与 PoC(概念验证)在技术决策中的作用?

  • 风险评估
  • PoC
  • 技术决策

风险评估识别技术选型/方案的风险(可行性、性能、团队、集成),PoC(概念验证)用最小原型验证关键风险点(如某项技术是否满足性能、能否集成)。组合:风险评估确定"要验证什么",PoC 用最小成本验证,降低不确定性后做决策。PoC 应聚焦"验证不确定的关键假设",而非完整实现。风险高、不确定的决策用 PoC 降低风险。

风险评估定验证点,PoC 最小成本验证关键假设,降低技术决策不确定性。

#

80. Pipeline / 编排型架构(如 Temporal / Camunda)

请说明 Pipeline / 编排型架构(如 Temporal / Camunda)?

  • Pipeline 架构
  • 编排型
  • Temporal/Camunda

Pipeline/编排型架构把业务流程编排为步骤/工作流:Pipeline 用管道按序处理数据;编排型用工作流引擎(Temporal、Camunda)编排多步骤流程,支持状态管理、重试、超时、补偿。Temporal 用代码定义工作流、持久化执行状态、自动重试;Camunda 用 BPMN 编排流程。价值:复杂流程显式化、具备重试/恢复/补偿能力,适合长流程、多步骤、需可靠执行的业务(订单、审批、分布式协调)。

编排型架构用工作流引擎(Temporal/Camunda)管理流程的状态、重试与补偿,适合长流程。

#

81. 事件溯源系统如何选择快照频率并验证重放确定性,事件模式升级后旧历史怎样兼容

事件溯源系统如何选择快照频率并验证重放确定性,事件模式升级后旧历史怎样兼容?

  • 快照频率
  • 重放确定性
  • 事件兼容

事件溯源系统的快照频率选择:权衡存储(快照多占空间)与重建性能(快照少需重放更多事件),按事件量与重放成本选频率(如每 N 个事件或时间间隔)。验证重放确定性:重放同一事件序列应得到一致状态(用特定种子/固定输入验证,排除随机性)。事件模式升级后旧历史兼容:用事件版本化、升级器(把旧事件转新格式)、只增不改,保证旧事件可被新代码重放。快照 + 确定性验证 + 版本兼容支撑事件溯源长期演进。

快照频率权衡存储与重建,确定性验证保证重放一致,版本化兼容旧事件。

#

82. 在 GraalVM Native Image 下使用 Spring Modulith 构建事件驱动架构的反射配置最小集

在 GraalVM Native Image 下使用 Spring Modulith 构建事件驱动架构的反射配置最小集是什么?

  • Native Image 反射
  • Spring Modulith 事件
  • 最小配置

在 GraalVM Native Image 下用 Spring Modulith 构建事件驱动架构,反射配置最小集:事件对象(事件类需注册反射,因事件序列化/反序列化需反射)、模块事件监听器的注册(Spring 容器反射)、事件处理的序列化配置。Spring Modulith 的事件发布与回放依赖反射与序列化,需 @RegisterReflection 或 runtime hints 声明事件类、监听器。最小集是"事件类 + 监听器 + 序列化"的反射 hint,配合 AOT 处理。

Native Image 下事件架构需反射 hint(事件类、监听器、序列化),保证事件处理正常运行。

#

83. 性能/可用性/扩展性的 SLI/SLO/SLA

请说明性能/可用性/扩展性的 SLI/SLO/SLA?

  • SLI/SLO/SLA
  • 性能/可用/扩展
  • 定义

SLI(Service Level Indicator)是度量指标(如可用性 99.9%、P99 延迟、错误率);SLO(Service Level Objective)是目标值(如 P99 < 200ms、可用性 99.9%);SLA(Service Level Agreement)是与用户的协议(含赔偿)。性能 SLO 用延迟/吞吐指标,可用性 SLO 用可用率/错误率,扩展性用吞吐随容量增长。定义 SLO 用 SLI 度量,SLA 是 SLO 的对外协议。用 SLI 度量、SLO 目标、SLA 协议保障服务质量。

SLI 度量、SLO 目标、SLA 协议,性能/可用/扩展各有对应指标与目标。

#

84. 故障演练(Chaos Engineering)的边界

请说明故障演练(Chaos Engineering)的边界?

  • Chaos Engineering
  • 故障注入
  • 边界

故障演练(Chaos Engineering)主动注入故障(延迟、中断、资源耗尽)验证系统韧性。边界:在生产/准生产进行,需控制爆炸半径(小范围、可回滚);注入"可恢复"的故障(避免不可控损坏);演练前有回滚预案;关注"验证假设"而非制造破坏。边界还在于:不演练关键数据丢失、不破坏持久化、合法合规。故障演练用受控的故障注入验证系统的容错与恢复能力,需有预案与边界。

故障演练是受控故障注入,需控制爆炸半径、可回滚、不破坏关键数据,验证韧性。

#

85. 绞杀者模式迁移旧系统时,流量路由、数据双写和回退开关应按什么顺序演进

绞杀者模式迁移旧系统时,流量路由、数据双写和回退开关应按什么顺序演进?

  • 绞杀者迁移
  • 流量路由
  • 数据双写与回退

绞杀者模式迁移旧系统的演进顺序:先做数据双写(新系统与旧系统同时写,保证数据一致,为切换做准备);再开流量路由(把小比例流量切到新系统,验证);最后逐步放大流量并保留回退开关(新系统出问题可快速切回旧系统)。顺序是"先数据就绪 → 再小流量 → 后放大 + 可回退"。回退开关保证任一步失败可回到旧系统,数据双写是切换的前提。

迁移顺序:数据双写先行、流量灰度路由、回退开关兜底,逐步放大并可回退。

#

86. 架构的安全设计(Security by Design)

请说明架构的安全设计(Security by Design)?

  • 安全设计
  • 安全内置
  • 实践

架构的安全设计(Security by Design)把安全作为架构的一部分而非事后补丁:从设计阶段考虑威胁建模(识别威胁)、安全分层(网络、应用、数据)、最小权限、认证授权、数据加密、安全默认值。安全设计贯穿架构:网络隔离(NetworkPolicy)、应用安全(认证/授权/输入校验)、数据安全(加密/脱敏)、供应链安全。优先级是"安全内置"而非"安全附加",安全缺陷在架构层难以修复,故设计期即考虑。

Security by Design 把安全内置到架构(威胁建模、分层、最小权限、加密),避免事后补丁。