鍍金池/ 教程/ 產(chǎn)品經(jīng)理/ 程序員基礎(chǔ)知識
SOHO
寫點東西
懂點設(shè)計
常用軟件
Hacker
代碼架構(gòu)
獲取知識
代碼評審
程序員基礎(chǔ)知識
PM
團隊合作
其他方面
數(shù)據(jù)結(jié)構(gòu)與算法
關(guān)注健康
網(wǎng)絡(luò)知識
關(guān)于工作
提升效率
服務(wù)器部署
附錄

程序員基礎(chǔ)知識

想要成為一個合格的程序員,扎實的基礎(chǔ)是必不可少的。

想要成為一個優(yōu)秀的程序員,對計算機的發(fā)展需要有深入淺出的了解。

那么不如我們說說其中某些方面的前世今生。

字符編碼

為什么要先說說字符,因為計算機只認識0和1。所以字符的重要性不言而喻。

參考資料

技術(shù)名詞

技術(shù)上有很多的名詞,有的是縮寫,有的是創(chuàng)新的東西。了解他們,正確的說出來,會讓別人覺得你很專業(yè)。

參考資料

語義化版本

摘要

版本格式:主版本號.次版本號.修訂號,版本號遞增規(guī)則如下:

  • 主版本號:當(dāng)你做了不兼容的 API 修改。
  • 次版本號:當(dāng)你做了向下兼容的功能性新增。
  • 修訂號:當(dāng)你做了向下兼容的問題修正。 先行版本號及版本編譯信息可以加到“主版本號.次版本號.修訂號”的后面,作為延伸。

簡介

在軟件管理的領(lǐng)域里存在著被稱作“依賴地獄”的死亡之谷,系統(tǒng)規(guī)模越大,加入的套件越多,你就越有可能在未來的某一天發(fā)現(xiàn)自己已深陷絕望之中。

在依賴高的系統(tǒng)中發(fā)布新版本套件可能很快會成為惡夢。如果依賴關(guān)系過高,可能面臨版本控制被鎖死的風(fēng)險(必須對每一個相依套件改版才能完成某次升級)。而如果依賴關(guān)系過于松散,又將無法避免版本的混亂(假設(shè)兼容于未來的多個版本已超出了合理數(shù)量)。當(dāng)你專案的進展因為版本相依被鎖死或版本混亂變得不夠簡便和可靠,就意味著你正處于依賴地獄之中。

作為這個問題的解決方案之一,我提議用一組簡單的規(guī)則及條件來約束版本號的配置和增長。這些規(guī)則是根據(jù)(但不局限于)已經(jīng)被各種封閉、開放源碼軟件所廣泛使用的慣例所設(shè)計。為了讓這套理論運作,你必須先有定義好的公共 API。這可以透過文件定義或代碼強制要求來實現(xiàn)。無論如何,這套 API 的清楚明了是十分重要的。一旦你定義了公共 API,你就可以透過修改相應(yīng)的版本號來向大家說明你的修改??紤]使用這樣的版本號格式:XYZ (主版本號.次版本號.修訂號)修復(fù)問題但不影響 API 時,遞增修訂號;API 保持向下兼容的新增及修改時,遞增次版本號;進行不向下兼容的修改時,遞增主版本號。

我稱這套系統(tǒng)為“語義化的版本控制”,在這套約定下,版本號及其更新方式包含了相鄰版本間的底層代碼和修改內(nèi)容的信息。

語義化版本控制規(guī)范(SemVer)

以下關(guān)鍵詞 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照 RFC 2119 的敘述解讀。(譯注:為了保持語句順暢, 以下文件遇到的關(guān)鍵詞將依照整句語義進行翻譯,在此先不進行個別翻譯。)

  1. 使用語義化版本控制的軟件“必須 MUST”定義公共 API。該 API 可以在代碼中被定義或出現(xiàn)于嚴謹?shù)奈募?nèi)。無論何種形式都應(yīng)該力求精確且完整。

  2. 標準的版本號“必須 MUST”采用 XYZ 的格式,?? 其中 X、Y 和 Z 為非負的整數(shù),且“禁止 MUST NOT”在數(shù)字前方補零。X 是主版本號、Y 是次版本號、而 Z 為修訂號。每個元素“必須 MUST”以數(shù)值來遞增。例如:1.9.1 -> 1.10.0 -> 1.11.0。

  3. 標記版本號的軟件發(fā)行后,“禁止 MUST NOT”改變該版本軟件的內(nèi)容。任何修改都“必須 MUST”以新版本發(fā)行。

  4. 主版本號為零(0.yz)的軟件處于開發(fā)初始階段,一切都可能隨時被改變。這樣的公共 API 不應(yīng)該被視為穩(wěn)定版。

  5. 1.0.0 的版本號用于界定公共 API 的形成。這一版本之后所有的版本號更新都基于公共 API 及其修改內(nèi)容。

  6. 修訂號 Z(xyZ | x > 0)“必須 MUST”在只做了向下兼容的修正時才遞增。這里的修正指的是針對不正確結(jié)果而進行的內(nèi)部修改。

  7. 次版本號 Y(xYz | x > 0)“必須 MUST”在有向下兼容的新功能出現(xiàn)時遞增。在任何公共 API 的功能被標記為棄用時也“必須 MUST”遞增。也“可以 MAY”在內(nèi)部程序有大量新功能或改進被加入時遞增,其中“可以 MAY”包括修訂級別的改變。每當(dāng)次版本號遞增時,修訂號“必須 MUST”歸零。

  8. 主版本號 X(Xyz | X > 0)“必須 MUST”在有任何不兼容的修改被加入公共 API 時遞增。其中“可以 MAY”包括次版本號及修訂級別的改變。每當(dāng)主版本號遞增時,次版本號和修訂號“必須 MUST”歸零。

  9. 先行版本號“可以 MAY”被標注在修訂版之后,先加上一個連接號再加上一連串以句點分隔的標識符號來修飾。標識符號“必須 MUST”由 ASCII 碼的英數(shù)字和連接號[0-9A-Za-z-]組成,且“禁止 MUST NOT”留白。數(shù)字型的標識符號“禁止 MUST NOT”在前方補零。先行版的優(yōu)先級低于相關(guān)聯(lián)的標準版本。被標上先行版本號則表示這個版本并非穩(wěn)定而且可能無法達到兼容的需求。范例:1.0??.0-alpha、1.0.0-alpha.1、 1.0.0-0.3.7、1.0.0-x.7.z.92。

  10. 版本編譯信息“可以 MAY”被標注在修訂版或先行版本號之后,先加上一個加號再加上一連串以句點分隔的標識符號來修飾。標識符號“必須 MUST”由 ASCII 的英數(shù)字和連接號[0-9A-Za-z-]組成,且“禁止 MUST NOT”留白。當(dāng)判斷版本的優(yōu)先層級時,版本編譯信息“可 SHOULD”被忽略。因此當(dāng)兩個版本只有在版本編譯信息有差別時,屬于相同的優(yōu)先層級。范例:1.0.0-alpha+001、1.0.0+20130313144700、 1.0.0-beta+exp.sha.5114f85。

  11. 版本的優(yōu)先層級指的是不同版本在排序時如何比較。判斷優(yōu)先層級時,“必須 MUST”把版本依序拆分為主版本號、次版本號、修訂號及先行版本號后進行比較(版本編譯信息不在這份比較的列表中)。由左到右依序比較每個標識符號,第一個差異值用來決定優(yōu)先層級:主版本號、次版本號及修訂號以數(shù)值比較,例如1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。當(dāng)主版本號、次版本號及修訂號都相同時,改以優(yōu)先層級比較低的先行版本號決定。例如:1.0.0-alpha < 1.0.0。有相同主版本號、次版本號及修訂號的兩個先行版本號,其優(yōu)先層級“必須 MUST”透過由左到右的每個被句點分隔的標識符號來比較,直到找到一個差異值后決定:只有數(shù)字的標識符號以數(shù)值高低比較,有字母或連接號時則逐字以 ASCII 的排序來比較。數(shù)字的標識符號比非數(shù)字的標識符號優(yōu)先層級低。若開頭的標識符號都相同時,欄位比較多的先行版本號優(yōu)先層級比較高。范例:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0- rc.1 < 1.0.0。

為什么要使用語義化的版本控制?

這并不是一個新的或者革命性的想法。實際上,你可能已經(jīng)在做一些近似的事情了。問題在于只是“近似”還不夠。如果沒有某個正式的規(guī)范可循,版本號對于依賴的管理并無實質(zhì)意義。將上述的想法命名并給予清楚的定義,讓你對軟件使用者傳達意向變得容易。一旦這些意向變得清楚,彈性(但又不會太彈性)的依賴規(guī)范就能達成。

舉個簡單的例子就可以展示語義化的版本控制如何讓依賴地獄成為過去。假設(shè)有個名為“救火車”的函式庫,它需要另一個名為“梯子”并已經(jīng)有使用語義化版本控制的套件。當(dāng)救火車創(chuàng)建時,梯子的版本號為3.1.0。因為救火車使用了一些版本3.1.0 所新增的功能, 你可以放心地指定相依于梯子的版本號大等于3.1.0 但小于4.0.0。這樣,當(dāng)梯子版本3.1.1 和3.2.0 發(fā)布時,你可以將直接它們納入你的套件管理系統(tǒng),因為它們能與原有相依的軟件兼容。

作為一位負責(zé)任的開發(fā)者,你理當(dāng)確保每次套件升級的運作與版本號的表述一致。現(xiàn)實世界是復(fù)雜的,我們除了提高警覺外能做的不多。你所能做的就是讓語義化的版本控制為你提供一個健全的方式來發(fā)行以及升級套件,而無需推出新的相依套件,節(jié)省你的時間及煩惱。

如果你對此認同,希望立即開始使用語義化版本控制,你只需聲明你的函式庫正在使用它并遵循這些規(guī)則就可以了。請在你的README 文件中保留此頁連結(jié),讓別人也知道這些規(guī)則并從中受益。

參考資料

Semantic Versioning 2.0.0

命名規(guī)范

說到命名規(guī)范,個人認為包含了目錄,文件以及變量的命名。提前先說一句,命名規(guī)則沒有誰對誰錯,在項目中保持一致才是關(guān)鍵。

混亂或錯誤的命名不僅讓我們對代碼難以理解,更糟糕的是,會誤導(dǎo)我們的思維,導(dǎo)致對代碼的理解完全錯誤。相反,良好的命名,則可以讓我們的代碼非常容易讀懂,也能向讀者正確表達事物以及邏輯的本質(zhì),從而使得代碼的可維護性就大大增強,讀命名好的文章是非常流暢的,會有一種享受的感覺。

目錄

由于 Windows, OSX 下文件名不區(qū)分大小寫(linux 是區(qū)分的),所以命名我們建議還是以全部小寫為主,個人習(xí)慣連字符使用-中劃線。比如: my-project-name

項目中的子目錄一般按照作用,使用常用單詞表示,有復(fù)數(shù)的情況,使用復(fù)數(shù)命名法,比如: scripts, styles, imagesdata-modules

文件

文件的命名我個人也是推薦使用-中劃線進行連接。和目錄的連接字符保持一致。但是 linux 系統(tǒng)文件推薦的文件命名一般是下劃線。

變量

變量命名有兩種方式:

  • 下劃線命名法: my_variable
  • 駝峰式命名法: myVariale 當(dāng)然不同語言也是有不同的規(guī)范,網(wǎng)上也有很多大公司的命名規(guī)范可以參考。

JavaScript

變量推薦駝峰式命名法

CSS

推薦使用中劃線進行連接,CSS 語法本身就使用連字號作為連接(比如 font-family,text-align等)。

總結(jié)

良好的命名,以及良好的命名習(xí)慣,由于我們總是對每個概念的名稱要求非??量?,我們會思考這個名稱所表達的概念是否正確,該名稱是否正確表達了事物的本質(zhì)或正確反映了某個行為的邏輯。所以,這種對命名的良好思考習(xí)慣,可以反過來幫助我們糾正之前的一些錯誤設(shè)計和代碼實現(xiàn);比如,你之前有一個地方可能命名不太準確,然后你發(fā)現(xiàn)后面有另一個地方需要用這個名字,且更合理。所以你會發(fā)現(xiàn)這個名字對前面的地方就不適合了,從而你會去思考前面的地方可能需要用其他的名字,或者你會發(fā)現(xiàn)前面的地方的設(shè)計根本就是有問題的。這種就是名字可以促使你思考你的設(shè)計是否正確的例子。

