MST
星途 面试题库

面试题:Redis字典API之专家难度:复杂数据结构与事务处理

要求利用Redis字典API实现一个购物车功能,购物车中每个商品以哈希表形式存储详细信息,同时支持添加商品、修改商品数量、删除商品以及结算等操作,并保证在高并发场景下数据的一致性,使用Redis事务机制来实现。请详细描述设计思路并编写核心代码(语言自选)。
17.8万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 数据结构设计
    • 使用Redis的哈希表(Hash)来存储每个商品的详细信息,例如商品ID、名称、价格等。
    • 使用Redis的哈希表来存储购物车,购物车哈希表的键为商品ID,值为商品在购物车中的数量。
  2. 操作实现
    • 添加商品:如果购物车中该商品不存在,先在商品哈希表中添加商品详细信息,然后在购物车哈希表中添加该商品并设置数量为1;如果购物车中已存在该商品,则仅增加购物车中该商品的数量。
    • 修改商品数量:直接在购物车哈希表中修改对应商品的数量。
    • 删除商品:从购物车哈希表中删除对应商品,同时如果该商品没有在其他购物车中存在(可通过计数等方式判断,这里简化不做详细实现),可以从商品哈希表中删除该商品详细信息。
    • 结算:遍历购物车哈希表,根据商品ID从商品哈希表中获取商品价格,计算总金额。
  3. 高并发处理:使用Redis事务机制(MULTI、EXEC),确保上述操作在高并发场景下数据的一致性。在事务执行过程中,Redis会将一系列命令作为一个原子操作执行,要么全部成功,要么全部失败。

核心代码(Python示例)

import redis


class ShoppingCart:
    def __init__(self, host='localhost', port=6379, db=0):
        self.r = redis.StrictRedis(host=host, port=port, db=db)

    def add_product(self, product_id, product_info):
        pipe = self.r.pipeline()
        try:
            pipe.multi()
            # 判断购物车中是否已有该商品
            cart_count = pipe.hget('shopping_cart', product_id)
            if cart_count is None:
                # 添加商品详细信息到商品哈希表
                pipe.hmset(f'product:{product_id}', product_info)
                # 添加商品到购物车,数量设为1
                pipe.hincrby('shopping_cart', product_id, 1)
            else:
                # 购物车中已有该商品,数量加1
                pipe.hincrby('shopping_cart', product_id, 1)
            pipe.execute()
        except redis.RedisError as e:
            print(f"Error adding product: {e}")
            pipe.reset()

    def modify_product_count(self, product_id, count):
        pipe = self.r.pipeline()
        try:
            pipe.multi()
            pipe.hset('shopping_cart', product_id, count)
            pipe.execute()
        except redis.RedisError as e:
            print(f"Error modifying product count: {e}")
            pipe.reset()

    def delete_product(self, product_id):
        pipe = self.r.pipeline()
        try:
            pipe.multi()
            # 从购物车中删除商品
            pipe.hdel('shopping_cart', product_id)
            # 这里简化处理,不检查该商品是否在其他购物车中,直接删除商品详细信息
            pipe.delete(f'product:{product_id}')
            pipe.execute()
        except redis.RedisError as e:
            print(f"Error deleting product: {e}")
            pipe.reset()

    def checkout(self):
        total_amount = 0
        pipe = self.r.pipeline()
        try:
            pipe.multi()
            cart_items = pipe.hgetall('shopping_cart')
            for product_id, count in cart_items.items():
                product_price = pipe.hget(f'product:{product_id.decode()}', 'price')
                total_amount += float(product_price) * int(count)
            pipe.execute()
        except redis.RedisError as e:
            print(f"Error during checkout: {e}")
            pipe.reset()
        return total_amount


使用示例

if __name__ == '__main__':
    cart = ShoppingCart()
    product_info = {'name': 'example_product', 'price': 10.0}
    cart.add_product('1', product_info)
    cart.modify_product_count('1', 2)
    total = cart.checkout()
    print(f"Total amount: {total}")
    cart.delete_product('1')