飞书前端社招一面:从基础原理到场景设计的完整复盘
2026/8/29 22:42:48 网站建设 项目流程

1. 投递这一面之前,我做了哪些准备

先交代一下背景。我是社招,主攻方向是中后台复杂前端应用,之前做过在线文档、低代码平台这类偏“重型”的项目。投飞书前端,理由其实很直接:飞书是典型的 To B 协作工具,文档、表格、会议、审批这些场景天然就是前端的深水区——长文档渲染、多人实时协同、复杂表格交互、消息流性能,哪一个拿出来都能挖得很深。这正好是我这几年一直在积累的东西,所以我判断这个岗位的面试官大概率会贴着项目问,而不是纯考八股。

简历我改了三天。一开始我写的是“负责 xx 模块开发,提升 xx 效率”,后面发现这种写法根本没法打。后来我把每一段项目经历都改成“面对什么问题,我做了哪些方案对比,最终选择什么,拿到什么可量化的收益”。举一个我改完的例子:以前写“实现了大文件上传功能”,改成“视频素材上传场景下,原方案在 2GB 文件时主线程阻塞约 4 秒,我改造成基于 Web Worker 的分片上传 + 断点续传方案,上传耗时降低 35%,整体内存峰值下降 40%”。

为什么这么改?因为社招一面基本不会对着简历逐字问,面试官只会挑你写出来的技术点,顺着往下挖。你写得越具体,他越容易找到切入点,你也越容易把话题引到自己的强项上。如果你只写“负责 xx”,面试官就只能从常见八股题库里随便抽题考你,那场面就不可控了。

技术准备这块,我没有按照传统“前端面试题”的清单死背,而是按底层原理重新过了一遍。我当时的准备清单大概是这样的:

方向核心知识点我用的练习方式
JavaScript事件循环、闭包、原型链、垃圾回收、Promise/A+手写实现 + 给代码猜输出
浏览器渲染流程、合成层、重排重绘、性能指标用 Performance 面板实测自己的项目
框架React 渲染流程、Fiber、diff 策略;Vue 响应式原理画执行流程图 + 手写简化版
工程化Webpack/Vite 构建流程、微前端沙箱、monorepo搭一个最小可运行的微前端 Demo
场景题大文件上传、协同编辑、消息推送、离线缓存每周写一个设计思路文档

另外,飞书这类业务对“实时协作”和“复杂编辑器”的知识特别看重,所以我把之前研究过的 OT 算法、CRDT 思路、WebSocket 重连机制、SSE 推送、IndexedDB 缓存这些内容都重新整理了一遍。

还有一个容易被忽略的准备:面试前把飞书的产品打开,认真用一下。我在面试前一周,每天会用飞书写文档、做表格,感受它们的交互细节。比如飞书文档的光标位置处理、多人头像展示、表格冻结行列的交互,这些看起来只是功能,但如果你能说出“这个功能的难点在哪里”,面试官会眼前一亮。

提示:社招一面和校招最大的区别是——面试官默认你是有实际项目经验的,所以他问的每一个基础题,最终都会落到“你在项目中怎么用它解决了问题”上。准备时一定要给每个知识点准备一个项目案例。

2. 开场自我介绍与项目深挖:这一问就聊了 25 分钟

一面开头照例是自我介绍。我的表达在 2 分钟左右,结构是“过去做了什么 + 目前最擅长的方向 + 为什么来面这个岗位”。建议大家不要花太多时间讲经历,面试官真正想听到的是:你的技术标签是什么、和这个岗位匹配度有多高。

我给自己定的标签是“复杂前端应用和高性能渲染”。因为我做过的在线文档和低代码平台,都涉及长列表渲染、协同编辑、复杂状态管理,这和飞书文档、表格的场景非常匹配。所以自我介绍里我就直接说:“我近几年主要在做复杂前端应用,涉及编辑器渲染、多人协同和性能优化,飞书文档类业务应该是我最能发挥价值的方向。”这句话相当于主动递了一个钩子。

结果不出所料,面试官接着就问:“那你挑一个最能代表你能力的项目,讲讲里面最复杂的技术点。”我讲的是之前做过的在线文档表格协同项目,然后就是长达 25 分钟的连环追问。

我当时讲的是一个自研的表格渲染和协同模块,但面试官的追问风格不是“你做了什么”,而是反复问“你怎么证明你的方案是对的”。整个深挖过程我整理了下面几个核心问题,大家可以感受一下考察逻辑:

2.1 协同冲突是怎么处理的,客户端还是服务端合并

我遇到过这类问题,所以干脆提前讲清楚:我们用的是基于操作转换的思路,客户端的每一次编辑都生成一个操作描述,发送给服务端。服务端维护一个操作序列,当不同客户端的操作发生冲突时,通过转换算法让后到的操作相较于先到的操作做一次调整,然后再广播给所有客户端。

面试官追问:“你这里为什么用操作转换而不是 CRDT,有对比过吗?”这是很关键的问题。我的回答是:表格场景的数据结构比较结构化,操作转换的效率更高,且实现逻辑与现有编辑器的数据结构更匹配;CRDT 的优势在于天然适合离线合并和去中心化,但对表格这类“位置频繁移动”的场景,元数据膨胀问题很难接受。面试官听到这个对比,明显是满意的,因为他说“看来你确实把两种方案都研究过”。

这里我给自己提了个醒:项目讲述不能只讲结果,要把“方案选型的对比过程”说出来。面试官真正想看的不是你知道 OT 还是 CRDT,而是你有没有能力在多个可行方案里做合理决策。

2.2 Web Worker 解决了什么,不用行不行

我提到过用 Web Worker 做表格的渲染调度和计算任务分离。面试官直接问了一个很实在的问题:“你这里不用 Web Worker 会怎样?”

这个问题的考察点在于:你是否真实验证过性能瓶颈,还是跟风用了个热门技术。我的回答是:我们在一个 5000 行的表格上做过压测,不做调度优化时,主线程的长任务会阻塞页面交互,输入延迟达到 300 毫秒以上,下拉滚动有明显的空白闪烁。用 Worker 把行高计算和渲染指令生成移出去之后,主线程的长任务从 180 毫秒降到了 20 毫秒左右。我特意提了一句“交互输入延迟降低到 50 毫秒以内,用户体感基本无感了”,因为这些都是实测数据。

面试官没有继续纠细节,但追了一句:“Worker 和主线程之间的通信本身也有开销,你怎么平衡?”我说:我们的原则是只把“计算密集且不需要频繁回传”的任务放到 Worker 里,比如行高批量计算;而用户输入响应这类高频、低计算量的任务保持在主线程,避免序列化和消息传递的开销。简单说就是“重计算、轻交互”的划分。

2.3 如果让你设计一个多人同时编辑的表格,模块怎么拆分

这是一个典型的设计题。面试官问这个问题的潜台词是:你已经做过了,那你有没有总结出可复用的架构模式?

我是这样拆的:渲染层(负责可视区的表格渲染和交互)、操作管理层(负责本地操作的生成、应用和 undo/redo)、同步层(负责与 WebSocket 通信、操作序列的处理和冲突解决)、状态层(维护最终一致的数据模型)。同时我提到,本地状态会做备份和持久化,断网时先走本地缓存,恢复连接后再做增量补偿。这个设计也呼应了飞书文档离线编辑的场景。

这一段聊下来,我总结出一个很重要的经验:项目介绍时不要平铺直叙地罗列功能,而是要“制造钩子”,每讲一个技术点就留下一个面试官可能追问的线索。比如我提到 Worker 时故意说“性能数据从 180 降到 20 毫秒”,这比单说“用了 Worker”更有被追问的余地。

3. 前端基础与原理考察:看起来是八股,其实都在考场景

项目深挖结束,面试官切换到基础考察环节。这个环节大概是 15 分钟,面试官没有一上来就让我背概念,而是丢出来几段代码和一些场景问题。我印象比较深的几个点如下。

3.1 事件循环:不是背输出,而是讲调度过程

面试官给了一段代码,要求说出输出顺序:

console.log('script start'); setTimeout(() => { console.log('timeout1'); }, 0); Promise.resolve().then(() => { console.log('promise1'); }); queueMicrotask(() => { console.log('microtask1'); }); console.log('script end');

这个输出是:script start、script end、promise1、microtask1、timeout1。

关键是,面试官没有在我说出答案后就放过我,而是追问:“为什么 Promise 回调会在setTimeout之前执行?如果 setTimeout 嵌在两个 Promise 里,执行顺序会怎样?”

我当时的回答思路是:每一轮事件循环里,入栈的逻辑先全部执行完,然后处理微任务队列;微任务队列清空后,再从宏任务队列取下一个任务。所以script end输出完后,先清空微任务,再执行宏任务。而setTimeout即使延迟是 0,也会在下一轮宏任务执行。

这类题很多人是背口诀“先微后宏”,但面试官真正想验证的是你有没有理解“队列的调度优先级”和“为什么微任务需要被一次性清空”。如果只是背口诀,遇到嵌套 Promise 和嵌套 setTimeout 的变种题就会慌。我建议准备面试时把事件循环的这个调度过程用“生产者和消费者”的模型理解一遍:JS 引擎是一个消费者,任务队列是缓冲区,微任务优先级更高,只有微任务清空才会消费下一个宏任务。

3.2 闭包:从一道循环输出题展开

紧接着是经典的循环输出:

for (var i = 0; i < 5; i++) { setTimeout(() => { console.log(i); }, 0); }

输出全是 5。原因是var声明的i是函数级作用域,循环结束后i已经变成 5,五个定时器回调共用同一个变量。

面试官的追问是:“如果不用 let,你有哪些方式让输出变成 0、1、2、3、4?”我给出了两种:IIFE 传参,以及把setTimeout放到一个函数工厂里。前一种方式还衍生出一个问题:为什么 IIFE 里能保留每次循环的i值?核心是“每次迭代都会创建一个独立函数作用域,参数被复制到当前作用域里”。

面试官又问:“闭包会导致内存泄漏吗?你在项目里遇到过吗?”这个问题我很有感触,因为我真的排查过一次:一个地图应用里,事件回调函数引用了大量 DOM 节点和业务对象,页面切换时没有主动解绑,导致内存持续上涨,最后整个页面在移动端直接被系统杀掉。我用 Chrome DevTools 的 Heap Snapshot 对比了操作前后的内存变化,定位到是闭包引用链没有释放。这种“真实经历过”的回答,比任何标准答案都有说服力。

3.3 浏览器渲染与性能优化:从 URL 输入到页面显示

面试官问了一段很经典的问题:“在地址栏输入 URL 到页面显示,经历了哪些过程?”这种题大家都会答,但我要提醒一句:社招不能只答那几个大步骤,面试官一定会挑一两个细节深挖。

我回答时重点展开了两个阶段:HTML 解析和渲染合成。HTML 解析阶段,我提到了 CSS 和 JS 对渲染的阻塞关系:CSS 会阻塞渲染树的构建,而普通脚本会阻塞解析。然后面试官顺着问了一个实际的优化问题:“如果你有一个 2000 行的表格,加载时会出现长时间白屏,你怎么排查和优化?”

我的回答是:先确认瓶颈在哪个阶段——如果网络请求时间占比高,就要做数据分片或骨架屏;如果 JS 执行时间长,就要考虑任务拆解、懒加载、虚拟滚动;如果渲染阶段时间长,就要看是不是表格单元格样式太复杂,触发了大量重排。针对表格场景,我实际做过:只渲染可视区域的行列,滚动时通过绝对定位保持视图稳定,使用will-change提升合成层,减少重绘面积。面试官追问“虚拟滚动的空白区域怎么处理”,我说用一个占位块把整个滚动高度撑起来,并维护可视区到数据索引的映射,这样滚动条的真实高度不会失真。

