一、梳理JML语言的理论基础

1、jml的注释结构

  jml注释语言的每一行都以@作为开始,若是块注释,则需要在注释块的首尾使用/*@ 与@*/

2、jml的表达式体系

1、原子表达式

  表达式可以看作是一个原子类型,常见的有\result表达式(用于表达某个方法执行后的结果)、\old表达式(用来表示某个对象执行某操作之前的值)。

2、量化表达式

  量化表达式是对给定范围内对象批量操作的表达式,其存在大大简化了jml语言,常见的有\forall表达式(范围内对象,都要满足某要求)、\exists表达式(范围内存在对象,满足某要求)、以及\sum表达式、\product表达式、\max表达式等数学方法的量化表达式

3、集合表达式

  用来在jml规格中构造一个集合(容器),来简化jml规格

4、操作符

  包括算数操作符和逻辑操作符。例如等价操作符<==> 与 ==,其中特别要注意的是<==> 与 ==这样的操作符,优先级是不一样的!

  此外操作符还包括变量引用操作符,例如\nothing指示一个空,\everything指示一个全集。

3、jml的方法规格

  我们使用与学习的方法规格只是最基础的部分,核心内容是三方面:前置条件、后置条件、副作用限定。

1、前置条件

  前置条件使用requires语句来表示,requires P意味着需要确保P的值为真。需要注意的是,requires语句如果多行一起出现,是并列条件,需要全部满足。

2、后置条件

  后置条件使用ensures语句来表示,ensures P意味着需要确保P的值为真。同样,ensures语句如果多行一起出现,是并列条件,需要全部满足。

3、副作用限定

  在方法执行时,为了满足前置条件与后置条件,我们可能会对对象做一些与前置条件和后置条件无关的改动,也就是副作用。有时候需要通过副作用限定来对方法实现进行约束。

  这里,我们可以选择assignble和modifiable。

  assignble 表示可赋值,而 modifiable 则表示可修改。虽然二者有细微的差异,在大部分情况 下,二者可交换使用。

  这两个关键词既可以约束特定的对象,表示更改特定对象。也可以选择约束\nothing 和 \everything这样的关键词,来表示什么都不更改,或是全部更改。

4、其他

  当前置条件与后置条件需要对多个对象进行约束时,可以与用\forall或者\exists表达式结合使用。

  我们使用signals语句,来表示异常处理,语句signals (***Exception e) b_expr 的意思是当 b_expr 为 true 时,方法会抛出括号中给出 的相应异常e。

4、jml的类型规格

  不变式(invariant),语法上定义 invariant P ,其中 invariant 为关 键词, P 为谓词,表示要求在所有可见状态下都必须满足的特性。

  状态变化约束(constraint),用来对前序可见状态和当前可见状态的 关系进行约束。

5、总结

  jml语言是一套逻辑严密的注释语言体系,通过对方法行为的描述,预防bug的出现,并使得检查过程比原先轻松,提高了代码的可维护性。

二、jml应用工具链情况

  首先,是jml语言的编写,可以使用专门的jml编译器。

  jml规格的校验,可以使用openjml。

  JMLUnitNG可以根据规格的实现自动生成TestNG测试样例。

三、部署JMLUnitNG

1、测试代码

package demo;
public class Demo {
private /*@ spec_public @*/ int[] nodeList; public Demo(int[] nodeList) {
this.nodeList = new int[16];
} /*@ requires index >= 0 && index < size();
@ assignable \nothing;
@ ensures \result == nodes[index];
@*/
public /*@pure@*/ int getNode(int index){
if (index >= 0 && index < size()) {
return nodeList[index];
} else {
return 0;
}
} //@ ensures \result == (nodes.length >= 2);
public /*@pure@*/ boolean isValid(){
boolean ret = false;
if (nodeList.length >= 2) {
ret = true;
}
return ret;
} public static void main(String[] args){ } }

2、测试方法

  首先,尽管已经有很多前人感谢过伦佬了,但我还是要在这里郑重地再感谢一次伦佬。

3、测试结果

[TestNG] Running:
Command line suite

