OO第三单元个人总结

JML理论与基础与应用工具链

JML是什么?

  • Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为 。它结合了Eiffel的契约设计方法 和Larch 系列接口规范语言的基于模型的规范方法 ,以及细化演算的一些元素 。草稿 《Design by Contract with JML》(由Gary T.Leavens和Yoonsik Cheon撰写)解释了JML作为Java的契约式设计(DBC)语言的最基本用法。

JML基础语法

  • 原子表达式

    \result:表示此方法执行后的返回值。

    \old(expr):表示一个表达式expr在方法执行之前进行计算后的取值。

  • 量词表达式

    \forall:全称量词,对于每个在范围内的变量,若全部满足表达式,则返回真。

    \exists:特称量词,对于每个在范围内的变量,若存在一个变量满足表达式,则返回真。

    \sum:返回给定范围内的表达式的和。

  • 前置条件

    require P;使用者必须满足前置条件,即P为真。

  • 后置条件

    ensures P;实现者依据前置条件,保证实现过程满足P的要求。

  • 副作用

    assignable(可赋值)、modifiable(可修改)

    /nothing关键词表示没有任何可修改的变量,/everything关键词表示可修改任何变量

  • 异常处理

    signals (***Exception e) b_expr当b_expr为真时,方法抛出异常e。

    signals_only (***Exception e)满足前置条件即抛出异常e。

  • 不变式

    invariant P;在所有可见状态下都要求满足P为真。

  • 状态变化约束

    constraint P;前序可见状态和当前可见状态的约束。

JML工具链

  • openjml:对JML注释的完整性进行检查。检查包括经典的类型检查、变量可见性与可写性等。通过命令行使用OpenJML时,可以通过-check参数(缺省)指定类型检查。

  • SMT Solver:一般为检查代码规格,生成运行时测试等。与openjml一同使用。

  • JMLUnitNG:针对类自动生成测试样例并进行测试。

部署SMT Solver

  • /*@ public normal_behavior
    @ ensures \result == a1 + a2;
    @*/
    public int sum(int a1, int a2) {
    return a1 + a2;
    }

  • /*@ public instance model int[] arr;
    @*/
    private ArrayList<Integer> array = new ArrayList<>(); /*@ public normal_behavior
    @ requires arr != null;
    @ ensures (\forall int i,j; 0 <= i && i <= j && j < arr.length; arr[i] <= arr[j]);
    @ also
    @ public exceptional_behavior
    @ signals (NullPointerException e) arr == null;
    @*/
    public void sorted() {
    Collections.sort(array);
    }

  • 对第11次作业进行检查

部署JMLUnitNG/JMLUnit

[TestNG] Running:
Command line suite Passed: racEnabled()
Passed: constructor MyGroup(-2147483648)
Passed: constructor MyGroup(0)
Passed: constructor MyGroup(2147483647)
Failed: <<MyGroup@800003e1>>.addPerson(null)
Failed: <<MyGroup@800003c2>>.addPerson(null)
Failed: <<MyGroup@3e1>>.addPerson(null)
Failed: <<MyGroup@800003e1>>.delPerson(null)
Failed: <<MyGroup@800003c2>>.delPerson(null)
Failed: <<MyGroup@3e1>>.delPerson(null)
Passed:<<MyGroup@800003e1>>.equals(null)
Passed:<<MyGroup@800003c2>>.equals(null)
Passed:<<MyGroup@3e1>>.equals(null)
Passed: <<MyGroup@800003e1>>.equals(java.lang.Object@800003e1)
Passed: <<MyGroup@800003c2>>.equals(java.lang.Object@800003c2)
Passed: <<MyGroup@3e1>>.equals(java.lang.Object@3e1)
Passed: <<MyGroup@800003e1>>.getAgeMean()
Passed: <<MyGroup@800003c2>>.getAgeMean()
Passed: <<MyGroup@3e1>>.getAgeMean()
Passed: <<MyGroup@800003e1>>.getAgeVar()
Passed: <<MyGroup@800003c2>>.getAgeVar()
Passed: <<MyGroup@3e1>>.getAgeVar()
Passed: <<MyGroup@800003e1>>.getConflictSum()
Passed: <<MyGroup@800003c2>>.getConflictSum()
Passed: <<MyGroup@3e1>>.getConflictSum()
Passed: <<MyGroup@800003e1>>.getId()
Passed: <<MyGroup@800003c2>>.getId()
Passed: <<MyGroup@3e1>>.getId()
Passed: <<MyGroup@800003e1>>.getRelationSum()
Passed: <<MyGroup@800003c2>>.getRelationSum()
Passed: <<MyGroup@3e1>>.getRelationSum()
Passed: <<MyGroup@800003e1>>.getValueSum()
Passed: <<MyGroup@800003c2>>.getValueSum()
Passed: <<MyGroup@3e1>>.getValueSum()
Failed: <<MyGroup@800003e1>>.hasPerson(null)
Failed: <<MyGroup@800003c2>>.hasPerson(null)
Failed: <<MyGroup@3e1>>.hasPerson(null)
Failed: <<MyGroup@800003e1>>.updateRelation(null)
Failed: <<MyGroup@800003c2>>.updateRelation(null)
Failed: <<MyGroup@3e1>>.updateRelation(null)

如上,得到对MyGroup测试结果,基本为边界条件,如int最大最小和零,以及引用为null的情况。

作业架构分析

第九次作业

本次作业要求通过Person、Network接口和其中的JML规范,实现自己的MyPerson、MyNetwork类,总体难度不大,依据JML完成实现即可。

由于性能的要求,我们需要寻找合适的容器实现交互网络中的Person的存储和每个Person对应的联系人Person的存储,在这里我使用HashMap作为容器,由于可能需要大量的contians判断一个Person对象是否已经存储在容器中,因此使用Hashmap帮助我们完成散列表的查找,以常数的时间复杂度完成。

对于isCircle的判断,我采用BFS广度搜索来判断图的连通性,由于使用了图论算法,我构造了MyMap对顶点进行管理,并实现了MyNode管理一个点内的数据结构。

第十次作业

本次作业增加了Group接口和JML规范来实现对群组中的人的模拟,增加了RelationSum、ValueSum、ConflictSum、AgeMean、AgeVar等方法,这些方法的普通实现都需要对群组中的容器进行遍历,性能损失极大,因此这里采用了对RelationSum、ValueSum、ConflictSum的缓存,在对Group中增加Person时,更新相应的数值,从而避免一次又一次的重复遍历。

由于AgeVar在计算方差时,使用一些特殊的公式会造成精度不足的情况,因此在实现中仅采用遍历计算。

第十一次作业

本次作业增加了borrowFrom、queryMoney等与对应的Person中money有关的方法,实现并不困难,重点在于queryStrongLinked、queryMinPath以及queryBlockSum方法,对性能和算法都有着较高的要求。

queryStrongLinked没有使用tarjan等困难的算法,由点的双连通的特性,通过寻找出一条连通路径,除去两头端点,遍历剩余各点,每次只删除遍历到的一个点,然后进行bfs运算,观察是否连通,运用这种暴力方法,可以检查这个路径中是否存在割点,也就是说,两个点之间是否存在割点,若存在,则必不可能存在点的双连通性,也就计算出了结果。

queryMinPath方法的实现采用了Dijsktra算法加利用TreeSet的最小值计算优化,由于TreeSet本身采用红黑树实现,在我们寻找最小权重的点时,极大地简化了时间复杂度。

queryBlockSum使用了并查集的算法,在每次addRelation时,将两个点的祖先寻找到,并将其中较长的分支,插入较短的分支中,保持其不退化。最后,遍历割点,计算没有祖先,即祖先是自己的点的数量,即可得到Block的数量。

Bug与修复

第九次作业

本次作业在在强测中没有遇到问题。

在互测中,主要构造边界数据,尽量制造可能TLE的数据,同时。利用对拍器和随机测试数据生成器完成正确性检验,在此次互测中没有hack到别人。

第十次作业

本次作业由于在五一期间,当时正在外旅游,在最初并未实现缓存,仅仅使用ArrayList加快遍历速度,并且根据对称性减半了遍历的次数,但由于时间紧张,没有进行全面的测试,未发现双重for循环中i、j终止条件写错了,导致强测爆零,甚至没有进入互测。

在修复bug中,除了上述bug,增加了缓冲机制,解决了TLE的问题。

第十一次作业

本次作业强测让人及其糟心,四个点t了,但重新提交一次,就能过一个点,另外两个点被生生卡在超过时限0.0几秒的地方。在研讨课中有同学提到初始容量问题,遂减小初始大小,过了……(说好边界不卡的)

互测中同样利用自动化评测机对其他代码疯狂输出,可惜未发现问题,在查看其代码与JML匹配程度中也未发现问题。

心得体会

JML是一种面向规格的设计语言,他让我们依据规格,能够正确的使用方法和数据,能够写出完善的功能实现,并且在保证正确性的条件下,选择不同的实现方式,这种代码编写方式让人十分舒服,写的有理有据。

