這是個好問題。就是難度有點高。

這可能是我在知乎上回答的、難度最高的問題了。


從題主加的標籤看,他似乎想問的是「如何讀懂程序代碼、並用語言描述其功能」。

嗯……這本身就是個難題。

因為程序代碼是「為了解決問題而給CPU安排的一系列動作」;但這些動作本身是瑣碎的、而且丟失了大量信息——包括待解決問題、包括解決思路、包括決策點的設計原理/上下文等等,全都丟失了。

當然,如果有注釋的話,部分被丟棄的信息還是可以找回來的。注釋越詳盡,可以找回來的信息就越多。

但是,注釋也是有時效性的。一段代碼可能經過了很多修改,這些修改會使得一些注釋變得無效、甚至指向了反方向。

如果願意花時間的話,或許跟蹤修改記錄,查看伴隨每次提交的說明信息(comment),也有助於還原真相……

總之,和警察破案差不多,需要大量的經驗,也需要靈活的腦子——猜測最初面對的問題,猜測設計者的解決思路;尋覓證據,證明自己的猜測……

沒錯。讀代碼是個苦差事。尤其是那些腦洞大開、自解釋性差、又沒有注釋的代碼。

當我寫這些代碼時,只有我和上帝知道它要做什麼。現在只有上帝知道了。

——某人給自己的程序寫的注釋。


既然讀代碼是只有上帝才敢保證自己能搞定的難題,我當然也只能繞開了。

既然我們不是上帝,那麼,作為人,我們是否可以想想辦法,把代碼寫的簡明易懂、方便後來者(包括半年後的我們自己)讀懂它、維護它呢?

沒錯。這正是業界一直推崇的做法。


先從細節說起吧。

我提過很多次了:代碼難讀難懂,根本原因是因為信息的丟失。

要解決什麼問題?解決思路是什麼?這一段做了什麼事?

一旦寫成代碼……

因此,我們不得不防微杜漸,盡量在代碼中多保存信息。

比如說,推崇結構化程序設計、推崇面向對象程序設計,使得代碼中的功能分界清晰、每塊的總體結構(循環/多重循環/分支/dispatch等等)一目了然。

比如,要求變數命名規範合理,有自解釋性:一個變數叫x,你當然摸不著頭腦;但如果它被程序員精確的命名為「userInputedNumber」,你就知道它的值從何而來;而如果它能叫「inputForSum」,你馬上就知道這個值是用戶輸入的、用來做匯總(sum)。

類似的,函數名、類名、模塊名、命名空間名稱等等,都必須如實反映其功能。這就叫「代碼有自解釋性」。

當然,設計方案到代碼,信息散失太過嚴重。僅靠代碼自解釋往往是不夠用的。此時就必須以注釋補充了。

注意,注釋的作用是「補充代碼無法自解釋的信息」。因此,不要寫這種注釋:

//計算b+c的值,存入a
int a=b+c;

這種注釋沒有提供任何信息,作用僅僅是浪費了讀者和寫者的時間。

當然,這種錯誤的注釋更不行:

//計算d+c的值,存入a
int a=b+c;

注釋應該說明無法在代碼中體現的思路:

//解決XX情況下、無法走通用流程的問題
//解決思路是,生成一個虛擬的XX表,設置其中xx和yy欄位值為a/b
//這樣,當遇到XX情況時,這個虛擬的XX表就可以參與運算,求得結果
//處理結束後,因為系統中會多餘一個XX表,因此需要設置個標記,在YY流程中刪除

如此一來,代碼的設計思路、corner case的解決思路、因此造成的後遺症以及workaround,全都清清楚楚擺在讀者面前了。


容易想到,想要把注釋寫清楚,那麼寫注釋的大腦必須是清醒的、有條理的——如果別人問你這是怎麼回事,你吭哧半天:「我這樣一弄、一弄……再一弄,就成了……」

你覺得這種人能把注釋寫清楚?

你覺得這種人寫的代碼,你可以隨隨便便解釋清楚其中的每個細節?他自己都不清楚怎麼「弄」出來的。

