BUAA_OO Unit 3

刘祖权-22371221 学生 2024-05-18 13:38:23

一、整体架构

本单元由于 JML 的存在,大部分时候做的只是翻译工作,将 JML 的规格描述转换为代码。只是对于少数几个函数,如 queryBlockSum,出于性能考虑,需要进行特殊的结构设计。

图模型构建

​本单元实现的社交网络本质上是一个无向带权图。将 MyPerson 作为节点,acquaintance 设计为 HashMap,其中存储了该节点的邻接节点及对应边的权。社交网络的基本功能为增加节点、边,修改权值,查找连通性、连通块个数、三元环个数、最短路径,以及相邻节点间的消息传递等。

并查集

​本单元代码中,唯一一个不在 JML 规格描述中的类为 Conuter,主要目的在于建立并查集,以提高 queryBlockSumisCircle 的性能,顺带动态维护了 TripleSum。为了进一步提高性能,在并查集中采用了路径压缩的策略,避免树的深度过大。在删边时,只重建与两个节点有关的部分并查集,可以有效的节省时间。

动态维护

​测试点中会出现查询指令多次重复的情况,此时时间复杂度较高的遍历查找往往会超时,所以动态维护一些需要查询的值就显得很有必要。在 Counter 类中,加边、删边的同时动态维护了 blockSumtripleSum。对于 queryTagValueSum,在加边、删边、修改权值、addPersonToTagdelPersonFromTag 时,动态维护相关 TagvalueSum。这样的设计虽然增加了简单操作的成本,但同时有效地将 queryTagValueSum 等方法的时间复杂度降低到了 O(1)。

二、测试

黑盒测试与白盒测试

​黑盒测试只关注程序的每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口处进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。

​白盒测试又称为结构测试或逻辑驱动测试。在测试中,把程序看成一个透明的盒子,测试人员需要理解程序内部的代码逻辑、数据结构和算法,并据此设计测试用例,对程序可能存在的逻辑、性能问题进行检查。

单元测试、功能测试、集成测试、压力测试与回归测试

  1. 单元测试:指对软件中的最小可测试单元进行检查和验证。“单元”一般是一个函数、方法或者类。单元测试通常采用白盒测试,在理解代码逻辑的前提下进行。
  2. 功能测试:检验软件的功能是否满足设计要求,通常采用黑盒测试。
  3. 集成测试:软件通过单元测试后,需要检验方法间的协同、模块间的交互是否正常。测试中应采用增量集成,相比一次性集成更容易发现问题所在。
  4. 压力测试:对软件施加沉重的、超出正常工作情况的负载,以测试软件在极端条件下的性能和稳定性。
  5. 回归测试:在代码进行修改后,重新测试此前已经进行过的测试,以确认此次修改没有引入新的错误。

数据构造策略

  1. 增加数据规模:通过构造大量的数据,尽可能提高测试用例的覆盖率,同时对程序的性能进行检验。
  2. 设计针对性数据:一方面是进行边界情况测试;另一方面是在了解程序内部逻辑的前提下,针对可能存在的逻辑漏洞设计测试用例。

三、性能问题及修复情况

重建并查集超时

​起初采取删边时无脑重建整个并查集的方式,但在数据规模极大时会出现超时现象。为此调整为只重建与两个节点有关的部分并查集,问题得到了修复。此外,也可以设一个脏位,在删边时将脏位置 1,但并不重建,而是在需要查询时再进行重建,这样有效减少了重建的次数,也可以改善性能问题。

queryTagValueSum 超时

​在编写此方法时并没有意识到,但如果单纯按照 JML 进行循环遍历,此方法的时间复杂度为 O(n^2)。为此改为了动态维护每个 TagvalueSum

规格与实现分离

​规格明确了方法的功能,限制了方法的作用范围,但不对其具体实现作要求。在实现规格所要求的功能时,需要考虑到代码的简洁与性能,必要时可以设计规格中未提及的属性、方法、类以辅助实现。

四、Junit 测试

  1. 前置条件对测试点的数据进行了限制,或者是对可能出现的不同情况进行了说明,可以据此提高测试的覆盖率
  2. 根据规格的副作用要求,在 Junit 测试中检验是否有限制范围之外的对象被改变
  3. 后置条件明确了方法的功能和返回值,是测试中最重要的部分

五、学习体会

​本单元在代码实现上轻松了不少,因为 JML 的要求清晰明确,大部分时候做的只是翻译工作,还挺喜欢这种编程形式的,每个方法的功能很明确,方法间的协同性很好,代码的可读性也得到了提高。在具体实现中,学会了并查集的实现与其优化:路径压缩、按秩合并,以及用动态维护降低方法的复杂度。

​三次编程任务结束后,遗憾还是有的,一是对 JML 的阅读不够细致导致 HW11 出现了很愚蠢的错误;二是HW9 的 case6 到底是什么样例,到最后都没过……

...全文
56 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