cswork / libraryOpen practice workspace

Articles · Meta

Meta 软件工程师面试准备:Coding、设计与 BQ 的证据清单

Meta 软件工程师面试准备指南:先确认一般 SWE、前端、ML 或其他邀请的范围,再分别建立 Coding、设计与 BQ 证据。通过时间窗口变体、照片权限与分页失败路径、个人贡献回答,检查契约、不变量、缓存一致性和项目责任。区分版本未确认的指南镜像与历史工程背景,不推定所有岗位有固定轮次、时长或 AI 工具权限。

准备 Meta 软件工程师面试,最有用的不是一张“刷完多少题”的清单,而是三类能够被追问的证据:Coding 能解释为什么正确,设计能说明失败时怎样工作,BQ 能分清你自己的决定与团队的成果。先确认邀请对应的岗位、级别和面试类型,再用陌生变体检验这些证据。

本文面向准备一般 SWE 面试的中文读者,不替前端、ML、Production Engineering 或 AI-enabled 邀请推定相同流程。你可以用 Meta Software Engineer questions挑选练习,但候选人报告题是训练材料,不是下一次面试的题目预测。

先确认面试类型,不从一篇面经推导整个流程

可公开读取的 Meta SWE Full Loop Guide 镜像将 Coding、Design 与 Behavioral 分开介绍。不过,这是第三方托管的原始文档副本,本次无法独立确认其修订版本,也未能读取当前官方 Careers 准备页。因此,本文采用它的准备维度,不将其中的轮数、时长或工具说明当作所有当前岗位的规则。

面经中的“设计”也不是一个充分精确的标签。产品接口、客户端交互与后端容量讨论需要不同的证据。向招聘方确认你收到的是 system design、product architecture、专业方向设计,还是另一个名称;同时确认是否需要运行代码、可用语言与工具,以及是否允许指定 AI 功能。没有明确许可,按独立完成准备。

保存一份小的邀请记录即可:职位链接、岗位方向、通知日期、轮次原名、已确认工具、仍待问的问题。看到另一位候选人描述某个环节时,先对照角色和年份。这里不把旧前端报告或其他职级的经验混成一套一般 SWE 流程,也没有验证两份同周期、同方向的独立报告来支持新的固定流程结论。

Coding 证据应包含契约,而不只是答案

契约是输入、输出和边界行为的约定。它决定什么结果算正确,也决定一个算法的假设是否成立。口头说“我用滑动窗口”还不够:窗口按时间还是按元素个数?重复用户计数一次还是多次?边界是否包含?这些问题会改变实现。

下面是原创练习,不是 Meta 原题:输入按时间非递减排列的事件 (秒数, 用户ID) 和正窗口宽度 W。对每个事件时刻 t,统计已经读到、且时间处于 (t-W, t] 的不同用户数,返回这些计数的最大值。相同时间的事件依输入顺序进入;因此中间计数描述的是已读前缀,而不是一次性聚合所有同刻事件。

先考虑每个位置向前扫描的方案,明确它的重复工作,再利用有序输入移动左端。维护每个用户在当前窗口的出现次数,只有次数降到零才删除用户。这比用一个集合删除过期用户更可靠:集合无法区分“该用户有一个事件过期,但还有另一个事件留在窗口”。

def peak_distinct(events, width):
    if width <= 0:
        raise ValueError("width must be positive")
    counts = {}
    left = 0
    best = 0
    previous = None
    for right, (time, user) in enumerate(events):
        if previous is not None and time < previous:
            raise ValueError("events must be sorted")
        previous = time
        counts[user] = counts.get(user, 0) + 1
        while events[left][0] <= time - width:
            old_user = events[left][1]
            counts[old_user] -= 1
            if counts[old_user] == 0:
                del counts[old_user]
            left += 1
        best = max(best, len(counts))
    return best

循环完成一次后,不变量是:计数字典恰好覆盖 events[left:right+1],其中没有时间小于或等于 t-W 的事件。每个事件进出窗口各一次,采用通常哈希表假设时总时间是 O(n),额外空间受窗口内不同用户数限制。正宽度确保当前事件不会被过期循环删掉;空输入返回零。

用反例暴露“熟悉题”和“掌握题”的差别

对 [(1,A),(2,A),(3,B),(6,C)],取 W=3,每个已读前缀的不同用户数依次是 1、1、2、1。到 t=6 时,t=3 正好落在开区间的左边界之外,B 必须移除。最大值仍为 2,而不是最后窗口的 1。

练习时先写预期,再运行。加入重复用户、同刻事件、恰好过期、很大的时间跳跃和空输入。如果实现每次过期直接从集合删除 A,那么到一个 A 过期、另一个 A 仍然有效的时刻,就可能低估人数。这是说明“次数表为何必要”的最短反例,不是用更多随机输入替代推理。

