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

在库存管理系统(WMS)中,如何设计缓存策略?比如本地缓存、分布式缓存(Redis),缓存更新策略(写时复制、双写)。

南光(集团)有限公司信息技术类难度:中等

答案

1) 【一句话结论】在WMS中设计缓存策略需结合业务场景,采用“本地缓存+分布式缓存”分层,高频读用本地缓存提升性能,分布式缓存解决跨服务共享;更新策略上,读多写少场景用写时复制减少锁竞争,需保证数据最终一致性,双写策略需考虑失败处理,避免脏数据。

2) 【原理/概念讲解】缓存的核心是“缓存-数据库”的读写分离,目的是减少数据库压力,提升系统响应速度。

  • 本地缓存:数据存储在应用进程的内存中(如Java的ConcurrentHashMap),适用于高频读、数据不常变的情况(如库存数量、商品信息),因为读操作远多于写操作,本地缓存能快速响应。
  • 分布式缓存(如Redis):数据存储在独立服务中,多个应用进程可共享,适用于跨服务、高并发场景(如入库、出库查询模块共享库存数据),避免重复查询数据库。
  • 缓存更新策略:
    • 写时复制(CoW):写操作时复制旧数据,写完成后更新新数据,原数据不变,减少锁竞争,适合读多写少。
    • 双写:先更新缓存再更新数据库(或反之),保证数据最终一致,但存在中间状态不一致风险(如先写缓存后数据库失败导致脏数据)。

3) 【对比与适用场景】

类别本地缓存分布式缓存(如Redis)
定义应用进程内内存存储的缓存,数据仅该进程可见跨进程/机器的共享缓存,数据由Redis等存储
特性读写速度快(进程内访问),无需网络通信需网络通信,但可共享,支持高并发
使用场景高频读、数据不常变(如静态商品信息、库存快照)跨服务共享、高并发读(如入库、出库查询)、分布式系统
注意点进程重启后缓存数据丢失,需持久化或热重启网络延迟、Redis故障导致数据丢失,需备份
更新策略写时复制(CoW)双写(先缓存后数据库/先数据库后缓存)
原理写操作时复制旧数据,写完成后更新新数据,原数据不变先更新缓存,再更新数据库(或反之),保证数据最终一致
适用场景读多写少,减少锁竞争,提升并发性能写操作频率不高,或需保证数据一致性(如金融场景)
优点减少锁竞争,读操作不受写影响保证数据最终一致性
缺点写操作时内存开销(复制数据),可能增加延迟写操作失败导致数据不一致,需重试或补偿

4) 【示例】

  • 本地缓存示例(伪代码):

    public class InventoryService {
        private final ConcurrentHashMap<String, Integer> localCache = new ConcurrentHashMap<>();
        private final JdbcInventoryDao dao;
    
        public InventoryService(JdbcInventoryDao dao) {
            this.dao = dao;
            loadInitialData();
        }
    
        private void loadInitialData() {
            List<Inventory> inventories = dao.getAllInventories();
            for (Inventory inv : inventories) {
                localCache.put(inv.getProductId(), inv.getQuantity());
            }
        }
    
        public int getQuantity(String productId) {
            Integer quantity = localCache.get(productId);
            if (quantity == null) {
                quantity = dao.getQuantity(productId);
                localCache.put(productId, quantity);
            }
            return quantity;
        }
    
        public void updateQuantity(String productId, int delta) {
            dao.updateQuantity(productId, delta);
            localCache.put(productId, localCache.getOrDefault(productId, 0) + delta);
        }
    }
    
  • 分布式缓存(Redis)示例:

    // Redis缓存:库存数量
    {
      "key": "inventory:product:123",
      "value": 100,
      "ttl": 3600 // 1小时过期
    }
    
    // 写操作(先数据库后缓存,双写)
    1. 更新数据库:UPDATE inventory SET quantity = quantity + 1 WHERE product_id = 123;
    2. 更新Redis:SET inventory:product:123 101 EX 3600;
    
    // 读操作(先Redis后数据库,缓存未命中时查数据库)
    1. GET inventory:product:123 -> 100
    2. 若为空,查询数据库,然后SET缓存
    

5) 【面试口播版答案】
面试官您好,在库存管理系统(WMS)中设计缓存策略,核心是分层缓存(本地+分布式)结合更新策略,保证性能与一致性。首先,高频读场景用本地缓存(如进程内ConcurrentHashMap),快速响应,比如库存数量、商品信息,因为读多写少,本地缓存能减少数据库压力。对于跨服务共享或高并发读,用分布式缓存(如Redis),比如入库、出库查询模块都访问库存,通过Redis共享数据,避免重复查询数据库。更新策略上,读多写少用写时复制(CoW),写操作时复制旧数据,写完成后更新新数据,减少锁竞争,提升并发;如果写操作频率不高或需保证一致性,用双写(先数据库后缓存),比如库存扣减,先更新数据库,再更新Redis,保证最终一致性。总结来说,本地缓存解决高频读,分布式缓存解决跨服务共享,写时复制优化读多写少场景,双写保证一致性,需根据业务场景选择组合。

6) 【追问清单】

  • 问题1:如何处理缓存击穿(热点数据突然大量请求,缓存未命中)?
    回答要点:设置热点数据预加载(缓存预热),或用互斥锁(分布式锁)保证同一时间只加载一次,避免重复查询数据库。
  • 问题2:如何处理缓存雪崩(大量缓存同时过期)?
    回答要点:设置缓存过期时间随机化(比如1-3小时),避免集中过期;或用分布式锁控制过期时间,或增加缓存预热。
  • 问题3:如何处理缓存穿透(查询不存在的数据,导致缓存空值,频繁查询数据库)?
    回答要点:对空值缓存(比如设置空值过期时间,或用布隆过滤器过滤不存在的数据),避免频繁查询数据库。
  • 问题4:本地缓存和分布式缓存如何选择?
    回答要点:本地缓存适用于高频读、数据不常变(如静态信息),分布式适用于跨服务共享、高并发读(如动态库存)。
  • 问题5:写时复制和双写哪个更优?
    回答要点:写时复制适合读多写少,减少锁竞争;双写适合写操作频率不高或需保证一致性(如金融场景),需考虑失败处理。

7) 【常见坑/雷区】

  • 缓存穿透:未命中时直接返回空,导致大量请求查询数据库,可设置空值缓存或布隆过滤器。
  • 缓存击穿:热点数据未缓存,大量请求导致数据库压力,需预加载或互斥锁。
  • 缓存雪崩:大量缓存同时过期,导致数据库压力激增,需随机化过期时间或预热。
  • 更新策略选择不当:读多写少用双写会导致读操作等待写完成,降低性能;写多读少用写时复制可能增加内存开销。
  • 缓存失效策略:未设置过期时间或过期时间不合理,导致数据不一致或过期后数据失效。
  • 分布式缓存故障:Redis故障导致数据丢失,需备份或主从复制。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1