2005年12月29日星期四

最近研究文件系统

因为还是想参加下次的软件大赛,所以最近差不多在开始准备了。涉及的主要技术是关于文件系统的。我希望能自己去修改 FAT32 的 FAT,文件属性域等等,使得能实现用 API 无法实现的功能。现在考虑地比较多的是两点:1. 我这样做是不符合微软公布的标准的,怎样才能使这样的修改不被磁盘工具判断为错误;2. 直接修改磁盘固然很强大,但是也很危险,如果改错了项,几乎是无法恢复的。

以后再慢慢写关于这方面的进展吧。

2005年12月24日星期六

最近的情况

这学期变化很大,变得很内向了,很少和班里的人接触。这样做并不是因为我怕和人接触,就想我原来那样,怕别人看不起我,怕别人嘲笑我,而是因为我觉得没有接触的必要。至少我觉得,我现在足够地独立,足够地成熟,已经慢慢能自己照顾自己,能自己找到自己的角色。小的时候,我很怕接触别人,很大程度上因为父亲的原因,但同时又怕离群索居,因为那样会感到孤独和无助。一个小孩子,一个人能做什么事呢?他没有任何能力照顾自己,养活自己的。小孩子也是有理智的,他知道离群索居的危险。

现在,我更多的是去关心自己的事,而不是别人的眼色。我更多的是帮助别人,我讨厌去“求”别人的帮助,因为我的命运得由别人来决定。这也是我从小很好强的原因。也许是父母和家庭环境的影响,我从小不爱作弊,使心眼,这样我为了获得好成绩,必须有比别人更强的能力。我知道,有些人只要利用那张灵活的嘴就能活得很舒服,我则需要在实际能力上远远超过所有人才能让自己活得舒服。

这几天晚上回宿舍,推车走过那个上坡路时常常去看月亮。路灯一般是没有亮的,月亮也异常的美。要是没有月亮,这段路就十分黑暗了。我觉得,我喜欢这种黑暗,因为黑暗让我感到安全,在黑暗中,没人知道你是谁,没人知道你在做什么,没人知道你在想什么。同样,我喜欢安静。记得大二上学期,也是那个寒假回家,一天晚上,一个人在成都的街上走,那种冷清的感觉很难用言语来表达。我觉得那才是成都本来的样子:安静,闲适,慢节奏。还记得高考前的那段冲刺,晚上 1 点钟了,一个人坐在书房里看书,也是一、二月份的冬天,窗外一片黑暗,一片安静,整个世界里好像就只有我一个人了。

很多人怕黑暗,怕冷清,大凡文学作品里面,喜欢黑暗的角色也往往不会有好下场。我呢,觉得这两样使我能真正放下面具,叩问自己的内心,孤独,我早已习惯了。

2005年12月18日星期日

插件式编程

最近下载了一个软件,Babylon,很著名的翻译软件。

以前一直用金山词霸的。最近因为需要德语的翻译,金山词霸就做不到了,又懒得每次去找代理上线上翻译网站,所以找到了这款软件。这款软件好就好在,他的词库是按照插件的方式和主程序整合到一起,所以只要添加了词库,就等于多了一门语言。而如果想要改进软件本身的功能(如支持通配符,列出所有可查词汇,这在用户记不清词的准确拼写时很有用),只需要修改主程序即可。这样降低了程序模块之间的耦合度,也就增加了程序的灵活性。而且,Babylon 提供词库制作工具,使得用户们能够创造自己的词库,大大增加了软件的生命力。这也是拜开放的架构所赐。

写到这里,我想到了 Eclipse,同样也是一个插件式的 IDE。我本人不使用 Java,所以对 Eclipse 也不是很了解,不过从《程序员》我还是能看出,Eclipse 很成功,原因也是在于它先进的理念和开放的架构。似乎在这个时代,软件只有开放了才会有生命力。

我在想,其实一个计算机系统本身就是一个插件系统,操作系统就是主程序,而用户程序就是符合操作系统提供的接口的子程序。Windows 和 Linux 的不同在于,Windows 的主程序是封闭的,由 Microsoft 来负责维护,而 Linux 就连它的内核都是开放的。程度上的不同决定了软件本身的性质。

但是,正如我在第二段里面所说,“如果想要改进软件本身的功能,只需要修改主程序即可”。问题是,由谁来修改主程序呢?Babylon 可以由 Babylon Ltd. 来改进它,Linux 由谁来改进?Linus?Ecplise 呢?IBM?开源软件最大的特点在于它不是属于某一个人或某一个组织,它属于任何对它感兴趣的人们。那么,如果 10 个人对它感兴趣,那么软件前进的道路就有 10 条,从这点看,原本开源希望的将众人的力量合起来开发软件,反而分散了软件的开发者们,因为大家都没有一个领头羊。我在想,如果 Linux 从一开始就没有什么 Rad Hat,没有 Fedora,而是把这些公司里的人才们合到一块儿去开发 Linux,那么 Linux 还会是现在的样子吗?

我不反对开源的理念,但我觉得,群龙无首是不行的。

2005年12月11日星期日

人与人是不同的

越来越深切地发现,人与人之间的差异是那么的大。从小没有父亲的我,总是很自卑,总认为自己做事的形式和方法比别人的欠缺,没有别人的好。这是潜意识里面的一种感觉,虽然外表随着年龄增大和知识增多,越来越显得自信和骄傲,但心底深处仍然觉得我不如别人,那个虚构的、抽象意义上的人。我总是觉得,随大流,干大多数人干的事情,虽然自己不愿意,但至少会有安全感,至少不会被别人认为是另类。我害怕那种异样的眼光。

不太清楚具体从什么时候开始,我开始感觉到,很多大多数人的所作所为其实根本不适合我,而我就算按照自己的方式做事也不会受到伤害。我逐渐意识到,我长大了,我已经有了保留自己个性的权力了。人与人之间的不同是如此之大,似乎每个人都应该想想自己做每件事是否是出于自愿的。往往,我会羡慕某人是如此的善于交际,现在转念一想,他就是他,这是他的生活方式,不是我的。我,在很长时间里,是一个程序员,一个爱乐人,一个思考者,一个独一无二的组合。

我觉得,现在的我,就像是摆脱了缰绳的马,终于又打开了被父亲的死加上的另一把锁。

2005年12月7日星期三

最近的两点感想

1. 为什么人们总是喜欢家?为什么家总是有着那么一种特殊的吸引力?抛开其他的原因,我想,最重要的是,家常常代表着亲人,友人,熟悉的环境,熟悉的生活。同时,如果家没有了亲人,没有了朋友,那么,家也就失去了大多原来的意义。我想这也可以解释为什么莫扎特对曼海姆的喜爱甚于萨尔茨堡,因为曼海姆人喜欢他,喜欢他的音乐(当然还有韦伯一家),而萨尔茨堡,只有大主教。

2. 女性更大程度上还是一种感性的,如一个朋友说的,男人总是试图从他们自己的角度去理解女性,但结果常常是错误的,而且是不幸的,因为他们没有意识到,他们的理性思考在女性上常常是行不通的。一个女人爱一个男人,可能根本不会去思考这个男人会带给她多少好处,仅仅因为对他有好感,仅仅因为一种冲动。而男人一般首先是想这件事对自己有没有用。当然,不否认也有些女人是很理性的,但是我不会太喜欢这种类型,可能感性本事,不同于男人,才是女人可爱的本质吧。

2005年11月22日星期二

难得的闲暇

今天中午去修自行车。在那里等师傅修的时候,一个人坐在那里,看着那个湖面,那些小草,那个碧蓝的天空,吹着小风,突然想到,现在这样什么都不用去思考、什么都不用去顾虑、完全无所事事的闲暇已经那么得少了。

修车师傅的小孩在那里玩着轮胎,看着他,我想到自己小的时候也是那样,做着现在觉得幼稚无比的事,却能从中找到无比的乐趣,相比起来,现在的我活得真的太累了。再想想以后大学毕业了,需要整天为生活而奔波的日子,似乎小时候的那种闲暇可能只能等到老来才有可能重拾了。说实话,现在的我,确实无法控制自己在有空的时候不去思考计算机的问题,思考生活的问题,我也早已有些厌烦了。

