有赞

emmm。寄生组合继承和new,diff和nextTick()没答好,其余都答出来了然而还是挂了。可能看我主要是vue开发,react部分问的较少,总体而言问的非常基础没有过多询问框架方面的问题。

面试过程大概40分钟,面试官态度还不错。评价是有几个问题没答出来但因为只有一年经验,还可以。

css

position的几个属性,分别的效果

两种盒模型区别

BFC

说几种css3的选择器

重绘和回流

JavaScript

实现一个深拷贝

commenJS和ES6中的模块的区别

原生实现一个promise.cancel()

箭头函数和普通函数区别

寄生组合继承方式实现

实现一个new操作符

垃圾回收机制的两种算法,以及具体思路

闭包的概念,用途

事件循环的机制、宏任务、微任务

http

缓存方式,怎么实现

跨域方式,具体原理和操作方法

vue

diff算法

双向数据绑定原理和实现

为什么数据变更后视图要延时更新

实现一个nextTick()方法

react

高阶组件的原理和用途

阿里

直接从简历项目入手的。先自我介绍,然后抓住自我介绍中的项目开始问。背景是最近做的项目有一个vue里嵌入react的,一个用docker部署发布的。

vue嵌入react

Q1:基于什么需求什么场景,为什么会这么做,实现思路是什么,中间踩过什么坑?

A:老的鲁班平台是基于的VUE的,开放式多团队开发,想在团队内升级和做代码管理,但又需要原有的发布流程,只有嵌套别的框架。

​ 实现过程是在vue宿主页面下建立一个空的div id=”root”根节点,让编译后的react渲染到这个根节点上,这样左侧的菜单还是vue的,右侧的content是react渲染的。

​ 踩过的坑有 引入的js渲染出的页面失去了所有的事件,点击和hover都不起作用,一开始的解决方法是把代码包裹在$.ready里,后续觉得这样也不方便因为还要在打包好后的代码前后包裹上函数体,后续采取动态创建script的方式延迟引入js文件,也解决了这个问题。

Q2:还有一些点,比如左侧路由和右侧content怎么配合呢。

A:一开始是一个页面一个react单页框架。后续打算让react劫持和判断路由,如果浏览器的url命中了react的路由表,那么交由react去跳转路由,如果react未命中,说明是原有的老页面,跳转到原有的vue框架去处理。

Q3:思路是对的,但这个过程中必然还有一些问题,比如如果我跳转前的页面里注册了全局事件,跳转之后这些没注销的事件监听会造成内存泄露的问题,这个怎么解决。

A:在componentWillUnmount()里注销事件监听?

Q4:这样对代码要求很高,团队内的同学可能不能都做到这样。

A:在路由跳转前加个回调,路由一旦发生变化就去做注销事件的操作。

Q5:思路不错。但可能缺少具体的API实现。如果我封装了一个类,有一个静态方法xxx是addEventListener,我在组件里先是实例化了这个类,后又调用了这个方法注册了一个事件侦听,那么我注销事件传入handler的时候是传入classname.xxx还是this.xxx会确保注销这个事件?

A:我觉得是this。实例化后的handler能更精确的引用了这个handler吧。。

Q6:emmm,你说反了,classname.xxx更确保注销这个事件,你可以再看看这方面的东西。嵌入的尝试我们团队也在这么做,还会有一些内存泄漏、组件样式覆盖,同名不同版本依赖相互覆盖等等问题,不过你都还没碰到过。后面你也会碰到的。

docker部署

Q1:你们docker部署的流程是怎么样的?

A:代码写好编译好后push进git,服务器上pull这份代码后,根据dockerfile,build一个docker image,镜像名标注版本号,然后kill掉上一个版本的docker进程,run起新的docker镜像。

Q2:手动敲命令起docker?没有别的工具吗?

A:这是我们在本地测试的时候用的流程,测试ok后会把docker移交给业务方,通过k8s管理docker。

