Left-Leaning Red-Black Tree

July 7th, 2008 2 comments

CLRS 上对 Red-Black Tree (RBT) 的介绍简直是一团乱麻,代码又乱,解释又罗嗦,我完全没有实现它的兴趣……

不得不佩服 Robert Sedgewick 啊,他在 Algorithms in C 里先介绍 2-3-4 Tree,把 RBT 作为 2-3-4 Tree 的一种表示方式来介绍 RBT,这样就清楚多了。当然,Sedgewick 本来就是 Red-Black Tree 的发明者之一,他能够讲清楚也就不奇怪了。除了解释清楚以外,Sedgewick 使用递归实现,因此代码很简洁,看起来很舒服。

不过即使如此,Red-Black Tree 还是很复杂,所以即使看了 Sedgewick 的代码以后还是没有自己实现的冲动。好在 Sedgewick 已经考虑过这个问题,其结果就是 Left-Leaning Red-Black Tree。(这份幻灯片做得非常好!Apple 的 Keynote 貌似不错啊。)LLRBT 跟 RBT 的不同之处在于 2-3-4 Tree 的 3-node 在 LLRBT 中只有一种表示方式,因此 LLRBT 减少了 RBT 的插入/删除需要处理的情况数量,从而大大减小了复杂度。RBT 的 Java 迭代实现要用 150 行代码,而递归实现需要 46 行代码,LLRBT 递归则只需要 33 行。删除需要的代码行数也大大减小了,实现难度当然也大大降低了。

我用 Common Lisp 试着实现了 LLRBT,确实很简单。不过我还在想怎样才能迭代实现 LLRBT,找到了 FreeBSD 用头文件实现的 LLRBT,被彻底雷到了,这宏用的太牛了!

Update: 其实 LLRBT 是在好几个月前看到的,最近才想到写出来。FreeBSD 中 LLRBT 实现的作者 Jason Evans 写过一篇文章 “Left-leaning red-black trees are hard to implement“,不过他写文章时候使用的算法中 4-node 对应 RBT 中向左倾斜的 3 个节点,可能因此比较难以实现。Sedgewick 在后来的幻灯片中更新了算法,4-node 变为平衡的三个节点。Evans 还比较了 LLRBT 和其他树实现的性能,在文章的注释中也提到了他将算法改为迭代所采用的办法。

一份介绍 Unicode 和国际化的幻灯片

June 27th, 2008 5 comments

很久没有更新博客了。做毕设的时候是没时间,做完以后是没了动力。六月马上就要过去了,再不写点这个月就没有文章了。

这次就偷个懒,发一份去年在 Linux 程序设计课上做演讲时所做的幻灯片吧,点这里下载。内容是关于 Unicode 和国际化的。制作这份幻灯片时参考了 Tim Bray 的几篇文章,UTF-8/UTF-16 的 RFC 文档,还有 Arnold Robbins 的 “Linux Programming by Exmaple“。主要内容有:

  • 国际化的相关概念
  • 字符集、字符集编码、语言等概念的澄清
  • 使用标准 C 的 wchar_t 和 locale 来解决国际化问题
  • Unicode 的历史,一些基本概念。如 Unicode 和 ISO 10646 的关系,Unicode 的划分。
  • UTF-16, UTF-8 的编码方法,各自优点和缺点
  • gettext 的使用

最早开始接触编码的问题是自己写文本编辑器的时候,为了支持中文才去了解这方面的知识。这份幻灯片准备的还是蛮用心的,花了一个多星期的时间。准备这份幻灯片的时候对编码之类的问题算是搞的比较清楚了,自己写的文本编辑器支持 UTF-8 编码了,后来碰到数据库链接、网页乱码之类的问题都可以猜出问题大概出在什么地方,看别人的解决办法也不会觉得不明不白。Unicode 的知识对于写程序来说还是很重要的,可惜老师不会讲这种东西(或许有些老师自己也不是很明白),只好自己花时间去弄明白了。希望这份幻灯片能给希望了解 Unicode 和国际化的人提供一些帮助。请原谅,幻灯片里中英混杂比较厉害。

PS:

北大楼

毕业快一个星期了,不过最近还在南京待着。出去转了几个学校,除了南农以外,其他从中央大学分出去的学校都去逛了一下。南师的随园很不错,不过还是更喜欢金陵大学的北大楼。看过东南以后觉得当初南大把中央大学的四牌楼校区留给工学院,文理学院搬去金陵大学也不是太遗憾。不知当初设计出金陵大学北大楼的是何许人也,实在是佩服!唯一的遗憾是北大楼后面现在出现了两座高楼,大煞风景,真是可惜!

