CCFRec-人大高瓴-KDD2025-序列推薦中充分融合協同信息與語義信息

文章目錄

  • 1. 背景與問題
  • 2. 方法
    • 2.1 多視圖 sid
    • 2.2 Code-Guided Semantic Fusion
      • 核心創新:
      • 常規操作:
    • 2.3 Enhanced Representation Learning via Code Masking
      • 2.3.1 Masked Code Modeling (MCM)
      • 2.3.2 Masked Sequence Alignment (MSA)
    • 2.4 復雜度分析
      • 2.4.1 訓練階段(Training)
        • SFM部分
        • SR部分
        • 總體訓練復雜度
      • 2.4.2 部署階段(Deployment)
  • 3. 實驗
    • 3.1 主實驗
    • 3.2 消融實驗
    • 3.3 codebook 層數
    • 3.4 不同 sid
    • 3.5 加 item id
  • 4. 總結

這里記錄一下人民大學高瓴學院-KDD2025的一篇關于語義與協同對齊的文章:《Bridging Textual-Collaborative Gap through Semantic Codes for Sequential Recommendation》

論文鏈接:https://arxiv.org/abs/2503.12183

代碼鏈接:https://github.com/RUCAIBox/CCFRec?tab=readme-ov-file

1. 背景與問題

序列推薦任務下,主流做法都是側重于 ID 協同過濾(只看用戶和商品的 ID,忽略內容),可以很好的捕捉用戶和商品間的互動關系,但現代平臺的商品文本內容(標題、品牌、描述)極為豐富,這些信息能更精準刻畫商品本身,也有助于解決冷啟動問題。

近年來有一些方法把文本信息和 ID 信息拼接或加權,但常常導致兩種信息融合不自然,要么太依賴文本,忽略協同關系,要么文本利用不足,丟失語義信息。

在這里插入圖片描述

本文關注如何在序列推薦任務中,通過更智能的語義融合機制,把商品文本信息和用戶行為序列的信息深度結合起來,讓推薦系統既懂“內容”又懂“行為”。

本文提出 CCFRec 通過 sid(semantic id)作為橋梁,sid 有兩個重要特征

  1. 可以理解為特殊 id,每個 id 有自己的可學習 embedding,可以像傳統 id 那樣建模協同語義。
  2. 每個 item 可以有多組 sid(每個 item 多個特征如:標題、品牌、類別,每個特征一組 sid,代碼中搞了 5 套),能反應不同層次的內容語義,讓相似內容的 item 自動貼近(同 RPG 文章中提到的,如果有幾位相同的 sid 這兩個 item 就比較相似)。

本兩個創新目標

  1. 用 sid 指導模型,靈活地從文本信息中抽取對推薦有用的部分,不會死板地全部用文本。
  2. 讓商品的最終表示既有內容信息,又有協同信息,讓推薦系統更精確。

2. 方法

在這里插入圖片描述

2.1 多視圖 sid

這里思想特別簡單(有點大力出奇跡的意思),就是將每個 item 的多種屬性,論文代碼中是 5 種(title,brand,features,categories,description),經過 embedding model 得到對應的 embedding,然后搞多套 sid

對比之前的方法都是將每個 item 的所有屬性拼成一句話經過 embedding model,這樣更細致了。最后將每個屬性的 sid 拼在一起,組層一個大 sid 表。(每個屬性 20 層 pq/rq 的 codebook,拼在一起 100 層)

每個商品有多個文本屬性(如title、brand、features、categories、description):

  • Step 1:文本編碼
    用預訓練模型分別將每個屬性編碼為文本embedding向量:
    zit=PLM(ai),i∈{1,...,m}z_i^t = \text{PLM}(a_i), i \in \{1,...,m\} zit?=PLM(ai?),i{1,...,m}

  • Step 2:向量量化成sid
    對每個屬性的文本embedding,用向量量化技術(PQ或RQ)轉為多層語義碼sid
    zit→(c1i,...,cki)z_i^t \rightarrow (c_1^i,...,c_k^i) zit?(c1i?,...,cki?)
    比如用了5個屬性,每個屬性20個sid,則每個商品就有5×20=100個sid。

2.2 Code-Guided Semantic Fusion

在這里插入圖片描述

核心創新:

