01.06 讓程序員淚流滿面的 11 個 Git 面試題,到底有多難?


在今年的 Stack Overflow 開發者調查報告中,超過 70% 的開發者使用 Git,使其成為世界上使用人數最多的版本控制系統。Git 通常用於開源和商業軟件開發,對個人、團隊和企業都頗有益處。

Q1: 什麼是 Git 復刻(fork)?復刻(fork)、分支(branch)和克隆(clone)之間有什麼區別?

主題:Git 難度:⭐⭐

  • 復刻(fork) 是對存儲倉庫(repository)進行的遠程的、服務器端的拷貝,從源頭上就有所區別。復刻實際上不是 Git 的範疇。它更像是個政治/社會概念。
  • 克隆(clone) 不是復刻,克隆是個對某個遠程倉庫的本地拷貝。克隆時,實際上是拷貝整個源存儲倉庫,包括所有歷史記錄和分支。
  • 分支(branch) 是一種機制,用於處理單一存儲倉庫中的變更,並最終目的是用於與其他部分代碼合併。

Q2: “拉取請求(pull request)”和“分支(branch)”之間有什麼區別?

主題:Git 難度:⭐⭐

  • 分支(branch) 是代碼的一個獨立版本。
  • 拉取請求(pull request) 是當有人用倉庫,建立了自己的分支,做了些修改併合併到該分支(把自己修改應用到別人的代碼倉庫)

Q3: “git pull”和“git fetch”之間有什麼區別?

主題:Git 難度:⭐⭐

簡單來說,git pull 是 git fetch + git merge。

  • 當你使用 pull,Git 會試著自動為你完成工作。它是上下文(工作環境)敏感的,所以 Git 會把所有拉取的提交合併到你當前處理的分支中。pull 則是 自動合併提交而沒有讓你複查的過程。如果你沒有細心管理你的分支,你可能會頻繁遇到衝突。
  • 當你 fetch,Git 會收集目標分支中的所有不存在的提交,並將這些提交存儲到本地倉庫中。但Git 不會把這些提交合併到當前分支中。這種處理邏輯在當你需要保持倉庫更新,在更新文件時又希望處理可能中斷的事情時,這將非常實用。而將提交合併到主分支中,則該使用 merge。

Q4: 如在 Git 恢復先前的提交?

主題:Git 難度:⭐⭐⭐

假設你的情形是這樣,其中 C 是你的 HEAD,(F) 是你文件的狀態。

(F)

A-B-C

master


要修改提交中的更改:

git reset --hard HEAD~1


現在 B 是 HEAD,因為你使用了 --hard,所以你的文件將重置到提交 B 時的狀態。

要撤銷提交但保留更改:

git reset HEAD~1


現在我們告訴 Git 將 HEAD 指針移回(後移)一個提交(B),並保留文件原樣,然後你可以 git status 來顯示你已經檢入 C 的更改。

撤銷提交但保留文件和索引:

git reset --soft HEAD~1


執行此操作後,git status,你講看到索引中的文件跟以前一致。
Q5: 什麼是“git cherry-pick”?

主題:Git 難度:⭐⭐⭐

命令 git cherry-pick 通常用於把特定提交從存儲倉庫的一個分支引入到其他分支中。常見的用途是從維護的分支到開發分支進行向前或回滾提交。

這與其他操作(例如:合併(merge)、變基(rebase))形成鮮明對比,後者通常是把許多提交應用到其他分支中。

小結:

git cherry-pick <commit-hash>


Q6: 解釋 Forking 工作流程的優點

主題:Git 難度:⭐⭐⭐

Forking 工作流程 與其他流行的 Git 工作流程有著根本的區別。它不是用單個服務端倉庫充當“中央”代碼庫,而是為每個開發者提供自己的服務端倉庫。Forking 工作流程最常用於公共開源項目中。

Forking 工作流程的主要優點是可以彙集提交貢獻,又無需每個開發者提交到一箇中央倉庫中,從而實現乾淨的項目歷史記錄。開發者可以推送(push)代碼到自己的服務端倉庫,而只有項目維護人員才能直接推送(push)代碼到官方倉庫中。

當開發者準備發佈本地提交時,他們的提交會推送到自己的公共倉庫中,而不是官方倉庫。然後他們向主倉庫提交請求拉取(pull request),這會告知項目維護人員有可以集成的更新。

Q7: 告訴我 Git 中 HEAD、工作樹和索引之間的區別?

主題:Git 難度:⭐⭐⭐

  • 該工作樹/工作目錄/工作空間是你看到和編輯的(源)文件的目錄樹。
  • 該索引/中轉區(staging area)是個在 /.git/index,單一的、龐大的二進制文件,該文件列出了當前分支中所有文件的 SHA1 檢驗和、時間戳和文件名,它不是個帶有文件副本的目錄。
  • HEAD是當前檢出分支的最後一次提交的引用/指針。

