通过RpmBuild构建redis-5.0.9版本的RPM类型包

news2024/11/25 14:26:53

系列文章目录

rpmbuild基础知识

文章目录

  • 系列文章目录
  • 前言
  • 一、rpmbuild相关操作
    • 1、安装rpmbuild命令
    • 2、安装spec文件检查工具
    • 3、查看rpmbuild版本
    • 4、编译工具安装
    • 5、修改rpm制作包的默认路径
  • 二、资源准备
    • 1、创建rpmbuild工作目录
    • 2、目录作用解释
    • 3、下载redis源码包
    • 4、上传redis.conf文件
    • 5、上传创建redis实例脚本和创建分布式集群脚本
  • 三、构建过程
    • 1、redis.spec文件
    • 2、修改用户自定义宏相关文件rpmmacros
    • 3、创建RPM包签名
    • 4、构建带签名的RPM包
    • 5、查看结果
  • 四、结果演示
    • 1、安装构建完成的RPM包
    • 2、创建redis实例
    • 3、查看RPM包签名到期时间
    • 4、卸载redis-rpm包
  • 总结


前言

承接rpmbuild基础知识章节和对应的背景要求,开始着手下载redis源码包、编写spec文件、构建出符合要求的redis安装包,具体方法如下所示。


提示:以下构建文件及方式已在centos 7 x86_64系统架构上测试运行,一切均正常

一、rpmbuild相关操作

1、安装rpmbuild命令

[root@python2 ~]# yum install -y rpm-build
[root@python2 ~]#  yum install rpmdevtools

2、安装spec文件检查工具

[root@python2 ~]# yum install rpmlint -y

如果返回错误/警告,使用 “-i” 选项查看更详细的信
[root@python2 ~]#  rpmlint -i program.spec

也可以使用 rpmlint 测试已构建的 RPM 包,检查 SPEC/RPM/SRPM 是否存在错误。你需要在发布软件包之前,解决这些警告。此页面 提供一些常见问题的解释。如果你位于 SPEC 目录中,请执行:

[root@python2 ~]# rpmlint NAME.spec ../RPMS/*/NAME*.rpm ../SRPMS/NAME*.rpm

3、查看rpmbuild版本

[root@python2 ~]# rpmbuild --version
RPM version 4.11.3

4、编译工具安装

# 编译工具
[root@python2 ~]#  yum install -y gcc make  gcc-c++ 

5、修改rpm制作包的默认路径

[root@python2 ~]#  echo "%_topdir /export/rpmbuild"  >> /root/.rpmmacros
%_topdir /export/rpmbuild  #/root/.rpmmacros文件是存储各种宏定义,比如_topdir宏的值来自定义打包路径

二、资源准备

1、创建rpmbuild工作目录

手动创建
[root@python2 ~]#   mkdir -p /export/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
rpmdevtools 命令创建
[root@python2 ~]#   cd /export/
[root@python2 ~]#   rpmdev-setuptree

[root@python2 ~]#  cd /export/rpmbuild && ls
	BUILD  RPMS  SOURCES  SPECS  SRPMS

2、目录作用解释

默认位置宏代码名称用途
/export/rpmbuild/SPECS%_specdir文件目录保存 RPM 包配置(.spec)文件
/export/rpmbuild/SOURCES%_sourcedir源代码目录保存源码包(如 .tar 包)和所有 patch 补丁
/export/rpmbuild/BUILD%_builddir构建目录源码包被解压至此,并在该目录的子目录完成编译
/export/rpmbuild/BUILDROOT%_buildrootdir最终安装目录保存 %install 阶段安装的文件
/export/rpmbuild/RPMS%_rpmdir标准 RPM 包目录生成/保存二进制 RPM 包
/export/rpmbuild/SRPMS%_srcrpmdir源代码 RPM 包目录生成/保存源码 RPM 包(SRPM)

3、下载redis源码包

将源码包下载至SOURCES目录,专门用于存放源文件
[root@python2 ~]#  cd /export/rpmbuild/SOURCES
[root@python2 ~]#  wget  https://download.redis.io/releases/redis-5.0.9.tar.gz

