佰钧成 社招 一面
1. “评估需求、排期”的工作流程?
“我的工作流程一般是这样的:
- 需求评审: 首先会和产品、后端同学一起过需求,确保我完全理解了业务背景和要实现的价值,而不仅仅是功能点。
- 技术方案设计: 之后,我会进行技术方案的初步设计,评估实现的可行性和技术难点,比如是否需要新技术、是否存在兼容性风险、是否需要后端配合接口设计等。
- 工时评估: 基于技术方案,我会将需求拆解成一个个具体的开发任务点,并为每个任务评估一个保守且合理的工时。评估时会留出20%左右的Buffer时间用于应对意外情况(如联调阻塞、bug修复)。
- 排期同步: 将评估结果和排期与产品、测试同步,达成一致后,就进入开发。
2.页面错误是如何处理,比如页面白屏页面报错你是如何第一时间知道的
让反馈人一次性给齐:机型/系统、网络(4G/Wi-Fi/公司代理)、登录态、页面路径+操作步骤、发生时间(方便对日志对点)。
同步两件事:
a.本地调试环境复现(开发者工具 →详情→ 真机调试);
b.临时开启线上埋点(onError、接口耗时、首屏超时点)
定位问题的关键方法
1本地复现
在本地调试环境复现问题,检查控制台是否有错误日志。
使用浏览器开发工具(DevTools)的 Network面板检查资源加载是否成功。
2 线上日志分析
分析监控平台或后端日志,定位问题发生的频率、用户环境和错误堆栈,
3 用户环境验证
检查用户浏览器、操作系统版本、网络环境等因素。
4 断点调试
- 5.常见坑位速查表
- 分包路径大小写、页面相对路径写错。
- 合法域名漏配子域,开发可用,线上全白。
- 全屏cover-view /oading 遮罩未移除。
- 图片原图过大(超大长图、base64),低端机染崩。
3.vue2和vue3的区别
Vue2是使用object.defineproperty来做的,
在页面刚开始加载时,Vue会遍历data中的所有属性,
然后使用object.defineproerty把这些属性全部转为getter/setter,
当用户访问或修改某个属性时会触发对应的getter/setter方法,然后会通知每个组件实例对应的watch方法,
最后实现视图的更新。defineproperty的缺点:
1.对于复杂对象需要深度监听,一次性监听到底,它的计算量是非常大的,性能也是不太好的
2.对于新增、删除操作是无法监听的,需要使用到Vue.set和Vue.set和Vue.set和Vue.delete来作为辅助
3.需要重写数组的原生方法来实现数组的监听所以Vue3使用proxy代替Vue2的defineproperty。
proxy的优势:
1.它可以监听整个对象,而不需要遍历监听属性,性能会有所提升
2.它可以直接监听数组的变化,而不需要重写数组的原生方法,它的便利性会增加很多
3.它有多达13种拦截方法,所以它的功能会更强大
4.proxy作为一个新标准,它会收到浏览器厂商持续的性能优化,也就是它会享受到传说中的新标准的性能红利。解题思路:
1.Vue2是怎么做的?
2.Vue2这种方法有什么问题?
3.Vue3是怎么做的?
4.Vue3又是怎么解决Vue2的这些问题?
4.闭包的优缺点,什么场景下用到
闭包是什么:JS中内层函数可以访问外层函数的变量,外层函数无法操作内存函数的变量的特性。我们把这个特性称作闭包。
闭包的好处:
- 隔离作用域,保护私有变量;有了闭包才有局部变量,要不然都是全局变量了。
- 让我们可以使用回调,操作其他函数内部;
- 变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期;
闭包的弊端:内层函数引用外层函数变量,内层函数占用内存。如果不释放内存,过多时,易引起内存泄露。
解决办法:无法自动销户,就及时手动回收,使用后将函数的引用赋null。
5.js的数据类型
string number null undefined boolean object bigInt symbol
6.检测 JavaScript 数据类型时,typeof和 instanceof 有什么区别?
typeof 和 instanceof都是用来检测JavaScript 数据类型的,但两者用途和适用场景不同:
6.1.typeof
·用于检测基本数据类型
typeof'abc'//'string
typeof 123// 'number
typeof true//'boolean'
typeof undefined //'undefined'
typeof symbol()//'symbol'
typeof BigInt(1)//'bigint'
·局限性:
typeof null //'object'(特殊情况)
.typeof {} // 'object
typeof [] // 'object
typeof function(){} //"function'
6.2.二、instanceof
·判断对象是否属于某个构造函数的实例:
[] instanceof Array // true
{}instanceof object // true
new Date()instanceof Date // true
·局限性:
'abc'instanceof string // false,基础类型返回false
iframeArray instanceof Array //false,不同全局对象
- 仅适用于引用类型(对象),不适用于基本类型:
- 跨iframe等不同上下文时,可能失效:
推荐实践:
基础类型优先用 typeof
对象类型优先用 instanceof或0bject.prototype.toString.call()。
例如:
Object.prototype.tostring.call([])//[object Array]Object.prototype.tostring.call(null)//[object Null]
7.性能优化
7.1.一、页面渲染性能优化
1.虚拟列表与长列表优化
使用 vue-virtual-scroller 实现长列表虚拟滚动,只渲染可视区域的 DOM 节点
避免一次性渲染数百或上千条数据导致卡顿
优化后页面滚动流畅度提升明显,卡顿问题基本消除。
2.组件懒加载与路由懒加载。
利用 Vue 异步组件和import()实现按需加载页面和组件。
首屏体积减小约 30%,首屏加载速度提升 1~2 秒。
3.合理使用 v-show替代 v-if
减少频繁销毁重建组件,提升视图切换性能。
7.2.二、网络请求与接口性能优化
1.接口合井与请求缓存。
合并多接口为一个批量接口,减少请求数量;
对部分静态数据实现本地缓存(如用户权限、字典表),免重复请求。
2.防抖和节流
对搜索框输入、窗口 resize 等高频操作加防抖/节流;
显著降低请求频率,减轻后端压力。
7.3.三、构建与打包优化
1.按需引入和 Tree shaking。
替换全量导入组件库为按需加载(如 Element Plus):
启用生产环境 Tree Shaking,有效减少无用代码。
2.CDN 外链和 externals 配置
将 Vue、ECharts 等大依赖通过 CDN 引入,减小打包体积
Bundle 体积缩小约 40%。
3.代码分割与缓存策略
配置 SplitChunks 拆分公共代码和第三方库;
使用 contenthash 保证缓存命中,提升用户二次访问速度。
8.请解释一下什么是模块化开发?
解答:模块化开发是一种组织代码的方法,它将应用程序分解成独立的、可复用的模块。每个模块负责实现特定的功能,并通过导出和导入API与其他,口模块通信。模块化开发有助于代码的组织、维护和重用,同时也促进了团队协作。
9.ES6 你使用过哪些语法特性?简单介绍一下
1.块级作用域:let 和 const
- 替代 var,解决变量提升和作用域污染问题;
- const 用于定义常量不可重新赋值,
- 实际项目中我默认用const需要修改时才用 let
2.箭头函数
- 简化函数写法;
- 自动绑定 this,常用于事件回调、数组操作等;
3.解构赋值
- 更方便地从对象或数组中提取变量;
配合函数参数结构体使用频率很高,
4.模板字符串
- 支持变量插入和多行字符串,避免字符串拼接混乱;
5.模块化:import/export
- 实现 ES 模块机制;
6.Promise 异步编程
- 提供更优雅的异步写法,避免回调地狱;
我通常在封装请求或并发控制时使用。
7.展开运算符/剩余参数(…)
- 对象/数组拷贝、合并、函数参数处理都非常方便:
10.JS性能优化
层面 | 关键优化点 |
---|---|
编码 | 减少查找、优化循环、事件委托、防抖节流 |
DOM | 批量操作、使用 DocumentFragment 、避免布局抖动 |
内存 | 解除引用、避免泄漏、使用 WeakMap |
网络 | 压缩、代码分割、Tree Shaking、利用缓存 |
加载 | 使用 async /defer 属性 |
API | Web Workers, rAF , Intersection Observer |