【Redis 神秘大陆】003 数据类型使用场景

三、Redis 数据类型和使用场景

img

  • Hash:对象类型的数据,购物车
  • List:队列/栈
  • Set:String类型的无序集合,intset,抽奖、签到、打卡,商品评价标签
  • Sorted Set:存储有序的元素,ziplist,skiplist+ dict,排行榜
  • Geo:地理位置信息
  • Hyperloglogs:基于基数的统计
  • Streams:流计算

3.1 基础命令

命令作用示例返回值
keys *查看所有键keys *所有键列表
dbsize键总数dbsize键的总数
exists key检查键是否存在exists java1 或 0
del key [key]删除键del java删除个数
expire key seconds设置键的过期时间expire hello 101 或 0
ttl key查看键的剩余过期时间ttl hello剩余时间
type key查看键的数据结构类型type hello数据类型

3.1.1 单个键管理

功能命令说明
键重命名rename key newkey将指定键重命名为新键名。如果新键名已存在,则会覆盖原有键的值。
随机返回一个键randomkey从当前数据库中随机返回一个键的名称。
键过期expire key seconds设置键在指定秒数后过期。
expireat key timestamp设置键在指定时间戳后过期。
pexpire key milliseconds以毫秒为单位设置键在指定毫秒数后过期。
pexpireat key milliseconds-timestamp以毫秒为单位设置键在指定毫秒级时间戳后过期。
ttl key获取键的剩余过期时间(单位:秒)。
pttl key获取键的剩余过期时间(单位:毫秒)。
persist key移除键的过期时间,使其永久有效。
键迁移move key db将指定键移动到另一个数据库。
dump key+restore key ttl value在不同 Redis 实例之间进行数据迁移。
`migrate host port key“” destination-db timeout [copy] [replace] [keys key [key …]]`

3.1.2 键的遍历

对应 mysql limit

功能命令说明
全量遍历键keys pattern返回匹配给定模式的所有键。pattern 可以包含通配符,如 ***** 匹配所有键,? 匹配单个字符,[] 匹配指定范围的字符。Keys 命令可能会导致 Redis 阻塞,不建议在生产环境中使用,但在某些情况下,如数据量较小或者在从节点上执行,可以使用。
渐进式遍历scan cursor [match pattern] [count number]使用游标方式逐步遍历所有键。cursor 是游标值,从 0 开始,每次遍历完毕后会返回新的游标值。match 可选参数用于模式匹配,count 可选参数表示每次遍历的键个数,默认为 10。Scan 命令可以有效避免阻塞,但无法保证完全遍历所有键。可用于检测过期或闲置时间、寻找大对象等场景。
面向哈希类型扫描hscan key cursor [match pattern] [count number]渐进式遍历哈希类型键的所有字段。与 scan 类似,但专用于哈希类型。
面向集合类型扫描sscan key cursor [match pattern] [count number]渐进式遍历集合类型键的所有元素。与 scan 类似,但专用于集合类型。
面向有序集合扫描zscan key cursor [match pattern] [count number]渐进式遍历有序集合类型键的所有成员。与 scan 类似,但专用于有序集合类型。

3.2 字符串

img

  • Redis的字符串类型是最基础的数据结构。
  • 所有键都是字符串类型,其他数据结构都是在字符串类型基础上构建的。
  • 值可以是简单字符串、复杂字符串(如JSON、XML)、数字(整数、浮点数)甚至是二进制(图片、音频、视频),但值的最大大小不能超过512MB。

3.2.1 命令

常用命令
  1. 设置值
  • set key value [ex seconds] [px milliseconds] [nx|xx]: 设置键的值,并可选地设置过期时间和条件。
  • setex key seconds value: 设置键的值,并同时设置过期时间(秒)。
  • setnx key value: 仅当键不存在时设置键的值。
  • setxx key value: 仅当键存在时设置键的值。
  1. 获取值
  • get key: 获取键的值。
  • mget key [key …]: 批量获取多个键的值。
  1. 批量操作
  • mset key value [key value …]: 批量设置多个键值对。
  • mget key [key …]: 批量获取多个键的值。
  1. 计数
  • incr key: 对键的值进行自增操作。
  • decr key: 对键的值进行自减操作。
  • incrby key increment: 对键的值进行指定数字的自增操作。
  • decrby key decrement: 对键的值进行指定数字的自减操作。
  • incrbyfloat key increment: 对键的值进行浮点数的自增操作。
