面试

一、js基础

1.cdn原理

CDN 的工作原理就是将源站资源缓存到位于全球各地的 CDN 节点上,用户请求资源时,就近返回,不需要每个请求从源站获取,避免网络拥塞、缓解源站压力,保证用户访问资源的速度
简单来说,CDN就是根据用户位置分配最近的资源
原理:
1.负载均衡系统
应用CDN后,DNS 返回的不再是 IP 地址,而是指向CDN的全局负载均衡,找就近、相同网络、负载较轻的节点,然后把这个节点返回给用户,用户就能够就近访问CDN的缓存代理
2.缓存代理
分成一级缓存节点和二级缓存节点。
一级缓存配置高一些,直连源站,二级缓存配置低一些,直连用户
回源的时候二级缓存只找一级缓存,一级缓存没有才回源站,可以有效地减少真正的回源

于是,用户在上网的时候不用直接访问源站,而是访问离他“最近的”一个 CDN 节点,术语叫「边缘节点」,其实就是缓存了源站内容的代理服务器。

2.es5和es6继承的区别、

https://www.mdnice.com/writing/d4a6f872b4484750916e72943baccf89
ES5 prototype 继承:
实质是先创造子类的实例对象this上,然后再将父类的方法添加到这个this上。类似使用:Father.apply(this)

S6 class 继承
通过class的extends + super实现继承。
子类没有自己的this对象,因此必须在 constructor 中通过 super 继承父类的 this 对象,而后对此this对象进行添加方法和属性。
super关键字在构造函数中表示父类的构造函数,用来新建父类的 this 对象。
内部实现机制上,ES6 的继承机制完全不同,实质是先创造父类的实例对象this---需要提前调用super方法,然后再用子类的构造函数修改this指针

二者区别:
答:不是完全一样的,主要有以下几个差异点:
1.写法不一样。class的继承通过extends关键字和super函数、super方法继承。(关于super实现继承的使用方式,具体我就不展开了)
2.类内部定义的方法都是不可枚举的,这个 ES5 不一样
3.类不存在变量提升,这一点与 ES5 完全不同
4.类相当于实例的原型,所有在类中定义的方法都会被实例继承。如果在一个方法前,加上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就成为静态方法
内部实现机制不一样

因为实现机制不同,导致这两种继承在继承原生构造函数时有些差异:
es5的写法不能继承原生构造函数(比如Array、Number等)
因为es5的继承是先创造子类的实例对象this,再将父类原型的属性和方法重写到子类上,因为没法访问父类的内部属性,导致es5的继承方式无法继原生的构造函数。
es6允许继承构造函数生成子类。因为es6是先创建父类的实例对象this,然后再用子类的构造函数修饰,所以子类就可以继承父类的所有属性和方法。因此class可以继承并自定义原生构造函数的子类。extends不仅可以用来继承类,还能用来继承原生构造函数,因此也就可以在原生数据结构的基础上,构造自定义的数据结构

3.闭包(高频)

闭包是指有权访问另一个函数作用域中的变量的函数
闭包用途:
1.能够访问函数定义时所在的词法作用域(阻止其被回收)
2.私有化变量
3.模拟块级作用域
4.创建模块
闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏

4.this指向、new关键字

this对象是是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。
在实际开发中,this 的指向可以通过四种调用模式来判断。

