Random Tech Thoughts

The title above is not random

介绍两本数学书

最近重新看线性代数,看的是网上的一本免费的教材,Linear Algebra 。觉得写的很清楚,用例子引出理论,看起来比较有动力。另外它每一章后面会有一些专题,其中有一些计算机方面的材料,很有意思。这些专题涉及计算机代数系统,计算准确性,网络模拟,水晶结构,马尔可夫链等等。

另外一本是统计教材,不过还没有完全完成,名字是 Introduction to statistical thought。这本书的特点是用统计软件 R 作为教学工具来帮助学习,相对具体的统计方法,更重视介绍统计的思想。

这两本教材我都看了一些,感觉都还不错,看的时候都会觉得有意思而继续看下去。想起 “Concrete Mathemacits” 的前言,”mathematics should be fun”,开始有这样的感觉了。如果我们的教材能够给我们这样的感觉的话我也用不着现在再来重学了。

Dive Into Python

我觉得很不错的一本讲 Python 的书。Dive Into Python,适合有经验的程序员,GNU Free Documentation License 下发布。

每一章先上一段代码,通过这些代码解释语言的特性,没有什么废话,很快就涉及语言里比较高级的特性(第 4 章就开始讲 introspection 了。Dave Thomas 的 Programming Ruby 这本书就感觉太罗嗦,因为没有耐心看最后几章,Ruby 的 introspection 特性我都不怎么了解。)

去年就学了 Ruby,不过没有用它做过实际的项目,只写过一些小的文本处理的脚本而已。毕设我不打算用 C,开发效率太低了,Java 已经腻了,而 Ruby 糟糕的实现始终有点让人担心,对 Common Lisp 还是没有把握。看到今年的语言流行度,加上毕设可能要用的一个重要的类库只有 Python 的绑定,还是决定学下 Python 了。初步印象还不错,不过还是很喜欢 Ruby 里面的 block。

上海–南京–无锡,2007 年的最后一个月

这篇文章将是 2007 年的最后一篇了,一个月没有更新,所经历的事情都想记录下来,即使看起来像是鸡毛蒜皮的小事,但对我来说都有一些特别的意义。就是一篇流水帐,但以后就可以靠这篇流水帐记起这一个有着许多变化的月份中尽可能多的一些细节。

这一个月,来回在上海、南京和无锡之间。发现了对上海的一点不适应与失望,找到了对浦口、对南大、对南京的归属感,而曾祖母的去世也让我更加珍惜与祖辈亲人们相聚的机会。

上海

12 月 7 日从浦口到上海。没有太多的不舍,有的是对新环境的憧憬。

到上海以后第一个去的地方是实验室。说是实验室,其实跟机房也差不多,分到的临时使用的机器比在浦口的差不少,另外因为网络供应商的问题,网速很差,连我自己的 blog 都很难访问。实验室的好处是有午饭和晚饭,不过不是福利,而是为了方便工作,所以不能什么都不干而只是跑去吃白饭;实验室可以直接访问教育网和校园网,在浦口的时候从来没有体验过教育网和校园网丰富资源的我终于见识了。实验室有两个南大的师兄,一个研一,一个研三。

我暂时住在北区的博士生的宿舍,除了留学生宿舍以外这应该是复旦最好的宿舍了。一个单元里面有四个单人间,每个单人间有一个不大的阳台,卫生间是四人共用的,有热水器,不过冬天在宿舍洗澡还是会比较冷,饮水机每桶纯净水只要 2 元(上海的自来水漂白粉味道重得我受不了)。宿舍楼下有防盗门,用一卡通照一下就能开门,没有一卡通是进不了宿舍楼的,因此复旦的一个楼管可以负责好几幢宿舍。不过宿舍在六楼,这个比较麻烦,好在食堂和体育馆离宿舍楼都很近。

说起食堂,真想念浦口的食堂!复旦的食堂平均每顿要比浦口贵出 2 元,东西给得比浦口少,关键还不好吃,唯一的好处是随便什么时候去都不挤,可能因为不好吃而去的人少吧。像我一天在食堂最多也就吃两顿,通常都只吃早餐,在实验室和外面吃的比较多。总之在复旦吃的没有浦口爽,苦啊……

