OO第4次博客作业

OO第4次博客作业

一、第4单元设计

      第四单元主要围绕UML图的结构进行JAVA代码编写,对JAVA的层次结构进行更多的认识。个人认为编程操作在实质上与上一章的PathContainer有许多的相同之处,难度也较上一章降低的很多。与此同时有许多新的新的概念需要理解,对我提出了编程之外的要求。

第十三次作业

    这次作业主要解决UML中的类图。主要包括2点内容,即类图的构建以及相应的查找函数。

1、课程预先写好的接口给出的是一种链式存储结构,通过ParentId找到所属的上层结构。在实际的编程中为了方便操作和查找,我采取的做法时自己编写了各个类储存下层结构和上层结构的Id,实现有序的层次结构。

2、由于在构造函数传入的Element元素无法确保合理的顺序性。因此需要分别对不同元素进行排序,分层处理。我的处理方式将CLASS和INTERFACE放在第一层, UML_INTERFACE_REALIZATION UML_ATTRIBUTE UML_OPERATION UML_ASSOCIATION UML_GENERALIZATION放在第二层,UML_PARAMETER UML_ASSOCIATION_END放在第三层,分别进行处理。

3、这次的测试似乎并没有对性能有任何要求,因此在查询函数中我为了确保正确性,使用了普通的顺序遍历就成功通过了所有测试案例。

第十三次作业类图:

第14次作业

      14次作业在第13次作业基础上增加了顺序图和状态图。并且在开源LAVA代码中增加了大量Element子类。表面上难度似乎大幅增加,实质上这次顺序图和状态图考的内容都非常简单并且和第13次作业非常相似,只是简单的计数和遍历问题。同时助教也将细节部分大幅简化了,少了很多重名、合并等边界问题。给出的Element子类最后也用到的不多。个人认为这次作业在难度上完全可以更上一个台阶。

      这次作业的难点不多,其中之一是UML003规则的判定,即类和接口的重复实现。需要判断的情况相对较多,包括只包含接口的重复实现,只包含1个类和接口的重复实现。类重复实现了父类已经实现的接口以及父类重复实现导致的子类也重复实现的情况。种类较多,比较容易遗漏。

      另一个难点在于代码量的控制。由于这一次作业概念较多导致代码量较大,想在500行之内搞定是不可能的,每个方法也非常容易超过60行的限制。我将UMLINTERACTION拆分成了3个类,1个类包括构造函数,第二个类负责上一次作业的查找函数,而第三个类负责这一次作业的函数。三个类之间有继承关系,从而使得最终类的代码量只有原来的三分之一。

 第十四次作业类图: 

      可以看见由于将每个元素都自己写一个独立的类,同时将最终类分成三层分别实现,导致我的代码和结构都比较复杂。优点则是将所有的实现都独立开来,方便代码复用。第十四次作业实现时完全照着上一次作业的模板在其之上添加而成。

第十三、十四次作业BUG修复

这二次作业共产生了3类BUG。第一是非常普遍的BUG:空指针异常。产生原因是对顺序图理解不够完全。例如第二次作业中出现了发送给endpoint的消息,但我的程序则忽略了对其的处理。

第二个BUG是类型转换错误。这一次的JAVA包中包括大量枚举、继承以及接口实现关系。我不慎将两个没有继承关系的类进行了强制转换,导致了BUG出现。

第三个BUG是对循环继承处理的错误。我在该项检查时使用了非常简单的方法,让一个类不断getfather,当最终回到自己是则最终出现循环继承。BUG在于若它的父类存在循环继承而其本身并不存在会导致循环判断最终步入死循环。

二、架构演进