1.函数调用,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
2.方法调用,如果一个函数作为一个对象的方法来调用时,this指向这个对象。
3.构造函数调用,this指向这个用new新创建的对象。

  1. apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply接收参数的是数组,call接受参数列表,`` bind方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this指向除了使用new `时会被改变,其他情况下都不会改变。

new的创建过程:
首先创建了一个新的空对象
设置原型,将对象的原型设置为函数的prototype对象。
让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象

5.Event Loop

执行顺序如下所示:
1)首先执行同步代码,这属于宏任务
2)当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
执行所有微任务
3)当执行完所有微任务后,如有必要会渲染页面
4)然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数

微任务包括 process.nextTick ,promise ,MutationObserver。
宏任务包括 script , setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering。

6.http如何实现缓存

1.强缓存==>Expires(过期时间)/Cache-Control(no-cache)(优先级高)
协商缓存 ==>Last-Modified/Etag(优先级高)
Etag适用于经常改变的小文件 ,Last-Modefied适用于不怎么经常改变的大文件
缓存过期,Last-Modefied会向服务器发送请求验证资源是否有更新,如果资源没有改变,就返回304
Last-Modefied缺点:如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成 Last-Modified 被修改,服务端不能命中缓存导致发送相同的资源
而ETag 类似于文件指纹,If-None-Match 会将当前 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来

强缓存策略和协商缓存策略在缓存命中时都会直接使用本地的缓存副本,区别只在于协商缓存会向服务器发送一次请求。它们缓存不命中时,都会向服务器发送请求来获取资源。在实际的缓存机制中,强缓存策略和协商缓存策略是一起合作使用的。浏览器首先会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源。如果不命中则根据头信息向服务器发起请求,使用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器直接使用本地资源的副本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。

二.react

1.setState

只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。
setState的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。
setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setState , setState 的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新。

6.高阶组件

高阶组件是参数为组件,返回值为新组件的函数。HOC是纯函数,没有副作用。HOC在React的第三方库中很常见,例如Redux的connect组件。
高阶组件的作用:
1.代码复用,逻辑抽象,抽离底层准备(bootstrap)代码
2.渲染劫持
3.State 抽象和更改
4.Props 更改

三、计算机网络

1.http与https区别

1.HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
2.HTTP 是不安全的,而 HTTPS 是安全的
3.HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
4.在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
5.HTTP 无法加密,而HTTPS 对传输的数据进行加密
6.HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书

2.安全防御

XSS避免方式:
1.url参数使用encodeURIComponent方法转义
2.尽量不是有InnerHtml插入HTML内容
3.使用特殊符号、标签转义符。

CSRF避免方式:
1.添加验证码
2.使用token:
1)服务端给用户生成一个token,加密后传递给用户
2)用户在提交请求时,需要携带这个token
3)服务端验证token是否正确

3.状态码
200响应成功
301永久重定向
302临时重定向
304资源缓存
403服务器禁止访问
404服务器资源未找到
500 502服务器内部错误
504 服务器繁忙

四、微前端

目前主流微前端方案:

1.iframe:基于iframe标签实现,技术难度低,隔离性和兼容性
2.基座模式:主要基于路由分发,qiankun和single-spa就是基于这种模式,监听路由来还在不同的应用,以实现应用间解耦
3.组合式集成,即组件单独打包和发布,然后在构建或运行时组合,类似npm包的形式
4.EMP,一种去中心化的微前端实现方案,它不仅能很好地隔离应用,还可以轻松实现应用间的资源共享和通信;
5.web components,它通过对组件进行更高程度的封装,来实现微前端,但是目前兼容性不够好,尚未普及。

qiankun基本原理:

将一个大型应用拆分成若干个更小、更简单,可独立开发、测试和部署的子应用,然后由一个基座应用根据路由进行应用切换。
基于sing-spa框架搭建的,在其基础上进行封装和增强,使其更加易用。

微前端的主要优势

1.技术兼容性好,各个子应用可基于不同技术架构
2.代码库更小、内聚性更高
3.便于独立编译、测试和部署,可靠性更高
4.耦合性更低,各个团队独立开发互不干扰
5.可维护性和扩展性更好,便于局部升级和增量升级

关于技术兼容性,由于在被基座应用加载前, 所有子应用已经编译成原生代码输出,所以基座应用可以加载各类技术栈编写的应用;
由于拆分后应用体积明显变小,并且每个应用只实现一个业务模块,因此其内聚性更强;
另外子应用本身也是完整的应用,所以它可以独立编译、测试和部署;
关于耦合性,由于各个子应用只负责各自的业务模块,所以耦合性很低,非常便于独立开发;
关于可维护性和扩展性,由于拆分出的应用都是完整的应用,因此专门升级某个功能模块就成为了可能,并且当需要增加模块时,只需要创建一个新应用,并修改基座应用的路由规则即可。

微前端缺点

1.子应用间的资源共享能力较差,使得项目总体积变大
2.需要对现有代码进行改造(指的是未按照微前端形式编写的旧工程)

qiankun与single-spa实现原理

微前端问题分为:
1.应用的加载与切换 :路由问题、应用入口、应用加载
2.应用的隔离与通信:js隔离、css样式隔离、应用间通信


image.png

single-spa很好地解决了路由和应用入口两个问题,但并没有解决应用加载问题,而是将该问题暴露出来由使用者实现(一般可以用system.js或原生script标签来实现);qiankun在此基础上封装了一个应用加载方案(即import-html-entry),并给出了js隔离、css样式隔离和应用间通信三个问题的解决方案,同时提供了预加载功能。

single-spa实现原理

1)路由问题
single-spa通过监听hashChangepopState这两个原生事件来检测路由变化的。
总的来看,当路由发生变化时,hashChangepopState会触发,这时single-spa会监听到,并触发urlReroute;接着它会调用reroute,该函数正确设置各个应用的状态后,直接通过调用应用所暴露出的生命周期钩子函数即可。
当某个应用被推送到appsToMount后,它的mount函数会被调用,该应用就会被挂载;而推送到appsToUnmount中的应用则会调用其unmount钩子进行卸载。

image.png

2)应用入口
single-spa采用的是协议入口,即只要实现了single-spa的入口协议规范,它就是可加载的应用。single-spa的规范要求应用入口必须暴露出以下三个生命周期钩子函数,且必须返回Promise,以保证single-spa可以注册回调函数:
1.bootstrap:用于应用引导,基座应用会在子应用挂载前调用它
2.mount: 用于应用挂载,就是一般应用中用于渲染的逻辑
3.unmount:用于应用卸载
3)应用加载
实际上single-spa并没有提供自己的解决方案,而是将它开放出来,由开发者提供。

qiankun原理

1)应用加载
针对上面我们谈到的几个弊端,qiankun进行了一次封装,给出了一个更完整的应用加载方案,qiankun的作者将其封装成了npm插件import-html-entry
该方案的主要思路是允许以html文件为应用入口,然后通过一个html解析器从文件中提取js和css依赖,并通过fetch下载依赖
2)js隔离
qiankun通过import-html-entry,可以对html入口进行解析,并获得一个可以执行脚本的方法execScripts。qiankun引入该接口后,首先为该应用生成一个window的代理对象,然后将代理对象作为参数传入接口,以保证应用内的js不会对全局window造成影响。由于IE11不支持proxy,所以qiankun通过快照策略来隔离js,缺点是无法支持多实例场景
3)css隔离
两种:一种是基于shadowDom的;另一种则是实验性的,思路类似于Vue中的scoped属性,给每个子应用的根节点添加一个特殊属性,用作对所有css选择器的约束
4)应用通信
qiankun思路是基于一个全局的globalState对象。这个对象由基座应用负责创建,内部包含一组用于通信的变量,以及两个分别用于修改变量值和监听变量变化的方法:setGlobalState和onGlobalStateChange。

你可能感兴趣的:(面试)