“啊朋友再见~”—— OO课程总结

OO第四单元暨课程总结

18373513 朱辰啸

目录

  • 第四单元作业架构设计
  • 单元回顾
  • 课程收获
  • 一些建议
  • 线上OO学习体会

一、第四单元作业架构设计

Homework 13

  • 本单元的第一次作业我并没有在架构上进行较多分析和思考,主要的精力放在了对UML模型的理解上。事后想起来,造成这一情况的一大原因就在于我在理论课学习当中的理解并不到位。理论课上只是对UML所要表达的内容以及形式化的图形操作进行了肤浅的理解,至于“树形结构存储”这样的话当时没太听明白,事后也就没多想……所以这次代码虽然效果不太理想,但过程还挺折磨人的。
  • 整体上来说,这次作业的架构很简单,我并没有新创建任何数据存储结构,而是直接在MyUMLInteraction这一个类内部完成了所有操作。同时,由于OS考试和各种大作业的轮番轰炸,我的测试做的也很不到位,至于结果嘛……果然被查出了成吨的bug。
  • 从结果上来看,最终出现的bug问题在于我对题目要求的理解不到位。我以为样例中并不会出现多继承的情况,但我忽略了在Java 8语法中是允许接口多继承的,于是乎最终连中测都没有完全通过……
  • 不过,在修改这次作业的bug的过程中,我也意识到自己的架构查询效率过低,而且这样的情况是完全可以避免的。我当时也思考过直接将UML模型图转化成树形的索引结构,但自己也感觉效果上不会有太大提升,最后还是借鉴了同学在研讨课上分享的思路进行了重构。重构思路基本上就是构造了一个MyClass数据结构,内部管理了该类具有的属性和操作,而在MyUmlInteraction当中管理类和接口之间的各种关系。按理来说接口和方法也应当构造相应的数据结构,管理各自具有的数据,但由于其本身结构比较简单,我就分别在MyUMLInteraction和MyClass当中进行了映射管理。(如下图)

Homework 14

  • 这周正好赶上OS理论考试和航概、马原两门大作业的ddl,我花在OO作业上的时间确实有限。在第十三次作业的架构设计中我也写到了,本次作业我进行了重构,但是重构的代价也是极其惨重的,我花了相当长的时间去重构并修改重构之后的bug,最终导致我没有赶上这次作业的ddl,于是就无效了……所以以下架构设计分析实际上都是我在第十五周完成的。
  • 单从架构上来说,我这次依旧沿袭了上次作业重构之后的做法(如下图):
    • 在状态图中,我构造了MyStateMachine以及MyState两个数据结构,前者和类图中的MyClass相似,用来储存并管理该状态机下的各种状态以及状态迁移,而后者的创建则是为了将UmlState、UmlFinalState和UmlPseudoState都抽象为MyState,进而方便状态机进行管理。
    • 在顺序图中,我构造了MyInteraction数据结构,用来存储和管理其内部的属性和消息等,与类图中的MyClass类相似。
  • 从代码的角度来说,这次作业的难度比上一次作业低了一些,实话说,这次作业最终无效真的是非常可惜了……

Homework 15

  • 在完成OS考试和各种ddl之后,这周我就轻松了很多,有时间扫清前面遗留下来的bug、完成本次作业并进行一定量的测试。
  • 本单元的额第三次作业主要是就模型的有效性进行了检查,从内容上来看并不复杂,但细节上还是需要注意的。整体架构上,由于程序本身的目的就在于模型有效性的检查,并不需要用到各个数据结构本身,所以我也没有单独创建新的数据结构进行存储,而是在顶层直接对各个既有数据结构的id进行了管理。这样的设计一方面可以减少内存空间的开销,另一方面也和程序的最终目的更为契合。
  • 在测试方面,这次作业的测试还是有一定难度的。因为程序本身就是对有效性的检查,所以测试样例应当兼顾到各种无效情况,而且还要排列组合尝试各种多处无效的样例,从而验证发生无效冲突是的情况。由于本人并没有使用自动测试工具,所以最终数据并不全面,也导致了强测出现了两处问题。经过修改,bug的出现并未理解问题,而是程序中的一处笔误所致,实属可惜。

二、单元回顾

