OO第一阶段纪实



$ 0 写在前面
  在DDL一次次的推动下,历经三个周期的更迭,一个月的时光匆匆而过。谨撰此博文,以记录这一段见证成长的心路历程。



$ 0-0 JAVA“一天速成”
没有修习过传说中的“OO先导课”,在学期开始之前也从未接触过JAVA编程,真正的从零开始学JAVA。有了先前课程的基础,经过了一年的积累,在短时间内学会使用一门语言并不困难,在加上JAVA天然的与C语言之间的某种相似性,也使得“JAVA一天速成”并非遥不可及。

$ 0-1 “过程式”VS“对象式”
但值得注意的是,JAVA作为一种面向对象的开发语言,其本质上与C语言有着重大差异,只不过在第一次作业的时候,由于对JAVA的一无所知,就也只能按照头脑中既定的那种根深蒂固的过程式程序模式来编写。而作业要求“注意体会过程式和面向对象式程序的区别”也成为了一直困扰我的难题。

$ 0-2 棘手的需求
在第二次作业中,由于有了第一次作业和实验课的经验,我也阅读了更多身边同学所编写的代码,使我对面向对象的概念有了进一步的了解。同时由于作业项目引入了一个具体的应用背景,也使我对“类”的定义和使用更加得心应手。不过新的难点总是会不断涌现,这一次我所面临的新难题便是—指导书。可以说指导书就是一种用户需求,相比于在未来工作中可能遇到的需求而言,指导书可以说是将规定做到尽量细致了。但是大量的内容同时涌现,个别定义的模糊不清,成为了对我的新的考验。

$ 0-3 惨痛的教训
紧接着第三个工作周期,也就是刚刚结束的那项任务对我而言是一次惨痛的教训。由于第三次作业的内容继承自上次作业,同时对上次作业的内容有了更进一步的需求,这就考验了我们所设计的代码的可扩展性。另外捎带请求、同质请求独特的判定方式相互交织,也为调度方法的设计与实现增添了不小的难度。能否做好与上次作业的衔接、能否架构好顶层设计便成为了这次作业的主题。



$ 1 第一次作业



$ 1-0 从I/O开始
万事开头难,一个程序往往是要以一组输入作为起始,由于一上手还不了解“对象”的概念与使用,java的一组用于控制输入的语句在我看来显得“玄妙异常”。

import java.util.Scanner;
Scanner input = new Scanner(System.in);
if(input.hasNextLine()) {
text = input.nextLine();
}
input.close();

这里的input为实例化的一个java内置Scanner类里的对象,System.in作为Scanner构造方法的参数被传递进去,hasNextLine()和nextLine()都是Scanner类里的方法。最后的close()方法的调用也是编译器的一种建议,不写该方法会收到一条警告信息。

注意在读入一行前,一定要先判断是否存在下一行,从而避免直接落入Exception的处理之中。同时也尽量在读入阶段末尾调用close()方法,以免出现未知错误。
下面列出一些常用的Scanner类中的方法,便于日后使用时查阅。

(图片来源于网络资料)

$ 1-1 正则!正则!
在上一学期的《计算机组成原理》Project 0中我们了解到,正则表达式是一种有效的字符串匹配机制,其本质就是基于FSM实现。因而这里我也尝试了一下在java中用简洁的正则式来取代原来书写FSM所采用的繁琐的状态转移。
正则式的表达虽然简洁,但随之而来的问题也着实为我带来不小的困扰—爆栈。
由于本次作业的输入是有一定规模的,总共输入项数的上限多达50*20。对于这种规模的输入,如果不加以拆分,直接进行整体正则匹配将无法通过压力测试(实验证实)。
由此我便得到启示:在待匹配的字符串规模较大时,可以采用以下语句,来实现对字符串的拆分:

// while(m.find())
//    m.group(0)

其中find()方法用于判定找到了带匹配的字符串,group()方法则可以用于截取出匹配到的字符串。
至此,正则式的两大用途都很清晰了:一是可以用于格式检查,二是用于从原字符串中截取符合规格的标准段。那么如何综合应用这两种功能,去解决对大规模输入的匹配呢?
我在第一次作业中就应用了分段匹配的办法,每次只匹配一个多项式的长度,并将匹配好的部分存入一个String中,逐次累加,最后比对存储的串是否和原串相同,即可完成匹配。
还有几点值得说明的是,在正则式中尽量应用^$来标记待匹配字符串的首尾,用非捕获性的(?:)来代替捕获性的()匹配。这两处细节可以优化我们的正则处理过程。

