跳至主要内容

一个好玩的现象

一个好玩的现象

redraiment, 2009-07-05

一个好玩的现象





  这学期上了一门叫“软件工程实践”的课程。目的在于从需求分析、概要设计一直到验收结题,全程模拟真是的软件项目开发过程。让我们这些象牙塔里的本科生也有机会体验一下实战经历。

  一个学期做下来,对我来说印象最深的就是文档写作。相信很多程序员对写文档这档子事都是深恶痛绝。我们的需求频繁地更改(估计是老师们为了体现真实感而故意前后说得不一致),导致每次洽谈结果都是要修改大堆文档。但是我的厌恶倒并不在于需求变更,因为不管需求变化不变化我回来都照样工作,对于具体是什么工作我倒并不在乎。原本在Debian下我习惯用LaTeX来排版,但课程是硬性规定只能用Word排版、Visio画图、打包成rar提交。可惜了Word和LaTeX我都是半桶子水(不好意思,给咱们科班丢脸了),所以期间遇到了很多问题。但在用Word修改文档的过程中突然发现了一个很好玩的现象:“一个新手往往事必躬亲,每件事都亲历亲为;相反那些老手或者高手倒都是一个个懒人,能让机器做的绝不自己做。


  初看觉得很好笑,因为事必躬亲往往是那些能力强又追求完美的人喜欢做的:周围比自己好的人不多,事情交代下去就是不放心,干脆就自己解决掉算了。但环顾四周和计算机打交道的,猛然发现我们平时还真抢了不少计算机的饭碗!而且很多时候的烦恼都来自这些原本不属于自己的事情(的确有点杞人忧天,庸人自扰)。

从使用软件的角度看

  例如,作为一个Office(或者网页设计)新手,由于对软件功能的不熟悉同时也是在好奇心的驱使下,往往会不厌其烦地为每一句话甚至每一字设置字体、字号、颜色等,对每处细节都精雕细琢、力求完美(例如文档要求所有的引用需要用五号斜体宋体,新手们就手工一段一段地设置尺寸为五号、字体为宋体、风格为斜体,如果文章长的话就得花费很多时间),最终呈现的产品也可能完全符合要求。但这样的做法可维护性比较差,如果临时提出要求说所有引用的段落都要加粗,此时新手们可能要加班加点地给所有引用的段落添加粗体风格(可能会有遗漏。万一修改完成后又要求重新改回去,估计再温和的人都要发飙了^_^);老手们有更简便的方法,就是定义一些格式类型然后去套用(例如标题1、标题2等),要统一修改时只要右键“选择相同格式的文本”,就可以一次性全部重新定制。我们只需向计算机描述我们想要什么,比如告诉LaTeX,我要写一个报告(\documentclass{report}),标题是“Test”(\title{Test}),作者是“redraiment”(\author{redraiment})等等。至于“报告型文档”该怎么布局、标题该用多大尺寸、作者名是不是应该用斜体,都无需我们劳心,这些是LaTeX的工作。


  “绿色软件”这一概念也是一个很典型的例子!作为一个成熟的操作系统,统一管理软件包的安装与卸载属于份内之事。安装一款新的软件,不仅仅是把软件拷贝到硬盘上,将自己融入整个系统之中,在需要它的时候能很方便地调用(比如用IE在网页上打开一个pdf文件能自动调用Adobe Reader来显示)。而这些和操作系统打交道的工作交给系统本身是再合适不过了;“绿色软件”的思想是让应用程序与系统泾渭分明,目的在于尽可能少地产生系统垃圾。传统的“绿色软件”是很有益的,它们大部分都属于小工具,实在没必要向系统注册什么信息,这也恰巧体现了“物尽其用”的原则。只是最近“绿色软件”有被滥用的趋势:像office等通用软件也被制作成“绿色软件”。这意味着你要手工进行文件关联等操作,结果往往没系统自己做的好。我称他们为绿色发烧友,因为他们决定完全摒弃系统自动化的软件管理程序(由于抵触系统垃圾或其他什么原因)。

从开发软件的角度看

  产生上述这些现象有一部分原因在于新手对软件功能的不熟悉,也有一部分原因在于软件本身没做好本职工作(比如Windows环境下注册表体积增大的确会影响系统响应速度)。


  软件开发过程中也有很多此类现象:用Java开发GUI程序,新手普遍还不能理解Layout布局带来的优越性,为达到理想效果一般更倾向于用setLayout(null),把控件位置的控制权掌握在自己手中。但诸如不同平台上可能显示的位置不同,或出现重叠等棘手问题将接踵而至。


  另一个典型例子就是我们这些年轻程序员往往有一种“非自己做不可”的强烈情绪,相比于去理解和维护前辈们留下的代码更乐意于自己从零开始创作。这导致的结果会是文化没有沉淀、知识没有积累,从软件专业的角度来看就是代码没得到重用(重用的话题以后再聊)。一味地从零开始创作而不是在以往的基础上进行拔高,一般很难有所突破。

无为而治

  从上面的例子来看,似乎这是初学者过度到有经验者需要经历的一个阶段。这是不同的人,理解事物的方式不同:上述的新手们可能都是从结果到原因,而老手们则是从原因到结果。比如第一个例子中使用word排版,新手们就是因为“引用文字是斜体”这个结果才把某一段文字设置成斜体,而不是“因为这段文字是引用,所以它才是斜体”。如果一开始就本着这样的思想去学习,也许会少走一些弯路。


  事必躬亲虽然精神上值得鼓励,但可能不是长远之计。用这种方式去思考问题容易钻牛角尖,也容易沉浸于一些奇技淫巧中而学不到真正有价值的东西,终究只是看的见一棵树看不到整片森林。比如会有很多经验丰富C程序员告诫你“循环中用++i比i++快”、“整数的乘除尽量换成移位运算”等等。这些编程技巧基本上都是那些编程老手和自己的编译器混得太熟,以至于愿意为它们分担一些工作。但终归到底和语言本身无关,何况现代的高级编译器都已经具备自动优化功能。过度地手工优化不仅可能破坏代码的可读性和移植性,而且让编译器难以进行优化、发挥不出其长处,到底是聪明反被聪明误!


  而尽量让计算机来做事,这不仅体现“物尽其(奇)用”、“各司其职”,还反映了道家的无为思想(我所理解的无为不是不做任何事情,更确切的说应该是不做多余的事情。即“最小行为”或“按自然法则行为”。由于我的坚持,在中学里曾一度被语文老师树为反面教材)!它让我们摒弃一切不相干的事情,一心着眼于问题本身,提高解决问题的效率和质量。

后记

  “不做多余的事情”,这是与计算机打交道的方式,但不应该用来处理人际关系。虽然我们也都有各自的工作要做,但我还是挺愿意偶尔帮我老爸老妈干点活的~



评论

此博客中的热门博文

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