代碼審查中常見的「能跑通但上線炸裸」典型案例:用雙層循環比較兩個字串陣列的差異,時間複雜度 O(n×m),資料量一大直接拖垮系統。
public class WrongCompare {
public static void main(String[] args) {
String[] str1 = {"1","2","3","4","5","6"};
String[] str2 = {"0","2","3","4","5","6","7"};
// 找 str1 有、str2 無
for (int i = 0; i < str1.length; i++) {
boolean has = false;
for (int j = 0; j < str2.length; j++) {
if (str1[i].equals(str2[j])) { has = true; break; }
}
if (!has) System.out.println(str1[i] + " 在str1中,不在str2中");
}
// 找 str2 有、str1 無
for (int j = 0; j < str2.length; j++) {
boolean has = false;
for (int i = 0; i < str1.length; i++) {
if (str1[i].equals(str2[j])) { has = true; break; }
}
if (!has) System.out.println(str2[j] + " 在str2中,不在str1中");
}
}
}
痛點:兩次雙層循環,測試環境數據少不顯山露水,生產環境萬級數據直接 OOM/超時。
import java.util.*;
public class RightCompare {
public static void main(String[] args) {
String[] str1 = {"1","2","3","4","5","6"};
String[] str2 = {"0","2","3","4","5","6","7"};
Set<String> set1 = new HashSet<>(Arrays.asList(str1));
Set<String> set2 = new HashSet<>(Arrays.asList(str2));
// 差集:str1 - str2
for (String s : set1) {
if (!set2.contains(s))
System.out.println(s + " 在str1中,不在str2中");
}
// 差集:str2 - str1
for (String s : set2) {
if (!set1.contains(s))
System.out.println(s + " 在str2中,不在str1中");
}
}
}
| 指標 | 雙重循環 | HashSet |
|---|---|---|
| 時間複雜度 | O(n × m) | O(n + m) |
| 空間複雜度 | O(1) | O(n + m) |
| 10萬級數據耗時 | ~10¹⁰ 次操作(不可接受) | ~2×10⁵ 次操作(毫秒級) |
contains 平均 O(1)。HashSet/HashMap。此例雖簡單,卻折射出「演算法意識」在工程落地中的生死攸關地位。