盤)
安徽省冠再見安大。這行字在我朋友圈里躺了很久現(xiàn)在終于輪到我自己發(fā)出來。對我來說這句話有兩層意思第一層大學期間跟著實驗室隊伍拿到了安徽省賽冠軍第二層我真的要離開安徽大學開始新的階段。很多學弟學妹在實驗室里問過我競賽到底值不值得打、怎么打、拿完獎之后這些東西還有沒有用。我干脆把這幾年的路線、踩坑、復(fù)盤以及告別之前的收尾工作整理成一篇博客。如果你還在讀書正在猶豫要不要投入時間做競賽、搞項目或者準備從校園過渡到職場這篇內(nèi)容應(yīng)該比單純曬獎牌更有參考價值。1. 省冠不是終點真正值錢的是工程落地能力1.1 競賽結(jié)果只有一行榜單但備賽過程是一整套系統(tǒng)很多人看競賽看到的是“誰拿了省冠”“哪個學校又登頂了”。但真正經(jīng)歷過的人都知道榜單上的一行結(jié)果背后是一整套系統(tǒng)。這個系統(tǒng)至少包括需求理解、方案拆分、時間管理、資源預(yù)估、錯誤排查和隊友協(xié)作最后才是現(xiàn)場的代碼輸出。比賽只是把這套系統(tǒng)壓縮到了幾個小時內(nèi)讓你必須在高壓下跑完整個流程。拿最常見的備賽節(jié)奏來說最后沖刺那幾個月每一天都很像在跑一個小項目。早上起來先看昨天的日志和未解決的問題上午集中精力寫代碼或者調(diào)方案下午做模擬題或者迭代數(shù)據(jù)流程晚上再花半小時復(fù)盤當天遇到的坑。這個節(jié)奏和公司里做開發(fā)非常接近先做最小驗證再開發(fā)再測試再 review最后交付。只不過比賽把每個環(huán)節(jié)都壓得更緊容錯空間也更小。所以我在比賽結(jié)束后最大的收獲不是記住多少算法模板也不是背了多少數(shù)據(jù)公式而是知道怎么在一堆不確定因素里把任務(wù)推進下去。比賽成績是短期結(jié)果備賽過程才是長期資產(chǎn)。如果只是為了拿獎而突擊比賽結(jié)束后知識會很快遺忘如果是為了提升工程能力去比賽哪怕最后只拿了省二省三你也能帶走一套完整的做事流程。這里有個很關(guān)鍵的建議不要只盯著“我要拿第一”而是要問自己“通過這次比賽我能練習到哪些以后會長期用到的方法”這個問題想清楚投入產(chǎn)出比會高很多。1.2 拿獎之后還能帶走什么省冠帶來的最直接好處當然是簡歷上的亮點和內(nèi)心的認可。但這些都會隨著時間慢慢貶值。真正能帶走的我總結(jié)成四樣拆解問題的能力拿到一個模糊的題目先判斷限制條件再拆分模塊最后逐個擊破。調(diào)試和排查能力知道報錯之后先看哪一行日志知道數(shù)據(jù)邊界為什么會引發(fā)崩潰知道怎么在最快時間內(nèi)定位問題。團隊協(xié)作的經(jīng)驗知道什么時候該堅持自己的方案什么時候該接受隊友的替換怎么用最少的時間對齊信息。面對失敗的韌性比賽不會永遠順利環(huán)境崩了、思路錯了、時間不夠了這些場景多經(jīng)歷幾次人就不容易慌。這些能力不是比賽專屬。做課程設(shè)計、畢業(yè)設(shè)計甚至進入公司之后一樣能用。尤其是“拆解問題”和“排查能力”這兩項在面試里最容易通過一個追問暴露出來。面試官問你“遇到什么問題、怎么排查”的時候有過真實比賽經(jīng)驗的人和只背過八股的人回答的顆粒度完全不一樣。所以我的態(tài)度很明確省冠是榮譽但它不是終點。真正值錢的是這四年訓(xùn)練出來的工程落地能力。2. 從零到省冠的成長路線和資源準備2.1 先確認賽道算法、開發(fā)、硬件還是數(shù)據(jù)很多同學上來就問“我要參加什么比賽”正確的順序應(yīng)該是先確認自己的興趣方向再選合適的賽道。不同賽道的準備周期、隊友搭配和軟硬件條件都不一樣。方向核心內(nèi)容適合人群典型產(chǎn)出算法類數(shù)據(jù)結(jié)構(gòu)、算法設(shè)計、數(shù)學建模喜歡寫代碼和邏輯推導(dǎo)代碼題解、算法模板、比賽排名開發(fā)類系統(tǒng)設(shè)計、前后端、服務(wù)部署喜歡做完整可演示的產(chǎn)品Web 應(yīng)用、小程序、API 服務(wù)硬件類單片機、傳感器、電路、機器人喜歡動硬件、做實驗智能小車、嵌入式設(shè)備、作品演示數(shù)據(jù)類數(shù)據(jù)分析、爬蟲、可視化、簡單建模喜歡和數(shù)據(jù)打交道數(shù)據(jù)報表、分析報告、預(yù)測模型選擇方向前先問自己三個問題我喜歡寫代碼本身還是更喜歡用代碼解決一個具體問題我能接受長時間面對屏幕調(diào)邏輯還是更愿意動手做實驗我當前的基礎(chǔ)是更偏編程還是更偏數(shù)學、產(chǎn)品或者寫作這些問題沒有標準答案但能幫你快速排除掉不適合的選項。如果還是拿不準最有效的辦法是找往年賽題看一遍。不需要動手寫只看題目描述和獲獎作品問自己“這個題目讓我準備三個月我愿意嗎”。如果心里有抵觸那就換一個方向。方向不匹配后面堅持會非常痛苦。2.2 環(huán)境、資料和隊友怎么選確定方向之后準備環(huán)境。以開發(fā)類競賽為例一臺內(nèi)存不低于 16GB 的電腦會比較舒服因為要同時跑數(shù)據(jù)庫、前后端服務(wù)和調(diào)試工具。如果是算法類或數(shù)據(jù)類普通電腦也能起步但要注意數(shù)據(jù)集比較大的時候內(nèi)存和磁盤空間會影響效率。沒必要一上來就買頂配服務(wù)器先用自己手里的配置把流程跑通再考慮升級。資料方面常見的組合是官方文檔、往年賽題、開源項目和經(jīng)典教材。但不要囤資料很多人把時間花在“找資料”上真正動手的時間反而很少。我一般會先看三樣?xùn)|西近三年的真題、一份系統(tǒng)性的入門文檔、一個能跑通的示例項目。先把這三樣吃透比收藏幾十個鏈接更有用。隊友選擇比資料更重要。不要只找和自己關(guān)系好的人要互補。一個擅長快速寫代碼一個擅長分析問題一個擅長做文檔和展示這樣的組合比較穩(wěn)。還要看性格比賽壓力下容易急躁的人至少要搭配一個能穩(wěn)住場面的人。隊友之間不需要每個人都技術(shù)頂尖但一定要能溝通不能遇到分歧就冷戰(zhàn)。我的經(jīng)驗是第一次組隊可以先做一個小的模擬賽。模擬賽不是看成績而是看配合誰負責什么、遇到?jīng)_突怎么解決、時間不夠時先砍掉哪部分。如果模擬賽里就已經(jīng)出現(xiàn)溝通問題正式比賽會放大很多倍。最好在賽前就把分工和決策機制定好。2.3 可量化的訓(xùn)練計劃從每天兩小時到賽前沖刺訓(xùn)練計劃不能只寫“每天刷題”要有明確的數(shù)字和階段目標。我習慣把備賽周期分成三個階段。階段時間占比重點內(nèi)容判斷標準起步期30%熟悉題型、補充基礎(chǔ)、跑通最小樣例能做對中等難度的題目并在賽后復(fù)盤專項期50%針對自己和隊伍薄弱點集中訓(xùn)練單類題目的正確率和速度明顯提高沖刺期20%全真模擬、故障演練、心態(tài)調(diào)整連續(xù)兩輪模擬都能穩(wěn)定完成并輸出起步期可以每天投入一到兩小時周末再加半天的團隊討論。專項期可以增加到每天三小時左右但要注意別讓刷題變成機械勞動。每次做題后留 15 分鐘寫復(fù)盤記錄卡點、錯誤原因和優(yōu)化空間。沖刺期一定要模擬“比賽當天的狀態(tài)”包括時間限制、平臺卡頓甚至斷網(wǎng)的情況提前練怎么應(yīng)對。這里最容易被忽略的是復(fù)盤。刷一百道題不復(fù)盤效果不如刷二十道題并認真總結(jié)。復(fù)盤不是把代碼抄一遍而是回答三個問題我為什么卡住下一次怎么避免有沒有更優(yōu)的思路我會在復(fù)盤文檔里列一個簡單的表格日期、題目、卡點、原因、改進、用時。到了賽前翻這個表格比重新刷題更有效。3. 比賽、項目和畢業(yè)設(shè)計如何共用一套方法3.1 用最小樣例驗證核心風險無論是比賽題、課程設(shè)計還是畢業(yè)設(shè)計我踩過最大的坑就是“最后才發(fā)現(xiàn)核心方案不可行”。以后基本都會用最小樣例先驗證核心風險。舉個例子如果題目要求對大量數(shù)據(jù)進行實時處理不要一開始就寫完整流程而是先構(gòu)造一個小數(shù)據(jù)集把輸入、處理、輸出跑通確認核心算法和數(shù)據(jù)結(jié)構(gòu)的性能可以接受。如果做一個 Web 系統(tǒng)先寫一個最簡單的頁面和接口確認端口、依賴和部署方式?jīng)]問題再逐步加功能。這個習慣對比賽尤其重要?,F(xiàn)場賽時間有限你不可能把一個龐大方案完整落地后再測試。先把最不確定的風險點驗證掉后面寫代碼才會穩(wěn)。這也是很多經(jīng)驗豐富的選手會把“讀題”和“拆解”放在最前面而不是立刻動手寫代碼的原因。我在備賽時給自己定過一條規(guī)則拿到題目后先花 10 分鐘寫一個“最小可行思路”。不需要完整代碼只需要寫出輸入、輸出、核心算法和可能的風險點。如果這一步能清晰寫出來再開始動手如果寫不出來說明理解還不夠需要繼續(xù)讀題。3.2 版本管理、日志和自動化測試從第一天就要做很多學生在自己做的小項目里沒有版本管理覺得“就我一個寫不需要”。但比賽和項目一旦進入多人協(xié)作或者迭代到第三版之后沒有版本管理就會非常痛苦。哪怕是單人項目我也建議從第一天就使用 Git至少把每次改動留一個記錄。最簡單的一組命令是這樣git init git add . git commit -m feat: 完成最小可運行樣例 git log --oneline不要覺得用 Git 會浪費時間。比賽現(xiàn)場如果改壞了代碼有版本記錄可以直接回退。比重新寫一遍快得多。如果和隊友協(xié)作還可以用分支隔離不同模塊避免互相覆蓋。日志看起來簡單但真正遇到問題的時候日志能幫你省下一大半時間。我給自己定的要求是關(guān)鍵分支打印信息輸入輸出留痕跡程序異常捕獲后記錄堆棧。這樣不管是在比賽現(xiàn)場還是答辯前都能快速定位問題。自動化測試聽起來很正式但你可以從很小的規(guī)模開始。寫一個測試腳本固定驗證輸入輸出是否正確每改一次代碼就跑一遍。比賽里很多隊伍不是輸在不會寫而是輸在“改一處代碼導(dǎo)致另一處功能崩了”。自動化測試能把這個風險降下來。至少對核心函數(shù)做一組回歸測試。3.3 參數(shù)調(diào)優(yōu)和資源邊界別在最后一天才壓榨性能如果你做的比賽涉及模型調(diào)參、并發(fā)配置、數(shù)據(jù)庫優(yōu)化這些內(nèi)容最忌諱的事情就是把性能優(yōu)化放到最后一天。因為性能問題往往是多方面因素疊加的數(shù)據(jù)量、內(nèi)存、緩存、網(wǎng)絡(luò)、參數(shù)設(shè)置任何一個環(huán)節(jié)都可能影響最終結(jié)果。我更建議的做法是前期先把功能做對中期做一次性能摸底后期只針對瓶頸做優(yōu)化。比如先用默認參數(shù)跑一遍記錄耗時和資源占用然后試著調(diào)整關(guān)鍵參數(shù)看結(jié)果改善是否明顯如果改善不大就優(yōu)先處理輸入格式、循環(huán)次數(shù)、緩存策略這些更基礎(chǔ)的問題。另外要給自己設(shè)定一個資源邊界。比如“這個任務(wù)最多花三十秒、最多增加 512MB 內(nèi)存、最多允許 5% 的失敗率”。沒有邊界就沒有判斷標準很容易無限調(diào)參陷入自嗨。這里有一個實操方式每次調(diào)參只改一個變量記錄下運行時間和結(jié)果質(zhì)量。不要一次改好幾個參數(shù)否則出了問題很難判斷是誰導(dǎo)致的。把每次實驗的參數(shù)和結(jié)果放進表格最后回頭看你會很清楚哪些調(diào)整真正有效哪些只是心理安慰。4. 賽場上的判斷標準和失敗排查順序4.1 遇到問題先看輸入和邊界條件比賽和開發(fā)里最常見的錯誤其實不是邏輯本身而是對輸入和邊界條件的假設(shè)錯了。數(shù)組越界、空值、極端值、編碼格式、文件路徑這些都是高頻問題。我自己的排查順序是先看輸入數(shù)據(jù)再看代碼邏輯輸入是否完整、格式是否符合預(yù)期。是否存在空值、空文件、特殊字符、超長字符串。邊界條件是否覆蓋最小值、最大值、零值、負數(shù)、重復(fù)項。輸出格式是否和題目要求一致空格、換行、小數(shù)點精度都不能漏。代碼中是否對異常輸入做了保護還是直接拋錯崩潰。這套順序在比賽現(xiàn)場很管用。很多時候你以為算法有 bug結(jié)果只是數(shù)據(jù)文件讀錯了或者把樣例里的測試集當成完整測試集。先確認輸入再進入代碼邏輯會少走很多彎路。4.2 五分鐘原則卡住不要死磕準備比賽的時候老師跟我們說的一句話讓我印象很深卡住了先退出來不要死磕。比賽是有時間成本的行為每道題都有價值。我后來把這個原則總結(jié)為“五分鐘原則”如果一個問題五到十分鐘還沒有進展就停下來重新讀題、查看日志、換個思路或者先做其他部分。這樣做不是為了逃避而是避免陷入“越調(diào)越亂”的狀態(tài)。很多 bug 是你在情緒緊張時改出來的。先離開那一段代碼做點別的再回來往往一眼就能看到問題。當然五分鐘不是機械的數(shù)字要根據(jù)題目難度和時間預(yù)算調(diào)整。如果是最后半小時只剩一道關(guān)鍵題那就要合理分配剩余時間。但大方向是不要讓一個卡點吃掉全部時間。這個原則在項目里也一樣。代碼運行不通過的時候越急越容易亂改。先冷靜下來把現(xiàn)象寫清楚再開始排查效率會高很多。4.3 結(jié)果的可持續(xù)性怎么驗證比賽中的“通過”不代表“完全正確”。有些樣例能過是因為你剛好滿足小數(shù)據(jù)的情況換成大數(shù)據(jù)、邊界條件結(jié)果可能就不對了。所以我會給自己增加一步驗證把輸出和預(yù)期放在一起做 diff跑一次邊界用例再重復(fù)跑兩次看結(jié)果是否穩(wěn)定。我通常會做一個簡單的驗收清單檢查項標準通過正常輸入結(jié)果符合預(yù)期是邊界輸入不崩潰合理處理是重復(fù)運行結(jié)果一致是異常輸入報錯信息清楚是性能達標耗時和資源占用可接受是這個思路在項目里同樣重要。一個功能偶爾能成功不等于穩(wěn)定。如果連續(xù)跑五次只有兩次成功就不能算完成。比較好的標準是相同輸入下結(jié)果一致不同輸入下結(jié)果符合預(yù)期異常輸入下程序會給出明確的錯誤提示而不是直接崩潰?,F(xiàn)場答辯或面試時如果你能說出“我做了哪些驗證、失敗率是多少、邊界情況怎么處理”比只說“我做了一個功能”要可信得多。5. 告別安大之前的收尾工作5.1 代碼、文檔和交接清單當“再見安大”開始倒計時我第一件事不是收拾行李而是把電腦里的代碼和文檔整理好。比賽和項目留下的代碼如果不整理過三個月連自己都看不懂更不要說交給學弟學妹。我會按項目建目錄每個項目包含四個部分源碼按模塊拆分加上必要的 README。數(shù)據(jù)分為原始數(shù)據(jù)、樣例數(shù)據(jù)、輸出數(shù)據(jù)注明來源和格式。文檔立項說明、技術(shù)方案、答辯 PPT、復(fù)盤記錄。部署/運行說明環(huán)境要求、依賴版本、啟動命令、常見問題。目錄結(jié)構(gòu)大概長這樣project/ ├── README.md ├── src/ ├── data/ │ ├── raw/ │ ├── sample/ │ └── output/ ├── docs/ └── scripts/寫文檔不需要很宏大但一定要讓一個從沒接觸過的人能照著運行起來。判斷標準是另一個人拿到目錄后能否在不問你的情況下復(fù)現(xiàn)結(jié)果如果可以說明交接基本合格。如果不可以說明還欠整理。5.2 把經(jīng)歷轉(zhuǎn)成簡歷和面試表達拿完獎之后很容易進入一個誤區(qū)在簡歷上堆一堆獎項名字。但面試官更關(guān)心的是你在比賽里做了什么、怎么解決問題。獎項只能幫你獲得一次面試機會能不能留下看的是你的真實能力。我建議每段經(jīng)歷都寫成“背景 - 任務(wù) - 行動 - 結(jié)果”的結(jié)構(gòu)并且要有量化信息。例如背景省賽隊伍負責數(shù)據(jù)分析模塊。任務(wù)處理 5 萬條原始日志提取關(guān)鍵特征。行動編寫清洗腳本建立輸入輸出規(guī)范加入異常檢測。結(jié)果樣例數(shù)據(jù)的處理時間明顯縮短最終隊伍獲得省冠。面試表達也要練。不要只是背項目描述而是準備三四個“為什么”的問題為什么選這個方案遇到什么問題怎么排查如果重新做會怎么改這些比直接問你“會什么”更能體現(xiàn)出真實水平。比賽里的復(fù)盤記錄這時候就是很好的素材庫。5.3 開源共享給下一屆留下可持續(xù)資源臨走前我還做了一件事把比賽過程中沉淀的模板、工具腳本、復(fù)盤模板和資料清單整理成一份共享資源放在實驗室團隊內(nèi)部并寫了一個簡單的索引。下一屆選手不用從零開始可以直接站在已經(jīng)驗證過的流程上做改進。這種共享不一定是寫一個大開源項目哪怕只是一個代碼片段、一份踩坑清單、一個選題列表對后來者都很有價值。關(guān)鍵在于“可持續(xù)”不是把垃圾打包丟給學弟學妹而是分類清楚、有說明、能運行。這個過程本身也在鍛煉文檔能力和結(jié)構(gòu)化表達。共享資源里最重要的是索引。沒有索引的資源庫別人根本不知道從哪里看起。我一般會在第一個文件里寫明這個倉庫有什么、按什么順序看、哪些內(nèi)容已經(jīng)過時、哪些還在維護。這樣后來者可以快速找到自己需要的東西。6. 如果重新來一次我會提前做的幾件事6.1 盡早積累自己的代碼庫如果時間能倒流我會在第一次接觸競賽時就開始建立個人代碼庫。不是那種隨手亂放而是分好類常用算法模板、輸入輸出處理、調(diào)試腳本、圖表生成、自動化工具。這樣每次寫新題的時候可以更快地復(fù)用而不是重復(fù)造輪子。代碼庫不需要一開始就很完善。先放一個最簡單的排序、一個二分、一個 DFS寫清楚適用場景和注意事項。遇到新技巧就補進去定期重構(gòu)。到了沖刺階段你會發(fā)現(xiàn)這個庫比任何資料都有含金量因為它是你親自驗證過的。我會把代碼庫分成幾個目錄比如codebase/ ├── algorithms/ ├── io_utils/ ├── debug_scripts/ ├── templates/ └── README.md這個習慣的好處很快就能看到。比賽現(xiàn)場時間緊張如果有一個常用模板可以省去很多重復(fù)調(diào)試時間。更重要的是整理代碼庫的過程會逼你理解每個模板的原理而不是簡單復(fù)制粘貼。6.2 多做跨學科與產(chǎn)品化嘗試比賽和課程設(shè)計往往會限定在一個技術(shù)框架里但真實問題往往跨學科。如果重來一次我會多和不同專業(yè)的同學組隊嘗試把一個技術(shù)原型包裝成一個小產(chǎn)品哪怕只是做一個能演示的網(wǎng)頁、一個能跑的機器模型。這個過程中的用戶視角、需求理解、展示能力都是單純寫代碼練不到的。另外技術(shù)再好也要學會怎么講。做產(chǎn)品化嘗試會讓你被迫練習“向外行解釋你的工作”這項能力在答辯、面試、路演里太重要了。你可能是隊伍里最會寫代碼的人但如果不能在五分鐘內(nèi)讓別人聽懂你的方案很多機會都會溜走。我見過一些技術(shù)很強的同學簡歷投出去之后面試并不順利原因不是代碼能力不行而是表達沒有邏輯。跨學科組隊和產(chǎn)品化嘗試是練習表達邏輯的好機會。6.3 穩(wěn)定的作息和心理建設(shè)最后一項聽起來不技術(shù)但我真的建議提前重視保持穩(wěn)定的作息給心理留緩沖。比賽和項目沖刺期熬夜是常態(tài)但如果長期熬夜、焦慮、不運動效率和狀態(tài)一定會下降。現(xiàn)場賽也好答辯也罷比拼的往往不是誰突擊得更多而是誰的狀態(tài)更穩(wěn)定。我自己的經(jīng)驗是賽前一周不再做難題只做基礎(chǔ)題和模擬流程每天保證足夠的睡眠把“能完賽”和“拿到獎”分開對待。心理建設(shè)不是告訴自己“一定贏”而是提前想好“如果現(xiàn)場崩了我按什么順序處理”。比如提前準備好一套應(yīng)急清單如果代碼庫崩潰了怎么辦、如果隊友臨時聯(lián)系不上怎么辦、如果某個功能沒有做出來怎么辦。把這些預(yù)案寫下來現(xiàn)場遇到問題就會從容很多。沒有預(yù)案的時候人會憑本能做事有了預(yù)案才能按計劃行動。離開安大的那天我最后看了一眼實驗室的工位。桌面已經(jīng)清空但電腦里那些代碼和文檔還在它們會繼續(xù)被下一屆使用?,F(xiàn)在再回頭看“安徽省冠再見安大”這行字我反而覺得這不是終點。省冠給了我一小段高光安大給了我一整套方法論而未來真正要用的是后者。如果你也正在準備一場比賽、一個項目或者一次告別希望這篇復(fù)盤能幫你少走一點彎路至少能在離開一個地方的時候留下一些別人能接著用的東西。