BUAA_OO_UNIT2_Summary

面向对象第二单元总结——电梯

程序及bug分析:

第一次:

设计思想:本次作业要实现的功能为可稍带电梯。我的设计采用了生产者消费者模式,具体的设计需要三部分,一是输入线程,二是调度器,三是电梯线程。输入线程和所有的电梯线程共用一个调度器,输入线程获取请求并将其放入调度器,电梯根据自身情况(是否静止、上行状态还是下行状态)从调度器中获取请求,并且在运行途中根据电梯的运行方向进行捎带(LOOK算法)。

UML类图

 程序复杂度

设计反思第一次作业要求实现一个能捎带的电梯,其中的核心知识点是多线程,我在做本次任务的时候,大量的时间用在了学习多线程的相关知识上,在优化上下的功夫少了很多,最后仅仅做到了正确性的保证,没有得到很高的强测分。总体而言,我觉得第一次作业的难度比较大,尤其是多线程的安全运行方面,线程的安全,包括线程安全运行,线程安全退出两大部分。安全运行的关键有二,共享对象的访问控制、死锁的预防。对于这个需求,我的处理方式是采用synchronized关键字,对于调度器中读写请求队列的操作进行加锁,保证读写正常。而线程安全退出的关键在于退出时机的选择,我的措施是当输入线程发现输入结束时,向调度器线程中存入null,随后自己死亡,电梯线程获取到null并且自己此时不在运行状态,结束自己。

第二次:

设计思想:本次作业新增了数个功能,包括电梯最大人数的限制,电梯数量的初始化,电梯可运行楼层的扩大。这次作业我是在第一次作业的基础上迭代开发的,整体变化较小。主要的变动是把对于处理输入的功能,即生产者部分,全部放入了主线程。主要原因是主线程需要通过获取最先输入的数字来确定电梯数目,而如果依旧使用生产者线程,则在主线程和生产者线程当中会出现两处对于输入的获取,可能导致线程不安全。

UML类图

 

程序复杂度

 设计反思:因为第二次作业是在第一次基础上的开发,所以导致了一些函数的复杂。整体而言,第二次作业比第一次好一些,一方面终于体会到了迭代开发的快感,另一方面第二次作业针对接人策略进行了一些优化,但是优化依旧没有做到很好,我对于电梯运行途中是否要进行折返接人进行了较多的考虑,但是后来担心电梯安全性出问题放弃了。。。

第三次作业:

设计思想:这次作业新增的要求是电梯的新建,以及电梯的分类和分类带来的不同特性(包括停靠楼层,最大人数,运行速度),同时扩大了电梯能到达的总楼层数。本次作业我的主要处理策略是将电梯线程做处理,对于各个电梯不同的地方挨个提取出来作为电梯线程的属性,在初始化线程的时候根据电梯类型进行赋值,保证了最大限度地减少修改。同时因为这次作业很大的一个难点就是换乘,我的处理方式是新建一个people类,根据接人的电梯类型、这个人的出发楼层以及要去的楼层,提前设置好要换乘的楼层,将该换乘楼层暂时设定为这个people对象要去的楼层,将这个人最终要去的楼层暂时存起来,并设定该人为special。电梯在送出人时进行判断,如果该人为special,那么需要根据当前楼层以及之前储存的这个对象最终要去的楼层重新生成请求,调用put方法放入调度器的请求队列,同样也是最大限度地减少重构。

UML类图

程序复杂度

 

 设计反思:这次作业依旧是在上一次作业上进行的改进,这一点是很大的进步,但是问题是,我在课下测试的时候曾经出现了比较大的正确性问题,在求助了同学之后终于发现是线程死亡的问题,本次作业中电梯死亡有好几个需要考虑的点:1、输入线程死亡 2、调度器请求队列为空 3、其余电梯中没有正在运行的要换乘人 。尤其是第三点最容易遗漏,如果某个要换乘的请求在还没坐换乘电梯时该换乘电梯就死亡了,那么该请求将无法送达。

第三次作业可扩展性

我认为我第三次仍然具有较大的可扩展性,一方面因为我的电梯线程功能封装比较好,移动一层,接人送人都有对应的封装函数,并且电梯主要可能的不同之处都挑出来设定为了属性,如果下次再有对于电梯的新设定,只需要进行少量的修改即可。另一方面我在第三次作业引入了people类,专门针对的就是人的换乘问题,如果之后再有对于人的限定,完全可以在这个类中新增属性以及对应的方法解决。还有一点就是我的换乘策略选择的是简单的一次拆分换乘,接人策略选择的是LOOK算法,没有进行太多的优化,这样接人送人策略比较简单,可扩展性更大。

分析自己程序的bug

这一单元的三次作业均没有在强测互测中出现正确性问题。主要原因是我在课下做的测试比较充分,重点放在了线程何时死亡的测试,各种换乘请求的测试以及新增电梯请求的测试,同时使用了评测机进行了覆盖性随机测试,保证了正确性。

分析自己发现别人程序bug所采用的策略

我认为发现别人程序的bug和测试自己程序bug采用的策略是一致的。重点测试了特殊换乘请求的测试,我在第三次作业中针对要去往3层的请求生成了许多测试数据,发现了我屋内一部分同学的问题。还有一点就是对于电梯何时死亡的测试,构造测试数据中前面全是使用AB电梯的请求,在最后来了需要使用C电梯的请求,重点测试此时C电梯是否还存活。另外还专门构建了是否能生成新电梯、电梯核定载人数的数据,这些都没有发现别人的bug。

心得体会

这一周的OO终于过去了,我的感受主要是不满意我自己的得分。分析失分原因,主要在于我自己过分保守,担心优化导致正确性出现问题,所以只采用了最简单的接人策略。但是根本原因还是在于自己懒惰了,没有把多线程相关的东西学熟练,如果熟练我一定是敢于大胆的去优化的,为此我自己觉得十分遗憾。不过这一周的学习我还是学到了很多关于多线程的知识的,包括基本的线程创建、同步控制以及死锁的预防,另外还掌握了一些多线程编程时的小技巧,比如要想让各个线程尽可能地均匀占用调度器的资源,可以在每个线程处理完一次请求之后小小的sleep(1),这样不至于出现一个线程一直占用调度器的现象。总体而言,这一周我学到了很多多线程知识,同时对自己的分数留有了遗憾,下一周要开始学习新的语言JML,希望自己可以吸取这一周的教训,把知识学扎实。

猜你喜欢

转载自www.cnblogs.com/shellyyzf/p/12716780.html