想要成為一個(gè)合格的程序員,扎實(shí)的基礎(chǔ)是必不可少的。
想要成為一個(gè)優(yōu)秀的程序員,對(duì)計(jì)算機(jī)的發(fā)展需要有深入淺出的了解。
那么不如我們說說其中某些方面的前世今生。
為什么要先說說字符,因?yàn)橛?jì)算機(jī)只認(rèn)識(shí)0和1。所以字符的重要性不言而喻。
技術(shù)上有很多的名詞,有的是縮寫,有的是創(chuàng)新的東西。了解他們,正確的說出來,會(huì)讓別人覺得你很專業(yè)。
版本格式:主版本號(hào).次版本號(hào).修訂號(hào),版本號(hào)遞增規(guī)則如下:
在軟件管理的領(lǐng)域里存在著被稱作“依賴地獄”的死亡之谷,系統(tǒng)規(guī)模越大,加入的套件越多,你就越有可能在未來的某一天發(fā)現(xiàn)自己已深陷絕望之中。
在依賴高的系統(tǒng)中發(fā)布新版本套件可能很快會(huì)成為惡夢(mèng)。如果依賴關(guān)系過高,可能面臨版本控制被鎖死的風(fēng)險(xiǎn)(必須對(duì)每一個(gè)相依套件改版才能完成某次升級(jí))。而如果依賴關(guān)系過于松散,又將無法避免版本的混亂(假設(shè)兼容于未來的多個(gè)版本已超出了合理數(shù)量)。當(dāng)你專案的進(jìn)展因?yàn)榘姹鞠嘁辣绘i死或版本混亂變得不夠簡(jiǎn)便和可靠,就意味著你正處于依賴地獄之中。
作為這個(gè)問題的解決方案之一,我提議用一組簡(jiǎn)單的規(guī)則及條件來約束版本號(hào)的配置和增長(zhǎng)。這些規(guī)則是根據(jù)(但不局限于)已經(jīng)被各種封閉、開放源碼軟件所廣泛使用的慣例所設(shè)計(jì)。為了讓這套理論運(yùn)作,你必須先有定義好的公共 API。這可以透過文件定義或代碼強(qiáng)制要求來實(shí)現(xiàn)。無論如何,這套 API 的清楚明了是十分重要的。一旦你定義了公共 API,你就可以透過修改相應(yīng)的版本號(hào)來向大家說明你的修改??紤]使用這樣的版本號(hào)格式:XYZ (主版本號(hào).次版本號(hào).修訂號(hào))修復(fù)問題但不影響 API 時(shí),遞增修訂號(hào);API 保持向下兼容的新增及修改時(shí),遞增次版本號(hào);進(jìn)行不向下兼容的修改時(shí),遞增主版本號(hào)。
我稱這套系統(tǒng)為“語義化的版本控制”,在這套約定下,版本號(hào)及其更新方式包含了相鄰版本間的底層代碼和修改內(nèi)容的信息。
以下關(guān)鍵詞 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照 RFC 2119 的敘述解讀。(譯注:為了保持語句順暢, 以下文件遇到的關(guān)鍵詞將依照整句語義進(jìn)行翻譯,在此先不進(jìn)行個(gè)別翻譯。)
使用語義化版本控制的軟件“必須 MUST”定義公共 API。該 API 可以在代碼中被定義或出現(xiàn)于嚴(yán)謹(jǐn)?shù)奈募?nèi)。無論何種形式都應(yīng)該力求精確且完整。
標(biāo)準(zhǔn)的版本號(hào)“必須 MUST”采用 XYZ 的格式,?? 其中 X、Y 和 Z 為非負(fù)的整數(shù),且“禁止 MUST NOT”在數(shù)字前方補(bǔ)零。X 是主版本號(hào)、Y 是次版本號(hào)、而 Z 為修訂號(hào)。每個(gè)元素“必須 MUST”以數(shù)值來遞增。例如:1.9.1 -> 1.10.0 -> 1.11.0。
標(biāo)記版本號(hào)的軟件發(fā)行后,“禁止 MUST NOT”改變?cè)摪姹拒浖膬?nèi)容。任何修改都“必須 MUST”以新版本發(fā)行。
主版本號(hào)為零(0.yz)的軟件處于開發(fā)初始階段,一切都可能隨時(shí)被改變。這樣的公共 API 不應(yīng)該被視為穩(wěn)定版。
1.0.0 的版本號(hào)用于界定公共 API 的形成。這一版本之后所有的版本號(hào)更新都基于公共 API 及其修改內(nèi)容。
修訂號(hào) Z(xyZ | x > 0)“必須 MUST”在只做了向下兼容的修正時(shí)才遞增。這里的修正指的是針對(duì)不正確結(jié)果而進(jìn)行的內(nèi)部修改。
次版本號(hào) Y(xYz | x > 0)“必須 MUST”在有向下兼容的新功能出現(xiàn)時(shí)遞增。在任何公共 API 的功能被標(biāo)記為棄用時(shí)也“必須 MUST”遞增。也“可以 MAY”在內(nèi)部程序有大量新功能或改進(jìn)被加入時(shí)遞增,其中“可以 MAY”包括修訂級(jí)別的改變。每當(dāng)次版本號(hào)遞增時(shí),修訂號(hào)“必須 MUST”歸零。
主版本號(hào) X(Xyz | X > 0)“必須 MUST”在有任何不兼容的修改被加入公共 API 時(shí)遞增。其中“可以 MAY”包括次版本號(hào)及修訂級(jí)別的改變。每當(dāng)主版本號(hào)遞增時(shí),次版本號(hào)和修訂號(hào)“必須 MUST”歸零。
先行版本號(hào)“可以 MAY”被標(biāo)注在修訂版之后,先加上一個(gè)連接號(hào)再加上一連串以句點(diǎn)分隔的標(biāo)識(shí)符號(hào)來修飾。標(biāo)識(shí)符號(hào)“必須 MUST”由 ASCII 碼的英數(shù)字和連接號(hào)[0-9A-Za-z-]組成,且“禁止 MUST NOT”留白。數(shù)字型的標(biāo)識(shí)符號(hào)“禁止 MUST NOT”在前方補(bǔ)零。先行版的優(yōu)先級(jí)低于相關(guān)聯(lián)的標(biāo)準(zhǔn)版本。被標(biāo)上先行版本號(hào)則表示這個(gè)版本并非穩(wěn)定而且可能無法達(dá)到兼容的需求。范例:1.0??.0-alpha、1.0.0-alpha.1、 1.0.0-0.3.7、1.0.0-x.7.z.92。
版本編譯信息“可以 MAY”被標(biāo)注在修訂版或先行版本號(hào)之后,先加上一個(gè)加號(hào)再加上一連串以句點(diǎn)分隔的標(biāo)識(shí)符號(hào)來修飾。標(biāo)識(shí)符號(hào)“必須 MUST”由 ASCII 的英數(shù)字和連接號(hào)[0-9A-Za-z-]組成,且“禁止 MUST NOT”留白。當(dāng)判斷版本的優(yōu)先層級(jí)時(shí),版本編譯信息“可 SHOULD”被忽略。因此當(dāng)兩個(gè)版本只有在版本編譯信息有差別時(shí),屬于相同的優(yōu)先層級(jí)。范例:1.0.0-alpha+001、1.0.0+20130313144700、 1.0.0-beta+exp.sha.5114f85。
這并不是一個(gè)新的或者革命性的想法。實(shí)際上,你可能已經(jīng)在做一些近似的事情了。問題在于只是“近似”還不夠。如果沒有某個(gè)正式的規(guī)范可循,版本號(hào)對(duì)于依賴的管理并無實(shí)質(zhì)意義。將上述的想法命名并給予清楚的定義,讓你對(duì)軟件使用者傳達(dá)意向變得容易。一旦這些意向變得清楚,彈性(但又不會(huì)太彈性)的依賴規(guī)范就能達(dá)成。
舉個(gè)簡(jiǎn)單的例子就可以展示語義化的版本控制如何讓依賴地獄成為過去。假設(shè)有個(gè)名為“救火車”的函式庫(kù),它需要另一個(gè)名為“梯子”并已經(jīng)有使用語義化版本控制的套件。當(dāng)救火車創(chuàng)建時(shí),梯子的版本號(hào)為3.1.0。因?yàn)榫然疖囀褂昧艘恍┌姹?.1.0 所新增的功能, 你可以放心地指定相依于梯子的版本號(hào)大等于3.1.0 但小于4.0.0。這樣,當(dāng)梯子版本3.1.1 和3.2.0 發(fā)布時(shí),你可以將直接它們納入你的套件管理系統(tǒng),因?yàn)樗鼈兡芘c原有相依的軟件兼容。
作為一位負(fù)責(zé)任的開發(fā)者,你理當(dāng)確保每次套件升級(jí)的運(yùn)作與版本號(hào)的表述一致?,F(xiàn)實(shí)世界是復(fù)雜的,我們除了提高警覺外能做的不多。你所能做的就是讓語義化的版本控制為你提供一個(gè)健全的方式來發(fā)行以及升級(jí)套件,而無需推出新的相依套件,節(jié)省你的時(shí)間及煩惱。
如果你對(duì)此認(rèn)同,希望立即開始使用語義化版本控制,你只需聲明你的函式庫(kù)正在使用它并遵循這些規(guī)則就可以了。請(qǐng)?jiān)谀愕腞EADME 文件中保留此頁連結(jié),讓別人也知道這些規(guī)則并從中受益。
說到命名規(guī)范,個(gè)人認(rèn)為包含了目錄,文件以及變量的命名。提前先說一句,命名規(guī)則沒有誰對(duì)誰錯(cuò),在項(xiàng)目中保持一致才是關(guān)鍵。
混亂或錯(cuò)誤的命名不僅讓我們對(duì)代碼難以理解,更糟糕的是,會(huì)誤導(dǎo)我們的思維,導(dǎo)致對(duì)代碼的理解完全錯(cuò)誤。相反,良好的命名,則可以讓我們的代碼非常容易讀懂,也能向讀者正確表達(dá)事物以及邏輯的本質(zhì),從而使得代碼的可維護(hù)性就大大增強(qiáng),讀命名好的文章是非常流暢的,會(huì)有一種享受的感覺。
由于 Windows, OSX 下文件名不區(qū)分大小寫(linux 是區(qū)分的),所以命名我們建議還是以全部小寫為主,個(gè)人習(xí)慣連字符使用-中劃線。比如: my-project-name
項(xiàng)目中的子目錄一般按照作用,使用常用單詞表示,有復(fù)數(shù)的情況,使用復(fù)數(shù)命名法,比如: scripts, styles, images 和 data-modules
文件的命名我個(gè)人也是推薦使用-中劃線進(jìn)行連接。和目錄的連接字符保持一致。但是 linux 系統(tǒng)文件推薦的文件命名一般是下劃線。
變量命名有兩種方式:
my_variablemyVariale
當(dāng)然不同語言也是有不同的規(guī)范,網(wǎng)上也有很多大公司的命名規(guī)范可以參考。變量推薦駝峰式命名法
推薦使用中劃線進(jìn)行連接,CSS 語法本身就使用連字號(hào)作為連接(比如 font-family,text-align等)。
良好的命名,以及良好的命名習(xí)慣,由于我們總是對(duì)每個(gè)概念的名稱要求非常苛刻,我們會(huì)思考這個(gè)名稱所表達(dá)的概念是否正確,該名稱是否正確表達(dá)了事物的本質(zhì)或正確反映了某個(gè)行為的邏輯。所以,這種對(duì)命名的良好思考習(xí)慣,可以反過來幫助我們糾正之前的一些錯(cuò)誤設(shè)計(jì)和代碼實(shí)現(xiàn);比如,你之前有一個(gè)地方可能命名不太準(zhǔn)確,然后你發(fā)現(xiàn)后面有另一個(gè)地方需要用這個(gè)名字,且更合理。所以你會(huì)發(fā)現(xiàn)這個(gè)名字對(duì)前面的地方就不適合了,從而你會(huì)去思考前面的地方可能需要用其他的名字,或者你會(huì)發(fā)現(xiàn)前面的地方的設(shè)計(jì)根本就是有問題的。這種就是名字可以促使你思考你的設(shè)計(jì)是否正確的例子。
一個(gè)程序員,最基本的是需要寫代碼,代碼之中其實(shí)就包含了注釋。如果是一個(gè)系統(tǒng)或者庫(kù)文件,其實(shí)還需要書寫文檔以配合。本文就交大家如何書寫文檔。
討論一下我們?nèi)绾问褂?Github Page 服務(wù)運(yùn)行 Github 幫助文檔 (目前每月有上百萬的訪問量)的。
用戶托管由一大堆 Markdown 文件組成的網(wǎng)站具體內(nèi)容 我們正常的撰寫流程可能是這個(gè)樣子的:
當(dāng) Jekyll 2.0 發(fā)布的時(shí)候,我們看到了曙光,是時(shí)候該把我們這套該死的流程換成純靜態(tài)站了!特別是新增加的 Collections 文檔類型能讓你定義你需要的文件結(jié)構(gòu)。另外,Jekyll 2.0 還增加了 Sass 和 CoffeeScript 的支持,這將使得編寫前端代碼變的更為簡(jiǎn)單便捷。
不管大型還是小型項(xiàng)目,清晰的目錄結(jié)構(gòu)是開發(fā)過程的好的開始。以我常用的 web 項(xiàng)目為例,搭建一下目錄結(jié)構(gòu).
├── src
│ ├── js
│ │ ├── main.js
│ │ ├── plugins.js
│ │ └── vendor
│ │ └── modernizr-2.8.3.min.js
│ ├── css
│ │ └── main.css
│ ├── img
│ ├── favicon.ico
│ ├── humans.txt
│ ├── index.html
│ ├── 404.html
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── crossdomain.xml
│ ├── robots.txt
│ ├── tile-wide.png
│ └── tile.png
├── test
│ ├── file_content.js
│ └── file_existence.js
├── dist
│ ├── 404.html
│ ├── LICENSE.txt
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── crossdomain.xml
│ ├── css
│ │ ├── main.css
│ │ └── normalize.css
│ ├── favicon.ico
│ ├── humans.txt
│ ├── img
│ ├── index.html
│ ├── js
│ │ ├── main.js
│ │ ├── plugins.js
│ │ └── vendor
│ │ ├── jquery-1.11.2.min.js
│ │ └── modernizr-2.8.3.min.js
│ ├── robots.txt
│ ├── tile-wide.png
│ └── tile.png
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── gulpfile.js
├── package.json
目錄結(jié)構(gòu)清晰是首要目標(biāo),至于命名只要能達(dá)到表意的目的即可。
此目錄專注于開發(fā),存放的都是源文件,不需要壓縮合并。目錄下主要分為:
此目錄為編譯生成目錄,用于部署環(huán)境,目錄結(jié)構(gòu)和 src 保持一致。
此目錄為測(cè)試目錄,存放和項(xiàng)目測(cè)試相關(guān)的文件。
如果存在文檔說明,放置在此目錄下。
根目錄下的其他文件,一般還有:
正則表達(dá)式,乍一看以為是很高升的東西,但是對(duì)于程序員而言,它真的應(yīng)該算是一個(gè)基礎(chǔ)知識(shí)。我們?cè)诤芏鄨?chǎng)合下都需要使用到它,這個(gè)技術(shù)又是一個(gè)比較通用的東西,所以對(duì)于程序員而言,是大有益處的。
名字起得文藝了一點(diǎn),主要是想表達(dá)程序員的職業(yè)提升之路。