当前位置: 首页 > news >正文

Redis存储⑤Redis五大数据类型之 List 和 Set。

目录

1. List 列表

1.1 List 列表常见命令

1.2 阻塞版本命令

1.3 List命令总结和内部编码

1.4 List典型使用场景

1.4.1 消息队列

1.4.2 分频道的消息队列

1.4.3 微博 Timeline

2. Set 集合

2.1 Set 集合常见命令

2.2 Set 集合间命令

2.3 Set命令小结和内部编码

2.4 Set集合使用场景

本篇完。


1. List 列表

列表两端插入和弹出操作:

        列表类型是用来存储多个有序的字符串,如上图所示,a、b、c、d、e 五个元素从左到右组成了一个有序的列表,列表中的每个字符串称为元素(element),一个列表最多可以存储个元素。

        在 Redis 中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等,如下图所示。

列表的获取、删除等操作:

列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

列表类型的特点:

  • 列表中的元素是有序的(指的是顺序很关键,不是指升序 / 降序),这意味着可以通过索引下标获取某个元素或者某个范围的元素列表,例如要获取上图中的第 5 个元素,可以执行 lindex user:1:messages 4 或者倒数第 1 个元素,lindex user:1:messages -1 就可以得到元素 e。
  • 区分获取和删除的区别,例如上图中的 lrem 1 b 是从列表中把从左数遇到的前 1 个 b 元素删除,这个操作会导致列表的长度从 5 变成 4;但是执行 lindex 4 只会获取元素,但列表长度是不会变化的。
  • 列表中的元素是允许重复的,例如下图中的列表中是包含了两个 a 元素的。

列表中允许有重复元素:


1.1 List 列表常见命令

lpush

将一个或者多个元素从左侧放入(头插)到 list 中。

语法:lpush key element [element ...]

命令有效版本:1.0.0 之后

时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。

返回值:插入后 list 的长度。

示例:

前面的序号时专门给结果集使用的序号,和 list 下标无关。


lpushx

在 key 存在时,将一个或者多个元素从左侧放入(头插)到 list 中。不存在,直接返回。

lpushx 指的是:left push exists

语法:lpushx key element [element ...]

命令有效版本:2.0.0 之后

时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。

返回值:插入后 list 的长度。

示例:


rpush

将一个或者多个元素从右侧放入(尾插)到 list 中。

语法:rpush key element [element ...]

命令有效版本:1.0.0 之后

时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。

返回值:插入后 list 的长度。

示例:


rpushx

在 key 存在时,将一个或者多个元素从右侧放入(尾插)到 list 中。

语法:rpushx key element [element ...] 

命令有效版本:2.0.0 之后

时间复杂度:只插入一个元素为 O(1),插入多个元素为 O(N),N 为插入元素个数。

返回值:插入后 list 的长度。

示例:


lrange

获取从 start 到 end 区间的所有元素,左闭右闭(闭区间),下标支持负数。

lrange 指的是:list range

语法:LRANGE key start stop

命令有效版本:1.0.0 之后

时间复杂度:O(N)

返回值:指定区间的元素。

示例:

        Redis 的做法是直接尽可能的获取到给定区间范围内的元素,如果给定区间非法,比如超出下标,就会尽可能的获取对应的内容。


lpop

从 list 左侧取出元素(即头删)。

语法:lpop key 

        Redis 5 版本中在这后面是没有 [count] 参数的,从 Redis 6.2 版本开始,新增了一个 count 参数,用来描述此次要删除几个元素。

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:取出的元素或者 nil。

示例:


rpop

从 list 右侧取出元素(即尾删)。

语法:rpop key

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:取出的元素或者 nil。

示例:

  • 搭配使用 rpush 和 lpop 就相当于队列。
  • 搭配使用 rpush 和 rpop 就相当于栈。

lindex

获取从左数第 index 位置的元素。

lindex 指的是:list index

语法:lindex key index

命令有效版本:1.0.0 之后

时间复杂度:O(N)

返回值:取出的元素或者 nil。

示例:


linsert

在特定位置插入元素。

语法:linsert key <before | after> pivot element

命令有效版本:2.2.0 之后

时间复杂度:O(N),N 表示列表长度。

返回值:插入后的 list 长度。

示例:

        insert 进行插入时,要根据基准值找到对应的位置,从左往右找,找到第一个符合基准值的位置即可。如有两个4:


llen

获取 list 长度。

语法:llen key

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:list 的长度。

示例:


lrem

根据参数 count 的值,移除列表中与参数 element 相等的元素。

  • count > 0 : 从表头开始向表尾搜索,移除与 element 相等的元素,数量为 count。
  • count < 0 : 从表尾开始向表头搜索,移除与 element 相等的元素,数量为 count的绝对值。
  • count = 0 : 移除表中所有与 element 相等的值。

语法:lrem key count element

命令有效版本:1.0.0 之后

时间复杂度:O(N)

返回值:被移除元素的数量。 列表不存在时返回 0 。

示例:


ltrim

        Redis 的 Ltrim 对一个列表进行修剪(trim),也就是说,让列表只保留 start 和 stop 区间内(闭区间)的元素,不在区间之内的元素都将被直接删除。

语法:ltrim key start stop

命令有效版本:1.0.0 之后

时间复杂度:O(N)

返回值:命令执行成功时,返回 OK。

示例:


lset

通过索引来设置元素的值。当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。

语法:lset key index element

命令有效版本:1.0.0 之后

时间复杂度:O(N)

返回值:操作成功返回 OK,否则返回错误信息。

示例:

  • lindex 可以很好的处理下标越界的情况,直接返回 nil。
  • lset 则会报错,不会像 js 一样,直接在 10 这个下标搞出一个元素。

1.2 阻塞版本命令

blpop 和 brpop 是 lpop 和 rpop 的阻塞版本,和对应非阻塞版本的作用基本一致,除了:

  • 在列表中有元素的情况下,阻塞和非阻塞表现是一致的。但如果列表中没有元素,非阻塞版本会直接返回 nil,但阻塞版本会根据 timeout 阻塞⼀段时间(使用 blpop 和 brpop 时,这里是可以显示设置阻塞时间的,不一定是无休止的等待),期间 Redis 可以执行其他命令(此处的 blpop 和 brpop 看起来好像耗时很长,但实际上并不会对 Redis 服务器产生负面影响),但要求执行该命令的客户端会表现为阻塞状态(如下图所示)。
  • 命令中如果设置了多个键(key),那么会从左向右进行遍历键,一旦有一个键对应的列表中可以弹出元素,命令立即返回。
  • 如果多个客户端同时多一个键执行 pop,则最先执行命令的客户端会得到弹出的元素。

阻塞版本的 blpop 和非阻塞版本 lpop 的区别: 


blpop

lpop 的阻塞版本。

语法:blpop key [key ...] timeout

        此处还可以指定超时时间,单位是秒(Redis 6 中,超时时间允许设定成小数,Redis 5 得是整数)。

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:取出的元素或者 nil。

示例:


brpop

rpop 的阻塞版本。

效果和 brpop 类似,只不过这里是头删。

语法:brpop key [key ...] timeout

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:取出的元素或者 nil。

        blpop 和 brpop 这两个阻塞命令的用途主要就是用来作为 “消息队列”。虽然这两个命令可以在一定程度上满足 “消息队列” 这样的需求,但整体来说,功能还是比较有限。 


1.3 List命令总结和内部编码

下表是List命令的作用和时间复杂度:


内部编码

列表类型的内部编码有两种(旧版本,现在已经不再使用,了解即可):

  • ziplist(压缩列表):当列表的元素个数小于 list-max-ziplist-entries 配置(默认 512 个),同时列表中每个元素的长度都小于 list-max-ziplist-value 配置(默认 64 字节)时,Redis 会选用 ziplist 来作为列表的内部编码实现来减少内存消耗。
  • linkedlist(链表):当列表类型无法满足 ziplist 的条件时,Redis 会使用 linkedlist 作为列表的内部实现。

        现在采用的内部编码都是 quicklist。quicklist 相当于是链表和压缩列表的结合,整体还是一个链表,链表的每个节点是一个压缩列表。每个压缩列表都不让它太大,同时再把多个压缩列表通过链式结构连起来。


1.4 List典型使用场景

1.4.1 消息队列

        如下图所示,Redis 可以使用 lpush + brpop 命令组合实现经典的阻塞式生产者-消费者模型队列,生产者客户端使用 lpush 从列表左侧插入元素,多个消费者客户端使用 brpop 命令阻塞式地从队列中 “争抢” 队首元素。通过多个客户端来保证消费的负载均衡和高可用性。

阻塞消息队列模型:

        brpop 是阻塞操作,当列表为空时,brpop 就会阻塞等待,一直等到其他客户端 push 了元素为止。当新元素到达之后,首先是第一个消费者拿到元素(按照执行 brpop 命令的先后顺序来决定是谁获取到)。第一个消费者拿到元素之后,也就从 brpop 中返回了(相当于这个命令执行完了)。如果第一个消费者还想继续消费,就需要重新执行 brpop,排在最后。此时,再来一个新的元素过来,就是第二个消费者拿到该元素,以此类推。


1.4.2 分频道的消息队列

        如下图所示,Redis 同样使用 lpush + brpop 命令,但通过不同的键模拟频道的概念,不同的消费者可以通过 brpop 不同的键值,实现订阅不同频道的理念。

Redis 分频道阻塞消息队列模型:

        多个列表(channel)/ 频道(topic),这种场景很常见,日常使用的一些程序,比如抖音。有一个通道用来传输短视频数据,还可以有一个通道来传输弹幕,一个通道来传输点赞、转发、收藏数据,一个通道来传输评论数据......弄成多个频道就可以在某种数据发生问题时,不会对其他数据造成影响(解耦合)。


1.4.3 微博 Timeline

        每个用户都有属于自己的 Timeline(微博列表),现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。

1. 每篇微博使用哈希结构存储,例如微博中 3 个属性:title、timestamp、content

hmset mblog:1 title xx timestamp 1476536196 content xxxxx
...
hmset mblog:n title xx timestamp 1476536196 content xxxxx

2. 向用户 Timeline 添加微博,user:<uid>:mblogs 作为微博的键

lpush user:1:mblogs mblog:1 mblog:3
...
lpush user:k:mblogs mblog:9

3. 分页获取用户的 Timeline,例如获取用户 1 的前 10 篇微博

keylist = lrange user:1:mblogs 0 9
for key in keylist {hgetall key
}

此方案在实际中可能存在两个问题:

        1 + n 问题。即如果每次分页获取的微博个数较多(不确定当前一页中有多少数据,可能会导致下面的循环次数很多),需要执行多次 hgetall 操作,此时可以考虑使用 pipeline(流水线 / 管道)模式批量提交命令,或者微博不采用哈希类型,而是使用序列化的字符串类型,使用 mget 获取。虽然这里是多个 Redis 命令,但是把这些命令合并成一个网络请求进行通信,这样就大大降低了客户端和服务器之间的交互次数了。

        分裂获取文章时,lrange 在列表两端表现较好,获取列表中间的元素表现较差,此时可以考虑将列表做拆分

选择列表类型时,请参考:

  • 同侧存取(lpush + lpop 或者 rpush + rpop)为栈。
  • 异侧存取(lpush + rpop 或者 rpush + lpop)为队列。

2. Set 集合

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

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

集合类型:

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

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

2.1 Set 集合常见命令

sadd

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

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

语法:sadd key member [member ...]

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:本次添加成功的元素个数。

示例:


smembers

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

语法:smembers key

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 是集合中的元素个数。

返回值:所有元素的列表。

示例:


sismember

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

语法:sismember key member

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:1 表示元素在 set 中。0 表示元素不在 set 中或者 key 不存在。

示例:


scard

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

语法:scard key

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:set 内的元素个数。


spop

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

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

语法:spop key [count] 

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 是 count

返回值:取出的元素。

示例:


smove

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

语法:smove source destination member 

命令有效版本:1.0.0 之后

时间复杂度:O(1)

返回值:1 表示移动成功,0 表示失败。

示例:

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


srem

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

语法:srem key member [member ...]  

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 是要删除的元素个数.

返回值:本次操作删除的元素个数。

示例:


2.2 Set 集合间命令

交集(inter)、并集(union)、差集(diff)的概念和数学一样,如下图所示:

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

sinter

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

语法:sinter key [key ...]

命令有效版本:1.0.0 之后

时间复杂度:O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数。

返回值:交集的元素。

示例:


sinterstore

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

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

语法:sinterstore destination key [key ...] 

命令有效版本:1.0.0 之后

时间复杂度:O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数。

返回值:交集的元素个数。

示例:


sunion

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

语法:sunion  key [key ...]  

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 给定的所有集合的总的元素个数。

返回值:并集的元素。

示例:


sunionstore

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

语法:sunionstore destination key [key ...]

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 给定的所有集合的总的元素个数。

返回值:并集的元素个数。

示例:


sdiff

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

语法:sdiff key [key ...]

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 给定的所有集合的总的元素个数。

返回值:差集的元素。

示例:


sdiffstore

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

语法:sdiffstore destination key [key ...] 

命令有效版本:1.0.0 之后

时间复杂度:O(N),N 给定的所有集合的总的元素个数.

返回值:差集的元素个数。

示例:


2.3 Set命令小结和内部编码

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

Set 集合类型命令:


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

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

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

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

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


2.4 Set集合使用场景

        场景一:集合类型比较典型的使用场景是标签(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
...

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

        场景三:使用 Set 还能统计 UV(去重)。一个互联网产品如何衡量用户量,用户规模呢?主要的指标是以下两个方面:

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

本篇完。

下一篇:Redis存储⑥Redis五大数据类型之Zset+渐进式遍历+数据库管理。

相关文章:

Redis存储⑤Redis五大数据类型之 List 和 Set。

目录 1. List 列表 1.1 List 列表常见命令 1.2 阻塞版本命令 1.3 List命令总结和内部编码 1.4 List典型使用场景 1.4.1 消息队列 1.4.2 分频道的消息队列 1.4.3 微博 Timeline 2. Set 集合 2.1 Set 集合常见命令 2.2 Set 集合间命令 2.3 Set命令小结和内部编码 2.…...

使用PyCharm进行Django项目开发环境搭建

如果在PyCharm中创建Django项目 1. 打开PyCharm&#xff0c;选择新建项目 2.左侧选择Django&#xff0c;并设置项目名称 3.查看项目解释器初始配置 4.新建应用程序 执行以下操作之一&#xff1a; 转到工具| 运行manage.py任务或按CtrlAltR 在打开的manage.pystartapp控制台…...

C# 综合运用介绍

.NET学习资料 .NET学习资料 .NET学习资料 C# 作为一种由微软开发的面向对象编程语言&#xff0c;在软件开发领域占据着重要地位。凭借其简洁、类型安全以及与.NET 框架的紧密结合等特性&#xff0c;C# 被广泛应用于多个领域。下面将详细介绍 C# 的综合运用。 一、C# 语言特性…...

Docker 和 Docker Compose

Docker 和 Docker Compose 是两个相关但用途不同的工具&#xff0c;它们在容器化应用的管理和部署中扮演不同的角色。以下是它们的核心区别&#xff1a; 1. 功能定位 Docker: 是一个容器化平台&#xff0c;用于创建、运行和管理单个容器。适用于单个容器应用的开发和测试。通过…...

文件上传到腾讯云存储、签名及设置过期时间

将文件上传到腾讯云对象存储&#xff08;COS&#xff0c;Cloud Object Storage&#xff09;可以通过腾讯云提供的 SDK 实现。以下是详细的步骤和示例代码&#xff0c;帮助您完成文件上传操作。 步骤 注册腾讯云账号并创建存储桶&#xff1a; &#xff08;1&#xff09;登录腾讯…...

从0开始达芬奇(6)

软件交互 就是与PR&#xff0c;AE软件进行交互。&#xff08;这个就不多说啦&#xff09; 快捷键&#xff08;以下是TIM总结的常用快捷键&#xff09;...

如何在Windows上使用Docker

引言 WSL2&#xff08;Windows Subsystem for Linux2&#xff09;是微软开发的一种技术&#xff0c;允许在 Windows 操作系统上运行 Linux 环境。它提供了一个兼容层&#xff0c;使得用户可以在 Windows 系统中直接运行 Linux 命令行工具、应用程序和开发工具&#xff0c;而无需…...

细胞计数专题 | 如何减少台盼蓝沉淀?

台盼蓝&#xff08;Trypan Blue&#xff09;是一种在生物学研究中广泛使用的染料&#xff0c;尤其常用于细胞活力检测。当细胞死亡时&#xff0c;其细胞膜会变得对台盼蓝具有通透性&#xff0c;染料因而能够进入细胞并与细胞内的蛋白质结合&#xff0c;产生染色效果。由此&…...

go流程控制

流程控制是每种编程语言控制逻辑走向和执行次序的重要部分&#xff0c;流程控制可以说是一门语言的“经脉”。 Go 语言中最常用的流程控制有 if 和 for&#xff0c;而 switch 和 goto 主要是为了简化代码、降低重复代码而生的结构&#xff0c;属于扩展类的流程控制。 if else…...

Spring Web MVC项目的创建及使用

一、什么是Spring Web MVC&#xff1f; Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架&#xff0c;从⼀开始就包含在 Spring 框架中&#xff0c;通常被称为Spring MVC。 1.1 MVC的定义 MVC 是 Model View Controller 的缩写&#xff0c;它是软件工程中的一种软件架构…...

RabbitMQ 从入门到精通:从工作模式到集群部署实战(四)

#作者&#xff1a;闫乾苓 系列前几篇&#xff1a; 《RabbitMQ 从入门到精通&#xff1a;从工作模式到集群部署实战&#xff08;一&#xff09;》&#xff1a;link 《RabbitMQ 从入门到精通&#xff1a;从工作模式到集群部署实战&#xff08;二&#xff09;》&#xff1a; lin…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_options函数

声明 就在 main函数所在的 nginx.c 中&#xff1a; static ngx_int_t ngx_get_options(int argc, char *const *argv); 实现 static ngx_int_t ngx_get_options(int argc, char *const *argv) {u_char *p;ngx_int_t i;for (i 1; i < argc; i) {p (u_char *) argv[i]…...

TCP长连接、HTTP短轮询、HTTP长轮询、HTTP长连接、WebSocket的区别

1.TCP长连接 &#xff08;1&#xff09;概念&#xff1a;该连接属于传输层的协议。客户端和服务器之间建立连接后&#xff0c;不立即断开该连接&#xff0c;而是一直保持这个状态&#xff0c;以便后续数据的持续、连续传输。&#xff08;2&#xff09;应用场景&#xff1a;适合…...

在 Flownex 中创建自定义工作液

在这篇博文中&#xff0c;我们将了解如何在 Flownex 中为流网添加和定义一种新的流体温度相关工作材料。 Flownex 物料管理界面 在 Flownex 中使用与温度相关的流体材料时&#xff0c;了解其特性与温度的关系非常重要。这种了解可确保准确预测各种热条件下的流体行为&#xff0…...

基于Spring Boot的图书个性化推荐系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

【抽象代数】1.1. 运算及关系

集合与映射 定义1. 设 为 的子集&#xff0c;定义 到 的映射 &#xff1a; 使得 &#xff0c;称 为 到 的嵌入映射。 定义2. 设 为 的子集&#xff0c; 为 到 的映射&#xff0c; 为 到 的映射&#xff0c;如果 &#xff0c;称为的开拓&#xff0c; 为 的限制&…...

拥抱开源,助力创新:IBM永久免费云服务器助力开源项目腾飞

近年来&#xff0c;开源项目蓬勃发展&#xff0c;为全球科技进步做出了巨大贡献。然而&#xff0c;服务器成本高昂常常成为开源项目的巨大障碍。许多优秀的项目因缺乏资源而难以持续发展&#xff0c;甚至夭折。令人振奋的是&#xff0c;IBM云计算平台推出了一项重磅活动&#x…...

Windows Docker笔记-简介摘录

Docker是一个开源的容器化平台&#xff0c;可以帮助开发人员将应用程序与其依赖项打包在一个独立的容器中&#xff0c;然后在任何安装的Docker的环境中快速、可靠地运行。 几个基本概念和优势&#xff1a; 1. 容器 容器是一个轻量级、独立的运行环境&#xff0c;包含了应用程…...

threejs 建筑设计(室内设计)软件 技术调研之五 墙体生成后自动生成房间(地面)

运用threejs 开发 建筑设计&#xff08;室内设计&#xff09;软件 技术调研 四 墙体添加真实门窗并保持原材质 在线体验地址&#xff1a;http://47.96.130.245:8080/design/index.html 实现功能&#xff1a; 墙体材质变换后&#xff0c;自动根据墙体的顶点生成相应的房间 视…...

C++:string类的模拟实现

目录 1.引言 2.C模拟实现 2.1模拟实现构造函数 1&#xff09;直接构造 2&#xff09;拷贝构造 2.2模拟实现析构函数 2.3模拟实现其他常规函数 1&#xff09;c_str函数 2&#xff09;size函数 3&#xff09;begin/end函数 4&#xff09;reserve函数 5&#xff09;re…...

UE制作2d游戏

2d免费资产: Free 2D Game Assets - CraftPix.net 需要用到PaperZD插件 官网下载后启用即可 导入png素材 然后全选 - 创建Sprite 创建 人物基类 设置弹簧臂和相机 弹簧臂设置成旋转-90 , 取消碰撞测试 设置子类Sprite 拖到场景中 绑定设置输入映射,让角色移动跳跃 神似卡拉比…...

verilog练习:i2c slave 模块设计

文章目录 前言1. 结构2.代码2.1 iic_slave.v2.2 sync.v2.3 wr_fsm.v2.3.1 状态机状态解释 2.4 ram.v 3. 波形展示4. 建议5. 资料总结 前言 首先就不啰嗦iic协议了&#xff0c;网上有不少资料都是叙述此协议的。 下面将是我本次设计的一些局部设计汇总&#xff0c;如果对读者有…...

mysql的语句备份详解

使用mysqldump工具备份&#xff08;适用于逻辑备份&#xff09; mysqldump是 MySQL 自带的一个非常实用的逻辑备份工具&#xff0c;它可以将数据库中的数据和结构以 SQL 语句的形式导出到文件中。 1. 备份整个数据库 mysqldump -u [用户名] -p [数据库名] > [备份文件名].…...

BFS算法篇——广度优先搜索,探索未知的旅程(上)

文章目录 前言一、BFS的思路二、BFS的C语言实现1. 图的表示2. BFS的实现 三、代码解析四、输出结果五、总结 前言 广度优先搜索&#xff08;BFS&#xff09;是一种广泛应用于图论中的算法&#xff0c;常用于寻找最短路径、图的遍历等问题。与深度优先搜索&#xff08;DFS&…...

短剧APP开发:短剧风口下的机遇

今年春节以来&#xff0c;各种精品短剧不断上线&#xff0c;短剧赛道热度持续上升&#xff0c;展现出了强大的经济效益&#xff0c;为影视市场提供了越来越多的机会。短剧的持续火爆也带动了短剧APP的发展&#xff0c;“短剧”迎来了爆发式增长&#xff0c;本文将探讨短剧APP开…...

PT2021K 单触控同步输出 IC

1. 产品概述 PT2021K 是一款电容式触摸控制 ASIC &#xff0c;支持 1 通道触摸输入&#xff0c; 1 通道同步型开关输出。具有低 功耗、高抗干扰、宽工作电压范围、高穿透力的突出优势。 2. 主要特性 工作电压范围&#xff1a; 2.4~5.5V 待机电流约 9uAV DD 5V&…...

[论文笔记] Deepseek-R1R1-zero技术报告阅读

启发: 1、SFT&RL的训练数据使用CoT输出的格式,先思考再回答,大大提升模型的数学与推理能力。 2、RL训练使用群体相对策略优化(GRPO),奖励模型是规则驱动,准确性奖励和格式化奖励。 1. 总体概述 背景与目标 报告聚焦于利用强化学习(RL)提升大型语言模型(LLMs)…...

选择LabVIEW开发外协还是自己做开发?

在决定是否选择外协进行LabVIEW开发时&#xff0c;选择合适的外协团队是至关重要的。一个专业的外协团队不仅能提高项目的开发效率&#xff0c;还能帮助解决技术难题&#xff0c;确保项目的高质量交付。在选择团队时&#xff0c;以下几个方面值得特别注意&#xff1a; ​ 1. 团…...

网络工程师 (20)计算机网络的概念

一、定义 计算机网络是指将地理位置不同、具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路及通信设备连接起来&#xff0c;在网络操作系统、网络管理软件及网络通信协议的管理和协调下&#xff0c;实现信息传递和资源共享的计算机通信系统。 二、组成 资源子网&…...

RockyLinux9.4安装教程

Rocky Linux 9.4 安装教程 Rocky Linux 是由 CentOS 创始人 Gregory Kurtzer 发起的一个社区企业操作系统,旨在与 Red Hat Enterprise Linux (RHEL) 保持二进制兼容。本教程将详细介绍如何在您的系统上安装 Rocky Linux 9.4。 步骤 1: 下载 Rocky Linux 9.4 ISO 文件 打开 R…...

单片机之基本元器件的工作原理

一、二极管 二极管的工作原理 二极管是一种由P型半导体和N型半导体结合形成的PN结器件&#xff0c;具有单向导电性。 1. PN结形成 P型半导体&#xff1a;掺入三价元素&#xff0c;形成空穴作为多数载流子。N型半导体&#xff1a;掺入五价元素&#xff0c;形成自由电子作为多…...

TOTP实现Google Authenticator认证工具获取6位验证码

登录遇到Google认证怎么办? TOTP是什么?(Google Authenticator) TOTP(Time-based One-Time Password)是一种基于时间的一次性密码算法,主要用于双因素身份验证。其核心原理是通过共享密钥和时间同步生成动态密码,具体步骤如下: 共享密钥:服务端与客户端预先共享一个…...

114,【6】攻防世界 web wzsc_文件上传

进入靶场 传个桌面有的 直接空白了 我们 访问一下上传的东西 /index 没显示用于解析的.htaccess和.user.ini 文件&#xff0c;还两个都不显示 .htaccess 和 .user.ini 文件分别用于 Apache 服务器和 PHP-FPM 环境的目录级配置 但上传的时候bp查看状态码是200&#xff0c;…...

Rust unresolved import `crate::xxx` 报错解决

问题阐述 该问题出现在我使用actix编写的crud后端api中&#xff0c;我的后端结构如下: D:. | handle_err.rs | lib.rs | main.rs | ---application | mod.rs | user_service.rs | ---domain | dto.rs | mod.rs | user.rs | ---infrastru…...

dl学习笔记(9):pytorch数据处理的完整流程

1&#xff09;自动导入常用库的设置方式 在开始之前&#xff0c;这里介绍一下自动导入常用的你需要加载的库的操作方式。 首先在我们的目录下找到ipython文件&#xff0c;如下图&#xff1a; 然后找到里面的startup文件&#xff1a; 然后新建一个文本文档&#xff0c;输入你每…...

结构化表达(三):归纳分组

目录 归纳分组 一、如何归纳分组 二、如何掌握更多模型 归纳分组 一、如何归纳分组 整理思路&#xff0c;多用分类模型&#xff0c;列如&#xff1a; 1、内部、外部分类。 2、市场营销学中的4P&#xff1a;产品、渠道、价格、促销。 3、战略3C&#xff1a;公司、客户、竞…...

BUU17 [RoarCTF 2019]Easy Calc1

自用 源代码 $(#calc).submit(function(){$.ajax({url:"calc.php?num"encodeURIComponent($("#content").val()),type:GET,success:function(data){$("#result").html(<div class"alert alert-success"><strong>答案:&l…...

openGauss 3.0 数据库在线实训课程2:学习客户端工具gsql的使用

openGauss数据库状态查看 前提 我正在参加21天养成好习惯| 第二届openGauss每日一练活动 课程详见&#xff1a;openGauss 3.0.0数据库在线实训课程 学习目标 学习openGauss数据库客户端工具gsql的使用。 课程作业 gsql是openGauss提供在命令行下运行的数据库连接工具&am…...

mac环境下,ollama+deepseek+cherry studio+chatbox本地部署

春节期间&#xff0c;deepseek迅速火爆全网&#xff0c;然后回来上班&#xff0c;我就浅浅的学习一下&#xff0c;然后这里总结一下&#xff0c;我学习中&#xff0c;总结的一些知识点吧&#xff0c;分享给大家。具体的深度安装部署&#xff0c;这里不做赘述&#xff0c;因为网…...

C# SQlite使用流程

前言 不是 MySQL 用不起&#xff0c;而是 SQLite 更有性价比&#xff0c;绝大多数的应用 SQLite 都可以满足。 SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎&#xff0c;它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机…...

mysql8 C++源码中创建表函数,表字段最大数量限制,表行最大存储限制

在 MySQL 8 的 C 源码中&#xff0c;表的最大字段数量限制体现在 MAX_FIELDS 宏定义中。这个宏定义了表中可以拥有的最大字段数量。 代码中的体现 在 mysql_prepare_create_table 函数中&#xff0c;有以下代码段检查表的字段数量是否超过最大限制&#xff1a; cpp if (alt…...

stable diffusion安装包与常用模型下载

本地安装包&#xff08;直接借用秋叶大佬的包&#xff09;&#x1f64f; 1.最好用的 Forge 版整合包 网盘&#xff1a;https://pan.quark.cn/s/4e9459b17c94 解压密码&#xff1a;bilibili-秋葉aaaki 2.最好用的整合包&#xff01; https://pan.baidu.com/s/1MjO3CpsIvTQID…...

Redis | 十大数据类型

文章目录 十大数据类型概述key操作命令数据类型命令及落地运用redis字符串&#xff08;String&#xff09;redis列表&#xff08;List&#xff09;redis哈希表&#xff08;Hash&#xff09;redis集合&#xff08;Set&#xff09;redis有序集合&#xff08;ZSet / SortedSet&…...

19爬虫:使用playwright登录超级鹰

本次案例一共解决了如下两个问题&#xff1a; &#xff08;1&#xff09;如何使用playwright截图&#xff0c;特别是验证码图片 &#xff08;2&#xff09;在playwright中如何判断一个元素可见 1.截图 我们首先解决第一个问题&#xff0c;截图。如果前期接触过selenium的小伙…...

强化学习笔记6——异同策略、AC、等其他模型总结

异步两种方法&#xff1a;1&#xff1a;经验回放 2&#xff1a;数据动作非同时产生 举例QLearning为什么是异策略&#xff1f; 生成动作时e的概率从Q表选&#xff0c;1-e概况随机。 更新策略时&#xff0c;贪心策略选择Q_max作为动作。 策略优化两种主要方法&#xff1a;基于梯…...

【工具变量】上市公司企业渐进式创新程度及渐进式创新锁定数据(1991-2023年)

测算方式&#xff1a; 参考顶刊《经济研究》孙雅慧&#xff08;2024&#xff09;老师的做法&#xff0c;用当期创新和往期创新的内容重叠度作为衡量渐进式创新程度的合理指标。通过搜集海量专利摘要&#xff0c;测算当前专利申请和既有专利的内容相似度&#xff0c;反映企业在…...

高级测试工程师,在接口自动化方面,如何用AI提升?DeepSpeek回答

思考过程&#xff1a; 嗯&#xff0c;用户现在的问题是作为高级测试工程师&#xff0c;在接口自动化方面如何用AI来提升。首先&#xff0c;我需要回顾之前的对话历史&#xff0c;看看之前给过哪些建议。之前讨论过AI在测试中的核心应用场景&#xff0c;比如智能测试用例生成、自…...

每日一题——插入排序实现数据流中的中位数

插入排序实现数据流中的中位数 题目描述功能要求数据范围 解题思路算法流程 代码实现代码详解1. 全局变量2. Insert 函数3. GetMedian 函数 复杂度分析Insert 函数GetMedian 函数空间复杂度&#xff08;整体&#xff09; 注意事项 题目描述 设计一个算法&#xff0c;用来计算数…...

arcgis for js范围内天地图高亮,其余底图灰暗

在GIS地图开发中&#xff0c;有时我们需要突出显示某个特定区域&#xff0c;而将其他区域灰暗处理&#xff0c;以达到视觉上的对比效果。本文将介绍如何使用ArcGIS for JavaScript实现这一功能&#xff0c;具体效果为&#xff1a;在指定范围内&#xff0c;天地图高亮显示&#…...

【Unity】从父对象中获取子对象组件的方式

1.GetComponentInChildren 用于获取对与指定组件或游戏对象的任何子级相同的游戏对象上的组件类型的引用。 该方法在Unity脚本API的声明格式为&#xff1a; public T GetComponentInChildren(bool includeInactive false) includeInactive参数&#xff08;可选&#xff09…...