因此,寫文檔精確描述需求的能力、提綱契領三言兩語說清設計思路的能力、有條不紊分解問題、詳略得當的把一個極為複雜的事物分片分塊說清楚的能力,歸根結底,就是你的寫代碼能力——也是你的讀代碼的能力。

換句話說,寫代碼、讀代碼、寫設計文檔、需求文檔,這幾種能力歸根結底是一體的。根本無法拆分:要麼全好,要麼全壞;不存在說不清思路卻寫的一手好代碼的可能;也不存在文檔寫的絲絲入扣、每個邊角都能照顧到、卻怎麼都寫不好代碼的可能

換句話說:有強悍的實施能力,必然有強悍的規劃能力;想要有強悍的規劃能力,那麼實施能力必然登峰造極。

否則,沒有強悍的規劃能力,大腦稀里糊塗,前因後果都理不明白、注釋都寫不清楚,能寫清楚代碼?

沒有強悍的實施能力,規劃?規劃個屁啊。你怎麼保證你規划出來的,就一定能實施呢?

規劃個「識別用戶手機殼顏色切換界面主題」,不是找打么?

因此,我才說題主這個問題問的好,問的難。因為你問的,其實是整個軟體工程這個至今未能解決的老大難問題。


當然,雖然沒有成法,雖然沒有什麼「套路」;但一般化的思路還是有的。

第一板斧叫「溯源」。

「溯源」就是徹底搞清楚一件事究竟是什麼,弄明白它的本質、它的來龍去脈。

舉例來說,有人問「為什麼我include個C頭文件,程序就能正確運行了」?

這個問題,如果你不挖到根本,那麼起碼得一本書才說得清;而且你讀了之後,多半還是丈二和尚摸不著頭腦。必須很長很長時間的消化——還不一定真消化得了。

而我呢,直接挖本質:函數就是內存中的一段二進位數據。

C 語言為什麼只需要 include& 就能使用裡面聲明的函數?

技術問題,想徹底解決必須溯源,從根本上把它看透。

如果不能看透,攔腰來一下,你就得編譯器鏈接器系統調度啥的眉毛鬍子一把抓。這樣自然越說越複雜,越學越困難。

但一旦看透了,一切就都是那麼一句話,自然而然就串起來了。

從要做什麼事、為什麼要做、為什麼這樣能行、可以玩出哪些花樣,全都給串起來了。

很多人喜歡在我的回答下評論說什麼「生命有限」,意思是技術內容浩如煙海,短暫的人生根本學不過來。

還是那句回應:你們學錯了。

跟著樹葉學,收集一千萬片葉子,把自己搞的頭昏腦脹,照樣不知道樹是什麼樣子;找到主幹,學習分岔規律、學習葉子生長綻開規律、學習開花結果的規律、學習能量循環的規律——別說一棵樹,一片森林都輕輕鬆鬆放腦子裡。

學習是這樣,解決問題也是這樣。你必須極其善於抓主幹;一旦抓到主幹,一切細節都不過是基於少量基本規律的衍生物罷了。

第二板斧叫「抽象」。

我們知道了「函數就是內存中一段二進位數據」,把整個編譯鏈接過程全都「衍生」出來自然很容易。

但這樣很容易造成「複雜度失控」:

哎呀這個是不是函數?

不是,字元串。

那個是不是函數?

不是,它在data段。

哎哎,你剛才不是說它不是函數嗎?這裡怎麼調用它了?

嗯……我看看……他在這裡做了手工編譯動作,把編譯後的指令存到原本字元串佔用的空間,因此現在它已經是函數了……

好吧……這個函數為什麼執行出錯?

調用約定不同,你看調用者沒清棧它也沒清……

怎麼樣,暈不暈?

因此,想要簡潔,我們還必須有意識的丟棄一些信息,從而完成「抽象」。

通過「抽象」,諸多不同的實體被藏起了個性、只留共性;於是外層使用者就可以拿它當「光滑的抽象物」使用,無需關注細節。

通過抽象,函數就從「一段二進位指令」變成了「可以接受外部參數、做一些處理然後返回處理結果」這樣一種功能更明確、限制更多、同時又有了諸多相關約定(比如調用時參數如何壓棧、由誰保護執行現場由誰清棧、比如變數的作用域等)的抽象概念。

