OO第二单元总结

2019面向对象课程序设计第二单元总结

面向对象程序设计第二单元的作业是三次电梯调度,主要训练的是我们多线程相关的知识:如何写多线程程序,学习使用生产者消费者模式,同步和互斥等。相比第一次作业,这一次的作业完成得相对简单一点。一方面,这一次不用处理输入输出,不用考虑非法输入确实减少了不少工作量,另一方面,经过第一单元的练习,我们对java语言已经面向对象程序设计思想有了进一步的了解。但是,这一次的作业我完成得并不太理想,下面是我对本单元作业的分析。

一、 历次作业分析

1. 第五次作业分析

结构分析

 

第五次作业我分了四个类,两个线程。Main类一个线程,用于处理输入,并将请求存进请求队列中,Scheduler调度器线程,用来从请求队列中读取队列,并控制电梯。Requests类用来存取请求,建立一个Arraylist,采用生产者消费者模式保证线程安全。

难点及解决方法

第一次作业相对比较简单,出现过的困难有两个:一个是线程之间的安全问题,另一个是程序结束的问题

前者可以根据课件的内容,稍加修改就能结局。而关于程序的结束,我才用的方法是,如果主线程读到NULL,主线程结束,电梯线程读到NULL,直接exit(这样也为后来的作业带来了一些问题)

由于第一次的作业比较简单,调度也是性能最差的傻瓜调度,所以除了程序结束的判断,并没有遇到什么有代表性的bug,互测中也没有出现。

2. 第六次作业分析

结构分析

 

在这一次的作业中,我在上一次的结构上做了一定的修改,Main类基本不变。电梯类一个线程,每到一层从请求队列中读取请求,根据请求运动。调度器写在请求队列中,当电梯取请求时,根据电梯当前的位置与运行方向决定分给电梯哪些请求。

我的捎带策略如下:

(1)电梯为空,取主请求。

(2)在电梯前往接主请求的过程中进行捎带,但保证电梯在一次换向内能接到主请求。

(3)主请求已经在电梯中,根据主请求移动,同时,每到一层,将电梯的运行状态反馈给调度器,调度器根据电梯当前的运行方向及楼层分配请求。

(4)每当主请求已出电梯但电梯不为空时,选择最早到的请求为主请求一直到电梯为空.

bug分析

这次的bug主要是“飞天遁地”的bug,在自己的程序中以及互测中都有出现。就我的程序而言,出现这种bug的原因是某个请求本应出电梯但是并未出去,导致电梯不为空而且始终不会换向。导致电梯到达的楼层超过楼层限制。

该bug产生的具体原因是在确定主请求是应为Math.abs(tofloor - fromfloor)但我错误的写成了Math.abs(tofllor)-fromfloor。因为这个bug在强测中挂掉特别多的测试点。

(这次的bug告诉我通过中策之后进行测试真的很重要,一组随机生成的数据都能很容易的发现我的这个bug)

3. 第七次作业分析

结构分析

 

 这一次的作业在上衣的基础上添加了两台电梯,并且每台电梯的运行时间,能到达的楼层是不同的。在这一次的作业中,我主要修改了调度器和请求队列,请求队列分为三个,同样是从主线程读入请求,然后调度器根据三台电梯能到的楼层确定请求应该放在那个请求队列中。同时确定应该怎样换乘。由于在我写代码时并不支持对于请求的修改,所以我新建了一个请求类。

分别存原请求,是否需要换乘,现在是换乘的第几个阶段。

另外,在本次作业中遇到的另一个困难是程序结束的时间问题:

(1)由于在第一次作业中,电梯线程读到NULL就直接exit,所以导致这一次作业中,某一个线程读到NULL程序结束,产生错误

(2)出先的另一个错误是,某个电梯读到NULL,线程结束,换乘请求到来,由于电梯已经停止运行,产生错误。

bug分析

吸取上一次的教训,这一次我在通过中测后进行了很多测试,所以并没有出现影响强侧正确性的bug,但出现了影响性能的bug:误将B电梯的15楼设置为不可达,带来了很多不必要的时间开支。另外,由于这一次的作业涉及三台电梯同时工作,所以为了更方便的找出自己作业中的错误,可以另写程序对输出结果进行检测,我的思路如下:

(1)对于三个电梯分别建立三个对象,检验电梯移动,开门时间是否符合要求,电梯开门楼层是否正确,是否出现跳层现象

(2)对于每一个乘客,建立一个对象,检测其是否到达,是否出现乘客滞留。

 线程安全问题

在这一次的作业中,有三台电梯同时运动,每台电梯一个线程,每台电梯之间都存在线程安全问题,我的解决思路如下:
(1)为每一台电梯建立一个单独的队列,由调度器分配请求,每台电梯在对应的队列中取请求,而不建立单独队列。

(2)对于指导书中提到的输出接口的线程安全问题,可以在主类中建立lock对象,所有电梯类共享一个lock对象,每当输出时,加锁。

 二、 SOLID原则

SRP原则:本次作业中,每个类只对自己负责

OCP原则:所有变量都为private,方法根据用途分为private和public

LSP原则:本次作业不涉及继承

DIP原则:没有使用接口

ISP原则:没有使用抽象类

三、 心得体会

经过三次作业,从开始的不懂多线程到能写出多线程程序,解决不同线程之间的竞争问题。另外,与上一单元作业相比,每次作业重构的代码变少了(第一单元作业中,每一次代码都基本重构了),在本单元作业中,每一次完成代码时,都考虑到了怎样设计才能够让后续的扩展更加简单。所以,相比起来,能够在更少的时间里完成更多的工作。在本单元作业中仍然存在很多不足,主要体现在验证方面,因为多线程程序相对难debug,所以在前两次作业中并没有多花时间验证程序正确性,也因此挂了第二次强测。

总的来说,这单元的作业也有不少的收获。希望在以后的作业中也能不断进步,提高能力。

 

posted @ 2019-04-22 21:09  17373462  阅读(128)  评论(0编辑  收藏  举报