OO第二次单元总结

OO第二次单元总结

前言

第二单元的三次作业:系列电梯与多线程。

第五次作业

(1)设计策略

电梯的第一次作业是单部傻瓜电梯,采用FAFS调度策略,电梯按队列顺序依次处理请求,单次只处理一个请求。本次作业采用了简单的生产者-消费者模式,而调度器则采用了单例模式。

(2)基于度量来分析自己的程序结构

类图:

复杂度分析:

依赖度分析:

本次作业很简单,共设计了四个类,除主线程外包含一个请求输入线程和一个电梯线程。Scheduler类为单例模式调度器,内部有一个请求队列。Input类负责请求的获取和存入,每当获取到一个有效请求时,调用调度器中add方法存入队列。Elevator类为电梯类,调用调度器中getArray方法获取请求并执行。类各有分工,便于拓展下一次作业。

(3)分析自己程序的bug

由于本次作业调度方法很简单,线程交互也不复杂,所以在公测和互测中并没有发现bug。但在写的过程中遇到的最大问题是无法关闭电梯线程,后得到解决。

(4)分析自己发现别人程序bug所采用的策略

由于设计简单,大部分人代码量很小,所以主要采用了阅读代码的方式寻找别人的bug。

第六次作业

(1)设计策略

电梯的第二次作业为单部可捎带电梯,采用ALS调度策略。和上一次作业相比,只是增加了负楼层以及改变了调度策略,因此设计模式完全继承于上一次作业,做出了部分改变。

(2)基于度量来分析自己的程序结构

类图:

复杂度分析:

依赖度分析:

本次作业也是四个类,除主线程外两个线程。Scheduler类调度器负责存储和分配请求。Input类负责请求的获取和存入。这次,在Elevator类中增加了一个请求队列,用于存储主请求及其可捎带请求,电梯每到一层与请求队列进行交互,从而判断乘客的进出。由于设计缺陷,Elevator.run方法过长,从由图中可以看出,其复杂度很高。

(3)分析自己程序的bug

由于最后时间紧迫,这次作业在写完进行很简单测试后便提交了,通过了中测。但在强测中,发现了致命bug而未进入互测。bug不涉及线程安全,而是调度算法的缺陷,当电梯到达某一楼层时,我采取先下后上,当全部下去后(队列为空),我需要从队列取出主请求,来判断是否可以上,这时便会报错error。当我改成先上后下,问题就不存在了。之后应该合理安排时间,多编写测试样例,避免低级错误。

第七次作业

(1)设计策略

电梯的第三次作业为多部多线程智能(SS)电梯。单部电梯的调度策略上,我仍采用了上一次作业的可捎带(ALS)调度。和上一次作业相比,由一部电梯变为三部电梯,而且这三部电梯的可停靠楼层、运行时间、最大载客量都不相同。最大的限制在于可停靠楼层不同,因此乘客可能需要在中间换乘才能到达目的地。最后,我采用了最简单直接的方法,将请求固定地拆分成两个请求,然后存入队列,等待执行。因此,本次作业设计模式基本继承于第二次作业,并做出了部分改变。

(2)基于度量来分析自己的程序结构

类图:

复杂度分析:

依赖度分析:

本次作业共五个类,除主线程外一个输入线程,三个电梯线程。这次新增加了一个Request类,用于将PersonRequest拆分后封装新的请求,有五个属性,增加了id和request,分别用于存放执行电梯号和换乘前请求。其它类的功能和上一次作业一样。Elevator.run方法继承于上一次的代码,由于时间不够,过长的问题没有解决。由于调度器的调度方法采用硬编码的形式,由一系列if-else组成,因此很明显,Scheduler.add方法复杂度很高,几乎无法拓展。

(3)分析自己程序的bug

性能较差,但在公测和互测中并没有发现bug。

(4)分析自己发现别人程序bug所采用的策略

在互测中仍主要依靠阅读代码来发现bug,但效果很不好。

总结

这一单元三次电梯作业让我们对多线程有了由浅入深的了解。但抛去暴力轮询的方法,我对wait和notifyall的使用还不够熟练,总会出现很多问题,在之后的学习中会多加练习,争取掌握。此外,在代码设计上仍有很大的不足,缺乏明确的设计而导致部分方法过长,先写后修难度很大,复杂度也很高,之后的作业中,要尽量在写之前设计分配好各方法,对代码风格和debug都有帮助。下一单元,继续努力!

posted on 2019-04-24 20:51  Hefarry  阅读(144)  评论(1编辑  收藏  举报