深夜的商场里,一台名叫小智的自动售货机器人正在巡逻。它时而停下接待顾客,时而“叮”一声吐出饮料,电量不足时溜回墙角充电,库存告急时拐进仓库补货。细心观察你会发现,小智从不“胡思乱想”——同一时刻,它永远只处于一种明确的工作模式:巡逻、接待、出货、充电或补货。是什么让它在这些模式之间切换?是顾客的出现、订单的确认、电量的报警……这些发生在它身上的“事件”。 这种“有限个状态 + 输入事件 + 跳转规则”的思考方式,就是有限状态机(FSM)。它是人工智能与自动化领域最朴素的决策模型:把系统可能所处的所有情况画成有限的格子,再约定格子之间的跳转规则,机器就能像小智一样稳定、有序地工作。本篇文章以小智为主线,从最基本的五元组讲起,依次介绍状态转移图、机器人行为切换、层次化FSM、代码实现方法,并把它和更复杂的“行为树”做一番对比,帮你彻底读懂这台“决策大脑”的运转逻辑。

岗位关联

掌握有限状态机的建模思维,是理解机器人决策系统的第一块基石。它能把混乱的行为逻辑梳理成清晰的图纸与代码,是“规划与控制”方向最经典、最实用的基础工具。

目录
  1. 可视化演示
  2. FSM基本概念:小智的心情清单
  3. 状态转移图:给小智画一张地图
  4. 机器人行为切换:感官与决策
  5. 层次化FSM:给小智装抽屉
  6. FSM实现方法:大脑三件套
  7. 与行为树对比:给小智换大脑
  8. 经典状态模式:把状态做成插件
  9. 适用场景与局限:工具边界
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示深入理解有限状态机FSM的核心机制,通过架构/数据/状态/性能四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

深入理解有限状态机FSM:有限状态 有限状态机FSM的形式化定义 状态转移图设计与建模 核心机制可视化 深入理解有限状态机FSM整体架构与关键组件

FSM基本概念:小智的心情清单

小智为什么从不慌乱?因为它有一张“心情清单”,清单上写满了它可能进入的全部模式:巡逻、接待、出货、充电、补货。任何时刻,小智只能勾选其中一个。这个“一次只能选一个”的清单,就是有限状态机的第一个关键词——有限状态集合。状态的数量必须有限,否则机器无法预先设计;状态之间必须互斥,否则小智会一边出货一边充电,场面就会失控。

有了清单,还需要“切换规则”。小智在巡逻时收到“发现顾客”信号,就切到接待;在接待时收到“确认购买”,就切到出货。这种“当前状态下收到某个事件就跳转到新状态”的规则,就是状态转移函数。加上用来触发转移的外部信号、机器上电时的初始状态,以及可选的终态集合,就凑齐了FSM的完整定义。

可以这样理解:五元组就是小智出厂时写进脑子里的“行为宪法”。只要外部事件不触发,小智就安安静静待在当前状态;一旦事件到来,δ 就按条款办事,把状态切换到下一个格子。有限、确定、可控,这是FSM最迷人的地方。

M=(S,Σ,δ,s0,F)\displaystyle M = (S, \Sigma, \delta, s_0, F)
这个五元组是有限状态机的“身份证”:S 是状态清单,Σ 是事件清单,δ 是切换规则,s₀ 是开机默认模式,F 是收工停机模式。
  1. 有限状态集合 S把系统所有可能的状态放进一个有限清单,比如小智的巡逻、接待、出货、充电、补货。
    S={s1,s2,…,sn}S = \{s_1, s_2, \ldots, s_n\}
  2. 输入事件集合 Σ刺激状态发生跳转的外部信号,例如“顾客出现”“电量低”“库存告急”。
    Σ={e1,e2,…,em}\Sigma = \{e_1, e_2, \ldots, e_m\}
  3. 状态转移函数 δ规定“在某个状态收到某个事件后,去向哪个新状态”。
    δ:S×Σ→S\delta: S \times \Sigma \to S
  4. 初始状态 s₀机器上电那一刻所处的状态,小智一开机默认是巡逻。
    s0∈Ss_0 \in S
  5. 终态集合 F可选的“任务完成”状态,比如小智进入停机维护模式。
    F⊆SF \subseteq S

