首页
/ Apple 前端面试准备全解(front-end-interview-handbook):从 JS 编码、UI 实战到系统设计与内部人经验

Apple 前端面试准备全解(front-end-interview-handbook):从 JS 编码、UI 实战到系统设计与内部人经验

2026-09-05 15:16:37作者:何举烈Damon

本文基于 front-end-interview-handbook 仓库中的 Apple Front End Interview Questions 文档整理成文,系统覆盖 Apple 前端面试的五大题型——JavaScript 编码、User Interface 编码、系统设计、Quiz 与算法题,并给出每题的解题思路与可运行代码参考。读完本文,你将掌握一套针对 Apple 面试的完整准备方案,包括社区内部人总结的面试流程细节(4 × 45 分钟虚拟面试的结构、Vanilla JS 侧重、Redux 与 Web Performance 考点等),以及每类题目的练习切入点。

一、Apple 前端面试的整体画像

原文明开宗义义地说:"Not much is known about Apple's front end interview process."(关于 Apple 前端面试流程,公开信息并不多)。但从 apple-front-end-interview-questions.md 汇总的 Glassdoor 面经和 GreatFrontEnd 社区 2024–2025 年的内部人分享,可以拼出一个相当清晰的画像:

  • 流程结构:一位最终轮候选人(2025 年 5 月 21 日分享)转述了招聘方的说明——共 4 轮、每轮 45 分钟的虚拟面试,可以一天内完成,也可以分两天,四个考察方向分别是:
    1. JavaScript:编码题(与技术面类似);
    2. Bug Hunt:在既有代码库上找 bug、修 bug 的编码题;
    3. Web Performance:围绕 Web 性能领域的知识问答;
    4. Product Thinking:行为面,聚焦协作能力、技术与业务需求的平衡、对用户影响的理解。
  • 轮次组合的另一版本:2025 年 8 月 20 日分享者描述其 senior full stack 面试 loop 为 React 电话面 + 4 轮 onsite(数据库 schema 设计、React 编码、行为面、外加一轮"很 Apple 特色"的面试)。
  • 考察深度:另一位拿到 offer 的候选人(2025 年 9 月 3 日)强调 Apple 会认真考 DSA / LeetCode,题目会从一道基础题出发不断追问变体,"模式识别"(Pattern recognition)是关键——能把新题映射到做过的题型上,问题就解决了大半。他的建议是:没有拿下 Blind 75 的底子不要进 Apple 面试,"如果 DSA 轮你过不了而其他候选人能过,通常就结束了"。
  • Vanilla JS 是重头戏:2024 年 4 月 14 日的面经写道:"大概总共 6 轮,全是基础题,Vanilla JS,5 年经验",并确认 Apple 大量考 Vanilla JS 和 DOM 相关问题——这与下文 UI 编码题"用原生 JS、不依赖库"的要求互相印证。
  • 团队差异极大:2024 年 4 月 3 日的面经显示,某次电话面几乎没考算法,大部分时间问背景和经验,最后 10 分钟才出一道"超级简单的 JS 题"。结论是:流程强依赖你要面试的具体团队,Apple 更看重你与岗位的匹配度,而非单纯解 LeetCode 的能力。
  • 薪酬预期:多位分享者提到 Apple 的 TC 在同类 offer 中偏低(2025 年 8 月与 2024 年 12 月两位面经都提到这一点),且招聘方给出的备考信息"非常不一致,不要完全相信其准备建议"。
  • 岗位性质:2025 年 9 月拿 offer 的候选人所在岗位"偏前端但技术上是全栈——团队正在把后端迁移到 Node.js,FE 工程师被期望能接手后端工作"。他虽未被深挖后端系统设计,但主动提及后端概念来表明自己的认知是有效策略。

从这些一手信息可以推断,Apple 前端面试的特点是:基础题占比高、团队定制化强、Web 性能与产品思维是差异化的考点。下面的题型拆解即据此展开。

二、JavaScript 编码题

原文列出的 JS 编码考点有两类:

  1. 手写 Array.prototype 方法flatmapreduceconcat
  2. 按顺序执行一个 Promise 数组(How can you execute an array of promise in sequence?)。

2.1 手写数组方法

这四个方法是 Apple 高频考点,仓库中 javascript-utility-function.md 专门整理了手写数组工具函数的题单(其中 Flatten 是免费练习题),可作为练习入口。下面给出可参考的最小实现:

// flat: 仅展开一层(完整版需处理 depth 参数)
Array.prototype.myFlat = function () {
  return this.reduce((acc, cur) =>
    Array.isArray(cur) ? acc.concat(cur) : acc.concat(cur), []);
};

// map: 对每个元素应用回调,返回新数组
Array.prototype.myMap = function (fn) {
  const result = new Array(this.length);
  for (let i = 0; i < this.length; i++) {
    result[i] = fn(this[i], i, this);
  }
  return result;
};

// reduce: 把数组归约为一个值
Array.prototype.myReduce = function (fn, initial) {
  let idx = 0;
  let acc = initial;
  if (arguments.length < 2) {
    acc = this[idx++]; // 无初始值时取第一个元素
  }
  for (; idx < this.length; idx++) {
    acc = fn(acc, this[idx], idx, this);
  }
  return acc;
};

// concat: 合并数组与任意参数
Array.prototype.myConcat = function () {
  const result = Array.from(this);
  for (const arg of arguments) {
    result.push(...(Array.isArray(arg) ? arg : [arg]));
  }
  return result;
};

面试时注意两个细节:map 需要把索引和原数组传给回调;reduce 在有/无初始值两种情况下的起点不同。手写这些方法本质上考察的是对迭代协议的理解,而不是背 API。

2.2 顺序执行 Promise 数组

这是与 Promise.all 相对的经典题:Promise.all 是并发执行、全部完成才返回,而"按顺序"要求前一个 Promise resolve 后才启动下一个。两种等价写法:

// 写法一:async/for...of(最直观)
async function runSequentially(promises) {
  const results = [];
  for (const p of promises) {
    results.push(await p); // await 保证串行
  }
  return results;
}

// 写法二:reduce 链式 then(纯 Promise 风格)
function runSequentiallyChain(promises) {
  return promises.reduce(
    (prev, p) => prev.then(() => p),
    Promise.resolve()
  );
}

// 用法
const promises = [
  new Promise((r) => setTimeout(() => r(1), 300)),
  new Promise((r) => setTimeout(() => r(2), 100)),
  new Promise((r) => setTimeout(() => r(3), 200)),
];
runSequentially(promises).then(console.log); // [1, 2, 3],总耗时约 600ms 而非 300ms

追问点往往在这里:如何支持每个 Promise 接收上一个的结果(类似 reduce 的语义)?把 prev.then(() => p) 改为 prev.then((val) => p(val)) 即可。仓库中 javascript-questions.md 的 Promise 小节(三状态、Promise.all 的优缺点)以及 Event Loop 相关内容,是回答这类追问时可直接引用的基础知识点。

三、User Interface 编码题

原文列出 5 道 UI 编码题,共同特征是 Vanilla JS 实现为主、手机屏幕尺寸约束

题目 要点
用 Vanilla JS、零依赖实现一个照片排序工具 DOM 操作、拖拽或上下按钮重排、状态同步
构建进度条组组件(phone-screen 变体,无动画) 状态驱动渲染,进度条进度可更新
实现多步表单,导航在步骤间传递数据,预期用 Redux 跨步骤共享 state、表单校验、Redux 中间层
用 CSS 实现 Pinterest 式瀑布流(Masonry)布局(CSS 主导轮) 纯布局能力,常配合系统设计的 Pinterest 题
用 React 实现一个基础 To-Do 应用(较小的 phone-screen 变体) 组件化、受控输入、列表渲染

练习入口:仓库文档标注了进度条与 To-Do 两道题在 GreatFrontEnd 上有免费版练习题;仓库内的 user-interface-questions-cheatsheetuser-interface 章节 提供了 UI 题型的通用检查清单(布局、可访问性、渐进渲染等),可作为 UI 轮的准备索引。React 方向的 To-Do 题,仓库 react-interview-playbook 的状态设计(react-state-design)与 Hooks 章节是配套的练习材料。

3.1 进度条组的参考实现思路

"进度条组、无动画"意味着考察点集中在数据 → 视图的单向映射

// state 驱动渲染:每完成一项,只重绘变化的 DOM 节点
const state = { tasks: [{ label: 'Upload', pct: 0 }, { label: 'Process', pct: 0 }] };

function render() {
  for (const [i, t] of state.tasks.entries()) {
    const bar = document.querySelector(`[data-task="${i}"] .fill`);
    bar.style.width = `${t.pct}%`;
    bar.parentElement.setAttribute('aria-valuenow', String(t.pct));
  }
}

面试中值得主动补充的点:用 width 而非 transform 控制进度条会触发布局;若后续追问性能,可说明 transform: scaleX() 走合成层更廉价——这一点正好衔接下文 Quiz 题的"CSS 合成层"。

3.2 Masonry 布局与 React To-Do

Pinterest 式瀑布流有两种典型路线:纯 CSS(CSS Columns,缺点是按列排序)与 JS 计算每列高度(短列优先放置,可保持 DOM 顺序)。原文特别注明这是 "CSS-focused round",建议优先打磨纯 CSS 方案与 column-count/column-gap 的行为边界。React To-Do 题较小,核心是受控 <input>onChange/onSubmit 事件处理与列表 key 的正确使用,仓库 react-event-handling 章节覆盖了 React 合成事件的绑定与生命周期行为,可作为答题依据。

四、系统设计题

原文列出两道系统设计考点:

  1. 设计数据库 schema(偏全栈的轮次;面试官可能让你在之后选择深挖前端或后端方向);
  2. 设计 Pinterest(瀑布流 feed)。

仓库的 front-end-system-design.md 提供了前端系统设计的完整框架(评估维度、常见题型、常见错误与速查表,对应 system-design 指南包),可配合准备。其中 framework 章节 明确指出:当组件本身就是产品主体时(例如 Pinterest 的 masonry grid 这类较复杂的组件),组件 API 设计是必须花时间讨论的部分——这直接对应 Apple 的"设计 Pinterest"一题,答题时应把瀑布流组件的 API(列数策略、图片尺寸上报、虚拟滚动、分页加载)作为设计的一等公民来讨论,而不仅是接口与缓存。

数据库 schema 题的建议路径:先澄清实体关系(用户、feed、卡片、互动),给出表结构与索引策略,再主动说明前端如何消费该 schema(分页 cursor、字段裁剪),并在面试官给出"深挖前端或后端"选项时,结合你面试的团队选择方向——2025 年 9 月的面经提到团队正在向 Node.js 迁移后端,主动展示 Node 生态认知是加分项。

五、Quiz 题

原文只列了两句:

  • How do you build an npm package?(如何构建一个 npm 包)
  • What is a compositing layer in CSS?(CSS 中的合成层是什么)

5.1 构建 npm 包

标准答案结构:

  1. 初始化 package.jsonnameversionmain/exports 入口、files 字段控制发包内容);
  2. 用构建工具(如 esbuild、tsc、rollup)把源码编译为目标产物,同时产出 TypeScript 声明文件;
  3. 本地用 npm pack 验证包内容、npm install ./xxx.tgz 自测;
  4. npm publish 发布(需要 NPM 账号与 2FA)。

追问方向通常是:mainmodule/exports 的区别、CommonJS 与 ESM 双构建、files 白名单与 .npmignore 的取舍。

5.2 CSS 合成层(Compositing Layer)

这是 Web Performance 轮的高概率考点。核心事实链:改变 transformopacity 不触发布局(reflow)和重绘(repaint),只触发合成(composition);浏览器会为这类元素创建独立的 GPU 图层,合成在 GPU 上完成,因此动画更流畅、绘制时间更短。而改变绝对定位属性则触发 reflow,走 CPU 路径。仓库 css-questions.md 中关于 translate() 与绝对定位对比的条目正是这个知识点的原文表述,可以直接引用复习。延伸追问:什么会创建合成层(transformopacity 动画、will-change、视频/canvas 等),以及滥用合成层的代价(GPU 内存、层数过多反而掉帧)。

六、算法题

原文给出的原题:

Given an array, return an array where the each value is the product of the next two items: E.g. [3, 4, 5] -> [20, 15, 12]

即结果中第 i 项等于原数组第 i+1i+2 项的乘积。注意示例的边界处理:最后一项 12 = 4 * 3(回绕到首位,或者说 i+1i+2 按某种循环取法),中间项 15 = 4 * ?——对照 [20, 15, 12]20 = 4 * 515 = 5 * 312 = 3 * 4,可以确认取的是循环意义上的"后两项"(越界时回到数组开头)。参考实现:

function productOfNextTwo(arr) {
  const n = arr.length;
  return arr.map((_, i) => arr[(i + 1) % n] * arr[(i + 2) % n]);
}
// productOfNextTwo([3, 4, 5]) -> [20, 15, 12]

面试策略上,这道题本身简单(O(n) 一次遍历即可),真正的考察在后面:拿到的面经提到 Apple 的题目会"从一道基础题开始,用其他题目的概念不断追问",所以应主动覆盖边界情况(空数组、长度为 1/2、含 0 元素),并说明非循环版本(尾部补 undefined/0)的行为差异。仓库的 algorithms.mdintroduction.md 中关于算法准备的建议(刷题范围、时间复杂度表述习惯)可用于配套准备。

七、内部人经验汇总与备考建议

把原文 "Insider tips" 小节(来源:GreatFrontEnd 社区已完成 Apple 面试的用户,按时间倒序)浓缩为可执行清单:

2025-09-03(拿到 offer)

  • Apple 要"什么都学",包括 DSA / LeetCode;题目从基础题出发、后续追问串联其他题型,模式识别是关键——能映射到做过的题,问题就解决了 75% 以上;
  • 底线要求:至少拿下 Blind 75,DSA 轮过不去基本出局,"现在的候选人太强了,门槛确实很高";
  • 团队依赖性强:其岗位偏 FE 但技术上是全栈(后端迁移到 Node.js,FE 要能接手后端);没被深挖后端系统设计,但他主动带出后端概念来示意认知

2025-08-20(senior full stack loop)

  • 流程:React 电话面 + 4 轮 onsite(数据库 schema、React 编码、行为面、一轮"很 Apple 特色"的轮次);
  • 电话面感觉像"进度条组"题但无动画;onsite React 题是多步表单、导航传数据(要求 Redux);还有一轮纯 CSS——实现 Pinterest 式 masonry 布局;
  • 警示:招聘方给的备考信息" wildly 不一致",除非内容非常扎实,否则别全信;TC 是他这一批 offer 中最低的——带着这个预期去谈。

2025-05-21(最终轮)

  • 4 × 45 分钟虚拟面试,可一天或分两天;四个方向:JavaScript 编码 / Bug Hunt(既有代码库上调试)/ Web Performance(领域知识问答)/ Product Thinking(协作、技术与业务平衡、用户影响的行为面)
  • 该候选人判断 Web Performance 轮大概率是覆盖广的 JS 深度 trivia,类似 FE 系统设计中常见的那些概念。

2024-12-02

  • Apple 题库很大,"基本团队对团队不一样";会考系统设计,FAANG 级别的门槛很高,且"FAANG 里薪酬最低的一档"。

2024-04-14(5 年经验,基础题为主)

  • 共 6 轮,全是 fundamentals 与 Vanilla JS;大量 DOM 相关问题;准备方式是做 UI 题的 Vanilla JS 实现版本。

2024-04-03(电话面)

  • 电话面没问 LeetCode 题,大部分时间问背景和经验,剩 10 分钟给一道很简单的 JS 题;流程真的取决于你要面试的团队;他们更关心你是否适合这个岗位,而不是能否 ac 一道 LC 题

由此得到的备考优先级:

  1. Vanilla JS + DOM:四个数组方法手写、Promise 串行执行、进度条/To-Do/排序工具等 UI 题的原生实现,这是多份面经交叉验证的最高频考点;
  2. 算法底线:Blind 75 级别的 DSA 储备 + 对每道题追问变体的练习习惯;
  3. Web Performance 知识网:合成层、重排重绘、加载性能(load 事件的局限、渐进渲染)、事件循环——仓库 css-questions.mdjavascript-questions.md 中相关条目可作复习索引;
  4. Redux 多步表单:跨步骤数据传递是 React 轮的实锤题型;
  5. Bug Hunt 专项:找几位同事的既有代码库做限时 debug 练习(原文中候选人公开征集这方面的练习建议,说明它没有标准题库,只能靠模拟);
  6. 行为面准备:Product Thinking 与协作案例,用 STAR 结构准备"技术 vs 业务取舍"的真实案例,仓库 behavioral 指南 覆盖了这类行为的框架。

最后提醒原文中的适用前提:以上题型与轮次均来自 2024–2025 年候选人的一手描述与 Glassdoor 面经(源文档 已注明来源),团队差异极大,本文的结论应视为"高概率画像"而非官方流程;准备时以本文题型清单为底,再针对具体团队 JD 做增量调整。

登录后查看全文
热门项目推荐
相关项目推荐