首页 > 技术文章 > OO第四单元总结暨OO课程总结

DanGuge 2020-06-14 10:48 原文

一、第四单元作业总结

本单元的主要任务是对 Uml 图元素进行管理和查询,测试一开始会输入一个静态图,之后会对图中相关内容进行查询。

第13,14次作业

第14次作业新增内容很少,故与第13次作业放在一起讨论

13次作业架构图

14次作业架构图

13次作业为类图的查询,14次作业新增了状态图和顺序图的查询。

  • 第13次作业中,我最初的想法是将每个元素都建立一个类进行管理,每次查询通过类之间的连接进行查询,但是类图元素每次查询的密度很高,而且查询内容比较单一,所以如果每个元素建类,在查询的时间复杂度上不容易控制,所以我主要采取容器的元素管理,来方便查询
/* UmlManager */
/* Id Query */
private HashMap<String, String> idQueryName;
private HashMap<String, MyClass> idQueryClass;
private HashMap<String, MyElement> idQueryElement;
private HashMap<String, MyInterface> idQueryInterface;
private HashMap<String, ArrayList<String>> idQueryExtend;
private HashMap<String, UmlAssociationEnd> idQueryEnd;
private HashMap<String, ArrayList<UmlParameter>> idQueryPara;
/* name Query */
private HashMap<String, ArrayList<MyClass>> nameQueryClass;
/* class count */
private int classCnt;
  • 第14次作业中,新增了关于状态图和顺序图的查询,基本上是计数查询,没有实现上的难度,不过对于 Uml 图的理解上会有些难度。

第15次作业

本次作业引入关于 Uml 图的检查模块,针对8个特定问题对 Uml 图进行检查。

ps.这一次作业,我没有考虑架构上的设计,比较摸鱼,就新增了一个StandardPreCheckManager类,在里面构造了八个类别的检查函数,第一次单个java文件代码行数到了快500行

  • 本次作业中,我在StandardPreCheckManager类中将需要检查的元素单独抽取出来,用容器进行存储和管理,对于不需要的元素就没有进行任何管理了
  • 本次作业的后四个检查基本没有实现难度,主要谈谈前四个检查

R001:

  • 这个检查要求检查类的重名成员,主要在于对于需要检查重名元素的理解,这个一开始我对于关联对端所连接的UMLAssociationEnd理解出现偏差

  • 检查可以通过 HashSet 对元素是否重复进行检查,如果重复了话,将相关信息填入重复元素容器中,用于异常时的返回

/* class id to attribute name */
private HashMap<String, HashSet<String>> classIdQueryAttributeName;
/* check containers */
private HashSet<AttributeClassInformation> checkSet001;

R002:

  • 循环继承检查,我看到这个的第一反应就是有向图的 tarjan 算法,检查强连通模块,所以实现的时候也是通过 tarjan 算法+关于单个元素的特判实现的
  • 输出的时候就是将同一个连通图中的元素输出(单个元素的连通块需要特判是否有循环继承)
//单个元素可能出现的循环继承情况
public class A extends A {
}

