前端面试中,无论是大厂还是小厂,基础功底和技术视野都是考察的重点。尤其对于小厂而言,更倾向于招聘 “即插即用” 的全能型人才 —— 既要扎实掌握 CSS、JS 等核心知识,又要了解框架实战和前沿技术。本文整理了 12 个小厂高频面试题,从盒模型到 AI 工具使用,帮你全面梳理考点,轻松应对面试。
一、CSS 基础:盒模型与定位
1. 被问烂的盒模型,该怎么答才加分?
面试官问 “CSS 盒模型” 时,别只说 “标准和怪异两种”,关键是讲清区别和使用场景:
- 标准盒模型(content-box) :width/height 仅包含内容区,总尺寸 = 内容 + 内边距 + 边框 + 外边距。这种模式下,调整 padding 或 border 会意外撑大元素,布局时容易出问题。
- 怪异盒模型(border-box) :width/height 包含内容、内边距和边框。无论怎么调整内边距和边框,元素总尺寸始终不变,极大简化了响应式布局计算。
- 实战建议:现代开发中几乎都会用
box-sizing: border-box统一盒模型,可举例说明 “在做卡片布局时,添加内边距不会导致卡片换行”。
2. 定位属性不止 “relative 和 absolute”
CSS 定位是布局的核心,回答时要结合使用场景,体现实战经验:
- static:默认值,按文档流排列,适合普通内容布局。
- relative:相对自身偏移,保留原位置,常用于 “微调元素位置” 或 “作为 absolute 的父容器”。
- absolute:脱离文档流,相对于最近的非 static 祖先定位,适合 “弹窗、下拉菜单” 等需要悬浮的元素。
- fixed:相对于浏览器窗口定位,滚动时位置不变,典型场景是 “顶部导航栏、回到顶部按钮”。
- sticky:滚动到阈值后固定,比如 “列表标题随滚动粘在顶部”,注意父元素不能有 overflow:hidden。
二、JavaScript 核心:变量、拷贝与运算符
3. var/let/const 的区别,面试官想听这些细节
这道题考察对 ES6 的理解,别只说 “块级作用域”,要讲清底层差异:
- 作用域:var 是函数作用域,let/const 是块级作用域(
{}内有效)。比如在 for 循环中,var 声明的变量会泄露到外部,而 let 不会。 - 变量提升:var 会提升到作用域顶部,声明前使用返回 undefined;let/const 虽也提升,但存在 “暂时性死区”,声明前使用会报错。
- 重复声明:var 允许重复声明,let/const 则会报错。
- const 细节:声明时必须赋值,且不能重新赋值,但对象 / 数组的属性可以修改(因为是 “引用常量”)。
4. 深浅拷贝:不止 “JSON.parse” 这么简单
浅拷贝和深拷贝的核心区别在于是否复制嵌套对象:
-
浅拷贝:只复制第一层,嵌套对象复制引用。常用方法:
Object.assign()、扩展运算符...、数组的slice()/concat()。 -
深拷贝:完全复制所有层级,生成新对象。实现方式:
JSON.parse(JSON.stringify(obj)):简单但有缺陷(无法复制函数、undefined、Symbol,不支持循环引用)。- 递归实现:手动遍历对象,对不同类型(数组、对象、Date 等)单独处理,可解决 JSON 方法的问题。
- 第三方库:Lodash 的
_.cloneDeep()(工业级方案)。
5. 展开运算符:是深拷贝还是浅拷贝?
展开运算符(...)本质是浅拷贝,仅复制第一层元素 / 属性:
const obj = { a: 1, b: { c: 2 } };
const newObj = { ...obj };
newObj.b.c = 3;
console.log(obj.b.c); // 输出3,说明嵌套对象共享引用
总结:展开运算符适合复制扁平对象,处理嵌套结构时需配合深拷贝方法。
三、布局实战:从两列布局到移动端适配
6. 左固定右自适应:3 种方案对比
实现 “左固定右自适应” 布局,不同方案各有优劣:
| 方案 | 代码示例 | 优点 | 缺点 |
|---|---|---|---|
| Flex 布局 | .container { display: flex; } .left { width: 200px; } .right { flex: 1; } | 简单直观,兼容性好(IE10+) | 无明显缺点,现代开发首选 |
| Float+Margin | .left { float: left; width: 200px; } .right { margin-left: 200px; } | 兼容性极佳(IE6+) | 需清除浮动,避免父元素高度塌陷 |
| Position+Margin | .container { position: relative; } .left { position: absolute; width: 200px; } .right { margin-left: 200px; } | 实现简单 | 脱离文档流,可能影响其他元素 |
7. 移动端适配:rem 和 lib-flexible 的原理
移动端适配的核心是 “等比缩放”,rem 是常用方案:
-
rem 的优势:基于根元素(html)的 font-size 计算,通过动态调整 font-size,可让元素随屏幕宽度等比变化。
-
lib-flexible 工作流程:
- 动态设置 viewport 的 scale(如设计稿 750px,设备 375px 时 scale=0.5)。
- 计算 html 的 font-size(通常为屏幕宽度的 1/10,如 375px 屏幕下 font-size=37.5px)。
- 开发者按设计稿尺寸除以 100(如设计稿中 200px 的元素,写成 2rem),实现无缝适配。
-
注意:现在更推荐使用 vw/vh 结合 flexible,或直接用 postcss-px-to-viewport 自动转换单位。
四、框架与组件设计
8. 高复用组件:5 个设计原则 + 实例
设计可复用组件,需兼顾灵活性和易用性:
-
单一职责:一个组件只做一件事,比如 “Button 组件只负责按钮样式和点击逻辑”,避免堆砌无关功能。
-
可配置性:通过 props 暴露配置项,例如:
<Button type="primary" size="large" disabled={false} onClick={handleClick}>
提交
</Button>
-
状态管理:内部状态(如 loading)由组件自身维护,外部数据通过 props 传入,避免不必要的状态提升。
-
样式隔离:使用 CSS Modules(
import styles from './Button.module.css')或 BEM 命名法(button--primary)防止样式冲突。 -
文档完善:注明 props 类型、默认值和使用示例,可配合 Storybook 生成交互文档。
9. React 数据请求:为什么选 useEffect?
在 React 中,数据请求的最佳位置是useEffect钩子:
-
执行时机:
useEffect在组件渲染完成后执行,不会阻塞 UI 显示(比componentWillMount更合理)。 -
依赖控制:通过第二个参数(依赖数组)控制请求时机,例如
useEffect(() => { fetchData() }, [id]),仅在 id 变化时重新请求。 -
清理机制:返回清理函数可取消未完成的请求,避免组件卸载后触发状态更新(防止内存泄漏):
useEffect(() => {
const controller = new AbortController();
fetch('/data', { signal: controller.signal }).then(res => res.json());
return () => controller.abort(); // 组件卸载时取消请求
}, []);
10. useEffect 深度解析:生命周期的替代者
useEffect并非简单对应某个生命周期,而是更灵活的副作用处理机制:
- 模拟 componentDidMount:依赖数组为空时(
[]),仅在组件挂载后执行一次。 - 模拟 componentDidUpdate:依赖数组包含变量时(如
[count]),初始渲染和 count 变化后都会执行。 - 模拟 componentWillUnmount:返回的清理函数在组件卸载或依赖变化前执行。
- React 18 注意点:严格模式下,开发环境会执行两次 effect,需确保清理函数能正确处理重复执行的情况(比如移除事件监听时要对应添加的监听)。
五、AI 时代:工具使用与效率提升
11. AI IDE 高效使用指南
AI 工具(GitHub Copilot、Cursor 等)是开发利器,但需掌握正确方法:
- 精准描述需求:避免模糊指令,例如不说 “写个登录功能”,而说 “用 React hooks 写一个登录表单,包含用户名 / 密码验证,成功后跳转首页”。
- 分步骤生成:复杂功能拆分为小任务,先让 AI 生成框架,再逐步完善细节(如先写组件结构,再加状态逻辑)。
- 严格审查代码:AI 生成的代码可能存在逻辑漏洞(如未处理错误边界)或性能问题(如不必要的渲染),必须逐行检查并测试。
- 学习复用:将 AI 生成的优质代码(如优雅的数组处理方法)整理成代码片段,积累个人知识库。
12. 降低 AI 代码错误率的 5 个技巧
当 AI 生成的代码有 bug 时,可通过以下方法优化:
- 补充上下文:在 prompt 中加入项目技术栈(如 “使用 Vue 3 的 Composition API”)、现有函数 / 变量定义,帮助 AI 理解环境。
- 提供示例代码:给出类似功能的正确实现,让 AI 模仿风格(例如 “参考下面的表单验证逻辑,实现注册功能:[代码示例]”)。
- 明确错误信息:告诉 AI 代码的具体问题(如 “这段代码在输入为空时会报错,需要添加判断”),而不是只说 “代码有问题”。
- 结合单元测试:让 AI 同时生成测试用例(如 “为这个函数写 Jest 测试,覆盖正常输入和边界情况”),通过测试快速验证代码正确性。
- 限定输出格式:要求 AI 按特定格式返回(如 “先写思路,再给代码,最后说明注意事项”),便于理解和修改。
总结
小厂面试更注重 “实用性”,既考察基础是否扎实,也关注解决实际问题的能力。从 CSS 盒模型到 React hooks,再到 AI 工具的使用,掌握这些核心考点,不仅能顺利通过面试,更能提升日常开发效率。记住:技术面试的本质不是背答案,而是展现你的理解深度和解决问题的思路。