现在,对老人们可能又有了一些新的认识吧,他们走过了几十年的人生道路,经历了各种各样的是非,在老了有机会的时候,选择了自己认为最适合、最喜欢的生活方式,消磨人生的最后时光。好吗?令人羡慕吗?不好吗?不令人羡慕吗?

托福也考完了,虽然感觉作文考砸了,但心底深处还是隐隐约约有一点成就感的,毕竟,自己的英语水平也由此提高了一些。

2005年11月17日星期四

最近的情况

总的来说,虽然没有什么大的变化,但我觉得现在的我总是在逃避,总是告诉自己不喜欢就不要去做,以至于现在的生活变得非常单调和形式化。我不知道这是不是大三学生应该有的特点,至少,我不喜欢这样。

似乎越来越受到广东这个大环境里面的一些思想的影响,虽然这些思想我认为无可厚非,但我个人不喜欢它们。现在,思考自己的时间越来越少了,更多的实在考虑更实际、更世俗的东西。上个星期花了两天去买了一辆破自行车,这周又努力复习托福,可能下周又是泡在宿舍里搞 Linux。这一切我为的是什么?为的就是尽量少去想那些不愿触动的东西,就好像刚失恋或者刚死了亲人的人总是拼命地工作一样。我从来没想过我会变成这样,我也不希望自己变成这样,但看来,人还是很容易受影响的。

现在听音乐更加专注于那几首曲子,巴赫的 BWV 1057(第六钢协?),布鲁克纳第七交响,还有拉赫玛尼诺夫第三钢协。管很久没练过了,给自己找的理由是等托福考完再说。现在想起来,大一那时虽然是最傻的,但也是这么几年里活的最轻松最快乐的,不是学习任务或者其他的什么少,而是心理的压力最少,幻想破灭地最少,也最像高中时那个纯洁的自己。

可能人确实不得不随着年龄增大而改变。但愿这是“不得不”的吧。

2005年11月4日星期五

上帝的惩罚?

看来星期二的疯狂工作导致了到今天还在持续的头昏脑涨,脑部缺血。一整天人昏昏沉沉没精神,偏偏又没有任何其他的症状。今天从医院回来的路上,突然想到,这可能是上帝的惩罚。

对于每个人来说,时间都是相同多的,但每个人完成的事却不一样多。努力的人,聪明的人,在相同的时间能就能做很多事。然而,上帝是公平的。你不能超越别人太多,他不能容许这种极端的不公平出现。天才很少会遗传,天才也很少会长寿,否则,大多数的人就没有什么存在的价值了。上帝是公平的。

我想起了父亲,也是年轻的时候很刻苦,很努力,做到了绝大多数人无法想象的事。正打算在 30 岁以后大干一场,成就一番事业,上帝却看不过了。他或许是太努力了,把他的天才使用得太过度了,上帝告诉他:“凭什么你要在这么短的时间里面完成那么多事?既然这样,我就得让你生病,让你不能再做出成绩,直到你赎清了你的债。”无奈,他是太刻苦、太天才了,直到死的那一天都还不完。

我得出的结论是,上帝可能不公平(否则,他干嘛又麻麻烦烦要造出那么多天才来?大家一个样不更好?),父亲可能的确是寿终正寝,但有两件事是要记住的:一、什么事都要慢慢来,切不可急躁;二、每操作计算机一个小时,就要起来活动一下,疏络经骨,否则搞计算机这一行,短命。

2005年11月1日星期二

完成中间代码生成

最晚突发灵感,一口气写代码生成写到凌晨 5 点。睡了一觉,逃了一天课,下午又接着写,终于完成了这个 "Simple Compiler"。说实话,写这个编译器花的时间最多的不在代码生成,但确实感到代码生成的技术含量是最高的,也难怪每一本讲编译的书在代码生成上的章节是最长的。想想 2 个月前的暑假时还认为写编译器是一项不可能在短时间完成的任务,而现在基本上对编译器的流程有了一个大致的了解和实践,真的还是应了那句老话:“没有什么是学不会的。”

这个编译器,词法分析方面主要参照了《编译原理与实践》(Compiler Construction Principles and Practice) 里的那个 TINY Compiler 处理方法和技巧,构造 DFA,分状态处理输入字符。语法分析就是纯正的 LL(1)。

语义分析和中间代码生成这个阶段就不像前两个阶段那样有一个公式可以套。可以说,每个语言都有不同的、属于自己的分析方法,所以这个部分我更多的参照了教科书里面的方法。虽然说先根据语法分析的结果生成语法树,再根据语法树生成代码会简单一些,但这样会增加代码,降低效率,而且在某些情况下不适用,同时因为我的语法分析是 LL(1),所以我还是选择在不改变语法的情况下直接在语法分析中间添加语义分析的代码。

具体技术上,主要是使用“回填”技术。为了解决如何延后修改已经生成的代码的问题,我设立了一个四元式的数组,把生成的中间代码写进去,在 backpatch 函数中修改相应四元式。在分析完了所有程序后,用 emit 函数将四元式输出到控制台上。

其实,虽然感觉在实际编写代码上的时间并不是很多,但平时一直都在看关于编译的书,也正是有这些积累,才能够有比较清晰的思路来完成它。还要感谢那些前辈们宝贵的智慧和经验,没有他们,编译还是 Mission Impossible。

《编译原理》,Compilers: Principles, Techniques, and Tools,龙书
《编译原理与实践》,Compiler Construction Principles and Practice
《可变目标C编译器——设计与实现》,A Retargetable C Compiler: Design and Implementation,lcc
《编译器构造:C语言描述》,Crafting a compiler with C

2005年10月19日星期三

Visual Studio 2005 试用

昨天从网上下载到了 Visual Studio 2005 Professional Edition 的 RTM 版,马上试着安装。遇到的第一个问题是,VS2005 需要 Windows XP SP2,我还是 SP1。在 Aaron Stebne 的 Blog 找到了没有 SP2 也能安装 VS2005 的方法。因为 setup.exe /NO_BSLN_CHECK 简单,也没仔细看就尝试。结果总是在安装 MSI 的时候出错。没办法,改了注册表重试,一切顺利。(根据 Aaron Stebne 的说法,VS2005 并没有使用 SP2 的特性,微软的这一限制只是为了推广 SP2,所以即使没 SP2 也不会对使用造成任何不同)

试用了一下,嗯,界面不错,但是和 2003 比起来,改变还是不大,主要是 Dock 上有点变化。2005 似乎很强调网络功能,从 Start Page 到 Search,都提供并推荐使用线上服务,而菜单中更是加入了 Community 选项,看来微软认为 2005 要把所有的程序员通过网络联系起来吧。

功能上,乍一看还真么什么新东西,只多了个 Call Browser 和 Code Definition Window。C++ 工程属性页加入了 Manifest Tool 和 XML Document Generator 两个,默认选项变了一些。现在,编译错误不再在 Task List 里面显示了,而是一个独立的 Error List,这样对经常使用 Task List 的人来说可能更方便一些了。其他的都大同小异。

说说问题。第一,设置、界面、习惯变了,虽然不大,但还是不爽。当然,这是可以预料的。第二,Visual Assist X 的 10.1.1301 版不能用在 2005 里面,10.1.1418 版又因为试用期已过,无法再用,所以现在写代码都有些没信心。第三,Start Page 里面的 Recent Projects 没用!我打开了无数次 Solution,但那里面永远都是空的。修改设置里面的值,可以看到空白变长变短。进到注册表里面,发现 ProjectMRUList 是空的。不知这个问题该怎么解决。第三,有很多功能在这个版本里面没有包含,如 Code Profiling 等,毕竟是 Professional 版。还是很期待 Team Suite 版,也不知什么时候才能得到。

另外,调试功能好像也有一点问题。经常下了断点,按下了 "Start Debugging" 按钮,也停在了断点处,居然 Debug 工具栏的所有按钮都是灰色的,但菜单里面的选项又可以用。而且,在这种情况下过不了多久就会弹出一个 "Stop Debugging" 窗口。停止重新运行后又恢复了正常。有些怀疑这个 RTM 版的真实身份。

总的来说,目前对 2005 没有失望,但也没什么值得兴奋的地方。

2005年9月25日星期日

Glenn Gould 诞辰 73 周年

总觉得把“诞辰”这个词用在古尔德身上不太合适(一般感觉都是那些优秀而先进的共产党员们才配得上这个伟大而光荣的词的),但这是事实:古尔德已逝。至今,古尔德仍然是我最习惯的诠释巴赫的音乐家。




2005年9月22日星期四

初识编译器设计

最近终于开始自己动手写编译器了。老师给了一个名为 SIMPLE 的语言,叫我们写一个词法分析和语法分析。我是用 C++ 写的,刚刚把语法分析做出来了,总的来说还是有点心得的。

词法方面更多的还是参照了《编译原理与实践 (Compiler Construction Principles and Practice, Kenneth C. Louden) 》的 TINY Compiler,原因主要还是因为对编译器不熟,现在有比较成熟的方法,先拿来再说。分析的方法还是先在纸上构造出相应的 DFA,然后用一个 switch 语句选择各种状态分别处理。实际编写的时候,还是发现了很多和 TINY 不同的地方,所以自己也在他的基础上进行了修改。

我们的 SIMPLE 语言比 TINY 要复杂很多(Simple > Tiny ?),所以语法分析方面,相应的函数也多了很多。语言是符合 LL(1) 文法的,所以用的还是递归下降分析法(后来发现,其实还是有一个表达式不符合 LL(1),不过找到了解决办法)。因为有一个非终结符的两个候选式的 First 集合有交集,所以一时想不到该怎么去选择候选式。后来发现,可以用以下办法解决这个问题:将两个候选式 First 集合的交集抽出来,如果一个候选式可以推出另一个候选式(前者比后者大),那么在遇到交集里的终结符时,选择大的候选式。其他的非交集部分则选择各自候选式。举个例子:

abc → id | | id relation id | arith_exp relation arith_exp

arith_exp 是算术表达式,可以是 id + id,也可以是 id,还可以是 id + num,等等。可以看出,由于 arith_exp 和 id 的 First 集合具有交集 id,如果当前符号是 id,则不知道应该选择哪一个候选式。因为 arith_exp 可以推出 id,所以我把上式改成了

abc → arith_exp [relation arith_exp]

因为如果满足了 id,则一定满足 arith_exp,反之如果满足 arith_exp,不一定满足 id。事实上,上面的例子只是一个简化了的表达式,实际中还要考虑一些其他因素,不过总的思路就是这样了。当然,最好的方法还是仔细的设计标准的 LL(1) 文法,这也算是一点教训吧。

2005年8月27日星期六

“海顿”和古尔德

今天坐飞机回到广州。一路上一直在听古尔德弹的那三首“海顿”奏鸣曲,也不知这是我第几次重听她们了。昨晚没睡好,飞机上一直昏昏沉沉的。伴着古尔德的琴声,我脑中迷迷糊糊的出现了一个场景:古尔德坐在那他那把矮矮的椅子上,随随便便地穿了一件衬衫,弓着腰伏在钢琴上用手指敲击着键盘,嘴巴还不停地随着哼唱着。这无疑是标准的古尔德弹钢琴的姿态,但是当那时耳朵里响起第三第二乐章的那个忧伤淡淡的 e 小调时,我突然感到一阵难以言喻的快乐。

一是贝多芬写这几首奏鸣曲时不过才 25 岁左右,那时的他和 52 岁的他比起来确实太年轻了,而那时的作品和“锤子键”等晚期作品比起来同样是太稚嫩了。但是简单就是美,我认为,“海顿”胜就胜在她的天真,她的纯洁,她的洛可可。

二是我似乎又找到我喜欢古尔德的新的原因。在刚才那一幕里面,任何一个不认识他的人肯定会觉得这人的举动十分可笑,但这正是因为古尔德全身心地投入到钢琴中,完全忘记了外在的这个世界。其实,我觉得很少有人比古尔德更爱钢琴,更爱音乐。我们知道,平时晚上一时兴起,就要通过电话和朋友聊上几小时的音乐。古尔德一生未婚,对于他来说,可能钢琴的地位已经取代了那个可能的妻子。他对待钢琴演奏就像母亲对待婴儿一般疼爱。另一方面,古尔德是一个很孩子气的人,天真,淘气,任性,纯洁,这些特点我觉得他都有。对待他喜欢的曲子,比如这三首“海顿”奏鸣曲,他常常会弹得很慢,慢慢得享受,慢慢得陶醉,就像孩子们总喜欢在沙滩上多呆一会儿。而对待他不喜欢但又不得不演奏的曲子,他就像孩子一样任性,以最快的速度敷衍过去,就像我小时候对待不喜欢吃但大人们逼着吃的菜。我喜欢的就是古尔德那孩子般纯洁的对音乐的爱。

2005年8月25日星期四

变长文件管理器

这段时间做了一个变长文件管理器(类似 WinRAR,可以把多个文件装进一个文件)。原本是学校的作业,但是我也算是认真对待了的。做的过程中遇到了很多比较抽象的问题,解决过程中也确实领悟到不少有用的编程思想,看来计算机科学这玩意儿还是要多动手写才会有提高,光看书还是不够的。(程序源码和客户端放在后面,有兴趣可以去下载)

记录文件的格式类似于FAT文件系统,采用簇作为存储单位,这样比较方便对文件进行操作。虽然这次程序引入了读取参数配置,压缩文件这些原来没有涉及过的方面,但是最终还是就一个 exe。原本觉得应该把管理器的类库做成一个 DLL,供客户端来调用,但是尝试后还是发现要把所有类库用的 .h 文件倒入到客户端那边去,而我又习惯在 .h 写类的实现,所以太麻烦,只好作罢。看来以后还是要改一改编写习惯。

这次写的过程中遇到一个问题,至今也没有想到解决办法。我本想做一个类似数据库的结构,用 Struct 模拟表中的字段,Struct 的成员变量类型相当于字段类型。用链表模拟整个表,链表传入的模版就是之间声明的 Struct,这样一个链表就可以存储任意多个具有相同成员类型的数据了,在这一点上还是很像数据库的。问题是,一个数据库可以容纳任意多的表,并且每个表的结构可以不同,这一点如何用模版实现呢?最开始想到的还是用一个链表来模拟数据库,用链表来保存链表。但是这是不行的,因为模拟表的链表本身就是模版了,都具有不同的模版类型,而链表只能存储相同类型的数据。想来想去,只能用类似 .NET 中 ArrayList 的方法,把模拟表的链表转化成类似 Object 的基类,使其具有相同类型。

那么如何在 C++ 里面模拟“所有类型具有共同基类”呢?我想到的是自己写一个 Object 类:

class MyObject
{
void* dataPtr;
int size;
}

dataPtr 保存数据所在的内存地址,size 保存数据大小。装箱时,要同时传入数据本身和数据所占字节数。然后 Object 到内存中分配一个 size 大小的空间,保存数据,并记录内存地址;拆箱时,将 void* 转化成需要的类型的指针,返回值即可。

理论上要实现还是不难,但实际中这种转换很难办到。首先,C++ 对运行时动态类型转换支持并不好。比如,假设有 MyObject a = 1 ,如何实现 int b = a 呢?MyObject 怎么知道要把 void* 转换成 int* 呢?难道 int b = a.Convert(int) ,或者 int b = a.Convert("int") ?这些都不可能,C++ 不支持传入一个类型,更不可能根据字符串转换数据类型(C++ 之提供了一个动态获得类型的方法 type_id)。其次,C++ 中各种数据类型多种多样,很难只用一个 void* 一概而论。比如,要实现字符串 char* 怎么办?要实现 STL List 怎么办?

当然,要解决这些问题也不是绝对没有办法。如果 C++ 的标准就由我来制定,C++ 的所有代码就由我来写,那我完全可以自己写这个 Object,自己实现 Object 对所有类型的转换。可能有人会说,这根本不是一个办法的办法。其实,.NET 就做到了这一点,Java 就做到了这一点,我想关键还在于它们都是由一个公司开发出来的,语言的耦合度自然就比 C++ 大。耦合度大,语言确实失去了一定的自由度,但也确实更加方便。也是到现在,我才真正体会到 C# 原来是那么方便强大的一个语言。