南大、东南、南师的老校区进校门都是非常相似的,都是两排高大的梧桐树,南林、河海的校区也有不少的梧桐。要说我对这几个学校校园环境的喜欢程度,南大为首,南师其次,东南和南林(学校里有不少漂亮的树林)并列第三,河海虽然为末,但也不错。

Tags:

答辩结束

May 28th, 2008 4 comments

论文准备了两个星期,修改了好几次,今天终于答辩了。

记得去年查师兄答辩时穿的是红色 T 恤,今天我也特意选了红色的 T 恤,不过答辩的房间是 625 而不是 614。回想去年答辩时自己只是听众,而今天自己要作为答辩人,不由感慨时间过得真是快。

8:30 答辩开始。毕设是关于访问控制机制里的安全模型的设计和实现,这种东西 10 几分钟要想讲清没那么容易,而我为答辩做的准备也不是太充分,讲的时候感觉有点乱。感觉讲的有点挫,演示虽然很顺利,但是因为毕设的主要工作是在内核里,能看到的效果也就是 root 用户的权限被限制了,还有我们的访问控制机制确实是生效了。答辩的老师对访问控制之类的东西可能也不是很熟,没有问我什么太技术性的问题,问到的问题都轻松回答了。没想到就这么结束了,比我想像的要失败一些……

同时答辩的同学全部答辩结束以后老师讨论结果。等待的时候有那么一点点担心因为答辩时失败的表现而出岔子,不过公布结果时论文被刘嘉老师表扬为是这两年里本科一辩论文中他看到的最好的,听到这个称赞还是很开心的,不过也有点心虚。刘老师欠我的一件 IBM 的纪念 T 恤就此也不打算去追着要了,说不定他也记得这事,所以就故意表扬我一下,让我不再追究。

本科学业到今天就结束了,距离离校还有 20 多天。想起来下个星期还有一次小提琴课,这样算的话学业也还没有结束。然而总还是会要离开的,要好好珍惜最后这段日子了。

Tags:

地震

May 14th, 2008 2 comments

看到很多人在博客里谈这次博客,为灾区的人祈福,觉得自己什么连在博客上都没有写上些什么真是不该。

5.12 下午在机房写论文,三点的时候看到 Google Reader 订阅的草莓上有消息说有地震。开始时有点怀疑,后来看到的美国地震监测网站上的消息说震级有 7.5 级而且网上开始有照片发出来才开始相信。

遇难人数从刚开始确定的 2000 多人一下子飚升到 12000 多人,实在是太令人震惊了,第一次看到一次灾难能够在如此短的时间内夺去这么多人的生命!这种时候真的能够感觉到生命是脆弱的。

灾区的人们生活因此而遭到破坏,我这里一切都安然无恙,或许该感到庆幸吧。为如此之多同胞的遭遇感到同情应该是一个有心有肺的正常人都会有的情绪吧,然而除了祝福受灾的人以外无法直接为他们做些什么。学校开始组织捐款,下次去力行馆的时候把身上的零钱都捐出来吧。

Tags:

第一次听音乐会

April 27th, 2008 3 comments

昨天晚上去南京文化艺术中心听了维也纳爱乐弦乐独奏家乐团的音乐会,生平第一次听音乐会,也算是长见识了。

这个弦乐独奏家乐团一共 11 人,六个小提琴演奏家,两个中提琴和大提琴,还有一个低音提琴。(查了一下,低音提琴又叫大贝司,贝司指的是低音吉他。)宣传说这个乐团的主要成员来自维也纳爱乐乐团,去听的时候发现海报上的音乐家们比实际的看起来要年轻,估计海报上是很早以前的照片,而且其中有几个(大概是 3 个,都是小提琴手)比较年轻的面孔是海报上没有的。演奏曲目和宣传海报上的一样,莫扎特的 D 大调弦乐嬉游曲,罗西尼的弦乐协奏曲,巴赫的 D 小调双小提琴协奏曲还有柴可夫斯基的小夜曲。巴赫和莫扎特的都曾经听过,也是很喜欢的曲子,其他的两首都是陌生的。

买的是 180 的票,13 排,还算靠前,但在最边上,离舞台大概三、四十米的样子。因为是第一次听音乐会,所以也不知道昨天的音响效果究竟如何,总之比我用 iPod 听要好。而这个级别的演奏家我自然也是挑不出什么刺来,评论的话也没有那个水平。小提琴老师说乐队演奏要让声音像丝绸一样,昨天确实感受到了,看演奏家们一起配合演奏出动听的旋律出来是很享受的,也很赞叹他们的技巧。

