編程筆試拆解:題型規(guī)律、高頻考點(diǎn)與答題策略)
又到一年校招季后臺(tái)收到不少準(zhǔn)備投遞手機(jī)廠(chǎng)商的同學(xué)問(wèn)筆試怎么準(zhǔn)備。今天就以vivo 2020屆校招在線(xiàn)編程筆試A卷為切入點(diǎn)聊聊這類(lèi)在線(xiàn)編程筆試到底在考什么、怎么答才能拿高分。我當(dāng)年也是從這套卷子一路走過(guò)來(lái)的后來(lái)幫學(xué)弟學(xué)妹改簡(jiǎn)歷、做模擬面試對(duì)這類(lèi)題型的套路已經(jīng)摸得比較透。這篇文章不打算貼原題答案網(wǎng)上也找不到完全可信的版本而是把試卷背后的出題邏輯、高頻考點(diǎn)、答題節(jié)奏、常見(jiàn)坑位一次講清楚。不管你是2025屆還是2026屆只要目標(biāo)是手機(jī)廠(chǎng)商、互聯(lián)網(wǎng)大廠(chǎng)的校招研發(fā)崗這份拆解都值得你花十分鐘看完。1. 這場(chǎng)筆試在考什么題型結(jié)構(gòu)與整體設(shè)計(jì)思路1.1 在線(xiàn)編程筆試的典型構(gòu)成先說(shuō)一個(gè)很多人忽略的事實(shí)vivo這種手機(jī)廠(chǎng)商的在線(xiàn)編程筆試和互聯(lián)網(wǎng)大廠(chǎng)的題風(fēng)格不太一樣。大廠(chǎng)喜歡出偏競(jìng)賽思維的題繞好幾個(gè)彎才能想到最優(yōu)解手機(jī)廠(chǎng)商更看重工程落地能力和代碼基本功題目往往背景清晰、需求直白但會(huì)在邊界條件和數(shù)據(jù)規(guī)模上埋雷。2020屆A卷整體分兩部分客觀題和編程題。客觀題通常是選擇題覆蓋計(jì)算機(jī)網(wǎng)絡(luò)、操作系統(tǒng)、數(shù)據(jù)結(jié)構(gòu)、Java/C語(yǔ)言基礎(chǔ)等這部分考察的是計(jì)算機(jī)基礎(chǔ)是否扎實(shí)。編程題一般是2到3道難度呈梯度上升從“送分題”到“區(qū)分題”最后一道通常有區(qū)分度用來(lái)篩選真正有算法功底的人。在線(xiàn)編程的平臺(tái)一般是牛客網(wǎng)或者賽碼網(wǎng)支持的語(yǔ)言比較全C/C、Java、Python都能選。我建議你提前登錄平臺(tái)熟悉一下代碼編輯器和提交方式尤其是輸入輸出模板別把時(shí)間浪費(fèi)在調(diào)試本地環(huán)境上。1.2 vivo筆試題目的出題傾向從歷年題目看vivo筆試的編程題有幾個(gè)明顯偏好第一是數(shù)組和字符串操作出現(xiàn)頻率極高。比如數(shù)組去重、排序后統(tǒng)計(jì)、字符串匹配、子串截取這類(lèi)題看著簡(jiǎn)單但往往要求在一次遍歷內(nèi)完成考察你的代碼是否簡(jiǎn)潔高效。第二是動(dòng)態(tài)規(guī)劃幾乎年年必考。背包問(wèn)題、爬樓梯變體、二維路徑問(wèn)題都很常見(jiàn)而且通常作為壓軸題出現(xiàn)。原因是DP既能考察建模能力又能暴露代碼功底一道題就能篩掉大部分人。第三是不太考復(fù)雜的圖論和高級(jí)數(shù)據(jù)結(jié)構(gòu)。像線(xiàn)段樹(shù)、后綴數(shù)組、網(wǎng)絡(luò)流這些在手機(jī)廠(chǎng)商筆試?yán)锘静粫?huì)出現(xiàn)。出題人更關(guān)心的是你能否用基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)解決實(shí)際問(wèn)題這和企業(yè)日常開(kāi)發(fā)的需求是匹配的。所以備考策略很明確把基礎(chǔ)算法吃透把常見(jiàn)題型的模板寫(xiě)好比盲目刷難題有效得多。我見(jiàn)過(guò)太多同學(xué)天天刷LeetCode hard結(jié)果筆試時(shí)連一道中等的DP都沒(méi)寫(xiě)出來(lái)就是因?yàn)榛A(chǔ)不穩(wěn)、模板不熟。2. 核心考點(diǎn)逐類(lèi)拆解從送分題到壓軸題2.1 數(shù)組與模擬類(lèi)題先把邏輯理順再動(dòng)手這類(lèi)題在A卷里通常是第一道目的很單純給大部分候選人送點(diǎn)分也快速過(guò)濾掉完全不會(huì)寫(xiě)代碼的人。典型的題目背景可能是“給定一個(gè)整數(shù)數(shù)組統(tǒng)計(jì)出現(xiàn)次數(shù)前k大的元素”或者“將一個(gè)數(shù)組按奇偶順序重新排列”。我以“按奇偶順序重新排列數(shù)組”為例講講這類(lèi)題的標(biāo)準(zhǔn)解法。題目要求把所有奇數(shù)放在數(shù)組前半部分偶數(shù)放在后半部分并且保持相對(duì)順序不變。最直觀的做法是額外開(kāi)一個(gè)臨時(shí)數(shù)組第一遍遍歷收集所有奇數(shù)第二遍收集所有偶數(shù)最后合并回去。時(shí)間復(fù)雜度O(n)空間復(fù)雜度O(n)代碼清晰面試筆試都?jí)蛴谩?include vector using namespace std; vectorint reorderArray(vectorint nums) { vectorint result; for (int num : nums) { if (num % 2 ! 0) result.push_back(num); } for (int num : nums) { if (num % 2 0) result.push_back(num); } return result; }這里有個(gè)容易踩的坑如果題目要求“在原數(shù)組上操作不開(kāi)額外空間”就不能用上面的寫(xiě)法。原地版本用雙指針一個(gè)從前往后找偶數(shù)一個(gè)從后往前找奇數(shù)找到就交換。但這種方法會(huì)改變相對(duì)順序如果題目額外要求“保持相對(duì)順序”就需要用插入排序的思路找到奇數(shù)后依次移動(dòng)中間的元素時(shí)間復(fù)雜度會(huì)變成O(n2)。筆試時(shí)遇到這類(lèi)題先看清楚題目對(duì)空間和順序到底有沒(méi)有額外要求再?zèng)Q定用哪種解法。我見(jiàn)過(guò)不少同學(xué)看到“數(shù)組重排”就默認(rèn)雙指針結(jié)果因?yàn)楦淖冺樞驅(qū)е聵永^(guò)不了白白丟分。2.2 字符串處理類(lèi)題邊界條件決定生死字符串處理是A卷的第二類(lèi)高頻題常見(jiàn)的有反轉(zhuǎn)句子中的單詞順序、判斷回文串變體、計(jì)算字符串中某個(gè)子串出現(xiàn)的次數(shù)等。這類(lèi)題技術(shù)含量不高但特別考驗(yàn)細(xì)心程度邊界條件處理不好很容易出現(xiàn)“樣例全過(guò)、提交0分”的慘劇。舉一個(gè)典型的例子給定一個(gè)字符串反轉(zhuǎn)其中每個(gè)單詞的字母順序但單詞之間的相對(duì)位置不變。比如輸入hello world輸出olleh dlrow。這道題的核心思路是先按空格把句子拆成單詞對(duì)每個(gè)單詞反轉(zhuǎn)再重新拼接。但要注意兩點(diǎn)第一單詞之間可能有多個(gè)連續(xù)空格不能直接split后簡(jiǎn)單拼接否則空格數(shù)會(huì)變第二C里用getline讀取帶空格的整行時(shí)要處理好換行符Java里用nextLine也容易踩坑。public static String reverseWords(String s) { StringBuilder result new StringBuilder(); int i 0; while (i s.length()) { char c s.charAt(i); if (c ! ) { int j i; while (j s.length() s.charAt(j) ! ) j; StringBuilder word new StringBuilder(s.substring(i, j)); result.append(word.reverse()); i j; } else { result.append( ); i; } } return result.toString(); }這段代碼的邏輯是用雙指針定位每個(gè)單詞的起止位置對(duì)單個(gè)單詞做反轉(zhuǎn)后追加到結(jié)果中空格原樣保留。這樣做的好處是無(wú)論字符串中有多少個(gè)連續(xù)空格都不會(huì)丟失信息。字符串題目在筆試?yán)锏娜蒎e(cuò)率很低因?yàn)闇y(cè)試用例會(huì)故意包含空串、全空格、首尾帶空格等特殊情況。我建議你在本地寫(xiě)代碼時(shí)至少準(zhǔn)備五個(gè)測(cè)試用例空字符串、單字符、全空格、正常句子、帶多個(gè)連續(xù)空格的句子。養(yǎng)成這個(gè)習(xí)慣后字符串題基本不會(huì)翻車(chē)。2.3 動(dòng)態(tài)規(guī)劃類(lèi)題狀態(tài)定義是核心A卷的壓軸題或者倒數(shù)第二題通常是動(dòng)態(tài)規(guī)劃。這里的DP不會(huì)出得太偏比較常見(jiàn)的是背包問(wèn)題的變體、二維路徑問(wèn)題、最長(zhǎng)遞增子序列等。2020屆這次出的是和“任務(wù)安排”或“物品選擇”相關(guān)的背包類(lèi)變體核心是考察狀態(tài)定義和狀態(tài)轉(zhuǎn)移方程。以經(jīng)典的0-1背包為例有n個(gè)物品每個(gè)物品有重量w[i]和價(jià)值v[i]背包容量為W問(wèn)能裝入的最大價(jià)值是多少。標(biāo)準(zhǔn)解法是定義dp[i][j]表示前i個(gè)物品放入容量為j的背包能獲得的最大價(jià)值。狀態(tài)轉(zhuǎn)移方程不選第i個(gè)物品dp[i][j] dp[i-1][j]選第i個(gè)物品前提是j w[i]dp[i][j] max(dp[i-1][j], dp[i-1][j-w[i]] v[i])def knapsack(W, w, v): n len(w) dp [[0] * (W 1) for _ in range(n 1)] for i in range(1, n 1): for j in range(W 1): dp[i][j] dp[i - 1][j] if j w[i - 1]: dp[i][j] max(dp[i][j], dp[i - 1][j - w[i - 1]] v[i - 1]) return dp[n][W]筆試的時(shí)候很多人不是不會(huì)寫(xiě)轉(zhuǎn)移方程而是壓根沒(méi)想到這題要用DP或者想不出怎么把題目描述抽象成狀態(tài)。這里分享一個(gè)我自己的判斷方法如果題目里出現(xiàn)“最大”“最小”“方案數(shù)”這些詞而且直接暴力搜索會(huì)指數(shù)爆炸那大概率是DP題。接下來(lái)問(wèn)自己三個(gè)問(wèn)題狀態(tài)用什么表示狀態(tài)之間怎么轉(zhuǎn)移初始條件是什么把這三個(gè)問(wèn)題想清楚代碼就水到渠成了。還有一種情況是用滾動(dòng)數(shù)組優(yōu)化空間。在上面的0-1背包中每一行的狀態(tài)只依賴(lài)上一行所以可以用一維數(shù)組從后往前更新def knapsack_optimized(W, w, v): dp [0] * (W 1) for i in range(len(w)): for j in range(W, w[i] - 1, -1): dp[j] max(dp[j], dp[j - w[i]] v[i]) return dp[W]注意這里的第二層循環(huán)必須從后往前否則會(huì)重復(fù)選擇同一個(gè)物品退化成完全背包。這個(gè)細(xì)節(jié)我面試時(shí)問(wèn)過(guò)很多人能答對(duì)的不到一半筆試時(shí)更是有不少人在這一步栽跟頭。2.4 邊界與數(shù)據(jù)規(guī)模你以為寫(xiě)對(duì)了其實(shí)沒(méi)有在線(xiàn)編程筆試和平時(shí)刷題最大的區(qū)別就是存在“數(shù)據(jù)規(guī)模”這個(gè)隱形殺手。2020屆A卷的編程題雖然整體偏基礎(chǔ)但在數(shù)據(jù)范圍上做了不少文章。舉個(gè)例子題目要求計(jì)算某種數(shù)組操作的次數(shù)看起來(lái)很簡(jiǎn)單但如果數(shù)組長(zhǎng)度n的范圍是10^5那么O(n2)的暴力解法一定超時(shí)必須優(yōu)化到O(n log n)或O(n)。很多人本地測(cè)試小樣例沒(méi)問(wèn)題提交后顯示超時(shí)就是因?yàn)闆](méi)注意到數(shù)據(jù)范圍。再比如如果題目涉及累加和或乘積要考慮結(jié)果是否超出int范圍。C的int是32位最大約21億當(dāng)n超過(guò)10^5且累加和接近n2時(shí)結(jié)果大概率溢出。這時(shí)候應(yīng)該直接用long long避免踩坑。Java也有類(lèi)似的問(wèn)題int溢出后變成負(fù)數(shù)會(huì)導(dǎo)致判斷邏輯出問(wèn)題。還有一點(diǎn)是關(guān)于取模。如果題目說(shuō)“結(jié)果可能很大請(qǐng)對(duì)10^97取模”那么中間每一步計(jì)算都要取模不能只在最后取一次。尤其是遞推類(lèi)題目中間結(jié)果一旦溢出后面再怎么取模都是錯(cuò)的。我的建議是做每一道題之前先花30秒掃一眼題目里給出的數(shù)據(jù)范圍心里大致估算一下自己方案的復(fù)雜度能不能過(guò)。如果是O(n2)且n是10^5趕緊想優(yōu)化方案別浪費(fèi)時(shí)間寫(xiě)一個(gè)必超時(shí)的代碼。3. 在線(xiàn)編程平臺(tái)的實(shí)操細(xì)節(jié)別讓非技術(shù)因素拖后腿3.1 輸入輸出處理必須爛熟于心的基本功在線(xiàn)編程筆試和本地IDE調(diào)試最大的區(qū)別就是你需要自己處理標(biāo)準(zhǔn)輸入輸出。很多同學(xué)代碼邏輯沒(méi)問(wèn)題結(jié)果卡在輸入解析上這實(shí)在太冤了。C常見(jiàn)場(chǎng)景是用cin讀取不定長(zhǎng)的輸入。比如題目說(shuō)“第一行一個(gè)整數(shù)n第二行n個(gè)整數(shù)”可以這樣讀int n; cin n; vectorint arr(n); for (int i 0; i n; i) { cin arr[i]; }如果題目給的輸入是“一直讀到文件末尾”則需要用while循環(huán)配合cinint a, b; while (cin a b) { // 處理每組輸入 }Java這邊用Scanner居多但筆試時(shí)數(shù)據(jù)量大的場(chǎng)景建議用BufferedReader性能更好BufferedReader br new BufferedReader(new InputStreamReader(System.in)); int n Integer.parseInt(br.readLine().trim()); String[] parts br.readLine().split( );Python則要善用sys.stdin.read()一次性讀取再解析不要用input()一行行讀浪費(fèi)時(shí)間也容易出錯(cuò)import sys data sys.stdin.read().strip().split()還有一個(gè)高頻坑有時(shí)候輸入數(shù)據(jù)包含了多余的空行或者末尾換行符如果直接用nextLine或getline可能讀到空字符串導(dǎo)致轉(zhuǎn)換報(bào)錯(cuò)。穩(wěn)妥的做法是每次讀一行后先trim掉首尾空白。這里想多說(shuō)一句不要輕視輸入輸出這道工序。正式筆試的每一分鐘都很寶貴如果連基本的IO都要現(xiàn)場(chǎng)想時(shí)間肯定不夠用。建議考前把C、Java、Python三種語(yǔ)言的常用IO寫(xiě)法各準(zhǔn)備一套模板存到腦子或本地筆記里考試時(shí)直接套用。3.2 答題順序與時(shí)間分配策略vivo的在線(xiàn)筆試通常總時(shí)長(zhǎng)在90到120分鐘之間包含客觀題和編程題。合理分配時(shí)間是拿到高分的關(guān)鍵。我的習(xí)慣是拿到試卷先把所有題目快速瀏覽一遍對(duì)編程題的難度有個(gè)整體判斷先做客觀題里自己有把握的部分不要在一道選擇題上糾結(jié)超過(guò)兩分鐘。編程題的順序嚴(yán)格遵循“先易后難”原則。第一道通常是數(shù)組/字符串類(lèi)送分題20分鐘內(nèi)寫(xiě)完第二道中等難度30到40分鐘最后一道如果有思路就寫(xiě)沒(méi)思路就先把基礎(chǔ)用例的暴力解法寫(xiě)上能拿部分分就不虧。一定留出最后的10到15分鐘統(tǒng)一檢查編譯和提交。很多在線(xiàn)筆試平臺(tái)支持多語(yǔ)言我建議你選擇自己最熟練的語(yǔ)言不要為了炫技選擇不熟悉的語(yǔ)言。比如你平時(shí)寫(xiě)Java寫(xiě)得多突然想在筆試?yán)镉肞ython快速實(shí)現(xiàn)DP結(jié)果語(yǔ)法不熟調(diào)試耗掉大量時(shí)間得不償失。我備考時(shí)的模擬練習(xí)方法是每次模擬筆試都嚴(yán)格限制90分鐘手機(jī)靜音不許查資料模擬真實(shí)環(huán)境下的緊張感。這樣練過(guò)幾次之后上了考場(chǎng)節(jié)奏感會(huì)很穩(wěn)不容易慌。3.3 代碼風(fēng)格與提交規(guī)范在線(xiàn)筆試雖然不要求你寫(xiě)出生產(chǎn)級(jí)代碼但代碼的可讀性會(huì)影響面試官對(duì)你的印象。尤其是有些筆試平臺(tái)的代碼會(huì)留檔面試官在后續(xù)面試中可能會(huì)翻看你的提交記錄。幾個(gè)實(shí)用建議變量命名要有意義不要全是a、b、c關(guān)鍵邏輯處寫(xiě)簡(jiǎn)短注釋說(shuō)明思路函數(shù)塊之間用空行隔開(kāi)避免深層嵌套如果if里套if里再套if說(shuō)明邏輯可以簡(jiǎn)化。還有一點(diǎn)是關(guān)于邊界條件的處理。在寫(xiě)完主體邏輯后一定要在代碼開(kāi)頭或者關(guān)鍵位置處理空輸入、單元素輸入等特殊情況。比如數(shù)組類(lèi)的題目先判斷if (arr.empty()) return 0; 這行代碼簡(jiǎn)單到不能再簡(jiǎn)單卻能避免運(yùn)行時(shí)錯(cuò)誤。有一次我在模擬時(shí)寫(xiě)了這樣一段代碼遍歷數(shù)組找最大值初始化max INT_MIN結(jié)果數(shù)組為空時(shí)直接返回INT_MIN題目最后的預(yù)期是0導(dǎo)致整個(gè)測(cè)試用例失敗。后來(lái)我養(yǎng)成習(xí)慣凡是有數(shù)組輸入先判斷是否為空再?zèng)Q定怎么初始化變量。進(jìn)筆試現(xiàn)場(chǎng)之前這個(gè)習(xí)慣已經(jīng)變成了條件反射。4. 高頻失誤與調(diào)試技巧從“樣例通過(guò)”到“完整AC”4.1 樣例通過(guò)但提交0分的三個(gè)典型原因在線(xiàn)編程筆試最讓人崩潰的場(chǎng)景就是本地測(cè)試明明通過(guò)了提交后卻是0分。我自己經(jīng)歷過(guò)太多次總結(jié)一下最常見(jiàn)的三個(gè)原因第一個(gè)原因是數(shù)組越界或訪(fǎng)問(wèn)了不存在的下標(biāo)。比如C里用了vector的size()做索引但沒(méi)有注意size()返回的是size_t無(wú)符號(hào)類(lèi)型可能在某些循環(huán)條件下產(chǎn)生負(fù)數(shù)轉(zhuǎn)無(wú)符號(hào)數(shù)的問(wèn)題。建議把所有涉及索引的循環(huán)都寫(xiě)成int且顯式判斷邊界。第二個(gè)原因是多組輸入的清空問(wèn)題。如果平臺(tái)是多組測(cè)試用例連續(xù)輸入每處理完一組相關(guān)的計(jì)數(shù)器、臨時(shí)數(shù)組、標(biāo)志位都必須重置。我見(jiàn)過(guò)一個(gè)同學(xué)在循環(huán)外定義了局部變量循環(huán)內(nèi)忘記重新初始化導(dǎo)致第二組用例開(kāi)始后結(jié)果全錯(cuò)。第三個(gè)原因是取模時(shí)機(jī)不對(duì)。前面已經(jīng)提到過(guò)遞推過(guò)程中每一步都要取模而不是最后統(tǒng)一處理。特別是涉及減法的取模如果中間結(jié)果為負(fù)要先加上MOD再取模。關(guān)于第二個(gè)原因再展開(kāi)說(shuō)一下。有一次我遇到一道題題目說(shuō)了多組測(cè)試數(shù)據(jù)每組數(shù)據(jù)第一行一個(gè)整數(shù)n接下來(lái)n行輸入然后輸出結(jié)果。我寫(xiě)的是int T; cin T; while (T--) { int n; cin n; vectorint arr(n); for (int i 0; i n; i) cin arr[i]; // 處理邏輯結(jié)果輸出 }這個(gè)框架本身沒(méi)問(wèn)題問(wèn)題出在我的處理邏輯里定義了一個(gè)std::map卻沒(méi)有在每組數(shù)據(jù)之間清空。結(jié)果第二組數(shù)據(jù)來(lái)的時(shí)候map里還殘留著第一組的結(jié)果直接影響了計(jì)數(shù)。后來(lái)我把map的定義挪到while循環(huán)內(nèi)部問(wèn)題就消失了。這是一次記憶很深的實(shí)戰(zhàn)教訓(xùn)也讓我之后特別重視變量的作用域。4.2 死循環(huán)與運(yùn)行時(shí)錯(cuò)誤如何快速定位筆試時(shí)時(shí)間緊張如果程序運(yùn)行超時(shí)或者崩潰不要干瞪眼要有系統(tǒng)性的排查思路。先說(shuō)出死循環(huán)。常見(jiàn)原因是循環(huán)邊界寫(xiě)錯(cuò)比如while (l r)寫(xiě)成了while (l r)導(dǎo)致搜索區(qū)間不正確或者循環(huán)體內(nèi)變量更新遺漏導(dǎo)致某個(gè)變量永遠(yuǎn)不會(huì)接近退出條件。排查辦法是檢查循環(huán)變量的更新語(yǔ)句確認(rèn)每一步都在向退出條件靠近。再說(shuō)運(yùn)行時(shí)錯(cuò)誤比如空指針、除零、棧溢出。最容易忽略的是除零尤其是當(dāng)分母是某個(gè)變量而你沒(méi)有檢查它是否為0時(shí)。題目如果涉及“求平均值”“求比例”一定要先判斷分母是否為0否則本地測(cè)試數(shù)據(jù)如果恰好沒(méi)有0一到平臺(tái)就崩潰。還有棧溢出問(wèn)題。不少同學(xué)在筆試?yán)飼?huì)不知不覺(jué)用遞歸比如深度優(yōu)先遍歷二叉樹(shù)、遞歸DFS搜索所有排列組合。如果遞歸深度達(dá)到10^5以上C默認(rèn)的棧空間是不夠的很容易爆棧。解決辦法是把遞歸改成顯式棧的迭代寫(xiě)法或者改用動(dòng)態(tài)規(guī)劃/廣度優(yōu)先搜索。這里給一個(gè)通用調(diào)試流程先加幾個(gè)中間輸出看看變量的值是否符合預(yù)期如果代碼編譯不通過(guò)從報(bào)錯(cuò)信息的第一行開(kāi)始排查不要全篇亂找如果是運(yùn)行時(shí)崩潰檢查有沒(méi)有除零、數(shù)組越界、空指針這三個(gè)經(jīng)典問(wèn)題如果是超時(shí)考慮是不是復(fù)雜度太高能不能用哈希表或前綴和優(yōu)化。4.3 常用測(cè)試數(shù)據(jù)的自測(cè)方法一個(gè)成熟的做法是在本地準(zhǔn)備幾個(gè)固定模式的測(cè)試用例提交前快速跑一遍。我自己的測(cè)試清單包括普通輸入正常的題目描述示例驗(yàn)證主邏輯是否正確。邊界輸入最小數(shù)據(jù)規(guī)模n1空數(shù)組單字符等驗(yàn)證邊界處理。最壞情況n取到題目允許的最大值驗(yàn)證性能和是否溢出。多組輸入連續(xù)跑兩組驗(yàn)證每組之間的變量是否清空。特殊數(shù)據(jù)全相同元素、全不同元素、升序、降序、包含負(fù)數(shù)等。每一道題寫(xiě)完拿這個(gè)清單過(guò)一遍比盲目提交幾次再改正效率高得多。尤其是“最壞情況”這一條可以直接發(fā)現(xiàn)O(n2)超時(shí)、int溢出這類(lèi)在普通樣例中完全看不見(jiàn)的問(wèn)題。這個(gè)表你可以在腦子里存一個(gè)也可以寫(xiě)在一張紙上放在旁邊。筆試時(shí)看到題目先確認(rèn)數(shù)據(jù)范圍再?zèng)Q定算法最后按清單自測(cè)整個(gè)流程下來(lái)有條不紊。5. 備考方向與長(zhǎng)期能力建設(shè)5.1 校招筆試前一個(gè)月怎么準(zhǔn)備如果離筆試還剩一個(gè)月時(shí)間緊任務(wù)重不要漫無(wú)目的地刷題要有針對(duì)性地復(fù)習(xí)。第一周重點(diǎn)過(guò)基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)數(shù)組、鏈表、棧、隊(duì)列、哈希表、二叉樹(shù)。每種數(shù)據(jù)結(jié)構(gòu)至少能手寫(xiě)一遍基本操作包括插入、刪除、查找、遍歷。第二周集中刷高頻算法專(zhuān)題排序、二分查找、雙指針、滑動(dòng)窗口、BFS/DFS、動(dòng)態(tài)規(guī)劃。第三周做模擬套題找近幾年的知名互聯(lián)網(wǎng)公司和手機(jī)廠(chǎng)商筆試真題卡時(shí)間完整模擬。第四周復(fù)盤(pán)錯(cuò)題把不熟的模板重新默寫(xiě)一遍同時(shí)整理自己常用的輸入輸出模板和代碼片段。這里要特別強(qiáng)調(diào)一下手寫(xiě)代碼的重要性。你在IDE里寫(xiě)代碼時(shí)IDE會(huì)自動(dòng)補(bǔ)全、自動(dòng)提示這在筆試時(shí)會(huì)讓人產(chǎn)生依賴(lài)。很多在線(xiàn)筆試平臺(tái)的代碼編輯器補(bǔ)全能力很弱甚至連括號(hào)匹配都做得不好。所以平時(shí)練習(xí)時(shí)就應(yīng)該盡量脫離IDE的自動(dòng)補(bǔ)全用純文本編輯器手寫(xiě)代碼才能提前適應(yīng)考場(chǎng)環(huán)境。另一個(gè)容易忽略的點(diǎn)是目標(biāo)公司必須“對(duì)癥下藥”。vivo的筆試風(fēng)格偏向工程、通信、終端設(shè)備相關(guān)你刷題時(shí)也可以多看看字符串解析、數(shù)組操作、存儲(chǔ)管理這類(lèi)貼近硬件的場(chǎng)景題。如果目標(biāo)公司是純互聯(lián)網(wǎng)公司那側(cè)重可以放在復(fù)雜算法和系統(tǒng)設(shè)計(jì)上。5.2 長(zhǎng)期算法能力怎么培養(yǎng)如果準(zhǔn)備時(shí)間比較充裕或者你還在大二大三我建議走一條更扎實(shí)的路線(xiàn)。底子是數(shù)據(jù)結(jié)構(gòu)和算法這門(mén)課不要只背結(jié)論要理解每種數(shù)據(jù)結(jié)構(gòu)為什么這樣設(shè)計(jì)時(shí)間和空間復(fù)雜度是怎么分析出來(lái)的。比如哈希表為什么是O(1)的平均查找它的哈希沖突怎么解決鏈表和數(shù)組在不同場(chǎng)景下怎么取舍。這些問(wèn)題不只是考試面試時(shí)也經(jīng)常被問(wèn)到。然后是刻意練習(xí)。每天固定刷2到3道題比周末集中刷20道題效果更好。刷題的時(shí)候給自己計(jì)時(shí)一道題最多想30分鐘超過(guò)時(shí)間就看題解然后隔天再把這道題重新寫(xiě)一遍做到能獨(dú)立AC為止。我自己的經(jīng)驗(yàn)是刷題的關(guān)鍵不在量而在總結(jié)歸納。每做完一道題在筆記里記錄它的考點(diǎn)、解法和易錯(cuò)點(diǎn)定期回顧。比如“雙指針”這個(gè)技巧適用于有序數(shù)組的兩數(shù)之和、最長(zhǎng)無(wú)重復(fù)子串、快慢指針找環(huán)等很多場(chǎng)景把它們放在一起對(duì)比比單純記住一個(gè)題解有價(jià)值得多。5.3 筆試之外從題目看到公司技術(shù)風(fēng)格最后想聊一個(gè)很多人忽略的角度筆試題目其實(shí)透露了公司技術(shù)團(tuán)隊(duì)的價(jià)值取向。vivo的筆試重點(diǎn)偏向數(shù)組、字符串、動(dòng)態(tài)規(guī)劃和基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)說(shuō)明研發(fā)團(tuán)隊(duì)在實(shí)際工作中更看重扎實(shí)的編碼能力和業(yè)務(wù)邏輯抽象能力而不是極致的算法競(jìng)賽能力。這也符合手機(jī)廠(chǎng)商軟件研發(fā)的現(xiàn)實(shí)——大家寫(xiě)的大多是業(yè)務(wù)代碼需要能快速把需求抽象成清晰的邏輯結(jié)構(gòu)而不是整天研究高難度算法。所以如果你拿到了vivo的筆試機(jī)會(huì)答得不好也不要太挫敗。認(rèn)真復(fù)盤(pán)每一道題看懂它的考察意圖這本身就是一次寶貴的學(xué)習(xí)過(guò)程。即便這次沒(méi)過(guò)積累的知識(shí)點(diǎn)和方法論對(duì)后面的其他公司筆試同樣適用。在線(xiàn)編程筆試是所有研發(fā)崗求職者都要過(guò)的一道坎。它不像面試那樣需要臨場(chǎng)表達(dá)也不像簡(jiǎn)歷篩選那樣有主觀成分它把所有人的代碼能力放到同一個(gè)平臺(tái)上公平比拼。只要你基礎(chǔ)扎實(shí)、模板熟練、心態(tài)穩(wěn)定拿到一個(gè)不錯(cuò)的成績(jī)并不難。希望這篇拆解能幫你少走彎路祝你在校招季拿到心儀的offer。