2005年05月26日

关于睡眠:

1.假睡—看不见的健康杀手            
2.缺少睡眠的人更容易生病?

3.健康的睡眠知多少?                  4.人为什么要睡眠,不睡眠行吗?          

5.老人为什么夜间容易发生意外?     6.比恋爱更重要的—–睡眠            


7.将寝具变成造就健康的工具
            8.为什么要使用健康寝具?


9.健康睡眠知识
                       
10.床的变革:木板床—席蒙思—-保健床

 

1.假睡—-看不见的健康杀手

   
人的正常睡眠—般分为思睡、浅睡、中睡和深睡四个阶段。在浅睡阶段时,对外界环境仍保持—定的反应.所以易受外界干扰而醒来,在浅睡中仍能听到房子里钟摆
的声音。假睡就是长时间处于浅睡阶段,难以进入中睡和深睡阶段的非睡眠状态。现代人由于工作、学习的紧张,往住极易处于假睡的状态。

   
假睡——看不见的健康杀手,假睡的人一般表现为:多梦、夜惊、中间早醒.失眠等。危害:假睡一般不被人们重视,但长期下去,它对人造成的危害却不
小。假睡会导致头痛、耳鸣、健忘、容易兴奋、免疫力下降、血压升高等。假睡导致人的正常睡眠质量太差,由此极易损害人的健康。

2.缺少睡眠的人更容易生病?

   
睡眠不仅仅在于能恢复体力和脑力,消除疲劳,完成自身修复,更重要的还在于它能保持人体的免疫能力,使人体自身能抵御疾病的侵扰。美国科学家研究发现,缺
少睡眠将影响人体的免疫力,从而使人更容易生病。研究结果表明,一个人如果减少四小时睡眠,第二天,他身体内抵御外来细菌侵袭的免疫细胞的活动将大大减
弱。因此,患有失眠症或经常通宵活动的人要注意确保夜间的良好睡眠。

3.健康的睡眠知多少?

睡眠有助于消除疲劳,恢复体力。

睡眠有助于防病怯病。

睡眠能促进发育。

睡眠能提高智力。

睡眠有助于延长寿命。睡眠是一切生理活动所需能量恢复和重新积累的过程。

4.人为什么要睡眠,不睡眠行吗?

    睡眠是一种生理需要。人在白天处于活动状态时,能量的消耗是主要的;夜晚人处于睡眠状态时,人体的各种生理活动减弱,能量消耗大为减少,此时体内的能量贮存大于消耗。积累的能量为第二天的活动做好了准备。

    人不睡觉行吗?古人谓: 日思三餐,夜思一宿。经过睡眠可以使人们的精力和体力得到恢复,能够以更饱满的精力和热情投入生活、投入工作。

    如果不睡觉会怎么样?

   
实验———有一个叫彼得·特里普和美国人参加一项200小时不睡觉的实验。在前三天,一切正常、到了第四天出现了精神崩溃状态,表现得对一些并不滑稽的事
情也捧腹大笑、不能自控。一些不值得悲哀的消息,听了之后竟莫名其妙地嚎啕大哭;本来自己没有戴帽子,却不断地埋怨自己头上的帽子压得太重。到了第五天,
受试者歇斯底里地大喊大叫,一会儿说别人的上衣象正在爬行的蠕虫,一会儿又说自己从着了火的房里跑出来。200小时后,他受到类似精神病一样的折磨.几乎
疯了。当他被架到床上,他睡了9小时11分钟后便一切正常了。从这个实验可以看出,人不睡觉是不行的。

5.老人为什么夜间容易发生意外?

   
人平躺入眠后,机体内各器官的代谢活动变慢,血液需要量减少,心率变慢,使体内的血液循环减慢,对有动脉粥样硬化的人,容易形成血栓。回心血量增加,从而
加重心脏负担,心肌耗氧量增加,可诱发心绞痛,机体的迷走神经兴奋性增强,可使支气管处于相对痉挛状态,此时若感到寒冷,或“感冒”等刺激,可诱发支气管
哮喘、老年慢性支气管炎的发作。

   
黄昏至深夜,是一天中温差变化最大的时期。尤其是冬春季节,容易使人在夜间着凉,从而引起发热、咳嗽等症状。此时,寒冷可引起小血管收缩和血粘度增高、成
为导致心肌梗塞和脑血栓形成的一大诱因。如晚餐吃的过饱,过于油腻,饭后可使血脂猛然增高,胃肠负担加重,从而加重心脏负担,可诱发急性胰腺炎、心绞痛、
心肌梗死和脑卒中等疾病。 过度疲倦也可能成为许多疾病的促发因素。疲劳可使机体的免疫功能相应地下降,抗病能力减弱,给多种疾病以可乘之机。

6.比恋爱更重要的—–睡眠

   
现代社会,节奏紧张,越来越多的人为睡眠不佳而烦扰,提高睡眠质量已成当务之急,如何过好快乐健康的每一晚?当今香港最畅销青年作家张小娴在她的散文中说
过:睡眠跟恋爱相似,是一种温暖而散漫的行为。睡眠能补充体力,好的恋爱也能补充体力,令人精神饱满。午睡是最幸福的一种习惯,象初恋和热恋:晚上的睡
眠,象一段稳定的感情,抚慰心灵;失眠和失恋一样,觉得每一天晚上都很难过,长夜漫漫,何时才等到天亮?

   
此话极形象,但事实上,睡眠比恋爱更为重要。因为一个人的一生,差不多有三分之一的时间在睡眠,对于成熟的人来说,可以没有恋爱,却不能没有睡眠。在一定
条件下,睡眠比饮食对于生命和健康更为重要。因为人在卧睡时脑和肝的血流量是站立时的7倍。睡眠可以使体内所有系统都缓慢下来,如心脏跳动缓慢,血压降
低,体温降低,使能量的释放大大降低,从而达到保存能量的作用。同时睡眠能促进生长激素释放,并有利于各种活性酶的激活,生长激素在夜间熟睡时的分泌量要
比白天高出5-7倍,它有利于儿童和青少年的生长发育,也能激活中老年人体内各种活性酶,从而加速新陈代谢,延缓大脑衰退。

     人不吃饭,能活20天

     人不喝水,能活7家

     人不睡觉,只能活5天

7.将寝具变成造就健康的工具

   
当人们意识到健康的重要性,对睡眠的认识,已从过去单纯的睡觉进讲求舒适、健康了;枕头、盖被及睡垫不再是普通而单纯的“传统寝具”了,而应该是既可带来
舒适的睡眠,又能更进一步利用睡眠时进行平衡身体、调整并强化身体机能的“道具”,由此来解决人们对运动不足、营养过剩、偏食、身体平衡失调、骨骼异常等
等苦恼。

    理想的寝具应从医学、生理、人体工程学之观点出发,考察枕头、睡垫及盖被的材质、厚度、轻度与适当的硬度等,进行全面性的分析研究,然后研制出能
够使人睡得舒适的寝具,比如一钻进被窝里即可迅速入睡、熟睡、醒来时能够轻松、爽朗的----具有下列条件能“造就健康”的寝具。

   (1)能使身体暖和。

       在睡眠中,人体的体温和温度调节功能都会下降,为防止人体散热,必须保持温暖。但维持保温不能依赖电热垫、火炉等设备,因为这种热能易使人体的自愈力退化。

  (2)睡垫不可太软或太硬。

  (3)盖被要轻。

    较重的盖被容易产生身体局部压迫,进而影响血液循环,造就肌肉疲劳。

  (4)能迅速散发汗水、透气、排湿。

  总之,我们需要的是软硬适中、干爽、透气、舒适、暖和的健康寝具。

8.为什么要使用健康寝具?

   
现代人的生活节奏越来越快,人们每天都处于十分繁忙的社会活动中,劳累程度也在不断的增加,患各种疲劳综合症人群也越来越多.同时,各种现代文明病也在困
扰着许多人,出现了头痛、肩颈痛、背痛、手足麻木、失眠等医院束手无措的症状。因此健康成为人们在满足了吃好、穿暖、生活舒适化后的下一个重要的需求。当
人们在追求健康的过程中,使用了很多方法,如:运动、吃营养品等方式,但使用健康寝具来改善健康的方法还是很多人不了解的,那么,为什么要使用健康寝具
呢?   

    我们知道,我们的寝具已经走过了三代,即土炕、木板床、席梦思,用棉被、棉褥等传统寝具的家庭还是占很大比例的。传统的寝具已不能满足现代人的生
活方式了,因为现代人的生活方式比较以前已发生了很大的变化,他们的身体也因各种原因发生了各种变化,因此,现代人就要使用现代化的寝具。我们家的电器设
备已经由单一功能替换成多功能,但惟独我们一生中接触最多的寝具还是单一功能的,人的三分之一的时间是在床上度过的,现在该是更换寝具的时候了。

    健康寝具的使用最早来源于日本,现在中国也有很多注重健康的有识之士开始关注健康寝具了。有一个很形象的比喻,现代人的身体如同手机电池,电池要
想使用寿命长就必须充足放净,否则,余电残留在电池内就回产生记忆,因此影响电池的寿命。现代人每天奔波劳累,体内易产生大量的疲劳物质(乳酸),加上夜
生活的丰富使人的睡眠时间越来越短,睡在单一功能的传统寝具(如席梦思、棉被褥等)上,人的疲劳得不到充分的缓解,清晨醒来的时候浑身发皱是很多现代人的
通症,这就是因为体内的乳酸等疲劳物质没有充分排散的原因。这就如同有余电在电池内一样,人体内的疲劳物质不断地积攒,会刺激我们的肌体使身体的抵抗力迅
速下降,严重影响细胞功能,直至折损人的寿命。

   
据科学家的研究,人的正常寿命可达到120年到150年,但是为什么人到了五、六十岁就已呈现老态了那?80%的原因是因为生活方式的不正确,睡眠是人的
一生中非常重要的生活方式,良好的睡眠不但可以使人得到充分的休息,还是维系人健康的重要组成,这是很多人尚未认知的。一套可以给您“充电”的健康寝具,
使您可以摆脱白天产生的诸多身体烦恼,以健康的体魄投入明天的工作。因此使用多功能的健康寝具已成为我们生活中的必需。

 9.健康睡眠知识

   
睡眠对于维持人体健康有着举足轻重的作用。睡眠是人体的一种本能的生理现象,对解除疲劳起着积极的作用。同时,对荷尔蒙的分泌等人体机能的正常工作有着密
切的关系。我们在日常生活中,为了维持身体本身的生理机能,适应外部环境的改变而选用各种服装,与此同时,为了保证每晚睡眠时生理机能(如体温变化、新陈
代谢低下、翻身、发汗等)不受外界的影响,有必要选择品质优良的寝具。

1) 通过睡眠消除疲劳

    众所周知,充足的睡眠能够消除疲劳、恢复健康。那么,睡眠为什么能够有此功效呢?我们在日常活动中,一种叫疲劳物质
酸沉积在肌体中导致疲劳。如果这种疲劳物质一直无法从体内消除的话,就会导致人没有活力、萎靡不振、神经衰弱、身心和肉体不健康的这种恶性循环。无法安眠
或者持续睡眠不足的话,就会感到身体不舒服、头重脚轻、缺乏食欲、情绪不佳、思考能力减弱、精神不集中,以上这些现象就是由于疲劳物质无法消除引起的。因
此,舒适的睡眠是恢复健康的良药。

2)促进安眠的姿势

   
体在生理上采取怎样的姿势才能获得最好的睡眠效果?一般认为向上仰躺,背部和手脚伸直,这种姿势最能熟睡。人体的脊椎骨支撑着沉重的头部和内脏器官,承受
着重压。在睡眠中让脊椎骨得到休息、缓和压力是极其重要的。因此,有人认为最好的姿势是就寝时脊椎骨很好地伸展开来,让寝具与脊椎骨的骨节之间空开23厘米。这样就能促进睡眠中血液的流动,提供氧份,顺利分解乳酸这种疲劳物质。背部弯曲着入睡的人多数会出现腰痛和肩膀酸痛,因此要获得高效睡眠的条件就是选择品质优良的寝具。

3) 运动不足和精神压力

   
康需要适度的运动。运动能够增强体力,促进新陈代谢,改善血液循环。运动的结果扩张了血管,加快了血液流动。身体缺乏运动,体力、耐力和速度自然就会降
低。不仅如此,社会生活中的紧张、不安、烦燥等精神上的压力也是导致生病的主要原因。因此,运动有利于消除精神压力,健康离不开运动。

10.床的变革:木板床—席蒙思—-保健床

   
不知你留意没有,前几年最明显,最引人注目的摆设也许是高低柜、沙发、小家电等之类的东西,可现在最引人注目的并不是这些,而是同我们朝夕相处,伴随人一生的床。道理很简单,因为生活的改善,人们的观念早已从那种注重美观、实用型的生活用品向保健型转化了。人的一生有1/3的时间是在床上度过的,可想而知,床在人的一生何等重要。

    这些年,床具的发展突飞猛进,越来越调高档、讲究,越来越注重花样、色调和材料的质地。

   
关于床的变革,也许人们记忆又回到了从前。在五、六十年代,一般家庭大多数是用棉胎做床垫,棉胎下面或是棕绷,或是木板。新的棉花胎还比较松软,透气性也
还好,但经过一段时间,棉花压实变硬了,汗水不易散发,导致棉垫潮湿,失去弹性和张力,一到休息日,家庭主妇们就纷纷拿出被子到外面去晾晒,大街小巷经常
出现“彩旗”。那时,人们头脑比较简单,什么美观不美观,只要便宜能暖人就行了。于是有的地方出现了购物券购买
78元一张木板床的情况。到后来,又风行了一阵泡沫塑料床垫。然而,泡沫塑料床垫依然没有解决透气和长期保持弹性的问题。而且人们发现,它比棉花胎更易潮湿,对人的副作用更大。

   
进入八十年代,“席梦思”席卷大江南北。这无疑是床具的一次革命性变化。在人们看来,这种床虽然贵一些,但它是居民最理想的一种了,因为它由弹簧、海绵
垫、棕绳等综合制成的,能较长时间保持柔性,它的疏通性也还不错,因为它的夹层是疏通的,容易透气。

   
进入九十年代,人们的生活步伐,办事频率加快了,常感到疲惫难忍。于是人们又把床的美观和保健作用放到了首位,以便以充沛的精力和体力投入第二天的工作。
研究人员也相继加强了对床上用品的研究和投资。这两年,带有保健型的一系列床垫应运而生。目前,一部分人家用上了高档的磁性健康床垫,虽然价格高一点,也
有很多人对其产生兴趣。这种新型的床垫,以棒状磁石紧贴人体易疲劳的部位,使磁力线能发挥更好的效果。其天然羊毛纤维层有良好的吸湿和疏爽作用,加上两层
新材料泡沫,保持了床垫的弹性和还原性。并且是折叠式的,便于携带和保藏。由此看来,床的保健功能有待开发,一方面,是消费者有这种需求,另一方面,生产
厂家也瞄准了这一市场的消费趋势。

  据悉,国外流行的充水床垫和充气床垫也正悄悄地流入内地,但是否被大多数消费者接受,尚需时间的验证。

