301
社区成员
发帖
与我相关
我的任务
分享本单元的主要学习内容是JML规格的掌握与使用。JML的作用在于通过形式化规范和自动化工具,帮助开发人员编写更可靠、更高质量的Java代码,并确保程序行为符合预期。熟练运用JML可提升代码的整体可读性
黑箱测试指测试人员在对代码测试的过程中不需要了解具体的内部实现,只关注输入和输出。而白箱测试中测试人员需要了解软件的内部结构和实现原理,通过分析代码逻辑来设计测试用例,确保代码的每个路径都得到测试。
黑箱测试的优点
黑箱测试的缺点
白箱测试的优点
白箱测试的缺点
从上述分析来看黑箱测试与白箱测试是互补的,两者结合使用可以更全面地保证代码的质量。黑箱测试从功能和用户角度出发,确保项目满足需求;白箱测试从代码实现角度出发,确保代码的正确性和可靠性。
单元测试是一种针对软件中的最小可测试单元(通常是函数或方法)进行测试的方法,确保其在各种输入情况下能够正常工作;功能测试用来验证软件的功能是否符合需求和设计规范。测试人员通过模拟用户操作,检查系统的各个功能模块是否正确实现;集成测试则验证多个模块或组件之间的交互和集成是否正确,测试人员将单独测试过的模块集成在一起,检查它们是否能够协同工作;压力测试是一种非功能性测试方法,通过施加超出正常工作负荷的条件,检查系统在高负荷下的表现和稳定性;回归测试指在对软件进行修改或升级后,验证新代码是否引入了新的错误或导致已有功能失效。
不同类型的测试方法各有侧重,适用于不同的测试阶段和目的。单元测试侧重代码的正确性,功能测试侧重系统功能的实现,集成测试侧重模块间的交互,压力测试侧重系统在高负载下的表现,回归测试侧重修改后的稳定性。通常综合运用这些测试方法,可以更好地确保项目的质量和可靠性。
对于测试数据的构造一方面从随机性考虑,可以构造数据生成脚本,这样做可以一定程度上扩大测试的覆盖率,同时可以通过调节测试指令的分布来验证特定功能的正确性;另一方面从极限的角度考虑,可以手动构造一些极端数据用于测试,这对于测试代码在极端情况下的正确性以及代码的性能有很大帮助。
通过JML规格的描述,可以大致确定关于图的存储格式为邻接矩阵,为了实现更好的的查询性能,代码中大部分数据结构使用Hashmap。对于有特定需求的数据,如每个person的messages需要有头部插入的功能,可以选择双向链表优化插入性能。除了数据结构方面的优化,算法方面的优化也是不得不需要考虑的一部分。接下来我将针对本次作业中实现的几个比较重要的算法优化进行分析。
并查集
在本单元第一次作业中,有isCircle方法,来测试图中两点是否在同一个连通块中。而isCircle方法在JML规格中的实现的时间复杂度很高,考虑到超时的可能性,可以选择并查集进行方法的实现。并查集(Union-Find Set)是一种用于处理不相交集合的数据结构,主要用于解决动态连通性问题,时间复杂度接近O(1)。
动态维护
在本单元作业中,有很多方法在每次调用时如果重新计算,时间复杂度未免会很高。如果当图产生改变时,方法测试的属性只会发生很简单的变化,则可以考虑动态维护来大大降低方法的时间复杂度。例如query_triple_sum、query_block_sum、query_tag_value_sum、query_tag_age_var、query_social_value等指令,可以通过动态维护的策略大大减小方法的时间开销。
设置“Dirty位”
有些操作并不需要跟随指令的添加而实时进行,而是可以只在有需求的情况下进行调用。比如图中可能有删除边的操作,这时可能会产生重建并查集的需求。然而重建操作的时间开销显然是很大的,所以我们可以设置一个Dirty位,只有当Dirty位为真并且需要使用并查集时才进行重建操作。
本单元另要求了对代码的一些方法通过JUnit进行测试,来验证方法的正确性。对于测试的思路,我采用了随机生成图的方法进行多次测试。随机生成的图有利于更好的覆盖图的不同情况,相比于手动生成特定图减少了针对数据生成的考虑的难度。同时基于JML提供的帮助,可以通过对JML规格中的很多条件进行一一检验,提高了方法检验的完整性。
本单元主要讲授了JML规格语言以及契约式编程的相关内容。由于我第一次接触JML这种规范化语言,所以在理解和掌握的过程中难免花费了不少的精力。虽然感觉JML对于今后的实际生产生活帮助可能不大,但是多掌握一项技能肯定不是坏事。