复旦的邯郸校区分成三大片,南区、北区宿舍和夹在中间的教学区。有些学院和图书馆单独在外,不过离教学区也不院,如经院,管院和新传院。我所在的实验室离得比较远,在邯郸路上的一幢写字楼里,从北区宿舍骑车过去要十五分钟。南区有个体育场,很现代化的样子,北区有一个体育馆,里面有篮球场,几片羽毛球场和一个乒乓球馆。教学区每天骑车去实验室的时候会经过,虽然也有树林,也有一些古建筑,但树林没有金陵苑那样茂密可爱,古建筑也没有北大楼精致古朴。而矗立在学校东边的光华楼完全是现代化的体现(也是富有的体现),当然里面设施也是足够的现代化,听同学说自习环境很好。

南区宿舍外有条街,人称南区一条街,街上有各色饭店,还有一些小超市。北区宿舍北门出去不远也有一条休闲娱乐街,而北区南门出去那条街则人称”非洲街“,据说那里的店比较黑。五角场离复旦也只有一站路的距离,骑车的话 5 分钟,那里有 Walmart,各式时装店、饭店、娱乐场所。复旦就在这么一个非常适合腐败的地方,生活上当然很便利。(南大的师兄却觉得鼓楼更方便,可惜我无从比较。)刚来复旦的第二天就和同学去五角场玩了一次,K 歌吃饭,印象最深的就是冰火菠萝包,确实很好吃,当然价格有点贵。然而,在如此摩登繁华的商业中心逛的时候还是感到了一点不适应。在这里我就是一个土人,虽然我不在乎这一点,而且也不打算在这一点上做出什么变化,但我似乎不喜欢这种喧嚣的现代化。或许是初来时产生的排斥吧,更可能的是我希望一个城市带有更多自然气息和历史底蕴。而我还没有发现上海在这方面的体现,唯一看到的就是她的现代化与喧闹。

在复旦的同学们大都很享受这里的生活,常常在 bbs 上版聊,聚在一起去腐败。(而我在南大的高中同学到现在也只聚过 3, 4 次而已,平时联系也比较少,或许是因为我们没有一个可以大家一起交流的地方。)学习之外也过得很精彩,甚至学习本身倒未必是占最重份量的(不过他们学习成绩都不错)。以前在浦口时一直对单调的生活感到不满,可现在却觉得浦口平静的生活也很可贵。有点怕环境的喧嚣、过多的诱惑使自己无法静心读书。Bella 说是否平静关键还是在自己的内心,她这么一说倒使我宽慰不少。

晚上一个人在宿舍的时候会感到孤独,突然发现浦口的宿舍有那么多同学朋友是那样美好,即使宿舍的条件比这里的差一些。在什么地方并不重要,重要的是跟谁在一起吧。看了 Ann 推荐的 Becoming Jane,唏嘘不已,于是连电影都不敢看。后来回到宿舍就在燕曦上和高中同学版聊,终于不再感到孤单。

南京

12 月 18 号,从上海到浦口。非常盼望回浦口,就像盼望回家一样。

上海火车站进站的路上有一个广告牌,上面写着“喜欢南京的理由”。看到时怔住了,突然发现我其实挺喜欢南京,尽管在南京时我几乎从没有这样觉得。甚至于在 11 月时, Anne 带我到夫子庙的莲湖糕团点吃赤豆元宵时问我对南京有没有归属感,我可以毫不犹豫的说没有。

走出南京火车站,看到眼前的玄武湖,如此熟悉,如此漂亮,这就是喜欢南京的一个理由。159 依然拥挤,但我不再埋怨。在公车上想起 11 月时去中山陵一带玩,想起总统府,想起台城的杨柳和城墙,南京是个很有自然气息和历史底蕴的城市。就目前来看,我会更喜欢南京一些,可能是因为对她更熟悉,在这里生活的几年中南京已经让我喜欢上了她,也可能与我与生俱来的性格有关。

回到浦口,真的有种回家的感觉!隔壁宿舍的 Billy 在,聊了一会儿,去食堂很爽的吃了一顿,真是想死浦口的食堂了!正好是周二,晚上又去上了一次小提琴课,很伤心的发现一个多星期不碰琴的后果是完全没有感觉了。下课时麻烦一个可爱的材料系大二 MM 帮我跟老师一起拍了几张照。送老师去坐校车的时候老师鼓励我继续学琴,老师还告诉我靠选修课学琴一年到我这个程度的还是第一个。很想继续练琴,不过在复旦还要想办法自己创造条件才行。

