Jenkins环境搭建与实战

news2024/9/21 0:48:51

Jenkins环境搭建与实战

  • 1、Jenkins
  • 2、GItLab的安装
    • 2.1、安装依赖
      • 2.1.1、CentOS8安装报错
      • 2.1.2、找不到对应包安装报错
    • 2.2、配置镜像
    • 2.3、安装gitlab
  • 3、安装Jenkins
  • 4、Maven安装
    • 4.1、出现报错 The JAVA_HOME environment variable is not defined correctly的错误
  • 5、Jenkins 通过Git+Maven构建Jar包
    • 5.1、报错 No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
  • 6、构建发布
    • 6.1、添加 Publish over ssh插件
    • 6.2、修改构建配置
    • 6.3、nohup命令
  • 7、构建前清理操作
    • 7.1、pre steps 构建前操作
    • 7.2、构建触发器
  • 8、回调自动构建项目
    • 8.1、Jenkins配置
    • 8.2、gitlab配置
  • 9、邮件通知设置
  • 10、Docker自动化部署
    • 10.1、采用dockerfile进行构建容器
    • 10.2、外挂jar包创建容器
    • 10.3、Jenkins与docker配合使用
    • 10.4、Jenkins配合dockerfile进行构建
  • 11、Jenkins集群部署
    • 11.1、Jenkins多节点部署
  • 12、pipeline流水线

1、Jenkins

Jenkins是一个可扩展的持续集成引擎。

持续集成,就是通常所说的CI(Continues Integration),可以说是现代软件技术开发的基础。

持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也意味着每天可能会发生多次集成。

每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。

2、GItLab的安装

2.1、安装依赖

sudo yum install -y curl policycoreutils-python openssh-server perl
systemctl enable sshd
systemctl start sshd

2.1.1、CentOS8安装报错

本地环境安装报错:(本地环境:CentOS8)
Error: Failed to download metadata for repo ‘appstream’: Cannot prepare internal mirrorlist: No URLs in mirrorlist

自2022年1月31日起,CentOS团队从官方镜像中移除CentOS 8的所有包,但软件包仍在官方镜像上保留一段时间。现在被转移到https://vault.centos.org。如需继续运行旧CentOS 8,可以在/etc/yum.repos中更新repos.d,使用vault.centos.org代替mirror.centos.org。需要执行以下代码

sudo sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sudo sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

2.1.2、找不到对应包安装报错

Error: Unable to find a match: policycoreutils-python
产生这个错误的原因是未配置yum源,所以需要安装 EPEL 源

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

你要用python2还是python3?改为

sudo yum install -y curl policycoreutils-python3 openssh-server perl

2.2、配置镜像

curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash

2.3、安装gitlab

EXTERNAL_URL="http://192.168.60.128" yum install -y gitlab-jh
# 通过命令进行启动、查看状态、停止
gitlab-ctl start
gitlab-ctl status
gitlab-ctl stop

启动之后直接访问虚拟机的ip,如果无法访问可以查看虚拟机的防火墙的状态,将防火墙关闭即可

# 查看防火墙状态
systemctl status firewalld
# 关闭防火墙
service firewalld stop

访问虚拟机ip之后就可以直接访问到我们安装的GItlab了,在安装的时候默认会给配置好一个root用户,直接进入该文件当中,通过cat命令查看文件,得到密码直接登录即可。

在这里插入图片描述
通过docker进行安装

docker run --detach \
  --hostname 192.168.60.128 \
  --publish 443:443 --publish 80:80 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/tools/gitlab/etc/gitlab:Z \
  --volume $GITLAB_HOME/logs:/tools/gitlab/log/gitlab:Z \
  --volume $GITLAB_HOME/data:/tools/gitlab/opt/gitlab:Z \
  --shm-size 256m \
  registry.gitlab.cn/omnibus/gitlab-jh:latest

3、安装Jenkins

在官网上进行下载对应的war包:https://www.jenkins.io/zh/download/

下载完成之后将对应的war包传到虚拟机上,通过java -jar命令来进行启动war包,前提是要有jdk的环境。jenkins默认启动是使用8080端口,如果该端口被占用,也可以修改启动端口,命令如下

