在C++裡面這樣的情況很多見:知道了語言實現的底層機制,卻不知道語言特性本身的意義在什麼地方,這裡將介紹C++教程問題的解決方法,在這裡拿出來和大家分享一下。
其實,對於這個問題,Bjarne已經宣傳了十年。早在99年的時候Bjarne就寫了“Learning C++ as A New Language”,並在好幾篇技術訪談這裡,這裡,這裡,還有這裡)裡面提到如何正確對待和使用C++中支持的多種抽象機制的問題。
Andrew Koenig也寫了一本現代C++教程《Accelerated C++》這本書後面還會提到)。然而這麼多年來,C++社群的狀況改善了嗎?就我所知,就算有改善,也是很小的。學習者還是盲目鑽語言細節,只見樹木不見森林;
網上還是彌漫著各種各樣的“技術”文章和不靠譜的“學習C++的XX個建議”;一些業界的有身份的專家還是在一本接一本的出語言孔乙己的書寫一些普通程序員八輩子用不著的技巧和碰不著的角落);而業界真正使用C++的公司在面試的時候還總是問一些邊邊角角的細節問題,而不是考察編程的基本素養不,掌握所有的語言細節也不能讓你成為一個合格的程序員)。
這個面試理念是錯誤的,估計其背後的推理應該是“如果這個家伙不知道這個細節,那麼估計他對語言也熟悉不到哪兒去;而如果他知道,那麼雖然他可能並不是好的程序員,但我們還是能夠就後一個問題進一步測試的”,這個理念的問題在於對語言熟悉到一定程度什麼程度後面會具體建議)。
就已經可以很好的編程了剩下的只需查查文檔);而很多公司在測試“對語言熟悉程度”的時候走得明顯太遠了比如,問臨時對象生命期和析構順序當然是無可厚非的,但問如何避免一個類被拷貝或者如何避免其構建在堆上?);當然,有些語言知識是必須要提前掌握的,具體有哪些後面會提到,面試的時候並非不能問語言細節,關鍵是“問哪些”。
C++的整個生態圈這麼些年來在學習C++的哲學上,實在沒有多少改善。 為什麼?是因為Bjarne介紹的學習方法在技術上沒有說到點子上?是Andrew Koenig的書寫得不夠好?說了誰也不會相信。因為實際上,這裡的原因根本不是技術上的,而是非技術的。
眾所周知的一個事實是,從最表層講,C++教程的最嚴重問題是在語言學習階段占用了學習者的太多時間。翻一翻你的C++書架或者電子書目錄,絕大多數的C++“經典”都是在講語言。在我們通常的意義上,要“入門”C++,在語言上需要耗的時間一般要兩三年。而要“精通”C++,則搞不好需要耗上十年八年的。這跟Peter Norvig說的“十年學習編程”其實不是一回事,人家那是說一般意義上的編程技能,不是叫你當語言律師。)
那為什麼我說“C++教程的復雜性是根本原因”是個有漏洞的推理呢?因為,要讓人們在使用一門語言去做事情之前耗上大量時間去學習語言中各種復雜性,除了語言本身的復雜性的事實之外,還有一個重要的事實,那就是學習者的態度和更重要的)方法。而目前大多數C++學習者的態度和方法是什麼呢?——在真正用C++之前看上一摞語言書日常編程八輩子都未必用得到)。而為什麼會存在這樣的學習態度呢?這就是真正需要解釋的問題。實際上,有兩方面的原因:
事實4:市面上的絕大多數C++書籍包括很多被人們廣泛稱為“必讀經典”的)實際上都是反面教材。 也就是說,隨便你拿起哪本C++書籍包括很多被人們廣泛稱為“必讀經典”的),那麼有很大的可能這本書中的內容不是你應該學的,而是你不應該學的。我之所以這麼說有兩個原因,因為一,我曾經是受害者。二,也是更實質性的原因,這些所謂的必讀經典。
充斥的是介紹C++中的陷阱和對於C++教程的缺陷的各種workarounds好聽一點叫Idioms慣用法)或techniques技術));又因為C++中的這類陷阱和缺陷實在數不勝數,所以就拉出了一個“長尾”;這類書籍在所有語言中都存在“C缺陷和陷阱”、“Effective Java”、“Effective C#”等等),然而在C++裡面這個尾巴特別長,導致這類書數不勝數。三,這些書中列出來的缺陷和陷阱根本不區分常見程度。
對於一個用本程序員來說,應該希望看到“從最常見的問題到最不常見的問題”這樣的順序來羅列內容,然而這些書裡面要麼全部混在一起,要麼按照“資源管理、類設計、泛型”這樣的技術分類來介紹內容,這根本毫無幫助如果我看到一個章節的內容,我當然知道它講的是類設計還是資源管理,還用廢話麼?),使得一個學習者無法辨別並將最重要的時間花在最常見的問題之上。