跳至主要内容

第六章〈懷疑的種子〉

台版 v2


地點:鏡界・中介島(百粵商港) 時間:1023年1月—8月 主角:林昭明


醫院走廊的燈光永遠是那種沒有溫度的冷白色。

1023年2月。中介島。百粵商港。

林昭明坐在某間公立醫院病房外的塑膠椅上,看著牆上「探病時間:18:00–20:00」的那塊壓克力牌。規矩是死的人是活的,但門口保全卻不是。六點前進不去。八點一到,護士準時拉開布簾,用毫無情緒的聲音請家屬離開。

每天就這兩個小時。坐在母親病床邊,聽著各種機器的運作聲。

其餘二十二個小時,他對著電腦。


母親入院的那天,他什麼都放下就飛回來了。本來以為是幾個禮拜的事。但是母親在醫院躺了很久。病危、穩定、康復,接著是漫長的復健。他留在中介島,一個月變兩個月,兩個月變四個月。最後,待了八個月。

這八個月裡,他的生活只剩兩條線。醫院、電腦。

探病時間是六點到八點。但是母親的親戚多。阿姨、舅舅、表弟、姊姊——他們很疼他母親,差不多天天都有人來。探病那兩個小時,病房裡很多時候已經有好幾個人。林昭明真正能夠陪母親的時間,通常只有半個小時到一個小時。放假的時候人更多,有時十五分鐘就得出來。

他沒有抱怨過。母親有人陪,這件事本身是好的。

但是這段時間,公司那邊有些奇怪的事情開始發生。

大部分會議沒找他。這點他能理解。他不在翠鏡島,有些遠距會議(meeting)不需要他參與。但偏偏有幾個——與廠商對口(DM)的會、一個重新啟動的緊急任務小組(Tiger Team)——全部排在六點到八點。

Cindy與阿K說協調過那些對口會議的時間。工廠那邊六點之前要全力做測試,對口只有六點之後才有空。他們還說:「你不用擔心啦,我們會搞定的。」

但林昭明每天都有掛上線,雖然人在病床邊,耳機塞著,靜音(mute)聽著會議。母親大部分時間都在睡覺,他會不時跟她說幾句話,叫醒她,聊兩句。醫生說過:如果沒了求生意志,她會撐不住。所以林昭明每天去都會跟她說話。有時說多一點,有時只有幾句。但一定要說。

然後耳機裡的會議繼續。八點開不完、九點、十點。核對重疊的測試結果,討論各種「創意」的測試方法——聽起來很有新意,但做出來的結果跟上次一樣。為做而做。但你必須在場。

其他會議呢?背後還有沒有其他他不知道的會?他覺得一定有。但沒人告訴他。他問,也問不到。老闆的話在他腦海浮起:「不要整天這麼多陰謀論。你自己多心了。」

或許是他多心。

但為什麼那些會全部都在他探病的時段才開?

他沒有問。


平安夜那件事,一直留在他腦海。

不是陳工的聲音。不是那句「想過死」。這些他記得,但不是一直存留在那裡的東西。

一直存留著的,是那份會議紀錄。

「林昭明有提交分析報告,建議轉移調查方向,已作參考。」

已作參考。

這四個字他記得非常清楚。幾個月的數據分析,幾百次測試結果,全部變成這四個字。然後結論沒變——供應商繼續測試。

他叫停了。聖誕節那天,他一個人打電話、發訊息,將這件事停了下來。陳工可以休息,供應商可以喘口氣。

但是問題沒有解決。

能芯模組沒問題——他很肯定。幾百次測試,全部通過。出事的案例全部是新系統。如果問題是在新系統與舊模組的整合層——在時序(timing),在極端情況(edge case)的處理——叫供應商測模組,測到天荒地老也測不到。

還有一個方向:替代料。有人懷疑供應商偷偷換了零件。但是廠商那邊的報告寫得很清楚——這幾年沒換過替代料。而且想想看,幾間不同的供應商,會不會剛好同個時間一起換?不合理。

但是林昭明到一件事。如果將問題歸咎於替代料,有一個好處:可以推動更換客製化零件。

客製化零件的生意很大。幾個億、甚至幾十億的產值都不稀奇。這些零件在什麼層級、讓誰賺錢,林昭明不知道。他只知道:團隊裡的同事分不到多少,但會很賣力地去推這件事。

他那時候沒想那麼複雜。只是覺得這個方向對不上。

他那份報告寫得很清楚。但是沒人聽。

那麼問題到底在哪裡?


林昭明開始翻數據。

不是因為有人叫他翻。沒人叫他做任何事。他放假時叫停了測試,之後母親入院,他飛了回來。翠鏡島那邊,沒人再跟他提起那件事。好像從來沒發生過。

但是他自己記得。

他記得陳工的聲音。記得那四個小時的會議。記得會議紀錄上的那四個字。

然後他開始想:如果問題不是出在能芯模組,是在系統整合層,那到底是哪一層?

他沒有後台的日誌(log)。從來沒有。ALC——魄紀錄核心——他有基本存取權限,可以看到前台的測試報告、症狀紀錄、某些公開的數據。但是後台的東西——完整的系統日誌、底層的運行紀錄——他進不去。

這不是新問題。他之前問過老闆。老闆說:「你想太多。」

所以他利用他所擁有的。


他將過去半年所有的測試報告匯出來。症狀分佈、出錯時間、出錯條件、哪些機型、哪些批次、哪些環境溫度、哪些操作序列。

ALC裡的數據多到你難以想像。不是空的。正相反——裡面塞滿了東西。幾萬條錯誤日誌(error log),幾千條狀態更新。標籤、分類、備註。每一條都是人寫的,每一條都有參考序號。

問題是:它們對不齊。

測試報告用一套編號,JIRA(專案管理系統)用另一套,產品規格書用第三套。同一個症狀,A部門叫「硬體介面超時」,B部門標記為「韌體版本不符」,C部門直接結案「無法重現」。

林昭明以前在舊公司時,每個禮拜花兩天寫腳本(script),將不同部門的數據對齊。一條公式,一個Excel對應表,搞定。他自己用,省了很多時間,然後慢慢介紹給其他人用。從一個人用,變兩個人用,變成整個團隊的標準(standard)。

在靈韻合成,他試過同樣的事。

但是這裡的反應不同。

說句公道話,不是沒人在做事。其他同事確實有在做工具。像是有一張從能芯單元轉換為模組的對應表——據說是廠商提供的,但在公司內部變成了「自行開發」的標準工具。每間廠商都認同,每個人都用,最後變成整個團隊的系統。

所以不是說小工具完全沒空間。有的,其他人做到了。

但是林昭明注意到一件事:那些工具,全部都是在做「統一」。將A的格式換去B的格式,將這個名字對應那個名字。一張表,一條規則(rule),硬性的、固定的。

他想做的不是統一,而是抽象化(abstraction)。

統一是指:這個編號等於那個編號。一對一,寫死的。 抽象化則是:找出底層的共通結構,提高相容性,讓不同器材的數據可以自動對齊。不需要每次有新產品出來就再做一張表。

兩件事聽起來差不多。但一個只是貼膠帶,一個是在改水管。

他那時候覺得,至少可以從一個最小可行性產品(MVP)開始。自己做一個示範,證明概念可行(work),然後慢慢推廣出去。

老闆那邊給了一堆回饋(feedback):「只是你自己用的東西,對公司沒貢獻啊。」然後給了一堆人的聯絡資料——這個引擎的總監(director)、那個部門的主管(head)——要他去談整個企業資源規劃系統(ERP)要怎麼改。

林昭明說:「我可以先做出一個示範案例,展示可能性就好。會不會簡單一點?」

「那個示範案例有多少人認同你?你的同事認不認同?廠商認不認同?能不能跨部門?」

他僵在那裡。話都扯到ERP等級了,你還講什麼示範案例。

而另一邊,其他同事繼續做他們的「統一工具」。一張又一張的對應表,一個又一個的小系統。每一個都得到認同,每一個都「有貢獻」。

林昭明看著那些工具,心裡不是生氣。說不上氣憤,只是覺得整件事很奇怪。

因為那些工具用起來其實超級麻煩。一開始大家都一直在抱怨。但抱怨歸抱怨,有沒有用不重要,重要的是做得漂漂亮亮,門面撐得住,大家可以拿獎。

拿完獎之後呢?慢慢就沒人用,被晾在那裡。然後過一陣子,再設計一個新的,又抱怨,又做得漂亮,又拿獎,又晾在那裡。

