Java 比較器解析

一、比較器的核心作用與應用場景

在 Java 編程中,數據比較是一個基礎但重要的操作。對于基本數據類型(如 int、double、boolean、char 等),Java 語言本身就提供了完整的比較運算符(>、<、==、>=、<=、!=)可以直接使用。例如:

int a = 10;
int b = 20;
boolean result = a < b; // 返回 true

然而,當涉及到自定義對象(即開發者定義的類實例)時,情況就完全不同了。假設我們有一個 Student 類:

class Student {private String name;private int score;// 構造方法和其他方法...
}

如果我們嘗試直接比較兩個 Student 對象:

Student s1 = new Student("Alice", 90);
Student s2 = new Student("Bob", 85);
boolean comp = s1 > s2; // 編譯錯誤!無法直接比較對象

這時就需要比較器來發揮作用。比較器的核心作用就是為自定義對象定義明確的比較規則,使得這些對象能夠按照開發者的預期進行排序或比較。Java 提供了兩種主要的比較方式:

  1. Comparable 接口:讓對象自身實現比較邏輯
  2. Comparator 接口:定義獨立于對象的比較邏輯

比較器在實際開發中有廣泛的應用場景,主要包括:

  1. 集合排序

    • 對 List、Set 等集合中的自定義對象進行排序
    • 例如:對學生列表按成績從高到低排序
    • 使用 Collections.sort() 或 List.sort() 方法
  2. 優先級隊列

    • 實現基于自定義規則的優先級隊列(PriorityQueue)
    • 例如:急診系統中的患者優先隊列
  3. Stream 操作

    • 在 Stream 流操作中使用 sorted() 方法進行排序
    • 例如:從數據庫查詢出的數據流按特定字段排序
  4. 有序集合

    • 實現具有自定義排序規則的數據結構
    • 如 TreeMap(基于鍵的排序)、TreeSet 等
    • 例如:按員工工號排序的員工信息映射表
  5. 算法實現

    • 在需要比較操作的算法中使用,如二分查找、排序算法等

比較器的使用使得對象間的比較和排序變得靈活且可控,開發者可以根據業務需求定義任意的比較規則,比如按多個字段組合排序、按逆序排序等。這種機制是 Java 集合框架強大功能的重要支撐之一。

二、Comparable 接口:對象自身的比較能力

Comparable接口位于java.lang包下,是一個泛型接口,其定義如下:

public interface Comparable<T> {public int compareTo(T o);
}

2.1 核心方法解析

compareTo(T o)方法是Comparable接口中唯一的抽象方法,它的作用是將當前對象與參數對象o進行比較,返回一個整數值,具體含義如下:

  • 返回正整數:表示當前對象大于參數對象
  • 返回0:表示當前對象等于參數對象
  • 返回負整數:表示當前對象小于參數對象

該方法需要滿足以下數學特性:

  1. 自反性:x.compareTo(x) == 0
  2. 對稱性:x.compareTo(y)與y.compareTo(x)符號相反
  3. 傳遞性:如果x.compareTo(y) > 0且y.compareTo(z) > 0,則x.compareTo(z) > 0

2.2 使用示例:自定義對象實現 Comparable

下面以Student類為例,演示如何實現Comparable接口:

public class Student implements Comparable<Student> {private String name;private int age;private double score;// 構造方法public Student(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}// getter和setter方法public String getName() { return name; }public int getAge() { return age; }public double getScore() { return score; }@Overridepublic int compareTo(Student o) {// 按照年齡升序排序return Integer.compare(this.age, o.age);// 如果需要降序排序,可以改為:// return Integer.compare(o.age, this.age);// 注意:直接使用減法(this.age - o.age)可能導致整數溢出問題}
}

實現Comparable接口后,我們就可以使用Collections.sort()或Arrays.sort()方法對對象數組或集合進行排序:

