oo第一次作业主要考察了多项式的求导,从简单的幂函数求导到三角函数求导再到嵌套函数的求导,难度循序渐进,对我们对于面向对象的理解的要求也在一次一次提升。一行行代码打下来,一夜夜熬过去,我也来到了这个短暂的停靠站,对自己前三次的作业进行一个简单的回顾。
第一次作业:
测试结果:在强测时被一个同质bug hack到了六个点,直接导致我自己很可惜的没有进入互测,问题在于x和^之间的空格在我写正则表达式进行判断时被遗漏,导致强测大多数点输出的结果都是”WRONG FORMAT!”,我个人对这个评测结果和给分制度并没有任何的异议,因为我觉得这个问题的出现确实是我没有做好本地测试的原因,最基础的错误,往往是也是最严重的,这一点不管是在现在的学习还是以后的工作都会得到体现。
主要问题:感觉第一次作业结果并不好的原因就在于中测通过之后没有进行更严格的测试,不是按照先测试、后写代码的顺序来进行的,没有按照规律构建较为完备的测试集,才导致了这么基础的错误的发生。在第二三次作业中由于我做好了这一点,导致结果明显比第一次要好很多。
过程反思:在第一次作业的时候我个人感觉自己并没有很好的理解“面向对象”这个概念,整个程序就是按照一个main从头到尾地写了下来,还依旧停留在c语言面向过程的思维里,这样写出来的程序不论是鲁棒性、扩展性还是后面对于修复bug而言都是十分不利的,很多时候修复一个bug往往需要对好几个方法进行改动,这一点我在第一次作业的修复过程中深有体会。
第二次作业:
测试结果:强测点全部通过,但是显然我对于对于三角函数的化简并没有做到最好,只是简单地进行了sin(x)^2+cos(x)^2=1这个公式的有关化简,对于大多数三角公式都没有进行处理,最终强测只拿到了98.3分,互测也被找到了三个bug。
主要问题:第二次我觉得我确实相对于第一次有了一定的进步,但是代码架构仍然十分令自己不满意,各种方法的关系错综复杂,没有做好逻辑的梳理,导致自己在检查bug时依然十分头疼,总是在一个类中反复寻找逻辑关系。
过程反思:但是第二次作业我也有了一定的收获,那就是在互测环节中,我自己尝试去利用shell脚本进行了程序的对拍,这样对于bug的查找即高效又省力,我需要做的仅仅就是确保自己写的shell文件没有任何的问题即可。
虽然第二次作业和第一次作业有着许多相似之处,但是我深知我必须对自己的代码进行彻底的重构,不然对于第三次作业的进行将会极为不利。但是第二次作业我对对象的理解仍然不够深刻,我只是简单的将程序分为了main、多项式处理(poly)和单项式处理(mono)这三个类来进行书写,这样我的poly类中仍然有着庞大的代码数目和十分复杂的方法关系,很多完全可以单独拿出来作为一个类的方法,都被我杂糅进了poly这个类中,这是我所犯下的错误。
第三次作业:
测试结果:第三次作业和前两次作业相比难度确实大了很多,就我个人而言,对有关结构的问题和同学进行了近两天的讨论,最后通过两个夜晚的奋斗终于在周二下午成功解决了中测的所有测试点,(虽然后来延时心里确实有些小小的不平衡,但是还是利用这个时间找出了自己的几个bug并进行了略微的优化)。最终强测还是错了一个测试点,并且在互测中被找出了一个bug,不得不说一下在互测的过程中我深刻的感受到了同级大佬的强大,不论是优化的程度,还是代码的架构都十分让人佩服。
过程反思:在这次互测中同班的朋友教会了我使用python脚本进行表达式的求导和计算,这样我就可以利用shell文件对每个人的表达式赋值计算并查看结果,这无疑是一件让人十分有成就感的事,这样我也避免了去检查同组复杂的的输出表达式,而可以直接通过结果来快速判断正确性。
在第三次作业中我觉得我的整体架构比前两次要好得多,清晰得多,我一共分了八个类,并在因子的求导部分利用了继承来进行书写,常数、三角函数、单项式和表达式因子都是因子这个父类的子类,这样写起来逻辑十分的清晰,在debug的过程中也更加容易锁定自己bug所在的位置并快速进行修改,正确度也高了许多。
三次作业代码分析:
在三次作业之后,我利用idea自带的metrics插件对三次作业的代码复杂度进行分析,结果如下:
我个人很惊讶的发现到第三次作业代码长度竟然略小于第二次的作业代码长度,这里我对这个现象进行了一下简单的分析,首先是我第三次作业的优化明显不如第二次做的好,而对于第二次作业来说,结果优化部分大概占据了八十到一百二十行的代码量,这是原因之一,其次是我第三次作业的框架要优于第二次作业,不论是类的划分,还是继承等方面都比第二次好得多,这也就导致少了很多冗余重复的代码。
这三次作业每一次都让我对面向对象这个概念有了进一步的认识,对程序的构架设计的越好,程序的各方面性能也随之变得更好。我利用idea查看了每一次作业的类图,结果如下:
第一次作业:
第二次作业:
第三次作业:
很明显我每一次作业的设计都相对于上次的有了很大的提升,而随着我结构的一次次完善,相应测试的分数也有所提高,修改bug的难度也变得越来越简单,我觉得我在逐渐从过去的面向过程往面向对象不断地前进,这也是我必须从这门课里学习到的最重要的东西之一。
对于bug查找的分析:
其实就我个人的感觉而言,这一次作业bug并不太可能出现在求导的部分,基本上当大家通过了中测的所有样例之后,对因子或者项的求导功能大概率是不存在缺陷的,所以在互测环节时,bug基本都是出现在正则表达式的判断部分,或者是输出的格式问题上,构造一个完备的略微基础的测试集,有时候比很复杂很长但是测试类型同质的测试样例更为有效。
以我自己为例,在第二次作业的互测环节中,我被hack到的样例分别是1*和++++,这些数据都是最简单最基础的测试样例,但是往往我们就会在正则匹配的部分忽略这些情况,其实复杂的测试样例也就只是多个简单样例的综合测试,我们提前做好一个完备的简单样例的测试集,复杂样例的通过只不过是顺其自然的事情。
小小的总结:
虽然通过每一次作业我都能看到自己在某些方面取得了明显的进步,也有了继续努力的动力,但是相比于同级大佬们的代码而言,我的程序各个方面都还存在着极大的优化空间,这将是我未来进一步努力的方向,希望自己的能力可以通过这门课得到极大的提升。