直立行走的猴子

猴子

我最近拿到了苏州一家美企大厂的 Offer。软件工程师职位,Senior级别,年薪相比前一份工作上涨了超过 50%。

拿到Offer之前,我是在一家芯片设计公司工作了八年的“高级”嵌入式软件工程师,是公司的“技术骨干”。但我一直没发现,其实,自己一直只是一只猴子而已。

我会熟练的使用Tmux + Vim,是那种老鸟级别的,一个terminal分割成七八个豆腐块来用,全键盘操作。但是,直到一年多前,我才逐渐会写“Quick Sort”。

我会写 Linux Driver,了解软硬中断机制,偶尔还能反汇编定位一下 Kernel Panic;几本领域内的英文 Standard 也看得烂熟。但是,直到一年多前,我才知道什么是“Heap”。

我的 C++ 基础还不错,懂得虚表结构,甚至还会写递归template;大部分C++17语言特性也能熟练使用。但是,直到一年多前,我才知道经过Heap优化的Dijstra算法的时间复杂度是O(ElogE)。

我想说,十年来,在软件这个行业,我洋洋得意的把弄着各式新奇玩具;但全然不知,自己其实就只是一只猴子,连“直立行走”都没有学会!

可能,你也和之前的我一样?

算法,算个毛?

算法,起初,于我而言,只是进大厂的工具。这么看,没毛病,至少让我有了开始学习的动力。

力扣,华人内卷大法席卷全球的例证,起初,对我而言,也只是为了进大厂的工具。但它为我开启了一扇门。

刷题一年多,实不相瞒,最大的动力,就是大厂那诱人的薪资。刷了700多道题,也勉强算是补上了一些短板。同时,我逐渐后背发凉的体会到:我,一名不懂算法的软件工程师,之所以能在这个行业混到饭吃,只是因为,这行业在国内,尚未进入到淘汰“落后产能”的阶段。

总有人说起,“算法有毛用啊,工作那么些年,见哪个问题非得靠什么算法才能解决的呢?面试造飞机,工作拧螺丝嘛!”

这话听起来有道理,细想,就如同下面这话一样可笑,”扎马步有毛用啊,打群架这么些年,见哪次干架是靠扎马步赢的?趁其不备,脑袋后面来一板砖儿才是王道!“

但是,殊不知,若不从马步扎起,这武林,就没有你的一席之地;你,最多就是个会打黑拳的街头混混。

你,只想当个街头混混嘛?你,是否也是即将被淘汰的“落后产能”?

进大厂,要准备啥

刷题,是显而易见的,后面详谈。先谈一些别的。

简历

精心准备简历,非常重要。我修改简历的时间,加起来,应该超过80个小时(,建议准备简历,要至少花40个小时)。字斟句酌,反复删减修改,最终留下的,都是最重要的。

如果去的是外企,英文简历的打磨也不是闹的。写简历的几条经验:

  • 一页A4纸,十年内工作经验,不论你做的事多么牛,都是一页。当然,你可以调节页边距、行距,充分利用这一页纸的空间。
  • 简明扼要,突出重点,狭窄专业领域内的术语出现频率不要过高,尽量使用行业通识性词汇
  • 针对应聘岗位调整简历内容描述侧重点,以及不同项目经历的排列顺序
  • 写在简历上的所有技术相关的内容,必须要烂熟,不能被问到时说不清楚,会让人对你的诚信产生质疑。
  • 使用我这里用到的特定词语加粗的方式,让面试官在没时间看完每个字的情况下,也能抓住重点

面试

这不是仅仅指做算法题。技术面试,除了做题以外,一般会聊你做过的项目,之前的工作内容,兴趣;如果遇到工作经验较长的面试者,可能还会考察“系统设计”的问题。

自我介绍

这部分有的大厂会要求使用英文,基本上可以提前准备,可以包含教育背景,工作经历简介。建议反复练习,保证简洁、流畅,控制在1分钟内。

介绍项目经历

介绍你之前工作中的某些成果的时候,要尽量简洁易懂。因为,面试官可能没有做过相关领域,你需要短时间内将你所做的事情清晰的告诉面试官。一般的套路是:问题是什么,我做了什么事情,达成了什么效果

有的放矢

要重点介绍你认为最能证明你符合该岗位需求的工作、项目经历,业余兴趣也行。

