SDK 设计题怎么从需求讲到架构
一句话先讲清楚
SDK 设计题最怕一上来就报模块名。更好的讲法是,先讲这个 SDK 要解决什么问题,再讲约束,再讲分层和扩展点。
一个通用回答框架
我一般会按这个顺序讲:
-
先讲目标
这个 SDK 到底是做什么的,解决谁的问题。 -
再讲约束
比如要不要跨框架、能不能影响业务性能、数据能不能丢、接入成本高不高。 -
再讲分层
哪些能力放核心层,哪些放适配层,哪些做成插件。 -
再讲关键链路
数据怎么采、怎么处理、怎么上报、怎么兜底。 -
最后讲取舍
为什么这样拆,代价是什么,后面怎么扩。
30 秒版本
SDK 设计题我一般不会直接从代码结构讲,而是先讲目标和约束。比如监控 SDK 要解决的是观测问题,埋点 SDK 要解决的是业务行为数据问题,但它们都有几个共同约束,比如不能影响业务、要控制接入成本、要支持后续扩展。讲清楚这些以后,我再往下拆核心层、环境适配层、插件层和上报链路。这样面试官会觉得你是在做系统设计,而不是在背一个目录结构。
1 分钟版本
如果面试里让我设计一个 SDK,我通常会先把问题重新定义一下,而不是直接说我要拆几个包。因为 SDK 设计本质上不是模块划分题,而是约束下的系统设计题。
我一般先讲三个东西。第一,这个 SDK 的核心目标是什么,比如监控 SDK 更偏观测,埋点 SDK 更偏业务分析。第二,它有哪些硬约束,比如不能明显影响业务性能、要支持多框架、接入成本要低、数据链路要稳定。第三,它未来一定会扩展什么能力,比如监控会继续加白屏、行为、接口耗时,埋点会继续加自动采集、事件治理、领域事件。
讲完这些以后,我再开始拆层。一般会有一个核心层,放初始化、事件模型、插件机制和 transport 抽象;一个环境适配层,处理浏览器或框架差异;再加一层插件层,把错误采集、性能采集、行为采集这种能力做成可插拔模块。最后再讲关键链路,比如采集、清洗、队列、批量上报、页面退出兜底。
这样讲的好处是,你不是在背“我有 core、browser、utils”,而是在讲为什么这些东西要这么拆。
2 到 3 分钟版本
我觉得 SDK 设计题最容易答偏的地方,是一上来就进入实现细节,比如“我会封装一个类”“我会监听一个事件”。但面试官真正想看的是,你有没有先建立设计问题。
所以我通常会先说,这类题我会先明确两个层面。第一个层面是业务目标,这个 SDK 最终要给谁用、解决什么问题。比如监控 SDK 是为了观测系统健康和用户体验,埋点 SDK 是为了沉淀业务行为数据和转化分析。第二个层面是工程约束,比如不能明显拖慢页面、要兼容不同框架、要支持灰度接入、要有后续扩展空间。
接着我会从架构分层去拆。一般会有一个核心层,负责统一初始化、生命周期、事件模型、插件注册、transport 抽象;一个适配层,处理浏览器、React、Vue 或其他环境差异;一个插件层,把错误监控、性能监控、行为采集、埋点规则这些能力做成 integration。这样核心层不被具体能力污染,扩新能力时也不用去改最底层流程。
再往下,我会讲关键链路。也就是数据从哪里来,经过哪些处理,最后怎么发出去。通常会包括采集、标准化、上下文补充、队列缓存、批量上报、失败兜底。这里我会特别强调,SDK 不能只考虑“采到了”,还要考虑“业务不能受影响”,所以像批量、采样、限流、
sendBeacon、有限重试这些都要在这一层考虑。最后我会补一句取舍。比如为什么要插件化,因为需求一定会扩;为什么核心层不依赖框架,因为要保持稳定;为什么要统一事件模型,因为后续存储、查询和分析都依赖它。这样整套回答会更像一个成熟的设计过程,而不是在背答案。
所以如果让我总结,SDK 设计题不是“你会不会拆文件夹”,而是“你能不能先把需求、约束、分层、链路和演进路线讲清楚”。
一个万能答题骨架
你可以直接套这个:
这个 SDK 我会先从目标和约束入手。目标上,它主要解决 X;约束上,它需要满足 Y。基于这个前提,我会把它拆成核心层、适配层和插件层。核心层负责统一模型和生命周期,适配层处理环境差异,插件层承接具体能力。数据链路上再做采集、标准化、队列、批量上报和兜底。这样拆的好处是扩展性和可维护性更好,代价是前期抽象会重一点,但对 SDK 这种长期演进型项目是值得的。
最后一句收尾
所以 SDK 设计题最重要的不是“我能写出来”,而是“我能把为什么这样设计讲清楚”。