2021年的big surprise:与月影大佬的一次沟通机会

2,136 阅读10分钟

感恩掘金平台

今年2月底逛掘金博文,无意间看到 3 月闯关活动开启,等你来战!的活动,刚开始只想靠参加活动来督促自己每天学习进步,可没曾想居然能闯关成功,意外收获掘金周边大礼包,最终还幸运地被月影大佬选中,感受了一波字节跳动的面试。
这里由衷的感谢掘金平台,感谢勤劳的掘金运营童鞋和月影大佬,给予一次和大佬1v1交流的机会,开开眼界~~

闯关历程

任务1:刷题打卡

3月初,工作之余的时间开启了刷题打卡模式,坚持了每天刷一道leetcode,发布11篇解题思路的文章,其中有7篇被推荐上了首页。算法基础一直是我薄弱的地方,刷题打卡刚好可以督促自己每天练习一道算法题。

任务1闯关成功名单:🌻 刷题打卡、技术点评获奖名单公布 | 掘金寻人,Offer 临门

任务2:项目复盘

3月中旬,开始做项目复盘,输出了2篇文章,一篇项目优化实录,一篇造轮子学习记录,没想到在公司做的webpack编译优化实录荣获了项目复盘优秀文章奖,阅读量773,点赞46,评论7。自己刚开始尝试做技术优化,就得到这么多用户的认可,心里暗暗窃喜了许久。感谢用户的支持和认可,以后我会继续加油提升自己,在掘金社区输出干货满满的文章~~

任务2闯关成功名单:项目复盘任务获奖名单🏆 三月闯关继续!

任务3:沸点互动

3月下旬,终于不用发布文章啦,利用摸鱼时间每天发布条沸点,坚持5天就ok啦。

终极闯关成功名单: 💫 终极奖品揭晓,掘金 3 月春招闯关活动落幕!

导师1v1视频交流

通关后,21位童鞋都等待大佬们翻牌,很惊喜自己被月影大佬选中。2021-04-09 终于和月影大佬1v1视频见面啦,满心期待,但又特别紧张。本来之前还列个问题清单准备咨询大佬,可惜交流过程太紧张最后只咨询了个关键的。月影大佬特别nice,看我比较紧张,就先和我闲聊了几句家常,才慢慢进入面试环节。先来波月影大佬的个人简介,明星导师 介绍也可以看到: image.png 下面就是月影大佬问我的几个问题(个人信息和项目问题除外),大家可以参考看看:

1、最近你有在关注前端技术哪个方向?

回答: web性能优化的方向。

2、你在工作中有用到性能优化的知识吗?如何把性能优化的知识和业务项目联系起来呢?

回答: 工作中前端项目用到了webpack打包优化的知识。现在Vue、React、Angular前端三大主流框架基本都是使用webpack打包的。我们项目是使用vue+webpack的技术栈,业务代码堆砌的越来越庞杂,就想说做webpack的打包优化,提升项目构建速度。

3、webpack编译优化提升构建速度,具体是怎么做的,可以展开来说下吗?

回答: 刚开始,我先逛了各种博客论坛,看看webpack编译优化可以从哪些方面入手。多数技术博文都提到了webpack测速插件speed-measure-webpack-plugin,因此我便将该插件引入项目中,先用来检测每个项目编译构建的速度,看看到底是哪个loader、plugin耗时久。测速后,发现主要是搜索解析文件,将vue、es6语法、sass/scss/less文件转换成js、css的loader,以及压缩打包资源的plugin耗时比较久。发现问题后,就可以针对性地进行优化,主要采取如下措施:

  • 第三方依赖多,搜索解析文件慢:采用缓存策略,hard-source-webpack-plugin为依赖模块提供中间缓存,极大程度地提升二次构建速度。
  • loader解析转换慢:配置loader的test、include、exclude,缩小文件解析搜索范围。
  • 压缩打包资源plugin执行慢:比如uglify-webpack-plugin,可以开启缓存、多进程。

4、除了前端知识,有了解http这块的知识吗?比如缓存机制有了解过吗?

回答: 有了解一些。http的缓存有强缓存和协商缓存2种类型。浏览器的资源在Nginx代理服务器上可以配置cache-control:max-age=xxx 来触发强缓存。协商缓存,则是浏览器第二次访问资源,会和服务器端协商,如果缓存和新版本内容一致,直接返回缓存数据。

当时缓存机制回答不是太深入,下来后查阅了资料,补充学习了HTTP缓存机制及原理,整理成如下的时序图:

  • 强缓存的机制:
sequenceDiagram
    participant 客户端
    participant 缓存数据库
    客户端->> 缓存数据库: 1 请求数据
    缓存数据库-->>客户端: 1-2 有缓存数据,且未失效,返回数据
    缓存数据库-->>客户端: 2-2 缓存数据失效了
    客户端->>服务器: 2-3 请求数据
    服务器-->>客户端: 2-4 返回数据和缓存规则
    客户端->>缓存数据库: 2-5 将数据和缓存规则存入缓存数据库
  • 协商缓存的机制:
sequenceDiagram
    participant 客户端
    participant 缓存数据库
    客户端->> 缓存数据库: 1 获取缓存数据标识
    缓存数据库-->>客户端: 2 返回缓存数据标识
    客户端->>服务器: 3 请求服务器验证缓存标识对应的数据是否失效
    服务器-->>客户端: 4-1 通知客户端缓存未失效
    客户端->>缓存数据库: 5-1 获取缓存数据
    服务器-->>客户端: 4-2 返回新数据和缓存规则
    客户端->>缓存数据库: 5-2 将数据和缓存规则存入缓存数据库

