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测试
- http://localhost:8080/api/user/sign
- POST
- (记得带上令牌哦)
- 然后查看Redis里是否在你当前日期签到了
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后端内容发布哦!