本文是BUAA OO课程Unit3在课程讲授、三次作业完成、自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客。主要包含JML相关梳理、SMT Solver验证、JML单元测试、设计策略、代码度量、BUG测试和心得体会等内容。

目录

一、JML简单梳理

二、SMT Solver的部署和验证

三、JML单元测试

四、架构设计梳理

五、测试与BUG分析

六、心得体会


一、JML简单梳理

1.1 JML语言理论基础

  The Java Modeling Language (JML) is a behavioral interface specification language that can be used to specify the behavior of Java modules. It combines the design by contract approach of Eiffel and the model-based specification approach of the Larch family of interface specification languages, with some elements of the refinement calculus.

  JML(Java建模语言)是一种进行详细设计的符号语言,它鼓励我们用一种全新的方式看待Java的类和方法。面对对象的分析和设计的一个终于原则就是过程性的思考应该尽可能地推迟。Java建模语言在Java代码中增加了一些符号,这些符号用来标识一个方法是干什么的,却不关心它的实现。通过这种方式,JML把过程性的思考延迟到了方法设计中,从而拓展了面对对象的这个原则,同时通过引入大量用于描述行为的结构,比如有模型域、量词、断言可视范围、预处理、后处理、正常行为与异常行为等等,这些结构就使得JML非常强大了。通过分析JML,我们能够更为精确地了解代码的用途,减小引入bug的几率,更高效地检测并纠正代码的bug等。

1.2 JML应用工具链

  除了OpenJML、JML Editing、JMLUnitNG以外,常用的JML工具还包括以下:

  • The AspectJML tool is able to specify and do runtime assertion checking for both Java and AspectJ programs. Ajmlc uses aspect-oriented compilation techniques to provide significantly improved runtime assertion violation messages, and also works with JavaME.
  • The jml4c tool is a JML compiler built on the Eclipse Java compiler. It translates a significant subset of JML specifications into runtime checks. Notable features of JML4c include (1) support for Java 5 features such as generics and enhanced for loops, (2) support for nested classes, (3) improved compilation speed, and (4) improved error messages. Using JML4c, one can now verify Java 5 classes annotated with JML specifications.
  • Sireum/Kiasan for Java, which is a JML contract-based automatic verification and test case generation tool-set for Java program units.
  • JMLEclipse, which is a pre-alpha version of the JML tool-suite developed on top of Eclipse's JDT compiler infrastructure.
  • JMLOK is a tool that uses random tests to check Java code against JML specifications and suggest likely causes for non-conformance problems it finds.

返回目录


二、SMT Solver的部署和验证

  因OpenJML不能支持\forall、\exists,本次作业中无法完成测试验证,略。

返回目录


三、JML单元测试

  为了规避\forall和\exists,作业中的其他方法过于简单,改为使用以下测试代码进行测试:

package test;

public class Test extends Exception{
public static void main(String[] args) {
try {
divide(35, 7);
} catch (Exception e) {}
} /*@ public normal_behavior
@ requires b != 0;
@ ensures \result == a / b;
@ also
@ public exceptional_behavior
@ requires b == 0;
@ signals (Exception e);
@*/
public static int divide(int a, int b) throws Exception {
if (b == 0) {
throw new Exception("Divided by zero!");
} else {
return a / b;
}
}
}

  即一个简单的除法(整除),要求除数为零时报错,否则需要输出正确的答案。

  测试的结果如下:

  可见自动构造的测试数据是使用0,最大正数和最大负数等几个极端数据生成的,这一定程度的和易出现bug的情况相符。

返回目录


四、架构设计梳理

4.1 第一次作业

4.1.1 类图

4.1.2 简析

  第一次作业较为简单,从互测来看同学们的实现也较为类似,基本上按照规格实现功能不需要做很大的改动,选择合适的容器即可完成任务。即对于Path,使用ArrayList即可;对于PathContainer,我采用了双ArrayList,现在来看,实际上使用双HashMap在编写时更直观清晰一些。

4.2 第二次作业

4.2.1 类图

4.2.2 简析

  本次作业继承了PathContainer,在保持其原有功能的同时增加了两点间的距离计算,此为本次核心任务。大致有两种不同的设计理念,其一是在add Path和remove Path时使用Dijstra、Floyd等算法计算并缓存所有点之间的距离等信息,可以使查询在瞬间完成,另一种是在查询时才使用DFS等算法来计算距离,则对图结构影响的操作执行起来更快。我采取的是前者,主要在影响图结构的操作执行时更新所有路径容器、距离矩阵、自环统计这三个容器。在修复的时候,为了提升性能,我映入了映射机制,将输入的结点映射到1到250并改用静态数组。因此,除了增加映射机制从而改变了Path的容器和添加、删除方法之外,其他方面基本上无需对上一次的代码进行重构,而增加新功能。

4.3 第三次作业

4.3.1 类图

4.3.2 简析

  本次作业继承了Graph,在保持其原有功能的同时增加了更多的要求,基本上都可理解为带权路径的相关最小路径求解,以及需要求联通块数。仍然存在刚才提到的两种设计理念。我仍然使用在图的结构改变时计算所有结果的理念,并继续使用了映射机制。本次对最小路径、最少换乘、最少费用、最低不满意度的计算,实际上是拥有相似性的,都可以通过单程最近距离+换乘两步使用两次Floyd算法完成,因此我将上一次的代码重构为工厂模式,将进行某种特定距离的矩阵的运算封装成产品。联通块数目则单独使用一种算法,由于距离矩阵已经被计算,也可以非常简单地算出。

返回目录


五、测试与BUG分析

5.1 第一次作业

  本次作业中强测出现了超时的问题,但功能是正确的,原因在于代码设计不够合理。原先采用的设计是每次调用计算distinct nodes把所有点加入HashSet重新计算一遍,这是没有必要的,应该直接设置一个HashSet容器来存储所有distinct nodes,并改成每次加入或删除Path时就更新一次该容器,则查询时不再需要重新计算,从而节约CPU运行时间。

  本次作业的互测中没有发现bug。

5.2 第二次作业

  本次作业中强测也出现了超时的问题,但功能是正确的,原因在于使用的算法不够合理。使用的是一种添桥式的动态规划算法,但由于是每增加一条边更新一次,效率实在太慢,因为增加一条路径时可能有很多条边,而标准的Floyd算法只需要在添加后更新一次即可,就节约了CPU时间,从而不会超时。

  由于超时严重,在本次作业的互测分组中发现了较多的bug,主要有使用了错误的算法、容器选择不合理等。主要根据测试的限制构造几乎达到上限的随机数据进行测试即可测出主要的bug。

5.3 第三次作业

  本次作业的强测中没有出现bug,互测时也没有找到别人的bug。

返回目录


六、心得体会

  本单元的学习中,我感到规格的特点和好处,尤其在大型项目中,规格是顶层的设计对底层实现的一种很好的规范和约束,免去了思考具体实现,却又能保证正确性。不仅如此,规格能够清晰界定每个模块的功能,这非常有利于高内聚低耦合化的开发。结合单元测试,规格能使程序具有更好的健壮性和可维护性,规格和文档相结合对团队的合作也有较好的帮助。

  我感到撰写规格的时候和写程序时既有相似又有不同之处。相似之处在于写规格时也用到了很多相似度很高的语句,而最大不同之处在于规格的目的并不是分析问题解决问题,而是描述某一事物的所有可能性和状态。如正常情况、异常情况,何种条件下会导致怎么样的结果,对哪些数据有影响,哪些数据没有改变。如果想要准确的描述,还应保证语句的规范,例如对数理逻辑中全称量词和存在量词的使用,才能使规格达到要求。为了能使用OpenJML编写时还应注意一些语法格式,由于这方面工具的不充分(没有自动补全、高亮、纠错等),需要格外注意。

  本单元中运用的数据结构技巧也很多,我认为最为精巧的设计方法是第三次作业中将票价、最少换乘、最低不满意度、最近距离问题全部转化为单程最近距离+换乘两步使用两次Floyd算法,仅仅有细节上的差异,因此可以使用工厂模式来进行求值,从而使所有查询都能在极短时间内完成。

返回目录

