第五次作业
说明
第五次作业是虽然也是电梯,但是在设计上与第三次作业有很大的不同。我使用了ReqConsumer类,ReqProducer类,ReqTray类,Elevator类和Request类。
前三个类顾名思义是模拟生产者-消费者模型的。从控制台输入的指令经过ReqProducerr中的字符串处理方法检查是否合法,然后加入请求托盘,等待消费者来取走。ReqTray类中定义了一个容器来存放这些请求。ReqConsumer从托盘中取出请求然后调用调度器方法,调度器将这些请求分配给三个电梯。电梯来执行请求。
前四个类分别都是一个线程,不断的将输入传给调度器然后即使送给电梯来处理,电梯就不断的运行。
发现的bug
这次是简单的多线程应用,而且捎带的问题已经解决过了,所以程序公测和互测都没有测出bug
测试bug的方法
就是先看看程序的基本功能是否正确,比如在一些边界情况下捎带是否正确,是否每次选择累计运动量最少的进行分配。然后这些都没有问题,就用把很多情况组合起来测试,一般总能发现问题。
优缺点
优点:运用了很标准的生产者消费者模型,并且在很大程度上保证了线程之间的安全。
缺点:对三个电梯线程分开管理,用不同的变量名命名,所以在分配请求时显得十分繁琐。
Metrics
类图
时序图
第六次作业
程序说明
第六次作业的内容是文件的监控系统。整个程序有一个处理输入的线程InputHandler,不断的处理来自控制台的输入。对于每一个输入,如果合法,就创建一个监视器线程对于这个文件进行相应类型的监控。最重要的是一个SafeFile类,把相当于创建一个File类的对象,但是把File类中的方法锁起来,让他们线程安全,就可以保证不同监视器在读取文件状态和不同测试线程在改变文件属性的过程是线程安全的。每一个监视器都会不断的扫描他所处的监控范围,通过一定的算法来检测文件是否发生了要检测的改变。
发现的bug
这次的bug主要集中在对不同改变的检测上,比如两个监视器如果检测同一个文件,他们之间的优先级,如果一个文件改动了还该不该继续监视。大体上的都没有什么问题,但如果不注意一些小的细节会在一些地方出很多错误并且极难调试。
对目录进行监视时通常需要通过递归来解决,以前没有怎么用过,在写的时候有很多没有考虑到的点,比如递归的结束条件,递归的最终返回值都需要产生了很多问题。
测试bug的方法
这次测试bug主要也是从自己发现的bug的角度来看,首先把错误分支树上公测没有测过的点都测试一遍,这是基本功能,还有的就是如果开多个监视器线程,线程之间会不会产生不安全的情况。其次就是detail,summary输出的有没有问题。
优缺点
优点:能够熟练的开线程管理线程之间的关系了,在绝大多数情况下程序是线程安全的。
缺点:对于文件的操作不熟悉,以及对于一些嵌套,边界情况考虑不周,大体上都对,但是很多细碎的点还是会出bug。
Metrics
类图
时序图
第七次作业
程序说明
第七次作业进入了出租车的领域,刚开始看到出租车的时候感觉很害怕,觉得这么多车,这么复杂的地图,应该会很难,但实际上我感觉到的难度没有IFTTT难,可能是已经比较熟练掌握了多线程的编程结构吧.
先通过一个类MapReader来读取地图,然后通过一个InputHandler线程来处理输入,判断输入的格式坐标是否满足要求.如果符合要求就给这个请求分配一个scheduler线程.scheduler获取这个请求的所有信息包括发出地目的地和请求时间,在三秒内不断检索出租车队列,访问出租车当前状态.将满足要求的出租车放进一个抢单队列里,三秒结束后在抢单队列里选信用度最高的车进行派单.然后这个线程结束.出租车在收到信号后,改变自身状态行驶,先去接人然后再把人送到相应的位置.
发现的bug
就是刚开始没有看清楚在信用度一样的条件下选最近的,还有就是在找最短路径时刚开始用递归写,非常浪费时间,后来用了队列模拟就好了.
测试bug的方法
这次程序的测试方法应该说与以前不一样,对于一些细节性的问题,即使在gui中发现了bug也很难复现,这就需要去读代码来找出哪一块设计有问题,还是十分有难度的.
优缺点
优点:结构比较清晰,各个线程之间共享的资源很安全.构建代码的时候就在每一步操作后输出提示信息,这样后面调试起来就比较方便.
缺点:BFS还是只针对无向无权图的最短路径搜索,还没有考虑过更复杂的图最短路径搜索的方法
Metrics
类图
时序图