OO2021-第三单元总结
一、设计策略
本单元中采取的设计策略如下:
1. 通读指导书,对各个模块间的组织关系有大致的了解,并根据要求完成构建方法。
2. 参照JML描述,完成各模块内部的实现,根据模块间的依赖关系,先实现Person、Group等,再实现Network。
3. 根据模块所提供的方法的需要,为模块内部的数据结构选择合适的容器。
4. 根据方法的JML描述,按顺序实现模块内部的每个方法,并注意边界条件。
5. 对于运算量较大的方法,需要找到合适的算法实现。
二、测试方法和策略
1. 使用指导书和手动构造的简单样例来测试是否运行正常。
2. 对于复杂的方法,使用JUnit进行单元测试,保证对语句的全覆盖,检验正确性。
3. 使用python构造以及评测机提供的强化用例进行性能测试。
三、容器的选择与使用经验
1.HashMap&HashSet
由于本次作业中,大量涉及对数据的查找,且HashMap在查找时的性能为O(1),大大优于线性表的O(n),
因此对于需要频繁查找的元素的组织方式,均采用了HashMap&HashSet。


2.对于部分没有频繁查找需求的数据,则采用ArrayList。

3. 在实现某些算法时,比如广度优先搜索、Dijkstra算法时,使用了队列Queue/优先队列PriorityQueue。


总结下来:
要求查找性能的用Hash,否则用ArrayList; 实现搜索相关算法时使用队列进行辅助。
四、出现的问题
1.正确性错误:
因为疏忽,在计算平均值的方法中,漏掉了对0值的检查,造成了除零错误。

2.性能问题
因为对算法的生疏以及对重复计算的优化不够,本单元作业出现了严重的性能问题。
1)重复计算
对于一些计算量大的get()方法,如果每次调用均需重新计算,效率会很低,
此时把结果作为一个属性存储,在发生变化时实时更新,查询时则无需重新计算。
比如计算Group的平均年龄,getAgeMean():

如果为Group新增一个属性ageAvarage, 在增加/删除Person时进行维护,就能提高效率。
2)算法优化
可以使用并查集来优化isCircle()、queryBlockSum等算法。
在sendIndirectMessage()中,Dijkstra算法可以进行堆优化。
五、图的构建与维护策略
1.构建
图以邻接表的形式储存。对每个Person节点,都用一个HashMap作为邻接表,保存与其连通的其他节点及权值。

2.维护
通过JML中定义的add、del等方法,对相应的Hash表进行增删。
六、心得体会
首先,通过JML的学习与应用,我体会到规格化设计的作用:
1.使用逻辑严格的规格代替自然语言描述,这样可以避免自然语言的模糊性、二义性。尤其是对特殊情况的规定清晰明了,不容易产生误解。
2.降低了沟通成本,可以将设计与实现的过程独立分开进行。当然这一切都要建立在双方对规格理解的细致与严谨之上。
除此之外,我还意识到实现人员在保证输出要求的同时,应灵活地实现代码,比如可以增加一些内部方法简化程序、
可以增加一些规格外的数据方便计算等,而不是仅限于JML规定的成分。

浙公网安备 33010602011771号