python web开发高频面试题

8 阅读2分钟

业务场景相关

  1. 如何优化大文件导出? 比如导出一个excel文件包含10w条数据, 会拖慢整个系统?

    可以使用celery异步任务工具, 将导出任务交给celery, 让celery在后台异步实现数据查询, 并生成excel文件, 将生成的文件临时保存到服务器的某个目录。前端可以通过celery返回的任务id, 查询任务是否执行完毕, 执行完毕之后, 通过对应链接地址将生成文件下载下来即可。

  2. 如何防止订单重复支付?

    1. 前端可以在用户点击支付按钮之后, 禁用该按钮, 防止支付按钮被重复点击。
    2. 后端可以使用redis分布式锁, 防止同一条订单数据, 被同时处理。
    3. 后端数据库也可以使用悲观锁(select id,amount from order where id=订单id and pay_status=0 for update;), 锁定要处理的订单数据。
  3. 如何保证数据库和redis缓存的一致性?

    1. 在更新完数据库中的数据之后, 立即更新redis中对应的缓存数据。
    2. -更新完数据中的数据之后, 删除redis中的对应的缓存数据, 等待下次请求该数据的时候, 再将数据库中查询出来的数据更新到redis缓存中。
    3. 如果并请求发量比较高,可以先更新redis缓存,然后使用celery异步任务更新数据库中的数据。
  4. 电商高并发如何防止库存超卖?

    1. 将活动商品库存预先加载到redis中,使用商品id作为key,比如product:1, 商品库存作为value。
    2. 提交订单时,优先查询redis中的库存,如果有库存,则扣减redis中的库存数据,并通过redis异步任务去更新数据库中的缓存数据,并将订单数据以celery异步任务的方式写入数据库。
    3. 查询扣减库存可以借助lua脚本实现原子操作,防止查询库存时有库存,提交订单时库存不足的问题。
    4. 对于超时未支付的订单,可以使用celery定时任务去轮训订单表,取消未支付订单,并补偿相应数量的库存,redis和数据库都需要进行补偿。