第一部分:三次作业设计策略分析

第五次作业

电梯建了一个类,电梯管理着楼层信息,包括哪一层有哪些人要接,哪些人要送

调度器建了一个类,管理电梯的调度,维护一个Target队列,每次新来一个人,调度器会更新Target,电梯每进来一个人,也会更新Target;

程序开始,电梯从调度器得到一个target,并运行过去,如果尚未达到Target,且中途遇到某一层外面有人,还是会选择开门,将那个人拉进来。每次开门,都会启动remove和pick两个线程,remove负责送人,pick负责接人,同时修改调度器的Target

第六次作业

结构同上,只不过优化了电梯从调度器哪里getTarget的方法,用来提升了性能

第七次作业

这次作业三个电梯,且都有人数上限,还有换乘,于是设计了一个等级调度。每个电梯配备一个子调度器,电梯从自己的自调度器得到下一个目标;此外还有一个高级调度器,负责读取请求,并分配给相应的子调度器。

乘客分两种情况,一种是可以通过某一个电梯直达,一种是需要换乘。这次作业中可以发现任何一种请求最多换乘一次就可以完成,因此设计起来可以稍微overfit一下这个性质。

每一个请求到来,先去检查ABC谁可以单独完成这个任务,如果没有,就去看AB,AC,BC组合谁可以完成任务。确定好哪两个电梯之后,实际上,因为任何两个电梯重合的可停楼层是可以看出来的,可以用判断函数零点是否在某个区间内的算法选定一个在ToFloor和FromFloor之间可以换成的楼层(如果都不是零点就随便选一个,效率先靠后放)。此外为了让PersonRequest记录上换乘楼层的信息,写了一个Wrapper。举例来说,比如分配到的两部电梯是AB,首先高级调度器把这个任务wrap之后分给A,A完成之后检查当前层不等于真正的ToFloor,于是返回给高级调度器,高级调度器查一下分配记录,然后转给B,B执行完成后看到当前层等于真正的ToFloor,于是任务完成。

此外,为了防止总是一个电梯去执行任务,我设计了轮换机制。假设这次执行任务的是A,下次从B开始匹配,如果这次是B,下次从C开始,以此类推。

调度策略(不一定最优)

维护两个队列,Upper和Lower,分别代表所有在当前层上面的目标楼层和当前层下面的目标楼层;

求出四个值:

UpperMin:完成Upper中所有目标(包括接送),需要访问到的楼层最小值;

UpperMax:完成Upper中所有目标(包括接送),需要访问到的楼层最大值;

LowerMin:完成Lower中所有目标(包括接送),需要访问到的楼层最小值;

LowerMin:完成Lower中所有目标(包括接送),需要访问到的楼层最大值;

这四个值每次都现算复杂度很高,所以就每次来一个新目标就更新维护一下;

记当前层为cur,不管先向上还是先向下,如果没有新的指令进来,一路到底再换方向比中间多次换方向时间要短

如果先向上,耗时为:

U = UpperMax - cur + UpperMax - Min(LowerMin, UpperMin) + LowerMax - Min(LowerMin, UpperMin)

如果先向下,耗时为:

L = cur - LowerMin + Max(UpperMax, LowerMax) - LowerMin + Max(UpperMax, LowerMax) - UpperMin

如果U小先向上走,否则向下

第二部分:基于度量来分析自己的程序结构

程序分析使用IDEA JAVA的插件Calculate Metrics对每次作业的类和方法进行基于度量的复杂度分析,参数意义解释如下:

1)ev(G) :Calculates the essential complexity of each non-abstract method. Essential complexity is a graph-theoretic measure of just how ill-structured a method's control flow is. Essential complexity ranges from 1 to v(G), the cyclomatic complexity of the method.
(即表示一个方法的结构化程度,值越大则程序结构越“病态”)2) iv(G):Calculates the design complexity of a method. The design complexity is related to how interlinked a methods control flow is with calls to other methods. Design complexity ranges from 1 to v(G), the cyclomatic complexity of the method. Design complexity also represents the minimal number of tests necessary to exercise the integration of the method with the methods it calls.
(即表示一个方法与其调用的其他方法的紧密程度,值越大则越紧密)3)v(G):Calculates the cyclomatic complexity of each non-abstract method. Cyclomatic complexity is a measure of the number of distinct execution paths through each method. This can also be considered as the minimal number of tests necessary to completely exercise a method's control flow. In practice, this is 1 + the number of if's, while's, for's, do's, switch cases, catches, conditional expressions, &&'s and ||'s in the method.
(即表示一个方法的穷尽每一条路径所需要的次数,也就是循环复杂度)4)OCavg :Calculates the average cyclomatic complexity of the non-abstract methods in each class. Inherited methods are not counted for purposes of this metric.5)WMC :Calculates the total cyclomatic complexity of the methods in each class.

