BUAA OO第三单元作业总结

面向对象第三单元总结

一、准备测试数据

​ 在本单元中提出了一个新的测试方法——Junit,其作用是针对每个方法测试,可达到全面无死角的测试。一开始本打算尝试这种测试方法,但后来由于其数据构造需要手动实现,且需要根据自己的理解来对每个方法写判断前提和结果约束,一旦自己的理解错误则会造成测试结果的错误,因此我没有采用这种测试方法。我最后采用的测试方法是随机构造数据 + 与同学对拍。

​ 在随机构造数据时,如果采用全随机的方式,那效率将会是极其低效的,因为大量的指令的结果都会是抛异常(不过也可以借此检查抛异常是否完全正确),所以最好在构造数据时要有自己的构造策略,我的策略是根据JML规格尽可能的覆盖每一种指令并且测试它们的边界情况,例如每个group中的人数不能超过1111人。同时构造数据还要有兼顾时间复杂度的数据。比如第一次作业的qbs指令,如果完全按照JML翻译则会造成超时,可以构造每个人都处于一个独立的联通块的数据。第二次作业的qgvs,应该维护一个valueSum值,否则也会超时,可以构造一个向组内加入1111人然后不断查询的数据。

二、架构设计和维护策略

1.架构设计

​ 本单元作业的总体架构已经由课程组给出,我们的工作是一些接口的的方法,并根据需要加上一些自己的方法,故在架构设计上还是较为简单。

2.维护策略

​ 因为大多数指令都要通过id来找到其具体对象,故在容器的使用上,我采用的均是HashMap,使每个对象和其id一一对应,这样可以降低查询的时间复杂度。

​ (1)用并查集实现isCircle和qbs,并在并查集中加入了路径压缩,同时为了防止爆栈我采用的是非递归的方式实现。

​ (2)用Prim算法实现qlc指令。同时采用了堆优化的方法

。只需要使用Java提供的数据结构PriorityQueue维护一个边集即可达到堆优化的效果。

​ (3)用最短路径算法Dijkstra实现sim。与最小生成树算法相似,这里同样使用PriorityQueue来实现堆优化。

三、性能问题和修复情况

​ (1)第一次作业主要可能出现性能问题的指令是qbs。我在理解了这个问题之后并没有按照JML的描述直接实现,而是通过计算联通块的方式实现,故没有出现性能问题。

​ (2)第二次作业主要出现性能问题的指令是qgvs。这里只需要维护一个valueSum变量,并在每次ar,atg,dfg操作中更新valueSum值即可,因为写的时候就考虑到了这个地方,故本次作业也没有出现性能问题。

四、Network的JML扩展

/*@ public normal_behaviour
      @ requires containsProduct(productId);
      @ assignable \nothing;
      @ ensures \result.length == 3 && \result.get(0) == getProduct(productId).producerId
      @      && \result.get(1) == getProduct(productId).advertisers[size - 1]
      @      && \result.get(2) == getProduct(productId).customers[size - 1];
      @ also
      @ public exceptional_behaviour
      @ signals (ProductNotFoundException e) !containsProduct(productId);
     */
    public int[] getRoads(int productId) throws ProductNotFoundException;

/*@ public normal_behavior
  @ requires containsProduct(id);
  @ ensures \result == productIdList.get(id);
  @ also
  @ public exceptional_behavior
  @ signals (ProductIdNotFoundEXception e) !containsProduct(id);
  @*/
public /*@ pure @*/ int queryProduct(int id) throws ProductIdNotFoundException;

/*@ public normal_behavior
  @ requires product != null;
  @ assignable producers;
  @ ensures(\forall int i; 0 <= i && i < produces.length; products[i] != product);
  @ ensures(\forall int i; 0 <= i && i < produces.length;
  			(\exist int j; 0 <= j && j < \old(produces.length); old(produces[j]) == product[i])));
  @ ensures(\forall int i; 0 <= i && i < \old(produces.length);
  			old(produces[i] != product ==> (\exist int j; 0 <= j && j < produces.length; old(produces[i]) == product[j])));
  public void buyProduct(Product product);

五、学习体会

​ 通过本单元的学习,我熟悉了JML的阅读,知道如何从JML中提取出重要的信息。同时也理解了JML的意义,它可以防止二义性的产生。同时我们在具体实现的过程中不一定要按照JML所描述的直接去实现。可以在自己理解的基础上再进行自己的设计。

​ 同时,在本单元中我第一次自己写了评测机,掌握了一些命令行的使用,以及构造数据的能力。

posted @ 2022-06-06 09:18  郑凯荠  阅读(45)  评论(0编辑  收藏  举报