本文不是大厂的面试文,主要面向各位初中级前端,笔者从毕业开始,一直供职于一个二线城市的it公司,外包性质的公司带来的是技术的缓慢成长。虽然后面开始醒悟开始努力提高技术水平,但是总归还是浪费了几年的时光,现在后悔不已。希望各位刚开始工作初级前端同学加油。
笔者7月中旬来到杭州找工作,自己给自己定位是中级前端,因为暂时还没有算法基础,没有考虑大厂,只是面向一些中小型公司。花了1周半的时候各种面试,整体都比较顺利,对比之后确认了offer,8月初入职现在的公司。想把自己碰到的面试流程以及面试题分享给大家。
1、面试流程
1周半的时候,大部分日子基本都排满了面试,上午下午加上晚上的电话或者视频面试,我差不多面试了15个公司。整体来说,大部分中小公司的面试流程很简单,一到二轮的技术面试,一轮的hr面试。当然也碰到了5轮以上的公司(大华),不过效率都很快,要么直接当天几轮全部完成,要么就是先电话或者视频面试。
技术面:先自我介绍,然后技术面,不同公司问的问题深度都不太一致(凭这个其实可以大概了解这个公司的具体技术情况),有的甚至连vue源码都没有问到,手写代码的不多(我入职的这家公司我手写了简化的promise以及发布订阅设计模式)。主要还是偏向几块必备的知识点,js偏多,css相对比较少,vue框架,webpack,浏览器和http。然后基本上所有的公司对之前做过的项目问的还是比较多的,而且会很详细,大家可以在这方面多准备一下,比如项目的难点,项目中的优化。(说实话,真的做没做过不是那么重要,你可以以你现在的技术水平去编造一些项目的优化,当然必须是你自己真的深入学习过的,不然一问就露底了)
hr面:基本都类似,离职原因,期望的薪资,对于加班的看法,希望找一个怎么样的公司工作等等。
2、面试题
2.1 css
css问到的题基本都很简单
flex
三栏样式
float, float + bfc, Position, table, flex, gird。
垂直水平居中
flex + 块状子元素margin: auto, flex, absolute实现
css中定位有几种,相对于什么来定位
三种,相对定位(相对于原位置定位),绝对定位(相对于第一个不是默认定位的父元素的padding盒子的左上角定位),固定定位(相对于浏览器视图左上角定位)
css层叠上下文
这题可以有另外一种出题方式,是一道字节的面试题。z-index: auto和z-index: 0一样吗?
2.2 javascript
js是基础,一定要扎实
amd,cmd,common模块引入方式的区别(问到很多次)
common是服务端引入方式,js和业务逻辑是同步加载的。
amd和cmd是浏览器端的引入方式,业务逻辑是在js加载之后的异步回调里加载的。
amd是预加载所有的js,再去执行业务代码。cmd是懒加载,在业务代码里需要执行了再去加载。
怎么判断一个变量是数组(问到很多次)
instanceof
Object.prototype.toString.call
Array.prototype.isPrototypeOf
constructor
Array.isArray
补充:如何判断一个空数组?
防抖节流(问到很多次)
js继承(问到很多次)
一定要知道最优的寄生组合继承
深拷贝(问到很多次)
注意深拷贝需要注意一些特殊的数据类型,比如正则,date。基本数据类型直接返回就行,还要注意变量的循环引用问题
js隐式转化(问到很多次)
数组去重(问到很多次)
[...new Set(arr)]
Array.from(new Set(arr))
instanceof原理
不断的通过getPrototypeOf获取父的prototype然后进行比较
eventloop事件循环机制
宏任务通过堆栈一个一个运行,一个宏任务完成,会把所有的微任务全部运行完成。运行完成之后,如果浏览器刷新时间到了,会进行视图渲染。完成之后,继续执行下一个宏任务。
promise运行顺序
promise的构造函数里的内容是同步加载的,then后面定义的内容是放到微任务里异步加载的。
js冒泡,捕获以及事件代理
addEventListener的第三个参数配置点击事件是冒泡还是捕获,默认是false,冒泡,点击之后往上冒泡到document。可以设置为true,定义点击事件为捕获。
事件代理是冒泡的一个应用实践,如果一个子列表都需要点击事件,可以把点击事件定义在父元素上,子项点击的时候,会冒泡到父列表。然后通过获取到的target拿到点击的子列表的内容进行处理。
箭头函数与普通函数的区别?
箭头函数不会创建自己的this
箭头函数继承而来的this指向永远不变
箭头函数不能作为构造函数使用
箭头函数没有自己的arguments
箭头函数没有原型prototype
箭头函数不能用作Generator函数,不能使用yeild关键字
说一下高阶函数?
一个函数可以接受另一个函数作为参数或者返回值为一个函数,这种函数就称为高阶函数。
2.3 浏览器网络
说一下缓存?
缓存有四个地方可以存储,内存,硬盘,service Work,push cache。有两种缓存策略,强缓存和协议缓存。强缓存通过max-age过期时间判断是否直接获取缓存,如果过期,访问服务器,通过ETag判断文件是否过期,未过期返回304,浏览器从缓存取资源。如果过期,返回新的资源。
jsonp?
简单说就创建一个script标签,通过callback传过去一个函数名,在window下定义这个函数,服务端会运行这个函数,然后把数据传回来。需要可以手写jsonp代码
http和https区别?
http是明文传输的,虽然可以约定用非对称和对称密钥来通信,但是还是容易被拦截。
http是通过非对称和对称密钥,还需要经过一个ca,通过ca的公钥私钥的加解密来辨别数据是否被劫持,更加安全
浏览器从输入url到渲染的过程?
web端安全问题?
XSS:反射型,dom型,存储型
CSRF
点击劫持
控制台运行危险代码
2.4 vue框架
注意,我在这里只是写一下简单的原理,原理的具体实现必须深入源码去学习,靠这种简单的原理是过不去面试的。
vue的响应式实现原理?
vue中的响应式的实现主要是靠三个东西,defineProperty,Dep类,Watcher类。defineProperty用来劫持变量的get和set方法,Watcher类是vue渲染组件的方法,Dep类用来让变量存放与其有关的渲染Watcher的依赖。变量变化,通过收集到的依赖去进行视图的响应式更新。
vue的diff原理?
同级比较,再比较子节点
先判断一方有子节点一方没有子节点的情况(如果新的children没有子节点,将旧的子节点移除)
比较都有子节点的情况(核心diff)
核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。
说一下虚拟Dom?
虚拟dom本质就是用一个原生的JS对象去描述一个DOM节点,它映射到真实DOM要经历VNode的create、diff、patch等阶段。
key属性的作用?
在diff中进行key值的判断,尽可能的来复用dom元素。key不但需要设置,而且必须是设置成一个固定的值,不要使用v-for循环的index来当做key。不然不但不能提高性能,而且在一些特殊场景下还会出现bug。
组件中的data为什么是一个函数?
vue中组件是通过extend来生成一个vue的子类来进行渲染的,如果多次调用,是从缓存中直接调用的。data如果是一个对象,是引用类型,一个修改了,所有的调用组件都会发生变化。所以需要时一个函数,每次返回一个新的数据对象。
3、总结
上面题目其实不多,只是一个大致的方向,而且很多也只是说了一个简单的原理,面试当然不仅仅只有这些内容,有了扎实的基础,才能在面试的时候信手拈来。
准备面试,其实也是一个提升自我,查漏补缺的过程,js和css基础扎实,很多常见的js源码能够了解其实现原理,对vue(高级应用和源码)有相对较全面的深入学习(react我不了解),了解浏览器和http,熟悉工程化开发。
有了这些,才能作为一个合格的中级前端。
4、感谢
首先感谢您的浏览,希望您能够动动小手给咱点个赞,谢谢大家。有什么问题,大家可以加我下面的微信。