腾讯IM
1. 什么是腾讯 IM SDK?与 TUIKit 有什么区别?
回答:
腾讯 IM SDK(又称 Tencent Cloud Chat / IMSDK)是即时通讯的底层能力集合,提供登录、会话、消息、群组、关系链、离线推送等 API。TUIKit 是官方基于 IMSDK 封装的 UI 组件库(会话列表、聊天窗口、群管理等现成页面),用于快速搭建业务界面。
- 何时只用 SDK: 强定制 UI、复杂业务逻辑、轻 UI 场景。
- 何时用 TUIKit: 追求快速上线、默认交互范式可接受。
- 混用策略: 用 TUIKit 搭主流程,关键页面(例如红包、礼物、自定义消息渲染)用 IMSDK 定制扩展。
2. iOS 初始化与登录的关键步骤?
回答:
- 初始化(App Launch)
- 在 application(_:didFinishLaunchingWithOptions:) 中调用:
- V2TIMManager.sharedInstance().initSDK(sdkAppID, config: V2TIMSDKConfig)
- 设置日志级别、数据库路径、是否上报、V2TIMSDKListener 等。
- 签发 userSig(必须服务端生成)
- 基于 SDKAppID + userID + 私钥 用 HMAC-SHA256 生成,客户端只拿到短期凭证。
- 登录
-
V2TIMManager.sharedInstance().login(userID, userSig, succ, fail)
-
监听 onConnecting/onConnectSuccess/onConnectFailed 与 onKickedOffline。
常见坑:
-
userSig 绝不能在客户端生成;过期(默认 7 天或按你服务端策略)要及时刷新。
-
同一 userID 多端同时在线策略可配置(例如“允许多端”、“后登踢前”等)。
-
时钟漂移会导致签名校验失败,要确保服务器与客户端时间一致(NTP)。
3. 会话(Conversation)模型与 ID 规则?
回答:
-
会话用于聚合消息与未读计数,类型分 C2C 与 Group。
-
conversationID 规范:
- C2C:c2c_userID
- Group:group_groupID
-
通过 V2TIMManager.getConversationManager() 获取列表、订阅变化,使用 V2TIMConversationListener 监听增删改、未读数变化。
未读计数策略:
-
拉活或前台时调用 markC2CMessageAsRead / markGroupMessageAsRead;后台切前台可适时清零焦点会话未读,避免红点不同步。
常见坑:
-
自己造会话缓存易与 SDK 本地库不一致,尽量依赖 SDK 会话变更回调驱动 UI。
-
会话置顶/草稿等属性更新要落地本地存储,否则重启丢失。
4. 消息类型与发送流程(含自定义消息)
回答:
-
常见类型:文本、图片、语音、视频、文件、表情、自定义(V2TIMMessage.elemType == .custom)。
-
发送:先构建 V2TIMMessage,设置优先级、离线推送配置,再调用 sendMessage,监听进度与回执。
-
自定义消息:setCustomElemData(_:) 塞入二进制(建议 JSON 编码),同时规范化离线推送的 title/desc/ext 以便 APNs 展示。
可靠性要点:
-
消息唯一 ID 与本地临时 ID 区分(发送前后 ID 变化导致“二次渲染”问题)。
-
断网重试与超时重发:利用 SDK 内置重试;UI 上给“发送中/失败重发”。
-
消息顺序:SDK 内部按 seq 排序,UI 只需按 timestamp/seq 合并;不要仅靠客户端时间。
5. 历史消息拉取与分页策略
回答:
-
使用 getHistoryMessageList(按 anchorMessage + count + direction)分页拉取。
-
双端一致性:以服务器为准,SDK 本地库做缓存;撤回、删除等事件通过回调修正 UI。
-
上滑加载:记录最早一条消息作为新的 anchor;避免一次拉太多导致内存峰值。
常见坑:
-
多窗口并行拉取要合并去重(按 msgID 或(seq, rand))。
-
图片/视频消息缩略图与多清晰度预取策略要结合网络状态与首屏时间做权衡。
6. 消息撤回、编辑、删除与已读回执
回答:
- 撤回:revokeMessage,对方收到撤回系统提示;通常允许“消息发送后 N 分钟内”。
- 编辑:部分形态通过“发送一条新消息 + 关联原消息 ID”模拟;或使用 SDK 提供的“二次编辑接口”(视版本)。
- 删除:分本端删除(不影响对端)与全局删除(需要后台能力配合)。
- 已读回执:
-
C2C 支持单聊已读,调用 sendC2CReadReceipt 或 markC2CMessageAsRead。
-
群聊回执通常只对小群/工作群开放,大群/直播群不建议逐条回执。
面试点:说明“回执风暴”问题与限流:大群中应禁用或做聚合回执。
-
7. 群组类型与典型场景(Public/Work/Meeting/AVChatRoom 等)
回答:
-
Work(私有/工作群):成员可见、适合组织沟通;支持更丰富的管理与回执。
-
Public(公开群):需要申请加入,适合兴趣社区。
-
Meeting:临时会议群,进出自由,历史消息可见策略灵活。
-
AVChatRoom(直播大群):超大规模、弱一致、仅保留少量消息/不产生未读,适合弹幕、直播间聊天。
关键差异:成员上限、入群审批、消息存储/未读策略、禁言/白名单、属性变更通知频率。
踩坑:选错群型会导致未读爆炸或能力受限,例如直播间绝不要用 Work 群。
8. 离线推送(APNs)与在线推送策略
回答:
-
iOS 端注册 APNs,SDK 维护 deviceToken;后台透传离线推送载荷(title/desc/ext)。
-
免打扰:按会话/群维度关闭推送或仅保留角标。
-
前台在线推送:前台通常不走 APNs,使用 V2TIMAdvancedMsgListener 直接刷新 UI。
-
VoIP/音视频通话:可配合信令(TRTC/RTC)使用 VoIP Push(CallKit),务必区分生产/开发证书与环境。
常见坑:
-
混用生产/开发证书导致收不到;
-
后台杀进程时仅依赖在线回调会丢提示,必须依赖 APNs;
-
推送文案需落地到自定义消息 ext 字段,才能跨平台一致显示。
9. 关系链与资料(资料卡、好友、黑名单、分组、标签)
回答:
- 资料:昵称、头像、个签、自定义字段(需在控制台配置);拉取缓存 + 监听变更。
- 好友:双向关系,支持申请/同意、分组、备注;
- 黑名单:拦截消息与申请。
- 标签/分组:面向运营与灰度(如精细化推送、分层通知),可配合后台维护。
10. 自定义表情/富文本与消息渲染
回答:
- 图片/表情:统一走图片消息或自定义消息(约定 type + payload)。
- 富文本:通常前端渲染 Markdown/HTML 解析,但强烈避免原生 HTML 直渲染,改用“结构化消息”(安全 & 跨端一致)。
- 消息高亮与跳转:自定义字段附带 action(schema 跳转参数),收端按协议处理。
11. 多端同步与设备在线状态
回答:
- 登录策略:单终端/多终端同时在线可配置。
- 自定义在线状态:可周期上报状态(如“忙碌/直播中”),好友端订阅在线变化。
- 冲突处理:后登踢前时需要在 UI 显示“被踢下线”,引导重新登录或切换账号。
12. 音视频与信令(与 TRTC 的关系)
回答:
- IM 负责信令与消息,TRTC 负责实时音视频。
- 呼叫流程:IM 自定义信令/或官方信令扩展 → 对端接通 → 进入 TRTC 房间 → 会中用群或房间内消息同步状态。
- 弱网策略:信令重发、超时回落到文本提示;通话中断线由 TRTC 重连,IM 同步状态。
13. 性能优化与大规模会话/消息管理
回答:
- 首屏:优先加载最近活跃 N 个会话;消息列表做增量渲染与高度缓存。
- 图片/视频:缩略图优先、原图懒加载;磁盘缓存清理策略(LRU + 总量阈值)。
- 大群:禁用未读、限制@全体频率、服务端节流系统消息广播。
- 数据库:SDK 内置本地库,避免在主线程做大量 I/O;分页严格控制量级。
- 崩溃与日志:打开 SDK 日志并上报,精确定位发送/拉取/解析阶段。
14. 常见错误码与定位思路
回答:
-
签名相关(userSig 过期/非法):检查服务器时间、私钥、SDKAppID 是否匹配。
-
频控/限流:高频发送、撤回、群广播触发;需退避重试或提升配额。
-
权限不足:群管理员/成员角色不符;控制台开关未启用。
-
推送收不到:证书/环境不匹配、topic 未配置、应用被系统限制通知。
定位策略: 端侧 SDK 日志 + 后台请求链路 + 最小可复现场景(单一用户、单一群、单一消息类型)逐步收敛。
15. 安全与合规(风控、审核、加密)
回答:
- 敏感词审计:可用云端审核(文本/图片/音视频)或接入自有风控;对命中内容做拦截、替换或仅标记。
- 敏感信息保护:自定义消息 payload 做加密(例如 AES-GCM),仅在会话内解密。
- 隐私合规:尽量减少在消息体携带个人隐私字段;对可选字段做最小化收集与脱敏存储。
16. 与业务系统的典型集成点
回答:
- 账号体系:将业务 userID 与 IM userID 对齐(或维护映射),登录态统一。
- 订单/客服:自定义“卡片消息”(订单卡、客服入口)、机器人问答接入(FAQ → 人工)。
- 直播/社交:礼物弹幕走 AVChatRoom,自定义消息携带礼物信息;离线时通过 APNs 简版提示。
- 运营活动:通过关系链标签/服务端标签做分层运营与灰度开关。
17. 如何设计自定义消息协议,保证跨端一致与可演进?
回答:
- 约定统一结构:{ "version": 1, "type": "gift", "payload": { ... }, "display": { "title": "...", "desc": "..." } }
- 版本前向兼容:未知 type 走“兜底渲染”(纯文本/占位符),避免崩溃。
- 资源 URL 走 CDN,带宽/格式自适应(WebP/HEIF);离线推送复用 display 字段。
- 在文档库沉淀协议手册与样例消息,配合单元测试与回放工具。
18. 典型面试追问:为什么 userSig 必须服务端生成?如何安全落地?
回答:
- userSig 含有 SDKAppID 与私钥签名,一旦泄露私钥,攻击者可伪造任意 userID;
- 正确做法:
- 客户端登录业务服务器 → 服务器校验身份后 签发短期 userSig(TTL 可控、可撤销) → 客户端再用 userSig 登录 IM;
- 结合 HTTPS + 设备指纹 + 频控 降低撞库、批量刷号风险;
- 定期轮换私钥并灰度升级。
19. 如何做消息表情反应(reaction)/消息扩展(extensions)类能力?
回答:
- 若 SDK 版本未内置,可用 自定义消息 + 合流统计:对某条消息发送“reaction 变更”指令,服务端聚合计数并回推最新汇总,客户端按消息 ID 合并展示。
- 大群需限流与去抖,防止刷屏与服务器压力;UI 做本地乐观更新,失败回滚。
20. 从零接入到上线的最小闭环 checklist
回答:
- 控制台:创建应用(SDKAppID)、生成测试 key、开通所需能力。
- 服务端:实现登录鉴权与 userSig 签发、黑白名单、基础审计。
- 客户端:初始化 → 登录 → 会话列表 → 聊天页(文本、图片、自定义) → 未读/推送 → 退出登录。
- 测试:多端互通、弱网、杀进程、证书环境切换、边界(撤回/回执/禁言/踢人)。
- 监控:SDK 日志、崩溃、消息成功率、APNs 送达率、关键接口耗时。
21. 常见与面试相关的代码片段(Swift 简化示例)
回答:
// 1) 初始化
let cfg = V2TIMSDKConfig()
cfg.logLevel = .LOG_INFO
V2TIMManager.sharedInstance().initSDK(UInt32(sdkAppID), config: cfg, listener: self)
// 2) 登录
V2TIMManager.sharedInstance().login(userID, userSig: userSig, succ: {
print("IM login ok")
}, fail: { code, msg in
print("IM login fail \(code) \(msg ?? "")")
})
// 3) 发送自定义消息
let msg = V2TIMManager.sharedInstance().createCustomMessage(Data(
#"{ "version":1, "type":"gift", "payload":{ "id":"rose", "count":1 }}"#.utf8))
let offline = V2TIMOfflinePushInfo()
offline.title = "你收到一个礼物"
offline.desc = "玫瑰 x1"
V2TIMManager.sharedInstance().send(msg, receiver: "peerUserID", groupID: nil,
priority: .PRIORITY_NORMAL, onlineUserOnly: false,
offlinePushInfo: offline, progress: nil, succ: {
print("sent")
}, fail: { code, msg in
print("fail \(code) \(msg ?? "")")
})22. 如何回答“为什么选腾讯 IM 而不是自建 IM”?
回答:
- 成本与时间:长连接、路由、消息存储、离线推送、跨区容灾、弱网重连等自建成本高、稳定性难保障。
- 全球节点:跨境延迟与可用性。
- 配套生态:TRTC、云点播、内容审核、AI 能力等组合拳。
- 劣势/取舍:深度定制受限、费用预算需评估、部分能力需按量付费。
- 给出混合架构方案:核心消息走云 IM,业务私密数据/风控走自建服务,形成清晰边界。
23. 线上问题快速排查 SOP
回答:
- 明确范围:单人/多人、单群/多群、单类型/多类型、单端/多端。
- 看日志:端侧 SDK 日志 + 网关时间线;核对 userSig 时间戳与环境。
- 回放重现:最小场景(一个群、一种消息),抓包校验重试与错误码。
- 灰度回滚:关闭可疑开关(例如大群回执),退回稳定版本。
- 复盘固化:问题标签化、用例补齐、告警与看板指标化(成功率、耗时、离线到达率)。
24. 面试高频“坑点”快速答
回答:
-
Q:消息乱序?
A:UI 以 seq/timestamp 排序,避免用本地时间;服务端合并与 SDK 已保证最终有序。
-
Q:直播间未读爆表?
A:直播场景使用 AVChatRoom,其策略是“不计未读”。
-
Q:APNs 收不到?
A:检查证书环境、deviceToken、topic、是否被系统关闭通知;后台杀进程时必须依赖 APNs。
-
Q:userSig 安全?
A:服务端签发 + 短期 TTL + 频控 + 私钥轮换;客户端永不内置私钥。
-
Q:自定义消息跨端不一致?
A:制定协议文档与版本,未知类型走兜底渲染。
25. 给架构面的延伸题(简答点到为止)
回答:
- 弱网优化:断线重连指数退避、图片分辨率自适应、发送队列序列化。
- 多租户/多业务线:按 SDKAppID 或逻辑租户隔离,消息协议前缀区分业务。
- 灰度开关:服务端下发策略(回执开关、推送样式、资源域名),SDK 端热更新读取。
- 合规:日志脱敏、用户数据可导出/可删除、审核与仲裁链路留痕。