51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个酒店库存管理系统,需支持实时库存更新(如预订后立即扣减库存),同时保证查询库存的实时性,请设计数据库表结构,并说明如何实现高并发下的库存操作(如并发扣减库存)。

南光(集团)有限公司旅游酒店类难度:困难

答案

1) 【一句话结论】:核心是采用数据库事务结合乐观锁(或分布式锁),通过缓存+数据库双写保证实时性,确保并发扣减库存时原子性,同时优化查询性能。

2) 【原理/概念讲解】:讲解库存管理的关键需求:实时扣减(事务性,保证扣减后库存准确)和实时查询(一致性,用户查询时看到最新库存)。关键技术点:

  • 数据库事务:ACID特性,保证扣减操作的原子性、一致性(如扣减后库存为负则回滚)。
  • 乐观锁:通过版本号(version字段)实现,类比图书馆借书系统,系统记录库存版本,扣减时检查版本是否一致,不一致则重试,适用于低到中并发场景,性能高。
  • 悲观锁:直接加锁(如SELECT ... FOR UPDATE),适用于高并发扣减(秒杀),但可能造成锁竞争,影响性能。
  • 缓存策略:使用Redis缓存库存数据,通过数据库更新后异步更新缓存(双写),保证查询实时性,减少数据库压力。

3) 【对比与适用场景】:

方式定义特性使用场景注意点
乐观锁基于版本号,更新前检查版本是否一致低锁竞争,高并发下性能好,高并发时重试次数多低到中并发(酒店预订)高并发下可能因重试导致延迟,需控制重试次数
悲观锁直接加锁(如SELECT ... FOR UPDATE)确保操作独占,避免并发冲突高并发扣减(秒杀)锁粒度大(如锁整表)可能导致性能瓶颈,锁竞争严重

4) 【示例】:

  • 表结构:
CREATE TABLE hotel_inventory (
    hotel_id INT NOT NULL,
    item_id INT NOT NULL,
    stock INT NOT NULL CHECK (stock >= 0),
    version INT NOT NULL DEFAULT 1,
    PRIMARY KEY (hotel_id, item_id)
);
  • 扣减流程(乐观锁伪代码):
  1. 查询库存:SELECT stock, version FROM hotel_inventory WHERE hotel_id = ? AND item_id = ?;
  2. 扣减逻辑:若stock >= amount且version == expected_version,则更新:
    UPDATE ... SET stock = stock - amount, version = version + 1 WHERE hotel_id = ? AND item_id = ? AND version = ?;
  3. 若更新失败(版本不一致),则重试步骤1-2(最多重试N次,如3次)。

5) 【面试口播版答案】:
“面试官您好,针对酒店库存管理系统的设计,核心是要解决实时扣减库存和实时查询的一致性问题。首先,数据库表结构上,我会设计一个库存表,包含酒店ID、商品ID、当前库存、版本号(用于乐观锁)。然后,实现高并发扣减时,采用乐观锁机制:查询库存时获取版本号,扣减后更新库存并递增版本号,若版本号不一致则重试。同时,为了提升查询性能,引入Redis缓存库存数据,通过数据库更新后异步更新缓存(双写),保证查询实时性。具体来说,扣减流程是:先从Redis查库存,若缓存不存在则从数据库查,然后执行扣减,扣减成功后更新数据库并异步更新Redis。这样既能保证实时性,又能减少数据库压力。对于并发问题,乐观锁能避免锁竞争,适用于酒店预订这类非秒杀场景,高并发下通过重试机制保证原子性。”

6) 【追问清单】:

  • 问题1:如果扣减库存时遇到超时或重试次数过多,如何优化?
    回答要点:设置重试次数上限(如3次),超时后记录日志并通知业务层,避免死循环。
  • 问题2:如何处理缓存雪崩或缓存穿透?
    回答要点:缓存雪崩用随机过期时间,缓存穿透用布隆过滤器或空值缓存。
  • 问题3:数据库事务的隔离级别如何选择?
    回答要点:选择REPEATABLE READ(或READ COMMITTED),避免脏读,同时保证事务一致性。
  • 问题4:如果库存扣减后,后续订单处理失败,如何回滚库存?
    回答要点:使用事务回滚,扣减库存时开启事务,失败则回滚,确保库存数据正确。
  • 问题5:锁的粒度(如锁整行 vs 锁整表)对性能有何影响?
    回答要点:锁整行(行级锁)比锁整表(表级锁)性能高,减少锁竞争,适用于高并发场景。

7) 【常见坑/雷区】:

  • 坑1:只考虑乐观锁但忽略高并发下的重试次数,导致性能下降。
    雷区:高并发下重试次数过多,增加系统延迟。
  • 坑2:缓存更新策略错误(如先更新缓存再更新数据库),导致缓存与数据库不一致。
    雷区:缓存数据过期后查询到旧库存,影响用户体验。
  • 坑3:事务隔离级别设置不当(如READ UNCOMMITTED),导致脏读。
    雷区:用户查询到未提交的库存数据,库存不准确。
  • 坑4:锁粒度过大(如锁整张表),导致并发性能下降。
    雷区:多个线程竞争同一把锁,阻塞严重。
  • 坑5:忽略库存扣减的原子性,导致库存为负数。
    雷区:业务逻辑错误,库存数据错误,影响订单处理。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1