OO_Unit4_Summary

OO_UNIT4_SUMMARY&&OO课程总结

写在开头的话

一个学期快乐(痛苦)的OO终于结束了,u1s1,OO这么课程是真的很赞,对我的编程能力和工程化写代码的能力有极大的促进作用。

回想起来第一单元最开始写的时候,痛苦不已,每次完成作业都至少需要花上很多时间(一周需要两天时间来完成作业而且都会奋战到一两点),印象最深的就是第一次作业,自己由于没有充分了解面向对象的思想和java,完成作业炒鸡不顺利(到周五晚上才写完,然而一测试发现各种bug问题,最后只能全部推翻重构),当时真的崩溃的想哭,那个晚上我记得我只睡了4h,1点上床,5点又爬起来写,不过后来在仔细看了一篇讨论区的帖子之后,瞬间冷静下来把问题想得很清楚,然后行云流水3h迅速完成了重构,然后一波AC哈哈哈,虽然道路曲折但是还是能见到彩虹滴。后来几个单元,还是逐渐掌握了方法,自己都是认真想清楚问题,设计好架构,再动手,效率提高了不少(一次作业大概只需要一个白天?)。

四个单元下来,自己还是较为”顺利“的完成了所有作业(虽然强测成绩没辣么好康但是忍不住为自己鼓掌哈哈 👏),自己也确实在这门课上真的得到了成长,不仅对面向对象编程的思想有了自己的体会和理解和会去顺着这个思想思考和解决问题(走出了一个main函数走天下的思维),而且新学会了很多新知识比如UML,JML等等,加深了对之前算法的理解也在问题的驱动下阅读博客学到了很多新的算法,同时checkstyle也帮助我纠正了很多坏习惯,hackbug的机制也很新颖,刀人的体验和快感也让我学会了一点点写自动化测试机。

总而言之,如果满分5颗星,我给OO4.9颗星⭐️(少给0.1颗怕你骄傲嘿嘿嘿)

接下来开始回到正文了

 

Part1:Unit4

Unit4需要我们做一个UML的解析器,所以在动手之前需要对Uml有一个全面的了解,也要阅读助教大大们下发的代码,弄清楚每一个类是做什么的,类中的属性对应的是什么。

Hw1

类图

第一次作业针对的是类图的解析。

这次作业难点不大,但是比较整理元素关系特别麻烦,需要增加很多属性来管理数据。首先需要理解uml图中元素与元素的关系,然后将每个元素分门别类放好包括(class,interface等元素),最后储存好之后根据元素之间的关系,将所有元素串起来(找到管理自己的元素,比如attribute找到管理自己的class,class找到自己实现的interface等等,查询的话也没有什么很难的,唯一比较难的查询是类实现的接口,但直接bfs就行了。

还有就是这次作业涉及到的异常包括notfound和duplicate,我是用一个<String,boolean>map来完成的,遍历时把元素的名字put进map,如果第一次put,就将boolean值设为true,如果时第二次甚至第三次,就改成false,查询的时候如果是null了,就抛notfound异常,如果是false,就抛duplicate异常。

然后就是这次作业需要使用到适配器模式,由于助教下发的代码里很多类的方法是private,所以需要一个类来正常使用这些类的方法,所以需要一个适配器类,比如我需要调用某个Class类的方法,管理它就是MyClass类,MyClass唯一的属性就是Class类的一个实例class,然后如果需要调用Class的private方法就直接class.method()即可

Bug

虽然这次作业不难,然而我写查询属性的时候,出现了一个小bug,本来我想的是把只有参数输入、只有返回值的、两者都有的、属性的总数统计好,根据这四个数字就可以算出其他的几个比如有参数无返回值的,但是最后写查询函数的时候将这四个数字的定义弄混了,比如查询有参数输入的属性数目的时候我就只返回了只有参数输入统计的数目(实际上还要加上两者都有的),这个bug让我丢了1/3的分数(呜呜呜)

 

Hw2

类图

第二次作业增加的是对状态图和顺序图的解析。

这次作业的难度很小,可以直接照搬第一次的模式,理清元素之间的关系,然后串起来就好了,而且第一次和第二次作业之间彼此没有交集,所以产生bug的可能大大降低。

但是这里需要注意的是,由于大部分同学都是把类图、顺序图、状态图的元素区别开来储存,但是有些顺序图、状态图的元素它的parentid是类图中的元素(孤儿元素),一般用Hashmap存parentid到元素的映射,就很容易出现空指针异常,所以处理得时候,增加判断一下这个元素是否是孤儿元素即可。

 

Bug

这次作业强测里没有出现bug

 

Hw3

类图

第三次作业增加的是8个有效性的检查

第三次作业难度相比于有了一个提升,因为有效性的检查就包括了对类图、顺序图、状态图的检查,是一个全盘的考虑。这次作业里首先要对wrongrule的有充分的了解,在理解了之后的基础上可以比较顺利的完成几个有效性的查询(rule1,5,6,7,8),但是rule2,3,4还是个刺头需要解决,rule2是不能循环继承(类和接口),rule3是类和接口不能重复继承,rule4是类不能重复实现,然后做法一般就是bfs或者dfs。

但在这里我的做法有点独特,我当时想着bfs和dfs想着脑袋有点晕,我就直接使用了邻接矩阵和可达性矩阵来完成这个题(实现上风险是很大的,这个待会再说),我为class实现了一个类的邻接矩阵C继承关系,为接口实现了邻接矩阵I表示继承关系,为类和接口实现了一个邻接矩阵R表示类实现接口的关系,然后对邻接矩阵进行幂的操作即可得到可达性矩阵,如果在幂的计算过程中发现C^k或者I^k(k为正整数)对角线上有不为0的,那肯定是有循环继承了,而如果在幂的计算过程发现Cij或者Iij不为1,那从i到j就有多条路径,所以就会有重复继承,而如果类的可达性矩阵C',接口的可达性矩阵I',令Z=C'RI',如果zij不为0,则说明从类i到接口j有多条路径,即出现了重复继承。这样的算法简单粗暴,只需要建立好矩阵,完成矩阵的乘法和加法即可。

 

Bug

这次公测没有bug

虽然上述的算法简单粗暴,写程序写的很顺利,但是我后来在室友的提醒下发现自己忽视了复杂度,一般bfs或者dfs就是O(V+E),而我这个矩阵的幂的复杂度可是O(V^3),所以非常容易tle,最后能够通过强测也是九死一生,因为有一个点限制是30s,我的运行结果是29.96s,所以说我上述的做法风险是真的很大(感谢助教大大手下留情)

 

Part2:四次单元的分析

Unit1

架构设计

第一单元,多项式求导。由于之前完成的写代码练习多是解决一个比较具体的问题,最多也就两三百行,而oo这单元作业相当于给了一个很庞大的任务然后细细拆分逐一击破,难度陡增。除此之外,这次作业也完成了我的思维从面向过程到面向对象的转变。

在这个单元里,一次次迭代,多项式的种类逐渐丰富,求导的形式也逐渐丰富。本单元中,前两次作业里,我把多项式建立了一个类,底下管理着项类,项类里分为因数,底数(函数类)和指数,函数类里又有正常的powerfun类,三角函数类,层次化的思想和设计贯彻了这次作业,其中每个函数类根据自己的特性实现了求导接口和tostring接口,在第三次作业里,我建立了一个表达式树,其中节点本身表示加法,减法、乘法,嵌套(括号),左儿子右儿子是运算数,运算数里包含了函数类和指数。

OO方法的理解

第一单元的作业是面向对象的初体验,层次化的设计和类的封装、继承、实现也得到了体现,比如Sin类继承了三角函数类,powerfun实现了求导接口,此外我们还学会了工厂模式,即将一个段字符串传入工厂,工厂完成判断是什么类,解析参数,设置好后然后直接返回一个完善的项。

 

测试

由于对自动化测试一窍不通,当时的测试主要是手动构建一些测试集包括边界测试集来自我测试和hackbug,当时也参考了讨论区的一篇帖子,学习如何手动构造全覆盖的测试集,但是由于构建好之后自己再求导太麻烦了,索性后来使用了室友搭建的自动评测机(其实自己立了搭评测机的flag🎏:,不知道倒了多少次了😓,倒的原因也不是因为懒,是因为当时每次完成作业都差不多周六上午了,与其花时间搭评测机,不如赶紧手动测试),。

 

Unit2

架构设计

第二单元,多线程电梯。本单元出现了面向对象的一大特色,多线程的处理。本单元关键就是多电梯和调度器的协调。在这个单元中,其实主要的基础架构就是生产者消费者模式,所以整体的架构还是的很清楚的,生产者进程处理输入提交请求放入调度器,把调度器当成托盘,多个电梯成为多个消费者。但是还需要考虑的就是作业要求的是可稍带电梯,所以每个消费者即电梯需要一个控制器类,控制器每次从调度器里选择请求的时候会选择自己能够捎带的,其次由于性能分的要求,需要考虑稍带的策略,我这个单元采用的算法是,当电梯没有人的时候从调度器中取得一个请求作为主请求,在完成主请求前允许稍带与这个主请求方向相同的请求。

OO方法理解

本单元对OO的方法理解上便是多维思维的突破,从单线程运行成为多线程运行,多个对象会共同完成某项任务,所以在设计的过程中就会有很多多线程才会有的bug和问题需要注意,比如死锁、轮询等,死锁尤其容易产生,生产者和消费者得同步还好处理,但电梯与电梯得竞争获取请求,一点没注意就会死锁,而且在这个单元第三次作业中涉及到了换乘,所以电梯可能不单单是从托盘中取得请求,还会往托盘中放请求,其消费者的角色特征不再那么明显,如果无法理清楚约束的顺序,死锁更易发生。

测试

多线程的debug和测试其实很迷,常规的debug不再适用,因为多线程的运行结果很难复现,所以我的debug多是通过在函数添加println来实现的,出现了死锁时也是通过添加println定位死锁的位置然后再来思考死锁的原因。然后在测试时,我还是通过手动构造边界和特殊测试集,但是会去使用python随机产生一些常规数据来hack,并且我使用了室友的带有时间戳的输入程序,最后的效也不错,这个单元hack的刀数🔪是三个单元里最多的。

 

Unit3

架构设计

第三单元,JML社交网络。本单元是对JML语言的理解上的进行的,所以整体代码架构上是课程组已经完成了,而我们的任务就是根据给的JML,阅读并理解JML给出得规格然后进行代码的编写,在这个过程中体会规格化的设计。

OO方法的理解

在本单元,我觉得最重要的是对规格的理解,规格是一种沟通使用者和设计者的契约,用户和生产厂家的契约,设计者根据用户给出的JML要求,实现所要求的功能,在实现过程中要充分了解要求并理解透彻,当然实现的方式并不唯一,选择的算法也各不相同,实现所要求的功能的同时保证较高的性能自然更佳更佳,但保证最基础的要求才是底线。当然除此之外,还需要考虑用户不按照所要求的使用方式来使用设计的产品即异常情况,所以还应给出相应异常的处理方式来提示错误使用的用户。

测试

这个单元自己的测试主要还是手动构造数据集,除此之外还用了一下junit进行测试(但是感觉还是有点麻烦,编写测试程序也需要花费一定的时间,还是自动测评机机更香),但是由于个人认为这单元的作业过于简单(实则不然),同学们应该都不会有错误,对于hack bug就没有很重视,只构造了一些较大的数据集hack到了几个超时的。

 

Unit4

架构设计

第四单元,UML解析器。本单元是根据对UML各个元素的理解进行编写的。其最上层结构通过官方接口给出,但是架构还是得自己去实现。而第四单元可以说是前三个单元的总结,首先Uml类图中有第一单元的层次化设计思维,与第二单元相对应的是Uml顺序图,最后则是我们需要参考第三单元,选择好的数据结构和算法来实现所要求的功能。

架构设计则基本是照搬UML中的层次化管理架构,比如class下管着operatioin,attribute,就依葫芦画瓢,写一个myclass管理myoperation,attribute,除此之外就是在myXXX中增加了一些查询所要求的cache数据。

OO方法的理解

本单元是一个OO思维的凝聚和升华成熟。本次的代码,层次化,myXXX类封装UMlXXX类,算法的选择,合适的数据存储的选择,对JML、UML的理解,可谓都包含在其中,都是面向对象思维的一种体现和提高。这次作业需要对UML图有一个充分的了解,了解元素之间的关系,然后再思考合适的架构和算法,最后再动手完成,比最开始的自己上来就敲代码,边敲边思考,思考的更加清楚顺利,完成的也更加熟练,所以自己确实是成长了不少。

测试

这次的测试主要是使用startuml绘制好图之后,使用下发的jar包导出,再进行测试,相对来说由于不同的查询操作有一个明显的界限,所以做到针对每个查询操作的单元测试和覆盖测试也不是太难,但是迫于os复习的压力选择了牺牲oo的测试(逃

 

OO课程的收获

一个学期下来OO真的学到了很多很多很多(重说三),我也非常感谢认真授课的老师和热情负责的助教大大,虽然之前的内容也提到了很多收获,但还是进行一下总结吧。

  1. 首先oo最重要的就是oo思维培养(object oriented),将具有相似数据特征的抽象成类,有共同行为特征的抽象成接口,将一个任务进行内容划分,分成几个步骤或者说几个部分,每一部分任务设计相应的对象来完成,最后整个任务由多个对象共同协作完成。

  2. 代码风格的大大改善,代码风格的严格要求一开始的确很烦,但是对之后的学习和工作很有帮助,我也借此机会改正了自己很多编写程序的坏习惯。

  3. 工程化思维和能力的培养,每次作业每次任务,相对其他的代码课程来说都是一项大工程,如何分析一个大工程,如何将大工程的任务内容分解为子任务,如何根据分解拆分的子任务编写相应的代码,这些工程化分析和设计在oo中都有很大的进步。

    一杯电脑一份指导书,一次作业敲一天,在oo中,长时间的在电脑前完成作业和一单元随随便便上千行的工程量,对我的耐心严谨的思考、长时间的编程能力和(我的头发减少速度)都有提高。

  4. JML,UML,JUNIT,startUML,这些都是学习java语言的利器,学了之后觉得挺有意思,也很有收获

  5. 算法的巩固和新算法的学习,在四个单元中,每个单元都有相应的算法需要掌握和学习,有的是学过的算法得到了温习,而新算法则通过浏览博客学习,这让我的自学能力得到提高,每次学会了一个新算法也觉得很有趣很有成就感

  6. 寻找bug的能力和测试能力的提升,互测环节的加入给oo添加了一些趣味,如何寻找同学的bug像是一个”游戏“,但娱乐其中时也提高了自己hack bug和debug的能力,而如何保证自己的代码没有bug,也需要拥有足够的本地测试。

 

改进建议

  1. 理论课有些无聊,很多内容我觉得可以通过自己的阅读和learning by coding,老师上课的东西有些宽泛有些大,比如JML,JML我觉得不用老师介绍JML是什么,有什么用,意义是什么,是什么完全可以通过阅读一份JML手册来学习定义、语法等,而至于有什么用意Ⅰ是什么,那就learning by coding,敲代码的过程中自然会感受到JML的好处和用处。

  2. 第一单元作业难度过大,作为一名高工6的学生,虽然寒假完成了预习,但是在第一单元感受到了极大的压力,相比于之前上过的数据结构和C语言,陡然提升的工程量和算法的要求是一个很大的挑战,所以希望刚开始的时候助教和老师能够多帮助帮助有困难的同学(我当时第一次作业差点完不成就特别崩溃,非常希望有个人能够教教我帮帮我),度过刚开始的这个困难期,之后的单元就相信会轻松很多了。

  3. 讨论区中助教能够给出一些排雷贴、易错点、易忽视点归纳帮助通过中测,有的时候一个点过了n次还没过,但又不知道哪里错了真挺崩溃的,像第三单元中的作业,由于那几个孤儿元素的 空指针异常,很难想到,确实让人摸不着头脑,那次作业我直到看到了水群里同学的分享才修改了这个bug通过了中测,而这个地方只要指导书中提一句有些UmlAttribute可能不是UML类图里的元素就可以帮助减少很多不必要的debug的时间,也可以挽救很多同学。

 

 

线上学习感受

其实线上学习体验还行,每周一份作业的快乐(压力山大)与每次历尽千难万险的通过中测的成就感交织贯穿了整个学期哈哈哈。

虽然完成代码不受什么线上还是线下的影响,但是有时候作业遇到困难挑战的时候,需要和同学交流合作解决问题还是受到了影响,线上给交流带来了一定的不便,而同学的互帮互助肯定能够帮助更快更有效的完成作业。

而最大的遗憾就是研讨课,本来非常想要听到一些大厂里的大咖们分享他们的工作和生活是什么样的,想要了解他们的学习经验和历程,因为线上都泡了汤,确实很可惜。

 

 

 

posted @ 2020-06-19 16:09  通眉大侠  阅读(120)  评论(0)    收藏  举报