快看!百度提前批的面试难度,你能拿下吗?

最近各家的秋招提前批陆续都开始招聘了,相比于秋招正式批(9-11 月)来说,提前批的特点是:招聘规模小、应聘人数少、竞争压力小、面试难度低,因此对于学校比较好的同学来说是一次难得上岸的好机会。

大家可以感受以下百度提前批的面试难度:

除了场景题外,其他问题基本都是白送,这样的面试拿不下就说不过去了。

好了,咱们来看里面最难的场景题:纯使用 MySQL 如何实现秒杀?

秒杀系统分析

秒杀系统的特点是:

  1. 数据一致性要求高:在秒杀系统中,必须确保"用户扣款、商家收款、商品减少、订单提交"这四个步骤一起执行。
  2. 库存有限:商品数量通常极少(如 10 件),需严格控制超卖。
  3. 瞬时高并发:大量用户在极短时间内同时发起请求,流量激增。
  4. 要求公平性:需避免机器人或脚本刷单,确保普通用户机会均等。

其中,数据一致性和库存问题可以通过 MySQL 数据库事务(Transaction)结合行级锁(如 FOR UPDATE)来保证

核心实现思路

我们需要让"用户扣款、商家收款、商品减少、订单提交"这四个操作必须在一个事务中按顺序执行,核心实现思路如下:

  1. 检查商品库存并锁定库存行(SELECT ... FOR UPDATE)。
  2. 扣减商品库存(UPDATE inventory)。
  3. 创建订单记录(INSERT order)。
  4. 用户账户扣款(UPDATE user_balance)
  5. 商家账户收款(UPDATE merchant_balance)。

所有操作在同一个事务中完成,任一失败则回滚

具体实现步骤

具体步骤如下:

  1. 开启事务(BEGIN)。
  2. 查询商品库存时使用 SELECT ... FOR UPDATE 对库存行加排他锁,防止其他事务同时修改。
  3. 判断库存是否足够,不足则回滚并退出。
  4. 执行库存减少。
  5. 插入订单记录。
  6. 扣减用户余额。
  7. 增加商家余额。
  8. 提交事务(COMMIT),若任一步失败则 ROLLBACK。

注意:所有操作必须在同一事务中,且顺序合理,避免死锁问题。

其中:

  • 行级锁与悲观锁:SELECT ... FOR UPDATE 是悲观锁的一种实现,它会在读取记录时加上排他锁,直到事务结束才释放。在高并发秒杀中,多个请求同时竞争同一商品库存,FOR UPDATE 能保证只有一个事务能获取到锁并继续执行,其余事务阻塞等待或超时。
  • 死锁预防:多个事务按不同顺序访问资源可能导致死锁。建议所有事务按固定顺序操作:先库存 → 再订单 → 用户 → 商家。设置合理的锁等待超时(innodb_lock_wait_timeout),避免长时间阻塞。
  • 库存扣减的优化:可在 UPDATE 时直接判断库存,避免两次查询: UPDATE inventory SET stock = stock - 1 WHERE product_id = ? AND stock > 0;若影响行数为 0,说明库存不足,直接回滚。

具体实现案例

以下是 MySQL 具体实现案例:

sql 复制代码
BEGIN;

-- 1. 锁定商品库存行(悲观锁)
SELECT stock FROM product_inventory WHERE product_id = 1001 FOR UPDATE;

-- 假设上一步查出 stock = 5 > 0,则继续

-- 2. 扣减库存
UPDATE product_inventory SET stock = stock - 1 WHERE product_id = 1001;

-- 3. 创建订单
INSERT INTO `order` (user_id, product_id, amount, status, create_time)
VALUES (123, 1001, 100.00, 'paid', NOW());

-- 4. 用户扣款
UPDATE user_account SET balance = balance - 100.00 WHERE user_id = 123;

-- 5. 商家收款
UPDATE merchant_account SET balance = balance + 100.00 WHERE merchant_id = 5001;

-- 提交事务
COMMIT;

若任一语句失败(如余额不足、库存为0、死锁等),执行 ROLLBACK。

高并发优化

MySQL 层面的高并发优化手段:

  1. 使用乐观锁:在高并发下,悲观锁可能导致大量阻塞。可改用乐观锁,通过版本号或 CAS 操作: UPDATE product_inventory SET stock = stock - 1, version = version + 1 WHERE product_id = 1001 AND stock > 0 AND version = @expected_version;
  2. 使用连接池:避免频繁创建连接(如使用 HikariCP)。
  3. 索引优化:添加适当的索引(如商品 ID),提高查询效率。
  4. 分库分表:热点商品可分桶库存(如库存拆为 10 个子库存)减少锁冲突,加速执行效率。

非 MySQL 高并发可使用缓存(库存存储到缓存)+异步消息队列(消息补偿)的方式来提升并发效率。

公平性保证

保证公平性的手段:

  • 验证码限制:前端加验证码防止短期大量请求。
  • 请求限流:一个用户一段时间内只能发送一次请求。
  • 用户资格校验:后端校验用户资格(是否已抢过)。
  • 黑白名单限制:刷单 IP 存储到黑名单,取消抢单资格。

分布式场景下的挑战: 若系统拆分为微服务,MySQL 事务无法跨服务。需引入分布式事务(如 Seata)或最终一致性方案(消息队列 + 补偿事务)。

小结

找工作要趁早,越早机会越多、面试难度和竞争压力也就越小,所以各位准备找工作的朋友们,把简历一起投起来吧,有开始就有希望。命运的齿轮已经开始转动,您准备好了吗?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:场景题、SpringAI、SpringAIAlibaba、并发编程、MySQL、Redis、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、JVM、设计模式、消息队列、Dify、Coze、AI常见面试题等。

相关推荐
编程爱好者熊浪10 分钟前
RedisBloom使用
java
苇柠23 分钟前
Spring框架基础(1)
java·后端·spring
yics.27 分钟前
数据结构——栈和队列
java·数据结构
在未来等你29 分钟前
RabbitMQ面试精讲 Day 14:Federation插件与数据同步
中间件·面试·消息队列·rabbitmq
架构师沉默32 分钟前
我用一个 Postgres 实现一整套后端架构!
java·spring boot·程序人生·架构·tdd
xiucai_cs36 分钟前
布隆过滤器原理与Spring Boot实战
java·spring boot·后端·布隆过滤器
向阳花自开38 分钟前
Spring Boot 常用注解速查表
java·spring boot·后端
程序视点1 小时前
如何高效率使用 Cursor ?
前端·后端·cursor
huan_19931 小时前
通过docker构建一个java镜像
java·docker
岁忧2 小时前
(LeetCode 面试经典 150 题) 82. 删除排序链表中的重复元素 II (链表)
java·c++·leetcode·链表·面试·go