這是其實比較新穎的一個點就是將經過 embedding model 得到的 embedding 作為 K/V 去增強 embedding 質量。

這個模塊是本文最核心的創新

輸入兩類embedding:

  • 屬性embedding Zt=[z1t,...,zmt]Z^t=[z_1^t,...,z_m^t]Zt=[z1t?,...,zmt?](內容信息)
  • 語義碼embedding Zc=[z1c,...,zncc]Z^c=[z_1^c,...,z_{n_c}^c]Zc=[z1c?,...,znc?c?](協同信息)

這個模塊由多層Transformer-like結構組成,每層包括:

  • Self-Attention層
    語義碼之間相互融合:
    H~l=MHA(Hl?1,Hl?1,Hl?1)\tilde{H}^l = \text{MHA}(H^{l-1},H^{l-1},H^{l-1}) H~l=MHA(Hl?1,Hl?1,Hl?1)

  • Cross-Attention層
    以語義碼embedding 為 query,以文本屬性 embedding 為 key 和 value,主動抽取有用的文本信息:
    Hl=FFN(MHA(H~l,Zt,Zt))H^l = \text{FFN}\left(\text{MHA}\left(\tilde{H}^l,Z^t,Z^t\right)\right) Hl=FFN(MHA(H~l,Zt,Zt))

  • 最終得到商品融合表示:

    • 先池化獲得整體表示:e=Pool(H)e=\text{Pool}(H)e=Pool(H)

    • 再加一個殘差連接保留原始sid信息:
      e~=e+Pool(Zc)\tilde{e}=e+\text{Pool}(Z^c) e~=e+Pool(Zc)

通過上述模塊,每個商品得到了高質量的語義融合向量 e~\tilde{e}e~

常規操作:

  • 將用戶歷史序列商品的融合embedding拼成序列,加位置編碼,輸入Transformer網絡:
    h^i0=e~i+pi\hat{h}_i^0=\tilde{e}_i+p_i h^i0?=e~i?+pi?

  • Transformer多層建模序列行為關系,得到最后一層隱藏狀態:
    H^l=FFN(MHA(H^l?1,H^l?1,H^l?1))\hat{H}^l=\text{FFN}\left(\text{MHA}\left(\hat{H}^{l-1},\hat{H}^{l-1},\hat{H}^{l-1}\right)\right) H^l=FFN(MHA(H^l?1,H^l?1,H^l?1))

  • 最后一個位置的隱藏向量表示用戶當前興趣:
    r=H^L[?1]r=\hat{H}^L[-1] r=H^L[?1]

損失

用戶表示 rrr 與下一個點擊商品embedding e~n+1\tilde{e}_{n+1}e~n+1? 相似度最大,負樣本相似度最小。 用Cross-Entropy損失:
LCE=?log?exp?(g(r,e~n+1)/τ)∑j∈Bexp?(g(r,e~j)/τ)\mathcal{L}_{CE}=-\log\frac{\exp\left(g(r,\tilde{e}_{n+1})/\tau\right)}{\sum_{j\in\mathcal{B}}\exp\left(g(r,\tilde{e}_j)/\tau\right)} LCE?=?logjB?exp(g(r,e~j?)/τ)exp(g(r,e~n+1?)/τ)?

  • 其中,B\mathcal{B}B是正負樣本集合,τ\tauτ是溫度系數,ggg是余弦相似度。

2.3 Enhanced Representation Learning via Code Masking

作者提出通過額外的兩個訓練任務(基于掩碼策略)增強模型的表示學習能力,分別是:

  • Masked Code Modeling (MCM, 掩碼語義碼建模)
  • Masked Sequence Alignment (MSA, 掩碼序列對齊)

在這里插入圖片描述

2.3.1 Masked Code Modeling (MCM)

  1. 核心思想

受自然語言處理中 BERT 模型的啟發(通過掩碼語言建模MLM學習文本表示),這里對語義碼序列進行隨機掩碼,訓練模型去恢復被掩蓋的語義碼,以促進語義碼和文本信息更好地融合

  1. 具體做法
  • 每個商品擁有一個語義碼序列:
    sc=(c1,c2,...,cnc)s^c = (c_1, c_2, ..., c_{n_c}) sc=(c1?,c2?,...,cnc??)

  • 隨機將一定比例 ρ\rhoρ 的語義碼掩蓋 (如 [MASK][MASK][MASK] ),得到掩蓋后的序列:
    s^c=(c1,...,[MASK],...,cnc)\hat{s}^c = (c_1, ..., [MASK], ..., c_{n_c}) s^c=(c1?,...,[MASK],...,cnc??)

  • 語義融合模塊(SFM)接收到這個掩蓋序列,要利用文本embedding和未掩蓋的碼,推測出被掩蓋的碼。

  1. 損失函數

預測的目標是讓模型給掩蓋位置預測正確的語義碼:
LMCM=1∣Mc∣∑x∈Mc?log?exp?(g(h^x,zxc)/τ)∑j∈Cexp?(g(h^x,zjc)/τ)\mathcal{L}_{\text{MCM}} = \frac{1}{|\mathcal{M}^c|}\sum_{x\in\mathcal{M}^c}-\log\frac{\exp(g(\hat{h}_x,z_x^c)/\tau)}{\sum_{j\in C}\exp(g(\hat{h}_x,z_j^c)/\tau)} LMCM?=Mc1?xMc??logjC?exp(g(h^x?,zjc?)/τ)exp(g(h^x?,zxc?)/τ)?

  • 其中:
    • Mc\mathcal{M}^cMc 為掩蓋位置的集合。
    • g(h^x,zxc)g(\hat{h}_x,z_x^c)g(h^x?,zxc?) 為預測表示(通過融合模塊輸出的隱藏向量h^x\hat{h}_xh^x?)和真實碼embedding zxcz_x^czxc? 的余弦相似度。
    • 分母上的集合 CCC 表示所有語義碼集合,作為分類的類別。
    • τ\tauτ 是溫度系數,用于softmax平滑。
  1. 作用與優勢
  • 增強語義碼之間的關聯性
  • 提高文本embedding與語義碼之間的對齊能力。

2.3.2 Masked Sequence Alignment (MSA)

  1. 核心思想

這個任務用來增強推薦主干網絡的序列建模能力,通過掩蓋部分語義碼產生數據增強(data augmentation),再進行對比學習(Contrastive Learning),提升模型對于序列建模的穩健性

  1. 具體做法
  • 同樣對輸入商品序列的語義碼隨機掩蓋部分碼,獲得掩蓋后的序列。
  • 掩蓋序列經過語義融合模塊(SFM)得到增強版的商品表示(augmented item representation)。
  • 將增強版的序列與原始序列分別輸入到推薦主干網絡,得到兩種用戶序列表示:
    • 原始表示 rrr(未掩蓋序列)
    • 增強表示 r^\hat{r}r^(掩蓋序列)
  • 希望相同序列的原始和增強版表示更相似,不同序列的表示更不同。
  1. 損失函數(公式7、8):

采用 InfoNCE 對比損失:
LMSA=12(InfoNCE(r^,r,Br)+InfoNCE(r,r^,Br^))\mathcal{L}_{\text{MSA}} = \frac{1}{2}\bigl(\text{InfoNCE}(\hat{r}, r, \mathcal{B}_r) + \text{InfoNCE}(r, \hat{r}, \mathcal{B}_{\hat{r}})\bigr) LMSA?=21?(InfoNCE(r^,r,Br?)+InfoNCE(r,r^,Br^?))
其中 InfoNCE定義為:
InfoNCE(x,y+,Ry)=?log?exp?(g(x,y+)/τ)∑y∈Ryexp?(g(x,y)/τ)\text{InfoNCE}(x, y^+, \mathcal{R}_y) = -\log\frac{\exp(g(x,y^+)/\tau)}{\sum_{y\in\mathcal{R}_y}\exp(g(x,y)/\tau)} InfoNCE(x,y+,Ry?)=?logyRy??exp(g(x,y)/τ)exp(g(x,y+)/τ)?

  • (x,y+)(x,y^+)(x,y+) 表示一對正樣本(即來自同一用戶序列的原始表示與增強表示)。
  • 集合 Ry\mathcal{R}_yRy? 包含了正樣本和批次內其他序列(負樣本)的表示。
  • 目的是拉近同序列表示(正樣本),拉開不同序列表示(負樣本)。
  1. 作用與優勢:
  • 增加訓練數據多樣性,有效提升模型對用戶序列的泛化能力和穩健性。

