代码行为异常容错机制与自我调节

2021年9月6日 3点热度 0条评论 来源: 苁心開始

目录

1、吧啦吧啦吧啦

1.1、代码自我意识

1.2、代码功能安全

1.3、代码保密性

1.4、代码执行完整性

1.5、代码的容错机制与自我调节

2、设计观与方法论

2.1 设计观与代码容错机制、自我调节

2.2 问题是否能够被解决

2.2.1 意识行为是否具有虚拟性

2.2.2 思维是否具有方向性

2.3 问题与问题解决

2.4 软件与问题

3、代码容错机制与异常

4、一个微型实例

4.1 业务逻辑异常

4.2 执行控制异常

4.3 系统级别异常

5、代码容错机制与自我调节总结

“行为”“自我调节”是心理学和日常生活中比较常见的用语,意义还是很明确的,那么,无论从信息加工论的认知观来看,还是从类比人的心理活动和行为、对代码构建一种新的描述方式来看,“代码行为异常”“代码自我调节”意义都是很明确的。

 

1、吧啦吧啦吧啦

吧啦吧啦吧啦是什么?补习时,学生模仿我讲道理的时候常常会说“吧啦吧啦吧啦”以示略过。在这里,它就算是一些表达我观点概念性词语吧。这些概念就是电影里的快镜、远景或背景旁白,虽然只有廖廖几个,却足以勾画我的道理的基本框架,成为电光石火间的一道思绪掠影。

 

1.1、代码自我意识

“代码是具有自我意识的。”

“年轻人,别太高大上。”

代码就是一篇由程序设计语言承载的“小说”,或短篇或中篇或长篇,不同于文学小说的是,代码反映的内容只有一项:这个问题怎么解决。说代码具有自我意识,这是基于既把代码当作、又是代码能够成为独立对象的。程序运行过程中对自身、对运行环境的感知与评价就是代码的自我意识。这对于大多数软件来说,是处于正常业务逻辑之外的,也是不必须的。而说到自我意识,就不得不面对终极之问:我是谁?我存在吗?这种终极之问的答案在同一个维度内和同一个形式系统内很难回答:在找到更高级的智慧生命形态之前,我思故我在可以通过感知思考过程证明客观实在的“我”,但是代码却很难从同一代码系统内的指令层面上对为用户服务的自己、虚拟环境下的自己和反编译下的自己做出绝对区分。软件漏洞问题实际上就是涉及方方面面的逻辑检测、异常捕获是否得到充分展开的问题。如果存在充分展开就会在代码层面上形成一个良好的自我意识系统。

 

1.2、代码功能安全

软件是为解决一定问题、实现某个业务功能而存在的,软件代码中为确保业务功能得以正常实现的、系统或局部机制下的、在常规业务逻辑流程之外的代码行为都属于代码功能安全范畴,包括代码保密机制、代码执行完整性检查、代码容错机制与自我调节,不包括业务逻辑内的身份验证、使用授权、通信加密等。软件处理的业务越重要,代码功能安全问题就越突出。代码功能安全机制很像带有独立功能的单位的秩序保障机制,有了它,软件的功能才得以平稳而有序地展开,这个世界才会有另一个精彩绝伦的故事,给世间创造一笔笔财富。对于大多数软件来说,一般只要求能实现正常的业务逻辑、一定期限内稳定运行即可,对软件功能安全的意识和要求不高。软件一般会有代码容错和自我调节机制,较高层次的软件支持执行完整性,更高一级的系统(更底层生态的系统)才可能会在前两者基础上要求代码保密。

 

1.3、代码保密性

不记得是谁说过,比陆地更广阔的是海洋,比海洋更广阔的是天空,比天空更广阔的是你我的心胸。可是,我就要告诉你,人的心胸再大,也装不下不应该知道的秘密。保密是一个老得掉牙的话题。底层基础的、原理的、原子的以及核心的代码往往是双重非公开,既是用户非公开,也是普通设计员或技术维护员非公开,还是形式非公开。用户眼里,软件永远只是一个个交互界面。而普通设计员或技术维护员,只能访问和修改公开性的授权代码。形式非公开,是指即便通过一定技术手段,也只能得到一行行的形式代码,即以或二进制指令、或机器指令、或字节码等形式而存在的代码,但却只是一种加密形式,非原来代码本身。这也是一种认知非公开。说到这里,我不得不赞叹一句:是谁发明了加密这种极具智慧的方法?比如说,小三(2)班只有李雷会讲英文,一天转来一位新加坡的新生露西。韩梅梅只想和露西讨论习题的时候,会偷偷地把露西拉到一个没人的地方,而当李雷只想和露西讨论的时候,则可以正大光明地于阳光之下用英文和露西交流,其他同学同样只有蒙圈的资格。

 

1.4、代码执行完整性

代码执行完整性问题实际上是关于“我是我吗”或“你是谁”的问题,是正常业务逻辑内或代码系统本身在“自我信息感知”这一层面上,确保自己或对方是合乎要求的自己(自然独立实体)或对方(非冒充者)的一种身份确认和保证特性。这对于基于网络传输的软件来说无疑是意义重大的。关于执行完整性,我在网上找到一些资料,一起来感受一下。

基于完整性的执行控制设计与实现,这是在百度学术中看到的一篇论文,摘要:为防止外来漏洞程序(如来自网络或U盘)威胁系统,本文在LSM框架下构建一个基于完整性的执行控制安全模块,控制这些程序的执行。为区分这些程序,本文定义了完整级,将这些程序标记为最低完整级,普通用户不能执行这些程序,而超级用户可以在构建的沙箱中执行这些程序,从而确保系统的安全。

从摘要看出,这种执行完整性控制是环境级别的,不是软件自身自发的,而是来自外在运行环境的监测。类似这种设计的检测与控制模式在杀毒软件或其他安全软件中用的比较多。

一种程序执行完整性保护方法和系统 [发明],这是在专利之星系统中检索到的内容,摘要: 本发明公开一种程序执行完整性保护方法,包括:根据跳转指令,将程序分割成顺序执行的程序块,在每个程序块的起始位置插入校验值标识CK_FLAG和校验值CK_VALUE;在程序运行时,进行实时程序块校验值计算,并和预先计算好的程序块校验值进行比较,在程序块受到破坏或者没有按照预期执行程序块时给出警报信号。

从摘要来看,这是一种比较典型的完整性检查,可以和某些类型的文件在网络传输中的校验检查做类比,主要检查程序当前的执行指令或模块是否是按照设计者最初的设计进行的。如果是,那么这种执行是完整的,否则是不完整的,即代码的当前行为不是代码本身、而是外在因素发起的,当前的代码行为环境是虚拟而非真实操作系统。执行完整性检查既是一种智慧活,需要一定的策略来确定代码的自然独立和真实性,也是一种智力活,检查策略将以系统性的代码形式体现出来,即能够被翻译成合适的计算科学技术和方法。我能通过我正在思考确定我的客观实在性,但我又是怎么知道我在思考的?很明显,自我感知。也就是说,要把策略转化为形式代码。

