2020中高级前端面试题合集

“全方位总结一下所遇到的面试题目,与大家共同学习,也是对自己的一次总结”

文章同步到我的公众号《前端小时》,欢迎大家关注!

01 前言


2020是不平凡的一年,这一年里发生许多事情,大家也都知道。对于互联网行业来说也是一次重大的打击,也有一些企业在这次疫情中倒闭了,所以可能对于今年2020年毕业的同学来说是一次很大的考验,也关乎我们的前途。

今年的面试基本上都不会线下面试,都是采取线上电话/视频的形式来进行,今天我就总结一下,分享一下自己所遇到的一些面试题,希望大家在这次春招中能够拿到满意的offer!毕竟自己当初也是看了很多师兄姐的面经,算是一个回馈社区。共勉!

02 目录


下面是这篇文章的目录结构,一般比较简单的问题我就一笔带过了,主要是分享一下比较有难度的知识点,答案来自网上,如果有版权问题我会删除。还有本文只是给出一个大概的知识点,如果想要深入学习还要靠自己去查一下哦!

如果答案有错误,欢迎指正!

  • 计算机基础
  • 前端基础(HTML/CSS)
  • JavaScript
  • 前端框架
  • 浏览器渲染
  • 计算机网络
  • 手写代码
  • Webpack
  • Node
  • ES6

03 计算机基础


进程与线程的区别

查看详情

  • 进程是系统进行资源分配和调度的一个独立单位
  • 线程是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位
  • 一个进程至少有一个线程组成

线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源

进程间通信方式
  • 管道通信
  • 消息队列通信
  • 信号量通信
  • 共享内存通信
  • 套接字通信
函数库与系统库
  • 系统库调用运行在内核模式,函数库运行在用户模式
  • 系统调用是os提供的服务,处于内核态且不能直接调用,而要使用类似int 0x80的软中断陷入内核
  • 库函数中有很大部分是对系统调用的封装
  • 函数库属于过程调用,开销小;系统库需用户空间和内核上下文环境切换,开销大
  • 用户态可以调用系统提供API接口调用内核来切换成内核态(中断方式)
二叉树
  • 二叉树每一个节点不能多于两个孩子
  • 没有孩子的节点就是叶子节点
  • 一个节点有左右两个指针,若无则指向null
  • 深度为h的二叉树最多有2^h-1个结点(h>=1),最少有h个结点
  • 二叉树的遍历三种方式,如下:
    (1)前序遍历(DLR),首先访问根结点,然后遍历左子树,最后遍历右子树。简记根-左-右。
    (2)中序遍历(LDR),首先遍历左子树,然后访问根结点,最后遍历右子树。简记左-根-右。
    (3)后序遍历(LRD),首先遍历左子树,然后遍历右子树,最后访问根结点。简记左-右-根
数据库索引
  • 索引是一种数据结构(B+树)

  • 不推荐使用索引

(1)表记录太少;
(2)数据重复且分布平均的字段(只有很少数据值的列);
(3)经常插入、删除、修改的表要减少索引;

  • 使用索引

(1)主键,unique字段;
(2)和其他表做连接的字段需要加索引;
(3)在where里使用>,≥,=,<,≤,is null和between等字段;
(4)使用不以通配符开始的like,where object like ‘Math%’;
(5)order by和group by字段;

数据库引擎
  • InnoDB存储引擎
  • MyISAM存储引擎
  • MEMORY存储引擎
  • Archive存储引擎
虚拟内存及缓冲区溢出
虚拟内存
  • 虚拟内存是计算机系统内存管理的一种技术
  • 应用程序认为它拥有连续的可用的内存,实际分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上
  • 虚拟内存技术可以通过覆盖或者把处于不活动状态的程序以及它们的数据全部交换到磁盘上等方式来实现
缓冲区溢出
  • 计算机向缓冲区填充数据时超出了缓冲区本身的容量,覆盖合法数据
危害
  • 堆栈溢出,可以改变返回程序地址
  • 程序崩溃,拒绝服务
  • 执行非法代码,获取非法权限
  • 程序运行失败,系统宕机,重启
排序算法

查看详情

  • 快速排序(nlogn)
  • 选择排序(n^2)
  • 插入排序(n^2)
  • 希尔排序(n^1.5)
  • 归并排序(nlogn)
  • 冒泡排序(n^2)
常用git指令
  • 下载一个项目和它的整个代码历史 git clone [url]
  • 添加指定目录到暂存区,包括子目录 git add [dir]
  • 提交暂存区到仓库区 git commit -m [修改信息]
  • 同步到远程仓库, git push
  • 列出所有本地分支 git branch
  • 新建一个分支,并切换到该分支 git checkout -b [branch]
路由器与交换机
  • 路由器可以给你的局域网自动分配IP,交换机只是用来分配网络数据的
  • 路由器在网络层,路由器根据IP地址寻址,路由器可以处理TCP/IP协议,交换机不可以
  • 交换机在中继层,交换机根据MAC地址寻址
  • 路由器提供防火墙的服务,交换机不能提供该功能

04 前端基础(HTML/CSS)


flex容器布局
  • 查看详情
主轴属性
  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content
交叉轴属性
  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self
BFC/IFC

BFC(Block Formatting Context)叫做“块级格式化上下文"

(1)内部的盒子会在垂直方向,一个个地放置;
(2)盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠;
(3)每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此;
(4)BFC的区域不会与float重叠;
(5)BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此;
(6)计算BFC的高度时,浮动元素也参与计算。

触发条件
(1)float的属性不为none;
(2)position为absolute或fixed;
(3)display为inline-block,table-cell,table-caption,flex;
(4)overflow不为visible

IFC(inline Formatting Context)叫做“行级格式化上下”

(1)内部的盒子会在水平方向,一个个地放置;
(2)IFC的高度,由里面最高盒子的高度决定;
(3)当一行不够放置的时候会自动切换到下一行;

CSS3的filter属性详解
  • 查看详情

  • blur

  • brightness

  • contrast

  • grayscale

  • hue-rotate

  • invert

  • opacity

  • saturate

  • sepia

CSS的继承属性(部分)
  • font-size:设置字体的尺寸
  • text-indent:文本缩进
  • text-align:文本水平对齐
  • text-shadow:设置文本阴影
  • line-height:行高
  • 元素可见性:visibility
  • 光标属性:cursor
CSS盒模型
  • W3C 标准盒模型:
    属性width,height只包含内容content,不包含border和padding

  • IE 盒模型:
    属性width,height包含border和padding,指的是content+padding+border

content-box(标准盒模型)
border-box(IE盒模型)

CSS的四种定位
  • Static

    这个是元素的默认定位方式,元素出现在正常的文档流中,会占用页面空间。

  • Relative

    相对定位方式,相对于其父级元素(无论父级元素此时为何种定位方式)进行定位,准确地说是相对于其父级元素所剩余的未被占用的空间进行定位(在父元素由多个相对定位的子元素时可以看出),且会占用该元素在文档中初始的页面空间,即在使用top,bottom,left,right进行移动位置之后依旧不会改变其所占用空间的位置。可以使用z-index进行在z轴方向上的移动。

  • Absolute

    绝对定位方式,脱离文档流,不会占用页面空间。以最近的不是static定位的父级元素作为参考进行定位,如果其所有的父级元素都是static定位,那么此元素最终则是以当前窗口作为参考进行定位。可以使用top,bottom,left,right进行位置移动,亦可使用z-index在z轴上面进行移动。当元素为此定位时,如果该元素为内联元素,则会变为块级元素,即可以直接设置其宽和高的值;如果该元素为块级元素,则其宽度会由初始的100%变为auto。

    注意:当元素设置为绝对定位时,在没有指定top,bottom,left,right的值时,他们的值并不是0,这几个值是有默认值的,默认值就是该元素设置为绝对定位前所处的正常文档流中的位置。

  • Fixed

    绝对定位方式,直接以浏览器窗口作为参考进行定位。其它特性同absolute定位。当父元素使用了transform的时候,会以父元素定位

CSS权重计算
  • 第一等级:代表内联样式,如style="",权值为 1000
  • 第二等级:代表id选择器,如#content,权值为100
  • 第三等级:代表类,伪类和属性选择器,如.content,权值为10
  • 第四等级:代表标签选择器和伪元素选择器,如div p,权值为1
    注意:通用选择器(*),子选择器(>),和相邻同胞选择器(+)并不在这个等级中,所以他们的权值为0

CSS优化技巧
  • 合理使用选择器
  • 减少DOM操作,减少重绘和重排
  • 去除无效的选择器
  • 文件压缩
  • 异步加载文件
  • 减少@import的使用
px/em/rem/vh/vw
  • px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的
  • em是相对长度单位。相对于当前父元素的字体尺寸。如未设置,则相对于浏览器的默认字体尺寸
  • rem是CSS3新增的一个相对单位。使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素
  • css3新单位,view width的简写,是指可视窗口的宽度。假如宽度是1200px的话。那10vw就是120px
  • css3新单位,view height的简写,是指可视窗口的高度。假如高度是1200px的话。那10vh就是120px

05 JavaScript


闭包以及作用域
  • 查看详情

  • 作用域是可访问变量的集合,可以分为全局作用域和局部作用域。

  • 闭包就是将函数内部和函数外部连接起来的一座桥梁

  • this是在函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用

事件循环机制
  • 查看详情

  • 宏任务与微任务的区别

  • Node中的事件循环机制

JS垃圾回收与V8垃圾回收
  • JS:标记清楚法/引用计数法
  • V8:标记清除发/标记压缩法/增量标记法/压缩算法 查看详情