现场的好处还在于可以看到音乐家们实际演奏的样子,看到他们如何用动作交流来配合。这些对我这样稍微学过一点小提琴的人来说也是很有趣的。一个细节是高个子的小提琴手坐着拉小提琴时不用把右腿向后挪,这个比较爽,可以坐的很舒服。另外一个细节是用脚打拍子的只有首席,而且只有在乐曲在节奏很快的时候才会打拍子。很羡慕他们的右手手腕在运弓时可以那样柔软,但是运弓又很有力。低音提琴手演奏起来也很有趣,运弓的方式跟其他提琴差别很大,弓子不用与琴弦相垂直运动,是一个可爱的大个老先生演奏的,得一直站着,难为他了。

上半场最后一首巴赫的双小提琴协奏曲演奏完三个乐章以后马上加演了一个乐章,不知道是哪首曲子(听不懂首席说的话),非常忧伤的一首曲子。同去的 Ann 第一次听巴赫的双小提琴协奏曲,很有感觉,而对加演的这首曲子更是感动。最后加演的三首中两首是施特劳斯的(施特劳斯跟维也纳爱乐乐团的关系果然不一般啊),一首是完全拨弦的(可惜我不知道名字),另外是一首波尔卡舞曲。拨弦的那首演奏时很有意思,演奏低音提琴的大爷原来站在舞台右侧,演奏时拿了一个声音像碰铃的乐器漫步走到乐队前面,随着节奏敲出了几声银铃一般的声音,而最后一下敲到了自己的手指,然后便回到原位,拿着提琴到舞台后面去了。乐曲快要结束的时候,老大爷又从舞台左侧出来了,在最后一个音的时候做了个很夸张的像是要摔倒的动作,实在是很可爱。加演的最后一首是闪闪的红星,听到如此熟悉的曲子全场都跟着一起用掌声来打拍子了。(这个好像也是维也纳爱乐乐团在新年音乐会演奏结束曲拉德斯基进行曲时候的惯例。)

听音乐会礼仪上还是有点讲究的,Ann 在这方面就比我在行,正装出席,而我连正装都没有一套,结果只能穿着休闲衬衫、牛仔裤和运动鞋去,好在周围的人多数也没有穿得太正式,不然就太突兀了。另外每一首曲子的乐章间隔时不该鼓掌,昨天虽然在开场前和第一首曲子结束后在广播中有告知听众,但还是有人在乐章之间鼓掌,只有到了最后一首小夜曲的乐章间隔,可能是由于曲子本身的原因,大家都不好意思去打破宁静的氛围而没有在乐章间隔鼓掌。而谢幕时怎样鼓掌表示请求加演,什么时候应该站起来 Ann 也不是很清楚,以后要找个行家扫盲。到了上海听音乐会的机会会比较多,到时候不能在这种事情上面丢人。

有时会 YY 遇到个会拉小提琴的女朋友。听过今天的音乐会想,如果如愿的话以后婚礼的时候和要和她一起演奏巴赫的双小提琴协奏曲。不过巴赫的曲子据说很难演奏,再加上要与乐队配合不是件简单的事,以上 YY 情节的最后一部分恐怕是没有机会实现了。最后贴一个巴赫的双小提琴协奏曲第一乐章的视屏。

Tags:

Ternary Search Tree

April 18th, 2008 3 comments

今天谈下技术。介绍一个蛮有趣的数据结构 Ternary Search Tree,我毕设里的关键代码就依赖于这个数据结构。

这个数据结构的思路 1960 年左右就有了,不过其实际使用价值一直被忽略了。Jon Bentley 和 Robert Sedgewick 在 1997 年发表的论文 Fast Algorithms for Sorting and Searching Strings 中利用这个数据结构实现了针对字符串的快速排序和查找算法,网页上除了论文以外还有实现和测试代码。后来他们又专门针对 Ternary Search Tree 发表了一篇文章,Dr. Dobb 上有在线版本。我是在 Robert Sedgewick 的《Algorithms in C, 3rd edition》中 Radix Search Tree 这一章看到这个数据结构的,这本书将 multi-way branching tries 和 TST 放在一起进行介绍,把 TST 作为 multi-way branching tries 的另一种表现形式来看待,另外也将 TST 和 digital search tries 进行了比较。这里只是对这个数据结构进行概述,详细内容还是看作者的论文去。

