非商业转载请注明做译者、出处,并保留本文的原始连接:http://www.ituring.com.cn/article/198010html
王晓华是一位热衷于算法研究的程序员,他是CSDN算法专栏的超人气博主,也是《算法的乐趣》一书的做者。他2005年毕业于华中科技大学,目前在中兴通信上海研发中心从事光纤接入网通信设备开发,担任EPON(以太网无源光网络)业务软件开发经理,参与开发的PON设备在全球部署过亿线,为数亿家庭提供宽带接入服务。程序员
王晓华最大的乐趣就是用程序解决生活中的问题。当年为了方便使用Visual Studio 6.0开发软件,他特地编写了一个tabbar插件,并随后开源了这个软件。为了文档安全,他开发了一个基于layerFSD技术的透明文件加密系统,在朋友圈内广为流传。后来他在使用Source Insight软件的时候,又之外挂的形式为Source Insight开发了TabSiPlus插件,受到了不少程序员朋友的欢迎。算法
问:你从何时开始迷上了算法?编程
这个要从上大学时候提及了。像我这样的懒人以为拼音输入法太繁琐,因而就去学“表形码”(固然,由于笨的缘由,如今还在用拼音输入法)。资深一点的游戏玩家都还记得,那个时候为了玩中文DOS游戏,不少人都装了UCDOS中文环境,UCDOS没有表形码,可是支持经过码表文件增长自定义输入法。我研究了Windows上的表形码码表文件(老师给的,适用于Windows 3.x版本)和UCDOS码表文件的格式,发现两者有必定的类似性:都是文本文件,有固定的格式,每一行由一组编码和一个字或词组成一个编码对。两者的区别仅仅在于一个文件是编码在前,对应的字或词在后面,另外一个恰好相反,字或词在前,对应的编码在后面。码表文件有十几万行,手工修改是不可能了,恰好当时在上C语言课,就决定写个程序来作这个事情。安全
第一次运行我写的程序,十几秒钟都没有结束,我以为程序挂了,因而我就“Ctrl+Break”了,由于我以前写的C语言做业,历来没有哪一个程序运行时间超过1秒钟的。可是分析代码又以为没有问题,看了遗留在磁盘上的码表文件,发现转换了几千行,而且内容是对的。因而再次运行程序,等了2-3分钟,程序结束了。我急不可待地将获得的码表文件导入UCDOS,发现能够用,当时就感受很是有成就感。这是我第一次为解决一个实际的问题编写算法,尽管当时尚未算法、软件的概念,可是隐隐约约就以为这东西有用,不是只用于完成做业,还能够解决实际的问题。后来就是接触更多的有用算法以及各类算法竞赛,一直到如今,写个程序解决问题几乎成了一种习惯。微信
问:《算法的乐趣》这本书在内容的设计上和其余同类型的书相比,最大的特色是什么?网络
在我学习算法的过程当中,兴趣是最大的推进力,兴趣来自于我以为这东西能解决问题,对本身有用。可是在我写《算法专栏》博客的时候,网上能看到的博客都是对各类竞赛题目的解答,这些竞赛题目虽然有趣,可是对不少人来讲依然抽象,与程序员们平常的工做关系不大,难以提起大多数人的兴趣来学习。因而我就想,如过能经过一些现实中广泛应用的算法作切入点,经过这些例子让你们以为算法是有用的,并经过这个来吸引你们关注算法,学习算法,从而达到提升能力的做用,岂不是个很好的主意?数据结构
在策划《算法的乐趣》这本书的时候,我依然沿用了这种思想。选取的例子都是你们生活中没有在乎,可是却到处都会遇到的算法,但愿以此来“鼓动”起你们学习算法的兴趣。因此本书只用了不多的章节介绍算法的本质和设计算法的经常使用思想,把主要内容放在介绍这些生活中的趣味算法的解决过程,并在这个过程当中给出各类算法设计中经常使用的模式、技巧和思想,提醒读者在阅读过程当中不只关注本题的解决,更要关注解决这个问题过程背后的思想,既培养了兴趣,又提升了解决问题的能力。框架
问:算法学习是一条并不简单的路,请问你是否有其余优秀的算法书愿意推荐给读者们?阅读这些书的顺序和注意事项是什么?机器学习
就个人经验而言,在计算机上学习算法首先须要熟悉编程语言和数据结构,关于编程语言和数据结构有不少经典的书籍,我就很少介绍了。但就算法而言,我看过的书有Cormen的《算法导论》、Knuth的《计算机程序设计艺术》、Weiss的《数据结构与算法分析》、Levitin的《算法设计与分析基础》、Kleigberg的《算法设计》等等。想参加算法竞赛的同窗能够参考刘汝佳等人编写的《算法艺术与信息学竞赛》,以及《ACM国际大学生程序设计竞赛题解》。由于时间过去过久了,已经不记得看这些书的顺序了,只记得最先看的是《算法导论》,关于顺序实在没有什么经验可谈。
至于如何读这些算法的经典书籍,我却是有一些经验和你们分享。无论哪一本书,都不要泛泛地看一遍就以为看懂了,而是要把书中的每个例子算法都用程序写出来,这样才能留下深入的印象。若是遇到看不懂的地方,不要停下来,跳过去看其余算法,过几天在回头来看,若是还看不懂就再过几天再回头来看。千万不要在一个地方停下来,不然你极可能就此失去兴趣,恐怕永远也看不完这本书了。
问:有哪些学习算法的网站值得推荐?
有不少游戏开发相关的算法介绍:
http://www.gamedev.net
http://theory.stanford.edu/~amitp/GameProgramming
http://www.gamasutra.com
http://www.sudoku.com
俄罗斯方块游戏的算法网站:
http://gforge.inria.fr/projects/mdptetris
http://colinfahey.com/tetris/tetris.html
leetcode,最近很火的算法网站:
http://www.leetcode.com
Topcoder,也很经典,每周都有竞赛,有奖金的:
http://community.topcoder.com/tc
晋中教育网的“信息学竞赛辅导”:
http://www.jzsyz.jzedu.cn/xxjs/suanfa/index.html
不少大学也有本身的竞赛题库,好比:
北大:http://poj.org/
杭电:http://acm.hdu.edu.cn/
华中科技大学:http://acm.hust.edu.cn/vjudge/toIndex.action
问:不少人都认为“学习算法很难”,你是否知道有哪些方法能够下降学习算法的难度?
许多算法是有难度的,理论很复杂,不容易理解和掌握,这是客观存在的现实。可是咱们能够经过提升自身分析问题和解决问题的能力来相对地下降学习难度。从基础来说,要深刻理解数据结构,至少要很是熟练地掌握一种排序算法,各类线性表的插入、删除算法,树的遍历和插入、删除算法,图的遍历算法等等。而后要多学习,掌握一些常见问题的解决模式,好比穷举算法如何应用,动态规划算法如何应用等等。最后要勤思考,对应已经掌握并解决的算法,要想一想为何用这种方法解决,有没有其余方法,相似的问题怎么办,提升触类旁通的能力。
问:想学好计算机算法,是否须要从新学数学?
这个问题没法回避,数学的重要性不在于算法中用了哪些公式或数学原理,其重要性在于一种思惟方式的培养。当咱们遇到一个新的问题的时候,一般有两种解决问题的方式,一种方式是创造一种新的方法来解决这个问题,另外一种方式是将新问题分解、转化成已知问题,而后用已知的方法解决这个问题。这两种方式都很须要抽象思惟能力,现实生活中不多有机会锻炼抽象思惟能力,而学习数学是一种很好地培养这种能力的方法。我强调数学学习的目的不是说要学好算法就必需成为数学大咖,而是经过学习数学促进抽象思惟能力的提升。
问:背算法和理解算法是通常算法学习者都可以作到的,可是不少人会在设计算法的过程当中遇到困难,请问算法设计为何那么难?如何能完成从“输入”到“输出”的转化?
参加算法竞赛实际上是一件很痛苦的事情,要通过大量的训练,不少人会选择背一些算法或整理一些算法模板,到时候能够直接套用。在理解算法的基础上熟记一些经典的算法实现其实也是一件无可厚非的事情,我上学的时候也参加过一些比赛,一般在比赛以前也会突击训练一两个月,并背不少东西,基本上也是过后一个月就全忘了。
比赛的题目通常都有特定的套路,可是现实生活中的算法每每就事而论,有可能只有你遇到过,没有现成的经验,须要本身从无到有来解决问题。我在书中强调算法设计有三个方面:模型的创建、演化算法和输入、输出的转换。这三个方面中模型的创建是关键,不少状况下,模型建好了,演化算法和输入、输出的转换就水到渠成。
创建模型的基础是数据结构。当一个问题的数据存在先进先出的特性时,你要想到队列。当一个问题的数据须要频繁查找操做时,你要想到有序表、hash、map。当一个问题的数据须要频繁的插入、删除操做时,你要想到链表。当一个问题中的数据包含父子关系时,你要想到树。当一个问题中的数据中既有节点又有路径什么的,你要想到图。这些都和使用数据结构的经验有关,只要多练习就能掌握。
创建模型还须要抽象的逻辑思惟能力,简单地说,就是运用抽象的逻辑思惟,抓住问题的主要因素,忽略次要因素,创建问题的框架。算法设计之难体如今思惟方式的转换和模型的创建,前面说过,这须要有抽象思惟能力,缺少这种能力,连问题都很难想明白,更不用说设计解决问题的算法了。幸运的是这种能力是能够培养的,学好数学,多研究一些算法,积累些经验,都是很好的提升抽象思惟能力的方法。
问:算法在大数据领域有着普遍的应用,《算法的乐趣》的推荐者王益和黄鑫也都是机器学习方面的专家,请问编程算法和数据挖掘涉及的算法有什么区别和联系吗?
编程算法应该只是算法的一种表达形式,咱们还能够用表格或流程图来表达算法。数据挖掘领域涉及的算法和其余领域的算法并没有本质的区别,只是问题域不一样。数据挖掘和机器学习经常使用的方法,好比决策树、贝叶斯学习、神经网络、遗传算法等等,在其余领域也都是有应用的。神经网络、遗传算法做为启发性搜索算法在人工智能和最优化求解领域也获得了普遍应用,本书中就介绍了遗传算法,只不过所举的例子是用来解决0-1背包问题,有点“大材小用”。贝叶斯学习在一些电子邮件应用程序中也有应用,主要用于垃圾邮件的识别。在人工智能领域或各类专家系统中,决策树算法也是经常使用算法。各类算法之间的联系仍是很广泛的,在不一样的领域扮演着不一样的角色,本质上没有区别。
问:在平常生活中,咱们有机会见到愈来愈多的推荐算法,请问你对如今流行的推荐算法是否有一些研究?要作好推荐算法,有哪些问题须要特别注意?
确实是这样,我曾经想买一个佳能镜头,因而用了一下百度,想了解几种镜头的评价,结果一连几天,只要登陆京东或淘宝,首页都会给我推荐与数码相机有关的配件或镜头信息。
由于工做领域的缘由,我对推荐算法没有深刻的研究,这种算法应该主要是创建在大数据上的数据分类、筛选和过滤吧。不过就我对算法的理解来讲,目前的推荐算法仍是有改进的余地的,好比要能区分同一台计算机的不一样使用者,不要在我用电脑的时候向我推荐女式内衣和化妆品,那是我老婆关注的东西。
问:除了书中介绍的不少经典算法,你是否在工做或生活中发现其余让您印象深入的算法?
应该说,在个人工做和生活中也是到处都有算法。说到网络协议,TCP协议中的“滑动窗口算法”也是很经典的算法。路由器和交换机中为了不出现端口环路,都会使用最小生成树算法。在接入网设备中,一般语音报文的优先级高于视频报文,视频报文的优先级又高于通常的数据报文,当一大波各类报文来临时,设备如何处理?这个算法也很经典,就是用多个队列加上一个调度算法,简单说就是六个字:分分类,排排队。
随着宽带的普及,如今几乎家家都有路由器,不少人都会在路由器上给各个端口配置带宽,这就会用到带宽分配算法,令牌算法和Max-Min Fairness带宽分配算法都是经典的带宽分配算法。网络传输的数据报文出了错码怎么办?那就要纠错,Reed-Solomon编码和解码算法就是这样的经典纠错算法,除此以外,Reed-Solomon编码和解码算法还用于光盘、磁盘的数据纠错。
问:研究算法以来,对你来讲工做和生活中最大的收获是什么?
说实话,我曾经“玩”过的算法,绝大多数都没有机会直接应用到工做当中,可是“玩”算法对个人影响是显而易见的,它提升了个人动手能力,以及遇到问题时分析并解决问题能力,这就是收获,也是任何一个软件企业对程序员最基本的要求。
更多精彩,加入图灵访谈微信!