程序员的遗憾:忽视数学必定后悔!
Posted CSDN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序员的遗憾:忽视数学必定后悔!相关的知识,希望对你有一定的参考价值。
对于程序员来说,数学很重要吗?
也许你对数学并不很精通,却依然能够成为拿着高薪的专业程序员,但是本文的作者用自己的切身经历表明:抓住机会学习数学,否则迟早有一天你会后悔!他认为,编程本质上就是解决数学问题,数学几乎和所有知识都有着千丝万缕的联系。接下来,我们就一起来探讨下数学对编程的重要性。
声明:本文已获作者 Walter Schulze 翻译授权。
作者 | Walter Schulze
译者 | 弯月,责编 | 郭芮
出品 | CSDN(ID:CSDNnews)
以下为译文:
数学很重要吗?或许数学比你想象得更重要,或许没有你想象得那么重要……
也许你可以忽视数学,却依然能够成为拿着高薪的专业程序员。编程是一个非常广泛的领域,你可以选择自己想要关注的领域(其中一些领域就不需要数学 ),然后取得成功。然而:
数学是用来解决专业问题的工具,而且——
编程就是解决数学问题。
我举几个例子,希望通过这些例子鼓励你学数学。为此,我挑选了一些短视频(平均每个10分钟),这些视频很有意思,能够很好地解释这些概念。
但是,首先让我讲一个故事。一个关于我忽视数学的故事……
在大学的时候,我并没有觉察到数学的重要性。大学的数学与我们高中所学有很大的出入,而我真正想学的是编程。数学似乎是阻碍我获取学位的难关,但是只有拿到学位我才能接触更多编程的工作。我最没有动力学习的就是证明,我感觉证明只是在考试中充数,而且对我的编程生涯没有任何价值。我固执地认为自己是个“有原则”的人,我拒绝研究证明。这导致我在大学第一年的成绩非常差。过于骄(愚)傲(蠢)的我拒绝学习证明,并希望在40%的题目都是证明的考试中勉强及格。而我依然没有醒悟,于是第二年我不得不参加补考。在补考中我终于与我的“原则”妥协,而且整个暑假我的大部分时间都在学习证明。我未能就此攻克数学,我的假期就这么白白溜走了,而我仍然不明白为什么数学这么重要。你可能会认为,我会从这次惨痛的失败中得到教训,但我仍然为自己的顽固感到汗颜。可以这么说,如果数学是一门选修课的话,我绝对不会选它!事后看来,这是我最大的遗憾之一:五年之后,我发现我最感兴趣的问题都以数学为基础。
最终,我拿起了一本计算机科学书开始读,并在提交硕士论文的那一周里阅读了书中规定的材料。这时,我幡然醒悟,数学和计算机科学有着千丝万缕的联系。从那以后,我开始奋起直追,课间的时候向那些好学生看齐,并利用宝贵的业余时间学习。十多年来,我一直在坚持不懈地努力学习,如果大学四年我能够抓住机会好好学习,那该有多好?这十年的时间我本可以像同事那样学习新技术,但我把这十年都花在了数学上,而且我的数学仍然没有达到研究生的水平。有时我真心感觉我浪费了自己的生命……好了,我的故事就讲到这里,下面让我们举几个例子,来看一看数学对编程的重要性。
很明显,游戏和电影中的图形编程需要物理知识,但由于精确的物理实现起来代价太大,无法正确模拟,因此我们通常会使用数学中的数值方法。例如使用韦尔莱积分法来近似地模拟布娃娃物理系统:
谷歌的网络搜索算法也是一个很好的例子。你可能以为这个算法只是统计网页上的单词,然后将相关单词数量最多的页面显示在最顶部,但这种排名算法太容易操控了,例如只是在网页上重复“数学”一词,实际上却不包含任何数学内容。对页面进行排名,然后将关联性最显著的结果显示在顶部是一个更复杂的问题。页面排序算法考虑了进出网页的链接数量并将它们放在矩阵中,然后使用线性代数中的特征向量来求相关性排名的近似值:
(完整视频可点击:https://youtu.be/F5fcEtqysGs)
我在学习时发现人工智能(或者更确切地说是机器学习这个子领域)非常有趣。模仿舞蹈游戏中的手势,在Netflix上查找你可能喜欢的电影,识别当前正在播放的歌曲等。如果你想参与这些系统的构建,那么至少要对微积分、概率论和线性代数有很好的理解。
(完整视频可点击:https://youtu.be/8onB7rPG4Pk)
这些例子足以说明,数学是解决特殊问题的工具。接下来,我想谈谈数学是编程的问题,我发现这个问题更有趣。
抽象是编程中非常重要的一部分,我们将复杂的问题分解成小问题的一种方式。当我们看到一些模式或想要隐藏一些复杂性时,我们会使用抽象类或接口等创建一个抽象。我们甚至会为如何抽象创建模式,并在这些模式上抽象。我们的抽象方法非常重要,因为抽象可能会添乱,也可能会非常有用。
众所周知,计算机问世已经几十年了,但计算和计算引擎设计的问题已有数百年的历史。你可能会对此非常惊讶,但与数学相比,这仍然是一个非常年轻的领域,数学已有数千年的历史。这意味着数学经过了更加漫长的岁月为各种问题提出解决方案。我们不妨看看我们是否可以从数学中借鉴一些想法——吸取精华才是对这门学科的尊重!
毫无意外,数学中有一个叫做抽象代数的子领域。下面是一段有关抽象代数的视频,其中介绍了“群”(Group)的概念:
(完整视频可点击:
https://youtu.be/QudbrUcVPxk)
群(Group)是加法和乘法的抽象,但它也是幺半群(Monoid)的超类。如果你取一个群,然后删除元素需要反转的属性,就会得到一个幺半群。幺半群是一组元素,它包括一个幺元,还有关联的运算符。这个抽象不仅适用于加法,还适用于:
这种抽象很有用,因为现在我们可以编写适用于任何幺半群的函数实现。例如:
我们可以进一步抽象,让这个函数不仅适用于树,还可以适用于任何可折叠容器,换句话说,任何可以转换为列表的容器。
在设计库时,掌握幺半群的知识会很有用。如果你有一个二元函数,比如乘法,它的输入为类型相同的两个参数并返回相同类型的结果,那么你最好考虑一下其幺元是什么。如果你能找到幺元,就可以找到一种非常直观的方法,可以在列表中使用二元函数。这个函数可以处理空列表,因为你有一个合理的默认值和数学属性,遇到这种情况它会报错,这会大大简化用户代码。
在这里,我们使用抽象来创建可以共享的实现,但抽象的用途远不止于此。抽象还可以解释或发现连接。
人类解决复杂问题时惯用的方法是分治法。将问题分解为小问题,然后逐个解决这些小问题,再将这些解决方案组合成解决大问题的解决方案。你还能想到其他常用的方式吗?……
在编程中,我们将一个问题分解成几个较小的问题,然后编写较小的函数解决这些较小的问题,再将它们组合成大函数,最终解决大问题。将这些组合在一起的最佳方法是什么?我在想我们是否可以借鉴数学的思路?
范畴论是数学的另一个子领域,我喜欢称之为抽象代数的抽象,但实际上它是组合数学,我们研究的是对象的上下文而不是它们的内容。在这里,我们可以找到很多实用的概念,例如:
函子(Functor),我们可以通过map函数针对容器中的每个元素运行一个函数,例如Python中的Lists、Java API中的Stream API和Optional,乃至Haskell中的函数。
单子(Monad),它是Python中列表推导的基础,C#中的LINQ、Scala中的解析器组合、Haskell中的IO和大多数并发等。无论是何种编程语言,都有一种有用的单子。
F-Algebras,我们可以利用它来递归抽象——但说实话,我知道的就这么多了。
你可能需要一段时间才能消化这些极其抽象的概念,因此越早开始越好。下面是一则介绍单子的短视频:
(完整视频可点
击:
https://youtu.be/Nq-q2USYetQ)
这是数学这顿大餐中最甜蜜的一道菜,也是最后一道菜。
你可能还记得我说过,在上大学时证明是我最不愿学习的部分。但是,现在我想告诉你类型可以被视为证明中的命题和程序:
x + y = y + x
P & (Q | R) = (P & Q) | (P & R)
length(filter(谓词,列表)) <= length(list)
C编译器生成的可执行代码与源C程序的语义完全一致,请参阅CompCert(http://compcert.inria.fr/compcert-C.html)。
现在我知道我可以使用编程来从数学上进行证明,而且我发现证明是最有趣的编程任务。我们可以利用证明编写更安全的程序、减少错误,因为我们可以证明属性而不仅仅是测试它们。
但是等等,如果你能用编程来证明,那么是不是也可以通过我们喜欢的事情——编程——来为数学做贡献?没错,数学非常需要每个人贡献自己的力量。对你来说,证明很难,其实对数学家来说也很难。数学家的证明总是在出bug——几十年来这些bug都未被发现。同伦类型论(homotopy type theory)研究的是不同类型的相等,其对单一观点的数学带来了很大冲击,因为它认为所谓的数学基础都是错误的。是的,甚至连数学都不是完美的,而且还有很多我们努力的空间。
虽然在使用编程证明的概念上,我还是个新人,但我对此十分感兴趣,迫不及待地想了解更多这方面的知识。我推荐你阅读《The Little Typer》,这本书很好地向有递归经验的程序员介绍了使用依赖类型做证明的方法。
我一直在不惜一切代价回避的数学,最终却成了我最喜欢的领域。我希望你们不要犯同样的错误:抓住机会学习你所有的必修课,否则迟早有一天你会后悔。
如果你的导师或教育资源没有给你提供探索该广阔知识领域的机会,那么你可以利用众多在线资源,比如YouTube、Coursera或Edx,或者也可以阅读相关的书籍。你一定可以找到掌握这些高难度概念的渠道,只是需要一些时间。此外,你还需要不断地练习,就像练习编程一样。
如果不是因为我不理解新材料的基本概念的话,如今也不需要付出如此艰辛的努力。不要羞于回头重新巩固你的基本知识,在数学中,许多知识是互为基础的,如果没有坚实的基础,就会寸步难行。所以,我觉得花点时间,回头通过这些资源学习数学的基本知识,并掌握关键的概念,也是物有所值的,毕竟我们不想撞得头破血流。
我建立了一个任务清单,我希望尽快补齐遗漏的数学知识。如你所见,这是一个漫长但又很愉快的旅程。数学是一个巨大而又令人兴奋的学科,几乎所有知识都有千丝万缕的联系。下面的视频大概介绍了主要部分:
原文:https://awalterschulze.github.io/blog/post/neglecting-math-at-university/
作者:Walter Schulze,软件工程师@Facebook。
点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。
以上是关于程序员的遗憾:忽视数学必定后悔!的主要内容,如果未能解决你的问题,请参考以下文章
5 个被忽视的习惯,决定了你很难成为高级开发工程师!
heartisyouregretisyou啥意思?
数学建模竞赛“爱你不容易,爱你不后悔”
汉语-词语-遗憾:百科
学习计算机的三年
写给程序员的机器学习入门 - 从基础说起