$ 1-2 防御与攻击

第一次在互测阶段被发现了一处bug,这处bug出现的原因在于我对“-0”以及“前导0”的理解不够全面。仅考虑了形如“-0”的情况,却忽略了“-0”也可能存在前导零。这就在被测试阶段,给测试者留下了可攻击的漏洞。

在进行测试时,我所遵循的逻辑也是由表及里的策略:即通读指导书、略读I/O、检查异常处理、深入理解代码逻辑几个步骤。
拿到的第一份代码的漏洞出现在缺乏try-catch(关于try-catch的重要性将在下节叙述)。在这个基础上,在合理范围内使程序crash的几率就大大增加。紧接着我发现,作者运用了大量的定长数组代替长度可变的数组,而且在Input阶段的正则匹配也采用了十分开放的贪婪匹配策略,这就为程序引入了潜在威胁。
因此,通过构造一组恰好数组越界的小型数据输入用例便crash掉了这个程序。

$ 1-3 try everything && catch me if I fall

任何情况下程序都不应crash。
这一要求一点都不过分,对程序鲁棒性的追求没有极限。让自己的程序在高强度的测试下保持稳定性,是每位设计者必须要致力于的目标。
因此,永远不要忘记try和catch!
此外,结合后续作业中的经验,try语句块不仅应出现在最顶层,在输入阶段、类型转换阶段、访问定长数组阶段等“危险”时期,最好都应用try-catch结构,而且为了忽略掉异常情况使程序继续正常运转下去,在内部的try-catch结构可以不用exit(0)。

$ 1-4 代码度量分析



$ 2 第二、第三次作业



$ 2-0 “面向对象”的进一步理解
这一次作业由于有了具体的应用场景,在加上设计建议,让我有机会进一步理解了“面向对象”的概念。
为了便于我自己的理解,我认为我们在JAVA中定义的class视作和C中定义的struct类似,都是一类封装好的属性的集合,但class在struct的基础上还能在其中定义方法。尽管这种理解并不准确,但确实在我编程的过程中给我了一些提示。
“对象”则是我们实例化的一个具体的编程实体,实例一个对象的好处是其中的数据易于维护。这就和我之前在编程时喜欢用的全局变量截然不同,对象内部的数据易于保护,对外界不可直接访问与修改,这就大大降低了由数据共享所引入的风险。

$ 2-1 多变的需求与应对策略
第二、第三次的指导书内容庞大,issue的讨论区也有很大的信息量。如何整理出其中的逻辑,从何处下手是工作的重点。和测试同学交流过后,我也很认同他所提到的前期设计。而我也不得不承认,由于设计工作不够充分,导致了很多的细节考虑不够周到,也为我后来的debug工作造成了重大的影响。
一种值得借鉴的好习惯是,把指导书和issue中提及的关键点提取出来,记录到文档中,便于设计时查看;采取显式的设计模式,将设计流程完整的呈现出来,对自己的设计也是一个提示作用;测试驱动开发,测试点的设计要用心,多考虑边界情况,不断校正模型。

$ 2-2 新一轮的防御与攻击
在这一个周期的攻防阶段中,由于最后的提交阶段时间紧迫,没有来得及提交readme、还有很多细节的地方,比如Interface/toString()、包括一个已知的尚未来得及调试的bug。
在同质请求和捎带请求混杂在一起的情况出现时,边界条件的判断就显得尤为重要,尤其是同质判断和可捎带判断边界差了1秒的开关门时间。所以边界时间的+-1、是否取等号都需要纳入考虑的范畴。
由于设计工作的欠缺,后期陷入了调试的深渊。最终也因为一个边界取值的原因,被测试人员发现了一处bug。

同时测试中也发现了一些重要的bug,在类型转换过程中,溢出了数据类型规定的范围,导致程序异常终止。这也就是我在$ 1-3 中提到的,try-catch结构内置的意义,同时也要为输入的正则匹配加以限制,尽量避免贪婪匹配的使用。

$ 2-3 代码度量分析 && 类图
$ 2-3-0 第二次作业

$ 2-3-1 第三次作业

综合$ 1-4和本节的结果分析,从度量分析结果来看,代码的逻辑复杂度、嵌套块深度等指标在三次作业中均超出了标准值。内聚度不高、耦合度超标也是在设计中凸显的矛盾。在代码逻辑的部分、方法的抽象度不高,很多功能相似或相近的方法代码段出现大量重复。在第三次作业中这种矛盾更为明显:Complexity 均值高达6.3;Parameters per method 均值达1.3;Block depth 也超过标准值。这些显然都是由于代码中大量的循环嵌套、条件分支的交互错杂造成的,这也为我的调试带来了难以估量的灾难性后果。
工程化方法的指导思想在于“高内聚、低耦合”,但要做到这一点显然需要前期大量的准备工作,顶层的架构、显式的设计过程、测试驱动的开发,都将有效帮助我在下次的设计中进一步优化。



$ 3 关于Object Oriented 的一些其他感想



$ 3-0 关于申诉
第一次OO作业的申诉经历,足以证明:我航学子的学品与素养,托得住,信得过。即使在OO的高压双盲互测体制下。依然可以保持人与人之间最单纯的信任,真心希望能与诸位同行一道,摒弃流言蜚语,摒弃偏见,以此课程平台为契机,增进交流,建立信任。学在其中,乐在其中。共同收获技术上的不断提升!致力于正能量的传递,我们一起!

$ 3-1 关于无效作业
在OO Project2 中,我遗憾的看到了身边有很多朋友被申报了无效作业。而产生无效的原因也很令人诧异。看到查找别人个人信息的方式也不禁令我大跌眼镜。故意找别人的个人信息申无效,难道这是课程组设计的本意么?交流技术,看代码,看文档就好。一般情况下难道会有人特意点开pdf属性看作者?或是用强行打开.project文件?就为了找个人信息申无效?为了多得分方法有很多,最好的方法还是做好自己的任务,毕竟每个人都很努力,还是希望能够彼此多尊重对方的劳动成果吧。



$ 4 特别致谢



“没有人是一座孤岛”。说实话,前三次作业的过程充满了艰辛,一路走来,必须要感谢在这一过程中给我最大帮助的朋友们。他们是:
中国好室友LCJ,对于我解决各种琐碎的疑难总是回应以最大的热情,尤其是第三次作业ddl前极限操作时帮我赶制readme和interface,让我至今回想起来都很感动。
RHX哥、ZZH哥,给我在解决问题上提供了大量宝贵的思路。NYZ、GZP在具体的技术实现的细节上给了我大量的指导。ZKN、LHY、LQY为我提供的大量测试用例,帮助我有效的检验修正模型。JSH搭建了公共测试平台并维护,造福全系同胞。
当然更要感谢在每次互测阶段,秉持公平公正、认真互测的测试者,和坚持积极沟通交流并给我充分理解的被测试者们,是你们让我看到的跟多的是这一机制的积极一面。

希望在紧接着即将到来的挑战中,总结经验、继续努力,不断提高技术能力。也希望能尽我个人之所能,为这一课程做出一份贡献!

原文地址:https://www.cnblogs.com/chrischen98/p/8708790.html

时间: 2024-10-13 19:41:07

OO第一阶段纪实的相关文章

oo第一阶段总结

我系的重课真的是懒癌克星. 一如计组当初的警语:惰怠会导致惨剧.从寒假就抱着一本JAVA从入门到精通回家享乐了... 第一次作业:多项式加减 类图 & 度量 第一次作业相对简单,所需的类不多,逻辑上相对容易实现,重点在于正则表达式的学习使用,但是一夜速成JAVA还是正则表达式爆栈了 ,虽然在提交之前有测试到这个问题,但已经来不及更改,其他没有错误. 从度量分析可以看到,因为没有将main()方法独立成一个类,并且在main()中实例化了其他类,导致快嵌套层数比较高,在小规模的工程中尚可, 但代码

面向对象编程第一阶段总结

