使用 Go 语言与 Redis 构建高效缓存与消息队列系统

news2024/12/25 4:29:05

什么是 Redis?

  • Redis 是一个开源的内存数据库,支持多种数据结构,包括字符串、列表、集合、哈希和有序集合。由于 Redis 运行在内存中,读写速度极快,常被用于构建缓存系统、实时排行榜、会话存储和消息队列等高并发场景下的服务。
  • 在这篇博客中,我们将介绍如何使用 Go 语言集成 Redis,构建高效的缓存和消息队列系统。

安装 Redis

  • 安装 Redis: 你可以通过以下命令安装 Redis(适用于 Linux 和 macOS):
sudo apt-get install redis-server
  • 或者通过 Homebrew 安装:
brew install redis

启动 Redis 服务

redis-server

验证安装

  • 可以通过以下命令进入 Redis CLI,验证 Redis 是否正常运行
redis-cli

安装 Go Redis 客户端

  • 在 Go 项目中,我们将使用 go-redis/redis 这个流行的 Redis 客户端库。你可以通过以下命令安装:
go get github.com/go-redis/redis/v8

连接 redis

rdb := redis.NewClient(&redis.Options{
	Addr:     "localhost:6379",
	Password: "",
	DB:       0,
})

string 类型

  1. set 设置 string 的值
func TestSetKey(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	err := rdb.Set(ctx, "name", "hello world", time.Second*1000).Err()
	if err != nil {
		panic(err)
	}
	fmt.Println("设置值成功")
}
  1. get 获取 string 的值
func TestGetKey(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	result, err := rdb.Get(ctx, "name").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("result", result)
}

  1. getset 获取到的值是上一次的值
func TestGetSet(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	result, err := rdb.GetSet(ctx, "name", "hello world").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(result)
}

  1. setnx 如果值存在则不设置,如果不存在则设置
func TestSetNx(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	err := rdb.SetNX(ctx, "name", "hello set nex", time.Second*1000).Err()
	if err != nil {
		panic(err)
	}

}
  1. mget 批量获取值
func TestMGet(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	result, err := rdb.MGet(ctx, "name", "k1", "k2").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(result)
}

  1. 批量设置
func TestMSet(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	err := rdb.MSet(ctx, "k1", "value1", "k2", "value2", "k3", "value3").Err()
	if err != nil {
		panic(err)
	}

}

  1. 自增
// 自增
func TestIncrBy(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	result, err := rdb.IncrBy(ctx, "money", 1).Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(result)
}
  1. 自减
func TestDecrBy(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	val, err := rdb.DecrBy(ctx, "money", 1).Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(val)
}

  1. 删除
func TestDel(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	err := rdb.Del(ctx, "k1").Err()
	if err != nil {
		panic(err)
	}
}
  1. 设置过期时间
func TestExpire(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	rdb.Expire(ctx, "key2", 1000*time.Second)
}

哈希类型

  1. HSet 设置哈希值
func TestHSet(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	result, err := rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log(result)
	err = rdb.HSet(ctx, "user", "name", "张德志").Err()
	if err != nil {
		panic(err)
	}
	t.Log("设置hash成功")
}

  1. HGet 获取哈希值
func TestHGet(t *testing.T) {
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err := rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Logf("连接数据库成功")
	result, err1 := rdb.HGet(ctx, "user", "name").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Logf("获取值:%s", result)
}

  1. TestHGetAll 获取所有哈希值
func TestHGetAll(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr: "127.0.0.1:6379",
		DB:   0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log("连接数据库成功")
	result, err1 := rdb.HGetAll(ctx, "user").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(result)
}
  1. HIncrBy 哈希累加
func TestHIncrBy(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log("数据库连接成功")
	count, err1 := rdb.HIncrBy(ctx, "user", "count", 2).Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(count)
}
  1. HKeys 获取所有 keys
func TestHKeys(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log("连接数据库成功")
	keys, err1 := rdb.HKeys(ctx, "user").Result()
	if err1 != nil {
		panic(err)
	}
	t.Log(keys)
}

  1. HLen 查询字段数量
func TestHLen(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log("连接数据库成功")
	result, err1 := rdb.HLen(ctx, "user").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(result)

}

  1. HMGet 批量获取
func TestMGet(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	result, err1 := rdb.HMGet(ctx, "user", "name", "count").Result()
	if err1 != nil {
		panic(err)
	}
	t.Log(result)
}
  1. HMSet 批量设置
func TestHMSet(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	data := make(map[string]interface{})
	data["name"] = "周华建"
	data["age"] = 44
	data["gender"] = "男"

	err = rdb.HMSet(ctx, "user", data).Err()
	if err != nil {
		panic(err)
	}
}
  1. HDel 删除值
func TestHDel(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.HDel(ctx, "user", "name").Err()
	if err != nil {
		panic(err)
	}

}
  1. 检测是否存在
func TestHExists(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr: "127.0.0.1:6379",
		DB:   0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	result, err1 := rdb.HExists(ctx, "user", "name").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(result)
}

List 类型

  1. TestLPush 左侧插入
func TestLPush(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}

	err = rdb.LPush(ctx, "key", 1, 2, 3, 4, 5).Err()
	if err != nil {
		panic(err)
	}
	t.Log("插入成功")
}
  1. 判断集合左侧是否可以插入,如果存在则不插入,如果不存在则插入
func TestLPushX(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.LPushX(ctx, "key", 6, 7, 8).Err()
	if err != nil {
		panic(err)
	}
}
  1. 从右则删除一个值并返回删除后的值
func TestRPop(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	val, err1 := rdb.RPop(ctx, "key").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(val)
}
  1. RPush 从列表右则插入值
func TestRPush(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.RPush(ctx, "key", 12).Err()
	if err != nil {
		panic(err)
	}
}

  1. LPop 从左侧删除
func TestLPop(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	result, err1 := rdb.LPop(ctx, "key").Result()
	if err1 != nil {
		panic(err1)
	}
	fmt.Println(result)
}
  1. LLen 获取集合的长度
func TestLLen(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	result, err1 := rdb.LLen(ctx, "key").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(result)
}
  1. 遍历集合
func TestLRange(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	result, err1 := rdb.LRange(ctx, "key", 0, -1).Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(result)

}
  1. 删除数据
func TestLRem(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log("数据库连接成功")
	err = rdb.LRem(ctx, "key", 0, -1).Err()
	if err != nil {
		panic(err)
	}
	t.Log("删除成功")

}

  1. 获取值的索引
func TestLIndex(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr: "127.0.0.1:6379",
		DB:   0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}

	val, err := rdb.LIndex(ctx, "key", 1).Result()
	if err != nil {
		panic(err)
	}
	t.Log(val)
}

set 集合

  1. sadd 添中集合
func TestSAdd(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.SAdd(ctx, "set", 100).Err()
	if err != nil {
		panic(err)
	}
	t.Log("添加集合成功")
}
  1. scard 获取集合元素个数
func TestSCard(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr: "127.0.0.1:6379",
		DB:   0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	t.Log("连接数据库成功")
	size, err := rdb.SCard(ctx, "set").Result()
	if err != nil {
		panic(err)
	}
	t.Log(size)
}

3.sIsmember 判断元素是否在集合中

func TestSIsMember(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	ok, _ := rdb.SIsMember(ctx, "key", 100).Result()
	if !ok {
		t.Log("集合不含令指定元素")
		return
	}
	t.Log("集合包含指定元素")
}
  1. smembers 获取集合中所有的元素
func TestSMembers(t *testing.T) {

	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	values, err1 := rdb.SMembers(ctx, "set").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(values)
}

  1. srem 删除集合中元素
func TestSRem(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.SRem(ctx, "set", 100).Err()
	if err != nil {
		panic(err)
	}
	t.Log("删除成功")
}

  1. SPop 随机删除并返回删除的值
func TestSPop(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	val, _ := rdb.SPop(ctx, "set").Result()
	t.Log(val)
	vals, _ := rdb.SPopN(ctx, "set", 5).Result()
	t.Log(vals)
}

可排序集合

  1. zadd 添加一个或多个元素到集合,如果元素已经存在则更新分数
func TestZAdd(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
		DB:   0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.ZAdd(ctx, "zAdd", redis.Z{Score: 2.5, Member: "张德志"}).Err()
	if err != nil {
		panic(err)
	}
	t.Log("插入成功")
}

  1. zcard 返回集合元素个数
func TestZCard(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	size, err1 := rdb.ZCard(ctx, "zAdd").Result()
	if err1 != nil {
		panic(err)
	}
	t.Log(size)

}

  1. zCount 获取某个区间的值
func TestZCount(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	size, err1 := rdb.ZCount(ctx, "zAdd", "1", "5").Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(size)

}

  1. ZIncrBy 增加元素的分数
func TestZIncrBy(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.ZIncrBy(ctx, "zAdd", 2, "张德志").Err()
	if err != nil {
		panic(err)
	}
}

  1. zrange 返回集合中某个索引范围的元素
func TestZRange(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	result, err1 := rdb.ZRange(ctx, "zAdd", 0, -1).Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(result)

}
  1. ZRangeByScore 根据分数范围返回集合元素,元素根据分数从小到大排序,支持分页
func TestZRangeByScore(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	opt := redis.ZRangeBy{
		Min:    "2",
		Max:    "1000",
		Offset: 0,
		Count:  5,
	}
	vals, err1 := rdb.ZRangeByScore(ctx, "set", &opt).Result()
	if err1 != nil {
		panic(err1)
	}
	t.Log(vals)
}
  1. 根据指定 key 删除元素
func TestZRem(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.ZRem(ctx, "zAdd", "张德志").Err()
	if err != nil {
		panic(err)
	}
	t.Log("删除成功")
}
  1. ZRemRangeByRank 根据索引范围删除元素
func TestZRemRangeByRank(t *testing.T) {
	var err error
	ctx := context.Background()
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})
	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		panic(err)
	}
	err = rdb.ZRemRangeByRank(ctx, "zAdd", 0, 1).Err()
	if err != nil {
		panic(err)
	}
	t.Log("删除成功")
}

相关链接

演示地址
获取更多
源码地址

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

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

相关文章

论文《OneLLM:One Framework to Align All Modalities with Language》

(没有会员只有做100个节点,mindmaster金主爸爸可不可以给我一个会员啊啊啊啊呜呜呜~) 欣赏论文的图和表: 表中作者将自己的模型那一行选择灰色作为背景,更加凸显自己的数据,另外对于最好的结果用加粗黑体…

threads_created增加过大?

set global thread_cache_size128; 在my.cnf文件中直接加上thread_cache_size128 原值为58 MySQL中的Threads线程相关指标解读 - SRE Work mysql性能优化(thread_created) - 八戒vs - 博客园 MySQL :: MySQL 8.4 Reference Manual :: 7.1.10 Server Status Variables

基于Vue3+axios+element-plus等技术开发的新闻发布管理系统

新闻发布管理系统是一个基于Vue3piniavue-routeraxioselement-plus等开发的系统,主要功能包括:登录模块、注册模块、新闻分类管理模块、新闻管理模块、个人中心模块(包括基本资料、更换头像、重置密码功能)等。 代码下载&#xf…

凡事预则立,不预则废

在交易的竞技场上,每位交易员都拥有自己的一套打法,这些独特的交易风格不仅塑造了他们的个人特点,更是他们成功的关键所在。今天采访的Eagle Trader交易员刘先生,就给我一种很稳妥的感觉,那么,刘先生的“稳…

Linux使用Docker部署Paperless-ngx结合内网穿透打造无纸化远程办公

文章目录 前言1. 部署Paperless-ngx2. 本地访问Paperless-ngx3. Linux安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 前言 本文主要介绍如何在Linux系统本地部署Paperless-ngx开源文档管理系统,并结合cpolar内网穿透工具解决本地部署…

腾讯云License 相关

腾讯云视立方 License 是必须购买的吗? 若您下载的腾讯云视立方功能模块中,包含直播推流(主播开播和主播观众连麦/主播跨房 PK)、短视频(视频录制编辑/视频上传发布)、终端极速高清和腾讯特效功能模块&…

【springboot9734】基于springboot+vue的财务管理系统

作者主页:Java码库 主营内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 项目描述 随着信息技术和网络技术的飞速发展,人类已进…

2024 kali虚拟机安装教程,分两大步骤,图文讲解(2)

准备工作: 按照图文讲解(1)搭建好虚拟机,继续以下步骤 2024 kali虚拟机安装教程,分两大步骤,图文讲解(1)-CSDN博客 正式开始 1.开启,↑ ↓ 方向键,选择第一…

2024双十一有什么值得买?2024年双十一必买清单大全!

双十一购物狂欢节即将到来,这是一年中家电和数码产品打折的绝佳时机。然而,随着产品的多样化,选择一款合适的商品变得越来越困难。今天,我将为大家分享一些在双十一期间值得选购的高品质好物,让我们一起探索这些精选商…

年薪30W的Java程序员都要求熟悉JVM与性能调优!

一、JVM 内存区域划分 1.程序计数器(线程私有) 程序计数器(Program Counter Register),也有称作为 PC 寄存器。保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址&#xff0…

自动化测试 | 窗口截图

driver.get_screenshot_as_file 是 Selenium WebDriver 的一个方法,它允许你将当前浏览器窗口(或标签页)的截图保存为文件。这个方法对于自动化测试中的截图验证非常有用,因为它可以帮助你捕获测试执行过程中的页面状态。 以下是…

EcoVadis认证内容有哪些?EcoVadis认证申请流程?

EcoVadis认证是一个国际性的可持续发展评估平台,旨在帮助全球企业和供应链评鉴其在环境、社会和治理(ESG)方面的表现。该认证框架由法国的检验、认证和检测机构必维集团(Bureau Veritas)创建,得到了众多跨国…

python34_可变字符串

可变字符串 说明 在 Python 中,字符串属于不可变对象,不支持原地修改,如果需要修改其中的值,智能创建新的字符串对象。 但是,经常我们确实需要原地修改字符串,可以使用 io.StringIO对象或 array 模块impo…

光伏开发:一充一放和两充两放是什么意思?

一充一放 一充一放是指储能设备在一次充电过程中充满电,并在一次放电过程中将电能全部释放。这种模式的原理相对简单,充电时电能转化为化学能或其他形式的能量储存,放电时则将这些能量转化回电能供应给负载。一充一放模式适用于对储能设备充…

国家医保局印发《长期护理保险专家库管理暂行办法》

银发经济『新趋势大数据』 AgeNews 每日银发产业大事件速览 2024-10-10 星期四 AgeClub整理 国家医保局印发《长期护理保险专家库管理暂行办法》 北京出台《关于加强“老老人”服务保障的若干措施》 《2024全景生态流量秋季报告》:茶饮、生鲜市场均迎来70后扩…

【有啥问啥】 群体智能(Swarm Intelligence):从自然到人工智能的深度探索

群体智能(Swarm Intelligence):从自然到人工智能的深度探索 什么是群体智能? 群体智能(Swarm Intelligence)是一个迷人的研究领域,它专注于社会性生物(如蚂蚁、蜜蜂、鸟类等&#…

uniapp学习(004-1 组件 Part.1)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战,开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第26p-第p30的内容 文章目录 uniapp和vue差异对比写几个组件并且引用props传值添加类型约束约束类型并且添加默…

JVM性能调优-JVM工具使用

命令行工具 jps jps -q 只看进程id jps -l 显示java进程的完整类名 jps -m 查看传递给主类main()的参数 jps -v 列出虚拟机启动时的jvm参数 以上参数可以组合使用 jstat 查看JVM统计信息 例:jstat -gc -t 19788 1000 10 -gc:打印gc统计信息 ;-t&am…

使用激光跟踪仪提升码垛机器人精度

标题1.背景 码垛机器人是一种用于工业自动化的机器人,专门设计用来将物品按照一定的顺序和结构堆叠起来,通常用于仓库、物流中心和生产线上,它们可以自动执行重复的、高强度的搬运和堆垛任务。 图1 码垛机器人 传统调整码垛机器人的方法&a…

王松绿读《归潮》:岭南文化根脉中流动的文学镜像

王松绿 ,生于河南。后于琼从军为文近二十载。现居三亚。 岭南文化根脉中流动的文学镜像 王松绿 小说《归潮》,打破了作者陈崇正向来善于营造的多重宇宙和多线叙事的阅读迷障,故事角色与作者一起,实现了叙事方式、故事内容…