当我满怀期待叩开OO的大门,却发现宝藏藏在层层阻难之后


第一次作业

1、度量分析

>关于第一次作业的metrics图分析没有出现标红的McCabe Cyclomatic Complexity或者Nested Block Depth,但笔者在第一次作业后也反思了自己的问题:在解析多项式将其中的数据取出时并没有设计一个很好的方法,而是繁琐的if-else判断和while语句,代码的嵌套现象还是比较严重的。

2、类图

>第一次作业刚刚学习JAVA,对于类与对象的概念还不是特别清晰。所以很容易看到笔者只分了两个类,而且在方法的分配上并没有做的很平均,在ComputePoly类中还是进行的太多的操作导致此类太过于冗杂。但好在第一次设计我便将计算等部分功能放在了Poly类中,也算是分担了一部分的职能。

3、关于BUG

  OO的第一次作业,也是笔者第一次去编写一个完整的JAVA程序。由于要从长期的C语言的怀抱中挣脱出来,所以教程也要求我们在写JAVA面向对象编程的同时写一份C语言的面向过程式代码,在对比中去深入感受和理解面向对象的思想。这次作业是多项式的加减法,总得来说设计难度不大,但需要注意的细节很多。我分别被公测和测试者各找到一个bug,公测的bug是当某指数在多项式曾出现过且在计算过程中系数和为0时,笔者的程序将本不该输出的系数为0项输出了出来。其中的关键就在于笔者将数组中的值初始化为10000,导致在出现这种情况时反而满足了输出的条件,使这种特殊情况发生了错误。但追其根本,仍是程序前后设计不够统一完备,而这种特殊情况的错误就是程序矛盾性最好的体现。而作为被测试者这次互测被测出来的bug则是正则表达式的问题。确实在这次作业当中正则表达式的编写是一块重要而又繁杂的部分,为了避免表达式太过冗长而且防止爆栈,笔者已经将格式匹配的正则表达式用split分为两部分,但还是被测试者找到了一个表达式中符号位置错误而不报错的bug。自以为在测试格式方面作足了准备的笔者没想到自己的正则表达式仍然存在漏洞,不禁感叹自己离真正的严谨还差的很远。
  而作为测试者,第一次笔者拿到的程序公测就Wrong了很多,待我把他所错的公测样例一一看过之后不免为此人感到一丝可惜:基本功能完全没有问题,但细节与特殊情况的处理上稍差一些,于是笔者将测试的重心放到了他的正则表达式与对于特殊情况的处理上。在仔细分析他的正则表达式和一些特殊处理,以及剔除他公测已经错误的bug分支之后,笔者仍然发现了他在正则中并没有卡多项式的个数以及单个多项式中的项数,而且没有对于0多项式的特殊输出0,而且没有处理过的单纯输出{}。这就是第一次作业中笔者与bug的恩怨情仇。


第二次作业

1、度量分析

>不同于第一次作业,当来到傻瓜电梯的时候McCabe Cyclomatic Complexity和Nested Block Depth出现的标红的情况。McCabe Cyclomatic Complexity 表示圈复杂度,由于刚刚开始做项目所以在为各个类分配职能的时候并没有做到很均匀,导致Schedule类中承担的职能太过于多,导致圈复杂度出现了超标的现象。而Nested Block Depth表示嵌套块深度,主要表示了if-else语句等循环嵌套现象的存在情况。而笔者对于输入的处理仍然沿用了第一次作业暴力的判断与解析方法,导致嵌套现象严重。

2、类图

>由于笔者遵循了上课老师PPT以及指导书中的建议,所以这次的类图调用关系还是相当清晰与明确。但同时也能看出来在Scheduler类中并没有去分很多的方法,而把许多不同的操作强行放到了scheduler方法中,导致了上面metrics分析出现的问题。另外一个问题就是程序的复用性还是太多,很多相同的代码没有很好的去进行分类以及封装,这方面的不足我相信也会通过不断的努力去弥补做的更好。

3、关于BUG

  无论是相比于第一次作业情况繁杂还是第三次的捎带电梯,第二次傻瓜电梯的调度问题个人觉的似乎简单了不少。由于只是单纯的一条条执行请求,所以也不存在繁琐的请求关系。当然笔者的第二次作业在公测或互测中也没有被发现bug的存在,同时笔者拿到的代码也是相当完美,没有一点纰漏。由于此代码功能简单也不存在任何问题,故本来准备了虽为数不多但足够完备的测试样例想要在代码的边界情况等方面做些文章,缺被“千山万水总是绿”的AC而折服。


第三次作业

1、度量分析

>由上图可以发现第三次作业的情况和第二次作业的情况几乎完全相同。这是因为笔者的scheduler_ALS大部分是与上一次作业的scheduler一样,并且又加入了对于捎带处理的操作。导致嵌套程度本来就很高的程序显的过于臃肿(时间有限,没有充足改善),而圈复杂度也没有丝毫的降低。又这几次作业的metrics分析可以深刻地告诉我们程序封装以及简洁的重要性,像笔者前几次的代码并没有很好的做到这一点,所以在将来的作业中希望可以有所改进。

2、类图

>第三次的作业根据要求使用继承和接口来更好的控制elevator,其他类并没有实质上的改变,都只是小的修修补补。这次作业虽然在处理同质、输出、toString等方面做了一些封装的尝试,但程序上述的问题仍然存在。但整体思路还是比较清楚的  -_- 。

3、关于BUG

  在经过平淡的傻瓜电梯之后,电梯的捎带问题又掀起了一阵波澜。这次作业投入的时间与精力也是最长的,笔者也给自己做了许多的测试。但反映出一个重要的问题就是由于难度的上升笔者将测试的重点完全放在了测试捎带这个功能上,从bug树中每一种情况,到多个100行的测试完备功能的代码,再到3w,5w的超强测试样例,在一次次修正与补丁以后程序的功能终于完善了。但我却忽略了一个致命的问题,对于不符合规范输入的请求的输出格式错误,而愚蠢的笔者竟然没有去进行测试导致公测的错误,总有种捡了芝麻丢了西瓜的愧疚心理。当然吸取经验,避免遗漏基础与细节也是相当重要的。而且在后来的自我反思中笔者发现了另一个小bug,就是当处理STILL类的请求时判断同质遍历的初始变量是0,也就是从第二个STILL开始程序会将请求本身也当做同质请求。虽然侥幸没有被测试同学找出这个小bug,但笔者的内心还是有点后怕的。-_- 而这次笔者拿到的代码作业与第二次作业一样优秀,笔者完全按照给自己代码测试的方法,从一条条bug树类样例到超长的功能测试代码都没有找到这份作业的错误。打开代码分析其正则以及各类输出的格式方面也一无所获。致此,第三次作业的bug之旅也就到此结束了。


心得体会

1.刚刚步入JAVA和面向对象的世界,虽然也见识过很多dalao对于代码的精致封装,但真要自己在有限的时间内既要完成代码又要有良好的设计着实对于我这只小caiji来说还有点困难。到仍然要去不断进步地去划分每次作业中的类,运用好封装至关重要。
2.我在完成此三次作业的时候就已经想到应该先将整个程序的思路完全想清楚并大致给自己画一张类似于类图的设计思路,尽量细致,清楚。这样会大大减少在之后开始写代码和debug的时间。但我可能做的还不够,尤其是第三次作业,在写完之后bug仍像浪潮一般一波又一波侵袭着我。
3.关于调试与debug,个人认为虽然JAVA中单步调试很方便也很简单,但有时单步调试并不能真正反映一些代码的细节与内涵问题。所以在很多情况下print式debug大法还是很有必要和实用性的。我建议两者要结合起来灵活使用,可能涉及到更加细微的地方使用print更能说明问题。但不管怎样,无论用什么方法,快速而准确地找出bug且明白错因才是最重要的也是最终的目的。
4.关于时间的分配与利用上,笔者有做的好的方面当然也有做的很差的一面。每次周五就已经布置的作业笔者都拖到周一去开始动工,虽然启动晚能够看到更加完善合理的指导书与issue,但整体进度的拖沓还是导致了熬夜的出现。而个人认为比较好的一点是笔者在开始项目的时候去把所有的工作做了详细的时间规划与进度要求。比如思考并画出思路图的时间可以说应该是整个作业过程中最长的,其次是写完程序后的debug和测试的时间,真正完成主要代码的时间很短,而这也正符合了思路清晰完成较快的一贯原则。随着作业难度的不断增大与深入,在今后几次作业笔者吸取熬夜的教训,尽早去动工着手作业。
5.笔者认为前三次作业不但将我们从面向过程式的编程拉到面向对象上,同样教会了我们处理细节问题的重要性。其实在互测过程中无论是笔者本人还是其他很多同学,自身代码功能考虑的很全面,测试也很完整,但在很多格式方面或者指导书中不起眼的小规范上却翻了阴沟。这深刻地警示着我们不能只光顾着代码功能的完善,而是要以更加缜密的思维去应对一切代码中可能出现的问题与情况。而这同时就要做更加完备的计划与测试,每出现一种新情况或边界问题就要加入到自己设计的流程图中,将问题和自己的代码和谐地融为一体,这样才能更好的避免细微错误的出现。
6.Emmm 最后就谈谈互测吧,毕竟有不少人从第一次作业开始就吐槽OO的评测体系,笔者这里仅仅发表一些个人看法。笔者倒认为互测其实是一种很培养大家读代码以及测试能力的。为了写出他人便于阅读的代码,我们不断的在完善自己的编程习惯比如写尽量详细的注释,将代码分装到清晰明了。同时大家也可以从分配到的代码中学习到很多的东西,比如规范的编程风格与更加优化的算法等,相信OO互测本身的意义也体现在这里。所以笔者在这里想告诉大家的是我们能不能将关注点更多的放在双方代码优秀与否和互相学习切磋上面,而不是有一种“尔虞我诈”的既视感。


写在最后

  ~~总而言之,从刚开始对面向对象这个概念都懵懵懂懂,到现在三次作业后的略知一二,经过了几个午夜的洗礼,大家也算是逐渐正式步入了OO的大家庭中。在此感谢在完成过程中帮助过我的同学以及在互测过程中对我程序认真负责的测试同学。希望我们能够正视这门课程的真正意义所在,共同努力共同学习共同进步,借鉴彼此。最后祝大家JAVA越学越6,代码越写越美,OO越肝越牛逼。

始入OO课程的殿堂,初识面向对象的奥妙——OO第一次博客总结的更多相关文章

  1. OO第一次博客作业

    OO第一次博客作业 一.三次作业的bug反省 1.自己发现别人的问题 (1)输入处理的问题,比如第一次作业,主要就是处理输入的字符串,然后有同学的正则表达式有问题,则对于一些错误输入就不能正确判断. ...

  2. oo 第一次博客作业

    oo 第一次博客作业 早在大一就听说了oo的各种传奇故事,大二下学期终于也开始了我的oo之旅. 基于度量来分析自己的程序结构 第一次作业 类图分析 耦合度分析 可以看出在第一次作业中,我的耦合度非常高 ...

  3. OO第一次博客总结

    虽然早在开学之前就已耳闻过OO这门课的威力,也在寒假自学了一些java的语法,但在真正面对OO这样的工程训练时才发现寒假所学的那点语法简直不值一提,也深刻的感受到在这个过程中自己的提升确实很快,毕竟d ...

  4. OO第一次博客作业总结反思

    使用了masteruml插件来生成类图和metrics插件分析代码 第一次作业 1.UML类图 >在第一次作业中,使用了两个类,代码中有没有使用的变量与函数,为平衡两个类的内容,我将输出函数放在 ...

  5. 2019年北航OO第一次博客总结

    一.基于度量对程序结构的分析 1. 第一次作业 1.1 基于类的分析的度量 首先,基于类的属性个数,方法个数,每个方法的规模,每个方法的控制分支数目,类总代码规模等特征对本次作业的结构进行分析. 1. ...

  6. OO第一次博客作业--第一单元总结

    OO第一单元总结 面向对象设计与构造的第一单元,对“面向对象”的概念还根本不理解不熟悉,只觉得需要“分模块”,但不知道怎么分,分多少模块,怎么根据需要的模块的功能建立类.学习的进度又太慢,根本跟不上出 ...

  7. OO第一次博客

    过去的三周里我们完成了表达式求导的程序设计与构造.表达式求导程序,大致思路是实现一个表达式类,支持表达式的输入.求导运算和输出功能.可能的话,还可以增加表达式的化简方法,从而得到更高质量的输出结果.总 ...

  8. [BUAA OO]第一次博客作业

    第一次作业 第一次进行面向对象的编程,不论是针对数据设计类还是对方法进行合适的归于不同类中,都不是很熟悉.所写出来的程序还是面向过程+有函数的类(虽然现在很大程度上感觉起来也是这样).索性作业难度并不 ...

  9. 第一次博客作业(初识C++)

    Q1:学习<C++语言程序设计>课程之前,你知道什么是编程吗?谈谈上这门课之前你对编程的理解,以及你对自己编程能力的评估. A1:开始课程之前,我认为编程是这样的:用计算机的语言写一份流程 ...

随机推荐

  1. Django:settings中关于static静态文件目录的设置

    django项目settings中关于静态资源存放位置的设置 主要涉及以下3项:STATIC_URL.STATICFILES_DIR和STATIC_ROOT 1.STATIC_URL 这项是必须配置的 ...

  2. c# 访问postgressql,使用pghelper访问pgsql

    由于工作需要,数据库是postgressql的,本来以为很简单的,结果弄了一晚上,为了总结经验,现将C#连接PGSQL(postgres sql)的资料整理如下. 一.总体思路 1.通过第三方Npgs ...

  3. maven第一天——入门与基本概念

    一.什么是maven? 1.概述 核心点:项目构建.依赖管理.[更新]:源码关联 (如何关联源码:在依赖的jar上右击 maven download source即可) Maven是一个项目管理和综合 ...

  4. 学习和使用STL

    STL是一个标准规范,它只是为容器.迭代器和泛型算法等组件定义了一整套统一的上层访问接口及各种组件之间搭配运用的一般规则,而没有定义组件底层的具体实现方法. STL主要包括下面这些组件:I/O流,st ...

  5. 【RedHat Linux】 链路聚合

    [链路聚合] RHEL 7运行模式:teamd 守护进程, teamdctlroundrobin 轮询activebackup 热备份, 其中一个位为backuploadbalance 负载均衡lac ...

  6. P3674 小清新人渣的本愿

    P3674 小清新人渣的本愿 一道妙不可言的题啊,,, 一看就知道是个莫队 考虑求答案 1号操作就是个大bitset,动态维护当前的bitset \(S\),把能取哪些值都搞出来,只要\(S\ and ...

  7. Python函数之总结

    ''' 1.什么是函数 函数就是具备某一特定功能的工具 2.为什么用函数 减少重复代码 增强程序的扩展性 增强可读性 3.如何用函数 1.函数的使用原则:先定义后调用(*****) 定义阶段:只检测语 ...

  8. Python 学习 第二篇:数据类型(字符串)

    字符串是一个字符的.有序的.不可变的序列,用于存储基于文本的信息.字符串所包含的字符存在从左至右的位置顺序,不可以在原处(in-place)修改.Python没有C语言的字符和字符串之分,只有字符串. ...

  9. CSS快速入门-定位(position)

    一.概述 CSS 定位 (Positioning) 属性允许你对元素进行定位. 定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的 ...

  10. loadrunner使用过程中的问题记录

    一.录制时选错应用类型,导致提示“loadrunner sockets proxy auto-starter mercury interactive corp.(2002)” 解决办法:重新选择正确的 ...