Programmer's biggest regret: Ignored mathematics in college

You can ignore the math, you may just want to be a highly paid programmer. Programming is a very broad field, you can choose the fields you want to focus on (some of which do not require knowledge of mathematics) and still be successful. But from another perspective:

  1. Mathematics is a tool used to solve special problems;

  2. Programming is doing math.

I want to give you two examples, hoping to inspire you to give yourself a chance to learn mathematics. To this end, I picked some short (10 minutes on average) videos that might excite you and use them to explain these concepts.

But first allow me to say something that has nothing to do with mathematics...

If you don’t want to learn, you won’t learn

When I was in college, I really didn't understand the meaning of studying mathematics. University mathematics is very different from our high school mathematics, and what I really want to learn is programming. Mathematics seems to be the only way for me to get a degree, just for exams, it seems to have no value to my programming career. I stubbornly believed that this was the case, so I refused to invest a lot of time in mathematics, which resulted in me being assigned to a poorly performing group in the first year. I am too proud (it should be said to be stupid), but 40% of the test is related to the math certificate, and I just barely passed the test. In the second year, I still did not change my previous views, and in the end I had to take the make-up exam. During the make-up exam, I finally compromised and spent most of the summer studying math. After spending a summer vacation, I still haven't learned mathematics thoroughly and still don't understand why it is so important. You might think that I will learn some lessons from this huge failure, but in fact I am still blinded by stubbornness. I just want to say that if mathematics is only an elective course, I would not choose it! But in hindsight, this is one of my biggest regrets: five years later, I discovered that the problems I am most interested in are closely related to mathematics.

In the week after I submitted my master's thesis, I finally picked up a computer book. At this time, I finally realized that mathematics and computer science are connected in a very interesting way. Since then, in my precious spare time, I have been trying to catch up with those students who listened carefully in class. This is a process that has lasted for more than ten years, and I could have done these things in four years of university. In the past ten years, I could have spent time learning new things, just like my peers, but my mathematics has not yet reached graduate level. Sometimes I really feel that I was wasting my life, but instead of struggling with it, let us look at some examples to see how important mathematics is to programming.

Mathematics is a powerful tool for programmers

Graphics programming in games and movies involves physics knowledge, but accurate physics simulation is very expensive, so we usually use mathematical numerical methods instead, such as using Verlet integration to approximate physics:

https://youtu.be/2TIEfgC3tAo

You might think that Google’s search algorithm simply counts the number of words on a web page, and then displays the page with the highest number of relevant words. If this is the case, then ranking is too easy. You only need to count the number of words repeatedly, without including Any mathematical problems. But in fact, ranking search pages is a big problem. The PageRank algorithm takes into account the number of links between web pages, puts them in a matrix, and then uses the eigenvector approximation algorithm of linear algebra to calculate the ranking:

https://youtu.be/F5fcEtqysGs

During the learning process, I found artificial intelligence (or a subfield of machine learning) very interesting. Track gestures in dance games, find movies you might like on Netflix, identify currently playing songs, etc. If you want to participate in the construction of any part of these systems, you need at least a good understanding of calculus, probability theory, and linear algebra.

https://youtu.be/8onB7rPG4Pk

I think these examples are enough. They all use mathematics as a tool to solve special problems. Now I want to talk about the less obvious problems and explain why mathematics is programming.

Programming is a process that eats up mathematics, abstraction is an appetizer

Abstraction is an extremely important part of programming. We use abstraction to break a complex problem into smaller parts. When we find some patterns or want to hide some complexity, we will abstract, such as using abstract classes or interfaces. We even create higher-level patterns for how to abstract and abstract these patterns. The way of abstraction is very important, because abstraction can be very confusing, and it can be very useful. How can we discover the most useful abstractions?

Although computers have only existed for a few decades, the design problems of calculations and calculation engines have existed for hundreds of years. This fact is indeed surprising, but compared to mathematics, it is still only a very young field, because mathematics has existed for thousands of years. In other words, mathematics has more time to solve certain problems. We might as well see if there is an idea that can be stolen-in fact, if we don't, we seem a little arrogant!

抽象代数是数学的一个子领域,下面是对抽象代数的一些介绍:

https://youtu.be/QudbrUcVPxk

群是加法和乘法的的抽象,也是幺半群(Monoid)的超类。如果一个组移除了元素需要逆运算的属性,就只剩下幺半群。幺半群是一组元素,包括恒等元素及其关联操作。下面的抽象不仅适用于加法,而且还可以:

图片

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

  • 一个简单的函数 mconcat,将一系列幺半群元素组合成一个单独的元素,这个时候对整数列表求就变得与重叠图像列表一样。

  • 一个复杂的函数 foldMap,可以递归地遍历树,或者:

    • 返回值为 true 的元素;

    • 找出是否有任何元素大于 5;

    • 将可折叠结构转换为集合。

我们可以进一步抽象,不仅可以将这个函数用于树,也可以用于任何可折叠容器,换句话说,就是任何可以转换为列表的容器。

在设计程序库时,幺半群也是很有用的。如果有一个二元函数,比如乘法,它接受两个相同类型的参数,并返回一个相同类型的结果,这个时候最好要考虑一下哪些是恒等元素。如果找到了,就等于找到了一个非常直观的方法来使用二元函数。你的函数甚至可以处理空列表,因为你有一个合理的带有数学属性的默认值,这将简化用户代码。

在这,我们使用抽象来创建实现,但其实抽象的作用不仅限于此,抽象的作用是解释或发现连接。

组合是主菜

分而治之是人类解决复杂问题的一种非常流行的方法。把问题分解成更小的部分,解决这些小问题,然后把这些解决方案组合成更大问题的解决方案。你能想到另一种更通用的方法吗?

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

范畴理论是数学的另一个子领域,我喜欢把它叫作抽象的抽象代数,但实际上,它是有关组合的数学。我们可以从中找到很多有用的想法,比如:

  • 函子(Functor),我们可以使用映射函数将函数应用于容器中的每个元素,比如 Python 的 List、Java 的 Stream API 和 Optional,甚至是 Haskell 的函数。

  • 单子(Monad)是 Python List 遍历、C# LINQ、Scala 解析器组合符、Haskell IO 和并发性的基础。我们可以找出任何一种编程语言的的单子。

  • F 代数,我们通过递归进行抽象。

要理解这些抽象的概念可能需要一段时间,所以你开始得越早越好。下面是一个简短的视频,试图解释单子是什么:

https://youtu.be/Nq-q2USYetQ

数学证明是甜点

你们可能还记得我之前说过数学证明是大学数学中最无聊的部分。但我想告诉你的是:类型可以被看作命题,程序可以被看作证明:

https://youtu.be/SknxggwRPzU

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

  • x + y = y + x

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

  • length(filter(predicate, list)) <= length(list)

  • C 编译器生成的可执行代码与 C 程序的语义完全相同,请参见 CompCert:http://compcert.inria.fr/compcert-C.html

现在,我们知道我们可以用编程来证明一些东西,而我发现证明是编程中最有趣的事情。我们因此可以编写更安全、错误更少的程序,因为我们可以证明属性,而不只是测试它们。

但是等等,如果你能用编程来证明一些东西,不是也能通过写程序来为数学做出贡献吗?是的,数学证明不仅对你们来说是难题,对于数学家来说也是难题。数学家总是在证明过程中中制造错误——而这些错误几十年来都没有被发现。同伦类型理论研究的是不同类型的等式,它以单价观点颠覆了数学的基础,认为所谓的数学基础是有缺陷的。是的,即使数学也不是完美的,还有很多需要我们去提升的空间。

我还只是这方面的新手,不过我发现这非常有趣,并且迫不及待地想要学习更多。我可以推荐读者阅读一下 Little Typer:

https://mitpress.mit.edu/books/little-typer

它为有递归经验的程序员提供了如何使用依赖类型来进行证明的入门知识。

寻找灵感,打好基础

这似乎是我以前一直在试图不惜一切代价避免的事情,结果却变成了我最喜欢做的事情。所以,不要犯我曾经犯过的错误:充分学好你的数学必修课,否则你以后会后悔的。

如果你的教材不能激励你去探索这一领域的知识,那么可以转向其他的在线资源,比如 YouTube、Coursera 或 Edx,或者试着找一本更好的书。有些人能够将难以理解的概念解释清楚,并激励你——你只需要花点时间去把这些人找出来。你还需要进行练习,就像练习编程一样。

还有一些时候,我也感到很挣扎,因为有些新的概念需要以之前的东西为基础,但我却缺失了这些东西。请不要羞于回头重新去学习之前错过的东西。在数学中,很多东西都是建立在彼此的基础之上,没有坚实的基础,很难取得进步。花点时间回头学习之前错过的东西总是值得的,试着正确地把握这些关键概念,而不是盲目地往前走,让自己陷入一片混乱之中。

我有一个待办事项列表:

https://github.com/awalterschulze/learning/blob/master/Mathematics.md

我用它来弥补之前错过的东西。这只是一个漫长而愉快的旅程的开始。数学是一门庞大而令人兴奋的学科,几乎所有的东西都是相互联系的。我们可以从更大的角度来看待数学:

https://youtu.be/OmJ-4B-mS-Y


Guess you like

Origin blog.51cto.com/15060462/2677938