题目与适用场景
请设计一个实时支付反欺诈平台。它位于支付授权之前,对每次请求返回 ALLOW、STEP_UP、REVIEW 或 BLOCK。STEP_UP 要求额外身份验证;REVIEW 可以延后履约或其他可逆业务动作,但反欺诈服务本身 不执行资金扣款。
假设系统平均每秒接收 1,000 个请求,峰值每秒 5,000 个,每个请求约 1.5 KB。同步决策的 p99 低于 100 毫秒,月可用性目标为 99.99%。运营团队每天最多人工审核 10,000 个案件。决策记录保留七天热查询, 原始事件归档 400 天。这些数字是面试假设,不代表真实产品指标或法定保留期。
支付服务发送令牌化支付工具、账户、商户、设备、网络、金额、币种和事件时间等属性。反欺诈平台不得 接收原始卡号或安全码。它负责风险决策、规则与模型版本、在线风险特征、审核案件和反馈标签;支付授权、 3DS 执行、拒付与资金账本仍由各自系统负责。
面试官考察什么
第一项信号是候选人能否定义决策契约,而不是只优化模型准确率。欺诈损失、误拦正常用户、额外验证 摩擦、人工审核容量、延迟和可用性共同约束策略。模型分数只是证据;带版本的策略负责把证据转换成动作。
第二项信号是时间正确性。速度特征要包含当前尝试,又不能在幂等重试时重复计数。历史训练特征只能使用 原决策发生时已经可用的信息。拒付和审核结果会延迟到达,因此未标注交易不能立刻当成负样本。
第三项信号是同步路径是否有明确边界。关键路径只做身份与结构校验、批量读取一小组特征快照、执行规则 与一个生产模型、应用策略、持久化可重放决策并返回。全局图遍历、大型联表、模型训练和案件分析都应移出 关键路径。图或批处理任务把紧凑的风险特征提前发布给同步服务读取。
第四项信号是降级规则是否明确。过期特征不等于安全特征,模型缺失也不等于风险分为零。动作要根据特征 新鲜度、金额、受影响实体和现有兜底能力改变。高质量答案会说明每个依赖故障下何时放行、加强验证、送审 或拦截。
最后是方案能否被证伪。每个决策都记录请求摘要、特征来源、命中规则、模型与策略版本、分数、动作、 原因码和延迟。这样才能用历史重放、时间点特征核对、重复与乱序事件、热点键压力、依赖故障、对抗流量、 影子流量和小流量发布检验设计。
回答前要确认的问题
- 平台放在哪个环节? 本方案在授权前同步决策。纯异步检测器可以发现团伙并支持调查,但阻止不了
当前这笔支付。
- 可用动作有哪些? 题目给出四种动作。
REVIEW受到每天 10,000 个案件的硬上限约束,不能把每个
不确定分数都丢给人工。案件等待期间哪些业务动作可以撤销,由支付产品定义。
- 上游提供哪些标识? 要求稳定的
decision_id、令牌化支付工具 ID、存在时的账户 ID、商户 ID 和
设备 ID。原始卡数据不进入边界;缺失的可选身份要变成显式特征,不能伪造默认值。
- 特征要多新? 十分钟速度规则不能使用一小时前的计数。每组特征都有最大允许年龄和兜底策略;画像
特征也许能容忍数分钟,关键速度状态可能只能容忍数秒。
- 标签何时、如何到达? 审核员结论是较早但可能出错的信号,随后确认的拒付是更强标签。应保存标签
来源、观察时间、成熟状态和版本,后续纠正不能静默改写历史。
- 跨实体图检测是否同步执行? 在 100 毫秒预算内不做全局遍历。离线或流式图任务发布实体风险、
邻居风险等紧凑特征;只有测得延迟与可用性后,才考虑为特定事件增加在线查询。
- 故障时默认放行还是拦截? 没有统一答案。低金额、已知客户可以在规则兜底下放行;关键特征不可用
时,高金额新设备支付可以加强验证或拦截。
- 隐私边界是什么? 保留期、跨地域处理、调查权限和特征是否合法,需要安全、隐私与合规负责人确认。
本答案最小化标识并审计访问,但不虚构特定司法辖区规则。
30 秒回答框架
“我会先固定带版本的决策契约:一个 decision_id、不可变请求摘要、四类动作、100 毫秒 p99 预算和 人工审核硬上限。同步服务批量读取新鲜在线特征,用幂等的实体速度状态把当前尝试计入窗口,再执行硬规则 和模型,最后应用策略,并在返回前持久化全部来源信息。事件同时进入流处理和离线存储;训练使用时间点 特征和带版本的成熟标签。全局图计算保持异步,只发布紧凑风险特征。依赖缺失或过期时,按金额与身份风险 执行明确的降级矩阵,不能静默给零分。最后用历史影子重放、小流量发布、热点键压力和故障注入,同时验证 欺诈结果与正常用户摩擦。”
分步深入分析
第一步:把题目转成预算和不变量
平均每秒 1,000 个请求意味着每天 8,640 万次决策。按每个请求 1.5 KB 计算,复制和索引前每天约有 129.6 GB 原始输入;峰值每秒 5,000 个请求约为 7.5 MB/s。如果一条紧凑决策记录平均为 2 KB,七天 热数据在索引和副本前约为 1.21 TB。这些只是容量锚点,不是精确存储预测;压缩率、字段开销和索引都要 实测。
更尖锐的产品约束是人工审核容量:每天 10,000 个案件只覆盖 8,640 万次决策的约 0.012%。策略必须 具备优先级和准入控制。队列满时,最低优先级审核区间要根据预期损失与用户摩擦转为带护栏的 ALLOW、 STEP_UP 或 BLOCK,不能无限堆积案件。
审核配额保存在决策服务的权威数据库中。按天的条件计数器可以再为不同风险区间预留名额,并在创建决策 与审核案件的同一事务里按 decision_id 认领。审核流量很低,不值得再引入独立分布式配额系统。认领 失败时,策略先计算已声明的溢出动作再提交,因此并发服务不会突破每日上限。
一个示例的 100 毫秒预算可以是:鉴权与校验 8 毫秒、批量在线特征与速度状态 25 毫秒、规则 10 毫秒、 模型推理 20 毫秒、策略与持久化决策 15 毫秒,剩余 22 毫秒留给网络和长尾。每一段的超时都短于自身 预算。关键不变量为:
one decision_id identifies one immutable request digest
an idempotent retry returns the original decision and does not increment velocity twice
every returned action has a persisted policy, model, rule, and feature provenance record
missing or expired critical features cannot be interpreted as normal values
review admissions never exceed the configured operational capacity
training features contain only values available at the historical decision time
labels retain source, observation time, maturity state, and version
raw payment card data never enters the fraud platform第二步:定义 API 与决策记录
同步接口保持收敛:
POST /v1/risk/decisions create or replay a decision
GET /v1/risk/decisions/{decision_id} read the immutable result and current case status
POST /v1/reviews/{case_id}/disposition record an analyst outcome
POST /v1/feedback ingest a dispute or trusted fraud outcome创建请求包含 decisionid、eventat、金额与币种、令牌化实体 ID、商户与渠道,以及本次请求属性。 响应包含 action、稳定原因码、可选的加强验证类型或审核案件 ID,以及 decision_version。数据库用 decision_id 唯一键保存规范化请求哈希;同 ID、同哈希重放原结果,同 ID、不同负载返回冲突。
按职责拆开数据:
risk_decisions:标识、请求哈希、事件时间、分数、动作、原因码、特征快照与新鲜度、规则包、模型与
策略版本、延迟和降级状态;
review_cases:决策引用、优先级、队列状态、处理人、处置结论和时间戳;feedback_labels:决策引用、标签、来源、观察时间、成熟状态、置信度和版本;policy_bundles:经过签名且不可变的规则、阈值、审核预算和故障兜底配置;outbox_events:本地已提交、等待异步发布的决策事件。
返回前,在一个本地事务中提交决策和 outbox。事件流按至少一次投递,消费者用 decision_id 与事件版本 去重。支付服务只能把这份不可变结果用于对应请求,不能换一个金额或支付工具后继续复用。
第三步:拆开同步决策与学习管道
同步数据流为:
payment service
-> decision API
-> idempotency lookup
-> batched online feature + velocity read
-> hard rules
-> model inference
-> versioned action policy
-> decision store + outbox
-> ALLOW | STEP_UP | REVIEW | BLOCK异步数据流消费决策、身份验证、支付结果、审核和拒付事件。流处理器去重后按事件时间开窗,更新十分钟 尝试次数、一小时不同商户数、金额偏离、设备年龄、近期验证失败等在线实体特征。不可变原始事件与特征 历史也进入离线存储,供分析与训练使用。
这对应实用的特征存储分工:在线存储保留最新值,服务低延迟读取;离线存储保留历史时间序列,负责训练 和物化。两边应共享特征定义、类型、实体键和转换测试,但不必共用存储引擎。让一个数据库同时承担任意 历史扫描与稳定低延迟查询,会把两种冲突工作负载绑在一起。
规则和模型互补。硬性策略、可信黑名单与高置信速度限制显式且快速;模型负责组合较弱信号和交互关系。 最终策略根据规则结果、模型分数、特征新鲜度、金额、身份可信度和审核容量映射动作。纯模型方案在故障时 难以运营;纯规则是合理的首版,却会随行为变化逐渐脆化。
第四步:让速度特征恰好一次计入当前尝试
由流处理更新的计数可能落后于正在评分的请求。两笔并发测卡请求可能读到同一个旧计数。对少量关键速度 规则,使用分区风险状态服务,提供幂等操作:
observe(entity_type, entity_id, window, decision_id, event_at, value)
-> count, sum, distinct_estimate, state_version, freshness服务按实体键排序更新,在窗口去重状态中保存 decision_id,把当前尝试计入后返回新计数。重试会返回 同一次观察,不再重复加一。状态分区具备副本和检查点,也能从事件日志重建。高基数去重特征可以使用有界 近似结构,精确拦截阈值则使用精确计数。
一笔请求同时涉及账户、支付工具、设备、IP 网段和商户。跨所有实体做全局原子事务会损害延迟与可用性。 并行查询各实体,并分别保证幂等;若部分超时,记录哪组不可用并交给策略降级,绝不能用零替代缺失值。 还要单独路由和压测已知热点实体,因为被攻击的支付工具或 IP 可能让单个分区过载,即使总 QPS 正常。
事件时间处理必须应对重复、迟到事件和空闲分区。水位线描述事件时间进度,不会让迟到数据自动消失。 为每项特征定义允许迟到范围,并用更高特征版本发布修正,同时监控水位线延迟。在线决策保留它实际看到 的快照;后续修正只改善未来决策与离线分析,不能假装早先服务已经知道新值。
第五步:执行新鲜度契约和明确降级矩阵
每组特征返回 computed_at、源事件时间、版本和最大允许年龄。特征服务据此得到 FRESH、STALE、 MISSING 或 ERROR,策略直接消费这个状态。只有业务上正常稀疏的数据才使用训练过的缺失标识;依赖 故障不能伪装成普通空值交给模型。
使用具体故障矩阵:
| 故障 | 低风险路径 | 较高风险路径 | 恢复信号 |
|---|---|---|---|
| 模型服务不可用 | 规则兜底放行或加强验证 | 加强验证、有限送审或拦截 | 模型超时与兜底率 |
| 关键速度状态缺失 | 支持时加强验证 | 拦截或有限送审 | 特征组可用性与年龄 |
| 流延迟导致画像过期 | 使用旧值并记录过期原因码 | 收紧阈值或加强验证 | 消费延迟与水位线延迟 |
| 审核队列满 | 只接收预期损失更高的案件 | 加强验证或拦截 | 队列年龄、流入量与审核吞吐 |
| 新策略导致异常 | 回到上一签名版本 | 回到上一签名版本 | 小流量差异与回滚完成度 |
具体单元格属于业务决策,但必须有版本并接受测试。全部放行会把依赖故障变成资损,全部拦截会把它变成 客户和收入故障。如果模型与关键速度状态同时缺失,策略仍可利用金额、可信身份、商户风险和验证能力, 但必须返回独立降级原因并通知值班人员。
第六步:构建时间点训练集和可变标签历史
每条历史决策以自己的 decision_at 为边界。只有底层事件已经发生、并且当时已经可用的特征行才能参与。 时间点联表必须处理迟到数据;用今天修正过的仓库重算上个月七日计数,会泄漏当时在线服务没有的信息。
标签有生命周期:
UNOBSERVED -> PROVISIONAL_ANALYST_OUTCOME -> MATURE_CONFIRMED_OUTCOME
\-> CORRECTED_VERSION具体成熟规则取决于支付和拒付流程。每个标签版本都要保留,不能在后续拒付到达时覆盖审核员结论。训练 明确选择一种标签定义与成熟截止点。评估使用向前的时间切分,对重复或相互关联案件做实体级检查,最后 保留一个完全未触碰的时间窗。离线与在线特征一致性测试要让同一批原始事件经过两套实现,再比较决策 边界上的取值。
监控不能只看整体 precision。需要衡量欺诈损失或避免损失、误拦金额与比例、授权和加强验证完成率、 审核命中率与队列年龄、分数校准、特征漂移、标签覆盖,并在合法前提下按商户、渠道、地域、支付方式、 金额区间和身份状态切片。全局表现良好的阈值仍可能静默伤害某个群体。
第七步:把图检测移出关键路径
欺诈团伙会连接账户、设备、支付工具、地址、商户和网络标识。每笔支付都遍历完整图,会与延迟和依赖 预算冲突。流式与批处理任务应提前计算危险邻居数、共享设备扩散度、连通分量风险、与已确认风险实体的 连接时间等紧凑特征,由在线存储带着新鲜度元数据提供最新版本。
这样会产生已知检测延迟。新攻击活动出现时,运营人员可以先发布范围收敛、带签名的规则或黑名单,等待 图管道跟上。只有历史重放证明在线图查询带来显著增量、p99 能装进剩余预算、并且故障有明确兜底时, 才值得加入同步路径。图证据还应给调查人员返回可读路径或原因码,不能只给一个无法解释的分数。
第八步:发布、安全、观测并验证系统
规则、模型、特征和策略阈值各有不可变版本,一份带签名策略包固定本次决策使用的组合。新版本先重放 带成熟标签的历史流量,再用影子流量运行而不改变动作,随后进入小流量发布。晋级时比较欺诈损失、误拦、 放行率、加强验证完成率、审核准入与命中率、延迟、特征新鲜度和兜底率。回滚只切换生效包指针,旧决策 仍可复现。
服务只接收令牌化 ID,对敏感属性做传输与静态加密,使用最小权限,审计调查访问与策略变更,清理日志, 并把策略审批和部署权限分开。数据删除与保留任务根据记录过的标识映射执行,并产出可审计结果。训练导出 受访问控制,不能把审核备注或未来结果混入特征。
验证清单包括:
- 用同一和不同负载重放相同
decision_id; - 在水位线边界发送重复、迟到和乱序事件;
- 对比历史决策时间点的离线与在线特征;
- 压测每秒 5,000 个请求、热点实体键和冷缓存启动;
- 分别关闭模型、在线存储、流处理器、一个状态分区和审核系统;
- 耗尽审核容量并检查准入策略;
- 影子运行并小流量发布一条故意更严格的规则,再执行回滚;
- 测试特征投毒、标识扩散、原因码泄漏、未授权策略变更和重放滥用。
运营看板要分开系统健康与决策质量。系统指标包括端点延迟、错误、依赖超时、特征年龄、流延迟、状态 重建进度、降级动作和队列年龄;结果指标只在成熟标签窗口上重算,并始终标记产生它们的策略与模型版本。
高质量示范回答
“我先固定决策契约:平均每秒评分 1,000 笔支付、峰值 5,000 笔,p99 在 100 毫秒内返回四种动作, 每天最多送审 10,000 个案件。这意味着审核是稀缺动作,模型准确率不是唯一目标,策略还要权衡欺诈损失、 误拦和加强验证摩擦。
支付服务用稳定决策 ID、令牌化实体 ID、事件时间、金额和请求属性调用决策接口。决策 ID 唯一保存不可变 请求哈希:相同请求重放,负载变化则冲突。服务批量读取带版本的在线特征,并把当前尝试幂等写入关键实体 的速度窗口,然后执行硬规则、一个模型和带签名的策略包。决策、原因码、特征新鲜度、命中规则、模型与 策略版本和 outbox 在动作返回前提交。
事件流更新在线聚合,并把原始历史写入离线存储。训练在原决策时间点联表,只选择在声明截止点前成熟的 标签版本。图计算保持异步,发布紧凑的邻居风险特征。每组特征都携带年龄与可用性;模型或关键计数故障 时,策略根据金额与身份风险选择规则兜底、加强验证、有限审核或拦截,绝不能把故障当成零风险。
我会用历史重放、影子流量和小流量逐步发布策略包,比较欺诈损失、误拦、放行与加强验证完成率、审核 命中率、延迟、特征新鲜度和降级率,并按关键维度切片。重复请求与事件、迟到数据、热点键、依赖故障、 审核饱和和对抗性特征输入都要成为测试。这样系统既满足低延迟,也受运营容量约束,还能解释并复现每次 决策。”
常见错误
- 错误:只优化 AUC 或准确率,再选一个阈值。 失败原因:这些指标没有包含损失金额、正常用户摩擦、
审核容量与系统故障。修正方法:建立带成本和容量约束的动作策略,同时监控结果与体验指标。
- 错误:读取流更新计数,就假设已包含当前尝试。 失败原因:并发攻击会读到相同旧计数,重试还可能
重复计数。修正方法:对关键速度状态按实体幂等观察,并记录状态版本与新鲜度。
- 错误:依赖不可用时填
NULL或零。 失败原因:故障被伪装成普通低风险输入。修正方法:把可用性和
年龄送入策略,执行经过测试的降级矩阵。
- 错误:同步查询全局欺诈图。 失败原因:遍历延迟不可预测,依赖面也会破坏 SLO。修正方法:异步发布
紧凑图特征,任何在线查询都要用测得的增量价值证明。
- 错误:没有拒付就立刻标成正常。 失败原因:结果延迟,新近负样本的观察窗口不完整。修正方法:保留
标签版本,只在声明的成熟窗口训练。
- 错误:用今天的仓库重算历史特征。 失败原因:迟到和修正数据会泄漏未来信息。修正方法:用事件时间
与可用时间做时间点联表,并保留实际服务快照。
- 错误:所有不确定案件都送人工。 失败原因:每天 10,000 个名额只能覆盖约 0.012% 的流量。修正方法:
按预期可避免损失排序,执行准入与溢出策略。
- 错误:规则或模型直接全量发布。 失败原因:服务技术上可用,仍可能造成大面积误拦。修正方法:历史
重放、影子评估、小流量、签名版本和快速回滚。
追问及应对
追问一:同一支付工具的两次并发尝试都看到计数未达阈值,怎么办?
把关键规则从被动缓存聚合改成按实体幂等观察。状态分区按该支付工具排序更新,每个决策 ID 只记录一次, 把当前尝试计入后返回新计数与版本。其他实体特征可以保持最终一致。压测必须加入单一热点支付工具,因为 均匀 QPS 测试暴露不了这个分区瓶颈。
追问二:模型服务故障十五分钟,放行还是拦截?
执行带版本的故障矩阵。硬黑名单和关键速度规则继续运行;低金额且身份可信的支付可由纯规则放行,高金额 或新设备支付可以加强验证、进入有限审核队列或拦截。所有兜底动作带降级原因。既要监控依赖恢复,也要 监控业务影响,不能静默返回默认分数。
追问三:拒付标签要几周才成熟,但今天出现新攻击活动,如何适应?
用验证失败、审核结论、商户报告和共享实体聚集等领先信号支持调查,但将它们与成熟标签分开记录来源。 通过影子和小流量发布范围收敛、可撤销的规则。只有所选标签定义具备足够成熟覆盖后才重训,否则最新的 “看似正常”样本会让评估产生偏差。
追问四:每天需要审核 50,000 个案件,容量仍是 10,000,怎么办?
按预期可避免损失、证据质量、金额和时效排序,为必须处理的群体保留容量,只接收前 10,000 个。其余 区间按预先批准的加强验证、放行或拦截策略处理,并监控队列年龄与人员吞吐。只把消息塞进没有可执行 服务水平的队列,是把过载藏起来。
追问五:为什么不让在线特征存储同时成为唯一训练数据源?
在线存储为低延迟读取保留最新值,通常无法重建数百万个历史决策时点所知的信息。训练需要时间序列历史、 时间点联表、回填和大型扫描。应让在线与离线存储共享定义并接受一致性测试,而不是强迫一个引擎承担两种 冲突负载。
追问六:图任务后来发现某个欺诈团伙,能否改写之前的决策?
不能。保留原动作与当时的完整来源,新增一条带观察时间的发现或标签版本,执行允许的后续动作,更新实体 在线风险以影响未来决策,并把案件纳入重放。改写旧决策会抹去服务当时真正知道的信息,破坏审计和模型评估。