java -jar jenkins.war --httpPort=8081

启动之后访问虚拟机ip+8081端口,需要填入密码,直接获取启动初始化的密码

在这里插入图片描述

进入之后安装推荐的插件即可,等待安装插件之后,创建一个管理员用户,到这里Jenkins就安装好了,

4、Maven安装

maven安装只需要从官网上下载一个gz的压缩包,之后通过 tar -zxvf命令进行解压即可,maven会依赖jdk环境,

4.1、出现报错 The JAVA_HOME environment variable is not defined correctly的错误

修改下 /etc/profile的 java_home的路径 可以使用了

vi  /etc/profile

# 检查JAVA_HOME
export JAVA_HOME=/training/jdk-19.0.1
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin;

# 刷新配置
source /etc/profile

5、Jenkins 通过Git+Maven构建Jar包

首先我们在Jenkins当中安装一个maven的插件,在Manage Jenkins里面找到插件管理,
在这里插入图片描述
进去之后在可选插件当中搜索maven找到对应的插件进行安装即可

在这里插入图片描述
之后新建一个item(任务)在安装该插件之后,我们可选一个构建Maven项目,任务名称任填,填完之后直接下一步,在这里我们本地也启动了gitlab,我们先搞个最简单的springboot项目并且提交到gitlab上(这一步本文就不赘述了),之后就是相关的配置了,第一个是源码的配置,指定好git地址和对应的分支

在这里插入图片描述
并且在 Manager Jenkins当中的Global Tool Configuration进行配置maven,可以使用虚拟机上安装了的,也可以使用默认提供的

在这里插入图片描述
到这里全部配置好了之后保存配置,在操作台上面直接启动该任务即可。

5.1、报错 No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

在终端安装jdk,使用命令安装,安装完成之后再在jenkins当中进行构建

yum install -y  java-devel

在构建打包完成后,查看输出可以看到打出的war包存在该目录下,cd进入到对应目录,通过java -jar命令启动war(jar)包进行验证,无法访问的话应该是对应端口没有开放,通过防火墙放开对应端口即可

[INFO] Installing /root/.jenkins/workspace/service-lzq-test/target/service-lzq-test-1.0-SNAPSHOT.war to /root/.m2/repository/org/example/service-lzq-test/1.0-SNAPSHOT/service-lzq-test-1.0-SNAPSHOT.war
[INFO] Installing /root/.jenkins/workspace/service-lzq-test/pom.xml to /root/.m2/repository/org/example/service-lzq-test/1.0-SNAPSHOT/service-lzq-test-1.0-SNAPSHOT.pom

6、构建发布

6.1、添加 Publish over ssh插件

首先我们需要在jenkins里面安装一个新的插件 publish over ssh ,安装完成之后在Configure System当中对安装的publish over ssh插件进行配置,指定对应部署的虚拟机

在这里插入图片描述

6.2、修改构建配置

在任务配置当中添加一个ssh相关的配置,将前面打包之后的war包推送到服务器(这里我用的都是同一台虚拟机),推送到根目录下面,最后配置一个启动war包的命令,这里启动的war包是后台启动的,可以使用jps命令还进行查看服务是否启动。
在这里插入图片描述
构建完成会发现,他虽然是构建了一个war包并且推送到服务器上启动了,但是发现控制台输出的却存在warning,我们可以看一下报warning或者error的地方的日志

ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,013 ms]

这个ERROR主要是脚本没有正常的关闭,jenkins等待120秒后超时关闭了。这里出现这个问题的原因还是启动war包的脚本的问题,先了解一下nohup命令。

6.3、nohup命令

首先我们看执行war包的脚本命令,nohup的用途是不挂断地运行命令。而最后一个&是表示在后台运行

如果你正在运行一个进程,而这个进程可能要运行很久,比如每小时统计个数据,统计个七七四十九个小时,那么账户可能在这期间就退出了,终端也关闭了,而你的进程不能够结束,那么这个命令【可以让你在退出账户/关闭终端之后继续运行相应的进程】。

如何修改这个问题呢,需要修改启动war包的命令,修改之后重新构建一下查看效果

nohup java -jar /root/service*.war >my.log 2>&1 &

这里通过 >my.log 指定对应的日志输出的文件

  • 标准输入(stdin):代码为0,使用<或<<;
  • 标准输出(stdout):代码为1,使用>或>>;
  • 标准错误输出(stderr):代码为2,使用2>或2>>
  • 覆盖写 >
  • 追加写 >>

7、构建前清理操作

在jenkins进行构建推送启动jar包操作,会很显然的存在问题,那就是在前一次构建之后,再一次进行构建由于上一次启动的服务并没有停止,而再次推送jar包进行启动肯定是启动不了的,在这里jenkis当中就有一个构建前操作,

7.1、pre steps 构建前操作

在pre steps 当中还是和构建后一样,添加一个ssh的操作,连接上远程机,并且这里直接通过sh脚本来进行操作,可以看到我们直接执行根目录下的x.sh脚本并且附带一个参数进去,

在这里插入图片描述

之后就是编写脚本了,脚本内容也不过多解释了,分别的操作是

  1. 先写入一个入参的txt文本文档
  2. 删除对应jar(war)包和log日志文件
  3. 找当前服务是否还是启动状态,找到其pid
  4. 判断是否存在pid,存在即kill杀死进程
#!/bin/bash

rm -rf  $1.txt

echo "开始输出脚本日志">$1.txt

rm -rf $1*.war
rm -rf $1*.log

# 获取执行命令传入的参数

echo $1

# 过滤出该jar包的pid (过滤出包含service-lzq-test不包含grep) 并且通过awk找到第二个数据进行输出
# ps -ef | grep service-lzq-test | grep -v grep | awk '{printf $2}'

# 同上 过滤出包含 service-lzq-test 并且包含 java -jar
# pid=`ps -ef | grep service-lzq-test | grep 'java -jar' | awk '{printf $2}'`