oo到目前为止也算是结束了第一个阶段,作为一个在本学期开学之前一行JAVA代码也没写过的菜鸡,这几周过得真的很艰难...一切都是从零开始摸索,全靠查资料和翻书自学orz 在这次的课程总结中,因为电梯部分的作业更加困难,我出现的问题也较多,所以主要只对第二三次作业进行分析. 第二次作业--傻瓜电梯 一.程序分析 二.个人反思 拿到第二次作业之后,当时整个人是毫无头绪的,本来是想通过画出逻辑关系类图先理清思路,但是冥思苦想了一个下午还是不太能理解课件所给出的的设计建议,于是决定按照自己的想法进行尝试

团队第一阶段绩效考核

成员 \权重 目标 实现( 25%) 工作量 (20%) 改善 创新( 10%) 完成及时 (15%) 积极性 (15%) 团队意识 (10%) 学习情况 (5%) 总分 郭庆樑 90 80 80 90 80 100 80 89 林彦汝 88 70 80 80 80 100 75 85.25 张金 80 70 70 75 100 100 90 81.5 以上是本团队第一阶段绩效考核方法及个人成绩.

S5PV210-uboot源码分析-第一阶段

uboot源码分析1-启动第一阶段 1.starts.S是我们uboot源码的第一阶段: 从u-boot.lds链接脚本中也可以看出start.S是我们整个程序的入口处,怎么看出的呢,因为在链接脚本中有个ENTRY(_start)声明了_start是程序的入口.所以_start符号所在的文件,就是我们整个程序的起始文件,_start所在处的代码就是我们整个程序的起始代码. 2.我们知道了程序的入口是_start这个符号,但是却不知道是在哪一个文件中,所以要SI进行查找搜索,点击SI的大R进行搜索

第一阶段绩效评估

以下是本团队第一阶段绩效考核方法及个人成绩. 成员 \权重 目标 实现( 25%) 工作量 (20%) 改善 创新( 10%) 完成及时 (15%) 积极性 (15%) 团队意识 (10%) 学习情况 (5%) 总分 李青 98 90 95 95 100 100 95 96 胡金辉 98 95 95 95 100 100 90 96.75 张瑶 100 96 95 95 100 100 95 96

团队项目第一阶段冲刺站立会议10

补昨天: 今天是第一阶段冲刺的最后一天,也是项目初次成果展示的一天,忙碌的一周终于要结束了,今天的站立会议并主要讲的是晚上去哪吃饭的问题,庆祝第一阶段的结束. 五一放假好好放松一下,等待第二个冲刺阶段的到来吧.最后附团队合照一张:

四则运算app第一阶段冲刺

第一阶段冲刺 [开发环境]:eclipse [开发项目]:小学生四则运算APP [开发人员]:郑胜斌 http://www.cnblogs.com/zsb1/ 孔德颖 http://www.cnblogs.com/kong21/ 李豌湄 http://www.cnblogs.com/leewanmei/ 江丹仪 http://www.cnblogs.com/JDY64/ [开发时间]:2015-11-20 第一阶段中,我们小组的人员都在学习四则运算的算法,并分别收集核心的算法,总的来说,核心算法

第一阶段总结

第一阶段的冲刺结束了,历时6天,我感觉第一阶段最大的感触就是学的没有方向感觉自己经过这十天的团队项目合作练习,我确定了好好补补以前的知识例如java还有就是团队的重要性,这里不是某一个人的英雄主义行为,一个人的力量再强大,也不如团队的力量强大,不过我们似乎没有把团队的力量发挥到极致,刚开始我们的热情还很高涨,不过经过几天的磨合,由于项目进展不大,逐渐产生了动摇的想法,想换个题目,不过后来仔细想了一下,我们的课题还是挺好的,只是没有认真分析讨论,我们的集体合作时间很少,除了每天站立会议那十几分钟,

第一阶段冲刺的总结报告(补)

第一阶段冲刺的目标:实现基本的截图任务,为实现第二阶段的冲刺奠定基础 第一阶段冲刺实际完成的任务:已基本实现冲刺目标,但是存在快捷键的冲突问题未解决,未实现与第二阶段有关的相应功能 对第一冲刺阶段的总结与思考: 第一阶段冲刺过程中,对于某些问题过于乐观,没有进行很好的团队安排,再出现问题时,没有进行详细的团队讨论,以至于造成问题遗留,团队交流进行不充分.另外,没有按照项目最初决定的方向进行开发,临时更换实现思路,导致项目的进度延迟,没有进行充分的风险评估.