OO第三单元单元总结

测试过程

黑箱操作和白箱操作

黑箱操作我认为就是通过随机构造合法数据对代码进行测试,在测试过程中应当着重对边界条件、前置条件、结果正确性等方面进行判断。不需要具体到代码的逻辑,通过大量暴力的数据尝试找到代码的bug

白箱操作就是通过看代码的方式用人工逻辑的方式找到代码的bug,这样更具体、更有针对性。但是旁人看代码总是会因为每个人代码风格的问题不容易理解、找出bug(纯个人认为,因为在互测的时候看别人的代码我从来找不到别人的错误)

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

单元测试 :以模块为单元,以验证模块正确性和稳定性为目的,通过预先设计设计的单元测试,程序员可以编写自动化测试工具对某个模块代码进行针对性测试

功能测试:测试软件功能能否按照需求正确完成。

集成测试:是单元测试的逻辑扩展。它最简单的形式是:把两个已经测试过的单元组合成一个组件,测试它们之间的接口。(摘自百度百科)

压力测试:使用大数据,测试代码跑通数据的时间、所需要的空间是否足够,主要在是测试算法的优化、数据结构的使用是否合理。

回归测试:修改了旧代码后,使用跟以前的测试数据测试代码会不会有bug(防止出现改了1个bug,生成100个bug的情况)

测试工具

本次测试使用了往届学长的测试工具稍微修改后和同学进行了对拍测试,在测试中发现了不少bug,但是难过的是还是在强测中发现问题

数据构造

使用随机构造方式

图模型构建和维护策略

图模型

一般来说我们的图一般采用的有两种

第一种是矩阵形式,即通过一个n*n的矩阵来存储所有n个人之间的关系

第二种方式就是邻接表的方式,构造n个MyPerson,每个MyPerson中需要存储一个Acquaintance列表(数组、hashmap等)然后在Network类中存储所有的MyPerson(数组、hashMap等)

本次采用的是第二种方式,我使用了一个Hashmap来存储每个人的Acquaintance,起初我以侥幸的心理用了ArrayList,结果在同学的对拍中我的时间特别特别慢,所以果断换成了HashMap,哈希表的好处是可以快速get、remove元素。

维护策略

首先是要维护一些寻常变量,这在第一次作业中非常常见,比如三角关系(tripleSum)、块数(blockSum)之类的,后续我们还有bestAcquaintance之类的变量。维护的方式就是在增减关系和增加人的时候增减这些变量,好消息是这些变量大多数只需要加1或者减1

其次要维护的就是整个图了,整个图的维护主要维护的就是关系和人,如果是加人那么就是new一个MyPerson然后put到Network里面。加关系就是直接在人关系的双方的Acquaintance里面增加双方各自即可。

比较麻烦的是modifyRelation,这个方法本质上就是减关系,如果两个人的value值在被修改后小于0的话会直接被删去。这个问题主要在于维护那些个寻常变量之中。比如TripleSum,如果删除关系的话,就要遍历两者的共同好友的数量,然后删减这些TripleSum。blockSum需要加1。

并查集的使用

在本次作业中我两个地方用到了并查集(不过都是看了佬的算法才知道怎么写的)

第一个是本单元第二次作业中,删除关系后我们还需要判断两个人是否有相同的路径。这个地方我们用了并查集,如果确定两个人的关系终结了。我们必须维护一个并查集,他们的共同属性是他们是否可以相连,如果可以相连的话,我们就需要把他们放在一颗子树中。(关于判断两个人是否在删除直接关系后依然相连,方法是使用bfs遍历全图,做出以两者中的一人为根节点的并查集,再查看另一个人是否已经被包含到这棵树中)

第二个地方是在第三次作业中我使用了Dijkstra算法判断从一个点出发的最小环,具体参照的算法是一下这个链接。https://blog.csdn.net/qq_33362864/article/details/77466841

性能问题

本次的算法我误解了助教所说的“在算法层面上会有所减弱 希望大家不要卷错方向~” 我以为的算法层面的减弱是减弱到用暴力就可以完成强测,但是助教的意思应该是需要一些算法和数据结构。比如我在第一次的作业中,我最开始使用了ArrayList存储所有信息,然后完全照抄JML的要求来写,后来根据和同学的交流才明白这么写的复杂度是有多么多么的大~

