业务实现
你是怎么独立完成一个业务功能的?比如草稿箱功能?
我按照需求→设计→开发→测试→上线的完整流程推进:
需求分析:明确草稿箱解决用户填写表单时信息丢失问题,梳理核心流程:手动保存、自动保存、草稿列表、恢复、删除。
系统设计:
- 数据库:因为每个审批流程的表单字段不一致,所以用longtext存储表单数据(longtext 更通用、性能更好、跨版本更兼容,也更适合存大型 JSON)
- 接口:设计POST/draft/save、GET/draft/list等RESTful接口
开发实现: - 后端:分层架构,先检查该用户是否已存在草稿,若存在则更新,不存在则创建。
- 前端:localStorage存储草稿数据,30秒定时自动保存,优化用户体验
测试上线:功能、并发、兼容性、场景测试,灰度发布后全量上线。
自动保存草稿时,如何保证幂等(idempotent)?
幂等(Idempotency)是编程与分布式系统中的核心概念,核心定义是:同一操作(或请求)被执行一次,与被执行多次的结果完全一致,且不会对系统状态造成额外副作用。
我主要做了两层保证:
数据库唯一索引:
- 草稿表添加
(user_id, definition_id)唯一索引,同一个用户 + 同一个流程定义,只允许存在一个草稿。 - 定义
definition_id为审批流程的唯一标识,确保每个流程的草稿独立存储。
- 草稿表添加
前端请求幂等:
- 前端在保存草稿时,添加
requestId到请求体,后端根据此 ID 检查是否重复请求。 - 如果重复请求,后端直接返回之前的保存结果,不重复处理。
- 前端在保存草稿时,添加
你做草稿功能遇到过什么坑?
坑一:自动保存和手动保存冲突
问题描述:
用户手动点"保存"的同时,自动保存定时器一起触发,会覆盖掉前者。
解决办法:
- 自动保存打上标记,前端做优先级控制
- 手动保存优先级高于自动保存
- 自动保存只能更新非关键字段(比如更新时间)
坑二:恢复时表单版本不一致
问题描述:
流程设计器更新了表单字段,但历史草稿还存在旧结构 → 恢复会报错。
解决办法:
保存草稿时记录表单版本号:
{ "form_data": {...}, "form_version": "1.2.0" }恢复时进行版本比对:
- 版本一致 → 正常恢复
- 版本不一致 → 兼容模式(只恢复匹配字段)
扫码登录如何实现?
核心流程:
生成二维码(UUID)
后端生成一个临时loginToken,存 Redis,设短期过期(如 60 秒)。
前端展示二维码,二维码内容为:https://xxx.com/qrLogin?token=xxxx轮询登录状态
网页端每 1~2 秒轮询 Redis 查询该token是否被确认。手机扫码 → 授权
用户打开 App/小程序 → 扫码 → 将登录授权请求发送给后端:loginToken + 用户凭证(如 userId / session / jwt)后端验证后将 Redis 中
token状态改为 “已确认并绑定 userId”。网页端完成登录
轮询收到状态变为已确认 → 后端生成正式 JWT → 浏览器完成登录。
为什么微信只能扫码登录?
因为 PC 端无法直接拿到微信账号体系的凭证。
微信的登录凭证(OpenID、SessionKey)只能通过 微信客户端或小程序内部调用微信 API 获得,网页环境无法拿到微信的用户授权。
所以微信 PC 端必须通过手机授权(扫码登录)才能确认用户身份。
分享邀请如何判断邀请来源?如何防刷?
一、如何判断是谁邀请的?
给邀请链接加 inviterId:
https://xxx.com/register?inviterId=12345新人注册时带上此字段,后端记录邀请关系即可。
二、防刷方案:
限制同设备/同 IP 的注册次数
- 设备指纹
- IP 限流(如 1 小时只能注册 1 次)
手机号唯一性
一个手机号只能被邀请一次。风控校验
- 注册号段黑名单
- 代理 IP / 云主机 IP 自动拒绝
- 频繁注册的设备直接拉黑
行为验证
- 图形验证码
- 滑块验证
- 短信验证码限制(1 小时 n 次)
延迟发放奖励
如:被邀请者满足 登录+使用 3 天 才给奖励,减少恶意批量注册。
假设有一个用户量级达上千万或上亿的系统,举办营销活动让用户抢同一个产品,如何保证该产品只能被一个人抢到?
核心方案:Redis分布式锁(Redisson)+ 数据库乐观锁(version/库存字段)双校验,配合库存预扣减+异步确认,步骤如下:
- 用户抢单先抢Redis锁(按商品ID设锁,防并发);
- 抢到锁后,数据库执行
update 商品表 set 库存=库存-1 where 商品ID=xxx and 库存>0(乐观锁本质,update语句原子操作防超卖); - 若更新行数>0,抢单成功;否则失败,释放Redis锁;
- 异步同步订单状态,超时未支付自动回滚库存。
有商品售卖系统和商品后台管理系统两个系统,商家在运营管理系统更新商品数量(如苹果今日上限100个、明日上限200个)时,如何让数据实时同步,使用户在售卖系统查询时能看到最新数量?
1. 直接数据库同步(简单但实时性好)
- 两个系统用同一个数据库表
- 后台管理系统更新库存后,售卖系统直接查数据库拿最新数据
- 优点:实时性强、实现简单
- 缺点:数据库压力大,高并发时可能拖垮系统
2. 缓存 + 消息队列异步刷新(高性能)
- 缓存层:售卖系统把商品库存放 Redis 里
- 消息队列:
- 商家在后台系统更新库存表后,发个消息到 MQ(像 Kafka、RabbitMQ 那种)
- 售卖系统订阅 MQ,收到消息就更新 Redis 缓存
- 查询逻辑:售卖系统先查 Redis,没有再查数据库
- 优点:高并发时查询快、数据库压力小
- 需要注意:确保消息靠谱投递,别让库存数据对不上
3. 事件驱动 + 缓存预热(再优化一下)
- 对每日限量、秒杀库存这些特殊情况,后台管理系统一更新就立刻刷新 Redis
- 可以配合过期时间或者预扣库存机制,保证售卖系统在高并发时看到的库存和后台一致