news 2026/7/22 8:27:35

【面试情景剧】大厂面试官灵魂拷问:电商秒杀系统扛不住?谢飞机被问到「回家等通知」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【面试情景剧】大厂面试官灵魂拷问:电商秒杀系统扛不住?谢飞机被问到「回家等通知」

【面试情景剧】大厂面试官灵魂拷问:电商秒杀系统扛不住?谢飞机被问到「回家等通知」

业务场景:电商秒杀
技术栈:Spring Boot + Redis + Kafka + MySQL + Redisson分布式锁
人物:面试官(严肃专业)、谢飞机(搞笑水货程序员)


🎬 开场

面试官端坐在会议室里,面前摆着一杯已经凉了的美式咖啡。门被推开,谢飞机穿着一件印有「BUG FREE」的T恤大步走进来,胸前还别着一个工牌——上面写着「谢飞机 · 全栈(全站在旁边看)」。

面试官:(面无表情)请坐。看你简历上写做过电商项目,今天我们就围绕秒杀系统来聊聊。

谢飞机:(自信满满地坐下)面试官您好!秒杀我太熟了,不就是「限时打折」嘛,我双十一秒过三箱牛奶、两袋狗粮、还有一台……算了不说了。

面试官:……我说的是技术层面的秒杀系统。

谢飞机:哦哦,技术啊,那我也熟,我天天被秒杀——被需求秒杀。


🎯 第一轮:基础与业务衔接

问题1:请你描述一下秒杀系统的核心业务流程。

谢飞机:(来了精神)这个简单!用户点「抢购」按钮 → 后端检查库存 → 库存够就扣减 → 生成订单 → 完事儿!跟我去超市抢鸡蛋一个流程。

面试官:(微微点头)基本流程没问题。那你想想,如果10万人同时抢1000台手机,你这个流程能扛住吗?

谢飞机:(愣了一秒)呃……扛不住的话,就多叫几个超市……不是,多开几台服务器?

面试官:(叹了口气)方向是对的,但远远不够。我们继续。

问题2:秒杀场景下,库存扣减为什么不能直接操作MySQL?

谢飞机:(挠头)因为……MySQL太慢了?就像……你让一个老大爷去数10万个人的入场券,他数到一半人就都冲进来了。

面试官:(居然笑了)比喻倒是挺形象。没错,MySQL在高并发下会成为瓶颈。那你觉得应该用什么?

谢飞机:(抢答)Redis!Redis在内存里跑,快!就跟把老大爷换成高铁检票口一样!

面试官:(点头)不错,这个知识点答对了。Redis基于内存操作,单机QPS可以达到10万级别,是处理高并发库存扣减的首选。那我们继续深入。

问题3:用Redis扣减库存,你怎么保证不超卖?

谢飞机:(自信)这个我会!用Redis的DECR命令啊,它是原子操作,一次只能减1,不会超卖!就像……就像自动售货机,投一个币出一瓶水,不会多给你。

面试官:(挑眉)DECR确实是原子操作,基本思路是对的。那我问你,如果你的秒杀系统是分布式部署的,多台服务器同时执行DECR,还能保证不超卖吗?

谢飞机:(笑容逐渐凝固)呃……多台服务器……那它们不是都连着同一个Redis吗?应该……还是可以的吧?

面试官:(严肃)DECR本身是原子的,多个客户端并发执行确实不会超卖,这一点你说对了。但问题在于,仅仅DECR不够——你还需要保证「检查库存」和「扣减库存」这两步操作的原子性。如果分开执行,在检查和扣减之间,库存可能已经被别人扣了。这就是典型的竞态条件问题。

谢飞机:(恍然大悟状)哦!所以就像两个人同时看到最后一瓶水,都伸手去拿……

面试官:对,所以我们需要更严谨的方案。后面会考你。

问题4:秒杀请求到达后端之前,前端可以做哪些优化?

谢飞机:(来劲了)前端!这个我知道!按钮点一次就变灰,不让重复点!还有……还有……(冥思苦想)

面试官:还有呢?

谢飞机:还有……让页面好看一点?让用户忘了自己在抢东西?

面试官:(扶额)前端优化远不止这些。常见的包括:按钮防重复点击倒计时前不展示抢购按钮请求排队/验证码削峰CDN静态化页面减少服务器压力、本地缓存秒杀令牌等。你回去整理一下。

谢飞机:(疯狂记笔记)好的好的,面试官说得对……


🔥 第二轮:进阶与原理探究

问题5:你说用Redis预扣库存,那Redis和MySQL之间的数据一致性怎么保证?

谢飞机:(开始含糊)这个……就是……Redis扣完了,然后……然后写个消息……不对,写个定时任务……把数据同步到MySQL?就像……就像你在备忘录上记了花了多少钱,晚上回家再记到账本上。

面试官:(追问)那如果Redis扣减成功了,但消息发送失败,或者同步到MySQL的时候失败了,怎么办?

谢飞机:(眼神开始飘忽)那就……重试?或者……人工对账?实在不行……让运维兄弟手动修一下数据?

面试官:(严肃)这在生产环境是不可接受的。正确的做法是:Redis预扣库存成功后,发送消息到Kafka,由消费者异步创建订单并扣减MySQL库存。如果消息发送失败,需要回滚Redis库存。同时,消费者端要做好幂等性处理,防止重复消费。这就是经典的最终一致性方案。

谢飞机:(小声)最终一致性……就是「最终会一致,但中间可能不一致」的意思吧?

面试官:理解没错,但实现起来要严谨得多。

问题6:Kafka在这个场景中起什么作用?为什么选Kafka而不是RabbitMQ?

谢飞机:(试图蒙混过关)Kafka嘛……就是……一个消息队列,用来……异步的?削峰的?至于为什么选Kafka不选RabbitMQ……因为Kafka名字短?

面试官:(面无表情)名字短?

谢飞机:(赶紧找补)不是不是!因为Kafka……它……吞吐量高?我看网上都这么说的!

面试官:吞吐量高是对的,但不够全面。秒杀场景选择Kafka的核心原因有三点:

  1. 超高吞吐量:Kafka单机写入TPS可达数十万,适合秒杀瞬间的流量洪峰;
  2. 消息持久化:Kafka将消息顺序写入磁盘,配合零拷贝(Zero-Copy)技术,持久化性能极高;
  3. 消费者组机制:支持多个消费者组并行消费,便于扩展。

而RabbitMQ的优势在于路由灵活消息可靠性更强延迟更低,适合对延迟敏感但吞吐量要求不那么极端的场景。

谢飞机:(崇拜脸)面试官,您是不是背过标准答案?

面试官:……这是基本功。

问题7:如果Kafka消费者创建订单时,发现MySQL库存不足了怎么办?

谢飞机:(思考了一下)那……就告诉用户抢失败了?把Redis里扣的库存加回去?

面试官:方向对,但具体怎么做?Redis库存已经扣了,MySQL库存不够,这个不一致怎么处理?

谢飞机:(开始冒汗)呃……可以……发一条补偿消息?或者……用那个……那个什么事务?

面试官:(严肃)这里涉及两个关键点:

  1. Redis预扣库存时要留buffer:比如实际1000台,Redis里只放1000个库存令牌,不会超发;
  2. 消费者端幂等+补偿:如果MySQL扣减失败(理论上不应该,因为Redis已经做了第一层拦截),需要发送补偿消息回滚Redis库存。

核心思路是:Redis做前置拦截,MySQL做最终兜底

问题8:分布式环境下,如何防止同一个用户重复下单?

谢飞机:(抢答)加锁!用那个……synchronized!

面试官:(摇头)synchronized只能在单JVM内生效,分布式环境下无效。

谢飞机:(慌了)那……用数据库唯一索引?同一个用户ID+秒杀活动ID建唯一索引?

面试官:(终于露出赞许的表情)这个答对了。数据库唯一索引是防重的最后一道防线。除此之外,还可以在Redis层用SETNX做分布式锁,用户点击抢购时先尝试获取锁,获取成功才能继续。但要注意锁的超时时间和释放机制。

谢飞机:(松口气)还好我蒙对了一个……


💀 第三轮:架构与极端场景

问题9:如果Redis主节点挂了,库存扣减正在进行中,怎么处理?

谢飞机:(彻底慌了)Redis挂了?那……重启?

面试官:(盯着他)重启需要多久?重启期间用户请求怎么办?正在扣减的库存数据丢不丢?

谢飞机:(开始胡言乱语)那个……Redis有……哨兵?对,哨兵模式!哨兵会自动……切换?然后……数据就……回来了?

面试官:(严肃)Redis Sentinel可以实现故障自动转移,但存在一个核心问题:异步复制可能导致数据丢失。主节点扣减了库存但还没同步到从节点就挂了,切换后新主节点的库存数据是不一致的。

谢飞机:(小声)那……用那个……RedLock?

面试官:RedLock是分布式锁的方案,不是解决数据同步的。对于库存数据,可以考虑:

  1. Redis AOF持久化:配置alwayseverysec策略,减少数据丢失窗口;
  2. 库存数据重建机制:从MySQL恢复Redis库存数据;
  3. 降级方案:Redis不可用时,直接降级为MySQL + 分布式锁方案,牺牲性能保证正确性。

问题10:秒杀系统如何做限流?如果流量超过系统承载能力怎么办?

谢飞机:(已经放弃治疗)限流……就是……限制流量?用那个……Nginx的limit_req

面试官:Nginx限流是一层,但不够。完整的限流方案应该是多层级的。

谢飞机:(试图挣扎)我知道!还有……Sentinel!阿里的Sentinel!可以……配置规则……

面试官:(点头)Sentinel确实是一个选择。完整的秒杀限流方案通常包括:

  1. 前端层:验证码、按钮防抖、请求排队;
  2. 网关层:Nginx限流(令牌桶/漏桶)、用户维度限流;
  3. 服务层:Sentinel熔断限流、接口级别流控;
  4. 库存层:Redis预置库存本身就是最天然的限流——库存没了,请求自然被拒绝。

谢飞机:(喃喃自语)原来库存就是最好的限流器……

问题11:秒杀结束后,大量未支付的订单占用库存,怎么处理?

谢飞机:(已经神志不清)让……让用户快点付款?发短信催他?

面试官:(无语)技术上怎么解决?

谢飞机:(开始胡说)那个……设个……超时时间?超时了就……取消订单?然后把库存……还回去?

面试官:思路是对的,但实现细节呢?怎么做到订单超时自动取消?轮询数据库吗?

谢飞机:(彻底摆烂)我……我用定时任务?每分钟扫一次数据库?

面试官:(叹气)定时任务扫表在订单量大时性能极差。常见方案有:

  1. 延迟队列:使用Kafka延迟消息或RabbitMQ的TTL+死信队列,订单创建时发送一条30分钟的延迟消息,到期后检查订单状态,未支付则取消并回滚库存;
  2. Redis过期监听:利用Redis的Key过期事件通知(但不可靠,不推荐用于核心业务);
  3. RocketMQ事务消息:支持延迟投递,更适合这种场景。

问题12:最后一个问题——如果让你从零设计一个支撑百万QPS的秒杀系统,你会怎么设计整体架构?

谢飞机:(沉默了10秒)……面试官,我能说「我会先辞职」吗?

面试官:(终于忍不住笑了)好吧,这个问题确实有难度。简单说一下思路:

百万QPS的秒杀系统,核心架构思路是**「流量漏斗」**:

用户请求(百万级) ↓ CDN + 前端静态化(拦截90%) ↓ 网关层限流 + 用户鉴权(拦截8%) ↓ Redis预扣库存(拦截1.9%) ↓ Kafka异步下单(仅成功请求进入) ↓ MySQL落库(最终一致性)

每一层尽可能拦截流量,让真正到达数据库的请求降到最低。同时配合服务降级、熔断、灰度发布等容灾手段。

谢飞机:(目瞪口呆)面试官,您这不是面试,这是上课啊……

面试官:(收起笑容,合上笔记本)好的,今天的面试就到这里。你的基础知识还有一些印象,但在深度和系统性上还有很大提升空间。

谢飞机:(紧张)那……我……

面试官回去等通知吧。

谢飞机:(站起来,小声嘀咕)等通知……等通知……我上辈子等了多少通知了……


📚 文末技术解析:小白也能看懂的秒杀系统全攻略

下面由「技术主笔」为大家详细解析面试中涉及的所有技术点和业务场景,确保小白读者也能学到干货!

一、秒杀系统核心业务流程

┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ │ 用户点击抢购 │ → │ 前端校验+限流 │ → │ Redis预扣库存 │ → │ 发送MQ消息 │ └─────────────┘ └──────────────┘ └─────────────┘ └──────────────┘ ↓ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ │ 返回抢购结果 │ ← │ 更新Redis状态 │ ← │ MySQL创建订单 │ ← │ 消费者异步处理 │ └─────────────┘ └──────────────┘ └─────────────┘ └──────────────┘

关键点

  • 秒杀的本质是**「在极高并发下保证数据一致性」**
  • 核心矛盾:瞬时高并发vs库存数据的准确性
  • 解决思路:层层拦截流量,让真正到达数据库的请求尽可能少

二、Redis预扣库存方案详解

2.1 为什么不用MySQL直接扣?
// ❌ 错误方案:直接操作MySQL // 高并发下,大量请求打到MySQL,导致数据库连接池耗尽、响应超时 @Transactional public void deductStock(Long goodsId) { // UPDATE stock SET count = count - 1 WHERE goods_id = #{goodsId} AND count > 0 // 问题:行锁竞争激烈,10万并发 = 10万个事务竞争同一行 }
2.2 正确的Redis预扣库存方案
// ✅ 正确方案:Redis Lua脚本保证原子性 // 将「检查库存」和「扣减库存」合并为一个原子操作 String luaScript = "local stock = tonumber(redis.call('get', KEYS[1])) " + "if (stock <= 0) then return -1 end " + // 库存不足 "if (redis.call('sismember', KEYS[2], ARGV[1]) == 1) then return -2 end " + // 重复抢购 "redis.call('decr', KEYS[1]) " + "redis.call('sadd', KEYS[2], ARGV[1]) " + "return 1"; // KEYS[1] = 库存key, KEYS[2] = 已购用户集合 // ARGV[1] = 用户ID Long result = redisTemplate.execute(luaScript, keys, userId); if (result == 1) { // 扣减成功,发送MQ消息 kafkaTemplate.send("seckill-order-topic", orderMessage); } else if (result == -1) { throw new BusinessException("库存不足"); } else if (result == -2) { throw new BusinessException("请勿重复抢购"); }

为什么用Lua脚本?

  • Redis执行Lua脚本是单线程原子操作,不会被其他命令插入
  • 避免了「先GET检查 → 再DECR扣减」之间的竞态条件
  • 一次网络往返完成所有操作,减少RTT延迟

三、Kafka异步削峰详解

3.1 为什么选Kafka?

| 特性 | Kafka | RabbitMQ | |------|-------|----------| | 单机吞吐量 | 数十万/秒 | 数万/秒 | | 消息持久化 | 顺序写磁盘+零拷贝 | 内存+磁盘 | | 延迟 | ms级别 | us级别 | | 适用场景 | 高吞吐、大数据量 | 低延迟、复杂路由 |

秒杀场景的核心需求是超高吞吐量,Kafka是更合适的选择。

