跳至主要内容

环境驱动编程

环境驱动编程——参加算法论坛后有感

redraiment, 2009-11-07

现场回顾





  我很荣幸地作为特邀专家入京参加 CSDN 主办的 SD2.0 大会。大会以“移动+嵌入+云”为主题,举办了三天。白天有很多名家讲座,晚上还有5个主题沙龙,我参加的是算法论坛的沙龙。主持人是王尧(左轻侯),曾经先后工作于 Borland 中国公司和微软中国公司,现供职于 IBM 中国开发中心,从事 DB2 的研发工作。与会的还有五位嘉宾:
  1. 王炜:北京南天软件有限公司总架构师;
  2. 宋兴烈:起步软件公司总工程师;
  3. 云风:网易公司技术研发经理;
  4. 贾自艳:腾讯搜索技术研发中心研究员;
  5. 顾森:北大在校学生(http://www.matrix67.com/)。
  论坛围绕“在新一轮技术浪潮中,算法又重新站到了重要位置”这一话题展开讨论。本来有几个问题想和各位嘉宾讨论,但由于时间不足,加上我住处较远,只好忍痛在 21:20 出去赶班车,到家已经 23:40 了。不过收获还是不少,我结合大会上其他专家的一些观点,将其整理出来和大家分享。

算法重获重视

  IT 行业经历了大型机时代、PC 时代、互联网时代,以及即将到来的移动终端+云计算时代。早期由于硬件的先天不足,需要靠软件后天来补;随着硬件的高速发展,一个普通的算法在十八个月以后性能就可以提升一倍,而且大部分经过高度优化的算法都被打包成类库,需要可以方便地调用;但随着互联网时代的到来,用户能够主动参与建设互联网,算法要处理的不再是几台 PC 中存储的数据,而是整个互联网中的信息。
  引用李德毅院士的话:“集中统一的调度,顺序的、确定的输入,不能描述互联网的工作机理和交互机理,互联网突破了图灵机的描述范畴。”李院士将云计算定义为传统的“图灵计算”结合“大众计算”,“大众计算”意味着至少能处理这浩如烟海的互联网信息,因此算法也必须与时俱进。

环境驱动编程

  在讨论中,王玮一直强调要灵活地运用算法,这个我以前提的“工具理论”不谋而合。他现场举了个例子:字符串匹配算法中,Rabin-Karp 算法理论上并非最优的,但在实际运用地比较好。这是由于硬盘的I/O效率远低于内存等高速存储器,并非理想的高效随机存储器。其他匹配算法都需要反复读取前面的数据,而 RK 算法只需按顺序从前往后以此处理,在处理大数据时避免了大量的读取操作,因此在实践中的表现反而比其他理论上更高效的算法要好。如果有一天,硬盘的随机存取速度达到了内存甚至寄存器的水平,那这些原本最优的算法可能又会变得没有优势。
  我在上一篇文章中也提过,真的要深入研究算法,就不可能仅局限于理想状况,必须结合硬件等现实环境。这意味着编程时选用什么算法,受到程序所处环境的制约。比如现在主流操作系统选用“分时机制”而不是“批处理机制”,也是因为受到所处环境需要实时交互的制约,而“分时机制”在频繁调度作业时也需要开销,机器利用率反而比不上“批处理机制”。
  我将这个思想称作“环境驱动编程”,它是“工具理论”在编程实践中的运用。但要真正能做到“环境驱动编程”并不简单,需要我们有很深厚的算法功底,就像在《做到忘记》一文中提到的,要做到无招胜有招,必须先把所有招数融会贯通。讨论中云风也提到:“在将来,把克努特的《计算机程序设计艺术》三卷本读完,可能只是作为程序员的基本素质!”

我的发言

  那天云风在现场提问:对一个长度为 N 的数组实现洗牌算法。作为大学生的我初生牛犊不畏虎,也不怕丢人就举手回答了。当时我的原话是:“用一个 FOR 循环从 N 倒退回 1,每次都随机产生一个 0 到 i 之间的数,对应的元素与第 i 个元素交换。”翻译成 C++ 代码就是:
for ( int i = v.size() - 1; i > 0; i-- ) {
    swap ( v[i], v[rand() % i] );
}
  但几位嘉宾似乎没听清楚,于是我重新组织语言重复了一遍,但好像还是没讲清楚,只好坐下让顾森自己来讲。以前我的队友反映我说话难懂我还不相信,看来真的要去学学口才基础了,呵呵。

我的遐想

  据顾森自己介绍,他最近在研究中文分词技术。他觉得很多人将计算机“神话”了,认为它无所不能,还举了一个例子:想知道今天北京的天气,只需在搜索引擎中输入“北京”、“天气”这两个关键词即可,但很多“脑子不好使的人”(这是原话)就喜欢输入“今天北京气温多少度?”等计算机无法理解的话。他一说完,我随即也听到了一些反对的声音:“你那样才是脑子不好使,人家的做法才算正常。”
  我当时脑海中想起 TAOCP 作者克努特在做 ACM 图灵奖演讲时举的例子:“电影制造厂家在1920年强烈地反对有声电影的引进,因为他们为能够不用声音也可以传递词语这样一种方式感到自豪。”因为较少的设施总能给人带来更多的快乐,我之前也大侃特侃《物尽其(奇)用》,以至于很难割舍那些很有美感的方法。我能理解巧妙运用关键词而快速获得信息的乐趣,因为这是一门艺术,并非所有人都能运用自如。但计算机终究需要是一台可以方便使用的工具。在对艺术有了深入了解后,艺术就慢慢地过渡到科学。关于科学与艺术的讨论可以参看克努特1974年获得图灵奖时的演讲。
  在参加完为期三天的大会后,我一直在思索一个问题:IT 业不断地发展,累计下来的知识越来越丰富,今天进入了移动终端时代,也许明天就迎来量子计算的时代。云风说看完 TAOCP 三卷本也许对很多人来说是玩笑话,但转眼看看现在的大学本科教育,它也非常矛盾:踏踏实实从基础学起,四年时间不够了解冰山一角;讲究实用直接建造空中楼阁,又会缺乏理论基础,很难有突破。如果真有那么一天,花毕生精力也不能全面了解,那这个行业将如何发展?
  我猜测将来会提有一套新的体系来取代现有的图灵模型和冯式计算机。现在用计算机解决问题,都习惯将问题划分成小规模的子问题来解决,这意味着子问题的性质和问题本身相同,有点像化学中的“分子”,麻雀虽小五脏俱全。但现实就像薛定谔的那只猫一样,都是概率问题:个人的运动时无规则的,但组合成一个整体后是有规律的。就像一个人的形态是稳定的,而具体到每个原子的运动又是无规律的。如果未来的计算机也是如此,能够整个这些并发的无规则计算,由量变引起质变,产生有规则的计算结果,那世界又会如何呢?期待一下 ^_^。

总结

  整个大会都很精彩,让我这只一直窝在学校里的井底之蛙开阔了视野。这次是我第一回去北京,住处安排得太远,只好忍痛舍弃第二天的沙龙,非常可惜。希望以后还有机会参加!


评论

此博客中的热门博文

AutoHotKey 新手入门教程

AutoHotKey 真是一个好玩的工具!短短几行代码就是先了“窗口置顶”、“窗口透明”等功能,之前我还特意为此装了好几个小工具,现在都可以卸掉了。闲来无事,就把 Quick Start 翻译了一下,我没有逐字逐句地翻译,有时候我嫌原文罗嗦就用自己的话概括地描述了一下。 原文地址:http://www.autohotkey.com/docs/Tutorial.htm 教程目录 创建脚本 启动程序 模拟鼠标键盘 操纵窗口 输入 变量与剪切板 循环 操纵文件 其他特性 创建脚本 每个脚本都是一个纯文本文件,由一些能被 AutoHotKey.exe 执行的命令组成。一个脚本可能还包含 热键 和 热字符串 。如果没有热键和热字符串,脚本在启动的时候就会从头依次执行到尾。 创建一个新的脚本: 下载 并安装 AutoHotkey。 右击鼠标,选择 新建 -> 文本文档 。 输入文件名并确保以 .ahk 结尾。例如:Test.ahk。 右击文件,选择 编辑脚本 。 输入以下内容:#space::Run www.google.com 上一行的第一个字符 "#" 代表键盘上的 Windows 键;所以 #space 表示在按住 Windows 键后再按空格键。"::" 后面的命令会在热键激活后执行,在本例中则会打开谷歌主页。继续按下面步骤操作,来执行这个脚本: 保存并关闭该文件。 双击该文件来启动它。在系统托盘里会出现一个新图标。 按下 Windows 和空格键,网页会在默认的浏览器里打开。 右击系统托盘里的绿色图标可以退出或编辑当前脚本。 注意: 可以同时启动多个脚本,并且在系统托盘里都会有一个相应的图标。 每个脚本都能定义多个 热键 和 热字符串 。 想让某个脚本开机即启动,可以将它的 快捷方式放到开始菜单的启动目录里 。 启动程序 命令 Run 可以运行程序、打开文档、网页链接或快捷键。请参看以下示例: Run Notepad Run C:\My Documents\Address List.doc Run C:\My Documents\My Shortcut.lnk Run www.yahoo.com Run mailto:someone@somedoma...

好玩的数学——吉普赛读心术解密

好玩的数学——吉普赛读心术解密 redraiment, 2009-11-19 神奇的吉普赛读心术   闲着无聊窜寝室,看到一个同学在玩一个 flash 游戏:吉普赛读心术( http://gb.cri.cn/mmsource/flash/2006/04/10/er060410001.swf )。规则如下: 任意选择一个两位数(或者说,从10~99之间任意选择一个数),把这个数的十位与个位相加,再把任意选择的数减去这个和。例如:你选的数是23,然后2+3=5,然后23-5=18 在图表中找出与最后得出的数所相应的图形,并把这个图形牢记心中,然后点击水晶球。你会发现,水晶球所显示出来的图形就是你刚刚心里记下的那个图形。   咋看之下觉得很神奇,但仔细把玩两三回后你就会发现其中的奥秘: 右边的图标每次都会改变; 9、18、27、...、81 这9个图标永远是一样的。   假设你选择的两位数是 ab(即 ab=a×10+b),其中 1≤a≤9, 0≤b≤9 。按照规则计算就是 (a×10+b)-(a+b)=9×a,结果是 9 的倍数,∵ 1≤a≤9 ∴ 结果为 9、18、27、...、81 中的任意一个。又∵ 这9个图标是一样的,∴ 水晶球神奇地知道你记的图标。 手指计算器   无独有偶,记的小学数学课上老师教我们用手指计算任意两个5-10之间的数的积。   例如 6×8 ,一只手伸出 6-5=1 根指头,另一只手伸出 8-5=3 根指头。1+3=4,4 就是积的十位数;把两手弯曲的指头数相乘得 4×2=8,8 是积的个位数。则 6×8=48。   道理和上面相同:a×b=[(a-5)+(b-5)]×10+(10-a)×(10-b) 神秘的失踪   做这道题一定要的亲自动手才有滋味!否则就会像浮光掠影,印象不深。   将一个正方形分割成 7×7=49 的小方格,并按下图将它们分为“甲、乙、丙、丁、戊”五部分。   然后,甲块不动、乙块和丙块对调、戊块上移、丁块右移。得到新图如下:   经过这样重新组合拼成的新正方形,中间奇迹般地空出了一个洞!   实际上这只不过是一个小戏法,上面的新图形并不是真的正方形。 观察原始图可知 △ABC 和 △AED 是相似三角形 ∴ DE:CB=AD:AC=4:7 ∴ DE=8/7 ∴ EF=DE+DF=36/7 ∴ 上图...

JavaScript中的字符串乘法

JavaScript中的字符串乘法 redraiment, Date 原文 原文地址: http://www.davidflanagan.com/2009/08/string-multipli.html 原作者:David Flanagan In Ruby, the "*" operator used with a string on the left and a number on the right does string repetition. "Ruby"*2 evaluates to "RubyRuby", for example. This is only occasionally useful (when creating lines of hyphens for ASCII tables, for example) but it seems kind of neat. And it sure beats having to write a loop and concatenate n copies of a string one at a time--that just seems really inefficient. I just realized that there is a clever way to implement string multiplication in JavaScript: String.prototype.times = function(n) {     return Array.prototype.join.call({length:n+1}, this); }; "js".times(5) // => "jsjsjsjsjs" This method takes advantage of the behavior of the  Array.join()  method for arrays that have undefined elements. But it doesn't even bother creating an array with n+1 undefined ele...