当你参加比赛前,教练会问你状态如何;当你参加考试前,父母会问你状态如何;当你参加演出前,伙伴会问你状态如何。如果状态不好,那么你在这些活动的表现就可能不尽如人意,相反则可能有出人意料的表现。
可见,一个人状态的好坏会直接影响他的真实表现。但是,今天的状态不佳,明天的状态却有可能很好,可见状态也是会变化的。人如此,计算机也一样——计算机的很多思想都来自于人的生活,因此生活中的状态在计算机中也是遍地开花。
我最早接触状态机的概念是在学习编译原理的课程中。当时觉得状态机虽然在词法分析中发挥了神奇的作用,但总觉得抽象不太容易理解。后来在计算机的学习和工作中慢慢了解到状态机在计算机中还有很多应用,例如正则表达式。
正则表达式使用单个字符串(如图一)来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。比如[abc]d
既可以匹配ad
,也可以匹配 bd
,cd
。^1[3|4|5|7|8][0-9]\d{8}$
则可以匹配目前的手机号码。
图一:正则表达式
那么,正则表达式是如何起作用的呢?这就需要了解正则表达式的引擎了。目前主流的引擎分为 3 类:DFA(确定的有限状态机),传统型 NFA **(非确定的有限状态机),POSIX NFA**。
那什么是确定的有限状态机?数学上的严谨定义是确定的有限状态机从起始状态开始,一个字符接一个字符地读入一个字符串,并根据给定的转移函数一步一步地转移至下一个状态。通过状态图,我们可以清晰的看出这类状态机的大致模样(如图二)。
图二:有限状态机
简单来看,当 s1 状态在输入 0 的时候会进入 s2 的状态,而s2的状态在输入 0 的时候则会重新回到 s1 的状态,这种状态转移图正好符合正则表达的内涵。我们可以将某个正则表达式生成一张对应的状态图,然后根据输入的字符串来进行一个状态转移,如果过滤完该字符串后刚好到达有向图的结尾,那么该输入字符串则匹配了该正则表达式。
就拿之前提到的手机号码举例,^1[3|4|5|7|8][0-9]\d{8}$
对应的有向图如(图三),只有在输入符合条件的手机号码时,状态有向图才会从最开始状态走到结束状态。对于复杂的正则表达,借助状态有向图则可以达到事半功倍的效果。
图三:状态有向图
除了在正则表达式上的应用外,状态机还在网络协议中发挥了重要的作用。我们都知道 CDN 中离不开缓存系统,而被我们熟知的 ATS ( Apache Traffic Server )则是一个由状态机模型实现的异步事件处理程序。状态机模型具有很强的描述系统行为的能力,尤其是针对具有事件驱动的并发的特征的问题,用状态机来建模非常合适。将状态机作为一种构建系统的基本模块来对系统进行分解,将会使很多原本复杂的问题简单化。由此可见,状态机模型的引入可以有效解决协议处理过程的复杂性从而将系统变得简单和稳定。
曾经有个理论说,你最多通过其中的 6 个人就可以和世界上任何一位陌生人建立联系,果真如此的话,每个人的认识状态图也未免有些简单吧,不过每次的状态转移可不是这么轻松的哦。
另:本文由UPYUN CDN工程师 杨阳 供稿
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。