301
社区成员
发帖
与我相关
我的任务
分享黑箱测试是根据软件的需求或功能来设计测试用例,不需要了解内部代码结构或实现细节,只关注输入和输出以及软件功能是否符合预期。在测评网站上进行的测评就是一种黑盒测试。
白箱测试是一种需要了解软件内部代码结构和实现细节的测试方法。其重点在于检查软件的内部逻辑是否正确,是否符合设计要求,以及代码是否达到预期的覆盖率。在作业中针对具体的方法,考虑到每个分支的情况,编写junit进行测试即是一种白盒测试。
在作业的测试中针对关键的方法编写junit测试,保证每个分支下方法的正确性。同时在代码完成后通过测评网站进行黑盒测试,在测试出错时根据出错的测试数据进行调试,查看代码内部的问题。通过黑箱测试与白箱测试的结合,可以大大提高测试的效率以及代码的正确性。
qts,qtvs等,这些查询函数如果设计不好很容易出现性能问题。addPersonToTag中tag大小超过1111的情况。此外还有MyPerson类构建堆时两个person对象进行比较时,若处理不当还会出现数据溢出的情况导致出错。UML类图:

采用并查集维护连通分支,在并查集构建的过程中采用路径压缩和按秩合并来进一步优化。在删边时选择重建并查集,但并不是在每次删边时都重建一遍,而是在查询时重建,从而减少开销。在isCircle()查找时只需要查询两节点的根是否相同即可,复杂度为O(1)。在查询分支数量时遍历查找根的数量,复杂度为O(n)。
对于queryTripleSum()使用变量tripleSum进行维护,在关系增加或删除时遍历其中一人的好友,若为两人的共同好友则对变量'tripleSum'进行增减。
本次作业引入了Tag类,对于Tag类变量的均值和方差使用变量进行维护,在增减人时进行更改。对于ValueSum的维护,在增减人时需要遍历tag中所有人与此人的value进行维护。此外在netWork类中关系变化时也需要进行维护。通过定义HashMap<Integer, HashMap<Integer, ArrayList<Tag>>>类型的变量tags,记录同时拥有两人的Tag变量。当修改关系时通过该tags获得响应的Tag变量维护其valueSum的值。
对于queryCoupleSum()也是选择维护变量coupleSum。当修改关系时:修改前分别判断两人如果为一对couple中的一个则coupleSum减1,修改后分别判断两人如果为一对couple中的一个则coupleSum加1。同时注意有些情况下两人互为couple的情况。从而实现对coupleSum的维护。
对于queryShortestPath()函数由于只需要返回路径长度,因而选择dfs来实现,并从两个端点同时开始遍历,这样在面对稠密图的时候会有更好的性能。
在deleteColdEmoji()方法中需要删除某个emojiId的EmojiIdMessage变量,因此我定义了HashMap<Integer, ArrayList<Integer>> emojiToMes变量,在增添消息时进行维护。这样在删除时只需要根据emojiId获取相应的消息序列,而不用遍历所有消息,减少了开销。
在hw9中由于在每次删边时都进行并查集重建,开销过大。通过修改为查询时查询时重建解决。
在hw10中queryCoupleSum()通过遍历查询实现,开销过大。通过修改为上面提到的维护方法解决。
规格中对于方法的描述只保证了基本功能的正确实现,但并不保证性能的良好。我们在具体实现时要选择合适的数据结构与算法。
Person类的规格描述中反复强调acquaintance与value数组的长度相等,相同位置的对应关系,我们很容易想到使用HashMap类型的变量进行存储。queryShortestPath()方法的规格中只对最后返回的结果以及中间变量的内容作了约束,我们不可能据此来实现方法,需要自己选择算法来实现。而像int queryTripleSum()方法的规格其实就描述了实现该方法的一个算法,但该方法复杂度较高,我们仍需要考虑其他更优的算法。在编写Junit时我们需要检查规格描述的每一个信息,包含:
通过本单元的学习让我初步了解了JML这一规范化语言。虽然在初次接触的时候抱怨其描述的繁琐和复杂,但是通过三次作业的完成,我逐渐感受到JML独特的优势:通过前置条件、后置条件和类不变式的规定,我能够更清晰地了解程序的预期行为,这种严谨清晰的表述也减少了我在代码编写中出现错误的情况。同时在阅读规格描述时我能够深入地理解方法的作用和实现细节,为我实现方法提供了思路。
我还学习到一些图论的经典算法,如并查集,最短路径等,以及方法优化的一些思路,如变量的维护,脏位的设置以及数据结构的合理选择等。