Android熱修復實現方案深度分析

熱修復的核心目標是在**不發布新版本、不重新安裝、不重啟應用(或僅輕量級重啟)**的情況下,修復線上應用的 Bug 或進行小范圍的功能更新,極大地提升用戶體驗和問題響應速度。

一、熱修復的核心原理

無論哪種方案,其核心思想都是繞過 Android 系統的安裝流程(APK 簽名驗證、Dex 優化、資源編譯等),在運行時動態修改或替換有問題的代碼、資源或 So 庫。主要涉及以下幾個關鍵技術點:

  1. 類加載機制 (ClassLoader):

    • Android 使用 PathClassLoader(主 APK)和 DexClassLoader(加載額外 Dex/Jar)來加載類。
    • 關鍵點在于 DexPathList 中的 dexElements 數組。類加載遵循雙親委托模型,當需要加載一個類時,會按順序遍歷 dexElements 數組中的 Dex 文件,直到找到目標類。
    • 熱修復原理: 將包含修復后類的 Dex 文件(補丁包)插入到 dexElements 數組的最前面。這樣,在加載目標類時,系統會先找到補丁 Dex 中的修復類并加載,從而覆蓋原 APK 中 bug 類的加載。這是大部分 Dex 替換方案(如 Tinker, QZone)的基礎。
  2. 資源修復:

    • Android 資源管理通過 AssetManagerResources 完成。每個 APK 在安裝時都會生成一個唯一的資源 ID (packageId) 和編譯后的資源表 (resources.arsc)。
    • 直接替換 resources.arsc 或資源文件通常不可行,因為 packageId 不匹配。
    • 熱修復原理:
      • 創建新 AssetManager: 創建一個新的 AssetManager 實例,先加載補丁資源包(通常是一個單獨的 APK 或資源壓縮包),然后再加載原 APK 的資源路徑。調用 AssetManager.addAssetPath(path)
      • 替換 Resources: 用這個新的 AssetManager 創建一個新的 Resources 實例,并替換掉 ApplicationActivityContext 持有的 Resources 引用(通過反射或接口方式)。
      • 資源 ID 沖突處理: 確保補丁包中的資源 ID 與主 APK 一致(通常在編譯補丁時通過固定資源 ID 或公共庫實現)。Sophix 采用了更復雜的運行時資源合并策略。
  3. So 庫修復:

    • 本地庫(.so)由 System.loadLibrary() 加載到進程的 Native 內存空間。
    • 直接覆蓋已加載的 So 庫非常困難,因為內存映射和符號綁定問題。
    • 熱修復原理:
      • 重啟后加載: 最穩妥的方式。將補丁 So 庫文件下載到應用私有目錄(如 libs),在應用下次啟動時(或輕量級重啟后),修改 java.library.path 或使用 DexClassLoader 的 Native 庫路徑參數,優先加載補丁目錄下的 So 庫。需要確保補丁 So 的 ABI 兼容性。
      • dlopen 替換 (高風險): 少數方案嘗試在運行時使用 dlopen 重新加載補丁 So 并替換函數指針(如 AndFix 的 Native 方法替換原理的延伸),但這極其復雜,兼容性極差,且容易導致崩潰,不被主流方案采用。

二、主流熱修復方案深度分析

以下是對幾種代表性方案的深度剖析,涵蓋原理、實現、優缺點及適用場景:

  1. Dex 插樁/類替換方案 (代表:QZone / Nuwa / 早期 Tinker 核心)

    • 原理: 利用類加載機制。
      • 在編譯時,通過字節碼插樁(Transform API / ASM)在所有類的構造函數或特定方法(如 Application.attachBaseContext)中插入一段對某個“空”工具類的引用(稱為“插樁類”)。
      • 線上出現 Bug 時,生成一個補丁 Dex。這個 Dex 包含兩個部分:1) 修復后的業務類; 2) 那個“空”工具類的真正實現類(其中包含加載補丁 Dex 的邏輯)。
      • 應用啟動時,默認加載的 APK 中只有“空”工具類的樁(Stub)。當代碼執行到引用該工具類的地方時,觸發類加載。
      • 在工具類的 <clinit>(類初始化)方法中,通過反射獲取 PathClassLoaderDexPathList 中的 dexElements 數組。
      • 將補丁 Dex 文件(已下載到本地)封裝成一個 Element 對象,并插入到 dexElements 數組的最前面
      • 后續加載任何類(包括修復類)時,都會優先從補丁 Dex 中查找。修復類成功覆蓋原類。
    • 優點:
      • 兼容性相對較好(主要依賴公開的類加載機制)。
      • 修復范圍廣(類級別)。
    • 缺點:
      • 性能損耗: 插樁增加了類數量和初始化開銷。應用啟動時插入補丁 Dex 的操作(反射、數組合并)也消耗時間。
      • CLASS_ISPREVERIFIED 問題 (Dalvik): 在 Dalvik 虛擬機(Android < 5.0)上,如果一個類在 dexopt 時被驗證為只引用了同一個 Dex 內的類,會被打上 CLASS_ISPREVERIFIED 標記。插樁導致工具類引用了主 Dex 外的類(補丁 Dex 里的修復類),違反此假設,導致 pre-verify 崩潰。需要通過防止類被打上 PREVERIFIED 標記的 Hack 解決(如讓所有類都引用一個獨立的幫助 Dex 中的類),進一步增加復雜性。
      • Art 兼容性問題: Art 采用 AOT 編譯,直接修改 dexElements 后,已 AOT 編譯的代碼可能不會被重新編譯執行,導致修復在某些情況下不生效(尤其涉及類結構變更時)。需要結合解釋執行或強制 deopt。
      • 補丁體積較大: 包含整個修改后的類文件。
    • 適用場景: 對啟動時間不敏感、需要兼容較老系統(尤其是 Dalvik)的應用。目前逐漸被更優方案取代。
  2. 底層替換方案 (代表:AndFix / Sophix 底層方法替換)

    • 原理: 直接修改虛擬機層的方法結構或 Native 指針。
      • AndFix: 主要針對 Dalvik。
        • Dalvik 中,Java 方法通過 Method 結構體表示,其中包含一個指向其實現的 insns 指針(指向 DEX 字節碼)和 accessFlags
        • AndFix 通過 JNI Native 代碼,找到目標方法(有 Bug 的方法)和補丁方法(修復后的方法)對應的底層 Method 結構體。
        • 直接將目標方法的 insns 指針替換為補丁方法的 insns 指針。同時可能需要修改 accessFlags 等屬性。
        • 后續調用該方法時,實際執行的是補丁方法的字節碼。
      • Sophix (方法級): 在 AndFix 思路上做了增強和兼容性處理,嘗試支持 Art。
        • Art 中方法結構更復雜(ArtMethod 對象),包含更多信息(JIT/Profiling 信息、入口點地址等)。
        • 替換 ArtMethod 的難度和風險更高。Sophix 采用了更謹慎的替換策略(如替換部分關鍵字段),并處理了 JIT 緩存等問題,但兼容性依然不如 Dex 替換方案完美。
    • 優點:
      • 即時生效: 無需重啟應用或 Activity,修復立刻生效(對用戶體驗最好)。
      • 補丁體積小: 只需包含修改的方法及其直接引用類(理論上)。
      • PREVERIFIED 問題: 不依賴類加載機制。
    • 缺點:
      • 兼容性差: 嚴重依賴虛擬機內部實現細節(Method/ArtMethod 結構)。不同 Android 版本、不同 OEM 廠商的 ROM 差異巨大,極易導致崩潰。Android 版本升級(尤其是 Art 的演進)經常導致方案失效。Sophix 也僅在其支持的特定版本上保證方法替換。
      • 修復范圍受限: 只能修改方法體內部邏輯。無法進行以下操作:
        • 增/刪/改字段 (Field)
        • 增/刪方法 (Method)
        • 增/刪/改類 (Class) 及其繼承關系、接口實現
        • 修改構造函數
        • 修改靜態初始化塊 (<clinit>)
      • 穩定性風險高: 直接操作運行時內存結構,風險極高。錯誤替換可能導致難以排查的崩潰或詭異行為。
    • 適用場景: 對即時性要求極高且修改內容嚴格限定為簡單方法體內部邏輯變更的場景(如緊急修復一個關鍵計算函數)。需嚴格測試目標 Android 版本。不推薦作為主要熱修復手段。
  3. 全量 Dex 替換方案 (代表:Tinker)

    • 原理: 比較新、舊 APK 的 Dex 文件差異(BSDiff 等算法),生成一個體積較小的差異補丁包(.patch 文件)。在客戶端,將補丁包與手機上的舊 APK 的 Base Dex 進行合并,重新生成一個完整的新 Dex 文件。然后利用類加載機制(類似方案1),用這個新 Dex 完全替換舊的 Base Dex(或多個 Dex)。
    • 優點:
      • 修復能力強大: 支持增/刪/改類、方法、字段、資源(需配合其資源修復模塊)、So 庫(需重啟)。功能最接近發布新版本。
      • 兼容性極佳: 核心是加載一個完整的新 Dex,不涉及底層 Hack,對 Android 版本和 ROM 兼容性好。
      • 穩定性高: 替換的是整個 Dex 單元,避免了底層替換的風險。
      • 社區活躍,文檔完善: 微信團隊開源,應用廣泛,社區支持好。
    • 缺點:
      • 需要重啟生效: 合并生成新 Dex 的操作通常在下次啟動時進行(冷啟動修復)。部分場景支持“溫重啟”(重啟部分組件,如非 ApplicationContentProvider)。
      • 補丁體積相對較大: 雖然用了差量,但改動較多時補丁仍可能較大(尤其涉及資源或大型 So 庫時)。比底層替換方案大,但比插樁方案只包含修改類的方式通常要小(因為插樁方案包含整個修改類,Tinker 的差量更細)。
      • 性能開銷 (合并過程): 在低端設備上,合并 Dex 文件的操作可能比較耗時,影響啟動速度(但只發生在打補丁后的第一次啟動)。
      • 磁盤空間占用: 需要在設備上存儲 Base APK 和合并后的新 Dex 文件。
    • 適用場景: 目前最主流、最推薦的方案。適用于絕大多數需要熱修復的場景,特別是修復范圍較大、涉及結構變更、對穩定性要求高的應用。
  4. 混合方案 / 綜合方案 (代表:阿里 Sophix - 非底層方法替換部分)

    • 原理: 并非單一技術,而是根據修復內容的類型(類、資源、So)和修復生效時間要求(即時、重啟),智能選擇最合適的技術組合
      • 類修復: 優先采用類似全量 Dex 替換的思路(可能優化了差量和加載過程),保證強大的修復能力和兼容性。放棄了高風險的即時底層方法替換作為主要手段(僅可能作為可選項或輔助)。
      • 資源修復: 采用成熟的 AssetManager 重建方案。Sophix 聲稱解決了不同 Android 版本(特別是 O 及以上)的資源修復兼容性問題,可能通過更精細的資源表 (resources.arsc) 合并或重建策略。
      • So 修復: 采用穩妥的重啟后加載補丁路徑 So 的方案。
      • 核心思想: 通過強大的后端服務和客戶端 SDK,在生成補丁階段就分析出最優的修復策略和最小補丁包;在客戶端應用階段根據設備環境選擇最安全可靠的加載方式。
    • 優點:
      • 功能全面: 一站式解決類、資源、So 修復。
      • 兼容性優秀: 規避了高風險技術,重點保證各模塊在主流系統上的兼容性。
      • 補丁生成優化: 可能結合多種差量算法和策略,生成更小的補丁包。
      • 部署靈活: 云端管控能力強。
    • 缺點:
      • 商業化方案: Sophix 是阿里云的商業化產品(有免費額度),非完全開源(核心代碼閉源)。
      • 需要重啟 (大部分情況): 類修復和 So 修復通常仍需重啟生效(類修復可能是輕量級重啟)。
      • 集成依賴: 需要依賴 Sophix SDK 及其后端服務。
    • 適用場景: 追求開箱即用、一站式解決方案、有商業化預算支持、對阿里云服務接受度高的團隊。特別適合大型復雜應用。
  5. Instant Run (Google 官方 / AS 內置)

    • 原理: 嚴格來說,Instant Run 是開發調試工具,并非面向生產環境的熱修復方案。但其部分技術(尤其是增量構建和熱/溫交換)啟發了熱修復。
      • 熱交換 (Hot Swap): 僅修改方法體內部邏輯 - 類似底層替換(但更安全,可能利用了 ART 的 Debugger 或 JVMTI 接口)。
      • 溫交換 (Warm Swap): 修改資源或修改了類結構(如增刪方法字段) - 需要重啟 Activity。
      • 冷交換 (Cold Swap): 涉及清單文件修改、繼承關系變更等 - 需要重啟應用。
    • 優點: 開發調試效率極高。
    • 缺點:
      • 僅限 Debug 模式: 嚴重依賴 IDE 和 Debug 環境,無法用于線上發布。
      • 穩定性/兼容性: 在復雜的項目或某些設備上可能不穩定。
    • 適用場景: 僅用于開發階段,加速編譯-部署-調試循環。

三、方案選擇的關鍵考量因素

  1. 修復范圍與能力:

    • 需要修復什么?簡單方法體 Bug?增刪字段/方法/類?修改資源?更新 So 庫?
    • Dex 替換 / 全量替換 / 混合方案 > 底層替換方案。
  2. 生效時間要求:

    • 是否需要即時生效(無感知)?是否可以接受重啟應用?是否可以接受重啟 Activity?
    • 底層替換 (即時) > 輕量級重啟 (部分混合方案可能支持) > 重啟 Activity (溫重啟) > 重啟應用 (冷啟動)。
  3. 穩定性與兼容性:

    • 對線上崩潰的容忍度?目標用戶的 Android 版本和機型分布?
    • 全量替換 / Dex 替換 / 混合方案 > 底層替換方案。
  4. 補丁包大小:

    • 用戶網絡環境?對下載速度的要求?
    • 底層替換 (最小) > 全量替換 (差量優化后) ≈ Dex 替換 (包含修改類) > 全量替換 (無優化) / Dex 替換 (包含過多類)。
  5. 性能影響:

    • 應用啟動時間敏感度?運行時性能損耗?
    • 底層替換 (運行時無感) > 全量替換 (首次合并耗時) > Dex 插樁 (類加載開銷)。
  6. 接入成本與生態:

    • 團隊技術棧?是否愿意/有能力維護自研方案?是否接受商業化方案?
    • 成熟開源方案 (Tinker) / 商業化方案 (Sophix) > 自研方案 (高成本,高風險)。
  7. 安全性:

    • 如何保證補丁包的來源合法性和完整性(簽名驗證)?如何防止補丁被篡改?
  8. 平臺政策 (Google Play):

    • 特別注意: Google Play 對非 Google 自身的代碼熱更新(特別是修改 DEX 字節碼的行為)有嚴格限制。使用熱修復可能導致應用被下架。國內市場和獨立分發渠道無此限制。

四、最佳實踐建議

  1. 首選成熟開源方案 (Tinker): 對于大多數團隊和應用,Tinker 是目前綜合最優的選擇:功能強大(類/資源/So)、兼容性好、穩定性高、社區活躍、文檔齊全。其需要重啟的缺點在大多數場景是可以接受的折衷。
  2. 考慮商業化方案 (Sophix): 如果追求更便捷的一站式服務(尤其資源修復兼容性聲稱更好)、有預算、且接受云服務依賴,Sophix 是一個省心的選擇。
  3. 謹慎使用底層替換 (AndFix / Robust): 僅建議在極其緊急修復內容嚴格符合限制(僅方法體內部邏輯)的場景下,作為臨時補救措施。務必進行充分測試。Robust 在底層替換基礎上做了改進(自動生成補丁類),但本質局限仍在。
  4. 避免使用過時的插樁方案: 如無特殊兼容性要求(如必須支持極老的 Dalvik 設備),不推薦使用純 Dex 插樁方案(Nuwa 等),因其性能和兼容性問題在現代設備上更突出。
  5. 明確區分開發與生產: 絕對不要將 Instant Run 用于線上熱修復。
  6. 重視測試: 建立完善的補丁測試流程,包括單元測試、自動化 UI 測試、Monkey 測試、覆蓋目標機型和系統版本的兼容性測試。熱修復本身的 Bug 可能導致更嚴重的線上問題。
  7. 灰度發布與監控: 熱修復補丁必須采用灰度發布策略。同時加強線上監控(崩潰率、ANR、關鍵指標),一旦發現補丁引入問題,能迅速回滾。
  8. 安全加固: 對補丁包進行簽名校驗,確保其完整性和來源可信。防止補丁被惡意篡改。
  9. 關注 Google Play 政策: 如果應用上架 Google Play,務必仔細閱讀并遵守其關于代碼更新的政策,避免違規。考慮使用 App Bundle 和 In-App Updates 等官方機制。

五、總結

Android 熱修復是一個涉及虛擬機機制、類加載、資源管理、Native 層的復雜技術。沒有完美的“銀彈”方案,選擇時需要根據應用的具體需求(修復范圍、生效時間、穩定性要求、性能、成本)進行權衡。

  • 追求強大修復能力、高穩定性、良好兼容性: Tinker (全量替換) 是當前開源首選。
  • 追求便捷、一站式服務、資源修復優化: Sophix (混合方案) 是優秀的商業化選擇。
  • 追求即時生效且愿意承擔高風險: Robust (改進的底層替換) 可作為特定場景下的補充(但非主力)。
  • 避免使用: 過時的插樁方案、高風險的純底層替換 (AndFix)、以及僅用于開發的 Instant Run。

無論選擇哪種方案,嚴格的測試、灰度發布和監控都是保障線上穩定性的關鍵。熱修復是強大的工具,但也需謹慎使用。

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

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

相關文章

HTML前端顏色漸變動畫完整指南

漸變動畫已經成為現代網頁設計中不可或缺的元素&#xff0c;它們不僅能為網站增添視覺吸引力&#xff0c;還能顯著提升用戶體驗。通過巧妙運用CSS漸變動畫&#xff0c;開發者可以創造出令人印象深刻的動態背景效果&#xff0c;而無需依賴圖片或復雜的腳本。 漸變動畫的魅力所在…

b-up:Enzo_mi:Transformer DETR系列

1.視頻1&#xff1a;self-Attention&#xff5c;自注意力機制 &#xff5c;位置編碼 &#xff5c; 理論 代碼 注意&#xff1a; q-查詢; k-商品標簽&#xff1b; v-值&#xff08;具體商品&#xff09; * 不是指乘法&#xff0c;類似概念 a1:相似度&#xff1b; b1:總分 若想…

算法題(179):單調棧

審題&#xff1a; 本題是單調棧的模板題 補充&#xff1a;單調棧 單調棧中的數據始終保持單調遞增或單調遞減 使用情景&#xff1a;給定一個數組&#xff0c;要求尋找 1.某個數左側&#xff0c;離他最近且值大于他的數 2.某個數左側&#xff0c;離他最近且值小于他的數 3.某個數…

CF每日5題(1500-1600)

545C 貪心 1500 題意&#xff1a;給 n 棵樹在一維數軸上的坐標 xix_ixi? &#xff0c;以及它們的長度 hih_ihi?。現在要你砍倒這些樹&#xff0c;樹可以向左倒也可以向右倒&#xff0c;砍倒的樹不能重合、當然也不能覆蓋其他的樹原來的位置&#xff0c;現在求最大可以砍倒的…

HW藍隊:天眼告警監測分析之Web攻擊

Web攻擊 信息泄露 敏感數據包括但不限于:口令、密鑰、證書、會話標識、License、隱私數據(如短消息的內容)、授權憑據、個人數據(如姓名、住址、電話等)等&#xff0c;在程序文件、配置文件、日志文件、備份文件及數據庫中都有可能包含敏感數據 信息收集方法 漏洞分類 備份文…

大騰智能國產3D CAD軟件正式上架華為云云商店

深圳市大騰信息技術有限公司&#xff08;以下簡稱“大騰智能”&#xff09;與華為云達成深度合作&#xff0c;大騰智能CAD軟件及配套服務通過了華為云在功能適配、安全可用、穩定高效等方面的嚴選商品認證&#xff0c;已正式上架華為云云商店&#xff0c;成為華為云云商店的聯營…

論文復現-windows電腦在pycharm中運行.sh文件

1.更改終端路徑&#xff08;前提&#xff1a;已下載git bash&#xff09;2.授權打開pycharm終端&#xff0c;輸入 chmod x 文件名3.根據當前位置&#xff0c;運行.sh文件

開關電源安全保護電路:浪涌保護、過流保護、過壓保護

開關電源安全保護電路:浪涌保護、過流保護、過壓保護 引言 對于開關電源而言, 安全、可靠性歷來被視為重要的性能之一. 開關電源在電氣技術指標滿足電子設備正常使用要求的條件下, 還要滿足外界或自身電路或負載電路出現故障的情況下也能安全可靠地工作. 為此, 須有多種保護措…

C語言(十)

一、函數概述函數是面向過程編程思想的具體體現&#xff0c;主要作用&#xff1a;降低程序之間的耦合性提高代碼的復用性和可維護性一個完整的 C 程序由**一個或多個程序模塊&#xff08;源文件&#xff09;**組成。為便于開發與調試&#xff0c;通常會將代碼拆分為多個源文件&…