一個迴圈。

林昭明看著這些事,覺得毫無意義。這些浪費動作的行為,他盡量不去參與。

但他後來發現,其中一張對應表裡的對應關係(mapping)確實有問題。他當時沒多想。但那粒種子已經種下了。

他只能用最笨的方法。一條一條挑,一條一條對。自己做,不出聲。


中介島的書房很窄。一張桌子、一部電腦、一張椅子。窗外是密密麻麻的舊樓。晚上八點多從醫院回來,沖個澡,坐下,開電腦。然後做到凌晨三、四點。睡幾個小時,早上起床繼續做。下午五點多出門去醫院。

每日如是。

他在這段時間的工作量,比他在翠鏡島的任何時候都多。

不是因為有人逼他。是因為他腦海裡有件事放不下——一個做了十幾年的工程師,在電話那頭說他想過死。而整件事的起因,可能根本不在他們那邊。

如果林昭明找到真正的原因,至少可以證明:供應商沒錯。那些無止盡的測試,根本就不該發生。


三月。

他開始注意到一些事。

幾百條錯誤日誌裡,有一批的時間點很特別。不是隨機的,是跟著一個規律(pattern)。每次系統從休眠喚醒時,特定的操作序列,特定的運算負載(processing load),就會出事。

他第一次見到時以為是巧合。但是他將三個月的數據排在一起,同一個規律出現了十幾次。

不是隨機。不是巧合。是有規律的。

他那晚坐在書房,盯著螢幕好久。

他沒辦法百分之百確認。因為他沒有後台日誌。他看到的是前台的症狀——就像一個醫生只能看到病人的體溫紀錄,但是照不到X光照。

但是體溫的變化傾向告訴他:問題出在裡面,不是外面。

他寫了一份備忘錄(memo),將各種跡象整理出來,發給了幾個人。

沒有人回覆。


四月。

他繼續挖掘。

這次他看到了另一件事——某幾個特定的記憶體區位(memory block),在系統喚醒的瞬間會出現異常。不是每一次,是在某些特定條件下。非常隱蔽,如果你不是一條一條日誌逐行對照,你不會注意到。

他開始畫一張他自己的地圖。沒人叫他畫,沒人知道他在畫。

這張地圖上有:所有出過事的案例、症狀的分佈、時間的規律,以及他推斷的可能原因。

推斷。他很清楚這兩個字的意思。他有的只是數據規律,他沒有證據。證據在後台,後台他進不去。

但是規律夠清楚、夠一致。他愈看愈覺得:問題不是出在個別硬體。問題在更底層的地方。可能是BIOS(基礎輸入輸出系統),可能是韌體,可能是驅動程式,也可能是某一層的初始化程序(initialization sequence)有漏洞。

他講不準,但他知道方向。


他打電話給強哥。

強哥是供應商那邊的專案經理(PM)。之前在翠鏡島時合作過幾次。平安夜那件事,強哥知道。陳工是他團隊的人。

「強哥,我發了一份東西給你,你看一下。」林昭明的聲音有點沙啞。「下次你們測試時,幫我特別留意一下系統喚醒那零點幾秒的記憶體狀態。我覺得之前那些莫名其妙的問題,不是你們的機台,是我們這邊底層有東西。」

電話那頭沈默了幾秒。

「昭明哥,你這份東西做得好細。」強哥聲音壓得很低。「我會叫下面的人看看。」

「謝謝。有結果再跟我說。」

掛斷。

林昭明以為,有強哥那邊的實機數據配合,他的推斷就可以再進一步。


之後的幾個禮拜,強哥沒有回覆。

林昭明以為他們忙,測試要時間。先放下,繼續挖其他東西。

五月。母親醒了。從病危到穩定到清醒,過程很漫長,但她終於醒了。

林昭明跟公司提了一句。

然後那些六點到八點的會議,全部停了。

不是逐個停,是一起停。對口那邊的會、緊急任務小組的會——全部不再約那個時段。好像從來沒安排過一樣。

林昭明看著行事曆。沒想太多。母親醒了,他不用再在探病時間掛著耳機,這是好事。

但他心裡動了一下,很輕。閃過就沒了的那種。

然後五月底,他收到一封電子郵件。是靈韻合成內部的一個大型檢討會議(review meeting)紀錄。他因為不在翠鏡島,不知道有這個會。紀錄是事後轉發(forward)給他的。