动态维护

我认为第一个重要的优化是动态维护一些变量,这样强测的时候就不需要通过复杂度很高的方法来求取blockSum,tripleBlockSum等变量了。这样queryBlockSum的复杂度会是O(1).queryTripleSum的复杂度也是O(1).

并查集

第二个我的教训是在并查集的处理上。并查集其实只需要一个hashMap就可以实现,而我还是用传统的树结构,用类似于C语言的指针数组的方式存储所有的子节点。这种虽然也行,但是,访问每个子节点就慢很多了,因为调用方法的速度明显慢于直接调用HashMap的get方法

遍历范围的确定

第三个教训是在一些方法,比如modifyRelation的过程中,我们需要进行dfs,但是事实上,dfs遍历的时候只需要遍历根节点的Acquaintance中的所有元素即可,而我遍历了整个图中的所有人。这个小优化看起来没啥,在复杂图中确实没有太多的时间节省,但是在稀疏图中差别超级超级大。在我使用了时间戳工具计算后,在极端情况(整个图中有10000个人,但是根节点的Acquaintance只有10个),性能优化可以在10s以上!

Dijkstra算法优化

我最后一个问题就是在第三次作业中的Dijkstra算法使用堆优化后可以大大减少时间复杂度。堆优化前是O(n^2)的复杂度,但是堆优化后是O(n*log(n))的复杂度

规格与实现分离

关于这个问题,在第一次作业中,我可以说是根本没有理解规格的作用。甚至误以为规格就是让我们按照规格实现一遍算法即可。但是事实上,许多规格只是指出了最终结果和实现前提条件,完全照抄只会收获一堆复杂度为O(n2)甚至O(n3)的代码。

另外,规格的实现首先一个就是冗长的规格中找到需要的目的。有些需求其实可以用中文一行说清楚(当然在不考虑语义中的歧义)比如说,queryLeastMoment方法的规格非常非常长,但是总结下来的一句话就是:返回目标id的最小环。但是规格还是对于程序员的规范化代码又很大很大的帮助(虽然我实在读不下去那些特别冗长的JML)

okTest

这一部分我认为是本单元中收获最大的部分。为了完成本单元作业的okTest,我每次都额外建立了一个类okTest,他传入所有的参数后建立一个个的ensure方法进行分析

以下是伪代码

public class OkTest{private Element beforeData;private Element afterData;private int result;public OkTest(Element beforeData, Element afterData, int result) {this.beforeData = beforeData;this.afterData = afterData;this.result = result;}public int okTest() {if (ensure1()) {return 1;}if (ensure2()) {return 2;}if (ensure3()) {return 3;}return 0;}public boolean ensure1() {if (xxx) {return true;}return false;}public boolean ensure2() {if (xxx) {return true;}return false;}public boolean ensure3() {if (xxx) {return true;}return false;}
}

这种架构我认为是比较简单明了,而且在对拍中可以快速定位哪里有错误

总结

在本次单元中,我学会了如何阅读规格,如何写规格。虽然来说,日后在工作中很难会去写规格,但是这种严谨的开发流程是我们应当学习的。另外,这次作业的算法也让我更加深入了解了Dijkstra,并查集等优秀的算法和它们的优化方式,算法一直都是我们计算机学习者一个很重要的学习环节。

