【Redis 初阶】Redis 常见数据类型(Set、Zset、渐进式遍历、数据库管理)

news2024/11/27 17:50:03

一、Set 集合

集合类型也是保存多个字符串类型的元素的(可以使用 json 格式让 string 也能存储结构化数据),但和列表类型不同的是,集合中:

  1. 元素之间是无序的。(此处的 “无序” 是和 list 的有序相对应的)
  2. 元素不允许重复,如下图所示。

集合类型:

一个集合中最多可以存储个元素。Redis 除了支持集合内的增删查改操作,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多问题。

  • list:[1, 2, 3] 和 [2, 1, 3] 是两个不同的 list
  • set:[1, 2, 3] 和 [2, 1, 3] 是同一个集合

1、普通命令

(1)SADD

将⼀个或者多个元素添加到 set 中。

注意:重复的元素无法添加到 set 中。

语法:

SADD key member [member ...]

命令有效版本:

1.0.0 之后

时间复杂度:

O(1)

返回值:

本次添加成功的元素个数。

示例:


(2)SMEMBERS

获取一个 set 中的所有元素,注意,元素间的顺序是无序的。

语法:

SMEMBERS key

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 是集合中的元素个数。

返回值:

所有元素的列表。

示例:


(3)SISMEMBER

判断一个元素在不在 set 中。

语法:

SISMEMBER key member

命令有效版本:

1.0.0 之后

时间复杂度:

O(1)

返回值:

1 表示元素在 set 中。0 表示元素不在 set 中或者 key 不存在。

示例:


(4)SCARD

获取一个 set 的基数(cardinality),即 set 中的元素个数。

语法:

SCARD key

命令有效版本:

1.0.0 之后

时间复杂度:

O(1)

返回值:

set 内的元素个数。

示例:


(5)SPOP

从 set 中删除并返回⼀个或者多个元素。

注意:由于 set 内的元素是无序的,所以取出哪个元素实际是未定义行为,即可以看作随机的。

语法:

SPOP key [count] 

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 是 count

返回值:

取出的元素。

示例:


(6)SMOVE

将一个元素从源 set 取出并放入目标 set 中。

语法:

SMOVE source destination member 

命令有效版本:

1.0.0 之后

时间复杂度:

O(1)

返回值:

1 表示移动成功,0 表示失败。

示例:

针对上述情况,smove 不会视为出错,也会按照删除、插入来执行。


(7)SREM

将指定的元素从 set 中删除。

语法:

SREM key member [member ...]  

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 是要删除的元素个数.

返回值:

本次操作删除的元素个数。

示例:


2、集合间操作

交集(inter)、并集(union)、差集(diff)的概念如下图所示:

集合求交集、并集、差集:


(1)SINTER

获取给定 set 的交集中的元素。

语法:

SINTER key [key ...]

命令有效版本:

1.0.0 之后

时间复杂度:

O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数。

返回值:

交集的元素。

示例:


(2)SINTERSTORE

获取给定 set 的交集中的元素并保存到目标 set 中。

要想知道交集的内容,直接按照集合的方式访问目标 set 这个 key 即可。

语法:

SINTERSTORE destination key [key ...] 

命令有效版本:

1.0.0 之后

时间复杂度:

O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数。

返回值:

交集的元素个数。

示例:


(3)SUNION

获取给定 set 的并集中的元素。

语法:

SUNION key [key ...]  

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 给定的所有集合的总的元素个数。

返回值:

并集的元素。

示例:


(4)SUNIONSTORE

获取给定 set 的并集中的元素并保存到目标 set 中。

语法:

SUNIONSTORE destination key [key ...]

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 给定的所有集合的总的元素个数。

返回值:

并集的元素个数。

示例:


(5)SDIFF

获取给定 set 的差集中的元素。

语法:

SDIFF key [key ...]

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 给定的所有集合的总的元素个数。

返回值:

差集的元素。

示例:


(6)SDIFFSTORE

获取给定 set 的差集中的元素并保存到⽬标 set 中。

语法:

SDIFFSTORE destination key [key ...] 

命令有效版本:

1.0.0 之后

时间复杂度:

O(N),N 给定的所有集合的总的元素个数.

返回值:

差集的元素个数。

示例:


3、命令小结

下表总结了集合类型的常见命令:

集合类型命令:


4、内部编码

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数并且元素的个数小于 set-max-intset-entries 配置(默认 512 个)时,Redis 会选用 intset 来作为集合的内部实现,从而减少内存的使⽤。
  • hashtable(哈希表):当集合类型无法满足 intset 的条件时,Redis 会使用 hashtable 作为集合的内部实现。

(1)当元素个数较少并且都为整数时,内部编码为 intset

(2)当元素个数超过 512 个,内部编码为 hashtable

(3)当存在元素不是整数时,内部编码为 hashtable

 


5、使用场景

场景一:集合类型比较典型的使用场景是标签(tag)。例如 A 用户对娱乐、体育板块比较感兴趣,B 用户对历史、新闻比较感兴趣,这些兴趣点可以被抽象为标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于增强用户体验和用户黏度都非常有帮助。 例如一个电子商务网站会对不同标签的用户做不同的产品推荐。

下面的演示通过集合类型来实现标签的若干功能。

(1)给用户添加标签

sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
...
sadd user:k:tags tag1 tag2 tag4

(2)给标签添加用户

sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
...
sadd tagk:users user:1 user:4 user:9 user:28

(3)删除用户下的标签

srem user:1:tags tag1 tag5
...

(4)删除标签下的用户

srem tag1:users user:1
srem tag5:users user:1
...

(5)计算用户的共同兴趣标签

sinter user:1:tags user:2:tags

场景二:还可以使用 Set 来计算用户之间的共同好友(基于 “集合求交集”),基于此还可以做一些好友推荐。 

场景三:

使用 Set 还能统计 UV(去重)。一个互联网产品如何衡量用户量,用户规模呢?

主要的指标是以下两个方面:

  1. PV(Page View),用户每次访问该服务器都会产生一个 pv。
  2. UV(User View),每个用户访问服务器都会产生一个 uv,但是同一个用户多次访问并不会使 uv 增加。uv 需要按照用户进行去重,去重的过程就可以使用 Set 来实现。

二、Zset 有序集合

有序集合相对于字符串、列表、哈希、集合来说会有一些陌生。它保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有一个唯一的浮点类型的分数(score)与之关联,着使得有序集合中的元素是可以维护有序的,但这个有序不是用下标作为排序依据而是用这个分数。

Zset 的内部数据结构是跳表。

如下图所示,该有序集合显示了三国中的武将的武力。

有序集合:

有序集合提供了获取指定分数和元素范围查找、计算成员排名等功能,合理地利用有序集合,可以帮助我们在实际开发中解决很多问题。

有序集合中的元素是不能重复的,但分数允许重复。类比于一次考试之后,每个人一定有一个唯一的分数,但分数允许相同。

列表、集合、有序集合三者的异同点: 


1、普通命令

(1)ZADD

添加或者更新指定的元素以及关联的分数到 zset 中,分数应该符合 double 类型,+inf/-inf 作为正负极限也是合法的。注意:负无穷大不是无穷小,负无穷大的绝对值和无穷大是一样的。

ZADD 的相关选项:

  • XX:仅仅用于更新已经存在的元素(member),不会添加新元素。

  • NX:仅用于添加新元素(member),不会更新已经存在的元素。

  • LT:仅当新分数小于当前分数时才更新现有元素,不会阻止添加新元素。

  • GT:仅当新分数大于当前分数时才更新现有元素,不会阻止添加新元素。

  • CH:默认情况下,ZADD 返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。

  • INCR:此时命令类似 ZINCRBY 的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。

语法:

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]

member 和 score 称为是一个 "pair",类似于 C++ 里的 std::pair。不要把它们理解成 “键值对”(key - value pair),键值对中是有明确的 “角色区分”,一定是根据键 -> 值。而对于有序集合来说,既可以通过 member 找到对应的 score,也可以通过 score 找到匹配的 member。

命令有效版本:

1.2.0 之后

时间复杂度:

O(log(N))

返回值:

返回新增成功的元素个数。

示例:

如果修改的分数影响到了之前的顺序,就会自动的移动元素位置,保持原有的升序顺序不变:


(2)ZCARD

获取一个 zset 的基数(cardinality),即 zset 中的元素个数。

语法:

ZCARD key 

命令有效版本:

