面試中的那些 Git 問題 - 基礎部分

團隊協做能力一直是咱們招聘開發人員的重要考覈指標之一。而考覈這個能力的緣由很簡單:通常公司都不會只有一個開發…而一旦涉及多人協做開發,良好的協做能力和習慣能顯著提升整個團隊的開發效率。Time is money!ios

說到協做,面試中固然就會聊到開發人員平常最須要協做的事情,代碼協做。由於 Github 在國內的流行,不少公司都已經把代碼託管到 Github 或者內部的 git 服務上,因此你們也慢慢把 git 技能的考察引入到面試中。git

下面就分享一些筆者我的整理的 git 相關問題以及解析。面試

基礎部分

平時都用什麼 git 工具?

除了 git 自帶的命令行工具,作爲 iOS 開發,接觸最多的固然是 Xcode 自帶的 Source Control 功能,可是這兩個工具都有一些本身的不足。swift

  • Xcode:Xcode 自己本身是支持 git 的,可是它有一個特別坑的點的:那就是卡…並且文件越大越卡,甚至會 Crash。因此對於 .pbxproj 這種大文件的衝突,Xcode 基本是蒙圈狀態的,另外它提供的 git 支持也有些單薄。安全

  • 命令行:只能說十個裏面九個菜,還有一個是大神,雖然命令行提供了所有的功能,可是不少用 GUI 工具能夠很便捷解決的問題,命令行作起來都比較麻煩。固然並非讓你們不要去命令行,經過命令行能夠對 git 的功能和原理有一個更深刻的瞭解。app

由於這些不足,因此咱們一般會用一些第三方 GUI 工具來提升咱們 git 倉庫管理的效率:svn

  • SourceTree:筆者平常使用的一個圖形化的 git 加強工具,而最好用的功能就在於它集成了 GitFlow,讓開發者能夠更簡單、更規範的去作一些 git 操做;另外它還提供了更友好的 merge 界面,可是操做起來不是很順手,由於它只支持整行刪除;工具

  • SmartGit測試

  • Tower:Tower 被譽爲 Mac 平臺最好的 git 客戶端。軟件大大簡化了 git 的使用難度,用戶能夠經過拖拽完成操做,更方便、更高效。須要注意的是,30 天后還想使用全特性的話,須要 $60。atom

  • Atom:Atom 自己並非專門用來作 git 管理的工具,而是一個支持多種開發語言的開源 IDE。提到它的緣由是 merge-conflicts, 這個插件提供的 merge 界面,要比 SourceTree 的更好用,Atom 會在當前內容的基礎上,把有衝突的部分直接對比標示出來,開發人員能夠像編輯普通文本同樣在標示的區域內直接進行修改,並最終選擇本身滿意的那個部分做爲 merge 以後的內容。

考察關鍵點:
  • 對本身所用 git 工具的瞭解程度;
  • 主觀能動性,是否能主動找方法解決目前工做中的痛點。
回答關鍵點:

不要只說你用什麼。而是要分析優劣勢。爲何用哪一個工具?爲何不用哪一個工具?

git add 和 git stage 有什麼區別

在回答這個問題以前須要先了解 git 倉庫的三個組成部分:工做區(Working Directory)、暫存區(Stage)和歷史記錄區(History):

  • 工做區:在 git 管理下的正常目錄都算是工做區,咱們平時的編輯工做都是在工做區完成。
  • 暫存區:臨時區域。裏面存放將要提交文件的快照。
  • 歷史記錄區:git commit 後的記錄區。

而後是這三個區的轉換關係以及轉換所使用的命令:

而後咱們就能夠來講一下 git add 和 git stage 了。其實,他們兩是同義的,因此,驚不驚喜,意不意外?這個問題居然是個陷阱…引入 git stage 的緣由其實比較有趣:是由於要跟 svn add 區分,二者的功能是徹底不同的,svn add 是將某個文件加入版本控制,而 git add 則是把某個文件加入暫存區,由於在 git 出來以前你們用 svn 比較多,因此爲了不誤導,git 引入了git stage,而後把 git diff --staged 作爲 git diff --cached 的相同命令。基於這個緣由,咱們建議使用 git stage 以及 git diff --staged。