注意,函數有很多種實現方式;有些語言/專家還會把「執行一些動作、但沒有結果返回」的函數(function)另外抽象為「過程(procedure)」;這些概念又被另一些語言混亂的雜糅起來,比如C,一切都是函數,再比如tcl,一切都是過程(它就是用proc聲明函數/過程的)……

編程領域,這類混亂是常態。以至於很多人覺得這個領域的各種概念都「沒有定義」,是沒法討論的虛擬物。

嗯……編程領域的各種概念,的確是人為了各種目的抽象出來的虛擬物;但它們絕不是什麼「沒有定義」「沒法討論」的虛擬物。

恰恰相反,這裡恰恰需要你那強悍的抽象能力。

比如說,當有人說,過程/函數一團亂,沒法討論時,真正的行內人會告訴你,這類東西有嚴格定義;只不過太多人做了太多隨心所欲的擴展/分類,這才攪亂了討論基礎。

想要討論,很簡單,找一個最簡潔最原始的抽象,在它上面討論就行了。

比如,函數就是一段代碼,執行完還會返回到調用點,沒了。

在這個基礎上,如果我們要考察它是否返回值,就把它分為「函數」和「過程」;要考察它是否存在內部狀態,於是把函數區分為「只要輸入參數相同、返回總是同一個值」的、「冪等」的函數,和每次調用都因為引用的全局/靜態變數影響而得到不同結果的、非冪等的函數,等等。

類似的,Linux說一切皆文件,這個一切皆文件就是它的核心抽象——它管理的一切對象,歸根結底就是個讀寫操作嘛,所以可以全都歸結到文件上;然後繼續添加細節,分成字元設備(文件)/塊設備(文件)之類(根本區別是後者有緩衝區,前者沒有)……

無論如何,思路是一樣的:我們需要先搞出一個最簡的核心抽象,然後再在上面添加細節。

顯然,想要找出這個最簡的核心抽象,先得完成「溯源」。否則何以做出最簡抽象?

這個核心抽象可不是隨隨便便就能搞出來的。它看起來簡單,卻是最見功底的一環

舉例來說,當年的MFC,把圖形界面程序抽象成消息、窗口、消息循環等等,然後又搞DDX/DDV(對話框數據交換/對話框數據驗證),複雜難懂難用;之後呢,我們知道,有人把圖形界面程序抽象為MVC——數據模型(Model)、查看數據/和用戶交互的視口(View)、窗口/數據的控制(Control),一下子就把圖形程序設計變成了只需拖拖拉拉、連小學生都會玩堆積木/繪圖板。

你看,僅僅是核心抽象思路的不同,一個難學難用、到處都是神秘咒語(各種奇怪的宏),就連驗證下輸入框中的數據是否全是數字,你都得通過宏動用難懂的DDV機制;另一個呢,你只要拖個控制項上去、然後設置屬性!

你覺得,是一個MFC程序容易講明白呢,還是一個MVC程序容易講明白?

當然,講明白的前提是你看得懂。先看懂人家的核心抽象,接下來稍微一提就能說通;否則……你慢慢玩,我研究研究你——研究你還能把自己的腦子攪亂到什麼程度。

做好了抽象,想要真正簡化我們的描述——也簡化我們的代碼實現——我們還需要……

第三板斧,封裝

前面說過,抽象是為了主動丟棄一些細節;但你丟了,你的用戶又給它找回來了;或者,你自己寫程序時,不自覺的又去窺探細節了——這個抽象,是不是就白費心機了?

因此,我們需要添加一個界面層。這樣將來用戶就不再能「直接在數組中存機器碼當函數用」,而是必須透過我們的這個界面,按照標準流程聲明和使用函數。

這樣做的好處是,我們可以把函數產生、調用以及運行維護等等細節全部自動化,藏在界面層之後;於是用戶們就可以忘記一切細節,只管聲明函數、按函數名/函數指針調用它——我們會自動幫他們檢查參數個數、類型是否正確,幫他們維護好棧、保護好執行現場,甚至幫他們優化寄存器的使用、自動清理棧上對象,等等。

這些全都對用戶「透明」。

透明的意思是,他們可以真的認為,函數這種東西的的確確是存在的、是嚴格定義的——並不是用一段二進位數據模擬的。

做到這點,這才是高明的封裝——術語叫「依賴倒置」:設計者想好自己打算做出怎樣的抽象、然後實實在在把這個抽象提供給用戶,使得用戶的的確確得到了我們的抽象。

不能是反過來,猜想用戶將來會怎麼用我們的東西、我們要如何迎合他們、他們將來有什麼奇葩需求我們該怎麼滿足……千萬不要這樣。這會引來沒完沒了的工作和無窮無盡的bug。

相反,我們得「依賴倒置」:我們搞了一個抽象,我們要把這個抽象搞的盡善盡美,就好像函數這個事物真的存在一樣——絕不能讓用戶看到隱藏在後面的東西、干擾到我們的實現細節(反過來說也對:絕不能讓我們的實現細節干擾到用戶)。

用術語說,這就叫「封裝要自然,不能有封裝泄露」。

當然,這是理想。現實中往往有很多妥協。比如為了性能,常常就不得不選擇封裝泄露。

舉例來說,C++的placement new就是一種封裝泄露。它泄露了對象初始化流程,使得用戶不得不用怪異的語法更改這個流程。

類似的,現在的很多語言喜歡幫用戶管理內存,稱其為「託管代碼」;但直接使用裸指針的需求無法消除,此時就不得不「封裝泄露」,允許用戶使用unsafe代碼。

最典型就是MFC。嗯,業內現在認為,MFC壓根就沒封裝,人家的一切本就在外面露著……

封裝的很好,你就可以直接從抽象講起——這個系統由數據、視圖、控制三大基本元素構成,它們的關係是……

一旦封裝泄露,你就得下潛一個層次,從背後原理談起——這個消息循環啊,它其實是一個dispatch,用來派發OS傳來的事件……事件和中斷的關係是……

至於壓根沒封裝的……你先看看書。先看完微機原理操作系統原理網路原理編譯原理……當然,看他們之前你得先搞懂數據結構與演算法……之前你得先上機,做大量練習……沒這十幾本書打底,我給你講再多也白講。

你看,想要「傻瓜式編程」,封裝必不可少。封裝的越優秀,你的用戶才可以越傻瓜

類似的,寫程序時,你也一定要做好抽象,然後在良好抽象的基礎上完成封裝——然後在抽象的基礎上講,才能輕易說清你的設計思路、說清某段程序的功能與職責。


很明顯,封裝的好壞取決於抽象水平

人生如戲,全靠演技。抽象就是這個演技,抽象的越好,越合理,封裝就越自然,越不容易泄露——最好的封裝甚至都不需要付出性能代價(甚至反而能輕易得到最優化性能)。

抽象水平又受制於追根溯源、抓住主幹的能力

越是善於抓主幹,你「講故事」時,就越容易講的邏輯清晰、短小精悍。

換句話說,雖然「外向的程序員盯著自己的腳尖和你說話」,但真正玩透了的程序員一定有強悍的語言表達能力。因為他的工作就是尋找自己面臨的、複雜的任務的核心矛盾,然後形象生動的把它講清楚——清楚到連電腦都能聽懂、都能一絲不苟的把事情做完美的程度。

為了講清楚這些,他的等效能力、抽象能力,必然會向著登峰造極的方向不斷發展——與之同時,優秀程序員的理解力必然得到鍛練。以至於很多很多東西,只要你提一個關鍵詞,前因後果他就全知道了。

當然,我也遇到過很多很多怎麼講他都不明白的。甚至可以說這些人是大多數。「聽不懂一個機制」很可能僅僅是因為這個機制就有那麼複雜,實在沒法繼續簡化。

還是那句話,表達能力和理解能力本是一體,你不可能丟掉其中一端。程序員這個職業不存在「茶壺裡煮餃子」這一說,畢竟他們的「溝通目標」是機器——人和機器的區別是,機器只要你把事情講清楚了,不管篇幅多長,它都不會漏看半個字。

