前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么你学算法容易忘?

为什么你学算法容易忘?

作者头像
TechFlow-承志
发布2023-03-02 15:07:01
3880
发布2023-03-02 15:07:01
举报
文章被收录于专栏:TechFlowTechFlow

作者 | 梁唐

出品 | 公众号:Coder梁(ID:Coder_LT)

大家好,我是老梁。

最近在知乎上看到一个很有意思的问题,叫做“程序员怎么记住众多代码的?”

我相信对于在座的萌新程序员来说,可能更想知道的是,为什么我学了新的算法总是容易忘?大牛们都是怎么做到的?今天就和大家聊聊这个话题,希望能够帮助一些同学解除困惑。

心理表征

在著名的畅销书《刻意练习——从新手到大师》一书当中提到了这么一个案例。说是在导航软件出现之前,伦敦的司机有一项超能力,可以瞬间反应出到达目的地的最优线路。要知道伦敦是国际化大都市,城市交通网错综复杂。要记住庞大的路线、地图已经足够困难,更何况还需要快速计算出路径呢?

对于这个问题书中给的解释是心理表征,这是一个英文翻译词,因为文化隔阂的原因导致它比较难以理解。我个人觉得理解成抽象信息更加直观,随着信息的一层层抽象和聚合,信息的密度会增大,信息的体积会随之减小。也就是说信息越抽象,我们要“记”的内容就越少,也就越容易被记住。

伦敦的出租车司机并不是将地图印在了脑子里,而是对伦敦的路线提炼了非常精炼的抽象信息。使得只要一听目的地和当前时间,就能立刻反应出应该选择的最优路线。书中还有一个例子是记棋谱的例子,一些象棋高手可以快速记住一局残局每一颗棋子的位置。然而神奇的是,如果棋盘中的棋子是随机摆放的,他们的表现和普通人相差不大。只有是真实对弈的残局或者局面时,他们才能快速地记住。

这说明了高手们之所以能记住盘面,并不是依靠记忆力记住了每一颗棋子的位置。而是利用了盘面中棋子位置之间的抽象信息,随机摆放的棋子是不包含抽象信息的,而真实对弈的棋局,每一颗棋子摆放的位置相互之间存在一定的逻辑。这些象棋高手可能自己也说不出来这逻辑究竟是什么,但他们正是通过它完成了记忆。

如果大家了解过深度学习,尤其是卷积神经网络的话,会发现这和图像识别问题当中的卷积网络异曲同工。我们知道一张图片包含上百万甚至上千万像素点,每一个像素点都有独立的取值,因此图片的内容千变万化。我们直接从像素点入手想要设计一个模型是非常困难的,因此我们势必要做一些抽象和聚合。这也正是卷积神经网络训练的过程,我们来看下下图。

模型的输入是一系列像素点,第一次抽象,我们会将相邻的像素点聚合,从而得到了一些边。第二次抽象,我们再将相邻的边聚合,得到了一些区域图。第三次抽象,我们再将局部的特征图聚合,就得到了一张完整的人脸。在这个过程当中,模型的参数数量是减少的,相比于输入层上百万甚至更多的参数,输出层可能只有几百个甚至几十个。

这正是因为信息的高度抽象使得模型要“记住”的内容大大减少,到最后,都是高度抽象的信息,根本用不到太多的参数。

在编程和算法领域也是一样的,高手们能力出众依靠的并不是记忆力,并不是因为他们记住了多少算法。算法题千变万化,只靠记忆是不够的,高手们和伦敦的出租车已经象棋高手一样,依靠的是对心里表征或者说高度抽象信息的驾驭。

联想能力

有一句著名的广告语,叫做人类失去联想,世界将会怎样。不考虑商业成分,单纯看字面意思,这句话毫无毛病。联想能力几乎能和思维能力画等号,这也是算法高手们的杀手锏所在。

前面说了算法高手之所以能力出众,并不是依靠记忆力,靠记住了多少算法,而是依靠的抽象信息。那么在我们思考问题的过程当中,这些抽象信息是怎么起作用的,或者说高手们是如何进行思考的呢?依靠的都是本能吗?当然不是,依靠的是联想。

普通人的大脑当中,知识是以点状图分布的。当遇到实际问题时,能想起来的只有那么几个点。而高手的思维当中,知识同样是以点分布的,只不过和普通人不同的是,高手会用联想将这些点串联起来,组成一张知识网络。遇到问题时想起来的就不再是几个零星的点,而是一大片知识网络,因此更容易获得启发想出解法。

比如我们来举个例子,我们遇到了LeetCode中一道题。普通人读完题目之后一旦没有思路,就会陷入干想。他们知道要分析要推导,但完全不知道从何下手,只能瞪眼干想。而高手们呢?由于他们的知识体系非常紧密,读完题之后可能瞬间就联想到了几道类似的问题,或者是常用的一些解决方案,脑子里能有好几种想法。之后只要把这些想法一一验证,过滤掉不可行的。

如果这些想法都不可行,那么就进一步分析它们不可行的原因,再从这些原因出发继续联想。如此操作往复多次,往往解法也就浮出水面了。

看到了吗,不是在记忆里检索学过的算法生搬硬套,而是分析问题,通过联想寻找解法。

原理大于一切

通过前面的论述我们已经知道了,思维能力由两个部分组成,一个是知识点,另一个是联想能力。那么想要提升能力也可以从这两个角度针对性地入手。

专题练习

虽然我们说学算法不能靠死记硬背,但并不是说记忆力不重要。一个算法我们完全都没听说过,自然也就很难解决它适用的相关问题。想要拓展知识面,别无他法,只有依靠学习和练习。

但学习和练习也是有技巧的,并不是机械的越多越好。由于篇幅原因,这里只说一个最贴切的——重质不重量。

字面意思是更加看重质量而非数量,深挖一点来说是更加看重理解,尤其是核心原理的理解。核心原理是算法领域抽象程度最高的信息,最有含金量,将它记住的成本最低。比如很多同学觉得动态规划很难,种类很多,千变万化。但它的原理很简单,无非是状态转移和最优子结构两点。我们深入理解了原理之后,剩下的只需要根据实际情况随机应变即可,根本不用拘泥于代码形式。

想要达成这点,最好的方法是专题练习。每次只学一个算法,一次把这个算法相关的各种变形问题都做一遍。把当前算法的原理搞懂吃透,一般来说一个专题做完之后,算法也就完全记住了。

发散练习

发散练习针对的是单个题目,大多数情况下,一道问题往往有多种解法。通常情况下,我们最容易想到的是我们最熟悉的算法。不少同学追求刷题数量,一旦通过题目就放在一边了,也不会再去深入思考尝试其他解法了。

在一道已经通过的问题上继续花功夫,怎么看都是无用功,但事实并非如此,这也是很多acm大牛常用的训练方法,叫做发散练习。

这么做的好处很明显,首先可以帮助我们开拓视野,一个是可以增强一些我们不太常用的算法的练习,另外一个很重要的理由是,很多时候不同的算法意味着不同的思路不同的推导过程。我们把几种方法都写出来,互相对比,不但对问题理解得更加深刻,也可以让我们对算法本身加深认识。很多时候会有“原来这题也可以使用这种方法”恍然大悟的感觉。

还有一些大佬在练习的时候,会强制自己使用某一个算法。明明不是动态规划的问题,也想尽办法用动态规划去解释去思考。明明不是网络流的问题,也通过网络流去建模。通过这种方法逼自己开拓视野,增加对算法的理解和熟悉。动态规划和网络流非常经典,适用面也非常广,号称一切问题都可以使用这俩来建模。虽然略有夸张,但这种做法却很值得我们借鉴。

这几年随着互联网行业发展越发成熟,国内大小公司对于算法问题以及思维能力的考察也要求越来越高。越来越多的公司会在面试当中进行算法题和思维题的考察,因此想要成为优秀的工程师,斩获知名公司offer,算法能力的提升和补充非常重要。

针对大家的这个需求,老梁最近一直在更新《代码随想录》的学习笔记系列。说是学习笔记,其实可以认为是随想录的随想录了,我会就书中提到的比较重要的算法和习题都做我个人的阐述和讲解。有没有看过原书都不影响大家的阅读

算法学习路上,与你同行,共勉。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 心理表征
  • 联想能力
  • 原理大于一切
    • 专题练习
      • 发散练习
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档