不常用命令
  1. 追加值
  • append key value: 向键的值尾部追加字符串。
  1. 字符串长度
  • strlen key: 返回键的值的长度。
  1. 设置并返回原值
  • getset key value: 设置键的值并返回键原来的值。
  1. 设置指定位置的字符
  • setrange key offset value: 设置键值的指定位置的字符。
  1. 获取部分字符串
  • getrange key start end: 获取键值的指定范围的子字符串。
时间复杂度
命令时间复杂度
setO(1)
getO(1)
msetO(N)
mgetO(N)
incrO(1)
decrO(1)
incrbyO(1)
decrbyO(1)
incrbyfloatO(1)
appendO(1)
strlenO(1)
getsetO(1)
setrangeO(1)
getrangeO(N)

3.2.2 内部编码

Redis字符串类型的内部编码与底层数据结构密切相关,不同的编码方式会对应不同的底层数据结构,如下所示:

  • int:采用8个字节的长整型存储,底层数据结构为整数类型, 节省内存空间和提高访问速度。
127.0.0.1:6379> set key 8653 OK
127.0.0.1:6379> object encoding key "int"
  • embstr:对于小于等于39个字节的字符串,采用内嵌字符串编码,底层数据结构为简单的字符数组,避免额外的内存分配和释放操作。
# 小于等于39个字节的字符串:embstr
127.0.0.1:6379> set key "hello,world" OK
127.0.0.1:6379> object encoding key "embstr"
  • raw:对于大于39个字节的字符串,采用原始字符串编码,底层数据结构为动态字符串(dynamic string),通常是一个结构体,内部包含了指向字符数组的指针以及该字符串的长度等信息。
# 大于39个字节的字符串:raw
127.0.0.1:6379> set key "one string greater than 39 byte........." OK
127.0.0.1:6379> object encoding key "raw"
127.0.0.1:6379> strlen key (integer) 40

3.2.3 应用场景

缓存功能

典型的缓存使用场景是将 Redis 作为缓存层,通过 Redis 快速获取数据,减轻后端数据库的压力。下面是模拟的代码示例:

UserInfo getUserInfo(long id){
    String userRedisKey = "user:info:" + id;
    String value = redis.get(userRedisKey);
    UserInfo userInfo;
    if (value != null) {
        userInfo = deserialize(value);
    } else {
        userInfo = mysql.get(id);
        if (userInfo != null) {
            redis.setex(userRedisKey, 3600, serialize(userInfo));
        }
    }
    return userInfo;
}
计数功能

Redis 可以作为计数的基础工具,用于实现快速计数和查询缓存的功能。以下是一个简单的示例:

long incrVideoCounter(long id) {
    String key = "video:playCount:" + id;
    return redis.incr(key);
}
共享 Session

使用 Redis 可以集中管理用户的 Session 信息,解决分布式 Web 服务中的 Session 分散管理问题,确保用户登录状态的一致性。示例代码如下:

// 在登录时将用户的 Session 信息存储到 Redis
redis.setex(sessionId, 3600, serialize(userInfo));

// 在需要获取 Session 信息时,直接从 Redis 中获取
UserInfo userInfo = deserialize(redis.get(sessionId));
限速功能

通过 Redis 实现对特定操作的限速,如限制用户获取验证码的频率、限制 IP 地址的访问频率等。示例代码如下:

String phoneNum = "138xxxxxxxx";
String key = "shortMsg:limit:" + phoneNum;

// SET key value EX 60 NX
String isExists = redis.set(key, "1", "EX 60", "NX");

if (isExists != null || redis.incr(key) <= 5) {
    // 允许操作
} else {
    // 限速
}

3.3 哈希

3.3.1 命令

命令示例说明
hset key field valuehset user:1 name tom为指定键的哈希类型设置字段及其对应的值
hget key fieldhget user:1 name获取指定键的哈希类型中指定字段的值
hdel key field [field …]hdel user:1 name删除指定键的哈希类型中一个或多个字段
hlen keyhlen user:1计算指定键的哈希类型中字段的数量
hmset key field value [field value …]hmset user:1 name mike age 12 city tianjin批量设置指定键的哈希类型中的多个字段及其对应的值
hexists key fieldhexists user:1 name判断指定键的哈希类型中是否存在指定字段
hkeys keyhkeys user:1获取指定键的哈希类型中所有字段的名称
hvals keyhvals user:1获取指定键的哈希类型中所有字段的值
hgetall keyhgetall user:1获取指定键的哈希类型中所有字段及其对应的值
hincrby key field incrementhincrby user:1 age 1将指定键的哈希类型中指定字段的值按指定增量增加
hstrlen key fieldhstrlen user:1 name计算指定键的哈希类型中指定字段的值的字符串长度

3.3.2 内部编码

哈希类型是 Redis 中常用的数据结构之一,其内部编码有两种:ziplist(压缩列表)和hashtable(哈希表)。

根据哈希类型元素个数和值的大小,Redis会动态选择使用合适的内部编码来存储数据。

  • ziplist(压缩列表):

  • 当哈希类型元素个数小于 hash-max-ziplist-entries 配置(默认512个)且所有值都小于 hash-max-ziplist-value 配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现。

  • Ziplist 使用紧凑的结构实现多个元素的连续存储,因此在节省内存方面比 hashtable 更加优秀。

  • hashtable(哈希表):

  • 当哈希类型无法满足 ziplist 的条件时,Redis会使用 hashtable 作为哈希的内部实现。因为此时 ziplist 的读写效率会下降,而 hashtable 的读写时间复杂度为O(1)。

下面是示例演示了哈希类型的内部编码,以及相应的变化:

当field个数比较少且没有大的value时,内部编码为ziplist:

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 OK
127.0.0.1:6379> object encoding hashkey "ziplist"

当有value大于64字节时,内部编码会由ziplist变为hashtable:

127.0.0.1:6379> hset hashkey f3 "one string is bigger than 64 byte...忽略..." OK
127.0.0.1:6379> object encoding hashkey "hashtable"

当field个数超过512,内部编码也会由ziplist变为hashtable:

127.0.0.1:6379> hmset hashkey f1 v1 f2 v2 f3 v3 ...忽略... f513 v513 OK
127.0.0.1:6379> object encoding hashkey "hashtable"

这种动态选择内部编码的机制有效地节省了内存空间,并提高了 Redis 在处理哈希类型数据时的效率。

3.3.3 应用场景

缓存用户信息

img

将用户信息存储为哈希类型,每个用户的属性作为field,属性值作为value。这种方式相比于使用字符串序列化缓存用户信息更加直观,并且在更新操作上更为便捷。

UserInfo getUserInfo(long id) {
    String userRedisKey = "user:info:" + id;
    Map<String, String> userInfoMap = redis.hgetAll(userRedisKey);
    UserInfo userInfo;
    if (userInfoMap != null) {
        userInfo = transferMapToUserInfo(userInfoMap);
    } else {
        userInfo = mysql.get(id);
        redis.hmset(userRedisKey, transferUserInfoToMap(userInfo));
        redis.expire(userRedisKey, 3600);
    }
    return userInfo;
}
缓存对象属性

类似于缓存用户信息,哈希类型也可用于缓存对象的属性。每个对象的属性作为field,属性值作为value。这样可以在对象更新时只更新相应的属性,而不需要更新整个对象。

数据存储和索引

哈希类型可以用于存储数据并建立索引,例如存储文章内容和相应的标签。文章内容可以作为value,而标签可以作为field,这样可以快速地根据标签检索到相关的文章内容。

统计数据

哈希类型可以用于存储统计数据,例如用户的访问次数、订单数量等。每个用户或对象的ID作为key,相应的统计数据作为field和value。这样可以方便地对数据进行更新和查询。

3.3.4 优缺点分析

使用哈希类型缓存用户信息的优缺点如下:

优点
  • 简单直观,易于理解和实现。
  • 每个属性都支持更新操作,可以灵活地更新部分属性而不影响其他属性。
  • 如果合理使用哈希类型的内部编码和控制字段数量,可以有效地减少内存占用。
缺点
  • 在使用hashtable作为内部实现时,会消耗更多的内存。
  • 如果哈希表的field数量过多,会导致内存占用增加,需要合理控制field数量。
  • Redis不支持复杂的关系查询,因此在模拟关系型数据库的复杂查询时开发困难,维护成本高。

3.3.5 用户信息缓存方案比较

方案优点缺点适用场景
原生字符串类型简单直观每个属性支持更新操作占用过多的键内存占用量较大 用户信息内聚性较差,不利于维护适用于简单的数据结构,且数据量较小的场景
序列化字符串类型简化编程可提高内存使用效率(如果合理使用序列化)序列化和反序列化有一定开销 更新属性需要反序列化、更新、再序列化,操作复杂且开销较大适用于需要简化编程且数据结构较为复杂的场景,数据量较小、读取频率高、更新频率低
哈希类型简单直观 每个用户属性使用一对field-value,内存空间使用相对较少(如果合理使用)需要控制哈希内部编码的转换,转换为hashtable会消耗更多内存无法针对某个 field 进行失效处理适用于结构化数据,且字段较多的场景,需要减少内存空间的使用、提高数据存取效率的场景

3.4 列表

3.4.1 命令

操作类型描述命令示例用法
添加操作从右向左插入元素到列表。rpush key value [value …]rpush listkey c b a
添加操作从左向右插入元素到列表。lpush key value [value …]lpush listkey c b a
添加操作向某个元素前或者后插入元素linsert key before|after pivot value
查找获取指定范围内的元素列表。lrange key start endlrange listkey 1 3
查找获取指定索引下标的元素。lindex key indexlindex listkey -1
查找获取列表长度。llen keyllen listkey
删除从列表左侧弹出元素。lpop keylpop listkey
删除从列表右侧弹出元素。rpop keyrpop listkey
删除删除指定元素。lrem key count valuelrem listkey 4 a
删除按照索引范围修剪列表。ltrim key start endltrim listkey 1 3
修改修改指定索引下标的元素。lset key index newValuelset listkey 2 python
阻塞操作从左至右阻塞弹出元素。blpop key [key …] timeoutblpop list:test 3
阻塞操作从右至左阻塞弹出元素。brpop key [key …] timeoutbrpop list:test 3

3.4.2 内部编码

img

Redis 列表类型的内部编码主要有两种:ziplist(压缩列表)和 linkedlist(链表)。选择合适的内部编码类型取决于列表的大小和元素的特性。

  1. ziplist(压缩列表)
  • 当列表的元素个数小于 list-max-ziplist-entries 配置(默认 512 个),并且列表中每个元素的值都小于 list-max-ziplist-value 配置(默认 64 字节)时,Redis 会选用 ziplist 作为列表的内部实现来减少内存的使用。
  • ziplist 是一种紧凑且高效的数据结构,适用于存储少量元素且元素值较小的列表。
  1. linkedlist(链表)
  • 当列表类型无法满足 ziplist 的条件时,Redis 会使用 linkedlist 作为列表的内部实现。
  • linkedlist 是一种灵活的数据结构,适用于存储大量元素或者元素值较大的列表。
示例演示
  1. 当元素个数较少且没有大元素时,内部编码为 ziplist:
bashCopy code
127.0.0.1:6379> rpush listkey e1 e2 e3
(integer) 3
127.0.0.1:6379> object encoding listkey
"ziplist"

2.1 当元素个数超过 512 个,内部编码变为 linkedlist:

bashCopy code
127.0.0.1:6379> rpush listkey e4 e5 ...忽略... e512 e513
(integer) 513
127.0.0.1:6379> object encoding listkey
"linkedlist"

2.2 或者当某个元素超过 64 字节,内部编码也会变为 linkedlist:

bashCopy code
127.0.0.1:6379> rpush listkey "one string is bigger than 64 byte...............
................."
(integer) 4
127.0.0.1:6379> object encoding listkey
"linkedlist"

3.4.3 应用场景

1. 消息队列

消息队列常用于解耦系统组件,实现异步通信和削峰填谷等功能。在 Redis 中,可以使用 lpushbrpop 命令组合来实现阻塞队列:

  • 生产者客户端使用 lpush 从列表左侧插入元素。
  • 多个消费者客户端使用 brpop 命令阻塞式地获取列表尾部的元素。

这样设计可以保证消费的负载均衡和高可用性。

2. 文章列表

img

文章列表通常需要按照一定的规则进行排序和分页展示。在 Redis 中,可以使用列表存储每个用户的文章列表,并进行分页展示:

  1. 每篇文章使用哈希结构存储,例如每篇文章有标题、时间戳和内容等属性。
hmset article:1 title "xx" timestamp 1476536196 content "xxxx"
hmset article:k title "yy" timestamp 1476512536 content "yyyy"
  1. 向用户文章列表添加文章,使用 lpush 将文章 ID 插入用户文章列表的左侧。
lpush user:1:articles article:1 article3 ...
lpush user:k:articles article:5 ...
  1. 分页获取用户文章列表,使用 lrange 命令按照索引范围获取指定用户的文章列表,然后根据文章 ID 获取文章内容。
articles = lrange user:1:articles 0 9
for article in articles
    hgetall article
开发提示

在使用列表时,可以根据以下口诀选择合适的操作组合:

  • lpush + lpop = 栈(Stack)
  • lpush + rpop = 队列(Queue)
  • lpush + ltrim = 有限集合(Capped Collection)
  • lpush + brpop = 消息队列(Message Queue)

3.5 Set 集合

3.5.1 命令

操作命令返回值
添加元素sadd key element [element …]成功添加的元素个数
删除元素srem key element [element …]成功删除的元素个数
计算元素个数scard key集合中元素的数量
判断元素是否在集合中sismember key element1(存在)或 0(不存在)
随机返回指定个数的元素srandmember key [count]随机元素或元素数组
从集合中随机弹出元素spop key被弹出的元素
获取所有元素smembers key集合中的所有元素
求多个集合的交集sinter key [key …]交集元素的数组
求多个集合的并集sunion key [key …]并集元素的数组
求多个集合的差集sdiff key [key …]差集元素的数组
保存交集、并集、差集的结果sinterstore destination key [key …]保存结果的集合的元素个数
sunionstore destination key [key …]保存结果的集合的元素个数
sdiffstore destination key [key …]保存结果的集合的元素个数

3.5.2 内部编码

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

示例:

  1. 当元素个数较少且都为整数时,内部编码为intset:
rubyCopy code
127.0.0.1:6379> sadd setkey 1 2 3 4 (integer) 4
127.0.0.1:6379> object encoding setkey "intset"
  1. 当元素个数超过512个,内部编码变为hashtable:
rubyCopy code
127.0.0.1:6379> sadd setkey 1 2 3 4 5 6 ... 512 513 (integer) 509
127.0.0.1:6379> scard setkey (integer) 513
127.0.0.1:6379> object encoding listkey "hashtable"
  1. 当某个元素不为整数时,内部编码也会变为hashtable:
rubyCopy code
127.0.0.1:6379> sadd setkey a (integer) 1
127.0.0.1:6379> object encoding setkey "hashtable"

3.5.3 应用场景

用户的兴趣可以被表示为一组标签,例如,一个用户可能对娱乐、体育感兴趣,而另一个用户可能对历史、新闻感兴趣。以下是使用集合类型实现标签功能的一些功能:

  1. 给用户添加标签
sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
sadd user:k:tags tag1 tag2 tag4
  1. 给标签添加用户
sqlCopy code
sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
sadd tagk:users user:1 user:2
  1. 删除用户下的标签
srem user:1:tags tag1 tag5
  1. 删除标签下的用户
bashCopy code
srem tag1:users user:1
srem tag5:users user:1
  1. 计算用户共同感兴趣的标签
rubyCopy code
sinter user:1:tags user:2:tags

在开发中,需要注意以下几点:

  • 用户和标签的关系维护应该在一个事务内执行,以防止部分命令失败造成数据不一致。
  • 计算用户共同感兴趣的标签可以使用 sinter 命令。

3.6 Zset 有序集合

3.6.1 命令

命令描述时间复杂度
zadd key score member [score member …]添加成员及其分数到有序集合O(log(N))
zcard key获取有序集合的成员个数O(1)
zscore key member获取成员的分数O(1)
zrank key member获取成员的排名(升序)O(log(N))
zrevrank key member获取成员的排名(降序)O(log(N))
zrem key member [member …]删除成员O(log(N)+M)
zincrby key increment member增加成员的分数O(log(N))
zrange key start end [withscores]返回指定排名范围的成员(升序)O(log(N)+M)
zrevrange key start end [withscores]返回指定排名范围的成员(降序)O(log(N)+M)
zrangebyscore key min max [withscores] [limit offset count]返回指定分数范围的成员(升序)O(log(N)+M)
zrevrangebyscore key max min [withscores] [limit offset count]返回指定分数范围的成员(降序)O(log(N)+M)
zcount key min max返回指定分数范围内的成员个数O(log(N))
zremrangebyrank key start end删除指定排名范围的成员O(log(N)+M)
zremrangebyscore key min max删除指定分数范围的成员O(log(N)+M)
`zinterstore destination numkeys key [key …] [weights weight [weight …]] [aggregate summinmax]`
`zunionstore destination numkeys key [key …] [weights weight [weight …]] [aggregate summinmax]`

其中,N 表示有序集合的基数(即成员的个数),M 表示返回结果的基数。

3.6.2 内部编码

有序集合类型的内部编码有两种:ziplist(压缩列表)和skiplist(跳跃表)。

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

以下是示例说明:

  1. 当元素个数较少且每个元素较小时,内部编码为skiplist。
127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3 (integer) 3
127.0.0.1:6379> object encoding zsetkey "ziplist"
  1. 当元素个数超过128个时,内部编码变为ziplist。
127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3 12 e4 ...忽略... 84 e129 (integer) 129
127.0.0.1:6379> object encoding zsetkey "skiplist"
  1. 当某个元素大于64字节时,内部编码也会变为hashtable。
127.0.0.1:6379> zadd zsetkey 20 "one string is bigger than 64 byte............." (integer) 1
127.0.0.1:6379> object encoding zsetkey "skiplist"

3.6.3 应用场景

添加用户赞数

用户上传视频后,根据获得的赞数将用户添加到相应日期的排行榜中。可以使用有序集合的zaddzincrby功能。例如,用户mike上传了一个视频,并获得了3个赞:

zadd user:ranking:2016_03_15 mike 3

如果之后再获得一个赞:

zincrby user:ranking:2016_03_15 mike 1
取消用户赞数
  1. 当用户注销或发生其他需要将用户从排行榜中删除的情况时,可以使用zrem命令删除用户。例如,删除用户mike:
zrem user:ranking:2016_03_15 mike
展示获取赞数最多的十个用户

使用zrevrange命令可以获取指定日期排行榜中获取赞数最多的前十个用户的信息:

zrevrange user:ranking:2016_03_15 0 9
展示用户信息以及用户分数

可以将用户的详细信息保存在哈希类型中,并通过hgetall命令获取用户信息。同时,可以使用zscorezrank命令获取用户在排行榜中的分数和排名:

hgetall user:info:tom
zscore user:ranking:2016_03_15 mike
zrank user:ranking:2016_03_15 mike

以上功能实现了一个基本的排行榜系统,用户可以根据赞数排行查看排名前十的用户,并查看每个用户的详细信息以及其在排行榜中的分数和排名。