Passed: racEnabled()
Passed: constructor Demo()
Passed: <<demo.Demo@1a8f2434>>.getNode(-2147483648)
Passed: <<demo.Demo@5f5a92bb>>.getNode(0)
Passed: <<demo.Demo@376b9c22>>.getNode(2147483647)
Passed: <<demo.Demo@54768a01>>.isValid()
Passed: static main(null)
Passed: static main({})

===============================================
Command line suite
Total tests run: 8, Failures: 0, Skips: 0
===============================================

4、测试思考

  这个自动化测试emmmm,实际上,只是测试了几个边界条件,似乎正能起到一个锦上添花的作用。

四、架构设计

1、第一次作业

  在pathcontainer中,我的选择是构造三个hashmap,一个用path作为key,pathid作为value。另一个用pathid作为key,path作为value。(这里需要在mypath类中重构path对象的hashcode方法)。这两个hashmap实现了path的快速查找和改动(总有一个hashmap可以用key查找,查找出来的value作为另一个hashmap的key)。第三个hashmap,使用node作为key,node的数目作为value,用来,存储当前容器内的节点数量。

  在path中,除了本身的节点数组外,我还构造了一个hashmap,用于判断path中是否含有某node。

2、第二次作业

  本次作业要求,在第一次作业的基础上,加入了判断两个节点是否联通,两个点是否能构成一条边,以及得到两个节点间的最短路径。

  我并没有对第一次的构造进行改动,而是在第一次作业的基础上又构造了两个静态数组,一个hashmap,和一个arraylist,其中hashmap是保存节点与映射节点的关系(我将图内的节点映射到了0到nodesize内),具体做法是,先检查arraylist如果arraylist不为空,从arraylist内取出一个可映射的值,与当前节点映射。否则,当前映射id与当前节点映射并加一。当一个节点,不存在图中时,将其从hashmap中删除,并将对应的映射值,存入arraylist中。

  两个静态数组都是大小为nodesize的二维数组,(节点查找使用映射值)一个存储的是当前图内的点的联通情况(权重为1),另一个存储的是对联通性矩阵进行floyd运算后的矩阵。

3、第三次作业

  本次作业,对nodesize要求更改,并且添加了新的需求,联通块数量计算,最少票价计算,最少换乘次数计算,最少不满意度计算。

  首先,nodesize的更改,由于我没有使用magic number(上一次作业的教训),直接改动nodesize即可。

  此外,分析发现,新的需求中,联通块计算可以通过并查集实现,我增加了并查集方面的方法。

  而剩下的三个需求,其实可以和第二次作业中的最短路径一起归纳为图的权重问题。我对第二次作业的floyd方法进行了重构,重构成了一个templatefloyd(c++课中的模板类思想),并又构建了5个二维矩阵,用来存储不同需求下的图的权重矩阵和floyd运算后的结果矩阵。

五、bug与修复

1、第一次作业

  未发现bug。

2、第二次作业

  本次作业中,我忽略了得到最短路径方法的jml规格中的描述:当fromnodeid == tonodeid时,最短路径为0 ,导致了大面积的wa。

3、第三次作业

  未发现bug。

六、心得体会

  首先,我深刻理解了这一单元最开始时,老师在课上反复强调的,只要严格按照jml来实现,就不会有bug。自己的bug也是没有完全按照jml的约束实现。

  然而,在jml的实现中,仅仅做到实现jml也是不足够的。我的第三次作业的强测有一个点过的特别危险,35s的时间limit,我花了34.6779s跑完了程序。诚然,我严格按照jml约束实现了,但我没有考虑到性能的优化。在jml的实现中,还要注意性能的优化。

