當面試官問我C++ 11新特性的時候,應該怎樣回答?
自己籠統地了解一些,比如lambda表達式(之前會一點Haskell)、auto關鍵字、智能指針,但是都沒有實際使用過,準備面試過程中也不知道應該學到什麼程度。
希望大家發表自己的看法,給自己一些建議。
關於C++11,介紹的時候,先分個類吧:
- 革新
- 語法糖
- 標準庫的擴充
- 老語法bug的fixed
面試官最想聽的肯定是第1點,然後第2點。沒得聊了就聊第3點、第4點。
1. 革新有啥呢?
很多啊。一言以蔽之是啥?——模板。模板肯定不是C++的新事物,但C++11的很多革新確實是圍繞模板展開的,或者說都能和模板搭上點曖昧關係。。(個人感覺智能指針真的沒什麼好談的,想裝逼,談模板)
decltype關鍵字,編譯期推導表達式類型。
可變參數模板(class...、typename... ),這真是元編程強有力的幫手。
函數模板的默認模板參數(叫做語法糖,似乎也可以);模板的別名(這個其實真的是語法糖了)
然後就是幾乎你不說,面試官也可能會問你的右值引用(),move語義(std::move)和完美轉發(std::forward&
綜上,自此C++編程終於從一門嚴肅的編程語言開始轉向腦筋急轉彎了。。
函數對象的概念被擴充了,,不過我感覺都算語法糖吧。
另外還有一個小點——nullptr。。也算是小革新吧,C語言指針的鍋該甩了。。另外nullptr真不屬於語法糖,這tm要算也應該算個 bug fixed吧。。
2. 語法糖有啥呢?
列舉幾個:比如auto關鍵字(自動類型推導),配合容器、迭代器、「各種」函數對象使用簡直不要太好。
lambda表達式(匿名函數對象),你可以將其理解為語法革新,但我傾向於它是一種語法糖。因為它要解決的工程問題,C++11之前基本也能做,但比較麻煩,有了lambda則變得十分高效簡潔了。
初始化參數列表。。這個肯定也是不得不說的一個語法糖了。。C++真的是向腳本語言學習了很多。。
類的非靜態成員在聲明時賦值。。Java程序員肯定笑了。
基於範圍的for循環(Java中稱作增強for循環)。Java程序員又笑了。
模板的別名。。恩,又說了一遍。。
3. 標準庫的擴充
這個其實沒啥好談的,無法就是將boost庫里幾個備胎轉正了。比如智能指針shared_ptr、unique_ptr。另外weak_ptr(本質上不上智能指針,只是shared_ptr的助手),而auto_ptr則是在C++11之前就存在的,現在基本棄用。。還有就是bind啦,並非是unix中socket操作的那個bind哈!而是和快速組裝一個函數對象的bind綁定器。
另外就是標準庫終於有了「散列容器」,只是它的名字叫unordered_map/unordered_set/……,並非是hash_map/hash_set/……,(可能是因為hash前綴的容器名被第三方庫給用爛了,介面又不統一。C++標準委員會只能無奈給孩子改名了,逃)。
還新增了一個容器——元組(tuple)。。感覺也是從腳本語言處得到的inspire吧。。
線程庫第一次被納入到公眾庫中,從此C++不再需要使用Unix C的API來處理線程和非同步啦。當然你把線程庫,看做是革新或許也是合理的。
其他新增庫還有很多,比如時間日期庫——chrono,還有新增了很多演算法。。不一一介紹了。
4. bug的fixed
最容易想到的就是模板的&>&>中間不需要加空格了。。。其他的bug fixed,我拋磚引玉請網友們補充吧(其實一時之間,真的窮舉不出來了。。囧)。當然了C++的bug肯定還是存在的,每當你新標準解決了上一代的bug,但是在增加新特性的同時,卻會引入更多的bug。。
切記,作為程序員在工程實踐中,不要貪戀奇技淫巧,小心弄巧成拙。工作了之後,你會發現:很多編程語言的的高級特性,你最後一次用到它是在面試的時候……
把你知道的都列舉出來,然後問您想聽哪個?
現在都c++20了。你老了。我給你說說新特性。
像lambda表達式,起碼要把幾種常用的情況,是否捕獲參數、值捕獲、引用捕獲、有無返回值等,都會用,並且能寫出代碼來。
其他的,正則表達式,也是類似,常見的幾個正則模板類、特化類,方法,都要能說得上來,並且能構造一些示例來使用。
……
所以,如果你只是知道,那接下來,就寫代碼,寫代碼,寫代碼!
知道多少回答多少啊,面試不都該這樣嗎。
除了能描述出大體的概念以外,最好能補充說明每一個新特性都是為什麼要引入進來的,目的是什麼,為了解決什麼問題。在沒有這些特性的時候,這些問題是如何解決的。目前的標準裡面還有哪些缺陷,後面會如何完善,等等。
為了達到這種效果,除了看大量資料以外,還需要實際動手去進行試驗。
有些特性在實際工程中很少用到,這些不了解也沒什麼問題。
具體怎麼回答還是需要你自己來探索,沒有實際使用過肯定是回答不好的。
11最核心的新特性,無非就是lambda和右值引用+移動語義。
可以說一點一般人如果只看教程 手冊 所不常用卻很有用的特性吧。
例如:很多人知道11之後
std::string a=「1」, b="2";
std::string c=a+b 很高效率了。因為有了右值拷貝構造嘛。
殊不知,最高效的方法卻是
std::string c=a+b;
這其實才是當時最期待的右值特性,因為std::string c=a+b 在03里,也可以通過swap語義達到等價的優化效果。
換而言之,顯式的使用具名右值(其實是左值了)來延長匿名右值的生命周期是最划算的。我見了好多在我面前賣弄右值拷貝的人都不了解上面這種基本語法。
下面有評論同學告訴我是錯的,說高版本編譯器的返回值優化已經可以穿越函數,函數返回值,函數返回值用於構造, 這3個過程了。。。有機會我也去試下,但是我個人真心推薦直接使用顯式的語法而不是依賴編譯器的隱式行為。
我之前面試應聘者時問了這個問題,希望聽到他回答他在項目中使用了哪些特性,以及自己的理解,遺憾的是他僅僅是知道某些特性,但都沒有怎麼使用。
最後我發現我是個很水的面試官。。。
那我就先說說ISO-14882吧
比較有聊頭的是 智能指針 移動語意左值右值這些 推薦effecttive modern 那本
從語法和標準庫兩個方面來答
會多少答多少,平時不用就說完概念然後直接說我平時其它語言用的多了。話說都17了,怎麼不問17都加了什麼,說明面試官也一知半解,他都不一定能深刻理解這些新特性,就如我,因為我平時也不用,畢竟python用的多,答不是所有程序都用過python,如果簡歷寫的精通python,我肯定問源碼了,但其他語言我也就問個大概,畢竟語言是最不重要的
告訴你知道的即可 比如auto deltype 智能指針 for 多線程 lambada 右值 即可
實事求是。不知道的就直接說沒用過,不了解,不要強答
effective modern c++
所以你用這些特性寫過幾行代碼?
然後再說為什麼會引入它們的問題。
不如跟面試官說,今天我回答出來的特性,今後我都會用到工作的項目之中。所以,你希望我回答出哪幾個(#手動滑稽)。
你反問,你們請的是底層碼農,還是模塊設計師?還是系統分析師?還是架構設計師?
如果是第一個。。不好意思。我的專長不在這裡。
推薦閱讀:
※既然c++模板元編程是圖靈完全的,那麼刷leetcode的時候如果都用模板元編程,能不能全刷成0ms?
※如何使用C++實現一個and函數?
※如何在 C++ 代碼中提示編譯器某個分支的執行概率高?
※C++定義一個函數,返回值為一個對象,如何想辦法返回一個邏輯上的空值?
※C++ 函數如何返回多值?