4、上传redis.conf文件

[root@python2 ~]#  cd /export/rpmbuild/SOURCES
[root@python2 ~]#  rz
此处替换为自己环境现有的redis.conf文件即可

5、上传创建redis实例脚本和创建分布式集群脚本

将这两个脚本封装到rpm包中去,安装之后可快速执行脚本产生redis实例,并构建出相应的分布式集群

[root@python2 ~]#  cd /export/rpmbuild/SOURCES
[root@python2 ~]#  rz
create_port_redisconf.sh
#!/bin/bash
# help
useage() {
	echo -e "useage: $0 [ port ] [[yes|no cluster] default no]
	eg:$0 7889 no|yes\n"
	exit 2
}

redis_cluster_conf() {
    # redis config file
    cat > ${redis_dir}/conf/${port}/redis_${port}.conf << EOF

include ${redis_dir}/conf/redis.conf

daemonize yes

cluster-enabled yes
cluster-config-file "nodes.conf"
cluster-node-timeout 15000

pidfile "${redis_dir}/logs/redis_${port}.pid"
logfile "${redis_dir}/logs/redis_${port}.log"

appendonly no

dir "${redis_dir}/conf/${port}"
port ${port}
# Generated by CONFIG REWRITE
timeout 600
tcp-keepalive 3600
save 900 1
save 300 10
save 60 10000
client-output-buffer-limit normal 0 0 0
repl-timeout 180
repl-backlog-size 50mb
client-output-buffer-limit slave 0 0 0

EOF
}

redis_standard_conf(){
    # redis config file
    cat > ${redis_dir}/conf/${port}/redis_${port}.conf << EOF

include ${redis_dir}/conf/redis.conf

daemonize yes

pidfile "${redis_dir}/logs/redis_${port}.pid"
logfile "${redis_dir}/logs/redis_${port}.log"

appendonly no

dir "${redis_dir}/conf/${port}"
port ${port}
# Generated by CONFIG REWRITE
timeout 600
tcp-keepalive 3600
save 900 1
save 300 10
save 60 10000
client-output-buffer-limit normal 0 0 0
repl-timeout 180
repl-backlog-size 50mb
client-output-buffer-limit slave 0 0 0

EOF

}

