﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-学习java-主要是学习别人的文章</title><link>http://www.blogjava.net/sdaunch/</link><description>好好生活</description><language>zh-cn</language><lastBuildDate>Sun, 03 May 2026 08:27:47 GMT</lastBuildDate><pubDate>Sun, 03 May 2026 08:27:47 GMT</pubDate><ttl>60</ttl><item><title>详解spring事务属性[转]</title><link>http://www.blogjava.net/sdaunch/archive/2010/07/12/325905.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Mon, 12 Jul 2010 12:15:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2010/07/12/325905.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/325905.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2010/07/12/325905.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/325905.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/325905.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的try&#8230;catch&#8230;finally代码。 <br />
我们在使用Spring声明式事务时，有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为，事务的隔离级别，事务的超时值和事务只读标志组成。我们在进行事务划分时，需要进行事务定义，也就是配置事务的属性。 <br />
Spring在<strong>TransactionDefinition</strong>接口中定义这些属性,以供PlatfromTransactionManager使用, PlatfromTransactionManager是spring事务管理的核心接口。 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>TransactionDefinition &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;TransactionDefinition&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;getPropagationBehavior(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;getIsolationLevel(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;getTimeout(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;isReadOnly(); &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">TransactionDefinition
public interface TransactionDefinition {
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
}</pre>
<br />
<br />
getTimeout()方法，它返回事务必须在多少秒内完成。 <br />
isReadOnly(),事务是否只读，事务管理器能够根据这个返回值进行优化，确保事务是只读的。 <br />
getIsolationLevel()方法返回事务的隔离级别，事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。 <br />
<br />
在TransactionDefinition接口中定义了五个不同的事务隔离级别 <br />
<strong>ISOLATION_DEFAULT </strong>这是一个PlatfromTransactionManager默认的隔离级别，使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应 <br />
<strong>ISOLATION_READ_UNCOMMITTED</strong> 这是事务最低的隔离级别，它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读，不可重复读和幻像读。 <br />
&nbsp; 例如: <br />
&nbsp; Mary的原工资为1000,财务人员将Mary的工资改为了8000，但未提交事务 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>Connection&nbsp;con1&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></span></li>
    <li><span>con.setAutoCommit(</span><span class="keyword">false</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>update&nbsp;employee&nbsp;set&nbsp;salary&nbsp;=&nbsp;</span><span class="number">8000</span><span>&nbsp;where&nbsp;empId&nbsp;=</span><span class="string">"Mary"</span><span>;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">  Connection con1 = getConnection();
con.setAutoCommit(false);
update employee set salary = 8000 where empId ="Mary";</pre>
<br />
与此同时，Mary正在读取自己的工资 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>Connection&nbsp;con2&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></span></li>
    <li><span>select&nbsp;&nbsp;salary&nbsp;from&nbsp;employee&nbsp;where&nbsp;empId&nbsp;=</span><span class="string">"Mary"</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>con2.commit();&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">Connection con2 = getConnection();
select  salary from employee where empId ="Mary";
con2.commit();</pre>
<br />
<br />
Mary发现自己的工资变为了8000，欢天喜地！ <br />
而财务发现操作有误，而回滚了事务,Mary的工资又变为了1000 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//con1 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;con1.rollback();&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//con1
con1.rollback();</pre>
<br />
像这样,Mary记取的工资数8000是一个脏数据。 <br />
<br />
<strong>ISOLATION_READ_COMMITTED&nbsp; </strong>保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现，但是可能会出现不可重复读和幻像读。 <br />
<br />
<strong>ISOLATION_REPEATABLE_READ&nbsp; </strong>这种事务隔离级别可以防止脏读，不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外，还保证了避免下面的情况产生(不可重复读)。 <br />
<br />
在事务1中，Mary 读取了自己的工资为1000,操作并没有完成 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>con1&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></span></li>
    <li><span>select&nbsp;salary&nbsp;from&nbsp;employee&nbsp;empId&nbsp;=</span><span class="string">"Mary"</span><span>;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">con1 = getConnection();
select salary from employee empId ="Mary";</pre>
<br />
<br />
在事务2中，这时财务人员修改了Mary的工资为2000,并提交了事务. <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>con2&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></span></li>
    <li><span>update&nbsp;employee&nbsp;set&nbsp;salary&nbsp;=&nbsp;</span><span class="number">2000</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>con2.commit();&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">con2 = getConnection();
update employee set salary = 2000;
con2.commit();</pre>
<br />
<br />
在事务1中，Mary 再次读取自己的工资时，工资变为了2000 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//con1 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>select&nbsp;salary&nbsp;from&nbsp;employee&nbsp;empId&nbsp;=</span><span class="string">"Mary"</span><span>;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//con1
select salary from employee empId ="Mary";</pre>
<br />
<br />
在一个事务中前后两次读取的结果并不致，导致了不可重复读。 <br />
使用ISOLATION_REPEATABLE_READ可以避免这种情况发生。 <br />
<br />
<strong>ISOLATION_SERIALIZABLE </strong>这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读，不可重复读外，还避免了幻像读。 <br />
<br />
目前工资为1000的员工有10人。 <br />
事务1,读取所有工资为1000的员工。 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>con1&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></span></li>
    <li><span>Select&nbsp;*&nbsp;from&nbsp;employee&nbsp;where&nbsp;salary&nbsp;=</span><span class="number">1000</span><span>;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">con1 = getConnection();
Select * from employee where salary =1000;</pre>
共读取10条记录 <br />
<br />
这时另一个事务向employee表插入了一条员工记录，工资也为1000 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>con2&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></span></li>
    <li><span>Insert&nbsp;into&nbsp;employee(empId,salary)&nbsp;values(</span><span class="string">"Lili"</span><span>,</span><span class="number">1000</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>con2.commit();&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">con2 = getConnection();
Insert into employee(empId,salary) values("Lili",1000);
con2.commit();</pre>
<br />
<br />
事务1再次读取所有工资为1000的员工 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//con1 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>select&nbsp;*&nbsp;from&nbsp;employee&nbsp;where&nbsp;salary&nbsp;=</span><span class="number">1000</span><span>;&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//con1
select * from employee where salary =1000;</pre>
<br />
<br />
共读取到了11条记录，这就产生了幻像读。 <br />
ISOLATION_SERIALIZABLE能避免这样的情况发生。但是这样也耗费了最大的资源。 <br />
<br />
<strong>getPropagationBehavior()</strong>返回事务的传播行为，由是否有一个活动的事务来决定一个事务调用。 <br />
<br />
<strong>在TransactionDefinition接口中定义了七个事务传播行为</strong>。 <br />
<br />
<strong>PROPAGATION_REQUIRED </strong>如果存在一个事务，则支持当前事务。如果没有事务则开启一个新的事务。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA{ &nbsp;&nbsp;</span></li>
    <li><span>&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>methodB(); &nbsp;&nbsp;</span></li>
    <li><span>&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA{
&#8230;&#8230;
methodB();
&#8230;&#8230;
}
//事务属性 PROPAGATION_REQUIRED
methodB{
&#8230;&#8230;
}</pre>
<br />
使用spring声明式事务，spring使用AOP来支持声明式事务，会根据事务属性，自动在方法调用之前决定是否开启一个事务，并在方法执行之后决定事务提交或回滚事务。 <br />
<br />
单独调用methodB方法 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>main{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;metodB(); &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">main{
metodB();
}</pre>
<br />
相当于 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>Main{ &nbsp;&nbsp;</span></span></li>
    <li><span>Connection&nbsp;con=</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;rry{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.setAutoCommit(</span><span class="keyword">false</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span class="comment">//方法调用 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(); &nbsp;&nbsp;</span></li>
    <li><span class="comment">//提交事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>con.commit(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>Catch(RuntimeException&nbsp;ex){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//回滚事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;con.rollback();&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//释放资源 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;closeCon(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">Main{
Connection con=null;
rry{
con = getConnection();
con.setAutoCommit(false);
//方法调用
methodB();
//提交事务
con.commit();
}
Catch(RuntimeException ex){
//回滚事务
con.rollback();
}
finally{
//释放资源
closeCon();
}
}</pre>
<br />
Spring保证在methodB方法中所有的调用都获得到一个相同的连接。在调用methodB时，没有一个存在的事务，所以获得一个新的连接，开启了一个新的事务。 <br />
<br />
单独调用MethodA时，在MethodA内又会调用MethodB. <br />
<br />
执行效果相当于 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>main{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;Connection&nbsp;con&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methodA(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.commit(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>cathc(RuntimeException&nbsp;ex){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;con.rollback(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;closeCon(); &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">main{
Connection con = null;
try{
con = getConnection();
methodA();
con.commit();
}
cathc(RuntimeException ex){
con.rollback();
}
finally{
closeCon();
}
}</pre>
<br />
调用MethodA时，环境中没有事务，所以开启一个新的事务. <br />
当在MethodA中调用MethodB时，环境中已经有了一个事务，所以methodB就加入当前事务。 <br />
<br />
<strong>PROPAGATION_SUPPORTS </strong>如果存在一个事务，支持当前事务。如果没有事务，则非事务的执行。但是对于事务同步的事务管理器，PROPAGATION_SUPPORTS与不使用事务有少许不同。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;methodB(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_SUPPORTS&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA(){
methodB();
}
//事务属性 PROPAGATION_SUPPORTS
methodB(){
&#8230;&#8230;
}</pre>
<br />
单纯的调用methodB时，methodB方法是非事务的执行的。 <br />
当调用methdA时,methodB则加入了methodA的事务中,事务地执行。 <br />
<br />
PROPAGATION_MANDATORY 如果已经存在一个事务，支持当前事务。如果没有一个活动的事务，则抛出异常。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;methodB(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_MANDATORY&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA(){
methodB();
}
//事务属性 PROPAGATION_MANDATORY
methodB(){
&#8230;&#8230;
}</pre>
<br />
当单独调用methodB时，因为当前没有一个活动的事务，则会抛出异常 <br />
throw new IllegalTransactionStateException("Transaction propagation 'mandatory' but no existing transaction found"); <br />
<br />
当调用methodA时，methodB则加入到methodA的事务中，事务地执行。 <br />
<br />
<strong>PROPAGATION_REQUIRES_NEW </strong>总是开启一个新的事务。如果一个事务已经存在，则将这个存在的事务挂起。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;doSomeThingA(); &nbsp;&nbsp;</span></li>
    <li><span>methodB(); &nbsp;&nbsp;</span></li>
    <li><span>doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRES_NEW&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA(){
doSomeThingA();
methodB();
doSomeThingB();
}
//事务属性 PROPAGATION_REQUIRES_NEW
methodB(){
&#8230;&#8230;
}</pre>
<br />
当单独调用methodB时，相当于把methodb声明为REQUIRED。开启一个新的事务，事务地执行。 <br />
<br />
当调用methodA时 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>main(){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;methodA(); &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">main(){
methodA();
}</pre>
情况有些大不一样.相当于下面的效果。 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>main(){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;TransactionManager&nbsp;tm&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">try</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//获得一个JTA事务管理器 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm&nbsp;=&nbsp;getTransactionManager(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm.begin();</span><span class="comment">//开启一个新的事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;Transaction&nbsp;ts1&nbsp;=&nbsp;tm.getTransaction(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;doSomeThing(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm.suspend();</span><span class="comment">//挂起当前事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tm.begin();</span><span class="comment">//重新开启第二个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Transaction&nbsp;ts2&nbsp;=&nbsp;tm.getTransaction(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methodB(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts2.commit();</span><span class="comment">//提交第二个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;Catch(RunTimeException&nbsp;ex){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts2.rollback();</span><span class="comment">//回滚第二个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//释放资源 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="comment">//methodB执行完后，复恢第一个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm.resume(ts1); &nbsp;&nbsp;</span></li>
    <li><span>doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;ts1.commit();</span><span class="comment">//提交第一个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">catch</span><span>(RunTimeException&nbsp;ex){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;ts1.rollback();</span><span class="comment">//回滚第一个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//释放资源 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">main(){
TransactionManager tm = null;
try{
//获得一个JTA事务管理器
tm = getTransactionManager();
tm.begin();//开启一个新的事务
Transaction ts1 = tm.getTransaction();
doSomeThing();
tm.suspend();//挂起当前事务
try{
tm.begin();//重新开启第二个事务
Transaction ts2 = tm.getTransaction();
methodB();
ts2.commit();//提交第二个事务
}
Catch(RunTimeException ex){
ts2.rollback();//回滚第二个事务
}
finally{
//释放资源
}
//methodB执行完后，复恢第一个事务
tm.resume(ts1);
doSomeThingB();
ts1.commit();//提交第一个事务
}
catch(RunTimeException ex){
ts1.rollback();//回滚第一个事务
}
finally{
//释放资源
}
}</pre>
<br />
在这里，我把ts1称为外层事务，ts2称为内层事务。从上面的代码可以看出，ts2与ts1是两个独立的事务，互不相干。Ts2是否成功并不依赖于ts1。如果methodA方法在调用methodB方法后的doSomeThingB方法失败了，而methodB方法所做的结果依然被提交。而除了methodB之外的其它代码导致的结果却被回滚了。 <br />
使用PROPAGATION_REQUIRES_NEW,需要使用JtaTransactionManager作为事务管理器。 <br />
<br />
<strong>PROPAGATION_NOT_SUPPORTED</strong>&nbsp; 总是非事务地执行，并挂起任何存在的事务。 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;doSomeThingA(); &nbsp;&nbsp;</span></li>
    <li><span>methodB(); &nbsp;&nbsp;</span></li>
    <li><span>doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_NOT_SUPPORTED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA(){
doSomeThingA();
methodB();
doSomeThingB();
}
//事务属性 PROPAGATION_NOT_SUPPORTED
methodB(){
&#8230;&#8230;
}</pre>
<br />
当单独调用methodB时，不启用任何事务机制，非事务地执行。 <br />
当调用methodA时，相当于下面的效果 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>main(){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;TransactionManager&nbsp;tm&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">try</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//获得一个JTA事务管理器 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm&nbsp;=&nbsp;getTransactionManager(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm.begin();</span><span class="comment">//开启一个新的事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;Transaction&nbsp;ts1&nbsp;=&nbsp;tm.getTransaction(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;doSomeThing(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm.suspend();</span><span class="comment">//挂起当前事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methodB(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;</span><span class="comment">//methodB执行完后，复恢第一个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;tm.resume(ts1); &nbsp;&nbsp;</span></li>
    <li><span>doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;ts1.commit();</span><span class="comment">//提交第一个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">catch</span><span>(RunTimeException&nbsp;ex){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;ts1.rollback();</span><span class="comment">//回滚第一个事务 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//释放资源 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">main(){
TransactionManager tm = null;
try{
//获得一个JTA事务管理器
tm = getTransactionManager();
tm.begin();//开启一个新的事务
Transaction ts1 = tm.getTransaction();
doSomeThing();
tm.suspend();//挂起当前事务
methodB();
//methodB执行完后，复恢第一个事务
tm.resume(ts1);
doSomeThingB();
ts1.commit();//提交第一个事务
}
catch(RunTimeException ex){
ts1.rollback();//回滚第一个事务
}
finally{
//释放资源
}
}</pre>
使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。 <br />
<br />
<strong>PROPAGATION_NEVER</strong> 总是非事务地执行，如果存在一个活动事务，则抛出异常 <br />
<br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;doSomeThingA(); &nbsp;&nbsp;</span></li>
    <li><span>methodB(); &nbsp;&nbsp;</span></li>
    <li><span>doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_NEVER&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA(){
doSomeThingA();
methodB();
doSomeThingB();
}
//事务属性 PROPAGATION_NEVER
methodB(){
&#8230;&#8230;
}</pre>
单独调用methodB，则非事务的执行。 <br />
调用methodA则会抛出异常 <br />
throw new IllegalTransactionStateException( <br />
"Transaction propagation 'never' but existing transaction found"); <br />
<br />
<br />
<strong>PROPAGATION_NESTED</strong>如果一个活动的事务存在，则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行 <br />
<br />
这是一个嵌套事务,使用JDBC 3.0驱动时,仅仅支持DataSourceTransactionManager作为事务管理器。需要JDBC 驱动的java.sql.Savepoint类。有一些JTA的事务管理器实现可能也提供了同样的功能。 <br />
<br />
使用PROPAGATION_NESTED，还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true; <br />
而nestedTransactionAllowed属性值默认为false; <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="comment">//事务属性&nbsp;PROPAGATION_REQUIRED&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodA(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;doSomeThingA(); &nbsp;&nbsp;</span></li>
    <li><span>methodB(); &nbsp;&nbsp;</span></li>
    <li><span>doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">//事务属性&nbsp;PROPAGATION_NESTED </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>methodB(){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&#8230;&#8230; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">//事务属性 PROPAGATION_REQUIRED
methodA(){
doSomeThingA();
methodB();
doSomeThingB();
}
//事务属性 PROPAGATION_NESTED
methodB(){
&#8230;&#8230;
}</pre>
<br />
如果单独调用methodB方法，则按REQUIRED属性执行。 <br />
<br />
如果调用methodA方法，相当于下面的效果 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.CopyToClipboard(this);return false;" href="http://www.javaeye.com/topic/78674#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>main(){ &nbsp;&nbsp;</span></span></li>
    <li><span>Connection&nbsp;con&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>Savepoint&nbsp;savepoint&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">try</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;con&nbsp;=&nbsp;getConnection(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;con.setAutoCommit(</span><span class="keyword">false</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;doSomeThingA(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;savepoint&nbsp;=&nbsp;con2.setSavepoint(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methodB(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;}</span><span class="keyword">catch</span><span>(RuntimeException&nbsp;ex){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;con.rollback(savepoint); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//释放资源 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;doSomeThingB(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;con.commit(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">catch</span><span>(RuntimeException&nbsp;ex){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;con.rollback(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span class="keyword">finally</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">//释放资源 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">main(){
Connection con = null;
Savepoint savepoint = null;
try{
con = getConnection();
con.setAutoCommit(false);
doSomeThingA();
savepoint = con2.setSavepoint();
try
methodB();
}catch(RuntimeException ex){
con.rollback(savepoint);
}
finally{
//释放资源
}
doSomeThingB();
con.commit();
}
catch(RuntimeException ex){
con.rollback();
}
finally{
//释放资源
}
}</pre>
当methodB方法调用之前，调用setSavepoint方法，保存当前的状态到savepoint。如果methodB方法调用失败，则恢复到之前保存的状态。但是需要注意的是，这时的事务并没有进行提交，如果后续的代码(doSomeThingB()方法)调用失败，则回滚包括methodB方法的所有操作。 <br />
<br />
<strong>嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时，会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚</strong>。 <br />
<br />
<strong>PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区别</strong>:它们非常类似,都像一个嵌套事务，如果不存在一个活动的事务，都会开启一个新的事务。使用PROPAGATION_REQUIRES_NEW时，内层事务与外层事务就像两个独立的事务一样，一旦内层事务进行了提交后，外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务管理器的支持。 <br />
使用PROPAGATION_NESTED时，外层事务的回滚可以引起内层事务的回滚。而内层事务的异常并不会导致外层事务的回滚，它是一个真正的嵌套事务。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTED时，需要JDBC 3.0以上驱动及1.4以上的JDK版本支持。其它的JTA TrasactionManager实现可能有不同的支持方式。 <br />
<br />
PROPAGATION_REQUIRED应该是我们首先的事务传播行为。它能够满足我们大多数的事务需求。 <br />
<img src ="http://www.blogjava.net/sdaunch/aggbug/325905.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2010-07-12 20:15 <a href="http://www.blogjava.net/sdaunch/archive/2010/07/12/325905.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring事务的传播行为和隔离级别[转]</title><link>http://www.blogjava.net/sdaunch/archive/2010/07/12/325902.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Mon, 12 Jul 2010 11:37:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2010/07/12/325902.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/325902.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2010/07/12/325902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/325902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/325902.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Spring事务的传播行为和隔离级别                                                                                                                                                                      ...&nbsp;&nbsp;<a href='http://www.blogjava.net/sdaunch/archive/2010/07/12/325902.html'>阅读全文</a><img src ="http://www.blogjava.net/sdaunch/aggbug/325902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2010-07-12 19:37 <a href="http://www.blogjava.net/sdaunch/archive/2010/07/12/325902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IBM 中国研究院 Offer 之感言——能力是一种态度[转]</title><link>http://www.blogjava.net/sdaunch/archive/2009/12/04/304824.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Fri, 04 Dec 2009 13:40:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/12/04/304824.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/304824.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/12/04/304824.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/304824.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/304824.html</trackback:ping><description><![CDATA[<h1>IBM 中国研究院 Offer 之感言——能力是一种态度</h1>
<div>
<p>
2009-12-04 09:53&nbsp;|&nbsp;
3233次阅读&nbsp;|&nbsp;
来源：移山之道 Silver&nbsp;&nbsp;【已有<font id="remark_count1" class="cmtcount" style="font-size: 12px; color: #cc0000;">37</font>条评论】<a href="http://news.csdn.net/a/20091204/215546.html#postcomment" target="_self">发表评论</a>
</p>
<p>
关键词：<a href="http://tag.csdn.net/IBM/">IBM</a> &nbsp;|&nbsp;感谢<a href="http://hi.csdn.net/ydj9931">ydj9931</a>的提供&nbsp;|&nbsp;
<cite><a href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();" class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友">收藏这篇新闻</a></cite>
</p>
</div>
<p>当我对着远程的大屏，给北京的IBM中国研究院几位面试官汇报完30分钟技术报告之后，心里忐忑不安，这已经是终面了一关关拼得不容易，但却很精彩!</p>
<p>在之后的几天，很高兴接到了来自IBM两位高级经理的电话，分别给我介绍了他们部门情况和项目情况，表示我的报告印象深刻，能力很突出真的是非常感谢他们能给我这个机会！</p>
<p><strong>诀窍</strong></p>
<p>我不是聪明过人的人，但是我相信自己的研究能力，这来源于一个诀窍我悟出一条定律，那就是：能力是一种态度！</p>
<p>简单解释如下：这世界上不缺乏聪明人，但是缺乏懂得运用自己聪明才智的人。</p>
<p>今天的帖子，我希望通过7个真实的故事，去诠释这条定律能力是一种态度！</p>
<p>1.
我通过qq在课题组做了一次试验，将同一个问题群发给了6个成员，有3个人回复我：这个我没遇到过，不会做啊；有2个去Google了下，大概告诉了解了
应该怎么弄；有一个人，做程序试验了不同方法的优劣，告诉我最好的方法是什么。多年以后，对很多问题都报以没遇到过，不会啊的人，和能力在积累的人，虽然
一样聪明，但是差距就很大了。</p>
<p>2. 行人仿真系统研发的初期，我突然发现A*算法和Social Force
Model特别有意思，就钻了进去，花了一些时间把它们研究透彻当我兴致勃勃给老板介绍完各种模型算法之后，老板说：你去给领导介绍这些模型算法是没用
的，他们要的是效果，模型是无止境的。当时我也很沮丧，但是后来事实证明，我的不务正业是对的！因为智能化的动态寻路能力成为了我们系统的核心创新点，也
是每次项目介绍中最得意的内容。</p>
<p>3.
给北京做的城市轨道交通运营辅助决策系统是要在08奥运前上线的，时间很紧，临近系统调试的时候，北京测试人员突然打电话说发现某些车站之间候选路径似乎
少了一条当时大家都认为可能就是边界条件问题，稍微改改就好了。我研究了下这个K短路算法(其他人负责开发的)发现竟是理论上的缺陷</p>
<p>一时半会儿又没办法给领导解释清楚，我就决定重写这个部分，用数据来说明。由于时间太紧，在北京回上海的火车上看这些很多文献，凭借着良好的A*算法基础，很快设计出新的算法。通过测试发现，老算法共丢了500多条路径！（总共十几万条左右），这时候大家总算舒了一口气了</p>
<p>但我并没有罢休，因为匆忙，算法速度不快。继续花了几天，将北京轨道网络中2万多OD之间清分计算时间优化到10多分钟，最后优化到1分钟（在我笔记本上）。上线调试当天，领导赞叹道：这算法可真是又快又准啊！</p>
<p>4. 还是上面这个系统的故事：当时北京路网基础数据是一个硕士负责录入的，他毕业以后，上海路网数据没人弄了，老板叫我去做。虽然只是半天时间的体力活，但是心里很不是滋味</p>
<p>虽然有人劝说：花个半天搞定算了哦！但是我决心不用笨办法我花了一个星期，凭借曾经开发的二维矢量图形库，设计出一个智能化的基础数据管理子系统，
只需要在图上简单点击，然后拷入excel中的车站名称和代码，系统自动识别，然后再自动生成区间、换乘关系等等6张数据库表需要的全部数据。后来课题组
利用这个工具构建了很多路网，因为非常简单，这个子系统也成为了后来863中网络客流仿真系统的基础。</p>
<p>5. 上物流系统课老师提到一个著名的NP问题Vehicle Routing
Problem，要求大家回去写写系统设计书。我当时就决定要开发这个系统，后来的几个星期，我发现遗传算法和自然界的规律真的是如此的吻合，达到了如痴
如醉的地步，被女朋友嘲笑为：整天关在屋里下崽后来结果是，我设计的遗传算法，不但能够求解最少需要多车，还能找到总里程很短的方案。</p>
<p>6. 在斯坦福访学主要是参与一个疏散仿真系统的研究。但是，由于有遗传算法的背景，另外一个教授介绍我参加他们的一个课题办公大楼改造优化方案的辅助决策系统。</p>
<p>刚开始我认为这是一个确定性问题，因此采用A*算法得到了比较好的效果，已经可以满足项目需求了。我想为了作对比，又设计了遗传算法，居然发现在少
数情况下能变异到更好解。大量实验后，我发现了两种算法虽然原理差别很大，数据结构上却存在内在联系，能够组合成一种具备通用性的框架，解决大量离散优化
问题。</p>
<p>完全出于对科学问题本身的痴迷，我并没有罢手自行设计了一种数据结构替换哈希表，将两个算法性能同时提升10倍之多（在遗传算法中提出了花名册的概
念），后来又发明一种交叉算法，再次将遗传算法提升十几倍。当时测试案例的人说已经完全跟不上了（已经让他反复做了好多次了），因此最后我们paper里
面的数据不是我最快的算法得到的。</p>
<p>7.
利用上面的离散优化问题搜索框架，我发现还可以解决《编程之美》中的许多问题。在大家都忙于找工作面试的时候，我却整整花了一个月关在寝室里研究《编程之
美》，有时候挑战一个题目整整花去1天时间，当时我身边的人都说我不务正业，我自己都有点怀疑了。可是事实证明，这份研究不但证明了兴趣，还证明了我的算
法能力，对后来找工作很有帮助。</p>
<p><strong>结论</strong></p>
<p>通过上面的故事，我想已经可以证明我这个定律了能力是一种态度。如果要问态度是什么，那么我想是一种单纯的，没有任何功利的科学态度，对问题本身的执着。</p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/304824.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-12-04 21:40 <a href="http://www.blogjava.net/sdaunch/archive/2009/12/04/304824.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 什么是问题？--转好友一篇文章</title><link>http://www.blogjava.net/sdaunch/archive/2009/07/07/285745.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Tue, 07 Jul 2009 01:53:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/07/07/285745.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/285745.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/07/07/285745.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/285745.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/285745.html</trackback:ping><description><![CDATA[<strong>&nbsp;什么是问题？</strong>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">1. 上下文 --
和问题相关的场景，指一组已经是明确已知的，关于问题的条件的描述。 </p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">2. 目标 --
指关于构成问题的结论的明确的描述。 </p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">3. 障碍 --
指问题的正确解决方法不是显而易见的，必须通过一定的思维活动，才能找到答案。 </p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">&nbsp;</p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">良好的定义问题是解决问题的关键步骤。</p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">定义问题就是鉴别期望和现状的差异。有如下几个关键点：</p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">1.
首要的是，收集整理关于现状的可信的信息，而不要假设已经拥有完备的可信信息； </p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">2. 不暗示倾向于某种原因或者解决方法；
</p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">3. 只陈述现状和期望的状态； </p>
<p style="margin: 0in; font-size: 9pt; font-family: SimSun;">4.
在解决问题的过程中，问题的定义可能（有必要）会不断的改进或者转换形式。</p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;">&nbsp;</p>
<p style="margin: 0in; font-size: 8pt; color: #666666; font-family: 宋体;">源文档
&lt;<a href="http://zh.wikipedia.org/w/index.php?title=%E9%97%AE%E9%A2%98&amp;variant=zh-cn">http://zh.wikipedia.org/w/index.php?title=%E9%97%AE%E9%A2%98&amp;variant=zh-cn</a>&gt;
</p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;">&nbsp;</p>
<p style="margin: 0in; font-weight: bold; font-size: 10pt; font-family: SimSun;">心态</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: Calibri;">&nbsp;&nbsp;&nbsp;
</span><span style="font-family: SimSun;">静心：在定位问题之前，最好先安静下来，摒除杂念。放下自己的身份（项目经理、开发人员），以解决当前系统的问题为中心。静心之后，将问题现象在脑中过一遍，弄清问题。</span></p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">&nbsp;</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-weight: bold; font-family: 宋体;">问题解决者不轻信，不盲从<br />
</span><span style="font-family: Calibri;">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体;">绝不因为一句&#8220;应该是对的&#8221;&#8220;大概没有变化&#8221;而抛弃一个怀疑的点。<br />
</span>&nbsp;</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-weight: bold; font-family: 宋体;">大局观：不要尽早的陷入细节<br />
</span><span style="font-family: Calibri;">&nbsp;&nbsp;&nbsp; </span><span style="font-family: SimSun;">实际上，在整个问题定位和解决的过程中，都应该尽量在头脑中对整个系统的映像以及当前位置保持清晰的认知。这样有助于前后、上下联系，在更高更广阔的空间中发现问题。</span><span style="font-family: 宋体;">在解决问题的时候提醒自己：我现在处于一个什么位置？如果不启动调试环境我能不能解决掉这个问题？</span></p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">&nbsp;</p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;"><span style="font-weight: bold;">预判断，然后验证</span>：尽量将日志、调试、HttpFox等都用作验证问题的工具——首先对问题的原因做预判断（猜测），然后确定该原因会导致什么现象，然后验证该现象（日志等）。预判断比验证更应被关注。</p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;">&nbsp;</p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;">当很难预判断问题位置时，可以采用<span style="font-weight: bold;">排除法</span>：每次排除系统范围的一半左右，逐步将包围圈缩小到问题原因本身。应注意：排除的过程中，同样要注意验证排除的是否正确，即：排除、验证、排除、验证&#8230;&#8230;</p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">&nbsp;</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-weight: bold; font-family: 宋体;">关注日志<br />
</span><span style="font-family: Calibri;">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体;">很多问题解决过程中其实打开日志文件就能马上得到结论，但是开发人员宁可自己猜也不愿意动手打开日志。<br />
另外也暴露了我们系统日志没有为开发人员提供足够的信息支持用以解决问题，后面的设计中要把异常设计作为一个重要部分。</span></p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">&nbsp;</p>
<p style="margin: 0in; font-weight: bold; font-size: 10pt; font-family: 宋体;">充分利用工具，能得到事实就不猜测</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: 宋体;">比如：</span><span style="font-family: Calibri;">HttpFox</span><span style="font-family: 宋体;">等工具能将</span><span style="font-family: Calibri;">HTTP</span><span style="font-family: 宋体;">请求录下来，我们不需要猜测；还有</span><span style="font-family: Calibri;">Windows</span><span style="font-family: 宋体;">事件日志，性能计数器，</span><span style="font-family: Calibri;">Windbg</span><span style="font-family: 宋体;">等等工具可用</span></p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">&nbsp;</p>
<p style="margin: 0in; font-weight: bold; font-size: 10pt; font-family: 宋体;">通过差异找到问题的原因</p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">很多问题的解决可以不依赖开发态的调试，比如通过比较当前版本和上一版本的区别，比较产品和产品之间的差别就能通过差异来定位问题。</p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;">&nbsp;</p>
<p style="margin: 0in; font-size: 10pt; font-family: 宋体;"><span style="font-weight: bold;">解决掉一个问题不是终结<br />
</span>之前往往满足于一个能够解决眼前问题的答案；这是远远不够的，一个问题的出现暴露出我们系统的缺陷，这是一个线索，需要避免同样的问题的出现</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: 宋体;">一个问题的出现我们要追究到问题的本质，例如前段时间SSO登陆失败和验证码本地使用失败，本质上都是由于配置文件中指定了</span><span style="font-family: Calibri;">Cookie</span><span style="font-family: 宋体;">的域。</span></p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;">&nbsp;</p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/285745.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-07-07 09:53 <a href="http://www.blogjava.net/sdaunch/archive/2009/07/07/285745.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>2、三五个人十来条枪 如何成为开发正规军（二）</title><link>http://www.blogjava.net/sdaunch/archive/2009/07/03/285289.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Fri, 03 Jul 2009 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/07/03/285289.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/285289.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/07/03/285289.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/285289.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/285289.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:PunctuationKerning/>
<w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing>
<w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
<w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:Compatibility>
<w:SpaceForUL/>
<w:BalanceSingleByteDoubleByteWidth/>
<w:DoNotLeaveBackslashAlone/>
<w:ULTrailSpace/>
<w:DoNotExpandShiftReturn/>
<w:AdjustLineHeightInTable/>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:UseFELayout/>
</w:Compatibility>
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
</w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles deflockedstate="false" latentstylecount="156">
</w:LatentStyles>
</xml><![endif]--><style>
<!-- /* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-alt:SimSun;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;
mso-font-charset:134;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:3 135135232 16 0 262145 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
line-height:150%;
mso-pagination:none;
font-size:10.5pt;
mso-bidi-font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:宋体;
mso-font-kerning:1.0pt;}
h1
{mso-style-update:auto;
mso-style-link:" Char Char6";
mso-style-next:正文;
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
line-height:240%;
mso-pagination:lines-together;
page-break-after:avoid;
mso-outline-level:1;
font-size:16.0pt;
mso-bidi-font-size:22.0pt;
font-family:"Times New Roman";
color:red;
mso-font-kerning:22.0pt;}
span.CharChar6
{mso-style-name:" Char Char6";
mso-style-locked:yes;
mso-style-link:"标题 1";
mso-ansi-font-size:16.0pt;
mso-bidi-font-size:22.0pt;
font-family:宋体;
mso-fareast-font-family:宋体;
color:red;
mso-font-kerning:22.0pt;
mso-ansi-language:EN-US;
mso-fareast-language:ZH-CN;
mso-bidi-language:AR-SA;
font-weight:bold;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
</style>
<![endif]--><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<h1><a name="_Toc214770387"><span lang="EN-US">2</span></a><span><span style="font-family: 宋体;">、三五个人十来条枪</span> </span><span><span style="font-family: 宋体;">如何成为开发正规军（二）</span></span></h1>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: 宋体;">上一次，写了一篇文章《三五个人十来条枪</span>
<span style="font-family: 宋体;">如何走出软件作坊成为开发正规军》，反响异常激烈。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我的一个朋友也看到了我的博文，他是做某个行业企业管理软件的。他说：你这个方法，在我从事的行业不适用。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我对他从事的那个信息化的行业还是有一定了解的。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　他们的实施模式是：</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　一个实施项目，大约</span><span lang="EN-US">50</span><span style="font-family: 宋体;">万的签单额，做完验收后给最后的</span><span lang="EN-US">20%-30%</span><span style="font-family: 宋体;">的尾款。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　他们是一家小公司，为了多做项目多赚钱（企业都希望利润保持的很高，如果毛利低，做软件就不合适了，受的苦和压力和不规律性比其他行业多的多），所以一个项目只派一个人去，而这个人需要培训、辅助导入旧系统数据、清洗合并数据、规范化数据、报表制作、需求协调、推动切换上线、现场运行监控、个性化定制修改代码。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　如果不能推动客户上线，就无法验收结项。不结项，就无法去追尾款。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　一个项目这个人，身兼项目经理、开发员、需求调研、软件设计、功能测试、实施培训、定制化开发，还有时候写培训文档。因为公司里都是这样的人，根本没有分工出专门的文档人员，所以产品根本没有培训手册和帮助手册。除非客户必须要，这个项目的这个人才写一份草稿应付。而公司又没有人来做文档管理工作，所以各个项目各个人写，也没有人合并，也没有人来统一收集。每个文档都在项目每个人的移动硬盘里。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　由于项目就老哥一个人全活儿，所以自己答应了客户修改什么需求就自己修改，根本没有啥需求调研方法和版本管理方法，就看这个老哥和客户之间的博弈了。每个项目一套源代码，而且都在各个项目的各个人手里。返回公司后，往公司的服务器上一扔做个备份。以后谁的项目出了问题或需求，就谁负责继续修改。但是，很有可能这个人已经在做其他项目了，还需要修改前几个项目的需求或</span><span lang="EN-US">BUG</span><span style="font-family: 宋体;">，还需要接听前几个项目的支持电话。如果这个老哥是在顶不住压力和焦虑而跑路了，只能把这些所有的活交给现存活的人的手里，啥也没有。无法交接也得交接，反正人要跳槽。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　由于每个人都是这样一人挡一摊或数摊项目，而且项目周期长，每个项目都需要</span><span lang="EN-US">2-3</span><span style="font-family: 宋体;">个月的时间。老板也想把公司做大，但是每个项目能去实施的人，要求都非常的高，新人来了一年也上不了前线干不了活。所以，对招新人也是不愿意招，干花钱没见起作用，小公司培养不起人。而对项目游刃有余的人，都是跑单帮跑惯了，带着个新人，还干不了活，还浪费出差费用，真是气死人了，还不如自己亲自动手三下五除二搞定爽。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　于是，公司五六年了也就那么大规模，老板员工都干的很辛苦，当然老板得到的钱要多一些，赚个</span><span lang="EN-US">500</span><span style="font-family: 宋体;">多万没啥问题，自己后半辈子算是有靠了。所以，老板也得过且过，反正现在赚钱速度已经比较满足了，这样也熟练习惯了，经验路径依赖，就这样顺坡下驴做吧。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我的朋友是个理想和现实总是不断冲突的人<strong>。一方面，他确实想把项目做的很是顺畅，另一方面，他却觉得一切都像是被各种因素牵扯，根本无法转变模式，于是只能认命继续现在。</strong></span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我说，你这种情况其实在中国很普遍。中国大部分软件公司都是从事行业信息化，因为这块技术难度最低，而且只要有人脉关系就可以做销售开干。而很多软件公司的成立，就是由于老板有一个关系，接到了某个项目，于是拉住了某个客户，小活不断，于是成立了公司。这是很多老板成立公司的原因。既然这类公司成立就没有目标，其目的就是认识几个人多拉一些项目多赚一些钱，所以如何复制模式，他们其实关注性也不大。原因很明白，就是自己不认识的客户，要想打入这个单子，很难，每个客户庙前都有</span><span lang="EN-US">N</span><span style="font-family: 宋体;">多关系户。对于自己有关系的客户，也就那么多个，有多大关系就能做多大的摊子，那就尽量从现有客户中持续做项目。维护好客户关系是最重要的。这类模式非常常见，并不是你这个行业特殊。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　老板的生活已经趋向于小康稳定，而你呢？你还在挣工资。你也在一线客户那里天天呆着，要么你把老板的客户抢过来你做，要么为了你自己工作能轻快些，你必须自己给自己找方法。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我的朋友说，抢过来不可能。自己虽然天天在第一线和客户天天在一起，关系也处的不错。但现在人先认的是钱，后认的是感情。而老板给他们这帮人都持续吃喝玩乐送东西分回扣，自己只是一个干苦力的。自己只能找方法。但你说的方法是针对一个公司的变革，不是针对我个人而言的，所以不适用。我想有一个方法能帮助我自己的方法，你帮我想想。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我想了想我过去写过的文章，确实是，自己一直从事职业经理人操盘产品研发管理，也统管咨询、实施、培训、支持，<strong>但都是在公司管理的层面上看问题分析问题解决问题，而没有从一个个体上去思考。而中国，大量像我这样的朋友，他们需要帮助，而我写的却是公司层面的，无法帮助他们，所以他们老说我的文章空洞、理想。</strong></span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我说，咱们俩一起分析解决。也是给大量像我朋友这样辛苦的人带个福音。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　咱们首先先说一下你想达到什么效果。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我朋友说：我现在在这里待的很烦，出差时间太长了，我就想早点回家。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　那你什么地方费时间了，需要</span><span lang="EN-US">2-3</span><span style="font-family: 宋体;">个月在客户现场？</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我朋友说：</span> <span style="font-family: 宋体;">嗯，我看完你的那篇文章，我也做了一下反思和总结。我感觉有三个方面特别费时间：<strong>客户需求，数据准备，报表制作</strong>。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　一去客户那里，你是见不到客户老板的，也是看不到用户的，你主要面对的是客户信息科的人。他们一开始要求你先做演示，看看是否符合他们本企业使用。在这个演示过程中，就不断提出需求让你修改。而且，你不修改完，他们没法接受你以下的演示，说想象不出后来的样子，对着你画的界面图想象以后的功能变化，有点纸上谈兵的感觉。而且，往往演示的时候必须信息科科长在，否则底下的科员都做不了主，演示了也是白演示。而信息科科长却老不在。而他们上班时间也极为规律，该下班时立马下班，根本不加班。所以边演示变修改再边演示。好容易修改完了，也演示完了，时间一俩个星期就过去了。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　信息科算是通过了，就需要录入基础数据了。问题又来了。现在大部门企业都已经上过一套软件了，可能是</span><span lang="EN-US">Foxpro</span><span style="font-family: 宋体;">的，也可能是</span><span lang="EN-US">PB</span><span style="font-family: 宋体;">的。人家要求你把数据倒进新系统中，但是一看过去的数据，都乱七八糟的，过去上线都是没经验，后来也用的乱了，积腋成疾了。现在要导入，真是要把垃圾输入，得出来的也是垃圾。你苦口婆心的说服让他们重新录入，但是他们一看都好几千条，不想录入，让你能导多少导多少，然后在基础上再维护。这一松口不要紧，你不仅忙活了一个多星期写各种</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">导数据，而且往往旧系统也没有文档，数据结构需要你自己理解，理解有误也是你的事。好容易导完了，再维护，发现数据是通过</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">导入的，在界面上却不能维护，因为很多校验都是写死在程序里的，而不是约束在数据库。磕磕碰碰，自己边后台修改数据，边让他们信息科维护。他们信息科首先先检验导进去的数据对不对，没有填写齐的字段填写齐。然后把没有导进去的数据录入进去。然后再打印出来，统一对一遍，看看哪些数据录入的有错误。这样折腾，一个月，</span><span lang="EN-US">22</span><span style="font-family: 宋体;">天工作日就过去了，用户还没培训呢。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　第二个月开始用户培训了，但一培训就发现了问题。用户的需求和信息科所的需求，根本不是一码事。原来一个企业，信息科也和业务科室是两张皮，就和在软件公司一样，开发部和销售部是两张皮。于是，用户和信息科开始吵架，各说各的道理，谁都在维护自己的利益。而且用户部门有业务在身，也不可能天天大部分时间泡在</span><span lang="EN-US">IT</span><span style="font-family: 宋体;">讨论上面，开会不来人，或者要来人也来了个小兵充数，根本起不了决定，还提自己的意见，过几天开会，用户部门的主任来开会，又把需求再推翻。业务部门主任是站在主任的层次上看</span><span lang="EN-US">IT</span><span style="font-family: 宋体;">管理，</span> <span style="font-family: 宋体;">而业务部门科员是站在自己轻松使用的角度上提需求，而信息科是为了自己以后维护着想。不断的讨论不断的推翻不断的扯皮。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　讨论扯皮推翻再讨论再修改。终于消停了。开始培训了。但问题来了，用户上机一操作，发现基础数据很多不是平常现实那样的。计算机数据过去就和现实数据脱离了，现在想借新系统上线再回到计算机管理上。于是，一边培训一边修改数据，有人报告数据错误就修改。而培训没有文档，培训也没有课程，培训也没有专业训练。培训如何层层开展，培训如何组织，都不知道。反正就老哥一个被订在这里了，只能这么上手了。人没有来齐，也得开始。等来了再重新讲一次。一次不会，再讲一次。有人年龄大打字不熟练，有人看不清屏幕，需要调整大字。一调整，界面发生错位了。有人不会用鼠标双击和单击，有人不会控制打印机。过去是</span><span lang="EN-US">UCDOS</span><span style="font-family: 宋体;">系统，还没用过</span><span lang="EN-US">WINDOWS</span><span style="font-family: 宋体;">的，用不惯。从基础培训起吧。否则怎么办呢？人家不上线用起来，人家不给验收结项啊，尾款回不来啊。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　用户也培训完了，该上线了，就需要初始化库存了。先得现实盘点，然后再录入计算机，还必须一边得继续营业。于是，真实库存和计算机库存肯定对不上去。由于品种太多，所以只能一批批盘点一批批录入。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　由于操作不熟练，特殊业务不知道如何处理，只能瞎处理。处理完后发现不对，想冲抵回去。没有冲抵功能，只能修改数据库中的数据。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　由于前期修改，根本没有测试，就是老哥自己一个人改。改完了有时候烦了连自己都不想测试。于是上线用着用着就不能运行了，需要当时就立即修改，中午晚上的连续作战紧急解决，否则第二天一早还需要开门迎客。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　好容易业务录入了，但是报表不对。一检查，原来是前段时间录入的非法业务数据造成，功能没想到没拦住。怎么办？偷偷自己修改数据，然后使报表平账。过段时间，发现报表又不平了，发现还是非法数据进入造成。怎么进来的呢？想不明白。只好蹲点现场，直到客户都运行正常了才能走人，算是上线成功。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　这个累呀，两三个月都是紧着过的。好不容易回来休息会，另一个项目就要启动了，就这么几头能干活的蒜，老板笑着脸让你去。于是，遭遇再次上演，日子就是这么过来了，一月又一月，一年又一年。顶不住的就跑路。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　我听完了我的朋友的诉苦。我说咱们一件件事情的排查。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　第一件事，边演示边修改，还得信息科长在，还得他拍板。这段时间的浪费如入缩短。我过去也作过灯塔客户的实施，我过去一去了客户那里，并没有一开始就这么做。我先是调研此次项目组的人员构成、能力、职责、上线时间、用户计算机能力、用户部门对上一套系统的最突出的抱怨，信息科对上一套系统的最突出的抱怨，现在还有哪些系统在持续运行，上一套系统用户部门和信息科觉得哪里好，上一套系统的功能结构和操作流程。这样，我就确定了我该如何开展项目实施。<span style="color: red;">这就是项目调研阶段。</span>人往往很眷恋自己已经习惯的事情。而且人的想法，人的能力，各个部门的利益冲突，人和人的私人关系和恩怨，都有助于项目的推进。亚洲人做事，<span style="color: red;">需要面上的和面下的都得下功夫</span>。纯粹都是正式的或者都是不正规的，都无法做好一个项目。我会在项目调研后，重新建议项目组人员构成、职责、流程、项目阶段时间、各方面负责人、<strong>本项目的最突出要解决的前</strong></span><strong><span lang="EN-US">5</span></strong><strong><span style="font-family: 宋体;">个目标问题</span></strong><span style="font-family: 宋体;">。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　人常说，上下同欲者胜，庙算者胜。你一开始必须界定好项目的边界和目标和执行标准和责任人，否则大家谁都想管或者谁都不管，大家没有目标，或者大家各有各的目标，肯定无法项目很好的推进。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　有了目标，责任人、标准、时间计划，就要按照这个目标来分解做。基础数据的校验，需要用户参与先来校验原有系统的数据。不要认为用户现有这套系统就没有问题。如果没有问题，企业也不会用你这套来代替他现有这套。<span style="color: red;">所以校验现有基础数据很有必要。没有的数据，先让他们做准备，但你要书面把要准备的规范写好交给要参与的各个用户，而且要做好<strong>培训工作</strong>，不能讲讲就认为他们理解了。</span>有了的数据，需要校验。地基打好，才能上面很快盖房子。而且，<span style="color: red;">信息科和用户对老系统很熟悉，校验数据比你快的多，而且准确的多。只有经过他们的确认，你可以导数据，也可以不负责导数据。</span>其实，基础数据，虽然多，但只要有</span><span lang="EN-US">5-10</span><span style="font-family: 宋体;">个人，</span><span lang="EN-US">2-3</span><span style="font-family: 宋体;">天就能录入完毕。比你导更快更准确。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　在用户嚷嚷需求的时候，一定要以<strong>系统目标</strong>为约束。因为每个人看法不一样，站的利益角度不一样，每个人的计算机应用水平也不一样，所以每个人都有看法。你让百家争鸣，而且什么需求都可以提，<strong>没有目标没有边界</strong>，就让你一个人修改，那么你结果不会好而且你会心身疲惫，你会很快就厌烦了项目。</span><strong><span style="font-size: 14pt; line-height: 150%; font-family: 宋体;">吃力不讨好，就是方法不对</span></strong><span style="font-family: 宋体;">。需求，一定要围绕时间阶段和目标为约束，大家要一个目标。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　还有你刚才讲到的没有培训方法、培训文档、培训素质，说明必须要有专人来做培训。这块是项目实施非常重要<strong>而且工作量大的一块</strong>。这才是真正的项目实施。<strong>项目实施不是让你来修改需求来了</strong>。培训做不好，上线会出一堆麻烦，<strong>软件再约束不强，报表就是平不了。</strong>而培养一个培训的人员还是容易的。如果想培养一个会协调推进来事的、会修改软件的、懂得业务需求的、会</span><span lang="EN-US">SQL</span><span style="font-family: 宋体;">语句导数的、会培训的，这样的专业神人确实很难。而且这样的神人一定不专业。所以，要带人，先要让他搞培训，而且让他编写针对不同用户的培训手册，有培训时间课程、培训规范、考试考核、模拟练习环境、模拟数据。这是这个培训专员可以做到的。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　<span style="color: red;">软件修改，尤其项目型软件，不修改是不太可能的。我不赞成在客户处修改软件。因为不仅仅你只会以事论事的修改，容易陷入到这家客户具体的需求中，而不会考虑其他客户的需求兼容，所以你修改的软件有很大局限性，最后形成只能一家维护一套代码，最后客户越多越累成本越高越不赚钱，被客户多而拖累死</span>。而且你在现场那么多事情，那么多人打扰，你根本无心踏实下来修改软件，只想着赶快改完上线回家，你急躁，潦草，应付，软件质量就没法保证了。你想改变这种现状，你必须把需求整理好，交给在家里专门编写代码的程序员。你在现场，你也很懂业务，你和你本公司的程序员沟通肯定比客户沟通要顺畅的多。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　这样，你在现场，<span style="color: red;">你的任务就是当好一个项目经理，专门协调，控制，理顺，制定流程、规范、目标、时间，保证执行到位。现场还有培训专员分担你的培训工作，可以帮助你校验数据，测试功能。</span>公司里还有专门</span><span lang="EN-US">coding</span><span style="font-family: 宋体;">的程序员分担你的开发测试工作，而且人家写的代码更加多家客户兼容使用，而且质量稳定性比你高。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　只有专业分工合作，才能转成正规军。否则，你只能把自己熬倒了，心力交瘁，最后心灰意冷，跳槽而走。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　从民兵，到武工队，到土八路，到正规军。这条路有好几个阶段。不能想着一步到位。现实情况也不容许我们一步到位。我们只能是能改进什么就改进什么，天天进步一点，我们就会大变样。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　<span style="color: red;">如果从心里就认为不可更改，直到心冷不想改进，那么我们永远不会进步</span>。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　为了我们自己心身愉快，我们也要进步。</span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">　　记住，你是项目经理。你是这个项目的领头人。你决定这个项目的成败。</span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: 宋体;">如果你连这个定位都没有，那么你什么都决定不了，你这个项目的成败只能随波逐流，那样你真的很失败了，你什么作用都没有，要你干吗。</span></p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/285289.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-07-03 10:02 <a href="http://www.blogjava.net/sdaunch/archive/2009/07/03/285289.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3、三五个人十来条枪 如何成为开发正规军（三）</title><link>http://www.blogjava.net/sdaunch/archive/2009/07/03/285287.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Fri, 03 Jul 2009 02:01:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/07/03/285287.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/285287.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/07/03/285287.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/285287.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/285287.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:""@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
line-height:150%;
font-size:10.5pt;
font-family:"Times New Roman";}
h1
{
mso-style-link:" Char Char6";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Times New Roman";
color:red;}
span.CharChar6
{mso-style-name:" Char Char6";
mso-style-link:"标题 1";
font-family:宋体;
color:red;
font-weight:bold;}
/* Page Definitions */
@page
{}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
</style>
<![endif]--><!--[if gte mso 9]><![endif]--><!--[if gte mso 9]><![endif]-->
<h1>3<span style="font-family: 宋体;">、三五个人十来条枪 </span><span style="font-family: 宋体;">如何成为开发正规军（三）</span></h1>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">自从写了关于《三五个人十来条枪</span>
<span style="font-family: 宋体;">如何走出软件作坊成为开发正规军》走出软件作坊：三五个人十来条枪</span> <span style="font-family: 宋体;">如何成为开发正规军（二），系列文章后，收到了很多网友的评论，也收到了很多网友的疑问请教。而大部分人都已经当上了项目经理，手下有个</span>2-3<span style="font-family: 宋体;">个人或</span>5-6<span style="font-family: 宋体;">个人。少部分人还在上学或者才毕业出来</span>1-2<span style="font-family: 宋体;">年，询问的还是学什么语言和什么才是核心技术的之类问题。</span></p>
<p><span style="font-family: 宋体;">　　从接到的请教来看，许多中国国内软件公司都<strong>是以项目为主</strong>，有单做单，没单就干靠，靠的时间长了老板心毛了就裁人，来活了就招人，就这样反反复复。所以，大量的公司没有开发部（因为除了销售，开发部从开发到实施到支持都全做），当然也没有开发部经理，只有项目经理。更不用提技术总监和</span>CTO<span style="font-family: 宋体;">。即使有个技术总监的头衔，也是为了给客户的名片，而手下也就</span>5-6<span style="font-family: 宋体;">个人，项目一来，技术总监也需要编码和实施，其实就是一个项目经理。</span></p>
<p><span style="font-family: 宋体;">　　在国内，项目经理这个词如此常见。均为<strong>实施项目经理和开发项目经理</strong>混为一身，统称项目经理。虽然，开发和实施是软件产品的不同阶段，不同阶段关注的重点也有不同。但既然都为项目经理，那么其关注点也有共性之处。</span></p>
<p><span style="font-family: 宋体;">　　项目经理，主要职责是：</span></p>
<p><span style="font-family: 宋体;">　　<strong>项目范围定义项目计划制定、分解、分配、协调、汇报项目质量控制项目需求变更控制国内项目经理一般没有人事权和财务费用权。老板给分配什么人就带什么人，自己只是一个最能干的工人加工头而已，当然更没有财务费用权，要想请客户吃顿饭，当然需要和老板打报告（</strong>自己团队想休息娱乐会，只能联机打把游戏，想团队吃顿饭，不可能给费用的）。</span></p>
<p><span style="font-family: 宋体;">　　不过，从现状来看，国内现在的项目经理，连<strong>项目范围和项目需求都无法控制</strong>。老板说什么就是什么，客户说什么就是什么，用户说什么就是什么，只要自己和自己的团队能做，并且不累死或者不跑路，能做的都照单全收。当然，做什么，什么时候做完，都不属于自己管理和控制，当然，项目计划的制定由项目经理制定，就是虚设了。唯一剩下的，就是项目<strong>质量控制：开发有代码的质量，实施有实施的质量</strong>。</span></p>
<p><span style="font-family: 宋体;">　　接到网友很多询问，都问我工具的使用情况（对组织结构和流程问的极少，可能觉得都自己改变不了，根本没有机会实现，道理能不能行的通也就不用去想了，因为想了也白想）。问我现在的团队使用什么</span>UML<span style="font-family: 宋体;">工具、什么压力测试工具、什么数据库设计工具、什么版本管理工具、什么需求管理工具、什么进度管理工具、什么</span>BUG<span style="font-family: 宋体;">管理工具。</span></p>
<p><span style="font-family: 宋体;">　　在他们眼里可能觉得，一个团队，只要用上先进的工具就会成为一支装备了机关枪的军队。就跟我们的客户一个想法，只要上了这套</span>ERP<span style="font-family: 宋体;">软件，我们的管理就上了一个台阶，我们的盈利就会提升。这个想法，真是奇怪，就如同一个人拿了一把屠龙刀，人没砍到，倒是把自己砍伤了。一把好厨子的刀，到了不会做菜的人的手里，仍然做不出好菜，就这么浅显的道理，但大家还在幻想。</span></p>
<p><span style="font-family: 宋体;">　　许多人想得到答案，觉得一个正规的开发团队应该使用是</span>Rose<span style="font-family: 宋体;">、</span>Together<span style="font-family: 宋体;">、</span>LoadRunner<span style="font-family: 宋体;">、</span>PowerDesigner<span style="font-family: 宋体;">、</span>VSS<span style="font-family: 宋体;">、</span>CVS<span style="font-family: 宋体;">、</span>SVN<span style="font-family: 宋体;">、</span>ClearRequest<span style="font-family: 宋体;">等等。</span></p>
<p><span style="font-family: 宋体;">　　但其实，我们也并没有使用这些工具。</span></p>
<p><span style="font-family: 宋体;">　　我一直在商业软件公司工作，也深深的明白<strong>自己的责任就是帮助公司最大限度的利润最大化</strong>。而利润最大化的实现手段就是<strong>最小的成本、最少的人、最少的时间、最简单的方法</strong>达到老板的目的，拿出合适质量和功能的产品，包装好，卖上尽可能高的价格。只要能赚到老板想赚到的钱，达到老板的目的，只要不影响这个目标，不影响大目标，小磕磕碰碰自然难免，有问题解决问题，没问题继续前进。哪个企业没个矛盾没个利益集团，哪个企业没个问题没个埋怨，有人爱自然有人恨。就是这样，这样是常态，不是异常。所以，我使用工具，一般都是在各种手段我都使用的差不多的情况下自然使用的，而非为了正规而正规，而是为了解决问题，而且是很有效的解决问题，而且是最简单的解决方法。我从来不为面子工程付出成本。</span></p>
<p><span style="font-family: 宋体;">　　我们最先遇到的问题当然也是<strong>软件质量的问题</strong>。软件的质量问题，引起了实施培训、实施推动上线的困难、客户使用效果的困难、支持费用的增高、支持难度的加大。最后实施部不愿意实施、销售部不愿意销售、支持部直接把电话转开发部。所有人对把自己工作的不顺利和不顺心归罪到开发部。当然，这样的开发部，不被老板开掉才怪。</span></p>
<p><span style="font-family: 宋体;">　　于是我空降入主了。</span></p>
<p><span style="font-family: 宋体;">　　我采取的第一个策略就是：专门划出一个辅助开发人员（因为他对客户需求也不了解，讲了</span>3<span style="font-family: 宋体;">遍也不懂，写的代码也考虑不周全，所以代码漏洞百出。不过这个小伙耐心还不错，就是有些懒。看来懒人一般都耐心不错。不过还是有些得过且过，做一天和尚撞一天钟。就这么个才。），让他做技术支持兼测试。</span></p>
<p><span style="font-family: 宋体;">　　过去是实施部有不少人，每个人都直接打开发员的电话。支持部也是。客户也是。老板呢，不懂软件也不深入操作研究软件，却从使用者角度老提意见，看到哪里想到哪里就直接给开发员打电话让开发员修改，从最皮毛的字的字号到最深入的商业智能问题，都提，而且让立即改掉，其他所有人包括客户提的都靠后。这样，<strong>一个开发被干扰的无法工作，最后离职</strong>。</span></p>
<p><span style="font-family: 宋体;">　　我划出开发部专人支持后，规定流程。所有的需求，不管是哪个部门或哪个客户，都归口到他这个人手上。即使还有人直接打给开发员，包括老板打给开发员的，开发员必须把需求或问题再并口到这个技术支持手里，我来统一安排调度开发。</span></p>
<p><span style="font-family: 宋体;">　　开发人员是消停了，可以安心按我的安排的进度和优先级修改了。而支持小伙子呢，电话开始被打爆。幸好我给小伙子的指示是，都先接上记录好，能不能解决，能不能快速解决，看自己能力，不着急，谁跟你急，你跟我说。于是，小伙子被吃了一颗定心丸。</span></p>
<p><span style="font-family: 宋体;">　　小伙子一开始使用的是一个</span>EXCEL<span style="font-family: 宋体;">。别人提的问题都自己记录在里面。但是弄到最后，我的手里、小伙子手里、开发人员手里、支持人员手里，都出现了不同版本的</span>EXCEL<span style="font-family: 宋体;">。互相都说这个已经修改了，那个说没有修改。这个说有多少</span>BUG<span style="font-family: 宋体;">，那个说不可能。</span></p>
<p><span style="font-family: 宋体;">　　于是，我上了第一个工具，</span>BUG<span style="font-family: 宋体;">管理系统。不管是</span>BUG<span style="font-family: 宋体;">还是需求还是建议还是疑问，谁想提，都提到这里来，随时记录。不管你是出差还是在支持部坐班，都记录到这里来。凡不记录者，一律不解决。</span></p>
<p><span style="font-family: 宋体;">　　于是，天下太平。经过技术支持和开发人员努力，一个大风浪过去。利益冲突处于一个平衡或者可能随时崩塌引来下一次冲突。</span></p>
<p><span style="font-family: 宋体;">　　我于是给支持小伙子分配了另一项重要工作。测试。为了不让你以后继续享受折磨，那么你必须卡好关。你自己卡不好，那么以后的技术支持仍然很痛苦。小伙子为了自己以后能过上幸福的上班生活，于是测试做的不错。所有测试出来的</span>BUG<span style="font-family: 宋体;">也记入到</span>BUG<span style="font-family: 宋体;">管理系统。</span> <span style="font-family: 宋体;">现在，开发人员工作量和工作质量有了量化，支持人员的工作量和工作质量也有了量化，给我安排计划和考核人员和申请资源做了大量的支持工作。</span></p>
<p><span style="font-family: 宋体;">　　所以，一个</span>BUG<span style="font-family: 宋体;">管理工具，能把计划、进度、质量、需求、</span>BUG<span style="font-family: 宋体;">都能管理起来，而且能追溯，能考核，能统计工作量和工作质量。真是必备。</span></p>
<p><span style="font-family: 宋体;">　　但是，接下来发现了一个问题。<strong>就是在修改的时候，老误会客户的需求</strong>。程序员一天在家里面开发，不了解外面的客户和在第一线战斗的实施人员到底想表达什么。于是修改完，程序员觉得自己费了很大的劲，而实施人员和客户却非常恼火，一点不领情还发怒。最后，搞的开发人员和实施人员冲突不断。</span></p>
<p><span style="font-family: 宋体;">　　<strong><span style="color: red;">需求如何描述清楚</span></strong>，成了必须提上日程的事情。许多没有经验的项目经理尤其会在这一步犯晕。</span>UML<span style="font-family: 宋体;">工具、数据库设计工具，需求管理工具，能上的都上，最后也没解决问题，把自己和自己的团队累的半死。</span></p>
<p><span style="font-family: 宋体;">　　我使用了</span><strong><span style="color: red;">PPT+WORD+</span></strong><strong><span style="font-family: 宋体; color: red;">脑图</span><span style="color: red;">+EXCEL</span></strong><span style="font-family: 宋体;">的描述方法。</span></p>
<p><span style="font-family: 宋体;">　　因为很多需求都是这个支那个叉出来的。程序员往往想的了这头想不了那头。这就是人的思考的周密性差异。</span></p>
<p><span style="font-family: 宋体;">　　想让人能从千万丝绦中理出头绪，于是脑图软件上场。把各个分支来龙去脉表现清楚。</span></p>
<p><span style="font-family: 宋体;">　　到了描述某个节点的时候，</span>PPT<span style="font-family: 宋体;">上手。一页</span>PPT<span style="font-family: 宋体;">相当于一个界面窗口。每页</span>PPT<span style="font-family: 宋体;">的图形模仿了菜单、输入框、按钮。按钮按下，还可以跳转到其他的</span>PPT<span style="font-family: 宋体;">页上，和软件操作流程非常相似。</span></p>
<p><span style="font-family: 宋体;">　　让程序员很直观的看到未来软件作出来是什么样子。关于</span>PPT<span style="font-family: 宋体;">的详细描述，如字段，流程，特殊注意，特殊控制，都用</span>WORD<span style="font-family: 宋体;">说明好。</span></p>
<p><span style="font-family: 宋体;">　　遇到有报表功能的时候，用</span>EXCEL<span style="font-family: 宋体;">把报表画出来，让程序员喜闻乐见。</span></p>
<p><span style="font-family: 宋体;">　　这样，从表及里，从概要到详细，从分支到关联，都表述</span>OK<span style="font-family: 宋体;">。客户也能明白，程序员也能明白，实施人员也能明白，老板也能明白（这点非常重要。虽然老板不懂软件，但他要干涉软件，他如果不明白，他就不知道这帮家伙到底在干吗，是在真正干活还是在偷懒，到底工作量是大是小，软件功能是复杂还是简单。老板如果不明白，老板在给与资源和时间上就会很谨慎，处处提防。这是许多项目经理都忽略了大事。还拿</span>UML<span style="font-family: 宋体;">做秀，谁也看不懂，谁也用不了，白花费时间画那些好看的图。这就是中国的现状，我们站哪个山头就唱哪个山头的歌，<strong><span style="color: red;">有效解决问题提高销售收入才是我们的根本任务</span></strong>，我们不抱怨不幻想踏实推进解决问题）。</span></p>
<p><span style="font-family: 宋体;">　　于是，<strong>老板的天平开始向开发部倾斜了。资源，当然就容易申请了</strong>。</span></p>
<p><span style="font-family: 宋体;">　　画这些</span>EXCEL+PPT+<span style="font-family: 宋体;">脑图</span>+WORD<span style="font-family: 宋体;">，当然很费时间（我直到引进了日本外包开发过程管理才发现，我们的解决方法和强调质量的日本人的做法非常相似）。于是，我申请一个人，把过去实施的一个项目经理（还居然会写点</span>SQL<span style="font-family: 宋体;">，从数据库查数据，调整个报表。实在太强了）调入开发部，专门编写这些文件。</span></p>
<p><span style="font-family: 宋体;">　　开发部开始蒸蒸日上。<strong>项目经理、开发人员、测试兼技术支持</strong>已经到位。工具也已用的不亦乐乎，深入到了公司的每个部门。每个部门都按照标准描述方法和标准流程走。现在，连实施人员都会画</span>EXCEL<span style="font-family: 宋体;">报表格式、</span>PPT<span style="font-family: 宋体;">界面。</span></p>
<p><span style="font-family: 宋体;">　　软件到位，就需要包装，否则软件就卖不上好价格。这是很自然的事情。干啥都要个品相。<strong><span style="color: red;">漂亮的姑娘谁都喜欢</span></strong>。</span></p>
<p><span style="font-family: 宋体;">　　<strong>软件包装，第一步就需要帮助文件、视频操作、解决方案、产品介绍、演示系统。</strong>当然，文案人员很快到位。美工美化也自然到位。能多赚钱干吗不做，老板也不是傻子。谁喜欢卖一个土灰土脸的产品。</span></p>
<p><span style="font-family: 宋体;">　　有了好的产品，出不去开发部也是个问题。只有自己内部人知道功能怎么用，怎么满足客户的需求，其他部门都不知道。许多人都不知道新功能和旧功能的改变。文档中都写了，更新说明也有，就是没有人看。还是打电话找技术支持，技术支持只能不断解释。问题又来了。</span></p>
<p><span style="font-family: 宋体;">　　<strong>文案出马。每次版本发布，功能更新，文案反复举办集中培训，办班，一批次一批次的培训，百其不厌。</strong></span></p>
<p><span style="font-family: 宋体;">　　四套马车，于是真正的天下太平了。</span></p>
<p><span style="font-family: 宋体;">　　从此，<strong>开发人员和实施人员过上了幸福的生活</strong>。</span></p>
<p><span style="font-family: 宋体;">　　后续记：</span></p>
<p><span style="font-family: 宋体;">　　接到很多网友的评论，都说老板不可能给资源的。说我写的太理想。</span></p>
<p><span style="font-family: 宋体;">　　嗯，如果你看完我的文章就直接找老板要资源，当然是会被赶回来的。因为，你什么都没有做就开始要资源。</span></p>
<p><span style="font-family: 宋体;">　　<strong>有人还说，公司就这几条枪，能干活的更是那几头蒜。根本不可能给你派人。</strong></span></p>
<p><span style="font-family: 宋体;">　　嗯，如果你思考的目标不是为老板赚取更多的钱，那么老板不可能给你一丁点的，甚至还会把你干掉。如果你觉得，这样的老板我还不伺候呢，那么中国大部分都是这样的公司，除非你转行不干这行了。要干，就别混日子。想得过且过让老板公司倒闭，这个基本不可能。再说老板倒闭了对你一点好处都没有。</span></p>
<p><span style="font-family: 宋体;">　　迈出你的第一步吧。不迈出第一步，你都会觉得这是不可能完成的任务。</span></p>
<p><span style="font-family: 宋体;">　　想过幸福的生活，从现在就开始脚踏实地的动手吧。</span></p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/285287.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-07-03 10:01 <a href="http://www.blogjava.net/sdaunch/archive/2009/07/03/285287.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>1、三五个人十来条枪 如何成为开发正规军（一）</title><link>http://www.blogjava.net/sdaunch/archive/2009/06/29/284545.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Mon, 29 Jun 2009 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/06/29/284545.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/284545.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/06/29/284545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/284545.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/284545.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:""@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
line-height:150%;
font-size:10.5pt;
font-family:"Times New Roman";}
h1
{
mso-style-link:" Char Char6";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Times New Roman";
color:red;}
span.CharChar6
{mso-style-name:" Char Char6";
mso-style-link:"标题 1";
font-family:宋体;
color:red;
font-weight:bold;}
/* Page Definitions */
@page
{}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
</style>
<![endif]-->
<h1>1<span style="font-family: 宋体;">、三五个人十来条枪 </span><span style="font-family: 宋体;">如何成为开发正规军（一）</span></h1>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">自从发了上一篇博文，这几天收到很多朋友的来信。</span></p>
<p><span style="font-family: 宋体;">　　大家从各个开发语言的优缺点和适用领域，一直讨论到设计模式、框架、重构、单元测试，乃至敏捷编程，最后都讨论到了软件开发过程管理，甚至都谈到了盈利模式和中国软件的悲哀。</span></p>
<p><span style="font-family: 宋体;">　　最后不了了之，都觉得改善中国内地现在的软件生产状况不可能。</span></p>
<p><span style="font-family: 宋体;">　　为什么呢？</span></p>
<p><span style="font-family: 宋体;">　　我重新把这几天大家的讨论留言翻了一遍，发现大家的软件团队都存在着这样一种普遍现象大部分人所在的公司，开发人员仅</span>3-5<span style="font-family: 宋体;">人，多的在</span>10<span style="font-family: 宋体;">人。别看就这几条枪，还从售前支持，软件开发，测试、打包发布、文档编写、实施安装、培训、技术支持都做。</span></p>
<p><span style="font-family: 宋体;">　　这还不算什么，而且几乎是一个人负责一个产品或一个项目，一个人从头跟到尾，而且负责多个客户的维护工作。</span></p>
<p><span style="font-family: 宋体;">　　这还不算什么，而且随时老板会找来八竿子打不着的新活，要的还挺紧，突然要开发，打乱了所有的计划，最后都懒的按计划行事，每天撞钟，老板有事就吩咐，没事就上网，还不让听歌，当然更不让打游戏。甚至还不让看技术书籍，呵斥不干工作。只能上网装作在工作。</span></p>
<p><span style="font-family: 宋体;">　　老板和员工互相斗智斗勇，在年终奖、报销、出差、平时福利上啊，都明争暗斗。老板卡的紧，员工就在项目和产品上下药，还不知道是谁占了谁便宜，谁给谁打了工。</span></p>
<p><span style="font-family: 宋体;">　　员工一边在刻苦钻研各种开发工具，阅读源代码，学习做</span>DEMO<span style="font-family: 宋体;">例子，阅读</span>UML<span style="font-family: 宋体;">、设计模式、单元测试、敏捷编程等等，一边却懒的修改现在公司的产品，有问题就打补丁，客户不嚷嚷就懒的修改，代码不优化，界面不友好，架构没架构，代码不封装但是，在讨论中，我时时都强烈感觉到，大家是想把产品开发好，把开发过程管理的井井有条，但是都心有余而力不足。阅读了</span>N<span style="font-family: 宋体;">多软件工程的书籍，从重型方法到轻型方法都阅读了，但都无法把现在的开发状态一点点扭转好。</span></p>
<p><span style="font-family: 宋体;">　　许多人想闹革命，把现在这些产品和团队都砸塌，然后重新来过，但这只是梦想，说说而已。只能希冀下一次跳槽，能找到一个好的公司，把自己平生所学全部发挥出来，但这好像也只是梦想，因为交流了一下，大家彼此的境况基本相同。</span></p>
<p><span style="font-family: 宋体;">　　一些极端主义者自己开了公司，才发现不持家不知道油盐贵，现在自己和手下变成了老板和员工的关系，走了过去的老路。</span></p>
<p><span style="font-family: 宋体;">　　更有一些极端主义者辞职，自己做软件，最后由于生活拮据或做做发现这个软件没什么意义，就丢弃了自己的梦想，随便找一家公司开始沉默撞钟。</span></p>
<p><span style="font-family: 宋体;">　　一些聪明的家伙，有的入了外企，有的进了大的网游公司，有的进了外包公司，有的进了大网站公司，都是讲究大规模开发的公司，希望能找到一条中国式团队开发产品保证之路作为小软件公司，我们真的无能为力了么？我们真的成为炮灰了么？</span></p>
<p><span style="font-family: 宋体;">　　但是，中国软件行业大部分都是这样的公司。从每年的</span>CSDN<span style="font-family: 宋体;">的程序员调查都可以看到，中国软件公司大部分都保持在这种开发团队规模，开发人员大部分都在毕业</span>1-3<span style="font-family: 宋体;">年。</span></p>
<p><span style="font-family: 宋体;">　　<strong>我们是在等待时间让人变得成熟么？我们是在等待时间让人变得技术综合实力增强么？</strong></span></p>
<p><span style="font-family: 宋体;">　　依笔者看，作为中国软件群体最大的小软件公司，需要的不是</span>UML/RUP/CMM<span style="font-family: 宋体;">这些重型方法，不是前几年大家关注的小组开发方法，也不是敏捷编程这样的结对方法，我们都无法有这样的资源实现这样的方法。</span></p>
<p><span style="font-family: 宋体;">　　但是，想想，星星之火可以燎原。红军能从爬雪山过草地起家，最后解放全中国。我们就没有方法？</span></p>
<p><span style="font-family: 宋体;">　　那我们就需要想，就我们目前能拥有的权力和资源，我们如何一点点改进。我们需要的是从游击队到兄弟连，从兄弟连到正规军的方法。我们现在还处于游击队，一个队长领了一帮游兵散勇，有的人甚至没有枪还背着大刀，有的人还没杀过鬼子。</span></p>
<p><span style="font-family: 宋体;">　　首先，要把我们自己变成兄弟连。</span></p>
<p><span style="font-family: 宋体;">　　我常常观看国际著名的</span>CS<span style="font-family: 宋体;">战队的比赛录像，他们配合的多好啊。如果他们都单兵作战，那么早就死翘翘了。这和咱们的软件开发多么相像。我们多么神往这种默契的配合，打的多么流畅。我们要的就是这个。他们也不几个人么。</span></p>
<p><span style="font-family: 宋体;">　　那让我们来分析分析吧。</span></p>
<p><span style="font-family: 宋体;">　　我们想好好专职的开发软件，但我们的时间都被实施安装、培训、技术支持占去了。为什么我们要做这些？是因为我们软件没有操作说明，其他部门人都不会用。而且我们也没有培训机制，其他部门人更不会用。而且我们的软件不稳定，其他部门人都拒绝实施。由于我们软件不稳定，老出问题，出了问题其他部门人也帮不上忙，只能我们自己去做技术支持。</span></p>
<p><span style="font-family: 宋体;">　　从以上来看，主要矛盾就是在：</span><strong><span style="font-size: 14pt; line-height: 150%; font-family: 宋体;">操作说明、培训机制、稳定性。</span></strong><span style="font-family: 宋体;">如何保证这三点。而且从以上来分析，<strong><span style="color: red;">稳定性是最重要的</span></strong>。不稳定，你即使有操作说明和培训机制，其他部门人都躲着实施，谁想去客户那里尴尬丢脸挨骂呀。所以，其他部门人会找各种理由向老板告开发部的状，以躲避实施，说软件太烂，根本无法拿出去。这也就是开发部往往和其他部门关系都不好，开发人员老抱怨自己就闷头辛苦开发解决问题，没有人说好，却被奸人陷害。天长日久，积怨颇深。其实说起来，根源还在开发部自己这里。</span></p>
<p><span style="font-family: 宋体;">　　如何保证稳定性？</span></p>
<p><span style="font-family: 宋体;">　　大家第一想到的就是招测试人员。当然，一些公司的老板是拒绝养测试人员的。另外，如果你只想到招测试人员，其他方法不配合测试人员，即使有了测试人员，软件稳定性仍然不会有提高。所以，有一些工作，是不管有没有测试人员，都必须是我们开发人员要做的：</span></p>
<p><span style="font-family: 宋体;">　　每个人的技术水平都参次不齐的，每个人对自己代码的负责认真性也都是不一样的，所以要想提高稳定性，必须专门从队伍中找一个人，他作为公共代码开发员。每个产品或项目的修改需求，必须首先经过他的思考，能做成公共代码，能封装成函数，就他来做。其他的程序员只管调用函数，实现客户</span>UI<span style="font-family: 宋体;">操作和辅助功能。这个公共代码开发员必须具备以下能力：</span></p>
<p><span style="font-family: 宋体;">　　参与过<strong>几个主要项目的开发、实施、支持</strong>。这样，他对客户需求有综合的把握。如果队伍中没有这样的人，只有开发经理一个人有这样的经理，那么接到客户需求，分析客户需求，分解析辨是公共代码员来做还是其他开发人员来做。</span></p>
<p><span style="font-family: 宋体;">　　公共代码开发员具有负责认真的工作态度，代码细心严谨考虑周详异常保护做的到位内存创建释放有头有尾，代码优美，代码可阅读，代码重构，代码性能和稳定都高公共代码开发人员的技术能力高，知道封装成什么样的函数接口，在灵活性，以后的修改变化性上最好应该说，找一个技术能力好的，工作认真负责的人，应该是不难找到的。<strong>而且专门做这件事，不让他参与各种杂事，他是应该能干好这件事的，而且会越做越好，这就是术有专攻。</strong></span></p>
<p><span style="font-family: 宋体;">　　刚才还讲到一件事，那就是<strong><span style="color: red;">开发经理要熟悉客户需求，而且是深刻理解客户需求</span></strong>。</span></p>
<p><span style="font-family: 宋体;">　　客户需求，客户需求。这个让开发部最头疼的字眼。每当想起客户需求，就想起了以下这些话：</span></p>
<p><span style="font-family: 宋体;">　　程序员说：这是你们家个性的需求，太邪门，我们不做。客户说：不做我们找你们老板去，我们是花钱买了你们的产品的。</span></p>
<p><span style="font-family: 宋体;">　　客户说：我不会用鼠标，你给我做一个语音输入吧。我们还想要一个类似</span>QQ<span style="font-family: 宋体;">的东西供我们内部沟通，你们给我们做一个吧。程序员：我晕。</span></p>
<p><span style="font-family: 宋体;">　　程序员说：等你们内部斗争完，你们协调完了，我再调研需求。</span></p>
<p><span style="font-family: 宋体;">　　似乎，我们在需求上无能为力，我们永远在追赶客户的需求，满足他们的现状，把</span>N<span style="font-family: 宋体;">多家的客户需求都加进软件中，只要能实现的，我们尽量咬牙实现了。</span></p>
<p><span style="font-family: 宋体;">　　最后，我们发现，我们的软件无比复杂，谁也不会用了，连开发部门都不会用了，谁也不知道这个需求当时为什么是这样的。因为无比复杂，所以实施、培训、技术支持都成了问题，稳定性更成了问题。代码互相交叉，根本无法理清有多少交叉影响点。维护的程序员都快崩溃了，天天在祈求，千万别接到客户电话，千万别接到客户电话。</span></p>
<p><span style="font-family: 宋体;">　　这个问题终归是问题，而且是软件开发最大的问题。虽然我们也动用了这样的技巧：</span></p>
<p><span style="font-family: 宋体;">　　客户业务部门不能随便提需求。必须集中汇总到客户</span>IT<span style="font-family: 宋体;">部门，由客户</span>IT<span style="font-family: 宋体;">部门汇总过滤完，再集中报给软件公司客户</span>IT<span style="font-family: 宋体;">部门的需求，必须客户方负责</span>IT<span style="font-family: 宋体;">项目的老板签字才能生效，才能报给软件公司不能随时报，每</span>3<span style="font-family: 宋体;">个月集中报一次不能口头报（即使在现场实施支持也不行），不能电话报，只能</span>MAIL<span style="font-family: 宋体;">或传真来报必须按我们规定的格式报，要严格写清楚需要实现的功能的界面，输入数据或输出数据，输入输出数据的格式要求，谁操作，多长时间操作一次。</span></p>
<p><span style="font-family: 宋体;">　　软件上线后只能免费修改</span>3<span style="font-family: 宋体;">次。以后再有需求，就必须另签合同另收费，否则不予修改。</span></p>
<p><span style="font-family: 宋体;">　　经过这么几招，客户也疲了。需求是不提了，开发部欢呼雀跃。但我们真的做好了么？难道客户真的满意了么？客户为什么要用我们的软件？难道仅仅是为了把他们现在手工做的，然后转到计算机去做。让计算机的查询统计计算速度代替人工？</span></p>
<p><span style="font-family: 宋体;">　　<strong><span style="color: red;">客户为什么要提这样的需求？客户要根本解决什么问题？这些问题谁来想，谁来想解决办法？</span></strong></span></p>
<p><span style="font-family: 宋体;">　　，</span>My God!<span style="font-family: 宋体;">我们无能为力，因为我们是技术人员，我们不懂业务。</span></p>
<p><span style="font-family: 宋体;">　　那这个问题谁来解决？</span></p>
<p><span style="font-family: 宋体;">　　程序员苦笑了：没有人解决，也没有人能解决。客户就要，你不做他就要给老板打电话。</span></p>
<p><span style="font-family: 宋体;">　　噢，那就让程序员的噩梦继续吧。谁也救不了你，能救你的只有你自己。</span></p>
<p><span style="font-family: 宋体;">　　要救我们自己，必须我们自己走出我们自己。谁让我们就处在这样的处境呢？我们都想过的好，只能我们自己救我们自己。</span></p>
<p><span style="font-family: 宋体;">　　那我们就鼓足勇气，走出来，从我们的设计模式、</span>OO<span style="font-family: 宋体;">、软件工程、虚拟接口、反射、持久化、框架中走出来。开发经理来承担起客户行业研究来：</span></p>
<p><span style="font-family: 宋体;">　　客户行业这个群体有多大？大中小规模各有多少家，各分布在什么省？我们面对的最佳客户是什么规模什么信息化程度的？我们的次佳客户是什么规模什么信息化程度的？</span></p>
<p><span style="font-family: 宋体;">　　我们的上层竞争对手、本层的竞争对手、下层竞争对手目前的产品怎么样？他们各自的优点是什么？他们各自的缺点是什么？我们应该突出的优点是什么？我们的缺点是什么？</span></p>
<p><span style="font-family: 宋体;">　　客户行业的过去</span>5<span style="font-family: 宋体;">年，现在</span>2<span style="font-family: 宋体;">年，未来</span>3<span style="font-family: 宋体;">年的发展历史和趋势是什么？他们面临哪些挑战和机遇？</span></p>
<p><span style="font-family: 宋体;">　　我们现在所做的典型客户，他们的组织结构，人员规模，每个岗位每日业务流程、每个岗位每日每周每月每季每年的异常处理业务流程，每个岗位每日每周每月季每年的输入表格，每个岗位每日每周每月季每年的常用数据查询，每个岗位每日每周每月季每年的统计报表针对以上的了解，客户面对未来挑战和机遇，未来应该如何变更他们的岗位和职责和流程，尽量流程少，效率高，运转快？</span></p>
<p><span style="font-family: 宋体;">　　其实，开发经理就相当于业务架构师（因为我们还是游击队，不可能有专职的业务架构师），公共代码开发员就相当于技术架构师。</span></p>
<p><span style="font-family: 宋体;">　　柳传志说的非常好：<strong>搭班子，定战略，带队伍</strong>。你班子不行，上什么需求管理软件、版本管理软件、项目进度管理软件、自动测试、自动集成软件，都是无法落地执行的。</span></p>
<p><span style="font-family: 宋体;">　　有了夯实的业务</span>+<span style="font-family: 宋体;">技术，功能实用、功能符合客户操作、功能稳定。这是软件最基本的要求，就都能满足了。这时候再招测试人员，就能把质量再夯实了。</span></p>
<p><span style="font-family: 宋体;">　　而且，测试人员由于熟知产品，他们还能做技术支持呢，这样可以有更多的开发人员来专职开发，开发的专业性就能越来越提高了。</span></p>
<p><span style="font-family: 宋体;">　　<strong>好的产品，还需要有好的文档和培训，否则其他部门还是不会接开发部的产品的</strong>。</span></p>
<p><span style="font-family: 宋体;">　　那就招一个文案人员，写帮助说明，制作操作视频，制作学习版数据库，参与辅助测试（这个很重要，否则文案人员不熟知产品，无法写出有质量的文案）。有了这些文案的基础，最熟悉产品的非开发人员就有了两个岗位：测试兼技术支持，那么文案就兼起培训工作（由于他自己写文案自己用自己的文案做培训，在培训中会有各种提问，会更加增进他对文案和产品的理解，能写出更好的文案。而且他不是开发人员，他能站在使用者的角度上来写来讲，而且他属于开发部门，他会给产品开发带来更多更好的产品易用性建议）。</span></p>
<p><span style="font-family: 宋体;">　　好了，开发部的四套马车终于起来了，这就是我要讲的开发模式：从游击队转变为兄弟连，从软件作坊走向记住：业务架构、技术架构、测试兼技术支持、文案兼培训，四套马车。</span></p>
<p><span style="font-family: 宋体;">　　我们一直用它，效果很好，搭建团队容易，循序渐进不革命。</span></p>
<p><span style="font-family: 宋体;">　　有了这么好的团队，就能比过去产出更好的软件，软件的质量，软件的进度，软件的竞争力就都上来了，再上各种管理软件：如项目管理软件、版本管理软件、</span>BUG<span style="font-family: 宋体;">管理软件、自动测试软件，就水到渠成了。</span></p>
<p><span style="font-family: 宋体;">　　其他部门也愿意接软件了，软件的实施和培训和技术支持都被其他部门接过去了。开发部门也终于专职专业起来了，整个公司都很协调了，部门间也不互相陷害抱怨了。公司发展速度蹭蹭的。</span></p>
<p><span style="font-family: 宋体;">　　老板看着形式这么好，也不抠门了。奖金福利随之而来。老板看着公司产品销售这么好，也不用再为公司生存发愁了，不用随处找单子养活了，给开发部门更带来了专业理顺的计划发展。老板也开始重视研发部门了，研发部门在公司的地位高多了，给与研发部门的资源和支持也更多了。</span></p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/284545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-06-29 09:36 <a href="http://www.blogjava.net/sdaunch/archive/2009/06/29/284545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>8、水清则无鱼</title><link>http://www.blogjava.net/sdaunch/archive/2009/06/24/283873.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Wed, 24 Jun 2009 01:35:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/06/24/283873.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/283873.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/06/24/283873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/283873.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/283873.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:""@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
line-height:150%;
font-size:10.5pt;
font-family:"Times New Roman";}
h1
{
mso-style-link:" Char Char6";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Times New Roman";
color:red;}
span.CharChar6
{mso-style-name:" Char Char6";
mso-style-link:"标题 1";
font-family:宋体;
color:red;
font-weight:bold;}
/* Page Definitions */
@page
{}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
</style>
<![endif]-->
<h1>8<span style="font-family: 宋体;">、水清则无鱼</span></h1>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">我的朋友开了家屁小公司，纯粹的三五个人十来条枪。每年还不死，但活的也很辛苦。平时做的也就是两三万的单子，运气好能做</span>8-10<span style="font-family: 宋体;">万的单子。那天，突然给我打了电话，说要请我吃饭。</span></p>
<p><span style="font-family: 宋体;">　　饭肯定是不能白吃的。朋友告诉我：唉，烦心啊。客户不成熟，是麻烦事。客户太成熟，也是个麻烦事。</span></p>
<p><span style="font-family: 宋体;">　　我说，此话怎讲？</span></p>
<p><span style="font-family: 宋体;">　　我朋友说：你看，我过去跟单，客户对软件不懂，但他却知道有个华军软件园，里面有可以免费下载的管理软件。我报个两万的价格客户直晃脑袋说：我以为你们的软件</span>600<span style="font-family: 宋体;">块钱就能买到，怎么你们要杀人啊？</span></p>
<p><span style="font-family: 宋体;">　　我朋友一脸苦难相：两万块您都觉得贵啊。我们可是带技术支持，还有培训，还要给您做定制化开发呢。我给您这两万的报价，也已经是我插草标卖人的价儿了。</span></p>
<p><span style="font-family: 宋体;">　　客户还是直晃脑袋：谁不知道你们软件开发，就一台电脑一个人，啥费用也没有，就卖我们两万。你看我们，进原料买地建厂房招人买流水线搞运输招商做广告打价格战，我们可是水深火热啊。我们全是成本，毛利极低，赚的都是血汗钱。你们呢，啥原材料也不进，流水线也不买，也不建厂房，居然卖两万，你说你们的利润多高？</span></p>
<p><span style="font-family: 宋体;">　　我朋友无语。</span></p>
<p><span style="font-family: 宋体;">　　我朋友就盼着能有个了解软件行业艰难的企业</span>CIO<span style="font-family: 宋体;">能互表衷肠。</span></p>
<p><span style="font-family: 宋体;">　　这回他总算遇见了。</span></p>
<p><span style="font-family: 宋体;">　　大活儿。这次可是大活儿。我的朋友这样评价这个项目。</span></p>
<p><span style="font-family: 宋体;">　　原来是一家企业，计划要给它的全国经销商渠道开发一套管理软件，以能管理全国进销存的情况。但是这次就是由于是个大活儿，所以客户方要求把价格报清楚了，不能开发费</span>+<span style="font-family: 宋体;">实施费</span>+...=<span style="font-family: 宋体;">总费用这么简单。他需要我给他说出个道理。为什么这么多。而且这个企业</span>CIO<span style="font-family: 宋体;">最难搞的就是，他明告诉我，别跟我说你们一个开发人员的每天费用是</span>3000<span style="font-family: 宋体;">块。你开发人员月工资</span>9<span style="font-family: 宋体;">万啊？</span></p>
<p><span style="font-family: 宋体;">　　这回我是折了。我过去都是做小单子，和客户反正也有关系（现在哪个上三万元的单子是打陌生电话打出来的？），于是就囫囵吞枣就把单子签了。水清则无鱼，看似软件利润高，但软件这个东西看不见摸不着不好销售啊，报的价格高了谁都觉得你利润高，不吃你吃谁。所以到处都是爷，哪个门都得把香烧到了，最后落手里其实我也剩不下多少个子儿。还得给员工发工资，还得请客送礼，还得交税，还要交办公室租金，每月这费那费都是要钱的。苦啊。</span></p>
<p><span style="font-family: 宋体;">　　我故意逗他：那你干脆关了公司，回去继续当程序员。</span></p>
<p><span style="font-family: 宋体;">　　我的朋友诡秘一笑：呵呵，还是比给别人打工赚的多。别跟我打岔了，快给我想个方法，怎么报价让他觉得合理。</span></p>
<p><span style="font-family: 宋体;">　　我说：看到了吧。<strong>耍嘴皮的哑了口，混天黑的犯了愁</strong>。以后，<strong><span style="color: red;">拍脑门的时代就算一去不复返了</span></strong>。客户也不是冤大头，你说个</span>10<span style="font-family: 宋体;">万就给你</span>10<span style="font-family: 宋体;">万。你以后不给说清楚了，谁也不会跟你签单。</span></p>
<p><span style="font-family: 宋体;">　　我朋友说：那你快教教我啊。</span></p>
<p><span style="font-family: 宋体;">　　我说：唉。我遇到的问题和你不一样，但我的解决方法也能解决你的问题。</span></p>
<p><span style="font-family: 宋体;">　　我过去遇到的问题是：我一直在琢磨如何提高销售收入。否则，这么老路子做软件，费死劲也挣不了几个钱。所以，我在研发过程管理上引入了一些方法，引入专职的项目经理、公共代码开发、测试员，来收集需求、控制需求、安排进度、把控质量。在产品制造上我引入了美工来美化界面，引入了文案编写了精美的帮助文档、产品白皮书、演示版和视频教学。让销售拿出去给客户打单，一看</span>PPT<span style="font-family: 宋体;">一看产品演示就感觉这是个专业的产品。另外，我在实施和咨询和技术支持也下了大功夫，让这种专业性一直连贯的保持下来，否则就会让客户感觉签单前很专业，一签了单子就糊弄人，这样生意就没得做了。</span></p>
<p><span style="font-family: 宋体;">　　有时候你会遇到这样的场景：客户说你的东西太贵了，而你的回答往往是一点不贵啊，我才给您报</span>3<span style="font-family: 宋体;">万块，您的企业一年的流水就一个亿呀，您坐的宝马车一次保养就</span>3000<span style="font-family: 宋体;">多块。您看，软件能全体员工用，而且能提高您企业的运营效率，才</span>3<span style="font-family: 宋体;">万块，多值啊。</span></p>
<p><span style="font-family: 宋体;">　　但客户还是觉得贵。为什么呢？不是他掏不起这三万块钱，他可能请他的客户吃饭，一顿饭就能吃</span>3<span style="font-family: 宋体;">万块。他为什么觉得他吃饭</span>3<span style="font-family: 宋体;">万块不贵，而</span>3<span style="font-family: 宋体;">万块买你的软件就贵呢？<strong><span style="color: red;">原因就在于他觉得你产品不值</span></strong></span><strong><span style="color: red;">3</span></strong><strong><span style="font-family: 宋体; color: red;">万块。但到底值多少钱，他也不了解软件成本构成，所以他按心理估计，给你的报价上打个</span><span style="color: red;">5-7</span></strong><strong><span style="font-family: 宋体; color: red;">折应该没错。</span></strong></p>
<p><span style="font-family: 宋体;">　　而软件这个东西，尤其是管理软件这个东西，就非常类似古董字画一样。<strong><span style="color: red;">在识货的人看来，他非常值。在不识货的人看来，一文不值。</span></strong>而管理软件的销售人员，尤其是销售这个行当，正规的管理方法很少，大部分都是术和案例，喜欢出新招出奇招，而对按部就班的流程运作颇为不感冒，所以对固化流程的管理软件也是觉得没什么大作用，比</span>EXCEL<span style="font-family: 宋体;">贵还比</span>EXCEL<span style="font-family: 宋体;">难用，所以也讲不出来这个管理软件该值多少钱。客户也不知道值多少钱，销售也不知道值多少钱。这样，双方的价格磋商，就成了互相猜心。客户觉得打他个</span>5<span style="font-family: 宋体;">折，他估计就实在了。而销售呢，估计客户能承受</span>xx<span style="font-family: 宋体;">万的价格，所以我就报个</span>xx<span style="font-family: 宋体;">万。<strong><span style="color: red;">价格和软件成本没了关系。</span></strong>到底这个项目做到最后是赚是赔，都不清楚。反正单子我是签了，我的销售任务完成了。</span></p>
<p><span style="font-family: 宋体;">　　我就是为了应对这种销售和客户乱猜拳互博弈谈价格，才出此方法。</span></p>
<p><span style="font-family: 宋体;">　　我先给你说说软件<strong>开发费怎么报</strong>。下次再请我吃饭，我再跟你说如何<strong>给实施报价</strong>。</span></p>
<p><span style="font-family: 宋体;">　　产品开发由以下阶段构成：</span></p>
<p><span style="font-family: 宋体;">　　<strong>客户调研、客户调研报告编写功能设计、功能设计说明书编写开发测试帮助文档、培训课程、培训演示版本编写其实，产品开发完毕后，还必须由开发部的文档组对实施部门的培训专员和项目经理进行内训，否则产品知识无法通过培训专员和项目经理传递给客户。这个内部培训也都是有成本的，而客户和你，往往都会遗漏的。</strong></span></p>
<p><strong><span style="font-family: 宋体;">　　由于功能说明书为内部产品开发使用，所以功能说明书不会销售给客户。如果客户非要连功能说明书都认为是他的产品的一部份，那么他也需要花钱买走。这也是文案人员和项目经理辛苦劳动的成果，又不是自动产生的。有付出就必然要求回报。</span></strong></p>
<p><span style="font-family: 宋体;">　　产品开发团队由如下人员构成客户调研团队产品开发团队产品测试团队产品文档教育团队客户调研团队，由项目经理和培训专员构成，亲自到客户现场去调研。每个调研团一般由</span>2<span style="font-family: 宋体;">名人员构成，</span>1<span style="font-family: 宋体;">名项目经理，</span>1<span style="font-family: 宋体;">名培训专员。由于不同经验的人当然工资待遇不同，而工作的质量也就不同。所以我们的调研项目经理，也有高级调研项目经理，中级调研项目经理，调研项目经理三个等级。你如果作为客户，你敢把企业的需求和流程梳理交给一个刚毕业出来的毛头小子么？他对企业的感觉连企业的一个看门人都不如。当然，不同等级的调研项目经理，调研一天的工作费用当然也是不同的。与之匹配的调研助理（培训专员）也是有不同的经验等级的。</span></p>
<p><span style="font-family: 宋体;">　　调研费用，按调研团队人数和工作天数和他们的工作费用和调研家数计算。出差过程所花费的交通、住宿、餐费不包含在他们的工作费用中。调研是调研费，这是调研的工作，但出差产生的费用是出差的费用。如果你把这些都整到一块，你的调研费用肯定看起来很高，客户又质问你怎么一天</span>3000<span style="font-family: 宋体;">块了，还不如报的时候就清楚的报。哪里都需要钱呀。</span></p>
<p><span style="font-family: 宋体;">　　一般，调研周期为两周。先是调研收集客户现有状况细节，然后进行现有状况梳理。梳理理解后，总结疑问，并与调研方开会，双方就疑问和目标和需求进行讨论。最后是根据多次讨论进行调整，得出最后的调研报告。</span></p>
<p><span style="font-family: 宋体;">　　我为啥说需要两周呢。因为一个企业有许多部门许多岗位。<strong><span style="color: red;">你要把客户的整个组织结构和岗位职责和流程，和他们的现状问题，和他们的需求目标，都需要调查清楚，而且还要和他们协商统一认可好如何改进，否则你怎</span></strong>么设计适合他们的系统。没有两周的调研和讨论和反复修改磨合，你出来的软件更是痛苦，调研</span>3<span style="font-family: 宋体;">天，开发</span>1<span style="font-family: 宋体;">月，实施和不断修改</span>2<span style="font-family: 宋体;">月，维护修改和稳定和技术支持</span>3<span style="font-family: 宋体;">月。最后客户还抱怨你的软件太不稳定，</span>N<span style="font-family: 宋体;">多需求都没有做，当然不能付尾款了。你不答应他们的需求，你就拿不到尾款。于是，需求修改更新，发现又引出了其他的</span>BUG<span style="font-family: 宋体;">和需求，噩梦循环啊。</span></p>
<p><span style="font-family: 宋体;">　　咱们说说调研。</span></p>
<p><span style="font-family: 宋体;">　　例如，调研</span>10<span style="font-family: 宋体;">家客户。客户分布在东北、华北、华东、华南、华中、西南、西北。调研需要</span>2<span style="font-family: 宋体;">周的时间。如果遇到星期六日还需要出差进行工作，那么休息日加班费就按国家规定累计。</span></p>
<p><span style="font-family: 宋体;">　　这样来算一下费用。高级调研项目团队，中级调研项目团队，标准调研项目团队，（每个相应等级的调研项目经理每天的调研工作费用</span>+<span style="font-family: 宋体;">他的每天对应的餐费交通费通讯费住宿费</span>+<span style="font-family: 宋体;">每个相应等级的调研助理每天的调研工作费用</span>+<span style="font-family: 宋体;">他的每天对应的餐费交通费通讯费住宿费）</span>x10<span style="font-family: 宋体;">天工作日</span>x10<span style="font-family: 宋体;">个城市，你看看多少调研费用吧。你用一个</span>EXCEL<span style="font-family: 宋体;">做个自动计算就</span>OK<span style="font-family: 宋体;">了。你把这个公式内置到</span>EXCEL<span style="font-family: 宋体;">中，客户只需要选择自己想要等级的调研人员，填写要调研一家的天数，再填写要调研的总家数，调研费用自然就出来了。如果客户觉得不能接受，就让客户自己玩这个计算公式，<strong>直到他自己都觉得确实没什么水分了作罢</strong>（他也不是变态狂，以榨干软件公司逼死软件公司为乐。所以，<strong>他认可的是一个合理的报价，而不是离谱的报价。他认可的合理的利润还是手下留情的</strong>）。</span></p>
<p><span style="font-family: 宋体;">　　想想吧。没有跟客户要一点浑水摸鱼的费用。都是大家都能认可和理解的费用。假设，一个在本行业信息化工作了</span>5<span style="font-family: 宋体;">年的调研经理，他的月薪水达到</span>6000<span style="font-family: 宋体;">块应该没有人质疑吧。那么他这个人每天最低的成本就是</span>200<span style="font-family: 宋体;">元。再说了，这个员工消耗的其他办公费用与福利与税金也是有均摊成本的（企业总不能无原因生钱吧。钱肯定还是要从客户这个源头来）。</span></p>
<p><span style="font-family: 宋体;">　　另外，我还没有计算调研团队在这</span>2<span style="font-family: 宋体;">周的调研时间内，还有</span>4<span style="font-family: 宋体;">天的休息日，如果工作的话，这个加班费用还没算呢。你可以算一下。</span></p>
<p><span style="font-family: 宋体;">　　调研完了，就要开发了。你以为雇佣几个编码人员就能搞定了。那样的搞定也是活稀泥的，最后不断修改的成本能让你把赚的钱都吐出来。所以为了以后不秋后算账，我们就得从一开始好好做（如果你想赚更多的钱，可以把我给你讲的配置都缩减了。当然，质量和效果也就缩减了。一文价钱一文货，谁也不白给。国内软件如此现状，就是为了多赚钱，最后把客户给的合适的费用都缩减了，但是给客户报的却是达到</span>100%<span style="font-family: 宋体;">效果的人员数量和人员素质和人员天数。这个中间差就是个小九九了）。</span></p>
<p><span style="font-family: 宋体;">　<strong>　产品开发团队，一般由以下角色构成开发总监</strong></span><strong>1</strong><strong><span style="font-family: 宋体;">名架构师</span>1</strong><strong><span style="font-family: 宋体;">名，公共代码开发人员</span>2</strong><strong><span style="font-family: 宋体;">名业务开发组长</span>1</strong><strong><span style="font-family: 宋体;">名，主要代码开发</span>1</strong><strong><span style="font-family: 宋体;">名，辅助开发</span>1</strong><strong><span style="font-family: 宋体;">名。</span></strong><span style="font-family: 宋体;">每个子系统由</span>3<span style="font-family: 宋体;">名人员构成。假设有</span>4<span style="font-family: 宋体;">个子系统，就需要有</span>12<span style="font-family: 宋体;">名开发人员产品测试团队，一般由以下角色构成测试员</span>1<span style="font-family: 宋体;">名。假设有</span>4<span style="font-family: 宋体;">个子系统，就需要有（</span>4+1<span style="font-family: 宋体;">）</span>=5<span style="font-family: 宋体;">名开发人员，其中</span>+1<span style="font-family: 宋体;">是公共代码测试。</span></p>
<p><span style="font-family: 宋体;">　　产品文档团队，一般由以下角色构成每个子系统一个文档编写与内部培训人员。假设有</span>4<span style="font-family: 宋体;">个子系统，就需要有</span>4x1=4<span style="font-family: 宋体;">名文档人员。</span></p>
<p><span style="font-family: 宋体;">　　所以，一个产品开发过程，以</span>4<span style="font-family: 宋体;">个子系统为例，共需要参与开发人员客户调研团队</span> 2<span style="font-family: 宋体;">名产品开发团队</span> 16<span style="font-family: 宋体;">名产品测试团队</span> 5<span style="font-family: 宋体;">名产品文档团队</span> 4<span style="font-family: 宋体;">名共计</span>27<span style="font-family: 宋体;">名参与者（估计许多人会说我三五杆枪能有这么多人么？楼主真是搞笑痴心妄想白日做梦。<strong>我报这个人数，是为了计算一个能达到客户效果的一个合理人员配置上</strong>。国内软件公司往往无法满足，所以效果就不断衰减。不过，我一般都建议三五条枪的企业最好能从实施部门抽调过来调研、文档、测试人员，这样人数可以缩减，但<strong>要做的事情不能缩减</strong>，这样效果衰减的就不会很厉害。很多三五条枪的企业现状都是做一单骗一单砸一单，就是什么人也没有，两个开发人员从调研到设计到开发到测试到实施到支持都这两位老哥。甚至干脆一个人全挑。这样的现状如果不去想办法改观，软件质量和软件竞争力仍然无从提高。）。</span></p>
<p><span style="font-family: 宋体;">　　客户调研周期</span>14<span style="font-family: 宋体;">天。产品开发周期</span>60<span style="font-family: 宋体;">天，产品测试周期</span>10<span style="font-family: 宋体;">天，产品文档周期</span>10<span style="font-family: 宋体;">天，产品内部培训周期</span>10<span style="font-family: 宋体;">天。由于产品测试周期和开发同步测试，自己独立出来的</span>10<span style="font-family: 宋体;">天是综合测试。产品文档周期</span>10<span style="font-family: 宋体;">天也是如此。而产品内部培训周期</span>10<span style="font-family: 宋体;">天，是必须在产品文档发布后才能培训。</span></p>
<p><span style="font-family: 宋体;">　　<strong>所以总的项目周期会是</strong></span><strong>14+60+10+10=94</strong><strong><span style="font-family: 宋体;">天，</span>27</strong><strong><span style="font-family: 宋体;">名参与者。才能保证一个产品（</span>4</strong><strong><span style="font-family: 宋体;">个子系统</span>+1</strong><strong><span style="font-family: 宋体;">个系统管理系统）开发的质量。</span></strong></p>
<p><span style="font-family: 宋体;">　　平均每人</span>6000<span style="font-family: 宋体;">元月工资算（因为有低工资的培训专员和辅助编程，也有中等工资的各职责经理组长，也有高工资的总监，所以拉平</span>6000<span style="font-family: 宋体;">元，应该也算比较合理。）。一个产品的开发大约是</span>6000x3<span style="font-family: 宋体;">月（</span>94<span style="font-family: 宋体;">天）</span>x27<span style="font-family: 宋体;">人</span>=486,000<span style="font-family: 宋体;">费用（这可都是成本，诸位客官都看到了，里面没有加任何企业的利润点）。再加上</span>30%<span style="font-family: 宋体;">的毛利，共</span>486,000+145800=631,800<span style="font-family: 宋体;">。大约</span>63<span style="font-family: 宋体;">万开发费用和</span>3<span style="font-family: 宋体;">个月的时间才能保证</span>4<span style="font-family: 宋体;">个业务管理系统的软件质量和进度。</span></p>
<p><span style="font-family: 宋体;">　　这些人的成本，你都可以做一个计算公式，明明白白得算。在客户要求的质量、时间限制内，使用多少人，使用多高工资的人，一算，成本就出来了。成本出来了，再加上你希望的合理毛利，就得出了你应该报出来的价格了。否则，<strong><span style="color: red;">你拍脑门报价，做到项目结束，你还真有可能亏损了。那些被项目拖死的公司还少吗？</span></strong></span></p>
<p><span style="font-family: 宋体;">　　的毛利，剔除销售费用和税金和管理费用，纯利在</span>15%<span style="font-family: 宋体;">以下。也就是说，年销售</span>1000<span style="font-family: 宋体;">万，纯利才</span>150<span style="font-family: 宋体;">万，其他都产生了费用支出。根本无法支撑下一年的生产再发展。</span></p>
<p><span style="font-family: 宋体;">　　这样来看，软件公司确实活的挺惨。</span></p>
<p><span style="font-family: 宋体;">　　这样来深入计算软件公司一个软件的成本和利润，我想那个说</span>600<span style="font-family: 宋体;">元软件的客户该理解了吧（当然，那些总觉得老板是黄世仁的程序员，心里或许也能舒坦舒坦）。</span></p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/283873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-06-24 09:35 <a href="http://www.blogjava.net/sdaunch/archive/2009/06/24/283873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>4、人，是人，真的是人</title><link>http://www.blogjava.net/sdaunch/archive/2009/06/23/283677.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Tue, 23 Jun 2009 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/06/23/283677.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/283677.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/06/23/283677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/283677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/283677.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:""@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
line-height:150%;
font-size:10.5pt;
font-family:"Times New Roman";}
h1
{
mso-style-link:" Char Char6";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Times New Roman";
color:red;}
span.CharChar6
{mso-style-name:" Char Char6";
mso-style-link:"标题 1";
font-family:宋体;
color:red;
font-weight:bold;}
/* Page Definitions */
@page
{}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
</style>
<![endif]-->
<h1>4<span style="font-family: 宋体;">、人，是人，真的是人</span></h1>
<p><span style="font-family: 宋体;">　　有网友评论我之前的几篇博文：分析的不错，方案似乎也很能解决问题！不过必须满足一个潜条件：一定要找到非常合适人。现实中，就连最基本的程序员，找个合格的也不容易（<strong>聪明伶俐的养不住、经验丰富的养不起</strong>、迟钝呆傻的没法要、碰上心术不正的还够你喝一水壶的）还有网友评论：楼主所说的很多方法，都是假设了客户还不错、对项目的重视程度、习惯于正规化的程度都还过得去，而楼上有些朋友的质疑则是指出这些资源不一定满足的情况；但是跟贴最多的评论就是：现实问题描述的很精确，但解决方案不现实，太理想化，老板根本不可能给你人。<strong>如果真的发慈悲心，也是给你一个新人让你哭死。你想主导项目，省省吧，死了你的心吧，一切都是老板说了算</strong>。而且，你敢和客户说个不字，看来你是不想要你的饭碗了。还是乖乖敲好你的代码，多干活，多跟客户搞好关系。高手做啥都是高手，低能再培养再有方法管理他也是低能。你这样研究，只能吃饱饭瞎想瞎扯蛋，有你这工夫，早就把项目做好了。</span></p>
<p><span style="font-family: 宋体;">　　种种评论来看，<strong>一切的根源都是人，是人</strong>。大家都觉得我的方法要想实施，必须老板支持，员工也是高素质的，客户也是高素质的。而三者要想凑到一起具备，根本不可能。所以我的方法算是理想的痴人说梦。</span></p>
<p><span style="font-family: 宋体;">　　能支持的老板从哪里来？高素质的员工从哪里来？高素质的客户从哪里来？好像一切都是运气而来。好像我们就有高薪能聘得起高素质的员工。好像我们的产品面对的就是高素质的客户。</span></p>
<p><span style="font-family: 宋体;">　　但我回顾了自己</span>10<span style="font-family: 宋体;">多年的从业经验和管理经验，我并没有发现这个规律。我并非供职国际巨头公司，也不是国内知名企业，只是信息化行业内略有名气而已。手下很少出现名牌大学的员工，也很少能达到所谓的高薪（我自认自己还没有在马云、史玉柱、牛根生、柳传志这样大胸怀大眼光的企业家手下任过职，我们所从事的行业信息化也不是暴利的行业，大家也都知道管理软件没啥暴利，定制化修改、实施、咨询、培训、支持占去了很多成本。），我们的客户也是各种各样的人都有，从挖煤暴发户的私营老板到死气沉沉勾心斗角的国企，我们的客户千奇百怪。</span></p>
<p><span style="font-family: 宋体;">　　在这样的环境下，我能把方法用起来，我和许多网友也交流过，最重要的是我认可了以下观点，这就是一个职业经理人和老板的关系：</span></p>
<p><span style="font-family: 宋体;">　　<strong>老板都是疑人也用用人也疑。用人不疑，疑人不用，我不奢望。</strong></span></p>
<p><span style="font-family: 宋体;">　　再劳苦功高，我也只是职业经理人，我不拥有这个企业的哪怕</span>1%<span style="font-family: 宋体;">所有权，所以我做好职业经理人本分，老板的归老板，职业经理人的归职业经理人。<strong>职业经理人的职责范围的，老板权力范围的，不要超越，也不要动歪脑筋。</strong>即使公司大部分的收入都是你研发的产品带来的。</span></p>
<p><span style="font-family: 宋体;">　　计划不计划一件事情，执行不执行一件事情。<strong>一定要以老板利益为目的</strong>。老板不赚钱，一切好事一切好想法都会被老板推翻，老板就是老板。老板赚钱赚的眉开眼笑，其他的事情就好办的多。这是很多职业经理人居然都认识不到的，他们总抱怨老板限制太死，什么资源也不给，干活还贼累。根源就出在这里了。想实现你的想法，<strong>必须在实现了老板想法和目的的前提下才能做</strong>。所以我的方法能实现，多靠此。</span></p>
<p><span style="font-family: 宋体;">　　而且我的方法不是为了我自己有什么好处，我的每一个方法也都不是为了正规化装修门面图好看。<strong>我的方法都是为了解决实际问题，为了老板赚钱更快更省成本更容易，员工更省力，客户更满意，而且每个方法都是在本企业能力和成本范围内能执行落地的解决方案。</strong>这样的解决方案，哪个老板会不支持呢。但很奇怪的是，很多研发部主管都忽略这个重点，老板在想利益，他在想技术。两人说不到一个目的去，互相不理解互相不支持互相埋怨，久而久之互相猜疑互相提防互相留一手。其实技术就是个手段，赚钱是目的，双方一起绑定去赚钱，怎么合法的赚更多钱怎么来。如果研发主管能脚踏实地的从本企业的能力和困境和现状去思考改进方法执行落地，而不是抱怨这样的环境没法实现想法消极怠工或心想跳槽，我想很多心结就都打开了。</span></p>
<p><span style="font-family: 宋体;">　　<strong>只有和老板具备了这样的距离和关系</strong>，我的方法才好实施下去。所以，很多人觉得太理想化，就是和老板没有找到自己的位置。</span></p>
<p><span style="font-family: 宋体;">　　但是，即使有这样的基础，要实现我所述的方法，也需要其他的环境支持。</span></p>
<p><span style="font-family: 宋体;">　　我个人是这么看的：</span></p>
<p><span style="font-family: 宋体;">　　<strong>好的氛围，才会引入、留住好的人（乱世强盗多就是这个理）</strong>。</span></p>
<p><span style="font-family: 宋体;">　　<strong>好的人，才会有好的制度，并且保持好这个制度（制度是人定的）</strong>。</span></p>
<p><span style="font-family: 宋体;">　　<strong>好的人和好的制度，才会遇到好的客户</strong>（有句老话，夜路走多了总会遇见鬼。有些人老想着邪门事，最后也被邪人玩。近朱者赤近墨者黑，什么人总遇到什么人，就这个道理）。好客户就会产生好的结果。</span></p>
<p><span style="font-family: 宋体;">　　<strong>所以，好的人才，好的客户都不是运气来的，而是来自你自己。你就是控制源头的人。</strong></span></p>
<p><span style="font-family: 宋体;">　　如何制造好的氛围，我讲讲我的职业经理人管理人的一些心得：</span></p>
<p><span style="font-family: 宋体;">　　<strong>师傅制</strong>。这里没有总监，没有经理，只有师傅，老师。总监，经理，会让员工产生隔阂，距离，权力争斗。每一个人总有一个师傅。每一个新人进来，都要指定一位合适的师傅。尤其是新人，更要短期内注意看时候合适，不合适就要更换合适的师傅。什么问题都可以问师傅，从技术到公司制度到公司新闻公司历史到职业发展规划到个人生活问题。团队的凝聚力，配合性，归属感，责任感，很多问题都被人的感情消化了。</span></p>
<p><span style="font-family: 宋体;">　　<strong>朝九晚五，禁止加班</strong>。其实大部分程序员也是不喜欢加班的（不过有些程序员是光棍，也是漂在北京，反正也是一个人，于是就喜欢呆在公司上网玩游戏看小说看电影吹空调，美其名曰加班。还有一类老板喜欢看表面功夫，谁加班就喜欢谁，于是大家都装做很忙都要加班）。因为加班不给钱。不给钱，还加班，天长日久就觉得自己很亏，心里不平衡，各种心思就都有了。其实也没有多大的事。我的老板一开始对我的不加班也是心存戒心，但是每次交给他的结果比加班的部门做的都好都快，他也就默许了。</span></p>
<p><span style="font-family: 宋体;">　　<strong>良好的办公环境和良好的个人形象</strong>。我们看到美女就兴奋的口吐莲花，我们看到阳光溪水草地我们就心情舒畅。当然，我们看自己，别人看我们，都是一个道理。心情好，工作才能好。一个满桌狼藉充满烟味饭味脚丫子味有人在冥思苦想解决问题有人在打游戏有人在放朋克音乐有人在骂有人在打闹嬉笑有人把脚放到桌子上的办公环境，我看谁都会逃离。</span></p>
<p><span style="font-family: 宋体;">　　<strong>以更快更省成本更容易完成任务为目标</strong>，以赚更多钱为目标，以提高产品质量产品价值产品售价为目标，鼓励员工进行自我岗位上的改进创新，我经常给与交流和指导，一旦有效，进行精神或物质的奖励或职位提拔或工资晋级。</span></p>
<p><span style="font-family: 宋体;">　　<strong>好的氛围有了，就需要有好的人才</strong>。以下是我引入好的人才的几个心得：</span></p>
<p><span style="font-family: 宋体;">　　人的年龄和工作经验拉开距离。年年招，时时招。不断看人，试人，滤人，培养人，形成<strong>层次感有阶梯有接力的员工组织，绵绵不断前赴后继，不会出现人才地震、集体疲劳、小团伙争斗</strong>。避免不同高低职位上全是</span>80-84<span style="font-family: 宋体;">年的人。下属还在窝里斗互相不服（很多员工不看对方能力，就看对方的工资和年龄。凭啥你就是我师傅？），那么客户逼你，老板压你，其他部门利益冲突你，下属还闹你，你这个孤独人算是失道者寡助也。</span></p>
<p><span style="font-family: 宋体;">　　<strong>人的技术能力高低先放一边。</strong>首先要过</span>EQ<span style="font-family: 宋体;">关。有些中小型企业没有</span>HR<span style="font-family: 宋体;">经理，一般考察</span>EQ<span style="font-family: 宋体;">，都是老板把关。如果你现在招人没有老板把关，那么必须先考察人的</span>EQ<span style="font-family: 宋体;">，再考察他的技术能力。我最怕有些羡慕科学管理的管理者照搬什么</span>EQ<span style="font-family: 宋体;">测试问卷或什么团队游戏来评测。我的评测方法仍然是<strong>不讲道理，要讲经历</strong>。没有工作经历，至少有学习经历和生活经历吧。<strong>一个人的情感、压力、正义感、真诚感、领悟力、心细观察力、思路整理总结能力、关注全面平衡能力、执着力，都能看的出来</strong>。</span></p>
<p><span style="font-family: 宋体;">　　招聘程序员也得看这些。我曾遇到一个程序员，思维混乱所以代码也混乱，思考也不全面，程序到处都是漏洞，思路也不自我整理总结，无法举一反三，给他讲了多遍的需求他都无法自己重述，一有了问题很急躁说搞不定了，一看还是很简单的问题，把错误提示原模原样输入到百度中查百度就能搜到好多，你说这样的程序员算技术合格吗？</span></p>
<p><span style="font-family: 宋体;">　　其实<strong>，试用期的三个月就是主要看他的</strong></span><strong>EQ</strong><strong><span style="font-family: 宋体;">和他的技术能力、理解学习成长能力，而不是片面只看他的现状技术能力</span></strong><span style="font-family: 宋体;">。一个不愿意学习钻研，没有方法钻研快速学习理解，推一下动一下，或者怎么说都理解不了的，都需要统统辞掉。另外，对于心术不正有仇必报不服管教之类，早就扫出门外。一个讲究吃穿用享受或者满口脏话习惯毛病一堆或者不孝顺父母或者满口介词的人坚决不能要。</span></p>
<p><span style="font-family: 宋体;">　　<strong>专业发展，流程协作。如果不专业化，老板有什么活就分配什么活，时间短了还认为自己是在学习更多知识在锻炼。时间长了就会觉得自己就像个混子，干什么都干过，但什么都拿不起来。出去应聘啥职位，是应聘开发呢，项目经理呢，实施呢，支持呢，销售呢。啥都做过，但啥都没做专，都了解个皮毛，真要让上手还真给人家拿不下来。心就慌了，觉得自己是个被老板困在手心的小鸟，无法飞出本企业的樊笼，一旦飞出就要饿死没有能力存活。好可怕。难道只能在这家公司耗死了？赶快能逃逃吧，逃到一个正规的专业的公司去。</strong></span></p>
<p><span style="font-family: 宋体;">　　下一阶段目标交流制定。交流，我想每个</span>CTO<span style="font-family: 宋体;">或技术总监或研发经理都会做。交流可以了解员工的困难和心中的疑惑、个人期望、个人专业兴趣的变化、人生观世界观技术观管理观生活观（以调整自己以后和该员工如何交流、如何讲解工作、如何鼓励、如何布置任务、如何考察等等）。交流也可以让员工多了解自己是怎么想的。双方在日常很多事情的分歧和误解就会消除，心会往一处想，劲会往一处使。但是，交流也不仅仅实现这些目标。更重要的是，交流，主要为了能给该员工制定一个切实可行的、某段时间段内可达到的、他也喜欢也愿意努力的、也会他未来职业发展很有好处的职业目标。<strong>没有目标的工作，虽然他很努力，但是他容易迷失方向。</strong>如果他又是一个不能很有悟性很有规划的人，他的工作就会形成做一天和尚撞一天钟。撞钟撞的不错，但没什么更高层次的提高。天长日久，就会木然，倦怠，不思进取，思想守旧，遇到新问题无法突破。所以，我会根据双方的交流，和员工一些协商一个下一阶段的职业发展目标，并且时常指导调整他的做事方法和思考方法，给他讲解一些我过去的工作经验和我的感受，鼓励指导他们有计划有目标的走的更高更专业。这是很多研发部门主管没有做的一点。</span></p>
<p><span style="font-family: 宋体;">　　最后有几句话和大家分享一下：</span></p>
<p><span style="font-family: 宋体;">　　毛主席说：社会主义就是打土豪分田地（不是资本论这样的天人天书），要天天讲，时时讲，到处讲，要团部建设到连队。所以，借用毛主席的方针，咱们的团队精神建设也得这样。<strong>天长日久，就形成了文化精神，就形成了习惯</strong>。</span></p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/283677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-06-23 09:36 <a href="http://www.blogjava.net/sdaunch/archive/2009/06/23/283677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>5、习惯决定性格，性格决定命运，细节决定成败--实施经理的工具箱</title><link>http://www.blogjava.net/sdaunch/archive/2009/06/17/282761.html</link><dc:creator>sea</dc:creator><author>sea</author><pubDate>Wed, 17 Jun 2009 01:29:00 GMT</pubDate><guid>http://www.blogjava.net/sdaunch/archive/2009/06/17/282761.html</guid><wfw:comment>http://www.blogjava.net/sdaunch/comments/282761.html</wfw:comment><comments>http://www.blogjava.net/sdaunch/archive/2009/06/17/282761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdaunch/comments/commentRss/282761.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdaunch/services/trackbacks/282761.html</trackback:ping><description><![CDATA[<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 11" />
<meta name="Originator" content="Microsoft Word 11" />
<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" /><!--[if gte mso 9]><xml>
Normal
0
7.8 磅
0
2
false
false
false
MicrosoftInternetExplorer4
</xml><![endif]--><!--[if gte mso 9]><![endif]--><style>
<!--
/* Font Definitions */
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:""@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
line-height:150%;
font-size:10.5pt;
font-family:"Times New Roman";}
h1
{
mso-style-link:" Char Char6";
margin-top:17.0pt;
margin-right:0cm;
margin-bottom:16.5pt;
margin-left:0cm;
text-align:justify;
text-justify:inter-ideograph;
line-height:240%;
page-break-after:avoid;
font-size:16.0pt;
font-family:"Times New Roman";
color:red;}
span.CharChar6
{mso-style-name:" Char Char6";
mso-style-link:"标题 1";
font-family:宋体;
color:red;
font-weight:bold;}
/* Page Definitions */
@page
{}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.Section1
{page:Section1;}
-->
</style><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{
mso-style-parent:"";
font-size:10.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
</style>
<![endif]-->
<h1>5<span style="font-family: 宋体;">、习惯决定性格，性格决定命运，细节决定成败--</span><span style="font-family: 宋体;">实施经理的工具箱</span></h1>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">前段时间，</span>
<span style="font-family: 宋体;">项目经理的工具箱</span>---<span style="font-family: 宋体;">走出软件作坊：三五个人十来条枪</span> <span style="font-family: 宋体;">如何成为开发正规军（三）</span>
<span style="font-family: 宋体;">写完后，发现写的有些偏，偏向了<strong>开发经理</strong>，而没有顾及<strong>项目实施经理</strong>。在项目实施的时候，有些独特的地方，需要有独特的工具来帮助。</span></p>
<p><span style="font-family: 宋体;">　　前天晚上，和一位做了多年实施项目带领的朋友吃饭。</span></p>
<p><span style="font-family: 宋体;">　　我笑着跟他说：<strong>实施，能不能不实施？！</strong>不去人，也不搞实施，把软件卖了就</span>OK<span style="font-family: 宋体;">，你们做好</span>IT<span style="font-family: 宋体;">咨询就可以，把什么数据准备、培训、协调业务部门和信息科需求、推动上线、报表制作都让客户做。咱也不赚他的实施费用。因为你们是个合伙成立的小公司，你们如果也是从开发到定制化到实施到支持，你们根本没有那么多人，项目周期又这么长，销售价格竞争又如此激烈，你们赚不了几个钱。<strong>实施尤其是最耗成本的</strong>，你们好不容易拿到的单，实施完剩不了多少，所以你们这么多年公司也没有大发展，不断在年年求生存。</span></p>
<p><span style="font-family: 宋体;">　　他说：<strong>你纯粹是白日作梦</strong>。我一直在想怎么能缩短点或干活轻快点，你还在做梦不实施。不实施，人家买你的啊。企业那帮人，连数据准备都不想录入，你让他们自己实施？</span></p>
<p><span style="font-family: 宋体;">　　我说，我虽然没有你实施的客户多，但我也做过灯塔标杆客户。再说，我多年统管开发、实施、服务三大部门，没个方法能搞定么？我给你介绍一下我的一些心得。可能不会真的让你不去实施，那样确实可能带来客户连单都不签的危险。咱们一起交流一下怎么能让实施尽可能的短。能短一点也是一点。我这个人就有个习惯，</span><strong><span style="font-size: 14pt; line-height: 150%; font-family: 宋体;">能改进我就不在原地踏步</span></strong><span style="font-family: 宋体;">。这个改进方法不行，我就继续想其他改进方法，不断尝试不断推进，哪怕一点改进我都要去实现它。<strong>量多了就会引起质变</strong>。<strong><span style="color: red;">许多人就等着大机会大改变，对小改进懒的动，我不赞同</span></strong>。</span></p>
<p><span style="font-family: 宋体;">　　我说说我在项目实施和项目管理上的一些好的方法和心得。</span></p>
<p><span style="font-family: 宋体;">　　做实施，最怕的不是人家使用中出现各种麻烦。而是<strong>业务部门抵制用，不想用，出各种各样理由</strong>，项目进展很慢（真不知道过去是怎么签单了）。究其原因就是：你们用软件能做到的，我用</span>EXCEL<span style="font-family: 宋体;">也能做到。我现在就用的挺好，你们的软件还挺难用，还不根据我的需求我的习惯修改。修改了我就用。</span></p>
<p><span style="font-family: 宋体;">　　完了。原来我们辛辛苦苦研发出来的管理软件，跟一个电子表格没啥区别。人家</span>EXCEL<span style="font-family: 宋体;">还可以盗版免费用，网上随便下载。我们这个还花钱，还有时候有</span>BUG<span style="font-family: 宋体;">，还要服务器，还要专职系统维护。</span></p>
<p><span style="font-family: 宋体;">　　实施人员没招了。都是些刚出身社会一两年，<strong><span style="color: red;">学生气和学生思维习惯</span></strong>都还没有摆脱，就让来实施管理软件，并且给人家管理人员讲软件中的<strong>管理理念</strong>。这有点勉为其难。</span></p>
<p><span style="font-family: 宋体;">　　其实有些管理软件不仅仅是减轻工作量，用电脑代替人工这么简单。它还蕴藏着丰富的<strong><span style="color: red;">管理经验</span></strong>。但说到管理经验，就很玄妙了。管理这个东西，是个公说公有理婆说婆有理的东西。很多人经常一说，他们管理落后。啥叫管理落后？你具体说说。说不出来了，指东打西的说的不到点子上。</span></p>
<p><span style="font-family: 宋体;">　　<strong>如果先进的管理理念说不出来，有些软件就跟做手工一样了</strong>。</span></p>
<p><span style="font-family: 宋体;">　　这是很多实施管理软件人的难题。<strong>先进的管理理念说不出来</strong>。因为自己就是个实施人员，又没有管理过企业，又没有多少管理经验，也就管过</span>1-2<span style="font-family: 宋体;">个人，怎么能说服人家天天待在企业处理业务的管理人员呢。无法说服人家，人家就觉得这个管理软件就跟</span>EXCEL<span style="font-family: 宋体;">一样，还不如</span>EXCEL<span style="font-family: 宋体;">好使，人家肯定不用，没法上人家用起来呀。怎么办呢？</span></p>
<p><span style="font-family: 宋体;">　　针对这个现象，我专门从软件附着的管理理念中抽取出<strong>了管理模型</strong></span><strong>KPI</strong><strong><span style="font-family: 宋体;">、管理模型计算公式、管理模型流程。把管理模型</span>KPI</strong><strong><span style="font-family: 宋体;">一亮，都是管理人员很喜欢的和利润费用成本相关的东西。</span></strong><span style="font-family: 宋体;">他们就来劲了。然后就给他们展示这些</span>KPI<span style="font-family: 宋体;">是怎么得到的。<strong>计算公式上场。</strong>计算公式中的值是怎么得到的呢。<strong>管理模型流程上场，</strong>是这么走流程就可以得到。那这么流程怎么能保证让各个部门一致的顺利的走下来呢。好啦。管理软件，水到渠成，客户老板立马拍板，谁拖延了上线就问谁的责任。</span></p>
<p><span style="font-family: 宋体;">　　好的开端有了，就需要做实施的第一步，数据初始化。</span></p>
<p><span style="font-family: 宋体;">　　做实施，在实施的前期，最大的时间消耗就在数据准备。这是一座信息化大楼的基础啊。基础出了问题，就会引起输入的问题，更会引起输出的问题。越发现的晚，以后调整的难度越大。我曾经遇见一个实施人员的案例，就是数据准备这块没做好，上线十来天才发现。最后他发现是他的问题，就自己偷偷改后台数据，没想到还改乱了，系统更是问题百出，客户急了，他也慌了。最后紧急救场。但仍然有一部分数据已经错误很难对齐了，给企业带来了当月财务处理核算很大的问题，我们不仅开除了员工，还给客户赔了钱，真是损失惨重。</span></p>
<p><span style="font-family: 宋体;">　　痛定思痛。</span></p>
<p><span style="font-family: 宋体;">　　<strong>首先做的第一项决定就是严厉测试数据字典准备功能</strong>。每一个基础数据录入窗口界面，都各种边界测试，非法字符测试，乱点乱按测试，删除默认值测试，机器反应速度慢测试，突然断网测试，突然断电测试，严把数据口。有些基础数据是互相关联的，就要严格测试数据关联性，保证前置数据没有准备好，后续数据字典不准进入维护窗口。</span></p>
<p><span style="font-family: 宋体;">　　<strong>第二步就是封锁数据库。把数据库访问权限严格控制。所有视图、存储过程加密。</strong>所有更新删除插入语句留下日志审计，修改前修改后的字段信息日志。每条记录的最后更新时间和更改人留下日志。停用标志的停用时间和停用人的日志。这样增加了数据的安全性。</span></p>
<p><span style="font-family: 宋体;">　　<strong>第三步，错误日志。</strong>一旦发现了没有程序预先想到的处理的错误，<em>就立即终止软件，把软件的错误界面快闪自动保存成</em></span><em>GIF</em><em><span style="font-family: 宋体;">文件，真正内部错误，都保存下来，可以点击按钮通过网络发送到公司报告</span></em><span style="font-family: 宋体;">。</span></p>
<p><span style="font-family: 宋体;">　　我还专门组织编写了数据准备手册。详细的数据准备操作流程，输入输入规范约束默认值不可为空不可重复等等都说明的很清楚。而且还给了一份清单，每通过一步，就打一个勾。如果这个清单上的列表，每项勾都打好了，说明数据准备阶段就完成了。很清晰，很了解自己目前的工作进展。</span></p>
<p><span style="font-family: 宋体;">　　其实，实施，做数据准备是非常耗费时间的。他们过去的数据用了那么多年，有很多重复，废旧，编码或命名不规范的数据。而且没有人愿意做数据准备。因为基础数据往往挺多，录入就是个人工活，还要校对规格和价格，否则以后业务处理就有问题。</span></p>
<p><span style="font-family: 宋体;">　　所以，实施人员一般去了才去整理过去的数据。说整理吧，人家过去的系统还不了解，又不是自己公司开发的。而且居然大多没有文档。数据结构根本不明白。<strong>就是根据数据瞎猜</strong>。</span></p>
<p><span style="font-family: 宋体;">　　到了数据录入阶段吧，人都溜的贼快。反正你在现场，反正你着急回家，反正你的老板正焦急的催你上线节省费用早日上线早日催尾款。于是，<strong>只要自己一个人录入一个人校对，其他人都在偷着乐</strong>。这种实施，真不是人干的活。怎么他们上线用软件，他们自己不忙，实施人员倒是成了长工。唉，谁让人家是出钱的呢。有钱就是娘啊。</span></p>
<p><span style="font-family: 宋体;">　　现在，我力求实施人员能不去现场做数据准备就不去，给他们按照数据准备手册按照流程给他们信息科培训几次，模拟操作几遍，就回到公司，不会在那里继续干耗。他们拖时间是他们自己拖。他们自己不想上线，他们的老板会找他们算帐。而且现在已经做的这么简单安全稳定了，客户的信息科他们都会自己根据安装手册做了。如果他们还懒还说不会，就说不过去了。</span></p>
<p><span style="font-family: 宋体;">　　我的朋友开始限于思考状态中。</span></p>
<p><span style="font-family: 宋体;">　　做实施，在实施中期，<strong>最耗费时间的就是培训</strong>。需要把人聚集起来，需要培训教室，还需要定点，还需要组织人，还需要模拟练习的机器。这就很难办了，业务部门是用户使用者，但他们都在工作中，让他们扔开工作来培训，谁来接替他们的工作，大家都很忙。另外，培训教室也是个事，那么多人需要培训，即使按拨来，也好几拨，哪有那么空闲的地方搞培训教室。人还有时到不齐，还需要重复培训。培训一次，不会，还需要再次培训。累啊。</span></p>
<p><span style="font-family: 宋体;">　　针对这个问题，我们也想了招。这都是被迫了，老板要<strong>讲究成本和时间和人力</strong>。你搞不定，你就下课。</span></p>
<p><span style="font-family: 宋体;">　　<strong>我首先，让培训专员制作了培训课程、培训教材、培训考试卷、模拟练习学习版软件、视频教学软件。在没有实施的时候就发下去光盘，让他们自己看视频看帮助看教材做练习。懒的看懒的学？可以，我还有培训</strong>。</span></p>
<p><span style="font-family: 宋体;">　　到了真正的培训期，网络教室管理软件又派上了用场。他们每个机器都配个随身听那种耳机，随便一个耳机就可以，街上批发有许多，花不了多少钱。我在信息科电脑跟前坐，他们在他们的电脑跟前坐，根本不用培训教室，也不用他们离岗。他们的电脑一律显示的是我的电脑的演示。我边操作边讲。他们边听边看。</span></p>
<p><span style="font-family: 宋体;">　　在讲的过程中，我也启动了我机器上的录像软件。讲完后，谁忘了听或者有事或者没听懂，都可以重复看。</span></p>
<p><span style="font-family: 宋体;">　　<strong>谁想浪费我的培训苦心，随便听听，把培训当玩。我这里还有考试卷，考试打分。然后报给他们领导。而且还从中选出优秀者做业务标兵。这就很尴尬了。谁也不想当科室里的落后者。爱怎样就怎样的科员我还比较少见，因为现在的企业都不养闲人。</strong></span></p>
<p><span style="font-family: 宋体;">　　我的朋友眼睛开始闪光，兴奋中。</span></p>
<p><span style="font-family: 宋体;">　　做实施，后期最大的时间就花在了<strong>上线后的监控运行上</strong>。那个客户端出现了问题，或者功能不会操作了，就需要立即赶去处理。由于上线后第一个星期，你正跑到</span>18<span style="font-family: 宋体;">楼解决问题，</span>4<span style="font-family: 宋体;">楼的用户就给你打电话了，让你去解决。刚解决好</span>4<span style="font-family: 宋体;">楼，</span>15<span style="font-family: 宋体;">楼的用户又给你打电话了。你的手机不断，挥汗如雨的奔忙在楼层之间，电梯人还多，每层都停，让你累的半死一个上午也解决不了几个问题。</span></p>
<p><span style="font-family: 宋体;">　　现在网上很多免费的或收费很少的软件，如网络教室管理软件，如网吧管理软件，如远程监控软件很多。你给每个客户端在装</span>PC<span style="font-family: 宋体;">的时候就都标配装上。这样，你以后就可以在信息科就可以掌控所有的计算机。<strong>那个计算机出了问题，你连接过去就看到了解决了，电话一交流，甚至内部</strong></span><strong>IM</strong><strong><span style="font-family: 宋体;">系统一交流就全搞定了</span></strong><span style="font-family: 宋体;">。</span></p>
<p><span style="font-family: 宋体;">　　我的朋友不断点头称好。</span></p>
<p><span style="font-family: 宋体;">　　在项目的维护期，就涉及到版本更新的问题。尤其是有些行业客户，需要你在实施过程中就修改需求定制化软件，否则不修改完不让上线，非要按照他们的习惯做才肯用，自然更新版本不断。</span></p>
<p><span style="font-family: 宋体;">　　而客户端非常多，更新一次非常累。而且哪个更新了哪个忘了更新，更新的版本一致不一致，都会引起数据异常的问题，以后报表不平，查问题就很困难了。所以，为了更新，网上有很多局域网内文件同步软件，可以设置定时监测更新，如中午吃饭的时候正好自动更新，也可以设置每次启动计算机自动监测更新。你也可以用用。</span></p>
<p><span style="font-family: 宋体;">　　我的朋友脸有点窘说：嗯，确实是个点子。我现在更新仍然需要一台台的安装更新覆盖。更新一次确实挺累。</span></p>
<p><span style="font-family: 宋体;">　　我说：我现在已经改进的更好了了。直接在软件中集成同步功能了。客户端软件一启动的时候，先自动监测服务器上的版本一致不一致？如果不一致，就自动更新同步服务器上的软件文件。但是客户的局域网由于这权限那权限，网络安全设置极为怪异，所以有时服务器数据库能访问，但就是无法访问文件夹。这样的情形我们的同步功能也考虑了，一旦检测无法同步，会自动提示版本不一致，需要手工版本同步。就不允许他继续登陆软件继续使用，否则他机器上的软件还是旧的，</span>BUG<span style="font-family: 宋体;">仍然没有修复，他输入进去的数据还可能是错误的，给后续的技术服务会带来很多的困难。</span></p>
<p><span style="font-family: 宋体;">　　我过去经常遇到这样的情形：网络管理员打来电话说版本更新了仍然软件功能不好使。最后双方争论的很厉害，客户支持部呢说他没更新，网管说更新了。客户支持部说再更新一次，可能更新时候有异常，网管说已经再次更新了。客户支持部说：那我远程支持连接看看。他说无法上网。只好出现场。如果这个客户在海南岛就惨了，成本居贵。去了一看，是有的更新了有的没有更新。更新一次，</span>OK<span style="font-family: 宋体;">，全搞定了。惨，</span>3<span style="font-family: 宋体;">分钟搞定的问题，却花了飞机出差，也花费了大量客服支持人员找问题的时间，客户满意度还不行。</span></p>
<p><span style="font-family: 宋体;">　　自从<strong><span style="color: red;">软件有了同步和版本监测功能</span></strong>，客服支持电话少多了。而且由于一次机缘，客户的服务器必须定时在线数据上传，我们又利用这次机会，做了在线更新探测。我们一旦发现问题更新了软件，就放到了我们的支持服务器上。客户的服务器有驻留软件定时探测，一旦发现有新更新，自动下载更新，可以更新数据库，也可以更新文件。服务器更新完了，客户端就会自动按照服务器的版本变化自动更新了。从此，客户满意度提高了不少。因为有的客户还没有发现那个</span>BUG<span style="font-family: 宋体;">的时候，就已经被我们更新了。客服的工作更轻松了。</span></p>
<p><span style="font-family: 宋体;">　　上线还有一个小窍门，这个也能帮助你缩短时间。这也是我的一个心得。</span></p>
<p><span style="font-family: 宋体;">　　我记得我做灯塔客户的时候，两家客户在不同的两座城市，但是两座城市比较近，</span>2<span style="font-family: 宋体;">个多小时的路程。我实施完了</span>A<span style="font-family: 宋体;">客户，去了</span>B<span style="font-family: 宋体;">客户那里继续实施。但是</span>A<span style="font-family: 宋体;">客户打了电话，说需要有些工作需要支持支持。我就去了。因为我已经实施他这家了，所以他也不好意思继续用我。我来支持他们，也是一是人情二是近。于是我一去了他就问我这次能在他这里待多少时间。我说大概</span>1<span style="font-family: 宋体;">天。于是，他会立即召集他的下属，把平时积累的问题都拿了出来，非常配合也工作节奏非常快工作效率也非常高的完成了。<strong>如果我说大概能待</strong></span><strong>3</strong><strong><span style="font-family: 宋体;">天，估计他的人影在第三天才能出现。这就是人的惰性，时间不催赶着他，他总觉得还有明天</span></strong><span style="font-family: 宋体;">。</span></p>
<p><span style="font-family: 宋体;">　　所以，如果你去上线实施，<strong>如果一开始不明确告诉所有人，你必须</strong></span><strong>1</strong><strong><span style="font-family: 宋体;">月后离开，而且必须实施完毕，那么他们半年都上不了线，即使上了线也是用的松松垮垮。如果限定项目时间，努力奔着这个时间，而且限定好项目此阶段着重解决的三个问题，他们就会工作节奏快的多。注意，不限定项目边界，项目时间目标都是假的，很容易就超过项目时间，再想遵守项目时间就很难了</span></strong><span style="font-family: 宋体;">。</span></p>
<p><span style="font-family: 宋体;">　　我过去还实施过一家客户，没有实施前就是个松松垮垮的企业。小城市，人们中午</span>11<span style="font-family: 宋体;">点下班后还回家买菜做饭，不像北京大城市中午回不去必须吃工作餐。他们还有午休时间。所以，小城市的生活是安逸的。<strong>但是我想快速实施。我早就准备好了很多项目过程管理表格和项目进度汇报流程。一去了，各种表格方法一拿出来，他们一看，来的人非常专业，混是不好混的，于是心情揣揣不安看我会如何。我每天邮件报告给我的老板、他的老板、项目涉及到的每个人，通报今天的工作内容和明天的工作计划。</strong>本来大家都觉得很难啃的一个客户，被我按计划时间完成。大家都一开始笑称我需要在那里买套房安家才能实施完，没想到我这么快。</span></p>
<p><span style="font-family: 宋体;">　　这个案例就说明，你</span><strong><span style="font-size: 14pt; line-height: 150%; font-family: 宋体; color: red;">自己得过且过不正规，别人更就不把你当回事</span></strong><span style="font-family: 宋体;">。你举止文雅谈吐内涵，别人也不好意思在你面前大放厥词。</span></p>
<p><span style="font-family: 宋体;">　　我的朋友很尴尬的说：我服了你了。我实施多年，也没有想出你这么多招。总觉得什么都动不了。这些方法我们现在一个都没有用。如果用了，我相信能缩短现在一半实施周期。缩短了周期，就能减少成本。成本低了，利润就高了。</span></p>
<p><span style="font-family: 宋体;">　　我说：我也是没有办法，老板逼的，老板向我要效益啊。人在压力中，自然就能想出办法。你如果觉得无法突破，那么你真的就无法突破了。<strong>我就是由于不相信这个老规矩就破除不了，所以就大胆思考大胆尝试，最后还真管用。这些方法不仅仅能降低成本。你实施周期短了，你可以实施更多的客户，这是一个开源节流的好方法。企业利润，不外乎多赚钱，少花钱。我全办到了。</strong></span></p>
<img src ="http://www.blogjava.net/sdaunch/aggbug/282761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdaunch/" target="_blank">sea</a> 2009-06-17 09:29 <a href="http://www.blogjava.net/sdaunch/archive/2009/06/17/282761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>