Jenkins教程(自动化部署)

Jenkins教程(自动化部署)

1. Jenkins是什么?

Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。

2. 什么是持续集成(CICD)

因为开发部门同时维护多个版本,多个版本的发布,测试需要大量人力,所以要有一个专业的持续集成工具来管理持续重复的工作。

个人理解,说白了就是把代码测试、打包、发布等工作交给一些工具来自动完成。这样可以提高效率,减少失误,开发人员只需要关心开发和提交代码到Git就可以了。

3. Jenkins的安装

夸克网盘分享夸克网盘是夸克推出的一款云服务产品,功能包括云存储、高清看剧、文件在线解压、PDF一键转换等。通过夸克网盘可随时随地管理和使用照片、文档、手机资料,目前支持Android、iOS、PC、iPad。https://pan.quark.cn/s/631fd86feeda

夸克网盘分享:https://pan.quark.cn/s/631fd86feeda

链接里包含jenkins.war  maven  jdk17     jenkins-start.sh简易shell命令

maven正常解压配置环境变量 ,记得修改maven目录里config的settings.xml配置

jdk如果系统jdk就为17  可以不用下载,不是的话就将jdk压缩包解压,将Jenkins-start.sh里面的java路径换成所解压的文件夹就行       

(1)准备条件

安装JDK

下载JDK压缩包,并上传至Linux某个目录下解压。

. 配置jdk的环境变量

#进入/etc/profile配置文件
vim /etc/profile

. 将以下代码填入到profile文件内底

export JAVA_HOME=/usr/wubin/jdk11
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH

. 使配置生效

source /etc/profile

. 检测java环境信息

javac

输入javac后出现以下信息则安装jdk成功!

ps:jenkins不同版本对jdk版本有不同要求,如果系统里面是jdk8,但是想在不升级jdk版本情况下使用更高版本的jenkins(比如要求jdk17),也可直接在jenkins启动时指定jdk路径,就不用修改系统里配置的jdk版本

(2)安装Jenkins

1. 下载jenkins

wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war 

2. 启动jenkins

# 使用nohup命令启动 nohup 当虚拟机黑屏时 也会运行 日志—>输出到jenkins.log & 后台运行

nohup java -jar /usr/wubin/jenkins.war  --httpPort=8777 --httpsPort=8778 > /usr/wubin/jenkins.log 2>&1 &

3. 使用tail命令查看启动日志,日志中会输出jenkins密码

4. 通过浏览器访问jenkins(端口号必须为8777)

http://你的ip:8777

点击安装推荐的插件

(3)Jenkins中配置JDK路径

jenkins-》全局工具配置-》JDK-》新增JDK

(4)Jenkins忘记密码的解决方案

4. 集成Git

为了Jenkins能够拉取代码,需要安装Git环境和jenkins对应的Git插件

(1) CentOS 7 上安装Git环境

# 安装
$ yum install git -y
# 查看版本
$ git --version

复制

(2) Jenkins安装Git插件

(3) Jenkins配置Git环境

此处无需在jenkins中配置Git环境,采用默认生成的即可

(4) Gitee上任意建一个仓库

(5) 测试凭据是否能够使用

jenkins-》新建任务-》自由风格项目

进入jenkins的工作空间查看文件是否拉取下来,所有拉取的文件都会存放在jenkins工作空间中

到这一步用户名和密码方式的凭证已经打通Git

5. 凭证配置

凭据就是用来存储需要密文保护的数据库密码、Gitee密码信息、Docker私有仓库密码等,以便 Jenkins可以和这些第三方的应用进行交互。

1. 凭证插件安装Credentials Binding

该插件默认在一开始就会被安装,安装后在jenkins-》系统管理-》安全栏目会出现Manage Credentials选项,若没有需要安装插件并重启。

6. Maven集成

jenkins上发布Java项目时需要使用Maven来进行构建打包(Gradle项目则需要安装配置Gradle)

回到顶部

(1) 下载安装

# 找一个目录存放maven
cd /usr/wubin/# 从阿里云上下载maven安装包
wget https://mirrors.aliyun.com/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz# 解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz# 当前maven的安装目录为:
/usr/wubin/
apache-maven-3.6.3

回到顶部

(2) 环境配置

vi /etc/profile在最后面JDK配置上作出一些更改
export MAVEN_HOME=
/usr/wubin/
apache-maven-3.6.3
 export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH

复制

回到顶部

(3) 使配置生效并查看安装情况

source /etc/profile
mvn -version

回到顶部

(4) Jenkins配置Maven

(5) 安装Maven插件

(6) 在/data/software目录下新建一个repository文件夹,用来作为maven的仓库

$ cd /usr/wubin
$ mkdir repository

复制

(7) 使用root账户修改Maven的settings.xml文件(指定仓库目录和阿里云镜像)

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"><!--本地仓库-->          <localRepository>/data/software/repository</localRepository><mirrors><!--阿里云镜像--><mirror><id>aliyun-maven</id><mirrorOf>central</mirrorOf><name>aliyun maven mirror</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url></mirror></mirrors>......
</settings>

(8) Maven测试项目构建

接下来的步骤是将java项目传到Gitee上供jenkins拉取打包,如果运维同学不懂Java代码,可以直接将我的Git项目fork或采用gitlab 等其他方式进行拉取。

新建Maven项目

在码云上建一个同名的git项目

使用Git上传到码云

使用git bash命令将项目初始化,无论是传到Gitee、GitHub、GitLab、Codeup步骤一样,如果对Git的安装部署不熟悉

# 进入到本地的项目文件夹
$ cd existing_folder
# 初始化仓库
$ git init# 添加文件至工作区并提交
$ git add .
$ git commit -m "first commit"# 关联Gitee远程仓库
$ git remote add origin https://gitee.com/nobug8/it235-jenkins-jar.git# 将本地仓库推送到远程仓库的master分支,此处会弹出用户名密码交互
$ git push -u origin master## 如果push报错可以先拉取一下,会有新的gitee生成的文件拉下来,然后重新添加提交并push
$ git pull origin master --allow-unrelated-histories
$ git add .
$ git commit -m "拉取下来合并后再次提交"
$ git push -u origin master

复制

(9) Jenkins添加Maven项目任务

①. 新建任务

②. 编写Maven编译命令

③. 构建并查看控制台日志

保存后,点击立即构建,然后进入日志控制台查看日志

从日志可以看到代码已经在拉取了,而且走的事阿里云仓库,第一次拉取过程会比较长。

通过查看/data/software/repository可以看到有存放拉取的jar包,通过这2个证据可以证明settings.xml文件配置成功且有效

ps:如果使用git账号密码拉取代码即使权限都已经给够了还是出现403等等一些问题,可以考虑使用ApiToken方式拉去代码,在git/gitlab创建apiToken,在凭证管理地方加上凭证

构建成功后查看jenkinsworkspace目录下的jar包

到此Maven集成完毕

配置Post Steps,选中执行shell

7. 配置SSH免密登录

由于jenkins构建消耗内存极大,一般jenkins是一台单独的工具机器,Java项目一般在其他的机器上,这里我重新安装一台虚拟机

应用服务器信息

  • IP:192.168.223.129
  • JDK:1.8
  • user:root
  • 部署路径:/data/app/my-boot
  • 端口:9010

免密登录主要是方便jenkins服务器192.168.223.128的root用户—》应用服务器192.168.223.129的root用户上的jar包拷贝,部署本就是jar包拷贝的过程

在192.168.223.128机器上使用root用户生成秘钥注意此处是root用户

$ ssh-keygen -t rsa
# 3次回车

复制

运行后会在当前用户的根目录生成一个.ssh文件夹

ssh文件夹中的文件描述

  • id_rsa : 生成的私钥文件
  • id_rsa.pub : 生成的公钥文件

接下来需要将公钥导入到认证文件中

$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

复制

如果希望ssh公钥生效需满足至少下面两个条件:

  • .ssh目录的权限必须是700
  • .ssh/authorized_keys文件权限必须是600

给对应文件授权

$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys

复制

authorized_keys文件拷贝到另一台应用服务器的root用户.ssh目录下

# 在应用服务器(192.168.223.129)上用root用户创建/root/.ssh文件夹  mkdir -p /root/.ssh# 在jenkins服务器(192.168.223.128)上将pub公钥文件拷贝到应用服务器的.ssh目录下scp -p ~/.ssh/id_rsa.pub root@192.168.223.129:/root/.ssh/authorized_keys

复制

在jenkins192.168.223.128服务器上进行免密连接测试

# 在jenkins服务器的/root/目录下创建filetest文件,并拷贝到应用服务器
$ cd ~/
$ touch filetest
$ scp -p filetest root@192.168.223.129:/root/filetest
# 进入到应用服务器(192.168.223.129),检查/root目录下是否出现filetest# 在jenkins服务器上使用ssh进行免密连接测试,成功后会出现Last Login的提示
$ ssh root@192.168.223.129
Last login: Sun Sep 20 21:53:03 2020
$ exit

