git branch 分支

Git自学之路(四)- git branch 分支

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。 在很多版本控制系统中,这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说,这样的过程会耗费很多时间。

有人把 Git 的分支模型称为它的`‘必杀技特性’’,也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出。 Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。 理解和精通这一特性,你便会意识到 Git 是如此的强大而又独特,并且从此真正改变你的开发方式。

分支简介

Git 保存的不是文件的变化或者差异,而是一系列不同时刻的文件快照。

在进行提交操作时,Git 会保存一个提交对象(commit object)。知道了 Git 保存数据的方式,我们可以很自然的想到——该提交对象会包含一个指向暂存内容快照的指针。 但不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象,而由多个分支合并产生的提交对象有多个父对象。

Git 的分支,骑士分支上仅仅是指向提交对象的可变指针。 Git的默认分支名字是 master 。在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。它会在每次的提交操作中自动向前移动。

注意: Git的 “master” 分支并不是一个特殊分支。它就跟其他分支完全没有区别。之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它。

分支的创建

Git 创建新分支其实很简单,它只是为你创建了一个可以移动的新的指针。例如,创建一个 testing 分支,你需要用 git branch 命令:

$ git branch testing
  • 1

这会在当前所在的提交对象上创建一个指针。

那么,Git 是如何知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD 的特殊指针。 请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD 概念完全不同。 在 Git 中,它是一个指针,指向当前所在的本地分支将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅创建一个新分支,并不会自动切换到新分支中去。

你可以简单地使用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 –decorate。

$ git log --oneline --decorate
f30ab (HEAD, master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project
  • 1
  • 2
  • 3
  • 4

正如你所见,当前 “master” 和 “testing” 分支均指向校验和以 f30ab 开头的提交对象。

分支切换

要切换到一个已存在的分支,使用 git checkout 命令。现在我们切换到新创建的 testing 分支去:

$ git checkout testing
  • 1

这样 HEAD 就指向 testing 分支了。

那么,这样的实现方式会给我们带来什么好处呢?现在改动下在提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'
  • 1
  • 2

如图所示,你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。 这就有意思了,现在我们切换回 master 分支看看:

$ git checkout master
  • 1

这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。 也就是说,你现在做修改的话,项目将始于一个较旧的版本。 本质上来讲,这就是忽略 testing 分支所做的修改,以便于向另一个方向进行开发。

分支切换会改变你工作目录中的文件

在切换分支时,一定要注意你工作目录里的文件会被改变。 如果是切换到一个较旧的分支,你的工作目录会恢复到该分支最后一次提交时的样子。 如果 Git 不能干净利落地完成这个任务,它将禁止切换分支。

再稍微做些修改并提交:

$ vim test.rb
$ git commit -a -m 'made other changes'
  • 1
  • 2

现在,这个项目的提交历史已经产生了分叉。 因为刚才创建了一个新分支,并切换过去进行了一些工作,随后又切换回 master 分支进行了另外一些工作。 上述两次改动针对的是不同分支,你可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来。 而所有这些工作,你需要的命令只有 branch、checkout 和 commit。

在使用 git log 命令查看分叉历史。 运行 git log –oneline –decorate –graph –all ,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。 创建一个新分支就像是往一个文件中写入 41 个字节(40 个字符和 1 个换行符),如此的简单能不快吗?

这与过去大多数版本控制系统形成了鲜明的对比,它们在创建分支时,将所有的项目文件都复制一遍,并保存到一个特定的目录。 完成这样繁琐的过程通常需要好几秒钟,有时甚至需要好几分钟。所需时间的长短,完全取决于项目的规模。而在 Git 中,任何规模的项目都能在瞬间创建新分支。 同时,由于每次提交都会记录父对象,所以寻找恰当的合并基础(译注:即共同祖先)也是同样的简单和高效。 这些高效的特性使得 Git 鼓励开发人员频繁地创建和使用分支。

分支的新建与合并

新建分支

创建新分支可以使用 git branch 命令,但想要在新建一个分支并同时切换到那个分支上怎么办呢?可以运行一个带有 -b 参数的 git checkout 命令,如你现在的线上系统出现一个 #10 问题,你可以专为这个问题创建一个分支进行修复:

$ git checkout -b issue10
Switched to a new branch "issue10"
  • 1
  • 2

它是下面两条命令的简写:

$ git branch issue10
$ git checkout issue10
  • 1
  • 2

现在你就可以在 issue10 这个分支上进行你的修复工作而不影响 master 分支。在此过程中,issue10 分支会不断向前推进,因为你已经切换到该分支。当然在这个过程中你也可以切换回 master 分支中开发。

合并分支

当你在 issue10 分支中修复之后就需要合并到 master 分支了,首先应该切换到 master 分支,但是,在切换之前,要留意你的工作目录和暂存区里那些还没有被提交的修改,它可能会和你即将检出的分支产生冲突从而阻止 Git 切换到该分支。 最好的方法是,在你切换分支之前,保持好一个干净的状态。 有一些方法可以绕过这个问题(即,保存进度(stashing) 和 修补提交(commit amending))。 现在,我们假设你已经把你的修改全部提交了,这时你可以切换回 master 分支了:

$ git checkout master
  • 1

当你切换回 master 后就可以使用 git merge 命令进行分支的合并工作了:

$ git merge issue10
  • 1

执行上述命令后 Git 会很聪明的为你完成合并工作,Git 将此次合并的结果做一个新的快照并且自动创建一个新的提交指向它,一切就是这么简单。

遇到冲突时的分支合并

一个在聪明的人也会有出错的时候,Git 也一样,有时候合并操作并不会如此顺利。如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你在对 #10 问题的修改和在 master 的修改都涉及到同一个文件的同一处,在合并它们的时候就会产生合并冲突:

$ git merge issue10
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
  • 1
  • 2
  • 3
  • 4

此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。 你可以在合并冲突后的任意时刻使用 git status 命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件。

任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。 Git 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。 出现冲突的文件会包含一些特殊区段,看起来像下面这个样子:

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> issue10:index.html
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这表示 HEAD 所指示的版本(也就是你的 master 分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支)在这个区段的上半部分(======= 的上半部分),而 issue10 分支所指示的版本在 ======= 的下半部分。 为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内容。 例如,你可以通过把这段内容换成下面的样子来解决冲突:

<div id="footer">
please contact us at email.support@github.com
</div>
  • 1
  • 2
  • 3

上述的冲突解决方案仅保留了其中一个分支的修改,并且 <<<<<<< , ======= , 和 >>>>>>> 这些行被完全删除了。 在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决。

你可以再次运行 git status 来确认所有的合并冲突都已被解决,如果你对结果感到满意,并且确定之前有冲突的的文件都已经暂存了,这时你可以输入 git commit 来完成合并提交。

删除分支

既然分支 issue10 的修复已经完全合并到 master 分支了,你已不在需要 issue10 分支了,删除它并不会丢失任何东西。现在你可以使用带参数 -d 的 git branch 命令进行分支的删除工作:

$ git branch -d issue10
  • 1

分支管理

git branch 命令不只是可以创建与删除分支。 如果不加任何参数运行它,会得到当前所有分支的一个列表:

$ git branchiss53
* mastertesting
  • 1
  • 2
  • 3
  • 4

注意 master 分支前的 * 字符:它代表现在检出的那一个分支(也就是说,当前 HEAD 指针所指向的分支)。 这意味着如果在这时候提交,master 分支将会随着新的工作向前移动。 如果需要查看每一个分支的最后一次提交,可以运行 git branch -v 命令:

$ git branch -viss53   93b412c fix javascript issue
* master  7a98805 Merge branch 'iss53'testing 782fd34 add scott to the author list in the readmes
  • 1
  • 2
  • 3
  • 4

–merged 与 –no-merged 这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。

当包含了还未合并的工作的分支,尝试使用 git branch -d 命令删除它时会失败,如果真的想要删除分支并丢掉那些工作,可以使用 -D 选项强制删除它。

分支开发工作流

由于分支管理的便捷,因此衍生出一些典型的工作模式,可根据项目实际情况选择使用。

长期分支

因为 Git 使用简单的三方合并,所以就算在一段较长的时间内,反复把一个分支合并入另一个分支,也不是什么难事。 也就是说,在整个项目开发周期的不同阶段,你可以同时拥有多个开放的分支;你可以定期地把某些特性分支合并入其他分支中。

许多使用 Git 的开发者都喜欢使用这种方式来工作,比如只在 master 分支上保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。 他们还有一些名为 develop 或者 next 的平行分支,被用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master 分支了。 这样,在确保这些已完成的特性分支(短期分支,比如之前的 issue10 分支)能够通过所有测试,并且不会引入更多 bug 之后,就可以合并入主干分支中,等待下一次的发布。

一些大型项目还有一个 proposed(建议) 或 pu: proposed updates(建议更新)分支,它可能因包含一些不成熟的内容而不能进入 next 或者 master 分支。 这么做的目的是使你的分支具有不同级别的稳定性;当它们具有一定程度的稳定性后,再把它们合并入具有更高级别稳定性的分支中。 再次强调一下,使用多个长期分支的方法并非必要,但是这么做通常很有帮助,尤其是当你在一个非常庞大或者复杂的项目中工作时。

特性分支

特性分支对任何规模的项目都适用。 特性分支是一种短期分支,它被用来实现单一特性或其相关工作。 也许你从来没有在其他的版本控制系统(VCS)上这么做过,因为在那些版本控制系统中创建和合并分支通常很费劲。 然而,在 Git 中一天之内多次创建、使用、合并、删除分支都很常见。

你在自己的特性分支(如 iss53 和 hotfix 分支)中提交了一些更新,并且在它们合并入主干分支之后,你又删除了它们。 这项技术能使你快速并且完整地进行上下文切换(context-switch)——因为你的工作被分散到不同的流水线中,在不同的流水线中每个分支都仅与其目标特性相关,因此,在做代码审查之类的工作的时候就能更加容易地看出你做了哪些改动。 你可以把做出的改动在特性分支中保留几分钟、几天甚至几个月,等它们成熟之后再合并,而不用在乎它们建立的顺序或工作进度。

请牢记,当你做这么多操作的时候,这些分支全部都存于本地。 当你新建和合并分支的时候,所有这一切都只发生在你本地的 Git 版本库中 —— 没有与服务器发生交互。

远程分支

远程引用是对远程仓库的引用(指针),包括分支、标签等等。 可通过 git ls-remote (remote) 来显式地获得远程引用的完整列表,或者通过 git remote show (remote) 获得远程分支的更多信息。 然而,一个更常见的做法是利用远程跟踪分支。

远程跟踪分支是远程分支状态的引用。 它们是你不能移动的本地引用,当你做任何网络通信操作时,它们会自动移动。 远程跟踪分支像是你上次连接到远程仓库时,那些分支所处状态的书签。

它们以 (remote)/(branch) 形式命名。假设你的网络里有一个在 git.ourcompany.com 的 Git 服务器。 如果你从这里克隆,Git 的 clone 命令会为你自动将其命名为 origin,拉取它的所有数据,创建一个指向它的 master 分支的指针,并且在本地将其命名为 origin/master。 Git 也会给你一个与 origin 的 master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础。

“origin” 并无特殊含义 
远程仓库名字 “origin” 与分支名字 “master” 一样,在 Git 中并没有任何特别的含义一样。 同时 “master” 是当你运行 git init 时默认的起始分支名字,原因仅仅是它的广泛使用,“origin” 是当你运行 git clone 时默认的远程仓库名字。 如果你运行 git clone -o booyah,那么你默认的远程分支名字将会是 booyah/master。

推送分支到远程服务器

当你想要公开分享一个分支时,需要将其推送到有写入权限的远程仓库上。 本地的分支并不会自动与远程仓库同步 - 你必须显式地推送想要分享的分支。 这样,你就可以把不愿意分享的内容放到私人分支上,而将需要和别人协作的内容推送到公开分支。

如果希望和别人一起在名为 serverfix 的分支上工作,你可以像推送第一个分支那样推送它。 运行 git push (remote) (branch):

$ git push origin serverfix
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
Total 24 (delta 2), reused 0 (delta 0)
To https://github.com/schacon/simplegit* [new branch]      serverfix -> serverfix```Git 自动将 serverfix 分支名字展开为 refs/heads/serverfix:refs/heads/serverfix,那意味着,“推送本地的 serverfix 分支来更新远程仓库上的 serverfix 分支。”  下一次其他协作者从服务器上抓取数据时,他们会在本地生成一个远程分支 origin/serverfix,指向服务器的 serverfix 分支的引用:  ```git
$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit* [new branch]      serverfix    -> origin/serverfix<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

要特别注意的一点是当抓取到新的远程跟踪分支时,本地不会自动生成一份可编辑的副本(拷贝)。 换一句话说,这种情况下,不会有一个新的 serverfix 分支 - 只有一个不可以修改的 origin/serverfix 指针。

可以运行 git merge origin/serverfix 将这些工作合并到当前所在的分支。 如果想要在自己的 serverfix 分支上工作,可以将其建立在远程跟踪分支之上:

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这会给你一个用于工作的本地分支,并且起点位于 origin/serverfix。

跟踪分支

从一个远程跟踪分支检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。

当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支。 然而,如果你愿意的话可以设置其他的跟踪分支 - 其他远程仓库上的跟踪分支,或者不跟踪 master 分支。 可运行 git checkout -b [branch] [remotename]/[branch]。 这是一个十分常用的操作所以 Git 提供了 –track 快捷方式:

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

将本地分支与远程分支设置为不同名字:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

现在,本地分支 sf 会自动从 origin/serverfix 拉取。

设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支,你可以在任意时间使用 -u 或 –set-upstream-to 选项运行 git branch 来显式地设置。

$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

查看设置的所有跟踪分支,可以使用 git branch 的 -vv 选项。 这会将所有的本地分支列出来并且包含更多的信息,如每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有。

$ git branch -vviss53     7e424c3 [origin/iss53: ahead 2] forgot the bracketsmaster    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do ittesting   5ea463a trying something new<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里可以看到 iss53 分支正在跟踪 origin/iss53 并且 “ahead” 是 2,意味着本地有两个提交还没有推送到服务器上。 也能看到 master 分支正在跟踪 origin/master 分支并且是最新的。 接下来可以看到 serverfix 分支正在跟踪 teamone 服务器上的 server-fix-good 分支并且领先 2 落后 1,意味着服务器上有一次提交还没有合并入同时本地有三次提交还没有推送。 最后看到 testing 分支并没有跟踪任何远程分支。

需要重点注意的一点是这些数字的值来自于你从每个服务器上最后一次抓取的数据。 这个命令并没有连接服务器,它只会告诉你关于本地缓存的服务器数据。 如果想要统计最新的领先与落后数字,需要在运行此命令前抓取所有的远程仓库。 可以像这样做:$ git fetch –all; git branch -vv

拉取

当 git fetch 命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。 然而,有一个命令叫作 git pull 在大多数情况下它的含义是一个 git fetch 紧接着一个 git merge 命令。 如果有一个像之前章节中演示的设置好的跟踪分支,不管它是显式地设置还是通过 clone 或 checkout 命令为你创建的,git pull 都会查找当前分支所跟踪的服务器与分支,从服务器上抓取数据然后尝试合并入那个远程分支。

由于 git pull 的魔法经常令人困惑所以通常单独显式地使用 fetch 与 merge 命令会更好一些。

删除远程分支

假设你已经通过远程分支做完所有的工作了 - 也就是说你和你的协作者已经完成了一个特性并且将其合并到了远程仓库的 master 分支(或任何其他稳定代码分支)。 可以运行带有 –delete 选项的 git push 命令来删除一个远程分支。 如果想要从服务器上删除 serverfix 分支,运行下面的命令:

git 
$ git push origin --delete serverfix 
To https://github.com/schacon/simplegit 
- [deleted] serverfix 

基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。

至此,你现在应该能自如地创建并切换至新分支、在不同分支之间切换以及合并本地分支,你现在应该也能通过推送你的分支至共享服务以分享它们、使用共享分支与他人协作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/451390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件工程师的十个“不职业”行为

职业化是软件工程师的必然选择。本文根据我在教学和软件开发管理方面的实践&#xff0c;列举几个软件工程师“不职业”的行为或习惯&#xff0c;从另外一个侧面进一步探讨什么是真正的软件工程师职业化。职业化之于软件工程师非常重要。因为&#xff1a;软件是看不见也摸不着的…

fn:substring()函数

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 fn:substring()函数返回字符串中指定开始和结束索引的子串。 语法 fn:substring()函数的语法如下&#xff1a; ${fn:substring(<s…

大数据分析如何创建最佳的移动应用用户体验

2019独角兽企业重金招聘Python工程师标准>>> 如今&#xff0c;越来越多的人使用移动应用程序。而移动应用将在未来成为一个价值数十亿美元的产业。大数据可以帮助企业构建最佳的用户体验。 多年来&#xff0c;开发移动应用程序的技术一直在不断发展&#xff0c;这实…

C语言自学的方法

一、C语言入门的基本学习方法 《C语言》的内容很丰富&#xff0c;有的部分涉及到的细节很多&#xff0c;如硬件知识和数据结构知识等&#xff0c;自学时不可能面面俱到&#xff0c;否则必然会顾此失彼&#xff0c;反而抓不住主要矛盾。笔者认为对初学C语言的考生&#xff0c;开…

CAP原理简单理解

C&#xff1a;集群中所有机器状态是一致的。 A&#xff1a;客户端访问集群中任意一个节点&#xff0c;总能得到"处理成功"的结果。 假设有五个节点&#xff1a;n1~n5 &#xff0c;出现网络分区被分成两组&#xff1a;[n1~n2]和[n3~n5]&#xff0c;那么当n1出来客户端…

Jstorm+Spring+mybatis整合

在现有的jstorm框架下&#xff0c;有一个需求&#xff1a;jstorm要对接mysql数据库的实时读取数据&#xff0c; 通过bolt处理&#xff0c;可能要调用service层的框架&#xff0c;最后保存到数据库。 在网上寻找了一下&#xff0c;发现storm集成spring的资料非常少&#xff0c;有…

无限享受百度文库,财富值无视

相信大家在百度上找东西时&#xff0c;遇到有的文库需要财富值&#xff0c;可是自己又没有&#xff0c;是不是很头疼啊。请看&#xff1a; 找到自己要的文库&#xff0c;如我找的文库链接为&#xff1a;http://wenku.baidu.com/view/7db6 ... html?l5.1.5.1&&#xff08;…

JavaScript onerror 事件( window.onerror = )

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 使用 onerror 事件是一种老式的标准的在网页中捕获 Javascript 错误的方法。 实例 onerror 事件 如何使用 onerror 事件捕获网页中的错误…

上海云栖:金融政企行业的CDN最佳实践

2019独角兽企业重金招聘Python工程师标准>>> 摘要&#xff1a; 在刚刚结束的上海云栖大会飞天技术汇分论坛上&#xff0c;阿里云视频云产品架构师罗小飞进行了《阿里云CDN——面向金融政企的CDN最佳实践》主题分享&#xff0c;为上海的嘉宾介绍CDN的解决方案与技术服…

lunix基本命令

安装lunix 批量创建文件 whoami查看当前用户 sudo adduser lilei创建用户 groups lilei 查看用户所属用户组 sudo usermod -G root lilei 赋予root权限 sudo deluser lilei --remove-home ls -l 显示目录的文件 ls -a 显示隐藏文件 PWD 获取当前目录 cd .. 返回上层目录 cd 进入…

开启Swarm集群以及可视化管理

为什么80%的码农都做不了架构师&#xff1f;>>> 在搭建的两台coreos服务器上开启swarm集群 前置条件&#xff1a; docker均开启2375端口同一个局域网内主服务器上安装Portainer容器安装Portainer容器执行&#xff1a; docker run -d -p 9000:9000 --restartalways …

python基本语法:序列

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 序列的基本操作&#xff1a; 2.用例&#xff1a; 3.序列包含字符串、元组、列表。

移动互联网开始降温:“人才热”退烧

去年的疯狂抢人变成了今年的裁员甚至关门歇业&#xff0c;漫天要价变成了工作难找&#xff0c;移动互联网市场正回归理性 工作不好找了。 “去年这个时候&#xff0c;一个刚毕业的Android开发工程师&#xff0c;就能轻松拿到七八千一个月&#xff0c;而今年&#xff0c;很难找到…

MAP存储数据

map可以装多种类型的值&#xff0c;当然键不能重复&#xff0c;值可以重复。可以使用多种类型的父类&#xff0c;来指定值的类型。比如Object是其他类的父类。例如&#xff1a;HashMap<Object,Object>&#xff0c;它的键和值都可以存储多种类型&#xff0c;反正都是Objec…

IMDb、烂番茄、MTC、各种电影行业评分名字整理

这篇不是技术文章&#xff0c;就是对总是看到但是不知道具体是什么的一些电影名词、评分、来源&#xff0c;学习一下。 IMDb 互联网电影资料库&#xff08;Internet Movie Database&#xff0c;简称IMDb&#xff09;是一个关于电影演员、电影、电视节目、电视明星和电影制作的在…

iOS应用:成功就像中彩票,大半开发者亏本

移动是座大金矿&#xff0c;从来都不乏一飞冲天的成功故事&#xff08;Draw Something、愤怒的小鸟等&#xff09;。但是大家往往只看到光鲜的一面&#xff0c;对于移动开发者来说&#xff0c;现实是残酷的&#xff0c;根据市场营销机构App Promo的一项调查&#xff0c;绝大多数…

python基本语法:元组

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 元组说明&#xff1a; 元组和列表类似&#xff0c;只不过元组和字符串一样是不可变的&#xff0c;即你不能修改元组。 元组通过圆括…

docker安装nginx容器小记

前言: 使用docker安装了nginx容器&#xff0c;很久才成功跑起来&#xff0c;对安装过程做下记录 linux系统&#xff1a;centos7.4 docker安装不阐述&#xff0c;直接记录安装创建nginx容器的过程 1. 拉取nginx的镜像&#xff0c;此处拉取的最新版 docker pull nginx2. 创建ngin…

long==int

int 与 long 进行比较时&#xff0c;int 会自动进行隐式的类型转换&#xff0c;将int提升为 long 类型。

Mybatis 拦截器介绍

Mybatis 拦截器介绍1.1 目录1.2 前言1.3 Interceptor接口1.4 注册拦截器1.5 Mybatis可拦截的方法1.6 利用拦截器进行分页拦截器的一个作用就是我们可以拦截某些方法的调用&#xff0c;我们可以选择在这些被拦截的方法执行前后加上某些逻辑&#xff0c;也可以在执行这些被拦截的…