綜合A卷:游戲公司筆試核心考點(diǎn)全解析)
每次校招季總有人翻出前幾年的經(jīng)典筆試卷來(lái)研究。完美世界2017校招技術(shù)綜合A卷就是這樣一份被反復(fù)拿出來(lái)討論的題目原因很簡(jiǎn)單它代表了一類游戲公司技術(shù)筆試的典型出題思路——覆蓋面廣、基礎(chǔ)要求扎實(shí)、算法題占比重并且?guī)黠@的C傾向。哪怕放在今天這套卷子考察的知識(shí)點(diǎn)依然是游戲研發(fā)崗筆試的核心理解它的出題邏輯比刷十套新題更有用。我剛?cè)胄心菚?huì)兒為了準(zhǔn)備游戲公司校招把能找到的往年筆試題都刷了一遍完美世界的這套A卷是其中質(zhì)量相當(dāng)高的一份。它不偏不怪但每道題都能看出出題人對(duì)基礎(chǔ)功底的重視。這篇文章我結(jié)合自己做過(guò)的題和后來(lái)帶新人時(shí)總結(jié)的經(jīng)驗(yàn)把這份卷子涉及的核心技術(shù)點(diǎn)、典型題型拆開(kāi)講一遍同時(shí)也聊聊這類筆試背后的考察邏輯。正在準(zhǔn)備游戲公司校招的同學(xué)或者想系統(tǒng)復(fù)習(xí)CS基礎(chǔ)的開(kāi)發(fā)者都可以參考。1. 從這套綜合卷看游戲公司校招筆試的出題邏輯先聊一個(gè)很多人忽略的問(wèn)題為什么游戲公司的技術(shù)筆試要考綜合卷了解出題動(dòng)機(jī)比糾結(jié)每道題本身更有價(jià)值。完美世界這類做大型網(wǎng)游、端游、手游研發(fā)的公司技術(shù)崗位覆蓋客戶端、服務(wù)端、引擎、工具鏈、數(shù)據(jù)庫(kù)運(yùn)維等多個(gè)方向。但校招筆試階段他們通常不會(huì)按具體崗位出得特別細(xì)而是先拿一套技術(shù)綜合卷篩一遍基礎(chǔ)。這套卷子的核心目的是確認(rèn)兩件事第一你的計(jì)算機(jī)基礎(chǔ)是否成體系第二在時(shí)間壓力下你能不能快速準(zhǔn)確地解決問(wèn)題。所謂綜合體現(xiàn)在題目分布上。根據(jù)我接觸過(guò)的信息和同類卷子的普遍規(guī)律這套A卷大體包含這樣幾個(gè)模塊模塊大致占比考察目標(biāo)數(shù)據(jù)結(jié)構(gòu)與算法35%-40%邏輯思維、編碼功底、復(fù)雜度意識(shí)C/C語(yǔ)言20%-25%內(nèi)存管理、指針、面向?qū)ο罄斫獠僮飨到y(tǒng)10%-15%進(jìn)程線程、內(nèi)存調(diào)度、并發(fā)基礎(chǔ)計(jì)算機(jī)網(wǎng)絡(luò)10%-15%TCP/IP、Socket、網(wǎng)絡(luò)編程基礎(chǔ)數(shù)據(jù)庫(kù)5%-10%SQL基礎(chǔ)、索引原理、事務(wù)概念邏輯/智力題5%左右臨場(chǎng)反應(yīng)、思維縝密度這個(gè)比例不是隨便定的。游戲公司無(wú)論是客戶端還是服務(wù)端日常開(kāi)發(fā)都重度依賴C所以語(yǔ)言題占比高是必然的。而算法題占比最高是因?yàn)樗钅芎Y選出底層思維能力強(qiáng)的人——這類人上手新項(xiàng)目、排查復(fù)雜bug通常更靠譜。有意思的是這套卷子很少出現(xiàn)偏題怪題。我印象中它考的東西都是教材里反復(fù)強(qiáng)調(diào)的知識(shí)點(diǎn)但出題角度會(huì)刻意繞開(kāi)背誦題更多考理解題。比如不會(huì)直接問(wèn)你什么是虛函數(shù)而是給你一段存在繼承關(guān)系的代碼讓你推導(dǎo)輸出結(jié)果。這種出題方式背概念的人會(huì)吃虧真正寫(xiě)過(guò)代碼、調(diào)試過(guò)程序的人反而覺(jué)得簡(jiǎn)單。2. 數(shù)據(jù)結(jié)構(gòu)與算法模塊整張卷子的分水嶺數(shù)據(jù)結(jié)構(gòu)與算法是這套卷子的絕對(duì)核心也是面試官最看重的部分。我見(jiàn)過(guò)不少筆試成績(jī)不錯(cuò)的同學(xué)算法模塊就能拉開(kāi)別人二三十分。這部分的題目往往不直接考會(huì)背哪種排序而是換個(gè)包裝讓你現(xiàn)場(chǎng)分析。2.1 鏈表與樹(shù)的經(jīng)典考察方式綜合卷里鏈表和二叉樹(shù)是高概率出現(xiàn)的考點(diǎn)。原因很直白游戲項(xiàng)目里場(chǎng)景管理、NPC列表、技能CD隊(duì)列、消息分發(fā)底層大量用到鏈表和樹(shù)結(jié)構(gòu)。筆試不會(huì)考你刷LeetCode那種上百行的難題而是考基礎(chǔ)操作的變體。一種典型考法是給定一個(gè)單鏈表判斷是否有環(huán)并找出環(huán)的入口節(jié)點(diǎn)。這題看著簡(jiǎn)單但考察了兩個(gè)層次第一層是快慢指針的判斷方法第二層是找入口時(shí)為什么會(huì)有一個(gè)兩倍速的推導(dǎo)過(guò)程。很多同學(xué)知道快慢指針能判斷環(huán)但被追問(wèn)相遇點(diǎn)和入口節(jié)點(diǎn)之間的數(shù)學(xué)關(guān)系時(shí)會(huì)卡殼。我當(dāng)時(shí)復(fù)習(xí)時(shí)專門把這類推導(dǎo)過(guò)程寫(xiě)了一遍因?yàn)檫@個(gè)為什么比怎么做更能體現(xiàn)你懂不懂。另一種高頻考法是二叉樹(shù)遍歷的非遞歸實(shí)現(xiàn)尤其是中序遍歷。遞歸版本大部分人都能寫(xiě)但要求用棧模擬非遞歸時(shí)很多人會(huì)在何時(shí)入棧、何時(shí)出棧、何時(shí)訪問(wèn)節(jié)點(diǎn)三個(gè)狀態(tài)里繞暈。我建議準(zhǔn)備時(shí)自己推一遍模擬過(guò)程拿一棵三層滿二叉樹(shù)用紙筆畫(huà)幾輪入棧出棧的序列把細(xì)節(jié)刻進(jìn)腦子里考場(chǎng)上就會(huì)條件反射式地寫(xiě)出來(lái)。2.2 排序與復(fù)雜度分析不是背是算排序算法幾乎是所有綜合卷的必考項(xiàng)。這套A卷涉及的排序題重點(diǎn)不在默寫(xiě)代碼而在三類問(wèn)題第一給一個(gè)特定數(shù)據(jù)分布比如近乎有序的數(shù)組問(wèn)選擇哪種排序最優(yōu)。答案是插入排序因?yàn)榻跤行驎r(shí)它的比較次數(shù)接近O(n)。這題考察的是對(duì)不同排序算法特性的理解而不只是時(shí)間復(fù)雜度表。第二問(wèn)快速排序在最壞情況下的時(shí)間復(fù)雜度和觸發(fā)條件。最壞情況是每次劃分都極度不均比如數(shù)組本身有序且每次選第一個(gè)元素作為基準(zhǔn)時(shí)退化成O(n2)。我面過(guò)的人里有一半能答出O(n2)但說(shuō)不清觸發(fā)條件。這其實(shí)是排序原理的理解問(wèn)題。第三要求分析某個(gè)排序算法是否穩(wěn)定并說(shuō)明原因。以選擇排序?yàn)槔遣环€(wěn)定的——比如{5, 3, 5, 1}里有兩個(gè)5第一輪選出1交換到第一個(gè)位置第一個(gè)5被換到后面兩個(gè)5的相對(duì)順序就變了。這種細(xì)節(jié)題很能看出有沒(méi)有真正理解排序的交換過(guò)程。復(fù)雜度分析也是重點(diǎn)。我建議大家復(fù)習(xí)時(shí)不要只記O(1)、O(n)、O(log n)這些記號(hào)要能說(shuō)出每個(gè)量級(jí)的典型場(chǎng)景。比如哈希表平均O(1)但最壞O(n)二叉搜索樹(shù)平均O(log n)但退化成鏈表后變O(n)這些邊界情況正是筆試喜歡出題的角落。2.3 一道典型的綜合算法題拆解結(jié)合這類卷子的普遍規(guī)律我復(fù)原一道很能代表綜合A卷風(fēng)格的題目給定兩個(gè)有序數(shù)組要求合并后保持有序并分析時(shí)間復(fù)雜度。這題常見(jiàn)的坑有三個(gè)第一個(gè)是用concat再排序時(shí)間復(fù)雜度變成O((nm)log(nm))雖然能過(guò)功能測(cè)試但在筆試答案里會(huì)被扣分第二個(gè)是沒(méi)考慮一個(gè)數(shù)組先遍歷完的情況導(dǎo)致越界第三個(gè)是原地merge時(shí)從前往后覆蓋會(huì)把原數(shù)組元素沖掉正確的做法是從后往前填。標(biāo)準(zhǔn)的歸并寫(xiě)法是雙指針從前往后掃描比較兩個(gè)指針指向的元素小的放入結(jié)果數(shù)組時(shí)間復(fù)雜度O(nm)空間復(fù)雜度O(nm)。如果題目要求O(1)空間那就利用兩個(gè)數(shù)組尾部有多余空間的特性從后往前移動(dòng)。這類題目想表達(dá)的核心是你不僅要寫(xiě)出能跑的代碼還要寫(xiě)出復(fù)雜度最優(yōu)、邊界完善的代碼。3. 操作系統(tǒng)與網(wǎng)絡(luò)游戲研發(fā)躲不開(kāi)的底層功課很多準(zhǔn)備校招的同學(xué)覺(jué)得操作系統(tǒng)和網(wǎng)絡(luò)離游戲客戶端開(kāi)發(fā)很遠(yuǎn)這其實(shí)是個(gè)誤解。客戶端要處理多線程渲染、資源異步加載、網(wǎng)絡(luò)同步服務(wù)端要處理高并發(fā)連接、內(nèi)存管理、I/O模型——每一個(gè)都和操作系統(tǒng)、網(wǎng)絡(luò)的底層機(jī)制強(qiáng)相關(guān)。所以這套卷子在OS和網(wǎng)絡(luò)上的出題不會(huì)浮于表面通常會(huì)結(jié)合具體場(chǎng)景。3.1 進(jìn)程與線程絕不只考概念關(guān)于進(jìn)程和線程筆試題目常見(jiàn)的出法有幾種線程和進(jìn)程的優(yōu)缺點(diǎn)對(duì)比、進(jìn)程間通信方式列舉、死鎖產(chǎn)生的四個(gè)必要條件。但完美世界這類公司的卷子往往還會(huì)加一道場(chǎng)景題。我印象里比較典型的一道是多個(gè)線程同時(shí)對(duì)一個(gè)全局變量做自增操作最終結(jié)果一定等于線程數(shù)嗎答案是不一定因?yàn)樽栽霾僮鞑皇窃拥乃x取、加一、寫(xiě)回三步多個(gè)線程交錯(cuò)執(zhí)行時(shí)會(huì)出現(xiàn)丟失更新。進(jìn)一步追問(wèn)就是如何解決加鎖互斥鎖、原子操作C11的std::atomic、或者無(wú)鎖編程。這題考察的是對(duì)并發(fā)本質(zhì)的理解而不是靠背概念能答好的。死鎖那四個(gè)條件——互斥、占有并等待、不可搶占、循環(huán)等待——也是必背。但筆試??嫉氖亲凅w給一段加鎖代碼判斷是否可能死鎖或者問(wèn)怎么打破死鎖條件。我記得當(dāng)年復(fù)習(xí)時(shí)自己總結(jié)過(guò)一句解決死鎖最實(shí)用的思路是讓加鎖順序全局一致比如兩個(gè)線程都按先鎖A后鎖B的順序取鎖循環(huán)等待就被破壞了。這句話在筆試論述題里很好用。3.2 TCP三次握手與Socket編程的常見(jiàn)考點(diǎn)網(wǎng)絡(luò)模塊里TCP三次握手和四次揮手幾乎是必考。但程度好的卷子不會(huì)只讓你默寫(xiě)過(guò)程而是會(huì)問(wèn)為什么握手要三次揮手卻要四次答案的關(guān)鍵在于握手時(shí)雙方都能主動(dòng)發(fā)起連接所以第三次握手是為了確認(rèn)客戶端的接收能力正常防止已失效的連接請(qǐng)求突然到達(dá)服務(wù)端造成資源浪費(fèi)而揮手時(shí)服務(wù)端可能還有數(shù)據(jù)要發(fā)所以ACK和FIN分開(kāi)發(fā)送就多了一次。Socket編程題也經(jīng)常出現(xiàn)常見(jiàn)的考法是給一段代碼讓你指出錯(cuò)誤或說(shuō)明流程。比如客戶端connect失敗后立即close服務(wù)端在accept之前客戶端就發(fā)數(shù)據(jù)這些問(wèn)題都考察了對(duì)TCP狀態(tài)機(jī)的理解。我建議復(fù)習(xí)時(shí)把listen、accept、connect、read、write、close這個(gè)流程在紙上默寫(xiě)一遍同時(shí)標(biāo)出每步的系統(tǒng)調(diào)用可能返回的錯(cuò)誤碼比單純看書(shū)有效得多。另外OSI七層模型和TCP/IP四層模型的對(duì)應(yīng)關(guān)系也是基礎(chǔ)題但通常不會(huì)單獨(dú)出而是綁定在具體問(wèn)題里。比如問(wèn)HTTP和HTTPS各自工作在哪一層HTTPS在TCP和HTTP之間加了SSL/TLS層目的是加密和身份認(rèn)證。這種題簡(jiǎn)單但能看出你是否有完整的網(wǎng)絡(luò)分層意識(shí)。3.3 內(nèi)存管理游戲客戶端最敏感的話題游戲開(kāi)發(fā)對(duì)內(nèi)存是出了名的斤斤計(jì)較??蛻舳艘环葙Y源的加載、卸載、緩存策略服務(wù)端每個(gè)玩家對(duì)象的內(nèi)存占用都直接影響性能。所以這套卷子里內(nèi)存管理相關(guān)題目也有一席之地。虛擬內(nèi)存、分頁(yè)、分段這些概念屬于基礎(chǔ)??嫉氖翘摂M內(nèi)存解決了什么問(wèn)題——讓多個(gè)進(jìn)程能隔離運(yùn)行同時(shí)允許進(jìn)程使用超過(guò)物理內(nèi)存大小的地址空間。而堆和棧的區(qū)別幾乎每年都考考察點(diǎn)包括分配方式棧自動(dòng)分配、堆手動(dòng)分配、分配方向棧向低地址增長(zhǎng)、堆向高地址增長(zhǎng)、效率差異棧高、堆低和存儲(chǔ)內(nèi)容棧存局部變量和函數(shù)調(diào)用信息堆存動(dòng)態(tài)分配的對(duì)象。C相關(guān)的內(nèi)存考察還會(huì)深入到內(nèi)存泄漏——程序運(yùn)行過(guò)程中不再使用的內(nèi)存沒(méi)有被正確釋放。筆試常考的形式是給一段代碼找出內(nèi)存泄漏的位置或者問(wèn)用哪些工具可以檢測(cè)valgrind、AddressSanitizer等。這里我多說(shuō)一句面試官問(wèn)這些其實(shí)是想知道你有沒(méi)有真正的調(diào)試經(jīng)驗(yàn)因?yàn)閮?nèi)存泄漏這種問(wèn)題光看不練是發(fā)現(xiàn)不了的。4. C/C語(yǔ)言與數(shù)據(jù)庫(kù)游戲公司最看重的基本功游戲公司技術(shù)崗C是繞不開(kāi)的主語(yǔ)言。無(wú)論是客戶端引擎還是服務(wù)端邏輯絕大部分代碼都是C寫(xiě)的。所以這套綜合卷里C相關(guān)題目占的比重相當(dāng)大而且考得非常細(xì)。數(shù)據(jù)庫(kù)模塊占比雖然不大但往往會(huì)有一道服務(wù)端玩家數(shù)據(jù)存儲(chǔ)相關(guān)的SQL題。4.1 指針、引用與內(nèi)存經(jīng)典中的經(jīng)典指針和引用的區(qū)別是C筆試的常青樹(shù)這套卷子也不例外。兩者的核心區(qū)別包括引用必須初始化且不能改變指向、引用沒(méi)有獨(dú)立的內(nèi)存地址從語(yǔ)義上講、sizeof(引用)得到的是所引用對(duì)象的大小而sizeof(指針)在64位系統(tǒng)下是8字節(jié)、指針可以有多級(jí)但引用不行。這些點(diǎn)不復(fù)雜但很多人被問(wèn)到時(shí)容易漏項(xiàng)建議用表格把區(qū)別寫(xiě)全記憶。智能指針也是高頻考點(diǎn)。C11引入的unique_ptr、shared_ptr、weak_ptr分別解決什么問(wèn)題、各自的使用場(chǎng)景是什么這是校招生必須清楚的。我見(jiàn)過(guò)一道很典型的題多個(gè)shared_ptr循環(huán)引用會(huì)導(dǎo)致什么答案是引用計(jì)數(shù)無(wú)法歸零造成內(nèi)存泄漏。解決方法是把其中一個(gè)改為weak_ptr打破循環(huán)。這道題在游戲項(xiàng)目的對(duì)象管理里有非常實(shí)際的應(yīng)用場(chǎng)景——比如場(chǎng)景對(duì)象和其子對(duì)象互相持有對(duì)方的shared_ptr時(shí)。const關(guān)鍵字的各種用法也是??柬?xiàng)。const修飾變量、指針const int* p和int* const p的區(qū)別、成員函數(shù)const成員函數(shù)承諾不修改對(duì)象狀態(tài)、函數(shù)參數(shù)const引用避免拷貝基本都是送分點(diǎn)但如果平時(shí)沒(méi)在意很容易在指向const的指針和const指針之間繞暈。4.2 面向?qū)ο笕筇匦缘墓P試出題方式面向?qū)ο蟆庋b、繼承、多態(tài)——在C筆試?yán)锖苌僦苯訂?wèn)什么是多態(tài)而是通過(guò)代碼題考。比如給一段包含基類、派生類和虛函數(shù)的代碼問(wèn)輸出結(jié)果是什么如果析構(gòu)函數(shù)沒(méi)有加virtual會(huì)發(fā)生什么。這里有個(gè)經(jīng)典考點(diǎn)基類析構(gòu)函數(shù)不聲明為virtual通過(guò)基類指針delete派生類對(duì)象時(shí)只會(huì)調(diào)用基類的析構(gòu)函數(shù)派生類的析構(gòu)函數(shù)不會(huì)執(zhí)行導(dǎo)致派生類中動(dòng)態(tài)分配的資源泄漏。正確答案是把基類析構(gòu)函數(shù)聲明為virtual。為什么因?yàn)樘撐鰳?gòu)讓delete動(dòng)作能沿著虛函數(shù)表找到最底層的派生類析構(gòu)函數(shù)實(shí)現(xiàn)從外到內(nèi)的完整析構(gòu)。字節(jié)對(duì)齊、構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序先基類后成員再自身也是常出的題。純虛函數(shù)和抽象類也是高頻考點(diǎn)。抽象類不能實(shí)例化純虛函數(shù)是接口約定由派生類實(shí)現(xiàn)。游戲開(kāi)發(fā)里的組件系統(tǒng)、狀態(tài)機(jī)、尋路算法經(jīng)常用抽象基類定義接口再派生出不同實(shí)現(xiàn)。筆試考這個(gè)本質(zhì)上是看你對(duì)面向接口編程有沒(méi)有概念而不只是記語(yǔ)法。4.3 數(shù)據(jù)庫(kù)SQL與索引基礎(chǔ)數(shù)據(jù)庫(kù)題在這套卷子里題目量不大但屬于送分題級(jí)別丟了可惜。常見(jiàn)考點(diǎn)包括SQL基本增刪改查、多表連接inner join、left join的區(qū)別、GROUP BY配合聚合函數(shù)的使用以及索引的基本原理。有個(gè)特別經(jīng)典的考察點(diǎn)是給一張表問(wèn)在哪些字段上建索引能提升查詢效率為什么。答案不是全建索引就完事——因?yàn)樗饕龝?huì)降低寫(xiě)入速度、占用存儲(chǔ)空間。正確思路是在WHERE條件、JOIN關(guān)聯(lián)字段、ORDER BY排序字段上建索引在高區(qū)分度字段比如玩家ID上的索引效果優(yōu)于低區(qū)分度字段比如性別。同時(shí)使用函數(shù)包裹字段、隱式類型轉(zhuǎn)換、LIKE前置通配符都會(huì)讓索引失效這些都是在游戲日志查詢中經(jīng)常遇到的坑。事務(wù)的ACID特性、隔離級(jí)別、臟讀/不可重復(fù)讀/幻讀的區(qū)別也偶爾出現(xiàn)。這些概念對(duì)服務(wù)端處理玩家并發(fā)操作非常關(guān)鍵——一個(gè)交易系統(tǒng)如果事務(wù)隔離級(jí)別沒(méi)選對(duì)就可能出現(xiàn)玩家同時(shí)買一件物品導(dǎo)致超賣的問(wèn)題。5. 筆試實(shí)戰(zhàn)中的通用策略拿到題目后怎么思考這部分我想聊聊比具體知識(shí)點(diǎn)更重要的東西——考場(chǎng)上面對(duì)一套綜合卷你的解題順序和思考策略。我當(dāng)年參加筆試時(shí)吃過(guò)虧后來(lái)幫別人做模擬面試也發(fā)現(xiàn)不少同學(xué)不是不會(huì)而是策略出了問(wèn)題導(dǎo)致會(huì)做的題也丟了分。5.1 時(shí)間分配先拿穩(wěn)定分再啃硬骨頭技術(shù)綜合卷的題量通常不小時(shí)間卻只有兩小時(shí)左右。我建議拿到卷子先花兩分鐘快速瀏覽一遍所有題目做一次難度分級(jí)第一檔穩(wěn)定分概念題、基礎(chǔ)知識(shí)選擇題。比如sizeof大小、SQL查詢、簡(jiǎn)單復(fù)雜度判斷。這類題要先做確保拿滿。第二檔重點(diǎn)分中等難度算法題、代碼閱讀題。這類題需要思考和一定時(shí)間放在中間做。第三檔拔高分綜合算法大題、開(kāi)放性設(shè)計(jì)題。放到最后時(shí)間不夠時(shí)至少寫(xiě)出思路框架能拿過(guò)程分。一個(gè)常見(jiàn)誤區(qū)是死磕某道卡殼的算法題做完一道再說(shuō)。筆試不是競(jìng)賽過(guò)線需要的是總分的穩(wěn)定而不是單題的完美。我見(jiàn)過(guò)不少同學(xué)在快排的非遞歸實(shí)現(xiàn)上耗了二十分鐘結(jié)果后面簡(jiǎn)單的SQL題和網(wǎng)絡(luò)題沒(méi)時(shí)間做非常不劃算。5.2 代碼題的答題規(guī)范思路比結(jié)果更重要手寫(xiě)代碼題閱卷老師通常有兩種評(píng)分方式一種對(duì)照測(cè)試用例看結(jié)果另一種按步驟看思路。很多公司的筆試題其實(shí)兼有兩者——代碼能跑通最好跑不通的話思路清晰也能拿到大部分分。所以寫(xiě)代碼題時(shí)我會(huì)這樣組織答案先在旁邊用一兩句話寫(xiě)明算法思路用什么數(shù)據(jù)結(jié)構(gòu)、關(guān)鍵步驟是什么再寫(xiě)代碼代碼里注釋重點(diǎn)行的作用。比如寫(xiě)歸并排序時(shí)先寫(xiě)遞歸拆分有序合并時(shí)間復(fù)雜度O(nlogn)再開(kāi)始寫(xiě)代碼。這樣就算個(gè)別邊界條件寫(xiě)錯(cuò)閱卷人也能看出你懂這個(gè)算法。還有一點(diǎn)變量命名盡量語(yǔ)義化。筆試代碼雖然不用達(dá)到工程標(biāo)準(zhǔn)但一個(gè)叫mergeHelper的函數(shù)總比f(wàn)1、f2顯得專業(yè)。這個(gè)細(xì)節(jié)在閱卷時(shí)是真的會(huì)加印象分的。5.3 心態(tài)與驗(yàn)證寫(xiě)完代碼一定要走一遍示例筆試時(shí)最常見(jiàn)的丟分原因是代碼寫(xiě)完不驗(yàn)證。建議寫(xiě)完一道算法題立刻用一個(gè)最簡(jiǎn)單的輸入在腦子里跑一遍代碼邏輯檢查邊界數(shù)組為空時(shí)怎么辦只有一個(gè)元素時(shí)怎么辦目標(biāo)值不存在時(shí)返回值是什么比如寫(xiě)二分查找時(shí)檢查左右指針的更新邏輯會(huì)不會(huì)死循環(huán)寫(xiě)鏈表反轉(zhuǎn)時(shí)檢查頭節(jié)點(diǎn)為nullptr時(shí)會(huì)不會(huì)解引用空指針。這些小細(xì)節(jié)平時(shí)在自己電腦上編譯運(yùn)行根本發(fā)現(xiàn)不了但筆試考的就是你在無(wú)編譯環(huán)境下的嚴(yán)謹(jǐn)度。平時(shí)練習(xí)時(shí)養(yǎng)成寫(xiě)完就走查的習(xí)慣考場(chǎng)上就不會(huì)心里發(fā)虛。6. 復(fù)盤(pán)與備戰(zhàn)這套卷子教我的幾件事最后聊點(diǎn)實(shí)際的關(guān)于這套2017年的試卷對(duì)后來(lái)備戰(zhàn)校招的參考價(jià)值。雖然題目逐年更新但核心考察邏輯是穩(wěn)定的。我復(fù)盤(pán)下來(lái)有幾點(diǎn)想強(qiáng)調(diào)的。把基礎(chǔ)概念理解透比刷題數(shù)量重要。這套卷子里的題目嚴(yán)格來(lái)說(shuō)沒(méi)有一道是超綱的全部來(lái)自教材里的基礎(chǔ)知識(shí)。但為什么有人考高分、有人掛在60分線上區(qū)別就在于對(duì)為什么的理解深度。快慢指針為什么能判環(huán)、虛析構(gòu)為什么能避免內(nèi)存泄漏、TCP為什么三次握手——這些問(wèn)題的答案教科書(shū)上有但沒(méi)有深入思考過(guò)的人考場(chǎng)上很難自己推出來(lái)。動(dòng)手寫(xiě)代碼和純看書(shū)的復(fù)習(xí)效果差別巨大。我準(zhǔn)備校招那陣子每天堅(jiān)持手寫(xiě)兩三道經(jīng)典算法題不依靠IDE提示寫(xiě)完用編譯器驗(yàn)證。堅(jiān)持一個(gè)月后筆試時(shí)手寫(xiě)代碼的流暢度明顯不一樣。強(qiáng)烈建議準(zhǔn)備階段用紙筆寫(xiě)代碼編譯器驗(yàn)證的方式練習(xí)這能模擬考場(chǎng)環(huán)境又能得到反饋。最后想分享一個(gè)小心得不要把復(fù)習(xí)局限于單一公司的真題。完美世界這套2017年A卷的知識(shí)點(diǎn)覆蓋面其實(shí)是很多游戲公司、互聯(lián)網(wǎng)公司技術(shù)筆試的共性。我當(dāng)年刷完這套卷子后再去參加其他公司的筆試發(fā)現(xiàn)很多題目只是換了層皮核心考點(diǎn)大同小異。把一套綜合卷吃透比零散地刷幾十套題效率高得多。如果你正在準(zhǔn)備校招建議拿這套卷子做個(gè)自測(cè)卡好時(shí)間做完然后逐題復(fù)盤(pán)自己的卡殼點(diǎn)。那些讓你猶豫的題目就是你接下來(lái)復(fù)習(xí)的重點(diǎn)方向。筆試沒(méi)有捷徑但走對(duì)方向、用對(duì)方法確實(shí)可以少走很多彎路。