Hiyaa.AI Android 项目深挖面试知识点整理

整理自项目模拟面试,覆盖流式消息处理、HTTP streaming、Markdown 渲染、角色配置、FCM 拉活、模型微调与评估


一、项目里核心的 AI 问答消息是如何处理的

一句话

发送侧做了什么

  1. 用户发送消息后,不是只把当前一句话直接发给服务端
  2. 会先从本地会话库里取最近一段上下文消息
  3. 再拼上当前用户输入、角色对应的 system promptroleIdmodelId
  4. 最后带上 stream=1 发到聊天接口

为什么这样做

接收侧做了什么

状态管理

落库策略

这样设计的价值


二、HTTP streaming、SSE、WebSocket 的区别与取舍

先说结论

三者区别

方案 通信模型 适用场景 特点
HTTP streaming 单次 HTTP 请求,服务端持续写响应体 AI 问答、长文本生成 接入成本低,和现有 HTTP 体系兼容
SSE 基于 HTTP 的单向事件流 服务端持续推文本/事件 比较标准化,适合单向流式输出
WebSocket 双向长连接 IM、协同编辑、强实时双向交互 更灵活,但连接管理复杂

为什么项目里优先选 HTTP streaming

trade-off


三、OkHttp 为什么能持续读取流,readTimeout 有什么影响

原理

readTimeout 的含义

在流式 AI 场景里的影响

更合理的做法


四、用户点击 Stop 之后会发生什么

客户端侧

服务端侧

为什么没有直接 cancel OkHttp Call


五、HTTP/1.1 chunked transfer 和 HTTP/2 streaming 的区别

HTTP/1.1

HTTP/2

对业务层的意义


六、Markdown 渲染是如何做的

一句话

基本链路

  1. parse(md) 把 Markdown 解析成 AST
  2. render(node) 把 AST 转成 Spanned
  3. setParsedMarkdown(...) 设置到 TextView

为什么选这条路线

做了哪些增强

设计模式角度可以怎么讲

Spanned 能不能做复杂 Markdown


七、角色配置是怎么实现的

设计思路

角色公共配置

数据来源

为什么要本地预置 + 远端拉取

用户个性化配置

聊天时如何消费


八、FCM 拉活推送是怎么做的

链路拆分

  1. 应用初始化时获取 fcmToken
  2. 把 token 同步给业务服务端
  3. 订阅拉活 topic
  4. Firebase 收到消息后回调 FirebaseMessagingService
  5. action 分发到不同推送处理器
  6. 组装通知内容并展示
  7. 用户点击通知后跳转到目标角色聊天页

为什么 FCM 能做拉活

data message 在应用死掉后还能不能收到

拉活推送里的客户端策略

这样做的价值


九、微调模型的数据怎么来,怎么做,怎么评估

数据来源

  1. 真实业务里的高质量对话样本
  2. 人工整理过的角色设定、首句、system prompt 等配置数据
  3. AI 辅助生成的对话初稿,再做人工筛选和清洗
  4. 安全和负向样本,例如 NSFW、拒答、越界约束数据

为什么要准备训练集和验证集

微调方式上怎么讲更稳妥

数据处理会做什么

怎么判断微调效果

离线

在线

面试里怎么收口


十、一句话速记

知识点 速记
AI 流式消息 本地组装上下文,HTTP 流式接收,chunk 增量渲染,结束统一落库
HTTP streaming 仍然是 HTTP,不是 WebSocket;请求一次,响应持续写
OkHttp 读流 ResponseBody 是可持续消费的字节流,持续 read() 即可
Stop 处理 当前实现更偏客户端软中断,保留部分结果,不等于服务端瞬时停算
Markdown 渲染 Markwon 把 Markdown AST 转成 Spanned,原生 TextView 渲染
角色配置 公共角色配置 + 用户个性化配置,两层解耦
FCM 拉活 借系统推送通道触达用户,再通过通知点击把访问拉回 App
模型微调 重点是数据处理、格式转换、部署和批量效果评估