<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>yh_private</title>
    <description></description>
    <link>http://yh-private.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>二．	测试的粒度，我们到底应该把粒度控制到多细？</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/221394" style="color:red;">http://yh-private.javaeye.com/blog/221394</a>&nbsp;
          发表时间: 2008年07月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          对于数据不稳定的讨论：<a href="http://www.javaeye.com/topic/221103" target="_blank">http://www.javaeye.com/topic/221103</a><br /><br />是不是一定要测试到具体数值才叫具体？在没有找到新方法之前，想保证测试具体到结果或者说是数值准确，那这个测试代码会表现的非常脆弱，而花费了很多心思去写出完美的测试最后这段测试代码也没有测出任何问题，有些得不偿失了。<br />为什么要写测试？<br />都是为了写出健壮的代码，正确的行为，获得重构的勇气等等。<br />好，如果说写出健壮代码需要写很细粒度的TestCase，而且数据库通常不支持我们这样做。导致测试很难写。<br /><br />我想说，测试是分很多类型的，也可以认为是关注着不同的方向。<br />比如TestCase就要保证我的测试比较完善，包括对结果的验证，边界条件检查等等，这样的测试包括了我们业务代码的方方面面，包括在开发时想到的，没想到的。通过细粒度来提高我们程序的健壮性。也可以说是逼我们写出健壮的代码。<br />在比如TDD，其实TDD所关注的是需求，也就是代码的行为。他要保证业务代码被实现后确实做了我们预想的事情。很多时候我们不太关心TestCase的边界条件，毕竟，客户要件棉袄，这件棉袄可以过冬就行了，而我们花了很多时间做出了一个刀枪不入，甚至能穿着去外太空的棉袄，用户可能永远都不能用上这些花哨的功能。TDD需要小步快跑。不需要笨重的测试代码。<br />    上面两个简单例子他们都能为我们提供重构的勇气。同时可以发现不同的测试方法对于测试的关注点是不一样的。<br />我们的测试应该更多的关注行为。而不是去扣活的数据。数据的准确性是应该在我们开发代码时，最晚也是发布之前一定要确保的。那么我们现在关注的就只有行为，行为是否正确，行为是否被执行。这样对于测试，我们完全可以写出覆盖度非常高而且对数据依赖非常小的测试代码。比如<br />Void TestGetSomeReport(){<br />	List list = someDao.getSomeReport();<br />	assertNotNull(list);<br />}<br />这样就行了，这样的测试关注的是我的Dao是否被执行，如果执行表结构是否支持（如果表结构更变会得到通知）。而且对数据的依赖非常小。我们根本不需要去验证他们。现阶段我们只要保证所有的流程都会在测试中执行，这样就可以了。<br />如果进行重构这些反映代码行为的测试会告知重构者，他们是做什么的，当时的那个程序员的思考过程。这已经足够了，如果你不能保证重构之后的结果依然正确，就暂时不要去触碰他，等你有足够能力去保证产出的代码可以有正确结果之后在考虑这些。<br /><br /><br />由于我们暂时还不能得到稳定的测试数据，所以准备采用测试行为的方式。而更少去关注细节。对于业务型代码，粒度会加细。<br />由于推广测试的路途坎坷，不能一下子全部搞好，所以，准备先以粗粒度进行，并且保证覆盖度。
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/221394#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, 30 Jul 2008 09:42:54 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/221394</link>
        <guid>http://yh-private.javaeye.com/blog/221394</guid>
      </item>
      <item>
        <title>我们到底要怎样才能保持测试数据不变。</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/221103" style="color:red;">http://yh-private.javaeye.com/blog/221103</a>&nbsp;
          发表时间: 2008年07月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一．	数据不稳定，我们能否使用不稳定的数据来写测试？<br />由于我们的测试环境是基于开发数据库，所以数据经常有变化，尤其是统计功能，基本不能对其进行测试。<br />办法一：我们使用Spring-mock提供的事物来解决测试过程中出现的脏数据以及解决测试过程中会改变数据库状态。<br />问题一：由于使用Spring-mock在做测试的时候需要准备大量数据，比如对一个查询进行测试，这个查询关联两张表，就会出现如下场景：<br />对这两张表进行准备数据，new 出很多VO，将关联信息写在VO中，然后调用不同DAO进行持久，之后测试目标代码，如果得到相同结果测试通过。<br />这样需要在onSetUp方法中写很多VO的初始化代码。并且很多统计涉及的表并不止两张。造成初始化的工作量很大，导致大家不喜欢写测试。<br /><br />方法二：就使用现有数据+Spring-mock。这样我们在插入、修改、删除操作时使用Spring_mock,统计或者查询的时候使用数据库中现有数据。<br />问题二：由于使用开发数据库中的现有数据进行测试，导致开发数据库中数据一旦更变就会出现测试跑不通的情况。程序员又要回来修改以前的测试代码，而且是因为数据库中数据变化导致错误。很影响程序员写测试的积极性。导致大家又不写测试了。<br /><br />方法三：使用DBunit和Spring-mock进行测试。DBunit负责保证测试时数据不变，Spring-mock提供事物处理。<br />问题三：由于DBunit在团队中普及度并不是很高，如果使用需要培训。而且需要程序员自己去维护XML，虽然提供了导出的接口和方法，但维护起来相对比较麻烦，而且在进行单元测试时需要插入的数据太多，导致测试效率低下（一张表的单表维护大概要3倍以上的时间）。总之属于很耗费资源而且成本偏高。并且一但表结构改动，相关的测试数据需要重新维护一次。<br /><br />方法四：使用TestDB+Spring_mock，TestDB保证本身数据不变化。培训成本为0。<br />问题四：如果使用TestDB来测试，如果表结构改变，就需要同步开发数据库以及测试数据库。如果进行了同步，相关的数据也会变化。导致测试失败。<br /><br /><br /><br /><br />以上是在我们测试的时候所遇到的一些问题，不知道大家都是如何解决测试数据不变问题的。简单总结过后发现自己心情好多，希望大家可以提供一些意见和方法。我们都是为了写出健壮的代码，正确的行为，获得重构的勇气。<br />加油！！！
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/221103#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>Tue, 29 Jul 2008 15:04:00 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/221103</link>
        <guid>http://yh-private.javaeye.com/blog/221103</guid>
      </item>
      <item>
        <title>丁磊：那时候我们除了会写软件,什么也不会做</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/216437" style="color:red;">http://yh-private.javaeye.com/blog/216437</a>&nbsp;
          发表时间: 2008年07月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          丁磊：那时候我们除了会写软件,什么也不会做<br />关键字: 丁磊：那时候我们除了会写软件,什么也不会做<br />丁磊：那时候我们除了会写软件,什么也不会做　<br />[ 2007-3-3 19:56:00 | By: alibaba ]<br /> <br />丁磊：那时候我们除了会写软件 什么也不会做<br /><br />--------------------------------------------------------------------------------<br /><br />2006.05.24    <br /><br /> <br /><br />经历过的事情是一种收获。我是学工科的，我今天演讲的主题，选了李白的《行路难》：“长风破浪会有时，直挂云帆济沧海”，其实前面还有两句：行路难，行路难，多歧路，今安在？我有时候自己也不知道创业，从93大学本科毕业到现在，12年来怎么走过来的，跌跌撞撞，非常契合。<br /><br />其实我也和在座的大家一起，我自己不认为自己是一个非常聪明和有智慧的人。我在89年考大学，我是班上第10名，只高出重点分数线1分。我隔壁班的同学现在是你们浙大的老师，他当时是第一名呀，他高考的分数刚好比我高出100分。<br /><br />我当时89年的时候，看学校的介绍，叫电子科技大学，这个大学1956年成立的，在四川成都，我也不知道成都在什么地方，我看它地处天府之国应该挺好玩的，我不想在浙江读大学，就填了志愿电子科技大学，没想到第一批就收到录取通知书了。其实我填的专业的也是很被动的，坦白地讲我在中学的并不是一个成绩非常优秀的学生。我在读初中的时候，我们所在的中学从来没人考上过大学，好在我在高中考上了奉化一中，我在奉化一中的第一学期，全班54个人，我的成绩倒数第6 名，还被老师痛骂一顿，说你们这6个人拖了班上后腿，我<br /><br />印象非常深刻。后来我的成绩慢慢上升，考大学的时候最好，上升到班里的第10名。<br /><br />我在选择专业的时候，我很喜欢电脑，我在高中时候就在苹果电脑上写游戏，我自学完了 BASIC语言。我很想选计算机专业，我父母说什么专业都可以选，计算机不要选，因为计算机对人体有害，你每天坐在电脑前就像照X光。这个说法不是没道理的，因为当年计算机显象管的辐射的非常大的，对健康多少是有影响的。所以，我就填了成都电子科技大学的通讯专业，我被分到了全校最小的系——微波通讯，一个系只有30个人。我有个同乡说，你们这个系历来是最难分配的，而且分配之后的地方也非常不好，通常要跑到山沟沟里去，因为微波和卫星通讯都是在边远的农村。所以我在大学四年的时候，挺郁闷的，认为自己的专业不好。<br /><br />我那时经常跑图书馆去看计算机方面的书，还到计算机系里坐到后面去蹭课旁听。我觉得我在大学最大的收获就是学习方法，我可以坦诚地对同学们说，我在大学里学到的知识在我后来的工作里基本上就从来没有用到过。我经常在上课的时候看另外专业的书，每次到考试前我只要把书翻出来，复习一个星期就足够了。我在97 年开始搞互联网的时候，没有几个人能教你互联网是什么，关于互联网的书还非常少，我印象中 TCPIP的书还要请别人吃饭才能借到，而且看书的时候要不停做笔记，因为那时候原版书非常少。我上大学的时候，如果对课程感兴趣，基本上能快速地掌握和领悟，这样的学习过程对我后来创业影响非常大。<br /><br />后来我自己也在思考，为什么我还比较顺利，我觉得我蛮顺利，我想有一点要向今天的同学们交流——你一定要做你喜欢做的事情，你不要勉强自己去干一件自己不喜欢的事情，这我觉得是非常非常重要的。当你喜欢做一件事情的时候，你一定很愿意把它做好，一定会钻进去，会成为一个领域的专家。我从高中毕业1986年到2005年，我根本没有离开过计算机相关专业领域，一个人像我这样专注于一个行业将近20年，当然也会成为一个专家。所以同学们喜欢一件事的时候，一定要深入下去，不要浅尝辄止，这是我非常深刻的一个体验。我前些日子在网上看一篇文章，苹果电脑创始人史帝夫.乔伊斯在读大学的时候退学，他发现大学的英文书法很好，就去听英文书法的课。他说英文书法的课对他日后创建苹果电脑公司有巨大的帮助——他发现电脑用来做排版没有一点艺术性可言，所以他把苹果电脑一出来就定位在艺术家专用的排版服务，而且他把大学里学习的书法艺术利用到了苹果电脑排版软件中，他第一个发明了人机交换图形操作界面，这一灵感完全来自于他读大学时对书法的爱好。所以我给同学们的一个建议就是，如果你在读大学的时候喜欢一件事情，就一定要深入下去。<br /><br />我在读大学四年的时候，有一件事情很辛苦，我每年四此往返宁波和成都，都是坐72个小时的火车硬座，我读大学时候从来没坐过一趟飞机。我后来在创业时候，回想到当年坐火车那么脏、那么拥挤，这种环境都过来了，创业时候遇到点困难算什么？对我人生的磨砺很大，这点我要感谢我的父母，他们一直不鼓励我坐飞机或者卧铺，他们说：你长大了，你应该自己去开拓，人生有甜也有苦。我非常感谢父母对我的教育。<br /><br />我1993年分配到宁波电信局，我在哪里度过了将近2年，我不喜欢电信局那里的环境，论资排辈很严重，年轻人没有什么机会，同时每天做的工作又是重复和枯燥，没有一点创新性，没有一点开拓。1995年的时候，我一个人离开宁波去了广州。那时我要离开电信局的时候，电信局领导说：“我们这里从来没有大学生辞职的，你是国家培养的大学生，你怎么能够辞职？”单位说不能辞职，只能除名。后来到了 1995年4月，我跟领导说，我明天不来上班了，十几天后单位出了个文件，说丁磊旷工两个多星期，被除名了。<br /><br />我去广州之前经过选择。我在宁波时候就考虑过，95年时候的浙江不是一个做IT的好环境，比较保守。我的几个朋友对我说，广州自从邓小平南巡讲话后，经济发展很快；而且临近香港，人的思想意识都比内地开放。所以我一个人提个皮箱，辞职以后就跑到广州去了。<br /><br />到广州第一步是找个工作糊口，我当时找了一个美国的数据库公司Sybase找了份编程的工作。工作之余，我开始寻思创业的问题。当时没有人可以教我怎么创业，我父母都是国企员工，那时也没有一本书教你怎么当个老板。广州当时就有些年轻人很积极地办公司创业，这个给我启发很深刻。<br /><br />我在1997年5月的时候创办了网易公司，那时中国的互联网用户不到10万人。我们取名叫“网易”的意思，就是希望上网变得容易一点，这是一个很简单的想法。当时开公司要2个人，2个身份证，我就问朋友借了一个身份证，2个人到工商局去登记注册。在登记之前，我跟朋友说，我们要写个合约，合约中规定你要把股份无条件地转让给我，因为我是唯一的出资投资人。<br /><br />注册好了之后，我们找了一个很小的房间，大概只有8平方米，没空调，很热。我们成立网易后的第一个业务是帮人家写软件，先生存下来。有一天我和几个同事在商量，我们做互联网一定要找到一个好的商业模式。我们发现我们电脑的硬盘很大，有9个G的容量，大家不要笑，在1997年的时候，9个G的电脑硬盘是当时最大的了，不像现在硬盘可以有300G、500G。而我们当时网易的网页页面一共才3页，加上图片1M都不到。我当时和我同事说，9G的硬盘浪费了好可惜啊，要不我们做个免费的个人主页吧！于是我们就推出了 20M的免费个人主页业务。就是这样一个非常简单的想法，对我们的公司产生了巨大的影响。我们当时抱着一个好玩的心态，做免费个人主页，给中国不到10万的互联网用户，让大家上传个人主页到我们一台服务器上。结果很莫名其妙的，我的印象中有2万多个人，包括国外的人，来申请我们的免费个人主页。结果我们在 CNNIC的年度最佳网站排名，我们就排到了第一名。<br /><br />自从我们被CNNIC排到中文优秀网站第一名后，华尔街的投资人就在我们门口排队了，我是隔三差五地接待香港过来的投资银行的人，他们抢着要给我们钱。那时候是1998年中，我们公司才10个人左右。那时候我们除了会写软件，什么也不会做，我们当时开发了一套免费电子软件，我自己当销售，我另外两个搭档是开发软件的，我就拿着<br /><br />软件到处卖，我们卖得挺贵的，一套软件能卖10万美金。投资人认为我们这个10个人的小公司很厉害，又能写软件又能赚钱。<br /><br />我们当时的机会真的是很好的，非常重要一点就是把公司开在广州，离香港近，风险投资银行主动找我们，要给我们钱。从1999年年初到2000年6月30日美国上市，18个月时间我们一共融资了1亿1千5百万美金。我作为公司的领导，不知道那么多钱怎么用，感到很困惑。公司本来是赚钱的，搞上市之后，不但不赚钱，而且老亏钱。我们当时的主要业务是网络广告，而2000年7月以后，全球互联网泡沫破灭，纳指从50000点跌到了1500点，市值蒸发了2/3。<br /><br />所以我在2000年的时候，我也面临着一个很大的转型。创办网易的时候，我只是想做一个小老板，我从来没有一个远大的理想，从来没有想要成为一个很有钱。我那时的理想就是，有个房子有辆汽车，不用准时上班可以睡懒觉，有钱可以出去旅游。你们千万不要以为我当时抱着一个伟大的理想去创办一个伟大的公司，绝对没有这个想法。<br /><br />到2000年以后，我们面临一个非常大的挑战，除了经济衰退，网络广告大滑坡，公司内部也面临了严重的问题。我那时很苦闷，员工也很没信心，不知道公司该往哪里走。<br /><br />我觉得当时有件事情做得很对，我苦闷的时候不是每天闷在办公室里，而是自己跑下去做市场调查，问了好多人，调查过好多行业，去调查人家怎么赢利。我后来发现了短信业务，一毛钱一条短信，成本只要5分5厘，我非常积极地与移动合作。我说，网易有用户，有邮箱，有免费个人主页，如果我们每月从一个用户身上赚一块钱的话，<br /><br />我们公司就能赢利持平。就这么一个很简单的4分多钱的生意，我们跟移动合作，利用自己巨大的用户资源和移动的接入平台，我们从广告的阴影中走出来。<br /><br />第二件事情，我跟我们同事说，我们做网页这个东西没有多少技术含量，我们每次出现点有创意的东西，我们的竞争对手新浪搜狐他们老抄我们，而且抄的速度很快。我说我们一定要做一个东西出来，技术含量很高，这帮人抄不了。所以我们决定做游戏，做网络游戏。其实网络游戏这个东西，我在1996年的时候就打过主意，那时侯主要是文字MUD。到了2000年，索尼和EA已经开发出了图形的网络游戏，我就找索尼和 EA，要做代理把他们的产品引进到中国。但是索尼和 EA公司很高傲地说，不和中国公司合作，说中国都是盗版，不考虑中国市场，他们就直接把我赶出来。我回来之后很生气，我就对同事们讲，第一个，老美能做出来的东西，我们也一定能够做出来；第二个，我们有钱。我们虽然从来没有做过游戏，但我们可以出钱买一家做过游戏的公司。<br /><br />我后来在广州找到一家很小的公司，跟我几年钱创业的时候一样，7、8个人拨号上网在做游戏。我问他们怎么做游戏，他们一五一十地跟我说了，我就把他们这个公司买下来了，很便宜的，花了30万美金。我对网络游戏的信心非常强，因为网络游戏能防止盗版。网络游戏做出来之后，必须联到服务器上才能玩；同时网络游戏的技术含量相对高，我相信我的竞争对手像新浪抄不会，抄起来要很漫长。买下这个公司后，我还抽调了公司最优秀的技术团队过来参与开发游戏。<br /><br />游戏开发的时间很漫长，我们从2001年开发，到2002 年1月的时候，出来了第一款网络游戏产品——《大话西游》，结果这个游戏是失败的。失败的原因是，我们有一个工程师想创新，在我们的游戏客户端里嵌入了一个IE浏览器，结果这个IE5.0浏览器很不争气，经常导致游戏客户端crash，电脑要重启。<br /><br />我没有放弃，我对我们同事说，能不能重写一下，我的目标是稳定。同事说，老板没问题，给我们 6个月时间。2002年6月，我们的《大话西游2》诞生，从客户端到服务器都很稳定。但是开始的时候用户不多，大概只有3000人。我对同事说，不要怕，只要产品好，我去做营销。我当时也不知道怎么做营销，所以我就买了好多营销的书一个人看。光看书没有用，我翻开通讯录找。我想，中国谁的营销做得好，我去请教他总可以吧。后来我就找到了步步高的老总段永平，他当时在东莞。我找到他的名片后，就打电话给他请教，能不能去拜访他，他很客气地说：“那你就过来吧”。见面之后，我就请教他营销怎么做。我就是这样一边看书一边请教学习营销知识的。我们的《大话西游2》，也是从最初的3000人的规模，到现在最高在线人数达到55万人。<br /><br />我总结《大话西游2》的成功营销原则是，（1）我们的定价原则，我们定了市场上最高的价格。当时市场上别人都是三毛钱一小时，我四毛钱一小时，当时我的同事听说我定四毛钱一小时都认为我发疯了，韩国游戏都只有三毛钱一小时，你敢定四毛钱一小时？我说我敢这样定，是因为真正想玩这个游戏的人不会在意这一毛钱，在网吧玩一小<br /><br />时就就需要2元钱，产品好多一毛钱是值得的。而四毛钱和三毛钱相比，给公司增加了33%的利润，在公司起步阶段是非常重要的。（2）我们从来不做短期利益的事情，那时很多游戏都有包月，一个月35元或者40元可以无限制玩。我说我们千万不要做包月制度，首先包月会缩短游戏的寿命；此外我们做游戏的目的，是 “你玩游戏”而不是“游戏玩你”，包月制度会造成玩家过度沉迷。由于不包月产生的经济压力，我们的玩家相对都比较理性。而我们的竞争对手，由于包月，把游戏产品的寿命缩短了。前几年整个市场上大概有140多个游戏，其实真正做得好的就这么5、6个，真正赚到钱的也就是这么三四家公司。<br /><br />所以我想对大家说的是，我在做企业的时候，是个不断学习的过程，从来没有人教过我们怎么运作这个公司。做企业的时候，一些优秀的人才对公司非常重要。我认为虚心求教和咨询很重要。同时，我认为公司人才储备很重要。公司人不是越多越好，而是优秀的人才越多越好，一个出色的人才能顶好几个人。<br /><br />我们希望，员工在这个公司的时候是自己的兴趣，因为有兴趣你才会钻进去；第二个要“自我学习，自我管理”，要有不断进取的精神。这个行业进步很快，你不学习就会落后。我们当时派过去作游戏的几个工程师，自己都是非常热爱游戏的，所以他们能把游戏做好。<br /><br />我要跟大家分享的是，“信心“很重要。2001年的时候，我刚开始做游戏的时候，所有的媒体所有的同行都说我疯了。那时候的报纸我还留着，都是一片责骂声。员工也不相信。但我有信心。结果呢，当时说我们坏话的儿女，他们现在都眼馋我们了。所以我送一句话给大家：”有信心不一定会成功，但没有信心一定不会成功。”<br /><br />除了“信心”，我要跟大家讲的另外一个单词是“付出”。我们做企业那么久，每个项目时间很长，做游戏三年，做免费邮箱则是从1998年到2006年，积累了大批免费用户。我始终相信一句话：“付出不一定有回报，但是不断地付出，你一定有回报。” <br /><br />我觉得“创新”是个很危险的事情，我这个公司到今天，我很害怕创新。我觉得创新的风险非常大，尤其对于新公司来说，一不小心创新就把一家公司搞死了。创新的风险为什么大？首先创新需要很多钱，其次创新的东西需要用户有一个逐步接受的过程，还有创新要克服很多技术难关。<br /><br />我坦白地讲，如果你要创新的话，你首先要把别人的东西搞明白了，摸透了，你再去搞创新。我看一本书讲微软公司的。微软公司的很多产品都不是自己发明的，譬如window，word和excel等等，都是follow别人的，但是它不断地做，不断地改进，就做成功了。所以我说，我们一定要做正确的事情，这个在我们企业里叫战略，战略要正确，动作可以慢，但战略一定要正确，看准了再跟上去，这样风险比较小，这样别人犯过的错误就不会再犯。我们现在在制定营销战略的时候，都首先看我们的竞争对手在干什么，他们做完了，我们把他们的问题全都找出来，这样我们就不再犯了，少走很多弯路。<br /><br />但是，你光有“战略”不行，还需要“执行”，要正确地做事。我们认为人是关键，同样的事情，不同的人做出来是不同的。微软的成功，<br /><br />跟他的创始人非常专注在产品上很有关系。所以我说，一个企业的成功，产品是最至关重要的。我现在很郁闷，一些媒体老是说资本运作，我到现在搞不清楚资本运作是怎么回事情。现在很多企业沉迷于兼并和收购，我最不敢作收购和兼并，我觉得兼并和收购我看不懂。我公司除了20001年收购了这个7、8人的游戏公司外，没做过收购兼并。做事情就是踏踏实实地，把你的产品做好，当你的产品做得好，赢利才是顺理成章的。<br /><br />最后，我觉得我在做企业的过程中一直在学习。网易现在已经成为中国互联网行业中赢利能力最高的公司，我们现在有1800人，其中还包括400个客户服务人员。我做梦都没想到我有朝一日会掌握一家赢利超过2亿5千万人民币的公司，我也是一路跌跌撞撞，边打边学的走过来的。我最后要送给同学们两句话，是句英语的 <br /><br />stay hungry 保持饥饿的状态，stay fulish 保持充实，保持求知状态，因为只有这样，你在人生的路上才能不停地进步。<br /><br /><br />回答同学们提问： <br /><br />问：您最喜欢的书是什么：<br /><br />答：如果你们对管理感兴趣的话，我推荐三本书《基业常青》、《从优秀到卓越》、《你的灯还亮着吗？》此外，我最近看得比较多的是《道德经》等哲学方面的书。<br /><br /><br />问：您对网易的未来设想是什么？<br /><br />答：网易要做优秀和卓越的中国互联网服务公司，能够为未来2亿的中国网民服务。我们要把产品做好，这是我的人生目标。而且我想证明，外国人能做好的产品，我们也能做好，譬如我们的免费邮箱就做得比外国好。<br /><br /><br />问：中国的富豪似乎不太热衷慈善事业，您怎样认为？<br /><br />答：我认识的几个富豪朋友，都对慈善事业很关心，但中国目前的情况下做慈善事业不够成熟。我今年1月5日，我捐助了1000万人民币给中国红十字会，捐给印度洋海啸。我其实很想做慈善，但找不到好方法，我很担心中国慈善机构的执行能力。但我有一点可以告诉大家，我一生用不掉那么多钱，我也不会把多余的钱留给我孩子，也不希望孩子继承公司，我想等环境成熟时候，有更多的时间能服务中国慈善事业。<br /><br /><br />问：您刚才说不喜欢兼并其他公司，我想问的是，你是否考虑过网易公司是否会被别人兼并。<br /><br />答：我认为网易被别人收购的可能性不大，首先我个人是个超过股份50%的大股东，如果我不愿意，收购不太可能会成功；此外，阻止恶意收购还有“毒丸计划”这样的方式。<br /><br />问：网易和其他竞争对手似乎没什么不同？网易未来会采用什么什么新的形式？<br /><br />答：我觉得专注能把一件事情做好是非常不容易的事情。有人问我，你应该多一点东西啊？譬如我们的邮件系统，能把这个系统做好，已经是个非常不容易的事情了，譬如反垃圾，反病毒。加一些花里胡哨的东西，不是一个理性企业的选择。虽然是一个邮箱，但竞争对手很难超越我们。<br /><br />我很佩服你们杭州的一个企业家——娃哈哈的宗庆后，我很佩服他。我说你能把卖水都做成这样，不容易啊。水的产品差异化很小，但水是生活中的必需品。我去年去新疆的喀那斯玩，在山沟沟里，没有可口可乐，却有娃哈哈的非常可乐。水这样的产品，再过十年还是这样的一瓶水。我觉得有时候做企业就是这样，在一个领域里做深做精了非常不容易。美国可口可乐，这么多年就做可口可乐；吉列这么多年来一直只做刮胡须刀；把一个产品做深做精很重要。<br /><br /><br />问：网易游戏部门的长远发展规划是什么？<br /><br />答：游戏的成功，除了产品好，还有渠道好，还要定价好，很多相关因素在里面。在我们游戏部门中，我们有很多经验可以共享，我们有很多失败的教训可以汲取。<br /><br />未来中国的游戏市场非常大，我们目前有四个游戏在同时做。我们认为做游戏非常关键的一点是“设计者的水平”，就像一部电影导演比演员更重要。我认为未来游戏的成功在于设计游戏的玩法上，这个很重要。<br /><br /><br />问：最后，我要代表所有毕业生问您，假设您现在是个毕业生，您有两个选择，一是出去创办一个未来可以成为像网易这样成功的公司，二是在网易这样一个成功的公司工作，您会选择哪个？<br /><br />答：我不鼓励毕业之后马上创业，因为你的经验不够，你会跌得很惨，甚至跌倒后站不起来。我当年就跌过一次，我们网易被停过牌，还被美国小股东告过，好在我们运气好，活过来了。如果我今天是个毕业生，我一定会找一个我喜欢的工作，而且我会努力把这个工作做好。现在很多同学投简历，是为了解决自己就业的问题。我建议同学们在毕业时候找工作时候，一定要找一份自己喜欢的工作，把自己的兴趣放进去。只要你有信心，坚持努力，终有一天你会心想事成的。
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/216437#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, 19 Jul 2008 09:25:32 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/216437</link>
        <guid>http://yh-private.javaeye.com/blog/216437</guid>
      </item>
      <item>
        <title>体验结对编程</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/201056" style="color:red;">http://yh-private.javaeye.com/blog/201056</a>&nbsp;
          发表时间: 2008年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          体验结对编程一周多的时间，遇到诸多问题和大家分享一下。<br />两名程序员，<br />一名为编程老手，有丰富的开发经验经常可以提供一些非常好的想法，只是对业务不够熟悉。<br />另一个是个菜鸟，但进入团队时间较早对业务也相对熟悉。<br /><br />两人形成互补型结对组。<br />故事：<br />由于老手（A）并不熟悉业务，而且时间箱规定时间紧迫，第一周由菜鸟程序员（B）进行主要的开发工作，<br />AB两人在会议室简单沟通需求和场景后，进入开发阶段。B希望可以一边开发一边让A尽快熟悉业务以及相关API，<br />B（菜鸟）在开发时遇到一些关键需求时总要停下来和A程序员交流，包括使用到以前定义好的类和业务上下文。<br />有时两人会因为过去的代码不够简洁而讨论新的方案。<br />直到周六的下午（时间箱规定周六交付一个可以使用的版本），程序员B突然拍着自己的脑门大叫一声：晕~！！忘了一个需求。而且是关键性需求。<br />这导致近3天的工作付诸东流。需要重新考虑。<br />周六下午。程序员B很是郁闷。在会议室里苦苦思索为什么会出现遗漏。。。。。。<br /><br />原因分析：由于老手A并不熟悉业务上下文，不能参与前期准备。只有程序员B知道下一步应该做什么。而B在开发中经常与A交流关于业务上的事情，导致编程思路不流畅。经常需要分神去解释和讨论，经过一段时间之后又回到自己的代码上。<br />开发过程由原来的：测试——开发——重构——测试    <br />变成了：测试——开发——讲解——讨论——开发——重构——测试  两次开发之间经历了漫长的讨论与讲解。导致菜鸟程序员精力不够，甚至出现致命的遗留问题。<br /><br />之后两个人在会议室里分析了问题的原因，由于此时已经经过了一周的结对开发，程序员A也对需求渐渐明朗起来。<br />此时两人都意识到这样的开发过程过于缓慢。原计划2天完成的任务干了3天还遗漏需求。经过商讨决定下周实行新办法：两人一起站在白板前探讨需求，程序员A不明确的地方由B在这个时候进行说明，以及两个人的讨论都在这个时间进行，开发回归  测试——开发——重构——测试
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/201056#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>Fri, 06 Jun 2008 21:28:44 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/201056</link>
        <guid>http://yh-private.javaeye.com/blog/201056</guid>
      </item>
      <item>
        <title>反射私有方法</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/183345" style="color:red;">http://yh-private.javaeye.com/blog/183345</a>&nbsp;
          发表时间: 2008年04月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          任务概述:今天黄俊兄发现把构造方法私有化之后，Spring一样可以把Bean实例创建出来,于是乎,找了一下午的答案，在老张的提点下,得出了结果,还是用的反射，以下是总结. <br /><br />1.私有构造函数的调用:<br />主要的类:java.lang.reflect.Constructor <br /><br />首先要拿到构造方法，具体如下：<br />Class clazz = Class.forName("Bean");  <br />Constructor[]  cons = clazz.getDeclaredConstructors();<br />这样拿到的cons数组保存着所有的这个类的构造函数，包括私有的和公有的。<br />迭代并调用con.toGenericString()可以拿到每个构造方法的全限定名(带修饰符，带参数)。<br />如果要拿单个构造方法，可以调用getDeclaredConstructor(Class args);来拿，只要参数匹配了就可以得到，如果没有参数，则传null即可。   <br /><br />然后需要调用Constructor的方法setAccessible设置为true，表示允许使用私有构造函数。这个方法是父类AccessibleObject的方法，这个类的自类有Constructor, Field, Method分别代表构造函数，成员变量，和成员方法。也就是说使用这个方法，可以访问类的所有的方法、变量、构造函数。   <br /><br />最后，使用Constructor的newInstance方法就可以把对象创建出来了：<br />Bean bean = (Bean)con.newInstance(Object args);<br />没有参数的构造函数可以传null进去。  <br /><br />2.调用私有的方法：<br />主要的类：java.lang.reflect.Method <br /><br />首先还是要拿到那个私有的方法，可以调用<br />Method[] ms =  clazz.getDeclaredMethods();来拿到所有的方法的集合。<br />也可以拿某个单独的方法：getDeclaredMethod(String name, Class... parameterTypes)匹配名字和参数的方法会被拿到，方法若没有参数传null.<br />同样可以调用toGenericString()看全限定名。 <br /><br />然后同样需要调用setAccessible(true)来设置可以方法私有方法。 <br /><br />最后，就可以使用method.invoke(bean, Object args);来调用这个方法。两个参数分别是对象，和这个方法的参数。 <br /><br />3.调用私有成员变量,也叫字段。<br />主要类：java.lang.reflect.Field <br /><br />首先还是要拿到要使用的字段：<br />还是两种，拿全部：Field[] fs =  clazz.getDeclaredFields();<br />拿某个:clazz.getDeclaredField(String fieldName); <br /><br />老步骤：setAccessible(true) <br /><br />最后， f.get(obj) ，就能拿到传入对象的私有变量。 <br /><br />测试: <br /><pre name="code" class="java">
