程序设计策略

第一次作业

第一次作业实现的是FAFS式傻瓜调度电梯,由于是第一次接触多线程,难度不是很大。在我的设计里,我借鉴了生产者消费者模式,设计了一个输入线程和一个电梯线程,控制器的设计使用了单例模式,维护了一个请求队列,作为托盘使用。在运行时,输入线程负责向请求队列提供请求,电梯线程负责拿取请求,并运行到指定楼层。这次作业的缺点是,我设计的控制器较为鸡肋,其实质只是一个存储调度指令的队列,我将具体的运行逻辑全写在了电梯里面。由于电梯是傻瓜式调度,这样的设计在正确性上没有出现问题,但是导致了扩展性很差,使得我在做第二次作业时不得不重写了电梯运行的逻辑和控制器的绝大部分内容。

第二次作业

这一次作业要求实现一个可稍带的ALS电梯。由于上述第一次设计的缺陷,我重构了控制器和电梯逻辑。调度策略方面采用了近似look的策略。线程个数保持不变,输入线程保持不变,电梯线程进行了较大的改动,我将所有的运行逻辑全部剥离,电梯只负责进行上人、下人、开门、关门、沿运动方向移动一层的原子操作,而控制器负责维护一个请求队列,负责所有的请求处理。即电梯每次上行或者下行一层都要向控制器发送自身状态,控制器获取状态后,遍历整个请求队列,选出同方向捎带的进入请求和到达请求给予电梯,同时控制器修改队列里的请求状态,将到站的请求删除。电梯获取请求后根据请求内容决定是否执行上人、下人、开门、关门、沿运动方向移动一层,到了下一层再获取新的请求。
为了实现以上逻辑,我电梯里新增了几个电梯状态参数:最远到达楼层、电梯运行方向、空闲位。每次电梯运送同方向的人时修改最远到达楼层。如果到了一次运行的最远到达楼层且没有同方向的可稍带请求,那么就将空闲位置位。控制器发现有空闲电梯时,就会使电梯向目前的请求队列的第一个请求移动。若当前请求队列为空,则使电梯静止空等。
这一次作业我认为设计的保证了正确性,实现了不同模块之间的独立性。性能上有待改进的是空闲时,可以让电梯运行,而非空等。

第三次作业

这一次作业要求多部多线程智能(SS)电梯的实现。有了第二次作业的架构设计,这一次作业的主要任务就是进行了限定人数、楼层、运行速度等新增要求的扩展,还有多线程运行时的线程安全问题。为了满足人数、楼层的要求,我又在电梯类里新增了电梯的楼层、当前人员序列,传给控制器获取请求时也增加了这两个成员。为了应对请求需要拆分成多部电梯的情况,我将人员请求设计成了一个类,每个请求在读入时,按照周转楼层最少的原则进行拆分,每个人员内部建立一个请求队列,人员再组成一个大的请求队列。控制器逻辑加入了楼层判断、人满判断,其余同上一次大致相同。同时在设计时还注意了从请求队列里遍历时,只能判断每个人员内部队列的第一个请求,这是保证人员必须完成第一个请求才能换乘电梯,防止出现时序问题。
这一次作业可优化的地方有不少,例如把根据电梯实际运行情况实时切分请求、根据电梯负载分配新请求等等。

程序度量分析

第一次作业

类图

类复杂度

方法复杂度

时序图

SOLID设计原则评价:

SOLID原则分析

  • SRP:几乎所有的调度逻辑全部丢给了电梯类,控制器几乎无作用。
  • OCP:由于电梯类包含了太多的运行逻辑,可扩展性较差,分配逻辑扩展起来很困难。
  • LSP:没有使用继承
  • ISP:未实现接口类
  • DIP:由于采用生产者消费者模式,输入和输出模块互不依赖。

第二次作业

类图

类复杂度

方法复杂度

时序图

SOLID设计原则评价:

SOLID原则分析

  • SRP:调度器仅负责调度,电梯仅运行进行运行的原子操作,职责划分明确。
  • OCP:由于将所有运行控制部分从电梯里抽离,所以新增功能时可以轻松地扩展属性、增添调度逻辑
  • LSP:没有使用继承
  • ISP:未实现接口类
  • DIP:输入和输出模块互不依赖,但控制器调度需要获取电梯属性,依赖电梯的具体状态。

第三次作业

类图

类复杂度

方法复杂度

时序图

SOLID设计原则评价:

SOLID原则分析

  • SRP:调度器仅负责调度,各个电梯仅运行运行的原子操作,职责划分明确,互不影响。
  • OCP:由于电梯参数在构造方法时传入,所以支持新增电梯或者属性的扩展。
  • LSP:没有使用继承
  • ISP:未实现接口类
  • DIP:输入和输出模块互不依赖,各个电梯互相不知道彼此存在,调度器通过一个消息类抽象与电梯通信。

bug相关

个人bug

在这个单元作业中,由于前两次的调度策略较简单,也没有较大的线程安全问题,我前两次作业都没有出现正确性问题。但第三次作业中,我在强测时出现了线程安全问题。举例说明我的问题:处理请求999-FROM-3-TO-2时,先拆分成999-FROM-3-TO-1以及999-FROM-1-TO-2。由于存在同步问题,可能导致在1楼换乘时,先输出IN-999-1-B再输出OUT-999-1-C的错误。这说明问题在于输出和修改人员状态的不同步。在原来的设计中,我实现的方法是在调度器修改人员状态(在哪部电梯上),同时将进电梯和出电梯的人员以列表形式传给电梯,由电梯进行输出In和out信息。这就可能导致在一个线程对一个人员状态进行修改后还未来得及输出,另一个线程就进行了下一次操作。
修改措施是增加了修改状态的判断,控制器在修改人员状态时,会判断人员是否在电梯内。若人员已不在电梯内,则证明已经输出了out,可以修改状态;否则不修改。

hack相关

第一次作业较简单,同组都是满分,没有正确性问题。第二次作业开始,除了随机生成数据以外,我hack别人时采用的策略主要来自于个人写程序时出现的问题,有以下几点:1.一层重复开关门问题,这类问题往往是判断是否转向运行时容易出现的,因此构造1-2-1这样的反复转向数据。2.开关门的间隔上人问题,这类问题主要出现在可能设计出了开关门的0.4秒不能上人的问题,针对这一点可以构造【0.0】n条请求,【0.4】n条请求这类数据,若没有在边界时间带人,很容易就会超时。但由于取消了T_max限制 ,hack他人时,基本也没出现正确性问题,倒是随机生成的简单至[0.0]1-FROM-1-TO--1这样的数据hack到了人。
第三次作业则是hack的重灾区,不幸中的万幸是我没有被hack出来强测的错误,这可能是由于相关样例不好构造的缘故。由于这次作业完成的时间紧张,我主要时随机生成数据,生成结果后再交给检查程序检查。在查看他人代码时,我发现电梯调度策略多种多样,问题也出现的各种各样,理清一个人的思路已实属不易,找出程序运行的逻辑更是难,所以我只着重查看了两个方面,一个是调度队列的同步问题,另一个是TimableOutput线程不安全问题。

这一单元与第一单元的测试策略相比,着重点从边界数据转移到了线程安全问题上,构造一些针对线程安全的数据(例如请求拆分、队列加锁、输出安全等)更容易得分。

总结

这一单元的重点是多线程相关问题,包括线程安全、线程同步设计等。重中之重就是线程安全的确保,在这一单元自己写出的bug无一不是线程安全导致的时序同步问题。相比第一单元,算法部分减少了,但多线程并发的问题更加棘手。另外的难点是调试部分,一行行print输出确实很考验人的耐心。电梯控制逻辑嵌套也很多,把所有情况分析全面很困难。总之,这一单元充满了挑战,也让我收获不少。希望在之后的面向对象课程学习里,我能继续努力,考虑更加全面,保证程序的正确性。

转载于:https://www.cnblogs.com/codearning/p/10760479.html

BUAA_OO_第二单元作业总结相关推荐

  1. 面向对象课程第二单元作业总结

    面向对象课程第二单元作业总结 前言 电梯系列作业分为三个阶段,逐步深入实现越来越复杂的电梯运行状态模拟. 第一阶段实现单部多线程傻瓜调度(FAFS)电梯的模拟: 第二阶段实现单部多线程可捎带调度(AL ...

  2. BUAA-OO 第二单元作业“电梯调度”总结与思考

    一.需求分析 利用java线程的相关知识实现 1)单部多线程傻瓜调度(FAFS)电梯 2)单部多线程可捎带调度(ALS)电梯 3)多部多线程智能(SS)调度电梯 二.思路分析 1.基于度量的程序结构分 ...

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

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

  4. OO第二单元作业小结

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

  5. BUAA_OO_第二单元

    一.设计策略分析总结 本单元实验要求对进阶难度的电梯进行模拟,要求模拟乘梯人员发出输入请求,且能够让电梯处理请求并模拟运行.开关门.将乘客送到目的地,在电梯做出相应行为时输出一定的信息. 在本次任务中 ...

  6. OO第二单元作业分析

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

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

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

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

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

  9. OO第二单元作业总结

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

最新文章

  1. 计算机多媒体技术广泛应用于各个领域,多媒体技术发展前景计算机现状及
  2. Hadoop动态扩容,增加节点
  3. Zstd 压缩性能分析(含比较)
  4. session很快失效_深夜,我偷听到程序员要对session下手...
  5. android 本地资源 uri,Android 本地文件选择
  6. ERROR: source database template1 is being accessed by other users解决方法
  7. php学习日志(3)-echoprint
  8. TensorFlow 深度学习中文第二版·翻译完成
  9. Could not load file or assembly (Exception from HRESULT: 0x80131047)-解决办法
  10. windows环境下创建多个Redis实例
  11. 修改XP/Win7开机动画
  12. 谈内置创新5.1/7.1声卡效果开混响模式滋滋啦啦炸麦声音【案例解析】
  13. 为缺少调色板的png图片添加调色板
  14. PPT插入形状,在里面填写文字,文本框过大
  15. 用计算机制作演示文稿教案博客,《制作多媒体演示文稿》教学案例
  16. Android 微信聊天页面
  17. Failed to load module “canberra-gtk-module“
  18. ERP的工单(MO)
  19. flutterdio_强大的Flutter http请求库dio
  20. 改善监控过程中逆光的方法

热门文章

  1. python进程池pool_python多任务--进程池Pool
  2. oracle数据库时分秒格式_Oracle如何输出指定格式的日期时间数据呢?
  3. Python pandas库159个常用方法使用说明(转载)
  4. LeetCode 474. Ones and Zeroes 动态规划解法+拓展
  5. LeetCode 1770. 执行乘法运算的最大分数(DP)
  6. 剑指Offer - 面试题65. 不用加减乘除做加法(位运算,要看哦)
  7. LeetCode 950. 按递增顺序显示卡牌(deque)
  8. k8s挂载目录_拥抱云原生,如何将开源项目用k8s部署?
  9. 整理与总结Python关于对文件的操作
  10. 关于Django中JsonResponse返回中文字典编码错误的解决方案