第五次作业
这次作业是电梯系列作业的终极版,要求是使用多线程实现三部电梯的运行。这次作业的难点在于第一次运用多线程技术,对于线程中的行为并不了解,以及电梯功能的实现(如果之前作业采取的是扫描指令队列预先判断电梯行为,而电梯类仅用于实现状态跳转,那么就意味着这次作业要重新设计)。多线程这部分,我在完成作业的时候了解的并不多,仅仅使用了thread.sleep()方法进行对于运行时间的模拟,以及在指令队列中疯狂添加synchronized修饰方法,而并不知道这样的深刻意义。而核心的电梯行为这部分,由于前次作业我最终推到重来,按照指导书的要求采取了标记主请求,记录请求队列,并对电梯行为进行有限状态机的模拟,故而这次作业在电梯核心部分的改动并不多。
关于bug,这次作业犯了低级错误,一是忘记考虑1层向下指令以及20层向上指令的报错,二是忘记invalid和same指令的输出规范(这点我有点不服,这部分的规范助教在知道书中并没有显式更新,而是放在群里更新的,这让很多人都看不到啊……)
度量分析部分,可以观察到的是,程序的Dispatch线程中run方法的圈复杂度过高、嵌套深度过高。这体现了我在实现不同情况下对于请求分发这个过程的实现过于集中在一个run方法下的情况,逻辑判断过于集中,没有分开进行,不利于代码维护。
第六次作业
这次作业在做之前听说是做文件系统,根据往届学长分享的经验,作业难度并不高,我也就没太担心,殊不知,这险些导致我第一次无效作业产生。IFTTT主要是实现对于文件夹的监控,以及对于文件夹内改动的输出。作业核心内容就是使用多线程对文件进行监控,而文件监控这部分有File类,虽然File类存在线程不安全的情况,但是使用自己构造的安全文件类就可以解决。作业指导书看起来并不复杂,但是一些没有注意到的小细节险些杀死我。其一,指导书中并没有显式说明监控对象应为文件或是文件夹,而我在大致阅读完指导书并浏览完在File类中可用的方法之后,在潜意识里认为监控对象只能为文件。其二,没有看清楚需要输出信息的是新增文件,这就意味着,我们必须监控之前文件所在目录下的所有文件,保存后,在于当下文件夹下文件进行比对更新,再判断。跟要命的是,这两点忽视的发现并不是同时的!!!我简直是*^!@#$%
此外,由于上次作业并没有认真学习多线程程序设计,仅仅了解了如何完整所需的程序功能,导致我这次作业在多线程设计方面着实下了很大功夫。我也在最后临近提交的时候,为了保险起见,最后测试了一下程序功能。结果差点心碎,出现了很多我之前没有发现的问题,由于多线程程序调试的不便捷性,我检查起来实在费劲,最后凭借着对于debug信息的判断,勉强de掉了我发现了bug,但对于我能想到的其他一些较为复杂的情况,我没有测试。
不能不说,结果还是挺令我意外的,并没有被测试出bug。虽然这次作业实际难度不低,但是对于最后一些特别情况的处理却没有在指导书里进行显式规定,而是让我们自行在readme中说明即可。我在readme里面说明的并不是很清楚,但是我程序的测试者却没有刁难我…真的谢谢了。
度量分析部分,可以看到,还是一样的老毛病,在圈复杂度和嵌套深度上面出现了问题(这两个想必也是一起来的吧…)。主要问题是请求处理部分包括了对于字符串的处理,导致增加了部分逻辑复杂度。而核心执行部分Trigger,其对于文件的寻找search方法写的过于臃肿,没有统一设计好,而是中途为了debug而添加了许多实际上可以合并的分支,导致的逻辑复杂度过高。
第七次作业
这次作业要求我们实现打车调度功能,是后续作业的基础,十分重要。整体难度不高,核心的路程寻找算法也有给出(我们只需要在找到最短路径的距离的基础上,生成所需的导航就可以了),而图像界面也有帮我们写好(这简直让我们告别了syso debug法啊!!!)。这次作业的核心设计是比较关键的,由于也是请求——请求队列——处理分配请求——目标执行的模板,我就采取了跟我的电梯作业比较类似的设计思路,使用了RequestAdd线程进行指令生成,使用Dispatch类进行指令队列的添加,使用Car线程进行目标对象的行为模拟。由于在测试的时候可以使用gui类生成图形界面来进行程序调试,程序的完成过程变得顺理了很多,一路过来也没有什么特别的问题。
互测方面,我的程序没有被测出bug,而我也没有测出对方的bug。
度量分析部分,可以看到相比之前,有一定的提高。ps:gui的问题不怪我啊…。寻找路径的getRoute方法,在反馈的结果上来看,圈复杂度过高,23确实显得有些渗人。不过这是因为我之前很早就写了相关的内容,当时使用的是比较暴力的上下左右判断,对于点位置的获得需要使用多个if-else判断,而更好的方式应该是gui里面所写的使用{-1,1,80,-80}数组,运用数组下标控制,获得点位置,我想这应该不算是大问题。嵌套深度这边令我有些惊讶,原以为之前出现的嵌套深度问题应该是伴随着圈复杂度过高而出现的问题,这里,我却发现car类下的run方法,虽然没有出现圈复杂度过高的问题,却出现了嵌套深度的问题。我认为应该是对于汽车等待服务状态下,逻辑判断不够紧凑而导致的,7的深度也算是能够接受。