以上两种方式侧重点有所不同,但可大致归类于执行完整性检查,第一种是来自代码外部的,基于代码的完整性作出安全风险评估,并给予不同的执行环境,以尽可能地减少对真实的系统带给破坏性的影响。第二种是来自代码内部的,通过基于设计流的校验码来确定当前的代码行为是发自原始的自身。

 

1.5、代码的容错机制与自我调节

我首先来列举一下代码有哪些异常吧。代码异常有两种级别:系统级别和软件级别。软件级别的异常又分执行控制异常和业务逻辑异常。

系统级别异常:软件正常运行所需要的资源,如权限、内存空间、某种设备资源使用通道、所依赖的系统组件等,操作系统因某种原因无法给予正常提供而导致的访问、修改、运行异常,即代码无法正常进行当前阶段的业务处理行为,实现某个功能。

执行控制异常:执行控制异常即行为流向异常。在当前阶段,根据不同的输入,代码的行为会按照业务处理逻辑有条不紊地指向某一个方向。也即,在控制系统的协调下数据和实现业务的功能模块有序地交互作用。当这种有条不紊和有序受到破坏,也可看作是实现业务处理或软件本体处理及相关处理要求的“规律”受到破坏,从而引发执行控制异常。

业务逻辑异常:也可以称为问题求解异常。当实现某个功能所需的条件不成立时,求解过程或业务处理过程脱离预定逻辑,便发生业务逻辑异常。另一种情况是,数据是正确的,条件是提供的,但是解决方法不对。总之,无法实现正常的业务处理,解决问题。

上面只是代码异常的两种级别和分类,在不同的应用情境、语境下,这些异常都可以包含非常丰富的实际内涵。

代码行为就如学生行为,但比学生行为要可爱多一点,因为它们都可以是形式化的,界定起来要简单得多。一看就知道小明同学是学霸,可是像小明一样不迟到不早退、上课听讲认真下课作业倍儿棒地完成的同学多了去,然而考出99分的就只有小明。既然出现问题代码行为,自然要进行处理,以最低的代价使影响发生在最小范围,这就是代码的自我调节。而支撑代码自我行为调节的,就是代码容错机制。在设计代码容错机制与自我调节时,要注意的一个平衡策略是:既要能路径通畅,又不能代价太大。一般来说,要代价适中、适度地解决问题。如果解决问题的代价比问题本身的代价还要大,说明解决方法是错误的。如果两者代价相近,说明解决方法是可以更优的。如果解决问题的代价在问题本身代价一半附近甚至更低,则解决方法是较优的。我这里也只是以一种设计型的视角做的一个大致规划,有兴趣的朋友可以进一步深入研究。

上述内容是我以一种认知的、基于计算机科学的、类比人类自身又以面向对象的设计方法或汇总或建构起来的观点,这样,下面说起来就比较容易。

 

2、设计观与方法论

2.1 设计观与代码容错机制、自我调节

这里本不该用“设计”,太容易让人误解,因为一说到设计,自然以为是产品设计、程序设计、功能设计等等,实际上我这里的“设计”指的是“解决问题”设计,设计观实际上就是解决问题的策略观。因为这不是出于对许许多多的、大量的实例、事实、实验结果的总结、归纳和概括,而是一种个人观点,一种设计型的表述。也就是说,下面所说的是一种日常概念和直觉经验,是在对一些直觉经验或我自己也想不起来源的常识的归纳后做的假设演绎式推理。

我道理中的解决问题,就是指代码中容错机制和自我调节的具体内涵。也许像我一样,可能会有这么弱弱一问:那不就是软件测试和调试吗?从开发者行为形式和软件工程角度来看,两者之间的确很像但又有本质区别。首先是对象主体不同,前者是代码自身行为,后者是软件测试者行为。其次是内涵不同,前者是体现代码容错机制和自我调节行为的设计的代码表现,是内在系统性的、策略性的,后者是对软件的一种测试与修改,是软件外部行为性的。最后,前者在代码中具体体现在逻辑检查、条件判断、异常捕获与处理的规划、潜在漏洞预测与控制以及更高要求的检查,后者则侧重对不同形态下同类业务问题是否能够正确解决的检查,包括语句、模块、功能、集成等方面的检查与修改。从这个意义上看,两者是有重叠的地方,但是对从具体中抽象出来的“问题”本质的把握,有助于解决问题时打开更广阔的视野从而找到更多通往目标的路径,以寻求更优。

 

2.2 问题是否能够被解决

终极之问:问题是否能够被解决?

什么是问题?怎样才是解决问题?我们可以从几个方面来吧啦一下。

 

2.2.1 意识行为是否具有虚拟性

你认为网络具有虚拟性吗?

玩过游戏的人都知道,游戏是具有虚拟性的。什么是虚拟?虚拟与现实相对,是非现实的,在认知上不把游戏中的一切和现实世界中的一切联系到一起,它们之间不具备相似性,游戏中的一切不能做为现实中任何行为的先行条件。那么网络呢?可能你出身于高教家庭,但网络的出生身份却是一种“超级工具”,它的工具性质使得其上的信息变化和现实中的事物变化能够一一对应起来,正如物理理论中的一些公式变化可以和现实中的事物变化能够一一对应起来,都是一种对应和描述关系。但是,当网络承载的非工具性功能越来越多,便充斥着大量不和现实变化对应的信息,和现实世界既非对应关系,也非描述关系,从这个意义来看,网络不也是一个大型游戏吗?网络和游戏,甚至和所有的被称为“信息系统”的东西一起,都有因建构而虚拟的一面。虚拟的程度如何,取决于网络上的信息能和实际生活有多大的联系,以及我们在现实中进行某个行为时有多以它们为决策参考依据。此外,网络本身也可看成是一个大型“信息系统”,作为人与现实世界交互的中介环节,这种中介性质是虚拟的;网络上各种类型的社区生态,以信息处理作为载体模拟现实世界人际交互的、非实质行动性精神交流,更具虚拟性。

你认为人类文明具有虚拟性吗?

前面说了网络的虚拟性,这种虚拟性是建立在网络上呈现的信息与现实生活中行为的联系密切程度、与现实世界变化的一致性程度上的,或者是建立在拟本体性上的。那么人类文明呢?这要从另一个角度来看一致性和本体性。

我插一句,用自然语言来说明想法就是好,如果是在一个形式系统上讲道理,那么,对于“这要从另一个角度来看”,可能会很难进行下去。

什么是人类文明?人类文明与自然世界相对应。放眼世界及历史发展,人类文明大致包含三部分:一是人类与人类自身特点和行为特点,二是人与人之间的关系和交互,三是人类创造出来的、能以一定方式表达和呈现的、实质性或非实质性之物,比如高楼大厦,学校,文化艺术品等。这三者组成人类文明,但是,高贵的我们会机智地从中选择一些作为人类文明象征。至于为什么要象征,往进化上说就是群体的代表必然是优质的,往情操上说就是我们人类必须是高贵的。

