如何成為一名合格的 C

寫在前面的話

在大多數開發或者準開發人員的認識中,C/C++ 是一門非常難的編程語言,很多人知道它的強大,但因為認為“難”造成的恐懼讓很多人放棄。

筆者從學生時代開始接觸 C/C++,工作以後先後擔任過 C++ 客戶端和服務器的開發經理並帶隊開發,至今已經有十多年了。雖然時至今日哪種編程語言對我來說已經不再重要(我目前主要從事 Java 開發),但 C/C++ 仍然是筆者最喜歡的編程語言。在我看來,C/C++ 一旦學成,其妙無窮,就像武俠小說中的“九陽神功”一樣,有了這個基礎,您可以快速學習任何語言和編程技術。

C/C++ 的當前應用領域

需要注意的是本文不細分 CC++ 的區別,通常情況下,C++ 可以看成是 C 的一個超集,在古典時期,可以認為 C++ 就是 C with classes。雖然如今的 C++ 從功能層面上來看,離 C 越來越遠了;但是從語法層面來上來看,大多數 C++ 語法還是與 C 基本一致的——所謂 C++ 的面向對象特性,如果細究 C++ 類方法的具體語法還是 C 的過程式語法。當然,面向對象是一種思想,語言本身對其支持的程度固然重要,能否熟練使用更要看開發者的水平。

C 語言目前主要用於像操作系統一類偏底層的應用開發,包括像 Windows/Linux 這樣的大型商業操作系統,以及嵌入式操作系統、嵌入式設備上的應用。還有一些開源的軟件,也會選擇 C 開發,這些系統主要優先考慮程序執行效率和生成的可執行文件的體積(C 代碼生成的可執行文件體積相對更小),當然還有一些是歷史技術選型問題,這類軟件像 Redis、libevent、Nginx,目前像國內的電信服務商所使用的電話呼叫系統,一般也是基於一款叫

FreeSWITCH的開源 C 程序做的二次開發。

C++ 面向對象的語法與 C 相比較起來,在將高級語言翻譯成機器二進制碼的時候,C++ 編譯器在背後偷偷地做了大量工作,生成了大量的額外機器碼,而這種機器碼相對於 C 來說不是必須的。例如,對於一個 C++ 類的實例方法,編譯器在生成這個方法的機器碼時,會將函數的第一個參數設置成對象的 this 指針地址,以此來實現對象與函數的綁定。正因為如此,許多開發者會優化和調整編譯器生成的彙編代碼。

我們再來說說 C++。C++ 的應用領域目前有三大類,第一類就是我們目前見到的各種桌面應用軟件,尤其 Windows 桌面軟件,如 QQ、安全類殺毒類軟件各種瀏覽器等;另外就是一些基礎軟件和高級語言的運行時環境,如大型數據庫軟件、Java 虛擬機、C# 的 CLR、Python 編譯器和運行時環境等;第三類就是一些業務型應用軟件的後臺,像遊戲的服務器後臺,如魔獸世界的服務器和一些企業內部的應用系統。筆者在某交易所從事後臺開發,其交易系統和行情繫統就是基於 C++ 開發的。

C++ 與操作系統平臺

從上面的介紹可以看出,與 Java、Python 等語言相比,C/C++ 語言是離操作系統最近的一種高級語言,因此其執行效率也比較高。但是有得必有失,因為如此,C/C++ 這門語言存在如下特點。

C/C++ 整套的語法不具備“功能完備性”,單純地使用這門語言本身提供的功能無法創建任何有意義的程序,必須藉助操作系統的 API 接口函數來達到相應的功能。當然,隨著 C++ 語言標準和版本的不斷更新升級,這種現狀正在改變;而像 Java、Python 這類語言,其自帶的 SDK 提供了各種操作系統的功能。

舉個例子,C/C++ 語言本身不具備網絡通信功能,必須使用操作系統提供的網絡通信函數(如 Socket 系列函數);而對於 Java 來說,其 JDK 自帶的 java.net 和 java.io 等包則提供了完整的網絡通信功能。我在讀書的時候常常聽人說,QQ、360 安全衛士這類軟件是用 C/C++ 開發的,但是當我學完整本 C/C++ 教材以後,仍然寫不出來一個像樣的窗口程序。許多過來人應該都有類似的困惑吧?其原因是一般 C/C++ 的教材不會教你如何使用操作系統 API 函數的內容。

C/C++ 語言需要直接使用操作系統的接口功能,這就造成了 C/C++ 語言繁、難的地方。如操作內存不當容易引起程序宕機,不同操作系統的 API 接口使用習慣和風格也不一樣。接口函數種類繁多,開發者如果想開發跨平臺的程序,必須要學習多個平臺的接口函數和對應的系統原理。

在應用層開發,直接使用操作系統接口的函數,往往執行效率高、控制力度大。而開發能力僅僅限制於操作系統本身,Java 這類語言,很多功能即使操作系統提供了,如果 Java 虛擬機不提供,開發人員也無法使用。正如著名的編程大師 Charles Petzold 所說:

“顯而易見,究竟用哪種方式編寫應用程序最好,其實並無一定之規。應用程序本身的特性應該是決定採用何種編程工具的最主要因素,但是無論將來你採用什麼樣的編程工具,通過了解操作系統 API 從而深入理解操作系統的工作原理,這本身就有很重要的意義。操作系統是一個非常複雜的系統,在 API 之上加一層編程語言並不能消除其複雜性,最多不過是把複雜性隱藏起來而已。說不定什麼時候,複雜的那一面遲早會蹦出來拖你的後腿,懂得系統 API 能讓你到時候可以更快地掙脫困境。在基本操作系統 API 之上的任何軟件層或多或少都會限制你使用操作系統的全部功能。比如,你或許發現採用 Visual Basic 來編寫你的應用程序非常理想,但是就有那麼一兩項非常基本的功能 Visual Basic 無法支持。往往這個時候你得非要調用基本 API 。作為直接使用操作系統 API 的程序員,我們的活動空間完全由 API 來規範,再沒有什麼其他方式比直接調用 API 更有效、更靈活多樣了。”

總結起來,C/C++ 語言的開發核心建立在直接調用操作系統 API 的基礎上,優點是執行效率高、發揮空間大;缺點是,需要經過系統深入的學習,學習週期長,編寫代碼較複雜,容易出錯。

Linux C++ 與 Windows C++ 領域之爭

我之所以把這個標題單獨列出來,是想糾正現在很多 C/C++ 新人和初學者一些不當的認識,一般有以下幾種觀點:

  • Linux C++ 開發就是後臺開發,而 Windows C++ 開發就是客戶端開發;
  • 後端開發比客戶端開發(前端)高級,因此後端開發行業薪資水平比客戶端開發薪資要高;
  • 我只學 Linux,不學 Windows。

我相信對於 80 和 90 的這一代開發者來說,當初接觸計算機並進入軟件行業,都是從接觸 Windows 開始的。時至今日,大數據、人工智能等各種新技術方興未艾,移動互聯網如火如荼。無論是 Linux 還是 Windows,尤其是 Windows,仍然是我們大多數人工作、學習、娛樂使用最多的操作系統——我們每天都會使用其上的各種軟件。使用這些軟件像喝水、呼吸空氣一樣自然,所以很多人就忽視了這類軟件的 “基礎作用”。

Windows 上的軟件開發發展了很多年了,這些領域也比較成熟,一般不再招初中級開發,而是需要水平較高、經驗較豐富的高級開發者。這讓很多人造成了“Windows C++”開發市場需求已經很小了的錯覺。試問,QQ PC 部門這些年對外招了多少人?

Linux C++ 和 Windows C++ 一樣,沒有孰高孰低之分,只是兩種不同的操作系統而已,不要覺得在 Linux 下敲命令就比在 Windows 的圖形化界面點擊鼠標達高級。

