Apple 前端面试准备全解(front-end-interview-handbook):从 JS 编码、UI 实战到系统设计与内部人经验
本文基于 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 分钟的虚拟面试,可以一天内完成,也可以分两天,四个考察方向分别是:
- JavaScript:编码题(与技术面类似);
- Bug Hunt:在既有代码库上找 bug、修 bug 的编码题;
- Web Performance:围绕 Web 性能领域的知识问答;
- 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 编码考点有两类:
- 手写
Array.prototype方法:flat、map、reduce、concat; - 按顺序执行一个 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-cheatsheet 与 user-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 合成事件的绑定与生命周期行为,可作为答题依据。
四、系统设计题
原文列出两道系统设计考点:
- 设计数据库 schema(偏全栈的轮次;面试官可能让你在之后选择深挖前端或后端方向);
- 设计 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 包
标准答案结构:
- 初始化
package.json(name、version、main/exports入口、files字段控制发包内容); - 用构建工具(如 esbuild、tsc、rollup)把源码编译为目标产物,同时产出 TypeScript 声明文件;
- 本地用
npm pack验证包内容、npm install ./xxx.tgz自测; npm publish发布(需要 NPM 账号与 2FA)。
追问方向通常是:main 与 module/exports 的区别、CommonJS 与 ESM 双构建、files 白名单与 .npmignore 的取舍。
5.2 CSS 合成层(Compositing Layer)
这是 Web Performance 轮的高概率考点。核心事实链:改变 transform 或 opacity 不触发布局(reflow)和重绘(repaint),只触发合成(composition);浏览器会为这类元素创建独立的 GPU 图层,合成在 GPU 上完成,因此动画更流畅、绘制时间更短。而改变绝对定位属性则触发 reflow,走 CPU 路径。仓库 css-questions.md 中关于 translate() 与绝对定位对比的条目正是这个知识点的原文表述,可以直接引用复习。延伸追问:什么会创建合成层(transform、opacity 动画、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+1 与 i+2 项的乘积。注意示例的边界处理:最后一项 12 = 4 * 3(回绕到首位,或者说 i+1 与 i+2 按某种循环取法),中间项 15 = 4 * ?——对照 [20, 15, 12]:20 = 4 * 5、15 = 5 * 3、12 = 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.md 与 introduction.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 题。
由此得到的备考优先级:
- Vanilla JS + DOM:四个数组方法手写、Promise 串行执行、进度条/To-Do/排序工具等 UI 题的原生实现,这是多份面经交叉验证的最高频考点;
- 算法底线:Blind 75 级别的 DSA 储备 + 对每道题追问变体的练习习惯;
- Web Performance 知识网:合成层、重排重绘、加载性能(
load事件的局限、渐进渲染)、事件循环——仓库 css-questions.md 与 javascript-questions.md 中相关条目可作复习索引; - Redux 多步表单:跨步骤数据传递是 React 轮的实锤题型;
- Bug Hunt 专项:找几位同事的既有代码库做限时 debug 练习(原文中候选人公开征集这方面的练习建议,说明它没有标准题库,只能靠模拟);
- 行为面准备:Product Thinking 与协作案例,用 STAR 结构准备"技术 vs 业务取舍"的真实案例,仓库 behavioral 指南 覆盖了这类行为的框架。
最后提醒原文中的适用前提:以上题型与轮次均来自 2024–2025 年候选人的一手描述与 Glassdoor 面经(源文档 已注明来源),团队差异极大,本文的结论应视为"高概率画像"而非官方流程;准备时以本文题型清单为底,再针对具体团队 JD 做增量调整。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00