wpe7.jpg (11495 bytes)

我的征尘是星辰大海。。。

The dirt and dust from my pilgrimage forms oceans of stars...

-------当记忆的篇章变得零碎,当追忆的图片变得模糊,我们只能求助于数字存储的永恒的回忆

作者:黄教授

二〇〇四


一月四日 天有阴晴,月有圆缺

昨天,看了《我的野蛮女友》心情很郁闷。今天总算完成了让我太阳穴疼痛多日的scanner。不过,对于注释的输出处理得不好,所以,当注释很长的时候,会有些问题。但是原来的作业要求并不是那样。先这样吧,否则今天的心情就更加郁闷了,难道是因为参加老朱家的party?我想这不是真正的原因。但是,心却莫名的疼痛。。。改了好几次,总算完成了。我自己都觉得有些不可思议,我为什么要去实现"nested comment",实现并没有什么,问题是有什么意义呢?难道你要求程序员写注释的时候都要考虑括号匹配?我纯粹有些无聊。为了绕过feof,我不得不用ifstream,而这时我一向不喜欢的,为了能够把空格,回车换行符都读到,我不得不用一个低级函数get,结果换行符成了1310,我只能把这两个都当作是whitespace。这真是烦。我还突发奇想把程序的源码当作输入文件,知道这是自动机的那个鬼证明题在作怪吧?你不明白?当然了,不是computer science的有几个明白?当然了,那个源代码被改得七零八落的。


一月七日 雪霁

我还不敢开始我的parser,因为和scanner比起来难度是几何级数,这正如context-free-language的复杂度不是regular language所能比拟的。很多基本的算法我都还不懂。去找教授没找到,却看到一幅有趣的漫画,其中的寓意与孔圣人所谓的人需要鞭策异曲同工,我应该就是这么一个贱骨头,如果价格合适的话,我也许应该去买这样的东西。回来的路上,在地铁里倾听“地铁音乐家”的即兴创作,其中那位爱沉思创作的电子琴手的演奏让人流连忘返,仿佛引领你的想象力在无边无际的原野驰骋。我的parser也许应该是OO并非简单的object-oriented而是operator-oriented,因为所有的语言里都是operator为中心的。

玩了一会儿c++的宏命令,因为,我一看到Java就总觉得恶心,这种小孩子的玩意儿,我猜想肯定如同当初我学Delphi一样都是人家做出几个类包装好了你设定几个属性,对着回调函数写事件函数,那时候好有成就感啊!结果学了半天并不是在学习什么编程,只不过是学习其他程序员的编程习惯,包括变量函数的命名习惯,因为,你天天在用的就是别人命名的方法名字。想到这里我就来气,想起不知道在那里看到的一段议论,大意是业界使用开发工具来把程序员变成白痴,大学则是想方设法与之抗衡,但是随着越来越多的大学使用Java这种白痴工具,看来这种竞争中工业界占了上风。一气之下,我决定定义一行宏以后统统用sesame open door来代替using namespace std。


一月十日 酷冷

半夜醒来,想写一个“语法”阅读器,因为CFG本身也应该以文件的形式来读入,可是,问题没有想清楚,结果就如同“软件工程”这门课里介绍的一样,一个project半途而废。我不知道在我开始写parser之前还要准备多久。


一月十二日 冷酷

磨蹭了好几天才完成了一个如此简单的小程序:context-free-grammar reader。是否有人明白其中的用途?因为要写一个parser,而他会不断地需要检查语法,此外,假如我们可以由用户定义语法,势必要有这么一个语法阅读器,不用说去除left-recursion就更是需要了。写在还很不完备,仅仅是从文件读入了,对于一个数组来说添加删除是一件很头痛的事情,就把语法修改的任务放到下一步吧?因为我想吃饭了。

无聊之际跑到sinoquebec发现我一年前贴的帖子现在还在,不过把年份换成了2004。


一月十四日 零下31度,加上风力你会认为是零下43度(是摄氏不是华氏)

我不明白究竟零下30度和零下四十度有多大的区别,我也不明白在这样的清晨里在户外做苦力会给你留下多深的印象,我只知道当我坐在我的小屋里迎面看着从门窗射进来的刺眼的阳光时候,头脑中也如这惨白的阳光一样一片空白,人的记忆难道真的如沙滩上的脚印一样朝朝暮暮地被海浪洗刷的一干二净?我记得我的scanner所用的我自以为很独特的方法不过是table-driven的一种变形,而且不容否认的是table-driven比函数数组来的更有效率,更容易扩展,因为,在编译器的设计里,函数都是一种奢侈品。我记得我的梦想随着我的前进一步步地模糊,我记得我曾经以为自己是一条一天到晚不停地游泳的鱼,我记得我总是沉浸在深度搜索里几十层以下畅游的乐趣,我记得我总是幻想创造一种新的语言,我记得我时时刻刻意识到自己是一个凡夫俗子的痛苦。我记得什么?我只记得我今天冒着严寒干了一早上挣了20块钱。除此之外,没有什么了。

以后要记住‘0d*’代表八进制,‘0xd*’代表十六进制。要在c里面表示单引号:‘\'’。双引号同理,'\'单独用在macro里做换行符,feof有函数和macro两个版本,我也不知道编译器用哪一个,干脆以后直接用FILE里面的flag来判断好了。


一月十五日 阳光灿烂可是应该很冷很冷的

与jeppeter君商榷,你的mailbox退信,故改在这里了。

Is template a kind of macro in C++?


一月十六日 下雪了吗?

The several stupid mistakes I made when first using java.


一月十八日 天下着大雪

殚精竭虑,夙兴夜寐,终于完成了table-driven-scanner。我为了效率考虑,不惜去初始化一个138x72的巨大的表,同时还有别的表,用尽了我所能想得出的dirty trick。一般情况下我是不大喜欢把code写的这么tricky且无延展性的,可是效率,效率,效率。以至于我甚至把15个关键字也纳入了DFA的状态了,就不用说256个ASCII字符了。


一月二十三日 天晴了

scanner有一些小毛病,比如错误出现的行号会差一行,因为,换行符被读到的时候正好是token结束的时候,同时error-handling的机制要改进以便将来整个compiler都可以来调用。其他都是小问题,就不值一提了。在旧书摊买了一本关于二次大战中加密解密的故事,我觉得学计算机科学的学生都应该来读一读,因为信息科学乃至所有的科学文化都无非是一个加密解密的过程。在amazone订购的英文版<besieged fortress>过了半年才到。

下午想转到另一个section没有成功,心情很郁闷,我并不是100%认为Dr.Probst是一个不学无术的教授,可是,至少他的方法我认为是失败的:在学生还没有接触任何实际的一个操作系统的解决方案之前向学生灌输独立于操作系统的原则与思想是非常危险的,也是非常无用的。我不可能荒废一个学期时间来学习理解加拿大电视台里快嘴主持人的俏皮话。痛苦之余只好写一个奇怪的字典聊以自慰。这是一个奇怪的数据结构,也许受Huffman编码的启发吧,我一直觉得我没有能在数据结构的学习中尝试自己写Huffman编码是一个很大的遗憾,为什么在Concordia不讲讲这个有意思的东西呢?在效率与节省内存之间我总是捉摸不定,一开始我曾经想用一个快速字典来查询,也就是每一个字母下有26个字母,这样一个巨型的树需要多少字节呢?即便我用最精省的bool来表示,一个所有单词不超过8个字母的字典需要大约200G的内存,太夸张了!所以,我只能缩减为链表结构。当很多词有类似的拼写的时候,或者说有很多相同的子串的时候,我的结构比二叉搜索树有更好的效率,并极大地节省了内存。当然,我的字典非常难以删除一个词。


一月二十九日 晚上开始下小雪了

346的作业实在是bullshit!这不是我说的,这是“阿里”说的,不过也是我所想说的。

354的project需要一个简单的文字显示界面,我想把这种routine的layout的工作简单化,就写了一个Layout manager。原理很简单,说起来好笑就是把每一个可显示的对象定义为长方形,那么这个对象会有一个左上角和右下角的坐标,这个区域内的显示让对象自己去通过一个pure virtual的方法displayRow来实现,其他部分的default的显示就交给Layout Manager来做了。


一月三十一日 这是补记的日记,忘记天气了

The Daemon arises here.


二月一日 天气好象是不错的,忘了

If you cannot see Daemon, I can show you.   Anyway I shouldn't say about the minor issues.

Maybe we should neglect the minor one and concentrate on the Deamon.


二月二日 天阴沉沉的

Either my English is too poor or we are not talking about same question. I think I have to ask someone else.

What a wonderful explanation!!! And finally we caught the subtle daemon! Mokhov 可以说是我在Concordia里不多几个值得敬佩的研究生了。

这几天我被动态链接库所折磨,被多线程编程所折磨,理不出头绪,各位客官是否有那位能够在dll得编译上指点我一下?先谢过了。


二月三日 阳光明媚

既生瑜儿何生亮?


二月五日 下了一天一夜的大雪

这个语法阅读器真是累。熬了半个通宵才完成了一个功能:common-left-factor这是语法修正的两个内容之一,我的预想是这个功能完成之后,再remove-left-recursion的时候就不用担心有两个以上的left-recursion了。但是,同一个variable有三个或三个以上的语法有common-left-factor怎么解决?CLF不止一个token呢?这些都解决了,不过好累啊。


二月六日 又开始下雪了

殚精竭虑,夙兴夜寐,昨晚是连骗带哄的完成了语法阅读器中的remove-left-recursion的第一个小功能,也算是一个版本吧?

早晨不甘心我在dll编译上的挫折,又重新来过,终于不负苦心,明白了必须加extern "C"的编译指示,而且也可以从delphi里调用了,从此,可以重新考虑图形界面的选择了。昨天有人告诉我说昨天是元宵节,昨天又看到北京看灯会踩死很多人,中国真是一个遥不可及的世界了。


二月八日 天晴了,阳光灿烂了

我总是无法完成我的计划。今天早上起来把上一次的烂尾工程做完了---remove-left-recursion的第二个部分,remove-immediate-recursion,意外的收获是发现我原来的想法不对,我本来认为在RLR与CLF之间应该先做CLF这样就可以取掉一个以上的immediate-left-recursion。结果我发现这样做会产生redundant variable,所以我就先做RLR再作CLF至少这样不会有redundant variable了,看起来舒服多了,再说怎样去出redundant variable绝对不是我现在所能完成的,I am pretty sure about it!虽然First set刚开了个头,我想还是先保存这个版本吧?另外,我把前一个 版本里面难懂得代码改了改,尽可能写成小函数,比较好读一些。

My idea of project.


二月九日 晴天一个霹雳!

我的天!当我看到{...}这样的meta symbol对我的语法阅读器不亚于一个晴天一个霹雳!天哪!我怎么去表示这种语法呢:A -> L { , L }这里的{...}相当于Kaleen star这怎么来表示呢?还有对于我已经完成的RLC,CLF以及First set来说,这也是一个大大的问题!而且更严重的问题并不是在计算Follow set,因为那只是表示方法的问题,在parser的过程之后的sematical analyser 才是大大的问题!我简直不敢想下去了。不过还好老师给的语法好像不会有大问题,至少现在是这样。我现在已经没有太多的选择了,只好走一步,看一步了。不过令人欣慰的事,我的工作并非完全是无意义的,也就是说我花了一个星期写的工具并非一个傻瓜可以不用这个工具随随便便在十五分钟内用手工完成。(不过脑子灵便的应该可以吧?可是,我想单单用手key in这样繁琐的工作很难不出错吧?我相信电脑不相信人脑。有那位有不同意见不妨看看这样的语法。这里是电脑优化过的去除了left-recursion, common-left-factor的结果。)为保险起见,现存一个first的版本再去计算follow。


二月十日 天没有塌下来

其实都是庸人自扰!{}与|有什么本质的区别呢?我昨天就是脑子转不过弯来。今天拼了老命才把follow写完,虽然难度上和first一样,甚至代码都很相似,问题是其他相应的bug层出不穷,我先是为了{}的错误在付出代价,把它取出就是一个麻烦事情,后来又发现,即便是RLC与CLF依然会产生redundant variable。我没有办法了!虽然能够去除明显的redundant,但是多余的语法我实在不想再去除了。太累了,当这个类超过一千行代码时,我对他的作用开始产生怀疑了,而且,我单单磨刀就用掉了一个多星期,parser的影子还没有看到呢。我不敢再去优化他了。暂且这样,还不知道以后会发现多少bug呢?


二月十二日 天气很好

昨天心情一直不好。昨天夜里更遇到噩梦般的问题,几乎使得我一个星期的工作夭折。我的scanner是手写出来的,我没有去动态地产生token-type,这样即便我的parser是根据语法产生的,我怎么能够把scanner返回的token-type和我的语法里的token对应起来呢?另外,我的NT-Table建立的时候会检查语法是否符合LL(1),我还发现了我的程序没有办法替换非直接的common-left-factor。我只好硬生生地把那个捣蛋的语法放到出错的语法前面强迫先进行left-recursion的替换。此外,我发现我还有很多繁琐的工作忘记作了,比如去除一个token的代价是改变整个表,绝对不会比去除一条语法来得少。所以,干脆不去掉了。先暂时保存一个版本吧?

二月十三--十四日    今天天气好象还不错:小雪(我说的是昨天也就是十三日)

终于完成了我的parser:一个我可以少许为之骄傲的工程,一个自动读入以E-BNF形式写成的CFG语法;一个自动进行去除left-recursion,common-left-factor的语法优化器;一个自动计算所有non-terminal的First, Follow set的语法计算器;一个自动生成LL(1)语法的parsing table;一个以parser为核心的,由parser驱动的table-driven的scanner;一个table-driven的parser;一个相对独立的错误处理小模块;一个我呕心沥血费时近一个月(parser+scanner)写成,将近三千行代码的,也许marker只用十分钟就胡乱批改完的工程。(我真想痛骂他几句,并不是所有的学生都会像我这样傻傻地费这么大的力气来学编译器吧?即便是研究生也不一定会有几个会去写这种吃力不讨好的东西,对吧?那么我是否应该得到最起码的尊重?)而且,我一直有一个观点,这个也是从去年教我C++的那个老师那里得到的:没有写过超过两千行代码的单个程序的程序员是不会有面向对象的需求的。(当然,不要告诉我你写的是图形界面的程序,因为,那种程序别人替你做得太多了,你自己写的如果有两三千行的话整个程序应该非常的大了。

如果,我把它作为情人节的礼物,不知道有没有女孩子想要呢?哈哈。。。应该不会吧?

随便玩玩frontpage做做实验


二月十四日 好像要下雪了

和黄勇探讨离散数学获益不少,又把以前的问题再讨论了一遍。实际上对于特殊形式的Chinese Remainder Theorem的问题:

S = M (mod p)   (1)

S = M (mod q)   (2)

(1) +(2) + gcd(p,q)=1  ==>  S = M (mod p*q) 并不需要用到chinese remainder theorem按照黄勇的简单的obvious地证明法:(1)+(2) ==> (S-M)|p   and (S-M)|q 。根据P183Lemma1(S-M) | p*q因为:(1) ==> exists some k such that (S-M) = k*p;   (2) ==> k*p | q ;   and   gcd(p,q)=1 + Lemma1 ==> k | q ==> (S-M) | p*q

想知道Lemma1是什么? a*b |p  +  gcd(a,p)=1  ==> b | p


二月十五日 天又变冷了

早上把作业小小改动了一下,因为我实在是没有耐心去做那种机械重复的工作,只好用程序来做。下午睡了一下午,晚上和朱春明同学夜话数据结构与离散数学,回来意犹未尽就想玩玩多线程,结果成了四不像。我本意是dining-philosopher的问题,写的时候想到的是bounded-buffer,后来改成了reader-writer,实际上什么也不是,我不想仅仅把pseudo-code翻译成c++。那么改来改去就不知道在干什么了。


二月十七日 天气倒是很好

我们伟大的教授总是习惯于用他那种奢侈的方式来浪费宝贵的内存,目的仅仅为了方便他那不习惯于c形式的index。这样的程序用什么意义呢?对于parallel prefix sum来说,除非有多个cpu否则会有更好的效率吗?当然这是一个小孩子的玩意给初学多线程编程的学生做的。


二月十八日 寒流依然肆虐着大地。。。

透过双层玻璃窗注视着我的阳光是那么的炙烈,现在的白天依然短过黑夜,冬天会踯躅到五月,夏天短暂而热烈,那时候庆祝的人流里有美酒和音乐,而现在这里还是冰雪的世界,在24小时开着暖气的日子里,我的星辰大海般的征尘就是我的一切。。。

想去公共图书馆看书,结果没有开门,正好去区政府领取“回收箱”,一切手续都那么简单自然,不禁让人想到马恩列斯描述的“当社会财富极大丰富的时候,社会所要做的就是按需分配”,这不就是在某种程度上是国人的理想吗?可是,我耳闻目睹的却多的是抱怨,更多的是向往国内某种人压迫人,人剥削人的制度。一辈子抬轿子过苦日子的奴隶翻身解放之后,不是先尽情享受自由的幸福,而是首先想尝一尝当初所痛恨的坐轿子的生活。最想当奴隶主的其实是那些整天被压迫的奴隶,正如同所有的农民起义领袖最终都要做皇帝一样,而几乎所有的产业工人也都向往着做一个资本家。人剥削人,人压迫人的不是制度,可能只是人类的本性。

地铁的音乐家是我所敬仰的一群,从学校图书馆回来,又看到那个胖键盘手在即兴创作,我可以体会他沉浸在音符里的快乐,也许正如同我对BIT&BITE操作的乐趣。我以前除了汇编几乎没有去玩过BIT的操作,今天为了节省内存空间,不得不把SHIFT&REDUCE的信息放在一个代表STATE的整数的高位,因为,我的LR(0)语法表不想用结构来存储。碰到一个白发苍苍的老人家向我要零钱,我就把我仅有的几毛钱硬币给了他,心情觉得很愉快。我想只有穷人才会真正帮助穷人吧。monk地铁站的那个吉他手弹得很敬业,他的吉他都破的绑上胶布了,可是,他还是一如既往的弹着那时而激越,时而幽咽的古典吉他曲。


二月十九日 天气好热

按照老师的code练习了一下dining philosopher这样经典的线程同步的问题。我发现我只有具体写的时候才真正理解了每个philosopher需要三个状态的用意,才明白是每一个吃晚饭的philosopher的责任来唤醒他两旁的人来吃饭。但同步以外的一个显示的问题还是解决不了,就是每一个线程用cout来显示的时候会一团糟,我试图给显示部分统统加一个mutex,但是这个会影响到整个线程的运行。最后,我只好将结果全部存到一个数组里,等线程结束的时候才显示。这实在是一个笨办法,不知道各位看官有什么高招,我将不胜感激。


二月二十一日 昨天开始下雪了

这是昨天完成的sleeping barber的小程序,应该是一种简单的练习吧?


二月二十三日 晴

今天和朱春明同学区看大教堂,有一次感受到了中西方文化的冲击,我们再一次对中国文化里的繁文缛节不切实用的倾向作了最深刻的批判。吃完饭看到艺术广场上的“暖亭子”,就是大功率的红外加热管做的小亭子,人们可以在最冷的冬天里坐在露天喝咖啡,晒太阳,真好。简单的写了几个基类,是用在console里显示用的。


二月二十四日 大晴天

console里的类又改了很多,加了几个中间类。黄教授和小韦买了鱼和酒,我也喝了一杯,,基本上晚上就是放假了。不过红酒这东西总是让人心里有些怅惘与迷茫。听着王菲的歌曲,格外的有滋味:天晓得,既然说,你快乐就是我快乐。。。


二月二十五日 又是晴天

board加强了好几个功能


二月二十六日 天光光

加了一个rummy来验证同花,顺子,和group(就是炸弹了),并且加了一个接受用户输入的简单的类--CListener,并把以前写好的字典稍稍的改动了一下。


二月二十七日 又是一个大晴天

354的project暂时有了一个初步的样子,我想再回到我的被打断的LRParser来,这时候才体会到他的复杂性,我仿佛是一个奉命突击的战士,当我已到达冲锋的位置的时候我才发现我还不理解命令的实质,又好像一个初次登临讲坛的讲师自以为一切了然于胸而到了现场被一个简单的提问就蒙住了。正如Professor Grogono的email里说的,当你准备讲稿的时候才发现你其实并不了解你要讲的问题。我想编程序的最大的好处就是,除非你对这个问题十分的清楚一直到每一个细节,否则,you are stuck for sure,不管你看书的时候多么的自以为懂了,都没有用。我想今天似乎锐气已经挫尽了,暂时重新整顿一下再说吧。

胡乱逛来逛去,找到我以前在csdn.net上贴得AVLTree的源代码,有个家伙的评价是AVL比较难实现的是remove而我却没有实现,当时很不服气,我也记不清我以前是怎么做的,就回了个帖子说AVL从BST(Binery Search Tree)继承来的,remove的方法可以照样用的原因,使我把AVL内部remove的实现改过了,后来仔细看代码才发现,我好像当时并没有实现,因为,insert就已经很复杂了,我奋战了好几天,后来没有做remove,很惭愧,只好下午补课。真是好复杂,而且好像没有现成的算法,也就是说,造成不平衡的要移动的节点并不一定在被remove掉的节点的一侧,这样问题就复杂了。而且,应该转动的balance factor为+/-2的节点的两个子节点有可能factor都等于0.这样是和insert大不一样,我没有办法,只好看到一个情况改一个,天知道是否还会有别的情况,海,有谁知道算法?


二月二十八日 加拿大的天是晴朗的天

早上看了一个上午的Mr. bean就是不想做我的作业,我现在仿佛对programming以外的作业都提不起兴趣来了。朱春明同学提出一个很有意思的问题,使得我去查c++的源代码,看到了其中一个从未见过的操作符重载operator void*()。


二月二十九日 阴天

You almost convinced me.


三月二日 现在还是临辰,不知道什么天气

LR(0)也许是我第一次让我对自己的程序失去信心的一个吧?我写到后来简直不敢相信程序有可能运行。因为,创建一个DFA需要的东西太多了!我对这个东西前后思考了一个多星期,真可以使夙兴夜寐,殚精竭虑了。当我运行出来一对结果时候我已经不再奢望去进行检验了。能run就好了。


三月四日 我昨天刚刚把冬天的衣服收起来,现在好像又要下雪了

LR(0)完成了初步的修正,改掉了一些bug,主要是类似于left-recursion导致死循环创建DFA的状态,还有就是parsing table的mask里面int类型问题,这个困扰了我许久:一个32位的掩码在和我的状态值“与”操作后居然不能再与这个32位的掩码比较了,也许微软编译器把0优化为一个较短的数了,我是这么猜测的。当然也发现了我一个stupid bug。我居然用16进制的0xd01111111来做掩码,这是好笑。我不想做一个临时的LR(0),所以,想直接就建立LR(1)或者SLR(1)等等。不过,parser还没有写出来,虽然不会复杂,还是要多想想,因为,还有很多问题不明白,再次验证了,只有写程序来实现才真正明白要解决的问题。现保存一个版本吧。当一个类的实现部分超过两千行代码的时候,维护工作确实变的有些棘手。


三月五日 天下着小雨,中雨

去实验室完成了project的一两个新功能


三月六日 晚上居然开始下雪了

朱春明同学请客去了一家中国人的karaoke,门票5块钱,进去后看到的一群男女觉得好像又回到了福建乡下老家安海镇。保存一个版本吗?算了,明天再说吧,有点不好意思称之为版本了。


三月七日 阳光灿烂,哪里看得出来又下过雪?地上干干净净的

The professor is an idiot on programming。。。  

I don't bother to guess his word puzzle as long as my program works.

Is algorithms in PA2 more efficient than that in PA1?

改正了java多线程程序中的算法,现在是按照老师的意图了,对于多cpu来说应该有更高的效率,可是,我得到的解释却是五花八门的。

写了一个模板实现的hash-table。希望能够写的尽量通用,可是,用template传入用户自定义的方法这一点上我很为难,太多了使用不便,太少了又缺乏通用性,是否模板与继承总是一对矛盾的双方呢?

我觉得我没有办法再去攻克comp354的project里的DFA,这对我来说是一件痛苦的事。我以前总认为DFS是我的噩梦,可是在学了automata之后,我知道DFA<==>DFS,他们对我来说是同样痛苦的记忆。我看了一晚上的<pretty woman>发现我实际上几乎没有从头看到尾过,这也许仅仅是感觉,而不是事实。也许因为,我不相信那后半段的神话,因为没有人相信,连导演都觉得太过分了,故意在结尾强调:This is Hollywood, a land of dream. 我们对梦想的态度也许都是近似的,正如在Julia Roberts的另一部超现实主义的浪漫剧<Notting Hill>中男主人公的经典台词:It is surreal, but nice。

田震的歌声配着我下午花了30个dollar买的speaker自有别样的韵味。在孤寂的,干燥的,寒冷的春夜里,我还毫无倦意,也许一颗心总在迷茫中漂泊。


三月八日 早上好象下雪了

去上totorial又在实验室里和angel研究明白了程序里的很多问题。现在好像对整个程序算是明白了,这算是编程还是猜字谜?不好意思就在贴一个版本,表示我今天并非无所事事一整天。翻出来以前的东西,作为我自己的理由吧。完成了一个简单的CPlayer的控制类,连同上一次做的CBag类总算可以算一个版本了。


三月十二日 晴朗的天空下大雪,这就是蒙特利尔的特色

上午阳光灿烂,我还和老张跑步去Maxi买菜,下午天空依旧晴朗,只是突然飘起了鹅毛大雪。奋战了好几天总算把一个初步的symbol-table做出了。我要说这个步骤对于compiler-compiler-writer来说都是最头疼的,因为,你看,作为scanner,parser我们可以做到完全的自动化,可是,这个时候,我不得不开始研究语法了。离开语法特征我完全无法知道该在什么时候作变量声明。当然,以我的意见,这就是之所以几乎所有的compiler-compiler都是LR的一个原因,因为,再LR里面的“状态”是非常有用的,而且你不会把原来输入的语法改的面目全非。我决定明天再作进一步的测试,现在保存一个版本吧?

朱春明同学的一句话叫我至今耿耿于怀:写程序本没什么了不起,惟手熟尔。这本来是我的原话,可是却听起来不那么顺耳,如果这样一言以蔽之,世间的万事万物岂不都是惟手熟尔?可是,客观地说,问题的复杂度一般都是不一样的,此惟手熟尔非彼惟手熟尔,正好像算法之间的复杂度的表示法中的big Oh一样,还是应该有所区别的。我无意贬低或抬高什么,(真的吗?人都有好恶的吧?) 也许其他人并不像我一样执著的相信人类的未来全部寄托在一些诞生不超过50年的“语言”的创作加工者身上。因为,也许人类的最终的解放就是彻底的自动化,其中的核心就是Intelligence Automation(I.A.)。也许A.I.这个词被用的太滥了,为了表示敬意,我创造一个新词来反用。这一切的一切就从编译器的自动化来开始吧?我想我在这个充满期待的即将到来的夏天应该能够写出一个完美的LR parser compiler吧?加上一个lex-like-scanner。这是一个多么让人激动地计划。但愿我不负了自己的誓约!

晚上没心情做别的事情就玩了会多线程,还是老问题,就是同步里的小问题,太简单了以至于我不好意思提出来,不过,我想我还是有可能犯错误的。同时对于windows上的多个线程的运行顺序感到不可理解。另一个奇怪的事情是SwitchToThread这个API明明在头文件里定义了,MSDN里也有,可是就是链接不上,后来我把api函数的定义拷过来,等于是直接调dll里面的api还是连接不上,说明dll里面确实是没有,window2000也是如此。看来只有问微软才知道了,该去那里问呢?


三月十三日 天气真冷啊,而我已经把厚衣服收藏起来了

早上调试我的compiler真是累啊,按照老师的意思是要彻底的测试,我这个project已经有四千行的代码了,有不少我现在都快忘了为什么那么写了,而这种语法测试实在是麻烦,首先你自己要知道结果吧?不然测什么?太累了,就和小邹去saint Laurence河边上去看冰层花了没有,真冷啊。下午去游泳,好久没有锻炼了,可能叫我游上一千米都会有些问题吧?屏气也坚持不了两分钟了。回来发现了scanner的一个大bug。不过,我觉得这个问题责任不全在我,因为老师当初没有说end of file也是一个token。否则我就不会这样出错了。如果以后要修改scanner的话,一定要记得。


三月十四日 天气还算晴朗

今天是Saint Patrick Day早上先把数码相机的电池充好电准备去看热闹。早上又在debug我的compiler,真是一个痛苦的过程,我想如果我当初能够用LR来写就不会这么写的ackward。还是留一个版本吧?


三月十六日 阴天

晚上上课回来偶然聊到《大话西游》因为我没有看过,感到有些遗憾没有机会了解现代的大学生的心态,所以就借来看看满足一下好奇心。当然是不明白所以然,本来也没有所以然,因为这正如P.P.所写的多线程程序一般充满了chaoes,一切都是只言片语,也许每一个场景都是刻意的塑造成永恒,而整个线索的无序成为事实上的无聊。因为,这也许正和激动的年代的躁动的脚步合拍。

昨晚和今天早上奋战完成了一些初步架构,保存一个版本吧?code generation摆在我面前的困难逼迫我要彻底地解决parser的问题,下个星期这是头号的任务。把昨天的小改动合并一个版本吧?


三月二十一日 阴晴不定

这几天事情不少,喜忧参半,烦恼不少。是否都要一一记录呢?summer research project算是一幢好事吧,去欧洲的旅费至少有了着落,word rover大致完工也算是一件高兴的事吧?因为我原来定下的目标就是这个周末完成。令人烦恼的还是操作系统这门课,哎!还有一些privacy的问题,真不知从何说起,欲说还休,不提也罢。

前天跑完步之后对springland的朱春明同学的居室进行了一次短暂的工作访问,对双方所共同关心的话题广泛深入地交换了看法,会谈的气氛是友好诚挚,会谈的结果是令双方所满意的。会谈所涉及的话题有就人类的认识发展与生物进化的关系,马克思主义哲学与形而上学之间的异同,离散数学在编译原理中的具体运用,自动机原理与算法理论等等,在相互的切磋探讨中进一步加深了彼此对客观世界的观点看法地了解,取得了广泛的认同,这次交流是一次有历史意义的盛会,双方都表示今后要定期举行此种交流,不妨成立一个名为springland-monk的合作组织,定期举行交流会。

保存wordrover的版本。


三月二十五日 小雨

好几天没有动笔了,或者说动手吧,因为,现在这学期所有的课程的作业都要电子版,几乎没有动笔的了。这几天也没有干成什么,除了改动了游戏的小bug什么也没有做,code generation的部分我还是没有开始,我又一次地陷入了这么一种困境,就是已经到达指定出发阵地,也接到了冲锋的命令却还不知道要向哪里进攻,甚至觉得连武器也没有找到。早上读了一遍moon machine的文档才略略明白了一点,我现在要产生的是intermediate code,不是什么真正的assembly code,只是一种自定义的类似p-code的代码,目标机器是一种想象的虚拟机,不过说想象也不对,因为,基本就是229里面定义的机器,而moon就是Dr. Grogono写的一个模拟器,我对他的敬仰又加深了一层。早上粗粗看了moon的源代码,又把范例的汇编码拿来编译运行,现在才真正有些明白了。模拟器人人都可以写啊!想起来当初在York旁听的时候偷偷下载的模拟器,当时觉得真是不可想象的神秘,看到是MIT的教授写的,就对MIT肃然起敬,现在想想Concordia的教授不也是能够做的吗?

常常地想,一个人每天头脑中的思虑何止百条,其中不乏真知灼见,甚至是灵感的火花,可是凭借常人的记忆有多少留了下来?过后回想起来总觉得如《围城》里面描述的,如同一个竹篮子去捞月亮,定神凝思总觉得就在那里,可是动起手来抓却都是空空如也。从前总觉得思虑如电,无数的华章美句在脑海里纷至沓来,但觉得伸手一抓,抓到哪一条都是挂一漏万,总想象着如果有一个agent环仕左右随时记录该有多好,现如今有机会及时纪录了,又发现经常头脑空空了。


三月二十八日 春光明媚

所以我就出去晒晒太阳。我看到的“冰河时代”以及“Saint Patric Day"。

心血来潮玩了会汇编,我常常想,假如我是生在dos时代的程序员我也许可以成为一个写汇编的专家吧?哈哈,我有点自不量力了,不过我觉得我确实对他独有情钟,可惜时间精力不允许我。记住编译的一个小错误:extrn声明部分是放在.code部分的!先编译/c,后用link链接都没有什么特别的。


三月三十日 蒙特利尔的春天终于来了

346的作业


四月二日 阴雨绵绵

已经一个多星期了,我几乎昼思夜想穷尽心智以求一个解答,昨天再次去见Dr. Opatrny才算有一个方向了,我完全不必用stack去模仿function call。这实在是一个不能承受的工作量,不是说有多么复杂而是说我不可能又回到了“汇编”时代啊!实际上真像教授说得那样:“90%的工作量来自于code generation”。我又连续几天利用时间冥想准备,仿佛攻坚战之前的火力侦察,养精蓄锐终于决定今天早上发起进攻,初步决定准备付出一天的时间和牺牲100万脑细胞的代价扫清所有的外围阵地,包括必要的数据结构,状态控制方式,框架函数,并预留出最终代码产生所需的一些函数的calling位置。如果一切顺利明天发动总攻,后天写文档测试,星期一留半天机动作为总预备队,决心一定,依令执行!任务完成不了,各级指挥员剃头来见。(不过,前天我已经把头给剃了,哈哈,我发现男人的智商和头发的长度成反比,女人的柔情和头发的长度成正比,那位有意见不妨提出反例?)这一个星期没有写程序结果我全身上下都开始出问题了,首先是头疼,其次是脖子疼,晚上睡得少,下午睡的沉,天天头脑空空。。。 

我最近眼神不好,也忘记怎么数数了。*_*  ~_~ &_&  :)


四月三日 天阴沉沉

战斗进行的异常艰苦,我从来没有遇到这样顽强抵抗的敌人,我的意思是说我现在已经把程序改的面目全非,简直惨不忍睹,现在根本不考虑什么效率与coding的艺术了,完完全全是白刃战肉搏战,所有的代码交织在一起,难分彼此,遍地是stack,不停地增加enum和struct,经常回过来在struct里面添加新的field。局部变量随处可见,全局变量已经到了命名的极限。战斗进行到这个阶段完全是一种胶着状态,唯一可能战胜敌人的武器就是指战员的意志和信念:Dr.Opatrny说过,if-statement是最复杂的,解决了他,就解决了一半。

战斗进展的很不顺利,我一方面根本不知道可能遭遇的困难,另一方面,每前进一步都是那么的艰难。

累死我了,眼睛都快睁不开了。没有完成既定的任务,不过在负出了惨重代价的同时,成功的攻克了if-statement。我实在太累了。


四月四日 又下雨了

现在是早上10点,六个小时以前我留下的一个版本还没有办法实现function call,现在依然不行,因为,参数的传递与检查是一个不容易的问题。一个人究竟需要多少时间来睡觉呢?


四月五日 又下雪了

人间四月芳菲尽,蒙特利尔飘雪花。昨天提前庆祝我的code generation大功告成,其实本来也没有什么,只不过我想给自己一些奖励罢了。于是,在肖邦的钢琴曲的伴奏下,油爆了一小盘冻虾,炒了一盘白菜,煮了一锅红豆稀饭,倒了一小小杯的8。99一升的干红,这样的生活真好啊。这样的生活不知道还有什么不满足的?今天打扫战场又改了不少的bug,就保存一个版本吧?或者说合并上一个版本


四月七日 天晴但冷

改了很多的bug,并加了一个结束画面,现在可以把我的小成果给大家展示一下了。唯一可惜的是只能在win2000或win xp下运行。


四月八日 现在天还是黑的

昨天,Probst介绍了一个所谓的多线程算法---parallel-ranking-list,问题本身似乎没有什么实际意义只能作为多线程的练习,不过我还是想了半个晚上,因为,写c++习惯了总喜欢数数,不懂得应用已经获得的数据,也就是说,计算ranking的时候,你可以把你的后继的rank加到你自己rank里面,只要保证这同时,你的后继不再改动。其实这个同步问题还不如去计算一下pizza店里面多个server的队列的问题来的更有实际意义。


四月九日 晴天

花了一整天时间找我的wordrover的bug。现在这个版本算是完美版了吧?我把字典改成了可以增加的,也就是说每次运行前从dictionary.txt和readme.txt读入,运行完以后由存回dictionary.txt,这样我的字典可以越变越大,你不喜欢完整的字典吗?当然你不喜欢的话,你就把dictionary.txt删除或者改名,然后再readme.txt里面输入你喜欢的词。


四月十二日 大晴天

早上去跑步,中午去shopping算是负重急行军,回来后躺在场上让灿烂的阳光晒在肚皮上阵舒服,醒来后又去和小朱去跑步,这就是我的感恩节。应广大群众要求把comp346的所谓project贴出来,我实在觉得不好意思,如果被其他学校的人看到不定要怎样笑话Concordia呢。这也算是我一直藏拙的一个原因吧?这么一个简单的链表操作居然被冠以project的名目,真是让我等学计算机的人无地自容啊。教授不要脸面,学生还是要的。哈哈。。。复活节童言无忌了。


四月十三日 雨

应同志们的要求不敢藏拙,把我的346作业贴出来献丑了。另外这是课本的标准答案,使Laura发给我的,我想不能不与大家共享。还有probst在最后一堂课里讲到的考试范围,不过我的涂鸦可能连我自己都不一定看得懂,如果你不明白,再来问我吧?如果我也能看得懂的话。:)  1, 2, 3


四月十六日 好像夏天一样

一直盼望着夏天,可是当我们都能闻到夏天身上的气息的时候却又不知道要做什么了,只能到太阳下走走。编译器的战斗到了最后的阶段,不知道什么原因指战员有一点点厌战情绪,也许这个project远远超出了当初的预测,也许是前面两个阶段即symbol table和three-address-code做的非常不好使得我现在非常不容易进一步扩展,可能就像software engineering课程里软件扩展曲线变得非常陡峭,也就是说我现在没做一次扩展所要花费的时间精力正以几何级数增加。


四月十八日 又是阴晴不定

compiler这个project对一个人的编程的信心打击是最大的。我面对复杂的内存分配,终于开始后悔我当初想写一个完美的compiler乐。因为,人力有时有尽,对我来说记忆力下降到我对我的代码始终像是看天书,尤其对于在跟踪moon模拟器里的汇编码简直不知怎样入手,你看,我的compiler产生的汇编码我自己就看不明白对不对还要去内存里跟踪模拟器,到底谁对谁错我能清楚吗?现在我才真正体会到做一个现代的c++的程序员有多么幸福,因为在一二十年前编程是一件多么痛苦的工作啊,我对我自己在这么傻瓜化的vc下玩代码实在是要被人笑死了,当然,我去嘲笑玩VB,java的人的那种刻薄劲会一分不拉的被真正的高手还给我。世界之大真是超过我的想象力了,我现在觉得自己浅薄的如同台湾南部坐井观天的那帮农民了。数组对我是一个头疼的事,我初步想法试用类似于c面的指针一类的特殊变量来实现,这是一个复杂的问题,我不知道能不能行,在传参数里用真正的reference即地址和用stack传递value,最后在回写是各有利弊的,我不觉得我现在的传地址的方案有什么原则上的失误,当时对于数组我却始终没有想出好办法,229里面有专门的寄存器来记录index,而我却想不出怎样模拟。现保存一个版本吧?我对code generation部分非常得不满意,决定将其等级将为一颗星。 moon machine的模拟器在这里。


四月二十日 有雨

总算完成了绝大多数的功能,这一直都是我不敢相信的!我不敢相信这是真的,经过了这么多的磨难好像唐僧去西天取经经过了八十难,不知道那最后一个磨难会在什么时候出现,最好是越早发现越好。我的这个project充满了遗憾与不足,假如能让我从来过,我一定要把scanner与parser一同来写;我一定要用LR(1)来写;我一定要把code generation部分分离出来;我一定要临时变量重复使用stack里的地址;我也许要使用类似于passing by value的方式,因为,这给了module里面的数据的独立性,如果,要passing by reference就简单地pop回原来的地址,因为,绝对的passing by address是一个非常危险的方式。我也许要彻底引入指针变量,而不是像现在这样似是而非;我也许想要解决label的问题,因为,并非所有的汇编器都这样的支持label吧?总而言之,是否用3-address-code的中间代码是一个值得考虑的问题。我要重新设计我的中间代码指令集。明天,不,应该是今天要继续作大量的测试,同时争取把报告的结构理出来。教训就是:never underestimate the difficulty!这个问题再写我的word rover就已经遇到过了,我当时还希望加入华丽的图形界面,多种选项,甚至A.I.。结果全都是不切合实际的。现在我已经根本不奢望提前demo了,能够不出现问题就谢天谢地了,看着我的那个乱七八糟的parser+code gengerator部分,我经常不敢相信这是我写的,因为我经常看不懂,不过,后来当我穷经皓首地调试跟踪汇编码的时候,我开始羡慕调试c++程序了,毕竟那是比较接近人的思维的吧。保存一个版本

对了,前两天收到不知名的美国的一个大概是college的学生发的邮件央求我替他做project,大概是一个min-max-heap的数据结构的东西,虽然我很有兴趣,实在是没有时间,而他的due date比我的还早,只好婉言谢绝了,毕竟人家透过google找到我这里不容易啊。而且这家伙网页做的挺漂亮的。现在敝人在google上也是榜上有名的,不信把我的大名输进去查一下,哈哈。。。自我陶醉一下吧,在这个温暖的春夜里听梁咏琪的歌曲很有一些情调的。


四月二十一日 晴朗的天空好像蓝色果冻,白云好像棉花糖,我有点饿了

其实,现在天空是黑黑的,离天亮还有好几个小时呢,我奋战了一晚上才找到递归调用的问题,其实并不是我所担心的是栈的问题,恰恰是我从没有想到的条件转向语句的问题。if-then-else,loop-end都有小问题,等我发现这种错误,我已经跟踪那天书一般的汇编不知多少回了。随便几行代码,汇编就是上百行,我看的头昏脑胀,因为,并不知道问题是编译环节有好几层,我再不能确定问题出在那里的时候,找起来真是困难。现在总算解决了,至少看上去是这样,fibonacci,factorial 之类的经典递归功能都可以了。我也快累死了。就让我在梁咏琪的歌声中留一个版本吧?

明天就要交报告了,我在梁咏琪青春靓丽的歌声中回顾我的日记中关于编译器的部分,突然才意识到它是这么的漫长,我从严寒的冬天一直写到春暖花开的季节,断断续续的有四个月了,粗略统计可能有近六千行代码吧?实际上当然包括不少的注释,和comment掉的代码,不过这些部分表示实际的工作量要比这多得多,因为,一方面改错绝对是很辛苦的一件事,费的时间更多,另一方面我想有关语法的注释可能比代码部分更难懂吧?如果你没有学过parsing的话。回顾这中间的苦乐酸甜,真是一种令人难忘的经历,正如歌曲里唱得那样:突然之间翻到了小说结尾的那一章,我想我不但要给教授一个report,也要给自己打一个分数吧?如果要打分的话,那就给个75分吧?因为,这是从我付出的努力来着眼的,毕竟从最初写语法阅读器有很多intuitive的成分,从这一点出发,我对自己还是满意的,这之前我并不明白什么是compiler-compiler,只是从直觉出发,抛开所有的工作不提,我想我应该给自己这个分数。教授给我多少分,我倒是不太在乎了,只要我学到了我想要得,还计较什么?至少我想我会有一点可能比班上其他人写得多一点点,或者真实一点点,那就是报告的最后一部分,wish-list或者一个what-if或者一个if-only-list。我在这门课程上投下了这么多的心血,同样也得到太多的遗憾与不满。假如让我重头来过,我会。。。

人生也许就是这样,假如。。。我会。。。我会吗?


四月二十五日 晴间多云

O.S.实在是一件无聊的事。整理了一下我的编译器,现在包含了最后的一个版本,以及moon的所有文件,和我的报告。点击这里download

线程同步的问题非常难。有没有兴趣讨论一下,指点我一下


四月二十六日 有雨?

今天在学校呆了一天,晚上才回来看到同学们的妹儿,是关于以往probst346考试题目,赶紧贴出来,希望大家讨论一下。

You are really a genius!  And even great Mokhov might have made a mistake?

Probst的很多问题,你并不知道他想问你什么,这就是最大的问题。我看了几道他的问题,我决定放弃,因为,我非常怀疑他的很多问题是从哪里抄来的,所以有些名词和思想怪怪的。也许这门课真地像他说得那样不用看说,不如去看summary。我随便打了几道题,实在是有付诸位的期望。


四月二十七日 有雨

昨天真是一个黑暗的日子,concordia真是可耻的学校,教授连考题都懒得出,竟然沿用上学期的题目!我当初可以想象Probst是一个Phony Scholar因此,作业出的数年都一样,还真没想到它连考题也敢这样干!虽然,那些题目我看过和没有看过区别不大,不会的还是不会,但毕竟让我觉得好像作弊一样,写到最后一题,我实在是懒得检查了,也许多检查一遍就相当于多作弊一次吧?我说过,教授不要脸面,做学生的不能不要。不过,后来想一想,似乎也没有什么,因为学校毕竟没有禁止重复出考题,比如229据说题目就经常重复,对于所有concept多于计算的课程,这也许是通病。

早晨没事做,就翻了翻那本我一直想读的《Battle of Wits》,这是一本讲述二次大战密码战的书。这是我的心愿,因为我一直认为人类的一切文明活动都是一个加密与解密的过程,你读书,听人说话,也不过是将一系列的声音文字信号进行翻译,任何有意义的信号都可以想象成一种密码形式,也许从密码学里可以找到我所需要的灵感。没看两页,又想起要做一个monitor,找了半天,没有头绪,就先练习以下Event吧,我不明白auto-reset的event和semaphore究竟有什么区别?有那位高手可以告诉我,在这些众多的同步对象里,我究竟应该怎样正确使用?因为,有时候感觉可以有很多种办法来使用这些semaphore, event,mutex??


五月一日 晴有暴雨

下午去和朱春明踢球结果遇到暴雨,我就在雨中踢球跑步。晚上向小韦借来久已向往的DVD《master&commander》,确实是震撼般的真实,就如同我小时候看过的《达尔文》般的令人震撼,认识一种蓝色文明是要花费几代人的时间和代价的,就如同这种文明形成需要很多个世纪一样。大英帝国的辉煌是建立在blood&sweat上的,决不是中国今天这种blood&sweat工厂!中国这个民族不具有这种历史与这种禀赋,至少没有可能在一个世纪内形成。那种组织,纪律,信仰,热情,勇气,信心是我这个黄土文明所不具备的,至少我们看不到在中国的历史上各朝各代的贵族几乎没有已扩展疆土,征服自然,征服同类或者异类为己任的,把对自然规律的追求与战场上的勇气加以完美的结合,一手拿手术刀,一手拿长剑,医生间作屠夫,自然科学家和战场上的战士加以完美的结合----A fighting naturalist


五月二日 阴天

经“梧桐大虾”指教,我决定暂时停止《曹操传》的测试工作,重写一个简单版本的bid for 24的程序,这也就是我们小时候玩的凑24 的小游戏。我重写的原因和方法很简单:一日不练手生,写程序这玩意,越不写越手生。当然这个版本比以前要好懂多了,因为,我从前刚开始学c++脑子还转不过弯来,现在写这个就容易多了,同时,最主要是对问题清楚,不想第一次的时候要先把问题翻译成一个可以用计算机解决的问题,这个也许是最耗时的一个工作吧?程序的名字叫“24revisited”这是学习《matrix》的手法,明明已经解决了的问题,为了商业利益硬要编出一个狗尾续貂的续集,而且一编就是两个续集,真是无耻。

五月三日 又是阴天

看《battle of wits》里面的最基本的加密法----Vigenere Tableau,原理很简单,但是很有效,因为,二次大战以前大部分的加密可能都是固定公式替换,不管你的替换方法有多么复杂,哪怕你把次序也改变了,可是你不能改变的就是个个字母在语言里的出现频率,比如字母'e'在英语里面出现的几率大约是12%,'t'是9%等等,只要有大量的数据可以统计那么你的加密就算破了。因此,Vigenere Tableau解决的就是这样一个问题,方法也很简单也很古老,用一个任意的钥匙来分割字串,这样同样的字母就不会被替换成相同的字母了。这不能叫做程序,只是我学习的方法,当我不明白一个算法的时候,用写程序来理解,这是一个笨办法,别人学不来的。


五月十三日 夏天的每一分钟都像金子一样宝贵

我这段时间在干什么呢?我没法给自己一个满意的答复。看到二战中日本曾经用过的一种奇怪的加密方法:元音与辅音分开加密,比如六个元音用一个6x6的Vigenere Tableau,其余的20个辅音也用Vigenere Tableau加密,不过,我不敢确认我的理解是否正确,一个简单的示范程序写的头昏脑胀。为了简单起见,假定元音与辅音用同样的密匙。我觉得这种加密法很不怎么样,因为,至少别人可以从元音的特征就能推测出你的词汇。不知道是因为日本人比欧洲人笨很多还是因为我理解错了,总之,比起德国Enigma来实在是一个天上一个地下。


五月十九日 我傻傻地站在街角假装等人实际上在享受灿烂的阳光

Il y a du Nouveau (There is something new!). Just be patient for my Enigma.


五月二十一日 阳光,阳光,加拿大最廉价,也是最宝贵的物资

小韦拿来的DVD《PayCheck》,看了之后,你应该会明白这一定是DreamWork的作品,甚至我一直认定男主角是同一个人。因为思想和技法和《MinorityReport》是惊人的相似,简直是翻版,不过我不知道别人是否这么看,至少我的印象是一样的:中心思想是雷同的,未来如果可以被预测,将是一场灾难,未来如果被预测,人的命运将可以改变,也将不存在命运,也将从根本上否定未来是可以预测的,我想这是人所共知的逻辑paradox。从特技的角度可以看到DreamWork似乎很喜欢那种玄到刀尖般的新科技,并且一切都加上了超完美主义般的戏剧巧合,一个科学家可以比《MissionImpossible》中的超级特工更加专业,仅仅凭借对未来的一知半解一个人可以上天入地,无往不利。实际生活中很多人对自己的未来充满信心并不见得就可以成为一个超级特工,对吧?就算你十分清楚你将来要做什么,能做什么。不过,这还是一部不错的片子,好就好在它符合我一贯的理念,并且略微的超出我的想象力,这也是我最喜欢的游戏风格,简单并且有一点点难度。我的Enigma有些问题,加密之后如果不能正确的解密,那还有什么用途呢?


五月二十五日 阴天

很多天没有做什么有意义的事情了,除了测试《曹操传》,这真是我的大问题。感谢“柯云”大虾指出我以前作业里的重大错误,(那个marker基本上不改作业)在polynomial里面指数是相加的,我花了好两三个钟头想继续维持原来code的简洁与一致性,后来发现几乎不可能,索性重新定义一个小函数,花不了几行代码。我猜想,乘法与加法是处在不同的“阶”,在算法上可能不能统一吧?这当然是我胡思乱想了。


五月二十八日 阴晴不定

五月是一个堕落的月份,我几乎什么也没有做,除了偶尔写了几行的SQL,学习了两行PHP,而且这实在称不上编程,太多的计划,和太多的遗憾了!我原本以为学完了compiler design我在本科学习中不会再有programming的挑战了,可是,现在碰到的这些我认为soft coding似乎并非完全如我想象般的容易,因为,并不要求你做的有多么的好,多么专业,可是,你要做的杂,比如,在perl里面夹杂了一大堆“surface evolver”的定义,就让我看的不知所云,这也是我始终不想开始我的project的一个原因。database德project里面也是夹七夹八的,要再html里面嵌套php,然后连接到oracle查询。如果,我没有sql的经验,我觉得让我在一个半月里面做这些太不容易了。早上鼓起勇气,准备写一个关于dependency的东西,也就是数据库里会用到的function dependency。刚开了一个头,就偷懒不写,就实现了一个reader的功能。为保持版本的连续性,就记下来吧。见笑了。


五月二十九日 晴天,阳光灿烂但是很冷仿佛到了冬天

昨天和朱春明讨论的关于类的问题应该是这样的:对于composition的成员的constructor带参数的情况,即类的数据成员是另一个类的对象,并且它没有默认的constructor,或者说他的所有constructor都需要参数,且不是所有的参数都有默认值的情况下,只能在该类被包含的类的constructor加初始化语句,也就是“:”领头的在constructor之后的语句。之所以不可以在类的成员变量加上他所需要的参数的明显的原因是那是类的声明部分,而基本上所有的编译器对于声明部分只做类型检查。对于方法(method)来说或者函数来说,声明部分不是必需的,可是类的声明却是必需的,原因应该是成员变量地址分配的需要,因为这些不是在stack里面动态分配的,类本身就是从结构扩展而来的,所谓类的constructor仅仅是在内存分配完后才执行的第一个方法,自然结构体内的任何成员都是在此之前完成分配的。c++的编译器应该是在c的编译器上扩展而成的,自然对于声明部分采取与c的函数一致的策略,即只检查类型。顺便说一下,昨天写dependency的时候的一个一分钟的疑惑,我的rule类里面是一个模板类bitset,它需要一个特殊的类型参数(真的是类型吗?)也就是一个集合的size来initialize这个bitset。这不算是constructor的参数,因为,作为模板类,他的参数决定他的类型,所以,他在我的类rule里面还是作为成员对象的类型声明而已。

The symbol is beyond what you see with mortal eyes...


五月二十九日 大晴天可是很冷

今天花了差不多一天时间在重写我的集合类,这个题目是和DFS,DFA一起成为我最喜欢写的题目,虽然写来写去变化不大,我却乐此不疲。也许出了疯狂的操作符重载之外就只有遍历所有的子集的方法值得一提了,按照以往的习惯我总会希望写成函数指针做参数的哪一种回调函数的形式,或者是用模板参数传递方法指针,这一次我完全按照c的习惯类似于“strtok”方式多次call,这个更简洁。


六月一日 临辰从睡梦中惊醒感到无比羞愧,外面下着细雨

这个五月是无所事事的五月,我在梦中都感到无地自容。left-redundancy如果不清楚的话,我是否要继续我的程序呢?

为了减轻自己的内疚,我花了两三个小时完成了一个小小的功能:计算candidate key。

在实验室呆了一下午,练习那些无聊的php连接oracle。这种编程让我想起了刚开始学习delphi的情况,玩着别人做的玩具自以为很有成就感。我想这样的人大约有几百万吧?


六月二日 天色阴沉沉的,还很冷

LOGIC@#$%^&*SET ?????!!!!!!


六月三日 晴朗的天空飘着白云,突然一阵风吹来下雨了。

加拿大的小生意真是难以生存啊,看到每年这个时节monk的区政府就要想尽办法振兴商业,花了一大堆钱,步行街,小火车,露天集市,可是货品年年一样,那些小商店的货品连价钱都和去年一样,存留那些放了多年的皮衣已经慢慢变成一种类似博物馆的意义了,怎么和walmart这种巨人竞争呢?只有在中国商业还处在一种早期的阶段,小商业还有生存的意义与空间,但绝对不会永远。

我的dependency基本完成了,现在完成了canonical cover, candidate key,  decomposition, lossless checking,甚至还有dependency set的logical imply, equivalent的功能,还需要什么?

六月四日 晴朗的天空灿烂的阳光

写一个callback函数的小例子

好为人师的我为了说明回调函数可以用模板来类似的实现,折腾了一个下午,最后终于搞明白了是vc++的一个bug。这一点,我觉得我应该是可以负责地说了吧?因为,这个问题应该和我让我们伟大的朱春明同学向他所敬仰的Hanna老师请教的问题一样:VC++的编译器在识别模板函数的声明与实现部分有问题,搞得我一个下午都在怀疑这怀疑那。


六月五日 阳光还是灿烂,可是屋子里还是有些冷

伟大领袖毛主席教导我们,理论必须与实践相结合,并在实践中得到检验和发展。于是,我就以我的comp353的实际的project来检验,找出了很多的bugs,并且,我的程序经受住了考验,实在是太强大了!想想看,设计的时候不用去画什么E-R图,只要把用户可能用到的attributes写下了,再写出他们之间的关系,即dependency,然后,我的程序自动运行,自动计算candidate key, canonical cover, decomposition to BCNF and check lossless joining。你所要做的就是根据我的decomposition建立表,根据其中的dependency的lhs设定为key。这么简单,这么强大!


六月七日 阳光,绿树,清风

阳光,绿树,清风。绿油油的树叶被亮灿灿的阳光映射的发亮刺眼,茂密的枝叶被轻柔的无法触摸的清风抚摸着而发出快乐的沙沙笑声。我一只手拿着1.29元一大袋子的一个大面包,另一只手拿着4.99元一大箱子的一根小黄瓜,坐在后院里法国式的黑色螺旋扶梯台阶上,仰头看着头顶那灿烂度只有广岛原子弹爆炸时一千分之一亮度的太阳,耳边听着从我那心爱的笔记本那单薄的扬声器里播放的钢琴板的王菲的《爱与痛的边缘》,幻想着假如有一天当我的银行户头里的余额万一不幸地达到了天文数字,我是否还能如今天此时此刻这般的快乐?我问对面的大树,大树不停地摇头说不;我问头顶的太阳,太阳翻着白眼不屑于回答这等简单的问题;我问身边隐身人一般的清风,清风调皮地抓起凉衣绳上衬衣的两支长袖朝我一阵乱舞,回答说不;我低头扪心自问,肚皮听见了我的问题,听了听厨房里灶台上蒸煮的沸腾的一锅清水煮土豆的咕噜声,也情不自禁地学着咕噜了一声,算是回答。对,决不能让那种可怕的日子到来!我决定继续在加拿大坚持扶贫工作。


六月十一日 天晴

感谢Vincent发现的一个dependency的大bug! database的project实在是不好做,因为,双拳难敌四手,php操作数据我总觉得别扭的紧。

Dependency vs. 3NFTry with dependency!

我的dependency作了一个小小的改进,就是计算candidate key的时候,剔除掉所有只出现在右手边的元素,因为他们绝对不是key的一部分,正如同所有不出现在右手边的元素一定是key 的一部分一样,这可以大大加快搜索,我粗略估计了一下,集合大小为39,试验其中一个有19各元素的集合的所有子集是否为key的过程,通常会运行10分钟以上,我实在没有耐心等下去,经过这个小小的改进,只需要大约一秒钟了,这是几十上百倍的改进啊!


六月十三日 晴朗

把我做的小工具贴出来。这是一个数据产生程序


六月十四日 阴天

We don't allow employee to be deleted.


六月十六日 晴天

our assumption。这是昨晚我在眼皮睁不开前发出的mail,估计Jean应该不会在熬夜的时候check mail。


六月十七日 阴天但是很舒服的日子

羔羊的沉默。 下午睡醒了才头脑清醒地明白,我早上想的问题是:natural out join 和Cartesian product的关系问题,我始终想把两者统一起来,这种统一的想法并非如朱春明所说的那种统一场之类的不可能,世界上本没有什么不可能用理论来解释的现象,比较难的是这种理论本身是否可以被别的理论所揭示。因为,即便是随机数,在有限范围内我也可以用一个或一系列公式来产生,当然,超出这个范围并不适用,我需要更多的修正方程,正如脚痛医脚,头痛医头的经验公式的修补,只要你有新发现,旧的公式不适用,我就推翻重来,如此便是相对论。这种科学究竟是一个自圆其说的过程还是。。。

加入null的Cartesian product。

明天要考数据库了,趁机把project文件都备份以下,其实都是一些零零碎碎的东西,大概9个query里有三四个还值得看一下,因为有的query大概有超过两百行的sql吧?我写了10个triggers, 有一两个还值得以后浏览一下。其他大都是htm和php的垃圾,再就是在linux上玩sqlplus连接oracle你非要写一些小东西,不然累死你了,比如soft link这个东西我就发现很好用,ln -s /yourpath/ softlinkname,以后cd softlinkname就可以了,不用再打字了。


六月十八日 阴天,但是经常看到太阳

A simple example of initializing constant in class. This is from book, I mean, I rewrite them.


六月二十一日 晴间多云 

You usually need a default constructor for your base class, but not always unless...

关于赋值兼容的解释:你可以把子类对象赋给基类对象,编译器很愉快地接受了你的选择,为什么不能反其道而行之?也许你再做一个很大的项目,写了一个函数,参数是一个类,过了一年,功能要增加了,你从这个类继承了一个子类,增加了很多数据成员和方法,很无疑地,你也许还是怀念你一年前的代码,至少它对于原来的基类的操作是很可靠的,你现在也许也仅仅就需要这样的功能,你把子类的对象带入了这个函数,编译器很信任你的选择,因为,虽然参数传递过程中很多子类的新数据成员被“砍掉”了,可是,没什么,因为,你本来就没有指望他们在这个旧函数里有什么用,当初在写基类的时候你甚至没有意识到你的代码会流传千古,也不会为还未诞生的子类多操心。按照继承的顺序来做兼容就是这样的。

class Father {。。。};

class Son : public Father{。。。};

Father fatherArray[ArraySize]={Son("son1"), Son("son2"), Father("father1");


六月二十二日 阴雨绵绵

帮助同学复习数据结构真是一件快乐的事情。温故而知新,不亦乐乎?


六月二十六日 今天中午下了一场雨

终于有机会可以安安静静地看我买的《1984》了。我个人的意见是超现实主义往往比科幻电影更难以理解,至少对我来说是这样的,因为,科幻电影是努力让你明白一件难以相信的事,而超现实主义是努力让你不能相信一件你相信的故事;《第22条军规》(Catch22)就是这样一个例子,应该说这是和“兄弟连”完全无关的电影,但是两者的对立总是让我将其联系起来。影片一开始就让你相信美国空军是一个疯人院:任何正常的人必须完成飞行任务,只有疯子才可以停止飞行;任何人要停止飞行必须提出申请,但是提出申请的人就已经自己证明并不是疯子,所以,没有人可以停止飞行,这就是第22条军规---catch22。其中的风言风语所在皆是也。比如,美军查封意大利妓院时的理由也是第22条军规,因为,美国是世界警察与审判官,他是法律的执行者与制定者。当然,所有这一切都是:The most insane thing a sane man has done before he got insane。


六月二十八日 晴间多云

即将过去的六月是一个失败的月份。我的Enigma是一个未完成的烂尾工程,不时有多么复杂,而是当时时间不允许,事后又因种种理由,也许是google搜出了一大堆关于Enigma的程序,让我觉得有些兴味索然吧?原本这就是一个算法的实现,非常的straight-forward,没有多少实际意义,在计算机发明之前,破译的可能性确实是非常小。另一个令人沮丧的就是database的project做得有些失败,虽然我觉得自豪的是写了一个dependency化简的程序,并且几乎所有的问题我都基本上用一个query来实现,可是,从软件工程的角度讲是一个失败的典型,无论是组织,设计,调度等等无一不是失败的。summer research project也是一个不成功的例子,对于evolver的使用我还是茫茫然,再perl与c++语言之间反复徘徊,甚至连续犯了一些低级错误,至少有两三天时间让我对VC6.0浮点运算产生怀疑,真是好笑。当今天终于想兑现我的LR-Parser的承诺的时候,面对我的CFGReader得繁杂我又开始望而生畏了。可以想象仅仅一个几千行代码的小工程的改造就让我头痛不已,怎么可以想象将来的巨大的expert system呢?人真是一种渺小的动物,借用Matrix里面Agent嘲讽人类的口头语:Only Human!我还有多少愿望与梦想要在这短暂而宝贵的夏天来实现呢?秋天,冬天两个学期我给自己的计划也让我感到不安,我是否真的能够一学期上15,16各学分的课吗?即便扣除乱七八糟的英语数学化学,一个学期上三门comp字头的四学分课程实在是一种折磨,对于我来说这样的安排肯定是遗憾比收获来得多。今天,我翻找compiler design的笔记的时候看到comp348的讲义心头又是一阵得难受,这门课可以说是我在Concordia的一大遗憾,正向我在给Dr. Grogono的mail里说得那样,我在学完了compiler design之后才开始真正理解很多comp348所讨论的计算机语言上的概念,我真希望我能在自己有接触更多的计算机语言之后再去上这门课,可惜人的经历就是这样一个不可逆的过程,我在双脚踏进恒河之水的时候就已经注定要后悔了。这个秋天和冬天我是否又走在恒河河边上?

为了忘却的纪念,先把我的失败的Enigma贴上,这样一个简单的东西我还没有做好,真是一种耻辱!好让那句熟悉的话语经常回荡在我耳边:Your mission is a failure!


六月二十九日 早晨的太阳懒洋洋的

昨天在最后一分钟下定决心take engl207这样秋天的压力小一点,实在不想买原版书,就上sinoquebec去买二手书,一看大多数卖书都是comm经济书,想想也对,Concordia学经济的中国人早就如过江之鲫一般多了,这是理所当然的,但是卖书的这么多的原因也许不仅仅如此吧?抑或这经济之道原本就是过河之后要把桥拆了当劈柴来卖,抑或学经济的人原本就是把这个行当当作敲门砖,门敲过了还要砖干什么?当然门敲过了不代表门一定会开,也不代表敲门的人还会继续顽强地接着敲,敲门的砖倒是很有可能要丢掉了,一则砖是随地捡的,得来便宜(所谓的书大多是复印的,简称书云云),弃之自然如敝履,二则要敲别家的门也许还要别处去捡新砖头(听说蒙特利尔这个中国人的小圈子里面每隔一段时间就有一些所谓的热门专业)。抑或出国,读书都是所谓的敲门之砖,敲敲看,说不定门就开了,不然就再念一句咒语:Sesame! Open the door!世界上本无绝对正确的门,门开了人进去了,事后大可向别人证明自己捡的砖头平整,自己认门道来的精明,然则进了门廊是否还要登堂入室,进的外门是否还想要进内宅,敲得开大门,是否还有运气打得开二门。自然,门坎都未找到何必担忧其它?同样一群门外汉彼此之间又有什么本质的区别?只是偶尔地想象一下登堂入室的感觉罢了。也许人之一生本就是一块敲门之砖,不然怎么会有那么多人信奉所谓的天堂,对于他们来说,人生的尽头就是一扇天堂之门,能不能打开却要看今生所谓的积善积德,这一辈子就是一块砖,这也许并不是最可悲的地方,因为最可悲的是两敲门的人都不是自己,自己只是别人用来敲开他们的贪欲之门的一块砖,这些别人自然是那些宣称自己高高在上,端坐在神坛之上通天教主。人恒弃敲门之砖,砖亦恒弃弃砖之人。

经过昨天的深刻反省,广大指战员认识到斗争的严酷性,决心攻克Enigma的堡垒,经过一天一夜的鏖战终于完成了。教训就是不能像当然,比如密匙轮的转动问题,我一开始以为用两个数组来表达,加上平移就够了,其实不对,我需要另外26个数组来表达输入数组的每一个平移。再比如,我一开始以为密匙轮时不停地转动,其实不对,应该是每一个字母处理完了才转动,否则无法解密了。光这两个问题我就debug了一整天才明白。下午抽空又重看了一遍<kill bill>实在是精彩,相比之下张艺谋的所谓“英雄”简直就是一个玩笑。


六月三十日 阳光灿烂得如同那个什么一样。。。

早晨从睡梦中惊醒,有梦到在中国读大学考试的时候竟然不知道要考什么科目,头脑中不记得一学期学过什么课程,卷子发下来之前坐在考场里想来想去,最后竟让我猜到了:应该是考辩证唯物主义。醒过来才觉得可悲,那时候,我什么书也没有念,整个班级除了一心想出国的那几个天天坐在第一排的女生外大家都号称不读书,人人比赛看谁能在考试前的最后一天用最短的时间突击并能取得最高的分数来证明自己的聪明才智,有时候,不小心区教室自修回来的路上总像做贼一样,因为如果被人看到一定会被取笑低能弱智:这么简单的课程居然还要学,你如果考试成绩不高就更会被人看不起,如果你不幸考的还可以,同样会被人归结为死读书靠拼时间而不是靠聪明才智取得的成绩。那个时候生活得非常压抑,因为大家都不读书,只有畅谈怎样赚大钱才是时尚的话题,宿舍里大家整天在打麻将,下军棋,围棋,后来连桥牌这种东西都被认为太费脑筋不如80分来的简单刺激。那样的年代,那样的青年,你难以想象其中的很多人是那个时代的精英。我这么说也不是很过分,因为,其中的很多人现在也确实是在赚大钱的,可是,这些是中国的教育的成果呢,还是教育的失败?不管怎么说,我不属于那个团体,这个结论的得出花了十年的时间。我试图寻找另一个答案,也许要在花掉十年的时间。如果有了结论,我在想那个时候我是否还在乎答案;如果没有答案,我是否会再找一个解答,或者。。。

给我的Enigma加一颗星吧?我对自己不满意,为什么要对我心爱的程序不满呢?也许这颗星是所有星里面比较不值钱的,可是,出于对Enigma的敬仰我不能拒绝这个请求。满足了这个要求,我不能拒绝给CFGReader也加一颗星,这本来就有的,只是当时我过于苛刻才摘掉了,现在补回去。


七月二日 晴

折腾了一天一夜的唯一结果就是找到了一个sample能够从c的命令行来调用sql server。但是编译有问题,花了我一天的心思也没有找到解决makefile的办法,唯一的结论就是vc6.0得编译参数应该有一些是以非文本方式写在.ncb文件里的,因为,在.dsp里面我能够找到所有的makefile的参数,但是external dependencies file的信息不知道写在什么地方,难道是编译的时候自动生成的?这些真是我的痛苦的地方,找不到合适的资料,摸索的过程好像在破解密码,而且浪费了大量的精力。


七月三日 好天气

久有凌云志,重登皇家山快乐的一天

实际上,昨天的问题后来是解决了,解决的方法是我突然脑子开窍了,悟出了一个道理:我辈学武所为为何?不就是用计算机解决实际问题吗?这个出发点找对了,我那么关心很多细节为何?也许那个sample是用vc以前的版本做的,或许她的makefile有特殊的地方,可是这一切都不重要,重要的是我要用它干什么?我管他那些自定义的数据类型干什么?我管它是否能够和dos兼容干什么?我管它是用于什么windows版本干什么?只要我把它改道在我的notebook上运行就可以了,就这么简单,何必耗费我的宝贵精力去钻牛角尖?我有更重要的dependency-analysis的想法要去实现,为什么要去研究这一类如同“回”字有四种写法的职能作为炫耀的资本的问题呢?

Turing真是一代伟人!他有锐利的眼光能够透视出Enigma的真谛:在三个rotor的情况下,共有17576各不同的映射方程要去识别,可是,Enigma的齿轮传动是每26个字符之后,中轮才转动,也就是说,又一小段(25)字串是非常普通的单个轮子的26各映射方程,这就大大简化了识别的难度。(因为,可以把其他中轮(middle rotor),后轮(right rotor),反射轮(reflector),替换线(stecker)想象成一个单一的映射方程。)也许常人穷心竭力也能有万分之一的机会悟道这一层,再往下就不可逾越了,因为,后面的部分我就没有看懂,明天再看。:)


七月五日 阴天

把这两天我的微不足道的工作做一个备份,首先声明,这个连接类仅仅是为我个人的目的,并且我没有写什么程序,仅仅是把MSDN上的例子包装成一个简单的类以便我自己使用,我想这不算是侵犯版权,各位如果看到也不能耻笑我的coding能力,因为我压根没有些什么程序。我的真实目的仅仅是想从c/c++来连接SQL server,并且我的要求也很简单,连接,传送SQL statement,最简单的显示,好像SQLplus一样的基本功能。也许下一个版本加一个简单的script-file的功能。其中,我花了大部分时间在试图弄明白为什么采用windows验证时候连接不上,结果还是没办法,只能采用SQLServer的用户验证。不明白。


七月七日 小雨

今天无聊之机就写了个小工具,在UNIX下我们有grep去查找字串,可是没有替换工具,这就是我的replace,它可以接受命令行参数:usage: replace filename source target 现在只能选择替换第一个出线的字串。


七月八日 小雨

15puzzle的问题我以为我以前解决过了,偶然翻看从前的代码,首先是目不忍睹,其次是我根本没有解决。我本以为这又是一个简单的DFS得简单问题,结果发现我的想法是不对的,状态并不能用一个空白方块的位置来表示,(这一点我以前应该是明白的,但是现在忘记了,又作了一遍。)所以,当我发现程序运行十几小时无结果,我才意识到不限制loop不行,但是,我简单的用方块的位置的loop来限制又不会有结果。(这个东西我应该是在写走迷宫的程序利用的,对于一个方块在迷宫中的移动这是正确的,对于puzzle来说必须要考虑所有的方块的位置,这是不是vector space呢?)为了开始别的解决方案,现保存一个版本,毕竟失败的东西也是有意义的。

我一直印象中我写过一个更加通用的DFA标准类来做DFS。可是,我找了许久没有找到,最后还是在VC++德workspace里发现有源代码,才在我的网页里找到了html文件,但是很显然没有发布出来,我觉得这个程序是我所有DFS类里面写得比较好的一个,可是为什么没有发布呢?我想可能是那段网站初期没有highspeed连接的非常时期遗漏了,看来是把一个宝贝捡了回来,不是吗?这一次再一次充分证明了我的记忆力是有限的,(我想谁都是差不多的)三个月后,或者半年一年以后再回头看你原来写的代码,有意义的部分我想使不太多的,可是有趣的是,我后来在重写一边,解决问题的方法与思路,或者错误都是相似的。

Unix真是个混蛋!我花了差不多两个小时在debug我的replace小工具,最后才明白了两点:必须用\来表示双引号,比如replace filename \"source_str\" \"target_str_with_quotes\";另一个大问题又是换行符得老问题,我已经在这上面吃过苦头了可是又一次在了跟头!微软好像是\n只解决了10,13中的一个,另一个他就不管了?!!我还是不确定,总之,我干脆全都加入条件判断力就是了。晚上,为了在8个server上执行几行代码的小工作,我去专门写了一个replace的小工具,并且在写c程序去生成脚本文件去执行,本来一件工作是无聊的15分钟我把它变成了痛苦与困惑的3个小时,这就是tool-maker的标准工作方式。

恩格斯说过:制造工具与使用工具是把人和类人猿区分开了的一个最重要的标志。从这个意义上说,只用别人写好的开发工具作应用程序岂不是猴子的工作,难怪mcgill的那个老教授在他的数据结构的课堂上老是强调有些工作他可以训练猴子来做。我一定不能做猴子啊。


七月十日 昨晚的天空是淡淡的水墨画,今天是灰蒙蒙的一片,午后的小雨依然郁闷

心情也如天气。早晨,从google找到了15puzzle的算法,不可思议的简单,有效,虽然我也曾差不多想到了,但是,作者的话却让人有些灰心,他说这基本上没有AI的成分。这个结论才是真正让人苦恼的,究竟什么才叫AI,在什么程度上算是AI,AI 应该是不会在一夜之间实现,AI也不会有一个明确的界限,那么基于这些假设,前方的路似乎太遥远,模糊了。也许如歌词里说的:If the way ahead is not so clear, I need a guiding star...(这是我杜撰的,我搜索了一下,原来的歌词不是这样的。anyway, it doesn't matter。)我跑了三千米睡了一觉,睡梦中以为有了一些线索,我就开了一个头,这是一个类似贪吃蛇似的串,可以长大,可以游动,吃完午饭,等我在回过头来看,其实都没有意义。因为,这条蛇虽然可以写得很通用,但是操作起来远比单个节点复杂得多,对这个特定的问题来说没有什么实际意义,不如原来作者的简单实用。这样一个经典的搜索问题,我耗费整整三天,还不算以前的尝试,真是让人沮丧,打个不恰当的比喻,好比号称精锐的德国装甲师被苏联红军的一辆KV-1坦克阻挡了整整两天的无奈。不小心把整锅的排骨烧焦了;想打个电话又把pin number全刮掉了,又是白白损失4个dollar;想出门,雨又下个不停;想睡觉,对面IGA门口的法国人有欢天喜地地唱个不停,真想冲过去把他那些免费品尝的啤酒喝光,省得他唠叨个不停。郁闷的星期六!


七月十一日 阳光还算灿烂

我怎么也不能相信这个15puzzle到现在还没有被攻克!我已经连续奋战了一天一夜,牺牲了四百万的脑细胞,一包方便面,半小瓶红葡萄酒,半袋子虾皮,三块面包,一个橙子,一杯牛奶,4到5个失败的版本和不成熟的尝试,结果却是我迷失了方向,我一会儿尝试一种智能的寻路方式,一会儿试图一种简单有效的算法。最后,我自己则淹没在越来越模糊的code里。

经过几十个小时的折磨,我的头脑已经麻木,饿得受不了就去对面“龙之家”要了一盘炒河分,终于我承认失败了,因为,这个算法并不那么简单,我不是很理解它是怎样调整顺序的,我的方块会卡死。失败使我的头脑变得冷静,我这时才意识到昨天已开始我想用“贪吃蛇”来做的想法并非没有道理,再重新捡起“串”做法之前保存又一个失败的版本


七月十四日 阳光灿烂

虽然c++不让你创建纯虚函数的实例,但是,你却可以创建对象数组并初始化。


七月十六日 好像是不错的天气

尝试code contest对我来说只是一种令人沮丧的活动,我甚至不能在规定时间完成一个简单的题目,当然,我也看到不少参加者和我一样得到鸭蛋。这是一个非常简单的水资源分配的小问题,我却在数据初始化的时候反复遗漏。

面向对象的设计:这些结构的合理性我无权评价,但是,面向对象的思想是模仿生物进化的一些模式,比如,地球上曾经出现过长着长长牙齿的老虎,那种如大象一般的装饰性的所谓武器不是最后被证实没有什么效率了吗?面向对象从来没有真正定义过什么规则就是因为它更主要是一种思想,而不是什么protocal。应用的玄妙有时候存乎一心,很难用对措来形容。


七月十八日 天气很好

昨天打了一下午的网球,当然,主要在捡球了。晚上去看中国队的焰火表演,我觉得还可以,也许因为今年是第一次刊的关系没有参照物,对朱春明同学的所谓中国队的火力不如德国队的说法不以为然,虽然,我被同志们认定是铁杆汉奸与洋奴,但是,最起码还是很客观的。回来后又开始对血型的分布开始争辩,网上有一个所谓统计资料,说O型血的比例最高,这个非常出乎我的意料,因为从中学生物课之后我头脑中就有不可动摇的意识是O型血的遗传机会最小,我决定写一个小程序来验证。结果也还是有些出人意料,我的意思是O型血的遗传机会有这么小吗?我想如果有谁是这方面的权威可以告诉我。

I found out a small displaying mistake which is quite stupid and the result is all opposite. I mean I exchanged the result of O type and AB type. In order to save face and save space, I decide to modify it without creating a new version.

我用最笨的办法来计算概率,确定无疑地说:Double E专业的直觉往往不如computer science.


七月十九日 晴朗

有时候,我自己也会觉得我要么愚不可及,要么脑子进水,为什么要去花时间去证明一个不可能有结果的问题呢?我们中间没有这方面的专家权威,这个问题向某些人说得没有现实意义,我记不懂生物也不懂遗传,对生物进化的全部知识就是15岁以前学过的,对于一个智者来说不会把宝贵的时间浪费在没有结果的问题上,经济学家会说资源浪费,普通人会说无聊。我也同意。因为,我并非什么智者,I am a common man with a common wish to try to make myself look like uncommon. Is this not common?

不过,无聊的定义是因人而异的。每个人有自己的定义,One man's meat is another man's poison。对于福尔莫斯来说无聊就是没有任何犯罪案件的下午的一针吗啡,对于很多“正常人”来说就是体内某些不知名的化学成分太少。对于我来说,就是脑子空空如也。在蒙特利尔美丽的夏天我有权利消遣我的时间,今天的人类比十九世纪伊丽莎白时代已经大大的堕落了,那时候,最美好的莫过于在朝阳的洒满阳光的书房里,昏昏欲睡地读完<Alice in wonderland>的一两个章节。血型的分布简单地分析也是一个非常复杂的递推公式

And I am not in slightest mood to add any more sentence to my simple dialog between HAL9000 and Dave.

第二个实验是把血型因子纳入考虑,并假设AB型是一个衍生的血型组合。即人类的始祖是纯粹的A,B,O型,结果和第一个实验有重大的不同,A,B市增长最快的,AB其次,O最少。这和现在的统计情况差别更大。但是不管怎么说,那种认为血型因子的总体数量比例维持不变,血型分布比例也不便的天真幼稚的说法是完全错误的


七月二十一日 天气不错,心情不好

我想模仿printf()那样有不定数量的参数,可是,模板就有问题,我想也许模板类参数的传递和别的函数不一样吧?还是虚函数的?还是c++类成员函数?或者。。。


七月二十三日 天阴沉沉的,好像有什么心事

签证还是拿不到,中国护照除了回国几乎没有任何用途。我想了好几天才想明白一个最最基本的问题,在迷宫里如果你没有很好的记忆力,单单靠方向感,应该是没有任何保险的算法能够走到目的地的,除非你记住你走过的路,即坐标。想明白了这么一个基本的幼稚的问题,所有问题都迎刃而解,因为,我一直以为人类比计算机聪明,现在发现人也不过是因为对已经走过的路由印象,才能保证走出迷宫,从这个意义上看,计算机不比人笨,是我比计算机笨,那么我就放心了。所以,基于这一点,一个简单的深度搜索就可以了,我不再为内存大小而担心了,反正都要记住坐标,索性就把走过的坐标都记下来,这是一个必须要做的工作,不可能有更好的办法。我以前一直迷信靠墙贴边走的方法,对于中心空旷的迷宫或者由柱子的迷宫都不适用。既然走过的路要记住,与其记录路径,不如记录坐标。


七月二十五日 天晴多云

我再次尝试我的小蛇,它能够游动,长大,可是,问题是在狭窄的空间里经常无法腾挪,最重要的是对于15puzzle来说,它并不是一个什么好的算法。当蛇的长度比边长来的长的话我无法找到一个好的算法来让他游动长大,经常卡死,而且即使我能找到的话,当边长缩短到2的时候,蛇的概念变得毫无意义。我又一次从一个充满信心的起点走到了一个无底的深渊,到达了一个我没有预料的终点,当然,我所钟爱的小蛇也许可以作为类似贪吃蛇的小游戏的素材。

这两天一直在看老电影,一部1957年的美国歌舞剧《silk stocking》很是好看。其中的唱词风趣,幽默,充满韵律,舞蹈欢快多变,糅合了芭蕾,现代舞,有时候还能看到俄罗斯民间舞蹈的影子,爵士乐是其中的主调。美国人真是有创造性,那种认为美国没有历史,文化的很多国人的想法是肤浅可笑的,短暂的瞬间有时能迸发出更灿烂的辉煌。可惜今年的娱乐开支已经大大超过预算了,否则我很想从Amazon去买一张DVD来仔细欣赏。


七月二十六日 晴天

有朋自远方来,不亦乐乎?找到一个同好,非常高兴

It is my greatest honour to receive such encouragement from respectable professor Mr. Cliff Shaffer!


七月二十七日 阴天

我又用模板写一个集合类,这已经是我的执著了。不过,我还是很满意这种重复劳动的,我把一大堆的操作符作了重载,有两点很有意思,一个是建立全集,与空集,另一个是用类作模板参数来传入方法指针,这个也是旧话重提,不过都是我的爱好。我用一个static的计数器来控制constructor,与destructor不然,会陷入死循环。但是,这些都还是可以解决的问题,编译器似乎不能解决的问题是power set的问题,即一个集合的所有子集的集合,这时候,模板类型参数本身就是当前的模板类本身,这似乎不符合模板类型参数仅仅是placeholder的思想,我也像不清楚模板在什么时候instantiate,这样的问题要让人发疯的


七月二十九日 现在还是临辰

想破了头才想出了去除比较函数的方法,这是一个很巧妙的办法。因为,我的集合类函数都有重载==函数。只要最底层的成员数据有正确的"=="作比较符,那么就不用再专门输入新的“==”寒暑。不过对于成员数据像“char*”之类,“==”不是正确的比较符,那么你就要去specialize集合类。这里你要知道,char* 必须先用typedef来定义!我累死了!

compiler-talk.

想起昨天与春明踢球时候对中国的儒家哲学又作了第n次的批判,中国人在这样的思想窒酷下怎么可能产生现代的科学技术呢?

下午观看《长征》学习伟大领袖的坚忍不拔的精神,听到主席念咏《娄山关》的诗篇,不禁热血为之沸腾。


八月七日 天有小雨

又是一个浑浑噩噩的星期过去了,什么也没有做成!我忽而想完成我的编译器,忽而想继续完善我的自动证明,计划完成一个类似模板的可以做迪归的东西,计划学习MFC,计划尝试操作符相对优先级的表达式parser,计划预习网络和AI的课程,计划。。。结果什么也没有做,唯一的成果是练习打网球把胳膊练酸了,帮同学搬了几次家,发现了我的所谓的replace工具根本就没有用!我要么用临时文件存储,要么直接用win32API,当然后一种方法是无法在UNIX上用的了。


八月八日 你知道蒙特利尔的雨有多大吗?

这个日子我今天才知道居然是Fayer的生日。中午去爬皇家山,浇成了一个彻头彻尾的落汤鸡,整个衬衣脱下来可以不停地拧出水来,在大雨中光膀子和王林森比赛爬山实在是过瘾。其实我没什么可骄傲的,皇家山上到处都可以看到七八十岁的老头老太太在雨中攀登,相比之下我总觉得中华民族是一个彻头彻尾的孱弱的民族。并且这个习惯于在异族奴役下苟且偷生的民族又一次不小心忘记了几十年前这个日子里曾经应该值得纪念的用血与肉换来的胜利。

我觉得我的每个暑假都有相同的问题:生于忧患,死于安乐。(I only live in danger and difficulty and I always die in safety and slackness.)
孤单只会让我更加充满斗志,和凡人接触太多让我沉沦。看过《西游记》吗?孙猴子出生的时候目运金光,气冲斗牛,惊动上苍,后来食了人间烟火,便失去了灵性变得和普通猴子没有什么差别了。


八月九日 风轻云快

一点体会。


八月十日 又下雨了

我一直想写一下Huffman code。因为这是一个基本的算法,考虑到这么一个基本简单的东西,我一直没有触及,有一点不可忍受。事实上,我想很久以前我就想尝试,当时应该觉得有些困难吧?学过了数据结构之后,他的神秘少了许多,但是,压缩文件还是比较麻烦,我就放弃了,因为,bit的操作很麻烦,文件看来只能写byte,那么我要把Huffman code以bit的形式来写实不可能的,align成一个一个byte比较繁琐,我懒得动了。


八月十五日 天晴了,我的衣服终于经受住了风吹雨打的考验可以收了

我一直想找一种探测ambiguous grammar 的算法,学了编译原理我想用SLR(1)来尝试,当然我自己都不相信这是一种可靠或者可行的办法。


八月十六日 晴间多云

有一个小小的game供你自娱自乐。当然,我相信很多人根本体会不到其中的乐趣,也许还看不懂问题吧?

有多少人会犯我这样的低级错误?我有时候觉得我读到英文字和我的想法总是格格不入,因为,我总是以一种先入为主的想法对待客观世界,如果,他们不符合我的预想,我常常忽略他们; 如果,他们符合我的预想,我还要看书干什么?所以,我基本上不读书。


八月二十二日 阴天很冷

关于磁盘寻址的latency时间的问题,几乎每一个学过计算机结构的人都知道是平均1/3。问题是我不知道怎么算出来的,我用一个小程序去模拟的时候,才意识到应该有一个前提,就是平均等待时间的定义问题,这个和操作系统中进程的等待时间有一定的相似的地方,就是排队理论中要求队伍的长度相对固定,否则系统的平均等待时间是无意义的。比如,一个队伍不断在增长,你可以想象其平均等待时间也是在不断增长的。因此,这里的latency是在一个理想状态下,任务sparse and few,应该是一个简单的微积分或概率问题,只是我不知道要怎样解决。一个简单的问题居然号称写了两个版本,有时候,我觉得我自己写程序好像是找老板要工钱一样的巧立名目。实际上,我真正挣钱的时候,写的程序却很少,我指的是evolver脚本,我没有权力贴出来,因为大部分不是我写的,也很乱七八糟,不过,我只是想安慰自己一下,我这些天没有无所事事,天天忙着伺候那八个服务器上的东西,原来分配给我100M空间的时候我心里还在嘀咕,现在才知道根本不够,空间只够同时运行4-5个server。

其实磁头寻址这样一个问题是一个很简单的微积分的问题,不过因为我在大学里面不学无术,微积分和没有学过一样,现在开始补课了。


八月二十五日 阳光灿烂

花了一块钱看了一场电影《kill bill2》,比国内还便宜。不过2比1差很多,看来导演的灵感是枯竭了,从《four rooms》的毫无创意就可以看出这个喜欢标新立异的新导演由江郎才尽的味道了。

看《Battle of Wits》里面IBM的早期的排序机器被美国特工用来破译日本的密码,想到了这是一个radix sort的绝妙的应用。不过写完以后,向炫耀式的考问朱春明,没想到它很快地用95%以上的程序员都会用的普通方法来解决这个简单的问题:怎样在一个长长的字串中寻找一定长度的重复字串?c/c++程序员一定会用两个指针从头搜索到尾,这是一个O(n^2)的算法,虽然比radix sort德O(nlogn)要慢,但是,他简单的多,并且,radix sort德O(nlogn)是一个系数很大的nlogn,因为要拷贝很多次。我真是糊涂。


八月二十六日 灿烂阳光

整个暑假我都在看各种各样的电影,大多数是电影频道的老片子,很多非常的好,比如《red sun》,一部西部牛仔与日本武士结合的西部片,非常的精彩,日本武士好像是高仓健,我不确认,但是牛仔第二号人物却是阿兰德龙,是真正的剽悍的西部片。《taxi driver》则是一类我们很难理解的片子,但是也同样是一部经典。《I married a monster from outspace》实在是一部真正反映美国人冷战思维的经典:外星人寄居人形好像KGB的间谍,秘密占领整个小镇,掌握了警察通信交通,渗透到社会的各个角落。同时具有星际旅行这样先进的文明生物,却在精神生活中极度贫乏,需要美国这样一个地球人的领袖族类来教导外星人怎样去爱或者体验所谓的感情,这样先进的外星文明貌似强大,但是,却无法抵御人类的宠物--猎犬的进攻,所以,美国人是人类的保护者,美国文明是地球文明的代表,以至于整个星系的领袖,美国的生活方式是人类的模板。我不知道哪一个更幼稚:是相信全世界三分之二的人处于水深火热中需要解放,还是相信美国人的文化科技是整个银河系中领先的。


八月二十九日 下午突然下起了大雨,电闪雷鸣非常好看

为了尝试写一个简单的graphic demo,我决定先把我的简单得不能再简单的运动轨迹小程序先备份一下,对VSS我还是抱持一种不信任的态度。下午,又尝试dll的调用,又第n次的犯了calling convention的错误:我几乎没有在一个work space里面做两个以上的project,因为,delphi编译目录的噩梦总让我避免这样做,(实际上很安全的,现在想不起来为什么Delphi要那样弱智的要设定一个default的obj文件目录,像VC++这样傻瓜的解决方法不是很好吗?)几乎和我想象的一样,VC6.0可以让你trace进dll的code里面,尽管你是用loadlibrary来调用你得dll,我无法想象这给程序员造成的错觉有多大,至少我是坚信dll的代码可以trace并不代表你可以真正看到运行的数据,毕竟dll生活在另一个我们无法接近的程序空间---操作系统动态分配的地址编译器怎么能够追踪得到?事实正是我的想法那样,VC6只不过运行了一下你的dll,并且非常乖巧地同步了你的tracing。我想在这里提醒自己的是:不要再犯同样愚蠢的错误了!如果你再dll里面声明为extern "C",你就已经明确地声明了你的调用约定(calling convention)为__cdecl,那么相应的,在声明函数指针以便调用dll里面的函数的时候,这个函数指针就要用__cdecl的调用约定,同时非常handy的做法是用typedef把你的函数类型声明成一个新的类型,以便在GetProcAddress()的时候强制转换类型的时候少写几个字。同时,我发现我非常难以接受VC6得很多wizard,因为,我不会用,是用wizard几乎和接受别人的思维习惯是同义词,碰巧我在这方面狠迟钝,除非我明白了为什么。

早上又费了不少时间明白了一个简单的道理:如果你因为你要写的函数太简单而感到内疚以至于要把他写成带参数的macro的话,请记住其中的参数不能使表达式,因为,macro是由preprocessor直接替换的,那时候parser还没有开始工作呢,自然对于operator的precedence无法正确地解释,因而这种替换是危险和不可预测的,比如#define ABS(x) (x>=0?x:-x),如果你这样做ABS(--x)十有八九会有问题,--x>=0究竟是true还是false呢?我不知道,也不想知道。如果,你觉得macro太危险,函数太奢侈,那么不妨试一下inline的函数。

我想说我喜欢vc++的一个原因就是tracing的强大功能,相比之下,那些用YACC,Bison等等compiler-compiler编出的一些所谓脚本语言实在是一种垃圾,因为,那些parser经常连语法错误都无法爆出,至少在我适用的范围内,perl是这样的弱智。


八月三十日 又下了(降水超过5毫米?中雨:小雨)

今天开始学习LISP,我的感觉好像和Haskell差不多,但愿这一次能够好好学一学。朱春明说他们的考题有:在函数内部定义的namespace中的identifier是global还是local?我觉得教授出这样的考题真的是有些纯粹为了考倒学生了,这个如同很久以前我听到的问题:再vc里面类型如何自动转换,或者说那些是兼容的能够自动转换的类型。这如同考问一个以英语为第二语言的人是否能够辨别出德克萨斯口音与美国中西部口音的区别的一类问题了,这是面向对象语言的本质问题还是vc6.0的tips?把五月的日记移走吧。


八月三十一日 天还是黑的

有大虾寄来的小puzzle,其中第二题和原来的第20题是一样的。


九月二日 晴冷

要记住:scheme里面的( let ((source  target))  (here you can write your expression)),这里,中间的()是必需的,否则,解释器不认为你的定义结束了,scheme的语法真是无理性。还有,let地执行顺序好像是从内到外,并且,最外面的let影响最里面的,好像和我们c语言里面的scope正好相反,不知道怎么实现的?要注意:define才是我所认可的macro: (define (fun par) expression),let到像是declaration,但是算是global还是local?

夏天最后的余晖我眼中的余晖我心里的余晖


九月三日 阳光这么灿烂

AI注册不上怎么办?真是人算不如天算,世事总是在你最意想不到的地方抓住你,为了这门课,我书都买了还专门调整了一门课程到冬天去,结果不知道怎么搞得误操作了一次,弄到现在选不上了。

我就是驴子我怕谁?


九月八日 早上起来精神饱满,阳光也灿烂

我记得data-structure的tutor写过这样的简单的demo,我当时还和她说过离散数学书本上的算法和这个不一样。其实这么简单的迪归算法,我却折腾了半个晚上,当然,这种绞尽脑汁的磨洋工是有好处的,我明白了一个道理:算法有时候是可以“设计”的,或者至少可以“猜”出来。

昨天是开学第一天有些混乱,我犯下了一个致命的stupid mistake,也许我在毕业以前都无法修习AI了,这简直是一个大笑话,因为这也许解释的人性的可笑的本质,你所谓最care的东西是你所得不到的东西。或者,“汝果欲学诗,则功夫在诗外”,因为,我已经逐渐认识到AI是一个最综合的大筐子,什么都可以包括,反而没有什么东西了,不如我先去学习些实用的工具再回头?不过。。。


九月十四日 今天是什么天气呢?好像是阳光灿烂

Angel从国内回来帮我买了一个MP3Player,现在国内的电子产品实在是发展太快了,我早已落伍的不知道多少了。今天,调试网络文件传输的程序实在是有一点辛苦,一会儿是server运行,跟踪client,一会儿又要反过来,总算是完成了一个界面及其丑陋的小程序,我最主要的工作是想要重现delphi对于socket的封装的样子,不过是重新把代码组织了一下。贴出来供大家参考,但是,希望不要照抄,不然大家都惨了。


九月十五日 天晴

scheme里面可用(load "filename")输入文件,同时,(define fun_name (lambda (param) (fun new_param)))来定义递归。我对于向量的一些基本操作总是记不住,就写了一个超级简单的小小程序来帮助记忆,其中唯一值得一提的是“。。。”这样的参数,哈哈,我不知道在座的是否知道这样的不定数量的参数。


九月十八日 天晴有云

早上和王林森去皇家山跑步,经测算花了45分钟跑到山顶,(包括绕道“十字架”在跑回Charlet)。争取以后能更快一些,因为现在我们还赶不上训练有素的洋妞呢。

下午,接着学习数学分析,总算明白了1+1=\=0的道理,不过,假如我们假定0的唯一性,不知道是否能够用9个基本定律来证明1+1=\=0。大多数的所谓证明大都是书本上的,我只不过在简单的推到一遍,实在是简单得可笑,你能相信我证明的问题都是我从来没有任何疑问的小学时候学过的,比如,任何数字乘以零还是零,任何不为零的数的倒数的倒数是它本身等等,很简单吧?

想了想还是把我的程序贴出来吧。


九月二十一日 天阴

Sometimes, I just wish I have the chance to study more about mathematics.

I am hesitating on if I should post my ultimate version.


九月二十二日 天晴了,该收衣服了

这三天的过程象极了数学归纳法。

我无意中听到了黑客的脚步声


九月二十三日 天晴,我把衣服收了

昨天晚上的课堂上那个伶牙俐齿的法国小妞当众对着我讲了一大堆的merge-sort的第二阶段sublist的数目不能过少,否则i/o就会太多,我听得一头雾水,早上看书才明白了内存大小确实的有一定的限制,因为,disk的最小存取单位是block,而第一阶段内存大小与i/o次数是无关的,但是,merge的阶段,我们是把所有的sublist一起merge,因此,内存大小要足够容纳所有的sublist,也就是内存的block数目的平方要大于整个文件的block数目。

一个扩展命题。


九月二十四日 晴天,该洗被套了,不然冬天到了就没地方晒衣服了,

I proved a trivial lemma...

I began to suspect my theory.


九月二十七日 天晴,被套要记得收啊。

早上看了两部关于“梵高”的电影,都是片断,心里不禁有些感动,梵高的作品生前无人问津,死后却被所谓的收藏家推上了拍卖行的巅峰,实在是一种莫大的讽刺。我个人对其作品几乎一无所知,也并不相欣赏,因为画家作画本是传达一种激情,和传教士传递信仰,并无本质上的区别,都是一种信者恒信,不信者恒不信的类型,不象数学家传播逻辑,科学家交流思想那样完全可以,也非常有必要进行验证的类型。“艺术品并无验证的方法”,不过,作为创作者的人格却是完全可以加以分析与检验。“梵高”是一个典型的艺术家,充满激情,不断发掘周围的美,并想方设法要表达自己内心地感受,在这一点上和普通人并无两样,我完全可以体验他画金灿灿的麦浪时候的喜悦和我在100层深度搜索的快乐十项类似的。这样的情感不一定可以,也不一定必要能让芸芸众生来体验,子非鱼,焉知鱼之乐?

昨天吃饱了撑得了


九月三十日 天晴,可是谁收了我的被套?

人生就是一个过程,每个人都知道自己的结果,因为不管你是怎样的该市英雄,最终都不过是一抔黄土。如果不是人生过程的靓丽,我很难想象一个人还有什么必要活着。
成功固然诱人,可是失败何尝不是一种人生的体验。你并非生来成功,你也不必在死后为失败而发愁。所以,成功与失败又有什么看不开的?

我忙死了,我想把数据库中用到的一些算法和结构写成小程序来练习,我想尝试进一步丰富向量空间,我还想尝试追踪网络中神秘的噪音。可是,作业太多了,单单算法语言这一门课就让我手足无措了。结果,和去年秋天一样,充满了遗憾与穷于应付。


十月三日 昨天下了大雨,今天天晴了

昨天,花了一块钱看了两部大片《King Arthur》, 《I, robot》。其中的代价是去电影的路上被淋成了落汤鸡,只好坐在电影院里晾衣服了。“亚瑟王”的故事在西方家喻户晓的程度不亚于三国演义在中国的地位,国人对这些历史的无知,正如西方人对中国历史的无知,又何必要强求外国人对中国诸葛亮的了解。其中的战争场面还是非常值得一看的,罗马帝国重骑兵的铠甲,英国的长弓,投石车等等,如果你玩过“帝国时代”会有更深的体会。“I,robot”特技还可以,情节稍微的老套一些,总的来说,也还可以,至少比“minority report”要好很多吧?

据说winzip用的就是Lempel-Ziv的压缩算法,昨天看电影前匆匆写了一个压缩的算法,解压缩的算法稍稍的复杂一点,留在下一个版本。


十月五日 天阴,很冷,我只穿了衬衣去上学好像特别的醒目

上线性代数课,老师问有没有计算机系的,好像就我一个人举手,当时很惊讶也很惭愧,好像觉得计算机系的人数学都是学得不错的可以免掉这门课。我不知道为什么我却觉得有太多的东西等着我“发现”。也许是我现在变得越来越笨了,开始认识别人早已习以为常司空见惯的问题,也许我现在有时间去重新看待我以前想当然的问题

这其间的差别岂止十几公里?


十月九日 晴,头发长了,见识短了,我把头剃了

晚上看CBC转播的美国总统电视辩论,很受触动,且不说美国的所谓民主制度等等,我只想提一点,两位总头候选人唇枪舌战,口才便利,思路敏捷,不是地列举大量数字,我只想说我的年龄也许就只有他们的一半多一点,可是我的记忆里好像已经不如他们了。郭亮在我们国家的最高行政机构里面工作过,说过我们的前总理朱镕基仅仅会在每个月要各个部长汇报工作的时候列举数字,那些部长们就已经绘几天睡不好觉,我可以感受到中国永远赶不上美国不是因为别的原因,只是因为领导体制的不同,美国的总统实在是不好当,相反,在中国我向往着做人民公仆的工作,而且,这个公仆的职责越重大,我想我会越轻松。


十月十二日 天晴了

昨天花了一天时间再写我的UDP程序,还不算前天,我原本根本没有预料要花这么多时间,不知道是什么原因要这么久,想想可能是因为我对要做的stop-and-wait的protocol还没有十分得清楚,而且这种通过模拟router实时传送无法跟踪,因为,而我原本没打算怎么debug的。真是累啊,为了一个stupid的手误,花了好几个小时,最后在最不可能的地方找到一个不等号写成了=!我简直气晕了。另一个头疼的问题还是原自于bit的操作,char居然也是有sign的,最高一位不能用,如果#define  Some_Char  0xF0这样居然会被编译器认为是int,真是麻烦,这种细节问题着实的多。还有一个小问题,我以前有错误的认识,extern的变量写在头文件,实际上是声明在其他的include他的cpp文件里面,这和声明成static还是有本质区别的,我不知道我以前怎么就不明白,到底我是越来越不笨了还是相反?最后一个重大问题是确认的问题,我觉得无解,老张也说这是有定论的:在网络连接无保障的情况下,发送方要接受方确认收到文件结尾,接受方要确保回复,那么这个循环是无止境的。所以,只能是接受方直接受到就断开,发送方看运气了,错误次数超过限度报错就是了。我为这个也花了不少功夫。还有,到底文件传送前是否应该同步一次,这一点我原本没有意识到,最后才发现,不管是server,client方,发送方负责同步还是比较合理的,当然我本来用接受方来负责同步是等效的,可是,问题是别人看起来别扭甚至是误解了。相反,用client,server来划分同步的责任,反而使更复杂吧?(我想不清楚了)再有就是错误处理机制,搞得不好就是一团乱麻,我现在才比较清楚一点,就是错误处理和exception-handle是不同的意义,我当初这样写确实是有一点by intuition,但是还是不错的,只是抛出了exception再把错误号码传递到另一方,再导致另一方的exception被抛出,就千万不要再把错误传回来了,不然又是一个无线循环。还有就是,select并不代表已经recv了,你还是要recv把data从buffer里面读出来,这是一个基本常识,我也犯了错。还有什么错误?啊,ReadFile返回至并不是false代表文件结尾,只有当返回至为非零,而读到的字节为零的时候才使文件结尾。


十月十五日 小雨

看线性代数看到一大堆问题。我总觉得这门课很深奥,可是几乎所有的人都不以为然,真让人苦恼。

昨天听了sliding-window德protocol后,我觉得我后来的想法是对的。为了能够确保eof的信息传递给receiver,我们可以多加一个end of transmission的包,当这个包确认的时候,也就保障了之前的eof的包的确认,从这一刻起,即便有什么传输的错误,都不再会影响到之前的eof,也就是说,文件传输是彻底完成了,传输双方不论有无丢包都可以退出了。


十月十七日 小雨

算法的题目真是头疼,寻找maximum matching的题目还算有头绪,我懒得数数,就写一个最最简单的DFS来找结果。但是,distinct representative的问题我单单去理解问题,就花了半个下午,还不知道要干些什么,后来只好用google搜索才大概明白一些相关的东西,其中的一个“结婚定理”,相信大多数的女孩子会很有兴趣的:对于n个男孩,假如任意k个男孩子中所认识的女孩数目至少是k,那么一定可以让每个男孩子和一个他认识的女孩子结婚。证明可不是我等所能够理解的,而且作业业和这个不是太相关,因为也是matching的问题。昨天我也花了大半天时间痴心妄想试图找出另一个Strassen's algorithms的改进法,真是自不量力,让矩阵相乘减少一个乘法的算法是很高深莫测的,怎可能轻易想出来?我只是似乎看到这是一种线性变换的思想就想去尝试,实在是不明智,唯一有可能的是搜索16个小矩阵乘法的线性组合,然后,尝试从8维的向量空间变换到小于7维的向量空间。(我也不知道这种说法对不对。)

晚上看线性代数真是头疼,其中的证明题很是费脑筋。我的这位老师是号称Erdos number=2教授,这等人物可能在中国是很难碰到的吧?没有学过离散数学的大概很少听说过Erdos吧?那么我也就不解释了。


十月十八日 阴天

Guess what I look like...

学了线性变换才明白了这么个简单的道理。

Are we proving they are linearly independent or not?

Yes, I am wrong.


十月十九日 晴天

我不明白三个字串的相同子串为什么会不一样?


十月二十日 晴天

累死了,晚上的database的实验课真累啊,下午睡过头了没吃饭就去上课,结果课程取消了,真是气人!结果实验课给oracle设定cluster, 和各种各样的index,折腾了一晚上,这还是挺有意思的,因为,以前从来不知道怎样fine tune database,学了数据库设计才知道一次查询有多么的昂贵,才知道可以自己重新组织数据的存储。不过早上的作业的疑问还是没有被解答:My puzzle in assignment...


十一月二日 雨天

时间就是这样的度过,在你不知不觉中你又度过了你生命中了无痕迹的两个星期,当你回头看看你这一小段生命的意义时候,你是否觉得懊悔。至少我有一点是:数据库我考得一塌糊涂,我曾经试图写一些程序,但是每一个idea都是开了个头就无疾而终了,B-tree,dynamic-hash,external-sorting,scanning-port-by-socket,min-cut-max-flow,topological-sort-for-connected-component。。。我好像无法集中精力做完一件事,当然我也承认很多的algorithm实现起来麻烦,而且其中的细节我想不清楚,很多的东西单单建立起那个环境就很麻烦。不过,这些理由也许并不是真正的理由吧?既然我现在没有mood去做,就让我记住我有什么没有做吧,就像夏天的从来没有开始过的compiler project,但愿我有一天能够完成这些计划。(像那个揪心的“斑马问题”困扰了我一年,对于DFS我竟然需要将近一年时间去体会)

那位erdos number等于2的教授确实让人耳目一新,当我从教室里面走出来的时候,我看到的加拿大蔚蓝的天空变得更加得蓝了,一些久久困扰的问题有了一些线索,但是最大的收获实际上是一种心灵的安慰,我至少知道了我并非庸人自扰,我所有的concern都有人考虑过,而且应该都是由答案的。number system和vector system不管是否是两个独立的系统,他们回答了为什么我们小学中学甚至大学的时候take for granted的东西:线性变换和提取公因式似的因式分解似的numb-minded mechanical operation有着深邃的联系,vector space仿佛是一个线索,把我所有的学过的数学知识全部的串联起来了,这也许是中文对于数学上ring的解释吧?

我很喜欢networking教科书上的一些引言:

Data is not information; Information is not knowledge; Knowledge is not understanding; Understanding is not wisdom;

也许我可以这么理解人的一生,在幼儿园时候,我们的所见所闻都是无意义的原始数据,我们懵懵懂懂:数据从来不会自动转化为信息;在小学时候,老师在启蒙我们的时候,我们馄饨初开,对这个世界开始有了认识,但是认识从来不是真正的知识;到了中学的时候,我们开始变得主动学习思考,但是知其然并不一定就知道所以然,知识并不代表理解,我记得那个时候所谓的“知识竞赛”很热门流行,但是就好象今天我们在比较两个数据库能够存储的数据总量一样,有时候查询速度比总存储量来得更重要;到了大学时候,开始理解一些道理,但是只见树木却不见森林,有时候知其然,也知其所以然,却不一定知道怎样才能正确地探索并得出正确的所以然。好比学了数据结构知道了很多算法,却不一定知道怎样才能设计并找出正确的算法,就比如知道了所有的排序算法都不可能超过nlgn,那么是否可以从这个lgn猜测出来几乎所有的算法都使用divide-conquer去把list分成若干个小的list?因为,这种binary式的划分需要的次数都是lgn,可是为什么我们不能划分为两个以上的list呢?也许是因为sequence本身就是一个二维的向量空间,其中的元素间只有两两间关系(relation)我们没有必要划分更多,也不可能划分更多。但是strasseng的矩阵快速乘法的给人耳目一新的震撼难道不能在这里重现吗?除非我们能有一些特殊的排序要求,以至于一个sequence里面有多个排序的标志量,或者这个sequence是有多于2的维数?所以,也许我们可以说理解从来不会自然的生出智慧。圣贤之书就算读了千百遍如果没有思考实践,也许还是原封不动别人的思想。如果不嫌弃我狗尾续貂的话,我想再加上一句我自己的理解:wisdom is not originality;

今天学到了两个简单的know-how,当你需要链接某一个lib文件时候,通常是让程序员在vc6++的project/settings/link里面自己加入.lib文件,与之相当的办法是写一个编译器指示字:

# pragma comment (lib, "libfileName.lib")

另一个非常simple的问题是我以前一直没有找到调试运行时候怎样加上命令行参数,这个问题是够愚蠢的,我不知道我为什么以前一直没有找到,project/settings/debug的program argument。

我还是搞错了,dll是不能静态链接的,只有implicit or explicit call,前者就是靠操作系统帮你自动load,后者是要自己用loadLibrary去主动load library。另一个会混淆的地方就是静态库文件和动态库文件的“接口文件”,这是一个非常迷惑人的东西,我被骗了很久!你要implicit链接动态库,你需要link 一个动态库的接口文件---.lib文件。可是如果你要编译一个静态库,他的文件扩展名也是.lib。但是这两个东西完全不是一回事,前者没有代码,仅仅是一个类似于头文件的函数原型,后一个确是一个类似于obj的文件。微软这么做实有原因的,也许linker始终都回去链接这么一个.lib文件来resolve你的程序里面用到的所有函数。记住,静态库你还是要自己把.lib文件加入链接的文件列表中。(见上)


十一月八日 天气不错

早上作了一个小试验,试图找出一些idea来寻找多个strings的LCS。我试验了所有的排列,结果看不出什么,这当然是意料中的事了。我还异想天开试验他们的10进制的数字的关系,还是看不出所以然。


十一月十日 天阴沉沉的

comp465的作业实在是让人绝望,我已经没有信心在努力了。一个算法想了很久,而且这个是被公认为认为最容易的一个,因为,教授出这道题适应他的老朋友的要求,不得已出的玩的,我原来想错了,后来又不敢确定,只好用c++验证。


十一月十一日 天突然下了小雪,不过很快就停了

真是累啊。一道题的证明我就费了5页纸,monotone的算法,我早上想了一上午,结果连上课都忘了,在地铁里才想到可以直接用binary search搜索对角线,寻找第一个菲负的entry,然后分割矩阵为四个小矩阵,递归搜索左下角,右上角的两个,我用master theorem证明是O(n),比我想象的还要好。等上课回来,再改吧?我累死了,晚上还有一节课呢。


十一月十二日 天突然晴了,又出太阳了

费了一晚上才把一个简单的binary search加了进去,真是让人笑掉大牙,我本来以为我可以边看电影便把一个binarysearch加进去,谁知道竟然让我调试了这么久:一开始从正的方向逼近这一点我就没有注意,浪费了很多精神去怀疑边界到底是对不对,后来又发现我要和linearsearch比较,我必须修改一点点越界的情况,边改遍又看了一遍《heat》,这部西方人的侠义片非常的片面,一伙异常凶残的杀人抢劫的惯匪被导演表现的感情丰富,忠于并热爱家庭,对同伙有情有义,对仇人决不放过,聪明才智不亚于警察。不过想想看在抢银行的时候,这帮匪徒用强大火力的自动武器不知道杀了多少个警察,大街上的行人就更不计其数了。这合情理吗?

这个程序是简单,不过用master theorem进行分析还是很有意义,至少我终于有机会发现本以为无用的理论的实际价值。

晚上把gobackN的代码写完了,当然,仅仅是写了一个框架,我原来费了不少心思的一个queue形式的supplier类被无情的抛弃了,因为,窗口本身有很多的要求用queue实现起来很罗索。同时,我还是对于同时能够运行gobackN和stop-and-wait的结构心里没有底,我实在不想把代码写得那么乱七八糟,我这个第三版的作业已经太多垃圾了,当初对于通讯协议一无所知的时候所设想的都没有什么用。而且,作业的要求也改了很多,前后不一致,当然tutor是想降低难度,真让人扫兴。


十一月十四日 晴天?阴天?

花了两天左右的时间才完成了go-back-N的作业,主要的问题是protocal的问题,究竟要有多少timer,是否需要逐个确认,还是逐个否认,怎样能够让go-back-N能够兼容stop-and-wait,也就是说,能否让代码最大限度符合stop-and-wait?这最后一个问题,我到了最后一分钟才明白,当window size=1时候,并且,delay在router程序被禁止的时候才行,缺一不可。我最后还是采用了tutor的一个建议,不用NAK的否认,因为,确认上一个就是了,为什么要去否认当前呢?当sender发过来一组的packet,其中第一个packet乱了次序,你需要一个个的否认吗?如果,你得NAK也被延迟了,当sender好不容易在下一个时间段发过来了正确的,(或者说router忘记捣乱了),又受到了你这个迟来的否认,sender是否会有重复一遍?所以,干脆默不作声,只有当timeout确认上一个就是了。receiver应当每次受到正确的packet都确认,但是这个ACK不一定保证按时收到,所以,sender也并不是每次收到一个ACK就从这里开始重新发,只有当timeout才重发,如果timeout之前收到窗口的最后一个就移动窗口,这样也节省了大量的重发的通讯。最后一个packet最是tricky,我一开始没有想到这个问题,就把eof夹杂在最后一组packets里面一起发送,结果问题一大堆,因为最后的packets个数不一定等于窗口的大小,只能靠eof来识别,可是,假如其中顺序颠倒了怎么办?所以,你一定要等到sender确定全部发完了再来发送单独的一个eof,但是,最后一个packet是没有任何算法来保证解决的。我的想法,应该说是综合了两个tutor的建议,第一,我另外设定了一个end德packet在eof之后,在sender确定receivers受到了eof得前提下,我要让sender继续发送end,假如,receiver受到了end,他简单的回复end就直接退出,因为,这个时候,1。sender知道文件发送成功了,receiver知道sender直到文件发送成功了,即使后面的通讯失败也无妨了。2。sender尝试发送end一定次数,并等待回复一定次数,即便失败了也无妨,因为他知道文件传送成功了。这个时间点是一个安全的退出点,双方都可以在log里面负责任地写道:文件传输成功。Tutor千方百计想把作业简化,他们允许用一个大序列数字来避免modulo,我承认这的确省掉了很多弯弯绕的麻烦,可是文件的大小也受到了限制,packet头也增加了存储数字的浪费。我顽强的抵御这种诱惑,另外,我发现无论是现成的模板的queue还是自己去写的queue都不如最朴素的一个数组,反正queue也是一个circular array,何必浪费?


十一月十五日 晴天

去实验室测试,改了一两个非常subtle的小错误,比如,sender收到receiver的ACK时候,是否应该更新他的current,答案是只有新的sequence才应该更新。另外,receiver记错误是以timeout的次数来计算而不是已收到out of order的packet的个数。。。等等。


十一月十六日 晴天

我对老师的proof不太满意,也许我的理解不很对,虽然结果正确,可是,证明本身还是我的比较convincing。


十一月十七日 阴天?

什么叫真正的dynamic programming?教授对于dynamic programming非常的嗤之以鼻,认为在思想上没有什么深度,的确这是一个很有用但是看起来也很简单的东西。不过,想想看,当你机械地把所有可能的sub-problem全部计算完毕发现其实这个问题根本用不到这么多的,你会不会觉得很傻?你是否想过应该“dynamically programming”而不是“机械地programming”。也许这个会给你一点点启发,的确,思想很简单,窗户纸薄薄的一层,一捅就破了,无非就是在原来迪归方程的基础上加上一个判断,如果,原来这个case计算过了,直接把结果抓过来用就是了不用再迪归调用了。也许这正是dynamic-programming的本意,只是我们理解得不全面吧?

Dynamic Programming is not powerful as you expect. And it is not as less powerful as you underestimated.


十一月二十日 阴天

花了大半天改写go-backN,因为,我选择的modulo太小和windows size太相近,再由delay的网络条件下被delay的packet会mixup。原因和stop-and-wait不能delay一样,其实,stop-and-wait可以看作是go-backN的一个windowsize=1的特例,我当初虽然有些担心,却没有想的很明白,结果在demo的时候才真正发现了modulo sequence让sender, receiver陷入了一个deadlock.我不想用真正的large sequence number,因为这个太baby了。实际的protocol我想应该和我做的一样,是选择一个很大的modulo来让sequence number看上去针对较小的window size来说是一个大的sequence。这样一来传输文件没有大小的上限,二则sequence不会占用太多的空间,在我的例子里,我把一个byte的后面5个bit拿出来做sequence number。结果,这里我因为节省居然翻了一个很傻的错误:我本来想用4个bits,而要modulo=32这怎么可以?真是昏头了。我一直想为这件事写email给几个tutor去complain他们为什么不在requirement里面警告我要选择较大的modulo?因为,从课本里面我照猫画虎地看到modulo和window size大一,我就自然的认为可以了,那是在网络情况为没有delay,只有丢失的情况下。


十一月二十一日 小雨

今年的气候反常好像全球温室效应提前到达了。早上跑步去future shop买了一条内存256M,装上后电脑好像是快了不少。好不容易看了一会儿那本计算机学生的bible,明白了一点关于NPC,NP,P的问题,但是还是很难理解,至少这类问题的证明和自动机的证明一样难。其中说道问题的表达和问题的解决所需要的时间有很大的关系,可是在我看来,几乎是直接的关系,比如从前的那个数字表达的老笑话,财主的儿子上学学写字,第一天学了一个一,就是一画,第二天学了二,就是二画,第三天学了三,结果傻小子就不学了回家了对他老爹说都懂了,老爹一高兴叫他写个请帖让邻村万财主来家庆贺,结果傻小子就画啊画,画不完了。很简单的故事,道理其实不简单,从computer science的角度来看,encoding的不同问题本身的表达就天差地别,如果我们的数字不是十进制二是一进制,那个傻小子无疑是正确的,这样任何的加减乘除等等算术运算要花的时间都是和数字大小成线性关系,然而用二进制表达之后,数字的表达变成了lgn,(我这里暂时不考虑计算本身),假如从另一个角度看十进制,可以看作是一个十维向量空间,有十个独立的向量也就是阿拉伯数字组成了空间的base,所有数字都是这是个基本向量的线性组合,我总在想有没有可能证明数字本身和用“多少”进制表达无关,比如,质数如果是数字的本身特性,它应该和用什么进制无关,也就是说在不同进制转换中保持独立性?


十一月二十二日 小雨?

给我顶住!今天去买了一台打印机,我那台旧的懒得再去买兼容墨盒了。效果就是不错。算法这门课实在是让我头疼欲裂,subset sum化简问题我看了n多遍还是不知所云,一个看似算数的问题却可以用逻辑的3-cnf-sat问题来表示。NPC实在是超过人的想象了。


十一月二十四日 天阴

怎么形容自己做的蠢事,问的愚蠢的问题呢?(8,4)=70这么简单的东西我都会当成排列数!烦闷,郁闷,数学分析的作业也不想做了。看电视看得更是心情不好,突然会从理查德,基尔的一部警匪片想到了上个世纪末的往事,也许可以用另一部电影名字来形容《激动的昭和十年》,中文译作《军阀》。


十一月二十六日 晴天,昨天好像还下了几片雪花

随便练习一下dynamic programming。这是另外一个简单的小问题,pocket ruler。我从数据库这门课学到的一点东西


十一月二十八日 阴天

学习NP-complete记下的一些模糊认识。这个东西非常非常的难。我常常想,也许他们都是算法问题的核心和本质。因为,我好像没有看到对于算法本身定义,大多数naive的定义,就是procedure description的普通代过。我不满意这种说法,正好像古希腊人会相信火和风都是宇宙中的基本元素一样,其实,他们是现象,是物质运动的表象,这么推理算法应该也是一种现象,反映了一些“关系”中最本质的东西,究竟是什么?


十一月二十九日 晴天?

为什么每次我洗衣服的时候天就要下雨?我现在越来越懒得做那种机械重复工作,就写了一个小程序来做networking里面的Bellman-Ford Algorithm。这是一个非常简单得routing algorithm,非常地intuitive。我懒得在写matrix的输入函数,就借用了我以前写得matrix的简化版。


十二月一日 雪

昨天晚上我及时地把衣服收了回来避免了以一个“洗礼”。今天,布什总统访问加拿大,在Halifax发表讲话,我觉得我听了他的演说之后,对他的负面印象要少很多了,这也许就是领袖的人格魅力,有时候,正如我听来的一句话:"Sometimes what is right doesn't work; Sometimes what works isn't right;"就算我对于这个人从理性上看不同意,但是感性上不得不同意他的实际。当然,我们都知道演说稿不大可能是他自己写的,可是,西方领袖演讲时候不可能照本宣科,开场白一般还要一些小幽默活跃气氛,这些对于共产党体制下的领导来说要求就太高了,何况念讲稿还要有起伏顿挫,好像自己写的一样,至少要熟悉好几遍,这样的领导当起来可比咱们的书记在酒桌上拚酒讲荤笑话累得多了。从这一点看,大陆的体制和人治还比西方落后一两个世纪呢。如果,你能读一读布什总统的讲稿,我想你可以体会更多西方人的讲话技巧,远胜于“东方文明”国家中国日本间的“对话”。


十二月二日 雪

我想写一个模拟scheduler的程序,这是数据库中管理transaction的一个东西,我想先实现用timestamp来控制的,如果可能再写locking的,不过好像时间尚不太可能,这学期我有太多的烂尾工程了,一个重要原因是时间不允许,第一,我没有时间,第二,很多东西单单建立一个环境就要花去大量的精力,以至于到后来我队要干什么都模糊了。比如,scheduler里面要管理的是一系列transaction,transaction 里面是一系列task,task针对的是某一个数据库对象element的某一项动作,如read,write。scheduler里面还要有一个task存放的结构,我决定scheduler用最简单的round-robin,因为,主要的目的是模拟timestamp的transaction管理。先写这个开头的小东西吧。太饿了,晚上还要上课。

对Bellman-Ford改进了一点点。


十二月四日 晴天吧?

又有一点殚精竭虑的感觉,奋斗了一整天完成了这个scheduler。我对他还是比较满意的,这个模拟程序自动产生一系列的任务,然后,scheduler按照round-robin的法则执行任务,每个任务都是针对一个数据库对象进行写和读的操作,每个任务有一个timestamp,scheduler 根据timestamp的同步法则决定是否读写操作可以进行,或者abort,transaction执行结束进行commit动作。其中最大的收获是我认为我发现了书本里面的一个大的漏洞,在读的法则中,书本要求一定要检查对象的committed状态,这是不对的,只有true才能进行,这是不对的,因为,如果读写来自同一个transaction,当然不需要考虑committed状态了,否则就会造成死锁。代码写得比较难懂,不过呢这个问题本来就不是那么简单,恐怕也难以简化了吧?我常常想很多人号称学c++多少多少年了,可是真正写代码的时间恐怕并不多,这样我只能理解他说的是多少多少年前他学过c++,现在不怎么用就又忘了,哈哈。真正的飞行员之间只会用一个标准来衡量:每年飞行的小时数,如果按照这个标准,我想我大概在五六百以上吧?

这雪下得正紧!我踏着白雪,顶着雪花出发准备去探望朱春明的新家。一路上到处可以看到五彩缤纷的圣诞灯,天空和地面的积雪一样白花花的一片,仿佛北极圈里的白夜一样。来到朱春明的新家,一看还真不错,新买的家具给人一种新潮的感觉。(太夸张了吧?)我又滔滔不绝地向他介绍我最近的心得,比如在struct里面写成员函数,模板比继承的效率来的高,concurrency的本质就是遵循一定的顺序,至于说怎样的顺序,以及怎样来维护确有两种截然不同的出发点:悲观主义认为顺序总是会被破坏,所以时时刻刻用lock, semaphore, exclusive来限制;而乐观主义则相反,认为大多数时候,秩序可以自动得到维护,我们所要做的只是事后来检查。这正像东方人认为人之初性本恶,default状态要下地狱,因此处处防范堵截;而西方人认为人之初性本善,只要不是死不改悔都会上天堂,只要没证据证明每个人都是innocent;所以,数据库里面的concurrency-control有lock,与timestamp两大类。针对朱春明同学对我的不读书的第n次惊讶,我给他讲了一个小故事,这是从电影里看来的:讲的是英国一个私立学校里面拉丁语课的一个老师为人正直敬业,对教学一丝不苟,班上有一个学生很好学每天到他那里额外学习拉丁语,结果遭到班上其他不学习的同学的嫉恨,有一天,老师用拉丁语说了一句谚语,英语就是:“The art of learning is to conceal learning.”班上的其他同学水平有限都如同听天书,唯有这个小同学发出了会心的微笑,老师心里很高兴就让他翻译给其他同学,这个小同学犹豫了一下,说了一句话,老师心里更高兴了,这句话是什么呢?我先不说,我想说释迦牟尼说法的时候捻花而笑,其中唯有一个弟子也作捻花的动作相视而笑的典故和这有异曲同工之妙。如果,那个小同学真地听懂了谚语,他的回答自然就是:我没有听懂。如果你听懂了就应该明白我平常不读书自有我的道理,conceal应该有很多种形式吧?当然,也许我是真的不爱读书呢?


十二月七日 时有雪

Concordia真是一个藏龙卧虎的地方,至少我是这么认为的。上一次,我说过有人的才智胜过我十几公里还不止,这一次,我有从时间上对比了一下,差距至少是半个月。对于reduce问题的理解我脑子一直没有转过弯来,经同学的解释之后才明白了一点。


十二月十三日 雪停了

一大队不顺心的事情,眼看考试就要到了,还是没辙。郁闷的写了一个比较失败的东西,希望以后能够改进了


十二月二十五日 临辰

今天是圣诞节了,楼上的室友要赶早班飞机回国,结果在她出发之前,我已经被迫醒来算是欢送吧?我没有一丝一毫的抱怨,因为,也许我还是这么早醒来的,并且你还有机会看一部很有意思的电影《woman in red》,我以前看《matrix》并不知道mouse画得woman in red是有典故,我上一次看到了他的结尾:一个已近不惑之年的老人要去体会他偶然发现的浪漫,比如说“上帝带给他的最后的礼物。。。”之类,这有一点点阴损,不过这不是我说的,我只是引用而已,是钱钟书在《围城》里说的,“如同老房子失火”。当然大家应该不会误会我在讥讽现实的风云人物吧?可是,即便的了诺贝尔的什么奖什么的,也会和他的从前合作十几年,几十年的伙伴有着那么多耐人寻味的争执,即便是得了诺贝尔什么奖的,也会经常以为自己是无所不能的政治风云人物,从这里我们仿佛知道这些都是凡人所共同拥有的品德而已,并不一定是他们头顶上的光环所能掩盖的,不过那个光环却能给与他们一些常人不能超越的通行证而已。当然,我觉得我无权评论某些名人私生活,但是,谁让他们是名人呢?最后,电影的女主角我发现原来是《魔戒》里面的那个女精灵,她在停车场里的地面通风口上的一小段独舞真是绝妙,可能是从玛丽莲梦露那里学来的吧?


十二月二十七日 雪停了

 昨天是所谓boxing day,也就是加拿大劳动人民被商业资本家欺骗的一天,哈哈。严重了。我纯粹凑热闹去看了看,回来的时候一不小心在地铁上睡过头了,就只好去wal-mart,一不小心买了一双鞋子,终于把我那双去年穿了一年的鞋子更新了。这两天头脑不是很清楚,一个简单的动态hash花了两天才完成。

                           

                               back.gif (341 bytes)     up.gif (335 bytes)     next.gif (337 bytes)