You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JS引擎在执行JS脚本的时候是单线程的,脚本会顺序放入执行栈中依次解析并执行,如果遇到setTimeout这种延时任务,会交给Web APIs线程处理,web api 等到延时结束后把回调函数推进宏任务队列,遇到promise这种异步任务时,会把它推进微任务队列。宏微任务也有其执行规则,每次执行完一个宏任务,就要把微任务队列中的所有微任务取出来执行,微任务执行完毕,开始检查渲染。这就是JavaScript的异步执行机制,也叫事件循环。
// 构造函数:functionmyFunction(arg1,arg2){this.firstName=arg1;this.lastName=arg2;this.sayName=function(){console.log(this.lastName)}}// This creates a new objectvara=newmyFunction("Li","Cherry");a.sayName();
具体步骤:
①. 在与webpack配置文件同级目录下新建webpack.dll.config.js
②. 在package.json中配置dll命令
③. 接下来在我们的webpack.config.js中增加配置代码
④. 执行 npm run dll
⑤. 会发现生成了我们需要的集合第三方代码的vendor.dll.js 我们需要在html文件中手动引入这个js文件
⑥. 这样如果我们没有更新第三方依赖包,就不必npm run dll。直接执行npm run dev npm run build的时候会发现我们的打包速度明显有所提升。因为我们已经通过dllPlugin将第三方依赖包抽离出来了。
[TOC]
JS
1. 用过的ES6新特性
分别能答出 是啥、咋用、解决了什么问题
2. Promise
Promise为我们解决了什么问题?
Promise的调用流程:
这是个「观察者模式」,这种
收集依赖 -> 触发通知 -> 取出依赖执行
的方式,被广泛运用于观察者模式的实现,在Promise里,执行顺序是then收集依赖 -> 异步触发resolve -> resolve执行依赖
。1. BAT前端经典面试问题:史上最最最详细的手写Promise教程
2. 八段代码彻底掌握 Promise - 掘金
3. 事件循环(输出顺序)
JS引擎在执行JS脚本的时候是单线程的,脚本会顺序放入执行栈中依次解析并执行,如果遇到setTimeout这种延时任务,会交给Web APIs线程处理,web api 等到延时结束后把回调函数推进宏任务队列,遇到promise这种异步任务时,会把它推进微任务队列。宏微任务也有其执行规则,每次执行完一个宏任务,就要把微任务队列中的所有微任务取出来执行,微任务执行完毕,开始检查渲染。这就是JavaScript的异步执行机制,也叫事件循环。
宏任务包括:
微任务包括:
图解搞懂JavaScript引擎Event Loop
从面试题看 JS 事件循环与 macro micro 任务队列(带async/await)
微任务、宏任务与Event-Loop
深入理解NodeJS事件循环机制
4. 对this的理解
this是动态变化的,谁调用它,就指向哪里,this有四种绑定规则:
作为一个函数调用
函数作为方法调用
使用构造函数调用函数
作为函数方法调用函数
参考
掘金 - this、apply、call、bind
5. 讲解闭包及其作用
什么是闭包?
如何产生一个闭包?
闭包的注意事项:
通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止。
闭包的应用:
设计私有的方法和变量。
函数柯里化
参考
闭包
6. 实现new
7. 实现 bind
8. 隐式类型转换
[] == ![] !? 浅析JS的类型系统和隐式类型转换
JavaScript 运算符规则与隐式类型转换详解
9. 浏览器事件相关
e.target和e.currentTarget的区别?
load 与 DOMContentLoaded
DOMContentLoaded
意思是HTML下载、解析完毕之后就触发。
load
意思是页面的html、css、js、图片等资源都已经加载完之后才会触发 load 事件。
JS中事件冒泡与捕获
10. 跨域
跨域的几种解决方式。
...
后端如何设置cors?
11. 对 async/await 的理解
首先,
async
函数返回的是⼀个Promise
对象;然后,
async
函数内部return
返回的值。会成为then
方法回调函数的参数; 如果async
函数内部抛出异常,则会导致返回的Promise
对象状态变为reject
状态。抛出的错误而会被catch
方法回调函数接收到。async
函数返回的Promise
对象,必须等到内部所有的await
命令的Promise
对象执行完,才会发生状态改变.正常情况下,
await
命令后面跟着的是Promise
,如果不是的话,也会被转换成一个 立即resolve
的Promise
.理解 async/await
CSS
1. flex
容器属性,指定容器内元素的排列、对齐方式
项目属性,指定元素本身的排列、对齐方式
参考
1. Flex 布局教程:语法篇
2. Flex 布局教程:实例篇
2. 浮动布局
也就是说,right 会挨着 left,而不是重叠。
这种情况与
position:absolute
正好相反这时候,right 会覆盖在 left 上面。
但是,有时可能需要强制一个浮动元素移至任何浮动元素下方,那么使用
clear: both;
:参考
1. MDN - float
3. position
参考
1. MDN - position
2. 前端重构范式之 position
4. css各种布局
两栏布局
三栏布局
圣杯布局
水平垂直居中
5. 伪类和伪元素的区别
伪类
伪类用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,我们可以通过:hover 来描述这个元素的状态。虽然它和普通的 css 类相似,可以为已有的元素添加样式,但是它只有处于 dom 树无法描述的状态下才能为元素添加样式,所以将其称为伪类,伪类的操作对象是文档树中已有的元素。
伪元素
伪元素用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before(或::before,CSS3标准) 来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。
参考
Alloy-team - 总结伪类与伪元素
网络
1. 对缓存的了解
分为强缓存和协商缓存:
1)浏览器在加载资源时,先根据这个资源的一些http header(expries和cache-control)判断它是否命中强缓存,强缓存如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器。比如某个css文件,如果浏览器在加载它所在的网页时,这个css文件的缓存配置命中了强缓存,浏览器就直接从缓存中加载这个css,连请求都不会发送到网页所在服务器;
2)当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header(last-modified和etag)验证这个资源是否命中协商缓存,如果协商缓存命中,服务器会将这个请求返回,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从自己的缓存中去加载这个资源;
3)强缓存与协商缓存的共同点是:如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;区别是:强缓存不发请求到服务器,协商缓存会发请求到服务器。
4)当协商缓存也没有命中的时候,浏览器直接从服务器加载资源数据。
(精辟)流云诸葛 - 浏览器缓存知识小结及应用
彻底理解浏览器的缓存机制
2. HTTP 状态码
3. 对 https 的了解
首先讲HTTP的缺点:
https的出现就是为了解决这三个问题:
掘金 - HTTP和HTTPS详解
掘金 - 看完这篇 HTTPS,和面试官扯皮就没问题了
4. 讲解http1.1 、http2.0、https
http1.0
http1.0存在问题
每个tcp连接只能发送一个请求,下一个请求发送需要重新建立tcp连接,性能很差
http1.1
针对http1.0的问题,http1.1做了很大的优化
长连接
http1.1默认connection:keep-alive,一个tcp连接可以持续传输请求。
管道机制
因为http1.1支持长连接,发送一个请求之后还可以发送第二个请求,如果第二个请求要等待第一个请求返回之后才发送,效率就很低,所以引入了管道机制,多个请求可以按顺序同时发送,响应按顺序返回
Content-Length
因为一个tcp可以同时发送多个请求,我们需要一个字段来区分多个请求,Content-length表示当前请求响应共有多少字段,超过这个值的响应就不是该请求的响应
分块传输
因为http1.1是按顺序发送请求和响应,如果一个顺序靠前的请求响应时间较长,会阻碍后面请求的响应,造成很大的延迟,这就是线头阻塞。故http1.1支持分块传输:Transfer-Encoding: chunked,每个响应头前都有一个16进制数字表示该块儿大小,如果为0表示本次分块数据传输完成
其他功能
新增PUT、PATCH、HEAD、 OPTIONS、DELETE请求方法
客户端请求头新增Host字段,有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。
http1.1存在问题
主要还是线头阻塞问题,为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。如果HTTP协议设计得更好一些,这些额外的工作是可以避免的。
http1.1和http1.0对比
http2.0/SPDY
http2.0是基于SPDY的,两者没有太大的区别,主要是header压缩方式以及http2.0支持明文传输。
对比http1.1,主要区别有以下几个
多路复用
http2.0一个tcp连接支持多个stream流同时传输
请求优先级
多路复用可能会带来一个新的问题,多个请求并发可能导致关键请求被阻塞,故http2.0支持request设置优先级
header压缩
header中的一些信息是重复的,采用合适的压缩算法减少请求大小
服务端推送
正常文档流请求style.css后服务端会主动推送script.js到客户端,服务端请求的时候直接从缓存读取
浏览器
1. 浏览器本地存储
浏览器的本地存储主要分为Cookie、localStorage、sessionStorage 和 IndexedDB。
cookie
Cookie 本质上就是浏览器里面存储的一个很小的文本文件,向同一个域名下发送请求,都会携带相同的 Cookie,服务器拿到 Cookie 进行解析,便能拿到客户端的状态。
cookie 就是用来做状态存储的,但是也有缺陷:
localStorage
localStorage有一点跟Cookie一样,在同一个域名下,会存储相同的一段localStorage。
相对Cookie的区别:
应用场景:
sessionStorage
与localStorage基本相同。
但sessionStorage和localStorage有一个本质的区别,那就是前者只是会话级别的存储,并不是持久化存储。会话结束,也就是页面关闭,这部分sessionStorage就不复存在了。
应用场景:
indexedDB
IndexedDB是运行在浏览器中的非关系型数据库, 本质上是数据库,理论上容量是没有上限的。
重要特性:
参考
浏览器灵魂之问 - 能不能说一说浏览器的本地存储?各自优劣如何?
2. 对前端路由的了解
何为前端路由?
为实现这一目标,我们需要做到以下 2 点:
接下来要介绍的 hash 模式和 history 模式,就是实现了上面的功能.
hash 模式
这里的 hash 就是指 url 后的 # 号以及后面的字符。比如说 "www.baidu.com/#hashhash" ,其中 "#hashhash" 就是我们期望的 hash 值。
由于 hash 值的变化不会导致浏览器向服务器发送请求,而且 hash 的改变会触发 hashchange 事件,浏览器的前进后退也能对其进行控制,所以在 H5 的 history 模式出现之前,基本都是使用 hash 模式来实现前端路由。
history 模式
在 HTML5 之前,浏览器就已经有了 history 对象。但在早期的 history 中只能用于多页面的跳转:
在 HTML5 的规范中,history 新增了以下几个 API:
参考
「前端进阶」彻底弄懂前端路由
3. 前端安全(xss、csrf)
sql 注入
要理解sql注入的场景,它的原理是什么,当前的数据库的解决方案是什么?
xss 攻击
分为 DOM xss、反射型xss、存储型 xss
常见的攻击场景,什么类型的网站容易被xss攻击,整个流程的原理是什么?
恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,其他用户看到这个包括恶意脚本的页面并执行,获取用户的cookie等敏感信息,从而达到恶意攻击用户的目的。
预防措施:防止下发界面显示html标签,把</>等符号转义 。
csrf 攻击
其实就是一个钓鱼网站,要理解为什么会收到攻击,应该采取什么策略进行防御。
CSRF通过伪装来自受信任用户的请求来利用受信任的网站。用户C首先登录受信任网站A,并在本地生成Cookie。在不登出A的情况下,访问危险网站B。B要求访问站点A,浏览器会自动带上用户C的cookie,并且A站点也分辨不清好坏,B就可以冒充受信任用户C来进行操作。
预防措施:请求中加入随机数,让钓鱼网站无法正常伪造请求。
cookie 安全
要理解为什么用token,优势等
密码安全
主要是用户登陆,用户数据提交,加密,存入数据库的一整个流程
https
https解决了什么问题
参考
1. 前端安全知识
2. 前端安全系列(二):如何防止CSRF攻击?
4. cookie
把cookie聊清楚
5. 结合跨域问题理解简单请求和非简单请求
CORS 简单请求+预检请求(彻底理解跨域)
框架及工具
1. 对 React 的理解
记住一个公式:
UI = f(state)
React 的声明式编程,抛弃了直接操作DOM的方式,只关注数据变动,引入virtual-dom,使得DOM操作由框架完成,提升了可读性可维护性。遵循从高阶组件到低阶组件的单向数据流。
2. hooks、typescript
hooks 解决了什么问题
react组件冗长且难以复用。尤其是那些写成class的组件,它们本身包含了状态(state),所以复用这类组件就变得很麻烦。
官方推荐解决方案:render props 和 高阶组件
但是这里又会出现嵌套层级太深的问题。
也会产生很多重复代码
比如说要手动绑定this
写函数式组件的时候,随着组件越来越复杂,可能又要改成成有状态的组件
hooks的用法和注意事项
最简单的React Hooks入门级教程
参考
30分钟精通React Hooks
3. React 生命周期
react v16.3 之前的生命周期:
react 16.3 新引入了两个钩子:
componentDidMount 中通常都做些什么操作?
4. constructor 中的 super(props)的作用
如果要从另一个角度看的话:
假设在es5要实现继承,首先定义一个父类:
再定义他sup的子类,继承sup的属性和方法:
这时调用父类生成一个实例化对象:
这就是es5中实现继承的方法。
而在es6中实现继承:
参考
1. 为什么我们要写 super(props) ?
5. React fiber
背景:
react在进行组件渲染时,从setState开始到渲染完成整个过程是「一气呵成」的。如果需要渲染的组件比较复杂,js执行会占据主线程时间较长,会导致页面响应速度变差,使得react在动画、手势等应用中效果比较差。
原因:
在setState后,react会立即开始reconciliation过程,从父节点(Virtual DOM)开始遍历,以找出不同。将所有的Virtual DOM遍历完成后,reconciler才能给出当前需要修改真实DOM的信息,并传递给renderer,进行渲染,然后屏幕上才会显示此次更新内容。对于特别庞大的vDOM树来说,reconciliation过程会很长,在这期间,主线程是被js占用的,因此任何交互、布局、渲染都会停止,给用户的感觉就是页面被卡住了。
解决:
fiber的机制是每次只做一个很小的任务,做完后能够“喘口气儿”,回到主线程看下有没有什么更高优先级的任务需要处理,如果有则先处理更高优先级的任务,没有则继续执行。
对于如何区别优先级,React 有自己的一套逻辑。比如对于动画这种实时性很高的东西,也就是 16 ms 必须渲染一次保证不卡顿的情况下,React 会每 16 ms(以内) 暂停一下更新,返回来继续渲染动画。
参考
1. fiber 精简版总结
2. fiber 详细总结
6. React render
render 函数并不做实际的渲染动作,它只是返回一个JSX描述的结构,最终由React来操作渲染过程。(render函数并不往DOM树上渲染或者装载内容,它只是返回一个JSX表示的对象,然后由React库来根据返回对象决定如何渲染。而React库肯定是要把所有组件返回的结果综合起来,才能知道该如何产生对应的DOM修改。)
render函数还可以返回 字符串 / 数组
7. React 8 种条件渲染方式
场景:组件内有两种状态,对应渲染不同的元素
参考
React的8种条件渲染方法 - 内有示例代码
8. React 中如何减少 render 次数
参考
1.性能!!让你的 React 组件跑得再快一点 - 政采云前端团队
2. React优化:竭尽全力的减少render渲染
9. React setState
setState 三种用法:
setState({key: value})
this.setState((prevState) => ({ count: prevState.count + 1 }))
setState(partialState, callback)
setState 同步/异步 如何表现:
参考
你真的理解setState吗?
10. 虚拟DOM的优缺点
答题思路:
传统DOM的劣势 --> react diff --> vdom的出现解决什么问题 --> vdom的优势
传统前端编程方式是命令式的,直接操作DOM,代码可读性差可维护性低;
react的声明式编程,抛弃了直接操作DOM,只关注数据变动,DOM操作由框架完成,提升了可读性可维护性;
最初react在更新的过程中会刷新整个页面,后来引入的diff过程,对比数据变动前后的DOM结构,但DOM结构diff起来太复杂,由此引出了vdom;
VDOM 和 Diff 算法的出现是为了解决由命令式编程转变为声明式编程、数据驱动后所带来的性能问题的。换句话说,直接操作 DOM 的性能并不会低于虚拟 DOM 和 Diff 算法,甚至还会优于。
这么说的原因是因为 Diff 算法的比较过程,比较是为了找出不同从而有的放矢地更新页面。但是比较也是要消耗性能的。而直接操作 DOM 就是有的放矢,我们知道该更新什么不该更新什么,所以不需要有比较的过程。所以直接操作 DOM 效率可能更高。
React 厉害的地方并不是说它比 DOM 快,而是说不管你数据怎么变化,我都可以以最小的代价来进行更新 DOM。 方法就是我在内存里面用新的数据刷新一个虚拟 DOM 树,然后新旧 VDOM 进行比较,找出差异,再更新到 DOM 树上。
虚拟DOM的作用:
虚拟DOM的缺点:
首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入慢。
虚拟 DOM 需要在内存中维护一份 DOM 的副本(跟上面一条其实也差不多,上面一条是从速度上,这条是从空间上)。
如果虚拟 DOM 大量更改,这是合适的。但是单一频繁地更新的话,虚拟 DOM 将会花费更多的时间处理计算的工作。所以,如果你有一个 DOM 节点相对较少页面,用虚拟 DOM,它实际上有可能会更慢。但对于大多数单页面应用,这应该都会更快。
参考
把这篇文章看完 - 从 React 历史的长河里聊虚拟 DOM 及其价值
Virtual Dom 的优势在哪里?
11. webpack 拆包
对于开发项目中不经常会变更的静态依赖文件。类似于我们的elementUi、vue全家桶等等。因为很少会变更,所以我们不希望这些依赖要被集成到每一次的构建逻辑中去。 这样做的好处是每次更改我本地代码的文件的时候,webpack只需要打包我项目本身的文件代码,而不会再去编译第三方库。以后只要我们不升级第三方包的时候,那么webpack就不会对这些库去打包,这样可以快速的提高打包的速度。
这里我们使用webpack内置的
DllPlugin
DllReferencePlugin
进行抽离.具体步骤:
①. 在与webpack配置文件同级目录下新建webpack.dll.config.js
②. 在package.json中配置dll命令
③. 接下来在我们的webpack.config.js中增加配置代码
④. 执行
npm run dll
⑤. 会发现生成了我们需要的集合第三方代码的vendor.dll.js 我们需要在html文件中手动引入这个js文件
⑥. 这样如果我们没有更新第三方依赖包,就不必npm run dll。直接执行npm run dev npm run build的时候会发现我们的打包速度明显有所提升。因为我们已经通过dllPlugin将第三方依赖包抽离出来了。
参考
2.5.1.5 抽离第三方模块
React diff 策略
tree diff
基于策略一,React 对树的算法进行了简洁明了的优化,即对树进行分层比较,两棵树只会对同一层次的节点进行比较。
即同一个父节点下的所有子节点。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。这样只需要对树进行一次遍历,便能完成整个 DOM 树的比较。
component diff
React 是基于组件构建应用的,对于组件间的比较所采取的策略也是简洁高效。
element diff(不带key)
element diff(带key)
带key diff的过程看这里
参考
react diff 策略
webpack tree shaking 存在的问题
Tree-Shaking能帮助我们删除掉没有使用的代码,将会大大缩减打包后的代码量。
参考
1. 你的Tree-Shaking并没什么卵用
webpack 占位符
[ id ]
– 返回块ID。[ path ]
– 返回文件路径。[ name ]
– 返回文件名称。[ ext ]
– 返回扩展名。[ hash ]
– 返回构建Hash。如果构建任何部分发生更改,则也会发生更改。[ chunkhash ]
– 返回条目块特定的hash。在配置中定义的每个entry都会收到自己的hash。如果entry的任何部分发生变化,那么hash也会发生改变。[chunkhash]比[hash]定义更细。[ contenthash ]
– 返回特定于内容的hash。[contenthash]只适用于ExtractTextPlugin,是可用的、最具体的选项。Webpack入坑秘籍(18)
其他
1. 组件封装的要点
9. 如何设计一个 dialog 组件
① 确定UI
三种类型:alert、confirm、modal
样式是否支持自定义
② 确定API
③ 具体实现
参考
React造轮系列:对话框组件 - Dialog 思路
2. 项目中的难点
3. 工作收获
4. 项目经历
5. 职业规划
6. 还有什么要问的吗
7. 前端性能优化
后端log日志,流入kafka,可以准确监控接口异常
window.onerror js异常监控
try catch 捕获
异步异常的捕获,unhandledrejection
前端的performance api
Chrome devtool performance 工具
统计UV PV 转化率
8. 前端异常捕获与上报
前端异常捕获与上报
前端异常监控、上报及js压缩代码定位
8.1 前端首屏加载时间和白屏时间的概念
Web 性能优化-首屏和白屏时间
9. 对前端工程化的理解
前端的规模越来越大,已经上升到了工程学的问题,如何提高前端工程师的开发效率变得非常重要。这就是前端工程化所要解决的问题。前端工程化是根据业务特点,将前端开发流程规范化,标准化,它包括了开发流程,技术选型,代码规范,构建发布等,用于提升前端工程师的开发效率和代码质量。
一个符合前端工程化要求的方案应该包含以下要素:
我对前端工程化的理解
10. 单点登录和oauth2
前端关于单点登录的知识
The text was updated successfully, but these errors were encountered: