第一次blog作业
前言:刚刚接触java时,尝了几盘开胃小菜,觉得并没有什么与与学过的其他语言有什么太大的不同之处,而自从段老师强调的第五周pta作业开始,我才真正的体会到所谓“面向对象”的可怕之处,如后面的内容所说,从第五周开始,我们的作业里出现了一道不断更新迭代的面向对象的棘手难题(虽然老师天天在说这问题都搞不定)——电梯的收取命令与正确调度问题 。这可不得了了,原来我对java的理解还只停留在getter,setter,搞俩方法,Main类调用一下解决了事的阶段(毕竟c语言就是如此嘛),更可怕的是,我当时还在为自己方法中的既要又要而沾沾自喜(一个方法既处理数据,又输出结果)。而第五周这个题目的出现,像是晴空霹雳,劈开了我Java新世界的大门。第五次题目中,内外部的双线请求算是题目中最为新颖的一个点。还没等喘口气,第六次的题目又难题频出——在原来的基础上完成多个类的分化,用多个类共同完成对电梯的命令拾取与调度(控制类首次作为联系出现在我们的练*当中,不过鉴于老师上课讲过一个雨刷的例子,也不算太晦涩难懂)。这就完了?想多了。第七次作业中的“乘客类”横空出世更是让我手忙脚乱——它的出现让这个电梯调度问题上升到了另一个维度。惭愧的是,这三次的题目的测试点的分我都没有得到。盲目的自信与轻敌,往往没什么好结果。不幸中的万幸,三次作业也并非全无收获:加深了对于Java编程中最底层基础的理解,任何编程都建立在基础的编程能力之上。更重要的是,我真正开始重视起了面向对象中的“单一职责原则(SRP)——设计时注意,写代码时注意,检查时更要注意。一个合格的,优秀的java coder,若是这个点都不注意,那真是贻笑大方了题目中还存在其他问题:管理电梯内部和外部的乘客请求队列(其中外部请求队列需区分向上和向下),搞清楚电梯的运行规则,默认停在 1 层静止,有请求时启动,优先处理同方向请求,运行中每次移动一层并检查是否停靠处理请求。这就需要精确地控制电梯的状态和请求处理顺序,保证电梯运行的高效和合理。在之后自己的思考和同学的帮助下,我对这个电梯调度迭代问题还是有了一定的认识,下面我且谈谈我对于这个题目的浅显的理解总结于看法。
设计
第五次作业:主要就是分为电梯类和Main类,类图如下:
Main类是处理与操作的类,而Elevator类中则负责储存各种属性,储存内外部命令,以及给Main类提供可调用的方法。
第六次作业:类不再仅仅限于两类,题目要求使用多个类别储存属性,状态,命令等等,为进一步实现单一职责原则,控制类出现在我们的视野中,它的存在如同一个枢纽,汲取命令,让后“翻译”出对应的操作。类图不再单一,如下:
Elevator类:主要是各种属性的getter、setter方法,以及对队列楼层是否合法的判断。
Direction类:为枚举(Enum)类,列举了电梯的三种状态(向上,向下,空闲)。
State类:反应出电梯此时的状态(移动和停止),与Diretion类有着密切联系(只有moving状态下才有UP和DOWN的Diretion)。
ExternalRequest类:用于处理外部请求,有floor,direction两种属性,getter方法能够反映外部请求的需求。
RequestQueue类:其中有内外部队列的getter,setter,add方法,用于处理队列请求,将内外部请求分开存储。
Controller类:除getter,setter方法外,进行了电梯程序主要的算法处理,是处理命令中最直接关键的一环,其中包括电梯的移动,命令的删除等等。
Main类:进行各种属性的输入,将输入的内外部指令分别存入到两个LinkedList中。
此次作业里,学*到了新概念“内部类“,了解到类在其他类中也可以当作一种类型使用。
第七次作业:
若是说前两次作业我还整出来一点名堂来,这第七次作业我就有点糊涂了,在原来的基础上,本次作业又新引入了“乘客类”,在原有的运行规则基础上,又添加了一下规则:
乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层> • 对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)。类图如下: 
本次题目中的其他类别与第六次作业中的设计大差不差,而新增的Passenger类的作用自然是完成此次作业中的新需求:本次作业中的算法逻辑发生了一点有趣的小变化,现在的外部请求更像是两个指令:指令左侧的相当于原来题目中的一个外部请求,而右侧则是额外的一个内部请求,并且会加入内部请求的末尾。这对于我们代码对指令的处理要求就更高了,只有处理好每一个内外部代码的先后与背后逻辑,才能使得电梯正确的运行。
错误心得:
- 第一次接触这个电梯调度迭代问题时,我就犯了一个根本性的错误——我的设计根本不符合这个题目的原则:
![]()
这是第一次题目中的设计样例,我没有认真看懂题目的底层逻辑,只是通过简单的一个样例,误以天真的认为这个题目就是电梯先向上,一直到内外部所有命令中最高的楼层,中途停靠在内外部命令中有的楼层,最后再处理外部命令中Diretion是DOWN的命令,做到真正的只有“一上”和“一下”(我还以为所有的命令是同时发生的,其实只有内外部各自第一个命令同时,有点滑天下之大稽了,hhh)。
2. 这应该是很多人一开始都会忘记考虑的问题:当你下一个处理的指令是一个外部指令,而你从当前楼层去往外部指令请求楼层时,到达目的楼层时的方向可能与外部请求的方向相反,此时务必要将状态改为外部请求的状态,而不是保持原来的状态,例如,电梯以UP的状态到达目的楼层,而外部请求的方向是DOWN,不改变方向则在接下来的进程里会优先处理UP方向的指令,与题目里的逻辑不符。
3. 第三点算是我个人的一点小问题,我思考的时候老是会钻牛角尖。例如:
第七次题目里有个测试用例是:
这很好理解嘛,
外部:<5,9>,<9,3>
内部:8,4,2
根据题目的要求,第一个处理的是外部的指令,
结束后成了:
外部:<9,3>
内部:8,4,2,9
一样的逻辑以此类推,很快就能推出 
的输出结果。
但是我看到内外部指令第一个楼层数相同的时候愣了一下(当时真没有直接转过弯来),例如:
当时吧我在想,这是先处理内部啊,还是处理外部啊——纠结老半天。后来想通透了:外部方向DOWN则先处理内部,方向为UP则一块处理了,只能说平常对于生活的观察和理解还是太缺乏了,毕竟这是生活中再平常不过的情况了。这跟老师上课所说的不谋而合:把代码中的各种逻辑和关系与实际生活中的各种现象结合起来理解,这样才能有助于我们加深对于代码逻辑与深层含义的理解。
自己做题过程中一点小阻碍后的一点小分析:
- 内部指令和外部指令总有一方会先将所有的指令执行完,这时候要对其对应的LinkedList进行验证,如果其中一个为空,则要将另一个LinkedList中的其余指令全部按顺序执行,这是题目的底层规则逻辑,因此这方面得做好
![]()
这样的一段代码是必不可少的。
2. 对于第七次作业里的外部命令分析:
如何分析对外部命令是题目里的关键,例如<5,4>的命令其实可以是看作原来题目中的<5,DOWN>+“<4>”,“+”表示附带,附带就是执行前一个才会出现的东西,意为执行了<5,DOWN>后会在所有内部请求后面再填上一个<4>的命令,因此它(们)基本上在其他命令之后才会执行。
改进建议(对自己):
说实话,我上学期养成的写代码*惯很不好,表现在很多的方面。
其一:没有在代码后写注释的*惯,当时觉得没什么是因为代码都很很简单,一眼就能看到想要的部分,这个学期可不一样了,这才刚开始就是几百行代码,别说老师懒得一点点找,就是自己找部分想要改错或者优化都得找得自己眼花缭乱。因此,从现在开始培养出写注释的*惯很有必要,这也是为日后学*与工作中打好基础。
其二:写代码老是搞自己的一套格式,虽然自己看着没啥问题,但是其他人会看着很别扭,这种东西也有自己的业界规范,只能尽力去向那上面去靠了。
其三:以前为了偷懒,我会将所有的变量(现在的属性)写成a,b,c等等为了方便,其实这是一种很不好的*惯,这个学期开始我已经开始在慢慢改正了,希望能形成*惯(这其中造成了一定的困扰,例如:方法名很多都是有大写字母的,我原来会把判断闰年的函数(方法)命名为ry(run year)有点搞笑了说是)。
然后是关于进步方面的一点建议:
Java与c语言不同,c语言中要用的函数大多数要靠自己写,而java中自带了很多final 类,例如Math,我们在知道的情况下可以直接调用其中的方法,例如Math.abs
等等。所以java语言本身给我们提供了这么多的便利,我们怎么能不好好利用,所以,接下来我要去多记一些自带方法的使用条件与效果,使得代码编写的更加便捷。
最后是老生常谈的问题,注意好每一段代码中的单一职责原则问题,使得我们写出来的都是,合格,严谨,优秀的代码。
总结:
这一轮的pta题目可以说做的很失败,总的来说两个原因:1.把问题想得太简单2.花的时间不够多,吸取这一轮的经验,争取下一轮做好来。
这次作业虽然结果不理想,但是也有所收获,增强了java语言的基础,学会了LLinkList的使用,学会使用内部类等等,希望在接下来的学*中更*一步


浙公网安备 33010602011771号