JS 内存泄漏如何检测?场景有哪些?
- 检测: 1.1 浏览器的控制台->performance->勾选 Memory->左侧红点开始->stop 结束->clear 清除; 1.2 观察 HEAP 数据(正常为锯齿状,泄漏一直升高);
- 场景 2.1 被全局变量,函数引用,组件销毁时未清除; 2.2 被全局事件,定时器引用,组件销毁时未清除; 2.3 被自定义事件引用,组件销毁时未清除;
垃圾回收(GC)的算法:
- 引用计数(之前),但是循环引用会发生内存泄漏;
//IE6-IE7 内存泄漏的bug
var div1=docment.getElementById('div1');
div1.a=div1;
2.标记清除:不定时的从 window 遍历,看是否可以得到某个变量,可以得到/不可以得到,保留/删除;
闭包是内存泄漏吗?
闭包不属于内存泄漏,内存泄漏是预期之外的数据不可以被垃圾回收,而闭包的数据不可以被垃圾回收是预期范围内的;
weakMap 和 weakSet
weakMap 和 weakSet 是弱引用,有 get 方法,但是没有 forEach 和 size 方法; weakMap 和 weakSet 的 key 必须是引用类型,value 可以是值类型;
浏览器和 node.js 的时间循环又什么区别?
浏览器和 node.js 的 event loop 流程基本相同;
node.js 的宏任务和微任务分类型和优先级
单线程和异步
js 是单线程(无论浏览器还是 node.js),浏览器中的 js 执行和 DOM 渲染共用一个线程;
宏任务和微任务(浏览器)
宏任务,如 setTimeout,setInterval,网络请求等;
微任务,如 promise,async/await;
微任务在下一轮 DOM 渲染之前执行,宏任务在之后执行;
浏览器执行顺序
同步任务->微任务->网页渲染->宏任务;
先执行同步任务,遇到宏任务或者微任务分别放到两个队列里,当同步任务执行完后,触发 Event loop 机制,执行微任务,接着执行网页的渲染,再执行宏任务;
node.js 异步
Node.js 同样使用 ES 语法,也是单线程,也需要异步.异步任务也分为:宏任务,微任务.但是,它的宏任务和微任务分不同的类型,有不同的优先级;
node.js 宏任务类型和优先级(由高到低)
Timers-setTimeout,setInterval;
I/O callbacks-处理网络,流,TCP 的错误回调;
Idle,prepare-闲置状态(nodeJS 内部使用);
poll 轮训-执行 poll 中的 I/O 队列;
Check 检查-存储 setImmediate 回调;
Close callbacks- 关闭回调,如 socket.on('close');
node.js 宏任务类型和优先级
promise,async/await,process.nextTick;
process.nextTick 的优先级最高;
nodejs 执行顺序
执行同步代码-> 执行微任务(process.nextTick 优先级最高)->按照 6 个优先级的顺序执行宏任务
新版本 node.js 推荐使用 setImmediate 代替 process.nextTick;
vdom 真的很快吗?
vdom 并不快,JS 直接操作 DOM 才是最快的,但"数据驱动视图",要有合适的方案,不能全部 DOM 重建,vdom 就是目前最合适的技术方案.
vdom
Virtual DOM ,虚拟 DOM.用 JS 对象模拟实现 DOM 节点数据,由 React 最先推广使用.
Vue React 等框架的价值
组件化
数据视图分离,数据驱动视图(重要)
遍历数组,for 和 forEach 那个更快?
for 会更快,forEach 每次都要创建一个函数来调用,而 for 不会创建函数;函数需要独立的作用域,会有额外的开销;
nodejs 如何开启进程,进程如何通讯?(PM2)
进程:OS 进行资源分配和调度的最小单位,有独立的内存空间;
线程:OS 进行运算调度的最小单位,共享进程内存空间;
JS 是单线程的,但可以开启多进程执行,如 WebWorker;
答案:开启子进程 child_process.fork 和 cluster.fork,使用 send 和 on 传递信息;
为何需要多进程
多核 CPU,更适合处理多进程;
内存较大,多个进程 才好利用(单进程有内存上限)
什么是 js Bridge 实现原理?
常见的实现方式?
注册全局 API
URL Scheme
requestIdCallback 和 requestAnimationFrame 有什么区别?
requestAnimationFrame 每次渲染完都会执行,高优;
requestIdCallback 空闲时才会执行,低优;
由 React fiber 引起的关注
组件树转换为链表,可以分段渲染;
渲染时可以暂停,去执行其他高优任务,空闲时再继续渲染;
如何判断空闲?- requestIdCallback;
他们是宏任务还是微任务
都是宏任务,因为他们在 DOM 渲染完才会执行;
vue 每个生命周期都做了什么?
beforeCreate:创建一个空白的 vue 实例,data method 尚未被创建,不可以使用;
created:Vue 实例初始化完成,完成响应式绑定,data method 都已经初始化完成,可以调用,尚未创建模板;
beforeMount:编译模板,调用 render 生成 vdom,还没有开始渲染 DOM;
mounted:完成 DOM 渲染,组件创建完成;
beforeUpdate:data 发生变化,准备更新 DOM;
updated:data 发生变化,且 DOM 更新完成;(不要在 updated 中修改 data,可能会导致死循环)
beforeUnmount:组件进入销毁阶段(尚未销毁,可以正常使用),可以移除,解绑一些全局事件,自定义事件;
unmounted:组件被销毁了,所有子组件销毁;
Vue 什么时候操作 DOM 比较合适?
mounted 和 updated 都不能保证子组件全部挂载完成,使用$nextTick 渲染 DOM
mounted(){
this.$nextTick(function(){
<!-- 仅在整个视图都被渲染之后才会执行 -->
})
}
Ajax 应该在那个生命周期
created 和 mounted 都可以,推荐 mounted
Vue3 Composition API 生命周期有何区别?
用 setup 代替了 beforeCreate 和 created;
使用 Hooks 函数的形式,如 mounted 改为 onMounted();
Vue2 Vue3 React 三者 diff 算法有何区别?
React diff 仅右移;
Vue2 双端比较;
Vue3 最长递增子序列;
diff 算法
diff 算法很早就有;
diff 算法应用广泛,例如 GitHub 的 pull Request 中的代码 diff;
如果要严格 diff 两棵树,时间复杂度 O(n^3),不可用;
Tree diff 的优化
只比较同一层级,不跨级比较;子节点通过 key 区分(key 的重要性)
Vue React 为何循环时必须使用 Key?
vdom diff 算法会根据 key 判断元素是否要删除.匹配了 key,则只移动-性能好;不匹配 key,则删除重建-性能差;
vue-router 的 MemoryHistory 是什么?
vue-router 三种模式
hash:网址中出现#号
webHistory
MemoryHistory(v4 之前叫做 abstract history):没有前进后退