Ternary Search Tree 的主要应用场景如下:字符串作为 key,每个字符串的长度不定,需要一种支持动态集合操作的数据结构以便能够快速的通过 key 查找到其对应的 value。用 hash table 的话可以做到快速的搜索,但是有两个缺点,一是随着保存的字符串的增多,需要重新构建 hash table 以保证快速的查找,二是 hash table 中不维护 key 之间的顺序关系。使用平衡 Binary Search Tree (BST) 两个问题都能解决,但是查找的速度相对 hash table 变慢了。如果使用 digital search trie 的话查找虽然非常快,但是需要的内存空间太大。

Ternary Search Tree 结合了 BST 和 trie 两者的优点,利用它还可以很容易的实现 partial-match searching, near-neighbor searching 这样的字符串搜索操作。而且 TST 本身非常简单,实现起来也很容易。与 BST 相比,TST 中每个节点存放的不是整个 key,而只是 key 中的一个字符。而对 tries,只需要进行一点小的修改就得到了 TST。(用 trie 描述起来比较方便,如果不知道 tries 的话可以先看下 trie 是什么。)

  1. 把 tries 中的每个节点保存的 bit 换成一个字符
  2. 和 tries 一样,数据都保存在叶子节点
  3. tries 中每个节点最多有两个子节点,TST 有三个,分别称为 left, mid, right

插入 key 的时候,从树根作为当前节点开始(树为空的时候树根为 nil),一个字符一个字符的递归执行下面过程。

  1. 如果当前节点为 nil,则创建一个新的节点,将当前字符保存在节点中,将其设置为当前节点。
  2. 如果当前字符和当前节点保存的字符都为 ‘\0′,将数据存于当前节点,终止调用。
  3. 如果当前字符小于当前节点保存的字符,那么递归将当前字符插入节点的 left 子节点,大于则插入 right 子节点;相等则将下一个字符插入当前节点的 mid 子节点。

搜索的过程和插入类似,把 key 一个字符一个字符的和树中节点保存的字符进行比较,同样从树根开始递归执行。

  1. 如果当前节点为 nil,则查找失败。
  2. 如果当前字符比节点中的小,递归对 left 子节点查找,依然比较当前字符。
  3. 如果当前字符比节点中的大,递归对 right 子节点查找,依然比较当前字符。
  4. 如果当前字符与节点中的相等且都为 ‘\0′,则这个节点中就存着 key 对应的 value,终止调用。如果相等但是不是 ‘\0′,则递归对 mid 子节点查找,比较字符为下一个字符。

对 TST 性能的最坏情况分析在 “The Analysis of Hybrid Trie Structures” 这篇论文中,不过这篇论文下不到。对失败的查找,字符比较次数往往远小于其中包含的字符个数。使用 hash table 的话仅计算 hash 值就需要访问 key 中的所有字符(比如这里的 string hashing function),而且得到 hash value 之后还得检查 search key 与实际保存的 key 是否相等。所以 TST 的不成功的搜索比 hash table 更快。

论文的两位作者提供的 C 源代码里给出了迭代的插入和搜索的实现。对插入还作了优化,通过预先分配内存池的办法避免了内存分配成为性能瓶颈。对于数据的保存使用了一点 hack,通过 type cast 直接用叶节点的 mid 指针保存 value。因为 char 默认为 unsigned (至少 gcc 如此),所以保存 ‘\0′ 的节点的 mid 和 left 肯定不会指向节点(right 节点可能指向树的节点),所以可以利用他们来保存 value。示例代码直接将 key 保存在叶节点中,但实际上 key 保不保存都没关系,除非以后要用到。对示例代码还有一点要说明的是递归版本和迭代版本有一点小差别,递归版本在实现遇到相同的 key 的时候会将新 value 的存入,而迭代的版本则不会。

对于 partial-match search, near-neighbor search 我就不罗嗦了,论文作者肯定比我说的清楚多了。我毕设里面使用的 search 也是标准 search 的一个小变种。我的 TST 中的 key 是文件系统的路径(假设文件系统用 UTF-8 编码,所以树的节点存放 char 就 OK 了),给定一个 search key (path),如果 TST 中存有 search path 的祖先目录,我希望能够找到与之距离最近的祖先目录。用 TST 来实现这个操作也是非常容易的,有兴趣的可以自己想一下 :-)

TST 也有可以改进的地方。插入过程中,往往到了末尾的字符的时候树种的每一个节点都只有一个 mid 字节点,也就是所谓的 one-way branching,这导致了使用多余的空间,而且对于成功的搜索速度也不一定是最优的。一种改进办法是在接近字符串的尾部使用 multi-way branching 来减少需要的 node,不过怎样确定在什么地方开始 multi-way branching 比较麻烦,而且还要处理多种节点类型的情况。另一种方法是使用 PATRICIA 的思想,在每个节点上再存一个索引,表示其存放的字符是 key 中的第几个字符,比较的时候直接将其与 key 中的特定字符进行比较而不是一个一个的往下比较。这样一来减少了使用的节点,二来对成功的查找,如果保存着的两个 key 之间有几个连续的相同字符就可以跳过这些字符,直接跳到能够区分出这两个不同字符串的字符位置。但这样要求树中也保存 key,在找到节点之后还不要比较一下 search key 和 TST 中保存的 key 是否相同才能决定是否是成功的查找。

发现描述数据结构算法之类的东西还是挺麻烦的,看别人的文章的时候不觉得,自己写的时候就发现难了,也不知道写的能不能让人明白了。欢迎提出建议 :-)

Tags:

爱因斯坦也拉小提琴

April 17th, 2008 2 comments

毕设告一段落,可以放心写博客了。这次我也做回标题党,主要内容其实是介绍我昨天看的一本书的 :-)

昨天去图书馆,在音乐的一个书柜上找到这本书,《古典音乐欣赏入门》,作者刘一贯,他在大学里讲授古典音乐欣赏,又很崇拜爱因斯坦,说要像爱因斯坦一样教音乐,书里还有一张爱因斯坦拉小提琴的照片。由此产生兴趣,看过之后才知道爱因斯坦不仅是古典音乐爱好者,他本人还会演奏小提琴(没有记错的话李四光也会拉小提琴),有时还和鲁宾斯坦合作演奏室内乐。铃木镇一的《莫扎特教育风暴》中有一篇文章,《爱因斯坦的小提琴》,此文介绍了铃木本人在德国时在小提琴学习上受到爱因斯坦鼓励,也讲述了爱因斯坦童年学习小提琴的经历。(铃木是日本著名的小提琴教育家。)

爱因斯坦教别人欣赏古典音乐的方法就是让人听录音,从巴赫的作品开始,但是不对作品做什么讲解,就是让人多听,用直觉去感受。(在巴赫逝世 200 周年时代表美国科学界邀请卡萨尔斯到美国举办音乐会的就是爱因斯坦,或许爱因斯坦还是个巴赫迷。)书上摘录了爱因斯坦对科学和艺术关系的一段精彩的评论:

当我们作为自由的人对世界进行观察、探索和赞美的时候,我们就进入了艺术和科学的领域。

如果把见闻感受用逻辑的语言表达出来,所从事的就是科学。如果其表达形式不能被理智接受,而只能凭直觉领悟,所从事的就是艺术。

两者有一个共同之处,就是对于超越个人利害关系事物的热爱和献身精神。

想起了 Knuth 对科学和艺术的评论,当我们能够将原先只能靠直觉感受的事物用逻辑语言(数学)描述的时候,科学就得到了进步。牛人们对科学和艺术的见解真是精辟,听来让人激动!

作者说像爱因斯坦一样教古典音乐其实就是要让学生多听,而不多做讲解,靠直觉去感受。作曲家的表达媒介就是音乐。有一种音乐体裁叫无词曲,李斯特对它的解释是文字不能表达他想表达的东西,为了避免听众被误导干脆就去掉文字。音乐和其他艺术相比最大特点是它是与时间紧密相关的,乐谱描述的是从音乐开始到结束这段时间内每一个时间点上应该发出什么样的声音,这构成了旋律,它是音乐的灵魂。而古典音乐的一个特点是耐听,一首曲子听过很多遍都不会厌。作者觉得有时候自己喜欢一首曲子部分是因为熟悉,所以通过多听记住一首曲子的旋律,慢慢的就会喜欢上它。听古典音乐的时候遇到自己不喜欢的曲子先跳过好了,没有关系,没必要觉得自己不喜欢是因为听不懂。那些说自己懂一首曲子的人往往是过分自信自己对音乐理解的人。

作为“非专业”入门级古典爱好者,作者的这些看法我挺赞同的。我觉得对理解音乐有意义的解说可能只有作品的创作背景,通过这些背景可以了解作曲家创作时的心情,从而推测出他想在音乐中表达的感情。我觉得即使忽略这些也没关系,自己喜欢就行了,当然这些背景当成八卦来看也挺有意思的。比如有些求爱的曲子之类是为谁创作的,创作以后作曲家有没有把 MM 追到:-) 更何况有些幻想曲、或者炫技的曲子就是灵感来了而做的,也没有什么创作背景可谈,作曲家自己都可能不一定说的清想表达什么。书里面介绍了一些作曲家和演奏家的生平,其中有一些东西可以当八卦来看。

仅仅靠听当然也有不足,比如只靠听的话很可能永远都明白不了作品名字前的什么 A 小调之类的东西是什么意思。(曲式,体裁之类的东西靠听到还是能够自己领悟出来的。)因此书中还介绍了一些乐理方面的基础知识,而这些乐理知识也可以认为是描述音乐的逻辑的语言,使得我们可以系统化的去理解古典音乐。学乐理最好的方法很可能是先去学下钢琴,小时候学电子琴的时候老师跟我讲过一些乐理方面的东西,可惜差不多都忘了。这本书上给了一个钢琴键盘图,通过它来讲解还是很清楚的。书中介绍了音程、音数、度数的概念,它们之间的区别和联系,音程与听觉协和度的关系。还有用五度相生、十二平均律来选择基本音级,调式等基础乐理知识。这些描述都是用的“逻辑的语言”,不少乐理方面的东西在我看来像是数学小游戏。(之前看到 Solidot 上说微软在开发自动生成伴奏的软件,开发这东西的人应该需要不少乐理方面的东西,比如和弦和声什么的。要是我也能去的话就好了,想必那里会有一堆古典音乐的 CD,还可以假借研究之名欣赏古典音乐,妙哉!)

乐理方面只说一个魔鬼音程吧,其实更有意思的是五度相生和十二平均律,但描述起来比较复杂,有兴趣的人可以自己搜下,或者等我以后再写 :-) 魔鬼音程东西跟 sqrt(2) 有关。音程指的是先后或同时发出的两个音之间的结合,表示音高的差别,但是注意决定协和程度的不是音高的差,而是两个音频率的比值,因此音程描述的是音高的比值。完全协和两个音的频率比值是 1:2 (也就是八度的差别),次之的是 2:3。小整数比值的音程听起来会比较协和。钢琴上最不协和(也许听起来并不是最不协和的,但很可能是最难唱准的)的音程的音高比值无法用整数描述,是 1:sqrt(2),也被称为魔鬼音程。看来人们天生还是喜欢整数更多一些啊。

我开始欣赏古典音乐也是到了大学,作者是从 25 岁开始,看到这里也就不觉得自己起步晚了。小时候看过中央电视台的一期节目,介绍了小提琴和三种名琴的历史,那期节目里放了不少维瓦尔第的四季的录音,有吕思清用一把名琴演奏的版本。对这期节目印象很深。从此喜欢上维瓦尔第的四季,也逐渐喜欢上了小提琴和古典,或许也是这期节目让我在大学里产生兴趣并鼓起勇气去学小提琴。喜欢古典导致的一点遗憾是现在从来不听流行音乐了,每次有人拉我去 K歌都只能沉默,最多只能唱几首高中时会唱的。

作者推荐欣赏古典从一些简单的小品开始,他最喜欢的是卡萨尔斯的巴赫大提琴小品,另外他还推荐莫扎特的一些小品。作者自己收藏有上千张的 CD,书中推荐了非常之多的古典名作,我就准备拿着上面的曲目单子来扫盲了。(巴赫的大提琴组曲多亏了卡萨尔斯才被世人认识,也使得大提琴作为独奏乐器得到了重视。他 13 岁看到这部作品,25 岁第一次登台演奏其中的一首作品,到 35 岁才给整部作品作了录音。卡本人还有不少传奇的故事。)除了维瓦尔第以外,我听古典音乐也是从巴赫和莫扎特开始的,不过是直接从听协奏曲开始的。贝多芬的作品要到一定的时候才会喜欢吧,并不适合入门。欣赏古典是一条漫长而有趣的道路,我只是刚踏上愉快的旅程而已,所以对于推荐什么没有什么好说的。

爱因斯坦认为对音乐的欣赏没有影响他的科学研究,反而是帮助了他,甚至于在他的自传中写到:“我一生的事业得益于童年时期的音乐训练。”我童年时也有过一点音乐训练,很遗憾的是父亲恨铁不成钢的方式使我一直疲于应付甚至抵触,最终没有坚持下去。但即使这样,还是要感谢父母让我能够在小时候接触到乐器,小时候的经历对我现在学习小提琴还是有帮助的。看到爱因斯坦的故事以后,我更加希望能够坚持把小提琴练下去,争取早日可以拉出动听的旋律来 :-)

最后贴几个视频。第一个是前几天在土豆上看到的罗斯特罗波维奇演奏的巴赫无伴奏大提琴组曲中的前奏曲,给人很静谧的感觉。第二个是 Hilary Hahn(美女!)的访谈,其中有 Bach 的 A 小调小提琴协奏曲第一乐章的录音。第三个是穆特演奏的莫扎特降 B 小调第一小提琴协奏曲,分了好多段,我觉得不错,贴一个第一乐章的。(不过莫扎特的五首小提琴协奏曲里最受欢迎的貌似是第三协奏曲。穆特阿姨当年也挺漂亮的。)

