当前位置: 首页 > news >正文

Git 分支管理与多人协作实战指南

目录

1.分支管理:

1.1.理解分支:

1.2.创建分支

1.3.切换分支

1.4.合并分支

1.5.删除分支

2.合并冲突

3.分支管理策略

分支策略

4.bug分支

5.删除临时分支

git branch -d 和 git branch -D的区别

6.多人协作

6.1.多人协作一

6.2.多人协作二

1.分支管理:

1.1.理解分支:

本章开始介绍 Git 的杀手级功能:分支。

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习 C++的时候,另一个你正在另一个平行宇宙里努力学习 JAVA。
如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并
了,结果,你既学会了 C++ 又学会了 JAVA!

在版本回退里,你已经知道,每次提交,Git都把它们串成一条时间线,这条时间线就可以理解为是一个分支。

截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即 master分支。
再来理解一下HEAD,HEAD 严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD 指向的就是当前分支。

每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长,而HEAD只要一直指向master分支即可指向当前分支。

1.2.创建分支

Git 支持我们查看或创建其他分支,在这里我们来创建第一个自己的分支 dev ,对应的命令为:

git branch #查看当前本地所有分⽀
* master
git branch dev #新建分⽀dev
git branch
dev
* master

当我们创建新的分支后,Git新建了⼀个指针叫dev, * 表示当前 HEAD 指向的分支是 master 分分支。

一张图总结:

1.3.切换分支

那如何切换到 dev 分支下进行开发呢?使用git checkout 命令即可完成切换,示例如下:

git checkout dev
Switched to branch 'dev'
git branch
* devmaster

我们发现 HEAD 已经指向了 dev,就表示我们已经成功的切换到了 dev 上!
接下来,在 dev 分支下修改 ReadMe 文件,新增一行内容,并进行一次提交操作。

我们观察到的现象如下:

当切回master分支之后,我们就会发现在master分支上ReadMe文件并没有做任何改变!再切换回dev分支后发现文件内容改变了,这是为什么呢?

因为我们是在dev分支上提交的,而master分支此刻的提交点并没有变,此时的状态如图如下所示。

当切换到 master 分支之时,HEAD 就指向了 master,当然看不到提交了!

1.4.合并分支

为了在 master 主分支上能看到新的提交,就需要将 dev 分支合并到 master 分支,示例如下!

git branch 
* devmaster
git checkout master # 切换到 master 上进⾏合并
Switched to branch 'master'
git merge dev # 合并 dev 分⽀ 
Updating 16623e1..3740dce
Fast-forwardReadMe | 1 +1 file changed, 1 insertion(+)

git merge dev

git merge 命令用于合并指定分支到当前分支。合并后,master 就能看到 dev分支提交的内容
了。此时的状态如图如下所示。

Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。
当然,也不是每次合并都能 Fast-forward,我们后面会讲其他方式的合并。

1.5.删除分支

合并完成后,dev分支对于我们来说就没用了,那么dev分支就可以被删除掉,注意如果当前正处于某分支下,就不能删除当前分支,如:

hyb@139-159-150-152:~/gitcode$ git branch
* devmaster
hyb@139-159-150-152:~/gitcode$ git branch -d dev 
error: Cannot delete branch 'dev' checked out at '/home/hyb/gitcode'

而可以在其他分支下删除当前分支,如:

hyb@139-159-150-152:~/gitcode$ git checkout master 
Switched to branch 'master'
hyb@139-159-150-152:~/gitcode$ git branch -d dev 
Deleted branch dev (was bdaf528).
hyb@139-159-150-152:~/gitcode$ git branch
* master

此时的状态图如下:

合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和
因为创建、直接在master分支上工作效果是一样的,但过程更安全。

2.合并冲突

可是,在实际分支合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。
为了演示这问题,创建一个新的分支 dev1 ,并切换至目标分支,我们可以使用 git checkout -b dev 一步完成创建并切换的动作

在 dev1 分支下修改 ReadMe文件,更改文件内容如下,并进行⼀次提交,如:

hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch # 将 aaa 该为 bbb
hyb@139-159-150-152:~/gitcode$ git add .
hyb@139-159-150-152:~/gitcode$ git commit -m"modify ReadMe"
[dev1 0854245] modify ReadMe1 file changed, 1 insertion(+), 1 deletion(-)

切换至master分支,并观察文件的内容

hyb@139-159-150-152:~/gitcode$ git checkout master 
Switched to branch 'master'
hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write aaa for new branch

