懶惰被視為七宗罪之一,是個(gè)貶義詞,但在一定場(chǎng)景下,懶惰變成了褒義詞:在我看來(lái),懶惰才是人類進(jìn)步的關(guān)鍵,正是因?yàn)閼?,才?chuàng)造出各種各樣的工具來(lái)提升效率。人們懶得走路,發(fā)明了自行車,后來(lái)懶得蹬車,就發(fā)明了汽車,最近連開(kāi)車都懶得開(kāi)了,于是出現(xiàn)了自動(dòng)駕駛汽車。對(duì)于工程師而言,懶惰也分兩種,這兩種類型的懶惰會(huì)使工程師的成長(zhǎng)出現(xiàn)截然不同的道路。
有利的懶惰
有利的懶惰是指討厭重復(fù)而低效的任務(wù),自己懶得做,就讓工具做,將重復(fù)任務(wù)自動(dòng)化。有利的懶惰能夠極大地提高效率,節(jié)約時(shí)間。下面舉幾個(gè)例子:
CocoaPods
CocoaPods 是開(kāi)發(fā) OS X 和 iOS 應(yīng)用程序時(shí)一個(gè)第三方庫(kù)的依賴管理工具。在 CocoaPods 出現(xiàn)之前,需要添加一個(gè)第三方庫(kù)需要以下操作:
下載第三方庫(kù)的代碼。
將第三方庫(kù)的代碼引入工程,并添加第三方庫(kù)所需的 Framework。
解決庫(kù)與庫(kù)之間、庫(kù)與工程之間的依賴關(guān)系,檢測(cè)重復(fù)添加的 Framework。
如果第三方庫(kù)有更新,需要將庫(kù)從工程中刪除,并重復(fù)上面的步驟。
哦買(mǎi)噶,這些重復(fù)繁瑣的工作能把人煩死,有些“懶惰”的工程師無(wú)法忍受這種情況,于是 CocoaPods 出現(xiàn)了,它能夠自動(dòng)下載配置文件中指定的第三方庫(kù),處理庫(kù)與庫(kù)之間的依賴關(guān)系,并通過(guò)新建一個(gè) xcworkspace 的方式將第三方庫(kù)同工程連接起來(lái)。哈利路亞,感覺(jué)整個(gè)世界清凈了。
ARC 與 Block
ARC 為什么會(huì)出現(xiàn)呢?因?yàn)樵?MRC 下每次都要 retain/release 真是太麻煩了,而且還容易不配對(duì)導(dǎo)致內(nèi)存泄露,估計(jì)蘋(píng)果的工程師都寫(xiě)煩了,既然編譯器能夠識(shí)別出對(duì)象的生命周期,那就讓編譯器去做內(nèi)存管理吧,簡(jiǎn)單省事。有人可能不放心把內(nèi)存管理交給編譯器,你放心,在識(shí)別對(duì)象生命周期這件事上,編譯器比你厲害,再厲害的開(kāi)發(fā)者也有可能因?yàn)橐粫r(shí)疏忽而遺漏,但編譯器不會(huì)。另外,會(huì)有人認(rèn)為 ARC 會(huì)影響性能,這其實(shí)是不理解 ARC 的原理:ARC 不是垃圾回收,只是自動(dòng)幫你寫(xiě) retain/release,而且寫(xiě) retain/relese 時(shí)不再經(jīng)過(guò)消息傳遞,是直接調(diào)用對(duì)應(yīng)的 C 函數(shù),這會(huì)提升性能的。另外,對(duì)于工廠方法返回值,ARC 也會(huì)做優(yōu)化,不再將返回的對(duì)象放入 AutoReleasePool 了,而是直接返回,相當(dāng)于調(diào) alloc + init。所以放心的使用 ARC 吧,這種提高效率的東西為什么不用?
Block 為什么會(huì)出現(xiàn)呢?在我看來(lái),是因?yàn)樵谑褂没卣{(diào)函數(shù)時(shí),每次使用變量都要將變量整合到一個(gè)結(jié)構(gòu)體中,用 void * 指針的形式傳遞給回調(diào)函數(shù)的 context 參數(shù),真是太麻煩了。編譯器既然能識(shí)別出在回調(diào)函數(shù)里使用了哪些變量,就自動(dòng)地跟回調(diào)函數(shù)整合成為一個(gè)對(duì)象吧,這樣在回調(diào)函數(shù)中就能直接使用了。
《iOS 開(kāi)發(fā)進(jìn)階》中的腳本
唐巧的《iOS 開(kāi)發(fā)進(jìn)階》中讓我印象最深的是實(shí)戰(zhàn)技巧里的一些腳本,例如刪除未使用的圖片資源、檢查圖片長(zhǎng)寬是否是偶數(shù)等,雖然都是些簡(jiǎn)單操作,但是能提升效率,感覺(jué)很棒。
我寫(xiě)過(guò)的一個(gè)自動(dòng)部署工具
在中科院實(shí)習(xí)的時(shí)候,曾經(jīng)負(fù)責(zé)開(kāi)發(fā)維護(hù)一個(gè)嵌入式系統(tǒng),代碼是跑在一塊 ARM 開(kāi)發(fā)板上的,因此每次交叉編譯過(guò)后需要通過(guò) FTP 將包傳到開(kāi)發(fā)板上解壓,并配置一下 rcS 啟動(dòng)腳本。開(kāi)發(fā)階段只是一塊 ARM 板,手動(dòng)部署就還好,后來(lái)變成了十五塊 ARM 板,這下我不干了,手動(dòng)部署會(huì)死人的,而且一旦程序有 Bug,就要重新部署一遍。于是“懶惰”的我寫(xiě)了一個(gè)自動(dòng)部署工具,思路就是輪詢目標(biāo) ARM 板的 IP 地址,針對(duì)每個(gè) IP,先通過(guò) FTP 將程序包上傳,再通過(guò) Telnet 輸入解壓程序包以及覆蓋 rcS 啟動(dòng)腳本的指令,將整個(gè)過(guò)程自動(dòng)化。由于懶得每次 IP 地址改變就重新編譯程序,因此將 IP 地址、FTP 賬戶密碼等信息從程序中抽出來(lái),放到一個(gè)配置文件中,每次啟動(dòng)時(shí)讀?。ㄒ菜闶且环N依賴注入了)。同時(shí)也懶得每次 Telnet 輸入的命令改變就重新編譯程序,將 Telnet 要輸入的命令也寫(xiě)到一個(gè)文本文件中,動(dòng)態(tài)讀取。寫(xiě)好了之后,手動(dòng)部署估計(jì)要兩個(gè)小時(shí)的活,一行命令搞定,感覺(jué)生活頓時(shí)美好了許多。
如果仔細(xì)觀察,還有非常多的例子,其實(shí)要做到這一點(diǎn)與能力無(wú)關(guān),與方向無(wú)關(guān),與規(guī)模無(wú)關(guān),只跟態(tài)度有關(guān),包括個(gè)人與團(tuán)隊(duì)的態(tài)度。對(duì)于個(gè)人而言,遇到重復(fù)工作,是就這樣低效地重復(fù)下去,還是思考用自動(dòng)化提高效率?對(duì)于團(tuán)隊(duì)而言,是否給成員時(shí)間來(lái)完成一些能夠提高效率的工具?工程師文化越是濃厚的團(tuán)隊(duì),各種工具就越多,效率就越高??傊瞬⒉簧瞄L(zhǎng)做重復(fù)枯燥的工作,而這些工作恰恰是機(jī)器擅長(zhǎng)的,想辦法交給機(jī)器去做吧,遵循 DRY:
Don’t Repeat Yourself!
不利的懶惰
下面這些不利的懶惰會(huì)極大地妨礙我們成為優(yōu)秀的工程師(在寫(xiě)下面的內(nèi)容時(shí),我也在不斷反思自己,發(fā)現(xiàn)其實(shí)自己許多地方依然犯了懶惰的錯(cuò)誤,邊寫(xiě)邊出汗,膝蓋各種中箭。。。):
懶得搜索
我記得微博上有過(guò)一張亞一程 Laruence 一段群對(duì)話的截圖,里面是這樣說(shuō)的:“不是我說(shuō)你,這么簡(jiǎn)單的問(wèn)題,你不 Google,不百度,來(lái)群里問(wèn),簡(jiǎn)直是舍近求遠(yuǎn)”。其實(shí)真正原因就是懶。在現(xiàn)在這個(gè)時(shí)代,搜索是無(wú)比強(qiáng)大的工具,想想看,世界那么大,就去搜一搜,你不會(huì)是第一個(gè)遇到問(wèn)題的,也不會(huì)是最后一個(gè)遇到的,我覺(jué)得,Google + StackOverflow + Github + Dash 基本上能解決99%的問(wèn)題。
我們經(jīng)常會(huì)遇到搜索不到答案的過(guò)程,于是很多人就放棄了,回到了到處去問(wèn)的老路上。其實(shí)搜索不到答案的原因有2點(diǎn):1,我們沒(méi)有正確描述以及抽象問(wèn)題,找對(duì)關(guān)鍵字。2,我們沒(méi)有用搜索引擎的思維思考。遇到搜索不到的情況時(shí),不要放棄,努力思考如何修改關(guān)鍵字與描述,多試幾次,雖然很痛苦,但痛苦說(shuō)明我們的大腦在形成新的思維模式,一旦形成,我們的搜索會(huì)越來(lái)越準(zhǔn)確,效率也會(huì)越來(lái)越高。
哦,對(duì)了,最后提醒一下,對(duì)于技術(shù)問(wèn)題,還是避免使用百度吧,真的搜不到什么有用的東西。有人會(huì)說(shuō)用 Google 還要科學(xué)上網(wǎng),多麻煩,相比搜索到有效答案帶來(lái)的收益,F(xiàn)Q這點(diǎn)工作真不算什么,我們可是工程師啊,反思下是不是因?yàn)閼兴圆辉敢庥?Google?
懶得思考
我們?cè)趯W(xué)習(xí)一個(gè)知識(shí)的時(shí)候,要積極思考,不能死記硬背。一種框架/特性出現(xiàn)時(shí),一定有它的原因,多想想為什么會(huì)出現(xiàn)?解決了什么樣的問(wèn)題?為什么要這樣做?這樣做的好處是什么?原理是什么?到底是如何實(shí)現(xiàn)的?保持強(qiáng)烈的好奇心,這會(huì)使我們不斷發(fā)問(wèn),在回答問(wèn)題時(shí)會(huì)不斷思考,而只有不斷的思考才能真正理解一個(gè)知識(shí),從而能夠更好的使用。
另外,我們?cè)谟龅絾?wèn)題后,往往會(huì)搜到解決方案只是簡(jiǎn)單的拷貝,不分析背后的原因,不分析解決方案會(huì)造成哪些影響。Bug 是那磨人的小妖精,這次不徹底搞清楚原因,下次它還會(huì)來(lái)煩我們,我們就會(huì)成為傳說(shuō)中的救火隊(duì)長(zhǎng),哪里著火滅哪里,疲于奔命,但火卻越滅越多。
懶得閱讀
現(xiàn)在不是知識(shí)匱乏,而是知識(shí)爆炸,如果想學(xué)習(xí),有太多的東西可以學(xué)了:
書(shū):iOS 的經(jīng)典書(shū)籍,隨便一本都能讓人受益匪淺。
博客:有太多優(yōu)秀的博客了,那都是別人深思熟慮的精華,花了數(shù)個(gè)小時(shí)寫(xiě)出來(lái)的。
文檔:很多時(shí)候,StackOverflow 回答問(wèn)題的方式就是貼上一段官方開(kāi)發(fā)文檔上的文字,或者接口 API 的說(shuō)明,在看不到源碼的情況下,官方文檔可以看出源碼的接口說(shuō)明,很值得一讀。用 Dash 或 Xcode 自帶文檔工具,遇到不清楚的點(diǎn)就去看一看。
源碼。Reading the Fucking SOURCE CODE 不是一句空話,源碼之下無(wú)秘密。有些效果不知道怎么做,到 GitHub 上搜一搜,看懂了自己不就會(huì)了。
總之,Stay Hungry,Stay Foolish!
懶得動(dòng)手嘗試
看看這篇《Leveling Up》,紙上得來(lái)終覺(jué)淺,絕知此事要躬行,動(dòng)手才是學(xué)習(xí)最有效的方法:
在看別人教程時(shí),把 Demo 下載,自己跑一跑,改改參數(shù),或者自己嘗試重新寫(xiě)一遍,效果絕對(duì)比只看要好。自己有疑問(wèn)時(shí)或者有想法時(shí),都可以寫(xiě)個(gè) Demo 實(shí)驗(yàn)一下。
在看 Objective-C Runtime 原理時(shí),親自用 clang -rewrite-objc file.m 將 .m 文件轉(zhuǎn)成 .cpp 文件看一看。用 Associated Object 給 Category 加屬性時(shí)都自己寫(xiě)段代碼試一試。
想看系統(tǒng)函數(shù)的調(diào)用情況,可以用 Method Swizzle 給一些系統(tǒng)方法加一些“裝飾”,或者還可以用符號(hào)斷點(diǎn)。沒(méi)事干找臺(tái)越獄手機(jī)用 Reveal 看看別人家的 App。
懶得改進(jìn)優(yōu)化
唯一不變的就是變化。代碼在最初時(shí)由于業(yè)務(wù)簡(jiǎn)單一般都很不錯(cuò),但往往在增加新需求/需求變化時(shí)開(kāi)始出現(xiàn)壞味道,因?yàn)樾枨蟮淖兓?jīng)常導(dǎo)致大環(huán)境變化,而不同環(huán)境下的實(shí)現(xiàn)是不同的,例如網(wǎng)站支持100人訪問(wèn)與支持100000人訪問(wèn)是兩種實(shí)現(xiàn)方式,控件只支持一行顯示與支持多行顯示也是兩種實(shí)現(xiàn)方式。PM 有時(shí)候意識(shí)不到需求變化背后隱含的環(huán)境變化對(duì)技術(shù)實(shí)現(xiàn)的影響,覺(jué)得不就是簡(jiǎn)單的改一下,有什么難的?對(duì)啊,把大象裝冰箱里也只需要三步,有什么難的?為了應(yīng)對(duì)這些變化,工程師有時(shí)需要對(duì)結(jié)構(gòu)進(jìn)行調(diào)整,保證結(jié)構(gòu)的靈活,在下次變化來(lái)臨時(shí)更從容,這種調(diào)整就是重構(gòu)。重構(gòu)不是洪水猛獸,重構(gòu)可以很大,也可以很小,一切在于時(shí)間點(diǎn),修改的時(shí)間點(diǎn)越早,成本就越低,不然就會(huì)欠下技術(shù)債。在邏輯的世界里,只分對(duì)錯(cuò),欠下的一定會(huì)還。不要為了一時(shí)便利而忽略了可持續(xù)性,切記技術(shù)債是高利貸,利滾利,拖得時(shí)間越久,成本就越高,到最后一定會(huì)連本帶利讓欠債者賠個(gè)精光。
因此工程師在實(shí)現(xiàn)需求時(shí)一定要留出 Buffer 來(lái)處理結(jié)構(gòu)變化引起的重構(gòu)與遺留代碼帶來(lái)的技術(shù)債,不能懶,這樣以后的需求才會(huì)更好做。而團(tuán)隊(duì)在每個(gè)迭代中也應(yīng)考慮將一些技術(shù)債與優(yōu)化作為需求加入到需求池中,不然代碼的壞味道就開(kāi)始在工程中彌漫,需求越做越慢,Bug 越做越多,為了速度,開(kāi)始拼命加班招人,效率卻越來(lái)越低,進(jìn)入惡性循環(huán)。
懶得總結(jié)
在我看來(lái),經(jīng)驗(yàn)從來(lái)不是比拼總時(shí)間,而是比拼效果。有些人多年經(jīng)驗(yàn)卻不如有些人一年經(jīng)驗(yàn),這是為何?關(guān)鍵在于總結(jié)。就拿圣斗士星矢來(lái)說(shuō),如果單論時(shí)間,他能當(dāng)上青銅圣斗士都很勉強(qiáng)了,為什么他能打敗黃金圣斗士,因?yàn)樗f(shuō)過(guò):圣斗士不會(huì)敗給同一招兩次!犯錯(cuò)掉進(jìn)坑里不要緊,誰(shuí)沒(méi)有犯過(guò)錯(cuò)?但掉進(jìn)同一個(gè)坑兩次就不太好了,而有效的經(jīng)驗(yàn)?zāi)茏屛覀円院蟛辉俜赶嗤蝾愃频腻e(cuò)誤。
如何克服這些問(wèn)題
我仔細(xì)觀察過(guò)一些優(yōu)秀的 iOS 工程師,發(fā)現(xiàn):
每年都有 WWDC,大家都能看,但喵神 onevcat 總能寫(xiě)出高質(zhì)量的筆記與總結(jié)。
同樣是學(xué) Objective-C,陽(yáng)神孫源能玩出花來(lái),挖掘出各種特性與原理。(我曾經(jīng)在陽(yáng)神的博客上問(wèn)過(guò)一個(gè)問(wèn)題,陽(yáng)神告訴我他是通過(guò)反解匯編代碼得出的,我就意識(shí)到自己犯了懶于嘗試的錯(cuò)誤了)
動(dòng)畫(huà)狂魔葉孤城_與動(dòng)畫(huà)小王子 KITTEN-YANG 的動(dòng)畫(huà)屌炸天,不用問(wèn)他們?yōu)楹稳绱藢?,去他們?GitHub 上看看他們各種嘗試動(dòng)畫(huà)的 Demo 就知道了。
唐巧的《iOS 開(kāi)發(fā)進(jìn)階》讓我收獲最多的不是里面的知識(shí),而是他學(xué)習(xí)與總結(jié)的方式,我不斷的反思自己,我平時(shí)學(xué)習(xí)時(shí),是否能像他一樣總結(jié)出一本自己的 iOS 學(xué)習(xí)筆記。
還有許多優(yōu)秀的 iOS 工程師這里就不一一舉例了,我認(rèn)為,這些優(yōu)秀的 iOS 工程師并沒(méi)有比你我聰明,跟我們一樣只是普通人,但他們?cè)谏厦孢@些事情上不懶惰,積極思考、嘗試、總結(jié),在同樣的條件下收獲多一點(diǎn)點(diǎn),日積月累,于是他們變得優(yōu)秀。不要小看這一點(diǎn)點(diǎn),我們要相信積累的力量,水滴石穿啊,tinyfool 說(shuō)過(guò),這種積累所達(dá)到的層次,很難被人短時(shí)間追趕上,需要?jiǎng)e人同樣去積累,是非常具有競(jìng)爭(zhēng)力的。
面對(duì)這些優(yōu)秀的 iOS 工程師,我們經(jīng)常會(huì)犯另一種懶惰的錯(cuò)誤:我們總想加好友,攀交情,甚至用拉低姿態(tài)的方式,總覺(jué)得自己抱上大腿就能迅速成長(zhǎng),迅速變牛。這其實(shí)是種假象,是自己不自信不獨(dú)立的表現(xiàn)。即使加了好友,他們能夠答疑解惑,甚至手把手教,親自幫忙解決問(wèn)題又怎樣,那還是別人的東西,自己沒(méi)有任何成長(zhǎng),自己不就犯了懶惰的錯(cuò)誤嗎?
學(xué)習(xí)與成長(zhǎng)從來(lái)沒(méi)有捷徑,也只能靠自己!
除了欣賞與欽佩這些優(yōu)秀的人外,我覺(jué)得更重要的是默默地觀察與努力,觀察他們是如何成長(zhǎng)的,學(xué)習(xí)他們的好習(xí)慣,努力提升自己,向他們看齊,當(dāng)有一天達(dá)到了他們的水平之后,無(wú)需刻意培養(yǎng),同他們自會(huì)相熟,因?yàn)閮?yōu)秀的人總是互相吸引互相欣賞,“臭味相投”,不是嗎?
總之,借用《學(xué) iOS 開(kāi)發(fā)的一些經(jīng)驗(yàn)》里的一段話來(lái)激勵(lì)自己,努力成為一名“懶惰”而不懶惰的優(yōu)秀工程師:
我覺(jué)得支撐我們不斷探索和前進(jìn)的動(dòng)力不是興趣,而是永不滿足的好奇心,和對(duì)優(yōu)雅代碼的追求。
與技術(shù)無(wú)關(guān)的懶惰
最后提一下工程師非常常見(jiàn)的懶惰:懶得鍛煉,不注意自己身體。在我看來(lái),我們可以熱愛(ài)編程,熱愛(ài)自己的工作,熱愛(ài)自己的事業(yè),熱愛(ài)自己的公司,但這些不是最重要的,最重要的是我們自己的身體與我們的家庭。為什么呢?因?yàn)閷?duì)于公司而言,我們是可以替代的,無(wú)論我們多么牛,多么重要,少了我們,公司依然可以運(yùn)作。但對(duì)于身體與家庭而言,我們是不可替代的!身體不是程序,不能重置,一旦身體壞了,就很難恢復(fù),甚至繼續(xù)惡化,伴隨一生。一旦我們走了,我們的父母、配偶、子女就失去了唯一的我們,這帶來(lái)的傷害與損失對(duì)于家庭而言是無(wú)法估量的,甚至為持續(xù)一輩子(看看那些失孤的老人,讓人心碎?。J胫厥胼p,我相信理智的工程師會(huì)做出自己的決定。
我這里不是說(shuō)我們不要奮斗不要拼搏,這跟鍛煉身體完全是互不影響的,鍛煉身體甚至能讓我們能夠更好的拼搏與奮斗。我們不能學(xué)習(xí)現(xiàn)在敏捷的一些錯(cuò)誤做法,只強(qiáng)調(diào)快,卻忽略了可持續(xù)性(敏捷強(qiáng)調(diào)的是可持續(xù)性的快速迭代),所以不要拼一天的工作時(shí)長(zhǎng),留出點(diǎn)時(shí)間鍛煉健身,我們都加過(guò)班,長(zhǎng)時(shí)間加班加到后面其實(shí)腦子已經(jīng)不夠敏銳了,效率極低,對(duì)編程這種強(qiáng)腦力勞動(dòng)是很不利的,易出問(wèn)題,還不如回去跑跑步,早點(diǎn)休息,明天更高效完成就好了。有時(shí)候公司或團(tuán)隊(duì)的氛圍就是不把工程師當(dāng)人看,瘋狂加班,幻想著靠十個(gè)女人懷孕一個(gè)月就能把孩子生出來(lái),我覺(jué)得實(shí)在受不了就換一家吧,沒(méi)什么大不了,開(kāi)心健康地活著其實(shí)就是在賺錢(qián)。(醫(yī)院才是真正的銷金窟,錢(qián)到那個(gè)時(shí)候就是個(gè)數(shù)字,醫(yī)院里充斥著痛苦、無(wú)助、絕望、麻木,唯獨(dú)沒(méi)有幸福,誰(shuí)經(jīng)歷過(guò)誰(shuí)知道)
另外,在工程師的眼里,既然一切都是邏輯,為什么不把自己的身體當(dāng)做程序來(lái)調(diào)試與優(yōu)化呢?一樣的都有輸入輸出,對(duì)高熱量食物防御式編程等,我曾經(jīng)這樣試過(guò),成功減肥30斤,當(dāng)我能夠穿上一條許久都穿不上的褲子時(shí),相信我,那種成就感比寫(xiě)100個(gè)牛逼程序或 GitHub 上有一個(gè)10000+ Star 的倉(cāng)庫(kù)都要強(qiáng)。
-
工程師
+關(guān)注
關(guān)注
59文章
1570瀏覽量
68514
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論