复制

到此免密登录和拷贝实现成功,为接下来jar包部署提供了快捷的帮助

8. 编写Jenkins发布脚本

注意下面代码第6行代码server_ips=”需要部署到的机器ip”

#!/bin/bashecho "部署的目录和项目名称"
DIR="/data/app"
projectName="my-boot"echo "待部署的应用服务器,可多台"
server_ips="192.168.223.139"
for server_ip in ${server_ips[@]}
doecho "ssh连接进行备份操作"
ssh -Tq -oStrictHostKeyChecking=no root@${server_ip} <<EOF
mkdir -p $DIR/backup/${projectName}
mkdir -p $DIR/${projectName}
if [ -f "$DIR/${projectName}/${projectName}.jar" ];thenmv $DIR/${projectName}/${projectName}.jar $DIR/backup/${projectName}/${projectName}-`date "+%Y%m%d_%H%M%S"`.jar 
fi
EOFecho "拷贝jar包到目标服务器的tmp目录"
scp -q -oStrictHostKeyChecking=no ${WORKSPACE}/target/*.jar root@${server_ip}:/tmp/${projectName}.jarecho "ssh远程连接进行发布操作"
ssh -q -oStrictHostKeyChecking=no root@${server_ip} <<EOF
mv /tmp/${projectName}.jar $DIR/${projectName}/${projectName}.jarEOFdoneecho "success"

最新脚本,以端口kill进程

#!/bin/bash# 配置变量
LOG_FILE="/home/xxx/.jenkins/workspace/whale-mgnt-service/startup.log"
JAR_PATH="/home/xxx/.jenkins/workspace/whale-mgnt-service/whale-mgnt-service/target/whale-mgnt-service.jar"
APP_PORT=8081
MAX_ATTEMPTS=60
INTERVAL=5# 清空之前的日志
echo "" > $LOG_FILE# 使用多种方式查找和终止进程
kill_process_by_port() {local port=$1echo "Checking for processes using port $port..."# 方法1: 使用netstat查找local pid=$(sudo netstat -tlnp | grep ":${port}" | awk '{print $7}' | cut -d'/' -f1)# 方法2: 如果方法1失败,使用另一种方式if [ -z "$pid" ]; thenpid=$(sudo ss -tlnp | grep ":${port}" | awk '{print $6}' | cut -d',' -f2 | cut -d'=' -f2)fi# 方法3: 如果还是失败,尝试使用 ps 和 grepif [ -z "$pid" ]; thenpid=$(ps aux | grep "whale-mgnt-service" | grep -v grep | awk '{print $2}')fiif [ ! -z "$pid" ]; thenecho "Found process(es) with PID: $pid"for single_pid in $pid; doecho "Stopping process $single_pid"sudo kill -15 $single_pid 2>/dev/null || truesleep 3if ps -p $single_pid > /dev/null 2>&1; thenecho "Force killing process $single_pid"sudo kill -9 $single_pid 2>/dev/null || truesleep 2fidoneelseecho "No process ID found, trying alternative methods..."# 尝试直接通过应用名称终止sudo pkill -f "whale-service" || truefi# 等待端口释放sleep 5# 检查端口是否已释放if sudo netstat -tlnp | grep ":${port}" > /dev/null; thenecho "Warning: Port $port is still in use"return 1fiecho "Port $port is now available"return 0
}# 确保端口可用
echo "Ensuring port $APP_PORT is available..."
for i in {1..3}; doecho "Attempt $i to free port $APP_PORT"kill_process_by_port $APP_PORTif ! sudo netstat -tlnp | grep ":${APP_PORT}" > /dev/null; thenecho "Port successfully freed"breakfiecho "Current processes using port $APP_PORT:"sudo netstat -tlnp | grep ":${APP_PORT}"sleep 5
done# 最终检查端口
if sudo netstat -tlnp | grep ":${APP_PORT}" > /dev/null; thenecho "Failed to free port $APP_PORT after multiple attempts"echo "Current processes using port $APP_PORT:"sudo netstat -tlnp | grep ":${APP_PORT}"# 最后的紧急措施echo "Attempting emergency measures..."sudo fuser -k ${APP_PORT}/tcp 2>/dev/null || truesudo pkill -9 -f "whale-mgnt-service" 2>/dev/null || truesleep 5if sudo netstat -tlnp | grep ":${APP_PORT}" > /dev/null; thenecho "All attempts to free port failed. Please check manually."exit 1fi
fi# 启动服务
echo "Starting service..."
sudo nohup java -jar \-Xms256m \-Xmx512m \-XX:MaxMetaspaceSize=256m \-XX:+HeapDumpOnOutOfMemoryError \-XX:HeapDumpPath=/tmp/ \-XX:+UseG1GC \-XX:MaxGCPauseMillis=200 \$JAR_PATH \--spring.profiles.active=test \--server.port=$APP_PORT \--spring.jpa.open-in-view=false \--server.tomcat.max-threads=50 \--server.tomcat.min-spare-threads=20 \--spring.task.execution.pool.core-size=5 \--spring.task.execution.pool.max-size=10 \--spring.task.execution.pool.queue-capacity=100 \> $LOG_FILE 2>&1 &PID=$!echo "Starting service with PID: $PID"
echo "Waiting for service to start..."# 给予初始化时间
sleep 15attempt=1
while [ $attempt -le $MAX_ATTEMPTS ]; do# 检查进程是否存在if ! ps -p $PID > /dev/null; thenecho "Process died unexpectedly. Check logs:"tail -n 50 $LOG_FILEexit 1fi# 检查端口和应用状态if netstat -tunlp 2>/dev/null | grep ":$APP_PORT" > /dev/null; thenif grep -q "Started WhaleManagementApplication" $LOG_FILE; thenecho "Application started successfully"sleep 5if ps -p $PID > /dev/null; thenecho "Service is running stably"echo "Final memory usage:"free -mecho "Process memory usage:"ps -o pid,ppid,%mem,rss,command -p $PIDexit 0elseecho "Process died after startup"tail -n 50 $LOG_FILEexit 1fififiecho "Attempt $attempt of $MAX_ATTEMPTS - Service still starting..."# 检查启动日志中的错误if grep -q "Port $APP_PORT was already in use" $LOG_FILE; thenecho "Port conflict detected!"echo "Current port status:"sudo netstat -tunlp | grep ":$APP_PORT"[ -n "$PID" ] && kill -9 $PID 2>/dev/null || trueexit 1fiecho "Recent log entries:"tail -n 10 $LOG_FILEsleep $INTERVALattempt=$((attempt+1))
doneecho "Service failed to start within timeout. Last 50 lines of log:"
tail -n 50 $LOG_FILE
[ -n "$PID" ] && kill -9 $PID 2>/dev/null || true
exit 1

9. 编写应用启动脚本

/data/app/my-boot目录下创建启动脚本start.sh

$ touch start.sh
$ vi start.sh
# 将下面代码粘贴到start.sh中
#!/bin/bash
set -e #任何命令出错就退出
set -o pipefailAPP_ID=my-boot
APP_DIR="/data/app"nohup java -jar ${APP_DIR}/${APP_ID}/${APP_ID}.jar > release_out.log &
start_ok=false
if [[ $? = 0 ]];thensleep 3tail -n 10 release_out.logsleep 5tail -n 50 release_out.log
fi
aaa=`grep "Started" release_out.log | awk '{print $1}'`
if [[ -n "${aaa}" ]];thenecho "Application started ok"exit 0
elseecho "Application started error"exit 1
fi

/data/app/my-boot目录下创建停止脚本stop.sh

$ touch stop.sh
$ vi stop.sh
# 将下面代码粘贴到stop.sh中
#!/bin/bashAPP_ID=my-boot
ps aux | grep ${APP_ID} | grep -v "grep" | awk '{print "kill -9 "$2}' | sh

并进行启动和停止测试,查看日志输出是否正常

将下述启动代码配置jenkins

sh $DIR/${projectName}/stop.sh
sh $DIR/${projectName}/start.sh

访问并测试代码是否生效

如果是虚拟机则需要给防火墙添加9010端口

$ su root
# 开启防火墙9010端口
$ firewall-cmd --zone=public --add-port=9010/tcp --permanent
# 使配置生效
$ firewall-cmd --reload

修改代码返回值,提交至Gitee,并再次进行构建发布,访问http://192.168.223.129:9010查看结果是否更新

PS:异常修复   如出现jenkins内存占用异常,重启等方法都不能解决时  创建一个新的jenkins_home

mkdir -p /mnt/data/jenkins_home_bak/secrets /mnt/data/jenkins_home_bak/users /mnt/data/jenkins_home_bak/jobscp -a jobs users credentials.xml config.xml plugins tools /mnt/data/jenkins_home_bak/
cp -a secrets/hudson.util.Secret /mnt/data/jenkins_home_bak/secrets/
cp -a jenkins.model.*.xml hudson.tasks.*.xml /mnt/data/jenkins_home_bak/
cp -a hudson.plugins.git.GitTool.xml /mnt/data/jenkins_home_bak/
cp -a io.jenkins.plugins.gitlabserverconfig.servers.GitLabServers.xml /mnt/data/jenkins_home_bak/
cp -a jenkins.plugins.nodejs.tools.NodeJSInstallation.xml /mnt/data/jenkins_home_bak/
cp -a hudson.plugins.gradle.Gradle.xml /mnt/data/jenkins_home_bak/cp /mnt/data/jenkins_home/jenkins.install.InstallUtil.lastExecVersion /mnt/data/jenkins_home_bak/
cp /mnt/data/jenkins_home/jenkins.install.UpgradeWizard.state /mnt/data/jenkins_home_bak/

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

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

相关文章

linux 驱动验证是否成功 之 查看moudle信息

这些是 Linux 内核模块&#xff08;.ko&#xff09;中的元信息&#xff08;metadata&#xff09;&#xff0c;可以通过如下方式查看&#xff1a;✅ 1. 使用 modinfo 命令查看已加载或已编译模块信息 示例&#xff1a; modinfo aw2013.ko输出内容大概如下&#xff1a; filename:…

浏览器关闭之前请求接口到后端

2025.07.24今天我学习了如何在浏览器关闭之前请求一个接口返回到后端。可以用performance.navigation判断是浏览器关闭&#xff0c;还是浏览器刷新&#xff0c;因为我这边只需要浏览器关闭的时候才去触发1. 利用performance API&#xff08;刷新检测&#xff09; 刷新页面时&am…

MySQL批量数据处理与事务管理

MySQL是一种广泛应用的关系型数据库管理系统&#xff0c;尤其在数据分析和业务逻辑处理方面具有重要地位。在数据量庞大的业务场景中&#xff0c;批量数据处理和事务管理是提高效率和保障数据一致性的重要手段。掌握高效的批量数据操作方法与事务管理技巧&#xff0c;不仅能够提…

iOS网络之异步加载

为什么你的图片要异步加载&#xff1f;在仿写天气预报时&#xff0c;我们常常需要从网络加载天气图标&#xff0c;例如显示某个小时的天气状态图标。这看似简单的事情&#xff0c;如果处理不当&#xff0c;却很容易造成界面卡顿&#xff0c;甚至影响整个 App 的用户体验。错误做…

C#值类型属性的典型问题

问题复现&#xff1a;值类型属性的副本问题以下代码展示了值类型属性的典型问题&#xff1a;struct Point {public int X;public int Y; }class MyClass {public Point Position {get; set;} }// 使用属性修改结构体&#xff08;无效&#xff01;&#xff09; var obj new MyC…

机器学习基础-k 近邻算法(从辨别水果开始)

一、生活中的 "分类难题" 与 k 近邻的灵感 你有没有这样的经历&#xff1a;在超市看到一种从没见过的水果&#xff0c;表皮黄黄的&#xff0c;拳头大小&#xff0c;形状圆滚滚。正当你犹豫要不要买时&#xff0c;突然想起外婆家的橘子好像就是这个样子 —— 黄色、圆…

【WPF】NumericUpDown的用法

在 WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;NumericUpDown 控件并不是内置的标准控件之一&#xff0c;但它是一个非常常用的控件&#xff0c;用于让用户输入一个数值&#xff08;整数或浮点数&#xff09;&#xff0c;并提供上下箭头来递增或…

Kotlin位运算

Kotlin 提供了几种用于操作整数各个位&#xff08;bit&#xff09; 的运算符。这些操作是由处理器直接支持的&#xff0c;速度快且操作简单。在底层编程中非常重要&#xff0c;比如设备驱动、低级图形处理、网络通信、加密和压缩等。 尽管计算机通常都有高效的硬件指令来执行算…

墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)

一、SQL手工注入漏洞测试(MongoDB数据库) 本文以墨者学院靶场为例&#xff0c;演示MongoDB数据库的手工SQL注入全过程。靶场以自己的地址为准&#xff1a;http://124.70.71.251:42286/new_list.php?id1 二、注入原理说明 MongoDB作为NoSQL数据库&#xff0c;其注入方式与传…

Kafka——CommitFailedException异常处理深度解析

引言在分布式消息系统Kafka的生态中&#xff0c;消费者组&#xff08;Consumer Group&#xff09;机制是实现高吞吐量和负载均衡的核心设计。然而&#xff0c;消费过程中位移提交&#xff08;Offset Commit&#xff09;的稳定性始终是开发者面临的最大挑战之一。当消费者尝试提…

kafka的部署和jmeter连接kafka

zookeeper的安装 kafka依赖Zookeeper所以要先安装Zookeeper kafka的安装文章引用来源:Kafka下载和使用&#xff08;linux版&#xff09;-CSDN博客 通过wget命令安装 # 安装wget https://downloads.apache.org/zookeeper/stable/apache-zookeeper-3.7.1-bin.tar.gz# 解压tar…

Android UI 组件系列(八):ListView 基础用法与适配器详解

博客专栏&#xff1a;Android初级入门UI组件与布局 源码&#xff1a;通过网盘分享的文件&#xff1a;Android入门布局及UI相关案例 链接: https://pan.baidu.com/s/1EOuDUKJndMISolieFSvXXg?pwd4k9n 提取码: 4k9n 一、引言 在上一篇文章《Android UI 组件系列&#xff08;…

Android学习专题目录(持续更新)

1.Android 调试 1.1&#xff1a;Logcat日志分析 2.Android编译 2.1&#xff1a;android编译过程中的mk文件和bp文件的扫描机制 2.2&#xff1a;Android 构建系统中常见的 .mk 文件及其作用 2.3&#xff1a;Android构建系统中的mk文件语法函数 2.4&#xff1a;安卓中定…

c#Lambda 表达式与事件核心知识点整理

一、Lambda 表达式1. 概念 Lambda 表达式是一种匿名函数&#xff08;无名称的函数&#xff09;&#xff0c;简化了委托和匿名方法的写法&#xff0c;格式为&#xff1a; (参数列表) > 表达式或语句块 它可以作为参数传递&#xff0c;或赋值给委托类型变量。2. 基本语法与简写…

Springboot+Layui英语单词学习系统的设计与实现

文章目录前言详细视频演示具体实现截图后端框架SpringBootLayUI框架持久层框架MyBaits成功系统案例&#xff1a;参考代码数据库源码获取前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续输…

主要分布于内侧内嗅皮层的层Ⅲ的边界向量细胞(BVCs)对NLP中的深层语义分析的积极影响和启示

边界向量细胞&#xff08;Boundary Vector Cells, BVCs&#xff09;主要分布于内侧内嗅皮层&#xff08;MEC&#xff09;层Ⅲ&#xff0c;通过编码环境边界&#xff08;如墙壁、障碍物&#xff09;的距离和方向信息&#xff0c;为空间导航提供几何参考框架。这一神经机制对自然…

Selenium是解决了什么问题的技术?

Selenium 是一种用于自动化浏览器操作的技术&#xff0c;主要解决了以下问题&#xff1a;1. 自动化测试 Selenium 最初是为了解决 Web 应用程序的自动化测试 问题而设计的。它可以帮助开发者和测试人员&#xff1a; 模拟用户操作&#xff1a;如点击按钮、填写表单、选择下拉菜单…

JavaSE知识点(2)

目录 访问修饰符的区别 this关键字的作用 抽象类和接口有什么区别 抽象类可以定义构造方法吗 但是接口不可以定义构造方法 Java支持多继承吗 接口可以多继承吗 继承和抽象的区别&#xff1f; 抽象类和普通类的区别 成员变量和局部变量的区别&#xff1f; staic关键字…

(实用教程)Linux操作系统(二)

centos配置静态ip 注意&#xff1a; 1.系统中的网关要与虚拟机编辑器中的网关保持一致 2.如果配置虚拟机编辑器后发现ping不通外网的时候&#xff0c;就要还原默认设置再进行配置 总结&#xff1a; 虚拟机编辑器需要配置ip&#xff0c;网关&#xff0c;其中ip网段以及最后一…

ThinkPHP8集成RabbitMQ的完整案例实现

ThinkPHP8集成RabbitMQ的完整案例实现一、安装依赖&#xff1a;需通过Composer安装php-amqplib库‌二、配置RabbitMQ三、生产者1、发送一个邮件&#xff0c;将任务发送到RabbitMQ队列中。2、运行结果展示四、启动消费者&#xff1a;命令行执行php think rabbitmq:consumer1&…