Unit 1

  • 第一单元的三次作业是一份迭代完成的求导程序。要求事实上并不简单,最终得到的是一份拥有很好鲁棒性,可以完成求导任务并进行适当化简的完整的代码。
  • 就我个人的体验而言,第一单元的作业真的是当头棒喝,直接给我打懵了。说实话,之前确实没有经历过每周如此大代码量的设计和编写(计组虽然也很肝,但在涉及层面上的要求完全不及OO),而且第一单元的作业大家也都在拼性能分,我确实有点力不从心,也导致我这一单元的最后一次作业几乎完全放弃了化简。
  • 现在回想起来,我当时在完成第一单元作业的时候的确是完全不理解面向对象到底是个什么东西。虽然逐渐从C风格的代码中走了出来,但其实我这个时候仍然不理解类的创建是为了什么,为什么所有面向对象的代码都要封装在类里面。当时我基本上是在一边学习Java的相关语法,一边完成作业的(虽然假期的两个Pre已经联系过一部分常用的Java语法,但事实上和熟练使用Java语言之间的差距还是很大的),所以其实这个单元我本人还是比较被动的。
  • 从成绩上来看,我这个单元的作业还算说得过去,至少功能上满足了设计要求,但性能上还有很大的提升空间。另外,现在再回头看我自己当初的代码的话,就会明显感觉到,我当时对于类的理解还是太过具体,并没有想到组合的方式同样也可以抽象成对象并对其进行操作。理解的局限性一方面会使得我的代码非常复杂,也出现了类之间复杂的循环嵌套,耦合度非常高,另一方面也会限制我在性能方面提升的可能。
  • 在测试方面,我第一单元做的不多,因为本身这个单元的作业功能完成之后出现的bug并不会特别玄学(特别是和第二单元多线程相比),而且如果测试能够想到的点,基本上编写代码的时候也就已经想到了。这一单元自己出的数据并不太多,在强测互测方面被hack到了一些bug,不过主要都是WRONG FORMAT的判断方面。
  • 整体来说的话,我觉得自己第一单元作业的完成还算是合格的,虽然没有领悟到对象这一概念的精髓,但也学到了不少新的内容。

Unit 2

  • 第二单元的主题是多线程,而同步控制和线程安全则是多线程永恒的主题。在作业方面,三次作业迭代式完成了一个可捎带的多电梯调度系统,可以实时响应请求并进行分配。
  • 本单元的作业最开始准备时的任务量确实比较大,并不是说作业本身的要求有多么复杂,但是由于我之前从未接触过多线程的概念(甚至连线程的概念都是刚刚在OS理论课上听到的……),所以自己课下也花了大量时间对多线程的同步控制以及线程安全的问题进行了了解。这样的工作大多是在完成第一次作业的过程中进行的,而后续的主要精力则放在了和死锁的一系列斗争当中。
  • 在架构设计方面,我大体上分别使用过“生产者-消费者模式”、“单例模式”、“Master-Worker模式”,思路上还算清晰,不过这里面“单例模式”的使用似乎不太合适,后来也就弃用了。在性能处理上,我的调度算法设计的比较简单,基本上是基于ALS算法进行了小幅改进之后的结果,不过我的调度更像是一个静态的调度方法而不能动态根据电梯的运行状态进行调度,这也是设计方面的一个缺憾了。
  • 成绩方面,这个单元可能是我整个OO课程完成的最好的了,竟然在强测和互测当中都没有被hack到bug(感动到哭)。看到有很多同学都深受死锁问题的困扰,我的做法由于更多地使用了类自身作为钥匙,并将方法作为原子性操作的单位,虽然有的情况下会牺牲一定的性能,但也会大大降低死锁情况发生的可能。不过,从并发性的角度来看,课程组提倡的用对象作为钥匙同时缩小锁的作用范围的做法则更加“多线程”,只不过这样的方式需要考虑清楚多个钥匙的分发和收回顺序,从而避免程序进入死锁。另一方面,忍不住再次吐槽一下多线程的bug,确实是我见过最为玄学的问题了,我明明知道有bug,却不能复现,又不能断点调试,这确实给我的测试以及调试工作带来了极大的困扰。成绩上,虽然没有出现bug,但由于我对算法的理解不太到位,性能分的起伏就比较大。
  • 从测试的角度来看,实话说,这一单元作业的测试我有点摸不清头脑……因为线程安全的问题随时都有可能发生,但又很可能因为某种原因不会从输出当中很好的体现出来,所以我也不是很清楚应当如何设计有针对性的数据进行测试。因此,我这一单元作业的测试工作更多的是以测试性能作为测试目的,同时如果出现了线程安全的问题,也可以去解决。
  • 整体来说,这一单元的作业我完成的还算顺利,不过在架构方面还是有一定的改进空间,如果能做到根据电梯运行状态动态分配请求,性能上应该会有更大的提升吧。

Unit 3

  • 第三单元的主题是规格的理解和实现,作业方面要求迭代完成一个社交网络系统,可以完成添加成员、建群、查询等操作。
  • 刚拿到这个单元的作业的时候,我其实挺不理解的,我当时觉得这不就按照规格的要求一行一行写完了就行了嘛。于是呢,我就真这么干了,花了三个小时照着JML规格写完,出了几组数据再用Junit测试一下就交了,至于结果嘛,当然是直接裂开(暴风哭泣.jpg)……
  • 当我拿到成绩的时候,基本上就是石化的状态,之前基本上完全没有考虑过性能上的问题,而且我之前对JML的理解有比较大的问题,我以为规格是非常严格的要求,就连数据存储方式也要以此为准……所以就连我看到第一次作业的结果之后,仍然没有意识到问题的关键所在,于是第二次作业也裂开了……在第三次作业当中,我就Tarjan等算法进行了检索,同时也使用了并查集的存储方式,结果还算差强人意。
  • 在架构设计方面,这一单元的作业的框架较为简单,所以我也没有进行过多设计,只是在第三次作业加入了并查集这一数据结构。不过,在这一单元总结的过程中,我也意识到了存储方式对性能同样也有着不可忽视的作用(然而到了第四单元,我似乎又失忆了……)。
  • 在测试方面,应课程组的要求,这个单元主要用到了Junit,我也尝试了JunitNG,但这个东西的版本实在是过于古董了,很多JML规格的语法都不能兼容,虽然是听上去很好用的自动化评测工具,但使用起来真的是有很大限制……
  • 整体来说,这一单元大概是我完成的最差的一个单元了。后知后觉的我确实是在这单元吃尽了哑巴亏,不过相应的,收获也是相当大的,在性能方面,除了算法上的改进,数据存储方式同样也是一个很好的切入点。现在回想起来,我对面向对象思想的理解似乎也是从这个时候才真正开始的(说起来真的是晚有点晚……)

Unit 4

  • 第四单元的主题是对UML模型的理解,也是我认为的OO这门课最为精髓的一单元,在这个单元的学习中,我才最为真切的感受到了OO的思想。
  • 鉴于架构分析、成绩、测试方法等内容我在第一部分当中已经提及,此处就不再赘述了。
  • 目前,我对于面向对象的理解(准确的说,是对“对象”的理解)就是抽象和封装。类一方面可以是一个数据结构,单独管理其内部的数据并可以提供相应的构造、修改、查询方法;另一方面,类也可以是对一系列数据结构的抽象,本质上来说仍旧是一个数据结构,但是可以具有更高的抽象层次,比如说我在解析状态图时创建的MyState类,在状态图当中并不存在,但却是对UmlState、UmlFinalState和UmlPseudoState的抽象,从而便于统一管理。
  • 虽然因为各种连环夺命ddl的相继而至,我这一单元的作业完成的也不算理想,但这一单元却帮助我完成了对这门课程的理解,也算是值得了。

三、课程收获

  • 现在,OO课程终于结束了,从情感上,我是真的想说一句“再也不见”,但一方面确实从这门课程的暴虐过程中学到了许多,另一方面也知道大概很难再也不见,所以还是好好做个总结以便日后更深入的理解吧。
  • 其实上面所谓的对OO的理解也只是我目前的感受,以后可能还会有更加深入的理解。现在回想起寒假的时候,当时我对类的感觉就是一种可以提供操作的更为复杂的“结构体”(没错,就是C语言里那个玩意儿),所以我当时特别不理解为什么代码的所有内容都要写在类的内部。现在看起来,当时的想法确实是比较肤浅了。单从结构上来说,现在的我觉得类本身就像是一个黑箱,只提供了几个外部可见的接口(就是可见性为public的方法和属性),这个黑箱本身有自己的功能和不同的含义,可能是某个最基本的用于存储和管理数据的数据结构,也可能有着更高的抽象层级,而整个程序当中的许多黑箱由构成了一个网络,一个可以启动、可以接受输入、可以输出的程序。而对于顶层类来说(MainClass这种),一般只会提供一个“启动程序”的接口,而后则可以通过输入类接受不同方式的输入,最终通过一系列的结构调用和操作,得到我们希望得到的输出。在上述过程中,每个不同主题的操作都应当对应一个不同的类,这些类有可能会用到更为底层的用于直接管理数据的类,而这其中的每个层级也都可以作为所谓的“对象”进行操作。整体来说,我现在认为面向对象的核心应当是抽象和封装,也就是把数据进行合理封装,然后逐层进行抽象,作为“对象”。
  • 这门课给我的整体感觉首先就是肝……每周周二开始,完成作业只是开始,后面还需要进行自主测试、参与互测(期间提心吊胆)、修改强测bug。早在进入6系的时候就听说了OO的恐怖,但知道亲身经历过才知道原来一门课真的可以这么肝。不过付出这么许多,收获却是也是巨大的,最基本的,我可以使用Java完成一些基本的操作,对多线程、形式化规格、“对象”的概念有了基本的认识和理解,在测试方面有了更深的理解以及更加全面的方法。当然,学的内容越多,我也越发了解到了自己的渺小,别的不说,即使是Java这门语言,我现在的程度距离“精通”还有很长很长一段路需要走,这其间的差距不只是语言层面的,思想和理解方面同样也需要付出很多努力。至于其他方面,比如多线程、形式化规格的理解我觉得自己可能也就是刚刚入门,日后如果真的需要早工作中加以使用,恐怕还需要进行大量的学习。

四、一些建议

  • OO课程结束了,关于课程本身,我确实也有一些体会,以下提出自己的几个想法,仅供参考吧。
  1. 希望在每个单元前能够对这个单元的内容进行一些预告,比如说第二单元的多线程,在一周之内进行理解确实比较困难,但如果能提前一周进行预告,下发一些参考材料,应该就会好的多了。另外,比如第三单元JML的内容,也希望课程组能够提前对测试过程中的侧重点进行一定的预告,至少能够早一些提倡大家在存储结构方面进行思考,这样或许能够降低大家在看到自己强测成绩时的惊讶程度(实话说,当我看到自己第三单元第一次作业没有进入互测的时候,我还以为系统出bug了……)。
  2. 希望可以适当调整实验的内容和难度,不过这一点不知道是不是和本学期在家线上上课时间相对宽裕而且可以查阅资料有关。个人感觉本学期的部分OO实验的内容其实是可以用一些博客文章进行替代的,特别是一些概念性比较强的内容(比如最后一次实验)。我也不是说实验的难度过于简单,只是感觉有时候似乎实验并没有起到足够的作用,似乎一些技术博客也足以让大家进行了解……(仅个人看法)
  3. 这一条并不是对这学期课程的建议,相反,是希望沿袭的一些内容。这学期由于疫情原因居家上课,课程主要是录播的形式,虽然互动性差了一些,但由于可以反复观看,对知识的理解其实是有一定帮助的,希望日后也可以考虑留一些材料(音频也可以)以便大家课后进行复习和理解。

五、关于线上OO学习

  • 之前看到了吴际老师关于线上教学的那篇博客,我深以为然,虽然线上教学对计算机专业的一些课程在客观上影响不是很大,甚至给大家提供了更大的自由度,但我也认为线下教学仍旧有着不可忽视的优势。别的不说,上了一学期的课,我竟然连老师都没见过,啊这……
  • 个人认为,线下教学的最大优势就在于老师和同学之间的互动性,同学可以及时提出自己的问题,老师也可以更方便的得到反馈,线上教学虽然也有微信群作为辅助,但从效果上来看还是有不小的差距的。而且客观的来说,在家里我自己的学习状态明显不及在校期间……
  • 不过,线上教学也有可取之处,比如上文中提到的录播课的优势,不过可以想象,老师们为了录好这一次次课,肯定比线下上课要麻烦多了(老师们这学期真的辛苦了!)。从知识掌握的角度来看,本学期的效果确实不一定会比在校期间的效果差,只是这样的形式还是不太适应(毕竟一夜之间都成了函授大学生了……)。
  • 最后,感谢课程组的所有老师,也感谢所有一直为我们答疑解惑、提供各种帮助的助教们!这门课程能够成为计算机学院的招牌课程,确实名不虚传!

猜你喜欢

转载自www.cnblogs.com/ZCX2020-blog/p/13160557.html
今日推荐