OO第二单元总结

面向对象第二单元总结

一、第五次作业

1.设计思路

​ 第五次作业我挂掉了,原因主要是第一次接触多线程很多细节方面的东西了解的不是非常深入,导致出现了许多自己意料之外的bug,究其本源还是在线程控制和线程安全方面存在着一些问题,经过一段时间的修改之后实现的第五次作业的架构如下。

​ 第五次作业中不包含调度器,主要由输入线程和电梯线程组成。两线程之间通过共享对象waitqueue进行信息交互,输入线程将stdin中的请求信息存入等待队列waitqueue之中,电梯类中包含电梯内部的乘客队列,当电梯未满时在适当的楼层会从等待队列中提取出相应的请求执行。

​ Morning模式下电梯会在1楼进行等待,待人满之后一次性将乘客送往目的楼层,由于此模式下有要求乘客到达间隔不超过两秒,所以认为等人满后再运行节省的时间要比等待时间多。

​ Night模式下电梯会自动到达乘客请求队列的最高层,从上至下一次接待乘客,人满之后停止进入直接回到一层。然后重复上述过程直至接送完毕。

​ Random模式下,电梯实时处理请求,如果在处理请求的途中电梯非空且请求可以进入,则采用捎带原则将该乘客引入。

2.同步块设计

​ InputThread和Elevator之间共享对象waitQueue,InputThread将Request添加到waitQueue之中,Elevator从waitQueue之中取出Request。为waitQueue加锁,以保证线程之间的互斥,维护线程安全。

3.bug分析

​ 本次作业由于并没有提交成功,故没有互测hack其他人的环节,因此只对自己在本次作业中没改正过来的bug进行了修复。这次作业最主要的bug是由于我在主函数中创建了一个对象elevatorInput读取电梯模式,同时在InputThread线程中创建了一个elevatorInput读取用户请求,这种方法会导致前面有的请求信息无法进入请求队列,导致所有的测试点都无法通过,虽然我也不知道为什么。最后的解决办法是将Mainclass中的elevatorInput传入InputThread中。

​ 其他的bug属于一些基础设计的问题,例如sleep的顺序问题,以及某些模式下的行为错误,由于是设计逻辑方面的问题所以就不在这里一一赘述了。

4.类图分析

image

二、第六次作业

1.设计思路

​ 本次作业沿用了第五次作业的设计,增加了电梯队列以实现电梯的动态增长情况,为电梯类增加了单独内部等待队列以方便调度器分配,同时增加了调度器来给三个电梯分配任务请求。

​ 调度器的设计采用的是随机分配的方式,将到来的请求按照顺序一次分给电梯等待队列里面的电梯执行,优点是简单便捷。缺点是经常会出现单个电梯执行的时间过长而导致整体的时间过长。

2.同步块设计

​ 相较于第五次作业,此次作业中在InputThread和Schedular(调度器线程)之间增加了共享对象elevatorarraylist(电梯序列),实现电梯的实时增加,并且实现线程同步。

3.bug分析

​ 在写程序的过程中出现最多的bug是程序无法正常结束,即无法停止。发现自己有许多线程的设计逻辑上无法跳出循环,修复后成功解决了这些问题。

​ 本次作业强测出现了两个bug,第一个bug是在程序运行后期频繁出现大量的请求,由于设计分配的随机性导致其中一个电梯的运行时间超时,最终被hack;第二个bug是由于Night模式下的电梯设计逻辑出现了问题导致某种特殊情况下电梯无法正常停止,最终超时。第二个bug通过修改代码成功解决,但是第一个bug由于涉及策略问题,最终没有解决。

4.类图分析

image

三、第七次作业

1.设计思路

​ 本次作业继续使用了以前作业的设计,区别的是为每一部电梯type属性,并将移动时间,最大承载人数等内容添加到类中,并修改构造方法。调度器这次的策略是接到一个请求时优先考虑C类型的电梯,再考虑B类型的电梯,再考虑A类型的电梯,由于架构设计出现了问题导致换乘的处理方式及其复杂,最后出现了负优化,故没有材料换成策略。

2.同步块设计

​ 本次作业中的同步块设计沿用第六周的设计,没有太大的变化。

3.bug分析

​ 这次作业的强测和互测之中未被检测出bug,但写程序的过程中还是出现了一些bug,例如在进行优先级匹配的过程中的匹配逻辑出现问题导致将错误的请求发送到错误的电梯当中,最终使得电梯的功能错误。并且在修改代码中没有时刻注意代码之间的逻辑关系,导致出现了程序无法结束的情况,但有了第二次作业的经验,这类型的bug修复的较快。虽然本次强测和互测都没有被hack,但看到其他大佬的工作之后发现自己做的还是远远不够,下一次继续加油。

4.类图分析

image

四、互测bug策略

​ 手动构造相关的测试点,第二次构造的测试点主要是针对某些特定的调度算法设计测试点,例如,我知道我随机调度的缺点,因此把一些耗时长的请求都加入到其中某一个电梯之中,所以会使某一个电梯的耗时急剧增加导致整体程序的性能不佳。第三次构造的测试点,主要是B、C类型的电梯无法直接送达但是距离较长的情况,如果没有换乘会导致时间花费较多。

​ 和第一单元相比,本单元的bug并非侧重于正确性而是侧重与性能,主要是用来hack调度器的。而第一单元的hack策略则是侧重于特殊表达式的求导正确性。

五、心得体会

  • 本单元的难点主要体现在多线程的线程控制上,线程之间如何设置同步块,如何避免死锁问题的出现都是初期学习中较难的点。也正是因为一开始线程控制设置的不好导致了第五次作业出现了一些问题导致没有通过。
  • 在本单元线程安全的学习过程中,我发现各学科的体系之间是有联系的。操作系统课程中同步学习了信号量、PV操作的相关知识,通过本单元的学习也让我在操作系统课程的相关知识的理解上轻松了许多。
  • 层次化设计方面的重要性更加体现了出来,第七次作业失误的原因就是因为前两次作业层次化设计做的不够好,电梯与请求队列的联系过于紧密,无法分离,导致换乘方案的设计变得极其困难,最后不得不放弃。因此以后在程序设计之前一定要架构好程序的整体框架,思考可扩展性的要求。
  • 层次化设计是在进行实践之前就要确定下来的,需要根据实际问题的需求提前确定好层次需求,每个层次负责处理好自己的功能任务,并需要保证尽量的独立于其他层次。不仅仅是在程序设计的过程中需要考虑层次化,在解决任何问题的时候,层次划分都能够帮助我们做到事半功倍。
  • 这次作业的收获与第一次作业有所不同,第一次作业中更多的是实现了由面向过程向面向对象的转变,没有面向对象的思想会导致第一次作业的设计失败。而本次作业则是我第一次尝试多线程,在学习之前一直认为这是一个非常高大上的东西而不敢去接触,第五次作业实现的过程中也非常抵触,但是真正理解之后发现其实也没有那么难。万事开头难。
posted @ 2021-04-27 21:02  xiaominga  阅读(42)  评论(0编辑  收藏  举报