面试题答案
一键面试实现思路
- 存储数据:使用Redis的有序集合(Sorted Set)来存储用户及其分数。有序集合的成员(member)是用户标识,分值(score)是用户的分数。
- 切换排序:为了实现升序和降序切换,需要考虑两种情况:
- 升序(ASC):直接使用有序集合按照分值从小到大的默认排序特性。
- 降序(DESC):由于Redis没有直接反转有序集合排序的命令,一种解决方案是在需要降序时,对每个分数取反(例如,原分数为
score
,将其存储为-score
),这样升序获取时实际就是原分数的降序排列。
- 获取排名靠前的用户:根据当前的排序方式,使用相应的命令获取排名靠前的用户。
关键Redis命令
- ZADD:用于向有序集合中添加成员和分值。
- 语法:
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
- 示例:
ZADD user_scores 100 user1
- 语法:
- ZRANGE:按升序获取有序集合中指定范围的成员。
- 语法:
ZRANGE key start stop [WITHSCORES]
- 示例:获取升序排名前10的用户:
ZRANGE user_scores 0 9 WITHSCORES
- 语法:
- 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
参数决定是升序还是降序获取,并在降序时对分数恢复原值。