2019年前端面经

一、前戏

时隔「多年」,我又回来啦!

近期博客的月产出率实在不忍直视,转眼2019的上半年就这么就这么就这么过去了!马上就会迎接2020年了?!上半年自己的确发生了很多「故事」,去年年底刚吹完的??(详见本文--2019年工作展望),今年年初就要和我的老战友们说再见了,其中缘由复杂寒酸且不想谈了。

2月底3月初,在经历了一场无比刺激的社招面试大战之后,感受良多,也算是职业生涯中一场非常刻骨铭心的历练,经历过大厂的嘲讽;也经历过与小厂CTO的争执;更多的是和很多真正热爱技术的大牛相谈甚欢,但最终止于hr给出的薪酬待遇。幸而最后还是找到了属于自己的一份真爱(公司/技术团队)。

所有你所遇的,所得的,所见的,都离不开你曾经走过的每一步。

二、面试过程

这应该算自己真正意义上的第二次跳槽,相比于第一次跳槽的盲目面试,这一次也算有点小战略。前期,给自己定的是高强度电面刷题,查漏补缺,了解行情(当下面试的关注点都有哪些)。以至于前期的电话简直要爆了,自己也是累到喘不过气,这种做法还是稍有不妥,很影响自己在连续作战后的面试表现。

上图为其中某一天的来电记录,很容易因为上一场的电话面试延期而导致下一场的来电失败。想给自己点压力,这种也是没得办法┓( ´∀` )┏。。。

在经历了第一轮的电话面试之后,也能掂量出自己的半斤八两,同时也拿到了不少线下二面的机会,再经过一轮筛选后,便安排上了第二轮的战役,同样又是一场高强度的安排!orz...

上图为第二轮战役的部分截图,最惨的一次应该是一天没吃饭,连续面试了4家(中饭和晚饭的时间也安排上了),实际上当天晚上有安排第5家电话面试的,最终由于「法力值」消耗殆尽直接放弃了第5家的面试。

PS:之所以安排得如此紧张,是因为自己当时并非住在杭州,跑一趟杭州着实不易(请假费、交通费、住宿费都是钱呐),能放一块就尽量挤一挤吧。

三、面试摘要

面试的最大收益莫过于查漏补缺,短时间内理论知识储备的急剧上升,当然某些短板(例如高阶算法、源码解读等)是很难在短期内得到提升的,但至少自己能够意识到,并为此做好未来弥补的措施。

特殊的问题各厂花样百出,防不胜防,每年也都会有所不同,但是一些最基本的前端知识还是绕不开的,这里仅做一些此类基础题的记录,以免阴沟里翻了船。

先分享下在准备过程中,个人觉得很好看(very  useful)的几张图:

1. 关于MVVM的响应式原理

面试案例:

问:MVVM实现的方式是js的什么方法?

答:Object.defineProperty

M【模型】 -> V【视图】数据绑定  
V【视图】 -> M【模型】事件监听

MVVM是Model-View-ViewModel的简写。即模型-视图-视图模型。【模型】指的是后端传递的数据。【视图】指的是所看到的页面。【视图模型】mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。总结:在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信。

vueObserver 数据监听器,把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用Object.defineProperty()方法把这些属性全部转成setter、getter方法。当data中的某个属性被访问时,则会调用getter方法,当data中的属性被改变时,则会调用setter方法。

2. JS数据类型

面试案例:

问:js数据类型有几种?基础数据类型和引用数据类型有什么区别?数据深拷贝?如何判断数据类型是数组还是对象?......等等。

答:存储上,基础数据类型的值是存在栈中,引用数据类型的值是存在堆中,引用数据类型的指针是存在栈中;赋值上,基础数据类型是按值传递,引用数据类型是按指针传递。由于两者的存储/赋值的不同,也就引来了数据深拷贝的问题,数据深拷贝的方式请自行百度吧。

3. JS原型链

面试案例:

问:谈一下吧?(虽然很多面试官自己都不知道问这个有什么用,反正人家都这么问,那我也问一下吧)

答:(那就答一下吧)

定义层面上的理解:任何对象(函数、数组、对象)都有一个原型对象,这个原型对象由对象的内置属性(也叫隐式原型_proto_指向它的构造函数的prototype显式原型)指向的对象,即任何对象都是由一个构造函数创建的,但不是每一个对象都有prototype,只有函数(function)才有prototype。

方法/属性调用层面上的理解:当调用某种方法或查找某种属性时,首先会在自身调用和查找,如果自身并没有该方法或属性,则会去它的__proto__属性中调用查找,也就是它构造函数的prototype中调用查找。找都最后遇见null为止。

再来个简单的demo体会一下:

4. Event Loop

面试案例:

问:js异步函数有哪些?js的事件循环是怎样的?js的运行机制了解吗?js是多线程还是单线程?那浏览器呢?

答:浏览器是多线程的(more:一个tab页包含2个进程,分别是html引擎和js引擎),js是单线程语言。

js异步操作常见的有:DOM事件绑定Ajax请求setTimeout定时器。总的来说,涉及回调函数的都可以理解为异步操作。

js执行机制:所有同步任务都在主线程上的栈中执行 => 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。=> 一旦"栈"中的所有同步任务执行完毕,系统就会读取"任务队列",选择出需要首先执行的任务(由浏览器决定,并不按序)。

讲就讲这么多,这个知识点真的很关键,这个搞不懂的话怎么好意思说自己是js开发,几个重要的知识点:1.堆、栈、队列的认识。2. task(macro-task)和micro-task 两者的区别。更多资料可以参考 => 从Promise来看JavaScript中的Event Loop、Tasks和Microtasks

5. CSS盒子模型

问:css盒子模型有几种?怎么解决IE下的怪异盒子模型带来的问题?box-sizing的作用?

答:css盒模型本质上是一个盒子,封装周围的HTML元素,它包括:外边距(margin)、边框(border)、内边距(padding)、实际内容(content)四个属性。他在不同浏览器上的表现也有所不同,主要分为两种:W3C盒子模型(标准盒模型)IE盒子模型(怪异盒模型)

box-sizing 属性允许您以特定的方式定义匹配某个区域的特定元素。

Box-sizing: content-box;//宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框。

box-sizing: border-box;// 为元素设定的宽度和高度决定了元素的边框盒。就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。

box-sizing: inherit;// 规定应从父元素继承 box-sizing 属性的值。

即box-sizing属性可以指定盒子模型种类,content-box指定盒子模型为W3C(标准盒模型),border-box为IE盒子模型(怪异盒模型)。

(内心OS:我们公司早就放弃了对IE的治疗,box-sizing是哪位?)

面试总结

好累啊,不想总结了,只想吟诗一首——路漫漫其修远兮,吾将上下而求索。

发布了175 篇原创文章 · 获赞 345 · 访问量 74万+

猜你喜欢

转载自blog.csdn.net/fifteen718/article/details/95639841