圖形化界面之於命令行,是人們對更高級、更方便的工具追求的必然結果。Linux C++ 也不一定就是後臺開發,Windows C++ 也不一定就是客戶端開發;所謂的服務器與客戶端是個相對的概念,即誰給誰提供服務,提供服務的我們認為是服務端(後臺),被服務的我們認為是客戶端(前臺)。而 Windows 作為後臺服務的應用也比比皆是,如筆者之前所在的某交易所的服務器後臺都是 Windows 下的 C++ 程序;另外如一些遊戲類的服務器端,也不少是 Windows 的。

借用《UNIX 編程藝術》這本書的觀點,Windows 和 Linux 的哲學理念不一樣,Windows 是假設你不會操作,它教你如何操作,而 Linux 是假設你會操作然後進行操作。根據這個理念,Windows 一般是普通人用的多,而 Linux 是程序員用的多。

從編程的角度來說,Windows 的代碼風格是所謂的匈牙利命名法,而 Linux 是短小精悍的連字符風格。例如同一個表示屏幕尺寸的整型變量,Windows 上可能被命名為 iScreen 或 cxScreen ,而 Linux 可能是 screen;再例如 Windows 上創建線程的函數叫 CreateThread,Linux 下叫 pthread_create。有時候,我覺得 Windows 的匈牙利命名法反而更容易理解代碼。

這裡既然提到前端(客戶端)開發和後端開發,這裡不得不提一下,這二者沒有優劣之分。其側重點和開發思維是不一樣的,前端(客戶端)開發一般有較多的界面邏輯,它們是直接與用戶打交道,因而一款客戶端軟件的好壞很大程度上取決於其界面的易用性和流暢性,開發者只要把這一端的“一畝三分地”給管理好即可;而後端服務,對於普通用戶是透明的,開發者的程序必須儘量體現“服務”這個字眼,即更有效地為更多的客戶端服務,這就要求兼顧請求響應的正確性及時性流暢性

由於服務軟件也是運行在某臺物理機器上的程序,鑑於 CPU、內存、網絡帶寬資源有限,而服務程序一般是長週期運行的,因此必須合理地分配和使用資源(如儘量回收不再使用的各種資源)。開發者應從全局考慮,不能在某個“客戶端”這一棵樹上“吊死”。

從個人的職業發展來看,建議從事客戶端開發的人員適當地瞭解一下服務器開發的思路,反過來也建議從事後端開發的人員去學習一下客戶端開發,二者相得益彰。從個人的技術提高來說,也是很有幫助的。

例如您要學習一套開源的軟件代碼,如果您熟悉客戶端和服務器的基本開發和調試技巧,您可以更好地學習它。而在工作上,一個項目,往往是由客戶端和服務器程序組成,如果您都熟悉,您可以站在一個更高的角度去審視它、規劃它,這也是架構師的基本要求之一。

最後就是很多讀者關心的客戶端和服務器的薪資問題,這個沒有絕對的誰高誰低,因人而異,因能力而異,因崗位而異。

如何看待 C++ 11/14/17 新標準

C++ 開發者有個不成文的規定:即使您對 C++ 很熟悉,也不要在簡歷上寫上您精通 C++,原因很簡單—— C++ 這門語言包含的東西實在太多了,沒有人能真正“精通”所有。

C++ 既支持面向對象設計(OOP),也支持以模板語法為代表的泛型編程(GP)。而且新的 C++ 標準和遵循 C++ 新標準的編譯器也層出不窮,這些年,C++ 變化越來越大、越來越快,從最初業界和開發者翹首以盼的 C++11 標準,歷經 C++14、C++17 到今天的 C++20,這門語言與之前的版本差別越來越大,更多原來需要使用第三庫的功能也被陸續添加到 C++ 標準庫中。以致於 C++ 之父

Bjarne Stroustrup 也開始對這門語言表示擔憂:

“C++11 開始的基礎建設尚未完成,而 C++17 在使基礎更加穩固、規範性和完整性方面,基本沒有做出改善。相反地,卻增加了重要接口的複雜度,讓人們需要學習的特性數量越來越多。C++ 可能在這種不成熟提議的重壓之下崩潰,我們不應該花費大量的時間為專家級用戶們(比如我們自己)去創建越來越複雜的東西。(還要考慮普通用戶的學習曲線,越複雜的東西越不易普及。)”

文章參看這裡:https://zhuanlan.zhihu.com/p/48793948,在 Bjarne Stroustrup 的信中,他擔心 C++ 會像歷史的瓦薩號軍艦一樣,某天新的標準剛啟航(發佈)便立即沉沒。

當然,我們不用有這種擔憂,畢竟我們既不是 C++ 標準委員會成員,也不是 C++ 編譯器開發廠商。就我個人經驗來說,對於C++11、C++14、C++17 乃至 C++20,我們學習它們的準則應該是以實用為主,也就是說我們應該學習其實用的部分,至於新標準提到的一些高級特性和各種複雜的模板,我們大可不必去了解。我們並不是做學術研究,我們學習 C++ 是為了投入實際的生產開發,所以應該去學習 C++ 新標準中實用的語法和工具庫。關於 C++11 常用一些知識點,這裡也簡單地給讀者列舉一下。

  • auto 關鍵字
  • for-each 循環
  • 右值及移動構造函數 + std::forward + std::move + stl 容器新增的 emplace_back() 方法
  • std::thread 庫、std::chrono 庫
  • 智能指針系列(std::shared_ptr/std::unique_ptr/std::weak_ptr),智能指針的實現原理一定要知道,最好是自己實現過
  • 線程庫 std::thread + 線程同步技術庫 std::mutex/std::condition_variable/std::lock_guard 等
  • Lamda 表達式(Java 中現在也常常考察 Lamda 表達式的作用)
  • std::bind/std::function 庫

其他的就是一些關鍵字的用法(override、final、delete),還有就是一些細節如可以像 Java 一樣在類成員變量定義處給出初始化值。

C++ 語言基礎與進階

基礎

這裡說的基礎不是狹義上的 C++ 語言基礎,而是包括 C++ 開發這一生態體系的基礎,筆者認為的基礎包括:

  1. C++ 語言本身熟練使用程度。
  2. 前面也介紹了單純的 C++ 您啥也幹不了,您必須結合一個具體的操作系統平臺,所以得熟悉某個操作系統平臺的 API 函數,比如Linux,以及該操作系統的原理。這裡說的操作系統的原理不侷限於您在操作系統原理圖書上看的知識,而是實實在在與系統 API 關聯起來的,如熟練使用各種進程與線程函數、多線程資源同步函數、文件操作函數、系統時間函數、窗口自繪與操作函數(這點針對 Windows)、內存分配與管理函數、PE 或 ELF 文件的編譯、鏈接原理等等。
  3. 網絡通信,網絡通信在這裡具體一點就是 Socket 編程。這裡的 Socket 編程不僅要求熟練使用各種網絡 API 函數,還要求理解和靈活運用像三次握手四次揮手等各種基礎網絡通信協議與原理。關於 Socket 編程實踐,《TCP/IP 網絡編程》這本書是非常好的入門教材。

說了這麼多,您可能會覺得很抽象。筆者在這裡舉個具體例子。假設我們現在要開發一個類似電驢這樣的軟件,軟件界面如下圖:

如何成為一名合格的 C/C++ 開發者?


如何成為一名合格的 C/C++ 開發者?


如何成為一名合格的 C/C++ 開發者?


如上圖所示,假設操作系統選擇 Windows,使用語言使用 C++,這就要求您必須熟悉 C++ 常用的語法,如果還不熟悉,就需要補充這方面的知識。

在熟悉 C++ 語法的前提下,從這款產品實現技術來看,我們的目標產品分為

UI網絡通信部分。下面將詳細介紹這兩部分。

UI 部分

對於 UI 部分,我們的認識是,這裡需要使用 Windows 的窗口技術。可以直接使用原生的 Win 32 API 來製作自己的界面庫,也可以選擇一些熟悉的界面框架,如 MFC、WTL、Duilib、wxWidgets 等。無論您是在閱讀別人的項目還是需要自己開發這樣的項目,在確定了這款軟件使用的 UI 庫(或者使用原生 Win 32 API),您就需要對 Windows 的窗口、對話框、消息產生、派發與處理機制進行了解。同樣的道理,如果不熟悉您需要補充相關的知識(關於這一點,下文不再贅述)。

