详解SVN与Git相比存在的不足

原文全文详见个人博客:

详解SVN与Git相比存在的不足截至目前,我们已既从整理梳理的SVN和Git在设计理念上的差异,也重点对二者的存储原理和分支管理理念的差异进行深入分析。这些差异也直接造成了SVN和Git在分支合并、冲突解决、历史记录管理以及网络依赖等方面功能的显著区别,也彰显了Git的强大之处,因此最后我们详细总结分析,也算做个阶段性的学习小结:icon-default.png?t=N7T8https://www.coderli.com/detailed-analysis-of-the-drawbacks-of-svn-vs-git/加入群聊,大佬免费带飞:【Java学习交流(982860385)】

截至目前,我们已既从整理梳理的SVN和Git在设计理念上的差异,也重点对二者的存储原理和分支管理理念的差异进行深入分析。这些差异也直接造成了SVN和Git在分支合并、冲突解决、历史记录管理以及网络依赖等方面功能的显著区别,也彰显了Git的强大之处,因此最后我们详细总结分析,也算做个阶段性的学习小结:

一、分支合并场景

在没有冲突的情况下,SVN 的分支合并比 Git 繁琐,主要体现在以下几个方面:

(一)SVN分支合并问题梳理

1. 版本范围的指定

在 SVN 中,合并操作需要手动指定要合并的版本范围。每次合并都需要明确指出从哪个版本开始到哪个版本结束,而 Git 则自动处理这些细节。

假设我们有一个分支 feature1,需要将其合并回 trunk。 首先,我们需要找到 feature1 分支从 trunk 分离的起始版本,然后找到 feature1 分支的最新版本。

svn log --stop-on-copy http://svn.example.com/repo/branches/feature1

假设起始版本是 100,最新版本是 150。那么,我们需要手动指定这个版本范围进行合并:

svn checkout http://svn.example.com/repo/trunk
svn merge -r 100:150 http://svn.example.com/repo/branches/feature1
svn commit -m "Merge feature1 into trunk"

2. 合并记录的管理

在 SVN 中,合并操作需要手动管理合并记录,以避免重复合并。SVN 1.5 及以上版本引入了合并信息(mergeinfo)属性,但在实际操作中,管理这些属性仍然比较复杂和繁琐。

在合并时,SVN 会尝试更新合并信息属性:

svn propget svn:mergeinfo .

需要确保这些属性正确更新,防止重复合并和冲突。

3. 手动处理合并后的提交

在 SVN 中,合并操作完成后,需要手动提交合并结果。Git 则在合并时自动处理这些提交。

合并后,需要手动检查并提交:

svn status
svn commit -m "Merge feature1 into trunk"

4. 操作的复杂性和步骤多

在 SVN 中,合并操作涉及多个步骤,每一步都需要与服务器进行通信,这增加了操作的复杂性和时间成本。

完整的合并过程包括:

  1. 检出目标分支(例如 trunk):
     svn checkout http://svn.example.com/repo/trunk
    
  2. 找到源分支的起始版本和最新版本:
     svn log --stop-on-copy http://svn.example.com/repo/branches/feature1
    
  3. 合并指定版本范围的更改:
     svn merge -r 100:150 http://svn.example.com/repo/branches/feature1
    
  4. 检查合并结果并提交:
     svn status
     svn commit -m "Merge feature1 into trunk"
    

每个步骤都需要与远程服务器进行通信,增加了操作的繁琐性。

(二)与Git对比

相比之下,Git 的合并操作简单得多,因为 Git 自动处理大部分细 假设我们有一个分支 feature1,需要将其合并回 main。

  1. 切换到目标分支:
     git checkout main
    
  2. 合并源分支:
     git merge feature1
    
  3. 提交合并结果(如果有冲突则手动解决):
     git commit -m "Merge feature1 into main"
    

(三)分支合并总结

在没有冲突的情况下,SVN 的分支合并比 Git 繁琐,具体体现在:

  1. 版本范围的指定:SVN 需要手动指定版本范围,而 Git 自动处理。
  2. 合并记录的管理:SVN 需要手动管理合并信息属性,防止重复合并和冲突。
  3. 手动处理合并后的提交:SVN 需要手动提交合并结果,而 Git 自动处理。
  4. 操作的复杂性和步骤多:SVN 的合并操作涉及多个步骤,每一步都需要与服务器通信,而 Git 的操作在本地完成,步骤简单。

这些因素使得 SVN 的分支合并操作比 Git 更加繁琐和复杂。

二、冲突解决场景

在冲突解决方面,Git 比 SVN的优势主要体现在两个方面:一是某些场景下可能SVN会提示冲突但Git可以自动解决合并;二是在同样解决冲突的情况下Git提供更强大而便利的工具。

(一)SVN与Git冲突不一致的场景

在某些情况下,SVN 可能会提示冲突,而 Git 能够自动合并。这主要是由于 Git 的三方合并算法更智能和强大,能够更好地处理复杂的合并场景。下面是几个具体的场景:

1. 文件内容的并行修改

两个分支对同一个文件的不同部分进行了修改。

假设我们有一个文件 file.txt,初始内容如下:

Line 1
Line 2
Line 3
Line 4

在 trunk 分支上,我们修改了 Line 2:

Line 1
Line 2 modified in trunk
Line 3
Line 4

在 feature 分支上,我们修改了 Line 4:

Line 1
Line 2
Line 3
Line 4 modified in feature

在 SVN 中,合并这两个分支可能会提示冲突,因为 SVN 不能智能地处理并行修改:

svn checkout /project/trunk
svn merge /project/branches/feature
# SVN 可能会提示冲突,需要手动解决

在 Git 中,合并这两个分支通常不会产生冲突,Git 能够智能地合并这些并行修改:

git checkout main
git merge feature
# Git 能自动合并这两个修改,不会提示冲突

2. 文件重命名和修改

一个分支对文件进行了重命名,另一个分支对同一个文件进行了内容修改。

假设我们有一个文件 file.txt,初始内容如下:

Initial content

在 trunk 分支上,我们将 file.txt 重命名为 renamed_file.txt:

svn mv file.txt renamed_file.txt
svn commit -m "Rename file.txt to renamed_file.txt"

在 feature 分支上,我们修改了 file.txt 的内容:

echo "Modified content" > file.txt
svn commit -m "Modify file.txt content"

在 SVN 中,合并这两个分支可能会提示冲突,因为 SVN 不能智能地处理重命名和内容修改:

svn checkout /project/trunk
svn merge /project/branches/feature
# SVN 可能会提示冲突,需要手动解决

在 Git 中,合并这两个分支通常不会产生冲突,Git 能够智能地合并这些更改:

git checkout main
git merge feature
# Git 能自动合并重命名和内容修改,不会提示冲突

3. 文件的移动和修改

一个分支将文件移动到新的目录,另一个分支对同一个文件进行了内容修改。

假设我们有一个文件 file.txt,初始内容如下:

Initial content

在 trunk 分支上,我们将 file.txt 移动到 new_directory/:

mkdir new_directory
svn mv file.txt new_directory/file.txt
svn commit -m "Move file.txt to new_directory/"

在 feature 分支上,我们修改了 file.txt 的内容:

echo "Modified content" > file.txt
svn commit -m "Modify file.txt content"

在 SVN 中,合并这两个分支可能会提示冲突,因为 SVN 不能智能地处理移动和内容修改:

svn checkout /project/trunk
svn merge /project/branches/feature
# SVN 可能会提示冲突,需要手动解决

在 Git 中,合并这两个分支通常不会产生冲突,Git 能够智能地合并这些更改:

git checkout main
git merge feature
# Git 能自动合并移动和内容修改,不会提示冲突

4. 目录结构变化和文件修改

一个分支对项目的目录结构进行了修改,另一个分支对某些文件进行了修改。

假设我们有一个项目目录结构如下:

/project
    file1.txt
    file2.txt

在 trunk 分支上,我们对目录结构进行了修改:

mkdir src
svn mv file1.txt src/file1.txt
svn mv file2.txt src/file2.txt
svn commit -m "Reorganize directory structure"

在 feature 分支上,我们修改了 file1.txt 和 file2.txt 的内容:

echo "Modified content" > file1.txt
echo "More modified content" > file2.txt
svn commit -m "Modify file1.txt and file2.txt"

在 SVN 中,合并这两个分支可能会提示冲突,因为 SVN 不能智能地处理目录结构变化和文件修改:

svn checkout /project/trunk
svn merge /project/branches/feature
# SVN 可能会提示冲突,需要手动解决

在 Git 中,合并这两个分支通常不会产生冲突,Git 能够智能地合并这些更改:

git checkout main
git merge feature
# Git 能自动合并目录结构变化和文件修改,不会提示冲突

(二)冲突解决能力差异

Git 在冲突解决方面比 SVN 更强大,主要体现在以下几个方面:

1. 三方合并算法

Git 使用三方合并算法(Three-way Merge),这是处理冲突的关键技术。三方合并算法利用三个点:两个分支的最新提交和它们的共同祖先提交。通过比较这三个点,Git 可以更准确地检测冲突并合并更改。

假设有以下提交历史:

A---B---C (main)
     \
      D---E (feature)

在合并 feature 到 main 时,Git 使用 A 作为共同祖先提交,通过比较 B、C 和 E 的变化来进行合并。这样可以更智能地检测和解决冲突。

2. 冲突标记和自动合并

当发生冲突时,Git 会在冲突文件中插入冲突标记,清晰地显示冲突的具体位置和内容。用户可以直接在冲突文件中查看和编辑冲突部分。

假设在 main 和 feature 中对同一个文件 file.txt 进行了不同的修改,合并时发生冲突。Git 会在 file.txt 中插入冲突标记:

<<<<<<< HEAD
内容在 main 分支中的更改
=======
内容在 feature 分支中的更改
>>>>>>> feature

用户可以直接编辑文件,选择或合并不同的更改,并删除冲突标记。

3. 高级冲突解决工具

Git 提供了 git mergetool 命令,可以集成多种图形化冲突解决工具,如 KDiff3、Meld、P4Merge 等。这些工具提供图形界面,帮助用户直观地查看和解决冲突。

当发生冲突时,使用 git mergetool 启动冲突解决工具:

git mergetool

图形化冲突解决工具会显示冲突文件的不同版本,用户可以直观地比较和合并不同的更改。

4. 自动化合并和合并策略

Git 能够自动检测并合并大部分更改,减少手动操作。当两个分支没有冲突时,Git 会自动合并这些更改,不需要用户干预。

git checkout main
git merge feature

如果没有冲突,Git 会自动合并 feature 的更改到 main,并生成一个合并提交。

Git 提供多种合并策略,帮助用户根据具体情况选择最合适的合并方式。例如,git merge 提供了 –squash 和 –no-ff 等选项:

  • –squash:将所有合并的提交压缩成一个提交。
  • –no-ff:禁止快速前进合并,确保生成一个合并提交。
git merge --squash feature
git commit -m "Squashed merge of feature"
git merge --no-ff feature

5. 详细的合并日志

Git 的 git log 命令提供详细的合并日志,帮助用户理解和追踪合并过程中的变化。用户可以使用 –merge 选项查看合并相关的日志:

git log --merge

此命令会显示合并过程中涉及的提交和更改,帮助用户理解冲突的原因和解决过程。

6. 重做和撤销功能

Git 提供了方便的重做和撤销功能,如 git reset、git revert 和 git cherry-pick,帮助用户在解决冲突过程中进行调整和修正。

# 重置到上一个提交,撤销合并
git reset --hard HEAD~1

# 撤销某个提交
git revert <commit>

# 从其他分支挑选一个提交并应用
git cherry-pick <commit>

SVN 的冲突解决

相比之下,SVN 在冲突解决方面的工具和支持较弱:

  1. 基本的冲突标记:SVN 也会在冲突文件中插入冲突标记,但这些标记相对简单,用户需要手动解决冲突。
  2. 手动解决冲突:用户需要手动编辑冲突文件,并使用 svn resolve 命令标记冲突已解决。
  3. 缺乏高级工具:SVN 没有类似 git mergetool 的高级冲突解决工具,用户无法使用图形界面工具来解决冲突。
  4. 版本范围的指定:合并操作需要手动指定版本范围,增加了操作的复杂性和出错的可能性。

相比之下,SVN 在冲突解决方面的工具和支持较弱,增加了操作的复杂性和出错的可能性。

三、历史记录

在 SVN 中,分支和标签都是通过目录复制来实现的。例如,创建一个新的分支或标签,实际上是将当前目录结构复制到一个新的目录中。这种方式虽然直观,但在实际使用中会带来一些问题。

(一)情况梳理

假设我们有以下 SVN 仓库结构:

/project
    /trunk
    /branches
        /feature1
        /feature2
    /tags
        /release-1.0
        /release-2.0

这里的 trunk 是主开发线,branches 目录下存放着各个分支,tags 目录下存放着各个版本的标签。 在 SVN 中,每次创建分支或标签时,都会复制整个目录结构,这意味着每个分支或标签都有自己独立的历史记录。例如,当你在 feature1 分支上进行提交时,这些提交的历史记录只会存在于 feature1 目录下。示例如下: 在 feature1 分支上进行开发并提交:

svn checkout /project/branches/feature1
# 进行开发...
svn commit -m "Add feature 1"

此时,feature1 分支的历史记录如下:

/project/branches/feature1
    E (Add feature 1)
    F (Additional changes)

而 trunk 的历史记录不包含 feature1 分支上的提交。 当你将 feature1 分支合并回 trunk 时,合并记录会在 trunk 中创建一条新的提交,但不会包含 feature1 分支上的详细提交历史。你只能看到合并后的整体变化,而看不到每个提交的具体内容。

svn checkout /project/trunk
svn merge /project/branches/feature1
svn commit -m "Merge feature1 into trunk"

此时,trunk 的历史记录如下:

/project/trunk
    A---B---C---D---G (Merge feature1 into trunk)

而 feature1 分支的历史记录仍然独立存在:

/project/branches/feature1
    E (Add feature 1)
    F (Additional changes)

(二)历史记录分散的影响

由于 SVN 的分支和合并模型是基于目录复制的,每个分支和标签都有自己独立的历史记录,这就导致了以下问题:

  • 历史记录分散:每个分支的提交历史都独立存在,合并操作不会将所有详细的提交历史合并到目标分支中。这使得在查看和管理整个项目的历史记录时,需要分别查看每个分支的提交历史。
  • 难以集中查看:要了解整个项目的历史记录,需要在不同的分支和目录之间切换,这增加了复杂性和不便。
  • 合并历史不完整:合并后的目标分支只包含合并操作的整体提交记录,而不包含每个分支的详细提交历史。开发者难以了解具体的每一步更改。

(三)对比 Git 的历史记录管理

与 SVN 相比,Git 在历史记录管理方面有显著优势:

  • 集中管理历史记录:在 Git 中,所有分支和合并操作的历史记录都是集中管理的。每个分支和提交都有完整的历史记录,所有提交历史都存储在同一个仓库中。
  • 完整的合并历史:Git 的合并操作会保留所有详细的提交历史,合并后的目标分支不仅包含合并记录,还包含所有合并的详细提交。
  • 直观的历史查看工具:Git 提供了强大的历史查看工具,如 git log 和 git log –graph,能够直观地展示分支和合并历史,帮助开发者了解整个项目的演变过程。

假设我们在 Git 中有类似的分支结构和操作:

git checkout -b feature1
# 进行开发...
git commit -m "Add feature 1"
git commit -m "Additional changes"
git checkout develop
git merge feature1

此时,develop 分支的历史记录如下:

A---B---C---D---I (Merge feature1)
         \    /
          E---F (feature1)

通过 git log 和 git log –graph,你可以清楚地看到所有分支和合并的详细历史记录。这使得历史记录集中管理和查看变得非常方便。

四、SVN操作繁琐且依赖于网络通信

SVN 操作繁琐且依赖于网络通信,具体体现在以下几个方面:

(一) 分支创建和管理

SVN 中的分支创建

在 SVN 中,分支是通过复制整个目录树来创建的,这需要与远程服务器进行大量的通信。 假设我们有一个项目结构如下:

/project
    /trunk
    /branches
    /tags

要创建一个分支 feature1,需要执行以下操作:

svn copy http://svn.example.com/repo/trunk http://svn.example.com/repo/branches/feature1 -m "Create feature1 branch"

每次创建分支时,都需要与远程服务器进行通信,这在大项目中会占用大量时间和网络带宽。

Git 中的分支创建

相比之下,Git 的分支创建操作在本地完成,非常快速,不需要与远程服务器通信。

git checkout -b feature1

(二) 检出操作

SVN 中的检出操作

在 SVN 中,每次检出操作都需要从远程服务器下载整个目录结构,耗时较长。 要检出 trunk 分支,需要执行以下操作:

svn checkout http://svn.example.com/repo/trunk

对于大项目,这个操作可能需要很长时间,且对网络带宽的依赖较大。

Git 中的检出操作

Git 的检出操作在本地完成,不需要从远程服务器下载数据。即使需要从远程仓库克隆仓库,整个过程也比 SVN 更高效。

git checkout main

(三)提交操作

SVN 中的提交操作

每次提交操作都需要与远程服务器通信,提交过程会受到网络状况的影响。 要提交更改,需要执行以下操作:

svn commit -m "Commit message"

每次提交都需要将更改推送到远程服务器,这在网络状况不佳时可能会失败或非常缓慢。

Git 中的提交操作

Git 的提交操作在本地完成,不需要与远程服务器通信。

git commit -m "Commit message"

提交后,用户可以选择何时将更改推送到远程服务器,这使得提交操作更加灵活和高效。

(四) 合并操作

SVN 中的合并操作

每次合并操作都需要与远程服务器通信,操作复杂且容易出错。 要将 feature1 分支合并到 trunk,需要执行以下操作:

svn checkout http://svn.example.com/repo/trunk
svn merge http://svn.example.com/repo/branches/feature1
svn commit -m "Merge feature1 into trunk"

每一步操作都需要与远程服务器通信,增加了操作的复杂性和时间成本。

Git 中的合并操作

Git 的合并操作在本地完成,不需要与远程服务器通信。

git checkout main
git merge feature1
git commit -m "Merge feature1 into main"

(五)更新操作

SVN 中的更新操作

每次更新操作都需要从远程服务器下载最新的更改,操作繁琐且依赖网络。 要更新本地副本,需要执行以下操作:

svn update

这个操作需要与远程服务器通信,下载最新的更改。

Git 中的更新操作

Git 的更新操作在本地完成,如果需要从远程仓库获取最新的更改,可以使用以下命令:

git pull

即使没有网络,用户也可以在本地进行操作,提交和合并本地更改。

(六) 网络依赖和离线操作

SVN 的网络依赖

SVN 的大多数操作(如提交、更新、合并等)都需要与远程服务器通信,这使得 SVN 对网络的依赖非常强。如果网络状况不佳或无法连接到远程服务器,用户将无法进行这些操作。

Git 的离线操作

Git 的大多数操作(如提交、合并、检出等)都可以在本地完成,不需要与远程服务器通信。用户可以在离线状态下进行大部分开发工作,只有在需要同步远程仓库时才需要网络连接。

网络依赖总结

SVN 操作繁琐且依赖于网络通信,具体体现在:

  1. 分支创建和管理:每次分支创建都需要复制整个目录树,并与远程服务器通信。
  2. 检出操作:每次检出都需要从远程服务器下载整个目录结构,耗时较长。
  3. 提交操作:每次提交都需要与远程服务器通信,受网络状况影响。
  4. 合并操作:合并操作复杂且每一步都需要与远程服务器通信。
  5. 更新操作:每次更新都需要从远程服务器下载最新的更改。
  6. 网络依赖和离线操作:SVN 对网络依赖强,许多操作无法离线完成。

相比之下,Git 的大多数操作在本地完成,不需要与远程服务器通信,操作更加高效和灵活。这使得 Git 在现代软件开发中得到了广泛的应用。

欢迎加入频道【Java开发者乐园】,大佬免费指导:点击加入  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构之二元查找树转有序双向链表详解与示例(C/C++)

文章目录 1. 二元查找树&#xff08;BST&#xff09;简介2. 有序双向链表&#xff08;DLL&#xff09;简介3. 二元查找树的实现4. 转换为有序双向链表的步骤5. C实现代码6. C实现代码7. 效率与空间复杂度比较8. 结论 在数据结构与算法中&#xff0c;树和链表都是非常重要的数据…

【Linux】进程间通信之-- 共享内存与信号量的介绍(下)

前言 上一篇&#xff0c;我们由进程间通信&#xff0c;引入并讲述了管道、匿名管道和命名管道&#xff0c;本节&#xff0c;将继续学习进程间通信的另一种方式之&#xff0c;共享内存。还要学习几个系统调用接口&#xff0c;并演示两个进程通过共享内存来进行通信。。。 目录 1…

WGS84经纬度坐标 GCJ02火星坐标 BD09百度坐标互相转换

WGS84经纬度坐标 GCJ02火星坐标 BD09百度坐标互相转换 背景&#xff1a;uniapp做的微信小程序&#xff0c;使用到了相机拍照并获取位置坐标信息&#xff1b;在腾讯地图上展示坐标点位置信息&#xff1b; 由于业务需要我们的PC端用的不是腾讯地图&#xff0c;需要使用WGS84坐标或…

Java二十三种设计模式-代理模式模式(8/23)

代理模式&#xff1a;为对象访问提供灵活的控制 引言 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它为其他对象提供一个代替或占位符&#xff0c;以控制对它的访问。 基础知识&#xff0c;java设计模式总体来说设计模式分为三大类&#…

【网络】socket和udp协议

socket 一、六个背景知识1、Q1&#xff1a;在进行网络通信时&#xff0c;是不是两台机器在进行通信&#xff1f;2、端口号3、端口号vs进程PID4、目的端口怎么跟客户端绑定的呢&#xff1f;也就是怎么通过目的端口去找到对应的进程的呢&#xff1f;5、我们的客户端&#xff0c;怎…

uniapp小程序上传pdf文件

<template><view class"mainInnBox"><view class"formBox"><!-- 注意&#xff0c;如果需要兼容微信小程序&#xff0c;最好通过setRules方法设置rules规则 --><u-form :model"form" ref"uForm" :rules&quo…

Window版本nginx修改文件访问句柄数被限制,解决大并发量访问时无法响应问题

目录 一、问题背景 二、问题分析 三、解决办法 一、问题背景 Windows版本因为文件访问句柄数被限制为1024了&#xff0c;当大并发量访问时就会无法响应。会有如下错误提示&#xff1a;maximum number of descriptors supported by select() is 1024 while connecting to ups…

C# 基础语法(一篇包学会的)

C#&#xff08;读作"C Sharp"&#xff09;是一种现代的、通用的面向对象编程语言&#xff0c;由微软公司开发。它结合了C和C的强大特性&#xff0c;并去掉了一些复杂性&#xff0c;使得开发者可以更加高效地编写代码。 一、入坑C# (一) 安装和设置 首先&#xff0c…

【LeetCode】从中序与后序遍历序列构造二叉树

目录 一、题目二、解法完整代码 一、题目 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], …

鸿蒙OpenHarmony Native API【Rawfile】

