OOP第二次做业

OOP第二次博客做业

(1)从多线程的协同和同步控制方面,分析和总结本身三次做业的设计策略

在三次做业中,我都采用了经过一个共享队列,采用轮询(非暴力轮询)的方法进行信息的传递,在初次接触多线程时,因为惧怕产生死锁,故最初采用了这样的方法,但这样的信息交互方法,相对于普通生产者消费者模型的wait()notify()方法确定效率较低,有许多无用的查询,在之后的练习中,仍是须要改为wait()notify()python

在考虑同步控制的方法时,我是采用syncronized修饰临界区的方法来进行防止多个线程同时对一个临界资源进行操做。在刚接触多线程时,我记得最清楚的点就是ArrayList是线程不安全的,Vector是线程安全的。因为对于这一区别的不了解,我就在电梯第二次做业中,将全部的ArrayList都替换成了Vector,想以此来保证多线程的安全性。在后来本身的测试和资料的查阅中,我发现Vector的线程安全体如今其方法的原子性,但在符合操做中仍是得使用锁的方法进行互斥访问,因此在这里ArrayListVector并无差异。算法

在第一次做业,因为没有性能分,就直接照搬傻瓜调度的方法进行程序的构建。安全

在第二次做业,采用(伪)Look算法进行调度,可是因为本身的设计失误使得本身作了一个零优化。(在电梯进行调度接人时,例如电梯上行接一个要下行的人,我会将请求指令派发给电梯,却没有电梯的调度中增长目的楼层的刷新和检测楼层是否有人须要进出,也就致使了增长的优化毫无心义)多线程

第三次做业,我沿用第二次的架构,调度器先静态拆分不可直达的指令,再经过请求的优先级(例如-3-3优先级最高)来派发指令架构

while (true) {
           /*to split the personRequest*/
           checkSplit();
           for (int i = 1;i <= 3;i++) {
               upDispatch(i);
          }
           for (int i = 1;i <= 3;i++) {
               downDispatch(i);
          }
           if (waitList.isEmpty() && upList.isEmpty() &&
                   downList.isEmpty() && inputFlag.getFlag()) {
               managerFlag.setFlag();
               break;
          }
           Main.sleep(breakTime);
}

同时根据电梯的运行情况选择运送时间最短的电梯进行运送。性能

private ConcreteElevator chooseBestE(PersonRequest personRequest) {
       long leastTime = 50000;//the max time
       ConcreteElevator bestE = elevators[0];
       for (ConcreteElevator concreteElevator : elevators) {
           if (concreteElevator.isCarry(personRequest, isBypass)) {
               long time = concreteElevator.costTime(personRequest, isBypass);
               if (leastTime >= time) {
                   bestE = concreteElevator;
                   leastTime = time;
              }
          }
      }
       return bestE;
  }

因为第二次做业问题没有发现,致使了我在第三次做业的负优化。(因为一个指令派发给某一个电梯,可是因为他没有捎带走,只能等他运行完其余指令才能运送这一指令,形成了很大的性能损失)测试

(2)基于度量来分析本身的程序架构

三次做业的类图以下所示:优化

 

本次做业较为简单,未发现什么问题atom

 

 

 

 

 

和第三次做业大致一致,在第三次做业中详述spa

 

 

 

 

在第三次做业中,主要的问题仍是电梯过于复杂,因为我分配请求是根据当前状况下哪个电梯运送这个请求最快来指派电梯,因此须要计算cost,为了减轻代码量就把这一部分放在了电梯中泽娜加了电梯的复杂度,这一部份内容本应该所有有调度器负责。解耦合状况我认为也还能够。

 

总体类的分配我以为仍是较为合理的,没有出现类的职责严重混淆起来的状况。

优势:在计算时间时,将部分实现代码放在了电梯中,减小了总体的代码量

缺点:在计算时间时,将部分实现代码放在了电梯中,增长了电梯和调度器之间的耦合,不利于类与类职责的拆分

 

基于SOLID原则的分析:
Single Responsibility Principle:基本遵循,除了在上面写的计算时间时致使了电梯多承担了一部分功能
Open Close Principle:没有很好的实现,在进行功能的添加时,会对一些模块进行修改,说明在最初进行架构设计时并无很好的考虑接下来的可能需求,之后须要多对于此进行分析,在设计一个好的架构,可以实现对扩展开放、对修改关闭
Liskov Substitution Principle:没有体现,因为在这三次做业中都没有用到继承,因此没有涉及。
Interface Segregation Principle:没有体现,在这三次做业中没有出现多个类共享一个接口的状况,因此没有涉及。
Dependency Inversion Principle:在第三次做业中,限制了每一个电梯所能到达的楼层,但在以前我并无预估到这一状况的发生,因此将这一属性内嵌在了电梯的实现中,在以后的做业中,必定要好好的分析需求,使得方法依赖于抽象而不是具体实例。

(3)分析本身程序的bug

第一次和第二次做业在公测和互测中没有bug。

在第三次做业中因为一些事情,太迟进行代码的编写,致使对于代码的测试不足,一个小小的疏漏公测出了一个bug。

for (int i = 1;i <= 3;i++) {
upDispatch(i);
}
for (int i = 1;i < 3;i++) {
downDispatch(i);
}
//漏了一个=,致使调度器一直有一个15-1的人没法派分出去,致使了程序的不能结束。

因为对于多线程有了大概清晰的了解,而且采用轮询的方法,没有出现多线程相关的蜜汁bug

(4)分析本身发现别人bug所采用的策略

我采用python生成随机数据,再使用管道实现不断喂数据给程序,再对结果进行正确性检测。在测试别人的程序时,使用随机数据进行测试,测出了4,5个bug,效果仍是不错的,在第二次做业时,因为知道有同窗被发现了bug,因此针对其代码结构编写了测试样例,找到了一个bug。其余所有采用随机测试的方法,将错误同窗的输入复制到其文件夹中,以随机字符串给其命名以防止覆盖。

这个单元的测试和上个单元的测试是彻底不一样的,由于这一次若是不使用评测机就根本没办法进行测试,评测机的编写也是一个小难点。并且第一次能够只依靠手动罗列各类状况手写测试样例来找bug,而此次即便构造出测试样例也没办法测试。

(5)心得体会

1:不能使用基本数据类型做为共享对象,最初使用Boolean来做为共享对象,后来发现这不是引用传递,而是值传递,致使程序不能正常结束。

2:Vector的安全性只体如今其方法的原子性上,在复合操做中不保证原子性。

3:考虑在须要用视有多个读者的时候使用读写锁才来提升多线程对于数据访问的效率。

相关文章
相关标签/搜索