一口气讲完了Redis常用的数据结构及应用场景

Redis数据结构详解及不同场景应用指南 Redis是一个开源的、基于内存的键值存储系统,支持持久化到磁盘。它以其高性能、丰富的数据结构和灵活的扩展性而闻名。Redis的常见用途包括缓存、会话存储、消息队列、实时分析等。Redis的丰富数据结构使其成为解决多种问题的强大工具。通过合理选择数据结构,可以显著提高应用的性能和可扩展性。字符串:缓存、计数器。哈希:存储对象数据。列表:消息队列、最新消息列表。集合:标签系统、去重数据存储。有序集合:排行榜、优先级队列。 阅读详情

一、概述

Redis是互联网技术领域使用最为广泛的存储中间件,它是Remote Dictionary Service(远程字典服务)的首字母缩写,Redis以其超高的性能、活跃的社区、详细的文档以及丰富的客户端库支持在开源中间件领域广受好评,国内外很多大型互联网都在使用Redis,比如:Twitter、Github、新浪微博、阿里巴巴、京东、Stack Overflow等,可以说,深入了解Redis应用和实践,已成为如今中高级后端加法绕不开的必备技能。

二、Redis常见应用场景

三、Redis有哪些数据结构

3.1 String字符串

🔥字符串典型的使用场景:

  • 单值缓存

  • 对象缓存

  • 计数器

  • 分布式锁

单值缓存

127.0.0.1:6379> setnum 1
OK
127.0.0.1:6379> getnum
"1"
127.0.0.1:6379>

单值缓存

SETuser:1value(json格式数据)

计数器

文章阅读量、点赞量、评论量

127.0.0.1:6379> incrarticle:read:id1
(integer) 1
127.0.0.1:6379> incrarticle:read:id1
(integer) 2
127.0.0.1:6379> incrarticle:up:id1
(integer) 1
127.0.0.1:6379> incrarticle:up:id2
(integer) 1
127.0.0.1:6379> incrarticle:comment:id1
(integer) 1
127.0.0.1:6379> incrarticle:comment:id1
(integer) 2
127.0.0.1:6379>

分布式锁

  • setnx

定时任务防止同一时刻重复执行,可以在业务执行代码前使用分布式锁控制。

127.0.0.1:6379> setnxjobGlobalNotifyJob
(integer) 1
127.0.0.1:6379> getjob
"GlobalNotifyJob"
127.0.0.1:6379> ttljob
(integer) -1
127.0.0.1:6379>

伪代码如下:

@Slf4j
@ComponentpublicclassGlobalNotifyJob{

    privatestaticfinal String LOCK_KEY = "redis_notify_lock";

    /**
     * 每小时执行一次
     */@Scheduled(cron = "0 0 0/1 * * ?")
    publicvoidnotify(){
        if (!lockService.grabLock(LOCK_KEY)) {
            log.info("[GlobalNotifyJob] 没有拿到锁, 停止操作......");
            return;
        }
        // 拿到锁,开始执行业务...
    }
}
  • setex + 过期时间【SETNX KEY_NAME TIMEOUT VALUE】

127.0.0.1:6379> setexkey1 60 value1OK
127.0.0.1:6379> ttlkey1
(integer) 53
127.0.0.1:6379> getkey1
"value1"
127.0.0.1:6379>

hash哈希

🔥哈希典型应用场景:

  • 缓存对象信息(帖子标题、摘要、作者信息)

  • 记录帖子的点赞数、评论数和点击数

  • 电商购物车

命令

描述

HSET key field value

存储一个哈希表key的键值

HSETNX key field value

存储一个不存储的哈希表key的键值

HMSET key field value [field value...]

在一个哈希表key中存储多个键值对

HGET key field value

获取哈希表key对应的field键值

HMGET key field value

批量获取哈希表key中多个field键值

HDEL key field [field ...]

删除哈希表key中多个field的键值

HLEN key

返回哈希表key中field的数量

HGETALL key

返回哈希表key中所有的键值

127.0.0.1:6379> hmsetuser:1nameaustinage 25 addressguangzhoubalance 6888
OK
127.0.0.1:6379> hgetuser:1name
"austin"
127.0.0.1:6379> hgetuser:1balance
"6888"
127.0.0.1:6379> hmgetuser:1ageaddress
1) "25"
2) "guangzhou"
127.0.0.1:6379> hlenuser:1
(integer) 4
127.0.0.1:6379> hgetalluser:1
1) "name"
2) "austin"
3) "age"
4) "25"
5) "address"
6) "guangzhou"
7) "balance"
8) "6888"
127.0.0.1:6379>

list列表

🔥列表的典型应用场景:

  • 文章列表

  • 微博和微信公众号消息

Stack(栈FILO) = LPUSH + LPOP 
Queue(队列FIFO)= LPUSH + RPOP 
Blocking MQ(阻塞队列)= LPUSH + BRPOP

LPUSH  key  value [value ...]       // 将一个或多个值value插入到key列表的表头(最左边)
RPUSH  key  value [value ...]       // 将一个或多个值value插入到key列表的表尾(最右边)
LPOP  key                   // 移除并返回key列表的头元素
RPOP  key                   // 移除并返回key列表的尾元素
LRANGE  key  start  stop        // 返回列表key中指定区间内的元素,区间以偏移量start和stop指定
LINSERT key  BEFORE|AFTER pivot element // 在元素element前后插入pivot
LREM key count element                  //根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素 count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 
BLPOP  key  [key ...]  timeout          //从key列表表头弹出一个元素,若列表中没有元素,阻塞等待 timeout秒,如果timeout=0,一直阻塞等待
BRPOP  key  [key ...]  timeout          //从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待 timeout秒,如果timeout=0,一直阻塞等待

set集合

🔥列表的典型应用场景:

  • 抽奖

  • 微博点赞,收藏,标签

  • 共同好友

抽奖场景:

  1. 用户参与抽奖

# 将用户10001加入商品a的参与池子中
SADD luckdraw:product:a 10001
  1. 查看参与商品a抽奖的所有用户

SMEMBERSluckdraw:product:a
  1. 抽取1名幸运中奖者

SPOPluckdraw:product:a 1

共同好友场景:

用户1的好友为:3,4,8

用户2的好友为:4,5,11

取交集,获取用户1和用户2的共同好友,为用户4。

127.0.0.1:6379> sadduser_1 2 3 4
(integer) 3
127.0.0.1:6379> sadduser_2 4 5 7
(integer) 3
127.0.0.1:6379> sinteruser_1user_2
1) "4"
127.0.0.1:6379>

sorted set有序集合

🔥列表的典型应用场景:

  • 微博热搜榜

  • 刷礼物实时排行榜

  • 博客社区本周热议

Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double类型的分数,Redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数score却可以重复。下面使用redis-cli实践Redis有序集合命令:

zset几个基本命令:

命令

说明

zrange key start stop [WITHSCORES]

将集合元素依照顺序值升序排序再输出,start和stop限制遍历的限制范围

zincrby key increment member

有序集key的成员member的score值加上增量increment

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]]

计算给定的一个或多个有序集的并集,其中给定key的数量必须以numkeys参数指定,并将该并集 (结果集) 储存到destination

127.0.0.1:6379[3]> zaddzsetofpost 89 post:1
(integer) 1
127.0.0.1:6379[3]> zaddzsetofpost 123 post:2
(integer) 1
127.0.0.1:6379[3]> zaddzsetofpost 32 post:3
(integer) 1
127.0.0.1:6379[3]> zaddzsetofpost 432 post:4
(integer) 1
127.0.0.1:6379[3]> zaddzsetofpost 128 post:5
(integer) 1

#升序排序
127.0.0.1:6379[3]> zrangezsetofpost 0 -1withscores
 1) "post:3"
 2) "32"
 3) "post:1"
 4) "89"
 5) "post:2"
 6) "123"
 7) "post:5"
 8) "128"
 9) "post:4"
10) "432"

#降序排序
127.0.0.1:6379[3]> zrevrangezsetofpost 0 -1withscores
 1) "post:4"
 2) "432"
 3) "post:5"
 4) "128"
 5) "post:2"
 6) "123"
 7) "post:1"
 8) "89"
 9) "post:3"
10) "32"

#有序集合某个元素的score值加上对应的增量
127.0.0.1:6379[3]> zincrbyzsetofpost 40 post:1
"129"
127.0.0.1:6379[3]> zincrbyzsetofpost 500 post:3
"532"
127.0.0.1:6379[3]> zrangezsetofpost 0 -1withscores
 1) "post:2"
 2) "123"
 3) "post:5"
 4) "128"
 5) "post:1"
 6) "129"
 7) "post:4"
 8) "432"
 9) "post:3"
10) "532"

简单认识了Redis有序集合和对应的命令之后,我们来实现本周热议排行榜功能,博客的本周热议主要的实现思路是:

  1. 库获取最近 7 天的所有文章(或者加多一个条件:评论数量大于 0)。

  1. 把文章的评论数量作为有序集合的分数score,文章的ID作为key存储到zset中,当有人发表评论的时候,直接使用命令加一,并重新计算得到排行榜。

  1. 本周热议上有标题和评论数量,因此,我们还需要把文章的基本信息存储到Redis中,这样得到文章的ID之后,我们再从缓存中得到标题等信息,这里我们可以使用hash的结构来存储文章的信息。

  1. 因为是本周热议,如果文章发表超过 7 天了之后就会失效,所以我们可以给文章的有序集合一个有效时间。超过 7 天之后就自动删除缓存。

画图分析:

最终实现效果:

Bitmaps位图

🔥位图的典型应用场景:

  • 用户连续签到功能
    很多社区、博客平台其实都有每日签到模块,一开始看到这个模块需求的时候,很多人第一反应是利用MySQL来实现,创建一个签到表,记录用户ID和签到时间,然后统计的时候从数据库中取出来然后聚合计算,这样设计其实存在弊端,如我们想要做一些复杂的功能就不是太方便了,或者说不是太高性能了,比如,今天是连续签到的第几天,在一定时间内连续签到了多少天。另外一方面,如果按 100 万用户量级来计算,一个用户每年可以产生 365 条记录,100 万用户的所有签到记录那就有点恐怖了,查询计算速度也会越来越慢。其实Redis的Bitmaps位图操作非常适合处理每日签到功能场景,因为Bit的值为0或者1,位图的每一位代表一天的签到,1表示已签,0表示未签。 考虑到每月初需要重置连续签到次数,最简单的方式是按用户每月存一条签到数据(也可以每年存一条数据)。Key的格式为u:sign:uid:yyyyMM,Value则采用长度为4个字节(32位)的位图(最大月份只有31天)。

Redis位图命令基本命令

命令

说明

SETBIT key offset value

对key所储存的字符串值,设置或清除指定偏移量上的位(bit)

BITPOS key bit [start] [end]

查询指定字节区间第一个被设置成1的bit位的位置

GETBIT key offset

查询指定偏移位置的bit值

BITCOUNT key [start end]

统计指定字节区间bit为1的数量

GETBIT key offset

查询指定偏移位置的bit值

BITFIELD key offset

查询指定偏移位置的bit值

这里的offset,大家姑且当做用户ID来看就可以了,那么究竟如何去实现用户打卡功能呢,我们可以利用上面的setbit命令来实现,setbit的作用说的直白就是:在你想要的位置操作字节值,比如说u:sign:1000:202302表示ID=1000的用户在2023年2月7号签到记录。

# 用户1000在2023年2月7号签到
SETBITu:sign:1000:202302 6 1 # 偏移量是从0开始,所以要把7减1

# 检查用户1000在2023年2月7号是否签到
GETBITu:sign:1000:202302 6   # 偏移量是从0开始,所以要把7减1

# 统计用户1000在2月份签到次数
BITCOUNTu:sign:1000:202302

# 获取2月份前28天的签到数据
BITFIELDu:sign:1000:202302getu28 0

# 获取2月份首次签到日期
BITPOSu:sign:1000:202302 1  # 返回的首次签到的偏移量,加上1即为当月的某一天

示例代码:

/**
 * 基于Redis位图的用户签到功能工具实现类
 *
 * @author: austin
 * @since: 2023/2/7 1:50
 */publicclassUserSignKit{

    private Jedis jedis = new Jedis();

    /**
     * 用户签到
     *
     * @param uid  用户ID
     * @param date 日期
     * @return 之前的签到状态
     */publicbooleandoSign(int uid, LocalDate date){
        int offset = date.getDayOfMonth() - 1;
        return jedis.setbit(buildSignKey(uid, date), offset, true);
    }

    /**
     * 检查用户是否签到
     *
     * @param uid  用户ID
     * @param date 日期
     * @return 当前的签到状态
     */publicbooleancheckSign(int uid, LocalDate date){
        int offset = date.getDayOfMonth() - 1;
        return jedis.getbit(buildSignKey(uid, date), offset);
    }

    /**
     * 获取用户签到次数
     *
     * @param uid  用户ID
     * @param date 日期
     * @return 当前的签到次数
     */publiclonggetSignCount(int uid, LocalDate date){
        return jedis.bitcount(buildSignKey(uid, date));
    }

    /**
     * 获取当月连续签到次数
     *
     * @param uid  用户ID
     * @param date 日期
     * @return 当月连续签到次数
     */publiclonggetContinuousSignCount(int uid, LocalDate date){
        int signCount = 0;
        String type = String.format("u%d", date.getDayOfMonth());
        List<Long> list = jedis.bitfield(buildSignKey(uid, date), "GET", type, "0");
        if (list != null && list.size() > 0) {
            // 取低位连续不为0的个数即为连续签到次数,需考虑当天尚未签到的情况long v = list.get(0) == null ? 0 : list.get(0);
            for (int i = 0; i < date.getDayOfMonth(); i++) {
                if (v >> 1 << 1 == v) {
                    // 低位为0且非当天说明连续签到中断了if (i > 0) {
                        break;
                    }
                } else {
                    signCount += 1;
                }
                v >>= 1;
            }
        }
        return signCount;
    }

    /**
     * 获取当月首次签到日期
     *
     * @param uid  用户ID
     * @param date 日期
     * @return 首次签到日期
     */public LocalDate getFirstSignDate(int uid, LocalDate date){
        long pos = jedis.bitpos(buildSignKey(uid, date), true);
        return pos < 0 ? null : date.withDayOfMonth((int) (pos + 1));
    }

    /**
     * 获取当月签到情况
     *
     * @param uid  用户ID
     * @param date 日期
     * @return Key为签到日期,Value为签到状态的Map
     */public Map<String, Boolean> getSignInfo(int uid, LocalDate date){
        Map<String, Boolean> signMap = new HashMap<>(date.getDayOfMonth());
        String type = String.format("u%d", date.lengthOfMonth());
        List<Long> list = jedis.bitfield(buildSignKey(uid, date), "GET", type, "0");
        if (list != null && list.size() > 0) {
            // 由低位到高位,为0表示未签,为1表示已签long v = list.get(0) == null ? 0 : list.get(0);
            for (int i = date.lengthOfMonth(); i > 0; i--) {
                LocalDate d = date.withDayOfMonth(i);
                signMap.put(formatDate(d, "yyyy-MM-dd"), v >> 1 << 1 != v);
                v >>= 1;
            }
        }
        return signMap;
    }

    privatestatic String formatDate(LocalDate date){
        return formatDate(date, "yyyyMM");
    }

    privatestatic String formatDate(LocalDate date, String pattern){
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }

    privatestatic String buildSignKey(int uid, LocalDate date){
        return String.format("u:sign:%d:%s", uid, formatDate(date));
    }

    publicstaticvoidmain(String[] args){
        UserSignKit kit = new UserSignKit();
        LocalDate today = LocalDate.now();

        {   // doSignboolean signed = kit.doSign(1000, today);
            if (signed) {
                System.out.println("您已签到:" + formatDate(today, "yyyy-MM-dd"));
            } else {
                System.out.println("签到完成:" + formatDate(today, "yyyy-MM-dd"));
            }
        }

        {   // checkSignboolean signed = kit.checkSign(1000, today);
            if (signed) {
                System.out.println("您已签到:" + formatDate(today, "yyyy-MM-dd"));
            } else {
                System.out.println("尚未签到:" + formatDate(today, "yyyy-MM-dd"));
            }
        }

        {   // getSignCountlong count = kit.getSignCount(1000, today);
            System.out.println("本月签到次数:" + count);
        }

        {   // getContinuousSignCountlong count = kit.getContinuousSignCount(1000, today);
            System.out.println("连续签到次数:" + count);
        }

        {   // getFirstSignDate
            LocalDate date = kit.getFirstSignDate(1000, today);
            System.out.println("本月首次签到:" + formatDate(date, "yyyy-MM-dd"));
        }

        {   // getSignInfo
            System.out.println("当月签到情况:");
            Map<String, Boolean> signInfo = new TreeMap<>(kit.getSignInfo(1000, today));
            for (Map.Entry<String, Boolean> entry : signInfo.entrySet()) {
                System.out.println(entry.getKey() + ": " + (entry.getValue() ? "√" : "-"));
            }
        }
    }
}

运行结果:

您已签到:2023-02-07
您已签到:2023-02-07
本月签到次数:5
连续签到次数:3
本月首次签到:2023-02-02
当月签到情况:
2023-02-01: -
2023-02-02: √
2023-02-03: √
2023-02-04: √
2023-02-05: -
2023-02-06: √
2023-02-07: √
2023-02-08: -
2023-02-09: -
2023-02-10: -
2023-02-11: -
2023-02-12: -
2023-02-13: -
2023-02-14: -
2023-02-15: -
2023-02-16: -
2023-02-17: -
2023-02-18: -
2023-02-19: -
2023-02-20: -
2023-02-21: -
2023-02-22: -
2023-02-23: -
2023-02-24: -
2023-02-25: -
2023-02-26: -
2023-02-27: -
2023-02-28: -

Redis发布订阅

Redis提供了发布订阅功能,可以用于消息的传输,Redis的发布订阅机制包括三个部分:发布者、订阅者和Channel。发布者和订阅者都是Redis客户端,Channel则为Redis服务器端,发布者将消息发送到某个的频道,订阅了这个频道的订阅者就能接收到这条消息。Redis的这种发布订阅机制与基于主题的发布订阅类似,Channel相当于主题。

总结

本文详细介绍了Redis的五种数据结构和应用场景,希望可以帮助大家解决实际工作中遇到的问题

OpenCV中SGBM中BT代价计算 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar 阅读详情

相关推荐

手把手教你用Verilog在FPGA上驱动0.96寸OLED(I2C协议,含完整代码和字库)

本文详细介绍了如何使用Verilog在FPGA上通过I2C协议驱动0.96寸OLED显示屏,包含完整的硬件连接指南、I2C协议解析、Verilog代码实现及字库设计。从初始化序列到字符显示引擎,提供可立即上手的解决方案,适合嵌入式系统开发者快速实现OLED显示功能。

weixin_29655587的博客 328

Redis常用的数据结构及实际应用场景

本文介绍了Redis中常用的数据结构,包括字符串、列表、集合、哈希表、有序集合和Bitmap,并结合实际案例详细说明了它们在各种场景下的使用。

小薯条的博客 3079

逆向实战:我是如何一步步解开美团外卖App的mtgsig3.0签名(附关键代码片段)

本文详细记录了逆向分析美团外卖App的mtgsig3.0签名算法的全过程,从抓包到算法还原,包括Java层和Native层的深度分析。通过Frida、IDA Pro等工具,揭示了签名生成的多层加密流程,并提供了关键代码片段。文章还探讨了逆向工程中的反调试对抗和签名时效性问题,为安全研究人员提供了宝贵的技术参考。

weixin_42530732的博客 877

redis专题:redis的常用数据结构及使用场景

文章目录一. redis常用五大数据结构①:string && 使用场景②:hash && 其使用场景③:list && 使用场景④:set && 使用场景⑤:zset && 使用场景 一. redis常用五大数据结构         redis中存储数据是以key-value的形式去存储的,其中key为String字符串类型,value的数据类型

qq_1149513559的博客 1万+

麒麟KylinV10系统yum源更换全攻略:从官方源到第三方仓库的保姆级教程

本文详细介绍了麒麟KylinV10系统yum源的更换与优化方法,包括官方源配置、第三方仓库集成及RPM包管理技巧。通过实战案例和命令示例,帮助用户快速解决软件依赖问题,提升系统管理效率。特别适合需要在国产操作系统上进行开发的工程师参考。

weixin_30752699的博客 649

量化回测框架三选一:Backtrader、Zipline、PyAlgoTrade,新手到底该跟谁学?

本文对比分析了三大量化回测框架Backtrader、Zipline和PyAlgoTrade,帮助新手选择最适合的入门工具。从安装配置、策略编写到文档查阅,详细解析各框架的特点和适用场景,为量化交易初学者提供实用指南。

weixin_28745309的博客 268

redis基础应用场景

一、简介 Redis 是开源免费, key-value 内存数据库,主要解决高并发、大数据场景下,热点数据访问的性能问题,提供高性能的数据快速访问。项目中部分数据访问比较频繁,对下游 DB(例如 MySQL)造成服务压力,这时候可以使用缓存来提高效率。 Redis 的主要特点包括: Redis数据存储在内存中,可以提高热点数据的访问效率 Redis 除了支持 key-value 类型的数据,同时还支持其他多种数据结构的存储; Redis 支持数据持久化存储,可以将数据存储在磁盘中,机器重启数据将从磁盘重新

云端做梦 326

数字IC后端实战:如何用ICC搞定复杂模块的floorplan与powerplan(附避坑指南)

本文深入解析数字IC后端设计中复杂模块的floorplan与powerplan实战技巧,重点介绍多边形模块边界处理、MTCMOS电源网络优化及存储器摆放陷阱规避。通过Synopsys ICC工具的具体操作示例和项目实战经验,帮助工程师高效解决设计难题,提升芯片性能与可靠性。

weixin_29213525的博客 353

精通Redis2、Redis底层数据结构分析(一)

一.String 底层数据结构 Sds (Simple Dynamic String,简单动态字符串)是 Redis 底层所使用的字符串表示,它被用 在几乎所有的 Redis 模块中。 Sds 在 Redis 中的主要作用有以下两个: 实现字符串对象(StringObject); 在 Redis 程序内部用作 char* 类型的替代品; 1.1sds 优点 在 C 语言中,字符串可以用一个 \0 结尾的 char 数组来表示。 比如说, hello world 在 C 语言中就可以表示为 “hello

keep_learn的专栏 550

6.14华为OD机试真题 新系统 - 字符串格式调整 (Java/Py/C/C++/Js/Go)

# **字符串格式调整** > 2026 华为OD机试真题 6月14日华为OD上机新系统考试真题 100 分题型 点击查看华为 OD 机试真题完整目录:[2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解](https://blog.youkuaiyun.com/banxia_frontend/article/details/160346662) # 题目描述 输入一个字符串,字符串中只包含大写字母和数字。要求将字符串中的所有数字提取出来,按出现的顺序组

算法大师! 951

CAPL编程规范与最佳实践

通过本文的学习,读者应该对CAPL编程规范与最佳实践有了初步的了解,并能够编写高质量的CAPL脚本。在实际项目中,CAPL的应用非常广泛,希望读者能够通过不断的学习和实践,掌握更多的CAPL技巧,提高自己的开发能力。

闲人编程的博客 1748

Redis知识点整理(一)——Redis数据结构

《Redis设计与实现》读书笔记 Redis是一个以C语言编写的Key-Value类型数据库,数据库状态保存在内存中,主要用于mysql或oracle sql等重型数据库的缓存,以支持高性能、高并发的应用场景。 1、Redis的底层实现 1.1、整数集合 整数集合(intset)可以用于保存int16_t、int32_t、int64_t的无重复元素的整数值。每个intset结构包含了三个属性,属性encoding指明整数集合中整数值的类型,属性length指明集合中包含的元素数量,而contents[]是存

上海大猫集团 585

YOLOv11改进策略【小目标改进】| 添加专用于小目标的检测层 附YOLOv1~YOLOv11的检测头变化详解

在目标检测领域,小目标检测一直是一个具有挑战性的问题。算法以其高效快速的特点受到广泛关注,然而在面对小目标时,仍存在一些局限性。本文将介绍如何在中添加小目标检测层,以提高对小目标的检测能力。原始模型结构如下:详细内容参考:YOLOv11原始模型结构介绍 二、有效特征层对应的检测头类别 2.1 P3/8 - small检测头 原始模型中的对应的检测头主要用于检测相对较小的目标。其特征图大小相对较大,空间分辨率较高。 适合检测尺寸大概在到像素左右的目标。 2.2 P4/16 - medium检测头 这个检

Limiiiing的博客 8804

4 分布式缓存Redis6常见数据结构+指令实战—小滴课堂学习笔记

第四章 分布式缓存Redis6常见数据结构+指令实战(点击标题观看全篇视频讲解) 第1集 Redis6常见数据结构概览 简介:Redis6常见数据结构概览 数据结构多种多样,方便大家记忆,使用脑图的形式 中文文档:http://www.redis.cn/ 整个脑图,等讲完全部内容后会在资料里面加 第2集 Redis6数据结构之String类型介绍和应用场景 简介:Redis6...

xdclass888的博客 103

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

必备redis6教程-分布式缓存Redis6.X+高可用集群课程介绍-小滴课堂

第四章 分布式缓存Redis6常见数据结构+指令实战 第1集 Redis6常见数据结构概览 简介:Redis6常见数据结构概览 数据结构多种多样,方便大家记忆,使用脑图的形式 中文文档:http://www.redis.cn/ 整个脑图,等讲完全部内容后会在资料里面加 第2集 Redis6数据结构之String类型介绍和应用场景 简介:Redis6数据结构之String类型介绍和应用场景 数据结构介绍: 应用场景:验证码、计数器、订单重复提交、用...

XDCLASS21的博客 302

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

ios11修改微信步数_【Redis面试题】如何使用Redis实现微信步数排行榜?

1. 前言之前写过一篇博客,讲解的是Redis的5种数据结构及其常用命令,当时有读者评论,说希望了解下这5种数据结构各自的使用场景,不过一直也没来得及写。碰巧,在3月份找工作面试时,有个面试官先问了我Redis有哪几种数据结构,在我讲完后,面试官又问了我以下问题:如何用Redis实现微信步数排行榜?相信很多小伙伴都知道,可以使用 Redis 的有序集合 ZSET 来实现,本篇博客就基于此面试题,来...

weixin_39897687的博客 197

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

面试官问我知道的分布式事务,我一口气说了六种

阿里面试官没想到我真的全都会...

敖丙 4万+

【Redis】概述与安装配置

Redis 的配置文件通常位于,里面包含了大量参数可供调整。类别内容关键词基础概念键值对存储、内存数据库数据结构字符串、哈希、列表、集合、有序集合安装部署包管理器、源码编译、Docker配置管理配置文件路径、重要参数说明运维维护启动停止、日志查看、性能调优好了各位小伙伴,今天的课程到这里就结束啦!希望大家通过对 Redis 初步的认识和实际操作,能够建立起对其强大功能的基本印象。记住,纸上得来终觉浅,绝知此事要躬行。赶紧去试试看能不能把它玩转起来吧!下次见咯~👋。

silverclayz的技术分享 963

图文 红黑树,B树,B+树 本质区别及应用场景

小史是一个应届生,虽然学的是电子专业,但是自己业余时间看了很多互联网与编程方面的书,一心想进 BAT 互联网公司。 话说两个多月前,小史通过了 A 厂的一面,两个多月后的今天,小史终于等到了 A 厂的二面。 在简单的自我介绍后,面试官看了看小史的简历,开始发问了。 面试现场 小史:没问题,这个项目前端用的 React+Webpack,后端用的 Nginx+Spr...

Linias的博客 1万+

SpringBoot2.x整合Redis实战应用场景(1)

SpringBoot2.x整合Redis实战应用场景(1) 概述 redis相信你看到我这一篇文章和demo之前,相信你对Redis也有大概的认识了,所以本demo以本文代码基于SpringBoot2.0整合Redis自定义注入模板操作Bean组件。 废话不多说,下面我们开始编写相关demo案例。 一 导入相关依赖 <dependency> ...

以梦为马,不负韶华 786

【Redis核心原理和应用实践】Redis 可以用来做什么可以用来做什么

Redis 的业务应用范围非常广泛,让我们以掘金技术社区(juejin.im)的帖子模块为实例,梳理一下,Redis 可以用在哪些地方? 记录帖子的点赞数、评论数和点击数 (hash)。 记录用户的帖子 ID 列表 (排序),便于快速显示用户的帖子列表 (zset)。 记录帖子的标题、摘要、作者和封面信息,用于列表页展示 (hash)。 记录帖子的点赞用户 ID 列表,评论 I...

通往神秘的道路的专栏 183

【Redis 初阶】 从分布式演进背景到环境搭建全解析

做后端开发的朋友,没人能绕开 Redis。面试里它是八股重灾区,工作中它是性能救命稻草。但很多人上手就背命令、记数据结构,却很少停下来想:我们到底为什么需要 Redis?它在整个分布式架构里,处于什么位置?本文顺着技术发展的逻辑,从单机架构的演进讲起,带你理解 Redis 诞生的技术背景,拆解它的核心特性与适用场景,再一步步完成 Linux 环境的搭建与验证。全文兼顾原理与实战,既是入门指南,也能帮你梳理面试高频考点。

会当凌绝顶,一览众山小 2344

使用Redis实现微信步数排行榜功能

前言 之前写过一篇博客,讲解的是Redis的5种数据结构及其常用命令,当时有读者评论,说希望了解下这5种数据结构各自的使用场景,不过一直也没来得及写。 碰巧,在3月份找工作面试时,有个面试官先问了我Redis有哪几种数据结构,在我讲完后,面试官又问了我以下问题: 如何用Redis实现微信步数排行榜? 相信很多小伙伴都知道,可以使用Redis的有序集合ZSET来实现,本篇博客就基于此面试题,来讲解下ZSET的使用场景,以及微信步数排行榜的大致实现思路。 ZSET的使用场景 ZSET的经典使用场景是用来.

615
上一篇: 学习Nginx,跟着阿里大牛走,一套精心整理的Nginx
下一篇: 阿里人在Github分享的Spring Cloud全栈笔记,你想象不到有多全
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值