CMU大师对软件工程师的系统建议

2016-04-16 新智元 新智元

 新智元翻译1

来源:Quora

【新智元导读】软件工程师想学机器学习,有什么好建议?机器学习专家、卡耐基梅隆大学教授、1-Page公司首席科学家 Alex Smola 在 Quora 上给出了系统、具体的回答,还列出了推荐图书和论文。当然,如果你认为还有其他值得推荐的内容,留下评论,欢迎补充!

 

问题:你对想要学习机器学习的软件工程师有哪些建议?(What would be your advice to a software engineer who wants to learn machine learning?)

Alex Smola: 这 很大程度上取决于软件工程师的背景及其具体想掌握机器学习的哪部分知识。简而言之,我们以一名拥有四年本科学位和一到两年行业经验的初级程序员为例,并假 设这位程序员希望学习计算广告学、自然语言处理、图像分析、社交网络以及搜索和排序。那么,我们先说掌握机器学习有哪些基本要求(致学术界同仁的免责声 明:下列内容并不完整,如果未列入你的论著,在此提前致歉)。

线性代数

机器学习以及数据统计和优化都需要这方面知识。这也是为什么GPU(图形处理器)远比CPU(中央处理器)适合进行机器学习。作为程序员,至少需要基本掌握以下内容:

  • 标量、向量、矩阵、张量
    把它们看作你可以组建并相互转换的零维、一维、二维、三维和更高维物体,有点像乐高玩具,它们使得基本的数据转换成为可能。
  • 特征向量、范数、矩阵近似、分解
    这些概念本质上是让你习惯线性代数的用法。如果你希望分析一个矩阵的情况(比如,检查为何循环神经网络中出现梯度消失,为何增强学习算法中控制器出现分歧(diverge)),你就必须要理解在应用矩阵和向量时可能出现的增长和减小范围是多少。如果你希望代码表现出色和稳定,那么低秩等矩阵近似算法或乔列斯基分解就很有用。
  • 数值线性代数

    如果你需要做很多最优化计算,那么这部分知识就很有用。对核方法和深度学习来说如此,对图像模型和采样器而言则不那么重要。

最优化(和基本演算)

在许多情况下,设置要问的问题是相当容易的,但得出答案却没没那么简单。举例来说,如果要对一些数据进行线性回归(即找到一条线),你可能希望尽量减少与观测值的距离平方的总和。同样,如果想获得一个好的点击率预测模型,你就得最大化对于人们点击广告概率预测的准确性。这意味着我们通常会有一些目标、一些参数和大量数据,而我们需要通过一种方式来解决问题。这一点很重要,尤其因为我们常常不会有一个闭合式解决方案。

凸优化

很多时候,在优化问题不存在许多局部解决方案的情况下是不错的。当问题为凸时就会发生这种情况。(若你能在一个集合内任意两点间画出一条直线且这条直线处于该集合内,则这一集合就是凸的。若你能在图上任意两点间画出一条直线且这条直线位于图形上方,则这一函数是凸的。)

也许这一领域的经典书籍是这本由Steven Boyd和Lieven Vandenberghe所撰写的 Convex Optimization 。本书免费且非常棒。(回复041501下载,共730页)此外,Boyd的课程里也有许多很不错的幻灯片集。Dimitri Bertsekas也已经编写了关于最优化、控制等的宝典。这些应该足以供任何人开始了解这个领域了。

随机梯度下降算法

这一算法早期在很大程度上只是凸优化的一种特殊情况(至少早期定理是这样的),但最近发展很大,并且绝非是由于数据的增多。原因是,想象一下你有一些数据要处理,而你的算法需要将所有的数据都浏览一遍后才能继续新的步骤。而如果我故意给你10份同样的数据,那么你就必须重复10次工作,却没有什么实质性用处。显然,现实情况不会如此糟糕,但如果你需要操作多次小的新步骤,而每个小步骤之后都需要观测,它就能帮上忙。这在机器学习领域带来了相当大的变革型影响。此外,许多关联算法都容易得多。

我们面临的挑战是如何将其并行化。也许这个方向的第一步之一就是我们2009年的 Slow Learners are Fast 论文(回复041502下载)。最新版本是无锁变异型,例如Niu等于2013年所著的Hogwild论文(回复041503下载)。简而言之,这些算法通过人工计算机计算局部梯度并以异步方式更新共识参数集来运作。

