通过朋友内推有赞,经过电话面+技术面+hr面的完整面试流程,最终没有拿到offer,这儿给大家分享一下面试经验。
有赞的面试流程是内推流程过了后,会有电话面试的人跟你约你方便的时间。
以下是我在电话面试中遇到的一些问题:
电话面试还是比较喜欢基础好一些的候选人,跟我想的差不多,就结束了本次电话面试,整体过程还是挺好的。
电话面试2-3天左右很快就有了答复,告诉我通过了,约了复试,电话面试的小哥很负责,陆陆续续打了2个电话反复沟通。
这个问题我回答了好久,一边回忆一边说,因为当时配置好之后就全权交给运维去做了,后期维护的一些改变运维方面我没有及时去看,一直在看产出的报告,导致这个问题我答得磕磕巴巴的,面试之前千万千万要回顾并熟知每一个细节,否则就是给自己挖坑,下面是我面试时+面试后重新梳理的答案。
首先简单介绍了覆盖发布和非覆盖发布的区别
[id].[chunkhash].js
的形式,这样更新文件后,新文件不会影响旧文件的存在。覆盖式发布的缺点:
新页面里加载旧的资源
,页面和资源对应不上,会有页面混乱,还有执行会报错。旧的页面加载新资源
。无论如何,覆盖式发布都是能被用户感知到的,所以部分公司的发布是晚上上线
。其中如果使用vue-cli直接生成webpack配置打包的话,直接发布dist文件夹下资源就会产生这种特殊的替换问题,因为在build.js文件中存在这么一行代码,初衷应该是防止dist文件夹越来越大,但是rimraf模块会递归删除目录所有文件,没有详细了解过vue-cli生成编译环境的人,就默认的采用了这种旧资源删除新资源生成。
// build.js
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
...
})
然后发布的时候先将除html文件移动至发布路径,同名文件默认跳过,新生成的文件会产生新的hash,新旧文件不会冲突,共存在发布路径。
html文件的更新当时做了两种方案
因为node经验匮乏,当时第二种方案用了python写了一个服务,配置manifest.[chunkhash].js
及vendor.[chunkhash].js
,如果项目中存在首页骨架屏,那么还需要替换html文件body中的内容,用户服务进来后直接加载这个渲染后的页面。
分场景的话:
cdn的配置经验我比较少,公司的业务场景暂时没有提供cdn功能,所有的图片走的是七牛云的cdn,而服务器的css/js文件方面的cdn部署,没有相关的使用经验,面试回到家后一直在找相关的解决方案,如果你有比较好的科普性质的博文,欢迎在评论区留言。
可能前面的问题答得有些失误,为了缓和气氛问了这个问题。因为我之前一直做公司的web前端负责人,所以这个问题聊的比较迅速。我之前的公司是刚开始是没有前端的,我算是半路出家,公司从30人发展到500人,前端团队由2个人发展到接近10个人。然后说了下我主要负责的项目,以及一些团队协作,风险评估,需求评审,代码质量保证的一些事情,可能我做的工作有点low,TL的表情反馈有些平静。
这个看过一些,大概就是和缓存策略一样,需要在服务器进行配置,同时需要浏览器的支持。
http {
...
gzip on; // 开启gzip
gzip_min_length 1k; // 最小1k的文件才使用gzip
gzip_buffers 4 8k; // 代表以8k为单位,按照原始数据大小以8k为单位的4倍申请内存
gzip_comp_level 5; // 1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu)
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; // 支持的文件类型
gzip_disable "MSIE [1-6]\."; // IE6一下 Gzip支持的不好,故不实用gzip
...
}
服务器配置之后,会在浏览器请求接口后的response header的Content-Encoding字段看到gzip。
客户端请求数据时,请求头中有个Accept-Encoding声明浏览器支持的压缩方式,当客户端请求到服务端的时候,服务器解析请求头,如果客户端支持gzip压缩,响应时对请求的资源进行压缩并返回给客户端,浏览器按照自己的方式解析。
然后拓展问了下,如果传输的数据希望后端压缩,但是算法没有声明如何启用后端算法。我就模拟了下这个流程,客户端利用header头部的自定义字段将可以容忍的压缩算法告诉服务端,服务端配置允许发送这个自定义header,逐个匹配服务器上当前的算法,匹配到则发送成功结果,无法匹配则告知客服端数据无法进行压缩,等待接下来的操作。
算是一个解决方案的问题,面试官列举了一个有赞整点抢单的业务场景,如何同步所有客户端的时间。由于setTimeout类似的计时器无法高精度还原时间,我提出的想法是利用socket保持和服务器的长链接,利用推送的模式,定期给客户端发送当前服务器时间作为校验基准,但是由于HTTP传输的时间无法保证,所以也只能尽可能的同步两端的时间。
面试官又问了这个服务器推送的频率你认为大概需要多少,因为没有相关业务经验,只能按照逻辑推理,这个我的描述是当前服务器时间 = 服务器系统返回时间 + 网络传输时间 + 前端渲染时间 + 校准常量(可选)
,所以这个推送的频率采用变频的思路,就是离活动时间有一段时间,那么推送频率大概1分钟2次左右,马上快开始就需要频繁推送了,socket性能问题需要通过不断的矫正才能达到最好的效果,但是如果想100%实现高级度的计时器,以我目前的知识面看,还是存在很多问题的。
其实这个问题我在C++中就实践过,如果想测试超高级度的定时器,需要中间没有阻塞线程或者进程,以及防止计算机优先级较高的任务中断,这个知识涉及到操作系统的好多知识,大概就说到这。
对于这个问题我还是很感兴趣的,因为我面试后发现很多这种活动都有这个时间误差的问题,或大或小。如果你有过相关的业务场景,欢迎留言区分享你的思路。
技术面试过程的最后感觉自己可能没戏了,没想到还被问了一个现场编码的题目,大致题意如下:
Input:
'1024word'
' -1024word'
'word1024'
'10word24'
Output:
1024
-1024
0
10
程序大概写了不到5分钟吧,印象不是太深刻了,代码写的有点多。
function parseInt (value) {
// 输入值校验合法性
if (!value) { return 0; }
// 本需求对于空格需要剔除
let temp = value.toString().trim();
// 拦截全空字符串问题
if (temp.length === 0) {
return 0;
}
// 收集符号位
let result = temp[0] === '+' || temp[0] === '-' ? temp[0] : '';
// 设置开始索引
let i = result.length > 0 ? 1 : 0;
// 遍历,此处使用for循环为了方便中断遍历减少时间复杂度
for (;i < temp.length; i++) {
if (temp[i] >= '0' && temp[i] <= '9') {
result += temp[i]
} else {
break;
}
}
// [防爬虫标识-掘金-沙海听雨]
// 判断存在result为符号位造成Number('+')输出NaN问题
return result && (result === '+' || result === '-') ? 0 : Number(result)
}
问了能不能换种方法实现,我想了一下,说正则提取可以做到,但是当时就给了10分钟不到的时间,就没再继续了,其实是之前的问题把思路打乱了,一直在回忆之前没答好的问题。
下面是正则表达式的实现方法
// 方法一
function parseInt (val) {
if (typeof val !== 'string') { return 0; }
let match = val.toString().trim().match(/[+|-]{0,1}[0-9]*/g)[0];
if (!match) {
return 0;
}
return Number(match)
}
// 方法二
function parseInt (val) {
if (!val || typeof val !== 'string') { return 0; }
return +val.toString().replace(/^\s*([-+]?\d+)?.*$/, ($0, $1) => $1 || 0)
}
这个表达是里面用到的概念有点多,一直没有时间更新,其中几个关键点,在此处分析一下。
`^`以什么为开始
`\s`匹配任意的空白符
`*`只匹配出现 0 次及以上 \* 前的字符
`()`分组 `[]`匹配方括号内的任意字符
`?`之前字符可选
`\d`匹配数字
`+`只匹配出现 1 次及以上 + 前的字符`.`匹配任意字符除了换行符和回车符(贪婪匹配)
本来感觉结束了,整体单方面被虐,没想到TL说等一下,让hr来找我聊聊,有点意外,等了大概10分钟吧,hr小姐姐就过来进行人事面。
这个面试流程我就基本精炼一下:
我大学时期做ASP.Net,大学毕业第一份工作是C/C++嵌入式,后来又做了近一年的Django开发,最近两年才开始专一从事前端,所以这个聊的比较多,我觉得一个人能快速适应各种语言,算是一个优势吧,能侧面反应计算机基础,但另一方面广度过于宽会导致深度不够,这个我开始逐渐调整,由于掌握的语言比较多,所以上手很多技术还是很快的。
我的期许就是待遇上匹配的上时间成本,最重要的是想在一家规模比较大的企业做的久一些,沉淀一下业务能力和技术视野,大公司遇到的场景、并发、极端交互还是很令我向往的。
聊了下期许的薪资
我大概说了个数字,反正很诚心吧,有很大谈的余地,因为真的想跳出目前一直在小公司怪圈。
聊了整个面试流程感觉如何
说了合适的话会打电话沟通,不合适的话会发邮件通知原因
hr面试让我心里有些释怀,一扫之前技术面的紧张感,出门的时候如释重负吧,算是一个小阶段的结束,为了这个面试大概准备了1个多月,后来可能太紧张又是杭州梅雨季,回到家有些低烧,都是小插曲了。
最后的最后,等了大概一周多吧,还是没有消息,我对面试还是特别有诚意的,想等到结果再进行下一步,就问了内推我的朋友,得知面试被淘汰了,没接到正式婉拒通知有点小意外,可能各种原因,当个经历继续前行吧。
经历了完整的大企业面试算是对自己的一个自我认知的过程,虽然中间经历还是比较曲折的,但是算是成长吧,找工作还是有些吃力的,但是还是期待大公司的工作机会吧。
这位同学一共经历了2轮技术面和一轮HR面。
电话面的题都特别基础,相信大家只要好好准备下,问题都不大,这位同学也回答的比较好,进入了第二轮技术面。
但这位同学的第二轮技术面暴露的问题很多,特别是前端的代码发布方式这个问题,本来是很简单的一个题目,却花了大量的时间去和面试官沟通,而且面试官深入问细节时,答的又很糟糕。
建议大家在面试中遇到不熟悉的知识点时,千万不要磕磕绊绊的回答,直接告诉面试官自己知道哪些即可,不要浪费大家的时间。
“前端面试题宝典”经历接近一年的迭代打磨,目前已经提供了小程序刷题、PC端访问(https://fe.ecool.fun/)。
截至2022年3月24日,已经录入前端常见面试题800+,想刷前端面试题的小伙伴千万不要错过。
我们在近期推出了简历指导、模拟面试等增值服务,有想了解的小伙伴们可以添加小助手微信(interview-fe)进行咨询哦~
面经作者:沙海听雨
面经来源:https://juejin.cn/post/6844903890735857677