北航OO(2020)第三单元博客作业
一、JML理论基础及相关工具链
1.JML理论基础
该部分梳理本单元作业中涉及到的JML知识。
1.1注释结构
JML采用javadoc注释的方式来表示规格,且每行以@开头。通过使用//@annotation来进行行注释,使用/*@annotaion@*/来进行块注释。
1.2JML表达式
1.2.1原子表达式
\result表达式,在方法规格中使用,通过\result来指代返回值。在谓词中使用\result,来表达放回值的限制条件。
- \old(expr)表达式,返回表达式expr在方法执行之前的值。
- \not_assigned(x,y,...)表达式,该表达式为一谓词,当括号中变量在方法执行过程中未被赋值返回true,否则返回false。
- \not_modified(x,y,...)表达式,该表示为一谓词,当括号中变量在方法执行过程取值为变化返回true,否则返回false。
1.2.2量化表达式
- \forall表达式。表达式格式为\formall V; P1; P2。其中V定义了在该表达式中要使用的变量,谓词P1、P2为变量需要满足的条件。一般P1表示变量的范围,P2表示变量需要满足的其他条件。该表达式整体也为一个谓词,当V定义的变量的所有满足P1的取值都满足P2时返回true,否则返回false。
- \exists表达式。表达式格式为\exists V; P1; P2。其中V,P1,P2与\forall表达式中的相同。该表达式整体为一个谓词,当V定义的变量存在一个满足P1的取值也满足P2时返回true,否则返回false。
- \sum表达式。表达式格式为\sum V; P; N。其中V定义了表达式中要使用的变量,谓词P限制了变量的范围,N表示每一个满足P的情况下的增量。表达式最终返回所有增量的加和。
1.2.3操作符
- 推理操作符==>,使用格式P1 ==> P2。P1、P2为谓词,整个表达式也为一谓词。当P1为true,P2为false时该谓词返回false,否则返回true。
- 变量引用操作符。\nothing表示空集,\everything表示全集。
1.3数据规格
1.3.1规格变量
在本单元作业中,通过在接口中定义规格变量,来规定要管理的数据。
例如//@public instance model non_null int id;定义了一个规格可见的、引用不为空的、int型实例变量。同理将instance改为static可定义一个静态变量。
1.3.2 /*@spec_public@*/
通过对类中的字段添加/*@spec_public@*/可以指定该变量为规格可见。
1.1.3不变式invariant
//@invariant P;其中P为一个谓词。该语句规定在所有可见状态下,规格所管理的数据都必须满足谓词P。
1.1.4状态变化约束constraint
//@constraint P;其中P为一个谓词。该语句规定数据在前序可见状态与当前可见状态之间需要满足的约束。
1.4方法规格
1.4.1/*@pure@*/
通过对方法修饰/*@ pure @*/,表示该方法仅为查询方法,不会对类的数据做任何修改,使得该方法为规格内可见。
1.4.2行为
一个方法可以有多个行为,行为分为正常行为与异常行为。一个方法也也可以有多个正常行为与异常行为,但他们的前置条件之间不能有交集。正常行为用normal_behavior表示,异常行为用exceptional_behavior表示。多个行为之间用also连接。
1.4.3前置条件
通过使用requires语句实现。格式为requires P。P为一谓词,表示调用该方法时需要满足的限制。一个行为可以有多个requires语句,这些语句之间为且关系,在该行为下需全部被满足。
1.4.4后置条件
通过使用ensures语句实现。格式为ensures P。P为一谓词,表示该方法调用结束时需要满足的限制。一个行为可以有多个ensures语句,这些语句之间为且关系,在该行为下需全部被满足。
1.4.5副作用范围限定
通过assignable语句或者modifiable语句实现。格式为assignable/modifiable v。其中v表示可以被赋值/修改的变量。特别的,当v为\nothing时表示不能赋值\修改任何变量。
1.4.6 signals
signals语句使用在异常行为下。格式为signals E P。E为要抛出的异常包括异常类型与异常变量名称。P为一谓词,表示当谓词满足时抛出异常。当P与该行为前置条件的P相同时,可简化该语句为signals_only E。
2.相关工具链
2.1OpenJML
2.1.1介绍
根据OpenJML官网(http://www.openjml.org/)上的介绍,OpenJML通过使用SMT solver能够为Java程序验证其是否满足JML规格,分为静态(static)检查以及运行时(runtime)检查。
2.2JMLunitng
2.2.1介绍
JMLunitng能通过JML为Java程序提供测试集。
2.2.1本地部署
参考了这篇博客(https://www.cnblogs.com/starmiku/p/10908745.html)的配置。
执行如下指令后
java -jar jmlunitng.jar test/MyGroup.java
javac -cp jmlunitng.jar test/*.java
java -jar openjml.jar -rac test/MyGroup.java
java -cp jmlunitng.jar test.MyGroup_JML_Test
得到如下结果:


总共进行了55次测试,失败了4次。其中3次都是对addPerson传入null参数引起的,但在我们的作业中应当保证了传入的参数不为null。
而测试的样例中集中对边界数据进行了测试。
二、架构设计
1.第一次作业
第一次作业由于对规格不是特别了解,加上对规格的某些语句的工能有所误解,导致第一次作业完全就是按照规格的语句来完成整个设计的。MyPerson中的acquaintance和value,以及MyNetwork中的people都是采用链表结构,对数据的获取和查找基本上都是采用遍历的方式,所以性能较差,担幸好第一次作业在性能上的要求不是十分严格,所以还是逃过了一劫。
1.1类图

2.第二次作业
由于第二次作业比较强调的一点就是性能问题,所以需要对整个作业需要做一次完全的重构。同时将这个社交网络视为以Person为节点,link关系为边,value为边权的无向图。
2.1类图

2.2MyPerson
考虑到acquaintance与value中的数据有一一对应的关系,以及为了提高查找数据的效率,将他们整合成一个以Person为key以value为value的HashMap。
2.3MyGroup
同样为了提高查找效率上的考虑,使用HashSet来作为people数据的组织形式。
对getRelationSum, getValueSum, getConflictSum, getAgeMean, getAgeVar方法,为了不每次调用这些方法都重新遍历一遍数据,所以缓存了realtionSum, valueSum, ageSum, age2Sum(年龄平方和), conflictSum。其中relationSum以及valueSum需要在addPerson以及Network的addRelation时进行更新,其他数据在addPerson时更新即可。另外需要注意的是,ageMean的计算,为了保证与规格中的公式有相同的精确度,需要使用公式ageVar=(age2Sum - 2*mean*ageSum+n*ageSum**2)/n(摘自第十次讨论区乐洋同学的帖子)。
2.4MyNetwork
共用HashMap组织了三个数据:people, groups, peopleInCircle。people以及groups是为了快速通过id查找Person与Group。peopleInCircle无向图的连通分量,peopleInCircle在addRelation时更新。
通过这些储存结构,MyNetwork中大部分方法都只有几个语句,queryCircle方法可以通过查找他们是否在一个连通分量来实现。主要需要注意的方法就是addRelation,当person1与person2在一个Group中的时候需要为为这个Group更新relationSum以及valueSum,并且还需要注意person1与person2是否在同一连通分量,如果不在则需要合并两个连通分量。
3.第三次作业
第三次作业完全基于第二次作业迭代而来。
3.1类图

3.2MyPerson
与第二次作业保持一致。
3.3MyGroup
与第二次作业相比添加了delPerson方法,该方法同时更新people, ageSum, age2Sum, conflictSum, relationSum, valueSum。
3.4MyNetwork
添加了以HashMap组织的money,通过Person的id来查找其money。同时建立了一个内部类Edge来供图算法使用。
queryMinPath使用dijkstra算法,并用优先队列储存边来进行优化。
queryStrongLinked使用tarjan算法来计算点双连通分量以判断两Person是否stronglinked。
三、Bug分析
本单元的bug出现在第三次作业,强测中有两个点出现了CTLE的情况。后来经查看发现这两个点是针对queryMinPath进行测试的,导致CPU时间紧张。
由于自己偷懒就没有再去优化dijkstra算法,于是就选择在Bug修复中直接提交了之前的代码,幸好在评测机资源不紧张的状况下,出现CTLE的两个点都通过了测试。
四、心得体会
由于对JML的阅读还十分有限,所以也谈不上什么心得体会。主要策略就是先界定清楚不同正常行为以及异常行为,然后对每个行为中方法的逻辑进行分析,尝试用规范的逻辑语言去描述它,最后再转化为JML中的语句。
北航OO(2020)第三单元博客作业的更多相关文章
- 北航OO(2020)第四单元博客作业暨学期总结
一.第四单元架构设计 1.第一次作业 我在本次作业中设置了多个储存结构:Directory,ElementsInName,ElementsInId,Cache. Directory: 顾名思义,这是个 ...
- oo第三单元博客作业
JML语言理论基础 Java建模语言(Java Modeling Language,JML)是一种进行详细设计的符号语言,他鼓励你用一种全新的方式来看待Java的类和方法.JML是一种行为接口规格语言 ...
- OO第四单元博客作业
OO第四单元博客作业 BUAA_1706_HugeGun 目录 第四单元作业架构设计 四个单元架构设计及OO方法理解 四个单元测试理解与实践演进 课程收获 一点建议 第四单元作业架构设计 ### 第十 ...
- [BUAA OO]第三次博客作业
OO第三次博客作业 1. 规格化设计的发展 我认为,规格化设计主要源自于软件设计的两次危机.第一次是由于大量存在的goto语句,让当时被广泛应用的面向过程式的编程语言臃肿不堪,在逻辑性上与工程规模上鱼 ...
- OO第三次博客作业——规格
OO第三次博客作业——规格 一.调研结果: 规格的历史: 引自博文链接:http://blog.sina.com.cn/s/blog_473d5bba010001x9.html 传统科学的特点是发现世 ...
- [2017BUAA软工]第三次博客作业:案例分析
第三次博客作业:案例分析 1. 调研和评测 1.1 BUG及设计缺陷描述 主要测试博客园在手机端上的使用情况. [BUG 01] 不能后退到上一界面(IOS) 重现步骤:打开博客首页中任意博文,点击博 ...
- 北航OO(2020)第二单元博客作业
第二单元第一次作业 多线程设计策略 第一次作业的想法是设计三个线程:输入线程,调度器线程以及电梯线程.输入线程获取请求并发送给调度器线程:调度器线程通过查询电梯线程的状态(等待.停靠以及移动),并综合 ...
- 第三周博客作业<西北师范大学|李晓婷>
1.助教博客链接:https://www.cnblogs.com/lxt-/MyComments.html 2.学生作业打分要求: https://www.cnblogs.com/nwnu-dai ...
- OO第三次博客作业(第三单元总结)
(1)梳理JML语言的理论基础.应用工具链情况 Java 建模语言(JML)将注释添加到 Java 代码中,这样我们就可以确定方法所执行的内容,而不必说明它们如何做到这一点.有了 JML,我们就可以描 ...
随机推荐
- Jmeter(三十八) - 从入门到精通进阶篇 - 命令行运行JMeter详解(详解教程)
1.简介 前边一篇文章介绍了如何生成测试报告,细心地小伙伴或者同学们可以看到宏哥启动Jmeter生成测试报告不是在gui页面操作的,而是在gui页面设置好保存以后,用命令行来生成测试报告的.这一篇宏哥 ...
- javascript是一种什么样的语言
javascript是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML网页上使用,用来给HTM ...
- 99%的Python用户都不知道的f-string隐秘技巧
f-string想必很多Python用户都基础性的使用过,作为Python3.6版本开始引入的特性,通过它我们可以更加方便地向字符串中嵌入自定义内容,但f-string真正蕴含的功能远比大多数用户知道 ...
- 记一次在virtualbox中安装windows7遇到增强功能安装分辨率的问题
在windows7中遇到很多次安装好增强功能后并不能对其实现放大分辨率,使其跟随虚拟机界面大小而改变. 经过许多次的安装和恢复快照,发现了在设置中,显存的大小一直都是处于边缘的状态, 关闭虚拟机后,我 ...
- java多种文件复制方式以及效率比较
1.背景 java复制文件的方式其实有很多种,可以分为 传统的字节流读写复制FileInputStream,FileOutputStream,BufferedInputStream,BufferedO ...
- 使用Power BI构建数据仓库与BI方案
杀手级特性 今年Power BI的几大杀手级特性的GA,可以让其构建完整的数据仓库/数据湖和BI分析一站式方案. Power BI Premium Per User-超低的价格 Large datas ...
- 生活随笔:Furious 7:人生的路口,你先向西,但终点只有一个
FOR PAUL It's never goodbye see you again "他永远都是我们的家人."Dom起身准备离开 Letty问他,你打算不告而 ...
- SpringCloud-微服务架构编码构建
SpringCloud Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线).分布式系统的协调导致了样板模式, ...
- mac系统 php 7.2安装memcache扩展
memcache的安装 下载地址:https://github.com/websupport-sk/pecl-memcache/archive/php7.zip wget https://github ...
- ubuntu 14.04.5 编译Android 4.4.4 r1源码(最新)
本文博客链接:http://blog.csdn.net/qq1084283172/article/details/54426189 吐槽:ubuntu系统真是让人又爱又恨,也有可能是VMware Wo ...