柚子快報(bào)邀請(qǐng)碼778899分享:java 北航OO第三單元總結(jié)
柚子快報(bào)邀請(qǐng)碼778899分享:java 北航OO第三單元總結(jié)
1.測(cè)試過程
1.1黑箱測(cè)試與白箱測(cè)試
黑箱測(cè)試是一種測(cè)試方法,測(cè)試者不需要了解軟件內(nèi)部結(jié)構(gòu)或?qū)崿F(xiàn)細(xì)節(jié)。測(cè)試者關(guān)注的是軟件的功能和行為是否符合需求規(guī)格說明書的描述。
白箱測(cè)試是一種測(cè)試方法,測(cè)試者需要了解軟件的內(nèi)部結(jié)構(gòu)和實(shí)現(xiàn)細(xì)節(jié)。測(cè)試者基于代碼的邏輯路徑、分支條件、循環(huán)等編寫測(cè)試用例,以確保代碼的所有部分都被覆蓋和測(cè)試。主要是程序開發(fā)者對(duì)代碼的正確性進(jìn)行檢查的方法。
優(yōu)缺點(diǎn):
黑箱測(cè)試:關(guān)注軟件功能,不關(guān)心內(nèi)部實(shí)現(xiàn),適合驗(yàn)證需求和用戶體驗(yàn)。能有效發(fā)現(xiàn)輸入輸出相關(guān)的缺陷,但是不能覆蓋代碼的內(nèi)部邏輯和路徑,可能會(huì)遺漏內(nèi)部實(shí)現(xiàn)中的一些邊界情況或異常處理。白箱測(cè)試:關(guān)注代碼內(nèi)部邏輯和實(shí)現(xiàn),適合發(fā)現(xiàn)邏輯錯(cuò)誤和提高代碼覆蓋率,有助于優(yōu)化代碼質(zhì)量和性能。但編寫和維護(hù)測(cè)試用例的成本較高以及難以發(fā)現(xiàn)與輸入輸出相關(guān)的問題。
黑箱測(cè)試和白箱測(cè)試各有優(yōu)缺點(diǎn),單獨(dú)使用可能會(huì)有局限性,但結(jié)合使用可以發(fā)揮各自優(yōu)勢(shì),全面保障軟件質(zhì)量。通過合理的測(cè)試策略和自動(dòng)化工具的應(yīng)用,可以提高測(cè)試效率,減少軟件缺陷,提升用戶滿意度。
1.2具體測(cè)試
單元測(cè)試(Unit Testing)
單元測(cè)試是針對(duì)軟件中最小的可測(cè)試部分(單個(gè)函數(shù)或方法)不涉及其他模塊進(jìn)行的測(cè)試,來驗(yàn)證這些基本單元是否按預(yù)期工作。通過單元測(cè)試保證每個(gè)模塊的正確性來保證最終程序的正確性。個(gè)人感覺只要不是代碼邏輯上的錯(cuò)誤,就可以保證程序的正確性。
功能測(cè)試(Functional Testing)
功能測(cè)試類似于黑箱測(cè)試,驗(yàn)證軟件的各個(gè)功能是否按需求規(guī)格說明書描述的那樣工作。測(cè)試者關(guān)注的是功能是否正確實(shí)現(xiàn),而不關(guān)心內(nèi)部實(shí)現(xiàn)。具有一定的全面性可以覆蓋所有功能和用例,包括主流程和異常流程。
集成測(cè)試(Integration Testing)
集成測(cè)試是在單元測(cè)試之后,驗(yàn)證多個(gè)模塊或組件之間的交互是否正確。目的是發(fā)現(xiàn)接口和集成點(diǎn)的問題。
壓力測(cè)試(Stress Testing)
壓力測(cè)試是通過增加系統(tǒng)負(fù)載來測(cè)試系統(tǒng)在高壓條件下的表現(xiàn),比如構(gòu)造數(shù)據(jù)在該程序時(shí)間復(fù)雜度最高和超大數(shù)據(jù)的情況下進(jìn)行測(cè)試。目的是評(píng)估系統(tǒng)的穩(wěn)定性和性能瓶頸。
回歸測(cè)試(Regression Testing)
回歸測(cè)試是在軟件修改(增加新功能,修改部分功能)后進(jìn)行的測(cè)試,目的是確保修改沒有引入新的缺陷,且未影響現(xiàn)有功能。
2.架構(gòu)設(shè)計(jì)
本單元的設(shè)計(jì)框架基本都由
J
M
L
JML
JML給定了,主要就是維護(hù)一個(gè)社交網(wǎng)絡(luò)(
M
y
N
e
t
w
o
r
k
MyNetwork
MyNetwork),以每個(gè)人作為一個(gè)節(jié)點(diǎn),構(gòu)造一個(gè)無向圖形成社交網(wǎng)絡(luò)。
2.1整體圖架構(gòu)
2.2社交網(wǎng)絡(luò)維護(hù)策略
(一)第一次作業(yè)
在第一次作業(yè)中主要就是以人為節(jié)點(diǎn)構(gòu)建一個(gè)無向圖,形成一個(gè)社交網(wǎng)絡(luò),也就是是一個(gè)采用鄰接表維護(hù)的圖。
這次作業(yè)維護(hù)的重點(diǎn)在這幾個(gè)方法:
i
s
C
i
r
c
l
e
(
)
isCircle()
isCircle():查詢兩節(jié)點(diǎn)(Person)之間是否存在通路
q
u
e
r
y
B
l
o
c
k
S
u
m
(
)
queryBlockSum()
queryBlockSum():查詢?cè)摕o向圖中連通圖的數(shù)目
q
u
e
r
y
T
r
i
p
l
e
S
u
m
(
)
queryTripleSum()
queryTripleSum():通俗來說就是查詢?cè)撨B通圖中三個(gè)人之間相互聯(lián)通的數(shù)目
q
u
e
r
y
B
l
o
c
k
S
u
m
(
)
queryBlockSum()
queryBlockSum()和
q
u
e
r
y
T
r
i
p
l
e
S
u
m
(
)
queryTripleSum()
queryTripleSum()這兩個(gè)方法基本上都依賴于
i
s
C
i
r
c
l
e
(
)
isCircle()
isCircle()方法,但如果動(dòng)態(tài)處理的話,
q
u
e
r
y
T
r
i
p
l
e
S
u
m
(
)
queryTripleSum()
queryTripleSum()可以在添加關(guān)系和刪除關(guān)系時(shí)進(jìn)行動(dòng)態(tài)維護(hù)。方法如下:
//添加兩個(gè)節(jié)點(diǎn)關(guān)系時(shí)
public void addTripleSum(MyPerson myPerson1, MyPerson myPerson2) {
for (Person person : myPerson1.getAcquaintance().keySet()) {
if (person.isLinked(myPerson2)) {
tripleSum++;
}
}
}
//刪除兩個(gè)節(jié)點(diǎn)的關(guān)系時(shí)
public void deTripleSum(MyPerson myPerson1, MyPerson myPerson2) {
for (Person person : myPerson1.getAcquaintance().keySet()) {
if (person.isLinked(myPerson2)) {
tripleSum--;
}
}
}
i
s
C
i
r
c
l
e
(
)
isCircle()
isCircle()方法的維護(hù)主要采用并查集的方法,為每個(gè)連通圖設(shè)計(jì)一個(gè)父節(jié)點(diǎn),每個(gè)連通圖只有唯一一個(gè)父節(jié)點(diǎn),當(dāng)判斷兩個(gè)節(jié)點(diǎn)是否聯(lián)通時(shí),只要判斷這兩節(jié)點(diǎn)的父節(jié)點(diǎn)是否相同。
return union.isConnected(id1, id2);
public boolean isConnected(int id1, int id2) {
return find(id1) == find(id2);
}
(二)第二次作業(yè)
第二次作業(yè)圖的結(jié)構(gòu)沒有發(fā)生什么變化,主要就是新增了一些功能,具體要求如下:
q
u
e
r
y
S
h
o
r
t
e
s
t
P
a
t
h
(
)
queryShortestPath()
queryShortestPath():查詢兩個(gè)節(jié)點(diǎn)之間的最短路徑,首先要判斷兩個(gè)節(jié)點(diǎn)是否聯(lián)通
q
u
e
r
y
B
e
s
t
A
c
q
u
a
i
n
t
a
n
c
e
(
)
queryBestAcquaintance()
queryBestAcquaintance():找到一節(jié)點(diǎn)所有聯(lián)通的節(jié)點(diǎn)中關(guān)系最好的節(jié)點(diǎn),即權(quán)重最大的節(jié)點(diǎn)。前提是保證該節(jié)點(diǎn)有聯(lián)通的節(jié)點(diǎn)。
q
u
e
r
y
C
o
u
p
l
e
S
u
m
(
)
queryCoupleSum()
queryCoupleSum():圖中兩個(gè)節(jié)點(diǎn)相互是最好的
B
e
s
t
A
c
q
u
a
i
n
t
a
n
c
e
BestAcquaintance
BestAcquaintance的個(gè)數(shù)
q
u
e
r
y
T
a
g
V
a
l
u
e
S
u
m
(
)
queryTagValueSum()
queryTagValueSum():一個(gè)人的tag中所有人之間權(quán)值之和
q
u
e
r
y
S
h
o
r
t
e
s
t
P
a
t
h
(
)
queryShortestPath()
queryShortestPath()就是使用
b
f
s
bfs
bfs進(jìn)行廣度優(yōu)先搜索查找最短路徑。
q
u
e
r
y
B
e
s
t
A
c
q
u
a
i
n
t
a
n
c
e
(
)
queryBestAcquaintance()
queryBestAcquaintance()采用動(dòng)態(tài)維護(hù),對(duì)于每個(gè)節(jié)點(diǎn)設(shè)置
private int bestId;
private int maxValue;
在添加關(guān)系和改變關(guān)系,對(duì)這兩個(gè)值進(jìn)行更新,也是很好維護(hù)的。
q
u
e
r
y
T
a
g
V
a
l
u
e
S
u
m
(
)
queryTagValueSum()
queryTagValueSum()感覺是這次作業(yè)最難維護(hù)的方法,采用動(dòng)態(tài)維護(hù)如果遍歷當(dāng)時(shí)所有人中的所有tag,那么感覺和最后的雙重循環(huán)的時(shí)間復(fù)雜度感覺差不多,大概都是O(n)的復(fù)雜度。我采用的方法是在
p
e
r
s
o
n
person
person類中新維護(hù)一個(gè)
n
e
w
T
a
g
s
newTags
newTags
private final HashMap
這個(gè)
n
e
w
T
a
g
newTag
newTag存放該人在同一個(gè)
t
a
g
tag
tag里所有的
t
a
g
tag
tag,當(dāng)我們動(dòng)態(tài)維護(hù)時(shí),只要遍歷這個(gè)
n
e
w
T
a
g
s
newTags
newTags,這是不需要遍歷所有的
t
a
g
tag
tag,只需要遍歷部分的
t
a
g
tag
tag,最壞的情況才要遍歷所有的
t
a
g
tag
tag。
注意的細(xì)節(jié),因?yàn)橹挥型粋€(gè)
t
a
g
s
tags
tags里的
t
a
g
tag
tag的
i
d
id
id才會(huì)不同,但我們的
n
e
w
T
a
g
s
newTags
newTags里的
t
a
g
tag
tag的
i
d
id
id會(huì)有相同的情況,我就為這個(gè)
t
a
g
tag
tag新建了一個(gè)
i
d
id
id,這個(gè)
i
d
id
id只是為了避免重復(fù)和便于查找,沒有其他任何實(shí)際意義。
//netWork中的實(shí)現(xiàn)
public void addTag(int personId, Tag tag) {
MyPerson myPerson = (MyPerson) getPerson(personId);
myPerson.addTag(tag);
((MyTag) tag).setNewid(idcount);
idcount++;
}
public void addPersonToTag(int personId1, int personId2, int tagId) {
MyTag mytag = (MyTag) getPerson(personId2).getTag(tagId);
if (mytag.getSize() <= 1111) {
mytag.addPerson(getPerson(personId1));
((MyPerson) getPerson(personId1)).addToNewtags(mytag);
}
}
public void delPersonFromTag(int personId1, int personId2, int tagId) {
MyTag mytag = (MyTag) getPerson(personId2).getTag(tagId);
mytag.delPerson(getPerson(personId1));
((MyPerson) getPerson(personId1)).delFromNewTags(mytag);
}
public void addToNewtags(Tag tag) {
this.newTags.put(((MyTag) tag).getNewid(), tag);
}
public void delFromNewTags(Tag tag) {
this.newTags.remove(((MyTag) tag).getNewid());
}
//這步開始遍歷,并修改valueSum的值
public void find(MyPerson myPerson, int value) {
for (Tag tag : newTags.values()) {
if (tag.hasPerson(myPerson)) {
((MyTag) tag).changeValue(value);
}
}
}
(三)第三次作業(yè)
這次迭代就是發(fā)消息,這次作業(yè)沒有什么需要特殊維護(hù)的地方,只要讀懂
J
M
L
JML
JML的規(guī)格就行了,還有就是注意一些細(xì)節(jié)的實(shí)現(xiàn)基本上就沒什么問題了。
3.性能問題分析
3.1性能問題及其修復(fù)情況
我的代碼實(shí)現(xiàn)基本都使用動(dòng)態(tài)維護(hù)的方式,前面都介紹過了,這里不再贅述,動(dòng)態(tài)維護(hù)寫的基本上都可以通過強(qiáng)測(cè),感覺性能上沒啥太大的問題,
q
u
e
r
y
T
a
g
V
a
l
u
e
S
u
m
(
)
queryTagValueSum()
queryTagValueSum()采用了空間換時(shí)間的方式來優(yōu)化性能,其他需要雙重甚至三重循環(huán)的地方都采用動(dòng)態(tài)維護(hù)的方式進(jìn)行性能優(yōu)化。強(qiáng)測(cè)性能沒有問題,也沒有做任何修復(fù)。
3.2規(guī)格與實(shí)現(xiàn)分離
規(guī)格與實(shí)現(xiàn)分離是軟件開發(fā)中的一種設(shè)計(jì)原則,其核心思想是將軟件系統(tǒng)的規(guī)格(
J
M
L
JML
JML或需求)與實(shí)現(xiàn)(或代碼)分開,以實(shí)現(xiàn)更好的可維護(hù)性、可擴(kuò)展性和可重用性。規(guī)格與實(shí)現(xiàn)分離通過清晰地定義規(guī)格并將其與具體的實(shí)現(xiàn)分開,可以提高軟件系統(tǒng)的可維護(hù)性、可擴(kuò)展性和可重用性,降低系統(tǒng)的耦合度,從而更有效地開發(fā)和維護(hù)高質(zhì)量的軟件系統(tǒng)。
4.
J
u
n
i
t
Junit
Junit測(cè)試方法
我的
J
u
n
i
t
Junit
Junit測(cè)試方法主要包括構(gòu)造測(cè)試數(shù)據(jù)、驗(yàn)證前置條件、運(yùn)行測(cè)試方法、驗(yàn)證后置條件。
我在構(gòu)造測(cè)試數(shù)據(jù)時(shí),創(chuàng)建兩個(gè)完全相同的
N
e
t
w
o
r
k
Network
Network,這樣就實(shí)現(xiàn)了深拷貝的方法,對(duì)于其中一個(gè)的
N
e
t
w
o
r
k
Network
Network的通過
J
M
L
JML
JML規(guī)格保證前置條件的正確性,在調(diào)用代碼中的測(cè)試方法,得到新的
N
e
t
w
o
r
k
Network
Network和后置條件,通過比較這兩個(gè)結(jié)果是否
e
q
u
a
l
equal
equal來檢測(cè)代碼的正確性。
感覺這幾次的
J
u
n
i
t
Junit
Junit測(cè)試的難點(diǎn)在于數(shù)據(jù)的構(gòu)造,要保證數(shù)據(jù)盡可能地覆蓋所有的可能性,既要有稠密圖也要有稀疏圖,發(fā)送消息時(shí)也要考慮到所有的信息和發(fā)送的次數(shù)。
5.學(xué)習(xí)體會(huì)
這個(gè)單元的按照規(guī)完成代碼,雖然以后不是很常用,但是這種按照規(guī)格來寫代碼,保證這個(gè)方法的正確性,這種寫法感覺挺好的。但是這種模式只是給你最終實(shí)現(xiàn)的結(jié)果,具體的實(shí)現(xiàn)還得靠程序員,有時(shí)寫的代碼完全不同于規(guī)格所描述的,只是最終的結(jié)果符合他的規(guī)格敘述。
還有就是
J
u
n
i
t
Junit
Junit的編寫感覺還是有點(diǎn)麻煩,希望課程組可以在后期的課程中給一點(diǎn)關(guān)于
J
u
n
i
t
Junit
Junit測(cè)試的提示。
柚子快報(bào)邀請(qǐng)碼778899分享:java 北航OO第三單元總結(jié)
文章鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。