例如,我这次面试的岗位是云计算硬件相关的。但我没有相关的工作经历。我就介绍说:“我业余时间是一位服务器相关软硬件技术的爱好者,我自己购买了一些二手的服务器硬件,搭建了一台 Dual XEON E5 2696v2/64GB DDR3 REG ECC/ZFS RAID的 Proxmox Server。喜欢捣鼓虚机,也了解 Docker/Container,但对LXC还不太熟悉。”

具体而微

通过具体的说明,引导面试官提问,尽量不要让面试官太自由发散。

比如,“我会写Linux Driver”这个描述就不好,“我曾经对某某Linux Driver的软中断处理做过某某优化”就好一些。因为针对第一个描述,如果紧接着面试官说:“那请你写一个Linux Driver中字符设备的 ioctl 的实现框架吧”,你也没处儿说理去。因为,是你给了他一个无限大的提问空间。

算法题

一般大厂的面试会有多轮(,我去的这家有五轮面试,每轮一个小时,第一轮面试官是高级工程师,第二到四轮的面试官一般是Team Manager,第五轮的面试官是大部门主管),每一轮都会考察算法题。算法题有多难;是考察一道还是两道;在整场面试过程中,留多少比例的时间来让你做题,这些问题没有统一的答案,面试官不同,大厂不同,差别可能会很大。

但也有一些规律可循。比如:

  • 现在一般是远程面试,面试官一般会通过浏览器和你共享一个在线编辑器,或者会通过在线会议工具(,Zoom,teams)共享桌面。如果是要求你共享桌面的话,很可能会要求你自己编译代码,编写测试用例,最终执行确认结果;如果有问题,需要现场debug。我这次的五轮面试,都是用共享桌面的形式进行的。
  • 一道简单级别的题目,应当在10分钟内解决(,从面试官口述题目开始计时),一道中等入门级别的题目,应当在30分钟内解决(,最好是在20分钟内)
  • 如果只考察一道题目,一般会至少留30分钟时间,难度至少是中等入门级别,不太可能是简单题。我的最后一轮面试比较特别,只留了10分钟给我,一道中等题;前面的面试都符合这个规律。
  • 如果考察两道题目,一般项目的部分聊天的时间会减少,留出至少40分钟时间。可能是一道简单题,加一道中等题;也可能因为你做第一道中等题非常快,面试官再加试一道中等题。
系统设计

我并没有互联网行业的从业经验,对于互联网相关的领域内知识几乎一无所知。所以,这一块,其实我是比较弱的。

面试准备的过程中,基本上只是准备一些通识性质的知识。包括:

  • 跨进程通信机制,共享内存,Linux常用命令行,网络基础等
  • 阅读《程序员面试金典》第11章“进阶话题”,阅读《编程珠玑》
  • 观看YouTube上一些关于系统面试的教学视频,阅读网络上一些关于常见系统设计题目的分析文章。
  • 学习《极客时间》上的《性能调优应知应会》课程 (此课程仅作为一些知识点的入口,相关知识点的深入了解需要另外自己学习)

行为面试问题

大厂面试一般有多轮,以我为例,一共面试了5轮。“行为面试问题”可能会在任何一轮面试中出现。在面试准备过程中,这是非常容易被忽视的一个方面。

所谓“行为面试问题”,举几个例子就能明白:

  • 请举例说明一件令你最自豪的事情
  • 如果你和你的同事/上级发生了意见冲突,你一般如何解决?
  • 你为什么想要离职?
  • 你为什么觉得自己能够胜任你要应聘的这个岗位?
  • 你有什么问题要问我吗?(对,这也是一道行为面试题!)

行为面试在youtube上有一些相关的教学视频,看一看会有好处。此处不多谈,要细谈会是另一篇完整的文章。只说三点:

  1. 应对行为面试问题的最重要一点:迅速意识到这个问题是一个行为面试问题。因为“行为面试问题”常常在技术面试中穿插在技术问题中出现,所以,如果没有经过一定的训练,不一定能够迅速识别出来;而如果你没有识别出这是一个“行为面试问题”,则已经落了下风。
  2. 行为面试问题没有一般没有唯一正确答案,需要针对你所应聘的岗位和公司来设计你的回答。
  3. 上网查找常见的行为面试问题,并参照其它更专业的文章、视频学习后,对这些问题打下自己的腹稿。

英语

英语是去外企大厂高概率会考察的内容,如果你应聘的部门和国外总部有密切的工作往来,则要求会更高。

这里,我先只给两条关键建议

  • 听力,是英文听说读写四门功课之基础;走路听,通勤听,蹲坑听,睡前听,有奇效。
  • 能KeXue上网最好,天天听英文母语老外说,比英语学习软件效果更好(个人感受,仅供参考)