1.2.0 之后

时间复杂度:

O(1)

返回值:

zset 内的元素个数。

示例:


(3)ZCOUNT

返回分数在 min 和 max 之间的元素个数,默认情况下,min 和 max 都是包含的,如果不想要边界值,可以通过在边界值前加上 '(' 来排除。

语法:

ZCOUNT key min max

命令有效版本:

2.0.0 之后

时间复杂度:

O(log(N))

先根据 min 找到对应的元素,再根据 max 找到对应的元素,两次都是 O(log(N))。实际上,Zset 内部会记录每个元素当前的 “排行” / “次序”,查询到元素就直接知道了元素所在的 “次序”(下标),就可以直接把 max 对应的元素次序和 min 对应的元素次序做减法即可。

返回值:

满足条件的元素列表个数。

示例:


(4)ZRANGE

返回指定区间里的元素,分数按照升序。带上 WITHSCORES 可以把分数也返回。

语法:

ZRANGE key start stop [WITHSCORES]  

此处的 [start, stop] 为下标构成的区间,从 0 开始,支持负数。

命令有效版本:

1.2.0 之后

时间复杂度:

O(log(N)+M),N 是整个有序集合的元素个数,M 是 start - stop 区间内的元素个数。

返回值:

区间内的元素列表。

示例:

Redis 内部存储数据是按照二进制的方式存储的,意味着 Redis 服务器是不负责字符编码的,所以要把二进制对回到汉字需要客户端支持:


(5)ZREVRANGE

返回指定区间里的元素,分数按照降序。带上 WITHSCORES 可以把分数也返回。

备注:这个命令可能在 6.2.0 之后废弃,并且功能合并到 ZRANGE 中。

语法:

ZREVRANGE key start stop [WITHSCORES] 

命令有效版本:

1.2.0 之后

时间复杂度:

O(log(N)+M)

返回值:

区间内的元素列表。

示例:


(6)ZRANGEBYSCORE(弃用)

返回分数在 min 和 max 之间的元素,默认情况下,min 和 max 都是包含的,可以通过 '(' 排除。

备注:这个命令可能在 6.2.0 之后废弃,并且功能合并到 ZRANGE 中。

语法:

ZRANGEBYSCORE key min max [WITHSCORES]  

命令有效版本:

1.0.5 之后

时间复杂度:

O(log(N)+M)

返回值:

区间内的元素列表。

示例:


(7)ZPOPMAX

删除并返回分数最高的 count 个元素。

语法:

ZPOPMAX key [count]

命令有效版本:

5.0.0 之后

时间复杂度:

O(log(N) * M),N 是有序集合的元素个数,M 表示 count,要删除的元素个数。

既然是尾删,为什么不把最后一个元素的位置特殊标记一下,后续删除不久省却了查找过程,直接 O(1) 了吗?

这个是有可能的,但是目前 Redis 并没有这么做。事实上,Redis 的源码中针对有序集合确实是记录了尾部的特定位置,但是在实际删除的时候并没有用上这个特性,而是直接调用了一个 “通用的删除函数”(给定一个 member 的值,进行查找,找到位置之后再删除)。(个人认为此处是存在优化空间的)

返回值:

分数和元素列表。

示例:

如果存在多个元素分数相同(分数是主要因素,相同的情况下会按照 member 字符串的字典序来决定先后顺序),同时为最大值,那么 zpopmax 删除最大元素时,仍然只会删除其中一个元素。


(8)BZPOPMAX

ZPOPMAX 的阻塞版本。可以同时读多个有序集合。

语法:

BZPOPMAX key [key ...] timeout

timeout 单位是 s,支持小数形式。

命令有效版本:

5.0.0 之后

时间复杂度:

O(log(N)),删除最大值花费的时间。

如果当前 BZPOPMAX 同时监听多个 key,假设 key 是 M 个,那么此时时间复杂度是 O(log(N) * M) 吗?

每个这样的 key 上面都删除一次元素才需要 * M,而这里是从这若干个 key 中只删除一次。

返回值:

元素列表。

示例:


(9)ZPOPMIN

删除并返回分数最低的 count 个元素。

语法:

ZPOPMIN key [count] 

命令有效版本:

5.0.0 之后

时间复杂度:

O(log(N) * M)

返回值:

