<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
 <channel>
  <title>Nana</title>
  <link>http://pp99nn.blogbus.com</link>
  <description><![CDATA[Thoughtworks 一个开发人员，初来乍到]]></description>
  <generator> by blogbus.com </generator>
  <lastBuildDate>Sun, 16 Oct 2011 16:44:29 +0800</lastBuildDate>
  <image>
									<url>http://public.blogbus.com/profile/0/9/4/5195490/avatar_5195490_96.jpg</url>
									<title>Nana</title>
									<link>http://pp99nn.blogbus.com</link>
								</image>  <item>
   <title>软件开发中“人”</title>
   <description><![CDATA[<p>&nbsp;</p>
<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #ffffff; line-height: 160%; margin: 5px;">
<p>貌似在各行各业的工作中，人的问题永远是一切问题的根源所在。时至今日，在中国的很多软件公司/部门，却慢慢的忽视了这个问题，尤其是管理层。所以，很多公司，尤其是不以软件开发为住的公司中的IT部门，永远是公司节源的重点。为了&ldquo;节约成本&rdquo;，搞人海战术，而真正达到预期的项目又有多少？</p>
<p>值得庆幸的是，我作为一名开发人员，所在的公司对人的问题还是相当重视的，可即便如此，每天的工作中所遇到的问题，仍会引发我对人的重要性的感慨~~</p>
<p>项目 1：</p>
<p>在之前的一个项目中，是个成熟度很高的团队，最高开发经验为10年，最低的开发经验超过了3年。并且，每个人都对软件和代码的质量都非常重视（有些人，则追求到了完美的地步）。然而，作为一个敏捷团队，在每天超快的工作节奏中，大家保持着很频繁的沟通和交流，Session，Pair programming, story kick off。。。但是让所有人困惑的是，为什么由这些优秀的开发人员所组成的开发团队，讨论问题始终存在一些分歧，谁都无法说服谁。最终的选择，总是要有某些/人，很无奈的妥协而达成。沟通效率的低下，困惑了所有的人。</p>
<p>到底问题出在哪里？一群没有领头羊的狼，不是一个好团队？完全扁平的团队组织，行不通？</p>
<p>项目 2：</p>
<p>目前正在做的一个项目组，人员结构很复杂：有客户自己从其他不同IT部门调配的人（能力参差不齐），有外包公司的人，还有我们自己的TWer。人员配比为（Twer: Non-Twer = 1:4）。在技术上TWer是领头羊，但是在组织结构上，他们仍旧隶属于自己的部门，他们与项目的成败，没有直接关系。Twer承担着交付压力。所以，这就决定了他们从工作动力和态度上都不可能与Twer完全一样。再加上Coding能力的差别，就导致了部分人有混日子的状态。</p>
<p>为了提高开发效率，我们采取的措施：</p>
<p>1. 跟Non-TWer结对开发，从中发掘可造之材，重点培养，然后让培养出来的人，再去跟其他Non-TWer结对。从而，解决我们人手不够的问题。</p>
<p>2. 实施严格的Code-review，目的首先是检验大家写的代码，是否存在问题，从而保证代码质量。同时，可以让每个人都意识到，要负责的写每行代码，否则，就会让受到别人的&ldquo;chanllenge&rdquo;.</p>
<p>3. 让客户IT部门的开发人员，负责于他们内部系统连接的接口部分。这样做的主要原因，是因为他们对自己的内部系统比较熟悉，而且，他们认识内部系统的负责人。对于开发和以后的连调测试，都有帮助。</p>
<p>4. 做Session，把大家都要掌握的技能和编程思想，都统统灌输给每个人。推荐他们读类似《clean code》之类的书，让大家自己主动学。但事实证明，让他们主动学的期望，有点高了。毕竟，最初的组织结构就已经决定了这个结果。</p>
<p>5. 项目后期，接口部分的开发成了项目的瓶颈。有的接口，需求久久搞不清楚；有的接口，环境迟迟不能到位。我们的人就开始介入接口开发，发现他们内部系统的开发人员安排和开发排期相当复杂，根本达不到我们的期望上线时间。于是，我们就争取让他们内部系统的开发人员飞过来，跟我坐在一起工作。事实证明，这样做效率是最高的。但是，不幸的是，并不是所有内部系统部门都能派人过来。</p>
<p>其中，我们做的不好地方也有很多：</p>
<p>1. 无条件的接受了客户安排的所有人，并且没有淘汰任何&ldquo;混日子&rdquo;的人。</p>
<p>2. 没有找到摆正Non-TWer工作态度的关键点。以至于，有些人动不动就在工作时间，跑出去办自己的私事了。</p>
<p>3. 由于交付压力日渐加到，我们对Non-Twer的培养做的不够好，Session慢慢变少。</p>
</div><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F166732749.html&title=%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E4%B8%AD%E2%80%9C%E4%BA%BA%E2%80%9D">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/166732749.html</link>
   <author>pp_nn_99</author>
   <pubDate>Sun, 16 Oct 2011 16:35:00 +0800</pubDate>
  </item>
  <item>
   <title>老了</title>
   <description><![CDATA[<p>突然觉得&ldquo;老了&rdquo;很恐怖</p>
<p>今天我让姐姐替我买火车票，说了两次是买到徐州的，结果还是买了到上海的。。。</p>
<p>我很生气，接完电话后，把手机仍了老远。因为我就是想不通，为什么会这样。我印象中，姐姐一直是伶牙俐齿的人，怎么突然间脑子不管事了。</p>
<p>以前姥姥还教我翻筋斗，给我编竹楼，可以现在虽然身体很健康，可是眼睛什么都不看清楚了，耳朵也不不好使了。即使我站在她一米以内的距离，她都认不清楚我了。。。</p>
<p>爸妈今年退休了，妈妈打算把生意让嫂子做，说是，老了，脑子不好使了。</p>
<p>这都是，这一年里突然间让我感受到事情。</p>
<p>我心里一直还拗不过，总是想，怎么会这样。</p>
<p>可是现在突然想，如果我到了他们的年纪，是不是也会像他们一样。这种想法让我觉得很恐怖。</p>
<p>要是真的那样，该怎么办啊。。。</p>
<p>人的成长不是自己孤零零的长大，而是身下一波波的孩子催着你长大，还有长辈们慢慢拉着你一起变老。</p>
<p>因为，老人们已经听不懂你的那一堆的if 。。 else 。。，孩子们理解不了你的那套should do。</p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F156615907.html&title=%E8%80%81%E4%BA%86">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/156615907.html</link>
   <author>pp_nn_99</author>
   <pubDate>Wed, 17 Aug 2011 23:02:00 +0800</pubDate>
  </item>
  <item>
   <title>JPA 中表的关联关系</title>
   <description><![CDATA[<ul>
<li>JPA Mapping</li>
</ul>
<p class="MsoListParagraphCxSpFirst" style="text-indent:-18.0pt;mso-list:l0 level1 lfo1"><!--[if !supportLists]--><span style="mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;
mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin"><span style="mso-list:Ignore">1.<span style="font:7.0pt ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><!--[endif]-->JPA <span style="font-family:宋体;
mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin" lang="ZH-CN">中可以根据</span>2<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:
Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">个</span>Table<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:
Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">之间的外键关系，建立</span>2<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:
Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">个</span>domain<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:
Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">的单向和双向关联关系。如果建立双向关联，则需要在</span>2<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">个</span>domain
class<span style="font-family:宋体;mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">中声明引用，并在关系拥有者里面指定关系，而另外一个</span>class<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">使用&ldquo;</span>mappedBy<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">&rdquo;声明关系拥有者，例如，</span>@ManyToMany(mappedBy="attributeOfTheOwningClass")&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle"><span style="font-family:宋体;
mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin" lang="ZH-CN">举例说明：</span></p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2"><!--[if !supportLists]--><span style="mso-bidi-font-family:宋体;mso-bidi-theme-font:minor-fareast"><span style="mso-list:Ignore">（1）<span style="font:7.0pt ">&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><!--[endif]-->ManyToOne</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">Create Table Employee{</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">DEPT_ID&nbsp;NUMBER(19, 0) NOT NULL,</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">FOREIGN KEY(DEPT_ID) REFERENCES&nbsp;Department(ID)</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">}</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">Create Table&nbsp;Department{</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">ID&nbsp;NUMBER(19, 0) NOT NULL</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">}</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">&nbsp;</p>
<p class="MsoNormal">@Entity</p>
<p class="MsoNormal">Public class Employee{</p>
<p class="MsoNormal">@ManyToOne</p>
<p class="MsoNormal">@JoinColumn(name=&rdquo;DEPT_ID&rdquo;)</p>
<p class="MsoNormal">Private Department <span style="mso-spacerun:yes">&nbsp;</span>department;</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal">@Entity</p>
<p class="MsoNormal">Public class Department{</p>
<p class="MsoNormal">@OneToMany(mappedBy=&rdquo;department&rdquo;)</p>
<p class="MsoNormal">Private Collection employees;</p>
<p class="MsoNormal">}</p>
<p class="MsoListParagraphCxSpFirst" style="margin-left:72.0pt;mso-add-space:
auto;text-indent:-36.0pt;mso-list:l1 level1 lfo2"><!--[if !supportLists]--><span style="mso-bidi-font-family:宋体;mso-bidi-theme-font:minor-fareast"><span style="mso-list:Ignore">（2）<span style="font:7.0pt ">&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><!--[endif]-->OneToOne</p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left:72.0pt;mso-add-space:
auto">&nbsp;</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">Create Table Employee{</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">DEPT_ID&nbsp;NUMBER(19, 0) NOT NULL,</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">FOREIGN KEY(PSPACE_ID) REFERENCES&nbsp;ParkingSpace(ID)</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">}</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">Create Table&nbsp;ParkingSpace{</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">ID&nbsp;NUMBER(19, 0) NOT NULL</p>
<p class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;
text-indent:-36.0pt;mso-list:l1 level1 lfo2">}</p>
<p>&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle">@Entity</p>
<p class="MsoListParagraphCxSpMiddle">Public class Employee{</p>
<p class="MsoListParagraphCxSpMiddle">@OneToOne</p>
<p class="MsoListParagraphCxSpMiddle">@JoinColumn(name=&rdquo;PSPACE_ID&rdquo;)</p>
<p class="MsoListParagraphCxSpMiddle">Private ParkingSpace parkingSpace;</p>
<p class="MsoListParagraphCxSpMiddle">}&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle">@Entity</p>
<p class="MsoListParagraphCxSpMiddle">Public class ParkingSpace{<br />
@OneToOne(mappedBy=&rdquo; parkingSpace&rdquo;)</p>
<p class="MsoListParagraphCxSpMiddle">Private Employee employee;</p>
<p class="MsoListParagraphCxSpMiddle">}</p>
<p class="MsoListParagraphCxSpMiddle">&nbsp;</p>
<ul>
<li>&nbsp;JPA default fetch type is as following</li>
</ul>
<p>&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle">@OneToMany and @ManyToMany <span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">关系的默认</span>FetchType
<span style="font-family:宋体;mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">是</span>
LAZY<span style="font-family:宋体;mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:
minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">；</span></p>
<p class="MsoListParagraphCxSpMiddle">@OneToOne and @ManyToOne <span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:
Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">关系的默认</span> FetchType<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">是</span>EAGER<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">；</span></p>
<p class="MsoListParagraphCxSpMiddle"><span style="font-family:宋体;
mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin" lang="ZH-CN">即</span>reference<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:
Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">为集合的</span>fetch type <span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">是</span>Lazy, <span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">看上去还是比较有道理的。但是如果记不清的话，可以根据自己的需要统统声明一下。毕竟这些默认设置和</span>Hibernate<span style="font-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:
minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin" lang="ZH-CN">是不同的。</span></p>
<p class="MsoListParagraphCxSpMiddle"><span style="font-family:宋体;
mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin" lang="ZH-CN">例如：</span></p>
<p class="MsoListParagraphCxSpMiddle"><span style="font-family:宋体;
mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin" lang="ZH-CN">&nbsp;&nbsp; (1)</span></p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>@OneToOne(cascade
= CascadeType.ALL)<span style="mso-spacerun:yes">&nbsp; </span>// default <span style="mso-spacerun:yes">&nbsp;</span>fetch type for OneToOne is eager</p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
</span>@JoinColumn(name = "INSURANCE_POLICY_ID")</p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
</span>private InsurancePolicy policy;&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle">&nbsp;&nbsp; &nbsp;(2)</p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
</span>@OneToMany(cascade = CascadeType.ALL) // default fetch type for OneToMany
<span style="mso-spacerun:yes">&nbsp;</span>is lazy</p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
</span>@JoinColumn(name = "LOAN_ID")</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:9.6pt">&nbsp;private
List repaymentPlans;</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:9.6pt">&nbsp;</p>
<ul>
<li>N+1<span style="font-family:宋体;
mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:
宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin" lang="ZH-CN">问题</span></li>
</ul>
<p>&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle">Usually this happens when the UI displays a
table of entities, where the entities have lazy many-to-one associations that
are navigated in Java code. By default, there will be one select for the main
query, and one select for each entity returned for each many-to-one
association. If there are many entities, this will bombard the database with
queries.</p>
<p class="MsoListParagraphCxSpMiddle">&nbsp;</p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp; </span>1.
Use left join fetch - Fetch the entities up front in the main query.</p>
<p class="MsoListParagraphCxSpMiddle"><span style="mso-spacerun:yes">&nbsp;&nbsp; </span>2.
Use batch size - Set an appropriate batch size for collections and entities.
When one entity in an association is lazily loaded, Hibernate will pre-fetch
other instances of that same entity that have proxies in the Persistence
Context (Session).</p>
<p class="MsoListParagraphCxSpLast"><span style="mso-spacerun:yes">&nbsp;&nbsp; </span>3.
Use side-effect queries - Execute JPAQL queries to initialize the entities that
will be referenced, discarding the results.</p>
<p>推荐文章：<a href="http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping">http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping</a></p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F154830294.html&title=JPA+%E4%B8%AD%E8%A1%A8%E7%9A%84%E5%85%B3%E8%81%94%E5%85%B3%E7%B3%BB">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/154830294.html</link>
   <author>pp_nn_99</author>
   <pubDate>Sun, 07 Aug 2011 13:54:00 +0800</pubDate>
  </item>
  <item>
   <title>About SSH </title>
   <description><![CDATA[<p><span style="color: #cccccc; font-family: 宋体, serif; font-size: 16px; line-height: normal;">
<p style="font-size: 9pt; line-height: 18px;">SSH的英文全称是Secure SHell。通过使用SSH，你可以把所有传输的数据进行加密，这样"中间人"这种攻击方式就不可能实现了，而且也能够防止DNS和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的，所以可以加快传输的速度。SSH有很多功能，它既可以代替telnet，又可以为ftp、pop、甚至ppp提供一个安全的"通道"。</p>
<p style="font-size: 9pt; line-height: 18px;">统的网络服务程序，如：ftp、pop和telnet在本质上都是不安全的，因为它们在网络上用明文传送口令和数据，别有用心的人非常容易就可以截获这些口令和数据。而且，这些服务程序的安全验证方式也是有其弱点的，就是很容易受到"中间人"（man-in-the-middle）这种方式的攻击。所谓"中间人"的攻击方式，就是"中间人"冒充真正的服务器接收你的传给服务器的数据，然后再冒充你把数据传给真正的服务器。服务器和你之间的数据传送被 "中间人"一转手做了手脚之后，就会出现很严重的问题。</p>
<p style="font-size: 9pt; line-height: 18px;">最初SSH是由芬兰的一家公司开发的。但是因为受版权和加密算法的限制，现在很多人都转而使用OpenSSH。OpenSSH是SSH的替代软件，而且是免费的，可以预计将来会有越来越多的人使用它而不是SSH。<br />SSH是由客户端和服务端的软件组成的，有两个不兼容的版本分别是：1.x和2.x。用SSH 2.x的客户程序是不能连接到SSH 1.x的服务程序上去的。OpenSSH 2.x同时支持SSH 1.x和2.x。</p>
<p style="font-size: 9pt; line-height: 18px;">如果要实现ssh连通，需要在server端安装 OpenSSH-server</p>
<p style="font-size: 9pt; line-height: 18px;">SSH的安全验证是如何工作的<br /><br />从客户端来看，SSH提供两种级别的安全验证。<br />第一种级别（基于口令的安全验证）只要你知道自己帐号和口令，就可以登录到远程主机。所有传输的数据都会被加密，但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器，也就是受到"中间人"这种方式的攻击。<br />第二种级别（基于密匙的安全验证）需要依靠密匙，也就是你必须为自己创建一对密匙，并把公用密匙放在需要访问的服务器上。如果你要连接到SSH服务器上，客户端软件就会向服务器发出请求，请求用你的密匙进行安全验证。服务器收到请求之后，先在你在该服务器的家目录下寻找你的公用密匙，然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致，服务器就用公用密匙加密"质询"（challenge）并把它发送给客户端软件。客户端软件收到"质询"之后就可以用你的私人密匙解密再把它发送给服务器。<br />用这种方式，你必须知道自己密匙的口令。但是，与第一种级别相比，第二种级别不需要在网络上传送口令。<br />第二种级别不仅加密所有传送的数据，而且"中间人"这种攻击方式也是不可能的（因为他没有你的私人密匙）。但是整个登录的过程可能需要10秒。<br /><br />安装并测试OpenSSH<br /><br />因为受到美国法律的限制，在很多Linux的发行版中都没有包括OpenSSH。但是，可以从网络上下载并安装OpenSSH（有关OpenSSH的安装和配置请参考：http://www.linuxaid.com.cn/engineer/brimmer/html/OpenSSH.htm）。<br />安装完OpenSSH之后，用下面命令测试一下：<br />ssh -l [your accountname on the remote host] [address of the remote host]<br />如果OpenSSH工作正常，你会看到下面的提示信息：<br />The authenticity of host [hostname] can't be established.<br />Key fingerprint is 1024 5f:a0:0b:65:d3:82:df:ab:44:62:6d:98:9c:fe:e9:52.<br />Are you sure you want to continue connecting (yes/no)?<br />OpenSSH告诉你它不知道这台主机，但是你不用担心这个问题，因为你是第一次登录这台主机。键入"yes"。这将把这台主机的"识别标记"加到"~/.ssh/know_hosts"文件中。第二次访问这台主机的时候就不会再显示这条提示信息了。<br />然后，SSH提示你输入远程主机上你的帐号的口令。输入完口令之后，就建立了SSH连接，这之后就可以象使用telnet那样使用SSH了。<br /><br />SSH的密匙<br /><br />生成你自己的密匙对<br /><br />生成并分发你自己的密匙有两个好处：<br />1) 可以防止"中间人"这种攻击方式<br />2) 可以只用一个口令就登录到所有你想登录的服务器上<br />用下面的命令可以生成密匙：<br />ssh-keygen<br />如果远程主机使用的是SSH 2.x就要用这个命令：<br />ssh-keygen -d<br />在同一台主机上同时有SSH1和SSH2的密匙是没有问题的，因为密匙是存成不同的文件的。<br />ssh-keygen命令运行之后会显示下面的信息：<br />Generating RSA keys: ............................ooooooO......ooooooO<br />Key generation complete.<br />Enter file in which to save the key (/home/[user]/.ssh/identity):<br />[按下ENTER就行了]<br />Created directory '/home/[user]/.ssh'.<br />Enter passphrase (empty for no passphrase):<br />[输入的口令不会显示在屏幕上]<br />Enter same passphrase again:<br />[重新输入一遍口令，如果忘记了口令就只能重新生成一次密匙了]<br />Your identification has been saved in /home/[user]/.ssh/identity.<br />[这是你的私人密匙]<br />Your public key has been saved in /home/[user]/.ssh/identity.pub.<br />The key fingerprint is: 2a:dc:71:2f:27:84:a2:e4:a1:1e:a9:63:e2:fa:a5:89 [user]@[local machine]<br />"ssh-keygen -d"做的是几乎同样的事，但是把一对密匙存为（默认情况下）"/home/[user]/.ssh/id_dsa"（私人密匙）和"/home/[user]/.ssh/id_dsa.pub"（公用密匙）。<br />现在你有一对密匙了：公用密匙要分发到所有你想用ssh登录的远程主机上去；私人密匙要好好地保管防止别人知道你的私人密匙。用"ls -l ~/.ssh/identity"或"ls -l ~/.ssh/id_dsa"所显示的文件的访问权限必须是"-rw-------"。<br />如果你怀疑自己的密匙已经被别人知道了，不要迟疑马上生成一对新的密匙。当然，你还要重新分发一次公用密匙。<br /><br />分发公用密匙<br /><br />在每一个你需要用SSH连接的远程服务器上，你要在自己的家目录下创建一个".ssh"的子目录，把你的公用密匙"identity.pub" 拷贝到这个目录下并把它重命名为"authorized_keys"。然后执行：<br />chmod 644 .ssh/authorized_keys<br />这一步是必不可少的。如果除了你之外别人对"authorized_keys"文件也有写的权限，SSH就不会工作。<br />如果你想从不同的计算机登录到远程主机，"authorized_keys"文件也可以有多个公用密匙。在这种情况下，必须在新的计算机上重新生成一对密匙，然后把生成的"identify.pub"文件拷贝并粘贴到远程主机的"authorized_keys"文件里。当然在新的计算机上你必须有一个帐号，而且密匙是用口令保护的。有一点很重要，就是当你取消了这个帐号之后，别忘了把这一对密匙删掉。<br /><br />配置SSH<br /><br />配置客户端的软件<br /><br />OpenSSH 有三种配置方式：命令行参数、用户配置文件和系统级的配置文件（"/etc/ssh/ssh_config"）。命令行参数优先于配置文件，用户配置文件优先于系统配置文件。所有的命令行的参数都能在配置文件中设置。因为在安装的时候没有默认的用户配置文件，所以要把 "/etc/ssh/ssh_config"拷贝并重新命名为"~/.ssh/config"。<br />标准的配置文件大概是这样的：<br />[lots of explanations and possible options listed]<br /># Be paranoid by default<br />Host *<br />ForwardAgent no<br />ForwardX11 no<br />FallBackToRsh no<br />还有很多选项的设置可以用"man ssh"查看"CONFIGURATION FILES"这一章。<br />配置文件是按顺序读取的。先设置的选项先生效。<br />假定你在www.foobar.com上有一个名为"bilbo"的帐号。而且你要把"ssh-agent"和"ssh-add"结合起来使用并且使用数据压缩来加快传输速度。因为主机名太长了，你懒得输入这么长的名字，用"fbc"作为"www.foobar.com"的简称。你的配置文件可以是这样的：<br />Host *fbc<br />HostName www.foobar.com<br />User bilbo<br />ForwardAgent yes<br />Compression yes<br /># Be paranoid by default<br />Host *<br />ForwardAgent no<br />ForwardX11 no<br />FallBackToRsh no<br />你输入"ssh fbc"之后，SSH会自动地从配置文件中找到主机的全名，用你的用户名登录并且用"ssh-agent"管理的密匙进行安全验证。这样很方便吧！<br />用SSH连接到其它远程计算机用的还是"paranoid（偏执）"默认设置。如果有些选项没有在配置文件或命令行中设置，那么还是使用默认的"paranoid"设置。<br />在我们上面举的那个例子中，对于到www.foobar.com的SSH连接："ForwardAgent"和"Compression"被设置为 "Yes"；其它的设置选项（如果没有用命令行参数）"ForwardX11"和"FallBackToRsh"都被设置成"No"。<br />其它还有一些需要仔细看一看的设置选项是：<br />l CheckHostIP yes<br />这个选项用来进行IP地址的检查以防止DNS欺骗。<br />l CompressionLevel<br />压缩的级别从"1"（最快）到"9"（压缩率最高）。默认值为"6"。<br />l ForwardX11 yes<br />为了在本地运行远程的X程序必须设置这个选项。<br />l LogLevel DEBUG<br />当SSH出现问题的时候，这选项就很有用了。默认值为"INFO"。<br /><br />配置服务端的软件<br /><br />SSH服务器的配置使用的是"/etc/ssh/sshd_config"配置文件，这些选项的设置在配置文件中已经有了一些说明而且用"man sshd"也可以查看帮助。请注意OpenSSH对于SSH 1.x和2.x没有不同的配置文件。<br />在默认的设置选项中需要注意的有：<br />l PermitRootLogin yes<br />最好把这个选项设置成"PermitRootLogin without-password"，这样"root"用户就不能从没有密匙的计算机上登录。把这个选项设置成"no"将禁止"root"用户登录，只能用"su"命令从普通用户转成"root"。<br />l X11Forwarding no<br />把这个选项设置成"yes"允许用户运行远程主机上的X程序。就算禁止这个选项也不能提高服务器的安全因为用户可以安装他们自己的转发器（forwarder），请参看"man sshd"。<br />l PasswordAuthentication yes<br />把这个选项设置为"no"只允许用户用基于密匙的方式登录。这当然会给那些经常需要从不同主机登录的用户带来麻烦，但是这能够在很大程度上提高系统的安全性。基于口令的登录方式有很大的弱点。<br />l # Subsystem /usr/local/sbin/sftpd<br />把最前面的＃号去掉并且把路径名设置成"/usr/bin/sftpserv"，用户就能使用"sftp"（安全的FTP）了（sftpserv在sftp 软件包中）。因为很多用户对FTP比较熟悉而且"scp"用起来也有一些麻烦，所以"sftp"还是很有用的。而且2.0.7版本以后的图形化的ftp工具"gftp"也支持"sftp"。<br /><br />拷贝文件<br /><br />用"scp"拷贝文件<br /><br />SSH提供了一些命令和shell用来登录远程服务器。在默认情况下它不允许你拷贝文件，但是还是提供了一个"scp"命令。<br />假定你想把本地计算机当前目录下的一个名为"dumb"的文件拷贝到远程服务器www.foobar.com上你的家目录下。而且你在远程服务器上的帐号名为"bilbo"。可以用这个命令：<br />scp dumb bilbo@www.foobar.com:.<br />把文件拷贝回来用这个命令：<br />scp bilbo@www.foobar.com:dumb .<br />"scp"调用SSH进行登录，然后拷贝文件，最后调用SSH关闭这个连接。<br />如果在你的"~/.ssh/config"文件中已经为www.foobar.com做了这样的配置：<br />Host *fbc<br />HostName www.foobar.com<br />User bilbo<br />ForwardAgent yes<br />那么你就可以用"fbc"来代替"bilbo@www.foobar.com"，命令就简化为"scp dumb fbc:."。<br />"scp"假定你在远程主机上的家目录为你的工作目录。如果你使用相对目录就要相对于家目录。<br />用"scp"命令的"-r"参数允许递归地拷贝目录。"scp"也可以在两个不同的远程主机之间拷贝文件。<br />有时候你可能会试图作这样的事：用SSH登录到www.foobar.com上之后，输入命令"scp [local machine]:dumb ."想用它把本地的"dumb"文件拷贝到你当前登录的远程服务器上。这时候你会看到下面的出错信息：<br />ssh: secure connection to [local machine] refused<br />之所以会出现这样的出错信息是因为你运行的是远程的"scp"命令，它试图登录到在你本地计算机上运行的SSH服务程序&hellip;&hellip;所以最好在本地运行"scp"除非你的本地计算机也运行SSH服务程序。<br /><br />用"sftp"拷贝文件<br /><br />如果你习惯使用ftp的方式拷贝文件，可以试着用"sftp"。"sftp"建立用SSH加密的安全的FTP连接通道，允许使用标准的ftp命令。还有一个好处就是"sftp"允许你通过"exec"命令运行远程的程序。从2.0.7版以后，图形化的ftp客户软件"gftp"就支持"sftp"。<br />如果远程的服务器没有安装sftp服务器软件"sftpserv"，可以把"sftpserv"的可执行文件拷贝到你的远程的家目录中（或者在远程计算机的 $PATH环境变量中设置的路径）。"sftp"会自动激活这个服务软件，你没有必要在远程服务器上有什么特殊的权限。<br /><br />用"rsync"拷贝文件<br /><br />"rsync" 是用来拷贝、更新和移动远程和本地文件的一个有用的工具，很容易就可以用"-e ssh"参数和SSH结合起来使用。"rsync"的一个优点就是，不会拷贝全部的文件，只会拷贝本地目录和远程目录中有区别的文件。而且它还使用很高效的压缩算法，这样拷贝的速度就很快。<br /><br />用"加密通道"的ftp拷贝文件<br /><br />如果你坚持要用传统的FTP客户软件。SSH可以为几乎所有的协议提供"安全通道"。FTP是一个有一点奇怪的协议（例如需要两个端口）而且不同的服务程序和服务程序之间、客户程序和客户程序之间还有一些差别。<br />实现"加密通道"的方法是使用"端口转发"。你可以把一个没有用到的本地端口（通常大于1000）设置成转发到一个远程服务器上，然后只要连接本地计算机上的这个端口就行了。有一点复杂是吗？<br />其实一个基本的想法就是，转发一个端口，让SSH在后台运行，用下面的命令：<br />ssh [user@remote host] -f -L 1234:[remote host]:21 tail -f /etc/motd<br />接着运行FTP客户，把它设置到指定的端口：<br />lftp -u [username] -p 1234 localhost<br />当然，用这种方法很麻烦而且很容易出错。所以最好使用前三种方法。<br /><br />用SSH设置"加密通道"<br /><br />"加密通道"的基础知识<br /><br />SSH 的"加密通道"是通过"端口转发"来实现的。你可以在本地端口（没有用到的）和在远程服务器上运行的某个服务的端口之间建立"加密通道"。然后只要连接到本地端口。所有对本地端口的请求都被SSH加密并且转发到远程服务器的端口。当然只有远程服务器上运行SSH服务器软件的时候"加密通道"才能工作。可以用下面命令检查一些远程服务器是否运行SSH服务：<br />telnet [full name of remote host] 22<br />如果收到这样的出错信息：<br />telnet: Unable to connect to remote host: Connection refused<br />就说明远程服务器上没有运行SSH服务软件。<br />端口转发使用这样的命令语法：<br />ssh -f [username@remote host] -L [local port]:[full name of remote host]:[remote port] [some command]<br />你不仅可以转发多个端口而且可以在"~/.ssh/config"文件中用"LocalForward"设置经常使用的一些转发端口。<br /><br />为POP加上"加密通道"<br /><br />你可以用POP协议从服务器上取email。为POP加上"加密通道"可以防止POP的密码被网络监听器（sniffer）监听到。还有一个好处就是SSH的压缩方式可以让邮件传输得更快。<br />假定你在pop.foobar.com上有一个POP帐号，你的用户名是"bilbo"你的POP口令是"topsecret"。用来建立SSH"加密通道"的命令是：<br />ssh -f -C bilbo@pop.foobar.com -L 1234:pop.foobar.com:110 sleep 5<br />（如果要测试，可以把"sleep"的值加到500）。运行这个命令之后会提示你输入POP口令：<br />bilbo@pop.foobar.com's password:<br />输入口令之后就可以用"telnet"连接到本地的转发端口了。<br />telnet localhost 1234<br />你会收到远程mail服务器的"READY"消息。<br />当然，这个方法要求你手工输入所有的POP命令，这是很不方便的。可以用Fetchmail（参考<a style="text-decoration: underline; color: #e6a306;" href="http://www.mandrakeuser.org/connect/cmail3.html#conf">how to configure Fetchmail</a>）。<a style="text-decoration: underline; color: #e6a306;" href="http://metalab.unc.edu/mdw/HOWTO/mini/Secure-POP+SSH.html">Secure POP via SSH mini-HOWTO</a>、man fetchmail和在"/usr/doc/fetchmail-[&hellip;]"目录下的Fetchmail的FAQ都提供了一些具体的例子。<br />请注意IMAP协议使用的是不同的端口：IMAP v2的端口号为143而IMAP v3的端口号为220。<br /><br />为X加上"加密通道"<br /><br />如果你打算在本地计算机上运行远程SSH服务器上的X程序，那么登录到远程的计算机上，创建一个名为"~/.ssh/environment"的文件并加上这一行：<br />XAUTHORITY=/home/[remote user name]/.Xauthority<br />（如果在远程主机上你的家目录下不存在".Xauthority"这个文件，那么当用SSH登录的时候就会自动创建）。<br />比如启动一个X程序（xterm）可以这个命令：<br />ssh -f -X -l [remote user name] [remote machine] xterm<br />这将在远程运行xterm这个程序。其它的X程序也是用相同的方法。<br /><br />为linuxconf加上"加密通道"<br /><br />Linuxconf(http://www.solucorp.qc.ca/linuxconf/)是Linux的配置工具，它支持远程管理。Linuxconf的FAQ重说明了如何通过SSH使用linuxconf：<br />其命令为：<br />remadmin --exec [link_command] linuxconf --guiproto<br />如果你想在两台计算机之间用加密的方式传送信息，那么最好用ssh。命令是：<br />remadmin --exec ssh -l [account] linuxconf --guiproto<br />这是非常有效的而且运行用图形界面管理计算机。<br />这种方法需要在客户端安装linuxconf。其它的方法还有直接登录到服务器上用"X11Forwarding"或字符界面运行linuxconf。<br /><br />为Webmin加上"加密通道"<br /><br />Webmin(http://www.webmin.com/webmin/)是一个新的基于浏览器的配置工具。它运行在1000端口。你可以用SSH的"端口转发"对它进行加密：<br />ssh -f -l [remote user name] [remote host] -L 1234:[remote host]:10000 tail -f /etc/motd<br />把浏览器指向<br />http://localhost:1234</p>
<p style="font-size: 9pt; line-height: 18px;">转载自：<span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; line-height: 22px; color: #000000;"><a href="http://fanqiang.chinaunix.net/safe/program/2005-03-24/3011.shtml">http://fanqiang.chinaunix.net/safe/program/2005-03-24/3011.shtml</a></span></p>
</span></p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F152518640.html&title=About+SSH+">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/152518640.html</link>
   <author>pp_nn_99</author>
   <pubDate>Sat, 30 Jul 2011 15:59:00 +0800</pubDate>
  </item>
  <item>
   <title>翻转句子中单词的顺序--java</title>
   <description><![CDATA[<p><strong style="line-height: 21px; color: #00246e; font-family: 仿宋_GB2312; font-size: 16px;"><span style="text-decoration: underline;">
</span></strong></p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;"><strong style="line-height: 21px; color: #00246e; font-family: 仿宋_GB2312; font-size: 16px;"><span style="line-height: 24px; font-weight: normal; -webkit-text-decorations-in-effect: none;">题目：输入一个英文句子，翻转句子中单词的顺序，但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见，标点符号和普通字母一样处理。不允许用java提供的类库。</span></strong></p>
<p><strong style="line-height: 21px; color: #00246e; font-family: 仿宋_GB2312; font-size: 16px;">
</strong></p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #00246e; font-family: 仿宋_GB2312; font-size: 16px; padding: 0px;"><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">例如输入</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&ldquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US">I am a student.</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&rdquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">，则输出</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&ldquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US">student. a am I</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&rdquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">。</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US"><br /></span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">分析：</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">由于本题需要翻转句子，我们先颠倒句子中的所有字符。这时，不但翻转了句子中单词的顺序，而且单词内字符也被翻转了。我们再颠倒每个单词内的字符。由于单词内的字符被翻转两次，因此顺序仍然和输入时的顺序保持一致。</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US"><br /></span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">还是以上面的输入为例子。翻转</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&ldquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US">I am a student.</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&rdquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">中所有字符得到</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&ldquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US">.tneduts a ma I</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&rdquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">，再翻转每个单词中字符的顺序得到</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&ldquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;" lang="EN-US">students. a am I</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 宋体;" lang="EN-US">&rdquo;</span><span style="line-height: 24px; font-size: 12pt; color: #00246e; font-family: 仿宋_GB2312;">，正是符合要求的输出。</span></p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;"><code></code></p>
<p><code><span style="font-family: mceinline; color: #00246e; font-size: x-small;">
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">private void reverse(char[] src,int start,int end){</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;while (start&lt;end){</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char temp = src[start];</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;src[start] = src[end];</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;src[end] = temp;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;start++;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end--;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp;}</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;private void reverseWord(char[] centense) {</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int i = 0;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int start = 0;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;while (i&lt;centense.length){</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(centense[i]!=' '){</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;i++;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else{</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;reverse(centense,start,i);</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;start = i+1;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp;@Test</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp;public void should_reverse_string(){</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;char[] centense = {'i',' ','l','o','v','e',' ','y','o','u'};</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;reverse(centense,0,centense.length-1);</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;reverseWord(centense);</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;System.out.print(centense);</p>
<p style="margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; padding: 0px;">&nbsp;&nbsp; &nbsp;}</p>
</p>
</span></code></p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F139355080.html&title=%E7%BF%BB%E8%BD%AC%E5%8F%A5%E5%AD%90%E4%B8%AD%E5%8D%95%E8%AF%8D%E7%9A%84%E9%A1%BA%E5%BA%8F--java">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/139355080.html</link>
   <author>pp_nn_99</author>
   <pubDate>Thu, 23 Jun 2011 18:32:00 +0800</pubDate>
  </item>
  <item>
   <title>超人还是神奇四侠？</title>
   <description><![CDATA[<p>&nbsp;</p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">最近从一个做了</span>1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">年</span>6<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">个月的项目上</span>roll
off<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">，换到了一个&lsquo;新&rsquo;团队。其实这个项目也做了</span>1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">年左右了，对于我来说虽然是全新的环境，全新的技术，但是对于在这个团队中的老成员而言，也有种对项目结束望眼欲穿的心情。其实说实话，项目做久了，多少都有自己的特点、惯性和问题。只是由于组员，客户的特性不同，而略有不同。但尤其是是在更加注重人的敏捷团队中，由于人的原因所造成的问题更加引人注目。</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">其实大到国家，小到公司，团队甚至家庭，都采取着或中央集权，或民主自治的形式进行管理和沟通。孰好孰坏，每个人心里都有自己的想法（你懂的）。但这种组织方式放到一个真正以人为本的团队，问题就会更加突出。以把我亲身经历的</span>2<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">个项目为例。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">项目</span>A----<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">团队成员：</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">资深架构师</span>1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">名</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Tec Lead 1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">名</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">开发人员</span>7<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">名</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;</span>PM 1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">名</span></p>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">&nbsp;&nbsp; &nbsp;层级结构是按照技术决策权来的，我想这种结构在大多数团队是比较普遍的一种组织方式。之所以大家喜欢采用这种方式，其实原因很简单：便于管理，因为有权威人士压阵，大家不会群龙无首；分工不同，大家可以各司其职，从而可以提高工作效率。但也存在很多问题，大家如果也经历过这种项目或组织（你懂的），肯定可以列举出很多点来，例如：决策风险性高，毕竟大家都是凡人，没有人一辈子都不犯错误，但这个错误一旦是处于决策顶端的架构师犯得，那影响是很多的；团队士气和声音会受到打压，没有了发言权，或没有倾听者，对于每个团队成员来说，无疑会带来巨大的挫败感，进而影响工作热情和效率。而在我们的团队中，就存在由此引发的种种问题，最后的结果就是经历了</span>9<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">个月才完成真正的</span>release<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">。而这九个月中除了架构师忙的昼夜无眠外，其他人都处于游离状，大家除了觉得无名的挫败感外，就是有劲没处使。主要原因在于，中央集权的过于严重，早期开发中大家提出的问题和疑虑，被无情的受到了打压；中期问题凸显后，大家纷纷摩拳擦掌想去解决，但由于个人能力，以及前期对问题根本的认识不足，个别情况没有处理好，让架构师失去了信任，于是架构师把问题都大包大揽，决定自己解决；后期就是一大堆的问题大家都无能为力，而架构师时间和精力有限，成为了所以问题的瓶颈。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">项目</span>B-------<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">团队成员：</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Tec
Lead 1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">名，</span>5<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">名开发人员</span></p>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">&nbsp;&nbsp; &nbsp;技术决策完全民主，每个人都享有同等的发言权。这或许是很多人向往的团队组织方式，因为你可以有于老大同样的话语权。但如果大家都可以决定自己的薪水，结果会是如何呢？。而更糟的是，每个人都承担相同的责任，所以你不会让自己去承担别人决策的责任，也绝不会放弃自己的权利。在一个开发团队中，情况也非常让人吃惊。我们会为了一个表名到底叫什么，讨论半个小时。为完成一个需求所采用那种技术架构争论</span>1<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">个小时都没有任何结果，因为大家都在自己的假设性，做出正确的判断，可有于每种推断是完全有理有据的，没有人可以说服对方。最后的结果是，遇到每个问题，大家都不得不讨论很久，从而导致大家渐渐对讨论越来越厌烦，甚至不想再参加这种无休止的讨论。因为这个过程不但降低了工作效率，还总是没有太好的成果。但好消息是，没有人会成为项目的瓶颈，大家可以有自己的很多建议和想法。结果如何还有等到我们真正</span>release<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">了，才好告诉大家。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">&nbsp;&nbsp; &nbsp;但我要说的是，这两种情况无疑都暴露了团队的沟通问题。人的问题永远都是一个团队最重要，最难解决的问题，而一切这类问题都可以归结为沟通问题。这或许就是敏捷宣言中为什么把&ldquo;个体和交互&rdquo;放在一起的原因的。而针对有效沟通存在的方法有很多种，其中</span>DISC<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">模型是我看到的很实用的一种方式。</span>DISC<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">代表着</span>4<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">个角色（</span>Dominator,
Influencer, Supporter, Critical Thinker<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">），他们在团队中承担不同的责任。</span>Dominator <span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">有较高的威望和洞察力，并带领大家达成既定的目标；</span>Influencer
<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">喜欢说出自己的想法和疑问，从而引起大家的思考，同时可以接纳别人的想法；</span>Supporter
<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">是个低调的</span>Team
player<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">，具有很好的聆听能力，目的在于成为最后的团队成员。</span>Critical
Thinker <span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">是个思维缜密的完美主义者，关注并分析问题的所有细节。当然，在讨论过程中，每个人可能在不同的时间点担任不同的角色。但如果讨论过程中，一直存在某个角色的缺失，那么讨论的效率和效果就大大折扣，不信的话，我们自己试验一下。。。</span></p>
<p>&nbsp;</p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F128163256.html&title=%E8%B6%85%E4%BA%BA%E8%BF%98%E6%98%AF%E7%A5%9E%E5%A5%87%E5%9B%9B%E4%BE%A0%EF%BC%9F">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/128163256.html</link>
   <author>pp_nn_99</author>
   <pubDate>Sat, 14 May 2011 12:27:00 +0800</pubDate>
  </item>
  <item>
   <title>共享一下我们的秘籍</title>
   <description><![CDATA[<p><span style="font-family: mceinline;"><span style="font-family: mceinline;">.<span style="font: 7.0pt ">&nbsp;&nbsp; &nbsp; 进入新的项目组，发现这个项目组几乎没有什么Agile的痕迹。这让我很惊讶。。。没有Pair，没有Code review，也没有人关心CI是什么颜色。这一切的理由就是要快速上线，所以什么其他的东西都不重要。。。不知道其他人是什么反应，我反正是被震到了。毕竟这个Team里一半的人都是公司的老员工，甚至有元老级的人。</span></span></span></p>
<p class="MsoListParagraphCxSpFirst" style="text-indent: -18.0pt; mso-list: l0 level1 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;"><span style="font-family: mceinline;"><span style="font: 7.0pt "><span style="font-family: mceinline;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;初来乍到，我们也不敢轻举妄动，毕竟我们还是新Member。但是，作为一个&ldquo;局外人&rdquo;，我们有很多优势，比如有义务主动给大家带来"新鲜血液"。所以我们就一点点说服大家采用我们之前屡试不爽的小实践：</span></span></span></span></span></p>
<ol>
<li><span style="font-family: mceinline;"><span style="font-family: mceinline;"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">分离开发机器和个人机器。就是开发时，不可以把自己的笔记本放在旁边。换言之就是，干活的只能一心干活，不会三心二意。同时，</span>pair<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">的彼此也感受到了应有的尊重。试想一下，如果你在埋头干活，你的</span>Pair<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">在哪里聊天，或者网上购物，你会是什么心情呢？但是万事有利弊，规定的太死板也让人很不爽。例如要在自己电脑上考东西，或者要给出差的机器装环境，就要来回跑。</span></span></span></li>
<li><span style="font-family: mceinline;">Tasking。上过OObootcamp的同学都应该对tasking这件看似不太重要的活动有印象。但我但我要说的是，tasking真的是写代码的核心。在着手写代码前，尤其是面对比较复杂的需求，tasking不但可以让我们思路清晰，并保证2个人统一思路，同时还可以发现一些架构中的漏洞，而且在 switch pair的 时候，可以方便的进行knowledge传递。这项实践尤其是在做功能复杂的需求时，更能体现它的价值。</span></li>
<li><span style="font-family: mceinline;">15分钟session。15分钟你可以做什么，可能是打个水的时间，同时碰到了同事，闲聊几句；或者是吃水果的时间。但是如果我们把吃水果的时间，把一个Team的人组织在一起，一起做个session，技术相关的或者无关的，不但没有浪费太多工作时间，同时可以增长大家见识，提高大家士气，同时还可以让大家放松心情，增进大家感情。</span></li>
</ol><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F124782763.html&title=%E5%85%B1%E4%BA%AB%E4%B8%80%E4%B8%8B%E6%88%91%E4%BB%AC%E7%9A%84%E7%A7%98%E7%B1%8D">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/124782763.html</link>
   <author>pp_nn_99</author>
   <pubDate>Mon, 02 May 2011 14:45:00 +0800</pubDate>
  </item>
  <item>
   <title>重构与否？</title>
   <description><![CDATA[<p>&nbsp;&nbsp; &nbsp; &nbsp;今天花了一整天的时间，在做javascript的重构，并着手给重构的代码加unit test。说实话，半路萌生过想放弃的念头，但是最终还是坚持下来了。为什么想放弃呢，主要有以下几个原因：</p>
<p>&nbsp;</p>
<ol>
<li>我的pair认为这个&ldquo;遗留的&rdquo;javascript，很难测，如果从这个地方入手，第一次引入javascript unit test，难度会很大。。。我虽然可以理解他的心情，但是还是坚持说服他继续做下去，原因很简单，就是因为所有的js代码都还裸奔着，这样迟早得出大事，所以，我们死也要给他加上测试。</li>
<li>确实，对于现有的琳琅满目的js unit test框架，不太熟，所以选择多了，反倒是坏事。大家讨论了半天，也没有达成一致。。。讨论的时间过长，降低了大家行动的士气。</li>
<li>一般的IDE对js code没有很好的重构支持，导致重构过程，很多都是拷贝/黏贴。。。我对这种完全原生态的重构方式，还确实不放心。结果也是证明了，除了一些bug。</li>
<li>由于这些bug的引入，导致，我对这次重构的影响有了更多的担心，比较这是很核心的部分，如果出了问题，将会后患无穷。。。这也是我坚持要加unit test的主要原因。</li>
<li>对项目的进度有影响。话说如果不进行这次重构，那么我们今天可以做更多的新功能，而进行了这次重构，除了让我们自己心里更舒服/安心，客户是非但不会买账，还会让这个迭代的velocity也很有所下降。。。假如我是PM，或许我会有所妥协。不过，还好我不是<img src="http://public.blogbus.com/biaoqing/nownow/39.gif" border="0" alt="" />。当然，我还是尽快去做好他。</li>
</ol>
<div>&nbsp;&nbsp; &nbsp; &nbsp;截止到现在，重构还在进行中，但是令我欣慰的是，这次重构，不但让代码更加清晰了，重用性提高了，还利用我们的unit test发现了2个连QA都没有发现的，已经存在系统已久的bug。</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp;所以，以后如果还做类似的重构，我们还是首先要保证有单元测试。否则，结果可能就不一样了。</div>
<p>&nbsp;</p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F94085601.html&title=%E9%87%8D%E6%9E%84%E4%B8%8E%E5%90%A6%EF%BC%9F">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/94085601.html</link>
   <author>pp_nn_99</author>
   <pubDate>Tue, 28 Dec 2010 22:08:00 +0800</pubDate>
  </item>
  <item>
   <title>OO Design in Agile</title>
   <description><![CDATA[<p><span style="mso-spacerun: yes;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">在我们平时的软件开发中，是否有遇到过如下情况：</span></p>
<ul>
<li><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">每次增加新更能，或者改</span>bug<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">，总有牵一发而动全身的感觉，导致开发成本越来越高。</span></li>
<li><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">对代码的微小改动，竟然会引起业务不相干的功能被破坏。</span></li>
<li><span style="font-family: 宋体;">重复的代码和劳动，比比皆是。</span></li>
<li><span style="font-family: Symbol; mso-fareast-font-family: Symbol; mso-bidi-font-family: Symbol;"><span style="mso-list: Ignore;"><span style="font: 7.0pt ">&nbsp;</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">同一个</span>Bug<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">，或者同类的</span>bug<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">反复出现.</span></li>
<li><span style="font-family: 宋体;">开发人员的流失，导致以前的代码成为没人敢碰的黑洞。</span></li>
</ul>
<p><span style="mso-spacerun: yes;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">而所有的这些问题，对于整个团队的危害，可能是导致大家士气低落，越来越多的人想离开这个项目；而对已一个公司而言，无疑是一个定时炸弹，随时都可能毁掉整个公司。</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">如何解决</span>/<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">避免这个问题？有人说要提高代码质量，有人说要改进开发过程。那么敏捷软件开发和设计，是很好的一个解决方案。</span></p>
<p class="MsoNormal"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">敏捷软件设计采用的是简单设计方法，但不是没有设计，在简单设计中，我们希望代码先能工作，然后再进行小步重构。在重构的过程中，有很好的设计原则来指导我们将代码变为可维护，可复用的健壮代码。他们分别是：</span></p>
<p class="MsoListParagraphCxSpFirst" style="margin-left: 18.0pt; mso-add-space: auto; text-indent: -18.0pt; mso-list: l1 level1 lfo2;">
<p class="MsoListParagraphCxSpFirst" style="margin-left: 18.0pt; mso-add-space: auto; text-indent: -18.0pt; mso-list: l0 level1 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">1)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">单一职责原则</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">即：仅有一个引起他变化的原因</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">实现原则：从业务的角度上，在同一层的对象间进行分割；分割的粒度，要权衡对象的复杂度和对象间的通信代价</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">侧重点：解决对象间的分层和职责划分问题</span></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 18.0pt; mso-add-space: auto; text-indent: -18.0pt; mso-list: l0 level1 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">2)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">开放</span>-<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">封闭原则</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">即：对象对扩展是开放的，对更改是封闭的</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">实现原则：对于代码中，频繁变化的部分抽象出</span>pluggable<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">的模式，例如</span>strategy<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">模式和</span>template<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">模式。但是，这些代码模式应该是重构出来的，不是第一次编码设计出来的。因为，过早的抽象，在后期变化部分不同时，还有重新抽象，导致抽象对象的维护和重构成本变大。</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">侧重点：解决对象的抽象和多态，他也是</span>OO Design<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">的核心所在。</span></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 18.0pt; mso-add-space: auto; text-indent: -18.0pt; mso-list: l0 level1 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">3)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span>Liskov<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">替换原则</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">即：子类型必须能代替他的基类型</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">实现原则：子类不删除</span>/<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">覆盖父类的功能。当出现如下情况</span>class A{ function1(),
function2()}, class B:A{ function1(), function3()}<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">。我们可以采用提出公共部分的方式，避免这种情况：</span>class
C{ function1()}, class A:C{ function2()}, class B:C{ function3()}</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">侧重点：解决对象的继承和组合关系，他是开放</span>-<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">封闭原则实现的基础。</span></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 18.0pt; mso-add-space: auto; text-indent: -18.0pt; mso-list: l0 level1 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">4)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">依赖倒置原则</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">即：高层模块不应该依赖于底层模块；抽象不应该依赖于细节</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">实现原则：分层的框架设计，例如，高层模块要独立于底层模块，最好是降低模块间的耦合性；分离抽象和具体实现细节，从而依赖于接口和抽象类，例如，如果要使用一个有抽象基类的类，可以持有他的基类</span>(<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">例如，在需要引用和继承时</span>)<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">。如果使用一个变动不大，且没有派生对象的类，损害也不大。<span style="display: none; mso-hide: all;">表动，应用和模块前</span></span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">侧重点：是针对框架</span>(framwork)<span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">设计的核心原则。</span></p>
<p class="MsoListParagraphCxSpMiddle" style="margin-left: 18.0pt; mso-add-space: auto; text-indent: -18.0pt; mso-list: l0 level1 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">5)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">接口隔离原则</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">即：实现类不应实现接口中定义的不用方法。</span></p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">实现原则：把胖类的接口分解为多个特定于客户程序的接口，再多重继承这些接口，或者使用委托分离接口。</span></p>
<p class="MsoListParagraphCxSpLast" style="text-indent: -18.0pt; mso-list: l0 level2 lfo1;"><span style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"><span style="mso-list: Ignore;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c)<span style="font: 7.0pt &quot;Times New Roman&quot;;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;" lang="ZH-CN">侧重点：解决胖接口的缺点，即不具备内聚特性的接口。</span></p>
</p><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F93160059.html&title=OO+Design+in+Agile">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/93160059.html</link>
   <author>pp_nn_99</author>
   <pubDate>Sun, 26 Dec 2010 14:34:00 +0800</pubDate>
  </item>
  <item>
   <title>CI是一种态度</title>
   <description><![CDATA[<p>&nbsp;&nbsp; &nbsp; &nbsp;每个人对敏捷的理解都不尽相同，有人认为敏捷的核心就是快速反馈，有人认为敏捷的核心是无障碍的沟通。但无可厚非的是CI是敏捷实践中，最能体现敏捷特性的活动。因为CI可以以最直观的方式，最快的速度得到反馈。</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;CI来源于XP的12个实践之一，可以说是融汇贯通其他实践的一个利器，估计很多项目都可以做到这些实践，比如：使用大家都有更改权限的subversion工具管理代码；自动化的构建，测试，以及部署；<span style="font-family: verdana, arial; line-height: 23px; font-size: 13px; color: #111111;">在接近生产环境中进行测试；</span><span style="font-family: verdana, arial; line-height: 23px; font-size: 13px; color: #111111;">让每个人都能轻易获得最新的可执行文件，尤其是客户和测试人员。最重要是，可以可视化build的状态，让Team中的每个人都可以清晰的看到Dev的更改，以便安排自己的工作进度，可以说他是一种最有效，且直观的沟通方式。</span></p>
<p><span style="font-family: verdana, arial; line-height: 23px; font-size: 13px; color: #111111;">&nbsp;&nbsp; &nbsp; &nbsp;但是即使我们有了这一套CI实践，而不没有坚定不移的维护他，结果当然是截然不同的。例如有的Team，在build已经失败的情况下，还不停地check in code，并且没有人有时间修复一下；还有的测试覆盖率极低，没有达到很好的自动化测试的效果，且测试环境和生产环境相处甚远；更有甚者，大部分开发人员多代码没有所有的操作权限，等等。其实，这个时候的CI就形同虚设了。所以，与其说CI是一套实现活动/或者是一套软件系统，倒不是说是一种维持软件开发过程时刻保持可运行，整洁的态度。如果有了这种态度，我想CI可以做的实践还可以更多一些吧。</span></p>
<p><span style="font-family: verdana, arial; color: #111111; font-size: small;"><span style="font-size: 13px; line-height: 23px;">&nbsp;&nbsp; &nbsp; &nbsp;态度决定一切。<img src="http://public.blogbus.com/biaoqing/nownow/4.gif" border="0" alt="" /></span></span></p>
<p><span style="font-family: verdana, arial; color: #111111; font-size: small;"><span style="font-size: 13px; line-height: 23px;"><br /></span></span></p>
<p>备注：XP的12个实践包括以下内容：</p>
<p><span style="font-family: 'Helvetica Neue', HelveticaNeue, Helvetica, Arial, sans-serif; line-height: 16px; font-size: 13px; "><em></em></span></p>
<p><em>
</em></p>
<p><em>
</em></p>
<p><em>
</em></p>
<p><em>
</em></p>
<p><em>
<ul style="margin-top: 12px; margin-right: 10px; margin-bottom: 12px; margin-left: 10px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">User stories (planning)</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Small releases (building blocks)</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Metaphor (standardized naming schemes)</span></em></li>
</ul>
</em></p>
<ul style="margin-top: 12px; margin-right: 10px; margin-bottom: 12px; margin-left: 10px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; list-style-type: none; ">
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Collective ownership</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Coding standard</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Simple design</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Refactoring</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Testing (TDD)</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Pair programming</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">Continuous integration</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">40-hour workweek</span></em></li>
<li style="margin-top: 6px; margin-right: 0px; margin-bottom: 6px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; background-image: url(http://i.techrepublic.com.com/images/200705/icn_arrowBullet.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; background-position: 0px 1px; background-repeat: no-repeat no-repeat; "><em><span style="font-family: mceinline;">On-site customer</span></em><em>&nbsp;&nbsp; &nbsp;&nbsp;</em></li>
</ul><!--sp--><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fpp99nn.blogbus.com%2Flogs%2F91074402.html&title=CI%E6%98%AF%E4%B8%80%E7%A7%8D%E6%80%81%E5%BA%A6">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://www.blogbus.com" target="_blank">博客大巴，你的个人传媒早班车</a></b></div><br /><br />]]></description>
   <link>http://pp99nn.blogbus.com/logs/91074402.html</link>
   <author>pp_nn_99</author>
   <pubDate>Mon, 20 Dec 2010 22:17:00 +0800</pubDate>
  </item>
 </channel>
</rss>

