易2023校招ML算法崗提前批筆試:算法基礎(chǔ)與機(jī)器學(xué)習(xí)備考全攻略)
1. 從投遞到筆試提前批的整體情況與備考定位1.1 網(wǎng)易提前批筆試到底考什么先說說整體感受。網(wǎng)易2023校招機(jī)器學(xué)習(xí)算法工程師的提前批筆試和正式批相比有個(gè)很明顯的區(qū)別題量不算大但覆蓋面非常廣而且時(shí)間緊。我當(dāng)時(shí)做完第一感受是這不光是在考你會(huì)不會(huì)調(diào)包調(diào)參而是在考你的計(jì)算機(jī)基礎(chǔ)功底和算法思維底子。整個(gè)筆試分為幾個(gè)部分單選、多選、編程題外加一部分機(jī)器學(xué)習(xí)相關(guān)的理論問答。其中單選和多選涵蓋了數(shù)據(jù)結(jié)構(gòu)、操作系統(tǒng)、計(jì)算機(jī)網(wǎng)絡(luò)以及機(jī)器學(xué)習(xí)基礎(chǔ)理論。編程題則偏向經(jīng)典的算法題比如排序、字符串匹配、圖論搜索這類。這個(gè)崗位的特點(diǎn)是算法工程師首先得是合格的工程師。很多同學(xué)會(huì)有一個(gè)誤區(qū)覺得機(jī)器學(xué)習(xí)算法工程師筆試就應(yīng)該狂考神經(jīng)網(wǎng)絡(luò)、Transformer、損失函數(shù)推導(dǎo)但實(shí)際上筆試?yán)飻?shù)據(jù)結(jié)構(gòu)與算法的權(quán)重非常高甚至比機(jī)器學(xué)習(xí)理論考察的比例還高。網(wǎng)易的筆試風(fēng)格也延續(xù)了大廠算法崗的一貫思路基礎(chǔ)不牢地動(dòng)山搖。你如果只背了一堆模型面試題但代碼能力跟不上編程題就會(huì)卡住。提前批和正式批的另一個(gè)區(qū)別是提前批的筆試通過后會(huì)直接進(jìn)入面試流程面試官會(huì)拿著你的筆試成績來評(píng)估你的技術(shù)深度所以筆試表現(xiàn)直接決定后續(xù)面試的起評(píng)。我當(dāng)時(shí)是在牛客網(wǎng)的系統(tǒng)上完成的筆試全程攝像頭監(jiān)控雙機(jī)位倒計(jì)時(shí)嚴(yán)格整個(gè)氛圍還是比較緊張的。1.2 我的備考時(shí)間線與方法論我是提前大概兩周開始集中準(zhǔn)備的。兩周時(shí)間不算長所以策略很重要。核心原則是花最少的時(shí)間拿住基礎(chǔ)分再花精力突破難點(diǎn)。具體時(shí)間分配是這樣的前三天用來過數(shù)據(jù)結(jié)構(gòu)核心考點(diǎn)包括數(shù)組、鏈表、棧、隊(duì)列、樹、圖、堆、哈希表第四到第七天集中刷排序、搜索、動(dòng)態(tài)規(guī)劃和字符串匹配的經(jīng)典題第八到第十天過機(jī)器學(xué)習(xí)理論基礎(chǔ)重點(diǎn)看模型原理和損失函數(shù)推導(dǎo)最后三四天用來做模擬筆試完全按照考試時(shí)間、題量和難度來模擬。最后這個(gè)環(huán)節(jié)我強(qiáng)烈建議不要省略因?yàn)楣P試考的不只是會(huì)不會(huì)還有在有限時(shí)間內(nèi)能不能做出來模擬能幫你找到自己的做題節(jié)奏。關(guān)于刷題平臺(tái)主流的是LeetCode和???。牛客網(wǎng)有一個(gè)很大的優(yōu)勢(shì)它上面有大量大廠歷年真題特別是網(wǎng)易的真題非常多可以直接去搜“網(wǎng)易2023校招筆試”相關(guān)的題庫來做。LeetCode則適合專項(xiàng)突破按標(biāo)簽刷比如動(dòng)態(tài)規(guī)劃就集中刷動(dòng)態(tài)規(guī)劃不要今天刷一道鏈表明天刷一道貪心零散刷題的效率很低。2. 數(shù)據(jù)結(jié)構(gòu)與算法筆試的基本盤2.1 排序算法看起來送分其實(shí)全是坑排序算法幾乎是每場(chǎng)大廠筆試都會(huì)出的題網(wǎng)易也不例外。但它的考察方式并不只是讓你寫一個(gè)快速排序而是通過選擇題或者代碼填空題來考察你對(duì)排序算法底層原理的掌握程度。比如??嫉膯栴}有快速排序在最壞情況下的時(shí)間復(fù)雜度是多少、什么情況下會(huì)發(fā)生、堆排序建堆的時(shí)間復(fù)雜度、歸并排序的空間復(fù)雜度、哪些排序算法是穩(wěn)定的。我復(fù)習(xí)的時(shí)候習(xí)慣用一個(gè)表格把常見的排序算法整理清楚這個(gè)習(xí)慣強(qiáng)烈推薦給大家。排序算法平均時(shí)間復(fù)雜度最壞時(shí)間復(fù)雜度空間復(fù)雜度穩(wěn)定性冒泡排序O(n2)O(n2)O(1)穩(wěn)定選擇排序O(n2)O(n2)O(1)不穩(wěn)定插入排序O(n2)O(n2)O(1)穩(wěn)定希爾排序O(n^1.3)O(n2)O(1)不穩(wěn)定歸并排序O(n log n)O(n log n)O(n)穩(wěn)定快速排序O(n log n)O(n2)O(log n)不穩(wěn)定堆排序O(n log n)O(n log n)O(1)不穩(wěn)定如果筆試中遇到讓手寫排序算法的題我個(gè)人的經(jīng)驗(yàn)是優(yōu)先寫快速排序的隨機(jī)化版本。它綜合表現(xiàn)最好平均時(shí)間復(fù)雜度是O(n log n)而且代碼量適中。但要注意如果題目明確要求穩(wěn)定性那就得寫歸并排序快排是不穩(wěn)定的。另外還有一個(gè)容易被忽略的細(xì)節(jié)快速排序的最壞情況是輸入已經(jīng)有序或基本有序的時(shí)候因?yàn)槊看蝡artition只會(huì)把數(shù)組分成一邊為空、另一邊為n-1的極度不平衡狀態(tài)此時(shí)遞歸深度會(huì)退化為O(n)總時(shí)間復(fù)雜度是O(n2)。解決方法就是隨機(jī)選取基準(zhǔn)元素或者采用三數(shù)取中法來選基準(zhǔn)。我復(fù)習(xí)的時(shí)候反復(fù)寫了好幾遍堆排序因?yàn)樗亲钊菀资謱懗鲥e(cuò)的排序。核心在于理解siftDown的過程其實(shí)代碼本身并不復(fù)雜。關(guān)鍵是理解建堆時(shí)為什么要從最后一個(gè)非葉子節(jié)點(diǎn)開始向上調(diào)整以及排序時(shí)為什么要把堆頂元素交換到數(shù)組末尾。// 堆排序核心代碼C void siftDown(vectorint nums, int i, int n) { while (i n) { int left 2 * i 1; int right 2 * i 2; int largest i; if (left n nums[left] nums[largest]) largest left; if (right n nums[right] nums[largest]) largest right; if (largest i) break; swap(nums[i], nums[largest]); i largest; } } void heapSort(vectorint nums) { int n nums.size(); // 建堆從最后一個(gè)非葉子節(jié)點(diǎn)開始向上調(diào)整 for (int i n / 2 - 1; i 0; i--) { siftDown(nums, i, n); } // 排序把堆頂最大值交換到末尾然后調(diào)整堆 for (int i n - 1; i 0; i--) { swap(nums[0], nums[i]); siftDown(nums, 0, i); } }2.2 字符串匹配KMP的前世今生KMP算法是網(wǎng)易筆試中出現(xiàn)頻率非常高的考點(diǎn)甚至可以說是必考。筆試中不僅會(huì)考你KMP的next數(shù)組怎么求還會(huì)給你一個(gè)模式串讓你直接填next數(shù)組的值。比如題里給了一個(gè)典型的模式串p abacaba讓你寫出它的next數(shù)組這就考得非常細(xì)了。next數(shù)組的定義不同教材略有差異。這里以常見的“next[i]表示p[0...i-1]的最長相等前后綴長度”這個(gè)定義為例來講解。對(duì)于模式串a(chǎn)bacabanext[0] -1通常定義邊界值當(dāng)i1時(shí)考察子串a(chǎn)最長相等前后綴長度為0所以next[1]0當(dāng)i2時(shí)考察子串a(chǎn)b沒有相等前后綴next[2]0當(dāng)i3時(shí)考察子串a(chǎn)ba前綴a等于后綴a長度為1next[3]1當(dāng)i4時(shí)考察子串a(chǎn)bac沒有相等前后綴next[4]0當(dāng)i5時(shí)考察子串a(chǎn)baca前綴a等于后綴a長度為1next[5]1當(dāng)i6時(shí)考察子串a(chǎn)bacab前綴ab等于后綴ab長度為2next[6]2當(dāng)i7時(shí)考察子串a(chǎn)bacaba前綴aba等于后綴aba長度為3next[7]3所以next數(shù)組是[-1, 0, 0, 1, 0, 1, 2, 3]。如果筆試中遇到next數(shù)組的填空題我建議用“前綴后綴最長匹配”這個(gè)樸素的方法來求雖然慢但不容易出錯(cuò)。而在實(shí)際寫KMP匹配代碼的時(shí)候?yàn)榱诵阅芤话阌脙?yōu)化后的nextval數(shù)組它考慮了字符相等時(shí)的特殊情況。// KMP算法核心代碼C vectorint getNext(const string p) { int n p.size(); vectorint next(n 1, 0); next[0] -1; int i 0, j -1; while (i n) { if (j -1 || p[i] p[j]) { i; j; // 優(yōu)化如果p[i] p[j]則next[i] next[j] if (i n p[i] ! p[j]) next[i] j; else next[i] next[j]; } else { j next[j]; } } return next; } int kmp(const string s, const string p) { int i 0, j 0; vectorint next getNext(p); int sn s.size(), pn p.size(); while (i sn j pn) { if (j -1 || s[i] p[j]) { i; j; } else { j next[j]; } } return j pn ? i - j : -1; }這里有一個(gè)非常容易踩的坑next數(shù)組求的是模式串自身的匹配關(guān)系它的核心價(jià)值在于匹配失敗時(shí)不需要回退文本串的指針。為什么KMP能把時(shí)間復(fù)雜度優(yōu)化到O(nm)因?yàn)楫?dāng)一次匹配失敗時(shí)它利用next數(shù)組把模式串右移跳過了那些必然不匹配的位置。如果你不理解這個(gè)“跳過”的過程寫出來的代碼很容易出錯(cuò)。2.3 圖論與搜索從Dijkstra到二分圖HK算法大廠筆試的編程題里圖論算法也是???。網(wǎng)易提前批雖然不一定會(huì)出特別難的圖論題但基礎(chǔ)的圖論算法你得熟練掌握。高頻考點(diǎn)包括Dijkstra求最短路、拓?fù)渑判?、并查集、以及二分圖相關(guān)的算法。Dijkstra算法是經(jīng)典的單源最短路徑算法適用于邊權(quán)非負(fù)的圖。它的核心思想是貪心每次從未確定的節(jié)點(diǎn)中選一個(gè)距離最小的加入已確定集合然后松弛它的鄰居。樸素實(shí)現(xiàn)的時(shí)間復(fù)雜度是O(V2)用優(yōu)先隊(duì)列優(yōu)化后可以達(dá)到O((VE) log V)。筆試中如果數(shù)據(jù)量超過10^4個(gè)節(jié)點(diǎn)就一定要用優(yōu)先隊(duì)列實(shí)現(xiàn)否則會(huì)超時(shí)。熱搜詞里提到了“二分圖 HK算法”這個(gè)在算法崗筆試中屬于進(jìn)階考點(diǎn)。HK算法全稱Hopcroft-Karp算法是在匈牙利算法基礎(chǔ)上用BFS和DFS結(jié)合來求二分圖最大匹配。核心思路是先用BFS把匹配關(guān)系分層構(gòu)建出增廣路再用DFS沿著增廣路進(jìn)行匹配擴(kuò)展。它的時(shí)間復(fù)雜度是O(E√V)比樸素的匈牙利算法O(VE)快很多。雖然網(wǎng)易筆試直接考HK算法的概率不高但二分圖匹配的基本概念還是可能出現(xiàn)在選擇題里的比如“二分圖的最大匹配數(shù)等于什么”“匈牙利算法的原理是什么”等等。還有一個(gè)容易被忽略但很重要的數(shù)據(jù)結(jié)構(gòu)是并查集。筆試中很多看似復(fù)雜的題目比如判斷圖中有多少個(gè)連通分量、判斷兩個(gè)節(jié)點(diǎn)是否相連本質(zhì)上都可以用并查集解決。并查集的代碼很簡短但路徑壓縮和按秩合并這兩個(gè)優(yōu)化是必須掌握的。// 并查集核心代碼C class UnionFind { private: vectorint parent, rank; public: UnionFind(int n) { parent.resize(n); rank.resize(n, 0); for (int i 0; i n; i) parent[i] i; } int find(int x) { if (parent[x] ! x) parent[x] find(parent[x]); // 路徑壓縮 return parent[x]; } void unite(int x, int y) { int rx find(x), ry find(y); if (rx ry) return; if (rank[rx] rank[ry]) { parent[rx] ry; } else if (rank[rx] rank[ry]) { parent[ry] rx; } else { parent[ry] rx; rank[rx]; } } };2.4 貪心與動(dòng)態(tài)規(guī)劃送分題與送命題這兩類算法題是筆試編程題的核心。貪心算法相對(duì)容易只要你能證明局部最優(yōu)能推出全局最優(yōu)代碼往往非常短。但難的是什么時(shí)候用貪心。我總結(jié)的經(jīng)驗(yàn)是如果題目滿足兩個(gè)條件——每一步選擇都不會(huì)影響后面的選擇空間、每一步都有明確的最優(yōu)選擇標(biāo)準(zhǔn)——那大概率是貪心。動(dòng)態(tài)規(guī)劃則是另一個(gè)極端知道是DP題但寫不出狀態(tài)轉(zhuǎn)移方程是筆試中最痛苦的事情。網(wǎng)易筆試動(dòng)態(tài)規(guī)劃的考察范圍很廣從最基礎(chǔ)的背包問題、最長公共子序列到復(fù)雜的狀態(tài)壓縮DP、樹形DP都有可能出現(xiàn)。我的建議是短時(shí)間內(nèi)優(yōu)先掌握這幾類線性DP最大子數(shù)組和、最長遞增子序列、最長公共子序列區(qū)間DP石子合并、矩陣鏈乘背包DP0-1背包、完全背包樹形DP樹的最大獨(dú)立集、樹的直徑復(fù)習(xí)動(dòng)態(tài)規(guī)劃的核心是理解狀態(tài)定義和轉(zhuǎn)移方程。比如最長遞增子序列樸素DP的時(shí)間復(fù)雜度是O(n2)但用貪心加二分的思路維護(hù)一個(gè)tail數(shù)組記錄長度為i的遞增子序列的最小末尾值可以優(yōu)化到O(n log n)。筆試中如果數(shù)據(jù)量很大必須用優(yōu)化版本。3. 機(jī)器學(xué)習(xí)理論基礎(chǔ)模型、損失與優(yōu)化3.1 經(jīng)典模型的原理考察從樸素貝葉斯到集成學(xué)習(xí)筆試選擇題中機(jī)器學(xué)習(xí)理論的考察不會(huì)像面試那樣深入讓你手推公式但基礎(chǔ)概念和原理必須扎實(shí)。高頻考點(diǎn)集中在樸素貝葉斯、邏輯回歸、SVM、決策樹、隨機(jī)森林、GBDT、XGBoost等經(jīng)典模型的核心原理和適用場(chǎng)景。樸素貝葉斯??嫉氖撬摹皸l件獨(dú)立假設(shè)”以及貝葉斯公式的應(yīng)用。它假設(shè)特征之間相互獨(dú)立雖然現(xiàn)實(shí)數(shù)據(jù)中很難滿足這個(gè)假設(shè)但它在文本分類等場(chǎng)景下仍然表現(xiàn)不錯(cuò)。做題時(shí)經(jīng)常會(huì)遇到“給定先驗(yàn)概率和條件概率計(jì)算某個(gè)樣本屬于哪個(gè)類”的計(jì)算題這種題一定要細(xì)心尤其是多個(gè)條件概率相乘的時(shí)候別算錯(cuò)小數(shù)位。SVM的考點(diǎn)集中在最大間隔的思想、支持向量是什么、軟間隔與懲罰參數(shù)C的作用、核函數(shù)的作用。核函數(shù)是一個(gè)容易被混淆的知識(shí)點(diǎn)它本質(zhì)上解決的是在高維空間計(jì)算內(nèi)積的復(fù)雜度問題而不是說把數(shù)據(jù)映射到高維就一定能線性可分。常見的核函數(shù)包括線性核、多項(xiàng)式核、高斯核RBF核和sigmoid核高斯核是實(shí)際中最常用的因?yàn)樗鼘?duì)應(yīng)無限維映射表達(dá)能力更強(qiáng)但也更容易過擬合。集成學(xué)習(xí)的考點(diǎn)有兩個(gè)方向Bagging和Boosting的區(qū)別。Bagging的代表是隨機(jī)森林每個(gè)基學(xué)習(xí)器并行訓(xùn)練用投票或平均的方式組合結(jié)果目的是降低方差Boosting的代表是AdaBoost和GBDT基學(xué)習(xí)器串行訓(xùn)練每個(gè)學(xué)習(xí)器都關(guān)注前面學(xué)習(xí)器犯錯(cuò)的樣本目的是降低偏差。這個(gè)區(qū)別是選擇題的???。3.2 損失函數(shù)與優(yōu)化算法理解比背公式更重要損失函數(shù)是機(jī)器學(xué)習(xí)理論筆試的另一大塊。核心損失函數(shù)包括均方誤差MSE、交叉熵?fù)p失、合頁損失、指數(shù)損失等。MSE對(duì)應(yīng)的是回歸問題它有一個(gè)特點(diǎn)是當(dāng)誤差較大時(shí)梯度也大對(duì)離群點(diǎn)比較敏感。所以如果數(shù)據(jù)中有明顯的異常值可以用MAE平均絕對(duì)誤差來替代它對(duì)離群點(diǎn)的魯棒性更好。交叉熵?fù)p失是分類問題中最常用的損失函數(shù)它的推導(dǎo)源于最大似然估計(jì)。對(duì)于二分類問題交叉熵?fù)p失可以寫成L -[y * log(p) (1 - y) * log(1 - p)]其中p是模型預(yù)測(cè)樣本屬于正類的概率。為什么分類問題一般不使用MSE而使用交叉熵因?yàn)镸SE在結(jié)合sigmoid激活函數(shù)時(shí)由于sigmoid在兩端飽和導(dǎo)致梯度非常小訓(xùn)練會(huì)非常慢而交叉熵與softmax結(jié)合時(shí)梯度形式是(p - y)不會(huì)出現(xiàn)梯度消失的問題。優(yōu)化算法方面從最基礎(chǔ)的梯度下降到目前主流的Adam每個(gè)算法都有筆試考點(diǎn)。梯度下降有三種形式批量梯度下降BGD、隨機(jī)梯度下降SGD、小批量梯度下降Mini-batch GD它們的區(qū)別在于每次更新參數(shù)時(shí)用多少數(shù)據(jù)來計(jì)算梯度。解決過擬合的正則化手段L1和L2的區(qū)別也是??键c(diǎn)L1正則化產(chǎn)生稀疏解因?yàn)樗葍r(jià)于在參數(shù)上施加Laplace先驗(yàn)L2正則化產(chǎn)生較小的參數(shù)但不至于為0因?yàn)樗葍r(jià)于施加Gaussian先驗(yàn)。3.3 模型評(píng)估與調(diào)參這些細(xì)節(jié)決定成敗模型評(píng)估也是筆試中的高頻考察方向。核心考點(diǎn)包括準(zhǔn)確率、精確率、召回率、F1、ROC曲線和AUC。這里有一個(gè)非常容易混淆的點(diǎn)精確率Precision和召回率Recall的區(qū)別。精確率是“預(yù)測(cè)為正類的樣本中真正為正類的比例”召回率是“真實(shí)為正類的樣本中被正確預(yù)測(cè)為正類的比例”。用一個(gè)簡單的例子來理解假設(shè)有100個(gè)病人其中10個(gè)人真的生病了模型預(yù)測(cè)出8個(gè)人有病但這8個(gè)人中只有6個(gè)人真的有病。那么精確率是6/875%召回率是6/1060%。當(dāng)兩者出現(xiàn)矛盾時(shí)可以用F1分?jǐn)?shù)來綜合衡量它是精確率和召回率的調(diào)和平均數(shù)。ROC曲線和AUC的考點(diǎn)在于理解它們的含義。ROC曲線的橫軸是假正例率FPR縱軸是真正例率TPRAUC是ROC曲線下的面積。AUC表示隨機(jī)給定一個(gè)正樣本和一個(gè)負(fù)樣本模型將正樣本排在負(fù)樣本前面的概率。AUC越接近1模型性能越好AUC0.5說明模型沒有判別能力。還有一個(gè)容易被忽略但近幾年考得越來越多的點(diǎn)樣本不均衡問題如何處理。常見方法包括過采樣SMOTE算法、欠采樣、修改損失函數(shù)中正負(fù)樣本的權(quán)重、使用Focal Loss等。網(wǎng)易筆試可能會(huì)以選擇題形式考察這些策略的基本原理。4. 手撕代碼編程題實(shí)操全過程4.1 一個(gè)完整的編程題示例與AC代碼編程題是筆試中最拉分、也最考驗(yàn)綜合能力的部分。我在準(zhǔn)備網(wǎng)易提前批筆試時(shí)把??蜕辖甑木W(wǎng)易真題編程題都刷了一遍發(fā)現(xiàn)它的命題風(fēng)格比較穩(wěn)定。下面我拿一道我做過且非常典型的題來做一個(gè)完整解析。題目描述簡化版給定一個(gè)長度為n的數(shù)組nums你可以進(jìn)行任意次操作每次操作選擇一個(gè)下標(biāo)i將nums[i]加1或減1。求最少需要多少次操作使得數(shù)組中所有元素都相等。這道題的核心思路中位數(shù)是最優(yōu)解。證明也很直觀如果所有元素都等于x那么總操作數(shù)是sum(|nums[i] - x|)這個(gè)函數(shù)是一個(gè)凸函數(shù)在x取中位數(shù)時(shí)達(dá)到最小值。如果x取在數(shù)據(jù)范圍之外總操作數(shù)只會(huì)更大。換一個(gè)角度看這道題它和“會(huì)議室安排”“求最小移動(dòng)次數(shù)”是同一類問題都涉及排序和后繼元素對(duì)齊的思路。解題步驟很簡單三步走排序、找中位數(shù)、累加絕對(duì)值差。#include bits/stdc.h using namespace std; int main() { int n; cin n; vectorint nums(n); for (int i 0; i n; i) cin nums[i]; sort(nums.begin(), nums.end()); long long median nums[n / 2]; // 中位數(shù) long long ans 0; for (int i 0; i n; i) { ans abs(nums[i] - median); } cout ans endl; return 0; }這道題雖然簡單但它考察的是你能否快速識(shí)別出“中位數(shù)最優(yōu)”這個(gè)關(guān)鍵性質(zhì)。筆試時(shí)時(shí)間緊張如果上來就想用DP或者二分來硬解反而容易卡殼。所以先分析問題結(jié)構(gòu)、識(shí)別題型、再選擇算法這個(gè)做題順序不能亂。4.2 我在筆試現(xiàn)場(chǎng)踩過的三個(gè)坑筆試現(xiàn)場(chǎng)踩坑的代價(jià)非常高因?yàn)闀r(shí)間不等人。這里分享三個(gè)我親身經(jīng)歷的教訓(xùn)希望大家別重蹈覆轍。第一個(gè)坑是審題不仔細(xì)把輸入輸出格式搞錯(cuò)了。有些題目要求輸出結(jié)果保留幾位小數(shù)有些要求用特定分隔符有些是多組輸入直到文件結(jié)尾。我筆試時(shí)有一道編程題題目要求輸出一行多個(gè)數(shù)中間用空格分隔我習(xí)慣性用了換行分隔結(jié)果整道題判斷錯(cuò)誤。雖然代碼邏輯完全正確但輸出格式不對(duì)一分沒得。經(jīng)驗(yàn)是讀題時(shí)先用三秒鐘確認(rèn)輸入輸出格式再開始寫代碼。第二個(gè)坑是編譯環(huán)境和本地環(huán)境有差異。??途W(wǎng)筆試系統(tǒng)通常支持C14/17、Java 8/11、Python 3等環(huán)境但本地編譯器和遠(yuǎn)程系統(tǒng)版本可能不同。比如C代碼里我用到了vector的某些新特性本地沒問題但線上系統(tǒng)用的編譯器版本較老編譯直接報(bào)錯(cuò)。我的建議是筆試前提前到??途W(wǎng)的模擬環(huán)境試一下自己熟悉的語言和編譯器版本寫代碼時(shí)盡量不要用太新的語言特性。第三個(gè)坑是大數(shù)溢出沒有提前預(yù)防。筆試題目給的數(shù)據(jù)范圍經(jīng)常是10^9甚至10^18級(jí)別如果你用int存儲(chǔ)中間結(jié)果很容易溢出。我有一道題用了int存儲(chǔ)累加結(jié)果導(dǎo)致答案錯(cuò)誤排查了半天才發(fā)現(xiàn)是溢出問題。從那以后凡是涉及累加、乘法、求和的場(chǎng)景我都不假思索地用long long。5. 筆試后的復(fù)盤與進(jìn)階建議5.1 常見問題排查速查表根據(jù)我自己的筆試經(jīng)歷把容易出錯(cuò)的地方整理成一個(gè)速查表考前過一遍非常有用。問題類型具體表現(xiàn)解決方案整數(shù)溢出中間結(jié)果超過int范圍答案錯(cuò)誤累加、乘法、求和都用long long數(shù)組越界訪問了nums[-1]或nums[n]循環(huán)條件用i n判斷邊界單獨(dú)處理KMP求錯(cuò)next數(shù)組填錯(cuò)匹配結(jié)果錯(cuò)誤用樸素前綴后綴法驗(yàn)證快排退化有序輸入時(shí)超時(shí)采用隨機(jī)化基準(zhǔn)或三數(shù)取中遞歸超深遞歸調(diào)用層數(shù)過多棧溢出改成迭代循環(huán)寫法輸出格式錯(cuò)誤分隔符、空格、換行與題目要求不符先確認(rèn)輸入輸出格式再寫代碼浮點(diǎn)數(shù)精度保留小數(shù)位不足或過多用printf/格式化字符串控制輸出還有一個(gè)小技巧筆試時(shí)如果第一遍提交沒有AC不要慌先檢查邊界條件。比如數(shù)組長度為1時(shí)、輸入為空時(shí)、元素都相同時(shí)你的代碼能否正確處理。很多隱藏的測(cè)試用例都是在考邊界條件。5.2 關(guān)于機(jī)器學(xué)習(xí)算法工程師這個(gè)方向我的幾點(diǎn)體會(huì)最后聊聊筆試之外的一些想法。網(wǎng)易提前批筆試只是整個(gè)求職過程的第一步但它能很清晰地反映出目前在機(jī)器學(xué)習(xí)算法工程師這個(gè)崗位上的整體認(rèn)知趨勢(shì)算法工程能力與機(jī)器學(xué)習(xí)理論并行數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)與模型原理缺一不可。如果你在準(zhǔn)備過程中發(fā)現(xiàn)排序算法寫起來都費(fèi)勁那就意味著刷題量還不夠如果你覺得損失函數(shù)推導(dǎo)無從下手那說明理論部分需要重新過一遍。我個(gè)人的體會(huì)是準(zhǔn)備筆試最好的狀態(tài)不是把所有題目都刷完而是建立一套完整的知識(shí)框架確保拿到任何一道題都能快速歸類到對(duì)應(yīng)的技術(shù)棧里。遇到一道編程題你要能在十秒內(nèi)判斷它屬于排序、搜索、DP、圖論中的哪一類然后快速調(diào)用對(duì)應(yīng)的模板。遇到一道機(jī)器學(xué)習(xí)選擇題你要能迅速定位到它考的是模型原理、損失函數(shù)、優(yōu)化算法、模型評(píng)估中的哪個(gè)模塊然后根據(jù)已知的結(jié)論去匹配選項(xiàng)。這種快速歸類的能力沒有捷徑只能通過大量練習(xí)來形成。我當(dāng)時(shí)是把所有做錯(cuò)的題、踩過的坑、總結(jié)的模板都放在一個(gè)文檔里考前翻一遍。這樣做的好處是你對(duì)自己容易出錯(cuò)的地方有清晰的認(rèn)知上考場(chǎng)時(shí)心里就有底了。網(wǎng)易2023提前批筆試已經(jīng)過去一段時(shí)間了現(xiàn)在回想起來那些為了弄懂一個(gè)算法而翻來覆去推導(dǎo)的夜晚那些看似枯燥的重復(fù)刷題最終都在考場(chǎng)上變成了實(shí)實(shí)在在的分?jǐn)?shù)。所以如果你正在準(zhǔn)備類似的大廠算法崗筆試別想太多靜下心來先把一道題一道題做好。機(jī)會(huì)永遠(yuǎn)是留給準(zhǔn)備好了的人。