public static void main(String[] args) {List<Student> students = new ArrayList<>();students.add(new Student("張三", 20, 85.5));students.add(new Student("李四", 18, 90.0));students.add(new Student("王五", 22, 78.5));students.add(new Student("趙六", 19, 88.0));// 直接調用sort方法,會使用Student類自身實現的compareTo方法Collections.sort(students);System.out.println("按年齡排序結果:");for (Student s : students) {System.out.printf("%s - 年齡:%d,分數:%.1f%n", s.getName(), s.getAge(), s.getScore());}
}

2.3 Comparable 的特點與局限性

特點:
  1. 自然排序:實現Comparable接口的類具有自身比較能力,可以直接進行排序
  2. 內置規則:排序規則是固定的,屬于類的一部分
  3. 實現簡單:只需重寫compareTo方法
  4. 廣泛支持:可以被標準集合類(如TreeSet、TreeMap)直接使用
局限性:
  1. 排序規則固定:無法在運行時動態改變比較邏輯
  2. 修改受限:如果類已經被定義且無法修改(如第三方類庫中的類),則無法實現Comparable接口
  3. 單一規則:只能實現一種排序規則,無法滿足多種排序需求(如需同時支持按年齡和分數排序)
  4. 侵入性強:需要修改類本身,可能違反開閉原則
替代方案:

當Comparable不能滿足需求時,可以考慮使用Comparator接口,它允許在不修改原有類的情況下定義多種比較規則。

三、Comparator 接口:外部比較器

1. 接口概述

Comparator 接口位于 java.util 包下,是一個泛型接口,也是 Java 函數式編程的重要接口之一。其核心定義如下:

@FunctionalInterface
public interface Comparator<T> {int compare(T o1, T o2);// 其他默認方法和靜態方法省略
}

2. 核心方法解析

compare(T o1, T o2) 方法是 Comparator 接口的核心方法,用于比較兩個參數對象的大小,返回值含義如下:

  • 返回正整數:表示 o1 大于 o2
  • 返回0:表示 o1 等于 o2
  • 返回負整數:表示 o1 小于 o2

這個方法遵循了反自反性對稱性傳遞性的數學比較規則,確保排序的一致性。

3. 使用方式

3.1 自定義類實現 Comparator 接口

這是最傳統的方式,適合需要重復使用的比較邏輯。

// 按照學生年齡升序排序的比較器
public class AgeAscComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge() - o2.getAge();}
}// 按照學生成績降序排序的比較器
public class ScoreDescComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {// 注意:double類型不建議直接相減,可能存在精度問題return Double.compare(o2.getScore(), o1.getScore());}
}

使用時,將比較器作為參數傳遞給排序方法:

public static void main(String[] args) {List<Student> students = new ArrayList<>();// 添加元素...students.add(new Student("Alice", 20, 88.5));students.add(new Student("Bob", 19, 92.0));students.add(new Student("Charlie", 21, 85.5));// 使用年齡升序比較器Collections.sort(students, new AgeAscComparator());// 使用成績降序比較器Collections.sort(students, new ScoreDescComparator());
}

3.2 匿名內部類形式

對于簡單的比較邏輯,可以使用匿名內部類,避免創建過多的比較器類:

// 按照姓名升序排序(字典順序)
Collections.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getName().compareTo(o2.getName());}
});// 按照學生ID排序
Collections.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Long.compare(o1.getId(), o2.getId());}
});

3.3 Lambda 表達式形式(Java 8+)

由于 Comparator 是函數式接口,在 Java 8 及以上版本中,可以使用 Lambda 表達式簡化代碼:

// 按照年齡降序排序
Collections.sort(students, (s1, s2) -> s2.getAge() - s1.getAge());// 按照成績升序排序
students.sort((s1, s2) -> Double.compare(s1.getScore(), s2.getScore()));// 更簡潔的寫法:使用方法引用
students.sort(Comparator.comparingInt(Student::getAge));

4. Comparator 的默認方法與鏈式比較

Java 8 為 Comparator 接口增加了多個默認方法,使得比較器的使用更加靈活,可以實現鏈式比較。