分数和元素列表。

示例:


(10)BZPOPMIN

ZPOPMIN 的阻塞版本。

语法:

BZPOPMIN key [key ...] timeout

命令有效版本:

5.0.0 之后

时间复杂度:

O(log(N))

返回值:

元素列表。

示例:


(11)ZRANK

返回指定元素的排名,升序。

语法:

ZRANK key member

命令有效版本:

2.0.0 之后

时间复杂度:

O(log(N))

ZRANK 查找元素的过程和 ZCOUNT 是一样的。

返回值:

排名。

示例:


(12)ZREVRANK

返回指定元素的排名,降序

语法:

ZREVRANK key member 

命令有效版本:

2.0.0 之后

时间复杂度:

O(log(N))

返回值:

排名。

示例:


(13)ZSCORE

返回指定元素的分数。

语法:

ZSCORE key member 

命令有效版本:

1.2.0 之后

时间复杂度:

O(1)

此处相当于 Redis 对于这样的查询操作做了特殊优化,付出了额外的空间代价。

返回值:

分数。

示例:


(14)ZREM

删除指定的元素。

语法:

ZREM key member [member ...] 

命令有效版本:

1.2.0 之后

时间复杂度:

O(M*log(N))

返回值:

本次操作删除的元素个数。

示例:


(15)ZREMRANGEBYRANK

按照排序,升序删除指定范围的元素,左闭右闭。

语法:

ZREMRANGEBYRANK key start stop  

命令有效版本:

2.0.0 之后

时间复杂度:

O(log(N)+M)

返回值:

本次操作删除的元素个数。

示例:


(16)ZREMRANGEBYSCORE

按照分数删除指定范围的元素,左闭右闭,也可以使用 '(' 来排除边界值。

语法:

ZREMRANGEBYSCORE key min max 

命令有效版本:

1.2.0 之后

时间复杂度:

O(log(N)+M)

返回值:

本次操作删除的元素个数。

示例:


(17) ZINCRBY

为指定的元素的关联分数添加指定的分数值。

语法:

ZINCRBY key increment member

命令有效版本:

1.2.0 之后

时间复杂度:

O(log(N))

返回值:

增加后元素的分数。

示例:

ZINCRBY 不光会修改分数内容,也能同时移动元素位置,保证整个有序集合仍然是升序的。


2、集合间操作

有序集合的交集操作:


(1)ZINTERSTORE

求出给定有序集合中元素的交集并保存进目标有序集合中,在合并过程中以元素为单位进行合并,元素对应的分数按照不同的聚合方式和权重得到新的分数。

在有序集合中,member 是元素的本体,score 只是辅助排序的工具人。因此,在进行比较 “相同” 时,只要 member 相同即可。如果 member 相同,score 不同,进行交集合并之后的最终分数看 AGGREGATE 后面的属性。

语法:

ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]
numkeys 是一个整数,用来描述后续有几个 key 参与交集运算。

命令有效版本:

2.0.0 之后

时间复杂度:

O(N*K)+O(M*log(M)),N 是输入的有序集合中,最小的有序集合的元素个数;K 是输入了几个有序集合;M 是最终结果的有序集合的元素个数。

返回值:

目标集合中的元素个数。

示例:


有序集合的并集操作:


(2)ZUNIONSTORE

求出给定有序集合中元素的并集并保存进目标有序集合中,在合并过程中以元素为单位进行合并,元素对应的分数按照不同的聚合方式和权重得到新的分数。

语法:

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

命令有效版本:

2.0.0 之后

时间复杂度:

O(N)+O(M*log(M)) N 是输入的有序集合总的元素个数,M 是最终结果的有序集合的元素个数。

返回值:

目标集合中的元素个数

示例:


3、命令小结

有序集合命令:


4、内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数小于 zset-max-ziplist-entries 配置(默认 128 个),同时每个元素的值都小于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会用 ziplist 来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。
  • skiplist(跳表):当 ziplist 条件不满足时,有序集合会使用 skiplist 作为内部实现,因为此时 ziplist 的操作效率会下降。

简单来说,跳表是一个 “复杂链表”,查询元素的时间复杂度是 O(logN)。相比于树形结构,更适合按照范围获取元素。

(1)当元素个数较少且每个元素较小时,内部编码为 ziplist