他打開來看。

第三頁。一張投影片(slide)的標題:「系統穩定性優化初期成果」。

他的眼睛停在那裡。

投影片裡的內容——症狀的分佈圖、日誌的比對邏輯、標註異常點的方法——他認得出來。因為那是他做的,那是他熬了幾個通宵整理的東西,發給強哥的東西。

但是投影片上的署名,不是他。

會議紀錄裡,有人說:「這個優化方向很不錯,終於找到一點頭緒。」另一個人說:「比之前一直叫人盲測好多了。」

林昭明坐在中介島的書房,看著螢幕。

他沒有生氣。或者說不是不生氣。是生氣不起來。

他想起故鄉香港的茶餐廳。公仔麵好不好吃是唯一的標準。你煮出一碗麵,食客吃了,問題解決了。是誰端出去的,是誰拿到小費——重要嗎?

他坐在那裡好久。

然後他告訴自己:算了,至少問題有人跟進,至少那個方向有人去查,至少不會再有人因為這件事,被迫在供應商那邊無止境地測試下去。

他找新的問題來做就行。


但是歷史不斷重演。

他在ALC裡挖出線索。因為沒權限直接修復,他將資料整理好,發給相關人士。然後石沈大海。或者過幾個禮拜,神奇地出現在其他人的報告裡。

他在中介島,他不在現場,他甚至連保護自己心血的資格都沒有。

但他繼續做。因為他腦海中有一個畫面放不下——陳工在電話那頭的聲音。「想過死。」如果底層的問題不找出來,同樣的事遲早會再發生。不是發生在陳工身上,就是發生在其他人身上。

所以他繼續挖。


六月。

母親的情況穩定了很多,開始進行復健。每天探病那兩個小時,他推著母親在走廊走兩個來回。母親走得很慢,他也走得很慢。

有一天,母親在走廊的窗邊停下,望著外面。

「你待在這邊的這段時間,那邊的工作怎麼辦?」母親問。

「還在做。」林昭明回答。

「辛不辛苦?」

「還可以。」

母親看著他,沒再問。母親識人無數,但她不會逼你說。

林昭明推著母親繼續走。走廊的燈光還是那種沒溫度的冷白色。


那段時間,林昭明在翻查日誌之餘,順帶看了一下「能芯」的韌體規格。也就是「GG檔案」(GG file)。

他原本只是想搞清楚底層邏輯——最基本那層到底在做什麼。但他打開後才發現:底層邏輯很簡單、純粹、通用。沒問題。

問題是在「上面」。

在那個簡單邏輯之上,堆疊了將近一半的功能。一層又一層,每一個都有名字,每一個都有文件。但他仔細看——這些功能到底在做什麼?有沒有人真的知道?

他問了幾個人。沒人答得清楚。每間廠商都覺得有些功能很奇怪,但沒人敢提出來。

他跟CTO提過。

兩個高級首席工程師立刻說:「這個我們有緊急任務小組在秘密進行中。之後再跟你說。」

緊急任務小組。電話那頭,CTO沈默了一陣。這個小組,他們兩個都沒聽過。

但是人家說有,你還能說什麼?

他不是第一次見到不知道在做什麼的功能。做得久了,見多了。

通常的做法是:不知道做什麼,但既然現在正常,就不要動它。「能跑就別碰」。這是有道理的——你不知道它在做什麼,也就代表你不知道關掉它會有什麼後果。不是懶,是謹慎。

但這裡不同。

這裡的情況是:環境已經在轉變了。新架構要來了,AI的東西要來了。這些舊功能不再是安靜地待著——而是已經在跟新的東西發生衝突。「能跑就別碰」的前提是系統處於靜止狀態。但現在,它不安分了。

他跟廠商聊了幾個月。每次問「這個功能是在做什麼」,他們不是不肯說——是真的不知道。

不知道的不只是廠商。他問回靈韻合成內部,傳上去一層一層問。問到最後,沒人有答案。

大家都有個模糊印象:「好像是某個專案留下來的內容」「應該是有原因的吧」「一直都是這樣,沒出過事」。但詳細規格?沒人。

那不是秘密,是從來沒人知道過。