4.1 常用默認方法

  • reversed():返回一個反向的比較器
  • thenComparing(Comparator):當前比較器比較結果相等時,使用參數比較器繼續比較
  • thenComparingInt(ToIntFunction):針對 int 類型的屬性進行二次比較
  • thenComparingLong(ToLongFunction):針對 long 類型的屬性進行二次比較
  • thenComparingDouble(ToDoubleFunction):針對 double 類型的屬性進行二次比較

4.2 鏈式比較示例

// 復雜排序:先按年齡升序,年齡相同按成績降序,成績相同按姓名升序
Comparator<Student> complexComparator = Comparator.comparingInt(Student::getAge).thenComparing(Student::getScore, Comparator.reverseOrder()).thenComparing(Student::getName);students.sort(complexComparator);

4.3 實用靜態方法

Comparator 接口還提供了一些實用的靜態方法:

// 處理null值的情況:null元素排在最后
Comparator.nullsLast(Comparator.comparing(Student::getName));// 自然順序比較
Comparator.naturalOrder();// 反向自然順序
Comparator.reverseOrder();

5. 實際應用場景

  1. 集合排序:對 List 進行多種規則的排序
  2. 優先隊列:自定義優先級隊列的排序規則
  3. TreeMap/TreeSet:自定義排序規則的集合
  4. Stream API:在流式操作中進行排序
  5. 數據庫查詢結果排序:對查詢結果進行內存排序

6. 注意事項

  1. 對于浮點數比較,建議使用 Double.compare()Float.compare() 而非直接相減
  2. 比較器應確保滿足比較的數學性質(自反性、對稱性、傳遞性)
  3. 對于可能為null的對象,考慮使用 Comparator.nullsFirst()Comparator.nullsLast()
  4. 在多線程環境下,比較器應該是線程安全的(通常是無狀態的)

通過合理使用 Comparator 接口及其豐富的方法,可以實現各種復雜的排序需求,使代碼更加簡潔和靈活。

四、Comparable 與 Comparator 的區別與聯系

特性

Comparable

Comparator

所在包

java.lang

java.util

方法名稱

compareTo(T o)

compare(T o1, T o2)

比較方式

自身與其他對象比較

兩個外部對象比較

實現位置

被比較的類內部

被比較的類外部

靈活性

固定排序規則,靈活性低

可定義多個比較器,靈活性高

適用場景

類的默認排序規則

動態改變排序規則或第三方類排序

聯系

  • 兩者都是用于定義對象之間的比較規則
  • 都返回 int 類型的比較結果
  • 都可以用于集合或數組的排序操作

五、比較器的底層排序原理

Java 中的排序算法會根據不同的場景選擇合適的排序實現。在基礎數據類型的排序中,Java 會使用針對特定數據類型優化的排序算法,如對int數組使用Dual-Pivot Quicksort(雙軸快速排序)。而對于對象數組或集合的排序,主要使用TimSort算法(Java 7 及以上版本),這是一種結合了歸并排序和插入排序的混合排序算法,具有以下特點:

  1. 時間復雜度:最壞情況O(n log n),最好情況O(n)
  2. 穩定排序:能夠保持相等元素的原始相對順序
  3. 對小規模數據會自動切換到插入排序

比較器在排序過程中的作用是提供靈活的比較規則,排序算法會根據比較器返回的結果來決定元素的位置。具體來說,排序過程會經歷以下步驟:

  1. 當調用Arrays.sort()或Collections.sort()方法時
  2. 排序算法會初始化比較器實例
  3. 在排序過程中,會多次調用比較器的compareTo或compare方法
  4. 根據返回值(負值、零、正值)判斷元素的相對順序
    • 負值表示第一個參數小于第二個
    • 零表示相等
    • 正值表示第一個參數大于第二個
  5. 通過不斷比較和交換元素位置,直到整個集合有序

應用示例:

List<Person> persons = new ArrayList<>();
// 添加元素...
Collections.sort(persons, (p1, p2) -> {// 先按年齡排序int ageCompare = Integer.compare(p1.getAge(), p2.getAge());if (ageCompare != 0) return ageCompare;// 年齡相同則按姓名排序return p1.getName().compareTo(p2.getName());
});

六、使用比較器的注意事項

6.1 避免整數溢出問題

當使用整數類型(如 int)的差值作為比較結果時,可能會出現整數溢出問題,尤其是在處理接近邊界值的情況時:

// 錯誤示例:可能導致溢出
@Override
public int compareTo(Student o) {// 當this.age為Integer.MAX_VALUE(2147483647),o.age為負數(如-1)時// 2147483647 - (-1) = 2147483648,超出int范圍導致溢出為-2147483648return this.age - o.age;
}// 正確示例:使用Integer.compare方法
@Override
public int compareTo(Student o) {// Integer.compare內部安全處理了邊界情況return Integer.compare(this.age, o.age);
}

同樣,對于 long 類型:

// 使用Long.compare
return Long.compare(this.bigNumber, o.bigNumber);

對于 double 類型:

// 使用Double.compare
return Double.compare(this.precisionValue, o.precisionValue);

6.2 保持比較的一致性

比較器的實現必須滿足以下數學性質,否則可能導致排序結果不穩定或出現異常:

  1. 自反性:compare(a, a)必須返回 0

    • 例:比較兩個相同對象時總返回0
  2. 對稱性:compare(a, b)與compare(b, a)的結果必須相反

    • 例:若compare("a","b")返回-1,則compare("b","a")應返回1
  3. 傳遞性:如果compare(a, b) < 0且compare(b, c) < 0,則compare(a, c) < 0

    • 例:若a < b且b < c,則必須保證a < c

6.3 注意空值處理

當比較的對象可能為 null 時,需要明確null的處理策略:

// 處理可能為null的情況
Comparator<Student> comparator = (s1, s2) -> {if (s1 == s2) return 0; // 包括兩個都為null的情況if (s1 == null) return -1; // 定義null小于任何非null值if (s2 == null) return 1;  // 定義非null值大于nullreturn s1.getName().compareTo(s2.getName()); // 都不為null時比較name
};// 另一種處理方式:使用nullsFirst/nullLast
Comparator<Student> nullSafeComparator = Comparator.nullsFirst(Comparator.comparing(Student::getName));

6.4 注意浮點類型的比較

浮點類型直接相減比較可能存在精度問題:

// 錯誤示例:可能存在精度問題
return (int)(this.score - o.score); // 可能丟失精度且仍可能溢出// 正確示例:使用Double.compare方法
return Double.compare(this.score, o.score); // 正確處理NaN和精度問題// 如果需要指定精度范圍比較
private static final double EPSILON = 0.0001;
public int compareWithTolerance(Double a, Double b) {if (Math.abs(a - b) < EPSILON) {return 0;}return Double.compare(a, b);
}

6.5 考慮排序的穩定性

穩定的排序算法在比較相等元素時能保持原始順序:

List<Student> students = ...;// 多級比較保證穩定性
students.sort(Comparator.comparingInt(Student::getAge)      // 主排序字段.thenComparing(Student::getName)   // 次排序字段.thenComparingInt(Student::getId)); // 唯一標識字段// 實際應用場景:先按部門排序,部門相同的按入職時間排序
employees.sort(Comparator.comparing(Employee::getDepartment).thenComparing(Employee::getHireDate));

七、實際開發中的最佳實踐

7.1 優先使用 Comparator 接口

在 Java 集合排序中,建議優先使用 Comparator 接口而非 Comparable 接口,因為 Comparator 提供了更靈活的排序方案:

  1. 多排序規則支持:可以為同一個類定義多個比較器,實現不同的排序規則。例如,對 Student 類可以分別按年齡、成績或姓名排序:

    Comparator<Student> byAge = Comparator.comparingInt(Student::getAge);
    Comparator<Student> byScore = Comparator.comparingDouble(Student::getScore);
    Comparator<Student> byName = Comparator.comparing(Student::getName);
    

  2. 非侵入式排序:不需要修改被比較類的源代碼,特別適合對第三方庫中的類進行排序。例如對 String 類進行自定義排序:

    Comparator<String> lengthComparator = Comparator.comparingInt(String::length);
    

  3. 運行時靈活性:可以在運行時根據業務需求動態選擇排序規則。例如:

    Comparator<Student> currentComparator = userPrefersAgeSorting ? byAge : byScore;
    

  4. 鏈式比較:支持多級排序,當第一個比較條件相等時,可以繼續使用其他比較條件:

    Comparator<Student> complexComparator = byAge.thenComparing(byScore).thenComparing(byName);
    

7.2 結合 Stream API 使用

Java 8 引入的 Stream API 與 Comparator 完美配合,可以優雅地實現集合排序:

  1. 基本排序示例

    List<Student> students = getStudents();
    List<Student> sortedStudents = students.stream().sorted(Comparator.comparingInt(Student::getAge))  // 按年齡升序.collect(Collectors.toList());
    

  2. 降序排序

    List<Student> reversedSorted = students.stream().sorted(Comparator.comparingInt(Student::getAge).reversed()).collect(Collectors.toList());
    

  3. 多字段排序

    List<Student> multiSorted = students.stream().sorted(Comparator.comparing(Student::getGrade).thenComparing(Student::getScore).reversed()).collect(Collectors.toList());
    

  4. 空值處理

    // 將null值排在最后
    Comparator<Student> nullsLast = Comparator.nullsLast(Comparator.comparing(Student::getName));
    

7.3 為常用比較器提供靜態工廠方法

在業務類中提供靜態工廠方法可以增強代碼的可讀性和復用性:

public class Student {private String name;private int age;private double score;// 構造方法、getter/setter省略.../*** 創建按年齡升序的比較器*/public static Comparator<Student> ageAscComparator() {return Comparator.comparingInt(Student::getAge);}/*** 創建按成績降序的比較器*/public static Comparator<Student> scoreDescComparator() {return Comparator.comparingDouble(Student::getScore).reversed();}/*** 創建先按班級后按姓名的比較器*/public static Comparator<Student> classThenNameComparator() {return Comparator.comparing(Student::getClassName).thenComparing(Student::getName);}
}// 使用示例
List<Student> students = getStudents();
students.sort(Student.ageAscComparator());
// 或者
students.sort(Student.scoreDescComparator());

這種模式的優點:

  • 將比較邏輯封裝在被比較類中,符合封裝原則
  • 方法名可以清晰地表達比較規則
  • 避免在業務代碼中重復編寫比較邏輯
  • 便于統一修改比較規則

7.4 使用 Comparator.comparing 簡化代碼

Java 8 的 Comparator 類提供了一系列靜態工廠方法,可以極大簡化比較器的創建:

  1. 基本比較方法

    // 按姓名排序(區分大小寫)
    Comparator<Student> byName = Comparator.comparing(Student::getName);// 按年齡排序
    Comparator<Student> byAge = Comparator.comparingInt(Student::getAge);// 按成績排序
    Comparator<Student> byScore = Comparator.comparingDouble(Student::getScore);
    

  2. 自定義鍵提取器

    // 按姓名長度排序
    Comparator<Student> byNameLength = Comparator.comparing(student -> student.getName().length());
    

  3. 鏈式比較

    // 先按年級,再按年齡,最后按成績
    Comparator<Student> complexComparator = Comparator.comparing(Student::getGrade).thenComparing(Student::getAge).thenComparingDouble(Student::getScore);
    

  4. 空值安全比較

    // 處理可能為null的屬性
    Comparator<Student> nullSafeComparator = Comparator.comparing(Student::getName, Comparator.nullsLast(Comparator.naturalOrder()));
    

  5. 自定義比較器

    // 使用自定義的字符串比較規則
    Comparator<Student> caseInsensitive = Comparator.comparing(Student::getName, String.CASE_INSENSITIVE_ORDER);
    

這些方法不僅使代碼更簡潔,還能提高可讀性和維護性,是現代化Java編程中處理排序的首選方式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92976.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92976.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92976.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java學習第一百二十一部分——HTTP

目錄 一、前言簡介 二、核心特性 三、通信基礎結構 四、關鍵組件詳解 五、性能演進——版本對比 六、開發者建議 七、總結歸納 一、前言簡介 HTTP&#xff08;“H”yper“t”ext “T”ransfer “P”rotocol&#xff0c;超文本傳輸協議&#xff09;是互聯網上應用最廣泛…

記錄RK3588的docker中啟動rviz2報錯

安裝好rk3588 的docker&#xff0c;pull了ros的完整鏡像后&#xff0c;想要啟動rviz但是報錯&#xff0c;下面是我的踩坑記錄 0.原始的啟動鏡像的腳本&#xff1a; sudo docker run -it --rm --privileged --nethost -e DISPLAY$DISPLAY --namemy_image_name \-e DISPLAY$DIS…

ThingJS 新手學習技巧

一、ThingJS 基礎認知 1.1 ThingJS 是什么 ThingJS 是一款基于 WebGL 技術的 3D 可視化開發平臺&#xff0c;它為開發者提供了簡單易用的 API 和豐富的 3D 場景組件&#xff0c;讓開發者能夠快速構建出高質量的 3D 可視化應用。無論是智慧園區、智慧樓宇、智慧交通還是工業監…

【軟考架構】需求工程中,系統分析與設計的結構化方法

結構化方法誕生于20世紀70年代&#xff0c;是為了應對當時日益復雜的軟件系統開發挑戰&#xff08;如“軟件危機”&#xff09;而提出的。它強調系統性、規范性、分解和抽象&#xff0c;目標是提高軟件開發的效率、質量和可維護性&#xff0c;降低復雜性。 核心思想&#xff1a…

FPGA常用資源之IO概述

目錄 一、前言 二、I/O資源 2.1 I/O端口資源 2.1.1 IOB 2.1.2 ILOGIC/OLOGIC 2.2 ZHOLD 2.3 IDDR/ODDR 2.4 IDELAY 2.5 ISERDES/OSERDES 2.6 IO Logic Resource連接 2.7 Device示意圖 三、工程示例 3.1 工程代碼 3.2 Device結果 一、前言 FPGA芯片從內部結構看主…

密集遮擋場景識別率↑31%!陌訊輕量化部署方案在智慧零售的實戰解析

一、零售業痛點&#xff1a;當技術遇上客流洪流據《2024智慧零售技術白皮書》統計&#xff0c;高峰期超市顧客密度超3人/㎡時&#xff0c;??目標漏檢率高達48%??。核心挑戰包括&#xff1a;??動態遮擋??&#xff1a;購物車/貨架造成的持續性目標截斷??計算瓶頸??&a…

力扣(O(1) 時間插入、刪除和獲取隨機元素)

一、題目分析&#xff08;一&#xff09;功能需求 我們需要實現 RandomizedSet 類&#xff0c;包含以下功能&#xff1a; RandomizedSet()&#xff1a;初始化數據結構。bool insert(int val)&#xff1a;當元素 val 不存在時&#xff0c;插入該元素并返回 true&#xff1b;若已…

前端開發的面試自我介紹與準備

前端面試自我介紹不知道怎么說的&#xff0c;直接參考下面的模板&#xff0c;然后換成你的經歷 自我介紹控制在1分鐘左右&#xff0c;千萬不要說的太久&#xff0c;面試官會煩的&#xff0c;但是又不好意思打斷你 切記面試是人和人面對面的交流&#xff0c;要有&#xff0c;面試…

10、系統規劃與分析

一、系統規劃步驟系統規劃步驟對現有系統進行初步調查分析和確定系統目標分析子系統的組成和基本功能擬定系統的實施方案擬定系統的可行性研究指定系統建設方案系統規劃階段的產出物&#xff1a;可行性研究報告、系統設計任務書。習題1、擬定系統的實施方案是在系統規劃階段完成…

Nginx學習筆記(六)—— Nginx反向代理

&#x1f4da;Nginx學習筆記&#xff08;六&#xff09;—— Nginx反向代理 &#x1f4cc; 一、反向代理核心概念 本質原理&#xff1a; #mermaid-svg-UkFRDp2Ut7MK5T2N {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-s…

三伍微電子GSR2406 IoT FEM 2.4G PA 射頻前端模組芯片

三伍微電子GSR2406 IoT FEM 2.4G PA 射頻前端模組芯片規格書Product Description The GSR2406 is a high-performance, fully integrated RF front-end module (FEM) designed for Zigbee technology, Thread, and Bluetooth (including low energy) applications. The GSR2406…

開發避坑指南(24):RocketMQ磁盤空間告急異常處理,CODE 14 “service not available“解決方案

異常信息 Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 14 DESC: service not available now, maybe disk full, CL: 0.94 CQ: 0.94 INDEX: 0.94, maybe your broker machine memory too small.異常背景 一個項目里面用到了rocketmq&#x…

開源WAF新標桿:雷池SafeLine用語義分析重構網站安全邊界

文章目錄前言【視頻教程】1.安裝Docker2.本地部署SafeLine3.使用SafeLine4.cpolar內網穿透工具安裝5.創建遠程連接公網地址6.固定Uptime Kuma公網地址前言 當個人或企業站點上線后面臨的首要威脅往往來自網絡攻擊——據統計&#xff0c;超過60%的Web應用漏洞利用嘗試在流量到達…

Mac M1探索AnythingLLM+SearXNG

SearXNG 能聚合來自多達 200 多個搜索服務&#xff0c;可私有化部署&#xff0c;并提供了靈活自定義選項。 AnythingLLMSearXNG&#xff0c;剛好能解決AnythingLLM因為網絡限制導致web search不可用的問題。 1 安裝docker 下載mac m1版本的docker并安裝。 https://docs.dock…

模式設計:策略模式及其應用場景

簡介 策略模式(Strategy Pattern)是一種行為型設計模式,它允許在運行時動態選擇算法或行為。核心思想是將算法封裝成獨立的類(策略),使它們可以相互替換,讓算法的變化獨立于使用它的客戶端。 核心思想 解耦:將算法的定義與使用分離。每個算法封裝起來,使它們可以互…

Squash Merge(壓縮合并)和Rebase Merge(變基合并)介紹

文章目錄**1. Squash Merge&#xff08;壓縮合并&#xff09;****定義****操作步驟****特點****優點****缺點****2. Rebase Merge&#xff08;變基合并&#xff09;****定義****操作步驟****特點****優點****缺點****3. 對比總結****4. 選擇建議****5. 示例場景****Squash Merg…

Linux編程 —— framebuffer

一、framebuffer概念framebuffer&#xff1a;幀緩沖&#xff0c;幀緩存技術Linux內核專門為圖形化顯示提供的一套應用程序接口。二、基本操作步驟1. 打開顯示設備(/dev/fb0) 2. 獲取顯示設備相關參數&#xff08;分辨率&#xff0c;像素格式&#xff09;---》ioctl 3. 建立顯存…

文件編輯html

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>文件行內容編輯器</title><script src&…

具有熔斷能力和活性探測的服務負載均衡解決方案

一、整體架構設計 1.核心組件 負載均衡器&#xff1a;負責選擇可用的服務節點健康檢查器&#xff1a;定期檢測服務節點的可用性服務節點管理&#xff1a;維護所有可用節點的狀態信息 2.負載均衡策略 輪詢(Round Robin)隨機(Random)加權輪詢(Weighted Round Robin)最少連接(Leas…

技術演進中的開發沉思-62 DELPHI VCL系列:VCL下的設計模式

今天聊聊設計模式&#xff0c;當然這個章節目前僅限于DELPHI VCL,因為接下來梳理的Factory/Factory Method、Bootstrap 和 ForEach 這三種設計樣例&#xff0c;看似獨立&#xff0c;卻在實際開發中相互配合&#xff0c;共同構建起高效、靈活的程序架構。在 DELPHI VCL 開發的技…