我们发现,切回来之后,文件内容由变成了老的版本,这种现象很正常,我们现在也完全能理解。
此时在 master分支上,我们对 ReadMe文件再进行一次修改,并进行提交,如下:

hyb@139-159-150-152:~/gitcode$ git branch dev1
* master
hyb@139-159-150-152:~/gitcode$ vim ReadMe 
hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write ccc for new branch 
hyb@139-159-150-152:~/gitcode$ git add .
hyb@139-159-150-152:~/gitcode$ git commit -m"modify ReadMe"
[master c10f6d0] modify ReadMe1 file changed, 1 insertion(+), 1 deletion(-)

现在, master分支和 dev1 分支各自都分别有新的提交,图示变成了这样:

这种情况下,Git 只能试图把各自的修改合并起来,但这种合并就可能会有冲突,如下所示:

hyb@139-159-150-152:~/gitcode$ git merge dev1 
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
hyb@139-159-150-152:~/gitcode$ git status
On branch master
You have unmerged paths.(fix conflicts and run "git commit")(use "git merge --abort" to abort the merge)
Unmerged paths:(use "git add <file>..." to mark resolution)both modified: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")

发现 ReadMe 文件有冲突后,可以直接查看文件内容,要说的是 Git 会⽤ <<<<<< , ======,  >>>>>> 来标记出不同分支的冲突内容,如下所⽰:

hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
<<<<<<< HEAD
write ccc for new branch 
=======
write bbb for new branch 
>>>>>>> dev1

此时我们必须要手动调整冲突代码,并需要再次提交修正后的结果!!
(再次提交很重要,切勿忘记 !)

到这里冲突就解决完成,此时的状态变成了

最后不要忘记了dev分支使用完毕了,直接删除。

3.分支管理策略

通常合并分支时,如果可能,Git会采用 Fast forward 模式。还记得如果我们采用 Fast forward 模式之后,形成的合并结果是什么呢?回顾一下

在这种 Fast forward 模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来最新提
交到底是 merge 进来的还是正常提交的。
但在合并冲突部分,我们也看到通过解决冲突问题,会再进行一次新的提交,得到的最终状态为:

那么这就不是 Fast forward 模式了,这样的好处是,从分支历史上就可以看出分支信息。例如我
们现在已经删除了在合并冲突部分创建的 dev1 分支,但依旧能看到 master 其实是由其他分支合并得到的:

hyb@139-159-150-152:~/gitcode$ git log --graph --pretty=oneline --abbrev-commit
* 2976afc (HEAD -> master) merge ReadMe
|\ 
| * c594fd1 modify ReadMe
* | c10f6d0 modify ReadMe
|/ 

Git 支持我们强制禁用 Fast forward 模式,那么就会在 merge 时生成一个新的 commit ,这样
从分支历史上就可以看出分支信息。
下面我们实战-下 --no-ff 方式的 git merge 。

git merge --no-ff -m "merge with no-ff" dev2

hyb@139-159-150-152:~/gitcode$ git checkout master 
Switched to branch 'master'
hyb@139-159-150-152:~/gitcode$ git merge --no-ff -m "merge with no-ff" dev2
Merge made by the 'recursive' strategy.ReadMe | 1 +1 file changed, 1 insertion(+)

请注意 --no-ff 参数,表示禁用 Fast forward 模式。禁用 Fast forward 模式后合并会创建一个新的 commit ,所以加上 -m 参数,把描述写进去。

可以看到,不使用 Fast forward 模式,merge后就像这样:

所以在合并分支时,加上 --no-ff 参数就可以用普通模式合并,合并后的历史有分支,能看出来曾 经做过合并,而 fast forward 合并就看不出来曾经做过合并。

分支策略

在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:

4.bug分支

假如我们现在正在 dev2 分支上进行开发,开发到一半,突然发现 master 分支上面有 bug,需要
解决。在Git中,每个 bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
可现在 dev2 的代码在工作区中开发了一半,还无法提交,怎么办?例如:

为什么无法提交呢?

如果当前分支有数据没有提交的话,是切换不了分支的。

你的工作区有未提交的更改。如果你此时切换分支(例如切换到 master 分支来修复 bug),Git 会阻止你切换分支,因为这些未提交的更改可能会与目标分支的文件冲突.

hyb@139-159-150-152:~/gitcode$ git branch 
* dev2master
hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d
i am coding ...
hyb@139-159-150-152:~/gitcode$ git status
On branch dev2
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")

Git提供了 git stash 命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来。

git stash注意需要在dev分支下进行.

