讀代碼比寫代碼難,真的嗎?
上讀代碼比寫代碼難,真的嗎?來聽聽別人都怎么說!
wsivoky
很多人不明白代碼意味著什么,代碼意味著要隨時(shí)理清這一坨:
讀代碼:找到圖中兩個(gè)節(jié)點(diǎn)之間的可能路徑。改代碼:替換一個(gè)節(jié)點(diǎn),完整地保證那個(gè)節(jié)點(diǎn)和每個(gè)節(jié)點(diǎn)之間的連通性,正確性。寫代碼:新增一個(gè)節(jié)點(diǎn),然后(其實(shí)不管你怎么)連到原圖中。產(chǎn)品經(jīng)理:我其實(shí)根本就不關(guān)心這些線是怎么連起來的。以上,讀代碼是NP難度,寫代碼,不好意思,對(duì)很多人是P級(jí)別的。
馮東
首先,就不說寫的爛的代碼了,只說寫的好的代碼。寫的好的代碼,依然是很難閱讀的。寫的好的代碼,一般是遵循一些原則。而這些原則,很難從最后的代碼中反推出來。這些原則一般都是 declarative knowledge,而我們看到的代碼大多是 imperative code。即使是 functional program 或者 declarative language 的 code,一般也是用低級(jí)的抽象來描述高級(jí)的原則。
舉一個(gè)類比,目前體育比賽中很多規(guī)則的修改,都是借鑒以往比賽中一些舊規(guī)則導(dǎo)致比賽比較沉悶,或者被運(yùn)動(dòng)員鉆空子的經(jīng)驗(yàn)教訓(xùn)。但是單單去看這些規(guī)則,你無法反推出來它們是為了避免什么情況。
所謂的「讀懂寫的比較好的代碼」,一般是從代碼以外的途徑了解作者的意圖。然后再掌握作者貫徹這些意圖的一些基本習(xí)慣。遵循原則的代碼已經(jīng)如此難以閱讀,事實(shí)比這個(gè)還糟糕。任何原則應(yīng)用于具體問題,都有例外。所以在任何代碼中,都有遵循原則的代碼和例外的代碼。好的代碼只是減少后者的比例,而無法完全杜絕。
vczh
好的代碼,讀起來容易,但這是有前提的——就是你得跟作者有相同的知識(shí)背景。當(dāng)然這一般是達(dá)不到的。就算人家有注釋,說不定你得把注釋當(dāng)成關(guān)鍵字,好好地Bing一把,學(xué)他個(gè)三五個(gè)月,你才能理解作者的意圖。
王子亭
自我開始編程以來,我一直覺得讀別人的代碼的難度,要幾倍于自己寫代碼。一直以來我都很困惑,難道是我技藝不精,所以讀別人的代碼很困難么。其實(shí)不是,我能看懂代碼中的每一句話,并沒有我不認(rèn)識(shí)的語法,但連在一起就不懂為什么作者要這么安排代碼了。后來我漸漸有了一些想法,代碼是程序員給計(jì)算機(jī)的命令,是作者思考過后的產(chǎn)物,但思考的過程卻沒有體現(xiàn)在代碼上,這就好比一道數(shù)學(xué)題,只有一個(gè)最終答案,所有的計(jì)算過程都被省略掉了,自然難以理解作者的意圖。
一段代碼一開始寫出來,后來發(fā)現(xiàn)存在問題,陸陸續(xù)續(xù)地改過好幾版是很常見的事情。最終版本中可能每個(gè)小的細(xì)節(jié),都是作者花了很多時(shí)間試錯(cuò)的結(jié)果,但這個(gè)試錯(cuò)的過程并沒有直接地體現(xiàn)在代碼上。另一方面,代碼中往往存在一些「隱含前提」,例如假定函數(shù)的參數(shù)已經(jīng)在傳入之前被以某種方式處理過了,這個(gè)假定很可能于另一個(gè)文件的某行代碼有關(guān),這種聯(lián)系很難引起閱讀者的注意。當(dāng)然,好的設(shè)計(jì)可以緩解這個(gè)問題,但很難被徹底地解決。代碼的歷史會(huì)被保存在版本控制系統(tǒng)里,但說實(shí)話,按我的經(jīng)驗(yàn),很少真的有人去翻版本歷史,因?yàn)檎_地使用版本控制工具相比起寫代碼是一項(xiàng)比較不受重視的技能,在這種情況下翻歷史是非常耗時(shí)的。
當(dāng)然,有些人會(huì)將一些細(xì)節(jié)以注釋的形式添加到代碼中,但注釋也只能承載很小的一部分信息,因?yàn)榫S護(hù)注釋也是一項(xiàng)很高的成本,我個(gè)人一向是反對(duì)添加注釋來解釋代碼的。所以閱讀代碼實(shí)際上并沒有看上去那么輕松,為了徹底理解一段代碼,很有可能你需要付出和編寫這段代碼差不多的努力,來了解這段代碼的歷史和前提。前面提到的是閱讀「好的代碼」的情況,比如大多數(shù)活躍的開源項(xiàng)目,如果是面對(duì)質(zhì)量較差的代碼情況就更為糟糕了。所以我的觀點(diǎn)是,讀代碼絕對(duì)不是一種好的學(xué)習(xí)方式,我認(rèn)為學(xué)習(xí)一項(xiàng)技術(shù)應(yīng)當(dāng)先閱讀書籍,然后嘗試自己實(shí)踐,最后再參考代碼質(zhì)量較高開源項(xiàng)目。對(duì)于大多數(shù)項(xiàng)目而言,可能從未把「供他人學(xué)習(xí)」當(dāng)作目標(biāo),只有當(dāng)你自己實(shí)踐過,積累了一些經(jīng)驗(yàn)并且也遇到過一些困難的時(shí)候,你才能讀懂代碼并且從中學(xué)到解決問題的技巧。而在開始實(shí)踐之前,最好的知識(shí)來源是書籍,因?yàn)闀膬?nèi)容是經(jīng)過精心的安排的,最高目標(biāo)就是供他人閱讀。
達(dá)達(dá)
用熱力學(xué)來回答一下這個(gè)問題:因?yàn)閺乃悸忿D(zhuǎn)換成代碼是熵增加的一個(gè)過程,要把代碼重新整理成思路是熵減少的一個(gè)過程。
好比一副有序的撲克牌很容易變亂,已經(jīng)變亂的撲克牌要變有序需要做更多的功。所以,寫代碼容易,讀代碼難。
MisterFin
假如你讀到這樣一篇文章:“張三把一個(gè)不明物體A、一個(gè)不明物體B、兩個(gè)不明物體C交給了杰克,杰克拿起A,把A的一部分出示給皮爾杜,皮爾杜開始在從一個(gè)本本里掏出一個(gè)東西,連同收到的東西一起交給門捷洛夫,門捷洛夫鼓搗了半天...然后告訴皮爾杜不對(duì),皮爾杜又掏出一個(gè)東西...門捷洛夫告訴皮爾杜對(duì),皮爾杜告訴了田中...”提問:張三在干嘛呢?你會(huì)不會(huì)頭疼上面都在胡說什么呢?如果做一個(gè)替換:張三 —— 顧客;杰克 —— 收銀員;皮爾杜 ?門捷洛夫 田中 —— 收銀臺(tái)(掃描 查詢 顯示)。讀代碼的困難之處同上,就是你沒法知道作者設(shè)置的x, y, count, option, timeline等變量究竟代表了什么東西。
貓殺
讀代碼有兩種情況,一種是讀局部,某個(gè)算法、流程的實(shí)現(xiàn);一種是讀全局,整體架構(gòu),模塊的組織耦合之類的。讀代碼的目的有兩種,一種是純學(xué)習(xí),看別人怎么做;一種是要用,缺文檔的項(xiàng)目要從代碼猜出怎么使用,要加功能做修改等。寫代碼你只需要知道一種實(shí)現(xiàn),讀代碼你可能需要知道多種實(shí)現(xiàn)。
要能很容易的讀懂別人的代碼,簡(jiǎn)單的說就是要見多識(shí)廣,涉及的方面很多,不管是知識(shí)上還是技巧上的,所以難度主要是在這一點(diǎn)上體現(xiàn)。代碼的質(zhì)量影響也很大,但是如果你有大量讀(寫)爛代碼的經(jīng)驗(yàn),難度會(huì)顯著的下降。拿到一個(gè)項(xiàng)目的代碼,你知道這個(gè)項(xiàng)目要做什么事情,有多少種可能的實(shí)現(xiàn)方法,比如是MVC還是View-Document,很快你就能從各種線索中確定是哪一種,方向一確定,隨后的事情就簡(jiǎn)單了,尋找的都是不同的地方(往往也是好看的地方)。比如拿到個(gè)JS寫的前端交互項(xiàng)目來做修改,一看到EventBus的出現(xiàn)就知道八九不離十是MVP模式了。
讀代碼對(duì)工具鏈的熟練程度要求也很高,自己寫代碼,某些人硬要不用IDE拿記事本寫,也就只是慢點(diǎn)而已。讀一個(gè)大型項(xiàng)目如果不會(huì)熟練的利用工具,快速在各種定義、調(diào)用和實(shí)現(xiàn)之間跳轉(zhuǎn),那就是找虐。還有一個(gè)就是目的性,有著目的性的去讀就要容易得多。比如我讀Chrome的源代碼就是對(duì)其多進(jìn)程架構(gòu)感興趣,于是從入口點(diǎn)開始追蹤,窗口的初始化、IPC的建立逐步的去順藤摸瓜的看。幾次讀Linux的源代碼時(shí),都是因?yàn)轫?xiàng)目需要,去研究Linux的時(shí)鐘管理、驅(qū)動(dòng)層實(shí)現(xiàn)等。尤其是大項(xiàng)目,整體讀完的可能性和實(shí)用性不大,帶目的性的、參考性的去讀就要合適一些。除此之外還有很多瑣碎的技巧性的東西,都是需要長期積累的。
王瑞期
情況有很多:
1:知識(shí)背景不同。比如你對(duì)數(shù)據(jù)庫的實(shí)現(xiàn)了解很少,你就完全不知道整個(gè)代碼到底是要實(shí)現(xiàn)什么算法,什么數(shù)據(jù)結(jié)構(gòu)。
2:思考方式不同。有人喜歡 a*(b c),有人喜歡 a*c a*c ,右撇子總是很難理解左撇子左手比較有力的那種感覺。
3:無關(guān)干擾很多?!伴T前有兩棵樹,一棵是棗樹,另一棵也是棗樹”,表達(dá)了作者當(dāng)時(shí)什么樣的意境?其實(shí)作者就是隨便這么一寫,但是別人看了,總覺得有深意,被繞進(jìn)去了。
4:寫代碼時(shí)臨時(shí)起意的情況很多。建房子,你知道標(biāo)準(zhǔn)流程就那樣了,所以一看就知道怎么建的。但是代碼呢,比如我要寫一個(gè)類,這個(gè)類專門用于建房子,我最初設(shè)想有幾個(gè)方法:拿錢,設(shè)計(jì),找建筑隊(duì),建設(shè),裝修。然后寫著寫著,我發(fā)現(xiàn),拿錢這事吧,該有個(gè)方法來處理怎么拿。然后設(shè)計(jì)這事吧,我得寫個(gè)方法,找出我最滿意的設(shè)計(jì)方案。。。。等等,在寫代碼的過程中,總體流程算是線性的,但是詳細(xì)的代碼過程中,會(huì)有很多突然蹦出來的東西。而我們讀代碼,模擬不了作者腦子不停蹦創(chuàng)意的過程,所以,就總覺得這代碼怎么感覺在迷宮里轉(zhuǎn)悠呀。
李遙
同樣是代碼,讀別人的SQL、HTML、CSS比讀別人寫的C 、JavaScript要容易,為什么?原因在于非聲明式的語言會(huì)引入Personal Style這個(gè)問題,而別人的Personal Style不像一個(gè)編程語言有教程有指南有參考手冊(cè),而且作者本人也不一定前后一致,很多情況下你只能“痛苦地”揣測(cè)他為什么這么寫,因此你的大腦自動(dòng)就排斥做這種事。
胡江
讀比你水平高的代碼,自然難。難在跟上人家的想法。讀水平相當(dāng)?shù)拇a,難。難在了解代碼后面來龍去脈,推測(cè)作者的意圖。讀低水平代碼。難在把爛東西看完還要一針見血總結(jié)出道道,避免自己犯同樣錯(cuò)誤。讀代碼難,其實(shí)難在對(duì)自己的認(rèn)識(shí)和對(duì)對(duì)象的把握。最后再扯一下,其實(shí)題目也不準(zhǔn)確,并不是所有讀代碼都難。例如開車狹路遇高手,對(duì)方會(huì)清楚地表達(dá)他的駕駛意圖,讓你輕松決定如何處理?;蚴侨思矣烷T一踩,你還沒反應(yīng)過來車已經(jīng)過去了。有而最怕的是前方本側(cè)有障礙,你特地給對(duì)方留出一大塊車道先行。結(jié)果對(duì)方遠(yuǎn)光不關(guān),一腳剎車等你來闖關(guān)。
聲明:本文來源網(wǎng)絡(luò),版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請(qǐng)與我聯(lián)系刪除。
------------?END?------------
●嵌入式專欄精選教程●精選匯總 | ST工具、下載編程工具●精選匯總 | 嵌入式軟件設(shè)計(jì)與開發(fā)●精選匯總 | STM32、MCU、單片機(jī)
歡迎關(guān)注我的公眾號(hào),回復(fù)“加群”按規(guī)則加入技術(shù)交流群,回復(fù)“1024”查看更多內(nèi)容。
歡迎關(guān)注我的視頻號(hào):
點(diǎn)擊“閱讀原文”查看更多分享,歡迎點(diǎn)分享、收藏、點(diǎn)贊、在看。