gitbook/业务开发算法50讲/docs/482844.md
2022-09-03 22:05:03 +08:00

134 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 特别策划面试BAT面试三关准备方法大揭秘
你好,我是微扰君。
春节将近,从今天起我们就不学习新算法了,轻松一点来聊一聊大厂算法面试该怎么准备更高效。
毕竟来极客时间学习很多同学可能都有一个相同目的想要通过自我提升拿到大厂Offer想要进大厂首先我们一定要过的就是算法面试。算法面试怎么过呢来得最快、效果也相当不错的方法当然就是刷题了。
因为我自己本科也不是计算机科班出身,第一份工作是做前端,但工作内容并没有给到很好的技术基础,对我后期的技术成长不是特别有利,加上自己又比较想去做一些偏基础架构的工作,我下定决心准备尽早跳槽到偏基础设施的岗位了。今天就来和你一起分享一下我的一些面试心得。
对于工作经验比较浅的同学,**大厂面试核心考察的就是你的潜力,主要就三关:算法、计算机基础知识、领域知识**,领域知识这块通常会和项目经验一起考察。
这里项目经历、领域知识和计算机基础知识,都需要较长时间的积累,我们短期能操作且一定能有效提升的就是算法面试。
我2020年筹备跳槽1月份春节的时候就开始疯狂刷题差不多两个月做了400道题提交最多的一次是就出现在大年初一那天我从早上做题做到晚上差不多AC了37道题。因为算法面试关技巧都是辅助的核心就是得下定决心坚持刷如果你真的能像我当时这样刷题想过大厂的面试关还是比较容易的。
不过刷题当然也是有窍门的,今天也整理了我自己的算法面试筹备经验,希望能对你有启发。
## 面试如何刷算法题
既然目的非常清晰,就是为了过算法面试关。首先要搞清楚大厂面试大概的能力要求是什么样的。
我自己的经验是,**如果你打力扣的周赛rating差不多能到1850分大厂面试就比较稳了**。基本面试三家就能拿到两家的offer另一个没有拿到的可能也不是因为算法被刷有可能是经历被卡或者是八股文被卡。
另一个等价的标准力扣题目是分难度的easy、medium、hard**如果你做medium没有什么压力的话或者周赛能稳定输出3道题基本上就是可以过面试了**。
目标理解清楚再就要考虑投入时间了。我个人比较建议用23个月的时间集中高强度地刷算法题因为这段时间其实就相当于在边刷边复习密集地学习和复习知识会让你对知识掌握地更牢固也不太容易忘。在这两三个月中做250~400道题就可以基本达到目标了。
刷题也是有方法的,我自己总结自己的刷题过程,大概分为三个阶段,按照这个方法刷题准备的同学面试结果往往也都还不错。
### 第一阶段:分专题刷
刚开始比较建议先按专题刷有一本很好的入门书是《剑指offer》很多人应该都听过它有题目、题解和对应知识点书里也把题目分了类。你一开始做题的时候可能很多题目都没思路甚至题目都要读半天。当然面试的时候如果是这个表现那肯定是过不了的但是也不要气馁这说明自己提升的空间很大。
**一开始刷题千万不要死磕一个专题只需要刷10道左右就可以了**。拿到题目不会做可以直接去看答案差不多看两三道题你就对题目有基本思路了。10道做完基本上再看力扣medium的题虽然不一定正确起码是有思路能上手写一写了。
到这个程度,我们就可以开始第二阶段的训练了。
### 第二阶段:随机精刷
现在你就可以力扣随机刷题了不过这个阶段不建议先看答案一定要先自己多去思考。因为很多题目比如说medium它比简单题难的地方就在于有不止一个知识点每道题也有可能有不同的做法**我们需要把不同的做法和不同的知识点都掌握到位,找经典的题目认真研究精刷**。
另外这个阶段就可以开始打周赛了帮助你检验自己学习的程度。周赛题除了第一道是easy的后面两道一般是medium也会考察不止一个知识点。我们可以按照一定的策略去刷先易后难先做排序、字符串、搜索之类的简单题之后再挑战比较进阶的比如DP、并查集等专题或者做一些比较综合的题目。因为困难一些的题目往往涉及不只一个知识点通常也能有效复习到前面的题。
![图片](https://static001.geekbang.org/resource/image/5e/41/5eyy678bf2b00926fac6b944988a6741.jpg?wh=1920x1129)
学到这里差不多两个月也过去了,第三个月可以进入最后一个阶段。
### 第三阶段
现在估计你也形成打周赛的习惯了,可以再加一些随机赛锻炼一下自己的临场发挥。力扣上有功能叫随机面试(当然也是要开会员的,能花小钱解决问题的,我们可以花钱解决),可以很好地模拟实际面试的过程,有时间限制所以会有压力。
这个阶段如果有题目做不出来,**一定要记得补题,把这道题高质量的题解看明白**,然后自己再把答案再写一遍,定期复习查漏补缺。
最后还有一个我自己准备面试的小trick当然也不见得每个人都认可你可以去试一试。因为我自己是从前端转基础架构对整个行情不是特别了解所以前期我有投一些公司其实我也不太可能会去投了一下就是想去体验真正面试的过程。收获也确实很多。
![图片](https://static001.geekbang.org/resource/image/11/40/11a4bc9983caa1cbc63f2ca04aa3a540.jpg?wh=1920x1145)
这就是我刷题的三个阶段,你可以参考。刷题其实最重要的是坚持,如果觉得自己执行力不够强,我也有两个方法,一是可以加一些社群大家互相帮助互相监督,二自然就是花钱了,极客时间算法训练营也不错,会有人专门监督你按进度学。
最基础、提升也最快的算法关解决,另外两个部分基础知识、项目经历同样也是需要准备起来的。
## 转岗如何准备基础知识
第一大问题是基础知识如何补充。
如果你不是科班出身针对八股文的面试关有两种办法一种就是你去看面经找一些类似《Java面试指南》这些比较浅显易懂的内容因为看完之后很快就可以背出来如果面试官问的不深你是真的可以答出来的。运气好自然就过了。
但是很显然这种快餐式的学习并不系统也不够深入,面试官如果多追问几个问题,很容易判断出来你是背的,还是真正对计算机基础知识、中间件、原理有自己的理解。
所以**如果你时间还比较充分,也对技术感兴趣,可以先从计算机基础知识补起,毕竟源码都是在建立在这些基础上的**比如为什么Kafka读写比较快这个问题肯定要对计算机体系结构和磁盘的工作原理有一定了解才能回答得出来。
因为我当时主要想要做分布式存储,对数据库比较感兴趣,整理了一些底层的学习资料也分享给你。
* CMU 15445讲数据库非常好的一门课里面讲了很多经典的paper。帮助你非常系统地梳理数据库发展的历史而且内容很新。
* CMU 15213可以打好计算机体系结构和操作系统的知识基础。CSAPP是这门课的指定教材。
* MIT 6.824,课程会带着你一起阅读许多经典的分布式领域的论文,了解大规模互联网应用会遇到哪些问题。
* DDIA被国外很多同学称为系统设计的圣经同样是能带你系统了解许多基础数据系统设计精髓的经典书籍。
* SICP能很好的帮助你了解编程语言底层原理。
这些课程能给到你非常扎实的基础知识积累了,面试是绰绰有余。
当然在学习的时候,**要有意识地深入思考和总结,虽然看起来一开始要投入更多时间,但长期看这一定是一条捷径**。
比如有的同学学快速排序可能过一道题背一背代码一个小时就掌握了但这个知识的深度是经不起工作考验的比如为什么复杂度是O(n\*logn)呢?快速选择法是什么你又知道吗?如果不知道的话,你可以去搜索了解一下哈,这里就不展开讲了。从我的经验来看,可以说只背题的人走的才是歪路。因为我不是科班出身,这一点之前没有深刻意识到,也确实走了弯路。
## 没有项目经历怎么办
项目经历是很多小厂同学头疼的事,毕竟平时的业务一般都在做增删改查。我当时是想转后端架构,但是自己工作是前端,项目上肯定是没有有优势了。怎么办?
**第一个方法就是自己写一些面试项目**。我当时写了一个玩具级别的工具类项目做分布式的缓存实现了一致性哈希、LRU缓存的功能。虽然是玩具级但是在没有什么工作内容可以讲的时候贴一个这样的项目面试官会觉得我比较努力另一方面项目里的一些东西我可以跟面试官聊一聊展示我对缓存设计的思考和想法。
当然现在这种项目也很多但是有总比没有强。网上一搜比如手把手教你实现一个RPC框架你完全可以按照教程来一遍。虽然在开源社区里这种项目是垃圾项目但起码是自己动手做过的面试官看到一般还是会对你比较认可。当然如果你工作中有相关项目肯定是更好了。
**另一个方法就是可以参加知名的开源项目**从熟悉的工作入手尝试做一些issue一旦你提交了PR开源社区里会有很多人来给你一些帮助只要你虚心请教一定要看提交的规范文档不要问一些愚蠢的问题什么叫愚蠢的问题谷歌上一搜就能搜到答案的问题就是这一类很多好的开源项目社区其实是很乐于帮助你的你甚至可以得到免费的指点。
## 大厂和算法
可能有同学一直很困惑,为什么大厂要考算法?很多人都会觉得算法在工作中并没有很多用武之地。实际不是的。
第一台计算机差不多应该是上个世纪40年代发明的是相当伟大的发明了把物理学上的很多知识运用到生活中解放生产力当时主要被用来做科学运算、密码破译然后六七十年代人们开始用计算机做一些伟大的事情比如登月探索星空探索宇宙。
这个时候最早期的一批程序员就出现了。他们用计算机处理了很多登月上的难题,比如说着陆、碰撞检测、导航系统设计等等,但是我们都知道那个时候的计算机性能其实很差,登月的阿波罗计划有一张非常有名的照片,一名女程序员和一摞齐人高的纸,那一摞纸就是阿波罗计划里面用到的源代码。
![图片](https://static001.geekbang.org/resource/image/96/7a/969d03cc06374584feba9479ba64ed7a.jpeg?wh=474x602)
当时的计算机内存就只有几KB在这种硬件条件下就需要极致压榨系统的性能数组能少开就少开能原地做的算法就一定要原地做空间复杂度可能比时间复杂度更重要总的来说怎么样写性能好就怎样写。所以程序员们的算法要求就特别高。
当然他们当时没有那么多复杂的依赖,也没有那么多抽象,很多问题都是通过比较暴力的方式,先把问题解决,也不会去管设计模式、让代码有多么的可读。但他们那时候发明的很多算法,包括早期的计算机网络、最短路算法等等,到现在都非常有用。
那现在算法要求比较高的程序员们在什么地方呢?**其实也是在需要更加注重性能的地方,以前是因为资源很有限,现在是因为并发量很大**。
一些互联网大厂虽然现在红利已经不在了但是毕竟积累的存量用户足够多服务器每天都是在面对海量的请求而且计算机毕竟受摩尔定律的约束你肯定希望在有限的内存里让它跑得更好。就比如基础的PyTorch或者中间件Kafka都是需要压榨性能的要么是因为IO的要求特别高要么是因为它本身要做的计算就非常复杂对于很复杂的计算来说即使现在的内存和硬件资源也不是很充足我们需要让它跑得尽量快。
在这些底层的东西里我们肯定也是需要用到算法的在大厂里相关的岗位就是基础架构的开发做数据库或者RPC服务框架之类。
当然我们更多的程序员是做普通的业务开发,日常练习算法除了能让思维更清晰敏捷、考虑问题更加全面之外,更重要的是,我们最终还是要依赖这些中间件的,一旦中间件出现问题就需要自己去定位去判断,这个时候就需要阅读相应源码,如果对源码里的算法不是很熟悉,你可能就会觉得源码这东西也太难啃了吧。
还有比如要做架构的选型肯定是不能只是去看网上的文章别人怎么说得自己更深入地去看、去使用这个中间件它到底快在什么地方比如用消息队列你是用Kafka、RocketMQ还是Pulsar它们之间到底有什么区别比如现在很多人就觉得Pulsar比Kafka性能更好为什么呢有些是架构上的变化也有很多是算法上的变化。
## 总结
如果你真的想在程序员这条路上走得更远,还是要想办法让自己在编程中找到自己的乐趣,无论是看业务发展突飞猛进,还是从技术实现自我的提升,找到自己的成就感。
我个人更喜欢在技术上做出成绩,所以如果你也是这样,可以研究偏中间件的系统、研究底层的算法、研究一些背后的机制,这些东西才是有技术价值也有技术乐趣的。当然这些背后我们一定要有好的计算机基础知识,也需要有好的算法和数据结构的基础知识。
![图片](https://static001.geekbang.org/resource/image/84/26/8419f1a73f215e2fcaea83bb2e61b226.jpg?wh=1920x1525)
### 聊一聊
今天就不设置课后作业了,欢迎你在留言区分享自己之前面试的有趣故事,我们一起聊一聊。
如果觉得这篇文章对你的面试准备有帮助的话,也欢迎转发给你的朋友。我们下节课见~