OO第二单元作业总结
一、第一次电梯作业
1.1具体实现
傻瓜电梯逻辑较为简单,易于实现。
使用两个线程:调度器在主线程负责读入请求,电梯线程逐个从调度器取出并处理请求。
1.2度量分析
1.3优缺点分析
优点:
实现简单。
缺点:
没有使用wait和notify,使CPU时间过长。
本可以使用单例模式,确保安全。
二、第二次电梯作业
2.1具体实现
调度器:优化调度器职能,将电梯索取请求变为调度器分配请求,多电梯时只需实现相应的调度算法即可,为多电梯做铺垫。
电梯:在第一次的基础上,在电梯内部维护一个Arraylist,存储电梯需要执行的请求。同时把请求分配至对应楼层,以便查询。在此基础上,电梯使用look算法,减少换向。
线程:使用wait和notify,避免忙等待。
2.2度量分析
2.3优缺点分析
优点:
使用look算法,减少换向,提高性能。
缺点:
对于容量方面的扩展有一定难度。
三、第三次电梯作业
3.1具体实现
关于调度:
进一步细化电梯状态,包括上行、等待、下行,以便调度器进行选择。
进一步优化调度器职能,并配置以调度算法。我的调度方法为存在最优解(即将路过起始楼层到达起始楼层时未满容量的电梯)时,选择最优解。否则,随机分配给可以实现该条请求的电梯。这是一种不大好的方法。这样的优点在于,可以避免某些情况下单部电梯负载过大。缺点是,对于特定数据,随机可能表现可能极差,并且加剧了不确定性,使得bug更加难以复现。正确做法应该是在不存在最优解时,进一步分析电梯状态,选择一个次优解。并且对于单部电梯可直达的请求,适度拆分也可以使得调度更快。
关于拆分:
在调度器内部维护一个Hashmap,当一条请求需要拆分时,将后半段请求以id-request的方式存入Hashmap,当电梯执行完一条请求后,查询调度器的Hashmap中是否有同名id的后半段请求,有的话则通知调度器可以分配。
3.2度量分析
3.3优缺点分析
优点:
可以很大程度上复用电梯代码,主要只增加了调度逻辑。
缺点:
调度算法实现较为简单,效率较低。
四、如何寻找程序的bug
构建自己的评测机:
在三次作业中,笔者都使用python搭建了本地的评测机与随机数据生成器。主要是通过subprocess库获取输出,并通过逻辑检查判断正确性。在开始的时候,由于无法解决JVM启动时间的问题,评测机总是无法精准投入。后来使用了其他同学改过的jar包,才解决了这个问题。通过大量的数据测试,一定程度上避免了bug的产生。在互测中,也通过这样的评测机寻找他人的bug。
在异常流打印电梯状态:
异常流中,可以打印出电梯的状态,例如:接收到请求,执行某一条请求,进出乘客时内部乘客信息等。这样配合标准流的输出,可以在bug出现时,快速定位问题代码,减少工作量。
五、个人总结
在三次电梯作业中,笔者在强测和互测中没有出现bug,在合理架构的基础上,正确性得到了保证。笔者对面向对象的思想和多线程的思想也有了进一步的理解。这一单元的作业确实让我收获很多。
在第三次作业中,没有实现一个很好的调度算法,也是一个遗憾吧。