【Redis】BitMap数据类型与用户签到功能的实现

29 篇文章 2 订阅

目录

一、BitMap

1、概念

2、命令

1.SETBIT

2.GETBIT

3.BITCOUNT

4.BITFIELD

5.BITFIELD RO

6.BITOP

7.BITPOS

二、用户签到

1、思路

2、代码实现

三、当前时间的连续签到天数

1、思路

2、代码实现


一、BitMap

1、概念

Redis中通过String类型实现的一种数据类型,因此存储上限是512M,转换为bit则是2^32个比特位,每一位存储0或1

2、命令

1.SETBIT

向指定key的指定位置中存入0或1

2.GETBIT

获取指定key指定位置的值

3.BITCOUNT

计算指定key中值为1的bit位数量

4.BITFIELD

查询、修改、自增指定key指定位置的值

5.BITFIELD RO

获取指定key中的bit数组,以十进制形式返回

6.BITOP

将多个指定key的结果做位运算

7.BITPOS

查询 bit数组中指定范围内第一个0或1出现的位置

二、用户签到

1、思路

一个月最多有31天,而bitMap有31位,我们可以将当前签到用户的id与当前时间年份+月份作为key,以BitMap为数据结构进行存储用户该月是否签到每一位表示一天,0与1表示是否签到,当用户点击签到请求时,服务器获取当前的时间与当前签到用户的id,以id+当前年月时间作为key,将当前的日作为下标,在BitMap中指定下标位存储1,比如当前签到用户是张三id=1,则key= “sign:1:2020-01”作为key,今天是1月11,则将这个key的第11位的也就是10下标的值修改为1即可表示签到

2、代码实现

void test() {
        // 1.获取当前用户id
        Long userId = 1L;
        
        // 2.获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 2.1 获取年月
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        // 2.2 获取日
        int day = now.getDayOfMonth();
        
        // 3.存入redis
        // 3.1 构造key
        String key = "sign:" + userId + keySuffix;
        // 3.2 存入
        stringRedisTemplate.opsForValue().setBit(key,day - 1,true);
    }

三、当前时间的连续签到天数

1、思路

当前时间的连续签到天数一定是从现在开始往前数,直到遇到没有签到的那天则结束计算,我们只需要获取到当前用户当前时间对应的bitMap中的每一个比特位,然后从后往前数1当数到0时则停止,最后返回数量即可,我们可以通过BITFIELD RO命令以十进制形式获取到数据,然后按位与1后,如果结果是1则计算变量++后无符合右移1位继续按位与1,直到按位与1等于0时停止。

比如 5 他的二进制是101,从后往前计算他的1的连续个数,101先进行101&1 = 1则计数器+1为1,此时101>>>1  变为10,此时10&1 = 0结束循环计数器值为1,说明从后往前连续的1只有1个

2、代码实现

Integer test() {
        // 1.获取用户id
        Long userId = 1L;
        
        // 2.获取当前时间
        LocalDateTime now = LocalDateTime.now();
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        int day = now.getDayOfMonth();
        
        // 3.获取对应的签到数值
        String key = "sign:" + userId + keySuffix;
        List<Long> result = stringRedisTemplate.opsForValue().bitField(
                key, 
                BitFieldSubCommands.create()
                        .get(BitFieldSubCommands.BitFieldType.unsigned(day)).valueAt(0)
        );
        if (result == null || result.isEmpty()) {
            return null;
        }
        
        // 4.开始计数
        Long num = result.get(0);
        if (num == null || num == 0) return null;
        int count = 0;
        while (true) {
            if ((num & 1) == 1) {
                count++;
            } else {
                break;
            }
            
            num >>>= 1;
        }
        // 5.返回
        return count;
    }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在简历中介绍使用Redis中的bitmap结构实现签到功能时,可以按照以下步骤进行: 1. 简单介绍RedisBitmap:首先简单介绍Redis是一个内存数据存储系统,而BitmapRedis提供的一种数据类型,它可以用于存储一系列的二进制标记,非常适合于需要高效处理二进制标记的场景。 2. 说明签到功能需求:接下来简要说明签到功能的需求,例如需要记录用户在某个时间点是否签到,以及需要对签到情况进行统计和分析等。 3. 介绍Bitmap实现签到的方法:接着详细介绍如何使用Redis中的Bitmap结构来实现签到功能,包括创建Bitmap、更新用户签到状态、查询用户签到状态、统计签到人数等步骤,以及如何利用Bitmap进行高效的位运算和统计计算。 4. 突出技术优势和实现效果:在介绍的过程中可以突出Redis中的Bitmap结构相对于其他存储方式的优势,比如空间占用少、查询速度快等,并可以列举一些实际的实现效果,比如能够支持海量用户的高并发访问、能够满足秒级响应要求等。 5. 强调自己的经验和贡献:最后可以适当强调自己在该项目中的经验和贡献,例如设计并实现了高效的签到功能,优化了性能,提高了用户体验等。 一个简短的例子: 使用Redis中的bitmap结构,实现了一个高效的签到功能。通过创建一个bitmap,每个用户对应bitmap中的一位,当用户签到时,将该位设为1,查询用户是否签到时,只需要查询该位是否为1,可以快速完成操作。在统计签到人数时,只需要对整个bitmap进行位运算即可。该方法占用空间较小,查询速度较快,能够支持海量用户的高并发访问,同时也满足秒级响应要求。我在该项目中设计并实现了高效的签到功能,并优化了性能,提高了用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1886i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值