里奇後退兩步,靠在椅背上,雙手交叉在胸前。
他不是在刁難,他只是充滿好奇。
這個問題不是憑空產生的,而是他真切遇到過的問題。
所以,里奇也在思考。
同樣地,他也期待眼前這個年輕人,能給出一個讓他感到新奇的解法。
就像他之前做到的那樣。
李林深深吸了一口氣。
此刻他腦海中有混亂、有震驚,但唯獨沒有恐懼。
因為他並沒有從里奇身上感受到惡意。
這只是一個挑戰。
一個他必須接受的挑戰。
這就是C語言之父的威能嗎,連繫統這種產物都得被他壓制。
幸好,李林的知識都裝在腦子裡。
「呼——」
他沒有急著動手,而是先試著理順思路,說出了自己的思考,
「要真正解決問題,必須依靠系統本身防禦錯誤的能力。畢竟,錯誤就像現實世界的熵增,一定會發生。所以,邏輯不僅要正確,還要設置防線。」
【記住全網最快小説站 101 看書網解無聊,𝟙𝟘𝟙𝕜𝕜𝕤.𝕔𝕠𝕞超靠譜 】
「那就讓分配器自己處理。」
里奇的聲音從虛空中傳來,他的思路逐漸與李林重合,
「唯一的目標是,不許崩潰。」
李林點點頭,似乎是同意了里奇的說法。
他重新抬起手,嘗試在方格紙上構築新的秩序。
這一次,他從邏輯入手,為它加上了一道免疫防線。
他修改了分配器,給每一個內存塊的頭信息添加了一個狀態標記。
分別代表已分配、空閒、已釋放。
釋放一塊內存之前,先檢查它的狀態。
如果狀態已經是「空閒」或「已釋放」,說明它已經被釋放過了。
這時候不再執行合併操作,而是直接拒絕第二次釋放,記錄一條錯誤信息,然後返回。
「狀態機?」
里奇的聲音再次響起,語氣裡帶著不加掩飾的驚喜。
他知道,他賭對了。
「你給每一個內存塊賦予了一個有限狀態機,從而把釋放變成了一次帶有前置條件驗證的狀態轉移。」
李林點了點頭,手指卻沒有停下來。
因為還不夠。
光靠狀態標記還不夠,錯誤可能更隱蔽。
李林的大腦在飛速運轉,模擬著編程場景中可能出現的錯誤。
比如,釋放了一個不屬於任何已分配塊的地址呢?
他又在分配器中加入了一個已分配列表,釋放時先在列表中查找目標地址。
找不到?
那就是野指針,同樣拒絕釋放,輸出警告。
「防禦性編程……在已經設立防線的情況下,還要用結構化的方式來儘可能保證安全。」
里奇滿意地點點頭,看向李林的目光不僅有欣賞,似乎還有些感慨。
像是在看一個和自己走在同一條路上的後輩。
「說說看,你是怎麼想到這些的?」
李林愣了一下。
怎麼想到的?
他思考片刻,搖了搖頭,然後如實說道,
「我的能力還不足以想到這些。我只是……站在巨人的肩膀上而已。」
里奇沒有說話,微微眯起眼睛,等待著他的下文。
「就像細胞。細胞里有遺傳物質,也有處理這些遺傳物質的酶。它們被同一個細胞膜包裹在一起,不分離。被釋放的內存塊也應該帶著自己的狀態、檢查狀態的方法和處理錯誤的方法。它不是一個被動的數據單元,而是一個主動的、對自己負責的結構。」
里奇沉默了很久。
頭頂的日光燈管依舊嗡鳴,身側PDP-11的機箱風扇依舊呼呼地轉著,但他卻覺得世界如此安靜。
然後,他笑了。
他緩緩地念叨了一遍,
「數據和操作數據的函數,封裝在同一個結構體裡。讓結構體自己去處理自己的生命周期。」
他頓了頓,目光落在李林身上,
「你來自哪裡,孩子?」
「半個世紀之後,里奇先生。」
「哦——那真的是……很幸運的事情。」
里奇語氣出奇的平和,
「你能見到這麼多我不知道、也沒機會知道的事情。」
他站起來,走到方格紙前,伸手在那棵已經恢復秩序的二叉樹上輕輕一點。
「這個想法,它應該有個名字。」
「面向對象,先生。您的C語言,是面向過程的。」
里奇沉默了一會兒,才緩緩開口,
「真是精闢的總結。」
里奇說完後,便仰頭注視著面前的方格紙。
年僅三十歲的里奇,此刻目光卻是如此深邃。
似乎在思考,又似乎只是純粹的觀賞這近乎完美的秩序。
良久,他才回到桌前,拿起那本一直攤開的筆記本,在上面緩緩寫下了幾行字,然後把那一頁折了個角。
「拿著吧,孩子,這算是我送給你的回禮。」
李林接過筆記本。
來沒來得及說些什麼,眼前的一切就都開始碎裂、一寸一寸地崩塌。
【考驗異常拋出,強制結束。】
似乎是察覺到了李林無奈的表情,里奇佇立在碎裂世界的中央,沖他揮了揮手。
他笑得很開心。
李林聽不到他的聲音,但僅從口型,隱約能看到……
「Keep it simple。」
隨後,白光一閃。
【考驗通過。】
【「C語言」水平提升(通曉→貫通)】
【獲得物品:「里奇的隨筆」。】
【解析中……經後人整理,丹尼斯·里奇在開發C語言與UNIX期間隨手記錄的工作筆記。前半部分是內存分配器的設計草圖,後半部分是里奇與一位「不知名的訪客」關於「面向對象」的對話記錄。末尾有里奇手寫的一行字:「也許現在還沒有人能完全理解這個想法。但總有一天,會有人需要的。」】
【獲得被動效果:「保持簡單」——當面對複雜不可解問題時,你的思維會自動將其拆解為有限可解問題的組合。】
李林猛然回過神。
他這才意識到,他依舊在胡云程的辦公室里。
但窗外的天色已經暗了下來。
李林低頭看了一眼自己的雙手,又看了一眼面前堆積的書本。
「……」
「喂!」
突然,胡云程的手在他面前擺了擺,
「睡著了,臭小子?!」
李林有些茫然地抬起頭,明顯還沉浸在剛才和里奇的深入交流之中。
胡云程看他那副魂不守舍的樣子,哼了一聲,把手中的手機遞了過來。
「行了,我算是看出來了,你就是個犟種。」
他的語氣還是一貫的不好聽,但手中的動作卻很乾脆,
「嚴老師,人家搞了二十年嵌入式開發,解決你的問題綽綽有餘。」
李林眨眨眼,似乎還沒反應過來,但手上已經被塞了個手機,
「總之,你有什麼問題,最好一口氣問明白了,問完就給我收心,再有疑問也得等初賽完了之後再折騰。否則——」
他做了個掐脖子的手勢。
李林把手機拿到耳邊,聽筒里傳來一個溫和的中年男聲,
「小同學,你那個問題,老胡跟我說了個大概。你能再複述一遍嗎?我很感興趣。」
李林下意識地開口,把自己的問題重新說了一遍——
當使用函數指針實現回調,且需要修改多個不同生命周期和類型的變量時,如何設計接口才能兼顧簡潔性、類型安全與內存安全。
一邊說著,李林在考驗中梳理過一遍的知識開始隨著問題自然地翻湧、排列。
「這個嘛……」
電話那頭的嚴正江聽到問題,皺了皺眉頭,似乎也陷入了思考。
但還沒等他說些什麼,李林自說自話地,便順著剛才的思路繼續往下推,
「……不對,其實答案已經在問題里了。」
「……」
嚴正江:?
在……在嗎?
「把數據和函數指針封裝在同一個結構體裡,讓結構體自己去管理生命周期。接口只暴露必要的函數指針,生命周期由擁有者負責。類型安全用函數指針的類型簽名來保證。至於內存泄漏和懸空指針,在分配器里加哨兵值和已分配列表校驗,攔截野指針。」
「……」
電話那頭沉默了好幾秒,
「來,小同學,你把手機先給胡老師。」
李林默默把手機遞了過去,胡云程接過來就被手機那邊的震聲嚇了一跳,
「這人你從哪找來的?!」
「不是和你說了嗎,我學生……」
「你的意思是,你隨便教出來的學生水平比我還高咯?」
「不是,我沒教他……」
「你的意思是,不教比我教過的還強?」
「不是……」
「彳亍,老胡啊,老胡,就你有好苗子是吧!你給我等著!」
「別,老嚴——」
「嘟嘟嘟……」
「好啊,你小子——」
胡云程看了看手機,又看了看李林,面無表情的臉抽了抽,
「前面裝成那樣給我下套,合著是就是特地來我面前裝逼是吧!」