5、强缓存和协商缓存的区别?

我的回答: 强缓存的状态码为200,协商缓存的状态码是304。强缓存header头有cache-control/Expires设置,协商缓存则通过Last-Modified/If-Modified-Since、Etag/If-None-Match标识。

大佬补充回答: 强缓存,缓存过的数据是从本地cache直接返回缓存数据,不会发起http请求;协商缓存则是会向服务端发起http请求,返回的数据只会有header,没有body的数据包。

6、有这样一个数组[-9,19,-1,11,2,8,3,7],要求配对相加为10,如何把这些配对元素找到呢?

我的回答: 暴力求解,通过2层遍历循环,遍历循环求解判断两数相加是否等于10,匹配到就返回配对元素。紧接着,我又提出了另外一个解法:先将数组元素存储成Map,接着遍历数组元素x,求解另外一个元素 10-x,通过Map搜索查找,匹配到就返回配对元素。

当时心想,我是不是踩坑啦,暴力求解,时间复杂度是O(n^2),而利用Map查询用匹配元素,虽然时间复杂度有所降低,但空间复杂度增加为O(n),都不是大佬想要听到的最优解。这会儿月影大佬看我思考的有些焦虑,然后很有耐心的一步步指引我思考进行解答。

大佬的解题思路: 现在的数据是无序的,可以先将数组排序(使用时间复杂度较小的排序算法),js的sort排序也还挺快的,时间复杂度是O(nlogn),排序后发现最小的数在最左边,最大的数在最右边,接着可以用二分查找配对,左边的数加右边的数判断是否等于10。如果大于10,右边的数向左寻找;小于10,左边的数向右寻找。二分查找的时间复杂度O(logn),综合起来解决这个问题的时间复杂度为O(nlogn),没有用到额外的数据空间,空间复杂度为O(1)。

下来后,我便去调研了下js的sort排序的V8源码底层实现,发现平时用sort方法性能如此优越,根据数据量匹配使用不同的排序算法:

  • 当 n<=10 时,采用插入排序;
  • 当 n>10 时,采用三路快速排序;
  • 10<n <=1000,采用中位数作为哨兵元素;
  • n>1000,每隔 200~215 个元素挑出一个元素,放到一个新数组中,然后对它排序,找到中间位置的数,以此作为中位数。 image.png 由上图分析对比这两个排序的时间复杂度来看,如果当 n 足够小的时候,最好的情况下,插入排序的时间复杂度为 O(n) 要优于快速排序的 O(nlogn),因此就解释了这里当 V8 实现 JS 数组排序算法时,数据量较小的时候会采用插入排序的原因了。当 n 足够大,使用快速排序明显优于插入排序。

7、有5个硬币,同时将这5个硬币抛起后落下,3个和3个以上硬币正面朝上的概率是多少?

我的回答: 在大佬的提示下,恍然大悟答道这是排列组合问题,5个硬币排列组合总共有2^=32种,3个和3个以上硬币正面朝上的组合可以套排列组合公式计算,C(n,m)=n!/m!(n-m)!。即为C(5,3)+C(5,4)+C(5,5)=5!/3!*2! + 5!/4!*1! + 5!/5!*0! = 10 + 5 + 1 = 16种。所以3个和3个以上硬币正面朝上的概率是 16/32 = 1/2。

大佬的解题思路:
思路1: 除了排列组合的方式,用js编程也是可以解决的。32种组合就可以将0~31分别转换成二进制,搜索找到有3个1和3个以上1的数,就是
思路2: 排列组合,还有这样的计算公式:C(n,m)=C(n,n-m)。C(5,3)=C(5,2),C(5,4)=C(5,1),C(5,5) = C(5,0),即为3个正面概率等于2个正面朝上概率,4个正面朝上概率等于1个正面朝上概率,5个正面朝上的概率和0个正面朝上(即5个反面朝上)的概率。求解3个及以上正面朝上的概率是不是刚好对半分了,即为1/2。

最后,面试的问题交流完后,月影大佬友善地询问:你还有什么问题想要了解的吗? 当时我就只记得问大佬一个心法问题:在解决问题的时候,您是怎么快速寻找到高效的解法? 大佬解答完,我们这次的模拟面试就结束啦,很愉快地say goodbye~

总结与思考

视频沟通下来,感觉和月影大佬交流如沐春风,他能很快发现我们身上的不足指点心法,也能发现我们的优点,给予鼓励和赞赏。今年通过掘金平台认识到月影大佬,是我最大的惊喜和收获(this is the biggest surprise~)
还有通过这次交流沟通,我发现大厂的大佬基本功特别扎实,抽象思维很好,综合能力很强。掘友们,无论是想跳槽进大厂,还是想提升技术升职加薪,平时还是得重视基础,训练多种解题思维,修炼好心法,才能让技术为业务产品创造价值。至于综合素质、软技能,主要还是靠自己职场上摸爬滚打,慢慢积累经验,不断提升,同时也应该多听听身边前辈们的建议。大家一起加油吧,干巴爹!!!

奖品丰盛

掘金每个活动准备的奖品特别多,这是我本次参加3月闯关活动获得的奖品: