十年編程經(jīng)驗總結(jié),三點技巧幫你提升代碼能力!
大家好,今天和大家聊一個老生常談的的話題,作為程序員,我們怎么提升我們的代碼能力?
在回答這個問題之前,我們需要先給代碼能力下一個定義,搞清楚究竟什么是代碼能力。只有找對了路才方便發(fā)力,很多同學(xué)對這個問題其實是不夠清楚的。往往會覺得代碼能力就是算法能力,就是去刷LeetCode或者是算法題。還有些同學(xué)覺得代碼能力就是要多刷項目,項目做得多了,代碼能力自然就上來了。
其實這兩種看法我個人感覺都是有一點誤區(qū)的,下面簡單聊聊我自己的看法,希望能夠幫助到大家。
語言基礎(chǔ)
很多人看到這里估計要吐槽了,這不是廢話么,程序員寫代碼語言沒學(xué)會還怎么寫代碼?
其實還真不是廢話,不同的語言有不同的特性,甚至有不同的原理,如果沒有對語言基礎(chǔ)有比較扎實的掌握,很容易犯一些低級錯誤。
舉個簡單的例子好了,之前認識的一個實習(xí)生,有一次寫了這么一段Python代碼,大家不妨看看有什么問題。
- def funcA(param):
- if param is not None:
- return funcB(param)
- return None
- def funcB(param):
- pass
不知道有多少同學(xué)能夠看出問題在哪里,有一些同學(xué)可能會覺得是is not None的判斷不對,應(yīng)該寫成not is None。其實問題不在這里,is not None才是標準判斷的寫法,只是這個問題當(dāng)中的障眼法。真正的問題是在函數(shù)調(diào)用的部分,他把funcB寫在了funcA的后面。
funcB寫在后面有什么問題?
大家試一下就會知道,這樣寫Python解釋器是會報錯的,我們必須要把funcB寫在funcA的前面。因為Python不是編譯型語言是解釋型語言,它是由解釋器逐行執(zhí)行的。所以它會先執(zhí)行funcA再執(zhí)行funcB,當(dāng)它執(zhí)行funcA的時候會發(fā)現(xiàn)funcB這個函數(shù)沒有出現(xiàn)過,所以會拋出錯誤。
當(dāng)時這位同學(xué)debug了半天也沒有找到問題所在,甚至還一度以為是Python版本的問題。這其實不是他代碼能力不行,而是對語言基礎(chǔ)掌握不夠扎實。
類似的例子非常多,因為每一門語言往往擁有大量自己的特性,如果我們對某一門的語言只是淺嘗輒止,那么寫出來的代碼一定是非常不規(guī)范的。比如Java如果不知道抽象類,Python不知道可變參數(shù)、裝飾器的話,很多時候?qū)懗鰜淼拇a看起來就是不舒服的,因為沒有做到最簡,會給人一種費了很大勁實現(xiàn)了一個很基礎(chǔ)的功能的感覺。
所以語言基礎(chǔ)也是代碼能力的基礎(chǔ),大家不要看不起這個,覺得只要會基本的語法會寫就可以了。其實這是大錯特錯的,一些特性和語法糖可能用得少,但是關(guān)鍵時候用起來是可以大大簡化代碼量以及增加代碼可讀性的。
代碼規(guī)范
不知道大家有沒有讀過那些特別不規(guī)范的代碼,我讀過一些,真的是感覺眼睛被針扎了一樣。
代碼規(guī)范其實更多的不是能力,而是工程師自己的素養(yǎng)。素養(yǎng)高的工程師會自己主動了解當(dāng)前這門語言的編碼規(guī)范,絕不會怎么舒服怎么來。大家可以百度一下代碼規(guī)范,每一門語言基本上都有自己的代碼規(guī)范,而且這個規(guī)范是非常細致的,具體到變量名、類名、方法名、文件名、常量名怎么命名都有對應(yīng)的規(guī)范。
不僅如此,還對一些特殊情況也做了限制,下面是我從Google的Java編碼規(guī)范當(dāng)中截取的一段,大家可以看下:
我們寫出來的代碼和這份規(guī)范越貼合,那么可讀性也就越強,也就體現(xiàn)我們編碼的素養(yǎng)越高。
代碼規(guī)范其實并不僅僅包含編碼的方面,同樣還包含其他很多領(lǐng)域。比如數(shù)據(jù)庫的連接池的使用,比如kafka的設(shè)置和使用,以及多線程的使用等等,都會有自己的規(guī)范。這些內(nèi)容不僅是起到一個規(guī)范作用,當(dāng)中的每一個點里面都是有對應(yīng)的原理的,值得我們?nèi)ド钔趯W(xué)習(xí)。
比如很多人都知道數(shù)據(jù)庫需要用數(shù)據(jù)庫連接池,那么請問為什么要用連接池呢?連接池的連接數(shù)又是怎么設(shè)置呢?其中的原理是什么呢?
看起來好像是面試題,但其中包含的就是我們對數(shù)據(jù)庫連接底層的理解。我們弄懂了可能不僅在編碼的時候用得到,也許在以后學(xué)習(xí)其他內(nèi)容的時候也能串聯(lián)起來。知識不是由許多點組成的,知識是一張網(wǎng),需要把很多點串聯(lián)起來。在我們串聯(lián)之前,我們首先需要足夠多的積累。
系統(tǒng)能力
系統(tǒng)能力是代碼能力當(dāng)中最高的要求,也是最貼合一個架構(gòu)師能力的部分。
同樣,我們來舉個例子。比如你承接了團隊當(dāng)中的一個任務(wù),開發(fā)一個新的系統(tǒng)。這個系統(tǒng)需要承接每秒100K請求的訪問。這些請求的數(shù)據(jù)我們不是全部都要,需要做一定的抽樣,并且還需要查詢一些存儲系統(tǒng)進行特征填充。最后把完整的數(shù)據(jù)存儲下來。
現(xiàn)在這個任務(wù)交給了你,請問,這當(dāng)中的性能瓶頸是什么?你該怎么設(shè)計這個系統(tǒng)當(dāng)中的細節(jié)?
估計很多同學(xué)會把眼光放在100K這個數(shù)字上,覺得這個請求量非常大,可能系統(tǒng)能不能抗住是最大的風(fēng)險點。但其實100K并不是重點,因為這些請求不需要返回,只是單純的接收,100K并不是非常大。但是當(dāng)中有許多隱藏的問題,比如說我們抽樣怎么抽,是在線抽,還是先把所有請求存儲起來一段時間之后再進行抽樣?如果是存儲起來再抽樣,會不會內(nèi)存扛不住?再比如我們會對存儲系統(tǒng)發(fā)起的查詢請求是什么量級?會不會影響存儲系統(tǒng)?
實際上后來實踐的過程果然發(fā)生了存儲系統(tǒng)扛不住,導(dǎo)致抖動很厲害的情況。那這個問題發(fā)生了之后,我們又該怎么解決?
對這些問題的敏感、理解以及解決,需要的就是系統(tǒng)能力。也就是我們理解系統(tǒng)的能力,這當(dāng)中涉及很多,需要我們有一定的操作系統(tǒng)的知識、分布式的知識,還需要對上下游的系統(tǒng)都有一定的了解。比如知道存儲系統(tǒng)的性能不是很好,大批量的請求可能扛不住。這當(dāng)中有一些是經(jīng)驗,更多的還是我們的基礎(chǔ)能力。
提升之道
其實這三點看完,相信大家對于怎么提升應(yīng)該都或多或少地有了一些自己的想法。
說穿了也沒有什么大不了的,無非是三點,我們來做個簡單的總結(jié)。
- 需要夯實語言基礎(chǔ),對于學(xué)習(xí)的語言不能淺嘗輒止,需要有比較深刻的理解。當(dāng)然這一點也不是說說而已,肯定需要針對性的做很多練習(xí),也需要閱讀其他大牛的代碼進行學(xué)習(xí)。
- 需要遵守代碼規(guī)范,不僅僅是變量的命名、一些特殊case的處理,還需要理解一些場景下的系統(tǒng)使用規(guī)范
- 需要充分理解系統(tǒng),對每一個環(huán)節(jié)仔細推敲,需要積累一些操作系統(tǒng)、分布式的知識點和技能點。
從這三點總結(jié)來看,好像沒什么大不了的,每個人都能很輕易做到的樣子。但實際情況告訴我們,往往越是簡單的道理,越是難以做到,希望大家不要輕視了它們。
本文轉(zhuǎn)載自微信公眾號「TechFlow」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系TechFlow公眾號。