OO第四单元作业总结以及课程总结
第四单元作业架构分析
第一次作业其实是本单元三次作业中最难的一次。由于第一次是第一次作业,要考虑到搭建框架和设计架构,这次作业的思维性很强。在了解了各个类型元素(Element)之间的关系之后,我采用了如下设计架构。类似于课程组所给的源代码的架构,但将class与interface一同继承于一个合并类。新建立operation和association类让自己能够更多的操作空间(能够更好地获取相关数据)。其实第一次作业很大部分时间都在完成架构的设计,这个框架设计好了之后完成代码就十分轻松了。
在第一次作业思路的启发下,第二次作业和第三次作业的设计架构基本思路都一样,将不好处理的、需要额外增加方法操作的类单独建立。如此思路清晰之后,每一个问题也都迎刃而解了。
单元作业架构分析
第一单元
在第一单元中由于出现的类别很多,很难用一种统一的表达形式将所有的可能性表达,所以这个时候就需要细致的分类。先用preprocess进行预处理,随后按照图中分为了sin、cos、幂函数、表达式这几类,他们统一实现“因子”接口。每一类都有自己的toString和derive方法。这很好的把第二次作业中Getoutput类的方法结合在了每一个不同的类中,提高了代码的耦合度。本次作业的架构设计十分有面向过程的味道,因为从类的名字就能看出来,首先预处理(Preprocess),然后计算PolyCompute。
第二单元
第二单元电梯作业是本课程的重难点。由于引入了多线程,这就让代码设计变得更加复杂,测试和验证也更加不稳定。在第二单元中,三次作业都是用的是生产者消费者模式进行构造。思路图和架构设计类图如下:
我采用了消费者和托盘交互的方式,在需求到达调度器时,调度器判断是否可以直达,需要坐哪一类的电梯。在电梯类中,当一个请求进入时,判断他是否需要转乘,若需要,则寻找他最近的转乘楼层作为目的地(这就是为什么我要创建一个newpersonrequest类)并存入一个transform的数组进行保存。当一个人out的时候,检查他是否在transform队列中,将他原来的楼层去出并返回给调度器(此时这个人就是直达类型)。许多判断的方法都在transform类中实现,降低了代码的耦合度。
但是这个单元最重要的还是保证线程安全。我在防止死锁等方面都遇到了不少的困难,在加上计算机调度线程的随机性,导致了输出结果的多样性和难复现性,代码的调试工作变得异常困难,第二单元的最后一次作业可以说让我十分痛苦,因为强测中出现了本地如何都无法复现的bug,并且我在多位同学的测评鸡的测试下也没有能够复现。最后的bug修复也只有放弃了。
第三单元
第三单元是JML相关任务,最最主要的重点就在于理解并准确的翻译JML规格,将规定的JML规格转化为完整、准确的java代码。对于第三次作业而言,由于要计算点双连通,需要用到tarjan算法以及图的性质,所以我创建了Edge类来帮助图的表达,创建了tarjan类进行tarjan算法的计算。同时,MyPerson和MyGroup类中的方法也保证其他MyNetwork类的要求能够快速正常完成,并且因此降低了代码的耦合度。
四个单元中测试理解与实践的演进
我在测试方面其实做的很不到位,很多时候要借助同学的测评鸡才能进行完整的测试,自己测试很多时候也只是随机生成数据和手撸数据。
在第一单元里,我并没有使用自动测评,而是使用python随机生成数据后自己用程序跑,用python自带的库来计算对拍。对于一些复杂的迭代,例如((((((x))))))这样的样例,我都是手动创造的。总的来说,这个单元由于自己在面向对象思维上还很薄弱,测试效果一般。
在第二单元中,我测试所有的数据都是自己创造的,可以说是十分单薄。后来我借用了同学的测评机进行测试,也通过测评机发现了bug。事实上,本单元的错误大多在于线程安全,死锁等等,这类的bug不好在本地复现,可能还需要更加充足的测试才能完全覆盖。
第三单元中,我还是采用了十分原始的测试方法:手撸数据,然后和同学对拍。在同学的帮助下,我也成功随机生成了测试数据,并且使用shell脚本与同学对拍。这个单元我并没有使用Junit来自己进行测试。
第四次作业中,我所有的测试数据都是自己手撸的。基本上每一个要求的需要讨论的情况都不算多,所以我都尽量将所有的情况画出来,进行测试,由于这些数据都可以手算,所以我并没有和同学对拍。
课程收获
学习OO课程的收获非常的多,首先我自己的编程能力在同学中十分不突出,甚至还很弱。但是通过一学期的OO课程,我认为自己的编程能力和计算思维提升了很多。由于我自己在学习过程中会遇到很多问题,我也经常请教大佬,和他们交流,我也能够收获很多新鲜的,有效的信息和知识。让我印象最深刻的就是第三单元第三次作业,我花了大量的时间来研究tarjan算法和迪杰斯特拉的堆优化算法。在此之前我都没有接触过这两个算法,但是最后我都将他们实现,这让我十分有成就感。
OO课程每周的代码量都不算少,这给我们的码代码能力和debug能力都做出了挺高的要求,一开始我十分不适应,需要比别人多出一两天才能完成任务,好在通过不停地训练和逼迫自己,我在课程的后半段也能够很快的完成每周的任务。
我觉得我不仅在知识和能力层面有提高。当我在面对茫茫的代码和无处下手的bug中,我也锻炼了自己坚强不屈的意志。
建议
以下建议都只是基于本人本学期的学习感受和体会,都是十分真实的,但是不一定有建设性。
1.第一单元作业难度有点大。诚然第一单元这样的求导和鲁棒性检查的要求对于我来说确实有点夸张,我也花了很大的力气来完成第一单元的作业。我也很清楚课程组在第一单元用一个与面向过程有很大交集的作业来帮助我们从面向过程到面向对象的转换。但我个人在第一单元的体验很累。
2.反馈实验结果。每两周的实验其实是巩固课上知识的一个非常好的机会,我也十分珍惜每单元第一次作业我看不懂部分作业要求,没有思路的时候,实验给我的帮助。但是每一次实验都得不到反馈确实让人有些失落,也有些惶恐。因为不知道自己的知识哪里没有掌握完全,或者理解是否有偏差。我认为反馈实验结果是十分有必要的。
3.中测=弱测。这个确实是大家的一个调侃,我也明白中测难度较小可以让更多人获得有效作业,并且进入强测。这也变相的导致了一些两极分化。如果很多人将有效作业作为目标,那么中测太弱就会让他们太过于轻松。而中测太弱,对于想在强测和互测中拿到高分的同学,他们自己的测试和验证就需要做更多的功课(课程组肯定也是这么想的)。但是这样的话同学们的想法和目标就会渐渐偏移,可能有的本来想做一些测试的同学就会觉得这个太麻烦,简单测几下就不管了,这导致强测出问题。我觉得适当增强中测其实是有利于同学课下测试的。因为增强中测就意味着简单的测试是无法得到有效作业的,那么也会激励同学们进行更多的更完整的测试。
线上学习oo课程的体会