﻿<?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-日出而作兮勤于外，日落而归兮忙于内</title><link>http://www.blogjava.net/cherishchen/</link><description>The art of living is to know when to hold fast and when to let go</description><language>zh-cn</language><lastBuildDate>Sat, 30 Aug 2008 15:03:02 GMT</lastBuildDate><pubDate>Sat, 30 Aug 2008 15:03:02 GMT</pubDate><ttl>60</ttl><item><title>一定要注意字符串处理方法的参数说明，是正则表达式还是普通字符串</title><link>http://www.blogjava.net/cherishchen/archive/2008/08/22/223676.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Fri, 22 Aug 2008 02:40:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/08/22/223676.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/223676.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/08/22/223676.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/223676.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/223676.html</trackback:ping><description><![CDATA[注意使用正则表达式和普通字符串的区别：<br />
昨天发现一个因为误用正则表达式而导致的bug，<br />
错误代码：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;get&#215;&#215;&#215;&#215;()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(mountPoint</span><span style="color: #000000;">!=</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;mountPoint.length()</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;mountPoint.replaceAll(</span><span style="color: #000000;">"</span><span style="color: #000000;">\\?</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\\|</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">""</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
这段代码的本意是为了将<span style="color: #000000;">mountPoint中的所有?替换成为|,但是由于没有仔细看</span><span style="color: #000000;">replaceAll的参数说明，导致了两个参数都是用regular express所必需的\\转义符号。</span><style type="text/css" charset="ISO-8859-1"> Font definitions */
html         { font-family: 'Tahoma',sans-serif; font-size: 11pt; font-style: normal; font-weight: normal; }
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size:1em; }
pre				{ font-family: monospace; }
/* Margins */
body	     { overflow: auto; margin-top: 0px; margin-bottom: 0.5em; margin-left: 0.3em; margin-right: 0px; }
h1           { margin-top: 0.3em; margin-bottom: 0.04em; }
h2           { margin-top: 2em; margin-bottom: 0.25em; }
h3           { margin-top: 1.7em; margin-bottom: 0.25em; }
h4           { margin-top: 2em; margin-bottom: 0.3em; }
h5           { margin-top: 0px; margin-bottom: 0px; }
p            { margin-top: 1em; margin-bottom: 1em; }
pre	         { margin-left: 0.6em; }
ul	         { margin-top: 0px; margin-bottom: 1em; }
li	         { margin-top: 0px; margin-bottom: 0px; }
li p	     { margin-top: 0px; margin-bottom: 0px; }
ol	         { margin-top: 0px; margin-bottom: 1em; }
dl	         { margin-top: 0px; margin-bottom: 1em; }
dt	         { margin-top: 0px; margin-bottom: 0px; font-weight: bold; }
dd	         { margin-top: 0px; margin-bottom: 0px; }
/* Styles and colors */
a:link	     { color: #0000FF; }
a:hover	     { color: #000080; }
a:visited    { text-decoration: underline; }
h4           { font-style: italic; }
strong	     { font-weight: bold; }
em	         { font-style: italic; }
var	         { font-style: italic; }
th	         { font-weight: bold; }
</style>
<h5>replaceAll(String regex, String replacement)</h5>
<br />
因此正确的代码是：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;get&#215;&#215;&#215;&#215;()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(mountPoint</span><span style="color: #000000;">!=</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;mountPoint.length()</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;mountPoint.replaceAll(</span><span style="color: #000000;">"</span><span style="color: #000000;">\\?</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">|</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">""</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br />
同样需要注意的包括indexOf，split<br />
<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/223676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-08-22 10:40 <a href="http://www.blogjava.net/cherishchen/archive/2008/08/22/223676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>multipathing  and cluster</title><link>http://www.blogjava.net/cherishchen/archive/2008/07/09/213520.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 09 Jul 2008 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/07/09/213520.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/213520.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/07/09/213520.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/213520.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/213520.html</trackback:ping><description><![CDATA[<table class="QandAEntry" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr style="padding-top: 3px;" id="answer12" valign="top">
            <td valign="top"><br />
            </td>
            <td class="dropCapA" align="left" nowrap="true">A.</td>
            <td class="ABlock">
            <p>Although
            both multipathing and clustering result in high availability and
            improved performance, they are not equivalent concepts. While
            clustering provides high application availability and can be
            implemented using a multipathing solution, multipathing provides high
            storage availability and does not require a clustering solution. <span style="background-color: #ffff00; color: #000000;" class="linemarker-marked-line">Clustering
            is the use of multiple computers, interconnects, and storage devices
            that work together to provide users with high application availability
            from what looks like a single system. Multipathing, as stated in the
            previous question, is the redundancy of the storage network components
            (the cabling, adapters, and switches) to provide users with high
            storage availability.</span></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/cherishchen/aggbug/213520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-07-09 09:56 <a href="http://www.blogjava.net/cherishchen/archive/2008/07/09/213520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JTable 列自动调整（转）</title><link>http://www.blogjava.net/cherishchen/archive/2008/06/19/209209.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Thu, 19 Jun 2008 09:18:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/06/19/209209.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/209209.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/06/19/209209.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/209209.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/209209.html</trackback:ping><description><![CDATA[http://book.77169.org/ask9/ask158152.htm<br />
<br />
<br />
public class TableUtil {<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; &nbsp;* use column's value to get the column width<br />
&nbsp;&nbsp;&nbsp; &nbsp;* <br />
&nbsp;&nbsp;&nbsp; &nbsp;* @param table<br />
&nbsp;&nbsp;&nbsp; &nbsp;* @param icol<br />
&nbsp;&nbsp;&nbsp; &nbsp;* @return<br />
&nbsp;&nbsp;&nbsp; &nbsp;*/<br />
<br />
&nbsp;&nbsp;&nbsp; public static int getPreferredWidthForCloumn(JTable table, int icol) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TableColumnModel tcl = table.getColumnModel();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TableColumn col = tcl.getColumn(icol);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int c = col.getModelIndex(), width = 0, maxw = 0;<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (int r = 0; r &lt; table.getRowCount(); ++r) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; TableCellRenderer renderer = table.getCellRenderer(r, c);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Component comp = renderer.getTableCellRendererComponent(table,<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; table.getValueAt(r, c), false, false, r, c);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; width = comp.getPreferredSize().width;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; maxw = width &gt; maxw ? width : maxw;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return maxw;<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
<br />
<br />
<br />
private void setTableWidthAuto(JTable table) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; table.getColumnCount(); i++) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int with = TableUtil.getPreferredWidthForCloumn(table, i) + 5;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; table.getColumnModel().getColumn(i).setPreferredWidth(with);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/209209.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-06-19 17:18 <a href="http://www.blogjava.net/cherishchen/archive/2008/06/19/209209.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iscsi 相关资料</title><link>http://www.blogjava.net/cherishchen/archive/2008/06/17/208729.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Tue, 17 Jun 2008 15:02:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/06/17/208729.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/208729.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/06/17/208729.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/208729.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/208729.html</trackback:ping><description><![CDATA[<br />
申请iscsi 空间&nbsp; http://www.bookindex.cn/index.html<br />
<br />
<br />
ubuntu下iscsi initiator的安装和配置，使用<br />
<br />
http://hi.baidu.com/lianxi1999/blog/item/636e2106db8aec7f020881ef.html<br />
<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/208729.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-06-17 23:02 <a href="http://www.blogjava.net/cherishchen/archive/2008/06/17/208729.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>任正非优秀党员座谈会发言：不要试图做完人</title><link>http://www.blogjava.net/cherishchen/archive/2008/06/16/208216.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 16 Jun 2008 01:18:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/06/16/208216.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/208216.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/06/16/208216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/208216.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/208216.html</trackback:ping><description><![CDATA[http://tech.sina.com.cn/t/2008-06-13/15252257028.shtml<br />
<br />
<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/208216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-06-16 09:18 <a href="http://www.blogjava.net/cherishchen/archive/2008/06/16/208216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>lvm  理解的一个图</title><link>http://www.blogjava.net/cherishchen/archive/2008/06/03/205508.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Tue, 03 Jun 2008 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/06/03/205508.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/205508.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/06/03/205508.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/205508.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/205508.html</trackback:ping><description><![CDATA[http://linux.bloghome.cn/gallery/0/123/481/original/99e5a0d6d311768f45caf6cfecdc05ca.png<br />
<br />
<img alt="" src="http://linux.bloghome.cn/gallery/0/123/481/original/99e5a0d6d311768f45caf6cfecdc05ca.png" height="502" width="451" /><br />
<p style="margin-bottom: 0cm;">物理卷（<span style="font-family: Bitstream Vera Serif,serif;">physical volume</span>，<span style="font-family: Bitstream Vera Serif,serif;">PV</span>）</p>
<p style="margin-bottom: 0cm; text-indent: 0.74cm;">物理卷就是指硬盘分区，也可以是整个硬盘或已创建的软<span style="font-family: Bitstream Vera Serif,serif;">RAID </span>，是<span style="font-family: Bitstream Vera Serif,serif;">LVM</span>的基本存储设备，与普通物理存储介质的区别是该设备包含有<span style="font-family: Bitstream Vera Serif,serif;">LVM</span>相关的管理参数。 </p>
<p style="margin-bottom: 0cm;"><br />
</p>
<p style="margin-bottom: 0cm;">卷组（<span style="font-family: Bitstream Vera Serif,serif;">volume group</span>，<span style="font-family: Bitstream Vera Serif,serif;">VG</span>）</p>
<p style="margin-bottom: 0cm; text-indent: 0.74cm;">卷组是由一个或多个物理卷所组成的存储池，在卷组上能创建一个或多个&#8220;<span style="font-family: Bitstream Vera Serif,serif;">LVM</span>分区&#8221;（逻辑卷）。 </p>
<p style="margin-bottom: 0cm;"><br />
</p>
<p style="margin-bottom: 0cm;">逻辑卷（<span style="font-family: Bitstream Vera Serif,serif;">logical volume</span>，<span style="font-family: Bitstream Vera Serif,serif;">LV</span>）</p>
<p style="margin-bottom: 0cm; text-indent: 0.74cm;"><span style="font-family: Bitstream Vera Serif,serif;">LVM</span>的逻辑卷类似于非<span style="font-family: Bitstream Vera Serif,serif;">LVM</span>系统中的硬盘分区，<span style="color: #000000;">它建立在卷组之上，是一个标准的块设备，</span>在逻辑卷之上可以建立文件系统。可以做这样一个设想来理解以上三者的关系：如果把<span style="font-family: Bitstream Vera Serif,serif;">PV</span>比做地球的一个板块，<span style="font-family: Bitstream Vera Serif,serif;">VG</span>则是一个地球，因为地球是由多个板块组成的，那么在地球上划分一个区域并标记为亚洲，则亚洲就相当于一<span style="color: #000000;">个<span style="font-family: Bitstream Vera Serif,serif;">LV</span></span>。</p>
<p style="margin-bottom: 0cm;"><br />
</p>
<p style="margin-bottom: 0cm;">物理块（<span style="font-family: Bitstream Vera Serif,serif;">physical extent</span>，<span style="font-family: Bitstream Vera Serif,serif;">PE</span>）</p>
<p style="margin-bottom: 0cm; text-indent: 0.74cm;"><span style="color: #000000;">物理卷以大小相等的物理块为存储的基本单位，同时也是<span style="font-family: Bitstream Vera Serif,serif;"><span style="font-family: 宋体,SimSun;">LVM</span></span></span><span style="color: #000000;">寻址的最小单元。</span></p>
<p style="margin-bottom: 0cm;"><br />
</p>
<p style="margin-bottom: 0cm;">逻辑块（<span style="font-family: Bitstream Vera Serif,serif;">logical extent</span>，<span style="font-family: Bitstream Vera Serif,serif;">LE</span>）</p>
<p style="margin-bottom: 0cm; text-indent: 0.74cm;">逻辑卷以大小相等的逻辑块为存储的基本单位，在同一个卷组中，<span style="font-family: Bitstream Vera Serif,serif;">LE</span>的大小和<span style="font-family: Bitstream Vera Serif,serif;">PE</span>是相等的，并且一一对应。</p>
<p style="margin-bottom: 0cm;"><br />
</p>
<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/205508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-06-03 11:27 <a href="http://www.blogjava.net/cherishchen/archive/2008/06/03/205508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>scsi,fc,iscsi（转)</title><link>http://www.blogjava.net/cherishchen/archive/2008/05/30/204083.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Fri, 30 May 2008 06:40:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/05/30/204083.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/204083.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/05/30/204083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/204083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/204083.html</trackback:ping><description><![CDATA[http://space.doit.com.cn/17236/viewspace-2729.html<br />
<br />
其历史顺序应该SCSI-&gt;FC(用于SCSI)-&gt;ISCSI；<br />
最初是从SCSI开始的，它也是存储领域最为广泛的协议；SCSI的命令和数据，可以直接在SCSI接口中传输，也可以通过封装进行传输，比如用USB，1394，FC，以及iSCSI等方式。 <br />
由于在传统的SCSI接口中，其传输的距离有限；因此用FC来扩大传输距离就应运而生，从而封装SCSI的FC接口流行起来，物理上它只是加上的FC的电路，其核心的SCSI部分基本不做修改，因此软件上移植SCSI HBA到FC的HBA实现难度并不大。&nbsp;&nbsp;<br />
同样，由于FC的成本和传输距离问题，iSCSI横空出世，它用TCP/IP协议来封装和传输，物理上加上TOE电路(或者用软件来实现这部分)，同样其
核心仍然是SCSI的处理，方式和FC查不错。至于iSCSI的流行，这和软硬件厂商的推广(需要在存储的各个应用环境中都加入iSCSI的支持)，以及
市场的接受程度相关。<br />
从物理上来讲，对于FC和iSCSI需要特殊的IC来完成处理；而软件上，改变会比较小，在windows下面，PCI
RAID卡、FC卡、iSCSI卡的驱动，都是采用Port/MiniPort驱动架构，其中Port
driver(是硬件无关的)由微软提供(在2003以前叫SCSIPORT,现在叫StorPort，在windows的系统目录下可以看见这该驱
动)，而Miniport包含了上面所说的三种卡，其架构都一样，只是要针对各种卡做对应的处理而已。对于其他的操作系统，这3种卡的软件处理方面也是类
似的。因为最主要的差别都在物理传输上，所以基本在硬件上完成；而软件上，都是以处理SCSI命令和数据为核心，然后围绕传输接口做相关的处理。<br />
个人对iSCSI，比较看好！
<img src ="http://www.blogjava.net/cherishchen/aggbug/204083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-05-30 14:40 <a href="http://www.blogjava.net/cherishchen/archive/2008/05/30/204083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>换工作中。。。。。</title><link>http://www.blogjava.net/cherishchen/archive/2008/05/05/198326.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 05 May 2008 02:10:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/05/05/198326.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/198326.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/05/05/198326.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/198326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/198326.html</trackback:ping><description><![CDATA[目前的单位还是很人性化的，可惜所处传统行业，不想老死在这里，咬牙辞职。。。<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/198326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-05-05 10:10 <a href="http://www.blogjava.net/cherishchen/archive/2008/05/05/198326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate分页查询原理解读(转）</title><link>http://www.blogjava.net/cherishchen/archive/2008/04/02/190391.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 02 Apr 2008 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/04/02/190391.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/190391.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/04/02/190391.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/190391.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/190391.html</trackback:ping><description><![CDATA[<p><a title="http://www.it.com.cn/f/edu/053/27/93817.htm" href="http://www.it.com.cn/f/edu/053/27/93817.htm">http://www.it.com.cn/f/edu/053/27/93817.htm</a> <p>2005-3-27 20:39:00　文/robbin　<a href="http://%e5%87%ba%e5%a4%84%ef%bc%9ahibernate.org/">出处：hibernate.org</a> <p><img height="1" src="http://www.it.com.cn/0.gif"> <p><img height="5" src="http://www.it.com.cn/images/0.gif" width="5"> <p>　　Hibernate 可以实现分页查询，例如： <br>　　从第2万条开始取出100条记录 <br>　　Query q = session.createQuery("from Cat as c"); <br>　　q.setFirstResult(20000); <br>　　q.setMaxResults(100); <br>　　List l = q.list(); <br>　　那么Hibernate底层如何实现分页的呢？实际上Hibernate的查询定义在net.sf.hibernate.loader.Loader这个类里面，仔细阅读该类代码，就可以把问题彻底搞清楚。 <br>　　Hibernate2.0.3的Loader源代码第480行以下： <br>　　if (useLimit) sql = dialect.getLimitString(sql); <br>　　PreparedStatement st = session.getBatcher().prepareQueryStatement(sql, scrollable); <br>　　如果相应的数据库定义了限定查询记录的sql语句，那么直接使用特定数据库的sql语句。 <br>　　然后来看net.sf.hibernate.dialect.MySQLDialect: <br>　　public boolean supportsLimit() { <br>　　return true; <br>　　} <br>　　public String getLimitString(String sql) { <br>　　StringBuffer pagingSelect = new StringBuffer(100); <br>　　pagingSelect.append(sql); <br>　　pagingSelect.append(" limit ?, ?"); <br>　　return pagingSelect.toString(); <br>　　} <br>　　这是MySQL的专用分页语句，再来看net.sf.hibernate.dialect.Oracle9Dialect: <br>　　public boolean supportsLimit() { <br>　　return true; <br>　　} <br>　　public String getLimitString(String sql) { <br>　　StringBuffer pagingSelect = new StringBuffer(100); <br>　　pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); <br>　　pagingSelect.append(sql); <br>　　pagingSelect.append(" ) row_ where rownum &lt;= ?) where rownum_ &gt; ?"); <br>　　return pagingSelect.toString(); <br>　　} <br>　　Oracle采用嵌套3层的查询语句结合rownum来实现分页，这在Oracle上是最快的方式，如果只是一层或者两层的查询语句的rownum不能支持order by。 <br>　　除此之外，Interbase，PostgreSQL，HSQL也支持分页的sql语句，在相应的Dialect里面，大家自行参考。 <br>　　如果数据库不支持分页的SQL语句，那么根据在配置文件里面 <br>　　#hibernate.jdbc.use_scrollable_resultset true <br>　　默认是true，如果你不指定为false，那么Hibernate会使用JDBC2.0的scrollable result来实现分页，看Loader第430行以下： <br>　　if ( session.getFactory().useScrollableResultSets() ) { <br>　　// we can go straight to the first required row <br>　　rs.absolute(firstRow); <br>　　} <br>　　else { <br>　　// we need to step through the rows one row at a time (slow) <br>　　for ( int m=0; m<br>　　} <br>　　如果支持scrollable result，使用ResultSet的absolute方法直接移到查询起点，如果不支持的话，使用循环语句，rs.next一点点的移过去。 <br>　　可见使用Hibernate，在进行查询分页的操作上，是具有非常大的灵活性，Hibernate会首先尝试用特定数据库的分页sql，如果没用，再尝试Scrollable，如果不行，最后采用rset.next()移动的办法。 <br>　　在查询分页代码中使用Hibernate的一大好处是，既兼顾了查询分页的性能，同时又保证了代码在不同的数据库之间的可移植性。&lt;/FIRSTROW;&gt;</p><img src ="http://www.blogjava.net/cherishchen/aggbug/190391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-04-02 16:04 <a href="http://www.blogjava.net/cherishchen/archive/2008/04/02/190391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二层交换机，三层交换机，四层交换机的区别</title><link>http://www.blogjava.net/cherishchen/archive/2008/04/02/190390.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 02 Apr 2008 08:02:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/04/02/190390.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/190390.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/04/02/190390.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/190390.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/190390.html</trackback:ping><description><![CDATA[<p><a href="http://www.pconline.com.cn/pcjob/nettech/cisco/others/0406/390946.html">http://www.pconline.com.cn/pcjob/nettech/cisco/others/0406/390946.html</a>  <p>　　二层交换技术是发展比较成熟，二层交换机属数据链路层设备，可以识别数据包中的MAC地址信息，根据MAC地址进行转发，并将这些MAC地址与对应的端口记录在自己内部的一个地址表中。具体的工作流程如下：<br>（1） 当交换机从某个端口收到一个数据包，它先读取包头中的源MAC地址，这样它就知道源MAC地址的机器是连在哪个端口上的；<br>（2） 再去读取包头中的目的MAC地址，并在地址表中查找相应的端口；<br>（3） 如表中有与这目的MAC地址对应的端口，把数据包直接复制到这端口上；<br>（4） 如表中找不到相应的端口则把数据包广播到所有端口上，当目的机器对源机器回应时，交换机又可以学习一目的MAC地址与哪个端口对应，在下次传送数据时就不再需要对所有端口进行广播了。  <p>　　不断的循环这个过程，对于全网的MAC地址信息都可以学习到，二层交换机就是这样建立和维护它自己的地址表。<br>　　从二层交换机的工作原理可以推知以下三点：<br>（1） 由于交换机对多数端口的数据进行同时交换，这就要求具有很宽的交换总线带宽，如果二层交换机有N个端口，每个端口的带宽是M，交换机总线带宽超过N×M，那么这交换机就可以实现线速交换；<br>（2） 学习端口连接的机器的MAC地址，写入地址表，地址表的大小（一般两种表示方式：一为BEFFER RAM，一为MAC表项数值），地址表大小影响交换机的接入容量；<br>（3） 还有一个就是二层交换机一般都含有专门用于处理数据包转发的ASIC （Application specific Integrated Circuit）芯片，因此转发速度可以做到非常快。由于各个厂家采用ASIC不同，直接影响产品性能。<br>　　以上三点也是评判二三层交换机性能优劣的主要技术参数，这一点请大家在考虑设备选型时注意比较。 </p> <p>注：二层交换仍然存在数据广播  <p>（二）路由技术<br>　　路由器工作在OSI模型的第三层---网络层操作，其工作模式与二层交换相似，但路由器工作在第三层，这个区别决定了路由和交换在传递包时使用不同的控制信息，实现功能的方式就不同。工作原理是在路由器的内部也有一个表，这个表所标示的是如果要去某一个地方，下一步应该向那里走，如果能从路由表中找到数据包下一步往那里走，把链路层信息加上转发出去；如果不能知道下一步走向那里，则将此包丢弃，然后返回一个信息交给源地址。<br>　　路由技术实质上来说不过两种功能：决定最优路由和转发数据包。路由表中写入各种信息，由路由算法计算出到达目的地址的最佳路径，然后由相对简单直接的转发机制发送数据包。接受数据的下一台路由器依照相同的工作方式继续转发，依次类推，直到数据包到达目的路由器。<br>　　而路由表的维护，也有两种不同的方式。一种是路由信息的更新，将部分或者全部的路由信息公布出去，路由器通过互相学习路由信息，就掌握了全网的拓扑结构，这一类的路由协议称为距离矢量路由协议；另一种是路由器将自己的链路状态信息进行广播，通过互相学习掌握全网的路由信息，进而计算出最佳的转发路径，这类路由协议称为链路状态路由协议。<br>　　由于路由器需要做大量的路径计算工作，一般处理器的工作能力直接决定其性能的优劣。当然这一判断还是对中低端路由器而言，因为高端路由器往往采用分布式处理系统体系设计。<br>（三）三层交换技术  <p>　　近年来的对三层技术的宣传，耳朵都能起茧子，到处都在喊三层技术，有人说这是个非常新的技术，也有人说，三层交换嘛，不就是路由器和二层交换机的堆叠，也没有什么新的玩意，事实果真如此吗？下面先来通过一个简单的网络来看看三层交换机的工作过程。<br>　　组网比较简单<br>　　使用IP的设备A------------------------三层交换机------------------------使用IP的设备B<br>　　比如A要给B发送数据，已知目的IP，那么A就用子网掩码取得网络地址，判断目的IP是否与自己在同一网段。<br>　　如果在同一网段，但不知道转发数据所需的MAC地址，A就发送一个ARP请求，B返回其MAC地址，A用此MAC封装数据包并发送给交换机，交换机起用二层交换模块，查找MAC地址表，将数据包转发到相应的端口。<br>　　如果目的IP地址显示不是同一网段的，那么A要实现和B的通讯，在流缓存条目中没有对应MAC地址条目，就将第一个正常数据包发送向一个缺省网关，这个缺省网关一般在操作系统中已经设好，对应第三层路由模块，所以可见对于不是同一子网的数据，最先在MAC表中放的是缺省网关的MAC地址；然后就由三层模块接收到此数据包，查询路由表以确定到达B的路由，将构造一个新的帧头，其中以缺省网关的MAC地址为源MAC地址，以主机B的MAC地址为目的MAC地址。通过一定的识别触发机制，确立主机A与B的MAC地址及转发端口的对应关<br>系，并记录进流缓存条目表，以后的A到B的数据，就直接交由二层交换模块完成。这就通常所说的一次路由多次转发。<br>　　以上就是三层交换机工作过程的简单概括，可以看出三层交换的特点：  <p>由硬件结合实现数据的高速转发。<br>　　这就不是简单的二层交换机和路由器的叠加，三层路由模块直接叠加在二层交换的高速背板总线上，突破了传统路由器的接口速率限制，速率可达几十Gbit/s。算上背板带宽，这些是三层交换机性能的两个重要参数。<br>　　简洁的路由软件使路由过程简化。<br>　　大部分的数据转发，除了必要的路由选择交由路由软件处理，都是又二层模块高速转发，路由软件大多都是经过处理的高效优化软件，并不是简单照搬路由器中的软件。<br>结论  <p>　　二层交换机用于小型的局域网络。这个就不用多言了，在小型局域网中，广播包影响不大，二层交换机的快速交换功能、多个接入端口和低谦价格为小型网络用户提供了很完善的解决方案。<br>　　路由器的优点在于接口类型丰富，支持的三层功能强大，路由能力强大，适合用于大型的网络间的路由，它的优势在于选择最佳路由，负荷分担，链路备份及和其他网络进行路由信息的交换等等路由器所具有功能。<br>　　三层交换机的最重要的功能是加快大型局域网络内部的数据的快速转发，加入路由功能也是为这个目的服务的。如果把大型网络按照部门，地域等等因素划分成一个个小局域网，这将导致大量的网际互访，单纯的使用二层交换机不能实现网际互访；如单纯的使用路由器，由于接口数量有限和路由转发速度慢，将限制网络的速度和网络规模，采用具有路由功能的快速转发的三层交换机就成为首选。<br>　　一般来说，在内网数据流量大，要求快速转发响应的网络中，如全部由三层交换机来做这个工作，会造成三层交换机负担过重，响应速度受影响，将网间的路由交由路由器去完成，充分发挥不同设备的优点，不失为一种好的组网策略，当然，前提是客户的腰包很鼓，不然就退而求其次，让三层交换机也兼为网际互连。<br>　　第四层交换的一个简单定义是：它是一种功能，它决定传输不仅仅依据MAC地址(第二层网桥)或源/目标IP地址(第三层路由),而且依据TCP/UDP(第四层) 应用端口号。第四层交换功能就象是虚IP，指向物理服务器。它传输的业务服从的协议多种多样，有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上，需要复杂的载量平衡算法。在IP世界，业务类型由终端TCP或UDP端口地址来决定，在第四层交换中的应用区间则由源端和终端 IP地址、TCP和UDP端口共同决定。 <br>　　在第四层交换中为每个供搜寻使用的服务器组设立虚IP地址（VIP），每组服务器支持某种应用。在域名服务器（DNS）中存储的每个应用服务器地址是VIP，而不是真实的服务器地址。 <br>　　当某用户申请应用时，一个带有目标服务器组的VIP连接请求（例如一个TCP SYN包）发给服务器交换机。服务器交换机在组中选取最好的服务器，将终端地址中的VIP用实际服务器的IP取代，并将连接请求传给服务器。这样，同一区间所有的包由服务器交换机进行映射，在用户和同一服务器间进行传输。 <br>第四层交换的原理<br>　　OSI模型的第四层是传输层。传输层负责端对端通信，即在网络源和目标系统之间协调通信。在IP协议栈中这是TCP（一种传输协议）和UDP（用户数据包协议）所在的协议层。<br>　　在第四层中，TCP和UDP标题包含端口号（portnumber），它们可以唯一区分每个数据包包含哪些应用协议（例如HTTP、FTP等）。端点系统利用这种信息来区分包中的数据，尤其是端口号使一个接收端计算机系统能够确定它所收到的IP包类型，并把它交给合适的高层软件。端口号和设备IP地址的组合通常称作“插口（socket）”。 1和255之间的端口号被保留，他们称为“熟知”端口，也就是说，在所有主机TCP/IP协议栈实现中，这些端口号是相同的。除了“熟知”端口外，标准 UNIX服务分配在256到1024端口范围，定制的应用一般在1024以上分配端口号. 分配端口号的最近清单可以在RFc1700”Assigned Numbers”上找到。TCP／UDP端口号提供的附加信息可以为网络交换机所利用，这是第4层交换的基础。 <br>　　TCP/UDP端口号提供的附加信息可以为网络交换机所利用，这是第四层交换的基础。  <p>具有第四层功能的交换机能够起到与服务器相连接的“虚拟IP”(VIP)前端的作用。 <br>　　每台服务器和支持单一或通用应用的服务器组都配置一个VIP地址。这个VIP地址被发送出去并在域名系统上注册。 <br>　　在发出一个服务请求时，第四层交换机通过判定TCP开始，来识别一次会话的开始。然后它利用复杂的算法来确定处理这个请求的最佳服务器。一旦做出这种决定，交换机就将会话与一个具体的IP地址联系在一起，并用该服务器真正的IP地址来代替服务器上的VIP地址。 <br>　　每台第四层交换机都保存一个与被选择的服务器相配的源IP地址以及源TCP 端口相关联的连接表。然后第四层交换机向这台服务器转发连接请求。所有后续包在客户机与服务器之间重新影射和转发，直到交换机发现<br>会话为止。 <br>　　在使用第四层交换的情况下，接入可以与真正的服务器连接在一起来满足用户制定的规则，诸如使每台服务器上有相等数量的接入或根据不同服务器的容量来分配传输流。 <br>　　如何选用合适的第四层交换 <br>　　a,速度 <br>　　为了在企业网中行之有效，第四层交换必须提供与第三层线速路由器可比拟的性能。也就是说，第四层交换必须在所有端口以全介质速度操作，即使在多个千兆以太网连接上亦如此。千兆以太网速度等于以每秒488000 个数据包的最大速度路由(假定最坏的情形,即所有包为以及网定义的最小尺寸,长64字节)。 <br>　　b,服务器容量平衡算法 <br>　　依据所希望的容量平衡间隔尺寸，第四层交换机将应用分配给服务器的算法有很多种，有简单的检测环路最近的连接、检测环路时延或检测服务器本身的闭环反馈。在所有的预测中，闭环反馈提供反映服务器现有业务量的最精确的检测。 <br>　　c,表容量 <br>　　应注意的是，进行第四层交换的交换机需要有区分和存贮大量发送表项的能力。交换机在一个企业网的核心时尤其如此。许多第二/ 三层交换机倾向发送表的大小与网络设备的数量成正比。对第四层交换机，这个数量必须乘以网络中使用的不同应用协议和会话的数量。因而发送表的大小随端点设备和应用类型数量的增长而迅速增长。第四层交换机设计者在设计其产品时需要考虑表的这种增长。大的表容量对制造支持线速发送第四层流量的高性能交换机至关重要. <br>　　d,冗余 <br>　　第四层交换机内部有支持冗余拓扑结构的功能。在具有双链路的网卡容错连接时，就可能建立从一个服务器到网卡，链路和服务器交换器的完全冗余系统。  <img src ="http://www.blogjava.net/cherishchen/aggbug/190390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-04-02 16:02 <a href="http://www.blogjava.net/cherishchen/archive/2008/04/02/190390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Java String的intern and ==的笔试题，没有全答对</title><link>http://www.blogjava.net/cherishchen/archive/2008/03/17/186782.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 17 Mar 2008 07:43:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/03/17/186782.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/186782.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/03/17/186782.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/186782.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/186782.html</trackback:ping><description><![CDATA[<blockquote>
<pre>package testPackage;<br />
class Test {<br />
public static void main(String[] args) {<br />
String hello = "Hello", lo = "lo";<br />
System.out.print((hello == "Hello") + " ");<br />
System.out.print((Other.hello == hello) + " ");<br />
System.out.print((other.Other.hello == hello) + " ");<br />
System.out.print((hello == ("Hel"+"lo")) + " ");<br />
System.out.print((hello == ("Hel"+lo)) + " ");<br />
System.out.println(hello == ("Hel"+lo).intern());<br />
}<br />
}<br />
class Other { static String hello = "Hello"; }<br />
</pre>
</blockquote>
<p><a name="229778"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and the compilation unit: </p>
<blockquote>
<pre>package other;<br />
public class Other { static String hello = "Hello"; }</pre>
</blockquote>
<pre> 正确答案：true true true true false true</pre>
<pre>&nbsp;</pre>
<p>This example illustrates six points:
</p>
<ul><a name="241676"></a>
    <li>Literal strings within the same class <a href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#3857">(&#167;8)</a> in the same package <a href="http://java.sun.com/docs/books/jls/second_edition/html/packages.doc.html#34412">(&#167;7)</a> represent references to the same <code>String</code> object <a href="http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#12028">(&#167;4.3.1)</a>. <a name="229807"></a>
    </li>
    <li>Literal strings within different classes in the same package represent references to the same <code>String</code> object. <a name="229797"></a>
    </li>
    <li>Literal strings within different classes in different packages likewise represent references to the same <code>String</code> object. <a name="23858"></a>
    </li>
    <li>Strings computed by constant expressions <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5313">(&#167;15.28)</a> are <strong>computed a</strong>t compile time and then treated as if they were literals. <a name="23859"></a>
    </li>
    <li><strong>Strings computed at run time are newly created and therefore distinct</strong>. <a name="23865"></a>
    </li>
    <li>The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents. </li>
</ul>
<p>&nbsp;</p>
<p>呵呵，我是没有能够全部答对</p>
<p>&nbsp;</p>
<p>另外一篇关于String intern的文章：</p>
<p><a title="http://laiseeme.javaeye.com/blog/102442" href="http://laiseeme.javaeye.com/blog/102442">http://laiseeme.javaeye.com/blog/102442</a></p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/186782.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-03-17 15:43 <a href="http://www.blogjava.net/cherishchen/archive/2008/03/17/186782.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入剖析Java编程中的中文问题及建议最优解决方法</title><link>http://www.blogjava.net/cherishchen/archive/2008/02/25/181887.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 25 Feb 2008 01:38:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/02/25/181887.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/181887.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/02/25/181887.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/181887.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/181887.html</trackback:ping><description><![CDATA[http://blog.csdn.net/AbnerChai/archive/2004/04/28/18576.aspx<br />
http://blog.csdn.net/AbnerChai/archive/2004/04/26/18577.aspx<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/181887.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-02-25 09:38 <a href="http://www.blogjava.net/cherishchen/archive/2008/02/25/181887.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关注mvnforum</title><link>http://www.blogjava.net/cherishchen/archive/2008/02/25/181883.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 25 Feb 2008 01:21:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/02/25/181883.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/181883.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/02/25/181883.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/181883.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/181883.html</trackback:ping><description><![CDATA[随时补充资料<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/181883.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-02-25 09:21 <a href="http://www.blogjava.net/cherishchen/archive/2008/02/25/181883.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计及设计模式：关于Java权限控制算法(转）</title><link>http://www.blogjava.net/cherishchen/archive/2008/02/25/181882.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 25 Feb 2008 01:20:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/02/25/181882.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/181882.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/02/25/181882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/181882.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/181882.html</trackback:ping><description><![CDATA[<p>http://publish.itpub.net/j/2008-01-24/200801240919412.shtml</p>
<p>
作者：<strong class="red">来自ITPUB论坛</strong>&nbsp;&nbsp;2008-01-24</p>
<p><br />
</p>
<p>向大家介绍一种很不错，也是Linux中的权限管理算法。
</p>
<p>　　定义a^b为：a的b次方</p>
<p>　　假如，我们为每一个操作设定一个唯一的整数值，比如：</p>
<p>　　删除A---0</p>
<p>　　修改A---1</p>
<p>　　添加A---2</p>
<p>　　删除B---3</p>
<p>　　修改B---4</p>
<p>　　添加B---5</p>
<p>　　。。。</p>
<p>　　理论上可以有N个操作，这取决于你用于储存用户权限值的数据类型了。</p>
<p>　　这样，如果用户有权限：添加A---2;删除B---3;修改B---4</p>
<p>　　那用户的权限值 purview =2^2+2^3+2^4=28，也就是2的权的和了</p>
<p>　　化成二进制可以表示为11100</p>
<p>　　如果要验证用户是否有删除B的权限，就可以通过位与运算来实现。</p>
<p>　　在Java里，位与运算运算符号为&amp;</p>
<p>　　即是：int value = purview &amp;((int)Math.pow(2,3));</p>
<p>　　你会发现，当用户有操作权限时，运算出来的结果都会等于这个操作需要的权限值!</p>
<p>　　原理：</p>
<p>　　位与运算，顾名思义就是对位进行与运算：</p>
<p>　　以上面的式子为例：purview &amp; 2^3 也就是　28&amp;8</p>
<p>　　将它们化成二进制有</p>
<p>　　11100</p>
<p>　　&amp; 01000</p>
<p>　　-------------------</p>
<p>　　01000 == 8(十进制)　==　2^3</p>
<p>　　同理，如果要验证是否有删除A---0的权限</p>
<p>　　可以用：purview &amp;((int)Math.pow(2,0));</p>
<p>　　即：</p>
<p>　　11100</p>
<p>　　&amp; 00001</p>
<p>　　------------------------</p>
<p>　　00000 == 0(十进制)　　!=　2^0</p>
<p>　　这种算法的一个优点是速度快。可以同时处理N个权限，设置N种角色.</p>
<p>　　如果想验证是否同时有删除A---0和删除B---3的权限</p>
<p>　　可以用purview&amp;(2^0+2^3)==(2^0+2^3)?true:false;</p>
<p>　　设置多角色用户。根据权限值判断用户的角色。。。</p>
<p>　　下面提供一个java的单操作权限判断的代码：</p>
<div style="overflow: auto; width: 500px;">
<pre style="border: 1px solid black; padding: 4px; background-color: #ededed;">
<div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><span style="color: #000000;">　　</span><span style="color: #008000;">//</span><span style="color: #008000;">userPurview是用户具有的总权限<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">optPurview是一个操作要求的权限为一个整数(没有经过权的!)</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">static</span><span style="color: #000000;"> boolean checkPower(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> userPurview, </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> optPurview){<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> purviewValue </span><span style="color: #000000;">=</span><span style="color: #000000;"> (</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)Math.pow(</span><span style="color: #000000;">2</span><span style="color: #000000;">, optPurview);<br />
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> (userPurview </span><span style="color: #000000;">&amp;</span><span style="color: #000000;"> purviewValue) </span><span style="color: #000000;">==</span><span style="color: #000000;"> purviewValue;<br />
}</span></div>
<br />
</pre>
</div>
<p>　　当然，多权限的验证只要扩展一下就可以了。</p>
<p>　　几点注意事项：首先，一个系统可能有很多的操作，因此，请建立数据字典，以便查阅，修改时使用。其次，如果用数据库储存用户权限，请注意数值的
有效范围。操作权限值请用唯一的整数!Java的int类型最多可以储存11个权限和.如果超过，可以选择其它数据类型，而且建议不同模块，使用多个权限
变量.</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/181882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-02-25 09:20 <a href="http://www.blogjava.net/cherishchen/archive/2008/02/25/181882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>回老家过节，祝各位朋友新春愉快！</title><link>http://www.blogjava.net/cherishchen/archive/2008/01/30/178529.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 30 Jan 2008 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/01/30/178529.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/178529.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/01/30/178529.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/178529.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/178529.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/178529.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-01-30 15:00 <a href="http://www.blogjava.net/cherishchen/archive/2008/01/30/178529.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>业务需求，程序员写</title><link>http://www.blogjava.net/cherishchen/archive/2008/01/16/175702.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 16 Jan 2008 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2008/01/16/175702.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/175702.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2008/01/16/175702.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/175702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/175702.html</trackback:ping><description><![CDATA[<p>最近项目郁闷，发展到要程序员写业务需求了<br />
</p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/175702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2008-01-16 15:24 <a href="http://www.blogjava.net/cherishchen/archive/2008/01/16/175702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对最近几个大片的精辟评价</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/25/170302.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Tue, 25 Dec 2007 06:14:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/25/170302.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/170302.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/25/170302.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/170302.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/170302.html</trackback:ping><description><![CDATA[<p>群里兄弟聊天，突然一兄弟贴出：<br />
</p>
<p>色戒告诉我们,女人是不可靠的;<br />
投名状告诉我们,兄弟是不可靠的;<br />
集结号告诉我们,组织是不可靠的 <br />
</p>
<br />
<p><br />
</p>
<p><br />
</p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/170302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-25 14:14 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/25/170302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wait sleep </title><link>http://www.blogjava.net/cherishchen/archive/2007/12/14/167796.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Fri, 14 Dec 2007 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/14/167796.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/167796.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/14/167796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/167796.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/167796.html</trackback:ping><description><![CDATA[<p>1.sleep()使线程休眠一段时间，一段时间结束后，线程进入可执行状态，但并不是立即执行，只是在被排程器调用的时候才执行。在休眠期间，并不释放所持有的&#8220;锁&#8221;；</p>
<p>2.wait()使线程休眠一段时间，若设置参数，时间到时，线程就自动进入可执行状态。若没有，则需要notify()方法去调用。注意：wait()方法和notify()方法都时针对this对象的，调用wait()方法后，会释放加在对象上的&#8220;锁&#8221;。</p>
<p>3.yield()使线程放弃执行的权利，进入可执行状态，也就意味着线程在yield()方法后，有可能又执行。使用yield()方法，线程并不释放自己锁持有的&#8220;锁&#8221;。</p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/167796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-14 16:04 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/14/167796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>public static final 数组的作用</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/06/165733.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Thu, 06 Dec 2007 02:24:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/06/165733.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/165733.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/06/165733.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/165733.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/165733.html</trackback:ping><description><![CDATA[<p>对于<span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;String[]&nbsp;CODES={&nbsp;</span><span class="string">"A"</span><span>,</span><span class="string">"B"</span><span>,&nbsp;</span><span class="string">"C"</span><span>,&nbsp;</span><span class="string">"D"</span><span>,&nbsp;</span><span class="string">"E},是得不到所期望的保护codes数组内容的功能的，至多只能做到保护</span></span>指向codes的指针不可更改。<br />
<br />
改进方案：<br />
</p>
<li class="alt"><span><span class="string">解决方案1:定义一个私有数组，以及编写一个公有的非可变列表：</span>&nbsp;</span>
<p class=""><span><span class="string">&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;final&nbsp;String[]&nbsp;CODES&nbsp;={&nbsp;"</span><span>A</span><span class="string">","</span><span>B</span><span class="string">",&nbsp;"</span><span>C</span><span class="string">",&nbsp;"</span><span>D</span><span class="string">",&nbsp;"</span><span>E</span><span class="string">"};</span>&nbsp;</span></p>
<p class=""><span><span class="string">&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;final&nbsp;List&nbsp;VALUES=&nbsp;Collections.unmodifiableList(Arrays.asList(CODES));&nbsp;</span></span></p>
这个时候，如果VALUES有修改操作，会抛出java.lang.UnsupportedOperationException </li>
<p class="alt"><br />
<br />
参考：<a href="http://www.javaeye.com/topic/54226">http://www.javaeye.com/topic/54226</a>&nbsp;&nbsp;&nbsp; <a title="慎重使用final数组" href="http://www.javaeye.com/topic/54226">慎重使用final数组</a></p>
<img src ="http://www.blogjava.net/cherishchen/aggbug/165733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-06 10:24 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/06/165733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Debugging tip，关于Server JVM和client JVM</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/05/165578.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 05 Dec 2007 08:45:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/05/165578.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/165578.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/05/165578.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/165578.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/165578.html</trackback:ping><description><![CDATA[Debugging tip:&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;For server applications, be sure to always specify the -server JVM command line switch when invoking the JVM, even for development and testing. The server JVM performs more optimization than the client JVM, such as hoisting variables out of a loop that are not modified in the loop; code that might appear to work in the development environment (client JVM) can break in the deployment environment (server JVM). For example, had we "forgotten" to declare the variable asleep as volatile in Listing 3.4, the server JVM could hoist the test out of the loop (turning it into an infinite loop), but the client JVM would not. An infinite loop that shows up in development is far less costly than one that only shows up in production.<br />
<br />
在开发环境下（一般使用的是client JVM）调试将要在Server JVM上运行的java程序时，最少指定jvm为server jvm，这样可以更早地发现问题，具体说明见上述描述
<img src ="http://www.blogjava.net/cherishchen/aggbug/165578.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-05 16:45 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/05/165578.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Volatile 变量</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/05/165551.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 05 Dec 2007 08:09:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/05/165551.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/165551.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/05/165551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/165551.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/165551.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;作为解决上篇中提到的多线程环境下的memory visibility问题，java提供了一种比同步（synchronization）机制相对弱的一种形式--Volatile 变量，来确保更新一个多线程共享变量可以以一种可预告的方式通知其他线程。volatile变量并不缓存到寄存器中（registers）或者缓存到其他处理器（多处理器环境，register只能被包含它的处理器看见）看不见的地方，因此对于volatile变量的读取总是会返回最新的结果（因为没有使用缓存）<br />
&nbsp;&nbsp;&nbsp;&nbsp;访问volatile变量不需要加锁，因此不会导致当前执行的线程堵塞，所以volatile变量相对于synchronized来说是一种轻量级的同步机制。<br />
&nbsp;&nbsp;&nbsp;&nbsp;显然因为没有利用缓存，所以比起非voiatile变量，在当前的处理器架构下，读取性能会略有损失<br />
</p>
原文：<br />
The Java language also provides an alternative, weaker form of synchronization, volatile variables, to ensure that updates to a variable are propagated predictably to other threads. When a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.<br />
<br />
Yet accessing a volatile variable performs no locking and so cannot cause the executing thread to block, making volatile variables a lighter-weight synchronization mechanism than synchronized.<br />
<br />
Volatile reads are only slightly more expensive than nonvolatile reads on most current processor architectures.<br />
<br />
<br />
So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and&nbsp; reading a volatile variable is like entering a synchronized block. However, we do not recommend relying too heavily on volatile variables for visibility; code that relies on volatile variables for visibility of arbitrary state is more fragile and harder to understand than code that uses locking.<br />
从memory visibility的方面来看，写入一个volatile变量就像离开一个同步块，而读取volatile变量就像进入一个同步块。尽管如此，建议不要太多依赖与volatile变量，因为这样会导致代码比起用同步块更难以理解<br />
<br />
Use volatile variables only when they simplify implementing and verifying your synchronization policy; avoid using volatile&nbsp;&nbsp;&nbsp; variables when veryfing correctness would require subtle reasoning about visibility. Good uses of volatile variables include ensuring the visibility of their own state, that of the object they refer to, or indicating that an important lifecycle event<br />
(such as initialization or shutdown) has occurred. <br />
<br />
The most common use for volatile variables is as a completion, interruption, or status flag。<br />
Volatile variables can be used for other kinds of state information, but more care is required when attempting this. For example, the semantics of volatile are not strong enough to make the increment operation (count++) atomic, unless you can guarantee<br />
that the variable is written only from a single thread.<br />
<br />
结论：Locking can guarantee both visibility and atomicity; volatile variables can only guarantee visibility.You can use volatile variables only when all the following criteria are met:<br />
&nbsp;&nbsp;&nbsp;&nbsp;􀁺 Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;􀁺 The variable does not participate in invariants with other state variables; and<br />
&nbsp;&nbsp;&nbsp;&nbsp;􀁺 Locking is not required for any other reason while the variable is being accessed. 
<img src ="http://www.blogjava.net/cherishchen/aggbug/165551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-05 16:09 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/05/165551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>刚刚申请到的免费jsp主机</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/05/165481.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 05 Dec 2007 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/05/165481.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/165481.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/05/165481.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/165481.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/165481.html</trackback:ping><description><![CDATA[http://www.myjavaserver.com/~cherishchen/
<img src ="http://www.blogjava.net/cherishchen/aggbug/165481.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-05 14:18 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/05/165481.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>synchronized 的另外一个作用memory visibility</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/05/165423.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 05 Dec 2007 02:56:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/05/165423.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/165423.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/05/165423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/165423.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/165423.html</trackback:ping><description><![CDATA[<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;NoVisibility&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;ready;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;number;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ReaderThread&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;Thread&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(ready)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.yield();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(number);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ReaderThread().start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">42</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ready&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<br />
synchronized关键字除了用于保证代码段的原子性外，另外一个非常重要的意义在于对于线程共享变量修改的可视。<br />
We want not only to prevent one thread from modifying the state of an object when another is using it, but also to ensure that when a thread modifies the state of an object, other threads can actually see the changes that were made.But without synchronization, this may not happen.<br />
<br />
When a thread reads a variable without synchronization, it may see a stale value, but at least it sees a value that was actually placed there by some thread rather than some random value.This safety guarantee is called out-ofthin- air safety. Out-of-thin-air safety applies to all variables, with one exception: 64-bit numeric variables (double and long) that are not declared volatile<br />
<br />
结论：<br />
Locking is not just about mutual exclusion; it is also about memory visibility. To ensure that all threads see the most up-to-date values of shared mutable variables, the reading and writing threads must synchronize on a common lock.<br />
互斥并不是加锁的唯一目的，还包含memory visibility。<strong>为了保证所有的线程能够访问到最新的共享变量的值，所有的读写共享变量的操作都需要对同一个对象加锁以保证同步<br />
</strong><br />
from Java Concurrency in Practice&nbsp; By Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes,<br />
Doug Lea 
<img src ="http://www.blogjava.net/cherishchen/aggbug/165423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-05 10:56 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/05/165423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Concurrency in Practice</title><link>http://www.blogjava.net/cherishchen/archive/2007/12/05/165381.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 05 Dec 2007 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/12/05/165381.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/165381.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/12/05/165381.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/165381.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/165381.html</trackback:ping><description><![CDATA[Java Concurrency in Practice<br />
<img alt="java concurrency in practice" src="http://ecx.images-amazon.com/images/I/51Hx%2Bg4Q6QL._SS500_.jpg" height="500" width="500" /><br />
<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/165381.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-12-05 09:49 <a href="http://www.blogjava.net/cherishchen/archive/2007/12/05/165381.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google Android 平台(转)</title><link>http://www.blogjava.net/cherishchen/archive/2007/11/18/161415.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Sun, 18 Nov 2007 09:01:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/11/18/161415.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/161415.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/11/18/161415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/161415.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/161415.html</trackback:ping><description><![CDATA[<h4><a title="http://chinese.engadget.com/2007/11/06/googles-android-platform-and-the-open-handset-alliance-a-quick/" href="http://chinese.engadget.com/2007/11/06/googles-android-platform-and-the-open-handset-alliance-a-quick/">http://chinese.engadget.com/2007/11/06/googles-android-platform-and-the-open-handset-alliance-a-quick/</a></h4> <p>&nbsp;</p> <p>&nbsp;</p> <p>老實說，到目前為止關於 Google Android 和 Open Handset Alliance 大家想必是「說得很清楚，聽得很模糊」，所以我們這裡稍微整理了一下已知道的事情，看能不能讓情況清楚一點。如果這樣還不夠明瞭的話，那知道一件事就夠了：第一隻 Google 作業系統的手機預計 2008 年下半年上市。 <ul> <li>Android 是Google 的手機作業系統和相關軟體的總稱，和一般在說「Symbian」、「Windows Mobile」時是相同的。  <li>今天的發表有兩個不同，但相關的組成元件：以 Linux 為核心的 Android 行動平台（這間公司是 Google 在 2005 年買下的）和 Open Handset Alliance，一個由 33 間手機製造商、軟體商和電信業者組成的 Android 推廣聯合會。  <li>並沒有所謂的硬體「Gphone」，而 Google 也沒有打算（或至少沒有公開打算）要進入手機硬體市場。到時候真的做手機的，是 HTC、Samsung、LG 這些手機廠，而因為 Android 的程式碼是開放式的，理論上任何人都可以以 Android 為基礎開發新手機。  <li>雖然平台是開放的，但並沒有辦法保證裝到手機上了之後還是開放的。手機商和電信業者有權利決定是否在特定的機種上允許第三方軟體的安裝。  <li>Nokia、Apple、Palm 和 Microsoft 不在這個 33 間公司的名單中。Palm 稍早發佈了新聞稿表示將繼續在 Palm OS 平台上支援 Google 的服務。  <li>第一批 Android 手機預計在 2008 年下半年上市。傳聞中 Google 有用一台 HTC 的概念機「Dream」來示範 Android 平台，而這隻概念機有可能成為第一批使用 Android 的手機之一。 </li></ul><img src ="http://www.blogjava.net/cherishchen/aggbug/161415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-11-18 17:01 <a href="http://www.blogjava.net/cherishchen/archive/2007/11/18/161415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>上周末考系分，又是一个失败</title><link>http://www.blogjava.net/cherishchen/archive/2007/11/05/158191.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 05 Nov 2007 02:20:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/11/05/158191.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/158191.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/11/05/158191.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/158191.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/158191.html</trackback:ping><description><![CDATA[<p>上次失败在论文上，这个看来也不会例外，一看论文的题目没有合适写的，最后编了个电子商务的项目写了写，对题干中的“技术基础设施”的含义猜测不透，勉强凑满2000字，估计已经离题万里，铁定过不了了。</p> <p>按说自己水平不行，也没有什么好说的，但是对于“技术基础设施”这种抽象的概念，出题者难得不能给个明确的范围或者定义吗？我google了这个词汇，什么解释都有，出题者在这点也太不负责了，软件领域强调沟通，这点应该是必须的。</p> <p>&nbsp;</p> <p>&nbsp;呵呵，发发牢骚，下次不准备再考，等水平够了再考</p> <p>&nbsp;</p> <p><a href="http://www.blogjava.net/images/blogjava_net/cherishchen/WindowsLiveWriter/fccfc0cd3caa_8FB6/image.png" atomicselection="true"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="238" alt="image" src="http://www.blogjava.net/images/blogjava_net/cherishchen/WindowsLiveWriter/fccfc0cd3caa_8FB6/image_thumb.png" width="377" border="0"></a> </p> <p>附上考题地址：<a title="http://rk.csai.cn/rjsp/200711032348471038.htm" href="http://rk.csai.cn/rjsp/200711032348471038.htm">http://rk.csai.cn/rjsp/200711032348471038.htm</a></p><img src ="http://www.blogjava.net/cherishchen/aggbug/158191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-11-05 10:20 <a href="http://www.blogjava.net/cherishchen/archive/2007/11/05/158191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>周末拓展</title><link>http://www.blogjava.net/cherishchen/archive/2007/10/22/155034.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 22 Oct 2007 08:49:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/10/22/155034.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/155034.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/10/22/155034.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/155034.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/155034.html</trackback:ping><description><![CDATA[上周末去怀柔拓展，很累，但是收获不小，感觉挺值<br />
<br />
不要想的太多，坚持就好<br />
<img src ="http://www.blogjava.net/cherishchen/aggbug/155034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-10-22 16:49 <a href="http://www.blogjava.net/cherishchen/archive/2007/10/22/155034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Discussion Toolkit（转）</title><link>http://www.blogjava.net/cherishchen/archive/2007/09/28/149220.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Fri, 28 Sep 2007 08:35:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/09/28/149220.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/149220.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/09/28/149220.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/149220.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/149220.html</trackback:ping><description><![CDATA[<p><a title="http://www.stickyminds.com/sitewide.asp?Function=WEEKLYCOLUMN&amp;ObjectId=12875&amp;objecttype=ARTCOL" href="http://www.stickyminds.com/sitewide.asp?Function=WEEKLYCOLUMN&amp;ObjectId=12875&amp;objecttype=ARTCOL"><font size="3">http://www.stickyminds.com/sitewide.asp?Function=WEEKLYCOLUMN&amp;ObjectId=12875&amp;objecttype=ARTCOL</font></a></p> <p><font size="3">By </font><a href="http://www.stickyminds.com/sitewide.asp?Function=WEEKLYCOLUMN&amp;ObjectId=12875&amp;objecttype=ARTCOL#authorbio"><font size="3">Michele Sliger</font></a></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"><strong>Summary</strong>: Saying the right thing at the right time can be difficult. Prepare yourself with a handful of phrases that will help you keep the conversation going in the right direction. In this week's column, Michele Sliger offers a few of her own phrases to help you build a discussion toolkit.</font></p> <p><font size="3">能够做到在恰当的时机说恰当的话是很不容易的。使用一些有用的表达方式来武装自己将会让交流向你期望的方向进行。Michele Sliger 提供了一些她自己总结的常用表达方式。</font></p> <p><font size="3">Many of us often find ourselves wishing we had some magic phrases that would make conversations more productive and less difficult. I'm sure we've all had our share of experiences where we've thought of the right thing to say several hours <i>after</i> the conversation or meeting ended. (That's frustrating!) Wouldn't it be great if we had a toolbox full of just the right phrases, the perfect questions, and the best ways to start, guide, or end discussions? We could just reach in and grab the most appropriate lines to help us in almost every situation. Below are a few lines you can use to help build your own basic discussion toolkit. </font></p> <h3><font size="3"></font></h3> <h3><strong><font size="3"></font></strong>&nbsp;</h3> <h2><strong><font size="3">For Personal Conflicts 个人冲突</font></strong></h2> <h2><font size="3"></font></h2> <p><font size="3"><b><i>And how is that working out for you?</i></b><br>This is a great rejoinder to use when you first want to make sure there's a problem on the table and that the other person recognizes it. After the person offers a lengthy explanation of how things are done, asking how it's working for him will lead either to a quick end of the discussion ("Everything is working out fine, thank you very much"—"Well that's great, I guess I'll be going then.") or a genuine interest in doing something differently ("It's not working out as well as I'd hoped, to be honest"—"Okay, let's see if I can help."). </font></p> <p><br><font size="3"><b><i>What did he say when you told him that?</i></b><br>This response to a complaint helps prevent team members from expecting you to be a go-between, and it can also help extricate you from having to listen to gossip. Usually folks are focused on handing the problem to you, and when you hand it right back it can take a minute for them to realize the ball is back in their court. This isn't to say that you should leave your associates to handle difficult conversations all by themselves if they aren't prepared to do so. Leaders do have a responsibility to help staff learn precisely how to sort these things out for themselves and how to find the right words and the right approach. <br><b><i></i></b></font></p> <p><font size="3"><b><i>I've noticed that . . .</i></b><br>This is an objective and non-confrontational way to begin a discussion. State what you've noticed, and then listen. Whether you've noticed that an individual is really stepping outside her job description to help others on the team or that an individual has a problem getting to work on time, starting a conversation with a presentation of things that you've observed to be true opens the door for the other person. She can respond with delight that you've noticed her hard work—or gripe that she has to be all things to all people. She may have an explanation for her tardiness or a promise to do better. <br><b><i></i></b></font></p> <p><font size="3"><b><i>What are you going to do next?</i></b><br>It's always good to leave a discussion with an understanding of how each person is going to take the information she's learned from the meeting room back to her desk and apply it in the business. Asking what the next steps are creates a future line of action items and milestones that can be followed so that the problem is tracked through to a resolution. </font></p><font size="3"> <p><br><b>For Meetings 会议</b></p> <h3></h3> <p><b><i>Would you summarize that into three or four bullet points for me?</i></b><br>Some people solve problems by talking about them out loud. Often team leaders find themselves being the sounding board for such monologues. Help your team members learn how to summarize issues by asking for verbal bullet points. This also keeps meetings moving. The question can be addressed to the whole team by saying, "<b>Who can summarize what Pat has just shared?</b>" Follow up with, "<b>Would someone like to share a different viewpoint?</b>" In this fashion, you can make sure that others have a say as well. </p> <p><br><b><i>Is this discussion helping us achieve our purpose?</i></b><br>All good facilitators ask this question in meetings when the conversation around a topic seems to be spinning. Help your team members achieve some traction by reminding them of the goal of the meeting. If the consensus is that the conversation is directly related to achieving the purpose, then make sure it can be resolved by asking additional questions, such as: <b>Can we solve this problem right now?; Is this the right group to make this decision?; How much more time do you want to spend discussing this topic?</b></p><strong></strong> <p><br><b><i>What else?</i></b><br>This question keeps a brainstorming session going in a meeting and can also be asked to make sure that an individual has really gotten everything off his chest. When the brainstorming seems to be winding down—or your watch says you're running out of time—end this portion of the discussion by asking, "<b>Anything else?</b>" It's a subtle shift, but the effect is to shut down the discussion. It indicates that it's time to move on. </p> <p><br><b>Miscellaneous</b><br><b><i>I appreciate . . .</i></b><br>Here's a phrase we don't use enough. Let people know when you are grateful for something they've said or done. Being recognized is a great reward, and training yourself to look for the positive things and not just the problems will make your management style well-rounded. If someone is appreciating you, don't forget to say, "<b>Thank you.</b>" </p> <p><br><b><i>That sounds hard.</i></b><br>Remember that you don't have to solve every problem brought to you. Sometimes people just need to talk and be heard. They need someone to bear witness to what they are going through. Dr. Alan Wolfelt calls this "companioning," which means you are there to listen with your heart and not analyze with your head. Also, reflective listening is always appropriate: "<b>This is what I heard you say . . .</b>" </p> <p><br><b><i>Yes, and . . .</i></b><br><strong>Use this phrase instead of "Yes, but . . ." </strong>It might be difficult to do at first and takes some practice, but this is a beneficial phrase for allowing a conversation to continue. By saying "Yes, <i>but . . .</i>" you are effectively telling the other person that you are discarding everything she just said and presenting your idea as the only real option. This can create frustration in the other person, who may feel like you've just dismissed her instead of acknowledging and exploring her idea. Responding with "Yes, <i>and . . .</i>" says, "I've heard you, and I'm willing to continue this discussion with you," without agreeing with her statement. For example, you can say "Yes, giving everyone Friday off would be nice, and I'd be concerned about how we'd meet our deadline if we did that." This gives the other person the opportunity to respond with an alternative; and the conversation continues. Of course, you could simply take the next option. </p> <p><br><b><i>No.</i></b><br>This is such a hard word to say for so many of us! Yet I've found this should often be at the top of one's discussion toolkit. William Ury, author of <i>The Power of a Positive No</i>, said in his book tour that Warren Buffet, investment manager and CEO of Berkshire Hathaway, has said that he says no all day to the investment proposals that pile up on his desk. "I only have to say yes four or five times in my life to the right things, and I'm a billionaire!" The trick for the rest of us is to learn how to say no with respect and to provide alternatives—if appropriate—in order to keep the negotiation going. Try following your no with phrases such as "Instead . . ." or "However . . ."—for example, "No, I can't work late tonight. However, I would be able to put in extra time on this next week." <br>Now you have a few phrases and questions that you can stow in your own discussion toolkit! What else can you think of that might be helpful? Or maybe I should say, "Anything else?"</p> <p><br></font><a><font size="3"><strong>About the Author</strong></font></a><br><font size="3">Michele Sliger has extensive experience in agile software development, having worked in both XP and Scrum teams before becoming a consultant. As a self-described "bridge builder," her passion lies in helping those in traditional software development environments cross the bridge to agility. Along with co-author Stacia Broderick, their forthcoming book "The Software Project Manager's Bridge to Agility" will focus on that topic, helping PMI-trained project managers make the transition. Michele is a Certified Scrum Trainer (CST) and a certified Project Management Professional (PMP). If you have a question, or would like help with your agile adoption, Michele can be reached at </font><a href="mailto:michele@sligerconsulting.com"><font size="3">michele@sligerconsulting.com</font></a><font size="3">.</font></p><img src ="http://www.blogjava.net/cherishchen/aggbug/149220.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-09-28 16:35 <a href="http://www.blogjava.net/cherishchen/archive/2007/09/28/149220.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样做一个优秀的系统分析师？</title><link>http://www.blogjava.net/cherishchen/archive/2007/09/26/148237.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Wed, 26 Sep 2007 02:45:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/09/26/148237.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/148237.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/09/26/148237.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/148237.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/148237.html</trackback:ping><description><![CDATA[<p><a href="http://blog.csdn.net/hdy007/archive/2007/03/14/1528642.aspx"><img height="13" src="http://blog.csdn.net/images/zhuan.gif" width="15" border="0">&nbsp;怎样做一个优秀的系统分析师？</a>  <p>作者：IT168 铁在烧 发表日期：2007-03-14 08:55  <p>笔者常常在思考一个问题,什么是系统分析师?什么样的人是优秀的系统分析师?什么样的人是企业真正需要的系统分析师?系统分析师也许很神秘,也许很抽象,他有很多其他称谓,比如需求分析师、分析师等等。你可以说系统分析师是IT技术专家,也可以说他是业务专家,甚至可以说系统分析师是管理专家,那么他到底是什么? <br>&nbsp;&nbsp;&nbsp; 也许,有一点我们可以确定,系统分析师连接着用户的需求,系统分析师主导着开发的实现,系统分析师的素质高低对IT项目的成败起到很重要的作用。&nbsp;<br>&nbsp;&nbsp;&nbsp; 近年来,我国IT软件产业发展规律迅猛,需要大量IT人才,尤其需要居于IT人才金字塔顶端的系统分析师人材,笔者以自己的做系统分析师一些经验和对这个职业的理解，试图用一些文字研究系统分析师的素质和能力模型，以飨读者和广大IT技术人员、系统分析师同仁。&nbsp;<br>&nbsp;&nbsp;&nbsp; 要想成为一名优秀的系统分析师，首先必须弄明白与系统分析师相关的一些职业理念和相关的工作概念定义。&nbsp;<br><strong>&nbsp;&nbsp;&nbsp; 一、 如何理解系统、信息系统、系统分析、系统设计、系统分析师？</strong><br>&nbsp;&nbsp;&nbsp; 系统是一组为实现某些结果相互联系、相互作用的部件的集合体。而信息系统是一组完成收集、处理、储存信息和以输出完成商业任务所需信息作为提交的系统。系统分析是理解并详细说明信息系统应该做什么的过程。系统设计是详细说明信息系统的诸多组件在物理上是怎样实施的过程。&nbsp;<br>&nbsp;&nbsp;&nbsp; 系统分析师是使用信息技术的商业专业人员，利用分析和设计技术解决业务问题。他是团队中的一种角色,主要负责与涉众客户代表协同工作,以便对项目需求进行获取、分析、编写说明规格、确认和管理,也可称需求分析师,业务分析员等。&nbsp;<br>&nbsp;&nbsp;&nbsp; 做一名系统分析师，要首先认识什么是系统分析师。对于同样一件事物的认识，每个人都会不一样，“一千个人有一千个哈姆雷特”，这关乎到认识论。其实,一个人的认识正好折射出了他的经验、水平、层次、能力。一句话，大道由简，我们也许熟悉了很多系统分析方面的技术，然后我们需要问自己是不是真的懂这个职业的本质含义所在，一定不要舍本求末。&nbsp;<br>&nbsp;&nbsp;&nbsp; 上面的定义很简单，但反映了一些基本的要素。系统分析师首先是商业人员，然后才是IT技术人员，但系统分析师不是程序员，他的使命是解决业务问题，手段是信息技术。他不但要理解还要会详细地说明，这意味着他的商业知识、理解分析能力以及表达能力是比较基础的核心能力。还有, 系统分析最重要的是实践过程。系统分析师最好和业务人员打成一片,这样才会获得用户的信任。&nbsp;<br>&nbsp;&nbsp;&nbsp; 顺便需要说明的是，信息系统有很多种类型,常见的有OLTP、 MIS、EIS、DSS。当然,你还可以谈很多,其实，任何一个名词都足够写一本书,你就大胆地讲出你的理解吧。但一定要记得总结,用一句话能总结出来就不用两句话,系统分析这个职位对思维的清晰要求颇高。&nbsp;  <p><strong>&nbsp;&nbsp;&nbsp; 二、系统分析师需要哪些技能？&nbsp;<br></strong>首先，系统分析师应熟悉如何建立信息系统，这要求相当高的信息技术能力，包括软件工程、主流技术架构、网络、数据库技术等等。&nbsp;<br><strong></strong>第二,系统分析师应必须熟悉自己正为之工作的商业行业，以及该行业如何使用各种类型系统的情况。&nbsp;<br><strong></strong>最后，系统分析师应需要熟悉相当多的人及其工作方式，因为这些人是信息系统的使用者，或者说是系统分析师的“客户”。&nbsp;<br><strong></strong>系统分析师是“通才”，正是因为他们连接了IT和业务。优秀的分析师其实懂三种“世界”的语言，即计算机语言、商业语言、人的语言。&nbsp;<br><strong></strong>对于商业，有些分析师一生专门研究一个特定的商业行业，比如制造业、零售业、服务业或贸易行业。一个非常熟悉某特定行业的分析师能够为这个行业的公司解决一些复杂的问题。 <br>熟悉这个公司则需要花费一些时间，尤其是细节方面，包括组织结构、使命、成功的因素、战略和计划、企业文化和企业价值。&nbsp;<br><strong></strong>总之,系统分析师=行业业务专家+IT技术专家+管理专家。&nbsp;<br><strong>&nbsp;&nbsp;&nbsp; 三、系统分析师解决问题的大致过程是什么？&nbsp;<br></strong><br><strong></strong>系统分析师解决问题的大致过程一般如下：&nbsp;<br><strong></strong>（1）研究和理解问题。&nbsp;<br><strong></strong>（2）核实解决问题的效益大于成本。&nbsp;<br><strong></strong>（3）确定解决问题的需求。&nbsp;<br><strong></strong>（4）制定一套可能的解决方案，提供多种可供选择的方法。&nbsp;<br><strong></strong>（5）决定最佳方案并推荐给决策层。&nbsp;<br><strong></strong>（6）详细说明所选方案的细节。&nbsp;<br><strong></strong>（7）实施解决方案。&nbsp;<br><strong></strong>（8）监控结果是否达到预期结果。&nbsp;<br><strong></strong>这个是经过归纳的大致过程,实际还有其他经典的过程,与之的区别只是形式上不同，但求解问题的过程是一致的。&nbsp;<br><strong></strong>上面的步骤是经过归纳过的，也许不同类型的系统，不同类型的企业工作方法不尽相同，但从宏观的角度看的确是类似的。  <p><strong>&nbsp;&nbsp;&nbsp; 四、系统分析原型法的意义&nbsp;<br></strong><br><strong></strong>原型(Prototype) 即样品、模型的意思。把系统主要功能和接口通过快速开发制作为“软件样品 ”，以可视化的形式展现给用户，及时征求用户意见，从而明确无误地确定用户需求。另外，原型也可用于征求内部意见，作为分析和设计的接口之一，可方便于沟通。&nbsp;<br><strong></strong>对原型的基本要求包括：体现主要的功能、提供基本的界面风格、展示比较模糊的部分以便于确认或进一步明确。原型最好是可运行的，至少在各主要功能模块之间能够建立相互连接。&nbsp;<br><strong></strong>原型法意义在于可视化、强化沟通、降低风险、节省后期变更成本、提高项目成功率。一般来说，采用原型法后可以改进需求质量。虽然投入了较多先期的时间，但可以显著减少后期变更的时间。原型法投入的人力成本代价并不大，但可以节省后期成本。对于较大型的软件项目来说，原型系统可以成为开发团队的蓝图。另外，原型通过充分和客户交流，还可以提高客户满意度。&nbsp;<br><strong></strong>原型法是在计算机技术发展到一定阶段，用户应用需求高涨的情况下发展的一种方法论，但它同时又是对开发人员有高要求的一种方法论。&nbsp;<br><strong></strong>原型法的基本思想如下: 原型法是确定需求策略，是对用户需求进行抽取、描述和求精。它快速地、选代地建立最终系统工作模型，对问题定义采用启发的方式，由用户作出响应。原型法实际上是一种动态定义技术。 <br>　　原型法被认为对于大多数企业的业务处理来说，需求定义几乎总能通过建立目标系统的工作模型来很好地完成，而且这种方法和严格定义方法比较起来，成功可能性更大。&nbsp;<br><strong></strong>原型法开发策略基于如下的假设： <br>　（1）并非所有的需求在系统开发以前都能准确地说明。 <br>　（2）有快速的系统建造工具。 <br>　（3）项目参加者之间通常都存在通信上的障碍。 <br>　（4）需要实际的、可供用户参与的系统模型(system model)。&nbsp;<br><strong></strong>文字和静态图形是一种比较好的通信工具，然而其最大的缺点是缺乏直观的、感性的特征，因而往往不易理解对象的全部含义。交互式原型系统能够提供生动活泼的规格说明，用户见到的是一个“活”的、运行着的系统。理解纸面上的系统和操作运行在机器上的系统，其差别是十分显著的。因此，当能够提供一个生动的规格说明成为可能的话，人们就不会满足于一个静止的、被动的规格说明。 <br>　　总之，当提供一个活生生的系统模型时，人们对它的了解将比说明性材料好得多。 <br>　（5）需求一旦确定，就可以遵从严格的方法。 <br>　　（6）大量的反复是不可避免的、必要的，应该加以鼓励。 <br>在信息系统设计的过程中，常用的各种不同形式的部分原型有： <br>　　（1） 对话原型 <br>　　原型模拟预期的终端交互，使用户可以从屏幕上查看他们将接收什么、进行的操作，并提出遗漏之处，从而加深正确的理解。终端对话的设计效果直接影响着系统的可用性和用户对系统的接受程度。 <br>　（2） 数据输入原型&nbsp;<br><strong></strong>建立数据输入的原型，可以检查数据的输入速度和正确性，还能进行有效性和完整性的检查。 <br>　（3） 报表系统原型&nbsp;<br><strong></strong>提供给用户的各种报告应在整个系统实现之前给用户看，报表子系统需要经常进行大量修改以满足系统的需要，因此，可以把报表生成器作为原型。 <br>　　（4） 数据系统原型 <br>　　首先生成一个含有少量记录的原型数据库，这样用户和分析师与它可以进行交互，生成报表和显示有用信息。这种交互经常导致产生对不同的数据类型、新的数据域或不同的数据组织方式的需求，还可以在原型化工具的帮助下探索用户将如何使用信息以及数据库是什么样的。 <br>　（5） 计算和逻辑原型 <br>　　有时一个应用逻辑或计算是复杂的。审计员、工程师、投资分析师和其他用户可以使用高级程序设计语言建立他们所需的计算实例。这些实例可以组合在一起构成一个大的系统，与其它应用系统、数据库或终端相连接，用户可以使用这些计算原型检验他们所求结果的准确性。 <br>　　（6） 应用程序包原型&nbsp;<br><strong></strong>在一个应用程序包和其它应用系统相连或实际使用之前，可以通过一个小组用户来鉴定这个应用程序包是否令他们满意，若不满意可以进行大量的修改，直到令他们满意。 <br>　　（7） 概念原型&nbsp;<br><strong></strong>原型法是近年来流行的软件需求捕获方法之一。我们应该明白原型法是手段而不是目的。需要回答的要点是,原型法的背景、概念、定义、意义、如何实现原型、最好能够举例说明。&nbsp;<br><strong></strong>能够回答这些问题才能说明你完全掌握了原型法。很显然,提出这种问题的企业对这种方法在实际工作中是会相当倚重的，因此您不仅要知之还要行之。&nbsp;<br><strong></strong>以一个简单的案例来说明，王五是某家大型电子商务贸易公司的系统分析师,他负责做了一个询盘系统。由于询盘系统牵涉到许多抽象专业知识,因此为了便于沟通, 王五经过一番研究制作了界面原型设计,并给出了解决方案,领导和客户看了原型设计后通过该需求方案。这个案例说明,今天的需求分析,不再是分析师和客户之间的访谈,更是一种通过实际原型(模型)互相启发,从而发现需求,归纳总结需求的一个实践过程。但我们可以看到,原型法只是一种手段,与用户良好的互动和沟通是获得需求的基本点所在。  <p><strong>&nbsp;&nbsp;&nbsp; 六、如何进行有效的需求开发过程?</strong><br><strong></strong>需求描述了客户需要或目标,或者描述了为满足这种需要或目标，产品必须具有的条件或能力,它是种特性,要求产品为涉众提供价值。&nbsp;<br><strong></strong>系统需求是系统必须完成的功能和局限性。功能需求是描述系统必须完成的活动或过程的一种系统需求,它就是系统要投入的商业应用。用户需求(User Requirement) 文档描述了用户使用产品必须要完成的任务，这在使用实例（Use Case）文档或方案脚本（Scenario）说明中予以说明。功能需求(Functional Requirement)定义了开发人员必须实现的软件功能，使得用户能完成他们的任务，从而满足了业务需求。而所谓特性(Feature)是指逻辑上相关的功能需求的集合，给用户提供处理能力并满足业务需求。&nbsp;<br><strong></strong>系统分析阶段的活动则有如下几种（表1）,同时列举了其对应解决相应的关键问题。  <p>表1  <p><strong>分析阶段的活动</strong>  <p><strong>关键问题</strong>  <p>收集信息<br>是否已经拥有了全部的信息来定义系统所必须完成的工作？  <p>定义系统需求<br>需要系统做什么？  <p>构建可行性的发现原型<br>可以证明此种技术能够实现想让它完成的那些功能吗？ <br>是否已经构建出一些原型让用户能够完全理解新系统的潜在功能？  <p>产生评估方案<br>创建系统的最好方案是什么？  <p>与管理部门一起复查各种建议<br>是否应该继续设计和实现我们提出的系统？  <p>&nbsp;&nbsp;&nbsp; 解决关键问题的方法，大致如下：&nbsp;<br>&nbsp;&nbsp;&nbsp; （1） 搞清楚系统相关者,通过组织结构图找系统角色,他们是系统的主要使用力量。&nbsp;<br>&nbsp;&nbsp;&nbsp; （2） 系统开发的分析阶段的目标是理解商业功能和获得系统需求。&nbsp;<br>&nbsp;&nbsp;&nbsp; （3） 在改正旧系统到新系统的转换过程中，关键是新系统。通过调查问卷，面谈去理解新系统的限制。通过复查现有文档，去理解信息的过程。通过研究商业过程和供应商，去理解新系统的功能。最终是为新系统开发出系统需求和模型。&nbsp;<br>&nbsp;&nbsp;&nbsp; 以上的描述是一种系统分析的流程,下面介绍从需求角度看分析师的业务问题。&nbsp;<br>&nbsp;&nbsp;&nbsp; 需求开发依先后顺序可以分为：需求获取（Elicitation）、分析(Analysis)、编写规格说明（Specification）和验证（Verification）四个阶段。这些子项包括软件类产品中需求收集、评价、编写文档等所有活动。&nbsp;<br>&nbsp;&nbsp;&nbsp; 需求开发活动包括以下几个方面：&nbsp;<br>&nbsp;&nbsp;&nbsp; （1） 确定产品所期望的用户类。&nbsp;<br>&nbsp;&nbsp;&nbsp; （2）获取每个用户类的需求。&nbsp;<br>&nbsp;&nbsp;&nbsp; （3） 了解实际用户任务和目标以及这些任务所支持的业务需求。&nbsp;<br>&nbsp;&nbsp;&nbsp; （4）分析源于用户的信息，以区别用户任务需求、功能需求、业务规则、质量属性、建议解决方法和附加信息。&nbsp;<br>&nbsp;&nbsp;&nbsp; （5）将系统级的需求分为几个子系统，并将需求中的一部份分配给软件组件。&nbsp;<br>&nbsp;&nbsp;&nbsp; （6）了解相关质量属性的重要性。&nbsp;<br>&nbsp;&nbsp;&nbsp; （7）商讨实施优先级的划分。&nbsp;<br>&nbsp;&nbsp;&nbsp; （8）将所收集的用户需求编写成规格说明和模型。&nbsp;<br>&nbsp;&nbsp;&nbsp; （9）评审需求规格说明，确保对用户需求达到共同的理解与认识，并在整个开发小组接受说明之前将问题都要弄清楚。&nbsp;<br>&nbsp;&nbsp;&nbsp; 需求分析（Requirement Analysis）包括提炼、分析和仔细审查已收集到的需求，以确保所有的风险承担者都明白其含义并找出其中的错误、遗漏或其它不足的地方。分析的目的在于开发出高质量的需求，这样你能做出实用的项目估算并可以进行设计、构造和测试。&nbsp;<br>&nbsp;&nbsp;&nbsp; 通常把需求中的一部分用多种形式来描述，如同时用文本和图形来描述。分析这些不同的视图将揭示出一些更深的问题，这是单一视图无法提供的。分析还包括与客户的交流以澄清某些混淆，并明确哪些需求是更为重要的。其目的是确保所有风险承担者尽早地对项目达成共识并对将来的产品有个相同而清晰的认识。下面是需求分析中经常使用的方法:&nbsp;<br>&nbsp;&nbsp;&nbsp; （1）绘制系统上下文示意图&nbsp;<br>&nbsp;&nbsp;&nbsp; 这种示意图是用于定义系统与系统外部实体间的界限和接口的简单模型。同时它也明确了通过接口的信息流和物质流。&nbsp;<br>&nbsp;&nbsp;&nbsp; （2）创建用户接口原型&nbsp;<br>&nbsp;&nbsp;&nbsp; 当开发人员或用户不能确定需求时，开发一个用户接口原型———个局部的可能实现——这样使得许多概念和可能发生的事更为直观明了。用户通过评价原型将使项目参与者能更好地相互理解所要解决的问题。注意要找出需求文档与原型之间的所有冲突之处。&nbsp;<br>&nbsp;&nbsp;&nbsp; （3）分析需求可行性&nbsp;<br>&nbsp;&nbsp;&nbsp; 在允许的成本、性能要求下，分析每项需求实施的可行性，明确与每项需求实现相联系的风险，包括与其它需求的冲突，对外界因素的依赖和技术障碍。&nbsp;<br>&nbsp;&nbsp;&nbsp; （4）确定需求的优先级别&nbsp;<br>&nbsp;&nbsp;&nbsp; 应用分析方法来确定使用实例、产品特性或单项需求实现的优先级别。以优先级为基础确定产品版本将包括哪些特性或哪类需求。当允许需求变更时，在特定的版本中加入每一项变更，并在那个版本计划中作出需要的变更。&nbsp;<br>&nbsp;&nbsp;&nbsp; （5）为需求建立模型&nbsp;<br>&nbsp;&nbsp;&nbsp; 需求的图形分析模型是软件需求规格说明极好的补充说明。它们能提供不同的信息与关系，以有助于找到不正确的、不一致的、遗漏的和冗余的需求。这样的模型包括数据流图、实体关系图、状态变换图、对话框图、对象类及交互作用图。&nbsp;<br>&nbsp;&nbsp;&nbsp; （6）创建数据字典&nbsp;<br>&nbsp;&nbsp;&nbsp; 数据字典是对系统用到的所有数据项和结构的定义，以确保开发人员使用统一的数据定义。在需求阶段，数据字典至少应定义客户数据项以确保客户与开发小组是使用一致的定义和术语。分析和设计工具通常包括数据字典组件。&nbsp;<br>&nbsp;&nbsp;&nbsp; （7）使用质量功能调配&nbsp;<br>&nbsp;&nbsp;&nbsp; 质量功能调配(Quality Function Deployment，QFD）是一种高级系统技术，它将产品特性、属性与对用户价值联系起来。该技术提供了一种分析方法以明确哪些是客户最为关注的特性。QFD将需求分为三类：期望需求，即客户或许并未提及，但如若缺少会让他们感到不满意；普通需求；兴奋需求，即实现了会给客户带去惊喜，但若未实现也不会受到责备。&nbsp;<br>&nbsp;&nbsp;&nbsp; 系统分析师需要掌握需求捕获、需求分析和需求确认方法,并且要有一定的实践经验,因为需求分析是门需要实践的学问。&nbsp;<br>&nbsp;&nbsp;&nbsp; 需求捕获的方法其实有多种,你可以熟悉每一种方法。通过文档概要、面谈、观察、原型、调查表、供应商调查、联合应用会议等等方法是可以获得需求的。但在实际中,你不必十八般武艺样样都要使出来, 本质上持续不断的捕获高质量的需求的方法只有一个，就是和业务人员打成一片,这样,不再是你去找需求,需求可能会来找你了,这是一种主动需求的方法,所以系统分析师一般都需要有良好的人际互动能力。&nbsp;<br>&nbsp;&nbsp;&nbsp; 当然,需求捕获还是有其自身的方法的, 要讲需求捕获必先谈到收集信息, 信息不足则“巧妇难为无米之炊”。其实这里有三个经典的问题,会是系统分析师经常用到的或提到的问题。由信息收集到需求捕获，再到需求分析是需求开发的中轴线,而能否收集到必要的有效的需求信息, 请仔细体会如下三个问题。&nbsp;<br>&nbsp;&nbsp;&nbsp; （1）商业过程和操作是什么，即你要干什么&nbsp;<br>&nbsp;&nbsp;&nbsp; 系统分析师核心是理解商业过程,一般用户只会对现状回答,但分析师要能识别在改进的系统中哪些要保留，哪些要删除。这个问题是沟通的第一步,回想当年笔者第一次就这样问用户：“你的流程是什么？你有什么问题”,何其愚也,从问用户的问题可以看出这个分析师是不是有经验。&nbsp;<br>&nbsp;&nbsp;&nbsp; （2 ）商业过程应该怎样完成，即系统分析师该如何完成它,或者说需要哪些步骤&nbsp;<br>&nbsp;&nbsp;&nbsp; 用户谈的是老系统的完成办法,而系统分析师的核心是新系统应该如何支持这项功能,而不是在现有系统下如何执行。分析师重要的是超越现在,使新技术带来的商业处理方法更高效。&nbsp;<br>&nbsp;&nbsp;&nbsp; （３）需要什么样的信息，即为了完成商业过程，系统分析师要使用哪些信息，使用什么样的表单或报告。&nbsp;<br>&nbsp;&nbsp;&nbsp; 有价值的系统分析师有一套需求捕获的手法，有价值的系统分析师一定会从理论到实际仔细研究需求分析的过程。&nbsp;<br>&nbsp;&nbsp;&nbsp; 笔者在上面介绍的一些概念和理念，并不是使您成为一个优秀系统分析师的“金科玉律”或“武功秘笈”。笔者想借助此文与读者和同仁交流沟通。 </p><img src ="http://www.blogjava.net/cherishchen/aggbug/148237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-09-26 10:45 <a href="http://www.blogjava.net/cherishchen/archive/2007/09/26/148237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模拟Adapable的demo</title><link>http://www.blogjava.net/cherishchen/archive/2007/09/17/145895.html</link><dc:creator>凭栏观海</dc:creator><author>凭栏观海</author><pubDate>Mon, 17 Sep 2007 08:22:00 GMT</pubDate><guid>http://www.blogjava.net/cherishchen/archive/2007/09/17/145895.html</guid><wfw:comment>http://www.blogjava.net/cherishchen/comments/145895.html</wfw:comment><comments>http://www.blogjava.net/cherishchen/archive/2007/09/17/145895.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cherishchen/comments/commentRss/145895.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cherishchen/services/trackbacks/145895.html</trackback:ping><description><![CDATA[<p>学习了What is IAdaptable？这篇文章，有点困惑，干脆做个demo巩固下，包括三个部分：OldObject 、NewObject和工厂类YearFactory </p> <p>&nbsp;</p> <p><span style="color: #0000ff">import</span> org.eclipse.core.runtime.IAdaptable;<br><span style="color: #0000ff">import</span> org.eclipse.core.runtime.Platform;<br></p><pre>// 实现了IAdaptable 接口
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> OldObject <span style="color: #0000ff">implements</span> IAdaptable {
	<span style="color: #0000ff">private</span> String yearmonthday;

	<span style="color: #0000ff">public</span> String getYearmonthday() {
		<span style="color: #0000ff">return</span> yearmonthday;
	}

	<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setYearmonthday(String yearmonthday) {
		<span style="color: #0000ff">this</span>.yearmonthday = yearmonthday;
	}

	<span style="color: #0000ff">public</span> Object getAdapter(Class adapter) {
		<span style="color: #0000ff">return</span> Platform.getAdapterManager().getAdapter(<span style="color: #0000ff">this</span>, adapter);
	}

}</pre><pre></pre><pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> NewObject {
    <span style="color: #0000ff">private</span> String year; 

    <span style="color: #0000ff">public</span> String getYear() {
        <span style="color: #0000ff">return</span> year;
    } 

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setYear(String year) {
        <span style="color: #0000ff">this</span>.year = year;
    } 

}</pre><pre>&nbsp;</pre><pre>完成具体的转换</pre><pre><span style="color: #0000ff">import</span> org.eclipse.core.runtime.IAdapterFactory;
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> YearFactory <span style="color: #0000ff">implements</span> IAdapterFactory {
	<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> Class[] types = { NewObject.<span style="color: #0000ff">class</span> };

	<span style="color: #0000ff">public</span> Object getAdapter(Object old, Class clazz) {
		<span style="color: #0000ff">if</span> (clazz == NewObject.<span style="color: #0000ff">class</span> &amp;&amp; old <span style="color: #0000ff">instanceof</span> OldObject) {
			NewObject objectNew= <span style="color: #0000ff">new</span> NewObject();
			objectNew.setYear(((OldObject) old).getYearmonthday().substring(2)); //随意的规则
			<span style="color: #0000ff">return</span> objectNew;
		} <span style="color: #0000ff">else</span> {
			<span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
		}

	}

	<span style="color: #0000ff">public</span> Class[] getAdapterList() {
		<span style="color: #0000ff">return</span> types;
	}

}</pre><pre>&nbsp;</pre><pre>调用转换的代码：</pre>
<blockquote><pre>Platform.getAdapterManager().registerAdapters(<span style="color: #0000ff">new</span> YearFactory(), OldObject.<span style="color: #0000ff">class</span>);
OldObject old = <span style="color: #0000ff">new</span> OldObject();
old.setYearmonthday("<span style="color: #8b0000">20070914</span>");</pre><pre>Object adaptable = old.getAdapter(NewObject.<span style="color: #0000ff">class</span>);
<span style="color: #0000ff">if</span> (adaptable != <span style="color: #0000ff">null</span>) { </pre><pre>    NewObject node = (NewObject) adaptable; </pre><pre>   System.out.println(node.getYear());</pre><pre> } </pre></blockquote>
<p>总结：</p>
<p>术语：源对象、转换类型、工厂</p>
<p>目的：实现两个不相关对象的转换</p>
<p>&nbsp;</p>
<p>（1）源对象需要实现IAdaptable接口，或者继承PlatformObject抽象类</p>
<p>（2）在源对象IAdaptable接口方法getAdapter的实现可以如下，即直接转发给AdapterManager的getAdapter()方法</p>
<blockquote><pre>&nbsp;public Object getAdapter(Class adapter) {</pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;return Platform.getAdapterManager().getAdapter(this, adapter);</pre><pre>}</pre></blockquote><pre>（3）实现转换工厂类，具体负责转换，需要实现IAdapterFactory接口，其接口方法getAdapterList()负责通知AdapterManager转换类型，</pre>
<blockquote><pre>而getAdapter方法具体完成转换</pre></blockquote><pre>（4）将转换工厂类注册到AdapterManager：</pre>
<blockquote><pre>Platform.getAdapterManager().registerAdapters(<span style="color: #0000ff">new</span> YearFactory(), OldObject.<span style="color: #0000ff">class</span>); </pre><pre>&nbsp;</pre></blockquote><pre>这样的好处在于，如果源对象需要转换到多个不相关的对象的时候，不需要修改源对象，而直接转发给相应的工厂类，这样在一定程度上保护了源对象免于修改，</pre><pre>而是修改或者增加新的工厂类。</pre>
<p>&nbsp;</p><font face="Courier New"></font><pre>&nbsp;</pre><pre>&nbsp;</pre><img src ="http://www.blogjava.net/cherishchen/aggbug/145895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cherishchen/" target="_blank">凭栏观海</a> 2007-09-17 16:22 <a href="http://www.blogjava.net/cherishchen/archive/2007/09/17/145895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>