OO第二单元总结
第一次作业
- 设计思路:
根据大佬们在讨论区推荐的look算法,完成了这次作业。首先,我将Personrequest,转变成了person类,信息和personreque一样,但是多了一个direction属性,来存放他是上楼还是下楼,1是上楼,-1是下楼。然后我创建了floor类,里面可以存放person,还有floors类,由floor的list组成。当有input时,我就根据他在那个楼层,将该楼层的Arraylist加入一个新的person,elevator和input共享floors,然后根据look算法运行elevator。同时有个inside类,保存elevator中的person。 - bug:
第一次作业强测中没有出现bug,但是互测中出现了两个bug,都是cpu超时,当时知道是轮询了,但是一直没找到错误,知道在第二次作业的时候发现了那个错误,是一个判断wait的方法写错了,他是判断floors里面有没有人,没人就应该wait,知道输出结束,但是我在floors类里写IsEmpty方法是,在方法内部写成了floors.IsEmpty。而这个floors又是floors类里面的list成员,而Arraylist自带IsEmpty方法,floors.size一直是15,所以它本该wait,结果一直在while判断,出现了CPU超时。 - Metrics:
class metrics
method metrics
第一次作业比较简单,因此复杂度都挺低的,除了elevator中的run方法写了一大堆,其实可以分成几个方法写,复杂度应该会低很多。
- UML:
第二次作业
- 设计思路:
第二次作业基本框架和第一次作业一样,只是多了几个电梯,多了几层楼,我在floors里面创建多几个floor就解决了多了楼层,同时新建了一个elevators类,里面有Arraylist用来存放elevator。由于第二次作业多了负数楼层,所以我自认为用了个比较巧妙的方法来处理这个问题,一共有三层地下楼,16层地上,所以我一共创建了19个floors,在读取请求时,创建person对像,修改Tofloor和Fromfloor,如果大于零就加3,小于零就+4,这样-3到16层楼,就变成了1-19,处理起来就变得方便了一些,只用在输出的时候还原楼层就可以了。对于电梯接人,我并没有做任何处理,因为我在第一次作业我就是在电梯类里决定怎么走,并没有调度器类,因此我第二次作业就是电梯自己去抢人,谁抢到就是谁的,最后强测的结果显示这种做法性能居然还不错。 - bug:
第二次作业犯了一个愚蠢的bug,电梯限载7人,我在判断是否到七人的那个判断写错了,导致最多可以到8个人,除此之外就没有bug了。 - metrics:
class metrics
method metrics
第二次作业的复杂度比第一次在大部分地方,都高了一点点,同样的elevator中的run方法还是比较复杂。
- UML:
第三次作业
- 设计思路:
第三次作业在第二次作业的基础上展开,最难的地方是多了电梯类型不同能去的楼层不同,所以我在电梯内部多加了一个hashset用来存储它能去的楼层,然后修改了一下上下电梯的方法,这一次作业最难的地方应该就是换乘问题,这个问题,我是通过三种类型的电梯都经过1和15楼解决的,在1-和15楼上的乘客只有该电梯能够把他送到目的楼层才可以上,而其他楼层只要有请求就可以上,同时如果电梯经过1或15楼,那么电梯判断这个电梯里是否有该电梯不能去的楼层的乘客,如果有就下电梯。完成了换乘。 - bug:
第三次作业的bug是程序本该结束却一直wait的情况,这个情况在我写这次代码时已经出现过了很多次,比如这个电梯应该等另一个电梯的乘客下来再带该乘客去目处于的楼层,本应wait,但是我把它结束掉了,导致楼层里一直有人。第二次是一个方法没有加锁出现了线程不安全。而这个强测和互测中出现的这个问题,是新的问题,我还没找到。 - metrics:
class metrics
method metrics
第三次作业的有的方法复杂度比较高,但是我再这几个类的基础上写,确实有的方法需要很多东西。复杂度较高。
- UML:
分析别人的bug
我是先看别人代码中的wait,和notify,首先wait再是否在while里,wait的条件是什么是否同步,然后上测试数据,比较特殊的,比如第二次作业在同一层上30个人,第三次作业,全是需要换乘的乘客。但是我测试的他们都找不到bug。。由于自己没有评测机,手写数据,测不出来bug。。。
心得体会
第一次写多线程程序,发现多线程中最难的应该就是线程安全和wait问题,一旦线程不安全就会出现奇怪的问题,就比我实验课写了一个判断是否wait的方法,但是没有加那个synchronized关键字,导致程序无法正常结束。可惜我发现bug的时候实验课已经结束了。判断是否wait也很重要,一但出问题,就可能暴力轮询你,导致CPU时间出错。还有一个比较难受的就是多线程调试,有的时候正常运行是对的,调试就错了,有的时候调试对了,运行就错了,明明知道自己有问题,却不知道具体在哪儿,虽然后来用print大法找到了许多问题,但是这确实太low了。希望以后能学到更好的办法。