ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BUAA-OO-Unit4暨OO总结

2022-06-28 23:33:28  阅读:136  来源: 互联网

标签:OO 作业 BUAA 电梯 算法 UML bug 单元 Unit4


本单元架构设计

主要分为5大类:接口方法类,数据库类,处理器类,封装类,辅助方法类。

功能
接口方法类MyImplementation 提供用户接口,调用处理器方法
数据库类Database 输入数据归档 完成基本的初始化,如把关系比较大的UML元素组合在一起
处理器类XXHandler 用于响应类图or顺序图or状态图查询指令
封装类MyUMLXXX 方便组合需要的UML元素,提供扩展功能
辅助方法类Tarjan 完成较复杂的图计算

事实上,这个架构完全是被CheckStyle逼出来的:第一次作业,接口方法类承担了全部的归档、初始化、计算任务。第二次作业码量增加,超过了CheckStyle单类500行的限制,不得已把处理器类单独拆了出来,420行勉强通过。第三次作业又增加了9个方法,写完后主类已超700行,于是又把数据整理和初始化作为数据库拆了出来。最终形成了该架构。

全流程可描述为:数据输入 => 归档 => 初始化 => 检查R00x => 响应指令

三次作业没有经历大改或重构,作业之间保持了较好的延续性。

四个单元架构设计与OO方法理解的演进

第一单元:设计一个表达式解析器,表达式含有-+*/ 三角函数 幂函数 自定义函数 求和函数 数字 和 变元。要求在不改变输入表达式语义的前提下,展开输入表达式中所有可以展开的括号,同时尽可能的化简表达式。

  • 第一次作业由于理解不当,经历了大改,在助教的提示下,采用了递归下降算法解析表达式,为第二、第三次作业打下了较好的基础。

  • 第二次作业时间比较充裕,提前预判并兼容了第三次作业解析“嵌套因子”的需求,第三次作业就比较轻松。说明架构设计要为后续需求留下提前量。递归下降的方法,初步让我感受到继承和多态的威力。

第二单元:实现一个电梯调度系统。存在纵向普通电梯和横向环形电梯。要求用尽可能短的时间,把全体乘客送到目的地。这一单元主要对多线程及锁机制有了一定的认识。

  • 第二次作业我为了规避并发问题,设计了一个预分配的电梯调度算法。预分配的调度理论上与自由竞争的调度差别不大,但在极端情况下(先有m个乘客提出电梯请求,接着有n-1个新电梯加入系统)性能会弱n倍,这是因为新加入系统的电梯无法被利用。鉴于此,我设计了强盗电梯策略,插入电梯中。表现为当新电梯出现时,会自发的检测邻居电梯,并从邻居电梯的等待队列中抢夺乘客。实际性能与自由竞争较为接近。

  • 第三次作业由于使用了动态路径规划,当新电梯加入系统,会自动触发全体等待乘客的路径规划方法,重新进行一个预分配。因此,强盗电梯的策略不再有存在的意义。由于该策略是以方法调用的形式提供的,于是只需简单注释掉了策略方法那一行。借用OS黑书的那句话:策略与机制要分离。分离开了,调整起来就比较容易。LOOK算法更底层,可以看作我的电梯调度“机制“。如果当初把策略嵌入LOOK算法内部,那我只能带着相对简单粗暴的强盗电梯的策略做第三次作业,相对更精细复杂的动态路径规划就注定不会成功。

第三单元:根据JML规格,实现一个社交网络。要求可以处理社交网络中的群、人员、消息相关指令。

  • 这一单元难点在于阅读JML规格。架构已经由教学团队给出,只需要按规格实现代码。不得不说,这是一次感受教学团队架构设计风格的难得体验。这一单元并不直接训练我们描述规格的能力,而是从实现规格入手,训练我们理解规格的能力。依我看,以术入道,比以道驭术容易且有趣的多。

  • 第一次作业刚公布时,我曾经向舍友吐槽老师是提出需求(指导书)的客户,助教是将需求描述成规格的架构师,我们是纯纯的码农:啥也不用管,按规格实现就行了。现在看来,的确是这样。这个单元有助于我们脱离码农思维,从更高一个层级理解现实需求和代码实现的联系。