1、第一单元作业

      第一次作业是针对简单表达式的求导过程,对于JAVA语法以及正则表达式都是第一次接触和学习。由于第一次进行JAVA编写,因此在实现上大致采用的是面向过程的写法,并没有考虑代码重用方面的构造,导致下一次作业完全重写。

      第二次作业在第一次的基础上增加了三角函数。吸取了第一次作业的教训,我将第二次作业的多项式结构层次化分为2个类,多项式和项,通过正则表达式匹配项的种类进行求导。这次作业我沿用了上一次的空格判断函数,同时对JAVA的模块化设计有了更多的理解。

      第三次作业结构较上一次作业更为复杂多变。我沿用了第二次作业的结构,并在其上增加了因子类,通过递归方式进行求导,顺利通过了这次的作业。

      在测试方面第一单元由于经验不足,大部分测试样例都是自己脑补出来的,主要聚焦于边界条件等方面,因此在互测以及自己对BUG的发现方面有许多不足之处。

  2、第二单元作业

       第一次作业是简单的单电梯且无换乘,因此没有BUG出现,代码量也非常少。在这一次作业中确定了电梯程序的3个基本类,包括输入线程,调度类以及电梯线程。在两个线程中使用了同步锁,初步感受到了线程协同的过程。

       第二次作业在上一次的基础上增加了电梯的捎带以及对于CPU时间的检查。我在第一次作业的基础上增加了电梯线程对于每一层对于捎带的判断,同时使得电梯线程和输入线程互相通信,防止电梯线程的轮询查询。

      第三次作业在第二次作业的基础上增加了多电梯运行的情况,以及每个电梯对于停靠楼层的限制。多电梯运行不难解决,为每一个线程增加等待和运行队列以及考虑电梯协同即可。关键在于对于每个电梯任务的拆分和合理调度,这也是这次作业我思考最多的地方。

      这一次作业的BUG测试无法采用上一次作业的自我脑补方式。我的做法是通过编写C程序随机生成测试样例,同时通过自己编写的检测程序判断测试样例的合理性,同时通过一些自己编写的代码量较小的针对边界条件的测试程序进行BUG检查。总体上效率明显高于上一次的作业。

3、第三单元作业

       第一次作业针对的是简单的 PathContainer,所要执行的任务也只是增删查而已。在图的构造方面,由于这次作业对性能有非常严格的要求,因此我采用HASHMAP存储PATH。同时针对getDinstinctCount指令的复杂性,在每一次增减指令的时候更新DINSTINCTCOUNT,减少调用该函数的负担。

      第二次作业在第一次作业的基础上增加了最短路径以及连通性的查询。解决方法通过BFS替代DJ算法,降低复杂度,保证了性能。

      第三次作业增加了非常多的概念,包括不同的权重图,最大连通块的存储以及对于换乘的处理。在沿用第二次作业总体构造的基础上,我增加了对于连通块并查集的存储以及权重图的存储。同时通过拆点法解决换乘问题。这一次作业最大的难点就是对于DJ算法的处理。我使用了堆排序优化了算法,但是没有找到好的方法缓冲中间查询结果,导致超时情况的大量出现。

    针对BUG的寻找以及互测,我的方法沿用上一次的内容,通过大量构造随机数据进行压力测试,并自己编写程序测试边界情况。不同的是这一次作业网上提供了大量JML工具,我也利用了JML UnintNG和Junit进行测试。

4、第四单元作业

(即本博客前部分内容)

三、课程回顾

      在面向对象课程中我充分感受到了不同于C语言的面向对象编程方法,模块化设计以及对于测试的各类方法。学习了多线程编程,JML,UML等各种JAVA编程的特性方法,同时也学习掌握了JAVA编程大量的辅助工具链。此外锻炼了我们的自我学习能力,许多关于JAVA构造函数,HASHMAP等各类JAVA特性方法的使用都是通过自己的不断尝试实践之后才能够完全掌握的,而不是老师的一味教学。最后,这次的课程也锻炼了我们对于大量程序代码的构造以及长时间编程能力,以及对于代码一步步构造和分析的能力,这也将为我们未来工作打下一定的基础。

四、对于课程的建议

1、最后一次关于UML的作业第1、2次作业几乎没有什么跨度,同时关于UMLENDPOINT等大量新增概念都没有用上,函数也是非常基本的函数。可以适当提高该部分内容的难度。

2、适当增加中测的难度,同时增加强测测试点的梯度。常常出现有人一个小点忽视导致强测爆光而另外一个人构造本身有问题却能安然无恙的情况。

3、感觉可以增加一单元的综合内容,将现实中企业可能遇到的编程问题交给我们来编程而不是简单的给一些抽象问题,感觉这样能够得到更大的锻炼。

4、可以增加对于常用工具链的介绍。仅仅介绍UML和JML感觉比较有限,可以增加对于自学其他常用工具的要求。

猜你喜欢

转载自www.cnblogs.com/h87d/p/11073088.html