U3总结
(1) 自测的测试数据
根据方法的JML规格准备测试数据:
-
方法名前是否存在
/*@ pure @*/
标记,如果有,那么此方法不应该改变任何变量的值。 -
根据
require
条件分别准备满足条件和不满足条件的数。判断满足条件的数据是否有返回值满足ensure
的规定,是否只有assignable
修饰的变量改变;不满足条件的数据能否正确抛出异常。 -
随机构造测试数据时,可以通过增加测试数据条数,来提高测试数据的强度。
(2) 梳理本单元的架构设计,分析自己的图模型构建和维护策略
在图模型中,由人作为节点,两人之间的关系作为边,value作为关系的权重,构建了图的结构,其中在网络中,通过HashMap
存储节点和节点id
。
为了提高指令的速度,需要同时维护一些数据以便快速查询。
(3) 按照作业分析代码实现出现的性能问题和修复情况
qci
性能问题:每次在查询该指令时,都对所有节点的熟人进行遍历直到找到目标,导致的超时。
修复情况:对于每个节点,保存节点的父节点。在生成一个新节点的时候,该节点就是它的父节点,那么只需一直查询父节点的父节点即可得到根节点。在添加关系时,如果两个节点的根节点不同,那么将其中一个节点的根节点的根节点设为另一个节点的根节点,那么与这两个节点直接或间接连接的节点都具有了相同的根节点。
qbs
性能问题:每次在查询该指令时,对网络中的所有人进行遍历,从而找到根节点的个数,导致的超时。
修复情况:在网络中保存分块数量n。n初始化为0,每向网络中添加一个人,n加一,而通过添加关系将两个根节点不同的节点连接时,n减一。即可直接查询n的值返回结果。
qgvs
性能问题:对组内所有人进行遍历,两次for循环,导致的超时。
修复情况:查询一个组内所有人的关系权重之和。从一个人开始遍历其所有熟人,然后再遍历其熟人的所有熟人,知道将组内所有的关系遍历完毕。
qlc
性能问题:在查询最小生成树时将所有节点分为两组,一组为有确定的连接的边的节点,另一组为没有确定的边的节点。使用两个for循环遍历其中所有节点寻找权重最小的边时会造成超时。
修复情况:应当记录两组节点中所有节点据最初节点的权重,在每次更新当前节点的所有熟人节点的权重后,找出所有未连接节点中权重最小的节点,将其作为下一轮的当前节点。
sim
使用迪杰斯特拉算法+堆优化算法。
(4) 请针对下页ppt内容对Network进行扩展,并给出相应的JML规格
假设出现了几种不同的Person
-
Advertiser:持续向外发送产品广告
-
Producer:产品生产商,通过Advertiser来销售产品
-
Customer:消费者,会关注广告并选择和自己偏好匹配的产品来购买 -- 所谓购买,就是直接通过Advertiser给相应Producer发一个购买消息
-
Person:吃瓜群众,不发广告,不买东西,不卖东西
如此Network可以支持市场营销,并能查询某种商品的销售额和销售路径等 请讨论如何对Network扩展,给出相关接口方法,并选择3个核心业务功能的接口方法撰写JML规格(借鉴所总结的JML规格模式)
Producer向Advertiser提供商品信息
/*@ public normal_behavior
@ requires containPerson(advertiserId) && containProduction(productId) &&
@ (\forall int i; 0 <= i && i < getPerson(advertiserId).products.length;
@ !getPerson(advertiserId).hasProduct(productId);
@ assignable getPerson(advertiserId).products ;
@ ensures (\forall int i; 0 <= i && i < \old(getPerson(advertiserId).products.length);
@ getPerson(advertiserId).hasProduct(getPerson(advertiserId).products[i].getId());
@ ensures getPerson(advertiserId).products.length == \old(getPerson(advertiserId).products.length) + 1 ;
@ ensures getPerson(advertiserId).hasProduct(productionId);
@ also
@ public exceptional_behavior
@ signals (AdvertiserIdNotFoundException e) !containPerson(advertiserId);
@ signals (ProductionIdNotFoundException e) !containProduction(productionId);
@ signals (EqualProductionIdException e) (\exists int i; 0 <= i && i < getPerson(advertiserId).products.length;
@ getPerson(advertiserId).products[i].getId() == productionId) ;
@*/
public void sendProduct(int advertiserId,int productId);
Advertiser发送广告
/*@ public normal_behavior
@ requires containsMessage(id) && getMessage(id).getType() == 0 &&
@ getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()) &&
@ getMessage(id).getPerson1() != getMessage(id).getPerson2();
@ assignable messages;
@ assignable getMessage(id).getPerson1().socialValue;
@ assignable getMessage(id).getPerson2().messages, getMessage(id).getPerson2().socialValue;
@ ensures !containsMessage(id) && messages.length == \old(messages.length) - 1 &&
@ (\forall int i; 0 <= i && i < \old(messages.length) && \old(messages[i].getId()) != id;
@ (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
@ ensures \old(getMessage(id)).getPerson1().getSocialValue() ==
@ \old(getMessage(id).getPerson1().getSocialValue()) + \old(getMessage(id)).getSocialValue() &&
@ \old(getMessage(id)).getPerson2().getSocialValue() ==
@ \old(getMessage(id).getPerson2().getSocialValue()) + \old(getMessage(id)).getSocialValue();
@ ensures (\old(getMessage(id)) instanceof Advertisement) ==>
@ (\forall int i; 0 <=i && i < \old(getMessage(id)).getPerson2().products.length; getMessage(id).getPerson2().hasProduct(\old(getMessage(id)).getPerson2().products[i]));
@ ensure getMessage(id).getPerson2().hasProduct(((Advertisement)\old(getMessage(id))).getProduct());
@ ensures (\forall int i; 0 <= i && i < \old(getMessage(id).getPerson2().getMessages().size());
@ \old(getMessage(id)).getPerson2().getMessages().get(i+1) == \old(getMessage(id).getPerson2().getMessages().get(i)));
@ ensures \old(getMessage(id)).getPerson2().getMessages().get(0).equals(\old(getMessage(id)));
@ ensures \old(getMessage(id)).getPerson2().getMessages().size() == \old(getMessage(id).getPerson2().getMessages().size()) + 1;
@ also
@ public normal_behavior
@ requires containsMessage(id) && getMessage(id).getType() == 1 &&
@ getMessage(id).getGroup().hasPerson(getMessage(id).getPerson1());
@ assignable people[*].socialValue, people[*].money, messages, emojiHeatList;
@ ensures !containsMessage(id) && messages.length == \old(messages.length) - 1 &&
@ (\forall int i; 0 <= i && i < \old(messages.length) && \old(messages[i].getId()) != id;
@ (\exists int j; 0 <= j && j < messages.length; messages[j].equals(\old(messages[i]))));
@ ensures (\forall Person p; \old(getMessage(id)).getGroup().hasPerson(p); p.getSocialValue() ==
@ \old(p.getSocialValue()) + \old(getMessage(id)).getSocialValue());
@ ensures (\forall int i; 0 <= i && i < people.length && !\old(getMessage(id)).getGroup().hasPerson(people[i]);
@ \old(people[i].getSocialValue()) == people[i].getSocialValue());
@ ensures ((\old(getMessage(id)) instanceof Advertisement)) ==>
@ (\forall Person p; \old(getMessage(id)).getGroup().hasPerson(p);
(\forall int i; 0 <=i && i < \old(p).products.length;p.hasProduct(\old(p).products[i])));
@ ensures ((\old(getMessage(id)) instanceof Advertisement)) ==>
@ (\forall Person p; \old(getMessage(id)).getGroup().hasPerson(p);
@ p.hasProduct(((Advertisement)\old(getMessage(id))).getProduct());
@ also
@ public exceptional_behavior
@ signals (MessageIdNotFoundException e) !containsMessage(id);
@ signals (RelationNotFoundException e) containsMessage(id) && getMessage(id).getType() == 0 &&
@ !(getMessage(id).getPerson1().isLinked(getMessage(id).getPerson2()));
@ signals (PersonIdNotFoundException e) containsMessage(id) && getMessage(id).getType() == 1 &&
@ !(getMessage(id).getGroup().hasPerson(getMessage(id).getPerson1()));
@*/
public void sendAdvertise(int id) throws PersonIdNotFoundException,MessageIdNotFoundException,RelationNotFoundException;
查询价格
/*@ public normal_behavior
@ requires contains(personId) && getPerson(personId).Productcontains(productId);
@ assignable \nothing;
@ ensures \result == getPerson(personId).getProduct(productId).getValue();
@ also
@ public exceptional_behavior
@ signals (PersonIdNotFoundException e) ! contians(personId);
@ signals (ProductIdNotFoundException) contians(personId) && ! getPerson(personId).Productcontains(productId);
@*/
public \*
(5) 本单元学习体会