摘要:IBM软件工程师、百度软件工程师、刷题5年的算法热爱者左程云分享算法学习之道:先找到线团,然后进入线团里学着怎么玩,但为了进入线团需要先把基础知识掌握好。唯一需要注意的是,一定要写代码,光看没有用的。
左程云,华中科技大学本科(计算机科学与技术)、芝加哥大学硕士(计算机科学)。IBM软件工程师,百度工程师,GrowingIO工程师、刷题5年的算法热爱者。2014年起专职做程序员算法和数据结构培训、代码面试培训、刷题交流等相关工作。
《程序员代码面试指南--IT名企算法与数据结构题目最优解》 作者,书籍涉及算法与数据结构编程题目240道以上,并且个人实现出最优解,大部分题目为面试高频。
以下为采访正文
CSDN:请简单介绍下您和目前所从事的工作。
左程云:之前在IBM和百度工作,为了写书从百度辞职了一年,这期间在线下开办了50多次算法交流活动,线上讲了20多次直播课。最主要的目的是通过学员反馈找到每个题怎么讲才好理解,然后把好的解释写进书里。写书期间非常累,但是现在终于出版了,目前刚刚闲下来,出去旅游了一下放松了心情。目前刚刚投入到工作状态中,在GrowingIO做后端工程师。
CSDN:在算法方面,您是如何和学习成长的?
左程云:本科在华中科技大学计算机学院,这一期间能在学业上让自己满意的可能就是没有挂科而已。硕士在芝加哥大学,出国之前就了解到想要在国外找工作的话,面试时几乎只考算法和数据结构的题目,于是开始了刷题,也就是搜集这方面的题,并且代码实现出来。 就这样从2010年到今天,刷了5年算法和数据结构的面试题。刚开始其实只是为了找工作才开始刷题,但是半年之后就上瘾了,根本停不下来。 最开始是把能找到的所有这方面的书全部看懂,并且实现了好几遍,然后开始刷LeetCode和CareerCup这两个网站上的题,去网上搜各种各样的分析文章,总之是把一切有关代码面试的东西都搜来学习。其实并不是一夜之间变得这么勤奋的,完全是因为学费很贵,一门课的学费高达5000美金,也就是听一个小时的课,差不多650元人民币就没了。这件事情对我来说很刺激,觉得不好好学习真的没脸活下去,当时就是这么极端的想法。因为钱的刺激,我一年内走出校园的次数都屈指可数,用了大量的时间好好刷题。
刚开始代码实现算法和数据结构的题目真的非常痛苦,因为这部分的内容相比其他方面的知识绝对算高门槛,而我最开始的基础也并不好。现在我经常在网上给同学们讲题,看到同学们表达的抱怨,那简直就是当年的我。这是一个脱胎换骨的过程,但好在会迅速上瘾,坚持半年之后就能一直坚持下去了。
算法和数据结构问题的技术累积非常需要长期坚持,因为内容又多又杂。如果大家看一下每年大公司的算法和数据结构面试题,就可以了解到这个特点。刚开始准备的时候,肯定是先把书本上基础的内容熟练掌握,把时间复杂度和空间复杂度的基础分析方法熟练掌握。把基础打实之后,接下来我技术累积的路线就是所有坑全跳进去,掉到坑里还不愿轻易出来,还在坑里打滚,哈哈,这和我的性格有关,就是很难听人劝。一直分析到筋疲力尽,终于明白自己的方法就是不如书上的或网上的,然后还要想很久这个更好的方法实质上到底是什么。每一道题基本上都是这样做的,总之就是进步非常缓慢,但好处是学的坚实。差不多代码实现到200题的时候,感觉自己有了很好的感觉。这里要对大家有一个提醒, 刷完一道题其实是一件很难的事情,因为普通解法很容易,但是最优解真得去耐着性子研究好久,去查资料,去做优化,这个过程很漫长。 刷题圈流行一句话,“刷200道题之后,再无庸手”,说的就是用必须找到最优解的心态去刷200道题之后,进步真的非常大。我就这样折腾了好几年,每天都刷题,每天都想解法,最后终于发现没啥新鲜的面试题了。最近觉得有意思的题,都是ACM竞赛题,这里就不再介绍这方面的内容了,因为与准备代码面试的同学离得比较远。在刷题这么长的时间中,代码实现能力和对经典算法的学习是共同进步的。
CSDN:不久前您出版了《程序员代码面试指南》一书,为什么写这本书?写书一种怎样的体验?有哪些心得和体会可分享?
左程云:其实现在拿到自己写出来的书,还是挺震撼的,没想到能写成,还能写这么多。其实就是有一天我看到自己刷题的文件,好多啊,不出书似乎有点难受了,于是就开始写。 当时在百度,平时工作很多,为了写书常常熬夜,后来真的吃不消了,就辞了工作,专心把书写出来。 期间还有一个很大的变化,就是开始办一些算法交流班,因为会做题和能把解法讲清楚之间差别很大。所以我就给刚开始准备面试的人讲很多题,这也是我对这本书最自信的地方,因为在很多同学的反馈中,我修炼了自己的表达,怎么讲最好懂,怎么举例子最能说明问题,在办算法交流班的过程中我也学到了很多,教学相长的感觉很不错。写书期间办了60多次讲座,把想写进书里的题全讲了一遍,然后根据反馈来写书,就是这么过来的。我觉得这本书最大的特点是题目很全,涉及的代码技巧也很多,最关键的是解释清楚,难懂的地方都举了例子。这里要感谢李旷世先生和牛客网CEO叶向宇先生,他们给我提供了很好的平台。
CSDN:您这本书最大的特色是什么?
左程云:题目非常多,基本上把近些年IT企业的高频代码面试题目一网打尽了。但让我最自信的是对实现的技巧介绍非常全,直到今天我依然会关注新出现的代码面试题,但发现解法的原型几乎都跑不出我这本书的范围。另外就是 所有的解法都有完整的Java实现 。
CSDN:您这本书是介绍面试中遇到的算法和数据结构的高频题,及其解法。请问以面试为目的算法学习和我们正常理解的算法学习有什么区别和联系?
左程云:在网络上流行一句话:算法分三种,竞赛的算法、面试的算法、算法。虽然我觉得这么分非常让人无语,但其实可以去这么理解,因为竞赛、面试和纯理论的要求和限制是不同的,所以算法在不同的要求中展现了不同的样子。
对于竞赛来说,每道题对输入参数和样本量的要求都是非常明确的,同时规定的非常明确的还有空间的限 制和运行时间的限制。
而对于面试来说,限制往往并不明确,造成这个现象的原因也很好理解。竞赛中当然是分数最重要。在面试的过程中,与面试官的交流和体现 自己想事情的方式、体现自己逻辑的严密更重要。所以同一道题,在竞赛中必须写清楚限制,而在面试中一道题刚开始的限制没那么多,目的就是缩短你理解题目的时间,让面试者先写出一点什么,然后和面试官展开讨论,随着讨论的深入,再逐渐的把限制加上去。总之在面试的场合就是想看看你想问题的习惯、轨迹以及表达 能力是否符合要求。
当然,不管是什么要求下的算法,经常练习算法和数据结构题目对一个人在逻辑上的提升都是显而易见的,在学校参加ACM并取得很好成绩的同学,如果不是表达能力特别差的话,是一定会收获很多offer的,因为思维被锻炼的很好。
CSDN:您在面试这块有很深的实践积累,大小互联网公司有什么不同?以及国内外的互联网在算法面试这块有着怎样的区别?
左程云:面试题不光有算法和数据结构题目,但是其他类型的题目都很好准备,记住了,理解了,就不会忘。比如,系统、数据库、网络、编程语言等等吧,都具备这样的特点。而算法和数据结构题目真的需要好好写代码才能掌握, 所以我建议大家准备面试的时候,抽出20%的时间去理解和记忆非算法和数据结构的题目,剩下的时间就是去刷题 。
一般来讲,工资高的公司在面试时算法和数据结构题目的比重较大,工资一般的公司比重较小。当然同样公司的不同岗位,要求也会不同,但总体趋势就是 国内好公司爱考算法和数据结构 。这是目前国内互联网公司的情况。国外的互联网公司几乎只考算法和数据结构,早个8年前就是这样了,一直如此。我相信国内会逐渐变得像国外一样,并不是崇洋***,而是算法和数据结构题目真的能考出东西。
算法面试的特点就是没有特点,什么样的题都可能遇到,因为根本没有考纲,面试官就是普通的程序员,他们在工作中或者在网络上遇到什么题不错,就可能考。所以我这本书写了530页嘛,因为内容太多了,这不是一个标准考试,这是能力考试。
CSDN:怎么看待IT企业在招聘要求中,对算法和数据结构的要求越来越高这个事实。
左程云:其实在很多年前,美国的那些知名IT企业在招聘的时候就已经不怎么考除了算法和数据结构之外的东西了。可能是觉得这样能选出聪明的人吧。但我觉得只考算法和数据结构的东西也不健康,就像练功一样,内功和外功同样重要。
CSDN:对于刚开始准备代码面试的同学,有哪些提醒。
左程云:别觉得辛苦,越练会越上瘾的,而且那真的很有营养也很精彩。
CSDN:算法学习是一条并不简单的路,对于-1~3岁的从事算法相关职业的人或那些对算法感兴趣者,算法学习你有什么经验可分享?以及学习时应该注意什么?
左程云:先找到线团,然后进入线团里学着怎么玩。为了进入线团,需要先把基础知识掌握好,然后有一些很经典的书可以迅速让你进入状态,比如我这本《程序员代码面试指南》,还有《剑指offer》(请参见作者访谈—— 专访何海涛:“不正经”程序员的进阶之路)和《程序员面试金典》(《cracking the coding interview》中文版)这些好书。我不建议刚开始刷题的人就直接在网络上搜集文章开始学习,因为太散了,而且需要花很多时间去鉴别正确与否。当这些内容都掌握之后,再开始在网上搜集各种各样的题,并与网友参加各种各样的讨论,会比较高效。把底子打好之后,对于专项算法的学习就得心应手了,而且会学的很快。 对于很庞大的算法,我个人的习惯是找例子来引导自己的思路,一点一点的接近算法的核心。唯一需要注意的是,一定要写代码,光看没有用的。
- 对于某一个具体的算法,首先要搞清楚这个算法解决的问题是什么,可能是实现一个具体的功能,也可能是在某些方面,比如时间复杂度或者空间复杂度方面很卓越,总之搞清楚这个算法被研究出来的目的是什么。
- 然后就要弄清楚这个算法的生存环境了,也就是看看你此时研究的东西是不是对别的知识有依赖,应该先把底层依赖的知识理解并掌握。这些问题都解决之后,就进入到算法本身的学习,理解一个算法是一件辛苦的事情,刚开始看必然会产生很多的困惑,比如经常会怀疑作者讲述的内容的重要性?这些内容和这个算法有什么联系呢?经常会有这种摸不着头脑的感觉,其实作者做的铺垫都是为了建立起描述算法主要内容的基础,只有接受和理解这些基础,才能逐渐触碰到算法的精髓,所以耐心是很重要的。
- 算法的主要过程看完之后,往往还是会感到困惑,主要是不知道这个过程好在哪,这就进入了下一个阶段,理解作者对这个过程在功能性或者效率卓越这件事上的解释和证明。这才真正触碰到算法最精髓的部分,也就是深度的理解算法的主要过程所带来的好处,这才是最锻炼人理解能力的地方。
- 上面几点是算法学习阶段的过程了,接下来就是研究算法的代码实现,自己设计测试用例亲自跑一下代码,以及从代码运行时间的角度分析这个算法的优势,这也是加深对算法的理解的过程。
- 最后是配合相应的题目练习,让自己通过题目练习的方式,会用、善用学习到的算法,并对这个算法产生一定的敏感程度,具体是指看到某些题目时,能够根据题目的特点,产生与该算法的对应,也就是具备举一反三的能力。
CSDN:您是如何走上编程之路的?以及写代码如何与算法高效的结合?常用的语言是?
左程云:因为本科和硕士阶段都是计算机专业,所以走上编程之路的过程是非常自然的,但我真正享受编程的过程是在开始做算法和数据结构的题目之后,牛人们写出来的东西怎么就是比我快呢?所以开始研究起来,并越来越痴迷。程序=算法+数据结构,所以不存在结合的问题。常用的语言是Java。
CSDN:你是否在工作或生活中发现其他让您印象深刻的算法?以及研究算法,对您的工作和生活有什么收获?
左程云:很多算法对我的影响都很大,从开始时的很基础的排序算法,到后来看到的BFPRT、KMP、Manacher、蓄水池采样、skew、Morris遍历等等等等先贤们的成果,震撼我的次数已经数不清了。对自己的头脑变得越来越自信,这是最大的收获。