状态转移图:给小智画一张地图

光有文字条款,工程师看起来还是费劲。于是大家把“状态清单 + 跳转规则”画成一张地图:每个状态是一个圆圈,每条跳转规则是一条带箭头的路,箭头旁标注触发事件。小智看到这张图,就像游客拿到景区导览图,一眼就知道自己在哪里、能去哪、走哪条路。

这张图就是状态转移图(State Transition Diagram)。图中的节点代表状态,有向边代表转移;边上的“事件”标签说明要发生什么才会走上这条路。有些更严谨的FSM还会在边上写“事件[守卫条件]/动作”,比如“订单确认[库存>0]/开始出货”——库存不足就不允许走这条路。状态转移图与转移表可以互相转换,转移表就是把图上的信息一行行整理成“当前状态、事件、下一状态”的清单。

对工程师来说,画图的过程就是建模的过程。每画一个新状态,都会逼问自己一次:这个状态下哪些事件合法?哪些转移会遗漏?如果小智在“出货”时收到“充电”信号,是忽略、排队还是立刻响应?这些边界问题,在图纸阶段暴露得越早,代码阶段就越省心。状态转移图不是流程图——流程图强调“先做什么后做什么”,状态转移图强调“处于什么模式,以及模式之间如何跳转”。小智的巡逻路线是普通流程图,但“巡逻中忽然低电回充”这种模式切换,必须用状态转移图才能表达清楚。

机器人行为切换:感官与决策

机器人学里有一句老话:感知、规划、行动。小智的“摄像头识别顾客”是感知,“决定切换到接待”是决策,驱动轮子过去是行动。FSM承担的正是“决策”这一环——它不关心轮子怎么转,只负责在正确的时间把状态切到正确的位置。机器人的行为切换,本质上是把一个复杂任务拆成若干个稳定“行为模式”。

以一台巡逻机器人为例,它可以处于四种行为状态:巡逻、追踪、避障、回充。传感器源源不断地送来事件:红外发现入侵者、超声波距离过近、电量低于20%。FSM收到“发现入侵者”事件,从“巡逻”切到“追踪”;收到“障碍物过近”事件,从“追踪”切到“避障”;收到“电量低”事件,无论当前在巡逻还是追踪,都无条件切到“回充”。这就是事件驱动状态切换的核心价值:转移不仅依赖当前状态,也依赖输入事件。

在设计机器人的FSM时,有一个常用技巧:把“持续动作”放在状态内部,把“瞬间动作”放在转移边上。小智处于“巡逻”状态时,轮子持续转动是持续动作;它从“巡逻”切到“充电”时,发出一声“电量低,去充电”的语音播报,这是瞬间动作。区分二者,能让状态图更干净。当你看到一台机器人在不同行为间流畅切换时,背后往往就是一张设计良好的FSM在稳定调度。

层次化FSM:给小智装抽屉

随着任务变多,小智的状态清单越来越长:接待细分出“询问需求”“推荐商品”“确认支付”,出货细分出“取货”“找零”“出货口检测”……如果把这些状态全部平铺在一张图里,箭头会密密麻麻地交叉,别说维护,光是看清就让人头疼。解决办法就像整理房间:给状态装抽屉。

层次化FSM(HFSM)允许一个父状态内部再嵌套子状态。比如把小智的“服务中”设为父状态,内部包含“接待”“出货”“找零”三个子状态;对外部来说,“服务中”还是一个整体状态。父状态能定义“继承”的转移规则:任何子状态收到“紧急停止”事件,都可以统一跳转到“待机”,不需要在每个子状态里各画一条线。子状态收到父状态没有处理的事件时,事件会“向上冒泡”交给父状态处理。

层次化的好处是显著的:原本 n 个子状态各画 m 条公共转移,需要 n×m 条线;抽到父状态后只需 m 条线。小智的状态图从一张密密麻麻的蛛网,变成一棵结构清晰的“状态树”。不过层次化不是银弹——层级过深会让事件传递路径变长,排查问题时多一层绕路。合理做法是“两层到三层”,像公司组织架构一样,别让小智的世界变成无限套娃。

S服务中={s接待,s出货,s找零}\displaystyle S_{\text{服务中}} = \{s_{\text{接待}}, s_{\text{出货}}, s_{\text{找零}}\}
这个式子表示“服务中”是一个复合状态,它内部还有三个子状态。子状态共享父状态的转移规则,从而减少重复连线。
  1. 父状态集合外层状态“服务中”内部包含的若干子状态。
    S服务中={s接待,s出货,s找零}S_{\text{服务中}} = \{s_{\text{接待}}, s_{\text{出货}}, s_{\text{找零}}\}
  2. 子状态归属“接待”等子状态都属于外层父状态,外部事件先由子状态尝试处理。
    s接待∈S服务中s_{\text{接待}} \in S_{\text{服务中}}
  3. 继承与上抛子状态处理不了的事件交给父状态,父状态的转移规则对全部子状态生效。
    δ(x,e)=y,x∈S服务中, y∈S服务中\delta(x, e) = y,\quad x \in S_{\text{服务中}},\ y \in S_{\text{服务中}}

FSM实现方法:大脑三件套

图纸画得再漂亮,最终要落到代码里让小智真正跑起来。实现FSM的方式成千上万,但最常见的是“三件套”:switch-case、查表法、事件队列。初学者最熟悉的是switch-case——用当前状态做外层分支,用事件做内层分支,逐条写转移。它的优点是直观易读,缺点是状态一多,嵌套分支会膨胀成难以维护的“意大利面”。

更工程化的做法是查表法:用一张二维表记录所有转移规则,表中每一行都是一条“当前状态 + 事件 → 下一状态”的规则。代码收到事件后,到表里查一次,找到匹配行就切换状态;找不到就忽略或记录日志。查表法把“规则”和“逻辑”解耦,新增一条转移只需在表里加一行,根本不用动业务代码。事件队列则是给FSM加了一个“信箱”:传感器事件先进入队列,FSM依次处理,避免多个事件同时到达时互相踩踏。

工业界还经常使用现成的状态机库,例如Python的 transitions、机器人操作系统ROS里的 SMACH。这些库已经把状态注册、转移查表、事件分发都封装好了,工程师只需要像填表格一样声明规则。小智的大脑并不神秘:一个状态变量、一张转移表、一个事件入口,就足以支撑起它一天的工作。记住,FSM最重要的不是用了什么语法,而是“状态与事件”的划分是否清晰。

δ(s,e)=s′,α(s,e)=a\displaystyle \delta(s, e) = s' ,\qquad \alpha(s, e) = a
δ 决定状态跳到哪,α 决定转移时输出什么动作。查表法实现时,表中每行记录的就是这样一条 (s, e) 对应 s' 的规则。
  1. 当前状态 s转移发生前小智所处的状态。
    s∈Ss \in S
  2. 触发事件 e让转移发生的外部信号。
    e∈Σe \in \Sigma
  3. 下一状态 s’调用 δ 之后得到的新状态。
    s′=δ(s,e)s' = \delta(s, e)
  4. 输出动作 a有些FSM在转移时会附带瞬间动作,比如播放提示音、发送消息。
    a=α(s,e)a = \alpha(s, e)

与行为树对比:给小智换大脑

有人对小智说:“FSM太老土了,现在流行行为树(Behavior Tree)。”小智很困惑。其实这两个工具根本不是替代关系,而是不同场景下的不同选择。FSM像是景区地图——你站在哪个景点、走哪条路,一目了然;行为树则像一份带优先级的任务清单——从上到下逐条检查条件,命中的任务就执行,执行不下去就返回失败、尝试下一条。

二者的差异主要体现在三处。第一,结构:FSM是“状态 + 状态之间箭头”的图结构,行为树是“控制节点 + 行为节点”的树结构。第二,复用:FSM的状态之间是网状耦合,抽出一个状态比较困难;行为树的行为节点可以独立挂载到任何一棵树上,模块化程度更高。第三,决策机制:FSM靠事件触发转移,行为树靠条件检查和优先级调度,天然具备“如果情况A就做X,否则做Y”的组合能力。

对小智的售货流程而言,FSM已经够用:状态就那么几个,转移清清楚楚。但如果让小智在整座商场里做复杂任务——先巡逻、遇到顾客就接待、同时监听火警、电量低还要回充——行为树能让这些任务按优先级组合起来,比FSM更舒展。工程上也不排斥两者混用:外层用行为树调度大任务,内层用FSM控制具体行为。给小智换大脑,不是把旧工具扔掉,而是知道什么时候用哪把刀。

经典状态模式:把状态做成插件

代码写多了,工程师发现if-else判断状态实在痛苦:每个功能都要先问“现在是不是巡逻?如果是,再判断是不是低电……”。这种写法不仅啰嗦,还容易漏掉组合。小智的状态切换,能不能像手机换主题一样“插拔”?这就是经典的状态模式(State Pattern)要解决的问题。

状态模式的核心思想是:每个状态都封装成一个独立的类,类里定义“收到事件时该怎么办”;上下文对象(Context)只持有一个“当前状态对象”,把请求委托给当前状态对象处理。状态对象内部决定“是否切换到另一个状态”。如果需要新增一个“巡逻”状态,只需增加一个巡逻状态类,不需要改动其他状态类的代码。

状态模式和FSM是一对好搭档:FSM是建模思维,状态模式是实现手段。小智的“充电”状态类内部封装了“充满电后切换回巡逻”的逻辑;上下文小智本人不需要知道充电的具体细节,它只知道自己当前的状态对象是谁。这样代码的可读性、可维护性都比散落的if-else高出一个量级。不过要提醒的是,状态模式适合状态数量适中的系统;如果状态上百个,类数量也会膨胀,这时回归查表法反而更轻量。工具没有绝对优劣,只有合适与否。

适用场景与局限:工具边界

给所有钉子都配一把锤子,是新手常犯的错。FSM虽然经典,但它有自己的适用边界。先看它擅长什么:状态明确、数量可控、事件驱动清晰的场景。售货机、电梯控制、通信协议、机器人巡逻——这些系统天生就是“状态 + 事件”的结构,用FSM建模既简洁又可靠。小智的售货流程就是典型例子:所有状态在出厂前就能穷举完,不会突然冒出第十种意外模式。

再看它的局限。首先是状态爆炸:如果系统同时包含多个维度的状态(位置、电量、任务、故障),平铺的FSM会组合出天文数字的状态数,转移表写到怀疑人生。其次是并行困难:FSM天然表达“同一时刻只在一个状态”,但真实机器人常常需要“一边巡逻,一边监控电量,一边响应遥控指令”——并行状态需要正交状态或并发扩展,模型复杂度和理解成本都会飙升。再者是历史状态:FSM默认只记住当前状态,如果任务要求“从上次中断处继续”,就需要额外维护历史栈。

小智最后明白一个道理:FSM是决策工具箱里的一把好刀,但不是万能刀。遇到状态维度少、逻辑明确的任务,优先用它,杀伐果断;遇到高维并行、动态组合的复杂任务,就考虑行为树、层次状态机或混合架构。真正的工程师不是只会用FSM的人,而是知道“什么是状态明确的场景”并选对模型的人。小智的售货大脑用FSM,商场总控用混合架构——各得其所,各尽其能。

AI 应用场景

多楼层巡检机器人

阶段:决策与规划

解决的问题:巡检机器人需要按计划巡逻、发现异常上报、低电自动回充。用大量if-else实现时,新增一种紧急情况就要改动多层嵌套逻辑,极易出错。FSM把“定时巡检”“异常上报”“回充待命”等行为建模为状态,传感器事件驱动切换,逻辑链路一目了然。

具体案例:某数据中心的巡检机器人通过红外传感器与电量计,在“巡检、报警、回充、待命”四个状态间自动跳转。夜间电量低于阈值时,机器人自发停止巡检并返回充电桩,充电完成后重新进入巡检序列,全程无需人工干预。

仓储AGV调度

阶段:多机调度与决策

解决的问题:潜伏式AGV需要完成取货、搬运、卸货、充电等动作,且要响应后台调度指令。FSM将每台AGV建模为“空闲、取货、送货、充电、避让”等状态,调度消息作为事件输入,状态切换清晰可控。

具体案例:大型电商仓库中,AGV收到“取货”指令后进入取货状态,托举货架后进入送货状态;电量低时暂停任务、切换到充电状态,充电完成再继续未完成任务。事件队列保证高并发指令不丢失。

工业机械臂取放料

阶段:运动规划与执行控制

解决的问题:机械臂的“待机—抓取—搬运—放置—回位”流程状态明确,由接近开关和到位传感器触发。FSM避免了大段状态判断代码,异常情况下还能安全切入“急停”状态。

具体案例:自动化产线的六轴机械臂在传感器信号驱动下按固定节拍上下料;当夹爪检测到异常夹持时,FSM将机械臂切到“急停”状态,排除故障并复位后继续生产节拍。

Python 演示

python41 行
class DemoRobot:    def __init__(self):        self.states = ['idle', 'approach', 'sell', 'charge', 'restock']        self.table = {            ('idle', 'customer'): 'approach',            ('approach', 'arrive'): 'sell',            ('sell', 'done'): 'idle',            ('idle', 'low_battery'): 'charge',            ('charge', 'charged'): 'idle',            ('idle', 'low_stock'): 'restock',            ('restock', 'filled'): 'idle',        }        self.actions = {            'idle': lambda: print('巡逻中,等待顾客或事件...'),            'approach': lambda: print('发现顾客,前往接待...'),            'sell': lambda: print('售卖中,完成出货...'),            'charge': lambda: print('电量低,返回充电桩...'),            'restock': lambda: print('库存不足,前往仓库补货...'),        }        self.current = 'idle'        self.actions[self.current]()     def send(self, event):        key = (self.current, event)        if key in self.table:            self.current = self.table[key]            self.actions[self.current]()        else:            print(f'忽略事件 {event}(当前状态 {self.current} 不响应)')  def main():    robot = DemoRobot()    for event in ['customer', 'arrive', 'done',                  'low_battery', 'charged',                  'low_stock', 'filled']:        robot.send(event)  if __name__ == '__main__':    main()
目的:演示用查表法实现一个自动售货机器人的FSM,事件驱动状态切换,模拟小智的完整工作循环。
  1. self.table = {...}用字典存储转移表,键是“(当前状态,事件)”,值是“下一状态”。
  2. self.actions = {...}每个状态对应的进入动作,状态切换后自动执行。
  3. self.current = 'idle'初始状态设为巡逻,模拟小智开机后的默认模式。
  4. def send(self, event)对外暴露的事件入口,相当于FSM收到一个输入信号。
  5. key = (self.current, event)用当前状态和事件组成的元组去查表,命中即转移。
  6. if key in self.table:查不到说明该事件在当前状态下不合法,选择忽略。
  7. self.current = self.table[key]查到后更新状态变量,完成状态跳转。
  8. self.actions[self.current]()进入新状态后执行对应的动作函数。

常见误区

误区很多初学者认为状态机必须写一个 `while True` 循环,不断轮询当前状态,否则就不叫FSM。

正解FSM是一种建模思想,而不是一种固定运行模式。关键在于“有限状态 + 事件驱动转移”,事件可以通过消息队列、回调函数、中断信号等方式投递。小智的传感器事件由硬件中断触发,并不需要它每秒反问自己“我现在该干嘛”。用循环实现只是其中一种方式。

为何常见:单片机教程里经常用 while + switch 写按键状态机,看多了容易把“实现方式”当成“定义本身”。

误区“进入状态就等于执行一段动作,离开状态就是动作结束”——这种理解把状态和动作混为一谈。

正解状态描述的是系统“处于什么模式”,动作是进入或离开状态时执行的副作用。小智在“充电”状态时,“插上充电枪”是进入动作,“拔枪出发”是离开动作,而“持续充电”是状态内部的持续过程。区分“状态、进入动作、离开动作、持续活动”这四层,是读懂FSM的关键。

为何常见:人习惯用“我在做什么”来描述状态,但机器的状态其实是“我处于什么条件下”。

误区“FSM状态越多,系统表达力就越强,所以要把所有细节都拆成状态。”

正解状态越多,转移表越复杂,状态爆炸会让系统难以维护。正确的做法是:把“确实不同的处理模式”设为状态,把“变化不大的细节”留在动作里。层次化FSM也能把大量子状态收敛到父状态中,而不是全部平铺在一张图上。

为何常见:新手画状态图时追求“一状态一细节”,没有意识到状态之间的组合数量是乘法级增长的。

误区“代码里写了几个 `if 状态 == ...` 的判断,我就用了FSM。”

正解if-else可以表达等价逻辑,但缺乏显式的状态建模,状态一多就会出现漏转移、难测试、不可维护的问题。FSM的价值在于把规则集中到一张表或一组状态类中,让“当前状态、合法事件、下一状态”一目了然。判断标准不是语法,而是有没有把状态与事件的关系显式建模。

为何常见:很多项目从if-else“演进”到FSM,但中间地带长得太像,让人误以为自己已经在用FSM了。

误区“行为树比FSM先进,FSM已经过时了,应该全面换成行为树。”

正解工具没有绝对高低。FSM擅长表达“状态明确”的切换逻辑,行为树擅长“复杂行为组合与优先级决策”。对小智的售货流程,FSM简单直接;对整座商场的全局调度,行为树更灵活。工程中两者经常混用,外层行为树管任务调度,内层FSM管具体行为控制。

为何常见:游戏AI圈流行行为树后,很多人被“新工具更优”的观点带偏,忽视了场景与工具的匹配关系。

面试题

Q1. FSM五元组中,符号S代表什么?

单选题 · easy

  • A.S代表有限状态集合← 正确答案
  • B.S代表输入事件集合
  • C.S代表输出动作集合
  • D.S代表终态集合

答案:A。五元组为 M = (S, Σ, δ, s₀, F),S是有限状态集合,Σ是输入事件集合,δ是转移函数,s₀是初始状态,F是终态集合。就像小智的心情清单,S才是那张“可勾选的状态列表”。

Q2. 状态转移函数δ的输入是什么?

单选题 · mid

  • A.当前状态和输入事件← 正确答案
  • B.上一个状态和动作
  • C.当前状态和输出信号
  • D.初始状态和终止状态

答案:A。δ 的定义域是 S × Σ,即“当前状态”和“输入事件”的组合。小智在“巡逻”状态收到“发现顾客”,δ 才有依据把状态切换成“接待”。输出信号是 α 的职责,不是 δ 的输入。

Q3. 状态转移图中,带箭头的边表示什么?

单选题 · easy

  • A.状态之间的转移关系← 正确答案
  • B.时钟周期的分隔线
  • C.传感器信号的波形
  • D.状态内部的动作流

答案:A。状态转移图中,圆圈是状态,带箭头的边是转移关系,边上标注触发事件。小智地图上“巡逻→充电”的箭头,就代表“电量低”事件引发的转移。

Q4. 层次化FSM引入父状态和子状态的主要目的是什么?

单选题 · mid

  • A.让状态图视图更接近树
  • B.通过嵌套降低状态数量← 正确答案
  • C.提升状态转移运行速度
  • D.自动生成随机事件序列

答案:B。层次化FSM把公共转移上提到父状态,子状态继承父状态的转移规则,避免每个子状态重复画线,从而降低整体状态数量与复杂度。它不是用来提速的,而是让结构更清晰。

Q5. 下列哪些属于FSM的基本组成部分?

多选题 · mid

  • A.有限状态集合← 正确答案
  • B.输入事件集合← 正确答案
  • C.状态转移函数← 正确答案
  • D.神经网络参数

答案:ABC。FSM五元组由状态集合、事件集合、转移函数、初始状态、终态组成。神经网络参数是机器学习模型的内容,与FSM的基本定义无关。小智的售货规则里没有神经元,只有状态和转移。

Q6. 关于FSM与行为树的对比,下列说法正确的是?

多选题 · hard

  • A.FSM状态间靠事件转移← 正确答案
  • B.行为树子节点可独立复用← 正确答案
  • C.FSM完全没有组合机制
  • D.行为树不支持条件判断

答案:AB。FSM靠事件驱动状态跳转,行为树的行为节点可以独立挂载和复用。但层次化FSM也提供组合机制,不能说“完全没有”;行为树恰恰通过条件节点和选择节点实现判断。C和D都过于绝对。

Q7. 巡检机器人“巡逻中”收到“电量低”事件,需要立刻回充。最合理的FSM设计是?

单选题 · hard

  • A.增加巡逻到充电的转移← 正确答案
  • B.设置两个并行状态机
  • C.扩展输入事件集合
  • D.关闭所有状态切换

答案:A。正确的设计是在状态转移图上画一条“巡逻→充电”的转移边,并让“电量低”作为触发事件。单独设计并行状态机会让简单问题复杂化;扩展事件集合(选项C)描述的是事件本身,并没有建模回充行为。

Q8. 用查表法实现FSM时,转移表通常用什么作为查询键?

单选题 · mid

  • A.当前状态与触发事件← 正确答案
  • B.触发事件与上一状态
  • C.当前状态与输出动作
  • D.系统时间与事件等级

答案:A。查表法的核心是把“当前状态+事件→下一状态”的规则存进表里,运行时用二元组 (当前状态,事件) 查表。这与 δ: S × Σ → S 的定义完全对应,是最直接的实现方式。

Q9. 关于有限状态机,以下哪个描述是正确的?

单选题 · easy

  • A.状态数量必须是有限的← 正确答案
  • B.任何时刻可处于多个状态
  • C.转移必须由定时器触发
  • D.状态之间只能单向转移

答案:A。有限状态机的前提就是“有限”,这也是它名字里“有限”二字的由来。小智任何一个时刻只能处于一种状态;转移由事件触发而不一定是定时器;状态之间完全可以双向转移。B、C、D都与FSM的定义冲突。

Q10. 状态模式(State Pattern)相比if-else状态判断,有哪些优点的说法是正确的?

多选题 · hard

  • A.新增状态只需增加新类← 正确答案
  • B.状态相关行为聚类到类中← 正确答案
  • C.需要在上下文中写大量分支
  • D.所有状态类完全独立不通信

答案:AB。状态模式把每个状态封装成独立类,新增状态无需改动原有分支;每个状态类内聚了该状态下的全部行为,上下文不再写大量条件判断。但状态类之间并非完全隔离,它们可以通过上下文对象交换数据。C是状态模式要消除的痛点,D说法过于绝对。