周三上午年级大会上浩然姐姐把毕设的要求说了,就这样,本科就只剩下最后的毕业设计了。我剩下的半年时间都会在复旦度过,因此在浦口的时间其实也只有 3 年半而已(有点为最后一年的学费不平)。下午找到 Jay 和 Taylor 签了 Sun email 来的协议,再寄回北京,就等着 Sun 把奖品寄来了。一个小组的三个人,填了三个不同的邮寄地址。在机房一起写程序参加比赛也就是三个月前的事,而半年前机房还有查师兄,大家一起写程序,发牢骚,聊天,开玩笑。玩笑总喜欢开在润的头上。唉,润其实是个多愁善感的人(我也是)。就在这一天,小曹告诉我润在上海找到了他喜欢的工作,祝贺他了!以后可以在上海多见面了。晚上去沙宣理念理发,想起第一次来这里的时候是查师兄推荐的,那次有我,查师兄,Jay, Taylor 四人,大家一致认为这家店理发很认真,从那次以后就都来这里了。

特意待到周四再走,想在浦口多待些时间。上午约了大二的学弟带我去琴房练琴,这还是头一次,真对不起被我干扰了一年的舍友。去的时候琴房已经有人在弹钢琴,不知道什么曲名,难度挺大,弹的很好听,好听的让我有点不好意思拉琴,相信练琴的是个很好的 MM。下午收拾东西,越来越觉得舍不得离开。宿舍只有我一个人,很无耻的死缠烂打把 Billy 拉到我宿舍,有人陪才把东西收拾完。最后去食堂吃了晚餐,Billy 很爽快的答应送我到车站,实在是谢谢他,被我烦了一个下午。坐上 131,换了几次车到了在台城的阿姨家,为的是明天去看次 Bella,谢谢她经常在我失落时开导我,同时也为了在走之前再看看鼓楼的南大,看看可爱的北大楼。

从没有想过,离开之后竟会觉得浦口如此可爱,而我会对离开如此不舍。以前总觉得我对南大没有归属感,但在上海时遇到南大的师兄时自然产生的亲切感使我明白,我确实属于南大。明年的 5 月我一定回来再好好看看!

无锡

12 月 21 日,从南京到无锡。回家了,只有父亲接我,母亲明天才回来。

23 日早晨,还没有起床,家里接到电话,曾祖母去世了。和曾祖母虽然感情不深,但她毕竟也是我的亲人。曾祖母身体一直都还可以,不耳聋,也不眼花,过年就 90 岁了。以前每次回到奶奶家,她都会走到门口来迎接我们。她喜欢叫我“囡囡”,别人送她的零食她都会拿来问我要不要吃。而每次走的时候都会一再的嘱咐多回来看看,有时甚至会因为舍不得我们走而流泪。然而我每年也就回去几次而已。记不清最近的一次见面是 5.1 还是去年春节了,如果 22 号去奶奶家的话还能多见曾祖母一面。可我却是因为她去世才去奶奶家,否则也没有去的打算。

值得宽慰的是曾祖母走的很平静,是在睡梦中离去的。虽然曾祖母身体还可以,但毕竟年级大了行动不便,有时也会有些病痛。平时就只有奶奶和她住在一起,奶奶出去的时候一定很寂寞,她又没什么文化,电视报纸之类的东西不能拿来娱乐。离去对于曾祖母来说也是种解脱,她从此不用担心自己哪天瘫痪在床以后要由谁来照顾,也不会再有那些小毛小病带来的痛苦了。而如此平静的离去也一直都是她自己所希望的。

25 日曾祖母下葬了,正巧是圣诞节,祝你在天国一切都好!

奶奶,外公和外婆都已经 70 出头了,祝你们健康长寿!我以后会经常回来看你们的,从上海回无锡要比南京方便一些。


26 日无锡到上海,定下毕业设计的题目。29 日又回到无锡,写下以上文字。

最后祝福我的朋友们和看到本文的人新年一切顺利!

Weak Reference

