乐趣区

记一次前端面试的全过程

引言
接上一篇面试总结一年半经验,百度、有赞、阿里面试总结,把这段时间的面试总结束一下吧。
本文主要记录一下当天面试的全过程(可能有遗漏,事隔三四天了,我已经尽量回忆了),答案亦为参考答案,仅供借鉴。
正文
有赞一面结束后过了两天就收到了二面的邀请,我回复面试邀请的短信,说最近可能请假太多,能不能约到晚上面试,对方很很爽快的答应了,就约在了晚上七点半,我回复可以的,然后第二天,收到了确切的面试的时间和地点,时间定在了晚上 7 点 15 分。
到了面试当天,我提前了五分钟下班,照着百度地图的提示路线(约 1 小时 9 分钟),到了公交站等车。。。然后等呀等,等了十五分钟公交还没来,怕自己迟到,就打了个滴滴过去,到了面试地点之后上到了公司的前台,前台没有人,可能是因为到饭点了,前台去吃饭了吧。然后看到前台那层楼好多人在打乒乓球,大家也玩得挺开心,看起来环境也很不错,当时想,诶呀,原来有赞的环境这么好。等了一会儿之后,看了一下短信,发现面试邀请里留有面试官的联系电话,果断打了过去,过了一会儿面试官到前台接我,然后找了一个会议室,开始了当天的面试。

面试官:先自我介绍吧
我:巴拉巴拉 …
面试官:先说一下你上一家公司的研发部署流程
我:巴拉巴拉 …(其实这个是我绝活,每次都可以吹很久)
面试官:既然你们是文件覆盖式发布,那你们的缓存是怎么刷新的
我:从公司的业务出发,巴拉巴拉 …(还没说完)
面试官:那我现在就不谈业务,你说一下浏览器的缓存方案吧
我:哦,脱离业务呀,首先,浏览器有两种缓存方案,一种是强缓存一种是协商缓存。
面试官:嗯,那怎么使用强缓存?
我:浏览器在第一次请求资源的时候,服务端响应头里可以设置 expires 字段,该字段表示该资源的缓存过期时间,第二次请求的时候,如果时间还在该缓存时间之内,则会直接使用缓存,否则重新加载资源,这个 expires 字段有个缺陷,就是它必须服务端和客户端的时间严格同步才能生效,所以现在很多人不会使用改方案。另外一种方案是第一次请求资源的时候,服务端设置响应头 cache-control: max-age,这样设置的意思是告诉浏览器,这个资源什么时候过期,等第二次请求资源的时候,判断是否超出了过期时间,如果没超出,直接使用缓存。
面试官:cache-control 这个头是服务端设置的还是客户端设置的?
我:cache-control 服务端设置的
面试官:cache-control 的其他值,你也说一下吧
我:首先是 public,客户端和服务端都可以缓存;然后是 private,只能客户端缓存;no-store,不使用缓存;no-cache,使用协商缓存。
面试官:那你往下说,说一下协商缓存
我:协商缓存有两种,一种是 Last-Modified,就是第一次请求资源的时候,服务端会在响应头里面设置该字段,表示该资源的最后修改时间,浏览器第二次请求该资源的时候,会在请求头里面加上一个字段 If-Modified-Since,值为第一次请求的时候服务端返回的 Last-Modified 的值,服务端会判断资源当时的最后更改时间与请求头里面的 If-Modified-Since 字段是否相同,如果相同,则告诉客户端使用缓存,否则重新下载资源。然后另外一种协商缓存时使用 ETag,原理与 Last-Modified 类似,就是第一次请求的时候,服务端会根据资源的内容或者最后修改时间生成一个标识,然后在响应头里面设置为 ETag 返回给客户端,客户端第二次请求的时候会在请求头里面带上这个 ETag,也就是在请求头里面加上 If-None-Match 字段,服务端接收到了 ETag 之后判断是否与原来第一次的标识相同,如果相同,则告诉客户端使用缓存。
说一下 Last-modified/If-Modified-Since 和 If-None-Match/ETag 两种方案的优缺点
我:嗯呢,这个我想一想(我并不知道,假装思考一下)…… 我觉得其实 ETag 其实也是有的时候是根据资源的最后修改时间生成的,原理和 Last-modified 好像有点类似,而 ETag 需要耗费服务端的资源去生成,所以性能较低。。。(虽然不会,也尽量说说,万一面试官也不知道呢。哈哈哈哈)
面试官:那说一下性能优化的方案吧
我:首先,减少 HTTP 请求次数,比如说合并 CSS 和 JS 文件,但是也不要完全的合并在同一个文件里面,一个域名分散三四个资源,这样方便浏览器去并行下载,当然浏览器对每个域名的并行下载个数有限制,一个域名分配三四个资源虽然增加了 HTTP 请求数量,但是对比并行下载来说,性价比更高。
面试官:为什么浏览器要限制同一域名并行下载资源的个数。
我:嗯呢,这个我也想一下(其实我也不知道)…… 这个我没有深究过,难道是因为浏览器启动了太多下载线程的原因?
面试官:下载资源和线程有什么关系?
我:除了了每个标签页是一个进程以外,浏览器有一个进程是专门用来管理下载,我觉得大概是每下载一个资源启动一个线程吧(反正我也不知道,也猜猜结果是不是这样)
面试官:(沉默了一会儿),进程和线程区别是什么
我:进程是分配内存的最小单位,线程是 CPU 调度的最小单位,进程可以包含多个线程。
面试官:nodejs 用得多吗?说一下 nodejs 进程之间是怎么通信的
我:nodejs 用的比较少,nodejs 可以启动子线程,然后用主线程来监听订阅子线程的消息,子线程之间的通信,由主线程来控制。(大概错了吧,应该是进程)
面试官:好吧,性能优化继续往下说
我:减少 HTTP 请求数量还可以把图标合并在同一张图片里面,使用的时候用 background-position 去控制。然后首屏的时候图片使用懒加载的形式,尽量在需要显示的时候在加载它,当然占位符和图片尽量指定宽度和高度,避免图片加载完之后替换图片浏览器会进行回流。
面试官:图片懒加载怎么实现
我:监听浏览器的滚动事件,结合 clientHeight、offsetHeight、scrollTop、scrollHeight 等等变量计算当前图片是否在可视区域,如果在,则替换 src 加载图片,当然这个滚动事件要主要节流。
面试官:怎么判断图片是否加载完成
我:使用 onload 事件。
面试官:好吧,你继续往下说。
我:性能优化的话,还可以合理的利用缓存,尽量把 CSS 和 JS 文件使用外链的形式,虽然使用内联的 CSS 和 JS 在空缓存的时候更快,因为内联的样式和脚本不需要发送 HTTP 请求,但是为了尽量发挥浏览器的缓存功能,尽量使用外链形式。
我:然后尽量把 CSS 放在头部,JS 放在底部。
面试官:假如现在页面里放在 head 的 css 文件下载速度很慢,页面会出现什么情况?
我:大概页面会等待这个 CSS 的下载,这个时候页面是白屏状态,然后这个 CSS 资源会有一个超时时间,假如超过了这个超时时间,这个资源相当于会下载失败,浏览器会直接跳过这个 CSS 资源,根据已有的 CSS 资源生成 CSS 规则树,进而生成 Render 树,然后渲染页面。
面试官:假如我现在在页面动态添加了一个 CSS 文件,页面一定会回流吗?
我:只要假如的 CSS 影响到了页面的结构,那么浏览器就会回流。
面试官:例如页面这个 CSS 文件中有 translate3d 呢?
我:其实我感觉它不会回流,因为 translate3d 只是变换了自己的位置,不会影响其他元素的位置,但是实际上是会造成回流的。
面试官:那假如我在页面里面加了一个 <div style=”position:absolute;width:0;hegiht:0″></div> 呢,会回流吗
我:不会,因为没有影响页面结构的变化。
面试官:好吧,那你继续往下说
我:性能优化,尽量使用 CDN。
面试官:CDN 的原理是啥?
我:首先,浏览器会先请求 CDN 域名,CDN 域名服务器会给浏览器返回指定域名的 CNAME,浏览器在对这些 CNAME 进行解析,得到 CDN 缓存服务器的 IP 地址,浏览器在去请求缓存服务器,CDN 缓存服务器根据内部专用的 DNS 解析得到实际 IP,然后缓存服务器会向实际 IP 地址请求资源,缓存服务器得到资源后进行本地保存和返回给浏览器客户端。
面试官:你来实现以下刚刚说的节流函数吧
。。。当时有点不记得什么是防抖,什么节流,把函数写成了防抖。(这个时候有一个人走进了会议室,好像是一面小哥)
var debounce = function(fn, delay, context) {
let timer = null;
return function() {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
const arg = Array.prototype.slice.call(arguments);
fn.apply(context, arg);
}, delay)
}
}

// 测试部分
var run = function(text) {
console.log(text);
}

run = debounce(run, 200);

run(‘run1’);
run(‘run2’);

setTimeout(() => {
run(‘run3’);
}, 201)

面试官:我这边没有什么问题了,你还有什么要补充的吗?
我:那我把性能优化这个问题说完?
面试官:可以。
然后我开始描述使用 webpack 使用进行减少 js 文件的体积,可以使用 babel-plugin-import、babel-plugin-component、webpack.ContextReplacementPlugin、webpack.IgnorePlugin…
面试官:这个我知道。你还有什么问题吗?(大概是想结束面试了吧,不想让我往下说了)
我:巴拉巴拉。。。问了很多关于有赞公司的问题,比如公司有多少层楼啊、公司主要技术栈啊、公司主要做 2B 还是 2C 的啊,公司有多少前端的啊(本人可能还是太啰嗦)
最后问了一个问题,问了一下面试官本次便是的评价是啥,面试官只回了一句,还好吧。然后面试到此结束了,全称大概一个多小时。

面试结束后,面试官送我到电梯口。。。可以说楼层是真的高,上楼和下楼都需要等很久的电梯。。。到了外面之后,下着大雨,落汤鸡似的又打了个滴滴回家,结束了当天的面试之旅。
最后
直到昨天,收到了有赞的面试结果回复邮件,告知没有合适的职位(有赞还是挺不错的,没通过面试还通知一下),心里虽然有点不甘,但是想想确实可能是自己不够优秀,或者是自己面得不是很好,或者是自己的能力跟公司的职位不太匹配。
在上一篇面试总结中一年半经验,百度、有赞、阿里面试总结,部分同学关心最后面试结果情况,情况是已经有幸的收到了百度的 offer,蚂蚁金服的一面面试已经过一周了,不知道是因为流程太长还是一面被挂了。
这个时候一想,其实面试还是有很大的运气成分在里面,正好公司需要,正好你又合适,这个时候就很幸运。

退出移动版