题干与适用场景
运行时、租户隔离和执行预算已经存在。本题只讨论兼容与组合:数百个已安装组件实现了不同代际的 WebAssembly Interface Types(WIT),一次工作流还会串联解析、脱敏和导出组件。请设计兼容层,让平台能改接口、组合组件并安全淘汰旧版本。
WIT 只定义契约,不定义行为;world 会列出组件的导入和导出,Component Model 允许把组件组合起来。这些机制让兼容性可以检查,但不会替平台决定哪些变更安全、组合图最终能拿到什么权限。
面试官考察点
- 能否区分源码兼容、WIT 结构兼容和业务语义兼容。
- 能否逐项授权组合图的导入,避免一个插件借另一个插件扩大权限。
- 能否让适配器有版本、可观测、可下线,而不是永久隐式逻辑。
- 能否处理资源所有权和状态,使回滚真正可执行。
回答前需要澄清的问题
- 需要兼容哪些已安装版本,支持期多长?
- 调用传递的是无状态值、流,还是 owned/borrowed 资源句柄?
- 插件可否直接调用插件,还是必须经过宿主?
- 变更只是增加字段,还是改变错误、默认值或所有权?
- 整条工作流必须原子回滚,还是组件可分别升级?
无状态值通常可以内联适配;资源所有权变化往往需要新主版本和迁移。只有链接阶段能证明最终导入仍在租户授权内,才适合直接组合。
30 秒回答框架
“我会把每个 WIT package 和 world 按不可变版本登记,提取导入、导出、类型和资源所有权,再在实例化前检查组合图。旧插件继续运行旧契约;小型适配器可以转换旧值,但不能凭空增加权限,也不能悄悄改变失败语义。宿主只授予租户策略与组件声明权限的交集。发布前用固定样本对照新旧图,再按租户灰度,并保留旧图直到回滚和下线门槛都通过。”
分步骤深入解答
第一步:建立接口注册表和兼容报告
登记 WIT 包版本、world、导入导出、类型、资源所有权、制品摘要和适配路径。发布时与所有受支持前代比较。增加可选字段可能可适配;删除 variant 分支、改变错误含义或把 borrowed 句柄改成 owned 资源,都需要明确迁移。
第二步:把适配器限制为单向小转换
适配器只处理一对已知契约,可以改字段名、填入有文档的默认值或映射错误。无法安全表达的数据必须拒绝。尽量只允许一跳适配;多层链路会放大歧义,也让回滚难以解释。
第三步:对完整组合图做能力授权
链接前解析每个导入的提供者,生成最终能力清单。宿主再按租户和插件授权检查文件、网络、时钟、随机数或业务服务接口。脱敏插件不能因为和导出插件组合就得到网络权限。高权限调用继续经过宿主接口,便于统一执行策略和审计。
第四步:用行为证据决定是否退役
让新旧图跑同一组确定性样本,对照类型化输出、错误、资源创建与释放、宿主调用和资源预算。安全时再影子处理真实请求,并按租户灰度。回滚切换到上一份兼容图;存在有状态句柄时要先排空或迁移。
高质量示范回答
“我会把 WIT world 当作可部署契约。注册表中的每个不可变条目记录包版本、完整导入导出、类型结构、资源所有权、制品摘要和受支持前代。只涉及值的增量变更可以用一个受审查的适配器;所有权变化、缺失的 variant 分支或新增副作用必须发新契约并迁移调用方。
组合由版本化图描述。链接器负责解析提供者,宿主另外检查完整导入集合。权限上限同时受租户策略和各组件声明约束。上线前用固定样本对照值、错误、宿主调用和资源生命周期,再按租户灰度。旧图保留到不匹配率、错误率、延迟和资源泄漏都过线。这样回答的是接口演进与安全组合,不会重复通用插件沙箱设计。”
常见错误
- 把所有新增项都视为兼容 → 新导入或新默认值也会改变行为 → 分别检查类型、权限、所有权和语义。
- 组合时合并全部权限 → 低权限组件借到高权限能力 → 按组件与租户授权校验完整图。
- 无限串联适配器 → 实际行为依赖不透明链路 → 限制跳数,并依据使用量退役。
- 只比较成功输出 → 错误、宿主调用和资源泄漏仍可能回归 → 同时比较副作用和生命周期。
- 有状态组件直接切回旧版 → 活跃句柄可能属于新契约 → 先排空、迁移或固定会话。
追问及应对
新版本要求额外网络权限怎么办?
把它当成权限变更,发布新组合图并让租户管理员明确授权。未授权的已安装实例继续使用旧契约。
旧值无法表示成新类型怎么办?
适配器返回类型化的不兼容错误,受影响样本或租户停止灰度。编造默认值会隐藏数据损失,应改用迁移工具或并行主版本。
如何下线适配器?
按版本记录安装调用方、真实调用量、不匹配率和最后使用时间。先停止新安装,再迁移存量并保留回滚窗口;确认没有受支持组合图引用后才删除。
组件能否绕过宿主直接互调?
导入和资源语义明确时可以静态组合,但文件、网络等特权能力仍由宿主接口提供。授权、配额和审计才能落在平台可控边界。