Senior SWE · Onsite Mixed Coding/System Design

Apple 并发图片上传:内存存储与即时状态更新

把不断收窄的面试约束转为可讨论契约,解释线程生命周期、状态机、背压和状态推送。

题目重点:把不断收窄的面试约束转为可讨论契约,解释线程生命周期、状态机、背压和状态推送。

题意与假设

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

  • 将问题分成原始产品目标和面试官最后明确的 RAM toy 约束;不能把 Java WebSocket 实现或云 bucket 当作最终题面。
  • 训练契约是每张图分配 upload_id,状态 QUEUED→RUNNING→SUCCEEDED/FAILED,内存保存 byte[] 的私有拷贝;最大并发/最大总字节须受限,否则原始‘每图一线程’会耗尽资源。

解题路线

  1. 先复述新约束:输入 `List<byte[]>`,输出每张 upload_id 与可查询状态;问清是同步等待还是异步返回、失败如何报告、字节数组是否可被调用方修改。
  2. toy 实现可创建有限数量的 Java Thread,并在提交前把 bytes 拷贝以避免调用方并发修改。每个任务以 try/catch/finally 推进状态,存储成功后再标 SUCCEEDED;状态 map 和 byte map 需线程安全,状态转移单调。
  3. 状态传给用户有轮询、长轮询或 WebSocket 三种接入方式。若产品必须‘尽快’,服务端在每次转移发事件,但仍保留查询接口,供断线恢复;WebSocket 是传输方式,不是上传持久化保证。
  4. 生产方案应限定队列、线程、单图大小和总 RAM;持久资源通常直传对象存储再提交 metadata,RAM toy 在进程重启时丢失全部图,明确可用性边界。
  5. 并发竞态测试包括 0 图、重复上传、调用者修改原 byte[]、某张图异常、乱序完成、客户端断线和进程重启;在没有最终接口前不伪造可运行的‘原题答案’代码。

手动走一遍

用户一次交三张图,A/B 状态先转 RUNNING,C 排队。B 先成功就立即发 B 的 SUCCEEDED 事件,不等 A;前端断线重连后按 upload_id 查询快照。若 RAM 总预算不足,C 应被拒绝/等待,而非盲目再起一条线程。

规模与取舍

n 张图大小合计 B 字节时,复制并存 RAM 需要 O(B) 内存,状态 O(n);若每图单独 Thread 则线程数 O(n),生产必须限制最大并发 W 及队列长度,完成时间受上传/存储速度和最大并发影响。

易错点与追问

容易失分的边界

  • 题目收窄到 RAM byte[] 后仍把云 bucket/WebSocket 当必须实现。
  • 每图创建无限 Thread,缺内存/调度上限。
  • 直接存调用方传入的可变 byte[],后续被修改。
  • 先报 SUCCEEDED 再写入数据,状态与事实不一致。
  • 只推送事件、不保留可查询状态,断线后用户无法恢复。

继续深挖

  • 没有 ThreadPoolExecutor 但要限制并发,你会怎样协调有限 Thread?
  • 状态回调与查询如何避免乱序或过期更新?
  • 如果切换到对象存储直传,成功确认点在哪里?
  • 进程重启后 RAM 数据丢失,如何改变产品承诺?
✓已复制微信号!