很多年前,當(dāng)我還是一名計(jì)算機(jī)專業(yè)的大四學(xué)生時(shí),整天上網(wǎng)瀏覽各類招聘信息,想找到一個(gè)合適的程序員實(shí)習(xí)崗位。
除了實(shí)習(xí)崗位外,我偶爾也會(huì)點(diǎn)進(jìn)一些“高級(jí)工程師”的招聘帖里。現(xiàn)在回想起那些帖子,拋開讓人眼花繚亂的技術(shù)名詞,我印象最深的就是常出現(xiàn)在第一行的崗位年限要求:“本職位要求 工作經(jīng)驗(yàn) 5 年以上”。
作為一只一天班都沒(méi)上過(guò)的小菜鳥,這些年限要求在我眼里簡(jiǎn)直長(zhǎng)到夸張。不過(guò),望洋興嘆之余,我有時(shí)也會(huì)在心中暗暗憧憬一下:“五年工作經(jīng)驗(yàn)的程序員,那該多厲害???寫代碼對(duì)于他們來(lái)說(shuō),是不是像吃飯一樣簡(jiǎn)單?”
時(shí)光荏苒,一晃十幾年過(guò)去了。如今回頭一望,自己也成了一名有著 14 年工作經(jīng)驗(yàn)的光榮打工人。在軟件開發(fā)行業(yè)摸爬滾打這些年后,我發(fā)現(xiàn)很多事情,與我在大四時(shí)所想象的大不相同,比方說(shuō):
- 隨著經(jīng)驗(yàn)增長(zhǎng),編程并不會(huì)變簡(jiǎn)單太多,“像吃飯一樣簡(jiǎn)單”只出現(xiàn)在夢(mèng)里
- 給許多“大項(xiàng)目”寫代碼不光沒(méi)意思,還很危險(xiǎn),遠(yuǎn)不如在 LeetCode 上做一道算法題有趣
- 只從技術(shù)角度思考問(wèn)題,成不了好程序員,有些東西遠(yuǎn)比技術(shù)更重要
細(xì)想起來(lái),這類關(guān)于編程的感觸還有許多。我整理了其中 8 條,寫成了這篇文章。如果其中某些觀點(diǎn)引起了你的共鳴,我會(huì)非常高興。
更多編程干貨:
編程曾經(jīng)是一項(xiàng)門檻很高的專業(yè)技能。從前,一個(gè)普通人想學(xué)編程,最常見的做法就是通過(guò)教材和書本學(xué)習(xí)。不過(guò)大部分編程專業(yè)書,十分艱深晦澀,對(duì)于初學(xué)者來(lái)說(shuō)很不友好。因此不少人在嘗到編程的樂(lè)趣前,就早早地半途而廢。
但如今,學(xué)編程正在變得越來(lái)越容易。學(xué)習(xí)不再像以前那樣,只能硬啃書本,而是多了許多新途徑。觀看教學(xué)視頻、參加 Codecademy[1] 的交互式課程,甚至直接在 CodeCombat[2] 通過(guò)玩游戲來(lái)學(xué)編程,每個(gè)人都能找到適合自己的學(xué)習(xí)方式。
“媽,我真沒(méi)在玩游戲,我在學(xué)編程呢!你看屏幕右邊!”
此外,編程語(yǔ)言也在變得越來(lái)越易用。經(jīng)典的 C 和 Java 不再是大多數(shù)初學(xué)者的首選,許多更簡(jiǎn)單、更易上手的動(dòng)態(tài)類型語(yǔ)言如今大受歡迎,與之相關(guān)的 IDE 等工具也變得越來(lái)越完善。這些因素進(jìn)一步降低了編程的學(xué)習(xí)門檻。
總而言之,編程早已褪去了它的神秘面紗,從只有少數(shù)人才能掌握的神秘技能,變成了一門人人皆可學(xué)習(xí)的普通手藝。
但更低的學(xué)習(xí)門檻,更友好的編程語(yǔ)言,并不意味著人人都能寫出一手好代碼。如果你已經(jīng)工作,參與過(guò)一些項(xiàng)目,那我很想問(wèn)你一個(gè)問(wèn)題:”你日常接觸的這些項(xiàng)目的代碼質(zhì)量如何?是好代碼多,還是爛代碼多?”
不知你會(huì)怎么回答,我先來(lái)說(shuō)說(shuō)我的答案。
1. 好代碼還是很少
2010 年,我跳槽到了一家總部位于北京五道口的大型互聯(lián)網(wǎng)公司。
加入這家公司前,我只在十人規(guī)模的小公司待過(guò),因此,我對(duì)新公司在各方面都有著很高的期待,尤其是軟件質(zhì)量方面。當(dāng)時(shí),我心里想的大概是這樣:“這可是支撐了有著千萬(wàn)用戶量的產(chǎn)品的大項(xiàng)目,代碼質(zhì)量跟之前那些比,肯定有質(zhì)的飛躍吧!”
等到在新公司工作了一周后,我才發(fā)現(xiàn)自己實(shí)在是錯(cuò)得離譜。所謂“大”項(xiàng)目的代碼質(zhì)量同我的預(yù)期相去甚遠(yuǎn)。打開 IDE,數(shù)百行的函數(shù)和神秘的數(shù)字字面量比比皆是,開發(fā)任何一個(gè)小需求都難如登天。
后來(lái),在待過(guò)更多公司,接觸了更多軟件項(xiàng)目后,我總結(jié)出一個(gè)道理:不論公司多大、項(xiàng)目多牛,在實(shí)際工作中遇見好代碼,仍然是小概率事件。
2. 好代碼有哪些要素?
話說(shuō)回來(lái),到底怎樣的代碼才算是好代碼?在這方面,Martin Fowler 有一句話常被大家引用:
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
“任何傻瓜都能寫出計(jì)算機(jī)能理解的代碼。優(yōu)秀程序員寫人類能理解的代碼。”
我認(rèn)為它可以作為評(píng)價(jià)好代碼的原點(diǎn):好代碼一定是可讀、易讀,且容易理解的。寫出好代碼的第一原則,就是把人類讀者放在第一位。
除了可讀性以外,評(píng)價(jià)代碼好壞還有許多其他維度:
- 貼合編程語(yǔ)言:是否使用了當(dāng)前編程語(yǔ)言的推薦寫法?語(yǔ)言特性和語(yǔ)法糖,使用程度是否恰到好處?
- 易于修改:代碼設(shè)計(jì)是否考慮了未來(lái)的需求變更,當(dāng)變化發(fā)生時(shí),代碼是否容易隨之修改?
- API 設(shè)計(jì)合理:API 設(shè)計(jì)是否合理,易于使用?好的 API 在簡(jiǎn)單場(chǎng)景下使用方便,在高級(jí)場(chǎng)景下又可以隨需求擴(kuò)展。
- 性能夠用:代碼性能是否滿足當(dāng)前業(yè)務(wù)需求,同時(shí)為未來(lái)保留了一定提升空間?
- 避免過(guò)度設(shè)計(jì):代碼是否存在過(guò)度設(shè)計(jì)、過(guò)早優(yōu)化的毛???
- …
總而言之,對(duì)于任何層級(jí)的程序員來(lái)說(shuō),好代碼都不是什么唾手可得的東西。要寫出好代碼,需要在許多維度上反復(fù)權(quán)衡、精心設(shè)計(jì),最后再加以持續(xù)打磨。
既然如此,假如想盡快掌握寫代碼這門手藝,有捷徑嗎?
3. 寫好代碼的捷徑
在許多層面上,我認(rèn)為編程和寫作非常相似[3]。二者都是使用文本和符號(hào)來(lái)表達(dá)思想,只是方式略有不同。
談到寫作,我想問(wèn)一個(gè)關(guān)于作家的問(wèn)題:“你聽說(shuō)過(guò)不讀書的作家嗎?你有沒(méi)有聽到過(guò)某位作家說(shuō),他從來(lái)不讀其他人的作品,只讀自己的東西?”。我猜答案應(yīng)該是否定的吧。
如果你去查閱相關(guān)資料,你會(huì)發(fā)現(xiàn)許多職業(yè)作家的日常生活,就是閱讀和寫作兩件事在不斷循環(huán)。他們每天會(huì)花大量時(shí)間閱讀各類文字,然后再寫作。
同樣是“文字工作者”,程序員們就很少重視閱讀。但要想快速提升編程能力,閱讀正是不可或缺的重要一環(huán)。除了日常工作接觸到的項(xiàng)目以外,我們應(yīng)該更多地閱讀那些經(jīng)典軟件項(xiàng)目,從中學(xué)習(xí) API 設(shè)計(jì)、模塊架構(gòu)和代碼編寫的技巧。
不光代碼和技術(shù)文檔,最好再定期讀一些計(jì)算機(jī)方面的專業(yè)書,保持閱讀書籍的習(xí)慣。在這方面,我認(rèn)為 Jeff Atwood 在 15 年前寫的文章 "Programmers Don't Read Books -- But You Should(都說(shuō)程序員不讀書——但你應(yīng)該讀)"[4],如今讀來(lái)仍不過(guò)時(shí)。
提升編程能力的捷徑,就藏在“閱讀 <-> 編程”這個(gè)無(wú)盡循環(huán)里。
“一個(gè)好的程序員應(yīng)該做什么?”
在程序員的日常工作中,有很多事情會(huì)讓人充滿成就感,甚至情不自禁地感嘆“編程真美好”。比方說(shuō),修復(fù)了一個(gè)極難定位的 Bug,用新算法將代碼性能提升了一倍,等等。但在所有的這類事情當(dāng)中,沒(méi)有任何一件,能和“親手創(chuàng)造出一件東西”相比。
當(dāng)你在編程時(shí),創(chuàng)造新事物的機(jī)會(huì)實(shí)際上隨處可見。因?yàn)椴⒎侵挥邪l(fā)布一個(gè)新軟件,才稱得上是“創(chuàng)造”。寫一個(gè)可復(fù)用的工具函數(shù)、設(shè)計(jì)一套清晰的數(shù)據(jù)模型,全都可以歸入“創(chuàng)造”的范疇。
身為程序員,保持對(duì)“創(chuàng)造”的熱情至關(guān)重要。因?yàn)樗梢詭臀覀儯?/p>
- 更高效地學(xué)習(xí):學(xué)習(xí)一門新技術(shù),最高效的方式就是用它開發(fā)一個(gè)真實(shí)項(xiàng)目,在創(chuàng)造的過(guò)程中學(xué)習(xí),效果最好。
- 有機(jī)會(huì)邂逅了不起的東西: 許多改變世界的開源軟件,最初都是作者純粹出于興趣所創(chuàng)造,比如 Linus Torvalds 和 Linux,Guido van Rossum 和 Python。
1989 年的圣誕假期,荷蘭人 Guido van Rossum 敲下了 Python 語(yǔ)言的最初幾行代碼,Python 最初僅被期望作為 ABC 語(yǔ)言的繼承者,但后來(lái)“吞噬”了全世界
雖然“創(chuàng)造”好處多多,程序員們也有大把機(jī)會(huì)去做,但許多人常常缺少一種身為“創(chuàng)造者”的覺(jué)悟。就像那個(gè)廣為流傳的小故事所說(shuō):一位哲學(xué)家詢問(wèn)正在砌磚的工人,有人清楚地知道自己是在建造一座大教堂,有人卻認(rèn)為自己只是在砌磚。很多程序員正是“只見磚塊,不見教堂”。
將自己定位成創(chuàng)造者后,看待事物的方式就會(huì)發(fā)生天翻地覆的變化。舉個(gè)例子,同樣是給 API 增加報(bào)錯(cuò)提示文字,創(chuàng)造者們就能跳出“快速完成需求就好”的思維陷阱,向前一步,追問(wèn)自己一些更重要的問(wèn)題:“我想為用戶創(chuàng)造什么樣的產(chǎn)品體驗(yàn)?怎樣的報(bào)錯(cuò)文字,更能幫助我達(dá)成該目標(biāo)?”
就像任何一個(gè)有用的編程模式一樣,“創(chuàng)造者思維”也能成為你的職業(yè)生涯的一道巨大推進(jìn)力。因此,現(xiàn)在就試著問(wèn)自己一個(gè)問(wèn)題吧——“我的下一份創(chuàng)造會(huì)是什么?”
我曾參與開發(fā)過(guò)一個(gè)互聯(lián)網(wǎng)產(chǎn)品,它設(shè)計(jì)精美,功能豐富,每天都有大量用戶使用。
但就是這么一個(gè)從市場(chǎng)角度看頗為成功的產(chǎn)品,工程質(zhì)量卻非常糟糕。如果你打開它的后端項(xiàng)目,把所有目錄翻個(gè)底朝天,都找不到任何一行單元測(cè)試代碼,其他自動(dòng)化測(cè)試流程也是無(wú)從談起。而業(yè)務(wù)邏輯偏偏又十分復(fù)雜,最后,項(xiàng)目代碼間的意料耦合多如牛毛,開發(fā)一個(gè)新特性,很容易把舊功能給搞掛。
“在忙啥呢?” “試著修復(fù)我之前修一個(gè)問(wèn)題時(shí)搞出來(lái)的問(wèn)題,那問(wèn)題是我之前解決另一個(gè)問(wèn)題搞出來(lái)的,而那個(gè)問(wèn)題又是我……”
因此,項(xiàng)目每次發(fā)布時(shí),開發(fā)和產(chǎn)品同學(xué)全都得嚴(yán)陣以待,氛圍十分緊張。整個(gè)發(fā)布過(guò)程也很刺激,緊急回滾時(shí)有發(fā)生。一個(gè)人在這樣的環(huán)境中工作,技術(shù)成長(zhǎng)拋開不談,心理素質(zhì)肯定能得到極大鍛煉。
編程原本是一件充滿樂(lè)趣的工作,但為這樣的項(xiàng)目編程,樂(lè)趣根本無(wú)從談起。究竟是什么奪走了編程的樂(lè)趣?
1. 理想的編程體驗(yàn)≈“刷題”
LeetCode[5] 是一個(gè)著名的編程學(xué)習(xí)網(wǎng)站,上面提供了許多覆蓋各個(gè)難度的編程題,大部分與算法相關(guān)。用戶可以選擇自己感興趣的題目,直接在瀏覽器上編寫代碼(支持十幾種編程語(yǔ)言)并執(zhí)行。如果通過(guò)了全部的測(cè)試用例,則算作解答成功。
在 LeetCode 上做題
在 LeetCode 刷題很像在玩游戲,富有挑戰(zhàn)性,同時(shí)也很有趣。整個(gè)做題過(guò)程,實(shí)際完美展現(xiàn)了一種理想化的編程體驗(yàn):
- 關(guān)注點(diǎn)分離:每道題目都是一個(gè)獨(dú)立個(gè)體,同一時(shí)間內(nèi),開發(fā)者可以完全沉浸在一道題目中;
- 快速獲得精準(zhǔn)反饋:開發(fā)者每次調(diào)整代碼后,能通過(guò)自動(dòng)化測(cè)試快速獲得結(jié)果反饋;
- 零成本試錯(cuò):寫出的代碼語(yǔ)法有錯(cuò)誤、邏輯有問(wèn)題,沒(méi)有任何不良后果,心理負(fù)擔(dān)小。
不過(guò),屏幕前的你很可能覺(jué)得我在說(shuō)些廢話。
“不然呢?解算法題、寫小腳本,不就是這樣的體驗(yàn)嗎?有啥特別值得說(shuō)的?”你很可能會(huì)繼續(xù)補(bǔ)充道,“你知道我們公司的項(xiàng)目有多復(fù)雜嗎?規(guī)模超大,模塊巨多,你懂我意思嗎?每天服務(wù) ××× 萬(wàn)人,光數(shù)據(jù)庫(kù)就好幾套,消息隊(duì)列都有三種,開發(fā)起來(lái)當(dāng)然要麻煩一點(diǎn)咯!”
確實(shí),全世界的軟件千差萬(wàn)別,開發(fā)起來(lái)不可能都像在 LeetCode 上刷題一樣輕松愉快。但這并不意味著,我們不應(yīng)該努力改善自己身處的編程環(huán)境,哪怕只有一點(diǎn)點(diǎn)。
要通過(guò)改善環(huán)境來(lái)提升編程體驗(yàn),可用的理念和工具包括:
- 模塊化思想:妥善設(shè)計(jì)項(xiàng)目中的每一個(gè)模塊,降低耦合,提升正交性
- 設(shè)計(jì)原則:微觀層面上,應(yīng)用那些經(jīng)典的設(shè)計(jì)原則和模式,比如“SOLID”原則
- 自動(dòng)化測(cè)試:編寫規(guī)范的單元測(cè)試,必要時(shí)使用 Mock 技術(shù),用自動(dòng)化測(cè)試覆蓋業(yè)務(wù)關(guān)鍵路徑
- 縮短反饋回路:切換編譯速度更快的工具,優(yōu)化單測(cè)性能,竭盡全力縮短從“改完代碼”到“獲得反饋”的等待時(shí)間
- 微服務(wù)架構(gòu):必要時(shí),將大單體拆分為多個(gè)職責(zé)各異的微服務(wù),分散復(fù)雜度
- ……
關(guān)注編程環(huán)境,刻意創(chuàng)造出允許高效試錯(cuò)的“代碼樂(lè)園”,讓工作像刷題一樣輕松愉快。是經(jīng)驗(yàn)豐富的程序員能為自身團(tuán)隊(duì)做出的最好貢獻(xiàn)之一。
在代碼質(zhì)量上精益求精是好事,但也要注意別掉進(jìn)完美主義的陷阱。因?yàn)榫幊滩皇撬囆g(shù)創(chuàng)作,不鼓勵(lì)人們無(wú)限度地追求極致。作家大可花上數(shù)年打磨一本傳世之作,但程序員在代碼上鉆牛角尖就很有問(wèn)題。
世間沒(méi)有完美的代碼。大多數(shù)時(shí)候,你的代碼只要能滿足當(dāng)前需求,又為未來(lái)擴(kuò)展留了一些空間就夠了。有那么幾次,我在簡(jiǎn)歷上看到候選人給自己打著“代碼強(qiáng)迫癥”標(biāo)簽。隔著屏幕,我雖能感受到 TA 對(duì)代碼質(zhì)量的那份重視,但在我心底,其實(shí)更期望 TA 早已將完美主義陷阱遠(yuǎn)遠(yuǎn)甩在了后頭。
在軟件開發(fā)領(lǐng)域,“單一職責(zé)原則”(全稱為 Single responsibility principle,后簡(jiǎn)稱為 SRP)是一條非常著名的設(shè)計(jì)原則。它的定義很簡(jiǎn)單,一句話就可以概括:“每個(gè)軟件模塊應(yīng)該只有一個(gè)被修改的理由”。
單一職責(zé)原則:能做到,并不意味著你就該這么做
要掌握 SRP 原則,關(guān)鍵在于搞清楚“被修改的理由”為何物。很顯然,程序是沒(méi)有生命的,它自身不能也不需要主動(dòng)去改變。任何修改程序的理由,都來(lái)自與之相關(guān)的人,人是導(dǎo)致修改的“罪魁禍?zhǔn)住薄?/p>
舉個(gè)簡(jiǎn)單的例子。看看下面這兩個(gè)類,其中哪一個(gè)違反了 SRP 原則?
- 一個(gè)字典數(shù)據(jù)類,支持兩類操作:存數(shù)據(jù)、取數(shù)據(jù);
- 一個(gè)員工資料類,支持兩類操作:更新個(gè)人信息、渲染一張用戶資料卡片圖。
在大多數(shù)人眼里,第一個(gè)例子沒(méi)問(wèn)題,但第二個(gè)例子卻明顯違反了 SRP 原則。要得出該結(jié)論,好像無(wú)需任何嚴(yán)格的分析和證明,運(yùn)用一丁點(diǎn)直覺(jué)即可。但假如做一些正經(jīng)分析,第二個(gè)例子的可疑之處,在于能為其輕松找出兩個(gè)不同的修改理由:
- 管理員認(rèn)為資料中的“個(gè)人電話”字段不能有非法號(hào)碼,需增加簡(jiǎn)單的校驗(yàn)邏輯
- 某員工認(rèn)為資料卡片圖上的“名字”部分太小,希望加大字體
”It is people who request changes. And you don’t want to confuse those people, or yourself, by mixing together the code that many different people care about for different reasons.” ——“The Single Responsibility Principle”
“是人在要求軟件變更。你絕不想把那些不同人出于不同原因所關(guān)心的代碼混在一起,這樣只會(huì)把他們和你自己搞糊涂?!薄皢我宦氊?zé)原則”
理解 SRP 原則的關(guān)鍵,在于先理解人以及人在軟件開發(fā)中所扮演的角色。
再舉一個(gè)例子。微服務(wù)架構(gòu)是近些年很火的一個(gè)技術(shù)話題。但許多人在討論它時(shí),往往只關(guān)注技術(shù)本身,卻忽視了微服務(wù)架構(gòu)與人之間的關(guān)系。
將微服務(wù)架構(gòu)風(fēng)格與其他東西區(qū)分開的關(guān)鍵,在于將大單體拆分為獨(dú)立的微服務(wù)后,不同模塊間的邊界可以變得更清晰。跟數(shù)百人的團(tuán)隊(duì)一同維護(hù)著一個(gè)大單體比起來(lái),許多小組織各自維護(hù)著獨(dú)立的微服務(wù),明顯擁有更高的運(yùn)作效率。
如果缺少了特定的組織規(guī)模(也就是“人”)作為前提,空談微服務(wù)的各種技術(shù)優(yōu)勢(shì)和那些花活,純屬本末倒置。
技術(shù)當(dāng)然很重要。身為技術(shù)人員,那一張張瑰麗的架構(gòu)圖和獨(dú)具匠心的代碼細(xì)節(jié),天然吸引著我們的注意力。但是,也請(qǐng)千萬(wàn)不要對(duì)軟件開發(fā)里的另一個(gè)重要因素“人”視而不見。必要時(shí),轉(zhuǎn)換一下看事情的角度(從“技術(shù)”轉(zhuǎn)向“人”),那樣對(duì)你大有裨益。
如今人人都在說(shuō)“終身學(xué)習(xí)”,而程序員是一個(gè)尤其需要終身學(xué)習(xí)的職業(yè)。因?yàn)橛?jì)算機(jī)技術(shù)的迭代更新非???,某個(gè)三年前流行的框架或編程語(yǔ)言,很可能一個(gè)月前已經(jīng)過(guò)時(shí)。
一分鐘之內(nèi)會(huì)發(fā)生什么事情?Netflix 觀看時(shí)間增長(zhǎng) 70,000 小時(shí);Snapchat 上有三百萬(wàn)視頻被觀看;Google 新增兩百四十萬(wàn)次搜索;一個(gè) JS 新框架被發(fā)明(這條不是真的 )
要在工作中表現(xiàn)得游刃有余,程序員們需要學(xué)習(xí)的東西非常多,涵蓋各個(gè)層面。拿我比較熟悉的后端領(lǐng)域舉例,一位合格的后端工程師至少需要掌握以下這些:
一種或多種后端編程語(yǔ)言 / MySQL 等關(guān)系數(shù)據(jù)庫(kù) / Redis 等常見存儲(chǔ)組件 / 設(shè)計(jì)模式 / 用戶體驗(yàn) / 軟件工程 / 編譯原理 / 操作系統(tǒng) / 網(wǎng)絡(luò)基礎(chǔ) / 分布式系統(tǒng) / …
雖然要學(xué)很多,但據(jù)我觀察,大部分程序員其實(shí)都挺愛學(xué)習(xí)(至少不排斥),因此心態(tài)不是問(wèn)題。不過(guò)有的時(shí)候,光有“求知若渴”的心態(tài)并不夠,學(xué)習(xí)時(shí),我們尤其需要關(guān)注“性價(jià)比”。
1. 關(guān)注學(xué)習(xí)性價(jià)比
下面這張圖,展示了學(xué)習(xí)成效和投入之間的關(guān)系。
學(xué)習(xí)成效與投入關(guān)系圖,橫軸為學(xué)習(xí)投入,縱軸為學(xué)習(xí)成效
從圖中可以看到,在學(xué)習(xí)的初級(jí)階段,投入較少時(shí),所獲得成效增長(zhǎng)飛快。但當(dāng)成效超過(guò)某個(gè)閾值后,之后再想繼續(xù)提升,所需要的學(xué)習(xí)投入就會(huì)呈指數(shù)級(jí)增長(zhǎng)。
正因如此,我建議你在學(xué)習(xí)任何一項(xiàng)新事物時(shí),先在腦海中想清楚一個(gè)問(wèn)題:“我應(yīng)該在上圖中的哪個(gè)位置停下來(lái)?”,而不是悶頭猛學(xué)。
知識(shí)的海洋浩瀚無(wú)邊,有些東西需要我們成年累月的持續(xù)學(xué)習(xí),不斷精進(jìn)。也有些東西,蜻蜓點(diǎn)水般學(xué)到一些皮毛已綽綽有余。準(zhǔn)確判斷并分配自己有限的學(xué)習(xí)精力,甚至比努力學(xué)習(xí)本身更重要。
2. 挑選合適的學(xué)習(xí)資料
有了學(xué)習(xí)目標(biāo)后,下一步就是尋找合適的學(xué)習(xí)資料。在這方面,我想分享一次自己的失敗經(jīng)歷。
有段時(shí)間,我突然對(duì)產(chǎn)品交互設(shè)計(jì)產(chǎn)生了濃厚的興趣,認(rèn)為自己應(yīng)該在這方面有所精進(jìn)。于是,我精心挑選了一本領(lǐng)域內(nèi)非常經(jīng)典的專業(yè)書:《About Face 4: 交互設(shè)計(jì)精髓》[6],將其買回家中,滿懷信心地認(rèn)為自己的交互設(shè)計(jì)能力可以迅速獲得提升。
但事與愿違,當(dāng)我捧著那本經(jīng)典著作時(shí),發(fā)現(xiàn)自己連第一章都無(wú)法順利讀完——那句老話說(shuō)的沒(méi)錯(cuò):“隔行如隔山”。
從這次失敗中,我總結(jié)出了一點(diǎn)經(jīng)驗(yàn)。那就是學(xué)習(xí)某項(xiàng)新東西時(shí),我們最好挑選那些更易讀,更適合“門外漢”的學(xué)習(xí)資料,不要“眼睛大,嘴巴小”,只知道奔著最經(jīng)典、最權(quán)威的資料而去。
回顧之前的經(jīng)歷,我覺(jué)得以下幾本書非常適合門外漢學(xué)習(xí)使用,性價(jià)比極高:
- 《寫給大家看的設(shè)計(jì)書》[7]:設(shè)計(jì)相關(guān)
- 《點(diǎn)石成金》[8]:Web 用戶體驗(yàn)相關(guān)
- 《鳥哥的 Linux 私房菜》[9]:Linux 系統(tǒng)相關(guān)
也許每個(gè)人的內(nèi)心,都想成為一個(gè)博學(xué)的人,無(wú)所不知,無(wú)所不曉。但可供分配的時(shí)間的精力總是有限,我們不能,也不需要在所有領(lǐng)域都成為專家。
我非常非常喜歡單元測(cè)試,我認(rèn)為寫單測(cè)這件事,對(duì)我的編程生涯影響極大??鋸堻c(diǎn)說(shuō),如果以“開始寫單元測(cè)試”作為分界線,把我的職業(yè)生涯分割成兩段,后面那段遠(yuǎn)比前面那段精彩得多。
寫單測(cè)的好處很多,比如單測(cè)可以驅(qū)動(dòng)你改善代碼的設(shè)計(jì)、可以作為代碼的一種文檔,等等。此外,完善的單元測(cè)試還是構(gòu)建前面提到的“高效犯錯(cuò)的環(huán)境”的關(guān)鍵。
我已經(jīng)寫過(guò)幾篇關(guān)于單測(cè)的文章,比如《有關(guān)單元測(cè)試的 5 個(gè)建議》[10]、《游戲“蔚藍(lán)山”教我的編程道理》[11]。所以在這兒,我不打算再重復(fù)一遍。只說(shuō)一句:如果到目前為止,你從未試過(guò)寫單元測(cè)試,或從沒(méi)重視過(guò)測(cè)試,我建議你從明天就開始寫起來(lái)。
一般情況下我不測(cè)試我的代碼,但假如測(cè)的話,我在生產(chǎn)環(huán)境測(cè)
在大多數(shù)程序員段子里,產(chǎn)品經(jīng)理經(jīng)常作為反派角色出現(xiàn)。他們口中的項(xiàng)目需求總是變個(gè)不停,一天冒出一個(gè)新想法,搞得程序員苦不堪言。
客戶每天都在不停修改需求,所以,我們決定在下次發(fā)布前,把這些需求“凍結(jié)”起來(lái)
在這些段子的烘托下,不斷修改需求的產(chǎn)品經(jīng)理,仿佛真成了程序員們最大的仇敵。似乎只要產(chǎn)品不亂改需求,大家的工作環(huán)境馬上就會(huì)成為烏托邦。
雖然偶爾吐槽一兩句產(chǎn)品經(jīng)理很有意思,但我還是想一本正經(jīng)的說(shuō)一句:產(chǎn)品經(jīng)理不是敵人。
因?yàn)閺哪撤N角度來(lái)說(shuō),軟件生來(lái)就是準(zhǔn)備被修改的(不然你猜,軟件為什么叫“軟”件?)。這樣看來(lái),開發(fā)軟件和修建房子完全不同。因?yàn)闆](méi)人會(huì)在建好一棟大樓后說(shuō):“讓我們把它推倒重建一遍吧!一樣的樓,但是用的鋼筋和水泥比之前少 30%!”
所以,產(chǎn)品經(jīng)理以及不穩(wěn)定的需求不是程序員的敵人。并且,能否寫出易于修改、適配變化的代碼,是區(qū)分普通程序員和優(yōu)秀程序員的重要標(biāo)準(zhǔn)之一。
那么,程序員們最大的敵人又是什么呢?
1. 復(fù)雜度是最大的敵人
就像《代碼大全 2》中所說(shuō):軟件開發(fā)的核心問(wèn)題是管理復(fù)雜度。失控的復(fù)雜度就是程序員最大的敵人。
來(lái)看看那些導(dǎo)致項(xiàng)目復(fù)雜度不斷增長(zhǎng)的要素:
- 不斷增加的新功能: 更多的功能等于更多的代碼,更多的代碼通常意味著更高的復(fù)雜度
- 對(duì)高可用的需求: 為了實(shí)現(xiàn)高可用,消息隊(duì)列等額外的技術(shù)組件和代碼被引入
- 對(duì)高性能的需求: 為了提升性能,緩存和相關(guān)模塊代碼被引入,部分模塊被拆分后,換成高性能語(yǔ)言重寫
- 一再被推遲的重構(gòu):因項(xiàng)目排期過(guò)于緊張,迫在眉睫的重構(gòu)被一再推遲,技術(shù)債越積越多
- 忽視自動(dòng)化測(cè)試: 沒(méi)人寫單元測(cè)試,也沒(méi)人關(guān)心測(cè)試
- …
終有一天,當(dāng)項(xiàng)目的復(fù)雜度增長(zhǎng)到一定程度后,空中會(huì)傳來(lái)一聲巨響?!斑?!”,一個(gè)大家不愿改、不敢改的“大坑”憑空出現(xiàn)在了所有人的 IDE 中。
猜猜看,究竟是誰(shuí)挖下了這個(gè)坑?
那些在降低復(fù)雜度上投入時(shí)間的團(tuán)隊(duì),所負(fù)責(zé)的軟件項(xiàng)目更容易成功
2. 減緩復(fù)雜度增長(zhǎng)的過(guò)程
雖然復(fù)雜度總是會(huì)不可避免地持續(xù)增長(zhǎng),但有許多實(shí)踐可以減緩該過(guò)程。如果每個(gè)人都能做到以下這些事,復(fù)雜度就有可能被長(zhǎng)期控制在合理范圍內(nèi):
- 精通當(dāng)前編程語(yǔ)言與工具,寫整潔的代碼
- 使用合適的設(shè)計(jì)模式和編程模式
- 對(duì)重復(fù)代碼零容忍,抽象庫(kù)和框架
- 適當(dāng)運(yùn)用整潔架構(gòu)、領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)思想
- 編寫詳盡的文檔和注釋
- 編寫規(guī)范有效的單元測(cè)試
- 分離那些變動(dòng)的與不變的
- …
要求看上去很多,但總結(jié)起來(lái),核心其實(shí)就是一句話:寫更好的代碼。
2020 年,我在小組內(nèi)做了一個(gè)分享,當(dāng)時(shí)的 PPT 標(biāo)題是《編程十年后的十個(gè)感觸》。將資料分享在公司內(nèi)網(wǎng)后,有位同事看到,評(píng)論說(shuō)光看 PPT 不過(guò)癮,希望我能將其擴(kuò)展成一篇文章,我回復(fù)說(shuō)沒(méi)問(wèn)題。如今 3 年過(guò)去了,我總算是兌現(xiàn)了自己的承諾。
當(dāng)年準(zhǔn)備分享材料時(shí),我做完整個(gè) PPT,最后一頁(yè)實(shí)在不知道該放些啥。于是靈機(jī)一動(dòng),搞了個(gè)純白色的背景,中間打了一行黑體大字:“十年很短,編程很難”。如今,第二個(gè)十年也已快行至中途,而這句話的后半部分好像對(duì)我仍然適用——長(zhǎng)進(jìn)不大,繼續(xù)加油 。
原文鏈接:https://www.piglei.com/articles/programming-is-still-hard-after-14-years/
歡迎關(guān)注作者微信公眾號(hào):「piglei」
復(fù)制本文鏈接 文章為作者獨(dú)立觀點(diǎn)不代表優(yōu)設(shè)網(wǎng)立場(chǎng),未經(jīng)允許不得轉(zhuǎn)載。
發(fā)評(píng)論!每天贏獎(jiǎng)品
點(diǎn)擊 登錄 后,在評(píng)論區(qū)留言,系統(tǒng)會(huì)隨機(jī)派送獎(jiǎng)品
2012年成立至今,是國(guó)內(nèi)備受歡迎的設(shè)計(jì)師平臺(tái),提供獎(jiǎng)品贊助 聯(lián)系我們
AI輔助海報(bào)設(shè)計(jì)101例
已累計(jì)誕生 753 位幸運(yùn)星
發(fā)表評(píng)論 為下方 5 條評(píng)論點(diǎn)贊,解鎖好運(yùn)彩蛋
↓ 下方為您推薦了一些精彩有趣的文章熱評(píng) ↓