(2)当元素个数超过 128 个,内部编码 skiplist

(3)当某个元素大于 64 字节时,内部编码 skiplist


5、使用场景

有序集合比较典型的使用场景就是排行榜系统。例如常见的网站上的热榜信息,榜单的维度可能是多方面的:按照时间、按照阅读量、按照点赞量。本例中我们使用点赞数这个维度,维护每天的热榜:

(1)添加用户赞数

例如用户 james 发布了一篇文章,并获得 3 个赞,可以使用有序集合的 zadd 和 zincrby 功能:

zadd user:ranking:2022-03-15 3 james

之后如果再获得赞,可以使用 zincrby:

zincrby user:ranking:2022-03-15 1 james

(2)取消用户赞数

由于各种原因(例如用户注销、用户作弊等)需要将用户删除,此时需要将用户从榜单中删除掉,可以使用 zrem。例如删除成员 tom:

zrem user:ranking:2022-03-15 tom


(3)展示获取赞数最多的 10 个用户

此功能使用 zrevrange 命令实现:

zrevrangebyrank user:ranking:2022-03-15 0 9

(4)展示用户信息以及用户分数

次功能将用户名作为键后缀,将用户信息保存在哈希类型中,至于用户的分数和排名可以使用 zscore 和 zrank 来实现。

hgetall user:info:tom
zscore user:ranking:2022-03-15 mike
zrank user:ranking:2022-03-15 mike

三、渐进式遍历

Redis 使用 scan 命令进行渐进式遍历键,进而解决直接使用 keys 获取键时可能出现的阻塞问题。不是一个命令将所有的 key 都拿到,而是每执行一次命令,只获取到其中的一小部分,这样就可以保证当前这一次操作不会太卡。每次 scan 命令的时间复杂度是 O(1),但是要完整地完成所有键的遍历,需要执行多次 scan。渐进式遍历其实是一组命令,这一组命令的使用方法是一样的。整个过程如下图所示:

scan 命令渐进式遍历

  • 首次 scan 从 0 开始。
  • 当 scan 返回的下次位置为 0 时,遍历结束。

返回值的前半部分1)是告诉我们,下次继续遍历的光标(当作一个字符串即可)要从哪里开始。第二部分2)是我们真正遍历到的 key 的内容。


1、SCAN

以渐进式的方式进行键的遍历。

渐进式遍历再遍历过程中不会在服务器这边存储任何的状态信息,此处的遍历是随时可以终止的,不会对服务器产生任何的副作用。

语法:

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]

这里的 count 是限制这一次遍历能够获取到多少个元素,默认是 10。

注意:此处的 count(给 Redis 服务器一个 “提示” / “建议”,写入的 count 和实际返回的 key 的个数不一定完全相同,但是不会差很多)和 MySQL 的 limit(精确的)不一样。

命令有效版本:

2.8.0 之后

时间复杂度:

O(1)

返回值:

下一次 scan 的游标(cursor)以及本次得到的键。

示例:

除了 scan 以外,Redis 面向哈希类型、集合类型、有序集合类型分别提供了 hscan、sscan、zscan 命令,它们的用法和 scan 基本类似。

注意:渐进性遍历 scan 虽然解决了阻塞的问题,但如果在遍历期间键有所变化(增加、修改、删除),可能导致遍历时键的重复遍历或者遗漏。


四、数据库管理

Redis 提供了几个面向 Redis 数据库的操作,分别是命令:dbsize、select、flushdb、flushall。


1、切换数据库

select dbIndex  

许多关系型数据库,例如 MySQL 支持在一个实例下有多个数据库存在的,但是与关系型数据库用字符来区分不同数据库名不同,Redis 只是用数字作为多个数据库的实现。Redis 默认配置中是有 16 个数据库,我们不能创建新的数据库,也不能删除已有的数据库,这 16 个数据库中的数据是隔离的(相互之间不会有影响)。select 0 操作会切换到第⼀个数据库,select 15 会切换到最后⼀个数据库。

0 号数据库和 15 号数据库保存的数据是完全不冲突的,如下图所示,即各种有各自的键值对。默认情况下,我们处于数据库 0。

Redis 管理的数据库:

Redis 中虽然支持多数据库,但随着版本的升级,其实不是特别建议使用多数据库特性。如果真的需要完全隔离的两套键值对,更好的做法是维护多个 Redis 实例,而不是在一个 Redis 实例中维护多数据库。这是因为本身 Redis 并没有为多数据库提供太多的特性,其次无论是否有多个数据库,Redis 都是使用单线程模型,所以彼此之间还是需要排队等待命令的执行。同时多数据库还会让开发、调试和运维工作变得复杂。所以实践中,始终使用数据库 0 其实是⼀个很好的选择


2、清除数据库

flushdb / flushall 命令用于清除数据库,区别在于 flushdb 只清除当前数据库,flushall 会清楚所有数据库。

永远不要在线上环境执行清除数据的操作,除非你想体验一把 “从删库到跑路” 的操作。 

语法:

FLUSHDB [ASYNC | SYNC] 

FLUSHALL [ASYNC | SYNC] 

  • ASYNC:异步
  • SYNC:同步

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

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

相关文章

重载云台摄像机如何通过国标28181接入到统一视频接入平台(视频国标接入平台)

目录 一、国标GB/T 28181介绍 1、国标GB/T28181 2、内容和特点 二、重载云台摄像机 1、定义 2、结构与设计 3、功能和优势 4、特点 5、应用场景 二、接入准备工作 1、确定网络环境 &#xff08;1&#xff09;公网接入 &#xff08;2&#xff09;专网传输 2、检查重…

软件测试基础1--功能测试

1、什么是软件测试&#xff1f; 软件是控制计算机硬件运行的工具。 软件测试&#xff1a;使用技术手段验证软件是否满足使用需求&#xff0c;为了发现软件功能和需求不相符合的地方&#xff0c;或者寻找实际输出和预期输出之间的差异。 软件测试的目的&#xff1a;减少软件缺陷…

golang JSON序列化

JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 json历史 [外链图片转存失败,源站可能有防盗链机…

080基于ssm+vue的大学生兼职信息系统

开发语言&#xff1a;Java框架&#xff1a;ssmJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.…

获客工具大揭秘:为何它能让获客如此轻松?

你是不是也觉得&#xff0c;现在的市场环境&#xff0c;获客越来越难了&#xff1f; 今天我要给大家分享一个实用且高效的获客工具&#xff0c;它简直是营销界的福音&#xff01; 1、关键词搜索 关键词搜索功能是获客工具的基础&#xff0c;也是其重要性不可小觑的原因。 这…

【数据中台】大数据管理平台建设方案(原件资料)

建设大数据管理中台&#xff0c;按照统一的数据规范和标准体系&#xff0c;构建统一数据采集&#xfe63;治理&#xfe63;共享标准、统一技术开发体系、统一接口 API &#xff0c;实现数据采集、平台治理&#xff0c;业务应用三层解耦&#xff0c;并按照统一标准格式提供高效的…

LabVIEW发电机控制器自动测试系统

随着飞机电源系统对自动化与精确控制需求的提高&#xff0c;开发了一套基于LabVIEW和NI PXI硬件平台的飞机发电机控制器测试系统。该系统利用先进的测试技术&#xff0c;实现对飞机发电机控制器的自动测试&#xff0c;显著提升测试的效率、精度和一致性。 项目背景 飞机发电机…

nginx反向代理+nginx黑白名单+nginx负载均衡+平滑升级+配置jdk环境-7.30

一、反向代理 1.前端服务器配置 前端服务器&#xff1a;用于接收和响应客户端&#xff0c;代理另一台主机 Nginx 安装 (1).下载安装nginx [rootweb ~]# wget https://nginx.org/download/nginx-1.26.1.tar.gz (2).解压 [rootweb ~ ]# tar -zxvf nginx-1.26.1.tar.gz (3…

《从零开始做个摸鱼小网站! · 序》灵感来源

序 大家好呀&#xff0c;我是summo&#xff0c;这次来写写我在上班空闲(摸鱼)的时候做的一个小网站的事。去年阿里云不是推出了个活动嘛&#xff0c;2核2G的云服务器一年只要99块钱&#xff0c;懂行的人应该知道这个价格在业界已经是非常良心了&#xff0c;虽然优惠只有一年&a…

【论文共读】【翻译】【CGAN】【Conditional Gernerative Adversarial Networks】

论文地址&#xff1a;https://arxiv.org/pdf/1411.1784 翻译&#xff1a; Conditional Gernerative Adversarial Networks 条件生成对抗网络 0. 摘要 生成对抗网络[8]最近被引入&#xff0c;作为一种训练生成模型的新方法。在这项工作中&#xff0c;我们引入了生成对抗网络的…

同步与异步,阻塞与非阻塞的深入分析

&#x1f60e; 作者介绍&#xff1a;欢迎来到我的主页&#x1f448;&#xff0c;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff08;领取大厂面经等资料&#xff09;&#xff0c;欢迎加我的…

人在迷茫无聊时该干什么?

做两件事&#xff0c;收和放。 第一件事收&#xff0c;全面收缩。 迷茫不是无事可做&#xff0c;而是所做的事没有意义&#xff0c;没有意义就停掉&#xff0c;空出时间让身心恢复到正常状态。迷茫会让你焦虑&#xff0c;让你晚睡&#xff0c;让你狂吃&#xff0c;让你迫不及待…

公司里的IT是什么?

公司里的IT是什么&#xff1f; 文章目录 公司里的IT是什么&#xff1f;1、公司里的IT2、IT技术3、IT行业4、IT行业常见证书 如果对你有帮助&#xff0c;就点赞收藏把&#xff01;(&#xff61;&#xff65;ω&#xff65;&#xff61;)&#xff89;♡ 前段时间&#xff0c;在公…

ARMv8 内存属性

目录 普通内存 (normal memory)设备内存&#xff08;device memory&#xff09;arm64 mair_el1 系统寄存器及linux 对其配置页表中的内存属性总结 普通内存 (normal memory) 弱一致性&#xff08;weakly ordered)。 存在分支预测&#xff0c;数据预取&#xff0c;高速缓存行预…

二分算法及其公式

二分查找 二分查找是大多数人第一个接触到的算法&#xff0c;很多人都认为只有有序的数组可以使用二分查找&#xff0c;但这种思想其实是错误的&#xff0c;二分查找是可以用于拥有二段性的数组&#xff0c;而且二分算法是由模板做参考的&#xff0c;所以只要掌握就可以解决大…

【区块链+绿色低碳】基于区块链的双碳能源纳管平台 | FISCO BCOS应用案例

在双碳战略的指导下&#xff0c;南京区块链产业应用协会牵头研发的双碳能源纳管平台&#xff0c;依托区块链、人工智能、云计算、 物联网、大数据、工业互联网与边缘计算等技术&#xff0c;对绿电追溯、需求侧响应、能源微网、源网荷储、隔墙用电、 碳排放权认证、额度计量、预…

矩阵常见分解算法及其在SLAM中的应用

文章目录 常见特殊矩阵定义Cholesky分解&#xff08;正定Hermittian矩阵&#xff0c;分解结果唯一&#xff09;Cholesky分解应用 SVD分解&#xff08;将singularvalues排序后分解唯一&#xff09;SVD 分解的应用&#xff08;任意矩阵&#xff09; QR分解&#xff08;任意矩阵&a…

第六周:机器学习周报

机器学习周报 摘要Abstract机器学习——类神经网络训练不起来怎么办&#xff1f;1. 自动调整学习率&#xff08;learning rate&#xff09;1.1 特制化的Learning Rate——parameter dependent1.1.1 Root Mean Square&#xff08;RMS&#xff0c;均方根&#xff09;1.1.2 RMSPro…

【Python】基础语法(下)

本篇文章将接着上篇文章继续讲解基础语法&#xff1a; &#xff08;4&#xff09;变量 &#xff08;5&#xff09;注释 &#xff08;6&#xff09;输入 &#xff08;7&#xff09;条件语句 四&#xff1a;变量 变量其实就是我们生活中起别名和外号。让变量名指向某个值&a…

旅游卡,免费,旅游是真的吗?真相是……

但这种包来回大交通&#xff0c;一旦成本大于利润&#xff0c;他们就会以各种理由推卸责任。这就是我在“揭秘&#xff1a;共享旅游卡免费旅游&#xff0c;包来回路费&#xff0c;这背后的3大真相&#xff01;”这篇文章里面讲到那个大妈的惨痛教训。 以上这5点真相&#xff0…