ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

面向正确性和健壮性的软件构造学习概要(上)

2022-06-08 23:05:54  阅读:157  来源: 互联网

标签:Exception 概要 健壮性 代码 程序 正确性 Error


Outline

1.健壮性和正确性;

2.关于健壮性和正确性的测度;

3.Java中的Error和Exception;

4.处理异常;

5.断言;

6.防御式编程;

7.Debug的一些工具;

2022-06-08 20:56:50

 


 


 

1.健壮性和正确性

可靠性=健壮性+正确性

健壮性:系统在不正常输入或不正常外部环境下仍能够表现正常的程度。(尽可能保持软件运行而不是总是退出)

面向健壮性的编程:处理未期望的行为和错误终止;即使终止执行,也要准确的向用户展示全面的错误信息;错误信息有助于进行debug。

面向健壮性的编程的原则:封闭实现细节,限定 用户的恶意行为;考虑极端情况,没有“不可能”。

Postel’s Law:对别人宽容点,对自己狠一点。程序员应总是假定用户恶意、假定自己的代码可能失败;把用户想象成“白痴”,可能输入任何东西。

正确性:程序按照spec加以执行的能力,是最重要的质量指标。(永不给用户错误的结果)

正确性和健壮性的对比:

  正确性倾向于直接报错(error),健壮性则倾向于容错(fault-tolerance)。

  正确性让开发者变得更容易:用户输入错误,直接结束(不满足precondition的调用)。

  健壮性让用户变得更容易:出错也可以容忍,程序内部已有容错机制。

  对外的接口,倾向于健壮;对内的实现,倾向于正确。(与后文中提到的Exception和Assertions的使用场景类似)

  以几个例子来说明一下二者的区别:

 

 

提升程序健壮性和正确性的一般步骤:

 

  1. 利用assertions、代码评审、防御性编程、exception等编写代码;
  2. 观察程序运行错误后的状态(例如Memory dump、stack traces、execution logs);
  3. 确认潜在错误(Debug、局部化bug);
  4. 修改bug。

 

用一张我认为很好的图概括一下:

 

 

 


 

 

 

 2.关于健壮性和正确性的测度

外部观察角度MTBF:平均故障间隔时间(平均无故障运行时间),是指相邻两次故障之间的平均工作时间。即总的运行时间/总的故障次数。

MTBF的计算依赖于对系统failure的定义:对于可修复系统,是指导致系统不可使用的failure,出现问题,但系统仍可运行,则不视为failure。

同理还有故障前平均时间MTTF,它是用来描述不可修复系统的故障前平均时间。

下图描述的是可修复系统的MTBF(注意可修复系统没有MTTF):两个红色状态的间隔时间即为MTBF。

内部观察角度残余缺陷率:每千行代码中遗留的bug的数量。

 

像一般企业的代码残余缺陷率为1 - 10 defects/kloc,而像NASA这样的用于科研航空机构的代码残余缺陷率低至0.01 - 0.1 defects/kloc。

 

另外还可以用Halstead Volume来描述,具体内容之前在面向可维护性的软件构造中提到过,这里不再赘述。

 

 

 

 


 

3.Java中的Error和Exception

Java中所有的Error和Exception都是继承自Throwable类,记住下面这张图即可:图中红色虚线圈起来的一部分包括所有的Error和RuntimeException都属于Unchecked Exception,其余异常都属于checked Exception(编译时异常),下一节中会具体讲到对二者的区别对待。

 

 

Error通常是指内部错误,程序员通常无能为力,一旦其发生,应该想办法让程序优雅的结束。所以我们不要抛出Error对象(即使抛出了也是毫无意义的,程序员不能让内部错误恢复);异常则是你自己程序导致的问题,可以捕获、可以处理。

Error的分类:用户输入错误、设备错误、物理限制。一些典型的Error有OutOfMemoryError、StackOverflowError、InternalError、NoClassDefFoundError。

 

 


 

 *.关于我在Lab2程序编写时碰到的一个RuntimeException的思考与回味:

当时在编写Lab2时,对一个Map进行了迭代器遍历,第一遍的时候程序没有任何报错,一切运行也很正常;但是在我第二次运行时,程序莫名其妙的报了一个NullPointerException。当时还没有学到这一章节的内容,我便去搜索引擎上查找相关原因,这个运行时异常是由程序对一个空的(null)对象解引用造成的,但是奇怪的是这个Map在我的程序中不可能有一个key指向一个空的对象啊(这里的Map存放的是当前单词在语料库生成图中的出边集(目标点和边权值),与这个单词没有连接的单词也不会出现在Map中,所以更不会有null出现)。在学习完这一章节的知识之后,我恍然大悟,首先这个异常属于Unchecked Exception,所以静态检查和编译都通过了,运行的时候才报错;至于后面为什么不会解引用null也会出现这个异常,我的推测是IDE并不知道我们的具体代码实现,它只清楚在当前这个Map的迭代遍历中可能会出现NullPointerException,所以负责任地提醒我们编写的代码存在着漏洞,这样的处理百利而无一害。但是我当时自然而然地将NullPointerException当做普通的编译时异常try catch了一下,运行时也没有报错了,说明源代码确实也不会触发NullPointerException,只是IDE细致入微的考虑。放现在来看,这并不是一个好的处理,Unchecked Exception最好的解决办法是重写代码,而不是try catch和throw。

下面是我当时的代码:现在看来,最好在对value解引用之前判断一下其是否为空,然后再去操作,这样就不会触发异常了。

感觉这个试错也是学习中的一大乐趣吧,学以致用才能更好地把握知识。

 

标签:Exception,概要,健壮性,代码,程序,正确性,Error
来源: https://www.cnblogs.com/gb-0526/p/16357546.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有