Skip to content

面试经验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):升级后 setTimeoutPromise 中的 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;defineProperty vs Proxy
  • 深层(面试官想听)
    • 响应式底层: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。

4. 怎么理解 Vue2 里面的 this?

  • 本质this代理对象(Proxy/代理层),不是单纯的 Vue 实例。
  • 机制:Vue 在初始化时,通过 Object.definePropertydatacomputedmethods 全部挂载到组件实例上,并做了一层响应式代理。所以你写 this.count,实际访问的是 data 中的 count,触发了 getter 进行依赖收集。
  • 致命陷阱(必答)箭头函数中不要用 this,因为箭头函数的 this 指向父级作用域(即外层的 window/undefined),无法指向 Vue 实例。生命周期、methods 必须用普通函数。

5. 怎么理解浏览器的 window?

  • 核心window 是浏览器环境下的全局对象(Global Object),也是 BOM(浏览器对象模型) 的顶级对象。
  • 两层含义
    1. ECMAScript 层面:它是 globalThis 在浏览器端的实现,存放 MathsetTimeoutconsole 等。
    2. 宿主环境层面:它代表当前浏览器窗口,包含 documentlocationhistorynavigator,且通过 window.xxx 可以访问全局声明的变量。
  • 深度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 调用,否则报错。
    • 类的方法默认不可枚举,且严格模式下运行;构造函数原型方法默认可枚举。
    • 继承实现:类用 extendssuper(内部基于 Object.setPrototypeOf),比组合继承更规范。
  • 外部能否修改变量
    • 看修饰符(JS 虽无真正私有,但有约定)。TS 中用 private 编译后虽可绕开,但运行时仍可访问。
    • ES2022 私有字段 #value:外部无法访问/修改。
    • 如果变量是闭包内部变量(构造器内 let count = 0),外部修改不了;如果是 this.count = 0,外部实例可直接 instance.count = 10 修改。

8. 怎么理解 Promise?

  • 状态机:Pending -> Fulfilled / Rejected,一旦改变不可逆。
  • 微任务.then/.catch/.finally 的回调会推入微任务队列,执行时机在宏任务(setTimeout)之前。
  • 链式调用:每个 .then 返回新 Promise,解决回调地狱。
  • 面试加分项:手写简易 Promise(考察发布订阅模式)或聊聊 async/await 是 Generator + 自动执行器的语法糖。

9. 浏览器输入 URL 后发生了什么?

  • 经典必考,需分层次回答
    1. DNS 解析(递归查询 -> 拿到 IP)。
    2. TCP 连接(三次握手,HTTPS 额外加 TLS 四次握手)。
    3. HTTP 请求(构建请求头/体,发送)。
    4. 服务器响应(返回 HTML 或重定向状态码)。
    5. 浏览器解析
      • 构建 DOM 树(遇到 <script> 可能阻塞,defer/async 区别)。
      • 构建 CSSOM 树。
      • 合成 Render Tree(渲染树),计算布局(Layout),绘制(Paint),合成(Composite)。
    6. JS 执行(事件循环接管,处理微任务/宏任务)。

10. 这些问题分别考察什么?答到什么程度算通过?

面试题考察核心初级(P5)中高级(P6/P7)通过标准
React 16->18版本升级与兼容性知道改 API必须说出并发特性、StrictMode 副作用、批处理对业务逻辑的影响,以及如何解决升级中的水合(Hydration)报错。
华为技术栈项目适配与认知用过/听过名字能抽象出“自研库解决的是私有化安全和统一规范”,并展现出快速上手内部框架的能力。
Vue2 vs 3框架底层原理列举 API 不同讲出 Proxy 相比 defineProperty 解决了哪些 Vue2 遗留痛点(如数组、新增属性),以及 Diff 优化原理。
Vue2 thisJS 执行上下文指向实例讲出数据代理机制(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)、阻塞与关键渲染路径优化。
最近更新