JML代码规格,说白了又是一次离散数学的学习,通过形式化语言的表述,让程序员更加精准的完成代码,也让测试变得更加切中肯綮,总体来说,为我们的学习之路打开了一扇新的窗户。

OO第三单元个人总结的更多相关文章

  1. OO第三单元作业总结

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

  2. 规格化设计——OO第三单元总结

    规格化设计--OO第三单元总结 一.JML语言理论基础.应用工具链 1.1 JML语言 ​ JML(java modeling language)是一种描述代码行为的语言,包括前置条件.副作用等等.J ...

  3. 【OO学习】OO第三单元作业总结

    [OO学习]OO第三单元作业总结 第三单元,我们学习了JML语言,用来进行形式化设计.本单元包括三次作业,通过给定的JML来实行了一个对路径的管理系统,最后完成了一个地铁系统,来管理不同的线路,求得关 ...

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

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

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

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

  6. OO第三单元作业——魔教规格

    OO第三单元作业--魔教规格 JML的理论基础和相关工具   JML(Java Modeling Language,Java建模语言),在Java代码种增加了一些符号,这些符号用来标志一个方法是干什么 ...

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

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

  8. 2020北航OO第三单元总结

    2020北航OO第三单元总结 本单元要求是根据JML规格完善代码,初看是一个简单的代码照搬实现的东西,但最后才发现由于CPU时间的限制,还考察了大量优化策略及数据结构中关于图的知识,是一次非常注重细节 ...

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

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

随机推荐

  1. 负利率时代,NGK DeFi是否会推动资本向加密货币迁徙?

    2020年,全球经济危机持续,贸易战争以及天灾人祸使得全球各国的经济雪上加霜,为了挽救低迷的经济,美国.欧洲.日本各国央行竞相放水,全球正在滑入负利率时代. 负利率下,资本加速从法币向数字货币迁徙,因 ...

  2. NGK全球启动大会圆满落幕

    加州时间2020年11月25日,NGK全球启动大会在美国硅谷圆满落幕.本次NGK全球启动大会为NGK正式在全球上线拉开了序幕. 百余位受邀嘉宾出席了本次NGK全球启动大会,其中包括NGK创始人.星盟投 ...

  3. 03.Jupyter Notebook高级-魔法命令

    %run %run C:\Users\User\Desktop\hello.py hello world %timeit %timeit L = [i for i in range(1000)] 29 ...

  4. 文件I/O的内核缓冲

    本文转载自文件 I/O 的内核缓冲 导语 从最粗略的角度理解 Linux 文件 I/O 内核缓冲(buffer cache),啰嗦且不严谨.只为了直观理解. 当我们说一个程序读写磁盘上的文件时,通常指 ...

  5. 开源OA办公平台功能介绍:应用市场-固定资产管理(一)功能设计

    概述 应用市场-固定资产管理,是用来维护管理企业固定资产的一个功能.其整个功能包括对固定资产的台账信息.领用.调拨.借用.维修.盘点.报废等一整个生命周期的动态管理过程.力求客户安装就可以使用. 本应 ...

  6. HTTP/1.1 有点慢,我想优化下!

    问你一句:「你知道 HTTP/1.1 该如何优化吗?」 我想你第一时间想到的是,使用 KeepAlive 将 HTTP/1.1 从短连接改成长链接. 这个确实是一个优化的手段,它是从底层的传输层这一方 ...

  7. RabbitMQ(二) Java使用RabbitMQ

    2-1 RabbitMQ 生产者消息发送 创建 Maven 项目 Send 加入依赖 <dependency> <groupId>com.rabbitmq</groupI ...

  8. 你们一般都是怎么进行SQL调优的?MySQL在执行时是如何选择索引的?

    前言 过年回来的第二周了,终于有时间继续总结知识了.这次来看一下SQL调优的知识,这类问题基本上面试的时候都会被问到,无论你的岗位是后端,运维,测试等等. 像本文标题中的两个问题,就是我在实际面试过程 ...

  9. LightOJ-1074(SPFA判负圈+Bellman-Ford算法)

    Extended Traffic LightOJ-1074 这题因为涉及到减法和三次方,所以可能会出现负圈. 这里使用的算法叫做SPFA算法,这个可以用来判负圈和求解最短路.Bellman-Ford算 ...

  10. IDEA的下载、安装与破解

    IDEA的下载.安装与破解 下载地址:https://www.jetbrains.com/idea/download/#section=windows 建议下载2018.2版本,方便破解 安装 一直下 ...