[Git](https://www.git-scm.com/book/zh/v2)是一款開源的分布式版本控制系統,它的出現和Linux緊密相關。Linux內核項目組為了能更好地管理和維護Linux內核開發,于2002年開始啟用商業的分布式版本控制系統BitKeeper。雖然軟件開發商授權了Linux社區能免費使用,但是好景不長,到了2005年,BitKeeper的開發商由于某些原因終止了與Linux社區的合作關系。于是Linux的作者Linus Torvalds就決定開發一款能替代BitKeeper的分布式版本控制系統(即Git),在花費十天的時間后發布了Git的第一個版本。
## 一、版本控制系統
  版本控制系統(Version Control System,VCS)能管理文件內容的變更記錄,即可追蹤文件的修訂歷史,確保不同的人在編輯同一文件時能保持同步。該系統不僅能應用于保存源碼的文本文件,還能對圖像、Word文檔等各種類型的文件進行版本控制。有了版本控制系統之后,就能很方便的回退文件到某個狀態、比較文件變更前后的區別、查詢到修改文件的人等。目前市面上的版本控制系統大致可分為兩種:集中式和分布式,下面會對它們做單獨的講解。
**1)集中式**
  當需要多人協同工作時,就得讓集中式版本控制系統(Centralized Version Control Systems,CVCS)登場了。
  這類系統包括CVS、Subversion等都是在一臺中央服務器中建立一個倉庫,專門用來管理文件的修訂版本,客戶端可通過網絡連接到這臺服務器,取出最新文件或提交變更,如圖3所示。
:-: 
圖3 集中式版本控制系統
  雖然使用CVCS帶來了諸多便利,但是其缺點也很明顯,例如中央服務器一旦宕機,那么客戶端將無法提交變更和協同工作;或者中央服務器磁盤故障,沒有備份倉庫,那么將丟失所有的變更記錄。
**2)分布式**
  為了解決CVCS所帶來的問題,又有人提出了分布式版本控制系統(Distributed Version Control System,DVCS)。
  這類系統包括Git、BitKeeper等都會將服務器中的倉庫完整的克隆到本地,這么一來,即使網絡斷開,也能繼續工作,并且受服務器故障的影響也能降低到最小。在圖4中,服務器和兩臺電腦三者之間都能相互推送各自的修訂記錄,并且每臺電腦上都保存了一個本地倉庫。
:-: 
圖4 分布式版本控制系統
  由此可知,DVCS剝奪了服務器的生殺大權,只讓它負責中轉大家的修訂記錄,即使缺了服務器,也不影響協同工作。
## 二、快照
  Git不會像CVS、Subversion等版本控制系統那樣存儲每個文件所變更的內容以及修訂文件版本之間的關系。Git更像是一個文件系統,它存儲的是文件快照(Snapshot)。
  Git會先將那些變更的文件拷貝一份,然后把備份文件轉換成Blob對象,并對其進行壓縮,再把文件各自的內容通過SHA-1哈希運算出對應Blob的名稱(即版本號),如下所示,最后由這些哈希值作為索引組成一個快照(即版本信息),而通過快照就能反推出該版本中所有發生變更的文件內容。
~~~
fbcceef922ce47253804cf00c72c2e955b8bc1b3
~~~
  每次提交都會生成一個新的快照,而對于未更改的文件,則直接鏈接到上一個版本。
## 三、工作區域
  Git的工作區域包含三部分:工作目錄、暫存區和倉庫,它們的說明如下所列:
  (1)工作目錄(Working Directory)就是去除項目版本信息后的目錄,即磁盤上實際操作的目錄。
  (2)暫存區(Stage)也叫索引區(Index),是一個記錄了變更信息的文件,即保存著變更文件的當前快照,為提交到倉庫中做準備。
  (3)倉庫(Repository)也叫版本庫,是一個名為.git的隱藏目錄,保存著項目的元數據、快照等信息,Git的倉庫可分為遠程和本地兩種。
**1)工作流程**
  在圖5中,通過工作區域的三部分描繪出了Git基本的工作流程,簡單的將其分為四步,并給出了相應的Git命令。
:-: 
圖5 Git的工作流程
  首先在工作目錄中修改源文件,然后用add命令將變更記錄保存到暫存區,再用commit命令將暫存區中的文件提交給本地倉庫,最后用push命令將本地倉庫的信息推送給遠程倉庫。圖中的云朵表示網絡,因為一般遠程倉庫都會被托管在某臺服務器中,需要通過網絡將本地信息傳送過去。
**2)三種狀態**
  Git中的文件有多種狀態,此處列出其中的三種:已修改(modified)、已暫存(staged)和已提交(committed)。
  (1)已修改是還未提交的變更文件。
  (2)已暫存是記錄在當前快照中的變更文件。
  (3)已提交是保存在本地倉庫中的變更文件。
## 四、常用命令
  本節將列舉出Git常用的命令,包括創建倉庫、提交更新、查看信息等。
**1)創建倉庫**
  如果要在當前目錄中創建倉庫,那么可以用下面的初始化命令。
~~~
git init
~~~
  在執行該命令后,就會生成名為.git的隱藏目錄。
**2)克隆倉庫**
  GitHub是一個提供Git倉庫托管服務的網站,如果要在本機獲取網站中已經存在的倉庫,那么可以使用克隆命令,如下所示。注意,這兩條命令的效果是相同的,因為Git支持HTTPS和SSH兩種數據傳輸協議。
~~~
git clone https://github.com/pwstrick/demo.git
git clone git@github.com:pwstrick/demo.git
~~~
  在執行該命令后,就會創建一個名為demo的目錄。默認情況下,遠程倉庫中的每個文件的每個版本都會被拉取下來。
**3)提交更新**
  工作目錄中的文件可分為兩大類:已跟蹤(tracked)和未跟蹤(untracked)。已跟蹤的文件是指已經被納入版本控制的文件,它們的狀態可以是已修改、已暫存或已提交;而未跟蹤的文件正好與之相反,并且不會被記錄在之前的快照中。當初始化工作目錄時,其中的文件都是未跟蹤的;而當克隆倉庫時,其中的文件都是已跟蹤的。
  使用add命令,開始跟蹤文件,其后面跟的參數既可以是文件路徑,也可以是目錄路徑,下面命令中的點號表示跟蹤當前目錄中的所有文件。
~~~
git add .
~~~
  在執行add命令后,工作目錄中新增或變更的文件就會被記錄在暫存區,并且確定了下次提交時的快照內容。
  當暫存區已準備完畢可以提交時,就能執行commit命令了,如下所示,其中“-m”參數能為此次提交添加備注說明,注意,得用引號包裹。
~~~
git commit -m "add files"
~~~
  commit命令能為本地倉庫創建一個持久快照,其內容來自于暫存區的臨時快照。commit命令還有一個“-a”參數,可以讓已經跟蹤過的文件直接到暫存區,然后一并提交給本地倉庫,從而就能跳過add命令,如果要與“-m”一起使用,可以像下面這樣。
~~~
git commit -am "add files"
~~~
  當然,對于未跟蹤的文件,無法省略add命令,仍然得執行。
**4)忽略文件**
  在工作目錄中創建一個名為.gitignore的文件,列出要忽略的匹配模式(如下所示),就能讓Git不再管理相關的文件或目錄,例如忽略日志、編譯生成的臨時文件、Node.js的安裝目錄等。
~~~
# system
*.docx
node_modules/
~~~
  第一行相當于注釋,第二行是告訴Git忽略后綴為“.docx”的文件,第三行是忽略node\_modules目錄。.gitignore文件支持[Glob](https://rgb-24bit.github.io/blog/2018/glob.html)模式匹配(即簡化過的正則表達式),另外還有一些格式規范:
  (1)所有空行或以“#”開頭的行都會被Git忽略。
  (2)匹配模式能以“/”開頭防止遞歸。
  (3)匹配模式能以“/”結尾指定目錄。
  (4)只要在模式前加上“!”取反,就能忽略該模式以外的文件或目錄。
**5)刪除文件**
  Git提供了rm命令,可刪除工作目錄中的指定文件,并且能消除它在暫存區中的記錄,如下所示。
~~~
git rm demo.txt
~~~
  rm命令的后面既可以跟文件或目錄的名稱,也能跟Glob模式的正則表達式,例如像下面這樣刪除后綴為“.log”的文件。
~~~
git rm *.log
~~~
  結合commit命令就能將刪除的操作告知本地倉庫。
**6)撤銷操作**
  如果要撤銷工作目錄中的文件變更,可以使用checkout命令,如下所示,撤銷了demo.txt文件中的變更。注意,命令中的“--”不能省略,否則就會執行切換分支的操作。
~~~
git checkout -- demo.txt
~~~
  如果要撤銷暫存區中的文件變更,可以使用reset命令,如下所示,其中HEAD是一個指針,指向當前分支,通過它能得到該分支上最后一次提交的快照。
~~~
git reset HEAD demo.txt
~~~
  注意,上述兩種撤銷都是在commit命令之前執行的。有些情況下的撤銷需要依次執行上面兩條命令才能完成,例如demo.txt修改了多次,并且執行了多次“git add .”命令,然后要撤銷所有的更改。
**7)回退版本**
  如果要實現版本回退,那么首先得知道版本號,而通過log命令就能獲取到當前分支的歷史版本,如下所示,包括版本號、作者、備注等信息。
~~~
$ git log
commit 00ef86de2fe382c5e1a9185a182a35bbbd34c0fd
Author: strick <pwstrick@163.com>
Date: Tue Jul 2 14:26:31 2019 +0800
test
commit 9a701365eeb47cf876c726cf5e321af5ce9cabbf
Author: strick <pwstrick@163.com>
Date: Tue Jul 2 14:13:19 2019 +0800
add demo.txt
~~~
  現在就能通過reset命令,指定版本號,實現回退,如下所示。由于HEAD指針的存在,Git的版本回退其實就是移動指向,因此其速度是非常快的。
~~~
git reset --hard 9a701365eeb47cf876c726cf5e321af5ce9cabbf
~~~
**8)查看信息**
  在Git中用于查看信息的命令包括log、status、diff和reflog等,其中log命令已在前文介紹過,用來查看提交的版本歷史,按提交時間倒序排列。接下來會先修改demo.txt文件,然后再執行相關的查看命令,其中命令可選擇的參數由于篇幅原因都沒有給出。
  status命令用來查看工作目錄的狀態,顯示變更信息以及提示可用命令,如下所示。
~~~
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: demo.txt
no changes added to commit (use "git add" and/or "git commit -a")
~~~
  diff命令用來查看工作目錄和暫存區之間的差異,如下所示,其中a和b表示的是同一個文件的不同版本。
~~~
$ git diff
diff --git a/demo.txt b/demo.txt
index d28d40b..30d74d2 100644
--- a/demo.txt
+++ b/demo.txt
@@ -1 +1 @@
-add
\ No newline at end of file
+test
\ No newline at end of file
~~~
  diff命令還能比較暫存區和本地倉庫、兩次commit提交、文件修改前后等之間的差異。
  reflog命令用來查看當前分支的所有操作記錄,包括commit、reset、pull等,如下所示。
~~~
e1ce188 HEAD@{0}: pull origin master: Fast-forward
9a70136 HEAD@{1}: reset: moving to 9a701365eeb47cf876c726cf5e321af5ce9cabbf
......
fb8e5df HEAD@{13}: commit: demo
f1f30d6 HEAD@{14}: clone: from https://github.com/pwstrick/demo.git
~~~
**9)遠程倉庫**
  與遠程倉庫相關的命令有remote、fetch、pull和push,其中remote可與其它命令(例如add、show、rename等)配合實現擴展功能。
  remote命令可列出所有遠程倉庫的簡稱,在執行克隆命令時,Git會默認為其添加一個名為origin的遠程倉庫。如果為remote命令添加“-v”參數,那么會顯示遠程倉庫的簡稱和其讀寫的URL。
~~~
$ git remote -v
origin https://github.com/pwstrick/demo.git (fetch)
origin https://github.com/pwstrick/demo.git (push)
~~~
  fetch命令可從遠程倉庫中拉取本地沒有的數據,例如缺失的分支。
  pull命令可抓取遠程分支的最新變更,并將其自動合并到當前分支中,在pull后面會緊跟遠程倉庫的簡稱和分支名稱,如下所示。
~~~
git pull origin master
~~~
  push命令可將本地快照、變更的文件等信息推送到遠程倉庫中,其格式與pull命令類似,如下所示。
