本篇总结了我这一个月来的面试经历和一些知识点。
面经归纳
javaScript
- js数据类型有哪些 ,typeof null和typeof undefined 区别
- 深浅拷贝
- var let const区别
- 块级作用域
- 箭头函数与普通函数的区别
- 原型链
var name='byte'
var obj1={
name:'dance',
getName:()=>{
return this.name;
}
}
var obj2={
name :'day1',
getName:function getName(){
return this.name;
}
}
obj1.getName();
obj2.getName();
- 事件循环
首先事件循环分为两种,一种是浏览器内部的宏微任务循环,一种是nodejs基于libuv的事件循环模型,二者必须区分开来。
推荐三篇文章:
js中的宏任务与微任务 - 知乎
看完一定懂的 Event Loop
某谷面试实录
回答宏任务微任务:
JS是单线程的,但是我们在写代码的时候,会有同步执行的代码和异步执行的代码。EventLoop就是一种解决异步回调的一种机制。具体的解决办法就是使用一个执行栈和事件队列,事件队列又分为宏任务队列和微任务队列。简单的来讲,就是把代码从上到下,会把同步任务压入到执行栈,遇到异步的任务,根据异步任务的类型,放入不同的事件队列,交给其它线程进行处理。如果执行栈空的话,就从事件队列当中取出结果,放入到执行栈中执行并执行。Event Loop 的每一次循环称为一个tick
,具体是先拿出一个宏任务,然后检查它里面的微任务,如果有的话,就执行所有的微任务,结束之后,进行一次渲染。再拿出一个宏任务,按照刚刚的过程继续进行。
执行顺序:
- 先执行同步代码(取出一个宏任务)
- –>执行所有微任务 (本轮完毕)
-->UI render
- –>执行下一个宏任务 (下轮开始)
- –>执行下一个所有微任务 (下轮完毕)
-->UI render-->......
- –>执行下一个宏任务 (下下轮开始)
- …
-
列举一下有哪些函数是宏任务,有哪些是微任务?
宏任务
script(整体代码) setTimeout setInterval I/O UI交互事件 postMessage MessageChannel setImmediate(Node.js 环境)
微任务
Promise.then Object.observe MutationObserver process.nextTick(Node.js 环境)
-
MutationObserver是什么?
Mutation observer 是作为观察DOM树结构发生变化时,做出相应处理的API。
//new MutationObserver(function(records, itself){}); //变化记录数组(MutationRecord),另一个是观察者对象本身 //void observe(Node target, optional MutationObserverInit options) //dom节点,可选参数 // Firefox和Chrome早期版本中带有前缀 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver // 选择目标节点 var target = document.querySelector('#some-id'); // 创建观察者对象 var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); }); }); // 配置观察选项: var config = { attributes: true, childList: true, characterData: true } // 传入目标节点和观察选项 observer.observe(target, config); // 随后,你还可以停止观察 observer.disconnect();
-
讲讲数组有哪些方法
TypeScript
-
ts比起原生js有什么好处?
-
如果一个函数返回的值不确定,怎么确定类型?
通过类型推断或者泛型
-
类型推断如何理解
-
typescript 泛型
提供ts一种灵活定义数据类型的能力注意:必须把泛型定义的参数当做是任意类型
比如你不能
function loggingIdentity<T>(arg: T): T { console.log(arg.length); // Error: T doesn't have .length return arg; }
但可以使用约束,即让T继承一个接口
interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // Now we know it has a .length property, so no more error return arg; }
- ts 接口和type的区别
- type可以声明基本类型别名、联合类型、元祖等类型
// 基本类型别名 type Name = string; // 联合类型 interface Dog { wong() } interface Cat { miao(); } type Pet = Dog | Cat; // 具体定义数组每个位置的类型 type PetList = [Dog, Pet];
Vue
-
父组件嵌套子组件,父子组件的生命周期顺序
因为在父组件挂载时(beforeMount 和mounted)中间会定义一个
updateComponent = () => { vm._update(vm._render(), hydrating) }
其中执行vue.render();render的作用是生成vnode,render其中_c('test')会分析是普通元素还是组件,如果是组件则会执行createComponent,这时子组件会被再次合并选项,安装生命周期钩子..
所以顺序是父create两个 父beforeMount 子组件生命周期 父mounted 这个顺序执行。
-
Vue nextTick原理
可看:异步更新原理
要先说vue异步更新原理:
- 修改 Vue 中的 Data 时,就会触发所有和这个 Data 相关的 Watcher 进行更新。
- 首先,会将所有的 Watcher 加入队列 Queue。
- 然后,调用 nextTick 方法,执行异步任务。
- 在异步任务的回调中,对 Queue 中的 Watcher 进行排序,然后执行对应的 DOM 更新。
自然,在异步更新之后,因为先入先出原则,所以会执行用户注册的nextTick函数,此时就能获取到更新后的dom了。
CSS
- 至少3种方法实现元素的垂直居中布局
- 弹性布局
-
flex:1是哪几种属性的缩写?
flex-grow flex-shrink flex-basis
flex-grow:分配弹性盒占比,默认0
flex-shrink:分配剩余空间占比,默认1,比如父盒子300px,3个子盒子150px,设置flex-shrink分别1:1:2第一个盒子削减 1501/4
第二个盒子削减1501/4
第三个盒子削减150*1/2 -
flex有哪些属性?
flex-direction flex-flow flex-wrap justify-content align-items align-content aligin-self flex-grow-flex-shrink flex-basis
-
flex-basis 属性用于设置伸缩(主轴上)基准值,和witdh差不多,但basis优先级更高。
-
css如何画三角形
transparent 会让边框透明,这里理解的关键是边框的形状。<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> /* css3绘制三角形 */ .triangle { width: 0px; height: 0px; /* border-top: 200px solid #00a497; */ border-bottom: 200px solid #cc7eb1; border-left: 200px solid transparent; border-right: 200px solid transparent; } </style> </head> <body> <div class="triangle"></div> </body> </html>
前端性能
-
有哪些关于前端性能的指标?
FCP: First Contentful Paint
LCP: Largest Contentful Paint
FMP: First Meaningful Paint
DCL: DOMContentLoaded Event
L: onl oad Event -
怎么度量,获取这些指标?
利用performance可视化工具和performance API
-
如何让用户访问时更快的看到主要元素
预加载
-
延迟加载,预加载?
延迟加载,利用getBoundingClientRect()判断视口位置,在视口内部就渲染,不在则不渲染。
预加载 preload或者prefetch,二者在html头部选择
二者的区别就在于preload是强行提高加载优先级,prefetch是利用js的空闲时间实现预加载。
-
页面上的图片的优化策略
缓存,预加载,懒加载,用户机型适配
-
讲一下图片压缩算法
gzip
不同图片格式也有自己的算法jpg,png等等
有无损压缩和有损压缩
计算机网络
- tcp和udp的区别
- 请求方式有哪些,get和post的区别
- cookies怎么设置
算法&编程题
- 数据结构算法 |排序有哪些|数的结构,有哪些遍历方法
- 实现一个parseObj({a:{b:[0,1,2,3,4]}},'a.b[0]'),取出a.b[0]的值
- 实现函数的call、apply、bind方法
- promise.all