林昭明那時候想:如果你不知道它在做什麼,而它又在引發衝突——那麼關閉它,然後观察後果,是一個合理的選擇。不是激進。是因為「不動它」這個選項,其實早就消失了。

老闆那邊的回饋(feedback)很一致:「這些不是你要關心的事。你應該多熟悉我們的流程,了解每一項操作的程序。」

林昭明一直有在留意。但檯面下的流程怎麼跑,他永遠看不到。

他將這件事暫時放下。繼續做他的日誌分析。


七月。

他的地圖已經畫得很大一張。

幾百條日誌的交叉對照、十幾個規律、幾個可能的方向。每一個方向他都標註了「推斷」。因為沒有後台日誌,每一個都只是臆測。

但是這些推斷加在一起,指向同一個方向:問題不是硬體,是軟體底層。可能是BIOS。

奇怪的是,其他部門並非完全不理。他們會挑戰、會說:「有沒有可能是其他設定的問題?」「會不會是這邊的組態(configuration)?」聽起來很有道理,好像大家一起在找原因。

但是找歸找,從來找不到。不是說他們不賣力——有些人是真的在做事的。但最後出來的魚骨圖,每一個分支都寫著「已排除」、「沒問題」。

BIOS?沒問題。韌體?沒問題。驅動程式?沒問題。硬體?沒問題。能芯模組?持續測試中。

全部沒問題。

但系統就是有問題。用戶投訴是真的,當機是真的。

全部都沒問題,但就是有問題。

林昭明看著那份魚骨圖。他一邊爭取說不是能芯的問題,但當其他人全部都說自己那邊沒問題時,你還能說什麼?到最後,大家的結論變成了:「那好吧,我們一起繼續找囉。」

整個氣氛很奇怪。好像每個人都很努力,但每個人都找不到。好像每個人都在做事,但事情永遠在原地踏步。

他後來才明白:那不是找不到,是大家心照不宣地在「爭取時間」(buy time)。

但那時候他還沒想到這層。他只覺得很奇怪。

如果問題是在BIOS——或是任何底層軟面——這件事絕不可能沒人發現。系統內部一定有人知道。做BIOS的、做韌體的、做驅動的——他們每天對著這些東西,不可能完全看不到。

但是沒人提過。

會議紀錄裡,從來沒人提過「BIOS」這四個字母。所有的討論、所有結論,焦點永遠在硬體、供應商、還有「測試方法需要改進」。

林昭明坐在書房,看著自己畫的地圖。

他沒辦法解釋。可能真的是他錯了,可能他的圖形識別(pattern recognition)有偏差,可能有些他不知道的原因,讓這個方向不成立。

但是他心裡有個疙瘩,很微小,說不出口。好像有些事,不是他想不到,是有人不想讓他想到。

他搖搖頭。別瞎想。

繼續做。


那段時間,他跟老婆通電話。

因為他在中介島,老婆在翠鏡島。每天傍晚他出門去醫院前,會打個電話。

「翠鏡島那邊怎麼樣?」他問。

「老樣子啦。你公司那邊呢?有沒有人問你什麼時候回來?」

「沒人問。」

沈默。

「那媽呢?」

「好多了,開始在走路。」

「那就好。」

又是沈默。

「你的聲音聽起來很累。」老婆說。

「沒睡好。」

「你要保重身體。」

「知道。」

掛斷電話後,他站在窗邊。中介島的黃昏,對面的舊樓密密麻麻。冷氣機的水滴落到地上,滴答、滴答。

他心裡有很多話想說。但不知道該怎麼說。

有一個人因為一個會議想過死。他叫停了測試,但是根源沒人理。他挖掘到的東西被別人拿走了。他覺得有些事情很不對勁,但他甚至連「不對勁」到底在哪裡都說不清楚。

這些事要怎麼跟家人開口?

他沒說。出門,去醫院。


八月。

母親出院。復健持續進行,但可以回家休養。林昭明安排好一切,準備回翠鏡島。

走之前,他在中介島的書房坐了最後一個晚上。

八個月。他在這間窄到轉身都勉強的書房,對著電腦挖了幾百條日誌,畫了一張沒人見過的地圖,寫了幾十份沒人回覆的備忘錄。

他以為回到翠鏡島,他可以將這些東西拿出來說。面對面說,找對的人說。