Q3:我看你用过python的flask,你能说下flask怎么设置多进程处理并发吗。

A:emmmm。。不能,不会。

Q4:flask只是个框架,你们怎么对外提供服务?

A:ngnix,配了一层反向代理。让前端访问flask的端口,再让ngnix对外提供web服务。

模块化

Q1:说说对模块化的理解。

A:从ES5时代,有了AMD规范和蚂蚁的玉伯提出的CMD规范,采用module.export和require的语法导入导出一个模块,区别是AMD的依赖需要在文件头写明,CMD随用随引。再后来ES6推出了import和export语法。还有一套模块化规范是CommenJS,同步模块加载,nodejs受CommenJS指导更多,但不适用于前端页面需要异步加载模块的场景。

Q2:模块化带来什么好处?

A:大概能想到两点吧,首先是让前端工程化成为可能,拆分功能模块使前端能够有能力构建大型项目,另一个是适应多团队开发,只要遵循约定和规范暴露出接口就可以让不同团队协作开发。

Q3:嗯,那模块化在代码和性能上有什么意义?

A:模块化切分了作用域,使模块的变量私有化,不污染全局也不担心变量名冲突。性能上的话,模块的加载是有缓存的,同一个模块只会被加载一次,下一次引用会直接从缓存取用。

Q4:模块和类继承都可以实现我们的一些需求,你会在什么样的场景使用模块化,什么场景使用继承?

A:其实我不太理解这个问题。。不过说一下我的两个开发经历吧。

​ 之前用echarts画图的时候,一个页面要画好多图,每次都要把echarts的api都调用一遍,于是我写了一个类,把初始化和渲染等公用的方法封装进这个类的静态方法,然后折线图、饼图、柱图等子类继承父类,同时再定义子类自己的私有方法组织不同的数据结构,调用父类上的公有方法初始化和渲染图表。

​ 模块化方面的实践是我在写项目的时候,ajax需要加上平台的token,sls请求也需要每次都自己实现一遍。如果每次都写的话又很繁琐,于是写了一个npm包把请求过程封装进去,每次用的时候从npm包导入方法调用即可,尽量的屏蔽了里面的细节。

​ 因此我觉得类适合写一些有共性的但又有不一样的功能,模块适合写一些工具类耦合性极低的功能。

源码

Q1:你用过vue全家桶、react、jq,看过源码吗?

A:看过vue1.0 core.js部分的源码,描述了一个vue类实例化的过程,在不同的生命周期阶段不断的给vue挂载属性和方法,挂载dom节点,初始化数据以及初始化双向绑定的过程。也看过jq1.0部分的源码,描述了一个jq对象的生成过程,无new实例化,链式调用等等功能的实现。

Q2:挺好的,那你知道vuex的实现过程吗?

A:大致描述了一下状态管理的流程,视图层dispatch一个action,做一些异步调用,把数据commit到mutation,再mutate到state中,最终视图层再引用这个state。

Q3:那你知道VUEX怎么跟vue组件建立联系的吗?

A:不知道。

Q4:如果让你实现一个VUEX,你会怎么做?

A:简单的状态管理的话,用vue的事件总线,通过事件触发的方式传递消息。复杂一些的话,可能我会封装一个类,在类中保存状态,对外暴露方法取用状态数据。

Q5:是个可行的思路,不过你看过VUE的源码,有个mixin的过程,你有什么启发吗?

A:我没答出来,是create一个全局的对象,mixin到vue根实例里。vuex也是这么干的。

剩下细枝末节的问题想起来再补,面试过程一个半小时,面试官对我的评价是能力不错想法很好,源码阅读习惯也很好,但webpack和移动端开发因为没接触到所以是个短板,前后端架构能力还需要提高。虽然感觉希望渺茫,面试体验很好,而且觉得学到了很多东西。。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

做事与共事 Previous
函数的节流和防抖 Next