目录

  • 写在前面
  • JML理论基础
  • JML工具链
  • JMLUnitNG的使用
  • 架构设计
  • Bug分析
  • 心得体会

写在前面

OO的第三单元学习结束了,本单元我们学习了如何使用JML语言来对我们的程序进行规格化设计。并对openjml以及JMLUnitNG、JUnit等工具的使用有了初步的了解。

JML理论基础

注释结构

JML以javadoc注释的方式来表示规格,每行都以@起头。

JML表达式

JML表达式有一下几种:

  • 原子表达式:如\result\old等。
  • 量化表达式:如\forall\exists等。
  • 集合表达式:这个不怎么常用,比如new JMLObjectSet {Integer i | s.contains(i) && 0 < i.intValue()}
  • 操作符:常用的包括等价关系<==>,推理关系==>,变量引用\nothing等。

JML方法规格

  • 前置条件:通过\requires P表示,是对方法调用者的要求,意思是调用者确保P为真。
  • 后置条件:通过\ensures P表示,是对方法实现者的要求,意思是方法实现者确保方法执行返回结果一定满足谓词P的要求,即确保P为真。
  • 副作用范围限定:通过\assignable x表示,其中x为此方法可以更改的对象,极端情况为\nothing\everything
  • signals子句:一般用来限制抛出异常的条件。

JML类型规格

  • 不变式invariant:是要求方法在所有可见状态下都必须满足的特性。
  • 状态变化约束constraint:是要求对象的状态在变化时也要满足的约束。

JML工具链

  • 使用OpenJML对实现的代码进行检查:包括JML语法静态检查,代码静态检查,运行时检查。
  • 使用JMLUnitNG根据JML语言自动生成TestNG测试。

JMLUnitNG的使用

针对如图的compare方法,利用JMLUnitNG生成测试样例:

生成的样例点:

可以看到,自动生成的样例点对方法的各种边界情况进行了测试,包括正数和正数,正数和负数,负数和负数,还有0的情况,如果我们写的方法出现了加减法溢出的问题,这些测试样例也都会检测出来并报Failed。

架构设计

第九次作业

本次作业主要内容是实现Path和PathContainer,其中主要的查询方法是不同节点数的个数,我使用了均摊策略,即把查询的时间复杂度平均到addPath和removePath中,每次添加或删除路径时更近存放节点的HashMap,这样可以实现O(1)复杂度的查询方法。

第十次作业

本次作业是实现Path和Gragh,而Gragh是继承了PathContainer的,所以我在写的时候也使用了继承。本次作业的主要查询方法是最短路径,所以我重写了PathContainer里面的addPath和removePath方法,在添加删除路径的时候重新建图,并更新最短路径。对于PathContainer里面的其他方法,直接继承使用。

本次作业我使用的方法:

  • Floyd多源最短路算法
  • HashMap嵌套实现邻接矩阵的存储

第十一次作业

本次作业是实现Path和RaiwaySystem,其中RailwaySystem继承了Gragh。本次作业涉及到加权图以及换乘的代价,所以算法难度较大。在拓展的时候,我还是重写了addPath和removePath方法,并添加了几个方法来计算新的最短路问题。

本次作业我使用的方法:

  • 分层的Floyd算法:即图结构变更之后,先对每条路径内部的点使用Floyd算法更新最短路,然后加上换乘代价,再对所有路径中的所有节点使用Folyd算法,即可实现带换乘代价的最短路算法。
  • 静态数组存储结构:即用二维静态数组替代HashMap嵌套来实现邻接矩阵的存储,这样做的优点是计算速度,存取速度快,减少时间复杂度。缺点是不好维护和拓展。如果不是追求极致性能,还是慎用此类方法。
  • 计算连通块的数量:使用并查集。

Bug分析

第九次作业

本次作业中,我的bug是减法溢出,具体是因为:我在实现compareTo方法的时候,采用的是两个整数相减来判断大小。而如果出现减法溢出的情况,那么判断结果跟正确答案是正好相反的。为此我也炸了强测+互测的20多个点。

本次作业中,同组同学的bug有:查询方法复杂度过高从而导致TLE,还有跟我一样的减法溢出问题。

第十次作业

本次作业中我的程序未被发现bug,我也未发现其他同学的bug

第十一次作业

本次作业中我的程序也未被发现bug,我也未发现其他同学的bug

心得体会

规格撰写方面

本单元让我体会到真正参与编写一个工程的感觉,即在一整个工程中分出一小部分让我们完成,并且要符合工程的要求。在这种情况下,JML语言体现出非常大的作用,它非常方便,不关注方法的实现过程,只专注于前因后果,因为只有前因后果才是把整个工程的思路贯穿起来的渠道。

