RECORDING MY FANTASY

Sunday, September 09, 2007

要开始找工作了....

时间过的真快,转眼就九月份了。一个暑假的时间已经无影无踪了。

好像突然间,校园招聘就开始了,各大bbs上开始了火热的“广告”,什么 微软阿, 百度阿, 腾讯阿,一股脑儿全开始了。
赶紧修改修改简历,使劲往外投。

Wednesday, September 05, 2007

截取rtsp视频流的某一刻的图片

darwin流媒体服务器,来提供rtsp的视频流。
现在在某一时刻截取其rtsp流中的一帧图像,保存为想要的格式,比如bmp,jpg等等。
想来解决这个问题的方式比较简单,就是: 打开rtsp视频流;--》截取图像——》保存图像。这样一个流程而已。
涉及到的知识包括流媒体,mpeg4,rtsp协议。图像处理。

我以前也就上课的时候接触图像处理,视频编解码方面的基础知识。水平实在是有限,所以在解决这个问题的时候首先想到的就是利用现成的工具。
通过请教别人+google,知道ffmpeg可以达到这方面的要求,心里非常高兴。安装ffmpeg,按照网上所贴的参数运行:
./ffmpeg -i rtsp://192.168.2.17:554/sample_100kbit.mp4 -y -f image2 -t 0.001 test.jpg
结果没有反应。但是,ffmpeg在处理本地文件的时候可以截取出需要的图片。可以看出,问题处在了ffmpeg对rtsp的支持上。没办法,下源代码,编译,调试。发现,在libavformat/rtsp.c文件中,当程序执行到rtsp_send_cmd,开始播放的时候(这个地方记不太请了-_-!), 出现了一个奇怪的错误,系统提示: Bind: Address Already in Use
当时,用ddd调试的,有好多调试命令不会用,只用基本的调试手段。所以,没能查出最后是什么问题。google上也没找着,很是让人郁闷。

然后,只好先转向其他的视频处理的lib库了,找着一个livemedia(www.live555.com)的开源库,vlc中有它的应用。它是一个完全面向对象设计的库。我用C语言比较多,看C程序比较习惯。现在一下子开始看C++的库,很是发怵。还好,代码里面有一些testProgs,第一个就是openRTSP,它可以打开一个rtsp协议的视频流,将视频和音频分别保存。我试着用了一下,能够成功的解出视频流,并且保存为可以播放的本地文件。

看起来,livemedia的库很不错。
不过,首先得了解整个架构,参照实例程序,才有可能实现自己的东西。我google出来一篇中文的文章,利用Livemedia做二次开发的,
LiveMedia库总结
还有这个:在Livemedia的基础上开发自己的流媒体客户端 V 0.01

然后我参照openRTSP的程序,只截取RTSP流的视频部分,并且保存为一个本地文件。接着,需要完成的工作就是能够将mpeg4的一帧截取出来,保存为图片。根据我粗浅的了解,它的帧应该是yuv格式的,需要将它转换成其他格式的,比如yuv->bmp,再转其他的也不难了。现在做到这一步了,

livemedia的库中有一个类 MPEG4VideoStreamParser,它用来解析mpeg4视频流,但是我的mpeg4的知识太 有限了,好多基本概念都不是太清楚。现在还不知道怎么利用它来完成我想要的功能。
---一个想法,是不是可以实现一个新的类,继承自MPEG4VideoStreamParser,增加处理图像的功能?
试一下再说吧!

Thursday, August 30, 2007

HowToDoWhatYouLove

http://www.wanglianghome.org/cgi-bin/wiki.cgi/HowToDoWhatYouLove
上面的网页把HowToDoWhatYouLove翻译成中文了:如何才能去做喜欢的事情。我没有看过原文,只是无意中看到的文章,开始竟然一直以为是网站的作者写的,心里面佩服他竟然能写出这么深奥的东西;可是看着看着,发现提到的很多事例都像是USA的-原来是老外的文章。不管这些了,好文章总是会流传的,就像金子总会发光一样。
这篇文章适合正在求学的大学生、正要或者正在找工作的同仁们、已经工作的人们--总之,适合所有需要工作的人。

名词解释:无耻·流氓·弱智

从lqqm上看到的,特转载如下:

1、
“老师,有个问题想请教一下。”
“嗯,什么问题,说说看吧。”
“老师,您能给我们形象地解释下‘无耻’、‘流氓’和‘弱智’么?都说现在是河蟹社会,我们都看不到这些现象了呀!”
“这个嘛,很简单啦,听老师给你慢慢道来。先说说‘无耻’,嗯,比方说,希望工程希望大家都来捐资助学,你要是能有能力,会不会也参加进来呢?”
“嗯,当然啊,老师这还用问么?电视里广播里不总是说西部的孩子怎么苦怎么苦,还有好多下岗子女,给他们捐钱好歹也是一种善举吧。”
“阿弥陀佛,你们啊就是幼稚。要是你捐了这么几年之后,忽然有一天报纸揭露说:其实你的钱捐给的是副局长的女儿,她故意说自己的父母下岗又没房住,你会怎么想?”
“啊?!还有这种事?!太无耻了,这不明摆着就是欺诈么?”
“问题是事后上级领导说既然人家父母已经把钱退回来了,就不是欺诈,依然是个好公仆。”
“简直就是流氓嘛!当我们都是弱智啊!”
“Nod,你觉悟了。”

2、
“老师,您再举个例子,我还想好好体会下什么是‘无耻’、‘流氓’和‘弱智’。”
“比方说你毕业之后去外地工作,但是房价高的一年的工资只能买几平米,所以你们一般只能暂时和朋友合租一间房。虽然是鸽子笼子,但是好歹也算有张床。一年累死累活,可是人家土地局的局长一人就拥有住宅30多套,市委书记腐败就上亿,还天天说房价太低,结果双规后一查,他自己光情妇就11个。”
“MD,真是太无耻了!——不过老师,这下房价能跌了吧?”
“跌?做梦吧?政府下文了,说为了确保居者有其屋,所以即日起禁止合租房,你说房价会跌么?”
“KAO!政府是弱智吧?傻子都知道是高房价逼得人被迫合租,没事TMD谁不想自己一个人有间自己的房子啊。不让人合租房,大家就都要被轰出来,这样也能确保居者有其屋?流氓!”
“Nod,你又觉悟了。”

3、
“老师,您说,有没有谁能把‘无耻’、‘流氓’和‘弱智’集于一身啊?看起来似乎很难啊……”
“难?哎呀你还是没经历社会的磨练啊。你知道王旭明不?就是那个说‘教育就是到商店买衣服,有钱你就买好的,没钱你Y的给我滚’的那位。”
“哦,我知道了,那个人总说无耻的话啊。而且太流氓了,居然恬不知耻说什么‘保护我要像保护大熊猫一样’,呸!难怪中国教育界那么烂!——只是老师,人家好歹也算是学者型的官员,弱智似乎还联系不上他吧?”
“怎么会联系不上呢?还记得刚才我给你说的那个欺诈捐资助学者的事情吧?捐款人很不高兴的一点,就是觉得受捐助人一点表现感谢的意思都没有。因此王旭明那个IBM说了:‘这正说明了国家资助困难学生的政策效果是最好的。’”
“老师,您糊涂了吧?这之间有必然的联系么?我咋没听懂。”
“你没听懂?再好好想想,这两件事之间的联系……”
“老师,我确实没搞清楚,被资助学生不感恩,怎么会说明国家资助困难学生政策好?这里面压根没有一点逻辑啊……”
“所以说啊,王旭明就是中国头号大弱智。”

Tuesday, August 21, 2007

ubuntu X程序看着还可以的字体设置

在ubuntu上的比较老的X程序(采用lesstif等)如ddd,字体都太难看;
而同样的程序在fedora/CentOS上的字体就大小合适而且字体很漂亮。我一直想把我的ubuntu7.04的X字体显示给改的像在fedora上一样,可是总是改不好。

今天晚上用xfontsel程序尝试了几种X字体,觉得
-lucida-lucidasans typewriter-book-r-*-*-*-*-*-*-*-*-*-*
还可以。

我现在的桌面字体就是用的lucida sans typewriter 9号字体,然后把屏幕(最大分辨率1280*1024)的分辨率给调整到了1152x864,看着还算舒服。

ddd的显示效果


现在还有缺陷的地方就是菜单选项下面远远的有几个underline....不知道是怎么搞的-_-!

Thursday, August 02, 2007

今天开始用folders.live.com的live folders服务

我是用@live.com的帐号登录的,登录后发现windows live folders提供了500MB的存储空间。按权限分成了personal folders, shared folders, public folders三个大区;personal又分成了documents,music和pictures这三部分。感觉这个分类方式还是挺合理的,不过就是空间太小了。500MB的空间存些文档还差不多,至于music和pictures放在里面就太难了XD

Thursday, July 19, 2007

人中吕布!马中赤兔!猪中广沪

人中吕布!马中赤兔!猪中广沪
-----纪念07月18日的国足比赛。

Monday, July 16, 2007

这是真的

有个村庄的小康之家的女孩子,生得美,有许多人来做媒,但都没有说成。那年她不过十五六岁吧,是春天的晚上,她立在后门口,手扶着桃树。她记得她穿的是一件月白的衫子。对门住的年青人,同她见过面,可是从来没有打过招呼的,他走了过来,离得不远,站定了,轻轻地说了一声:“噢,你也在这里吗?”她没有说什么,他也没有再说什么,站了一会,各自走开了。   就这样就完了。
  后来这女人被亲眷拐了,卖到他乡外县去作妾,又几次三番地被转卖,经过无数的惊险的风波,老了的时候她还记得从前那一回事,常常说起,在那春天的晚上,在后门口的桃树下,那个青年。
  于千万人之中,遇见你所要遇见的人,于千万年之中,时间的无涯的荒野里,没有早一步,也没有晚一步,刚巧赶上了,那也没有别的话可说,惟有轻轻地问一声:“噢,你也在这里吗?”

Monday, July 02, 2007

第一次见这样的joke: 中国职工工资总额和平均工资连续四年两位数增长

中新社7月1日电 记者今天从中国劳动学会主办的“深化企业薪酬制度改革促进构建和谐社会”论坛上获悉,中国职工工资总额和职工平均工资连续四年实现两位数增长,并分别超过同期国内生产总值、人均国内生产总值的增长速度,为改革开放以来职工工资水平增长最快时期。

据悉,2002年,中国在岗职工工资总额为13161亿元,到2006年达到23439亿元,扣除价格上涨因素,年均递增13.5%,比同期国内生产总值年均递增10.3%,高3.2个百分点,是1998年到2002年全国在岗职工工资总额年均增长速度的1.9倍。

2002年,中国在岗职工平均工资为12422元,到2006年达到21001元,扣除价格上涨因素,年均递增12%,比同期人均国内生产总值年均递增9.2%,高2.8个百分点,是改革开放以来中国职工实际工资收入水平增长最快的时期。

--------
俺就只转一下新闻,不发表什么评论的.俺的评论一向是无力的,俺就不说了.
看一下网易上的评论吧,哈哈
---
张家有财一千万,九个邻居穷光蛋,平均起来算一算,个个都是张百万!!!!!!!!!!!!


广西日*报南宁讯:2007年7月2日一大早,记者路过南宁市一桥,发现大桥已经严重交通堵塞,车辆跟本无法通行。因为桥上早已站满了人,这些人不断的往河里抛洒RMB,记者怀着好奇的心理上前询问一位民工模样的大叔“大叔,您把这钱就这样丢到河里,您不可惜吗?”“不可惜,我们民工这两年得到国家的扶持,现在讨薪成功率比以前高多了,到手的钱也多了,今天出来洒点钱敬敬河神”。记者慢慢移动,发现地上,河面上飘满了RMB,红通通的一片,煞是喜人。几个乞丐懒散的在路上边走边拣钱,但基本上50以下面值的都视而不见。记者不禁发出感概:“啊,我们的祖国多么富裕!我们生活在这样的时代是多么幸福。”



今天你信了吗?


人活在中国,不能如此无耻到这种地步啊!!!!!!



不知山西黑煤窑的工人的工资涨了没有

Sunday, June 10, 2007

谢国忠:竞争是进步之源

一部名为“300”(中文名“斯巴达三百勇士”)的电影正迅速席卷全球票房。影评家对这部电影嗤之以鼻,却丝毫不妨碍观众的热情。我既不是影评人,也不是电影专家,我想说的是,电影和真实的历史存在很大差距。
竞争有时会造成浪费、混乱甚至不道德,但没有竞争,结局就是停滞

【网络稿专栏】一部名为“300”(中文名“斯巴达三百勇士”)的电影正迅速席卷全球票房。影评家对这部电影嗤之以鼻,却丝毫不妨碍观众的热情。我既不是影评人,也不是电影专家,我想说的是,电影和真实的历史存在很大差距。

故事发生在公元前480年秋天,那是第二次希波战争中的一场战役。雅典和斯巴达是希腊诸城邦中抵抗波斯的主要力量,但希腊人并不团结。斯巴达国王列奥尼达(Leonidas)和他手下的300勇士,带领着5000名希腊士兵,试图将波斯军队阻击在温泉关(Thermopylae)。该地区有利的地形使希腊人可扼守一条狭窄的通道,令波斯国王薛西斯(Xerxes)军队的人数优势难以发挥。9月17日,波斯人发动第一次进攻,被希腊人打退。18日,薛西斯发现了另一条道路,可以绕过希腊部队把守的要冲。当希腊士兵意识到他们已被包围时,多数都开了小差。列奥尼达和他的斯巴达勇士留了下来,战斗至最后一人。本来,这场战斗在整个战争中无关大局,但斯巴达人用它来宣扬自身的英勇精神,后来更成为欧洲反抗外族入侵的一个英雄主义神话。

温泉关战役之后,薛西斯虽然一度占领雅典,但却在一次失败的海战后,留下十万大军,自己回了波斯,并最终于次年输掉了整场战争。无疑,如果不是犯下致命错误,波斯人当时完全可能征服希腊。即使在失败后,波斯仍有能力卷土重来,直到希腊屈服为止。

但是,波斯发现这么做在经济上并不合算,转而采取一种“势力均衡”政策,让雅典和斯巴达两个城邦互相牵制,其中任何一个都不能强大到对波斯帝国构成威胁。这一政策行之有效长达150年,直到马其顿王国兴起并征服希腊、消灭波斯为止。

中希对比
如果当时波斯征服了希腊,历史就会完全改写,因为希腊人将失去发展数学、科学和哲学的机遇,而这些成就奠定了现代科学的基础。本文的主要目的,就是要说明社会经济发展中文化与机遇的重要性。需要注意的是,古希腊和古代中东、印度、中国的社会有一个明显区别,即古希腊从没有形成一个统一的政治实体,而是由众多城邦组成。

公元前5到6世纪,希腊和中国之间存在某种相似之处。希腊城邦为了经济利益不断发生战争,特别是在雅典和斯巴达两强之间。中国则处在战国时代,诸侯间也是战火不断。到公元前4世纪后半叶,马其顿从希腊外围崛起,成为希腊世界的霸主;一个世纪后,罗马人摧毁了希腊城邦体系,将希腊纳入罗马帝国体系。而秦也是从诸侯的外围崛起,百年后灭六国,建立了秦朝。

希腊与中国的知识分子亦有许多相似之处。连绵的战火促使知识分子去思考人类的行为,并勾画出他们心目中理想的人类社会。“百花齐放”恰如其分地形容了当时的知识状况。不过,希腊人和中国人得出的结论却大相径庭。中国朝着和谐的思想演进,认为应通过避免矛盾实现美好的社会,人们彼此应当以“礼”相待。通向和谐的道路是“中庸”,所有人都试图成为中间派——在极端的情况下,人们会变得毫无区别。这些思想都成为统治中国长达两千年的儒家学说的一部分。

但希腊人却迥然不同,他们接受了英雄主义。成为英雄并不需要什么道德目标,只要取得胜利就行。例如,希腊世界最受欢迎的人是奥林匹克冠军。荷马史诗《伊利亚特》和《奥德赛》深刻地塑造了希腊的这种精神。就是这种执著,驱使着列奥尼达在无法取胜的战斗中战死。在他看来,证明斯巴达人的勇武,比他的生命更加重要。英雄主义还影响了希腊社会的组织方式。失败者必须服从胜利者,一个失败者最坏的结局就是成为奴隶。在希腊,战争中胜利的一方通常把对方的人口卖为奴隶。这样,奴隶制逐渐成为最重要的经济制度。这种制度要求对非奴隶人口的权利作出界定。由此也产生了作为奴役状态对立面的“自由”概念。

自由人或公民的组织方式存在更多的可能性。斯巴达在战争时期有两个国王,本质上就是军事统帅,公民可以起诉国王。雅典采用的是直接民主制,在公民大会的讲台上,每个人都有权发言。忽略这些具体的差异,希腊社会更重视发挥成文契约或者说宪法的作用,这明晰了公民的权利和义务。相反,中国社会希望在权利和义务的模糊界定下进行统治。希腊城邦会各自组织运动队,并互相展开竞赛。这留给后世的影响远比奥林匹克运动会为多。

从现在的观点看,希腊社会的组织原则并没有多少吸引力。不断地竞争使人们的生命变得危险、野蛮而短促。中国的方式反而会带来和平与繁荣。但是,竞争虽然在短期内造成混乱,却会成为促使人们进步的力量。古希腊社会随着时间的发展,取得了巨大的进步。城邦间竞争达到均衡的一个显著后果,就是希腊军事的发达。

政治与军事斗争的另一个结果,是给思想自由提供了更大的空间。在竞争的环境下,没有一个权威强大到可以使人们接受一种思想,并镇压那些新的思想。在古希腊,思想也变成了一种竞技体育。学者总是希望胜过别人,证明过去的理论是错误的。这和中国恰恰相反,中国人总是喜欢引用古人说的话来作为自己观点的佐证。思想的竞争最终引导人们发现普遍的真理,这可能是人类思维进程中最大的突破。因为很多人都喜欢用例证法来说明一个观点,但是一个例子中的条件可能与另一个完全不同。普遍真理的一个例子就是毕达格拉斯定理(勾股定理)。两千年后的今天,我们仍然不能给欧几里德的《几何原本》挑出任何错误。柏拉图提倡人生的意义在于发现真理,而希腊的科学奠定了现代科学兴起的基础。

竞争文化
我认为,古代希腊和中国最大的差异就在于对待竞争的态度。礼、中庸、和谐这些概念反映出中国人是多么希望避免竞争。中国人总是盼望一个稳定的、没有变化的社会。但希腊人崇尚竞争,在胜利的荣耀中找寻生命的价值。就在孔子去世那年,希腊打赢了反抗波斯的战争。胜利让希腊人相信,他们的生活方式是优越的。这种自信在希腊的竞争文化中延续。

理性思维的兴起实际上发生在希腊的少数人当中。苏格拉底、柏拉图和亚里士多德这些知识精英对大众并没有很大的影响力,荷马的作品比他们奇特的哲学更为人们所熟知。多数希腊人都依照传统生活,并时刻对其他城邦保持警惕。这些知识精英的思想经常被大众认为是危险的。公元前399年,民主制的雅典判处苏格拉底死刑,罪名是“不尊敬城邦所敬奉的诸神而且还引进了新的神”,以及“败坏青年”。这个例子很好地说明了希腊的知识精英在大众中是多么不受欢迎。

尽管理性思维并不为多数希腊人所接受,但希腊社会的竞争性包容了这一少数派的兴起。而他们的思想最终改变了世界。在一个等级森严的社会,统治阶层会阻止人们为自己而思考,他们也能阻止人们思考。长期来看,社会发展所依赖的创新常常来自少数人。所以,容许思想自由的社会才能长盛不衰。

我认为,希腊学术思想的缜密来自于他们的辩论文化。任何人想要成功,都必须有能力通过讲演和辩论说服他的同胞。这种竞争促进了修辞的发展,并使论证过程更加合理。希腊世界的领袖都是演说家。当代西方沿袭了这一传统。给人留下深刻印象的领导人首先都是演说家,比如丘吉尔、撒切尔夫人和克林顿。这同中国恰恰相反,因为中国的决策都是在统治机构内部形成的。这种领导风格的差异,很大程度上也能说明中国同西方的差异。

文化可以改变,人也一样。在希腊文明的基础上,现代科学16至17世纪在西欧兴起。当时,西欧人心目中的希腊形象就如同神明一般,尽管当时的希腊仅仅是土耳其奥斯曼帝国的一小部分而已。当希腊独立战争在1821年打响时,很多西欧人都加入了战斗,包括英国诗人拜伦,他甚至死在希腊。但希腊独立后,西欧人才发现,希腊人不过是和他们一样的普通人。西欧人的失望导致了这样一种理论,即现代希腊人是斯拉夫移民的后裔。但真实的情况是,文化已经改变了。帝国统治带来的是服从的文化而不是竞争的文化。罗马帝国、拜占庭帝国和奥斯曼帝国延续两千年的统治彻底改变了希腊。

得大于失
亚当·斯密所建立的经济理论的一个基本观点,就是竞争是好的。现在看来这观点稀松平常,但在三百年前却是革命性的理论。当时,各个帝国、各种宗教、各派哲学都在为限制竞争辩护——竞争意味着混乱,并给每个人的生活带来痛苦。在工业化之前,生产力发展十分缓慢,以至于人一生都几乎察觉不到进步。如果蛋糕不能做大,竞争就变成蛋糕的再分配,这通常会带来一场负和的博弈。希腊城邦间无休止的战争就带来了巨大的破坏,导致了社会对恃强凌弱的认可,虽然这看来不道德,但却可以减少损失。在古代,帝国的兴起可以缓解竞争、减少破坏,所以在帝国建立的早期,经济通常会出现繁荣景象。

不过,尽管是在古代,生产力也还是处于增长之中。也许一代人不能觉察,但几代人之后就会显现出来。缺乏竞争的帝国最终会扼杀新思想,并使经济增长停滞。长年累月,人口的增加就会导致贫困,从而使帝国变得虚弱;在遭遇蛮族入侵时,崩溃也就无法避免。罗马帝国后期就变得极端衰弱,以至于依赖日耳曼人的保护。对于日耳曼人来说,毁灭罗马帝国实在太容易了。

现代科学与现代工业同时在西欧兴起绝非巧合。这一地区有很多独立的相互竞争的国家。有了竞争,哥伦布可以在被葡萄牙人拒绝后,从西班牙国王那里得到资助,去实现他向西航行到达印度的理想。如果当时的西欧是一个统一的帝国,他的理想就无从实现了。新大陆(行情论坛)的发现刺激了西欧的移民潮。而如果没有哥伦布的航海,或许就不会有今天的现代社会。总之,西欧的政治竞争促进了新思想的萌发。

在现代社会中,由于生产力的增长日新月异,竞争带来的成本已经远小于它潜在的效益。今天,所有成功的国家都鼓励竞争。上世纪60至70年代,很多国家都在所谓“战略性行业”推行国有化,并限制竞争。最后这被证明是低效的。多数国家在上世纪80至90年代重新推行私有化并引入竞争,使绩效大大提高。甚至冷战时期的军备竞赛都不是一场浪费。虽然按今天的价格计算,美国可能为冷战付出了10万亿美元,看上去是极大地浪费,但军事技术的竞争带来了开创性的技术,如互联网、半导体和计算机。这些技术都是从美国的国防项目中脱颖而出的,它们给民用产业带来的收益可能远超过军备竞赛的开支。

竞争同时展现了人性中最好的和最坏的一面。人们总是会受到这样那样的诱惑去限制竞争。但是,没有竞争,人类会停止改善世界的努力,这将导致更大的悲剧。有时,政治、军事和商业上的竞争看上去会造成浪费、混乱甚至不道德。但是,没有竞争,结局就是停滞。两千年前,在世界一个小小的角落里,希腊人选择了竞争的人生,不肯屈从于外来的帝国。这改变了整个世界。■
作者为摩根士丹利首席经济学家

Monday, June 04, 2007

专制的统治者可以是这样的或那样的,但他们唯一不可能成为的,就是经济学家

诺贝尔经济学奖得主弗里德曼先生曾断言:专制的统治者可以是这样的或那样的,但他们唯一不可能成为的,就是经济学家。

尽管部分经济学家认为,适度的通货膨胀有利于提高就业,但今天的人们已越来越认同:通货膨胀的真正受益者,只是政府和执政者,它们可以利用这东西有效地消除自己的财政赤字,而于人民,实质就是一种变相掠夺。也因此,欧盟和美国都严格限制政府实行通货膨胀的比率,并把物价稳定作为重要执政目标之一。

亚当·斯密说,专制国家的政府,往往乐意经营壮丽堂皇的工程,因为这些大动作对领导而言,可以“壮观瞻,邀声誉”,但“实际上的效用,是受到漠视的。”无独有偶,哈耶克也说,二战前德国和意大利的那些壮丽的公路,看上去是非凡的卓越成就,实际则是资源被误用的证明。

Monday, May 21, 2007

你应当如何学习C++(以及编程)(rev#1) By 刘未鹏

你应当如何学习C++(以及编程)(rev#1)

By 刘未鹏(pongba)

C++的罗浮宫(http://blog.csdn.net/pongba)

Javascript是世界上最受误解的语言,其实C++何尝不是。坊间流传的错误的C++学习方法一抓就是一大把。我自己在学习C++的过程中也走了许多弯路,浪费了不少时间。

为什么会存在这么多错误认识?原因主要有三个,一是C++语言的细节太多。二是一些著名的C++书籍总在(不管有意还是无意)暗示语言细节的重要性和有趣。三是现代C++的开发哲学必须用到一些犄角旮旯的语言细节(但注意,是库设计,不是日常编程)。这些共同塑造了C++社群的整体心态和哲学。

单是第一条还未必能够成气候,其它语言的细节也不少(尽管比起C++起来还是小巫见大巫),就拿javascript来说,作用域规则,名字查找,closurefor/in,这些都是细节,而且其中还有违反直觉的。但许多动态语言的程序员的理念我猜大约是学到哪用到哪罢。但C++就不一样了,学C++之人有一种类似于被暗示的潜在心态,就是一定要先把语言核心基本上吃透了才能下手写出漂亮的程序。这首先就错了。这个意识形成的原因在第二点,C++书籍。市面上的C++书籍不计其数,但有一个共同的缺点,就是讲语言细节的书太多——《C++ gotchas》,《Effective C++》,《More Effective C++》,但无可厚非的是,C++是这样一门语言:要拿它满足现代编程理念的需求,尤其是C++库开发的需求,还必须得关注语言细节,乃至于在C++中利用语言细节已经成了一门学问。比如C++模板在设计之初根本没有想到模板元编程这回事,更没想到C++模板系统是图灵完备的,这也就导致了《Modern C++ Design》和《C++ Template Metaprogramming》的惊世骇俗。这些技术的出现为什么惊世骇俗,打个比方,就好比是一块大家都认为已经熟悉无比,再无秘密可言的土地上,突然某天有人挖到原来地下还蕴藏着最丰富的石油。在这之前的C++虽然也有一些细节,但也还算容易掌握,那可是C++程序员们的happy old times,因为C++的一切都一览无余,everything is figured out。然而《Modern C++ Design》的出世告诉人们,“瞧,还有多少细节你们没有掌握啊。”于是C++程序员们久违的激情被重燃起来,奋不顾身的踏入细节的沼泽中。尤其是,模板编程将C++的细节进一步挖掘到了极致——我们干嘛关心涉及类对象的隐式转换的优先级高低?看看boost::is_base_of就可以知道有多诡异了。但最大的问题还在于,对于这些细节的关注还真有它合适的理由:我们要开发现代模板库,要开发active library,就必须动用模板编程技术,要动用模板编程技术,就必须利用语言的犄角旮旯,enable_iftype_traits,甚至连早就古井无波的C宏也在乱世中重生,看看boost::preprocessor有多诡异就知道了,连C宏的图灵完备性(预编译期的)都被挖掘出来了。为什么要做这些?好玩?标榜?都不是,开发库的实际需求。但这也正是最大的悲哀了。在boost里面因实际需求而动用语言细节最终居然能神奇的完成任务的最好教材就是boost::foreach,这个小设施对语言细节的发掘达到了惊天地泣鬼神的地步,不信你先试着自己去看看它的源代码,再看看作者介绍它的文章吧。而boost::typeof也不甘其后——C++语言里面有太多被“发现”而不是被“发明”的技术。难道最初无意设置这些语言规则的家伙们都是oracles

因为没有variadic templates,人们用宏加上缺省模板参数来实现类似效果。因为没有concepts,人们用模板加上析构函数的细节来完成类似工作。因为没有typeof,人们用模板元编程和宏加上无尽的细节来实现目标… C++开发者们的DIY精神不可谓不强。

然而,如果仅仅是因为要开发优秀的库,那么涉及这些细节都还是情有可原的,至少在C++09出现并且编译器厂商跟上之前,这些都还能说是不得已而为之。但我们广大的C++程序员呢?大众是容易被误导的,我也曾经是。以为掌握了更多的语言细节就更牛,但实际却是那些语言细节十有八九是平时编程用都用不到的。C++中众多的细节虽然在库设计者手里面有其用武之地,但普通程序员则根本无需过多关注,尤其是没有实际动机的关注一般性编码实践准则,以及基本的编程能力和基本功,乃至基本的程序设计理论以及算法设计。才是真正需要花时间掌握的东西。

学习最佳编码实践比学习C++更重要。看优秀的代码也比埋头用差劲的编码方式写垃圾代码要有效。直接、清晰、明了、KISS地表达意图比玩编码花招要重要

避免去过问任何语言细节,除非必要。这个必要是指在实际编程当中遇到问题,这样就算需要过问细节,也是最省事的,懒惰者原则嘛。一个掌握了基本的编程理念并有较强学习能力的程序员在用一门陌生的语言编程时就算拿着那本语言的圣经从索引翻起也可以编出合格的程序来。十年学会编程不是指对每门语言都得十年,那一辈子才能学几门语言哪,如果按字母顺序学的话一辈子都别指望学到Ruby;十年学习编程更不是指先把语言特性从粗到细全都吃透才敢下手编程,在实践中提高才是最重要的。

至于这种抠语言细节的哲学为何能在社群里面呈野火燎原之势,就是一个心理学的问题了。想像人们在论坛上讨论问题时,一个对语言把握很细致的人肯定能够得到更多的佩服,而由于论坛上的问题大多是小问题,所以解决实际问题的真正能力并不能得到显现,也就是说,知识型的人能够得到更多佩服,后者便成为动力和仿效的砝码。然而真正的编程能力是与语言细节没关系的,熟练运用一门语言能够帮你最佳表达你的意图,但熟练运用一门语言绝不意味着要把它的边边角角全都记住懂得一些常识,有了编程的基本直觉,遇到一些细节错误的时候再去查书,是最节省时间的办法

C++的书,Bjarne的圣经《The C++ Programming Language》是高屋建瓴的。《大规模C++程序设计》是挺务实的。《Accelerated C++》是最佳入门的。《C++ Templates》是仅作参考的。《C++ Template Metaprogramming》是精力过剩者可以玩一玩的,普通程序员碰都别碰的。《ISO.IEC C++ Standard 14882》不是拿来读的。Bjarne最近在做C++的教育,新书是绝对可以期待的。

P.S. 关于如何学习编程,g9blog上有许多精彩的文章:这里这里这里这里 实际上,我建议你去把g9老大的blog翻个底朝天 :P

P.S. 书单?我是遑于给出一个类似《C++初学者必读》这种书单的。C++的书不计其数,被公认的好书也不胜枚举。只不过有些书容易给初学者造成一种错觉,就是“学习C++就应该是这个样子的”。比如有朋友提到的《高质量C/C++编程》,这本书有价值,但不适合初学者,初学者读这样的书容易一叶障目不见泰山。实际上,正确的态度是,细节是必要的。但细节是次要的。其实学习编程我觉得应该最先学习如何用伪码表达思想呢,君不见《Introduction to Algorithm》里面的代码?《TAOCP》中的代码?哦,对了它们是自己建立的语言,但这种仅教学目的的语言的目的就是为了避免让写程序的人一开始就忘了写程序是为了完成功能以为写程序就是和语言细节作斗争了Bjarne说程序的正确性最重要,boost的编码标准里面也将正确性列在性能前面。

此外,一旦建立了正确的学习编程的理念,其实什么书(只要不是太垃圾的)都有些用处。都当成参考书,用的时候从目录或索引翻,基本就对了

再再P.S. myan老大和g9老大都给出了许多精彩的见解。我不得不再加上一个P.S。具体我就不摘录了,如果你读到这里,请务必往下看他们的评论。转载者别忘了转载他们的评论:-)

许多朋友都问我同一个问题,到底要不要学习C++。其实这个问题问得很没有意义。“学C++”和“不学C++”这个二分法是没意义的,为什么?因为这个问题很表面,甚至很浮躁。重要的不是你掌握的语言,而是你掌握的能力,借用myan老大的话,“重要的是这个磨练过程,而不是结果,要的是你粗壮的腿,而不是你身上背的那袋盐巴。”。此外学习C++的意义其实真的是醉翁之意不在酒,像C/C++这种系统级语言,在学习的过程中必须要涉及到一些底层知识,如内存管理、编译连接系统、汇编语言、硬件体系结构等等等等知识(注意,这不包括过分犄角旮旯的语言枝节)。这些东西也就是所谓的内功了(其实最最重要的内功还是长期学习所磨练出来的自学能力)。对此大嘴Joel在《Joel On Software》里面提到的漏洞抽象定律阐述得就非常漂亮。

所以,答案是,让你成为高手的并不是你掌握什么语言,精通C++未必就能让你成为高手,不精通C++也未必就能让你成为低手。我想大家都不会怀疑g9老大如果要抄起C++做一个项目的话会比大多数自认熟练C++的人要做得漂亮。所以关键的不是语言这个表层的东西,而是底下的本质矛盾。当然,不是说那就什么语言都不要学了,按照一种曹操的逻辑,“天下语言,唯imperativedeclarative耳”。C++是前者里面最复杂的一种,支持最广泛的编程范式。借用当初数学系入学大会上一个老师的话,“你数学都学了,还有什么不能学的呢?”。学语言是一个途径,如果你把它用来磨练自己,可以。如果你把它用来作为学习系统底层知识的钥匙,可以。如果你把它用来作为学习如何编写优秀的代码,如何组织大型的程序,如何进行抽象设计,可以。如果掉书袋,光啃细节,我认为不可以(除非你必须要用到细节,像boost库的coder们)。

然后再借用一下g9老大的《银弹和我们的职业》中的话:

银弹和我们的职业发展有什么相干?很简单:我们得把时间用于学习解决本质困难。新技术给高手带来方便。菜鸟们却不用指望被新技术拯救。沿用以前的比喻 一流的摄影师不会因为相机的更新换代而丢掉饭碗,反而可能借助先进技术留下传世佳作。因为摄影的本质困难,还是摄影师的艺术感觉。热门技术也就等于相机。 不停追新,学习这个框架,那个软件,好比成天钻研不同相机的说明书。而热门技术后的来龙去脉,才好比摄影技术。为什么推出这个框架?它解决了什么其它框架 不能解决的问题?它在哪里适用?它在哪里不适用?它用了什么新的设计?它改进了哪些旧的设计?Why is forever. 朋友聊天时提到Steve McConnell的《Professional Software Development》里面引了一个调查,说软件开发技术的半衰期20年。也就是说20年后我们现在知识里一半的东西过时。相当不坏。朋友打趣道: 该说20年后IT界一半的技术过时,我们学的过时技术远远超过这个比例。具体到某人,很可能5年他就废了。话虽悲观,但可见选择学习内容的重要性。学习 本质技艺(技术迟早过时,技艺却常用长新)还有一好处,就是不用看着自己心爱的技术受到挑战的时候干嚎。C/C++过时就过时了呗,只要有其它的系统编程 语言。Java倒了就倒了呗,未必我不能用.NETRuby昙花一现又如何。如果用得不爽,换到其它动态语言就是了。J2EE被废了又怎样?未必我们就 做不出分布系统了?这里还举了更多的例子

一句话,只有人是真正的银弹。职业发展的目标,就是把自己变成银弹。那时候,你就不再是人,而是人弹。

最后就以我在Bjarne的众多访谈当中摘录的一些关于如何学习C++(以及编程)的看法结束吧(没空逐段翻译了,只将其中我觉得最重要的几段译了一下,当然,其它也很重要,这些段落是在Bjarne的所有采访稿中摘抄出来的,所以强烈建议都过目一下):

I suspect that people think too little about what they want to build, too little about what would make it correct, and too much about "efficiency" and following fashions of programming style. The key questions are always: "what do I want to do?" and "how do I know that I have done if?". Strategies for testing enters into my concerns from well before I write the firat line of code, and that despite my view that you have to write code very early - rather than wait until a design is complete.

译:我感觉人们过多关注了所谓“效率”以及跟随编程风格的潮流,却严重忽视了本不该被忽视的问题,如“我究竟想要构建什么样的系统”、“怎样才能使它正确”。最关键的问题永远是“我究竟想要做什么?”和“如何才能知道我的系统是否已经完成了呢?”就拿我来说吧,我会在编写第一行代码之前就考虑测试方案,而且这还是在我关于应当早于设计完成之前就进行编码的观点的前提之下。

Obviously, C++ is very complex. Obviously, people get lost. However, most peple get lost when they get diverted into becoming language lawyers rather than getting lost when they have a clear idea of what they want to express and simply look at C++ language features to see how to express it. Once you know data absreaction, class hierarchies (object-oriented programming), and parameterization with types (generic programming) in a fairly general way, the C++ language features fall in place.

译:诚然,C++非常复杂。诚然,人们迷失其中了。然而问题是,大多数人不是因为首先对自己想要表达什么有了清晰的认识只不过在去C++语言中搜寻合适的语言特性时迷失的,相反,大多数人是在不觉成为语言律师的路上迷失在细节的丛林中的。事实是只需对数据抽象、类体系结构(OOP)以及参数化类型(GP)有一个相当一般层面的了解,C++纷繁的语言特性也就清晰起来了。

Well, I don't think I made such a trade-off. I want elegant and efficient code. Sometimes I get it. These dichotomies (between efficiency versus correctness, efficiency versus programmer time, efficiency versus high-level, et cetera.) are bogus.

I think the real problem is that "we" (that is, we software developers) are in a permanent state of emergency, grasping at straws to get our work done. We perform many minor miracles through trial and error, excessive use of brute force, and lots and lots of testing, but--so often--it's not enough.

Software developers have become adept at the difficult art of building reasonably reliable systems out of unreliable parts. The snag is that often we do not know exactly how we did it: a system just "sort of evolved" into something minimally acceptable. Personally, I prefer to know when a system will work, and why it will.

There are more useful systems developed in languages deemed awful than in languages praised for being beautiful--many more. The purpose of a programming language is to help build good systems, where "good" can be defined in many ways. My brief definition is, correct, maintainable, and adequately fast. Aesthetics matter, but first and foremost a language must be useful; it must allow real-world programmers to express real-world ideas succinctly and affordably.

I'm sure that for every programmer that dislikes C++, there is one who likes it. However, a friend of mine went to a conference where the keynote speaker asked the audience to indicate by show of hands, one, how many people disliked C++, and two, how many people had written a C++ program. There were twice as many people in the first group than the second. Expressing dislike of something you don't know is usually known as prejudice. Also, complainers are always louder and more certain than proponents--reasonable people acknowledge flaws. I think I know more about the problems with C++ than just about anyone, but I also know how to avoid them and how to use C++'s strengths.

In any case, I don't think it is true that the programming languages are so difficult to learn. For example, every first-year university biology textbook contains more details and deeper theory than even an expert-level programming-language book. Most applications involve standards, operating systems, libraries, and tools that far exceed modern programming languages in complexity. What is difficult is the appreciation of the underlying techniques and their application to real-world problems. Obviously, most current languages have many parts that are unnecessarily complex, but the degree of those complexities compared to some ideal minimum is often exaggerated.

We need relatively complex language to deal with absolutely complex problems. I note that English is arguably the largest and most complex language in the world (measured in number of words and idioms), but also one of the most successful.

C++ provides a nice, extended case study in the evolutionary approach. C compatibility has been far harder to maintain than I or anyone else expected. Part of the reason is that C has kept evolving, partially guided by people who insist that C++ compatibility is neither necessary nor good for C. Another reason-- probably even more important--is that organizations prefer interfaces that are in the C/C++ subset so that they can support both languages with a single effort. This leads to a constant pressure on users not to use the most powerful C++ features and to myths about why they should be used "carefully," "infrequently," or "by experts only." That, combined with backwards-looking teaching of C++, has led to many failures to reap the potential benefits of C++ as a high-level language with powerful abstraction mechanisms.

The question is how deeply integrated into the application those system dependencies are. I prefer the application to be designed conceptually in isolation from the underlying system, with an explicitly defined interface to "the outer world," and then integrated through a thin layer of interface code.

Had I had a chance to name the style of programming I like best, it would have been "class-oriented programming", but then I'm not particularly good at finding snappy names. The school of thought that I belong to - rooted in Simula and related design philosophies - emphasizes the role of compile-time checking and flexible (static) type systems. Reasoning about the behavior of a program has to be rooted in the (static) structure of the source code. The focus should be on guarantees, invariant, etc. which are closely tied to that static structure. This is the only way I know to effectively deal with correctness. Testing is essential but cannot be systematic and complete without a good internal program structure - simple-minded blackbox testing of any significant system is infeasible because of the exponential explosion of states.

So, I recommend people to think in terms of class invariants, exception handling guarantees, highly structured resource management, etc. I should add that I intensely dislike debugging (as ah hoc and unsystematic) and strongly prefer reasoning about source code and systematic testing.

Pros: flexibility, generality, performance, portability, good tool support, available on more platforms than any competitor except C, access to hardware and system resources, good availability of programmers and designers. Cons: complexity, sub-optimal use caused by poor teaching and myths.

Monday, May 14, 2007

ARM GNU常用汇编语言介绍 zz

ARM汇编语言源程序语句,一般由指令,伪操作,宏指令和伪指令作成.

ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令.

伪操作,是ARM汇编语言程序里的一些特殊的指令助记符,其作用主要是为完成汇编程序做各种准备工作,在源程序运行汇编程序处理,而不是在计算机运行期间有机器执行.也就是说,这些伪操作只是汇编过程中起作用,一旦汇编结束,伪操作的使命也就随之消失.

宏指令,是一段独立的程序代码,可以插在程序中,它通过伪操作来定义,宏在被使用之前必须提前定义好,宏之间可以互相调用,也可自己递归调用.通过直接书 写宏名来使用宏.并本具宏指令的格式输入输出参数.宏定义本身不产生代码,只是在调用它时把宏体插入到原程序中.宏与C语言中的子函数形参和实参的调用相 似,调用宏时通过实际的指令来 代替宏体实现相关的一段代码,但宏的调用与子程序的调用有本质的区别,既宏并不会节省程序的空间,其优点是简化程序代码,提高程序的可读性以及宏内容可以 同步修改.

伪操作,宏指令一般与编译程序有关,因此ARM汇编语言的伪操作,宏指令在不同的编译环境下有不同的编写形式和规则.

伪指令也是ARM汇编语言程序里的特殊助记符,也不在处理器运行期间由机器执行,他们在汇编时将被合适的机器指令代替成ARM或Thumb指令,从而实现真正的指令操作.

4.1 ARM GNU常用汇编伪指令介绍
1. abort
.abort: 停止汇编

.align absexpr1,absexpr2:
以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第二个表达式值表示填充的值.

2. if...else...endif
.if
.else
.endif: 支持条件预编译

3. include
.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.
4. comm
.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length. Ld连接器在连接会
为它留出空间.

5. data
.data subsection: 说明接下来的定义归属于subsection数据段.

6. equ
.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.

7. global
.global symbol: 定义一个全局符号, 通常是为ld使用.

8. ascii
.ascii "string": 定义一个字符串并为之分配空间.

9. byte
.byte expressions: 定义一个字节, 并为之分配空间.

10. short
.short expressions: 定义一个短整型, 并为之分配空间.

11. int
.int expressions: 定义一个整型,并为之分配空间.

12 long
.long expressions: 定义一个长整型, 并为之分配空间.

13 word
.word expressions: 定义一个字,并为之分配空间, 4bytes.

14. macro/endm
.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.

15. req
name .req register name: 为寄存器定义一个别名.

16. code
.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令.

17. ltorg
.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.

4.2 ARM GNU专有符号
1. @
表示注释从当前位置到行尾的字符.

2. #
注释掉一整行.

3. ;
新行分隔符.

4.3 操作码

1. NOP
nop
空操作, 相当于MOV r0, r0





2. LDR
ldr , =
相当于PC寄存器或其它寄存器的长转移.

3.ADR
adr

Tuesday, May 08, 2007

计算n的阶乘n!末尾所含有“0”的个数

声明:来自chinaunix论坛帖子http://www.chinaunix.net/jh/23/926848.html

问题描述

给定参数n(n为正整数),请计算n的阶乘n!末尾所含有0的个数。

例如,5!=120,其末尾所含有的0的个数为1;10!= 3628800,其末尾所含有的0的个数为2;20!= 2432902008176640000,其末尾所含有的0的个数为4。

计算公式

令f(x)表示正整数x末尾所含有的0的个数,则有

当n <>= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

问题分析

显然,对于阶乘这个大数,我们不可能将其结果计算出来,再统计其末尾所含有的0的个数。所以必须从其数字特征进行分析。下面我们从因式分解的角度切入分析。

我们先考虑一般的情形。对于任意一个正整数,若对其进行因式分解,那么其末尾的0必可以分解为2*5。在这里,每一个0必然和一个因子5相对应。但请注意,一个数的因式分解中因子5不一定对应着一个0,因为还需要一个因子2,才能实现其一一对应。

我们再回到原先的问题。这里先给出一个结论:

结论1: 对于n的阶乘n!,其因式分解中,如果存在一个因子5,那么它必然对应着n!末尾的一个0

下面对这个结论进行证明:

(1)当n 在 0, 5 之间时,f(n!) = 0;

(2)当n >= 5时,令n!= [5k * 5(k-1) * ... * 10 * 5] * a,其中 n = 5k + r (0 <= r <= 4),a是一个不含因子5的整数。

对于序列5k, 5(k-1), ..., 10, 5中每一个数5i(1 <= i <= k),都含有因子5,并且在区间(5(i-1),5i)(1 <= i <= k)内存在偶数,也就是说,a中存在一个因子2与5i相对应。即,这里的k个因子5与n!末尾的k个0一一对应。

我们进一步把n!表示为:n!= 5^k * k! * a(公式1),其中5^k表示5的k次方。很容易利用(1)和迭代法,得出结论1。

上面证明了n的阶乘n!末尾的0与n!的因式分解中的因子5是一一对应的。也就是说,计算n的阶乘n!末尾的0的个数,可以转换为计算其因式分解中5的个数。

令f(x)表示正整数x末尾所含有的0的个数, g(x)表示正整数x的因式分解中因子5的个数,则利用上面的的结论1和公式1有:

f(n!) = g(n!) = g(5^k * k! * a) = k + g(k!) = k + f(k!)

所以,最终的计算公式为:

当n < size="2">当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

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

这是帖子作者给出的笔记,后面有人回帖提到在柯召,孙琦的《数论讲义》上册的数论函数部分中就有。

Pot_p(n!) = [n/p] + Pot_p([n/p]!)

递归使用这个公式就可以得到 Pot_p(n!) 的表达式。

Thursday, May 03, 2007

恭王府花园半日游

好久之前就听好多同学说“恭王府”不错,很值得去一次,可惜一直没有时间去。转眼5.1到了,7天的假期要好好珍惜。因为,假期过后,就得抓紧时间作毕设了,7月份要中期检查,还要在这之前完成自己的小论文....。赶紧趁5.1难得的假期出去玩一趟吧。^_^
昨天是5月2号,天上飘着些白云,偶尔会遮住太阳。虽然夏天来了,天气越来越热,但昨天的温度还可以,并不是像今天这样热的变态。
我和3个同学一起去的,考虑到恭王府离北航并不是很远(810大概20多分钟的路程),而且起床比较晚,起来的时候都10点了,干脆我们就先去食堂吃了午饭,从超市买了几瓶水就出发了。
恭王府和什刹海离的很近,它们在北海北门的地方分道扬镳,恭王府在西边,什刹海在东边。可能是中午好多旅游团都休息的原因吧,中午到恭王府的路上人还好,不是非常多。路边的小店到处在兜售《和珅密传》和仿制的福字,不过看上去这门生意不是很好做。
今天在维基百科和google上查了一下恭王府,才知道现在开放的只是恭王府很小的一部分-恭王府花园。虽然恭王府花园很小,但是绝大多数的精华就在这个花园里面了。去历史氛围很重的地方游玩,最重要的是找寻一个讲解比较精彩和细心的导游--我们去的时候就跟对了导游,除去 她对恭王府纪念品的推销有一些过分热情之外,她的表现真是非常的完美。哈哈
据说,和珅对府院的设计极为细心,恭王府内的建筑布局、雕刻都蕴含着很深的意味。在古代,蝙蝠与“福”谐音,是吉祥的象征;在恭王府内到处都可以看到“福”的踪迹,进西洋门、见独乐峰,紧接着就是一个倒挂蝙蝠形状的小湖,边上的回廊上刻的都是蝙蝠形状的小装饰。还有窗户上的暗蝠,不一而足。据导游介绍一共有999个蝙蝠,再加上恭王府一绝的福字碑上由康熙亲自书写的福字,加在一起就是“万福”。
顺着导游的指引,接着来到了流杯亭。
东南角有一小景,名曰“流杯亭”,据说在清代等级森严的制约下,北京只建了六座类似的亭子,此亭为六中之最小的一座。亭上四周有忠孝节义典故的彩绘,亭中 地面有弯曲凹槽,正看呈“寿”字,垂直呈“水”字,正北入水口为“主位”,当年和珅经常在这里喝酒吟诗,地面凹槽通水后取“曲水流觞”之意境。流水的水波 推动酒杯缓缓前行,杯止行酒令,好一幅风雅文人行酒做乐之景致。
导游介绍说 谁做到水流出的地方就有好福气,可惜最开始过去的时候人太多了挤不过去,只好在逛完一遍之后在去重温一下。^-^
她还给我们介绍 康熙 写这个福字的典故。这些在网上都可以找到,就不说啦。
接着,我们进了垂花门,穿过垂花门内的牡丹院,院中有紫藤萝架。过了一会就到了花园的后门了,导游把人都集中到那里,说,大家来的时间很好,还能够摸到福字碑上的福字。因为之前拓字、游人太多,导致福字碑损害严重,现在只能用一层玻璃给保护起来了;随着可以预见的人流还会持续的增加,国家正考虑过一段后要封洞--果真那样的话,以后就很难去沾一下 福 字 的灵气了。2006在封碑前,工匠们集中拓了一部分的字。这些字经过精心的装裱,现在正在限量发售当中。不得不承认这个导游水平高,讲解得好,很好地掌握了大家的心理--很多人都买了手拓的福字,要不是穷学生的话,我也想买一份了。
在进入假山下面的山洞里面摸 福 之前,我们先走了一遍连接蝠厅的长廊。据导游讲,这段长廊记录着和珅的发迹之路,所以走的时候非常有讲究。
首先,从西边的口上长廊,长廊刚开始的地方有两处有石阶的地方,这些地方都要跨石阶而过,意味着跨过坎坷;然后上长廊的时候已经要直直往前走,千万不能回头。听着挺玄的阿,我们都照着导游说的到了蝠厅-那是和珅赏月的地方,下面的假山里面就藏着福字碑。这地方很隐秘,而且是在龙脉之上,连后来嘉庆都不敢动,所以这里的建筑才保存的如此只好。
下面的福字碑据说是周总理发现的,他看到假山上有一个双龙戏珠的图案,就对随从说,有龙的地方必有皇家之物,后来果然在双龙戏珠的珠子的正下方发现了这块碑。可惜,国宝保护的不好,以前毫无节制的拓字和游人接触造成了严重的损坏,现在我们去的时候只能隔着玻璃与福字碑接触了。
导游告诉我们,摸碑的时候也要有讲究的。首先是要用右手摸,摸的时候要先摸玉玺的印章,然后再摸整个字;因为这个字蕴含的深意很多,“多子,多才,多田,多寿,多福“,要全部都沾上也挺难的,就看大家最想要什么了,就可以
摸对应“多子,多才,多田,多寿,多福“的部分了,最后模完之后要把福气放到口袋里面才好。过程很顺利,唯一不爽的就是有两个保安在碑前面一直推着有人往前走,与福字碑的接触时间很短。
恭王府花园还有很多地方值得一看,比如妙香亭,戏楼,门口的一段小长城。院子里的湖,湖心是湖心亭。湖水还算清,里面有很多大大小小、各种颜色的鱼,值得一看。
在走之前,我们特意去流杯亭去温习了一下。坐在出水口的地方,两脚踩在出水口的两边,这样就能够得福得寿啦。可惜人太多了,一波一波的人流涌过来,挤的我们很快就走了。这会儿可能太晚了,还是有些导游不上心?反正她们只是简单介绍了一下这个亭子就把游客们领走了;和我们跟的导游相比,差的太远了。
出来的时候已经5点了,但是花园门外面贴着墙根,游客们还排着长长的队伍,看上去大多数都是旅游团的。不过这么晚了,进去游玩的时间肯定很紧,导游们怎么可能这么短时间内把经典的景致都介绍完呢?
接着我们去逛了一下什刹海的前海、后海;边上林立着酒吧--我感觉真是刹风景,就不提它们了。
总体来说,恭王府花园是一个非常值得推荐的地方,浓重的文化气息,加上幽静的环境。很值得一游。

Friday, April 27, 2007

米兰频道上线YOUTUBE

2007/3/30
A.C.米兰俱乐部的官方电视台米兰频道宣布在YOUTUBE网站上设立专属频道。这将是与YOUTUBE签署合约的第一家意大利电视台。

观众遍世界
2007/3/30 13:03:00

米兰频道成为了这个星球上第一个在Youtube网站上播出的意大利电视频道。米兰频道的网址是www.youtube.com/milanchannel。

A.C.米兰俱乐部的官方电视台米兰频道宣布在YOUTUBE网站上设立专属频道。这将是与YOUTUBE签署合约的第一家意大利电视台。

全世界都可以通过访问www.youtube.com/milanchannel 这个网址来观看米兰频道的特别版,其中将包括日常新闻剪辑,特别片段,独家视频和“米兰经典”内容,节目将以意大利语和英语的双语形式播出。

观众将有机会以多种形式与其他人互动,如投票,评论内容及向朋友发送自己喜爱的视频。他们还可以直接与米兰频道联系,发表自己对视频节目的意见。

“作 为第一家与YouTube合作的意大利频道,我们感到很自豪,”米兰频道主席里卡多.席尔瓦说道。“米兰频道再一次确认了自己是意大利最受欢迎的足球俱乐 部主题频道,在Sky电视台和全世界拥有55,000注册订阅用户。凭借无数的国际转播协议,米兰频道的节目在23个外国频道播出,涵盖了世界48国。 YouTube的社区每天都有数以千万计的视频节目被收看,与他们合作将借助互联网的力量吧把米兰频道在世界范围内的观众群进一步扩大。”

“米兰频道在YouTube上播出是个证明,”AC米兰商业和市场副总裁劳拉.马西说道,“它证明了俱乐部的成功策略,即通过互联网和内容的国际转播合约来真正的实现与我们球迷的实质性接触。”

Thursday, April 12, 2007

世界第9大奇迹-西直门立交桥

一名北京交警的自述
  大家好!俺是一名交警--不,应该说曾经是一名交警。俺现在已经辞职不干了,俺当了八年交警,立过五次一等功,九次二等功。可是俺前两天辞职不干了,因为领导要派俺去西直门。
   西直门刚改造好的时候,马师傅被派去负责那里,大伙儿都挺羡慕他,因为那是北京最气派的立交桥。可是过了仨月,局里接连接到投诉,说马师傅业务不熟练, 乱指路。想去安定门的让他给指到了动物园,想去动物园的让他给指到了蓟门桥,想去蓟门桥的让他给指到了金融街……最夸张的是有一位司机哭诉说他想去八达岭 长城,按马师傅说的一直走结果到了保定。局里把马师傅调离了西直门,可是马师傅多倔呀,每天一下班儿就骑着自行车到西直门一通绕,非要把这路都搞清楚不 可。后来局里让他休假了,他就干脆整天泡在西直门,一边儿绕圈儿一边嘴里念念有词……直到他搬进安定医院(精神病医院)我们都不知道他嘴里念叨什么呢。
   马师傅调离之后,牛师傅接了他的班儿。要说牛师傅不愧是业务骨干,就是心细,他花了几个月时间把西直门摸了个透熟,熬了几十个晚上练习画图。后来,甭管 谁问路,他掏出纸笔几分钟就把路线图画出来了。后来他被北大数学系一位老教授请走了,说他解决了数学界一大难题--徒手绘制七元八次方程组的解集图。他被 请去给全国各地数学系讲课。牛师傅哪儿会讲课呀,他只会画图,上来就画,黑板画满了就往墙上画,教室里画,家里画,白天画,晚上画……后来安定医院所有的 白墙也都让他画满了--除了马师傅那间病房,因为马师傅一看见牛师傅画的图就浑身哆嗦。
  牛师傅之后,小杨师傅接了班儿。一天,他正在指挥交 通,一转身儿,看见那边桥底下停着一辆汽车,司机坐在车里东张西望。小杨师傅有点儿纳闷儿,因为他印象里好像从来没在这个位置看见有车,今儿头一回,这司 机还怪模怪样。小杨便走过去,让司机赶紧把车开走,司机死活不走,说他只要一动就违章。小杨四下一看,可不。前面桥上挂着禁止驶入,地上画着左转线,可是 一旦左转就是逆行,右转呢?不行,也是禁止驶入。那就掉头吧?嘿,人家都替你想到了,左边就戳着个禁止调头的牌子。那也不能就这么停着呀,因为右边还立着 个前后200米内禁止停车的牌子。小杨问司机是怎么开到这儿来的,司机说刚才在路口地面标线和路边的指示牌不一致,他就按地面标线开,结果就开到这儿来 了。小杨发了一会儿呆,用步话机通知了附近的同事,然后他自己骑着摩托车直接就开进了安定医院,说什么也不出来了。
  小杨之后,局里就派俺来接 班儿。对了,俺姓朱,叫俺小朱好了。俺在西直门呆了一天,就知道这不是人干的活儿,赶紧托人找工作。没过几天,一哥们儿给介绍了西城环卫局的一份儿工作, 俺立马辞了职,到清洁队报到去了。俺负责一段儿长安街的保洁工作,干了两天,感觉好极了!俺每天把清洁车往路边儿一搁,然后就坐在马路牙子上看着川流不息 的车,又宽又直的马路,心里这叫一个痛快。在西直门呆久了,差点儿认为汽车都是爬着走的呢。看着看着,俺不知不觉高兴得都笑出声儿了。 昨天,上头领导来检查工作,检查到俺这儿,俺正坐在马路牙子上看着车流笑呢,领导刚要发火儿,俺们队长赶紧小声说:他就是那个西直门……那个交警……领导 立马多云转晴,微笑着对俺说:小朱啊,汽车好玩儿吗?俺白了他一眼,又吐了他一口吐沫,没搭理他。切,当俺是傻子呀,俺能没见过汽车吗?俺也当过交警呢, 西直门交警。

Friday, April 06, 2007

在北京航空馆门口的花


flower 花, originally uploaded by minjun_buaa.

今天天气真不错,上午开始晴晴的天,过会就有一片片的白云了;暖暖的风吹着,感觉到春天(夏天?)真的来了。^_^

中午的时候拿着数码相机出去拍了几张照片。
这一张是在北京航空馆门口拍的,这花正开着,很好看;不像周围的一些花的花期早,叶子都开始败了。

Wednesday, April 04, 2007

Linux操作系统中i2c总线设备驱动程序的设计分析


原文是从http://www.cechinamag.com/bbs/showtopic.aspx?id=18445这个地址得到的。
我想了解的内容是 i2c总线的驱动程序的体系结构,

1。I2C总线
I2C 总线通过串行数据SDA 和串行时钟SCL线在连接到总线的器件间传递信息,每个器件都有一个唯一的地址识别。根据数据传输时的功能不同,把器件分为主机和从机。主机是初始化总线 的数据传输并产生允许传输的时钟信号的器件,通常是微控制器。此时,任何被寻址的器件都被认为是从机,例如LCD驱动器、E2PROM等。
这样看来,一般外接的都是被寻址的器件,应该是从机。
2。Linux中I2C总线驱动结构
Linux的I2C框架中各个部分的关系如图所示:

内核中I2C相关代码可以分为三个层次:
1. I2C core框架:提供了核心数据结构的定义和相关接口函数,用来实现I2C适配器驱动和设备驱动的注册、注销管理,以及I2C通信方法上层的、与具体适配器无关的代码,为系统中每个I2C总线增加相应的读写方法。

2. I2C总线适配器驱动:定义描述具体I2C总线适配器的i2c_adapter数据结构、实现在具体I2C适配器上的I2C总线通信方法,并由i2c_algorithm数据结构进行描述。

3. I2C 设备驱动:定义描述具体设备的i2c_client和可能的私有数据结构、借助I2C core提供的函数接口完成设备在内核的注册,并实现具体的功能,包括read, write以及ioctl等对用户层操作的接口。

总体而言,Linux中I2C总线的驱动分为两个部分:总线驱动(BUS)和设备驱动(DEVICE)。I2C core与I2C总线适配器驱动完成了硬件上的主机总线驱动(BUS),而I2C driver则实现了从机设备驱动。在设计中,I2C core提供的接口是统一的,不需要修改,我们只需要实现特定I2C总线适配器驱动和I2C设备驱动,这样大大提高了系统的可移植性。

Tuesday, April 03, 2007

函数指针 条款14

/*
* 条款14
* 函数指针
*
* 我们可以声明一个指向特定类型函数的指针
*/
void (*fp)(int);//指向函数的指针

/*括号是必不可少的,它表明fp是指向一个返回值为void的函数的指针*/

extern int f(int);

extern void g(long);

extern void h(int);
//...
fp = f; //错误!&f的类型为int (*)(int), 而不是void (*)(int);
fp = g; //错误!&g的类型为void (*)(long), 而不是void (*)(int);
fp = h; //正确!
fp = &h;//正确!
/* 将一个函数的地址初始化或者赋值给一个指向函数的指针的时候,无需显式地取得函数
* 地址,编译器知道隐式地获得函数的地址,因此这种情况下&是可省的,通常忽略不用
*/

/* 类似的,为了调用函数指针所指向的函数而对指针进行解引用操作也是没有必要的,编译
* 器可以帮你解引用
*/

(*fp)(12); //显式地解引用
fp(12); //隐式得解引用,结果相同

/* 和void *指针可以指向任何类型的数据不同,不存在可以指向任何类型函数的通用指针;
* 还要注意,非静态成员函数的地址不是一个指针,因此不可以将一个函数指针指向一个
* 非静态成员函数
*/

/* 函数指针的一个传统用法就是回调(callback).
* 一个回调就是一个可能的动作,这个动作在初始化阶段配置,以便在将来可能发生的事件进
* 行响应。打个比方,如果我们希望救火,那么最好在开始阶段就计划好如何做出反应
*/

extern void stopDropRoll();
inline void jumpIn();

//...
void (*fireAction)() = 0;

//...
if(!fatallist) {//如果你关心失火了
//那么设置适当的动作以防万一
if(nearWater)
fireAction = jumpIn;
else
fireAction = stopDropRoll;
}

/* 一旦决定了要执行的动作,代码中的令一部分就可以专注于是否以及何时去执行动作,而
* 无需关心这个动作是什么了
*/
if( ftemp >= 451 ) {//如果着火了
if(fireAction)
fireAction();//执行之
}
/* 注意,一个函数指针指向一个内联函数是合法的,然而,通过函数指针调用内联函数不会
* 导致内联式的函数调用;编译器只能生成间接的/非内联的函数代码
*/

/* 另外,函数指针持有个重载函数的地址也是合法的,指针的类型被用在各种不同的候选函数中
* 挑选最佳匹配的函数
*/
void jumpIn();
void jumpIn(bool canSwim);
//...
fireAction = jumpIn;

Monday, April 02, 2007

C++复制操作 条款13

/*
* copy_operations.cpp
* 1.复制构造和复制赋值是两种不同的操作;
* 但是,在类的实现中,它们需要被放在一起,同时出现并且需要兼容.
*/

class Impl;
class Handle {
public:
//...
Handle(const Handle& ); //复制构造函数
Handle &operator = (const Handle &); //复制赋值函数

void swap(Handle &);
//...
private:
Impl *impl_;
};
/*
* 2.复制操作如此深远,以至于总是被成对的声明,具有如上所示的签名
*/

/*
* 3.对于一个类来说,如果成员形式的swap实现具有性能或者安全的优势,那么定义
* 一个swap成员函数往往是一个非常好的主意。典型的wap实现是很直观的
*/
template <typename T>
void swap(T &a, T &b)
{
T tmp;
tmp = a;
a = b;
b = tmp;
}
/*
* 它是根据T类型的复制操作来进行定义,如果T的实现很简单,这种方式就会工作的很好;
* 但如果T是一个复杂而且庞大的类,这种方式就会导致很大的开销。对于Handle类这样的类,
* 我们有更好的方式,即交换指向各自实现的指针
*/

inline void Handle::swap(Handle &that)
{
std::swap(impl_, thta.impl_);
}
/*
* 对于句柄类来说,这项技术工作的尤其好。句柄类的全部或者部分实现就是由一个
* 指向其实现的指针构成的.因此,为其编写异常安全的swap非常简单,容易实现
*/

/*
* 4.对于复制赋值的实现来说,一个微妙之处在于,复制构造的行为必须和复制赋值的行为
* 兼容,尽管它们不是相同的操作,但是它们产生的结果不应该有区别。
* 当用标准容器时,这种要求更加严格,因为标准容器的实现通常用复制构造来替代复制赋值
* 当然也就期望两种操作产生一致的结果。
*/

/*
* 一个或许更为常见的复制赋值实现具有如下的结构
*/
Handle &Handle::operator = (const Handle& that)
{
if(this != &that) {
//赋值操作
}
return *this;
}
/*这种检查一般出于正确性和效率的考虑*/

4月1号愚人节。。。

愚人节真没有意思,为什么什么东西流传到中国就变味了呢?! 老是骗老实人,就算骗成功了的话也没有成就感阿!

愚人节真真假假的事情太多。

最大的事件就是赶在愚人节这天,把项目的代码给写完调通了,真不容易。

其次的大事件就是,我同学的老婆4月1号生了一个胖小子,这日子挑的..... -_-|

Friday, March 30, 2007

聪明的推销员

今天看《Writing Clean Code》,第3章里面引用了一个售货员的例子,感觉人的心理太微妙了,太容易被诱导了。
它是引自Robert Cialdini博士在"Influence: How and Why people Agree to Things"中的故事。

如果你是一个售货员,那么,当顾客来到你负责的男装部准备购买毛衣和套装时,你应该总是先给顾客看套装,然后再给顾客看毛衣。这样做的理由是可以增加销售额。因为顾客在买了一件$500元的套装之后,相比之下一件$80的毛衣就显得不那么贵了。但是如果先给顾客看毛衣,那么$80一件的价格可能使其无法接受,最后也许你只能卖出一件$35的毛衣。任何人只要花30秒想想看,就会明白这个道理。可是又有多少人花时间想过这个问题呢?

Thursday, March 29, 2007

blogspot.com又可以访问了

感谢万能的长城,blogspot.com又可以访问了。
纪念之。

今天早上来实验室的时候都10点多了,天上是温暖的太阳,而地上则是一层湿湿的水,我心里面暗自赞叹-后勤工人就是勤劳,一大早就把道路洒了一遍。^_^
一到实验室,却发现有把伞晾在那儿,我就好奇的问了一句:“你怎么拿伞出来了?”
。。。。。。。
听到的回答是 =今天早上下雨了,你不知道?!!
呜呜,又被鄙视了。

今天有人出国了...

早上10点钟起来,就看见手机上有一封短信,一看发现是凤云发的,已经在来北京的火车上了.她们公司这一批出国的有十个人吧?从北京坐飞机出发, 可能是她们一行人东西也太多了,行动也不方便.我也没去看看她们.这一去,不知道得过多长时间才能回来一趟, 等回来路过北京的时候再联系她吧.
希望她们一行人平平安安,顺顺利利!!

Monday, March 26, 2007

春风吹遍北京城

这两天风的时代开始了,从早到晚吹个不停;暖暖的风,可惜吹的到处都是尘土。

北京的春天来了。

Sunday, March 25, 2007

googler推荐的C++和程序设计书

今天晚上,调程序实在是郁闷极了,从水木的google版上看到又有人在到处问google面试会问C++的什么内容,Curvelet (小曲线)给推荐了好多;我看了一遍,有的书是看过,但是都是粗略的看,而且很多内容都没有看-基础太不扎实了,我估摸着这几天把项目弄完了,时间充裕点了,就开始看这些书,争取在到我找工作之前能有明显的进步!现在好久没有用STL写过C++的程序了,结果上次一个极简单的问题,都没有解出来。-_-!!打击太大了。

=====废话少说,言归正传。
恩,xucuan 说的 http server 不错...

如果是为写程序打基础,我推荐一些书吧:

首先是关于程序设计语言,
C++ 是平时用的最多的语言,
除非你就不打算写服务端程序,
否则一定要掌握好。
为了正确的使用 C++,
你起码需要读过下面五本书:
C++ Primer,
Effective C++,
More Effective C++,
The C++ Standard Library,
Effective STL。
另外 Inside C++ Object Model 也不错。这些书基本上都有中文版/电子版。

其次是关于程序的设计分析,看《设计模式》,再配合多写点代码。

最后,最近大家很推崇的一本 CMU 大二 CS 教材《深入理解计算机系统》不错,
可以作为一本大杂烩复习本科学过的关于系统结构的东西。

不用花太多时间去专研太多开源的库,因为公司里面未必会用。
有需要的时候看看代码大致了解一下即可。

以上建议主要针对广大人民群众,能够看标准文档或能自己写 STL ctn/alg 的例外。