• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

2022年北航OO第二单元总结

目录2022 BUAA OO第二单元一到三作业摘要1。首次作业1.1需求分析1.2实施方案1.3结构分析1.4测试思路2。二次作业2.1需求分析2.2实施方案2.3结构分析2.4测试思路2.5总结反思3。第三次作业3.1需求分析3.2实施方案3.3结构分析3.4总结架构设计的反思经验

一至三次作业总结

1. 第一次作业

1.1 需求分析

这项任务要求我们能够在ABCDE的五栋大楼里将乘客从起点位置运送到目标位置。指令中推荐ALS算法,需要多线程实现。

1.2 实现方案

这次作业是我第一次接触多线程的知识,也是这个单元最痛苦的一次作业。为了给接下来的两个作业打好框架,避免多线程相关的问题,在开始搭建框架之前,我学习了一段时间多线程的知识。对电脑上的代码也有很好的理解。在熟悉多线程之后,我决定完全锁定RequestQueue,也就是请求队列的外部方法,从而实现外部调用方法的多线程特性隐藏。我的三个作业中的所有请求“托盘”都是这个类的实例。同时,使用生产者和消费者模式,以输入为生产者,调度器负责将生产者的“生产”请求放入相应建筑的RequestQueue中,同时唤醒。在这里,为了避免轮询,我使用while而不是if在请求队列中输入wait(),以避免CPU时间超时。每个电梯处理器都是对建筑做出反应的消费者,它控制着电梯的所有行为。有相应的ALS实现手段和大量接口供处理器了解电梯的当前信息,处理器对电梯有绝对的控制权。电梯的UML图如下:

obp32sgd5q13027.png

程序运行的逻辑如下:

电梯在不同状态下运行

空闲状态:调用request queue :3360 get request()方法。如果里面没有请求,整个程序没有完成,电梯就会陷入wait(),直到生产者生成新的请求notifyAll()并响应。

主请求不在板上状态:从空闲状态获得一个新的请求,并切换到这个状态。此时,电梯的目的地位置被设置为主请求的出发位置。此时电梯只能搭载目的地在电梯目的地之前或在电梯目的地的乘客,也就是说可以接收到主请求。

主请求搭乘状态:从主请求未搭乘状态切换,此时电梯目的地被设定为主请求目标位置。同时,为了防止主请求到达时电梯闲置0.4秒,此时,电梯可以搭载所有目标方向相同的乘客。主请求到达后,到达位置离该电梯最近的请求为主请求。如果电梯未被占用,乘客调用RequestQueue 33603360 GetRequest(),或者重置主请求,或者进入空闲状态。

RequestQueue提供了所有的查询接口。

为了提高程序的并发性,我没有直接设置for循环来返回RequestQueue中的请求集。而是如果有相关需求(比如携程或者优化的携程需求)可以返回;否则,它将返回null。处理器收到null后,就不会再循环了。这种方法减少了程序对请求队列的占用时间,从而在一定程度上提高了程序的并发性。

1.3 结构分析

测量结果如下:

班级指标:

班级

OCavg

OCmax

世界泰拳理事会

安排

3.00

请求队列

2.00

20

请求

1.00

一个

过程

3.60

36

主要的

2.00

d> 2 2 InputThread 2.00 3 4 Elevator 1.23 3 32 Total 108 Average 1.83 3.86 15.43

Method metrics:

CogC ev(G) iv(G) v(G)
Total 126 89 117 134
Average 2.14 1.51 1.98 2.27

本次作业中由于在写代码前分析架构分析了好久,因此代码调试成功之后并没有出现BUG,进行程序反演与自己构建的不同数据进行测试之后,强测也得到了95分,也很幸运在互测中没有被Hack。

1.4 测试思路

同一栋楼使用大量同时到达请求进行轰击,同一层使用大量请求进行轰击,并在代码过程中输出电梯状态实时状态观测,查看有无BUG。

2. 第二次作业

2.1 需求分析

第二次作业需要在第一次作业之上增加环形横向电梯,并且实现可动态增添电梯的行为,乘客需求增加了横向需求。

2.2 实现方案

通过对此次的作业的分析,我发现横向电梯暴露给处理器的接口与纵向电梯完全一致,而且横向电梯除了运行方式之外与纵向电梯完全一直,因此我创建了抽象类BaseElevator,其中只有run()为抽象方向,然后将电梯所有属性与公共方法同一放在其中,之后让其子类继承其并在两子类VertEle和CrossEle中实现抽象方法。除此之外,我构建了Position类来替换作业一中所有的楼层值,其作为横向电梯与纵向电梯在传递数值的通货,同时在此类中封装判断横向运行方向的方法:CrossRightOrNot()由横向电梯调用来进行运行,至此,这一部分新增的功能全部实现,并且修改后原代码逻辑几乎保持不变。之后对于响应构建电梯的请求,只需要增加新的ElevatorRequeue类来进行对电梯请求的收集,我还构建了Maker类来构建新的电梯与电梯控制器,同时实现绑定。这样输入线程将电梯请求交给ElevatorQueue供Maker进行消费,将乘客请求交给Schedule进行分发到不同电梯托盘供各个消费者进行消费。程序的UML图如下:

1b3fnebddjk3028.png

2.3 结构分析

Class metrics:

class OCavg OCmax WMC
VerticalEle 2.00 3 6
SP 0
Schedule 4.00 7 8
RequestQueue 3.44 10 62
Prequest 1.00 1 4
Position 1.29 2 18
Maker 3.00 5 6
Main 3.00 3 3
InputThread 3.00 5 6
EleRequest 1.29 3 9
EleControl 3.78 11 34
CrossEle 2.00 3 6
BaseEle 1.12 3 29
Total 198
Average 2.04 4.46 14.14

Method metrics:

CogC ev(G) iv(G) v(G)
Total 278 162 182 225
Average 2.87 1.67 1.88 2.32
2.4 测试思路

本次测试我首先利用到了上次的BUG修复,成功发现我在检测电梯是否满载的过程中控制流设置错误,导致电梯人员可以超过上限,修改完此BUG后,我对同层乘客多个电梯竞争接乘进行了大量测试与形式验证,同时测试了单层电梯运行方向。最终在强测中得到了95分,也算是一个我比较理想的成绩。

2.5 总结反思

本次作业迭代我对架构的改变就只是在对“通货”的改变上,首先是横向电梯继承上减少了许多代码的改动,之后又是对整体程序里传递数据的Position(Floor + Build)的相关改动,使得程序十分简洁,其他则是对新增函数的完善,但由于认为自己在多线程的运行过程已较为熟练,并且前两次作业迭代到目前整体结构可扩展性(自认为)很好,这样的错觉让我在本单元第三次作业犯下了一个重大BUG,导致前五次作业均分95+功亏一篑,甚至那晚辗转难眠......

3 第三次作业

3.1 需求分析

第三次作业增添了换乘和横向电梯可达性的需求,其次增加了可定制多种不同类型的电梯功能。

3.2 实现方案

由于前两次作业的架构,对于电梯定制化将承载上限与速度仅仅在BaseElevator中新定义属性,再又Maker线程解析传入参数即可,对于换乘需求呢,我的设计是将一对多生产者消费者模式变为多对多,即每个电梯控制器都是一个生产者,与输入线程共享一个托盘,自定义乘客需求类新建fromFinalPos与tarFinalPos属性,输入线程当检测到该请求为换乘请求时使用这两个参数对乘客需求进行初始化,即转化为同层或同栋的需求。乘客出每个电梯时根据当前位置与最终位置判断是否到达,到达则该任务完成,否则修改乘客需求,返回到调度器中,而初始化乘客需求与修改乘客需求方法全部封装在乘客需求类中,此外我构建了新的共享资源类NumMonitor,输入线程检测到换乘乘客时调用加一方法,电梯控制器校验任务完成后调用减一方法,此类值为0也作为整个程序结束的一个条件,对于可开门,每辆电梯在构建时将会进行注册,注册信息与输入线程完全共享,输入线程因此通过横向电梯所有的注册信息判断中转乘客的中转楼层,将其作为参数传递给请求初始化函数,再在横向电梯运行方法中使用while,每当校验楼座可开门时才跳出,程序UML图如下:

23eouayl4we3029.png

3.3 结构分析

Class metrics:

class OCavg OCmax WMC
VertiaclEle 2.00 3 6
SP 0
Schedule 4.00 7 8
RequestQueue 3.20 10 64
Prequest 1.17 2 14
Position 1.38 2 22
NumMonitor 1.00 1 4
Maker 3.00 5 6
Main 4.00 4 4
InputThread 3.33 5 10
EleRequest 1.29 3 9
EleControl 4.11 11 37
CrossQueue 3.00 11 48
CrossEle 2.50 5 15
CrossControl 4.11 11 37
CanStropFinder 2.00 4 6
BaseEle 1.11 3 30
Total 320
Average 2.29 5.44 18.82

Method metrics:

CogC ev(G) iv(G) v(G)
Total 483 255 297 364
Average 3.45 1.82 2.12 2.60

本次作业的各项复杂度相比前两次改变并不大,因此复杂度指标并没有太大的变化。

3.4 总结反思

其实第三次作业的设计有一个很明显的BUG,说真的,我在当初写的时候似乎有印象,但写着写着就忘了......BUG在于注册信息中,电梯是会判断已注册的横向电梯并对请求是否可达进行校验,当满足后该楼层即可能作为中转楼层,这里是保证了乘客在该中转层有可以对应转移的电梯,但如果该层有两座电梯,他被抢走了地话,就会在电梯里转个不停......比如6层有两座横向电梯7号和8号,7号电梯A,C楼座可达,8号电梯A,B座可达,1号乘客由于注册器信息检测到有8号电梯可转乘B座,且楼层最优,因此被转运到6层,然而此时7号电梯恰好到达A座,根据可携程原则将其搭载,此时1号乘客就和电梯在整个楼层中转个不停.......这也是由于太浮躁没有注意电梯运行过程中犯下的大错,由于这个BUG我的强测爆了6个点,还是感谢助教的心理辅导,不然感觉真地晚上就要睡不着了。

架构设计体验

回忆这三周的OO作业,最艰难的便是第一周了,由于电梯在现实生活中十分常见,因此其架构设计并没有花费我大量的时间,主要是在多线程的学习之中,为了让之后的作业不会因为基础知识的掌握问题而产生问题,我在多线程的学习上花费了大量的功夫,然而就当挺过前两次之后,第三次由于没有校验搭乘爆炸,让我还是没能很好地结束这个单元的学习,有趣的是,那周的OS考试的Extra也没做出来,心里真地好难受。

心得体会

通过本单元的学习,很大地增强了我对多线程的理解和写代码一定要谨慎心细的教训,不能在写代码的时候浮躁,不过失去的分现在也已经无能为力了,那周的电梯爆炸和OSExtra真地好痛苦好难受,不过还是要挺过去的呀!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now