看到了这篇 blog 文章,Understanding Weak Reference。作者说很多 Java 程序员都不知道什么是 weak reference,他的评论至少对我来说是对的。不过这也证明了 Java 的一点好处就是即使你不是很懂 Java 也能用 Java 写程序,不过写的比较烂而已。有人说 Java 程序通常都是一团糟,其实是因为用 Java 写程序的人有许多都不能算合格的 Java 程序员,从这一点上来说这又是 Java 的缺点。扯远了,总之,我觉得我的 Java 不合格,学 Java 还从来没有完整看过哪怕一本书,或许看过了的话就不会连这个在 Java 里有了近一个年代的东西都完全不知道……

回到正题上来。Weak Reference 是什么?其实是跟垃圾收集相关的东西。我做个原文摘要,有兴趣的看原文吧。

有 Weak Reference 当然也有 Strong Reference。其实我们常用的引用就是 strong reference,比如下面代码就会创建一个 strong reference。

Object foo = new Object();

执行上面代码的时候将创建一个对象,变量 foo 中存放了这个对象的 Strong Reference,利用它可以访问到该对象。

记住一点,只要有 Strong Reference 指向对象,这个对象就不会被垃圾收集器回收。Weak Reference 同样用来引用对象,但是 Weak Reference 指向的对象是可能被回收的,比如当没有 Strong Reference 指向它的时候。

那么什么时候可能用到 Weak Reference?看看下面几个场景。

  1. 你想给对象附加一些信息,于是你用一个 Hashtable 把对象和附加信息关联起来。你不停的把对象和附加信息放入 Hashtable 中,但是当对象用完的时候,你不得不把对象再从 Hashtable 中移除,否则它占用的内存变不会释放。万一你忘记了,那么没有从 Hashtable 中移除的对象也可以算作是内存泄漏。理想的状况应该是当对象用完时,Hashtable 中的对象会自动被垃圾收集器回收,不然你就是在做垃圾回收的工作了。
  2. 你想实现一个图片缓存,因为加载图片的开销比较大。你将图片对象的引用放入这个缓存,以便以后能够重新使用这个对象。但是你必须决定缓存中的哪些图片不再需要了,从而将引用从缓存中移除。不管你使用什么管理缓存的算法,你实际上都在处理垃圾收集的工作,更简单的办法(除非你有特殊的需求,这也应该是最好的办法)是让垃圾收集器来处理,由它来决定回收哪个对象。

Weak Reference 这时候就能派上用场了。把对象的 weak reference 放入 Hashtable 或者缓存中,当没有 strong reference 指向他们的时候,对象就可以被垃圾收集器回收了。实际上,有一个 WeakHashMap 就是专门做这个事的。 那么怎样创建对象的 weak reference 呢?很简单,Java 标准库中有个类 WeakReference,

WeakReference weakref = new WeakReference(ref);

这样 weakref 就是 ref 指向对象的一个 weak reference。要引用这个 weak reference 指向的对象可以用 get 方法。

Object ref = weakref.get();

注意,get 可能返回 null,这时原先指向的对象就不可用了,它可能已经被回收了。

除了 Weak Reference 以外还有 Soft Reference, Phantom references。更多内容除了参考那篇 blog 原文,也可以参考 JDK 文档的 java.lang.ref 包和相关类的文档。我对对象什么情况下可用被回收的解释可能不是完全正确,那个 WeakReference 的文档的解释实在是……如发现错误请纠正。

Weak Alias

Weak Alias 跟 Weak Reference 完全没有任何关系,不过是我在看到 Weak Reference 的时候想到的而已。

Weak Alias 是 gcc 扩展里的东西,实际上是函数的属性。这个东西在库的实现里面可能会经常用到,比如 glibc 里面就用了不少。抄录一段 gcc 手册里面的话解释下函数属性是干啥的,

In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.

先上代码,看看 weak alias 怎么写。第一个文件 dummy.c 内容,

1
2
3
4
5
6
7
8
#include 

/* Do some thing. */
int __foo() {
    puts("I do no thing.");
}

int foo() __attribute__ ((weak, alias("__foo")));

weak 和 alias 分别是两个属性。weak 使得 foo 这个符号在目标文件中作为 weak symbol 而不是 global symbol。用 nm 命令查看编译 dummy.c 生成的目标文件可用看到 foo 是一个 weak symbol,它前面的标记是 W。