考察關鍵點:
  • 對 git 工做區(Working Directory)、暫存區(Stage)和歷史記錄區(History)以及轉換關係的瞭解;
  • 對 git add 和 git stage 的瞭解。
回答關鍵點:
  • 工做區(Working Directory)、暫存區(Stage)和歷史記錄區(History)以及轉換關係不能少;
  • git stage 是 git add 的同義指令;
  • 我用 git stage。

git reset、git revert 和 git checkout 有什麼區別

這個問題一樣也須要先了解 git 倉庫的三個組成部分:工做區(Working Directory)、暫存區(Stage)和歷史記錄區(History)。

首先是它們的共同點:用來撤銷代碼倉庫中的某些更改。

而後是不一樣點:

首先,從 commit 層面來講:

  • git reset 能夠將一個分支的末端指向以前的一個 commit。而後再下次 git 執行垃圾回收的時候,會把這個 commit 以後的 commit 都扔掉。git reset 還支持三種標記,用來標記 reset 指令影響的範圍:

    • --mixed:會影響到暫存區和歷史記錄區。也是默認選項;
    • --soft:隻影響歷史記錄區;
    • --hard:影響工做區、暫存區和歷史記錄區。

    注意:由於 git reset 是直接刪除 commit 記錄,從而會影響到其餘開發人員的分支,因此不要在公共分支(好比 develop)作這個操做。

  • git checkout 能夠將 HEAD 移到一個新的分支,並更新工做目錄。由於可能會覆蓋本地的修改,因此執行這個指令以前,你須要 stash 或者 commit 暫存區和工做區的更改。

  • git revert 和 git reset 的目的是同樣的,可是作法不一樣,它會以建立新的 commit 的方式來撤銷 commit,這樣能保留以前的 commit 歷史,比較安全。另外,一樣由於可能會覆蓋本地的修改,因此執行這個指令以前,你須要 stash 或者 commit 暫存區和工做區的更改。

而後,從文件層面來講:

  • git reset 只是把文件從歷史記錄區拿到暫存區,不影響工做區的內容,並且不支持 --mixed、--soft 和 --hard。
  • git checkout 則是把文件從歷史記錄拿到工做區,不影響暫存區的內容。
  • git revert 不支持文件層面的操做。
回答關鍵點:
  • 對於 commit 層面和文件層面,這三個指令自己功能差異很大。
  • git revert 不支持文件層面的操做。
  • 不要在公共分支作 git reset 操做。

GitFlow 基本流程和你的理解

GitFlow 是由 Vincent Driessen 提出的一個 git操做流程標準。包含以下幾個關鍵分支:

名稱 說明
master 主分支
develop 主開發分支,包含肯定即將發佈的代碼
feature 新功能分支,通常一個新功能對應一個分支,對於功能的拆分須要比較合理,以免一些後面沒必要要的代碼衝突
release 發佈分支,發佈時候用的分支,通常測試時候發現的 bug 在這個分支進行修復
hotfix hotfix 分支,緊急修 bug 的時候用

GitFlow 的優點有以下幾點:

  • 並行開發:GitFlow 能夠很方便的實現並行開發:每一個新功能都會創建一個新的 feature 分支,從而和已經完成的功能隔離開來,並且只有在新功能完成開發的狀況下,其對應的 feature 分支纔會合併到主開發分支上(也就是咱們常常說的 develop 分支)。另外,若是你正在開發某個功能,同時又有一個新的功能須要開發,你只須要提交當前 feature 的代碼,而後建立另一個 feature 分支並完成新功能開發。而後再切回以前的 feature 分支便可繼續完成以前功能的開發。
  • 協做開發:GitFlow 還支持多人協同開發,由於每一個 feature 分支上改動的代碼都只是爲了讓某個新的 feature 能夠獨立運行。同時咱們也很容易知道每一個人都在幹啥。
  • 發佈階段:當一個新 feature 開發完成的時候,它會被合併到 develop 分支,這個分支主要用來暫時保存那些尚未發佈的內容,因此若是須要再開發新的 feature,咱們只須要從 develop 分支建立新分支,便可包含全部已經完成的 feature
  • 支持緊急修復:GitFlow 還包含了 hotfix 分支。這種類型的分支是從某個已經發布的 tag 上建立出來並作一個緊急的修復,並且這個緊急修復隻影響這個已經發布的 tag,而不會影響到你正在開發的新 feature

