【OO】BUAA-OO-U3——JML模拟社交网络

BUAA OO U3总结

单元图模型构建与维护

本单元要求根据规定好的JML规格实现一个模拟社交网络,该网络中包含了用户、标签、消息、公众号等多种对象类型,在其之间存在归属、关联等关系将其联系起来,形成一定规则下的复杂社交网络。

构建

在构建该社交网络编程实现时,我认为要保持一些意识:

  1. 建立关系时该关系作为一种映射是何种类型,如关系的一方是否可以归属于不同的另一方
  2. 两对象间存在的不同关系是否存在依赖关系,如本单元中Tag依赖于Relation
  3. 容器中的对象是否可以重复,是否是同一个对象
  4. 同一类的实例对象是否会由于不体现在继承实现层面的,而是体现在实例不同的归属关系导致其在不同层次上虽然代码判定(equals)相同但是在意义上并不相同,如不同Person可以有相同id的Tag,而这些Tag实例虽然equals,但在全局的Network来看,其意义并不是相同的。

维护

本单元进行的操作均为简单的增删查改,仍然要保持一些意识:

  1. 增加时注意相关的维护变量是否会由此发生改变,是否要在多个不同位置中添加
  2. 删除时注意维护变量,尤其是最值变量,删除时可能需要重新遍历寻找新的最值。同时注意是否删干净,删正确,在不同层次是否均删除,同一容器中多个该对象是否均删除,是否删除了在当前层次不该删除的对象。删除关系时还要注意会不会影响相关的依赖关系。
  3. 查找时能维护的变量可以通过存储变量来进行快速查询,减少频繁查询过程的耗费时间。
  4. 修改时注意维护变量是否变化,是否存在有依赖的对象需要修改。

性能与修复

本单元中存在性能问题的操作我认为只有查询和删除。相应的,查询导致的性能问题可以通过维护变量使其复杂度降低到常数级;删除导致的性能问题可以通过维护索引关系降低其时间复杂度(主要是通过哈希方法)。下面为一些查询和删除的实现思路实例。

查询连通性

可以通过并查集或者直接BFS实现

查询三元环

增加或删除关系时遍历当前所有人,判断是否存在三元环,维护三元环总数。

删除接收到的文章

自行构建容器储存接收的文章,用HashMap索引节点,节点构成双向链表,对双向链表进行维护。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
static class MyLinkedList<E> {
private static class Node<E> {
private E data;
private Node<E> prev;
private Node<E> next;

Node(E data) {
this.data = data;
}
}

private final HashMap<E, HashSet<Node<E>>> indexMap = new HashMap<>();
private Node<E> head;
private Node<E> tail;

public void addFirst(E e) {
Node<E> newNode = new Node<>(e);
if (head == null) {
head = newNode;
tail = newNode;
} else {
newNode.next = head;
head.prev = newNode;
head = newNode;
}
if (!indexMap.containsKey(e)) {
indexMap.put(e, new HashSet<>());
}
indexMap.get(e).add(head);
}

public void remove(E e) {
HashSet<Node<E>> set = indexMap.get(e);
if (set == null) {
return;
}
for (Node<E> node : set) {
if (node.prev != null) {
node.prev.next = node.next;
} else {
head = node.next;
}
if (node.next != null) {
node.next.prev = node.prev;
} else {
tail = node.prev;
}
}
indexMap.remove(e);
}

public boolean contains(E e) {
return indexMap.containsKey(e);
}

public int size() {
return this.toList().size();
}

public List<E> toList() {
List<E> list = new ArrayList<>();
Node<E> current = head;
while (current != null) {
list.add(current.data);
current = current.next;
}
return list;
}
}

总之,性能问题是本单元需要着重关心的问题之一,可以认为规格仅给出了正确性约束,而良好的性能则需要实现的过程中使用更好的方法。这里体现了规格和实现的分离。

测试

本单元中可以采用多种测试方法,单元测试可以通过JUnit这一工具对各个类的方法进行测试,保证方法层次的正确性。功能测试可以对社交网络中的一些简单功能进行测试。集成测试注重各个类之间的交互关系是否正确。这些方法在对自己的代码进行测试的过程中都是非常有效的。在互测环节,采用的策略主要是黑盒测试和压力测试,针对容易出错的地方,自行或AI辅助构造数据点,如大量删除文章,群组红包无法整除人数等。

大模型辅助

大模型可以很好地辅助JML这一单元的开发,第一次作业我直接将JML丢给大模型,生成的代码基本满足规格,但某些细节出现了问题,如删除关系时没有把联系人从Tag中删除。于是后面的作业我便没有全权交给大模型编写代码,而是把较为简单重复的部分交给其实现。
另一个方面可以利用大模型构造数据,以下使用的模型为claude-3.5-sonnet

1
2
......(互测数据限制)
以上是数据要求,当前项目为一个模拟社交网络,我希望你能帮我构造一些测试样例,如将一篇文章转给同一个人多次然后再删除该文章,给群组中的人发送不能被人数整除的面额的红包等多种情况

生成的数据样例最初存在参数错误的问题,经指正后便可以生成较为不错的数据样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
您说得对,我需要更准确地理解每个指令的参数。以下是基于Network类实现的正确测试样例:

### 测试样例1:将文章转发多次后删除文章

text

Apply

ap 1 Zhang 20

ap 2 Li 21

ar 1 2 100

coa 1 3 Official

foa 2 3

ca 1 3 101

afm 1 101 1 2 0

sm 1

afm 2 101 2 1 0

sm 2

afm 3 101 1 2 0

sm 3

qra 2

da 1 3 101

afm 4 101 1 2 0

sm 4

qra 2

qrm 2

### 测试样例2:不能被人数整除的红包测试

text

Apply

ap 1 Zhang 20

ap 2 Li 21

ap 3 Wang 22

ar 1 2 50

ar 1 3 60

at 1 101

att 2 1 101

att 3 1 101

arem 1 17 1 1 101

sm 1

qm 1

qm 2

qm 3

### 测试样例3:表情消息热度和冷表情删除

text

Apply

ap 1 Zhang 20

ap 2 Li 21

ap 3 Wang 22

ap 4 Zhao 23

ar 1 2 100

ar 2 3 90

ar 3 4 80

sei 101

sei 102

sei 103

aem 1 101 1 2 0

sm 1

aem 2 101 2 3 0

sm 2

aem 3 102 3 4 0

sm 3

qp 101

qp 102

qp 103

dce 2

qp 101

qp 102

qp 103

### 测试样例4:社交关系和最佳关系查询

text

Apply

ap 1 Zhang 20

ap 2 Li 21

ap 3 Wang 22

ap 4 Zhao 23

ar 1 2 150

ar 1 3 100

ar 1 4 80

ar 2 3 120

qba 1

ar 1 2 50

qba 1

mr 1 3 100

qba 1

......

心得体会

经过本单元的学习,我体会到了规格在大模型辅助编码中的便利性和重要作用,同时对于一些编程实践思想有了新的认识,整个项目不是一道简单的题目,用精妙的方法实现某些特定的目的,而是可以通过更朴素使用的方法,如维护变量等,基于整个项目而不是一个方法来看待任务。同时对增删查改等操作编码时的操作实践有了更深的理解和体会。


【OO】BUAA-OO-U3——JML模拟社交网络
http://example.com/2025/05/19/【OO】BUAA-OO-U3——JML模拟社交网络/
作者
mRNA
发布于
2025年5月19日
许可协议