面向对象第三单元总结

weixin_41030950 weixin_41030950 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

面向对象第三单元总结

第三单元的任务为在JML规格的约束下完成社交网络的模拟,重点在于写出符合JML规格的代码实现的同时,尽可能提高代码的性能。
· hw9实现了一个简单的社交网络,仅考虑好友之间的关系,并在这个无向图上进行传统图论问题的查询
· hw10增加了好友分组标签,并添加了查询标签内统计信息的操作
· hw11增加了对收发消息的模拟,并添加了对发送消息前后用户属性,如社交活跃度、余额,以及emoji使用情况的查询操作。

本单元的测试过程

黑箱测试与白箱测试

黑箱测试是指在不知道程序内部具体实现的情况下,仅根据功能需求设计测试用例,以验证程序的正确性。

白箱测试是指在知晓程序内部实现及工作流程的情况下,依照程序内部结构设计测试用例,验证程序内部逻辑是否均能走通

本单元的测试是黑箱测试与白箱测试结合的过程。通过JUnit,我们既可以根据JML规格对方法的所有前置和后置条件进行检查,以进行黑箱测试验证功能是否符合需求,也可以针对具体的实现编写特殊的极端测试用例,以进行白箱测试验证所有逻辑分支的正确性。

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

单元测试是指针对软件系统中的最小测试单元,如一个方法,进行单独测试。单元测试的编写较为简易,隔离程度很高,可以用于单独验证系统中一部分实现的正确性。在本单元作业中,编写JUnit对某个方法测试的过程,就是进行了单元测试。

功能测试是指测试软件的功能是否符合指定的规格。它属于黑箱测试,即只要求每个模块对外部体现出的功能达到规格要求。本单元的公测根据自己程序的输出与标程输出进行比较以判断是否通过,就属于功能测试。

集成测试是指将多个模块放在一起进行测试,以验证这些模块之间的交互过程符合要求。在本单元中,不仅有许多改变网络状态的操作,还有许多对这些改变后的效果进行查询的操作,对这些查询结果的正确性验证在一定程度上就相当于集成测试。

压力测试是指通过超出正常水平的工作负载来测试程序在极端情况下是否仍能保持正常工作,以测试系统的稳定性和可靠性。在强测与互测中的极端案例就属于压力测试,用于验证程序在某种特殊情况下是否仍能按预期需求工作,而且表现出较好的性能。

回归测试是指在修复bug后重新进行验证时,保证之前通过的测试用例现在仍能通过,即保证了不通过修复这部分bug引入新的bug。本单元的bug修复环节就是在进行回归测试,只有在通过之前出错的测试用例同时,不增加新的未通过的测试用例,才可算作修复了bug

数据构造的策略

综上,在构造数据进行测试时,我们应该主要考虑对全部的功能进行充分的测试,以及对有性能要求的模块进行压力测试。

对于功能测试,我在评测机中使用了随机生成指令的方式,并为每条指令赋予不同的随机权重,通过变换这些权重,理论上就会生成出覆盖各种情况的不同测试用例。对于压力测试,我选择通过白箱测试的方式,针对代码实现生成出使该实现获得最差性能表现的数据,并反复验证以确保在极端情况下该实现也能符合性能要求。如生成完全图的过程中反复进行att与qtvs,或qts

本单元的架构设计

由于本单元是完全的增量式开发迭代,这里只展示最后hw11的架构:

img

在类的设计上,基本保持了和官方基类相同的结构,仅将基类继承后实现具体的方法。不过,由于并查集涉及到的操作聚合程度较高,因此将其分离出来作为单独的类。

在图模型的构建与维护中,始终涉及到人员、人之间关系、人的分组标签以及消息等数据集合的维护,同时,所有的查询操作也是在其上进行。因此,对图模型的维护主要在于对这些数据结构的设计。

由于本单元中许多数据都拥有唯一的id,如person的id,person中tag的id,以及message的id和emoji的id,因此用以id作为key的HashMap可以高效地实现对这些数据所在集合的维护。

同时,对于涉及到连通性和连通块的查询,我使用了并查集来高效地维护每个person所在联通块的信息。

关于性能问题

尽管按照JML的规格进行实现可以保证正确性,但朴素的实现性能十分低下,因此要在符合规格的前提下分离规格与具体实现,尽可能达到更高的性能。

在我的架构中,一个重要的对规格与实现的分离的方式就是在修改时动态更新、预先求值,并在查询时直接返回符合要求的值。

例如,在查询两个person是否连通(qci)时,不会在每次查询时在网络中进行搜索,而是在添加与修改关系(ar、mr)时更新并查集。这样在查询时可以立即得到结果。再例如,查询每个人关系最好的朋友(qba)时,不在查询的时候遍历邻居,而是在添加关系与修改关系的同时更新关系最好的朋友,并将其储存以供查询使用。

但对于一些查询操作,无法在查询时直接返回答案,如qcs,但仍能通过预先保存部分结果,即每个人的最好朋友,以大大减少该查询复杂度

反过来,另一个通过分离规格与实现来降低总体复杂度的方法是延迟更新。

例如在删除关系(mr)后进行连通块数量的统计(qbs)的操作,需要bfs遍历新的图并重建并查集,以保证修改之后的qbs可以通过并查集获得正确的结果。但如果在k次mr的每次后都针对这次修改重新建并查集,就相当于进行了k次O(n+m)的操作,但如果只有一条qbs,其实只需在这一条查询之前进行重建即可。因此,在每次修改之后可以先将并查集打上标记,而不做具体修改,只在需要查询并查集的数据时,判断是否需要重建并执行重建,并在重建之后取消标记。在这样的逻辑下,只在必需的时刻执行O(n+m)的操作,有效降低了总体的复杂度。

