第六章〈懷疑的種子〉
台版 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,繼續工作。
在這裡,沒有「我們」。從頭到尾,只有他一個。
他已經習慣了。
精采看點:
「他在中介島照顧母親的那八個月,有人在翠鏡島的辦公室,將所有棋子重新排過。等他回去,他已經踏上了一個他不認識的棋盤。而他還不知道。」