16061013 尹一航
保证正确性方法及其优缺点
测试
“To err is human.”——Alexander Pope
是人就会犯错,但是好的程序不应该有bug,尤其对于工业界、国防产业来说,犯错的成本太高,测试是必须的。
但是,随着工程越来越复杂,构造完备测试集的难度可能呈指数级发展,而且,测试也有一个特点,往往保证正确的功能是很容易的,对应的测试也很简单,绝大多数的经历,都实在预测一些很难发生但却会造成问题的情况。
这是我在网上看到的一则笑话,我认为这非常完美地体现出了测试任务的特点:
举个栗子:银行转账
其实功能性测试很简单,A给B转1块,B再给A转5块,结果对了,这个程序就完成了基本功能。
然而,对于银行转账这种性质的问题,真正需要测试的是转账失败了、超出范围了、余额为负数了、同时把一笔钱转给两个人了、很多人一起转账如何调度等等这样的问题。这就如同上面的笑话,正常来讲一个人进酒吧喝一杯啤酒就应该完事了,但你永远不知道经过一番奇怪的操作,你的程序会发生什么情况。
因此,枚举所有可能情况的这种做法,在大工程里就不太合适了。
在此也可以类比上学期的计组课程,为了保证CPU的正确性,也需要进行仿真和大量的测试,但事实上在工业界,CPU的集成电路规模已经变得无比巨大,仿真测试的成本极高,耗时甚至超过设计一个CPU本身的时间,因此,工业界也广泛使用基于推理的形式论证方法,与接下来要说的正确性论证有着相似之处。
正确性论证:
正确性论证则是希望采用逻辑上的推理,来保证程序的正确性,像是数学定理的证明,并不需把所有的情况列举出来,思维的难度增加了,但是所需要的工作减少了,这也是能从根本上保证程序没有问题的方法。
课程组为我们提供了一个简单但是较为完备的论证模板,其主要内容为:
1、抽象对象有效实现论证
2、对象有效性论证
3、方法实现正确性论证
抽象对象的有效实现论证,主要是看在逻辑上对类别的划分是否清晰,符合逻辑,并且符合SOLID等设计原则。
而对象有效性主要是判断各个方法对对象的改变,是否会改变repOK的值,即对象是否永远是有效的,按照方法逐个论证即可。
而方法实现的正确性论证就是对方法输入的可能值,按照方法的逻辑进行划分,之后对结果进行论证。
论证的正确性如果能够保证,那程序不经过测试也可以保证正确了。
但是这里有了一个很矛盾的问题,就是论证也是人做的,其实也并不能保证正确性,只是增加了正确的信心。
难道还要引入正确性论证的正确性论证?永无止境。
实际生产生活中,将开发与测试分离,分层次进行测试,分单元和集成进行测试,多轮次的测试,将测试与论证相融合也许才是更好的办法。
何为OCL
OCL(Object Constraint Language)。
相似之处
功能上,和JSF功能类似,用来说明对象的规格,如约束、前置条件后置条件等等。而且,和JSF一样也是一种形式化无二义性的语言,JSF采用一阶逻辑进行形式化的说明,而OCL使用约束和表达式进行说明。
区别在于
OCL每一个表达式都需要指定上下文,OCL是一种声明式语言,大部分表达式执行后会返回一个布尔值,也有一些表达式会用来选择一个单一值或者一个对象/值的集合。
电梯UML
类图
顺序图
状态图
这学期的九九八十一难
四个单元模块
第一章 Java与对象(Java和面向对象基本概念入门)
第二章 并发与安全(多线程程序设计入门)
第三章 抽象与规格(规格化与整体设计进阶)
第四章 测试与论证(工程化质量保证措施学习与体验)
自己的进步
首选,在学习这门课之前我对面向对象编程还是有一些基本了解的,使用Python进行过一些面相对象的开发。使用Ruby搭建过自己的网站,也都是使用面向对象方法。
不过,我只是知道属性、对象、类这几种基本的概念,以及一些简单的实现方式,我对如何设计好多线程、如何评价工程质量,如何用工程化思维设计程序是毫无经验的。
最大的进步在于掌握了多线程的设计方式,在之前自己的探索之中,我只会使用多进程,因为多线程之间涉及到一些资源共享、线程同步等等,让我无从下手。不过在充分了解锁的概念和线程通信之后,我对多线程终于有了比较全面的了解。
对于工程质量,之前的项目都是自己做着玩,没有人会在乎工程质量,而在实际生产生活中,这肯定会直接和公司利益、个人所得挂钩,因此如何评价工程质量的好坏,以及是否遵循了好的设计原则,也是本学期进行OO学习的重要收获。
对工程化开发的理解
首先,我一直认为,一旦到了实际的生产生活当中,一切问题应该尽量在开始写代码之前避免。
能有严密的流程、良好的规格设计、以及高质量的需求文档、开发文档的书写,必定会为开发带来加速式的体验。
在设计上保证逻辑的严谨成本不是很高,而想要通过构造测试用例测出问题则很不容易,若暴露在实际的生产环境中,造成的损失可能就更大了,因此,程序员应该形成良好的规格化设计的习惯。将bug扼杀在萌芽之中~
对课程的建议
OO是被吐槽最狠的课,虽然我相信课程组这样设计课程一定有其道理。
槽点多的根本原因,我认为在于这门课设计的过于真实。
我相信实际生活中的甲方一定是非常不好说话,并且经常改需求的。
在每一次的OO作业中,最令人头疼的是看指导书,其难点主要在于10页的指导书,需求到处都是,偶尔还有自相矛盾的时候。基本上,按照大家的平均水平,一个作业做4天,指导书至少得看2天,issue一般一次作业都有40-50个,可以说,写OO作业,主要难点在于搞清指导书上写的到底是啥意思?
这就很真实,我知道指导书已经是实际生活的过度简化版本,比如电梯,倘若对电梯运行就这么一点限制,肯定要死人的。我们知道里面也已经有了设计上的内容,而不仅仅是描述需求,但阅读完这样的指导书之后,写代码还是有很多很多很多的细节,是需要指导书作者本人确定的,这是课程难点之一,但或许也是弊端。用2天的时间读指导书,还是浪费了不少时间,倘若写的再简洁明了一些,我觉得,对造福学弟学妹们来说,真真是极好的。
重点建议
我觉得今年引入bug树是一件好事,使得互测这种充分彰显人性之恶的环节变得更加规范化。但希望课程组除了申诉以外,能够提供一种对恶意测试的惩罚措施。现在的测试环节,只有找bug的奖励,而没有找错bug的惩罚,这使得很多人为了高分而不择手段,被申诉之后也没有什么损失。让恶意的测试者有一些后顾之忧,必定会让课程变得更加公平合理,有利于维护OO课程组在计算机学院中良好的声誉。