BUAA OO 第三单元总结

测试过程

黑箱测试与白箱测试

黑箱测试是指通过测试来检测每个功能是否都能正常使用。在完全不考虑程序内部结构和内部特性的情况下,
在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收
输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面
和软件功能进行测试。

在我的理解中,黑箱测试是一种对功能的测试,无需程序的具体实现,只用对比输入和输出即可,是通过jml验证自己写的是否正确的主要方式,同时,也是各种测试程序的主要测试方法,但是有可能会出现检查不出程序bug的问题。

白箱测试又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试是一种测试用例设计方法,
盒子指的是被测试的软件,白盒指的是盒子是可视的,即清楚盒子内部的东西以及里面是如何运作的。
“白盒”法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。“白盒”法是穷举路径测试。在使用这一方案时,
测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。

白箱测试是在清楚程序的具体实现后,通过对程序的全覆盖来验证程序每一步的正确性,能够将隐藏的bug揭示出来,也能让自己对程序的具体实现记忆更深刻。但是测试需要构造很多的数据,耗时更多,且不能保证符合jml。

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

单元测试是对软件组成单元进行测试。其目的是检验软件基本组成单位的正确性。
测试的对象是软件设计的最小单位:模块。又称为模块测试

单元测试是对程序的小单位来进行测试,能够找到单独的模块本身实现的bug,便于定位bug的位置,易于修复。如果单元太多会不容易写全。

功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。

功能测试是测试程序的各个功能,类似于黑箱测试,不需要程序的具体实现。能够验证程序在功能上的正确性。便于实现,也能验证是否满足规格。对于程序的问题也不容易完全发现。

集成测试,也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)
组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证
连接起来也能正常的工作。一些局部反映不出来的问题,在全局上很可能暴露出来。

集成测试是在单元测试的基础上来验证接口的正确性,同时测试的单元构成不是很复杂,便于分析错误成因,提高单元的兼容性。也容易对程序进行改正。

压力测试是一种软件测试,用于验证软件应用程序的稳定性和可靠性。压力测试的目标是在极其沉重的负载条件下
测量软件的健壮性和错误处理能力,并确保软件在危急情况下不会崩溃。它甚至可以测试超出正常工作点的测试,
并评估软件在极端条件下的工作情况。

压力测试是对程序在高压条件下的运行的测试,在我的理解中主要是会导致cpu运行时间的过长和一些程序的不正常运行,通过压力测试,能够对自己的程序进行相对应的优化,使得程序能够应对大量数据的压力。

回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。自动回归测试将大幅降低系统测试、
维护升级等阶段的成本。

回归测试是在代码进行迭代后,对迭代前已有功能的验证,确保已有功能的正确性,便于之后对新增功能的测试的针对性和便于改正。对于迭代开发的程序来讲十分重要,能够降低修复bug耗费的时间。

数据构造

在对程序进行测试的过程中,数据构造是一个问题。为了保证构造数据的强度,尽量覆盖各种情况,我的数据构造在随机生成的基础上,还有完全图的构造和删除、零图的构造等,并尽量在各种情况下找到程序的bug,同时,也进行各种功能的压力测试,使得程序能够通过强测。

第九次作业

架构设计

在本次作业过程中,我通过对官方包接口的继承并建立了并查集来解决问题。

«interface»
Person
MyPerson
«interface»
Network
MyNetwork
Disjoint

图模型构建和维护策略

在MyPerson中用arraylist来存储邻居和与其的value,在MyNetwork中存入所有的人作为点,人与其邻居构成权值为value的边,最终构成图。
图的维护策略是直接维护, 在加人(addperson),加关系(addrelation),改关系(modifyrelation)时直接进行维护。

性能问题及其修复

第九次作业如果不考虑性能很好实现,因为要考虑性能,不得不进行一些优化,要找出需要优化的地方是十分重要的。

isCircle

如果使用bfs或者dfs时间复杂度均为O(n^2),因此需要用其他的方法进行维护。
起初我想在每个MyPerson中存入一个与其有路径的人的集合,然而无法处理删边情况的出现,所以没有使用,把它放弃了。然而这个方法没删干净,一直被调用,导致程序效率很低,强测大失败
最后后我使用了并查集作为处理该函数的方法。
并查集的具体实现为初始时每个人都指向自己,在add relation时若最终指向(即若指向的人的指向的人不为自己,则继续往下指向,直至最后的人指向为自己)的人不同,则将一个人指向另一个人,可以使用将一个人指向另一个人,可以使用按秩合并,即初始时各个人秩为一,每指向一次秩加一,秩小的指向秩大的。在modifyrelation时,若需要删边,则进行bfs找一个点的所有能联系的点指向它,并将秩变为1。在调用 isCircle时,不断寻找这两个人的最终指向,若相同,则为true,否则,为false。
这种做法会发现删边操作复杂度较高,因此对于删边操作可以进行进一步优化,即滞后操作,在需要用到的时候在进行bfs,避免了无用的bfs,提高了程序的效率。

queryBlockSum

这个方法是双重循环,时间复杂度为O(n^2),也需要进行优化。
通过阅读jml,我们发现这个方法求的是分支个数,这么一想,再有并查集实现的基础上,就知道解决方法了,即查询并查集中有多少个根节点(指向的是自己的人)。

queryTripleSum

这个方法是三重循环,时间复杂度是O(n^3),一定是要优化了。
我的方法是进行一个数的维护,即在一下情况下(addrelation)增加,一些情况下(modifyrelation)降低,调用这个方法只用返回个数即可。

第十次作业

架构设计

«interface»
Person
MyPerson
«interface»
Network
MyNetwork
Disjoint
«interface»
Tag
MyTag

性能问题及其修复

这次作业也有一些性能问题,一些不易发现,而且优化后时间复杂度仍然很高,导致可能会觉得是负优化,就不优化了,然而,在极端的压力条件下,这些“负优化”才能通过。

queryCoupleSum

这个方法本身可以说是O(n)虽然jml写的是双重循环,但是想一想就能写成一个单循环,然而,其调用的queryBestAcquaintance也是O(n),因此需要做一些简单的优化。我采用了脏位优化,只在一些情况下计算,平常使用之前的数据。

queryTagValueSum

这个方法是O(n^2),优化十分不容易,我选择在network的一些操作时对所有tag进行维护。
这些维护中有一些是O(n^2),优化后仍很复杂,因为滞后操作的实现过于困难,因此实现了并不好的优化, 不过最后实际跑起来效果不错。然而我开始时没有构造出这样的压力测试,所以就删掉了

第十一次作业

架构设计

«interface»
Person
MyPerson
«interface»
Network
MyNetwork
Disjoint
«interface»
Tag
MyTag
«interface»
Messge
MyMessge
«interface»
EmojiMessge
MyEmojiMessge
«interface»
NoticeMessge
MyNoticeMessge
«interface»
RedEnvelopeMessge
MyRedEnvelopeMessge

和上次一样,就加了新增的类。

性能问题及其修复

这次作业没有性能问题。

对规格与实现分离的理解

规格的实现虽然能够实现,但是效率可能很低,在这种情况下,我们需要重新写一个方法来进行优化,来保证程序整体的效率。或者规格只规定了结果的样子,没有给出实现的过程,也需要自己进行自己的实现。
在进行规格与实现分离时,要对规格有正确的理解,不然花费半天实现的方法可能完成不了规格的要求,那就得不偿失了。

junit测试

junit测试首先要保证满足规格需要的变化的内容,保证一些东西变成了规格所要求的东西,同时,规格本身有一些是没有要求变的,就需要对这些其他内容进行相等的对比,保证其他内容的严格相等,同时,我们还要有着一定的数据,或者随机生成,或者自己用心构造,尽量能够覆盖各种数据,使得junit的约束能够与规格的要求一致。同时,能够根据自己的代码相适应,覆盖全自己的代码。
junit测试能够测出一些黑箱测试测不出的bug,提高程序的正确性。

学习体会

在这个单元的学习中,我对于面向对象编程的一些原则有了更多的理解,对接口有了更多的认识。对于jml的阅读变得熟练起来,并能编写jml代码。对于程序的优化和测试有了更进一步的认识。在面对优化效果不尽人意时,要有对自己优化的自信,并多使用压力测试来验证优化发挥作用的效果。同时,要多与同学交流,只与一部分人进行交流可能会导致都错的情况出现,而与更多的人交流,这种情况就不太可能出现。在进行优化时,尽量全部删掉之前的代码,否则会在奇怪的地方浪费效率并且出现找不到bug的状况。最后,不要在不精神的时候写代码,否则可能会花费更多的时间去寻找十分愚蠢的bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值