一、需求分析

利用java线程的相关知识实现

1)单部多线程傻瓜调度(FAFS)电梯

2)单部多线程可捎带调度(ALS)电梯

3)多部多线程智能(SS)调度电梯

二、思路分析

1、基于度量的程序结构分析

流程时序图(利用SequenceDiagram插件)

注:使用UML Support插件时,采用实现runnable接口的方法生成的类关系图更优美一点

Input类(三次作业复用):

Elevator类:

第一次

第二次

图太大了戳这里

第三次

图太大了戳这里

代码行数统计(利用Statistic插件)

第一次

第二次

第三次

代码设计复杂度(利用MetricsReloaded插件)

ev(G)基本复杂度,用来衡量程序非结构化程度
iv(G)模块设计复杂度,用来衡量模块判定结构
v(G)独立路径条数

第一次

第二次

第三次

2、BUG分析

第一次:

强测中得分 100

互测:未被hack。未hack别人。

第二次:

在强测中得分 82.558(所有数据性能分几乎为0)

未被hack。未hack到别人。

第三次:

在强测中得分  76.9294(WA两个数据点,其余数据性能分几乎为0)

被hack1次,hack他人1次。

自己错误:出现了电梯容量已满却仍进人的情况。

他人错误:电梯换向时到了21层。

三、知识技能总结

1、代码编写层面的优化

1)第三次作业中一种快速处理换乘楼层的写法

记A电梯为001,B电梯为010,C电梯为100.

则可乘坐的电梯的类型可以用三位二进制数来表示,例如:

在1层的人可以乘坐A、B电梯,则建立楼层1到二进制数011的映射(map)。

在3层的人只能乘坐C电梯,则简历楼层3到二进制数100的映射。

这样避免了用八个等待队列储存所有情况的繁杂写法。

2)电梯不同状态间的切换:run方法中,用状态机来实现,简单直观

 1     public void run() {
 2         while (true) {
 3             synchronized (this) {
 4                 try {
 5                     if (state == 0) {
 6                         break;
 7                     }
 8                     if (state == 1) { //main request
 9                         while (true) {
10                             if (Singleton.getInstance().isend()) {
11                                 close();
12                                 state = 0;
13                                 break;
14                             }
15                             mainRequest = Singleton.getInstance().getMainRequest();
16                             if (mainRequest == null) {
17                                 synchronized (Singleton.getInstance()) {
18                                     Singleton.getInstance().wait();
19                                 }
20                             } else {
21                                 solveMain();
22                                 break;
23                             }
24                         }
25                     }
26                     else if (state == 2) { solveUp(); }
27                     else if (state == 3) { solveDown(); }
28                 } catch (InterruptedException e) {
29                     //DO STH
30                 }
31             }
32         }
33     }

2、多线程设计模式的实际运用

1)单例模式

2)生产者—消费者模式

3)线程池(Worker Thread模式)

4)观察者模式

3、输出日志信息 Log4j

配置log4j2-test.xml文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <configuration status="OFF">
 3     <appenders> <!—输出模块-->
 4         <Console name="Console" target="SYSTEM_OUT">
 5             <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
 6         </Console>
 7     </appenders>
 8     <loggers><!—日志模块-->
 9 <logger name=“elevator.WorkerThread" level="trace" additivity="false">
10             <appender-ref ref="Console"/>
11         </logger>
12         <root level="error">
13             <appender-ref ref="Console"/>
14         </root>
15     </loggers>
16 </configuration>

4、JProfiler的使用

5、定点投放的实现

思路:正则表达式分离时间戳+sleep

python程序已上传至GitHub

6、线程安全容器总结

这一单元作业中我采用了CopyOnWriteArrayList作为线程安全数组

COW(Copy On Write)机制的介绍:https://yq.aliyun.com/articles/665359

四、自己的一点思考

1、程序测试方法

随机数据测试(测试cpu-time和基本的功能)+构造数据测试(测试电梯是否满足所有限制条件)

对拍器SPJ测试的功能,同时也是构造数据时重点检验的功能:

是否满足到达——开门——出入人——关门的顺序。

是否满足楼层限制

是否满足容量要求

除此之外,三次作业重难点在于:

1)HW5:是否可正常退出线程:接收器不再接收请求,电梯继续处理完已经读入的请求

2)HW6:是否可将所有请求捎带(如果有请求的区间与当前等待队列区间不重合,是否将其放入等待队列?)、同一楼层是否会开关两次门

3)HW7:2->3、4->3的换乘需要特殊处理。换乘指令拆解后是否按顺序执行(在人下电梯后才能从同楼层上另一电梯)。

2、优化方法

四、疑问与建议

1、对拍器的意义?

助教说,A组强测和互测成绩远好于B组和C组的一大原因是“大佬们基本人手一个评测机”。

我承认互测的确是测试的有效手段,这导致我这一单元的最大收获就是学会写得一手好脚本。

但当我发现自己用在写评测机的时间远远大于学习多线程思想的时间的时候,我感觉自己在面向“评测机”编程。

不知道老师和助教为何大力鼓励同学们来写评测机。知识无穷,学什么只要用心了都会有收获,也都会有相应的欢喜和满足。但这种偏离正轨的导向还是会让人感觉食之无味,弃之可惜。

2、架构or性能?

自我感觉第二单元作业的难度要低于第一单元。程序的大体架构老师在课上已经基本讲过,剩下的添添补补,这三次作业竟然没有重构。

如果说性能优化基于架构的话,那性能优化的方向是什么呢?

当我问及性能的问题时,助教和老师都在强调正确性为主,但作为两次被性能分踩死的选手,还是想要了解一下助教出题时构想的优化的可能思路。T_T

3、b站都开源了,大佬们的代码可以开源吗

如果助教觉得上面的话都没道理的话......我只是想请求看一看大佬们的优秀代码,学习一下。/小纠结

PS. 实验课的题面在结束之后可以开放吗?这样还能复习巩固一下下。

转载于:https://www.cnblogs.com/Ryan0v0/p/10752795.html

BUAA-OO 第二单元作业“电梯调度”总结与思考相关推荐

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

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

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

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

  3. BUAA OO 第二单元总结

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

  4. BUAA OO 第二单元 电梯

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

  5. OO第二单元作业小结

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

  6. OO第二单元作业分析

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

  7. OO第二单元作业总结

    一:设计策略 第一次作业:第一次是单电梯傻瓜调度策略,因此我把调度器当作共享资源对象,有一个put和一个get方法,因为只有一个电梯,并且单次取出和投放一个请求,因此只需要同步控制一下这两个方法是互斥 ...

  8. 第二单元作业——电梯模拟总结

    一.设计策略 1. 单部先来先服务电梯 第一次作业采用了最基本的生产者-消费者模型,电梯请求是模型中的商品,将控制器作为存储请求的仓库,主线程作为生产者向仓库存放请求,电梯作为消费者从仓库取出请求并处 ...

  9. OO第二次作业电梯总结

    这三次作业,发现自己无论采取怎样的架构,最后自己写的类都只有两个(除了给出的TestMain demo类). 在类图中,都是只有三小块....架构复杂性完全没有变? 第一次作业: 类图: 设计模式: ...

最新文章

  1. linux文件移出目录命令_Linux 文件与目录管理详解
  2. matlab添加文件到并行池,【Matlab Debugging】使用 addAttachedFiles(pool, files) 指定要附加的必要文件。...
  3. 于XAML导入命名空间的代码
  4. 高级 Linux 命令精通指南
  5. linux不能ping通域名能ping通ip
  6. CG CTF WEB AAencode
  7. Qt工作笔记-树图结构的2种方式,实现右键菜单
  8. 等差数列末项计算(信息学奥赛一本通-T1035)
  9. [Ubuntu] tmux
  10. vs2010 打开项目卡死问题解决办法
  11. cecore.cls.php 08cms,08cms小说系统 v1.0PHP CMS源码下载-华软网
  12. C中的struct,union,Bit Filed以及内存对齐
  13. java 数据库 事务 只读_Spring 事务 readOnly 到底是怎么回事?
  14. linux3.0字符设备驱动,linux字符设备驱动的 ioctl 幻数
  15. (附源码)spring boot跨境电商系统 毕业设计211003
  16. 腾讯正式推出密码保护卡,貌似对火狐用户重视不够
  17. openlayer画的圆比实际的小?4326和3857投影的不同
  18. 春节词汇 Spring Festival Words
  19. linux im6q交叉编译paho.mqtt.c
  20. Idean2018版本创建Gradle项目配置Tomcat报404错误(The origin server did not find a current representation for the)

热门文章

  1. java s1=abc s2=abc s1==s2_经典问题:String s1 = abc 与 String s2 = new String(abc)的区别...
  2. mysql文件类型_MyCat教程:实现MySql主从复制
  3. Apollo进阶课程㊱丨Apollo ROS深入介绍
  4. 在Kaggle上免费使用GPU
  5. java 反射 类变量_java反射机制取出model类的所有变量,以及value
  6. java递归统计一个文件夹含子文件夹里文件不同后缀的出现次数
  7. 计算机lab模式适用于,计算机考证二级选择题1
  8. 命令行 蓝牙_Ubuntu使用BlueZ驱动蓝牙dongle
  9. 《关于我的那些面经》滴滴Java岗(附答案)
  10. C++:08---成员变量初始化方式