309
社区成员
发帖
与我相关
我的任务
分享面向对象Unit3主要是针对JML进行规格驱动开发。本次作业围绕模拟bilibili用户、视频、网络交互环境进行设计。根据助教给出的JML规格实现具体方法,完成一个简单的bilibili用户系统。重点考察了与图有关的算法。此外,作业还需要按照JML要求比那些Junit测试进行检测,保证相应方法严格按照JML要求实现。
@requires x > 0; // 前置条件:参数x必须大于0
@ensures \result > 0; // 后置条件:返回值必须大于0
@invariant \forall int i,j; 0 <= i && i < j && j < users.length; !users[i].equals(users[j]); // 不变式:用户数组中没有重复用户
JML的核心在于规定方法的行为规范,确保方法在满足前置条件的情况下正确执行,并且在执行后满足后置条件。同时,不变式保证了类的状态始终处于合法范围内。前文提到,JML重点在于规定方法的行为规范,而Junit测试则是用来验证方法是否满足这些规范。通过编写Junit测试,我们可以模拟各种输入情况,验证方法在不同条件下的行为是否符合JML的要求。Junit测试可以帮助我们发现方法实现中的潜在问题,确保方法在满足前置条件的情况下正确执行,并且在执行后满足后置条件。
在本单元的三次作业迭代中,系统逐步引入了更多类型的对象(如从单纯的用户和视频,到加入评论、硬币、勋章等)以及更复杂的网络关系查询和异常处理机制。这一过程不仅考察了对JML规格的实现,更对程序的性能提出了较高的要求。如果完全照搬规格中描述的逻辑(如多重嵌套\forall、\exists遍历),必定会导致TLE(超时错误)。因此,需要在遵循JML规格的基础上,选择合适的数据结构与算法,并在适当的地方进行状态维护与缓存。
第九次作业
性能分析与优化:
初次作业中涉及了部分网络连接关系的查询。按照JML的描述可能是要求遍历图中的路径,一旦直接使用DFS或者BFS每次重新搜索,复杂度会极高。主要的优化策略是新建一个变量来实时统计用户相互关注的总数。通过对变量的维护(在用户关注/取关时更新),查询时直接返回该变量的值,从而将查询复杂度从$O(N)$降低到$O(1)$。
第十次作业(系统功能的扩展)
性能分析与优化:
随着系统体系的复杂化,出现了一些特定统计值的频繁查询指令。如果采用“查时再算”的全量遍历策略,无疑会面临巨大的时间开销。我在相关类中引入了额外的缓存变量(例如计算某个视频的交互总热度等)。当发生修改相关属性的指令时,同步更新对应的缓存变量;在查询方法被调用时直接返回该缓存值,从而将原本$O(N)$的查询转化为$O(1)$。不过这种优化只会在反复查询且数据未改变的情况下有效。
第十一次作业(深入计算与高阶应用)
性能分析与优化:
在此阶段处理涉及到图的最短路或者具有权重的路径搜索时,直接BFS已经不能满足要求。此时需要应用到图算法领域的经典算法。如果是带权图的最短路径搜寻,通过结合使用PriorityQueue实现堆优化的Dijkstra算法,能够有效地减少无效的边扩展,保持算法良好的时间上界。
在游戏中,初次编写自然语言用于描述问题是比较简单的,但是如果自然语言没有严格规定相应的实现要求,会导致编写JML十分困难。需要在编写JML时,自己理解自然语言的意思,理清相应的逻辑关系,总结出前置条件、后置条件以及不变式等内容。才能正确编写出相应的JML。