什么是自然?如果对于旁观者的我们以人类视角去看动物世界、植物世界和它们所在的生态环境,很容易概括出“自然”:行为表现与意识情感的高度一致就是自然。大多数动物、植物没有意识怎么办?别啊,不能和意识情感保持一致,行为反应、生理反应、自然变化和客体自身构造对应的功能高度一致不也一样的吗?说简单一点,也行:动物、植物的蛮与野就是自然。

自然性行为不是虚拟的,是实在客观的。

动值物具有自然“行为”,那是不是说像动物一样就是自然?

肯定不是的。人类和动物有差别,那么人类的“自然”必然有差别。

人类和动物有本质的差别吗?“人和动物的本质区别是劳动”、“使用物质工具进行劳动生产,这是人和动物最本质的区别”、“由于人有了以语言为主的第二信号系统,其学习与动物有了本质区别”,这些常见的教科书式说法很容易找到出处。流传范围的宽广可大致看成是客观性的衡量指标,因而上述说法是大众认可的。精神生产工具是中介性质的,它的使用产生出作为人类社会发展结果的高级心理机能,于是人便有不同于动物的由感知觉、情感态度、意识需求、智力活动等构成的独有特性。其中,情感态度、意识需求决定着人的行为方向,智力活动是该方向的选择器和助推器。但我想说的是,人类和动物的最本质差别从外在上区分,是在所有物种的最大公因数式的生存条件下,进行以高级心理机能为依托的建构性语义行为,包括维持的和创造的。

人类行为有着客观虚拟性和独特自然性。人类行为的独特自然性,指人类行为是意识反应的外在表现,带有主动意识的行为表现是人类行为自然性的体现。并非只有像动、植物一样反应才是自然,因为人类有着和它们的本质区别。那么客观虚拟性呢?一方面,人具有动物不具备的高级心理机能和思维活动,对于从外界接收的信息做出处理变换后才表现在行为上,这种中介性加工变换使得人类的客观世界仅仅是一种语义映像,是对真实客观世界的一种描述、加工和反映。这和我们用一段程序来解决问题的过程没什么实质性的不同。所以人类和环境交互的行为具有客观虚拟性。另一方面,从一致性来看,人类行为分三种:一是无意识行为,这种行为只是缺少某个强烈的方向做为加工信息的指引,并非没有在头脑中加工处理信息;二是有意识行为且知情意行合一,这二种行为最能代表人类行为的自然,虽然它们是客观虚拟性的;三是有意识行为但知情意行不合一,这是人类行为客观虚拟性的典型代表。之所以不合一,是因为人类意识中建构性动机而非机体功能性动机的增多。

人与人之间的关系和交互是虚拟性的。人类行为产物既包含行为习惯,也包含人与人之间的关系及基于关系的交互作用,也就是你来我往大家一起讨论问题、做作业、交朋友和争第一名。为什么是虚拟的?并不是说人际关系和交互不是客观实在的,而是关系及基于关系的交互中的“关系”,带有浓浓的描述色彩和建构色彩。“色彩好看吗?”“好看,绿绿的太阳比红红的太阳更好看。”“太阳不是红色的吗?”“不,我只能感到绿色,只有绿色对我有意义。”关系是有意义的,所以是虚拟的。说到建构,不得不说到模仿,一种类型的模仿是:一段时间内人较原始的动机行为呈现一定方向性,随着时间推移,当人的自我意识加强或变化后,察觉到这种方向并总结成行事指导原则,指导后续行为,因而上升到意识水平,成为模仿。模仿的结果是,在一个新的层面上再次造就知、情、意、行的合一。另一种类型的模仿是意义建构:说得东式点,就是人法地,地法天,天法道,道法自然,高度建构性的“自然”还有另一层含义:使制度与规则的具体表征物像一个自然物运转。说得西式点,就是以一个客观对象为蓝本,在一代或几代人的理论钻研、技术改进的积累下,最终制造出该对象的人造之物。不管是模仿还是意义建构,都是虚拟的。

人类行为创造物的虚拟性。基于上面提到的虚拟性,大量的人造物都是某个自然物在人类世界中的呈现与映射,因而也是虚拟性的。

人类社会这个庞然又复杂的大物能够像一只鸟、一条鱼或者其他的有机体一样自然的运转,得益于一些制度、规则的遵循与维护行为。而这些行为都来源于人类意识。比如,学校之所以是学校,是因为从外在来说,有学校场地和相应人员、设施,从内在来说我们会把这样的场地、人员、设施“视为”学校的一种成分。即便有学校场所、有教室、有大门牌匾,但是人进去后只做一件事,找个空地栽栽树,那么“xx学校”对人类来说依旧只是一个林场,不具备“学校”的意义。那么社会或代表社会文明之物是怎么来的呢?如前所提的模仿与建构:反省、总结外加建构。而且,建构性意识行为也是有其建构依据或方向的,要么来自自身问题的改进,要么来自模仿外在物。对于人类而言,外在物很大的构成比例是动、植物及相关生态组成的自然界。因而人类社会的规则和自然界规律相比,本身具有效仿性,是一种人造规律。

无论是从信息的加工变换来看,还是从一致性来看;无论是从个体行为来看,还是从群体行为产物及群体的自身联系来看;无论从模仿来看,还是从建构来看,人类文明有一定虚拟性。

虚拟性并不代表人类文明的非自然。

所以,作为人类文明原因的人类意识行为具有虚拟性。

2.2.2 思维是否具有方向性

人类文明基于意识的维系,是带有虚拟性质的,既模仿大自然建构人造物又有自己独有的特点。这种模仿并非说我们一定要像大自然一样运作,或者是像大自然一模一样的运作,而是说通过人与人之间的有意识的维系性行为,使得人类社会能像大自然中的一个客观存在的、独立又统一的客观对象去运转。人类社会的规则如果要成为规律,是建立在人主动遵守的基础上的。

人造规律主要还是通过效法自然实现的。既然有效法,就一定有效法对象,因而我们的思维活动必定具有指向性,这种指向性体现在思维活动沿着思维规律向目标变化。思维规律其实就是大脑的物质性构造呈现的功能性规律在我们意识层面上的映射。这种内在规定性与意志、动机特别是建构性动机无关。无论是思维活动效仿的指向性,还是思维活动受思维规律制约,都说明思维活动是有方向、有序的。这种方向和有序便是人能解决问题的基础。

思维活动是客观或非客观问题的本体,因而,问题不一定能被解决,但是,问题可以被解决。

2.3 问题与问题解决