现在再回想起初中时刚开始接触编程的那个时候,在看看现在的自己,发现自己确实在成长,曾经觉得要不可及的那些 C 语言代码,现在只是当作工具来用了。说来现在感觉自己又进入了一个新的高度,不再是原来的桌面应用程序,不再是 Flash 和 ASP,而是编译器,操作系统,文件系统,更多原理级的东西,更接近数学。当然,这也只是一个新的开始,在这条路上还有很长要去走,还有很多高度要去翻越。

变长文件管理器 RecordManager

假期结束

整个八月没有来写新的日志,总觉得有一些想记的东西,但又总是不知道从何下笔。

暑期的的生活还是那么有规律,我还是一个不喜欢外出的人。这个暑假其实也没干什么事,前半段用来上 TOEFL 了,后半段主要在做学校的数据结构作业。怎么说呢,其实这个假期觉得自己还是有一些新的认识,有一些改变,但是要具体说是什么又说不清了,总之,自己清楚。

请几天,在加拿大读书的表哥回来了,到我家来了 2 天。出去快 3 年了,感觉他还是老样子,应该有的性格和习惯都还在,不该有的东西还是没有。原本想在加拿大读书,接触的大多都是外国人,在兴趣爱好上和语言习惯上应该都会和以前不同了吧,结果他还是很流利、“很地道”的成都话,喜欢的除了上网聊天就是聚会结交。这些没什么不好,如果他不是这样我反而会认不出他了呢。但是从这里我发现,出国并不能从根本上改变一个人。

上次和 Alex 谈到这个问题的时候就觉得,其实现在很多人出国仅仅是赶时髦,随大流,绝大多数人对出国的目的并不明确,甚至抱有幻想。很多人认为出国留学就是为了移民,就认为出了国,成了老美,那我这一辈子,我的子子孙孙以后就可以享尽荣华富贵,就好像在国外就有金子等着中国人去捡,这一点我在新东方上课的时候就很有感受。是的,不可否认在国外,很多环境因素比国内要好,医疗,福利,人口,公共设施,等等。但是对于一个中国人来说,能不能融入别人的国家才是最重要的,文化差异,这不是一两天就可以消除的。其次,为什么会想国外就有金子等着中国人去捡呢?难道说我在国内都没有能力、找不到好工作,在国外还能去把别人踢开自己当老板?人在任何社会里受到的待遇都是公平的,就像在美国赚美元一样,赚的是美元,花的也是美元啊。我觉得,出国留学为的就是学习到更新更丰富的专业知识,是否留在国外,那得看当时情况。如果仅仅为出国而出国,那我是绝不愿意做的。

对了,前天得到一个 Gmail 帐号 crendking@gmail.com,不过还是不打算用,比较现在都两个邮箱了,够用了。最近 Google 炒的好像比较热,很多言论预测 Google 要取代 Microsoft 成为新一代的业界霸主。我倒不偏向哪一方,其实我对两家都比较喜欢的,只是我觉得 Microsoft 能走到今天这步绝对不是吹的,要扳倒它绝不是一天两天的事。愿两家各自走好吧。

明天就要回广州了,下一年的学习生活可能会非常紧张,总算现在已经是养足了精神。

2005年7月17日星期日

求大数的阶乘

昨天看到博客园的一篇文章《10000的阶乘的算法(大数的阶乘)》,自己也想了一下,写了一个 C# 版的。程序也比原文的要简单。

原文中,数组大小 M = log10^1+log10^2+log10^3...+log10^n,好像不对。我觉得应该是 M = log10(1) + log10(2) + ... + log10(n),log10(1) 表示以10为底数、1为真数的对数。可能我们表达的是一个意思,只是写法不同而已(不过我还是觉得10^3 = 1000,log10^3 = 3,这样明显不对嘛)。

程序:

using System;

namespace Factorial
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int n, M, carry = 0, t1;
double t2 = 0;
bool display = false;
int[] result;

Console.Write("Input the number you want to factorial: ");
n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("");

for (int i = 1; i <= n; i++)
t2 += Math.Log(i, 10);
M = (int)Math.Ceiling(t2);

result = new int[M];
result[0] = 1;

for (int i = 1; i <= n; i++)
for (int j = 0; j < M; j++)
{
t1 = result[j] * i + carry;
result[j] = t1 % 10;
carry = (t1 - result[j]) / 10;
}

Console.WriteLine("The result is: ");
for (int i = M - 1; i >= 0; i--)
{
if (result[i] != 0 && !display)
display = true;
if (display)
Console.Write(result[i]);
}

Console.ReadLine();
}
}
}

用 Windows XP 自带的计算器验算了一下,1000! 应该是没问题的,但算 10000! 确实算不出来,要等很久。原文的那个程序也是要等很久,而 Windows 自带计算器只等了 1 秒钟左右。我想,要不然是 Calc 省略了后面的位数,要不然是 Calc 有更好的算法。

小程序,轻松一下。:-)

平淡的日子

