--- tags: [test/review, fsm, pattern, workflow-engine] create time: 2026-08-09 12:00 --- # 有限状态机在业务中的应用 — 测试题 ## 概述 本测试覆盖 FSM 的三种典型业务场景:审批流、订单生命周期和资源交付八阶段,以及非法转移防护和并发安全要求。共 10 道题目(6 选择 + 3 填空 + 1 简答)。 --- ## 一、选择题(6道,由浅入深) > **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景 ### Q1(基础)— 考察定义层面 以下哪条订单状态转换是**非法**的? A. PendingPayment → Paid(用户支付) B. Paid → Cancelled(已支付的订单直接取消) C. Shipped → Completed(用户确认收货) D. Refunding → Refunded(退款完成) ### Q2(基础)→ 审批流中"驳回"的语义可以是: A. 只有一种——终止流程回到终态 B. 只有一种——退回上一步到前置状态 C. 两种都有可能——终止或退回,需要在模型中明确区分 D. 不是有效的状态转换事件 ### Q3(进阶)— 核心原理 资源交付八阶段中,为什么删除必须是**两阶段**的? A. 因为存储 API 不支持一次性删除 B. 先标记 CleanupPending 再执行物理删除,避免误删且支持回滚 C. 因为需要等待 CDN 节点同步 D. 因为需要先通知用户 ### Q4(进阶)— 比较/辨析 以下关于三种业务场景 FSM 的对比描述哪个是正确的? A. 审批流的循环转移最多(有退回修改) B. 订单生命周期的并发安全要求最低(单人审批) C. 资源交付是线性流程无循环转移 D. 三种场景的状态数量都在 5~8 之间 ### Q5(深入)— 场景推理 某电商平台的订单出现了一个状态转换请求:`Paid → Cancelled`(已支付后申请取消)。但系统校验发现这个转移是非法的。最合理的处理方式是: A. 静默忽略,不报错也不执行 B. 返回错误 "invalid transition: PAID -> [CANCELLED]" C. 自动将订单转为 Shipping 状态 D. 将该请求丢入后台慢慢处理 ### Q6(深入)— 源码级/边界场景 原文提到审批链动态变化(A 请假了由 B 代审)时不应使用什么方案? A. FSM 框架 B. 策略模式 + 规则引擎 C. 硬编码审批人 D. 数据库持久化 --- ## 二、填空题(3道) ### F1 — 填空1 审批流审计追踪中每次状态转换必须记录三个关键字段:_____、timestamp、comment。这些信息不可删除,用于事后合规审查。 > **提示**: 回想原文表格中的字段名。 ### F2 — 填空2 资源交付场景中,"流量统计"被建模为_____而不是事件,因为流量统计是一个持续监控行为而非瞬时动作。在实际工程中它可能通过 sidecar 或事件总线持续运行,不受单用户的控制流影响。 > **提示**: 回忆 FSM 的四个核心概念中哪个对应这个描述。 ### F3 — 填空3 订单生命周期并发安全要求_____,因为多人同时操作同一订单的场景频繁发生。解决方案是每步写 DB + 事件日志,必要时加乐观锁或悲观锁。 > **提示**: 原文中的形容词,表示一种程度级别。 --- ## 三、简答题(1道) ### S1 面试官问:"在一个在线学习平台中,一个课程工单从创建到完成会经历多个阶段:CREATED → ENROLLED → IN_PROGRESS → COMPLETED / DROPPED / REFUNDED。其中 REFUNDING 子流程包含 REFUND_REVIEW → REFUND_SUCCESS / REFUND_REJECT。如果 REFUND_REJECT 则回退到 IN_PROGRESS。请设计一个 FSM 状态图,并回答以下问题: 1. 哪些转换是非法的? 2. 如何防止用户在退款审核中途重复提交退款申请? 3. 如何处理退款失败后的状态恢复?" > **答题框架提示**: > 1. 画出完整状态转换图(用文字描述节点和边) > 2. 分析非法转换场景 > 3. 讨论幂等保护机制 > 4. 异常路径的设计 --- ## 参考答案与解析 ### 选择题答案 | 题号 | 正确答案 | 解析 | |------|---------|------| | Q1 | B | 原文列出的非法转移示例:Paid → Cancelled(已支付的订单不能直接取消),应该走 Refunding → Refunded 路径。Completed → Shipped 和 PendingPayment → Shipped 也是非法的。 | | Q2 | C | 原文明确指出:"驳回"可以是终止(回终态 Rejected)也可以是退回上一步(回到前置状态 ManagerRevise → Draft)。需要在模型中明确区分,不能混为一谈。 | | Q3 | B | 原文警告:资源删除必须是两阶段的——先标记 CleanupPending 再执行物理删除。跳过这个阶段是数据丢失的头号原因。这提供了误删回滚的安全网。 | | Q4 | C | A 错:订单生命周期也有循环(Refunding → Paid 退款拒绝→重新支付);B 错:订单并发安全要求极高;D 错:资源交付是 8 个状态不在 5~8 的下限范围内。只有 C 正确——资源交付是线性流程无循环。 | | Q5 | B | 非法转移应返回明确的错误信息而非静默忽略。原文明确说:"非法转移应返回错误或被拒绝,而非静默忽略"。这样调用方能知道哪里出了问题。 | | Q6 | C | 原文指出:审批链动态变化时硬编码审批人在生产环境中是不可接受的。应引入策略模式 + 规则引擎,让审批人分配变成可配置的。 | ### 填空题答案 | 题号 | 答案 | 解析 | |------|------|------| | F1 | `operator` | 审批流审计追踪的三个核心字段:operator(谁操作的)、timestamp(何时操作)、comment(什么理由)。这些数据不可删除以保障合规性。 | | F2 | `状态` | 原文原话:"流量统计是一个持续的监控行为,不是一个瞬时动作。FSM 在这里只记录'是否已进入此阶段'"。它是一个持续的行为标记。 | | F3 | `极高` | 订单场景多人同时操作(如用户支付、客服退款、仓库发货可能在极短时间内相继发生),必须有强并发保护(乐观锁、事务、事件日志)。 | ### 简答题参考答案 S1:**参考答案要点**: 1. **完整状态转换图**:CREATED(初始) → ENROLLED(报名) → IN_PROGRESS(进行中)。IN_PROGRESS → COMPLETED(完成) / DROPPED(退出) / REFUNDING(申请退款)。REFUNDING → REFUND_REVIEW(审核中) → REFUND_SUCCESS(成功) → IN_PROGRESS(恢复) / REFUND_REJECT(拒绝) → IN_PROGRESS(继续学习)。 2. **非法转换**:CREATED → COMPLETED(未报名就完成);ENROLLED → DROPPED(需要先开始才允许退出);COMPLETED → IN_PROGRESS(已完成不能倒回去继续学);IN_PROGRESS → CREATED(只能前进不能后退到更早状态)。 3. **防重复退款**:在 REFUNDING 状态下设置屏蔽——只有在 IN_PROGRESS 才能发起退款。收到退款请求时检查当前状态,如果不是 IN_PROGRESS 直接拒绝。配合数据库唯一约束做最终兜底。 4. **恢复设计**:REFUND_REJECT 回到 IN_PROGRESS 是因为退款失败不代表要退出课程。但如果是 REFUND_SUCCESS 则直接进入已完成状态(因为已经退款,服务关系终结)。 **评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点。 ## 关联笔记 - [[有限状态机核心概念]]