接着改约束:事件允许乱序怎么办?如果一次处理完整有限列表,可以先排序,复杂度变成 O(n log n)。如果输入是长期运行的流,排序全部数据不是可用答案,你需要讨论允许迟到的范围、何时输出最终结果、以及修正旧结果的代价。别在需求尚未约定时擅自丢弃晚到事件。

再改输出:要求每个完整同刻批次的计数,而不是每条输入前缀计数。最大值通常仍可通过本例处理找到,但逐条输出的语义已经不对,需要按时间批次输出。记录“结果没变”和“接口正确”是不同结论,能帮助你避免只看最终数字。

设计证据:从照片可见性走到分页与失败

原创设计练习是好友照片流:用户只能看到当前有权限访问的照片,列表支持分页。先定义创建照片、修改可见性、读取下一页和删除照片的行为,而不是立即画队列、缓存与数据库图。

接口可使用 GET /feed?cursor=...&limit=...。游标至少需要表达稳定排序的位置,例如 (created_at, photo_id);两个照片创建时间相同仍有确定顺序。还要问:翻页期间是否要求固定快照?允许新照片只出现在刷新后的第一页吗?如果选弱快照语义,就明确可能看不到翻页过程中新增的部分内容,不伪装成完全稳定快照。

权限变化是更重要的边界。推荐候选列表中有一张照片,不代表请求时仍有权返回其内容。假设用户移除了好友或把照片改为私密,读取路径需要以约定的权限来源作检查,缓存键也不能把一个用户的授权响应直接共享给另一个用户。你可以缓存候选 ID,但必须解释内容与授权如何保持约定,而不是把 TTL 当作即时撤销保证。

Meta 的历史工程文章 TAO: The power of the graph讨论了关联的点查、范围与计数,以及简单 API 和应用层工作的分工。它是理解接口取舍的公开技术背景,不是当前面试评分表,也不证明候选人必须复制该架构。

从“加缓存”走到能验证的失败约定

缓存失效是使旧缓存条目不再被当作当前数据的机制;它与设置过期时间并不是同一个承诺。Meta 的 Cache made consistent用写入、失效与缓存回填的竞态说明一致性问题。阅读它时,练习说出旧响应如何覆盖新状态,而不是背诵文中的线上指标。

把这一思路转成照片练习:数据库已记录版本 8 的私密状态,缓存尚有版本 7 的公开状态。若旧读取随后回填缓存,只靠“写完再删除一次”是否足够?版本检查能拒绝旧值,但版本元数据本身被驱逐后怎么办?你的答案需要说明版本信息的生命周期、回源校验与失败时的返回策略。

对权限敏感的读取,可以提出无法确认授权时不返回内容,并解释这会增加失败率或延迟。对非敏感候选排序,可容忍短暂陈旧,以减少回源压力。这不是“所有数据都最终一致”或“所有地方都强一致”的二选一:同一请求中的不同数据可以有不同语义。

留下可验证的设计产物:一条正常请求路径、一条撤权后读取路径、一条数据库超时路径。为每条写明用户会看到什么、在哪记录异常、怎样发现问题。只有图而没有这些行为约定,面试官仍然无法检查你的设计。

BQ 证据:把团队成果拆成个人决定

BQ 在中文面经中通常指 behavioral questions,即行为问题。准备时应把它当作过去工作中的判断与协作证据,而不是价值观口号填空。使用 STAR 能帮助组织顺序,但不能替你补出真实行动。

下面是虚构回答对比。弱版本是:“我们优化了照片加载,性能大幅提升,我沟通了各团队。”它没有说明问题如何发现、你能决定什么,也没有定义性能指标。

更可追问的版本是:“在移动端照片流项目中,我负责请求取消与客户端状态,不负责后端索引。我们观察到切换筛选后旧响应覆盖新列表,我提出给请求关联查询版本,并补了乱序返回测试。后端同事负责接口变更。我能展示复现步骤与回归结果;没有同口径线上数据,所以不声称带来了某个百分比的生产提升。”

这样的回答不因没有巨大数字而变弱。它提供了个人职责、替代方案、具体行为与证据边界。继续追问“为什么没直接串行请求?”时,可以讨论串行化会增加等待,而取消并不能保证服务器从未完成工作,因此客户端仍需要判断响应是否属于当前状态。

冲突故事也要留下对方的合理诉求。假如产品希望立即上线、工程希望补测试,不要将它写成“我说服了不懂技术的人”。先解释共同目标,再说明你提出了哪些范围、风险或回滚选择,谁承担最终发布决定,以及你后来是否改变了判断。

把准备清单变成可以被别人检查的记录