~~~
git push origin master
~~~
## 五、分支
  Git之所以能高性能的處理分支,主要得益于其與眾不同的存儲設計:棄文件變化,取文件快照。每次commit提交,Git都會創建一個提交對象(Commit Object),該對象包含本次快照的指針、父對象的指針(即上一個提交對象)、當前工作目錄的結構和相關附屬信息(例如作者、備注等),注意,首次提交產生的提交對象沒有父對象。
  Git的分支本質上就是指向提交對象的可變指針,其默認分支叫master,如圖6所示,用圓代表提交對象,圓內的字符串表示版本號的前5位。
:-: 
圖6 分支和其提交歷史
**1)創建**
  創建分支其實就是新建一個新的可移動指針,如果要創建一條develop分支,那么執行的命令可以像下面這樣。
~~~
git branch develop
~~~
  現在就會變成兩條分支,如圖7所示。
:-: 
圖7 兩條分支
  執行“git branch”命令能夠查看已有的分支,在當前分支的名稱前會加“\*”標記,如下所示。
~~~
$ git branch
develop
* master
~~~
**2)切換**
  在Git中,有一個特殊的HEAD指針,之前曾提到過它能指向當前分支,相當于當前分支的別名,如圖8所示。
:-: 
圖8 HEAD指向當前分支
  切換分支其實就是改變HEAD的指向,例如切換到develop分支,其命令如下所示,內部操作如圖9所示。
~~~
git checkout develop
~~~
:-: 
圖9 切換分支
  有一條快捷命令,可以創建一個分支并自動切換到那個分支,如下所示,給checkout命令添加了“-b”參數。
~~~
git checkout -b develop
~~~
**3)合并**
  有了分支后,就能在各自的分支工作,并且互不干擾,例如在develop分支提交了一個版本,如圖10所示,develop分支向前移動了,而master分支仍在原地。
:-: 
圖10 HEAD自動向前移動
  現在用“git checkout master”命令將分支切換回master,HEAD會指向master分支,并且工作目錄將恢復成master分支中的快照。如果要將develop分支中的變更記錄合并(Merge)到master分支中,那么可以使用merge命令,如下所示。
~~~
$ git merge develop
Updating 9a9636b..64ea4b2
Fast-forward
demo.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
~~~
  注意上面的Fast-forward,說明這次合并使用了快進模式,即直接將指針向前移動。舉例來說,當前開發處在develop分支,在提交一系列變更后,切換到master分支,而master分支沒有提交新的變更,此時將develop分支合并到master分支就會采用快進模式。
**4)沖突**
  如果兩個分支對同一文件的同一行都做了不同的修改,那么在合并時就會發生沖突(Conflict),如下所示,都修改了demo.txt文件的第一行。
~~~
$ git merge develop
Auto-merging demo.txt
CONFLICT (content): Merge conflict in demo.txt
Automatic merge failed; fix conflicts and then commit the result.
~~~
  此時,Git就會停止工作,等待沖突的解決。使用status命令可以查看所有沖突的文件,如下所示。
~~~
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: demo.txt
no changes added to commit (use "git add" and/or "git commit -a")
~~~
  查看demo.txt文件,可以看到下面的特殊區段。
~~~
<<<<<<< HEAD
test
=======
minus
>>>>>>> develop
~~~
  Git用>>>>>>標記出不同分支的變更,其中上半部分是HEAD所指的master分支,下半部分是develop分支。要解決沖突,就得手動去掉Git生成的多余字符,以及保留其中一個分支的修改,在完成這一系列的操作后,demo.txt文件中的內容就會變成下面這樣。
~~~
minus
~~~
  現在只要將沖突文件的變更保存到暫存區(如下所示),就能將它們標記成已解決,繼續下面的工作了。
~~~
git add .
git commit -am "conflict"
~~~
  當沖突的文件特別多時,一個個的查找難免會費時費力,改用Git客戶端工具會便捷很多,例如TortoiseGit,它不僅能列出沖突的文件,還能提供圖11中的可視化編輯界面。
:-: 
圖11 TortoiseGit沖突解決
**5)遠程**
  之前通過push命令將本地分支的信息推送到了遠程倉庫中(如下所示),與此同時,如果沒有遠程的同名分支,那么Git會自動為其創建一個,并且還會為它們兩個建立跟蹤關系。
~~~
git push origin master
~~~
  利用branch命令可在本地查看遠程倉庫(如下所示),分支會以“遠程倉庫/分支名稱”的形式顯示,例如origin/master。
~~~
$ git branch -r
origin/develop
origin/master
~~~
  如果當前分支與遠程分支存在跟蹤關系,那么在push或pull時可省略分支名稱,如下所示。
~~~
git pull origin
git push origin
~~~
  Git允許手動建立跟蹤關系,只要為branch命令添加“-u”或“--set-upstream-to”參數即可(如下所示),從而就能讓一個本地分支跟蹤多個遠程分支。
~~~
$ git branch -u origin/strick
Branch develop set up to track remote branch strick from origin.
~~~
  如果當前分支只有一個可跟蹤的遠程分支,那么在push或pull時連倉庫名稱都能省略,如下所示。
~~~
git pull
git push
~~~
**6)刪除**
  如果要刪除分支,那么有兩條命令可供選擇,下面的第一條可刪除本地分支,第二條可刪除遠程分支,本質上它們做的只是移除相應的指針。
~~~
git branch -d develop
git push origin --delete develop
~~~
**7)變基**
  變基(Rebase)能將一條分支上的變更轉移到另一條分支上,以圖12中的master和develop兩條分支為例。
:-: 
圖12 變基前的兩條分支
  假設當前分支是develop,變基的目標分支是master,執行rebase命令后的分支情況如圖13所示。
:-: 
圖13 變基后的兩條分支
  接下來會通過一個例子來講解變基的用法,首先通過log命令查看master分支的提交歷史,如下所示,其中“number”是修改demo.txt文件時所提交的備注。
~~~
$ git log
commit 7c27be31904221f3bb4556ca39dd7c8dea071178
Author: strick <pwstrick@163.com>
Date: Wed Jul 3 17:48:47 2019 +0800
number
~~~
  然后切換到develop分支,并執行rebase命令,如下所示。注意,變基目標是master而不是develop。
~~~
$ git checkout develop
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: digit
Using index info to reconstruct a base tree...
M demo.txt
Falling back to patching base and 3-way merge...
Auto-merging demo.txt
CONFLICT (content): Merge conflict in demo.txt
Failed to merge in the changes.
Patch failed at 0001 digit
The copy of the patch that failed is found in:
D:/demo/.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
~~~
  由于兩條分支同時修改了demo.txt文件中的內容,因此產生了沖突,必須先將其解決,才能繼續后面的操作。注意,develop分支的修改記錄先于master分支提交。
  當解決了所有沖突之后,先執行add命令,注意,此時不需要commit命令。然后再為rebase命令添加“--continue”(如下所示),就能完成變基,其中“digit”也是修改demo.txt文件時所提交的備注。
~~~
$ git add .
$ git rebase --continue
Applying: digit
~~~
  接著切換回master分支,并將develop分支中的修改合并進來,注意,此時開啟了快進模式。
~~~
$ git checkout master
$ git merge develop
Updating 7c27be3..24c4b5a
Fast-forward
demo.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
~~~
  最后執行log命令,就能看到develop分支所提交的版本添加到了master分支的后面,注意,它沒有根據提交時間按順序插入。
~~~
$ git log
commit 24c4b5adb332f8c4f2e5ec39a7c77e0fc224b065
Author: strick <pwstrick@163.com>
Date: Wed Jul 3 17:48:00 2019 +0800
digit
commit 7c27be31904221f3bb4556ca39dd7c8dea071178
Author: strick <pwstrick@163.com>
Date: Wed Jul 3 17:48:47 2019 +0800
number
~~~
  變基的一大特點就是能將分叉的提交歷史梳理成一條直線,另一個特點是它會改變提交歷史,這與合并完全不同。變基還有一條基本原則,即只對尚未推送和分享給他人的本地修改允許執行變基操作。
*****
> 原文出處:
[博客園-前端利器躬行記](https://www.cnblogs.com/strick/category/1472499.html)
[知乎專欄-前端利器躬行記](https://zhuanlan.zhihu.com/pwtool)
已建立一個微信前端交流群,如要進群,請先加微信號freedom20180706或掃描下面的二維碼,請求中需注明“看云加群”,在通過請求后就會把你拉進來。還搜集整理了一套[面試資料](https://github.com/pwstrick/daily),歡迎瀏覽。

推薦一款前端監控腳本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不僅能監控前端的錯誤、通信、打印等行為,還能計算各類性能參數,包括 FMP、LCP、FP 等。
- ES6
- 1、let和const
- 2、擴展運算符和剩余參數
- 3、解構
- 4、模板字面量
- 5、對象字面量的擴展
- 6、Symbol
- 7、代碼模塊化
- 8、數字
- 9、字符串
- 10、正則表達式
- 11、對象
- 12、數組
- 13、類型化數組
- 14、函數
- 15、箭頭函數和尾調用優化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、類
- 21、類的繼承
- 22、Promise
- 23、Promise的靜態方法和應用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基礎實踐
- 3、WebRTC視頻通話
- 4、Web音視頻基礎
- CSS進階
- 1、CSS基礎拾遺
- 2、偽類和偽元素
- 3、CSS屬性拾遺
- 4、浮動形狀
- 5、漸變
- 6、濾鏡
- 7、合成
- 8、裁剪和遮罩
- 9、網格布局
- 10、CSS方法論
- 11、管理后臺響應式改造
- React
- 1、函數式編程
- 2、JSX
- 3、組件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表單
- 8、樣式
- 9、組件通信
- 10、高階組件
- 11、Redux基礎
- 12、Redux中間件
- 13、React Router
- 14、測試框架
- 15、React Hooks
- 16、React源碼分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基礎
- 4、webpack進階
- 5、Git
- 6、Fiddler
- 7、自制腳手架
- 8、VSCode插件研發
- 9、WebView中的頁面調試方法
- Vue.js
- 1、數據綁定
- 2、指令
- 3、樣式和表單
- 4、組件
- 5、組件通信
- 6、內容分發
- 7、渲染函數和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、數據類型
- 2、接口
- 3、類
- 4、泛型
- 5、類型兼容性
- 6、高級類型
- 7、命名空間
- 8、裝飾器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系統和網絡
- 3、命令行工具
- 4、自建前端監控系統
- 5、定時任務的調試
- 6、自制短鏈系統
- 7、定時任務的進化史
- 8、通用接口
- 9、微前端實踐
- 10、接口日志查詢
- 11、E2E測試
- 12、BFF
- 13、MySQL歸檔
- 14、壓力測試
- 15、活動規則引擎
- 16、活動配置化
- 17、UmiJS版本升級
- 18、半吊子的可視化搭建系統
- 19、KOA源碼分析(上)
- 20、KOA源碼分析(下)
- 21、花10分鐘入門Node.js
- 22、Node環境升級日志
- 23、Worker threads
- 24、低代碼
- 25、Web自動化測試
- 26、接口攔截和頁面回放實驗
- 27、接口管理
- 28、Cypress自動化測試實踐
- 29、基于Electron的開播助手
- Node.js精進
- 1、模塊化
- 2、異步編程
- 3、流
- 4、事件觸發器
- 5、HTTP
- 6、文件
- 7、日志
- 8、錯誤處理
- 9、性能監控(上)
- 10、性能監控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 監控系統
- 1、SDK
- 2、存儲和分析
- 3、性能監控
- 4、內存泄漏
- 5、小程序
- 6、較長的白屏時間
- 7、頁面奔潰
- 8、shin-monitor源碼分析
- 前端性能精進
- 1、優化方法論之測量
- 2、優化方法論之分析
- 3、瀏覽器之圖像
- 4、瀏覽器之呈現
- 5、瀏覽器之JavaScript
- 6、網絡
- 7、構建
- 前端體驗優化
- 1、概述
- 2、基建
- 3、后端
- 4、數據
- 5、后臺
- Web優化
- 1、CSS優化
- 2、JavaScript優化
- 3、圖像和網絡
- 4、用戶體驗和工具
- 5、網站優化
- 6、優化閉環實踐
- 數據結構與算法
- 1、鏈表
- 2、棧、隊列、散列表和位運算
- 3、二叉樹
- 4、二分查找
- 5、回溯算法
- 6、貪心算法
- 7、分治算法
- 8、動態規劃
- 程序員之路
- 大學
- 2011年
- 2012年
- 2013年
- 2014年
- 項目反思
- 前端基礎學習分享
- 2015年
- 再一次項目反思
- 然并卵
- PC網站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端學習之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 2024年
- 日志
- 2020