00000000 T __foo
00000000 W foo
         U puts

而 alias 则使 foofoo 的一个别名,foo 和 foo 必须在同一个编译单元中定义,否则会编译出错。

那么这个东西的用处是?看第二个文件,func.c,

1
2
3
4
5
#include 

int foo() {
    puts("I do something.");
}

这里有一个函数名字是 foo。如果我们编译 func.c 和 dummy.c 得到两个目标文件,当我们同时使用 func.o 和 dummy.o 和其他目标文件进行链接时,如果其他目标文件里面引用符号 foo,最终使用到的是 func.c 中定义的函数,而不是 __foo,虽然它有一个别名 foo。也就是说,我们最终使用到的函数会是“实际做事”的那个函数。当然,单独使用 dummy.o 链接的话使用的是那个“不做事”的函数。如果 dummy.o 中的 foo 不是 weak symbol 的话,在链接时会产生冲突,这就是我们要使用 weak 的原因。

glibc 的实现里面经常用 weak alias。比如它的 socket 函数,在 C 文件里面你会看到一个 socket 函数,它几乎什么都没有做,只是设置了一些错误代码,返回些东西而已。在同一个 C 文件里面会再声明一个 socket 的 weak alias 别名 socket。实际完成工作的代码通过汇编来实现,在另外的汇编文件里面会有设置系统调用号,执行 sysenter 或者 int 等动作去请求系统调用。以前看 glibc 里面系统调用的实现的时候郁闷过很久,就是那个时候才知道了 weak alias 这个东西。

本科最后一场考试

人机交互,大概是 10:40 的时候交卷的。

就这么结束了,没什么特别的感觉,就记得这次考试还有一点特殊的意义。

读研的时候还会有很多考试的,就算以后工作了还会有很多考试,所以没有什么感慨吧。

Harmonic Number and Violin

Concrete Mathematics 里面提到 Harmonic number 的时候说一下它的名字是怎么来的,和小提琴的泛音有关系,比较有意思。

Harmonic number 中文名称是调和数,

H(n) = 1/1 + 1/2 + 1/3 + ... + 1/n

现在看来中文名翻译成调和数不好,更能体现名字由来的译名应该是泛音数。Harmonic 本来就有泛音的意思,而这个数跟小提琴的泛音确实有关系。

昨天上课时问了下老师。小提琴的泛音是通过手指搭在弦上不按到指板(就是琴弦下面那块黑色的木板)时运弓发出的。通常手指按在弦上但不压到指板运弓的话发不出什么声音,但在如果搭在靠近演奏者的琴弦长度的 ½, 1/3, ¼ 等位置却能发出比较清脆的类似笛子的声音,音调比空弦高,1/2 处比空弦高八度。这些位置发出的声音就叫自然泛音。(另外还有人工泛音,我自己从来没有试过,就不说了。)注意到这些泛音的位置了吗?空弦算作 1/1, 泛音的位置 ½, 1/3, ¼ 正好与 H(n) 中的每一项对应。(网上再查了下,其他两处泛音的位置分别是 2/3 和 ¾ 处,这两个位置就不对应了。更多关于小提琴泛音的资料看这里。)

不过我还是不太明白为什么搭在琴弦的这些特定位置能够发出响亮的声音出来。其他地方发不出声音来我想是因为琴弦的振动被手指阻止了,这几个特定的位置难道正好引起了琴身的共振所以能够发出比较清脆的声音?

Small Tips to Improve Window Switcher Performance in Compiz

After using Sawfish for some time and seeing the amazing new effects provided by compiz-fusion, I switched to compiz-fusion. (I switch window managers about every two months ;–) ) Every thing goes smoothly. The installation of compiz-fusion on Arch is simple, no extra configuration for X is needed since I’ve used beryl before. It just works :–)

One feature I love for compiz & beryl is window switching: You get a preview of each window so it’s much easier to select the desired window. However, the switching operation is not quite smooth on my box no matter what window switcher I am using. I tried to change the configuration for the shift switcher and found that using none overlay icon dramatically increases the performance. I tried this on other window switchers and it also works. Anyway, the overlay icon is not very useful to me, so I can still be happy without it.

Another option I suggest to toggle on is Mipmaps. You will get much better preview without any noticeable performance degeneration.

我来自浦口大学

我来自浦口大学。

前三天都在鼓楼校区转悠,这里虽然陌生,但是却令人喜爱。在校园徘徊很久,不想离开,发自内心地希望自己属于这里。然而,很不甘心的发现,我属于浦口。唯一能够做的就是尽力多看些,多走些地方,留下些照片,证明我曾经来过这里,也好防止忘却。

三年多了,却没有对南大有很强的归属感。浦口平淡的生活也没有什么特别令人留恋的,当然,生活平淡部分也是因为自己的选择。这里的环境我唯一喜欢的就是安静,我不知道是否喜欢这里的荒凉。快要离开了,却没有太多的伤感,可能是因为还没有到再也不会回来的地步,也或许是因为要去的地方有许多的憧憬。毕竟在这里生活过,想到要离开还是会有点异样的感觉。

明年六月的时候不知道又会是怎样的心境,肯定会有更多的伤感,而没有在鼓楼生活过会是我最大的遗憾。在我看来,鼓楼才是真正的南大。如果能够到鼓楼来生活,我也许就不会选择离开。

在复旦的校园里漫步时,我发现这里没有浦口的安静,这里的树林没有鼓楼的可爱茂密,比起那些现代化的高楼,我更喜欢北大楼那样漂亮而又古朴的建筑。而这里的女孩,虽然更摩登,想必也会更加的现实和物质……或许,上海并不是适合我的地方。

我不知道十年以后我会在哪里,会和谁在一起。但我知道现在应该离开浦口,我需要换个环境,浦口过于闭塞。虽然会更喜欢鼓楼一些,但上海可能更能激发我的斗志,也会让我有更多的选择和机会。

真心希望以后能有机会回到鼓楼,弥补未曾在这里生活的遗憾,让我找回应有的归属感:

我来自南京大学!

Squeak — 很卡通的 Samlltalk 开发环境

最近没有怎么看 Common Lisp 方面的东西,时间用来看书和研究 Rubinius 的代码了。(当然,上网也浪费了不少时间 :–( )之前玩了下 Squeak,发现 Smalltalk 跟 Lisp 很像,尤其是他们完全交互式的开发环境,也看到 Ruby 从 Smalltalk 吸收到的东西,比如 block 的语法就跟 Smalltalk 的语法很像,还有对象系统。Squeak 的开发环境好卡通(自己试试看就知道卡通是什么意思了),看了下 image file 包里面的 Welcome 文件,发现这么几行:

Portions of Squeak are: Copyright (c) 1996 Apple Computer, Inc. Copyright (c) 1997-2001 Walt Disney Company, and/or Copyrighted works of many other contributors. All rights reserved.

Walt Disney!完全没有想到,这是我第一次在软件中看到迪斯尼公司的名字。不过这个倒也解释了为什么 Squeak 的吉祥物是只小老鼠 :–)。

Smalltalk 的开发环境很特别,看起来像是一个完整的桌面系统,有文件浏览器,编辑器,桌面等等,很特别。当然,对这样的环境不是很习惯,因为没有 vim 等工具可以使用了,窗口切换之类的也得用鼠标来(有快捷键的话暂时也不知道)。在现在的图形环境下让一个语言包含这样完整的图形系统可能意义不大,但是 Smalltalk 诞生在 Macintosh 之前,它在那个年代就创建了这样的图形环境,是它影响了 Macintosh,Windows。

这里是一篇 Squeak 的不错的 tutorial,抄一段它对 Smalltalk 历史的介绍:

Smalltalk is undoubtedly one of the most influential programming languages ever developed. It was created way back in the ‘70s and early ’80s at a time when many programmers were still entering code at a command prompt rather than into a half-way decent text editor. Smalltalk was to change all that. Unlike other languages, Smalltalk had its own dedicated user interface. Its programming environment included a multi-font editor, a graphical debugger, overlapping windows and pop-up mouse menus. Indeed, it was this environment that provided the inspiration both for the Macintosh and, later on, for Windows.

现在看 Smalltalk 的语法总觉得有点诡异,但它作为对 OO 产生重要影响的一个非常有影响力的语言,很多的程序员都认为它是有必要学习一下的。不过时间有限,我没有打算认真学 Smalltalk,只准备做点简单的了解。