3.2 生产者代码
@Service public class SeckillProducer { @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void sendSeckillMessage(SeckillOrderMessage message) { // 以用户ID作为key,保证同一用户的请求进入同一分区(顺序消费) kafkaTemplate.send( "seckill-order-topic", message.getUserId(), // partition key JSON.toJSONString(message) ).addCallback( result -> log.info("消息发送成功: {}", message.getUserId()), ex -> { log.error("消息发送失败: {}", ex.getMessage()); // 发送失败需要回滚Redis库存 rollbackRedisStock(message.getGoodsId()); } ); } }
3.3 消费者代码(含幂等处理)
@Component public class SeckillOrderConsumer { @KafkaListener(topics = "seckill-order-topic", groupId = "seckill-group") public void consume(String message) { SeckillOrderMessage orderMsg = JSON.parseObject(message, SeckillOrderMessage.class); // 幂等性检查:防止重复消费 String idempotentKey = "seckill:idempotent:" + orderMsg.getUserId() + ":" + orderMsg.getGoodsId(); Boolean acquired = redisTemplate.opsForValue().setIfAbsent(idempotentKey, "1", 24, TimeUnit.HOURS); if (Boolean.FALSE.equals(acquired)) { log.warn("重复消息,跳过: {}", orderMsg.getUserId()); return; } try { // 创建订单 + 扣减MySQL库存 createOrderAndDeductStock(orderMsg); } catch (Exception e) { // 失败则删除幂等key,允许重试 redisTemplate.delete(idempotentKey); throw e; // 抛异常触发Kafka重试 } } }

四、分布式锁防重复下单

// 使用Redisson分布式锁 RLock lock = redissonClient.getLock("seckill:lock:" + userId + ":" + goodsId); try { // 尝试获取锁,最多等待1秒,锁持有时间最长10秒 boolean acquired = lock.tryLock(1, 10, TimeUnit.SECONDS); if (!acquired) { throw new BusinessException("系统繁忙,请稍后重试"); } // 执行业务逻辑 processSeckill(userId, goodsId); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } }

关键点