# 通过传入的参数控制查找的jar或war包
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`

echo $pid>>$1.txt

if [ -z $pid ];
	then
		echo "$1 not start">>$1.txt
	else
		kill -9 $pid
		echo "$1 stoping ....">>$1.txt
fi

7.2、构建触发器

  • 快照依赖构建/Build whenever a SNAPSHOT dependency is built
    当依赖的快照被构建时执行本job
  • 触发远程构建 (例如,使用脚本)
    远程调用本job的restapi时执行本job
  • job依赖构建/Build after other projects are built
    当依赖的job被构建时执行本job
  • 定时构建/Build periodically
    使用cron表达式定时构建本job
  • 向GitHub提交代码时触发Jenkins自动构建/GitHub hook trigger for GITScm polling
    Github-WebHook出发时构建本job
  • 定期检查代码变更/Poll SCM
    使用cron表达式定时检查代码变更,变更后构建本job

8、回调自动构建项目

8.1、Jenkins配置

在jenkins配置当中有一个构建触发器,我们先手动加一个身份令牌

在这里插入图片描述
这个身份令牌是做什么的呢?在下面jenkins提供了一个url我们直接访问对应的地址并且携带上我们刚才加上的令牌。也就是http://192.168.60.128:8081/job/service-lzq-test/build?token=service-lzq-test 这个地址,我们会发现他会自动再去帮我们构建一次这个任务,

当然了,这是在同一个浏览器当中,我们是登录过jenkins的了,而当我们将该地址换个浏览器访问,就会跳转到登录界面,这个该如何处理呢?这个时候我们需要安装一个jenkins的插件 Build Authorization Token Root 。在插件的介绍当中我们可以看到我们只需要访问改地址即可

在这里插入图片描述
这样我们只需要修改连接地址即可:http://192.168.60.128:8081/buildByToken/build?job=service-lzq-test&token=service-lzq-test 填入对应的任务名称和job名称

8.2、gitlab配置

在gitlab当中我们进入到对应的项目当中选择 setting -> Webhooks 添加一个,url就填上面配置好的url,选择推送事件和合并事件触发该hook,添加如果出现该提示 Url is blocked: Requests to localhost are not allowed 无法添加,切到管理员该选项下,勾选该选项即可。

在这里插入图片描述
最后我们直接给springboot加一个请求并且推送gitlab来进行查看jenkins是否会在推送代码之后进行自动构建

9、邮件通知设置

在进行构建的时候我们可以在构建完成之后发送邮件进行通知。首先我们需要一个发送邮件的服务器,这里我们使用网易邮箱免费的SMTP进行发送邮件,注册邮箱之后,在设置当中将这两个进行开启,开启会要扫码发送短信,按照提示完成之后会得到一个类似JVMAWFMWRUVXJWWQ的码,这个先保存好,后面需要用到,

在这里插入图片描述

而后进入到jenkins当中的manager jenkins -> Configure System当中,第一步配置Jenkins Location

在这里插入图片描述
第二步配置发送邮件设置,并且往下滑可以找到一个 Default Recipients (默认收件人)这个地方我们可以用自己别的邮箱进行收件(如QQ邮箱、foxmail等)

在这里插入图片描述
最后一步,配置邮件通知

在这里插入图片描述
到这里就配置完成了,然后我们只需要给任务添加一个配置(构建完成后发送邮件操作),进入任务配置页面,在构建后操作添加一个 Editable Email Notification 暂时采用默认配置。然后直接手动构建项目试一下

未收到邮件 An attempt to send an e-mail to empty list of recipients, ignored. 试图向空的收件人列表发送电子邮件,已被忽略。

这个时候需要检查:(可能是以下某个原因导致)

  • 通过Manage Jenkins进入Configure System 查看Default Recipients这一栏是否填写了收件人
  • 查看Post-build Actions(构建后操作)里有没有添加Editable Email Notification这个功能,并且不要勾选Disable Extended Email Publisher(禁用扩展电子邮件发布服务器)这个选项栏。查看Project Recipient List(项目收件人列表)这一栏有没有填写收件人

10、Docker自动化部署

10.1、采用dockerfile进行构建容器

使用docker命令报错 cannot connect to the docker daemon at unix ///var/run/docker.sock. Is the docker daemon running?
执行命令 dockerd,问题解决。

在进行jar包打包的过程当中我们可以使用openjdk来作为其依赖,首先编写一个dockerfile,在这里对于docker的介绍就不阐述了,docker相关见 该文(单击跳转)

FROM openjdk:11
EXPOSE 8888

WORKDIR /root

ADD jar/service-lzq-test*.war /root/app.war

ENTRYPOINT ["java","-jar","/root/app.war"]

打包镜像: docker build -t service-lzq-test .
创建并运行容器:docker run -d --name service-zhwg-lzq -p 8888:8888 service-lzq-test

10.2、外挂jar包创建容器

还可以直接将jar包挂到docker上进行创建容器进行启动

docker run -d -p 8888:8888 --name service-lzq-test-out -v /root/jar/service-lzq-test-1.0-SNAPSHOT.war:/app.jar openjdk:11 java -jar app.jar

10.3、Jenkins与docker配合使用

在前面我们已经创建好了容器,jenkins与docker配合使用,本质上与前面配置jar包启动没有很大区别,只是将步骤进行略微调整。

  • 在构建之前我们需要执行将jar包删除、将容器停止
  • 然后推送jar包到服务器,再将容器启动即可

10.4、Jenkins配合dockerfile进行构建

构建前操作:

rm rf *
docker stop service-lzq-test
docker rm service-lzq-test
docker rmi service-lzq-test

并且我们将dockerfile文件加到git仓库当中,在构建的时候将dockerfile也发给远程机,直接执行docker命令进行打包镜像和启动容器

docker build -t service-lzq-test .
docker run  -d --name service-zhwg-lzq -p 8888:8888 service-lzq-test

11、Jenkins集群部署

11.1、Jenkins多节点部署

在之前都是采用一台虚拟机来进行配置任务进行启动,对于多节点来说需要多台虚拟机,首先将之前的虚拟机克隆一份,并且修改对应的ip

而后启动jenkins之后,在jenkins当中 Manager Jenkins -> Manage nodes and clouds 当中新增一个节点,节点配置就填我们克隆出来的机器的相关配置,(包含ip、账号密码,其他任意)而后保存,可以看到,这个node-1节点就是新增的节点

在这里插入图片描述
并且在任务配置当中:General -> 勾选 在必要的时候并发构建,这样就完成了jenkins构建负载了。

12、pipeline流水线

使用流水线可以让我们的任务从ui手动操作,转换为代码化,像docker的dockerfile一样,从shell命令到配置文件,更适合大型项目,可以让团队其他开发者同时参与进来,同时也可以编辑开发Jenkinswebui不能完成的更复杂的构建逻辑,作为开发者可读性也更好。

完整语法

pipeline:整条流水线
agent:指定执行器
stages:所有阶段
stage:某一阶段,可有多个
steps:阶段内的每一步,可执行命令

在jenkins的插件当中可以安装一个blue Ocean插件,这里提供了一个web页面进行查看

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

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

相关文章

SWIFT Framework .NET 2023

SWIFT Framework .NET 2023 Latest 2023 specification messages.Improves parsing..NET Framework 4.8 release.Performance updates.Improves handling of special characters. SWIFT Framework.NET是一个用于在组织信息系统基础架构中捕获、验证和处理SWIFT消息的系统。SWI…

3.5主存储器与CPU的连接

文章目录一、引子二、单块存储芯片与CPU的连接三、多块存储芯片与CPU的连接1.现代计算机2.命名3.增加主存的存储字长--位扩展&#xff08;1&#xff09;单块&#xff08;2&#xff09;多块4.增加主存的存储字数--字扩展&#xff08;1&#xff09;单块&#xff08;2&#xff09;…

19行列式公式和代数余子式

行列式公式 学习了关于行列式的这么多性质&#xff0c;现在我们有能力推导二阶行列式公式了&#xff1a; 观察上面的推导过程&#xff0c;不难发现&#xff0c;行列式的值等于使用性质3.b 分解后所得的那些非零行列式的和&#xff0c;所谓的非零行列式也即该行列式各行各列都…

【算法基础】大整数加减乘除法(高精度)

大整数的思想:用数组存储大整数(超长整数),比如存储1000位的整数只需要开辟一个长度为1000的数组(C++通常使用vector),今天将通过OJ例题来介绍高精度问题。(完全0基础的先建议自主学习一下,本博客默认已了解大致思想) 一、 大整数加法(大整数 + 大整数) (一)Qu…

6 逻辑斯蒂回归

文章目录回归问题和分类问题问题提出逻辑回归二分类问题逻辑函数与线性回归方程的不同模型变化loss函数不同BCEloss函数的介绍课程代码课程来源&#xff1a; 链接课程文本来源借鉴&#xff1a; 链接以及&#xff08;强烈推荐&#xff09; Birandaの回归问题和分类问题 有监督学…

Docker安装Tomcat服务器

Docker安装Tomcat服务器查看tomcat镜像下载 tomcat镜像启动tomcat容器浏览器访问容器中的tomcat1 查看ip2 查看容器是否启动3 进入容器重启容器浏览器访问查看tomcat镜像 docker search tomcat下载 tomcat镜像 咱直接下载最近版本的tomcat镜像 docker pull tomcat查看一下本…

芯片验证系列——激励(stimulus)

对于芯片验证&#xff0c;主要的挑战在于&#xff1a;1.如何打出所有可能的激励灌给DUT&#xff1b;2.如何在各种可能得激励情况下&#xff0c;判断出不符合硬件描述的行为。本文单单聚焦于一些关于构造stimulus方面的想法吧&#xff0c;结合了红皮书, writing testbench和项目…

储殷黄日涵教授《丁香花》唐磊推荐杨语莲,意味拜师赵本山有望吗

熟悉娱乐圈的人都知道&#xff0c;这个圈子包含有很多潜规则&#xff0c;尤其是一些女艺人&#xff0c;想要有所成就&#xff0c;不是有才华就可以的。就拿音乐人杨语莲来说&#xff0c;她是一个非常有才华的歌手&#xff0c;然而就因为不接受潜规则&#xff0c;至今仍是歌红人…

设计模式:单例模式

1、单例模式 单例模式是指在整个系统生命周期内&#xff0c;保证一个类只能产生一个实例&#xff0c;确保该类的唯一性。 为什么需要单例模式 单例模式是为了保证程序的线程安全。 线程安全&#xff1a; 在拥有共享数据的多条线程并行执行的程序中&#xff0c;线程安全的代…

cuda和pytarch的安装-参考官网的安装-较为通用

文章目录cuda 安装PyTorch 1.x版本安装cuda 安装 官网&#xff1a;cuda各个版本安装教程 选择相应版本点击版本前方链接就可以进入安装教程页面 例如&#xff1a;我想要为ubuntu系统安装一个11.7版本的cuda&#xff0c;则选择11.7版本的连接&#xff0c;然后进入安装教程页面…

深度学习之优化算法

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 目录 一、优化算法与深度学习 1、优化算法对于深度学习的意义 2、优化算法与深度学习的关系 3、优化算法在深度学习中的主要挑…

如何用Spring整合MyBatis和Junit

Spring整合MyBatis和Junit一. 整合MyBatis1. 目录&#xff1a;2. pom.xml&#xff1a;3. domain层&#xff1a;4. dao层&#xff1a;5. service层&#xff1a;AccountService接口类&#xff1a;AccountServiceImpl实现类&#xff1a;6. jdbc.properties配置文件&#xff1a;7. …

HBase基于HDFS上是如何完成增删改查功能的

HDFS只支持文件append操作, 而依赖HDFS的HBase如何完成增删改查功能&#xff1f; 1.如何理解? 1.这句话有个更专业的说法&#xff1a;HDFS 采用数据流方式来访问文件&#xff0c;只支持单个客户端向一个文件追加数据. 2 上半句话&#xff0c;访问文件不外乎读和写&#xff0…

SecureCRT for mac的坑

最新macOS升级到13&#xff08;原来是11&#xff0c;一直没升&#xff09;&#xff0c;升级之后输入法和SecureCRT挂了。 记录一下SecureCRT&#xff0c;备忘 1、第一个坑居然是下载 网上找破解版&#xff0c;想找个新一点的版本&#xff0c;发现都是收费的 收费也就罢了&…

三、优惠卷秒杀

文章目录优惠卷秒杀1.redis实现分布式ID2.优惠券秒杀下单3.超卖问题4.lua脚本5.分布式锁6.redis stream消息队列实现异步秒杀7.redis消息队列list实现消息队列PubSub实现消息队列stream实现消息队列stream的消息队列-消费者组学习黑马点评项目整理总结:https://www.bilibili.co…

腾达Tenda路由器中继wifi步骤

前提&#xff1a; 你有一个信号比较弱&#xff0c;但能上网的wifi&#xff08;暂时叫它1号wifi&#xff09;&#xff0c;并知道其密码你有一个有中继功能的路由器&#xff0c;比如Tenda某型号路由器&#xff0c;插上电&#xff0c;这个路由器的wifi暂时叫它2号wifi 长按下拉菜…

数据库面试题总结

文章目录一、索引相关&#xff08;1&#xff09;什么是索引?&#xff08;2&#xff09;索引是个什么样的数据结构呢?&#xff08;3&#xff09;为什么使用索引&#xff1f;&#xff08;4&#xff09;主键和索引的区别?&#xff08;5&#xff09;说一说索引的底层实现&#x…

educoder数据结构 排序 第2关:实现快速排序

本文已收录于专栏 &#x1f332;《educoder数据结构与算法》&#x1f332; 任务描述 本关要求通过补全快速排序私有函数QSort__来供函数QuickSort调用&#xff0c;以此来实现快速排序的功能。 相关知识 快速排序的基本过程是&#xff1a;从待排序记录中任选一个记录&#…

MS-Model【2】:nnFormer

文章目录前言1. Abstract & Introduction1.1. Abstract1.2. Introduction1.3. Related work2. Method2.1. Overview2.2. Encoder2.2.1. Components2.2.2. The embedding layer2.2.3. Local Volume-based Multi-head Self-attention (LV-MSA)2.2.4. The down-sampling layer…

【通信原理(含matlab程序)】实验五:二进制数字调制与解调

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; 本人持续分享更多关于电子通信专业内容以及嵌入式和单片机的知识&#xff0c;如果大家喜欢&#xff0c;别忘点个赞加个关注哦&#xff0c;让我们一起共同进步~ &#x…