友好连接

2008年9月21日星期日

深度探讨:真正技术高手是如何炼成的?

在由CSDN和《程序员》杂志联合举办的第三届中国软件技术英雄会(上海站)上,由主持人CSDN首席分析师孟岩,上海群硕大中华区软件开发总监邵荣,阿里软件技术总监叶伟,盛大游戏首席技术官朱继盛, 趋势科技(中国)有限公司技术总监蔡昇钦,巨人网络集团首席技术官CTO宋仕良,淘宝网首席架构师王文彬共同参与的CTO论坛上,就有关CTO是否必须为技术高手,从程序员到技术高手成长之路,知名互联网公司如何招聘人才等问题与参会者进行了深入的交流。精彩观点:我觉得CTO并不必须是技术大拿,大家今天可以看到,从CTO的定义来看,CTO的角色是用技术服务公司的商业模式。从这个定义,只要你对技术有相当性的掌握,其实你可以不必从底层做起。——王文彬CTO很重要的目标是在于它能够整合公司的商业能力,成为一个CTO的重点,是你对公司核心技术的了解度跟掌握度,还有公司主要的核心业务的掌握度。——蔡昇钦技术高手和CTO这两个角色,打个比方,像一个乐队里面,技术高手像小提琴演奏者,或者是一个钢琴演奏者,但是CTO相当于一个乐队的总指挥,乐队的指挥需要有对音乐的整体感觉,这方面肯定更拿手。——朱继盛CTO还是应该是一个内功高手,还是要有点内功,这说明什么,你在技术方面,应该有技术的洞察力,要看到商业和技术的结合。——叶伟跟技术团队,尤其跟程序员,跟工程师,你要有共同语言,我觉得如果说没有一定技术深度的话,其实很难能够融进整个的团队。——邵荣如果作为一家创业型的公司,特别是互联网,特别是软件行业,CTO必须是一个技术高手,因为你是一家创业公司,技术平台应该是公司的核心业务,如果CTO不是技术高手,这个公司很难在商业上有大的作为。——宋仕良程序员或高手容易犯的错误是什么,或者我觉得做得不够的地方,是程序员容易觉得我做的这个东西很好,很牛,我这个东西别人应该喜欢用,由我来推演别人。——邵荣要成为高手,就像练功一样,你必须能耐得住寂寞,要关在研究室里面,像大家一样,晚上写代码,有时候这种东西不是平常人可以做到的,假如你可以呆过这段期间的话,我相信你练到功成了以后,这些东西你就可以发挥出来了,我想这是成为高手很重要的因素。——王文彬我建议大家去尝试做产品经理或者系统分析师,架构师很多人误解为纯技术的,其实许多的架构师对商业的分析是非常擅长,对于系统分析师,因为系统分析师是非常清晰地要描绘出商业的目标在什么地方,分解成什么东西,跟技术有关联。——叶伟首先在于留住人才,我们让工程师知道,工程师他不是低于管理者的,也就是说,你一个经理,他所拿到的整个薪资,不一定要大于他所管理的工程师。——蔡昇钦以下为论坛实录:主持人:在正式开始之前想先做一个小调查,我想请问一下,在座的六位CTO都是技术管理者,都是技术大拿,你们谁认为成为一个技术管理的高手,或者CTO,成为技术高手是必经之路,想成为一个CTO必须先成为一个技术高手吗?淘宝网首席架构师王文彬:先说明一下,我是假CTO,我的职位其实是做技术,在淘宝做品牌架构,说实在的,我有一个技术背景,但我觉得CTO并不必须是技术大拿,大家今天可以看到,从CTO的定义来看,CTO的角色是用技术服务公司的商业模式。从这个定义,只要你对技术有相当性的掌握,其实你可以不必从底层做起,我们今天讲的是CTO是不是一定要从底层的技术人员干起,假如从这个角度,我觉得做CTO不一定经过必须这个角色,当然现在业界很多CTO,我想在座很多CTO是从技术出身,这是现实,但是理论上我不觉得是一定的事实。趋势科技技术总监蔡昇钦:我认为CTO有很重要的目标是在于它能够整合公司的商业能力,成为一个CTO的重点,是你对公司核心技术的了解度跟掌握度,还有公司主要的核心业务的掌握度,所以不一定说非要从底层干起,当然CTO也可以是掌握技术最高的那个人,但是这不是一个唯一的一个对应关系。盛大游戏首席技术官朱继盛:技术高手和CTO这两个角色,打个比方,像一个乐队里面,技术高手像小提琴演奏者,或者是一个钢琴演奏者,但是CTO相当于一个乐队的总指挥,乐队的指挥需要有对音乐的整体感觉,这方面肯定更拿手,但是你说他,说到他必须是一个小提琴高手,或者必须是一个钢琴高手,这不一定,也说明作为一个CTO的话,不一定是从一个技术高手成长过来的,作为一个CTO,他最主要的职能在于整体的协调,对于音乐整体的把握,或者技术整体的把握上。阿里软件技术总监叶伟:这个问题很难回答,是不是一定要成为一个高手,我曾经发现自己技术上好像也有点高,但是很快发现自己不高了,因为高手太多,刚才盛大的朱总也谈到了,你不可能样样都精通,我本来想打这个比喻也差不多,不过总的感觉,还是应该是一个内功高手,还是要有点内功,这说明什么,你在技术方面,应该有技术的洞察力,要看到商业和技术的结合。我还得补充一点,我们就从CTO的词上来说,最后一个词是officer,officer什么意思,实际上是个管理者,你真正的本事是把一个团队凝聚在一起,并且服务于商业,如果你没有那方面的能力,你今天编程越厉害,或者某个方面精通的,根本不能把你放到CTO这个位置上面,越放到上面越危害,你带着一帮人不知道往哪方面奔,你纯粹只是兴趣,无法为给公司带来商业价值,大家都知道公司其实是要产生这个价值。群硕大中华区软件开发总监邵荣:我更倾向于必须成为技术高手才能成为CTO。刚刚几位的观点我是认同的,但是还有一些不同的想法。第一个就是自己大言不惭来讲,我自己是走技术这条路过来的,然后在这个过程里面,我自我感觉,就是说你跟技术团队,尤其跟程序员,跟工程师,你要有共同语言,我觉得如果说没有一定技术深度的话,其实很难能够融进整个的团队,尤其,当这个团队,比如说从很小规模,你很可能在前面做很高指点的话,能够落地,给他们一些帮助,所以说在整个我觉得成为一个技术主管的过程当中,如果说有相关的比较深的这样一个经验的话,我想应该会有一定的帮助,整个到后面真正成为CTO,或者成为技术的主管的时候,那个时候是不是技术还是跟原来一样重要,不是,它只是属于在整个的过程当中,其中一环吧。巨人网络集团首席技术官宋仕良:刚才几位的观点我是同意的,我之所以更倾向于必须成为技术高手才能成为CTO,其实我自己也是一个从技术的底层干起来,我也是写程序的,我为什么觉得这个问题可能要分两个部分来看,如果作为一家创业型的公司,特别是互联网,特别是软件行业,CTO必须是一个技术高手,因为你是一家创业公司,你的公司要创业,技术平台应该是公司的核心业务,如果CTO不是技术高手,我觉得这个公司可能是很难在商业上有大的作为,如果像一些传统的公司,或者做金融那些公司,它来有一个做IT的部门,就不一定是一个技术高手,更重要的是偏重管理,或者是对业务流程的熟练,并不一定是对技术要专注。主持人:不管怎么说,台上的六位都是我们心目中公认的技术高手,我想问其中几位,台下有很多人,有的人已经是高手了,有的人还在成为高手的路上,我想你们跟大家分享一下,如何才能成为一名技术高手,成为一个技术高手一个最重要的经验是什么,我想邵荣首先与大家分享一下你的观点。邵荣:先简单说说我自己的一个成长经历,其实我在95年、96年左右的时候,我在操作系统上玩java,我的导师要求我在一个月之内掌握当时的内容,其实就在那个时间开始做很多事,凭着狂热,后面我在DOS里面写自己的Windows的驱动,去驱动整个的鼠标、键盘,再到后面,帮那个研究所做过一个,大家不知道南极星,我自己做了一个,帮香港的一个公司做了一个斯托尼方。我那个时候真的有点不知天高地厚,就想走出苏州,我以前在苏州大学里面,自己也做了老师,还教软件工程,教C++,当时我走出苏州的时候,我讲了一句话,在整个苏州可能没有人在C++上超过我,最多只能跟我沟通交流,过了多少年才知道自己错得多厉害,当时自己的自信心很膨胀,我那时候基本上把白天黑夜倒过来干,基本上是每天吃完早饭回去睡觉,然后别人吃中饭,我吃早饭,连续很多年,大概是最起码4、5年时间一直这么来干活和工作的。但事实上随着时间推移,号称自己觉得还可以,慢慢开始有不同的理解,当中有一个关于互联网,我不知道有多少人知道“白云黄鹤”这个BBS,这是在教育网里面仅次于清华的,我当过两年版主,通过在里面解决问题,带来很多思索,之后我又开始疯狂看软件工程,后面又开始看管理,在市面上的管理方面的书我都看过,事实上一步一步走过来,到今天我思索很多东西,很多时候在里面思索一些商业模式,思考整个团队的建设,思考很多东西三年之后会发生什么事情,客户那边是什么东西,那这么多年里面,我觉得有一个词,就是我影响很深刻的,可能对大家有些启发,叫EMPATHY,这个词的中文含义叫移神,那么我把它去更形象化来讲,就是将心比心,我觉得这么多年过来了,从技术高手转到现在为止,可能很多时间是负责技术的方向,甚至于是整个业务方向,从原来的执行者变到现在的一个布局者,我觉得很多很多时候,EMPATHY这个词给我自己很大的一个促进或启迪吧,程序员或高手容易犯的错误是什么,或者我觉得做得不够的地方,我做的这个东西很好,很牛,我这个东西别人应该喜欢用,由我来推演别人,EMPATHY这个东西,我做这个东西首先站到别人的角度看,我想要带团队,我会站到团队角度看这个问题,你必须在很早的时候预估到很多部分,我觉得很多程序员应该了解,但是最后没有做的事情是尝试性的一些东西,所以随着时间推移,我觉得做真正的技术高手,或者想成为技术高手,我觉得应该往一些更软性的东西想,讲句实话,我往管理方向做的时候,看了很多哲学和心理学的书,这些东西对拟人生有非常多的促进,不要走太多刚硬的路。主持人:邵总很性急,一下把我后面要问的问题全都回答了。我们接着往下问问叶总,我知道您的技术非常好,思路也很活跃,所以您走上技术这条路,但是我有一个问题是,您后来为什么没有走上创业的路线,您觉得怎么评价一个技术人员的价值,跟着人干也算成功,还是我非要自己创业呢?叶伟:这个问题相信很多人都面临着,不管你曾经或者将来,你最终选择了什么,你有可能选择了去创业,也可能这时候没有想创业,我个人认为呢,有几个方面,一个是来自于客观上,比如说跟人的性格有关系,有些人可能性格上并不善于冒风险,大家都知道创业是非常冒风险的。第二个,你的知识结构能力方面可能有局限性,你创业,所有的责任都是你在承担,你要考虑是否能得到成功,你会考察你的特长在什么地方,从性格方面说,可能有的人说我希望去宁为鸡头,不为牛尾。我另外有一个观点,这也是我自己的,可能我没有去创业的很重要的想法,我真正想创造社会价值,这个价值要摆在舞台上,这个舞台如果适合你发展,而且它也很大,而且我们大家都知道互联网可以把全世界都联合起来,你有没有智慧,你跟着英明的道路走,这是你可以考虑的。说实在的,我自己的经历,我开始的时候,没有进外企,为什么呢,我读书的时候去打工,所以我在民营企业,很快做大了,那时候我做CTO,管理几十个人,后来我觉得这个行业比较小,我做ERP,我也不再做CTO了,ERP大家知道会影响很多的企业,OK,我去做这个东西,我进了金蝶,在行业里比较大,然后后来我进了互联网行业,阿里巴巴,因为我们要去做电子商务,电子商务它将影响更大范围的人,所以我觉得这个能够创造更大的社会价值。主持人:我昨天去巨人访问的时候,巨人的同事向我们说,宋总其实是一个不善于言词的人,但是我想问的问题是,您这样典型的技术人员的个性,怎么样管理一个团队呢。 宋仕良:确实我平时在工作中是不善言词的,因为我应该说比较喜欢做技术工作,我在学校里面天天钻研技术,工作之后也遇到一些朋友,然后朋友都是一些技术高手,因为我工作的时候去一家公司,那家公司的同事也是技术高手,在清华BBS上被评为中国十大黑客之一,那不是贬义的,是软件高手或者技术高手,是做输入法的一个作者,我从他的身上看到一个真正的技术高手,是一个什么样的人,就是说平时不去太追逐一些功名这些东西,回到刚才说的话题,我一个不善言词的人如何把100多人的团队带下来,主要还是靠朋友,可能我会跟我的另一个搭档,他的沟通能力比较强,然后他在从事人际交往,在管理当中会比较擅长一点,我专注于做技术这块,相当于一个黄金组合了。主持人:王文彬先生是我们淘宝网的首席架构师,我知道您在淘宝网上扮演两种角色,一种是带领团队的角色,另外一种是掌管整个淘宝的架构。您觉得这两种角色,CTO带团队的角色和做架构师是什么关系?您是如何协调好这两者的关系的?王文彬:的确有点挑战,我老板每次跟我说你架构为什么没有做好,我说我一个人扮演两个角色(笑),但是这个角色里面是有相关的,比如我下面的同仁,其实大家都关注架构,所以其实我今天在带领淘宝团队做架构的时候,会依赖他们实行部分的架构设计,因为淘宝这么大的网站不是一个人就可以做得出来的,这也需要大家通力合作。这样自然就有一个团队,我想我只是起带头作用,带这个团队成本比较小,这也是为什么我两方面能够兼顾的原因吧。其实我再补充一点,刚刚主持人问怎么去变成技术高手,需要什么调整,我也一直在思考,其实我同意邵总的讲法,今天你做程序,技术上的东西最需要的是热情,这个热情也需要你具备一定的条件,我总结我自己的经验来看,当然我也有一点运气,加入了一流的团队,我想这会刺激一个人潜力的发挥,假如我今天没有遇到这群人,我不觉得我今天的看法能够到这种程度,但是另外一点,我觉得你今天要走技术这条路,有一点,要成为高手,就像练功一样,你必须能耐得住寂寞,要关在研究室里面,像大家一样,晚上写代码,有时候这种东西不是平常人可以做到的,假如你可以呆过这段期间的话,我相信你练到功成了以后,这些东西你就可以发挥出来了,我想这是成为高手很重要的因素。现在在中国,很多公司都在征才,其实大家对技术高手的需求是非常大的,只要把握这几点,相信大家有机会成为一个技术高手。主持人:叶总好像有什么想补充的?叶伟:是的,我想补充的是说,管理这个东西,它是你的工具,你的手段,对一个CTO来说,或者对负责技术研发的总监来说,实现这个目标,这是你的责任,管理是你的手段之一,你搭好架构,也是你的手段之一,这些东西你都要去管,没有一项可以落下来。另外一方面,这些责任不见得是跑在最顶上的人才有责任,其实我们的一个技术主管,经理他都会有责任,你说他当经理不要管团队,也要,只是CTO更专注在商业和技术架构之间形成桥梁,他需要把商业的东西分解成技术解决方案,反过来又要用我们的技术驱动创新,形成商业上的一些想法,所以我觉得是说,管理它是一个工具,帮助我们,你不要去忽略它,然后我想补充一下,刚才邵总前面谈的问题,怎么样成为一个CTO,一个是说你要以终为始,你看CTO核心的能力点在什么地方,我们刚才谈到是说,它是在跨越商业和技术,所以你要有这个技术,第二个你要组得起团队来搞攻坚战,这两方面都要,你要练很多东西,我今天讲不完,我提两个主要的,你可以同时去尝试,可能你距离CTO就近一些,第一个是做项目经理,没有丰富的项目经理,你根本就不知道怎么样跟人家合作,怎么样取舍,怎么样排列优先顺序,怎么样控制你的资源,前面我说CTO是个officer,第二个方面,他更多要有站得高看得远的角色,所以我建议大家去尝试做产品经理或者系统分析师,我谈架构师,因为谈架构师很多人误解为纯技术的,许多的架构师对商业的分析是非常擅长,所以我还是谈一谈系统分析师,因为系统分析师是非常清晰地要描绘出商业的目标在什么地方,分解成什么东西,跟技术有关联,我建立大家在这两个角色方面尝试一下。主持人:谢谢叶总,我们还有一位没发言。我知道趋势科技有一个特别优良的传统,你们在培养人才,以及留住人才这件事情上很有功力,我想了解一下,您怎么在您的技术团队里面培养人才,留住人才,这是一个大家现在很关心的话题。蔡昇钦:培养人才在趋势科技的做法,就是你给他舞台,然后他就是自己的编剧,他就是自己的导演,用这样的方式来做,我们在培养技术高手的层面上,在公司的框架当中,我们是把人才分成两个方面来看,在技术这条路上走的话,首先在于留住人才,我们让工程师知道,工程师他不是低于管理者的,也就是说在趋势,你一个经理,他所拿到的整个薪资,不一定要大于他所管理的工程师,因为我们必须让公司的团队知道,你喜欢钻研技术,那是因为你的兴趣所在,你喜欢管理团队,你喜欢跟人打交道,那是你的兴趣所在,从一个公司角度看,我们鼓励人基于自己的兴趣做好他的发展,所以从这样的情况了解员工后段的需求,然后安排他去他有可能的位置,很自然而然员工就会跟公司走得很近。像我通常会跟我的团队的人员讲,不管是资深的还是资浅的,我每年会问他们一个问题,你有没有想过你5年后干嘛,我会记得他们2006年跟我讲什么,2007年跟我讲什么,2008年跟我讲什么,他有没有改变他人生的五年规划,三年规划,我们尽可能在公司的范畴满足员工的需要,我想这样子,员工就会成长,就会跟公司走在一起。主持人:人才的问题其实是现在大家都很关心的,我在主持这个会之前,有人特意给我发消息,建议我多问在座的CTO一些关于怎样招募团队,保留团队的问题,由于我们现在人才培养存在一些问题,导致我们市场上优秀人才的数量有限,就带来保留人才和争夺人才之间的矛盾,我想问一下宋总,我昨天去巨人的时候,听说你们团队相当稳定,你觉得除了巨人的收入高以外,这个当然是很重要的因素,你还有什么诀窍吗?宋仕良:应该还是说公司重视技术人员,首先你重视人才,你应该是要尊重人才,一个技术人员,他有他自己的想法,而且每个人的想法都是不一样的,你要重视他的想法。 主持人:这种想法跟公司的目标不一致怎么办。宋仕良:目标不一致的话,那应该是给他做工作,就找他谈心,这个肯定要统一目标的,如果目标不一致,大家肯定走不到一起来,首先你在组建这个团队的时候,在选人方面,应该是物以类聚,我觉得至少应该选大家有兴趣,或者有共同拼搏方向的,或者是大家奋斗的方向是一致的,至少奋斗的目标一致的话,才能够很好地沟通,不会说我提出一个观点,另外一个人会有很大的反驳,首先你在组建团队的时候,每个人虽然达不到完全一致,但是大家的目标是一致,中间团队在磨合的过程中,肯定会出现这样那样的问题,这些问题我想都是可以解决的,因为公司或者通过一些协调,或者是互相的理解,互相的支持。主持人:朱总您觉得盛大在保持人员不流失方面如何。朱继盛:我觉得核心的思想只有一点,给相应的人自己的舞台,施展他自己的东西。可以举一些例子,比如说我们盛大集团的副总裁是80后的,他能作为一个上市公司的总裁。再举一个例子,去年盛大有很优秀的员工离职了,这个离职并没有任何人劝他,他自己有这个意愿,要自己创业,盛大有机制,让他自己编一个游戏,他在盛大的周围去工作,这样的例子,实际上在盛大有非常多这样的例子。主持人:谢谢台上的嘉宾和底下的观众。嘉宾:谢谢大家

学编程与炒番茄蛋

今天晚上,要给我们软08级的新生做一个交流会,要我去做专业学习方面的,自己最多也算是勉强刚刚入门,我面对的是没有任何基础的学弟学妹,想来想去就那这个番茄鸡蛋作比喻了,希望大伙给点意见!
怎么学习编程
分析:这个应该是大家最关心的问题,也是我觉得最不好讲的问题。编程就相当于做菜,老师课堂讲的语法知识相当于菜谱,至于你能炒出什么样的菜,就看你自己在下面的练习和体会了。
如何炒好一盘番茄鸡蛋?
第一步,确定一个菜系
中国有八大菜系,鲁菜 、 川菜 、 苏菜、 粤菜 、 闽菜 、 浙菜 、 湘菜 、 徽菜 ,也就是说同样的番茄鸡蛋至少会有八种不同的风味,你要选择那种作为学习的起点呢。其实,不同的编程语言就相当于不同的菜系,区别在于实现同样的功能(番茄鸡蛋)采用了各自不同的处理机制(风味不同)。 对于一个从没做过菜的人,学习那个菜系的番茄鸡蛋是不是一样的,选择菜系的意义在于通过该菜系去了解番茄鸡蛋的入门级的基本方法,同样选择一们编程语言的目的在于选择你是从哪个门去进入编程这个领域的,对于什么都不同的新手而言,最开始学哪一门都是一样的。
第二步,记菜谱。
选好了菜系,那么就要记菜谱了,菜谱告诉了我们:1.不能番茄鸡蛋里没有番茄,也不能番茄鸡蛋里没有鸡蛋。2.以怎样的方式使用番茄鸡蛋,比如放多少盐,什么时候放。菜谱告诉你炒番茄鸡蛋一些规则和方法,也就是说我们在学习编程的时候,书本上的语法知识仅仅是告诉了我们一些编程的必须遵循的规则和方法,这个是所有编程开发的基础。
第三步,炒出能吃的番茄鸡蛋。
菜谱记的再熟不见的你能炒出好吃的番茄炒鸡蛋。课本上的语法记得再熟不见得你能写出漂亮的程序。厨师要把菜谱告诉的信息变成现实中的番茄鸡蛋才有意义,我们要把课堂学到的变成实际存在的代码才能体会到编程的意义。这个转化的过程中目的在于学习,只要你炒出来的东西能吃就行了,只要你能实现老师布置的作业或者书上的练习题就好。
第四步,炒出好吃的番茄鸡蛋。
我们的要求不能这么低吧,肯定不能满足于能吃而已,那我们尝试做一盘好吃的番茄鸡蛋。重复的背菜谱能提高番茄鸡蛋水平吗,不能!多炒几盘才是硬道理。那么重复的记忆书上的语法规程能提高编程水平吗,不能!多写几遍才是王道。从能吃到好吃这个过程是经验的积累,从实现功能到熟练的编程这个过程也是经验的积累。
第五步,炒出创意的番茄鸡蛋
已经能中规中距的炒出一盘好吃的番茄鸡蛋了,还不满足,那就在创意点吧。比如,我们能不能变化番茄鸡蛋的存在形式,菜谱上一定是最好的吗。把鸡蛋换成煮好的茶鸡蛋怎么样,换成鸭蛋呢。换到编程上来,同样的功能,我们是不是可以用另外的方法实现,老师讲的就一定是最好的方案吗?我们完全可以去尝试使用自己的方法实现同样的功能。从好吃到创意是个思维延展的过程,从熟练到怀疑的态度也是个是思维延展的过程,但这个过程有一点很重要,不论的你的思维怎么延展,一定要把你想的编程现实,能用了才是对的。就相当于光更改菜谱没有用,创意版本的番茄鸡蛋能不能吃,还要炒出来尝尝看。
第六步,炒出人性化的番茄鸡蛋
经过前面的训练,我们现在已经可以炒出来相当有水准的番茄鸡蛋了,但是我们忽略了点,我们炒番茄鸡蛋的目的是什么,也就是说我们编程的目的是什么。 除了自炒自吃,更多的时候是炒出来的番茄鸡蛋给顾客吃的,而这个顾客又是厨师所不能控制的,顾客的爱好有很多,稍咸一点儿、清淡一点、要辣椒、不要辣椒等等,这个时候你要根据不同的顾客去炒出不同的番茄鸡蛋了,才能让顾客满意。那么编程呢,除了自娱自乐,编程或者说软件开发最重要的是服务于客户,你不能去要求客户什么,那么就需要我们自己根据不同的应用环境来变通了。从创意到人性化这个是认识挺高的过程,不要把自己的思维局限于技术本身,某种程度上可以说是客户的需求决定你要选择的一切。当然类似于番茄鸡蛋不要鸡蛋,这个没事找抽的可以不予理会。
第七步,炒出其他菜系的番茄鸡蛋
经历以上六步,修炼成一个番茄炒鸡蛋的高手是没有问题的了。这时候你肯定会发现各个菜系的番茄鸡蛋从菜谱到手法上其实差不多的,区别仅仅是一些调料的或者其他方面的小差距。对于编程而言,你会发现其实很多语言在设计上同样有很多相同的地方,但是由于一些具体细节的实现机制不同会有一些细微的差别。对于番茄鸡蛋而言,炒菜所需的方法是固定的,具体实现上会有些小差别,对于编程而言,编程的思想是固定的,具体到实现方式上会有一些不同。
当然番茄鸡蛋比较简单,编程又是个比较复杂的东西,这个我体会的方法希望会对大家有所帮助。经常炒才炒出好吃的菜,经常练才能写出漂亮的程序。 菜谱记得再熟,饭店不会要这样的厨师。决定厨师水平的就烧菜的能力怎么样,也就是菜烧得好不好吃。 语法记得再熟,公司不会要这样的程序员,决定程序员水平的是编程的能力怎么样,也就是程序写得好不好。
重要的不是菜谱,而是使用菜谱的能力。对于学习编程而言,重要的不是语言本身,而是驾驭语言的能力。
补充一点:学会在不同天气下做番茄鸡蛋。在实际工作中,面临种种外界压力,保持心中不慌。就像奥运会中韩国人在暴雨天气中都能射出十环的箭一样。
本文来自:http://www.cnblogs.com/flychaochao/archive/2008/09/18/1293178.html

我的丑震惊了党

鲁迅说,世上本没有丑,帅的人多了便有了丑,我来了,就又没了丑。笛卡儿说,我思故我在,笛卡儿见过我后就改口了:我帅故我在。语气十分强硬。 我是在丑人族学校长大的,先在奇丑无比班读书,几天内使所有同学患上了自恋症,于是为我特设了一个班,叫丑的n次方班。 初恋当然是网恋。见面那天,距我五十米时他就疯了,家长报案,法院认为长的丑的确不是我的错,但约出来吓人就是我的不对了,判我整容3年,整的丑上加丑。 我朋友都是丑人,都单身,也都单的心服口服,除了一位,这位发誓要结婚。那天她在街上拦住一绝色帅哥,递上一相片,是她与我的合影,帅哥看了后,一句话也没说,默默的回家准备婚礼,当天就取了她。  晚上才敢出门,出门必戴墨镜口罩牙套耳帽,溜墙根钻桥洞,却依然是万人围观,交警报110,110报军委,军委拉来大部队有组织有纪律地围观。 全球500丑大会,我的确参加了,但一见到我真人,他们就把我打出来,并换了会场横幅:“全球499帅哥大会” 有人投了猪胎,泼了硫酸,专程跑梅园找我比丑,刚从门镜打了个照面,他就跑了,飞快,我依稀听清了他留在风里的怒吼“太~他~妈~的~丑~了!” 英俄日法德美意奥,无论哪本字典,“丑”字的解释一律是:横刀立墙。地球人都认识也都认可这四个方块字。 红十字会正在讨论一项目,要给全球人民接种一种疫苗,据说该疫苗能使别人看见我时,自动产生马赛克效果。 抗洪形势严峻那阵,某大领导骑自行车驮我去帮忙,请了三次后,我去了。酒饱饭足,我对江面说了无耻至极的3个字“我不丑”,立马长江倒流,国泰民安。 我出生了两次。 第一次,一个医生从娘胎里把我拽出来,突然晕倒,一个护士闭上眼摸索着,把我塞了回去……
第二次我出生以后,医院所有的人都躲在太平间哭泣,院长自己抽自己的嘴巴子,怪自己有眼无珠,不该贪财接了我这个生意…… 母爱是伟大的,她不嫌弃我,把我养大成人,不过他在我脸上贴了一张骷髅照片,以减轻心理压力,面具伴随我到十岁。 十一岁那年,我上三年级,全班同学都是好奇心最重的时候,都拼命的想看看面具后的我到底什么样子,有个外号叫李大胆的同学趁我小便的时候一把扯下了我的面具,从此后,李大胆同学患上一种怪病,不会说话,目光呆滞,一天到晚什么也不干,对着一个人的头骨打死不眨眼,一闭上眼,就流泪不止…… 校长上报了教育局,教育局派人来了,因为全校的同学都转学了,校长每天早上只能吃半碗稀饭,老师的工资已经两月没着落…… 教育局的人见到我后,局长立刻辞职下海不干了,连锁反应,全国的教育机构解散…… 我走在街上,路边的人全在狂哭不止,一群猪从后边冲到我这里,忙不迭的给我戴红花,发奖杯,还给了我一个证书,上写:猪的救星。 隔壁刘麻子的媳妇要跟他吹,说他的一脸麻子太恶心了,绝对要离!!!正巧我走到他们窗前,刘麻子老婆一见我,
不说话了,拿出钱,到保险公司给刘麻子的麻子保了险,一个麻子一万…… 又惊动了联合国(?为什么要说又呢),安南无计可施,要求强迫我整容,可是没有成功,所有的整容医生见到我以后全部大哭不止,将近半数的医生进了精神病院,症状全部一样,什么也不会说,只有一句:“太~他~妈~的~丑~了!” 阿拉法特派专机来接我,要求我站在总统府门口,以抵抗以军的包围,我去站了一分钟,以军全军撤退,沙龙被迫辞职,巴勒斯坦举国欢腾,但当阿拉法特要介 绍我这个民族英雄的时候,巴勒斯坦全国人民打着灯笼也找不到了…… 一个作家找我,声泪俱下:我长这么大,最大的梦想就是得一次诺贝尔文学奖,可是现在的高手太厉害了……我有个绝招,只要我能在你面前写一部书,我一定能得奖!!! 我不信,于是他跟我待了一星期,写出一部长达五百万字的小说《地狱七日》,结果,连诺贝尔医学奖也被他拿了…… 诺贝尔总部宣布,世界上要是能找出形容我面貌文字,就能得文学奖,结果,全部的作家都改行卖猪肉了,诺贝尔文学奖从此消失…… 国家足协特招我进队,想借此真正冲出亚洲,在世界杯上,中国队一球未失,每一场都是一个比分12:0,一人一个球,踢完了就在草坪上开野餐会,我一个人在球门前bbq,对方球员包括守门员全部哭晕在地,裁判连红牌都掏不出来了 当然我们的队员也经过了循序渐进式的魔鬼训练,先看我的照片,然后看着我照片吃饭,然后再踢球…… 大力神杯从此永久的留在了中国,国外媒体评论我是魔鬼化身。 世界撒谎大赛开赛,各色人种的参赛选手开天辟地的狂吹乱侃,我走上台,只说了三个字就得了冠军,并且永久
保留冠军头衔,我说:我不丑…….

菜鸟VS老鸟

《1》OICQ
一日,菜鸟问老鸟:“老鸟,我有个问题想问你?”
老鸟爽快的说:“你问就是了”
菜鸟有点儿含糊的说:“先说,我问了这个问题你可不能笑我哦”
老鸟还是爽快的说:“放心好咯,我一点不会笑你”
菜鸟问:“真的?”
老鸟拍着胸口说“我对天发誓,绝对不笑!”
菜鸟问:“请问OICQ的意思是不是就是‘我爱重庆’的意思啊?”
“考!我可不可以收回我刚才的誓言啊!”老鸟喷饭中……
《2》ctrl+alt+del
一日,菜鸟遇见了老鸟,搔头道:“上次你给我介绍的那种启动方式是不是错咯。怎么就不行啊?”
老鸟奇问:“怎么不行啊?是不是那种热启动,同时按下ctrl+alt+del的方法啊?”
菜鸟带着有点儿抱怨的口气说:“就是!”
老鸟更讶:“怎么不行啊?”
菜鸟迷惑的说:“我用了五根手指头分别按下了c,r,a,d,e,可是……用什么样的办法才能同时安下两次t和三次i呢?”
“倒~”老鸟无言以对。
《3》cs搞笑篇
一日,沙丘二的小巷中,土匪聚在一起摆谈……
文化贼说:“我那天运气奇差,我那天刚冲出A门,就被一群CT的手雷给挂了!”
花裤贼说:“你这算什么,我那天阴到了一个CT,刚要阴的时候,却不小心给摔死了!”
男人贼说:“哎呀,我的苦才是一言难尽啊.那天我刚出来,就被CT的狙击给爆了头!”
新来的贼说:“我那天看大家匆匆离去,但是谁掉了一个闪着红光的小盒子,我等没了人的时候就去拣……”

2008年9月19日星期五

An Autobiography of a Windows Forms custom control in its own words [ComboView]



Introduction
Who am I? What am I doing here at CodeProject? Well, I’ll answer myself all these questions and others.
I am a ComboView control. You might think, well what’s that? Well, I am a ComboBox with the capability of displaying columnar items in a ListView. Well, you might ask, there are lot of other similar controls available, then what’s so special about me. Nothing, the only difference being I am going to narrate to you how I had been brought to life, and on this journey to my creation, the lessons learned by my creator.
In the Beginning
It was all a few days back when a crazy developer thought of creating me. It was not out of love for me but out of greed. The greed to learn something, the greed to understand the intricacies of control development etc. etc. So, you see a man is very greedy. He does everything for his needs.
Well, let's see what all things were on his mind when he was planning to create me.
He needs to learn control creation in .NET (specifically in C#).
He needs to understand how to create a composite control.
He needs to understand the way ListView works.
He needs to understand the details of how to provide custom databinding.
He needs to understand how to work with custom events.
Etc…
Well, I need to admit one thing. I am not one of the best controls, not even closest to them. But I am happy because to certain degree, it was through me the creator of me understood all the above objectives (or I assume he understood).
Let's dissect myself, and on the journey, you and me can learn a few things.
Dissecting myself
First things first. In order for me to come into existence, I needed to have a parent. The developer decided that the UserControl should be my parent.
So, I was inherited from System.Windows.Forms.Usercontrol. That would imply that I would be having all the attributes and behavior of my parent (UserControl).public class MyCombo : System.Windows.Forms.UserControl
{
Since I am a ComboView, in order for me to come into existence, I would require the support of a few other controls, specifically, a Button, a ListView and a TextBox. private System.Windows.Forms.ListView lvObject;
private System.Windows.Forms.TextBox txtObject;
private System.Windows.Forms.Button btnDropDown;
OK, I would explain why the above three controls are required:
The ListView would be used to display the data in multi-columnar form.
The TextBox would be used to display the selected value.
The Button would serve the purpose of drilling me up and down.
Then the developer needed certain variables to control my behavior. So, he declared it in its own region.#region MyCombo Variables
private object _dataSource;
private string _dataMember;
private string _displayMember;
private string _valueMember;
protected ArrayList _columnHeader = new ArrayList();
private object _selectedValue;
private object _selectedText;
//Size
const int MIN_WIDTH = 140;
const int MIN_HEIGHT = 22;
#endregion
Let me tell you what some of these variables mean to me, rest are obvious. (Later, we will add respective set/get property for the above variables.)
_dataSource
I need to be able to populate myself with data from different sources like custom class, a database, an XML file etc. Use this property to assign the data source.
_dataMember
A _dataSource can contain multiple tables. Specify which table I should pick up the data from through this property.
_displayMember
Since I would present myself in multi-column format, specify which column to display in the TextBox through this property.
_valueMember
This would ideally be the unique ID for each of the data elements within a single row of data. You would require this value for querying, saving etc.
_selectedValue
This returns the value from _valueMember variable.
_selectedText
This returns the value from _displayMember variable.
_columnHeader
This is an ArrayList. This will hold the columns' title with me.
Now comes the events part. Events are needed in order for the user of the control to know when something happens to me. Right now, the developer has provided only one custom event.#region MyCombo Events
public delegate void
SelectedItemChangedEventHandler(object sender, EventArgs e);
public event SelectedItemChangedEventHandler
OnSelectedItemChangedHandler;
#endregion
The OnSelectedItemChangedHandler will be raised whenever the user selects any of the list items from the ListView.
As I promised, here are my corresponding get/set accessors. The user of me would see this properties rather than the variables we have seen above. public string DisplayMember
{
get
{
return _displayMember;
}
set
{
_displayMember = value;
}

}
public string ValueMember
{
get
{
return _valueMember;
}
set
{
_valueMember = value;
}
}
public string DataMember
{
get
{
return _dataMember;
}
set
{
_dataMember = value;
}
}
public object DataSource
{
get
{
return _dataSource;
}
set
{
_dataSource = value;
OnDataBind();
}
}
public object SelectedText
{
get
{
return _selectedText;
}
set
{
_selectedText=value;
}
}
public object SelectedValue
{
get
{
return _selectedValue;
}
set
{
_selectedValue = value;
}
}
In the DataSource property, you see a method OnDataBind(). This would be explained as we go further.
Now, there should be a mechanism through which the user of me would assign columns to me. That’s taken care by the following function. The function takes two parameters, the name of the column and the width of the column. This function simply adds the column name to the ArrayList we just saw above. public void Columns(string columnName, int colWidth)
{
_columnHeader.Add(columnName);
OnHeaderBind(columnName,colWidth);
}
Now, lets see the OnHeaderBind() function. This function adds the columnName to the actual ListView object and also sets its width. protected void OnHeaderBind(object v, int colWidth)
{
lvObject.Columns.Add(v.ToString(), colWidth, HorizontalAlignment.Left);
}
There should also be a provision for manually adding data to me rather than using a data source and data member. This is achieved by the following function. This function takes an ID, and an array of items to be added to the ListView. So, the user of me can add an item to me like:.Add (“101”,”Rajesh”,”23) public void Add(string id, params string [] items)
{
ListViewItem lvi = new ListViewItem(id);
foreach(string s in items)
{
lvi.SubItems.Add(s);
}
lvObject.Items.Add(lvi);
}
Now, as promised earlier, let's come to the OnDataBind() method. This method is called whenever you assign a data source to me. This method would just fill the ListView the information from the data source. protected void OnDataBind()
{
if (_dataSource == null)
return;
IList iList = InnerDataSource();
Type type = iList.GetType();
string s;
for (int i = 0; i < s=" GetField(RuntimeHelpers.GetObjectValue(iList[i]),_valueMember);" lvi =" new" j =" 1;"> 0)
{
iList = ((IListSource)
((DataSet)_dataSource).Tables[_dataMember]).GetList();
}
else
{
iList = ((IListSource)((DataSet)_dataSource).Tables[0]).GetList();
}
}
else if (_dataSource is IListSource)
{
iList = ((IListSource)_dataSource).GetList();
}
else if (_dataSource is ICollection)
{
object[] objs = new object[((ICollection)_dataSource).Count];
((ICollection)_dataSource).CopyTo(objs,0);
iList = objs;
}
else
{
iList = (IList)_dataSource;
}
return iList;
}
IListSource: this interface provides functionality to an object to return a list that can be bound to a data source.
ICollection: this interface defines size, enumerators and synchronization methods for all collections.
Compile me, add a test project and add reference to me, and I am ready to face the world.
That’s it to me for now. There are lots of things that needs to be done to me. Probably, that would come later on.
I hope you enjoyed reading me. Any suggestions, criticism, ideas should be directed to the creator of me, so that he could improve me or learn a bit more.
For complete source code, check the sample project uploaded with this article.
Bye for now,
ComboView
Credits
InnerDataSource and related functions -> These functions has been taken from The Code Project/ or somewhere from the Internet. If any one knows the original author, please sent a comment to me, I would like to give credit to him.
Revision History
12-28-2003: Original article.