OO第三单元总结
Published on 2021-05-27 21:25 in 分类: 2021Spring-BUAA-OO with dutrmp19

OO第三单元总结

要求

(1)总结分析自己实现规格要求所采取的设计策略
提示:设计策略一般指整体性的设计思路分析

(2)结合课程内容,整理基于JML规格来设计测试的方法和策略

(3)总结分析容器选择和使用的经验

(4)针对本单元容易出现的性能问题,总结分析原因
如果自己作业没有出现,分析自己的设计为何可以避免

(5)梳理自己的作业架构设计,特别是图模型构建与维护策略
提示:针对最终形成的架构进行分析,应和设计策略部分的相关阐述配合起来

设计策略

(1)总结分析自己实现规格所采取的设计策略

  1. 阅读往年学长博客,查看坑爹的地方。具体地说,在任意一篇总结博客中,Ctrl+F,“超时”。
  2. 通读规格,对整个project有大概的了解,尽量从自然语言的角度去理解规格。
  3. 调整规格使用的容器
    虽然规格里都是数组,但是,我们必不可能跟它一样。所以,找到所有可以不用数组的地方,确定要使用的容器类型。
  4. 对规格方法的调整。
    就像在第十次作业里,我们要手动维护ageVar一样,整个规格里,还是有很多方法有优化的空间,所以就尽可能地优化。
  5. 和同学交流,看看有没有什么比较坑的地方。

测试的方法和策略

(2)结合课程内容,整理基于JML规格来设计测试的方法和策略

这个问题问得非常有深度,让我有点把握不住,所以思索良久后,我打开了百度百科

方法:
方法是一个汉语词汇,方法的含义广泛,一般是指为获得某种东西或达到某种目的而采取的手段与行为方式。方法在哲学,科学及生活中有着不同的解释与定义。

策略:
计策谋略。一般是指:1. 可以实现目标的方案集合;2. 根据形势发展而制定的行动方针和斗争方法;3. 有斗争艺术,能注意方式方法。

感觉方法注重的是行为方式,而策略注重的是一类方法。

策略:面对要测试的对象,给定输入,保证输出的正确性。

方法:

  1. 用Junit对各个方法进行测试,输入的数据包括:合法数据、边界数据以及非法数据
  2. 当完成一整个project后,用测评机对整个工程进行测试

以上就是我能想到的测试方法。

容器选择和使用

(3)总结分析容器选择和使用的经验

  1. 注意到要我们实现的类中,很多都是有一个专有的ID,为了性能,Hashmap会被大量地使用。
  2. 有些容器在使用的时候,强调了“有序性”,比如获取一个Person的前四条消息,“前四条”就具有非常明显的顺序特征,所以使用了ArrayList。
  3. 有些容器是为了专门的算法而设计的,比如堆优化的迪杰斯特拉算法中的PriorityQueue。

以上三点就是我容器选择的考量。

至于经验,删除的时候使用迭代器就好了,没啥大的经验。如果高级一点的话,stream很不错。

性能问题

(4)针对本单元容易出现的性能问题,总结分析原因。如果自己作业没有出现,分析自己的设计为何可以避免

homework10/Network.java: isCircle()

可能出现性能问题,跟个人的实现方式有关。如果写得好,实际上dfs和bfs都不会出问题,没必要用并查集。关键在于,要把遍历过的点给收集起来,避免重复遍历。

使用并查集的话,,如果有一天该Network中某个人去见马克思了,得重新更新。

getValueSum()同理。

homework10/Group.java: getAgeMean()

求平均数的函数。如果不做优化,复杂度为O(n),当Group中Person人数很多时,耗时间。

我的设计是在Group中维护一个ageSum,每当要对Group中的人进行增或删时,就同步修改ageSum,要getAgeMean()时,就返回ageSum/size。这样就把复杂度降低到了O(1)。

getValueSum()同理。

homework11/Network.java: sendIndirectMessage()

要返回两个Person之间最短路径的长度。

如果采用普通的迪杰斯特拉算法,复杂度为O(n^2),直接使用会超时。

我的设计是使用堆优化的迪杰斯特拉算法,复杂度为O(nlogn),所以没有超时。

架构

(5)梳理自己的作业架构设计,特别是图模型构建与维护策略
提示:针对最终形成的架构进行分析,应和设计策略部分的相关阐述配合起来

图(graph),说到底,就是节点(vertex)和边(edge)。

本次作业,Network中,我通过Hashmap<Integer, Person> personId2Person来维护图中的节点。对于图中的边,则通过HashMap<Person, Integer> person2Value来维护,为了方便我的isCircle(),我还使用了ArrayList<Person>来维护每个节点的邻接节点。

这个好处是体现了面向对象的思想。我记得在离散数学课程中,边的维护是依靠图中的三元组,而到了面向对象这门课里,让节点维护自己的边,类似于邻接表,这样更符合生活实际。

图模型的构建就是基于以上三种数据结构。

至于维护,只要保证增删改时,三种数据结构以及做了维护的ageSum等变量被同步更新,特别注意删除时用迭代器。

总的来看,为了效率,特定去维护一些变量,这样可能造成某些方法考虑不周,导致维护不当而出错,所以要辅之以必要的测试,这应也是本单元的一个考察要点。

心得

互测就这样结束了,这是我唯一一次和其他同学对拍,感觉良好,三次作业都没出bug。

不过,,这样的结果就是被分配到比较强的互测屋,每次把别人的jar打包好,然后跑上测评机,一无所获。觉得心蛮累的。

还有就是契约式编程,当我们写一个函数的时候,要求考虑到各种情况,契约式编程把这种需求完整地表达了出来,虽然以后我们很少用JML,但是,对于我们思维的全面、少写bug,是很有帮助的。

如果您有任何关于文章的建议,欢迎评论或在 GitHub 提 PR

作者:dutrmp19
本文为作者原创,转载请在 文章开头 注明出处:https://www.cnblogs.com/dutrmp19/p/14819853.html
遵循 CC 4.0 BY-SA 版权协议


posted @   dutrmp19  阅读(67)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示