Leetcode 计划

前言

自己准备的 Leetcode 计划,我参考很多一亩三分地的帖子,这里直接放上自己的总结版本。作为给自己的提醒也是一个激励。

Leetcode 遍数

  1. 前 200 高频
  2. Tag 刷题 + cracking the coding interview
  3. Round 1 顺序扫题 ~ 600 题 In total
  4. Round 2 公司 Tag + 实习面试
  5. Round 3 顺序扫荡 + Weekly Contest

Leetcode 计划 General tips

看 Youtube 视频刷题,提高效率

一上来不是去刷题,而是先看看一些youtube的视频/论坛。找那种,会告诉你正统做法怎么做的,解题步骤,思路是什么。

看看别人怎样从暴力解,到OK解,再到最优解,并且完成 follow up。

千万不要看那种,一上来,就说【这题很简单我们直接写代码】的。

搜索的时候直接youtube / 谷歌 那道题的题号 + 题目。

选题

很多人一上来就先一直做easy的题。个人推荐做最frequent的题。按照freq排序做头200题足够了。做到后面见一题会一题。

一开始不建议按tag刷题,因为看着tag是two pointers、hash map 你心里就知道这题该用什么思路了。一开始就按照freq的排序混着做,自己去想思路。心里多总结。

给一个前两百题的,高频排列 LC-Frequency.xlsx

其他人的回答

每道题就算做出来了,也一定要看看讨论区的其他高分回到,一来我们还菜的时候想到的不一定是最优解,二则每一题多一些思路以后更加灵活。有时候follow up就是【这题你还有啥其他解法】。

题目里有【one-line solution】字样的新手可以不用点开了。

按tag精做

等到比较熟练了,(easy基本会,medium三成会)就开始按tag分类别做题,leetcode题目自带tag。

可以看着经典书籍cracking the coding interview做,不要被厚度吓到了,后大半本是题目的答案,前大半本有一定程度废话,千万不要被厚度吓到了。建议边看边刷。比如看完书上和hash table有关的,就去把hash table的题做了。

另外,这本书的作者,在youtube上是有视频的,有每个章节的内容的讲解。如果有需要,在github上有官方的,不同编程语言的版本cracking the coding interview。

按公司刷题

面具体公司的时候,去刷那个公司最freq的30题,中奖率是有的。这时候刷就不用真的去写了,看题然后看看自己心里有没有思路就行了。在leetcode/lintcode题库里就可以选具体公司。leetcode的explore还整理得蛮好的,它会具体到这题是谷歌的onsite还是phone还是campus。

心态上更多是看这个公司的出题喜好,而不是真的一定只要原题。

做题习惯

做题时养成笔头逻辑推理之后,再书写代码的习惯。一开始不要上来就写。

另外,平时养成开记事本写代码的习惯,不要依赖notebook/IDE。倒不是指不要依赖tab补全之类的,主要是不要依赖他们的纠错/报错。要做到记事本写代码一跑就bug free.

格式

不是科班出身的人经常不知道格式。

命名

函数、变量的命名规则要统一且规范。

另外,别人就算不看注释也能无障碍看懂代码。另外一定要写清楚这个函数/变量是什么。比如说,loop一个list的坐标点 ,新手就容易 for item in list_a ...,别人完全不知道item是啥,一定要 for point in point_list ... 诸如此类的别人看得懂的命名方式。

另外新手命名map/dic也容易瞎命名。某个dic,从A map 到B,这个dic 就可以命名为A_to_B, 诸如此类。

注释 + 查input

写注释: 函数开头要写注释,把type和变量是啥写清楚

    def two_sum(self, nums, target):
        """
        :type nums: List[int] - a list of numbers that ...
        :type target: int - the target number
        :rtype: List[int] - a list of two numbers that ...
        """

查input:查input是否合法等,然后报错/扔异常,问问面试官要求

面试的时候,十有八九,写一次面试官就意会你懂了,就会说“我知道你懂了,后面的函数可以不写了注释 + check input了。”

白板排版 划重点

面试时,拿到白板/白纸就画条竖线。 把功能明确的代码写成函数,尤其是会被复用的,左侧写非常简洁明了的主函数,右侧写def 要用到的其他函数。 比如一上来,左侧先写:

def find_route(map):
	find_neighours(...)
	...
	check_exit(...)
	...

整个左侧简洁明了,思路清晰,面试官一看就知道我要干嘛——

我想找路径
	找这个点的邻居哪个是路
	...
	查点是不是出口
	...

然后,右侧一上来先写:

def find_neighours(...):
	就这样空着
def check_exit(...):
	就这样空着

并不急于去写里面的东西。 等和面试官确认左侧展现的思路他/她认可了,再去补右侧的函数。

千万不要所有东西都堆在主函数里,看起来就是 ——

我想找路径
	看看这个点的上面
	看看这个点的左面
	看看这个点的右面
	看看这个点的下面
	...
	看看这个点的坐标
	这个坐标是不是地图边界
	...

让人看着很乱,面试官理解就要很久。

良好的排版,可以防止

  • 某个地方卡壳到最后都没说清楚整题思路
  • 代码太多太杂影响面试官看思路
  • 思路本来就错的,没提前沟通,写到后面没时间改。

99%的情况下,面试官不会让你真的把右边每个函数都写出来。他/她一般挑1-3个最重要的让我们写。无形中防止了,时间不够写不完代码。

画图讲思路

有时候题目非常复杂/非常绕,觉得讲不清楚就画图阐述思路。

真的不会

千万不要沉默,聊题,聊思路,面试官一定会给tips的。

如果面试官给完tips以后,你想到了另一个能work的思路,哪怕比面试官的更好,千万不要走,一定要按照面试官给的tips写完这题。不然面试官容易生气,觉得悟性不足。不要问我怎么知道的。

其他准备

内推

能内推就别网申。

小问题准备

除了大题,很多公司都会问一些小的tech问题。目的是看看熟练程度之类的。科班出身的人这些都是日常,很多人并不需要准备。但是零基础的人经常并没有实际操作过,是需要系统准备一下的。

去tutorial points看看会问什么小问题(如对比不同语言的gc之类, SVC 函数每个参数具体代表什么之类的)在tutorial points找interview question

https://www.tutorialspoint.com/java/java_interview_questions.htm

也可以直接谷歌搜”XX top interview questions” 。

我当时自己整理了700多个Q&A吧,很多都被问到了。

OS, database, git 与计算机网络

非CS本科的人学OS, database, git 与计算机网络是需要较长时间的。就算时间不足够也一定不能就此放弃还是要准备的。

首先,cracking the coding interview对应的部分看完。

另一个是搜”XX top interview questions”, 准备好每个领域最常问的问题,至少top 30问题心里有数。

最后,平时自己刷题的代码就用git管理,一举两得。

Argue

觉得自己表现没有问题,或者觉得面试官有问题,被刷了,可以去和HR argue的。有理有据的情况下,成功率不低。

比如,我谷歌一面argue成功因为面试官的英语我真的没有听懂。

Thank you letter + follow up

面试完之后立即发 Thank you letter,给HR和面试官都发。有个chrome的extension,叫 RocketReach,能找到非常多人的working email addr.

很久没回复就自己follow up 一下,客客气气地没关系的。

简历 & linkedin

CV + linkedin + cover letter一定要找外国人改。

CV改完挂上openCV, CVlibrary, monster等上。

Linkedin 和挂CV一定要搞好,全世界的猎头和HR都找你的,电话接到手软。

这期间千万不要漏接电话,说不定就是心仪的公司的。

注意背景调查

简历上每一笔经历,入职的时候,背景调查公司都是会细问入职时间和职位的。

所以,

  1. 没有人/银行流水/入职证明能证实的经历,尽量不写。虽然一般背景调查可以选择【我拒绝被调查这段经历】,但是尽量不要去试。
  2. 需要前雇主证明的话,提前打好招呼,客客气气地。
  3. 职位一定要写精确。笔者每段实习经历,都比较随意地填了software engineer,被背景调查公司要求书面说明,为什么他们调查结果,我的职位是intern,为什么和我写的software engineer不符合。令人非常焦虑。最后我现任雇主,出面表示不介意这个出入,背景调查公司才放过这个问题。

时间安排

申请的时候问清楚HR每一个环节要多久,做好时间上的安排,不要留下遗憾。是一个统筹安排的问题。不要因为心仪的公司申太迟而没法等待。

边面边学

初期可以申你本来就不想去的公司,不仅积累经验,有时候面试官人呢贼好,会手把手教你很多东西哦。

“来我考你一下…, 不会?” 掏出一个白板 “来,我教你哦…”

下面讲讲我找工作的具体过程。 我计划的面公司的顺序是这样的:

1, 几乎不想去的公司(Ebay, Walmart, Cisco, Pure Storage等等)。

2, 喜欢但是很远的公司(Uber, Lyft, Pinterest, Yelp, Salesforce, Twitter等等)。

3, 喜欢的公司(Microsoft, Apple, Tesla, PayPal等等)。

4, Dream Companies(Google, Facebook, LinkedIn, Amazon, Netflix等等)。

这样做的有很多优点,首先Dream Companies肯定是要面的,而且很好拿到面试,所以我可以在面之前拿其他公司练手。而且如果有了其他公司的offer也可以用来催它们或者谈total compensation。

刷题

刷题对找工作的帮助至少占90%,当你不知道该干什么的时候去刷题吧,一定不亏。 无论你基础如何,我强烈推荐Princeton Robert Sedgewick教授的Algorithms, Part I和Algorithms, Part II,好好听一遍受用终身。老人家的Slides整理得相当之好,他的code和证明也非常清晰。这两门课覆盖了大多数面试中会用到的算法,但最大的缺点是没有讲Dynamic Programming。 所以我推荐细读Introduction To Algorithms中关于Dynamic Programming的这一章,有时间的话建议通读全书。

还有一本必读的书是Cracking the Coding Interview,但我当时没看,有时间的话一定要看看。

学了这些之后基本你可以刷大部分题了,然后你每隔几天可以学习一下下面的算法: Floyd Cycle Detection, Boyer-Moore Voting Algorithm, Reservoir Sampling, Euler Path (Hierholzer’s algorithm), Binary indexed tree (Fenwick Tree), Segment Tree, Morris Tree Traversal 你刷的前两百道题可能会比较吃力,后面应该越刷越顺。

刷题方式大体分为兔派和龟派,我属于龟派。 兔派的方式大概是扫一遍题目,想个几分钟,如果做不出来马上看答案,看懂后自己Implement。

兔派的优点是速度快,效率高,适合记忆力比较强的人,适合面Facebook和LinkedIn等不怎么出新题的公司。

龟派的方式大概是尽量自己解题,即使耗掉半天也自己解,实在做不出来的情况下看看提示再自己解。 龟派的优点是锻炼思维能力,适合分析能力较强的人,适合面谷歌等只出新题的公司。

刷题时间:我建议白天刷题,原因是面试都是在白天,而且晚上刷题的话想不出来很痛苦…… 临近面试时建议:每天刷一两道新题,帮助活跃思维。刷高频题,刷自己经常写错的题,刷近期面经(请斟酌:面经有很多问题,比如没答案,比如题表达错误等等)。

系统设计

这个一开始大家一定很头大,其实还是有套路的。建议早点开始准备,学习好数据库。 一定要学一学Grokking the System Design Interview,最好再自己花钱上个补习班。

系统设计的书很少,目前最公认的是这本:Designing Data-Intensive Applications.

数据库

我认为数据库是除了算法之外对找工作最有用的一门课,占5%吧。如果实在没时间可以不看,我大部分转专业的朋友都完全不懂数据库,但是也都找到了理想的工作。如果真想学好数据库的话,至少要花两个月时间吧。

建议SQL和NoSQL每个掌握一样,比如MySQL和Cassandra。

数据库的书我推荐这本:Database System Concepts

Object Oriented Design & Design Patterns

传说是Amazon必考的内容,微软偶尔也考。如果你不面这两家可以不准备。

推荐书:

Design Patterns, Elements of Reusable Object-Oriented Software (终极参考书)

Head First Object-Oriented Analysis and Design (好理解的一本书)

Agile Principles Patterns and Practices (重点看S.O.L.I.D principles)

其他CS知识:

如果你时间真的超级充裕的话我还建议你学习以下内容:

Operating Systems,面SRE的时候很容易考到里面的知识。 推荐书:Operating Systems 龙书

Computer Networking,同样的,SRE容易被考。推荐书:Computer Networking - A Top-Down Approach (6th Edition)

简历

建议至少有三个软件相关的Projects:一个数据库,一个网站,一个其他(Big Data, Machine Learning, 游戏等等)。

简历是一个绝对头疼的东西,不管你的简历多好,挂在地里大家肯定能指出一大堆问题,而且说得不一定对。 如果你实在一个拿得出手的Project都没有,我有以下几点建议:

  1. udemy报一个Web development的课,肯定能出一个project.
  2. 报一个big data的班,能出两三个Hadoop的projects.. From 1point 3acres bbs
  3. 把自己工作时的东西“软件包装”。比如你平时的工作时技术支持,要记录用户的问题,那你就说你使用数据库来记录。当然我们不要骗人,最好真的自己搭一个数据库。再比如你平时做实验需要run三样东西,你就说你用script来run这些东西。同样的,建议你真的写script来试试run。 你一定要有一个自己特别了解的Project,面试时几乎100%会被问题,目的是考你是否能讲清楚一样东西,具体内容不重要。

Behavior Questions

这类问题最好回答也最难回答,主要考核你是否适合在他家工作。 What is your Biggest challenge? 想听的是你面对challenge和如何解决的能力。 最引以为豪的project是什么? 考你的沟通能力,看看你能不能通过画图和讲话把一个project说清楚。 如果在团队中你有不同意见会怎么办?如果他人针对你你会怎么办?想听你解决冲突和沟通能力,答案的关键词是沟通,沟通可以解决一切问题…… 有什么赶掉deadline或者几乎赶掉deadline的情况吗?怎么处理的?想听你的计划和抗压能力,答案的关键词是计划好,如果计划赶不上变化要赶快和经理以及相关人员沟通,然后每次update进度时通知这些人,开会时写meeting minutes并发给他们。 告诉我一个你之前manager给你的negative feedback。你犯过最大的错误是什么。这时候一定要回答一个真真正正的错误,他们主要想听你以后是如何改正或者避免的。

必问题:What questions do you want to ask me?

参考问题: A. What is the ratio of testers to developers to program managers? B. What brought you to this company? C. Why did the product choose to use the X protocol over the Y protocol? D. I’m very interested in scalability, and I’d love to learn more about it. What opportunities are there at this company to learn about this? E. I’m not familiar with technology X, but it sounds like a very interesting solution. Could you tell me more about how it works?

英语

英语也重要也不重要,平时练习一下给别人用英语把题讲清楚,对方能听明白就可以了。 有追求的朋友可以学习一下美音是如何发音的,很多单词的美音和英语差别很大。比如Herb, Watch等等。再有一些单词的读音可以注意一下,老美会故意吞音,比如Button, Manhattan等等。 还有重音要弄清楚,很多朋友连Project都读错了,作名词讲时重音是在前的。 另外,注意老美什么时候卷舌什么时候不卷舌,简单来讲是看单词里有没有R,比如Idea就不卷舌,Paper就卷舌。

Written on July 28, 2019