2021面经不易懂笔记

用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小)


HTTP/2 头压缩算法 —— HPACK

它对header进行压缩,消除了多余的 header 字段,将漏洞限制到已知的安全攻击,并且在受限的环境中具有有限的内存需求


vue 是单向数据流

也就是数据总是从父组件传递到子组件中,子组件无权修改父组件中的数据。因为当父组件 可能存在多个子组件,假如子组件可以修改父组件的数据,那么会导致其他依赖父组件的子组件都会受到影响。


div块中高度总是宽度的一半

height: 0;12 padding: 25% 0;


项目中为啥用vuex?什么场景下才用得到?有没有提前规划好哪些模块使用vuex?

由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。这样通常会导致代码无法维护。所以我们需要把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护。

由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。所以需要抽离出组件的共享状态,以全局单例模式存储起来,使项目状态集中式管理以及结构化和更易维护。

1 + []   // '1'    1+ ['a'] // '1a'    1+ [1,2]  //  '11,2'

复杂数据类型在隐式转换时会先转成String,然后再转成Number运算


session落地方案

1 基于nginx的ip_hash策略来进行负载均衡,那么相同ip的机子,每一次请求的时候,都会被请求到同一机子上。

2 借助一些mysql,redis,mongodb这些数据库来进行集中式处理,将相应的session存入这些地方



session储存在内存当中,如果有两台服务器,会出现什么问题,怎么解决


session丢失 不一致问题,用redis达到一致或者改成用jwt,session只存在一个服务器,在负载均衡的作用下,用户会被随机打到A和B上,所以会出现有时登陆得了,有时登陆不了的情况。



首屏加载

dns预解析、使用缓存、使用cdn内容分发加载vue、vue-router等资源、外部导入js,css文件,css放在头部,js放在尾部,js预加载,图片懒加载,图片使用css sprite,通过background-img、background-repeat、background-position控制,js文件抽离公共代码,尽量减少重绘和重排,减少dom节点操作,减少http请求。


for、forEach、map的性能区别

for > forEach > map

map 会返回一个等长数组,forEach 不会,所以 forEach 大于 map


cookie怎么加入token

js 创建 cookie 是用 document.cookie = 'token=221212fsfsfafas'

这里有个更方便的方法,也是更安全的。

让后端在接口的返回值 header 里添加 set-Cookie,这样的话浏览器会自动把 token 设置到 cookie 里。

还有,如果接口的返回值 header 里有设,Http-Only: true 的话,js 里是不能直接修改 cookie 的,这样更安全点。


vue-router

两种模式: hash和history两种

hash模式就是通过location.hash拿到值,调用onhashchange方法监听url变化

history模式是利用interface在HTML5中新增的方法History 

工作流程有如下几步

1. url改变

2. 触发监听事件

3. 改变vue-router里面的current变量

4. 监视current变量(变量的监视者)

5. 获取对应的组件

6. 调用vue实例render() 更新视图


Vue性能优化

分为四个:编码阶段/SEO/打包阶段/用户体验

编码阶段

尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher

v-if和v-for不能连用

如果需要使用v-for给每项元素绑定事件时使用事件代理

SPA 页面采用keep-alive缓存组件

在更多的情况下,使用v-if替代v-show

key保证唯一

使用路由懒加载、异步组件

防抖、节流

第三方模块按需导入

长列表滚动到可视区域

动态加载图片懒加载

SEO优化

预渲染

服务端渲染SSR

打包优化

压缩代码

Tree Shaking/Scope Hoisting

使用cdn加载第三方模块

多线程打包happypack

splitChunks抽离公共文件

sourceMap优化

用户体验

骨架屏PWA

还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启gzip压缩等。


SSR

服务端渲染:

将Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把html直接返回给客户端。

优点:

SSR有着更好的SEO、并且首屏加载速度更快等优点。

缺点:

比如我们的开发条件会受到限制,服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境。

服务器需要有更大的负载需求


Vue2.0组件通信:

父子:prop/emit

获取实例:$parent、$children

z总线:Vue.prototype.$bus = new Vue

跨组件:Vuex/$attrs、$listeners、Provide、inject



Vue中组件生命周期调用顺序

组件的创建到渲染顺序是:先父后子,渲染完成的顺序是:先子后父。

组件的销毁操作是:先父后子,销毁完成的顺序是:先子后父。

加载过程:

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted

子组件更新:

父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新:

父 beforeUpdate -> 父 updated

销毁:

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed


keep-alive:

实现组件缓存有两个方法:

include: 参数可以是字符串或者正则表达式,符合匹配的组件会被缓存

exclude:参数可以是字符串或者正则表达式,不符合匹配的组件会被缓存

有两个钩子:activated,deactivated

原理:最近最少使用算法(LRU),是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰

注意点:

页面第一次加载的时候会触发created和activated生命周期

