教材的事就不说了,下面开始讲如何学习算法和数据结构。其实没啥好讲的,无非就找两本好书看看,然后自个在机器上敲敲,熟悉熟悉,技巧性的东西,多写写,跑跑代码,就差不多可以掌握了,没什么好说的。
最好呢,就是先找一个讲课水平高的老师,跟着上课,先听,把核心的东西先掌握,那就是算法思想,这个是最重要的,贯穿计算机科学的始终,这个不好好学,就会有问题。正好最近跟别人讨论过这个问题,就顺带说说我的看法。因为我发现一般培训班出来的人就对这个比较排斥,觉得非常非常难,这就是算法思想没掌握,底子没打好,培训班的课程毕竟是市场产物,肯定就比较短视,只教市场上最火热的框架、技术之类的东西,比如ssm框架,vue框架,gin框架之类的,看似学了一大堆技术,但说实话,都是花架子,这种东西学再多不过也就是apicaller,立不起来,5年经验跟1年经验没啥区别。
当一个人不了解一个东西的时候,就往往出现认知偏差,可能会把某个东西神化,比如说算法,他就会觉得这东西太高级了。这我就很疑惑:大学计算机系是个人都会的东西,哪里高级了?看不出来。一个工具而已,谁会觉得自己家里的铁锨和锄头高级?都是前人玩剩下的东西,非要给赋予一层神秘感,就很奇怪,总要把一个简单问题复杂化,这是很危险的,如果一个人在内心里将完成一件事的难度无限拔高,那么他很可能就无法完成那件事,毕竟未战先怯,兵家大忌,你都没有勇气去面对对手,那怎么可能战胜对手?(对,就把算法想象成一个对手)
那位网上认识的朋友,他觉得“算法这东西可不是谁都能搞的”。
我是这样回答他的:你非要这么说,那就没得说了,很简单东西,没必要复杂化,算法就是解决问题的能力,你以为是啥,为什么程序=算法+数据结构因为你是要解决具体的实际问题,不是说学什么屠龙术,这些问题很可能就是你经常遇到的,别人一看就知道咋回事,迅速解了,你还要cvsearch一波,这不是聪明,投机取巧从来都不是聪明,你cv了代码,看不懂代码是在干啥,说白了就是搬运工,没有技术含量的事,随便找个人都能替代掉,不敢提涨工资,因为你可能学了好多年这个啥都不会,啥都没学到,最后35岁光荣毕业,外卖骑手+1,所谓高级程序员低级程序员无非就是解决问题能力的高低,跟工作年限真没太大关系,不然为啥人家愿意招985211应届生,也不愿意招培训班出来的,要想,要多想,就说到这吧,一会又被群体而攻之就不好了,毕竟忠言逆耳。
为什么我会说“群体而攻之”,“忠言逆耳”这样的话,因为之前真的遇到过,就在同一个群,这个群吧,大概培训班的学生多一点,就是说基本都是学了一堆花架子,然后科班的那一套计算机科学的东西,如计算机组成原理,操作系统,编译原理,计算机网络,算法设计,数据结构,数据库系统原理之类的东西,他是一个都没学过,这就导致他底子很差,只能干quickstart,readme.md,cvsearch之类的活,干啥都是面向百度编程,面向CSDN编程,稍微玩点花活就把他难住了,比如说限流,这个不就是流控吗?你都不用看算法,学过计算机网络的,学过TCP协议的,能不知道滑动窗口?毕竟这么重要的东西呢。我直接把leetcode上的滑动窗口的题目扔给他,人家一脸懵逼。
所谓的“穷人思维”,就是说他走的每一步都非常短视,没有任何长远打算,走一步看一步,做事全凭运气,全靠个人有限的经验,这就很危险,就很容易最后无路可走,当一个人被眼前的东西所迷惑的时候,就很难走的更远,所谓“一叶障目”,“听了好多大道理,却还过不好这一生”说的就是这种人,他从来就没有认真审视过对方的观点,而是固执己见,认为只要跟他意见不同的就是故意跟他抬杠,就是他的敌人,就可以肆无忌惮的挑衅,敌视,辱骂,他们内心自卑又脆弱,听不得一点批评的意见,哪怕是最温和的批评,他也会认为你是在针对他,遇到问题全是别人的锅,跟自己一毛钱关系都没有,没有一点责任意识,年龄上虽然是成年人了,但是心理上跟小孩没啥区别,易怒、暴躁、软弱、自卑。算了,讨论算法学习,这扯到心理学是咋回事,就此打住。
之前一位老同学,搞运维的,跟我诉苦,说他们那系统单元测试没毛病,一串起来就出问题,当时说的具体的我记不大清了,大意我就建议说让那个人试一下写个适配器,把问题解决。然后这老兄弟就说咱理论一套一套,要实践如何如何。把我逗乐了,这都是基本功呀,不是理论一套一套的,就是你不懂的话,就两眼抓瞎,网上到处搜答案,到处问人,从CSDN找答案,十个答案九个错,七个都是在复制粘贴别人的答案,也就是自个都没明白呢,也不实际玩一下,就直接人云亦云。
没人掌握整个系统的全部细节,不像硅谷好多老程序员,就5、60岁的那帮大爷,那叫一个强,人家是真的掌握每一处细节,你把他辞了,别人来了也接不了他的活,回头你还得把人请回来,给人涨一波工资。毕竟太复杂了,越到后面越复杂,越不敢轻易改动,但是人家就无所谓,各个细节全公司没有比他更清楚更了解的,动个小手术,动个刀子啥的,这不easy得很。
leetcode,其实社区环境还好,氛围还行,没有啥互相诋毁,踩踏,谩骂之类的事,毕竟大家都是文明人。就是刷题圈真的现在风气全给带坏了,各种攀比,各种歧视,各种撕x,各种抱团站队,已经在向饭圈靠拢了。知道的是做了几道计算机奥数题的学生,不知道的还以为进了某个流量明星的饭圈打榜群了,就做几道前人已经做了无数遍的题,这都能做出优越感来,真的令人匪夷所思。一个学生,一个打工人,不好好学习,想着提高技术的技术水平,整天为几道题跟人撕x,这不吃饱了撑得。
曾有位朋友跟我讨论这个问题,说这些人都是科学家,我们工程师不需要搞发明创造创新,拿着别人的东西直接用就行,我是非常反对这种观点的。工程师不需要创新吗?工程师如果没有自己独到的地方,那他跟工人有啥区别?当一个理论功底扎实,实践经验丰富的工程师,这个人要是还有一双善于发现问题的眼睛,能够发现问题,并研究出巧妙的解决方案,这样的人难道不是人才吗?一个人就不能既是工程师又是科学家还是说科学家只负责理论研究,只负责创新,工程师只管埋头干活就行这样的话,有没有可能科学家的理论变成了空谈,因为他没用工程经验作为底子,而工程师则蜕变为大号工人,因为他不需要思考。
其实现在这种状况,挺悲哀的。就是说算法没有真正变成学生的知识,而是变成一种脑力游戏之类的东西,变成了进入所谓大厂的敲门砖之类的东西,就是已经僵化到这个程度了,完全丧失了其本来的东西。对网上搞算法培训的,和很大一部分学生来说,算法这个东西其实已经被异化了,完全被工具了,成为了“无用”的“大厂入场券”,然后他去了给人搬砖,就说这个东西没什么卵用,本质还是没有学会算法,过分注重技巧性,思想是一点都没有掌握。“题海战术”绝对是最笨的学习方法,庸才可以通过背原题跟天才同台竞争而不落下风。
如果你真的对算法感兴趣,从工程上去玩,去看,你会发现很多有意思的,绝不是说会做几道计算机奥数题就算是会算法了,那太小儿科了,真正的大科学他大概率就是找个一个工程上的难题,然后设计出一种非常巧妙的方法,把问题给解了,然后这个就是他发明的算法,就是这么个事,既考验基本功,考验阅历,工程经验,还有设计能力,算是一个人的综合素质方面的考察吧。
从Amazon出来的人写了一本《ProgrammingInterviewsExposedCodingYourWayThroughtheInterview》,你直接去Google搜就行,跟上面这本差不多,国内没翻译过来,书有点老了,但是很经典,这本书可以好好看一下。
左程云那本《程序员代码面试指南》这本书其实很像一本习题集,但是题目全是左程云先生自己做的,原创度就比较高,他其实讲的很细,然后最好配合他那套视频课程学,b站就有,很详细的,先看视频,在看书,你就会发现其实视频里讲的书上都有些影子,这就比较好。
《编程之美:微软技术面试心得》,习题集,很经典,可以好好看看。
刘汝佳先生和陈锋先生的《算法竞赛入门经典》这一套书是专门打竞赛的入门书,口碑相当不错,用c/c++语言写的。陈小玉女士的《算法训练营》也是偏重于竞赛的,用c++写的。
至于一些公众号主写的一些书也可以参考,但是基本都是偏重技巧性的东西,看看就好,别沉迷。打游戏要适度,做计算题奥赛题也要适度,沉迷就有害了。如下:《代码随想录》、《算法通关之路》、《labubadong的算法小抄》。
说句题外话,如果你数学底子好的话,可以直接上《算法导论》和高司令的《计算机程序设计的艺术》这一套,不要怂,直接干他,你能把这两巅峰选手干趴下。什么BAT,这个段位的选手可以直接略过了,直接去FAANG,现场表演什么叫“那年我双手插兜,不知道何为对手”,对面直接投降,还面个啥,人家就一个“水滴”就可以直接干趴下你那三千艘恒星级战舰,还有必要打吗?
EdsgerW.Dijkstra写了本《编程的修炼》,可以看看,大佬写的,这个人真的牛。百度百科粘的,成就:
1.提出“goto有害论”;
2.提出信号量和PV原语;
3.解决了“哲学家就餐”问题;
4.Dijkstra最短路径算法和银行家算法的创造者;
5.第一个Algol60编译器的设计者和实现者;
6.THE操作系统的设计者和开发者;与高德纳并称为我们这个时代最伟大的计算机科学家的人。
如果你计算机基础扎实的话,你肯定知道什么意思,这一堆,计算机领域很重要的东西,印在课本上的,这个老头一个人搞出来的,你不好奇他怎么搞的?那就看一下人家的书,主要是好好学学思路,好好看看他研究工作的心路历程,这个很重要,学会了就是你的,完全掌握,吊打同龄一帮混子,跟玩似的。
《柔性字符串匹配》(GonzaloNavarro,纳瓦罗,MathieuRaffinot,拉菲伊诺特)能看尽量看吧,名字就能看出来,讲字符串的,数学好好学。英文名《FlexiblePatternMatchinginStringsPracticalOn-lineSearchAlgorithmsforTextsandBiologicalSequences》。
其实还可以往深了延伸,比如DP(动态规划)是从哪里来的?运筹学,那么你可不可以去找一本运筹学课本,看看人家到底在研究什么?在解决什么工程上的具体问题,这个好不好?不要整天沉迷于“偷房子”,“买卖股票”,“背包放东西”之类的智力游戏,算法不是什么智力游戏,而是现实中具体工程问题解决方案的抽象化,你把这个当智力游戏玩你就载进去了,出不来了。没必要通过这个显示自己智商高,没意义,说实话人跟人的智商真差不了多少,就是一个习惯问题。正常人谁会觉得“最强大脑”那些演员是什么天才、学霸之类的?天才、学霸就是纯靠记忆力的?一个人之所以被称为天才,一定是他在他所在的领域做出了巨大的贡献,解决了什么大问题,难题,而不是说他参加了什么低水平的靠包装人设、讲故事、贩卖焦虑的三流综艺节目成为天才,要搞清楚这一点。
最后,哲学史看一下,就研究研究那些人的思考方法,分析和解释问题的思路,这很重要。不了解哲学,不知道苏格拉底,遇到问题只会追求所谓的“标准答案”,缺乏更深入的思考,就入不了科学这道门。
最后这两个是很实用的东西,不要觉得跟算法无关,算法你不就是解决问题的方法嘛。那多研究研究,把别人的思考、分析、解释的这些东西学到手,然后再多想想,未尝自己搞不出来一个,要敢想,不要害怕,中国的很多小孩就是胆子小,内向,这个不太好,很多东西思路打开了也就那样,就怕自己给自己设限。
先看视频听思想,再做题,同时看书理解。看书先找英文的,直接看英文,算法英语同时学,提高英语水平,有利于阅读文档。