而後就是 GitFlow 最經典的幾張流程圖,必定要理解:

feature 分支都是從 develop 分支建立,完成後再合併到 develop 分支上,等待發布。

當須要發佈時,咱們從 develop 分支建立一個 release 分支

而後這個 release 分支會發布到測試環境進行測試,若是發現問題就在這個分支直接進行修復。在全部問題修復以前,咱們會不停的重複發佈->測試->修復->從新發布->從新測試這個流程。

發佈結束後,這個 release 分支會合併到 developmaster 分支,從而保證不會有代碼丟失。

master 分支只跟蹤已經發布的代碼,合併到 master 上的 commit 只能來自 release 分支和 hotfix 分支。

hotfix 分支的做用是緊急修復一些 Bug。

它們都是從 master 分支上的某個 tag 創建,修復結束後再合併到 developmaster 分支上。

考察關鍵點
  • GitFlow 包含的分支類型和功能;
  • GitFlow 的優點;
  • 對 GitFlow feature、release、hotfix 流程的理解。
回答關鍵點
  • GitFlow 的基本內容以及優點;
  • 對於 feature 流程,都是從 develop 分支發起,而後經過 PR/MR 的方式合併回 develop 分支;
  • 對於 release 流程,則是要注意幾點:
    • 若是 release 分支上有 bug 須要修復,直接在 release 分支上完成;
    • release 分支上的 bug 修復要持續經過 PR/MR 的方式合併回 develop 分支;
    • 最後確認發版的時候才把 release 分支直接合併到 master 分支。
  • 對於 hotfix 流程,則是要注意幾點:
    • 從 master 分支發起;
    • 修復完要同時合併到 develop 和 master。

解釋下 PR 和 MR 的區別

PR 和 MR 的全稱分別是 pull request 和 merge request。解釋它們二者的區別以前,咱們須要先了解一下 Code Review,由於 PR 和 MR 的引入正是爲了進行 Code Review。

Code Review 是指在開發過程當中,對代碼的系統性檢查。一般的目的是查找系統缺陷,保證代碼質量和提升開發者自身水平。 Code Review 是輕量級代碼評審,相對於正式代碼評審,輕量級代碼評審所須要的各類成本要明顯低的多,若是流程正確,它能夠起到更加積極的效果。

進行 Code Review 的緣由:

  • 提升代碼質量
  • 及早發現潛在缺陷與BUG,下降事故成本。
  • 促進團隊內部知識共享,提升團隊總體水平
  • 評審過程對於評審人員來講,也是一種思路重構的過程,幫助更多的人理解系統。

而後咱們須要瞭解下 fork 和 branch,由於這是 PR 和 MR 各自所屬的協做流程。

fork 是 git 上的一個協做流程。通俗來講就是把別人的倉庫備份到本身倉庫,修修改改,而後再把修改的東西提交給對方審覈,對方贊成後,就能夠實現幫別人改代碼的小目標了。fork 包含了兩個流程:

  • fork 並更新某個倉庫

  • 同步 fork

和 fork 不一樣,branch 並不涉及其餘的倉庫,操做都在當前倉庫完成。

因此 PR 和 MR 的最大區別就在於此。

考察關鍵點:
  • Code review;
  • PR 和 MR 所屬流程的細節。
回答關鍵點:

回答這個問題的時候不要單單隻說它們的區別。而是要從 PR 和 MR 產生的緣由,分析它們所屬的流程,而後再得出二者的區別。

進階部分

進階部分請移步:iOS 面試指南

相關文章
相關標籤/搜索