如果地址栏有改变相当于初始化,会触发created和activated生命周期

如果地址栏没有变化,只会出发activated生命周期


虚拟Dom以及key属性的作用

虚拟Dom作用:抽象dom树

由于在浏览器中操作DOM是很昂贵的。频繁的操作DOM,会产生一定的性能问题。这就是虚拟Dom的产生原因。Virtual DOM本质就是用一个原生的JS对象去描述一个DOM节点。是对真实DOM的一层抽象。

key的作用是尽可能的复用 DOM 元素。

key是diff算法对比新旧children的唯一标识,作用是减少没必要的diff算法的对比,尽可能复用dom节点元素。

新旧 children 中的节点只有顺序是不同的时候,最佳的操作应该是通过移动元素的位置来达到更新的目的。

需要在新旧 children 的节点中保存映射关系,以便能够在旧 children 的节点中找到可复用的节点。key也就是children中节点的唯一标识。


Vue模板编译原理:

将template转换成render,具体步骤为:生成AST然后进行优化,然后codegen,将ast树转换成可执行代码。


Vue事件绑定

原生事件:addEventListener(事件名,回调函数,冒泡还是捕获,默认为false冒泡)

组件:$on @


v-model的原理

value + input方法的语法糖。可以通过model属性的prop和event属性来进行自定义


Computed和Watch:

Computed是vue定义的计算属性,有缓存,不支持异步,是一个具备缓存的订阅者watcher,属性改变更新视图,主要用于计算性能消耗大的场景,例如购物车。

watch是vue定义的监听器,没缓存,支持异步,观察的作用比较多,一个数据影响多个数据,应用场景为需要异步的操作或者开销较大的操作,例如搜索框


Vue2.0怎么监听数组的变化可以改变原数组的方法:

push,pop,shift,unshift,sort,splice,reverse

理解:vue对上面的方法进行重写,通过原型链指向了自己定义的数组原型方法,当调用api时,可以通知依赖更新,如果数组包括引用类型,则会对数组的引用类型再次监控。


webpack plugin的执行顺序:

从右到左,因为webpack选择了函数式编程的compose方式,也就是compose模式,如果选择pipe模式就从左到右

函数式编程compose和pipe

可以这么理解,例如有a,b两个函数,compose(a,b) => a调用了b,后面的返回值作为前面的参数,即从右到左;相反pipe(a,b) => b调用a, 前面的返回值作为后面的参数,即从左到右。


MVVM

Model-View-ViewModel缩写,也就是把MVC中的Controler变成viewmodel。Model数据模型,View代表UI组件,ViewModel是连接两者的桥梁,数据绑定到ViewModel之后渲染至页面,视图变化会通知ViewModel更改数据


Vue双向绑定响应式原理

观察者模式: 定义对象一对多的依赖关系,当对象状态变化,所有依赖它的对象也会收到通知,松偶关系,观察者和目标直接进行交互。

发布-订阅者模式:定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。完全解偶,订阅者和发布者互不干扰,中间通过调度中心联系。

Observe 监听器  Watcher 订阅者  Compile 解析器 dep 发布订阅者的调度中心

总结:

1 监听器observer实现数据劫持,获取data,给每个data加上数据监听,绑定Object.definedProperty的getter和setter函数

2 当属性改变时,会调用调度中心dep的notify()方法通知所有订阅者watcher

3 订阅者watcher调用update方法进行更新视图操作,通知解析器compile进行编译

4 解析器compile把 template 编译成一段 document fragment,对每个节点进行解析,如果nodeType==3就找到 (双大括号) 的文本插值,进行replace替换,更新视图view,并初始化watcher订阅者。


2021面经不易懂笔记_第1张图片


事件循环  执行栈 + Event loop + web Apis

浏览器:一个settimeout执行完才会执行下一个settimeout 

node:所有settimeout都是一起的,执行所有红任务,再执行所有微任务


TCP/IP拥塞控制

原理:

拥塞: 请求资源大于可用资源,网络资源供应不足,导致性能,吞吐量下降

拥塞控制:防止过多资源注入网络,导致网络负荷过载,是一个全局性过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。

方法:慢开始( slow-start )、拥塞避免( congestion avoidance )、快重传( fast retransmit )和快恢复( fast recovery )。


http简单请求和非简单请求

浏览器发送跨域请求,如何判断?

浏览器在发送跨域请求的时候,会先判断下是简单请求还是非简单请求,如果是简单请求,就先执行服务端程序,然后浏览器才会判断是否跨域

简单请求:

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段

常见方法有:head、get、post

非简单请求

非简单请求是那种对服务器有特殊要求的请求

请求方法:PUT或DELETE,或者Content-Type字段的类型是application/json。

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

会检查: Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。



js为啥单线程

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准


map和foreach区别

foreEach()方法:

针对每一个元素执行提供的函数。

map()方法:

创建一个新的数组,其中每一个元素由调用数组中的每一个元素执行提供的函数得来。

区别

forEach()方法不会返回执行结果,而是undefined。也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回。


解决非工程化项目初始化页面闪动问题

vue页面在加载的时候闪烁花括号{}},v-cloak指令和css规则如[v-cloak]{display:none}一起用时,这个指令可以隐藏未编译的Mustache标签直到实例准备完毕。


vue中对象更改检测的注意事项

对于已经创建的实例,Vue不能动态添加根级别的响应式属性,但是可以使用Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。


vue更新数组时触发视图更新的方法

这些方法如下:push() pop() shift() unshift() splice() sort() reverse()


vue如何监听键盘事件中的按键


什么是vue生命周期?

 Vue 实例从创建到销毁的过程,就是生命周期。. 也就是从开始创建、初始化数据、编译模板、挂载DOM-渲染、更新-渲染、卸载等一系列的过程,我们称这是 Vue 的生命周期。

Beforecreate、created、beforeMount、Mounted、beforeUpdate、Updated、BeforeDestroy、destroyed


vue中如何编写可复用的组件

重点体现高内聚低耦合,可复用

组件由

状态props,允许外部环境传递数据给组件

事件Events,允许组件触发外部环境的副作用

片断slots, 允许外部环境将额外的内容嵌套在组件中。


的作用是什么?

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。


vue中子组件调用父组件的方法

this.$parent.event可以调用父组件身上的方法,无需绑定在子组件身上。补充:有时候会失效,暂未发现触发点,不建议使用。

$emit可以调用父组件在子组件身上自定义的事件,需要用@前缀。建议使用此种方式

props可以调用父组件绑定在子组件身上的事件,需要:前缀。在router-view身上使用失效

三种都可以实现子组件调用父组件的方法,但是效率有所不同,根据实际需求选择合适的方法,嗯,就酱~


vue.$nextTick

this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,简单的理解就是,当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。


vue事件中如何使用event对象

通过将一个特殊变量 $event 传入到回调中解决


vue-cli工程升级vue版本

手动package.json 里面修改vue的版本 同时修改 vue-template-compiler 为相同的版本.后者在devdepen....里面.然后npm install


vue中 key 值的作用

渲染列表时需要使用key来给每个节点做一个唯一标识,作用是减少没必要的diff算法的对比进而高效渲染虚拟DOM节点。


vue常用的修饰符

.stop 阻止冒泡

.prevent 阻止行为

.number 限制只输出number类型

.trim 去空格

.lazy 改变后再触发

.native 监听原生事件


Vue两个核心: 数据驱动(双向数据绑定)、组件系统


数据驱动,也叫双向数据绑定。

Vue.js数据观测原理在技术实现上,利用的是ES5Object.defineProperty和存储器属性: getter和setter(所以只兼容IE9及以上版本),可称为基于依赖收集的观测机制。核心是VM,即ViewModel,保证数据和视图的一致性。

组件系统。

.vue组件的核心选项:

1、模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。

2、初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。

3、接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。

4、方法(methods):对数据的改动操作一般都在组件的方法内进行。

5、生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。

6、私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。



Vue的渐进式理解

主张最少,没有多做职责之外的事,不像Angular,强主张,必须用它的模版机制和依赖。vue.js只提供了vue-cli生态中最核心的组件系统和双向数据绑定,其他东西需要什么引入什么,不会强制要求。

每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式。


package.json配置详解


2021面经不易懂笔记_第2张图片

name:包名字

version:包版本,x.x.x的格式,符合语义化版本规则

description:一些描述信息

main:入口文件,一般是index.js

scripts:指定了运行脚本命令的npm命令行缩写,默认是空的test

author:作者信息

license:许可证,默认是ISC、有的默认是MIT


请说出vue-cli工程中每个文件夹和文件的用处

2021面经不易懂笔记_第3张图片


vue-cli常用命令

1.  npm install:下载 node_modules 资源包的命令

2. npm run dev: 启动 vue-cli 开发环境的 npm命令

3.  npm run build: vue-cli 生成 生产环境部署资源 的 npm命令

4. npm run build--report: 用于查看 vue-cli 生产环境部署资源文件大小的 npm命令


用于构建vue的 vue-cli 工程都到了哪些技术,它们的作用分别是什么?

1、vue.js:vue-cli工程的核心,主要特点是 双向数据绑定 和 组件系统。

2、vue-router:vue官方推荐使用的路由框架。

3、vuex:专为 Vue.js 应用项目开发的状态管理器,主要用于维护vue组件间共用的一些 变量 和 方法。

4、axios( 或者 fetch 、ajax ):用于发起 GET 、或 POST 等 http请求,基于 Promise 设计。

5、vux等:一个专为vue设计的移动端UI组件库。

6、创建一个emit.js文件,用于vue事件机制的管理。

7、webpack:模块加载和vue-cli工程打包器。


说说mongoDB和MySQL的区别

MongoDB 是一种非关系型数据库,将数据存储为一个JSON文档,属于文档型数据库,数据结构由键值(key=>value)对组成,使用MongoDB查询方式(类似JavaScript的函数),占用空间大,不支持join方法。Mysql是一种关系型数据库,不同引擎数据存储方式不同,使用SQL语句,占用空间小,支持join方法。


说说网络分层里七层模型是哪七层

1)  物理层:通过媒介传输比特,确定机械及电气规范(比特Bit)

2)数据链路层:将比特组装成帧和点到点的传递(帧Frame)

3)网络层:负责数据包从源到宿的传递和网际互连(包PackeT)

4)传输层:提供端到端的可靠报文传递和错误恢复(段Segment)

5)会话层:建立、管理和终止会话(会话协议数据单元SPDU)

6)表示层:对数据进行翻译、加密和压缩(表示协议数据单元PPDU)

7)应用层:允许访问OSI环境的手段(应用协议数据单元APDU)

相关协议:

应用层:应用层、表示层、会话层(从上往下)(HTTP、FTP、SMTP、DNS)

传输层(TCP和UDP)

网络层(IP)

物理和数据链路层(以太网)


attribute和property的区别是什么

property是DOM中的属性,是JavaScript里的对象;

attribute是HTML标签上的特性,它的值只能够是字符串;

简单理解,Attribute就是dom节点自带的属性,例如html中常用的id、class、title、align等。

而Property是这个DOM元素作为对象,其附加的内容,例如classname、clientHeight等。


谈一下MVC和MVVM

MVC,包含model数据模型、view视图、controller控制器,业务逻辑等

View 传送指令到 Controller

Controller 完成业务逻辑后,要求 Model 改变状态

Model 将新的数据发送到 View,用户得到反馈

所有的通信都是单向的。

MVVM

View:UI界面  

ViewModel:它是View的抽象,负责View与Model之间信息转换,将View的Command传送到Model;  

Model:数据访问层

区别与MVC单向访问,viewModal与modal可以双向访问,view和viewModal也可以双向访问

Git fetch和git pull的区别

git fetch:相当于是从远程获取最新版本到本地,不会自动merge

git pull:相当于是从远程获取最新版本到本地,自动merge

优先选择git fetch,因为不建议自动合并,要考虑根据当时情况选择合并代码

Document.write() 的用法

Document.write() 方法将一个文本字符串写入一个由 document.open() 打开的文档流

如果在页面加载完毕,文档流已经闭合,再使用document.write则会先执行document.open()创建一个新文档流,这个新文档流将会覆盖替换掉之前的文档流.


简述对AMD、CMD、CommonJs的理解

1、AMD/CMD/CommonJs是JS模块化开发的标准,目前对应的实现是RequireJs/SeaJs/nodeJs.

2、CommonJs主要针对服务端,AMD/CMD主要针对浏览器端,所以最容易混淆的是AMD/CMD。

(顺便提一下,针对服务器端和针对浏览器端有什么本质的区别呢?服务器端一般采用同步加载文件,浏览器端可以异步加载。

也就是说需要某个模块,服务器端便停下来,等待它加载再执行。这里如果有其他后端语言,

如java,经验的‘玩家’应该更容易理解。而浏览器端要保证效率,需要采用异步加载,

这就需要一个预处理,提前将所需要的模块文件并行加载好。)

3、 AMD/CMD区别,虽然都是并行加载js文件,但还是有所区别,

AMD是预加载并行加载js文件的时候就会执行

(因为还需要执行,所以在加载某个模块前,这个模块的依赖模块需要先加载完成);

CMD是懒加载,虽然会一开始就并行加载js文件,但是不会执行,而是在需要的时候才执行

4、AMD/CMD的优缺点.一个的优点就是另一个的缺点, 可以对照浏览。

       AMD优点:加载快速,尤其遇到多个大文件,因为并行解析,所以同一时间可以解析多个文件。

       AMD缺点:并行加载,异步处理,加载顺序不一定,可能会造成一些困扰,甚至为程序埋下大坑。

       CMD优点:因为只有在使用的时候才会解析执行js文件,因此,每个JS文件的执行顺序在代码中是有体现的,是可控的。

       CMD缺点:执行等待时间会叠加。因为每个文件执行时是同步执行(串行执行),因此时间是所有文件解析执行时间之和,

尤其在文件较多较大时,这种缺点尤为明显。

5、如何使用?CommonJs的话,因为nodeJs就是它的实现,所以使用node就行,也不用引入其他包。

AMD则是通过

你可能感兴趣的:(2021面经不易懂笔记)