第五次作业

类图

UML图如下,除去主线程这次一共用了4个线程,电梯调度器各一个,为了增加并行效率,remove和pick乘客的操作是新开一个线程进行的,电梯门打开之后直接run两个线程,判断都结束之后再关门;

度量

可以看到电梯部分复杂度较高,因为各种运行开关门处理包括调度算法都在这个程序里了

Sequence Diagram

线程协作关系图如下

第六次作业

类图

大致思路和上次作业一样,remove和pick线程合成了一个,主线程负责起接收request的工作,Target队列的维护工作从Elevator中分离出来,单独建立了Scheduler类

度量

相比上次,各个类分工更加明确,Scheduler由于调度算法比较复杂,所以整体复杂度还是偏高


Sequence Diagram

线程协作关系图如下

第七次作业

类图

主线程负责起接收request的工作,调度器分两级,Scheduler给SubScheduler分配任务,SubScheduler给电梯线程分配任务,remove和pick分开,因为remove需要单独进行一些与Scheduler交互的操作

度量

两级调度器的复杂度较高,因为涉及调度算法和任务分配



Sequence Diagram

三次作业SOLID原则分析

SRP(单一责任原则):第一次作业中电梯类兼顾了调度算法,违背了单一功能原则(S),在后两次作业中进行了改进,调度是一个类,电梯是一个类;

OCP(开放封闭原则):第二次作业中调度器和电梯分离,放到第三次作业中可以分别对应到子调度器和电梯,结构上不怎么需要修改,说明程序具有一定的扩展性能。

LSP(里氏替换原则):作业中没有使用到继承,以后会多多尝试

ISP(接口分离原则):作业中没有使用到接口,以后会多多尝试

DIP(依赖倒置原则):本次作业层次比较简单,所以没有涉及这个问题,后面会注意

第三部分:程序bug分析

前两次强测中没有发现bug

第三次强测的bug比较可惜,原因在于旧代码一句话没有删干净。第三次作业是在第二次的基础上写的,前两次作业由于只有一个电梯,且不限载重人数,为了提升性能,我设计的算法为:电梯在get到下一个目标之后,运行途中如果检测到当前层有人,便会停下开门,即便当前层不是目标层,之后继续执行未完成的目标。第三次作业中对这个算法做了简化,计划写成未达到目标层中间都不会停(并不是最优调度,但可以降低算法复杂度),结果没有删掉前两次作业执行中间停的语句。导致的结果是,如果中间停下,原先没有完成的target直接被丢失,造成了任务的失败。且中测由于指令密度比较低,没有发现这个bug。

吸取的教训就是,如果要在原有代码的基础上更改,最好不要直接复制粘贴旧代码,就算是基本没有改动,还是照着手动敲一遍好,否则后面很难检查出来。

第四部分:心得体会

第一次写多线程任务,学到了很多新知识,比如多线程用法,避免死锁方法,一些wait notifyAll的组合技巧;

任务复杂的话很容易写出bug,这个时候,让每个对象做自己的事情就很重要;

在原有代码基础上构建新任务的代码,最好照着改不要复制粘贴,一样的部分对着敲一遍,不一样的部分重写,否则bug很难发现;

代码风格检查对代码风格帮助很大;

转载于:https://www.cnblogs.com/Ggalaxy/p/10740180.html

