Files
autumn-recruitment/07.模式/fsm/有限状态机在业务中的应用_test.md

145 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 个要点即可得满分;完全正确需覆盖全部要点。
## 关联笔记
- [[有限状态机核心概念]]