四月份OO总结分析

从上个月的三次作业有惊无险,几乎完美过关,顺带完成了OS实验,到这个月的三次作业全都功亏一篑,三个无效,还没时间做OS实验——如果忽略这是我的经历这一事实,我绝对会感叹人生无常,同时对这位同学报以怜悯同情之心,外加猜测这位同学这整月一定过得很舒坦,得此结果也算是报应不爽。

可惜啊,这就是我的经历,我没有资格去当旁观者,去感慨去怜悯去猜测。所幸,我还能平静地写下这份总结,还能冷静地思考一些我以前从未思考过的事情。关于思考感悟之类的东西暂且不提,且先把总结分析任务完成。

(1)多线程的协同和同步控制

第五次作业,请求管理器、调度器和电梯线程之间需要进行的协同和同步控制较少,需要着眼的地方在于请求管理器和调度器对请求队列的访问和修改,以及调度器线程和电梯线程对请求的访问和修改。这里我采用了flag信号进行控制,当一个线程在进行修改时flag为true,修改完成之后再将flag置为false;而只有当flag为false时,线程才能进行访问。

第六次作业涉及到的多个线程对同一内容(变量或对象)进行读写的操作较多,只采用设置flag方法就稍显不足了。所以,在这里除了设置flag之外,我还使用了任务转移和设置二级flag两个方法。任务转移,顾名思义,就是将某线程的一些任务交给另一线程进行处理,这里涉及的主要是对共享对象的修改任务。

设置二级flag稍显抽象,我们不妨看一个例子——线程A和B共同维护共享对象obj,共享对象中包含了许多元素;A遍历obj的元素,若某元素符合一定条件,则通知B对该元素进行某种处理;本次遍历中,A不确定符合条件的元素的数量和位置;另外,A希望遍历工作完成后,B再进行处理。这样就产生了一个问题——B是根据A设定的flag来判断是否有新任务产生的;而某元素触发flag产生时A不能立刻修改flag以通知B;当A能够通知B时,A已经在处理别的元素了,其所处理的元素未必会触发flag。如此,可引入二级flag,当某元素触发一级flag时,A将二级flag设置为true;遍历完成后,若二级flag为true,A在将一级flag设置为true,以通知B。

第七次作业涉及到的多个线程对同一内容(变量或对象)进行读写的操作也不少,我采用的协调方案与第六次作业的方案大体相同,稍有差别的地方在于,第六次作业侧重于设置二级flag,而第七次作业侧重于任务转移。

(2)基于度量的程序结构分析

第五次作业中,我只是注意到要控制每个方法的代码量,完全没有注意对各线程、各类的工作进行均衡化处理,这就造成了许多方法的操作极其简单、代码量极少,而重要的方法的操作则较多、调用的方法较多、调用层次较深。

另外,我的设计也并不符合显式表达原则,这体现在用多个数组存储一条request的请求楼层、请求时间、目标楼层等信息。这就造成了一些麻烦,比如每次传递一条请求的信息,都需要传递一堆参数。

要说明的是,因为时间有限,这份作业是没有完成的——在进行“极限操作”的时候,也许是因为脑子短路,我忘了让请求管理器把请求发送到请求队列,所以调度系统压根就“看不到”任何有效请求,那么调度电梯响应什么的就纯属扯淡了……

第六次作业原则上是要求每个触发器对应一个线程,但为了方便操作和管理,我采用的设计是——基于监控对象创建监控线程,然后每个监控对象再为其拥有的触发器创建触发器线程。如此,触发器线程只需要负责判断其对应的触发器是否被触发;而监控线程则根据触发器线程的触发情况进行相应处理。这次作业除了对方法代码量的控制,我还注意到了对方法调用深度的控制;但是我没有做到将输入处理部分从main中独立,所以Main类看起来比较臃肿。

毋庸置疑,既然这是一份无效作业,那么它就属于未完成的作业——我在处理输入的时候,把if条件写成了while条件,那么只要第一行输入不是结束命令,while条件就会一直生效,程序就会一直判断处理这行输入,至于第二行第三行什么的,对程序来说是不存在的,因为那根本都不会被读入的啊……

后来我又花了两天把它进行了补全、修改和优化,以上的UML图和复杂度分析图都是来着完全版。

第七次作业我不仅注意到对各线程、各类的工作量的均衡化,还遵循了显示表达原则等一系列原则,各线程之间的任务也比较清晰。但是,这依然是一份无效作业,因为程序的输出有问题——对于所有非无车请求,程序都正确处理并输出;但对于所有的无车请求,程序都没有输出处理过程。这也许是因为在共享对象的管理方面出现问题,因为在我的设计中,每个有车请求都有一张ProcessRecord,其中的部分内容是由调度系统记录的,而另一部分内容是由被派单的出租车记录的(其实这部分内容也可以由调度系统进行预判并记录,但这样就稍显“多此一举”);其中出租车对ProcessRecord的使用和管理也许出现了问题,导致调度系统无法完成对该请求的处理过程信息输出工作。

(3)程序bug分析

这三次作业中,我的程序都出现了致命性的bug,从而直接导致了作业无效。这些bug都对程序的基础功能起到了直接影响,而且很巧合的是,一个出现在了获取输入部分,一个出现在了有效输入结果传递部分,一个出现在了输出部分……

之所以会接连出现这样的bug,应该是因为状态问题和习惯问题。第五次作业,周日、周一和周二这三天,我总共睡了5小时,状态会是如何就不多说了;第六次作业,三天8小时,比起第五次也是不遑多让;第七次倒是好一些,可惜第七次作业的出租车管理器部分,我是在周三“凌晨”6点写的……当然,如果我的习惯够好,也不会出现这样的问题——可惜这个如果暂时不存在。每次完成一个类或者一个方法,我都不会怀着“这块内容保证不存在问题”的思想去做,而是想着“先按现在的思路写完,如果有bug在调试的时候会很明显的,到时候再改”。我不知道编程习惯跟我差不多的同学有多少,但我知道这样的同学的debug过程一定会漫长而痛苦。此外,如果情况紧急时间不足,那又会发生什么呢?

(4)互测分析

第五次互测,我当时只想着回血(补觉),所以也就没有仔细阅读我分配到的代码,而只是在一些设计细节方面进行了测试。

这是因为基于前几次分配的结果,我发现编程能力好的同学,其设计在基本功能的实现上可以说一定是完美的,也就是说其程序不会出现有的捎带没有实现、有的输出时间不对或者输出顺序不对之类的问题。但其对基本功能的实现越是完美,在细节上就越有可能出现问题,这些问题属于细枝末节上的问题,很容易被这种级别的同学忽略。到底是怎样的问题,还要基于具体情况分析,比如我第一次匹配到的那份疑似出自竞赛党之手的代码,这位同学把第一个多项式取出来进行单独处理,其余的多项式一起处理——但他忽略了一种情况,那就是输入只有两个多项式,并且都只含有1个0次项(也就是只有1个常数)。但是,毋庸置疑,这需要仔细阅读对方的代码,否则如此细微的问题是不可能被发现的。

如果分配到的是“巨灵神”级别的同学的代码,而测试者又想在粗略阅读甚至不阅读对方代码的情况下找到bug,也不是不行。这一样是在细节上着手,只不过这里的细节是结构细节而非代码细节。第五次互测我就是这样做的。只不过这就只能碰运气了,不像上面那招一样百试百灵,可以“吃遍天”。针对结构细节进行测试,大概指对最低临界情况(单个有效输入或直接输入结束命令)、最高临界情况(最大边界输入或最大+1或最大+N*最大)和特殊输入(有效+特殊无效)、(结束命令+有效输入)等情况的测试。

关于代码细节和结构细节的定义,我不确定我的定义是否合适而准确,我对此做出定义,只是为了方便区分两种在细节上进行测试的方法——其一是仔细阅读其代码,识别其在处理细节上可能会出现的问题;另一则是大体阅读甚至不需要阅读代码,直接对某些已知的或公认的细节进行测试。

再说说第六次和第七次互测。这两次我都没有测试对方代码——第六次是因为我当时需要补全和修改自己的程序;第七次是我忘了,想起了的时候已经是10点多了,对方代码早凉了……

(5)心得体会

三次作业下来,我的提升还是有的,比如不会再写那种百余行的方法、不会再把一个请求的信息切割成几块然后分别存储。但行文至此,是时候来点悲惋气氛了。

三次作业,全都是玩命去写,结果都是无效,最后直接保送补给站——哦,不能这样说,应该说最好的结果就是补给站,如果再多来几次似乎连进补给站都没资格。如此行为终得如此结局,哪怕我再平淡再无争再无谓,也难以说服自己,让自己心中不失望不悲凉。我该如何告知那个每周三早上,脸甚至开始明显变绿的自己——嗨,小子,看到没,你这周的努力就是徒劳的,看清楚没?这下服了没?你的挣扎是徒劳的!

我无法这样告知那样拼命的自己,但事实帮我做了。我要告知的,仅仅是你其实略有收获,还有,你需要休息,以及反思。

我需要休息,这毋庸置疑。有此遭遇,若是不好好缓缓,而是立刻知耻后勇、立刻精神抖擞地去学习、去拼搏,如果我真这样做了,那才是真的让自己彻底失望。我不是超人,哪怕我自认为毅力过人、无畏绝境,但也不能如此压迫自己,否则疯掉就是唯一结局。但这样倔强、这样无畏绝境的我,面对如此局面,也不需要哭哭啼啼,不需要埋怨别人“太狠”,更不需要去质疑自己是否真的无能。我需要的,仅仅是休息会儿,喘口气,缓缓心情,然后看看之前的结果,仅此而已。

我更需要反思。第五次作业恰好处在清明节前后,可我在清明节却浪了好几天,直到假期快要结束才开始着手去做。舒缓3月份的压力,这无可非议;可是我在明知第五次作业有难度的情况下,还玩什么“今朝有酒今朝醉”,那就属于作死了。这次教训也告诉我,舒缓也要看情况看方式,否则任你有天大的理由,也难免会造成不好的结局——事实不是人,它不需要讲人情讲道理。不过第六、第七次作业,我开始做的时间其实和其他同学差不多,可依然无效了,这就不是上面的理由可以解释的了。这其实跟我的个人特点有关,我的特点大概是“不善于速,而极于韧”“不善于受,而极于用”。具体来说,做某件事,我通常比别人做得慢,但无论如何,我都会坚持去做,并且坚持到底;学习某些东西,我学习得比别人慢,但学会之后,我会运用得比很多人都要更好。只是,OO作业要求的恰恰是要学得快、做得快,如果我不想挂,就只能提前去做、花更多的精力去做。

原文地址:https://www.cnblogs.com/1606-1054/p/8969797.html

时间: 2024-11-02 22:22:25

四月份OO总结分析的相关文章

2018-北航-面向对象567次OO作业分析与小结

设计策略及其变化 第五次作业-多线程电梯 在这次作业一开始的大部分时间,我一直想着怎样设计最为完美,完全使用BlockingQueue,导致交作业前发现设计并不能满足指导书的要求.最后仓皇之中加了一个新的类,既臃肿,又是轮询实现,导致出现了bug. 第六次作业-IFTTT 这次作业采用了不同照snapshot的方式实现,由于对指导书理解有些问题,导致出现了一个未考虑的情况.这次作业中线程安全的文件类的设计加深了我对线程安全以及Java文件操作的理解. 第七次作业-出租车调度 这次主要使用了锁来实

【转】EXT VTYPE自定义举例

原文地址:http://www.blogjava.net/xiaohuzi2008/archive/2012/12/08/392676.html 近日来对Ext特别感兴趣,也许是它那种OO的设计思想吸引了我,也可以追溯到第一次见到EXT那种漂亮的界面开始吧.求神拜佛不如自食其力,为了一点小的问题找遍了GOOGLE也没个结果,自己甚少去BBS混,也不熟悉规矩,只能硬着头皮自己干了.翻源代码是一道必不可少的工序,说来惭愧,自己对JS的认识还停留在入门阶段. 这里说说自己对于Ext验证这里浅薄的理解:

