Java面试要点:积分发放、冻结、扣减、过期与流水幂等
前言
积分系统常见于会员、电商、营销、SaaS 增值服务。面试会问:
- 积分为什么要有流水。
- 重复支付回调会不会重复加积分。
- 积分消费后退款怎么返还。
- 积分过期怎么处理。
- 冻结积分和可用积分有什么区别。
账户模型
常见字段:
- total_points:累计积分。
- available_points:可用积分。
- frozen_points:冻结积分。
- expired_points:已过期积分。
但关键不是余额字段,而是积分流水。
流水字段:
| 字段 | 说明 |
|---|---|
| flow_no | 流水号 |
| user_id | 用户 |
| biz_type | 来源类型 |
| biz_no | 业务单号 |
| change_points | 变动积分 |
| direction | IN/OUT |
| balance_after | 变动后余额 |
发放积分
常见来源:
- 支付成功。
- 签到。
- 评论。
- 活动奖励。
- 会员升级。
发放要做幂等:
1 | user_id + biz_type + biz_no 唯一 |
这样支付回调重复时不会重复加积分。
冻结和扣减
积分支付或兑换时常见两阶段:
- 下单锁定积分。
- 支付成功后正式扣减。
- 订单取消后释放冻结。
stateDiagram-v2
[*] --> 可用
可用 --> 冻结: 下单兑换
冻结 --> 已扣减: 交易成功
冻结 --> 可用: 取消/失败
可用 --> 已过期: 到期
积分过期
常见过期策略:
- 固定年底过期。
- 发放后 N 天过期。
- 先进先出扣减。
大规模过期不能一次性更新所有用户,通常按批次、按分区、按用户范围执行,并记录任务批次。
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 只存余额 | 简单 | 不可审计 |
| 余额 + 流水 | 可追踪 | 实现稍复杂 |
| 分桶积分 | 便于过期 | 查询和扣减复杂 |
企业里通常用“余额 + 流水”,有过期要求时再加积分批次。
高频面试题
为什么积分必须有流水?
因为积分属于用户权益,必须能追溯每次变动原因,方便对账、客服查询和问题修复。
重复发放怎么防?
用业务单号唯一约束和幂等表,消费消息也要支持重复投递。
积分退款怎么处理?
根据原订单和原积分流水做反向流水,不能简单修改历史记录。
积分过期怎么做?
按批次扫描可过期积分,生成过期流水,并控制任务速率,避免一次性打爆数据库。
总结
积分系统的重点是账户余额、积分流水、冻结释放、过期策略和幂等。面试回答时要强调:余额是结果,流水是依据;任何积分变动都要可追溯、可补偿、可对账。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Junly博客!
评论