QT項目-仿QQ音樂的音樂播放器(第二節)

目錄 自定義控件&#xff1a; BtForm類中實現 BtForm上的動畫效果 自定義控件&#xff1a; 該控件實際由&#xff1a;圖?、?字、動畫三部分組成。圖?和?字分別?QLabel展?&#xff0c;動畫部分內部實際為4 個QLabel。 ① 將BtForm的geometry的寬度和?度修改為200*35。…

【世紀龍科技】數字課程資源-新能源汽車概論

一、課程介紹本課程為通過項目任務式教學&#xff0c;全面系統的講解了新能源汽車的基礎知識及相關技能&#xff0c;培養和提高學生的動手能力和理論知識的工程應用能力。以典型工作任務帶動知識與技能的學習&#xff0c;采用項目教學培養學生的崗位技能、學習能力和職業素養。…

iOS Core Data 本地數據庫 使用詳解:從模型關系到數據操作

一、引言&#xff1a;Core Data&#xff0c;在本地數據持久化中的地位在 iOS 開發中&#xff0c;本地數據存儲幾乎是每一個 App 都繞不開的問題。無論是緩存用戶信息、離線瀏覽內容&#xff0c;還是記錄用戶操作歷史&#xff0c;一個合適的數據持久化方案都能大大提升應用的體驗…

Java-79 深入淺出 RPC Dubbo 動態路由架構詳解:從規則設計到上線系統集成

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持續更新中&#xff01;&#xff08;長期更新&#xff09; AI煉丹日志-30-新發布【1T 萬億】參數量大模型&#xff01;Kim…

Linux內核中動態內存分配函數解析

在C語言中&#xff0c;動態內存分配通常用于在運行時申請內存。在內核編程中&#xff0c;動態內存分配與用戶空間有所不同&#xff0c;因為內核需要更謹慎地處理內存&#xff0c;且不能使用用戶空間的庫&#xff08;如glibc&#xff09;。下面我們將詳細分析Linux內核中動態申請…

Next.js 中配置不同頁面布局方案

在 Next.js 應用中&#xff0c;你可以通過多種方式實現某些頁面全屏、某些頁面帶菜單/頁眉/頁腳的需求。以下是幾種實現方案&#xff1a; 方案一&#xff1a;使用多個布局組件 1. 創建不同的布局組件 // app/default-layout.tsx import Header from /components/header; import…

Spring Boot 使用外置 Servlet 容器:從配置到部署全指南

在 Spring Boot 開發中&#xff0c;我們通常使用嵌入式 Servlet 容器&#xff08;如 Tomcat&#xff09;&#xff0c;它能將應用打包成可執行 JAR&#xff0c;簡化部署流程。但在某些場景下&#xff08;如需要支持 JSP、復雜的容器定制或企業級部署規范&#xff09;&#xff0c…

借助AI學習開源代碼git0.7之九diff-files

借助AI學習開源代碼git0.7之九diff-files diff-files.c 是一個用于比較工作目錄中的文件和 Git 索引&#xff08;暫存區&#xff09;中文件的工具。 實質上&#xff0c;它是 git diff命令在不指定特定提交時功能的核心實現。 主要功能分析&#xff1a; 1. 核心功能 diff-files …

社區資源媒體管理系統設計與實現

社區資源媒體管理系統設計與實現 1. 系統概述 社區資源媒體管理系統是一個專為社區戶外廣告打造的高效、專業化平臺&#xff0c;旨在實現社區媒體的數字化管理、智能投放和便捷交易。該系統將整合社區各類廣告資源&#xff0c;為廣告主、物業公司和社區居民提供一站式服務。 1.…

12.1.6 weak_ptr

weak_ptr weak_ptr會指向一個share_ptr&#xff08;使用一個share_ptr來初始化weak_ptr&#xff09;&#xff0c;但并不會增加這個share_ptr的引用計數器&#xff0c;其析構也不會減少share_ptr的引用計數器。 構造函數及使用 #include <iostream> #include <memory&g…

深度分析Java內存模型

Java 內存模型&#xff08;Java Memory Model, JMM&#xff09;是 Java 并發編程的核心基石&#xff0c;它定義了多線程環境下線程如何與主內存&#xff08;Main Memory&#xff09;以及線程的本地內存&#xff08;工作內存&#xff0c;Working Memory&#xff09;交互的規則。…