﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-&#xE; oDiBo  “开封菜”WWW.KFC.IM-随笔分类-学习方法</title><link>http://www.blogjava.net/chenjiajin/category/40271.html</link><description>KFC.im记录学习、工作、生活中的点点滴滴…</description><language>zh-cn</language><lastBuildDate>Tue, 30 Jun 2009 03:12:37 GMT</lastBuildDate><pubDate>Tue, 30 Jun 2009 03:12:37 GMT</pubDate><ttl>60</ttl><item><title>软件开发的武陵秘笈</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/30/284703.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Tue, 30 Jun 2009 00:23:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/30/284703.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/284703.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/30/284703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/284703.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/284703.html</trackback:ping><description><![CDATA[<p>中国人大都喜欢用武侠小说来比较软件开发，但是在实战武功中，只有葵花宝典才是最厉害的，也只有掌握了葵花宝典，才能称为"不败"。 但什么才是软件开发的葵花宝典？</p>
<p>让我们先从一些现象出发。我们的前提是，软件开发是一项智力密集型劳动。对于智力密集型劳动，我们观察到的现象是，个体的表现差异很大，团队的表现差异很大，组织的表现差异很大，国家的表现差异很大。这不象体力占主要的劳动，象百米王跑百米的速度也仅比我快50%。但在棋类运动中，一个高手可以车轮战数位低手，而且毫无例外地将他们一一击败！</p>
<p>这些智力运动员表现出的特点是，计算精确而且速度快。其行为很象东方不败。虽然关于葵花宝典的传说很多，但最准确的描述只有一个字"快"。东方不败已经快到了吓人的地步。就象卡斯帕罗夫已快到了深蓝的地步。</p>
<p>有一则关于物理学家玻尔的轶事，有一次玻尔在普林斯顿大学听两个年青教授演讲他们的工作成果。期间玻尔突然发言说，如果照你们的研究算下去，会得到一个很有意思的推论。结果两个年青教授回去计算了两天，果然得出了同样的结论。玻尔是如何做到这样快的？</p>
<p>在软件开发中，我们同样注意到这样一种高手，他们可以每天写出一千行左右的高品质代码。他们可以运用已有的一些软件包，迅速完成一个新的产品。他们可以在很短的时间内，学会一项新的程序语言或是新技术。他们表现出一种神奇的速度。</p>
<p>在武侠小说中，所有的高手都有一些凡人不能企及的表现。象张无忌学太极，用龙爪手击败龙爪手名家；乔峰用太祖长拳击败天下英雄；姑苏慕容以其人之道还治其人之身，令狐冲一剑剌瞎十几双眼睛等等。我认为，之所以他们能做到这样，关键是在于他们快。</p>
<p>快并不意味着不准或品质差。快与品质并不矛盾。</p>
<p>高手的快，其实包含着很高的品质在其中。如果你因为高手的快，就质疑其品质，那就相当于在问：东方不败出手那么快，会不会刺不准？东方不败并不满足于刺死对手，他会在对手身上刺朵花。他把杀人变成了艺术。准确来说，他真正的兴趣不在杀人，而在于艺术。</p>
<p>退一步说，就算东方不败第一击有点偏差，他稍作修正后，马上跟上的第二第三击，也会击中他想击中的地方。在武功差的对手剑还没拨出来的时候，他已杀死对方并刺上了一朵花。</p>
<p>所以真正的软件高手，他并不满足于他的代码能有效地工作了，他认为编程是艺术，并醉心于其中。在低手能写出一个版本的时间里，他已经写出了第十版。其品质当然不可同日而语。就象一个九段棋手，在给定的时间里，他能计算十种可能，并将每种可能计算到100手之后，从中选择一种最有利的下法。低手岂有苟全的机会？</p>
<p>高手写软件总是不停地在重构(refactoring）。高手喜欢迭代式开发。高手说，增量就是打补丁，迭代就是推倒重来。对于软件这种东西，写一遍它可能OK（做到这一点也不容易），写十遍就是一个伟大的产品，再多写一遍它就更伟大些。</p>
<p>高手快的诀窍在于他很熟悉各种东西。高手看书很快，因为每一本新书里，值得他好好看的新技术只有一两章的内容。他能迅速看完，并准确领会这本书的中心思想和价值。而对于一个新手，每句话都是新的，他都需要去理解，每一段例子，他都需要去试。</p>
<p>很少看到一种100%全新的技术或理论。就象Java language specification里说的，Java没有使用任何新技术，用的都是业界久经考验的技术。对于高手来说，那些技术都是他所熟悉的。自然，很快他就从一个C++高手变成了Java高手。如果一个编程新手学Java，学两年也不如一个高手学两个月的。高手学新东西快。</p>
<p>高手写代码速度快。统计结果说，人均每人月的有效代码速度大概是300至400行。但那是业界平均生产效率。对于高手来说，这个数字太低了。每天写300至400行是完全有可能的。因为在写代码时，所有知识都已具备，已经没有任何需要他多花时间的事情了。他甚至很少需要Debug。</p>
<p>高手重用代码的能力很强，熟悉新的API的速度很快。这也是因为，他曾经使用过很多的API，重用过很多的代码。他知道哪些是可用的，哪些有缺陷。他既过用Qt，也用过gtk+，也用过windows API &amp; MFC，也用过AWT &amp; SWING。新的API对他来说，也是老熟人。</p>
<p>高手喜欢用轻量级的工具，象vi，notepad，最多到UltraEdit这样复杂的。高手用这种工具写出很多的东西。这些工具就象东方不败的针。那根针已具有神奇的魔力，有时候它可以当激光枪来用。</p>
<p>对于一些重量级的工具，高手虽不常用，但一经使出也威力大于常人。如果让东方不败用剑，最厉害的剑术名家也会败得很难看。高手其实用过很多的重量级工具，而且深知其优缺点。所以使出来，就会把威力发挥到最大，而把缺陷减少到最小。而低手则不然，总是把缺陷加以大大的发扬而浑不知其精髓何在。就象很多人学用UML、RUP、XP、Design pattern那样。</p>
<p>高手所学博杂且融会贯通。高手做什么都快，当低手还在一愁莫展的时候，高手已经圆满解决问题，去干别的事去了。</p>
<p>在成为高手的路上，要有热情，要循序渐进，要持之以恒。</p>
<p>要逼自己，书要快快地看。要试图迅速理解其主旨。其实你快快看所接受的信息量，与慢慢看接受的差不多。能明白多少很大程度上取决于你的功底。以后用到再回过头来看。一本对你来说新东西太多的书，不要指望看一次就全理解吸收。就象很多功力不够的人看design patterns那本书一样。慢慢看还不如找到多种信息来源，都快快看一遍。对于一个完全陌生的领域，只看一本书很远远不够的。</p>
<p>要逼自已，事要快快做。有一个朋友，几年前我介绍他去玩玩linux，他也表示想玩，但他现在还没碰过。他失去了很多机会。</p>
<p>平时要有意识提高自己写代码的速度，其实你一天写15行有效代码，与你写50行有效代码，其品质是差不多的。你应该把那些业界平均水平抛诸脑后，把超越自己做为唯一目标。等到你写了很多各式各样的代码，你的水平就不一般了。一个老师曾向我介绍他的学英语的决窍，他说你去啃原版小说，啃到50本，就和一般人有很大距离了。就是这个理。如果你写得太慢，怎么能写得多？水平怎么能提高？</p>
<p>要逼自己，学很多别人怕学的东西。低手总会说：这么多东西怎么学得过来啊。于是就少学或不学。这样就成不了高手了。高手有非常广的知识面，有很丰富的经验。知道很多低手不知道的事。玩过很多低手听都没听过的东西。</p>
<p>要逼自己，努力满足客户的各种需求。个人技能是在满足客户的各种需求的过程中提高的。比如你喜欢用Delphi，客户说一定要用VB，那你就答应他，然后把自己培养成为VB的高手。用户的需求看似变态，但对你是一个机会。</p>
<p>怎样才能做到看书快，写代码快，学新东西快，一个显而易见的途径就是将工作并行化。你在一台机器上make时，同时可以在看别的文档和聊天。对于计算机是这样，对人也是这样。如果你只能串行地处理问题，你的速度将提高有限。你的大脑有很大潜力可挖，它应该是一个多任务分时系统。努力减少它idle的时间。搞经济的Samuelson被人称为human brain main frame，可见他的大脑有多快。</p>
<p>让你的思维快起来，你就会区别于那些反应迟钝的人。如果你不能让人生的道路变长，就让它变宽。这世界变化快，需要你变得比它快才行。</p>
<p>这样加快并不会让你短命，相反，你有更多的时间来享受生活和锻炼身体。你的生活将更有品质，更丰富，更有意义。面对变化，你将立于不败之地。我们都是和自己赛跑的人，需要跑得比昨天的自己更快。</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/284703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-30 08:23 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/30/284703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>俞敏洪：度过有意义的生命</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/17/282740.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Tue, 16 Jun 2009 23:57:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/17/282740.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/282740.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/17/282740.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/282740.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/282740.html</trackback:ping><description><![CDATA[<p>　　6月2日，新东方教育科技集团董事长兼首席执行官俞敏洪，莅临同济大学，为同济学子做主题为&#8220;度过有意义的生命&#8221;演讲。</p>
<p>&nbsp;</p>
<p><br />
同济大学的同学们大家晚上好！</p>
<p><br />
　　其实人活着就挺好，至于生命有没有意义另当别论。活着每天都会有太阳升起来，每天都会看到太阳落下去。你就可以看到朝霞，看到晚霞，看到月亮升起和落下，看到满天的繁星，这就是活着的最美好的意义所在。</p>
<p><br />
　　没想到同济大学的同学们把我如此&#8220;高大&#8221;的形象放在大屏幕上，这就是理想与现实的差距。所以我相信同学们看到我的第一眼一定感到非常的失望。实际上，每一个人都是非常普通的，我们很多时候会发现生命中非常重要的东西跟我们未来的幸福和成功其实没有太多的联系。比如，有人认为，相貌跟未来的成功会有很多的联系；有人认为，自己的家庭背景会跟成功有必然的联；有人认为，上名牌大学的人会成功，在大学里成绩好的人比学习成绩差的人更加容易取得成功&#8230;&#8230;所有这些因素可能有部分是对的，但大部分基本无效，比如说相貌。</p>
<p><br />
　　如果说一个人的相貌和成功有关，那就不会有马云和阿里巴巴，因为如果在座的同学认为马云长得好看，那一定是审美出了问题。</p>
<p><br />
　　当然，这并不意味着相貌好看的人就做不成事情，比如说，另外一位大家比较熟悉的公司老总百度老总李彦宏。李彦宏非常英俊潇洒，他所有的照片看上去都像电影明星一样，但是他也取得了成功。所以不管相貌如何，都能取得成功，只不过李彦宏和马云坐在一起吃饭的时候，他们通常不太愿意坐在相邻的椅子上，因为两个人的对照到了惨不忍睹的地步，解决的方法就是把我放到他们两个中间，起到一个过渡的作用。像我这样，相貌没有什么特点的人也能取得成功。所以不管是男是女，最重要的是自己内心世界的丰富，自己风度和气质的培养，自己胸怀的扩展以及对理想目标坚定不移的追求。随着年龄的增加，这些会慢慢变成你的智慧，所有这一切才是构成你成功的真正的本质。</p>
<p><br />
　　那么成功和家庭背景有没有关系呢？我们常可以看到一些权贵富贾出身的人，他们一出生就含着金钥匙。比如，我们可能会看到，自己左边的一些同学穿着名牌服装，右边的拎着名牌的皮包，前面坐着市委书记的女儿，后面坐着中央领导的儿子，而你可能就一个来自普通工人家庭的大学生。</p>
<p><br />
　　有的时候你会心存不满，但这个世界本来就充满着不公平，而很多不公平常常就在你的眼前闪现。你会说，这个世界怎么会对我这样，为什么他什么都有，而我什么都没有？我在大学里也有过这种很正常的心理。比如，我的同学有部长的儿子、有大学教授的女儿，而我却是一个农民的儿子。3次高考后才走进了北京大学，穿着布衣挑着扁担走进去的。你会发现你总赶不上他们的状态，倒不如说赶不上他们的脚步。你会发现即使他们停下来一辈子什么都不做，他们所拥有的东西都比你多。</p>
<p><br />
　　比如，在大学一年级的时候，班上那个部长的孩子每周五都有开着奔驰280的司机把他接回去。你想我们那个时候连自行车都买不起，他居然坐着奔驰280，那是一种什么样的感觉。你感到这辈子基本就完蛋了。但是同学们你们要记住一个真理，生命总是往前走的，我们要走一辈子。我们既不是只走过大学四年，或研究生，我们要走一辈子。可能走到80、90岁，虽然走到80、90岁时，人生到底怎么样你是不知道的，你惟一能做的就是要坚持走下去。所以我非常骄傲地从一个农民的儿子走到北大最后又走到了今天。我的心态很平衡，但其实我走了很远。当然，有的同学会说，你进了北大就已经很成功了。确实，北大增加了我很多成功的因素。比如，因为北大读书气氛很浓厚，所以我读了很多的书，思维变得很敏锐。</p>
<p><br />
　　北大确实有人文的环境，蔡元培的铜像就树立在未名湖边上，但是每年进北大的有好几千人，出北大的也有几千人，能够成功的到底有多少呢？事实上，北大学生成功的比率并不比任何一个大学生成功比例高。</p>
<p><br />
　　所有的成功意味着你大学毕业后要进一步付出努力，如果大学就意味成功的话，那么也就没有马云了。我跟马云有很多相同的地方，他高考考了3年，我也考了3年，他考的是英语专业，我也考的是英语专业，第三年我去了北大，他去了杭州师范学院。我相信很多同学都没听说过这个学院，那我觉得我这辈子应该比他更加成功吧，但是非常不幸的是，从今天来看，阿里巴巴上市的市值就是新东方的3倍，而我除了做成一个新东方便什么都没了。不仅如此，他还有淘宝网、支付宝&#8230;&#8230;</p>
<p><br />
　　所以，你未来的成功和你上什么大学没有什么联系，只不过以后出国就业更加的容易一点。一辈子能不能走出精彩，大学为你奠定了基础，但不能决定你的一生。到大学毕业人生也只过了四分之一，接下来的时间我们该怎么过呢？首先是一定要坚持走下去，因为你不活了就什么都没有了。不管你相信不相信来世，我始终相信今生今世就是我们最好的天堂。所以我最讨厌自杀或者以自杀为威胁，我觉得这是对生命不尊重。有种理念，叫做&#8220;好死不如赖活着&#8221;。因为从我40多年的人生经验来体会，你在那坐久了，说不定天上真的会掉下馅饼来，当然也可能掉下块陨石。但不管怎样，不要自我了断，生命中会有很多奇迹发生。假如杨振宁教授不活到82岁，他怎么知道还能结第二次婚呢？</p>
<p><br />
　　但是同学们，人生总是要有份期待，哪怕是没有希望的期待。同学们可以想一下我们历史上有很多人物，比如说姜太公在河边钓鱼，到了80岁那一年，周文王在他边上走过，发现这个老头用直的鱼竿钓鱼，跟他一聊便发现这个老头很有智慧，所以把他带回去，两人一起打下了周朝的天下。齐白石同志在50岁的时候还在做木工，根本不是个伟大的画家，他的所有伟大的作品都是在80岁到90岁的时候完成的。所以生命总有这样的现象，有的人在年轻的时候有作为，有的人中年时候有作为，有的人老年时候有作为。花儿总是在不同的季节开放，如果所有的鲜花都在春天开放完毕了，到了夏天、秋天、冬天没有任何的花儿开放你还会觉得这个自然界是如此的美丽动人吗？</p>
<p>　　所以大家想一想，如果人生所有的精彩都在大学里过完了，后面永远都是平淡，你觉得这人生会完美吗？换句话说，你大学里过的不那么精彩，毕业后却变得越来越精彩是不是更加好呢？事实证明，我们很多同学在大学里的成绩总是名列前茅，可是大学毕业后却怎么也做不出什么事情来了。因为在社会上，并不是成绩在起作用。成绩只能证明你智商比别人高，但并不能决定你一辈子就一定有出息。</p>
<p><br />
　　成功并不仅仅是你的成绩所决定的，最重要的是与社会打交道的能力，为人处世的能力。在各种混乱的人际关系中，寻找机会的能力，以及你最后领导一帮人跟你一起创事业的能力。而所有的这一切都不是由你的成绩决定的。当然我并不是说，在大学不要好好学，拿到大学毕业证书这是必然的，因为在未来我们会发现这样一个现象，假如，连大学本科文凭都拿不到的话，你的生命将充满艰难。</p>
<p><br />
　　现在读过大学的人很多，有人说现在上大学没什么意思，因为找不到工作。确实到现在为止，今年应届毕业生找到工作的比例只有40%左右，但我相信这只是一个临时现象，因为中国的产业结构还没有调整过来。从历史来看，中国大学生远远不多，因为中国从制造业正在转向咨询、信息、物流、服务等与世界沟通交流的行业，也就意味着在座的所有大学生都具备这样的工作能力，必然能找到工作。</p>
<p><br />
　　一次有个大学生告诉我，俞老师我要创业，不上大学了。我说为什么，他说要向比尔&#183;盖茨学习。我说世界上有几个比尔&#183;盖茨，不就一个嘛，他说没关系，他可以成为第二个。我说，那你为什么不上大学呢？他说，我考试不及格，上不下去了。这还是没法跟比尔&#183;盖茨比的，人家是觉得自己的知识已经远远超过了老师，觉得上大学已经是时间的浪费，要把自己的创造力及时的发挥出来，所以钻到自己的汽车库里研究微软去了。这是两种完全不一样的概念。</p>
<p><br />
　　当然我刚刚强调的是你学习成绩好并不一定今后就做的好。有一份统计数据，将大学成绩前10名和后10名的同学做过一个调研，以20年一个阶段来说，大学最后10名的同学财富总量以及获得的社会地位，居然比前10名还要高。这就意味着，即便在大学里最落后的同学也不要放弃自己。比如，我在北大努力了5年，在毕业的时候就是以全班倒数第五名毕业的，但现在我们班的第一名到第五名全在新东方。所以，我们永远都不要放弃自己。</p>
<p><br />
　　是不是我们人生走长了就必然会有成就呢？不是的，因为人生的走法有两种：第一种在平原上走，走到90岁，十分的平坦，但是你却看不到周边美丽的景色。因为平原两岸的风景都是一样的。所以，当回顾自己一生的时候发现一片空白。</p>
<p><br />
　　我们的人生必须像连绵不绝的山脉一样，像青藏高原一样的度过。总是有无数的险峰在眼前需要我们去征服，而一旦我们登上险峰后，生命中无限的风光就会展现出来，整个世界都尽收眼底。当然，攀登并不是一件容易的事情，你必须付出很多代价，但这种代价都是值得的。你爬到一座山头，如果要去另外一个山头，必须从底下开始重新攀爬，因为没有任何两个山头是连在一起的。</p>
<p><br />
　　最精彩的人生是到老年的时候能够写出一部回忆录来，自己会因曾经经历过的生命而感动，会感动别人继续为生命的精彩而奋斗，这时候我才能说我的生命很充实。</p>
<p>　　很多同学家境富裕，要买手机、电脑，父母都会满足你，你在得到的一瞬间会感到很快乐，但因为容易得到，所以容易失去。因为容易，所以不会珍惜。而生命中最美好的就是珍惜得到的东西，珍惜的前提必定是因为你得来不易。</p>
<p><br />
　　我10年前就碰到一个特别令人感动的故事：有一个大学生来找我，因为非常贫困，但想出国，想上新东方的GRE和TOEFL班，但是他没钱所以跟我说他很想上新东方的课，但没钱，能不能暑假在新东方兼职做教室管理员，并且安排他到TOEFL和GRE的班，查完学生的听课证扫完地后就在后面听课，我说当然可以。没想到这个学生又提了个要求，如果两个月的兼职真的做的很好的话，能否给他500元工资让他买个录音机，我说没有问题。结果那孩子做了两个月，所有接触过他的人都说这孩子刻苦认真，所以到了两个月后，我给他一千块钱的工资让他买录音机。他买好后，边听着录音机边流着泪。我知道他被自己的行为感动了，以后肯定有大出息，果不其然几年后他被耶鲁大学以全额奖学金录取了，现在还在美国工作，年薪13万5千美元。所以说只有被自己感动的生命才会精彩。</p>
<p><br />
　　其实我也有一些让自己感动的故事，比如说我高考落榜。当时想着一定要考进大学，但没想过进北大，所以就拼命读书。有的时候你会发现你低着头一直往前走，目标就会在你的后面。所以当我拿到北大录取通知书的时候，真的是仰天大笑然后嚎啕大哭，跟范进中举一模一样。但如果当时没有坚持的话，也许我现在仍然只是一个农民的儿子。比如，当时我们村有个人跟我一样考了两年，他总分还比我高三分，当时我跟他说一起考第三年吧，但他的母亲说别考了，找个女人结婚算了，但当时我跟我妈说你让我再考一年，结果第三年我真的考上了。所以我得出两个结论，1、人必须往前跑，不一定要跑的快，但是要跑的久；2、不能停下来，你不能三天打渔两天晒网，要持之以恒。</p>
<p><br />
　　我走到今天没有一天懒惰过，我现在每天依然要工作近16个小时，从高考那天开始每天如此。但我发现，我还是比不过有些同事。从小学到高中，我学习也挺认真的，成绩总是在前10到20名之间，而在大学我学习更加认真，但最后却以全班倒数第五名毕业。龟兔赛跑的故事我们从小学就知道了，而生活中也经常体现出来。因为跑得快的人往往会停下来，而跑得慢的不能因为慢就不跑。只要跑，早晚会达到你所向往的终点。所以我们不要去计较大学时候谁的成绩高低，只要不停的去追求就可以了。</p>
<p><br />
　　有一次，一个朋友问我马和骆驼一辈子谁走的远吗？我觉得一定是马，他说您错了，骆驼走的路要远远比马多，因为马跑一会儿就会停下来，而骆驼一旦开始走，如果不让它停，它是不会停的。所以，一个聪明的人一辈子所创造的成就不一定比一个笨的人所创造的多，因为笨的人每天都在创造，而聪明的人可能创造一段时间会停下，即便是爱迪生这种超级天才，小时候也被认为是个白痴。爱因斯坦九岁才会说话，还好他有个好妈妈一直认为他是个天才，才使他成为一个伟大的科学家。所以当我的儿子到4岁时还不会说话，我老婆着急地带他到处求医时，我说，别看，4岁不会说话很正常的。我老婆说，为什么正常，我说，不会说话是语言功能发育不完全，不代表头脑就不发达。所以永远不要用你的现状去判断你的未来，只要你坚持就一定能获得你所意想不到的东西。</p>
<p><br />
　　生命中有很多意想不到的事情，比如，我高考三年从来都没想到会考进北大，但成绩公布后我发现超出了北京大学录取分数线7分。我们当时是考后填志愿的，当时我填好后还担心不一定被录取，结果北大还是录取了我。因为很多分数比我高的人没敢填写北京大学。之后我进入北大，由于成绩不好总在班级倒数，但我始终没有放弃学习。</p>
<p><br />
　　后来我班级里很多同学都联系出国，我看了羡慕，想要追赶他们的步伐，所以也开始联系出国。整整4年，联系了无数的美国大学和专业，没有一个美国大学给我奖学金。尽管拿到了几张录取通知书，但去美国大使馆签证，每次都拒签。当然，现在我的签证除了伊拉克的没有，其他国家几乎都有了。现在美国给我的签证是10年多次往返商务签证。因为新东方是在美国上市的，他必须允许我任何一天随时随地都能进入美国。所以当我儿时的朋友到现在还在面向黄河，这辈子还没有走出过我们镇的时候，我已经走遍了世界各地。大家想，在徐霞客、苏轼那个没有任何交通工具的时代，都能游遍山水，写下许多让我们感动和动人的文字，而在我们这个科技兴盛的时代，如果没有在世界上留下一些的文字和足迹，你怎么对得起自己。</p>
<p><br />
　　有的同学说，俞老师因为你现在有钱了所以可以这么做。坦率的说，以前我没钱我也会这样做。因为小时候我最崇拜的人物就是徐霞客，因为他是我的老乡，住在我家隔壁。只不过他是400年前住在我家隔壁，要知道地方上的名人对地方上少年的影响是非常巨大的。有次，我坐在长江边上看日出日落，我就在想徐霞客怎么能走那么远呢？所以也会向往这辈子我是否能跟他走的一样远。</p>
<p><br />
　　正是因为有这样一个榜样在，我才会发现高考一次、两次我都不绝望，因为我知道走出农村边界的惟一办法就是考上大学。我想把农村户口变成城市户口，因为当时城市户口是可以到处走的。尽管我平时很平和，但心中总是有一种愿望，叫做穿越地平线走向远方的渴望，就是看到眼前的地平线我总是不满足的，我总是希望翻开地平线看看另一边到底是什么样的。</p>
<p><br />
　　大家都知道，只要你不断的超越地平线一定会有很多的风景在你眼前展示出来。这跟你有没有钱没关系。而我曾怀揣100元人民币，走到了泰山，走到了黄山，走到了九华山，走到了庐山。我一边走一边帮人家干活，走到九华山发现没钱了，就睡到一个农民家里。那个农民在江边给我弄了个床，还找我要钱，而我口袋里只有5块钱。于是，我就说帮他一起插秧来抵消住宿费。他左看右看说，大学生怎么会插秧呢？结果插了一天我插了四分之三，而他只插了四分之一，把他感动的半死不活。他说，你怎么会插的那么快呢？我说，我14岁那年就获得过我们县的插秧冠军。然后，他晚上杀了一只鸡要我一起喝酒。他越聊越觉得我不像大学生更像农民。第二天我走的时候，他居然掏了10块钱给我说，我知道你口袋里没钱了，明天还要去庐山，这点钱就给你当路费。</p>
<p><br />
　　生命是有各种活法的，但是哪怕你坐到书斋中间，一辈子也要让自己的生命变的伟大。陈景润一辈子没出过书斋，不也是世界上最伟大的数学家？所以不管在什么状态下也要像一首诗写的那样&#8220;相信未来，热爱生命&#8221;。所以只有当我们的生命有了期待以后，才会有进步。有的时候，我们选择前进，不是因为我们有多么坚强。有这么一句话让我很感动，也变成了我的座右铭：&#8220;坚持下去不是因为我很坚强，而是因为我别无选择。&#8221;新东方有一个运动，叫做徒步50公里。任何一个新东方新入职的老师和员工都必须徒步50公里，而未来的每一年也都要徒步50公里。很多人从来没走过那么远的路，一般走到10公里就走不动了，尤其是要爬山涉水地走。每次我都会带着新东方员工走，走到一半的时候会有人想退缩，我说不行，你可以不走，但是把辞职报告先递上来。当走到25公里的时候你只有3个选择，第一，继续往前走；第二，往后退；但当你走到一半的时候，你往后退也是25公里，还不如坚持往前走呢；第三，站在原地不动。而在人生旅途中停止不前还有什么希望呢？</p>
<p><br />
　　我们人生有很多迷茫和痛苦，而只要你坚持往前走，痛苦往往会解决掉。在走的过程中，我也痛苦得流过泪，也曾经痛苦得嚎啕大哭过，但我知道真的坚持下去不是因为你坚强而是因为你别无选择。走到最后你会发现总会有成果。我没想到新东方能从培训13个学生，现在变成培训175万学生、其实所有这一切你都不一定要去想，只要坚持往前走就行了。</p>
<p><br />
　　我们生命中总要去追寻一种经历，有的时候我们觉得人连条鱼都不如，因为我在加拿大的时候，我看过加拿大三文鱼回流，每次它回流产卵的时候，我总会发现生命及其壮观，鱼卵产在沙子里会被其他动物吃掉很多。第二年春天的时候剩下的鱼卵会变成小鱼，小鱼会顺流而下，流到湖里，而在湖里又会被其他鱼类吃掉一些。一年后，长大的鱼会顺着大河奔入海洋，然后绕太平洋一周，每四年一个循环。如果三文鱼就在海洋中待着不回到湖里产卵，它就不会死，但它是受到内心的召唤集中在河口开始往前游，一旦游进河的时候就再也不吃任何东西拼命地往前游，然后游到目的地开始配对产卵，产好后就双双死亡。你会看到成千上万的红色死鱼漂在河上，而老鹰和黑熊就在边上等着。</p>
<p><br />
　　我看了后特别感动，一条小小的三文鱼也知道，生的使命是不能放弃。那我们人生的使命呢，比如父母为我们献出了青春财富，把你养育成人。而我们未来变成父母后也是一样。我们孩子的成长就是你的使命，而我们其他的使命感，如何让自己活得更加幸福，如何帮助别人，让这个社会变得更加有意义。为什么宗教人士会活得相对简单，因为他们灌输了一种使命感。而连一条鱼都经历了小溪流、湖泊、大海，他尝到了淡水的清香和海水的苦涩，完成了生命的周期。如果我们这一辈子都没有苦涩，没有幸福和甜美，那生命是很遗憾的。</p>
<p>　<br />
　　而你现在的状况并不决定于你的未来，我在北大的时候受到的打击比较多，首先是身份上的悬殊，确实我是穿着大补丁走进校园的，我们体育老师上课从来不叫我的名字的，都是叫那个大补丁来做个动作。因为我在农村锻炼过，跳跃性动作做得蛮好看，所以我常常被叫出来做演示。</p>
<p><br />
　　开学第一天晚上，全班开班会，我起来讲了一句话。现在新东方的王强老师是我们班级的班长，站起来跟我说你能不能不讲日语。因为我一直在农村上学，所以我们的语文老师从来没用普通话给我们上过课，我当时根本不知道普通话该怎么说。北大当时按照英语成绩分班，我当时因为高考英语考得蛮好所以被分到了A班，其实我的听说水平并不好，所以到了A班一个月以后就被贬到了C班，而C班主要是针对那些语音语调及听力障碍的同学。等后来，我发现我和同学的智商真的有差距，我的那些同学平时看他们学习也并不怎么认真怎么一到期末考试就能考出好成绩，我每天学习时间都要比他们多两三个小时，但每次期末考试都在全班倒数几名。这让我的心情非常郁闷。</p>
<p><br />
　　当时，我们班50个同学，25个男生25个女生。一开始我听完这个数字就特别兴奋，但是没想到我们班的女生没一个正眼瞧我一眼的。到了2001年的时候我们全班同学聚会，大家从世界各地赶回来。蓦然回首，大家突然发现班上那个挺没出息的，普通话也讲不好的，默默无闻的那个人怎么就成了全班最出色的了。这个时候女同学们都热情的走上来握住我的手，后悔当初没下手。</p>
<p><br />
　　所以后来大学女生问我，俞老师我们现在找男朋友要什么标准，我说很简单，参考我的长相。当然如果长得像我，那是绝对不能放过的。凡是长得比我难看的也不要放过，因为这个世界上的规律就是，越难看的人内涵越丰富。</p>
<p>　　大三的时候我最喜欢读的是《红楼梦》，而且刚好读到林黛玉咳嗽而死的那一章。结果发现自己也在吐血。到医院，医生一查说得了肺结核立刻关起来，一关就是一年。我跟医生说像我这样的小伙子怎么会得肺结核呢？医生让我讲讲现状。我说，您看我学习特别刻苦，可成绩就是上不去，班里没有一个女孩子喜欢我。他说，这种情况不得肺结核是完全不可能的。</p>
<p><br />
　　但这个病也给我带来了心态上的调整，因为我在大学一二年级，想要追赶我的同学就是我的精神支柱。但是到了三年级，病了一年后我完全改变了，我觉得活着就挺好。然后我就给自己订了一个最低标准，至少保证大学毕业拿到毕业证书，最后国家给我分配一份工作就挺好。虽然我并没有放弃努力，结果反而获得一个更加开阔的心胸。所以，到现在为止我学会了永远不要去比，因为总有比你更加优秀的，也总有比你更加落后的。</p>
<p><br />
　　这个世界上最正确的是跟自己比，想一想今天是不是比昨天进步了一点，想一想明年是不是比今年更加好一点。想一想，10年以后的你是不是比今年的你要更加出色。这样的心态一直保持到我大学毕业。</p>
<p><br />
　　大学毕业的时候，每个人都要上去讲一段话，比如后半辈子怎么过，我就上去讲了这么一段话：我说，同学们大家都很厉害，我追了大家5年没追上，但是请大家记住了，以后扮演一个骆驼的同学肯定不会放弃自己，你们5年干成的事情我干10年，你们10年干成的事情我干20年，你们20年干成的事情我干40年，实在不行我会保持心情愉快身体健康，到了80岁后把你们一个个送走了我再走。这是我个人保持到现在的人生态度，而我认为这种人生态度对我来说非常有效。</p>
<p><br />
　　有人问我，如果新东方没了怎么办？其实新东方早晚会没的，因为它已经是一个商业化运作的教育机构。大家想一想，前些天我们看到的一个消息，通用公司是美国的标志，不照样濒临破产了吗？新东方可能以后也会这样，变成历史的痕迹。但是我想，即使新东方没有了我依然很成功，因为我的心态很成功。我追求生命的那种向往和穿越地平线的渴望不会改变。我认为，新东方给我的是一种精神，一种力量，而不是新东方本身给我带来多少钱，当然如果新东方给我更多的钱，我也愿意要，不要钱才是傻瓜呢。但更重要的是，有了钱能否做出一些更加有意义的事情来。比如说我现在一直都想做一个小小的私立大学，可能我无法做到像同济大学那么大，但做到它的十分之一总是可以的吧？我在北京已经买了一块地，正在建大学校区，造完后它就跟新东方的上市公司脱钩了，变成一个非营利性的大学校园，那它可能就变成了你做的另外一件事情。</p>
<p><br />
　　如何把自己的生命变的更充实是最重要的事情，所以说，哪天新东方不存在了是非常正常的。如果新东方没了，我照样会过来跟大家做讲座，而且心情会更加的开朗。因为没有繁琐的事情了。我只要换个题目就行了今天叫&#8220;度过有意义的生命&#8221;，下次我改成&#8220;我是如何把新东方做没了的&#8221;。</p>
<p><br />
　　而在大学中，我们要做的几件事情就是：第一，把自己的知识结构打造完整；第二，就是要在大学里尽可能的多交朋友，因为你终身的朋友、合作者一定来自于你的大学；第三，如果有可能的话，在大学里谈一场比较专一的恋爱，因为回顾我北大的生活一片灰色。我想为什么会是灰色呢？其实，不是因为成绩不好，而是因为在大学5年我从来没有过花前月下的时光。所以一直成了我大学时代的遗憾。去年北京大学让我给所有北大新生做开学典礼的时候，我给他们强调一句，什么都不重要，重要的是谈恋爱，而且谈恋爱也不用害怕失败，因为自杀也自杀不了，未名湖就那么浅，跳下去还能爬起来；第四，就是为未来的工作做好打算。未来的工作跟你有多少朋友、跟你的专业知识学的多少是相关的。好好掌握你的专业，再差的专业也一定有人用，只要你学的好。</p>
<p><br />
　　我有一个朋友学的是越南语，越南语的确很少用，但所有的中央领导去越南都要找他，因为他是一流的越南语同声翻译专家。我还有一个大学同学研究蒋介石，研究了10年，穷困潦倒。但后来他去美国做了一个报告，美国方面帮他召开了一个中国现代史人物研讨会，他在报告上讲了自己的研究经过，结果下面一个老教授热泪盈眶。下来后一问，这个老教授也在美国研究了30年蒋介石，孤苦伶仃，就是找不到另一个研究蒋介石的，没想到有个&#8220;傻瓜&#8221;也在研究蒋介石。于是5万美元一年，让我同学跟着他在美国读研究生，然后读了四年的博士生。读完以后老头退休，他就变成了那个学校的教授。我去看他的时候，他已经在纽约买了套小房子，买了辆车娶了个老婆养了条狗。当时他跟我说，俞敏洪你看现在这一切都是蒋介石&#8220;给&#8221;我的。</p>
<p>我想用这个例子来说明什么呢？就是研究什么不重要，重要的是只要你真的喜欢就去做，然后就会有人用你。反过来，如果你觉得这个专业你不太喜欢，但很适合我找工作，这要不要学？当然要学。我就是这样一个状态，我从来没喜欢过英语，当初考英语只是因为数学不行。不喜欢英语是因为我的模仿能力不强。像我的班长王强，能够把任何话都模仿的惟妙惟肖。我普通话练了一年，才练成大家能听懂的样子。我老婆是天津人，跟我一吵架就用天津话骂我，但是我到现在为止只会说一句天津话。就是当她拿起棍子打我的时候，我向她大吼一声，&#8220;干嘛&#8221;（天津话）。</p>
<p><br />
　　但是后来我发现英语成了我生命中的工具，因为英语，我在北大当了老师。其实当初留北大并不是成绩好，而是当时正好四六级考试，北大各个系的同学都要学两年英语，结果北大急缺老师。而一些优秀的毕业生都去了外交部、经贸部，工资又高。后来我们系主任急了说，最后5名给我留下来。留下来的5个人现在都变成博士生导师了，可见现在北大教育质量如何。当然这是句玩笑话，他们后来也经过自己的努力，经历了很多次考试成了很优秀的教师。</p>
<p><br />
　　在登山的时候，你会在乎登山杖你喜欢不喜欢吗？不会，你只会在乎能否帮你登上山顶。那么英语就是我的登山杖，尽管我不是特别的喜欢，但我知道我要想攀上更高的人生的山峰就必须需要这个登山杖。我本来想把自己变成中国英语专家前100位的，后来发现一点戏都没有，因为中国留学生归来的越来越多了，有的在国外待了10年、20年，回来了怎么看英语水平都比我高。那我只能缩小范围，想变成英语语法专家。后来发现背单词不用动脑筋，所以就开始拼命地背单词，结果变成了中国还算不错的词汇专家。</p>
<p><br />
　　除了学专业外，同学们要在大学里多读书。新东方人读书都非常多。读书多，就意味着眼界更加的开阔，更加会思考问题，更具有创新精神。新东方流传一句话叫做&#8220;底蕴的厚度决定事业的高度&#8221;。底蕴的厚度主要来自于两方面，第一多读书，读了大量的书你的知识结构自然就会完整，就会产生智慧；第二就是多人生经历。把人生经历的智慧和读书的智慧结合起来就会变成真正的大智慧，就会变成你未来创造事业的无穷无尽的源泉和工具。</p>
<p><br />
　　比如，新东方招聘重要岗位的人才都是我面试。我只有几个问题，第一你大学读了多少本书，如果你说只读了几十本书，那肯定我不会要你。我心中的最低标准是200本书，而我在大学里读了800本书。新东方还有更红火的王强老师，在大学里读了1200本书，平均每天一本。有的人会问我，读过了忘了跟没读过有什么区别呢？其实完全不一样。就像你谈恋爱，一个谈过恋爱后又变成光棍汉的人和一个光棍汉相比是有自信的。因为当他看到别人在谈恋爱的时候，他会在旁边&#8220;嘿嘿，想当初老子也是谈过恋爱的嘛&#8221;。实在不行来不及读，你可以到书店看着那些书，记着那些名字用手摸一下，这样也能增加一点人文气质。</p>
<p><br />
　　我有一个理念，人活着要过一种诗意的生活，我们有多少时候是停下来看看月亮的，在假期去内蒙看一下漫天的繁星的，有多少同学看着朝霞和晚霞时心中感受过生命的涌动的。当然也要身体力行。大学时候，有一个非常著名的诗人叫海子，写了著名的诗句&#8220;面朝大海，春暖花开&#8221;，但非常可惜的是他没能抵抗现实社会的压力，卧轨自杀了。所以我们说一个人不能只在语言上表达诗意，还要在现实中去表达诗意。所以你必须克服现实中的障碍和挫折。有首诗叫&#8220;大漠孤烟直，长河落日圆&#8221;。我对&#8220;长河落日圆&#8221;有非常深刻的感觉，但对&#8220;大漠孤烟直&#8221;却没有什么概念。所以，进入北大校门之后第一件事情就是走向沙漠，走向戈壁滩，走向大草原。而到今天为止，这些地方成了我的精神家园。如果生命中一有过不去的事情，我就去蒙古草原上跟牧民一起骑马。牧民曾经说过，在汉人当中从来没看到像你那样不要命的。</p>
<p><br />
　　回过来讲诗意的生活，在大学里打游戏上MSN不叫诗意的生活，而在一张床上拿着书一边看书然后慢慢地睡着那就是一种诗意。要关注时事政治，要把握一些世界大事。这种能力将在你日后创业的过程中起到很大的作用。另外就是要尽可能地多交朋友，交朋友首先你要做个好人，你要做一个让人放心的人。在中国企业界就是这样的状态，如果你是个好心的人，在困难的时候一定会有人帮助。比如，蒙牛的牛根生大家都听说过，他为人处世很实在。所以蒙牛出事后，他需要资金，只需要打个电话我们就会把钱汇过去。而为什么连合同都不签我们就给他，道理很简单，信任。</p>
<p><br />
　　我也碰到过这样的情况，03年的时候遇到SARS，我们马上给学生退学费，新东方的流动资金一下子退光了。而当时我算下来，账上还缺2000万。于是我分别给两个朋友打了电话，一人一千万当天晚上就搞定了。所以，你变成一个让别人相信的人，比做一个让别人防着你的人，得到的好处要多得多。而建立这种信任，要做到以下几个要素：要以别人为中心不要以自己为中心；要有服务精神。</p>
<p><br />
　　当时我那些大学同学觉得我没出息，但为什么会回来跟我创业呢？这跟我大学里的行为有关。我大学里是个学习不好但挺喜欢帮别人的人。我们宿舍当时从来不排值日生，因为地全是我扫的。还有就是宿舍的水也基本都是我打，而他们之所以后来放弃国外优秀的条件来和我一起创业还是跟我当时宿舍打水有关系。若干年后，我去找那些大学同学回来，他们说连你那么没出息的人在中国都赚钱了那我们回来还了得？第二个理由是，我们知道你是个特别好的人，你有饭吃不会给我们喝粥，你有粥喝不会让我们饿死，所以就回来了。所以在大学毕业连一个朋友都没有的人，这辈子想成功几乎是不可能的。</p>
<p><br />
　　还有在大学里要交几个真正能帮助你的人，比如：心胸比你开阔，眼光比你敏锐。我在大学里交的就是这样的朋友，做人就要跟着牛人跑。比如，王强老师有天才的一面，而这些是我学不到。他喜欢读书，他一进大学就会把生活费一分为二，一份用来买书，一份用来买饭票，饭票吃完了决不用买书的钱，他宁可偷别人的饭票，我觉得这个习惯很好，我也一分为二，饭票吃完了我就偷他的。每到周末我们就去买书，我不知道买什么书，所以他买什么我跟着买什么，他被我弄烦了说你能不能不跟着我，我说你是我的班长有责任帮助落后同学。其实我知道他想把我赶走，因为当时他是我们班女生追求的对象，如果我不跟着他他就会带女生出去买书，我当时就看穿了他这个阴谋。到现在为止我的读书老师就是王强，他的藏书接近6万本，他每当看到有好的便宜的书就会帮我买，贵的会发个消息让我自己买。</p>
<p><br />
　　到现在为止我都要不断的读书。因为每当聚会，他们谈起好书的时候，一旦我没读过就会被他们说&#8220;你大学时候不用功，怎么现在还是这样。&#8221;所以，我们的读书氛围之所以非常的浓厚，最重要的原因就是王强，而你非常需要这样的朋友。还有就是徐小平老师。大学里我觉得这个老师很好，很想认识。一个礼拜后我买了支小钢笔送给他，敲开他家的门，他问我，你是谁。我说，我是你的学生，听了你的课后很感动，所以想跟你交个朋友，这是我带给你的小礼物。徐小平一看我手中拿着礼物就让我进去了，进了他家的门发现有一大群年轻老师在那。原来他有个习惯，一到周五晚上都会招一批老师来他家聊天。我当然很想听，问我能不能留下来听，他说不行啊，我们聊的都是些男男女女的问题，像你这样的纯情少年会被污染的。幸亏我反应快说，徐老师我在这方面刚好需要启蒙教育。机会总是自己发现的。我发现没有人给他们烧水，于是，我就帮他们烧水煮方便面。连续去了4个礼拜，到了第5个礼拜我不去了。为什么不去，不是因为我烦了，而是我觉得一个人在该显示重要性的时候一定要显示出来。果然徐小平一个电话过来说，你这个兔崽子怎么还不过来。我知道，不是我离不开他们而是他们离不开我了。从此，在一年的时间里，我不停听他们聊天，等到我办新东方的时候，我去的第一家就是徐小平家。我跟他说新东方不缺英语老师，但缺有思想的人物，所以希望你回去管理新东方的思想。所以在大学里要做的另外一件事情就是一定要交朋友，让自己变成一个别人信赖的人。</p>
<p><br />
　　而如果能谈一场恋爱还是很不错的。但谈恋爱有一个非常重要的前提条件就是要一心一意地爱。所谓一心一意的爱不是说，大学里只能谈一次恋爱，而是说一次只能谈一个。要爱到一个什么程度呢？要有这样的一个感觉，&#8220;为什么我的眼睛充满泪水？是因为我爱你爱的深沉&#8221;。</p>
<p><br />
　　第二个要素就是当你真的爱上一个人后，要以恰当的方式告诉他你爱他而不能只放在心里。我在大学就吃亏在爱上不少女孩子，但只放在心里，怕被别人拒绝。但其实人的追求最好还是表现出来，就算被一个女孩子拒绝了，她回家一定会在日记上写上，&#8220;今天又有一个男孩追我咯&#8221;。有一年去美国，跟一个以前班里很喜欢的女孩一起吃饭，她和她老公跟我一起吃饭。吃饭的时候我跟她说，其实我在大学对你特别有好感。她当时一拍大腿说当时你为什么不告诉我呢？</p>
<p><br />
　　第三条就是谈的要大度，所谓的大度就是说当另一个人爱上其他人的时候一定要大度的对他说，你的幸福就是我的幸福，你的快乐就是我的快乐。我始终觉得人在世界上总是有缘分的，如果大学没有人爱你，在你以后的人生中总是会有人爱你，等你一起牵手走向今后的旅程。</p>
<p>　　我是一个特别热爱生命的人我走路连蚂蚁都不敢踩，我想踩死那只公蚂蚁那只母蚂蚁怎么办。我吃鱼都不敢吃，我想吃了那条母鱼那公鱼该多痛苦啊，所以我一般不吃鱼要吃吃两条。当然，大学的恋爱是一个过程，不管研究生还是本科生，毕业以后真结婚的比恋爱要少的多。比如我们班十几对谈恋爱，大学毕业后结婚了三对，两年后离婚了两对。现在还剩下一对，这一对就是王强老师和他的夫人，我大学的同班同学。他们两人现在还过着幸福的生活。</p>
<p><br />
　　那么如果对大学的爱情有不满的也没有关系，看看我就行了。很多人都以为我不正常了，但是我还是照样地结婚了，照样找到心爱的人，照样生孩子，也有了比较美好的家庭。总而言之，生活就是这样美好的往前走。有平凡，有激动，有慢慢长夜，也有美丽的日子，这就是我们的生活。</p>
<p><br />
　　还有就是工作问题。工作问题是一个比较简单的问题。我相信同济大学的同学在找工作的时候都不会有太大的困难，但是有同学问我要不要创业。人生一辈子不创一次业一定是一件非常糟糕的事情。人一辈子总是要为自己干件事情，创业就是为自己干的事情。一份工作大家一起干，但是你并不一定大学毕业就要创业。为什么呢？因为创业需要经验和许多前提条件。</p>
<p><br />
　　第一，你的专业知识能在你创业中的运用；第二，你有能和同学朋友相处并且有分配利益关系的能力；第三，你要有对付中国社会如此复杂局面的能力；第四，你要有基本的商业操作原则或者商业运作知识；第五，自己要是个具有领导力的人；第六，你要有自己领域的运作知识和专业知识。</p>
<p><br />
　　比如，你想搞个培训学校，那你的运作知识从什么地方来呢？这个运作知识需要你通过观察别人怎么做得来的。如果当初我直接从北大出来就做新东方，那我是永远做不成的。我做新东方有两个前提条件。第一个，我在北大做了六年老师，所以做老师做的不错。还有第二个前提条件，我做新东方以前，我在另外一家培训机构干了近三年，我就在观察它是怎么做的。我碰到许多大学创业失败的人。我说你们怎么不创业了？他们说，同学之间只要一碰到利益关系，互相全是&#8220;狗屁&#8221;。是不是这样？是的，但是你会处理了就不是&#8220;狗屁&#8221;了。我和新东方这帮朋友也有利益关系，但是我不就处理好了吗？所以说现在关键是考虑有没有这样的本领。要创业但是我鼓励同学们先去某一个行业至少观察一到两年，最好是三到四年，慢慢积累自己的才能，自己也慢慢变得成熟，个性也慢慢变得稳定，最后再创业这样失败的机会也少了很多。</p>
<p><br />
　　创业有两种状态，第一种就是从零做起，我自己就是从零做起，马云也是从零做起。第二种创业就像杨元庆，也算创业，杨元庆是接柳传志的班最后变成了联想老总。美国著名的管理学家、企业家杰特威尔逊，他也是从一个普通工人做起，做了20年变成公司的老总；在公司老总的位置上干了20年把公司变成了全世界最大的公司。这也是创业，不一定是自己干。</p>
<p><br />
　　有学生问，俞老师，我怎么把一个培训机构和你干得一样大？很简单先到新东方来打扫卫生，如果你把卫生打扫的非常干净，那么我把你提升为卫生部长，如果你卫生部长干得好你就变成新东方后勤主任，等到你变成新东方后勤主任的时候，我就把你送到哈佛大学去学习了，学习完了回来我就把后勤行政全部交给你，你就变成后勤行政总裁。第几位？第二位。我&#8220;一翘辫子&#8221;你就是总裁了对不对？所以我们的成熟是慢慢来的，就像一棵树长大也是慢慢长大，哪有一下子就能变成自己创业成功的人？虽然这种人还是有的，但也是少数。我是32岁创业的，32岁才有了新东方。所以不要着急，人一辈子做多大的事都无所谓。</p>
<p><br />
　　还是我的老话：把生命活得精彩一点。我的比喻就是大树与小草的比喻，还有另外一个比喻：人的生活就像溪流一样，总有一个梦想——流进大海。有的人这一辈子没有流向大海，这条河就是不完整的。长江流向大海，黄河流向大海，但长江、黄河以自己不同的方式流向大海。长江开山劈石穿过大山流向大海，黄河没有开山劈石，结果绕过九曲十八弯。但是不管怎么样，生命再弯最后目标不变。我们惟一要记住的就是要像黄河、长江一样不断地向前流，但是不能变成黄河、长江里面的泥沙，最后自己沉淀下去，把生命给沉淀没了。总而言之，生命的精彩只靠自己不靠别人。从来没有什么救世主，想要活得精彩、幸福，只能靠我们身边的每一个朋友的共同努力！</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/cg05568256068/archive/2009/06/15/4271644.aspx</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/282740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-17 07:57 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/17/282740.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Web项目开发到底需要掌握哪些技术？</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282482.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Mon, 15 Jun 2009 15:40:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282482.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/282482.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282482.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/282482.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/282482.html</trackback:ping><description><![CDATA[<p>目前， 国内外信息化建设已经进入基于Web应用为核心的阶段， Java作为应用于网络的最好语言，前景无限看好。然而，就算用Java建造一个不是很烦琐的web应用，也不是件轻松的事情。概括一下，实施Java的WEB项目需要掌握的技术如下： <br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java语言<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 面向对象分析设计思想<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设计模式和框架结构<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XML语言<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 网页脚本语言<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据库<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 应用服务器<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 集成开发环境<br />
&nbsp;<br />
下面我们具体地看每个技术.</p>
<p>1、Java语言 </p>
<p>Java语言体系比较庞大，包括多个模块。从WEB项目应用角度讲有JSP、Servlet、JDBC、JavaBean(Application)四部分技术。<br />
&nbsp;<br />
（1）、Java Database Connectivity (JDBC)技术<br />
在Java Web应用开发中，数据库管理系统（RDBMS）的使用是不可缺少的。JDBC(Java Database Connectivity) 是一种用于执行 SQL 语句的 Java API。它由一组用 Java 编程语言编写的类和接口组成。JDBC 为工具/数据库开发人员提供了一个标准的API，使他们能够用纯Java API 来编写数据库应用程序。<br />
简单地说，JDBC 可做三件事：<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 与数据库建立连接，<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发送 SQL 语句，<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 处理结果。<br />
&nbsp;<br />
&nbsp;（2）、Servlet技术<br />
Servlet是运行在服务器端的程序，可以被认为是服务器端的applet。servlet被Web服务器（例如Tomcat）加载和执行，就如同applet被浏览器加载和执行一样。servlet从客户端(通过Web服务器)接收请求，执行某种操作，然后返回结果。<br />
&nbsp;<br />
Servlet的主要优点包括<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Servlet是持久的。servlet只需Web服务器加载一次，而且可以在不同请求之间保持服务(例如一次数据库连接)。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Servlet是与平台无关的。如前所述，servlet是用Java编写的，它自然也继承了Java的平台无关性。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Servlet是可扩展的。由于servlet是用Java编写的，它就具备了Java所能带来的所有优点。Java是健壮的、面向对象的编程语言，它很容易扩展以适应你的需求。servlet自然也具备了这些特征。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Servlet是安全的。从外界调用一个servlet的惟一方法就是通过Web服务器。这提供了高水平的安全性保障，尤其是在你的Web服务器有防火墙保护的时候。<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Servlet可以在多种多样的客户机上使用。由于servlet是用Java编写的，所以你可以很方便地在HTML中使用它们。<br />
&nbsp;<br />
（3）、JavaServer Pages(JSP) 技术<br />
JSP是从Servlet上分离出来的一小部分，简化了开发，加强了界面设计。JSP定位在交互网页的开发。运用Java语法，但功能较Servlet弱了很多，并且高级开发中只充当用户界面部分。JSP容器收到客户端发出的请求时，首先执行其中的程序片段，然后将执行结果以HTML格式响应给客户端。其中程序片段可以是：操作数据库、重新定向网页以及发送 E-Mail 等等，这些都是建立动态网站所需要的功能。所有程序操作都在服务器端执行，网络上传送给客户端的仅是得到的结果，与客户端的浏览器无关，因此，JSP 称为Server-Side Language。<br />
&nbsp;<br />
JavaServer Pages的主要优点包括<br />
●一次编写，各处执行(Write Once, Run Anywhere)特性<br />
作为Java 平台的一部分，JavaServer Pages 技术拥有Java语言&#8220;一次编写，各处执行&#8221;的特点。随着越来越多的供货商将JavaServer Pages 技术添加到他们的产品中，您可以针对自己公司的需求，做出审慎评估后，选择符合公司成本及规模的服务器，假若未来的需求有所变更时，更换服务器平台并不影响之前所投下的成本、人力所开发的应用程序。<br />
● 搭配可重复使用的组件<br />
JavaServer Pages技术可依赖于重复使用跨平台的组件（如：JavaBean或Enterprise JavaBean组件）来执行更复杂的运算、数据处理。开发人员能够共享开发完成的组件，或者能够加强这些组件的功能，让更多用户或是客户团体使用。基于善加利用组件的方法，可以加快整体开发过程，也大大降低公司的开发成本和人力。<br />
● 采用标签化页面开发<br />
Web 网页开发人员不一定都是熟悉Java 语言的程序员。因此，JSP 技术能够将许多功能封装起来，成为一个自定义的标签，这些功能是完全根据XML 的标准来制订的，即JSP 技术中的标签库(Tag Library)。因此，Web 页面开发人员可以运用自定义好的标签来达成工作需求，而无须再写复杂的Java 语法，让Web 页面开发人员亦能快速开发出一动态内容网页。<br />
今后，第三方开发人员和其他人员可以为常用功能建立自己的标签库，让Web 网页开发人员能够使用熟悉的开发工具，如同HTML 一样的标签语法来执行特定功能的工作。<br />
● N-tier 企业应用架构的支持<br />
有鉴于网际网络的发展，为因应未来服务越来越繁杂的要求，且不再受地域的限制，因此，<br />
必须放弃以往Client-Server的Two-tier 架构，进而转向更具威力、弹性的分散性对象系统。由于JavaServer Page 技术是Java 2 Platform Enterprise Edition (J2EE)集成中的一部分，它主要是负责前端显示经过复杂运算后之结果内容，而分散性的对象系统则是主要依赖EJB ( Enterprise JavaBean )和JNDI ( Java Naming and Directory Interface )构建而成。<br />
&nbsp;<br />
（4）、JavaBean(Application)应用组件技术<br />
Application是Java应用程序，在WEB项目和一些开发中主要应用JavaBean。它就是Application的一部分，逻辑运算能力很强，能极大的发挥Java语言的优点。JavaBean 被称为是Java 组件技术的核心。JavaBean 的结构必须满足一定的命名约定。JavaBean能提供常用功能并且可以重复使用，这使得开发人员可以把某些关键功能和核心算法提取出来封装成为一个组件对象，这样就增加了代码的重用率和系统的安全性。</p>
<p>高级的WEB项目会应用到以上所有技术，它们之间联合使用和协作开发会提高开发的效率和系统的性能。 </p>
<p>2、面向对象分析设计思想</p>
<p>Java语言是完全面向对象的语言，所以在项目设计时会有很大的帮助，在设计时应尽量舍弃以往的面向过程的设计方式。 </p>
<p>在分析项目业务关系的时候，应用一些UML(Unified Modeling Language)图,例如常用的用例图(use case diagram)，类图(class diagram)，时序图(sequence diagram)等等,会有很大的帮助，这样能尽快找出业务逻辑主要面对的对象，然后对每个对象进行行为划分，最后再实现对象之间的集成和通信。</p>
<p>3、设计模式和框架结构</p>
<p>Java从语言角度来讲不是很难，但是从整体设计角度来讲我们还需要了解一些高级应用框架。如果要设计一个良好的框架结构，单单只掌握Java语言远远不够。这就涉及到一个设计模式，还有和设计模式相关的一些知识。 </p>
<p>设计模式在Java项目实施过程更是重中之重。主要在与两层的设计模式、三层的设计模式和Ｎ层的设计模式。它直接决定着项目的应用、部署和实际开发设计。 </p>
<p>在普通的WEB项目中很多采用两层的开发结构。JSP+Servlet或JSP+JavaBean。当对开发要求高的项目中使用很多的还是MVC的三层开发结构，也就是JSP+Servlet+JavaBean。它能分有效的分离逻辑开发，使开发人员能专注于各自的开发。同时也能时整个开发结构流程更清晰，但是需要比较高的开发配合度。 <br />
在项目中，我们经常使用著名的Model-View-Controller(MVC)架构。MVC架构是随着smalltalk language语言的发展提出的，它是一个著名的用户界面设计架构。经典的MVC架构把一个组件（可认为是整个应用程序的一个模块）划分成三部分组 Model管理这个模块中所用到的数据和业务逻辑。而View 管理模块如何显示给用户，Controller 决定如何处理用户和该模块交互式时候产生的事件 如用户点击一个按钮等。 </p>
<p>4、XML语言</p>
<p>在服务器和设计模式结构中会应用到自定义文件，而且在应用高级设计时也会定义自用的标签，现在流行的是用XML去定义配置，所以XML语言应该有一定掌握。<br />
当前，Java 2平台企业版（J2EE）架构在厂商市场和开发者社区中倍受推崇。作为一种工具，可扩展标记语言（XML）简化了数据交换、进程间消息交换这一类的事情，因而对开发者逐渐变得有吸引力，并开始流行起来。自然，在J2EE架构中访问或集成XML解决方案的想法也很诱人。因为这将是强大系统架构同高度灵活的数据管理方案的结合。</p>
<p>XML的应用似乎是无穷无尽的，但它们大致上可以分为三大类：<br />
1、简单数据的表示和交换（针对XML的简单API（SAX）和文档对象模型（DOM）语法解析，不同的文档类型定义（DTDs）和概要（schemas））<br />
2、用户界面相关、表示相关的上下文（可扩展样式表语言（XSL），可扩展样式表语言转换（XSLT））<br />
3、面向消息的计算（XML-RPC（远程过程调用），基于SOAP协议的Web 服务（Web Services），电子化业务XML（ebXML））</p>
<p>5、网页脚本语言<br />
&nbsp;<br />
为了提高WEB项目的整体性能，提高人机交互的友好界面，网页的脚本语言是很有用处的，有的时候可以解决很大的难题或提高程序的性能和应用性。 </p>
<p>网页脚本语言的执行都是在客户端执行的，速度很很快，并且大多的操作与服务器没有交互运算，所以在一些应用中非常理想。在设计WEB项目的应用中，网页的脚本语言起着不能忽视的作用，所以如果设计WEB项目的应用中，对JavaScript应有一定的了解。<br />
&nbsp;<br />
JavaScript是一种基于对象(Object Based)和事件驱动(Event Driven)并具有安全性能（Secure）的脚本语言。使用它的目的是与HTML超文本标记语言、Java 脚本语言（Java小程序）一起实现在一个Web页面中链接多个对象，与Web客户交互作用。从而可以开发客户端的应用程序等。它是通过嵌入或调入在标准的HTML语言中实现的。它具有以下几个基本特点：<br />
1.&nbsp;&nbsp;&nbsp;&nbsp; 它是一种脚本编写语言<br />
JavaScript是一种脚本语言，它采用小程序段的方式实现编程。像其它脚本语言一样,JavaScript同样已是一种解释性语言,它提供了一个易的开发过程。 <br />
它的基本结构形式与C、C++、VB十分类似。但它不像这些语言一样，需要先编译，而是在程序运行过程中被逐行地解释。它与HTML标识结合在一起，从而方便用户的使用操作。 <br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于对象的语言。<br />
&nbsp;JavaScript是一种基于对象的语言，同时以可以看作一种面向对象的。这意味着它能运用自己已经创建的对象。因此，许多功能可以来自于脚本环境中对象的方法与脚本的相互作用。 <br />
3.&nbsp;&nbsp;&nbsp;&nbsp; 简单性<br />
&nbsp;JavaScript的简单性主要体现在：首先它是一种基于Java基本语句和控制流之上的简单而紧凑的设计, 从而对于学习Java是一种非常好的过渡。其次它的变量类型是采用弱类型，并未使用严格的数据类型。 <br />
4.&nbsp;&nbsp;&nbsp;&nbsp; 安全性<br />
&nbsp;JavaScript是一种安全性语言，它不允许访问本地的硬盘，并不能将数据存入到服务器上，不允许对网络文档进行修改和删除，只能通过浏览器实现信息浏览或动态交互。从而有效地防止数据的丢失。 <br />
5. 动态性<br />
&nbsp;JavaScript是动态的，它可以直接对用户或客户输入做出响应，无须经过Web服务程序。它对用户的响应，是采用以事件驱动的方式进行的。所谓事件驱动，就是指在主页(Home Page)中执行了某种操作所产生的动作，就称为&#8220;事件&#8221;(Event)。比如按下鼠标、移动窗口、选择菜单等都可以视为事件。当事件发生后，可能会引起相应的事件响应。 </p>
<p><br />
6、开发工具<br />
（1）、数据库 <br />
在主要的应用中，数据库相关的环节应用很多，所以对数据库应该有一定了解。不能单单只了解一种数据库，因为在很多实际开发中会提出很多数据库解决方案，所以只有在了解多种数据库的情况下才能有一个比较方案。<br />
对于数据库应该了解他的性能和一些基本的操作常识，还有该数据库的特点。而针对与Java语言WEB项目的数据库开发则主要是对JDBC的应用，还有数据库事务处理和连接池等高级概念的应用。</p>
<p><br />
（2）、Web服务器<br />
&nbsp;<br />
同数据库一样，应该了解该服务器的性能，特点和一些常识。<br />
在应用方面，Web服务器主要是针对于配置和部署，对目录的配置，调试；对配置文件属性的修改；对访问权限和并发性的控制；Java类的部署等。</p>
<p>（3）、集成开发环境（IDE）：<br />
&#8220;公欲善其事， 必先利其器&#8221;. 对于Web应用开发人员来讲，好的集成开发环境（IDE：Integrated Development Enviroment）是非常重要的。目前在市场上占主导位置的一个集成开发工具就是Eclipse. </p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/lianglx/archive/2006/09/26/1288142.aspx</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/282482.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-15 23:40 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/15/282482.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优秀程序员的十个习惯</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282480.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Mon, 15 Jun 2009 15:36:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282480.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/282480.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282480.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/282480.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/282480.html</trackback:ping><description><![CDATA[<p>在这个世界上，有数百万的人热衷于软件开发，他们有很多名字，如：软件工程师（Software Engineer），程序员（Programmer），编码人（Coder），开发人员（Developer）。经过一段时间后，这些人能够成为一个优秀的编码人员，他们非常熟悉如何用计算机语言来完成自己的工作。但是，如果你要成为一个优秀的程序员，你还可以需要有几件事你需要注意，如果你能让下面十个条目成为你的习惯，那么你才能真正算得上是优秀程序员。</p>
<p>1. 学无止境。就算是你有了10年以上的程序员经历，你也得要使劲地学习，因为你在计算机这个充满一创造力的领域，每天都会有很多很多的新事物出现。你需要跟上时代的步伐。你需要去了解新的程序语言，以及了解正在发展中的程序语言，以及一些编程框架。还需要去阅读一些业内的新闻，并到一些热门的社区去参与在线的讨论，这样你才能明白和了解整个软件开发的趋势。在国内，一些著名的社区例如：CSDN，ITPUB，CHINAUINX等等，在国外，建议你经常上一上digg.com去看看各种BLOG的聚合。</p>
<p><br />
2. 掌握多种语言。程序语言总是有其最适合的领域。当你面对需要解决的问题时，你需要找到一个最适合的语言来解决这些问题。比如，如果你需要性能，可能C/C++是首选，如果你需要跨平台，可能Java是首选，如果你要写一个Web上的开发程序，那么PHP，ASP，Ajax，JSP可能会是你的选择，如果你要处理一些文本并和别的应用交互，可能Perl, Python会是最好的。所以，花一些时间去探索一下其它你并熟悉的程序语言，能让你的眼界变宽，因为你被武装得更好，你思考问题也就更为全面，这对于自己和项目都会有好的帮助。</p>
<p>3. 理性面对不同的操作系统或技术。程序员们总是有自己心目中无可比拟的技术和操作系统，有的人喜欢Ubuntu，有的人喜欢Debian，还有的人喜欢Windows，以及FreeBSD，MacOSX或Solaris等等。看看我的BLOG(http://blog.csdn.net/haoel)中的那篇《其实Unix很简单》后的回复你就知道程序员们在维护起自己的忠爱时的那份执着了。只有一部分优秀的程序员明白不同操作系统的优势和长处和短处，这样，在系统选型的时候，才能做到真正的客观和公正，而不会让情绪影响到自己。同样，语言也是一样，有太多的程序员总是喜欢纠缠于语言的对比，如：Java和Perl。哪个刚刚出道的程序员没有争论去类似的话题呢？比如VC++和Delphi等等。争论这些东西只能表明自己的肤浅和浮燥。优秀的程序并不会执着于这些，而是能够理性的分析和理心地面对，从而才能客观地做出正确的选择。</p>
<p>4. 别把自己框在单一的开发环境中。 再一次，正如上面所述，每个程序员都有自己忠爱的工具和技术，有的喜欢老的（比如我就喜欢Vi编辑程序），而有的喜欢新的比如gedit或是Emacs等。有的喜欢使用像VC++一样的调试器，而我更喜欢GDB命令行方面的调式器。等等等等。程序员在使用什么样的工具上的争论还少吗？到处都是啊。使用什么样的工具本来无所谓，只要你能更好更快地达到你的目的。但是有一点是优秀程序员都应该了解的——那就是应该去尝试一下别的工作环境。没有比较，你永远不知道谁好谁不好，你也永远不知道你所不知道的。</p>
<p>5. 使用版本管理工具管理你的代码。千万不要告诉我你不知道源码的版本管理，如果你的团队开发的源代码并没有版本管理系统，那么我要告诉你，你的软件开发还处于石器时代。赶快使用一个版式本管理工具吧。CVS 是一个看上去平淡无奇的版本工具，但它是被使用最广的版本管理系统，Subversion 是CVS的一个升级版，其正在开始接管CVS的领地。Git 又是一个不同的版本管理工具。还有Visual SourceSafe等。使用什么样的版本管理工具依赖于你的团队的大小和地理分布，你也许正在使用最有效率或最没有效率的工具来管理你的源代码。但一个优秀的程序员总是会使用一款源码版本管理工具来管理自己的代码。如果你要我推荐一个，我推荐你使用开源的Subversion。</p>
<p>6. 是一个优秀的团队成员。 除非你喜欢独奏，除非你是孤胆英雄。但我想告诉你，今天，可能没有一个成熟的软件是你一个人能做的到的，你可能是你团队中最牛的大拿，但这并不意味着你就是好的团队成员。你的能力只有放到一个团队中才能施展开来。你在和你的团队成员交流中有礼貌吗？你是否经常和他们沟通，并且大家都喜欢和你在一起讨论问题？想一想一个足球队吧，你是这个队中好的成员吗？当别人看到你在场上的跑动，当别人看到你的传球和接球和抢断，能受到鼓舞吗？</p>
<p>7. 把你的工作变成文档。 这一条目当然包括了在代码中写注释，但那还仅仅不够，你还需要做得更多。有良好的注释风格的代码是一个文档的基础，他能够让你和你的团队容易的明白你的意图和想法。写下文档，并不仅仅是怕我们忘了当时的想法，而且还是一种团队的离线交流的方法，更是一种知识传递的方法。记录下你所知道的一切会是一个好的习惯。因为，我相信你不希望别人总是在你最忙的时候来打断你问问题，或是你在休假的时候接到公司的电话来询问你问题。而你自己如果老是守着自己的东西，其结果只可能是让你自己长时间地深陷在这块东西内，而你就更本不可以去做更多的事情。包括向上的晋升。你可能以为&#8220;教会徒弟能饿死师父&#8221;，但我告诉你，你的保守会让你失去更多更好的东西，请你相信我，我绝不是在这里耸人听闻。</p>
<p>8. 注意备份和安全。 可能你觉得这是一个&#8220;废话&#8221;，你已明白了备份的重要性。但是，我还是要在这里提出，丢失东西是我们人生中的一部份，你总是会丢东西，这点你永远无法避免。比如：你的笔记本电脑被人偷了，你的硬盘损坏了，你的电脑中病毒了，你的系统被人入侵了，甚至整个大楼被烧了，等等，等等。所以，做好备份工作是非常非常重要的事情，硬盘是不可信的，所以定期的刻录光盘或是磁带可能会是一个好的方法，网络也是不可信的，所以小心病毒和黑客，不但使用软件方面的安全策略，你更需要一个健全的管理制度。此外，尽量的让你的数据放在不同的地方，并做好定期（每日，每周，每月）的备份策略。</p>
<p>9. 设计要足够灵活。 可能你的需求只会要求你实现一个死的东西，但是，你作为一个优秀的程序，你应该随时在思考这个死的东西是否可以有灵活的一面，比如把一些参数变成可以配置的，把一些公用的东西形成你的函数库以便以后重用，是否提供插件方面的功能？你的模块是否要以像积木一样随意组合？如果要有修改的话，你的设计是否能够马上应付？当然，灵活的设计可能并不是要你去重新发明轮子，你应该尽可能是使用标准化的东西。所谓灵话的设计就是要让让考虑更多需求之外的东西，把需求中这一类的问题都考虑到，而不是只处理需求中所说的那一特定的东西。比如说，需要需要的屏幕分辨率是800&#215;600，那么你的设计能否灵活于其他的分辨率？程序设计总是需要我们去处理不同的环境，以及未来的趋势。我们需要用动态的眼光去思考问题，而不是刻舟求剑。也许有一天，你今天写的程序就要移植到别的环境中去，那个时候你就能真正明白什么是灵活的设计了。</p>
<p>10. 不要搬起石头砸自己的脚。程序员总是有一种不好的习惯，那就是总是想赶快地完成自己手上的工作。但情况却往往事已愿违。越是想做得快，就越是容易出问题，越是想做得快，就越是容易遗漏问题，最终，程序改过来改过去，按下葫芦起了瓢，最后花费的时间和精力反而更多。欲速而不达。优秀程序员的习惯是前面多花一些时间多作一些调查，试验一下不同的解决方案，如果时间允许，一个好的习惯是，每4个小时的编程，需要一个小时的休息，然后又是4个小时的编码。当然，这因人而异，但其目的就是让你时常回头看看，让你想一想这样三个问题：1）是否这么做是对的？2）是否这么做考虑到了所有的情况？3）是否有更好的方法？想好了再说，时常回头看看走过的路，时常总结一下过去事，会对你有很大的帮助。</p>
<p>以上是十条优秀程序员的习惯或行为规范，希望其可以对你有所帮助。</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/gdpu46/archive/2009/06/14/4265273.aspx</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/282480.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-15 23:36 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/15/282480.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java学什么</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282361.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Mon, 15 Jun 2009 07:08:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282361.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/282361.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282361.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/282361.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/282361.html</trackback:ping><description><![CDATA[<p>很多网友问我学习Java有没有什么捷径,我说&#8220;无他，唯手熟尔&#8221;。但是我却很愿意将</p>
<p>自己学习的一些经验写出来，以便后来者少走弯路,帮助别人是最大的快乐嘛！</p>
<p>要想学好Java，首先要知道Java的大致分类。我们知道，自从Sun推出Java以来，就力图</p>
<p>使之无所不包，所以Java发展到现在，按应用来分主要分为三大块：J2SE,J2ME和J2EE,</p>
<p>这也就是Sun?ONE(Open?Net?Environment)体系。J2SE就是Java2的标准版，主要用于桌</p>
<p>面应用软件的编程；J2ME主要应用于嵌入是系统开发，如手机和PDA的编程；J2EE是Jav</p>
<p>a2的企业版，主要用于分布式的网络程序的开发，如电子商务网站和ERP系统。J2SE开发</p>
<p>桌面应用软件比起VC,VB,DEPHI这些传统开发语言来说，优势好象并不明显。J2ME对于初</p>
<p>学者来说，好象又有点深奥，而且一般开发者很难有开发环境。所以现在应用最广泛又</p>
<p>最好学的就是J2EE了。J2EE又包括许多组件，如Jsp,Servlet,JavaBean,EJB,JDBC,Java</p>
<p>Mail等。要学习起来可不是一两天的事。</p>
<p>那么又该如何学习J2EE呢？当然Java语法得先看一看的，I/O包，Util包，Lang包你都熟</p>
<p>悉了吗？然后再从JSP学起。如果你学过HTML，那么事情要好办的多，如果没有，那你快</p>
<p>去补一补HTML基础吧。其实JSP中的Java语法也不多，它更象一个脚本语言，有点象ASP</p>
<p>。然后你就该学一学Servlet了。Servlet就是服务器端小程序，他负责生成发送给客户</p>
<p>端的HTML文件。JSP在执行时，也是先转换成Servlet再运行的。虽说JSP理论上可以完全</p>
<p>取代Servlet，这也是SUN推出JSP的本意，可是Servlet用来控制流程跳转还是挺方便的</p>
<p>，也令程序更清晰。接下来你应该学习一下Javabean了，可能你早就看不管JSP在HTML中</p>
<p>嵌Java代码的混乱方式了，这种方式跟ASP又有什么区别呢？还好，SUN提供了Javabean</p>
<p>可以把你的JSP中的Java代码封装起来，便于调用也便于重用。接着就是EJB了，EJB就是</p>
<p>Enterprise?JavaBean,看名字好象它是Javabean，可是它和Javabean还是有区别的。它</p>
<p>是一个体系结构，你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件（</p>
<p>也就是我们常听到的Weblogic,Websphere这些J2EE服务器）完成了，所以我们要做的程</p>
<p>序代码量很少，大部分工作都在设计和配置中间件上。至于JDBC，就不用我多说了，你</p>
<p>如果用java编过存取数据库的程序，就应该很熟悉。还有，如果你要用Java编发送电子</p>
<p>邮件的程序，你就得看看Javamail了。</p>
<p>好了，对Java和J2EE有了一些基本概念之后，你就应该编一些程序了，千万不要纸上谈</p>
<p>兵哦。最好找一些有实例且带光盘的书来看，这样看到好的程序就可以直接Ctrl+C再Ct</p>
<p>rl+V，也不用劳您老大架再亲自把它?再输一遍吧，再说直接复制还不用怕出错，何乐而</p>
<p>不为呢！还有就是要经常上一些好的Java编程文章，有好的文章要Cut下来，有问题尽管</p>
<p>问，只要问题不是太傻，一般高手都会回答你的。下面介绍几个好的Java方面的编程网</p>
<p>站：</p>
<p>CSDN论坛?http://www.csdn.net/?中国最有名的技术论坛，《程序员》杂志就是他们出</p>
<p>版的，你可以在上面提出问题，马上就有人回答你，如果你觉得好，你可以给那人加分</p>
<p>；</p>
<p>Java研究组织http://www.javaresearch.org/?上面有很多原创文章，高手还是挺多的；</p>
<p>&nbsp;</p>
<p>Java开发者?http://www.chinajavaworld.com/?那里Java资料比较全；</p>
<p>java.com.cn?http://www.java.com.cn/?看这域名就知道有多牛，注册用户快接近一万</p>
<p>了，同时在线人数也在一千左右，人气很旺的；</p>
<p>IBM的开发者网络http://www-900.ibm.com/developerWorks/cn/java/index.shtml?IBM</p>
<p>永远的蓝色巨人；</p>
<p>那么我书也看了，程序也做了，别人问我的问题我都能解决了，是不是就成为高手了呢</p>
<p>？当然没那么简单，这只是万里长征走完了第一步。不信？那你出去接一个项目，你知</p>
<p>道怎么下手吗，你知道怎么设计吗，你知道怎么组织人员进行开发吗？你现在脑子里除</p>
<p>了一些散乱的代码之外，可能再没有别的东西了吧！你现在最缺的是实际的工作经验，</p>
<p>而不是书本上那些凭空想出来的程序。所以你快去找一份Java的编程工作来做吧（如果</p>
<p>是在校学生可以去做兼职啊），在实践中提高自己，那才是最快的。不过你得祈祷在公</p>
<p>司里碰到一个高手，而且他还愿意不厌其烦地教你，这样好象有点难哦！</p>
<p>还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手，他们设计合</p>
<p>理，考虑周到，再加上有广大的程序员参与，代码的价值自然是字字珠叽，铿锵有力（</p>
<p>对不起，偶最近《金装四大才子》看多了）。学Java必读的两个开源程序就是Jive和Pe</p>
<p>t?Store。Jive是国外一个非常著名的BBS程序，完全开放源码。论坛的设计采用了很多</p>
<p>先进的技术，如Cache、用户认证、Filter、XML等，而且论坛完全屏蔽了对数据库的访</p>
<p>问，可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序，这是我们平</p>
<p>时编程时容易忽略的一部份（中国程序员一般只注重编程的技术含量，却完全不考虑用</p>
<p>户的感受，这就是我们与国外软件的差距所在）。Jive的资料在很多网站上都有，大家</p>
<p>可以找来研究一下。相信你读完代码后，会有脱胎换骨的感觉。遗憾的是Jive从2.5以后</p>
<p>就不再无条件的开放源代码，同时有licence限制。不过幸好还有中国一流的Java程序员</p>
<p>关注它，外国人不开源了，中国人就不能开源吗？这里向大家推荐一个汉化的Jive版本</p>
<p>—J道。Jive(J道版)是由中国Java界大名鼎鼎的banq在Jive?2.1版本基础上改编而成,</p>
<p>全中文，增加了一些实用功能，如贴图，用户头像和用户资料查询等，而且有一个开发</p>
<p>团队在不断升级。你可以访问banq的网站http://www.jdon.com/?去下载。Pet?Store（</p>
<p>宠物店）是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序，应该很具有权威</p>
<p>性，想学J2EE和EJB的朋友不要错过了。有意思的是，Pet?Store还经常作为各大J2EE厂</p>
<p>商的产品性能的比较标准，就连微软也曾作过一个Pet?Store试图证明.NET性能比J2EE优</p>
<p>越，可见Pet?Store的例子有多么深入人心。</p>
<p>你一定会高兴地说，哈哈，原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一</p>
<p>个项目经理，号称Java很简单，只要三个月就可以学会。其实说这种话的人就如当年小</p>
<p>日本号称&#8220;三个月拿下中国&#8221;一样大言不惭。不是Tomjava泼你冷水，你现在只是学到了</p>
<p>Java的骨架，却还没有学到Java的精髓。接下来你得研究设计模式了。设计模式是高级</p>
<p>程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的</p>
<p>是思想，它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧，让你能够真正</p>
<p>掌握接口或抽象类的应用，从而在原来的Java语言基础上跃进一步，更重要的是，设计</p>
<p>模式反复向你强调一个宗旨：要让你的程序尽可能的可重用。关于设计模式的资料，还</p>
<p>是向大家推荐banq的网站http://www.jdon.com/?，他把GOF的23种模式以通俗易懂的方</p>
<p>式诠释出来，纯Java描述，真是经典中的经典。有时间再研究一下MVC结构（把Model-V</p>
<p>iew-Control分离开的设计思想）吧，现在很流行的Structs就是它的一种实现方式，不</p>
<p>过Structs用起来实在是很繁，我们只要学习其精髓即可，我们完全可以设计自己的MVC</p>
<p>结构。然后你再研究一下软件Refactoring(重整)和极限XP编程，相信你又会上一个台阶</p>
<p>。</p>
<p>做完这些，你不如整理一下你的Java代码，把那些经典的程序和常见的应用整理出来，</p>
<p>再精心打造一番，提高其重用性和可扩展性。你再找几个志同道合的朋友成立一个工作</p>
<p>室吧，你可以去承接一些项目做了，一开始可能有些困难，可是你有技术积累，又考虑</p>
<p>周全，接下项目来可以迅速作完，相信大家以后都会来找你的，所以Money就哗啦啦的来</p>
<p>了。。。。。。</p>
<p>当然你也可以参加一些开源项目，一方面可以提高自己，另一方面也是为中国软件事业</p>
<p>做贡献嘛！开发者在互联网上用CVS合作开发，用QQ,MSN,E-mail讨论联系，天南海北的</p>
<p>程序员分散在各地却同时开发同一个软件，是不是很有意思呢？</p>
<p>下面介绍两个好的开源项目网站：</p>
<p>湖北省软件公共开发平台http://gro.clinux.org/</p>
<p>共创联盟http://cosoft.org.cn/</p>
<p>哇，好高兴哦，我终于成为高手了！非也，非也。古人云：&#8220;识时务者为俊杰&#8221;。你知</p>
<p>道计算机界现在的发展形势吗？你知道微软的.NET蓝图和SUN?ONE计划之间的明争暗斗吗</p>
<p>?你知道计算机技术将向何处发展吗?其实从各大计算机厂商最近的动作,都可以看出来&#8220;</p>
<p>Web服务将是下一代互联网应用的制高点&#8221;，而微软的.NET蓝图和SUN?ONE计划的斗争焦</p>
<p>点，也就是Web服务。Web服务就是一个崭新的分布式计算模型，它是一系列标准的综合</p>
<p>（XML,SOAP,UDDI,WSDL和WSFL等）。它使得不同语言编写的软件能够轻易的集成起来，</p>
<p>使网络资源和Web站点变成一种服务而不是混乱的垃圾场。不远的将来，我们就可以在家</p>
<p>里点击一下鼠标，就可以完成出门旅游的全部准备工作，包括定飞机票，定旅游线路，</p>
<p>定好房间等。请注意，这所有的一切都是Web站点间自动完成的，再也不用象现在一样，</p>
<p>表面上是电子商务，实际上很多环节都是人工操作。也许你会觉得这是天方夜谈，不过</p>
<p>就近的说，你也很有可能承接一个项目，要集成两个企业的ERP系统。很有可能上游企业</p>
<p>的系统是用Dephi编的，而下游企业的系统是用Java编的。你说你是Java高手，大家都看</p>
<p><br />
者你怎么做呢。所以啊，你还得学习新技术，如Web服务，而且你Dephi也要懂一点吧（</p>
<p>Dephi6现在已经提供Web服务的控件了）。?你编的Java系统，可能要和.NET集成，所以</p>
<p>你.NET要懂一点吧？到最后，你可能发现你已经成为Java高手了，但很多时间却在搞别</p>
<p>的技术。太极张三丰里说，最厉害的招式就是没有招式，可能就是这个道理吧！</p>
<p>因为刚刚兴起，所以网上Web服务的资料不是很多，我还是给大家推荐几个网站吧：</p>
<p>中国UDDI技术联盟http://www.uddi-china.org/</p>
<p>CSDN的柴晓路专栏http://www.csdn.net/develop/author/ColumnAuthor/fennivel/?（</p>
<p>注：柴晓路也是互联网上一个有名的人物，他发表过很多关于Web服务的文章，还出了一</p>
<p>书，应该称的上是中国Web服务技术的先行者）</p>
<p>IBM的开发者网络的XML&amp;Web?Service专栏:</p>
<p>http://www-900.ibm.com/developerWorks/cn/xml/index.shtml?csdn?IBM可是Web服务</p>
<p>的力推者</p>
<p>呜&#8230;你费劲千心万苦，总算成为Java高手了，怎叫人不由喜极而泣呢！是啊，真不容易</p>
<p>，真不简单，真叫人感动啊！那么打个电话告诉我吧，什么？我的电话号码是多少？昏</p>
<p>到，你打电话问不就知道了吗，真是的&#8230;&#8230;?</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/lvweiqiang/archive/2009/06/13/4266123.aspx</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/282361.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-15 15:08 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/15/282361.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个计算机专业学生几年的Java编程经验汇总</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282358.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Mon, 15 Jun 2009 07:03:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282358.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/282358.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282358.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/282358.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/282358.html</trackback:ping><description><![CDATA[<p>PS: 其实还有满多感想可以总结的，一次写多了怕大家扔砖头砸死我，怪我太罗唆。大家应该更加踏实更加务实的去做一些研究并互相分享心得，大方向和太前沿的技术讨论是必要的但最好不要太多，毕竟自己基础都还没打好，什么都讲最新版本其实是进步的一大障碍！</p>
<p>Java 学习杂谈（二）<br />
鉴于上回写的一点感想大家不嫌弃，都鼓励小弟继续写下去，好不容易等到国庆黄金周，实习总算有一个休息的阶段，于是这就开始写第二篇了。希望这次写的仍然 对志同道合的朋友们有所帮助。上回讲了Java动态加载机制、classLoader原理和关于jdk和jre三个问题。这次延续着讲一些具体的类库??</p>
<p>1． 关于集合框架类<br />
相信学过Java的各位对这个名词并不陌生，对 java.util.*这个package肯定也不陌生。不知道大家查询API的时候怎么去审视或者分析其中的一个package，每个包最重要的两个部 分就是interfaces和classes，接口代表了它能做什么，实现类则代表了它如何去做。关注实现类之前，我们应该先理解清楚它的来源接口，不管 在j2se还是j2ee中，都应该是这样。那么我们先看这三个接口：List、Set、Map。<br />
也许有些人不太熟悉这三个名字，但相信大部分人都熟悉ArrayList，LinkedList，TreeSet，HashSet，HashMap， Hashtable等实现类的名字。它们的区别也是满容易理解的，List放可以重复的对象集合，Set放不可重复的对象组合，而Map则放 &lt;Key,Value &gt; 这样的名值对， Key不可重复，Value可以。这里有几个容易混淆的问题：</p>
<p>到底Vector和ArrayList，Hashtable和HashMap有什么区别？<br />
很多面试官喜欢问这个问题，其实更专业一点应该这样问：新集合框架和旧集合框架有哪些区别？新集合框架大家可以在这些包中找since jdk1.2的，之前的如vector和Hashtable都是旧的集合框架包括的类。那么区别是？<br />
a. 新集合框架的命名更加科学合理。例如List下的ArrayList和LinkedList<br />
b. 新集合框架下全部都是非线程安全的。建议去jdk里面包含的源代码里面自己去亲自看看vector和ArrayList的区别吧。当然如果是jdk5.0之后的会比较难看一点，因为又加入了泛型的语法，类似c++的template语法。</p>
<p>那么大家是否想过为什么要从旧集合框架默认全部加锁防止多线程访问更新到新集合框架全部取消锁，默认方式支持多线程？(当然需要的时候可以使用collections的静态方法加锁达到线程安全)<br />
笔者的观点是任何技术的发展都未必是遵循它们的初衷的，很多重大改变是受到客观环境的影响的。大家知道Java的初衷是为什么而开发的麽？是为嵌入式程序 开发的。记得上一篇讲到classLoader机制麽？那正是为了节约嵌入式开发环境下内存而设计的。而走到今天，Java成了人们心中为互联网诞生的语 言。互联网意味着什么？多线程是必然的趋势。客观环境在变，Java技术也随着飞速发展，导致越来越脱离它的初衷。据说Sun公司其实主打的是J2se， 结果又是由于客观环境影响，J2se几乎遗忘，留在大家谈论焦点的一直是j2ee。</p>
<p>技术的细节这里就不多说了，只有用了才能真正理解。解释这些正是为了帮助大家理解正在学的和将要学的任何技术。之后讲j2ee的时候还会再讨论。<br />
多扯句题外话：几十年前的IT巨人是IBM，Mainframe市场无人可比。微软如何打败IBM？正是由于硬件飞速发展，对个人PC的需求这个客观环 境，让微软通过OS称为了第二个巨人。下一个打败微软的呢？Google。如何做到的？如果微软并不和IBM争大型机，Google借着互联网飞速发展这 个客观环境作为决定性因素，避开跟微软争OS，而是走搜索引擎这条路，称为第3个巨人。那么第4个巨人是谁呢？很多专家预言将在亚洲或者中国出现， Whatever，客观环境变化趋势才是决定大方向的关键。当然笔者也希望会出现在中国，^_^~~</p>
<p>2． 关于Java设计模式<br />
身边的很多在看GOF的23种设计模式，似乎学习它无论在学校还是在职场，都成了一种流行风气。我不想列举解释这23种Design Pattern， 我写这些的初衷一直都是谈自己的经历和看法，希望能帮助大家理解。<br />
首先我觉得设计模式只是对一类问题的一种通用解决办法，只要是面向对象的编程预言都可以用得上这23种。理解它们最好的方法就是亲自去写每一种，哪怕是一 个简单的应用就足够了。如果代码实现也记不住的话，记忆它们对应的UML图会是一个比较好的办法，当然前提是必须了解UML。<br />
同时最好能利用Java自身的类库帮助记忆，例如比较常用的观察者模式，在java.util.*有现成的Observer接口和Observable这 个实现类，看看源代码相信就足够理解观察者模式了。再比如装饰器模式，大家只要写几个关于java.io.*的程序就可以完全理解什么是装饰器模式了。有 很多人觉得刚入门的时候不该接触设计模式，比如图灵设计丛书系列很出名的那本《Java设计模式》，作者: Steven John Metsker，大部分例子老实说令现在的我也很迷惑。但我仍然不同意入门跟学习设计模式有任何冲突，只是我们需要知道每种模式的概念的和典型的应用，这 样我们在第一次编写 FileOutputStream、BufferedReader、PrintWriter的时候就能感觉到原来设计模式离我们如此之近，而且并不是多么 神秘的东西。</p>
<p>另外，在学习某些模式的同时，反而更能帮助我们理解java类库的某些特点。例如当你编写原型(Prototype)模式的时候，你必须了解的是 java.lang.Cloneable这个接口和所有类的基类Object的clone()这个方法。即深copy和浅copy的区别：<br />
Object.clone()默认实现的是浅copy，也就是复制一份对象拷贝，但如果对象包含其他对象的引用，不会复制引用，所以原对象和拷贝共用那个引用的对象。<br />
深copy当然就是包括对象的引用都一起复制啦。这样原对象和拷贝对象，都分别拥有一份引用对象。如果要实现深copy就必须首先实现 java.lang.Cloneable接口，然后重写clone()方法。因为在Object中的clone()方法是protected签名的，而 Cloneable接口的作用就是把protected放大到public，这样clone()才能被重写。</p>
<p>那么又有个问题了？如果引用的对象又引用了其他对象呢？这样一直判断并复制下去，是不是显得很麻烦？曾经有位前辈告诉我的方法是重写clone方法的时候 直接把原对象序列化到磁盘上再反序列化回来，这样不用判断就可以得到一个深copy的结果。如果大家不了解序列化的作法建议看一看 ObjectOutputStream和ObjectInputStream</p>
<p>归根结底，模式只是思想上的东西，把它当成前人总结的经验其实一点都不为过。鼓励大家动手自己去写，例如代理模式，可以简单的写一个Child类， Adult类。Child要买任何东西由Adult来代理实现。简单来说就是Adult里的buy()内部实际调用的是Child的buy()，可是暴露 在main函数的却是Adult.buy()。这样一个简单的程序就足够理解代理模式的基本含义了。</p>
<p>Java 杂谈（三）<br />
这已经笔者写的第三篇Java杂记了，庆幸前两篇一直得到论坛朋友们的支持鼓励，还望大家继续指正不足之处。笔者也一直渴望通过这样方式清醒的自审，来寻找自己技术上的不足之处，希望和共同爱好Java的同仁们一起提高。<br />
前两次分别讲述了关于jvm、jdk、jre、collection、classLoader和一些Design Pattern的自我理解。这次仍然不准备开始过渡到j2ee中，因为觉得还有一些琐碎的j2se的问题没有总结完毕。</p>
<p>1． 关于Object类理解<br />
大家都知道Object是所有Java类的基类， 意味着所有的Java类都会继承了Object的11个方法。建议大家去看看Object的 11个成员函数的源代码，就会知道默认的实现方式。比如equals方法，默认实现就是用"=="来比较，即直接比较内存地址，返回true 或者 false。而toString()方法，返回的串组成方式是??<br />
"getClass().getName() + "@" + Integer.toHexString(hashCode())"<br />
其实不用我过多的解释，大家都能看懂这个串的组成。接下来再看看hashCode()：<br />
public native int hashCode()；</p>
<p>由于是native方法，跟OS的处理方式相关，源代码里仅仅有一个声明罢了。我们有兴趣的话完全可以去深究它的hashCode到底是由OS怎么样产生 的呢？但笔者建议最重要的还是先记住使用它的几条原则吧！首先如果equals()方法相同的对象具有相通的hashCode，但equals ()对象不相通的时候并不保证hashCode()方法返回不同的整数。而且下一次运行同一个程序，同一个对象未必还是当初的那个hashCode() 哦。<br />
其余的方法呢？nofigy()、notifyAll()、clone()、wait()都是native方法的，说明依赖于操作系统的实现。最后一个有 趣的方法是finalize()，类似C++的析构函数，签名是protected，证明只有继承扩展了才能使用，方法体是空的，默示什么也不做。它的作 用据笔者的了解仅仅是通知JVM此对象不再使用，随时可以被销毁，而实际的销毁权还是在于虚拟机手上。那么它真的什么也不做麽？未必，实际上如果是线程对 象它会导致在一定范围内该线程的优先级别提高，导致更快的被销毁来节约内存提高性能。其实从常理来说，我们也可以大概这样猜测出jvm做法的目的。</p>
<p>2． 关于重载hashCode()与Collection框架的关系<br />
笔者曾经听一位搞Java培训多年的前辈说在他看来hashCode方法没有任何意义，仅仅是为了配合证明具有同样的hashCode会导致equals 方法相等而存在的。连有的前辈都犯这样的错误，其实说明它还是满容易被忽略的。那么hashCode()方法到底做什么用？</p>
<p>学过数据结构的课程大家都会知道有一种结构叫hash table，目的是通过给每个对象分配一个唯一的索引来提高查询的效率。那么Java也不会肆意扭曲改变这个概念，所以hashCode唯一的作用就是为 支持数据结构中的哈希表结构而存在的，换句话说，也就是只有用到集合框架的 Hashtable、HashMap、HashSet的时候，才需要重载hashCode()方法，<br />
这样才能使得我们能人为的去控制在哈希结构中索引是否相等。笔者举一个例子：<br />
曾经为了写一个求解类程序，需要随机列出1,2,3,4组成的不同排列组合，所以笔者写了一个数组类用int[]来存组合结果，然后把随机产生的组合加入 一个HashSet中，就是想利用HashSet不包括重复元素的特点。可是HashSet怎么判断是不是重复的元素呢？当然是通过 hashCode()返回的结果是否相等来判断啦，可做一下这个实验：<br />
int[] A = {1,2,3,4};<br />
int[] B = {1,2,3,4};<br />
System.out.println(A.hashCode());<br />
System.out.println(B.hashCode());</p>
<p>这明明是同一种组合，却是不同的hashCode，加入Set的时候会被当成不同的对象。这个时候我们就需要自己来重写hashCode()方法了，如何 写呢？其实也是基于原始的hashCode()，毕竟那是操作系统的实现， 找到相通对象唯一的标识，实现方式很多，笔者的实现方式是：<br />
首先重写了toString()方法:<br />
return A[0]&#8220;+&#8221; A[1]&#8220;+&#8221; A[2]&#8220;+&#8221; A[3]; //显示上比较直观<br />
然后利用toString()来计算hashCode()：<br />
return this.toString().hashCode()；<br />
这样上述A和B返回的就都是&#8221;1234&#8221;，在测试toString().hashCode()，由于String在内存中的副本是一样的，&#8221;1234&#8221;.hashCode()返回的一定是相同的结果。</p>
<p>说到这，相信大家能理解得比我更好，今后千万不要再误解hashCode()方法的作用。</p>
<p>3． 关于Class类的成员函数与Java反射机制<br />
很早刚接触Java就听很多老师说过Java的动态运行时机制、反射机制等。确实它们都是Java的显著特点，运行时加载笔者在第一篇介绍过了，现在想讲 讲反射机制。在Java中，主要是通过java.lang包中的Class类和Method类来实现内存反射机制的。<br />
熟悉C++的人一定知道下面这样在C++中是做不到的： 运行时以字符串参数传递一个类名，就可以得到这个类的所有信息，包括它所有的方法，和方法的详细信息。还可以实例化一个对象，并通过查到的方法名来调用该 对象的任何方法。这是因为Java的类在内存中除了C++中也有的静态动态数据区之外，还包括一份对类自身的描述，也正是通过这描述中的信息，才能帮助我 们才运行时读取里面的内容，得到需要加载目标类的所有信息，从而实现反射机制。大家有没有想过当我们需要得到一个JavaBean的实例的时候，怎么知道 它有哪些属性呢？再明显简单不过的例子就是自己写一个JavaBean的解析器：</p>
<p>a. 通过Class.forName(&#8220;Bean的类名&#8221;)得到Class对象，例如叫ABeanClass<br />
b. 通过ABeanClass的getMethods()方法，得到Method[]对象<br />
c. 按照规范所有get方法名后的单词就代表着该Bean的一个属性<br />
d. 当已经知道一个方法名，可以调用newInstance()得到一个实例，然后通过invoke()方法将方法的名字和方法需要用的参数传递进去，就可以动态调用此方法。</p>
<p>当然还有更复杂的应用，这里就不赘述，大家可以参考Class类和Method类的方法。</p>
<p>4． 坦言Synchronize的本质<br />
Synchronize大家都知道是同步、加锁的意思，其实它的本质远没有大家想得那么复杂。声明Synchronize的方法被调用的时候，锁其实是加 载对象上，当然如果是静态类则是加在类上的锁，调用结束锁被解除。它的实现原理很简单，仅仅是不让第二把锁再次被加在同一个对象或类上，仅此而已。一个简 单的例子足以说明问题：<br />
class A{<br />
synchronized void f(){}<br />
void g(){}<br />
}</p>
<p>当A的一个对象a被第一个线程调用其f()方法的时候，第二个线程不能调用a的synchronized方法例如f()，因为那是在试图在对象上加第二把锁。但调用g()却是可以的，因为并没有在同一对象上加两把锁的行为产生。<br />
这样大家能理解了麽？明白它的原理能更好的帮助大家设计同步机制，不要滥用加锁。</p>
<p>PS：下篇笔者计划开始对J2ee接触到的各个方面来进行总结，谈谈自己的经验和想法。希望大家还能一如既往的支持笔者写下去，指正不足之处。</p>
<p>Java杂谈（四）</p>
<p>不知不觉已经写到第四篇了，论坛里面不断的有朋友鼓励我写下去。坚持自己的作风，把一切迷惑不容易理清楚的知识讲出来，讲到大家都能听懂，那么自己就真的 懂了。最近在公司实习的时候Trainer跟我讲了很多经典事迹，对还未毕业的我来说是笔不小的财富，我自己的信念是：人在逆境中成长的速度要远远快过顺 境中，这样来看一切都能欣然接受了。<br />
好了，闲话不说了，第三篇讲的是反射机制集合框架之类的，这次打算讲讲自己对反序列化和多线程的理解。希望能对大家学习Java起到帮助??</p>
<p>1．关于序列化和反序列化<br />
应该大家都大概知道Java中序列化和反序列化的意思，序列化就是把一个Java对象转换成二进制进行磁盘上传输或者网络流的传输，反序列化的意思就是把 这个接受到的二进制流重新组装成原来的对象逆过程。它们在Java中分别是通过ObjectInputStream和 ObjectInputStream这两个类来实现的（以下分别用ois和oos来简称）。</p>
<p>oos的writeObject()方法用来执行序列化的过程，ois的readObject()用来执行反序列化的过程，在传输二进制流之前，需要讲这 两个高层流对象连接到同一个Channel上，这个Channel可以是磁盘文件，也可以是socket底层流。所以无论用哪种方式，底层流对象都是以构 造函数参数的形式传递进oos和ois这两个高层流，连接完毕了才可以进行二进制数据传输的。例子：<br />
可以是文件流通道<br />
file = new File(&#8220;C:/data.dat&#8221;);<br />
oos = new ObjectOutputStream(new FileOutputStream(file));<br />
ois = new ObjectInputStream(new FileInputStream(file));</p>
<p>或者网络流通道<br />
oos = new ObjectOutputStream(socket.getOutputStream());<br />
ois = new ObjectInputStream(socket.getInputStream()); </p>
<p>不知道大家是否注意到oos总是在ois之前定义，这里不希望大家误解这个顺序是固定的么？回答是否定的，那么有顺序要求么？回答是肯定的。原则是什么呢？<br />
原则是互相对接的输入/输出流之间必须是output流先初始化然后再input流初始化，否则就会抛异常。大家肯定会问为什么？只要稍微看一看这两个类 的源代码文件就大概知道了，output流的任务很简单，只要把对象转换成二进制往通道中写就可以了，但input流需要做很多准备工作来接受并最终重组 这个Object，所以ObjectInputStream的构造函数中就需要用到output初始化发送过来的header信息，这个方法叫做 readStreamHeader()，它将会去读两个Short值用于决定用多大的缓存来存放通道发送过来的二进制流，这个缓存的size因jre的版 本不同是不一样的。所以output如果不先初始化，input的构造函数首先就无法正确运行。</p>
<p>对于上面两个例子，第一个顺序是严格的，第二个因为oos和ois连接的已经不是对方了，而是socket另外一端的流，需要严格按照另外一方对接的output流先于对接的input流打开才能顺利运行。</p>
<p>这个writeObject和readObject本身就是线程安全的，传输过程中是不允许被并发访问的。所以对象能一个一个接连不断的传过来，有很多人 在运行的时候会碰到EOFException, 然后百思不得其解，去各种论坛问解决方案。其实笔者这里想说，这个异常不是必须声明的，也就是说它虽然是异常，但其实是正常运行结束的标志。EOF表示读 到了文件尾，发送结束自然连接也就断开了。如果这影响到了你程序的正确性的话，请各位静下心来看看自己程序的业务逻辑，而不要把注意力狭隘的聚集在发送和 接受的方法上。因为笔者也被这样的bug困扰了1整天，被很多论坛的帖子误解了很多次最后得出的教训。如果在while循环中去readObject，本 质上是没有问题的，有对象数据来就会读，没有就自动阻塞。那么抛出EOFException一定是因为连接断了还在继续read，什么原因导致连接断了 呢？一定是业务逻辑哪里存在错误，比如NullPoint、 ClassCaseException、ArrayOutofBound，即使程序较大也没关系，最多只要单步调适一次就能很快发现bug并且解决它。</p>
<p>难怪一位程序大师说过：解决问题90％靠经验，5％靠技术，剩下5％靠运气！真是金玉良言，笔者大概查阅过不下30篇讨论在while循环中使用 readObject抛出EOFExceptionde 的帖子，大家都盲目的去关注解释这个名词、反序列化的行为或反对这样写而没有一个人认为EOF是正确的行为，它其实很老实的在做它的事情。为什么大家都忽 略了真正出错误的地方呢？两个字，经验！</p>
<p>2．关于Java的多线程编程<br />
关于Java的线程，初学或者接触不深的大概也能知道一些基本概念，同时又会很迷惑线程到底是怎么回事？如果有人认为自己已经懂了不妨来回答下面的问题：<br />
a. A对象实现Runnable接口，A.start()运行后所谓的线程对象是谁？是A么？<br />
b. 线程的wait()、notify()方法到底是做什么时候用的，什么时候用？<br />
c. 为什么线程的suspend方法会被标注过时，不推荐再使用，线程还能挂起么？<br />
d. 为了同步我们会对线程方法声明Synchronized来加锁在对象上，那么如果父类的f()方法加了Synchronized，子类重写f()方法必须 也加Synchronized么？如果子类的f()方法重写时声明Synchronized并调用super.f()，那么子类对象上到底有几把锁呢？会 因为竞争产生死锁么？</p>
<p>呵呵，各位能回答上来几道呢？如果这些都能答上来，说明对线程的概念还是满清晰的，虽说还远远不能算精通。笔者这里一一做回答，碍于篇幅的原因，笔者尽量说得简介一点，如果大家有疑惑的欢迎一起讨论。</p>
<p>首先第一点，线程跟对象完全是两回事，虽然我们也常说线程对象。但当你用run()和start()来启动一个线程之后，线程其实跟这个继承了 Thread或实现了Runnable的对象已经没有关系了，对象只能算内存中可用资源而对象的方法只能算内存正文区可以执行的代码段而已。既然是资源和 代码段，另外一个线程当然也可以去访问，main函数执行就至少会启动两个线程，一个我们称之为主线程，还一个是垃圾收集器的线程，主线程结束就意味着程 序结束，可垃圾收集器线程很可能正在工作。</p>
<p>第二点，wait()和sleep()类似，都是让线程处于阻塞状态暂停一段时间，不同之处在于wait会释放当前线程占有的所有的锁，而 sleep不会。我们知道获得锁的唯一方法是进入了Synchronized保护代码段，所以大家会发现只有Synchronized方法中才会出现 wait，直接写会给警告没有获得当前对象的锁。所以notify跟wait配合使用，notify会重新把锁还给阻塞的线程重而使其继续执行，当有多个 对象wait了，notify不能确定唤醒哪一个，必经锁只有一把，所以一般用notifyAll()来让它们自己根据优先级等竞争那唯一的一把锁，竞争 到的线程执行，其他线程只要继续wait。</p>
<p>从前Java允许在一个线程之外把线程挂起，即调用suspend方法，这样的操作是极不安全的。根据面向对象的思想每个对象必须对自己的行为负责，而对 自己的权力进行封装。如果任何外步对象都能使线程被挂起而阻塞的话，程序往往会出现混乱导致崩溃，所以这样的方法自然是被毙掉了啦。</p>
<p>最后一个问题比较有意思，首先回答的是子类重写f()方法可以加Synchronized也可以不加，如果加了而且还内部调用了super.f ()的话理论上是应该对同一对象加两把锁的，因为每次调用Synchronized方法都要加一把，调用子类的f首先就加了一把，进入方法内部调用父类的 f又要加一把，加两把不是互斥的么？那么调父类f加锁不就必须永远等待已经加的锁释放而造成死锁么？实际上是不会的，这个机制叫重进入，当父类的f方法试 图在本对象上再加一把锁的时候，因为当前线程拥有这个对象的锁，也可以理解为开启它的钥匙，所以同一个线程在同一对象上还没释放之前加第二次锁是不会出问 题的，这个锁其实根本就没有加，它有了钥匙，不管加几把还是可以进入锁保护的代码段，畅通无阻，所以叫重进入，我们可以简单认为第二把锁没有加上去。</p>
<p>总而言之，Synchronized的本质是不让其他线程在同一对象上再加一把锁。</p>
<p>Java杂谈（五）</p>
<p><br />
本来预计J2se只讲了第四篇就收尾了，可是版主厚爱把帖子置顶长期让大家浏览让小弟倍感责任重大，务必追求最到更好，所以关于J2se一些没有提到的部 分，决定再写几篇把常用的部分经验全部写出来供大家讨论切磋。这一篇准备讲一讲Xml解析包和Java Swing，然后下一篇再讲java.security包关于Java沙箱安全机制和RMI机制，再进入J2ee的部分，暂时就做这样的计划了。如果由于 实习繁忙更新稍微慢了一些，希望各位见谅！ </p>
<p>1． Java关于XML的解析 <br />
相信大家对XML都不陌生，含义是可扩展标记语言。本身它也就是一个数据的载体以树状表现形式出现。后来慢慢的数据变成了信息，区别是信息可以包括可变的 状态从而针对程序硬编码的做法变革为针对统一接口硬编码而可变状态作为信息进入了XML中存储。这样改变状态实现扩展的唯一工作是在XML中添加一段文本 信息就可以了，代码不需要改动也不需要重新编译。这个灵活性是XML诞生时候谁也没想到的。 </p>
<p>当然，如果接口要能提取XML中配置的信息就需要程序能解析规范的XML文件，Java中当然要提高包对这个行为进行有利支持。笔者打算讲到的两个包是 org.w3c.dom和javax.xml.parsers和。（大家可以浏览一下这些包中间的接口和类定义） </p>
<p>Javax.xml.parsers包很简单，没有接口，两个工厂配两个解析器。显然解析XML是有两种方式的：DOM解析和SAX解析。本质上并没有谁好谁不好，只是实现的思想不一样罢了。给一个XML文件的例子： <br />
&lt;?xml version=&#8221;1.0&#8221; encoding=&#8221;UTF-8&#8221; &gt; <br />
&lt;root &gt; <br />
&lt;child name=&#8221;Kitty&#8221; &gt; <br />
A Cat <br />
&lt;/child &gt; <br />
&lt;/root &gt; </p>
<p>所谓DOM解析的思路是把整个树状图存入内存中，需要那个节点只需要在树上搜索就可以读到节点的属性，内容等，这样的好处是所有节点皆在内存可以反复搜索重复使用，缺点是需要消耗相应的内存空间。 </p>
<p>自然SAX解析的思路就是为了克服DOM的缺点，以事件触发为基本思路，顺序的搜索下来，碰到了Element之前触发什么事件，碰到之后做什么动作。由 于需要自己来写触发事件的处理方案，所以需要借助另外一个自定义的Handler，处于org.xml.sax.helpers包中。它的优点当然是不用 整个包都读入内存，缺点也是只能顺序搜索，走完一遍就得重来。 </p>
<p>大家很容易就能猜到，接触到的J2ee框架用的是哪一种，显然是DOM。因为类似Struts，Hibernate框架配置文件毕竟是很小的一部分配置信 息，而且需要频繁搜索来读取，当然会采用DOM方式（其实SAX内部也是用DOM采用的结构来存储节点信息的）。现在无论用什么框架，还真难发现使用 SAX来解析XML的技术了，如果哪位仁兄知道，请让笔者也学习学习。 </p>
<p>既然解析方式有了，那么就需要有解析的存储位置。不知道大家是否发现org.w3c.dom这个包是没有实现类全部都是接口的。这里笔者想说一下Java 如何对XML解析是Jdk应该考虑的事，是它的责任。而w3c组织是维护定义XML标准的组织，所以一个XML结构是怎么样的由w3c说了算，它不关心 Java如何去实现，于是乎规定了所有XML存储的结构应该遵循的规则，这就是org.w3c.dom里全部的接口目的所在。在笔者看来，简单理解接口的 概念就是实现者必须遵守的原则。 </p>
<p>整个XML对应的结构叫Document、子元素对应的叫做Element、还有节点相关的Node、NodeList、Text、Entity、 CharacterData、CDATASection等接口，它们都可以在XML的语法中间找到相对应的含义。由于这里不是讲解XML基本语法，就不多 介绍了。如果大家感兴趣，笔者也可以专门写一篇关于XML的语法规则帖与大家分享一下。 </p>
<p>2． Java Swing <br />
Swing是一个让人又爱又恨的东西，可爱之处在于上手很容易，较AWT比起来Swing提供的界面功能更加强大，可恨之处在于编复杂的界面工作量实在是 巨大。笔者写过超过3000行的Swing界面，感觉用户体验还不是那么优秀。最近又写过超过6000行的，由于功能模块多了，整体效果还只是一般般。体 会最深的就一个字：累! 所以大家现在都陆续不怎么用Swing在真正开发的项目上了，太多界面技术可以取代它了。笔者去写也是迫于无奈组里面大家都没写过，我不入地域谁入？ </p>
<p>尽管Swing慢慢的在被人忽略，特别是随着B/S慢慢的在淹没C/S，笔者倒是很愿意站出来为Swing正身。每一项技术的掌握绝不是为了流行时尚跟 风。真正喜欢Java的朋友们还是应该好好体会一下Swing，相信在校的很多学生也很多在学习它。很可能从Jdk 1.1、1.2走过来的很多大学老师可能是最不熟悉它的。 <br />
Swing提供了一组轻组件统称为JComponent，它们与AWT组件的最大区别是JComponent全部都是Container，而 Container的特点是里面可以装载别的组件。在Swing组件中无论是JButton、JLabel、JPanel、JList等都可以再装入任何 其他组件。好处是程序员可以对Swing组件实现&#8220;再开发&#8221;，针对特定需求构建自己的按钮、标签、画板、列表之类的特定组件。 </p>
<p>有轻自然就有重，那么轻组件和重组件区别是？重组件表现出来的形态因操作系统不同而异，轻组件是Swing自己提供GUI，在跨平台的时候最大程度的保持一致。 <br />
那么在编程的时候要注意一些什么呢？笔者谈谈自己的几点经验： </p>
<p>a. 明确一个概念，只有Frame组件才可以单独显示的，也许有人会说JOptionPane里面的静态方法就实现了单独窗口出现，但追寻源代码会发现其实现 实出来的Dialog也需要依托一个Frame窗体，如果没有指定就会默认产生一个然后装载这个Dialog显示出来。 </p>
<p>b. JFrame是由这么几部分组成： <br />
最底下一层JRootPane，上面是glassPane (一个JPanel)和layeredPane (一个JLayeredPane)，而layeredPane又由contentPane(一个JPanel)和menuBar构成。我们的组件都是加在 contentPane上，而背景图片只能加在layeredPane上面。 至于glassPane是一个透明的覆盖了contentPane的一层，在特定效果中将被利用到来记录鼠标坐标或掩饰组件。 </p>
<p>c. 为了增强用户体验，我们会在一些按钮上添加快捷键，但Swing里面通常只能识别键盘的Alt键，要加入其他的快捷键，必须自己实现一个ActionListener。 </p>
<p>d. 通过setLayout(null)可以使得所有组件以setBounds()的四个参数来精确定位各自的大小、位置，但不推荐使用，因为好的编程风格不 应该在Swing代码中硬编码具体数字，所有的数字应该以常数的形式统一存在一个静态无实例资源类文件中。这个静态无实例类统一负责Swing界面的风 格，包括字体和颜色都应该包括进去。 </p>
<p>e. 好的界面设计有一条Golden Rule: 用户不用任何手册通过少数尝试就能学会使用软件。所以尽量把按钮以菜单的形式（不管是右键菜单还是窗体自带顶部菜单）呈现给顾客，除非是频繁点击的按钮才有必要直接呈现在界面中。 </p>
<p>其实Swing的功能是相当强大的，只是现在应用不广泛，专门去研究大概是要花不少时间的。笔者在各网站论坛浏览关于Swing的技巧文章还是比较可信 的，自己所学非常有限，各人体会对Swing各个组件的掌握就是一个实践积累的过程。笔者只用到过以上这些，所以只能谈谈部分想法，还望大家见谅！</p>
<p>Java杂谈（六）</p>
<p><br />
这篇是笔者打算写的J2se部分的最后一篇了，这篇结束之后，再写J2ee部分，不知道是否还合适写在这个版块？大家可以给点意见，谢谢大家对小弟这么鼓 励一路写完前六篇Java杂谈的J2se部分。最后这篇打算谈一谈Java中的RMI机制和JVM沙箱安全框架。 </p>
<p>1． Java中的RMI机制 <br />
RMI的全称是远程方法调用，相信不少朋友都听说过，基本的思路可以用一个经典比方来解释：A计算机想要计算一个两个数的加法，但A自己做不了，于是叫另 外一台计算机B帮忙，B有计算加法的功能，A调用它就像调用这个功能是自己的一样方便。这个就叫做远程方法调用了。 </p>
<p>远程方法调用是EJB实现的支柱，建立分布式应用的核心思想。这个很好理解，再拿上面的计算加法例子，A只知道去call计算机B的方法，自己并没有B的 那些功能，所以A计算机端就无法看到B执行这段功能的过程和代码，因为看都看不到，所以既没有机会窃取也没有机会去改动方法代码。EJB正式基于这样的思 想来完成它的任务的。当简单的加法变成复杂的数据库操作和电子商务交易应用的时候，这样的安全性和分布式应用的便利性就表现出来优势了。 </p>
<p>好了，回到细节上，要如何实现远程方法调用呢？我希望大家学习任何技术的时候可以试着依赖自己的下意识判断，只要你的想法是合理健壮的，那么很可能实际上 它就是这么做的，毕竟真理都蕴藏在平凡的生活细节中。这样只要带着一些薄弱的Java基础来思考RMI，其实也可以想出个大概来。 </p>
<p>a) 需要有一个服务器角色，它拥有真正的功能代码方法。例如B，它提供加法服务 <br />
b) 如果想远程使用B的功能，需要知道B的IP地址 <br />
c) 如果想远程使用B的功能，还需要知道B中那个特定服务的名字 </p>
<p>我们很自然可以想到这些，虽然不完善，但已经很接近正确的做法了。实际上RMI要得以实现还得意于Java一个很重要的特性，就是Java反射机制。我们需要知道服务的名字，但又必须隐藏实现的代码，如何去做呢？答案就是：接口！ <br />
举个例子： <br />
public interface Person(){ <br />
public void sayHello(); <br />
} </p>
<p>Public class PersonImplA implements Person{ <br />
public PersonImplA(){} </p>
<p>public void sayHello(){ System.out.println(&#8220;Hello!&#8221;);} <br />
} </p>
<p>Public class PersonImplB implements Person{ <br />
public PersonImplB(){} </p>
<p>public void sayHello(){ System.out.println(&#8220;Nice to meet you!&#8221;);} <br />
} </p>
<p>客户端：Person p = Naming.lookup(&#8220;PersonService&#8221;); <br />
p.sayHello(); </p>
<p>就这几段代码就包含了几乎所有的实现技术，大家相信么？客户端请求一个say hello服务，服务器运行时接到这个请求，利用Java反射机制的Class.newInstance()返回一个对象，但客户端不知道服务器返回的是 ImplA还是ImplB，它接受用的参数签名是Person，它知道实现了Person接口的对象一定有sayHello()方法，这就意味着客户端并 不知道服务器真正如何去实现的，但它通过了解Person接口明确了它要用的服务方法名字叫做sayHello()。 </p>
<p>如此类推，服务器只需要暴露自己的接口出来供客户端，所有客户端就可以自己选择需要的服务。这就像餐馆只要拿出自己的菜单出来让客户选择，就可以在后台厨房一道道的按需做出来，它怎么做的通常是不让客户知道的！（祖传菜谱吧，^_^） </p>
<p>最后一点是我调用lookup，查找一个叫PersonService名字的对象，服务器只要看到这个名字，在自己的目录（相当于电话簿）中找到对应的对 象名字提供服务就可以了，这个目录就叫做JNDI (Java命名与目录接口），相信大家也听过的。 </p>
<p>有兴趣的朋友不妨自己做个RMI的应用，很多前辈的博客中有简单的例子。提示一下利用Jdk的bin目录中rmi.exe和 rmiregistry.exe两个命令就可以自己建起一个服务器，提供远程服务。因为例子很容易找，我就不自己举例子了！ </p>
<p>2． JVM沙箱&amp;框架 <br />
RMI罗唆得太多了，实在是尽力想把它说清楚，希望对大家有帮助。最后的最后，给大家简单讲一下JVM框架，我们叫做Java沙箱。Java沙箱的基本组件如下： <br />
a) 类装载器结构 <br />
b) class文件检验器 <br />
c) 内置于Java虚拟机的安全特性 <br />
d) 安全管理器及Java API </p>
<p>其中类装载器在3个方面对Java沙箱起作用： <br />
a. 它防止恶意代码去干涉善意的代码 <br />
b. 它守护了被信任的类库边界 <br />
c. 它将代码归入保护域，确定了代码可以进行哪些操作 </p>
<p>虚拟机为不同的类加载器载入的类提供不同的命名空间，命名空间由一系列唯一的名称组成，每一个被装载的类将有一个名字，这个命名空间是由Java虚拟机为每一个类装载器维护的，它们互相之间甚至不可见。 </p>
<p>我们常说的包（package）是在Java虚拟机第2版的规范第一次出现，正确定义是由同一个类装载器装载的、属于同一个包、多个类型的集合。类装载器 采用的机制是双亲委派模式。具体的加载器框架我在Java杂谈（一）中已经解释过了，当时说最外层的加载器是AppClassLoader，其实算上网络 层的话AppClassLoader也可以作为parent，还有更外层的加载器URLClassLoader。为了防止恶意攻击由URL加载进来的类文 件我们当然需要分不同的访问命名空间，并且制定最安全的加载次序，简单来说就是两点：</p>
<p>a. 从最内层JVM自带类加载器开始加载，外层恶意同名类得不到先加载而无法使用 <br />
b. 由于严格通过包来区分了访问域，外层恶意的类通过内置代码也无法获得权限访问到内层类，破坏代码就自然无法生效。 </p>
<p>附：关于Java的平台无关性，有一个例子可以很明显的说明这个特性： <br />
一般来说，C或C++中的int占位宽度是根据目标平台的字长来决定的，这就意味着针对不同的平台编译同一个C++程序在运行时会有不同的行为。然而对于 Java中的int都是32位的二进制补码标识的有符号整数，而float都是遵守IEEE 754浮点标准的32位浮点数。 </p>
<p>PS: 这个小弟最近也没时间继续研究下去了，只是想抛砖引玉的提供给大家一个初步认识JVM的印象。有机会了解一下JVM的内部结构对今后做Java开发是很有好处的。</p>
<p>Java杂谈（七）－－接口&amp; 组件、容器</p>
<p>终于又静下来继续写这个主题的续篇，前六篇主要讲了一些J2se方面的经验和感受， 眼下Java应用范围已经被J2ee占据了相当大的一块领域，有些人甚至声称Java被J2ee所取代了。不知道大家如何来理解所谓的J2ee (Java2 Enterprise Edition)，也就是Java企业级应用？ </p>
<p>笔者的观点是，技术的发展是顺应世界变化的趋势的，从C/S过渡到B/S模式，从客户端的角度考虑企业级应用或者说电子商务领域不在关心客户端维护问题， 这个任务已经交给了任何一台PC都会有的浏览器去维护；从服务器端的角度考虑，以往C/S中的TCP/IP协议实现载体ServerSocket被Web Server Container所取代，例如大家都很熟悉的Tomcat、JBoss、WebLogic等等。总之一切的转变都是为了使得Java技术能更好的为人类 生产生活所服务。 </p>
<p>有人会问，直接去学J2ee跳过J2se行否？笔者是肯定不赞成的，实际上确实有人走这条路，但笔者自身体会是正是由于J2se的基础很牢固，才会导致在J2ee学习的道路上顺风顺水，知识点上不会有什么迷惑的地方。举个简单的例子吧： </p>
<p>笔者曾经跟大学同学讨论下面这两种写法的区别： <br />
ArrayList list = new ArrayList(); //笔者不说反对，但至少不赞成 <br />
List list = new ArrayList(); //笔者支持 <br />
曾经笔者跟同学争论了几个小时，他非说第一种写法更科学，第二种完全没有必要。我无法完全说服他，但笔者认为良好的习惯和意识是任何时候都应该针对接口编程，以达到解耦合和可扩展性的目的。下面就以接口开始进入J2ee的世界吧： </p>
<p>1. J2ee与接口 </p>
<p>每一个版本的J2ee都对应着一个确定版本的JDK，J2ee1.4对应Jdk1.4，现在比较新的是JDK5.0，自然也会有J2EE 5.0。其实笔者一直在用的是J2EE1.4，不过没什么关系，大家可以下任何一个版本的J2ee api来稍微浏览一下。笔者想先声明一个概念，J2ee也是源自Java，所以底层的操作依然调用到很多J2se的库，所以才建议大家先牢牢掌握J2se 的主流技术。 </p>
<p>J2ee api有一个特点，大家比较熟悉的几个包java.jms、javax.servlet.http、javax.ejb等都以interface居多，实 现类较少。其实大家真正在用的时候百分之六十以上都在反复的查着javax.servlet.http这个包下面几个实现类的api函数，其他的包很少问 津。笔者建议在学习一种技术之前，对整体的框架有一个了解是很有必要的，J2ee旨在通过interface的声明来规范实现的行为，任何第三方的厂商想 要提供自己品牌的实现前提也是遵循这些接口定义的规则。如果在从前J2se学习的道路上对接口的理解很好的话，这里的体会将是非常深刻的，举个简单的例 子： </p>
<p>public interface Mp3{ <br />
public void play(); <br />
public void record(); <br />
public void stop(); <br />
} </p>
<p>如果我定义这个简单的接口，发布出去，规定任何第三方的公司想推出自己的名字为Mp3的产品都必须实现这个接口，也就是至少提供接口中方法的具体实现。这 个意义已经远远不止是面向对象的多态了，只有厂商遵循J2ee的接口定义，世界上的J2ee程序员才能针对统一的接口进行程序设计，最终不用改变代码只是 因为使用了不同厂商的实现类而有不同的特性罢了，本质上说，无论哪一种厂商实现都完成了职责范围内的工作。这个就是笔者想一直强调的，针对接口编程的思 想。 </p>
<p>接口到底有什么好处呢？我们这样设想，现在有AppleMp3、SonyMp3、SamsungMp3都实现了这个Mp3的接口，于是都有了play、 record、stop这三个功能。我们将Mp3产品座位一个组件的时候就不需要知道它的具体实现，只要看到接口定义知道这个对象有3个功能就可以使用 了。那么类似下面这样的业务就完全可以在任何时间从3个品牌扩展到任意个品牌，开个玩笑的说，项目经理高高在上的写完10个接口里的方法声明，然后就丢给 手下的程序员去写里面的细节，由于接口已经统一（即每个方法传入和传出的格式已经统一），经理只需关注全局的业务就可以天天端杯咖啡走来走去了，^_^： <br />
public Mp3 create(); <br />
public void copy(Mp3 mp3); <br />
public Mp3 getMp3(); </p>
<p>最后用一个简单的例子说明接口：一个5号电池的手电筒，可以装入任何牌子的5号电池，只要它符合5号电池的规范，装入之后任何看不到是什么牌子，只能感受 到手电筒在完成它的功能。那么生产手电筒的厂商和生产5号电池的厂商就可以完全解除依赖关系，可以各自自由开发自己的产品，因为它们都遵守5号电池应有的 形状、正负极位置等约定。这下大家能对接口多一点体会了么？ </p>
<p>2. 组件和容器 <br />
针对接口是笔者特意强调的J2ee学习之路必备的思想，另外一个就是比较常规的组件和容器的概念了。很多教材和专业网站都说J2EE的核心是一组规范与指 南，强调J2ee的核心概念就是组件+容器，这确实是无可厚非的。随着越来越多的J2ee框架出现，相应的每种框架都一般有与之对应的容器。 </p>
<p>容器，是用来管理组件行为的一个集合工具，组件的行为包括与外部环境的交互、组件的生命周期、组件之间的合作依赖关系等等。J2ee包含的容器种类大约有 Web容器、Application Client容器、EJB容器、Applet客户端容器等。但在笔者看来，现在容器的概念变得有点模糊了，大家耳熟能详是那些功能强大的开源框架，比如 Hibernate、Struts2、Spring、JSF等，其中Hibernate就基于JDBC的基础封装了对事务和会话的管理，大大方便了对数据 库操作的繁琐代码，从这个意义上来说它已经接近容器的概念了，EJB的实体Bean也逐渐被以Hibernate为代表的持久化框架所取代。 </p>
<p>组件，本意是指可以重用的代码单元，一般代表着一个或者一组可以独立出来的功能模块，在J2ee中组件的种类有很多种，比较常见的是EJB组件、DAO组 件、客户端组件或者应用程序组件等，它们有个共同特点是分别会打包成.war，.jar，.jar，.ear，每个组件由特定格式的xml描述符文件进行 描述，而且服务器端的组件都需要被部署到应用服务器上面才能够被使用。 </p>
<p>稍微理解完组件和容器，还有一个重要的概念就是分层模型，最著名的当然是MVC三层模型。在一个大的工程或项目中，为了让前台和后台各个模块的编程人员能 够同时进行工作提高开发效率，最重要的就是实现层与层之间的耦合关系，许多分层模型的宗旨和开源框架所追求的也就是这样的效果。在笔者看来，一个完整的 Web项目大概有以下几个层次： </p>
<p>a) 表示层（Jsp、Html、Javascript、Ajax、Flash等等技术对其支持） <br />
b) 控制层（Struts、JSF、WebWork等等框架在基于Servlet的基础上支持，负责把具体的请求数据（有时卸载重新装载）导向适合处理它的模型层对象） <br />
c) 模型层（笔者认为目前最好的框架是Spring，实质就是处理表示层经由控制层转发过来的数据，包含着大量的业务逻辑） <br />
d) 数据层（Hibernate、JDBC、EJB等，由模型层处理完了持久化到数据库中） </p>
<p>当然，这仅仅是笔者个人的观点，仅仅是供大家学习做一个参考，如果要实现这些层之间的完全分离，那么一个大的工程，可以仅仅通过增加人手就来完成任务。虽 然《人月神话》中已经很明确的阐述了增加人手并不能是效率增加，很大程度上是因为彼此做的工作有顺序上的依赖关系或者说难度和工作量上的巨大差距。当然理 想状态在真实世界中是不可能达到的，但我们永远应该朝着这个方向去不断努力。最开始所提倡的针对接口来编程，哪怕是小小的细节，写一条List list= = new ArrayList()语句也能体现着处处皆使用接口的思想在里面。Anyway，这只是个开篇，笔者会就自己用过的J2ee技术和框架再细化谈一些经验.</p>
<p>Java杂谈（八）－－Servlet/Jsp</p>
<p><br />
终于正式进入J2ee的细节部分了，首当其冲的当然是Servlet和Jsp了，上篇曾经提到过J2ee只是一个规范和指南，定义了一组必须要遵循的接 口，核心概念是组件和容器。曾经有的人问笔者Servlet的Class文件是哪里来的？他认为是J2ee官方提供的，我举了一个简单的反例：稍微检查了 一下Tomcat5.0里面的Servlet.jar文件和JBoss里面的Servlet.jar文件大小，很明显是不一样的，至少已经说明了它们不是 源自同根的吧。其实Servlet是由容器根据J2ee的接口定义自己来实现的，实现的方式当然可以不同，只要都遵守J2ee规范和指南。 </p>
<p>上述只是一个常见的误区罢了，告诉我们要编译运行Servlet，是要依赖于实现它的容器的，不然连jar文件都没有，编译都无法进行。那么Jsp呢？ Java Server Page的简称，是为了开发动态网页而诞生的技术，其本质也是Jsp，在编写完毕之后会在容器启动时经过编译成对应的Servlet。只是我们利用Jsp 的很多新特性，可以更加专注于前后台的分离，早期Jsp做前台是满流行的，毕竟里面支持Html代码，这让前台美工人员可以更有效率的去完成自己的工作。 然后Jsp将请求转发到后台的Servlet，由Servlet处理业务逻辑，再转发回另外一个Jsp在前台显示出来。这似乎已经成为一种常用的模式，最 初笔者学习J2ee的时候，大量时间也在编写这样的代码。 </p>
<p>尽管现在做前台的技术越来越多，例如Flash、Ajax等，已经有很多人不再认为Jsp重要了。笔者觉得Jsp带来的不仅仅是前后端分离的设计理念，它 的另外一项技术成就了我们今天用的很多框架，那就是Tag标签技术。所以与其说是在学习Jsp，不如更清醒的告诉自己在不断的理解Tag标签的意义和本 质。 </p>
<p>1． Servlet以及Jsp的生命周期 <br />
Servlet是Jsp的实质，尽管容器对它们的处理有所区别。Servlet有init()方法初始化，service()方法进行Web服务， destroy()方法进行销毁，从生到灭都由容器来掌握，所以这些方法除非你想自己来实现Servlet，否则是很少会接触到的。正是由于很少接触，才 容易被广大初学者所忽略，希望大家至少记住Servlet生命周期方法都是回调方法。回调这个概念简单来说就是把自己注入另外一个类中，由它来调用你的方 法，所谓的另外一个类就是Web容器，它只认识接口和接口的方法，注入进来的是怎样的对象不管，它只会根据所需调用这个对象在接口定义存在的那些方法。由 容器来调用的Servlet对象的初始化、服务和销毁方法，所以叫做回调。这个概念对学习其他J2ee技术相当关键！ </p>
<p>那么Jsp呢？本事上是Servlet，还是有些区别的，它的生命周期是这样的： <br />
a) 一个客户端的Request到达服务器 -&gt; <br />
b) 判断是否第一次调用 -&gt; 是的话编译Jsp成Servlet <br />
c) 否的话再判断此Jsp是否有改变 -&gt; 是的话也重新编译Jsp成Servlet <br />
d) 已经编译最近版本的Servlet装载所需的其他Class <br />
e) 发布Servlet，即调用它的Service()方法 </p>
<p>所以Jsp号称的是第一次Load缓慢，以后都会很快的运行。从它的生命的周期确实不难看出来这个特点，客户端的操作很少会改变Jsp的源码，所以它不需 要编译第二次就一直可以为客户端提供服务。这里稍微解释一下Http的无状态性，因为发现很多人误解，Http的无状态性是指每次一张页面显示出来了，与 服务器的连接其实就已经断开了，当再次有提交动作的时候，才会再次与服务器进行连接请求提供服务。当然还有现在比较流行的是Ajax与服务器异步通过 xml交互的技术，在做前台的领域潜力巨大，笔者不是Ajax的高手，这里无法为大家解释。 </p>
<p>2． Tag标签的本质 <br />
笔者之前说了，Jsp本身初衷是使得Web应用前后台的开发可以脱离耦合分开有效的进行，可惜这个理念的贡献反倒不如它带来的Tag技术对J2ee的贡献 要大。也许已经有很多人开始使用Tag技术了却并不了解它。所以才建议大家在学习J2ee开始的时候一定要认真学习Jsp，其实最重要的就是明白标签的本 质。 </p>
<p>Html标签我们都很熟悉了，有 &lt;html&gt; 、 &lt;head&gt; 、 &lt;body&gt; 、 &lt;title&gt; ，Jsp带来的Tag标签遵循同样的格式，或者说更严格的Xml格式规范，例如 &lt;jsp:include&gt; 、 &lt;jsp:useBean&gt; 、 &lt;c:if&gt; 、 &lt;c:forEach&gt; 等等。它们没有什么神秘的地方，就其源头也还是Java Class而已，Tag标签的实质也就是一段Java代码，或者说一个Class文件。当配置文件设置好去哪里寻找这些Class的路径后，容器负责将页 面中存在的标签对应到相应的Class上，执行那段特定的Java代码，如此而已。 <br />
说得明白一点的话还是举几个简单的例子说明一下吧： </p>
<p>&lt;jsp:include&gt; 去哪里找执行什么class呢?首先这是个jsp类库的标签，当然要去jsp类库寻找相应的class了，同样它也是由Web容器来提供，例如 Tomcat就应该去安装目录的lib文件夹下面的jsp-api.jar里面找，有兴趣的可以去找一找啊！ </p>
<p>&lt;c:forEach&gt; 又去哪里找呢？这个是由Jsp2.0版本推荐的和核心标记库的内容，例如 &lt;c:if&gt; 就对应在页面中做if判断的功能的一断Java代码。它的class文件在jstl.jar这个类库里面，往往还需要和一个standard.jar类库 一起导入，放在具体Web项目的WEB-INF的lib目录下面就可以使用了。 </p>
<p>顺便罗唆一句，Web Project的目录结构是相对固定的，因为容器会按照固定的路径去寻找它需要的配置文件和资源，这个任何一本J2ee入门书上都有，这里就不介绍了。了 解Tag的本质还要了解它的工作原理，所以大家去J2ee的API里找到并研究这个包：javax.servlet.jsp.tagext。它有一些接 口，和一些实现类，专门用语开发Tag，只有自己亲自写出几个不同功能的标签，才算是真正理解了标签的原理。别忘记了自己开发的标签要自己去完成配置文 件，容器只是集成了去哪里寻找jsp标签对应class的路径，自己写的标签库当然要告诉容器去哪里找啦。 </p>
<p>说了这么多，我们为什么要用标签呢？完全在Jsp里面来个 &lt;% %&gt; 就可以在里面任意写Java代码了，但是长期实践发现页面代码统一都是与html同风格的标记语言更加有助于美工人员进行开发前台，它不需要懂Java， 只要Java程序员给个列表告诉美工什么标签可以完成什么逻辑功能，他就可以专注于美工，也算是进一步隔离了前后台的工作吧！ </p>
<p>3． 成就Web框架 <br />
框架是什么？曾经看过这样的定义：与模式类似，框架也是解决特定问题的可重用方法，框架是一个描述性的构建块和服务集合，开发人员可以用来达成某个目标。 一般来说，框架提供了解决某类问题的基础设施，是用来创建解决方案的工具，而不是问题的解决方案。 </p>
<p>正是由于Tag的出现，成就了以后出现的那么多Web框架，它们都开发了自己成熟实用的一套标签，然后由特定的Xml文件来配置加载信息，力图使得Web 应用的开发变得更加高效。下面这些标签相应对很多人来说相当熟悉了： <br />
&lt;html:password&gt; <br />
&lt;logic:equal&gt; <br />
&lt;bean:write&gt; <br />
&lt;f:view&gt; <br />
&lt;h:form&gt; <br />
&lt;h:message&gt; </p>
<p>它们分别来自Struts和JSF框架，最强大的功能在于控制转发，就是MVC三层模型中间完成控制器的工作。Struts-1实际上并未做到真正的三层 隔离，这一点在Struts-2上得到了很大的改进。而Jsf向来以比较完善合理的标签库受到人们推崇。 </p>
<p>今天就大概讲这么多吧，再次需要强调的是Servlet/Jsp是学习J2ee必经之路，也是最基础的知识，希望大家给与足够的重视！</p>
<p><br />
Java杂谈（九）－－Struts</p>
<p>J2ee的开源框架很多，笔者只能介绍自己熟悉的几个，其他的目前在中国IT行业应用得不是很多。希望大家对新出的框架不要盲目的推崇，首先一定要熟悉它比旧的到底好在哪里，新的理念和特性是什么？然后再决定是否要使用它。 </p>
<p>这期的主题是Struts，直译过来是支架。Struts的第一个版本是在2001年5月发布的，它提供了一个Web应用的解决方案，如何让Jsp和 servlet共存去提供清晰的分离视图和业务应用逻辑的架构。在Struts之前，通常的做法是在Jsp中加入业务逻辑，或者在Servlet中生成视 图转发到前台去。Struts带着MVC的新理念当时退出几乎成为业界公认的Web应用标准，于是当代IT市场上也出现了众多熟悉Struts的程序员。 即使有新的框架再出来不用，而继续用Struts的理由也加上了一条低风险，因为中途如果开发人员变动，很容易的招进新的会Struts的IT民工啊， ^_^! </p>
<p>笔者之前说的都是Struts-1，因为新出了Struts-2，使得每次谈到Struts都必须注明它是Struts-1还是2。笔者先谈比较熟悉的 Struts-1，下次再介绍一下与Struts－2的区别： </p>
<p>1． Struts框架整体结构 <br />
Struts-1的核心功能是前端控制器，程序员需要关注的是后端控制器。前端控制器是是一个Servlet，在Web.xml中间配置所有 Request都必须经过前端控制器，它的名字是ActionServlet，由框架来实现和管理。所有的视图和业务逻辑隔离都是应为这个 ActionServlet， 它就像一个交通警察，所有过往的车辆必须经过它的法眼，然后被送往特定的通道。所有，对它的理解就是分发器，我们也可以叫做Dispatcher，其实了 解Servlet编程的人自己也可以写一个分发器，加上拦截request的Filter，其实自己实现一个struts框架并不是很困难。主要目的就是 让编写视图的和后台逻辑的可以脱离紧耦合，各自同步的完成自己的工作。 </p>
<p>那么有了ActionServlet在中间负责转发，前端的视图比如说是Jsp，只需要把所有的数据Submit，这些数据就会到达适合处理它的后端控制 器Action，然后在里面进行处理，处理完毕之后转发到前台的同一个或者不同的视图Jsp中间，返回前台利用的也是Servlet里面的forward 和redirect两种方式。所以到目前为止，一切都只是借用了Servlet的API搭建起了一个方便的框架而已。这也是Struts最显著的特性?? 控制器。 </p>
<p>那么另外一个特性，可以说也是Struts-1带来的一个比较成功的理念，就是以xml配置代替硬编码配置信息。以往决定Jsp往哪个servlet提 交，是要写进Jsp代码中的，也就是说一旦这个提交路径要改，我们必须改写代码再重新编译。而Struts提出来的思路是，编码的只是一个逻辑名字，它对 应哪个class文件写进了xml配置文件中，这个配置文件记录着所有的映射关系，一旦需要改变路径，改变xml文件比改变代码要容易得多。这个理念可以 说相当成功，以致于后来的框架都延续着这个思路，xml所起的作用也越来越大。 </p>
<p>大致上来说Struts当初给我们带来的新鲜感就这么多了，其他的所有特性都是基于方便的控制转发和可扩展的xml配置的基础之上来完成它们的功能的。 <br />
下面将分别介绍Action和FormBean， 这两个是Struts中最核心的两个组件。 </p>
<p>2． 后端控制器Action <br />
Action就是我们说的后端控制器，它必须继承自一个Action父类，Struts设计了很多种Action，例如DispatchAction、 DynaValidationAction。它们都有一个处理业务逻辑的方法execute()，传入的request, response, formBean和actionMapping四个对象，返回actionForward对象。到达Action之前先会经过一个 RequestProcessor来初始化配置文件的映射关系，这里需要大家注意几点： </p>
<p>1) 为了确保线程安全，在一个应用的生命周期中，Struts框架只会为每个Action类创建一个Action实例，所有的客户请求共享同一个Action 实例，并且所有线程可以同时执行它的execute()方法。所以当你继承父类Action，并添加了private成员变量的时候，请记住这个变量可以 被多个线程访问，它的同步必须由程序员负责。(所有我们不推荐这样做)。在使用Action的时候，保证线程安全的重要原则是在Action类中仅仅使用 局部变量，谨慎的使用实例变量。局部变量是对每个线程来说私有的，execute方法结束就被销毁，而实例变量相当于被所有线程共享。 </p>
<p>2) 当ActionServlet实例接收到Http请求后，在doGet()或者doPost()方法中都会调用process()方法来处理请求。 RequestProcessor类包含一个HashMap，作为存放所有Action实例的缓存，每个Action实例在缓存中存放的属性key为 Action类名。在RequestProcessor类的processActionCreate()方法中，首先检查在HashMap中是否存在 Action实例。创建Action实例的代码位于同步代码块中，以保证只有一个线程创建Action实例。一旦线程创建了Action实例并把它存放到 HashMap中，以后所有的线程会直接使用这个缓存中的实例。 </p>
<p>3) &lt;action&gt; 元素的 &lt;roles&gt; 属性指定访问这个Action用户必须具备的安全角色，多个角色之间逗号隔开。RequestProcessor类在预处理请求时会调用自身的 processRoles()方法，检查配置文件中是否为Action配置了安全角色，如果有，就调用HttpServletRequest的 isUserInRole()方法来判断用户是否具备了必要的安全性角色，如果不具备，就直接向客户端返回错误。(返回的视图通过 &lt;input&gt; 属性来指定) </p>
<p>3． 数据传输对象FormBean <br />
Struts并没有把模型层的业务对象直接传递到视图层，而是采用DTO（Data Transfer Object）来传输数据，这样可以减少传输数据的冗余，提高传输效率；还有助于实现各层之间的独立，使每个层分工明确。Struts的DTO就是 ActionForm，即formBean。由于模型层应该和Web应用层保持独立。由于ActionForm类中使用了Servlet API， 因此不提倡把ActionForm传递给模型层， 而应该在控制层把ActionForm Bean的数据重新组装到自定义的DTO中， 再把它传递给模型层。它只有两个scope，分别是session和request。（默认是session）一个ActionForm标准的生命周期 是： <br />
1) 控制器收到请求 -&gt; <br />
2) 从request或session中取出ActionForm实例，如不存在就创建一个 -&gt; <br />
3) 调用ActionForm的reset()方法 -&gt; <br />
4) 把实例放入session或者request中 -&gt; <br />
5) 将用户输入表达数据组装到ActionForm中 -&gt; <br />
6) 如眼张方法配置了就调用validate()方法 -&gt; <br />
7) 如验证错误就转发给 &lt;input&gt; 属性指定的地方，否则调用execute()方法 </p>
<p>validate()方法调用必须满足两个条件： <br />
1) ActionForm 配置了Action映射而且name属性匹配 <br />
2) &lt;aciton&gt; 元素的validate属性为true </p>
<p>如果ActionForm在request范围内，那么对于每个新的请求都会创建新的ActionForm实例，属性被初始化为默认值，那么reset ()方法就显得没有必要；但如果ActionForm在session范围内，同一个ActionForm实例会被多个请求共享，reset()方法在这 种情况下极为有用。 </p>
<p>4． 验证框架和国际化 <br />
Struts有许多自己的特性，但是基本上大家还是不太常用，说白了它们也是基于JDK中间的很多Java基础包来完成工作。例如国际化、验证框架、插件 自扩展功能、与其他框架的集成、因为各大框架基本都有提供这样的特性，Struts也并不是做得最好的一个，这里也不想多说。Struts的验证框架，是 通过一个validator.xml的配置文件读入验证规则，然后在validation-rules.xml里面找到验证实现通过自动为Jsp插入 Javascript来实现，可以说做得相当简陋。弹出来的JavaScript框不但难看还很多冗余信息，笔者宁愿用formBean验证或者 Action的saveErrors()，验证逻辑虽然要自己写，但页面隐藏/浮现的警告提示更加人性化和美观一些。 </p>
<p>至于Struts的国际化，其实无论哪个框架的国际化，java.util.Locale类是最重要的Java I18N类。在Java语言中，几乎所有的对国际化和本地化的支持都依赖于这个类。如果Java类库中的某个类在运行的时候需要根据Locale对象来调 整其功能，那么就称这个类是本地敏感的(Locale-Sensitive)， 例如java.text.DateFormat类就是，依赖于特定Locale。 </p>
<p>创建Locale对象的时候，需要明确的指定其语言和国家的代码，语言代码遵从的是ISO-639规范，国家代码遵从ISO-3166规范，可以从 <br />
http://www.unicode.org/unicode/onlinedat/languages.html <br />
http://www.unicode.org/unicode/onlinedat/countries.htm </p>
<p>Struts的国际化是基于properties的message/key对应来实现的，笔者曾写过一个程序，所有Jsp页面上没有任何Text文本串， 全部都用的是 &lt;bean:message&gt; 去Properties文件里面读，这个时候其实只要指定不同的语言区域读不同的Properties文件就实现了国际化。需要注意的是不同语言的字符写 进Properties文件的时候需要转化成Unicode码，JDK已经带有转换的功能。JDK的bin目录中有native2ascii这个命令，可 以完成对*.txt和*.properties的Unicode码转换。 </p>
<p>OK，今天就说到这里，本文中的很多内容也不是笔者的手笔，是笔者一路学习过来自己抄下来的笔记，希望对大家有帮助！Java杂谈一路走来，感谢大家持续的关注，大概再有个2到3篇续篇就改完结了！笔者尽快整理完成后续的写作吧&#8230;&#8230;^_^<br />
Java杂谈（九）－－Struts2</p>
<p><br />
最近业余时间笔者一直Java Virtual Machine的研究，由于实习分配到项目组里面，不想从前那么闲了，好不容易才抽出时间来继续这个话题的帖子。我打算把J2ee的部分结束之后，再谈谈 JVM和JavaScript，只要笔者有最新的学习笔记总结出来，一定会拿来及时和大家分享的。衷心希望与热爱Java的关大同仁共同进步&#8230;&#8230; </p>
<p>这次准备继续上次的话题先讲讲Struts-2，手下简短回顾一段历史：随着时间的推移，Web应用框架经常变化的需求，产生了几个下一代 Struts的解决方案。其中的Struts Ti 继续坚持 MVC模式的基础上改进，继续Struts的成功经验。 WebWork项目是在2002年3月发布的，它对Struts式框架进行了革命性改进，引进了不少新的思想，概念和功能，但和原Struts代码并不兼 容。WebWork是一个成熟的框架，经过了好几次重大的改进与发布。在2005年12月，WebWork与Struts Ti决定合拼， 再此同时， Struts Ti 改名为 Struts Action Framework 2.0,成为Struts真正的下一代。 </p>
<p>看看Struts-2的处理流程： <br />
1) Browser产生一个请求并提交框架来处理：根据配置决定使用哪些拦截器、action类和结果等。 <br />
2) 请求经过一系列拦截器：根据请求的级别不同拦截器做不同的处理。这和Struts-1的RequestProcessor类很相似。 <br />
3) 调用Action: 产生一个新的action实例，调用业务逻辑方法。 <br />
4) 调用产生结果：匹配result class并调用产生实例。 <br />
5) 请求再次经过一系列拦截器返回：过程也可配置减少拦截器数量 <br />
6) 请求返回用户：从control返回servlet，生成Html。 </p>
<p>这里很明显的一点是不存在FormBean的作用域封装，直接可以从Action中取得数据。 这里有一个Strut-2配置的web.xml文件：<br />
&lt;filter&gt; <br />
&lt;filter-name&gt; controller &lt;/filter-name&gt; <br />
&lt;filter-class&gt; org.apache.struts.action2.dispatcher.FilterDispatcher &lt;/filter-class&gt; <br />
&lt;/filter&gt; <br />
&lt;filter-mapping&gt; <br />
&lt;filter-name&gt; cotroller &lt;/filter-name&gt; <br />
&lt;url-pattern&gt; /* &lt;/url-pattern&gt; <br />
&lt;/filter-mapping&gt; </p>
<p>注意到以往的servlet变成了filter，ActionServlet变成了FilterDispatcher，*.do变成了/*。filter 配置定义了名称(供关联)和filter的类。filter mapping让URI匹配成功的的请求调用该filter。默认情况下，扩展名为 ".action "。这个是在default.properties文件里的 "struts.action.extension "属性定义的。 </p>
<p>default.properties是属性定义文件，通过在项目classpath路径中包含一个名为&#8220;struts.properties&#8221;的文件来 设置不同的属性值。而Struts-2的默认配置文件名为struts.xml。由于1和2的action扩展名分别为.do和.action，所以很方 便能共存。我们再来看一个Struts-2的action代码： <br />
public class MyAction { <br />
public String execute() throws Exception { <br />
//do the work <br />
return "success "; <br />
} <br />
} </p>
<p>很明显的区别是不用再继承任何类和接口，返回的只是一个String，无参数。实际上在Struts-2中任何返回String的无参数方法都可以通过配 置来调用action。所有的参数从哪里来获得呢？答案就是Inversion of Control技术（控制反转）。笔者尽量以最通俗的方式来解释，我们先试图让这个Action获得reuqest对象，这样可以提取页面提交的任何参 数。那么我们把request设为一个成员变量，然后需要一个对它的set方法。由于大部分的action都需要这么做，我们把这个set方法作为接口来 实现。 <br />
public interface ServletRequestAware { <br />
public void setServletRequest(HttpServletRequest request); <br />
} </p>
<p>public class MyAction implements ServletRequestAware { <br />
private HttpServletRequest request; </p>
<p>public void setServletRequest(HttpServletRequest request) { <br />
this.request = request; <br />
} </p>
<p>public String execute() throws Exception { <br />
// do the work directly using the request <br />
return Action.SUCCESS; <br />
} <br />
} </p>
<p>那么谁来调用这个set方法呢？也就是说谁来控制这个action的行为，以往我们都是自己在适当的地方写上一句 action.setServletRequest(&#8230;)，也就是控制权在程序员这边。然而控制反转的思想是在哪里调用交给正在运行的容器来决定，只要利 用Java反射机制来获得Method对象然后调用它的invoke方法传入参数就能做到，这样控制权就从程序员这边转移到了容器那边。程序员可以减轻很 多繁琐的工作更多的关注业务逻辑。Request可以这样注入到action中，其他任何对象也都可以。为了保证action的成员变量线程安全， Struts-2的action不是单例的，每一个新的请求都会产生一个新的action实例。 </p>
<p>那么有人会问，到底谁来做这个对象的注入工作呢？答案就是拦截器。拦截器又是什么东西？笔者再来尽量通俗的解释拦截器的概念。大家要理解拦截器的话，首先一定要理解GOF23种设计模式中的Proxy模式。 </p>
<p>A对象要调用f()，它希望代理给B来做，那么B就要获得A对象的引用，然后在B的f()中通过A对象引用调用A对象的f()方法，最终达到A的f()被 调用的目的。有没有人会觉得这样很麻烦，为什么明明只要A.f()就可以完成的一定要封装到B的f()方法中去？有哪些好处呢？ </p>
<p>1) 这里我们只有一个A，当我们有很多个A的时候，只需要监视B一个对象的f()方法就可以从全局上控制所有被调用的f()方法。 <br />
2) 另外，既然代理人B能获得A对象的引用，那么B可以决定在真正调A对象的f()方法之前可以做哪些前置工作，调完返回前可有做哪些后置工作。 </p>
<p>讲到这里，大家看出来一点拦截器的概念了么？它拦截下一调f()方法的请求，然后统一的做处理（处理每个的方式还可以不同，解析A对象就可以辨别），处理 完毕再放行。这样像不像对流动的河水横切了一刀，对所有想通过的水分子进行搜身，然后再放行？这也就是AOP（Aspect of Programming面向切面编程）的思想。 </p>
<p>Anyway，Struts-2只是利用了AOP和IoC技术来减轻action和框架的耦合关系，力图到最大程度重用action的目的。在这样的技术 促动下，Struts-2的action成了一个简单被框架使用的POJO（Plain Old Java Object）罢了。实事上AOP和IoC的思想已经遍布新出来的每一个框架上，他们并不是多么新的技术，利用的也都是JDK早已可以最到的事情，它们代 表的是更加面向接口编程，提高重用，增加扩展性的一种思想。Struts-2只是部分的使用这两种思想来设计完成的，另外一个最近很火的框架 Spring，更大程度上代表了这两种设计思想，笔者将于下一篇来进一步探讨Spring的结构。 </p>
<p>PS: 关于Struts-2笔者也没真正怎么用过，这里是看了网上一些前辈的帖子之后写下自己的学习体验，不足之处请见谅！<br />
Java杂谈（十）－－Spring</p>
<p><br />
笔者最近比较忙，一边在实习一边在寻找明年毕业更好的工作，不过论坛里的朋友非常支持小弟继续写，今天是周末，泡上一杯咖啡，继续与大家分享J2ee部分的学习经验。今天的主题是目前很流行也很好的一个开源框架－Spring。 </p>
<p>引用《Spring2.0技术手册》上的一段话： <br />
Spring的核心是个轻量级容器，它是实现IoC容器和非侵入性的框架，并提供AOP概念的实现方式；提供对持久层、事务的支持；提供MVC Web框架的实现，并对于一些常用的企业服务API提供一致的模型封装，是一个全方位的应用程序框架，除此之外，对于现存的各种框架，Spring也提供 了与它们相整合的方案。 <br />
接下来笔者先谈谈自己的一些理解吧，Spring框架的发起者之前一本很著名的书名字大概是《J2ee Development without EJB》，他提倡用轻量级的组件代替重量级的EJB。笔者还没有看完那本著作，只阅读了部分章节。其中有一点分析觉得是很有道理的： </p>
<p>EJB里在服务器端有Web Container和EJB Container，从前的观点是各层之间应该在物理上隔离，Web Container处理视图功能、在EJB Container中处理业务逻辑功能、然后也是EBJ Container控制数据库持久化。这样的层次是很清晰，但是一个很严重的问题是Web Container和EJB Container毕竟是两个不同的容器，它们之间要通信就得用的是RMI机制和JNDI服务，同样都在服务端，却物理上隔离，而且每次业务请求都要远程 调用，有没有必要呢？看来并非隔离都是好的。 </p>
<p>再看看轻量级和重量级的区别，笔者看过很多种说法，觉得最有道理的是轻量级代表是POJO + IoC，重量级的代表是Container + Factory。（EJB2.0是典型的重量级组件的技术）我们尽量使用轻量级的Pojo很好理解，意义就在于兼容性和可适应性，移植不需要改变原来的代 码。而Ioc与Factory比起来，Ioc的优点是更大的灵活性，通过配置可以控制很多注入的细节，而Factory模式，行为是相对比较封闭固定的， 生产一个对象就必须接受它全部的特点，不管是否需要。其实轻量级和重量级都是相对的概念，使用资源更少、运行负载更小的自然就算轻量。 </p>
<p>话题扯远了，因为Spring框架带来了太多可以探讨的地方。比如它的非侵入性：指的是它提供的框架实现可以让程序员编程却感觉不到框架的存在，这样所写 的代码并没有和框架绑定在一起，可以随时抽离出来，这也是Spring设计的目标。Spring是唯一可以做到真正的针对接口编程，处处都是接口，不依赖 绑定任何实现类。同时，Spring还设计了自己的事务管理、对象管理和Model2 的MVC框架，还封装了其他J2ee的服务在里面，在实现上基本都在使用依赖注入和AOP的思想。由此我们大概可以看到Spring是一个什么概念上的框 架，代表了很多优秀思想，值得深入学习。笔者强调，学习并不是框架，而是框架代表的思想，就像我们当初学Struts一样&#8230;&#8230; </p>
<p>1．Spring MVC <br />
关于IoC和AOP笔者在上篇已经稍微解释过了，这里先通过Spring的MVC框架来给大家探讨一下Spring的特点吧。（毕竟大部分人已经很熟悉Struts了，对比一下吧） <br />
众所周知MVC的核心是控制器。类似Struts中的ActionServlet，Spring里面前端控制器叫做DispatcherServlet。 里面充当Action的组件叫做Controller，返回的视图层对象叫做ModelAndView，提交和返回都可能要经过过滤的组件叫做 Interceptor。 </p>
<p>让我们看看一个从请求到返回的流程吧： <br />
(1) 前台Jsp或Html通过点击submit，将数据装入了request域 <br />
(2) 请求被Interceptor拦截下来，执行preHandler()方法出前置判断 <br />
(3) 请求到达DispathcerServlet <br />
(4) DispathcerServlet通过Handler Mapping来决定每个reuqest应该转发给哪个后端控制器Controller<br />
Java杂谈（十一）ORM</p>
<p>这是最后一篇Java杂谈了，以ORM框架的谈论收尾，也算是把J2ee的最后一方面给涵盖到了，之所以这么晚才总结出ORM这方面，一是笔者这两周比较忙，另一方面也想善始善终，仔细的先自己好好研究一下ORM框架技术，不想草率的敷衍了事。 </p>
<p>其实J2ee的规范指南里面就已经包括了一些对象持久化技术，例如JDO（Java Data Object）就是Java对象持久化的新规范，一个用于存取某种数据仓库中的对象的标准化API，提供了透明的对象存储，对开发人员来说，存储数据对象 完全不需要额外的代码（如JDBC API的使用）。这些繁琐的工作已经转移到JDO产品提供商身上，使开发人员解脱出来，从而集中时间和精力在业务逻辑上。另外，JDO很灵活，因为它可以 在任何数据底层上运行。JDBC只是面向关系数据库（RDBMS）JDO更通用，提供到任何数据底层的存储功能，比如关系数据库、文件、XML以及对象数 据库（ODBMS）等等，使得应用可移植性更强。我们如果要理解对象持久化技术，首先要问自己一个问题：为什么传统的JDBC来持久化不再能满足大家的需 求了呢？ </p>
<p>笔者认为最好是能用JDBC真正编写过程序了才能真正体会ORM的好处，同样的道理，真正拿Servlet/Jsp做过项目了才能体会到Struts、 Spring等框架的方便之处。很幸运的是笔者这两者都曾经经历过，用混乱的内嵌Java代码的Jsp加Servlet转发写过完整的Web项目，也用 JDBC搭建过一个完整C/S项目的后台。所以现在接触到新框架才更能体会它们思想和实现的优越之处，回顾从前的代码，真是丑陋不堪啊。^_^ </p>
<p>回到正题，我们来研究一下为什么要从JDBC发展到ORM。简单来说，传统的JDBC要花大量的重复代码在初始化数据库连接上，每次增删改查都要获得 Connection对象，初始化Statement，执行得到ResultSet再封装成自己的List或者Object，这样造成了在每个数据访问方 法中都含有大量冗余重复的代码，考虑到安全性的话，还要加上大量的事务控制和log记录。虽然我们学习了设计模式之后，可以自己定义Factory来帮助 减少一部分重复的代码，但是仍然无法避免冗余的问题。其次，随着OO思想深入人心，连典型的过程化语言Perl等都冠冕堂皇的加上了OO的外壳，何况是 Java中繁杂的数据库访问持久化技术呢？强调面向对象编程的结果就是找到一个桥梁，使得关系型数据库存储的数据能准确的映射到Java的对象上，然后针 对Java对象来设计对象和方法，如果我们把数据库的Table当作Class，Record当作Instance的话，就可以完全用面向对象的思想来编 写数据层的代码。于是乎，Object Relationship Mapping的概念开始普遍受到重视，尽管很早很早就已经有人提出来了。 <br />
缺点我们已经大概清楚了，那么如何改进呢？对症下药，首先我们要解决的是如何从Data Schema准备完美的映射到Object Schema，另外要提供对数据库连接对象生命周期的管理，对事务不同粒度的控制和考虑到扩展性后提供对XML、Properties等可配置化的文件的 支持。到目前为止，有很多框架和技术在尝试着这样做。例如似乎是封装管理得过了头的EJB、很早就出现目前已经不在开发和升级了的Apache OJB、首先支持Manual SQL的iBATIS，还有公认非常优秀的Hibernate等等。在分别介绍它们之前，我还想反复强调这些框架都在试图做什么： </p>
<p>毕竟Java Object和数据库的每一条Record还是有很大的区别，就是类型上来说，DB是没有Boolean类型的。而Java也不得不用封装类 （Integer、Double等）为了能映射上数据库中为null的情况，毕竟Primitive类型是没有null值的。还有一个比较明显的问题是， 数据库有主键和外键，而Java中仍然只能通过基本类型来对应字段值而已，无法规定Unique等特征，更别提外键约束、事务控制和级联操作了。另外，通 过Java Object预设某Field值去取数据库记录，是否在这样的记录也是不能保证的。真的要设计到完全映射的话，Java的Static被所有对象共享的变 量怎么办？在数据库中如何表现出来&#8230;&#8230; <br />
我们能看到大量的问题像一座座大山横在那些框架设计者们面前，他们并不是没有解决办法，而是从不同的角度去考虑，会得到很多不同的解决方案，问题是应该采 取哪一种呢？甚至只有等到真正设计出来了投入生产使用了，才能印证出当初的设想是否真的能为项目开发带来更多的益处。笔者引用一份文档中提到一个健壮的持 久化框架应该具有的特点： <br />
A robust persistence layer should support---- <br />
1. Several types of persistence mechanism <br />
2. Full encapsulation of the persistence mechanism. <br />
3. Multi-object actions <br />
4. Transactions Control <br />
5. Extensibility <br />
6. Object identifiers <br />
7. Cursors: logical connection to the persistence mechanism <br />
8. Proxies: commonly used when the results of a query are to be displayed in a list <br />
9. Records: avoid the overhead of converting database records to objects and then back to records <br />
10. Multi architecture <br />
11. Various database version and/or vendors <br />
12. Multiple connections <br />
13. Native and non-native drivers <br />
14. Structured query language queries(SQL)<br />
Java杂谈（十一） ORM<br />
现在来简短的介绍一下笔者用过的一些持久化框架和技术，之所以前面强调那么多共通的知识，是希望大家不要盲从流行框架，一定要把握它的本质和卓越的思想好在哪里。 <br />
1． Apache OJB <br />
OJB代表Apache Object Relational Bridge，是Apache开发的一个数据库持久型框架。它是基于J2ee规范指南下的持久型框架技术而设计开发的，例如实现了ODMG 3.0规范的API，实现了JDO规范的API， 核心实现是Persistence Broker API。OJB使用XML文件来实现映射并动态的在Metadata layer听过一个Meta-Object-Protocol(MOP)来改变底层数据的行为。更高级的特点包括对象缓存机制、锁管理机制、 Virtual 代理、事务隔离性级别等等。举个OJB Mapping的简单例子ojb-repository.xml： </p>
<p>&lt;class-descriptor class=&#8221;com.ant.Employee&#8221; table=&#8221;EMPLOYEE&#8221;&gt; <br />
&lt;field-descriptor name=&#8221;id&#8221; column=&#8221;ID&#8221; <br />
jdbc-type=&#8221;INTEGER&#8221; primarykey=&#8221;true&#8221; autoincrement=&#8221;true&#8221;/&gt; </p>
<p>&lt;field-descriptor name=&#8221;name&#8221; column=&#8221;NAME&#8221; jdbc-type=&#8221;VARCHAR&#8221;/&gt; <br />
&lt;/class-descrptor&gt; </p>
<p>&lt;class-descriptor class=&#8221;com.ant.Executive&#8221; table=&#8221;EXECUTIVE&#8221;&gt; <br />
&lt;field-descriptor name=&#8221;id&#8221; column=&#8221;ID&#8221; <br />
jdbc-type=&#8221;INTEGER&#8221; primarykey=&#8221;true&#8221; autoincrement=&#8221;true&#8221;/&gt; </p>
<p>&lt;field-descriptor name=&#8221;department&#8221; column=&#8221;DEPARTMENT&#8221; jdbc-type=&#8221;VARCHAR&#8221;/&gt; </p>
<p>&lt;reference-descriptor name=&#8221;super&#8221; class-ref=&#8221;com.ant.Employee&#8221;&gt; <br />
&lt;foreignkey field-ref=&#8221;id&#8221;/&gt; <br />
&lt;/reference-descriptor&gt; <br />
&lt;/class-descrptor&gt; </p>
<p>2． iBATIS <br />
iBATIS最大的特点就是允许用户自己定义SQL来组配Bean的属性。因为它的SQL语句是直接写入XML文件中去的，所以可以最大程度上利用到 SQL语法本身能控制的全部特性，同时也能允许你使用特定数据库服务器的额外特性，并不局限于类似SQL92这样的标准，它最大的缺点是不支持枚举类型的 持久化，即把枚举类型的几个对象属性拼成与数据库一个字段例如VARCHAR对应的行为。这里也举一个Mapping文件的例子sqlMap.xml： <br />
&lt;sqlMap&gt; <br />
&lt;typeAlias type=&#8221;com.ant.Test&#8221; alias=&#8221;test&#8221;/&gt; </p>
<p>&lt;resultMap class=&#8221;test&#8221; id=&#8221;result&#8221;&gt; <br />
&lt;result property=&#8221;testId&#8221; column=&#8221;TestId&#8221;/&gt; <br />
&lt;result property=&#8221;name&#8221; column=&#8221;Name&#8221;/&gt; <br />
&lt;result property=&#8221;date&#8221; column=&#8221;Date&#8221;/&gt; <br />
&lt;/resultMap&gt; </p>
<p>&lt;select id=&#8221;getTestById&#8221; resultMap=&#8221;result&#8221; parameterClass=&#8221;int&#8221;&gt; <br />
select * from Test where TestId=#value# <br />
&lt;/select&gt; </p>
<p>&lt;update id=&#8221;updateTest&#8221; parameterClass=&#8221;test&#8221;&gt; <br />
Update Tests set Name=#name#, Date=&#8221;date&#8221; where TestId=#testId# <br />
&lt;/update&gt; <br />
&lt;/sqlMap&gt; </p>
<p>3． Hibernate <br />
Hibernate无疑是应用最广泛最受欢迎的持久型框架，它生成的SQL语句是非常优秀。虽然一度因为不能支持手工SQL而性能受到局限，但随着新一代 Hibernate 3.x推出，很多缺点都被改进，Hibernate也因此变得更加通用而时尚。同样先看一个Mapping文件的例子customer.hbm.xml来 有一个大概印象： </p>
<p>&lt;hibernate-mapping&gt; <br />
&lt;class name=&#8221;com.ant.Customer&#8221; table=&#8221;Customers&#8221;&gt; <br />
&lt;id name=&#8221;customerId&#8221; column=&#8221;CustomerId&#8221; type=&#8221;int&#8221; unsaved-value=&#8221;0&#8221;&gt; <br />
&lt;generator class=&#8221;sequence&#8221;&gt; <br />
&lt;param name=&#8221;sequence&#8221;&gt; Customers_CustomerId_Seq &lt;/param&gt; <br />
&lt;/generator&gt; <br />
&lt;/id&gt; </p>
<p>&lt;property name=&#8221;firstName&#8221; column=&#8221;FirstName&#8221;/&gt; <br />
&lt;property name=&#8221;lastName&#8221; column=&#8221;LastName&#8221;/&gt; </p>
<p>&lt;set name=&#8221;addresses&#8221; outer-join=&#8221;true&#8221;&gt; <br />
&lt;key column=&#8221;Customer&#8221;/&gt; <br />
&lt;one-to-many class=&#8221;com.ant.Address&#8221;/&gt; <br />
&lt;/set&gt; <br />
&lt;/class&gt;<br />
&lt;/hibernate-mapping&gt; </p>
<p>Hibernate有很多显著的特性，最突出的就是它有自己的查询语言叫做HQL，在HQL中select from的不是Table而是类名，一方面更加面向对象，另外一方面通过在hibernate.cfg.xml中配置Dialect为HQL可以使得整个 后台与数据库脱离耦合，因为不管用那种数据库我都是基于HQL来查询，Hibernate框架负责帮我最终转换成特定数据库里的SQL语句。另外 Hibernate在Object-Caching这方面也做得相当出色，它同时管理两个级别的缓存，当数据被第一次取出后，真正使用的时候对象被放在一 级缓存管理，这个时候任何改动都会影响到数据库；而空闲时候会把对象放在二级缓存管理，虽然这个时候与数据库字段能对应上但未绑定在一起，改动不会影响到 数据库的记录，主要目的是为了在重复读取的时候更快的拿到数据而不用再次请求连接对象。其实关于这种缓存的设计建议大家研究一下Oracle的存储机制 （原理是相通的），Oracle牺牲了空间换来时间依赖于很健壮的缓存算法来保证最优的企业级数据库访问速率。 </p>
<p>以上是一些Mapping的例子，真正在Java代码中使用多半是继承各个框架中默认的Dao实现类，然后可以通过Id来查找对象，或者通过 Example来查找，更流行的是更具Criteria查找对象。Criteria是完全封装了SQL条件查询语法的一个工具类，任何一个查询条件都可以 在Criteria中找到方法与之对应，这样可以在Java代码级别实现SQL的完全控制。另外，现在许多ORM框架的最新版本随着JDk 5.0加入Annotation特性都开始支持用XDoclet来自动根据Annotation来生成XML配置文件了。 </p>
<p>笔者不可能详细的讲解每一个框架，也许更多的人在用Hibernate，笔者是从OJB开始接触ORM技术的，它很原始却更容易让人理解从JDBC到 ORM的过渡。更多的细节是可以从官方文档和书籍中学到的，但我们应该更加看中它们设计思想的来源和闪光点，不是盲从它们的使用方法。</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/smeyou/archive/2009/06/12/4259293.aspx</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/282358.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-15 15:03 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/15/282358.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA自学之路——马士兵</title><link>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282357.html</link><dc:creator>London2012</dc:creator><author>London2012</author><pubDate>Mon, 15 Jun 2009 07:02:00 GMT</pubDate><guid>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282357.html</guid><wfw:comment>http://www.blogjava.net/chenjiajin/comments/282357.html</wfw:comment><comments>http://www.blogjava.net/chenjiajin/archive/2009/06/15/282357.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chenjiajin/comments/commentRss/282357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chenjiajin/services/trackbacks/282357.html</trackback:ping><description><![CDATA[<p>&nbsp;JAVA自学之路 一:学会选择<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_1.html]<br />
&nbsp;<br />
&nbsp;为了就业，不少同学参加各种各样的培训。<br />
&nbsp;决心做软件的，大多数人选的是java，或是.net，也有一些选择了手机、嵌入式、游戏、3G、测试等。 <br />
&nbsp;<br />
&nbsp;那么究竟应该选择什么方向呢？<br />
&nbsp;我的意见是，不要太过相信各种培训机构或是抢手文章的说法（包括我），当你要走向社会的时候，就不要再把自己当成学生，不要把自己的将来交给别人，学会运用自己的眼睛去观察，去了解这个世界吧。 <br />
&nbsp;<br />
&nbsp;每个培训机构都会宣传自己的好处，并不能说明大的趋势。<br />
&nbsp;一些新闻文章很有可能是枪手写的，不必太过相信。<br />
&nbsp;国外背景的教师和课程，未必适合你。<br />
&nbsp;<br />
&nbsp;那么怎么才能确定自己将来的方向？如何才能从纷繁复杂、或真或假的数据世界中挖出一条路？ <br />
&nbsp;我讲一个通过招聘网站的观察方法。<br />
&nbsp;可以到各种招聘的网站上查询信息（可以到google上查询招聘的网站），例如:<br />
&nbsp;http://www.51job.com/ <br />
&nbsp;http://www.chinahr.com/ <br />
&nbsp;http://www.zhaopin.com/ <br />
&nbsp;以及csdn的招聘频道等<br />
&nbsp;还有一个网站也不错，http://www.jobui.com/，综合了各大招聘网站的数据。 <br />
&nbsp;这些数据都是最真实不掺假的原始数据，你可以每隔一段时间搜索一次，一些规律就会被总结出来了。<br />
&nbsp;比如说我在http://www.jobui.com/中搜索java，全国大概提供了3万个职位。<br />
&nbsp;然后要多翻几页，这样不仅能够看清楚大概有多少是有效的职位，而且还可以看清楚用人单位最关心的技能是什么，这个很重要，决定着你将来要花多少时间和精力在特定的知识点上，比如说swing，搜了一下，全国只有700个左右的职位，仔细读了一下，也并非全是有效的职位，花太多时间和精力在这个上面就不值得了，当然自己感兴趣或者为了研究的话另当别论。不过如果是为了快速的就业，把太多时间和精力花在很多职业生涯的前一、二年用不到的知识上就太可惜了。 同时，并非某一个行业的职位数目少，就不能当作一个方向进行选择，比如.NET，我搜索到的职位数是1.6万左右，比java少，是不是就选java了呢？不一定，因为java职位虽然多，但是可能竞争者可能也多，有些方向虽然职位数不多，但是和你竞争这些职位的人数量也少，不见得就不能选择。<br />
&nbsp;<br />
&nbsp;不过，如果某一个方向的职位数目过少，你可就要小心了，选择这样的方向风险会非常大，如J2ME。<br />
&nbsp;我个人觉得java/J2EE、.net、嵌入式开发是不错的三个方向。<br />
&nbsp;如果非要在java和.net中选择的话，我个人是推荐java的，原因：<br />
&nbsp;1：Java能够开发linux、unix服务器上的程序<br />
&nbsp;2：JavaEE和.NET在企业应用方面的关注点是差不多的，但是学习了java如果将来想转到.net上会比较简单，几天的学习然后上手开发应该是问题不大的，但是反之就不行了。 当然如果有了些经验之后，你就会发现语言或者平台不再是技术上的阻碍，一些原理性的东西学到手，然后再加上项目经验，使用什么平台，反而不是最重要的。不过如果非要用一种平台进入企业开发的领域，至少在目前，2007年9月，我推荐java。<br />
&nbsp;完全可以不同意我的观点，但是无庸置疑，如果是为了就业，多到招聘网站阅读阅读职位的信息，对你将来的方向和学习是大有益处的。<br />
&nbsp;选择是最痛苦的，看看《天生购物狂》中的刘青云就知道了，不过既然无法逃避，就作出自己的选择吧。<br />
&nbsp;<br />
&nbsp;每个人都会受到别人的影响，在作出决定之前，要想尽各种办法让自己理性一些吧。这样，你的选择会离正确的方向更近一些。<br />
&nbsp;<br />
&nbsp;JAVA自学之路 二:JAVA自学路线图<br />
&nbsp;<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_2.html]<br />
&nbsp;<br />
&nbsp;有不少的同学发信给我，和我探讨java的自学过程应该是什么样的，毕竟有很多人因为各种各样的原因不能参加培训。我试着给出自己的见解，抛砖引玉吧。 这个路线图是给那些为了就业的人准备的，如果只是兴趣，不一定照这个走。<br />
&nbsp;这里只是讲了路线图，关于路线中的各个阶段，学到什么程度，如何学习等，可以参考后面的JAVA自学之路 七:《路线图明细》。<br />
&nbsp;首先要学JavaSE，这是无庸置疑的。<br />
&nbsp;与此同时，是的，与此同时，和JavaSE的学习同步，建议大家研究一下数据结构与算法。<br />
&nbsp;在这儿之后，你可以选择向J2ME、或者Java GUI、Socket编程等方向努力，但是通过第一篇的办法，你可以很容易就将这方向过滤掉（永远不要忘了我们是为了就业），好吧，暂时和它们诀别，还是向着J2EE的方向前进吧。<br />
&nbsp;在JavaSE完成之后，可以试着完成一些小项目，同时关注一下设计模式的内容，不必强求自己能够完全掌握各种细节，往前走吧。<br />
&nbsp;掌握一种编程工具，比如说Eclipse。<br />
&nbsp;数据库，可以选择使用Oracle或者MySQL开始。<br />
&nbsp;JDBC，用Java连接数据库。<br />
&nbsp;可以选择在这个地方切入Hibernate，也可以选择在Struts之后。 <br />
&nbsp;HTML CSS JavaScript，这些东西是做web项目必需的内容。<br />
&nbsp;Servlet JSP，服务器端必需。<br />
&nbsp;XML AJAX，新的流行趋势不能不了解。 <br />
&nbsp;作一些小项目吧。比如BBS、留言系统、学籍管理、商城等等，随便着一些业务逻辑比较简单的来做一做。<br />
&nbsp;Struts，MVC的典型应用<br />
&nbsp;Hibernate，OR Mapping的典范之作。<br />
&nbsp;Spring IOC + AOP， 面向对象 ＋ 面向切面，完善的旅程。<br />
&nbsp;把以前自己的小项目加入Struts、Spring、Hibernate的元素吧。<br />
&nbsp;去研究各种商业项目的业务逻辑吧，才能在你的简历中加入浓重的一笔。<br />
&nbsp;EJB3.0，java在走了很多弯路后的回归之作，值得研究。<br />
&nbsp;SOA，业界铁定的未来趋势，要紧紧跟随。<br />
&nbsp;<br />
&nbsp;在后面，我会告诉你每一步的学习方法和学习重点。<br />
&nbsp;<br />
&nbsp;JAVA自学之路 三:要动手<br />
&nbsp;<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_3.html] 无论如何，请坚持不懈的动手实验！<br />
&nbsp;<br />
&nbsp;学习Java要动手，仅仅是看和听是不能够学好编程的。<br />
&nbsp;总有同学来信问我们这样的问题，说:"老师我看了视频了(下载：http://www.bjsxt.com/download.html)，可是怎么一动手就没有任何思路呢?"<br />
&nbsp;对此，我一般都会说不要着急，如果你只是看了视频就想行云流水的话，那老师这些年的锻炼真是白费了，这么多年的苦练才能略有些行云流水的感觉，你一朝一夕就想自己能够达到，不是太奢侈了吗<br />
&nbsp;<br />
&nbsp;作为编程的过来人想一下，当年自己学编程的时候是什么时候有思路的呢？至少也是照猫画虎画了一段时间之后吧，我本人是在某一个领域画虎画了上万行代码的时候才慢慢有自己思路的。就像写作文，要有自己思路总是一般来说要经过几个阶段，首先学习词汇，然后学习造句，然后大量阅读别人的文章，自己模仿着写一些，逐渐的经验积累，才能形成自己的思路。学编程，恐怕也得慢慢的来吧，只是看一看、听一听视频，是不足以学好编程的。<br />
&nbsp;<br />
&nbsp;所以，动手吧，跟着做，一行一行的跟着敲，一个项目敲完了，比如坦克，再试着加一些自己的功能，按照自己的思路敲一些代码，收获远比干听大的多。<br />
&nbsp;如果遇到，暂时对于一些思路不能理解的同学，我一般都会劝告说，动手写，先写代码，量变会引起质变的。而这种质变的确发生过不少次。<br />
&nbsp;提醒一句，要理解代码思路之后再跟着敲 ，背着敲，千万不要左边摆着别人的程序，右边自己一个一个子母的写，这就不再是程序员了，成了打字员了。<br />
&nbsp;<br />
&nbsp;纸上得来终觉浅，所以： <br />
&nbsp;别问那么多，别想那么多，动手写吧。<br />
&nbsp;<br />
&nbsp;JAVA自学之路 四:要事为先<br />
&nbsp;<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_4.html] 对待人生的任何事情都要：抓大放小，要事为先<br />
&nbsp;<br />
&nbsp;对于一个以前从来没有接触过java的人，java无疑是庞大的，似乎每个领域都可以拓展开来都是一片开阔地，每一个领域要想深入接触到每一个细节所耗费的精力都是巨大的。这个时候大家都胸怀壮志，两眼发光的盯着每一个崭新的知识点，遇见了任何一个知识点都恨不得抠的清清楚楚，明明白白。<br />
&nbsp;<br />
&nbsp;难道这有什么不对吗？<br />
&nbsp;我的意见是，没什么大毛病，但是学习效率太低了！<br />
&nbsp;我们推荐的学习方式是，抓大放小，要事为先。<br />
&nbsp;<br />
&nbsp;比如说学习J2SE的时候，学到GUI这一章，有的同学认为，既然学到这儿了，我们去把SWING细细的了解一遍吧；还有的同学，遇到了在Linux下的Shell编程，就恨不得把Shell先学成专家才肯，或者是才敢，继续往下学习；有没有过这样的感觉，一本书的上册没有学好，觉着下册心里也没底儿，甚至非要把上册复习一遍才敢继续学习。<br />
&nbsp;如果你也是这样，要去看看心理医生啦，没准儿会有洁癖的毛病。<br />
&nbsp;任何事情都要追求完美才敢继续往后进行，是一种性格缺陷<br />
&nbsp;<br />
&nbsp;大胆的放弃一些东西吧，有失才有得，把自己有限的、宝贵的精力用在对于就业直接相关的地方，这才是最有效率的学习方式！等你参加工作，有了可持续发展的事业动力和经济基础，有时间有精力闲的没事儿干的时候，再去研究那些其它吧。<br />
&nbsp;<br />
&nbsp;曾经有一个故事，说得是产能和产量的关系。<br />
&nbsp;一个人喜欢读书，读了一辈子，无所不通，这时候要做任何工作都可以，他的产能到了极致，但是，他老了，即便每天产出大量的东西也不能维持多久了，一辈子的产量并没有多少。<br />
&nbsp;另一个人直接工作，忙，天天在机器旁日复一日，做了一辈子，没时间学习和进修，可以想象，产量能有多大呢。<br />
&nbsp;人的一生，要锻炼产能，也要及时产出，引擎要转，也要停下来加油，这两者平衡的越好，你的贡献和产量就会越大。如果钻研的东西和产能目标（或者说近期的产能目标）无关的话，要舍得放手。<br />
&nbsp;<br />
&nbsp;所以，对于SWING，暂时先扔在一边吧。<br />
&nbsp;对于shell，对于各种协议过于详细的细节，对于喜欢的游戏编程，对于javascript各种华而不实的效果，都暂时和它们分别吧。<br />
&nbsp;一切和我们的直接工作目标关联不大的东西，扔在一边或者弄清楚到足够支持下一步的学习就可以了。<br />
&nbsp;<br />
&nbsp;那这样岂不是妨碍我成为通晓各种细节的高手了吗？<br />
&nbsp;我一向不认为一个人掌握了很多很多知识点的细节就是高手了，一个人如果告诉你，回字有四种写法，你会认为他是高手吗？ 毫不客气的说，现在我们所教授的所有知识细节在网上或书中都可以找到，只要你肯花时间花精力去动手试，去钻研，没有什么不能掌握的。struts、spring你能掌握吗？当然能！但是如果把时间花在spring的各种细节的研究上，花在研究中国企业应用不广泛地的spring mvc上，这个精力就太浪费了，而且学习的积极性会受到打击，谁愿意整天泡在细节的蜘蛛网中挣扎不出来呢？谁愿意天天经历风雨却总是不能见到彩虹呢？<br />
&nbsp;<br />
&nbsp;盖房子，要先建骨架，再谈修饰。<br />
&nbsp;画山水，要先画结构，再谈润色。<br />
&nbsp;认识一台结构复杂的机器，应该首先认清楚脉络，然后再逐步认识每一个关节。<br />
&nbsp;为了应付从小学到大学的考试，我们背了各种各样的不应该提前掌握的细节，同时也养成了见到细节就抠的学习习惯。而现在，是到改改的时候了。<br />
&nbsp;<br />
&nbsp;请在合适的时间，做合适的事情吧。<br />
&nbsp;把时间和精力花在作项目上面，花在写作品以及锻炼解决问题的能力上面吧，这是迈向高手的正确的而且快速的方向。 <br />
&nbsp;<br />
&nbsp;我一直不认为一个课程提供了很多很多的细节就是优秀的价值高的课程了，掌握必要的细节，这个不含糊，至于其他，或者通过视频给出（这样可以给出更多的细节，但是不占上课时间，课上只讲重要的、必要的细节知识），或者在掌握了自学的能力后自己能够查出，这才是正途。<br />
&nbsp;<br />
&nbsp;当你看书到某个地方暂时不理解的时候的，暂时放手吧，追求一些行云流水、自然而然的境界吧，只是不要停下前进的脚步，不要被大路旁边的支根末节干扰了你前进的行程，项目，真实的项目，这才是目的，就在不远的前方。<br />
&nbsp;陶渊明读书，叫做&#8220;不求甚解&#8221;，但他是大诗人。<br />
&nbsp;诸葛亮读书，总是&#8220;观其大略&#8221;，但他是大政治家。<br />
&nbsp;作研究的，是在确定了方向之后才详细的研究深入的东西。<br />
&nbsp;到了庐山，脉络形状扔在一边，盯着一棵棵小草、一粒粒石子的看，怎么样才能识得&#8220;真面目&#8221;？ <br />
&nbsp;作为应用型的人才，是研究回字的n种写法还是抓紧时间向着主要应用的方向努力，请自己作出抉择。<br />
&nbsp;<br />
&nbsp;以项目驱动自己的学习吧，当把握了技术的脉络之后再去补充细节的研究，是正途。<br />
&nbsp;<br />
&nbsp;这辈子就不研究其他的方向了吗？<br />
&nbsp;当然要研究！但是在将来合适的时间再说吧。<br />
&nbsp;所以，抓大放小，要事为先！<br />
&nbsp;那么，在JAVA的这些课程中，哪些才是大，才是要事呢？请继续读下去。<br />
&nbsp;<br />
&nbsp;JAVA自学之路 五:问题解决之道<br />
&nbsp;<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_3.html] 既然是学习，就不可能不遇到问题。<br />
&nbsp;既然是自学，就没有方便的和老师探讨的机会。<br />
&nbsp;那么，遇到问题之后，环境配不通，程序调不过，运行不正常，遇见这些恼人的问题的时候，该怎么办呢？<br />
&nbsp;<br />
&nbsp;首先我要恭喜你，遇见问题，意味着你又有涨经验的机会了，每解决一个问题，你的JAVA经验值就应该上升几百点，问题遇到的越多，知识提升的越快。<br />
&nbsp;<br />
&nbsp;但是总是解决不了也是很恼人的，怎么办呢？<br />
&nbsp;我一般要求我们的学生都是这样来进行的。<br />
&nbsp;当你遇到一个问题的时候：<br />
&nbsp;1：要仔细的观察错误的现象，是的，要仔细<br />
&nbsp;有不少同学的手非常快，在编译一个程序的时候，报了一大堆的错误，扫了一眼之后就开始盯着代码一行一行的找，看清什么错误了吗？没有！<br />
&nbsp;有的时候安装软件出问题了，一个对话框弹出来说出错了，马上举手问老师：&#8220;不得了了，出错了，出错了&#8221;。<br />
&nbsp;&#8220;什么错误？&#8221;<br />
&nbsp;&#8220;还没看呢？&#8221;<br />
&nbsp;这都是典型的不上心的方法！请记住，学习编程并不是一件很容易的事情，自己首先要重视，要用心才可以。<br />
&nbsp;在开发中，仔细观察出错信息，或者运行不正常的信息，是你要做的第一件事。<br />
&nbsp;读清楚了，才能在以后的步骤中有的放矢，哭了半天，总要知道哭的是谁才成。<br />
&nbsp;这里又分三种情况：<br />
&nbsp;&nbsp;&nbsp; A:错误信息读懂了，那么请进入2步：要仔细思考问题会出在哪些环节<br />
&nbsp;&nbsp;&nbsp; B:没读懂，愣是一点没看懂，进入第4步吧：google<br />
&nbsp;&nbsp;&nbsp; C:读了个半懂，有些眉目但是不太能确定，第2步和第4步结合着来。<br />
&nbsp;<br />
&nbsp;2：要仔细思考问题会出在哪些环节（重要）<br />
&nbsp;当你读懂了一个问题之后，要好好的思考这个问题可能会在哪些环节上出错。<br />
&nbsp;<br />
&nbsp;一辆汽车从总成线上下来，车门子关不上！<br />
&nbsp;哪错了？你怎么查？<br />
&nbsp;当然是顺着生产线一站一站的查下来。<br />
&nbsp;程序也是一样的，也是一系列语句完成后产生的结果。<br />
&nbsp;写一个网络程序，总是发现服务器端打印不出接收的数据，有几个环节会出错？<br />
&nbsp;仔细分析这个现象的环节：<br />
&nbsp;客户端产生数据-&gt;按&#8220;发送&#8221;按钮-&gt;发送到服务器-&gt;服务器接收到后打印<br />
&nbsp;这几个环节都有可能会出错：<br />
&nbsp;有可能客户端根本就没产生数据，有可能发送按钮按下去后根本就没发出去，或者发出去的不是你产生的东西，或者根本就没连接网络，或者发送出去服务器没有接收到，或者接收到之前就打印了等等等等。<br />
&nbsp;<br />
&nbsp;学着去这样仔细的分析程序的环节和这些环节可能会产生的问题，你的经验值定然会大幅度快速的提升，这样做很累人，但是一件事情如果做下来一点都不累的话，这个东西还有价值吗？<br />
&nbsp;<br />
&nbsp;在网页A输入了一个人的名字，提交到B，首先存储到数据库，然后再读出来，发现乱码！怎么办？<br />
&nbsp;当然是分析环节：<br />
&nbsp;客户输入-&gt;HTTP发送-&gt;B接收-&gt;存储到数据库-&gt;读出-&gt;展现到网页<br />
&nbsp;每个环节都可能出问题，怎么才能知道哪里出的问题？继续往下读。<br />
&nbsp;<br />
&nbsp;3：如何定位错误（重要）<br />
&nbsp;分析清楚有哪些环节之后，下一步就是定位到底什么环节出错了。<br />
&nbsp;定位有以下三种办法：<br />
&nbsp;A 打印输出，比如java的System.out.println()，比如js的alert()，这种办法常用，必须掌握<br />
&nbsp;B Debug，可以参考我们的视频《坦克大战》，详细讲了Eclipse的调试。<br />
&nbsp;C 删掉一部分调试一部分，也就是去掉一部分的功能，做简化，然后调试剩下的功能，JSP和JavaScript常用。可以参考我们的视频《BBS》等<br />
&nbsp;这些我说的比较简单，详细了解的话请关注以下我们的视频吧，在近期会逐步的将一些知识点的视频 进行免费的公布，http://www.bjsxt.com/download.html<br />
&nbsp;<br />
&nbsp;4：如果还不行，google吧<br />
&nbsp;还查不出来？恭喜你，你遇到的错误是值得认真对待的错误，是会影响你学习生涯的错误，问一下google或者百度吧。照着下面的方法查查看。<br />
&nbsp;<br />
&nbsp;一般来讲，搜索引擎可以搜到各种知识点，我曾经跟同学们开玩笑说：&#8220;学会了怎么google或者baidu，其实没必要跟老师学了，自己全都搞懂了，尚学堂是没必要来的。&#8221;当然，只是玩笑，培训的作用有三个：<br />
&nbsp;A：系统化知识<br />
&nbsp;B：真实项目锻炼经验<br />
&nbsp;C：少走弯路，节省时间<br />
&nbsp;不知不觉开始做广告了，请原谅，处其位谋其事，总得为尚学堂说点什么：）<br />
&nbsp;<br />
&nbsp;言归正传，如何查搜索引擎？<br />
&nbsp;先精后粗，首先先进行尽量精确的查找，比如一个错误，SocketException，你怀疑它是在connect()方法出的问题，那么当然是选这样的关键词java connect SocketException<br />
&nbsp;<br />
&nbsp;先中后英，本着以解决问题为主的想法，练习英文还是先放在一边吧，首先应该在中文网页中查询，还不行的话，搜索英文的吧，最近的尚学堂课程中会带大家阅读英文的书籍。有很多东西就像一层窗户纸，远看灰蒙蒙怪唬人的，你壮着胆子一捅，它就破了。阅读英文的书籍就是如此，不是想象中的那么困难：）宁可在沙场上战死，也不能被吓死不是吗：）<br />
&nbsp;<br />
&nbsp;信息筛选，搜索出来的结果不见得能够完全匹配，建议大家多阅读前几页的搜索结果，多打开几个网页看看，不过，我的经验是超过3页一般就没意义了，所以超过3页还没有找到合适的答案，或许应该调整一下关键词，或者放粗整个搜索的结果了。<br />
&nbsp;<br />
&nbsp;经常的进行知识难点的查询，如果一个问题牵扯的面比较广，就干脆到网上搜索一些相关的专题，比如&#8220;java 乱码 mysql&#8221; &#8220;oracle 创建用户&#8221;等等，如果有必要，不要犯懒，勤动手写一些小小的测试程序，来弄明白知识点的细节。这也是涨知识的重要的途径。<br />
&nbsp;<br />
&nbsp;5：什么？还不行？那么就BBS吧<br />
&nbsp;如果实在还不行，就到BBS上面问一问高手吧。<br />
&nbsp;到哪个BBS上？<br />
&nbsp;google或者百度不就行了么：）关键词&#8220;java论坛&#8221;&#8220;java bbs&#8221;<br />
&nbsp;<br />
&nbsp;然后在搜索结果里好好的看看那些活动频繁的论坛，以后就是你经常光顾的地方了。http://community.csdn.net/就很不错。<br />
&nbsp;<br />
&nbsp;向别人提问是非常需要技巧的！<br />
&nbsp;曾经有人问我这样的问题：&#8220;请问如何才能学好java呢？&#8221;<br />
&nbsp;这个要求太泛泛了。 <br />
&nbsp;还有人给我一段代码甚至jar包也寄过来，然后说老师的我的代码中有个错误您帮我查查：（<br />
&nbsp;我没有办法去花大量的时间建立环境去调试一个还不知道存在不存在的错误！<br />
&nbsp;还有人在BBS上问这样的问题：&#8220;是否有人能帮我完成一个完整聊天的程序？请帮我写一个登陆模块吧！&#8221;<br />
&nbsp;这个要求有些过分了，有人帮你做是你的运气，没有人帮你是正常反应。<br />
&nbsp;<br />
&nbsp;向别人提问，应该首先确定你已经做了自己应该做的事，简单说是我前面列举的1，2，3，4步你都作过了，然后再求助于人。不要没有经过认真思考就草率的向别人提问，自己也不会有长足进步的。<br />
&nbsp;那我该怎么样向别人提问呢？<br />
&nbsp;在google或百度搜索《提问的智慧》，你会找到答案。<br />
&nbsp;在这里我给出一个链接http://community.csdn.net/IndexPage/SmartQuestion.aspx，磨刀不误砍柴功，先花点时间去阅读一下吧。<br />
&nbsp;<br />
&nbsp;得到别人的回答，要懂得感恩。<br />
&nbsp;不需要去写信感谢，不需要支付费用，不需要那些花言巧语，做到下面这一点就够了：<br />
&nbsp;当你逐步成为高手的时候，要回答别人在论坛上提出的问题，有时间有精力的前提之下！<br />
&nbsp;<br />
&nbsp;6：还解决不了？问老师吧，这个只能是在你参加了培训的前提下了。<br />
&nbsp;7：还解决不了？天哪，是不是思路从根上就搞错了？写信给我，让我也学习一下，共同进步吧。mashibing2004@sina.com<br />
&nbsp;<br />
&nbsp;JAVA自学之路 六:项目的自学<br />
&nbsp;<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_6.html] 现在就业竞争的激烈程度已经远远高于当年了，记得我当年毕业时，一个会编程的毕业生站到台上，大声问道：&#8220;我会ASP，月薪5000有没有人要？&#8221; 台下的企业马上哗的举起一大片手："我要我要 !"<br />
&nbsp;那时 没有任何项目经验也会有人提供学习的机会：）<br />
&nbsp;这种好日子恐怕一去不复返了（有些夸张，但无疑当时找一份不错的工作是比现在要容易的多）<br />
&nbsp;<br />
&nbsp;而现在，即便是各种必要的知识你掌握的差不多了，但还有一座大山横在你的面前，那就是－<br />
&nbsp;项目经验。<br />
&nbsp;<br />
&nbsp;有经验的程序员都知道，学习编程的最有效率的方式，恐怕就是把你扔到一个项目组，连滚带爬的做下一两个项目来，你马上会发现所有的知识点全都连到一起了，不再是分散的，而是形成一个整体了。那种感觉是仅仅深入钻研知识点而不写真实项目的人所不能体会的。一个项目就是一根绳子可以把大片的知识串到一起。<br />
&nbsp;<br />
&nbsp;如果想锻炼实际开发的能力而不仅仅是背诵或者了解一些知识点，如果想成为真正的好手而不仅仅是背诵&#8220;回&#8221;字有几种写法，那么，作项目吧！<br />
&nbsp;<br />
&nbsp;目前，各种编程的知识点变得越来越容易掌握，按照《JAVA自学之路 五：问题解决知道》中的各种办法也可以逐步积累自己知识的广度和深度，那现在什么才能够体现水平的不同？当然是项目经验。<br />
&nbsp;<br />
&nbsp;目前，尚学堂的课程已经超越了知识点的研究和罗列，我们将在未来的时间里逐步公布各个知识点的视频，包括SSH、EJB等，这样做有两个好处：首先自学的同学可以免费得到原来商业培训的内容，这样起码可以节省一些时间，省一些力气。其次尚学堂自己可以更加专注于项目上。<br />
&nbsp;<br />
&nbsp;目前尚学堂的项目写作占了课程50%左右的比重，尚学堂的项目也早已经超越了简单的MIS系统的概念，逐步的成为综合了搜索引擎、工作流、SCA/SDO、Linux/UNIX、大型数据库系统、设计模式、架构模式、负载均衡等各种深层应用的综合大型项目并且采用手把手式的教学方法，做的更加的深入和细致，从现在看效果相当好，最近142班的就业就完全证明了这一点（了解142的就业情况），我们的计划是最近逐步将项目比重提升到70%以上，相信效果会更好。<br />
&nbsp;签于公司的规定，我们并不能将所有的项目实战都录制成视频来公布，但是已经公布的项目实战也是非常的有价值的：（http://www.bjsxt.com/download.html)<br />
&nbsp;1：Chat &amp; Tank系列 <br />
&nbsp;2：BBS<br />
&nbsp;3：Shopping（近期公布）<br />
&nbsp;<br />
&nbsp;那么如果自学我们应该怎么样才能学习项目的开发呢？<br />
&nbsp;一个比较有效的办法是，可以在现有项目的基础上做的更深入一些，比如在你按照视频完成了BBS之后，可以增加一些其他的功能，例如注册/积分/精华/搜索/贴图等等，在完成了Shopping之后，可以增加一些评论/排行/统计/存货等等方面的业务逻辑，尝试用自己的技术将他们作出来，这样既积攒了项目经验，又记住了知识点。<br />
&nbsp;<br />
&nbsp;那么如何才能确定我要写什么样的业务逻辑呢？<br />
&nbsp;应该讲这对于一个初学者是非常困难的，一些简单的系统，比如说BBS、Shopping、图书管理等等，它们的业务逻辑很容易确定，去浏览和参考一些现成系统的功能，很容易就能了解了。但是对于商用的大型系统，光是了解业务逻辑本身就会花费大量的精力，如果有时间有精力有财力的话，还是建议考虑一下我们的培训吧，这样经验的积累和薪水的提升会更快，从以前的统计数据看非常容易就可以回收这笔投资（替尚学堂的广告，必须得写，请见谅，但保证真实）。<br />
&nbsp;<br />
&nbsp;如果条件不允许，那么就按照上面的方法来学习项目吧，不要因为暂时不能接触更大型更深入的项目而气馁，记住：机会总是青睐有准备的头脑，努力吧。<br />
&nbsp;<br />
&nbsp;JAVA自学之路 七:路线图明细<br />
&nbsp;<br />
&nbsp;[转载请注明出处:http://www.bjsxt.com/zixue/zixuezhilu_7.html] 下面给出第二节《JAVA自学路线图》[http://www.bjsxt.com/zixue/zixuezhilu_2.html] 中知识点的明细：<br />
&nbsp;<br />
&nbsp;注：<br />
&nbsp;1：下面大多数的知识点我们已经公布了视频或者会近期公布（几个月之内），请大家关注一下这个网址http://www.bjsxt.com/download.html，可以按照该页面的提示，用电驴进行下载<br />
&nbsp;2：这里是为方便大家自学给出的列表，请大家不要同尚学堂的课程画等号，下面的内容要比实际授课简单很多，另外很多知识是融汇在项目开发中的，适合面授，不适合自学。<br />
&nbsp;<br />
&nbsp;一：J2SE <br />
&nbsp;面向对象－封装、继承、多态<br />
&nbsp;内存的分析<br />
&nbsp;递归<br />
&nbsp;集合类、泛型、自动打包与解包、Annotation <br />
&nbsp;IO <br />
&nbsp;多线程、线程同步 <br />
&nbsp;TCP/UDP <br />
&nbsp;AWT、事件模型、匿名类 <br />
&nbsp;正则表达式<br />
&nbsp;反射机制<br />
&nbsp;<br />
&nbsp;2：数据库（Oracle或者MySQL）<br />
&nbsp;SQL语句<br />
&nbsp;多表连接，内外连接， 子查询等<br />
&nbsp;管理表、视图、索引、序列、约束等 <br />
&nbsp;树状结构存储<br />
&nbsp;存储过程、触发器 <br />
&nbsp;数据库设计三范式、<br />
&nbsp;<br />
&nbsp;3：JDBC<br />
&nbsp;JDBC基础<br />
&nbsp;连接池 <br />
&nbsp;树状结构存储与展现 <br />
&nbsp;DataSource &amp; RowSet <br />
&nbsp;JDBC连接Oracle及MySQL<br />
&nbsp;<br />
&nbsp;4：HTML_CSS_JAVASCRIPT<br />
&nbsp;html、css、javascript基础语法<br />
&nbsp;JavaScript Form判断 <br />
&nbsp;Dom编程基础（事件处理等） <br />
&nbsp;JS常用效果如TreeView、下拉联动等 <br />
&nbsp;JS学习方法 <br />
&nbsp;JS调试方法 <br />
&nbsp;DreamWeaver初步（建立HTML、Table、Form、CSS）等<br />
&nbsp;<br />
&nbsp;5：Servlet &amp; JSP<br />
&nbsp;<br />
&nbsp;tomcat基础 <br />
&nbsp;servlet基础 <br />
&nbsp;web.xml配置基础 <br />
&nbsp;web application的结构 <br />
&nbsp;servlet生命周期 <br />
&nbsp;request response等常用方法 <br />
&nbsp;ServletContext类 <br />
&nbsp;HTTP协议基础（GET POST） <br />
&nbsp;Cookie <br />
&nbsp;Session <br />
&nbsp;Application <br />
&nbsp;<br />
&nbsp;JSP的几种语法（包括JSTL等）注意在项目中练习，不要拘泥于语法细节而裹步不前。<br />
&nbsp;<br />
&nbsp;6：Struts<br />
&nbsp;多层架构理论 <br />
&nbsp;Model 1 and Model 2 <br />
&nbsp;Struts基本概念 <br />
&nbsp;MVC<br />
&nbsp;Action与业务逻辑类的关系 <br />
&nbsp;在Struts与JSP之间传递数据 <br />
&nbsp;Struts处理流程（控制流） <br />
&nbsp;Struts TagLib（了解常用的） <br />
&nbsp;JSTL<br />
&nbsp;ActionForm <br />
&nbsp;字段收集 <br />
&nbsp;上传文件 <br />
&nbsp;类型转换 <br />
&nbsp;DTO <br />
&nbsp;动态Action Form <br />
&nbsp;验证框架<br />
&nbsp;ActionForward 转发与重定向 <br />
&nbsp;动态生成ActionForward <br />
&nbsp;全局与局部的ActionForward <br />
&nbsp;Action Forward Scope<br />
&nbsp;UnknownActionMapping <br />
&nbsp;Action的线程安全 <br />
&nbsp;I18N <br />
&nbsp;如何切换语言环境 <br />
&nbsp;Struts异常处理机制 程序处理 自动处理 自定义异常处理器 <br />
&nbsp;Struts的多模块配置<br />
&nbsp;<br />
&nbsp;7：XML<br />
&nbsp;（XML/XSL、XSLT/DTD、SCHEMA等基础的概念、关于Java的编程可以暂时扔在一边）<br />
&nbsp;<br />
&nbsp;8：Hibernate<br />
&nbsp;OR Mapping原理 <br />
&nbsp;Hibernate基础开发步骤 <br />
&nbsp;Hibernate基本接口（重点Session） <br />
&nbsp;普通属性映射 <br />
&nbsp;关联关系映射 <br />
&nbsp;Native SQL <br />
&nbsp;inverse lazy cascade <br />
&nbsp;继承关系映射 <br />
&nbsp;HQL <br />
&nbsp;性能优化 一级缓存 二级缓存 查询缓存 <br />
&nbsp;事务与并发 悲观锁、乐观锁 <br />
&nbsp;OpenSessionInView <br />
&nbsp;CurrentSession <br />
&nbsp;（至于JTA、联合主键、自然主键、动态主键、Any类型 Creteria Queries Intercepter and Event 自定义类型等，可以暂时扔在一边）<br />
&nbsp;<br />
&nbsp;9：Spring<br />
&nbsp;IOC/DI <br />
&nbsp;Spring配置<br />
&nbsp;Spring架构 <br />
&nbsp;AOP及Spring AOP <br />
&nbsp;声明式事务（AOP） <br />
&nbsp;Spring + Hibernate Spring支持Web <br />
&nbsp;Scope <br />
&nbsp;（其他的Spring模块对于自学来说可以暂时扔在一边）<br />
&nbsp;<br />
&nbsp;10：EJB3.0<br />
&nbsp;J2EE架构基础（JTA JMS等） <br />
&nbsp;EJB基础（地位及基本理论、分类等） <br />
&nbsp;Annotation <br />
&nbsp;Ant编译与部署EJB <br />
&nbsp;Session Bean <br />
&nbsp;EJB的依赖注入 <br />
&nbsp;Persistence API <br />
&nbsp;（可以用JBoss学习EJB3.0）<br />
&nbsp;<br />
&nbsp;11:至于SOA，对于自学的同学来说，暂时不用特别关注。<br />
&nbsp;<br />
&nbsp;梳理一下，你就会发现东西不是想象中的那么多呀！<br />
&nbsp;<br />
&nbsp;建议大家优先学习我们公布的视频，然后再去找参考书，因为这个时候就能分辨出来哪些书适合你了。<br />
&nbsp;<br />
&nbsp;那么，如何才能找到好书呢？一个简单的办法，在卖书的网站上，比如http://www.china-pub.com/，搜索你想了解的知识点比如"javascript"，按销售排行，排在前几位的，应该就是不错的，记下书名，到书店阅读几章，合适你的就是好书了。没钱买？简单！还有什么google + 电驴找不到的资料吗：）</p>
<p><br />
本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/tianxudong2004/archive/2009/06/12/4259513.aspx</p>
<img src ="http://www.blogjava.net/chenjiajin/aggbug/282357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chenjiajin/" target="_blank">London2012</a> 2009-06-15 15:02 <a href="http://www.blogjava.net/chenjiajin/archive/2009/06/15/282357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>