35歲生日,我被裁了。
十五年代碼,三千多個日夜的燃燒,最后換來HR一句冰冷的“人員結(jié)構(gòu)優(yōu)化”。我的上司,技術(shù)總監(jiān)李建國,那個昨天還拍著我肩膀喊“兄弟”的男人,此刻低頭看著自己的茶杯,仿佛那里面有一整個宇宙,唯獨沒有我的十五年。
“林默,你知道的,公司不是家?!彼K于開口,聲音干澀,“‘天穹系統(tǒng)’已經(jīng)穩(wěn)定了,你的歷史使命也算完成了。年輕人,更有沖勁?!?/p>
年輕人。
他指的是張浩,我親手帶出來的徒弟。此刻,他就坐在李建國的身邊,穿著我送他的那件格子襯衫,眼神躲閃,不敢看我。昨天,他還追在我屁股后面喊“師傅”,請教“天穹系統(tǒng)”最后一個核心模塊的寫法。今天,這份系統(tǒng)的知識產(chǎn)權(quán)所有者,就變成了他的名字。
我笑了,喉嚨里像是卡著碎玻璃?!袄羁?,‘天穹系統(tǒng)’的收尾工作是我昨晚通宵做完的。今天就優(yōu)化我,是怕我跟你們搶功勞嗎?”
李建國的臉色沉了下來,那張永遠掛著“奮斗”和“激情”面具的臉,第一次露出了冷酷的底色。“林默,注意你的言辭!公司給你的補償是N+1,業(yè)界良心了。別不識抬舉?!?/p>
“良心?”我看著他,也看著張浩,看著這間我用無數(shù)個夜晚換來的玻璃會議室,看著窗外那些假裝在忙碌、實則用眼角余光窺探著這場屠殺的同事們。我的心,一瞬間,死了。
我沒再說話,拿起那張薄薄的A4紙,那是我的死亡通知單。沒有爭吵,沒有憤怒,只有一片死寂的麻木。我站起身,走向門口。
“等等?!盚R喊住我,“你的工牌?!?/p>
我摘下脖子上那個印著“騰飛科技”logo和我的名字的藍色工牌,放在桌上。它與桌面碰撞,發(fā)出一聲清脆的響聲,像是我十五年青春的墓志銘。
出門,兩個高大的保安一左一右地“護送”我走向電梯,仿佛我是一個危險的罪犯。我的電腦權(quán)限在我走出會議室的那一刻就被鎖死,私人用品會被打包好寄到我家里。這就是“騰飛科技”的效率,裁掉一個十五年的老員工,就像從代碼里刪除一個過時的函數(shù)一樣,干凈,利落,不留痕跡。
電梯門緩緩關(guān)上,隔絕了那些熟悉的、又變得無比陌生的面孔。
我以為這就是谷底了。
走出騰飛大廈,冰冷的雨水瞬間澆透了我的襯衫。我像個游魂,在街上漫無目的地走著。手機響了,是一個陌生的號碼。我麻木地接起。
“喂,是林諾的父親嗎?”電話那頭的聲音,比這冬雨還要冷。
我的心臟猛地一縮?!拔沂??!?/p>
“我是市第一醫(yī)院,你女兒的醫(yī)藥費已經(jīng)拖欠半個月了。我們通知過你很多次,如果你今天下午四點前還不能繳清費用,我們將不得不……停止對她的治療?!?/p>
“轟——”
我的大腦,一片空白。
我忘了是怎么掛斷電話的。我只知道,我完了。事業(yè)、尊嚴,還有我女兒的命,在今天,我35歲生日的這一天,被打包成一個巨大的黑色笑話,狠狠地砸在了我的臉上。
我蹲在路邊,任由雨水和淚水混在一起,流進嘴里,又苦又澀。我看著眼前這個灰色的、冰冷的世界,看著那些行色匆匆的路人,看著遠處高聳入云的騰飛大廈,它像一個巨大的、吞噬一切的怪獸。
就在我絕望到想死的那一刻,我的眼睛,突然傳來一陣劇痛。
整個世界,在我眼前,開始分解、重構(gòu)。
眼前的紅綠燈,不再是紅綠燈,而是一行行滾動的代碼:if (time < 60) { light.color = RED; } else { light.color = GREEN; }。
路邊那輛飛馳而過的汽車,變成了一串串復(fù)雜的數(shù)據(jù)流:speed: 80km/h; direction: EAST; fuel_level: 34%;。
那個撐著傘從我面前走過的女孩,她的雨傘,她的高跟鞋,甚至她臉上的妝容,都變成了一層層疊加的、閃爍著微光的代碼。
我看到了。
我看到了這個世界的……源代碼。
而我,一個剛剛被世界拋棄的程序員,卻在這一刻,擁有了看穿世界所有BUG的……權(quán)限。
劇痛來得快,去得也快。
當視野恢復(fù)正常時,我依舊蹲在那個冰冷的街角,渾身濕透,像一條被世界遺棄的狗。剛才那匪夷所思的一幕,仿佛只是絕望催生的幻覺。
可我知道,不是。
那種感覺太真實了。世界在我眼前被解析成最底層的邏輯,那種洞悉一切的上帝視角,深深刻入了我的腦海。
手機又響了,還是醫(yī)院。我不敢接,直接按掉了。催命的電話,我拿什么去回應(yīng)?用我那可笑的N+1補償嗎?那點錢,對于諾諾的病來說,連杯水車薪都算不上。
諾諾,我的女兒。她才七歲,本該是在陽光下奔跑的年紀,卻因為罕見的血液病,常年住在無菌病房里。那間小小的病房,就是她的整個世界。而我,是她唯一的英雄,是她世界的全部支撐。
可現(xiàn)在,她的英雄,破產(chǎn)了。
我站起身,身體因為寒冷和饑餓而搖搖欲墜。我必須想辦法,我不能讓諾諾的藥停了。
我漫無目的地走著,大腦一片混亂。怎么辦?借錢?那些曾經(jīng)稱兄道弟的同事,現(xiàn)在恐怕連我的電話都不會接。賣房子?遠水救不了近火。
就在我六神無主之際,我路過了一家銀行的ATM機。一個男人剛?cè)⊥赍X,匆匆離去。
我的目光,不自覺地停留在那臺冰冷的機器上。
然后,那一幕,又發(fā)生了。
我的眼睛再次刺痛,ATM機在我眼中迅速“解碼”。外殼消失了,復(fù)雜的電路和機械結(jié)構(gòu)以線框圖的形式呈現(xiàn),旁邊是瀑布般滾動的代碼流。
我看到了它的操作系統(tǒng),一個老舊的、布滿冗余代碼的系統(tǒng)。我甚至能看到每一行代碼的注釋。
// Author: Wang Li, 2015
// Function: Core banking logic
我一行行地掃過去,像是在巡視自己的領(lǐng)地。突然,我的瞳孔猛地收縮。
我看到了。
在一個最不起眼的角落,在一個處理取款邏輯的函數(shù)里,我看到了一個致命的BUG。
function dispenseCash(amount) {
if (checkBalance(currentUser, amount)) {
updateBalance(currentUser, -amount);
// !! BUG: ejectCard() should be called BEFORE dispense() !!
hardware.dispense(amount);
hardware.ejectCard(); // <--- 漏洞在此!
return "SUCCESS";
} else {
return "INSUFFICIENT_FUNDS";
}
}
這是一個經(jīng)典的邏輯錯誤!正確的流程應(yīng)該是先更新余額,然后彈出銀行卡,最后再出鈔。而這臺機器的程序,是先出鈔,再彈卡!
這意味著什么?
這意味著,如果我在它出鈔的瞬間,用物理方式強行中斷交易(比如斷電或者按下緊急停止鍵),機器的程序?qū)⒉粫?zhí)行到hardware.ejectCard()和updateBalance()的后續(xù)步驟。我的賬戶余額不會被扣除,但錢,已經(jīng)吐出來了!
我的心,狂跳起來。
這是犯罪。作為一個寫了十五年代碼的程序員,我的職業(yè)道德在瘋狂地尖叫,警告我不要這么做。
可另一道聲音,卻更加響亮——那是醫(yī)院催款的電話鈴聲,是諾諾虛弱的呼喚。
去他媽的職業(yè)道德!我的女兒都要沒命了!
我環(huán)顧四周,街道上行人稀少。我走到ATM機前,顫抖著,插入了我那張只剩下兩位數(shù)余額的銀行卡。
屏幕亮起,我輸入密碼,選擇了最大取款金額——五千元。
機器開始運轉(zhuǎn),發(fā)出嗡嗡的聲響。我能“看”到,代碼正在一行行地執(zhí)行。
checkBalance(currentUser, 5000) -> true
updateBalance(currentUser, -5000)
來了!
我死死地盯著出鈔口。就在那疊嶄新的鈔票剛剛露頭的那一剎那,我的另一只手,狠狠地拍在了機器側(cè)面的紅色緊急停止按鈕上!
“啪!”
機器的屏幕瞬間黑掉,所有的聲音戛然而止。
一秒,兩秒,三秒……
死一般的寂靜。
然后,我聽到了一聲輕微的機械復(fù)位聲。屏幕重新亮起,回到了初始歡迎界面。我的銀行卡,還靜靜地插在卡槽里。而出鈔口,那厚厚的一疊鈔票,也靜靜地躺在那里。
成功了!
我一把抓起那五千塊錢,心臟狂跳得像是要從喉嚨里蹦出來。我迅速拔出銀行卡,塞進口袋,轉(zhuǎn)身就走,不敢回頭。
走了幾步,劇烈的頭痛,突然像海嘯一樣襲來!
眼前瞬間一黑,我什么都看不見了。大腦像是被一萬根鋼針同時穿刺,我痛得發(fā)出一聲悶哼,扶著墻壁才沒有倒下。
這是……代價嗎?
利用世界的BUG,就要承受世界的反噬。
這短暫的失明和劇痛,持續(xù)了將近一分鐘。當我的視力緩緩恢復(fù)時,我渾身已經(jīng)被冷汗浸透。
我看著手中那五千塊錢,它仿佛有千斤重。這是救命錢,也是……我與魔鬼交易的憑證。
我沒有絲毫猶豫,轉(zhuǎn)身沖向最近的地鐵站。
我要去醫(yī)院。
我要去告訴諾諾,爸爸來了。爸爸的英雄披風,破了,但爸爸,還能為她撐起一片天。
我的眼中,這個由0和1構(gòu)成的冰冷世界,第一次,因為那疊染著罪惡的鈔票,而有了一絲溫度。