面试题答案
一键面试设计思路
- 锁机制:使用分布式锁(如Redisson的分布式锁)来保证操作的原子性。在对Sorted Set进行任何操作前,先获取锁,操作完成后释放锁。这样可以避免多个并发请求同时修改Sorted Set导致的数据竞争问题。
- 操作顺序优化:
- 添加成员:直接使用Redis的
ZADD
命令。 - 更新成员分数:因为更新成员分数等同于先删除旧分数的成员,再以新分数添加成员,所以可以直接使用
ZADD
命令,ZADD
命令在成员已存在时会更新其分数。 - 删除成员:使用Redis的
ZREM
命令。
- 添加成员:直接使用Redis的
伪代码示例
以下以Java和Redisson为例展示伪代码:
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import redis.clients.jedis.Jedis;
public class SortedSetOperations {
private static final String LOCK_KEY = "sorted_set_lock";
private RedissonClient redissonClient;
private Jedis jedis;
public SortedSetOperations() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
redissonClient = Redisson.create(config);
jedis = new Jedis("127.0.0.1", 6379);
}
public void addMember(String key, double score, String member) {
RLock lock = redissonClient.getLock(LOCK_KEY);
try {
lock.lock();
jedis.zadd(key, score, member);
} finally {
lock.unlock();
}
}
public void updateScore(String key, double newScore, String member) {
RLock lock = redissonClient.getLock(LOCK_KEY);
try {
lock.lock();
jedis.zadd(key, newScore, member);
} finally {
lock.unlock();
}
}
public void removeMember(String key, String member) {
RLock lock = redissonClient.getLock(LOCK_KEY);
try {
lock.lock();
jedis.zrem(key, member);
} finally {
lock.unlock();
}
}
}
在上述代码中:
addMember
方法用于添加成员到Sorted Set,先获取锁,然后使用ZADD
命令添加成员,最后释放锁。updateScore
方法用于更新成员分数,同样先获取锁,再使用ZADD
命令更新分数(若成员存在则更新分数,不存在则添加),最后释放锁。removeMember
方法用于删除成员,获取锁后使用ZREM
命令删除成员,最后释放锁。
这样通过锁机制和优化的操作顺序,在高并发环境下保证了对Redis Sorted Set操作的原子性和数据一致性。