• 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,是很有帮助的。

  • 相关阅读:
    c#中常用的一些异常类小结希望大家留言补充
    【转】ASP.NET学习步骤
    【转】Android是什么?
    【转】.NET各大网站编程技术网址
    毕业设计日志(一)面向对象编程基础
    实习日志(1)
    多边形
    颜色选择器
    java多线程小练习
    方块移动
  • 原文地址:https://www.cnblogs.com/ticlab/p/14819853.html
Copyright © 2020-2023  润新知