0512面试积累

  • 新生代跟老生代区别
  • arr.some()//arr.find()模拟
  • 事件委托(按钮点击之后,事件顺序)
  • treeShaking原理
  • ssr原理
  • 前端工程化应用
  • node cluster集群
  • hmr原理
  • @import跟link区别
  • 强缓存跟协商缓存,cache-control中的private跟public区别
  • jsBridge原理
  • esModule跟commonjs区别,互相引用的问题
  • keep-alive原理以及activated和deactivated专属
  • 手写发布订阅模式
  • EventEmitter(发布订阅模式–简单版)
  • 高阶函数

答案稍微整理下

treeShaking原理

es6模块是静态分析的,编译的时候能知道加载了哪些代码,能分析程序流,判断哪些变量未被使用引用等(静态分析程序流,判断哪些模块和变量未被使用或者引用,进而删除未引用的代码)

es6中的import语法阔以完美使用tree-shaking,因为阔以在代码不运行的情况下就能分析出不需要的代码

副作用

esModule跟commonjs区别,互相引用的问题

  • commonjs模块输出的一个值得拷贝,es6模块输出的是值得引用

  • commonjs模块是运行时加载,es6模块是编译时输出接口

  • commonjs是单个值导出,es6模块阔以导出多个也阔以导出单个

  • commonjs是动态语法阔以写在判断里,es6静态语法只能写在顶层

  • commonjs中的this指向当前模块,es6中的this是指undefined

cache-control中的private和public

Cache-Control 除了可以设置 max-age(相对过期时间,以秒为单位)以外,还可以设置如下几种常用值:

  • public,资源允许被中间服务器缓存。浏览器请求服务器时,如果缓存时间没到,中间服务器直接返回给浏览器内容,而不必请求源服务器。
  • private,资源不允许被中间代理服务器缓存。浏览器请求服务器时,中间服务器都要把浏览器的请求透传给服务器。
  • no-cache,不管本地副本是否过期,每次访问资源,浏览器都要向服务器询问,如果文件没变化,服务器只告诉浏览器继续使用缓存(304)。
  • no-store,浏览器和中间代理服务器都不能缓存资源。每次访问资源,浏览器都必须请求服务器,并且,服务器不去检查文件是否变化,而是直接返回完整的资源。
  • must-revalidate,本地副本过期前,可以使用本地副本;本地副本一旦过期,必须去源服务器进行有效性校验。
  • proxy-revalidate,要求代理服务器针对缓存资源向源服务器进行确认。
  • s-maxage:缓存服务器对资源缓存的最大时间

Vue 事件绑定原理

原生事件绑定是通过 addEventListener 绑定给真实元素的,组件事件绑定是通过 Vue 自定义的 $on 实现的。如果要在组件上使用原生事件,需要加.native 修饰符,这样就相当于在父组件中把子组件当做普通 html 标签,然后加上原生事件。

$on、$emit 是基于发布订阅模式的,维护一个事件中心,on 的时候将事件按名称存在事件中心里,称之为订阅者,然后 emit 将对应的事件进行发布,去执行事件中心里的对应的监听器

1
2
3
4
5
6
7
8
// child.vue
private confimModal(): void {
this.$emit('confirm')
}
// parent
<parent
@confirm="confirmModal"
>

手写发布订阅模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class EventEmitter {
constructor() {
this.events = {}
}
// 添加主题订阅和回调函数
on(type, cb) {
if (!this.events[type]) {
this.events[type] = [cb]
} else {
this.events.push(cb)
}
}
// 主题发布
emit(type, data) {
if (this.events[type] && this.events[type].length) {
this.events[type].forEach(fn => {
fn.call(this, data)
});
}
}
// 删除订阅
off(type, cb) {
if (!this.events[type]) return false
if (this.events[type] && type.length) {
this.events[type] = this.events[type].filter(e => e != cb)
} else if (type.length) {
this.events[type] = []
} else {
this.events = {}
}
}
// 只执行一次事件
once(type, cb) {
function fn() {
cb()
this.off(type, fn)
}
this.on(type, fn)
}
}
const event = new EventEmitter()
const handler = (...rest) => {
console.log(`rest handler`, rest)
}
event.on('click', handler)
event.emit('click', 1,2,3,4)
event.off('click', handler)
event.once("dbClick", () => {
console.log(123456);
});
event.emit("dbClick");
event.emit("dbClick");

node cluster集群

PM2 其实利用的是 Node.js Cluster 模块来实现的,这个模块的出现就是为了解决 Node.js 实例单线程运行,无法利用多核 CPU 的优势而出现的

参考