OO第二次博客作业

一、第五次作业

1.1 多线程的协同和同步控制

这次作业没有考虑优化,直接使用单个请求单独运送的方式。主要利用生产者-消费者模式,以输入线程为生产者,将电梯作为消费者,调度器作为缓冲区。

一共有两个线程:1. 输入线程,作为生产者。

        2. 电梯线程,作为消费者。

每次当输入线程中有了新的请求进入,调度器就将请求转发给电梯,电梯完成一次运送后,再从调度器中取下一个请求。

1.2 程序结构分析

1.3 优缺点分析

优点:

实现十分的简单直接,没有bug。

缺点:

Elevator中run方法的复杂度略高,可以对于Elevator的功能进行进一步的拆分,Elevator的功能应该仅仅负责听从Scheduler的指令上下以及开关门,更有助于降低耦合。

1.4 程序bug

本次作业在公测和互测中没有被发现bug。

1.5 发现bug

本次作业较为简单,尝试提交了一些较为极端的测试用例(如在规则限制内卡时间,首尾输入留出很大间隔来测试其是否会提前终止),但是在我的room中没有发现别人的bug。

 二、第六次作业

2.1 多线程的协同和同步控制

本次虽然仍然只有一部电梯,所以大体沿用上一次作业的架构,设置了电梯线程和输入线程,输入线程作为生产者,电梯作为消费者。

调度器负责进行电梯与输入之间的交互,从输入线程获取PersonRequest,并且将每一楼层的进入和输出请求传递给电梯。

与上一次作业的不同点在于,这次使用的是ALS调度,需要在每一楼层单独分析是否需要捎带。在Scheduler中维护了一个请求队列,请求队列的插入和删除需要保证同步。

2.2 程序结构分析

 本次作业对于Scheduler进行了捎带相关的扩充,并且增加了Person类对于原本的PersonRequest类进行的升级,添加了是否已经进入电梯(isLoaded)和上下方向(direction)等几个属性,便于捎带请求的判断。

仍然是run方法飘红,这次作业在延续上次作业代码结构的同时也没有改掉run方法的缺陷。

2.3 优缺点分析

优点:

进行了较为鲁棒的测试,没有出现bug。

进行了灵活编码,本次作业的代码在下一次作业中被大规模沿用(比如电梯上下楼时间等量我使用的是宏定义,在下一次作业中仅仅只需要更改少量代码就可以完成复用)。

缺点:

Elevator中run方法的复杂度仍然略高,降低耦合的重视性不够。

2.4 程序bug

本次作业没有出现bug

2.5 如何发现别人的bug

 借用了讨论区某大佬的测试接口,使我的输入能够对于输入的时间有更为精确的控制,但在发现了几个本地测试中的超时bug后交上去时却没有奏效。可能是本地与评测机环境有所不同造成的误判。

三、第七次作业

3.1 多线程的协同和同步控制

本次作业设计多电梯的调度,电梯运行速率以及到达楼层不同,并且不是所有请求均可以直达,换乘时需要考虑多部电梯的轮换。

在换乘问题的处理上,我是优先判断能否直达,将能够直达的优先送达,需要换乘则将目标楼层依据可以换乘楼层进行修改,并且设置标志位,在出电梯时再将起始楼层和目标楼层进行修改,重新放回Scheduler的请求队列中。

Scheduler设置了两级:

  • 第一级是GlobalScheduler,负责从输入线程取请求,并且将请求调配给每一个二级Scheduler。
  • 第二级是每个电梯单独的Scheduler,负责从GlobalScheduler获取请求,并且将请求像上一次作业一样分配给每一个电梯。

三部电梯对于GlobalScheduler的请求队列的访问可能出现线程安全问题,所以需要进行阻塞。我使用LinkedBlockingQueue,利用put和take方法将请求队列同时被操作时锁住。

在每个电梯单独的Scheduler的线程安全的处理问题上,我还是复用的是上一次作业中的对方法加锁的模式。Scheduler的对象是单独传递给相应的Elevator对象,避免不对应的Scheduler与Elevator出现交叉。

3.2 程序结构分析

本次作业的代码绝大部分是沿用的上一次的,添加了一个GlobalScheduler负责宏观上的调控,GlobalScheduler的功能在前一小节部分已经说的很清楚了,我就不再赘述了。

在沿用代码的过程中run方法的问题始终存在,GlobalScheduler在进行请求相关操作时复杂度偏高。

3.3 优缺点分析

优点:

没有出现什么bug。

缺点:

一味沿用了第二次的代码,对于性能问题考虑不是很到位,ALS算法在这种随机数据测试时劣势很大,应该进行重构,尝试使用Look算法。

3.4 程序bug

本次作业没有出现bug

3.5 如何发现别人的bug

没有在同组同学的代码中发现bug。

四、心得体会

1. 应当尽量软编码,不要写死。

无论是OO的作业还是日后走上工作岗位从事软件开发,我们的目标都不只是需要一个软件的实现,更需要软件能够很好的修改,方便扩展。所以需要提前进行一些设计上的考量,便于对程序进一步重构,我们目的就是实现对象之间的松耦合,使程序能够应对多种情况下的变化,具有一定的扩展性。

2. 提前做好设计再开始写代码。

第七次作业有点仓促,导致花了半天写完了,却用了两天时间debug,在debug过程中需要对本次作业进行了很多冗余测试,很多bug是由于设计上的不周导致的(例如我由于电梯换乘后提前终止导致了中测最后一个点花了很长时间才过)。

从中吸取的教训就是提前对于整体的设计进行充分的思考,对于架构以及优化做出事先的考量,避免debug浪费过多时间。

3. 要善于利用多线程调试工具。

使用诸如https://github.com/HansBug/debug_logger的工具,将信息输出可以使得调试信息简单明了。

posted @ 2019-04-22 23:27  sherpahu  阅读(148)  评论(0编辑  收藏  举报