接著,根據上圖中的軟件功能,大致分為三大模塊,即資源下載分享。這三大塊是可以使用一個 Windows Tab 控件去組織,這個時候您需要了解 Windows Tab 控件的特性。

  • 對於資源模塊,本質上是一個窗口中嵌入了一個瀏覽器控件(WebBrowser 控件),那麼您需要了解這一個功能點的相關知識。當用戶點擊了某個列表中某個具體的資源,可以對齊進行下載。這就又涉及到 WebBrowser 控件與 C++ 宿主程序的交互了,那麼如何實現呢?可以選擇使用 ActiveX 技術,也可以使用 JavaScript 與 C++ 交互技術。
  • 再來看下載模塊,當產生一個下載操作時,界面上會產生以下下載列表,每個列表項會實時顯示下載進度、下載速率等參數,同時正在下載的項目也可以被暫停、停止和刪除。那麼這又涉及到 ListView 控件的相關功能,以及 ListView 如何與後臺網絡通信的邏輯交互。
  • 分享模塊是將本地資源分享到服務器或者給其他用戶。界面左側是文件系統的一個快照,那麼這又涉及到如何遍歷文件系統(瞭解枚舉文件系統的 API),右側也是一個 ListView 控件,這裡不再贅述。

網絡通信部分

網絡通信部分,主要有兩大塊,第一個是程序啟動時,與服務端的交互;第二個就是文件下載與分享的 P2P 網絡。您在閱讀或開發的過程中,如果對這些技術比較陌生,您需要補充這些知識,具體的就是 Socket 的各種 API 函數,以及基於這些 API 邏輯的組合。當然可能也會用到操作系統平臺所特有的網絡 API 函數,如 WSAAsyncSelect 網絡模型。

另外一點,網絡通信部分如何與 UI 部分進行數據交換,是使用隊列?全局變量?或者相應的 Windows 操作平臺提供的特殊通信技術,如 PostMessage 函數、管道?如果使用隊列,多線程之間如何保持資源的一致性和解決資源競態,使用 Event、CriticalSection、Mutex、Semaphore 等?

當然,筆者這裡只列舉了這個軟件的主幹部分,還有許多方方面面的細節需要考慮。這就需要讀者根據自己的情況,斟酌和篩選了。您想達到什麼目的,就要去學習和研究相關的代碼。

總結起來,可以得到如下公式:

一款 C++ 軟件 = C++ 語法 + 操作系統 API 函數調用

進階

如果您達到了我上面說的三點後,可以再找一些高質量的開源項目去實戰一下。需要注意的是,最好找一些沒有複雜業務或者您熟悉其業務的開源項目(如開源的 IM 系統)。如果你不熟悉其業務,不僅要學習其業務(軟件功能),還需要再去學習它的源碼,最後可能讓我們迷失了最初學習這款軟件的目的。

學習這些項目的同時,讀者應該先確定自己的學習目的,如果您的目的是學習和借鑑這款軟件的架構,那麼先從整體去把握,不要一開始就迷失在細枝末節中,這類我稱之為“

粗讀”;或者您的目的是學習開源軟件在一些細節上的處理與做法,這個時候,您可以針對性地去閱讀您感興趣的模塊,深入到每一行代碼上。

學習開源軟件存在一種風氣,許多新手喜歡道聽途說,一聽別人說這個軟件不好,那個軟件存在某某瑕疵就放棄閱讀它的打算了。然後到了實際開發中,因為心中沒有任何已有軟件開發問題的解決方案,產生挫敗感,久而久之就對本來喜歡的 C/C++ 開發失去了興趣。

學習的過程是先接觸,再熟悉,再模仿,再創造。不管什麼開源項目,在您心中沒有任何思路或者解決方案時,您應該先接觸熟悉,不斷模仿,做到至少心中有一套對於某場景的解決方案,然後再來談創新談批判、改造別人的項目。

