首页 > 基础资料 博客日记
电商类面试问题--02针对商品排行榜,你是怎么实现的
2023-09-04 21:11:56基础资料围观223次
Java资料网推荐电商类面试问题--02针对商品排行榜,你是怎么实现的这篇文章给大家,欢迎收藏Java资料网享受知识的乐趣
02-针对商品排行榜,你是怎么实现的
背景描述
当时产品提出了每日热销排行榜在零点进行变更的需求。在我接到这个需求后,我立即想到了使用Redis的有序集合(ZSET)来实现这个功能,并与我们的技术负责人进行了沟通。
经过与技术负责人的讨论和确认,我们一致认为使用有序集合是一个可行的解决方案。因此,我进行了技术评审,并得到了批准开始实施该方案。
在实现过程中,我使用了Redis的有序集合数据结构来存储和排序商品销量信息。具体而言,我将日期作为有序集合的key,商品ID作为成员(member),销售数量作为分值(score)。每当有订单数据更新时,我通过调用ZINCRBY
命令来增加对应商品的销售数量。这样,在每天零点之前,所有的订单数据会被累积到有序集合中。
至于定时更新排行榜数据的功能,我采用了Spring Boot提供的定时任务注解(@Scheduled
)来指定每天零点执行更新操作。在定时任务中,我首先删除前一天的排行榜数据,然后根据最新的订单数据重新生成排行榜。
代码实现
// 记录订单数据
public void recordOrderData(String date, String productId, int quantity) {
// 更新有序集合中对应商品的销售数量
redisTemplate.opsForZSet().incrementScore("daily_ranking_" + date, productId, quantity);
}
// 查询每日商品销量排行榜
public List<String> getDailyRanking(String date, int topN) {
// 获取分值最高的成员,即销量最高的商品ID
Set<String> members = redisTemplate.opsForZSet().reverseRange("daily_ranking_" + date, 0, topN - 1);
return new ArrayList<>(members);
}
// 定时任务更新排行榜数据(程序员fly)
@Scheduled(cron = "0 0 0 * * ?") // 每天零点执行
public void updateDailyRanking() {
String date = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 昨天的日期
String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 今天的日期
// 清除前一天的排行榜数据
redisTemplate.delete("daily_ranking_" + date);
// 根据最新的订单数据重新生成排行榜(程序员fly)
// 假设从数据库或缓存中获取当日的订单数据,并根据订单数据更新有序集合的分值
List<Order> orders = orderService.getOrdersByDate(today);
for (Order order : orders) {
String productId = order.getProductId();
int quantity = order.getQuantity();
recordOrderData(today, productId, quantity);
}
}
上述代码示例中,在实现每日热销排行榜的功能时,使用了Redis有序集合来存储和排序商品销量信息。对应的方法包括:
recordOrderData
:用于记录订单数据,并通过调用incrementScore
命令更新对应日期的有序集合中商品的销售数量。getDailyRanking
:查询每日商品销量排行榜,并通过调用reverseRange
命令获取分值最高的成员(即销量最高的商品ID)。updateDailyRanking
:定时任务,在每天零点执行。其中,清除前一天的排行榜数据后,根据最新的订单数据重新生成排行榜。
扩展点
- 分布式锁:在多个节点同时执行定时任务时,使用分布式锁来避免并发访问的问题。可以使用Redis的分布式锁机制(如RedLock),通过加锁和解锁操作来控制并发访问,防止重复记录或更新排行榜。
- 性能优化:如果每天的订单数据量较大,可以考虑对数据进行批量处理,减少与Redis的交互次数。例如,可以在一次操作中记录多个订单数据,或者使用Redis的pipeline技术进行批量操作。另外,根据实际情况设置合理的分页查询或限制每次更新的数量,以平衡性能和及时性
本文由博客一文多发平台 OpenWrite 发布!
文章来源:https://www.cnblogs.com/JavaFly1/p/17678105.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
上一篇:学习Markdown
下一篇:关于前后端交互,取header的尴尬