想纠正自己英语发音的,推荐 Rachel’s English 以及 youglish

另外,我个人的体会:英语能力再搭配上KeXue上网,对于技术学习会非常有帮助。

刷题!

作为一名35岁的程序员,家有小神兽,公司还经常要求加班,之前接触过的最复杂算法就是“冒泡排序”;刷题,对我来说,还是有点儿难度的。一路走来,我居然刷了15个月的题,总计题量700+。

分解下来,刷题,需要的是:决心和坚持,合理的方法。

决心和坚持

确认自己是否有决心:想清楚自己为什么要离职,这个原因要足够强,可以经得起时间的考验才行。

最初的两个月,你什么都不会,偶尔觉得学会了,很快会发现自己还是不会。加班回到家,9点半,疲惫不堪;打开力扣,可能每道题都在蹂躏你。如果你的决心不够强,你很快就会放弃。

坚持更重要,当审美疲劳出现的时候,你需要寻找适合自己的方式,让自己机械的坚持下来。坚持过一段段审美疲劳期,最终你才能够走到终点。

力扣的打卡题,寻找信得过的队友,俗气的鸡汤文,对未来的美好生活的畅想,等等,所有能让你坚持下去的力量,都要学会借助。

另外,在职刷题,周期很长,应届生的时间优势职场人是没有的。所以,比较好的心法是:“每2周设定一个目标,一点一点,稳稳走到终点”;否则,慢慢长路看不到头,很容易绝望。实不相瞒,我在刷题路上就曾放弃过7个月,幸而有好友鼓励,重拾了信仰。

合理的方法

刷题的方法有很多,我挑几条最重要的出来说。

看书刷题

书有两类,一类是专门针对面试的“速成秘籍”,另一类则是稳扎稳打的内功心法“。两种类型的书籍都有其作用和优势,准备面试的过程中,应当同时向这两类书籍借力。

招式

现在有很多公众号会提供题单,但最好的题单就是《程序员面试金典》和《剑指Offer 第二版》。刚开始刷题,这两本书里面的题,可以作为例题进行学习,边刷边看书。先做其中的简单、中等难度的题目。再搭配选择力扣主站的前200道经典题中的一部分,刷满200题,基本上,你已经见识过了面试中会考察到的算法的50%。

注意,一开始刷题,千万不要自己闷头想,想10分钟,没思路,就看书,看题解。学习,理解,消化。待到你做了100多题后,这个要求可以提高,你可以自己硬刚1个小时,看能不能想出来,想不出来,再看题解。

内功

另外,只有题单是不行的。我建议配合一两本教科书进行学习。《算法·第四版》和《算法导论》是不二选择。这两本书都有对应的视频课程。《算法·第四版》在Cousera上可以查到原作者上的公开课,《算法导论》在MIT的 OpenCourseWareYouTube 上都有视频。我更推荐《算法·第四版》,但《算法导论》的某些章节更经典,可以一本为主,一本为辅。我个人就是教科书配合视频来学习,先学完了Coursera上的《算法 Part1》,然后再跟着了MIT的《算法导论》视频课,学习了大概50%。

以面试应聘为目标,教科书可以不用一页一页看,挑选重点章节,逐字逐句从头到尾看。什么是重点章节呢?配合教学视频你自己就能体会到了。

按类型、频率刷题
按类型

同一类型的题目,集中做,类似于高中时,集中学一个单元的知识点,有很好的强化效果。缺点是:你已经被提示了解题的算法,所以,即便不看题解能自己写出来,也是降低了难度的结果。

前面提到的额《剑指Offer》和《程序员面试金典》两本书的章节安排就是将同一类型题目集中起来进行讲解的。所以,按照这两本书的章节顺序学习,就可以做到”按类型“刷题。

  • 举个栗子,假设你要刷”链表“类型的题。可以从力扣网站上将《程序员面试金典》中的链表类型题晒出来,自己先尝试做”简单“级别的。因为是第一次做,想5分钟没有思路,就可以看书中的解答和分析(在我写博客的这个时间点,即2021/12 ,来看,《剑指Offer》和《面试金典》书中的题解平均质量要高于力扣网站上同样题目的社区题解)。这些题目完成后,相当于学完了例题。然后可以再切换到到《剑指Offer》和力扣主站编号前200的题目,筛选出”链表“类型,继续做(,此时,可以提高一些要求,自己20分钟想不出来,才能看题解)。

