Part 0: 前言

令人闻风丧胆的OO还是来了。并没有像名字的外表一样可爱,简直就是恶魔。

疯狂压榨OS的时间,周末无法休息,互测狼人机制

虽然网上骂声很多,就算改进到9012年还是有很多不足的地方,但和往年相比,已经有很大进步,也更加人性化了,我们并不能力求在我们这一届做到完美,这毕竟是一个长期长期长期长期又漫长的过程。既来之,则安之,既然无法改变规则,就让自己适应规则吧。

Part 1: 量度分析

接下来将细分开每一个板块来对我自己的三次作业来进行分析

DesigniteJava

DesigniteJava是一款专门分析代码质量的静态评估工具,并且识别潜在的质量问题。它会检查代码的架构,设计和代码的异味并且以csv的格式给出详细的度量分析。

对与分析Java这种面对对象的语言,我们这次主要看这几个参数:

  1. CC 圈复杂度

    用来衡量一个模块判定结构的复杂程度,圈复杂度越大说明程序代码质量低,难以测试和维护

  2. LCOM 方法的内聚缺乏度 值越大说明类内聚合越小

  3. FANIN 类的扇入 扇入表示调用该模块的上级模块的个数,扇入越大,表示该模块的复用性好。

  4. FANOUT 类的扇出 扇出表示该模块的直接调用的下级模块的个数,扇出大表明模块内复杂度高,但扇出过小也不好。

    总结就是,一个好的JAVA代码,设计要求是高内聚低耦合的,所以LCOM值要小,FANIN的值要大,FANOUT值合理。

    那么用这个方法看三次的度量结果:

    第一次作业:

    第二次作业:

    第三次作业:

可以发现,在Main函数中我们的圈复杂度都是相对较高的,这是因为我在Main中放了存放和预处理字符串的代码,这导致圈复杂度增高,而且确实大量的正则表达式和字符串替换难以后续阅读和维护,这是毋庸置疑的。看了其他同学的优秀代码,比如17373331的代码,Main中几乎没有什么实际的执行代码,只是在调用其他方法和处理异常,看优秀的代码给我的感觉就是非常清晰,在主函数中就明确告诉我了这个project是在什么的,合理的类的命名,简单易懂的返回值设定和处理异常的语句,符合OOP的设计。

果然,没有对比就没有伤害:17373331的静态分析:

    明显可以看出参数饱满了很多,不像我生成的几乎都是0,较小的LCOM和较大的FANIN和合理的FANOUT,果然花花的代码能被称作标杆范文。
 
此外,可以看到我的代码分析后的FANIN是几乎没有的,说明我的代码的复用效率低下,可能存在很多重复的代码,反观我的代码确实在这几次作业中,确实有很多服用的代码,就比如字符串为了防止被查WF,反复用正则表达式检查变换几次,甚至用上了 while (matcher.find())这样的循环查找,不仅复用率低下,其实代码的执行效率也非常低下。

  反思自己的代码质量,几乎惨不忍睹,甚至感觉用来查c等面对过程的语言得到的结果也相差无几,主要是以下几点原因:
  1. 阅读面对对象的代码太少,学习了理论但是无法自己亲手时间,可能具备了阅读不同的代码说出是不是符合面对对象的设计,但是自己却无法写出。

  2. 对质量的盲目追求。在分数的利益驱动下,自然地用面对过程的语言,也就是自己熟悉的语言来处理字符串,这样虽然代码不是很好看,甚至在第三次作业中为了判断各种WF情况而写了冗杂的正则表达式查询代码,导致主函数内方法函数超60行,代码风格质量严重降低,这时又只能通过分开建立不同的方法来分担正则式的长度,恶性循环导致风格逐渐下降,但是分数可以很好,别人几乎不能攻击我的WF,这也是对自己的代码风格和分数之间的trade-off之间,分数占了上风吧。

  3. 还没有形成剥离抽象层的思维,像zsa学长在讨论区的接口讲解非常清晰,举出了生动的例子——手机的充电接口来让我们理解。 但是总是在自己构思的时候就无法剥离出sin cos 和x 和constant 之间的共性特征和共性方法,所以也很少使用继承或者借口了,在最后一次的作业中强制要求使用后才尝试用接口的方法来解决求导的问题。

接下来查看自己的UML图,由idea自动生成:

第二次作业UML   



第三次作业UML 

第一次作业似乎无法生成UML,可能是因为太面向过程了一点,但我还可以看到第二次和第三次的,但是要我评价自己的类图,我十分羞愧,因为这完全是一个没有上过OO理论课的人都能写出来的东西,所以我大概讲一下我的类图在写代码时的构造吧:

在第二次的代码中我才用了四元数的方式,所以自己构建了两个class,分别是Trig 三元组储存x 和 sin 和 cos,还有Term 四元数在三元数的基础上增加了前面的常数项,由这两个class我们就可以对相同的相进行合并。并且尝试了多态的方法;在第三次的代码中采用了接口的方式,对所有项的求导进行了归一化,但是其实可以更加优化,那就是将所有的项归并到抽象类中,因为他们都有共同的属性比如内部的表达式(指sin和cos内部的值)还有幂次都是共通的,用抽象类的方法可以将他们更加内聚在一起,所以我也打算重新写一遍第三次的代码了,当然是建立在阅读第二次优秀的代码基础之上。

在第三次作业中,我也对static和final有了更进一步的了解。之前看到java的代码中很多的static所以没有融入自己的思考盲目static,这直接导致我第二次作业开始,开的类多了之后出现致命的错误,创建多个对象之后共同修改一个属性,导致了大片的错误输出,所以说还是实践出真知。

Part 2: bug分析

第一次作业:

第一次作业比较简单,当然自己用面对过程的语言做所以没有出什么问题,最后是数据点全过+0hacked,但是当然还有美中不足的地方,那就是性能分没有拿到满分,具体在于自己运用HashMap的方式存储结果,查询不到HashMap如何查找到特定value的值,即正数的值放到第一位,所以最后性能分未满,但是如果现在要我再交的话,我会利用先存进ArrayList的形式来做一个简单的排序,从而将正项第一个输出。

第二次作业:

第二次作业在强测中出了一个BUG,导致被分配到了C组中去,因为自己优化太过于匆忙,疏忽了HashMap在puts之前要先检查是否存在,导致相同的Key值出现了覆盖Value的情况,最后失分。其实自己写了一个专门puts进HashMap的方法,在方法中检查了Key值并进行合并,但是由于是ddl前的早上优化所以没有进行太多的测试,过了弱测和中测就没有多想,这个案例说明 侥幸心理 是万万不可取的。

在互测屋中还被发现了一个特殊的bug,在输入以运算符结尾的时候我不能判断出格式错误,导致被人狂刀,这也是和自己的测试策略有关,自己在自测的过程中偏向于对正确性进行检验,而忽略了错误形式的表达式的构建,导致失分。

第三次作业:

吸取了第二次作业被WF杀害的经验教训之后,几乎最后一天都在对格式判断进行改动,但是没有注意到助教的置顶帖中已经说明移除了WF的数据,有一点时间没有用到刀刃上的感觉,甚至有点把自己给误伤了。过多的特殊WF情况的判断导致自己对代码的结构已经无法理解,结果在强测中对正确的输入报了WF,痛失去一个强测点。此外,对括号内的处理也不够仔细,忽略了幂次也能带有负号的问题,导致表达式提取出现问题,结果丢分。

在第一单元最后一次的研讨课上,有位同学给予了我们一个开始工程的思路——先构建数据集(测试集),再下手打代码,起到打代码的时候有的放矢的高效。开始的时候我是有点不理解的,但是在反思自己的作业的过程中,发现第三次作业中我所犯下的错误完全是可以由一开始构建一个较为完备的测试集而规避的,而且纪老师说在后续的工程化代码中,提前构造测试集是一种非常有效防止严重漏洞的手段,所以我也考虑在重写第三次作业的时候也尝试这种方式。

Part 3: hack

对于查找别人的漏洞的方式,主要在于以下几点:

  1. 自己在打代码的时候,测试自己的代码时所出错的数据点都一一保留,这应该是算弱测。

  2. 寻找特殊的表达式的特征,具体可能是x-x或者多个+-号的形式。

  3. py或者java自动生成代码加上mma的带入测试。

  4. 寻找同学进行求助,每个人对同一问题的思考角度不同,hack别人的点一般有很大区别,所以是一个补全的很好的策略。

Part 4:重构的说明

重构其实不是一件丢人的事情,自从上学期计组以来,发现其实解决自己bug的最好最快的方式就是重构。重构可以帮助我们在原有的基础上进行改善,一方面验证我们对现有知识体系的更加深层的理解是否正确,另一方面也是对未来增添功能时候提供一种方便。在初学的阶段,我认为重构代码时非常常见的,也是一种高效的学习方式,虽然时间会花费很多,所以在第二次作业中我就采取了重构的方式,改掉了原有的面向过程的写法,采用了初级入门的面向对象,并且在第三次作业中也复用了第二次作业的体系逻辑,虽然增添删改了许多内容但其实也减轻了我挺大的工作量的。

以上便是本人对于前三次OO作业的博客总结,后续可能会贴上自己第二次作业甚至第三次作业的优化的方法的思考。