我個人學習一套陌生的開源項目時,總是喜歡將程序用調試器正常跑起來,然後再中斷下來,統計當前的線程數目,然後通過程序入口 main 函數從主線程追蹤其他工作線程是如何創建的;接著,分析和研究每個線程的用途以及線程之間交互的,這就是整體把握,接著找我感興趣的細節去學習。

這裡我以學習

Redis 為例。將 Redis 源碼從官網下載下來以後,使用喜歡的代碼閱讀器進行管理。我這裡使用的是 Visual Studio,如下圖所示:

如何成為一名合格的 C/C++ 開發者?


在大致瞭解了 Redis 有哪些代碼模塊以後,我們把代碼拷貝到 Linux 平臺,然後編譯並使用 GDB 調試器跑起來。如下圖所示:

如何成為一名合格的 C/C++ 開發者?


然後按 CTRL+C 將 GDB 中斷下來,輸入 info threads 查看當前程序的所有線程:

如何成為一名合格的 C/C++ 開發者?


接著挨個使用 thread + 線程編號 和 bt 命令去查看每個線程的上下文調用堆棧:

如何成為一名合格的 C/C++ 開發者?


對照每個線程的上下文堆棧,搞清楚其邏輯,並結合主線程,看看每個線程是在何時啟動的,端口在何時啟動偵聽的,等等。做完這一步,關於 redis-server 的框架也基本清楚了。

接著我們可以選擇一個自己感興趣的命令,搞清楚 redis-cliredis-server 命令的交互流程。

最後,如果對 redis-server 源碼中各種數據結構和細節感興趣,我們可以進一步深入到具體的代碼細節。

當然,不熟悉 GDB 的讀者看筆者這段操作流程比較困難,這是正常的,說明如果想通過調試去研究 Redis 這一款開源軟件,您需要去補充一點 GDB 調試的知識。這就是我上文中所說的,針對性地補缺補差。

C++ 面試

需要注意的是,不僅僅是 C++ 面試,其他語言開發面試也是一樣。如果您是想進入大型互聯網公司的應屆生,那麼您應該優先好好準備算法和數據結構知識以應對面試,這是大型互聯網公司面試頻率最高的考察範圍。至於其他的基礎知識,如操作系統原理、網絡通信等(作為計算機相關專業的學生,這些應該是您的專業課),如果您已經在平時的學習中掌握得很好,那就不用擔心,這類問題一般對於應屆生求職不會問得太深;倘若您尚未學得紮實,而春招或秋招又時間臨近,沒有足夠的時間去準備這些,您應該只是儘量去補,實在來不及也沒關係,還是應該把重心放在好好準備算法和數據結構等知識上。

對於社會人士參加的 C++ 職位的面試,如果是大型互聯網公司,雖然社會招聘問的更多的是項目經驗,適當地為一些基礎的算法和數據結構知識做一些準備也是非常有用的。舉個例子,如果問到二分查找這一類基礎算法,如果答不出來未免會讓面試官印象不太好,場面也比較尷尬。另外,C++ 是一門講究深度的編程技能,對於有一定工作年限的面試者,面試官往往會問很多原理性的細節,這就要求廣大 C++ 開發者在平常多留心、多積累、多思考技術背後的原理。

對於大多數小型企業,無論是應屆生還是社會人士,只要有能力勝任一定的工作即可。一般只要對所面試的公司項目有類似經驗或者相關的技術能力,基本上就可以通過面試。大多數小公司在乎的是您來了能不能幹活,所以這類公司對實際項目經驗和技能要求更高一點。

關於項目經驗,許多人可能覺得項目經驗一定是自己參與的項目,其實不然,項目經驗也可以來源於您閱讀和學習其他人的項目代碼或者開源軟件,只要您能看懂並理解它們,在面試的時候提及到,能條理清晰、自圓其說即可。當然,如果不熟悉或者只是瞭解些皮毛,切記不可信口開河、胡編亂造甚至張冠李戴。