  • tryLock的等待时间不能太长,秒杀场景下用户等不了
  • 锁的超时时间要合理,太短会导致业务没执行完锁就释放了
  • Redisson的看门狗机制会自动续期,防止业务未执行完锁过期

五、订单超时自动取消方案

// 方案一:Kafka延迟消息(推荐) // 发送订单时,同时发送一条30分钟的延迟消息 public void sendDelayCancelMessage(Long orderId) { // Kafka本身不直接支持延迟消息,可通过以下方式实现: // 1. 使用独立的延迟Topic + 定时扫描 // 2. 使用RocketMQ的延迟消息功能 // 3. 使用Redis的Key过期监听 // 这里以Redis + 监听为例 String key = "seckill:order:timeout:" + orderId; redisTemplate.opsForValue().set(key, "1", 30, TimeUnit.MINUTES); } // 监听Redis Key过期事件 @Component public class OrderTimeoutListener extends KeyExpirationEventMessageListener { public OrderTimeoutListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { String key = message.toString(); if (key.startsWith("seckill:order:timeout:")) { Long orderId = Long.parseLong(key.split(":")[3]); cancelTimeoutOrder(orderId); } } private void cancelTimeoutOrder(Long orderId) { // 检查订单状态,未支付则取消并回滚库存 Order order = orderMapper.selectById(orderId); if (order != null && order.getStatus() == OrderStatus.UNPAID) { order.setStatus(OrderStatus.CANCELLED); orderMapper.updateById(order); // 回滚Redis库存 redisTemplate.opsForValue().increment("seckill:stock:" + order.getGoodsId()); } } }

六、百万QPS架构设计总结

┌─────────────────────────────────────┐ │ 用户请求(百万QPS) │ └──────────────┬──────────────────────┘ ↓ ┌─────────────────────────────────────┐ │ 第1层:CDN + 前端静态化 │ │ · 秒杀页面静态化,CDN分发 │ │ · 按钮防抖 + 验证码 │ │ · 拦截约 90% 请求 │ └──────────────┬──────────────────────┘ ↓ ~10万QPS ┌─────────────────────────────────────┐ │ 第2层:API网关限流 │ │ · Nginx limit_req 令牌桶 │ │ · 用户维度限流(单用户每秒1次) │ │ · 黑名单过滤 │ │ · 拦截约 80% 剩余请求 │ └──────────────┬──────────────────────┘ ↓ ~2万QPS ┌─────────────────────────────────────┐ │ 第3层:Redis预扣库存 │ │ · Lua脚本原子操作 │ │ · 库存扣完直接拒绝 │ │ · 拦截约 95% 剩余请求 │ └──────────────┬──────────────────────┘ ↓ ~1000 QPS ┌─────────────────────────────────────┐ │ 第4层:Kafka异步下单 │ │ · 消息队列削峰填谷 │ │ · 消费者按能力消费 │ └──────────────┬──────────────────────┘ ↓ ┌─────────────────────────────────────┐ │ 第5层:MySQL落库 │ │ · 最终一致性 │ │ · 唯一索引防重 │ └─────────────────────────────────────┘

七、核心知识点速记卡

| 知识点 | 核心要点 | |--------|----------| | Redis扣库存 | Lua脚本保证原子性,避免竞态条件 | | Kafka削峰 | 异步解耦,吞吐量数十万/秒 | | 分布式锁 | Redisson + 看门狗自动续期 | | 幂等性 | Redis SETNX + 唯一索引双重保障 | | 数据一致性 | Redis预扣 + MQ异步 + 最终一致性 | | 限流方案 | 多层漏斗:前端→网关→服务→库存 | | 订单超时 | 延迟队列 / Redis过期监听 | | 高可用 | Redis Sentinel/Cluster + 降级方案 |


谢飞机课后总结:面试官说得对,秒杀系统不是「限时打折」,而是一场流量的战争。每一层拦截都是一道防线,Redis是前线哨兵,Kafka是后勤补给线,MySQL是最后的大本营。至于我……我还是回去等通知吧。


如果这篇文章对你有帮助,欢迎点赞、收藏、关注!下一期我们将带来「AIGC内容生成平台的Java架构设计」面试情景剧,敬请期待!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/22 8:15:33

江门肇庆挂靠地址注册风险对比:独立办公与集群注册区别

肇庆挂靠地址与独立办公场景解析 不同选择适合不同需求&#xff0c;不能简单判断谁“绝对更好”。在江门、肇庆等地区创业时&#xff0c;企业注册地址的选择直接影响合规成本与经营灵活性。对于初创团队而言&#xff0c;是选择成本较低的挂靠地址&#xff08;集群注册&#xf…

作者头像 李华
网站建设 2026/7/22 8:14:45

【小白学习系列】傅里叶变换 FT / DTFT / DFT / FFT

寓言&#xff1a;小镇集市四层分光镜&#xff08;四种傅里叶&#xff09; 背景设定 一条小河里的水波时域信号&#xff1b;阳光里不同色光频率&#xff1b;分光镜傅里叶变换&#xff1b; 小镇有四种分光工具&#xff0c;对应 FT / DTFT / DFT / FFT&#xff0c;只讲用途&#x…

作者头像 李华
网站建设 2026/7/22 8:13:41

低代码与YOLOv8融合的AI视觉规则平台开发实践

1. 项目概述&#xff1a;低代码与AI视觉的融合创新这个项目将Java低代码开发与YOLOv8目标检测技术相结合&#xff0c;打造了一个面向非技术人员的可视化规则生成平台。核心创新点在于通过拖拽方式配置检测规则&#xff0c;后端采用Spring Boot框架&#xff0c;前端使用Vue.js实…

作者头像 李华
网站建设 2026/7/22 8:13:34

MySQL InnoDB索引机制与优化实践详解

1. MySQL InnoDB索引机制深度解析聚簇索引和非聚簇索引是MySQL InnoDB引擎中两种核心的索引类型&#xff0c;它们的存储结构和查询效率有着本质区别。聚簇索引的叶子节点直接包含完整数据行&#xff0c;而非聚簇索引的叶子节点仅存储主键值。这种差异直接影响着数据库的查询性能…

作者头像 李华
网站建设 2026/7/22 8:10:47

软件测试CMA认可人员资质资格要求与培训内容

人员是实验室运行中非常关键的一个要素&#xff0c;也是实验室在进行软件测试CMA认可过程中非常重要的一个评审要素。软件测试实验室在申请CMA认可时&#xff0c;首先需要明确人员的资质&#xff0c;人员资质符合要求后&#xff0c;需要对人员进行培训、监督、授权和监控&#…

作者头像 李华
网站建设 2026/7/22 8:10:17

EVSSM几何变换技术:CVPR 2024的算力突破

1. EVSSM几何变换技术解析&#xff1a;CVPR 2024的算力突破 在计算机视觉领域&#xff0c;几何变换一直是核心基础技术之一。传统方法如仿射变换、透视变换等虽然成熟&#xff0c;但在处理复杂视觉任务时往往面临算力消耗大、精度不足等问题。今年CVPR会议上提出的EVSSM&#x…

作者头像 李华