精华内容
下载资源
问答
  • 上篇我们大体讲了Flink容错机制的处理方法,和产生checkpoint的机制;这次主要讲一些补充 一,Flink的checkpoint形式 checkpoint有两种特殊形式: Savepoint:是一种特殊的checkpoint,只不过不像checkpoint定期的...

    上篇我们大体讲了Flink容错机制的处理方法,和产生checkpoint的机制;这次主要讲一些补充

    一,Flink的checkpoint形式

    checkpoint有两种特殊形式:

    Savepoint:是一种特殊的checkpoint,只不过不像checkpoint定期的从系统中去触发的,它是用户通过命令触发,
    存储格式和checkpoint也是不相同的,会将数据按照一个标准的格式存储,不管配置什么样,Flink都会从这个checkpoint恢复,是用来做版本升级一个非常好的工具;

     External Checkpoint:对已有checkpoint的一种扩展,就是说做完一次内部的一次Checkpoint后,还会在用户给定的一个目录中,多存储一份checkpoint的数据;

    二,Flink的状态划分

    Flink中包含两种基础的状态:Keyed State和Operator State。(Blink现在支持MapState)
    Keyed State

    顾名思义,就是基于KeyedStream上的状态。这个状态是跟特定的key绑定的,对KeyedStream流上的每一个key,可能都对应一个state。所以keyedState支持多种数据结构并支持动态拓展


    Operator State

    与Keyed State不同,Operator State跟一个特定operator的一个并发实例绑定,整个operator只对应一个state。相比较而言,在一个operator上,可能会有很多个key,从而对应多个keyed state。Operator State可以在任意流中使用但支持有限的数据结构(list)

    三,Flink状态持久化方式

    Flink有三种状态持久化的方式

    用户可以根据自己的需求选择,如果数据量较小,可以存放到MemoryStateBackend和FsStateBackend中,如果数据量较大,可以放到RockDB中。RockDB和FsStateBackend都支持将数据写在文件中,而文件路径传给master。

    MemoryStateBackend:state数据存储在内存中,并被保存在一个由多层java map嵌套而成的数据结构中,默认情况下,数据大小不可以超过5MB

    FsStateBackend:策略是当状态的大小小于1MB(可配置,最大1MB)时,会把状态数据直接存储在meta data file中,避免出现很小的状态文件。

    FsStateBackend另外一个成员变量就是basePath,即checkpoint的路径。它会记录状态的文件路径,然后传给master节点,一般用于记录容量比较大的状态。

    它会在本地文件系统中维护状态,KeyedStateBackend等会直接写入本地rocksdb中。同时它需要配置一个远端的filesystem uri(一般是HDFS),在做checkpoint的时候,会把本地的数据直接复制到filesystem中。fail over的时候从filesystem中恢复到本地。

    RocksDB:每个state存储在单独一个columnfamily中,存储状态的文件路径,只用于增量checkpoint。

    更新的时候会直接以key + namespace作为key,然后把具体的值更新到rocksdb中。

    做checkpoint的时候,会首先在本地对rockdb做checkpoint(rocksdb自带的checkpoint功能),这一步是同步的。然后将checkpoint异步复制到远程文件系统中。最后返回RocksDBStateHandle。

    RocksDB克服了HeapKeyedStateBackend受内存限制的缺点,同时又能够持久化到远端文件系统中,比较适合在生产中使用。

    本文章只用于理解,最后补充一下Flink实战的学习资源:

    1. 官网 https://ci.apache.org/projects/flink/flink-docs-stable/

    所有技术栈和接口都在官网文档中有介绍

    2. 数据仓库 https://www.ververica.com/flink-forward-san-francisco-2018

    各种有关于Flink前沿论坛的资料和视频

    3.阿里云flink系列 https://yq.aliyun.com/articles/225623#

    实战内容多一些,链接只是一个例子,教你如何在实战中配置使用

    4. 过往记忆 https://www.iteblog.com/archives/category/flink/

    很多大数据技术的中文文档

    5. Flink论坛 https://cwiki.apache.org/confluence/display/FLINK/Apache+Flink+Home

    可以看到很多课题和问题,以及解决方法

    6. github https://github.com/apache/flink

    源码才是王道

     

    展开全文
  • 代码行为异常容错机制与自我调节

    千次阅读 2020-03-29 21:32:22
    1.5、代码的容错机制与自我调节 2、设计观与方法论 2.1 设计观与代码容错机制、自我调节 2.2 问题是否能够被解决 2.2.1 意识行为是否具有虚拟性 2.2.2 思维是否具有方向性 2.3 问题与问题解决 2.4 软件与问题...

    目录

    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本次创建客户个人目录任务完成,再见!")
    

     

    展开全文
  • Flink状态管理和容错机制介绍

    千次阅读 2018-08-25 17:00:45
      本文来自8月11日在北京举行的 Flink Meetup会议,分享来自于施晓罡,目前在...状态管理和容错机制实现; 阿里相关工作介绍; 一.有状态的流数据处理 1.1.什么是有状态的计算    计算任务的结果不仅仅依赖于...

      本文来自8月11日在北京举行的 Flink Meetup会议,分享来自于施晓罡,目前在阿里大数据团队部从事Blink方面的研发,现在主要负责Blink状态管理和容错相关技术的研发。

    本文主要内容如下:

    • 有状态的流数据处理;
    • Flink中的状态接口;
    • 状态管理和容错机制实现;
    • 阿里相关工作介绍;

    一.有状态的流数据处理

    1.1.什么是有状态的计算

       计算任务的结果不仅仅依赖于输入,还依赖于它的当前状态,其实大多数的计算都是有状态的计算。 比如wordcount,给一些word,其计算它的count,这是一个很常见的业务场景。count做为输出,在计算的过程中要不断的把输入累加到count上去,那么count就是一个state。

    1.2.传统的流计算系统缺少对于程序状态的有效支持

    • 状态数据的存储和访问;

    • 状态数据的备份和恢复;

    • 状态数据的划分和动态扩容;

       在传统的批处理中,数据是划分为块分片去完成的,然后每一个Task去处理一个分片。当分片执行完成后,把输出聚合起来就是最终的结果。在这个过程当中,对于state的需求还是比较小的。

       对于流计算而言,对State有非常高的要求,因为在流系统中输入是一个无限制的流,会运行很长一段时间,甚至运行几天或者几个月都不会停机。在这个过程当中,就需要将状态数据很好的管理起来。很不幸的是,在传统的流计算系统中,对状态管理支持并不是很完善。比如storm,没有任何程序状态的支持,一种可选的方案是storm+hbase这样的方式去实现,把这状态数据存放在Hbase中,计算的时候再次从Hbase读取状态数据,做更新在写入进去。这样就会有如下几个问题

    • 流计算系统的任务和Hbase的数据存储有可能不在同一台机器上,导致性能会很差。这样经常会做远端的访问,走网络和存储;

    • 备份和恢复是比较困难,因为Hbase是没有回滚的,要做到Exactly onces
      很困难。在分布式环境下,如果程序出现故障,只能重启Storm,那么Hbase的数据也就无法回滚到之前的状态。比如广告计费的这种场景,Storm+Hbase是是行不通的,出现的问题是钱可能就会多算,解决以上的办法是Storm+mysql,通过mysql的回滚解决一致性的问题。但是架构会变得非常复杂。性能也会很差,要commit确保数据的一致性。

    • 对于storm而言状态数据的划分和动态扩容也是非常难做,一个很严重的问题是所有用户都会在strom上重复的做这些工作,比如搜索,广告都要在做一遍,由此限制了部门的业务发展。

    1.3.Flink丰富的状态访问和高效的容错机制

      Flink在最早设计的时候就意识到了这个问题,并提供了丰富的状态访问和容错机制。如下图所示:

    二.Flink中的状态管理

    2.1.按照数据的划分和扩张方式,Flink中大致分为2类:

    • Keyed States

    • Operator States

    2.1.1.Keyed States

    Keyed States的使用

    Flink也提供了Keyed States多种数据结构类型

    Keyed States的动态扩容

    2.1.2.Operator State

    Operator States的使用

    Operator States的数据结构不像Keyed States丰富,现在只支持List

    Operator States多种扩展方式

    Operator States的动态扩展是非常灵活的,现提供了3种扩展,下面分别介绍:

    • ListState:并发度在改变的时候,会将并发上的每个List都取出,然后把这些List合并到一个新的List,然后根据元素的个数在均匀分配给新的Task;

    • UnionListState:相比于ListState更加灵活,把划分的方式交给用户去做,当改变并发的时候,会将原来的List拼接起来。然后不做划分,直接交给用户;

    • BroadcastState:如大表和小表做Join时,小表可以直接广播给大表的分区,在每个并发上的数据都是完全一致的。做的更新也相同,当改变并发的时候,把这些数据COPY到新的Task即可

    以上是Flink Operator States提供的3种扩展方式,用户可以根据自己的需求做选择。

    使用Checkpoint提高程序的可靠性

      用户可以根据的程序里面的配置将checkpoint打开,给定一个时间间隔后,框架会按照时间间隔给程序的状态进行备份。当发生故障时,Flink会将所有Task的状态一起恢复到Checkpoint的状态。从哪个位置开始重新执行。

    Flink也提供了多种正确性的保障,包括:

    • AT LEAST ONCE;

    • Exactly once;

    备份为保存在State中的程序状态数据

    Flink也提供了一套机制,允许把这些状态放到内存当中。做Checkpoint的时候,由Flink去完成恢复。

    从已停止作业的运行状态中恢复

      当组件升级的时候,需要停止当前作业。这个时候需要从之前停止的作业当中恢复,Flink提供了2种机制恢复作业:

    • Savepoint:是一种特殊的checkpoint,只不过不像checkpoint定期的从系统中去触发的,它是用户通过命令触发,存储格式和checkpoint也是不相同的,会将数据按照一个标准的格式存储,不管配置什么样,Flink都会从这个checkpoint恢复,是用来做版本升级一个非常好的工具;

    • External Checkpoint:对已有checkpoint的一种扩展,就是说做完一次内部的一次Checkpoint后,还会在用户给定的一个目录中,多存储一份checkpoint的数据;

    三.状态管理和容错机制实现

    下面介绍一下状态管理和容错机制实现方式,Flink提供了3种不同的StateBackend

    • MemoryStateBackend

    • FsStateBackend

    • RockDBStateBackend

      用户可以根据自己的需求选择,如果数据量较小,可以存放到MemoryStateBackend和FsStateBackend中,如果数据量较大,可以放到RockDB中。

    下面介绍HeapKeyedStateBackend和RockDBKeyedStateBackend

    第一,HeapKeyedStateBackend
    第二,RockDBKeyedStateBackend
    Checkpoint的执行流程

      Checkpoint的执行流程是按照Chandy-Lamport算法实现的。

    Checkpoint Barrier的对齐
    全量Checkpoint

      全量Checkpoint会在每个节点做备份数据时,只需要将数据都便利一遍,然后写到外部存储中,这种情况会影响备份性能。在此基础上做了优化。

    RockDB的增量Checkpoint

      RockDB的数据会更新到内存,当内存满时,会写入到磁盘中。增量的机制会将新产生的文件COPY持久化中,而之前产生的文件就不需要COPY到持久化中去了。通过这种方式减少COPY的数据量,并提高性能。

    四.阿里相关工作介绍

    4.1.Flink在阿里的成长路线

      阿里是从2015年开始调研Flink,2015年10月启动Blink项目,并完善Flink在大规模生产下的一些优化和改进。2016年双11采用了Blink系统,为搜索,推荐,广告业务提供服务。2017年5月Blink已成为阿里的实时计算引擎。

    4.2.阿里在状态管理和容错相关的工作

      正在做的工作,基于State重构Window方面的一些优化,阿里也正在将功能做完善。后续将包括asynchronous
    Checkpoint的功能完善,并和社区进一步沟通和合作。帮助Flink社区完善相关方面的工作。

    更多精彩内容,请关注Flink china社区大群,下载“钉钉”。扫描下方二维码即可!

    展开全文
  • 拜占庭容错三个基本理论 1) CAP理论 - "如果网路发生阻断(partition)时,你只能选择资料的一致性(consistency)或可用性(availability),无法两者兼得"。论点比较真观:如果网路因阻断而分隔为二,在其中...

    拜占庭容错的三个基本理论

    1) CAP理论 - "如果网路发生阻断(partition)时,你只能选择资料的一致性(consistency)或可用性(availability),无法两者兼得"。论点比较真观:如果网路因阻断而分隔为二,在其中一边我送出一笔交易:"将我的十元给A";在另一半我送出另一笔交易:"将我的十元给B "。则此时系统要不是,a)无可用性,即这两笔交易至少会有一笔交易不会被接受;要不就是,b)无一致性,一半看到的是A多了十元而另一半则看到B多了十元。要注意的是,CAP理论和扩展性(scalability)是无关的,在分片(sharded)或非分片的系统皆适用。

    2)FLP impossibility (O网页链接)-在异步的环境中,如果节点间的网路延迟没有上限,只要有一个恶意的节点存在,就没有算法能在有限的时间内达成共识。但值得注意的是, "Las Vegas" algorithms(这个算法又叫撞大运算法,其保证结果正确,只是在运算时所用资源上进行赌博。一个简单的例子是随机快速排序,他的pivot是随机选的,但排序结果永远一致)在每一轮皆有一定机率达成共识,随着时间增加,机率会越趋近于1。而这也是许多成功的共识演算法会采用的解决办法。

    3)容错的上限-由DLS论文(O网页链接)我们可以得到以下结论: (1)在部分同步(partially synchronous)的网路环境中(即网路延迟有一定的上限,但我们无法事先知道上限是多少),协议可以容忍最多1/3的拜占庭故障(Byzantine fault)。(2)在异步(asynchronous)的网路环境中,具确定性质的协议无法容忍任何错误,但这篇论文并没有提及randomized algorithms在这种情况可以容忍最多1/3的拜占庭故障。(3)在同步(synchronous)的网路环境中(即网路延迟有上限且上限是已知的),协议可以容忍100%的拜占庭故障,但当超过1/2的节点为恶意节点时,会有一些限制条件。要注意的是,我们考虑的是"具认证特性的拜占庭模型(authenticated Byzantine)",而不是"一般的拜占庭模型";具认证特性指的是将如今已经过大量研究且成本低廉的公私钥加密机制应用在我们的演算法中。


    以上描述来自以太坊的官方Wiki - Proof of Stake FAQ (https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ

     

    • CAP theorem - "in the cases that a network partition takes place, you have to choose either consistency or availability, you cannot have both". The intuitive argument is simple: if the network splits in half, and in one half I send a transaction "send my 10 coins to A" and in the other I send a transaction "send my 10 coins to B", then either the system is unavailable, as one or both transactions will not be processed, or it becomes inconsistent, as one half of the network will see the first transaction completed and the other half will see the second transaction completed. Note that the CAP theorem has nothing to do with scalability; it applies to sharded and non-sharded systems equally. See also https://github.com/ethereum/wiki/wiki/Sharding-FAQs#but-doesnt-the-cap-theorem-mean-that-fully-secure-distributed-systems-are-impossible-and-so-sharding-is-futile.
    • FLP impossibility - in an asynchronous setting (i.e. there are no guaranteed bounds on network latency even between correctly functioning nodes), it is not possible to create an algorithm which is guaranteed to reach consensus in any specific finite amount of time if even a single faulty/dishonest node is present. Note that this does NOT rule out "Las Vegas" algorithms that have some probability each round of achieving consensus and thus will achieve consensus within T seconds with probability exponentially approaching 1 as T grows; this is in fact the "escape hatch" that many successful consensus algorithms use.
    • Bounds on fault tolerance - from the DLS paper we have: (i) protocols running in a partially synchronous network model (i.e. there is a bound on network latency but we do not know ahead of time what it is) can tolerate up to 1/3 arbitrary (i.e. "Byzantine") faults, (ii) deterministic protocols in an asynchronous model (i.e. no bounds on network latency) cannot tolerate faults (although their paper fails to mention that randomized algorithms can with up to 1/3 fault tolerance), (iii) protocols in a synchronous model (i.e. network latency is guaranteed to be less than a known d) can, surprisingly, tolerate up to 100% fault tolerance, although there are restrictions on what can happen when more than or equal to 1/2 of nodes are faulty. Note that the "authenticated Byzantine" model is the one worth considering, not the "Byzantine" one; the "authenticated" part essentially means that we can use public key cryptography in our algorithms, which is in modern times very well-researched and very cheap.

     


    =>更多文章请参考《中国互联网业务研发体系架构指南》

    =>更多行业权威架构案例及领域标准、技术趋势请关注微信公众号 '软件真理与光':

    公众号:关注更多实时动态
    更多权威内容关注公众号:软件真理与光
    展开全文
  • 一文读懂区块链共识及其容错机制

    千次阅读 2019-01-14 18:30:49
    翻译 | shawn编辑 | 波波区块链是一分布式和去中心化的系统,这意味着它需要一种可以追踪当前系统官方状态的方法。由于区块链可以包括金融交易和商业协议,因此所有相关...
  • 版权声明:本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和...在批处理过程中,数据是划分为块分片去完成的,然后每一Task去处理一分片。当分片执行完成后,把输出...
  • J2EE 十三个技术规范

    千次阅读 2013-04-01 16:07:18
    J2EE里面的核心内容是十三个技术规范,几乎包含了所有内容,Java强大功能的实现一依赖于这些规范,它的跨平台、可移植等特性。    Java体系结构   EJB(Enterprise Java Bean) EJB (Enterprise JavaBean)是J2EE...
  • 服务器容错技术

    千次阅读 2016-04-07 08:49:23
    目前主流应用的服务器容错技术有类,它们分别是:服务器群集技术、双机热备份技术和单机容错技术。它们各自所对应的容错级别是从低到高的,也就是说服务器群集技术容错级别最低,而单机容错技术级别最高。由此可知...
  • 一、简介HDFS——Hadoop分布式文件... HDFS中包含三个主要的进程:NameNode,DataNode,SecondaryNameNode。这三个进程一般是分布式不同的主机上,所以一般习惯上是用进程的名字称呼节点 二、特点 优点: 支持超大
  • Hadoop的容错

    千次阅读 2016-09-13 10:57:40
    要谈及Hadoop的容错性,就不得不先从Hadoop的组成...因为我自己接触2的时间不长,今天就针对前两来谈Hadoop的容错性。 一、MapReduce的容错性: 1, map或reduce运行时因代码原因而抛出的异常。在这种情况下,
  • can总线之容错can

    千次阅读 2018-04-04 08:52:26
    一文读懂容错CAN CAN-bus家族中有大成员,分别是高速CAN、容错CAN、单线CAN。其中容错CAN又叫低速CAN,它与最常用的高速CAN有什么异同呢?这里将与大家分享下对容错CAN的认识。 一、容错CAN的起源 1986年Bosch在...
  •  我们提出的弹性分布式数据集(RDDs),是一让程序员在大型集群上以容错的方式执行基于内存计算的分布式内存抽象。RDDs受启发于两类使用当前计算框架处理不高效的应用:迭代算法和交互式数据挖掘工具。这二者在...
  • 跳槽到一集团从事信息化专员职位已经3月了. 在此期间所遇到e
  • 首先用户程序 (JobClient) 提交了一 job,job 的信息会发送到Job Tracker中,Job Tracker 是 Map-reduce 框架的中心,他需要与集群中的机器定时通信 (heartbeat), 需要管理哪些程序应该跑在哪些机器上,需要管理.....
  • 本文集成转载了三篇文章,用于辨析三个概念:容错、高可用、灾备,希望对大家有所帮助!
  • 区块链之旅()智能合约与共识机制

    千次阅读 多人点赞 2021-05-09 00:00:08
    过程: 评价标准 共识机制的对比 PoW PoS DPoS Raft PBFT 场景 公链 公链、联盟链 公链、联盟链 联盟链 联盟链 去中心化 完全 完全 完全 半中性化 半中性化 记账节点 全网 全网 选出若干代表 选出一Leader 动态...
  • 一般而言,在介绍区块链时经常会提到两例子:一是由古老的记账模式延伸到分布式账本,二是...区块链上的共识机制主要解决由谁来构造区块,以及如何维护区块链统一的问题,该问题的理论基础是拜占庭容错(Byza...
  • 弹性指的是在复杂网络环境下,面对各种故障和挑战,仍能提供和维持一可以接受的服务水平,并正常运作。 -来自Wikipedia自从长期服务和最近的微服务被大家熟知和使用,很多应用程序开发人员已经将整体式的API,...
  • 实用拜占庭容错(PBFT)算法详细介绍

    千次阅读 2020-03-18 11:29:54
    本文主要讲述实用拜占庭容错算法(PBFT)的算法部分。
  • 区块链共识机制

    千次阅读 2019-01-13 16:50:45
    更多关于区块链技术和投资的文章,请关注...什么是共识机制 共识机制的起源 共识机制的原理  POW  POS  DPOS  BFT 共识机制总结  共识机制的评价指标  共识机制对比  共识机制展望   什么是共...
  • 关于HDFS需要掌握的有:分布式系统与HDFS、HDFS的体系架构和基本概念、HDFS的shell操作、Java接口以及常用的API、Hadoop的RPC机制、远程debugDistributed File System数据量越来越多,在一操作系统管理的范围存储...
  • 摘要:本篇文章是【区块链之技术进阶】的第七篇文章,在之前的文章中咱们多多少少提及了共识算法等相关知识,但是却没有具体地更加深入地了解,本文就为大家掰一掰区块链共识机制与分布式一致性算法,两者究竟有什么...
  • 在默认的情况下,负载均衡策略是线性轮询的方式,也就是说在客户端获取到的服务列表中依次交替,例如开启了三个服务server1、server2、server3,那么在线性轮询时,就会按这个顺序来调用。 我之前是开启了两个服务...
  • 我们在人工智能领域研发、开发和应用时,需要有专业性的标准标准化的指标、或评估规范等,在网上查找了一段时间,发现很多资料并不可靠,或简单介绍,让人头大呀;这里整理了一些比较专业的资料,分享给大家。 ...
  • DPOS机制

    万次阅读 2018-02-15 13:45:26
    前言共识机制是分布式应用软件特有的算法机制。在中心化的软件里,再复杂的问题都可以避开使用复杂的算法逻辑(当然,如果能用算法统领,代码...在第一部分,专门用一篇文章《共识机制,可编程的“利益”转移规则...
  • 在这一章节中,我将以Aviv Zohar和Jonatan Sompolinsky设计的GHOST(Greedy Heaviest-Observed Sub-Tree,又称幽灵协议)原理在权益证明中的应用来重新叙述Casper机制诞生的故事。 我称它为“友好的Ghost”(编者按...
  • 不过这块是逻辑概念,比较大,默认是64M。 Hadoop以“管理者-工作者”模式运行。NameNode就是管理者,它保存了文件系统中所有文件以及目录信息。也记录了每文件的分块信息。但这些分块具体在哪些机器上存储则...
  • 到目前为止,我们已经了解了 Git 基本的运作机制和使用方式,学习了许多 Git 提供的工具简单且有效地使用它,可以高效地帮助我们工作,提升我们的效率。 如果还不清楚 Git 的基础使用流程、分支的管理、托管服务器的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,038
精华内容 13,615
关键字:

容错机制的三个标准