菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
473
0

面向对象第二单元总结

原创
05/13 14:22
阅读数 94122

0. 写在前面

本单元的作业内容主要是电梯调度,主要目的为熟悉java的多线程操作,达到线程安全的目标。从我自身的体会来说,本单元作业的难度适中,第一次作业主要是对于java线程的熟悉,初步了解java线程的操作方法;第二次作业则着重处理多电梯的运行和调度问题,是对第一次作业的扩展;而第三次作业需要对于换乘问题和电梯类型进行考量,考验了设计的可扩展性。

1. 历次作业总结

第一次作业

第一次作业设计十分简单,只需要实现一部电梯的模拟即可。为此,我设计了五个类,由Main主类创建各需要的线程,使用Elevator线程进行电梯运行的模拟,使用Input类读入输入。为了实现类内和类间的信息传递,创建Waitingqueue类作为Input和Elevator之间的通信类,创建Processingqueue类内置于电梯内,保存电梯正在处理的请求。

第一次作业中,只有两个线程Input和Elevator,通过Input将请求读入并保存到Waitingqueue中,Elevator将Waitingqueue中的内容读入并进行处理。因此,我只对Waitingqueue进行加锁,保证两线程对其的处理不会重合。由于本次作业只有一部电梯,因此我并没有设计调度器对输入的请求进行调度。

以下为第一次作业的类图和协作图:

由此可以看到各个类之中拥有的成员和方法,以及各个类之间的协作关系。

第二次作业

第二次作业则将一个电梯扩展为了三个电梯,并要求支持添加电梯,因此,我在Input类中判断输入是否为添加电梯指令,如果是,则在其中直接添加电梯。为了调度输入的内容,合理的分配请求,我添加了一个Dispatcher类进行分配,分配的要求非常简单,只是将需求放入距离最近的同向电梯之中即可。由于有多部电梯,我将多部电梯及其Waitingqueue放入两个Arraylist之中嵌在调度器中,方便调度器获取电梯状态并处理请求。

以下为本次作业的类图和协作图:

第三次作业

第三次作业中,为电梯进行了分类,要求实现换乘的处理,主要还是对于原有的电梯运行的算法的问题。对于这个问题,我是这样考虑的,对于电梯,在电梯中对各种情况进行考虑,让其中的乘客在距离目的地最近的可达楼层离开,如果此时乘客未到达目的地,则生成一个新的请求重新分配给Dispatcher类进行处理;对于调度算法,我通过Dij算法求出最短耗时的路径,并将请求送到它第一个应该进入的电梯之中(事实证明这并不是一个好决策)。由于电梯实际上是内嵌在调度器线程之中的,因此请求的分派十分容易。

三次作业的同步块始终都是Waitingqueue的部分,只有Waitingqueue作为线程之间信息传递的媒介,因此并未出现死锁现象。

对于第三次作业的可扩展性,我认为适中,通过对电梯中所有参数进行处理,本设计基本可以支持在任意楼层以任意方式进行停靠的电梯,在电梯方面可扩展性较好;但是,调度器第三次作业实际上是继承了第二次的调度器,因此不具有很好的可扩展性,这也是我认为我的第三次作业在架构上的一大败笔。

第三次作业的类图和协作图如下:

2. 本人bug分析

第一次作业比较简单,在强测和互测中均没有发现bug,这一电梯模拟方式伴随了整个单元,在后来的测试中电梯也从未出错,从未出现过WA现象,令我比较满意。

第二次作业在强测中出现了一个bug,因为数据在180s时才输入,由于设计的调度算法未均分乘客,导致了将过多任务压在一部电梯上而其他电梯无人可载的问题,导致了RTLE。对调度算法进行了修改后轻松通过。

第三次作业则出现了较大的问题,由于抖机灵使用了Dij算法,导致调度算法出现bug,调度器一直将c电梯无法到达的请求分配给c电梯,导致遇到某些请求时会因为不断分派而导致RTLE。在bug修复过程中,我对算法进行了修复,成功修复了此bug。

3. 测试策略

(太菜了,本次互测一个Bug都没有找出来)

我的测试策略比较简单,首先测试在一个时间节点输入大量请求的情况,观察前提能否处理高并发问题;然后测试A,B,C电梯的边界情况(比如1-16层)的情况。如果测试不出来就放弃。。。。。。

另外,观察代码也是发现bug的一个好方法,比如如果出现在一个同步块中再次使用synchronized的现象,则往往容易出现死锁,针对这样的问题进行分析,也可以有效找到bug。

4. 心得体会

  1. 不要重复调用synchronized!不要重复调用synchronized!不要重复调用synchronized!重要的事情说三遍,出现死锁就要到电梯里去反省了呜呜呜

  2. 一定要做好课下自测!第一次第二次的课下自测比较充分,强测互测轻松过关,而第三次因为冯如杯未进行充分测试,结果出现了低级bug。夫互测岂为?同学乎?乃为自测耳。

  3. 理论课一定要好好理解,老师课上总会提出许多好的设计思想和好的模型,好好理解并领悟可以事半功倍。

  4. 注意和同学之间的交流,和dalao交流百利而无一害,通过和大佬交流,学会了lock,blockingqueue和vector等等好用的方法,还搞到了Jprofiler这种神级分析工具,它不香吗?

发表评论

0/200
473 点赞
0 评论
收藏