BIGO

后台开发工程师(AI 功能相关)二面面经

完整信息

10 条问法 · 10 道题

本篇目录

来源内容仅部分可用:原文不足

1. 请先做一下自我介绍

2.项目拷打

3. 如何设计客户端与服务端之间的图片安全上传链路?

图片上传不能只依赖扩展名和客户端校验。客户端可以进行初步限制,但最终安全判断必须在服务端完成。

服务端需要检查:

  • 文件真实类型,而不是只看后缀;
  • 文件大小和像素数量;
  • 图片是否包含恶意压缩数据;
  • 是否存在路径穿越或脚本内容;
  • 图片元数据是否需要清理;
  • 是否需要病毒扫描;
  • 是否需要生成隔离后的新文件;
  • 上传用户是否有对应权限。

图片上传后应先进入隔离存储,经过解码、重新编码和安全检查后,再进入业务存储。对外访问最好使用短时有效的签名 URL,不直接暴露内部路径。

public boolean validateImage(byte[] data, String contentType) {
    if (data == null || data.length > 10 * 1024 * 1024) {
        return false;
    }

    if (!Set.of("image/jpeg", "image/png", "image/webp")
            .contains(contentType)) {
        return false;
    }

    ImageInfo info = decodeImageHeader(data);
    return info != null
            && info.width() <= 10000
            && info.height() <= 10000;
}

4. 如果恶意客户端绕过正常流程直接访问网关接口,网关层需要做哪些防护?

网关不能只依赖客户端传来的用户 ID 或设备信息。应该从身份认证、请求完整性、访问权限、流量控制和异常检测几个层面进行防护。

具体包括:

  • 校验短期 Token 和签名;
  • 检查时间戳和随机数,防止重放;
  • 根据服务端会话确认用户身份;
  • 校验租户、资源和接口权限;
  • 对请求体进行大小和格式限制;
  • 按用户、设备、IP 和接口维度限流;
  • 对高风险接口增加二次验证;
  • 对异常请求记录审计日志。

签名校验时,不能只签名少量字段,否则攻击者可能替换未参与签名的参数。

signature = HMAC-SHA256(
    secret,
    method + path + timestamp + nonce + bodyHash
)

服务端还要限制时间戳有效期,并保存近期使用过的 nonce,避免同一请求被重复提交。

5. 在一个包含 Skill、Agent、RAG 和 MCP 的完整调用链中,如何划分各层职责?

Skill 应该描述面向业务的能力和执行流程,例如“生成穿搭建议”或“解释审核结果”。

Agent 负责理解用户目标、选择合适的 Skill、决定执行顺序,并根据中间结果调整策略。

RAG 负责从知识库或业务文档中获取补充事实,例如尺码规则、品牌规范或产品说明,但不应替代实时商品服务。

MCP 负责以统一协议暴露工具、资源和上下文能力,例如商品查询、库存查询、审核状态查询等。

一条完整链路可以是:

用户请求
  -> Agent 识别意图
  -> Skill 生成任务流程
  -> RAG 获取规则和知识
  -> MCP 调用业务工具
  -> Agent 汇总结果
  -> 客户端展示结构化响应

各层之间应传递结构化数据,并且记录版本、权限和来源,不能让所有逻辑都堆积在 Prompt 中。

6. Agent 执行任务时,Skill、MCP 工具和模型之间应该如何确定加载顺序?

不能一次性把所有 Skill 和工具都加载给模型,否则会增加上下文长度,也会提高工具选择错误率。

可以采用分阶段加载:

  1. 先根据用户意图加载候选 Skill;
  2. Skill 再声明当前阶段需要的工具;
  3. 进入具体步骤后才加载对应的 MCP 工具描述;
  4. 工具执行完成后,根据结果决定是否加载下一组能力。

例如用户只是查询服装尺寸,就不应该加载图片编辑、支付或订单修改工具。

工具描述需要包含输入约束、权限要求、失败类型和幂等说明。高风险工具不能仅仅因为被模型选择,就直接获得执行资格。

7. 如何解决客户端 AI 功能中的模型版本升级问题?

模型升级不能只替换一个模型名称。需要同时管理模型版本、Prompt 版本、工具协议版本、后处理逻辑和评测数据版本。

上线前可以进行:

  • 历史请求回放;
  • 固定数据集回归;
  • 边界样本测试;
  • 不同设备和网络环境测试;
  • 延迟、成本和失败率对比;
  • 小流量灰度。

客户端最好不要把模型名称和协议细节硬编码在多个页面中,而是通过能力配置或服务端下发版本信息进行统一管理。

如果新模型在部分任务上表现更好、部分任务上表现更差,可以使用能力路由,而不是强制全量切换。

8. 如何设计客户端 AI 功能的离线评测和线上指标?

离线评测需要覆盖正常样本、困难样本、边界样本和恶意输入。指标不能只看模型最终文本是否“看起来合理”。

可以分别评估:

  • 意图识别准确率;
  • 结构化字段正确率;
  • 图片目标定位准确率;
  • 工具参数合法率;
  • 事实引用准确率;
  • 拒答和降级正确率;
  • 端到端任务完成率。

线上还要关注:

  • 首次响应时间;
  • 完整任务耗时;
  • 用户重试率;
  • 用户修改率;
  • 人工接管率;
  • 崩溃率;
  • 单次请求成本;
  • 不同设备和网络环境下的成功率。

对于生成结果,最好结合规则检查、模型评审和人工抽检,不要只依赖一个自动评分。

9. 如果客户端请求 AI 服务时网络断开,如何保证用户体验和服务端状态一致?

首先需要区分请求是否已经到达服务端。客户端断网并不代表服务端没有执行成功。

对于查询类请求,可以安全重试,但应携带请求 ID。对于创建、修改或扣费类操作,必须使用幂等键,重新请求时先查询原请求状态。

客户端可以维护如下状态:

CREATED -> SENDING -> UNKNOWN
                  -> SUCCESS
                  -> FAILED

进入 UNKNOWN 时,不能直接显示失败,也不能盲目重复提交。应优先调用状态查询接口,根据服务端记录恢复最终状态。

网络请求还要设置连接超时、读取超时和总超时。重试需要指数退避,并且不能让多个页面同时对同一个操作进行重复提交。

10. 如何设计高并发用户行为数据上报系统,保证数据尽量不丢失且不会无限阻塞客户端?

客户端不应该为每次点击都同步等待服务端响应。可以采用本地批量队列,将事件暂存后批量上报。

客户端需要考虑:

  • 本地队列容量限制;
  • 事件优先级;
  • 网络状态;
  • 批量大小;
  • 重试次数;
  • 数据过期时间;
  • 应用异常退出时的恢复;
  • 敏感字段脱敏。

服务端接收后先进行快速校验,再写入消息队列,由后续消费者异步处理。对于关键事件,可以设置更高优先级和更长保存时间;普通曝光事件则允许采样或丢弃。

事件必须携带唯一 ID,服务端需要通过幂等表或去重缓存避免重复统计。

11. 实时高优先级事件和大批量普通事件同时上报时,如何避免普通数据挤占关键数据的资源?

不能让所有数据共用一个无界队列。可以按照优先级拆分通道:

  • 高优先级事件使用独立队列和连接池;
  • 普通事件采用批量异步上报;
  • 高峰时优先保留关键事件;
  • 普通事件达到上限后进行采样或丢弃;
  • 消费端也按照优先级分配线程和资源。

服务端可以使用多级队列或不同 Topic。生产端需要对队列长度、发送失败率、积压时间和丢弃数量进行监控。

class Event {
    String id;
    int priority;
    long timestamp;
    byte[] payload;
}

class EventBuffer {
    private final BlockingQueue<Event> critical =
本篇目录
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 07
  8. 08
  9. 09
  10. 10
    追问
    实时高优先级事件和大批量普通事件同时上报时,如何避免普通数据挤占关键数据的资源?

同作者面经

展开其余 5 篇收起其余 5 篇

相关公司