OO第三单元总结

OO第三单元总结

  • JML理论基础与工具链梳理

  JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言。我们使用 JML 来描述 Java 模块的行为可以忽略其具体实现。

  JML有类型规格和方法规格,类型规格主要包括类所管理的数据,不变式invariant和变化约束constraint。方法规格包括前置条件,副作用和后置条件,用来描述一个方法的行为(包括正常与异常行为)。

  JML的工具链包括OpenJML(用于对JML进行语法检查),SMT solver(用于检查代码等价性)和JMLUnit(用于生成测试数据)等。

 

  • SMT solverJMLUnit测试

  在实际运行中,可能是由于jdk版本的原因,SMT solverJMLUnit不断报错,因此最终放弃。

  此后我在网上查找了一些资料,也阅读了其他同学的博客,发现JMLUnit构造的数据不太具有针对性,仅仅是构造边界数值(如int的最大值),或者传入空引用。因此实际构造数据时不能依赖JMLUnit,仍应该主要使用手动的方法进行构造。

    

  • 程序架构分析

第一次作业:

  完全按照课程组提供的规格编写,难度较小,其中isCircle部分使用dfs实现,容器均为ArrayList

 

第二次作业:

  第二次作业中出现了性能问题,在有关age的几个方法中我选择在MyGroup类中增加中间变量,但是有关relationSumvalueSum的方法没有增加。同时将容器由ArrayList变为Hashmap,并且使用并查集重构了isCircle方法。

 

第三次作业:

  第三次作业中增加了几个图论相关的经典问题,包括查询连通块数,查找最短路径,判断点双连通等。其中查询连通块数使用并查集实现非常简单,查找最短路径使用Djistra算法,判断点双连通通过两次bfs实现。

 

  • bug分析

第一次作业:

  没有发现bug

 

第二次作业:

  出现了由于没有设置中间变量,而是使用二重循环求RelationSumValueSum导致的CTLE

    

第三次作业:

  出现了两个bug

  第一个是用Djistra求最短路径时的CTLE(超时0.02s-0.2s),经过优化后减少了大约1s的时间。

  另一个bug是判断点双连通时对于容器的操作错误导致RTE(确实是很低级的错误)。

  实际上在bug修复完成后还发现了两次bfs会出错的情况,如果使用tarjan算法则没有对应的问题,但是由于没有遇到此类数据,因此在bug修复中也没有体现这一点。

  本次由于课程组统一提供JML规格,因此选择直接阅读同学代码,其中重点阅读复杂度较高的部分代码,并成功找出了两个会导致CTLE的错误。

  • 心得与体会

  本单元是对于JML这一工具进行了详细的介绍,并通过实践让我们亲身体验。

  JML所体现的契约式编程方法,形式化设计与验证的思想都十分的巧妙。但由于相关工具链存在各种各样的缺陷,使得对于JML规格的设计和验证不像看上去那么美好,我认为目前JML仍然不够成熟,不足以广泛应用到实际的工程开发中。开发文档和人工构造测试集仍然是不可避免的。但是JML体现的模块化,规范化设计的思想确是很值得我们学习的。

  此外,对于JML所规定的功能,不能机械地去实现,JML只是为我们提供了基本的规则,我们在具体实现时仍然需要根据实际情况(包括对性能的要求,数据的规模等)进行具体分析以选择最合适的算法。

posted @ 2020-05-23 20:24  Asphodelus  阅读(172)  评论(0编辑  收藏  举报