[转载]阮一峰:我为什么喜欢编程

2010年02月9日 12 views

原文链接:
http://www.ruanyifeng.com/blog/2009/10/why_i_love_programming.html

这个周末,我在家核对More Joel on Software的最后定稿。

此书已经在申请书号了,一拿到书号,就可以印刷和销售了。所以,不出意外的话,年底之前就能上架。

在复核的过程中,我又读到了书中让我最有共鸣的一段话:Joel谈为什么公正对程序员很重要。

我不知道别人的情况,我自己喜欢编程,很大的原因就是觉得程序的世界更公平公正,谁对谁错,只要运行一下代码就知道了。这同现实世界截然不同,在现实的世界中,只要你有权有钱,善于搞人际关系和钻制度的空子,你就能把错的说成对的,把黑的说成白的。老老实实、埋头苦干的人,眼睁睁看着乾坤颠倒、小人得志,而只能束手无策、一筹莫展。

我们生活的这个国家,是一个禁止自由思考、党决定一切的国家。在这里,如果你想不撒谎、不干坏事、并且被公正地对待,那么可能你只能去编程了。

==================

不搞政治

作者:Joel Spolsky

译者:阮一峰

老实说,只要有两个以上的人待在一起,就会有政治。这很自然。我说“不搞政治”的真正的意思是“不搞恶性的政治”。程序员早就练出了对公正有非常良好的判断力。代码要么能运行,要么不能。坐在那里争论代码是否有问题,这是毫无意义的,因为你可以运行代码,答案自然就有了。代码的世界是非常公正的,也是非常严格有序的。许许多多的人选择编程,首要的原因就是,他们宁愿将自己的时间花在一个公平有序的地方,一个严格的能者上庸者下的地方,一个只要你是对的就能赢得任何争论的地方。

如果你要吸引程序员,你就必须去创造出这样一个环境。当一个程序员抱怨“人际关系复杂”时,他们的意思明白无误,就是指任何个人因素超过技术因素的环境。程序员在完成手头任务时,不被允许使用最合适的编程语言,而是被命令只能使用另一种特定的语言,原因仅仅是老板喜欢这种语言;没有什么比这更让人气愤了。晋升的原因不是成果,而是人际关系;没有什么比这更让人抓狂的了。程序员被迫去做技术上落后的东西,仅仅因为上级或者得到上级支持的人坚持这样;没有什么比这更让人发火了。

没有什么比因为技术原因赢得一场由于政治原因本来要输掉的争论更让人心满意足了。当我在微软公司刚开始工作的时候,有一个正在开发中的大型项目走入了歧途,项目的代号是MacroMan,目标是创造一种图形化的宏语言。真正的程序员遇到这种语言会很有挫折感,因为图形的特性让你真地没有办法完成循环和条件判断功能。此外,对于那些非程序员的用户,这种语言也不会有很大作用,因为我觉得那些用户不会习惯算法思维,没有办法很快地理解MacroMan。当我说出对MacroMan的负面评价时,我的老板告诉我:“如果火车要出轨,没有东西能够阻挡。算了吧。”但是,我还是不放弃,一再地不断地争论。那时我刚走出学校,在微软公司中差不多跟谁都没有利害关系,所以,渐渐地,人们开始倾听我的核心观点,MacroMan后来终止开发了。我是谁并不重要,重要的是我是对的。非政治性的组织就应该这样,这种组织才会让程序员感到高兴。

总的来说,关注你的组织的社交动态变化,对创造一个健康的、令人愉悦的工作环境是很关键的,这样可以留住程序员和吸引程序员。

(完)

AT&T汇编与gcc内联汇编

2010年02月1日 35 views

在*nix阵营中,AT&T形式的汇编是更普遍的,例如gas还有gcc的内联汇编都是这种,它与我们在汇编课上熟悉Intel形式的汇编(比如,MASM支持的那些)的不同点主要在以下几方面:

1. 操作数的顺序是反的。比如movl %eax, %ebx的意思是把eax的值赋值给ebx

2. 寄存器名字前面要加%,立即操作数前面要加$。比如movl $0×1984, %eax

3. 指令加后缀b (8bit), w (16bit), l (32bit)指示操作数大小,这一条并不强制,因为汇编器基本可以根据操作数自行推断,但建议加上。比如movb %al, %bl

4. 间接寻址,用圆括号不用方括号,并且有一个很恶心的格式 imm32(base,index,scale)。例如,-4(%ebx,%eax,8)等价于Intel的[ebx+eax*8-4]

下面说GCC的内联汇编,乍一看上去很简单,只要加个asm(或者__asm__)就可以了,例如 asm(”nop”); 但是麻烦的在于让其和上下文的C代码匹配上。内联汇编的格式如下:

asm ( assembler template
    : output operands               (optional)
    : input operands                (optional)
    : list of clobbered registers   (optional)
);

后面的三个可选项就是负责指定相应的“接口”。看这样一段简单的代码,作用是把局部变量a的值赋值给b:

{
    int a=10, b;
    asm ("movl %1, %%eax; movl %%eax, %0;"
        :"=r"(b)  /* output */
        :"r"(a)       /* input */
        :"%eax"); /* clobbered register */
}

这里我们直接写类似”movl a, %eax; movl %eax, b”是不行的,因为汇编代码里不知道a和b是啥东西,所以需要在output和input这两部分指定“约束”。“约束”的格式是一个字符串后面跟一个括号里的C表达式,比如”r”(a)表示a这个变量必须放在某个寄存器中。字符串里可以包含的字符及意义:

a   eax
b   ebx
c   ecx
d   edx
S   esi
D   edi
q   eax, ebx, ecx, edx
r   eax, ebx, ecx, edx, esi, edi
m   内存
i   立即数
数字0/1...   表示引用之前出现过的

可以有多个约束,用逗号隔开。在output部分需要前面加一个等号。上面代码里%0, %1这些就是和下面output, input两部分指明的约束是对应的,最先出现的”=r”(b)对应%0,然后出现的”r”(a)对应%1。有时候我们需要在input里指明output中已经出现过的某个约束,这时候就应该用”0″, “1″这种了。另外,注意现在表示寄存器时要加两个百分号(%%eax)了。

最后的clobbered register是指明这段代码里可能会用到的寄存器,意思是告诉gcc,这些寄存器里的值可能已经让我修改了,你不能假定它们还有效。出现在input和output里的寄存器会自动被认为是clobbered的,无须再写出。

这个东西实在是很乱很难说清楚,上面说的也只是最常用的一部分内容。最后用几段典型代码展示一下:

下面这段等价于var=var+1,注意input部分的”0″的使用

asm ("incl %0" :"=a"(var):"0"(var));

下面这段是把count个字节从src拷贝到dst

asm ("cld\n
rep\n
movsb"
: /* no output */
:"S"(src), "D"(dst), "c"(count));

最后来个货真价实的,传说中的Linux内核代码中的memcpy

static inline void * __memcpy(void * to, const void * from, size_t n)
{
    int d0, d1, d2;
    __asm__ __volatile__(
      "rep ; movsl\n\t"
      "testb $2,%b4\n\t"
      "je 1f\n\t"
      "movsw\n"
      "1:\ttestb $1,%b4\n\t"
      "je 2f\n\t"
      "movsb\n"
      "2:"
      : "=&c" (d0), "=&D" (d1), "=&S" (d2)
      :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
      : "memory");
    return (to);
}

简单来说上面那段代码的意思是一开始用movsl四字节复制,等发现快到头了,再根据剩余的情况用movsw和movsb。细节不解释了,仔细分析一下还是很好玩的 :)

随便写点啥

2010年01月30日 75 views

随便写点啥,表明我还活着。前段时间这个blog很少更新,因为实在是太烦乱了,很多事情纠结成一团,让我无暇顾及其他。不过话说回来,人生又何处不纠结,连量子都是纠结的。现在事情终于少了一点,让我有空来乱写一点什么了。

过几天就要回家了,据说家里接上了宽带,但愿如此,这样在家就不会很无聊了。展望一下新的一年,大事有这么几件:
1. 希望到年底基本把毕业的事搞得差不多
2. 希望找个好工作
3. 希望ACM-ICPC区域赛天津赛区一切顺利
4. 希望南非世界杯我意卫冕

这里第2条要特别提一下,因为我已经决定不读博了。关于这个我曾经给自己列了一大堆理由出来,最后算是把自己说服了吧。那些理由我不在这里列了,其实说白了,就是越长大越现实起来了。有时候想想自己过得挺失败的,一直在追问人生的意义,一直很信服罗素的回答:对知识的渴望、对爱情的追求、对人类苦难的同情,结果却发现,在这三点上我都做得一塌糊涂。我渴望知识,但为了钱途放弃了学术;我追求爱情,但爱情像避瘟神一样离我而去;我同情苦难的同胞,并且自认为了解造成这苦难的根源,但我除了在BBS上喊几句口号发几篇随时会被删的帖子之外,什么也做不了。要承认自己的平凡渺小,真是件痛苦的事情。

接下来打算做一些实际的东西,学习一下IT民工的基本技能,最近一直在胡乱看一些书,感觉还是有些东西要及时记录下来的好,所以此后的blog更新可能就偏向工程方面一些了。其实我还是有一些看上去不切实际的想法的,看看能做到什么程度吧,呵呵。

宝贝,听我说

2010年01月7日 147 views

RoBa注:此文为转载,原出处未知。转这篇只为劝一个人,可惜我写不出这么矫情的话来。我知道关注此blog的多为技术宅,很抱歉这篇不合大家的口味了,但还要请大家祝福。

================================================

宝贝,听我说
人的一生,都会遇到这样那样的人,有人喜欢你,有人讨厌你,有你喜欢的人,有你讨厌的人。在这期间,你会遇到你喜欢的但是不喜欢你的人,你会很痛苦。可这只是过程。每个人都会遇到这样的人。相信我,你很好,不喜欢你不是你不好,而是他已经遇到他喜欢的人。借酒消愁只会愁更愁,酒只会让你头痛,烟只会让你得肺病,所以别自暴自弃,别因此厌恶自己。宝贝,虽然你老说自己是个傻瓜,可我知道你是个聪明的女子。聪明的女子,要自己爱自己。

宝贝,听我说
我知道现在的你很痛,支撑你活着的只是回忆。你的心已经是千疮百孔,每个伤口都在汩汩的流血。你总是在无人的时候掉泪,你总是在半夜翻来覆去难以入眠。上课的你会走神,走路的你会恍惚,吃饭的你会发呆。我明白,你总是在凌晨睁开眼的时候开始期待黑夜,你总是在半夜闭上眼的时候开始期待黎明。可是宝贝,你要庆幸,你还有回忆,有些人连回忆也没有。你比那些没有回忆的人要幸福,所以没有理由这样放弃自己,过一天是一天。宝贝,别为爱,失去自己。

宝贝,听我说
回忆就像美好的梦幻,是曾经发生过的美梦,它已经被遗落在昨天,就像记忆中的过家家,只是孩童时的梦一样成为过去。也许,在你念念不忘的时候,它已经被他抛在九霄云外。即使他还记得,可是也不能改变什么,一切已经回不到从前,宝贝,你要记得,昨天其实是不存在的,存在的只有今天。不存在的昨天,连回忆也是不存在的。这样说对你会很残忍,可是是事实。所以,别活在昨天,别生存在虚幻中。记住该记住的,忘记该忘记的。让昨日的回忆成为今日的点缀,不论是美好还是忧伤。

宝贝,听我说
“誓”本来就是“拆开的语言”。说白了,誓言不过是美丽的谎言。说的时候,信誓旦旦,感天动地。美丽得让你相信它真的会实现,华丽得让你沉醉在其中忘乎所以。宝贝,别在梦碎后说誓言不过是花言巧语,要相信,在说的时候他是真的在乎你,他真的是发自肺腑,背弃是因为已经不在乎你。既然已经不在乎,誓言就不再是誓言。可是宝贝,别因为这样,你就随意许下诺言。记得,做不到的事情,别轻易许诺,它可以是蜜糖也可以是利刃。宝贝,相信誓言给你的快乐,接受誓言给你的痛苦。

宝贝,听我说
人生是一场戏,总会有散场的时候。一切故事都有始有终,有开始,就有结束。只不过是,有人半路结束了,有人到终点才结束。但其实都一样,最后都是要化为人间的尘土,消失了,不见了,没有了。他,只不过是旅途上的一个伴侣,能一起到终点是幸运,但是不能一起到终点也不需要遗憾,至少曾经相遇。有些人,遇见就是为了分开,无所谓长久。聚散终有缘,能够相遇是缘分,能够相爱是奇迹。所以别感伤,陪你到终点的人不是他。

宝贝,听我说
爱你的人不会让你流泪,哪怕你不是天使,让你流泪的人不值得你爱。可是,我却看着你的眼泪一而再再而三的为他流,如果不是他,我还不知道你其实也是个爱哭的女子,只是因为以前没有遇到让你流泪的人罢了。宝贝,够了,别再为他哭了。虽然他是个值得你爱的男生,可是你们却不在同一道上,如平行线般,远远看着相交,但其实根本没有遇到。如果注定不是你的,强求也不幸福。以及纠缠,不如给爱放生。宝贝,放手吧,别再执着,让他在你心中是最美好的回忆,让你成为他最记忆中最美好的女子。

宝贝,听我说
你撕着自己不再完整的心说结束,用尽最后一丝力气道再见,你咽住了到嘴边的哭腔,你遏制住了到眼眶的泪水。知道你的痛已经到了期限,可是我无能为力。宝贝,必须这样,哪怕粉身碎骨,即使体无完肤。宝贝,你做得很好,你很坚强,你很勇敢。可是宝贝,别说你已经不敢爱,别说你已经怕爱,别说你已经没有力气去爱。以后,你会遇到另一个男生,他会很爱很爱你,你会很幸福很幸福。所以宝贝,别不相信爱。对曾经的他说谢谢,感谢爱的路上曾经有他相陪,对曾经的他说对不起,抱歉耽搁他那么多时间;对未来的他说谢谢,感谢他爱你愿意陪你,对未来的他说对不起,抱歉前半生的记忆不是他。

宝贝,听我说
喜欢不等于爱,喜欢不是爱。如果你不喜欢,别接受他人的爱;如果对方只是喜欢你不是爱你,也别接受他的喜欢。宝贝,你要记得,在这个世界上,你是独一无二的,没有人像你,你也不需要去代替谁,你也没有办法去代替谁。在你的人生舞台上,你是自己的主角,不需要去做谁的配角。宝贝,别在难过的时候接受别的男子的爱,那对他不公平,你也不会幸福,要分清楚,是喜欢还是同情或者是怜悯。可是宝贝,别如你所说的,找一个爱自己的人就好。世界上好男生很多,你会遇到喜欢你而你又喜欢他的人。所以宝贝,别放纵爱,别吝啬爱。

宝贝,听我说
看着你卷缩成一团的冰冷身躯,我很心疼;看着你紧锁的眉毛,我很难过;看着你紧闭而挂在眼帘上的泪珠,我心痛;看着你额头上的细汗,我心酸。我悄悄地拥抱你冰冷的身躯,小心地揉平你紧锁的眉毛,轻轻地拭去你眼帘上的泪珠,慢慢地擦去你额头上的细汗。可是宝贝,我无法温暖你。但是我愿意相信,你会遇到这样的男生,他的怀抱很温暖,替你挡住一切风风雨雨;他的手很烫,他会把你的手放入他温暖的掌心,从此让你不在惧怕寒冬。宝贝,好好睡觉,别再在噩梦里沉浮。一切都已经结束,别再回首。

宝贝,听我说
纵使你失去全世界,你还有我,纵使没有人喜欢你,我还是会喜欢你,我还会不离不弃地在你身边,给你依靠。爱情只是一场梦,会有结束的时候,而我一直相信,还会有比爱情更悠长的东西,好比我和你之间的感情。你要记得,哪怕全世界已经没有人当你的宝贝,你还是我的宝贝,还是我王国里的公主。所以抓住我的手,跟着我的脚步,我们要远离昨天的美梦,抛弃昨天的噩梦,我们要去寻找今天的梦。宝贝,别人放开你的手,可是我永远不会放开。所以,放心跟我走。

宝贝,听我说
虽然我只是你的影子,没有生命的影子,陪你痛跟你爱,可是你是我的宝贝。你流泪,我陪你流泪;你寂寞,我也寂寞;你痛苦,我也痛苦。可是我不要你流泪,我不要你痛苦,我不要你寂寞,所以我要带你走,我想给我的宝贝幸福快乐。宝贝,相信我。宝贝,跟我走。

宝贝,明天你会是全新的你。让我们一起期待,一起努力。宝贝,你要永远记得,你还有我。宝贝,要做个聪明的女子,做个懂爱敢爱会爱的女子,要做个拿得起也放得下的女子,让错过你的男子后悔错过你,让爱你的男子更爱你。

C++笔记: 定义,声明,头文件及其他 (Part 2)

2009年12月19日 124 views

2. 变量

这里主要是讨论全局变量的使用,对于局部变量(即在函数内部定义的,在栈上分配空间的变量)不予考虑。全局变量的情况与前一篇说的函数的情况类似,但是更迷惑人一些。全局变量的定义是在所有函数的外面,比如下面语句:

  int roba;

定义了一个叫做roba的int型全局变量。而全局变量的声明是这样:

  extern int roba;

全局变量与函数一样要求,定义只能一次,声明可以多次,在使用前编译器必须看到声明。如果多个源文件要共享一个全局变量,初学者常犯的错误有两种:一种是在多个文件中都写了int roba;,这样会导致链接时发生重复定义的错误;另一种是只在一个文件中写了int roba;,以为在其他的文件的文件中可以直接用,但实际上因为在其他文件中没有对这个全局变量的声明,所以会发生编译错误。正确的写法是,在某一个文件中用int roba的形式定义,而在其他用到该变量的文件中用extern int roba的形式声明。

如果要把变量放到头文件里,从前面的讨论可以看出,一定不要把int roba;这样的定义放进去(因为这样的话如果这个头文件被包括进多个cpp文件就会产生重复定义),而应该写extern int roba;这样的声明,然后在某个cpp文件中定义int roba; 。

与函数类似,如果我们不想其他的文件看到某个全局变量,也可以用static修饰它,表示它的作用域局部于此文件内。(注意我说的不是static的局部变量)

下面又开始说特例了。对于这种写法:

  extern int roba = 1;

是被当作定义而不是声明的,尽管加了一个extern。

另外一个要注意的是const型的全局对象,它默认是局部于文件的,也就是说默认就是static的。这是因为C++允许(并且鼓励)这样的写法:

  const int N = 100;
  int loli[N];

我们可以看出,编译器必须知道N的值以后,才能确定loli数组的大小并生成相应代码。所以如果像非const的全局变量一样,把const int N定义在别的文件里,编译器就没办法在编译时知道它的值,也就不能单独编译这个cpp文件,这就违反了上次说的那个要求。基于这个考虑,C++规定const全局对象是局部于文件的,也就是说我们可以安全地把 const int N = 100; 这样的东西放在头文件里,不会出现重定义。

我们也可以用extern const int N = 100;这样的写法强制使其全局可见,在其他的文件中用extern const int N;来进行声明,但我认为这样会产生不必要的混乱,对程序效率也并没有提升。可能有人会觉得如果在每个文件里声明一个局部于本文件的全局const对象会浪费空间,但实际上编译器基本都会把这个const优化掉的,产生的效果和古老的 #define N 100 宏定义是一样的。

(待续)

C++笔记: 定义,声明,头文件及其他 (Part 1)

2009年12月19日 144 views

最近看了很多IT民工相关的东西,感觉还是应该记录一下,不然很快就忘了。下面这些都是比较简单的内容,但是我之前并不是十分清楚,请路过大牛多多指点。

首先必须区分各种对象(这里的“对象”是一个广义的说法,它包括变量、函数、类等等东西)的定义(definition)和声明(declarition)。下面来分如下几种主要情况讨论:

1. 函数

我觉得这是一种最容易理解的情况。函数的声明就是函数原型,函数的定义就是函数的具体实现。编译器在遇到一个函数调用语句时,必须知道这个函数的原型以进行相应的类型检查,因此必须把该函数的声明(当然定义也可以,因为在此时定义隐含了声明)放在前面。

只要是比ACM题目那种一百行左右代码再大一点的项目,一般都不会把所有代码写在一个文件里。注意编译器的执行过程是分两步的,首先把每个.cpp文件(或者.c, .cc等等)分别编译成目标文件(通常是.o, .obj等等),然后再用链接器把目标文件组装成一个可执行文件。注意“分别”两字,也就是说,编译器必须能够不依赖其他cpp文件就可以把当前的cpp文件编译成目标文件。

我们先不考虑类等等内容,假设现在我实现了一系列逻辑上有一定关联的工具函数,为了清楚起见我把它们放在同一个util.cpp文件里,而把使用这些工具函数的其他代码放在文件main.cpp里,那么要编译main.cpp,必须知道里面用到的工具函数的原型,所以必须在main.cpp里有一份该函数的声明(只需要声明就够了,编译器可以据此生成压栈、取返回值等等汇编代码,至于函数内部的实现代码是在util.o目标文件里,等链接的时候组装在一起就可以)

然而,当有多个cpp文件都要用到这些工具函数时,如果我们每次都要在cpp文件前面附加一堆函数声明的话,就显得有点太啰嗦了。于是头文件就派上用场了。这时惯常的做法是把util里(想提供给外界使用的)函数的声明放在.h头文件里,如果另外的cpp文件要用到某个函数,只要把对应的头文件include进来即可。注意一定不要把函数的定义放在头文件里,否则的话,如果这个头文件被包含进多个cpp文件里,在链接时就会出现函数重定义的错误。也就是说,函数可以声明多次,但只能定义一次(有一个例外下面会提到)。

另外一点是,如果不想某个文件里的函数被外面看到,应该用static修饰。应该只开放那些想公开的函数,并把想公开的函数的声明放到对应的头文件里。

这里再插一句,头文件只是为了方便程序员,编译器是看不到头文件的,把include的文件插入到相应的位置之类的事情都是预处理器完成的。头文件不必有对应的.cpp文件,不必是.h扩展名,实际上它可以是随便什么东西,只要你愿意就好,编译器根本不care。

关于头文件还有一点,如果我们不小心的话,经常会出现同一份头文件被包含了多次的情况(有时候可能是不可避免的)。比如我自己写了一个roba.h,里面有一句#include <string>,又写了一个main.h,里面即include了roba.h,又include了<string>,这样string就被包含了两次。这样就有可能出现重复定义(因为头文件里不止有函数声明,还有比如类的定义),这时我们可以用#ifndef这个东西控制这个头文件的内容只被包含一次。常见写法如下:

  #ifndef _ROBA_H_
  #define _ROBA_H_
  //...
  //the body of roba.h
  //...
  #endif

最后再说一下inline函数,这是一个特例,inline函数的定义应该写在头文件里。因为编译器要内联这个函数,就必须知道函数的实现,不然的话是无法单独编译出一个目标文件的。对inline函数不必担心重定义的问题,它可以看作局部于所在的源文件的。

样本方差为什么是除以n-1

2009年10月10日 757 views

不要bs……话说这个问题从中学开始就困扰着我,可是课本上通常都是语焉不详一笔带过,似乎是很显然的样子,搞得我一度无限怀疑自己的智商。最近仔细看了看书,整理了一下思路,终于把它推倒了。赶紧记下来,请各位过路的大牛指教。

下面的推倒过程需要两个结论,在这里不加证明了,基本上概率书上都有。(1)对于任意两个随机变量X,Y都有 E(X+Y) = E(X) + E(Y),和的期望等于期望的和 (2) V(X) = E(X^2) – E(X)^2,方差等于平方的期望减去期望的平方。(3)若X,Y独立,有V(X+Y) = V(X) + V(Y)。另外还有E(aX+b) = aE(X) + b, V(aX+b) = a^2*V(X)

从头来说,有这么个随机变量X,我们不知道它的分布,但是我们可以获得很多个满足同样分布的样本Xi,现在我们要从这些样本里估计这个随机分布的一些信息,比如它的均值(所谓总体均值)和方差(所谓总体方差)。当然我们想让我们的估计尽可能地准确,判断准确与否的一个标准(不是唯一标准)就是看它是不是“无偏估计”(unbiased estimation),所谓无偏估计就是说这个估计的期望值(每个样本都是一个随机变量,估计值是由这样样本算出来的,所以也是个随机变量,也有期望方差等等概念)就是真实值。

比如最简单的,样本均值 \bar{X_n} = \frac{1}{n} \sum_{i=1}^n X_i 就是一个无偏估计,因为我们可以证明E(\bar{X_n}) = \mu:

E(\bar{X_n}) = E(\frac{1}{n} \sum_{i=1}^n X_i) = \frac{1}{n} E(\sum_{i=1}^n X_i) = \frac{1}{n} n E(X_i) = \mu

这里第三个等号用到了结论(1)。

这个样本均值比较自然而符合直观,加起来一除自然是平均值。但下面不太符合直观的来了,样本方差S_n^2的无偏估计是

S_n^2 = \frac{1}{n-1} \sum_{i=1}^n (X_i - \bar{X_n})

这里的\bar{X_n}就是上面那个样本均值。这里就比较别扭了,因为感觉上应该是除以n才对,怎么会冒出一个n-1来?但是下面我们可以证明 E(S_n^2) = \sigma^2 .

推倒前还需要一个东西,\bar{X_n}的方差:
V(\bar{X_n}) = V(\frac{1}{n} \sum_{i=1}^n X_i) = \frac{1}{n^2} nV(X_i) = \frac{\sigma^2}{n}

下面可以开始了:

E(S_n^2) = E(\frac{1}{n-1} \sum_{i=1}^{n} (X_i - \bar{X_n})^2) = \frac{1}{n-1} E(\sum_{i=1}^n (X_i^2 - 2X_i\bar{X_n} + \bar{X_n}^2) )

这里后面那个E分成了三部分,第一部分

E(\sum_{i=1}^n X_i^2) = nE(X_i^2) = n(V(X) + E(X)^2) = n(\sigma^2 + \mu^2)

这里第二个等号利用结论(2)

关于第二部分和第三部分,实际上有

E(\sum_{i=1}^n X_i \bar{X_n}) = E(\sum_{i=1}^n \bar{X_n}^2) = nE(\bar{X_n}^2)

这个只要把\bar{X_n}代入展开就可以发现,所以后面两项就只剩下了  -nE(\bar{X_n}^2) ,而

E(\bar{X_n}^2) = V(\bar{X_n}) + E(\bar{X_n})^2 = \frac{\sigma^2}{n} + \mu^2

代入起来就有  E(S_n^2) = \frac{1}{n-1} (n(\sigma^2 + \mu^2) - (\sigma^2 + n\mu^2)) = \sigma^2 。故得证。

最后说一句,“无偏”不是必须的,比如我们就除以n了:S’ = (X1+X2+…+Xn)/n,可以发现当n趋于无穷时,这个S’和前面的样本方差是无限趋近的,这样的结果实际上也是不错的。

我的爱与不爱

2009年10月1日 318 views

值此普天同庆之际,我越发对自己的智商感到怀疑。我感觉自己陷入了混乱的概念中,我只知道我喜欢一些东西,讨厌另一些东西,但这两类东西似乎被有意无意地用同一套词汇来表示。不得已,只好举例说明,我爱的是什么,我不爱的是什么,希望各位同学帮我澄清一下概念。

我爱黑眼睛黄皮肤;我爱方块字;我爱宫保鸡丁和鱼香肉丝;我爱春节的鞭炮、端午的粽子、中秋的月饼;我爱华北平原的麦田;我爱村东头那个大水坑;我爱爸爸的皱纹和妈妈的白发;我爱漂亮女生;我爱我的朋友们的笑容。

我不爱晚清政府;我不爱焚书坑儒;我不爱革命和饿殍;我不爱那个德国人YY出来的理论;我不爱六十年前的承诺仍然遥遥无期;我不爱城乡分算的基尼系数;我不爱震成废墟的小学教室;我不爱情绪稳定;我不爱不明真相;我不爱我到服务器的连接被重置;我不爱我的部分搜索结果无法显示。

孙中山的国是大清么?甘地的国是不列颠么?我的国呢?

THEY ARE AFRAID

2009年09月1日 223 views
http://www.yeeyan.com/articles/view/66583/55110

1970年因受查禁而转入地下的捷克摇滚乐队宇宙塑料人(The Plastic People of the Universe)的这首歌中写到:他们害怕老人的记忆,他们害怕年少者的天真,他们害怕坟墓和墓上的鲜花,他们害怕……那么我们到底为什么要怕他们?

他们害怕老人的记忆

他们害怕年轻人的思想和理想

他们害怕葬礼,和墓上的鲜花

他们害怕工人,害怕教堂,害怕党员,害怕所有的快乐时光

他们害怕艺术,他们害怕艺术

他们害怕语言这沟通的桥梁

他们害怕剧院

他们害怕电影,害怕帕索里尼*,害怕戈达尔*

他们害怕画家,害怕音乐家,害怕石块和雕塑家

他们害怕

他们害怕电台

他们害怕技术,害怕信息自由流动

害怕《巴黎竞赛画报》,害怕电传,害怕古登堡*,害怕施乐

害怕国际商业机器公司,害怕所有的波长

他们害怕电话

他们害怕

他们害怕让人民进来

他们害怕让人民出去

他们害怕左派

他们害怕右派

他们害怕苏联军队突然离去

他们害怕莫斯科的变化

他们害怕面对陌生人,害怕间谍

他们害怕反间谍

他们害怕

他们害怕自己的警察

他们害怕吉他手

他们害怕运动员,害怕奥运会

害怕奥林匹克精神

害怕圣人,害怕儿童的天真

他们害怕政治犯

他们害怕犯人的家属,害怕良知

害怕科学

他们害怕未来

他们害怕明天的早上

他们害怕明天的晚上

他们害怕明天

他们害怕未来

他们害怕电吉他,害怕电吉他

他们害怕摇滚乐

他怎么回事?连摇滚乐队都怕?连摇滚乐队都怕?

摇滚乐队比别人更遭受

政治镇压

他们害怕

他们害怕摇滚乐,害怕电吉他

害怕电吉他,害怕走在街上和在锁好门后的老人

他们害怕人们写的东西

害怕人们说的话

害怕火,害怕水,害怕风,害怕雪花纷扬

害怕爱,害怕排泄

他们害怕噪音,害怕和平,害怕沉默

害怕悲伤,害怕欢乐,害怕语言,害怕笑

害怕色情,害怕诚实和正直,他们紧张了

他们害怕孤独,害怕学习,害怕有学识的人

他们害怕人权,害怕卡尔·马克思,害怕原生力量

他们害怕社会主义

他们害怕摇滚乐

他们害怕摇滚乐

他们害怕摇滚乐

他们害怕摇滚乐

那么我们究竟为什么要怕他们?

* 帕索里尼、戈达尔都是以叛逆著称的导演,约翰·古登堡,约1400-1468,德国印刷工,欧洲第一个使用活字印刷的人

http://babellist.xnet2.com/0207/msg00029.html
A HUNDRED PER CENT - REVISITED 

They're afraid of the old for their memory.
They're afraid of the young for their ideas - ideals.
They're afraid of funerals - of flowers - of workers -
of churches - of party members - of good times.
They're afraid of art - they're afraid of art.
They're afraid of language - communication.
They're afraid of theater.
They're afraid of film - of Pasolini - of God/dard.
 of painters - of musicians - of stones and sculptors.

They're afraid.
They're afraid of radio stations.
They're afraid of technology, free float form of
information. Paris Match - Telex - Guttenburg - Xerox
- IBM - wave lengths.
They're afraid of telephones.
They're afraid.
They're afraid to let the people in.
They're afraid to let the people out.
They're afraid of the left.
They're afraid of the right.
They're afraid of the sudden departure of Soviet
troops - of change in Moscow - of facing the strange -
of spies - of counterspies.
They're afraid.
They're afraid of their own police.
They're afraid of guitar players.
They're afraid of athletes - of Olympics - of the
Olympic spirit - of saints - of the innocence of
children.
They're afraid.
They're afraid of political prisoners.
They're afraid of prisoners families - of conscience -
of science.
They're afraid of the future.
They're afraid of tomorrow's morning.
They're afraid of tomorrow's evening.
They're afraid of tomorrow.
They're afraid of the future.
They're afraid of stratocasters - of telecasters.
They're afraid of rock 'n' roll.
What does he mean, even rock bands?  Even rock bands?
Rock bands more than anybody else suffer from
political repression.
They're afraid.
They're afraid of rock 'n' roll - of telecasters - of
stratocasters - of old age - in the streets - behind
the locked doors.
They're afraid of what they've written - of what
they've said - of fire - of water - of wind - of slow
- of snow - of love - excretion.
They're afraid of noise - of peace - of silence - of
grief - of joy - of language - of laughter - of
pornography - of honest and upright - they're uptight.

They're afraid of lone and learn and learned people.
They're afraid of human rights and Karl Marx and raw
power.
They're afraid of socialism.
They're afraid of rock 'n' roll.
They're afraid of rock 'n' roll.
They're afraid of rock 'n' roll.
They're afraid of rock 'n' roll. 

AND WHY THE HELL ARE WE AFRAID OF THEM?  
 

网页中文乱码问题之不完全分析

2009年08月31日 300 views

前几天帮实验室弄个页面,遇到了中文乱码的问题,在网上找了些资料最终解决了,在这里总结一下。

GB2312 – GBK – GB18030这三者是兼容的,但它们与UTF-8编码不兼容,这就是导致乱码问题的原因。如果你发现网页乱码,需要检查的地方有如下几个:

(1)网页文件本身。假设这是一个静态html文件,不同的文本编辑器(或者不同的选项)做出的文本文件的编码可能是不同的。我这次遇到的问题就是这样,用DreamWeaver保存出来的网页文件是GB18030编码(可能是我没有注意到软件里的选项设置),但我在其它的所有地方都声明编码方式是UTF-8,于是在FireFox下就出现了乱码,不过IE居然可以很威武地正常显示。建议使用稍高级一点的文本编辑器(比如win下的UltraEdit, Editplus等等都可以)把编码方式转换一下,使其与其他地方的配置一致。

(2)Apache的配置文件。在httpd.conf这个文件里有个AddDefaultCharset,这里可以设置默认的编码方式。这个东西会在浏览器向服务器发送请求时,包含在HTTP头信息中返回给浏览器。

(3)网页的<meta>标签。一个典型的代码是这样的

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

这样就声明了网页是UTF-8的编码。

(4)网页脚本文件,如PHP里可以写

header(”content-type:text/html; charset=utf-8″)

据说这个替换掉HTTP头的信息,我没有试过,不太清楚。

因为有这么多地方可以配置,当这些地方的配置出现不一致时,问题就出来了。<meta>标签,HTTP头,页面文件本身的编码,到底谁的优先级更高,不同的浏览器是不一样的。所以常会出现在IE下可以但在FF下乱码,或者反过来的情况。总之最好是让它们都保持一致啦。

另外,还有一种情况是数据库的乱码,等以后遇到了再说。