Thursday, November 08, 2007

Math For Programmers - 程序员怎样学数学

I've been working for the past 15 months on repairing my rusty math skills, ever since I read a biography of Johnny von Neumann. I've read a huge stack of math books, and I have an even bigger stack of unread math books. And it's starting to come together.

Let me tell you about it.

自从我读了Johnny von Neumann的传记,我已经为弥补我糟糕的数学技能花了15个月了.读了大量的数学书籍,不过呢,似乎我还有更多没有读.当然我会接着做的.
现在我就来告诉你这些.

Conventional Wisdom Doesn't Add Up
这并不包括传统的智慧

First: programmers don't think they need to know math. I hear that so often; I hardly know anyone who disagrees. Even programmers who were math majors tell me they don't really use math all that much! They say it's better to know about design patterns, object-oriented methodologies, software tools, interface design, stuff like that.

首先:程序员不认为他们需要了解数学.我常常听到这样的话;我不知道还有会不同意这个的.甚至于以前是主修数学的程序员也告诉我他们真的不是常常使用到数学!他们说 更重要的是要去了解

设计模式,面向对象原理,软件工具,界面设计,以及一些类似的东西.

And you know what? They're absolutely right. You can be a good, solid, professional programmer without knowing much math.

But hey, you don't really need to know how to program, either. Let's face it: there are a lot of professional programmers out there who realize they're not very good at it, and they still find ways to contribute.

你了解吗?他们完全正确.你不需要了解很多数学你就能做个很棒,很专业的程序员.

但是呢,同时你也不是真的需要知道如何来编程.我们要面对的是:有很多专业的程序员,他们认识到他们不是非常擅长数学,但他们还是寻找方法去提升.

If you're suddenly feeling out of your depth, and everyone appears to be running circles around you, what are your options? Well, you might discover you're good at project management, or people management, or UI design, or technical writing, or system administration, any number of other important things that "programmers" aren't necessarily any good at. You'll start filling those niches (because there's always more work to do), and as soon as you find something you're good at, you'll probably migrate towards doing it full-time.

如果你突然觉得自己好烂,周围的人都远远的超过你,你会怎么想呢?好,你可能会发现自己善于项目管理,或者人事管理,或者界面设计,或技术写作,或者系统 管理,还有许多其他程序员不必去精通的.你会开始堆积那些想法(因为工作永远干不完),当你发现一些你能掌握的东西时,你很可能会转移去全职的做这个工 作.

In fact, I don't think you need to know anything, as long as you can stay alive somehow.

So they're right: you don't need to know math, and you can get by for your entire life just fine without it.

实际上,我认为有些东西你不需要了解,当目前你还能够赖以生存.

所以他们是对的:你不需要了解数学,并且没有她你也能过的很好.

But a few things I've learned recently might surprise you:

  1. Math is a lot easier to pick up after you know how to program. In fact, if you're a halfway decent programmer, you'll find it's almost a snap.

  2. They teach math all wrong in school. Way, WAY wrong. If you teach yourself math the right way, you'll learn faster, remember it longer, and it'll be much more valuable to you as a programmer.

  3. Knowing even a little of the right kinds of math can enable you do write some pretty interesting programs that would otherwise be too hard. In other words, math is something you can pick up a little at a time, whenever you have free time.

  4. Nobody knows all of math, not even the best mathematicians. The field is constantly expanding, as people invent new formalisms to solve their own problems. And with any given math problem, just like in programming, there's more than one way to do it. You can pick the one you like best.

  5. Math is... ummm, please don't tell anyone I said this; I'll never get invited to another party as long as I live. But math, well... I'd better whisper this, so listen up: (it's actually kinda fun.)


    但是最近我学到一些东西可能会让你也感到惊喜:

    在你知道如何编程之后,数学更容易学会.实际上,如果你先学数学,然后半路出家做程序员的话,你会发现编程简直就是小菜一碟.

    学校里教数学的方式都错了.仅仅是教学的方法错了,不是教数学本身错.如果你以正确 的方式学习数学的话,你会学的更快,记住这会更长,但对你作为一个程序员来说也更有价值.

    哪怕了解一点点相关的数学知识就能让你写出可爱有趣的程序,否则会有些小难度.换 句话讲,数学是可以慢慢学的,只要你有时间.

    没人能了解所有的数学,就是最棒的数学家也不是.数学领域正不断的扩展,当人们发明 新的形式去解决自己的问题时.一些给出的数学问题,也正如编程,不止一种方法可以去 解决他.你可以挑个你最喜欢的.

    数学是......嗯,请别告诉别人我说过这个哈;当然我也不指望谁能邀请我参加这样的 派对,当我还活着的时候.但是,数学其实就是......我还是小声的说吧,听好了:(她其 实就是一种乐趣啦!)
The Math You Learned (And Forgot)
你学到的数学(和你忘了的)

Here's the math I learned in school, as far as I can remember:

Grade School: Numbers, Counting, Arithmetic, Pre-Algebra ("story problems")

High School: Algebra, Geometry, Advanced Algebra, Trigonometry, Pre-Calculus (conics and limits)

College: Differential and Integral Calculus, Differential Equations, Linear Algebra, Probability and Statistics, Discrete Math

这儿是我能记得在学校学到的数学:

初中:数,数数,算术知识,初级代数("问题故事")

高中:代数,几何,高等代数,三角学,? (圆锥和极限)

大学:微积分,微分公式,线性代数,概率和统计,离散数学

How'd they come up with that particular list for high school, anyway? It's more or less the same courses in most U.S. high schools. I think it's very similar in other countries, too, except that their students have finished the list by the time they're nine years old. (Americans really kick butt at monster-truck competitions, though, so it's not a total loss.)

上面那个关于高中数学课程单子上所列的,怎么来着?美国高中几乎都是这样的课程设置.我认为其他国家也会很相似的,除了那些在9岁之前就掌握了这些课程的学生.(美国人同时却在热衷于玩魔鬼卡车竞赛,虽然如此,整个来说也算不上什么大损失.)

Algebra? Sure. No question. You need that. And a basic understanding of Cartesian geometry, too. Those are useful, and you can learn everything you need to know in a few months, give or take. But the rest of them? I think an introduction to the basics might be useful, but spending a whole semester or year on them seems ridiculous.

代数?是的.没问题.你需要代数.和一些理解解析几何的知识.那些很有用,并且在以后 几个月里,你能学到一切你想要的,十拿九稳的.剩下的呢?我认为一个基本的介绍可能 会有用,但是在这上面花整个学期或一年就显得很荒谬了.

I'm guessing the list was designed to prepare students for science and engineering professions. The math courses they teach in and high school don't help ready you for a career in programming, and the simple fact is that the number of programming jobs is rapidly outpacing the demand for all other engineering roles.

我现在意识到那个书单列表原是设计来准备给那些以后要当科学家和工程师的学生的.他们在高中里所教的数学课程并不是为你的编程生涯做准备的,简单的事实是多数的编程工作相比其他的工程师角色更加要求快速.

And even if you're planning on being a scientist or an engineer, I've found it's much easier to learn and appreciate geometry and trig after you understand what exactly math is — where it came from, where it's going, what it's for. No need to dive right into memorizing geometric proofs and trigonometric identities. But that's exactly what high schools have you do.

甚至于你打算当一名科学家或者一名工程师,我会发现这更加容易去学习和欣赏几何学和三角在你理解了什么是数学之后-- 数学它如何而来,如何而去,为何而生.不必去专研记住几何上的证明和三角恒等式.但是那确实是高中学校要求你必须去做的.

So the list's no good anymore. Schools are teaching us the wrong math, and they're teaching it the wrong way. It's no wonder programmers think they don't need any math: most of the math we learned isn't helping us.

所以这样的书单列表不再有什么用了.学校教了我们不是最合适的数学,并且方式也不对.不奇怪程序员认为他们不再需要数学:我们学的大部分数学知识对我们的工作没什么大的帮助.

The Math They Didn't Teach You
他们没有教到你的那部分数学

The math computer scientists use regularly, in real life, has very little overlap with the list above. For one thing, most of the math you learn in grade school and high school is continuous: that is, math on the real numbers. For computer scientists, 95% or more of the interesting math is discrete: i.e., math on the integers.

在真实的生活中,计算机科学家有规则的使用数学,对于上面单子里列的有点小小超过. 举个例子,你在中学里学的大部分数学是连续性的:也就是说,数学是真实的数字.而对于计算机科学家来说,他们所感兴趣的部分是占95%也许更多的离散性的:比如,关于整数的数学.

I'm going to talk in a future blog about some key differences between computer science, software engineering, programming, hacking, and other oft-confused disciplines. I got the basic framework for these (upcoming) insights in no small part from Richard Gabriel's Patterns Of Software, so if you absolutely can't wait, go read that. It's a good book.

我打算在我以后blog中再谈一些在计算机科学,软件工程,编程,hacking,和其他常常迷惑的管理的之间的关键差异.我已经从Richard Gabriel的软件的模式这本书中洞察到一个无关细节的基本框架.如果你明显的等不下去的话,去读吧.是本不错的书.

For now, though, don't let the term "computer scientist" worry you. It sounds intimidating, but math isn't the exclusive purview of computer scientists; you can learn it all by yourself as a closet hacker, and be just as good (or better) at it than they are. Your background as a programmer will help keep you focused on the practical side of things.

到现在为止,不要让"计算机科学家"这个词困扰到你.它听上去很可怕,其实数学不是计算机科学家所独有的领域,你也能作为一个黑客自学它,并且能做的和他们一样棒.你作为一个程序的背景将会帮助你保持只关注那些有实践性的部分.

The math we use for modeling computational problems is, by and large, math on discrete integers. This is a generalization. If you're with me on today's blog, you'll be studying a little more math from now on than you were planning to before today, and you'll discover places where the generalization isn't true. But by then, a short time from now, you'll be confident enough to ignore all this and teach yourself math the way you want to learn it.

数学,我们用来建立计算模型的,大体上是离散的整数.这是普遍化的做法.如果正好今天你在看这篇博客,从现在起你正了解到更多的数学,并且你会认识到那样的普遍化是不对的.更多的,你将有信心认为可以忽略所有这些,并以你想要的方式自学.

For programmers, the most useful branch of discrete math is probability theory. It's the first thing they should teach you after arithmetic, in grade school. What's probability theory, you ask? Why, it's counting. How many ways are there to make a Full House in poker? Or a Royal Flush? Whenever you think of a question that starts with "how many ways..." or "what are the odds...", it's a probability question. And as it happens (what are the odds?), it all just turns out to be "simple" counting. It starts with flipping a coin and goes from there. It's definitely the first thing they should teach you in grade school after you learn Basic Calculator Usage.

对程序员来说,最有效的离散数学的分支是概率理论.这是你在学校学完基本算术后的紧接着的课.你会问,什么是概率理论呢?你就数啊,看有多少次出现满堂 彩?或者有多次是同花顺. 不管你思考什么问题如果是以"多少种途径..."或"有多大几率的...",那就是离散问题.当他发生时,都转化成"简单"的计数.抛个硬币看看...? 毫无疑问在他们教你基本的计算用法后他们会教你概率理论.

I still have my discrete math textbook from college. It's a bit heavyweight for a third-grader (maybe), but it does cover a lot of the math we use in "everyday" computer science and computer engineering.


我还保存着大学里的离散数学课本.可能他只占了三分之一的课程,但是它却涵盖了我们几乎每天计算机编程工作大部分所使用到的数学.

Oddly enough, my professor didn't tell me what it was for. Or I didn't hear. Or something. So I didn't pay very close attention: just enough to pass the course and forget this hateful topic forever, because I didn't think it had anything to do with programming. That happened in quite a few of my comp sci courses in college, maybe as many as 25% of them. Poor me! I had to figure out what was important on my own, later, the hard way.

也真是够奇怪的,我的教授从没告诉我数学是用来干吗的.或者我也从来没有听说过.种种原因吧.所以我也从没有给以足够的注意:只是考试及格然后把他们都忘 光,因为我不认为她还和编程有啥关系.事情变化是我在大学学完一些计算机科学的课程之后,也许是25%的课程.可怜的人!我必须弄明白什么对于自己来说是 最重要的,然后再是向深度发展.

I think it would be nice if every math course spent a full week just introducing you to the subject, in the most fun way possible, so you know why the heck you're learning it. Heck, that's probably true for every course.

我想,如果每门数学课都花上整整一周的时间,而只是介绍让你如何入门的话,那将非常不错,这是最有意思的一种假设,那么你知道了你正学习的对象是哪种怪物了.怪物,大概对每一门课都合适.

Aside from probability and discrete math, there are a few other branches of mathematics that are potentially quite useful to programmers, and they usually don't teach them in school, unless you're a math minor. This list includes:

除了概率和离散数学外,还有不少其他的数学分支,可能对程序员相当的有用,学校通常不会教你的,除非你的辅修科目是数学.这些数目列表包括:

  • Statistics, some of which is covered in my discrete math book, but it's really a discipline of its own. A pretty important one, too, but hopefully it needs no introduction.

  • Algebra and Linear Algebra (i.e., matrices). They should teach Linear Algebra immediately after algebra. It's pretty easy, and it's amazingly useful in all sorts of domains, including machine learning.

  • Mathematical Logic. I have a really cool totally unreadable book on the subject by Stephen Kleene, the inventor of the Kleene closure and, as far as I know, Kleenex. Don't read that one. I swear I've tried 20 times, and never made it past chapter 2. If anyone has a recommendation for a better introduction to this field, please post a comment. It's obviously important stuff, though.

  • Information Theory and Kolmogorov Complexity. Weird, eh? I bet none of your high schools taught either of those. They're both pretty new. Information theory is (veeery roughly) about data compression, and Kolmogorov Complexity is (also roughly) about algorithmic complexity. I.e., how small you can you make it, how long will it take, how elegant can the program or data structure be, things like that. They're both fun, interesting and useful.
统计学,其中一些包括在我的离散数学课里,她的某些训练只限于她自身.自然也是相当重要的,但想学的话不需要什么特别的入门.

代数和线性代数(比如,矩阵).他们会在教完代数后立即教线性代数.这也简单,这但相当多的领域非常有用,包括机器学习.

数理逻辑.我有相当完整的关于这么学科的书没有读,是Stephen Kleene写的,Kleene closure 的发明者,我所知道的还有就是Kleenex.这个就不要读了.我发誓我已经尝试了不下20次,却从没有读完第二章.如果那位牛掰有什么更好的入门建议的 话可以给我推荐,给个回复.虽然,这明显是非常重要的一部分.

信息理论和柯尔莫戈洛夫复杂性理论.真不可思议,不是么?我敢打赌没哪个高中会教你其中任何一门课程.她们都是新兴的学科.信息理论是(相当相当相当相当 难懂)关于数据压缩,柯尔莫戈洛夫复杂性理论是(同样非常难懂)关于算法复杂度的.也就是说,你要把它压缩的尽量小,你所要花费的时间也就变的越长,同样 的,程序或数据结构要变得多优雅也有同样的代价.他们都很有趣,也很有用.

...

For More ...
全文在这...




No comments: