面试中的那些 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 面试指南

相关文章
相关标签/搜索