什么是问题?一说到问题,像我或我们这种计算机科学专业的人第一反应是程序中出现的BUG,一个函数应用错误,程序运行时的异常,操作系统中出现的错误。还有一些人的第一反应是最近一段时间内最熟悉事件中出现的、导致事件无法正常完成的感觉印象或客观事实。在心理学中,关于问题是什么早就有讨论了,一百多年来认知心理学这一分支所重点关注的内容中就有解决问题这一项。用我的观点来概括就是,在一个或多个视角下,在一个可描述的系统中,无论是形式符号描述还是自然语言描述,当一个带有系统性语义对象的变化偏离它“行进”的路径即变化规律时,此时的系统状态就是“问题”。问题有三个要素:系统语义对象,系统语义变化,系统语义下的变化规律。其中,系统语义对象是“偏离”系统语义下变化规律的,而系统本身则是或描述或模仿客观自然的,或是建构的。

自然规律的固有属性是方向、有序,对于人造规律来说也如此。当然还有变换,但这里先不把变换作为强调对象,因为这与具体功能或问题有关。一个对象之所以成为一个有机整体,是因为其各组成部分及之间的联系、交互是客观存在的,这些联系与交互是有方向的、有序进行的。这种解释同样适用人类文明中的某个对象,比如之前说的“学校”,只不过学校的构成和作为一个独立对象的行为规律都是一种人赋予的意义建构和该意义下人、物的组成与行为交互:我认为有这个意义,并始终按这个意义去做,客观世界也能形成相应方向下的变化,这个意义才是客观,我的行为才是规律的。人类的认知、思维活动也是有方向、有序的,这为问题的解决提供现实可能性。也因此,人的思维活动是应遵循也必然遵循思维的基本规范的,如同一律、矛盾律、排中律、充足理由律及其四重根等,这为形式化问题的出现和解决提供现实可能性。总之,问题能够被解决,是可能的。

那么什么是问题解决?

回到前面说的“问题”上来,问题解决有两种含义:系统语义对象从初始状态沿变化规律发展为目标状态的“路径”的形成,中间没有非变化规律上的,或者是变化规律上但不是变化规律预期的状态,是一种问题解决。怎么可能出现变化规律下的非预期状态?之前说过意识行为具有虚拟性,再加上认知影响,人类发现的规律并不必然与对应的自然规律保持全面和整体的一致;而人造规律就更次之,解决思维逻辑问题和保证行为一致性的策略问题后也只是达到一个模拟规律级别。问题解决的第二种含义是,在系统语义对象从初始状态发展为目标状态过程中出现非变化规律上的其他状态或变化规律上的非预期状态,即异常状态,通过系统调节或对象自我调节后,异常状态消失,重新回到变化规律上,最终到达目标状态。

如同最开始说的,我这里的“问题”是一种设计观,因为它带有浓浓的系统性语义,客观世界是不带“意义”的,就只那么存在着,概念和命题都是意识产物,即便最接近它本身的形式系统,也因为各种概念离它渐行渐远。语义是有意识的人类独有的自然现象,但是,它是一种意识产物,对于客观世界而言无所谓问题不问题,问题是一种意识“设计”概念,是唯心(意识产物)和唯物(模仿自然)的。

2.4 软件与问题

什么是软件?从软件工程视角来看,对外在的用户而言,软件是一个带有服务周期可实现需求的“生命对象”;对内在的开发人员而言,和基于公理推演出来的一些物理上的、数学上的形式理论系统类似:软件是一个形式功能系统,只不过这个形式系统既有静态信息和静态性质描述,也有动态信息和动态行为描述。数学等领域的形式系统和这不同,它们是人类在探索客观规律后的一种表达型却可推演的形式系统,是静态的,表达于其上的运动规律通过几个关键性指标及其之间的关系来刻画,是简洁、无歧义的形式系统。代码无需将一个动态变化过程进行关键性地标记,当然也可以这样,而是直接把这一过程描述出来,相当于通过操作系统进行翻译的一个机器脚本。这个动态过程可以是规律性的,也可以是步骤性的。软件的代码描述和操作系统的脚本式驱动共同构造出软件这个生命实体。

软件的方向性和有序性。作为一个带有生命周期的生命实体,软件具有功能需求方面的刚性标准,该标准的达到保障就是代码功能安全体系:代码的保密机制、执行完整性检查、代码容错机制与自我调节,无论用户强调不强调、开发者重视不重视其中一个或多个方面。软件功能的完整实现便是其代码行为方向。

我们从以下几个方面来分析软件问题来源。

首先,软件与系统环境。软件是在操作系统下运行的,软件与操作系统的交互——软件访问系统资源和系统查询软件信息——是软件代码行为异常的来源之一。访问的资源得不到应答时,以及操作系统局部异常或关键异常将直接导致代码行为异常。特别是访问的资源越处于系统底层,需要开发者维护的工作和职责就越多,越容易发生致命性异常。

其次,软件和使用者。软件的功能实现和业务的正常处理,取决于各种形式的数据输入和指令输入,如数据文件的数据、命令行指令或图形界面指令等,因此,如果使用者本身是一种无序的、非理性的、非目标业务预期的,可能会出现以下结果:软件运行时没有任何问题,但是得不到正确的业务结果。或者,这些数据或指令不符合实现某个功能的代码的语义要求或形式要求,将会导致代码行为异常。通俗地说,实实在在的问题是问题,没有相应操作技能的用户也是问题。

第三,软件定义与功能实现。软件功能的实现即是用户需求的实现,也即解决问题的过程实现,从而定义软件本身。问题求解自然是产生问题的高危地带,同时也是解决问题的必经过程。代码对业务处理的执行控制的复杂程度取决于业务复杂程度,越复杂对开发者的逻辑严密性、处理问题策略性要求越高。对于C/S架构的、支持并发方式处理业务的、带有前后端的软件,软件行为一直保持在自身闭环内很关键,即软件是在和架构内另一端的自己对话及其实现。而如果业务安全度较高,处理的信息非常机密,那么对于多种软件协作处理共同业务时,进行数据通信的各方是否属于同一个业务处理集群以及数据加密很关键。

后面会通过一个抛研引玉的小例子就上述三个方面进行探讨。

3、代码容错机制与异常

首先明白一点,对于软件来说,工具性是第一位的,其他一切机制都是围绕保障这种工具性的实现展开的。因此,在设计过程中,业务逻辑和业务逻辑异常的处理是主线,对于执行控制异常和系统级别的异常是“卡关键点”。当然,对于生态平台性的系统则不是仅仅是卡关键点,机制和策略的系统性很重要。异常发生时,最佳状态是,代码行为在业务处理或问题求解上的流程虽然被暂时中断,但仍旧保持在软件自身内部。通过一番调整,为待重新求解,或撤销之前代码的处理结果回到最初状态,或保存当前的处理状态,或调节自身状态回到业务逻辑上另一“地点”,整个过程代码行为始终保持在自身可控范围,这便是代码的容错机制。

什么是代码异常?任何在软件运行过程中出现的,业务处理及支持业务处理方面的非预期性行为或反馈都是代码异常问题,这种异常可能是操作系统级的,可能是自身执行控制系统的,也可能是业务逻辑的。

4、一个微型实例

问题定义:为数据文件中的每位客户建立指定路径下的工作目录

问题分析:

1、用户提供数据文件,文件中有客户信息,客户信息按一定结构存放,每位客户的记录结构为:客户ID,姓名,电话号码(客户相关信息代表)。

2、用户指定客户工作目录所在路径。

3、为每位客户建立各自的工作目录。

4、信息提示与反馈界面。

问题解决:接受指定路径与数据文件的输入,提取数据文件中相关客户信息(这里是客户的姓名)为其创建目录,输出结果为指定路径下创建好的每位客户的工作目录。

任何一个能够实现需求的软件都是一个问题得到解决的结果。首先要观察问题情境,理解其各组成部分及之间的联系,按照自顶向下的原则逐层分解,当分解到一定层次后,再分析该层次下制约问题解决的各种条件,理顺它们的先后关系并根据IPO(输入-处理-输出)定义出模块。所有的原子模块和集成模块一起便构成了整个问题的解。

在观察问题情境时,为避免不必要的业务逻辑异常,要确定好业务内和业务间的关系,以便考虑权限与可见;要确定业务的驱动形式与结果反馈,以便考虑输入、输出的表达和规范;要确定软件的性能需求、运行平台需求、质量需求,以便考虑问题能够得到解决的先行条件和约束要求。这些考虑在需求分析就要体现,形成整套系统,不向后堆积。

 

4.1 业务逻辑异常

什么是业务?“业务”二字在营销中出现得多,但现在可泛指一个岗位职责事务,业务能力就是实现一个岗位职责所需的事务处理能力。业务逻辑是指业务处理的信息化、形式化、代码化,实际上就是模仿和虚拟化,只不过模仿者和模仿对象从人与自然变成机器与人。在代码内部,业务逻辑是指确保所有输入都正确(语法正确、语义正确)的基础上,按照要求输出预期结果的整个处理流程。业务逻辑问题体现在业务逻辑异常上。在这个实例中,业务逻辑的异常将集中在输入、处理和输出结果的表达上。先看一种极简单的求解:

import os
print("当前工作目录是:{}".format(os.getcwd()))
filename=input("请输入用户信息文件:\n")    
with open(filename.strip(),"r") as f:
        targetDir=input("请输入要创建的各客户个人目录的父目录:\n")
        num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
        for i in f:
            cc=i.split(",")
            client=cc[num]
            os.mkdir(targetDir+"\\"+name)
print("生成客户个人目录完成,再见!")

整个程序流程很简单,业务逻辑也很简单,在提示当前的工作目录后,接收用户输入的数据文件、客户个人目录的父目录、客户姓名所在列号,然后处理数据,这里只是提取相关信息,并生成客户工作目录。

这个业务逻辑是建立在非常理想状态下的,即:所有的输入都是有意义的,所有的操作都是可实现的,任何时刻程序运行的条件都是满足的,以及数据文件内容是极优质的,即不存在引发更多求解步骤的数据。

我们可以从行为角度分析这些代码的性质:输入与输出部分,涉及到程序与用户、程序与操作系统的交互,发生异常的可能性受到用户和系统环境双重影响;输入和输出之间的业务逻辑,才是完全受程序自身决定的,对于其间可能发生的异常完全能够在业务流程内解决。

那么,业务逻辑异常处理从哪里开始?是按输入-处理-输出,还是先实现业务逻辑和软件功能再引入异常处理机制?是一部分一部分的完成还是一起完成?这取决于我们思维能同时关注的维度的数量,也取决于程序的编写习惯,有时候也受限于熊(安全)与鱼(功能)的取舍。总之,对于普通软件来说,功能和问题求解优先,再决定其安全。技术手段无法触碰的范围要制定必要的、保障软件正常运行的软件使用管理规范。用户多做一点软件实现就容易一点,用户少做一点软件就可能要复杂很多,这涉及投入预算与软件规模。特别是带有语义的数据,用户进行语义保证是很简单的事情,若由代码提供语义识别,将复杂许多。

这里就从业务逻辑实现上入手吧。假设数据文件不是最优质,但也不是很劣质(无序,无意义数据较多),在用户输入指定列以后,面临三种情况:

第一种情况,指定列不存在:最好解决,交给语句语法检查与异常处理;

第二种情况,指定列存在但不是客户姓名列:这属于语义正确性检查,较难处理,可以以输入规范和语法规则解决为主,再辅以特征检查(但不是绝对有效),最好是,用户的问题还是交给用户解决:删掉成功建立的目录(但不是预期的)重来一次。

第三种情况,指定列存在也是客户姓名列但存在相同姓名的客户:这是个问题吗?这取决于创建目录的函数的实现过程:当存在同名客户,上面用到的os.mkdir创建目录时会认为目录已存在而引发异常。这个比较好解决,创建目录前先验证文件中客户姓名数量,若有同名同姓者则以“姓名(客户ID)”作目录名。改进代码如下:

import os
from sys import exc_info
print("当前工作目录是:{}".format(os.getcwd()))
filename=input("请输入用户信息文件:\n")   
try:  
    with open(filename.strip(),"r") as f:
            targetDir=input("请输入要创建的各客户个人目录的父目录:\n")
            num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
            s=f.read()
            f.seek(0)  #文件指针移回文件首,以便下面的访问
            for i in f:
                cc=i.split(",")
                client=cc[num]
                if s.count(client)>1:
                    sss=targetDir+"\\"+client+"(学号{})".format(cc[0])
                else:
                    sss=targetDir+"\\"+client
                os.mkdir(sss)
    print("生成客户个人目录完成,再见!")
except:
    t,v,tb=exc_info()
    st=str(t)
    t=st[st.find("'")+1:st.rfind("'")]
    print("指定列内容有没有问题?以下是问题详情:\n{}:{}".format(str(t),v))

                                                                                           第一种情况

第二种情况,我把语义问题完全交给用户解决:删除目录,再运行一次。从图中也可以看出,第三种同名情况能得到处理。

以上业务逻辑异常类型及相应解决方式并未使运行脱离代码自身范围,这可为得到真正的、所需的“解”提供最大保障,因而是容错的。是的,对于简单实例来说很多人都能做到这一点,这不就是普通意义上的测试与调试吗?但是稍有不同的是,调试会消除程序中的已知问题,而这种代码的容错机制并不是完全这样:各种类型语句或函数抛出的异常要处理,为解决某类局部问题或改变业务的和执行的处理流程而主动抛出的异常要处理,对只在某些极特殊情况才出现但影响极大的异常要处理(这需要一双有洞察力的双眼和严谨的逻辑),某个功能实现过程中、或某个业务处理中出现的异常也要处理。对于一些不可消除的异常,各种可能性级别的异常,代码会如何调整自己的行为呢?这需要形成策略性和系统性机制。并且,当软件一旦规模变大,如何处理突然显现的潜在BUG、关于业务的平衡性策略又是如何,都值得仔细思考。

4.2 执行控制异常

执行控制是软件保证正常业务逻辑、业务辅助逻辑、软件本体逻辑正常运行的功能性逻辑。如果所有的业务逻辑和业务辅助逻辑能够缩小为一条语句,那整个软件系统就是一个执行控制逻辑(模块)。执行控制异常是导致软件本体完整性丢失,业务逻辑流无法正常流动,或业务逻辑无法继续进展的异常。

例子比较简单,就说说输入输出吧。输入和输出分别是一个业务逻辑的基本出发点和归宿点,输入关系到业务逻辑的正常进展和软件功能的具体实现,输出关系到软件本身的执行控制流向,是内在业务逻辑与外在执行控制逻辑的交接点。当然,这个例子中的输入、输出相对于内部业务逻辑的起始点、归宿点来说,更侧重于代码和用户、代码和系统之间的交互。

先看代码和用户。对于用户闭上眼睛瞎摸乱打导致的问题,全都可以交给语法解决,只要能捕捉语法问题导致的异常即可。需要费心的是语义性输入问题。例如,程序要求用户提供姓名,在用户输入后,程序怎么知道这不是一个姓名的问题。但是,这种问题的解决现在有着非常成熟策略:输入内容的规范化,即按照一定的语义性词法和语法输入。这也是让人多做一点的策略的体现,最典型的莫过于开发软件时需要程序员输入的代表问题解决过程某种程序设计语言了:虽然硬件设备只知道如何做但不知道“自己”在做什么,但是操作系统是清楚的;虽然操作系统只知道如何做但不知道“自己”在做什么,但是软件本身却是清楚的。根据问题定义,要为客户创建工作目录,需要用户提供的信息有:父目录、数据文件、姓名所在列。

父目录:输入的路径要符合python的语法,要符合创建/检查父目录的语句或函数的使用要求。无需语义处理,完全交给语法及异常捕获解决。如果目录已存在,将忽略创建,否则将创建指定目录;如果父目录路径输入不合法,提示用户重新输入。

数据文件:分三个层次。首先,输入的内容代表一个文件;其次,是一个数据型文件;最后,是符合业务处理逻辑“期待”的数据文件。最后一个层次实际上是对前两个层次的统合,因此以它为标准即可。是否是合法文件交由语法解决,是否是符合业务逻辑期待,我这里交由用户自己解决,即假定它是符合期待的。

姓名所在列:内容合法性交由语法解决,语义合法性交由用户解决。

代码对用户的要求是:形式合法,意义合法。用户对代码执行结果的要求是:符合形式,符合预期。代码运行结果是:在指定位置出现每位客户的工作目录。

再看代码和系统。代码通过打开文件与创建目录来和操作系统交互。打开文件用于获取数据,有可能被创建的父目录用于存放各个客户工作目录,因而这两者都可以看作是一种“输入”。而将创建的客户工作目录则是代码的“输出”行为。

打开文件:这里涉及的问题主要有路径是否合法、软件是否有权限进行这样的操作、文件打开过程中是否出错等。这些都可以交由异常捕获解决。

创建目录:目录创建实际上也是路径合法性与语句要求问题、执行权限问题、执行过程问题。

尽可能地对正常逻辑和语法问题之外的潜在的运行时错误或逻辑设计漏洞作应对策略,是代码容错机制的强力保证,也是代码具有较强容错性的体现。改进代码如下。

import os
from sys import exc_info
from time import sleep
while True:
    print("当前工作目录是:{}".format(os.getcwd()))
    targetDir=input("请输入要创建的各客户个人目录的父目录:\n") 
    try:   
        os.mkdir(targetDir)
        break
    except FileExistsError:
        print("父目录已存在,将略过创建!继续...")
        break
    except:
        print("路径名称输入有误或其他未知错误,3秒后请重输!")
        sleep(3)
        os.system("cls") 
filename=input("请输入用户信息文件:\n")
try:      
    with open(filename.strip(),"r") as f:
        num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
        s=f.read()
        f.seek(0)
        for i in f:
            cc=i.split(",")
            client=cc[num]
            if s.count(client)>1:
                sss=targetDir+"\\"+client+"(学号{})".format(cc[0])
            else:
                sss=targetDir+"\\"+client
            try:
                os.mkdir(sss)
                print("客户目录 【{}】 创建成功!".format(sss))
            except FileExistsError:
                print("客户目录 【{}】 已存在,将略过创建!".format(sss))
        print("\n生成客户个人目录完成,再见!")
except:  
        t,v,tb=exc_info()
        st=str(t)
        t=st[st.find("'")+1:st.rfind("'")]
        print("文件名或路径名是对的吗?指定列内容有没有问题?以下是问题详情:\n{}:{}".format(str(t),v))

                                                                                  父目录路径不对:为空

                                      父目录路径不对:os.mkdir要求最后一级目录前的路径是存在的,第一个test不存在。

                                                                             父目录指定为当前目录,已存在

                                                                                 创建目录时没有权限

                                                                                          父目录成功创建

                                                                                       输入的数据文件问题

                                                                                      客户工作目录成功创建

                                                                        重复性任务,将忽略新的创建过程

                                                         运行中,指定目录权限“突然”发生变更,没有访问权限

以上每项测试代表一个代码异常及相应处理行为,各项测试之间没有关系,测试条件分别单独设计。

4.3 系统级别异常

上面所说的执行控制异常中,输入、输出所涉及的权限问题也可以划分至系统级别的异常中来。由于输入、输出导致的异常或多或少地影响到正常业务处理逻辑流动,暂且先归入执行控制异常。系统级别的异常多来至软件外部操作系统环境的变更,和正常的问题求解过程无关,和语法、形式无关,和业务逻辑设计无关,和潜在的BUG、运行时动态出现的问题有关,和软件运行时的操作系统环境有关,和隐性问题的敏锐觉察与应对策略有关,和运行的时机有关。

第一种情况,和业务逻辑相关的系统环境变化。比如,在即将创建客户工作目录时,父目录由于某种原因被删除,从而导致创建失败。这种问题是异常捕捉机制设计策略决定的。我们可以有两种方式来推进业务逻辑的向前进展:一是代码行为流向的安全职责分布到各阶段,每完成一个阶段,就表示处于该阶段的风险完全得到消除,后续阶段将假定前面阶段不再有遗留问题,不再做重复性检查。二是每次在关键操作处检查执行该操作需满足的各种条件,代码行为流向安全由局部的统一处理保证。两种方式都各有优劣。这里用的是第一种策略:创建客户工作目录时,应该具备的条件在前面都得到保证后才能从业务逻辑上行进到这里,在代码内部,此时是可以断定是没有创建失败风险的。

第二种情况,我是我自己吗?也即代码是否是在一个真实的操作系统下运行,代码的行为是否是自发的。例如,通过专业手段,直接跳过前面各阶段的代码执行某种操作,此时,由于软件本体安全壁垒被攻破,运行时的各种临时数据可以被随意修改,既能引发很深的信息安全问题(比如说代码处理授权范围有限制或非公开的某些信息),执行该操作的各种先决条件也得不到可靠保证。这种问题只能通过执行完整性相关的检查机制解决。

