L4 / SDE · OOD

Amazon OOD:Keyboard + Mouse 输入系统怎样设计?

先用有序事件流表达键盘与鼠标输入,再拆设备适配、状态与订阅处理。

题目重点:先用有序事件流表达键盘与鼠标输入,再拆设备适配、状态与订阅处理。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练处理设备适配器已产生的结构化事件:keyboard down/up与mouse move/button,目标读取并分发而非实现驱动。
  • 事件包含device_id、sequence、timestamp、类型和载荷;单设备sequence单调,跨设备不承诺物理全序。
  • 文本输入、输入法组合与快捷键可作为后续需求,不能用keycode直接宣称得到用户文本。

解题路线

  1. 先明确功能边界,InputEvent为不可变事件、DeviceAdapter把原生事件转通用形式,InputHub接收/排队/分发,InputState保留按住键与鼠标状态;不要为每个键建一套继承树。
  2. Hub分配接收序号保证本进程重放顺序,同时保留设备sequence。重复事件按(device,sequence)去重,乱序是否缓冲或拒绝需有策略;timestamp只能作观测,不能保证真实全局先后。
  3. 键盘down/up维护pressed set,repeat down不能被误判成多次新按下;失焦或设备断开要清理或标未知,避免永久“按住”。鼠标坐标需声明屏幕/窗口坐标与缩放。
  4. 监听器接口接收事件,不直接修改事件源;取消订阅、异常隔离、重入新增listener用快照或队列控制。慢监听器不能阻塞设备适配,队列需要容量和背压。
  5. mousemove可合并到最新位置,但keydown/up和button边沿不能随意丢弃,否则state不一致。若队列溢出,发显式重同步信号,不默默表现为用户没按键。
  6. 测试从输入→state→订阅输出重放:down/up/重复、断连、并发订阅取消、慢consumer与错误listener,验证是否漏边沿和能否重建。

手动走一遍

训练事件A seq1 keydown Shift、seq2 keydown A、seq3 keyup A、seq4 keyup Shift,pressed依次{Shift}、{Shift,A}、{Shift}、{};down A不等于文本“A”,输入法或布局需另由text事件表示。

规模与取舍

每事件更新状态期望O(1),分发O(L)监听者;队列O(Q)、按键状态O(K)。训练假设1000事件/秒、100字节/事件,仅载荷约0.1MB/秒,不含对象与排队开销;规模不是题目条件。

易错点与追问

容易失分的边界

  • keycode当最终文本。
  • 设备时间戳强行排序作全局真相。
  • 合并或丢弃keyup造成卡键。
  • 异常listener阻塞所有输入。

继续深挖

  • 多个键盘同时按同一键怎样记来源?
  • 快捷键配置和输入法应位于哪层?
  • 设备断开时怎样重建状态?
✓已复制微信号!