原型与原型链
  • 所有原型链的终点都是 Object 函数的 prototype 属性
  • 每一个构造函数都拥有一个 prototype 属性,此属性指向一个对象,也就是原型对象
  • 原型对象默认拥有一个 constructor 属性,指向指向它的那个构造函数
  • 每个对象都拥有一个隐藏的属性 __ proto __,指向它的原型对象

JavaScript基本类型及其判断
  • boolean
  • string
  • number
  • null
  • undefined
  • symbol
  • object
function getType(obj) {const str = Object.prototype.toString.call(obj);const map = {'[object Boolean]': 'boolean','[object Number]': 'number','[object String]': 'string','[object Function]': 'function','[object Array]': 'array','[object Date]': 'date','[object RegExp]': 'regExp','[object Undefined]': 'undefined','[object Null]': 'null','[object Object]': 'object'};return map[str];
}
JavaScript数组API

查看详情

  • push() pop()
  • shift() unshift()
  • sort() reverse()
  • concat() slice()
  • splice() join()
  • indexOf() lastIndexOf()
  • forEach() map()
  • filter() every()
  • some() reduce()
  • reduceRight()
JavaScript设计模式

查看详情

  • 单例模式
  • 适配器模式
  • 代理模式
  • 发布-订阅模式
  • 策略模式
  • 迭代器模式
操作节点API总结
查找节点
  • document.getElementById :根据ID查找元素,大小写敏感,如果有多个结果,只返回第一个
  • document.getElementsByClassName :根据类名查找元素,多个类名用空格分隔,返回一个 HTMLCollection 。
  • document.getElementsByTagName :根据标签查找元素, * 表示查询所有标签,返回一个 HTMLCollection 。
  • document.getElementsByName :根据元素的name属性查找,返回一个 NodeList 。
  • document.querySelector :返回单个Node,如果匹配到多个结果,只返回第一个。
  • document.querySelectorAll :返回一个 NodeList。
  • document.forms :获取当前页面所有form,返回一个 HTMLCollection ;
创建节点
  • createElement创建元素
  • createTextNode创建文本节点
  • cloneNode 克隆一个节点
  • createDocumentFragment 创建文档碎片,主要是用来存储临时节点,大量操作DOM时用它可以大大提升性能
修改节点
  • appendChild
  • insertBefore
  • removeChild
  • replaceChild

06 前端框架


vue的双向数据绑定原理
  • 监听器 Observer ,用来劫持并监听所有属性(转变成setter/getter形式),如果属性发生变化,就通知订阅者
  • 订阅器 Dep,用来收集订阅者,对监听器 Observer 和 订阅者 Watcher 进行统一管理
  • 订阅者 Watcher,可以收到属性的变化通知并执行相应的方法,从而更新视图
  • 解析器 Compile,可以解析每个节点的相关指令,对模板数据和订阅器进行初始化

vue不能检测哪些属性变化
数组
  • 使用下标更新数组元素
  • 使用赋值方式改变数组长度
  • 使用下标增删数组元素

官方应对方法:

  • Vue.set( target, key, value )
  • vm.items.splice(indexOfItem, 1, newValue)
对象
  • 增删元素

官方应对方法:

  • Vue.set(target, propertyName, value);
  • Vue.delete( target, propertyName/index )
虚拟DOM

查看详情

  • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象
  • diff 算法 — 比较两棵虚拟 DOM 树的差异
  • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树
vue模板解析

查看详情

  • 模板变成AST(解析器)
  • AST遍历静态节点(优化器)
  • 生成渲染函数(代码生成器)
diff算法
  • diff算法是比对组件中的节点异同的情况

vue的生命周期
  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed
  • activated
  • deactivated
  • erroeCaptured
vuex

查看详情

  • state:用于数据的存储,是store中的唯一数据源
  • getters:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算
  • mutation:类似函数,改变state数据的唯一途径,且不能用于处理异步事件
  • action:类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作
  • modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护
vue组件通信方式
  • props / $emit 适用 父子组件通信
  • ref 与 $parent / $children 适用 父子组件通信
  • EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
  • attrs/attrs/attrs/listeners 适用于 隔代组件通信
  • provide / inject 适用于 隔代组件通信
  • Vuex 适用于 父子、隔代、兄弟组件通信
watch/computed的区别
  • computed是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值
  • watch是观察监听的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作
  • 当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed
  • 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch
v-if与v-show的区别
  • v-if 是真正的条件渲染,直到条件第一次变为真时,才会开始渲染
  • v-show是由display样式决定,不管初始条件是什么都会渲染
  • v-if 适用于不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景
vue中的路由模式
history模式
  • HTML5中的两个API:pushState和replaceState,改变url之后页面不会重新刷新,也不会带有#号,页面地址美观,url的改变会触发popState事件,监听该事件也可以实现根据不同的url渲染对应的页面内容
  • 但是因为没有#会导致用户在刷新页面的时候,还会发送请求到服务端,为避免这种情况,需要每次url改变的时候,都将所有的路由重新定位到跟路由下
hash模式