最近广州还是很热,天一热,人也就懒了,每天的日子也过得很有规律,无非就是写写程序,看看书,订订外卖,睡睡觉。要说因此得到了什么,那只能说,知道了什么样的生活叫做无所事事,叫做没有动力。:(

明天托福班就开课了,总算是一个改变的契机吧,至少能给自己一个出门的理由。人是很容易被麻痹的,除非自己不断提醒自己,要改变,要像自己希望的方向改变。

2005年7月7日星期四

网络游戏的一点开发经验

以前从没接触过网络游戏方面的编写。前段时间因为课程原因,和班里同学组队写了一个网络游戏,虽然功能上比较简陋,但是麻雀虽小,五脏俱全,网络游戏应该有的几个基本元素都有了,也算是在网络编程上的一次新的尝试了吧。

游戏是用 Java 写的,原因是,我们学那本教材的示例是用 Java 写的。从产生最初的设想,到最后的完成总共是一个半月左右。因为是组队编写,所以在分工合作上就必须十分注意,而且一个月内要完成一个具有界面、网络通讯、游戏逻辑等等内容的软件对于一个没有经验的人来说工作量太大了些。

我们采用的方法是分工-整合,即先通过分析把软件分割成几个技术块,分给组员去研究,等他们把自己那块研究得很透彻了以后,就把自己在那一块的经验、需要注意的地方、一个自己写的典型的示例交给一个整合者。整合者需要较高的程序开发能力,至少要对各个技术块都要有一点了解,并且能够很快从各研究者那里学到东西,然后把各个部分整合起来,完成整个软件。

实际当中,我们分割的技术块有以下几个:

1. 核心算法、逻辑(同时也是整合者);

2. 界面设计;

3. AWT + Swing;

4. 网络通讯(组播 + 流式 Socket)

5. 安装和分发。

非常有幸的,我担任核心算法的那一块,从自己,也从别人那里学到了很多。

在编写过程中主要遇到了以下几个问题:

1. 各个客户端如何互相识别;

2. 非原子对象如何通过网络传输;

3. 组播的可靠性;

4. 逻辑部分的架构怎么设计,才能保证简洁、有效、少出错。

相应的每个问题的最后解决方案是:

1. 我们考虑了是否使用服务器作为中间人。一种情况就是各个客户端就通过组播传递一个只属于自己的 ID。但是因为组播机制的问题,我们(好像)不能仅仅经由组播组得知组里有多少成员,更不可能收到类似“有新的成员加入组”的消息。经过考虑,我们还是决定使用客户端-服务器模型,有服务器分发 ID,这样,服务器就能分担很多原本在客户端的开销了(特别是使用多线程以后)。

2. 很明显的,用序列化。为了这个,我和一个同学争论了一个晚上,他想用类似网页表单的形式,最后终于说服了他(有现成的技术干嘛不用)。

3. 通过最后的测试,我发现,组播的时序是一个很麻烦的问题,特别是在还有网络延迟的情况。在游戏中,3 个客户端在接收(并发送),1 个客户端在发送(并接收),我怎么保证客户端 A 他先收到客户端 B 接收后发送的消息,还是客户端 C 直接发送的消息?如何保证自己发送的消息自己能最快地接收到?实际情况中,几种可能性都是存在的,也都发生过。我没有找到什么很好的解决办法,只能是增加条件判断。

4. 架构,最难办的东西。就这么一个小游戏,要把它的规则用程序描述出来也是不容易的。更难的是在怎样有效、正确的传递结果,特别是在上面提到的不太可靠的环境下。为了赶时间,我没有花很多时间在设计架构上,还是采用了沿时间的线性编程。事实证明,这简直就是地狱,你将需要非常多的 if, else 放在各个关键点,很多时候为了解决一个匪夷所思的 Bug,又要添加 AND 或者 OR。到最后,逻辑部分变得很冗繁,很复杂,即使有 Bug 也很难找到。这也算是对我偷懒的惩罚吧。

其实对于架构,也想到一种方法,时间表。事前为每一个客户端制作一份时间表,时间表中记录了客户端每一步应该做的事情,这样每个客户端就不需要关心其他客户端发生的步骤,只需要将其他客户端发送的数据接收并正确显示即可。制作和使用时间表并不容易,但是对于复杂流程来说,这会是一个比较好的解决方案,从逻辑上来说,这就是把整个过程式的流程分割了并分发给每个客户端。每个客户端的对应时间表是在一份基本时间表加上以客户端的本地的独特数据(如 ID)作为基础的变化后生成的。我想在以后哪次写类似的软件时有可能会用到这种技术。

另外,以前都是用 C++,C# 的,第一次用 Java,感觉 .NET 确实是从 Java 中汲取了很多好的思想、细节,摒弃了很多麻烦、不实用的东西。两者在语法结构上都很相似,但感觉 C# 更像 C++ 一些。(而正是这许多些微的不同,形成了很多各式各样的争论。)个人来说并不觉得 Java 就比 .NET 差或者落后,只是比较不习惯。还是要看在什么领域里面应用,有些适合 J ,有些时候 N,没有一定的。不过,对于 Java 的图形界面设计,我是深恶痛绝。要想用 AWT 设计出像 .NET 一样整洁清新的“一般”窗体是多么困难的事啊!

还有很多感想,一下子也想不出。以后再说吧。

2005年6月3日星期五

古尔德的复调风格

再听古尔德的贝多芬钢奏,慢慢发现了古尔德演奏这部作品之所以和别的钢琴家那么不同的原因。

稍微注意一下他左手和右手的处理,可以发现在很多地方他的左右手力度几乎相同,即使在那些突出右手主弦律的地方也是如此。这种处理方法在复调音乐里是很基本的,因为复调的左右手根本没有什么分别。古尔德将这种方法用到了贝多芬里面,感觉就很不同了。虽然乍一想这样做很疯狂,但事实证明效果不错 lol !

除了左右手的处理,古尔德在速度上的掌握也充满了复调音乐的特点。在一首曲子里面,他极少有节奏速度的改变,而一般很多人对贝多芬都强调流畅,速度上会比较自由。这个特点也很明显的有复调感,好像古尔德弹贝多芬钢奏就像是在弹赋格的艺术,只是音符有所不同而已。另外,古尔德对自己喜欢的曲子一般都处理得很慢,不喜欢的就极速拉过去,这又是他个人风格的体现了。从海顿奏鸣曲和别的曲子不同的录音效果来看,古尔德应该是对这三首重录过的,这应该可以解释为什么三首的慢板乐章他会处理得那么慢了。

其实虽然古尔德这样演奏贝多芬就好像杀牛用马刀,但实际上我仍然很喜欢他的演奏,这是一种完全不同的方式,是另一种可爱,不可多得的。

2005年5月17日星期二

肖邦

今天学校的广播结束时,放起了肖邦的钢奏。那时我正准备出门,突然起了想要重听一下肖邦的念头。刚刚当夜曲(这套盘是那套鲁宾斯坦演奏的,夜曲是第一张盘上的)响起的时候,旧时的那些记忆又立刻重现了。这还是高中时的肖邦,还是和 Alex 在音乐课上听到的肖邦,还是三楼老家里,晚上准备高考冲刺时的夜曲。

论作曲技巧,肖邦远不如巴赫;论艺术手法,非贝多芬莫属,但肖邦确实是不可替代的,即使那么长时间没有去碰过那一套老碟,记忆中永远还是为他留着一席空间。肖邦的音乐并不是一成不变的忧伤,他有一种魔力,能让我总是去想而非去思考。如果要问到底在想什么,我只能说,就像很多涉及到艺术和内心的东西一样,那是难以言传的;而正为此,体会又更加地强烈。总而言之,耳中的音乐似乎和 5 年前的音乐是一样的,但它在自己内心中的 Image 又有了很大的变化。毕竟,人就是在变化。

晚上下了一场雨。回宿舍的时候,又路过湖边的那棵树。耳中的是夜曲,眼前是朦朦胧胧的北湖,鼻中是湿润清新的空气,加上头上的一轮半遮半掩的月亮,我觉得这棵树真的是那么地孤傲和威严,又那么地令人感觉和蔼可亲。一种自私的念头告诉我,我是在拿自己和它作比较。我希望自己能具有它的这些特质。夜色是美的,音乐也是宁静的。

回到宿舍,就像突然进入了另一个世界,一个陌生的世界。人,又总归得生活在陌生的世界里。

2005年5月14日星期六

再谈开源

我觉得开源在很多时候并不是旨在把自己写的代码公布出来,让大家学习、修改,因为真正的大型软件的代码也不是一两个人、每个人都能看懂的,那需要对软件构架有足够的了解。而那些真正又能够从这些开放的、有用的源代码中受益的、牟利的也只有大型的软件公司,换句话说,就是那些制作软件并公布源代码的公司的竞争对手们。我想这就是大型软件一般都不开源的原因,毕竟,源代码里面可以包含太多太多的东西。

但至少,开源项目标榜了一个概念,就是我的这一行绝不是由我一个人来解决所有问题,绝不是由我来垄断,我只是为这一行提供了一个可能的解决方案,用户要用哪个是由用户根据自己的实际情况来决定。正如我原来说过的,这样做确实不可能产生一个十分强大的软件或系统,能够平衡地应付所有已经被发现的问题,甚至会产生一台计算机为了解决不同问题需要安装几套开源软件。但是,如果出现了新的情况,新的问题,开源软件确实能够更快地做出调整、改变。而像 Windows 那样的大块头,要想翻一个身、挪一下腿,决不是一件容易的事情(这就像自然界中蚂蚁和大象比喻一样)。

其实我也很清楚,大家一般愿意选择商业软件的原因,除了为了有技术支持等等保证外,其实还有虚荣心。打个比方,你现在并不知道有 IE 和 Firefox 这两个浏览器,我现在告诉你,IE 是微软做的,Firefox 是 Mozilla 的,你会安装哪一个?我们可以假设你用的就是 Windows,因为看在 Windows 的市场占有率的份上这个假设并非不合理。我想首先你可能会想一下 Mozilla 是什么玩意儿,但绝不会去想微软是什么玩意儿。然后,草率的你(我们假设,只是假设)会毅然决定“用 IE 吧”,原因也不是说 Mozilla 不出名,而是,Windows 是微软的,干嘛又要来一个什么 Mozilla 的软件呢?清一色的微软不是更爽吗?这样,Firefox 就出局了,IE 的霸主地位也就建立了。

我想如果把上面的主角之一 Firefox 换成 Netscape,就重演了当年的那一幕,人们会说,这就是捆绑的力量。我不是说 IE 不好,因为 IE 也在进步,如果拿 IE 3.0 和 Firefox 来让你选,出局的一定是 IE。也正是拿 IE 6.0 来比,虽然在有些方面 IE 不如 Firefox,不如 Netscape,但和“清一色”的快感、安全感、满足感相比,这些不足也是完全可以接受的。虽然不太好听,但是大多数人在选择软件的时候都是“草率的”,包括我。有些人可能根本没有试用过某一款软件,就在某个论坛里说这个软件不如某某软件,而原因仅仅是他没有听过这个软件的名字和制作公司的名字。

无论如何,我只是想说,开源和不开源确实是各有优点的,各有各自适用的领域,任何事情都不是一两天、一两年就能看出端倪的,你我都不能保证在十年二十年以后,我们大家的电脑里是不是都装着 Linux,或者 xxxnux,对不对?

2005年4月23日星期六

软件大赛

去年 12 月,决定参加学校的软件设计大赛,今天初赛终于结束了。一个简单的 3D 引擎自然没有奢望要进复赛,但在这整个大赛的过程中思考了很多。

游戏开发。当初决定做的并不是 3D 引擎,而是用 DirectX 做一个 3D 的记事本,后来才转而去做 C# + Managed DirectX 的 3D 游戏引擎框架。一个 3D 游戏需要的是大量的综合的技术,你需要对图形学有很深的了解,对图形硬件有系统的知识,你需要对操作系统的相关接口比较熟悉,你还要考虑声音、用户输入、网络通讯、美工、兼容性……这一切不是一个人能做得完的,必须选择其中 1、2 个深入地研究。而对于我来说,更擅长的还是抽象、对象、算法和逻辑,那么,是不是说游戏开发对我来说并不合适呢?是不是说,如果我决定在图形这方面更深入地了解下去,CAD 对我会是更好的选择呢?

.NET 的位置。4 月份的《程序员》在很大程度上改变了我对 .NET 和 Java 以及开源的态度,那时也正是我写引擎进入最关键阶段的时候。建议有机会的话还是去看看那篇《微软:令专家失望的 .NET》。虽然我并没有因为这篇文章改变多少对微软软件的信赖,但着实让我对开源有了一些更多的认识。这次软件大赛结束后,遇到一位已经毕业的师兄,听他说对 J2EE 有些专,也就和他讨论了一些 Java 和开源。他说,开源最大的优势在于这个群体的庞大,它的庞大使它能满足任何的市场需求。大型服务器需要相关软件,就有人做服务器系统;软件开发需要相关软件,就有人做 IDE,做插件;甚至他们电信要软件,也可以在网上找到相关的软件,改一下拿来用。这些,微软一个公司是做不到的。微软更关心中小型企业的市场,如果你现在要在服务器上传输一个 40G 的文件,你能叫微软来帮你解决么?总而言之,微软是做出了软件让大家来适应它,开源是大家提出要求,它来实现。

我今后要走的路。真是感到矛盾,一方面,我对游戏、图形编程很感兴趣,用手指创造动画特效的感觉是无可替代的,另一方面,我又对更加底层、抽象的编程绝对热爱,那是一种数学的美,智慧的美,成就的美。当然,现在决定以后要专攻具体哪方面的研究似乎还为时太早,就像 Alex 说的,本科应该是广阔视野,打基础的时间。也许,这种矛盾也是一种好的现象,至少,它表明我对计算机仍然具有热情,和 10 年前相比只增无减的热请吧。

另外,我觉得我是一个这样的人,平时没有编程“任务”的时候,真的是一点程序都不想去碰,那种“又要动脑筋苦苦思索”的潜意识会阻止我去打开 Visual Studio。但一旦我不得不动手开始编一个程序,一旦我已经陷入这个程序了,那我会不吃不喝不睡不休得完成它。似乎这样对身体有很大的坏处,但,我有什么办法呢?江山易改,本性难移,青山不改,绿水长流。

2005年4月22日星期五

古尔德的贝多芬

这段时间一直在听古尔德演奏的贝多芬的钢奏,特别是前期的几首。很明显能听出来,前期的那几首古尔德是在后来重录过的,音质上和大部分后期作品很大不同。不仅如此,从他的演奏中也可以看出来他个人对前期奏鸣曲的喜爱:一个字,慢。如我们所知,古尔德对不喜欢的东西从来就能多快就多快地飞过去,而中意的那些曲子就慢慢的蕴,让自己陶醉进去。当然,我们是从中得益了。

前三首奏鸣曲古尔德演奏得确实太可爱了,除了可爱,我也找不到其他的词来形容了(特别是第三的第二乐章,那么的慢,但却丝毫不让人感到拖沓)。给我的感觉就是:我们似乎回到了一个梦幻般的童年,没有忧愁,没有顾虑,有的只是在那个梦幻里面应该有的。这种感觉,有时我也能在勃拉姆斯和肖邦里面找到,而在这里,在古尔德里面,我也找到了贝多芬纯洁、童真、浪漫的一面。我丝毫不觉得第一奏鸣曲的作曲技法有多幼稚,我只是认为,在这里没有,也不该有任何其他多余的东西了,它已经恰到好处了。说它像莫扎特,我觉得只有一个形似,骨子里面贝多芬永远是一个直率的人,不像莫扎特让人有那么多猜测。

写到这里,我想起我这几个星期的周六都是一个人去外面吃饭,吃到很晚,然后慢慢走回学校,在没有路灯的湖边一遍又一遍地走,听古尔德的贝多芬,一种“收缩”的感觉在那个时候那么的强烈,我好像是被孤独重重包围了,又好像不是。在那个时候,平时所有的朋友同学都在这个世界存在着,做着他们自己的事情,而在我的世界里面,他们又全都不在,没有任何一个别人和我一同感受我的感受。我似乎骄傲地享受这一特权,但实际上这只是自己给自己的特权罢了。我特别喜欢湖边的一棵树,很高很老的一棵树,没有什么特别的原因,或许它的形状在夜里让我感觉它永远都会像它现在一样。我想,如果十年二十年以后有一天我还能回到这里,我会记起去看它,就像对待老朋友一样,一个在患难中唯一给我帮助的朋友。

2005年4月7日星期四

我的父亲 (3)

父亲的死对我的影响是很深的,最直接的影响是:我对女性的态度。

首先,是对我的母亲。简而言之,是强烈的俄迪浦斯情结。父亲的死使我成为了家中唯一的男性,在这种环境下,我能够感到我自己好像是在替代父亲的位置,亦即成为自己的父亲和母亲的丈夫,而这在我潜意识中是强烈反抗的,我认为这是不对的。所以,我并不是对母亲更加亲切和更加孝顺,而是在无意识中疏远她。另一方面,我知道我是母亲的儿子,她是我的母亲,我应该去爱她,这又把我带回俄迪浦斯情结的边缘,因此,我一直在矛盾中苦苦寻找平衡。

然后,是对同龄的那些女孩们。对母亲的这种心理矛盾使我非常急于为自己找到一个安全的立足点,我希望我能够回到正轨上来,而最好的办法就是为自己找一个合情合理的爱人。这种感情内在的表现是对女性的强烈的渴望,而外在的表现却恰恰相反,即对女性的假意的冷漠。为什么?因为过分的表露对女性的渴望使我害怕别人(主要是女性)知道我的秘密,知道我热烈的原因,也就是知道我的俄迪浦斯情结,而这个情结是我连自己都千方百计避免去面对的。

我相信,这种情结在我有生之年都一直会或多或少地影响我。在父亲死后不久,我曾经认为,没有父亲其实并不会有多大的改变,因为还有母亲养活我,我还并不是孤儿,并不会因此改变生活环境,你看,不是一切照旧么?不是没有人知道我的秘密么,只要我把秘密守得够紧?现在我知道,我从他死去的那一刻就已经被决定了,我也再不可能像那些一般人一样了,这是无论我多么努力,靠自己的力量都无法改变了的。我无法完全理解那些一般人的某些思想,就像他们无法理解我的一样。这里面呢,也无所谓谁更占便宜,谁更优越一些,只要自己能面对事实,那么一切都是公平的。我现在很坦然地接受这一切,并不埋怨任何人和事,一切的一切,谁都没有错,谁都不可能有错,因为谁都没有权利在只有上帝才有权利决定的事里面作自己的主观判断,是不是?

2005年2月21日星期一

未来的体验是什么样的?

这几天看了《程序员》的关于 RIA 的专题,还是有些想法。说实话,每次捧着那本书的时候,都会犹豫一下“买不买”。这次,是 RIA 让我打消了犹豫。

因为我对 DirectX 很感兴趣,也相信 3D 的用户体验在不久的未来一定会占据普通用户的市场,所以很早就想如果能在网页中大量的嵌入 D3D 的程序,那么网络带给用户的比现在会多很多很多。比之 Flash(至少,这是目前 RIA 提倡的两大阵营中的一个),DX 优在它的 3D,因为好的 3D 程序不言而喻的能带给用户更丰富的体验,而它劣也劣在它的 3D,因为同等次的 3D 程序的开发难度肯定比 2D 的要难很多,这就会导致开发时间、成本,以致成品质量上的不足。同时,其庞大的体积也使其不可能在现在的互联网环境广泛、快速的传播。

但是,随着网络硬件的不断发展,体积问题将越来越不成为问题。而开发复杂的问题也应该会随着 3D 程序的框架化而得到最大限度的降低(同时,成本问题也会相应解决),毕竟,只有人们越来越多的关注某一种技术,这种技术才会得到长足的进步,这里的框架化也是以此为前提的。想一想,哪一天,一个普普通通的程序员都能用积木的方法“拼”出一个他自己的华里的 3D 程序,那么那时流行于网络的二进制代码带给我们的会是什么样的啊!

所以,比较一下当前的两大 RIA 解决方案,我更倾向于微软的 Avalon。当然,技术应该服务于需求,未来的一切最终还是由用户自己决定的。我们,应该预测未来。

我的父亲 (2)

当然,所有关于他的传奇我都是从别人那里听到的,真实性并不重要。重要的是,他是一个勤奋的人,这是事实。

之所以写这样一个话题,并不因为别的什么,因为我有这个能力和权力来写我的父亲。不像那些还有父亲的人,我的父亲在这个世界的生命线已经结束了,他再也不可能有任何新的东西可能让我在完整的写下他给我的印象之后加上去,这就决定了我已经拥有“完整”这个权力了。

说实话,从我能独立思考问题以来,我确实一直以我是他的儿子而骄傲,我以我姓金而骄傲。在我那朦胧的记忆力,他是一个好人(这是我在那个时候唯一的判断),对人温和又不失严肃。在老家,一半的空间是他的书房,里面堆满了各种画具、画、书和他自己做的小玩意。小的时候我从来对那个地方充满敬畏,也很少走进那个没有任何玩具的房间。在印象中,和其他很多父亲一样,他很少有爱我的很热烈的表示,我呢,和其他很多孩子一样,不清楚他是否真的很爱我,所以更多地和母亲亲近。

小的时候,我是住在奶奶家里,因为他和妈妈白天都不在家,所以托奶奶照顾一下。那时候,每天晚上,他就骑车到奶奶家来接我回家。那时我都是坐在他前面,好奇地问他沿街看到的每一个新鲜的事物,或者是月亮星星的运行问题。有些时候,我也求他给我讲一个什么故事,他呢,也就在车上即兴讲一个给我听。不过有时确实想不出来了,他也就说“爸爸现在想不出来,等下次再给你讲。”那时候是80年代末,街上的房屋都是平房,人们都很早就回家,商店也关得很早,四周都静静的。在当时想来,仿佛那个时候这个世界上就只有我和他两个人,在一个白天很熟悉、而那时却很陌生的世界里静静地、慢慢的走着。而现在,那种黑夜里,那种古老的房屋面前,我都或多或少会泛起那时候的回忆。在脑海深处,父亲已经和那种图像交织在一起了。

有一段时间,他很喜欢钓鱼,几乎每个星期(不记得星期几了,星期三,好像),他都带着钓竿到游泳池附近的一条河旁去钓鱼,当然也把我带上。那种时候常常是阳光明媚的下午,河边也一般有其他的钓鱼者。那条河流得很慢,颜色是那种十分深的翡翠绿,河面上漂着很多河萍,给人感觉那条河深不可测。我那时候很小,对钓鱼这种需要耐心的事不感兴趣,往往是坐不上10分钟就再也坐不住,跑到四周去找蚂蚁,或者到其它钓鱼人那里去问这问那。他也从来不管我,静静地钓他的鱼,那份耐心让那时候的我十分惊讶。有时会有收获,一般是一两条草鱼,有时一下午也没有,也算正常。一旦钓上了鱼,我就蹲在河边,看网中的鱼怎么游。他就经常叫住我,叫我不要离河边太近,而我从来很不耐烦他那么提醒我。收拾渔具回家是我最高兴的时候,一般那种时候我都已经无聊到了极点,虽然回家本身也没什么特别的魅力。有收获的时候,他就把鱼装进塑料袋,加一些河水,充满氧气(河那里有专门作这种服务的),把袋子挂在自行车车头上。我现在还记得,那时的太阳,西沉的太阳,是多么的红,是多么的美,只是那时没有现在这么完整的感性认识,只是觉得很不可思议。

最后一个完整的记忆是在我们有了新家以后的。母亲单位给分配了一套新房,父亲对此十分看重,因为那时我们家几乎和外公外婆住在一起,楼上楼下而已。我相信父亲对新房的那种爱不释手应该和我对自己新的小玩意的那种爱不释手是一样的,所以我现在很理解他那时为什么要花那么多精力和时间去自己打点新房的装修。他坚持新房子用水磨大理石作为客厅地板,我记得有一段时间那个新家地上全是水,还有一台水墨机放在客厅中央;他坚持饭厅墙壁全部钉上竹条,我记得有一段时间他每天坐在小板凳上把劈好的竹条一根一根钉上墙,我就旁边给他递这递那。

有一次,他又在那里钉,坐在一个塑料板凳上,那个板凳是妈妈前一天走时留下来的,当时我也就在他旁边看他。正钉着,那板凳从中间裂成了两半,他一下子坐到了地上。当时我们都不以为异,继续开始工作。没过多久,他就开始便血,自然也丝毫没有和这件事联系起来,我也压根儿没有再对任何人(包括妈妈)提起过这件事。后来的事已经在前一篇回忆里介绍了。现在,我个人认为他的癌症本身应该和这件事没有什么很必然的关系,但是我对此记得这么清楚的原因是,这确实太巧合了,现在想来仿佛上帝就是在暗示着什么,而我们却把它忽略了。我仍然相信,如果那时父亲立刻到医院作检查、治疗,他的病是能治的。还有,后来妈妈对她把这个罪恶的板凳留了下来(她知道那板凳不结实)一直耿耿于怀。

2005年2月11日星期五

我的父亲 (1)

很多人都写过他们的父亲。我也想写一写我的父亲,因为他并不是一个写无可写的人,也因为他对我的影响,特殊而又巨大。

我从来都想做一个独一无二的人,在任何地方都能和一般人有所不同。我不记得我产生这样的想法是在什么时候,至少,我现在是这么希望的。无论如何,上帝似乎听到了我的心声,他帮我完成了一件我自己无法做到的事,使我从小在大家面前就那么地与众不同。看来,我真应该感谢上帝才是。

他做了什么呢?很简单,召唤了一下死神,让他把爸爸召唤走了。因此,从小在别人、在自己眼中,我就是一个十分特别的人:这人没有父亲。从某种意义上来说,这并非不是好事,只是当时的他们、当时的我还不能理解这一点。我承认,我并不因为父亲的死而感到骄傲,因为那不是我所能决定的。但是,我仍然爱着他,即使只能从旁人的口中了解到一点他以前的事,我还是认为,他是一个不平凡的人。

在我现在的理解看来,天赋有两种:一种是我们平常理解的那种天赋,即对某种事物超乎一般人的理解能力和创造能力,也就是我们平时说的“聪明”;另一种,我认为是对某种事物的坚持不懈的能力,也就是“刻苦”。并不是每个人都能自由情愿地对任何事情坚持不懈做下去。有的人能每天 8 个小时,数十年如一日地坚持练习钢琴,而大多数人则不能,我就认为,那个人具有音乐,特别是钢琴上的天赋。是的,可以强求自己刻苦,但那样达到的成绩绝不能和前者相比,因为,没有兴趣,就没有催化剂。

我的父亲从小就显示出了很高的天赋,第二种天赋。和他的兄弟姐妹相比,他所取得的成就也是最高的。小时候,他喜欢音乐。因为没有钱买小提琴,他自己动手制作了一把,然后每天就用它来自学自练。演奏小提琴很重要的一点,和钢琴一样,手指需要张开得很大。为了将自己的小指拉开,他在每次练小提琴之前都要先用夹板把小指用力拉开,然后固定住。最后,可想而知,他的手指达到了他的要求。

是对音乐的喜爱促使父亲练习小提琴,但他当时并不是想今后一次谋生。一次偶然的机会:一天,他与大伯逛街的时候,发现一家店铺正在出售一把捷克的旧单簧管。他们立刻回家,和爷爷奶奶商量了一下,以 300 多块的价格买下了那把单簧管。买回来后,他自己把损坏的软垫、软木替换了,然后以后就开始每天练单簧管。

家里人为他找到了一位单簧管老师,每周上一次课。和父亲同时上课的还有那位老师的女儿。另那位老师感到惊讶的是,每一次上课,父亲完成作业的程度都超出他的女儿很多。几个月下来,老师慨叹说,他已经无法再教下去了。他不知道,父亲是怎样每天在烈日下刻苦练习的。他也不知道,左邻右舍的人们是如何对父亲的这种精神评价的。

另一次偶然的机会:还是一天,他与大伯逛街,走到一家出售字画的店。店主因为本身就擅长国画,又与他们相熟,就让他们俩进去随意画两笔,反正也无妨。父亲从小随爷爷写字,对毛笔是也很熟悉。落笔画了一下,店主就十分惊讶,说这几笔画很有味道,父亲是可造之材,为何不学习画国画呢?要是愿意,他可以充当老师。回家考虑了一下,他们就答应了那位店主。父亲开始学习国画了。

仍然是每周一次,仍然是进步迅速,原因仍然是刻苦练习。还是几个月后,因为爷爷在北京有亲戚,就决定然父亲到北京学画。到了北京,父亲找到了王雪涛,此时他已经是一位老人了。在看了父亲画的画后,王雪涛立刻决定收父亲为自己的关门弟子。在北京,父亲为了买颜料、毛笔和宣纸,常常是饱一顿饿一顿,毕竟,爷爷奶奶工作也辛苦,从成都寄的钱也不会很多。伴随着身体日渐消瘦,他的画却是一天一天地在进步。王雪涛对他的这个关门弟子甚是喜欢,因为他确实比其他的学生更有天赋。一位在他处学了十余年的学生也说,他自己确实不如父亲。

回到成都的几年时间里,父亲的国画的水平其实已经超过了王雪涛,但是,他并没有办任何的画展或是出一本画集。他认为他的水平还不够。他是一个完美主义者,不完成他手头的事,不达到令他满意的程度,他绝不停下来。那时,他在成都都已经小有名气了,很多认识的人都跑来请他画一幅,他却并不一股脑儿地全答应。对有些人,他鄙视地说,就凭他都像让我给他画,没门儿。是的,他傲,傲的是他不想让那些根本不懂得艺术的人去沾染他的艺术。对于那些诚心渴求的人,他是从来不拒绝的。

他娶了母亲,生下了我。父亲的才能让外公爱不释手。作为当时新华书店总经理的外公,让他瞧得上眼的并没几个,而他却一有机会就和父亲在他的书房里聊得哈哈大笑:他赞叹父亲年纪轻轻就懂得如此广泛的知识。他对父亲的爱甚至超过了对舅舅们的爱,而他对父亲的爱也同样复制到了我身上。对舅舅们不公平么?这也是父亲应得的,付出化为的回报,又有什么不公平的呢?

人无完人。上帝赋予了父亲太多的天赋,也同时夺走了他过多的健康。便血,这是他身体出现异常的最早的征兆。他说服自己说那是因为痔疮。医院的化验单告诉他,那是直肠息肉。晚了吗?那时只有上帝才知道:晚了。39 岁,他就死于了直肠癌。对他不公平么?这也是父亲应得的,天赋化为的痛苦,又有什么不公平的呢?他应该也知道这一点,没有必要抱怨,事实上,他也从来没有抱怨。对他来说,唯一的只有一些遗憾,不能看着我长大,不能让更多的人欣赏他纸上的和心中的那些画卷。

一点感受

对音乐,我仍然抱着同样的态度:用文字来描述音乐乃是一件十分可笑的事。用文字来赞美音乐,这没问题,这也是谁都会的一项本事。而音乐本身是无法用文字来描述的,就好像试图抓住天边的浮云,就好像试图抓住逝去的梦境中的那件珍奇异宝。接受音乐唯一的真正的器官只有耳朵,而感受的器官只有大脑,因音乐中真正的本质乃是其中蕴含的关于作曲者的、关于我们自己的回忆和心中的感情。同等的事物可以相互感染,所以我们总是可以从连绵的旋律中捕捉到作者的心声,而不同事物又如何能息息相通呢?我以为,视觉、文字,仅仅能作为辅助的手段,决不能接触到音乐的核心。

饶是如此,这里我也要在写一下最近对音乐的感受。近来又收集到了几个版本的贝多芬弦乐四重奏全集,所以现在共有 Gabrieli & Aeolian Quartet 、Talich Quartet 、Quartetto Italiano 、Vegh Quartet 、Amadeus & Hagen & Mendelssohn Quartet 演绎的这几个版本。从喜爱程度来说,仍然是 Quartetto Italiano 的这个版本。Vegh Quartet 虽被誉为历史上的最佳版本,但其录音质量(我的版本录制于 1952 年)确实有损于音乐的表现。当然,其表现手法仍可谓是独一无二。Talich Quartet 的版本很独特,其总体音效的高音非常明显,而低音则过于黯淡,给人的感觉是,太过于单薄。G & A Quartet 和 A & H & M Quartet 的两个版本介于中间,个人认为仍不失为优秀演绎,但收藏的价值就不甚高了。

2005年2月9日星期三

回家的感觉

好久没有写过 Blog 了,可能有近 2 个月了。前段时间是因为考试断了网,后来回家后又因为宽带的问题(他们搞垄断,乱收费),昨天才重新开了网。

回来了这么多天了,发现这次回来的感觉和以前很不同了,觉得自己长大了,也觉得自己似乎并不“属于”这个家了,自己只是在这里暂时歇歇脚,为今后的艰难人生做好准备。妈妈仍然那么爱我,家里人对我仍然很好,甚至更好了,我却觉得自己变得越来越虚伪。我发现了一些事情,我很不希望看到、知道的事情。大家确实很爱我,甚至有些过头了。姨妈因为我比他的儿子(我和表哥是从小一起长大的)更懂事、更聪明,有时流露出一丝骄傲、嫉妒和遗憾的神情;外婆因为相同的原因,爱护我这个外甥远比她的亲孙子;奶奶因为我父亲的原因,对于我的爱那是有目共睹的……我觉得,我的存在,或者如他们所说,“我是这一辈人中他们唯一最寄希望的”,似乎已经不再那么单纯的是能引以为傲的了,它,好像也在伤害着某些人。我个人对此并不感到有什么压力,他们的希望于我并不产生任何影响,我还是我,我永远是我。但会有一天,我不再是我吗?

这段时间买了很多书看,主要都是计算机和数学方面的。现在觉得,在我这个年龄,如果还不抓紧时间多学一点知识,以后就很难再成为佼佼者。玩,并不是不想。首先,玩什么?游戏,电影,逛街,这些离我好像都非常地遥远,对这些也提不起兴致(可能另有原因吧,嘿嘿);其次,就像我原来说的,我应该搞清楚,自己追求的“到底”是什么,是短暂的快乐,还是持久的荣誉?搞清楚这个了,该干什么就很明白了。

还有一点很重要的,是关于我父亲的。这次回来,我从大伯、姑姑那里了解到了很多关于爸爸的事,对他,我又有了一些新的看法,这些,我会过几天再写成另一篇文章。我以我是他的儿子而骄傲!

基本上就是这些了。今年的春节和往年基本一样,也就是说,毫无新意。不过,有点感动的是,居然有6、7位同学、朋友发短信给我,着实没有想到。是我变了吗?还是大家变了呢?