【黑马点评学习笔记 | 实战篇 】| 10-用户签到+UV统计

Bug如山勤为径,代码似海苦作舟。友友们好,这里是苦瓜大王。今天学习的是黑马点评项目实战篇------用户签到+UV统计部分的学习。学完这一部分,主播会暂时将后面的高级篇和原理篇搁置,后面有时间了再学习。本节笔记如下,后续会一直更新黑马点评学习过程中的笔记、问题等,请多多支持哦!

文章目录

一、用户签到

  • 使用位图进行签到统计

1.BitMap基本命令

  • 示例
  • 11100111
  • u指转成无符号数,i指转为有符号数

2.实现签到功能

  • UserController
java 复制代码
/**  
 * 签到功能  
 */  
@PostMapping("/sign")  
public Result sign(){  
   return userService.sign();  
}
  • UserServiceImpl
java 复制代码
/**  
 * 签到功能  
 * @return  
 */  
public Result sign() {  
    // 1.获取当前登录用户  
    Long userId = UserHolder.getUser().getId();  
    // 2.获取日期  
    LocalDateTime now = LocalDateTime.now();  
    // 3.拼接key  
    String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));  
    String key = USER_SIGN_KEY + userId + keySuffix;  
    // 4.获取今天是本月的第几天  
    int dayOfMonth = now.getDayOfMonth();  
    // 5.写入Redis SETBIT key offset 1  
    stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);  
    return Result.ok();  
}

前端没有做这个功能,所以用ApiFox测试

3.统计连续签到

  • 实现签到统计
  • 用1做与运算,就能得到最后一个比特位
  • UserController
java 复制代码
/**  
 * 统计连续签到  
 */  
@GetMapping("/sign/count")  
public Result signCount(){  
    return userService.signCount();  
}
  • UserServiceImpl
java 复制代码
/**  
 * 统计连续签到  
 */  
public Result signCount() {  
    // 1.获取当前登录用户  
    Long userId = UserHolder.getUser().getId();  
    // 2.获取日期  
    LocalDateTime now = LocalDateTime.now();  
    // 3.拼接key  
    String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));  
    String key = USER_SIGN_KEY + userId + keySuffix;  
    // 4.获取今天是本月的第几天  
    int dayOfMonth = now.getDayOfMonth();  
    // 5.获取本月截止今天为止的所有的签到记录,返回的是一个十进制的数字 BITFIELD sign:5:202203 GET u14 0    List<Long> result = stringRedisTemplate.opsForValue().bitField(  
            key,  
            BitFieldSubCommands.create()  
                    .get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0)  
    );  
    if (result == null || result.isEmpty()) {  
        // 没有任何签到结果  
        return Result.ok(0);  
    }  
    Long num = result.get(0);  
    if (num == null || num == 0) {  
        return Result.ok(0);  
    }  
    // 6.循环遍历  
    int count = 0;  
    while (true) {  
        // 6.1.让这个数字与1做与运算,得到数字的最后一个bit位  // 判断这个bit位是否为0  
        if ((num & 1) == 0) {  
            // 如果为0,说明未签到,结束  
            break;  
        }else {  
            // 如果不为0,说明已签到,计数器+1  
            count++;  
        }  
        // 把数字右移一位,抛弃最后一个bit位,继续下一个bit位  
        num >>>= 1;  
    }  
    return Result.ok(count);  
}

二、UV统计

1.HyperLogLog的用法

  • 所以引入了HLL,不仅操作简单,而且占内存小
  • 而且HLL不会计算重复的数据

2.实现UV统计

  • 通过info memory查看当前redis占用内存,前后进行对比,我们会发生他的误差是在允许范围内,并且内存占用极小
java 复制代码
@Test  
void testHyperLogLog() {  
    // 准备数组,装用户数据  
    String[] users = new String[1000];  
    // 数组角标  
    int index = 0;  
    for (int i = 1; i <= 1000000; i++) {  
    // 赋值  
        users [index++] = "user_" + i;  
    // 每1000条发送一次  
        if (i % 1000 == 0) {  
            index = 0;  
            stringRedisTemplate.opsForHyperLogLog().add("hll1", users);  
    // 统计数量  
            Long size = stringRedisTemplate.opsForHyperLogLog().size("hll1");  
            System.out.println("size = " + size);  
        }  
    }  
}

以上就是黑马点评实战篇------用户签到+UV统计部分的学习笔记,仅供参考,多多支持!

主播对于黑马点评部分的学习会暂时告一段落,因为后面的部分对于校招找工作来说暂时有点深奥用不上,所以一般的路线不会再继续学下去了,但是主播后续一定会捡起来重新学习 。🌹🌹🌹
接下来我应该会找一个项目做做,同样也会在CSDN上持续更新,友友们可以先点赞关注,后续会有其他的Java后端内容发布哦!

相关推荐
_饭团1 小时前
C 语言内存函数全解析:从 memcpy 到 memcmp 的使用与模拟实现
c语言·开发语言·c++·学习·算法·面试·改行学it
别催小唐敲代码1 小时前
FastAPI 从零开始完整学习教程
学习·fastapi
24白菜头1 小时前
第十五届蓝桥杯C&C++大学B组
数据结构·c++·笔记·学习·算法·leetcode·蓝桥杯
Victor3562 小时前
MongoDB(54)分片的优缺点是什么?
后端
Victor3562 小时前
MongoDB(55)如何监控分片集群?
后端
Engineer邓祥浩2 小时前
JVM学习问题记录(1) IDEA2025设置JVM启动参数
jvm·学习
qcwl662 小时前
深入理解Linux进程与内存 学习笔记#3
linux·笔记·学习
-Springer-2 小时前
STM32 学习 —— 个人学习笔记10-1(I2C 通信协议及 MPU6050 简介 & 软件 I2C 读写 MPU6050)
笔记·stm32·学习
SuniaWang2 小时前
《Spring AI + 大模型全栈实战》学习手册系列·专题一:《RAG技术全景解析:从原理到架构设计》
java·javascript·人工智能·spring boot·后端·spring·架构