怎麼樣才算是精通 C++?

對提問作補充幾點:
1. 精通C++的學習路徑.比如需要閱讀哪些書籍,參與哪類項目,完成何種開發體驗.
2. 能力達到何種水平,才算精通?代碼經驗,項目經驗,開發技巧等等.
3. 精通C++的學習成本.諸位大神分享一下,學習曲線,學習過程,以及走過的彎路.
4. 如何高效提升C++水平.


精通C++是一個艱巨的任務。為什麼C++比別的語言難學這麼多?其實這基本上是因為C++他爹Bjarne Stroustrup說過的一句話「我特別討厭語言的設計者把自己的喜好強加給用戶」(看向go)。結果C++為了不限制你的想法,於是也就變成了現在這個樣子——包含若干範式,大概有

  • 面向對象(靈活應用virtual繼承+shared_ptr可以達到java/C#的效果)
  • 模板(這裡分兩類,分別為type rich programming和meta programming,區別很大)
  • 函數式編程(如今有了lambda,配合&文件,簡直無敵了)
  • 過程式

但是難能可貴的是,這幾種東西在C++混在一起用也是多麼的自然。不過,這需要你花時間去掌控他。

那到底有沒有必要真的學到這個地步呢,我覺得跟你的領域是有關係的。譬如說我,基本上算是人格分裂的,因為:

  • 當我搞語言設計和編譯器的時候,我總是會傾向於創造各種小DSL來給自己用,用的都是模板(想想boost的spirit大概就明白我的意思了,雖然我不用它),盡量讓跟我有同樣背景的人一眼能看懂我代碼的意思。
  • 當我做我那個GUI庫(www.gaclib.net)的時候,純粹是用OO和IoC那一套。
  • 當我寫3D渲染程序的時候,我會變成一個為了性能不惜犧牲可讀性的人。

當我是不同的我的時候,我當然只會用C++的一部分來完成我當前的這個任務。這好像是多重標準,但是實際上是由於項目本身的性質而定的。

到了這個時候你會覺得,C++真是一門好語言。當你需要為了你的項目放棄不同的部分的時候,C++都能幫你做到。當你需要不同的抽象層次需要不同的性能要求的是,C++還是能夠幫你做到。如果你用別的語言,你最終會發現那個語言只能做某幾類的項目。這是因為,C++能夠自由的讓你放棄某些部分,而別的語言會阻止你放棄某些部分

為了達到這個層次,你必須進入一個無限接近於精通C++的狀態里,這個時候你才能收放自如,不被C++社區的各種不同的價值觀所捆綁。倘若你的項目非常大,不同的部分有不同的特徵的時候(什麼,一個沒有遍布全世界的一兩千人寫了20年的程序能叫程序嗎?),就更加需要你有這種本事了。

說到這裡,大家大概都明白精通C++大概是個什麼感覺了吧——大丈夫能屈能伸


最近在全職做c++程序的優化,發現這個語言真的是太複雜了。心累,但是非常有挑戰性。我覺得精通c++這件事情是水到渠成的,硬來不行的。

原答案:
-至少一次遇到 "Sorry, feature not implemented"
-至少一次遇到template報錯長到你找不到頭,因為terminal的buffer不夠
-能看懂gcc想表達什麼,而不再看gcc字面上寫了什麼(clang不算)
-代碼裡面看不到new/delete,再敢於用起new/delete
-各種design pattern的好處壞處都能理解
- 跟人在論壇上面大幹一架
- 理解「精通c++」這件事情連committe都沒幾個人能做到,每個公司還對這個語言的未來有不同的理解
-放棄「精通c++」這個偉大而艱巨的任務

抖個機靈。其實個人理解,編程要上一個檔次,要多接受不是跟c++直接相關的新知識。我對c++理解有質的飛躍其實是學了OS 和 OCaml/JavaScript了之後一波,上班之後被人code review是一波,修c++的程序又是一波。後面看meyers的書其實意義已經不是很大了。很多時候只是通過那些書了解這個輪子的細節,而不能理解這個輪子到底在那種車上跑,能跑多快,什麼時候會散架。


谷歌工程師對C++的掌握有兩個級別:

1. 擁有C++的readability(可讀性)認證。通過這個認證需要在實際工作中寫出一個比較複雜的完整的類,然後將這個類提交到一個委員會進行審查,委員會會幫你糾正常見的錯誤,如果你的這個類滿足style guide[1]的所有要求,一兩個星期之後你就可以拿到可讀性認證。一般來說,你需要在實際工作中寫過至少幾千行代碼才能達到這個要求。C++的readability對工程師的意義主要有兩個,一個是熟悉並避免C++的缺陷(比如不要使用iostream和exception),另一個是熟悉一些常用的庫函數(比如string的各種操作,hash_map和smart pointer的使用等)。通過這個認證之後,工程師就有權利在code review中審閱其他人寫的C++程序(注意這個不是readability review)。絕大多數工程師對C++的掌握處在這個水平。

2. 顧問級C++程序員。一般需要寫過數萬行C++代碼,用C++實現過比較複雜的系統,熟悉常見的設計模式並在實際工作中應用,對代碼重構有豐富經驗,最重要的是,成為小組以及周圍同事的C++顧問,是同事有C++使用問題時最先想到詢問的人。顧問級C++程序員通常是高級工程師(senior engineer)及以上級別,不僅對某種程序語言,對工作中的各種工程問題也經驗豐富。

其實「精通C++」並不僅僅是熟悉C++本身,你需要對C++需要實現的工程問題和周邊問題同樣精通;而且「精通C++」這種說法是相對的,如果你能成為組裡的C++顧問,能夠幫助同事正確使用這種語言有效率地解決工程問題並避免C++的誤區,你就算是精通C++的那個人。

[1] http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml


說實話看了樓上各位的回答後,我就不知道說什麼好了,該說的都給說完了。
按照二樓的說法,我應該是屬於「顧問」那一類的C++程序員。(跪
如果說熟練使用沒有坑就是「精通」,那我想樓上很多人都能做到。但是在這裡恐怕我猜樓主是想要個更加炫的答案。

按照樓上@vczh 的說法,C++是一個典型的多範式語言,不過他概括的還不夠全面。C++是四類範式的組合體:過程式/結構化面向對象代表Lambda的模板(元編程)以及作為一個Markov Machine也具有圖靈完備性的宏。此外還有一個我不知道怎麼歸類的type rich programming。

在這四類範式之外,還有各種各樣的奇技淫巧。這裡我說的奇技淫巧,並不是指Boost.MPL或者Loki那樣的,那些其實都是C++基本範式中的衍生做法,都是最規矩的。

這裡的奇技淫巧,給大家舉兩個例子。比如在C++03時候,還沒有explicit type cast operator,那要安全的提供operator bool,還要利用member function pointer的特殊轉化規則;又比如BOOST.AUTO在VS2008上利用了一個Bug完成的實現。奇技淫巧的問題在C++11消除了一部分,但是又增加了一些,比如說左值/右值引用的摺疊,就是不是一個邏輯上自然的、而是設計後的產物。

此外還有一些坑。比如說重載-多態-名稱掩藏、虛繼承、指針的轉來轉去導致的問題什麼的。

這些都還是最最基本的常識性問題。要是應用到生產中,就會變得更複雜。什麼時候用繼承,什麼時候用模板,什麼時候用多態,什麼時候用宏。好在有一些前輩已經給我們淌了路,比如說Shutter,比如說Meyes。熟讀 6E(Effective C++,More Effective C++,Exceptional C++,More Exceptional C++,Exceptional C++ Style,以及Effective STL),這大概是進階的唯一階梯。

再往上你學C++就沒啥用了。多學一學其他語言,例如Haskell,ML,Javascript,C#,自己做一做編譯器,了解一些語言設計上的常識,讀一些形式化系統的論文,都會幫助你對C++這麼一個複雜而醜陋的語言產生更多的同情。

當你開始覺得:C++的設計者真可憐;埋怨英文標點實在太少並開始同情BS;決定自己捲起袖子擼一個的時候,大概你就算是精通C++了。

當然擼的好,就是Rust;擼的不開心,那就是Go了。


Never trust a programmer who says he knows C++


href: Never trust a programmer who says he knows C++ by Louis Brandy


精通沒有標準,但學習有路徑。 我來說說 學習掌握C++的路徑吧,從低到高,分0~10級:

0級:掌握常見C++語法和語言構造,能夠順溜地寫清楚各種語言構造(很多小白鼠死在這裡)
1級:掌握基本的編程範式:面向過程、面向對象、泛型編程、以及C++11/14支持的函數式編程
2級:清楚編譯器在 後面幹了什麼(compiler under the hood-考驗功力的時候到了)
3級:清楚運行時內存模型(memory under the hood)
4級:對經典庫(包括但不限於STL, BOOST, Folly)應用熟練,關鍵原理清晰,掌握設計模式
5級:熟悉至少一個操作系統常用API和內核,調試工具和方法
6級:有清晰的機器和系統模型:CPU, Memery, Cache, GPU, Disk, I/O, Process, Thread, TCP/IP...
7級:有一定系統級應用開發經驗,被系統級應用的性能、內存、規模等問題折磨過,並解決過...
8級:從頭到尾設計過一個C++庫、或框架,並被一定量級的應用使用過
9級:設計並開發過系統級、高性能、大規模的軟體系統
10級:成為Bjarne Stroustrup,設計一門語言

當然,這些打怪升級並不完全線性遞增,有些需要綜合運用。修鍊則需要 研習+實踐,反覆螺旋。

最後安利一下我正在主持操辦的「2016 C++及系統軟體技術大會(10月28-29日,上海)。C++ 之父Bjarne Stroustrup 將出席並發表keynote演講:《What C++ is and what it will become》 ,除了Bjarne之外,還有C++大神Andrei Alexandrescu,Mike Spertus等。

就拿這次會議的嘉賓來說,個人認為,Bjarne Stroustrup和Andrei Alexandrescu當屬於第10級(別忘了Andrei除了在Facebook做了7-8年研究科學家,還是D語言之父)。 Mike Spertus 屬於第9級(Symantec Fellow),然後大會其他嘉賓基本集中在第7級~8級之間。


偏一下題,提一下幾個微小的意見。

感覺不應該去精通某一門語言;而應該去精通某一個領域,然後附帶著理解跟這個領域相關的知識點。而編程語言是這些知識點的一部分。

比如搞操作系統的,就附帶著了解C/彙編,附帶著了解32位定址的知識。

搞網路的,就懂得處理各種複雜的情況,處理各種瑣碎的斷線重連/容災備份等問題,熟悉網路編程的各種坑。比如tcp/ip協議,比如epoll模型等等。

我自己是做OCR的,那麼我需要的就是模式識別方面的知識。至於語言,為了做界面我用OC,為了性能和可以方便調用opencv我用C++, 未來還可能為了快速原型開發用一下lisp。然後就是各種專門的演算法,比如圖像中提取字元的演算法,svm等等。

如果把程序猿比作士兵,那麼熟悉編程語言就等於熟練基本功。但是不可能7-8年一直熟悉基本功吧。投入3年左右的時間做基本功,然後就應該想法子投入專門的戰場作戰。然後在戰場中再熟悉各種專門的基本功。

======================================================

回到題目上來。感覺還是lisp好。要精通也是精通lisp啊……


獨立寫出一個 C++ 編譯器工具鏈(預處理-前端-後端-標準庫)。
這是少數有效的充分條件。

ps. 有鬼佬推出了它的認證:C++ Grandmaster Certification [CPPGM]


對於精通方面,我的理解是實用主義。
像輪子哥說了很多C++特性,很多我沒接觸過。身為一個架構師,比較汗顏。
但我個人奉行實用主義。所以在C++方面,我的學習是這樣:
1. 一定要掌握調試。調試掌握的程度呢,我個人是達到彙編級調試。基本上,基本上C++那些數據類型,通過調試,我都在彙編級別了解過了。
2. OO思想一定要掌握。能夠很快用UML把邏輯了解清楚。

至於那些特性,該用時就用,不用管。


「怎麼才算是精通xxx」這個問題太難回答,無論標準如何定,都會有人不同意,不是嫌高就是嫌低。

「哪些人算是精通xxx」這個問題比較好回答,具備可操作性,不如我們先解決這個問題?

我肯定不在精通C++的人裡邊。

哪些人算是精通烹飪?你認不認識這樣的人?
哪些人算是精通攝影?你認不認識這樣的人?
哪些人算是精通駕駛?你認不認識這樣的人?
哪些人算是精通騎自行車?你認不認識這樣的人?

哪些人算是精通彈鋼琴?你認不認識這樣的人?


精通就不必強求了,live is too short to program in C++.

學習 C++ 可以經過這麼幾個階段。第一是找一本不太「膨脹」的 C++ 教材。基本上掌握 class , overriding, overloading, 最簡單的 template (完全不用掌握 partialization )。

第二步是好好閱讀《 The Design and Evolution of C++ 》。因為有人說過,一門學科的全部就是它的歷史。

接下來你可以學學編譯原理,看看高級動態語言,為第四步做準備。

第四步,也就是最最關鍵的一步。好好看看 C++ FQA (沒錯,不是 FAQ ,不是 frequently asked question ,而是 frequently questioned answer )。http://yosefk.com/c++fqa/ 這些揭穿了 C++ 設計者從自身角度文過飾非編寫的春秋筆法。《 The Design and Evolution of C++ 》解釋了 C++ 為什麼是一個怪胎,但是它還是一個怪胎。


C/C++總共分成四大流派
1.c風格流派
2.面向對象流派
3.模板元流派
4.混合流派

很難全面掌握C++,這個語言一共有18個以上的大的知識點。比其他語言要多出1~2倍,複雜度則要提升到3~4倍。先確定你要用的內容,然後再學習即可。

比較合理的路線是:先從c風格學起,逐漸接觸面向對象,再過渡到模板元,最終做到綜合使用。

但是,每一種流派都存在自身的優缺點,不存在誰比誰更好的問題。比較著名的程序員中,雲峰是c風格的,免費打工仔則是模板元的。

而對於大部分人來說,熟練掌握面向對象已經能夠很好的完成工作了。


曾經用了近八年的C++,自己的Blog也在cppblog上,當時已經達到了不用「run」就能知道有哪些warnings,哪些errors了。。。這算精通吧。。。
四五年沒關注,一天翻看一段代碼,愣是沒看懂,跟人說「這是Java嗎?絕不會是C++!」。。。實際那是標準的C++代碼,用了C++11標準的代碼。。。
現在我都說「C++啊。。會點。。。」


我斷斷續續寫過十年C++程序,曾經以為我已經對C++很精通了,但是在看了半本《Modern C++ Design》以後,我發現自己根本不會C++,之後就改Python去了…
供參考。
另外可以參考這個:
C++ 這門語言的優點體現在哪裡?


今日看到大把的同學的簡歷上都寫著「精通c++」,」精通xxxx」,其實他們可能只是會寫個helloworld,知道class是個關鍵字而已吧.其它的我都不是太懂,唯獨c++研究過些時日了,自己心中的精通為何也早有定義:
1)知道所有關鍵字的含義,這個是最基本的.有很多很少用的也必須知道..比如auto,mutable,explicit,volatile...
1.5)通讀過一遍 ISO C++標準
2)STL的使用和基本實現原理.
3)《Effective C++》,《More Effective C++》...之類的經驗手冊型書籍熟讀3本以上,其中大部分條款要爛熟於胸
4)boost庫的整體框架要了解,清楚其中某些實現的超級BT的庫不能被某些編譯器編譯的原因。還要清楚哪些庫將會被iso c++ 收錄...用到某些功能的時候會不由自主的想到「boost 中有這個功能?」結果花上比自己手寫還要多的時間去使用boost.
4)看過Moden C++ Design,loki的實現原理要清楚..當然也要知道loki是幹什麼的...
5)林銳的《高質量C++編程指南》後面的習題能得到90分以上(記得是第一次做,以後補的不算!)。
6)C++中的線程安全模型是怎樣的。
7)C++中的字元串處理庫,包括C++對unicode,多種語言編碼的支持。
8)預編譯命令都知道是用來幹什麼的和常見的使用習慣...
9)平時最常用的一個編譯器的所有編譯選項熟記於心,以及他和ISO C++定義的編譯器的差別
10)這條湊數...不管怎麼樣,也要會用gcc...這樣保證了在每個平台下面 都可以編譯個helloworld

按上面的標準查看下自己...還是要繼續努力啊...


以上內容轉自 http://blog.sina.cn/dpool/blog/s/blog_720483030100yw3a.html?


千萬不要精通c++,至少要在精通一門其它語言之後再來精通c++
否則太容易把c++的諸多設計缺陷、以及許多用於解決這些缺陷而衍生出來的技巧,當作理所應當的開發方式。輕則禍害自己,重則禍害團隊


自己沒精通,所以不知道精通是什麼樣的。
實際的面試中,一般按照以下的標準來區分水平。(隨便寫的,不成系統)
1 聽說過C++
常見的問題 什麼是類,什麼繼承
new和malloc有什麼區別
什麼是虛函數,什麼是虛繼承
之類的泛泛而談的入門問題
2 會C++
new實際上執行了什麼操作,可能在什麼步驟出現異常
怎麼寫一個class,禁止分配在棧上
怎麼突破private的限制訪問變數
虛繼承的細節
怎麼自己模擬實現引用
3 比較了解C++
主要是一些邊角的語法或者是不常見的問題
逗號表達式,位域
初始化列表的異常怎麼捕獲
對於常見的主流編譯器,寫不寫inline有什麼影響
完美轉發
怎麼在編譯器判斷一個類中有沒有定義某個特定的方法
構造函數中調析構函數會有什麼結果


怎麼樣才算是精通漢語?
怎麼樣才算是精通英語?

從來沒有一個成熟的人問這樣的問題。

因為語言是千變萬化的,你會語言寫出數學定理,但你不一定能用語言寫出藝術作品,你會用語言寫出藝術作品,但你不一定能用語言寫出工程產品,你永遠有不精通的一面,而是你永遠只是精通一小細節,如何只用英文26個字母加符號排列組合在10億的字元串上,整個排列組合是天文數字,整個人類加在一起不能說精通了某某語言,更何況是個人。

就算是語言的發明者,也只是撐握了把語法翻譯成二進位的方法,而不是精通語言本身。

如果能用某語言不帶參考寫個冒泡排序就算著精通,那隻能算著精通入門。


學C++的路子很長,可以先看一下《C++primer》多加練習,然後可以去看一下《Think in C++》《C++沉思錄》等。重要的是不要只看不練,重在動手練習,切忌浮躁,因為這條路真的很長。最好不要去看什麼《21天精通XXX》之類的書籍,它會讓你在不到21天的時間裡把C++忘得一乾二淨。其實要精通某一門語言不僅僅只是要學好這門語言本身,像代碼重構這些技巧也是要掌握的,並且工程經驗也要豐富,在應用該語言實現複雜系統時所遇到的種種問題要都能夠提出一個好的解決方案。這是一個很長的過程,不要急於求成,就像陳皓所說的他寫了十多年的C++也不敢說他精通C++。PS:推薦你去陳皓的個人博客看看:http://coolshell.cn


c艹畢竟只是工具,掌握到可以滿足自己設計的需求的程度就夠
除非你研究編譯,否則對語言本身不必刻意深入。一些邊邊角角的知識和一些坑,一邊做東西一邊也就了解了
而是否做出有價值的東西取決於演算法水平


精通使用筷子卻營養不良,這豈不是更大的笑話…


推薦閱讀:

TAG:程序員 | 編程語言 | 編程 | 程序 | C++ |