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. Rsync等传统文件同步方式已过时 如何寻找替代产品?

    Rsync原本是在Linux系统下面的一个文件同步协议,随着技术的发展,它也有其它版本的,如Windows和AIX.HPUX下面都有相应的版本可以支持的.它有很多版本都是免费的,配置也不复杂,所以很多 ...

  2. visual studio 2015 IOS开发连接mac时提示错误couldn't connect to xxxx, please try again的一个方法

    本人使用虚拟机MAC.原本使用虚拟机中的VS2015连接正常没有问题. 但是当把MAC的虚拟机文件COPY到另一个机器上,提示"couldn't connect to xxxx,  plea ...

  3. tidevice 报UsbmuxReplyCode.BadDevice错误解决办法

    备忘 换了个新手机照常使用tidevice进行操作发现报错 tidevice.exceptions.MuxReplyError: UsbmuxReplyCode.BadDevice 查了好久,终于解决 ...

  4. 使用vue的插槽理解

    使用插槽的时候其实就是引用子组件,在引用的组件中间写上你要的代码,然后在子组件的的<slot ></slot>中就包含父组件写下的代码. 父组件 import addshop ...

  5. 杭电oj 平方和与立方和

    给定一段连续的整数,求出他们中所有偶数的平方和以及所有奇数的立方和.   Input 输入数据包含多组测试实例,每组测试实例包含一行,由两个整数m和n组成.   Output 对于每组输入数据,输出一 ...

  6. React使用portal提示 The types returned by 'render()' are incompatible between these types.  Type 'ReactPortal' is not assignable to type 'ReactNode'.   Type '{}' is not assignable to type 'ReactNode'.

    原因:组件返回了个不是<></>的东西 原先代码: export default class Index extends React.PureComponent { rende ...

  7. JavaScript基础知识整理(变量)

    变量 ECMAScript变量有两种不同数据类型的值,分别是基本类型和引用类型,两者的不同在于基本类型值是简单的数据段,引用类型值一般指由多个值构成的对象 基本类型 基本数据类型包括5种:Undefi ...

  8. RabbitMQ宕机了怎么办?

    RabbiMQ宕机会导致消息丢失! 解决办法:可以做消息持久化. 非持久化消息:只有非持久化消息在RabbitMQ宕机时会发生消息丢失. 持久化消息:持久化的消息会在接收后被保存到磁盘中,所以Rabb ...

  9. css3 旋转 八仙桌

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. flutter 使用阿里iconfont图标库

    1. 打开Iconnfont,选择自己想要的图标添加到购物车! 2,在右上角点开购物车选择下载代码. 3. 解压下载的代码压缩包,我们可以看到一个iconfont.ttf 4. 在项目根目录下创建一个 ...