文章详情

背景

在计算机专业的面试中,经常会遇到一些业务上的BUG。这类不仅考察者对编程和系统理解的深度,还考验其对实际业务场景的应对能力。是一道典型的业务上BUG及其解析。

在一个在线电商系统中,用户可以在购物车中添加商品。系统设计了一个功能,允许用户通过输入商品ID来快速将商品添加到购物车。在实际使用过程中,发现当用户连续快速输入多个商品ID时,购物车中会出现重复的商品记录。是系统相关的代码片段:

python

class ShoppingCart:

def __init__(self):

self.items = []

def add_item(self, item_id):

if item_id not in self.items:

self.items.append(item_id)

return True

return False

# 假设这是调用接口

cart = ShoppingCart()

cart.add_item('123')

cart.add_item('456')

cart.add_item('123') # 这里可能会出现重复

分析

根据上述代码,我们可以看到`add_item`方法在添加商品到购物车时会检查商品ID是否已存在于购物车中。不存在,则添加该商品ID到购物车,并返回True表示添加成功;已存在,则返回False表示添加失败。

当用户连续快速输入多个商品ID时,出`if item_id not in self.items`这一行。由于Python的`in`操作在列表中进行时,会进行一次线性查找,当购物车中商品数量较多时,查找效率会降低。更重要的是,由于用户的快速操作,可能在两次检测之间,商品ID已经被添加到列表中,从而导致重复。

解答

针对上述我们可以采取几种方法来解决:

1. 使用集合(Set)代替列表(List)

由于集合(Set)是基于哈希表实现的,其查找效率比列表高。我们可以将`self.items`从列表改为集合,这样可以大大提高查找效率。

python

class ShoppingCart:

def __init__(self):

self.items = set()

def add_item(self, item_id):

if item_id not in self.items:

self.items.add(item_id)

return True

return False

2. 使用布隆过滤器(Bloom Filter)

商品ID的数量非常大,甚至超过了内存的限制,可以使用布隆过滤器。布隆过滤器是一个概率型数据结构,它可以用来测试一个元素是否是一个集合的成员。虽然它有误报的可能,但不会出现漏报。

python

import hashlib

from bitarray import bitarray

class BloomFilter:

def __init__(self, size, hash_count):

self.size = size

self.hash_count = hash_count

self.bit_array = bitarray(size)

self.bit_array.setall(False)

def add(self, item):

digests = [hashlib.md5((item + str(i)).encode()).hexdigest() for i in range(self.hash_count)]

for digest in digests:

index = int(digest, 16) % self.size

self.bit_array[index] = True

def check(self, item):

digests = [hashlib.md5((item + str(i)).encode()).hexdigest() for i in range(self.hash_count)]

for digest in digests:

index = int(digest, 16) % self.size

if self.bit_array[index]:

continue

return False

return True

class ShoppingCart:

def __init__(self):

self.bit_filter = BloomFilter(1000000, 10)

def add_item(self, item_id):

if not self.bit_filter.check(item_id):

self.bit_filter.add(item_id)

return True

return False

3. 优化业务逻辑

业务允许,我们可以优化用户的操作流程,限制用户在短时间内输入商品ID的次数,或者增加一个防抖动的机制。

通过以上方法,我们可以有效地解决因连续快速输入商品ID导致的重复提高系统的稳定性和用户体验。