北航oo作业第三单元小结的更多相关文章

  1. 北航oo作业第四单元小结

    1.总结本单元两次作业的架构设计 在我动手开始总结我的设计之前,我看了其他同学已经提交在班级群里的博客,不禁汗颜,我是真的偷懒.其他同学大多使用了新建一个类,用以储存每一个UMLelemet元素的具体 ...

  2. 北航OO(2020)第三单元博客作业

    一.JML理论基础及相关工具链 1.JML理论基础 该部分梳理本单元作业中涉及到的JML知识. 1.1注释结构 JML采用javadoc注释的方式来表示规格,且每行以@开头.通过使用//@annota ...

  3. OO作业第三单元总结

    目录 一.JML语言理论基础及应用工具链 二.部署JMLUnitNG,自动生成测试用例 三.架构设计 第一次作业 第二次作业 第三次作业 四.Bug分析 五.心得体会 一.JML语言理论基础及应用工具 ...

  4. 北航oo作业第一单元小结

    前言 在经过了三次艰辛的oo作业后,oo课程的第一单元告一段落,这一单元,我作为一个oo小白,开始了解oo的编程思想,也有了自己的一点心得体会.把笔粗成字,不当之处,还请各位大佬多多指教. 一.分析程 ...

  5. BUAA OO 2019 第三单元作业总结

    目录 总 JML规格化设计 理论基础 工具链 规格验证 验证代码 代码静态检查 自动生成测试样例 生成结果 错误分析 作业设计 第九次作业 架构 代码实现 第十次作业 架构 代码实现 第十一次作业 架 ...

  6. 北航OO(2020)第四单元博客作业暨学期总结

    一.第四单元架构设计 1.第一次作业 我在本次作业中设置了多个储存结构:Directory,ElementsInName,ElementsInId,Cache. Directory: 顾名思义,这是个 ...

  7. OO第三单元小结

    目录 JML理论基础 JML工具链 openjml使用 openjml总结 jmlunitng使用 代码分析 第一次作业 第二次作业 第三次作业 测试&bug分析 黑盒测试 白盒测试(Juni ...

  8. OO第三次博客作业--第三单元总结

    一.JML 语言的理论基础及应用工具链 JML 是一种行为接口规格语言,提供了对方法和类型的规格定义手段.通过 JML 和其支持工具,不仅可以基于规格自动构造测试用例,并整合了 SMT Solver ...

  9. OO课第三单元总结

    一.梳理JML语言的理论基础 (1)理论基础 JMl的出现很大程度上一为了行为接口的规范化,用这种语言来指定特定模块的特定功能.JML的核心部分分为三个部分:前置条件(requires).后置条件(e ...

随机推荐

  1. Java学习路线-知乎

    鼬自来晓 378 人赞同 可以从几方面来看Java:JVM Java JVM:内存结构和相关参数含义 · Issue #24 · pzxwhc/MineKnowContainer · GitHub J ...

  2. C++之string类

    1.String对象的初始化 string s1;               默认构造函数,s1为空串 string s4(n, 'c');     将s4初始化为字符c的n个副本 string s ...

  3. Hive 查询优化总结

    一.join优化 Join查找操作的基本原则:应该将条目少的表/子查询放在 Join 操作符的左边.原因是在 Join 操作的 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存, ...

  4. Pig Flatten 解包操作,解元组

    Flatten Operator The FLATTEN operator looks like a UDF syntactically, but it is actually an operator ...

  5. unreal3启动流程总结

    一.启动代码所在工程为Launch(win32),可为所有同一codebase项目共享. 但共享方式很不智能,是通过在源文件中添加大量#if/else条件编译宏来实现,即各项目在自己的工程中添加[程序 ...

  6. [CentOS7] 增加yum源

    下载最新rpm文件:http://fedoraproject.org/wiki/EPEL 通过源文件rpm来增加: rpm -ivh epel-release-latest-7.noarch.rpm

  7. bootstrap初学者模板

    <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> ...

  8. Ocelot - .Net Core开源网关

    Ocelot - .Net Core开源网关 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/10857688.html 源码地 ...

  9. 51nod1521(set.upper_bound())

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1521 题意:中文题诶- 思路: 我们先看一下set容器的三个 ...

  10. 洛谷P2474 [SCOI2008]天平

    P2474 [SCOI2008]天平 题目背景 2008四川NOI省选 题目描述 你有n个砝码,均为1克,2克或者3克.你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系.你把其中两个砝码A ...