用 git status 查看工作区,就是干净的(除非有没有被 Git 管理的文件),因此可以放心地创建分
支来修复bug。
储藏 dev2 工作区之后,由于我们要基于master分支修复 bug,所以需要切回 master 分支,再新
建临时分支来修复 bug,示例如下:

hyb@139-159-150-152:~/gitcode$ git checkout master # 切回master
Switched to branch 'master'
hyb@139-159-150-152:~/gitcode$ git checkout -b fix_bug # 新建并切换到 fix_bug 分
⽀
Switched to a new branch 'fix_bug'
hyb@139-159-150-152:~/gitcode$ vim ReadMe 
hyb@139-159-150-152:~/gitcode$ cat ReadMe 
hello bit
hello git
hello world
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e # 修复bug--忘记写e
hyb@139-159-150-152:~/gitcode$ git add ReadMe # 重新add,commit
hyb@139-159-150-152:~/gitcode$ git commit -m"fix bug"
[fix_bug 4bbc0c4] fix bug1 file changed, 1 insertion(+), 1 deletion(-)

修复完成后,切换到 master 分支,并完成合并,最后删除 fix_bug 分支:

⾄此,bug的修复⼯作已经做完了,我们还要继续回到dev2 分⽀进⾏开发。切换回 dev2 分支:

⼯作区是⼲净的,刚才的⼯作现场存到哪去了?⽤ git stash list 命令看看:

hyb@139-159-150-152:~/gitcode$ git stash list
stash@{0}: WIP on dev2: 41b082f modify ReadMe

⼯作现场还在,Git把stash内容存在某个地⽅了,但是需要恢复⼀下,如何恢复现场呢?我们可以使 ⽤ git stash pop 命令,恢复的同时会把stash也删了,⽰例如下:

hyb@139-159-150-152:~/gitcode$ git stash pop
On branch dev2
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: ReadMe
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (4f873250b3503687b5efd26196776aee7e3724c2)

再次查看的时候,我们就发现没有现场可以恢复了

另外,恢复现场也可以采用 git stash apply 恢复,但是恢复后,stash内容并不删除,你需要
用 git stash drop 来删除;

恢复完代码之后我们便可以继续完成开发,开发完成后便可以进行提交。

但我们注意到了,修复 bug 的内容,并没有在 dev2 上显示。此时的状态图为:

Master 分支目前最新的提交,是要领先于新建 dev2 时基于的 master 分支的提交的,所以我们
在 dev2 中当然看不见修复 bug 的相关代码。
我们的最终目的是要让 master 合并 dev2 分支的,那么正常情况下我们切回 master 分支直接合
并即可,但这样其实是有一定风险的。
是因为在合并分支时可能会有冲突,而代码冲突需要我们手动解决(在 master 上解决)。我们无法
保证对于冲突问题可以正确地一次性解决掉,因为在实际的项目中,代码冲突不只一两行那么简单,有可能几十上百行,甚至更多,解决的过程中难免手误出错,导致错误的代码被合并到 master 上。
此时的状态为:

解决这个问题的一个好的建议就是:最好在自己的分支上合并下 master ,再让 master 去合并
dev ,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master 。此时的状态
为,

5.删除临时分支

软件开发中,总有无穷无尽的新的功能要不断添加进来。
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个分支,我们可以将其称之为 feature 分支,在上面开发,完成后,合并,最
后,删除该 feature 分支。
可是,如果我们今天正在某个 feature 分支上开发了一半,被产品经理突然叫停,说是要停止新功
能的开发。虽然白干了,但是这个 feature 分支还是必须就地销毁,留着无用了。这时使用传统
的 git branch -d 命令删除分支的方法是不行的。

git branch -d 和 git branch -D的区别

  • 使用 git branch -d <branch-name> 时,Git 会检查分支的合并状态,如果分支尚未合并,则拒绝删除并给出警告。
  • 使用 git branch -D <branch-name> 时,Git 不会检查分支的合并状态,会直接强制删除分支。

因此,在删除分支之前,最好确认该分支的合并状态,以避免意外丢失尚未合并的工作。如果不确定分支的合并状态,可以先使用 git merge 命令合并分支,或者使用 git branch -vv 查看分支的详细信息。

6.多人协作

目前,我们所完成的工作如下:

  • 基本完成 Git 的所有本地库的相关操作,git基本操作,分支理解,版本回退,冲突解决等等
  • 申请码云账号,将远端信息clone到本地,以及推送和拉取。

是时候干最重要的一件事情了,实现多人协作开发!

6.1.多人协作一

这里我们的情况是多人在同一条分支上进行协作。

