網易互娛C++崗一面面經(涼麵)
前言
我報的網易互娛的提前批遊戲研發工程師C++崗,這個過程其實挺坎坷的,8月初跟著導師去黑龍江佳木斯開會,中途忽然間接到通知要筆試,從會場逃出來在賓館做的遠端筆試題,做的不是特別好,4道題只做對了一道半,沒想到還是過了筆試,感覺網易互娛的筆試不怎麼刷人。但是面試就比較全面了……現在想想,挺遺憾的,其實也沒什麼難的,基本上在書上都能找到,只是自己準備的太晚,很多東西複習的不好罷了。這是我2018年秋招參加的第一場面試,沒想到最想去的網易居然是拿來試水並毫不意外的掛掉了,有點難過。想進網易互娛的同學,如果本身能力不是特別強,還是要早點準備的好。
面試經過
網易互娛的一面是電話面,2018年8月24日(週五)下午4點打來的電話,和之前通知的時間點一模一樣,面試官非常準時。
Q:您好,請問是XXX同學嗎?
A:您好,我是。
Q:我是網易的XXX,請問現在是否有時間,我們……(一堆客套話)
A:有有有,方便方便方便(有點緊張,都是連續說了3遍)
Q:請問您最常用的一門語言是什麼?
(可能是公司要求,面試官挺客套的,全程是您,我每次答完之後,都會說好的,特別客氣)
A:C++比較熟悉一點。
Q:好的,那麼下面開始我們今天的面試,解釋一下C++中override和overload的區別?
A:(沒想到上來就問這個,有點懵逼,停頓了大約5秒鐘)overload是函式過載,C++支援同名函式不同函式引數形成過載機制,override是函式重寫,繼承中,子類方法重寫父類的虛擬函式(之所以先說的overload,是最開始沒想好怎麼解釋override,有點緊張了,這裡犯個失誤,C++對繼承的叫法是基類和派生類,而不是父類和子類,函式也不能叫方法,但是面試官默認了這一個叫法,因為下面他用父類子類來提問的,看來無傷大雅)。
Q:好的,那麼父類和子類如何實現多型機制呢?
A:主要是通過虛擬函式表來實現的,基類的函式被定義為virtual,派生類方法可以進行重寫定義自己的行為,其中包含定義為virtual函式的基類隱含一個指標成員,指向虛擬函式表,該表按照虛擬函式宣告順序儲存地址,派生類中也包含這樣一張表,如果發生重寫,就更新虛擬函式表的地址。
Q:好的,C++ STL庫瞭解嗎?
A:瞭解,但是不是特別深入(我其實對STL算比較熟了,但是我怕他問我底層實現,尤其是《STL原始碼剖析》那本書,沒怎麼看過,有點虛……)
Q: 好的,那說一下,vector、list和map三者有何區別?
A:vector底層是對連續記憶體的封裝,支援隨機訪問,訪問效率較高,list底層是連結串列結構,記憶體分佈不連續,但是易於移動和刪除,map是一種鍵值對映關係,底層由紅黑樹實現,預設按鍵值升序排序。
Q:好的,用過Boost庫嗎?
A:用過一點,不是特別熟(真的不熟……)。
Q:好的,能講一下嗎?都用Boost庫做了什麼?
A:只用過Boost的智慧指標,auto_ptr和shared_ptr,兩者都是體現的以物件管理資源的RAII思想(《Effective C++》裡面有講到過),其中auto_ptr對物件是獨佔式管理,多個指標指向同一個物件,只有一個是有效的,其餘都是NULL,當發生複製運算或者賦值建構函式時,被賦值的物件獲得物件的唯一管理權,而原指標被置為NULL,auto_ptr會在指向的物件作用域過期時自動回收資源。shared_ptr是引入計數方式的智慧指標管理類,允許多個指標指向同一個物件,並統計指標數量,當不再有指標指向資源時,自動釋放資源。兩者都保證了資源引用的安全釋放,類似於Java的GC機制。
Q:好的,那什麼是C++的異常機制?
A:(不是很熟悉,憑印象答了一下定義,感覺不是面試官想要的答案)異常用的不多,不是特別熟悉,異常機制是C++增強程式碼健壯性以及執行時安全的一種機制,主要通過關鍵字try/catch/finally/thrown等來捕獲異常,以及系統定義的異常類Exception等來進行異常處理。
Q: 好的,講一下深拷貝和淺拷貝的區別。
A:深拷貝是增加了一份資料副本,對拷貝的物件逐位複製,開闢新的記憶體,資料相對獨立而安全。而淺拷貝只是增加了一個指向,並沒有增加資料量。需要注意資料指向安全和資源管理。對於類而言,主要通過自定義拷貝建構函式和複製建構函式來管理深淺拷貝,一般而言,深拷貝只拷貝非靜態成員。
Q:好的,C++提供了哪些強制型別轉換符?
A:dynamic_cast、static_cast、const_cast和reinterpret_cast。然後簡單說了一下各自的作用。
Q:好的,能講一講程式執行時的堆和棧。
A:棧是由編譯器自動管理的區域,主要存放區域性變數等,堆則是由程式設計師控制,分配記憶體等。(感覺答得太簡單了,應該更深入一點的,講講實現)
Q:好的,什麼是堆?
A:(犯了一個低階錯誤,因為上個題剛問過我C++堆疊,我以為是記憶體的堆,結果答錯了,經面試官提醒,才知道自己答非所問,他問的是資料結構的堆,又重新說了一下……)。
Q:好的,你知道的排序有哪幾種?
A:選擇排序、插入排序、氣泡排序、快速排序、堆排序、歸併排序(怕問的太深,沒敢說太多,只說了最基礎的幾個)。
Q:好的,解釋一下什麼是快速排序,時間複雜度如何?
A:選定一箇中樞值,將待排資料分割為兩部分,左邊的都比這個值小,右邊的都比這個值大,然後遞迴執行左右子區間,直到全部有序。時間複雜度因情況而已,資料基本有序的狀態為O(n^2),一般情況下是O(n*logn)。
Q:好的,解釋一下什麼是雜湊表?產生衝突瞭如何解決?
A:一種簡直對映關係的資料結構,主要用於查詢。(解決衝突當時沒反應過來,我憑印象說了個開放定址法)。
Q:好的,解釋一下紅黑樹?
A:不好意思,我對紅黑樹不是很熟悉,只知道它是一種平衡樹,主要是用於優化查詢和排序的。
Q:好的,如何對一張圖進行遍歷?
A:深度優先,廣度優先。
Q:好的,那什麼是深度優先,什麼是廣度優先,兩者有何區別?
A:深度優先就是從一個頂點出發,從改點的任意邊開始向下遍歷,直到所有路徑上的所有頂點都被訪問為止,廣度優先就是從一個頂點出發,先訪問改點的所有鄰接頂點,然後再遍歷所有鄰接節點,直到訪問整張圖。
Q:好的,什麼是動態規劃?
A:(簡單解釋了一下動態規劃的定義)動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每一個解都對應於一個值,我們希望找到具有最優值的解。
Q:好的,解釋一下主流網路模型
A:(最開始沒懂啥是網路模型,面試官提示了一下,我說的是五層的,感覺應該他想問的是七層的)物理層、資料鏈路層、網路層、傳輸層、應用層。
Q:好的,什麼是TCP/IP協議?
A:(解釋了一下定義)TCP是傳輸控制協議,IP是網路協議。
Q:好的,那麼TCP/IP協議,分別位於OSI模型的哪一層?
A:TCP位於傳輸層,IP位於網路層。
Q:好的,TCP三次握手過程。
A:(大致說了一下流程,當時網路沒怎麼複習,說的不太細,感覺面試官不怎麼滿意……)。
Q:好的,TCP和UDP的區別。
A:TCP是面向連線的,保證傳輸資料安全。UDP是無連結的,盡最大努力交付(我僅僅回答了面向連線這一點,感覺遠遠不夠)。
Q:好的,說一下HTTP的長連線和短連線?
A:(完全懵逼,網路沒怎麼複習,HTTP不怎麼會)不好意思,這個不會。
Q:好的,做過scoket程式設計嗎?能不能講一講?
A:不好意思,沒有做過scoket程式設計。
Q:好的,做過網路程式設計嗎?有沒有做過網路程式設計開發?
A:(我回答說之前用Qt做過一個天氣預報的小外掛,使用的QNetworkAccessManager、QNetworkManager、QNetWorkRequest等使用,以及解析JSON等,說了一堆)然後追問,用的什麼協議?我回答,用的頂層的API,沒有參與協議的編寫,應該是基於TCP的(感覺面試官並不喜歡這種API呼叫,更喜歡你能實現底層原理)。
Q:好的,程序和執行緒的區別?
A:(解釋了一下定義)程序是作業系統進行排程和資源分配的最小單位,執行緒是排程的最小單位,程序擁有獨立的資源,執行緒依附於程序,共享資源(感覺答得太簡單了)。
Q:好的,程序中虛擬地址和實體地址是如何轉換的?
A:(感覺很熟悉,但是記不清楚了,憑感覺說了一下,貌似沒說對……)
Q:好的,如何實現執行緒同步?
A:互斥鎖和訊號量。
Q:好的,程序通訊,有哪些方式?
A:共享記憶體、管程等(最開始說錯了,說成共享資源了,面試官提示了一下,是共享記憶體嗎,我說是的是的是的……)。
Q:好的,做過Linux程式設計嗎?
A:沒有,不好意思(賊尷尬)。
基礎問了一大堆,之後就是演算法題了,答得慘不忍睹,更重要的是,當時實在是太緊張了,很多問題,其實不難,但是沒有向面試官展示自己分析問題的能力就直接放棄了,感覺這也是我電面沒過的主要原因吧……
Q:從n個數中取前K大的數,求時間複雜度?
A:我想了一下,用的快速排序,時間複雜度O(nlogn),但是面試官又問我,資料量非常大的時候怎麼辦?能不能做一下優化?我想了半天沒太好的想法,後來查了一下,這其實是個TOP n的問題,《劍指Offer》上有相關的講解,但是我沒複習到,用堆排會好很多,資料量大的時候比較省記憶體,同時比快排穩定。
Q: 有一張遊戲地圖,地圖上有一個圓,如何從地圖中圓內統計人數,並求時間複雜度
A:(聽懵逼了,線上筆試的時候就遇到了荒野求生的題,沒想到電面居然還有,我用最簡單的方法,直接對座標進行遍歷,計算圓的邊界,每一個人的座標是否在範圍內,他問是否能進行優化,又是優化,汗!!,我想了半天,還是沒想出來,就說一時半會兒沒有很好的想法)。
Q:從n個數中,找到一定範圍數,時間複雜度。
A:(我沒想出來,就說,直接遍歷,對每個資料進行判斷,他說這個太簡單了,能進行優化一下嘛?我想了一會兒,沒把握,就說不是很清楚,他說可以先做排序,然後直接取範圍內的數,我有點懵逼,排序的消耗應該比遍歷的要大的啊,但是沒敢問……);
Q:如何從n個數中,刪除重複的資料
A: (感覺用雜湊表應該可以,我說如果資料分佈不是很大,可以用雜湊表,他問時間複雜度,我說趨近於o(n),沒說行不行,也沒讓繼續優化,這是還可以的意思?不知道……)。
然後就是讓我問他幾個問題了,我大概問了一下接下來的面試流程,如果過了電面還有幾輪,他說,電面過了大概還有2~3輪,包括技術面和HR面,地點可能在杭州,具體待通知。如果不過,正式秋招沒有第二次機會(難受,一直以為提前批可以多一次機會……)。
總結
總的來講,面試還是比較基礎的,主要包括程式語言、計算機基礎和演算法分析設計3部分,我程式語言這一塊答得還挺好的,基本上沒怎麼被難住,都是平時經常用的,所以比較熟悉吧。但是計算機基礎和演算法這塊,有點弱,因為之前5~7月份的時候一直在參加網際網路+比賽,8月份的時候又去開會,自己又不是那種特別拼命擠時間的型別,所以複習的比較晚,很多地方沒顧及到,所以就悲劇了……現在12月份再回頭看,感覺這些問題都挺基礎了,自己當時弱爆了……
建議——
1. 《劍指Offer》是本好書,很多演算法題都從其中找到原題,如果不是ACM大神,還是早點刷刷這本書吧;
2. 程式語言:多看看《C++ primer》或者其他經典書籍,行有餘力推薦看看《Effective C++》。還有STL要熟悉(常用容器和演算法),如果可能,最好把《STL原始碼剖析》這本書也看一下,對資料結構也是一種提高。
3. 基本概念要會,更重要的是,要會說,我發現其實很多東西,都是知道,但是說的不溜,給人的感覺好像我很菜一樣……到秋招後期,身經百戰的我也變得賊能說,看來沒事還是要自己私底下多練練。
4. Linux和網路程式設計,由於實驗室的緣故,沒搞過這個,但是面試官賊喜歡問,有空多搞搞,記住幾條shell指令也挺好的,不能給人的感覺是這玩意兒我壓根不知道是啥……