1.JML规格设计策略

  我三次作业采用的方法都是从性能与存储大小方面考虑。在满足规格的条件下尽量做到运行速度最快,所用空间最小。因为这个单元的作业如果单单只是照着jml规格来翻译的话就失去了意义(因为我太菜了没写测评机啊啊啊啊啊)。

  本单元内容是根据给定的规格实现一个可以实现个人操作,好友关系操作,群组操作,收发消息等的社交网络。我写这个单元的时候,首先是写 Person 这个类, Person是这个单元最基础的类,和其他的类几乎没有牵连,故可以最先完成。每一次进行迭代的时候,我都将两次的规格进行文本对比以找出这所更新的,再来添加这些新的东西。写完 Person后写 Group、 Message等类,这个是只用到 Person的,之后再写 Network,这个是整个代码的核心。最后再完成异常类的编写。

  在具体的类的实现中,我首先是将所有的规格代码都看一遍,以此来选择最合适的容器来设计。在参考了一些同学的方法后,我优化了一些函数,像异常类出现频率高的直接整合成一个函数来调用,以及使用了一些已存在的函数(避免自己造轮子)。

2.测试方法和策略

  这次的测试方法主要还是根据jml规格来。阅读jml的代码,考虑每一句的极限情况,以此来构造边界数据。从理论上来说只要每一步都是正确的,那合起来肯定没问题,但是在实际的测试中发现其实很多情况对单独的一条限制来测试是不够的,因为也许会有其他的语句隐性地限制了,所以还是要阅读一整个方法的规格,综合起来考虑边界情况来测试。不过只要是写的满足了规格,在测试中就不会出错,这个单元重点就在认真阅读jml代码。

  测评机就没写了,自己构造了数据手跑和同学的进行对比。

3.容器的选择和使用

  这个单元的容器主要是 Hashmap。这是基于对速度的考量,而且三次作业的所有类的id都是唯一的,这也是一个很好的使用 Hashmap的条件。怎样选择容器,其实质是基于对jml规格代码的理解。在第一次作业的queryBlockSum函数中,其jml规格代码有用 Person与该 Person之前加入的所有 Person是否有相连关系,这个当时我就认为是和 Person的加入顺序有关的,于是在 Network中 Person这个我使用了Arraylist.直到参考他人的代码时才发现原来可以用 Hashmap,这个函数就是求联通分量的,而且这也是可以通过离散来证明的,果然还是基础学科没学好。

  我使用 Hashmap大多时候是建立一个id和对象的索引,不过在解决联通块问题时,也使用了 <Person, Person> 的哈希键值对,也是为了建立人际关系。另外其实在 Hashmap中,有许多已经造好的轮子,比如merge函数,这个函数实用性非常强,可以大大简化代码,估计性能上没太大的影响。还有就是compute函数,重新计算并返回新的值。我还是对java不太熟悉,感谢给我参考代码的同一个房间的同学!

4.性能问题

  第一次作业第一个性能问题就是每一个查询操作不能遍历,使用 Hashmap就可以解决这个问题。第二个性能问题是对于联通块的计算。在第一作业中,我的iscircle函数直接写的dfs,dfs搜到就立马退出,然后计算联通块也是完全照抄规格来写的,强测没有超时,但是被同房的同学hack超时了,在参考完同学代码后,使用了一个类似找出一个联通块的根的方法,创建了一个<Person, Person>的哈希表,同时定义了一个btc变量来记录联通块的数量。每次有people加入,btc++;每当有addRelation就btc--,同时寻找到根,将people与根相连。这样一来查询联通块直接返回btc,复杂度为O(1)。而iscircle的话直接比较两者的根是否相同即可。

  第二次作业的话主要是对求年龄平均数与标准差的计算,这个也是不能最后遍历求和啥的,得先定义一个变量来存储年龄和,年龄平方和。最后在对规格中给出的表达式来化简求值。主要是要注意精度问题,要严格按照规格来。对于getValueSum这个函数似乎没有好的化简方法,复杂度为O(n^2)。因为可能有删除person的操作,如果也事先记录的话,这个删除也会是O(n^2),并不会有化简。这个函数我选择每次只遍历没有进行比较过的,也只是少了一半的时间。

  第三次作业的话主要是最短路径的查询问题。我是用的是堆优化的Dijkstra算法,并且每查完一次都记录先来了(如果增加了新的关系就作废)。在这条路线上的所有点之间都是最短路径,尽量减少查询的次数。

5.架构设计

  本单元完成了一个基本社交网络的模拟,最基础的类为 Person,该类就是图的节点,之后各种各样的类也是围绕节点展开,节点之间存在联系,即构成边,并赋值为value。同时还存在 Group这种结构可以保存多个 Person,以及相应的数据内容。除此之外还有 Message 的结构可以实现人与人直接,人与组织之间信息的传递。最后 Network类将之前的各类联系和囊括在一起,保存了之前各类存在的信息。

  关于图的维护,主要是对节点和边的增删。主要有addPerson、addRelation等函数。在编写这些函数的时候,需要考虑到自己所有的容器,他们是否需要改变。比如在维护查询联通块的函数中,addPerson需要对联通块数量增1,addRelation则需要对联通块数量减1,同时更新根节点与节点之间的关系。在查询最短路径时,在这两个函数中都要及时维护边与节点的数量关系等等。

JML的更多相关文章

  1. JML契约式设计——第三单元学习小结

    一.前言 本单元作业都是关于JML(Java Modeling Language),JML是一种契约式设计(Design by Contract)的语言,契约式设计的主要目的是希望程序员能够在设计程序 ...

  2. 面向对象设计与构造:JML规格单元作业总结

    面向对象设计与构造:JML规格单元作业总结 第一部分:JML语言理论基础 JML语言是什么:对Java程序进行规格化设计的一种表示语言 使用JML语言有什么好处: 用逻辑严格的规格取代自然语言,照顾马 ...

  3. 2019年北航OO第3单元(JML)总结

    1 JML语言的理论基础及应用工具链 1.1 JML语言 Java建模语言(JML)是一种行为接口规范语言,可用于指定Java模块的行为.它结合了Eiffel的"契约设计(design by ...

  4. OO第三次作业总结(JML)

    第三单元的课题是JML, 即java建模语言.JML是一种描述接的语言.通过前置条件和后置条件,描述一个模块的行为.本单元我们扮演一个项目中的一员,完成自己的一小部分工作,最终实现整个项目.而限制我们 ...

  5. OO第三单元总结——JML

    目录 写在前面 JML理论基础 JML工具链 JMLUnitNG的使用 架构设计 Bug分析 心得体会 写在前面 OO的第三单元学习结束了,本单元我们学习了如何使用JML语言来对我们的程序进行规格化设 ...

  6. OO第三单元总结--根据JML写代码

    一. JML语言 1. 理论基础 首先,JML不是JAVA的一部分,它是一群研究者为JAVA设计的扩展部分,但还没有得到官方的支持.因此,JAVA编译器并不支持JML,所以要想JML起作用,只能采用类 ...

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

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

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

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

  9. OO_BLOG3_规格化设计(JML学习)

    目录 JML语言学习笔记 理论基础 应用工具链情况 JMLUnit/JMLUnitNG UNIT3 作业分析 作业 3-1 实现两个容器类Path和PathContainer 作业 3-2 实现容器类 ...

  10. 【面向对象】第三单元总结——JML

    梳理JML语言的理论基础.应用工具链情况 JML语言理论基础 JML(Java Modeling Language)是一种行为规范接口语言,通过使用不会被编译的注释形式,和固定关键字的语法,指定Jav ...

随机推荐

  1. Java方法之稀疏数组

    稀松数组 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组. 稀疏数组的处理方式是: 1.记录数组一共有几行几列,有多少个不同值 2.把具有不同值的元素和行列及值记录在一 ...

  2. python获取报文参考代码

    # -*- coding:utf-8 -*- import sys import stomp import logging import time class MyListener(object): ...

  3. TypeScript Number

    TypeScript Number TypeScript 与 JavaScript 类似,支持 Number 对象. Number 对象是原始数值的包装对象. 语法 var num = new Num ...

  4. Software--EB--Project 身份验证

    2018-01-09  16:57:51 身份验证服务 应该有两种形式得身份验证机制: 1. 在其他网站上又 Web 账号得顾客在注册或登陆到该网站时候应该能够使用这些账号. 2.没有的顾客或者希望新 ...

  5. mongodb更改账户密码

    docker部署方式更改 sudo docker exec -it mongodb mongo admin (登录数据库容器) use admin db.auth('admin','shijiehep ...

  6. java 类对象四种方法加载方式

    public static void main(String[] args) throws Exception { //第一种 //这里需要做异常处理,或的加载类的类对象类. Class<?&g ...

  7. java中BIO、NIO、AIO区别

    ava中的IO主要源自于网络和本地文件 IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启 ...

  8. dos命令初学

    DOS命令 打开DOS命令方式 开始+系统+命令提示符 WIN键盘+R 输入CMD 打开控制台(推荐使用) 在任意文件夹下面,按住shift键加鼠标右键点击,在此处打开命令行窗口 自愿管理器的地址栏前 ...

  9. not eligible for getting processed by all BeanPostProcessors

    描述 这个BUG大的起源是我上线以后,在后台看日志的时候发现一行奇怪的INFO日志: 2022-06-09 23:34:24 [restartedMain] [org.springframework. ...

  10. bzoj 2337

    有人说这题像游走... 关于游走的思想,他死了... 明明直接从期望dp的角度考虑更简单合理嘛 首先由于是异或运算不妨逐位考虑 对于每一位,设状态$f[i]$表示从第$i$个点到第$n$个点,这一位上 ...