讀代碼比寫代碼難,真的?

來源 | 綜合整理知乎內容

上讀代碼比寫代碼難,真的嗎?來聽聽別人都怎麼說!

wsivoky

很多人不明白代碼意味着什麼,代碼意味着要隨時理清這一坨:

讀代碼:找到圖中兩個節點之間的可能路徑。

改代碼:替換一個節點,完整地保證那個節點和每個節點之間的連通性,正確性。

寫代碼:新增一個節點,然後(其實不管你怎麼)連到原圖中。

產品經理:我其實根本就不關心這些線是怎麼連起來的。

以上,讀代碼是NP難度,寫代碼,不好意思,對很多人是P級別的。

馮東

首先,就不說寫的爛的代碼了,只說寫的好的代碼。寫的好的代碼,依然是很難閱讀的。寫的好的代碼,一般是遵循一些原則。而這些原則,很難從最後的代碼中反推出來。這些原則一般都是 declarative knowledge,而我們看到的代碼大多是 imperative code。即使是 functional program 或者 declarative language 的 code,一般也是用低級的抽象來描述高級的原則。

舉一個類比,目前體育比賽中很多規則的修改,都是借鑑以往比賽中一些舊規則導致比賽比較沉悶,或者被運動員鑽空子的經驗教訓。但是單單去看這些規則,你無法反推出來它們是爲了避免什麼情況。

所謂的「讀懂寫的比較好的代碼」,一般是從代碼以外的途徑瞭解作者的意圖。然後再掌握作者貫徹這些意圖的一些基本習慣。遵循原則的代碼已經如此難以閱讀,事實比這個還糟糕。任何原則應用於具體問題,都有例外。所以在任何代碼中,都有遵循原則的代碼和例外的代碼。好的代碼只是減少後者的比例,而無法完全杜絕。

vczh

好的代碼,讀起來容易,但這是有前提的——就是你得跟作者有相同的知識背景。當然這一般是達不到的。就算人家有註釋,說不定你得把註釋當成關鍵字,好好地Bing一把,學他個三五個月,你才能理解作者的意圖。

王子亭

自我開始編程以來,我一直覺得讀別人的代碼的難度,要幾倍於自己寫代碼。一直以來我都很困惑,難道是我技藝不精,所以讀別人的代碼很困難麼。其實不是,我能看懂代碼中的每一句話,並沒有我不認識的語法,但連在一起就不懂爲什麼作者要這麼安排代碼了。後來我漸漸有了一些想法,代碼是程序員給計算機的命令,是作者思考過後的產物,但思考的過程卻沒有體現在代碼上,這就好比一道數學題,只有一個最終答案,所有的計算過程都被省略掉了,自然難以理解作者的意圖。

一段代碼一開始寫出來,後來發現存在問題,陸陸續續地改過好幾版是很常見的事情。最終版本中可能每個小的細節,都是作者花了很多時間試錯的結果,但這個試錯的過程並沒有直接地體現在代碼上。另一方面,代碼中往往存在一些「隱含前提」,例如假定函數的參數已經在傳入之前被以某種方式處理過了,這個假定很可能於另一個文件的某行代碼有關,這種聯繫很難引起閱讀者的注意。當然,好的設計可以緩解這個問題,但很難被徹底地解決。代碼的歷史會被保存在版本控制系統裡,但說實話,按我的經驗,很少真的有人去翻版本歷史,因爲正確地使用版本控制工具相比起寫代碼是一項比較不受重視的技能,在這種情況下翻歷史是非常耗時的。

當然,有些人會將一些細節以註釋的形式添加到代碼中,但註釋也只能承載很小的一部分信息,因爲維護註釋也是一項很高的成本,我個人一向是反對添加註釋來解釋代碼的。所以閱讀代碼實際上並沒有看上去那麼輕鬆,爲了徹底理解一段代碼,很有可能你需要付出和編寫這段代碼差不多的努力,來了解這段代碼的歷史和前提。前面提到的是閱讀「好的代碼」的情況,比如大多數活躍的開源項目,如果是面對質量較差的代碼情況就更爲糟糕了。所以我的觀點是,讀代碼絕對不是一種好的學習方式,我認爲學習一項技術應當先閱讀書籍,然後嘗試自己實踐,最後再參考代碼質量較高開源項目。對於大多數項目而言,可能從未把「供他人學習」當作目標,只有當你自己實踐過,積累了一些經驗並且也遇到過一些困難的時候,你才能讀懂代碼並且從中學到解決問題的技巧。而在開始實踐之前,最好的知識來源是書籍,因爲書籍的內容是經過精心的安排的,最高目標就是供他人閱讀。

達達

用熱力學來回答一下這個問題:因爲從思路轉換成代碼是熵增加的一個過程,要把代碼重新整理成思路是熵減少的一個過程。

好比一副有序的撲克牌很容易變亂,已經變亂的撲克牌要變有序需要做更多的功。所以,寫代碼容易,讀代碼難。

MisterFin

假如你讀到這樣一篇文章:“張三把一個不明物體A、一個不明物體B、兩個不明物體C交給了傑克,傑克拿起A,把A的一部分出示給皮爾杜,皮爾杜開始在從一個本本里掏出一個東西,連同收到的東西一起交給門捷洛夫,門捷洛夫鼓搗了半天...然後告訴皮爾杜不對,皮爾杜又掏出一個東西...門捷洛夫告訴皮爾杜對,皮爾杜告訴了田中...”提問:張三在幹嘛呢?你會不會頭疼上面都在胡說什麼呢?如果做一個替換:張三 —— 顧客;傑克 —— 收銀員;皮爾杜 + 門捷洛夫 + 田中 —— 收銀臺(掃描 + 查詢 + 顯示)。讀代碼的困難之處同上,就是你沒法知道作者設置的x, y, count, option, timeline等變量究竟代表了什麼東西。

貓殺

讀代碼有兩種情況,一種是讀局部,某個算法、流程的實現;一種是讀全局,整體架構,模塊的組織耦合之類的。讀代碼的目的有兩種,一種是純學習,看別人怎麼做;一種是要用,缺文檔的項目要從代碼猜出怎麼使用,要加功能做修改等。寫代碼你只需要知道一種實現,讀代碼你可能需要知道多種實現。

要能很容易的讀懂別人的代碼,簡單的說就是要見多識廣,涉及的方面很多,不管是知識上還是技巧上的,所以難度主要是在這一點上體現。代碼的質量影響也很大,但是如果你有大量讀(寫)爛代碼的經驗,難度會顯著的下降。拿到一個項目的代碼,你知道這個項目要做什麼事情,有多少種可能的實現方法,比如是MVC還是View-Document,很快你就能從各種線索中確定是哪一種,方向一確定,隨後的事情就簡單了,尋找的都是不同的地方(往往也是好看的地方)。比如拿到個JS寫的前端交互項目來做修改,一看到EventBus的出現就知道八九不離十是MVP模式了。

讀代碼對工具鏈的熟練程度要求也很高,自己寫代碼,某些人硬要不用IDE拿記事本寫,也就只是慢點而已。讀一個大型項目如果不會熟練的利用工具,快速在各種定義、調用和實現之間跳轉,那就是找虐。還有一個就是目的性,有着目的性的去讀就要容易得多。比如我讀Chrome的源代碼就是對其多進程架構感興趣,於是從入口點開始追蹤,窗口的初始化、IPC的建立逐步的去順藤摸瓜的看。幾次讀Linux的源代碼時,都是因爲項目需要,去研究Linux的時鐘管理、驅動層實現等。尤其是大項目,整體讀完的可能性和實用性不大,帶目的性的、參考性的去讀就要合適一些。除此之外還有很多瑣碎的技巧性的東西,都是需要長期積累的。

王瑞期

情況有很多:

1:知識背景不同。比如你對數據庫的實現瞭解很少,你就完全不知道整個代碼到底是要實現什麼算法,什麼數據結構。

2:思考方式不同。有人喜歡 a*(b+c),有人喜歡 a*c+a*c ,右撇子總是很難理解左撇子左手比較有力的那種感覺。

3:無關干擾很多。“門前有兩棵樹,一棵是棗樹,另一棵也是棗樹”,表達了作者當時什麼樣的意境?其實作者就是隨便這麼一寫,但是別人看了,總覺得有深意,被繞進去了。

4:寫代碼時臨時起意的情況很多。建房子,你知道標準流程就那樣了,所以一看就知道怎麼建的。但是代碼呢,比如我要寫一個類,這個類專門用於建房子,我最初設想有幾個方法:拿錢,設計,找建築隊,建設,裝修。然後寫着寫着,我發現,拿錢這事吧,該有個方法來處理怎麼拿。然後設計這事吧,我得寫個方法,找出我最滿意的設計方案。。。。等等,在寫代碼的過程中,總體流程算是線性的,但是詳細的代碼過程中,會有很多突然蹦出來的東西。而我們讀代碼,模擬不了作者腦子不停蹦創意的過程,所以,就總覺得這代碼怎麼感覺在迷宮裡轉悠呀。

李遙

同樣是代碼,讀別人的SQL、HTML、CSS比讀別人寫的C++、JavaScript要容易,爲什麼?原因在於非聲明式的語言會引入Personal Style這個問題,而別人的Personal Style不像一個編程語言有教程有指南有參考手冊,而且作者本人也不一定前後一致,很多情況下你只能“痛苦地”揣測他爲什麼這麼寫,因此你的大腦自動就排斥做這種事。

胡江

讀比你水平高的代碼,自然難。難在跟上人家的想法。讀水平相當的代碼,難。難在瞭解代碼後面來龍去脈,推測作者的意圖。讀低水平代碼。難在把爛東西看完還要一針見血總結出道道,避免自己犯同樣錯誤。讀代碼難,其實難在對自己的認識和對對象的把握。最後再扯一下,其實題目也不準確,並不是所有讀代碼都難。例如開車狹路遇高手,對方會清楚地表達他的駕駛意圖,讓你輕鬆決定如何處理。或是人家油門一踩,你還沒反應過來車已經過去了。有而最怕的是前方本側有障礙,你特地給對方留出一大塊車道先行。結果對方遠光不關,一腳剎車等你來闖關。

聲明: 本文來源網絡,版權歸原作者所有。如涉及作品版權問題,請與我聯繫刪除。

點擊“ 閱讀原文 ”查看更多分享,歡迎點分享、收藏、點贊、在看。