17611538698
webmaster@21cto.com

一个程序员的遗憾:在大学里忽略了数学

编程语言 0 601 2023-03-02 09:40:40

图片

没错,你完全可以忽略数学,也能成为一名高薪的专业程序员。

编程是一个足够广泛的领域,你可以选择想要关注的领域。其中一些并不需要数学,并且你仍然会成功。

但是,从另一方面讲:

数学是这用于解决专门问题的工具,以及有的编程就是做数学。

  1. 我想给到你一些例子,希望这会激励你给数学一个成长的机会。为此我选择了一些简短的(平均为10 分钟时长)视频,这些视频应该会让你兴奋,也会比我的解释能更好的理解这些概念。


  2. 首先,请看一个故事,关于我是如何不关心数学的。


  3. 不想学就学不会


当我上大学的时候,然而当时并没有真正看到数学的意义和价值所在。


图片

它与我们在高中时所学的数学相比,起了一个非常大的变化。


我其实真正想做的就是编程,而数学只是获得学位的必选科目,但我就想立即开始编程工作。我也不断证明它是所有功课中最让我没有动力的,因为我感觉它只是为考试而死记硬背的东西,对我的编程生涯没有任何价值。


固执的我觉得自己太有“原则”了,然后我拒绝研究数学,这导致我在第一年被划分到一个针对表现不佳的学习小组里,我当时感觉仍然很骄傲,我拒绝研究证明题,即使 40% 的考试都是证明题。后来,我勉强通过了考试。


但仍然没有收到校方的通过消息,我不得不在第二年重修并考试。考试重修是我最终妥协“原则”的地方,我不得不放弃暑假的大部分时间来研究数学与证明题。


我真的不太喜欢数学,但为了它我失去了一个假期,但仍然不明白为什么它很重要。你应该会认为我会从这次巨大的失败中学到一些东西,但我仍然被自己的固执所蒙蔽。


当后来数学成为选修课时,我便没有选择它!事后看来,这是我最大的遗憾之一。


在五年后,我发现最有趣的科目是数学。但是当年,它成为一门选修课时,我没有选择它!从事后来看,很多有趣的问题都是以数学为基础的。


在我提交硕士论文的那一周,我终于拿起了一本计算机科学与技术书籍来阅读,包括学校规定的材料。我才终于意识到数学和计算机科学以一种非常有趣的方式联系在一起的时候,是多么的般配!


从那以后,我开始追赶所有真正在课堂上集中注意力的同学,我还搭上了下班后的空闲时间,那也是很宝贵的。


就这样,这个过程我持续了十多年,粗浅的我原本可以只关注它四年就够,结果书皮打在了我脸上。


这是我愿意花时间学习新事物的十年,就像我关注的同龄人一样。但是,我的数学仍然没有达到研究生水平。


有时,我真的觉得浪费了自己的生命,但与其再纠结于此,不如去全力一搏!


数学作为程序员工具的示例


很明显的一个道理,游戏与电影中的图形编程需要物理学的专业知识,但由于模拟精确的物理学可能太过昂贵而无法正确模拟。


我们通常使用数学中的数值计算方法,例如使用 Verlet 微积分来模拟布娃娃式的物理。


不太明显的可能是Google的网络搜索算法。你可能以为这只是简单地统计网页上的单词数,并将相关单词数最多的页面显示在顶部,但这种排名太容易操纵了,例如只重复单词匹配的网页,实际上并未包含任何数学知识。


对页面进行排名以使最相关的结果位于顶部是一个更难的问题。Google PageRank 算法考虑到网页的链接数量并将它们放在一个矩阵中,然后它使用线性代数中的特征向量的近似值来计算更相关的排名。


人工智能或者更确切地说,是机器学习的子领域,是我在学习时发现非常有趣的东西。


在舞蹈游戏中跟踪手势,在 Netflix 上查找您可能喜欢的电影,识别当前正在播放的歌曲等。如果想构建这些系统中的任何一个,你至少需要对微积分、概率有很好的理论理解,此外还包括线性代数。


图片

这些例子足以说明,数学是解决特殊问题的工具。接下来,我想谈谈数学是编程解决问题的核心,我觉得这个问题更有趣。

编程就是吃数学

抽象作为开胃菜。抽象是编程的一个很重要的部分——这是将复杂问题分解成更小部分的一种方法。我们看到一些模式或者想要隐藏一些复杂性,然后创建一个抽象,例如使用抽象类或接口。甚至为我们如何抽象和为这些模式创建模式。


编程如何抽象非常重要,因为抽象可能非常混乱或非常实用。我们怎样才能发现最有用的抽象?


尽管我们所知道的计算机只出现了几十年,但计算问题和计算引擎的设计已经存在了数百年。这是一个令人惊讶的事实,但它和已经存在了数千年的数学相比,它仍然是一个非常年轻的领域。这意味着数学有更多的时间来解决某些问题。我们不妨看看是否有我们可以借鉴的想法。从事实上,不这样做可能很傲慢!


这并不奇怪……数学有一个合适的子领域,称为抽象代数。这是抽象代数其中的一点味道,我们来使用数学解释一个Group(组概念):


图片

Group 是对加法与乘法的良好抽象,但它也是 Monoid 的超类。如果采用 Group 并删除元素需要反转的属性,将剩下一个 Monoid。Monoid 是一组元素,其中包括标识元素和关联操作。
现在我们便有了一个抽象,它不仅适用于加法,还适用于乘法、连接、扩展以及合并等。如下图示:

图片

这种抽象很有用,因为现在我们可以编写适用于任何幺半群的函数的单一实现。例如:

  • 一个简单的函数mconcat,它接受一个半群元素列表,并将它们组合成一个元素。对整数列表求和现在与叠加图像列表相同。

  • 一个更复杂的函数foldMap可以递归地遍历一棵树,并且:
    - 返回是否有任何元素为真,
    - 查找是否有任何元素大于 5,或将可折叠结构转换为一个集合,


    所有这些都取决于幺半群的类型。



    们还可以进一步抽象,不仅使这个功能适用于树,而且适用于任何可折叠容器,换句话说,任何可以转换为列表的容器。



了解幺半群在设计库时非常有用。每当你有一个二元函数时,比如乘法,它接受两个相同类型的参数并返回相同类型的结果,最好考虑一下单位元素是什么。如果你找到了,你就找到了一种非常直观的方法来使用列表上的二元函数。您的函数甚至可以在空列表上运行,因为您有一个具有数学属性的合理默认值,并且它将消除错误处理的情况,这将简化您的用户代码。

这里我们使用抽象来创建共享实现,但是抽象可以而且应该比这更有用。抽象是为解释或发现联系服务的。

主菜的构成

人类解决复杂问题的一种非常流行的方法是分而治之。


即将问题分解成更小的部分,解决那些更小的问题,然后将这些解决方案组合成更大问题的解决方案。


各位能想到另一种(通用)方式吗?


在编程中,我们将一个问题分解成几个较小的函数来解决较小的问题,然后将它们组合成越来越大的函数,最终解决更大的问题。将函数组合在一起的最佳方式是什么?我想知道数学是否有任何我们可以窃取的想法?


范畴论是数学的另一个子领域,我喜欢称之为抽象抽象代数,但实际上它是组合数学,我们研究对象的上下文而不是它们的内容。在这里我们可以找到许多有用的想法,例如:

  • 仿函数,它允许我们使用映射函数将函数应用于容器中的每个元素,例如 Python 中的列表、Java 中的 Stream API 和 Optional,甚至是 Haskell 中的函数。

  • Monad,它是 Python 中的列表理解、C# 中的 LINQ、Scala 中的解析器组合器、IO 和 Haskell 中的大多数并发等的基础。给我找一种编程语言,我会为你找到该语言中有用的 monad。

  • F 代数,它允许我们对递归进行抽象——但老实说,现在我们处于我的知识边缘。

这些极其抽象的概念可能需要一段时间才能在您的大脑中成熟,因此越早开始越好。请看下面一段试图解释 monad 的短视频:

图片

证据就在布丁里

这是数学大餐中最甜蜜也是最后的部分。

现在,你可能还记得我说过,我发现证明是在大学学习数学时最没有动力的部分。好吧,如果我告诉你类型可以被视为命题,程序可以被视为证明:

以下是一些可证明的属性:

  • x + y = y + x

  • P & (Q | R) = (P & Q) | (P & R)

  • length(filter(predicate,list) ≤ length(list)

  • C 编译器生成的可执行代码与源 C 程序的语义完全相同,请参阅CompCert


现在我知道可以编程可以使用数学上证明事物,越来越发现证明是编程中最有趣的事情。
证明让我们能够编写出错误更少、更安全的应用程序,因为我们可以证明属性而不仅仅是测试它们。

但是请等等,如果可以用编程来证明事情,难道你不能通过简单地做我们喜欢的事情,编写程序来为数学做出贡献吗?

是的,数学非常需要你。证明不仅对你来说很难,对数学家来说也很难。数学家总是在证明中制造错误——而这些错误几十年来都没有被发现。研究不同类型等式的同伦类型论正在以其单调的观点扰乱数学基础,因为它认为所谓的数学基础是错误的。是的,即使是数学也不是完美的,而且还有很大的贡献空间。

我对使用编程证明的概念还很陌生,但我发现这非常令人兴奋,迫不及待地想了解更多。我可以推荐阅读The Little Typer,它为任何有递归经验的程序员提供了证明使用依赖类型的很好的介绍。

我在 Devoxx UK 2022 上做了一个关于 Coq Proof Assistant Correct Code by Construction 的一场演讲——如果你想看我穿着建筑工人的衣服,看一些鸡的高能见度的话:

图片

寻找灵感并建立基础


这似乎是我一直试图不惜一切代价避免的事情,结果却是我最喜欢做的事情。不要犯我犯过的同样错误:充分利用你的必修数学科目,否则你以后会后悔的。


如果你的教育工作者或教育材料没有激发你去探索这个广阔的知识领域,那么请转向大量的替代在线资源,如 YouTube、Coursera 或 Edx,或者尝试寻找一本更好的书。有人可以解释一个困难的概念并启发你——你只需要花时间去寻找他们。您还需要练习使用练习,就像练习编程一样。


其他时候我一直在挣扎,因为我不理解理解新材料所需的先前基本概念。不要羞于回去修正你的理解。在数学中,许多事情都是建立在彼此之上的,没有坚实的基础就很难取得任何进展。几乎总是值得花时间回去寻找关于该主题的替代资源并尝试正确掌握该关键概念,而不是继续前进并用头撞墙。


我有一个待办事项列表,我正在使用它来尝试赶上我错过的所有数学。正如您将看到的,这只是一段漫长而愉快的旅程的开始。数学是一门庞大而令人兴奋的学科,几乎所有事物都相互关联。看看更大的图景可能会有用:

感谢
  • 感谢Steve Kroon难以置信的严谨校对。

  • Brandon Ashley启发了这篇文章。

  • Paul Cadman提供了数学视角。

  • Liyuan Bi帮助我添加更多示例。


原文超过10000次阅读。


译者:场长
作者:Walter Schulze,软件工程师@Facebook.com。
原文:https://awalterschulze.github.io/blog/post/neglecting-math-at-university/

评论