3.4 微前端与工程化:为什么很多团队都在做

飞书的中后台业务里,微前端是常见的工程化方案。面试官问了一个很实际的问题:“如果一个老项目要从单体应用拆成微前端,你会怎么做?主应用和子应用之间怎么通信?”

我提到了两种主流的隔离方式:JavaScript 沙箱和样式隔离。沙箱上,我解释过快照沙箱和代理沙箱的区别——快照沙箱适合运行前全局变量不复杂的场景,代理沙箱可以在运行时拦截全局对象的读写,实现更细粒度的隔离。样式隔离则分为每个子应用都挂载在自己的容器节点下,配合 CSS Modules 或者scoped属性来避免串样式。

我还主动提了一句“子应用加载完成前怎么避免主应用的白屏”,这是我没踩过的坑但确实是经常会遇到的实际问题。我建议的方案是主应用在路由切换时保留旧的子应用界面,拿到新子应用的加载状态后再渲染 Loading 态,同时注意预加载脚本资源,让切换更顺滑。这块我没有说得太深,但面试官显然认可,因为工程化问题背后其实是在考察“你是否理解大型团队协作时的架构治理”,而不是会不会用某个框架。

3.5 框架原理:React 与 Vue,至少要能讲清一条链路

飞书前端的组件库以 React 为主,但面试官没有限制我技术栈,问的是:“你在项目里用过 React,那 React 的 setState 之后发生了什么?能不能说清楚从调用到界面更新的完整链路。”

我回答的思路是:setState首先会触发一次更新标记,React 会把该组件标记为需要更新,然后把更新加入调度器。调度器根据当前优先级决定是同步执行还是进入异步调度。渲染阶段,从根节点开始,React 会通过 diff 算法对比新旧虚拟 DOM,生成需要变更的最小操作集合;提交阶段,把这些操作同步到真实 DOM 上。注意,在并发模式下,渲染阶段是可以被打断的,但提交阶段必须同步完成。

面试官又追了一个问题:“那 React 的事件系统和原生事件有什么区别?”我举了一个项目里的实际例子:React 17 之前,事件是委托到 document 上的,所以如果多个子应用微前端混用,就很容易出现事件对象被其他应用干扰的情况;React 17 之后改为委托到根容器上,这种冲突就明显减少。这又是一个“我实际遇到并解决过”的回答。

4. 手写题与场景设计题:两道题不是考代码,是考思考路径

大概面试进行到第 35 分钟,面试官进入了手写题环节。这个环节一共两道题,一道是代码实现,一道是场景设计。我这两道题加起来花了差不多 15 分钟。

4.1 手写题:带并发限制的任务调度器

面试官原话是:“实现一个 TaskScheduler,它有一个 add 方法,调用 add 时传入一个返回 Promise 的函数。要求同时最多只能执行两个任务,并且要能拿到任务的返回结果。”

我先把需求重复了一遍,确认了几个关键点:

  • 同时执行的任务数不能超过 limit;
  • 任务执行完毕之后,自动从等待队列取下一个任务执行;
  • 需要支持拿到每个任务的结果和错误。

然后我写了一个实现:

class Scheduler { constructor(limit = 2) { this.limit = limit; this.activeCount = 0; this.queue = []; } add(task) { return new Promise((resolve, reject) => { const run = async () => { this.activeCount++; try { const result = await task(); resolve(result); } catch (error) { reject(error); } finally { this.activeCount--; this.next(); } }; if (this.activeCount < this.limit) { run(); } else { this.queue.push(run); } }); } next() { if (this.activeCount < this.limit && this.queue.length > 0) { const run = this.queue.shift(); run(); } } }

面试官看了一会儿,没急着说对不对,而是出了一个变种:“如果任务之间有依赖关系,比如第二个任务必须等第一个任务完成才能执行,你会怎么改?”我回答:这种情况下,就不能纯粹靠并发调度器来解决了,需要在上层根据依赖关系构建一个任务拓扑图,或把依赖任务组合成一个 Promise 链后作为一个整体任务丢给调度器。具体到代码,可以先把有依赖的任务通过taskA().then(() => taskB())组装成一个新任务,再交给调度器统一调度。

面试官又追了一个性能问题:“网络请求类的任务,并行数和排队数怎么平衡?”这其实考察的是工程判断,不是代码能力。我说:并发数不能设置得太高,要结合服务端的处理能力和业务场景,一般 2 到 4 个就比较合理,同时要设置超时和重试机制,避免一个慢请求占住并发坑位。

4.2 场景题:大文件分片上传的客户端核心流程

这个场景题其实和我简历里的项目是重合的,面试官应该是特意挑了一个“你可能做过”的题来验证我的项目真实性。题目是:“如果要上传一个超大文件,比如 5GB 的视频,前端要怎么设计上传方案?”

我的思路分成四步:

第一,文件分片。通过File.slice(start, end)把文件切成固定大小的分片。分片大小不是随便定的,我一般取 1MB 到 5MB 之间。为什么这么定?分片太小会导致请求数量太多,网络往返时间占比高;分片太大会导致单次请求失败后重新传输的成本变高。我比较常用的是 2MB,这样 5GB 的文件大概分成 2560 个分片,数量上可接受,单分片体积也合适。

第二,计算文件指纹。用文件内容生成一个唯一标识,比如读取前几 MB 数据计算哈希,或者直接对整个文件做抽样哈希。上传前先给服务端发送一个“查询”请求,如果服务端说文件已经存在且完整,那就是“秒传”;如果服务端已经接收了一部分分片,就只需要上传剩余分片,这是“断点续传”。

第三,并发控制。不能把所有分片一次性发出去,需要通过一个并发调度器控制上传数量。这里我就直接复用了刚才第一道手写题的思路,设置并发数通常是 3 到 5 个。每个分片上传失败时要做指数退避重试,比如第一次失败等 1 秒,第二次等 2 秒,第三次等 4 秒,最多重试 3 次。

第四,进度计算。注意不能只看已上传分片数除以总分片数,因为每个分片大小可能不一致。更准确的是累计已上传字节数除以文件总字节数。

我还提到一个细节:上传计算可以放到 Web Worker 里,因为 Hash 计算、分片切片这些操作都比较消耗 CPU,放在主线程会卡住页面交互。如果还要实现上传进度条,就通过 Worker 的postMessage把进度信息回传主线程。热词里提到的“水波纹进度条”,其实就是拿到真实的进度比例后,用 CSS 动画做一个视觉反馈,原理并不复杂,但不能让动画进度脱离真实进度,否则用户会后知后觉。

面试官这时补了一句:“如果用户在上传到一半时切换了网络,比如从 WiFi 切到 4G,你会怎么做?”我的回答是:监听navigator.onLine事件和visibilitychange,一旦检测到断网,立即暂停所有未完成的分片上传请求,保存当前的分片上传状态到本地;恢复网络后,从本地状态读取已上传的分片列表,只上传缺失的部分。这正好呼应了飞书文档在弱网环境下的离线恢复体验。

4.3 场景题进阶:多人实时协作文档的前端架构

大文件上传聊完,面试官把场景升级了一下:“你做过在线文档,假设现在让你给飞书文档设计一个多人同时编辑的前端架构,你会怎么做?”

我给出的设计方案是分层架构:

  • 渲染层:负责文档内容的展示和编辑操作捕获,包括光标位置、选区、输入、删除、格式变化。这部分要尽量轻量,不做任何数据存储。
  • 状态层:维护一个本地文档模型,所有操作先应用在本地模型上,实现“乐观更新”。用户无感知地看到自己的操作立即生效。
  • 通信层:与服务器保持 WebSocket 长连接。操作发生时,把操作序列发送到服务端;服务端广播其他客户端操作,本地收到后应用。为了让消息更实时,可以用 SSE 做单向通知,用 WebSocket 做双向实时操作。
  • 冲突处理层:收到远端操作后,如果和本地操作冲突,通过 OT 算法进行转换,保证每个客户端最终看到一致的结果。
  • 离线缓存层:本地用 IndexedDB 持久化操作日志,断开连接时操作先记到本地,重连后按时间戳和序号重放。

我还加了一个扩展点:如果编辑器是纯文本,CRDT 可能是更容易实现的方案,因为它的数据结构天然支持无冲突合并;但如果是富文本、表格这类结构化数据,OT 更合适,因为富文本的格式边界和嵌套结构非常复杂,CRDT 的元数据膨胀和 GC 压力会变成一个很大的负担。

面试官这里问了一个很细的点:“本地缓存用 IndexedDB 还是其他方案,有没有考虑过 RxDB?”我承认我之前在一个低代码项目里用过 RxDB,它本质是把 IndexedDB 封装成了响应式数据库,适合做离线优先的本地状态管理。但在这里,我的考量是它引入的依赖和心智负担比较大,而文档协同场景的核心是操作日志的顺序和同步,不是复杂的查询,所以直接维护一个操作列表就够了。面试官听完没有反驳,他只说了一句“你用一下就知道这个场景的边界在哪里了”,这句算是给了一个经验性的提示。

场景题答完之后,我最大的感受是:面试官并不是想要一个完美的标准设计,而是想看到你如何拆解问题、如何权衡取舍。你每做一个技术选型,都要能说出理由,否则方案再漂亮也只是空中楼阁。

5. 反问环节与一面节奏复盘

手写题和场景题结束后,面试官很自然地说:“你有什么想问我的?”我当时准备的问题有三个,都围绕岗位实际价值。反问内容我觉得有必要写出来,因为很多同学容易在这个环节“送分”或“送命”。

我问了三个问题:

  1. 团队的技术栈和前端规模是怎样的?协作上有什么比较棘手的挑战?
  2. 你们现在做文档协同,底层渲染是自研的还是基于开源框架二次封装的?
  3. 这个岗位的业务交付节奏如何,前端在跨端和性能优化上有什么比较硬的目标?

这三个问题的共同点是“把面试官当成行业内的人,而不是考官”。我问技术栈和渲染方案,其实是想评估这个岗位的技术深度;问业务交付和目标,是想了解我入职后的成长空间和真实挑战。

有一个问题我原本想问,但觉得不妥,就没有问出口,提醒大家注意:“公司加班多不多”“这个岗位来了之后是不是很卷”这类问题,在一面阶段不要问。一面是技术考察为主,这类问题可以等到 HR 或业务二面再聊,不然面试官容易对你的入职动机产生疑虑。

关于一面整体的时间分配,我复盘了一下:

环节时间内容占比
自我介绍约 3 分钟技术标签 + 项目亮点
项目深挖约 25 分钟文档协同、性能优化、架构设计
基础与原理约 15 分钟事件循环、闭包、浏览器渲染、微前端、框架原理
手写 + 场景约 15 分钟任务调度器、大文件上传、协作文档架构
反问约 5 分钟岗位技术栈、业务挑战

一面接近尾声时,面试官的反馈信号比较明显:他在反问环节结束后,主动问了我“你目前面了几家公司,还有什么流程在走”,以及“如果你后续有二面,希望重点考察哪方面”。这种问题通常意味着面试官对你整体表现比较认可,才会做一定的“预期管理”。

我当时没有直接回答具体公司名称,而是说“目前手上有一个其他公司的流程在走,但飞书这个岗位和我的方向最匹配,所以我更倾向于这里”。这样说既表达了真诚,又不暴露过多细节。

6. 社招一面避坑建议:从这次经历沉淀出来的方法

这一节我专门写给正在准备社招前端面试的同学。我知道很多人会选择刷题、背八股文,但我在这次一面里最大的体会就是:面试官要的从来不是你知道什么,而是你会不会在真实场景里用出来。

6.1 八股文要会“组装”,不能只会“背诵”

面试官问事件循环时,不是直接问“宏任务和微任务的区别”,而是给了一段代码,让你分析输出顺序,再追问嵌套场景。问闭包时,不是问定义,而是直接甩一段循环输出题。这说明,你背下来的知识点必须能和具体代码、具体场景关联起来。我建议把每一个面试题整理成自己的一个“最小案例集”,每看到一个知识点,就想一个“这个现象在项目里出现过吗”。

6.2 项目经验要准备“技术决策”,而不是“功能列表”

这一点是对社招最重要的一条建议。我见过很多简历写“实现了 xx 模块”,但面试官问“为什么这么实现”,答不上来。我的做法是,对简历里的每个项目,拆成五个问题准备:

  1. 项目的核心业务目标是什么?
  2. 你负责的技术难点是什么?
  3. 你调研了哪些方案,为什么最终选了这个?
  4. 上线后有没有出过问题,怎么解决的?
  5. 如果再让你做一次,你觉得哪里能做得更好?

这五个问题,基本覆盖了面试官会追问的所有方向。另外,每个项目要准备 3 到 5 个可以深挖的技术点,并把它们记为“诱饵”。比如大文件上传项目里的“Web Worker + 并发调度 + 断点续传”,就很容易把面试官引到你擅长的地方。

6.3 手写题要“边说边写”,让面试官看到你的思路

手写题最容易犯的错误是闷头写代码,写完才和面试官说话。正确做法是边思考边表达:先确认需求、再说明数据结构、写的过程中解释每一步的意图。甚至在写之前可以说“我先说一下我的整体思路,您看方向对不对”,这不仅能降低写错的风险,还能让面试官觉得你是一个沟通顺畅的协作伙伴。

我在写 TaskScheduler 时,就先说了一句“我需要一个队列来保存等待执行的任务,同时用一个计数器记录当前处于处理中的任务数量”,面试官点了点头,我才开始写。这比直接甩代码要稳妥得多。

6.4 对业务的理解要提前做,尤其是有明确业务属性的岗位

飞书是 To B 协作工具,前端不仅要做界面,还要处理复杂的实时协同、离线编辑、权限控制等问题。如果你只是把前端当作“画页面的”,那大概率会在这种岗位上吃亏。我在面试前把飞书文档里的“评论、划词、版本历史、多人光标”等功能都实际体验了一番,思考背后可能的实现方式。这也让我在聊协作文档场景时,显得像是真正对这个业务场景有研究的人。

6.5 最后一个小技巧:准备一份你的“技术清单”

我所谓的“技术清单”,不是简历,也不是面试题,而是一份写给自己看的能力清单。比如我会写:

  • 我做过最复杂的数据结构是什么?我为什么觉得它复杂?
  • 我最近一个月读过的源码是哪个?我当时关注什么问题?
  • 我在项目里主动优化的最大一个性能瓶颈是什么?
  • 有什么问题是我比大多数人研究得更深?

临面试前一晚,我会快速扫一遍这份清单,它的作用是帮我把“我的技术画像”在脑子里重新拉一遍。面试时无论被问到哪里,我都能快速定位到对应的项目经验和知识储备。

一面结束当晚,我把所有问到的题目重新整理成了一份文档,包括每一道题的解题思路、我当时的回答、现在补充的答案。这个习惯我保持了很多年,每一次面试无论结果如何,都会变成一次技术体系查漏补缺的机会。如果你也在准备大厂社招,建议你也试试看,这比盲目刷三遍面试题要有用得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询