MST

星途 面试题库

面试题:Redis中如何在ASC和DESC选项间动态切换排序策略

在Redis中,假设你有一个有序集合,存储了用户的分数。现在要求根据用户的某种操作,动态地在升序(ASC)和降序(DESC)之间切换排序并获取排名靠前的用户。请描述实现这一功能的思路,并给出关键的Redis命令及代码示例(语言不限)。
40.5万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 存储数据:使用Redis的有序集合(Sorted Set)来存储用户及其分数。有序集合的成员(member)是用户标识,分值(score)是用户的分数。
  2. 切换排序:为了实现升序和降序切换,需要考虑两种情况:
    • 升序(ASC):直接使用有序集合按照分值从小到大的默认排序特性。
    • 降序(DESC):由于Redis没有直接反转有序集合排序的命令,一种解决方案是在需要降序时,对每个分数取反(例如,原分数为score,将其存储为-score),这样升序获取时实际就是原分数的降序排列。
  3. 获取排名靠前的用户:根据当前的排序方式,使用相应的命令获取排名靠前的用户。

关键Redis命令

  1. ZADD:用于向有序集合中添加成员和分值。
    • 语法:ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
    • 示例:ZADD user_scores 100 user1
  2. ZRANGE:按升序获取有序集合中指定范围的成员。
    • 语法:ZRANGE key start stop [WITHSCORES]
    • 示例:获取升序排名前10的用户:ZRANGE user_scores 0 9 WITHSCORES
  3. ZREVRANGE:按降序获取有序集合中指定范围的成员。
    • 语法:ZREVRANGE key start stop [WITHSCORES]
    • 示例:获取降序排名前10的用户:ZREVRANGE user_scores 0 9 WITHSCORES

代码示例(Python + Redis - redis - py库)

import redis

# 连接Redis
r = redis.Redis(host='localhost', port=6379, db = 0)

def add_user_score(user, score, is_desc=False):
    if is_desc:
        score = -score
    r.zadd('user_scores', {user: score})

def get_top_users(num, is_desc=False):
    if is_desc:
        result = r.zrevrange('user_scores', 0, num - 1, withscores=True)
        return [(user, -score) for user, score in result]
    else:
        return r.zrange('user_scores', 0, num - 1, withscores=True)


# 示例使用
add_user_score('user1', 100)
add_user_score('user2', 120)
add_user_score('user3', 80)

print("升序排名前2的用户:", get_top_users(2, False))
print("降序排名前2的用户:", get_top_users(2, True))

在上述Python代码中:

  • add_user_score函数用于向有序集合中添加用户及其分数,如果是降序模式,对分数取反后存储。
  • get_top_users函数用于获取排名靠前的用户,根据is_desc参数决定是升序还是降序获取,并在降序时对分数恢复原值。