最后还有一招,很多力扣题目下面会有一个“相似题目”的链接。做题的时候,可以将一道题目的所有“相似题目”顺手都做掉。

重视高频题

力扣会员可以看到出题频率。做高频题,不是为了面试押宝,而是因为这些题是经典。吃透这些题目,更容易做到能够举一反三。

初期刷题的类型:数组,链表,树,排序;同时,参考《剑指Offer》和《程序员面试金典》中的章节安排。
初期按频率刷:选前200题中的高频题

广度

常常有人问,刷多少力扣题目可以进大厂。

回答是:如果你是非计算机科班,算法几乎零基础,500题起步;如果计算机科班,学过算法,300题起步;然后再看你的悟性,如果平时你周围很少有人觉得你特别聪明,再加200题。如果你告诉我,有人刷了100题就进大厂了。我的回答是:你去试一下,就知道,你和他不一样。

深度

刷题的数量够了,并不能表示算法就过关了;因为,数量只能代表广度,深度不够,熟练度不够,技术面试该翻车还是翻车。

而且 欲速则不达。如果刻意追求数量,囫囵吞枣的结果只有一个:消化不良。

我建议的刷题速度:如果平均一天4小时的投入,中等题占一半或更高的比例,则平均一天最多4题;若超过这个数字,则大概率是没有吃透。

如何尽量吃透做过的题目呢?我用到的方式如下:

  • 看题解。对,这一条就这么简单,就是看题解。但要注意:即便这题你自己做出来了,没有运行,一次提交就AC了,你也要看题解!为什么呢?你看了题解就明白了! 看题解也有方法:

    • 一开始看,是逐字逐句看,顺着题解作者的思路去想。不过,这样看过之后,很容易出现“看懂了思路,但不明白这个思路是怎么想到的”的现象。所以,在累积了一定的题感后,看题解的方式就要变为“只看关键字”。具体的说,一道题目没有思路,打开题解,3秒钟扫一下,抓住几个关键字(或者只看一眼算法的名字),然后立即关闭题解,继续开始自己想。这样,当你想出来后,这个解题方法就有一半儿是真的属于你自己的。然后,再把自己想出来的方法和题解的方法对比,看你是不是还有一些细节处理得不够好,不够优化。
    • 要看官解的所有解法,这个原则适用于95%以上的题目,基本上,官解的每一种方法,即便不是复杂度不是最优的(暴力解除外),你也要看完,然后自己实现。
    • 要至少选一个点赞较高的社区题解看一下,不过社区题解的质量良莠不齐,这个就要自己拿捏一下了。
    • 学习代码实现。不仅要学题解的思路,还要通过对比自己的代码和题解的代码,提高自己的代码实现能力。
  • 一题多解,一题多刷。做任何一道题,至少写两种解法;即便此题全网只有一种解法,你也要尝试优代码实现方式,再写一次。很多经典题目,我写的解法可能会超过5种。而且,同一种解法,即便你学会了,隔一个月两个月,再做一次,对比之前的写法,你还会有新的收获。

  • 记笔记 + 复习,孔老夫子的“温故而知新”是大智慧

    • 我会用一个 excel 表格,记录下我每一题的收获,做题时间。对于这一次做感觉不是很顺的题目,会用黄色底色标记;感觉没有特别不顺,但不够熟练的,用蓝色底色标记;如果完全没思路,看完题解自己实现也磕磕巴巴,则用红色底色标记。后续复习的时候,看到颜色标记,就会知道要重点复习的题目是哪些了。
    • 每天睡觉前,看一下当天做的题目,在脑子里过一遍
    • 每隔一周,或者一周半,回头看之前做的题目,如果不能立即想到解题思路,则表示需要重做一次
    • 不要太频繁的复习,允许自己遗忘。何谓”太频繁“?一道题,你连续三天复习,每天都刷2、3遍,这就过头了。这样的方式,很容易让机械记忆替代”理解“,从而起到反效果。遗忘了一些之后再回头复习,往往效果更好。
  • 刷 leetcode book 的专题。刷专题会让你对某一类题型的认识在2~3周的时间内很快提升到一个新的 Level。不信?刷满200题后,从“DFS专题”开始。

  • 费曼学习法。了解费曼学习法的同学应该知道,其核心思想就是:将你认为学会的东西讲解给其它人听,在讲解的过程中,对自己进行查漏补缺。如果你有队友,可以尝试在自己理解了一种类型的题目之后,将心得告知队友。莫要担心被人偷学了技能;在教别人的过程中,获益最大的其实是你自己。你还可尝试自己出题,请队友解决。

熟练度

拳不离手
熟练度是基于对算法理解深度才能提升的;同时,也有所谓的“手感”。为了保持“手感”,刷题这件事情是不能中途暂停个几天的。如果要休息一下,一天可以,两天就要皱眉头了;若是三天,好吧,你这两周的功力基本要废去一半了。

切记:刷题如逆水行舟,不进则退!

掐表做题
做到什么程度可以算作”熟练“?我对于面试前的状态要求是:一道你做过的题目,中等入门难度,从看到题目,到用例全部通过,最多提交两次;第一次提交没过,要能够做到 不调试,不运行,通过肉眼看,找到问题点,总共用时不能超过10分钟。如果是一道你没有做过的中等入门难度题目,这个时间可以放宽到20分钟

所以,做题时自己掐表很重要,否则你磨磨蹭蹭搞出来了,这样对自己的“熟练度”是没有认知的。

刷题的编程语言

我推荐使用C++刷题。有C语言基础的,工作三五年的程序员,即便没有接触过C++,2个月上手,是没有问题的。一年下来,刷题、面试,应该都不会让人觉得水平有问题。

如果你还不能熟练使用C++,我想说:能够用业余时间迅速掌握一门语言,是一种能力的展现。如果你自觉没有这种能力,你可能还不太清楚自己的潜力。高数能学会,这玩意儿没什么难的。

用C++ 刷题的好处:

  • C++是一门包山包海的语言(面向过程,面向对象,泛型,Functional,什么都有),没有面试官会对一个能够使用C++写代码的人的语言功底有太多的质疑。
  • 使用C++17的语法和标准模板库,大部分题的代码基本可以做到和用Python写一样简洁。大部分题目不超过35行码就可以搞定;刷了700题,我遇到需要超过50行代码才能搞定的,应该一个手能数过来。代码行数越少,面试出错的可能性越小。
  • 使用C++可以做到和C一样Low Level,也能做到和Java/C#/Python一样High Level,可以应对更多的面试场景。
  • C++更适合用来参加力扣的周赛,而周赛,后面会说到,是为面试累积自信心的利器。

建议如果要从C切换到C++,首先要找一两本经典教课书来看,我首推《C++ Primer》(注意:没有Plus)和《A Tour of C++》。如果想更多了解C++17的语言特性,后者更推荐一点。

Meyers 的《Effective C++》系列也很不错,但建议至少有4个月的C++实操基础后再去看。

如果你会使用Python/Ruby/Lua/JS/TS 之类的脚本语言,那也是不错的,可以作为额外的亮点。但除非所面试岗位对这些语言有特别偏好,还是建议将C++/Java/C#/Go 这类语言作为第一语言:一场面试如果只有一道算法题,则用第一语言来实现,如果遇到两道题目,第二题可以换到其它语言。

不同阶段,合理分配精力

常常有人在刷题过程中会遇到一个困扰:如何合理分配有限的时间和精力?困难级别的题目,面试中被考察的概率极低,另有一些面试中较低频率出现的算法,要不要花时间学习?常常有人觉得一道困难题,要花2天时间搞懂,但收获并不大;或者学了很多算法,但面试考察的算法其实都很简单,知识点很局限,不会不亏了?

我的建议:前500题,不应太多考虑特定算法知识点被考察的频率;这个阶段,应该是地毯式扫除知识点盲区。数论题,学;概率题,学;KMP,Dijstra,Bellman Ford,都学!在此阶段,高频困难题,是需要做的。我700+的总题量,大概做了90+道困难题。

在经过一轮地毯式清查之后。基本上你已经没有“不知道自己不知道的”算法面试知识点了。然后,进入到下一个阶段(,直到面试前1个月),开始有侧重点的进行多轮的深化理解和巩固。但即便在此阶段,**“困难题”和“低频算法”依然可以作为训练你的思维肌肉力量的工具,不能放弃。**记住:刷题不是为了面试押宝,锻炼思维能力,遇到没做过的新题不慌,才是目标。

在面试前的1个月,可以进入另一个状态:“再度夯实基础!”这个阶段,针对你掌握的不够扎实的难题和低频算法,精力上进一步减少投入。90%的经历都用来关注最基础的简单、中等题目。让自己做这些难度级别的题目的熟练度进入到最佳状态。

模拟面试,周赛

未来章节

面试过程回顾

如何谈薪资

离职注意事项

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值