第二十章:第一次團隊合作與“豬隊友”

字數:7540   加入書籤

A+A-


    林小圈手腕上的白色Lv2手環還沒戴熱乎,雷銘就在一次奧賽隊晚間集訓時,投下了一顆重磅炸彈。
    “下周開始,進行為期兩周的團隊項目實踐。”雷銘站在活動室前方,聲音依舊沒什麽起伏,但內容卻讓底下所有隊員,尤其是低等級隊員豎起了耳朵,“項目主題:設計並實現一個簡易的‘在線判題係統’核心模塊,包括用戶提交代碼、後台判題、返回結果等基本功能。三人一組,自由組合。最終提交項目文檔、源代碼、以及小組貢獻說明。”
    他頓了頓,目光掃過在場眾人,補充了最關鍵的一句:“項目成績將計入本學期個人綜合評定,並影響貢獻點分配和等級晉升。不允許單人成組。”
    最後五個字,斬釘截鐵,斷絕了某些獨行俠的念想。
    活動室裏響起一陣低低的騷動。自由組合?這對於剛剛入學、彼此還不算熟悉的新隊員來說,無疑是個難題。林小圈下意識地看向旁邊的周博瀚,周博瀚也正好看向他,兩人交換了一個心照不宣的眼神——作為同桌和同期,他們顯然是天然的隊友。
    “還差一個。”周博瀚言簡意賅。
    林小圈的目光在活動室裏搜尋。他的視線落在了一個坐在角落、麵前攤開著一本厚厚《算法導論》筆記的男生身上。那個男生叫陳飛,平時沉默寡言,但理論課成績極好,幾次小測都名列前茅,據說對各種算法的原理和複雜度分析有著近乎偏執的鑽研。
    “陳飛怎麽樣?”林小圈小聲提議,“他理論很強。”
    周博瀚順著他的目光看去,皺了皺眉,似乎有些猶豫,但最終還是點了點頭:“可以試試。至少不會拖後腿……理論上。”
    兩人走到陳飛麵前,簡單說明了來意。陳飛從書本裏抬起頭,扶了扶厚厚的眼鏡片,眼神有些遊離,似乎在快速思考組隊的利弊,幾秒鍾後,他才慢吞吞地點了點頭:“好。我需要負責核心算法設計。”
    組隊成功。林小圈心裏稍稍鬆了口氣,對即將到來的團隊項目甚至抱有一絲期待。周博瀚技術紮實,陳飛理論深厚,加上自己也不弱的實踐和邏輯能力,這個組合看起來潛力不錯。
    然而,現實的骨感很快便顯露無疑。
    第一次小組討論,他們約在放學後的空教室。周博瀚開門見山,直接在白板上畫起了係統架構圖:“我認為應該采用微服務架構,用戶提交、代碼沙盒、判題邏輯分離,通過消息隊列通信,這樣可以提高並發能力和容錯性……”
    他語速很快,思路清晰,顯然是胸有成竹。
    但陳飛立刻打斷了他,指著架構圖上的“代碼沙盒”部分:“這個沙盒的安全性如何保證?使用Docker雖然輕量,但存在逃逸風險。我認為應該從底層係統調用攔截入手,參考SeccompBPF機製,設計一個安全的隔離環境,這是判題係統的核心,必須萬無一失……”他開始引經據典,大談特談各種安全模型和係統調用過濾的原理,完全偏離了架構討論的主題。
    林小圈試圖把話題拉回來:“陳飛,安全性確實重要,但我們第一步是先確定整體框架和模塊劃分,細節可以後麵再優化。周博瀚的架構我覺得思路是清晰的……”
    “細節決定成敗!”陳飛推了推眼鏡,語氣異常嚴肅,“如果不從最開始就考慮周全,後期重構的成本會非常高!我認為我們應該先花時間研究一下現有的開源沙盒方案,進行安全性評估……”
    周博瀚的臉色已經沉了下來,他有些不耐煩地用馬克筆敲了敲白板:“我們現在是在做一個簡易的、原型的核心模塊,不是要開發一個商用的、承受百萬級並發的係統!你說的那些東西,複雜度遠超項目要求,兩周根本實現不了!”
    “但這是正確的方向!”陳飛堅持道,“我們不能為了趕進度而犧牲代碼的質量和係統的健壯性!”
    眼看討論要陷入僵局,林小圈隻好站出來打圓場:“好了好了,這樣吧,架構大體按周博瀚的思路來,陳飛你重點關注判題邏輯和沙盒安全性的設計,我們先實現基礎功能,如果時間允許,再考慮優化安全部分,怎麽樣?”
    最終,在一種略顯壓抑的氣氛中,三人勉強達成了初步分工:周博瀚負責整體架構搭建和用戶交互模塊;林小圈負責判題邏輯的核心實現和數據庫設計;陳飛負責研究安全的代碼運行沙盒方案,並協助設計核心判題算法。
    分歧,從這一刻就已經埋下。
    項目在磕磕絆絆中推進。他們使用了Git進行版本控製,這本來是協作的利器,卻成了矛盾的放大器。
    周博瀚效率極高,很快搭好了基礎框架,並實現了用戶提交代碼的接口。他習慣小步快跑,頻繁提交。
    林小圈也穩步推進,開始編寫判題邏輯,針對不同的編程語言設計測試用例。
    而陳飛,則徹底沉浸在了他的“完美沙盒”研究中。他查閱了大量英文文獻,嚐試編譯各種底層庫,在本地虛擬機裏反複測試。幾天過去了,他除了提交了幾篇相關的論文鏈接到項目Wiki外,代碼庫裏的貢獻幾乎為零。
    第一次衝突爆發在項目開始後的第五天。周博瀚在合並林小圈提交的判題邏輯時,發現與他自己剛寫的用戶狀態更新模塊產生了衝突。
    “林小圈,你修改Judger類的接口為什麽不事先說一聲?”周博瀚在小組的即時通訊群裏質問,語氣帶著不滿。
    林小圈一愣,解釋道:“我加了兩個參數是為了傳遞更詳細的編譯錯誤信息,我覺得這樣更合理,當時你在忙架構,我就直接改了。”
    “但你沒通知我!我這邊調用的接口全錯了!”周博瀚發過來一個崩潰的表情。
    “我提交的時候寫了注釋啊……”
    “誰會每次都仔細看diff(代碼差異)?這種公共接口變動,至少要在群裏說一聲吧?”
    兩人在群裏爭執了幾句,氣氛有些僵硬。而陳飛,自始至終沒有在群裏說一句話,仿佛消失了一般。
    林小圈心裏有些委屈,也覺得周博瀚有些過於嚴苛,但他知道周博瀚說得有道理。團隊合作,溝通確實至關重要。他主動道了歉,並約定以後涉及公共模塊的修改,必須提前在群裏報備。
    然而,更大的麻煩來自陳飛。
    距離項目截止隻剩四天了,陳飛終於提交了他的第一份代碼——一個極其複雜、依賴了大量外部庫的沙盒實現雛形。周博瀚和林小圈嚐試集成,發現光是環境配置就極其繁瑣,而且與周博瀚搭建的現有架構格格不入,甚至因為引入的庫版本衝突,導致整個項目都無法編譯通過了。
    周博瀚的怒火終於爆發了。他在活動室裏,當著不少隊員的麵,直接對陳飛低吼道:“陳飛!你搞出來的這是什麽玩意兒?項目要求是簡易核心模塊!你看看你引入了多少不必要的依賴?架構完全被你打亂了!你這幾天到底在幹什麽?”
    陳飛的臉一下子漲紅了,他梗著脖子,聲音因為激動而有些發顫:“我在實現一個安全的沙盒!這是判題係統的基礎!你們那種簡單的Docker方案根本不行!”
    “不行?那你的行了嗎?連編譯都過不了!”周博瀚寸步不讓。
    “那是環境配置問題!是你們不會配置!”陳飛爭辯道。
    “我們沒時間也沒義務去研究你那個複雜無比的‘完美’方案!項目要的是能用,不是要發表學術論文!”周博瀚的話像刀子一樣。
    林小圈看著眼前這一幕,頭大如鬥。他試圖分開兩人:“別吵了!解決問題要緊!陳飛,你的方案確實有點重,我們現在時間很緊。周博瀚,你也冷靜點。”
    但這次,和事佬也不管用了。陳飛猛地合上電腦,丟下一句“道不同不相為謀!”,竟然直接背著書包離開了活動室。
    小組氣氛降到了冰點。
    那天晚上,林小圈拖著更加沉重的步伐回到家。連續幾天的熬夜討論和代碼編寫,加上今天的激烈衝突,讓他身心俱疲。
    顧無雙看到他眼下的烏青和滿臉的倦容,心疼不已:“圈圈,這幾天怎麽這麽累?項目不順利嗎?”
    林小圈歎了口氣,把團隊分工、溝通不暢、代碼衝突以及今天陳飛和周博瀚大吵一架的事情,簡單跟媽媽說了。他沒有說得太詳細,但那種無力感和 frustration(挫敗感)卻掩飾不住。
    “原來是這樣……”顧無雙若有所思,“三個人都有自己的想法和長處,湊在一起反而亂了套,是吧?”
    “嗯。”林小圈扒拉著碗裏的飯,沒什麽胃口,“感覺比一個人做累多了。周博瀚嫌陳飛不切實際,陳飛嫌我們隻顧進度不顧質量,我夾在中間……”
    一直安靜吃飯的林大強忽然開口,語氣平淡卻一針見血:“一個團隊,光有技術不夠。得有人掌舵,有人劃槳,有人瞭望。你們現在就是三條船都想當舵,能不亂嗎?”
    林小圈怔住了。爸爸的話,簡單卻深刻。他們小組,似乎缺了一個明確的“舵手”,也缺乏有效的分工和協作機製。
    “你爸說得對。”顧無雙接過話頭,“圈圈,你不是說陳飛理論很強嗎?能不能把他的長處用在對的地方?比如算法設計、測試用例設計這些?而不是讓他去負責一個他可能不擅長、或者需要大量協作的模塊?”
    媽媽的話像是一道亮光,瞬間照亮了林小圈混亂的思緒。對啊!陳飛的優勢是理論和算法,為什麽非要逼他去搞工程實現複雜的沙盒呢?讓他專注於判題邏輯的算法優化和邊界測試,豈不是更能發揮他的價值?
    第二天,林小圈找到周博瀚,把自己的想法和父母的話跟他溝通了。周博瀚冷靜下來後,也意識到昨天的衝突解決不了問題。項目還得繼續, deadline 像達摩克利斯之劍一樣懸在頭頂。
    “你說得對。”周博瀚揉了揉眉心,臉上也帶著疲憊,“是我太急了。陳飛的理論能力確實能幫上忙。現在的沙盒,先用簡單的Docker方案頂上去,安全性後期再考慮。讓他來幫我們設計更全麵的測試用例,尤其是邊界情況和性能測試,這是他擅長的。”
    兩人達成了共識。接下來,就是如何說服陳飛。
    他們找到獨自坐在圖書館角落的陳飛。這一次,林小圈沒有和稀泥,而是直接、誠懇地承認了之前溝通和分工上的問題。
    “陳飛,我們之前的分工可能不太合理,沒有充分發揮你的優勢。”林小圈看著他的眼睛說,“我和周博瀚討論過了,我們依然認為安全的沙盒很重要,但限於時間,這次項目我們先采用一個簡易方案保證基本功能。我們希望你能夠發揮你的理論特長,幫我們設計和優化核心判題算法,並且設計一套盡可能全麵的測試用例,包括各種邊界條件、極端輸入和性能測試。這部分是係統的‘大腦’,至關重要,我們倆都不如你擅長。”
    周博瀚也難得地放低了姿態,補充道:“對,判題邏輯的準確性和效率,直接決定係統好壞。這部分交給你,我們更放心。”
    陳飛緊繃的臉色,在聽到這番話後,慢慢緩和了下來。他推了推眼鏡,沉默了片刻,似乎在評估這個新提議。最終,他點了點頭,聲音雖然還是不高,但已經沒有昨天的激動:“可以。我會負責算法和測試部分。相關的設計文檔和測試用例,我會盡快給出。”
    破冰成功!
    接下來的幾天,小組的氛圍發生了微妙而積極的變化。溝通變得頻繁且更有針對性。他們建立了一個詳細的任務看板,明確每個人當前的任務、阻塞問題和下一步計劃。每日站會雖然簡短,但確保了信息同步。
    周博瀚專注於架構整合和接口聯調。
    林小圈負責具體功能的實現和Bug修複。
    而陳飛,則展現出了他理論紮實的巨大優勢。他設計了幾套針對不同算法題目的判題策略,考慮了時間、空間複雜度的權衡;他編寫的測試用例極其刁鑽,挖出了林小圈代碼裏好幾個隱藏很深的邊界條件Bug;他甚至對數據庫的索引設計提出了優化建議,提升了查詢效率。
    雖然過程中仍有小的摩擦和分歧,比如對某個API設計的不同看法,或者對某個測試用例必要性的爭論,但都在有效的溝通和相互妥協下快速解決了。他們學會了在群裏@對方,學會了使用更清晰的Git提交信息,學會了在爭論時拿出數據和邏輯,而不是情緒。
    最後四十八小時,三個人幾乎泡在活動室裏,困了就在桌子上趴一會兒,餓了就點外賣。咖啡杯和能量飲料罐堆滿了角落。鍵盤敲擊聲、低聲討論聲、解決問題後的短暫歡呼聲交織在一起。
    當他們在截止時間前最後一個小時,最終將代碼合並、並通過了所有核心測試用例時,三個人不約而同地長長舒了一口氣,彼此對望,都從對方眼中看到了如釋重負和一絲難以言喻的成就感。
    最終提交的項目,雖然距離“完美”還差得很遠,沙盒也隻是基礎版本,但核心功能完整,判題準確,性能也達到了基本要求。更重要的是,他們提交了一份清晰的項目文檔、分工說明和貢獻評估。
    雷銘在評審後,隻給了他們小組一個“良好”的評價,並在評語中寫道:“技術實現尚可,初期協作混亂,後期有所改善。記住,團隊項目的意義不在於證明個人有多強,而在於如何讓團隊變得更強。”
    這個評價很中肯,三人也都心服口服。
    項目結束後的第二天晚上,林小圈終於睡了一個好覺。第二天早上,他神清氣爽地起床,吃早飯時,顧無雙笑著問:“項目結束了?看你這臉色,結果是好的?”
    “嗯!”林小圈用力點頭,咬了一口包子,“雖然過程很曲折,但總算完成了。而且……感覺學到了很多東西,不光是技術上的。”
    他回想起這幾周的混亂、爭吵、妥協、再到最後的協同奮戰,心中感慨萬千。他明白了,真正的團隊合作,不是簡單的1+1+1=3,而是在摩擦和磨合中,找到各自最合適的位置,相互補位,最終爆發出超越個體之和的力量。
    他也第一次深切體會到,溝通、分工和妥協,這些看似與編碼無關的“軟技能”,在團隊項目中有多麽重要。
    周博瀚依舊毒舌,但關鍵時刻可靠;陳飛依舊固執,但他的嚴謹和理論深度彌補了團隊的短板;而他自己,似乎在中間起到了某種粘合劑和調和劑的作用。
    這第一次團隊合作,像一次洗禮,讓他這個習慣了單打獨鬥的“編程小天才”,真正開始向一個懂得協作的“團隊成員”蛻變。
    他看了一眼窗外湛藍的天空,深吸一口氣。奧賽隊的路還很長,未來肯定還有更多需要團隊作戰的時刻。但經曆了這一次,他覺得自己,好像又多了一點底氣和經驗。