Object-Oriented Programming Summary Ⅰ的更多相关文章

  1. Object Oriented Programming python

    Object Oriented Programming python new concepts of the object oriented programming : class encapsula ...

  2. JavaScript: Constructor and Object Oriented Programming

    Constructor :  Grammar: object.constructor Example: Javascript code: 1 function obj1() { this.number ...

  3. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性

    一千个读者,一千个哈姆雷特.对于面对对象编程,书上都会告诉我们它有三个基本特性,封装,继承,多态,但谈起对这三点的见解,又是仁者见仁智者见智,感觉还是得多去编程中体验把 . 面向对象编程(OOP, O ...

  4. Python 面向導向語言 Object Oriented Programming Language

    Pytho 是面向對象的程式語言,舉凡 Literals 值都是 Object.例如: >>> id(38)8791423739696 與 >>> id('ABC' ...

  5. leetcode@ [355] Design Twitter (Object Oriented Programming)

    https://leetcode.com/problems/design-twitter/ Design a simplified version of Twitter where users can ...

  6. opp(Object Oriented Programming)

    嗯,昨天忙了一天没来及发,过年啊,打扫啊,什么搽窗户啊,拖地啊,整理柜子啊,什么乱七八糟的都有,就是一个字,忙. 好了,废话也不多说,把自己学到的放上来吧.嗯,说什么好呢,就说原型链啊 原型对象 每个 ...

  7. oop(Object Oriented Programming)

    嗯,昨天忙了一天没来及发,过年啊,打扫啊,什么搽窗户啊,拖地啊,整理柜子啊,什么乱七八糟的都有,就是一个字,忙. 好了,废话也不多说,把自己学到的放上来吧.嗯,说什么好呢,就说原型链啊 原型对象 每个 ...

  8. Week 5: Object Oriented Programming 9. Classes and Inheritance Exercise: int set

    class intSet(object): """An intSet is a set of integers The value is represented by a ...

  9. python, 面向对象编程Object Oriented Programming(OOP)

    把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数 ...

  10. JS面向对象程序设计(OOP:Object Oriented Programming)

    你是如何理解编程语言中的面向对象的? 我们研究JS和使用JS编程本身就是基于面向对象的思想来开发的,JS中的一切内容都可以统称为要研究的“对象”,我们按照功能特点把所有内容划分成“几个大类,还可以基于 ...

随机推荐

  1. day30-client上传比较大的数据给server

    #在网络上面传输的数据叫数据包,数据包里面的数据叫报文,报文都有报头. #报头可以包含文件路径.文件大小.文件名称等等.#当数据比较长,一次性发送会报错,需要分多次发送.#client端上传数据到se ...

  2. Events|sample space|mutually exclusive events

    5.2Events The collection of all 52 cards—the possible outcomes—is called the sample space for this e ...

  3. iOS高仿微信悬浮窗、忍者小猪游戏、音乐播放器、支付宝、今日头条布局滚动效果等源码

    iOS精选源码 iOS WKWebView的使用源码 模仿apple music 小播放器的交互实现 高仿微信的悬浮小窗口 iOS仿支付宝首页效果 [swift]仿微信悬浮窗 类似于今日头条,网易新闻 ...

  4. 多版本firefox共存

    https://blog.csdn.net/gavinxlf/article/details/53173034 https://blog.csdn.net/weixin_33979745/articl ...

  5. Jsp入门EL表达式_学习笔记

    1.EL表达式 [1] 简介 > JSP表达式 <%= %> 用于向页面中输出一个对象. > 到JSP2.0时,在我们的页面中不允许出现 JSP表达式和 脚本片段. > ...

  6. LeetCode Day 3

    LeetCode0003 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 & ...

  7. Nginx的四层和七层代理

    理论部分: 所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器,它一般走的是tcp,udp协议    所谓七层负载均衡,也称为“内 ...

  8. 不疯“模”不成活,海尔阿里II代电视将极致进行到底

    我去过很多现场,经历过很多新品发布,各种概念,各种颠覆,有点见怪不怪.这次受邀海尔阿里II代电视发布会,本也是带着一颗平常心. 2点30分发布会准时开场,当 "智慧模块"在讲解员手 ...

  9. ES6的模块暴露与模块引入

    ES6的模块暴露和引入可以让我们实现模块化编程,以下列出ES6的几种模块暴露与引入的方式与区别. 1.ES6一共有三种模块暴露方法 多行暴露 模块1:module1.js //多行暴露 export ...

  10. vue子组件使用自定义事件向父组件传递数据

    使用v-on绑定自定义事件可以让子组件向父组件传递数据,用到了this.$emit(‘自定义的事件名称’,传递给父组件的数据) <!DOCTYPE html> <html lang= ...