一、分次作业总结
1、傻瓜电梯的调度
(1)设计策略
作为面向对象中多线程的入门,电梯调度单元整体难度并不是很大,其中的重点就在于如何实现多线程中各个线程工作的安全执行。在第一次作业中最重要的是如何实现共享资源的维护,即如何实现共享队列的维护,保证电梯请求的有序执行;以及在请求结束时程序的正常退出。
在做第一次作业时,我的设计策略主要是用一个ArrayList实现对于电梯请求(request)的存储与取出;由于在电梯运行过程中不需要考虑捎带的问题,所以在实现时只需要维护电梯外请求的ArrayList即可。而在终止指令进入(null)时,需要考虑电梯完成请求,且电梯外无请求只有null时程序退出即可。
类图
由于第一次作业实现功能较为简单,所以类图较为简洁,而且拓展性较强,只需要增加一些函数就能实现功能的拓展。
度量分析
分析:
由于本次作业实现功能较为简单,所以在测试过程中并未发现能发现的bug;但是在后续作业的编写过程中,我发现自己的第一次作业存在轮询的重大隐患,也是我第一次作业中最需要重视的问题。
互测hack心得
傻瓜电梯的构建较为简单,在互测环节中并未发现bug。
2、电梯捎带功能的增加
设计策略
作为电梯单元的第二次作业,这次作业增加的捎带功能只要是需要在每当电梯上升一层时都需要判断一次电梯外的请求队列中是否存在需要捎带的对象,在电梯第一次作业中增加一个查询功能就可以基本实现。
(2)类图
与第一次作业相比,我的第二次作业在函数上修改较多,主要是因为原本只需要一次性到达的电梯请求需要分解成为多个电梯楼层的判断过程,以及电梯方向在判断是否开门时的作用,需要同时用一个函数判断(dire)。
(3)度量分析
复杂度控制较差,主要是因为我在做程序之前未能很好地实现功能的分解,导致在函数的编写过程中出现了函数的嵌套,这也是我所需要注意的。
(4)bug分析:
在这次作业中,我有两个强测点出现了超时的现象。在检查自己的代码时,我发现自己在判断电梯是否需要开门请入乘客时忘记了分类讨论(电梯向下运行时接向下的乘客,向上时接向上的),直接以(from>to)作为开门的条件,这是一个十分愚蠢的错误,也促使我在今后的代码提交过程中对代码要进行更严格的检查。
(5)互测hack心得
在互测阶段中,我使用了一个对拍器利用测试数据对组内代码进行了测试。由于本次作业对于电梯运行方向的转换有一定的要求,hack方向主要就是测试他人电梯运行过程中是否存在“飞天遁地”的bug存在。
、多部电梯协调工作的实现
(1)设计策略
在电梯单元的第三次作业中,电梯数量变多了,停靠楼层也不再是所有楼层,所以需要各个电梯进行协调调度。所以,我的设计策略是在电梯请求进来时直接将请求塞入能实现该请求的电梯所在的ArrayList中,同时需要增加有效位来实现一个需要中转的乘客的第二部电梯调用(保证在人未送到中转站时第二部电梯不会被调用)。
同时在本次作业中,程序的正常退出也是难点之一。在我的设计过程中,我将所有的请求都首先分散到三个请求队列中(包括需要中转之后才能执行的请求),每个线程在自己的队列中所有请求全部执行完之后且队列中仅剩下null指令时线程退出,所以实现了程序的正常退出。
(2)类图
继承了上次作业的架构,本次作业并未增加类,只是在实现过程中需要传入每个电梯不同的参数,实现起来还需要保护程序运行的安全性,在我的作业中由于线程的请求都已经分配好了,所以线程安全问题并不需要过多地担心。
(3)度量分析
这次作业中,复杂度较高的部分主要也是由于我自己在设计过程中的考虑不周全所导致的“缝补过程”中复杂度的提升。
(4)bug分析
在测试过程中,我并未发现自己程序中存在的bug,要说还是自己在编写程序过程中的一些遗憾。
由于实现就将各个请求都存入了各个电梯的队列中,很容易出现一个电梯“忙到昏厥”,而另一个电梯“无事可做”,这样的情况下性能收到了很大的影响;但我理想中电梯调度过程中最好的调度方式(当一个请求进入时直接由三个电梯争抢,由用时最短的电梯接收该请求)却又会需要考虑很多的线程安全问题,在多次调试仍存在bug的情况下只能忍痛舍弃这种方案。这也是电梯单元中我所需要改进的一些地方。
(5)互测hack心得
在互测环节里,我所发现的bug主要是中转时乘客未到中转站便开始第二部电梯的传送,或是仅将乘客送到中转站就结束了任务。这个bug在我看来是因为有效位设置时出现了问题,导致程序运行的不准确。
二、心得体会
在多线程单元的学习过程中,线程安全问题是我认为最重要的一个注意点。线程不安全并不一定能在测试过程中反应出来,且即使能显示出来,这种显示也有可能是不可复现的。所以,在线程与线程之间协调工作的过程中,我们还是需要对其中每一步都进行足够的分析与保护,才能保证程序的稳定性。
相较于第一次作业,我在第二次作业中大面积的重构现象并未出现,也算是自己在编程过程中的一大进步,但在编写过程中,每个函数实现的功能有重叠,比较混乱,这也是我在接下来的面向对象课程学习过程中所需要着重强调学习的地方。