1. 莉莉丝前端一面:先搞清楚这场面试在筛什么
做了这么多年前端,也面过不少人,说句实话,莉莉丝游戏这类公司的前端一面,考察逻辑和普通业务型互联网公司是有明显差异的。2026年这轮春招面经里,莉莉丝一面给我的感觉是:基础考察范围非常标准,但追问深度比想象的狠。所谓“前端八股文”,其实并不是死记硬背就能过的,而是面试官用来快速判断你水平的一把尺子。
先给还没面的同学定个心。莉莉丝前端一面通常不会一上来就聊业务,也不会直接扔一道LeetCode hard让你手撕,它更偏向于“基础能力摸底 + 项目真实度验证 + 临场思维习惯观察”。换句话说,一面筛掉的是那些简历写得天花乱坠、但一问底层就露怯的候选人。所以这篇文章的核心目的,就是帮你把前端一面最常考的“八股文”按场景拆开揉碎,讲清楚每道题背后面试官的真实意图,以及你该怎么答才能从“背答案”升级为“讲逻辑”。
我结合莉莉丝2026年2月5日这场前端一面的面经内容,把高频考点分成几个大类:JavaScript基础与异步、CSS布局与渲染、浏览器与网络、框架原理(React为主)、手写代码题、项目深挖与软技能。每个板块我都会给你可复用的答题思路,同时补充一些我面试别人时特别在意的细节。这些内容不止适用于莉莉丝,字节、腾讯、蚂蚁这类大厂的前端一面,底层逻辑大差不差。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 前端一面必考的JavaScript基础:别只背结论,要能讲清原理
2.1 事件循环(Event Loop)——一面必问,但九成人答不全
莉莉丝一面问到了宏任务和微任务的执行顺序。这道题表面上是考事件循环,实际上是看你有没有真正理解JavaScript的单线程模型。很多候选人能背出“先同步、再微任务、再宏任务”这句话,但一给复杂例子就乱了。
建议你按这个层次来答:
第一层,先明确JavaScript是单线程语言,一次只能执行一个任务,这是为了避免多线程操作DOM时产生竞态问题。
第二层,说清楚任务队列分两种:宏任务(macrotask)包括script整体代码、setTimeout、setInterval、I/O操作、UI渲染;微任务(microtask)包括Promise.then、MutationObserver、queueMicrotask、async/await中await之后的代码。
第三层,讲执行流程:执行一个宏任务 → 执行所有微任务 → 渲染(如果需要) → 取下一个宏任务。这里最关键的是“执行完一个宏任务后,要清空整个微任务队列,才会进入下一个宏任务”。而且,微任务执行过程中如果又产生了新的微任务,会继续追加到当前微任务队列,直到队列完全清空。
我见过不少候选人在这里翻车。比如下面这段代码:
javascript复制console.log('start');
setTimeout(() => {
console.log('timeout1');
Promise.resolve().then(() => {
console.log('promise1');
});
}, 0);
Promise.resolve().then(() => {
console.log('promise2');
});
console.log('end');
正确的输出顺序是:start → end → promise2 → timeout1 → promise1。为什么promise1在timeout1后面?因为setTimeout产生的回调本身是一个宏任务,只有当微任务队列清空后才会执行它;执行timeout1回调时,它内部又注册了一个微任务promise1,这个微任务会在当前宏任务结束后立即执行,所以promise1紧接着timeout1输出,而不是等到下一轮。
面试官如果继续深挖,可能会问async/await的实现原理。你可以说await本质上是对Promise的语法糖,await后面的代码相当于被放进了.then回调里。但要注意,await那行代码本身会先同步执行,只有await之后的代码才作为微任务入队。这个细节很多人会忽略,导致回答有偏差。
2.2 闭包与作用域链——回答要有场景感
闭包几乎是前端面试的标配题。莉莉丝一面也问了“闭包是什么,实际开发中有哪些应用场景”。这道题想听到的不是教科书定义,而是你能不能在真实项目里认出闭包。
我的答题思路是拆成三个部分:
先说定义:闭包是指函数能够访问其词法作用域之外的变量,即使这个函数在外部执行,它依然持有对定义时作用域的引用。JavaScript中,函数在创建时就会形成闭包,这由词法作用域规则决定。
再说原理:函数对象内部有一个[[Environment]]属性,保存着函数定义时的词法环境。当函数执行时,会创建新的词法环境,其外部引用指向[[Environment]],于是形成了作用域链。外部变量之所以能被访问,就是因为作用域链上能找到对应的环境记录。
最后给场景:一个典型场景是防抖和节流函数的实现。比如防抖函数内部会保存一个timer变量,返回的函数每次执行时都能访问到它,这就是闭包。另一个场景是React中useState的setState更新函数,虽然表面上是框架封装,但底层也是通过闭包来持有对应的状态更新逻辑。还有Hook的使用,为什么useEffect能拿到最新的props和state?本质上也是因为每一次渲染都形成了新的闭包。
注意:如果面试官追问“闭包会带来什么问题”,一定要提到内存泄漏。旧版本IE中,如果DOM元素的事件回调持有对外部对象的引用,而外部对象又引用这个DOM元素,就会形成循环引用导致内存无法回收。现代浏览器的垃圾回收器已经能处理循环引用,但要避免无意间持有大量不必要的数据。回答时最好补一句:在开发中,长列表、定时器、全局事件监听器这些场景,用完要记得清理。
3. CSS与浏览器渲染:一面最爱考的背后原理
3.1 盒模型与BFC——答出底层逻辑才算过
盒模型是CSS最基础的概念,但莉莉丝一面问得比预想中细。面试官问:“标准盒模型和IE盒模型有什么区别?如何切换?”这个问题的价值在于,它考察你对CSS布局机制的理解是不是停留在“会用”层面。
标准盒模型中,width只包含content宽度,padding和border会额外增加元素的宽度。而IE盒模型(即border-box)中,width已经包含了content、padding和border。如今绝大多数项目都会在全局样式中设置:
css复制* {
box-sizing: border-box;
}
这样设置的好处是,在栅格布局、百分比宽度等场景下