2005年05月25日

有些情感是忙碌驱不走的,不像某些委屈和忧愁;
我工作,我学习,我打球,我让自己充实而紧张,有压力而悠然,却不能忘记某些情感;
就像是那个这种情感背后那个人一样;

忙忙碌碌奔波劳累,一切都是为了什么呢?
没有快乐的日子从现在就要来了吗,不然为什么快乐好久没有来了呢?

我封闭自己,把情感牢牢地锁在心底,因为说出去就显得不那么轻了;
我无法忘记,就像退去的潮水还会再来;
当女人花再次在耳边响起,可爱的模样浮现在眼前,酸楚的味道;

人活着到底为了什么,那目标可能会来吗?

2005年05月22日

人的感情这个东西,是一个难以捉摸的东西,明明知道如何对如何错就是无法控制自己的行为,思念是一张套牢自己的网,人在当中就像是待宰的羔羊,就像是落入蛛网的蚊蝇,挣扎而无济于事。
其实很多话都已经说得很明白了,只是不想伤她的心,分手又何必要鱼死网破呢,分手又何必要反目成仇呢,但是眼下的情况却总不是那么理想化。
就像原来看到有文章写得那样,分手了是不能做朋友的,如果能做朋友那么必然是双方都没有完全的付出。一直苦思不得明解,但感情这个东西似乎是你不服从答案的,且恰恰是背道而驰。越是似乎能保持朋友,越是痛苦,两个人的痛苦,就像毒药绞痛着两个人的心灵,梦魇一样的生活,求生不得求死不能的生活。
一直以为人们都说的话是不尊重个体特征的,但是这种经验主义在折磨中逐渐转为对大家言论的思考。世界上的事情都是讲道理的,既然存在就必然有其存在的道理,空穴来风必然毁于无形的风中,不攻而自破,但久攻而不破的就可能有其道理。
思想在实践的摸爬滚打中前行,对于普通人来说这其实是不足取的,只有先知才能忍受擦破皮肉摔断骨头的痛苦,并在小小的进步中获得心理的满足。但是没有办法,环境没有办法给你别的选择,成不了先知也要学会坚强。不敢于摸爬滚打就是放弃了自己的命运,别人来安排你的命运不一定就是不好的,那但至少是自己的意志减为无穷小了,我不喜欢。
环境给你的东西是什么,那就叫局限性。在局限中作决定就要敢于承担错误的代价,也许错了的一辈子都没有办法弥补,一辈子都会在心灵中留下阴影与缺憾,可是也带来了光明的希望,不能让美好的青春无休止的停留在夜里忍受黑暗和冷风的折磨,错误也是一种解脱,因为折磨在第一时间化为在一种巨大的痛苦而毁灭了自己。
一颗坦荡的心灵在一瞬间看似是一种卑鄙,也许会造成无法弥补的创痛,但是睿智的人儿啊,在漫长的人生道路上,时间也许会最终让人明晰一切。
上帝啊,保佑那颗受伤的心灵一瞬间找到煦暖的春风,保佑那颗历经坎坷饱受折磨得心灵能够稳稳睡上一觉好好休息休息吧。

2005年05月19日

shadow volume

http://developer.nvidia.com/object/robust_shadow_volumes.html

—————————————————————————

research On shadows

http://graphics.cs.lth.se/research/shadows/

————————————————————————–

CG shadow volume

http://www.gamedev.net/reference/articles/article1990.asp

————————————————————————-

graphic card and shadow

http://www.nvnews.net/previews/geforce_6600_series/

————————————————————————–

shadow techenology in Gamedev

http://www.devmaster.net/articles/shadow_techniques/

————————————————————————–

UltraShadow
II Technology

http://www.nvidia.com/object/feature_ultrashadow2.html

————————————————————————–

brown大学 game
research
组对于shadow的研究

http://graphics.cs.brown.edu/games/FastShadows/index.html

————————————————————————–




阴影锥原理与展望—真实的游戏效果的实现

作者:王浩

前言:真实的游戏效果

shadow volume 这个术语几乎是随着 DOOM3 的发布而成为
FPS 玩家和图形学爱好者谈论的对象的。虽然这个游戏还没有上市,但是凭借 John Carmack 的传奇经历以及 DOOM3
发布的一些让人惊讶的预览图片,我们仍然有理由认为它将会是 2004 年最热门的 FPS 游戏之一。 id software
向来都不吝惜为了达到最好的图像效果而使用最先进的渲染技术 ,
这曾经使得玩家为了玩它开发的游戏而不得不掏光口袋里面的钱来升级电脑,不知道这次我们可以幸免吗?

自 DX9 发布以来,大家的注意力似乎都被 shader 吸引住了, BBS
里面谈论的话题也总是离不开 shader based rendering ,前一段时间关于 GPU
内部精度的讨论大有遮天蔽日之感,但其实和闪闪发光的金属小球以及波光鳞鳞的水面比较,几个简简单单的影子常常能带给场景更多的真实感。也许这就是为什么
DOOM3 能够在多如牛毛的 FPS 游戏中脱颖而出的原因之一。

阴影的实现方法有很多种,现在比较流行的主要是 shadow mapping 和
shadow volume. 前者实现起来相对简单,可以发挥现在 GPU 可编程流水线的能力,但是由于先天不足,shadow mapping
在处理动态光源/物体的时候开销过大,经常作为一种静态场景中的廉价替代物。而 Shadow volume 的强项恰恰是 shadow
mapping 的短处,像 DOOM3 这种大量运用动态光源,并且要对时刻都在运动中的物体投射阴影,shadow volume
是现阶段唯一的选择。

Shadow mapping 的原理:

一个物体之所以会处在阴影当中,是由于在它和光源之间存在着遮蔽物,或者说遮蔽物离光源的距离比物体要近,这就是 shadow mapping 算法的基本原理。

Pass1:
光源为视点,或者说在光源坐标系下面对整个场景进行渲染,目的是要得到一副所有物体相对于光源的 depth map (也就是我们所说的
shadow map ) , 也就是这副图像中每个象素的值代表着场景里面离光源最近的 fragment 的深度值。由于这个 pass
中我们感兴趣的只是象素的深度值,所以可以把所有的光照计算关掉,打开 z-test 和 z-write 的 render state 。

Pass2:
视点恢复到原来的正常位置,渲染整个场景,对每个象素计算它和光源的距离,然后将这个值和 depth map
中相应的值比较,以确定这个象素点是否处在阴影当中。然后根据比较的结果,对 shadowed fragment 和 lighted
fragment 分别进行不同的光照计算,这样就可以得到阴影的效果了。

从上面的分析可以看出来,depth map
的渲染只和光源的位置以及场景中物体的位置有关,无论视点怎么运动,只要光源和物体的相互位置关系不变,shadow map
就可以被重复使用,因此对于没有动态光源的场景, shadow mapping 是很明智的一种选择。

除了上面提到的不能很好应付动态光源场景的限制之外,
shadow mapping 还存在着所有使用 texture
的场景面临的共同问题-锯齿。根据采样定理,只有纹理分辨率小于或者等于物体的实际分辨率时才不会失真,而当一副很大的纹理被贴到尺寸比它小的物体上时,
会出现一个 fragment 覆盖多个 texel 的情况,这时要准确的再现这个 fragment 的颜色信息,就要综合考虑所有被它覆盖的
texel 产生的影响,这就是各种纹理滤波方法最基本的原理。但是由于 depth map 是在不断的变化当中,所以不能像一般的纹理那样把各个
mip -map 事先计算好放到显存里面。有一种利用 pixel shader 的方法对 depth map 做 bilinear
filtering, 但是开销很大,在现阶段不具备实用意义。同样的问题在纹理分辨率小于屏幕分辨率的时候仍然存在,这时多个 fragment
会被投射到同一个 texel 上面,虽然从再现纹理的角度来说并不存在失真,但是由于多个 fragment
共用同一个纹理值,锯齿问题还是存在。更糟糕的是,没有一种滤波技术可以从根本上解决这样的锯齿,因为从数学上讲,人们不可能通过运算来创造出比原始
量更多 的信息。近年来,为了解决 shadow mapping 的锯齿问题,人们做了很多努力,比较有前景的是 adaptive shadow
map(ASM) 和 perspective shadow map(PSM) 。两者的基本原理都是在可能产生锯齿的地方人为增加采样率,使得一个
fragment 至少对应一个 texel , 区别是 ASM 增加采样率的地方是在 shadow 边缘,而 PSM
是在靠近视点的地方。修补一个本身存在缺陷的方法从数学上来说是缺乏美感的,正像 John Carmack 在 2002年8月的一封 email
中所说:

“ Shadow buffers make
good looking demos with controlled circumstances, but when you start
using them for a “real” application, you find that you need absolutely
massive resolution to get acceptable results for omni - directional
lights, and a lot of the artifacts need to be tweaked on a per-light
basis. While it is possible to do shadow buffers on GF1/radeon class
hardware, without percentage closer filtering they look wretched. If we
were targeting only the newest hardware, shadow buffers would have a
better shot, but even then, they have more drawbacks than are commonly
appreciated. ”

看起来似乎 John Carmack 找到了实现阴影更好的方法?让我们来看看它究竟是什么。

 

Shadow volume 的原理:

Shadow volume 这种算法第一次被提出是在
Franklin C. Crow 在 1977 年写的一篇论文 “SHADOW ALGORITHMS FOR COMPUTER
GRAPHICS ”里。其基本原理是根据光源和遮蔽物的位置关系计算出场景中会产生阴影的区域( shadow volume
),然后对所有物体进行检测,以确定其会不会受阴影的影响。


图中的绿色物体就是所谓的遮蔽物,而灰色的区域就是 shadow volume。


只有处于 shadow volume 里面的物体才会受阴影的影响。

shadow volume的算法

现在清楚了 shadow volume 的基本原理,那么如何确定一个物体或者一个物体的某一部分处于 shadow volume 中呢?这就要用到 stencil buffer 的帮助了。

z-pass 算法:

z-pass 是 shadow volume 一开始的标准算法,用来确定某一个象素是否处于阴影当中。其原理是:

Pass1:eNABle
z-buffer write ,渲染整个场景,得到关于所有物体的 depth map 。注意这里的 depth map 和 shadow
mapping 里面的区别是 shadow volume 里面的 depth map 是以真实视点作为视点得到的,而 shadow
mapping 里面的 depth map 是以光源为视点得到的。

Pass2:disable z-buffer write , eNABle
stencil buffer write, 然后渲染所有的 shadow volume 。对于 shadow volume 的 front
face( 既面对视点的这一面 ) ,如果 depth test 的结果是 pass, 那么和这个象素对应的 stencil 值加一。如果
depth test 的结果是 fail, stencil 值不变。而对于 shadow volume 的 back face(
远离视点的一侧 ) ,如果 depth test 的结果是 fail, stencil 值减一,否则保持不变。

用一句简单的话来概括 z-pass
的算法就是从视点向物体引一条视线,当这条射线进入 shadow volume 的时候, stencil 值加一,而当这条射线离开 shadow
volume 的时候,stencil 值减一。如果 stencil 值为零,则表示实现进入和离开 shadow volume
的次数相等,自然就表示物体不在 shadow volume 内了。

Pass3第二步完成以后,根据每个象素的 stencil 值判断其是否处于阴影当中(如果 stencil 的值大于零,则这个象素在 shadow volume 内,否则在 shadow volume 的外面),然后据此绘制阴影效果。


在这副图里面,视线三进三出 shadow volume, 最后的 stencil 值为零,表示物体在 shadow volume 外,不受阴影的影响。


这副图里面视线三进一出, stencil 值为 2 ,表示物体在 shadow volume 内,有阴影产生。


这副图里面从视点到物体的视线中止于 shadow volume 前,也就是说所有的 z-test 都是 fail, 相应的 stencil 值为零,表示物体在阴影外面。

z-pass 算法缺点及补救办法

以上的讨论都是基于视点在 shadow volume 外面的情况。在这个条件可以得到满足的情况下,z-pass 算法工作的很好,不过一旦视点进入到了 shadow volume 里面,z-pass 算法就会立即失效。

这副图里面的视线二进二出,按照 z-pass
的算法,最后的 stencil 值为 0
,表示物体在阴影外,可实际上物体是处于阴影内的。错误的原因就在于视点进入到阴影内,使得视线失去了一次进入 shadow volume
的机会,让原本应该是 1 的 stencil 值变成了 0 。

Z-Pass 这种错误的行为可以从下图中看出 :


注意地下的影子

Z-Fail 算法:

Z-Fail 算法是 John Carmack,Bill Bilodeau 和 Mike Songy 各自独立发明的,其目的就是解决视点进入 shadow volume 后 z-pass 算法失效的问题。

Pass1:eNABle z-write/z-test, 渲染整个场景,得到 depth map 。 ( 这一步和 z-pass 的完全一样 )

Pass2:disable z-write, eNABle
z-test/stencil-write 。渲染 shadow volume, 对于它的 back face ,如果 z-test 的结果是
fail, stencil 值加一,如果 z-test 的结果是 pass, stencil 值不变。对于 front face, 如果
z-test 的结果是 fail, stencil 值减 一 ,如果结果是 pass, stencil 值不变。


图中所有的 shadow volume 都处在 z-pass 的位置,因此 stencil 值不会改变。


视点在 shadow volume 内也没有问题,最后 stencil 的值是 2, 表示物体在阴影内。

上面那个 Z-Pass 无法处理的场景,用 Z-Fail 计算则可以得到正确的结果:


使用 z-Fail 算法的条件

Capping For Z-Fail

由于 Z-Fail 算法依靠计算 shadow
volume 不能通过 Z-test 的部分来确定 stencil buffer 的值,所以要求 shadow volume
是闭合的。下面的那张图里面红色的实线表示 capping, 可以想象,假如不人为的添加 capping, 那么 shadow object
1/2 的 stencil 值都会是 0 ,而实际上正确的 stencil 值应该是 1 ,因为它们都在阴影内。

Z-Pass 和近剪裁面的关系:

在 Z-PASS 算法中,当 shadow
volume 和视图体 (view frustum) 发生剪切关系的时候,需要附加的 capping 才能保证最后的结果正确。因为经过
view frustum 的剪裁作用以后,shadow volume 的一部分有可能变成敞开的,比如在图中 additional
capping 的位置,假如不人为的附加一部分多边形,在渲染 shadow volume 的时候 stencil buffer 就不会发生
+1 的操作 ( 因为这里没有任何多边形,自然也就不会和原来的 depth map 比较 ) ,最后的结果显然是不对的。

如何建立 shadow volume?

shadow volume
的建立是整个算法里面最重要的部分,在 GPU 出现以前, shadow volume 的建立都是基于 CPU 的。随着 GPU
应用的逐渐开展,人们又将 shadow volume 运算移植到了 GPU
上,不过后面一种方法需要对物体的几何数据进行预处理,下面就对两种方法分别进行解释:

CPU based method(基于CPU建立方法):

想必熟悉 shadow volume 的朋友对
silhouette edge 这个词会很熟悉。它表示从光源的角度看物体所得到的轮廓线。 Shadow volume 就是由
silhouette edge 扩展到一定距离以外或者无穷远处得到的。 silhouette edge
的确定方法有很多种,基本思想就是找出那些被朝向相反 ( 一个面向光源,另一个背向光源 ) 的两个三角形 ( 相对于光源来说 )
所共享的边,因为只有这样的边会最终成为 silhouette edge ,其他的边在光源看来都在物体投影的内部而不是边缘。

这副图是一个由 4 个三角形组成的多边形,假设光源处在读者头部的位置,那么外围的一圈实线就是所谓的 silhouette edge 。我们所要做的就是从原始数据里面将内部多余的 4 条边 ( 虚线 ) 去掉。具体实现是这样:

•  遍历模型的所有三角形

•  计算 dot3( light_direction , triangle_normal ) 。用这个结果判断三角形是面向光源 (dot3>0) 还是背向光源 (dot<0) 。

•  对于面向光源的三角形,将所有的三条边压入一个 栈 ,和里面的边进行比较,如果发现重复的 (edge1 和 edge2) ,将这些边删除

•  检测过所有三角形的 所有边 以后, 栈 里面剩下的 边就是 当前光源 / 物体位置下面的 silhouette edge.

•  根据光源方向 , 利用 CPU 或者 vertex shader 将这些 silhouette edge 投射出去形成 shadow volume.

值得一提的是,这种方法正是 DOOM3
所采用的方案,但是其中有一个问题就是 silhouette edge
是由光源和物体的相互位置确定的,也就是说这二者之间有一个的位置发生了变化, silhouette edge
就要重新计算,更新的数据也要传回显卡才能渲染 shadow volume ,这对 CPU 的计算能力以及 AGP
的带宽不能不说是一个不小的考验。

GPU based method(基于GPU建立方法):

Vertex shader
一出现人们就在思考能不能利用它来加速 shadow volume 的渲染速度。但即使是现在最先进的 vertex shader 3.0
也不具备创建新的几何物体的能力。简单点说 vertex shader 只能接受一个顶点,修改这个顶点的属性 ( 位置,颜色,纹理坐标,
etc), 之后输出这个顶点到光栅化部分,继而进行 pixel shader 运算。碰到需要创建新顶点的地方,就只有依靠 CPU 直接操作
vertex buffer 了。

另外一个方法就是事先把 shadow volume
需要的空间留出来,然后再通过 vertex shader
的运算使之外形达到我们需要的样子。这就好比我要存储一串数据,但又不很确定具体的规模是多大,只好事先分配一块很大的区域,这样不免会造成很大浪费,但
也是不得以而为之。

   

由于物体上的每条边都有可能成为 silhouette
edge ,所以我们需要事先插入 degenerate quad( 上图的红色三角形 ), 这些 quad
的面积为零,不作任何变换的话是不可见的,不会造成视觉瑕疵。但是在需要的地方,可以把这些 quad 拉伸成为 shadow volume 的侧壁。

显然,插入冗余的顶点会造成极大的浪费。因为大部分的
边最终 并不会成为 silhouette edge ,也就是说插入的 degenerate quad
是无用的。不过这样做的好处是几何数据只需要传输到显卡一次,之后无论光源的位置在哪里,预处理过后的几何体都可以用来生成 shadow
volume ,不像刚才解释过的方法那样一旦光源和物体的相对位置发生变化,就需要重新用 CPU 计算 silhouette edge
,之后再把结果 传送给显卡。

实际编程的时候,可以做一下改进,由于平坦的表面是不会产
生阴影的,所以在这些表面所包含的边上就没必要插入 degenerate quad
。而且所有的预处理应该在软件开发过程中完成,用户启动程序以后直接调用的就是插入过 quad 的模型,不需要 CPU 再进行计算。

建立/渲染 shadow volume 的 shader 代码:

// c0     : Light position in object space

// c1     : 1, 1, 1, 0

// c2- c5   : Light * View * Proj = LightClip

// c6- c9   : WorldInvLight matrix

// c10    : Color for exposing the shadow volume

vs.2.0

mov oD0, c10        // 输出特定的颜色使 shadow volume 可见

sub r1, v0, c0        // 光源方向

m4×4 r4, v0, c[6]        // 将顶点变换到光源坐标系

nrm r1, r1        // 光源向量归一化,这是为了 shadow volume 的各个边一样长

mov r10, c1

dp3 r10.w, v1, r1        //dp3 顶点法向量和光源向量,确定顶点的朝向

slt r10, c1.w, r10        // 根据 dp3 的结果设置 r10 寄存器的第四个单元

mul r4, r4, r10        // 设定 r4 的 w 位

m4×4 r5, r4, c[2]        // 输出顶点到 clip space

mov oPos , r5


Shadow volume 的算法优化(一)

Shadow volume 的基本算法讲到这里就基本完成了,下面说一下现在比较常用的一些优化算法。

(一)Z-Pass .VS. Z-Fail

前面提到过,Z-Pass 比 Z-Fail 速度要快,因此我们可以在不会产生问题的场合下适当使用 Z-Pass 来提高性能,但是如何确定何时 Z-Pass 不会带来问题呢? Z-Pass 失效主要是由于两种原因 :

原因一:视点进入 shadow volume 内,比如下图:

只要能探测出这两种情况,就能在需要的时候切换到 Z-Fail 算法。条件 A 的判定可以参照下图,在视点和光源之间做一条连线,如果这条线和遮蔽物相交,那么可以肯定视点在 shadow volume 内,将切换到 Z-Fail 算法。

原因二:shadow volume 与近 剪裁面 相交

至于情况 B 的判定可以利用光源和近 剪裁面 形成的
light-pyramid( 红色阴影部分 ) 与遮蔽物的交汇关系。如果遮蔽物完全在 light-pyramid 之外,则由它生成的
shadow volume 不会和近 剪裁面 相交,可以使用 Z-Pass 算法,否则将只能使用 Z-Fail 算法。

 

Shadow volume 的算法优化(二)

(二)tricks to save fillrate :

前面提到过,shadow volume
算法里面两个最耗时的步骤就是 silhouette edge determination 和 shadow volume rendering
。其中 shadow volume rendering 是完全考验 GPU 填充率的步骤,虽然现在的显卡动辄就有几十 G fragment/s
的填充率能力,但是遇到复杂的场景,流水线也不免不堪重负。此外,频繁的 stencil buffer
操作也会占据一部分显存带宽,如果能够找出一些办法尽量减小 shadow volume 的尺寸,将会是效果很明显的一种优化方法:

限定光照的范围(Attenuated Light Bounds):

如果所用的光源有衰减效应,则可以利用 scissor
test 将渲染的范围限定在光源的作用范围之内,因为超出了这个范围就不会有阴影存在,自然用不着去渲染那部分的 shadow volume
了。所谓 scissor test 就是人为地在屏幕坐标系下面定义一个矩形,只有坐标处在这个矩形范围内的 fragment
才能够通过测试,其内容才能被写入 帧 缓存。

NVIDIA的阴影加速技术(ultra shadow):

ultra shadow这项技术是随着NV35 的发布而浮出水面的,进而在 NV36/38 中得到了继承,我们基本上可以在 NVIDIA 今后的产品中,这项技术会得到持续的应用。

id software 的当家程序员 John
Carmack 曾经说过 NV35 是为 DOOM3 量身打造的 GPU ,我们在这里有理由怀疑 Carmack
说这番话的原因很有可能就是由于 NV35 中集成了 ultra shadow 阴影加速技术(近日GeForce
FX系列已经成为DOOM3的推荐GPU),那么 ultra shadow 究竟是什么,它如何加速阴影的渲染速度呢?

其实 ultra shadow 技术仅仅利用了一个 NVIDIA 新近提交的 OpenGL 扩展—— EXT_depth_bounds_test,我们先来看一下 NVIDIA 官方在 GDC2003 上对这个扩展的介绍:

首先注意一下名称的问题,GDC2003
在三月举行,那时这个扩展还只是 NVIDIA 独家的东西,到了 4 月这个扩展更名为 EXT_depth_bounds_test 。 EXT
开头的扩展表示有多家厂商在开发这项技术,也许不久以后我们就会看到 ultra shadow 在 ATI 的 GPU 上面实现。

Depth bounds test 的作用是比较由当前 fragment 的屏幕坐标( xw , yw )指定的 depth buffer 中的 z 值与用户通过 glDepthBoundsNV(GLclampd zmin , GLclampd zmax )
所指定的 [ zmin,zmax ], 如果 z 值在次范围之外,则将当前的 fragment 从流水线中剔除掉,不进行此处的 stencil
buffer 操作。注意这里比较的并不是 fragment(shadow volume) 的 z 值,而是前一个 path 中已经渲染过的
shadow receiver 的 z 值。具体情况请看下图:

可以看到,由于 A 点的 z 值在 [ zmin,zmax ] 范围之外,此点没有可能被阴影遮住,因此 A1/A2 点处的 fragment 就可以被丢弃。而 B 点的 z 值在 [ zmin,zmax ] 之外,所以 B1 点处的 fragment 就必须进行 stencil buffer 操作。

(详细的技术介绍请看:《NVIDIA的复仇计划 GF FX 5900 Ultra》)

阴影渲染实现技术的展望

shadow volume
是近阶段实现统一光照模型比较好的一种技术,现在主要的问题是基于 CPU 的方法对处理器依赖比较重,在 AI/ 物理运算较多的场景中 CPU
的运算能力可能不足,而基于 GPU 的方法效率太低,会产生大量的冗余顶点,其原因还是由于现在的 GPU( 包括即将发布的 NV40/R420)
都不具备在芯片内部产生新顶点的能力。 Microsoft 意识到了这一点,在 DirectX Next
的发展规划中将这种能力列为了要实现的目标之一:

从更长远的角度来说,基于真实物理模型的光照模型(比如
spherical harmonic
lighting、ray-tracing、radiosity)才是发展的方向,那时我们没有必要设计单独的算法来实现阴影,所有的光照/阴影效果都被
包扩在了一个统一的光照模型之中,任何效果实现起来都是自然而然的,就像它们在真实世界中的情况一样。当然,所有这些设想都要基于半导体生产技术的支持才
行,我们在近期(5-10年)将不会看到它们在硬件上的实现。

 


openGL的四个缓存

如果绘制3D对象时需要剔除隐藏表面的话,深度缓存是必要的。这个缓存在每个象素上存储了显示对象的深度值。当绘制附加对象的时候,会在每个象素上进行深度比较,这样就能决定新的对象是否可见。



  模板缓存用来进行复杂的掩模(masking)操作。一个复杂的形状可以存储在模板缓存里,然后绘制子序列操作可以使用模板缓存里的内容来决定是否更新象素。



  积累缓存是一个颜色缓存,不过典型地它有比颜色缓存更高的精度。这就允许一些图像通过积累产生一些合成的图像。比如说一个作用就是可以在积累缓存里对
一个对象随着他的运动绘制一些帧数。在积累缓存中的象素除以帧数以后,结果图像就展现出了运动模糊效果。相似的技巧也可以用来模拟景深效果以及高质量的全
屏抗锯齿。



  而通常的,当一个对象被绘制的时候,对于某个图元是否影像屏幕上的象素,会做一个单独的决议。多重采样缓存正是这样一个缓存,它允许每个渲染的对象在
象素内被采样多次,以进行高质量的全屏抗锯齿,而不必对这个对象渲染多次。每个象素内的采样包括:颜色,深度,模板信息。每个象素采样的次数当然是必须
的。当窗口包含多重采样缓存的时候,它将不回包括单独的深度或者是模板缓存。随着对象的渲染,颜色样本会被组合生成一个单一的颜色值,然后这个颜色值被传
递,并写入到颜色缓存里。因为他们包括窗口中每个象素的多个颜色、深度以及模板样本(通常是4,8或者是16),因此多重采样缓存会消耗相当数量的离屏缓
存。

2005年05月18日


Princeton图形学的研究生课程网站,每个方面经典的论文都列出来了。而且可以下载。http://www.cs.princeton.edu/courses/archive/fall02/cs526/resources.html

I have a dream.I hope I could reach very much depth in some point!

2005年05月14日

林锐 -修练8年C++面向对象程序设计之体会

from:http://www.donews.net/jiji262/archive/2005/05/13/378801.aspx

六年前,我刚热恋“面向对象”(Object-Oriented)时,一口气记住了近十个定义。六年后,我从几十万行程序中滚爬出来准备写点心得体
会时,却无法解释什么是“面向对象”,就象说不清楚什么是数学那样。软件工程中的时髦术语“面向对象分析”和“面向对象设计”,通常是针对“需求分析”和
“系统设计”环节的。“面向对象”有几大学派,就象如来佛、上帝和真主用各自的方式定义了这个世界,并留下一堆经书来解释这个世界。

  有些学者建议这样找“对象”:分析一个句子的语法,找出名词和动词,名词就是对象,动词则是对象的方法(即函数)。

 
 当年国民党的文人为了对抗毛泽东的《沁园春·雪》,特意请清朝遗老们写了一些对仗工整的诗,请蒋介石过目。老蒋看了气得大骂:“娘希匹,全都有一股棺材
里腐尸的气味。”我看了几千页的软件工程资料,终于发现自己有些“弱智”,无法理解“面向对象”的理论,同时醒悟到“编程是硬道理。”

  
面向对象程序设计语言很多,如Smalltalk、Ada、Eiffel、Object Pascal、Visual
Basic、C++等等。C++语言最讨人喜欢,因为它兼容C 语言,并且具备C 语言的性能。近几年,一种叫Java
的纯面向对象语言红极一时,不少人叫喊着要用Java 革C++的命。我认为Java
好比是C++的外甥,虽然不是直接遗传的,但也几分象样。外甥在舅舅身上玩耍时洒了一泡尿,俩人不该为此而争吵。

  关于C++程序设计的书藉非常多,本章不讲C++的语法,只讲一些小小的编程道理。如果我能早几年明白这些小道理,就可以大大改善数十万行程序的质量了。

1. C++面向对象程序设计的重要概念

  早期革命影片里有这样一个角色,他说:“我是党代表,我代表党,我就是党。”后来他给同志们带来了灾难。

  会用C++的程序员一定懂得面向对象程序设计吗?

  不会用C++的程序员一定不懂得面向对象程序设计吗?

  两者都未必。就象坏蛋入党后未必能成为好人,好人不入党未必变成坏蛋那样。

 
 我不怕触犯众怒地说句大话:“C++没有高手,C 语言才有高手。”在用C 和C++编程8年之后,我深深地遗憾自己不是C
语言的高手,更遗憾没有人点拨我如何进行面向对象程序设计。我和很多C++程序员一样,在享用到C++语法的好处时便以为自己已经明白了面向对象程序设
计。就象挤掉牙膏卖牙膏皮那样,真是暴殄天物呀。

  人们不懂拼音也会讲普通话,如果懂得拼音则会把普通话讲得更好。不懂面向对象程序设计
也可以用C++编程,如果懂得面向对象程序设计则会把C++程序编得更好。本节讲述三个非常基础的概念:“类与对象”、“继承与组合”、“虚函数与多
态”。理解这些概念,有助于提高程序的质量,特别是提高“可复用性”与“可扩充性”。

1.1 类与对象

  对象
(Object)是类(Class)的一个实例(Instance)。如果将对象比作房子,那么类就是房子的设计图纸。所以面向对象程序设计的重点是类的
设计,而不是对象的设计。类可以将数据和函数封装在一起,其中函数表示了类的行为(或称服务)。类提供关键字public、protected
和private 用于声明哪些数据和函数是公有的、受保护的或者是私有的。

  这样可以达到信息隐藏的目的,即让类仅仅公开必须要让外界知道的内容,而隐藏其它一切内容。我们不可以滥用类的封装功能,不要把它当成火锅,什么东西都往里扔。

  类的设计是以数据为中心,还是以行为为中心?

  主张“以数据为中心”的那一派人关注类的内部数据结构,他们习惯上将private 类型的数据写在前面,而将public 类型的函数写在后面,如表8.1(a)所示。

  主张“以行为为中心”的那一派人关注类应该提供什么样的服务和接口,他们习惯上将public 类型的函数写在前面,而将private 类型的数据写在后面,如表8.1(b)所示。

 
 很多C++教课书主张在设计类时“以数据为中心”。我坚持并且建议读者在设计类时“以行为为中心”,即首先考虑类应该提供什么样的函数。
Microsoft 公司的COM 规范的核心是接口设计,COM 的接口就相当于类的公有函数[Rogerson
1999]。在程序设计方面,咱们不要怀疑Microsoft 公司的风格。

  设计孤立的类是比较容易的,难的是正确设计基类及其派生类。因为有些程序员搞不清楚“继承”(Inheritance)、“组合”(Composition)、“多态”( Polymorphism)这些概念。

1.2 继承与组合

  如果A 是基类,B 是A 的派生类,那么B 将继承A 的数据和函数。示例程序如下:

class A
{
public:
void Func1(void);
void Func2(void);
};
class B : public A
{
public:
void Func3(void);
void Func4(void);
};
// Example
main()
{
B b; // B的一个对象
b.Func1(); // B 从A 继承了函数Func1
b.Func2(); // B 从A 继承了函数Func2
b.Func3();
b.Func4();
}

  这个简单的示例程序说明了一个事实:C++的“继承”特性可以提高程序的可复用性。正因为“继承”太有用、太容易用,才要防止乱用“继承”。我们要给“继承”立一些使用规则:

  一、如果类A 和类B 毫不相关,不可以为了使B 的功能更多些而让B 继承A 的功能。

  不要觉得“不吃白不吃”,让一个好端端的健壮青年无缘无故地吃人参补身体。

  二、如果类B 有必要使用A 的功能,则要分两种情况考虑:

  (1)若在逻辑上B 是A 的“一种”(a kind of ),则允许B 继承A 的功能。如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类Man 可以从类Human 派生,类Boy 可以从类Man 派生。示例程序如下:

class Human
{

};
class Man : public Human
{

};
class Boy : public Man
{

};

 
 (2)若在逻辑上A 是B 的“一部分”(a part of),则不允许B 继承A
的功能,而是要用A和其它东西组合出B。例如眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是头(Head)的一部分,所以类Head
应该由类Eye、Nose、Mouth、Ear 组合而成,不是派生而成。示例程序如下:

class Eye
{
public:
void Look(void);
};
class Nose
{
public:
void Smell(void);
};
class Mouth
{
public:
void Eat(void);
};
class Ear
{
public:
void Listen(void);
};
// 正确的设计,冗长的程序
class Head
{
public:
void Look(void) { m_eye.Look(); }
void Smell(void) { m_nose.Smell(); }
void Eat(void) { m_mouth.Eat(); }
void Listen(void) { m_ear.Listen(); }
private:
Eye m_eye;
Nose m_nose;
Mouth m_mouth;
Ear m_ear;
};

  如果允许Head 从Eye、Nose、Mouth、Ear 派生而成,那么Head 将自动具有Look、Smell、Eat、Listen 这些功能:

// 错误的设计
class Head : public Eye, public Nose, public Mouth, public Ear
{
};

  上述程序十分简短并且运行正确,但是这种设计却是错误的。很多程序员经不起“继承”的诱惑而犯下设计错误。

  一只公鸡使劲地追打一只刚下了蛋的母鸡,你知道为什么吗?

  因为母鸡下了鸭蛋。

  本书3.3 节讲过“运行正确”的程序不见得就是高质量的程序,此处就是一个例证。


1.3 虚函数与多态

  除了继承外,C++的另一个优良特性是支持多态,即允许将派生类的对象当作基类的对象使用。如果A 是基类,B 和C 是A 的派生类,多态函数Test 的参数是A 的 指针。那么Test 函数可以引用A、B、C 的对象。示例程序如下:

class A
{
public:
void Func1(void);
};
void Test(A *a)
{
a->Func1();
}
class B : public A
{

};
class C : public A
{

};
// Example
main()
{
A a;
B b;
C c;
Test(&a);
Test(&b);
Test(&c);
};

  以上程序看不出“多态”有什么价值,加上虚函数和抽象基类后,“多态”的威力就显示出来了。

  C++用关键字virtual 来声明一个函数为虚函数,派生类的虚函数将(override)基类对应的虚函数的功能。示例程序如下:

class A
{
public:
virtual void Func1(void){ cout<< “This is A::Func1 \n”}
};
void Test(A *a)
{
a->Func1();
}
class B : public A
{
public:
virtual void Func1(void){ cout<< “This is B::Func1 \n”}
};
class C : public A
{
public:
virtual void Func1(void){ cout<< “This is C::Func1 \n”}
};
// Example
main()
{
A a;
B b;
C c;
Test(&a); // 输出This is A::Func1
Test(&b); // 输出This is B::Func1
Test(&c); // 输出This is C::Func1
};

  如果基类A 定义如下:

class A
{
public:
virtual void Func1(void)=0;
};

  那么函数Func1 叫作纯虚函数,含有纯虚函数的类叫作抽象基类。抽象基类只管定义纯虚函数的形式,具体的功能由派生类实现。

  结合“抽象基类”和“多态”有如下突出优点:

  (1)应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。这一
招叫“以不变应万变”,可以大大提高程序的可复用性(这是接口设计的复用,而不是代码实现的复用)。

  (2)派生类的功能可以被基类指针引用,这叫向后兼容,可以提高程序的可扩充性和可维护性。以前写的程序可以被将来写的程序调用不足为奇,但是将来写的程序可以被以前写的程序调用那可了不起。


2 良好的编程风格

  内功深厚的武林高手出招往往平淡无奇。同理,编程高手也不会用奇门怪招写程序。良好的编程风格是产生高质量程序的前提。

2.1 命名约定

 
 有不少人编程时用拼音给函数或变量命名,这样做并不能说明你很爱国,却会让用此程序的人迷糊(很多南方人不懂拼音,我就不懂)。程序中的英文一般不会太
复杂,用词要力求准确。匈牙利命名法是Microsoft 公司倡导的[Maguire
1993],虽然很烦琐,但用习惯了也就成了自然。没有人强迫你采用何种命名法,但有一点应该做到:自己的程序命名必须一致。

  以下是我编程时采用的命名约定:

  (1)宏定义用大写字母加下划线表示,如MAX_LENGTH;

  (2)函数用大写字母开头的单词组合而成,如SetName, GetName ;

  (3)指针变量加前缀p,如*pNode ;

  (4)BOOL 变量加前缀b,如bFlag ;

  (5)int 变量加前缀i,如iWidth ;

  (6)float 变量加前缀f,如fWidth ;

  (7)double 变量加前缀d,如dWidth ;

  (8)字符串变量加前缀str,如strName ;

  (9)枚举变量加前缀e,如eDrawMode ;

  (10)类的成员变量加前缀m_,如m_strName, m_iWidth ;

  对于int, float, double 型的变量,如果变量名的含义十分明显,则不加前缀,避免烦琐。如用于循环的int 型变量i,j,k ;float 型的三维坐标(x,y,z)等。

2.2 使用断言

 
 程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。断言assert
是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况。以下是一个内存复制程序,在运行过程中,如果assert
的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。

//复制不重叠的内存块
void memcpy(void *pvTo, void *pvFrom, size_t size)
{
void *pbTo = (byte *) pvTo;
void *pbFrom = (byte *) pvFrom;
assert( pvTo != NULL && pvFrom != NULL );
while(size – - > 0 )
*pbTo + + = *pbFrom + + ;
return (pvTo);
}

 
 assert 不是一个仓促拼凑起来的宏,为了不在程序的Debug 版本和Release 版本引起差别,assert
不应该产生任何副作用。所以assert 不是函数,而是宏。程序员可以把assert 看成一个在任何系统状态下都可以安全使用的无害测试手段。

 
 很少有比跟踪到程序的断言,却不知道该断言的作用更让人沮丧的事了。你化了很多时间,不是为了排除错误,而只是为了弄清楚这个错误到底是什么。有的时
候,程序员偶尔还会设计出有错误的断言。所以如果搞不清楚断言检查的是什么,就很难判断错误是出现在程序中,还是出现在断言中。幸运的是这个问题很好解
决,只要加上清晰的注释即可。这本是显而易见的事情,可是很少有程序员这样做。这好比一个人在森林里,看到树上钉着一块“危险”的大牌子。但危险到底是什
么?树要倒?有废井?有野兽?除非告诉人们“危险”是什么,否则这个警告牌难以起到积极有效的作用。难以理解的断言常常被程序员忽略,甚至被删除。
[Maguire 1993]

  以下是使用断言的几个原则:

  (1)使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。

  (2)使用断言对函数的参数进行确认。

  (3)在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的
假定,就要使用断言对假定进行检查。

  (4)一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。

2.3 new、delete 与指针

 
 在C++中,操作符new 用于申请内存,操作符delete 用于释放内存。在C 语言中,函数malloc 用于申请内存,函数free
用于释放内 存。由于C++兼容C 语言,所以new、delete、malloc、free 都有可能一起使用。new 能比malloc
干更多的事,它可以申请对象的内存,而malloc 不能。C++和C
语言中的指针威猛无比,用错了会带来灾难。对于一个指针p,如果是用new申请的内存,则必须用delete 而不能用free
来释放。如果是用malloc 申请的内存,则必须用free 而不能用delete 来释放。在用delete 或用free 释放p
所指的内存后,应该马上显式地将p 置为NULL,以防下次使用p 时发生错误。示例程序如下:

void Test(void)
{
float *p;
p = new float[100];
if(p==NULL) return;
…// do something
delete p;
p=NULL; // 良好的编程风格
// 可以继续使用p
p = new float[500];
if(p==NULL) return;
…// do something else
delete p;
p=NULL;
}

  我们还要预防“野指针”,“野指针”是指向“垃圾”内存的指针,主要成因有两种:

  (1)指针没有初始化。
  (2)指针指向已经释放的内存,这种情况最让人防不胜防,示例程序如下:

class A
{
public:
void Func(void){…}
};
void Test(void)
{
A *p;
{
A a;
p = &a; // 注意a 的生命期
}
p->Func(); // p 是“野指针”,程序出错
}

2.4 使用const

  在定义一个常量时,const 比#define 更加灵活。用const 定义的常量含有数据类型,该常量可以参与逻辑运算。例如:

const int LENGTH = 100; // LENGTH 是int 类型
const float MAX=100; // MAX 是float 类型
#define LENGTH 100 // LENGTH 无类型
#define MAX 100 // MAX 无类型

  除了能定义常量外,const 还有两个“保护”功能:

  一、强制保护函数的参数值不发生变化

  以下程序中,函数f 不会改变输入参数name 的值,但是函数g 和h 都有可能改变name的值。

void f(String s); // pass by value
void g(String &s); // pass by referance
void h(String *s); // pass by pointer
main()
{
String name=“Dog”;
f(name); // name 的值不会改变
g(name); // name 的值可能改变
h(name); // name 的值可能改变
}

  对于一个函数而言,如果其‘&’或‘*’类型的参数只作输入用,不作输出用,那么应当在该参数前加上const,以确保函数的代码不会改变该参数的值(如果改变了该参数的值,编译器会出现错误警告)。因此上述程序中的函数g 和h 应该定义成:

void g(const String &s);
void h(const String *s);

  二、强制保护类的成员函数不改变任何数据成员的值

  以下程序中,类stack 的成员函数Count 仅用于计数,为了确保Count 不改变类中的任何数据成员的值,应将函数Count 定义成const 类型。

class Stack
{
public:
void push(int elem);
void pop(void);
int Count(void) const; // const 类型的函数
private:
int num;
int data[100];
};
int Stack::Count(void) const
{
++ num; // 编译错误,num 值发生变化
pop(); // 编译错误,pop 将改变成员变量的值
return num;
}


2.5 其它建议

  (1)不要编写一条过分复杂的语句,紧凑的C++/C 代码并不见到能得到高效率的机器代码,却会降低程序的可理解性,程序出错误的几率也会提高。
  (2)不要编写集多种功能于一身的函数,在函数的返回值中,不要将正常值和错误标志混在一起。
  (3)不要将BOOL 值TRUE 和FALSE 对应于1 和0 进行编程。大多数编程语言将FALSE定义为0,任何非0 值都是TRUE。Visual C++将TRUE 定义为1,而Visual Basic 则将TRUE定义为-1。示例程序如下:

BOOL flag;

if(flag) { // do something } // 正确的用法
if(flag==TRUE) { // do something } // 危险的用法
if(flag==1) { // do something } // 危险的用法
if(!flag) { // do something } // 正确的用法
if(flag==FALSE) { // do something } // 不合理的用法
if(flag==0) { // do something } // 不合理的用法

  (4)小心不要将“= =”写成“=”,编译器不会自动发现这种错误。

  (5)不要将123 写成0123,后者是八进制的数值。

  (6)将自己经常犯的编程错误记录下来,制成表格贴在计算机旁边。


3 小结

 
 C++/C 程序设计如同少林寺的武功一样博大精深,我练了8
年,大概只学到二三成。所以无论什么时候,都不要觉得自己的编程水平天下第一,看到别人好的技术和风格,要虚心学习。本章的内容少得可怜,就象口渴时只给
你一颗杨梅吃,你一定不过瘾。我借花献佛,推荐一本好书:Marshall P. Cline 著的《C++ FAQs》[Cline
1995]。你看了后一定会赞不绝口。会编写C++/C
程序,不要因此得意洋洋,这只是程序员基本的技能要求而已。如果把系统分析和系统设计比作“战略决策”,那么编程充其量只是“战术”。如果指挥官是个大笨
蛋,士兵再勇敢也会吃败仗。所以我们程序员不要只把眼光盯在程序上,要让自己博学多才。我们应该向北京胡同里的小孩们学习,他们小小年纪就能指点江山,评
论世界大事。

中文汉字替换为汉语拼音 的函数

from:http://www.donews.net/chenlq/archive/2005/05/13/378222.aspx

写此文使我很为难,一是担心读者误以为我轻浮得现在就开始写自传,二是担心朋友们误以为
我得了绝症而早早留下遗作。不论是落俗套还是不落俗套地评价,我在大学十年里都是出类拔萃的好学生。并且一直以来我对朋友们和一些低年级的学生们都有很大
的正面影响。这十年是一个从幼稚到成熟的过程,交织着聪明与蠢笨、勤奋与懒散、狂

热与怯懦、成功与失败。做对了的事可树立为榜样,做错的事可挂作为警钟。我写下经历与感受,期望以此引导和勉励无数比我年轻的学生们。我资历尚浅,既没有哲学家的深遂,也没有诗人的风华,不足以堂皇地育人,只能讲一些故事以表心愿。

 
 我出生在1973年的春节,属牛,是“牛头”。父母为我起了很好听的名字叫“林锐”。这一切暗示着上天对我别有用心,将降大任于我,可是这时候上帝去了
一趟厕所。天堂与人间的时差如此之大,就在上帝大小便的几分钟内,我混混沌沌地度过了童年和少年,天才因此成为凡人。

  我小时候生
长在浙江黄岩的偏僻山区。父母都是中学教师,由于山区师资缺乏,父母经常要从一个山头调到另一个山头教学。我换读过的小学的数目比我的年龄还大,没有伙
伴,也没有家的概念。我就象活在货郎担里的小鸡,缩成一团,在高兴或恐惧时至多“啾”“啾”地叫几声。我在读小学与初中的8年里,既不聪明活泼,也不调皮
捣蛋,确切地说象块木头,简直是我名字的反义词。在学习上我没有受过一次表扬,也没有任何值得留念的人或事。无论我现在多么努力都已无法追回失去的8年金
色年华,好心痛!

  我草草地并且稀里糊涂地在13岁时从初中毕业,无处可去。这下我发慌了,开始渴望学习。我灰溜溜地离开山区,可
怜巴巴地到一个比较好的乡下中学重读初三。我勤快得早晨4:30就起来读英语,脑袋似乎也被吓开窍了,“数理化”学得很好,并且生平第一次在物理考试中得
了满分。当我再一次从初中毕业时,我以全校第一的成绩考入了黄岩中学读高中。

  黄岩中学分农村班与城市班,我当然是农民阶级。“阶
级区别与歧视”对我是相当有促进作用的。我连任了几年的卫生委员,星期六和星期天同学们习惯地把活留给我,我这小官当得有滋有味。《物理》学得极好,有一
种直觉帮我快速准确地解题,常常是老师刚把题目写完我就报出答案来。上物理课时我没法讲废话,因为我一开口就是标准答案。

  可惜我
的文科成绩极差。那时期盛传“学好数理化,走遍天下都不怕”,我们年少不懂事,糟踏了学文科的好时光。我写作文的最高目标就是不逃题,考试前我总是反复祈
祷:我没干过坏事,保佑我作文不逃题吧!历史考试时填写“任课老师某年某月某日在我家乡英勇就义”,比谁的成绩更接近零分。更让我沮丧的是,这些行径都不
是我发明的,我顶多是个跟屁虫而已,一点回忆时的自豪感都没有。

  我现在认为文科教育实质是素质教育,如果素质不高,男孩再聪明也难以成大器,当然也难以吸引好女孩。


考时我语文得了54分(是班里的中上水平),总分只比重点线高十几分。我不敢报考好地方,只好选择内地。选来选去只觉得西安与成都两个城市还不错,我拿把
尺子在地图上一量,发现我家乡离西安的直线距离较短,于是就选了西安。老师们只听说过西安交通大学比较有名气,但谁也不了解。我以为在西安交通大学是学习
开火车、开轮船的,尽管我也很渴望能开车开船,但考虑到自己的身材单小,就忍痛割爱了。我觉得西安电子科技大学的名字很好听,符合我做科学家的梦想,于是
就报考西安电子科技大学(以下简称西电)技术物理系。

  上帝精神拌擞地从厕所回来,发现我已经上大学。也许他原先是把我安排在清华或者北大的,但事已至此,干脆也就撒手不管了。他这一偷懒反而是好事,我在读大学的十年中自由发展,成了卓而不群的学生。

 
 刚进西电,首先吸引我的是麻雀和馍。那麻雀滚圆滚圆的,简直是会飞的肉弹。它们不怕人,成堆聚集吵闹,常让我误以为是没有教养的一群鸡。那馍又白又大,
既不盐也不放糖,既不象馒头也不象包子。馍凉了后贼硬,据说有同学被楼上扔下的半块馍砸中脑袋,当场长出一个“肉包子”。最好笑的是人们把“馍夹肉”叫成
“肉夹
馍”,那东西实在好吃。

  西电原是军校,作风严谨,校园并不华丽,生活有些单调。尽管我来自山清水秀的地方,可我
的确喜欢西电的粗犷与憨厚。有一天我看到一个新生写的很肉麻的赞美西电的大字报,有一句是“我踏上了东去的列车”,我不禁笑掉牙。这一笑意味着“大个子欺
负小个子”历史的结束,“小个子欺负大个子”新纪元的开始。

  上大学的第一个学期刚好碰上美国打伊拉克(“沙漠风暴”行动)。那时全国都在谈电子战,我们全校都是研究电子的,而且以军事应用为主。在那种气氛里,同学们都有很强的使命感,并且被鼓动得信心十足。 
  
  一日,系主任视察早读,偏偏有同学迟到。系主任喝问:“你为什么迟到了?”
  “因为我来迟了,”同学毫不含糊地回答,昂然入座。

 
 我在班里年龄最小个子也小,上课时就象猩猩堆里的猴子那么显眼。由于我们是物理系学生,第一学期的《普通物理》课程就显得非常重要。系副主任给我们上
课,他长得象叶利钦,口若悬河,板书极快。象在高中上物理课那样,我常在“叶利钦”刚写完题目时就报出答案。开头几次,“叶利钦”满脸疑狐地扫视我们,好
像是要抓住拔掉他自行车气门芯的那个捣蛋鬼。后来他在第一排发现了我,我俩乐得裂了嘴。课间候息时,“叶利钦”常坐在我旁边,乘他给同学们答疑时,我就用
笔拔弄他硕大无比的手指,在他指甲上涂点什么。

  在第一学年,我就象乱草丛中的野花那样脱颖而出,倍受老师和同学们的关怀。就在我
光荣到感觉屁股都能绽放光彩的时候,发现了令我胆战心惊的学习缺陷——不会做实验。一进实验室,我就束手无策,浑身发抖。我相信大一的学生都有虚荣心,为
了维护“最聪明”这个荣耀,我完全可以掩盖、躲避甚至偷偷地弥补实验能力的不足。

  我做了一件了不起的事:为了对抗虚荣的引诱,我夸张其辞地把“缺陷”告诉每一个我认识的人,让我没有机会欺骗自己。

聪明的人并不见得都有智慧,他可能缺乏“真实”这种品质。虽然我是在硕士毕业的时候才立下誓言——“做真实、正直、优秀的科技人员”,但我在18岁的时候就已经做到了“真实”,我必定一生保持。

  第一年暑假回家,得到一个惊喜:家里竟然有了电路实验室!

 
 因为我常在信中鼓吹自己实验能力何等之差,“长此以往,下场将极为悲惨”。父母经不起这种“恐吓”,教英语的父亲将半年的工资连同“私有财产”全部捐
出,每周到很远的商品交易市场购买电子元件以及器材,在家里建立了实验室。父亲很威严,我从小就怕他,但那个暑假我一点也不怕他。我们一起做实验,都从零
学起,话不投机就用电烙铁“交流”,完全是同事关系。后来,我的兴趣转向了计算机,家里的实验室就由父亲独掌,继续发扬光大。现在父亲修理电器的水平在家
乡远近闻名,学生们都忘了他是英语教师。

  母亲是数学教师,年轻时略有姿色,智力远胜父亲。当她与他在山头的学校里相遇时,他一顿
热情洋溢的饭菜就把她缴械了。我小时候家里很贫穷,家就象一条飘荡的小船,父亲划浆,母亲掌舵。当我6岁上学时,母亲就说:“儿子啊,你将来只能靠笔吃饭
而不能靠锄头吃饭。”小时候,母亲怕我变狡诈而不允许我学下棋。尽管我在大学里已经相当出色,母亲来信总不忘叮嘱“德智体全面发展”。她常用独特的方式检
查我:

  (1)看我是否变胖。如果我胖了,表明我懒了。因为勤奋的人没有理由变胖。
  (2)看我说话是否还快。如果我说话慢条斯理,表明我变笨了。因为脑子灵活的人没有理由说话不快。

  我读博士研究生时,母亲的眉头才舒开。她经常在师生中发表自由言论:“儿子的智力与性格完全是我遗传的,他爸毫无半点功劳。” 

  第三学期的主要课程是电路分析。电路题目常常很滑稽,当你满头大汗地解完方程时,答案往往是零。我归纳了不少公式用于简化计算,所以照样能在老师画完电路图时报出答案。学习是如此的轻松以致于我有太多的课余时间。
  在课余我常做两件有意思的事:
  (1)我为学习较差的十几名同学办了补习班,给他们讲课,改作业,出考题。我就象老母鸡那样看护着一群小鸡,使班长、学习委员等班干部形同虚设。我这样做既提高了自己的表达能力,又帮助了同学。这事不是老师叫我干的,是我自己的主意。
  (2)我经常在宿舍里焊接电子线路,技艺渐精。我曾花了两天时间,把磁带盒做成能发声、发光的精美礼物,乐颠颠地送给一个女孩子。可惜不久后我迷上了计算机,从此再也没亲手做过好玩的东西。

 
 上大学以前我根本没见过计算机。在第四学期时我遇到了十年来最敬爱的老师周维真,从而对编程产生了强烈的兴趣。他教我们Fortran语言,
Fortran语言对我没有影响,影响我的是周老师高尚的师德以及他在教学和科研中的敬业精神。我从他那里学到的是怎样做人,怎样做学问。

  很多计算机系老师改作业时喜欢打“√”或打“×”了事。周老师不仅把作业里的错误都找出来,而且逐一评注“好在哪里”和“差在哪里”。为了不让周老师过于劳累,全系同学有一个约定:上课时不准吵闹,否则别来;作业必须清楚,否则别交;提的问题必须有质量,否则闭嘴。

Fortran
语言期末考试,我的卷面成绩是97分,有个女同学考了99分。我当时官为课代表,想不到被一个女生超过,甚为沮丧。可是报到系里的成绩单上,我的成绩是
99分,那个女同学是97分。我以为周老师搞错了,跑去问他。周老师笑笑说:“你平时的学习表现,该得满分。不能因为考试中的一个失误而打击你的积极性,
所以给你加2分作为鼓励。而她一上机就束手无策,要让她知道考试成绩高并不表示已经学好了,扣她2分以示警告。你本来就是第一名。”这时又跑来一个“查”
成绩的同学,他得了59分,哀求周老师让他及格。周老师说:“你的试卷我看了好几遍,的的确确是59分。而你平时的学习表现也不会超过59分。这一分不能
加,否则我会害你一生。”
  在我这一级(90级),周老师至少为技术物理系教出两名软件高手——我和马佩军。我和马佩军读到硕士时已在软件
方面雄霸西电,计算机系学生毫无翻身之望。由于马佩军不好名利,风头让我一人独得。我离开西电数年后,余威尚在。可惜我和周老师相处不到一年,他便调到北
京信息工程学院。然而师恩的厚薄不在于时间长短,好的老师会让人想念、感激一辈子。
  在上大学的前三个学期,学习如同表演,有趣而且轻松。自从第四学期学习了计算机课程,我就有了新的追求,我多么渴望拥有一台计算机,可以天天编程。如果挨一个巴掌能换取一分钟上机时间的话,我愿意每天挨1440个巴掌。如果非得加上一个期限不可,我希望是一万年。
  我本科的专业是半导体物理,一二年级由系里负责教学,三四年级由微电子所负责教学。在第四学期末,我央求系里把我推荐到微电子所参加科研,贾新章教授“收留”了我。我踏进微电子所的那一脚,让我从纯粹学习转向了科研,从“高分低能”转向了“低分高能”。
 
  我终于有了一台286电脑,那个暑假我就睡在实验室里,时时刻刻守着它,深夜里我一个人冲着它发笑,一会儿盖上布,一会儿掀开布,一会儿摸摸它的“脸”,一会儿理理它的“辨子”。我很快地完成了任务——设计一个“立方运算”的模拟电路,并且学会了C语言。

 
 西电有个好传统,每年冬季举办一次全校性的“星火杯”学生科技作品竞赛。每届都有六七百件作品展示,低年级的学生看后无不热血沸腾,跃跃欲试。我很希望
能独立开发一套软件,参加本届“星火杯”竞赛。贾新章老师是研究集成电路可靠性的,见我如此热切,就让我开发“集成电路可靠性分析软件”。

 
 我开始一边研究数值算法,一边设计软件。从炎热的8月份到发冷的十一月,几乎天天通宵编程,程序很快增长到一万多行。在离竞赛还剩一个月左右的时候,出
现了大量的问题。不仅程序老是出错误,而且发现原先的算法并不有效。此时已经没人能够“救”我。贾老师不会编程,不知道问题究竟出在程序上还是出在算法上
(实质上两者都有问题)。而那些懂软件开发的年青教师,实在看不明白我的上万行程序是如何组织的。他们只能悲伤地看着我挣扎。由于我经常逃课,好学生变成
了坏学生。系里意见极大,贾老师十分为难。不少老师和同学劝我赶紧“改邪归正”,放弃项目,不值得因小失大。

  当时我有个无法动摇的心念:如果放弃一次,那么碰到下一个挫折时我就会继续放弃;如果坚持而成功,那么碰到下一个挑战时我会激励自己再取成功。

 
 在压力面前,我依然坚挺。每当略有进展时,心里一阵狂喜,但很快又会碰到新的困难,有时一坐就是20个小时。每天在喜悦的颠峰与苦恼的深渊之间反复折
腾。在竞赛前二天,我终于成功地完成了软件研发,结果获得软件与论文两个二等奖。这个荣誉本身不值得一提,并且我付出很重的代价——对物理专业失去兴趣而
彻底抛弃了它。但那时我才19岁,在极限状态下,我磨练了意志,使我日后充满激情。


本科四年级,我认识了微电子所的郝跃老师。他是数学博士,是微电子所最有才华、最潇洒、最有领导风范的青年学者。我常去向他请教数学问题,他讲得意气风
发,我听得如痴如醉。我俩一个月的“交流量”很多硕士化一年时间也得不到。有一天,郝老师说:“你做我的学生吧。”我就毫不迟疑地从贾老师门下“跳槽”到
郝老师门下。郝老师后来是我的硕士生导师,他高兴时喜欢说:“好,很好,非常好!”我看着他升教授,升博导,升副校长,师生两人分别在各自的阶层中名声显
赫。

  在三四年级,我的专业课程没有一门及格过。但由于微电子所的老师们已经认可了我,就把我的卷面成绩作为及格线,我对同学们的帮助莫大于此!如果要我考研究生,我绝对考不上。系主任安毓英觉得我将来很有前途,于是不顾别人反对,一锤定音让我免试读硕士研究生。

 
 读硕士研究生后,我的科研条件相当好。导师十分开明,任我自由发展。我最喜欢做的事是设计图形用户界面和开发数据可视化软件。图形程序的最大魅力是即便
它毫无用处,你也可以自我欣赏。总有人担心“花很多精力、物力让界面那么漂亮,图形那么逼真是否值得?”这种问题不能强求别人与你一致。我当时赞美女孩子
的最高境界就是把她和我的图形程序相提并论。

  我喜欢设计用户界面是因为自己有相当好的美感。在读本科时我模仿过六七个流行软件的
界面,常常向同学演示、卖弄。觉得还不过瘾,就写了一篇名为“用户界面设计美学”的短文。凡是路过我实验室的同学都被我逮住,被迫听完我得意之极的朗读,
茫然者与痛苦者居多。不久我的朗读便所向披糜,闻声者逃之夭夭。

  我的研究工作基本上以集成电路的数值计算为主,数值计算产生的一
堆堆数据常把我搞得晕头转向。我发现用图形来表征、解释数据可以让自己不再迷糊下去,那感觉就象刚睡醒时冲凉水一样。我硕士学位论文中的软件就是用图形来
仿真集成电路生产过程中“缺陷”对成品率的影响。我并不是在看了学术论文后才开始研究可视化技术的,我是在做了工作后才发现那些好玩的技术叫做“可视
化”。由于我肚子里头的确有货,在硕士一年级,我没有使用“剪刀”与“浆糊”(这是很多人写书的法宝),只化了三个月时间就写完第一本著作《微机科学可视
化系统设计》。

  我在读硕士期间的工作强度与本科时的相当,但工作方式有很大不同。我有了明确的目标:(1)开发自主版权的软件产品;(2)培养做领导的才能。这个目标可以通过团队工作,参加全国性大学生科技竞赛而实现。

 
 我在西电成立了“可视创意软件小组”,马佩军、戴玉宏、马晓宇是我的主要技术伙伴,帮手很多(有几个漂亮的女生负责宣传)。办公室里贴满了标语,如“创
造性的事业要靠激情来推动”,“生于忧患,死于安乐”,“让春天消失”。还有大幅的“作战图”,倒计时牌。每个伙伴写了一张“军令状”放在机器上,我迄今
还记录着那些纯真、活泼、充满激情的文字。那是多么艰苦而幸福的日子,夜里放震耳欲聋的音乐、咬尖辣椒提神,有伙伴累得蹲在厕所里睡着了。

 
 在1994年和1995年的冬季,我们的软件作品分别获中国大学生应用科技发明大奖赛二等奖和全国大学生“挑战杯”学术科技作品竞赛二等奖,在西北地
区,我们是“老大”。我成了西电学生的榜样。如果你是西电学生,你可以不认识校领导(有名字的人并不见得就有名),但你不能不认识我,否则你就不是个好学
生。仰慕我的学生有一大批,我刚到浙大读博士学位时,收到一个西电计算机系学生的信,他说:“你走了,我呆在西电没有意思,我准备考浙大的硕士,你到哪里
我就跟到哪里。”

在硕士毕业前,我在鉴定表上这样写道:“我热爱科技事业,如同热爱生命一样。近5年的科研工作带给我最充实的生活,也寄托着我美好的向往。可我同时也感到了痛苦,因为5年来我耳闻目睹科研中太多的弄虚作假。我发誓:做一名真实、正直、优秀的科技人员,以正身自勉。”

  我在西电度过了幸福的6年半,最让我牵肠挂肚的是“吃”、“友情”和“爱情”。

 
 当我第一次吃红红的和青青的辣椒时,“感动”得满脸是泪,那滋味让我觉得前17年白活了。我在读硕士时已经能自力更生,我开发的软件不仅竞赛获奖挣了名
气,而且还挣了钱(卖了二十多份软件,平均每份挣500元)。写书得稿费7000元,那时我简直就是富翁。这些钱的小部分用来给女孩子买礼物,大部分用于
和与哥儿们吃香的喝辣的。
  我相信自己已经尝遍了西安的小吃,并且发现了一个真理:最好吃的东西都在地摊上,最香的东西一定是辣的,最辣的东西一定是香的。曾经沧海难为水,我在浙大的三年里很少再吃辣椒,因为怕它沾污我心目中的辣椒。
  
 
 在我小时候,我爸很讨厌土豆,他竟然因此不让我吃土豆。我哪敢跟他论理,于是忍啊忍,一直忍到我上大学“远走高飞”。如果说辣椒是我新交的女朋友,那么
土豆就是我天生的命(迄今尚未发现能让我不要命的食物)。我在西电经常用电炉(从来都没被抓住过)做“以土豆为核心”的菜,天长日久,朋友们干脆叫我“土
豆”。

  我吃饱土豆和辣椒后不免深思而感叹,人要是认认真真地吃,真的花不了多少钱,那些贪官究竟是怎么吃掉巨款的?我将来怎么吃得掉自己挣来的钱?

  我在读中学与本科时,满头白发,脑袋可以当白帜灯泡用。当我硕士毕业再照镜子时,吓了一跳,白头发不见了!我不知道究竟是哪种食物起的作用(估计是辣椒)。那些早生白发的小伙子们,你们就到西安上学吧。

  马佩军是我最早的朋友。刚入学时我们同住一个宿舍,他象国民党兵盘问良家妇女那样上下打量我,问:“喜欢干啥?”
  我怯生生地回答:“打乒乓球。”
  他再问:“什么风格。”
  我答:“快球。”
  他突然象阎锡山那样怪笑,拍拍我的肩膀说,“好!我喜欢,以后你就是我的朋友。我是陕西人,农民,会开拖拉机和卡车。这里是我的家,以后你有啥事,就对我吱一声。”

  马佩军和我打乒乓球时口中念念有词:“哼!你对我狠,我对你更狠;你对我好,我对你更好。”他好几次说要把世上最好吃的板栗送给我一袋,这一袋板栗我到现在都没拿到。

  马佩军夜里极能侃,吹他家乡的人跑得快,常把野兔追断气。有时他吹得太离谱,常令我们6人群起而攻之。为了把我们一举歼灭,他白天到图书馆查“资料”,夜里再挑起事端。双方就象印度与巴基斯坦,常干两个秃子争一把梳子的事。


佩军上大学前也没见过计算机,但他对计算机技术有极强的领悟力。我们第一次上机时,他把我拉到打印机旁边说:“帮我防着管机房的,我要修理这台打印机”。
还没等我反应过来,他就开始“肢解”打印机。我无比深刻地体会到:歹徒在作案时都不害怕,最提心吊胆的就是那个放风的。他在5分钟内修好了打印机,我佩服
得五体投地,甘愿下次再跟他干“坏事”。

  我一直认为马佩军是西电编程第一高手,他编程的时候根本不是人,是指针。之所以我的名气大,一是因为他不好名利,二是我把他的程序写上了我的名字(并且卖了不少钱)。

  马佩军的女朋友是我介绍的,我一眼就看出她将嫁给他。后来俩人果真结婚了,只是他嫁给了她。硕士毕业后,马佩军留在西电读博。前年我再见到他时,他说我害死他了,快乐得要宰了我。我喜欢陕西人源于马佩军。

 
 宋任儒是我们的班长,也是班里最早的预备党员,满口仁义之道,比唐僧还让人受不了。在二年级时,我迷上一个比我大一岁有了男朋友的女同学,多日沮丧。他
看在眼里痛在心里,跑去把那女同学教育了一通。苏联解体的时候他十分沉痛,在思想教育课上,他向我们作了深刻的检讨,好象是他没有管教好戈尔巴乔夫那小
子。最后他为我们点燃了希望:在不久的将来,“苏联”将重新成为苏联,共产主义旗帜将继续在全世界飘扬。

  在本科三四年级,他对跳舞十分入迷,连上厕所都滑翔而去。我那时常把自己关在实验室里搞科研,极少有空与他玩乐,等到本科毕业时,猛地发现他已经风度翩翩。
  
  宋任儒的学习既不好也不差,我们从来没有合作研究过什么。我喜欢他是因为他很有情趣,不落俗套。也许,我俩本来就是“敢爱而不恨”的同一类人。

  本科毕业时,他分到威海工作,走之前我为他饯行。可在硕士开学时,我的房门被人一脚踢开,他对我喊了一声“林子啊,我又回来了”。我就象祥林嫂见到了被狼叼走的孩子。

 
 宋任儒读硕士时被发配到临憧771所,他在那里过上了乐不思蜀的日子。有一天,他带来两个文静的女孩子(一个读硕士,一个读本科)来串门。就在我洗水果
的几分钟里,三个人已玩得乐翻了天,两个女孩满屋子追他,一会儿把他按到桌子上打,一按到床上打。我惊诧之极而又羡慕之极,恨不得挨打的人是我。想不到上
学竟然会有这等欢乐,看来我读硕士的日子白过了。

  后来,那个大一点的女孩子嫁给了他。当他带她去见公婆时,公公长叹一声:“把儿子交给你,我就放心了。”而婆婆已乐得合不拢嘴,竟然无法叹气。

  现在,宋任儒已从复旦大学获得博士学位,比我更早地成家立业。他和她既是夫妻,又象兄妹,还象伙伴。他叫她“聪聪”,她叫他“笨笨”。

  “聪聪”问“笨笨”:“老公啊,人活着为了什么?”
  “笨笨”答:“就是让咱们每天快快乐乐。”

  我迄今亲眼看到的幸福莫过于此。


我在大二时曾为系里学习最差的十几名同学办了补习班,谢伟在这个补习班里名列倒数前茅。在他睡懒觉时,我象催命鬼那样喊他捅他。他无比吃力地抬起沉重的眼皮,就象软弱无力的举重运动员,还没有挺起来就趴下了。

  他开始呻吟:“这一次就饶了我吧,下一次我一定一定会去的,求你了。”
  我不肯。
  “那么让我再睡5分钟,”他不死心。
  我仍不同意。
  “那么你就从1数到10,要慢一点,”他讨价还价。
  当我数到9时,他就接着数9.1,9.2, 9.3 ……

  一开始他觉得我很好玩,后来他就喜欢得离不开我了。并不是因为我学习好,而是那时侯我天真并且充满活力。在三四年级我忙于科研时,他照顾我的生活,叫我“少爷”,既做管家又做兄长。我们不仅共用饭菜票,并且共用仅有的一个碗,总是他买饭菜和洗碗。

  我们那一级的学生大多崇拜巨人公司的创始人史玉柱,我问谢伟:“我是不是和史玉柱一样能吃苦?”
  他说:“如果考虑年龄因素,你已经比他更能吃苦。你将来一定能做大事业,我就把希望寄托于你了。”

  在我们都还不成熟的时候,我成了他心中的灯塔,只要灯不灭,希望就在。现在他为了娶一个日本姑娘,披荆斩棘追到日本,有了新的希望。
  二十几年来,我就为一个男人哭过,那时他本科毕业。

  我读硕士研究生时,由于受我的影响,本系三四年级的学生蜂涌至微电子所参加科研。夜里看十二层高的科技大楼,灯火通明、热闹非凡的那一层就是微电子所。那时,我在微电子所学生中的地位仿佛伊拉克的萨达姆,手下兵将极多。

 
 我写第一本书时,有几个人老向我伸着手等待输入稿子,就象火车站行乞的人那样阴魂不散,使我没时间慢腾腾地打草稿。我就象金庸写小说,有如神来之笔,想
到那里就写到那里,写了一段他们马上输入一段,一气呵成。那本科技书写得很滑稽,同学们看得笑出眼泪,编辑看了拍案叫绝,只改了几个字就出版了。

  那时侯我的心情是如此之好,为一男同学乱蓬蓬的头发写了一篇散文,并送他一把梳子。又把一女同学的实验报告写成评书。我的文笔大概就是这样练出来的。

这一群学生中,戴玉宏、史江一和马晓华是我最好的伙伴(我们都属于牛)。

 
 戴玉宏其貌甚帅,眉中有一根白毛闪闪发光,因此号称“白眉鹰王”。“白眉鹰王”武功了得,是我软件产品的核心开发人员,我们合作最深最久。后来我开公
司,他就从广州辞职到杭州为我助威,令我感动不已,可见读大学时期我们有多铁!戴玉宏有一次打饱嗝,整整打了两天两夜,我差点心疼死。

 
 我尚未发迹之日曾与戴玉宏在校园里卖花,无人问津,就请电子工程系的鲁洁救助。鲁洁温柔貌美,她一言一笑尤如春风吹拂苏堤的杨柳,令人心里一荡再荡。顷
刻间就有男生围观,有人看花,有人看“贵妃”,鲁洁一走,我和戴玉宏可怜得就象两根蜡烛。鲁洁读大学时调皮捣蛋,到四年级时还不太会编程。她的本科毕业设
计是仿真“雷达跟踪飞行物”,程序基本上全是我编写的。我已记不起用了什么公式,只知道每次计算后都弹出一个对话框“报告长官,击中目标”。鲁洁毕业后到
深圳的一家软件公司工作,几年一过,她成了行家。再与她交谈时,我只有听的份,象鸡琢米一样点头。

  史江一和马晓华都是狭西人,和马佩军一样厚道热情。史江一性格稳重,属于“你办事我放心”的那类人。我对微电子专业一窍不通,全靠他帮我混过实验这一关。后来我开公司失败,陷入经济危机,就把希望工程的一个小孩托给了他。
 
 
 马晓华是我最不放心的人。他常常为别人做事情,但热情过头就忘了自己的事情。有几个不道德的学生就利用他的这个缺点,经常使唤他,并且借他的钱不还。马
晓华喜欢为那些人“卖命”并且挨训,他总是在受虐待够了的时候再跟我们嘀咕,我们实在气不过,只好对着他的屁股追加一顿拳脚,并给他一个绰号“受虐狂”。
但愿他找个好老婆,我可以早日放心。

  我们这一群小伙子同时喜欢上一个女孩子,她叫姜姗,是她班里的四大美人之一。我们不仅没有争
风吃醋,而且心甘情愿地让她坐遍每个人的脖子。姜姗小姐5岁时她爸姜晓鸿成了我的同事,我们经常一起去钓鱼,亲得象一家人。姜姗喜欢大喊大叫,声音高过帕
瓦罗蒂,我们教唆她喊她爸“姜球球”。

  我常带姜姗到小炒摊去吃女孩子不敢吃的东西,并哄她:“世上最好吃的东西是鸡屁股。”
  她无师自通地加上一句:“世上最好听的屁是鸡放的屁。”

  我常想着将来生个儿子并把他培养成天才,但如果能有姜姗这样的女儿,不要儿子也罢。

在本科三年级我第一次参加“星火杯”竞赛并获得软件二等奖后,马上成为低年级学生眼中的明星。我义务当上了一年级学生的上机辅导员。一天晚上我巡视机房,一女生请求帮助。

  我见屏幕上空白一片,根本没有一行程序,十分疑惑地问:“什么问题?”
  “没有问题。”她把书往我手上一塞说:“这些作业你帮我做。”然后就自个子跟她的同学玩乐,把我撇在一边,似乎我辛辛苦苦地学习就是为了给她做作业。

  我定神对她细看,发觉她简直就是《射雕英雄传》里的黄蓉再世,顿时心就“突突突”直跳。当天晚上我没睡着,接下几天的课不知所云。在选修课《操作系统》考试时,我给家里写了一封超短信:请快寄钱来,我谈恋爱了。我交了白卷直奔她去。

 
 我的初恋只有两个月,却让我思念了8年。她离我而去时没有任何理由,而我却失魂落魄。在我本科毕业前的18个月里,白天我狂热工作强作笑容,夜深人静时
心痛如刀割而无法抑制。没有人为我“疗伤”,我是硬挺过去的,这一段经历使我日后心理承受能力极强。后来我开公司的失败虽然对信心有所打击,但根本无痛可
言。

  我们分手后并未成为陌生人,就象两只刺猬,离得远了就有点留恋,离得近了,就刺着对方。认识她时我虽然已略显才气,但并不具备成熟男人的魅力,很多事情我并不知道怎么去把握。有时“喜欢”并不能成为“爱”,感情也许是永远研究不透的学问。
 
 
 我读硕士研究生时有了一群生机勃勃的朋友,感情的伤痛被掩没了。朋友堆里夹着一位女生,她文雅而富有气质。平日里无拘无束,大伙戏称她是我的秘书。我的
言行举止和穿着都经过她的调教,俩人出双入对,十分亲近,不知不觉有了感情。别人已经把我们当成恋人,我和她牵着小姜姗散步时,简直就象天堂里的一家人。
她的温柔有时能让我失去所有斗志。

  可是我当时着迷于事业,认为自己不久将干一番惊天动地的事。鉴于史玉柱在创业时就离过婚,所以我认为感情是事业的累赘,两者不可得兼。

 
 更糟糕的是,我和第一个朋友耦断丝连,偏偏她俩是同班同学。我知道脚踩两只船没有好下场,可我的的确确同时喜欢着两个人,并梦想她俩能合二为一。我情愿
被人指责,也不愿掩饰真实的感觉。有时她俩一同走过,我站在路上丢了魂似的看着俩人的背影,任凭看热闹的人指指点点。

  我和第二个朋友已经有了很深的感情,她毕业后我曾坐火车千里送鲜花给她,让GOG她感动过。而我固执的性格和对初恋的思念终于让她心碎。尽管我们已经几年没见,我依然看得见她留在我心里的那颗眼泪。

  我在西电六年半的学习和生活也许是一生中最珍贵的,叫我怎能不爱西电。

两年前我回西电,惊奇地发现校园里房前屋后长满了待收割的小麦!这所大学是事电子科技的,种小麦干啥呀?
  朱总理曾讲过:“目前国家粮食充足,再来三年自然灾害也不怕。”现在国泰民安,似乎用不着“深挖洞,广积粮”吧。我素知西电提创勤俭节约、自力更生,但与其种小麦还不如种蔬菜呢。

 
 老同学告诉我,种小麦是为了应付“211”工程(为21世纪选拔100所重点大学)的检查团,因为“211”工程有较高的绿化指标。偏偏检查赶在冬天,
那时的西北极难草。西电本来就人多地少,地上一长草马上就会被谈恋爱的学生给折磨死。一到冬天,整个校园就光秃秃一片。用小麦绿化校园可谓千古绝笔,检查
团的那些权贵人士早已五谷不分,岂知所见的“草坪”乃是麦田。

  浙江大学依山而傍西湖,是个美丽而高贵的大学。1997年春天,我
就象干儿子那样挤进她的怀抱,并期望得到关爱。我到了向往已久的计算机辅助设计与图形学(CAD&CG)国家重点实验室读博士学位。导师是石教英
教授,石老师虽然年过六旬,但精力充沛,红光满面,施拉普纳不及他半分精神。

  我幸福地幻想着大干一番自己喜爱的专业,并计划在35岁左右成为实验室主任。开学的第一天,我兴冲冲地奔向实验室。进门不到5分钟,就因不懂规矩被看门的年青女子训了几次。为了不再冒犯规矩,我就老老实实地抓起一份计算机报纸并且站着阅读,心想这下不得罪谁了吧!

  突然一个气得脸色铁青的男人(机房管理员之一)对我断喝:“你在干什么!你怎么可以不经允许就翻看别人的报纸!”似乎我是他一生中见到的最无耻的人。

 
 我就象一个情窦初开的少年飘飘然地去拥抱梦中情人,不料迎来两个耳光,此下场比《猫和老鼠》中的猫还惨。如果这两个年轻人有幸看到我这篇文章,应该好好
悔过自新,她与他的工作态度打击过数十个学生的积极性。我本是因为向往CAD&CG实验室而来的,得到的却是极坏的第一印象。

  不出几日,我就发现实验室里人们大多轻言寡语、小心翼翼、井水不犯河水。初到此实验室的北方同学极为迷惑地问我:“你们浙江人是不是都这个德性?我看你不太象嘛。”

 
 也许你以为我以前的研究单位很土,刚到高贵的CAD&CG实验室,有点象刘姥姥那样无所适从,甚至有点自悲。非也,西电微电子所的设备、人员超
过CAD&CG实验室数倍,我在微电子所的办公室就比CAD&CG实验室主任的还好。比物质条件是没有任何意思的,学生渴望的是自由、欢
乐的环境,这样才能激发他们的创造力。压抑的环境会把一
个本来充满活力的年轻学生变成一群小老头,他们只好套上硕大的眼镜以显示眼里的世界有多么渺小。

  如果不允许一个男人在工作时仰天大笑,这样的地方不去也罢。

  我颇费周折地考入CAD&CG实验室,却尚未热身就全力而退,决心自立门户。至今我都没有用实验室的计算机编过一行程序。


读博时我穷困潦倒,只有一床,一盆,一壶,一碗。我那些穷朋友们象挤牙膏一样挤一些钱资肋我。我买了一台计算机,在宿舍里开发软件产品“可视化软件开发工
具 VA
4.0”。1997年8月,我去北京参加首届中国大学生电脑大赛软件展示,路费也是借的。同学为我壮胆时说:“如果不能获奖,就回到实验室干活吧。”

  我说一定会拿第一名,不然去干啥。

 
 在软件展示时,我们发现很多好的作品是国家的科研项目,根本不是学生个人的作品,违背了竞赛的宗旨。如果允许这样做的话,我应该运几条生产线过来。我写
了一份抗议书,找了十几个人签名(很多人感恨而不敢签)。但抗议能顶屁用,我参加过的科技竞赛、见过的科研鉴定多了,哪一次我没看到虚假?我写抗议书是因
为眼里容不得沙子。如果我的专业是政治,早就坐牢去了。

  这次竞赛选出十个“软件明星”,只有我的软件和清华大学博士生的项目值得一看。

 
 我不能否认他的项目水平极高,但那不是他个人的作品(评委甚至认识他的导师,知道项目的来龙去脉)。我的作品被评为第一,他的项目被评为第二。组委会来
拍电视,可是找不到浙江大学的展板。因为浙江大学没有任何准备,我是一个人来的,我的作品夹在杭电的作品之中,没名没姓。我只好从塑料袋上剪下“浙江大
学”四个字,贴在展板上撑撑门面。

  自新中国成立以来,清华大学就一直在浙江大学头上“作威作福”,我好歹也争了一口气。可是颁奖时,组委会竟按地方顺序从北京念起,我沦落到第七,差点咽气。

  我曾在上海的一辆公共汽车上与一位北京来的旅客聊天,此公极健谈。似乎他到上海旅游的目的就是为了发掘北京的优越性。见我挂着浙江大学的红色校徽,且对清华、北大并不神往,不禁十分迷惑,就问:“浙江大学在浦东还是浦西?我要去看看。”

  北京已经是极度优越了,那里的处长局长比我见过的土豆还多。就请不要把什么鸡皮蒜毛的好东西都拿走,给我们留点希望吧.

 
 1997年11月,在穷得快挨饿的时候,我获得了中国大学生跨世纪发展基金特等奖(全国共20名,奖金1万元)。在人民大会堂领奖时,我以为能碰到宋健
等人物,不料见到的却是政协的人手,不禁甚为失望。给我们出钱的是一个靠资本运作发财的集团,在宴会前,该集团领导人和我们座谈,他什么不好吹偏偏吹自己
是个高科技企业。
  
  刚拿了“跨世纪发展基金”,又马上获得“浙江省青少年英才奖”,浙江大学也给我发奖学金。比起那些一个月只
有300元工资的博士生们,我简直是“暴富”。还了朋友们给我的“救济款”后,仍然是个“富翁”。我老是觉得手头的钱是抢劫来的,心不踏实。于是找浙江大
学校团委“诉苦”,请校团委把我的“不义之财”捐给浙大的困学生。校团委的老师热情而坦诚,说愿意等我成为真正的富翁时再接受捐款,现在不能让我“杀鸡取
卵”。但为了能让我表达心意,建议我资助“希望工程”的中学生,让我选了5个初一的学生,每个学生500元。我轻浮地以为自己真的帮助了5个中学生,直到
1998年暑假我见到了其中的一个中学生,才发现自己做的好事只不过杯水车薪而已。我是到了自己贫困失意时才真正去帮助那些孩子的。

在1997
年,我在学生时期的荣誉已登峰造极,觉得自己的翅膀已经硬了,不想再混下去。我总以为自己是第二个史玉柱,应该开个软件公司来振兴民族软件产业。我曾到东
软集团(沈阳)参加“民族软件产业青年论坛”,大不咧咧地作了一次演讲(现在现演讲的内容没有一项是可以操作的)。杭州有一个记者来采访我,我谈了一天的
理想,记者还是没听明白,干脆自己写新闻报道,并且含蓄地做了一个广告:万事俱备,只待投资。

  由于我能说会道,频频上电视,引来
近10个投资者。我选择了一位年龄比我大一倍、非常精明的商人作合伙人,成立了“杭州临境软件开发有限公司”。彼时,我可谓光芒四射,名片上印着“以振兴
民族软件产业为已任,做真实、正直、优秀的科技人员。”浙江大学想开除我,被我“晓之以理、动之以情”安抚住。

  我当时想开发一套
名为Soft3D的图形系统,此系统下至开发工具,上至应用软件,无所不包。公司名字起为“临境”有两个含义:一是表示身临其境,这是我对图形技术的追
求;二是表示快到了与SGI公司称兄道弟的境界,这是我对事业的追求。“临境”这个名字我在读本科时就已经想好了,1997年底公司成立的那一天,我有一
种“媳妇熬成婆”的悲壮感觉。

  我从实验室挖来一位聪明绝顶的硕士生做技术伙伴。他叫周昆,年龄很小(1978年出生),研究能力
极强。如果按照浙江大学计算机系博士生毕业的论文要求,他入学硕士的那一天就可以博士毕业。周昆的头明显比我的大,估计其脑容量至少是我1.5倍。我曾经
以师兄的身份为他洗过一双袜子,他因此觉得我是个好人。我俩一拍即合,常常为Soft3D的设计方案自我倾倒。一想到Microsoft公司的二维
Windows系统即将被Soft3D打击得狼狈不堪时,我们就乐不可支,冲劲十足。

  我已经把“振兴民族软件产业”列入日程,并
且提前担忧将来钱挣得太多用不完该怎么办。1998年5月份,我们做了一套既不是科研又不全象商品的软件。软件产品宣传了几个月,并没有出现订单如潮、接
应不暇的局面(事实上压根就没有反应)。我意识到没有找对市场,但仍觉得产品中的一些技术很有价值,将它改装成其它软件也许能开创“东方不亮西方亮”的新
局面。

  于是我向只有一面之缘尚在北大方正工作的周鸿一求助。他是真正的软件高手,当我小心翼翼地展示约10万行C++代码的软件时,他竟在十几分钟内就指出多处重大的设计错误,使我目瞪口呆地意识到整个软件系统的价值为零。那种心痛啊,就象眼睁睁看着孩子被狼吃掉一样。

  到1998年10月,我用光了30万元资金。周鸿一再一次从北京飞到杭州,三下五除二替我把只活了一年的公司给关闭掉。他放心不下,觉得我“恶病需用猛药补”,于是意尤未尽地把我捉到北大方正插在他管辖的部门,让我学习怎样做事情。

  北京寒冷的冬天可以营造一种凄凉的气氛,冲去一切可以自我原谅的借口。我并不是太爱虚荣的人,知道这次失败是我的毛病积累到一定水准忍不住喷发出来的结果。我绝不能以年纪尚轻不太懂市场与管理为理由轻率地敷衍过去。

 
 从北大方正“劳改”了两个月回来,我心服口服地承认失败了。我把察觉到的数十个毛病列出来,日后一个一个克服掉。我写的《软件工程思想》一书,大部分内
容取自我开公司失败的教训录。我现在能客观地从可行性分析角度说明我和投资方所犯的主错误,以祭我那幼年夭折的软件公司。

我的主要错误:

  (1)年青气盛,在不具备条件的情况下,想一下子做成石破天惊的事。我的设计方案技术难度很大(有一些是热门的研究课题),只有30万元资金的小公司根本没有财力与技术力量去做这种事。分析经济与技术可行性,即可否定我的设计方案。
 
 (2)我以技术为中心而没有以市场为中心去做产品,以为自己喜欢的软件别人也一定喜欢。我涉足的是在国内尚不成气候的市场,我无法估计这市场有多大,人
们到底要什么。伙伴们跟着我瞎忙乎一整年,结果做出一个洋洋洒洒没人要的软件。分析市场可行性也可以否定我的设计方案。
  (3)我做到了“真实、正直”,但并没有达到优秀的程度。我曾得到很多炫目的荣誉,但学生时代的荣誉只是一种鼓励,并不是对我才能和事业的确认。正因为我不够优秀,学识浅薄,加上没有更高水平的人指点我,才会把事情搞砸了。

  投资方的主要错误:

  (1)投资方是个精明的商人,他把我的设计方案交给美国的一个软件公司分析,结论是否定的。但他觉得我这个人很有利用价值,希望可以做成功其它事情,即使Soft3D软件做不成功,只要挣到钱就行。这种赌博心态使得正确的可行性分析变得毫无价值。
 
 (2)由于我不懂商业,又象所有单纯的学生那样容易相信别人。他让我写下了不公正的合同,我竟然向他借钱买下本来就属于我的30%技术股份。他名为投资
方,实质上双方各出了一半的资金(他出51%,我出49%)。他在明知Soft3D软件不能成功的情况下,却为了占我的便宜而丧失了应有的精明,最终导致
双方都损失。

  关闭公司时,他搬走了所有的固定财产。我明明投入了技术,又亏了15万元,却一无所得。几个月后当我意识到不公平而
找他协商时,他说:“只能怨你自己愚蠢,读到博士,连张合同都看不懂。”我觉得自己在此事上虽愚但不蠢,真实、正直的品质加上不懈的努力会让我变得有智
慧。自己的奋斗没什么可以后悔的,学到的远比失去的多,下一次会做得更好。

  公司关闭后,我就面壁反省,补习基础,准备为几年之后“东山再起”养精蓄锐。

1999
年1月,有一个民营企业家G先生向我请教一个问题:“我给一个年轻人投资了100万元,建立一家从事环保信息应用开发的软件公司。他曾许诺一年内创利润上
千万元,可是才过去5个月,他就把100万元用完了,什么也没挣到。我实在不明白是怎么回事,请你帮我分析分析。”

  这位G先生年龄有我的2.5倍,曾在西北当过几十年的技术兵,性格豪爽。他投资的那个年轻人叫Y(以下称Y经理),自称有英国的管理学文凭,能对公司的市场、技术、管理一把抓。G先生喜欢说“钱我没问题”,于是想也不想就投了100万元,并且给Y经理40%的股份。

 
 G先生请Y经理到家里坐谈。我那时突然狡猾起来,自称是G先生的远房亲戚,在浙大读半导体物理,特羡慕那些做软件的同龄人,渴望听听Y经理的高见。Y经
理果然信口开河,滔滔不绝,连绵不断,如黄河泛滥,一发而不可收拾。我激动地想去参观他的公司和产品,并表示要抛弃物理专业,立马转向软件专业。

  Y经理得意而笑:“对于IT行业你就不懂了,我们经营的是一种理念而不是产品,这是国外最先进的思想。你可以来参观我的公司,但你看不到具体的东西,只能用心去领会。”

  这屁话比曹元朗的诗还臭(《围城》)。我搞软件只有8年功夫,说我不懂IT行业并不过分。可我读了10年大学都没听到过如此“先进”的思想。如果这是英国管理学教育的成果,我认为自己已经发现了这个曾经是“日不落帝国”的衰败的真正原因,有必要找英国首相切磋一番。

  我对G先生说:“Y经理根本不懂技术,为人极其浮夸。应马上关闭公司,以绝后患。那100万元你也亏得起,就买个教训吧。”
  G先生说:“钱我没问题,那100万元就算我在澳门赌博输掉了。”

  1999年5月,G先生又来找我请教另一个问题。
  
  他说:“小林啊,你上次说得很有道理,我接受了教训。”
  我说:“那是好事,不论年龄大小,知错就改总是好孩子嘛。”
  他叹了一口气:“最近几个月,Y经理又花了我100万元。”
  我当时差点给噎死,气凶凶地训G先生:“我早跟你讲过,Y经理不是好东西,叫你关闭公司你不听,你老说钱没问题,亏你200万元活该。”

  老先生象犯了错误的小孩子:“Y经理每一次向我要钱时,都拍拍胸脯保证下个月就有利润,所以我一而再、再而三地掏钱给他,希望能救活软件公司。现在该怎么办?”


个有20名职员的软件公司,程序员只有三四个,连“十羊九牧”都不如。200万元的财务报表中,有100多万元用于吃喝玩乐和行贿。这种公司完全无药可
救。台湾作家李敖曾说过:“当你没法扶一个人上马时,也许应该拉他下马”。从5月份到8月份,我行侠仗义,替G先生清理软件公司,根除Y经理这些败类。


  可是难哪,因为G先生投资的公司根本不把G先生放在眼里,又岂能让我插手。就在我想方设法卡住Y经理的脖子时,Y经理总能从G先生那里挖出钱。G先生就象被吸血鬼附身,却仍存幻想:“如果吸血鬼能治好我的病,就让它再吸些血吧。”

  Y经理又和一个来自深圳的骗子H想了注意,教唆G先生再投资100万元新建一个“指纹”公司,说利润将比开发环保信息的应用开发更加可观(估计要用亿来度)。就在他们准备鉴合同之际,我偶而路过,发现异常,便强行阻止。

  G先生是个好人,但太顽固。好几次我气极想撒手不管,但又不忍心好人被坏人欺负。我曾请求G先生:“我求您别再说钱没有问题,您的私人财产会被人骗光。请让我把这漏洞堵住吧,好让我安心地回学校做完博士学位论文。”

  到8月份,我和G先生的两个儿子,伙同“黑社会”的朋友,强行把那个软件公司搬回G先生的工厂中,辞退所有员工。现在那个软件公司被别人接管,仍然半死不活,好在每月亏损不过几万元,G先生承受得起,我就不再去碰G先生的伤疤。

 
 我以前从未玩过与人勾心斗角的游戏,此三个月的经历让我疲惫不堪。那个软件公司的员工曾透露,Y经理的英国文凭大约是在上海或杭州某个大专培训班里混来
的。方鸿渐买美国克莱顿大学博士文凭尚知羞耻(《围城》),而Y经理却趾高气扬。害得我平白无故为英国教育界担心,回想起英国鬼子曾打劫过中国,倍感耻
辱。

  G先生是正人君子,不防小人,实在不是现代的商人。我和他成了忘年交。G
先生第一次见到我时问我工资几何,我答曰:“300元,够买几本书。”G先生甚为着急:“这样的条件怎么能生活?你就搬到我家来住吧,我家条件好,你可以
安心地学习,将来可为国家多作贡献。”后来他几次相邀,我就看在国家的份上住入他家,一直住到博士毕业。自从读中学以来,我第一次享受食来张嘴,不用洗衣
服的奢侈。唯一的麻烦是我得向很多朋友解释:“我不是被别人养起来了,是为了国家的利益,不得已才这么做的。G先生是男的不是女的,并且没有待出嫁的女
儿。”

我在读博士学位的三年里,经历有点奇特。我遗憾的是“真才实学”没有长进,并且没有了在西电那样的纯真友情和缠绵爱情。略为欣慰的是我做了几件感人的事,也碰到了几件有趣的事,让我发觉自己变得成熟了。

  我很想讲一讲自己参加希望工程的经历与感受。

 
 1998年暑假,浙江省云和县梅源中学的老师们带希望班几名优秀学生来到浙江大学,其中有受我资助的何晓丽同学。我才知道初中学生一个学期的学杂费就要
600元。何晓丽哭诉下学期不能再上学,其它的学生处境相似。我以前资助的2000元是5个人3年平均分派的,根本不起作用。

  那
时侯,公司倒闭使我债务累累,并且自信心遭受十年来最大的打击。我在入不敷出、心事重重的情况下,没有推卸义务,而是“变本加利”的去尽这个义务。我在西
电的好朋友史江一替我“接管”了一个中学生。有一个小姐追求我,我乘机给她一个活生生的“见面礼”。1999年7月份,我把工资卡送给了一个大学生,自己
成了无产阶级。从1997年11月起到我博士毕业期间,我直接或间接地为7个贫困学生捐助了约1万元。

  我有了几点感受:
  
  (1)对人的帮助莫过于给予希望。
  (2)人在任何时候都能够帮助比自己更困难的人,哪怕自己处于困境。
  (3)帮助是要负责任的,一定要设法做成有意义的结果。不负责任的帮助就是“施舍”。“施舍”缺乏诚意,不配称为“帮助”。

  不少人曾对我说:“你是做大事的人,不要在小事上浪费精力,更不要为了别人而害了自己。”

 
 很多人总以为自己将来是伟大人物而不愿做小事,从而到死也没做成什么有价值的事。也有很多人希望自己成功后再去帮助别人,无论他最终成功还是失败,一辈
子也没有帮助过人。还有很多人略有权势或略有名气后,便觉得自己吃喝玩乐、放屁、上厕所都是重要的事,在他们最能够帮助人的时候却以“太忙”“没空”为理
由不去做好事。

  我也在忙碌、在奋斗,也渴望成为伟大人物,但我希望让有意义的小事充实一生。

我还要讲另一件我常干的小事。

 
 很多受过高等教育的人保留了随地扔垃圾的“风俗习惯”,这恶习就象脚气那样虽然不致人于死地,但能遗臭万年。即便象浙江大学这等典雅的地方,你都经常可
以看见草坪、校门口的废纸、果皮、塑料袋,垃圾就如同天使脸上的一砣狗屎那样鲜艳,人们竟然无动于衷。我记不请自己多少次当众、当道捡垃圾,可是几年来我
都没有在大学里发现第二个做这种事的人。

  我很想对所有的教授、博士、硕士、学士们讲句话:“救人并不只是医生干的事,保护环境也不只是清洁工干的事。只要你多化几秒钟,弯几次腰,就能让环境更加清洁,让心灵更加清洁。我们不必个个道貌岸然,但至少应该做到‘读书明理’。”

  那些正在追我和将要追我的小姐们,你多捡一次垃圾就多一份希望,你丢一次垃圾就不再有希望。

  我这样碟碟不休地讲“希望工程”和“捡垃圾”,并不是在沽名钓誉,也不是在布道,只是希望我这些“金玉良言”能触动更多的自以为自己是高素质的人们。

  在浙大的三年里,我没有对感情“播种”,所以也没有收获,但有一次“艳遇”。

 
 在关闭公司的那天晚上,人去楼空,我象严监生断气前那样盯着尚未熄灭的灯。这时一位杭大(现已并入新浙大)的四年级女生来找我。一年前她曾作为实习记者
采访过我,谈得很投机。我知道她是聪明好学的学生,曾大言不惭地教导过她几次。我开公司的一年里几乎没与她来往过,想不到当我成了光杆司令时她还能“兔死
狐悲”地来看望我,着实让我感动。

  我不无自嘲地对她说:“你不用安慰我了,这次失败我还能挺得住。”

  她说:“我不是来安慰你的。我一直盼望你的公司倒闭,等了整整一年。在你去北京之前,我有话跟你说。”

  我心下一凉,搞不清什么地方得罪她了,让她如此记恨我。大概是我得意之日教导她时言语过重,伤了她的自尊心。好在我是知错就改的人,当下惭愧地向她道歉。

 
 她不理会我,说:“你开公司时光环重重,我根本无法靠近你。即便那时我成了你的好朋友,你也不会把我放在眼里。我暗恋你一年了,一直都没跟你讲。我早知
道你会失败的,失败时你就剩下一个人,你才会知道我是真心爱你的,而不是冲着其它来的。你是个优秀的理科学生,我是个优秀的文科学生,门当户对,珠帘合
壁。请你不要觉得女的追男的很荒唐,我是认真的,请你给我一次机会。

  我虽然评不上情场高手,好歹也在爱河里游过泳,呛过水。想不到仓促之下,被一女子说得脸红耳赤,无法掩盖窘相。

  我一直认为男人应该勤劳一辈子,好让柔弱的女子舒舒服服地在大树下乘凉。而学习、工作出色的女子只能做朋友,不能做夫人。


从小习诗弄文,读大学时蜚声杭大。我见到她第一面时就把她归类为事业上的朋友,所以才会正儿八经地与她交谈并教导她。我在西电的两个女朋友就属于读书不太
好但比较有魅力的女生,我从来也没有指导过她们学习。如果我喜欢一个女孩子并希望她成为我的女朋友,我早就去追求她了,岂能轮到她追我。

 
 她见我彷徨不安,便滔滔不绝地例举爱我的“证据”。我开公司一年来发生的事她了如指掌,就象在我的房间里放了窃听器,在我的朋友中安插了间谍。她甚至跑
到团中央去查阅我的老底,有些“案件”我过去的伙伴都未必知道。她思念我时,写了很多诗,留了很多泪,为此杭大的一些男生四处追查“凶犯”。

  我早知道有些人不编程序、不做实验就能写出论文,难道男女之间不接触也能滋生感情?

  第一回合我就被她挑翻在地,我莫名其妙地成了“负心郎”,无地自容地把她送走。我以为这是文科女生的风格,就当作一个趣事不放在心上。

 
 我从北大方正“劳改”回来不久后,她提着一篮鲜花来找我,并对我说了她的梦想:在寒冷的冬天,大地铺满积雪,四野人鸟绝迹。我孤独求败地深居在冷冰冰的
小木屋里。在一个狂风呼啸的黄昏,她一手拎着亲手做的饭菜(我想应该有土豆和辣椒),一手拎着一捆木柴,敲开了那扇紧闭的门和心房。终于木屋四壁生辉……


  我对第一个朋友最好的赞美是:“黄蓉很象你。”

  我对第二个朋友最深情的话是:“将来咱们老了,我回黄岩当物理老师,你当语文老师。”

  相比之下,我的确不及杭大女生浪漫。此后她再找过我几次,当我意识到她动真格的时候,她已不能自拔。爱情是很怪的东西,并不是两个好人就能碰出火花。就象一头好牛和一匹好马,可以一起干活,但没有必要吃住都关在一起。
 
  与其让她长痛,还不如让她狠痛一次。
  我对她说:“我们真的不能在一起。”
  她问为什么?
  我说:“我不喜欢你。”
  她再问为什么?
  我说:“不为什么,我没有心跳的感觉。”

  她说十年之后再找我。


知道她会奋发图强,因为她会一直想着“为什么”,期望让自己有个满意的答案。
这条路8年前我已经走过了。半年前我再见到她时,她已经直攻博了,在文学上有了长足的进步。并且找了一个软件工程师做朋友。我说软件工程师未必就懂得软件
工程的道理,待我写的软件工程书籍出版后再送她一本。她说将会送给我她的第一本著作,书中开头的几个故事是关于我和她。我说看了她的书后一定会写一篇读后
感给她。她仍然提醒我不要忘记十年后的相约。

  我在浙大有一个值得怀念的人,她是管宿舍楼的大妈。在1999年1月至5月,我在博
士生宿舍静心修炼内功,大妈就象我的“护法”。晚上九点钟时,她就会烧些东西给我吃。我和大妈非亲非故,同学们都不明白大妈为什么待我好。我想那是因为我
没把自己当成“博士”来看,而是当成“人”来看。
 
  5月份后,我看在国家的份上搬到一个千万富翁家里去住,大妈也调到“熊猫馆”
当掌门人。我一般隔几个月去看望大妈一次,中秋节我就和她在一起。朋友们知道我和大妈有这层关系,就纷纷托大妈物色女朋友。大妈果然称职,她就象特务那样
审视大楼里的女生。可大妈毕竟是大妈,她采用的“标准”是几十年前的版本,无法与现今的兼容。她盯住了不该盯的,却漏掉了不该漏的,至今都未“推销”成功
一个。

  这件事让我又明白了一个软件工程道理:光有完善的数据库还不够,还应该提供很好的搜索引擎。

  我相信
生活、科学、艺术中的很多道理是相通的,于是就不嫌人笑,写下《软件工程思想》这本书,并写下了十年来的故事,交最后一次作业。大学十年给我留下了很多美
好的回忆,现在可以打上漂亮的句号了。尽管我即将告别大学,但我会终生学习。也许我成不了天才,但还有机会成为天才的爸爸。

  我想大声呼喊出那种可以用双手把握未来的自豪。

  我要对年轻的朋友们说两句肺腑之言:
  一、主动去创造环境,否则你无法设计人生。
  二、生活和工作要充满激情,否则你无法体会到淋漓尽致的欢乐与痛苦。
  
  如果我碰到上帝,只会对他说一句话:“你看厕所去吧。”