总结一下,在同一分支下进行多人协作的工作模式通常是这样:

  • 首先,可以试图用 git push origin branch-name 推送自己的修改;
  • 如果推送失败,则因为远程分支比你的本地更新,需要先用 git pull 试图合并;
  • 如果合并有冲突,则解决冲突,并在本地提交;
  • 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!
  • 功能开发完毕,将分支 merge 进 master,最后删除分支。

我们使用git pull命令将远程的dev分支拉取到本地的分支,但本地分支不能直接对这个远程的dev分支进行操作,因此还需要使用git checkout -b dev origin/dev 会将本地分⽀和远程分⽀的进⾏关系链接。将本地的dev对远程的dev进行一个跟踪

使用git branch -vv 选项查看我们分支的跟踪情况。

git checkout -b [dev] [origin/dev]后面跟上origin远程链接,这样我们push的时候可以直接使用git push命令,不需要再加入其他的参数 origin 和master

6.2.多人协作二

一般情况下,如果有多需求需要多人同时进行开发,是不会在一个分支上进行多人开发,而是一个需求或一个功能点就要创建一个 feature 分支。
现在同时有两个需求需要你和你的小伙伴进行开发,那么你们俩便可以各自创建一个分支来完成自己的工作。

在上个部分我们已经了解了可以从码云上直接创建远程分支,其实在本地创建的分支也可以通过推送的方式发送到远端。在这个部分我们就来用一下这种方式。

# 新增本地分⽀ feature-1 并切换
hyb@139-159-150-152:~/git_teaching$ git branch dev
* master
hyb@139-159-150-152:~/git_teaching$ git checkout -b feature-1
Switched to a new branch 'feature-1'
# 新增需求内容-创建function1⽂件
hyb@139-159-150-152:~/git_teaching$ vim function1
hyb@139-159-150-152:~/git_teaching$ cat function1 
Done!
# 将 feature-1 分⽀推送到远端
hyb@139-159-150-152:~/git_teaching$ git add function1 
hyb@139-159-150-152:~/git_teaching$ git commit -m"add function1"
[feature-1 12ed0db] add function11 file changed, 1 insertion(+)create mode 100644 function1
hyb@139-159-150-152:~/git_teaching$ git push origin feature-1 
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 270 bytes | 270.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
remote: Create a pull request for 'feature-1' on Gitee by visiting:
remote: https://gitee.com/hyb91/git_teaching/pull/new/hyb91:feature1...hyb91:master
Togitee.com:hyb91/git_teaching.git* [new branch] feature-1 -> feature-1

对于小伙伴来说,可以进行以下的操作:

此时,在本地,你看不见他新建的文档,他看不见你新建的文档。并且推送各自的分支时,并没有任何冲突,你俩互不影响,用起来很舒服!!

正常情况下,你俩就可以在自己的分支上进行专业的开发了!
但天有不测风云,你的小伙伴突然生病了,但需求还没开发完,需要你帮他继续开发,于是他便把
feature-2分支名告诉你了。这时你就需要在自己的机器上切换到 feature-2分支帮忙继续开发,要做的操作如下:

# 必须先拉取远端仓库内容
hyb@139-159-150-152:~/git_teaching$ git pull
...
From gitee.com:hyb91/git_teaching305f78a..72c5345 dev -> origin/dev* [new branch] feature-2 -> origin/feature-2
# 可以看到远程已经有了feature-2
hyb@139-159-150-152:~/git_teaching$ git branch -adev
* feature-1masterremotes/origin/HEAD -> origin/masterremotes/origin/devremotes/origin/feature-1remotes/origin/feature-2remotes/origin/master# 切换到feature-2分⽀上,可以和远程的feature-2分⽀关联起来,
# 否则将来只使⽤ git push 推送内容会失败
hyb@139-159-150-152:~/git_teaching$ git checkout -b feature-2 origin/feature-2
Branch 'feature-2' set up to track remote branch 'feature-2' from 'origin'.
Switched to a new branch 'feature-2'
hyb@139-159-150-152:~/git_teaching$ ls
a.so b.ini file.txt function2 README.en.md README.md

切换成功后,便可以看见feature-2分⽀中的function2文件了,接着就可以帮⼩伙伴进⾏开发,然后进行推送。

这时,你的小伙伴已经修养的差不多,可以继续进行自己的开发工作,那么他首先要获取到你帮他开发的内容,然后接着你的代码继续开发。或者你已经帮他开发完了,那他也需要在自己的电脑上看看你帮他写的代码:

Pull 无效的原因是小伙伴没有指定本地 feature-2 分支与远程 origin/feature-2分支的链接,根据提
示,设置feature-2和origin/feature-2的链接即可:

