<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>flysky</title>
    <description></description>
    <link>http://flysky.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Group by ,Having, Aggregate functions and top 10</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/87433" style="color:red;">http://flysky.javaeye.com/blog/87433</a>&nbsp;
          发表时间: 2007年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.	今天实验的收获很大，最重要的就是Mr dennis帮我指出了我的一个严重错误！the serious error about querying the ten items having the least total quantities.<br />I didn’t understand the use of “group by” and “having” until now! They are just and mainly used for aggregate functions.<br />2.  http://www.w3schools.com/sql/sql_groupby.asp<br />SQL GROUP BY and HAVING<br />________________________________________<br />Aggregate functions (like SUM) often need an added GROUP BY functionality.<br />________________________________________<br />GROUP BY...<br />GROUP BY... was added to SQL because aggregate functions (like SUM) return the aggregate of all column values every time they are called, and without the GROUP BY function it was impossible to find the sum for each individual group of column values. <br />The syntax for the GROUP BY function is:<br />SELECT column,SUM(column) FROM table GROUP BY column<br /><br />________________________________________<br />GROUP BY Example<br />This "Sales" Table:<br />Company	Amount<br />W3Schools	5500<br />IBM	4500<br />W3Schools	7100<br />And This SQL:<br />SELECT Company, SUM(Amount) FROM Sales<br />Returns this result:<br />Company	SUM(Amount)<br />W3Schools	17100<br />IBM	17100<br />W3Schools	17100<br />The above code is invalid because the column returned is not part of an aggregate. A GROUP BY clause will solve this problem: <br />SELECT Company,SUM(Amount) FROM Sales<br />GROUP BY Company<br />Returns this result:<br />Company	SUM(Amount)<br />W3Schools	12600<br />IBM	4500<br /><br />________________________________________<br />HAVING...<br />HAVING... was added to SQL because the WHERE keyword could not be used against aggregate functions (like SUM), and without HAVING... it would be impossible to test for result conditions. <br />The syntax for the HAVING function is:<br />SELECT column,SUM(column) FROM table<br />GROUP BY column<br />HAVING SUM(column) condition value<br />This "Sales" Table:<br />Company	Amount<br />W3Schools	5500<br />IBM	4500<br />W3Schools	7100<br />This SQL:<br />SELECT Company,SUM(Amount) FROM Sales<br />GROUP BY Company<br />HAVING SUM(Amount)>10000<br />Returns this result<br />Company	SUM(Amount)<br />W3Schools	12600<br /><br />2.	http://mycodeblog.blogspot.com/2006/11/how-to-select-top-results-in-group-by.html<br />How to Select Top Results in a Group By to use Microsoft SQL Server:<br />SET ROWCOUNT 10<br />SELECT field1, field2, COUNT(*)<br />FROM table<br />GROUP BY field1, field2<br />ORDER BY COUNT(*) DESC<br /><br />3.	http://www.kekecn.com/blog/article.asp?id=146<br />Microsoft SQL Server<br />select top 3 e_name,e_wage from employee order by e_wage desc
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/87433#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 06 Jun 2007 18:56:56 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/87433</link>
        <guid>http://flysky.javaeye.com/blog/87433</guid>
      </item>
      <item>
        <title>谈谈目前自己对hibernate的了解</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/64481" style="color:red;">http://flysky.javaeye.com/blog/64481</a>&nbsp;
          发表时间: 2007年03月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          把简历交给tangyin后，突然感觉有点悬空，自己的项目经历中主要写Hibernate＋Spring＋JSF，但是突然意识到自己<br />对Hibernate好像是一遍空白。温习了一下，终于回忆起来了。<br /><br />Hibernate主要是使用OO思想存取数据库，根据数据库表自动映射对象，代码全部转为针对对象的操作，语义表达相比原来<br />的rs要强很多。Hibernate的关键是有针对数据库表的设计和编程转变为针对业务对象的设计和编程。<br /><br />但是Hibernate有一个缺陷，可能是由于要把数据库表映射为对象，使用Hibernate可能会出现严重的性能问题，速度很慢等情况。<br /><br />参考资料：<br /><br />大家来一起讨论如何通过Hibernate提高访问数据库的速度<br />http://www.jdon.com/jive/thread.jsp?forum=16&thread=28484<br /><br /> 最近本人正搞一个项目，项目中我们用到了struts1.2+hibernate3<br />由于关系复杂表和表之间的关系很多，在很多地方把lazy都设置false，所以导致数据一加载很慢，而且查询一条数据更是非常的慢，由于项目时间比较短，时间很紧，所以一直都在忙着实现功能，还没来的急进行优化<br />今天我设置下二级缓存 效果不大，我想肯定还有更好的方法，比如Hibernate.initialize 还有迫切连接等方法<br />请大家多给点意见，最好给一个详细的技术文章<br />谢谢大家~！<br /><br />re：<br /> 首先必须明白：性能问题完全取决于你的业务设计问题，而不是某个具体架构技术的性能。<br /><br />你的业务设计采取面向数据表分析，导致关系复杂表和表之间的关系很多，这是你的系统性能问题最本质原因，只有使用DDD重新分析你的系统，才从根本上改观。<br /><br />其他只是一些小修小打的微调，不能根本解决问题。<br /><br /> 如果不能掌握Domain Model的设计方式，使用ORM是比较艰难的。<br /><br />re：<br /> 很同意,有些人主动或被动把SQL搞得很复杂,这本身就背离了OR MAPPING的初衷,也背离了持久曾的实质.<br />好的DB设计不会有复杂的SQl代码,基本就是简单的CRUD语句,在它上层再用一层Service实现复杂的业务机制.当然,这必须在领域对象已经清晰的情况下.<br /><br />re：<br />使用Hibernate前提必须掌握领域建模的方法，也就是Evans DDD，至少了解类关联的意思和本质。<br /><br />我们以前很多程序员都是基于数据表编程的思路，现在使用了Hibernate这样的ORM，Hibernate替代了数据表，或者说；插在了数据表和程序员之间，程序员就看不见数据表了，程序员必须学会和Hibernate代表的对象打交道，如果还是念念不忘数据表，那么每次用Hibernate，总是要转个弯，就不自然而且不方便。<br /><br />换句话说：只有程序员真正掌握面向对象的分析设计和编程，才会觉得使用Hiberante等ORM工具是一个最简单的方式，否则，反而觉得数据表JDBC是一个简单的解决方式。<br /><br />所以，可以从是否善用Hibernate看出程序员的OO素质。虽然你的单位是电信大单位，但是OO作为一个与面向过程全新的革命性技术和思想，它是挑战和颠覆面向过程的思维的，而我们国内以前大学教育以及实践如Delphi/VB等等都是传统的面向过程思维，虽然他们做过大项目，经验丰富，但是也吃了很多苦头，只是朴素地直觉认为程序要灵活，但是没有上升为OO理论，因为掌握OO是对自己过去经验和习惯的挑战，是对自己的挑战，又有几个人做到，象你这样舒服的大单位，谁有没事折磨自己，挑战自己呢？<br /><br />re：<br />呵呵,我也是做电信项目的,看了一下,发表一下自己的观点,电信项目的数据量大,表的数目也比较多,业务逻辑也比较复杂,如果用oo设计,对象之间的关联比较多,而且比较复杂,所以load一条数据非常慢,另外,需求变更比较频繁,往往在项目过程进行中需要进行表的改动,面向对象有可能需要重新设计对象之间的关系,维护起来不方便,而且在数据查询优化方面也利用不到数据库的优势,导致查询数度比较慢,个人观点是对象分析可以帮助我们深入了解对象与对象之间的关系,也就是表与表之间的关联,但实际开发中可能就需要将对象关系降低,而且用户只关心他需要的数据,就是视图,我不否认oo的优势,但实际开发另当别论,不要因为oo而oo,另外提一下,上次公司有个项目用hib,差点死掉.......(说的不对别骂哦,呵呵^_^)<br /><br />re：<br /> 这个世界上的软件并不永远只有CRUD这种操作，统计/分析/报表等等同样是必不可少的，如果捆绑上hibernate，就如j10a所说，绝对会在性能上走向死亡。<br />通常我会在项目中同时使用hibernate和jdbc，当然，会有自己的封装。<br />单纯做ORM，我倒是觉得itabis是个更好的选择。<br /><br />re：<br /> 我很认同banq。之前，有3、4个项目使用hibernate。问题很多，一是项目组没有非常熟悉hibernate组员，二是我们对业务领域根本没有分析，基本上是沿袭老思路，建库，创表，编代码。需求在不断变更，问题越来越多。<br />现在，这个项目，我们在业务领域分析方面，做了一点小工作，并且借鉴spring的思路，多在行为定义，行为组装上下功夫，尽量解耦行为与数据、行为与数据关系。应该说，比原先有所进步。我相信，随着项目组对hibernate的深入，对OO的深入，对业务领域分析的深入，我们的路会越来越清晰。<br /><br />re：<br />我也很认同banq的观念，因为从数据表建模的思路转变到对象建模思路，我也有过这样的经历，以前设计系统时都是从数据库建模开始，这样的问题是如果你采用对象的方式编码的话，很多问题都出来了，结果项目的代码也被改动的的很多，而且维护也很麻烦。现在我如果从头设计一个系统，我往往先是业务对象建模，业务对象先运行起来，在用代理模式或装饰模式给业务对象增加防问数据库的能力。这样代码改动量虽然没见得减少，但改动的范围缩小了，控制在几个类之间，而且便于维护。<br /><br />re：<br /> 不得不承认，web2.0时代已经来临，这个强调性能、敏捷的时代，hibernate会死的更早。呼唤一个崭新的框架! OO很重要，但过于强调就是“女人的裹脚布”了，又臭又长！<br /><br />re：<br /> 其实，没有必要争论是JDBC，HIBERNATE哪个效率高，哪个好，同样的问题不同人的解决结果也未必一样，有些人用JDBC写的SQL访问数据库未必比HIBERNATE快，所以人是关键・<br />几个月前，一次经历：由于设计问题，使客户一次操作产生几千条SQL，这样明显是设计问题，后来采用工具+DEBUG，拦截宋庆龄，看看是什么地方产生的问题，最后找出问题，把几千条变为几条，性能提高越30倍。<br />最夸张的是有个同事发了HIBERNATE产出的SQL让我查错，竟然是几页WORD的SQL，我没有能力找错误，这问题在什么地方，在设计！<br />所以用HIBERNATE，你是不是准备好了，公司的技术储备是不是可以，是不是已经从数据分析转道对象，领域分析了，是否清楚如何设计合理的对象关系，所以HIBERNATE只是O/R工具，他需要分析设计先行的基础！<br /><br />re：<br />彭先生，说的非常用理，只有你采用面向对象思想分析系统，重构系统，才能使Hibernate体现的淋漓尽致，如果你的系统还是采用数据库方式驱动设计，而不采用DDD设计，再怎么优化还是有问题，原因何在，原因出在现在大部分系统有人还是没能走出数据库驱动方式开发系统阴影，还是用面向对象的语言而不是思想开发系统，从而使系统本质上不是面向对象的．因此还是建议重构吧．<br /><br />re：<br /> 我对hb不是很了解,正在学习中,简单说一下自己的想法:<br /><br />系统开发过程中,问题来自多方面，比如说用了hb,查询性能下降很多，<br />可能会是多中原因造成的，比如，开发人员熟悉hb的程度够不够，能不能对HQL语句进行优化；对hb的长处和短处是否理解，知道什么情况下，使用hb的缓存会提高性能；<br /><br />另外，还有设计的问题，对象的粒度是否合适，类和表怎样映射才更合理...<br /><br />总之一句话，你对hb理解到什么程度，写出的程序的性能也会不同！<br /><br />re：<br /> 你把lazy设成true就可以,当lazy为false的时候,数据抓取会抓出一棵树,所以会很慢.把lazy设成 true以后你可以根据自己具体需要来抓数据,具体可参考hibernate手册的fetch语句.
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/64481#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 Mar 2007 00:52:00 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/64481</link>
        <guid>http://flysky.javaeye.com/blog/64481</guid>
      </item>
      <item>
        <title>设计模式Singleton(zz)</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/64479" style="color:red;">http://flysky.javaeye.com/blog/64479</a>&nbsp;
          发表时间: 2007年03月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文1：http://www.68asp.com/Article/CJ/200409/853.html<br />原文2：http://www.jdon.com/designpatterns/singleton.htm<br /><br />原文1：<br />设计模式Singleton<br />副标题：<br />作者：本网收集 文章来源：本站收集 点击数：4996 更新时间：2004-9-28<br />    引言<br />   相信大多数拜读过"Gang Of Four"（Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides）的经典之作《Design Pattern》的同僚们，对这本书一定推崇有加。曾有人这么宣告："只有在读过《Design Pattern》后，我的编程水平才真正得到了质的飞跃。"<br />  <br />  那么，如何才能步入设计模式的殿堂？设计模式是资深程序员日积月累总结出来的一套可复用的、针对面向对象软件设计的解决方案，从这个意义上说，世界上存在无数多的设计模式，"Gang Of Four"总结的23种设计模式只是其中的23个精华。入手的关键就在于领会"设计模式"的思想，然后再将它们融会贯通、灵活应用到自己到开发过程中。<br />  <br />  <br />  --------------------------------------------------------------------------------<br />  <br />  Singleton模式<br />  Singleton可以说是《Design Pattern》中最简单也最实用的一个设计模式。那么，什么是Singleton？<br />  <br />   顾名思义，Singleton就是确保一个类只有唯一的一个实例。Singleton主要用于对象的创建，这意味着，如果某个类采用了Singleton 模式，则在这个类被创建后，它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton模式，最常见的比如我们希望整个应用程序中只有一个连接数据库的Connection实例；又比如要求一个应用程序中只存在某个用户数据结构的唯一实例。我们都可以通过应用Singleton模式达到目的。<br />  <br />  一眼看去，Singleton似乎有些像全局对象。但是实际上，并不能用全局对象代替Singleton模式，这是因为：其一，大量使用全局对象会使得程序质量降低，而且有些编程语言例如C#，根本就不支持全局变量。其二，全局对象的方法并不能阻止人们将一个类实例化多次：除了类的全局实例外，开发人员仍然可以通过类的构造函数创建类的多个局部实例。而Singleton模式则通过从根本上控制类的创建，将"保证只有一个实例 "这个任务交给了类本身，开发人员不可能再有其它途径得到类的多个实例。这一点是全局对象方法与Singleton模式的根本区别。<br />  <br />  <br />  --------------------------------------------------------------------------------<br />  <br />  Singleton模式的实现<br />  Singleton模式的实现基于两个要点：<br />  <br />  1）不直接用类的构造函数，而另外提供一个Public的静态方法来构造类的实例。通常这个方法取名为Instance。Public保证了它的全局可见性，静态方法保证了不会创建出多余的实例。<br />  <br />  2）将类的构造函数设为Private，即将构造函数"隐藏"起来，任何企图使用构造函数创建实例的方法都将报错。这样就阻止了开发人员绕过上面的Instance方法直接创建类的实例。<br />  <br />  通过以上两点就可以完全控制类的创建：无论有多少地方需要用到这个类，它们访问的都是类的唯一生成的那个实例。以下C＃代码展现了两种实现Singleton模式的方式，开发人员可以根据喜好任选其一。<br />  <br />  实现方式一：Singleton.cs<br />  <br />  using System;<br />  class SingletonDemo<br />  { private static SingletonDemo theSingleton = null;<br />   private SingletonDemo() {}<br />   public static SingletonDemo Instance()<br />   { if (null == theSingleton)<br />   {<br />   theSingleton = new SingletonDemo();<br />   }<br />   return theSingleton;<br />   }<br />   static void Main(string[] args)<br />   { SingletonDemo s1 = SingletonDemo.Instance();<br />   SingletonDemo s2 = SingletonDemo.Instance();<br />   if (s1.Equals(s2))<br />   { Console.WriteLine("see, only one instance!");<br />   }<br />   }<br />  }<br />  <br />  与之等价的另外一种实现方式是：Singleton.cs：<br />  <br />  using System;<br />  <br />  class SingletonDemo<br />  { private static SingletonDemo theSingleton = new SingletonDemo();<br />   private SingletonDemo() {}<br />   public static SingletonDemo Instance()<br />   { return theSingleton;<br />   }<br />   static void Main(string[] args)<br />   { SingletonDemo s1 = SingletonDemo.Instance();<br />   SingletonDemo s2 = SingletonDemo.Instance();<br />   if (s1.Equals(s2))<br />   { Console.WriteLine("see, only one instance!");<br />   }<br />   }<br />  }<br />  <br />  编译执行：<br />  <br />  Csc Singleton.cs<br />  <br />  得到运行结果：<br />  <br />  see, only one instance!<br />   <br /><br /><br />原文2：http://www.jdon.com/designpatterns/singleton.htm<br /><br />设计模式之Singleton(单态)<br /><br />板桥里人 http://www.jdon.com 2002/05/07<br /><br />模式实战书籍《Java实用系统开发指南》<br /><br />单态定义:<br />Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。<br /><br />在很多操作中，比如建立目录 数据库连接都需要这样的单线程操作。<br /><br />还有, singleton能够被状态化; 这样，多个单态类在一起就可以作为一个状态仓库一样向外提供服务，比如，你要论坛中的帖子计数器，每次浏览一次需要计数，单态类能否保持住这个计数，并且能synchronize的安全自动加1，如果你要把这个数字永久保存到数据库，你可以在不修改单态接口的情况下方便的做到。<br /><br />另外方面，Singleton也能够被无状态化。提供工具性质的功能，<br /><br />Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存，因为它限制了实例的个数，有利于Java垃圾回收（garbage collection）。<br /><br />我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。<br /><br />如何使用?<br />一般Singleton模式通常有几种形式:<br /><br />public class Singleton {<br /><br />　　private Singleton(){}<br /><br />　　//在自己内部定义自己一个实例，是不是很奇怪？<br />　　//注意这是private 只供内部调用<br /><br />　　private static Singleton instance = new Singleton();<br /><br />　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　<br />　　public static Singleton getInstance() {<br />　　　　return instance; 　　<br />　　 }<br />}<br /><br /> <br /><br />第二种形式:<br />public class Singleton {<br /><br />　　private static Singleton instance = null;<br /><br />　　public static synchronized Singleton getInstance() {<br /><br />　　//这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　 　<br />　　//使用时生成实例！<br />　　if (instance==null)<br />　　　　instance＝new Singleton();<br />　　return instance; 　　}<br /><br />}<br /><br /> <br /><br />使用Singleton.getInstance()可以访问单态类。<br /><br />上面第二中形式是lazy initialization，也就是说第一次调用时初始Singleton，以后就不用再生成了。<br /><br />注意到lazy initialization形式中的synchronized，这个synchronized很重要，如果没有synchronized，那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论，有兴趣者进一步研究。<br /><br />一般认为第一种形式要更加安全些。<br /><br />使用Singleton注意事项：<br />有时在某些情况下，使用Singleton并不能达到Singleton的目的，如有多个Singleton对象同时被不同的类装入器装载；在EJB这样的分布式系统中使用也要注意这种情况，因为EJB是跨服务器，跨JVM的。<br /><br />我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下：<br /><br />在Pet Store中ServiceLocator有两种，一个是EJB目录下；一个是WEB目录下，我们检查这两个ServiceLocator会发现内容差不多，都是提供EJB的查询定位服务，可是为什么要分开呢？仔细研究对这两种ServiceLocator才发现区别：在WEB中的 ServiceLocator的采取Singleton模式，ServiceLocator属于资源定位，理所当然应该使用Singleton模式。但是在EJB中，Singleton模式已经失去作用，所以ServiceLocator才分成两种，一种面向WEB服务的，一种是面向EJB服务的。<br /><br />Singleton模式看起来简单，使用方法也很方便，但是真正用好，是非常不容易，需要对Java的类 线程 内存等概念有相当的了解。<br /><br />总之：如果你的应用基于容器，那么Singleton模式少用或者不用，可以使用相关替代技术。<br /><br />进一步深入可参考：<br /><br />Double-checked locking and the Singleton pattern<br /><br />When is a singleton not a singleton?<br /><br />Singleton是邪恶的<br />(注：文章见http://www.jdon.com/jive/thread.jsp?forum=91&thread=17578；<br />singleton在多线程下会存在问题，比如出现死锁等。<br />)<br /><br />设计模式如何在具体项目中应用见《Java实用系统开发指南》
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/64479#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 Mar 2007 00:21:05 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/64479</link>
        <guid>http://flysky.javaeye.com/blog/64479</guid>
      </item>
      <item>
        <title>设计模式（15）－Facade Pattern(zz)</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/64478" style="color:red;">http://flysky.javaeye.com/blog/64478</a>&nbsp;
          发表时间: 2007年03月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文：http://www.cnblogs.com/zhenyulu/articles/55992.html<br /><br /><br />一、 门面（Facade）模式<br /><br />外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行，这就是门面模式。<br /><br />医院的例子<br /><br />用一个例子进行说明，如果把医院作为一个子系统，按照部门职能，这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道，就如同一个子系统的客户端与一个子系统的各个类打交道一样，不是一件容易的事情。<br /><br />首先病人必须先挂号，然后门诊。如果医生要求化验，病人必须首先划价，然后缴款，才能到化验部门做化验。化验后，再回到门诊室。<br /><br />解决这种不便的方法便是引进门面模式。可以设置一个接待员的位置，由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是门面模式的体现，病人只接触接待员，由接待员负责与医院的各个部门打交道。<br /><br />什么是门面模式<br /><br />门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。门面模式提供一个高层次的接口，使得子系统更易于使用。<br /><br />就如同医院的接待员一样，门面模式的门面类将客户端与子系统的内部复杂性分隔开，使得客户端只需要与门面对象打交道，而不需要与子系统内部的很多对象打交道。<br /><br />二、 门面模式的结构<br /><br />门面模式是对象的结构模式。门面模式没有一个一般化的类图描述，下图演示了一个门面模式的示意性对象图：<br /><br /> <br /><br />在这个对象图中，出现了两个角色：<br /><br />门面(Facade)角色：客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下，本角色会将所有从客户端发来的请求委派到相应的子系统去。<br /><br />子系统(subsystem)角色：可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类，而是一个类的集合。每一个子系统都可以被客户端直接调用，或者被门面角色调用。子系统并不知道门面的存在，对于子系统而言，门面仅仅是另外一个客户端而已。<br /><br />三、 门面模式的实现<br /><br />一个系统可以有几个门面类<br /><br />【GOF】的书中指出：在门面模式中，通常只需要一个门面类，并且此门面类只有一个实例，换言之它是一个单例类。当然这并不意味着在整个系统里只能有一个门面类，而仅仅是说对每一个子系统只有一个门面类。或者说，如果一个系统有好几个子系统的话，每一个子系统有一个门面类，整个系统可以有数个门面类。<br /><br />为子系统增加新行为<br /><br />初学者往往以为通过继承一个门面类便可在子系统中加入新的行为，这是错误的。门面模式的用意是为子系统提供一个集中化和简化的沟通管道，而不能向子系统加入新的行为。<br /><br />四、 在什么情况下使用门面模式<br /><br />    * 为一个复杂子系统提供一个简单接口<br />    * 提高子系统的独立性<br />    * 在层次化结构中，可以使用Facade模式定义系统中每一层的入口。<br /><br /><br />五、 一个例子<br /><br />我们考察一个保安系统的例子，以说明门面模式的功效。一个保安系统由两个录像机、三个电灯、一个遥感器和一个警报器组成。保安系统的操作人员需要经常将这些仪器启动和关闭。<br /><br />不使用门面模式的设计<br /><br />首先，在不使用门面模式的情况下，操作这个保安系统的操作员必须直接操作所有的这些部件。下图所示就是在不使用门面模式的情况下系统的设计图。<br /><br /> <br /><br /><br />可以看出，Client对象需要引用到所有的录像机(Camera)、电灯(Light)、感应器(Sensor)和警报器(Alarm)对象。代码如下：<br />using System;<br /><br />public class Camera<br />{<br />  public void TurnOn()<br />  {<br />    Console.WriteLine("Turning on the camera.");<br />  }<br /><br />  public void TurnOff()<br />  {<br />    Console.WriteLine("Turning off the camera.");<br />  }<br /><br />  public void Rotate(int degrees)<br />  {<br />    Console.WriteLine("Rotating the camera by {0} degrees.", degrees);<br />  }<br />}<br /><br />public class Light<br />{<br /><br />  public void TurnOff()<br />  {<br />    Console.WriteLine("Turning on the light.");<br />  }<br /><br />  public void TurnOn()<br />  {<br />    Console.WriteLine("Turning off the light.");<br />  }<br /><br />  public void ChangeBulb()<br />  {<br />    Console.WriteLine("changing the light-bulb.");<br />  }<br />}<br /><br />public class Sensor<br />{<br />  public void Activate()<br />  {<br />    Console.WriteLine("Activating the sensor.");<br />  }<br /><br />  public void Deactivate()<br />  {<br />    Console.WriteLine("Deactivating the sensor.");<br />  }<br /><br />  public void Trigger()<br />  {<br />    Console.WriteLine("The sensor has triggered.");<br />  }<br />}<br /><br />public class Alarm<br />{<br /><br />  public void Activate()<br />  {<br />    Console.WriteLine("Activating the alarm.");<br />  }<br /><br />  public void Deactivate()<br />  {<br />    Console.WriteLine("Deactivating the alarm.");<br />  }<br /><br />  public void Ring()<br />  {<br />    Console.WriteLine("Ringing the alarm.");<br />  }<br /><br />  public void StopRing()<br />  {<br />    Console.WriteLine("Stop the alarm.");<br />  }<br />}<br /><br />public class Client<br />{<br />  private static Camera camera1, camera2;<br />  private static Light light1, light2, light3;<br />  private static Sensor sensor;<br />  private static Alarm alarm;<br /><br />  static Client()<br />  {<br />    camera1 = new Camera();<br />    camera2 = new Camera();<br />    light1 = new Light();<br />    light2 = new Light();<br />    light3 = new Light();<br />    sensor = new Sensor();<br />    alarm = new Alarm();<br />  }  <br /><br />  public static void Main( string[] args )<br />  {<br />    camera1.TurnOn();<br />    camera2.TurnOn();<br />    light1.TurnOn();<br />    light2.TurnOn();<br />    light3.TurnOn();<br />    sensor.Activate();<br />    alarm.Activate();<br />  }<br />}<br /><br /> <br />六、 使用门面模式的设计<br /><br />一个合情合理的改进方法就是准备一个系统的控制台，作为保安系统的用户界面。如下图所示：<br /><br /> <br /><br />程序代码如下：<br />using System;<br /><br />public class Camera<br />{<br />  public void TurnOn()<br />  {<br />    Console.WriteLine("Turning on the camera.");<br />  }<br /><br />  public void TurnOff()<br />  {<br />    Console.WriteLine("Turning off the camera.");<br />  }<br /><br />  public void Rotate(int degrees)<br />  {<br />    Console.WriteLine("Rotating the camera by {0} degrees.", degrees);<br />  }<br />}<br /><br />public class Light<br />{<br /><br />  public void TurnOff()<br />  {<br />    Console.WriteLine("Turning on the light.");<br />  }<br /><br />  public void TurnOn()<br />  {<br />    Console.WriteLine("Turning off the light.");<br />  }<br /><br />  public void ChangeBulb()<br />  {<br />    Console.WriteLine("changing the light-bulb.");<br />  }<br />}<br /><br />public class Sensor<br />{<br />  public void Activate()<br />  {<br />    Console.WriteLine("Activating the sensor.");<br />  }<br /><br />  public void Deactivate()<br />  {<br />    Console.WriteLine("Deactivating the sensor.");<br />  }<br /><br />  public void Trigger()<br />  {<br />    Console.WriteLine("The sensor has triggered.");<br />  }<br />}<br /><br />public class Alarm<br />{<br /><br />  public void Activate()<br />  {<br />    Console.WriteLine("Activating the alarm.");<br />  }<br /><br />  public void Deactivate()<br />  {<br />    Console.WriteLine("Deactivating the alarm.");<br />  }<br /><br />  public void Ring()<br />  {<br />    Console.WriteLine("Ringing the alarm.");<br />  }<br /><br />  public void StopRing()<br />  {<br />    Console.WriteLine("Stop the alarm.");<br />  }<br />}<br /><br />public class SecurityFacade<br />{<br />  private static Camera camera1, camera2;<br />  private static Light light1, light2, light3;<br />  private static Sensor sensor;<br />  private static Alarm alarm;<br /><br />  static SecurityFacade()<br />  {<br />    camera1 = new Camera();<br />    camera2 = new Camera();<br />    light1 = new Light();<br />    light2 = new Light();<br />    light3 = new Light();<br />    sensor = new Sensor();<br />    alarm = new Alarm();<br />  }<br />  <br />  public void Activate()<br />  {<br />    camera1.TurnOn();<br />    camera2.TurnOn();<br />    light1.TurnOn();<br />    light2.TurnOn();<br />    light3.TurnOn();<br />    sensor.Activate();<br />    alarm.Activate();<br />  }<br /><br />  public void Deactivate()<br />  {<br />    camera1.TurnOff();<br />    camera2.TurnOff();<br />    light1.TurnOff();<br />    light2.TurnOff();<br />    light3.TurnOff();<br />    sensor.Deactivate();<br />    alarm.Deactivate();<br />  }<br />}<br /><br />public class Client<br />{<br />  private static SecurityFacade security;<br /><br />  public static void Main( string[] args )<br />  {<br />    security = new SecurityFacade();<br />    security.Activate();<br />    Console.WriteLine("\n--------------------\n");<br />    security.Deactivate();<br />  }<br />}<br /><br /> <br /><br />参考文献：<br />阎宏，《Java与模式》，电子工业出版社<br />[美]James W. Cooper，《C#设计模式》，电子工业出版社<br />[美]Alan Shalloway  James R. Trott，《Design Patterns Explained》，中国电力出版社<br />[美]Robert C. Martin，《敏捷软件开发－原则、模式与实践》，清华大学出版社<br />[美]Don Box, Chris Sells，《.NET本质论 第1卷：公共语言运行库》，中国电力出版社<br />posted on 2004-10-24 00:13 吕震宇 阅读(6640) 评论(10)  编辑 收藏 引用 网摘 所属分类: 设计模式<br /><br />评论<br /># re: 设计模式（15）－Facade Pattern 2004-10-25 09:09 HiRong<br />通过这个例子我只看到你将复杂度从一个类移到另一个类而已，并不能看到Facade Pattern的好处。如果再增加一个对象，比如说后勤人员可以控制一些灯的开和关，这时才能体现出Facade Pattern的用途。  回复  更多评论<br />  <br /><br /># re: 设计模式（15）－Facade Pattern 2004-10-25 09:36 lichdr<br />還是能看到好處的，就是寫前端的人不用管後端的事，它只跟那個facade打交道就行了。前後端隔離了<br /><br />當然前後端一個人干的就沒只是把複雜度從一個類到另 一個類而已了。  回复  更多评论<br />  <br /><br /># re: 设计模式（15）－Facade Pattern 2004-11-17 17:28 luoluo<br />这个例子客户端需要调用服务来做的事情的流程 不是很复杂<br /><br />医院的例子更好一些 病人要看病 需要做一系列的事情 比较复杂<br /><br />facade就显得很方便  回复  更多评论<br />  <br /><br /># re: 设计模式（15）－Facade Pattern 2005-08-01 10:00 BigHead<br />如果有很多Client这就体现出好处,可以试想下,如果Camera Light Sensor Alarm这几个类的实现改变了导致使用类也要改变的话,直接修改SecurityFacade就可以了.前提是这些改变不会导致连 SecurityFacade的接口也要改变.这就给维护带来了很好的简单性,这也就是松耦合带来的好处了. <br /><br /><br /><br /><br />facade模式的其他相关内容：<br />1.谁能给我解释下Facade模式???<br />http://www.javanb.com/j2ee/1/10508.html<br />我来举例子帮你说明：<br /><br />1)、假设你有一个类，里面分别提供了对某表的insert,update,delete,select方法。如果人家要对此表操作，就调用你这个类。可是你想这么做：对于那些高安全性的开发者，你可以给整个类的各种方法。可是对那些低安全性的开发者（比如第三方合作者），就只给select方法。<br />于是你再做了一个类，只有select方法（其实就是调用前面那个类的select），把这个facade类开发给低安全性开发者。这就是facade的第一个作用：隐藏<br /><br />2)、假设你有多个类，分别管理多表的操作。现在有个需求，可能一个事务涉及到多表的操作（比如用户登录，先要在用户表验证密码，然后再到登录日志表记一笔），那么你可以做一个facade，把这一系列的操作封装成一个方法。人家不用跟底层的单表打交道，只简单调用你的facade的方法就OK。这就是 facade的第二个作用：封装<br /><br />其他的作用我不清楚，我也没用过。但就上面这2个作用，让你有充分的理由用FACADE。<br /><br />2.设计模式之Facade(外观 总管　Manager)<br />http://java.ccidnet.com/art/3741/20040325/542091_1.html<br /><br />Facade模式的定义: 为子系统中的一组接口提供一个一致的界面.<br />Facade一个典型应用就是数据库JDBC的应用.<br /><br />3.关于JDBC facade 的疑问<br />http://www.jdon.com/jive/thread.jsp;jsessionid=8C27EB638A4561796FB7BF7DC68CDD07?forum=91&thread=6316<br /> 一个facade 要这样<br />private static ConnectionManager connManager = null;<br />private Connection conn = null;<br />private Statement stmt = null;<br />private PreparedStatement prepstmt = null;<br />private CallableStatement callstmt = null;<br /><br /><br />可能还有<br />private ResultSet rs = null;<br />private ResultSetMetaData rsmd = null;<br /><br />实现的一个类是很大的，而且每次调用都要new facade<br />这样是否有问题？<br /><br />我的意思是说 每次都生成这样大的一个对象，是不是很慢？<br /><br /><br />re: 当然 你使用singleton
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/64478#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 Mar 2007 00:03:00 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/64478</link>
        <guid>http://flysky.javaeye.com/blog/64478</guid>
      </item>
      <item>
        <title>设计模式之Command(zz)</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/64449" style="color:red;">http://flysky.javaeye.com/blog/64449</a>&nbsp;
          发表时间: 2007年03月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          板桥里人 http://www.jdon.com 2002/4/23/（转载请保留）<br /><br />模式实战书籍《Java实用系统开发指南》<br /><br />Command 模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体,规定很多的模式,正是这个灵活性,让人有些confuse.<br /><br />Command定义<br />n 将来自客户端的请求传入一个对象，无需了解这个请求激活的 动作或有关接受这个请求的处理细节。<br /><br />这是一种两台机器之间通讯联系性质的模式，类似传统过程语 言的 CallBack功能。<br /><br />优点：<br />解耦了发送者和接受者之间联系。 发送者调用一个操作，接受者接受请求执行相应的动作，因为使用Command模式解耦，发送者无需知道接受者任何接口。<br /><br />不少Command模式的代码都是针对图形界面的,它实际就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作.<br /><br />将这些命令封装成在一个类中,然后用户(调用者)再对这个类进行操作,这就是Command模式,换句话说,本来用户(调用者)是直接调用这些命令的,如菜单上打开文档(调用者),就直接指向打开文档的代码,使用Command模式,就是在这两者之间增加一个中间者,将这种直接关系拗断,同时两者之间都隔离,基本没有关系了.<br /><br />显然这样做的好处是符合封装的特性,降低耦合度,Command是将对行为进行封装的典型模式,Factory是将创建进行封装的模式,<br />从Command模式,我也发现设计模式一个"通病":好象喜欢将简单的问题复杂化, 喜欢在不同类中增加第三者,当然这样做有利于代码的健壮性 可维护性 还有复用性.<br /><br />如何使用?<br />具体的Command模式代码各式各样,因为如何封装命令,不同系统,有不同的做法.下面事例是将命令封装在一个Collection的List中,任何对象一旦加入List中,实际上装入了一个封闭的黑盒中,对象的特性消失了,只有取出时,才有可能模糊的分辨出:<br />典型的Command模式需要有一个接口.接口中有一个统一的方法,这就是"将命令/请求封装为对象":<br />public interface Command {<br />　　public abstract void execute ( );<br />}<br /><br />具体不同命令/请求代码是实现接口Command,下面有三个具体命令<br />public class Engineer implements Command {<br /><br />　　public void execute( ) {<br />　　　　//do Engineer's command<br />　　}<br />}<br /><br />public class Programmer implements Command {<br /><br />　　public void execute( ) {<br />　　　　//do programmer's command<br />　　}<br />}<br /><br />public class Politician implements Command {<br /><br />　　public void execute( ) {<br />　　　　//do Politician's command<br />　　}<br />}<br /><br />按照通常做法,我们就可以直接调用这三个Command,但是使用Command模式,我们要将他们封装起来,扔到黑盒子List里去:<br /><br />public class producer{<br />　　public static List produceRequests() {<br />　　　　List queue = new ArrayList();<br />　　　　queue.add( new DomesticEngineer() );<br />　　　　queue.add( new Politician() );<br />　　　　queue.add( new Programmer() );<br />　　　　return queue;<br />　　}<br /><br />}<br /><br />这三个命令进入List中后,已经失去了其外表特征,以后再取出,也可能无法分辨出谁是Engineer 谁是Programmer了,看下面客户端如何调用Command模式:<br /><br />public class TestCommand {<br />　　public static void main(String[] args) {<br />　　　　<br />　　　　List queue = Producer.produceRequests();<br />　　　　for (Iterator it = queue.iterator(); it.hasNext(); )<br />　　　　　　<br />　//客户端直接调用execute方法，无需知道被调用者的其它更多类的方法名。<br />　　　　　　　　((Command)it.next()).execute();<br />　　<br /><br />　　}<br />}<br /><br />由此可见,调用者基本只和接口打交道,不合具体实现交互,这也体现了一个原则,面向接口编程,这样,以后增加第四个具体命令时,就不必修改调用者TestCommand中的代码了.<br /><br />理解了上面的代码的核心原理,在使用中,就应该各人有自己方法了,特别是在如何分离调用者和具体命令上,有很多实现方法,上面的代码是使用"从List过一遍"的做法.这种做法只是为了演示.<br /><br />使用Command模式的一个好理由还因为它能实现Undo功能.每个具体命令都可以记住它刚刚执行的动作,并且在需要时恢复.<br /><br />Command模式在界面设计中应用广泛.Java的Swing中菜单命令都是使用Command模式,由于Java在界面设计的性能上还有欠缺,因此界面设计具体代码我们就不讨论,网络上有很多这样的示例.<br /><br />参考:<br />http://www.patterndepot.com/put/8/command.pdf<br /><br />http://www.javaworld.com/javaworld/javatips/jw-javatip68.html<br /><br />命令模式---我的理解<br /><br />设计模式如何在具体项目中应用见《Java实用系统开发指南》
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/64449#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 21 Mar 2007 20:59:00 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/64449</link>
        <guid>http://flysky.javaeye.com/blog/64449</guid>
      </item>
      <item>
        <title>内地与香港一流大学之比较——以人大和科大为例</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/58365" style="color:red;">http://flysky.javaeye.com/blog/58365</a>&nbsp;
          发表时间: 2007年03月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
发信人: yuegemofu (约格莫夫), 信区: RUCforum<br />
标  题: 转载：内地与香港一流大学之比较——以人大和科大为例<br />
发信站: 天地人大BBS站 (Mon Mar  5 12:02:14 2007), 站内<br /><br />
田方萌（美国乔治-梅森大学公共政策学院）<br /><br />
中国内地与香港的一流大学孰优孰劣？这一话题是2006年中国高等教育领域的讨论热点之<br />
一。旅美学者薛涌在四月首先挑起争论，直指北大清华有被香港高校赶上，沦为二流大学<br />
的危险。此文很快激起各方关于两地大学质量的辩论。年中香港高校在内地扩大招生名额<br />
，直接与北大清华争夺优质生源，进一步推动了论战的升级。<br /><br />
在关注这场论战之余，笔者愿从学生的角度，为中国高等教育的讨论提供一点直观的感性<br />
材料。过去五年里，笔者在中国人民大学经济学院和香港科技大学社会科学部先后攻读了<br />
经济学和社会科学两个方向的硕士学位。根据笔者的亲身经历和见闻，本文拟对人大和科<br />
大的成才环境作一比较，尤其是两校的研究生项目。<br /><br />
香港科大完全可以代表香港一流大学的水平，这一点似无疑问。人大在全国高校的综合排<br />
名中虽非名列前茅，但在社会科学不少专业上的排名还在前三，大部分专业都在前十以内<br />
。说它代表内地一流大学的水平，至少是一流大学的最低水平，也不为过。因此，本文的<br />
个案分析也就可看作一份比较内地和香港一流大学教育质量的参考资料。需要特别指出的<br />
是，笔者只关注中国大学对学术人才成长的指导和助益；至于商业人才和政治人才，另当<br />
别论。<br /><br />
先从容易观察和衡量的硬件开始比较，依其重要性排列。<br /><br />
一、 文献<br /><br />
文献是指学生可以接触到一切印刷和数字资料，其主要载体是大学图书馆，还包括教材、<br />
讲义和网络资源。单从藏书量来看，人大图书馆的规模（约三百万）远大于科大图书馆（<br />
约五十万）。但人大藏书绝大部分是中文著作，只有一个阅览室存放外文书籍，很多近年<br />
来出版的外文重要学术著作都没有收藏。比如弗朗西斯-福山最近几年出版的几本著作人<br />
大图书馆都没有收藏。科大图书馆的中英文馆藏约各一半，英文稍多。该馆英文文献颇成<br />
系统，中文稍逊，但包括大批港台著作，读者可以方便接触到许多大陆不易见到的材料。<br /><br /><br />
科大图书系统的另一好处是提供全港联校借书服务，学生可以通过图书馆代借香港所有高<br />
校图书馆上千万册的藏书。北京的大学之间并没有类似的合作协议，学生只能分头到各馆<br />
借阅。一所学校内，各系自己开设的图书室也是各自为政。<br /><br />
科大研究生的最大借书量也远多于人大学生。我在人大读研时最多可同时借阅二十册图书<br />
，在科大则可以借五十册。这还不算很多，据说在耶鲁大学，每个博士生可以借出多达两<br />
百册图书。<br /><br />
以电子数据库的数量而论，人大也超过科大。这几年人大的数字化生存空间大大拓展，总<br />
共购有中外数据库200多个，订阅32000种电子期刊。到2006年年底，科大共购买了164个<br />
数据库，订阅10363种电子期刊，明显少于人大。但若看数据库的品种，科大的电子资源<br />
似乎信息量更大一些。最知名的外文数据库如Proquest和Jstor两校均有购买，相差应该<br />
不是太大。我在人大写作硕士论文时几乎没有使用过电子数据库；而在科大作论文时，一<br />
半以上的文献都由数据库搜集而来。这当然一方面是由于我原先还不善于使用电子资源，<br />
另一方面也与人大当时较少对研究生进行文献查寻的系统性培训有关，据说现在情况已大<br />
有改善。<br /><br />
人大研究生使用的中文教材多是本校教师编著，形式虽不够活泼，内容还说得过去。问题<br />
在于，人大教材对某一学科的基本理论都有所介绍，但前沿性极差。<br /><br />
这在研究生教育阶段是个严重的缺点，因为研究生教育的目的并非常识性的了解，而在于<br />
立足前沿地带，探索新的知识。笔者走后，人大有些学院也开始使用英文原版教材。科大<br />
只有一些基础课程使用欧美出版的英文教材，大部分专业性较强的课程会布置按周分配的<br />
阅读材料。通常的做法是发给学生一本论文合集或一张光盘，再由学生复印或打印出来。<br />
某些阅读材料也可以在图书馆的“存阅处”（Reserve Desk）取得，供短时间阅读之用。<br /><br /><br />
文献一项，以科大十分计，人大可得六分。<br /><br />
二、 宿舍<br /><br />
宿舍决定了学生独立使用的空间大小。笔者在人大读研时与另外三位同学分享一间约三四<br />
十平米的宿舍，包括共用的阳台、卫生间和浴室，但无空调。每人拥有一台电脑桌和一张<br />
床铺，宿舍条件算是当年人大最好的。换到科大，同样是住四个人的学生公寓，除客厅外<br />
每人拥有一处五六平米的独立小间，门可上锁，<br /><br />
内装空调。共用洗手间和浴室的面积相对较大，每套公寓另设一厨房，可使用煤气做饭。<br /><br /><br />
宿舍条件是笔者在人大读研期间最不满意的状况之一。主要的烦恼在于难以保护隐私，而<br />
且室友之间相互干扰，欲求一安静自由的读书环境而不得。这方面科大的状况要好很多，<br />
但也不是全无问题，比如公寓内小间门板的隔音效果就很差。笔者初到科大时，一天清早<br />
起床，精神大振，抄起一份英文报纸就朗声念了出来。不一会听到对面室友敲门：“兄弟<br />
，小点声。”<br /><br />
宿舍一项，以科大十分计，人大可得四分。<br /><br />
三、设施<br /><br />
校园设施包括一切用于学习、资讯、文娱和健身方面的硬件，下面逐项分说。<br /><br />
学习方面，有无足够的自习坐位是衡量一所大学硬件条件的重要指标之一。<br /><br />
人大多年来没有很好地解决自习教室不足的问题，很多学生一大早爬起来在图书馆门排队<br />
占座。笔者在科大两年，只在期末考试期间见到过人满为患的现象，平常很少有找不到自<br />
习座位的情况。<br /><br />
资讯方面，今天大学生最看重的莫过于互联网。两校宿舍均设有宽带接口，<br /><br />
人大的网速稍慢一些，特别是在下载大字节电子文件的时候。由于内地和香港网络管制不<br />
同，科大学生可以访问一些人大学生不能访问的站点。但总的来说，尤其对于习惯阅读英<br />
文网页的学生，人大和科大的网络服务差距不是太大。报刊方面，人大订有包括港台出版<br />
物在内的大部分中文刊物，也收有一些英文重要刊物，<br /><br />
但取阅不是很方便。笔者在校时每次去要先将学生证压在管理员处，过刊还要托他到库房<br />
查找。科大订阅的国内中文刊物并不齐全，但主要的英文刊物，比如美国三大报纸和《经<br />
济学人》，都可以方便地读到。人大某些宿舍内装有有线接口，可收看包括凤凰卫视在内<br />
的电视频道。科大宿舍内可接入香港有线电视网，收看CNN和BBC等国外频道。<br /><br />
人大在文娱方面的可选择项目比科大要多。每周校园舞厅收费开放，周末常常有学生组织<br />
播放三四场电影。科大一到周末就冷冷清清，因为大部分香港学生都要回家，学校也没有<br />
常设的舞厅活动。该校的大陆学生组织会播放电影，片种受到版权法规的极大限制，很多<br />
片子有碟也看不了。<br /><br />
体育设施方面，人大拥有全北京高校最大的体育场馆“世纪馆”，另有一座室内游泳池，<br />
设施一流，收费开放；科大健身房及各场馆则免费开放，另有室外室内游泳池各一，换季<br />
轮替开放。此外，科大还设有几间琴房，供学生习练钢琴之用。<br /><br />
设施一项，以科大十分计，人大可得八分。<br /><br />
四、 校园<br /><br />
人大的和科大的校园环境恰好处在两个极端。前者位于北京三环西北角，地处闹市，浅门<br />
浅户；后者位于香港九龙清水湾，凭海临风，别有幽境。笔者在人大读本科时，宿舍窗口<br />
正对着一座购物商城，一早醒来能听到公共汽车报站的声音。校内每天都有不少外来人员<br />
进进出出。科大则清静像座桃花岛，美仑美奂，<br /><br />
却总是一样的景致。住在此间的人们来来回回碰到的都是熟悉的面孔，日久真是闷得发慌<br />
。人大的情侣在核桃林的石凳上谈恋爱还得提前占座；科大的山水清秀而浪漫，宜发海枯<br />
石烂之盟誓，可你就是见不着几对鸳鸯。<br /><br />
人大校园由一组风格并不统一，色调尚且协调的建筑组成。几条道路平铺直叙，四通八达<br />
。科大的教学办公楼是一整座迷宫般的巨大复合体（Complex），<br /><br />
从运动场到校长办公室的落差有三十层楼之多，全赖几十部电梯上上下下维持交通。在建<br />
筑内部，人大新建的教室均配有电教设备，科大亦同。人大教学楼内的洗手间不如科大的<br />
干净卫生，但阁下出恭之余可以欣赏涂鸦艺术家的壁画作品，<br /><br />
亦是一乐。在笔者看来，校园咖啡馆是大学必不可少的公共空间。人大在学生活动中心内<br />
原设有规模不大的水吧，笔者走后又开设了较大的咖啡馆“水穿石”。<br /><br />
科大校园内则有室内和露天结合的咖啡厅，满座可达一百人左右。<br /><br />
校园一项，两校都不算理想，科大稍佳。以科大十分计，人大可得七分。<br /><br />
五、 城市<br /><br />
城市决定一所大学的外围环境，大学生不可能不受到所在城市的主流文化氛围感染。就这<br />
点而言，北京和香港又处在两个极端。大略说来，北京多元、包容、政治挂帅；香港单调<br />
、排外、商业导向。这两座城市都居住着大量移民，北京的移民来自全国各省，五方杂处<br />
；香港的移民主要来自中国南方，尤其是广东省。<br /><br />
北京的人口结构比香港庞杂得多，最主要原因恐怕还在于准入制度：北京向全国人民开放<br />
，香港只准大陆同胞自由行。若想在港永久居住，比申请加拿大的移民签证还难。<br /><br />
语言和签证一样构成香港对内地人才的主要壁垒。香港规定的官方语言有三种，英文、粤<br />
语和普通话。占人口主体的港人交流多用粤语，像笔者这样的大陆学生如果不费心学习“<br />
丫夷桑”（一二三），就很难和港人沟通。香港上层社会普遍使用英语，一批大陆海归在<br />
那里倒是过得如鱼得水。相比之下，广泛使用普通话的北京则包容得多。<br /><br />
就社会和人文科学而言，北京的学术讨论气氛比香港浓厚很多。笔者以为可归于两项因素<br />
，一在地理，一在人事。首先，北京聚集了全国一半左右的知名学者，几十所高校密布海<br />
淀区。人大又位于这些高校中心，笔者在京就学期间得地利之便，骑自行车就可以接触到<br />
周边各校的学术资源。香港的高校分布比较分散，<br /><br />
从科大到最近的香港城市大学，乘公车和地铁还要半个多小时，自然不会产生所谓的“集<br />
群效应”（cluster effect）。其次，政治挂帅的北京吸纳了多种多样的人才，这里不仅<br />
是政治家的竞技场，也是大批商贾、学者、作家、演员、艺术家甚至异议人士活跃的舞台<br />
。丰富的人才储备决定了城市文化的多样性。相比之下，商业导向的香港就显得片面单一<br />
，学术价值和文化价值常常只能附身于商业价值之下。笔者接触过的香港人很少有自身利<br />
益之外的关怀，更少有学生为学术而学术了。<br /><br />
城市一项，以香港十分计，北京可得十六分。<br /><br />
下面再比较不易衡量，难以观测的软件，同样依其重要性排列。<br /><br />
六、师资<br /><br />
师资一项，颇难比较，说不好就要得罪我在两所学校的老师，含含糊糊一句“各有千秋”<br />
，又交代不过去读者。这里只好提前声明一句：吾爱吾师，吾更爱学术进步。<br /><br />
从师资来源看，人大教师大部分是本校的土产。中年教师很多是先留校再读博士，青年教<br />
师大都是博士毕业后留校的。大部分人大教师或多或少有海外访学和交流的经历，但真正<br />
从欧美大学博士毕业回来很少。笔者所在的经济学院长期以来只有一位老先生是49年以前<br />
从美国留学归来的，最近两年才在“提升国际性”的精神下引进了几位美国名校毕业的博<br />
士。笔者并不迷信洋博士的头衔，但坚信学术杂交的育种优势。“近亲繁殖”的问题并不<br />
只是在人大存在，可人大的问题比北大清华要严重一些。<br /><br />
与此截然相反，科大的教师几乎没有本校的博士生，绝大多数从欧美一流或二流大学毕业<br />
。这部分是因为科大是一所非常年轻的学校，比年轻的笔者还要年轻十几岁。主要原因则<br />
在于该校的聘任制度。科大在招聘教师方面有着一套非常严格的评审制度，任人唯亲的事<br />
情不是没有，但在很大程度上杜绝了。师资构成约有三分之一是大陆人，三分之一是港台<br />
同胞，还有三分之一是老外。科大的师资结构虽不能说做到了全球化，至少吸引了一批大<br />
中华地区的学术人才。<br /><br />
从笔者做学生多年的眼光看来，人大有一些非常优秀的老师，其学术素养并不逊于科大最<br />
好的老师。人大也有一些非常低劣的老师，他们的存在每每让你感觉到大学教育的荒谬。<br />
科大教师自然也有高下之分，但即使最差的老师也还算中规中矩，差不到哪里去。去掉两<br />
头的极值不谈，人大教授的平均水平仍低于科大教授。前者最主要的问题在于缺乏方法论<br />
的训练和对西方学术前沿的把握，往往自成一套，乐在其中。人大经济学院和科大社会科<br />
学部的大部分教授笔者都认识，<br /><br />
有一部分是熟识，他们的文章书著我也看过不少。笔者在这里以一个圈内人的观察对两者<br />
作出评价，相信不会太离谱。<br /><br />
虽然人大教授的专业水准平均说来不如科大教授，但前者的工作压力小一些，有时间博览<br />
群书，在学问的广度上往往超过科大的专家们。笔者跟人大老师相处多年，专业上虽然进<br />
展不大，却大大拓宽了学术眼界，同时也从他们身上学到了不少处世治学之道，这一点不<br />
可不提。科大教师常常只是辛勤耕耘自己那一块专业领地，出了这个圈子他们的所知就有<br />
限了。<br /><br />
师资一项，以科大十分计，人大可得七分。<br /><br />
七、课程<br /><br />
人大科大两校均实行学分制，学生依培养计划修课，修满学分，通过论文答辩，即可毕业<br />
。人大研究生课程要求较松，通常上课老师满堂灌，较少提问和讨论。有些教师私下里会<br />
组织自己的研究生召开定期或不定期的读书讨论会，也是一种可以取法的形式。期中和期<br />
末会有两次考试，有时也代之以论文。科大研究生课程则严格得多，每门课每周的阅读量<br />
比人大多好几倍，读物多是近年出版的英文文献。课上要求学生根据阅读材料积极参加讨<br />
论，有些课程甚至专为讨论而设（称为seminar）。一学期内，学生在课上有一两次机会<br />
做演示（presentation），可以锻炼口才和答辩技巧。科大课程的作业量也较人大课程为<br />
多。<br /><br />
论文写作训练是两校研究生项目的重大差异所在。前文提到，研究生训练的目的在于创造<br />
新的知识，而不是对已有知识进行分析和综述。就我所见，国内研究生的论文（包括笔者<br />
以前的论文）大部分属于后者。这种重复性工作并不是没有意义，学生至少可以通过写作<br />
了解某一领域的知识。但这一论文写作模式对于知识创新毫无价值可言，也就谈不上学术<br />
体系的积累和发展。笔者到科大以后才大体掌握了研究型的学术论文写作，包括确定题目<br />
、文献综述、提出假设、收集数据、检测假设、分析讨论等一系列步骤。<br /><br />
人大的课程平均质量虽然较差，学生却可以选择较多的课程种类。笔者在人大读研期间可<br />
以从全校各系开设的几百门选修课中进行选择。在专业之外，我曾经选修过其他学院名师<br />
讲授的课程，甚至到北京大学旁听。与人大相比，理工科占主体的科大并不重视人文与社<br />
会科学专业，社会科学部建立之初的主要任务只是给本科生提供辅修课程。该部研究生在<br />
某一专门领域可选的课程很少，心理学方向甚至只有两三位老师和一位研究生，你让他们<br />
怎么开课？<br /><br />
此外，人大教师上课很少准备教辅材料，也很少使用电教器材，常常从头侃到尾。科大几<br />
乎任何一门课程的讲授均配有PPT或幻灯片的投影演示，有时还会借助视频材料。教辅材<br />
料缺乏的部分原因在于人大没有助教制度，教师也不情愿把精力花在教学方面。<br /><br />
课程一项，以科大十分计，人大可得六分。<br /><br />
八、制度<br /><br />
大学制度千条百条，与学生有关的主要有两项，录取制度和学费制度。<br /><br />
国内大学的录取制度，本科生高考过线，研究生考研过线，基本上就有学上了，面试只会<br />
淘汰极少一部分人。人大依此成例。至于如何考取，有一大堆教辅参考书在那儿摆着，也<br />
不需笔者罗索。科大基本上依照英美高校的模式录取，语言关要考托福、雅思或GRE，学<br />
术关要提供成绩、简历和推荐信，有时还包括一篇论文样本（writing sample）。一个由<br />
教授组成的录取委员会会根据这些材料择优录取。如果我们相信考试成绩不见得能代表学<br />
术能力，科大的录取方式似乎更加科学一些。但在国内目前的宏观制度背景下，考试比评<br />
审更能够体现效率和公平。所以笔者并不主张内地高校自主招生。<br /><br />
学费制度是近年来中国高等教育改革的试点之一，总体来说趋向自费为主、辅以奖学金的<br />
模式。人大的自费硕士项目两年约需三万元学费，科大硕士项目一年约需六万港元。笔者<br />
当年在人大读研时尚且享有公费资助，每年只交不到一千元的住宿费，学费全免，此外每<br />
月还有250元补助。如果将所有明补和暗补均按货币折算，大约相当于每年两万元左右的<br />
奖学金。<br /><br />
笔者在科大申请到的全额奖学金需用于支付一切学杂费和生活开销，全年约有12万港元，<br />
暑假若担任助理研究人员，还可获得一万多元的工资。当然香港的物价水平大大高于北京<br />
，比如食品价格和房租约是北京的两三倍。若按购买力平价折算，笔者在科大获得的奖学<br />
金也有四五万人民币，仍是人大的两倍多。高额奖学金为笔者提供了充分的经济保障，甚<br />
至略有结余。相反，我在人大时常常入不敷出，不得不靠给书商打工挣点外块。况且，东<br />
一块西一块的暗补在经济效率上还不如完全货币化的明补。<br /><br />
制度一项，以科大十分计，人大可得六分。<br /><br />
九、生源<br /><br />
评价生源和评价师资一样，都是得罪人的事儿。我和两校同学多是泛泛之交，可交情还不<br />
算坏，这里胡说几句就请大家海涵了。本节的评价只针对群体，不针对个人。<br /><br />
谈起人才水准，国内大学流传着这样的说法：“一流的本科生，二流的研究生，三流的教<br />
授。”这一人才层次在人大尤为明显。人大在各省的高考录取分数线只在北大清华之下，<br />
有时还超出两校，故可保证本科阶段的优质生源。人大研究生一部分是本校升上来的学生<br />
，一部分是国内其他大学考取的学生。依笔者的印象，大多数研究生学习都很勤奋，但无<br />
论在学术还是在社会活动方面，都不如本科生活跃。至于三流教授的说法，笔者曾听一位<br />
人大中年教师谈起，他说他们那一代人里，做官的做官，下海的下海，出国的出国，剩下<br />
的才到高校里教书。<br /><br />
但愿前辈的故事不要在我们这一代人里重演。<br /><br />
科大的人才层次正好相反：三流的本科生，二流的研究生，一流的教授。科大本科生绝大<br />
多数都是香港本地学生，近年来内地学生的比例逐渐增大，但也就百十来人。笔者在这里<br />
并没有贬低香港学生的意思，只是觉得比起13亿人的中国内地，700万人的香港实在太小<br />
了。一座城市里选拔出来的优秀学生，怎么可能和一个大国选拔出来的优秀学生竞争？这<br />
就好比北京大学里的外地同学和北京同学在平均水平之间的差距。笔者接触到香港本科生<br />
大都是一些千人一面的小表哥小表妹，搞个活动都穿一色的西服套装，很少有人具有特别<br />
的才具和抱负。<br /><br />
虽然同属二流，科大研究生院的生源还是好过人大研究生院。科大研究生大多来自国内一<br />
流大学，有些和笔者一样，是在国内读完研究生才过来。据笔者的观察，这批在香港读书<br />
的大陆研究生多半是一些学术上还说得过去，但看不出未来有多大潜力的人。当然也有个<br />
别很出色的，某些系的生源质量甚至可以和欧美一流大学相媲美。在可能是理工科学生较<br />
多的原因，科大研究生在学术和社会活动上的活跃程度还不如人大研究生。至于科大的大<br />
陆籍教授，很多其实就是当年出国的那批八十年代的大学生。<br /><br />
生源好坏很大程度上决定了一所大学的文化景观和思想生态。人大的学术讲座绝大部分是<br />
学生自己办的，校方只负责审批。科大的大部分公共性讲座由校方出面承办。如果校园里<br />
年轻人对思想学术的热情尚不及中老年人，其余可想而知。<br /><br />
生源一项，以科大十分计，人大可得十六分。<br /><br />
十、服务<br /><br />
校园服务包括伙食、住宿、教辅、安全等一系列后勤供应和保障。<br /><br />
人大的伙食在笔者念书期间是出了名的差，还算温顺的人大学生为此就发动过好几次罢餐<br />
活动，不知道是否够得上大规模群体性事件的标准。笔者读研最后一年，经济上稍微宽裕<br />
，每天都有一顿是在校外吃的。科大的伙食谈不上丰富，以南方口味为主。虽然久吃也会<br />
腻，总得来说还是比人大的伙食营养可口。人大学生在高峰时间买饭需排长龙，科大则很<br />
少出现长龙。<br /><br />
人大要求学生在午夜之前回校，否则紧锁楼门。这一政策完全是为了方便管理人员，而不<br />
是学生的夜间活动。如果是为安全计，夜间就应该安排人手值晚班，<br /><br />
而不是一锁楼门了事。科大这点做得比较好，宿舍楼门任由学生24小时自由出入，同时有<br />
防盗摄相头监控。科大本科宿舍楼的楼门还配有密码。<br /><br />
一些教学辅助人员服务态度之差，服务质量之劣也是人大学生经常抱怨的。<br /><br />
按理说学校教辅人员应当服务学生，而实情则往往是学生需要讨好教辅人员。以笔者在科<br />
大两年所见，那里的教辅人员服务高效热诚，堪称模范。此外，人大学生的财物安全也很<br />
成问题。但这更多和北京市的治安状况有关，倒不见得是人大保安办事不力。笔者在科大<br />
时从没有听说过学生的财物被窃。科大保安多用老年人，足见其治安状况之佳。<br /><br />
服务一项，以科大十分计，人大可得五分。<br /><br />
以上大学比拼十项全能赛，科大胜出八项，人大仅在城市和生源上绝对胜出。<br /><br />
在科大领先的八项中，人大有三项非常落后（宿舍、课程、服务），有四项比较落后（文<br />
献、制度、校园、师资），一项稍微落后（设施）。以科大总分一百分计算，人大可得八<br />
十一分。因为城市和生源两项在软硬件方面的重要性靠后，如果加权计算，人大的分数还<br />
会更低，当在七十分左右。对一个渴望学有所成的少年人，孰优孰劣，自不待言。<br /><br />
需要特别指出的是，笔者虽然对人大现状不满，但没有责怪人大领导和师长的意思。中国<br />
高等教育就是目前这种状况，无论我们喜欢不喜欢，都必须在这个基础上进行变革和整改<br />
。人大存在的问题在全国高校普遍存在，人大相对来说还算是表现不错的。笔者离开人大<br />
三年来，学校已经出现了明显进步，在某些方面甚至走到了中国高教改革的前列。<br /><br />
人大虽然在大部分项目上落后于科大，基本属于学校内部政策可以调整的范围，厉精图治<br />
，定有改观。科大固然招收了一批内地优秀学生，但长期内仍会以香港学生为主体，生源<br />
质量改进的幅度不会太大，香港重商轻学的价值导向更非科大所能改变。三五十年之后，<br />
人大科大谁更领先，现在还很难预料。笔者撰写此文只是为了给国内的师长和同学们提供<br />
了一个外部的参照系，帮助大家了解我们在大学建设上还存在哪些差距和不足。<br /><br />
和很多中国名校一样，人大和科大都怀有建成世界一流大学的雄心，也都有着难以成为世<br />
界一流大学的障碍。唯有我国教育界同仁锐意改革，奋进突破，中国才能实现复兴学术文<br />
化的梦想。笔者在此愿与天下学子共勉之。<br /><br />
2007．2．14．<br /><br />
于弗吉尼亚Fairfax郡 <br /><img src="http://www.blogjava.net/flysky19/aggbug/102707.html" height="1" width="1" /><br /><br /><div align="right"><a href="http://www.blogjava.net/flysky19/" target="_blank" style="text-decoration:none;">不断前进的小乌龟</a> 2007-03-09 00:51 <a href="http://www.blogjava.net/flysky19/archive/2007/03/09/102707.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/58365#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 08 Mar 2007 16:51:00 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/58365</link>
        <guid>http://flysky.javaeye.com/blog/58365</guid>
      </item>
      <item>
        <title>写给想出国的师弟师妹，尤其是计算机系</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/58366" style="color:red;">http://flysky.javaeye.com/blog/58366</a>&nbsp;
          发表时间: 2007年03月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
发信人: facerbird (标准库函数), 信区: AbroadStudy<br />
标  题: 写给想出国的师弟师妹，尤其是计算机系<br />
发信站: 天地人大BBS站 (Tue Mar  6 00:45:04 2007), 站内<br /><br />
    有的人可能觉得我刚出国半年多，经验不足，应该不足以来传授一些东西，说对了，我正在做的就不是传授东西，而是想要大家自己多来想想一些关于自己的事。<br /><br />
    为什么呢？这是因为我在这半年里面所看到的和所经历的，与老一辈所鼓吹的和新一辈所崇尚的一些天堂般的国外生活是不太一样的。我之前也和万千将要
出国者一样，看过一些前人所写的文章，其中必然是以描述国外的新鲜为主要（这是因为刚出去的新奇），也有描述国外生活质量比较高的（这是因为相对来说外国
人确实生活得不错），还有描述找工作如何克服困难的（这是大家最关心的基本要求），很少有不断的抱怨和申诉生活的艰难或者不断累积的郁闷的，因为大家都报
喜不报忧阿，国内父老乡亲都在看着你的blog，你要是一天到晚唉声叹气茶饭不思，于心何忍。因此，这类帖子之少让大家觉得郁闷的事情实际上很少。然而并
非如此，如同恋爱就是双倍的快乐和双倍的痛苦一样，出国的快感和郁闷也是守恒的。我在这里不是泼冷水或者奉劝大家不要出国，你要是这样以为，那这篇文章起
到的作用和其他文章就没有什么区别了。我要做的不是告诉你们是或者不是，而是希望引起你们思考：自己是不是适合出国。这是一个非常非常重要的问题，你对我
提出这个观点不以为然正是因为你可能还没有真正认真来考虑这个问题。<br /><br />
    我想从学习、生活环境和找工作三个方面来说一下，在综合性的东西说完了之后再针对计算机系的各种情况说一下，没有耐心的人直接跳着看。由于本人是在英国，所以描述的对象大多着眼于英国环境，不过扩展性比较强，据在美国同学介绍，情况差不太多。<br /><br />
    学习：<br />
    在申请的时候大家最先考虑的，一般是这么几个问题：问题1，是读硕士还是读博士。因为舆论曰博士奖学金多，所以这个考虑变得很重要。首先说一点，
在英美，硕士和博士制度与国内不同，不是一个接一个，而是两条并行的线，硕士会用短时期来给你灌输一些专业各方面的知识，以上课为主，博士用长时期来专注
于一个非常非常窄的领域，毕业的目标是成为此领域的专家，在本科时期，我认为如果我读博，我就学人工智能，而事实上，一个博士将会仅仅研究人工智能里面的
机器学习领域里面的模糊逻辑方法里面的XX模糊逻辑规则的效率和扩展。这就是细粒度。硕士和博士应该选哪一种取决于你对自己的性格类型的判断和你出国的目
的，如果觉得自己并不是研究型的人，如果你觉得很难持续的看英文论文并且每天坐在实验室里，那可能硕士比较适合，对于只想学一点东西并顺便拿一个学位回国
发展的人，就更加适合。而博士，我认为只有对学术有着真正的热情并且比较有约束力的人才会非常享受地过着博士生活。想想看，在英国硕士一年博士三年
（50%的人需要四年才被允许毕业），在美国硕士二年博士五年，你能否在博士的位置上奋斗五年，这是一个你需要非常认真的评估自己性格的问题。我身边的每
一个人包括我自己，都认为我是一个非常搞学术的人，但我自己过来了之后，改变了硕士读完之后再读一个博士的想法，觉得我应该工作。当然这里有很大一部分原
因是觉得我无法忍受再用3-4年时间生活在英国，此处在生活环境一节再讲。<br />
    当奖学金这个东西卷入之后，硕士和博士的选择变得更加艰难，英国的硕士奖学金约等于零，我曾认为前人说奖学金很少那总还是有的，我够优秀的话一定
能得到。事实上，希望大家断绝这个念头，它几乎不可能。英国的博士奖学金稍微好一点，但是由于它不像美国是由导师全权操作财务，学校提供的奖学金机会很
少，只能靠一些机构和基金会，对于中国人来说，并不多，平均一下大概只有10%的人能够得到全奖，20%的人半奖。美国当然情况好一点，即使是硕士，奖学
金的希望也和英国的博士差不多。美国博士自然就不用说了，一般都有钱。<br />
    综合一下，大家应该思考一下自己的性格加经济。经济是一件非常明确可评估的东西，性格却不那么容易评价，请多注重考虑它。不是对技术和研究有着一股热情的人，除非你喜欢过一些悠闲堕落的生活而不在乎时间，否则你会觉得万分无趣而且没有尽头。<br /><br />
    问题2，外国教学水平和科技水平是不是高很多以至于学习效果很好很值得出国学习一下先进的知识？我认为外国的教师确实绝大部分非常有水平，因为很
多学术界的大牛都在大学教书，同时又认为，其实绝大部分的他们在很多时候也仅仅是使用一些经典的ppt和参考书来讲课，这意味着有了ppt和参考书（这两
样东西通常是此领域内的经典教材和其附带ppt），你可以自己学习。我记得我本科的时候学人工智能，老师用的ppt是《人工智能——一种现代方法》的附带
ppt，参考书则是一本国内人写的烂书。在这边，老师讲人工智能方面的东西，也是用的同一个ppt和《一种现代方法》这本参考书。在如下几个条件成立的前
提下，我发现自己学习达到同样的效果：1老师嘴巴里讲的内容全部来自ppt和参考书，2参考书写得非常仔细而全面，3老师不关心我做作业的好坏，4我比较
自觉学习。上述四个条件就是我们这里的现实，所以实际上，在国外学习能不能够真正学到东西，一定要靠你自觉学习。<br />
    在其他设备和教学器材方面，我觉得与国内一样。<br /><br />
   问题3，与上一问题有关，有人说出国学习不仅仅学专业知识，还有更多的与知名大牛交流和与国际学生交流的机会。这不假。对大家来说，考虑这么几个问
题，你在国内的时候，是不是经常会与人交流学术问题，是不是经常与刚认识的人交流学术问题，是不是可以找学院的教授探讨学术问题。如果你在国内便已经很愿
意开口说话和很愿意探讨学术（我在国内和在国外都曾因为和别人讨论学术过多而被人觉得另类），那么继续思考这几个问题，你对本专业的英文词汇掌握程度是否
足以让你和外国人交流无障碍，除学术交流之外你是否可以做到与外国人交流无障碍（请默默尝试用英语向外人描述你看完无间道三部曲之后的感受和剧情介绍），
你是否可以做好充分的准备与印巴人、非洲人、意大利人、东欧人等英语说得奇形怪状的人进行交流无障碍。<br />
    问题问完了以后讲一点事实，我身边95%的中国人都是和中国人相处在一起，虽然大家也都有外国朋友，偶尔也聊天，但是由于语言问题实在还不到充分的程度，成为密友的可能几乎没有。而想要同国际大牛探讨学术人生理想，就如同和纪宝成讨论后勤集团的恶行一样没有机会。<br />
    你内向还是开朗？出国后只会让你继续往内向那边偏一点点。<br />
    <br />
    以上是与学习有关的问题，学习是我们出国想的第一件事，那么你究竟是否适合研究，性格是否开朗常与人交流，是否会自我约束的进行学习，而这样出去得到的学位是不是你所需要的，这样出去学到的知识是不是在国内也能学到，思考吧。<br /><br /><br />
    生活环境：<br />
    在国内人的眼中，外国就是天堂，否则为什么有人偷渡，为什么有人花大钱移民，为什么出国留学的人要千方百计留在国外？我至今也没有想通这三个问
题，为什么没有想通呢，与“以小人之心度君子之腹”类似，小人觉得别人心里想的和自己一样，君子也觉得别人心里想的与自己一样。我和那些人想的不一样，所
以我觉得外国让我很受束缚。那么你究竟属于我这一类还是天堂那一类，这也是应该在出去之前就想清楚的，否则走错了的人会像我一样天天期望着回来。<br />
    我不喜欢生活在英国的几个原因：<br />
    原因1，时刻铭记自己是中国人，并且证明中国人有风度有礼貌。以前各种目的诡异的小文章曾说，外国人非常遵守交通规则，就算没有人没有汽车，外国
人走路开车的都会在红灯前面停下来。开车的停下来是不假，红灯处都有摄像头，闯过去被抓住了是重重的罚，我同学晚上骑单车没有开后灯都被抓住罚了32英
镑，开车闯红灯只怕要连汽车都没收了。而行人则是不看灯的，在没有汽车的时候，行人们就直接趟过去了。刚来的头一个月，每逢红灯我必停下来，然后看见外国
人CHUA CHUA的一个个从我身边穿过去了。英国人这么穿可以理所当然，我却会想如果我闯红灯会不会就被英国人一棒子把中国人都看扁了，于是我走路都
必靠左走，在电梯里公共汽车和火车上决不大声说话，上课决不讲小话云云，每次当和朋友在教室里说话，在火车上说话，边上的人用眼睛带着一点白色瞟过来的时
候，我会觉得很不舒服的。当你不管做什么都带着一点小心翼翼的心理，是不怎么舒服的。<br /><br />
    原因2，英国人不带痕迹和带着痕迹的排斥。英国的酒鬼是出名的，他们喝酒必醉，醉必发疯，若此时从他们面前经过，或许会听到
“Fxxxing Chinese”。英国人眼中的中国仍然是一个落后的国家，很多时候也被用来开玩笑。即使在牛津这种地方，英国人的醉鬼和流浪汉甚至印
巴的士司机都对中国女生进行挑衅、骚扰直至性攻击。中国女生晚上出门一定要男生送才安全，曾发生过深夜女生被袭击事件，的士司机性攻击事件，之后女生连单
独坐的士都不敢了。而我两个女同学在路上走被一群开车的醉鬼叫嚷“Let's go play”，她们快步走开酒鬼就叫
“Fxxxing Chinese”，CAOTM的英国酒鬼。我同一栋楼的两个女生，晚上在楼下车棚停单车，几个流浪汉就站在车棚铁门外晃悠，每当她们想
要开门了就围过来。结果打电话给我下楼接她们才敢开门。<br />
    英国人不带痕迹的排斥主要体现在找工作的领域，在下一节再讲。除此之外，外国人不怎么主动和中国人说话，一些变态的外国学生在做助教的时候故意挑
中国学生的刺，这一类就多了。如果稍微留心一点，会发现中国人永远难以融入到他们正常的社会中去，并且总被一股从上往下看的眼光所看着。<br /><br />
    原因3，没有娱乐，有很多寂寞感。英国人的娱乐就是看电视，我们在国内所熟悉和喜欢的东西，这里肯定是没有的。即使偶尔一起吃饭聚餐，还要担心占
用厨房太久别人有意见。由于是单人间，大多数时候是一个人呆在房间里面，如果处在一些中国人比较少的专业，那就会每天都一个人去上课，默默的听完课又一个
人回家，晚上一个在家里做一些作业，做完了就一个人看看电影上上网，有什么想法什么抱怨都没有适合的人可以交流，做作业没有人可以讨论，有问题没有人可以
咨询。不过这些想必大家都有所耳闻，也不会当作什么大不了的事情。对于有一大帮子朋友在国内的人来说，稍加比较，便会越发觉得毫无趣味。<br />
    长时间的一个人生活，是非常容易让人产生寂寞感的。大家或许不以为然地觉得在本科的时候也是一个人早上起来了走去上课，一个人去食堂吃饭，一个人
自习，然后一个人走回寝室睡觉，那是因为你边上全是熟悉的或者友好的人，是你可以与之说话的人，而在国外的单人宿舍里，一天一句话都不说是很正常的。我想
大多数人应该是从来没有这样的经历的。<br /><br />
    以上三个原因咋看起来毫不起眼，我也不是什么温室里的嫩草，只是当这三样东西从你生活的环境每一个方向压过来的时候，就会让人觉得在这里难以任凭
自己发挥，随自己的想要的发展，和国内的轻松。对，就是这样，对于没有什么磅礴理想，只想轻轻松松过日子的人，对于那些对生活细节太敏感、感情太细腻的
人，对于那些喜欢和朋友厮混在一起难以忍受长时间独处的人，国外的生活可能不会太让你觉得舒适。当然，有能力排除经济条件，只是想出来看看世界的同学们，
出来读一个硕士将是一件很好玩的事。<br /><br /><br />
    找工作：<br />
    在找的过程中，各公司不会说他们不倾向于收中国人，只是你的简历上需要注明你的国籍，你的工作许可状态。国籍这东西是绝对不会拿出来说的，工作许
可状态则是一个可以拿上台面说的东西，中国留学生最初都是没有工作许可的，虽然经过一些找律师之类的行为可以搞一个工作许可，不过谁会做呢？Google
在我们学校宣讲的时候就明确的讲了，我们不会给员工提供工作许可（听起来就像北京户口一样，有的公司会给你批北京户口，但是google就直接说我们不
收）。<br />
    其次，在可以收你的一些公司，如投行，技术公司等，面试的过程中，英国本地人占很大的优势，中国人虽然计算机技术不输给他们，但在英文表达能力等
方面就差得远。再加上有一定的倾向，最后招收的绝大部分是英国人，如我一个在英国待了四年的同学去的美林证券，最后几个人除了他之外全部是英国人。这还是
比较默默的淘汰外国人，有的公司就直接公然表示不招中国人，我对门住了一个香港女生，来英国也是4年，英语不错，她已经经历过至少两家金融咨询公司公然的
表示不招中国人。<br />
    然而实际上即使此香港人自己，也是不愿意把自己当作中国人的，虽然他父母都是内地人，虽然他在我们面前都说是中国人，但是在别人面前，都说自己是
香港人。当那两个金融咨询公司排挤她的时候，她向我们抱怨中无意透漏出：他们不招中国人，即使我说我是香港人，也没有用。她的这一段话给我留下了深刻的印
象。<br />
    在这样的环境中，或许我们能找到一个工作，程序员、咨询师、办公室职员这一类大把抓的平常工作，但是能够上升一层到管理层？我想几乎是不太可能的。在如此的氛围中。<br /><br /><br />
    关于出国的一些带着强烈的抱怨性的话语就写到这里，不可否认大家会觉得我有一点规劝别人不要出国的意思，我是有那么一点，这一点仅仅针对于那些性
格与我类似的人，因为我的若干个出国的朋友，都和我有同样的想回国的想法。我要让大家想的，就是你是不是属于我这一类人，如果是，那么你就该想想自己是不
是应该要出国来学学。<br />
    总结一下我认为适合出国的若干种性格：潜心学习的，即使在人大也仅仅往返于教一、食堂和宿舍之间，这一类不特别在乎生活的人；豪迈的，人生理想是
成为大企业家或者打定了主意要成为成功男人或者成功女人的人，这一类往往有强烈的自我控制，并且把绝大部分精力集中在学习和事业上，也就不会在乎一些小东
西；闯荡的，觉得应该到处看看，寻找一些新鲜的生活的人，这类关注的主要是新鲜，不是学习或事业，那么也就不会束缚于留学那郁闷的学习中。<br />
    以上集合的补集便是不那么喜欢出国生活的人了。<br /><br />
    针对所有师弟师妹们的建议到此结束，呵呵，骂声一片，不过你认为为什么我要写这么长的一篇文章呢。<br /><br />
    接下来是有关计算机系，信息学院的师弟师妹们的出国思考和建议。<br /><br /><br />
    我本科在计算机系，全名是计算机科学与技术系，我现在在计算机科学系，即Computer Science。这个全名很重要，并且并不是每一个人
都能在本科生涯里明白CS系的特色，这不奇怪，因为中国大学的计算机系通常都是计算机科学与技术系，所以对比比较少。但是我要告诉你们的是，明白这一点，
将会对你的学术路线和职业路线非常有意义。下面我摘录我某个文章里一段话来说这个事：<br />
    之所以中国在整体上比较偏向于算法型，我认为是因为中国的大学计算机系绝大部分是“计算机科学与技术”专业，他注重一个“科学”，所以从课程上来
讲，会包括更多的算法设计，编译原理，数值分析，计算机图形学，数据库原理等等理论性比较强的课程。与此进行比较，英国的计算机类学科并不全是“科学”
类，包括系统设计、软件工程等培养应用型人才的专业，他们与计算机科学专业平起平坐。他们之间的差别并不是每一个中国的计算机系大学生都能够分得清楚，在
此我举两个比较明显的例子：<br /><br />
    1，计算机图形学，在计算机科学专业学的是各种曲线曲面的方程，三维物体在平面上投影的计算和光照的模型等数学性较强的内容，在软件工程专业学的则是如何利用OpenGL,Direct3D等图形软件包来开发三维动画和空间。<br /><br />
    2，数据库，在计算机科学专业学的是数据库系统的理论，是范式，是并发性处理和锁，是公理系统，在软件工程系则是如何用java，asp等连接数据库，如何为一个系统设计各种表，如何更好的掌握Oracle,Mysql之间的不同。<br /><br />
    这两个例子应该很好的解释了计算机科学与计算机应用之间的不同。<br /><br />
    我在本科的时候，刚进来学N多数学课，与我的想象严重不符，计算机系居然不编程，而是学数学。这正是“科学”二字所在，我们系的培养目标是计算机
科学家，是为了更进一步的研究，而不是为了就业。我大四的时候，有一个工作了的师兄来了我们寝室对我们进行教育，他说工作很舒服的，工作的编程非常舒服，
跟在学校的编程完全不同。他说对了，这正是一个非常好的例子来说明如何认识到自己适合做的东西。因为绝大部分工作中的编程是“开发”，你给一个按钮写命
令，测试时按那个按钮，命令都执行了，多么有成就感。这就是开发，而我们在学校里学的是研究，是算法。在开发中，很容易找到成就感，而一个算法，想不出来
就完全不能动笔。但算法如同数学，是一项高雅的艺术，也是走向计算机科学的奠基石，通过对算法的学习，能够触类旁通，更加深刻的理解计算机，它需要勤奋的
研究才能掌握。<br />
    那么，你是喜欢开发，还是研究呢？思考它，少走弯路。<br /><br />
    其次，我建议你们不要申请英国的硕士，甚至博士，理由如下：<br />
    冲着短期拿学位的目的来的人自然我非常推荐读硕士，英国的硕士只有一年，这一年耗资学费加生活费约30万，而英国的计算机类牛校无非如下几个：剑
桥、牛津、帝国理工、爱丁堡、曼彻斯特，（你首先必须明白泰晤士报排名完全不具有参考价值），其他学校名气上和实力上就显然不如这几个学校，我想大家也不
会愿意花30万在一个不怎么出名的学校里去学习。<br />
    但这几个学校却各具缺点。<br />
    剑桥没有授课式计算机硕士，全部是博士，唯一的两个相关的一个是计算语言学研究性硕士，一个是生物信息学研究性硕士。研究性硕士就是很少上课，是以做研究为主，可以当作是PhD的预备班。<br />
    牛津的计算机硕士则比较倾向于以前是学软件工程或者计算机应用等的人，让他们转向计算机科学领域，所以有不少课程仅仅是在本科的基础上稍微加深了一点。再加上并不强制性的给学生布置很多功课，所以此地并不适合想学习更多知识的人，只适合想拿学位的人。<br />
    英国的计算机系有很大一部分专注于人工智能和编程语言，几乎每个学校如此，数据库阿什么的很少。而人工智能方面帝国理工很强，爱丁堡大学则是有欧
洲人工智能中心，都还不错。不过帝国理工一年大概需要40万。爱丁堡和曼彻斯特不具备上述三大顶级学校的缺点，在学术上还算不错，只可惜在国人眼里知名度
不够高，作为一个想追求知识的人，可以去，但是对追求名气的，不适合。因此英国前五的计算机系硕士都不是那么美好的。<br />
    而英国的博士申请奖学金则比美国少很多，上文也说了，极少由导师来控制钱，所以拿奖少，再加上实际上很多人需要4年才能毕业，和美国比起来也只是
少了一年，在实力上和研究领域上，美国的大学也比英国广泛。所以博士我也不很推荐来英国。GRE改革之后似乎比以前更好了，因此我更推荐去美国。<br />
    综上所述，英国的计算机是不很值得来学的。<br /><br />
    第二个问题，英国的计算机就业。不少人把就业当作出国的目的，虽然我极度不喜欢生活在国外，但还是提供就业的介绍。英国是一个极其看重应用的国
家，IT类公司（包括金融、财务公司的软件部门）对于毕业生所看重的是他所掌握的计算机技能，他所经历的项目经验，一句话来说，是知识。如果你没有牢固的
基础知识，比如把OSI七层模型每一层举出一个协议的例子，没有丰富的项目知识，比如Thread.start()是不是表示线程马上启动，那么找技术工
作的进程会不那么顺利。其实这只是一件小事，重要的是，由于全民搞应用，所以你将永远停留在初级程序员的位置上。中国人的口语表达和行为方式很难竞争过本
地人或欧洲人而进入管理层，又没有办法通过展现中国人远超外国人的智商来做一些研究上的突破，公司看重的是技术应用，所以一个程序员就只能这样写按钮，写
图表。中国人的语言劣势已经十分明显的让我们难以在管理、咨询、等非技术方向进行发展，又很难在公司里磨练技术上的提高，看起来无论是有创业大志的，还是
潜心学术的，抑或是安静轻松度日的人，都不太适合留在英国工作，当然还有两种除外，忍耐两年弄一个海外工作经验的人，和稳稳当当做一个小产阶级程序员生活
在英国的人。<br />
    与英国这些做卖飞机票系统的、卖股票系统的公司对比，美国的大公司就比较多，情况要好一点点，这一点与中国的情况很相似。所以，回国或者当初就去美国，会比来英国好。<br /><br />
    总结之，如果你不喜欢做技术，就千万不要再本着忍耐的心理出国学技术，尤其是读博；如果你不喜欢做研究型技术而喜欢做开发型技术人员，那么可以在
国内的公司磨练1-2年再考虑出国，因为国内的OOP教学实在是太不到位了，而国外读书则不能帮你培养开发的能力（因为大多是以科学为主）；如果你非常热
爱研究，那么建议你申请美国的PhD，那里有钱、有更多的机会、更大的国土来观览；如果你什么都不热爱，现在还在茫然之中，那就仔细的在国内考虑自己适合
做的事情，想出国的话以后再出，我现在周围的人除了中国人之外几乎全都不是应届毕业生，所以不要怕自己的年龄。我一直认为找到自己适合做的事情是第一重要
的，不要吝惜花时间去寻找和尝试，你那些以为无法浪费的时间，将来很可能浪费在当前草率的决定上。<br /><br />
    毕业不是表示下一步该做什么马上就要开始，而是提醒你你是否认真的想过自己应该做什么。而由于offer正在不断到来，所以本文对于满腔热情要出国的大四学生的作用不是特别大，低年级的同学们才更应该利用剩下的几年来为自己做决定。<br /><img src="http://www.blogjava.net/flysky19/aggbug/102706.html" height="1" width="1" /><br /><br /><div align="right"><a href="http://www.blogjava.net/flysky19/" target="_blank" style="text-decoration:none;">不断前进的小乌龟</a> 2007-03-09 00:50 <a href="http://www.blogjava.net/flysky19/archive/2007/03/09/102706.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/58366#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 08 Mar 2007 16:50:00 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/58366</link>
        <guid>http://flysky.javaeye.com/blog/58366</guid>
      </item>
      <item>
        <title>测试工具的选择和使用（zz）</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/57153" style="color:red;">http://flysky.javaeye.com/blog/57153</a>&nbsp;
          发表时间: 2007年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          来自：http://www.51testing.com/html/31/1321.html
          <br/>
          <span style="color:red;">
            <a href="http://flysky.javaeye.com/blog/57153#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 03 Mar 2007 16:45:57 +0800</pubDate>
        <link>http://flysky.javaeye.com/blog/57153</link>
        <guid>http://flysky.javaeye.com/blog/57153</guid>
      </item>
      <item>
        <title> 软件测试工具比较(zz)</title>
        <author>flysky</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://flysky.javaeye.com">flysky</a>&nbsp;
          链接：<a href="http://flysky.javaeye.com/blog/57150" style="color:red;">http://flysky.javaeye.com/blog/57150</a>&nbsp;
          发表时间: 2007年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          来自：http://testing.csai.cn/testtools/No284.htm<br />作者： 乔元 　来源：无忧软件测试网 http://www.csai.cn  2005年11月18日<br /><br />    随着软件测试的地位逐步提高，测试的重要性逐步显现，测试工具的应用已经成为了普遍的趋势。目前用于测试的工具已经比较多了，这些测试工具一般可分为白盒测试工具、黑盒测试工具、性能测试工具，另外还有用于测试管理（测试流程管理、缺陷跟踪管理、测试用例管理）的工具。<br /><br />    总的来说，测试工具的应用可以提高测试的质量、测试的效率。但是在选择和使用测试工具的时候，我们也应该看到，在测试过程中，并不是所有的测试工具都适合我们使用，同时，有了测试工具、会使用测试工具并不等于测试工具真正能在测试中发挥作用。<br /><br />    一、 JTEST<br /><br />    １、简介：<br /><br />    jtest是parasoft公司推出的一款针对java语言的自动化白盒测试工具,它通过自动实现java的单元测试和代码标准校验,来提高代码的可靠性。Jtest先分析每个java类，然后自动生成junit测试用例并执行用例，从而实现代码的最大覆盖，并将代码运行时未处理的异常暴露出来；另外，它还可以检查以DbC（Design by Contract）规范开发的代码的正确性。用户还可以通过扩展测试用例的自动生成器来添加更多的junit用例。Jtest还能按照现有的超过350个编码标准来检查并自动纠正大多数常见的编码规则上的偏差，用户可自定义这些标准，通过简单的几个点击，就能预防类似于未处理异常、函数错误、内存泄漏、性能问题、安全隐患这样的代码问题。<br /><br />    ２、优势：<br /><br />    1）使预防代码错误成为可能，从而大大节约成本，提高软件质量和开发效率<br /><br />    2）使单元测试——包括白盒、黑盒以及回归测试成为可能<br /><br />    3）使代码规范检查和自动纠正成为可能<br /><br />    4）鼓励开发团队横向协作来预防代码错误<br /><br />    ３、特征：<br /><br />    1）通过简单的点击，自动实现代码基本错误的预防，这包括单元测试和代码规范的检查<br /><br />    2）生成并执行junit单元测试用例，对代码进行即时检查<br /><br />    3）提供了进行黑盒测试、模型测试和系统测试的快速途径<br /><br />    4）确认并阻止代码中不可捕获的异常、函数错误、内存泄漏、性能问题、安全弱点的问题<br /><br />    5）监视测试的覆盖范围<br /><br />    6）自动执行回归测试<br /><br />    7）支持DbC编码规范<br /><br />    8）检验超过350个来自java专家的开发规范<br /><br />    9）自动纠正违反超过160个编码规范的错误<br /><br />    10）允许用户通过图形方式或自动创建方式来自定义编码规范<br /><br />    11）支持大型团队开发中测试设置和测试文件的共享<br /><br />    12）实现和IBM Websphere Studio /Eclipse IDE 的安全集成<br /><br />    ４、价格：昂贵<br /><br />    二、 JMETER<br /><br />    １、简介：<br /><br />    JMeter是Apache组织的开放源代码项目，它是功能和性能测试的工具，100%的用java实现。使用JMeter进行性能测试<br /><br />    ２、特征：<br /><br />    JMeter可以用于测试静态或者动态资源的性能（文件、Servlets、Perl脚本、java对象、数据库和查询、ftp服务器或者其他的资源）。 JMeter用于模拟在服务器、网络或者其他对象上附加高负载以测试他们提供服务的受压能力，或者分析他们提供的服务在不同负载条件下的总性能情况。你可以用JMeter提供的图形化界面分析性能指标或者在高负载情况下测试服务器/脚本/对象的行为。<br /><br />    ３、价格：未知<br /><br />    三、 JUNIT<br /><br />    １、简介：<br /><br />    JUnit是一个开源的java测试框架，它是Xuint测试体系架构的一种实现。在JUnit单元测试框架的设计时，设定了三个总体目标，第一个是简化测试的编写，这种简化包括测试框架的学习和实际测试单元的编写；第二个是使测试单元保持持久性；第三个则是可以利用既有的测试来编写相关的测试。<br /><br />    ２、优势：<br /><br />    2.1)junit是完全Free的。<br /><br />    2.2)使用方便。在你提升程序代码的品质时JUnit测试仍允许你更快速的撰写程序<br />    那听起来似乎不是很直觉，但那是事实。当你使用JUnit撰写测试，你将花更少的时间除虫，同时对你程序代码的改变更俱有信心。这个信心让你更积极重整程序代码并增加新的功能。没有测试，对于重整及增加新功能你会变得没有信心；因为你不知道有甚么东西会破坏产出的结果。采用一个综合的测试系列，你可以在改变程序代码之后快速的执行多个测试并对于你的变动并未破坏任何东西感到有信心。在执行测试时如果发现臭虫，原始码仍然清楚的在你脑中，因此很容易找到臭虫。在JUnit中撰写的测试帮助你以一种极大(extreme)的步伐撰写程序及快速的找出缺点。2.3)JUnit非常简单撰写测试应该很简单--这是重点！如果撰写测试太复杂或太耗时间，便无法要求程序设计师撰写测试。使用JUnit你可以快速的撰写测试并检测你的程序代码并逐步随着程序代码的成长增加测试。只要你写了一些测试，你想要快速并频繁的执行测试而不至于中断建立设计及开发程序。使用JUnit执行测试就像编译你的程序代码那么容易。事实上，你应该执行编译时也执行测试。编译是检测程序代码的语法而测试是检查程序代码的完整性(integrity)。<br />    2.4)JUnit测试检验其结果并提供立即的回馈。如果你是以人工比对测试的期望与实际结果那么测试是很不好玩的，而且让你的速度慢下来。JUnit测试可以自动执行并且检查他们自己的结果。当你执行测试，你获得简单且立即的回馈； 比如测试是通过或失败。而不再需要人工检查测试结果的报告。<br />    2.5)JUnit测试可以合成一个测试系列的层级架构。 JUnit可以把测试组织成测试系列；这个测试系列可以包含其它的测试或测试系列。JUnit测试的合成行为允许你组合多个测试并自动的回归 (regression)从头到尾测试整个测试系列。你也可以执行测试系列层级架构中任何一层的测试。<br />    2.6)撰写JUnit测试所费不多。使用Junit测试框架，你可以很便宜的撰写测试并享受由测试框架所提供的信心。撰写一个测试就像写一个方法一样简单；测试是检验要测试的程序代码并定义期望的结果。这个测试框架提供自动执行测试的背景；这个背景并成为其它测试集合的一部份。在测试少量的投资将持续让你从时间及品质中获得回收。<br />    2.7)JUnit测试提升软件的稳定性。你写的测试愈少；你的程序代码变的愈不稳定。测试使得软件稳定并逐步累积信心；因为任何变动不会造成涟漪效应而漫及整个软件。测试可以形成软件的完整结构的胶结。2.8)JUnit测试是开发者测试。 JUnit测试是高度区域性(localized)测试；用以改善开发者的生产力及程序代码品质。不像功能测试(function test)视系统为一个黑箱以确认软件整体的工作性为主，单元测试是由内而外测试系统基础的建构区块。开发者撰写并拥有JUnit测试。每当一个开发反复 (iteration)完成，这个测试便包裹成为交付软件的一部份提供一种沟通的方式，「这是我交付的软件并且是通过测试的。<br />    2.9)JUnit测试是以Java写成的。使用Java测试Java软件形成一个介于测试及程序代码间的无缝(seamless)边界。在测试的控制下测试变成整个软件的扩充同时程序代码可以被重整。Java编译器的单元测试静态语法检查可已帮助测试程序并且确认遵守软件接口的约定。<br />    一段测试的程序代码无法单独的执行，它需要是执行环境的一部份。同时，它需要自动执行的单元测试--譬如在系统中周期性的执行所有的测试以证明没有任何东西被破坏。由于单元测试需要符合特定的准则：一个成功的测试不应该是人工检查的（那可要到天荒地老了啊），一个未通过测试的失败应可以产出文件以供诊断修改。而Junit可以提供给我们这些便利.。这样所有测试开发者所需撰写的只是测试码本身了。跟optimizeit、Jtest那些昂贵而又超级麻烦的 tool比较起来，其利昭然可见！<br /><br />    ３、价格：免费<br /><br />    四、 WEBLODE<br /><br />    １、简介：<br /><br />    webload是RadView公司推出的一个性能测试和分析工具,它让web应用程序开发者自动执行压力测试;webload通过模拟真实用户的操作,生成压力负载来测试web的性能。<br /><br />    ２、特征：<br /><br />    １）用户创建的是基于javascript的测试脚本,称为议程agenda,用它来模拟客户的行为,通过执行该脚本来衡量web应用程序在真实环境下的性能<br /><br />    ２）如有需要可以在做负载测试的同时，使用服务器监控工具对服务器端的内容进行记录那样使负载测试更加全面。<br /><br />    ３、价格：<br /><br />    五、 WINRUNNER<br /><br />    １、简介<br /><br />    WinRunner:强大的企业级自动化测试工具<br /><br />    Mercury Interactive公司的WinRunner是一种企业级的功能测试工具，用于检测应用程序是否能够达到预期的功能及正常运行。通过自动录制、检测和回放用户的应用操作，WinRunner能够有效地帮助测试人员对复杂的企业级应用的不同发布版进行测试，提高测试人员的工作效率和质量，确保跨平台的、复杂的企业级应用无故障发布及长期稳定运行。<br /><br />    企业级应用可能包括Web应用系统，ERP系统，CRM系统等等。这些系统在发布之前，升级之后都要经过测试，确保所有功能都能正常运行，没有任何错误。如何有效地测试不断升级更新且不同环境的应用系统，是每个公司都会面临的问题。<br /><br />    如果时间或资源有限，这个问题会更加棘手。人工测试的工作量太大，还要额外的时间来培训新的测试人员等等。为了确保那些复杂的企业级应用在不同环境下都能正常可靠地运行，你需要一个能简单操作的测试工具来自动完成应用程序的功能性测试。<br /><br />    ２、特征：<br /><br />    １）轻松创建测试<br /><br />    用WinRuuner创建一个测试，只需点击鼠标和键盘，完成一个标准的业务操作流程，WinRunner自动记录你的操作并生成所需的脚本代码。这样，即使计算机技术知识有限的业务用户轻松创建完整的测试。你还可以直接修改测试脚本以满足各种复杂测试的需求。WinRunner提供这两种测试创建方式，满足测试团队中业务用户和专业技术人员的不同需求。<br /><br />    ２）插入检查点<br /><br />    在记录一个测试的过程中，可以插入检查点，检查在某个时刻/状态下，应用程序是否运行正常。在插入检查点后，WinRunner会收集一套数据指标，在测试运行时对其一一验证。WinRunner提供几种不同类型的检查点，包括文本的、GUI、位图和数据库。例如，用一个位图检查点，你可以检查公司的图标是否出现于指定位置。<br /><br />    ３）检验数据<br /><br />    除了创建并运行测试，WinRunner还能验证数据库的数值，从而确保业务交易的准确性。例如，在创建测试时，可以设定哪些数据库表和记录需要检测；在测试运行时，测试程序就会自动核对数据库内的实际数值和预期的数值。WinRunner自动显示检测结果，在有更新/删除/插入的记录上突出显示以引起注意。<br /><br />    ４）增强测试<br /><br />    为了彻底全面地测试一个应用程序，需要使用不同类型的数据来测试。WinRunner的数据驱动向导( Data Driver Wizard)可以让你简单地点击几下鼠标，就可以把一个业务流程测试转化为数据驱动测试，从而反映多个用户各自独特且真实的行为。<br /><br />    以一个订单输入的流程为例，你可能希望把订单号或客户名称作为可变栏，用多套数据进行测试。使用Data Driver Wizard，你可以选择订单号或客户名称用数据表格文件中的哪个栏目的数据替换。你可以把订单号或客户名称输入数据表格文件，或从其它表格和数据库中导入。数据驱动测试不仅节省了时间和资源，又提高了应用的测试覆盖率。<br /><br />    WinRunner还可以通过Function Generator增加测试的功能。使用Function Generator可以从目录列表中选择一个功能增加到你的测试中以提高测试能力。例如，你可以选择”calendar”，然后从日历功能的下属目录中选择，如Calendar_select_date(),然后你可以直观地输入参数，把这个功能插入到你的测试中。<br /><br />    针对相当数量的企业应用里非标准对象，WinRunner提供了Virtual Object Wizard来识别以前未知的对象。使用Virtual Object Wizard，你可以选择未知对象的类型，设定标识和命名。在录制使用该对象的测试时，WinRunner会自动对应它的名字，从而提高测试脚本的可读性和测试质量。<br /><br />    ５）运行测试<br /><br />    创建好测试脚本，并插入检查点和必要的添加功能后，你就可以开始运行测试。运行测试时，WinRunner会自动操作应用程序，就象一个真实的用户根据业务流程执行着每一步的操作。测试运行过程中，如有网络消息窗口出现或其它意外事件出现，WinRunner也会根据预先的设定排除这些干扰。<br /><br />    ６）分析结果<br /><br />    测试运行结束后，你需要分析测试结果。WinRunner通过交互式的报告工具来提供详尽的、易读的报告。报告中会列出测试中发现的错误内容、位置、检查点和其它重要事件，帮助你对测试结果进行分析。这些测试结果还可以通过Mercury Interactive的测试管理工具TestDirector来查阅。<br /><br />    ７）维护测试<br /><br />    随着时间的推移，开发人员会对应用程序做进一步的修改，并需要增加另外的测试。使用WinRunner，你不必对程序的每一次改动都重新创建你的测试。 WinRunner可以创建在整个应用程序生命周期内都可以重复使用的测试，从而大大地节省时间和资源，充分利用你的测试投资。<br /><br />    每次记录测试时，WinRunner会自动创建一个GUI Map文件以保存应用对象。这些对象分层次组织，既可以总览所有的对象，也可以查询某个对象的详细信息。一般而言，对应用程序的任何改动都会影响到成百上千个测试。通过修改一个GUI Map文件而非无数个测试，WinRunner可以方便地实现测试重用。<br /><br />    ８）帮助你的应用程序为无线应用作准备<br /><br />    随着无线设备种类和数量的增加，你的应用程序测试计划需要同时满足传统的基于浏览器的用户和无线浏览设备，如移动电话、传呼机和个人数字助理(PDA)。<br /><br />    无线应用协议是一种公开的、全球性的网络协议，用来支持标准数据格式化和无线设备信号的传输。<br />    使用WinRunner，测试人员可以利用微型浏览模拟器来记录业务流程操作，然后回放和检查这些业务流程功能的正确性。<br /><br />    六、 LOADRUNNER<br /><br />    １、简介：<br /><br />    LoadRunner 是一种预测系统行为和性能的负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题，LoadRunner 能够对整个企业架构进行测试。通过使用LoadRunner ，企业能最大限度地缩短测试时间，优化性能和加速应用系统的发布周期。<br /><br />    目前企业的网络应用环境都必须支持大量用户，网络体系架构中含各类应用环境且由不同供应商提供软件和硬件产品。难以预知的用户负载和愈来愈复杂的应用环境使公司时时担心会发生用户响应速度过慢，系统崩溃等问题。这些都不可避免地导致公司收益的损失。Mercury Interactive 的 LoadRunner 能让企业保护自己的收入来源，无需购置额外硬件而最大限度地利用现有的IT 资源，并确保终端用户在应用系统的各个环节中对其测试应用的质量，可靠性和可扩展性都有良好的评价。<br /><br />    LoadRunner 是一种适用于各种体系架构的自动负载测试工具，它能预测系统行为并优化系统性能。LoadRunner 的测试对象是整个企业的系统，它通过模拟实际用户的操作行为和实行实时性能监测，来帮助您更快的查找和发现问题。此外，LoadRunner 能支持广范的协议和技术，为您的特殊环境提供特殊的解决方案。<br /><br />    ２、特征：<br /><br />    １）轻松创建虚拟用户<br /><br />    使用LoadRunner 的Virtual User Generator，您能很简便地创立起系统负载。该引擎能够生成虚拟用户，以虚拟用户的方式模拟真实用户的业务操作行为。它先记录下业务流程(如下订单或机票预定)，然后将其转化为测试脚本。利用虚拟用户，您可以在Windows ，UNIX 或Linux 机器上同时产生成千上万个用户访问。所以LoadRunner能极大的减少负载测试所需的硬件和人力资源。另外，LoadRunner 的TurboLoad 专利技术能。<br /><br />    提供很高的适应性。TurboLoad 使您可以产生每天几十万名在线用户和数以百万计的点击数的负载。<br /><br />    用Virtual User Generator 建立测试脚本后，您可以对其进行参数化操作，这一操作能让您利用几套不同的实际发生数据来测试您的应用程序，从而反映出本系统的负载能力。以一个订单输入过程为例，参数化操作可将记录中的固定数据，如订单号和客户名称，由可变值来代替。在这些变量内随意输入可能的订单号和客户名，来匹配多个实际用户的操作行为。<br /><br />    LoadRunner 通过它的Data Wizard 来自动实现其测试数据的参数化。Data Wizard 直接连于数据库服务器，从中您可以获取所需的数据（如定单号和用户名）并直接将其输入到测试脚本。这样避免了人工处理数据的需要，Data Wizard 为您节省了大量的时间。<br /><br />    为了进一步确定您的Virtual user 能够模拟真实用户，您可利用LoadRunner 控制某些行为特性。例如，只需要点击一下鼠标，您就能轻易控制交易的数量，交易频率，用户的思考时间和连接速度等。<br /><br />    ２）创建真实的负载<br /><br />    Virtual users 建立起后，您需要设定您的负载方案，业务流程组合和虚拟用户数量。用LoadRunner 的Controller，您能很快组织起多用户的测试方案。Controller 的Rendezvous 功能提供一个互动的环境，在其中您既能建立起持续且循环的负载，又能管理和驱动负载测试方案。<br /><br />    而且，您可以利用它的日程计划服务来定义用户在什么时候访问系统以产生负载。这样，您就能将测试过程自动化。同样您还可以用Controller 来限定您的负载方案，在这个方案中所有的用户同时执行一个动作---如登陆到一个库存应用程序----来模拟峰值负载的情况。另外，您还能监测系统架构中各个组件的性能---- 包括服务器，数据库，网络设备等----来帮助客户决定系统的配置。<br /><br />    LoadRunner 通过它的AutoLoad 技术，为您提供更多的测试灵活性。使用AutoLoad ，您可以根据目前的用户人数事先设定测试目标，优化测试流程。例如，您的目标可以是确定您的应用系统承受的每秒点击数或每秒的交易量。<br /><br />    ３）定位性能问题<br /><br />    LoadRunner 内含集成的实时监测器，在负载测试过