第一次OO作业总结

时间:2021-04-13 17:25:14

前言

   在写第一次作业之前,我对java可以说是零基础,只是在刚开学的几天大致看了一下一个网站上的java教学,虽然现在回头看发现那个网站写的教学内容是不错的,但是由于当时我对面向对象和面向过程的区别不了解,所以看了网站后对java语言的了解还是一知半解。另外,我觉得如果有时间去好好学一门语言的时候,首先基本的一些语法是可以触类旁通的,所以快速掌握一门语言的诀窍就在于实践了,当想实现一些功能,比如要计算两个数相减的绝对值,就可以去上网查有没有实现的内置函数,这样就能肤浅地掌握一门语言的表面了。

 

第一次作业

  第一次作业由于让我们首先使用c语言写一遍,加之对于面向对象还没有什么深入的了解,所以第一次作业在写的过程中满脑子都是c语言的操作,最后写出来的程序中也充满了c语言的味道。其中我只写了两个类,一个类是装载多项式的类,这个类还装载了计算多项式的方法,另外一个类中主要负责对输入的处理和程序的入口。在处理输入中,由于处理的输入长度不定,写出的正则表达式又可能很复杂,所以我使用了只要细心就基本不会出错的状态机来完成。状态机还有一个好处是不会爆栈,但问题是处理的过程会相对复杂。

第一次OO作业总结

第一次OO作业总结

  从类图中可以看到这个程序的结构非常简单,我将所有多项式的储存在了Poly类里,并在ComputePoly类中对多项式进行计算。同时,处理字符串的函数也写在了ComputePoly类中。

  可以看到,虽然状态机处理的过程复杂,但是时间复杂度并不高,因为只是简单的判断并在状态之间切换,而由于我存储多项式的数据结构是开一个巨大的数组,数组的下标是指数,相应的内容作为指数的系数,所以计算时的时间复杂度会非常巨大,这种方法虽然简单,但是我觉得以后写的时候还是尽量避免这种数据结构。而且这种数据结构带来的问题也是程序鲁棒性的降低。

 

bug检查:

  我的程序由于粗心忘记设定处理单个数字过大的情况,导致在这个点上报错。由于作业相对简单,和我选择的数据结构的方便性,所以并没有什么其他错误。

  我的数据由于是使用了用数组下标作为指数的数据结构,所以输出的时候非常方便,只需要顺着挨个输出就行了。但是我在查别人的bug的时候发现了其程序没有考虑输出顺序的bug。

 

第二次作业:

  第二次作业相对于第一次作业来说,难度应该是一个很大的提升,因为第二次作业中突然要模拟一台电梯的运行,所以难点主要集中在了对这种状态的记录和模拟,而不是像第一次作业一样进行简单的计算,而难点反而放在了对输入的处理上。运行的方式是傻瓜调度,所以难点也并不是放在了运行策略上,而是如何判断处理同质,如何计算运行的时间。

第一次OO作业总结

 

第一次OO作业总结

  通过类图看出,我将处理字符串的函数放在了main函数内,这个处理字符串的函数会将提取的指令放在一个请求类临时变量中,经过合法性判断之后再装入指令队列类queue中。然后main函数调用command类队电梯进行调度。command类中的方法要从queue类中调取指令,运用demand类中的方法提取指令的信息,最终将结果储存在elevator类中并输出。

  可以看到,这次虽然输入的正则表达式非常好写,但是由于输入不仅要匹配正则表达式,还要判断诸如第一条指令是否T为0等很多麻烦的情况,所以导致了处理字符串的函数时间复杂度很高,每次除了正则表达式外,我还要调用一系列的方法对输入的字符串的合法性进行判断。

  这次作业相对于上次作业写得也更像java程序一点了,可以看到主程序主要调用其他类中的方法,管理不同类中的数据。

bug检查:

  这次作业我改过了多次程序的结构,并好好阅读了作业的指导书,所以这次作业中并没有bug,我觉得这次作业虽然难度提升很高,但是如果想清楚了要如何实现的方法,其实这次作业并不算特别容易出bug,我检查的对象也同样没有bug。

 

第三次作业

  第三次作业对输入的处理和很多电梯运行的部分可以说是与第二次作业相同,但是即便如此这却是我完成的最艰难的一次,我自己在构思如何实现的时候经常会陷入困境,不光是自己,甚至我看到有些人为了实现这个程序甚至更改了自己第二次作业储存指令的数据结构。我认为这次作业主要难在对主指令的判断,和在判断完之后如何处理,判断、计算后续的指令。我并没有更改我存储指令的数据结构,而是在原有的数据结构上直接进行更改。这一想法给我提供了便利,也同样让我付出了被报bug的代价。

第一次OO作业总结

第一次OO作业总结

  可以看到,当程序复杂起来并使用了继承和接口后,我的程序类图又变的杂乱起来,而且我认为这并不是程序本身要求复杂的问题,应该是我自己在写的过程中复杂化了我的程序结构,毕竟这次我对程序的改动很多,事前也并不是想得很清楚,所以总是改改停停,最终弄出来这样一个复杂的程序。我这次程序最复杂的函数在于判断捎带的函数,我将捎带的类型分的很多,每种都要判断一遍,导致该函数非常复杂。其中main函数中的inputParse方法继续调用用来处理字符串,并通过demand类中的方法储存在指令队列queue类中,然后command类调用schedule方法来处理指令,用inPassing方法来判断捎带指令并在elevator中计算时间,通过duplicate方法来判断同质指令,最终完成计算并输出。

  我在处理指令时,用的方法是将指令全部装进一个指令数组里,然后先确定一个主指令,再根据主指令所在位置,调换后面指令的顺序,要么调换到主指令之前,要么调换到之后,但是这样带来的问题就是我在构建函数的时候考虑到的情况非常复杂,导致我一不留神就写出了一个莫名其妙的bug,最后调试的时候又废了很大的功夫。

bug检查:

  这次我的程序出了两个bug,问题主要是我在写程序时将判断上行情况的代码直接复制粘贴到处理下行情况下去,并更改了相应的参数使其满足处理下行情况的要求。然而后来我在上行程序中找到了bug,却忘记同样去更改下行程序,导致程序处理下行程序中有未考虑的边界情况。

  这次的程序其实难度的提升幅度相对于第一次到第二次的提升并不大,我身边全ac的人比例也比上次更高,同样我检查的人也没有被我检查出bug。

 

总结

  这几个星期来,经历了从java零基础入门到略微识得一些皮毛,可谓是开学学习进步最飞速的一次,也是我真正感受到推背感的一次,幸好每周至少都在ddl面前存活了下来,但是这样的苟活也让我意识到了自己拖延症的致命性,所以从这一角度上来讲,我觉得最好还是每天想一想自己还有哪些硬性指标没有完成,这样即便做不完也去做一些,在最后晚上躺在床上时也会睡的心安理得。

  这门课的压迫感,从零基础一上来就开始编一些稍微有点难度的程序,比之于机组,我觉得更是对自己自学能力的考验,机组的知识是多而广,但是都只略微掌握一些,我认为这门课正相反,每节课抛出一两个知识点,下一次作业就必定要让你掌握了不可,但有了这门课的经验,也让我对以后迎接更加艰巨的任务有了更多的信心。

  在设计一个程序的时候,我之前更偏向于在头脑中构思出来大概的程序逻辑,再进行相应的设计。但是当我遇到诸如第三次作业这样设计比较麻烦的作业时,我时常会陷入思维的困境。我得出的心得是,当我们在设计一个比较麻烦的程序时,一定要先想好不同的需要处理的块,例如比较麻烦的第三次作业,首先我要想好用什么数据结构来储存我的指令,想到了这一步,才能去构想使用何种方法来判断同质和捎带。所以在思考的时候,要思路清晰,比如我选择了使用第二次作业的数据结构,就再去考虑基于这种数据结构的方法,将方法分为捎带的判断方法和同质的判断方法,再想想分别应该在何时处理,会不会有冲突,这样程序的架构就清晰起来了。

  在找bug时,我个人更倾向于想到一种bug种类,这种bug常常是我自己写的时候一开始没考虑到或是有别人提醒我我才想到的,然后基于这样的考虑再去构造bug测试点,当然,同样不应该忽视压力测试和边界问题测试。而对于随机生成输入来检查bug的方法,我本人更偏向于前者,即通过思考来构造bug。

 

写在最后

  在写程序的时候eclipse自带的debug功能非常强大,由于我没有写一块就测试一下bug,而是直接写完再统一测试,所以eclipse自带的debug可以很容易让我知道我的bug出在哪个方法调用里,而且oo的课上测试使用这个debug功能也非常方便。推荐对debug比较头疼而且不会使用eclipse自带的debug功能的同学可以去问问身边的人,学习一下。由于本人也是靠别人的帮助学会了如何使用eclipse的debug功能,所以这里便不赘述debug的方法。

  以上便是我在这三次作业中的一些小小的心得体会,与大家分享。