Q8: 你能解釋下 Gitflow 工作流程嗎?

主題:Git 難度:⭐⭐⭐

Gitflow 工作流程使用兩個並行的、長期運行的分支來記錄項目的歷史記錄,分別是 master 和 develop 分支。

  • Master,隨時準備發佈線上版本的分支,其所有內容都是經過全面測試和核準的(生產就緒)。
    • Hotfix,維護(maintenance)或修復(hotfix)分支是用於給快速給生產版本修復打補丁的。修復(hotfix)分支很像發佈(release)分支和功能(feature)分支,除非它們是基於 master 而不是 develop 分支。
  • Develop,是合併所有功能(feature)分支,並執行所有測試的分支。只有當所有內容都經過徹底檢查和修復後,才能合併到 master 分支。
    • Feature,每個功能都應留在自己的分支中開發,可以推送到 develop 分支作為功能(feature)分支的父分支。
讓程序員淚流滿面的 11 個 Git 面試題,到底有多難?

Q9: 什麼時候應使用 “git stash”?

主題:Git 難度:⭐⭐⭐

git stash 命令把你未提交的修改(已暫存(staged)和未暫存的(unstaged))保存以供後續使用,以後就可以從工作副本中進行還原。

回顧:

$ git status

On branch master

Changes to be committed:

new file: style.css

Changes not staged for commit:

modified: index.html

$ git stash

Saved working directory and index state WIP on master: 5002d47 our new homepage

HEAD is now at 5002d47 our new homepage

$ git status

On branch master

nothing to commit, working tree clean


我們可以使用暫存(stash)的一個地方是,如果我們發現在上次提交中忘記了某些內容,並且已經開始在同一分支中處理下一個提交了:

# Assume the latest commit was already done

# start working on the next patch, and discovered I was missing something

# stash away the current mess I made

$ git stash save

# some changes in the working dir

# and now add them to the last commit:

$ git add -u

$ git commit --ammend

# back to work!

$ git stash pop


Q10: 如何從 git 中刪除文件,而不將其從文件系統中刪除?

主題:Git 難度:⭐⭐⭐⭐

如果你在 git add 過程中誤操作,你最終會添加不想提交的文件。但是,git rm 則會把你的文件從你暫存區(索引)和文件系統(工作樹)中刪除,這可能不是你想要的。

換成 git reset 操作:

git reset filename # or

echo filename >> .gitingore # add it to .gitignore to avoid re-adding it


上面意思是,git reset <paths> 是 git add <paths> 的逆操作。/<paths>/<paths>

Q11: 是麼時候使用“git rebase”代替“git merge”?

主題:Git 難度:⭐⭐⭐⭐⭐

這兩個命令都是把修改從一個分支集成到另一個分支上,它們只是以非常不同的方式進行。

考慮一下場景,在合併和變基前:

A

^

\\

D


在 git merge master 之後:

A

^ ^

\\ \\

D


在 git rebase master 之後:

A


使用變基時,意味著使用另一個分支作為集成修改的新基礎。

何時使用:

  1. 如果你對修改不夠果斷,請使用合併操作。
  2. 根據你希望的歷史記錄的樣子,而選擇使用變基或合併操作。

更多需要考慮的因素:

  1. 分支是否與團隊外部的開發人員共享修改(如開源、公開項目)?如果是這樣,請不要使用變基操作。變基會破壞分支,除非他們使用 git pull --rebase,否則這些開發人員將會得到損壞的或不一致的倉庫。
  2. 你的開發團隊技術是否足夠嫻熟?變基是一種破壞性操作。這意味著,如果你沒有正確使用它,你可能會丟失提交,並且/或者會破壞其他開發者倉庫的一致性。
  3. 分支本身是否代表有用的信息?一些團隊使用功能分支(branch-per-feature)模式,每個分支代表一個功能(或錯誤修復,或子功能等)。在此模式中,分支有助於識別相關提交的集合。在每個開發人員分支(branch-per-developer)模式中,分支本身不會傳達任何其他信息(提交信息已有作者)。則在這種模式下,變基不會有任何破壞。
  4. 是否無論如何都要還原合併?恢復(如在撤銷中)變基,是相當困難的,並且/或者在變基中存在衝突時,是不可能完成的。如果你考慮到日後可能需要恢復,請使用合併操作。

讀者福利:

本人這邊專門整理了一套對應的Java面經pdf文檔複習資料,含全面的java知識點面試題,還有其他各類知識點的整理,特別適合一些即將面試或準備跳槽的Java開發者查缺補漏,需要獲取這套文檔資料的讀者朋友們可以關注小編,後臺私信關鍵字“面試資料”獲取這套Java面經pdf文檔資料


讓程序員淚流滿面的 11 個 Git 面試題,到底有多難?


分享到:


相關文章: