你遇到過哪些高質量的C++面試?
- 請問C++標準的ISO編號?
-----------
好吧。我來說一個在stackexchange上看到的[1]。
-- 為什麼C++的member function template不能是virtual的
問題的意思是,為什麼在C++裡面,一個類的成員函數不能既是 template 又是 virtual 的。比如,下面的代碼是不合法的:
class Animal{
public:
template&
virtual void make_sound(){
//...
}
};
為啥勒?這個問題涉及到一點 C++ 的(實現)機制,所以很少人能一下子答上來[1]。
原因如下:
因為C++的編譯與鏈接模型是"分離"的(至少是部分原因吧)。
- 從Unix/C開始,一個C/C++程序就可以被分開編譯,然後用一個linker鏈接起來。這種模型有一個問題,就是各個編譯單元可能對另一個編譯單元一無所知。
- 一個 function template最後到底會被 instantiate 為多少個函數,要等整個程序(所有的編譯單元)全部被編譯完成才知道。
- 同時,virtual function的實現大多利用了一個"虛函數表"的東西,這種實現中,一個類的內存布局(或者說虛函數表的內存布局)需要在這個類編譯完成的時候就被完全確定。
所以,由上面的矛盾可知,C++ 的 member function 不能既是 template 又是 virtual 的。
[1]: What is the best C++ interview question?
我覺得高質量不一定是難度大。
畢業找工作的第一次面試,我還記得其中幾個個問題:
1,enable_share_from_this 是做什麼的,請舉一個場景說明?
然後就開始聊多線程編程模式、線程安全等問題。我覺得這個問題是一個很好的問題,從語言出發,擴展到工程經驗和對編程的理解。而且弱指針確實是c++非常有特色的一個特性。
2,如何實現一個引用計數指針,以及其中要注意的點?
這也是一個比較有內容的問題。大致說了一下方案,面試官又追問了諸如入侵性與非入侵性設計的區別、優劣,以及析構對象時多動態庫架構情況下本地堆問題,還有引用計數的多線程安全問題,有鎖怎麼實現,無鎖怎麼實現。
3,為什麼stl中的內存分配器要設計為一個模板參數而不是一個構造函數參數?
這個就屬於瞎聊了,各抒己見唄。最後扯到類型系統如何幫助程序員排錯之類的問題。
那次面試還有當場編程測試,我做了倆題目,一個是實現一個字元串的演算法,主要是考察buffer設計之類的,數學上沒什麼難度。另一個是bug排查,程序中設置了一個典型情況,就是內存越界。
這樣的問題你說多難也沒多難,但是對於基礎知識、理解力,甚至表達能力都有不錯的考察角度。我覺得這樣的面試就是高質量的面試。
而且面試題其實和offer大小也很有關係不是嗎?你總不能一個月給五千然後面試人家手寫紅黑樹吧?有些公司就這樣,面試題又偏又難面試官吹鬍子瞪眼,可是待遇又不好。最後人家過了也不來,何苦呢?
我當時面試的這家公司待遇處於校招二線水平,從面試題來看,他們還是很務實的。我本科畢業之後的第一次面試是在一家做晶元的公司。然後面了一些題目。大概七到八題,基本上是考察C和C++的generated code的行為。
其中一個讓我印象比較深刻的,是問為什麼C calling convention的參數進棧順序是從右向左的。
這個問題我當時沒答上來。
唉,說起來都是淚,有 (partial) template specialization 沒聽說過的,有 dynamic_cast 不知道是什麼的,有說不出 std::map 和 std::unordered_map 特性和各操作時間複雜度的。我都想提高一下面試質量。
面網易的時候面試官面我的內容:
vector和deque的內部分別是什麼東西
vector的插入異常安全是怎麼實現的
deque如何實現O(1)下標查找
三種智能指針分別是什麼
分別是幹什麼用的
怎麼實現的
曾經去巨硬面試,遇到的唯一一個純C++題是
「虛函數怎麼實現的?虛表放在哪裡?類與虛表的關係?對象與虛表的關係?虛……」系列。
坦誠的說當時我答錯了 ,可當時我已經工作九年了。真是顏面掃地。
後來我硬著頭皮讀完了《Inside the C++ Object Model》,在前述的那類問題里應該再不會翻車了。可是生活不能undo,就這樣吧。
希望對正準備面試的朋友有些借鑒作用。
----------------------------------------
想了想,自扒黑歷史乾脆再扒開一點吧,這樣可能對入門弟妹們更有意義。
他:「……虛表是怎麼工作的?」
我:「啊,虛表就是一個函數指針數組。每個類對象里存一個虛表,這樣就……」
他:「你等會兒,假設我有一個類,它有兩個對象,這時內存里有兩個虛表是嗎?」
我:「……#%+_^$@,……」
我到現在經歷了十幾次面試,面到純粹的C++語法的就只有一道題,還是微軟的HR問的:
C++的*有多少種意思?
???
見過一些抖機靈的問題,例如:
按10分制,請問你給自己的C++水平打幾分?
回答8分的不敢說是弱雞,但可能評價不高。回答5分的其實是7分。回答Herb Sutter或者Bjarne Stroustrup是8分的應該有8分。這個問題倒不是說C++不能自詡精通,而是沒聽過這題的一般經驗不夠豐富。
就C++語言本身來說我心目中比較考驗精髓的問題:
- C++為什麼要有class?考對oop基礎的理解,而不是考死語法。可引申出動態多態,RAII,類型系統,隱式成員等一票問題。大牛還是菜雞,用這一個問題就暴露了。
- 指針是什麼?你能不用指針寫C++程序嗎?指針好還是不好?這個問題不僅考C基礎和計算機原理基礎,還可引申出引用,拷貝和移動語義,const correctness,value semantic等一票基礎問題。
- 經典問題:vector和list有什麼區別?一個不了解C++如何控制資源顆粒度的程序員恐怕不是一個好的C++程序員。可引申出一大票演算法和數據結構問題。
- C++為什麼要有類型?考對靜態類型語言的理解和權衡,可引申出類型安全,泛型,模板元編程,編譯時計算,靜態多態等一眾問題。
相比起大方向的理解,細節問題例如虛表是如何實現的,或者某個關鍵字怎麼用,某個設計模式怎麼實現這類問題實在意義不大。程序員不是編譯器,不應該考程序員模擬編譯器的水平。程序員是人,軟體工程終極的目標是服務於人,應該考程序員作為人機交互中人的一端表現出的水平,即——我們為什麼要用C++,以及為什麼C++是這樣用的。
----------------------------------------------更一波答案分割線-----------------------------------------------
- C++為什麼要有class: 類是C++用來實現OOP封裝、繼承和多態的核心機制。C++用虛函數實現多態,用RAII(和析構,異常機制)實現自動資源管理,用拷貝和移動定義資源的複製和轉移,進而用隱式成員(Rule of 5,析構,拷貝構造,拷貝賦值,移動構造,移動賦值)來幫助用戶省去手寫冗餘代碼,最終達到不多寫一個字的資源管理。如果說面向對象的概念已經有些過時了,資源管理卻是永不過時的,也是C++從機制上不同於C的最主要一點。有些人寫的糟糕C++代碼其實是把寫面向過程套了一層class的皮、濫用多態讓代碼糾纏不清、最終既不僅沒有簡化邏輯,也沒有簡化資源管理。
寫過3年多一點的C++程序,常見的C++的特性都懂一點,後來跳槽發現市場上對C/C++的需求少,但是要求高!學習C/C++的成本很高,而獲得的回報卻比不上另外一些語言,如Java/PHP等,當然,如果是大神級別的,語言的差異可以忽略,當我說的是玩笑話吧!以下為正式回答,都是面試中的遇到過的,其實好多已經有回答提及:vector在resize時是原來的多少倍?
explicit關鍵字的作用?
dynamic_cast等幾種強制轉換(記不住了 )分別用在哪種場合?使用過可變長模板嗎?使用在什麼場合?(當時我一臉懵逼,其實現在也是 )實現一個不可被繼承的類。const char *a = "123";const char *b = "123";a == b成立嗎?有類的定義為:class t {};問sizeof(t)等於多少?如何解決多繼承造成的類成員重複的問題?類的static函數能訪問類的普通成員嗎?為什麼?
...有一次面試完,面試官(一個150多人的公司的CTO)對我的評價是:都懂一點,但是不精!我自認為也是這樣,C++語言本身的東西太龐雜了,人生苦短啊! 去年跳槽轉PHP了,嗯,PHP是世界上最好的語言!cpp多態實現原理容器rotate的三種實現vector如何動態擴容,stl默認內存池如何實現手寫一個shared_ptr(不考慮各種異常)僅遍歷一次ip字元串,判斷該ip格式是否正確
cpp實現向量的延遲計算
cpp定位內存泄露和profile的工具你們到底是要招工程師啊,還是科學家啊?對得上你們開出的薪水嗎?
高質量的C++面試?你敢搞我就敢讓你招不到人。
我面試別人的時候震驚過兩次。
一次是我同事出了一道編程題,刪除鏈表中指定節點。我震驚了,這tm也太簡單了吧?大學本科課後作業的水平啊!事實是,面過大約10個人,C++編程經驗2到5年不等,只有1個能寫出基本正確的程序,更不要說我期待的能寫出兩種方法來實現的。
另一次震驚是我給另一個同事的。我提了個問題,簡單講講你都看過哪些C++書籍?我同事震驚了。因為他是一個勤奮好學的好孩子,在他看來,這完全是送分題。如果是問他的話,他有太多能講。結果是,大多數人都露出了尷尬的表情,能提到C++ Primer和Effective C++任意一個的就算合格了,兩本都提到那簡直是佼佼者了。如果再問問書里都講了啥,你都學到了啥,那尷尬的氣氛簡直突破天際。
這裡有兩組面試題,都是最基礎的題目,但是輕鬆通過的話已經超過我面試過的所有人。
Welcome to the C/C++ Quiz!C/C++ Quiz 2順便問一下,這兩組題給的時間都是1小時,但是幾乎沒有遇見都答完的情況,是因為題太多了嗎?
------------- 更新分割線-------------------
經提醒,修改了Quiz 2的第七題,確保能編譯通過。非常感謝!
Quiz 2的第六題,在有些編譯器上是編譯錯,有些是運行錯。
最後,我司非常窮,開不起高工資,請不用惦記了(所以沒有牛人投簡歷)。並且現在沒有head count。
------------- 順手再更一下-------------------
我覺得評論也挺開眼的,你們說對嗎?
把c艹當高級彙編用的表示一個問題都答不上來.
2017春招,鵝廠問了虛函數和虛表,m$問了面向對象?,呃好像和c++沒關係,總之針對語言的問題質量都挺低的..
---更新的分割線
講個鬼故事,我面試被問了c++結果來寫最好的語言
8月18日更新,說實話,共享指針還有弱指針確實是非常重要的東西,但是我個人覺得更多的時候是在多線程程序中有大用處,一般都是較大規模的cpp程序了。然而一個學生,或者說一個本科生哪來那麼多機會用cpp去寫大規模的cpp程序,現在學校的實驗室不都流行搞機器學習嗎,如果是學生團隊,那也得是搞cpp的團隊較優秀,這樣一來人就更少了。
所以我一直很好奇他們#校招#問這些東西的意義。就算學生答出來了,真的不用懷疑他是臨時抱佛腳的?原答案:
智能指針,虛函數表,設計模式,還有什麼各種特性啥的,認真刷兩天牛客基本就能應付了。大多是記憶性的(有一定基礎的前提)。而且現在的面試很僵的,考網路就是三次握手,4次揮手,time_wait,epoll,select,tcp流量控制。考os就是進程與線程的區別,i/o模型,中斷啥的。都是套路!今年春招騰訊二面,那總監問我「是不是我問的都是你準備的啊?」。我能說什麼!我能說你們問的牛客上全有嗎?後來面另外一個公司就6了,人家直接給一段代碼,讓我優化,我當時還覺得那代碼寫的沒問題啊。媽的,後來才知道這考的是體系結構,考的是數據相關,分支預測,還有cache友好。這東西就不是能背出來的,沒有足夠的經驗和紮實的理論基礎,根本不可能的。
恕我直言,單獨考cpp語言特性真的沒啥意思,那啥智能指針,虛函數表,啥動態cast,平時用的非常少,我面試前把他們都突擊一遍,然後面試時都答出來了就說明我很會寫cpp了?4月份的時候,我能清楚的寫出share_ptr的實現代碼,然而剛才看到這個詞時,我還得使勁想下這東西是個什麼原理。被問到過一些怪異的問題,用cpp11之前的版本實現反射,閉包機制,判斷輸入類的繼承方式。
想起05年北京,當時也在外企。但有個adobe面試機會。我抱著興奮的心情試試去了。兩位華人工程師全程英文面試我C++,難不難?其中有一個問題是有關解釋template specialization。用英文描述起來,那真的憋屈呀。沒面試過。當時我想adobe你B格太高了。我工程師一枚,你對英語口語要求這麼高。我工作過2家外企。CL面的時候沒面英文。UBI面的時候問的英文較簡單,C++問的也不複雜。而工作中會讀寫英文就可以了。哦,還面過微軟首面,電話面試C++,通過。非英語。
寫一個程序對給定數組排序,考官給出的答案是std::sort(a,a+10000)
面試都不敢問,問了的話一年也招不上人。
不過已經習慣了,反正這些看起來nb的語言特點,用不用也沒什麼區別。
無論是虛函數,模版,還是stl,序列化,不用就是了。主體用.net/python實現,c++只負責實現基礎數學庫。
而且有些特性,在c++算是奇技淫巧了,但是換個語言解決起來則不費吹灰之力。
比如c++解決反射,就能讓無數英雄折腰,什麼各種nb宏,什麼動態庫混入調試信息反解。
比如stl的各種約定,內存池,智能指針,換個語言,解決起來非常簡單。
c++的很多高級特性,只是這個語言本身帶來的複雜,並非實際需求引進的。
下面的一些,是我被面試(2012年)時候被問到的。
1. c++程序如何做單元測試?2. c++程序如何和其他語言交互?
3.說說你對並行思想的理解及其實現方式,包括進程線程和集群,談談每一種的調度方式,穩定性,資源控制特點。
4.平時如何寫文檔? 談談對設計文檔和代碼注釋的理解,怎麼看待團隊統一代碼風格?
5. 如何看待第三方庫? 如果你想引用一個第三方庫,程序裡面要做哪些操作? 文檔裡面要做哪些操作? 如果某一天因為某種原因,第三方庫不能繼續使用,如何更換?
6.如何做程序優化? 程序裡面有3種語言,c++,matlab,python,運行在2台機器上(cs架構的影像伺服器)。代碼量比較大,svn代碼目錄有1gb多,構建一次工程需要2小時左右。 應該如何著手優化程序性能??筆試
解釋下什麼是「重載」
答: 重新載入程序(寫的洋洋洒洒,一個研究生)
推薦閱讀:
※面試失敗後,你收到過最有情懷的拒信是怎樣的?
※想提高演算法能力是做網上面試題好還是刷ACM題目好?
※去面試一定要在網上先投簡歷嗎?可不可以提前主動打電話預約面試?
※說說你所遇到的那些奇葩面試官?
※G30早稻田本科面試會要求在面試中做題嗎?