面试经验1
针对你提出的这些面试题,我为你整理了一份**“由浅入深”的全面应答策略**。不仅要告诉你“怎么答”,更要告诉你“面试官考什么”以及“答到什么程度算过关”。
1. React 16 升级到 18 怎么升级?遇到了哪些问题?
- 面试官考什么:工程化实操能力、版本迭代敏感度、并发特性的理解。
- 浅层回答(Pass):执行
npm install react@18 react-dom@18,把ReactDOM.render改成createRoot。 - 深层回答(Offer):
- 升级步骤:①升级依赖;②入口文件改用
createRoot(root).render(<App />);③开启并发特性(如startTransition);④StrictMode在 Dev 下会双重挂载/卸载组件,用于检测副作用。 - 遇到的实际问题:
- 第三方库不兼容:如老版
react-router(v5)或antd(v4)内部未适配新 Root API,需升级配套库。 useEffect执行两次(StrictMode 导致):需要规范清除函数(cleanup),不能假设只执行一次。- SSR 变更:
renderToString虽保留,但流式渲染(Streaming)需改用renderToPipeableStream,服务端适配成本高。 - 自动批处理(Automatic Batching):升级后
setTimeout、Promise中的 setState 也会批处理,如果代码依赖了更新后的立即读取(如ref),需要加flushSync。
- 第三方库不兼容:如老版
- 升级步骤:①升级依赖;②入口文件改用
2. 华为项目里用过哪些技术栈?灵雀、LinkJS、Suitui、Aui?
- 面试官考什么:垂直领域的项目深度,是否了解自研生态 vs 开源生态。
- 应答策略(实话实说+逻辑推理):
- 灵雀(Alauda):通常是华为云内部的容器云平台或低代码配置平台,如果指组件库,它类似 Ant Design Pro 的后台方案。
- LinkJS:大概率是内部封装的微前端通信框架或 SDK 链接库(用于跨应用跳转鉴权)。
- Suitui / Aui:这是华为内部(或合作伙伴)的设计系统/基础组件库,对标外部
Arco/Antd,通常包含移动端(H5)和 PC 端两套。
- 加分项:如果没用过,坦诚说“主要用的是 React/Vue 生态”,但补充一句:“但我理解大厂自研库的核心是为了解决私有化部署、国际化和安全合规问题,且封装了统一的请求拦截和埋点。” 并反问:“您提到的这几个,是否特指华为内部的 DevUI 或 TinyVue 体系?”(体现你对华为开源生态的了解,如
@opentiny/tiny-vue)。
3. Vue2 和 Vue3 的区别
- 浅层:组合式 API vs 选项式 API;
definePropertyvsProxy。 - 深层(面试官想听):
- 响应式底层:Vue2 无法检测对象新增/删除属性(需
$set),数组需重写 7 个变异方法;Vue3 的Proxy能拦截 13 种操作,支持 Map/Set。 - 组件实例:Vue2 的
this指向组件实例,所有东西挂载在this上(性能开销大);Vue3 组合式 API 中this不再是组件上下文(setup中无this),更利于 Tree-shaking 和类型推导。 - Diff 算法:Vue2 全量比较;Vue3 引入静态标记(PatchFlags) + 最长递增子序列,只更新动态节点。
- 体积与碎片化:Vue3 支持 Fragment(多根节点)、Teleport(传送门)、Suspense。
- 响应式底层:Vue2 无法检测对象新增/删除属性(需
4. 怎么理解 Vue2 里面的 this?
- 本质:
this是代理对象(Proxy/代理层),不是单纯的 Vue 实例。 - 机制:Vue 在初始化时,通过
Object.defineProperty将data、computed、methods全部挂载到组件实例上,并做了一层响应式代理。所以你写this.count,实际访问的是data中的count,触发了 getter 进行依赖收集。 - 致命陷阱(必答):箭头函数中不要用
this,因为箭头函数的this指向父级作用域(即外层的 window/undefined),无法指向 Vue 实例。生命周期、methods 必须用普通函数。
5. 怎么理解浏览器的 window?
- 核心:
window是浏览器环境下的全局对象(Global Object),也是 BOM(浏览器对象模型) 的顶级对象。 - 两层含义:
- ECMAScript 层面:它是
globalThis在浏览器端的实现,存放Math、setTimeout、console等。 - 宿主环境层面:它代表当前浏览器窗口,包含
document、location、history、navigator,且通过window.xxx可以访问全局声明的变量。
- ECMAScript 层面:它是
- 深度:
window自身有继承链(__proto__指向Window.prototype),且存在 跨域隔离(不同 iframe 有独立 window)。
6. 数组方法为什么可以直接用?new Array 和字面量 [] 的本质区别?
- 为什么有方法:因为数组是对象,它继承了
Array.prototype。[].map其实是沿原型链找到了Array.prototype.map。这叫原型委托。 - 本质区别(重点):
- 字面量
[]:更推荐,引擎解析时直接创建数组,性能高且易读。 new Array():当传入单个数字参数时,行为诡异——new Array(3)会创建一个 length 为 3 的空数组(稀疏数组),不包含0,1,2这些索引属性;而[3]是长度为 1,包含元素 3。- 结论:除了传参歧义,两者最终实例都是
Array类型,功能无本质差异,但字面量是标准最佳实践。
- 字面量
7. 作为全栈,怎么理解类?类和构造函数的区别?能否外部修改类变量?
- 怎么理解类:类是面向对象编程(OOP)的蓝图。前端视角:React Class 组件/服务层 DTO;后端视角:实体映射(如 Java Spring 的 Entity)。本质是封装数据+行为的模板。
- 类 vs 构造函数:
- 构造函数(ES5)是函数,可被
new调用,也可被普通调用(污染全局);类(ES6)必须用new调用,否则报错。 - 类的方法默认不可枚举,且严格模式下运行;构造函数原型方法默认可枚举。
- 继承实现:类用
extends和super(内部基于Object.setPrototypeOf),比组合继承更规范。
- 构造函数(ES5)是函数,可被
- 外部能否修改变量:
- 看修饰符(JS 虽无真正私有,但有约定)。TS 中用
private编译后虽可绕开,但运行时仍可访问。 - ES2022 私有字段
#value:外部无法访问/修改。 - 如果变量是闭包内部变量(构造器内
let count = 0),外部修改不了;如果是this.count = 0,外部实例可直接instance.count = 10修改。
- 看修饰符(JS 虽无真正私有,但有约定)。TS 中用
8. 怎么理解 Promise?
- 状态机:Pending -> Fulfilled / Rejected,一旦改变不可逆。
- 微任务:
.then/.catch/.finally的回调会推入微任务队列,执行时机在宏任务(setTimeout)之前。 - 链式调用:每个
.then返回新 Promise,解决回调地狱。 - 面试加分项:手写简易 Promise(考察发布订阅模式)或聊聊
async/await是 Generator + 自动执行器的语法糖。
9. 浏览器输入 URL 后发生了什么?
- 经典必考,需分层次回答:
- DNS 解析(递归查询 -> 拿到 IP)。
- TCP 连接(三次握手,HTTPS 额外加 TLS 四次握手)。
- HTTP 请求(构建请求头/体,发送)。
- 服务器响应(返回 HTML 或重定向状态码)。
- 浏览器解析:
- 构建 DOM 树(遇到
<script>可能阻塞,defer/async区别)。 - 构建 CSSOM 树。
- 合成 Render Tree(渲染树),计算布局(Layout),绘制(Paint),合成(Composite)。
- 构建 DOM 树(遇到
- JS 执行(事件循环接管,处理微任务/宏任务)。
10. 这些问题分别考察什么?答到什么程度算通过?
| 面试题 | 考察核心 | 初级(P5) | 中高级(P6/P7)通过标准 |
|---|---|---|---|
| React 16->18 | 版本升级与兼容性 | 知道改 API | 必须说出并发特性、StrictMode 副作用、批处理对业务逻辑的影响,以及如何解决升级中的水合(Hydration)报错。 |
| 华为技术栈 | 项目适配与认知 | 用过/听过名字 | 能抽象出“自研库解决的是私有化安全和统一规范”,并展现出快速上手内部框架的能力。 |
| Vue2 vs 3 | 框架底层原理 | 列举 API 不同 | 讲出 Proxy 相比 defineProperty 解决了哪些 Vue2 遗留痛点(如数组、新增属性),以及 Diff 优化原理。 |
| Vue2 this | JS 执行上下文 | 指向实例 | 讲出数据代理机制(defineProperty 的 getter/setter),以及为什么箭头函数不能用。 |
| Window 对象 | 前端基石 | 全局对象 | 区分 ECMA 规范(Global)与宿主规范(BOM),聊到 iframe 隔离与 postMessage。 |
| 数组方法/原型 | 原型链理解 | 继承自 Array.prototype | 讲出 __proto__ 与 prototype 的区别,new Array(3) 的稀疏数组陷阱。 |
| 类与构造函数 | OOP 与 JS 进化 | 语法糖 | 讲出 class 必须 new、不可枚举、私有字段 #,以及全栈视角下的领域驱动设计(DDD)。 |
| Promise | 异步编程 | 解决回调 | 讲透微任务/宏任务执行顺序,能手写简易版 Promise(至少实现 resolve/reject/then)。 |
| URL 全过程 | 网络与渲染综合 | 简述步骤 | 详细阐述 TCP 握手、浏览器渲染流水线(Layout/Paint/Composite)、阻塞与关键渲染路径优化。 |