程式設計基礎篇 · 線性結構:你天天在用
陣列:你聊的每句話都躺在裡面
上一課說好了:資料結構 = 收納方式。第一種收納方式你其實天天在餵它資料——你和 AI 的每一段對話,在程式眼裡就是一個 message list,而 message list 的真身,是最樸素的收納方式:一排編了號的格子,叫陣列。這一課先把你的對話攤開來看,再順手回答一個老疑問:為什麼聊久了它會忘事。
先玩 · 你的對話正躺在一排格子裡
下面就是一個 message list:每條訊息佔一個格子,格子上方是它的索引(編號,從 0 開始數——程式設計師的老習慣)。點「發一條訊息」,看新訊息落在哪;再拖「上下文視窗」滑塊,留意哪些格子變灰了、哪個格子永遠不灰。
system(📌 釘住)
user(你)
assistant(AI)
底下有藍條 = 在上下文視窗裡
這就是「聊久了忘事」的全部真相。模型一次能讀的內容有上限(上下文視窗),裝不下時就得扔。扔哪頭?掐頭不掐尾——最早的閒聊先扔,最近幾句必須留著,不然它連你剛說什麼都不知道。唯獨
[0] 號格子的 system 提示詞被釘住了:它是人設和規矩(「你是一位貼心的助理」),扔了它,AI 就忘了自己是誰。所以「忘事」不是玄學,就是陣列切片:留下 system + 最近 K 條,其餘不再送進模型。
第二局 · 往中間插一條,有多貴?
陣列的格子在記憶體裡是緊挨著排的,中間不許有空位。這帶來一個麻煩:想往中間塞一個新元素,右邊的所有元素都得挨個往右搬一格給它騰地方。點任意一個格子,在它的位置插入一顆 ⭐,盯著「搬動次數」;再點「在末尾追加」對比一下。
👇 點格子 = 在這個位置插入 ⭐(越靠左,右邊要搬家的越多)
搬動次數0次
先點一個靠左的格子試試,比如 [1]
看出規律了嗎?末尾追加永遠只要 1 步,中間插入要搬動一大片——格子越多、插得越靠前,搬得越狠。這就是為什麼對話歷史被設計成只往後長(append-only):每條新訊息 push 到末尾,誰也不搬家,快且省。你從來沒見過哪個聊天軟體讓你「把一句話插到十分鐘前」,不是產品經理沒想到,是這麼幹真的貴。
陣列的看家本領(和它的軟肋)
看家本領:按編號直達
想拿第 3 條訊息?messages[3],不用從頭數,一步到位。因為格子緊挨著排,編號本身就是地址——這叫 O(1),翻譯成人話是「不管陣列多長,耗時都一樣」。按位置取資料,陣列是所有收納方式裡最快的,沒有之一。
軟肋:中間插入貴
你剛才親手搬過了。順帶認識一個親戚:連結串列——它中間插入很便宜(改兩根「下一個是誰」的指標就行),代價是失去了按編號直達,找第 100 個得從頭挨個走。沒有全能的收納方式,只有取捨。對話這種「只追加、常整段讀」的場景,陣列完勝,所以 message list 用它。
✅ 這一課想和你分享的
- message list 就是陣列:一排編了號的格子,每條訊息躺一格,索引從 0 開始
- 索引直達 O(1):按位置取資料,陣列是最快的收納方式
- 上下文截斷 = 陣列切片:留 system + 最近 K 條,「掐頭不掐尾」,這就是聊久了忘事的真相
- 中間插入貴、末尾追加便宜:所以對話歷史只往後長(append-only)
- 收納方式都是取捨:連結串列中間插得快但沒了直達——場景決定選擇