一、第一次作业
1、程序设计分析
图1 第一次作业类图
图2 第一次作业度量分析图
第一次作业整体较为简单,主要任务为判断输入的合法性。从度量分析中可以看出来圈复杂度(McCabe Cyclomatic Complexity)比较高,已经标红了。点开仔细看之后发现是Polynomial类的构造方法贡献了主要的复杂度,自己感觉应该是因为这个构造方法是从字符串获取多项式信息,不仅承担了用正则表达式解析字符串的功能,还完成了一大部分对输入合法性的检验,所以复杂度比较高。不过由于程序整体不太复杂,这个飘红的圈复杂度也不怎么感受的到,但在以后更复杂的设计中应当把不同的功能单独封装出来。
2、BUG分析
这次作业我通过了全部的公测,不过非常极限的是一个在计算时的比较致命的bug是在截止前20分钟才发现的。最后提交的时候这个bug并没有完全得到修复,这也导致了我互测时被查出了一个bug。我是为每一个Polynomial实例开了一个100w的数组来维护多项式的系数,这样无论是构造还是运算时逻辑都简化了很多。但是我又很多余的维护了一个最大系数deg属性,以减少一些不必要的运算,但是因为一时疏忽这个属性在运算时没维护好,导致了bug的产生。这个主要还是写完过了一些测试就很懒地没有再查代码导致的错误QAQ
二、第二次作业
1、程序设计分析
图3 第二次作业类图
图4 第二次作业度量分析
这次作业我思考的比较久的点就是如何筛去同质请求,一开始是当某个请求将要执行时往前去找是否有与它效果同质的请求,后来发现这样检查的情况并不完备。于是改为保证队首为合法的需要执行的请求,在每个请求运行完后往后筛去所有它的同质请求。这次的设计其实不太复杂,圈复杂度高主要是因为在main中进行了所有输入合法性的检查,大概也是设计比较简单导致dispatcher类分不到什么活沦为鸡肋(毕竟它只要拿出队首请求扔给电梯跑就行了)。
2、BUG分析
第二次作业公测挂了一个点,互测被找出一个BUG。公测挂的点是没有支持‘+’,这一方面是我没仔细看BUG树,一方面也是助教说的“前导0和‘+’号自行readme”误导了我。个人觉得这种东西留给readme来说意义不大,毕竟对程序设计没有实质性的影响,只是多起了争议。互测被找出的BUG是100条上限的问题,也是我理解错了助教的话吧,“超过100条的情况自行readme”被我理解成了只要出现这种情况所有的请求怎么处理都可以readme,于是我就设计成了超过100条电梯不运行直接结束。总的来说这次的BUG和程序设计还是不太挂钩的 。
三、第三次作业
1、程序设计分析
图5 第三次作业类图
图6 第三次作业度量分析
相比于第二次作业,本次作业需要完成“捎带”的功能,调度算法如何实现是本次的难点。在最开始构想时我把问题想简单了,写到获取捎带队列的时候发现其实十分麻烦。这个时候我面临着推倒重来和继续写下去(可能比较麻烦)两个选择,不过最后因为懒还是硬着头皮写下去了。这也导致最后写完有很多小BUG潜伏在很长的一段代码里,加上深夜debug脑子不清醒,花了很长时间才解决。第二天重新检查了一遍代码,修改了两处bug,就基本上ok了,还是比用数据来debug效率要高一点。
度量分析方面,这次圈复杂度偏高的主要原因我觉得还是因为本身算法设计的问题。在requestList类中用一个主请求从剩余请求队列中选出所有可捎带请求组成捎带队列的scan方法不可避免的有着很高的复杂的,事实上我在debug过程中看这段代码也是十分头疼,可见前期良好的设计还是十分关键的。
2、BUG分析
本次公测和互测都没有bug,个人觉得还是写的比较严谨,大量的测试给了这次的作业巨大的帮助。
四、寻找BUG的策略
在这三次作业的互测中,我拿到的代码写的都比较严谨,前两次各找出了一个基本无关程序设计只是和需求有冲突的bug。第三次的代码写了非常多的类和方法,有一点过度设计的意思,导致我看他的代码的时候十分不好受,不过还是用几组大数据测出了他设计上的BUG。
前三次我找别人bug的流程大概是:测自己的样例=>浏览代码的主逻辑,寻找逻辑上的设计错误=>仔细看具体实现的一些方法,寻找实现上的漏洞。从一些边界极限情况考虑程序的运行情况的时候,往往能找出一些BUG。
五、心得体会
在前三次作业中,我在编写代码之前都会做一个框架的设计,包括要实现哪些类,类中有哪些方法和属性,核心问题的算法如何设计等,发现确实这样在之后的编码过程中会顺畅很多,按照设计捋下来就行。
因此,就想计组的时候高老师教给我们的那样,充分的前期设计是十分重要的。不过虽然前期设计不可能想到每一个细节,还是要尽量多想清楚,或者给程序留够足够的调整空间,不然如果像我第三次作业一样写的过程中发现有问题就会面临一个不太好处理的情况。