好难好难!记东西对理科生好难!!现在就是找一些别认的面试题,和我身边人面试遇到的面试题来刷,所以如果看到重复的那可能就是问的多了哈哈哈。
说一下事件循环event loop
1、JavaScript是单线程,非阻塞的
2、浏览器的事件循环
- 执行栈和事件队列
- 执行栈: 同步代码的执行,按照顺序添加到执行栈中
- 事件队列: 异步代码的执行,遇到异步事件不会等待它返回结果,而是将这个事件挂起,继续执行执行栈中的其他任务。当异步事件返回结果,将它放到事件队列中,被放入事件队列不会立刻执行起回调,而是等待当前执行栈中所有任务都执行完毕,主线程空闲状态,主线程会去查找事件队列中是否有任务,如果有,则取出排在第一位的事件,并把这个事件对应的回调放到执行栈中,然后执行其中的同步代码。
- 宏任务和微任务
-
执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环。
-
宏任务:
- setImmediate
- setTimeout
- setInterval
- script(整体代码)
- I/O 操作等。
-
微任务:
- new Promise().then(回调)
- MutationObserver(html5 新特性)
-
node环境下的事件循环
-
和浏览器环境有何不同
- 表现出的状态与浏览器大致相同。不同的是 node 中有一套自己的模型。node 中事件循环的实现依赖 libuv 引擎。Node的事件循环存在几个阶段。
- 如果是node10及其之前版本,microtask会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行 microtask队列中的任务。
- node版本更新到11之后,Event Loop运行原理发生了变化,一旦执行一个阶段里的一个宏任务(setTimeout,setInterval和setImmediate)就立刻执行微任务队列,跟浏览器趋于一致。
-
事件循环模型
- 外部输入数据 --> 轮询阶段(poll) --> 检查阶段(check) --> 关闭事件回调阶段(close callback) --> 定时器检查阶段(timer) --> I/O 事件回调阶段(I/O callbacks) --> 闲置阶段(idle, prepare) --> 轮询阶段
-
宏任务和微任务
- 宏任务一样
- 微任务:
- process.nextTick
- new Promise().then(回调)
Promise.nextTick, setTimeout, setImmediate的使用场景和区别
-
Promise.nextTick
process.nextTick 是一个独立于 eventLoop 的任务队列。
在每一个 eventLoop 阶段完成后会去检查 nextTick 队列,如果里面有任务,会让这部分任务优先于微任务执行。
是所有异步任务中最快执行的。 -
setTimeout:
setTimeout()方法是定义一个回调,并且希望这个回调在我们所指定的时间间隔后第一时间去执行。 -
setImmediate:
setImmediate()方法从意义上将是立刻执行的意思,但是实际上它却是在一个固定的阶段才会执行回调,即poll阶段之后。
闭包
定义在一个函数内部中的另一个函数,其中一个内部函数在包含他的外部函数之外被调用时,就会形成闭包。
闭包会带来什么问题?
会造成内存泄露
为什么会造成内存泄漏
内存泄露是指我们无法通过js访问某个对象,而垃圾回收机制却认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存永远无法释放,积少成多。
重绘和回流说一下
回流:render树中一部分或全部元素需要改变尺寸、布局、或着需要隐藏而需要重新构建,这个过程叫做回流。
重绘:当页面中元素样式的改变并不影响它在文档流中的位置,只是影响元素的外观,风格,而不会影响布局的,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
什么样的场景会发生重绘和回流?
首次页面渲染
浏览器窗口大小发生改变
元素尺寸或者位置发生改变
元素内容变化(文字数量或者图片大小等等)
元素字体大小变化
添加或者删除可见的DOM元素
重绘和回流谁的开销更大?
回流
flex布局
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为 Flex 布局。
.box{
display: flex;
}
行内元素也可以使用 Flex 布局。
.box{
display: inline-flex;
}
Webkit 内核的浏览器,必须加上-webkit前缀。
.box{
display: -webkit-flex; /* Safari */
display: flex;
}
设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。
常用属性
position的几个属性说一下
relative:相对定位,不脱离文档流,相对于其正常位置进行定位,本身在文档流中的定位。
absolute:绝对定位,脱离文档流,相对于static以外的第一个父级元素定位,具体是哪个父元素,就要看父元素是否应用了position属性。如果父元素没有应用position样式,那么就会继续向上查找,直到html元素。如果都没有找到,absolute就会根据html进行定位;相反,如果找到某个父元素有absolute或者relative或者fixed,则会先对这个元素进行定位。
fixed:固定定位,脱离文档流,相对于视口(viewport,浏览器窗口)进行偏移,即定位基点是浏览器窗口。
static:默认值,元素出现在正常的流中。浏览器会按照源码的顺序,决定每个元素的位置,这称为"正常的页面流"(normal flow)。每个块级元素占据自己的区块(block),元素与元素之间不产生重叠,这个位置就是元素的默认位置。
promise解决的是一个什么问题?
是异步编程的一个解决方案,主要用来解决回调地狱。
常把promise用在哪里?
使用 Promise 将层层的嵌套回调做成了链式调用。
all 接收一个 Promise 数组,会同时执行数组中的每个方法(注意是同时执行,不是顺序执行),当所有方法执行完成,将每个方法的返回值按顺序封装成一个数组,然后统一执行then方法。
race用法:
all是所有方法完成才执行then, race 是其中任意一个方法执行完了就执行then,切记:then只执行一次
asycn await
Async就是generation和promise的语法糖,async就是将generator的*换成async,将yiled换成await
函数前必须加一个async,异步操作方法前加一个await关键字,意思就是等一下,执行完了再继续走,注意:await只能在async函数中运行,否则会报错
把await和成功后的操作放到try里,失败的放在catch
-
为什么要用await
- 为了使我们的异步代码,更像同步的代码
-
有多个promise,怎么拿到所有的promise都结束后的结果
- await是直接获取多个promise的结果的,因为Promise.all()返回的也是一个promise所以如果要使用await拿到多个promise的值,可以直接await Promise.all()
- async函数会返回一个promise,并且Promise对象的状态值是resolved(成功的)
- 如果你没有在async函数中写return,那么Promise对象resolve的值就是是undefined,如果你写了return,那么return的值就会作为你成功的时候传入的值
-
await 等到之后,做了一件什么事情?
那么右侧表达式的结果,就是await要等的东西。
等到之后,对于await来说,分2个情况,是不是promise?- 如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
- 如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。
你知道的数据结构
数组
栈
队列
链表
图
树
前缀树
哈希表
八大数据结构
栈和队列的区别
队列(Queue):是限定只能在表的一端进行插入和在另一端进行删除操作的线性表;
栈(Stack):是限定只能在表的一端进行插入和删除操作的线性表。
区别如下:
一、规则不同
- 队列:先进先出(First In First Out)FIFO
- 栈:先进后出(First In Last Out )FILO
二、对插入和删除操作的限定不同 - 队列:只能在表的一端进行插入,并在表的另一端进行删除;
- 栈:只能在表的一端插入和删除。
三、遍历数据速度不同 - 队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快;
- 栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。
git的常用命令
这个之前有说过太长了就不写了 给个链接吧git常用命令在最下面哦!