MyBean.java : 

package cn.yzj.entities; 

public class MyBean
{
 private String name;
 private Integer age;
 
 private MyBean()
 {
  this.name ="ABC";
 } 

 private MyBean(String name,Integer age)
 {
  this.name = name;
  this.age = age;
 }
 
 public String getName()
 {
  return name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
 
 private void printName()
 {
  System.out.println(this.name);
 }
} 

</pre><br /><br />Test1.java: <br /><pre name="code" class="java">
package cn.yzj; 

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; 

import cn.yzj.entities.MyBean; 

public class Test1
{
 public static void main(String[] args) throws ClassNotFoundException,
   IllegalArgumentException, InstantiationException,
   IllegalAccessException, InvocationTargetException,
   SecurityException, NoSuchMethodException
 {
  Class clazz = Class.forName("cn.yzj.entities.MyBean"); 

  // 获得私有成员变量并返回.
  // getField(clazz); 

  // 调用私有方法
  // getMethod(clazz); 

  // 用私有构造方法构造对象并返回.
  // getConstrutor(clazz); 

 } 


 //用私有构造方法构建实例的方法
 private static MyBean getConstrutor(Class clazz)
   throws NoSuchMethodException, InstantiationException,
   IllegalAccessException, InvocationTargetException
 { 

  // 拿所有的构造方法.
  /*
   * Constructor[] cons = clazz.getDeclaredConstructors(); for(Constructor
   * con : cons) { System.out.println(con.toGenericString()); }
   */ 

  // 1.拿无参数的构造方法.
  Constructor con = clazz.getDeclaredConstructor(null); 

  // 2.设置可以访问.
  con.setAccessible(true); 

  // 3.创建实例
  MyBean myBean = (MyBean) con.newInstance(null);
  return myBean;
 } 

 private static Object getField(Class clazz) throws NoSuchMethodException,
   InstantiationException, IllegalAccessException,
   InvocationTargetException
 {
  MyBean myBean = getConstrutor(clazz); 

  Field[] fs = clazz.getDeclaredFields(); 

  for (Field f : fs)
  {
   System.out.println(f.toGenericString());
  } 

  fs[0].setAccessible(true); 

  return fs[0].get(myBean);
 } 

 private static void getMethod(Class clazz) throws NoSuchMethodException,
   InstantiationException, IllegalAccessException,
   InvocationTargetException
 {
  MyBean myBean = getConstrutor(clazz); 

  Method[] ms = clazz.getDeclaredMethods(); 

  for (Method m : ms)
  {
   System.out.println(m.toGenericString());
  } 

  ms[0].setAccessible(true); 

  ms[0].invoke(myBean, null);
 } 

}
</pre><br /><br />原文在http://groups.csdn.net/itcast_6/topic/8e48d424-be3a-48cf-9708-e09866ac695d.aspx
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/183345#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, 16 Apr 2008 13:25:43 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/183345</link>
        <guid>http://yh-private.javaeye.com/blog/183345</guid>
      </item>
      <item>
        <title>关于测试facade的一点想法</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/182879" style="color:red;">http://yh-private.javaeye.com/blog/182879</a>&nbsp;
          发表时间: 2008年04月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          很肤浅的想法，希望大牛多多指点<br /><br />原来的façade代码<br /><pre name="code" class="java">
public class XxFacadeImpl implements XxFacade {
    public List doSomeThing(String param1) {
        //1组装查询条件
        XXVO xxVO=new XXVO();
        xxVO.setParam(param);
        //2.通过条件查询数据库已获得相业务数据
        List xxList = xxDao.getXXList(xxVO);        //Dao逻辑1
        //3.基于xxList的业务计算
		XXVO xxVO1 = new XXVO();              //业务逻辑1
        For(int i=0;i&lt;xxList.size();i++){
			xxVO1 = (XXVO) xxList.get(i);
			xxVO1.setName(String.valueOf(i));
}                          
        //4.把计算结果更新到数据库
        xxDao.updateXXList(xxList);                 //Dao逻辑
        //5.做其他事                               //业务逻辑 2     
        return xxList;
    }
}
</pre><br />这样的代码很常见，但是这样把业务代码和持久层方法调用写在一起的方法却很难被测试，如果想测试这样的方法大概的流程如下<br />1．	在数据库中准备符合条件的数据(insert)符合param1的查询条件<br />2．	调用XxFacadeImpl的doSomeThing（1）方法<br />3．	得到返回的List 验证业务逻辑1是否正确<br />对于这样的代码可以勉强测试，但是却相当麻烦，首先要建立测试数据，要想着自己所查询的表是否有关联，如果有还要一同插入测试数据，否则Dao逻辑1将不能得到数据，导致测试失败，测试之后还需要把数据回滚，不然数据库中就会留下垃圾数据。<br />很明显我们的façade并不关心Dao的实现或者表中的数据，但为了测试这个方法却要模拟这样一个环境。然而对于业务逻辑2中的代码我们如何测试呢？这只是一个勉强可以测试的Façade方法因为他所操作的数据正好是这个方法的返回值，我们简单修改一下这段代码<br /><pre name="code" class="java">
public class XxFacadeImpl implements XxFacade {
    public boolean doSomeThing(String param1) {
        //1组装查询条件
        XXVO xxVO=new XXVO();
        xxVO.setParam(param);
        //2.通过条件查询数据库已获得相业务数据
        List xxList = xxDao.getXXList(xxVO);        //Dao逻辑1
        //3.基于xxList的业务计算
		XXVO xxVO1 = new XXVO();              //业务逻辑1
        For(int i=0;i&lt;xxList.size();i++){
			xxVO1 = (XXVO) xxList.get(i);
			xxVO1.setName(String.valueOf(i));
}                          
        //4.把计算结果更新到数据库
		//upadateXXList(xxList)将返回更新是否成功
        return xxDao.updateXXList(xxList);            
    }
}
</pre><br />只是简单的修改了一下方法的返回值，我们现在只关心这个update 方法是否成功.<br />那怎么才能测试业务逻辑1呢?<br /><br />总结一下，<br />不可测试方法：这样的Façade很难被测试，甚至有些部分不能被测试或方法中的逻辑根本不能被测试，<br />垃圾数据：会在数据库中留下大笔的垃圾数据，虽然可以通过继承TestDaoConstant来自动回滚，但Façade业务本身是不需要事务的，如果引入mock来做孤立测试，Mock带来的复杂度也将被引入。<br />代码复用：这样的代码通常很难被复用。<br />测试覆盖度：由于方法中有不可测试部分也就不能保证测试的覆盖度。<br /><br /><br />改良的Façade编码如下<br /><br /><pre name="code" class="java">
public class XxFacadeImpl implements XxFacade {
    public boolean doSomeThing(String param1) {
        //1组装查询条件
        XXVO xxVO=new XXVO();
        xxVO.setParam(param);
        //2.通过条件查询数据库已获得相业务数据
        List xxList = xxDao.getXXList(xxVO);        //Dao逻辑1
        //3.基于xxList的业务计算
editUserName(xxList);		                //业务逻辑1
        //4.把计算结果更新到数据库
        xxDao.updateXXList(xxList);                 //Dao逻辑
        //5.做其他事                               //业务逻辑 2  
		someBusiness2(xx);
        return true;
}
public List editUserName(List xxList){
		XXVO xxVO1 = new XXVO();              //业务逻辑1
        for(int i=0;i&lt;xxList.size();i++){
			xxVO1 = (XXVO) xxList.get(i);
			xxVO1.setName(String.valueOf(i));
}  
return xxList;
}

public List someBusiness2(xxx){
	...
	…
	…
	…
return result;
}
}
</pre><br /><br />这样的代码XxFacade中doSomeThing方法并不关心业务逻辑的具体实现，只是这个逻辑的实现流程，他只是调用一些纯业务方法，而这些纯业务方法又不需要依赖Dao数据我们随便组装一个List就可以测试，我们不再需要数据库，也摆脱了事务，需要测试的只是这些干干净净的纯业务方法，他们只依赖简单的参数，返回这个业务操作后的数据。至于XxFacade中doSomeThing方法我们甚至不需要去测试他，他所调用的方法全部是测试过的可信赖方法<br /><br />看看简单的改动为我们带来了什么？<br />1．	使方法可测试，提高测试覆盖度<br />2．	让Façade可以脱离事务，数据库进行测试<br />3．	有效的拆分方法，每个方法的业务都很简单，一屏足已装下<br />4．	保证每个纯业务方法都只做一件事。<br />5．	提高方法被复用的机会<br />由于方法doSomething中所调用的全部是可信任方法，也就直接提高代码的质量和覆盖度，增加了重构的勇气。<br /><br />最后希望大家可以多多提交有效的测试程序，提高我们代码的质量，下班前跑遍测试看到著名的green bar回家睡个安稳觉。
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/182879#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>Tue, 15 Apr 2008 13:26:35 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/182879</link>
        <guid>http://yh-private.javaeye.com/blog/182879</guid>
      </item>
      <item>
        <title>谈谈Hibernate令人爽的地方</title>
        <author>yh_private</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://yh-private.javaeye.com">yh_private</a>&nbsp;
          链接：<a href="http://yh-private.javaeye.com/blog/105490" style="color:red;">http://yh-private.javaeye.com/blog/105490</a>&nbsp;
          发表时间: 2007年07月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          由于工作原因,现在将ORM从熟悉的Hibernate转到IBatis<br /><br />最近组里要把过去的一个项目从ms sql转到oracle下,原本在HB下很轻松的事情<br />结果现在要一个模块一个模块的改,而且出现的问题多多,改起来超级麻烦<br /><br />发现IBatis在持久层为我们做的少之又少，带来的是一堆堆 XML<br />改的时候IB不给输出执行时的SQL语句,出错基本不知道是什么地方的问题,只能一点点摸索(比如断点),要去XML中一个一个的对比,粘出去到ORACLE下执行语句.<br />一个小项目动辄几十个XML用来映射SQL,调程序必须在 SQL/CODE之间来回切换,谁知道是不是SQL在ORACLE下出错了,人写的么,都会有一点点毛病,<br />比如:<br /><pre name="code" class="java">select user.id,user.name form user_table as user where user.pass=#password#;</pre><br />这样的语句在SQL下可以正常运行,跑到ORACLE就会出错,ibatis应该报SQL没有正常结束<br />像这样烦人的问题每天都遇到一堆,因为你不知道以前好用的SQL在什么时候什么地方会出错,而且还把异常封状的那么难看<br /><br /><strong>再说说性能问题</strong><br />总是看人家说hibernate在批量操作的时候很慢(对比JDBC),其实完全是句废话,任何ORM封装JDBC都要有性能开销,不想要性能开销的可以用JDBC嘛,而且HB提供方法可以很容易的局部绕过HB API,直接使用JDBC<br /><pre name="code" class="java">
. . .
Connection conn=session.getConnection();

JDBC CODE
....
</pre><br />通常大家都会说这样一个例子,HB在update 1W以上数据是的性能,其实可以通过setBatch来解决<br /><br />作为ORM框架,应该为我们带来开发.管理上的效率而不是负担<br /><br /><br />一点点个人看法,不喜欢的马上扔砖头  <img src="/images/smiles/icon_rolleyes.gif"/>
          <br/>
          <span style="color:red;">
            <a href="http://yh-private.javaeye.com/blog/105490#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, 25 Jul 2007 21:41:07 +0800</pubDate>
        <link>http://yh-private.javaeye.com/blog/105490</link>
        <guid>http://yh-private.javaeye.com/blog/105490</guid>
      </item>
  </channel>
</rss>