面向对象第三单元个人总结

OO第三单元个人总结

一、如何利用JML规格来准备测试数据

1、首先保证代码语义与JML语言表达的语义的一致性,在完成代码后认真核对。

2、构造特殊数据,测试前置条件不满足时抛出异常的情况。

3、构造符合前置条件的数据,满足后置条件和约束条件,针对运行结果进行自我判断,或是进行对拍测试。

4、构造边界数据,或是构造超多数据,如超多条qgvs等等,来测试运行时间,若是运行时间过长,则需要进行优化。

5、借用室友搭建的评测机,进行对拍测试,发现自己的bug、发现自己运行速度过慢的问题。

二、图模型构建和维护策略

1、图模型构建:

 主要的图结构是Person类中的图结构,以各个Person为节点,以value为权值,在构建的MyRelation类中,以Perspn的id表示Person将有关联的Person相连。

2、维护策略:

isCircle中,运用了课程组提供的并查集的方法,提升了运行速度,从而没有产生超时的问题。

queryLeastConnection中,需要求最小生成树,最小生成树的算法选用了Prim算法,保证了该方法的运行速度较快。

sendIndirectMessage中,运用了堆优化的迪杰斯特拉算法来求最短路径,提高运行速度。

整个MyNetwork类中,person、groups、emoji等均采用Hashmap来进行存取,减少各方法中不必要的循环,提高运行速度。

MyGroup中的getValueSum做了优化,维护了一个valuesum的变量,在每一次的addPerson和delPerson中运算,而不是在getValueSum中进行暴力的循环运算。(这也是我在改动前在互测中被hack的原因)

三、性能问题和修复情况

queryGroupValueSum因为没有维护而超时,在互测中被hack多次。

修复情况:已在前文提到,即在MyGroup中的getValueSum做了优化,维护了一个valuesum的变量,在每一次的addPerson和delPerson中运算,而不是在getValueSum中进行暴力的循环运算,大大提高了运行速度。

除此之外无其他性能问题。

公测互测情况:

个人bug:

queryGroupValueSum超时;

第九次作业的强测中,因个人粗心大意,在delPerson将循环的变量写错而出现错误。

他人bug:

因addToGroup中没有判断getGroup(id2).getSize()<1111而出错。

四、Network扩展

新增Advertiser、Producer、Customer、AdvertisementMessage、Product、BuyMessage类。

Advertiser:广告商   Producer:生产商   Customer:消费者

AdvertisementMessage:广告商发送的广告信息   Product:生产商生产的产品   BuyMessage:消费者发送的购买消息

NetWork中新增方法:sendAdvertisementMessage(int AdvertiserId,int AdvertisementMessageId) 广告商发送广告信息、

addAdvertisementMessage(int ProducerId,int AdvertiserId,int AdvertisementMessageid) 生产商发送广告信息给广告商、

addProduct(Product product) 生产商生产产品、

BuyProduct(int Customerid,int Productid) 消费者购买产品、

querySalesVolume(int ProductId) 查询某一产品的销售额、

querySalesPath(int ProducerId,int CustomerId,int ProductId) 查询某一产品的销售路径

JML:

addAdvertisementMessage(int ProducerId,int AdvertiserId,int AdvertisementMessageid) :

/*@ public normal_behavior
  @ requires (\exists int i; 0 <= i && i < people.length; people[i].getId() == AdvertiserId && people[i] instanceof Advertiser && people[i].containsAdvertisementMessage(AdvertisementMessageId));
  @ assignable people[*].messages
@ ensures (\forall int i; 0 <= i && i < people.length; (getPerson(AdvertiserId).isLinked(people[i])) ==> (people[i].messages.length == \old(people[i].messages.length) + 1 && people[i].messages[0] == \old(getPerson(AdvertiserId).getAdvertisementMessage(AdvertisementMessageId)) && (\forall int j; 1 <= j && j < people[i].messages.length; people[i].messages[j] == \old(people[i].messages[j - 1])))); @ ensures (\forall int i; 0 <= i && i < people.length; !(getPerson(AdvertiserId).isLinked(people[i])) ==> (people[i].messages.length == \old(people[i].messages.length) && (\forall int j; 0 <= j && j < people[i].messages.length; people[i].messages[j] == \old(people[i].messages[j])))); @ also @ public exceptional_behavior @ signals (PersonIdNotFoundException e) (\forall int i; 0 <= i && i < people.length; people[i].getId() != AdvertiserId || (people[i].getId() == AdvertiserId && !people[i] instanceof Advertiser)); @ signals (AdvertisementMessageIdNotFoundException e) (\exists int i; 0 <= i && i < people.length && people[i].getId() == AdvertiserId && people[i] instanceof Advertiser; !people[i].containsAdvertisementMessage(AdvertisementMessageId)); @
*/ public void sendAdvertisementMessage(int AdvertiserId, int AdvertisementMessageId) throws PersonIdNotFoundException, AdvertisementMessageIdNotFoundException;

addProduct(Product product) :

/*@ public normal_behavior
  @ requires !(\exists int i; 0 <= i && i < products.length;products[i].equals(product));
  @ assignable products
  @ ensures products.length == \old(products.length) + 1;
  @ ensures (\forall int i; 0 <= i && i < \old(products.length);
  @ (\exists int j; 0 <= j && j < products.length; products[j] == (\old(products[i]))));
  @ ensures (\exists int i; 0 <= i && i < products.length; products[i] == product);
  @ also
  @ public exceptional_behavior
  @ signals (EqualProductIdException e) (\exists int i; 0 <= i && i < products.length;
  @                            products[i].equals(product));
  @*/
public void addProduct(/*@ non_null @*/Product product) throws EqualProductIdException;

querySalesVolume(int ProductId):

/*@ public normal_behavior
  @ requires containsProductId(ProductId);
  @ ensures \result == getProduct(Productid).getSalesVolume();
  @ also
  @ public exceptional_behavior
  @ signals (ProductIdNotFoundException e) !containsProduct(ProductId);
  @*/
public int querySalesVolume(int ProductId) throws ProductIdNotFoundException;

五、学习体会 

本单元主要学习了解了JML规格的使用与理解,它能够正确地表达程序的运行逻辑的,但是在编写和阅读时十分具有困难性,在今后的学习中具体是否能够经常使用还是不太确定的。本单元的作业在阅读与理解JML上困难性较低,虽然需要花费较多时间,但一句一句的阅读并不难理解,作业的难点却集中到了求最小生成树算法、求最短路径算法的运用与优化方面,训练算法固然有好处,但这是否有些本末倒置了,用算法的选择与优化来决定强测与互测是否能顺利通过、是否被hack这是我没有想到的,难道不应该是把注意力集中到JML的理解与运用上吗。经过三次作业,我也充分学习了最小生成树算法、最短路径算法及其优化,提高了我的算法水平。

 

 

posted @ 2022-06-05 11:01  苏俊行  阅读(20)  评论(0编辑  收藏  举报