Redis常见面试问题汇总
Redis 面试笔记整理
- 一、Redis 基础知识
- 1. Redis 概述
- Redis 是什么?主要特点有哪些?
- Redis 和 Memcached 的区别是什么?
- Redis 是单线程还是多线程?为什么单线程还能高效?
- Redis 6.0 之后的多线程模型是怎样的?
- 2. Redis 数据类型
- Redis 支持的数据类型及使用场景
- String(字符串)
- Hash(哈希)
- List(列表)
- Set(集合)
- ZSet(有序集合)
- Bitmap(位图)
- HyperLogLog(基数统计)
- GEO(地理空间)
- Stream(消息流)
- 底层实现原理
- ZSet实现(跳表+哈希表)
- Hash实现(压缩列表或哈希表)
- 3. Redis 持久化
- Redis 的持久化机制
- RDB 和 AOF 的区别与优缺点
- RDB 触发方式
- AOF 重写机制
- 生产环境配置建议
- 二、Redis 高可用与集群
- 1. 主从复制
- Redis 主从复制原理
- 主从复制常见问题
- 主从复制性能优化
- 2. Redis Sentinel(哨兵)
- Redis Sentinel 的作用
- 故障检测机制
- Sentinel 选举机制
- 3. Redis Cluster(集群)
- Redis Cluster 数据分片
- 节点通信机制
- 集群扩缩容
- 请求重定向机制
- 三、Redis 缓存问题
- 1. 缓存穿透、缓存雪崩、缓存击穿
- 缓存穿透
- 缓存雪崩
- 缓存击穿
- 2. 缓存一致性
- 如何保证缓存与数据库的数据一致性
- 先更新数据库再删缓存(推荐方案)
- 延迟双删策略
- 其他保障措施
- 缓存更新策略
- Cache Aside(旁路缓存)
- Read/Write Through
- Write Behind
- 3. 缓存淘汰策略
- Redis内存淘汰策略
- 策略选择建议
- 四、Redis 高级特性与优化
- 1. Redis 事务与 Lua 脚本
- Redis 事务(MULTI/EXEC)工作机制
- WATCH 命令(乐观锁实现)
- Lua 脚本优势及原子性保证
- 2. Redis 性能优化
- Redis Pipeline 机制
- BigKey 问题处理
- 慢查询分析
- 连接数优化
- 3. Redis 网络与安全
- Redis 通信协议 (RESP)
- 安全认证配置
- SCAN vs KEYS 命令
- 五、Redis 应用场景
- 1. 常见业务场景
- 分布式锁实现
- 限流方案
- 排行榜实现
- 消息队列方案
- Session共享
- 秒杀系统实现
- 2. 高级应用
- 布隆过滤器实现
- HyperLogLog统计UV
- GEO地理位置
- BitMap签到功能
- 六、Redis 与其他技术结合
- Spring Boot 集成 Redis
- Redis + MySQL 配合方案
- Redis 和本地缓存(Caffeine、Guava Cache)如何选择?
- 选择依据对比
- 电商分层缓存实战示例
- 场景:商品详情页缓存
- 选型建议
- 必须使用Redis的场景
- 优先本地缓存的场景
- 七、Redis 底层实现
- Redis 的 SDS(Simple Dynamic String)和 C 字符串区别
- Redis 字典(Hash 表)实现
- Redis 跳跃表(Skip List)工作原理
- Redis 过期键删除策略
一、Redis 基础知识
1. Redis 概述
Redis 是什么?主要特点有哪些?
- Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统
- 主要特点:
- 高性能:数据存储在内存中,读写速度极快(10万+ QPS)
- 支持多种数据结构:String、Hash、List、Set、ZSet等
- 持久化:支持RDB和AOF两种持久化方式
- 高可用:支持主从复制、哨兵、集群模式
- 原子操作:支持事务和Lua脚本保证原子性
Redis 和 Memcached 的区别是什么?
特性 | Redis | Memcached |
---|---|---|
数据类型 | 支持多种数据结构 | 仅支持简单的key-value |
持久化 | 支持RDB和AOF持久化 | 不支持持久化 |
集群模式 | 原生支持Cluster模式 | 需要客户端实现分布式 |
线程模型 | 单线程(6.0+支持多线程I/O) | 多线程 |
内存管理 | 支持内存淘汰策略 | 固定大小内存,LRU淘汰 |
适用场景 | 缓存、消息队列、计数器等复杂场景 | 简单的键值缓存场景 |
Redis 是单线程还是多线程?为什么单线程还能高效?
- Redis 核心网络模型是单线程的(6.0之前是完全单线程)
- 高效的原因:
- 基于内存操作,没有磁盘I/O瓶颈
- 单线程避免了多线程的上下文切换和竞争条件
- 非阻塞I/O多路复用(epoll/kqueue)
- 精心优化的数据结构(如跳表、哈希表)
Redis 6.0 之后的多线程模型是怎样的?
- Redis 6.0 引入了多线程I/O(默认关闭,需配置)
- 模型特点:
- 主线程仍处理命令执行(保持单线程特性)
- 新增I/O线程(默认4个)负责:
- 网络读:解析客户端请求
- 网络写:返回结果给客户端
- 配置参数:
io-threads 4 # 启用4个I/O线程 io-threads-do-reads yes # 启用读多线程
- 注意:
- 实际命令执行仍是单线程
- 性能提升主要在超高并发网络I/O场景
2. Redis 数据类型
Redis 支持的数据类型及使用场景
String(字符串)
- 存储结构:二进制安全的字符串,最大512MB
- 典型场景:
- 缓存对象(JSON序列化存储)
- 计数器(INCR/DECR命令)
- 分布式锁(SETNX实现)
- 会话管理(Session存储)
- 特殊操作:
SETEX key seconds value # 带过期时间设置GETSET key new_value # 设置新值返回旧值MSET/MGET # 批量操作
Hash(哈希)
- 存储结构:field-value映射表
- 典型场景:
- 存储对象属性(用户资料)
- 购物车数据(用户ID+商品ID)
- 配置信息集合
- 优势:
- 比String更节省空间(避免重复key)
- 支持部分字段操作
List(列表)
- 存储结构:双向链表
- 典型场景:
- 消息队列(LPUSH+BRPOP)
- 最新消息排行(朋友圈)
- 数据分页(LRANGE)
- 特点:
LPUSH/RPUSH # 左右插入BLPOP/BRPOP # 阻塞式弹出
Set(集合)
- 存储结构:无序唯一集合
- 典型场景:
- 好友关系(共同好友SINTER)
- 抽奖活动(SRANDMEMBER)
- 标签系统
- 核心命令:
SADD/SREM # 增删元素SISMEMBER # 判断存在SUNION/SDIFF # 并集/差集
ZSet(有序集合)
- 存储结构:跳表+哈希表
- 典型场景:
- 排行榜(ZREVRANGE)
- 延迟队列(时间戳作为score)
- 优先级任务
- 特点:
ZADD key score member # 带分数插入ZRANGEBYSCORE # 按分数范围查询
Bitmap(位图)
- 存储结构:String的位操作
- 典型场景:
- 用户签到(SETBIT)
- 活跃用户统计
- 布隆过滤器实现
- 示例:
SETBIT sign:2023:user1 1 1 # 第1天签到BITCOUNT sign:2023:user1 # 签到总数
HyperLogLog(基数统计)
- 存储结构:概率算法
- 典型场景:
- UV统计(去重计数)
- 大规模数据去重
- 特点:
- 固定12KB存储空间
- 误差率约0.81%
PFADD/PFCOUNT # 添加/计数
GEO(地理空间)
- 存储结构:ZSet扩展
- 典型场景:
- 附近的人
- 位置搜索
- 距离计算
- 核心命令:
GEOADD key 经度 纬度 memberGEORADIUS # 半径查询
Stream(消息流)
- 存储结构:持久化消息队列
- 典型场景:
- 消息队列(替代List)
- 事件溯源
- 日志收集
- 特点:
XADD/XREAD # 生产/消费Consumer Groups # 消费者组支持
底层实现原理
ZSet实现(跳表+哈希表)
- 跳表结构:
- 多层链表,查询复杂度O(logN)
- 支持范围查询
- 哈希表:
- 存储member到score的映射
- O(1)时间复杂度查询单个元素
- 内存优化:
- 元素小于128字节且数量<512时使用ziplist
Hash实现(压缩列表或哈希表)
- ziplist条件:
- 所有field/value长度<64字节
- field数量<512
- hashtable:
- 字典结构(数组+链表)
- 渐进式rehash策略
- 转换阈值:
hash-max-ziplist-entries 512hash-max-ziplist-value 64
3. Redis 持久化
Redis 的持久化机制
Redis 提供两种持久化方式:
- RDB(Redis Database):定时生成内存快照
- AOF(Append Only File):记录所有写操作命令
RDB 和 AOF 的区别与优缺点
特性 | RDB | AOF |
---|---|---|
持久化方式 | 二进制快照 | 命令追加日志 |
文件大小 | 较小(压缩存储) | 较大(持续增长) |
恢复速度 | 快 | 慢(需重放命令) |
数据安全性 | 可能丢失最后一次快照后的数据 | 可配置不同刷盘策略保证数据安全 |
性能影响 | 保存时影响性能 | 写入性能影响较小 |
恢复优先级 | 低 | 高(默认优先使用AOF恢复) |
RDB 触发方式
- 手动触发:
SAVE # 同步保存,阻塞主线程BGSAVE # 后台异步保存(fork子进程)
- 自动触发(redis.conf配置):
save 900 1 # 900秒内至少1个key变化save 300 10 # 300秒内至少10个key变化save 60 10000 # 60秒内至少10000个key变化
AOF 重写机制
-
作用:
- 压缩AOF文件体积(去除冗余命令)
- 重建更优的持久化命令序列
-
触发方式:
- 手动触发:
BGREWRITEAOF
- 自动触发(需配置):
- 手动触发:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
- 优化策略:
- 使用AOF重写缓冲区
- 配置合理的重写触发阈值
- 开启AOF-RDB混合模式(4.0+)
生产环境配置建议
-
选择策略:
- 数据安全性要求高:AOF(appendfsync always)
- 快速恢复优先:RDB
- 折中方案:同时开启RDB+AOF
-
推荐配置:
appendonly yes # 开启AOFappendfsync everysec # 折中刷盘策略aof-use-rdb-preamble yes # 开启混合持久化(4.0+)save 900 1 # 保留RDB触发条件
- 注意事项:
- 同时开启时重启优先加载AOF文件
- 混合模式结合两者优势(4.0+版本)
- 监控持久化文件大小和性能影响
二、Redis 高可用与集群
1. 主从复制
Redis 主从复制原理
-
全量同步过程:
- 从节点发送SYNC命令
- 主节点执行BGSAVE生成RDB文件
- 主节点将RDB文件发送给从节点
- 从节点清空数据后加载RDB
- 主节点将缓冲区的写命令发送给从节点
-
增量同步过程:
- 主节点维护复制积压缓冲区(repl_backlog)
- 从节点断线重连后发送PSYNC命令
- 主节点发送缓冲区中缺失的命令
-
关键参数:
repl-backlog-size 1mb # 复制积压缓冲区大小repl-backlog-ttl 3600 # 缓冲区保留时间(秒)
主从复制常见问题
-
数据延迟:
- 原因:网络延迟、主节点写入量过大
- 监控:INFO replication查看slave_repl_offset
-
主从切换问题:
- 故障转移时可能丢失部分数据
- 新主节点选举期间服务不可用
-
其他问题:
- 全量同步导致主节点内存峰值
- 从节点过期key处理不及时
- 网络闪断导致频繁全量同步
主从复制性能优化
- 网络优化:
- 主从节点同机房部署
- 增大复制缓冲区大小:
repl-backlog-size 256mb
-
配置优化:
- 关闭从节点AOF(除非需要)
- 设置合理的主节点保存间隔:
save 300 100
-
其他优化:
- 使用SSD磁盘提高RDB传输速度
- 适当增大TCP缓冲区大小
- 监控复制延迟(redis-cli --latency)
-
特殊场景优化:
- 级联复制减轻主节点压力
- 读写分离时控制从节点数量
2. Redis Sentinel(哨兵)
Redis Sentinel 的作用
-
核心功能:
- 监控:持续检查主从节点运行状态
- 通知:通过API向管理员发送故障报警
- 自动故障转移:主节点故障时提升从节点为新主节点
- 配置中心:客户端自动获取最新主节点地址
-
故障转移流程:
- 检测主节点失效(主观下线→客观下线)
- 选举领头Sentinel
- 领头Sentinel执行故障转移:
- 选择最优从节点
- 将其提升为主节点
- 配置其他从节点复制新主节点
- 通知客户端配置变更
故障检测机制
-
主观下线(SDOWN):
- 单个Sentinel实例检测到主节点无响应
- 判定条件(可配置):
down-after-milliseconds 5000 # 5秒无响应
-
客观下线(ODOWN):
- 多个Sentinel达成共识认为主节点不可用
- 判定条件:
quorum 2 # 需要至少2个Sentinel同意
Sentinel 选举机制
-
选举触发条件:
- 主节点被判定为客观下线
- 需要执行故障转移操作
-
选举规则:
- 基于Raft算法实现
- 每个发现主节点下线的Sentinel都会要求其他Sentinel选举自己为leader
- 先到先得原则(先发送选举请求的优先)
- 获得多数票(>N/2+1)的Sentinel成为leader
-
选举相关配置:
sentinel monitor mymaster 127.0.0.1 6379 2 # 监控的主节点名称、IP、端口、quorum数
sentinel failover-timeout mymaster 180000 # 故障转移超时时间(毫秒) -
选举失败处理:
- 若选举超时(failover-timeout)仍未选出leader
- 等待一段时间后重新发起选举
3. Redis Cluster(集群)
Redis Cluster 数据分片
-
哈希槽分配:
- 整个集群被划分为16384个哈希槽(slot)
- 每个key通过CRC16算法计算后取模:
slot = CRC16(key) % 16384
- 每个节点负责一部分哈希槽范围
-
槽分配示例:
- 节点A:0-5460
- 节点B:5461-10922
- 节点C:10923-16383
-
数据分布特性:
- 支持key哈希标签:
{user1000}.profile
和{user1000}.account
会被分配到相同slot - 迁移过程中允许部分key访问
- 支持key哈希标签:
节点通信机制
-
Gossip协议:
- 节点间通过PING/PONG消息保持通信
- 每个节点随机选择部分节点进行通信(默认每秒10次)
- 传播的信息包括:
- 节点状态
- 哈希槽分配
- 集群配置epoch
-
通信优化:
cluster-node-timeout 15000 # 节点超时时间(毫秒)
cluster-require-full-coverage yes # 是否需要所有槽被覆盖
集群扩缩容
- 扩容流程:
# 添加新节点
redis-cli --cluster add-node new_host:new_port existing_host:existing_port # 重新分配槽
redis-cli --cluster reshard existing_host:existing_port# 输入要迁移的槽数量# 选择接收这些槽的目标节点ID# 选择从哪些源节点迁移槽
- 缩容流程:
# 迁移待删除节点的槽到其他节点redis-cli --cluster reshard del_node_host:del_node_port# 删除空节点redis-cli --cluster del-node del_node_host:del_node_port node_id
- 自动平衡:
redis-cli --cluster rebalance --use-empty-masters
请求重定向机制
-
MOVED重定向:
- 当客户端访问错误的节点时
- 节点返回:
MOVED 1234 10.0.0.2:6379
- 表示key属于槽1234,应由10.0.0.2:6379处理
- 客户端应更新本地slot缓存
-
ASK重定向:
- 发生在集群迁移过程中
- 返回格式:
ASK 1234 10.0.0.2:6379
- 表示key正在迁移,临时访问目标节点
- 客户端需先发送ASKING命令
-
智能客户端处理:
- 维护slot与节点的映射关系
- 自动处理重定向请求
- 定期更新集群拓扑信息
三、Redis 缓存问题
1. 缓存穿透、缓存雪崩、缓存击穿
缓存穿透
问题定义:大量请求查询不存在的数据,绕过缓存直接访问数据库
解决方案:
-
布隆过滤器(Bloom Filter):
- 前置过滤器拦截不存在key的请求
- 优点:内存占用极小
- 缺点:存在误判率(可配置)
-
空值缓存:
- 对查询结果为null的key也进行缓存
- 设置较短过期时间:
SET key_null "" EX 300
-
其他方案:
- 接口层增加参数校验
- 用户权限校验前置
缓存雪崩
问题定义:大量缓存同时失效,导致请求直接冲击数据库
解决方案:
-
过期时间随机化:
- 基础时间 + 随机偏移量
SET key value EX ${1800 + random(300)}
- 基础时间 + 随机偏移量
-
多级缓存架构:
- 本地缓存(Caffeine) + Redis集群
- 不同层级设置不同过期策略
-
其他方案:
- 热点数据永不过期(后台异步更新)
- 熔断降级机制(Hystrix/Sentinel)
缓存击穿
问题定义:热点key突然失效,大量并发请求直接访问数据库
解决方案:
- 互斥锁(分布式锁):
- 使用SETNX实现锁机制
if (redis.setnx("lock_key", 1, "EX", 10)) {try {// 查询数据库// 更新缓存} finally {redis.del("lock_key")}
}
-
热点数据永不过期:
- 不设置过期时间
- 后台定时任务异步更新
-
其他方案:
- 逻辑过期时间(value中存储过期时间戳)
- 请求合并(将多个并发查询合并为单个查询)
2. 缓存一致性
如何保证缓存与数据库的数据一致性
先更新数据库再删缓存(推荐方案)
-
操作流程:
- 先更新数据库
- 再删除缓存
- 后续读取时重新加载缓存
-
优点:
- 实现简单
- 避免大多数并发问题
-
潜在问题及解决方案:
- 删除缓存失败 → 加入重试机制(消息队列)
- 读请求在删除前加载旧数据 → 设置较短过期时间
延迟双删策略
-
操作流程:
- 先删除缓存
- 再更新数据库
- 延迟一定时间后再次删除缓存
-
典型实现:
// 第一次删除redis.del(key)// 更新数据库db.update(data) // 延迟删除(如500ms后)Thread.sleep(500)redis.del(key)
- 适用场景:
- 对一致性要求高的场景
- 能容忍短暂延迟
其他保障措施
-
版本号机制:
- 在缓存value中加入数据版本号
- 更新时校验版本号
-
异步监听binlog:
- 通过canal监听数据库变更
- 自动更新/删除缓存
缓存更新策略
Cache Aside(旁路缓存)
-
读流程:
- 先查缓存,命中则返回
- 未命中则查DB,并写入缓存
-
写流程:
- 直接更新DB
- 删除对应缓存
Read/Write Through
-
读流程:
缓存作为主要数据源,自动从DB加载 -
写流程:
先写缓存,由缓存系统负责同步写入DB
Write Behind
- 写流程:
先写缓存,异步批量更新DB - 特点:
高性能但可能丢失数据
3. 缓存淘汰策略
Redis内存淘汰策略
-
不淘汰:
noeviction
→ 内存满时拒绝写入 -
全局淘汰:
allkeys-lru
→ 最近最少使用
allkeys-lfu
→ 最不经常使用
allkeys-random
→ 随机淘汰 -
有过期时间的key淘汰:
volatile-lru
→ 在过期key中LRU
volatile-lfu
→ 在过期key中LFU
volatile-ttl
→ 淘汰剩余TTL最短的
volatile-random
→ 随机淘汰过期key
策略选择建议
-
常规场景:
allkeys-lru
(平衡性好) -
热点数据明显:
allkeys-lfu
(更精准) -
严格保证数据不过期:
noeviction
+ 监控 -
混合使用场景:
volatile-lru
+ 合理设置TTL -
配置方式:
maxmemory-policy allkeys-lru
maxmemory 4gb # 设置最大内存
四、Redis 高级特性与优化
1. Redis 事务与 Lua 脚本
Redis 事务(MULTI/EXEC)工作机制
- 基本流程:
- 使用MULTI开始事务
- 将多个命令入队
- 使用EXEC执行所有命令
- 示例:
MULTISET key1 value1INCR key2EXEC
-
ACID特性支持:
- 原子性(A):单条命令原子执行,但事务不保证(某条失败不影响其他命令)
- 一致性(C):总能保证数据一致性
- 隔离性(I):单线程模型天然隔离
- 持久性(D):取决于持久化配置
-
事务特点:
- 不支持回滚(与关系型数据库不同)
- 命令执行期间不会被其他客户端打断
WATCH 命令(乐观锁实现)
- 工作原理:
- 监视一个或多个key
- 如果在EXEC前这些key被修改,则事务失败
- 示例:
WATCH balanceval = GET balanceMULTISET balance val-100EXEC
-
典型应用场景:
- 账户余额修改
- 库存扣减
- 需要CAS(Compare-And-Swap)的场景
-
注意事项:
- 需要配合重试机制使用
- 不适用于高竞争场景(可能导致大量重试)
Lua 脚本优势及原子性保证
-
推荐使用原因:
- 减少网络开销(多个操作合并)
- 避免竞态条件(脚本整体原子执行)
- 复杂操作封装(如分布式锁实现)
- 执行效率高(脚本会被缓存)
-
原子性保证机制:
- Redis单线程执行Lua脚本
- 脚本执行期间不会处理其他命令
- 示例原子操作:
local current = redis.call('GET', KEYS[1])if current == ARGV[1] thenreturn redis.call('SET', KEYS[1], ARGV[2])end
- 最佳实践:
- 控制脚本复杂度(避免长时间阻塞)
- 使用SCRIPT LOAD预加载脚本
- 避免在脚本中使用随机写操作
2. Redis 性能优化
Redis Pipeline 机制
-
基本原理:
- 将多个命令打包一次性发送
- 减少网络往返时间(RTT)
- 服务端按顺序执行并批量返回结果
-
性能提升方式:
- 典型提升5-10倍吞吐量
- 适合批量写入/读取场景
- 示例实现:
Pipeline p = jedis.pipelined();for(int i=0; i<10000; i++){p.set("key"+i, "value"+i);}p.sync();
- 注意事项:
- 单次Pipeline不宜包含过多命令
- 不适用于有命令依赖的场景
- 需要合理设置超时时间
BigKey 问题处理
- 排查方法:
- 使用内置命令:
redis-cli --bigkeysMEMORY USAGE key
- 扫描分析工具:
redis-rdb-tools分析RDB文件
-
优化方案:
- 大Key拆分:
将hash拆分为多个小hash - 数据压缩:
使用Snappy等算法压缩value - 存储优化:
改用更适合的数据结构
- 大Key拆分:
-
预防措施:
- 设置监控告警
- 避免存储超大value(>10KB)
- 定期扫描清理
慢查询分析
- 配置与查看:
- 设置阈值(微秒):slowlog-log-slower-than 10000- 保留条数:slowlog-max-len 128- 查看慢日志:SLOWLOG GET 10
-
常见优化方向:
- 避免O(N)命令操作大数据集
- 优化复杂Lua脚本
- 合理使用索引
-
分析工具:
- redis-faina分析监控日志
- 可视化工具展示慢查询趋势
连接数优化
-
连接池配置:
- 最大连接数:
maxTotal 50
- 最大空闲连接:
maxIdle 10
- 最小空闲连接:
minIdle 5
- 最大连接数:
-
优化建议:
- 合理设置超时时间:
timeout 3000
- 使用连接池复用连接
- 避免短连接操作
- 合理设置超时时间:
-
问题排查:
- 查看当前连接:
CLIENT LIST
- 分析连接来源:
INFO clients
- 紧急断开连接:
CLIENT KILL
- 查看当前连接:
3. Redis 网络与安全
Redis 通信协议 (RESP)
-
协议特点:
- 二进制安全的文本协议
- 简单易实现
- 支持多种数据类型编码
-
协议格式:
- 简单字符串: “+OK\r\n”
- 错误: “-Error message\r\n”
- 整数: “:1000\r\n”
- 批量字符串: “$6\r\nfoobar\r\n”
- 数组: “*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n”
-
工作方式:
- 客户端-服务端基于TCP通信
- 默认端口6379
- 支持管道和批量操作
安全认证配置
-
密码认证设置:
redis.conf配置
requirepass your_strong_password
客户端认证
AUTH your_strong_password
-
防护措施:
- 修改默认端口
- 绑定指定IP:
bind 127.0.0.1
- 禁用危险命令:
rename-command FLUSHALL ""
- 启用保护模式:
protected-mode yes
-
网络安全:
- 使用SSL隧道
- 配置防火墙规则
- 启用ACL(Redis 6.0+)
SCAN vs KEYS 命令
-
SCAN命令特点:
- 增量式迭代
- 不阻塞服务器
- 可能返回重复key
- 语法:
SCAN cursor [MATCH pattern] [COUNT count]
-
KEYS命令风险:
- 一次性返回所有匹配key
- 大数据量时会阻塞服务
- 导致性能骤降
-
生产环境建议:
- 永远禁用KEYS *
- 使用SCAN替代大数据量查询
- 监控脚本示例:
local cursor = "0"repeatlocal reply = redis.call("SCAN", cursor, "MATCH", "user:*")cursor = reply[1]-- 处理返回的keysuntil cursor == "0"
五、Redis 应用场景
1. 常见业务场景
分布式锁实现
核心方案:
-
基础实现:
SET lock_key unique_value NX EX 10
- NX: 仅当key不存在时设置
- EX: 设置过期时间(秒)
- unique_value: 唯一标识(通常使用UUID)
-
优化版(Lua脚本保证原子性):
if redis.call("SETNX", KEYS[1], ARGV[1]) == 1 thenreturn redis.call("EXPIRE", KEYS[1], ARGV[2])elsereturn 0end
- 注意事项:
- 必须设置过期时间
- 解锁需验证value值
- 考虑锁续期问题
限流方案
INCR计数器方案:
- 固定窗口:
local counter = redis.call("INCR", KEYS[1])if counter == 1 thenredis.call("EXPIRE", KEYS[1], ARGV[1])endreturn counter <= tonumber(ARGV[2])
- 令牌桶算法:
- 使用Hash存储:last_time, tokens
- Lua脚本计算当前可用令牌数
- 补充速率控制
参数示例:
- KEYS[1]: rate_limiter:user1
- ARGV[1]: 时间窗口(如60秒)
- ARGV[2]: 最大请求数(如100)
排行榜实现
ZSet核心操作:
-
更新分数:
ZADD leaderboard 100 "user1"
-
获取排名:
ZREVRANGE leaderboard 0 9 WITHSCORES
-
用户排名:
ZREVRANK leaderboard "user1"
优化技巧:
- 定期持久化到数据库
- 分片存储超大排行榜
- 使用ZUNIONSTORE合并多个榜单
消息队列方案
List基础方案:
-
生产者:
LPUSH orders "order_data"
-
消费者:
BRPOP orders 30
**Stream方案(Redis 5.0+):
-
生产消息:
XADD mystream * field1 value1 field2 value2
-
消费消息:
XREAD BLOCK 0 STREAMS mystream $
-
消费者组:
XGROUP CREATE mystream mygroup $
Session共享
实现方案:
-
存储结构:
SETEX session:sessionid 3600 "user_data"
-
Spring集成配置:
spring.session.store-type=redis
server.servlet.session.timeout=3600
-
集群方案:
- 相同TTL配置
- 合理设置序列化方式
秒杀系统实现
库存扣减方案:
- Lua脚本保证原子性:
local stock = tonumber(redis.call("GET", KEYS[1]))if stock > 0 thenredis.call("DECR", KEYS[1])return 1endreturn 0
- 优化措施:
- 库存预热
- 分段锁减少竞争
- 异步扣减+结果通知
参数示例:
- KEYS[1]: seckill:stock:123
- ARGV[1]: 无(可扩展传用户ID)
2. 高级应用
布隆过滤器实现
-
RedisBloom模块:
- 加载模块:
redis-server --loadmodule /path/to/redisbloom.so
- 基本命令:
BF.ADD myfilter item1
BF.EXISTS myfilter item1
- 参数配置:
BF.RESERVE myfilter 0.01 100000
- 加载模块:
-
原生实现方案:
- 使用Bitmap+多个哈希函数
- 示例SETBIT操作:
SETBIT bloom:filter hash1(item) 1
SETBIT bloom:filter hash2(item) 1
HyperLogLog统计UV
-
基础命令:
- 添加访问记录:
PFADD uv:20230515 user1 user2 user3
- 获取统计结果:
PFCOUNT uv:20230515
- 合并多日数据:
PFMERGE uv:week uv:day1 uv:day2
- 添加访问记录:
-
精度说明:
- 标准误差0.81%
- 固定使用12KB内存
- 适合大数据量去重
GEO地理位置
-
核心命令:
- 添加位置:
GEOADD locations 116.404 39.915 "user1"
- 查询附近的人:
GEORADIUS locations 116.404 39.915 10 km WITHDIST
- 计算距离:
GEODIST locations user1 user2 km
- 添加位置:
-
实现原理:
- 基于ZSet存储
- 使用Geohash编码
- 有效距离范围:-180到180经度
BitMap签到功能
-
每日签到:
- 用户签到:
SETBIT sign:user1:202305 15 1
- 查询签到:
GETBIT sign:user1:202305 15
- 统计签到:
BITCOUNT sign:user1:202305
- 用户签到:
-
连续签到计算:
- 获取位图数据:
GET sign:user1:202305
- 客户端解析连续天数
- 支持多维度统计:
BITOP AND result sign:user1:202305 sign:user1:202306
- 获取位图数据:
六、Redis 与其他技术结合
Spring Boot 集成 Redis
- 基础配置:
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=yourpassword
spring.redis.lettuce.pool.max-active=8
- 核心组件:
RedisTemplate
: 提供各种数据结构操作StringRedisTemplate
: 字符串专用模板LettuceConnectionFactory
: 默认连接池(优于Jedis)
- 典型用法:
@Autowired
private RedisTemplate<String, Object> redisTemplate;// 操作示例
redisTemplate.opsForValue().set("key", "value");
redisTemplate.opsForHash().put("user", "id", 1001);
Redis + MySQL 配合方案
- 缓存策略:
- Cache Aside Pattern:
- 读: 先查缓存→未命中查DB→回填缓存
- 写: 更新DB→删除缓存
- 双写一致性方案:
- 延迟双删:
- 删除缓存
- 更新数据库
- 延迟500ms再次删除
- 监听binlog变更(通过canal)
Redis 和本地缓存(Caffeine、Guava Cache)如何选择?
选择依据对比
特性 | Redis | Caffeine/Guava Cache |
---|---|---|
数据范围 | 全集群共享 | 仅单机有效 |
性能 | 微秒级(网络IO影响) | 纳秒级(内存访问) |
容量 | 支持GB/TB级别 | 通常MB级别(受JVM堆限制) |
数据结构 | 支持丰富的数据结构 | 简单KV结构 |
持久化 | 支持 | 不支持 |
适用场景 | 分布式缓存、共享数据 | 高频热点数据、临时数据 |
电商分层缓存实战示例
场景:商品详情页缓存
-
架构设计:
用户请求 → Nginx → 本地缓存(Caffeine)→ Redis集群 → MySQL -
代码实现:
// 初始化多级缓存@Beanpublic Cache<String, Product> productCache() {return Caffeine.newBuilder().maximumSize(10_000) // 本地缓存1万个商品.expireAfterWrite(5, TimeUnit.MINUTES).build();}// 查询逻辑public Product getProduct(Long id) {String key = "product:" + id;// 先查本地缓存Product product = productCache.getIfPresent(key);if (product != null) return product;// 再查Redisproduct = redisTemplate.opsForValue().get(key);if (product == null) {product = productMapper.selectById(id); // 查数据库// 异步回填缓存executor.execute(() -> {redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS);productCache.put(key, product); });} else {productCache.put(key, product); // 回填本地缓存}return product;}
-
优势分析:
- 本地缓存:扛住90%以上的商品查询请求
- Redis层:保证集群各节点的数据一致性
- 数据库:最终数据源,流量削峰达99%
-
关键配置:
- 本地缓存TTL(5分钟)< Redis TTL(1小时)
- 本地缓存最大条目数根据内存调整
- 使用异步线程回填避免阻塞主流程
选型建议
必须使用Redis的场景
- 需要跨服务共享的数据(如库存)
- 需要持久化的关键数据
- 复杂数据结构需求(如排行榜)
优先本地缓存的场景
- 极端性能要求(秒杀系统)
- 不要求强一致性的数据(商品描述)
- 单机高频访问数据(用户基础信息)
七、Redis 底层实现
Redis 的 SDS(Simple Dynamic String)和 C 字符串区别
特性 | SDS | C 字符串 |
---|---|---|
长度获取 | O(1) 直接读取len属性 | O(n) 需要遍历计算 |
缓冲区安全 | 自动扩容,不会缓冲区溢出 | 容易缓冲区溢出 |
二进制安全 | 可以存储任意二进制数据 | 只能存储文本,遇’\0’终止 |
内存分配 | 预分配+惰性释放策略 | 每次修改需重新分配 |
兼容性 | 末尾保留’\0’兼容C函数 | - |
Redis 字典(Hash 表)实现
-
核心结构:
- 哈希表数组 + 链表解决冲突
- 包含两个哈希表(ht[0]和ht[1])用于rehash
-
渐进式rehash过程:
- 扩容时机:负载因子 > 1 且允许rehash,或负载因子 > 5 强制rehash
- 步骤:
- 分配ht[1]空间(大小为第一个大于等于ht[0].used*2的2^n)
- 维护rehashidx计数器(初始为0)
- 每次CRUD操作时迁移ht[0][rehashidx]的键值对
- 全部迁移完成后用ht[1]替换ht[0]
-
优化特性:
- 单次迁移一个桶(链表)
- 期间查询会同时查两个表
- 定时任务辅助迁移
Redis 跳跃表(Skip List)工作原理
-
结构特点:
- 多层有序链表(默认最大32层)
- 每个节点包含:
- 成员对象(ele)
- 分值(score)
- 后退指针(BW)
- 层数组(level[]包含前进指针和跨度)
-
查找过程:
- 从最高层开始遍历
- 当前节点分值 < 目标分值 → 继续前进
- 当前节点分值 ≥ 目标分值 → 下降一层
- 时间复杂度:O(logN)
-
插入流程:
- 随机确定节点层数(幂次定律)
- 逐层更新前后节点指针
- 更新跨度信息
Redis 过期键删除策略
-
惰性删除:
- 触发时机:访问键时检查过期时间
- 优点:CPU友好
- 缺点:内存不及时释放
-
定期删除:
- 工作流程:
- 随机抽取20个键检查
- 删除其中已过期的键
- 如果超过25%键过期则重复过程
- 配置参数:
hz 10 # 每秒执行次数
- 工作流程:
-
内存淘汰触发删除:
- 当内存不足时,按策略淘汰键
- 相关配置:
maxmemory-policy volatile-lru
相关文章:
Redis常见面试问题汇总
Redis 面试笔记整理 一、Redis 基础知识1. Redis 概述Redis 是什么?主要特点有哪些?Redis 和 Memcached 的区别是什么?Redis 是单线程还是多线程?为什么单线程还能高效?Redis 6.0 之后的多线程模型是怎样的?…...
网络安全中的“后门”:概念、类型、作用与攻防技术
目录 什么是后门? 后门的常见类型 2.1 按植入方式分类 2.2 按功能分类 后门在安全测试中的作用 后门的玩法与免杀技术 4.1 常见后门技术 4.2 如何实现免杀(Bypass AV) 如何检测和防御后门? 总结 1. 什么是后门ÿ…...
AIGC1——AIGC技术原理与模型演进:从GAN到多模态融合的突破
引言 近年来,人工智能生成内容(AIGC)技术迅速发展,从早期的简单文本生成到如今能够创作高质量图像、视频甚至3D内容,其核心驱动力在于生成模型的持续优化与多模态融合技术的突破。本文将探讨生成对抗网络(…...
Python爬虫-爬取大麦网演出详情页面数据
前言 本文是该专栏的第50篇,后面会持续分享python爬虫干货知识,记得关注。 本文,笔者以大麦网平台为例。基于Python,实现获取演出详情页面的演出信息。 废话不多说,具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内…...
opencv图像处理之指纹验证
一、简介 在当今数字化时代,生物识别技术作为一种安全、便捷的身份验证方式,正广泛应用于各个领域。指纹识别作为生物识别技术中的佼佼者,因其独特性和稳定性,成为了众多应用场景的首选。今天,我们就来深入探讨如何利…...
玛卡巴卡的k8s知识点问答题(五)
17. Init 类型容器有什么特点,主要用途? 特点: 启动顺序:Init 容器在普通容器启动之前运行,必须先完成所有 Init 容器后,Pod 的主容器才会启动。 顺序执行:如果定义了多个 Init 容器ÿ…...
怎样提升大语言模型(LLM)回答准确率
怎样提升大语言模型(LLM)回答准确率 目录 怎样提升大语言模型(LLM)回答准确率激励与规范类知识关联类情感与语境类逆向思维类:为什么不,反面案例群体智慧类明确指令类示例引导类思维引导类约束限制类反馈交互类:对话激励与规范类 给予奖励暗示:在提示词中暗示模型如果回…...
CSP-J2022 山东 题解
[CSP-J2022 山东] 植树节 题目背景 受疫情影响,山东省取消了 CSP-J 2022 认证活动,并于次年三月重新命题,在省内补办比赛。 题目描述 植树节快要到了,学校要组织志愿者去给树苗浇水。 有一排树苗,编号依次是 0 ,…...
strcpy和strncpy和strcat和strncat和strstr和strtok函数使用及实现
目录 strcpy和strncpy函数的原理及实现 strcpy函数 my_strcpy优化代码 函数返回值的疑惑 strncpy函数 strncpy自定义 完整代码 字符串追加函数 strcat和strncat strcat函数 讲解和使用 过程解析 strcat代码 strcat无法给自己追加 strncat函数 讲解和使用 过程解…...
前端开发使用若依的优势
若依(RuoYi)前端框架是基于主流技术栈(如Vue.js或React)构建的企业级前端解决方案,其优势主要体现在以下几个方面: 1. 开箱即用的企业级功能 权限管理:集成动态路由、按钮级权限控制(RBAC模型),适配后台权限系统,无需重复开发。多标签页:支持类似浏览器的多标签页操…...
网络空间安全(44)Web实战篇
一、Web应用程序安全防护 输入验证 严格验证用户输入:对所有用户输入的数据进行合法性检查,防止恶意用户通过输入恶意数据攻击应用程序。验证应包括对表单数据、URL参数、Cookie等进行检查,确保输入的数据符合预期格式和范围。使用安全的编码…...
python列表常用方法大全
列表(List)是 Python 中最常用的数据结构之一,它是一个有序、可变的集合,可以存储任意类型的元素。以下是列表的定义及常见用法,包括拼接、增加数据、插入数据、删除数据、计算差值、相加、清空等操作,与字…...
Warm-Flow过去、现在和未来都不会有商业版
Warm-Flow过去、现在和未来都不会有商业版 Warm-Flow从24年2月加入Dromara开源社区,也正是由于加入他,Warm-Flow才等到更多人的关注和帮助。 同时吸引了不少贡献者,有的也成为了Warm-Flow的成员。 因此为了回馈大家,也是为了War…...
3. 实战(一):Spring AI Trae ,助力开发微信小程序
1、前言 前面介绍了Spring boot快速集成Spring AI实现简单的Chat聊天模式。今天立马来实战一番,通过Trae这个火爆全网的工具,来写一个微信小程序。照理说,我们只是极少量的编码应该就可以完成这项工作。开撸~ 2、需求描述 微信小程序实现一…...
3.23周赛补题
感觉还要多练,有的题思路不难,但是赛时就没思路。 A const int N110,M1e410; int dp[N][M]; void solve(){int n,m;cin>>n>>m;vector<int>a(n1);forr(i,1,n){cin>>a[i];}dp[0][0]1;//没钱 没菜 就是一种情况forr(i,1,n){refor…...
libpng-1.6.47-windows编译
本文操作按照《c&c开源库编译指南》中内容规范编写,编译环境配置、工具下载、目录规划,及更多其他开源库编译方法请参考该文章。 c&c开源库编译指南:https://blog.csdn.net/binary0006/article/details/144086155 本文章中的源代码已…...
RabbitMQ高级特性--重试特性
目录 1.重试配置 2.配置交换机&队列 3.发送消息 4.消费消息 5. 运行程序观察结果 6. 手动确认 注意: 在消息传递过程中, 可能会遇到各种问题, 如网络故障, 服务不可用, 资源不足等, 这些问题可能导致消息处理失败. 为了解决这些问题, RabbitMQ 提供了重试机制, …...
热门索尼S-Log3电影感氛围旅拍LUTS调色预设 Christian Mate Grab - Sony S-Log3 Cinematic LUTs
热门索尼S-Log3电影感氛围旅拍LUTS调色预设 Christian Mate Grab – Sony S-Log3 Cinematic LUTs 我们最好的 Film Look S-Log3 LUT 的集合,适用于索尼无反光镜相机。无论您是在户外、室内、风景还是旅行电影中拍摄,这些 LUT 都经过优化,可为…...
基础认证-单选题(一)
单选题 1、下列关于request方法和requestlnStream方法说法错误的是(C) A 都支持取消订阅响应事件 B 都支持订阅HTTP响应头事件 C 都支持HttpResponse返回值类型 D 都支持传入URL地址和相关配置项 2、如需修改Text组件文本的透明度可通过以下哪个属性方法进行修改 (C) A dec…...
C++ 变量类型
C 变量类型 在C编程语言中,变量是存储数据的基本单元。变量类型决定了变量的存储方式和所占内存大小。了解C中的变量类型对于编写高效、可维护的代码至关重要。本文将详细介绍C中的各种变量类型,包括基本类型、复合类型和用户定义类型。 基本类型 C提…...
智能粉尘监测解决方案|守护工业安全,杜绝爆炸隐患
在厂房轰鸣的生产线上,一粒微小粉尘的聚集可能成为一场灾难的导火索。如何实现粉尘浓度的精准监控与快速响应?我们为您打造了一套"感知-预警-处置"全闭环的智能安全方案! 行业痛点:粉尘管理的生死线 在金属加工、化工…...
美观快速的react 的admin框架
系统特色: - 🎨 精心设计的UI主题系统,提供优雅的配色方案和视觉体验 - 📦 丰富完整的组件库,包含大量开箱即用的高质量组件 - 🔨 详尽的组件使用示例,降低开发者的学习成本 - 🚀…...
CentOS 7 挂载与卸载文件系统笔记
挂载文件系统 挂载的基本概念 挂载是将存储设备(如硬盘分区、U 盘、光盘等)连接到 Linux 文件系统的特定目录(挂载点),使得系统能够访问存储设备上的数据。 查看已挂载的文件系统 命令:mount 或 df -h mo…...
UE5学习笔记 FPS游戏制作28 显式玩家子弹数
文章目录 添加变量修改ShootOnce方法,设计时减少子弹,没有子弹不能开枪在UI上显示 添加变量 在Gun类中添加BulletNum和ClipSize两个参数 BulletNum是当前还有多少子弹,ClipSize是一个弹匣多少子弹 Rifle的ClipSzie设置为30,Laun…...
VRRP交换机三层架构综合实验
题目要求: 1,内网Ip地址使用172.16.0.0/16分配 说明可以划分多个子网,图中有2个VLAN,可以根据VLAN划分 2,sw1和SW2之间互为备份 互为备份通常通过VRRP(虚拟路由冗余协议)来实现。VRRP会在两个…...
QSettings用法实战(相机配置文件的写入和读取)
很多情况,在做项目开发的时候,将参数独立出来是比较好的方法 例如:相机的曝光次数、曝光时长等参数,独立成ini文件,用户可以在外面修改即可生效,无需在动代码重新编译等工作 QSettings便可以实现该功能 内…...
洛谷题单1-P1001 A+B Problem-python-流程图重构
题目描述 输入两个整数 a,b,输出它们的和(∣a∣,∣b∣≤109)。 输入格式 两个以空格分开的整数。 输出格式 一个整数。 输入输出样例 输入 20 30输出 50方式-print class Solution:staticmethoddef oi_input():"""从…...
分布式系统
一、分布式系统概述 1.1 为什么需要分布式系统? 核心驱动力: 性能需求:单机性能受物理限制(CPU/内存/IO),分布式系统通过并行计算突破瓶颈可扩展性:水平扩展(增加节点&#x…...
前端开发学习路线完整指南
前端开发学习路线完整指南 前端开发是一个不断发展的领域,涉及多个技术栈。本文将为你提供一条系统的前端学习路线,帮助你从零基础到熟练掌握前端开发技能。 1. 前置知识 在学习前端之前,了解一些基础知识会对你的学习过程有很大帮助。 计…...
Sa-Token核心功能解剖二( Session会话、 持久层Redis扩展 、全局侦听器 、全局过滤器、多账号体系认证、单点登录)
文章目录 概要功能结构图5.Session会话6.持久层扩展7.全局侦听器8.全局过滤器9.多账号体系认证10.单点登录 概要 Sa-Token核心功能解剖(二),主要有: Session会话 —— 全端共享Session,单端独享Session,自定义Session,方便的存取…...
C++搜索
功能扩展说明: 图类封装:将图数据结构封装为类,提高代码复用性 最短路径查找:基于BFS实现未加权图的最短路径查找 路径重构:通过parent数组回溯构建完整路径 异常处理:当路径不存在时返回空向量 复杂度分析…...
NC,GFS、ICON 数据气象信息可视化--降雨量的实现
随着气象数据的快速发展和应用,气象信息的可视化成为了一项不可或缺的技术手段。它不仅能帮助气象专家快速解读数据,还能为公众提供直观的天气预报信息。今天,我们将从降雨量的可视化出发,带大家一起了解如何实现气象数据的可视化…...
Android SystemUI深度定制实战:QSPanel下拉状态栏动态日期显示全解析
一、需求背景与实现思路 在Android系统定制化开发中,SystemUI的下拉状态栏(Quick Settings Panel,QSPanel)是用户高频交互的核心模块。近期某产品需求提出:在下拉展开状态栏时,需在QSPanel的顶部区域动态显…...
Linux 部署 rocketmq centos7
mq部署方案 1、rocketmq 顺序消费记录 一个master ,一个 brocker ,多个group ,多个topic,采用集群消费模式。 注意 一个group 对应一个 topic。 生产者 和 消费者 可以有多个,但是 主题和分组 都是一对一的。这样保证…...
02_MySQL安装及配置
文章目录 一、下载二、安装及配置2.1、选择安装类型2.2、检查需要的依赖2.3、安装2.4、配置2.4.1、配置类型和网络2.4.2、配置账户和角色2.4.3、配置Windows服务2.4.4、让配置生效 2.5、验证是否安装成功 三、卸载3.1、运行MySQL安装工具3.2、卸载及清理3.3、卸载之后的检查工作…...
银行的压力测试如何进行?
为什么要进行压力风险测试? 压力风险测试的最终目的是测试银行在极度恶劣的市场环境中是否有足够的资本维持运转。 题主链接中的一级资本充足率(Tier 1 capital ratio) 亦即衡量标准,这个数字越大,表明银行资本约充裕,可以在停止…...
7、Linux C 进程通信
一、无名管道(pipe) 1. 函数介绍 #include <unistd.h> int pipe(int pfd[2]); 参数:pfd是一个包含两个整数的数组,pfd[0]为读描述符,pfd[1]为写描述符。 返回值:成功时返回0,失败时…...
Android Framework 层 Hook 技术详解
目录 Hook 技术概述 什么是 Hook 技术? Hook 技术的核心原理 Hook 技术的进化与创新 Hook 技术的魅力与局限 Android Framework 层结构 Framework 层在 Android 中的位置 Framework 层的核心组件 为什么 Framework 层适合 Hook? 常用 Hook 方法 方法替换:换个 “芯…...
java接口中 使用@RequestParam和@RequestPart区别
1. 介绍 这两个注解都是spring注解。 RequestParam通常用于获取请求参数,这些参数可以是URL中的查询参数,也可以是表单数据中的字段。而RequestPart则是用于处理多部分(multipart)请求中的部分,特别是当上传文件或处理…...
CentOS-7.0系统基础操作
配置ip地址 编辑网卡文件: vi etc/sysconfig/network-scripts/ifcfg-ens33 在网卡文件里参照如下设置: BOOTPROTO"static" IPADDR192.168.61.233 GATEWAY192.168.61.2 NETMASK255.255.255.0 ONBOOT"yes" 防火墙管理 开启防火墙&am…...
全星研发管理APQP软件系统:驱动汽车产品研发全周期,打造高效合规的质量管理引擎
全星研发管理APQP软件系统:驱动汽车产品研发全周期,打造高效合规的质量管理引擎 在汽车、电子、医疗器械等高度依赖质量管理的行业中,APQP(先期产品质量策划)作为国际通用的产品开发管理框架,是确保产品从…...
Maven 的下载与安装
背景 为什么要建立本地Maven ,idea 默认的maven 仓库是放在系统盘的,依赖每次都存在系统盘用就了C盘就爆炸了,所有我们可以在本地其他盘安装maven 建立仓库。 idea 默认的依赖拉取地址是maven 官网,我们建立本地仓库,…...
26考研——排序_插入排序(8)
408答疑 文章目录 二、插入排序基本概念插入排序方法直接插入排序算法描述示例性能分析 折半插入排序改进点算法步骤性能分析 希尔排序相关概念示例分析希尔排序的效率效率分析空间复杂度时间复杂度 九、参考资料鲍鱼科技课件26王道考研书 二、插入排序 基本概念 定义&#x…...
Mem0 Prompt优化
在使用mem0的时候,系统中自带的提取事件的Prompt, 效果很差,我们可以按照我们的需求修改 from datetime import datetime, timedeltacustom_fact_extraction_prompt f"""你是一位个人信息整理专家,专注于准确存…...
C++ STL常用算法之常用算术生成算法
常用算术生成算法 学习目标: 掌握常用的算术生成算法 注意: 算术生成算法属于小型算法,使用时包含的头文件为 #include <numeric> 算法简介: accumulate // 计算容器元素累计总和 fill // 向容器中添加元素 accumulate 功能描述: 计算区间内容器元素…...
Kubernetes Webhook必要知识点:原理、配置与实践
#作者:邓伟 文章目录 1. 什么是 Kubernetes Webhook?2. Webhook 的工作原理2.1 准入控制器(Admission Controller)2.2 Webhook 类型 3. Webhook 的配置3.1 Webhook 配置文件3.2 配置字段说明 4. Webhook 的开发与部署4.1 开发 We…...
IGS 转 STL 全攻略:迪威模型在线转码助力 3D 建模
在 3D 建模与制造业领域,不同文件格式之间的转换是经常面临的重要任务。IGS 和 STL 作为其中两种常用格式,前者凭借出色的曲面表达能力,在 CAD 领域广泛应用;后者凭借简单的三角网格结构,成为 3D 打印、快速成型的行业…...
【Bug】记录2025年遇到的Bug以及修复方案
--------------------------------------------------------分割线 2025.3.25-------------------------------------------------------windows环境下通过命令行终端(必须是命令行下,直接赋值传递,代码正常)的形式传递字符串时&a…...
Unity UGUI - 六大基础组件
目录 一、Canvas上 1. Canvas:复制渲染子UI控件 2. ✨Canvas Scaler✨:画布分辨率自适应 3. Graphics Raycaster:射线事件响应 4. ✨Rect Transform✨:UI位置锚点对齐 二、Event System上 5. Event System 6. Standalone …...
TCP网络编程与多进程并发实践
一、引言 在网络编程中,TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。而多进程并发则是一种提高服务器处理能力的有效手段,允许服务器同时处理多个客户端的请求。本文将详细介绍如何使用 TCP 协议进…...