OO第三单元单元总结相关推荐

  1. OO第三单元——规格化设计与地铁系统——总结

    OO第三单元--JML的使用与地铁系统 梳理JML语言的理论基础.应用工具链情况 JML The Java Modeling Language (JML) is a specification lan ...

  2. OO第三单元JML规格总结分析

    OO 第三单元博客作业 1. JML语言概述 1.1 理论基础 综述 Java建模语言(Java Modeling Language,JML)是一种进行详细设计的符号语言,使人们用一种全新的方式来看待 ...

  3. OO第三单元总结性博客

    OO第三单元总结性博客 JML理论基础与工具链 JML理论基础 JML是一种将java程序规格化表达的一种语言,其描述的是行为的规格,而非具体的代码实现. 通过对程序开展规格化设计,当然前提是使用JM ...

  4. OO第三单元作业总结

    OO第三次作业总结 一.JML (一)JML语言理论基础 (1)JML表达式: JML表达式包括以下几种: 原子表达式如\result(方法执行后的返回值).\old(表达式在相应方法执行前的取值): ...

  5. 计算机表格怎么同时选中分开的两项,excel怎么把三个单元格分成两个

    1. excel表 三个表格合并后怎么拆分成两个 1.首先我们鼠标点击选中要拆分的大单元格 2.然后鼠标右击它,在在弹出的选项点击[设置单元格格式] 3.接着我们点击窗口上端的[对齐] 4.现在我们把 ...

  6. c语言质数和合数事例,新人教版三年级数学下册第八单元单元教学计划

    第八单元 数学广角--搭配 (二) 新知识点: 1.简单事物的排列数. 2.简单事物的组合数. 教学要求: 1.联系学生的生活实际,使学生通过观察.猜测.试验等活动,找出简单事物的排列数和组合数. 2 ...

  7. 复杂字符串分列,例如将“花生100公斤”拆分到三个单元格,分别是花生、100、公斤

    如果单元格中的值是"花生100公斤",需要一键拆分到三个单元格中去,分别显示为花生.100.公斤,手工操作相当费时,如果有10000个单元格需要拆分,用工具来完成才是首选. 插件& ...

  8. 用计算机写文章 单元备课,信息技术第一单元单元备课精要.doc

    第一 2.了解计算机系统的组成,知道计算机的主要部件. 3.了解计算机的工作过程. 4.掌握鼠标的移动.单击.拖曳.双击四种操作方法,并能将这些操作灵活运用于计算机操作中. 5.了解键盘的构造和布局. ...

  9. 用计算机写文章 单元备课,泰山版小学信息技术第一册上第四单元单元备课

    泰山版小学信息技术第一册上第四单元单元备课 四年级第一册上 第四单元 记录珍贵信息单元备课平原县第一实验小学 王敏一.教学内容要点 本单元主要知识点是用记事本输入文字,以及文章的编辑修改.键盘是计算机 ...

最新文章

  1. Get started with ros -- 1
  2. nodejs高版本转低版本
  3. 多进程和多线程的概念
  4. 13 登陆_13级!凌晨,“黑格比”登陆!对莆田的最新影响……
  5. 文件管理服务器数据库,会博通系统的海量数据库管理策略
  6. odoo tree视图 当页不弹窗显示方法
  7. 从Java新手到大神需要学哪些知识?
  8. python socket自动重连_详解python3中socket套接字的编码问题解决
  9. gitlab使用git sourcetree时候的命令
  10. 数据增长浪潮下,PCIe 6.0的问与Rambus的答
  11. Kotlin程序用于打印JVM版本的Kotlin(打印Java属性)
  12. 你知道group by的工作原理和优化思路吗?
  13. CustomError可以设置绝对路径
  14. Java初学者需掌握的30个概念
  15. 这个开源的视频编辑项目,有点6~
  16. 2021-09-06
  17. Android Base64编码算法
  18. 摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人”
  19. Java字节码编程之非常好用的javassist
  20. 北京大学2019年优秀中学生暑期学堂招生简章发布!

热门文章

  1. matlab ws小世界网络,【MATLAB】构建WS小世界网络
  2. 源码时代UI干货分享|史上最全的HTML三大列表的写法总结,快来收藏吧!
  3. 雅思口语话题准备(一)
  4. html,css基础笔记(一)
  5. 引入阿里图标库(iconfont)后图标黑白问题
  6. 跟我学UDS(ISO14229) ———— 0x19 服务参数介绍
  7. 一些粗浅的研发阶段涉及软件汇总
  8. Linux 基础入门 05
  9. Intel Sapphire Rapids-SP Xeon CPU 具有 4 个 8-Hi HBM2E 堆栈,14 个 EMIB 互连,全 XCC 芯片尺寸约为 400mm2
  10. C++从入门到进阶的系列书籍推荐