死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中,探讨的是如何聚焦领域模型(抛开一些干扰因素,才能把精力集中在领域模型的设计上)?需要注意的是,上一篇我讲的并不是如何设计领域模型(本篇也是)?而是如何聚焦领域模型,领域模型的设计是个迭代过程,不能一概而论,还在路上. 当有一个简单的领域模型用例,完成一个从上而下过程的时候,就需要对领域模型和数据库进行对象关系

OO第三次课程总结分析

OO第三次课程总结分析 规格化设计发展历史 在网上找了好久也没找到合适的信息,稍稍参考了同学的博客.大致如下:最初的的软件并没有形式化方法,随着软件工程的兴起,为了便于工程间的协调管理,人们提出采用工程方法来组织.管理软件的开发过程并深入探讨程序和程序开发过程的规律,建立严密的理论.随着时代的发展,软件的复杂度日益加大,结构化程序设计的缺点日渐暴露出来,面向对象设计由此产生,规格化设计进一步发展,这一次的规格设计可以更好地区分置换条件,以适应面向对象设计.如今,规格化设计基本完善,软件可以轻松实

采用[ICONIX] 方法实践分析和设计之三 [需求复核](转)

需求复核旨在确保用例和域模型同时满足客户的功能性需求.同时确保客户知道开发小组将根据这些需求做何种设计.同时它也是系统分析阶段的一个里程碑(milestone).      这一阶段在ICONIX方法中的位置如下图:      三巨头的首次聚首:客户代表,开发小组代表,经理就已有的工具(用例,原型和域模型)帮助客户理解其需求,并确定系统的功能需求.在这一过程中,ICONIX方法认为可跟踪性(traceability)是非常关键的,它强调清楚每种需求是如何转换为一个或多个用例,以及域模型中的一个或

ENode框架Conference案例分析系列之 - 上下文划分和领域建模

前面一片文章,我介绍了Conference案例的核心业务,为了方便后面的分析,我这里再列一下: 业务描述 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的用户有两类:1)客户,可以创建和管理会议:2)会议座位预定者,可以预订会议座位.具体的关键业务描述如下: 客户创建一个会议,并录入会议的基本信息,比如名称.时间段.地点,等:会议创建后,系统会为客户自动生成一个AccessCode,客户可以通过AccessCode访问自己创建的会议: 客户定义某个会

分析最透彻的命令模式

转http://www.tracefact.net/Design-Pattern/Command.aspx Command 模式 Step by Step 引言 提起Command模式,我想没有什么比遥控器的例子更能说明问题了,本文将通过它来一步步实现GOF的Command模式. 我们先看下这个遥控器程序的需求:假如我们需要为家里的电器设计一个远程遥控器,通过这个控制器,我们可以控制电器(诸如灯.风扇.空调等)的开关.我们的控制器上有一系列的按钮,分别对应家中的某个电器,当我们在遥控器上按下“O

面向对象分析与设计—四色原型模式(彩色建模、领域无关模型)(概念版)

阅读目录: 1.背景介绍 2.问自己,UML对你来说有意义吗?它帮助过你对系统进行分析.建模吗? 3.一直以来其实我们被一个缝隙隔开了,使我们对OOAD遥不可及 4.四色原型模式填补这个历史缝隙,让我们真的看见OOAD的希望 5.在四色原型上运用彩色建模增强视觉冲击力 6.通过四色原型模式建模出领域无关模型 7.结束语:建模时你可以不考虑具体实现,但是建模者要懂技术实现 1.背景介绍 至今我都清楚的记得我第一次被面试官问起什么叫"建模"技术时的情景,那是好几年前的事情了,当时是胸有成竹

OO的片段

摘自C++编程思想: ------------------------------ 继承与组合:接口的重用 ------------------------------- 继承和组合都允许由已存在的类型创建新类型,两者都是在新类型中嵌入已存在的类型的子对象.然而,当我们想重用原类型作为新类型的内部实现的话,我们最好用组合,如果我们不仅想重用这个内部实现而且还想重用原来接口的话那就用继承.如果派生类有基类的接口,它就能向上映射到这个基类,这一点对多态性很重要. 虽然通过组合和继承进行代码重用对于快