第四单元:解析UML元素,响应UML图相关的查询指令

  • 这个单元的难点在于应对CheckStyle。CheckStyle存在的意义就是倒逼我们设计出“风格优美”的代码。什么是“风格优美“?经过这个单元的训练,我的感悟是:架构层级分明,各司其职;方法完全解耦,代码语义清晰;自底向上层层封装,可维护性强。

课程收获的总结

学习了

  • 递归下降算法,电梯调度算法,多线程的并发艺术,JML规格的理解与书写,UML类图的再理解;

  • 继承、多态、封装、容器、泛型、异常……

复习了

  • 数据结构和程序设计学过的Dijkstra、并查集、Prim、拓扑排序、Tarjan。(奇怪,怎么全是图论)

体会了

  • 一切皆为对象的抽象思维,学会以对象为单位构造程序。

当然,上面的东西跟下面的比起来都不重要。

以前深受OI思维毒害,看不上方法的多层调用,觉得能用一个函数写完的简单方法,为什么要来回调用?压栈弹栈时间很宝贵的,能省就省。OO确确实实给我上了一课。照以前的想法写单元作业,要么自己写的代码,过一个星期就看不懂,根本维护不动,更别说给别人看;要么就要接受CheckStyle的制裁。从这个角度上讲,OO课教会我最重要的内容,既不是花里胡哨的算法,也不是多线程等编程机制,而是写出人能维护的代码,即语义清晰、封装良好、高度解耦、可重用、可扩展的代码。

测试的理解与实践的演进

测试的目的是为了发现实现上的bug和设计上的漏洞。

第一单元:手工构造简单表达式,大眼观察法和代入简单数值计算。

第二单元:按一定的规则随机生成数据。由于多线程并发顺序不定,很难自动测试,也很难定位bug,因此只能根据输出情况捋一遍运行流程,大体给bug定位。除了简单的bug,比如死锁,一些诡异的bug只能靠时间去堆。大胆假设哪里有bug,小心手工求证。我就在第三次作业发现了这样一个诡异的bug,具体请参见第二单元总结-bug部分。

第三单元:初步接触JUnit单元测试。单元测试只能测出本单元有无问题,理想的情况下,各个单元没有问题,合起来也就没有问题。实际上可能并非如此,因此,需要多个单元共同测试,或者JUnit白盒+随机数据黑盒共同测试。据航天科技来分享技术的嘉宾称,白+黑也是目前业界主流的测试手段。

第四单元:这个单元比较朴素,各个方法代表相对独立的指令,彼此没有关系,而且每个方法逻辑上并不复杂,因此,保证各个方法没有问题,合起来就一定不会出问题。因此,合理构造UML图,将运行结果与期望结果对比,最为简单粗暴且有效。我构造了足以覆盖各个指令的全部情况的UML图,为R001~R009分别构造了UML图,测出了不少bug。

三个具体的改进建议

  1. Pre部分到第一单元跨度太大。Pre过于简单,第一单元指导书是所有单元最长的,定义是最多的,算法是最难理解的,码量也不小,大家都很折磨。建议加大Pre难度,并把Pre计入课程成绩,以督促同学们在假期完成Pre,给第一次作业留出充足的时间。甚至可以提前作业发布几天,进行递归下降的引导。

  2. 突出博客作业的意义。我的博客作业至今没有被任何老师或助教评价,我完全得不到任何正面或负面反馈,写的一头雾水。据观察,一次博客作业中被点评的同学比较少。博客作业都是同学们用心写出来的,图也是用心画的,反映的都是自己的真实感悟,没有任何反馈就很没有写下去的动力。希望下届至少可以每个同学点评一次吧。

  3. 图论算法有点多了。虽然用到的每一种图论算法都有我在OJ上的提交记录,但客观的说,这届6系是自主招生取消的第一届6系,大部分同学对算法的理解辄止于ds。就连老师也说:

    “我希望你们若干年后,如果被问到OO课学到了什么,想到的不要是我在某次作业用了并查集啊、我用了xx算法啊……”

    不幸的是,这些东西给人的印象确实挺深刻的。OO本身难度已经不低了,如果一定要用一些课外的东西,来填充OO宇宙内容的空白,那么或许可以雨露均沾一些?时限卡一卡,整点高级数据结构?或者来点DP?

“满纸荒唐言,一把辛酸泪。都云作者痴,谁解其中味。”

且住。

标签:OO,作业,BUAA,电梯,算法,UML,bug,单元,Unit4
来源: https://www.cnblogs.com/barque/p/16421661.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有