另一个挑战是如何应对控制过度拟合的各种方法,例如通过正则化来实现。对于凸罚函数来说,有一种所谓近端梯度算法。一种比较流行的选择是Amir Beck和Marc Teboulle的FISTA算法。部分代码参见Francis Bach的SPAM toolbox(http://spams-devel.gforge.inria.fr/)。

非凸方法

许多机器学习问题都是非凸问题。从本质上来说,任何与深度学习相关的问题都是。但聚类、主题模型和几乎任何潜变量方法和当前几乎所有在机器学习领域有意思的问题也都是。部分加速技术可以提供帮助。例如,我的学生 Sashank Reddy最近展示了在这种情况下如何获得收敛的良好比率。

有许多被称为谱方法的技术可以使用。 Anima Anandkumar在她最近的Quora session中已经非常详尽地回答了这一问题。请参阅她的回复,因为其回复无比详细(https://www.quora.com/profile/Anima-Anandkumar-1)。概括地说,凸问题并非唯一能够确切解决的问题。在某些情况下,可以得出一个难题的数学表达式以显示只有某一组特定的参数能找到所有的集群、主题、相关比例、神经元或所有数据中的任何东西。这仅在你有能力且愿意花很多数学的功夫时才有效。

在培训深层网络方面(Deep Networks),最近有许多新技巧。我会在后面的内容中提及这些,但在某些情况下,目标不仅仅是优化,而是制定出一套具体的解决方案(几乎像是那本题为The Journey is the goal《旅程即是目的》的书)。

系统

机器学习正在成为大部分有关于人、测量、传感器和数据的关键要素,这与过去十年标度算法(scaling algorithms)的突破密不可分。Jeff Dean去年出了六套机器学习教程,也并非偶然。如果有人过了十年与世隔绝的生活,在这里给补充一下,他就是MapReduce、谷歌文件系统、BigTable和其他十多项成就了谷歌的关键技术背后的男人。

说笑归说笑,关于系统的研究为解决分布、异步、容错、可扩展和简易问题提供了宝贵的工具。后者是机器学习研究人员常常忽视的一点。简易是一种特性,不是一个错误。一些基本的技巧将带给你很多:

分布式哈希表

这实质上是如分布式缓存(memcached)、dynamo、 pastry和orceph等方法

构建的基础。它们都解决同一个问题——如何在避免访问之前数据输往的中央储存库的情况下向多台机器发布数据。为了达到这一目的,你需要将地址以一种随机又确定的方式编码(也就是哈希)。此外,你需要解决如果任何一台机器出现故障时谁将负责处理。

这就是我们在参数服务器(Parameter Server)中使用的数据布局。我的学生李沐是这个项目背后的智囊。工具组合参见DMLC(http://dmlc.ml/)。

一致性和信息传送

所有这一切的教父是Leslie Lamport的PAXOS 协议。它解决了在不是所有机器任何时候都可用或有些机器出现故障时如何达成共识的问题(是的,我在这儿就一句带过了)。如果你曾经使用过版本控制,你可能靠直觉知道它是如何工作的——大量机器(或开发者)产生更新(或代码段),而你希望将这些都结合成有意义的信息(例如,你不该两次运用微分),但又不需要所有机器与其他所有机器一直传递着信息。

在系统中,解决方案是使用向量时钟(参见例子:谷歌的Chubby)。我们在参数服务器中使用它的一种变体。关键的区别在于(均引自李沐)在参数范围内使用向量时钟。这可以确保不会因为时间标识耗尽内存,就像一个文件系统并不需要为每一个字节都记录一个时间标识。

容错、Scaling和云


最简单的自学方法就是在亚马逊AWS、谷歌GWC、微软Azure, 或你可以找到的各个其他平台上运行算法。当你第一次启动1000个服务器,意识到你正在向一个实际上的合法僵尸网络发送大量指令时,还是很令人激动的。我在谷歌工作时,我们控制了欧洲某处了5000个高端机器,用于主题模型中的推理。我们所调用的能源价值如果和一个核电站相比,也要占很大的比重了。我的经理当时把我叫到一旁,说这真是个昂贵的实验……

或许最容易起步的是学习docker。为了让scaling更容易,人们热火朝天地开发了不少工具。Docker Machine和Docker Cloud或许是近来最好的新工具,使你能像更换打印机驱动一样方便地连接不同的云端。

硬件


这似乎显而易见,但如果你了解自己算法所运行的硬件,的确会很有帮助。这会让你知道你写的代码是否已经接近峰值性能。初学者可以阅读Jeff Dean的Numbers every engineer should know一书。我在面试时最喜欢问的问题(曾经)是,应聘者的电脑有多快。知道算法的局限大有裨益:是缓存、内存带宽、延迟时间还是硬盘等等。Anandtech上有非常棒的介绍性文章,以及对微处理器架构等相关内容的测评。只要英特尔、ARM、AMD发布新硬件时,都可以去看一看。

统计学


我特意把这点留到最后。因为每个人都知道这是关键(的确如此),然后就忽略了其他所有东西。统计学确保你能问出好问题,同时帮助你理解自己在数据建模时用了多少估算。
从图像模型、核方法到深度学习等等,很多改进其实来自提出对的问题,也即定义了合理的优化目标,从而进行最优化。

Statistics Proper


Larry Wasserman的《统计学完全教程》(All of Statistics)是不错的入门教材。另外也可以看一下 David McKay 的 Machine Learning 一书。该书免费(篇幅很长、内容全面,回复041504下载)。其他还有不少好书,比如说 Kevin Murphy, Chris Bishop, Trevor Hastie, RobTibshirani 以及 Jerome Friedman 的著作The Elements of Statistical Learning:Data Mining, Inference, and Prediction。是的,Bernhard Scholkopf 和我也写了一本Learning with Kernels

随机算法和概率统计


本质上就是用计算机科学解决一样的问题,关键区别在于他们是设计算法的一种工具,而非用来适配参数的一个问题。我特别喜欢 Michael Mitzenmacher 和Eli Upfal 写的书Probability and Computing: Randomized Algorithms and Probabilistic Analysis ,非常易读但同时谈到了许多深刻的问题。如果你想更深入地了解这些工具,还有 Rajeev Motwani 和 Prabhakar Raghavan 的书Randomized Algorithms,写得很好,不过如果你没有较好的统计学背景,可能较难读懂。

我的回答可能已经够长了,很少有人会一直读到这里。所以我接下来说得比较简短。网上有许多非常棒的视频资料。许多教授现在有自己YouTube频道,并上传自己的课程视频。如果你在学习比较复杂的工具,这些视频会有所帮助。我的视频在这里(https://www.youtube.com/user/smolix/playlists),Nando de Freitas的要好很多。

 

其他还有一些工具。DMLC是好的起点,其中有许多用于分布式可扩展推理的算法,包括基于MXNET的神经网络。

 

还有很多没谈到的:编程语言、数据源等等。但这个回答已经太长了,我会在其他问题中继续讨论。

附录,Alex Smola 著书:

  • G. Bakir, T. Hofmann, B. Schölkopf, A.J. Smola, B. Taskar, and S.V.N. Vishwanathan, editors. Predicting Structured Data. MIT Press, Cambridge, MA, 2006.
  • S. Mendelson and A. J. Smola, editors. Machine Learning, Proceedings of the Summer School 2002, Australian National University, volume 2600 of Lecture Notes in Computer Science. Springer, 2003.
  • B. Schölkopf and A. J. Smola. Learning with Kernels. MIT Press, 2002.
  • B. Schölkopf, C. J. C. Burges, and A. J. Smola, editors. Advances in Kernel Methods–Support Vector Learning. MIT Press, Cambridge, MA, 1999.
  • A. J. Smola, P. L. Bartlett, B. Schölkopf, and D. Schuurmans, editors. Advances in Large Margin Classifiers. MIT Press, Cambridge, MA, 2000.

Slow Learners are Fast 论文(回复041502下载)。最新版本是无锁变异型,例如Niu等于2013年所著的Hogwild论文(回复041503下载)

关于这一讨论,你认为还有其他值得推荐的内容?留下评论,欢迎补充!

购书可扫二维码或点击 阅读原文 获取促销链接

程序员,你能真正掌握多少编程技术?

来源:Andrew Wulf

译文:伯乐在线 – HansDo

链接:http://blog.jobbole.com/99680/

我总能看到一些公司在招聘广告里这样描述他们的岗位要求:“有丰富的从零开始构建 iOS 及 Android 应用的经验;精通移动及 Web 技术,包括 Java、HTML5、CSS3、JavaScript 和 AJAX。“

(可世上根本)没有这样的人:一个人只能真正精通一个(技术方向),而在其他方向上技术平平。你也可以在精通一门技术后转而钻研另一种技术,(但这会让你很快)忘掉前者的很多细节。这样或许已经足够让你轻松唬住很多人,让他们认为你无所不能、无所不晓——但真遇上棘手的问题,你也只能靠运气了。

今时不同往日,当代任何一个主流领域的技术都相当复杂,并且不断地变化,需要人投入大量时间。只是利用业余时间学习的话,连保持跟进某个技术领域的最新动态都很困难,更不用说从零开始“精通”这项技术了。因此,只有参与一个真实的项目才能让你真正学习一套新的(技术)环境。而能够同时参与开发大型原生 Android、iOS 应用以及响应式 Web 客户端程序的又有多少人?

在过去 34 年的程序员生涯里,我很少同时在多个技术领域上工作。我的第一份工作是在 Supermini 上开发,后来用 Apple 写 6502 汇编、在PC 上写 Pascal,我的两个创业公司的开发环境都是 Mac 和 C。在为别的公司(包括 Apple)工作时, 我先后用过 C、一点 C++、Objective-C/WebObjects, 然后转向基于 Java 的 Web 前后端开发(但很少同时开发这两者)。再后来,我写了一些 JavaScript,做过基于 C++ 的游戏编程, 最后,就是我现在做的: Objective-C 和 iOS。为了掌握各种新知识,这中间的每次技术转变我都花了几年时间一边做一边进行大量的学习。

如果出于某些原因,有人真的能够同时精通 Android 和 iOS,甚至是 Web ,那么作为一个真正的全才,我想他的期望薪酬会远远高出多数公司愿意给出的价格:公司实际上只想以最低的工资水平招几个“什么都能做”的人以节约成本。我至今无法理解有人能够同时成为许多方面的专家,以及他们怎么能同时掌握不同的技术、开发不同平台的应用并与时俱进。我认识一些才华横溢的人,但我不记得有哪一个能够像耍杂耍一样将多种技术玩弄于股掌之上,并开发出能体现精湛技艺的应用。

好吧,可能会有一些例外吧,但是我始终认为多数人做不到这一点。一个人固然能先精通一种技能,然后再尝试精通另一个,但这个过程中必然会忘记很多前面的知识。去年我有几个月无所事事,等着被公司解雇(公司所有的技术都早已经落伍被替代了,他们开始把整个品牌打折出售,所以显然我的下岗也只是早晚的问题)。我花了一个月做了一些 C++ 开发,然后是 Node.js, 最后还搞了一段时间 Swift。今年再回顾这些学过的技术时(我的新工作用的是 Objective-C),我发现我已经忘了之前学到的大多数内容。如果不是经常使用的东西,肯定会很快被忘到脑后。当我用 PHP 重新搭建我现在这个博客系统时,我掌握过的各种语言在我脑袋里全都糊成了一片。

如果你用过 Objective-C、然后使用 Swift 做 iOS 开发的话,那至少两者还有一部分重叠。不过 Android 开发跟 iOS 相比可不仅仅只是另一种语言的差别了:你需要掌握完全不同的开发工具、布局方法,以及如何支持多个版本的操作系统,并兼容 24000 多种安卓设备。另一方面,单单要跟上今年六月 WWDC 里发布的新变化就要花很大的功夫,Apple 发布的示例代码并不兼容最新 beta 版的 Xcode 更是雪上加霜。 就算你能不写代码,每天能看完最新的视频、读完最新的文档和示例代码,不过这样你又哪来的勇气称自己是个专家呢?

除了安卓和 iOS 这两个截然不同的复杂移动开发环境,现在的 Web 开发也添了不少乱,尤其是此起彼伏层出不穷的各种 JavaScript 框架, 要跟随它们的变化真得有三头六臂才行。而且从跟我共事过的 JavaScript 程序员来看,他们甚至连一个框架的变化都跟不上(嗯,我说的就是 AngularJS)。

所以如果你找到这样一个人选,他(她):iOS 和 Android 开发不在话下、JS 桌面/移动端 Web 编程小菜一碟;熟练运用现代风格的 API 又能兼容各个老版本 OS,各种 UI 设计方式优劣如数家珍,诸多浏览器特性及安卓设备特例了然于胸,还总能以破纪录的时间交付无 Bug 的产品…那你就真的赚大了——对了,他应该还愿意以低于市场价为你工作。

回想我开始编程那会,一切都原始而简单。我只需要掌握一种语言,一种操作系统,而不需要任何框架。即使在我的两家初创公司,我也只需要掌握 C 语言,了解 Macintosh 和偶尔的一些 68K 汇编。时代变了,但我们还是只有一个并不遵循摩尔定律、也没法升级的大脑。

最后,假如你能(真正的)同时做 Android、iOS 和移动 Web 开发,并写出大师级的作品的话,我要向你致敬!当然同时,我也希望你也能拿到你应得的三倍酬劳。

【伯乐在线小编补注】:本文作者 Andrew Wulf 是一位入行 35 年的程序员。推荐他最近一篇在 HN 和 Reddit 引发热议的文章:《写了 35 年代码的老程序员的最大遗憾》。

译者简介


HansDo:游走于Web前后端,一直在野路子上摸索着。对美术和数学有心无力(・-・*),尽其所能做一个生产者。

什么样的电子积木,让硬件创业变得如此简单?

2016-04-28 硅谷密探 硅谷密探

今天,小探要介绍一款电子积木。

咋一看,像乐高玩具。但其实,学问大了。

这款电子积木套件叫mCookie,是一套可编程的芯片。mCookie的每一片电子积木都有自己的功能,譬如WiFi模块,蓝牙模块,声音模块,GPS模块,等等。

先来看看怎么耍

mCookie的边框有着磁性化材料设计,因而,你在拼接时,不再需要焊接电路,而是直接把一个个mCookie粘贴在一起。

拼接,折叠,翻转,是如此的轻巧自如。

然后,把mCookie的模块(控制,感应,机动等模块拼在一起)装载到乐高积木,或者四轴无人机模型上,

本身不会动的模型就可以飞起来了!

想想看,从前到后,就是把需要的几个功能模块拼起来,再套上模型,就可以完成一个无人机这么复杂的智能硬件了。真的很神奇啊!

没错,mCookie可以帮助你最轻量化地制作智能硬件的原型产品。

譬如,这个音乐盒,只需要7个mCookie积木就可以制作完成:

而这个小型气象站也就是四五块积木就拼接完成了:

因而,mCookie无论用于电子电路及编程的教育,还是硬件创客的实践上,都是非常轻量级高质量的工具。而其实,mCookie又只是 Microduino 旗下的最新系列产品。

 那么,什么是Microduino?

Microduino是完全兼容Arduino的开发板,功能与Arduino无异。只不过,它们更小巧,有着许多功能模块。

Microduino有多牛?

清华大学专门开设了一门2个学分的课程,让学生学习使用Microduino。

Microduino还应用到了拯救秃鹫这一濒临灭绝的物种的挑战中,Discovery探索频道也报道了。

另外,雀巢咖啡也用了Microduino的产品做了一次很好的推广营销。

如今,Microduino的用户已经覆盖了六大洲,现在就差南极洲一个就能集齐七大洲了。(不知道会不会召唤出神龙呢?)

核心创始人也是大有来头

Tiki Wang,Bin Feng是复旦大学的同学,96年电子材料专业。后来Tiki去了清华读了电子设计的硕士;而Bin Feng则去了UCSD(加州大学圣地亚哥分校)念研究生,后来走上了市场和销售的道路。

两条完全不同的发展道路,却又最终有了交集。他们再次相聚,决心一起做翻事业,于是,拉上了朋友老潘,三个人培育了Microduino这个项目。

老潘也是个牛人,据说曾经有个团队做了3个月也没搞定的电路板,老潘一人一天就搞定了。神一般的技术达人!

编程需要知道多少数学知识?

英文:Al Sweigart

译文:伯乐在线 – 唐小娟

链接:http://blog.jobbole.com/19348/

下面是我在Reddit的子论坛 r/learnprogramming 看到的几个帖子:

  • “要成为一个优秀的程序员需要学习多少数学?”
  • “我应该重新学习数学吗?”
  • “这可能是我提问过的最愚蠢的一个问题。成为一个优秀的程序员究竟需要学习多少数学?”

数学和编程有一种容易让人误解的联系。许多人认为在开始学习编程之前必须对数学很在行或者数学分数很高。但一个人为了编程的话,需要学习多少数学呢?

(【伯乐在线编注】:本文仅为 Al Sweigart 一家之言,再推荐 Alan Skorkin 的这篇文章《数学是成就卓越开发人员的必备技能》。)

实际上不需要很多。这篇文章中我会深入探讨编程中所需要的数学知识。你可能已经都知道了。

对于基本的编程,你需要知道下面的:

  • 加减乘除 — 实际上,电脑会帮你作加减乘除运算。你仅需要知道什么时候运用它们。
  • 模运算 — 模运算是用来计算余数,它的符号通常用%百分号来表示。所以23除以7等于3,余数是2。23 mod 7 = 2。
  • 判断是奇数还是偶数的模运算 — 如果你想知道一个数是奇数还是偶数,用它mod 2来作模运算。如果结果是0,它就是偶数。如果结果是1,就是奇数。23 mod 2等于1,所以23是奇数,24 mod 2等于0,24是偶数。
  • 对一个数作百分数运算,就是用这个数来乘以一个百分数。譬如你要得到279的54%,就是用0。54*279。这就意味着为什么1.0等于100%,0.0等于0%。
  • 知道负数是什么。负数乘以负数等于正数。负数乘以正数等于负数。就这么简单。
  • 知道笛卡尔坐标系统。在编程中,(0,0)代表屏幕左上角,Y坐标的正轴往下。
  • 知道勾股定律,因为它是用来计算笛卡尔坐标中两点之间的距离的。勾股定律a^2 + b^2 = c^2。(x1, y1)和(x2, y2)两点之间的距离等于( (x1 – x2)^2 + (y1 – y2)^2 )。
  • 知道十进制、二进制、十六进制。十进制就是我们通常用的十个数:0-9。通常认为这个十进制系统是人类发明的,因为我们有十个手指。

电脑采用二进制数据,只有两个数字:0和1。这是因为我们用电子元件来构建的电脑,让电脑只识别两种状态更便宜些(一种代表0,另一种代表1)。

数是一样的,但是在不同的进制系统里的表现形式不同,因为不同进制包含的数的个数不同。十六进制比十进制多六个数字,所以我们用A-F表示超过9的数。能够表现这些进制系统的最简单方法就是用一个计数器(odometer)。下面三种不同的计数器显示的是同一个数,但在不同的进制系统中的形式不同:

你甚至不需要知道怎么从一个进制系统转换成另一个系统。每种编程语言都有帮你转换的函数。

(提示一下,十六进制的使用是因为一个十六进制的数可以表示四个二进制的数。因为十六进制中的3和二进制中的0011对应,十六进制的A和二进制的1010对应,所以十六进制中的3A(十进制的58)可以写成二进制的00111010。十六进制在编程中的使用是因为它是对二进制的简化。没人喜欢写出的数全是0和1。)

就是这么多了。除了进制系统以外,你可以已经知道编程所需的数学知识了。虽然普遍认为编程需要学习许多数学,但实际上并不需要那么多。你可能为了编写一个程序,譬如说地震模拟器,而需要学习数学。其实你更需要学习地震的数学,而不是因为要编写地震模拟器而学习数学。

某些编程领域中更为高级的数学

有一些领域中需要更多的数学知识(但95%的软件中,你都不需要知道它们。)

某些编程领域中更为高级的数学

有一些领域中需要更多的数学知识(但95%的软件中,你都不需要知道它们。)

3D游戏和3D绘图 — 3D通常需要涉及三角函数和线性代数(用矩阵来解决问题的数学)。当然,有许多3D图形库已经实现了这些数学编程,你不需要知道这些数学。

2D物理(譬如愤怒的小鸟)和3D物理(譬如许多流行的3D游戏) — 为了写涉及到物理的编程,你需要学习一些物理方程和公式(尤其是力学,如弹力,重力,球滚下斜坡等物理。)然而,已经有一些物理引擎和软件库帮你实现了,所以你也不需要知道游戏(如愤怒的小鸟)中的物理公式。

加密学 — 事实上我指的是RSA。你需要知道质数的有关知识,以及如何求最大公约数(其实是个非常简单的算法,还有许多编程语言中都有gcd()函数,帮你求解最大公约数)其他的编码大部分就是将数据按照某种步骤挪动。举个例子,下面的flash就是AES“Rijndael”编码的步骤。所有的步骤包含用一些数减去另一些数,将行向上移,将列数字打乱,再作简单的加法运算。

如果你要写你自己的加密算法(通常不需要你做,因为已经有许多很好的工具了,并且如果你不是加密学的专家的话,你的程序也许会很容易被破解。)如果你仅仅想加密一些数据的话,已经有许多加密和解密的软件库了。

所以就算是以上的情况,你也不需要真正的知道3D图像,物理或者加密的数学。你只需要学习运用软件库就行了。

编程需要学习什么?

你需要学习的是如何建模和设计算法。这意味着,如何将真实世界的运算或者数据处理抽象出来,写出代码,让计算机来帮你运算。例如,在游戏“龙与地下城”(Dungeons and Dragons)中,角色和怪兽都有许多不同的战斗统计值:

● 生命值(Hit points)是一个人死前所能经受的伤害值。越高的生命值就意味着可以经受更多的伤害。

● 防御等级(armor class)是对你的武器防御能力的量度。防御值越低,武器的防御能力越高。

● THAC0(读作“thay-co”,“To Hit Armor Class 0”),是对一个人进行有效攻击的能力的测量。THAC0值越低,攻击越准。

● 武器的攻击力用类似1d6+2来表示,它表示摇一个六面骰得到的值,然后再加2。2d4就是摇2个4面骰,然后将它们相加。(“龙与地下城”采用的是4,6,8,10,12和20面骰。)

要看攻击者打防御者,让攻击者摇动一个20面骰。如果这个数字大于或等于攻击者的THAC0减去防御者的防御能力,那么这个攻击就成功,防御者将受到伤害。不然,防御者就阻击了这个攻击,并且不费血。

我们假设两个人物,Alice和Bob,她们具有以下值:

● Alice: HP 14, AC 5, THAC0 18, DAMAGE 1d6

● Bob: HP 12, AC 7, THAC0 16, DAMAGE 2d4

所以Alice有更多的生命值和防御力(记住,AC越低越好)。但是Bob更可能成功击中对方(记住,THAC0越低越好),并造成更多的伤害。我们说Bob的攻击力更强是因为2d4可以造成2-8点伤害,而Alice的1d6只能造成1-6点伤害。(如果你懂统计学,你可以计算出Bob的期望伤害值是5,比Alice的3。5要高。)

你会打赌Alice或者Bob会赢得比赛对吗?很难讲谁会赢,他们看起来势均力敌。尽管可能你的统计学学得很好,但做这个计算将会十分头疼。编写“龙与地下城”的程序(模拟战斗过程),你甚至不需要知道统计学。仅仅需要运行几百次或者几千次战斗,看看谁赢得更多。

下面是用Python写的程序:(下载代码 http://inventwithpython.com/dnd_simulator.py)

import random, copy

NUM_FIGHTS = 1

VERBOSE = True

# Lower thac0 and lower ac values are better. Higher damage & hp values are better.

aliceTemplate = {‘name’: ‘Alice’, ‘hp’: 14, ‘ac’: 5, ‘thac0’: 18, ‘dmgnum’: 1, ‘dmgsize’:6, ‘dmgmod’: 0}

bobTemplate   = {‘name’: ‘Bob’,   ‘hp’: 12, ‘ac’: 7, ‘thac0’: 16, ‘dmgnum’: 2, ‘dmgsize’:4, ‘dmgmod’: 0}

def display(s):

if VERBOSE:

print(s)

def attack(attacker, defender):

if random.randint(1, 20) >= attacker[‘thac0’] – defender[‘ac’]:

damage = 0

for i in range(attacker[‘dmgnum’]):

damage += random.randint(1, attacker[‘dmgsize’])

damage += attacker[‘dmgmod’]

display(‘%s (%s hp) hits %s (%s hp) for %s points of damage. %s is reduced to %s hp.’ % (attacker[‘name’], attacker[‘hp’], defender[‘name’], defender[‘hp’], damage, defender[‘name’], defender[‘hp’] – damage))

defender[‘hp’] -= damage

else:

display(‘%s misses %s.’ % (attacker[‘name’], defender[‘name’]))

aliceWins = 0

bobWins = 0

for i in range(NUM_FIGHTS):

display(‘======================’)

display(‘Start of combat #%s’ % (i+1))

alice = copy.deepcopy(aliceTemplate)

bob = copy.deepcopy(bobTemplate)

while True:

attack(alice, bob)

if bob[‘hp’] <= 0: break attack(bob, alice) if alice['hp'] <= 0: break if alice['hp'] <= 0: display('Alice has died.') bobWins += 1 if bob['hp'] <= 0: display('Bob has died.') aliceWins += 1 print() print('Alice won %s (%s%%) fights. Bob won %s (%s%%) fights.' % (aliceWins, round(aliceWins / NUM_FIGHTS * 100, 2), bobWins, round(bobWins / NUM_FIGHTS * 100, 2)))

当运行这个程序时,你会看到:

Start of combat #1

Alice misses Bob.

Bob (12 hp) hits Alice (14 hp) for 6 points of damage. Alice is reduced to 8 hp.

Alice misses Bob.

Bob misses Alice.

Alice misses Bob.

Bob misses Alice.

Alice misses Bob.

Bob misses Alice.

Alice (8 hp) hits Bob (12 hp) for 5 points of damage. Bob is reduced to 7 hp.

Bob misses Alice.

Alice misses Bob.

Bob misses Alice.

Alice misses Bob.

Bob (7 hp) hits Alice (8 hp) for 2 points of damage. Alice is reduced to 6 hp.

Alice (6 hp) hits Bob (7 hp) for 6 points of damage. Bob is reduced to 1 hp.

Bob misses Alice.

Alice (6 hp) hits Bob (1 hp) for 1 points of damage. Bob is reduced to 0 hp.

Bob has died.

Alice won 1 (100.0%) fights. Bob won 0 (0.0%) fights.

但是可能Alice正好在某一次战斗中很幸运。让我们关掉输出再重新运行程序(在屏幕输出比运行程序更耗时间),当战斗次数达到30,000次时(将NUM_FIGHTS改成30000,VERBOSE变量变成False):

Alice 赢得12909 (43.03%)次战斗. Bob赢得17091 (56.97%)战斗。

所以我们看到使用上面的数值,Bob稍稍占先。电脑进行了30,000次战斗模拟。如果我们用笔和纸还有骰来进行30000次战斗模拟的话,可能需要几个月来算出结果,而我的笔记本仅用了8秒。

那么如果Alice的生命值从14增加到20呢。谁会赢呢?

Alice赢得19438 (64.79%)次战斗. Bob赢得10562 (35.21%)次战斗.

我们看到给Alice增加6点生命值,结果倒过来了,Alice占先了。那么如果Alice的生命值只是增加到16呢?

Alice赢得15176 (50.59%)次战斗啊. Bob赢得14824 (49.41%)次战斗.

所以仅仅增加2个生命值,就已经足够扳回Bob更强攻击力的胜算。

来看这个程序,它只用了加减乘除来计算一个百分比。甚至在更复杂的程序中,需要表示magic spells,治愈部位,多次攻击,在战斗中切换武器等不同效果时,我们也不需要知道更多的数学了。

当然,去学更多的数学吧。可以让你成为更出色的程序员。但是为了学习编程需要多少数学?真的非常少。

更新:我想我应该在基本知识点中增加基本代数,但仅仅需要知道的如 如果X * 3 = 12,知道X等于4。

——————

虽然大多数开发人员会告诉你,他们在工作中从来不需要数学,但是经过一番沉思后,我有了个想法:就是反马斯洛的锤子理论:当你有一把锤子,你会把一切看成是钉子。

本文仅为 Al Sweigart 一家之言,再推荐 Alan Skorkin 的这篇文章《数学是成就卓越开发人员的必备技能