SC_lab4 异常处理

Lab 4实验报告

1 实验目标概述
本次实验重点训练学生面向健壮性和正确性的编程技能,利用错误和异常处 理、断言与防御式编程技术、日志/断点等调试技术、黑盒测试编程技术,使程序 可在不同的健壮性/正确性需求下能恰当的处理各种例外与错误情况,在出错后 可优雅的退出或继续执行,发现错误之后可有效的定位错误并做出修改。 实验针对 Lab 3 中写好的 ADT 代码和基于该 ADT 的三个应用的代码,使用 以下技术进行改造,提高其健壮性和正确性: ⚫ 错误处理 ⚫ 异常处理 ⚫ Assertion 和防御式编程 ⚫ 日志 ⚫ 调试技术 ⚫ 黑盒测试及代码覆盖度

2 实验环境配置
在实验手册中找到给出的实验四仓库创建连接。进去后创建实验四的GitHub实验仓库。本地创建实验四的工程项目,利用git将工程仓库化,让后和GitHub上的仓库进行连接。传上去一个README.md。配置建立就完成了。

3 实验过程
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 Error and Exception Handling
3.1.1 TrackGame
首先是对田径比赛的处理。要明白什么时候会出现要处理的异常,所以先看看实验三的实验手册

首先是对game,即赛制的限制,赛制只能是三选一,且只能出现一次。所以检测到违规赛制,或者多次匹配到game时,就要抛出异常。
检测到game赛制违规时:

检测到赛制重复出现时:

然后是对运动员的检测。姓名国籍等各种规范,在利用正则表达式匹配时就已经做出了规范。若是不符合规范就会不进行匹配。对运动员重名不进行考虑(只要不完全重复就行了),而且若是完全重复的话,不会加如到轨道系统中去。
接着是对赛道数量的异常检测。 要求是4~10,如下:

至此,trackgame的文件读入的异常处理完成。(后续会补入日志记录)。

3.1.2 AtomicStructure
首先是电子轨道的要求

首先是对中心元素名的匹配。这个没啥问题,只要匹配到了,就一定合法。没匹配到就交给checkRep来进行判断了。不过存在元素名重复的情况:

轨道必须是正整数:

电子排布的情况比较多。如轨道号重复出现,轨道号大于了轨道数目,轨道号为负,轨道号不按照升序排列。在对匹配到的语句进行处理时进行异常处理:

3.1.3 SocialNetWork
首先看要求:

对于中心用户和friend,两者其实是完全相同的。区别之处是个数上的差异。所以对于centraluser,要判断是否重复:

对friend,以姓名和性别的判断为主:

之后便是对关系的判断了,这个的情况多了几个,首先是关系度的取值范围(0,1]:

然后是添加的关系中,有一个人不存在:

然后是对两人的关系重复设置:

。大致就这样。
3.1.4 异常的统一处理
三个轨道系统采用了同样的异常处理方法,即捕获到异常后,先打印出异常信息,然后读取文件的方法返回一个异常值,gui部分检测到这个异常值后,就提醒用户换个文件。否则的话,就正常进行可视化构建。下面是social network中的处理:
捕获异常

处理:
.
3.2 Assertion and Defensive Programming
即对ri等部分的防御性检测。因为公用一套adt,有时候参数的传入是固定的,所以就可以进行该部分的检测,防止程序故障。
3.2.1 checkRep()检查invariants
主要是对concreteCircleOrbit的表示不变量的检测,代码如下:

依照RI,中心物体必须存在,轨道物体也不能为空。利用assert进行断言。
然后是集合内不能有重复物体的存在。
在三个轨道系统的操作中,操作结束后分别调用checkRep进行判断。
如:在删除人员后进行checkRep,等。
3.2.2 Assertion保障pre-/post-condition
对传入的参数进行判断。
3.3 Logging
为程序加入日志功能。
3.3.1 写日志
大致了解了logging的功能后,发现并不怎么好用,于是决定自己写一个log类来存储相关的日志信息。
为日志类设置了域:

第一个是用来记录时间的,第二个二是记录方法名的,第三个是记录日志信息的。
构造时,time是实时构建的,故不用传入time的信息。
然后创建了构造方法。还有三个部分的get方法。然后重写了toString方法,便于打印后的可阅读性。
之后便是在每次检测到异常,或者对轨道系统进行了操作后进行日志的记录了。
对异常信息的记录:

先获取异常的各个信息,然后记录到日志中去。
对正常操作的记录也很简单:

直接手动编写日志信息就行了。
3.3.2 日志查询
我为日志查询编写了四个功能,分别是:全部日志查询,异常的查询,普通操作的查询,按方法名的查询:

日志也具有较好的可阅读性:

3.4 Testing for Robustness and Correctness
3.4.1 Testing strategy
对于各种文件读入可能出现的错误,分别编写相应的文件,进行输入测试。

  1. 对trackgame,分别进行,赛制重复,赛制错误,运动员重复,赛道数错误的异常检测
  2. 对atomstructure,分别进行,元素名重复,电子轨道数异常,电子信息错误进行异常测试
  3. 对socialnetwork,分别进行,中心人重复,朋友重复,关系度错误,关系重复的异常测试
  4. 对concretecircleorbit的各个方法进行测试
  5. 对各个adt的rep进行测试
    3.4.2 测试用例设计
    运用了junit的异常测试功能,expectexception方法,分别在文件中加入上述所说的错误,然后调用readTxt函数,检测是否抛出对应的异常。
    而对adt的各个方法大部分是boolean型的,将各种false和true的情况进行测试即可
    3.4.3 测试运行结果与EclEmma覆盖度报告
    测试用例是全部通过了;下面是各个测试文件的通过结果:

由于对gui的测试异常的困难,所以没有进行。导致了覆盖度不高。

语句覆盖度:

分支覆盖度:

路径覆盖度:

3.5 SpotBugs tool
发现了哪些错误,每种错误代表什么不良的编程习惯
发现了许多无用行。删除就行了。代表了我写代码太随意了,这样会导致代码的结构与可读性很差。
发现了大量的adt没有重写hashcode方法。没了解到这个方法有什么用。
重写equals方法时,可能用到hashcode方法,但没有重写。
几乎所有的bug都是由于没有重写hashcode方法所导致的。好吧,看来我得去了解一下hashcode的作用和写法了。经了解后,这就反映了我对java的一些基层的内容不够了解。
3.6 Debugging
我得三吐槽一下,上来个神仙算法让人debug,这算啥啊?而且有一处直接改变了算法的原意了好吧,根本不能算是bug了吧(直接是个失败算法了)。
3.6.1 理解待调试程序的代码思想

  1. 两个有序数组,找到中间值。
    先找的实际上的中间位置,然后将数组二分,以此搜索,左边的值都小于该数,右边的值都大于该数,然后对奇偶情况分别处理就行了。

  2. 删除注释部分
    设置个flag值,先匹配到/*的话就设为最高优先级,没有匹配到就正常输出,匹配到,则之间的内容全部作废。 //后的内容全部作废。

  3. 按一定规则找到对应时间点票数最高的人
    先用二分法根据获胜情况将投票情况顺序分组,在二分查找对应时间点的获胜情况。
    3.6.2 发现并定位错误的过程

  4. 一眼就看到中间位置求错了。然后造个数据进行debug,发现奇偶处理反了。

  5. 很明显的就能发现对//情况没有处理,然后造数据跑一遍,程序报错,凭经验仔细一看就发现数组越界了。

  6. 一开始没看懂,直接debug,发现了二分时陷入了死循环。然后
    {这个是修改过的代码}这个部分意义不明,最后发现是计票数用的,原代码不知道是什么骚操作(就是我要吐槽的bug)。
    3.6.3 如何修正错误

  7. 求中位数加个1,模2判断==0

  8. 增加对//的处理,加强判断条件,防止越界。

  9. 对while循环的左边界加1处理,防止死循环,计票数的1提到外面去。

3.6.4 结果
对三个代码,造了样例数据,然后写成了测试,测试情况如下:
测试的比较全面了。
然后在leetcode上发现了原题。交上去后通过。顺利解决问题。
4 实验进度记录
请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
日期 时间段 计划任务 实际完成情况
5.17 17-22 完成第一部分 完成
5.18 17-22 完成日志功能 未完成。在debug
5.19 11-21 完成全部代码部分 完成
5.20 14-19 写实验报告 完成
5 实验过程中遇到的困难与解决途径
遇到的难点 解决途径
异常怎么用,怎么捕获操作
Csdn找到了相关介绍。解决了
被调用函数所抛出的异常,无法被调用者函数所捕获。
网上没找到想要的答案,然后直接在被调用函数里捕获处理了。
Logging怎么用,是要输入到文件里吗
了解相关功能后,发现在lab4里logging貌似不好用,所以自己写了一个简易记录日志的log类
6 实验过程中收获的经验、教训、感想
6.1 实验过程中收获的经验和教训
测试技巧很重要啊,还有对代码的构架。这次写实验时就发现了我的代码结构很混乱,导致了一些遗留问题这次也没能解决。最大的教训是:可视化要写在一个部分,否则的话刷新界面都做不到啊。感想就是,果然还是得多加练习,只不过写一次gui要付出的代价太多了,不适合像acm那样的做题有趣啊。

6.2 针对以下方面的感受
(1) 健壮性和正确性,二者对编程中程序员的思路有什么不同的影响?
健壮性就会使你在写代码时考虑很多情况,考虑这考虑那,慢慢的代码量就翻了好几倍,但这样写出来的程序用起来很舒服。
正确性则要求对程序的io进行严格的检查啊,写起来是舒服不少,但不加入健壮性编程的话,用起来就很难受。
(2) 为了应对1%可能出现的错误或异常,需要增加很多行的代码,这是否划算?(考虑这个反例:民航飞机上为何不安装降落伞?)
划算,因为代码很容易出错。而飞机是很难出错的。就算安装了降落伞,没几个会用的啊。不安降落伞是因为做足了相关的工作来避免遇到的可能会用到降落伞的情况。 对比到程序中,可能就是0.0000001%会出现的错误了。这时候你不一定能发现这个错误。
(3) “让自己的程序能应对更多的异常情况”和“让客户端/程序的用户承担确保正确性的职责”,二者有什么差异?你在哪些编程场景下会考虑遵循前者、在哪些场景下考虑遵循后者?
设计个程序交给客户使用,考虑前者。写个程序自己用,考虑后者。
(4) 过分谨慎的“防御”(excessively defensive)真的有必要吗?如果你在完成Lab5的时候发现Lab5追求的是I/O大文件时的性能(时间/空间),你是否会回过头来修改你在Lab3和本实验里所做的各类defensive措施?如何在二者之间取得平衡?
保证所作的防御必要而不重复就行了。可能不会修改。 简化防御,删除冗余的防御措施。
(5) 通过调试发现并定位错误,你自己的编程经历中有总结出一些有效的方法吗?请分享之。Assertion和log技术是否会帮助你更有效的定位错误?
设置断点先debug跑一遍。或者打印出关键值。估计没,还没有sys.out好用。
(6) 怎么才是“充分的测试”?代码覆盖度100%是否就意味着100%充分的测试?
不是,对各种情况都考虑到的测试才是充分的测试。这就看个人的能力了,看你想到的情况是否全面。
(7) Debug一个错误的程序,有乐趣吗?
算法程序debug有趣,软件构造实验debug无趣。
(8) 关于本实验的工作量、难度、deadline。
适中,难度适中,deadline也还行(还是希望能考虑到其它课程的考试)。
(9) 到目前为止你对《软件构造》课程的评价和建议。
很好的一门课吧,目前的感觉是具体内容自学的比较多。目前是只关注于java,但各种思想和模式是否能讲一下迁移到其他语言的例子呢
(10) 期末考试临近,你对占成绩60%的闭卷考试有什么期望或建议?//请严肃的提出,杜绝开玩笑,教师会认真考虑你们的建议。
希望不要出现手写大量代码的题目(说的就是数据结构课),debug的题目还是挺好的。希望不要出现api的一些稀奇古怪,平常根本没用到的方法,或者做出一些介绍再考也行。还有不希望出一些考验眼力的题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值