他不知道的是,翠鏡島的辦公室,在這八個月裡已經變了。

他不知道誰走了,誰來了,誰的位置變了,哪些東西被重新分配了,哪些人的關係改變了。

他只知道:他準備好了。他有數據、有規律、有推斷。

他以為這些就夠了。


飛機的窗外,翠鏡島的輪廓慢慢浮現。

林昭明望著下方的城市。很窄、很密,好像每一棟樓都擠在一起。

他不知道的是,他即將回去的,並非他離開時的那個地方。

棋盤上的棋子,在他不在的這八個月裡,已經被全部重新排過。

而他,拿著他的地圖、他的數據、他的推斷,走進那間他以為自己認得的辦公室——

他不知道,他已經踏上了一個他不認識的棋盤。


★ 閃回C〈我們一起解決(We fix it together)〉


那天晚上在中介島的書房——應該是五月左右——林昭明工作到很晚,腦袋開始不受控地飄散。

他那時候剛發現自己的分析被別人拿走了。坐了好久。然後記憶不自覺地飄了回去。


五年前。同樣是在中介島,同樣是因為母親。

那次他在亞美利昂那邊工作。亞美利昂聯合體(Amerion Collective)。資深系統架構師。做了幾年。

母親突發心臟問題。他請了緊急事假飛回中介島。

飛機剛剛落地,還在去醫院的計程車上,電話就開始震動。亞美利昂那邊一個核心的支付閘道(payment gateway)更新後出事,交易失敗率每分鐘都在攀升。

那個閘道的底層架構是他寫的。除了他,短時間內沒人理得清那些依賴性(dependency)。

林昭明拎著行李箱站在醫院急診室的走廊。四周是救護車的鳴笛聲與護士的奔跑聲。他打開電腦想連虛擬私人網路(VPN)。醫院的Wi-Fi弱到連登入都辦不到。

那一刻,他覺得完蛋了。

商業世界的邏輯很簡單:系統崩潰了,你不在現場,你沒解決,就是你的責任。他已經做好被開除的準備。

然後他的直屬上司打了過來。一個亞美利昂人,滿臉鬍鬚的老頭。

林昭明接起電話,語氣充滿防備:「老闆,我很抱歉(Boss, I'm sorry)。我知道現在情況很糟,但我媽剛進手術室,我連VPN都連不上。我可能幾個小時內給不出解決方案(workaround)——」

他腦海中已經準備好聽那些話:「這是你的專案(This is your project)。」「你要想辦法解決(You need to figure it out)。」「公司每分鐘都在賠錢(The company is losing money every minute)。」

但電話那頭只有一陣短暫的沈默。背景隱約傳來有人在打字的聲音。

然後那個老頭用很平靜的聲音說了一句:

「照顧好你媽,昭明。別擔心閘道。我們會一起解決。(Take care of your mom, Zhaoming. Don't worry about the gateway. We fix it together.)」

照顧好你母親,昭明。不用擔心閘道。我們會一起解決。


那不是一句安慰的空話,是一個承諾。

之後的四十八個小時,加州總部三個工程師直接接管了他的權限。沒人趁機發電子郵件指責他「專案管理出問題」,沒人背後議論他「一出事就跑回中介島」。老頭自己下場,帶著團隊撐了兩個通宵,硬生生地將漏洞補上了。

等母親手術順利,林昭明重新登入公司電子郵件時,他看到的是一份已經結案的事故報告。

在「貢獻者」一欄,老頭將他的名字排在了第一個。

在那間公司,「我們(We)」這個字是真的。不是印在咖啡杯上的字母,不是人力資源部門口中的口號。

是當你站不穩的時候,真的有人伸手接住你。真的接住。


閃回結束。


中介島。書房。五月的夜晚。

林昭明從回憶中清醒。冷氣機的聲音很大。

他望著螢幕。靈韻合成的內部網頁還開著。上面有一行字:「我們的員工第一承諾(Our People First Commitment)。」

他盯著看了很久。

然後他將網頁關掉。

打開ALC,繼續工作。

在這裡,沒有「我們」。從頭到尾,只有他一個。

他已經習慣了。


精采看點:

「他在中介島照顧母親的那八個月,有人在翠鏡島的辦公室,將所有棋子重新排過。等他回去,他已經踏上了一個他不認識的棋盤。而他還不知道。」