MissingSemester-版本控制系统Git

news2024/10/24 18:57:51

title: Git的底层及基础使用
date: 2024-05-16 12:00:00
categories:

  • MissingSemester
    tags: 版本控制系统Git

版本控制系统Git

什么是Git

​ 版本控制系统 (VCSs) 是一类用于追踪源代码(或其他文件、文件夹)改动的工具。顾名思义,这些工具可以帮助我们管理代码的修改历史;不仅如此,它还可以让协作编码变得更方便。VCS通过一系列的快照将某个文件夹及其内容保存了起来,每个快照都包含了文件或文件夹的完整状态。同时它还维护了快照创建者的信息以及每个快照的相关信息等等。

现代的版本控制系统可以帮助您轻松地(甚至自动地)回答以下问题:

  • 当前模块是谁编写的?
  • 这个文件的这一行是什么时候被编辑的?是谁作出的修改?修改原因是什么呢?
  • 最近的1000个版本中,何时/为什么导致了单元测试失败?

Git 的接口有些丑陋,但是它的底层设计和思想却是非常优雅的。丑陋的接口只能靠死记硬背,而优雅的底层设计则非常容易被人理解

Git 的数据模型

快照

Git 将顶级目录中的文件和文件夹作为集合,并通过一系列快照来管理其历史记录。在Git的术语里:

  • 文件被称作Blob对象(数据对象),也就是一组数据。
  • 目录则被称之为“树”,它将名字与 Blob 对象或树对象进行映射(使得目录中可以包含其他目录)。
  • 快照则是被追踪的最顶层的树。(当前树的整体结构以及数据)

例如,一个树看起来可能是这样的

<root> (tree)
|
+- foo (tree)
|  |
|  + bar.txt (blob, contents = "hello world")
|
+- baz.txt (blob, contents = "git is wonderful")

这个顶层的树包含了两个元素,一个名为 “foo” 的树(它本身包含了一个blob对象 “bar.txt”),以及一个 blob 对象 “baz.txt”。

历史记录建模:关联快照

版本控制系统和快照有什么关系呢?线性历史记录是一种最简单的模型,它包含了一组按照时间顺序线性排列的快照。不过出于种种原因,Git 并没有采用这样的模型。

在 Git 中,历史记录是一个由快照组成的有向无环图。这代表 Git 中的每个快照都有一系列的“父辈”,也就是其之前的一系列快照。注意,快照具有多个“父辈”而非一个,因为某个快照可能由多个父辈而来。例如,经过合并后的两条分支。

在 Git 中,这些快照被称为“提交”。通过可视化的方式来表示这些历史提交记录时,看起来差不多是这样的:

o <-- o <-- o <-- o
            ^  
             \
              --- o <-- o

上面是一个 ASCII 码构成的简图,其中的 o 表示一次提交(快照)。

箭头指向了当前提交的父辈(这是一种“在…之前”,而不是“在…之后”的关系)。在第三次提交之后,历史记录分岔成了两条独立的分支。这可能因为此时需要同时开发两个不同的特性,它们之间是相互独立的。开发完成后,这些分支可能会被合并并创建一个新的提交,这个新的提交会同时包含这些特性。新的提交会创建一个新的历史记录,看上去像这样(最新的合并提交用粗体标记):

o <-- o <-- o <-- o <---- o
            ^            /
             \          v
              --- o <-- o

Git 中的提交是不可改变的。但这并不代表错误不能被修改,只不过这种“修改”实际上是创建了一个全新的提交记录。而引用(参见下文)则被更新为指向这些新的提交。

数据模型及其伪代码表示

以伪代码的形式来学习 Git 的数据模型,可能更加清晰:

// 文件就是一组数据
type blob = array<byte>

// 一个包含文件和目录的目录
type tree = map<string, tree | blob>

// 每个提交都包含一个父辈,元数据和顶层树
type commit = struct {
    parent: array<commit>
    author: string
    message: string
    snapshot: tree
}

这是一种简洁的历史模型。

对象和内存寻址

Git 中的对象可以是 blob、tree 或 commit:

type object = blob | tree | commit

Git 在储存数据时,所有的对象都会基于它们的 SHA-1 哈希 进行寻址。

objects = map<string, object>

def store(object):
    id = sha1(object)
    objects[id] = object

def load(id):
    return objects[id]

Blobs、tree 或 commit 都一样,它们都是对象。当它们引用其他对象时,它们并没有真正的在硬盘上保存这些对象,而是仅仅保存了它们的哈希值作为引用。

git commit 后会得到

$ git commit
[master (root-commit) 15cc653] Add hello.txt
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

这里的15cc653就是commit的快照的哈希值,通过

$ git cat-file -p 15cc653

可以得到

tree 68aba62e560c0ebc3396e8ae9335232cd93a3f60
author Jenwein <rgw127310@gmail.com> 1719917775 +0800
committer Jenwein <rgw127310@gmail.com> 1719917775 +0800
Add hello.txt

也就是之前所讲的一个snapshot的内容,这个tree后面的长串则是这个tree的哈希值,同样使用

$ git cat-file -p 68aba62e560c0ebc3396e8ae9335232cd93a3f60得到

100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad hello.txt

我们已经看到了这个tree中的Blob的哈希,继续git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad我们就得到了

最终这个Blob的内容hello world

树本会包含一些指向其他内容的指针,例如 baz.txt (blob) 和 foo (树)。如果我们用 git cat-file -p 4448adbf7ecd394f42ae135bbeed9676e894af85,即通过哈希值查看 baz.txt 的内容,会直接得到文本内容:

git is wonderful

引用

现在,所有的快照都可以通过它们的 SHA-1 哈希值来标记了。但这也太不方便了,谁也记不住一串 40 位的十六进制字符。

针对这一问题,Git 的解决方法是给这些哈希值赋予人类可读的名字,也就是引用(references)。引用是指向提交的指针。与对象不同的是,它是可变的(引用可以被更新,指向新的提交)。例如,master 引用通常会指向主分支的最新一次提交。

references = map<string, string>

def update_reference(name, id):
    references[name] = id

def read_reference(name):
    return references[name]

def load_reference(name_or_id):
    if name_or_id in references:
        return load(references[name_or_id])
    else:
        return load(name_or_id)

这样,Git 就可以使用诸如 “master” 这样人类可读的名称来表示历史记录中某个特定的提交,而不需要在使用一长串十六进制字符了。

有一个细节需要我们注意, 通常情况下,我们会想要知道“我们当前所在位置”,并将其标记下来。这样当我们创建新的快照的时候,我们就可以知道它的相对位置(如何设置它的“父辈”)。在 Git 中,我们当前的位置有一个特殊的索引,它就是 “HEAD”。

实际上HEAD指向的是快照,而不是工作目录,当前工作目录是独立于快照存在的。HEAD是一个引用,映射到当前的快照,并通过这个引用可以进行查看历史快照(git checkout)

git checkout hello.txt表示切换到当前head指向的hello.txt的状态,相当于撤销当前对文件内容的修改

git checkout 15cc65... #不需要完整哈希值即可找到,当然可以直接checkout引用名 这样会使HEAD指向对应的快照,当通过git log --all --graph --decorate 来查看可视化历史记录(有向无环图)时,可以看到以下内容:

* commit 49ae43f240b4ef1461e5bd20d0c06c1656929bf5 (master)
| Author: Jenwein <rgw127310@gmail.com>
| Date:   Wed Jul 3 17:47:12 2024 +0800
|
|     x
|
* commit 15cc65399db4357b57bdf408ef23ba78dd41396a (HEAD)
  Author: Jenwein <rgw127310@gmail.com>
  Date:   Tue Jul 2 18:56:15 2024 +0800

      Add hello.txt

有一个问题,如果在当前工作目录修改了文件内容但未提交快照,直接checkout会报错,或-f强制提交将会撤销当前的修改。

git diff用来显示与暂存区文件的差异,或者git diff <revision> <filename>: 显示某个文件两个版本之间的差异。直接git diff filename显示当前的工作目录下与HEAD的差异,等同与git diff HEAD filename

不存在说如果当前的HEAD指向的是一个历史快照,当前工作目录与这个HEAD的差异,因为之前提到,修改文件内容但为提交快照是无法checkout 到某个历史快照的。

再如果,你checkout到了某个历史分支,然后这时候的工作目录也会被修改,所以git diff不会有问题。

仓库

最后,我们可以粗略地给出 Git 仓库的定义了:对象引用

在硬盘上,Git 仅存储对象和引用:因为其数据模型仅包含这些东西。所有的 git 命令都对应着对提交树的操作,例如增加对象,增加或删除引用。

当您输入某个指令时,请思考一下这条命令是如何对底层的图数据结构进行操作的。另一方面,如果您希望修改提交树,例如“丢弃未提交的修改和将 ‘master’ 引用指向提交 5d83f9e 时,有什么命令可以完成该操作(针对这个具体问题,您可以使用 git checkout master; git reset --hard 5d83f9e

暂存区

Git 中还包括一个和数据模型完全不相关的概念,但它确是创建提交的接口的一部分。

就上面介绍的快照系统来说,您也许会期望它的实现里包括一个 “创建快照” 的命令,该命令能够基于当前工作目录的当前状态创建一个全新的快照。有些版本控制系统确实是这样工作的,但 Git 不是。我们希望简洁的快照,而且每次从当前状态创建快照可能效果并不理想。例如,考虑如下场景,您开发了两个独立的特性,然后您希望创建两个独立的提交,其中第一个提交仅包含第一个特性,而第二个提交仅包含第二个特性。或者,假设您在调试代码时添加了很多打印语句,然后您仅仅希望提交和修复 bug 相关的代码而丢弃所有的打印语句。

Git 处理这些场景的方法是使用一种叫做 “暂存区(staging area)”的机制,它允许您指定下次快照中要包括那些改动。

合并多分支到同一快照

checkout到历史快照,并对文件进行修改并提交,将处于一个分离的HEAD状态,在这种状态下,如果您切换回其他分支,对文件的修改可能会丢失。如果您想要保留这些更改并在主分支上继续工作,可以创建一个新的分支,如果想要查看或恢复之前在分离HEAD状态下的提交,可以使用 git reflog 命令来查找那些提交的引用。然后,您可以使用找到的提交ID来检出或创建新分支。也就是

git reflog
git checkout -b new-branch-name <commit-id>
git add .
git commit -m "描述您的更改"

git branch

仅执行git branch用来查看当前分支的信息,-vv 以显示更详细的内容

执行git branch cat后指定具体的名字以创建新的分支cat,但目前cat只是一个指向当前位置的引用,所以现在有一个新的引用cat,和HEAD指向同一个提交(两个引用指向同一个提交)

commit 51cbcebc7fba8f0314834099205550d3245dc30c (HEAD -> master ,cat)
Author: Jenwein <rgw127310@gmail.com>
Date:   Tue Oct 8 18:42:09 2024 +0800

    add animal.py

当前正在master分支,如果git checkout cat将会切换到cat分支指向的内容,就会变成

commit 51cbcebc7fba8f0314834099205550d3245dc30c (HEAD -> cat, master)

此时在cat分支修改animal.py文件

import sys

def cat():
    print('Meow!')

def default():
    print('Hello')

def main():
    if sys.argv[1] == 'cat':
        cat()
    else:
        default()

if __name__ == '__main__':
    main();

git diff显示:

$ git diff
diff --git a/animal.py b/animal.py
index ffe2c2e..3abbabe 100644
--- a/animal.py
+++ b/animal.py
@@ -1,10 +1,16 @@
 import sys

+def cat():
+    print('Meow!')
+
 def default():
     print('Hello')

 def main():
-    default()
+    if sys.argv[1] == 'cat':
+        cat()
+    else:
+        default()

 if __name__ == '__main__':
     main();

然后git add & git commit后查看

$ git log --all --graph --decorate --oneline
* 3a6634b (HEAD -> cat) add cat functionality
* 51cbceb (master) add animal.py
* c856d2a yes
* 49ae43f x
| * 7713b36 (otherbranch1) historyqweq
|/
* 15cc653 Add hello.txt

会发现仍然是线性的历史,checkout 到master查看animal,py则是没有cat函数的版本

所以我们可以在不同的开发分支之中跳转。此时如果需要有一个dog方法,dog分支也和cat分支一样是正在开发的分支,可能有人正在分支上开发,我们想要的是基于master分支开始构建dog函数,所以checkout到master分支重新开始

直接git branch dog;git checkout dog有一个简短的命令可以做到同样的效果:git checkout -b dog 此时的效果就是:

$ git log --all --graph --decorate --oneline
* 3a6634b (cat) add cat functionality
* 51cbceb (HEAD -> dog, master) add animal.py
* c856d2a yes
* 49ae43f x
| * 7713b36 (otherbranch1) historyqweq
|/
* 15cc653 Add hello.txt

在当前分支为animal.py添加dog函数后,git add & git commit 后查看当前提交记录:

$ git log --all --graph --decorate --oneline
* 6f9ecc6 (HEAD -> dog) add dog functionality
| * 3a6634b (cat) add cat functionality
|/
* 51cbceb (master) add animal.py
* c856d2a yes
* 49ae43f x
| * 7713b36 (otherbranch1) historyqweq
|/
* 15cc653 Add hello.txt

这样就可以并行开发多个分支,各分支开发完后是要合并的,合并的命令是git merge cat 将cat分支合并到当前分支,合并后提示:

$ git merge cat
Updating 51cbceb..3a6634b
Fast-forward
 animal.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

查看提交记录:

* 6f9ecc6 (dog) add dog functionality
| * 3a6634b (HEAD -> master, cat) add cat functionality
|/
* 51cbceb add animal.py
* c856d2a yes
* 49ae43f x
| * 7713b36 (otherbranch1) historyqweq
|/
* 15cc653 Add hello.txt


此时如果合并dog分支:git merge dog 会提示:

$ git merge dog
Auto-merging animal.py		# 尽力自行合并
CONFLICT (content): Merge conflict in animal.py
Automatic merge failed; fix conflicts and then commit the result.

合并冲突,当你尝试合并两个分支,存在一种并行开发方式可能与当前的一系列变化不兼容。

当打开animal.py时会看见:

import sys

<<<<<<< HEAD
def cat():
    print('Meow!')
=======
def dog():
    print('woof!')
>>>>>>> dog

def default():
    print('Hello')

def main():
<<<<<<< HEAD
    if sys.argv[1] == 'cat':
        cat()
=======
    if sys.argv[1] == 'dog':
        dog()
>>>>>>> dog
    else:
        default()

if __name__ == '__main__':
    main();

这里的

<<<<<<< HEAD
def cat():
    print('Meow!')
=======
def dog():
    print('woof!')
>>>>>>> dog

表示两个分支中冲突的内容,需要手动解决。解决后保存文件,再次将文件git add 后输入 git merge --continue就会完成合并,最终提交记录为:

$ git log --all --graph --decorate --oneline
*   60a7285 (HEAD -> master) Merge branch 'dog'
|\
| * 6f9ecc6 (dog) add dog functionality
* | 3a6634b (cat) add cat functionality
|/
* 51cbceb add animal.py
* c856d2a yes
* 49ae43f x
| * 7713b36 (otherbranch1) historyqweq
|/
* 15cc653 Add hello.txt

远程仓库

是什么

当想要使用git进行多人协同开发时,应当是别人那里也会有一个你的当前git仓库的副本,并且你的本地git仓库知道这个副本的存在,这就是远程仓库。git remote可以列出当前仓库所知道的远程仓库。

常用的github就可以看作是一个远程仓库,在配置其作为你的远程仓库后可以被git感知,那么就会有一些命令用来实现:将本地的代码推送到远程仓库,或将远程仓库的更改拉取到本地仓库。

这里以电脑中的另一个文件夹作为远程仓库。

在另一个位置创建一个文件夹remote 回到之前的仓库内,使用git remote add <name> <url>来配置远程仓库,让本地仓库知道远程仓库的存在。如果只使用了一个仓库,那么使用origin作为<name> (约定俗成的名字),<url>则用来填地址,github的url,在这里则只是刚才创建的远程仓库的目录,所以最终为

git remote add origin ../remote

然后再查看当前已知的远程仓库,发现成功配置。

$ git remote
origin

与远程仓库交互的命令

  • git push:将更改从本地发送到远程仓库

    使用:git push <remote> <local branch>:<remote branch>

    <local branch>的更改push到<remote>仓库的<remote branch>分支,如果远程仓库没有该分支将创建分支。

    在这里将是:

    $ git push origin master:master # 在远程仓库上创建一个名为master的分支
    Enumerating objects: 21, done.
    Counting objects: 100% (21/21), done.
    Delta compression using up to 12 threads
    Compressing objects: 100% (15/15), done.
    Writing objects: 100% (21/21), 1.96 KiB | 400.00 KiB/s, done.
    Total 21 (delta 2), reused 0 (delta 0), pack-reused 0
    To ../remote
     * [new branch]      master -> master
    
    

    成功推送后,log会有一些新信息:

    $ git log --all --graph --decorate --oneline
    *   60a7285 (HEAD -> master, origin/master) Merge branch 'dog'
    |\
    | * 6f9ecc6 (dog) add dog functionality
    * | 3a6634b (cat) add cat functionality
    |/
    * 51cbceb add animal.py
    * c856d2a yes
    * 49ae43f x
    | * 7713b36 (otherbranch1) historyqweq
    |/
    * 15cc653 Add hello.txt
    
    

    标志在origin上有一个分支master,与当前的master分支指向相同的位置。

    现在试着修改本地仓库文件的内容,这里我修改了print的信息的大小写,然后提交:

    $ git log --all --graph --decorate --oneline
    * 054953e (HEAD -> master) x
    *   60a7285 (origin/master) Merge branch 'dog'
    |\
    | * 6f9ecc6 (dog) add dog functionality
    * | 3a6634b (cat) add cat functionality
    |/
    * 51cbceb add animal.py
    * c856d2a yes
    * 49ae43f x
    | * 7713b36 (otherbranch1) historyqweq
    |/
    * 15cc653 Add hello.txt
    
    
    

​ 远程仓库仍停留在之前的快照,所以查看远程仓库的人只能看到之前的内容,不会获得这个修改

  • git clone

    克隆一个仓库到本地

    $ git clone ./remote demo2
    Cloning into 'demo2'...
    done.
    
    

    那么此时就可以把demo和demo2看作是两个人在各自机器上的仓库,其中一个人正在与远程仓库交互,对于之前的在demo中的最后一次的修改只存在与demo中,demo2并不会有最新的提交

然后就可以使用git push来将demo的最新提交同步到remote中,但是每次都输入git push origin master:master是很累的,git中有多种方法可以将本地分支与远程仓库的分支对应起来

  • git branch --set-upstream-to=origin/master 用来设置当前分支的上游分支(upstream branch)

    在 Git 中,上游分支是指当前分支要跟踪的远程分支,也就是你通常会从那里拉取(pull)更新,或者向它推送(push)更改的分支

    $ git branch --set-upstream-to=origin/master
    branch 'master' set up to track 'origin/master'.
    
    

    具体来说,这条命令的作用是将当前分支的上游分支设置为远程的 origin/master 分支

    • origin 是远程仓库的默认名称,master 是它的主分支。
    • 这样,你以后在当前分支执行 git pullgit push 时,不用手动指定远程分支,Git 会自动知道需要与 origin/master 交互。

    新版本的 Git 中,--set-upstream-to 的作用与 git branch -u 等价。通过git branch -vv可以看到:

     $ git branch -vv
      cat          3a6634b add cat functionality
      dog          6f9ecc6 add dog functionality
    * master       054953e [origin/master] x
      otherbranch1 7713b36 historyqweq
    
    

    这时我们就可以直接使用git push来推送更改。

    远程仓库已经被更改,现在来关注demo2

  • git fetch

    Git 中用于从远程仓库获取最新更改的命令。它会从远程仓库下载所有的提交、文件和引用(如分支、标签等),但不会自动合并或修改你当前的工作目录。

    git fetch [remote] [branch]

    $ git fetch
    remote: Enumerating objects: 5, done.
    remote: Counting objects: 100% (5/5), done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
    Unpacking objects: 100% (3/3), 284 bytes | 5.00 KiB/s, done.
    From E:/./remote
       60a7285..054953e  master     -> origin/master
    
    

    查看log:

    $ git log --all --graph --decorate --oneline
    * 054953e (origin/master, origin/HEAD) x
    *   60a7285 (HEAD -> master) Merge branch 'dog'
    |\
    | * 6f9ecc6 add dog functionality
    * | 3a6634b add cat functionality
    |/
    * 51cbceb add animal.py
    * c856d2a yes
    * 49ae43f x
    * 15cc653 Add hello.txt
    
    

    发现当前仍是指向master,master并没有被修改/合并,但是origin/master是已经指向这个最新的提交的,然后就可以通过git merge 将master上移到最新位置。有一个组合命令 git pull相当于先执行git fetch再执行git merge

    $ git pull
    Updating 60a7285..054953e
    Fast-forward
     animal.py | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    

    最后在log可以看到

    $ git log --all --graph --decorate --oneline
    * 054953e (HEAD -> master, origin/master, origin/HEAD) x
    *   60a7285 Merge branch 'dog'
    |\
    | * 6f9ecc6 add dog functionality
    * | 3a6634b add cat functionality
    |/
    * 51cbceb add animal.py
    * c856d2a yes
    * 49ae43f x
    * 15cc653 Add hello.txt
    
    

至此,所有仓库之间的更改已经同步。

other

  • 当想要git clone一个巨大的仓库时,可以添加参数--shallow,只会clone最新的快照而不会获取完整的历史提交。

  • 如果当前修改了文件,比如在文件中有两处修改:

    import sys
    
    def cat():
        print('meow!')
        
    def dog():
        print('Woof!') # place 1
    
    def default():
        print('hello')
    
    def main():
        print('debug')	# place 2
        if sys.argv[1] == 'cat':
            cat()
        if sys.argv[1] == 'dog':
            dog()
        else:
            default()
    
    if __name__ == '__main__':
        main();
    
    

    对于这次的修改,我只想要保留第一处的修改,而不保留第二处的调试信息,一可以直接修改文件删除调试信息,二可以交互式暂存git add -p animal.py

    不想要全部保存,所以s,分为多个判断,保留第一处,丢弃第二处。

  • git stash将工作目录恢复到上一次提交的状态,但是已经的修改并没有被删除,可以通过git stash pop 重新展示这个修改

  • git bisect 检索历史

  • .gitignore 将你不关心的文件加入gitignore文件内,避免提交。

内容来自https://missing-semester-cn.github.io/2020/version-control/#snapshots

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

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

相关文章

2024年第九期 | CCF ODC《开源战略动态月报》

点击蓝字 关注我们 CCF Opensource Development Committee 导 读 2024年第九期CCF ODC《开源战略动态月报》共摘选33篇文章&#xff0c;分为8个版块&#xff1a;ODC专栏、开源政策、理论观点、产业动态、技术项目、开源组织与机构、开源报告通讯会议以及RISC-V专栏&#xff0c;…

Webserver(1)Linux开发环境搭建

目录 配置软件虚拟机中安装ubuntu安装ubuntu18的操作系统 安装VM tools安装XshellVscode远程连接到虚拟机 配置软件 VMwareVScodeg安装ubuntu 18.04.iso 或者镜像版本 XShellXFTP 虚拟机中安装ubuntu 安装ubuntu18的操作系统 开启虚拟机 选择中文简体 安装VM tools 打开v…

V2X介绍

文章目录 什么是V2XV2X的发展史早期的DSRC后起之秀C-V2XC-V2X 和DSRC 两者的对比 什么是V2X 所谓V2X&#xff0c;与流行的B2B、B2C如出一辙&#xff0c;意为vehicle to everything&#xff0c;即车对外界的信息交换。车联网通过整合全球定位系统&#xff08;GPS&#xff09;导…

Java基础-注解机制详解

文章目录 注解基础Java内置注解内置注解- Override内置注解 - Deprecated内置注解 - SuppressWarnings 元注解元注解 - Target元注解 - Retention & RetentionTarget元注解 - Documented元注解 - Inherited 注解与反射接口自定义注解 深入理解注解Java8提供了哪些新的注解&…

如何高效集成聚水潭数据至MySQL-技术案例解析

如何高效集成聚水潭数据至MySQL-技术案例解析 聚水潭数据集成到MySQL的技术案例分享 在本次技术案例中&#xff0c;我们将探讨如何通过轻易云数据集成平台&#xff0c;将聚水潭的店铺信息高效地集成到MySQL数据库中。具体方案为“聚水潭-店铺信息查询-->BI崛起-店铺信息表”…

NewStarCTF 2023 公开赛道 Web week1-week2

目录 week1 泄漏的秘密 Begin of Upload Begin of HTTP ErrorFlask ​Begin of PHP R!C!E! EasyLogin ​week2 游戏高手 include 0。0 ez_sql ​Unserialize&#xff1f; Upload again! R!!C!!E!! week1 泄漏的秘密 使用ctf-scan.py&#xff08;https://gith…

随身 WiFi 通过 USB 连接路由器共享网络 扩展网络覆盖范围

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 之前几期随身 WiFi 的玩法都是关于骁龙 410 板子的随身 WiFi&#xff0c;可以刷 Debian 之后作为小型家庭服务器&#xff0c;跑跑 Docker&#xff0c;当当打印服务器什么的。而今天介绍的玩法用的是正儿八…

LockBit多版本简单对比

LockBit家族介绍 LockBit是一种非常知名且活跃的勒索软件家族&#xff0c;自2019年首次被发现以来&#xff0c;已经经历了多个版本的演变。它以其高效的加密速度和自动化攻击能力而闻名&#xff0c;对各类组织构成了严重威胁。 发展时间线如下&#xff1a; 时间 事件 2019年…

linux之网络子系统-路由子系统(3)路由表

一、路由表 linux 路由子系统代码量虽说不是很多&#xff0c;但是难度还是有的&#xff0c;最近在分析路由子系统这一块&#xff0c;对它的框架有了基本的了解。 路由子系统可以划分为三个部分&#xff1a;路由缓存、路由策略、路由表。前两个部分已经分析完&#xff0c;这里…

解决Vmware自动调整分辨率的问题

打开菜单&#xff1a;虚拟机→设置→硬件→显示器→显示缩放比例→勾选拉伸模式 Virtual Machine

【Linux】————磁盘与文件系统

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;Linux 创作时间 &#xff1a;2024年10月17日 一、磁盘的物理结构 磁盘的物理结构如图所示&#xff1a; 其中具体的物理存储结构如下&#xff1a; 磁盘中存储的基本单位为扇区&#xff0c;一个扇区的大小一般为512字…

【python爬虫实战】爬取全年天气数据并做数据可视化分析!附源码

由于篇幅限制&#xff0c;无法展示完整代码&#xff0c;需要的朋友可在下方获取&#xff01;100%免费。 一、主题式网络爬虫设计方案 1. 主题式网络爬虫名称&#xff1a;天气预报爬取数据与可视化数据 2. 主题式网络爬虫爬取的内容与数据特征分析&#xff1a; - 爬取内容&am…

【软件工程】软件工程入门

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;软件开发必练内功_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

多模态大语言模型(MLLM)-Blip3/xGen-MM

论文链接&#xff1a;https://www.arxiv.org/abs/2408.08872 代码链接&#xff1a;https://github.com/salesforce/LAVIS/tree/xgen-mm 本次解读xGen-MM (BLIP-3): A Family of Open Large Multimodal Models 可以看作是 [1] Blip: Bootstrapping language-image pre-training…

uniapp:uni.createSelectorQuery函数结合vue的watch函数使用实例

提醒 本文实例是使用uniapp进行开发演示的。 一、需求场景 在开发详情页面时&#xff0c;不同产品描述文案不同&#xff0c;有的文案比较长&#xff0c;需求上要求描述文案最多展示4行文案&#xff0c;少于4行文案&#xff0c;全部显示&#xff0c;此UI高度自动适配&#xff0c…

智慧城管综合管理系统源码,微服务架构,基于springboot、vue+element+uniapp技术开发,支持二次开发

智慧城管源码&#xff0c;智慧城管执法办案系统源码 智慧城管综合执法办案平台是智慧城市框架下&#xff0c;依托物联网、云计算、多网融合等现代化技术&#xff0c;运用数字基础资源、多维信息感知、协同工作处置、智能化辅助决策分析等手段&#xff0c;形成具备高度感知、互联…

pikachu靶场-Cross-Site Scripting(XSS)

sqli-labs靶场安装以及刷题记录-dockerpikachu靶场-Cross-Site Scripting pikachu靶场的安装刷题记录反射型xss(get)反射型xss(post)存储型xssDOM型xssDOM型xss-xxss盲打xss之过滤xss之htmlspecialcharsxss之href输出xss之js输出 pikachu靶场的安装 刷题记录 反射型xss(get) …

《什么是大模型、超大模型和 Foundation Model?》

前言 大模型旨在解决人类面临的各种问题,提高人类的生产力和生活质量。是一门涉及计算机科学、数学、哲学、心理学等多个领域的交叉学科,旨在研究如何使计算机能够像人类一样思考、学习、推理和创造。大模型的出现,让很多产业人士认为这项技术会改变信息产业格局,即基于数…

解码专业术语——应用系统开发项目中的专业词汇解读

文章目录 引言站点设置管理具体要求包括&#xff1a; Footer管理基于URL的权限控制利用数据连接池优化数据库操作什么是数据连接池&#xff1f;优化的优势 利用反射改造后端代码&#xff0c;AJAX反射的作用及其在后端代码中的应用AJAX 实现前后端无刷新交互 引言 创新实践项目二…

ThingsBoard规则链节点:Delete Attributes节点详解

引言 删除属性节点简介 用法 含义 应用场景 实际项目运用示例 智能家居安全系统 物流跟踪解决方案 工业自动化生产线 结论 引言 ThingsBoard是一个开源的物联网平台&#xff0c;它提供了设备管理、数据收集与处理以及实时监控等功能。其中&#xff0c;规则引擎是其核心…