Rawfile Overview Description: 提供操作rawfile目录和rawfile文件的功能 提供操作rawfile目录和rawfile文件功能 功能包括遍历、打开、搜索、读取和关闭rawfile Since: 8 Version: 1.0 Summary Files File NameDescription[raw_dir.h]提供rawfile目录相关功能[raw…

Debian Linux下rclone挂载谷歌云盘碰到的坑

可能是明月好久没有使用境外服务器挂载境外的云盘缘故吧,今天一个代维客户需要他的Linux服务器挂载谷歌云盘好进行云备份,本来是个很简单的事儿,没想到在rclone连接谷歌云盘的时候卡壳了,可是把明月给难为坏了,搜索到的简体中文教程倒是很多,但没有一个提到这个“坑”,最…

Docker启动PostgreSql并设置时间与主机同步

在 Docker 中启动 PostgreSql 时&#xff0c;需要配置容器的时间与主机同步。可以通过在 Dockerfile 或者 Docker Compose 文件中设置容器的时区&#xff0c;或者使用宿主机的时间来同步容器的时间。这样可以确保容器中的 PostgreSql 与主机的时间保持一致&#xff0c;避免在使…

C语言数组的相关案例

引导案例&#xff1a; 数组的遍历&#xff1a;这里需要注意的是我们在遍历数组时是使用for循环&#xff0c;这里则需要计算数组的长度 计算公式&#xff1a;sizeof(数组名) / sizeof(数组的数据类型) #include<stdio.h> int main() {int arr[] { 1,2,3,4,5,6,7,8 ,9,…

大厂面试-基本功

大厂面试第4季 服务可用性多少个9是什么意思遍历集合add或remove操作bughashcode冲突案例BigdecimalList去重复IDEA Debugger测试框架ThreaLocal父子线程数据同步 InheritableThreadLocal完美解决线程数据同步方案 TransmittableThreadLocal 服务可用性多少个9是什么意思 遍历集…

增值税发票核验API在Java、Python、PHP中的使用教程

在企业经营中&#xff0c;发票扮演着记录交易、报销和纳税的重要角色。然而&#xff0c;由于发票的众多类型和复杂的制作方式&#xff0c;一些企业可能面临着假发票、冒充发票等风险。为了提高财务管理的效率和准确性&#xff0c;以及防范不法行为&#xff0c;增值税发票核验成…

定制QCustomPlot 带有ListView的QCustomPlot 全网唯一份

定制QCustomPlot 带有ListView的QCustomPlot 文章目录 定制QCustomPlot 带有ListView的QCustomPlot摘要需求描述实现关键字: Qt、 QCustomPlot、 魔改、 定制、 控件 摘要 先上效果,是你想要的,再看下面的分解,顺便点赞搜藏一下;不是直接右上角。 QCustomPlot是一款…

Jenkins-zookeeper-docker-xxljob-rancher

文章目录 Jenkins实战1 新建任务需要的配置pipeline Zookeeper基础 Docker基础实操windows11 docker mysql DockerhouseDockerhubxxl-Job基础实战 Rancher基础思考 实战1 Rancher的某个namespace的scale为0 Jenkins 实战 1 新建任务需要的配置pipeline 该代码是Jenkinsfile&…

【接口自动化_08课_Pytest+Yaml+Allure框架】

上节课一些内容 的补充 1、openxl这个方法&#xff0c;第一个元素是从1开始的&#xff0c;不是从0开始 回写的列在程序里写的是11&#xff0c;是因为是固定值 一、1. Yaml入门及应用 1、什么是yaml YAML&#xff08;/ˈjməl/&#xff0c;尾音类似camel骆驼&#xff09;是一…

探索Python日志管理的优雅之道:Loguru库入门指南

探索Python日志管理的优雅之道&#xff1a;Loguru库入门指南 背景&#xff1a;为何选择Loguru&#xff1f; 在Python开发过程中&#xff0c;日志记录是不可或缺的一部分&#xff0c;它帮助我们追踪程序的运行状态&#xff0c;调试程序错误&#xff0c;并记录关键信息。然而&am…