最后,綜合起來三個優化目標(推薦預測損失、掩碼語義碼損失、掩碼序列對齊損失),整體訓練目標為:
L=LCE+αLMCM+βLMSA\mathcal{L} = \mathcal{L}_{CE} + \alpha\mathcal{L}_{MCM} + \beta\mathcal{L}_{MSA} L=LCE?+αLMCM?+βLMSA?

  • LCE\mathcal{L}_{CE}LCE?:推薦任務損失(預測下一個商品)。
  • LMCM\mathcal{L}_{MCM}LMCM?:掩碼語義碼建模損失,優化SFM語義融合效果。
  • LMSA\mathcal{L}_{MSA}LMSA?:掩碼序列對齊損失,優化序列建模的穩健性。
  • α,β\alpha,\betaα,β 為超參數,調節不同任務的比重。

2.4 復雜度分析

2.4.1 訓練階段(Training)

CCFRec有兩個關鍵模塊:

  1. 語義融合模塊(SFM, Semantic-Fusion Module)
  2. 序列推薦主干(SR, Sequential Recommendation backbone),比如SASRec那樣的Transformer結構。
SFM部分
  • 在SFM中,主要有三種操作:自注意力層(Self-Attention)、跨融合層(Cross-Fusion)、前饋網絡(Feed-Forward)。
  • 對于單個item,計算復雜度分別是:
    • 自注意力層:O(M2d)
    • 跨融合層:O(MKd)
    • 前饋網絡:O(Md2)
  • 其中:
    • d 是模型的表示維度(embedding維度)
    • M 是語義code序列的長度
    • K 是屬性序列的長度
  • **綜合起來,得到一個item的SFM輸出的總體復雜度:**O(M2d + MKd + Md2)
SR部分
  • 主干SR一般用的是SASRec那種Transformer結構,主要消耗在自注意力層和前饋層。
  • 假設用戶行為序列長度為N,則總復雜度為:O(N2d + Nd2)
總體訓練復雜度
  • 將SFM和SR加在一起,并考慮 batch(多個item同時訓練),總訓練復雜度為:O(N2d + Nd2 + NM2d + NMKd + NMd2)
  • 這里N是用戶序列的長度,M和K是item屬性和code數量,d是embedding維度。
  • 重點:實際應用中,M 和 K 遠小于 N(通常N>50,M、K一般不超過20),所以額外的開銷是可以接受的

(代碼中我看到 M=100,K=20,額。。。不過工業界數據上確實也是 K 會更大)

2.4.2 部署階段(Deployment)

  • 部署時,為了提高效率,SFM模塊可以被去掉,因為訓練好的語義融合表示(item embedding)是固定的
  • 我們可以提前離線計算每個item的最終embedding(用SFM提前處理好,存下來),只用主干SR進行推理。
  • 這樣,線上推理時的復雜度與SASRec等主流序列推薦模型完全一樣,都是 O(N2d + Nd2)
  • 也就是說,部署階段CCFRec的推理速度不會比常見的序列推薦模型慢。

這里倒是沒問題。

3. 實驗

3.1 主實驗

在這里插入圖片描述

3.2 消融實驗

感覺這些消融有點沒到點上,看不出來那些是本文最重要的組件。也沒有整個去掉(1)(2)的,都是去掉很小的東西,然后微降效果

在這里插入圖片描述

3.3 codebook 層數

層數增加效果提升,這里還是有點 scaling-law 的意義:

在這里插入圖片描述

3.4 不同 sid

在這里插入圖片描述

這里得到比較有趣的現象:

Random code是無用但無害:模型會“忽略”它,不依賴它。

SASRec code是冗余且有害:模型會“重復利用”協同信息,導致空間浪費,降低性能。

3.5 加 item id

論文采取了一種 參數高效(parameter-efficient) 的方式,簡單來說就是在保持原有文本-語義表示的基礎上,再加上一份獨立的 item ID embedding,并且只訓練這部分參數,步驟如下:

  1. 先用原始的 CCFRec 進行預訓練,學習出每個物品的語義融合表示(只用文本+code)。
  2. 引入 item ID embedding lookup table:對每個物品,分配一個隨機初始化的可訓練 embedding(通常與語義表征等長,比如128維)。
  3. 凍結原有 CCFRec 所有參數,只訓練 ID embedding,即其他部分參數都不動,只讓 ID embedding 隨訓練迭代更新。
  4. 最終物品表示為
    • 最終表示 = 語義融合表示 + ID embedding
    • 兩者直接相加后,作為輸入傳遞給序列推薦器(如 Transformer/SASRec 等)。
  5. 繼續用推薦損失(如交叉熵)finetune,直到收斂。

原本 CCFRec 只用文本和對應的 semantic code(語義碼)來表達物品,不用傳統的 item ID embedding。這樣做的好處是更關注于文本的內容表達,便于泛化和冷啟動,但有個明顯的短板:無法表達“物品之間純 collaborative(協同過濾)信息”,即沒法捕捉到只有 ID 層面才有的微小區分。

在這里插入圖片描述

4. 總結

主要是對 item embedding 與 text embedding 融合的工作,感覺設計的十分復雜(復現的時候訓練相比于其他模型時間多太多),實驗整體感覺差點意思,消融做的沒看出哪些最關鍵組件,不過對于部署階段的復雜度分析倒是感覺算是合理,相當于增加了訓練階段的算力以及存儲,換準確度?

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

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

相關文章

Python深入 Tkinter 模塊

目錄 一、為什么要寫 Tkinter 二、最小可運行示例:Hello World 不是終點,而是起點 三、布局三板斧:pack、grid、place 四、事件與回調:讓按鈕“響”起來 五、實戰案例:秒表 文件批量重命名器 六、樣式進階&…

LeetCode 面試經典 150_數組/字符串_刪除有序數組中的重復項(3_26_C++_簡單)

LeetCode 面試經典 150_刪除有序數組中的重復項(3_26_C_簡單)題目描述:輸入輸出樣例:題解:解題思路:思路一(雙指針):代碼實現代碼實現(思路一(雙指…

架構篇(一):告別MVC/MVP,為何“組件化”是現代前端的唯一答案?

架構篇(一):告別MVC/MVP,為何“組件化”是現代前端的唯一答案? 引子:一個困擾前端工程師的“幽靈” 在上一章《序章:拋棄UI,我們來構建一個“看不見”的前端應用》中,我們從零開始構建了一個純…

數組內存學習

一、內存簡介:1.內存分為5塊:a.棧(Stack)主要運行方法,方法的運行都會進入棧內存運行,云南行完畢之后,需要“彈棧”,為了騰空間。b.堆(Heap)保存的是對象&…

驗證 GitHub Pages 的自定義域(Windows)

驗證 GitHub Pages 的自定義域 您可以通過驗證您的域來提高自定義域的安全性并避免接管攻擊。 誰可以使用此功能? GitHub Pages 在公共存儲庫中提供 GitHub Free 和 GitHub Free for organizations,在公共和私有存儲庫中提供 GitHub Pro、GitHub Team、GitHub Enterprise Cl…

數字化轉型 - 企業數字化建設的幾點思考

關于企業數字化建設的幾點思考工業軟件領軍人才的培訓課中,如上的一個PPT,給人以許多反思。一是看企業成功的數字化案例時,也許只看到別人面上的東西,可能還有面下很多看不到的東西支撐著,因此可能只看到或學到別人的皮…

深入解析Java內存模型:原理與并發優化實踐

深入解析Java內存模型:原理與并發優化實踐 技術背景與應用場景 隨著多核處理器的普及,Java并發編程已成為后端系統提升吞吐量與響應性能的必備手段。然而,在多線程環境下,不同線程對共享變量的可見性、指令重排以及內存屏障控制都…

《設計模式之禪》筆記摘錄 - 9.責任鏈模式

責任鏈模式的定義責任鏈模式定義如下:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.…

05-ES6

數據解構SetES6 提供了新的數據結構 Set。它類似于數組,但是成員的值都是唯一的,沒有重復的值Set 本身是一個構造函數,用來生成 Set 數據結構//set集合,成員是唯一的,添加過程中會替換相同的元素。這里相同的標準是const s new S…

正則表達式 \b:單詞邊界

下面舉例說明 \b 用法。\b(?:https?://)(\S)\b各部分功能:\b:單詞邊界,確保匹配的 URL 是獨立的單詞,不會與其他字符粘連。(?:https?://):非捕獲組,匹配 http:// 或 https://(s? 表示 s 可…

從8h到40min的極致并行優化:Spark小數據集UDTF處理的深度實踐與原理剖析

在大數據領域,Spark以其卓越的并行處理能力著稱。但面對小數據集的極致并行需求時,默認優化策略往往成為瓶頸。本文將深入剖析如何通過精準控制分區策略,將僅170條數據的表拆分成170個獨立Task并行執行,實現100%的并行度&#xff…

JAVA算法題練習day1

開始前: 選擇leetcode-hot100。要求每日1道,并且需要親自二刷昨天的題目(每一種解法),要做解題筆記并發布CSDN,做完立刻二刷。做題時間為每日12:50起,不拖延,這是學習成…

【Word Press進階】自定義區塊的行為與樣式

前兩篇 【Word Press基礎】創建自定義區塊【Word Press基礎】創建一個動態的自定義區塊 說明白了怎么創建一個簡單的靜態區塊。但實在是太丑了。這里再進行一個優化,讓咱們的區塊好看又好用。 一個合格的區塊應當有著好看的外表,完整的功能&#xff0…

Pygame模塊化實戰:火星救援游戲開發指南

Pygame模塊化實戰:火星救援游戲開發指南用Python打造太空探險游戲,掌握模塊化開發核心技巧一、火星救援:模塊化開發的完美場景??想象這樣的場景??: 你是一名宇航員,被困在火星表面,需要收集資源、修復飛…

三維圖像識別中OpenCV、PCL和Open3D結合的主要技術概念、部分示例

文章目錄1. 三維點云基礎概念點云(Point Cloud)深度圖像(Depth Image)體素(Voxel)2. 點云預處理技術去噪濾波(Noise Filtering)降采樣(Downsampling)3. 特征提取與描述法向量估計(Normal Estimation)關鍵點檢測(Keypoint Detection)特征描述子(Feature Descriptor)4. 點云配準(…

7.23數據結構——單鏈表

文章目錄一、思維導圖二、單鏈表代碼head.htext.cmain.c現象一、思維導圖 二、單鏈表代碼 head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdlib.h> #include <stdio.h> #include <string.h>enum A {FAULSE-1,//失敗返回SUCCESS//成功返回};//給…

某種物聯網SIM卡流量查詢方法

說起流量卡,很多人可能還停留在營業廳辦理的常規套餐里。但其實在 2016 年,三大運營商就推出了一種資費更為劃算的正規流量卡 —— 物聯卡。當年,當不少人還在用 50 元 1G 的流量時,第一批體驗物聯卡的用戶已經享受到了 53 元 6G 的全國流量,徹底擺脫了流量焦慮。不過,至…

XTTS實現語音克隆:精確控制音頻格式與生成流程【TTS的實戰指南】

言簡意賅的講解XTTS解決的痛點 &#x1f4ce; 前置操作&#xff1a;如何使用 OBS Studio 錄制高質量 WAV 語音&#xff08;建議先閱讀并準備錄音樣本&#xff09; 本教程介紹如何使用 Coqui TTS 的 XTTS v2 模型 實現中文語音克隆&#xff0c;支持直接傳入 .wav 文件&#xff0…

C/C++中常量放置在比較操作符左側

目錄 介紹 原因詳解 避免誤用賦值運算符 示例對比 結論 介紹 在編程中&#xff0c;將常量放在比較操作符&#xff08;如 或 !&#xff09;的左側&#xff08;例如 if (42 value)&#xff09;&#xff0c;是一種被稱為 "Yoda 條件"&#xff08;Yoda Conditions…

Node.js 模擬 Linux 環境

&#x1f9e9; 項目介紹 該項目使用 Node.js 實現了一個模擬的 Linux 終端環境&#xff0c;支持多種常見的 Linux 命令&#xff08;如 ls, cd, cat, mkdir, rm 等&#xff09;&#xff0c;所有文件操作都在內存中進行&#xff0c;并持久化到本地文件系統中。適合用于學習 Shel…