#
if [[ $# -eq 1 && $1 -gt 0 ]] || [[ $# -eq 2 ]];then
    port=$1
    is_cluster=$2

    redis_dir='/export/server/redis'
    # create port dir
    [ -d ${redis_dir}/conf/${port} ] || mkdir -p ${redis_dir}/conf/${port}
    

    [ -f ${redis_dir}/conf/${port}/redis_${port}.conf ] && echo "${redis_dir}/conf/${port}/redis_${port}.conf File is exits!" && exit 2
    # 
    if echo "${is_cluster[@]}" | grep -w "yes" &>/dev/null;then
        # create redis config file
        redis_cluster_conf
    else
        # create redis config file
        redis_standard_conf
    fi
    # create start service file
    cat > ${redis_dir}/service_${port}.sh << EOF
#!/bin/bash

# help
useage() {
	echo -e "useage: \$0 [ start | stop | restart ]
	eg:\$0 start\\n"
	exit 2
}


start() {
    ${redis_dir}/bin/redis-server ${redis_dir}/conf/${port}/redis_${port}.conf 
}
stop() {
    kill -9 \`cat ${redis_dir}/logs/redis_${port}.pid\`
}

if [[ \$# -eq 1 ]];then
    case \$1 in
        start)
            start
    	    ;;
        stop)
            stop
    	    ;;
        restart)
            stop
            start
    	    ;;
        *)
            useage
    	    ;;
    esac
else
    useage
fi

EOF
    
    # add x mode
    chmod +x ${redis_dir}/service_${port}.sh
    

else
    useage
fi
create_clusterRedis.sh
#!/bin/bash

redis_home='/export/server/redis'


# help
useage() {
	echo -e "useage: $0 [ host1:port host1:port ... ]
	eg:$0 127.0.0.1:7001 127.0.0.1:7002 ...\n"
	exit 2
}

create() {
    ${redis_home}/bin/redis-cli --cluster create --cluster-replicas 1  $*
}

if [[ $# -gt 1 ]];then
    echo $*
    
    create $*

else
    useage
fi

至此,准备工作已完成,下面开始编写spec文件并构建RPM包

三、构建过程

提醒: 详细的rpmbuild相关宏定义、变量定义、构建分成的阶段等文档,在此处不进行细说,自行查看文章顶端的rpmbuild基础知识链接即可

1、redis.spec文件

[root@python2 ~]# cd /export/rpmbuild/SPEC/
[root@python2 SPEC/]# vim redis.spec
#自定义宏,相当于Linux中"Key-Value"变量形式
#--->名称
%define Name redis
#--->版本
%define Version 5.0.9
#--->本rpm包中需更换的配置文件
%define CONFIGFILE redis.conf
#--->本rpm包默认安装的路径
%define InstallPath /export/server/redis
#-->rpm包封装进去的脚本
%define create_port  create_port_conf.sh
%define create_cluster create_cluster.sh

%define _build_id_links none
# 软件包的名称 
Name: %{Name}
# 软件包的版本 
Version: %{Version}
# 软件包发布序列号,1表示第几次打包 %{?dist} 会再包名中添加操作系统系统
Release: 1
# 软件包的概要信息,不要超过50个 
Summary: The redis for centos 7 x86_64.

# 软件授权方式 
License: BSD

# 软件分类
Group:System Middleware

# 源代码软件包的官方地址或源码包的下载地址 
URL: https://download.redis.io/releases/redis-5.0.9.tar.gz



# 源代码软件包的名字 
Source0: %{Name}-%{Version}.tar.gz
Source1: %{CONFIGFILE}
Source2: %{create_port}
Source3: %{create_cluster}

# install使用的虚拟目录,安装后就在该目录下打包 
BuildRoot: %_topdir/BUILDROOT


#制作过程中用到的软件包
BuildRequires: gcc,automake,autoconf,libtool,make
Requires: bash,jemalloc

#软件包详细描述信息 
%description
This is %{Name}


%pre
if getent passwd %{Name} > /dev/null; then
    echo "user %{Name} already exist,The installation operation will continue!!!"
else
    useradd %{Name} -s /sbin/nologin
fi


# 安装前的准备工作,一般用于解压源码包
%prep
#解压并cd到相关目录  tar xf SOURCES/redis-5.0.9.tar.gz -C BUILD && cd BUILD
%setup -q

# 源码编译 make
%build
make %{?_smp_mflags}


# 源码安装
#目前还是在/export/rpmbuild/BUILD/目录中,执行以下操作
#rm -rf /export/rpmbuild/BUILDROOT
#mkdir -p /export/rpmbuild/BUILDROOT/export/server/redis/{bin,conf,data,logs,script}
%install
%{_rm} -rf %{buildroot} # 清理之前的安装
# 使用 make install 来自动安装到指定目录,替代手动复制文件的步骤
make install PREFIX=%{buildroot}%{InstallPath}

# 创建目录结构,如果make install没有创建(通常不需要,除非有特殊需求)
mkdir -p %{buildroot}%{InstallPath}/{conf,data,logs,script}

# 如果需要,创建必要的符号链接(检查是否已经由 make install 创建)
# ln -s %{buildroot}%{InstallPath}/bin/redis-server %{buildroot}%{InstallPath}/bin/redis-sentinel

# 复制自定义的或额外的配置文件和脚本
cp -rp %{SOURCE1} %{buildroot}%{InstallPath}/conf/
cp -rp %{SOURCE2} %{buildroot}%{InstallPath}/script/
cp -rp %{SOURCE3} %{buildroot}%{InstallPath}/script/
chmod +x %{buildroot}%{InstallPath}/script/*

# 设置文件和目录的所有权
chown -R redis.redis %{buildroot}%{InstallPath}


#卸载前需要做的任务 如:停止任务
%preun
if [ $1 -eq 0 ]; then
    echo "Automatically stopping all Redis services..."
    for script in %{InstallPath}/service_*.sh; do
        if [[ $script =~ service_([0-9]+)\.sh ]]; then
            sh $script stop
        fi
    done
    # RPM 卸载操作,备份或移动目录
    mkdir -p /export/backup/
    if [ -d %{InstallPath} ]; then
        cp -rp %{InstallPath}  /export/backup/
    fi
    echo "Redis data has been backed up to /export/backup/."
    
    userdel -r redis
    echo "Redis user has been deleted"
fi

#设置文件属性,包含编译文件需要生成的目录、文件以及分配所对应的权限
%files
%defattr(-,redis,redis,-)
%dir %{InstallPath}
%dir %{InstallPath}/bin
%dir %{InstallPath}/conf
%dir %{InstallPath}/data
%dir %{InstallPath}/logs
%dir %{InstallPath}/script
%{InstallPath}/bin/*
%{InstallPath}/conf/*
%{InstallPath}/script/*


#变更日志  第一行的变更时间格式 由date '+* %a %b %d %Y %T %z' 在命令获取然后粘贴即可
%changelog
* Fri Jul 05 2024 14:57:39 +0800
- Initial redis 5.0.9 RPM release

2、修改用户自定义宏相关文件rpmmacros

因为上述的redis.spec文件中引用了不少的宏变量,因此需要在此处定义

[root@python2 ~]# cat /root/.rpmmacros 
%_topdir /export/rpmbuild
%_rm    /usr/bin/rm
%_signature gpg
%_gpg_path /root/.gnupg/
%_gpg_name rpmbuild
%_gpgbin /usr/bin/gpg

3、创建RPM包签名

该流程和方法详情见文章顶部<rpmbuild基础知识>链接,查看RPM包签名流程部分即可

4、构建带签名的RPM包

在这里插入图片描述

#进入到SPEC文件目录下
[root@python2 rpmbuild]# cd SPECS/
[root@python2 SPECS]# ll
total 8
-rw-r--r-- 1 root root 4423 Jul  5 15:03 redis.spec
#执行构建命令
[root@python2 SPECS]# useradd redis -s /sbin/nologin  #先创建出redis用户,否则构建会报错
Creating mailbox file: File exists

[root@python2 SPECS]# rpmbuild --sign --bb redis.spec  #--sign 指的是构建RPM时指定RPM包签名

#构建过程
[root@python2 SPECS]# rpmbuild --sign --bb redis.spec 
+ umask 022
+ cd /export/rpmbuild/BUILD
+ cd /export/rpmbuild/BUILD
+ rm -rf redis-5.0.9
+ /usr/bin/gzip -dc /export/rpmbuild/SOURCES/redis-5.0.9.tar.gz
+ /usr/bin/tar -xf -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd redis-5.0.9
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
+ umask 022
+ cd /export/rpmbuild/BUILD
+ cd redis-5.0.9
+ make
    CC Makefile.dep
    ......  #全部过程就不在此展示了
9100 blocks
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
+ /usr/lib/rpm/redhat/brp-python-hardlink
+ /usr/lib/rpm/redhat/brp-java-repack-jars
+ umask 022
+ cd /export/rpmbuild/BUILD
+ cd redis-5.0.9
+ /usr/bin/rm -rf /export/rpmbuild/BUILDROOT/redis-5.0.9-1.x86_64
+ exit 0
Enter pass phrase:   #这块是签名所要输入的密码地方,然后rpm包才真正的签名成功
Pass phrase is good.
/export/rpmbuild/RPMS/x86_64/redis-5.0.9-1.x86_64.rpm:
/export/rpmbuild/RPMS/x86_64/redis-debuginfo-5.0.9-1.x86_64.rpm:

5、查看结果

[root@python2 SPECS]# cd ../RPMS/x86_64/
[root@python2 x86_64]# ll
total 7300
-rw-r--r-- 1 root root 1364252 Jul  5 21:48 redis-5.0.9-1.x86_64.rpm  #这个才是构建出来的RPM包
-rw-r--r-- 1 root root 6107072 Jul  5 21:48 redis-debuginfo-5.0.9-1.x86_64.rpm

至此,通过SPEC文件构建rpm包已完成,具体的rpmbuild指令及spec文件中定义的宏,都可以去查看文章顶部的<rpmbuild基础知识>学习了解到

四、结果演示

1、安装构建完成的RPM包

[root@python2 x86_64]# ll
total 7300
-rw-r--r-- 1 root root 1364252 Jul  5 21:48 redis-5.0.9-1.x86_64.rpm
-rw-r--r-- 1 root root 6107072 Jul  5 21:48 redis-debuginfo-5.0.9-1.x86_64.rpm
[root@python2 x86_64]# rpm -ivh redis-5.0.9-1.x86_64.rpm 
Preparing...                          ################################# [100%]
user redis already exist,The installation operation will continue!!!
Updating / installing...
   1:redis-5.0.9-1                    ################################# [100%]

2、创建redis实例

#查看安装后的目录结构
[root@python2 redis]# tree
.
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof
│   ├── redis-check-rdb
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── conf
│   └── redis.conf
├── data
├── logs
└── script
    ├── create_clusterRedis.sh
    └── create_port_Redisconf.sh

5 directories, 9 files

#创建一个端口为7889的redis实例并启动
[root@python2 redis]# sh script/create_port_confRedis.sh 7889 yes
[root@python2 redis]# sh service_7889.sh start
[root@python2 redis]# ps -ef |grep redis
root      11929      1  0 21:54 ?        00:00:00 /export/server/redis/bin/redis-server *:7889 [cluster]
root      11934   1173  0 21:54 pts/0    00:00:00 grep --color=auto redis

#再次查看Redis目录结构
[root@python2 redis]# tree .
.
├── bin
│   ├── redis-benchmark
│   ├── redis-check-aof
│   ├── redis-check-rdb
│   ├── redis-cli
│   ├── redis-sentinel -> redis-server
│   └── redis-server
├── conf
│   ├── 7889
│   │   ├── nodes.conf
│   │   └── redis_7889.conf
│   └── redis.conf
├── data
├── logs
│   ├── redis_7889.log
│   └── redis_7889.pid
├── script
│   ├── create_clusterRedis.sh
│   └── create_port_confRedis.sh
└── service_7889.sh

6 directories, 14 files

由此可见,创建redis实例前后,目录结构也发生了变化,而且redis实例也启动成功,但这个只是单节点的,要想创建一个redis分布式集群,还需要执行 create_clusterRedis.sh ip:port,xx,xx,xx,xx,xx yes才可以,不再详细描述!

3、查看RPM包签名到期时间

#查看签名到期时间
#获取到rpm包中的签名ID eb5c386d788b960f
[root@python2 .gnupg]# rpm -qpi /export/rpmbuild/RPMS/x86_64/redis-5.0.9-1.x86_64.rpm
Name        : redis
Version     : 5.0.9
Release     : 1
Architecture: x86_64
Install Date: (not installed)
Group       : System Middleware
Size        : 6280870
License     : BSD
Signature   : RSA/SHA1, Fri 05 Jul 2024 05:02:58 PM CST, Key ID eb5c386d788b960f
Source RPM  : redis-5.0.9-1.src.rpm
Build Date  : Fri 05 Jul 2024 05:02:46 PM CST
Build Host  : python2
Relocations : (not relocatable)
URL         : https://download.redis.io/releases/redis-5.0.9.tar.gz
Summary     : The redis for centos 7 x86_64.
Description : This is redis

#根据ID查看到期时间
[root@python2 .gnupg]# gpg --list-keys  eb5c386d788b960f
pub   4096R/788B960F 2024-07-05 [expires: 2026-07-05]
uid                  rpmbuild (GPG-RPM-KEY) <rootwxd@163.com>
sub   4096R/4CE2423E 2024-07-05 [expires: 2025-07-05]

4、卸载redis-rpm包

卸载也很顺利,没有任何问题

[root@python2 redis]# rpm -qa |grep redis
redis-5.0.9-1.x86_64
[root@python2 redis]# rpm -e redis-5.0.9-1.x86_64
Automatically stopping all Redis services...
Redis data has been backed up to /export/backup/.
userdel: /var/spool/mail/redis not owned by redis, not removing
Redis user has been deleted

至此,Redis-5.0.9版本的rpm包构建完成,并且也成功的部署到了线上,目前已运行了两周,并未发现任何问题


总结

要想看懂这篇文章,必须先把文章顶部引用的链接文章看几遍并读懂它,然后回过头来再看本文章,就会轻松很多,第一个中间件已通过rpmbuild的形式构建完成,勤能补拙,以描述的背景为例,多加练习构造出合适的rpm包,不仅比源码安装方便还更加利于管理,这样的安装方式谁能不爱呢!!!

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

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

相关文章

LLM - 神经网络的组成

1. 一个神经元的结构&#xff1a;即接受多个输入X向量&#xff0c;在一个权重向量W和一个偏执标量b的作用下&#xff0c;经过激活函数后&#xff0c;产生一个输出。 2. 一层神经网络的结构&#xff1a;该层网络里的每个神经元并行计算&#xff0c;得到各自的输出;计算方式是输入…

Go源码--channel源码解读

简介 channel顾名思义就是channel的意思&#xff0c;主要用来在协程之间传递数据&#xff0c;所以是并发安全的。其实现原理&#xff0c;其实就是一个共享内存再加上锁&#xff0c;底层阻塞机制使用的是GMP模型。可见 GMP模型就是那个道&#xff0c;道生一,一生二,二生三,三生…

【Spring Boot】统一数据返回

目录 统一数据返回一. 概念二.实现统一数据返回2.1 重写responseAdvice方法2.2 重写beforeBodyWriter方法 三. 特殊类型-String的处理四. 全部代码 统一数据返回 一. 概念 其实统一数据返回是运用了AOP&#xff08;对某一类事情的集中处理&#xff09;的思维&#xff0c;简单…

UML2.0-系统架构师(二十四)

1、&#xff08;重点&#xff09;系统&#xff08;&#xff09;在规定时间内和规定条件下能有效实现规定功能的能力。它不仅取决于规定的使用条件等因素&#xff0c;还与设计技术有关。 A可靠性 B可用性 C可测试性 D可理解性 解析&#xff1a; 可靠性&#xff1a;规定时间…

在Linux操作系统中关于逻辑卷的案例

1.如何去创建一个逻辑卷 1.1先去创建物理卷 如上图所示&#xff0c;physical volume 物理卷 被成功创建。 如上图所示&#xff0c;可以使用pvscan来去查看当前Linux操作系统的物理卷/ 1.2使用创建好的物理卷去创建一个卷组。 如上图所示&#xff0c;可以使用第一步创建的两个…

点亮led灯——Arduino uno R3 学习之旅

​ 常识: 一般智能手机的额定工作电流大约为200mA Arduino Uno板上I/0(输入/输出)引脚最大输出电流为40 mA Uno板控制器总的输出电流为200 mA 发光二极管介绍 发光二极管(Light Emitting Diode&#xff0c;简称LED)是一种能够将电能转化为光能的固态的半导体器件。 LED的极…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【密钥导入介绍及算法规格】

密钥导入介绍及算法规格 如果业务在HUKS外部生成密钥&#xff08;比如应用间协商生成、服务器端生成&#xff09;&#xff0c;业务可以将密钥导入到HUKS中由HUKS进行管理。密钥一旦导入到HUKS中&#xff0c;在密钥的生命周期内&#xff0c;其明文仅在安全环境中进行访问操作&a…

输入框输入值之后,检索表格中是否存在输入框中的值,存在就让当前文字为红色

this.searchValue为输入框的值 createKeywordHtml_content(data) { if (data undefined) { return data; } if (typeof data ! string) { data String(data) } let value data.replace(this.searchValue, <span style"color:#FF5555">$&</span>…

Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题

目录 Vue优化路径 一、使用key 二、使用冻结对象 三、使用函数式组件 四、使用计算属性 五、使用非实时绑定的表单项 六、保持对象引用稳定 6.1、保持对象引用稳定定义 6.2、保持对象引用稳定与不稳定的例子 6.3、vue2判断数据是否变化是通过hasChanged函数实现的 ①…

2024年软件测试岗必问的100+个面试题【含答案】

一、基础理论 1、开场介绍 介绍要领&#xff1a;个人基本信息、工作经历、之前所做过的工作及个人专长或者技能优势。扬长避短&#xff0c;一定要口语化&#xff0c;语速适中。沟通好的就多说几句&#xff0c;沟通不好的话就尽量少说两句。举例如下&#xff1a; 面试官你好&…

ONLYOFFICE 8.1版本震撼来袭,让办公更高效、更智能

官网链接&#xff1a; 在线PDF查看器和转换器 | ONLYOFFICE 在线办公套件 | ONLYOFFICE 随着科技的不断发展&#xff0c;办公软件已经成为现代企业提高工作效率、实现信息共享的重要工具。在我国&#xff0c;一款名为ONLYOFFICE的在线办公套件受到了越来越多企业的青睐。今天…

3086.力扣每日一题7/4 Java

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 思路 解题方法 时间复杂度 空间复杂度 Code 思路 首先通过循环计…

AI大模型对话(上下文)缓存能力

互联网应用中&#xff0c;为了提高数据获取的即时性&#xff0c;产生了各种分布式缓存组件&#xff0c;比如Redis、Memcached等等。 大模型时代&#xff0c;除非是免费模型&#xff0c;否则每次对话都会花费金钱来进行对话&#xff0c;对话是不是也可以参照缓存的做法来提高命…

ASUS/华硕飞行堡垒8 FX506L FX706L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;Windows10 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…

大量设备如何集中远程运维?用好向日葵的这几个功能很重要

当企业的业务不断发展&#xff0c;不同系统、不同用途的IT设备数量也会不断上升&#xff0c;面对不断扩张的设备规模&#xff0c;IT运维的压力自然也会陡然上升。 面对这种情况&#xff0c;传统的线下运维方式已经不再合适&#xff0c;我们需要引入一个专业的&#xff0c;可以…

Spring Boot集成jacoco实现单元测试覆盖统计

1.什么是jacoco&#xff1f; JaCoCo&#xff0c;即 Java Code Coverage&#xff0c;是一款开源的 Java 代码覆盖率统计工具。支持 Ant 、Maven、Gradle 等构建工具&#xff0c;支持 Jenkins、Sonar 等持续集成工具&#xff0c;支持 Java Agent 技术远程监控 Java 程序运行情况…

如何利用好用便签提高工作效率?

在忙碌的工作中&#xff0c;我们经常需要记住许多琐碎的任务。如果这些任务被遗忘&#xff0c;可能会对我们的工作产生影响。这时&#xff0c;便签就成为了我们的得力助手。通过合理的使用和管理&#xff0c;便签不仅能帮助我们记住重要的事项&#xff0c;还能提高我们的工作效…

计算机图形学入门25:BRDF的测量

1.前言 BRDF(双向反射分布函数)可以用各种各样的材质去描述&#xff0c;但是这只是一种基于物理的描述或者近似&#xff0c;那什么是真正的BRDF&#xff1f;只有测出来的才是真正的。 为什么要测出BRDF&#xff1f;因为之前所描述的BRDF并不准确。如下图所示&#xff0c;以菲涅…

MySQL 9.0 创新版发布,大失所望。。

大家好&#xff0c;我是程序员鱼皮。2024 年 7 月 1 日&#xff0c;MySQL 发布了 9.0 创新版本。区别于我们大多数开发者常用的 LTS&#xff08;Long-Term Support&#xff09;长期支持版本&#xff0c;创新版本的发布会更频繁、会更快地推出新的特性和变更&#xff0c;可以理解…

鸿蒙开发设备管理:【@ohos.account.appAccount (应用帐号管理)】

应用帐号管理 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 导入模…