目前,小伙伴的本地代码和远端保持严格一致。你和你的小伙伴可以继续在不同的分支下进行协同开发了。
各自功能开发完毕后,不要忘记我们需要将代码合并到master中才算真正意义上的开发完毕。
由于你的小伙伴率先开发完毕,于是开始 merge:

自己的操作也是跟上面一致,就不多赘述了

此时, feature-1 和 feature-2 分支对于我们来说就没用了,那么我们可以直接在远程仓库中
将dev分支删除掉。

这就是多人协作的工作模式,⼀旦熟悉了,就非常简单

总的来说:合并分两种,推荐第一种PR申请单,更加有保障。

相关文章:

Git 分支管理与多人协作实战指南

目录 1.分支管理&#xff1a; 1.1.理解分支&#xff1a; 1.2.创建分支 1.3.切换分支 1.4.合并分支 1.5.删除分支 2.合并冲突 3.分支管理策略 分支策略 4.bug分支 5.删除临时分支 git branch -d 和 git branch -D的区别 6.多人协作 6.1.多人协作一 6.2.多人协作二…...

使用pyboard、micropython和tja1050进行can通信

单片机和can收发器之间tx、rx不需要交叉接线&#xff01;&#xff01;&#xff01; tja1050的rx接Y3、tx接Y4 from pyb import CANcan CAN(1) can.init(modecan.NORMAL, prescaler6, sjw1, bs14, bs22, auto_restartTrue) # 1Mbps的配置&#xff0c;本文使用的micropython1.…...

新能源监控平台都管理哪些数据

北理新源信息科技有限公司&#xff08;简称“北理新源”&#xff09;依托北京理工大学电动车辆国家工程研究中心&#xff0c;建设和运营了“新能源汽车国家监测与管理平台”。该平台是国家级的新能源汽车数据监管平台&#xff0c;主要负责对新能源汽车的运行数据进行采集、监测…...

Go学习:常量

变量&#xff1a;程序运行期间&#xff0c;可以改变的量&#xff0c;变量声明需要使用 var 常量&#xff1a;程序运行期间&#xff0c;不可以改变的量&#xff0c;常量声明需要使用 const 目录 1. 常量不允许修改 2. 常量赋值不使用 : 3. 常量能够自动推导类型 1. 常量不允许…...

Apache Tika 详解

Apache Tika是一个开源的、跨平台的库&#xff0c;专门用于检测、提取和解析多种文件格式的元数据。以下是对Apache Tika的详细解析&#xff1a; 一、概述 Apache Tika旨在为各种类型的数据提取提供一个单一的API&#xff0c;它支持多种文件格式&#xff0c;包括文档、图片、…...

第12章:Python TDD完善货币加法运算(一)

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

KNN的调参方法

目录 1. K 值&#xff08;邻居数 K&#xff09;的选择2. 距离度量方式2.1 常见距离度量2.2 如何选择距离度量 3. 权重策略&#xff08;weights&#xff09;4. 特征预处理4.1 特征缩放&#xff08;标准化/归一化&#xff09;4.2 处理异常值 5. 特征选择或降维6. 使用交叉验证来综…...

mac 电脑上安装adb命令

在Mac下配置android adb命令环境&#xff0c;配置方式如下&#xff1a; 1、下载并安装IDE &#xff08;android studio&#xff09; Android Studio官网下载链接 详细的安装连接请参考 Mac 安装Android studio 2、配置环境 在安装完成之后&#xff0c;将android的adb工具所在…...

P3934 [Ynoi2016] 炸脖龙 I Solution

Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1​,a2​,⋯,an​). 有 m m m 个操作&#xff0c;分以下两种&#xff1a; modify ⁡ ( l , r , k ) \operatorname{modify}(l,r,k) modify(l,r,k)&#xff1a;对每个 i ∈ [ l , r ] i \in [l…...

数据库-多表查询

介绍&#xff08;什么是多表查询&#xff1f;&#xff09; 多表查询&#xff1a;查询时从多张表中获取所需数据 单表查询的SQL语句&#xff1a;select 字段列表 from 表名; 那么要执行多表查询&#xff0c;只需要使用逗号分隔多张表即可 如&#xff1a; select 字段列表 from …...

PID控制的优势与LabVIEW应用

PID控制&#xff08;比例-积分-微分控制&#xff09;已在工业控制领域得到广泛应用&#xff0c;尤其在实时控制和自动化系统中&#xff0c;其核心优点是简单、稳定且高效。尽管许多现代控制方法&#xff08;如自适应控制、模型预测控制等&#xff09;逐渐崭露头角&#xff0c;P…...

Next.js:构建大模型智能体GPT研究者应用的 Web开发框架

Next.js&#xff1a;构建大模型智能体GPT研究者应用的 Web开发框架 Next.js 基础知识 Next.js 是由 Vercel 公司开发维护的框架&#xff0c;极大地简化了 React 应用的开发流程。其核心特性包括&#xff1a; 服务器端渲染&#xff08;SSR&#xff09;与静态站点生成&#xff…...

航空航天混合动力(7)航空航天分布式电推进系统

航空航天分布式电推进系统 1.概述2.分布式电推进系统组成3.关键技术4.分布式电推进系统优势5.国内外研究情况5.1 国外5.2 国内6.分布式电推进系统应用场景6.1 航空领域6.2 航天领域tips:资料来自网上,仅供参考学习使用 1.概述 分布式推进系统是指飞行器推力由位于整个航空器…...

Java定时任务实现方案(一)——Timer

这篇笔记&#xff0c;简单来介绍一下Java如何使用Timer来实现定时任务&#xff0c;以及该方案的优点和缺点。 Timer是JDK自带的类&#xff0c;可以用来实现定时任务。使用 1.创建定时任务 ​ 定义一个实现了java.lang.Runnable接口的类&#xff0c;重写run()方法&#xff0c;…...

Linux(UOS系统:DNS)

赛题拓扑&#xff1a; 题目&#xff1a; 2.DNS 安装BIND9。配置为DNS根域服务器。其他未知域名解析&#xff0c;统一解析为该本机IP。创建正向区域“chinaskills.cn”。类型为Slave。主服务器为“AppSrv”。 rootispsrv:~# apt-get install bind9 -y rootispsrv:~# cd /etc/…...

一. 初始 Redis(快速入门-00)

一. 初始 Redis(快速入门-00) 文章目录 一. 初始 Redis(快速入门-00)Redis 概述&#xff1a;关系型数据库(如 MySQL ) 问题NoSQL 数据库(非关系性数据库)最后&#xff1a; Redis 概述&#xff1a; Redis 官方地址&#xff1a; https://redis.io/ Reids 中文的官方地址&#xf…...

Qt中的Item Widget组控件:QListWidget、QTreeWidget 和 QTableWidget使用方法(详细图文教程)

&#x1f4aa; 图像算法工程师&#xff0c;专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &a…...

汇编与逆向(一)-汇编工具简介

RadASM是一款著名的WIN32汇编编辑器&#xff0c;支持MASM、TASM等多种汇编编译器&#xff0c;Windows界面&#xff0c;支持语法高亮&#xff0c;自带一个资源编辑器和一个调试器。 一、汇编IDE工具&#xff1a;RadASM RadASM有内置的语言包 下载地址&#xff1a;RadASM asse…...

澎峰科技计算软件栈与沐曦GPU完成适配和互认证

近期&#xff0c;澎峰科技与沐曦完成了对PerfXLM&#xff08;推理引擎&#xff09;、PerfXCloud&#xff08;大模型服务平台&#xff09;与沐曦的曦云系列通用计算GPU的联合测试&#xff0c;测试结果表明PerfXLM、PerfXCloud软件与沐曦GPU产品实现了全面兼容。 PerfXLM高性能大…...

如何用vscode断点调试Vue.js的项目

源码放在git上了&#xff0c;大家自己去看吧&#xff0c;非常简单&#xff0c;视频教程里面也有。 GitHub - SpaceView/howto_debug_vue_js_with_vscode: A basic project show how to debug vue with vscode How to Debug? Following, Creating a Project | Vue CLI to …...

C++17 新特性解析:Lambda 捕获 this

C17 引入了许多改进和新特性&#xff0c;其中之一是对 lambda 表达式的增强。在这篇文章中&#xff0c;我们将深入探讨 lambda 表达式中的一个特别有用的新特性&#xff1a;通过 *this 捕获当前对象的副本。这个特性不仅提高了代码的安全性&#xff0c;还极大地简化了某些场景下…...

Springboot自动配置的原理

先拿redis来举个例子 第一步导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 第二步配置 spring: redis: database:host:127.0.0.1 port…...

第13章:Python TDD完善货币加法运算(二)

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

solidity基础 -- 存储类型

在Solidity智能合约开发中&#xff0c;存储类型是一个至关重要的概念。它不仅影响合约的性能&#xff0c;还决定了数据的存储位置和生命周期。Solidity提供了三种主要的存储类型&#xff1a;storage、memory和calldata。本文将结合给定的代码示例&#xff0c;并通过更多实例详细…...

GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比

GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比 目录 GA-CNN-LSTM-Attention、CNN-LSTM-Attention、GA-CNN-LSTM、CNN-LSTM四模型多变量时序预测一键对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基于GA-CNN-LST…...

AI对齐与开源发展:多学科融合创新之路

标题&#xff1a;AI对齐与开源发展&#xff1a;多学科融合创新之路 文章信息摘要&#xff1a; 本文分析了AI对齐研究中多学科融合的重要性及开源AI领域的最新发展。文章指出&#xff0c;AI对齐问题需要计算机科学与社会选择理论等学科深度结合&#xff0c;特别是在RLHF领域的应…...

大华Java开发面试题及参考答案 (下)

口述一种排序算法,如快排。 快速排序(Quick Sort): 快速排序是一种分治算法,基本思想是将一个数组分成两个子数组,然后递归地对这两个子数组进行排序。首先,从数组中选择一个元素作为基准元素(pivot),可以选择第一个元素、最后一个元素或随机元素。然后,将小于等于基…...

[Spring] OpenFeign的使用

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

java文件按行写入数据后并创建行索引及查询

背景 当有很多数据需要存储&#xff0c;这些数据只是想要简单的按行存储和查询&#xff0c;不需要进行其他条件搜索&#xff0c;此时就可以考虑不需把这些数据存储在数据库&#xff0c;而是直接写入文件&#xff0c;然后从文件中查询 但是正常情况下&#xff0c;如果仅仅只是按…...

在视频汇聚平台EasyNVR平台中使用RTSP拉流的具体步骤

之前有用户反馈&#xff0c;在EasyNVR平台中添加Pull时使用海康设备的RTSP流地址无法播放。经过研发的优化及一系列严谨的验证流程&#xff0c;我们已确认优化后的EasyNVR平台&#xff0c;通过Pull方式添加海康设备的RTSP流已经能够正常播放。以下是具体的操作步骤&#xff1a;…...

OS2.【Linux】基本命令入门(1)

目录 1.操作系统是什么? 2.好操作系统的衡量标准 3.操作系统的核心工作 4.在计算机上所有行为都会被转换为硬件行为 5.文件 6.简单介绍一些基本命令 1.clear 2.pwd 3.ls 1.ls -l 2.隐藏文件的创建 3.ls -al 4.ls -ld 5.ls -F(注意是大写) 4.cd 1.cd .. "…...

WPF 复杂页面布局及漂亮 UI 界面设计全解析

在 WPF 开发领域&#xff0c;打造一个既具备复杂功能又拥有美观 UI 界面的应用程序是众多开发者追求的目标。复杂页面布局与漂亮的 UI 设计不仅能提升用户体验&#xff0c;还能展现应用的专业性和独特性。本文将深入探讨如何在 WPF 中实现复杂页面布局以及设计出令人眼前一亮的…...

002-SpringBoot整合AI(Alibaba)

SpringBoot整合AI 一、引入依赖二、配置application.yml三、获取 api-key四、编写 controller五、起服务调用 一、引入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><vers…...

c++模板进阶

前言 一、非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数…...

99.8 金融难点通俗解释:净资产收益率(ROE)

目录 0. 承前1. 简述2. 比喻&#xff1a;养母鸡赚钱2.1 第一步&#xff1a;投资母鸡2.2 第二步&#xff1a;母鸡下蛋2.3 第三步&#xff1a;计算赚钱2.4 第四步&#xff1a;计算ROE 3. 生活中的例子3.1 好的ROE3.2 一般的ROE3.3 差的ROE 4. 小朋友要注意4.1 ROE高不一定好4.2 R…...

原生HTML集合

一、表格 1、固定表格 <div class"tablebox"><div class"table-container"><table id"myTable" border"0" cellspacing"0" cellpadding"0"><thead><tr></tr></thead>…...

【计算机网络】- 应用层HTTP协议

目录 初识HTTP 什么是HTTP 版本 HTTPS 模型 HTTP抓包工具 为什么使用 抓包工具的下载 下载后的重要操作 Fiddler的使用 HTTP请求与响应的基本格式 HTTP请求基本格式​编辑 HTTP响应基本格式 协议格式总结❗️❗️❗️​编辑 HTTP 详解 认识 URL URL基本格式 …...

python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖

【1】引言 前序学习了使用numpy创建单通道的灰色图像&#xff0c;并对灰色图像的局部进行了颜色更改&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 之后又学习了使用numpy创…...

数据库:MongoDB命令行帮助解释

MongoDB命令&#xff1a; mongodmongosmongoperrormongoexportmongofilesmongoimportmongorestoreMongostat MongoDB包中的核心组件包括: mongod 是 MongoDB 的核心服务器进程&#xff0c;负责数据存储和管理。mongos 是分片集群的路由进程&#xff0c;负责将请求路由到正确…...

python 统计相同像素值个数

目录 python 统计相同像素值个数 最大值附近的值 python 统计相同像素值个数 import cv2 import numpy as np import time from collections import Counter# 读取图像 image cv2.imread(mask16.jpg)# 将图像转换为灰度图像 gray_image cv2.cvtColor(image, cv2.COLOR_BGR2…...

工作流引擎Camunda与LiteFlow核心组件对比

以下为 Camunda 7 和 LiteFlow 详细的介绍&#xff0c;包括它们的核心组件和用途。 1. Camunda 7 详细介绍 Camunda 7 是一个基于 BPMN 2.0 标准的企业级工作流和决策自动化平台。它被广泛应用于复杂业务流程的管理和执行&#xff0c;其核心目标是通过流程自动化来提升企业效…...

记一个Timestamp时区问题的坑

resultSet.getTimestamp(“kpi_collect_time”)查出来的Timestamp居然是带时区的&#xff0c; 如果该Timestamp不是UTC时区的&#xff0c;Timestamp.toInstant().atZone(ZoneId.of(“UTC”))会把Timestamp转成UTC时区 使用Timestamp.toLocalDateTime()可以直接把时区信息抹除 …...

R语言学习笔记之开发环境配置

一、概要 整个安装过程及遇到的问题记录 操作步骤备注&#xff08;包含遇到的问题&#xff09;1下载安装R语言2下载安装RStudio3离线安装pacman提示需要安装Rtools4安装Rtoolspacman、tidyfst均离线安装完成5加载tidyfst报错 提示需要安装依赖&#xff0c;试错逐步下载并安装…...

Hive部署

1. 最小化安装Hive 本次安装的版本是Hive的3.1.3版本 解压缩Hive压缩包 # 解压缩 tar -zxvf apache-hive-3.1.3-bin.tar.gz、 # 修改文件夹名称(看个人习惯&#xff0c;可以不执行) mv apache-hive-3.1.3-bin apache-hive-3.1.3在conf目录下&#xff0c;新增hive-env.sh&…...

Windows第一次上手鸿蒙周边

端云一体所需装备 很重要&#xff1a;C/D/E/F盘要有二三十G的可用空间&#xff01; 硬件&#xff1a;华为鸿蒙实验箱&#xff08;基础版&#xff09;》飞机板核心板环境监测板 软件&#xff1a;Visual Studio Code写代码 终端编译 Hiburn烧录到开发板 MobaXterm &#xff08…...

【java数据结构】二叉搜索树

【java数据结构】二叉搜索树 一、二叉搜索树的概念二、二叉搜索树的操作2.1 插入2.2 查找2.3 删除&#xff08;重点以及难点&#xff09;2.3.1 删除节点的左边为null2.3.2 删除节点的右边为null2.3.3 删除的左右节点都不为空 三、二叉搜索树的性能分析3.1 最优情况3.2 最差情况…...

3D Vision--计算点到平面的距离

写在前面 本文内容 计算点到平面的距离 平台/环境 python open3d 转载请注明出处&#xff1a; https://blog.csdn.net/qq_41102371/article/details/121482246 目录 写在前面准备Open3D代码完 准备Open3D pip install open3d代码 import open3d as o3ddef compute_points2…...

相机内参的作用原理

由三角形角度关系&#xff0c;得到X_image / focal_length X_real / Z_distance 用双目测距得到Z_distance之后 然后联合X_image / focal_length可以计算得到真实世界的X_real...

计算机网络介质访问控制全攻略:从信道划分到协议详解!!!

一、信道划分介质访问控制 介质访问控制&#xff1a;多个节点共享同一个“总线型”广播信道时&#xff0c;可能发生“信号冲突” 应该怎么控制各节点对传输介质的访问&#xff0c;才能减少冲突&#xff0c;甚至避免冲突? 时分复用(TDM) 时分复用&#xff1a;将时间分为等长的“…...

代码随想录day1

704.二分查找&#xff1a; 1.左闭右闭 int search(vector<int>& nums, int target) {int right nums.size() - 1;int left 0;while(left < right){int middle left ((right - left) >> 1);if(nums.at(middle) target){return middle;}else if(nums[m…...