Tags: , ,

Phun – 2D physics sandbox

March 9th, 2008 1 comment

最早在 youtube 的 MIT sketching 这个视频上看到过这种东西,利用这种程序,你可以利用计算机画出一些东西,比如小车,链条,弹簧之类的,随意放置在不同的位置,然后它可以自动演示在有重力等作用你所画的物体将如何运动。slodit 上之前有提到过一个这样的游戏,Crayon Physics Deluxe,不过可惜的是只有 Windows 版的。

这次 solidot 提到的 Phun 是瑞典的一个学生开发的类似的程序,同时提供 Linux, Mac(即将推出) 和 Windows 版本。试了下,蛮有意思的。

Tags:

《交响情人梦》

March 6th, 2008 1 comment

最近让我堕落的源头就是这部电视剧了—《交响情人梦》。以前同学在看的时候因为觉得里面的小提琴演奏的动作比较假,就没有注意它。在复旦的时候有同学觉得这部电视剧不错,正好最近我也需要些娱乐的东西,于是就决定看这部电视剧了。没有让我失望,反倒是如果坚持最初的偏见而不看这部电视剧会是不小的损失。

总得来说属于搞笑类的电视剧,看起来很轻松。没有太多的注意剧情,因为音乐吸引了我多数的注意力。包含很多的古典名曲,莫扎特、贝多芬、肖邦、舒伯特、舒曼、勃拉姆斯等人的作品都有涉及,有不少作曲家我以前没有怎么听说过。作品的形式也很全,奏鸣曲、协奏曲、交响曲都有了。豆瓣上有电视剧中出现的所有曲子的列表,全听下来可不是件容易的事。

看过以后也长了不少音乐方面的知识,比如管弦乐团小提琴首席的重要性,指挥究的作用等等。有些作品出现时会通过某个角色来介绍作曲家和创作背景,演奏时有时会加上一些解说,这样对乐曲会有更好的理解。以前听古典音乐的范围很狭窄,基本只听小提琴协奏曲,而且只局限于莫扎特,维瓦尔第,巴赫这几位作曲家的作品,看这部电视剧的时候喜欢上了不少钢琴曲,比如肖邦的幻想即兴曲,莫扎特的双钢琴奏鸣曲,拉赫曼尼诺夫的第二钢琴协奏曲。我都有点后悔还是应该学钢琴了,钢琴不愧是乐器之王,独奏都能有管弦乐队的气势。小提琴在独奏上还是比不上钢琴,而我这种半路出家的又不可能进乐队去。现在对交响乐也渐渐能够接受了。这部电视剧里面还有很多我喜欢的曲子,有不少都是以前没有听过的。日本有推出这部电视剧中古典音乐合集的 CD,可惜国内没有,只好做不道德的事情了……这两天 iPod 几乎一直随身带着,不少曲子听多了以后轮流在脑中出现,感觉很幸福。

非常推荐这部电视剧,相信很多人看过以后都会开始喜欢上甚至迷上古典的,至少也会对古典产生兴趣 :-)

Tags:

对 Python 和 Ruby 的一点看法

February 27th, 2008 15 comments

还是从我在 Ruby 和 Python 上的经历说起吧。

大二暑假的时候学了 Ruby,但是到现在为止只用 Ruby 做过文本处理,还有一次做 Linux 网络编程作业的时候用 Ruby 实现了一个服务器的原型,还稍微尝试过一下 RoR,不过因为我对 Web 开发没什么兴趣,所以是浅尝辄止而已。平时自己机器上能够用到的 Ruby 程序也只有 deplate 而已。

今年寒假的时候开始考虑毕设的事情,考虑实现语言的时候也曾考虑过 Ruby。但是我要用的 dazuko 的 Ruby 绑定可能存在内存泄漏的问题,引起内存泄漏的原因应该在 Ruby 的实现上。考虑到 Python 的实现更成熟,对于要求稳定的系统程序来说可能更为合适而开始考虑 Python。于是开始看 Dive Into Python,被这本书吸引而继续学下去。我之前的介绍过这本书,很欣赏它。

最经开始更多的实际使用 Python 了,很自然的会想把它跟 Ruby 做些比较。因为我对 Ruby 和 Python 的语法和特性的了解只是一般而已,所以对语法的比较我说不出太多的东西。在我看来语法上来看它们相似的地方多于不同的地方,在它们中进行切换是很方便的。我很喜欢 Ruby 的 block 语法,但 Python 有 list comprehension 和 generator,很多 block 的用法都可以用它们来完成,所以我并不会在使用 Python 的时候非常的渴望 Python 也有 block 语法(仅有的时候是文件打开完成任务以后自动关闭这种地方,Python 里还没有很好的解决)。就语言本身来说我更喜欢 Ruby,个人觉得用 Ruby 写程序更为舒服,而且通常完成同样任务的 Ruby 程序也比 Python 更短。但是 Python 的优秀的社区使我选择 Python 而不是 Ruby。

在 Python 和 Ruby 中我只想选一个,用它来完成一些 quick and dirty 的任务,我希望一切越简单越好,最好就是别人已经帮我完成了,直接拿来用就可以。随着越来越多的使用 Python,看到 Python 社区所完成的工作,我觉得 Python 才是这一任务更好的选择。Guido 在一次访谈中说:

对于杀手锏应用(killer application),我个人并不十分迷信。如果你太看重杀手锏应用的话,实际上你可能会把焦点放错地方,或者你可能太专注于某一个方面。

以前对这话觉得不屑,觉得是酸葡萄心里而已,现在越来越觉得 Guido 是对的。Python 现在已经进入很多领域,在科研领域,已经出现像 NumPy, SciPy 这样优秀的软件。我也看到生物信息学研究者写的用 Python 编程来处理生物信息学问题的文章。在图形处理方面也有了优秀的软件,如 PIL。而 NASA, Google 等组织也在大量使用 Python。而在 Web 开发框架上,Python 有不止一个,另外还有像 twisted 这样高层的互联网应用程序开发框架。实现上 CPython 比 CRuby 也要成熟,两者都有许多实现,以前很看好 Rubinius,但现在我知道了 PyPy,如果 Rubinius 能够使得 Ruby 在性能上有很大的提升,那 PyPy 肯定也能,事实上 PyPy 现在应该比 Rubinius 更成熟。而我现在自己常用的 VCS 工具 Mercurial 就是用 Python 实现的。

从使用的广泛程度来说 Python 目前远超过 Ruby,记得 2008 年 1 月的程序设计语言使用广泛度统计中 Python 排名首次超过 Perl,而 Ruby 的排名反而下降了。不知道是因为 Python 有大量优秀的软件导致大量的使用,还是因为大量的使用导致有如此多优秀的软件,但现在的社区已经使得这两个方面可以互相促进,形成一个良性循环了。如果 Python 社区的注意力都集中在 Web 开发上,或许它可以出一个类似 RoR 的 killer application,但它就不会产生如此之多不同领域的优秀软件,也会使得 Python 的使用达不到如此广泛的程度。在我看来这是得不偿失的。

即使我不喜欢 Python 中一些 Guido 强加给我的限制,但是只要它能够让我把那些 quick and dirty work 以最快的速度最小的精力做完,我就不在乎,而那些限制在构建大型软件上可能反而能够带来好处。如果哪天 Ruby 能够像 Python 社区这样成熟,提供更多的优秀的软件,那我在解决个人的 quick and dirty work 时就会选择使用 Ruby。但是现在,我选 Python。

我仍然会花时间去学 Common Lisp,但 CL 现在不擅长跟 OS 和其他基础设施交互,所以我不会用它来完成日常的工作。我目前只打算想把它作为一个研究性质的语言,满足我对程序设计语言本身的兴趣。一方面,SLIME 提供的交互式的开发环境更加合适探索性的任务(ipython 虽然不错,但是跟 SLIME 和 CL 提供的环境比起来还是差了点);另一方面,正因为有许多工作在 Common Lisp 中还没有完成,我可以尝试自己来研究解决,在其中得到锻炼。我也希望在真正领悟 Common Lisp 的时候我能够成为一个更好的程序员。

语言的选择并不是至关重要的,但是我希望能够使用一个使得编程更加有趣的语言。以前在语言上花了太多的时间,现在决定把语言逐渐固定下来,把注意力放到更加重要的问题上,为我以后的研究做准备。

PS:
现在在浦口每天的时间都可以自己支配,太爽了 :-)

不过想看的书太多了宏观经济学(微观已经看完了),算法导论,线性代数,Ansi Common Lisp,还要每天在毕设上投入一点时间(现在还在准备阶段),再加上要利用本科最后这个学期好好练小提琴,有点安排不过来了。为了集中精力,有些书看了一点又要停下来了。

最近回到浦口真开心,爱死浦口的食堂了 :-) 我现在的日子跟查师兄去年的比真是太舒服了,这两天有点堕落,明天起要鞭策自己努力了。