前言
笔者毕业于东北大学,大学毕业社招进入环球网,前端开发工程师一职。技术栈:React+node,Github 地址
成果
来到杭州的目标非常的明确,大厂。其实就是网易、阿里和滴滴。好在基本三家都拿到了offer。最终决定选择阿里p6。
面试题
大厂流程比较长,比如阿里就面试了将近三周。所以期间也面试了很多别的公司,创业公司or上市公司。这里我把我所被问到的面试题总结梳理一下。简单深入的都有。笔者个人工作经验不丰富,如若回答不好的地方欢迎指正。
HTML && CSS 部分
React的render函数返回的是一个DOM描述,结果仅仅是轻量级的js对象,reactjs在调用setState的时候会更新DOM,而且是先更新virtual dom,然后和实际dom比较,最后更新dom。React厉害的地方不是说他比真实的dom速度快,而是你不敢数据怎么变化,我都以最小的代价来更新视图。方法就是我在内存当中使用新的数据来构建一个virtual dom,然后和旧DOM进行比较,找出差异,然后更新到DOM节点上。当我们修改dom上的一个节点对应的state,react会立即将他标记为“脏状态”,在事件循环的最后才重新渲染所有的脏节点。在实际的代码中,会对新旧两棵树进行一次深度优先遍历,这样每一个节点都会有一个唯一的标记,没遍历到一个节点,就把该节点和新的树进行比较,如果有差异就记录到一个对象中,最后把差异应用到真正的DOM树上。算法实现步骤为:用js对象模拟DOM树,比较两颗虚拟DOM的差异,把差异应用到真正的DOM树上,DOM DIFF采用的是增量更新的方式,类似于打补丁。React需要为节点添加key来保证算法的效率。Key属性可以帮助react定位到正确的节点进行比较。从而大幅度减少DOM操作,提高性能。
- MVC和MVVM了解么?可以大致说一下双向绑定的实现方式么?
Modal层代表数据模型,可以再modal层定义修改和操作数据的逻辑,view代表UI层,负责将数据转换成UI展现出来,viewModal是同步view和modal的对象。用户操作view层,view数据变化会同步到modal上,modal数据变化会立即反应到view中,viewModal通过实现双向绑定来将view和modal连接到一起。而双向绑定,我们可以从脏检查到标记更新来回答。
考核的主要是浏览器加载页面的机制。大概可以从浏览器拿到HTML,自上而下开始解析,大致分为解析DOM,解析CSSOM,构建渲染树,布局阶段以及绘制阶段来说明。其实尽可能的详细说明,比如构建DOM的时候分别通过Bytes、characters、tokens、Nodes最终到DOM等。回答也可以扩展repaint和reflow等浏览器优化。
顾名思义是form cache是强缓存,不会和服务器通信,而200OK即为服务器处理结果正确。以此可以从浏览器缓存、输入url回车、刷新页面以及强制刷新等方面展开缓存方面的讲解。
1、2采用二进制而非文本格式,二进制协议解析起来更高效。
2、采用多路复用,即为同一个tcp连接上可以建立多个http连接,那样的话,我们雪碧图就没有必要了。
3、使用报文头压缩,降低了开销。
4.可以让服务器主动向浏览器推送消息,支持服务端推送,也就是服务端可以对客户端有多个响应。
1 、GET把参数包含在URL中,POST通过request body传递参数。
2、GET在浏览器回退时是无害的,而POST会再次提交请求。 GET产生的URL地址可以被Bookmark,而POST不可以。 GET请求会被浏览器主动cache,而POST不会,除非手动设置。 GET请求只能进行url编码,而POST支持多种编码方式。 GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。 GET请求在URL中传送的参数是有长度限制的,而POST么有。 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。 GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。 GET参数通过URL传递,POST放在Request body中。
3、GET和POST是什么?HTTP协议中的两种发送请求的方法。
4、HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。5、HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
6、在我大万维网世界中,还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。
7、GET产生一个TCP数据包;POST产生两个TCP数据包。
8、对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?1. GET与POST都有自己的语义,不能随便混用。2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
构建工具
Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程,1、初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;2、开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;3、确定入口:根据配置中的 entry 找出所有的入口文件;4、编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;5、完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;6、输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;7、输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。
编写过webpack插件吗

1、Webpack 通过 Plugin 机制让其更加灵活,以适应各种应用场景。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。2、Webpack 启动后,在读取配置的过程中会先执行?new BasicPlugin(options)?初始化一个 BasicPlugin 获得其实例。 在初始化 compiler 对象后,再调用?basicPlugin.apply(compiler)?给插件实例传入 compiler 对象。 插件实例在获取到 compiler 对象后,就可以通过?compiler.plugin(事件名称, 回调函数)?监听到 Webpack 广播出来的事件。 并且可以通过 compiler 对象去操作 Webpack。3、在开发 Plugin 时最常用的两个对象就是 Compiler 和 Compilation,它们是 Plugin 和 Webpack 之间的桥梁。 Compiler 和 Compilation 的含义如下:Compiler 对象包含了 Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 Compilation 将被创建。Compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。4、Compiler 和 Compilation 的区别在于:Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只是代表了一次新的编译。5、开发插件时需要注意:只要能拿到 Compiler 或 Compilation 对象,就能广播出新的事件,所以在新开发的插件中也能广播出事件,给其它插件监听使用、传给每个插件的 Compiler 和 Compilation 对象都是同一个引用。也就是说在一个插件中修改了 Compiler 或 Compilation 对象上的属性,会影响到后面的插件、有些事件是异步的,这些异步的事件会附带两个参数,第二个参数为回调函数,在插件处理完任务时需要调用回调函数通知 Webpack,才会进入下一处理流程。
开发过webpack loader么
1、一个 Loader 的职责是单一的,只需要完成一种转换。 如果一个源文件需要经历多步转换才能正常使用,就通过多个 Loader 去转换。 在调用多个 Loader 去转换一个文件时,每个 Loader 会链式的顺序执行, 第一个 Loader 将会拿到需处理的原内容,上一个 Loader 处理后的结果会传给下一个接着处理,最后的 Loader 将处理后的最终结果返回给 Webpack。2、所以,在你开发一个 Loader 时,请保持其职责的单一性,你只需关心输入和输出。

感悟
以上问题包括但不全面对于这次杭州的求职。总的来说,你的简历就是你给面试官的考纲,所以简历一定要真实,及时面试过程中遇到不会的题目,也要沉着冷静思考,不会也要主动承认,然后最好能够提出自己的思考和猜测。千万别不懂装懂!千万别不懂装懂!千万别不懂装懂!
前端,个人还是觉得基础很重要,从基础到框架,从框架就到原理,从原理到源码,一步一脚印。一定要自信,直面面试官,表现出自己最好的状态。同事别太咄咄逼人,一定要尊敬面试官,礼貌。
最后,还是希望每一个求职者,都能够进入自己如愿以偿的公司拿到心仪的offer~
ps:如若文章有不当之处,欢迎大家指正。谢谢~
学习交流
关注公众号: 【全栈前端精选】 每日获取好文推荐。
公众号内回复 【1】,加入全栈前端学习群,一起交流。