通过上述的预先(部分)求值与延迟更新的优化,我在这单元的三次作业性能均展现出了良好的表项,没有在强测与互测中出现bug。

JUnit测试

本单元每次作业都针对了一个查询操作编写JUnit测试。

测试的流程分为构造前置数据、验证前置条件、运行测试方法、验证后置条件等步骤。对于网络中的查询,首先构造出一个初始的网络,可能是一个完全图,也可能是只有人(结点)。之后,开始循环进行多组验证,在每组中,都执行修改-查询的操作,即先用一条修改操作改变网络状态,如果修改成功,则再对每个新状态进行前置条件验证并记录必要的修改前数据,然后执行查询。最后,验证后置条件,检查是否满足所有的后置条件约束。同时,还要运行该类的不变式检查,保证始终符合不变式。

通过重复上述循环中的步骤,可以较好地覆盖到各种情况。但一切特殊逻辑还是需要特别的处理,如用id作为第二关键字对好友进行排序时,如果在加边时的好感度value随机范围过大,则很难产生相同value的两个好友以执行这部分逻辑,因此需要减小value随机范围以覆盖该逻辑。

本单元学习体会

本单元的总体难度比较简单,也没有过多的坑点,但整体的课程设计还是给我带来了一些困惑:

本单元给我的感觉就是像在做填空题一样,根据指定的需求写出代码。但是,课程组对本单元的重点——JML的学习目的的解释是十分含糊、难以服众的。JML的规格和语法已经表明了它是一种形式化的表示,本应与自动化验证有较深的联系,但是完成本单元的三次作业时,我们却只能通过肉眼观察JML形成自己的理解,然后写出符合规格的代码。我认为这与在IDE上写完程序后手动模拟计算机执行,在大脑中得到程序运行结果的行为并无二致。我们在课上课下花费了大量的时间来学习阅读和编写JML,将JML视为对方法功能的严格定义,但这些JML仅仅作为程序中的注释,而没有直接的验证方式,一切形式化的JML活动都只存在于人脑中,如果不小心写出了不符合JML的错误实现,还是得重新一行行地读JML形式化的语言,并在大脑中想象自己的实现究竟违反了JML的哪条约束,令人感到错愕不已。在优化图论算法的部分,对性能的要求较为宽容,但简单的算法仍被JML描述的十分“严谨”。对JML形式化语法的编写与阅读的要求之严格,与JML在验证图论算法中直接影响之微弱(其实就是没有任何影响,毕竟是注释)给同学们带来了极大的反差感,如此的倒错也让我感到有一种编程初学者被要求一行一行将注释写成小作文的美。不知助教与课程组的各位老师在课上或课程群里大言不惭地说出“可能很多人在上完OO后就不会再接触JML了,但在一些岗位上是非常重要的”时,是否想过全年级200+人月的开销是否对同学们上这门课所预期得到的能力或知识提升有任何正向的反馈。

...全文

相关推荐

前端开发组件示例源码_f1b6a91d详解

前端开发组件示例源码_f1b6a91d,内容包含源码/脚本与使用说明文档,结构清晰、注释完整,适合学习参考与二次开发,下载解压即可查看。

鱿鱼助手

前端开发基于history.js的HTML5与HTML4浏览器兼容方案:单页应用无刷新历史状态管理技术实现-Gjl4Gf1792158475

内容概要:本文系统介绍了如何利用history.js实现单页应用(SPA)在HTML5c与HTML4浏览器间s草错发的无缝历史状态管理。通过封装原生History API并在不支持的浏览器中自动降级为哈希路由,history.js解决了因浏览器兼容性导致的后退按钮失效、URL混乱等问题。文章详细讲解了其核心机制,包括状态对象管理、自动模式切换(HTML5 pushState vs HTML4 哈希)、状态数据持久化以及针,对Safari、IE等浏\览器的兼容性修复方案,并提供了从入门到实战的完整示例,涵盖初始化、事,件监听、页面加载及性能优化技巧。;Gjl4Gf1792158475 www.gblp.net www.gsctlq.com gezhixq.cn www.greendalian.com wap.gxqnm.com

2601_97196179

前端开发基于history.js的HTML5与HTML4浏览器兼容方案:单页应用无刷新历史状态管理技术实现-5Z6jeSqI1792158476

内容概要:本文系统介绍了如何利用history.js实现单页应用(SPA)在HTML5c与HTML4浏览器间s草错发的无缝历史状态管理。通过封装原生History API并在不支持的浏览器中自动降级为哈希路由,history.js解决了因浏览器兼容性导致的后退按钮失效、URL混乱等问题。文章详细讲解了其核心机制,包括状态对象管理、自动模式切换(HTML5 pushState vs HTML4 哈希)、状态数据持久化以及针,对Safari、IE等浏\览器的兼容性修复方案,并提供了从入门到实战的完整示例,涵盖初始化、事,件监听、页面加载及性能优化技巧。;5Z6jeSqI1792158476 sdhmgggw168.com www.shangliangwangye.com www.sdbing.net migu.blsxex.abxlbz.sc.cn www.safespeed.net.cn

2601_97196179

高校如何通过科技报告服务提升技术转移转化效率?.docx

科易网基于40亿+科创知识图谱数据库,深度探索AI技术在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,研究科技创新领域的AI+数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

科技服务机构如何提升服务大企业的技术诊断能力?.docx

科技服务机构如何提升服务大企业的技术诊断能力?

BIZKEEN
评论
收藏 已收藏
分享
返回顶部