但是,大多数同学喜欢仅仅扎进一本书里,一旦选定了自己的学习材料,就对其他材料充耳不闻,甚至是排斥的心理。这种做法,一方面又是“完美主义”的表现——非要把这本教材学透;另一方面,其实也是“犯懒”的表现,不愿意多翻翻,多看看,自己多比较比较,自己去寻找最适合自己的材料,一味地盲目相信所谓“大神”的推荐,殊不知,这些推荐,不一定是更适合自己的材料;更何况,还有很多大神,明明是靠不出名的“薄”教材入的门,但给别人做推荐的时候,就突然变成自己是算法奇才,自幼阅读《算法导论》而所成的神话了:)
6)实践前面说了很多和教材选择相关的话题,但对于计算机领域的学习来说,教材的意义其实远远小于实践的意义。如果仅仅是看学习材料就是学习的话,那么慕课网的视频后期处理人员就是水平最高的工程师了。因为每段视频,他们都需要看一遍。但是,很显然,仅仅是看视频,是无法学到知识的。
对于计算机领域的学习来说,真正动手实践去编程是异常重要的。怎么夸大其中的作用都不过分。
这就好比学游泳,必须下水去游泳;或者学开车,必须亲自上路。
否则你说的再头头是道,一个小学生文化水平的人,只要他开过车,游过泳,都能在这两个领域瞬间秒杀你。
很多同学都说我的算法讲得好,其实,我一直认为,这其中的一个最简单的秘诀就是:我带领大家把大多数算法都非常细致的实现了一遍;或者对其中的应用进行了非常具体的实践。
反观大多数高校教育,对于算法或者机器学习这种一定程度偏理论的学习,通常非常不强调实践。最终的结果是学习者只是接受了很多抽象的概念,但对其中具体的实现细节,却是云里雾里。
我见过太多同学,都明白什么是 O(n^2) 复杂度,什么是 O(nlogn) 的复杂度,却问我对于 100 万的数据规模,为什么自己的选择排序运行起来就没反应了。答案很简单:O(n^2) 的复杂度太慢了,100 万的数据规模太大了,一般家用计算机转选择排序一时半会儿是转不完的。这些同学一定理解 O(n^2) 的算法比 O(nlogn) 的算法慢,却没有真正实践过,不知道这个差距到底是多少。
在我的课程中,经常遇到有些同学提出这样的问题:这个算法的某句话(或者某段逻辑),为什么要写成 A 的样子,而不是 B 的样子?这种问题其实很好,但我觉得解决方法也很简单,实际的去把算法改写成 B 的样子,实际的运行试试看,看会发生什么。如果发生了错误,仔细分析一下,为什么会有错误?如果没有错误,具体比较一下:A和B两种不同的写法,为什么都正确?又有什么区别?
真正的学习上的提高,就发生在这个过程中。
我当然可以告诉给同学们一个结果,但是自己亲自实践一遍,相比阅读我给出的一个答案,自己对其中问题理解的深刻程度,是完全不可比拟的。
7)debug非常非常重要。我看到的另一类“经典”问题就是:老师,这个代码为什么错了,然后贴一大段代码。这种问题背后,依然是,透露着学习方法的不对劲:提问的同学懒得 debug 。
在计算机领域,debug 近乎和实践是一个意思。如果只是把材料上的代码“抄”一遍,这不叫实践,这叫抄代码。小学生也能做。但是“抄”一遍,不小心没抄对,发生了错误,然后自己一点一点调试,找到错误的根源,这叫真的实践。小学生不能做。(当然,我更推崇的是:自己理解了算法的逻辑,按照自己的理解,把算法写出来:)
不过很多同学不喜欢 debug,我当然理解。其实谁都不喜欢 debug ,但是,debug 才是最重要的能力。(通常在一个领域里,你最不喜欢做的事情,就是这个领域的核心竞争力:)是计算机领域异常重要的一项技能。我见过的所有计算机领域的“高手”,不管是在哪个细分领域,都无一例外,是个 debug 好手。我经常告诉大家,在实际工作中,其实 debug 的时间要占你真正编程时间的 70%。如果你做一个项目,根本不需要 debug ,要么是你的项目对你来说太简单了,要么是你根本没有接触到这个项目的核心。
debug 不仅仅是找到代码错误,解决错误的手段,其实更是一个重要的学习手段。通过 debug,看看自己写的程序执行逻辑,哪里和自己设想的不一致?再回头看自己哪里想错了,或者想漏了,分析一下自己为什么想错了,或者想漏了,等等等等,依然是,进步就是发生在这个过程的。