编码转化机制

img


当你发现这些内容对你有帮助时,为了支持我的工作,不妨给一个免费的⭐Star,这将是对我最大的鼓励!感谢你的陪伴与支持!一起在技术的路上共同成长吧!点击链接:GitHub | Gitee

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

六、OpenFeign服务接口调用

一、提问 已经有loadbalancer为什么还要学习OpenFeign? 两个都有道理的话&#xff0c;日常用那个&#xff1f; 二、是什么 OpenFeign是什么 官网翻译 Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并对其进行注释。它具有可…

【InternLM 实战营第二期笔记】LMDeploy 量化部署 LLMVLM实战

Huggingface与TurboMind介绍 Huggingface HuggingFace是一个高速发展的社区&#xff0c;包括Meta、Google、Microsoft、Amazon在内的超过5000家组织机构在为HuggingFace开源社区贡献代码、数据集和模型。可以认为是一个针对深度学习模型和数据集的在线托管社区&#xff0c;如…

python 列表对象函数

对象函数必须通过一个对象调用。 列表名.函数名() append() 将某一个元素对象添加在列表的表尾 如果添加的是其他的序列&#xff0c;该序列也会被看成是一个数据对象 count() 统计列表当中 某一个元素出现的次数 extend() 在当前列表中 将传入的其他序列的元素添加在表尾…

【AIGC】AIGC在虚拟数字人中的应用:塑造未来互动体验的革新力量

&#x1f680; &#x1f680; &#x1f680;随着科技的快速发展&#xff0c;AIGC已经成为引领未来的重要力量。其中&#xff0c;AIGC在虚拟数字人领域的应用更是引起了广泛关注。虚拟数字人作为一种先进的数字化表达形式&#xff0c;结合了3D建模、动画技术、人工智能等多种先进…

Kubernetes对象的定义和操作

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列、spring教程等&#xff0c;大家有兴趣的可以看一看 &#x1f4d9;Jav…

数据密集型应用系统设计 PDF 电子书(Martin Kleppmann 著)

简介 《数据密集型应用系统设计》全书分为三大部分&#xff1a; 第一部分&#xff0c;主要讨论有关增强数据密集型应用系统所需的若干基本原则。首先开篇第 1 章即瞄准目标&#xff1a;可靠性、可扩展性与可维护性&#xff0c;如何认识这些问题以及如何达成目标。第 2 章我们比…

PHP反序列化命令执行+PHP反序列化POP大链 +PHP反序列化基础

[题目信息]&#xff1a; 题目名称题目难度PHP反序列化命令执行1 [题目考点]&#xff1a; 反序列化命令执行&#xff0c;获取题目flag。[Flag格式]: SangFor{t5euvZ_OB8Jd_h2-}[环境部署]&#xff1a; docker-compose.yml文件或者docker tar原始文件。 docker-compose up …

内外网文件摆渡系统,如何贯通网络两侧被隔断的工作流?

随着业务范围不断扩大&#xff0c;产生的数据体量越来越多&#xff0c;企业会采取网络隔离&#xff0c;对核心数据进行保护。网络隔离主要目的是保护企业内部的敏感数据和系统不受外部网络攻击的风险&#xff0c;可以通过物理或逻辑方式实现&#xff0c;例如使用防火墙、网闸、…

电商技术揭秘二十六:智能库存预警与补货系统(下)

相关系列文章 电商技术揭秘一&#xff1a;电商架构设计与核心技术 电商技术揭秘二&#xff1a;电商平台推荐系统的实现与优化 电商技术揭秘三&#xff1a;电商平台的支付与结算系统 电商技术揭秘四&#xff1a;电商平台的物流管理系统 电商技术揭秘五&#xff1a;电商平台…

我的思考工作流(2024年版)

去年底&#xff0c;我对自己的思考工作流程又做了一些优化和改进&#xff0c;把它变得更为简洁、清晰。 因此&#xff0c;今天我想把它分享给大家&#xff0c;希望能给你一些启发。 我的核心方法论依然是我自己提出的「INKP知识管理法」&#xff08;参见《打开心智》第五章&…

【刷题笔记】第七天

文章目录 [924. 尽量减少恶意软件的传播](https://leetcode.cn/problems/minimize-malware-spread/)方法一&#xff0c;并查集方法二&#xff0c;dfs [GCD and LCM ](https://vjudge.net.cn/problem/HDU-4497#authorKING_LRL) 924. 尽量减少恶意软件的传播 如果移除一个感染节…

电机控制器电路板布局布线参考指导(五)

电机控制器电路板布局布线参考指导&#xff08;五&#xff09;大容量电容和旁路电容的放置 1.大容量电容的放置2.电荷泵电容器3.旁路电容/去耦电容的放置3.1 靠近电源3.2 靠近功率器件3.3 靠近开关电流源3.4 靠近电流感测放大器3.5 靠近稳压器 tips&#xff1a;资料主要来自网络…

环境搭建创建项目_使用DevEco开发工具进行开发_创建项目_认识项目结构---HarmonyOS4.0+鸿蒙NEXT工作笔记001

首先去下载DevEco Studio然后再去安装就可以了 安装下一步下一步非常简单 首先去安装nodejs,可以看到,有两个安装方法,左边是自己安装的制定文件夹就可以了,然后 右边是使用鸿蒙自带的,我们选择第二个 然后我们看这个ohpm其实就跟npm是一个意思,用来管理鸿蒙的包的. 这里我们…

apache配置ssl证书

SSL证书&#xff0c;即安全套接层证书&#xff0c;是一种数字证书&#xff0c;它通过在客户端浏览器和Web服务器之间建立一条加密通道&#xff0c;保证了双方传输信息的安全性。当用户访问一个使用SSL证书保护的网站时&#xff0c;浏览器会显示一个锁形图标&#xff0c;表示连接…

FILE类与IO流

目录 File类的实例化与常用方法 File类的理解 文件路径的表示方式&#xff1a; API的使用 IO流概述与流的分类 I/O流中的是Input/Output的缩写 IO流的分类&#xff08;不同角度&#xff09; Java程序中的IO流涉及40多个&#xff0c;但实际上都是由4个抽象类衍生出来的。 F…

零代码编程:用kimichat将mp4视频批量转为mp3音频

一个文件夹里面有多个子文件夹&#xff0c;里面的视频需要转成为mp3音频格式。可以在kimichat中键入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本的编写任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;D:\CHATGPT For TikT…

Docker Container (容器) 常见命令

Docker 容器的生命周期 什么是容器&#xff1f; 通俗地讲&#xff0c;容器是镜像的运行实体。镜像是静态的只读文件&#xff0c;而容器带有运行时需要的可写文件层&#xff0c;并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容 器有初建、运行、停止、暂停和删除…

HTTP协议安全传输教程

HTTP协议有多个版本&#xff0c;包括但不限于HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2和HTTP/3。这些版本各自具有不同的特点和改进&#xff0c;以适应网络技术的发展和满足不同的需求。例如&#xff0c;HTTP/1.0使用文本格式传输数据&#xff0c;简单易用且兼容性好&#xff0c;…

安装指定版本的ant-design-vue和指定版本的@ant-design/icons-vue 图标组件包

前言&#xff1a; 最近在完成公司的项目时&#xff0c;为了兼容其他的版本&#xff0c;需要安装指定版本的ant-design-vue和ant-design/icons-vue 图标组件包&#xff0c;安装成功之后&#xff0c;分享如下&#xff1a; 安装命令&#xff1a; ant-design-vue&#xff1a; 不…

深入剖析跨境电商平台风控机制,探索测评安全与稳定的秘诀

在跨境电商测评市场鱼龙混杂的当下&#xff0c;测评过程中可能隐藏的陷阱保持高度警觉。多年的测评经验告诉我们&#xff0c;选择一个适合的测评系统对于项目的成功至关重要。近年来&#xff0c;测评技术如雨后春笋般涌现&#xff0c;市场上涌现出众多测评系统&#xff0c;覆盖…