标签:覆盖 意义 自己实现 单元 需要 程序 操作 net 方差
个人的设计策略大致可分为这样几个步骤:
? 1.阅读指导书和接口中的定义,按照由下到上的顺序实现接口中的内容。本次实现的社交网络系统中,NetWork类是顶层设计,所以先实现其他底层的接口类。
? 2.选择合适的容器和算法,先简单实现JML规格所要求的功能(暂时忽略性能,只考虑正确性)。
? 3.对于时间复杂度较高的方法进行优化,保证CPU运行时间在规定范围内。
? 1.基于JML规格使用JUnit测试复杂方法,保证覆盖方法中所有代码行,进行正确性验证。
? 2.使用python随机生成数据(包括一般的正确性测试、边界测试和极端测试点),在验证方法正确性的同时,验证自己的实现有无出现CTLE的可能性。
? 3.和其他同学进行对拍,将自己程序的输出与其他人程序的输出进行比对,以测试代码实现的正确性。
本次作业中主要采用了HashMap
、ArrrayList
容器。针对本次作业的容器使用经验可以分为如下几点:
HashMap
,这样时间复杂度仅为O(1)。在NetWork类中的所要求实现的数组类型,均可以使用HashMap
存储。HashMap
可以节省空间,同时梳理逻辑结构。NetWork类中的emojiIdList
和emojiHeatList
的元素便是一一对应的,完全可以用HashMap
实现。同时,在定义的方法中,我们获取person
、group
、message
都是通过其id
进行访问的,因此采用HashMap<Integer, Value>
的设计,可以方便查找,优化性能。ArrayList
适用于不需要复杂存取操作的数组结构。在Group
类中实现的方法相对简单,所以采用此结构存储people即可。这里列举出容易出现性能问题的方法和规避TLE的策略:
isCircle
: 该方法用于判断无向图上的两个节点是否连通,可采用并查集来实现。queryBlockSum
:求无向图中连通块的数量,依赖isCircle
实现,一样可以用并查集实现。getAgeMean
/getAgeVar
:求一个 Group (Group 意义为无向图的一个子图)中所有人的年龄的均值与方差。可以采用直接遍历的方式求和,时间复杂度为O(n)。要进一步优化性能的话,可以在 Group 中添加两个变量来存储组内 Person 的年龄之和与年龄平方和,在addPerson
和delPerson
时更新变量的值。这样查询方法的复杂度降至O(1)。getValueSum
:求一个 Group 中所有边的边权之和。如果采用简单的二重遍历,那么在极端测试下会导致TLE(本人很荣幸中招了)。可以采用维护变量的思路,用一个变量存储边权和,在addPerson
和delPerson
时更新变量的值,以及对组内的人进行 addRelation
时对边权和进行维护,使本方法时间复杂度降至O(1)。sendIndirectMessage
:该方法的返回值是两个人之间的最短路,需采用 Dijkstra 算法对无向图中的单源最短路进行求解。注意使用 Dijkstra 时需要采用堆优化。我们所实现的社交网络系统本质是以人为结点的图模型。人与人之间的连接是通过熟人列表实现的,用isLinked
查询人与人的关系,而这些在规格已经定义完善,我们只需要负责实现功能就好。
对于图模型构建,笔者采用其id+对象存储在哈希表中,如熟人列表,network里面存储的person,message,emojiHeatList等均采用这样的思路进行存储。
针对维护策略,主要是通过各个接口类中的增加、删除方法和异常类抛出来共同实现。需要注意的是,在方法中如果对某些数组对象有增加、删减的操作,一定要按照规格要求更新数据。
本单元主要是了解JML规格化描述的方法,掌握根据规格编写代码的能力。JML规格可以很直观的呈现出方法的功能,实现将架构和代码分离的效果。对于开发者来说,只需要理解规格便能保证实现功能的正确性。当然,对于性能方面的优化,仍需要自己进行更加复杂的测试才能保证。
标签:覆盖 意义 自己实现 单元 需要 程序 操作 net 方差
原文地址:https://www.cnblogs.com/dky777/p/14831882.html