而人嘛……因為長了看不懂,所以太長不看。


綜上,如何語言描述代碼實現的功能?

首先,你得看透這個功能的本質。

然後,你得把這個本質清晰表達出來。

之後,你還得針對這個本質做出一個漂亮的抽象,把核心問題轉化到這個抽象上。

有了抽象之後,你再通過抽象「講故事」,把要做的事說清楚。

最後,把以上種種,全都通過代碼表達出來——這一步至關重要。很多對人類來說很簡單的事,電腦就完全不能理解。比如「妥善護住頸部、把孩子慢慢抱起來」,這句話就沒人能教給電腦。

看個實例。

假設我們需要做一個淘寶,允許成千上百萬類商品通過淘寶售賣。那麼這裡就有一個難題:電話卡的賣法能和網遊充值卡一樣嗎?和賣襪子等實物商品能一樣嗎?怎麼賣3件呢?怎麼第二件半價呢?怎麼「滿三十包郵」呢?

你看,幾百萬類商品啊,個個要求都不一樣……淘寶程序員要累死了吧?

還好。我們可以抽象。

怎麼抽象呢?

成千上百萬類商品,歸根結底都是「商品」。

商品是什麼呢?

一種「可以通過交易改變所有權」的、有形或無形的勞動產品。

好了,抽象有了:

1、商品有所有權

2、商品所有權可交換

3、滿足這兩點的,就是「抽象商品」

有了這麼個抽象商品,接下來就簡單了:

1、我們需要允許賣家自定義一個頁面,用來展示商品

2、我們需要允許賣家給商品定價

3、當買家有意購買時,他要付出相應的金錢

4、現在,我們要標記這件商品,把「它的所有權正在從XX賣家轉換到XX買家」更新到其狀態上

這是分界線內部做的事;外部使用者呢?

商家:

1、我要自己維護一個頁面,把自己的商品描述清楚

2、我要選擇一個定價策略,設置好商品價格

3、等待顧客購買

4、發貨(提供數字憑據,或者召喚快遞公司)

用戶:

1、我看到了一些商品,通過商品頁面的描述,我知道了它的各項參數

2、我看到了商品價格,也知道如何取得優惠

3、購買

4、商家給我發來了數字憑據,或者通過快遞公司送來了商品

你看,有形/無形商品,後台邏輯完全一樣嘛。

邏輯簡單了,是不是很容易就能說清楚了?

一旦基本邏輯說清楚了,繼續:

1、為商品添加更豐富的說明手段(支持更多表現形式)

2、增加更多更靈活的定價策略(包括618以及跨店滿減等等)

3、(後台)通過CDN使得用戶瀏覽更順暢,通過集群、隊列等各種技術支持秒殺

4、通過支付寶擔保交易

你看,核心抽象之上,可以添加很多很多東西。

你可能已經注意到了,核心抽象越簡單、功能越薄弱,系統反而可以寫的越靈活、越方便擴展

沒錯,這就是Linux哲學:做一件事,把一件事做好。

一樣樣做好抽象,確保這些抽象彼此「正交」,反倒更容易集成出龐大、複雜卻又高效的各種功能。

眉毛鬍子一把抓,反而什麼都做不好、將來也難以維護、難以擴展。

這種強悍的抽象能力,這種把複雜問題做簡單的能力,是軟體工程師的最重要的核心能力之一。

它的養成不是一蹴而就的,需要你長時間的浸淫其中,在大量的思考和實踐中總結、升華。

只有獲得這個能力之後,那些經典代碼背後藏著的思想才會對你開放——讀這些代碼時,你才能飛快抓住重點。

換句話說,強悍的讀代碼能力是靠著強悍的寫代碼能力支撐的;而強悍的寫代碼能力又要求你善於總結、善於抽象、善於表達;兩者相輔相成,讀懂代碼、講懂代碼和寫出易懂的代碼才會齊頭並進的發展。

這個能力的核心雖然說起來簡單,抽象和封裝而已;但這種能力的養成是水磨工夫,需要自己在大量的成功與失敗中慢慢體會——不然一句句都是「務虛」,沒一句是能馬上拿來用的。

——你看,為了把這件事說清楚,為了讓表達有說服力,我就不得不寫這麼長。

——寫這麼長,就必然會引來「太長不看」黨。然後繼續重複他們那可笑的錯誤……

——正是這種無法用條條框框取代亦難以言傳的經驗,使得軟體工程至今不能是個工程;程序設計仍然是個藝術。

【套裝4卷】計算機程序設計藝術京東¥ 534.30去購買?

代碼大全 第2版 電子工業京東¥ 96.00去購買?


大佬們從理論出發了……

我就說點兒,實際業務的:分層每層只描述自己這一層該知道的概念。每層的每個模塊都足夠簡單了,你就好描述了……

直接細化到 var a = "b"; 你當然不知道 a是幹嘛的 b是幹嘛的……

每個層級的概念混為一談,那就肯定會亂。

編程語言本身,就已經是很多層的封裝了……

也就提供了很多抽象的概念,執行順序、函數、運算、類、介面等等、等等我等CURD程序員,要做的是什麼呢?是把這些封裝,再進行封裝,封裝成 用戶數據結構,用戶類實例,用戶控制器,用戶介面並對外「暴露」這個介面。使得其他程序可以按照某種方式調用這個介面

對調用者來說,我只需要知道 用戶這個抽象概念有個創建介面,就足夠了。

至於裡面你是怎麼實現的,到底是操作了一個用戶表,還是操作了 幾十個表和我沒關係。

知乎計算機回答下面的回答,一般來說,很少看到經典的理論討論, 大多流於類似於B站看誰敲代碼快的競賽,而在知乎就是文章長,長就是對。上次談資料庫,隨口講了個範式,被一堆小鬼輪流百度百科。

語言描述代碼這是門科學,屬於概念設計底下。用的是偽代碼。pesudocode。順便說一句,這個單詞有趣的點在於,p是不發音的,所以你寫偽代碼寫的好,我就按正確的讀音讀,你偽代碼寫的不好,我就p發音,表示你寫的是個p。

在概要設計裡面,詳細代碼的功能實現,一般採用數學化偽代碼方式解決,這既照顧了普通人又照顧了實現者。

比如最常見的例子就是這個FFA,這就是標準的「語言描述代碼功能」,或者更準確一點「數學化自然語言描述代碼功能」,很多人可能會罵,這個你也算是自然語言?對不起,當談論編程的時候,你可以沒有實際編程時數,但是如果你沒有高中左右數學基礎,那我們還是去追割割比較好。別浪費時間。

在自然語言當中,有皮欽語,也就是一種語言的分支,比方言更正式化,但是和本源語言又有不同,比如很人多認為日本侵華時候的兵隊中國語就是一種日語和中文的皮欽語。皮欽語的存在是為了彌合兩個語言族群之間的落差而產生的一種溝通用「語言膠水」

在計算機世界也有皮欽代碼,也就是代碼和自然語言的混合,或者多種語言之間的混合。一種「洋涇浜代碼」,這讓自然人和程序員,或者不同語言程序員之間能夠就程序上溝通。


其實有些事不要陷進去,而是從整體量上看待,就能得出可靠的結論。

我一般一個工程項目30KB代碼,把這些代碼頭尾相連連續不斷地口頭讀一遍,差不多要多久呢?按照一秒鐘一個詞,平均三五個字母一個詞,我想大致2至5個小時吧。算上重寫的部分,差不多10個小時。(完全沒有重寫的新工程代碼,相當於要求人做數學題不用草稿紙,直接寫答案。)

注意,是講10個小時的量的,前後邏輯嚴謹的話。這樣看還能夠勝任嗎?

類似的例子還有,牛人完全理解一個操作系統,這是可能的。但是Windows系統的源代碼體積,查一查,就會發現那是一個人不吃不喝一輩子照著成品敲,也敲不完的量。因此顯而易見,一個人不能寫出一個完整的操作系統。


用語言去描述有點蒼白,一般很少有人直接寫文章去描述一個程序的實現細節和功能。

那我來說吧,我在梳理代碼的時候會使用流程圖來做輔助。

一般功能上的邏輯直接使用腦圖按照函數的調用關係進行一層一層梳理。

如果是面向對象的架構,使用viso畫出uml圖就比較直觀。

流程圖比語言更直觀,程序代碼,只要你理解了,梳理通了就可以去得心應手的解bug了。


盡量少寫注釋,提高自己的不可替代性,防止輕易地被優化掉


這是個什麼語病問題?

代碼都寫出來了,卻沒有文檔描述?不知道怎麼用自然語言描述和解釋?


確實是個好問題,我來蹭大神寫個回答。

讀代碼是一種能力,和寫代碼確實不一樣。

代碼是給計算機讀的,所以讀代碼時你得是一台計算機。

你首先必須熟悉計算機能幹什麼,最基礎的,cpu能幹什麼?看這個吧

《深入理解計算機系統(原書第3版) 》([美]蘭德爾 E.布萊恩特(Randal,E.·Bryant),等)【摘要 書評 試讀】- 京東圖書?

item.jd.com

CPU基本就是讀內存,算,寫內存。在代碼中,內存大多數時以變數形式存在,那一段代碼的基本行為,就是在讀變數,寫變數。你需要知道一種語言的變數生命周期,來確定哪些改變是臨時的,哪些是有意義的,需要你關心的。對於一段代碼的封裝語法,也是很重要的,現在封裝的比較流行的單位是函數,其實還是語言問題。

語言的話,我知道C++不完美,但是作為學習對象是非常不錯的。很多工程上的問題,作為學習目標來說,反倒是優點,比如特性多,啥範式都支持等等,有時間讀讀這個

《C++ Primer(中文版 第5版)》(Stanley B. Lippman,Josée Lajoie,Barbara E. Moo)【摘要 書評 試讀】- 京東圖書?

item.jd.com

明確了生命周期和函數的作用(輸入與輸出),就可以開始讀了,關注點就是變數,這個時候就是IDE出場的時候了,你需要學會按變數名查詢一個項目的所有引用,這樣可以針對關鍵變數在腦中或者紙上構建數據處理流。

除了數據處理之外,函數內部的計算過程其實大多數假設他們寫的是對的就行了,如果需要深究,學習一下基礎知識比較好,演算法導論這個時候出場

《演算法導論(原書第3版)/計算機科學叢書》([美]Thomas H.Cormen,[美]Charles E.Leiserson,[美]Ronald L.Rivest,[美]Clifford Stein)【摘要 書評 試讀】- 京東圖書?

item.jd.com

以上都過一遍之後,你可能發現只能看懂計算矩陣對角線數字的值這種代碼(話說這個叫啥來著,有個名詞來著)。但是CPU真的也就能幹這些。更進一步,需要其他硬體的配合了。問題是我是搞軟體的,硬體真的不懂,多虧有操作系統封裝了硬體相關的操作。其實不需要操作系統這門課,對與讀代碼幫助太小。我們需要的是操作系統的編程介面介紹,下邊兩本書值得推薦,當然手機和蘋果操作系統也需要,但是我不懂。

《微軟技術叢書:Windows核心編程(第5版)》(傑夫瑞(Jeffrey Richter),等)【摘要 書評 試讀】- 京東圖書?

item.jd.com

《UNIX環境高級編程(第3版)》((美)史蒂文斯(W. Richard Stevens),(美)拉戈(Stephen A. Rago))電子書下載、在線閱讀、內容簡介、評論?

e.jd.com圖標

操作系統編程介面,API,主要就是一些函數,我們知道功能就可以讀懂代碼了。

更進一步的話,需要看一個存在的框架的介紹了,當前要看的目標代碼所依賴的框架,做進一步研究。

以上基本是以C++語言為基礎假設做的推薦。對於帶虛擬機的語言,操作系統API,語言,框架等等,很多是合一的,可能需要單獨討論。但是,還是那句話,C++這系列雖然工程上有很多問題,但是學習的話,比較清晰明確,而且很多時候造輪子比較多,適合了解原理,對於任何軟體方向都是有幫助的。


推薦閱讀:
相关文章