【Redis】Redis 數據存儲原理和結構

一、Redis 存儲結構

1.1 KV結構

  • Redis 本質上是一個 Key-Value(鍵值對,KV)數據庫,在它豐富多樣的數據結構底層,都基于一種統一的鍵值對存儲結構來進行數據的管理和操作

  • Redis 使用一個全局的哈希表來管理所有的鍵值對,這個哈希表就像是一個大字典,通過鍵(Key)能快速定位到對應的值(Value)。

  • 從用戶視角看,用戶使用各種命令操作不同類型的數據結構(如 String、Hash、List 等),但從底層實現角度,它們都是以鍵值對形式存儲在這個哈希表中。

  • Redis的存儲分類的目的是,在數據量小的時候,追求存儲效率高;在數據量大的時候,追求運行速度快。

在這里插入圖片描述

數據類型(Value 所屬類型)編碼方式觸發條件
stringint字符串長度 ≤ 20 且可轉換為整數(如 "123"
embstr字符串長度 ≤ 44
raw字符串長度 > 44
cpu 緩存行優化(補充邏輯,基于緩存行 64 字節設計,輔助提升訪問效率,非獨立編碼類型)
listquicklistRedis 3.2+ 默認實現,是 ziplist + 雙向鏈表的混合結構(動態適配數據量)
ziplist數據量小時被 quicklist 間接使用(緊湊存儲小列表)
hashziplist節點數量 ≤ 512(hash-max-ziplist-entries)且字符串長度 ≤ 64(hash-max-ziplist-value
dict節點數量 > 512 或字符串長度 > 64
setintset元素全為整數且數量 ≤ 512(set-max-intset-entries
dict元素含非整數或數量 > 512
zsetziplist子節點數量 ≤ 128(zset-max-ziplist-entries)且字符串長度 ≤ 64(zset-max-ziplist-value
skiplist子節點數量 > 128 或字符串長度 > 64

1.2 字典(dict)

Redis 中的字典(dict) 是一種高效的鍵值對存儲結構,廣泛用于實現 Redis 核心的 KV 存儲(全局鍵值對)以及 Hash 類型在數據量較大時的底層存儲(當 Hash 節點數>512 或字符串長度>64 時)。其設計借鑒了哈希表的思想,通過鏈地址法處理沖突,并支持動態擴容(重哈希)以保證性能

字典數據結構組成

字典由三個核心結構體組成,層層嵌套實現哈希表的功能:

1. dictEntry哈希表節點

存儲單個鍵值對(key-value),next 指針用于連接哈希沖突的節點(形成鏈表)

typedef struct dictEntry {void *key;                  // 鍵(字符串類型)union {                     // 值(支持多種類型)void *val;              // 指針類型(如復雜數據結構)uint64_t u64;           // 無符號整數int64_t s64;            // 有符號整數double d;               // 浮點數} v;struct dictEntry *next;     // 下一個節點指針(處理哈希沖突的鏈表)
} dictEntry;
2. dictht 哈希表

管理哈希表數組,table 是存放 dictEntry 指針的數組,sizemask 用于快速計算鍵的索引(替代取余運算)。

typedef struct dictht {dictEntry **table;          // 哈希表數組(存儲dictEntry指針)unsigned long size;         // 數組長度(必須是2的冪,如4、8、16...)unsigned long sizemask;     // 掩碼,值為 size-1(用于計算數組索引)unsigned long used;         // 已存儲的節點數量(key-value總數)
} dictht;
3. dict字典頂層結構

通過 ht[2] 支持漸進式重哈希(避免一次性擴容的性能波動),rehashidx 跟蹤重哈希進度。

typedef struct dict {dictType *type;             // 字典類型(包含哈希函數、鍵值復制/釋放函數等)void *privdata;             // 私有數據(供type中的函數使用)dictht ht[2];               // 兩個哈希表(ht[0]:當前使用;ht[1]:重哈希時使用)long rehashidx;             // 重哈希索引(-1表示未進行重哈希;≥0表示當前遷移進度)int16_t pauserehash;        // 重哈希暫停標記(>0表示暫停,避免遍歷期間干擾)
} dict;

在這里插入圖片描述

哈希運算與索引映射

字典通過哈希函數將 key 映射到哈希表數組的索引,步驟如下:

  1. 計算哈希值:對 key(字符串)執行哈希函數(如 siphash),得到一個 64 位整數哈希值。

    • 特性:相同 key 必然得到相同哈希值(確定性);不同 key 可能得到相同哈希值(哈希沖突)。
  2. 映射到數組索引:利用 sizemasksize-1)對哈希值進行位運算(哈希值 & sizemask),得到數組索引。

    • 示例:若 size=4(2 的冪),則 sizemask=3(二進制 11)。哈希值 5(二進制 101)與 3 做 & 運算,結果為 1(二進制 01),即索引為 1。

    • 優勢:位運算(&)比取余運算(%)效率更高,且當 size 是 2 的冪時,哈希值 % size 等價于 哈希值 & sizemask

哈希沖突的處理

由于哈希值范圍(64 位)遠大于哈希表數組長度(size),根據抽屜原理(n+1 個蘋果放入 n 個抽屜,至少一個抽屜有 2 個),必然存在不同 key 映射到同一索引的情況(哈希沖突)。

字典采用鏈地址法解決沖突:

  • 每個 dictEntry 節點通過 next 指針形成單向鏈表,同一索引的所有沖突節點串聯在鏈表中。
  • 查找時:先通過索引定位到鏈表頭,再遍歷鏈表比較 key 以找到目標節點(時間復雜度:理想 O (1),沖突嚴重時 O (n))。

漸進式重哈希(擴容 / 縮容)

當哈希表的負載因子used / size)過高(擴容)或過低(縮容)時,需要調整數組大小以優化性能:

  • 擴容觸發:負載因子>1(默認),size 擴大為當前的 2 倍(仍為 2 的冪)。
  • 縮容觸發:負載因子<0.1,size 縮小為大于 used 的最小 2 的冪。
    在這里插入圖片描述

在這里插入圖片描述

為避免一次性遷移所有節點導致的性能阻塞,字典采用漸進式重哈希

  1. 初始化:創建 ht[1] 并設置新 size(如擴容為 ht[0].size * 2),rehashidx 設為 0(開始重哈希)。

  2. 漸進式遷移

    • 每次對字典執行增刪改查時,順帶將 ht[0]rehashidx 索引的所有節點遷移到 ht[1],并將 rehashidx 遞增 1。
    • 遍歷操作(如 HGETALL)時,會暫停重哈希(pauserehash 標記),避免遍歷期間節點遷移導致數據不一致。
  3. 完成遷移:當 ht[0].used 變為 0 時,釋放 ht[0],將 ht[1] 賦值給 ht[0]ht[1] 重置為空,rehashidx 設為 - 1(重哈希結束)。

scan

Redis 的 scan 命令是用于漸進式遍歷集合類數據(如鍵空間、哈希表、集合等)的命令,主要解決了 keys 命令因一次性全量遍歷導致服務器阻塞的問題

實現目標

  • 實現對 scan 開始時刻已存在的數據 進行遍歷,保證 不重復、不遺漏
  • 不阻塞服務器,通過分批次、漸進式的方式遍歷,每次返回部分結果,避免一次性處理大量數據導致的性能波動。

遍歷機制

  • 遍歷順序:采用 高位進位加法 的遍歷順序。這種方式的優勢是,在哈希表發生擴容 / 縮容(rehash)時,新舊哈希表的槽位在遍歷順序上是相鄰的,確保遍歷過程能適配哈希表結構的動態變化,維持遍歷的連續性。
  • 游標機制:通過游標(cursor)記錄每次遍歷的位置。首次調用時游標為 0,每次返回部分元素和新游標,當游標為 0 時表示遍歷結束。

在這里插入圖片描述

  • Redis 的哈希表(如字典)會因數據量變化發生擴容或縮容(rehash),導致鍵的映射算法(槽位計算方式)改變。
  • 借助 高位進位加法 的遍歷順序,即使 rehash 過程中映射關系變化,scan 仍能正確遍歷 scan 開始時已存在的數據,不會因 rehash 導致重復或遺漏。

1.3 Expire 機制

Redis 的 expire 機制用于管理設置了過期時間的鍵(key),通過兩種核心策略結合,在 “內存占用” 與 “性能消耗” 之間平衡,確保過期鍵能被及時清理

1. 惰性刪除(Lazy Expiration)
  • 觸發時機:當執行任何涉及該 key 的命令(如 GETSET 等)時,Redis 會先檢查 key 是否過期。

  • 執行邏輯

    • 若 key 已過期,立即刪除該 key,再執行后續命令;
    • 若未過期,直接執行命令。
  • 特點

    • 優勢:“按需刪除”,不占用額外 CPU 資源(僅在訪問時檢查);
    • 劣勢:若過期 key 長期未被訪問,會占用內存(內存泄漏風險)。
  • 適用范圍:僅支持對最外層 key 設置過期時間(如 Hash、List 等結構的內部字段無法單獨設置過期時間)。

  • 相關命令

    • expire key seconds:設置 key 的過期時間(秒);
    • pexpire key milliseconds:設置 key 的過期時間(毫秒);
    • ttl key:返回 key 剩余過期時間(秒,-1 表示永不過期,-2 表示已過期);
    • pttl key:返回 key 剩余過期時間(毫秒)。
2. 定時刪除(Active Expiration)

為彌補惰性刪除的內存泄漏問題,Redis 同時采用定時刪除策略,主動清理部分過期 key。

  • 觸發機制:由后臺定時器定期執行,每次檢查一定數量的過期 key。

  • 核心配置與邏輯

    • 默認每次檢查 25 個 key(由 ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP 定義);
    • 可通過 effort 參數調整檢查強度(默認 1,最大 10),計算公式為:config_keys_per_loop = 20 + 20/4*effort(effort 越大,每次檢查的 key 越多);
    • 執行函數 activeExpireCycleTryExpire 負責具體的過期檢查與刪除。
    #define ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP 20 /*
    Keys for each DB loop. */
    /*The default effort is 1, and the maximum
    configurable effort* is 10. */
    config_keys_per_loop =
    ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP +ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP/4*effort,
    int activeExpireCycleTryExpire(redisDb *db,
    dictEntry *de, long long now);
    
  • 特點

    • 優勢:主動清理長期未訪問的過期 key,減少內存占用;
    • 劣勢:若檢查過于頻繁,會消耗 CPU 資源(Redis 通過控制檢查頻率和數量避免性能波動)。

惰性刪除保證 “訪問時過期鍵必被清理”,避免無效數據干擾;定時刪除主動清理 “長期未訪問的過期鍵”,防止內存溢出。兩者結合,既保證了性能,又控制了內存占用

1.4 大Key

“大 Key” 指 Redis 中存儲的體積過大的對象(如包含數萬字段的 Hash、百萬元素的 ZSet 等),這類 key 會導致明顯的性能問題

1. 大 Key 的危害

  • 擴容卡頓:大 Key 所在的哈希表或數據結構(如 Hash、ZSet)擴容時,需要一次性申請大量內存(如從 1MB 擴容到 2MB),可能導致 Redis 短暫阻塞;
  • 刪除卡頓:刪除大 Key 時,Redis 需要一次性釋放大量內存,觸發內存回收機制,同樣會導致卡頓;
  • 內存波動:大 Key 的創建 / 刪除會導致 Redis 內存使用 “大起大落”,容易觸發內存告警或 OOM(內存溢出)。

大Key 的檢測

通過 Redis 自帶的 redis-cli --bigkeys 命令檢測大 Key,該命令基于 SCAN 遍歷所有鍵,統計不同類型中體積最大的鍵。

redis-cli -h 127.0.0.1 --bigkeys -i 0.1
  • --bigkeys:開啟大 Key 檢測;
  • -i 0.1:每執行 100 條 SCAN 命令后,暫停 0.1 秒,避免檢測過程阻塞 Redis 服務。

解決方案

  • 拆分大 Key:將大 Hash 拆分為多個小 Hash,大 ZSet 按范圍拆分為多個小 ZSet;
  • 避免批量操作:對大 Key 避免使用 HGETALLZRANGE 0 -1 等全量查詢命令;
  • 異步刪除:Redis 4.0+ 支持 UNLINK 命令(異步刪除),替代 DEL,減少刪除時的卡頓。

1.5 跳表

Redis 中的跳表(Skiplist)是一種多層級有序鏈表結構,主要用于實現有序集合(ZSet),支持高效的范圍查詢(如 ZRANGEZREVRANGE)和排序操作。其設計兼顧了查詢性能與實現復雜度,通過 “空間換時間” 的思路,在保證平均時間復雜度接近平衡樹的同時,避免了復雜的節點分裂 / 重構操作

在這里插入圖片描述

為什么使用跳表?

跳表的誕生是為了解決 “有序集合的高效查詢與修改” 問題:

  • 有序數組通過二分查找可實現 O (logN) 查詢,但插入 / 刪除需移動元素(O (N) 復雜度);

  • 平衡二叉樹(如 B+ 樹)可實現 O (logN) 操作,但節點分裂 / 合并邏輯復雜,不適合 Redis 對 “簡單高效” 的需求;

  • 跳表通過多層級鏈表模擬 “跳躍式查詢”,兼顧查詢效率(接近 O (logN))和實現簡單性(插入 / 刪除無需復雜重構),成為 ZSet 的理想底層結構。

跳表時間復雜度分析

  1. 理想跳表的邏輯
    理想情況下,跳表每間隔一個節點生成一個 “高層級節點”,模擬二叉樹結構(如第 1 層每 2 個節點有 1 個高層節點,第 2 層每 4 個節點有 1 個高層節點),此時查詢時間復雜度為 O(logN)。但這種結構在插入 / 刪除后難以維護(重構成本極高)。

  2. 概率化跳表(實際實現)
    為避免重構,跳表采用概率化層級生成

    • 每個新節點有 25%(Redis 中為 ZSKIPLIST_P=0.25)的概率增加 1 個層級,25%×25% 的概率增加 2 個層級,以此類推(最高層級有限制)。
    • 當數據量足夠大(如 ≥128)時,概率化生成的跳表結構趨向于理想跳表,查詢、插入、刪除的平均時間復雜度仍為 O(logN),且無需復雜重構。

在這里插入圖片描述

跳表的實現

  • 最高層級ZSKIPLIST_MAXLEVEL=32(足夠支持 2^64 個元素),避免層級過高導致的內存浪費。
  • 層級概率ZSKIPLIST_P=0.25(1/4),即每個節點晉升到下一層的概率為 25%,平衡層級數量與內存占用。

Redis 跳表通過 zskiplistNode(節點)和 zskiplist(跳表頂層結構)實現,配合 zset 結構體與字典(dict)協同工作

// 跳表節點
typedef struct zskiplistNode {sds ele;               // 元素值(字符串)double score;          // 排序分數(僅支持浮點數)struct zskiplistNode *backward; // 后退指針(用于反向遍歷)struct zskiplistLevel {struct zskiplistNode *forward; // 前進指針(當前層級的下一個節點)unsigned long span;            // 跨度(當前節點到下一個節點的元素數量,用于計算排名 ZRANK)} level[];             // 動態層級數組(長度為節點實際層級)
} zskiplistNode;// 跳表頂層結構
typedef struct zskiplist {struct zskiplistNode *header, *tail; // 頭節點、尾節點unsigned long length;                // 元素總數(對應 ZCARD 命令)int level;                           // 當前跳表的最高層級
} zskiplist;// ZSet 結構體(結合跳表與字典)
typedef struct zset {dict *dict;            // 字典:key=元素值,value=分數(快速查詢元素分數)zskiplist *zsl;        // 跳表:按分數排序,支持范圍查詢
} zset;

在這里插入圖片描述

更多資料:https://github.com/0voice

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

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

相關文章

【RAG優化】深度剖析OCR錯誤,從根源修復RAG應用的識別問題

1. 引言:OCR——RAG系統中的關鍵問題 當我們將一個包含掃描頁面的PDF或一張報告截圖扔給RAG系統時,我們期望它能“讀懂”里面的內容。這個“讀懂”的第一步,就是OCR。然而,OCR過程并非100%準確,它受到圖像質量、文字布局、字體、語言等多種因素的影響。 一個看似微不足道…

【第六節】方法與事件處理器

方法與事件處理器 方法處理器 可以用 v-on 指令監聽 DOM 事件: <div id="example"> <button v-on:click="greet">Greet</button></div>綁定一個單擊事件處理器到一個方法 greet 。下面在 Vue 實例中定義這個方法 var vm=new V…

大語言模型Claude 4簡介

Anthropic公司成立于2021年&#xff0c;由一群OpenAI前員工組成。他們最新發布的大語言模型(Large Language Model, LLM) Claude 4系列包括兩個版本&#xff1a;Claude Opus 4和Claude Sonnet 4&#xff1a;(1).Claude Sonnet 4&#xff1a;是Claude Sonnet 3.7的升級&#xff…

國產化PDF處理控件Spire.PDF教程:Python 將 PDF 轉換為 Markdown (含批量轉換示例)

PDF 是數字文檔管理的普遍格式&#xff0c;但其固定布局特性限制了在需要靈活編輯、更新或現代工作流集成場景下的應用。相比之下&#xff0c;Markdown&#xff08;.md&#xff09;語法輕量、易讀&#xff0c;非常適合網頁發布、文檔編寫和版本控制。 E-iceblue旗下Spire系列產…

PDF轉Markdown - Python 實現方案與代碼

PDF作為廣泛使用的文檔格式&#xff0c;轉換為輕量級標記語言Markdown后&#xff0c;可無縫集成到技術文檔、博客平臺和版本控制系統中&#xff0c;提高內容的可編輯性和可訪問性。本文將詳細介紹如何使用國產Spire.PDF for Python 庫將 PDF 文檔轉換為 Markdown 格式。 技術優…

深度解析 inaSpeechSegmenter:高效音頻語音分割與檢測開源工具

項目簡介 inaSpeechSegmenter 是法國國家視聽研究院(INA)開源的音頻分割與檢測工具,專為廣播、播客、采訪、影視等多媒體內容的自動化處理設計。它能夠高效地將長音頻自動分割為語音、音樂、噪聲、靜音等片段,并支持性別檢測(男聲/女聲),為后續的語音識別、內容檢索、轉…

VirtualBox安裝Ubuntu 22.04后終端無法打開的解決方案

問題現象在VirtualBox中使用"快速安裝"模式安裝Ubuntu 22.04后圖形終端&#xff08;gnome-terminal&#xff09;無法通過圖標或快捷鍵(CtrlAltT)啟動系統其他功能正常根本原因語言環境(Locale)配置異常導致&#xff1a;快速安裝模式可能跳過Locale生成步驟gnome-term…

java磁盤操作與IO流(序列化、Properties類)

目錄 一、磁盤操作 1、File類&#xff1a; &#xff08;1&#xff09;創建File對象&#xff1a; &#xff08;2&#xff09;獲取文件信息&#xff1a; &#xff08;3&#xff09;判斷文件 &#xff08;4&#xff09;刪除文件 &#xff08;5&#xff09;創建文件&#xff…

【WPF】WPF Prism 開發經驗總結:菜單命令刪除項時報 InvalidCastException 的問題分析與解決

WPF Prism 開發經驗總結&#xff1a;菜單命令刪除項時報 InvalidCastException 的問題分析與解決 在 WPF Prism 項目中使用 ContextMenu 執行刪除操作時&#xff0c;遇到一個令人疑惑的問題&#xff1a;命令綁定本身沒有問題&#xff0c;但點擊“刪除”菜單后&#xff0c;程序拋…

《WebGL打造高性能3D粒子特效系統:從0到1的技術探秘》

在游戲里,爆炸時四濺的火花、魔法釋放時閃爍的光暈;在可視化項目中,數據流動時呈現的璀璨光河,這些令人驚嘆的效果,背后離不開強大的技術支撐。而WebGL,作為在瀏覽器端實現硬件加速3D圖形渲染的技術,為我們開啟了構建高性能3D粒子特效系統的大門。 WebGL的渲染管線是整…

全國計算機等級考試二級題庫【C語言】:程序填空題型——結構體 自制答案詳解合輯

二級C語言程序填空題型簡介 1、/**********found**********/緊跟的下面一行的程序設空,一般為3個空; 2、常見錯誤: (1) (2) 3、做題推薦步驟: (1) (2) ---------------一、結構體--------------- 2、題目要求【結構體】 程序通過定義學生結構體變量,存儲了學生…

人工智能與城市:城市生活的集成智能

1. 智慧城市的核心價值&#xff1a;從 “硬件堆砌” 到 “智能協同”1.1 傳統城市的治理困境全球 55% 的人口居住在城市&#xff0c;到 2050 年這一比例將升至 68%。傳統城市管理面臨多重挑戰&#xff1a;資源分配失衡&#xff1a;早晚高峰主干道擁堵率達 80%&#xff0c;而支線…

Linux下掛載磁盤報superblock錯誤

Linux下掛載磁盤報superblock錯誤背景問題現象1、使用fdisk查詢設備文件信息2、掛載磁盤&#xff0c;報出fs type錯誤解決辦法1、使用e2fsk命令檢查整個磁盤2、resize2fs 命令調整文件系統塊大小和物理磁盤塊大小3、掛載磁盤&#xff0c;確認修復結果問題思考1、rclone命令做數…

Http證書體系及證書加密流程(通信流程)

一、HTTPS 證書體系&#xff1a;信任的基石 HTTPS 證書體系是保障網絡通信安全的核心機制&#xff0c;其本質是一套基于公鑰基礎設施&#xff08;PKI&#xff0c;Public Key Infrastructure&#xff09; 的信任體系&#xff0c;通過數字證書實現通信雙方的身份驗證和數據加密&…

【分布式架構】學習路徑概述:了解分布式系統的核心問題、解決方案與實戰說明

文章目錄零、前言一、分布式系統理論1、 分布式系統的一致性問題1.1、一致性問題理論&#xff08;CAP/BASE&#xff09;1.2、 一致性協議與算法&#xff08;Paxos/Raft&#xff09;&#xff1a;選主、分布式鎖1.3、 分布式事務(2PC\3PC\TCC)&#xff1a;服務一致性保障與性能2、…

C# 密封類_密封方法 (seadled 關鍵字)

C#允許將類聲明為密封類&#xff0c;密封類不能被繼承在什么場景用&#xff1f;答&#xff1a;防止重寫某些類導致代碼混亂密封類seadled 聲明密封類的關鍵字//seadled 聲明密封類的關鍵字 //密封類不能被繼承 sealed class Class1 {public int age;public string name;publi…

深度學習(魚書)day04--手寫數字識別項目實戰

深度學習&#xff08;魚書&#xff09;day04–手寫數字識別項目實戰 魚書的相關源代碼下載&#xff1a; 點擊鏈接&#xff1a;http://www.ituring.com.cn/book/1921 點擊“隨書下載” 第三項就是源代碼&#xff1a; 解壓后&#xff0c;在pycharm&#xff08;或其它IDE&#…

【自用】NLP算法面經(6)

一、FlashAttention 1、Tile-Based計算 將q,k,v分塊為小塊&#xff0c;每次僅處理一小塊&#xff1a; 利用gpu的片上SRAM完成QK^T和softmax避免中間結果寫入HBM 標準attention的計算算法如下&#xff1a;標準attention實現大量中間結果需要頻繁訪問HBM&#xff0c;而HBM的訪問速…

Vue頁面卡頓優化:從理論到實戰的全面解釋

目錄 1. 理解Vue頁面卡頓的幕后黑手 1.1 響應式系統的“雙刃劍” 1.2 虛擬DOM的“隱藏成本” 1.3 瀏覽器渲染的“性能陷阱” 實戰案例:一個“罪魁禍首”的排查 2. 優化響應式系統:讓數據“輕裝上陣” 2.1 使用v-if和v-show控制渲染 2.2 凍結靜態數據 2.3 精細化響應式…

從0開始學linux韋東山教程Linux驅動入門實驗班(6)

本人從0開始學習linux&#xff0c;使用的是韋東山的教程&#xff0c;在跟著課程學習的情況下的所遇到的問題的總結,理論雖枯燥但是是基礎。本人將前幾章的內容大致學完之后&#xff0c;考慮到后續驅動方面得更多的開始實操&#xff0c;后續的內容將以韋東山教程Linux驅動入門實…