Android EventBus使用方法與底層原理詳解

EventBus 是什么?

EventBus 是一個基于發布/訂閱(Publish/Subscribe) 模式的開源庫(主要由 greenrobot 開發維護)。它的核心目的是簡化 Android 應用中不同組件(如 Activity, Fragment, Service, Thread 等)之間的通信。它通過一個中央事件總線(Central Event Bus)來傳遞事件(Event 對象),允許組件訂閱它們關心的事件類型,并在事件發生時自動接收通知。這顯著降低了組件間的耦合度。

核心概念

  1. 事件 (Event): 一個普通的 Java 對象(POJO),代表需要傳遞的消息或通知。事件本身不包含邏輯,只是數據的載體。可以是任何類,比如 MessageEvent, DataUpdateEvent, UserLoggedInEvent 等。
  2. 發布者 (Publisher): 任何需要通知其他組件發生了某事的對象。它創建一個事件對象并通過 EventBus 實例post(event) 發布該事件到總線上。
  3. 訂閱者 (Subscriber): 對特定類型事件感興趣的對象。它包含一個或多個用 @Subscribe 注解標記的方法(稱為事件處理方法)。這些方法定義了當特定事件被發布時應該執行的邏輯。
  4. 事件總線 (EventBus): 單例(通常通過 EventBus.getDefault() 獲取)或自定義實例。它負責:
    • 維護所有訂閱者及其感興趣的事件類型的注冊表。
    • 接收發布者發送的事件。
    • 根據事件類型查找所有匹配的訂閱者。
    • 在正確的線程(根據訂閱方法指定的 ThreadMode)上調用訂閱者的事件處理方法。

一、 使用方法 (非常詳細)

1. 添加依賴 (以 Gradle 為例)

在 app 模塊的 build.gradle 文件中添加最新版本的 EventBus 依賴(請查看 Maven Central 獲取最新版本):

dependencies {implementation 'org.greenrobot:eventbus:3.3.1' // 檢查最新版本
}

2. 定義事件 (Event)

創建一個簡單的 Java 類來表示你想要傳遞的數據或通知。

public class MessageEvent {public final String message;public MessageEvent(String message) {this.message = message;}
}

3. 準備訂閱者 (Subscriber)

在需要接收事件的組件(如 Activity、Fragment、Service 或任何普通對象)中:

  • 注冊/注銷: 組件必須在開始接收事件前向 EventBus 注冊自己,并在不再需要接收事件(或生命周期結束時)注銷自己,以避免內存泄漏和無效調用。
    • 注冊: 通常在 onStart()onResume() 中進行。
    • 注銷: 通常在 onStop()onPause() 中進行(選擇與注冊對稱的生命周期方法)。對于 Fragment,onCreateView/onDestroyView 也是常見選擇。
public class MyActivity extends AppCompatActivity {@Overrideprotected void onStart() {super.onStart();EventBus.getDefault().register(this); // 注冊當前 Activity 作為訂閱者}@Overrideprotected void onStop() {super.onStop();EventBus.getDefault().unregister(this); // 注銷當前 Activity}// ... 其他代碼 ...
}
  • 聲明事件處理方法: 使用 @Subscribe 注解標記一個公共方法(方法名任意)。該方法的參數類型決定了它訂閱哪種事件。注解可以指定 threadModesticky 屬性。
    • threadMode (必選): 指定事件處理方法在哪個線程執行。這是 EventBus 的核心優勢之一。
      • ThreadMode.POSTING (默認): 在事件發布所在的線程調用。最快,避免線程切換開銷。小心:如果發布者在主線程發布,你在這里不能執行耗時操作;如果發布者在后臺線程發布,你在這里不能更新UI。
      • ThreadMode.MAIN: 在 Android 的主線程 (UI 線程) 調用。安全更新 UI。如果事件是在主線程發布的,方法會立即執行;否則,事件會被放入主線程隊列等待處理。
      • ThreadMode.MAIN_ORDERED: 類似于 MAIN,但事件在隊列中有序執行MAIN 可能在某些情況下插隊)。通常使用 MAIN 即可。
      • ThreadMode.BACKGROUND: 在后臺線程調用。如果事件是在非主線程發布的,就在該線程直接調用;如果是在主線程發布的,EventBus 會使用一個單一線程的后臺線程池來調用該方法。適合執行輕量級后臺操作
      • ThreadMode.ASYNC: 在獨立的、非主線程、非發布者線程調用。EventBus 使用一個線程池來調用這些方法。適合執行耗時操作(如網絡請求、數據庫大查詢),不會阻塞發布線程或主線程。
    • sticky (可選,默認 false): 是否處理粘性事件 (Sticky Event)。如果設為 true,那么即使事件是在該訂閱者注冊之前發布的,只要該粘性事件還在總線上,訂閱者注冊后會立即收到該事件的最新一次發布。非常適用于需要獲取“最新狀態”的場景(如當前登錄用戶信息、網絡狀態)。
// 示例1:在主線程處理 MessageEvent
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {// 安全更新UItextView.setText(event.message);
}// 示例2:在后臺線程處理 DataLoadedEvent
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void handleDataLoaded(DataLoadedEvent event) {// 處理數據,比如保存到數據庫(輕量級操作)saveDataToDatabase(event.data);
}// 示例3:處理粘性事件 UserLoggedInEvent
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onUserLoggedIn(UserLoggedInEvent event) {// 更新UI顯示當前登錄用戶信息updateUserProfile(event.user);
}

4. 發布事件 (Publisher)

在任何需要通知其他組件的地方(任何類中),獲取 EventBus 實例并調用 post(Object event) 方法。event 對象就是你要傳遞的事件實例。

// 在某個按鈕點擊事件或網絡請求回調中
public void someMethodThatTriggersEvent() {// 創建事件對象MessageEvent event = new MessageEvent("Hello EventBus!");// 發布事件到總線EventBus.getDefault().post(event);
}// 發布粘性事件 (會一直保留在總線上直到被覆蓋或手動移除)
public void postStickyEvent() {UserLoggedInEvent event = new UserLoggedInEvent(currentUser);EventBus.getDefault().postSticky(event);
}

5. 處理粘性事件 (Sticky Events) 的額外操作

  • 獲取最新粘性事件: 使用 EventBus.getStickyEvent(Class<T> eventType) 可以在訂閱者注冊前或任何地方手動獲取特定類型的最新粘性事件。
  • 移除粘性事件: 使用 EventBus.removeStickyEvent(T event)EventBus.removeStickyEvent(Class<T> eventType) 手動移除粘性事件。
// 在注冊訂閱者之前,檢查是否有最新的登錄信息
UserLoggedInEvent stickyEvent = EventBus.getDefault().getStickyEvent(UserLoggedInEvent.class);
if (stickyEvent != null) {// 立即使用最新用戶信息更新UI或狀態updateUserProfile(stickyEvent.user);
}

6. 事件繼承

EventBus 支持事件繼承。如果一個訂閱者訂閱了父類事件類型(如 BaseEvent),那么當發布者發布任何該父類的子類事件(如 SpecificEvent extends BaseEvent)時,該訂閱者也會接收到通知。這可以用于創建更通用的事件處理器。

7. 優先級 (priority)

@Subscribe 注解中可以設置 priority 屬性(整數,默認 0)。數值越大,優先級越高。優先級高的訂閱者方法會在優先級低的之前接收到事件。如果優先級相同,順序不確定。注意: 只有在同一個 ThreadMode 下,優先級才生效。優先級通常用于攔截或修改事件(高優先級訂閱者可以調用 EventBus.cancelEventDelivery(event) 來阻止事件繼續傳遞給低優先級訂閱者)。

@Subscribe(threadMode = ThreadMode.MAIN, priority = 1)
public void onHighPriorityEvent(MyEvent event) {// 高優先級處理if (shouldCancel(event)) {EventBus.getDefault().cancelEventDelivery(event); // 取消事件傳遞}
}

8. 混淆配置 (Proguard/R8)

如果使用代碼混淆,需要在 Proguard 規則文件 (proguard-rules.pro) 中添加以下配置,以確保 @Subscribe 注解方法在運行時能被正確找到(如果使用索引加速則可能不需要,但加上更保險):

-keepattributes *Annotation*
-keepclassmembers class * {@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# 如果使用了索引加速 (EventBusAnnotationProcessor)
-keep class org.greenrobot.eventbus.** { *; }

9. 索引加速 (EventBusAnnotationProcessor) - 推薦

EventBus 3 引入了索引加速,在編譯時通過 APT (Annotation Processing Tool) 生成一個索引類,列出所有 @Subscribe 方法及其信息(事件類型、線程模式、優先級等)。這避免了在 App 首次運行時使用反射掃描所有類查找訂閱方法,大大提高了注冊速度和啟動性能,并減少了運行時方法查找的開銷。

啟用步驟:

  1. 添加注解處理器依賴:

    dependencies {implementation 'org.greenrobot:eventbus:3.3.1'annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.3.1' // 與 eventbus 版本一致
    }
    
  2. 配置索引選項 (可選但推薦): 在 app 模塊的 build.gradle 中指定生成的索引類名:

    android {defaultConfig {javaCompileOptions {annotationProcessorOptions {arguments = [ eventBusIndex : 'com.yourpackage.MyEventBusIndex' ]}}}
    }
    
  3. 在 Application 中設置索引: 在自定義 Application 類的 onCreate() 中配置 EventBus 使用生成的索引:

    public class MyApp extends Application {@Overridepublic void onCreate() {super.onCreate();// 使用索引構建 EventBus 實例 (替代默認反射查找)EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();// 現在 EventBus.getDefault() 已經使用了索引}
    }
    

    或者在需要使用 EventBus 的地方手動創建帶索引的實例:

    EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();
    

二、 應用場景

EventBus 特別適合解決以下通信難題:

  1. Fragment 間通信: 兩個 Fragment 之間沒有直接引用。Fragment A 發布事件,Fragment B 訂閱并處理。比通過 Activity 中轉或接口回調更簡潔。
  2. Activity 與 Service 通信: Service 后臺完成任務(如下載完成、播放狀態改變)后發布事件,Activity 訂閱并更新UI。
  3. 后臺線程與 UI 線程通信: 在后臺線程(如網絡請求、數據庫操作)中完成任務后發布事件,訂閱者指定 ThreadMode.MAIN 安全更新UI。
  4. 跨層通信: 深度嵌套的組件(如 Adapter 中的 ViewHolder)需要通知頂層的 Activity 或 Fragment 執行某些操作(如打開新界面)。
  5. 廣播全局狀態變化: 用戶登錄/登出、網絡連接狀態變化、語言切換、主題更改等全局狀態變更。使用粘性事件尤其方便,新啟動的組件能立即獲取最新狀態。
  6. 替代部分 Intent/BroadcastReceiver: 對于應用內部通信,EventBus 比系統廣播更輕量、更快速、類型更安全(避免 Intent 的 key 字符串硬編碼)。
  7. 解耦業務邏輯與 UI 更新: 業務邏輯模塊(如 Presenter, ViewModel, Interactor)處理完邏輯后發布事件,UI 層(Activity/Fragment)訂閱事件并只負責展示,實現更好的關注點分離。
  8. 組件化/模塊化通信: 不同模塊之間通過定義和發布/訂閱公共事件接口進行通信,減少模塊間的直接依賴。

三、 底層原理 (深入解析)

EventBus 的核心在于高效地管理訂閱關系和在正確線程上派發事件。以下是其核心機制:

  1. 訂閱者注冊 (register(Object subscriber)):

    • 方法查找 (運行時 / 編譯時):
      • 運行時 (默認,無索引): 使用反射遍歷 subscriber 對象的所有方法,查找所有被 @Subscribe 注解標記的公共方法。提取方法參數類型(即訂閱的事件類型)、ThreadMode、優先級、是否粘性等信息。
      • 編譯時 (使用索引): 編譯期間 EventBusAnnotationProcessor 掃描所有類,找出所有 @Subscribe 方法,生成一個索引類(如 MyEventBusIndex)。注冊時直接從這個索引類中查找 subscriber 的類名對應的所有訂閱方法信息,避免了耗時的運行時反射掃描
    • 構建訂閱關系映射: EventBus 內部維護一個核心數據結構:Map<Class<?>, CopyOnWriteArrayList<Subscription>>
      • Key (Class<?>): 事件類型(event.getClass())。
      • Value (CopyOnWriteArrayList<Subscription>): 一個線程安全的列表,存儲了所有訂閱了該事件類型的 Subscription 對象。
      • Subscription 對象封裝了:訂閱者對象 (subscriber)、訂閱者方法 (SubscriberMethod - 包含方法對象、ThreadMode、優先級、是否粘性)。
    • 對于找到的每個訂閱方法,根據其訂閱的事件類型,將封裝好的 Subscription 對象添加到上述映射表中對應事件類型的列表中。列表根據 Subscription 的優先級(priority)排序。
  2. 事件發布 (post(Object event)):

    • 獲取當前線程狀態: post() 方法首先獲取當前線程的 PostingThreadState 對象(一個 ThreadLocal 變量)。PostingThreadState 包含:
      • eventQueue:當前線程待處理的事件隊列。
      • isPosting:標識當前是否正在派發事件。
      • isMainThread:標識當前線程是否是主線程。
      • subscription:當前正在處理的事件對應的訂閱信息(用于 cancelEventDelivery)。
    • 入隊: 將傳入的 event 對象加入到當前線程的 eventQueue 中。
    • 事件派發循環: 如果當前線程不在派發過程中 (!isPosting),則開始處理隊列:
      • 設置 isPosting = true
      • 循環從隊列頭部取出事件。
      • 調用 postSingleEvent(event, postingState) 處理單個事件。
      • 處理完隊列所有事件后,重置狀態 isPosting = false
  3. 單個事件處理 (postSingleEvent):

    • 查找訂閱者: 根據事件的運行時類 (event.getClass()),從訂閱關系映射表中查找對應的 Subscription 列表。
    • 處理事件繼承 (可選): 如果啟用了事件繼承(默認啟用),還會查找該事件類的所有父類和接口對應的訂閱者列表,并將所有找到的訂閱者合并到一個總的列表中(去重)。
    • 遍歷訂閱者并派發 (postToSubscription): 對于找到的每一個 Subscription
      • 檢查訂閱者是否已注銷(弱引用失效)。
      • 根據 ThreadMode 決定執行方式:
        • POSTING直接調用。在當前發布線程直接通過反射(或 MethodHandle)調用訂閱者方法。最快,但需注意線程安全。
        • MAIN / MAIN_ORDERED
          • 如果當前是主線程:直接調用(MAIN_ORDERED 會確保按入隊順序)。
          • 如果當前不是主線程:將調用包裝成一個 Runnable,通過 mainThreadPoster(通常是 HandlerPoster,它內部持有一個關聯到主線程 Looper 的 Handler)發送到主線程的消息隊列中排隊執行。
        • BACKGROUND
          • 如果當前不是主線程:直接調用(在當前后臺線程)。
          • 如果當前是主線程:將調用包裝成 Runnable,通過 backgroundPoster(通常是 BackgroundPoster,它內部使用一個單線程的線程池 ExecutorService)提交到后臺線程執行。
        • ASYNC總是將調用包裝成 Runnable,通過 asyncPoster(通常是 AsyncPoster,它內部使用一個通用的線程池 ExecutorService)提交執行,與發布線程和當前線程無關。
      • 優先級處理: 在同一個 ThreadMode 下,列表已經按優先級排序,高優先級的 Subscription 會先被處理。高優先級訂閱者可以通過 cancelEventDelivery(event) 取消事件,阻止后續低優先級訂閱者收到該事件。cancelEventDelivery 只能在 POSTING 模式下調用,因為它需要直接操作當前派發流程。
  4. 粘性事件 (postSticky(Object event)):

    • 存儲: EventBus 內部維護一個 Map<Class<?>, Object> 用于存儲粘性事件。Key 是事件類型,Value 是該類型最新的粘性事件對象。發布粘性事件時,會先更新這個 Map(覆蓋舊事件)。
    • 發布: 然后像普通事件一樣調用 post(event) 進行派發。
    • 新訂閱者處理: 當一個新的訂閱者調用 register() 時,如果它聲明了 sticky=true 的事件處理方法:
      • 注冊過程完成后,EventBus 會檢查粘性事件 Map。
      • 對于該訂閱者每個聲明為 sticky=true 的事件類型,從 Map 中取出最新的粘性事件(如果存在)。
      • 然后按照正常的派發邏輯(根據 ThreadMode)調用該訂閱者的對應方法,就好像這個事件剛剛發布一樣。
  5. 注銷 (unregister(Object subscriber)):

    • 遍歷內部訂閱關系映射表 (Map<Class<?>, CopyOnWriteArrayList<Subscription>>)。
    • 對于每個事件類型的訂閱者列表,移除所有 subscription.subscriber 等于傳入的 subscriberSubscription 對象。
    • 移除后,該訂閱者對象將不再接收任何事件。
  6. 線程安全:

    • 核心數據結構 Map<Class<?>, CopyOnWriteArrayList<Subscription>> 使用 ConcurrentHashMap 或其變體保證鍵的并發訪問安全。CopyOnWriteArrayList 保證了單個事件類型訂閱者列表的線程安全(讀無鎖,寫復制)。
    • 使用 ThreadLocal (PostingThreadState) 管理每個線程的派發狀態。
    • 不同 ThreadMode 的派發器 (HandlerPoster, BackgroundPoster, AsyncPoster) 內部使用隊列和鎖/Handler/線程池來保證任務的有序執行和線程安全。
    • 注冊/注銷操作通常是同步的(內部有鎖),應盡量在主線程或確保線程安全的環境下調用。

關鍵優化點:

  • 索引加速: 極大提升注冊速度,避免首次運行時反射掃描。
  • CopyOnWriteArrayList: 讀多寫少場景(事件派發是高頻讀,注冊/注銷是相對低頻寫)性能好,讀操作完全無鎖。
  • 線程局部變量 (PostingThreadState): 高效管理每個線程的事件隊列和派發狀態。
  • 按需線程切換: 只在需要時才將任務派發到其他線程(通過 Handler 或 Executor)。
  • 弱引用: Subscription 持有訂閱者對象的弱引用 (WeakReference)。這非常重要!它確保如果訂閱者對象(如 Activity)被垃圾回收(例如用戶關閉了 Activity 但忘記調用 unregister()),Subscription 中的弱引用會自動失效。EventBus 在派發事件時會檢查弱引用是否有效,無效則跳過或移除該 Subscription,從而自動防止了因忘記注銷而導致的內存泄漏。這是 EventBus 設計中的一個關鍵安全機制。(注意:雖然弱引用提供了保護,但最佳實踐仍是顯式 unregister() 以保持代碼清晰和及時釋放資源)。

總結:

EventBus 通過高效的發布/訂閱機制、強大的線程模式支持、粘性事件特性以及底層精心的設計(映射表、ThreadLocal、弱引用、線程池/Handler),為 Android 開發提供了一種極其便捷、靈活且相對安全的組件間通信方式。它特別擅長解耦跨組件、跨線程的通信需求。理解其底層原理(尤其是訂閱關系管理、線程派發邏輯和弱引用機制)對于正確、高效地使用 EventBus 至關重要。務必遵循注冊/注銷的生命周期管理,合理選擇 ThreadMode,并在大型項目中使用索引加速以獲得最佳性能。

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

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

相關文章

初等數論簡明教程

初等數論簡明教程 本文給出初等數論中的一些重要的定理與例題&#xff0c;證明風格采用 整除線法 與 命題節點法。 整除線法 指推理的第 nnn 步左邊的字符可由前面左邊的字符得到&#xff0c;右邊的字符可由前面右邊的字符得到&#xff0c;整除線變成了推理線&#xff0c;既少…

Spring之核心容器(IoC,DI,基本操作)詳解

Spring之核心容器IoC/DI/基本操作詳解一、核心概念&#xff1a;IoC與DI的本質1.1 IoC&#xff08;Inversion of Control&#xff0c;控制反轉&#xff09;傳統開發模式&#xff08;無IoC&#xff09;IoC模式&#xff08;Spring容器管理&#xff09;1.2 DI&#xff08;Dependenc…

【論文閱讀】基于注意力機制的冥想腦電分類識別研究(2025)

基于注意力機制的冥想腦電分類識別研究&#x1f4a1; Meta DataTitle基于注意力機制的冥想腦電分類識別研究Authors周梓涵Pub. date2025&#x1f4dc; Research Background & Objective背景&#xff1a; 現代生活壓力導致心理問題日益突出&#xff0c;冥想作為一種有效的心…

GitHub 上 Star 數量前 8 的開源 Web 應用項目

原文鏈接&#xff1a;https://www.nocobase.com/cn/blog/github-open-source-web-applications。 近期&#xff0c;我們發布了多篇「Top GitHub Star 開源項目推薦」系列文章&#xff0c;受到了大量點贊與收藏&#xff0c;很多開發者留言表示希望能看到更多不同領域的開源工具推…

FATFS文件系統原理及其移植詳解

一、FATFS簡介 FATFS 是一個完全免費開源的 FAT/exFAT 文件系統模塊&#xff0c;專門為小型的嵌入式系統而設計。它完全用標準 C 語言&#xff08;ANSI C C89&#xff09;編寫&#xff0c;所以具有良好的硬件平臺獨立性&#xff0c;只需做簡單的修改就可以移植到 8051、PIC、A…

KubeRay 和 Ray

KubeRay 和 Ray 不是替代關系&#xff0c;而是互補的協作關系。兩者在分布式計算生態中扮演不同角色&#xff0c;共同構成完整的云原生 AI 解決方案。以下是具體分析&#xff1a;&#x1f527; 1. 核心定位差異Ray 是分布式計算引擎&#xff0c;提供底層 API&#xff08;如 ray…

破解輪胎倉儲高密度與柔性管理難題

輪胎作為特殊的大件異形工業品&#xff0c;其倉儲管理長期面臨多重挑戰&#xff1a;規格型號繁雜導致SKU數量龐大&#xff0c;重型載重對貨架承重提出極高要求&#xff0c;橡膠材質對防壓變形、避光防老化等存儲環境存在嚴苛標準。傳統平置堆垛或普通貨架方案不僅空間利用率不足…

EVA series系列(上)

目錄 一、EVA 1、概述 2、方法 二、EVA-02 1、概述 2、架構 三、EVA-CLIP 1、概述 2、方法 四、EMU 1、概述 2、架構 3、訓練細節 4、評估 一、EVA 1、概述 為探尋大規模表征學習任務的MIM預訓練任務在ViT基礎上擴展到1B參數量規模&#xff0c;結合10M級別&am…

ABP VNext + EF Core 二級緩存:提升查詢性能

ABP VNext EF Core 二級緩存&#xff1a;提升查詢性能 &#x1f680; &#x1f4da; 目錄ABP VNext EF Core 二級緩存&#xff1a;提升查詢性能 &#x1f680;引言 &#x1f680;一、環境與依賴 &#x1f6e0;?二、集成步驟 ??2.1 安裝 NuGet 包2.2 注冊緩存服務與攔截器2…

3.1k star!推薦一款開源基于AI實現的瀏覽器自動化插件工具 !

大家好&#xff01;今天&#xff0c;我要給大家介紹一款超實用的開源工具——Chrome MCP Server&#xff01;這款工具不僅能大幅提升我們的工作效率&#xff0c;還能讓AI助手&#xff08;如Claude&#xff09;直接操控瀏覽器&#xff0c;實現自動化操作、內容分析等強大功能。 …

關于 OpenAI 的反思

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

Python爬蟲庫性能與選型對比

Python常用爬蟲庫的優勢對比。這是一個非常實用的問題&#xff0c;很多Python開發者都會面臨選擇合適爬蟲工具的困惑。我根據網絡很多搜索結果&#xff0c;整理出這些信息&#xff0c;為用戶提供一個全面且清晰的對比分析。以下是Python中常用爬蟲庫的核心優勢對比及選型建議&a…

NAT作業

拓撲圖 實驗要求 1.按照圖示配置IP地址&#xff0c;公網地址100.1.1.1/24..較網“說過?,使“掩入到互聯網&#xff0c;私服究的不到公的&#xff0c;使陽接入無三。.私網A通過NAPT&#xff0c;使R1接入到互聯網&#xff0c;私網B通過EASY,IP&#xff0c;使R3接入到互聯網實驗思…

JAVA進階--JVM

一.JVM的概述java語言有跨平臺特點, 寫一次java程序,可以在不同的平臺上運行.(JVM虛擬機的作用)前提條件: 在不同的平臺上安裝不同的虛擬機(虛擬機就是一個翻譯).java--->.class--->不同的虛擬機--->機器碼1.jvm作用:負責將字節碼翻譯為機器碼, 管理運行時內存2.jvm的…

基于Alpine構建MySQL鏡像

文章目錄基于Alpine構建MySQL鏡像一、基礎鏡像選擇與初始化1. 基礎鏡像選型2. 系統初始化二、核心配置構建1. 目錄與權限配置2. 配置文件優化三、安全增強配置1. 密碼策略強化2. 非root運行四、數據持久化與啟動配置1. 數據卷聲明2. 入口腳本優化五、完整Dockerfile示例六、關鍵…

Alamofire 網絡請求全流解析,通俗易懂

Alamofire 網絡請求全流程解析&#xff1a;從發起請求到處理響應 一、請求發起階段&#xff1a;準備你的"快遞" 1. 你告訴Alamofire要發什么"快遞" // 就像告訴快遞員&#xff1a;"我要寄一個包裹給https://api.example.com" AF.request("h…

鏈路聚合技術

鏈路聚合技術 鏈路聚合概述及應用場景 概述 鏈路聚合是把多條物理鏈路聚合在一起&#xff0c;形成一條邏輯鏈路。應用在交換機、路由器、服務器間鏈路&#xff0c;注意了&#xff0c;主機上面不能用鏈路聚合技術分為三層鏈路聚合和二層鏈路聚合鏈路聚合的作用 增加鏈路帶寬提供…

SpringCloud之Zuul

SpringCloud之Zuul 推薦參考&#xff1a;https://www.springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul 1. 什么是Zuul Spring Cloud Zuul 是 Netflix 提供的微服務網關核心組件&#xff0c;作為統一的 API 入口&#xff0c;承擔請求路由、過濾、安全控制等…

低精度定時器 (timer_list) 和 高精度定時器 (hrtimer)

Linux 內核提供了兩種主要類型的定時器&#xff0c;以滿足不同的時間精度需求&#xff1a;低精度定時器 (timer_list) 和 高精度定時器 (hrtimer)。它們各有特點和適用場景。下面&#xff0c;我將分別提供它們在內核代碼中的簡化使用示例。1. 低精度定時器 (timer_list) 示例ti…

虛擬機VMware的使用方法

虛擬機VMware的使用方法VMware是全球領先的虛擬化技術提供商&#xff0c;其產品&#xff08;如VMware Workstation Pro&#xff09;允許用戶在單一物理機上運行多個操作系統&#xff08;OS&#xff09;&#xff0c;實現資源高效利用、隔離測試和靈活部署。本文將詳細介紹VMware…