第二单元博客总结
第一次作业
(1)设计策略
设计策略,是几乎没有大的策略,模仿着ALS的调度方法,大致弄了个样子出来。
第一次作业的主要目的是熟悉单生产者,单个消费者的生产模式,熟悉共享对象的读写同步等操作。
电梯调度方面,实现了简单的捎带,调度判断等等策略,总的来说就是同楼层同方向的捎带,弱化版的ALS电梯
(2)可拓展性
如同前文所言,是弱化版的ALS,大部分时间集中在处理共享对象读取写入,进程的控制上面,忽略了电梯的调度,
使得运行时间非常长,可拓展之处在于优化电梯的策略,实现更快的调度
(3)度量分析
总体来说,并不复杂,最复杂的在于电梯run方法,以及共享对象里面对于存取的判断等,总而言之,第一次作业整体架构比较简单。
由于设计实在是太过于简单,只是单纯的生产者,消费者模型,共享对象只有增加,删除两个功能。
在SOLID原则上,单一职责并没有违背,里氏替换没有违背,接口隔离没有违背
主要违背的地方在于DIP原则,电梯和输入类,都直接依靠着共享对象类,而不是“依赖着抽象接口,在让共享对象类去实现这个接口"这种方式,
以及这种方式所导致的,开放封闭原则受到了影响。
但是总的来看,根据程序的总体设计,电梯的共享对象并不会出现巨大变化。
而且难以出现一个程序里面,不同电梯的共享对象的种类还要出现变化的情况,因为共享对象更类似于加了一些新方法的容器。
除此之外,严格来说,这个共享对象,算不上一个低级模块,只是充当容器的作用。
所以就没有设计接口,而是直接依赖实现。
(4)自己bug与别人bug
最大的bug来自于时间问题,运行的太慢了,导致rtle,这个问题改正方法就是重新写调度策略。
别人的bug并没找到,hack超时并没有成功
除此之外,提交之前最大的bug来自于电梯无法停下来,电梯线程无法结束,导致课下一直超时。
最终改变了一些种植条件,成功完成。
第二次作业
(1)设计策略
第二次作业,改动异常的少,甚至相比于第一次作业几乎没有任何变动
第二次的多部电梯,完全就是多个第一次的电梯共享一个队列,来回争取,没有任何调度策略。
但是实际测试中,没有策略的效果比一些调度策略甚至还好或者差不太多。
主要问题还是电梯跑的太慢了,拉了后腿。
总体就是,多个电梯,共享一个队列,然后互相抢夺
(2)可拓展性
由于电梯数目不确定,很难做针对性的调度策略,调度策略方面拓展性感觉比较小。
但是多个电梯,对于同一个队列的处理,有很高的拓展性。
比如3个从一楼去往3楼的人那边,一个电梯就够了,我却派出了三个电梯,导致运行的时候,电梯资源的浪费。
另外就是电梯还是比较慢,可以改进。
(3)度量分析
可以发现,和第一次作业相比,几乎没有任何变化,因为这次就是第一次基础上,加了多个电梯,共享一个队列而已。
同样的,因为设计的结构没改变,SOLID原则也和第一次一样,主要违背了DIP原则,顶层并不是面向共享对象的接口,而是直接依赖着共享对象的具体实现
同样的,由于违反DIP原则,导致在开闭原则上面也受到了若干影响。
前两次作业,违反原则主要原因是,我把共享对象当作了一个包含着新方法的容器类,具体实现上,共享对象也确实作为容器,按照容器的方式去实现了一些功能。
这样子的低级模块,就没有特意的去设计接口,而且严格来说,它也算不上是低级模块。
本着如无必要,勿增实体的想法,没有去迎合DIP原则的设计
(4)自己bug与别人bug
我自己和别人的主要bug,主要是两个System.in的缓冲区不共享,导致电梯会吃掉前面的人的情况。
主要原因是,主函数类里面,用一个输入读取总数,输入类里面,用一个输入读取人的信息,主函数输入没及时关闭,导致人的信息进入主函数缓冲区,主函数结束,信息也丢失。
改正方法就是及时关闭或者公用一个输入。
自己是在课下提交阶段找到的bug,hack别人的时候,没有hack成功,但是和同学讨论hack思路之后,他们hack成功
第三次作业
(1)设计策略
在第二次的基础之上,增加了特定层数可以停靠,也就代表着需要换程。
分析发现,所有楼层,最多一次换乘就可以达到,所以每个人进入之后,先交给调度器,规定好他的换乘楼层是哪里。
如果不用换乘,就直接把换乘楼层标记为目的地。
然后选择合适的电梯,加入电梯队列。
电梯只是负责把人送到他们的换乘地点,然后判断如果这个人换乘地点是目的地,就不用管他,
如果这个人换乘不是目的地,就塞回给调度器重新分配。
(2)可拓展性
主要是选择合适的换乘楼层和电梯。这次作业实现的时候,并没有仔细思考换乘策略,而是找到能换乘的站,就换乘。
这就导致了换乘有时候绕了一大圈远路,十分麻烦。
换乘策略上面有很大的拓展性。
(3)度量分析
总的来说,最核心的复杂度,在于选择合适的电梯换乘,以及选择合适的换乘站,这两个地方。
其中,选择合适的换乘站几乎占了复杂度的全部。
其他地方几乎还是和以前一样。
本次设计依然违背了DIP原则,没有对着接口设计,以及因此导致的开闭原则受到影响。
这次的类的设计上面很混乱,类与类的包含关系也十分混乱,有很大的重新架构,减少耦合的空间。
除此之外,单一原则也没有实现好,因为加新电梯的任务,也交给了调度器。
由于没有自己设计接口,接口分离原则无法实现或者没实现。
(4)自己bug与别人bug
这次最大的bug在于中止判断。三个电梯,必须等待所有人运完才可以停止,因为如果电梯有人需要换乘,但是其他电梯以及关闭的话,就会出bug。
本人在课下被这个bug卡住,也想去hack其他人,但是失败了。
除此之外,针对新增电梯的hack,也没成功。
总结与感悟
经过第二单元学习,对于多线程,线程同步,线程信息交换等概念都有了一定程度的掌握,多线程是一个重要的技术,但是也带来各种各样意想不到的问题,不单单是程序本身逻辑问题,各种不确定性也会带来各种问题。这一单元的学习中,学了各种手段来对抗不确定性,最大程度的发扬多线程的优势,减少他的问题。