SWE Phone / VO Coding(不同帖) · Coding / Concurrency

Anthropic 图片处理:JSON 顺序流水线、输入复用与进程池

把 m 张图与 n 个转换流水线的笛卡儿积落地到文件输出,解析六类操作、顺序语义和大小图片的并行扩容。

题目重点:把 m 张图与 n 个转换流水线的笛卡儿积落地到文件输出,解析六类操作、顺序语义和大小图片的并行扩容。

题意与假设

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

  • 训练版一条 pipeline 是有序操作列表;不同 pipeline 独立地从原始图开始,而不是从上一条 pipeline 的结果继续。
  • 题目说输出路径有现成 util,因此文章不编造真实命名规范;训练版需用 `(image_id,pipeline_id)` 生成唯一文件名,避免并发覆盖。
  • scale、blur、rotate 的参数取值/插值/边缘填充/颜色模式应由实际 JSON 和评测给定;本文只给控制流与库调用核对方式,不声称 Pillow 某默认值就是原题答案。

解题路线

  1. 先用一张 small image 和一条含多步的 JSON pipeline 建立黄金输出;按 JSON 顺序验证每步是否产生新的图像对象、是否改变尺寸/颜色模式、是否需要 RGB/RGBA 转换。
  2. 把处理定义为纯任务 `transform(image_bytes, pipeline_spec)→output_bytes`。若每张图要跑 n 条 pipeline,可在同一 worker 中解码一次原始图,然后对每个 pipeline 从原图 copy 开始,避免重复磁盘读和解码;若 worker 按 `(image,pipeline)` 切分,简化调度却可能重复读图。
  3. 对 small images 先串行产出 m×n 文件,断言个数、尺寸、关键像素和操作顺序;再对 big images 计量读盘、解码、变换、编码和写盘分段时间。只有 CPU 成为瓶颈时进程池才可能绕开 Python GIL;若 I/O 或库自身释放 GIL 更重要,线程池可能省跨进程序列化开销。
  4. 并行时只把可序列化的路径/规范提交 worker,或者在按图分组的 worker 内复用原图;父进程做任务枚举和结果收集。临时文件写完再原子发布,失败时输出可重试且不会留部分成品。限制同时在内存的解码图数量,尤其大图多进程会放大内存。

手动走一遍

训练例 2 张图、3 份 JSON,每份各有 2 步,共生成 2×3=6 张输出。Pipeline A 为水平翻转再旋转,Pipeline B 为灰度再模糊;B 必须从原始图开始,不能把 A 的旋转结果继续处理。若一张大图解码后占 200MiB、4 个进程各持有两份拷贝,光像素缓冲就可能接近 1.6GiB,尚未计编码缓存。

规模与取舍

设 m 张图、n 条 pipeline、第 j 条长度 k_j、单张图像像素数 P。至少要读/生成 m×n 个输出;朴素 CPU 工作约 O(mPΣk_j),具体操作有不同常数与插值成本。按图复用解码可把输入读取从 O(mnP) 字节趋近 O(mP),输出写入仍是 Ω(mnP_out);并行峰值内存约 O(workers×每任务同时驻留的图像缓冲)。

易错点与追问

容易失分的边界

  • 多个 JSON 操作不按顺序执行,或把所有 pipeline 串成一条。
  • 复用同一个可变图像对象,让前一个 pipeline 的处理污染后一个。
  • 只看 m×n 文件数,不校验像素、尺寸、模式和顺序。
  • 无界进程数/任务队列导致大图解码放大内存。
  • 假设所有 Pillow 操作都 CPU bound;应按分段实测选择线程或进程。

继续深挖

  • 如何设置输出文件的原子发布和失败重试,使局部失败不重复写错文件?
  • 大图不能全部放内存时,哪些操作可分块,旋转/模糊需要怎样的边界 halo?
  • 相同 pipeline 被大量图片复用时,如何缓存解析后的规范但不共享可变图像?
✓已复制微信号!