对 Coding,保存新题契约、首次思路、最短失败输入与修复后的回归结果。对设计,保存接口、一个容量假设和至少一个失败行为。对 BQ,保存自己决定的事项、实际交付物、结果来源与不能归功于自己的部分。清单的作用是暴露缺口,不是给自己打一个虚构的通过分。

让练习搭档每次只改变一项条件。窗口输入改成乱序,照片删除改成撤销权限,BQ 追问从“发生了什么”改成“如果没有你会怎样”。观察你是重新推导,还是把原答案继续讲下去。后者说明材料还没有形成可迁移的能力。

模拟后按最早失败点选择下一步:如果契约没有问清,先重写需求;如果实现正确却讲不出不变量,练短解释;如果设计只有组件名,补具体读写路径;如果故事只能说“我们”,回到真实文档核对自己的边界。不要因为一次模拟顺利,就把所有轮次都标成准备完成。

一次模拟怎样产生三种不同的修复

可以把同一份照片流练习交给搭档,但不要让三种证据共用一个“不错”的评价。Coding 模拟中,对方只观察你是否先说明时间有序与左边界开区间,再给一组重复用户;设计模拟中,对方只改变一次授权状态;BQ 模拟中,对方只追问一次个人决定。每次应留下具体失效位置。

假设 Coding 输出正确,却说不出为什么删除一个过期 A 后仍要保留 A。下一次修复不是再做一题类似窗口,而是画出 A 的两次出现,把字典频次与集合存在性分开。在解释中指出每个事件离开时只减少一次,直到零才删除;让搭档给一个同刻输入,检验你是否仍遵守已读前缀契约。

设计模拟若在撤权后仍返回旧内容,就回到授权来源,而不是马上调短 TTL。明确缓存究竟存候选 ID、照片元数据还是已经授权的响应;列出请求者身份如何进入检查,授权来源不可用时采用什么行为。一个失败案例可以揭示缓存边界,不能由一次成功读取证明权限撤销已经正确。

BQ 模拟若被问“这个决定是谁做的”时开始模糊,就回到真实会议记录或自己的提交。区分你提出建议、你执行方案与最终负责人批准方案。若没有保存可公开证据,不要编造文档编号;可以准确说明自己记得的动作与仍不能独立核对的团队结果。

修复以后,再给搭档一份没有原答案的新输入或新追问。第一次能照着笔记解释,只证明材料可读;第二次在变化条件下仍能建立契约,才更接近可迁移的准备。不要将这套自查宣称为 Meta 的内部评分或通过预测。

把产品架构追问与容量追问分开回应

照片练习若被追问“翻页时切换筛选”,先讨论客户端查询状态、取消请求与旧响应是否还能更新界面。若被追问“一个用户有大量好友”,再讨论候选生成、扇出、读取成本与热点。两种追问有关联,但先回答正确边界,比立即展示一张最大规模的图更重要。

容量数字可以用显式假设计算,不必捏造 Meta 的真实流量。例如虚构服务每秒读取 1,000 次、每次返回 20 个候选,就是每秒 20,000 个候选条目的检查负载;照片字节下载与候选元数据读取另算。若你的缓存只减少元数据回源,不能据此声称媒体传输成本也等比例下降。

用五道题训练不同证据,不押同一张题单

下面的 Meta 题库记录覆盖代码、设计与行为训练。记录来自报告材料,不保证你的邀请包含这些题或相同形式。

完整题目训练证据额外自查
Shortest 8-Directional Clear Path Across a Binary Grid搜索状态与最短路解释起终点堵塞、对角移动与访问标记
Check Whether a Letters-and-Numbers Abbreviation Matches a Word解析契约与指针边界数字段、前导零与越界
Design 24-Hour Ephemeral Stories for a Photo and Video Sharing App可见性与生命周期到期、删除与缓存读取是否一致
Design a Real-Time Chat Service for One-to-One and Group Messaging消息交付与失败路径重试、去重与成员权限变化
Answer core Meta behavioral questions个人判断与合作证据结果属于谁、还有哪些未知

准备好的标志是能处理追问

Meta 软件工程师面试准备应从邀请确认开始,以三种不同证据结束。能写出熟悉题并不等于能适应变化,能画架构并不等于能解释失败,能讲流畅故事也不等于能证明自己的贡献。

下一次打开 Meta Software Engineer questions,先挑与你最薄弱证据对应的一题。完成后改变一个约束,再把答案交给别人追问。比起增加一行“已刷”,这会给你一个更明确的下一步。

资料来源与延伸阅读

核查日期:2026 年 10 月 6 日。本文解释准备证据,不声称验证了当前所有 Meta SWE 岗位的招聘流程;历史工程文章不是面试规则。练习与回答对比为原创示例。