首先我们要理清朋友圈点赞具体需要涉及哪几个功能点:
- 存储点赞信息:需要存储哪些用户点赞了这条朋友圈,具体需要存储用户ID、点赞时间即可。
- 取消点赞:需要快速找到这名用户,将其移除点赞列表,
- 获取点赞列表:朋友圈需要展示点赞的用户头像列表信息
核心就是这么三点,其实就是增删查,那用什么来实现比较合适呢?
实现快速存储和删除,Set 就挺合适,而且还能天然去重,但是常见的 HashSet 是无序的,朋友圈的点赞列表需要按时间顺序排序。
而 TreeSet 理论上可以支持这些功能,顺序按点赞时间排序,所以在内存中利用 TreeSet 来保存朋友圈数据。
但是数据保存在 Java 内存中不合理,因为应用重启一下不就没了?
同样是内存,我们可以联想到 Redis ,将数据存放到 Redis 里即可,Redis 也支持 aof 和 rbd 持久化.
并且 Redis 恰巧有个 zset 结构,可以满足我们的需求。
zset 的 key 可以设置此条朋友圈的 id,score 为点赞时间,value 为点赞用户 ID。如果用户点赞,则将用户 id 和当前时间添加到 zset 中,时间复杂度为O(logN),N 为排序集合内总元素数
如果用户取消点赞,则从 zset 中移除此用户,时间复杂度为 O(logN*M),N 为排序集合内总元素数,M 删除的元素数.查看朋友圈点赞列表,调用 zset的 zrange key 0 -1即可,底层存储用的是跳表,时间复杂度为0(logN+M),N 为排序集合内总元素数,M 为返回的元素数。