R003:

  • 重复继承,这个在类中按照课程组的设定是不会发生的,所以只需要考虑接口的重复继承
  • 接口的重复继承,我采用的方法就是广度优先搜索的遍历,把这个某个接口实现的全部接口都存起来,判断是否重复(因为有10s的CPU时间

R004:

  • 重复实现接口,这个就是把类自身直接实现的所有接口,通过父类间接实现的所有接口和接口继承而实现的所有接口存储在一个容器中,判断容器元素是否发生重复

Bug分析

  • 自测
    • 本单元自测主要通过画图+对拍的方式
    • 发现过 3 次空指针的问题,是因为容器中没有存储对应元素,查询时没有对存在性进行验证,直接检查了正确性
    • 15次作业中的R001的理解上出现了偏差
  • 公测
    • 13次作业,菱形接口继承的图爆了ctle,搜索时没有适当优化,对已经搜索过的元素进行标记,最后复杂度高达 2^40

二、四单元架构设计及OO方法理解的演进

第一单元

(目前所有作业完成下来,我觉得第一单元是最难的一个单元)

本单元的核心设计目标是理解面向对象的层次化设计思想,将表达式一层层化简,变成求导的最小单元项;再通过一个个项的运算法则进行组合,变成求导后的表达式。

  • 层次化设计,将问题一步步抽象成为能够解决的问题
  • 统一管理,通过类的接口实现或者继承的方式,对具有相同属性的不同元素进行管理
  • 工厂模型,用于生产某一类的元素,让代码结构更加清晰

第二单元

本单元主要是引入了多线程,解决不同电梯之间并发的调度问题,并采用合适的调度机制,提高并发效率。

  • 生产者消费者模型,解决并发的元素管理和共享的问题
  • 合理的调度算法,从整体性能上去考量电梯的调度,而不是只顾及到细节的调度
  • 并发的同步问题,采用合适的同步控制,更大效率地提高程序性能

第三单元

本单元主要是掌握对规格化设计语言的初体验,了解规格化设计语言并根据要求实现代码。

  • JML 语言的理解与实现,规格化设计语言的需要是很好理解的,难点在实现,通过合适的容器和算法的应用来提高代码性能
  • 缓存机制,本单元是对一个动态图的查询,因为大量的重复性访问需求,需要对相关查询结果进行缓存,保证查询效率
  • 数据结构和图算法,本单元的难点在于相关图算法的实现,包括 tarjan,堆优化的Dijkstra等
  • 图数据和图模型的搭建,通过实现具体的算法类,图类,帮助自己更好查询相关数据

第四单元

本单元主要是对 UML 的理解和解析,通过输入一个 UML 的静态图,对其中的相关元素进行查询

  • 对于 UML 图的理解,本单元的实现都建立在对 UML 的理解上
  • 层次化设计 plus,UML 中的元素的呈现都是通过 id 的关联实现的,通过解析相关的 id,实现不同层次元素的关联
  • 架构设计,本单元关于 UML 的元素众多,需要对元素进行合理的划分和管理,设计良好的架构

总结

OO四单元,真的受益匪浅,从开始只会面向过程编程,到现在面向对象编程;对于一个具体的对象,有了更深层次的理解,从归类,层次化,到特征元素,数据管理,有了更深层次,更广角度的认识;几次的OO作业,在大量的代码量的鞭策下,切切实实感受到了自己的成长和进步;分析问题,也更有逻辑性,层次性和整体性,对于代码框架和架构的重要性有个更深刻的认识。

三、四单元测试理解和实践的演进

第一单元

第一单元,自动化测试的开始。第一单元是对多项式的求导,我通过 python 的正则工具库和 sympy 的库进行求导检查结果对比,主要使用的工具包括 java,python 和 shell 脚本。总体来说效果是很不错的,可以做到数据生成,正确结果生成,结果对比的全自动化的评测。

第二单元

第二单元,我到第二次作业才开始写自动化测试的程序,总体的设计思路也和第一单元一样,数据生成,正确结果检查。本单元没有可以直接对结果进行判断的库或者简便的方法,我是通过写了一个 java 程序,对最终的输出结果和输入结果进行检查对比,判断在程序运行的过程中,有无有误的输出结果。

第三单元

第三单元,关于程序的正确性检查我没有很好的自动化检查方法,最后采用的是和他人进行对拍的方式。关于数据生成,参考了强测数据测试点的数据生成模式,对特定的指令进行大量数据的爆破,自动生成。

第四单元

第四单元,本单元因为数据的关联性太高,而且临近期末,有过自动数据生成的念头,但是有点麻烦,遂放弃。本单元的测试,数据生成是手动画 UML 图,正确性验证是通过与他人程序进行对拍。

总结

四个单元,两个单元完成了完全自动化测试的评定,两个单元通过对拍来检查输出的正确性,总体来说还是可以的,针对合适的项目采用合适的测试方式。同时完全自动化测试的两个单元有很好地为之后的作业留出扩展性,也在一定程度上帮助自己理解作业的要求,这个是我认为自己在测试中做的相对不错的部分,每个单元只要写一次测评机,后面对测评机进行数据上的扩充就能够很好满足需求。

ps.其实非常好奇学长们在线的测试机是如何完成的,尤其是最后两个单元,想要知道是如何实现评测的。

四、课程收获与课程建议

OO 算是大学以来最系统,最完善的一门课程,自己也通过一学期的项目作业,对 java 语言,对项目实现,对项目扩展性保留,项目架构等方面都有了更多的认识。回顾这一学期的学习历程,发现自己也完成了这么多,且有一定难度的项目,很有成就感,每次坐电梯等待的时候,总会莫名其妙地思考着这个电梯的调度算法,并和自己在作业中实现的调度算法进行对比,挺有意思的。

OO 课程是自由度很大的一门课程,针对同一个项目,同学之间可以有完全不同的架构思路,并且在研讨的时候,不同架构的对比,思考的碰撞,让人受益颇丰;其次,是通过 OO 课程,深入理解一门语言,理解面向对象,java 语言开拓者的思想,尝试使用经典的架构模式,然后感慨怎么会有这么巧妙的设计想法,一次次尝试,一次次体验,都无不惊叹于前人对于这个领域所做的尝试和创新,真正意义上站在巨人的肩膀上,体验这个时代最伟大的思想和创造;最后,是自己的提升,不论是对于工程项目的理解,还是对于问题的理解,现在能够尝试站在一个更高层次的维度上来思考这个问题,不像从前想到哪里做到哪里。

对于课程的建议:

  1. 课程除了每个单元的总结博客,是不是可以让同学们自己写一些 java 学习博客(自愿),通过课程组或者讨论区分享,并对这种行为进行一定的奖励,为课程研讨课之外再开拓一个讨论和分享的空间;
  2. 实验课的内容可以适当早点发布,既可以早点准备相关上机内容,也可以在OO理论课的时候更好理解当日的内容,比如 UML 单元的元素理解,我主要是通过实验课的指导ppt来学习的;
  3. 增加关于并发的单元内容,仅仅一个电梯单元的并发学习还是比较少的,仅仅只是接触了皮毛,所以之后的单元中,是不是可以增加并发相关的内容,因为并发在面向对象中还是相当重要的一部分。

最后,感谢老师和助教在 OO 课程中的付出与帮助,感谢同学们在学习过程中的分享和帮助。

OO 收官完结,赛高!

推荐阅读