专栏集锦,大佬们可以收藏以备不时之需
Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html
Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html
Logback 详解专栏:https://blog.csdn.net/superdangbo/category_9271502.html
tensorflow专栏:https://blog.csdn.net/superdangbo/category_8691332.html
Redis专栏:https://blog.csdn.net/superdangbo/category_9950790.html
Spring Cloud实战:
Spring Cloud 实战 | 解密Feign底层原理,包含实战源码
Spring Cloud 实战 | 解密负载均衡Ribbon底层原理,包含实战源码
1024程序员节特辑文章:
1024程序员狂欢节特辑 | ELK+ 协同过滤算法构建个性化推荐引擎,智能实现“千人千面”
1024程序员节特辑 | 解密Spring Cloud Hystrix熔断提高系统的可用性和容错能力
1024程序员节特辑 | ELK+ 用户画像构建个性化推荐引擎,智能实现“千人千面”
1024程序员节特辑 | OKR VS KPI谁更合适?
1024程序员节特辑 | Spring Boot实战 之 MongoDB分片或复制集操作
Spring实战系列文章:
Spring实战 | Spring AOP核心秘笈之葵花宝典
Spring实战 | Spring IOC不能说的秘密?
国庆中秋特辑系列文章:
国庆中秋特辑(八)Spring Boot项目如何使用JPA
国庆中秋特辑(七)Java软件工程师常见20道编程面试题
国庆中秋特辑(六)大学生常见30道宝藏编程面试题
国庆中秋特辑(五)MySQL如何性能调优?下篇
国庆中秋特辑(四)MySQL如何性能调优?上篇
国庆中秋特辑(三)使用生成对抗网络(GAN)生成具有节日氛围的画作,深度学习框架 TensorFlow 和 Keras 来实现
国庆中秋特辑(二)浪漫祝福方式 使用生成对抗网络(GAN)生成具有节日氛围的画作
国庆中秋特辑(一)浪漫祝福方式 用循环神经网络(RNN)或长短时记忆网络(LSTM)生成祝福诗词
Redis 的有序集合(Sorted Set)是一个基于分数(score)排序的数据结构,它在 Redis 中非常重要,常用于实现排行榜、近似计数器等功能。
Redis 的有序集合(Sorted Set)是基于跳跃表(Skip List)实现的。跳跃表是一种高效的数据结构,其插入、删除和查找操作的平均时间复杂度都是 O(log n),相对于平衡树(如红黑树)的实现要简单很多。跳跃表的结构类似于链表,每个节点除了保存元素值外,还包含一个指针数组,分别指向对应层次的下一个节点。这种多级指针的设计,使得跳表可以跨越多个节点进行快速搜索,同时保证跳表结构的高效性和简洁性。
有序集合的底层数据结构由哈希(Hash)和跳跃表组成。在哈希中,存储了元素及其关联的评分(分数)。每个元素都有一个唯一的评分,用于确定其在跳跃表中的位置。当需要对有序集合进行操作时,Redis 首先通过哈希表找到元素及其评分,然后通过跳跃表进行相应的操作。
以下是 Redis 有序集合(Sorted Set)的一些核心操作及其对应的核心代码分析:
要使用 Spring Boot 和 Redis 实现排行榜功能,你可以遵循以下步骤:
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
dependencies>
# application.properties
spring.redis.host=localhost
spring.redis.port=6379
# application.yml
spring:
redis:
host: localhost
port: 6379
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
import java.io.Serializable;
public class RankingEntity implements Serializable {
private String userId;
private double score;
// 构造方法、getter 和 setter
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class RankingService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String RANKING_KEY = "ranking_list";
/**
* 添加分数
* @param userId 用户 ID
* @param score 分数
*/
public void addScore(String userId, double score) {
ValueOperations<String, RankingEntity> valueOperations = redisTemplate.opsForValue();
valueOperations.set(RANKING_KEY + ":" + userId, score, 60, TimeUnit.SECONDS);
}
/**
* 查询排名
* @return 排名列表
*/
public List<Object> getRankingList() {
List<Object> rankingList = redisTemplate.opsForList().range(RANKING_KEY, 0, -1);
return rankingList;
}
/**
* 查询用户排名
* @param userId 用户 ID
* @return 用户排名
*/
public Object getUserRanking(String userId) {
return redisTemplate.opsForValue().get(RANKING_KEY + ":" + userId);
}
* @param userId 用户 ID
*/
public void deleteUserScore(String userId) {
ValueOperations<String, RankingEntity> valueOperations = redisTemplate.opsForValue();
valueOperations.delete(RANKING_KEY + ":" + userId);
}
/**
* 更新用户分数
* @param userId 用户 ID
* @param score 新的分数
*/
public void updateUserScore(String userId, double score) {
ValueOperations<String, RankingEntity> valueOperations = redisTemplate.opsForValue();
valueOperations.set(RANKING_KEY + ":" + userId, score, 60, TimeUnit.SECONDS);
}
/**
* 获取用户排名列表的长度
* @return 用户排名列表的长度
*/
public long getUserRankingListSize() {
return redisTemplate.opsForList().size(RANKING_KEY);
}
/**
* 在用户排名列表中插入用户分数
* @param userId 用户 ID
* @param score 分数
* @param index 插入位置,0 表示插入到列表头部,负数表示插入到列表尾部
*/
public void insertUserScore(String userId, double score, long index) {
List<Object> rankingList = redisTemplate.opsForList().range(RANKING_KEY, 0, -1);
redisTemplate.opsForList().leftPush(RANKING_KEY, score, index);
}
/**
* 在用户排名列表中删除用户分数
* @param userId 用户 ID
* @param index 删除位置,0 表示删除第一个元素,1 表示删除第二个元素,依此类推
*/
public void deleteUserScore(String userId, long index) {
List<Object> rankingList = redisTemplate.opsForList().range(RANKING_KEY, 0, -1);
redisTemplate.opsForList().rightPop(RANKING_KEY, index);
}
/**
* 获取用户排名列表中的最后一个元素
* @return 用户排名列表中的最后一个元素
*/
public Object getLastUserScore() {
return redisTemplate.opsForList().rightPop(RANKING_KEY);
}
/**
* 获取用户排名列表中的第一个元素
* @return 用户排名列表中的第一个元素
*/
public Object getFirstUserScore() {
return redisTemplate.opsForList().leftPop(RANKING_KEY);
}
/**
* 在用户排名列表中添加元素
* @param score 添加的分数
*/
public void addUserScore(double score) {
redisTemplate.opsForList().rightPush(RANKING_KEY, score);
}
/**
* 在用户排名列表中删除元素
* @param index 删除位置,0 表示删除第一个元素,1 表示删除第二个元素,依此类推
*/
public void deleteUserScore(long index) {
redisTemplate.opsForList().rightPop(RANKING_KEY, index);
}
/**
* 获取用户排名列表
* @return 用户排名列表
*/
public List<Object> getUserRankingList() {
return redisTemplate.opsForList().range(RANKING_KEY, 0, -1);
}
/**
* 设置用户排名列表的长度
* @param length 用户排名列表的新长度
*/
public void setUserRankingListLength(long length) {
redisTemplate.opsForList().setSize(RANKING_KEY, length);
}
/**
* 获取用户排名
*
* @param userId 用户 ID
* @return 用户排名,如果用户不存在,返回 -1
*/
public int getUserRanking(String userId) {
List<Object> rankingList = getRankingList();
Object userScore = getUserRanking(userId);
if (userScore == null) {
return -1;
}
int rank = 0;
for (Object score : rankingList) {
if (score.equals(userScore)) {
break;
}
rank++;
}
return rank;
}
/**
* 获取用户排名列表中的指定位置的元素
*
* @param index 指定位置,从 0 开始
* @return 用户排名列表中的指定位置的元素
*/
public Object getUserRankingListElement(long index) {
return redisTemplate.opsForList().range(RANKING_KEY, 0, -1).get(index);
}
/**
* 获取用户排名列表中的用户分数
*
* @param userId 用户 ID
* @return 用户排名列表中的用户分数,如果用户不存在,返回 null
*/
public Object getUserRanking(String userId) {
ValueOperations<String, RankingEntity> valueOperations = redisTemplate.opsForValue();
return valueOperations.get(RANKING_KEY + ":" + userId);
}
/**
* 是否存在用户
*
* @param userId 用户 ID
* @return 是否存在用户
*/
public boolean existsUser(String userId) {
ValueOperations<String, RankingEntity> valueOperations = redisTemplate.opsForValue();
return valueOperations.hasKey(RANKING_KEY + ":" + userId);
}
/**
* 清除所有用户排名数据
*/
public void clearAllUserRankingData() {
redisTemplate.delete(RANKING_KEY);
}
}