本次面经共 2 轮。每轮单独成文;轮次标题重复时,以“第 N 轮”和稳定的轮次 ID 区分。
轮次导航
- 第 1 轮 · 一面(24 道题)
- 第 1 轮 · 二面(10 道题)
← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮共 10 道题。答案默认折叠,便于先自行作答。 1. 介绍一下你觉的最有成就感的项目 题目要点 略 参考答案 略 2. 项目为什么选择Lerna+Yarn Workspaces构建Monorepo 题目要点 Monorepo 实现多包统一管理,提升代码复用和维护效率 Lerna 管理版本发布、变更检测、脚本执行 Yarn Workspaces 优化依赖安装,支持本地包软链接 两者结合,实现高效、便捷的 Monorepo 构建和维护 适合大型复杂项目及多包同步开发场景 参考答案 一、考察点 理解 Monorepo 的概念及优势 多个相关包/模块统一管理、版本控制、发布流程等 掌握 Lerna 与 Yarn Workspaces 的功能和配合方式 包管理、依赖安装优化、版本发布、脚本执行等 能够分析技术选型的利弊和实际应用场景 团队协作、构建效率、依赖一致性等 展示架构设计思路和实践经验 二、参考答案 1.1 原理说明 Monorepo 概念 将多个相关的项目包(packages)放在同一代码仓库中统一管理 便于代码复用、版本统一、跨包协调 Lerna 功能 管理 Monorepo 中多个包的版本发布和依赖关系 支持基于 Git 的变更检测,自动决定哪些包需要发布 脚本集中执行,提升跨包开发效率 Yarn Workspaces 功能 优化依赖安装,自动将多个包的依赖扁平化安装,避免重复依赖 支持包之间的本地软链接,方便跨包开发调试 减少 node_modules 大小,提升安装速度 Lerna + Yarn Workspaces 配合优势 Lerna 专注版本和发布管理 Yarn Workspaces 专注依赖管理和安装优化 组合使用,实现 Monorepo 的高效管理和性能提升 1.2 核心用法 + 选择理由 选择 Lerna + Yarn Workspaces 的具体理由 依赖管理高效:Yarn Workspaces 扁平化依赖树,减少冗余,提高安装速度,节省磁盘空间 版本发布便捷:Lerna 支持自动检测改动包,实现增量发布,减少发布成本 跨包开发友好:Workspaces 实现包间软链接,调试时无需发布即可实时联动 统一管理多个包:代码结构清晰,版本一致性好,避免包版本冲突 社区成熟稳定:Lerna 和 Yarn 是成熟开源项目,生态完善,文档丰富 使用场景举例 大型前端项目拆分为多个业务组件包 同时管理多个相关 npm 包,需同步发布和升级 需要提升 CI/CD 流程效率和开发体验 1.3 常见误区或面试陷阱 ❌ 误区一:认为 Lerna 可以独立完成所有 Monorepo 管理工作 实际 Lerna 本身不管理依赖安装,需配合 Workspaces 或 npm/yarn 其他特性 ❌ 误区二:忽视依赖扁平化带来的版本冲突风险 需要合理规划依赖版本,避免冲突和不兼容 ❌ 误区三:Monorepo 不适合所有项目,盲目迁移可能增加复杂度 适用项目规模和团队协作需求需评估清楚 3. 如何解决子包间的循环依赖问题 题目要点 循环依赖会导致加载异常和维护困难 抽取公共模块拆分依赖,消除环路 使用接口抽象和依赖注入解耦 动态导入延迟加载,规避同步循环 设计单向依赖,保持依赖关系 DAG 配合工具检测和团队规范防范 参考答案 一、考察点 理解循环依赖的概念及危害 ...
← 已是第一轮 · 返回本次面经 · 第 1 轮 → 本轮要点: 作用域链与闭包、全方位解读this、函数柯里化、原型链与继承、DOM操作、深拷贝/浅拷贝、call、apply和bind 本轮共 24 道题。答案默认折叠,便于先自行作答。 1. 深拷贝浅拷贝有什么区别?怎么实现深拷贝? 题库原题:深拷贝浅拷贝有什么区别?怎么实现深拷贝? 题目要点 JS数据类型分别基本数据类型和引用数据类型,基本数据类型保存的是值,引用类型保存的是引用地址(this指针)。 浅拷贝共用一个引用地址,深拷贝会创建新的内存地址。 浅拷贝方法 直接对象复制 Object.assign 深拷贝 JSON.stringify转为字符串再JSON.parse 深度递归遍历 参考答案 一、数据类型存储 前面文章我们讲到,JavaScript中存在两大数据类型: 基本类型 引用类型 基本类型数据保存在在栈内存中 引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中 二、浅拷贝 浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝 如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址 即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址 下面简单实现一个浅拷贝 function shallowClone(obj) { const newObj = {}; for(let prop in obj) { if(obj.hasOwnProperty(prop)){ newObj[prop] = obj[prop]; } } return newObj; } 在JavaScript中,存在浅拷贝的现象有: Object.assign Array.prototype.slice(), Array.prototype.concat() 使用拓展运算符实现的复制 Object.assign var obj = { age: 18, nature: ['smart', 'good'], names: { name1: 'fx', name2: 'xka' }, love: function () { console.log('fx is a great girl') } } var newObj = Object.assign({}, obj); slice() const fxArr = ["One", "Two", "Three"] const fxArrs = fxArr.slice(0) fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"] concat() const fxArr = ["One", "Two", "Three"] const fxArrs = fxArr.concat() fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"] 拓展运算符 const fxArr = ["One", "Two", "Three"] const fxArrs = [...fxArr] fxArrs[1] = "love"; console.log(fxArr) // ["One", "Two", "Three"] console.log(fxArrs) // ["One", "love", "Three"] 三、深拷贝 深拷贝开辟一个新的栈,两个对象的属性完全相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性 ...