Q1 vue是怎样一个框架呢?
这道题答道了mvvm 运行效率 虚拟dom 内部集成打包测试语法规范..
缺点是没说到兼容性和渐进增强,响应式编程计算属性 b 会将 a 作为一个依赖进行追踪,每当 a 变化,b 也自动跟着变化。你不需要特意去声明 b 的依赖,因为这本来就不应该由你来做。
A1:
从技术选型上看,vue作为一个轻量级渐进增强的前端框架,运行效率高,向下兼容IE9,适合构建SPA单页应用,vue从1.0到2.0有着比较完整的全家桶套装,同时mpvue的出现也为微信全家桶的开发降低了开发成本,一些基于vue的spa应用不需要在使用微信的语法进行重写,可以直接从webapp过渡成小程序
从框架功能上看,vue-cil集成测试框架,代码检查,打包工具,可以实现一站式项目初始化,项目打包。同时基于npm的模块化开发也节约了开发成本。Vue的设计者尤雨溪在开发vue的时候借鉴了ng和react的语法,watch computed等api可以方便的完成数据的监听和依赖绑定和追踪。虚拟化dom操作使页面渲染的速度更快,减少性能损耗
从可迁移、可维护、可拓展上看:将原来的项目使用vue进行重写的成本是最低的。vue得语法基于ES6,简洁高效,单文件组件的模式易于维护,组件,插件,方法都可以自定义,配合styuls编写可以实现html css js的全组件化。拓展性很强
从学习成本上看,vue的语法相对简单,而且试试响应的模式方便调试,报错具体易于查找,论坛文本教程完善丰富。使用人群很多,团队给力处理issue的效率很高。
缺点是native开发能力相对较弱,生态建设有待完善(ide插件,高亮,提示)
Q2 说下语法规范和测试框架使用什么工具
因为自己写demo的时候疏忽了测试,但是语法规范还是有做有尝试的,所以只回答了eslint
A2:
测试工具的介绍阮一峰老师在博客中有提到,基本流程就是npm引入-->在需要测试的脚本同级目录下编写测试脚本-->引入断言库-->cd到该目录下-->$ mocha testfile-->返回测试结果、测试时间(命令后面紧跟测试脚本很的路径和文件名可以指定多个测试脚本$ mocha file1 file2 file3)
Mocha默认运行test子目录里面的测试脚本。(根目录下)所以,一般都会把测试脚本放在test目录里面,然后执行mocha就不需要参数了。,如果test子目录中也有需要运行的测试用例就需要使用$ mocha --recursive,这时test子目录下面所有的测试用例----不管在哪一层----都会执行。
http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
关于eslint的一些用法这篇文章总结的很好,代码规范化,有利于团队开发统一代码风格,规范化的代码有利于可读和维护。ESSint的优点在于所有的检测可插拔,规则相对独立,可以配置自己的codingstyle
https://www.cnblogs.com/yoable/p/5788198.html
测试工具:Nightwitch/chai/Mocha
语法检查:eslint
Q3 vue节约dom操作,具体怎么节约的,react有没有这种操作 具体实现原理虚拟dom和原生dom的区别
答道了对比jq的点,实现原理说到了虚拟dom dom树 渲染树渲染树和js接口通信,回流重绘,diff算法
A3:
渲染引擎在浏览器中是与JavaScript引擎分离的,JS操作DOM结构,渲染引擎会暴露一些接口供JavaScript调用。由于这两块相互分离,通信是需要付出代价的,因此JavaScript调用DOM提供的接口性能不咋地。各种性能优化的最佳实践也都在尽可能的减少DOM操作次数。
而虚拟DOM干了什么?它直接用JavaScript实现了DOM树(大致上)。组件的HTML结构并不会直接生成DOM,而是映射生成虚拟的JavaScript DOM结构,React和vue又通过在这个虚拟DOM上实现了一个 diff 算法找出最小变更,再把这些变更写入实际的DOM中。这个虚拟DOM以JS结构的形式存在,计算性能会比较好,而且由于减少了实际DOM操作次数,性能会有较大提升。
Q4 虚拟dom的运算在vue组件生命周期有对应的执行周期么?如果有是哪个周期呢?
这道题没有回答上,我只知道vue的10个钩子,但是具体哪一步会发生虚拟dom的计算之前没有关注过。这次好好学习下
A4:
Beforecreat 在vue实例创建之后,监控data数据变化之前
Created 在vue 初始化内部事件之后,查找el节点之前或者模板渲染成html模板之前或者在模板编译进路由之前,即通常初始化某些属性值,然后再渲染成视图。视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素
BeforeMount 在模板导入或者模板生成之后在用上面编译好的html内容替换el属性或vm。 $mount指向的dom对象(调用这个钩子的时候还没有生成html到界面)
Mounted 已完成模板渲染或el对应html渲染后,在模板渲染成html后调用,通常是 初始化页面完成后,再对html的dom节点进行一些需要的操作。一般插件
会经常用到这个钩子
Updated 事件更新完成后的钩子 和dom更新有关
Beforeupdate 事件更新之前的事件钩子
BeforeDestory 实例销毁之前
Destroyed 此时实例已经被销毁
综上虚拟dom运算应在Created之后BeforeMount之前会触发,还会在beforeupdate和update之间被触发
Q5虚拟dom的diff算法涉及到树的遍历吗?如果有是什么序的遍历方式呢?
A5:
mydivVirtual代表它,它存储了对应dom的一些重要参数,在改变dom之前,会先比较相应虚拟dom的数据,如果需要改变,才会将改变应用到真实dom上。很多时候手工优化dom确实会比virtual dom效率高,对于比较简单的dom结构用手工优化没有问题,但当页面结构很庞大,结构很复杂时,手工优化会花去大量时间,而且可维护性也不高,不能保证每个人都有手工优化的能力。至此,virtual dom的解决方案应运而生,virtual dom很多时候都不是最优的操作,但它具有普适性,在效率、可维护性之间达平衡。
virtual dom 另一个重大意义就是提供一个中间层,js去写ui,ios安卓之类的负责渲染,就像reactNative一样。
react的diff其实和vue的diff大同小异。所以这张图能很好的解释过程。比较只会在同层级进行, 不会跨层级比较。所以会涉及到树的遍历,是层序遍历如下图
Q6mvvm是什么架构 和mvc的区别
这道题回答的也不好,答道了mvc中vue可以访问model model不依赖于view但是view依赖于model 说到了mvvm是数据与页面逻辑分离的
A6:
Model-View-Controller
在ASP还在奋斗的时候WebForm突然到来,正如WebForm还在奋斗的时候MVC突然到来。当然,我这里讲的MVC还是最原始的MVC,因为MVC在我们还在争论的时候已经发展了许多不同分支了。
有一点相信大家同意的就是,我们今天讨论争论的MVC、MVP、MVVM、Code Behind等等都源自于职能分化和规划的思想与目的,MVC不是它们的开始,但是一个很好的开始。
相信MVC的模型大家很熟悉,也很容易找到,我们这里用一下某百科的图:
我们可以看到的是,界面被分到了View,数据分到了载体Model上由Model“携带”,业务集中在Controller中,而推动业务的事件由用户与View交互,通过View向Controller发动。当然,实现由很多种,每种细节上都有不同,所以我才只讲也只能讲大致的MVC。MVC的其中一个缺点便是没有明确的定义,所以不同的实现(比如Struts和ASP.NET MVC)细节上都是不一样的。
我们需要知道的是,MVC并不是像上面所说的一些事情那样是一种“必然的”结果,它是一系列必然结果问题中的一种解决方案,而且是不完美的解决方案。我们顺着推理去到一个地方很容易犯的一个错误就是认为路只有这一条而忽视其他可能性(估计这也是导致很多争斗的原因)。另外,我们在讨论一件事物不完美的时候是有一个情境的,所以请不要像“我说它色彩单一,然后你把它涂成彩色后证明我是错的”。
MVC的一般流程是这样的:View(界面)触发事件--》Controller(业务)处理了业务,然后触发了数据更新--》不知道谁更新了Model的数据--》Model(带着数据)回到了View--》View更新数据这里也不多再陈述MVC的原理、实践等等,因为这就太长篇大论了。
Model-View-Presenter和一些衍生
像我们之前推理的,分化是一种需求的必然结果,但却没有个一个确定的结果,比如Code Behind和Code Block的问题等等。MVC顺着需求把UI相关的工作分化成了三份,这点经过实践证明无可厚非。但是它们的三角关系却被一些人认为带来了一些问题,或者应该说他们有“更好的”解决方案。
在只有Code Behind和Code Block的那个时候维护是很直接的,不是在同一段代码内解决就是在同一个关联的事件上解决。三角关系的问题就是维护问题。在MVC,当你有变化的时候你需要同时维护三个对象和三个交互,这显然让事情复杂化了。
我们之前说到,随着摩尔定律,软件的需求不断地变化和变得庞大。随着需求变得庞大的时候,需求变化也变得频繁,这是一个出现了无数次以后也将会出现无数的无数次的一个问题,所以它需要一个解决方案,哪怕它不一定能被解决。
为了解决需求变化,从《人月神话》到敏捷到DDD,它不是我们已经解决了的问题,而是我们正在解决的问题。放在UI的模式和MVC上来讲,就是优化或者替代MVC模式,其中之一就是Model-View-Presenter(MVP)模式。
我们先看看两个MVP模式的图:
(图一)
(图二)
两幅图是不同的,但是对MVC的改进的思想却是一样的:切断的View和Model的联系,让View只和Presenter(原Controller)交互,减少在需求变化中需要维护的对象的数量。
这种方式很符合我们的期待,因为我们倾向于:
1.用更低的成本解决问题
2.用更容易理解的方式解决问题
许多时候并不是一种模式不好,而是因为人没办法执行,比如不容易理解,我们就会选择容易理解的方式。计算机依赖摩尔定律用数量的增长来解决问题,而人是用方式的改变来解决问题的。同样因为客观原因我们不善于维护多个对象和多个对象之间的关系,所以我们改变了,或者说简化了这种方式。
MVP定义了Presenter和View之间的接口,让一些可以根据已有的接口协议去各自分别独立开发,以此去解决界面需求变化频繁的问题。上面两图都有接口,不过接口的实现和使用细节不一样,不过思想上是一致的。
在这里要提到的是,事实上,需求变化最频繁的并不一定是最接近用户的界面,但基本可以确定的是,最接近用户的界面是因为需求变化而需要最频繁更改的。当然,如果View如果是API而不是UI,那就另说了。
还有一些用来“解决”MVC这项缺点的比如有:ASP.NET MVC的ViewBag,Cocoa的delegate。它们都为了简化数据更新的问题而存在,包括MVVM。
Model-View-ViewModel
先直接看看Model-View-ViewModel(MVVM)的图:
从图上看是比MVP简单了,更不用说MVC了。个人不认为MVVM是从MVP进化而来,我只觉得这是在MVP之后出现的一种“更好的”UI模式解决方案,但是用MVP来与之对比比较容易说明问题。
ViewModel大致上就是MVP的Presenter和MVC的Controller了,而View和ViewModel间没有了MVP的界面接口,而是直接交互,用数据“绑定”的形式让数据更新的事件不需要开发人员手动去编写特殊用例,而是自动地双向同步。数据绑定你可以认为是Observer模式或者是Publish/Subscribe模式,原理都是为了用一种统一的集中的方式实现频繁需要被实现的数据更新问题。
比起MVP,MVVM不仅简化了业务与界面的依赖关系,还优化了数据频繁更新的解决方案,甚至可以说提供了一种有效的解决模式。至此,我们能理解为什么许多人认为MVVM是最好的一种模式,没有之一。但事实上,MVVM也是依赖于我们至今所讲的“特有的情境”。当然,最优雅的也是第一个能作代表的实践就是Windows Presentation Foundation(WPF)了。
Web
之上,我们在模式演变的推论基本上都还是基于桌面软件的,但是过去十年却是互联网的时代。实际上大部分让大家争议的并不是在桌面领域最合适的是那个,而是在Web领域的模式问题,也就是在B/S场景下的问题。
当软件离开单机,去到网络的时候,因为场景变了,所以原有的解决方案也变了,不过需求依然是不变的。我们依然要解决的问题是用户交互与数据更新的问题,还有维护等等的问题。当场景变到Web的时候,我们发现MVVM用来做服务端是极其不适用的,至少现在是不适用的。而MVP你提都不用提。为什么呢?因为:
1.网络资源成本过高
2.开发成本过高
问大家一个问题,当一个网页的数据更新后,你希望更新用户看到的数据,你会怎么做?
一般情况下,你会:window.location.reload();就算你不这么做,用户也会:F5
就像之前说的,我们会选择更直接的方式解决问题。直接刷新页面的原因是因为这样更直接,更容易解决数据更新的问题。
很多时候你不会愿意为了一个数据更新写一个AJAX,更别说这个AJAX要带来Loading、事件顺序处理、网络问题、异常处理等等,这就是开发成本过高。另一个网络成本过高就更容易解释了,虽然宽带是基本包月的,但也不带这么用的,何况还有移动用户。更主要的原因是,在本地软件,更新数据是一个引用问题,而在网络应用上,这是一个传输问题。传输成本远高于引用成本,引用之上顶多是在本地内存中再进行一次内存拷贝。
这个时候,我们会更倾向于用MVC模式,因为在Web层面,我们更倾向于一次性更新数据。
Web的MVVM
所有问题都不是问题,就算有问题也要解决问题。为什么这个标题下突然冒出这么一句话?我想说的是,需求依旧是不变的,是推动进步的原动力。还有我之前说过,当我们讨论或者争论一个问题的时候,问题的对象已经发生改变了,而且这次是在我们讨论这个问题之前已经发生改变了。网络资源成本不断下降,相信已经不需要多提及。摩尔定律和相近的一些原理正在发挥着它应用的作用,网络带宽越来越高、相应速度越来越快。
如果传输因为相对成本下降而导致数据传输的成本低于开发人员拒绝客户的成本,那么它就会被实现而不是被拒绝。
另外还有一点就是因为技术的进步,技术的资源不断被更大规模地压榨,需求也不断地增长,那么需求始终会增长超过相对不变的开发成本的。比如jQuery的出现解决了很多问题,我们现在更多地去使用AJAX,哪怕很大一部分依然是为了解决网络资源不足的问题;我们会用更多的样式代码而用了相对更少的图片;我们不再那么依赖Flash一类的矢量图解决方案而直接录制视频。
至少上一节我们说到的两个导致大家选用MVC的问题都正在被解决,所以我们有理由相信未来Web不仅仅需要MVC,可能会需要MVVM或其他解决方案。至少我们能理解容易理解为什么前端会出现一些MVVM的框架,比如先驱knockout.js和AngularJs。这些框架本身的好坏就不作讨论了,因为我们讨论的是模式。在Web上,MVVM的对比对象就不是MVC,而是Code Block。数据即时更新的需求在扩大,但未必有达到一定要用MVVM这一等级的高大上的模式,实际上如果你要更新一个数据,你还是会采取:
$('.notice').html('发送成功!');
因为......我们依然会采取更直接的方式解决问题......
实际上,现在Web MVVM主要并不是用在了Web或者Wap上,而是移动App上。按照前面的说法,只可能是:
HTML+JS比原生在一些场景上更适合Native
在移动App上比Web上更适合使用MVVM
哪怕是Native开发,实际上iOS的开发上也是用类似的数据绑定的方式的。这里也不深究了,毕竟我也不算懂iOS。
要说的是,在Web MVVM或者Web的模式上,也就是Web的富应用上,现在还不过是个初期由膨胀的需求推动的阶段。重要的不是技术会怎么走,而是需求和客观条件会怎么走。
可能Webform会因为高速开发而焕发第二春,它的AJAX的模式也十分满足于简单开发,但似乎大家需要的不是GUI式的网页。
Q7mvvm有controller么?
我回答的是没有
A7:
MVVM将view controller 中的(view controller不是一个你拥有的对象,因为它是Apple class 的一个子类) 代码移动到了你拥有的view model 中。这样view controller 就很容易的能够聚焦view生命周期时间。尽管这样,我们的代码还是大量的聚集在一起,它只是从view controller 移动到了 view model 中而已。
Q8 event loop的了解,eventloop会空循环么?如果队列里的任务执行完了,他会退出循环还是保持循环?内部事件是栈还是队列排列?为什么?
说道时间循环,涉及道同步异步,js单线程机制,主线程读取时间是循环的,这种运行机制就是eventloop
A8:
这里引用阮一峰老师的两篇文章
什么是 Event Loop?
http://www.ruanyifeng.com/blog/2013/10/event_loop.html
JavaScript 运行机制详解:再谈Event Loop
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
Q9 es6的了解 箭头函数的特点
A9:
箭头函数是se6的语法,特点回答了this的指针指向定义它的对象,而不是执行的对象,保证了this的指针不会被改变,实现原理是箭头函数不会自动绑定局部变量,写法简单,简化函数的定义,
漏掉了他是个匿名函数的这一点
Q10 this的指向的内容是怎么传递到函数内部的?比如es5中有.bind(this)有形参传递到函数内部,但是es6是如何传递的呢?
我回答的是通过原型链,但是应该是错误的
A10:
这个答案没找到,心塞...
我问面试官的问题:怎样在深入了解api和熟练使用api上找到平衡
这个每个人的看法都不同,也分人,刚工作不久的话,能够熟练使用是必须具备的本职工作,就像学习是学生的天职一样。而且基层工作,要得是执行力,而不用思考太多,慢慢积累经验之后才有能力去深入理解,模仿和学习。另外也涉及到你自己对自己的职业生涯的规划了 ,有的岗位就是造轮子,有的岗位就是写crud ,前端开发本身就对算法基础要求没有其他的岗位高的
以下是面试官给出的意见:
自信一点,坦然面对不足学会查漏补缺,经得起考验
对于知识点盲区需要好好探索一下,吧自己的坑填好
多刷面试题