2019-OO-第二单元总结相关推荐

  1. OO第二单元(电梯)单元总结

    OO第二单元(电梯)单元总结 OO第一单元(求导)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉理解和掌握多线程的思想和方法.这个单元以电梯为主题,从一开始的最简单的单部傻瓜调 ...

  2. 【OO学习】OO第二单元作业总结

    OO第二单元作业总结 在第二单元作业中,我们通过多线程的手段实现了电梯调度,前两次作业是单电梯调度,第三次作业是多电梯调度.这个单元中的性能分要求是完成所有请求的时间最短,因此在简单实现电梯调度的基础 ...

  3. BUAA OO 第二单元总结

    OO 第二单元总结 本文为OO 第二单元电梯作业总结,本单元主要是掌握多线程和线程安全.三次作业总的架构类似,可分为输入线程.调度线程.电梯线程.三次作业的增量迭代如下 第五次作业 六部电梯 第六次作 ...

  4. 大闸蟹的OO第二单元总结

    OO的第二单元是讲多线程的协作与控制,三次作业分别为FAFS电梯,ALS电梯和三部需要协作的电梯.三次作业由浅入深,让我们逐渐理解多线程的工作原理和运行状况. 第一次作业: 第一次作业是傻瓜电梯,也就 ...

  5. BUAA OO第二单元作业总结

    一.作业设计策略 (一)第一次作业设计方案 模型:生产者消费者模型 两个线程:输入线程(生产者).电梯线程(消费者) 共享对象:请求队列 退出模式:输入线程读到null,退出run,并将null传入请 ...

  6. BUAA OO 第二单元 电梯

    前言 第二单元的主要任务是模拟电梯,主要涉及调度.电梯内部运行策略.换乘等,培养多线程编程的能力. 第一次作业 第一次作业的要求较为简单,模拟6部电梯的运作以及调度即可. 分析 笔者参考了上机所给的代 ...

  7. 2019年北航OO第二单元(多线程电梯任务)总结

    一.三次作业总结 1. 说在前面 对于这次的这三次电梯作业,我采用了和几乎所有人都不同的架构:将每个人当作一个线程.这样做有一定的好处:它使得整个问题的建模更加自然,并且在后期人员调度变得复杂时,可以 ...

  8. OO第二单元作业小结

    总结性博客作业 第一次作业 (1)从多线程的协同和同步控制方面,分析和总结自己三次作业的设计策略. 第一次作业为单电梯傻瓜调度,可以采用生产者--消费者模型,是一个有一个生产者(标准输入电梯请求),一 ...

  9. OO第二单元电梯作业总结

    目录 目录一.第一次作业分析设计策略基于度量分析程序结构二.第二次作业分析设计策略基于度量分析程序结构三.第三次作业分析设计策略基于度量分析程序结构四.分析自己程序的bug五.发现别人程序bug所采用 ...

  10. OO第二单元作业分析

    前言 这一单元关于线程安全的作业结束了,在助教提供的接口的帮助以及老师提供的设计模型的指导下,这三次作业还是相对轻松地完成了,中间也没有出现什么bug,可能就是因为简单的逻辑不容易出错吧,可惜两次都由 ...

最新文章

  1. 云计算里的安全:警惕云服务被恶意利用
  2. mysql 打开文件数_MySQL打开的文件描述符限制
  3. bootstrap validator 出现Maximum call stack size exceeded
  4. ansible提权操作
  5. gcc undefined reference to 问题解决方法(使用库)
  6. 对lua协程的一点理解
  7. 【c】写头文件要加#ifndef,#define, #endif
  8. python 添加图例_Python | 在图例标签中添加Sigma
  9. 开始位置 环状图_水星轨道发现千万公里环状结构,或将发现新的行星环
  10. HDU-1796 How many integers can you find 容斥定理
  11. Tableau系列软件概况
  12. 推荐系统实践学习系列(七)推荐系统实例
  13. 【Matlab代码】基于小波分析的音频信号的特征识别
  14. 记录淘宝里的点点滴滴
  15. iTunes只能装C盘吗_如何通过iTunes将iPhone备份到移动硬盘?
  16. 计算机中丢失rtutil,api-ms-win-core-winrt-string-l1-1-0.dll从您的计算机中丢失
  17. “网红直播+电商”是门好生意?直播的商品为什么这么好卖
  18. 英文金曲大赛c语言,英文歌曲_最激情!佐治亚理工开学典礼欢迎辞_沪江英语
  19. 不仅是工程学!人类认知偏差导致的12个AI研究盲区
  20. ArcGIS Server出图之Dynamic Layers

热门文章

  1. javascript框架比较(三)
  2. 漫步微积分十九——牛顿法解方程
  3. @scheduled注解配置时间_Spring Boot中使用@Scheduled创建定时任务
  4. PointDSC: Robust Point Cloud Registration using Deep Spatial Consistency (PointDSC) 论文学习笔记小结
  5. Python判断不可变对象(字符串,整数,浮点数,数组)相等的办法以及其底层实现原理
  6. 基于神经网络的文本分类(基于Pytorch实现)
  7. 【转】前端开发必备网站
  8. 【敏感度,查询,裁剪代码实现】差分隐私代码实现系列(六)
  9. TX1在opencv中调用gstreamer解码海康IP摄像头
  10. Java 8 Stream API详解