我曾經面試過一些開發者,看簡歷項目經驗豐富,實際一問的時候,只是把別人的框架或者庫拿來包裝調用一下,問及其技術原理時,不是顧左右而言他就是說不清道不明模稜兩可含糊不清,這一類人往往比不知道還讓人討厭,面試官一般反感這一類面試者所謂的項目經驗。

學生與社會人士學習 C++ 方式的區別

作為學生有充裕的時間,建議除了把 C++ 語法學好,系統地多讀一點基礎的書籍,如操作系統原理、網絡編程、數據結構與算法等相關各方各面的經典書籍。

儘量做到等您畢業走出校園以後,至少熟悉一門編程語言和其相應的開發環境,這就是一個基礎紮實、理論清晰、編碼能力強的求職者。可惜的是,從現在的各種招聘反饋來看,大多數學生在求職時,對相關開發工具和語言的陌生程度實在讓人瞠目結舌,面試官在面試的時候會很納悶:這位學生大學四年(或者七年)到底是否調試過程序?

社會人士由於已經走上工作崗位,家庭、工作的瑣事繁多,沒有太多的時間去系統地閱讀一些相關基礎書籍,如果您當前工作正好是從事 C/C++ 開發,那麼請結合您當前的項目來學習,搞清楚項目的體系結構、吸收項目中優秀的實現細節,針對性地補充相關知識,這是進步最快的方式。

但是實際情形中,很多人覺得公司的項目代碼又爛又雜,不願意去研究。這種思想千萬不能有的,在您沒有自己足夠好的能力給公司提供更好的解決方案,請先學習和模仿,我們此時要保持“空杯”心態,公司的代碼再爛,它也是公司的商業價值所在;即使是純粹的業務代碼,也有它的可取之處,擇其善者而從之,其不善者而改之。尤其是開發者處於一些初中級的開發崗位時,可能接觸不到公司核心框架的源碼,此時千萬不要盲目地去排斥。學業務,補基礎,時刻意識清醒自己所需,明白自己想要學的東西。

如果從事的不是 C++ 相關的開發,那麼可以擠出一些時間去學習一些開源的代碼,在閱讀開源代碼的過程中,針對性地補缺補差。不建議系統地去看《C++ Primer 中文版》《UNIX 環境高級編程》諸如此類的大部頭書籍,實際開發中不需要太多這類書中的細枝末節,閱讀這類書往往只會事倍功半,甚至最後因書籍太厚、時間不夠,最後堅持不下去,最終放棄。

當然,對於社會人士,當您有一定的時間的時候一定要去補充一些基礎的、原理性的東西,千萬不要沉溺於“面向搜索引擎編程”或者“面向工資編程”,有些問題雖然當時通過搜索引擎解決了,但如果想在技術或職業上有長足的發展,一定要系統地去讀一些經典的、輕量級的書籍(如《C++ 對象模型》)。長期在網上的文章中尋章摘句,只會讓您的知識結構碎片化、凌亂化,甚至混亂化。而且互聯網上的技術文章質量良莠不齊,有時候也容易對自己形成誤導和依賴。總而言之,作為技術開發人員,提高自己技術水平是改變現狀、改善生活最直接的途徑。

小結

關於 C/C++,暫且就討論這麼多。最後再強調一遍,C++ 是一門講究深度的語言,其“深度”不是體現在會多少 C++ 語法,而是能夠洞察您所寫的 C++ 代碼背後的系統原理,這是需要長期不斷的積累的,沒有速成之法。反過來一旦學成,可以快速地學習其他語言和框架。個人覺得,如果自主創業或者想在二三線城市長期發展的讀者,C/C++ 應該是優選語言,有了它作為基礎,您可以跳出依賴各種環境和框架的窠臼,快速地學習和開發您想要的軟件,完成您想要的業務產品。

最後,限於筆者經驗水平有限,歡迎讀者就文中的觀點提出寶貴的建議和意見,或者想與我做進一步交流,也歡迎在下方評論區裡留言,一起交流 C/C++ 編程技藝與思想。


分享到:


相關文章: