北航OO(面向对象设计与构造)课程2023第三单元总结

北航面向对象设计与构造第三单元总结

1 测试过程

1.1 对各种类型测试的理解

所谓黑箱测试就是完全不考虑被测试程序的内部结构,再此基础上构造测试数据并比对输出判断正确性。

白箱测试就是分析被测试程序的内部结构,分析出程序容易出错的薄弱点,再针对性的构造测试用例进行测试。

单元测试是针对程序的最小模块进行正确性检验的测试工作,通常情况下是白盒测试。

功能测试是从外部需求的角度,检验程序能否正确满足所有种类的外部需求进行的测试工作,通常采用黑盒测试方法。

集成测试的目的是发现各单元间的接口可能存在的问题,在多个单元测试的基础上进行,对象是多个通过单元测试的模块

压力测试,测试程序在高负载情况下系统的稳定性。

回归测试是在代码发生修改后使用测试过的所有用例重新测试,避免代码的修改引入新的错误。

1.2 使用的测试

在本次作业中,我主要使用了对拍程序(对往届的对拍器进行指令集层面的修改)对我和同学的代码进行黑箱测试。
此外,较为特殊的是,对OKTest进行的测试类似于“灰箱测试”,既考虑了HashMap数据结构本身的特点(例如Key不存在或KeyValuenull时,查找Key的返回值都是null)。

1.3 测试用例的构造

在本单元作业中,就我所使用的对拍器而言,输入指令的类型为完全随机,id的生成设定为以特定概率生成出现过的id和新id,用来保证数据的多样性。

为了进行qts, qbs, qcs, qlm等时间复制度明显较高的指令,我专门设置了指令集用来进行性能测试避免因为算法复杂度问题发生TLE,例如,

qlm_list = ['ap', 'ar', 'mr', 'qlm'];

专门用来测试qlm指令的执行性能。

2 总体结构

在这里插入图片描述

以上为我本次作业最终架构的uml图

2.1 异常部分

实现了一个ExcCounter类用来对每类发生的异常进行计数。

2.2 Network部分

包含了peoplegroup容器,均使用HashMap实现。
另外由于对Message的操作较为独立,仅依赖messages容器,考虑到文件代码行数的限制,将message相关操作包装为MessageWork类,也可以视为是增量开发的结果。
另外即使是从Network的语义来看,Network也是person(也包括group)构成的网络,而messeage是他们直接交换的内容,所以单独再封装一层也是合理的。

2.3 图模型构建和维护

再一次的,由于三次作业增量开发的锅,我的代码中其实存在两个图。一个图是Networkpeople容器中的person根据acquaintance关系形成的图,我根据这个图来完成qbsqtsqcs操作。一部分原因也是完成这几个操作的图算法相对简单(dfs和并查集),直接利用实际的关系进行了。

但是在第十一次作业中,qlm使用的dijkstra算法较为复杂,而且需要使用新的数据结构(邻接表和堆),出于独立性的考量,我终于还是专门构建了Map类对整个person间的人际关系进行抽象化的模型描述。在aparmr等操作时也对Map进行对应的修改。

3 性能优化

在第一次作业中,由于qbsqts操作的全局性较强,我使用了update标志用来记录上一次操作的结果以降低连续查询操作下的时间复杂度。

针对qbs操作,在第九次作业中使用了并查集算法尽可能优化,但是在后续任务中考虑到维护的复杂性问题退回到了dfs,稍微牺牲了一点性能。

针对qts操作,我在和同学的交流中获得了一种优化算法,大体思路是根据personid顺序进行三元环的遍历,减小了重复性的遍历次数。

qcs操作,我维护了每个personbestAcquaintancevalueid,而且并不是在所有类型的修改后无脑置脏位:

bestAcquaintance的value增大,更新其value即可

bestAcquaintance的value减小,置脏位

新acquaintance的value增大,更新bestAcquaintance和对应value

针对qlm操作,我使用了堆优化的dijkstra算法优化稀疏图下最短路径树的生成。遍历所有不在最短路径树上且不和根重合的边以及与根重合但是不在最短路径树上的边,通过这种方式在一次搜索的前提下找到满足要求的环路,时间复杂度约为O(VlogV + E)

最后,对规格与实现分类的感受,就是充分理解的规格需求之后就可以一定程度上的为了时间复杂度进行变通。最简单的层次就是在容器选择上使用HashMap,更多的是算法层面的优化,但是作业中的需求大部分都是较为常见的图论算法(就算自己一时间想不到上网或者与同学交流也可以得到启发),所以在算法层面满足规格要求可能是比较容易的一件事(没有太多需要我们额外重点关注的)。

4 bug

4.1 第九次作业

qtsOK方法中的多重循环嵌套中没有更新循环内部的iterator导致遍历不全

qts方法中,未能对people实现时使用的容器选择正确的遍历方式。使用根据for循环遍历数组的方式(规格中的写法)遍历了用HashMap实现的容器。

4.2 第十次作业

在写oktest过程中出现笔误

在oktest比较前后HashMap的not_assign要求时忘记了对比beforeDataafterData的size大小

4.3 第十一次作业

在课下测试的过程中发现了oktest的bug(Key不存在或KeyValuenull时,查找Key的返回值都是null)。强测中未发现bug。

4.4 测试策略

由于第九次作业没有对拍所以错得比较惨,后两次作业我修改了往届学长的对拍器(https://github.com/Hyggge/BUAA-2022-OO-JudgeSystem),但是没有做oktest的构造。关于oktest的测试是与同学一起手动构造完成的

5 OKTest

在实际完成作业的过程中,我并没有使用OKTest对我编写的对应程序进行测试(因为转换过程需要额外写代码+可以使用对拍黑箱测试完成测试,功能上存在重复),最终还是把它当成了一个普通的函数完成。

以后可以考虑增加在互测中为同学的代码编写oktest的任务,更有体验感。

6 心得体会

感觉本单元作业主打的就是一个细心,前几次作业中的强测bug也是没有完全完成规格要求(尤其是oktest)导致的,感觉oktest才是真正考察jml和规格实现理解的重点部分。

另外,本单元作业另一个较为花费时间的领域是算法的优化,这点上网搜索和与同学交流是破局关键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值