此外,我也尝试过自己根据已有方法编写JML,也是有很大难度的,一定程度上,比我们写代码要难得多,这也体现出来规格化的重要性。

JUnit初体验

针对本单元各种小型模块的测试,我第一次使用了JUnit这个工具。可以说这个工具非常强大。如果说评测机是狂轰滥炸的飞弹,那么JUnit就是一把可以精确打击的匕首,也许你可以侥幸逃过狂轰滥炸,但是你绝对逃不过那精确一击。

一般JUnit测试所用样例都是自己精心构造的数据。随着代码不断完善进行补充。最方便的一点是:在每次版本更新后,都可以用JUnit一键回归测试,看是否改错了某些地方,可以说是非常强大的工具。

此外,JUnit还可以在运行的时候检测代码覆盖率,我们可以看到哪些地方被测试过,哪些地方还没有做测试,方便之后针对那些没有被覆盖的地方,继续补充测试样例。

OpenJML的使用

使用OpenJML工具可以对代码进行静态检查,有时候可以发现一些非逻辑错误导致的问题。比如我在第九次作业中出现的减法溢出的问题,其实是可以用OpenJML发现的,但当时对这种工具的使用还不是很了解,所以导致出现了bug。这也更加证明了在一个工程中,做好充分测试的必要性,不要让一个庞大的工程因为一个细小的错误而全盘崩塌。

OO第三单元总结——JML的更多相关文章

  1. OO第三单元——基于JML的社交网络总结

    OO第三单元--基于JML的社交网络总结 一.JML知识梳理 1)JML的语言基础以及基本语法 JML是用于java程序进行规格化设计的一种表示语言,是一种行为接口规格语言.其为严格的程序设计提供了一 ...

  2. OO第三单元作业(JML)总结

    OO第三单元作业(JML)总结 目录 OO第三单元作业(JML)总结 JML语言知识梳理 使用jml的目的 jml注释结构 jml表达式 方法规格 类型规格 SMT Solver 部署JMLUnitN ...

  3. 2020 OO 第三单元总结 JML语言

    title: 2020 OO 第三单元总结 date: 2020-05-21 10:10:06 tags: OO categories: 学习 第三单元终于结束了,这是我目前为止最惨的一单元,第十次作 ...

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

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

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

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

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

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

  7. OO第三单元(地铁,JML)单元总结

    OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...

  8. OO第三单元——JML规格化设计

    OO第三单元--JML规格化设计 JML语言的理论基础以及应用工具链情况 理论基础 JML是对JAVA程序进行规格化设计的一种表示语言,是一种行为接口规格语言.JML整合了Java和JAVAdoc,并 ...

  9. OO第三单元作业总结

    OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...

随机推荐

  1. react基础语法(三)组件的创建和复合组件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. Android(java)学习笔记160:开发一个多界面的应用程序之清单文件

    清单文件的重要参数:     <intent-filter>             代表的应用程序的入口界面           <action android:name=&quo ...

  3. xorequation(DFS完全枚举)

    题目 有一个含有N个未知数的方程如下: x1^x2^...^xn= V,给定N,V,再给定正整数a1,a2,...an满足1≤ai≤9且∏Ni=1(ai+1)  ≤ 32768,请输出所有满足0≤xi ...

  4. HTML基础(三)图像和超链接

    图像 img 元素向网页中嵌入一幅图像. 语法 <img src="" alt="" /> img标签常用属性 src 跳转的url alt 图片不 ...

  5. 洛谷——P1627 [CQOI2009]中位数

    P1627 [CQOI2009]中位数 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 中位数的题目有关统计的话,可以转 ...

  6. 任务备忘(已经完成):用python写一个格式化xml字符串的程序

    功能: 1.将xml中多余的空格,换行符去掉,让xml字符串变成一行. 2.将xml中添加缩进,使用print能正确打印添加缩进后的字符串. 思路: 采用正则表达式来判断xml中字符串的类型: 1.文 ...

  7. <Jenkins> 入门一

    1.Continous integration 持续集成 2.Continous Delivery     持续交付 3.Java 写的

  8. docker-compose文件语法解析(v3.x)

    文件配置 compose文件是一个定义服务(service).网络(network)和卷(volume)的YAML文件 .Compose 文件的默认路径是 ./docker-compose.yml 提 ...

  9. linux配置网桥

    实现环境: centos7   Linux devstack01 3.10.0-693.el7.x86_64 1.创建br配置文件,ifcfg-br2 cp ifcfg-br0 ifcfg-br2 2 ...

  10. php 后端规范

    后端框架地址: git@gitee.com:xielisen/xcore.git 框架使用规范,内部沟通 Controller命名规范 1, 首字母大写,其余小写 2, 对应数据库名称. 不要下划线 ...