OO第二单元の小结
第二单元(线程与电梯问题)总结博客
三次作业的设计策略
第一次:本次作业只有一部电梯,而且不用捎带。因此,我一共设计了两个线程:一个负责管理输入,一个负责电梯运行。同时,我将调度队列设置为单例模式,里面存储着一个队列。由于是存一次取一次,所以我在该单例模式中的方法使用了生产者消费者模式:input一个,get一个。
第二次:本次作业依旧是一部电梯,但是需要捎带。由于本质上还是一部电梯,所以我依旧没把调度器写成线程。依旧是一个线程负责输入,一个线程负责电梯运行。但是这次由于要稍带,调度器的方法就不能是互斥的生产者消费者模式了,因为每运行到一层都需要判断捎带。
第三次:本次作业变成了三部电梯,也需要捎带。三部电梯,自然要三个线程。处理输入也需要一个线程。在调度器我们需要将总队列内的任务分配到三个电梯的请求队列中,因此,调度器也是一个线程。
程序结构度量分析


第一次:由于本次作业较为简单,每个类的功能单一,因此,自己感觉设计得没有什么缺点,或许值得改进的地方是要将调度器也改成一个线程,这样更方便之后任务的拓展。


第二次:本次作业附带了捎带,而每层判断的捎带算法由于嵌套了大量if,复杂度飙升。或许应该再另写一类协助处理这个方法。还有个比较大的问题:elevator类中的方法过多,违反了SOLID原则中的单一功能原则,我应该将elevator中的方法分类、写到新的类中,由elevator调用,这样方便类的扩展。


第三次:这次的作业由于非主线程多于两个,因此,我要说一说线程之间的关系。但是,其实很简单:主线程将剩余的几个线程建立,由电梯线程结束所有运行线程。而线程之间的沟通利用的是几个容器类,也就是说,线程间不会直接交互,这样也保证了线程安全。
设计的缺点,最大的一点是我三个电梯分别写了三个类。我应该写一个基类再分别取继承这个电梯基类,这是设计中的重大失误,增加了代码复用,违背了设计原则。另一点和第二次的电梯作业一样:我应该把一些方法放在一个方法类中,被电梯线程调用,也许一部电梯时问题不大,但到了多部电梯,我就发现代码复用的问题了:不方便调试以及扩展。
BUG分析
第一次和第三次作业,公测样例全部通过,互测也没有bug,故不谈。(主要是第三次作业采取了很怂的调度方法,只追求正确性而没有考虑运行性能,虽然公测的点全部AC,但是性能分都是85)。故主要谈第二次作业的问题,第二次作业算上互测一共被hack了12次。而我修改三行就修复了其中11个bug。究其原因,是我的调度逻辑出现了问题。我在电梯的出发层不是当前楼层时,将请求加入了电梯队列,但是在前往出发层时,我进行了捎带,甚至捎带了与主请求运行方向相反的请求,导致根本没有接到人就去送人了,又由于主请求还在电梯队列内,导致出现了无中生有放人出去的窘况。于是我加了三行代码,电梯在前往接人的时候不会捎带,这样就修复了几乎全部的bug(摊手)。还省的一个bug有些怪异,电梯队列内遗留了最后一个请求然后停止了。于是我加了一个判断语句,解决了问题。
BUG策略
第一次作业由于电梯实在太傻瓜了,hack不到别人。第二次作业主要考察捎带的判断,有没有漏人或者关人,主要判断反向请求是否会接受。第三次作业主要判断…我个人感觉是判断三部电梯接人是否会重复。三次作业我都没能够hack成功一次,真是非常惭愧。
这个单元和上个单元相比,由于正确性以及性能全部交给强测判断了,我们能判断的,也只有调度算法是否有逻辑错误以及线程安全的问题了,而第一单元的作业追求的是绝对的运算正确。但本次作业,比如说第三次作业,错误是很难复现的,尤其是cpu运行时间的错误,线程的错误往往是不能复现的,这为debug制造了困难。
心得体会
由于本人对线程比较感兴趣,所以这次的作业相比上次写起来还是愉悦不少的。本人对于线程的理解是:安全第一、优化第二。为了时间的优化而忽视了线程本身的安全性,我觉得是舍本逐末的行为。因此,虽然第三次作业的性能分比较低,但我宁愿让乘坐我电梯的乘客稍事等候,也不希望他们陷入不安全的情况下,抑或是为了速度疯狂换乘。就当是我的小小执念罢。
OO第二单元の小结的更多相关文章
- OO第二单元小结
OO第二单元小结 一.三次作业代码分析. 1.第一次作业 第一次作业是单部电梯的傻瓜调度,由于其过分傻瓜,所以第一次作业我只有两个类,一个main,一个电梯,main类负责不断从输入流中读取命令,如果 ...
- oo第二单元作业总结
oo第二单元博客总结 在第一单元求导结束后,迎来了第二单元的多线程电梯的问题,在本单元前两次作业中个人主要应用两个线程,采用“生产者-消费者”模式和共享数据变量的方式解决问题.在第三次作业中加入多个电 ...
- OO第二单元优化博客
OO第二单元优化博客 第五次作业没有性能分,但是,我在这一单元的宗旨就是写一个日常生活中 最常见的那种电梯,所以第五次我没有写傻瓜电梯,而是直接写了个\(look\),和第六次基本相同. 总计一下lo ...
- 【OO学习】OO第二单元作业总结
OO第二单元作业总结 在第二单元作业中,我们通过多线程的手段实现了电梯调度,前两次作业是单电梯调度,第三次作业是多电梯调度.这个单元中的性能分要求是完成所有请求的时间最短,因此在简单实现电梯调度的基础 ...
- OO第二单元多线程电梯总结
OO第二单元多线程电梯总结 第一次作业 设计思路 Input为输入线程,负责不断读取请求并将读到的请求放入调度器中. Dispatcher为调度器,是Input线程和Elevator线程的共享对象,采 ...
- 电梯也能无为而治——oo第二单元作业总结
oo第二单元作业总结 一.设计策略与质量分析 第一次作业 设计策略 在第一次作业之前,我首先确定了生产者--消费者模式的大体架构,即由输入线程(可与主线程合并)充当生产者,电梯线程充当消费者,二者不直 ...
- 2020北航OO第二单元总结
2020北航OO第二单元总结 前言 本单元考察基于多线程的电梯调度问题,成功让我从一个多线程小白到了基本掌握了使用锁来控制线程安全的能力,收获颇多(充分体验了迷茫地de一个又一个死锁bug的痛苦). ...
- OO第二单元——多线程(电梯)
OO第二单元--多线程(电梯) 综述 第二单元的三次联系作业都写电梯,要求逐步提高,对于多线程的掌握也进一步加深.本次作业全部都给出了输入输出文件,也就避免了正则表达式判断输入输出是否合法的问题. 第 ...
- OO第二单元作业小结
前言 转眼已是第九周,第二单元的电梯系列作业已经结束,终于体验了一番多线程电梯之旅. 第一次作业是单电梯的傻瓜调度,虽然是第一次写多线程,但在课程PPT的指引下,写起来还是非常容易:第二次作业是单电梯 ...
随机推荐
- java工具类 --千分位方法
/** * 千分位方法 * @param text * @return */ public static String fmtMicrometer(String text) { DecimalForm ...
- 多因子降维法(MDR,Multifactor Dimensionality Reduction )
多因子降维法(MDR,multifactor dimensionality reduction) 多因子降维法(MDR,Multifactor Dimensionality Reduction ) ...
- [GO] go使用etcd和watch方法进行实时的配置变更
监控代码 package main import ( "go.etcd.io/etcd/clientv3" "time" "fmt" &qu ...
- zTree的简单使用
理论可以看:http://www.cnblogs.com/shinhwazt/p/5828031.html zTree包:链接:http://pan.baidu.com/s/1eR4xP6M 密码:w ...
- 深海划水队项目--七天冲刺之day6
站立式会议:由于有位项目组成员回家了,所以由微信群在线讨论代替. 昨天已完成的任务:界面优化,实现方块的移动,旋转和下降. 今天已完成的任务:设置游戏按键,检查重合.检查是否超出边界.检查是否可以下落 ...
- linux 进程通信之 管道和FIFO
进程间通信:IPC概念 IPC:Interprocess Communication,通过内核提供的缓冲区进行数据交换的机制. IPC通信的方式: pipe:管道(最简单) fifo:有名管道 mma ...
- wp8.1 SQLite的基本使用
SQLite是一个轻量级的关系型数据库,正是由于其精悍小巧,在移动端平台被广泛应用,但不适合处理大量数据和批量操作.它的底层是由C语言编写,最初设计是为了应用于嵌入式,占用资源非常低且简单易用,而且绝 ...
- nutch-2.2.1 hadoop-1.2.1 hbase-0.92.1 集群部署(实用)
原文地址: http://www.cnblogs.com/i80386/p/3540389.html 参考网站:http://blog.csdn.net/weijonathan/article/det ...
- jmeter测试mysql数据库之JDBC请求
所有jmeter基本组件功能本文不做介绍.jmeter要链接mysql数据库,首先得下载mysql jdbc驱动包(注:驱动包的版本一定要与你数据库的版本匹配,驱动版本低于mysql版本有可能会导致连 ...
- jenkins pipeline中执行nohup java -jar ***.jar & 的时候会忽略执行jar之后的命令
搜索关键词:pipeline中执行nohup时忽略执行& 问题: 在做自动化部署的时候,脚本如下: sh "ssh root@'$target_ip' nohup '$java_ho ...