JML规格编程系列——OO Unit3分析和总结的更多相关文章

  1. UML系列——OO Unit4分析和学期总结

    一.本单元的架构设计 1.类图 第一次 第二次 2.关键方法和架构简述 总体而言是读取图的时候就完成大部分计算(完成缓存),调用查询方法时只是展示计算的结果,少部分直接计算.主要是设计了各种自己定义的 ...

  2. 电梯系列——OO Unit2分析和总结

    一.摘要 本文是BUAA OO课程Unit2在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.主要包含设计策略.代码度量.BUG测试和心得体会等 ...

  3. 多项式求导系列——OO Unit1分析和总结

    一.摘要 本文是BUAA OO课程Unit1在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.本文第二部分介绍三次作业的设计思路,主要以类图的形 ...

  4. 2019年北航OO第三单元(JML规格任务)总结

    一.JML简介 1.1 JML与契约式设计 说起JML,就不得不提到契约式设计(Design by Contract).这种设计模式的始祖是1986年的Eiffel语言.它是一种限定了软件中每个元素所 ...

  5. OO第三单元总结——JML规格设计

    • 1.JML语言的理论基础.应用工具链情况 JML(Java Modeling Language)—— java建模语言,是一种行为接口规范语言( behavioral interface spec ...

  6. OO第三单元总结——JML规格

    一.JML简介 1.JML语言的理论基础 JML(Java Modeling Language)是用于对Java程序进行规格化设计的一种表示语言.JML是一种行为接口规格语言 (Behavior In ...

  7. OO Unit3 总结

    OO Unit3 总结 OO课Unit3人际关系网JML应用技术回顾 BUAA.1823.邓新宇 2020/5/23 梳理JML语言的理论基础.应用工具链情况 方法规格 JML中,同一个方法在不同的条 ...

  8. OO unit3 summary

    Unit3 ​ JML(Java Modeling Language) 是用于对 Java 程序进行规格化设计的一种表示语言,它对于方法内部具体是如何实现的并无要求,只是对方法的接口以及行为进行限制, ...

  9. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

随机推荐

  1. 什么是Java内存模型

    转载 : https://www.jianshu.com/p/bf158fbb2432 在知识星球中,有个小伙伴提了一个问题: 有一个关于JVM名词定义的问题,说”JVM内存模型“,有人会说是关于JV ...

  2. 【转】使用fastboot命令刷机流程详解

    一.Fastboot是什么? 1.1 首先介绍Recovery模式(卡刷) 在系统进行定制时,编译系统会编译出一份ZIP的压缩包,里面是一些系统分区镜像,提供给客户进行手动升级.恢复系统.需要提前将压 ...

  3. tar_ssh 配合下载文件(适合于带宽充足传输大量小文件场景)

    局域网网速快,但是当要传输大量小文件时倘若仍然使用scp,由于每个文件传输完毕都需要独立进行传输完毕的确认,这样就无法充分利用带宽.一方面等待确认时tcp窗口无法填满,另一方面文件传完之前确认也不会开 ...

  4. 什么是CN2线路

      CN2全称为中国电信下一代承载网,英文Chinatelecom Next Carrier Network,缩写为CNCN,进一步缩写为CN2. CN2线路的优势在哪里 CN2作为“精品网络项目”被 ...

  5. [Bayes] Metropolis-Hastings Algorithm

    [Bayes] prod: M-H: Independence Sampler for Posterior Sampling dchisq gives the density,             ...

  6. 【linux基础err】NVIDIA-SMI has failed because it could't communicate with the NVIDIA driver.

    问题 安装nvidia driver和cuda关机重启之后出现不能进入系统的问题,进入命令行模式使用nvidia-smi检查驱动的问题. nvidia-smi NVIDIA-SMI has faile ...

  7. socket支持ipv6

    转自:https://www.jianshu.com/p/9926b99a7fef 以前cocos2d-x的项目里都使用的是libwebsocket,如果想支持ipv6,只需要升级相应的库即可,现在有 ...

  8. 并行编程架构(指令流水、进程、线程、多核,Pipe and Filter)

    最近在进行DSP软件优化时,查阅文献,看到了几种并行机制,下面予以总结: 关键词一:指令流水 关键词二:多进程 关键词三:多线程 关键词四:多核(多处理器.超线程结构.多核结构.多核超线程架构) 在体 ...

  9. Python 推导式详解

    各种推导式详解 推导式的套路 之前我们已经学习了最简单的列表推导式和生成器表达式.但是除此之外,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. ...

  10. python 浅拷贝和深拷贝(9)

    何谓浅拷贝/深拷贝,说得直白一点,其实就是数据拷贝,两者到底有什么区别呢?听着就挺迷糊的,python开发项目的时候说不定你就能碰上这样的坑~~     一.普通的变量赋值 我们平常使用的变量赋值就是 ...