在 Linux 上制作数据软盘或者 CD 镜像

当在 Linux 下和虚拟机共享文件时,我发现一个问题,并不是所有的虚拟机都支持(或很好的支持)在主机和虚拟机操作系统之间共享文件,这样在需要文件共享时候就会遇到很多问题。不过因为几乎所有操作系统都支持读写软盘和光盘,就可以使用一种比较迂回的办法解决这个问题:建立软盘或者光盘镜像文件,虚拟机使用读写软/光驱的方式打开它,Linux 主机直接挂载它,这样就可以将这个文件作为共享目录使用。不过当虚拟机的操作系统足够强大的时候,完全可以使用虚拟网络传输。

这样就涉及到如何建立一个数据软/光盘镜像。我们平常所挂载的光盘镜像,基本是用于只读的目的,而且是别人建立好的。如何使用 Linux 命令来建立一个数据软/光盘镜像呢?

建立光盘镜像很简单,使用下面命令即可:

genisoimage -o data.iso /data/yourdir/*

这就能直接将 /data/yourdir/ 下的所有文件建立成一个光盘镜像。但是使用光盘镜像唯一一个不足就是,它是只读的,所以文件的共享只能从一个方向进行(如果虚拟机上的系统不支持烧录CD的话 ^_^)。

建立软盘镜像:

前面在 Writing x86 PC Bootloader With Free Software 一文中提到了如何制作启动软盘镜像,但是这个软盘镜像仅仅能用来启动电脑,而不能用来存储数据。因为它没有被格式化,所以不能挂载,因此最主要的任务是要将它格式化。

首先,生成空白软盘镜像:
dd if=/dev/zero of=data.img bs=512 count=2880

使用 losetup 命令,将 data.img 作为 loop device 使用:
sudo losetup /dev/loop0 data.img

然后,格式化这个 loop device:
sudo mkfs.msdos /dev/loop0

检查文件系统:
sudo fsck.msdos /dev/loop0

删除 loop device:
sudo losetup -d /dev/loop0

这时候,data.img 已经格式化完成,可以作为一个软盘镜像使用,比如用 sudo mount -o loop data.img mountdir/ 挂载到 mountdir 上。设置一定的权限之后,使用虚拟机打开这个软盘镜像,就可以把这个镜像当作共享目录来使用,虽然很可怜的是这个文件只有 1.44 M 大小,但在某些时候已经能满足需要了。

Fedora 和 Ubuntu 上的段错误

LilyBBS discussion: Segmentation Fault on Fedora and Ubuntu

昨天和别人在小百合 LinuxUnix 版发帖讨论 Segmentation Fault 的问题,整理如下:

flyDutchMan 根据自己存在段错误的程序在 Fedora 和 Ubuntu 上的运行结果,认为 Fedora 和 Ubuntu 对段错误的处理方式不同,他的观点是(原文链接:[href: http://bbs.nju.edu.cn/vd83468/bbscon?board=LinuxUnix&file=M.1185514732.A&num=6528 ] ):

“Ubuntu认为段错误是很严重的错误,它的做法是当即中断程序。而Fedora对待段错误是比较宽容的,在Fedora中即使检测到某个进程正在对不属于它的地址空间进行操作,他仍然会完成这次“非法”的操作,并且继续执行后面的操作,只是在终端上打印出“Segment Fault”的错误。所以在这个程序中,虽然发生了段错误,Fedora仍然能运行到connect(),是整个程序顺利跑起来。”

并给出了一个 demo:

#include <stdio.h>

#define IP_ADDR_LENGTH 16
#define UMP_FUNC_NUM 6

int main() {
  char addr[IP_ADDR_LENGTH];
  addr[0] = '';
  strcat(addr, "172.16.64.181" );

  char (*taskpath)[IP_ADDR_LENGTH];

  printf("the address is %dn", &amp;taskpath[0]);

  int a;
  int b;

  sprintf(taskpath[0], "%s", addr);

  printf("taskpath[0]: %sn", taskpath[0]);
  printf("finish!n");
  fflush(stdout);

  return 0;
}

“在Ubuntu下运行,系统不会输出“ finish! ”这句,而是在输出taskpath[0]的地址后直接终止程序。注意,上面的int a; int b;声明不能省略,也不能赋值!因为如果省略或赋值,就不会产生Segment Fault!(赋值的话系统就会把这两个变量分配到Stack中,这就与对Heap操作的taskpath没有冲突了)”

我的回复是(原文链接:[href: http://bbs.nju.edu.cn/vd83468/bbscon?board=LinuxUnix&file=M.1185532985.A&num=6538 ]):

首先,我的观点,没有所谓 Fedora 和 Ubuntu 对段错误处理的不同。因为它们都是使用 Linux kernel,而内存管理只要 Kernel 的版本一样,我认为不会有不同的处理方式。

其次,我想纠正上文中的一个说法(可能有些讨人嫌哈,不过一些东西还是说清楚点儿好,因为 ls 用这个来解释自己的程序):

> 赋值的话系统就会把这两个变量分配到Stack中,这就与对Heap操作的taskpath没有冲突了

无论你赋值与否,这两个变量都是存在在 stack 中的; taskpath 也不是对 heap 进行操作,它只是存在于 stack 上的一个指针变量。

> 因为如果省略或赋值,就不会产生Segment Fault!

在我的系统中,都会产生段错误。

最后,我来给出我对这个问题的解释:

就上文的 demo 程序来说, a, b, addr, taskpath 都是存在于 stack 上的,这个很清楚,调试过 C 语言程序的人应该都知道,我就不解释了。

1. 为什么会出现段错误?

因为 taskpath 是一个野指针,在使用之前没有被赋值,所以 taskpath 会指向任何位置,对一个随机的位置进行写操作,显然会出现段错误。

2. 为什么同一个程序,定义不定义 a, b 会影响段错误出来的时间点?

虽然上面说 taskpath 会指向任何位置,但是这个说法并不完全正确。因为大家知道,taskpath 是在 stack 上的一个变量,而 stack 呢,是一直在重复使用的一个区域。要明确这一个概念,在操作系统中执行一个可执行文件,程序并不是从 main 开始的,它要先执行一段代码,也就是平常所说的 crt(c runtime)。这个一般是由 lib 提供的,其中要调用一些库函数,所以呢,在 main 执行之前, stack 被 crt 用过(这是最关键的一点)。

因为 stack 使用完是会被释放的,这也就是在调用函数时 function prologue 和 epilogue 所干的事情,开辟栈空间和恢复栈空间,主要动作就是移动栈指针。那么 taskpath 所占的位置很有可能被 crt 用过(不是一定),那么如果被 crt 写过,比如被 crt 用做保留 ebp 或者什么其他的寄存器,它的值就是确定的(在一定程度上说)。

如果 crt 在 taskpath 这个位置上保存过寄存器的值,尤其是 ebp 或者 esp,那么很有可能 taskpath 就指向此程序栈空间的某个位置。那么写 taskpath 指向的内存产生的段错误就没那么 critical,或者说操作系统对它的指针在自己栈空间中的操作比较容忍,就不会立即停止程序的运行。但是如果 crt 没有在这个位置上进行操作,那么这个位置就可能是某个垃圾地址,比如说操作系统自己的内存空间,那么写 taskpath 指向的内存就会造成很严重的后果,操作系统会立马检查出来终止它的运行。

我在 Ubuntu 7.04 下使用 gcc 4.1.2 编译、调试并反汇编的结果显示:两个程序唯一的不同是 taskpath 在堆栈上的位置,当定义 int a, b; 时,taskpath 是 $ebp -40 而这个地址没有被操作过;当不定义 int a, b; 时, taskpath 是 $ebp - 32,这个地址曾经被 crt 使用过。所以按照上面的解释,系统报段错误的时间不一样。

如果熟悉 GDB 的话,可以很容易的用调试证明这一点。计算出 crt 入口的 $ebp 和 main 中 $ebp 的差,以此计算出 taskpath 保存的位置,在上面设置 watch point,从 _init 执行到 main,看其中有没有对 taskpath 所在位置进行写操作。

3. 为什么不同的操作系统,结果不一样?
这个就比较简单了。kernel 不一样,可能内存管理的方式不一样。使用的 lib 或者 gcc 不一样,可能引起 crt 的汇编结果不一样。这两个都能导致同样的程序报错的时间不一样。

所以,不是 Fedora 或者 Ubuntu 能不能容忍段错误,没有 OS 容忍段错误,不同只是在产生段错误够不够 crucial 需要得到立即处理。

学术点名-来自蔡白银

Cai Baiyin 兄这个是我觉得印象最深刻的点名方式,回答一下吧。

规则:被点名者可以挑自己感兴趣的问题回答,如果你觉得问题设置的好,可以继续问别人。希望被提问者可以自己在后面继续加上你想要问的话题?可以相互提问。

1,你的专业是什么,她是你最喜欢的么?如果不是,那么你最喜欢的专业是什么?

我原来的专业是信息与计算科学(计算数学),现在的专业是信息安全。对于信息安全,我是比信息与计算科学喜欢一点儿,但是不是最喜欢的,我真的没谱。学理工的总想装作有文学修养,我也觉得古典文学对我可能更有吸引力一些 :-)。

2,在你最喜欢的专业里请你列举出至少五位大牛,其中一位是这个专业奠基者,另外一位是你最最崇拜的。

看来我还是说我最喜欢的专业是 CS 吧,因为我根本不知道什么信息安全方向大牛都有谁,计算机科学涵盖的广点儿,能说的人也多点儿。

John Von Nouma:我想应该算是计算机科学的奠基人之一吧,Turing Alan Mathison 也应该算吧。
Richard Matthew Stallman:Free Software 运动的发起者,我对他保持敬意。
Linus Benedict Torvalds:Linux 内核作者,我不知道他算不算牛,但是我很感谢他的贡献。
Claude Elwood Shannon:信息论的创始人,重要性自然不用说了。
Donald Ervin Knuth:TAOCP 的作者,Tex 软件的作者,我最最崇拜的一个人。

3,你觉得在这个专业里你能做出让自己满意的贡献么?说说你如此回答的理由?

我是个半路出家的和尚,虽然我有信心做出一些贡献。到现在为止,我还没找到什么让我满意的贡献方向 :-)。确切的来说,我还没有开始我真正的 CS 专业学习。

4,你满意的贡献能够具体描述给我看看么?

如果让我臆想的话,满意的贡献当然是指可以得 Turing Award 的了,可惜,我连臆想这个可能的方向都无从下手。

5,就你的这个专业,全球那一所学校是最强的?

MIT? Standford? Berkerly? Carnegie Mellon? 我确实不知道哪个是最强的,但能去其中任意一个我都能高兴地发疯!

6,你认为从事此学科的研究需要哪些方面的能力?你自己具备几条?

哈哈,看了 phoenixinter 的回答,我觉得自己什么能力都不具备。
还是装逼一点儿吧,我觉得做这方面研究,要有:
数学能力(有一点儿,要说没有老师会骂我的)
兴趣(还行)
独立自考能力(在学术方面有点差)
自学能力(还行)
狗屎运(到现在为止,觉得还可以)
细心与耐心(很差)

7,希望自己的老婆或者丈夫也是从事这方面研究的么?

千万不要,不然谁做饭?

8,人类历史长河中哪位智者是你最最高山仰止的?

智者太多了......
亚里士多德,哈哈,因为我老听说他,却不知道他的思想内容是什么,真的是“高山仰止”,哈哈!

9,你的人生哲学

Life is hard, get used to it.

10.每天你花多长时间在你的学科上,分别是做什么用的?我最最感兴趣的是你花在读论文上的时间

这个统计起来比较困难,得分阶段吧。我喜欢的时候是一整天,不喜欢的时候不会碰,平均下来,也就那么三四个小时吧~~~

读论文啊,读得很少很少很少,如果平均到四年,大概每天只有几分钟。

其实总的来说,虽然看起来我在计算机科学的应用方面还可以,但是真正对理论科学的研究是相当少的,这也是我为什么研究生阶段要转到一个计算机方向的原因(虽然也有很大一方面是因为世俗的欲望)。

接着点下去:
Forrest Sheng Bao, Eric You Xu

如果你们看到了,就接着来,没看到或者没时间就算了。

Hacking 《自己动手写操作系统》Chapter 1&2

——Writing x86 PC Bootloader With Free Software

本文内容已整理成一本电子书,请到这里下载

今天在看一本书,《自己动手写操作系统》(于渊,电子工业出版社),虽然很欢迎这样一本详尽介绍怎样写操作系统的书出现,但看完前两章后对作者的某些做法很不以为然。比如使用 Windows 作为开发平台,采用商业虚拟机作为测试平台,不是每个人都买得起这些软件的(我们要在心中牢固树立使用盗版软件就是犯罪的观念 X-D)。

我这篇文章的目的就是为了展示 Linux/Free Software 的强大,不使用任何商业软件,不用自己写的任何工具,使用免费的工具链,照样可以完成而且更高效地完成《自己动手写操作系统》前两章的 demo。

当然我也希望这篇文章为推动 Linux 和 Free Software 的发展出一点力,比如让部分读者(尤其是 EE 和 CS 学生)看完这篇文章后舍弃瘟都死,投身到 Linux 和 Free Software 阵营中来,或者《自己动手写操作系统》的作者在下一版(如果有的话)中完全使用 Free Software 来做 demo。

好了,下面开始,先介绍一下需要使用的工具。
操作系统:Ubuntu 7.04 Feisty,平台: i386 PC。
使用工具:gcc, binutils(as, ld, objcopy), dd, make, hexdump, vim, virtualbox。
上面所说的工具中,除了 virtualbox 虚拟机,剩下的工具在任何能用做开发环境的 Linux 版本上都是默认安装的。VirtualBox 也是遵从 GPL 协议的开源软件,可以从这里 [href: http://www.virtualbox.org ]下载。Ubuntu 只需要 sudo apt-get install virtualbox 安装即可。

首先,我们看第一个示例代码:
[wbyang@solrex-PC loader]$ more boot.asm
org 07c00h ; 告诉编译器程序加载到7c00处
mov ax, cs
mov ds, ax
mov es, ax
call DispStr ; 调用显示字符串例程
jmp $ ; 无限循环
DispStr:
mov ax, BootMessage
mov bp, ax ; ES:BP = 串地址
mov cx, 16 ; CX = 串长度
mov ax, 01301h ; AH = 13, AL = 01h
mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
mov dl, 0
int 10h ; 10h 号中断
ret
BootMessage: db "Hello, OS world!"
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
此段代码使用 Intel 格式的汇编语言写成,本也是用同样开源的 NASM 编译,但是鉴于很少有人在 Linux 下使用此汇编语法,它在 Linux 平台上的扩展性和可调试性都不好(GCC 不兼容),而且不是采用 Linux 平台上编译习惯,所以我把它改成了使用 GNU tool chain 去编译连接。这样的话,对以后使用 GNU Toolchain 编写其它体系结构的 bootloader 也有帮助,毕竟 NASM 没有 GAS 用户多。

上面的汇编文件可以用 AT&T 风格改写为:
[wbyang@solrex-PC loader]$ more boot.S
.code16 ;使用16位模式汇编(GAS 默认认为 .S 文件是 pure 32-bits i386 code)
.text ;代码段开始(为 link script 做定位)
mov %cs,%ax
mov %ax,%ds
mov %ax,%es
call DispStr ;调用显示字符串例程
INF: jmp INF ;无限循环(GAS 没有 $ 作为当前行标号的约定)
DispStr:
mov $BootMessage, %ax
mov %ax,%bp ; ES:BP = 串地址
mov $16,%cx ; CX = 串长度
mov $0x1301,%ax ; AH = 13, AL = 01h
mov $0x00c,%bx ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
mov $0,%dl
int $0x10 ; 10h 号中断
ret
BootMessage:.ascii "Hello, OS world!"
.org 510 ; 填充到 510 字节,使生成的二进制代码恰好为512字节
.word 0xaa55 ; 结束标志

但有一个问题, NASM 可以直接使用 nasm boot.asm -o boot.bin 将 boot.asm 编译成 bin 文件,GAS 不能。但是 GAS 的不能恰好给开发者一个机会去分步地实现这个过程,使编译更为灵活。下面请看 link script 和 Makefile:
[wbyang@solrex-PC loader]$ more solrex_x86.ld
SECTIONS
{
. = 0x7c00;
.text :
{
_ftext = .; //告诉链接器程序加载到内存的7c00处
} = 0
}

这个连接脚本的功能就是,在 link 的时候,将程序加载到内存 0x7c00 的位置(BOIS 将 PC 控制权转交给这个位置运行的程序),相当于 boot.asm 中的 org 07c00h 一句。有人可能觉得麻烦,还需要用一个脚本控制加载地址,但是 《自己动手写操作系统》就给了一个很好的反例:Chapter 1.5 代码 1-2,作者切换调试和运行模式时候需要对代码进行注释,而使用脚本控制,只需要编译时候调用不同脚本进行连接,就能解决这个问题。

这在嵌入式编程中是非常常见的处理方式,使用不同的连接脚本一次 make 生成某个程序分别运行在 board 上和 simulator 上的两个二进制文件 。

相信只要能耐心看到这里的人对下面 Makefile 中的内容都不会陌生。
[wbyang@solrex-PC loader]$ more Makefile
CC=gcc
LD=ld
LDFILE=solrex_x86.ld #使用上面提供的连接脚本 solrex_x86.ld
OBJCOPY=objcopy

all: boot.img

boot.img: boot.bin
@dd if=/dev/zero of=emptydisk.img bs=512 count=2880 #生成空白软盘镜像文件
@dd if=boot.bin of=boot.img bs=512 count=1 #用 bin file 生成对应的镜像文件
@dd if=emptydisk.img of=boot.img skip=1 seek=1 bs=512 count=2879 #在 bin 生成的镜像文件后补上空白,最后成为合适大小的软盘镜像

boot.bin: boot.elf
@$(OBJCOPY) -R .pdr -R .comment -R.note -S -O binary boot.elf boot.bin

boot.elf: boot.o
$(LD) boot.o -o boot.elf -e c -Tsolrex_x86.ld

boot.o: boot.S
$(CC) -c boot.S

clean:
@rm -rf boot.o boot.elf boot.bin boot.img

使用 Makefile,一个是方便,直接就可以生成可引导的软盘镜像文件,二是为了清楚,其间对源文件的任何处理都一清二楚。下面解释一下 Makefile 都做了什么:
第一步, gcc 调用 as 将 boot.S 编译成目标文件 boot.o;
第二步, ld 调用连接脚本 solrex_x86.ld 将 boot.o 连接成可执行文件 boot.elf。
第三步, objcopy 移除 boot.elf 中没有用的 section(.pdf,.comment,.note),strip 掉所有符号信息,输出为二进制文件 boot.bin。
第四步, dd 使用 boot.bin 生成可引导的软盘镜像 boot.img。

到此,我们使用开源工具链编译生成 bootloader 的过程已经结束,没有使用到任何商业软件,也没有自己写任何转换工具。《自己动手写操作系统》文中提到的 HD-COPY 和 Floopy Writer 都没有使用到。 为了验证也可以先用 hexdump -x -n 512 boot.img 将 boot.img 前 512 个字节打印出来,可以看到 boot.img dump 的内容和附送光盘中的 TINIX.IMG dump 的内容完全相同。这里我们也显然用不到 EditPlus 或者 UltraEdit,即使需要修改二进制码,也可以使用 vim 的 %!xxd 命令进行十六进制编辑。

写得真够累的,那个 virtualbox 就不说了,用法跟 virtualPC 没有什么大差别。安装上以后,新建一个虚拟机,加载 boot.img 光盘镜像到软驱,然后选择虚拟机重新启动,就可以看到红色的:
Hello, OS world!
当然,你如果喜欢的话,可以改成 "F-U_C-K Microsoft!" 不过要注意的一点是,做这件事是需要权限的,要把当前用户加到 vboxusers 组中,否则这个行为无法成功 :-)。

综上,很显然 VirtualPC 也不需要。《自己动手写操作系统》可怜的作者费了半天劲在瘟都死的 VirtualPC 里装 Redhat Linux,解决瘟都死和 Linux 的文件共享问题,解释了一番自己“工欲善其事,必先利其器”的动机,但我实在没看出有一点儿需要瘟都死的原因。瘟都死什么都不能给你,但 Linux 能给你整个世界!

Tor - Anonymity on Line

其实以前就见过 Baosheng 在博客里推荐 Tor 这个工具,据说可以访问 Wikipedia,只是当时潜意识里觉得太麻烦,就懒得搞。昨天晚上 Baosheng bg,请 ufx222, xum84, daoming, proline 我们一起吃饭,又提到了这个洋葱路由,今天就尝试了一下,果然好用。

简单来说,Tor 的功能就是,采用不同的“洋葱路由器(onion router 意思和代理服务器差不多)”来重定向网络请求,并且随时间更换路由,这样别人就无法监视你的网络访问情况,主要目的是为了保护隐私。而由此带来的副产品就是,onion routers 遍布全世界各地,所以就可以使用这个工具通过 onion routers 访问被“墙”封掉的站点(比如现在的 blogspot.com )。更多介绍请登录 Tor 官方网站 [href: http://tor.eff.org/ ] 。

从我的使用来看,刚开始使用访问网站速度可能慢点儿,用了一段时间之后速度就快很多了,大概是 Tor 自动在寻找洋葱路由服务器。而且最牛的是,我们公司的 DNS 坏了一小段时间,其间什么网站都没办法访问,而通过 Tor 居然访问正常,大概是 Tor 记录的是 IP 而不是 domain 吧。有意思的是访问 google.com 往往被重定向到某个欧洲的 Google 服务器,比如: google.de, google.es 之类的。

在 Linux 下 Tor 的配置很简单(我估计在 Windows 下会更简单,官方网站上有各种系统安装介绍):

首先,安装 Tor 软件,在 Ubuntu 下面就是:
sudo apt-get install tor
使用默认配置即可,即在 9050 端口打开一个 SOCKS 服务器。Tor 程序会以后台方式一直运行在系统里。

其次,为 Firefox 下载 torbutton 插件[href: https://addons.mozilla.org/en-US/firefox/addon/2275 ],安装。安装完成后,到"Tools->Add-ons->Extensions->Torbutton Preferences",在 "Proxy Settings" 中选择 "Use custom proxy settings",然后将前四个都留空,最后 "SOCKS Host:" 中填: localhost, Port: 9050,这样配置就完成了。

可以留意 Firefox 状态栏的最右端(窗口右下角),这时候会出来一个 "Tor Disabled",用鼠标点击该区域,就可以在 "Tor Disabled/Tor Enabled" 状态切换。这样在访问某些敏感站点时候就可以 Enable 它,在不需要时 Disable 它。也可以在 Torbutton Preferences中把这个文字格式的提醒改成一个洋葱头的图标提醒。

其实我想,不安装插件,只在网络设置中使用 SOCKS 代理也可以实现这种功能,如果这样的话,这里插件的作用只是启用和不启用代理的区别。那么,如果在校园网内,这个插件能否起到在 Firefox 的代理和插件这两个代理之间切换的目的呢?如果可以的话,就算不使用或者不能使用 Tor,这个插件也可以用作切换校园网代理使用了,倒也蛮方便的(只是我不需要用到了,所以就留给别人验证吧 X-D)。

PS: Yo2.cn 服务质量在下降,从 2007年7月19日8:25 到 9:00 之间都无法连接上,wget 可以下载但无法显示速度,更无法登录,最后出来一个错误:504 Gateway Time-out。唉,国产的 BSP 千万别学国产的足球队啊!烦死了,回去睡觉。

[zz] 世界上最短的距离

从 baosheng 的博客上看到一篇颇具灵性的文章《世上最短的距离... 》,特转载之.

Original post: [href: http://bbs.nju.edu.cn/vd45799/blogcon?userid=baosheng&file=1184249302 ]

Baosheng 者,鲍盛也,更多请看其个人主页:[href: http://forrest.bao.googlepages.com/]

PNN充分贯彻了Simple is beauty的原则:第一层求距离,第二层找最近的这也就是聚类识别的基本思路。这就带来一个问题,你如何定义距离? dot product? Euclidean distance?

所以,这世界上最短的距离不是我站在你面前而你不知道我爱你,而是我站在你面前,你却不知道如何定义距离。

近期准备写一篇文章,Why PNN is awesome? (为什么PNN帅呆了? )偶很喜欢把awesome翻译成帅呆了而不是令人敬畏的....

PNN: Probabilistic Neural Network(概率神经网络), 一种基于Radial Basis Network(径向基网络)修改过的网络,号称有下列优点:
1. 1000 times faster than back-propagation network
2. robust to noise

附H. Zhu研究small world时作的一篇文章:
偶大一时候还不懂什么叫greedy algorithm,那时居然想做研究,寒...

更多的信息请参考:
[1] J. M. Kleinberg, Nature 406, 845 (2000).
[2] M. Granovetter, Science 301, 773 (2003).
[3] Han Zhu and Zhuangxiong Huang, cond-mat:0404377 (available at arxiv.org)

[4] 成龙,舒淇,《玻璃樽》。

女孩子为了求得冥冥中的如意郎君,会作出种种傻事,据说其中第四十八傻的一种,是把求爱信放在一个瓶子里,投入大海,盼望在这种超越人和人的穿梭中,爱情能找到归宿。

之所以说这只是第四十八傻,因为这其实还并不算特别傻(相比于其他)。爱情是一种近邻双体相互作用,所以这种漫无目的的穿梭,由于其超越了人的因素,反而可能会快很多。

那么怎样才是最有效的传递方式呢?现在大家可能都听说过小世界的概念。人类社会是一个小世界,是因为在近邻联系之外,还存在着很小一部分长程联系。因此,表面上看起来千山万水的距离,也许就隐藏着一个很巧妙的快捷路径。

但是人类社会何其复杂,我们渺小的个人,怎能通晓所有的结构。世上人来人往,单纯的女孩,又何处寻找藏匿的他?很遗憾,即便是真的有很短的路径,我们也很可能茫然不知。

泰戈尔听说这一点以后,欣然修改了他的诗句:
  世界上最遥远的距离,不是天涯海角,
    而是有快捷路径,我却不知道。

先来考察一下,我们是怎样传递信息的?这是一个很基本的问题,每个人都有过体会。譬如说,我们要把一个信息传递给一个不认识的住在北京的医生。我们总是先把信息传给一个北京的朋友,他考虑了一下,再把信息传递给一个在医疗系统里工作的朋友,而由于这个人仍然不认识那个医生,只能把信息传给在那个医院里工作的熟人,最后才终于交给目标。每一次的传递,都是试图交给和目标最接近的人,曲线救国永远是不被考虑的。实际上,也许就存在着短得多的路径,比如说那个目标也许就是某个人的小舅子,但是由于是曲线救国,而没有被考虑到。

千万年来,人类都是采用这样一种方式(有个名字,叫greedy algorithm)。也许你已经猜到了,这种方式,只有在某一些网络里面才是有效的。条件很简单,在这些网络中,长程的联系出现的概率一定要随距离衰减(衰减不能太快,也不能太慢)。只有这样,北京人和北京人,医生和医生之间相互认识的概率才会比一般情况大。这样才能发挥greedy algorithm的优势。在真正随机建立起来的小世界网络中,它的效率是很低的。因此,在随机的小世界网络中,虽然真正的平均距离很小,但这毫无用处,因为我们根本找不到路径。

也许人类社会就是这样一种情况,也许还不够optimal。这是一个根本问题,要搞清楚它很不容易。

说到这里,我给仍然待字闺中,准备送出玻璃樽的女孩子们一个建议。我相信你们心目中肯定都对理想郎君有了很明确的标准。比如说,如果你们想要找帅哥,你们不妨可以采用greedy algorithm,因为南大帅哥是比较多的,你们可以先把求爱信交给南大的同学,然后南大的同学一看,帅哥物理系最多阿,再把这封信交给物理系,在物理系内部,帅哥之间的联系是很密切的,大家交流一下,很容易就能推选出符合你要求的人选。

泰戈尔了解到这一点,欣然改了他的诗句:
  世界上最遥远的距离,不是有快捷路径你却不知道,
    而是有物理系同学,你却不懂他的好。

类成员函数作为 pthread_create 函数参数

花了三个工作日把原来写的一段通信守护进程代码从过程方法改到了 template class,对于 template 的使用和类的派生明白了不少道理。还有个很受启发的一点,就是 C++ 中如何使用类的成员函数作为创建线程的开始函数。
pthread_create 是 POSIX 标准下创建线程的函数,函数原型是:
int pthread_create(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *), void *arg);

在 C 中,这个函数使用很简单,只要定义一个参数和返回值均为 void * 类型的函数,使用函数名字作为参数即可。就算不完全符合,可以使用 (void *(*)(void *)) 将其强制转换为符合类型检查规格的函数指针。但是,类的非静态成员函数隐含 this 指针作为第一个参数,所以参数完全不可能转化为 void * 类型,而 C++ 的类型检查要比 C 严格许多。由于我原来写的代码是 C 风格的,自然不会出现类型不符的问题,现在将线程开始函数封装到一个模板类中,再创建线程的时候就不能满足需要了。

在试了几种转换无效之后,从网上搜到一种方法:定义线程开始函数为类的静态成员函数(static member function),这样就不隐含 this 指针了,然后将 this 指针从 pthread_create 最后一个参数传给开始函数,在函数中将 void * 类型的 this 指针强制转换为类指针。看来静态成员函数还是有些妙用的。

===================我叫分割线===================

带着我妈和我妹在北京城里转悠了几天,累得不行。主要原因在我,没有考虑到身体因素,连着玩消耗太大,再加上自己也没车没房,倒公交车和住宾馆也要走很远,费时间又费劲。我都快受不了了,别说我妈了。以后再出去旅游,坚决不会再连着转三天以上,要么紧紧张张地玩两天,要么就花时间长点儿,走走歇歇。唉,谁让咱是穷人呢,又有钱又有闲的日子还没过上呢!

今天看了下积压很久的博客订阅,同学里开始写和继续写的人越来越多了。觉得有些文章比较阴沉低迷,因为自己从大三开始心情就老是跌宕起伏,反而在面对这许多次的分别聚首时坦然一些。要不是周熹在散伙饭时候专门招我,也不会哭得那么厉害。散了散了散了吧,没有离别,怎么会有重逢呢?

还是在 Yourui 的博客上看到小恪去新疆的消息,要是当面看到他,肯定会玩笑说发配三千里伊犁充军去了。这在边关待了两年之后,再回来学积分拓扑之类的数学还能看得下去吗?都说是命运无常,旅途坎坷却能看更美风景,只是不知道那关外还是不是大漠孤烟长河落日的大西北?

刚才去吃饭,走在晚间暖暖的懒洋洋的空气中,忽然有点儿秋天的感觉。想起 7 年前爸爸送我到商丘一高上学的情景,日子可真快啊!老了,老了!

晴朗的一天

一会儿晴一会儿阴,怪怪的天气持续好几天了,不像秋冬时候的北京,几乎滴水不沾。据说南京也下了好大雨,校园里的水都要沒过膝盖了。今天跟 baosheng 聊天时候还说:在南京待了四年没发过水,我一走,发了;在南大上了四年没死过人,我一走,死了。嗨,不说这个了,晦气。反正今天天气相当的好,当然,也相当的热。

前几天在“带三个表”博客上看到推荐《流血的仕途-李斯与秦帝国》,历史小说,觉得挺有意思的。周日到第三极书局,坐在台阶上看完了,真不错,语言杂古杂今,颇为诙谐。而且对那段历史有自己的解读,有很多事情觉得像是编的又像是确有其事,让人摸不准。反正自己也不是历史研究者,不必咬文嚼字,编不编就随他去吧,我只是喜欢故事。

后天我妈和我妹来北京玩,可能要请两天假了,陪我妈逛逛北京城。她在送我去南京上学的时候才第一次出过河南,而且当时家里比较困难,我也没有主见,在报到之后就让她回去了,没有在南京好好玩玩。我妈也只有寒暑假有时间,这个时候我一般又都在家,所以很可惜没机会带她再玩。现在就不一样了,我在北京已经基本稳定下来,而且自己实习也攒了点儿钱,可以告诉我妈说,你就坐车过来吧,不用带钱了,吃住玩儿子包了 :-)。我妈辛苦了一辈子,光在电视上见过首都,现在就能凭自己的能力让她在京城转转,真的很自豪,而且让老妈看看自己工作和学习的地方,对自己的担心也会少一点儿,以后能在家的时间真的很少了。

日志 20070707

今天比较闷热,刚刚外面在下雨,貌似又停了。在床上躺了将近一天,晚上跑北航吃的晚饭,因为 Weekly Report 还没有发给 PM,所以只好到公司一趟。昨天在北航食堂办了张租借卡,50 块押金,每月 5 块租金,刷卡加收 15% 餐费,真黑。不过没办法,在外面的小馆子吃饭有诸多不便,而且少有实惠又合口味的饭馆,只能忍了。从去年开始体验到在外面吃饭的诸多不爽,我就再也没抱怨过学校食堂,还是食堂比较合适各种口味的人吃饭。当然,那些从小娇生惯养的除外。现在幻想,Google 中国有自己的食堂和名厨,那他的员工真是相当的滋润,不过饭菜能打包回家吃不?

说到北航,就提一下最近挺有印象的两个特点。一,食堂的饭卡管理人员都是“一指禅”。而且还是相当慢的“一指禅”,那个打字的速度啊,输我的名字大概花费了二十秒,真不敢想象北航居然请这些人用电脑。如果说是照顾下岗职工或者是职工家属,你起码得找点能打字的吧,这样不是浪费同学的时间吗?二,搞笑的南门交通问题。北航的南门(锦秋国际对门)每天晚 7 点关门,非常不方便同学进出,但是它又有非常人性化的一面,南门的栏杆缝隙足够像我这样的体型进出。经常看见这种景象,保安关上门以后,看着一个个同学仍然义无反顾地朝关上的大门走去,然后非常精确地侧身从栏杆缝隙中穿过,简直可以算是北航一景了。我大概都穿越过二十次以上了,哪天一定要拍张照片发到相册中去。

昨天晚上和公司同事一起喝酒,一直到十一点多,回到住处已经是凌晨了,这也是导致今天没精神的重要原因。不过倒是听了不少有趣的谈话,硬件部的老板 Simon 说:“一个男人要想成熟应该学会四条:一,喝不加佐料的纯咖啡;二,喝啤酒,而且要是黑啤酒(guiness);三,吃苦瓜;四,品尝碧螺春。”然后他自己又加了一条:抽古巴雪茄,不过他说自己还没达到这一条。公司里还流传着一条 Slog: Be the best chip company in China. 据说是 Simon 酒后的豪言。还有一个 Berkeley EECS 的实习生 Kevin,今年大二,才 19 岁,不到美国允许喝酒的年龄,但是到中国就开怀畅饮啦!然后我问他在 UCB party 很多吧,有没有喝过酒?他说,我们 EECS 的学生课业很重的,party 很少的,他大学两年只参加过一次 party。他说 Berkeley 校区北部 party 比较少一些,南部比较多些。名校还是不一样,而且 EECS 读起来也应该不容易,啥会儿我能进这样的学校啊?

又回到北京了

好些天没有更新博客了(针对我的更新频率而言),原因很简单,有更重要的事情去做 :-)。

1 号到的北京,把寄放在同学那里的被子拖到租住的公寓,请邓飞、丽君吃了顿饭。2 号到公司报到,换了个办公桌,换了个电话。寄来的包裹和录取通知书同时到达,纳闷不已,为什么北京往南京挂号需要七天而南京挂号到北京只需要三天?害得我为了一张纸折腾(中科院的录取通知书着实简陋,信封是牛皮小信封,通知书就是一张请柬大小)。我原以为是通知书的那玩意儿是入学须知,但搞不明白的是,为什么入学须知要寄给我两次?

一毕业,这同学们好久不更新的博客都重新拾起来了,反而显得我有点儿懒。这下到公司工作,晚上的时间就多了些,可能又要恢复我正常的更新速度了。

这两天工作也没干什么事,FPGA 调试还不太熟练,模拟器又改了不少,而且更新中工作不太正常,所以就随便看看代码、看看邮件列表和一些 patch。GDB 的 mailing list 里这两天挺有意思的,有个人发了一个希望把 GDB 代码用 C++ 重写的邮件,然后一群大佬说这个问题别讨论了,各持己见讨论起来会没个头的。但是某个邮件里有巨牛的一句话:“The more C++ code I see, the more convinced I get that the language should die. ”让我叹服不已,哈哈。

重装了一个 Ubuntu,当然也装上了 beryl,比原来用着更方便了。Google desktop for linux 推出了,试用了一下,挺好的,特别喜欢它的两下 ctrl 就可以弹出搜索框,这样就免得我还得用鼠标把光标定位在 Google toolbar 里去。Google desktop 的 sidebar 没有在 Linux 版本上体现出来比较遗憾,那些小工具很有意思,但其实 Linux 本身就带有很多有一些的小玩意儿,喜欢玩的能把桌面配置得很 cool 或者 cute。为 Firefox 装了一个 IE7 的主题,看起来还是蛮好的,看来 Microsoft 的 UI 工程师也不是吃干饭的。但是 wine 现在还不支持 IE7,用 ies4linux 测试版装上之后,IE7 的 UI 效果一点儿也没有,真没劲。

毕业了,大家都在干不同的事,还有人(XHO)感叹没假期了,哈哈,准备成家立业的时候已经开始了,慢慢就该习惯了。

分离的时刻

最近发生很多事,但一直没有时间和心情好好地写下来。总之呢,大部分就是一切一切的毕业记事,吃饭喝酒唱歌或者其它事情,等有空吧。

已经买好 27 日晚回家的票,昨天把电脑托运回去了,三十八公斤,四十八块六,还真不轻。基本上剩下的就只有衣服和一点儿杂物了,走的时候能比较轻松。打算 7 月 1 日回北京继续我的实习,项目经理已经发邮件催了,还告诉我说有一个伯克利的学生在暑假也会到硬件部实习,能有机会和别人交流一下也挺不错的。

学习就不说了,回来这两个月根本不知道什么叫学习,只看了几本小说和历史书。21 号散伙饭,本来挺好的,被小黑招得哭得稀里哗啦的,大概数我哭得最凶了,嗓子痛了两天。酒也喝的不少,也基本吐出来了。

毕业了,散伙了,感言等等再发吧,我得好好过剩下这几天。项目经理说这是 golden days,man grows with beer and tears.

开始使用 WordPress

先引用一段著名的对话:
A: 你有博客吗?
B: 有。
A: 你介意换一个 BSP(Blog Service Provider) 吗?
B: 介意。
A: 你介意多一个 BSP 吗?
B: ......

总之呢,就是想说,在和菜头的竭力推荐下,在 GFW 的竭力阻拦下,在 Live Space 的竭力变慢下,我又在 yo2.cn 申请了一个博客。至于 yo2.cn 有什么好,请访问 http://www.hecaitou.net ,翻翻以前的文章,你就可以大致了解了。

现在算是把域名 blog.solrex.cn 绑定到了 yo2.cn 的博客上了,不是原来的域名转向,是绑定,就是所有文章什么的都可以用这个域名访问。据说这项服务以后要收费,其实收费没什么,自己申请一个空间一年还得好几百呢,还得自己配置 WP(WordPress),我也是因为懒得配置才不愿意找这个麻烦。最关键的是服务,QoS,我可不再希望自己花费了很多心血在上面的博客说被封就被封了,而且还不是我的责任,是 BSP 没有做好公关。这两年 livespace 和 blogspot 经常性的出问题已经很讨厌了,希望 yo2.cn 这个国内的博客服务商在这方面能做好一些。稍微慢一点儿没关系,发文章麻烦一点儿没关系,但别不能访问。

WP 挺好的,用起来很舒服,而且可以有很多自由度。我还把以前所有的文章都迁移到了现在的站点上,加起来有两百七十多篇吧。哈哈,两年,看来写的不少。

如果 yo2.cn 能保持现在这种服务,年费我愿意交。本想等用一段稳定了再重烧 feedburner,但昨天还是忍不住重烧了一下,所以可能使用 feedburner 订阅我的博客的就看到了今天有很多旧的更新 :)。不过这下再从 feed 中点进去到网站就不是 live space 了,留言也不用登录了,可惜的是,feedburner 教育网还是无法访问。唉,为什么在中国上个网就那么难呢?

最后重申一下,欢迎访问新博客。Live Space 和 Blogspot 仍然保持同步更新,没办法啊,我对中国小网站的风险抵抗能力还是持怀疑态度的。如果 yo2.cn 能保持一年不频繁停机、不被封站、并保持服务质量,我就放弃那两个博客。

《宽容》和《圣经的故事》

这几天读了两本房龙的书,《宽容》和《圣经的故事》。以前曾经读过他《人类的故事》,虽然写得很好,但是我一直认为这个人不了解亚洲,不了解中国。他所谓的亚洲,是南亚和西亚人的亚洲,而不是东亚、东南亚和东北亚的亚洲;他所谓的文明,也是尼罗河、希腊、两河和印度河文明,其中并不包括黄河和长江流域的文明。这对于一个以自己民族悠长绵延的文明史感到自豪的人来说,看到华夏民族在一本以"人类"名义写作的书中只占到一个非常小的角色,显然他会感到比较气愤的,进而也会对这个作者的狂妄自大感到不满。

但《宽容》这本书,由于高中教科书对其序言的引用,仍然是比较有魅力的。我很高兴自己还愿意并且读了这本书。在这本书中,作者没有显示自己的狂妄,很谦卑地述说着一些事。其实从大部分来说,这部书是讲述的宗教的不宽容,也夹杂着其它的不宽容。里面有着人类的原罪,其实可以说人类的历史就是不宽容的历史。读这本书可以让人反思许多。

在《宽容》里面对禁书的分析很有意思:荷兰的印刷商们经常派商业间谍获取意大利罗马的禁书目录,一旦得到,他们就会加紧印刷这些禁书,然后过边界线走私到被禁地区贩卖来获取暴利,而且禁书目录一般会成为下次改革的革命者的参考书目,省去了他们在浩如烟海的文献中寻找自己能利用的东西。这会使人联系到当前的一些现象,越是被禁止,可能就越流行。总之,只要人想要,就可以得到。禁制,只是增加一些资讯获取的难度,并且相反会扩大它们的影响。

我曾经浏览过一遍《圣经》(中文版),没觉得有什么意思,搞不懂为什么那么多人把它看成"唯一的书"。但是《圣经的故事》这本书还是值得一看的,没有圣经那么枯燥和理解不完的兄弟姐妹父祖儿孙的关系。不过看这本书就会更加强一种感觉,《圣经》只是一个小民族(犹太)的民族史,没有什么神圣的地方。里面的欺骗、杀戮、嫉妒、乱伦、恐吓、野蛮等等各种罪恶并不比其他的民族少,再加上《宽容》一书中对宗教不宽容的描述,基督教(天主教,新教以及乱七八糟的分支)坏事也是做绝了的。其实宗教嘛,就那么回事儿,信了,就自己骗骗自己,不信,也不用觉得多罪恶。最可恨的就是那些宗教狂热分子,不能给世界带来一点儿善,这样的人,就算是它的上帝(安拉,菩萨...)怎么可能保佑他呢?

《圣经的故事》中有一段话说得非常好:一个人的历史观会由他看的什么历史书决定。如果一个人只读本国的历史书,他绝对不可能得到客观的事实。如果一个人看过很多国家的历史,那么他就更有可能接触到事情的本质。不过这句话可能也适用于房龙自己,如果他真正了解中国和东亚的历史,就不会简单地认为雅典或者罗马就是当时世界的中心,中国只有一个学者叫做孔子;就像中国的历史学家认为长安或者元大都是世界的中心一样。傲慢与偏见是阻碍得到更高智慧的绊脚石。

收到录取通知书

今天(6 月 5 日)总算收到了中科院的录取通知书,9 月 1、2 号到中科院研究生院中关村园区报到。哈哈,第一年信息科学与工程学院都在中关村园区进行基础课学习,那就意味着我可以继续在公司兼职了,因为青年公寓到锦秋国际骑车的话也就二十分钟左右。青年公寓周围的环境我也摸得差不多了,这次过去,会很适应。

比较没谱的是寄给我通知书的时间是 5 月 31 日,我收到是 6 月 5 日,要求我在 6 月 8 日之前将档案寄送中科院。可学校给的答复是档案只能在 7 月份由机要局统一寄出,而且现在大学的档案还没有装袋,只能明天再打电话问一下那面的老师了。其实还有更没谱的,一个同学保去中科大数学系的,5 月 30 日寄给她通知书,却要求 5 月 31 日之前将档案寄去,而她 6 月 3 日才收到通知书,你说这叫什么?官僚主义还是白痴?

现在真觉得大学生活结束了,毕业典礼过了,通知书寄来了,就剩下一顿散伙饭了!!!抓紧这段时间玩玩吧~~~

毕业旅行

出去游玩了两天,今天下午六点左右回到了南大。坐在电脑前,恍若未曾离开宿舍一般,难道是无所挂碍的生活不算在真实世界的时间中?

3 号早上 6 点出发,穿上才印好的毕业衫,80 多号人,两辆车,一起离开南京前往浙江。第一天中午赶到的是神龙川风景区,其实主要是爬山啦。某些见识过高山的同学根本不屑于这种山的高度,某些比较懒的同学爬到半山腰就下去了,不过像咱这种从小就生长在平原上的土包子,曾经见到过最高的山就是紫金山,就觉得相当不错了,有山有水的,多好啊!所以呢,就高高兴兴地上上下下,山还是爬得很惬意的,虽然很累。

晚上在临安市昌化镇的一家小旅馆休息的,要说人家沿海城市真是发达呀,一个镇感觉上就能抵上俺们一个县城的规模,有点儿汗颜哈!俺们那乡镇里的医院都叫卫生院,人家那叫昌化人民医院...!

今天是到浙西大峡谷玩了一下,其实感觉上浙西大峡谷应该是新开发的景区,好玩的地方不多,爬山那一段没什么意思,是没有神龙川好玩。有意思的是在一个少数民族舞蹈风情的景点,那些跳舞的小姐会阴人。正跳着竹竿舞呢,忽然一停,就往你头上套红绸,那就得参加"婚礼",然后就得掏钱买一个绣花的小袋,很贵的,一个袋 40 块。

最开心的是漂流,虽然不长的一段,但是比较好玩,尤其是打水仗比较刺激。唉,到最后的结果是所有人的衣服裤子从内到外全部湿透,冻得哈赤哈赤的。有衣服的还好,到厕所换一下就可以了,没衣服的最惨,只能慢慢捂干。幸亏我有先见之明,还带了一套衣服。某个小白同学在我的再三叮咛下,还是听从了另一个小白的话,什么衣服都没带,结果两只小白只能穿着睡衣,套件外套坐车回来。

这里我要特别记下的一点是,徐扬扬这个没良心的家伙,打水仗时候向我们砸泥巴,害得我弄了一身沙子,连嘴里都是,xixi 也被殃及,头发上全是沙子,这笔账一定要记得!!!

唉,感觉这两天好快,因为在学校时候老被这事那事烦着,好容易能找到一个放下所有事情的机会,无忧无虑地玩一下。不过还好的是毕业旅游过后事情就不多了,虽然辅导员和管学工的党委副书记过两天都要出去招生,可能还得让我负责一些乱七八糟的统计,相比起来时间还是挺宽裕的,看看有没有机会到南京附近再玩一玩。:-)

毕业典礼

2007 年 6 月 1 号,儿童节,上午拍毕业集体照,下午开毕业典礼,至此我的大学生活正式宣告结束。

这些天忙的我可真是脚不沾地,连续七八天被别人叫醒,每天休息时间大约只有 6 个小时。尤其是今天,手机就没停响过,这个那个事,不过总算一切基本结束了,至少,剩下的事情可以慢慢办,不会因为少做某件事情而搞砸出丑。可以稍微轻松一下了!

下午的毕业典礼是我代表南大数学系 2007 届毕业生发言,居然感到了自己在这一年的变化。去年 9 月受邀参加南京师范大学数学与计算机科学学院的开学典礼,发言时因为紧张说错了不少话,出了不少丑。这一年经历了各种面试,跟许许多多陌生人打交道,在公司做 presentation,口才锻炼了不少。前两天去浦口参加交流会时第一次感觉到讲话时候的自然和顺溜,一点点都没觉得紧张和心跳加速,也博得了很多笑声和掌声。今天在毕业典礼上,预料的紧张也没有出现,反而意识到尝试控制自己的语速和感情,也没有说错话。真是好事啊,大概标志着自己更加的成熟稳健了!

前一天晚上临时赶写的发言稿被 yangyi 同学很是称赞,自己也算比较满意吧,贴在这里了。

南京大学数学系 2007 届毕业典礼发言稿

尊敬的老师,亲爱的同学们:

大家好!

初夏时节,我们迎来了这毕业的时刻。十几年寒窗聚成了脸上的欣喜,五千多个日夜凝成了眼中的笑意。悄然凝眸,记忆似雁过长空,了然无痕;蓦然回首,怀念恰风卷云舒,波澜难平。

四载寒暑,一千四百多个朝夕,我们将生命中最美丽最宝贵的一段刻在了南京大学的校园里。自少年而青年,我们在这段旅程中相遇相知;从舞象至弱冠,我们的人生在这里重叠交错。迈入南大时还是个懵懂孩童,怀着对象牙塔的无限期盼,抱着对大学生活的无尽畅想;转眼间就迈出校园,昔时的少年已纳天下经义于胸中,处大千之林而不动。在这里,在南京大学数学系,一百五十多位少年羽化成蝶,即将在我崛起中华的历史舞台上翩翩起舞,加入那美丽的乐章。

师恩没齿,难忘教导谆谆;蜡炬成灰,换得桃李天下。在这一刻,又怎能忘记带领我们在知识的天空里翱翔的恩师们?那四年间讲台上滴下的点滴汗水,记录了他们为我们付出的辛苦;那作业本上留下的只言片语,写下了他们对我们殷切的期盼;那头上渐渐显现的白发,昭示着他们为我们消逝的年华。他们在杏坛上默默地传道授业,将知识之杖传于我们,用真理之光引导我们,以智慧之念启发我们,教会我们如何做人,如何做学问。还有那为我们默默付出的辅导员和行政工作人员,在生活上、思想上帮助我们,开导我们。他们以严厉的批评修整我们旁蔓的枝条,使我们秉然正直,以百般的爱护融化我们心头的坚冰,让我们倍感温馨。我们定会记下师长们为我们所做的一切,怀着心中默默的祝福,去创造和书写属于我们,更归功于他们的历史。

慈母心怀, 点点如更漏,愿报春晖尽其有。我们坦然而幸福地站在这里,更需要记起的是我们的父亲母亲。寒窗苦读的背后,是母亲温柔的呵护;茁壮成长的身影,离不开父亲训导的支撑。我们所有的痛苦、悲伤和快乐,都会在父母的身上放大百倍。他们无私的爱,让我们能抵抗人生的各种狂风暴雨;他们深厚的情,给我们提供了一个永远安全的避风港。虽然在父母眼中我们仍然是孩子,但是在这一刻,我们要对爸爸妈妈说一句:孩子长大了,您可以歇歇了!

钟山无语,为别离悠悠凝噎;石城有思,留幽念默默心中。亲爱的兄弟姐妹们,天下无不散的筵席,但在这离别的一刻,我真的想能把这四年来的喜怒哀乐、悲欢离合打包压缩,刻录在我内心深处,使它们能耐住时间和遗忘的腐蚀,在我慢慢老去的时候,打开放在记忆角落中的它,依然能记起那些球场上飞扬的少年,那些教室中苦读的身影,那些花枝下呢喃的情侣,那些讲台上潇洒的恩师;依然能记起我们在军训场上流下的汗水,在新食堂里流下的口水,在成绩单前流下的泪水;依然能记起那熄灯后的卧谈,考试前的紧张,放假后的狂欢,开学前的想念。我愿将那温馨的一幕幕,酿成一杯杯的美酒,封存在我心中。等许多年后,拍开那历尽沧桑的封泥,定会传出更加醉人的芬芳。

各位同学,站在这里,怀着对恩师父母的感谢,对四年生活的回忆,对光辉未来的期待,我感到非常的幸福,因为我知道所有南京大学数学系2007届毕业生都伴随在我身边。雏鹰初展翅,清声傲云霄,无论身处何时何地,我相信我们07届毕业生定会以喷薄向上的雄姿,成为各自领域内的佼佼者,为我泱泱中华的崛起谱出一曲响亮的乐章。

谢谢大家!

Google 街景

Google Maps 推出了 Street View,就是在查询地点的时候,可以查看一条街的照片,然后一路走下去。感觉真是太震撼了,这样可以足不出户就把某些地方旅游一遍。不过可惜的是,Google Maps 并不支持中国市场而 Google Ditu 并不提供本类服务。

唉,最近被毕业的事情弄的好烦,老是碰上些没谱的人,做事情出力不讨好。算了算了,不说了,都是同学。

小世界

今天系里组织大四学长去浦口和学弟学妹们交流,给他们讲讲出国、保研、考研和找工作的事情。本来比较忙,没想着去参加。但是 yutian 的催促,想想以前在交流会上也受益匪浅,就想着自己也要尽点儿力,还是去了。

结果到了之后,低年级辅导员请我们去新食堂吃饭,居然在饭桌边遇到了想不到能遇到的人,01 的张振学长。在百合和博客上认识,还从来没有见过面,今天才知道,张振学长就是 04 级美女辅导员的老公。以前看张振在博客上写老婆老婆的,没想到他老婆我居然还认识,同时做为年级长还和她打过不少交道。哈哈哈哈,这世界太小了!!!

而且,Miss Tong 的男朋友随她也去了,却正好碰到一个他在计算机系的老师去蹭饭,然后他们就说,计算机系有蹭饭的传统。

总之呢,生活中经常发生你无法预料的事情,enjoy it!!!

从中科大音乐站抓MP3的一个脚本

由于南京大学的 COS 音乐 FTP 被关闭了,原来很喜欢 COS 按歌手和专辑分门别类的风格,现在就不知道到哪里去下歌了。今天发现了一个好的音乐网站:中国科学技术大学音乐站,[href: http://music2.ustc.edu.cn ],按歌手和专辑分类,在教育网内速度算是相当快的,可以在线听。我就动了心思,想把专辑自动下下来。

中科大音乐站是这样的,你先选择歌手、专辑和歌曲,点击"播放"会下载下来一个 music@ustc.m3u 文件,使用播放软件打开就可以在线播放选中的歌曲。其 music@ustc.m3u 文件中每首歌的条目如下例:

#EXTM3U 双节棍
http://music2.ustc.edu.cn:8088/6e6bbc6495aec1f5fc719dcbc826ab4c%2F64%2Ff05523485d63a9c422393215c676f194.mp3

可以看出,中科大音乐站在存储 mp3 音乐文件的时候采取了某种文件名加密方法,很难直接猜出文件名,而且在提交 form 的时候采取 post 方式,不知道它的 action 文件接受什么样的参数,所以想在这一步上减少工作量是很难的。而且从网站上拿下来这个列表并不算很麻烦,因为每个人基本只会对某些专辑感兴趣嘛。那么下面要做的工作就是自动处理这个列表,将歌曲下载下来存在应该的位置和保存为正确的文件名。

Linux Bash Shell 脚本如下:

for album in $(ls *.m3u)
do
# Test the encoding of music list file.
  encode=$(file -i $album | awk ’{print $3}’ | sed -n ’s/charset=//p’)
if [ $encode != "utf-8" ]
then
  iconv -f gbk -t utf8 $album &gt; ${album}.1
  mv ${album}.1 $album
fi
# Test if the album already exists.
if [ ! -d ${album%.*} ]
then
  mkdir -p ${album%.*}
fi
# Get the url list.
urls=(`grep -v "#" $album`)
# Download the song.
N=0
for song in $(grep "#" $album | sed -n ’s/#EXTM3U //p’ | sed ’s/ /_/g’)
do
  echo "Processing $song..."
  if [ ! -f ${album%.*}/${song}.mp3 ]
  then
    wget -O ${album%.*}/${song}.mp3 ${urls[$N]}
  fi
N=`expr $N + 1`
done
done

这个脚本所做的工作是:
1.找到当前目录下所有的以 m3u 为后缀名的专辑播放列表文件,循环处理它们。
2.检查专辑列表文件的编码方式,如果不是 utf-8 格式编码,将文件编码转换成 utf-8(为了处理歌曲文件名需要)。
3.去掉专辑列表文件后缀名 .m3u,以此为名字建立专辑目录。
4.得到专辑中歌曲的 url 列表。
5.下载歌曲到专辑目录中,并以对应的文件名命名,歌曲文件名中的空格被转化为下划线。

使用方法,先手动下载希望下载的每个专辑的播放列表(.m3u 文件),并将其文件名改为对应的专辑名,放到与脚本同一目录下,运行脚本,就会将每个专辑中的歌曲下载到以专辑名命名的目录下。

答辩通过

昨天下午论文答辩,纠缠那么久的论文,总算结束了。虽然自己仍然比较不满意,但是和某些同学比起来,我还是真真正正认认真真地写了一些东西,没有陷入欺诈之流。

说起欺诈,只能对很多人的做法无语。我不赞成这种做法,但是也能体会他们的难处。上次和 baosheng 聊天,他告诉我,他很想不通南京大学的学生为什么会在该做论文的时候天天玩游戏。在这一点上我有点儿无言以对,因为这就是我身边很多同学的生活状态。也许是大家觉得学士学位论文太不重要了,也许是他们对自己做的东西没有丝毫兴趣,也许就是从进大学后就培养出来的习惯,总之就是他们不在乎这个。我很能体谅吴朝阳老师不太愿意带本科生论文的原因,带本科生论文,只能是看着他们做的垃圾东西和垃圾效率生气又毫无办法。

不过有一点不得不值得我们思考,如果说一个两个学生这样,可能归结于个人的因素,但当这种心态成为一种群体意识的时候,就不能仅仅将责任推到学生身上了。说到底是教育制度的问题,但我觉得大学仍然可以做很多。如果老师们懂得如何激发学生学习的积极性,多几个对待学术方面严谨并且偏激的老师,造成正常的好的学术氛围,甚至多几个"愤青"同学,这个状况大概就会好很多。总之,一个好的大学,不应该现在这个样子。

=========={我是废话的分割线}==========

答辩完了,却还是有很多事情要做。大概是大家一直以来的惯性思维吧,虽然我不是毕业委员会里事务的负责人,但无论何事总会找到我,反而比自己负责更忙。不过也算是最后一次为大家服务了,也蛮愿意的。

前两天去南京的 Lonicom 做技术支持,只花了一个多小时就帮他们找到了 bug,PM 好好地表扬了我一番,这种感觉真不错。可能明天或者周末还要过去,我这个小实习生可给公司节省了不少银子啊。

今天晚上南大 Open 社团将在浦口举行本学期最后一场讲座,而且召集鼓楼 Linux User 商讨鼓楼 LUG 成立事宜。正好回去浦口怀念一下混在浦口的日子,希望能见到 baosheng, Lv, godtang, caibaiyin, dolphin9, abcx 这些朋友,可惜 snc 去不了。比较有意思的是,最近老认识 01 级的师兄,Linux 现版主 godtang 居然也是南大数学 01 级的,以前竟然没发现。