OO期末总结

OO期末总结

一学期的OO结束了,早在大二上就在知乎上看到了关于OO课程的许多评价,但只有像荣文戈老师在开学第一节课说的"只有自己体验了才知道",在经历了一学期的OO课后我发现OO课虽然的确花费了我许多时间,但给我带来的收益也是成正比的,不论是在代码水平上,还是在社交上。

第四单元架构设计

点击链接查看

四个单元中架构设计思维及OO方法理解的演进

第一单元

第一单元的面向对象思维体现得极为明显,由于第一单元采用的是递归下降的办法,因此在递归时对什么元素进行递归,对这种元素的选择本身就是一种面向对象的思维,可以说在一个好的架构可以令递归下降的代码编写更为简单,而递归下降方法也要求了代码需要有好的架构和面向对象的思维。

第一单元的设计思维主要是要弄好项、表达式、因子之间的继承关系,方便递归下降调用,同时判断好什么东西应该作为类(加法、乘法等运算也应该是一个类,表达式、因子等变量数字也应该是一个类)在第一次作业弄清了这一点以后,后面的作业就如鱼得水游刃有余了。

第二单元

第二单元主要是多线程的学习和架构设计,这一单元是使用设计模式最多的一个单元,其中整体架构采用的生产者消费者模式,输入作为生产者,调度器作为中间的生产者和消费者,电梯作为调度器生产者对应的消费者。

设计模式采用了几种,为了便于扩展还采用了观察者模式,方便注册和取消电梯(可惜作业没涉及到),同时采用了双锁的单例模式封装输出安全类,工厂模式创建不同电梯,使用策略模式封装电梯的调度策略,可以说第二单元是我面向对象思维体现得最好的一个单元

同时得益于寒假的预习,我从第二单元第一次作业开始采用的便是ReentrantLock保持线程间的同步互斥,个人感觉ReentrantLock的lock.lock()、lock.unlock()的方法能更好体现临界区的范围,对多线程代码编写更为方便有利

第三单元

第三单元是学习JML语言,由于课程组已经帮我们规划好了架构,只需要根据契约式编程的方式对着给出JML语言进行“完形填空”,因此架构上并没有太多发挥的空间。不过值得注意的是可以通过新建一个工具类将用到的数据结构封装起来,降低耦合度,同时也避免了代码行数的过长。同时可以大量采用HashMap来优化时间复杂度。

这一单元的OO方法也是如同上面所说的,将一些代码用到的数据结构封装成工具类,降低与实现代码之间的耦合度。

第四单元

第四单元是学习UML图,我采用的架构是把UML图中有需要查询的元素建立一个包装类,元素之间的关系作为一个实例对象保存在这些包装类中,实现自顶向下的查询。可以说这一单元和第一单元有点类似,只不过少了UML图输入数据的解析过程,但总体上都是要维护好元素之间的关系,方便操作(第一单元是拆括号、因子与因子之间的运算,第四单元是指令的查询)。

四个单元中测试理解与实践的演进

前言

在大二上的计组中,我在github上找到了19级一个大佬写的评测机,在每次完成课下实验用这个评测机评测,看着满屏幕的AC时有一种难以言说的安心感。在这种安心感的鼓舞下,我也慢慢有了想写评测机帮助他人的冲动,可惜那时候计组已经快结束了,已经来不及写评测机了,于是我把目光放到了下学期的OO课上,下定决心一定要写一次评测机。

一个学期的OO作业下来,事实证明我没有辜负大二上的我对自己的期望,在OO总共十二次作业中,我每次作业均自己独立开发了评测机,不仅帮助我在课下中找到了自己的不少bug,也在互测中找到了许多别人的bug,同时也帮助许多同学在课下找到了自己的bug,帮助他们在互测中找到了别人的bug。

但不得不说编写评测机(数据生成和自动化评测)是一件费时费力的事情,尤其还是在只有我一个人独立开发的情况下,每一周我都要花费整整半天多的时间来进行评测机的编写,编写完成后还需要看生成的数据符不符合规范(de评测机的bug),可以说相当于比别人多做了一份OO作业。听说许多人编写评测机都是几个人通力合作共同完成,其实我很羡慕这种模式和关系,毕竟孤木难支,一个人的时间和力量终究是有限的,难以与多人匹敌,合作开发评测机才是正道,可惜由于我并不认识多少6系和高工的同学,只能孤军奋战,哪怕最后取得了还算比较好的成绩,无论是肉体上还是精神上的疲惫感都是比较重的。在此对自己做个小小的期盼,希望我能在下学期的编译和数据库的课程中能认识更多的同学,一起讨论问题。

第一单元

第一单元我使用了Python来进行数据生成和自动化评测,其中数据使用xeger库编写正则表达式来随机生成符合指导书要求的表达式,自动化评测使用subprocess库,本地开启多个idea后复制路径进行自动化评测,judge部分采用eval代入数值来进行比较

第一单元的测试难点主要在全覆盖的数据生成,对拍的程序比较好写

第一次作业数据生成+自动化评测的代码共计89+139行

第二次作业数据生成+自动化评测的代码共计200+139行

第三次作业数据生成+自动化评测的代码共计256+139行

第二单元

第二单元我使用了Python来进行数据生成和自动化评测。这一单元对CPU时间有着要求,因此评测部分分为正确性评测和CPU时间评测

总体上来说,第二单元的数据生成难度远小于第一单元,但评测机制造难度高于第一单元。第一单元的数据生成需要根据指导书的形式化表述进行递归的数据生成,并且数据需要达到一定强度。而第二单元只需要根据指导书的输入格式随机生成数据,不需要特意制造边界数据就有不错的强度。对于评测机,第一单元只需要利用subprocess调用IDEA就可以了然后代入数值比较结果就可以了,但第二单元需要实现完整的评测逻辑。

数据生成部分其实没啥好说的,就是根据指导书的输入格式,随机生成数据。这部分不难。

正确性评测部分由于多线程调度的不确定性和调度策略的不同,每个人输出是不一样的,因此无法采用简单的对拍来进行评测,需要采用状态机建模的思想对每条输出进行状态转移的判断,这一部分比较麻烦。

CPU时间评测则是使用了助教发的ctypes库获取CPU时间

第五次作业数据生成+正确性评测+CPU轮询评测代码共计39+221+58行

第六次数据生成+正确性评测+CPU轮询评测代码共计145+338+58行

第七次数据生成+正确性评测+CPU轮询评测代码共计227+397+58行

第三单元

第三单元仍然使用Python进行数据生成和自动化评测。

这次的数据生成与前两个单元有些不同,前两个单元主要是根据指导书的输入要求来进行数据生成,而第三单元的数据生成则是对着官方包的源码接口方法的JML一步一步生成,其中不仅需要构造正常的数据,还需要根据JML的public exceptional_behavior进行异常数据的生成。其实写数据生成时就相当于把作业又重新做了一遍。

生成数据的策略是覆盖到每一条指令的正常行为和异常行为,确保在大量数据的轰炸下能全面地根据JML规格触发对应的正常行为和异常行为。

同时沿用第二单元的CPU时间评测查看是否会有TLE的情况

本单元自动化评测采用和第一单元一样的对拍方式

第九数据生成+自动化评测共计225+125行

第十数据生成+自动化评测共计639+127行

第十一次数据生成+自动化评测共计868+134行

第四单元

第三单元仍然使用Python进行数据生成和自动化评测。

我们只需要根据指导书的要求生成UML图元素的子集即可。而不同UML元素的输入格式则可以根据官方输入样例和自己画一些UML图然后使用官方包进行导出查看,然后照猫画虎生成数据即可。

我的数据生成的办法是每一种UML元素对应一个函数进行生成,在生成时需要根据UML图元素之间的关系进行有序的生成,同时在生成时对需要保存的元素之间的关系进行保存。

本单元自动化评测采用和第一单元、第三单元一样的对拍方式

第十三次作业数据生成+自动化评测共计506+136行

第十四次作业数据生成+自动化评测共计956+136行

第十五次作业数据生成+自动化评测共计2223+136行

总结

编写评测机虽然累,但也是一种从出题人的视角看作业的方式,通过编写评测机可以进一步地加深对作业要求以及边界条件的理解,减少了作业出错的可能。

最后附上12次作业评测机的截图,纪念一下一个学期的成果

image-20220626214450302

总结自己的课程收获

1.在checkStyle的帮助下锻炼了代码风格。以前一直听说写代码要有良好的代码风格,自己也一直很想拥有良好的代码风格,感谢OO课程组帮我们写了checkStyle,通过一学期的锻炼,现在我写的代码先不管功能性,起码从总体的观感上来说比之前好了很多。

2.锻炼了代码能力。每周一千多行的代码训练加上独立开发评测机,本学期码量比上学期大大增加,锻炼了打代码的手感和速度。

3.学习到了面向对象的思维和哲学,以及一些设计模式。面向对象的思维我认为是一种代码管理的手段,哪怕不去学,在编写大项目时不断的重构中也会慢慢体会,但OO课程的开设无疑加快了这一进度。

4.培养了细心阅读指导书的能力。每次作业的指导书可谓是“暗藏杀机”,如果理解稍有偏差就会导致代码出错。

5.初步了解了多线程的设计。

6.在完成作业的过程中认识了许多同学,一起交流问题。

7.掌握了针对要求编写测试数据的能力。

课程建议

1.公布每次课上实验的得分,让学生对自己当前的情况有认识,不清楚为啥OO课程组不公布每次课上实验的分数。

2.寒假的pre中增加可选部分,供学有余力的同学进一步学习,可以推荐一些有关设计模式的书籍资料给同学们阅读,俗话说“没吃过猪肉也见过猪跑”,仅仅阅读书籍资料就掌握设计模式不太可能,但事先了解一下什么是设计模式,设计模式能干什么,我认为对OO的学习是很有帮助的。同时将后面单元需要用到的额外知识(递归下降法、多线程设计)在pre中的可选部分提供资料供同学们学习,我认为面向对象需要考察的是面向对象,而不是这些额外的知识,提前学习这些额外的知识可以帮助同学们减轻学期中的压力,完成更有质量的具有OO风格的代码。

3.互测环节可以选择特定几个人来进行hack,hack的冷却时间根据hack的人数来决定,每次hack人数越少冷却时间越短。这样在第二单元可以针对某个人难以复现的bug进行多次hack,也不用担心在hack时不小心把其他人hack了,减少不必要的麻烦

posted @ 2022-06-26 21:54  繁华丶人间  阅读(133)  评论(5编辑  收藏  举报