面试题答案
一键面试数据结构设计
- 商品数据存储:
- 使用Redis的Hash数据结构来存储每个商品的详细信息。例如,对于商品ID为
product:1
,可以这样存储:
HSET product:1 id 1 HSET product:1 name "商品名称" HSET product:1 sales 100 HSET product:1 positive_rate 0.95 HSET product:1 shelf_time 1677638400 # 时间戳,假设为上架时间
- 使用Redis的Hash数据结构来存储每个商品的详细信息。例如,对于商品ID为
- 有序集合设计:
- 创建一个有序集合,例如命名为
product_rank
,来存储商品的综合排名。 - 有序集合的成员(member)为商品ID,分值(score)为综合排名得分。计算综合排名得分时,需要根据销量、好评率、上架时间等多个维度进行加权计算。假设销量权重为
w1
,好评率权重为w2
,上架时间权重为w3
,则综合得分score
的计算公式可以是:
score = w1 * sales + w2 * positive_rate + w3 * (1 / (current_time - shelf_time + 1))
- 这里
current_time
是当前时间戳,(1 / (current_time - shelf_time + 1))
的设计是为了让上架时间越近的商品得分越高,加1是为了避免分母为0的情况。
- 创建一个有序集合,例如命名为
更新策略
- 销量更新:
- 当商品销量发生变化时,首先更新商品Hash中的销量字段。例如,商品ID为
product:1
销量增加10:
HINCRBY product:1 sales 10
- 然后重新计算综合得分并更新有序集合中的分值。假设已经计算出新的综合得分
new_score
:
ZADD product_rank new_score product:1
- 当商品销量发生变化时,首先更新商品Hash中的销量字段。例如,商品ID为
- 好评率更新:
- 好评率发生变化时,同样先更新商品Hash中的好评率字段。例如,商品ID为
product:1
好评率更新为0.96:
HSET product:1 positive_rate 0.96
- 接着重新计算综合得分并更新有序集合中的分值:
ZADD product_rank new_score product:1
- 好评率发生变化时,同样先更新商品Hash中的好评率字段。例如,商品ID为
- 上架时间更新(极少发生,如重新上架):
- 更新商品Hash中的上架时间字段,例如商品ID为
product:1
重新上架,设置新的上架时间new_shelf_time
:
HSET product:1 shelf_time new_shelf_time
- 重新计算综合得分并更新有序集合中的分值:
ZADD product_rank new_score product:1
- 更新商品Hash中的上架时间字段,例如商品ID为
查询逻辑
- 获取排名靠前的商品:
- 使用
ZRANGE
命令获取排名靠前的商品。例如,获取排名前10的商品:
ZRANGE product_rank 0 9 WITHSCORES
- 该命令返回有序集合中排名从0(最小分值)到9(共10个元素)的商品ID及其对应的综合得分。
- 使用
- 获取某个商品的排名:
- 使用
ZRANK
命令获取某个商品的排名。例如,获取商品ID为product:1
的排名:
ZRANK product_rank product:1
- 如果返回结果为
nil
,表示该商品不在有序集合中;否则返回该商品的排名(从0开始)。
- 使用
- 分页查询:
- 假设每页显示
page_size
个商品,要查询第page_num
页的商品,可以使用ZRANGE
命令结合偏移量计算。偏移量offset = (page_num - 1) * page_size
,例如:
ZRANGE product_rank offset (offset + page_size - 1) WITHSCORES
- 这样可以获取第
page_num
页的商品及其综合得分。
- 假设每页显示