第三种情况,软件正常运行在操作系统下的刚性系统条件变更。比如,软件依赖的某个系统组件、服务出错,突然断电等。解决这种问题要把握两个方向:一个方向是在软件内部要有运行状态保存策略,以便再次运行时继续执行;或者状态清理策略,以便再次运行时在多方认同的基础上重新求解问题。另一个方向是对于软件的部署实施要有危机处理策略,比如为计算机加装一台安全电延装置,当断电发生时,能为计算机提供一段安全时间续电,并向计算机发出已断电信号;而当软件接收到已断电信号后,进行相应处理后立即结束运行。改进代码如下,这里主要解决的是第一种情况,第二、三种情况有机会、有条件时再一起探讨,但是会对第二种情况做一个模拟演示:

import os
from sys import exc_info
from time import sleep
while True:
    print("当前工作目录是:{}".format(os.getcwd()))
    targetDir=input("请输入要创建的各客户个人目录的父目录:\n") 
    try:   
        os.mkdir(targetDir)
        break
    except FileExistsError:
        print("父目录已存在,将略过创建!继续...")
        break
    except:
        print("路径名称输入有误或其他未知错误,3秒后请重输!")
        sleep(3)
        os.system("cls")  
filename=input("请输入用户信息文件:\n")
flag=[]
try:      
    with open(filename.strip(),"r") as f:
        num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
        s=f.read()
        f.seek(0)
        for i in f:
            cc=i.split(",")
            client=cc[num]
            if s.count(client)>1:
                sss=targetDir+"\\"+client+"(学号{})".format(cc[0])
            else:
                sss=targetDir+"\\"+client
            try:
                os.mkdir(sss)
                print("客户目录 【{}】 创建成功!".format(sss))
                flag.append(1)
            except FileExistsError:
                print("客户目录 【{}】 已存在,将略过创建!".format(sss))
                flag.append(1)
            except FileNotFoundError:
                print("客户目录 【{}】 创建失败!请检查路径是否发生变更!".format(sss))
                flag.append(0)
        if sum(flag):
            print("\n生成客户个人目录完成,再见!")
        else:
            print("\n生成客户个人目录失败,再见!")
except:  
        t,v,tb=exc_info()
        st=str(t)
        t=st[st.find("'")+1:st.rfind("'")]
        print("文件名或路径名是对的吗?指定列内容有没有问题?以下是问题详情:\n{}:{}".format(str(t),v))

                                  假设运行前text\text目录已存在,在运行至输入指定列时将最后的text删除。

                                                    最后一级的text即父目录被删除后,创建客户工作目录失败

 

改动程序,在flag=[]语句下加一句:haha=False,然后在try中flag.append(1)下面加一句:if client=="王五":

                    if haha==True:os._exit(-1)

其他不变:

import os
from sys import exc_info
from time import sleep
while True:
    print("当前工作目录是:{}".format(os.getcwd()))
    targetDir=input("请输入要创建的各客户个人目录的父目录:\n")
    try:   
        os.mkdir(targetDir)
        break
    except FileExistsError:
        print("父目录已存在,将略过创建!继续...")
        break
    except:
        print("路径名称输入有误或其他未知错误,3秒后请重输!")
        sleep(3)
        os.system("cls")  
filename=input("请输入用户信息文件:\n")
flag=[]
haha=False
try:      
    with open(filename.strip(),"r") as f:
        num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
        s=f.read()
        f.seek(0)
        for i in f:
            cc=i.split(",")
            client=cc[num]
            if s.count(client)>1:
                sss=targetDir+"\\"+client+"(学号{})".format(cc[0])
            else:
                sss=targetDir+"\\"+client
            try:
                os.mkdir(sss)
                print("客户目录 【{}】 创建成功!".format(sss))
                flag.append(1)
                if client=="王五":
                    if haha==True:os._exit(-1)
            except FileExistsError:
                print("客户目录 【{}】 已存在,将略过创建!".format(sss))
                flag.append(1)
            except FileNotFoundError:
                print("客户目录 【{}】 创建失败!请检查路径是否发生变更!".format(sss))
                flag.append(0)
        if sum(flag):
            print("\n生成客户个人目录完成,再见!")
        else:
            print("\n生成客户个人目录失败,再见!")
except:  
        t,v,tb=exc_info()
        st=str(t)
        t=st[st.find("'")+1:st.rfind("'")]
        print("文件名或路径名是对的吗?指定列内容有没有问题?以下是问题详情:\n{}:{}".format(str(t),v))

这样改动为了在代码内部模拟一次系统环境变更导致的异常:当运行到为客户王五生成工作目录后,突然遇到某个系统性原因导致代码运行终止。

这是一个模拟环境,模拟代码的非自发运行。实际上这是一个调试状态,通过调试环境模拟代码在虚拟环境下的非自发运行,此时可以说代码并非操作系统下真实的自己。在原有的业务逻辑中,haha一直处于False状态,但是可以通过局部变量窗口手动修改它的值为True,来改变代码的执行控制流程和业务逻辑流程,并以此来模拟操作系统环境变更导致的异常终止。此时业务处理状态为:

                                                           这是假设系统故障排除后,重新(接着)运行的结果

 

最后,将刚才用于模拟环境异常的语句去掉,再加入界面信息,改进代码如下:

import os
from sys import exc_info
from time import sleep
while True:
    print("当前工作目录是:{}".format(os.getcwd()))
    targetDir=input("请输入要创建的各客户个人目录的父目录:\n") 
    try:   
        os.mkdir(targetDir)
        break
    except FileExistsError:
        print("父目录已存在,将略过创建!继续...")
        break
    except:
        print("路径名称输入有误或其他未知错误,3秒后请重输!")
        sleep(3)
        os.system("cls") 
filename=input("请输入用户信息文件:\n")
print("\n"+"*"*20)
flag=[]
try:      
    with open(filename.strip(),"r") as f:
        num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
        print("\n"+"*"*20)
        s=f.read()
        f.seek(0)
        for i in f:
            cc=i.split(",")
            client=cc[num]
            if s.count(client)>1:
                sss=targetDir+"\\"+client+"(学号{})".format(cc[0])
            else:
                sss=targetDir+"\\"+client
            try:
                os.mkdir(sss)
                print("客户目录 【{}】 创建成功!".format(sss))
                flag.append(1)
            except FileExistsError:
                print("客户目录 【{}】 已存在,将略过创建!".format(sss))
                flag.append(1)
            except FileNotFoundError:
                print("客户目录 【{}】 创建失败!请检查路径是否发生变更!".format(sss))
                flag.append(0)
        print("*"*20)
        if sum(flag):
            print("\n生成客户个人目录完成,再见!\n目标文件夹:")
        print(os.listdir(targetDir))        
        print("*"*20)
except: 
        if flag==[]:
            print("(此处空空)\n"+"*"*20)
        print("\n生成客户个人目录失败,再见!")
        t,v,tb=exc_info()
        st=str(t)
        t=st[st.find("'")+1:st.rfind("'")]
        print("文件名或路径名是对的吗?指定列内容有没有问题?以下是问题详情:\n{}:{}".format(str(t),v))
        print("*"*20)

                                                                                      任务成功完成

                                                                               创建任务失败

                                                                                     任务再续成功

                                                                                        数据文件打开失败

 

5、代码容错机制与自我调节总结

从信息加工作视角来看,计算机和人具有“大致相仿”的宏观结构和行为,但我们仍将计算机看作是“计算机”;但是对于具有人工智能系统的机器设备,我们会进一步称之为“人”:机器人。可见,不是它真的是人,只是我们将它与人的相似性特征和它一起视为“人”。基于这种观点,从独立客体角度出发,我们可以认为软件是一个客观存在的对象,那么对于软件内部的代码,则是主体的构成。因此,代码是有自我意识的。

软件存在的最大价值是其功能,具有工具性。如果说,以前的物质工具和精神工具还比较楚汉分明的话,那么软件的出现则模糊了这两者之间的界线。为确保软件功能得以正常实现,软件具备代码安全系统,具体来说是代码保密性、代码执行完整性的保障机制和代码容错机制与自我调节。为确保某个原子性功能,也就是在一个维度下无法再细分的功能对外是不可见、不可知的,需要将相关代码进行保密。当软件运行时其内部代码间的执令流动、数据流动都是软件本身发起的,且基于软件自身“控制机构”的“设计规律”,那么这些代码行为都是预期的。预期的代码行为可以保证信息机密、业务机密、代码机密不被非授权性访问、修改。如何保证所有的代码行为都是预期的,这是代码执行控制和完整性检查要做的事。一旦软件功能在实施过程中遇到内部代码执行困难,将触发代码容错机制,并进行自我调节,使得代码的执行控制始终保持在从软件运行到软件结束(此时不一定完全解决某个问题)这一功能实现期内,从而保证业务处理涉及的方方面面都能得到最优处理。

在代码容错机制展开时,可能会遇到业务逻辑异常、执行控制异常和系统级别异常。业务逻辑异常大多是得到某个结果的先决条件不具备,或者进行业务处理的方法、策略不对,分类、分级的分情况处理不全面、不完善。执行控制异常往往导致代码行为偏离业务逻辑流和软件本体功能流的正常“跑道”,这个时候就要小心部署,以期能够捕获各种代码行为异常,并进行相应调节,回到软件的本次功能实现。系统级别异常是非软件自身能够掌控的,要做的是及时得到系统异常信号,最大限度的完成相关的撤销清理或状态保存工作。

代码行为异常的几个经典原因,一是来自用户。用户在使用时要提供一定的所需数据和执行条件,这就涉及到数据的合法性、所需性与执行业务处理的合理性。我们还是遵循那个原则:过程性的问题交由技术解决,意义性的问题将由用户解决。用户操作规范少一点,代码就要复杂一点;用户操作规范多一点,代码就要精准一点。这是策略性的问题,具体问题具体分析,但是,适当的语义定义和尽可能地让用户做选择而不是提供数据是解决用户、软件之间交互问题的通用做法。说到用户和软件的使用交互,由于用户操作的不规范、业务不熟悉等原因,有时能导致用户引发的业务逻辑异常,这种异常往往是BUG(漏洞)性的。二是来自系统。软件与软件之间资源使用同步问题、业务处理同步问题,软件与操作系统交互问题,操作系统的环境突变问题,都是代码容错机制和自身调节重点关注对象,特别是涉及到操作系统底层资源,越底层关注度就应越大。上面两种代码行为异常原因侧重于策略和机制层面,实际上因为开发者对某个函数或方法等理解不够而导致代码行为异常的情况并不少见。

代码异常发生的时机也是应当重视的。即便语法没问题,业务处理逻辑没问题,解决方法很正确,仍然可能会有想像不到的异常“蹦”出来。在设计代码时,一些问题交由语法解决,如捕获语法问题导致的异常;一些问题交由语义解决,如按一定规范分析某个对象;一些问题交由先行条件检查解决,如检查处理该业务时是否具备条件,但是,还是有一些看似相当正常的代码属于认知误区或问题解决误区之内的,认知不清晰、忽略对它们的关注(态度)、检查的忽略(思维缺陷)本身就是潜藏BUG的关键原因。这类错误往往能通过词法、语法检查和编译,但是在代码运行的时候非必然性的、偶然性地概率性地出现。一旦出现,对于软件自身来说就是致命性的,对于重要业务处理来说是代价惨重的。

虽然代码容错机制与自我调节很重要,但也不必逐变量逐表达式地生抠死查。一是根据开发财务预算,二是根据业务的重要性完全可以采用不同等级策略。对于代价不是体现在一定数量级的人力、物力、资源上,不是体现在严格授权等级的越级上,不是体现在信息机密上,不是体现在非常关键非常重视的数据上,等等,完全可以将保障软件安全运行的重任交给用户。

最后再看一下通过python函数装饰器实现的相似异常的统一管理。统一管理异常的方法有很多种,就不展开了。

from os import mkdir,getcwd
from sys import exc_info
def Boom_and_Watch(objF):
    def wrap(*args,**kwargs):
        of=True
        try:
            of=objF(*args,**kwargs)            
        except FileExistsError:
            print("目录 【{}】 已存在,将略过创建!".format(args[0]))
            of=False
        except FileNotFoundError:
            print("系统找不到路径:{}".format(args[0]))
            of=False
        except:
            t,v,b=exc_info()
            t=str(t)
            t=t[t.find("'")+1:t.rfind("'")]
            print("{}:{}".format(t,v))
            of=False
        return of
    return wrap
mkdir=Boom_and_Watch(mkdir)
open=Boom_and_Watch(open)
################################################################
print("当前工作目录是:{}".format(getcwd()))
targetDir=input("请输入要创建的各客户个人目录的父目录:\n")
mkdir(targetDir)
filename=input("请输入用户信息文件:\n")
num=int(input("请输入用户名称在信息文件中的第几列(起始列为0)\n"))
print("\n"+"*"*20)
################################################################
try:
    with open(filename.strip(),"r") as f:
            s=f.read()
            f.seek(0)
            for i in f:
                cc=i.split(",")
                client=cc[num if 0<=num<len(cc) else 1]
                sss=targetDir+"\\"+client+"(学号{})".format(cc[0])
                if s.count(client)==1:
                    sss=sss[0:sss.find("(")]
                if mkdir(sss)==None:
                    print("目录 【{}】 创建成功!".format(sss))
except:pass
print("*"*20)
print("\n本次创建客户个人目录任务完成,再见!")

 

    原文作者:苁心開始
    原文地址: https://blog.csdn.net/lingyu_me/article/details/105185488
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。