參考資料

書寫文檔

一個程序員,最基本的是需要寫代碼,代碼之中其實就包含了注釋。如果是一個系統(tǒng)或者庫文件,其實還需要書寫文檔以配合。本文就交大家如何書寫文檔。

github 如何管理文檔

討論一下我們?nèi)绾问褂?Github Page 服務(wù)運行 Github 幫助文檔 (目前每月有上百萬的訪問量)的。

以前的流程

  • 用于托管維護網(wǎng)站、管理網(wǎng)站所用資源和文檔搜索增強的 Rails 應(yīng)用程序
  • 用戶托管由一大堆 Markdown 文件組成的網(wǎng)站具體內(nèi)容 我們正常的撰寫流程可能是這個樣子的:

  • 當(dāng)有新特征開發(fā)出來的時候文檔團隊首先編寫好文檔內(nèi)容
  • 創(chuàng)建一個新的 issue 去追蹤這個特征
  • 當(dāng)文檔更新完畢一切就緒之后,我們會發(fā)起一個 pull request 去迭代更新文檔內(nèi)容。
  • PR 發(fā)起成功后,我們會使用 @ 方式提醒團隊(比如 @github/docs )并會讓隊友們審查一下我們的內(nèi)容。
  • 當(dāng)這個特征開發(fā)完畢已經(jīng)上線的時候,我們會合并之前創(chuàng)建的 PR。 使用 webhook 能夠幫助我們在 內(nèi)容倉庫 快速激活我們部署的 Rails應(yīng)用程序。webhook 承擔(dān)了負責(zé)更新數(shù)據(jù)庫的任務(wù)。

新的流程

當(dāng) Jekyll 2.0 發(fā)布的時候,我們看到了曙光,是時候該把我們這套該死的流程換成純靜態(tài)站了!特別是新增加的 Collections 文檔類型能讓你定義你需要的文件結(jié)構(gòu)。另外,Jekyll 2.0 還增加了 Sass 和 CoffeeScript 的支持,這將使得編寫前端代碼變的更為簡單便捷。

參考資料

開源協(xié)議

參考資料

目錄結(jié)構(gòu)

不管大型還是小型項目,清晰的目錄結(jié)構(gòu)是開發(fā)過程的好的開始。以我常用的 web 項目為例,搭建一下目錄結(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)清晰是首要目標,至于命名只要能達到表意的目的即可。

src

此目錄專注于開發(fā),存放的都是源文件,不需要壓縮合并。目錄下主要分為:

  • css(styles): 樣式文件
  • js(scripts): 腳本文件
  • img(images): 圖片素材
  • font(fonts): 存放字體
  • 其他: 按照分類不同劃分目錄 文件名上面,簡寫的話都使用單數(shù)形式,全稱的話使用復(fù)數(shù)形式。

dist

此目錄為編譯生成目錄,用于部署環(huán)境,目錄結(jié)構(gòu)和 src 保持一致。

test

此目錄為測試目錄,存放和項目測試相關(guān)的文件。

doc

如果存在文檔說明,放置在此目錄下。

其他根目錄文件

根目錄下的其他文件,一般還有:

  • .editorconfig: 代碼樣式統(tǒng)一格式文件
  • .jscsrc:
  • .travis.yml:
  • .jshintrc: jshint配置文件
  • csscomb.json: csscomb配置文件
  • .gitignore: git忽略文件
  • .gitattributes: git屬性文件
  • .bowerrc
  • bower.json
  • package.json
  • gruntfile.js/gulpfile.js

參考資料

正則表達式

正則表達式,乍一看以為是很高升的東西,但是對于程序員而言,它真的應(yīng)該算是一個基礎(chǔ)知識。我們在很多場合下都需要使用到它,這個技術(shù)又是一個比較通用的東西,所以對于程序員而言,是大有益處的。

參考資料

平凡之路

名字起得文藝了一點,主要是想表達程序員的職業(yè)提升之路。

參考資料