﻿<?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-Brian Sun @ 爬树的泡泡-文章分类-转贴</title><link>http://www.blogjava.net/briansun/category/456.html</link><description>&lt;marquee direction="down" scrollamount=4 height="120" align="right"&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/09/03/11884.html"&gt;关于洞穴寓言的几部电影&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/08/31/11634.html"&gt;关于AOP的七个猜想&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/07/31/8813.html"&gt;测试驱动开发全功略&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/07/21/8095.html"&gt;体验经济在软件&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/07/20/8028.html"&gt;NXUnit 中文说明&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/07/15/7765.html"&gt;发表我自己的开源软件&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/04/16/3336.html"&gt;4月16日评点IBM&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/04/04/2808.html"&gt;4月4日评点Google&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/27/2505.html"&gt;3月27日评点版权制度&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/21/2274.html"&gt;天下归一，谈EclipseCon2005&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/20/2270.html"&gt;软件标准的生命周期&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/18/2205.html"&gt;2005年度Jolt大奖&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/14/2067.html"&gt;3月14日评点Microsoft Office&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/14/2063.html"&gt;3月14日评点OMG&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/12/1963.html"&gt;关于UI的不同解释&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/07/1786.html"&gt;非理智的抗议，只为JDO&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/03/01/1597.html"&gt;关于ERP的未来&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/02/27/1534.html"&gt;有没有可能以开源软件为平台建构ERP？&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/02/26/1518.html"&gt;UI框架的组织模式&lt;/a&gt;&lt;br&gt;
&lt;a href="http://www.blogjava.net/briansun/archive/2005/02/19/1321.html"&gt;关于人工智能&lt;/a&gt;&lt;br&gt;
&lt;/marquee&gt;</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:17:19 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:17:19 GMT</pubDate><ttl>60</ttl><item><title>信不信由你</title><link>http://www.blogjava.net/briansun/articles/11445.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Mon, 29 Aug 2005 07:08:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/11445.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/11445.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/11445.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/11445.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/11445.html</trackback:ping><description><![CDATA[
                   &nbsp;&nbsp; 1.没有一张纸可对折超过7次 
<br>

<br>

 &nbsp;&nbsp;&nbsp;2.根据统计每年驴仔所杀的人比飞机失事所死的人还多 
<br>

<br>

 &nbsp;&nbsp;&nbsp;3.人睡觉比坐着看电视所消耗的卡路里还多 
<br>

<br>

 &nbsp;&nbsp;&nbsp;4.第一种有条形码的物件是香口胶 
<br>

<br>

 &nbsp;&nbsp;&nbsp;5.Wright's Brother发明飞机后第一次试飞的路程比一架波音747飞机的飞机翼还短 
<br>

<br>

 &nbsp;&nbsp;&nbsp;6.1987年，美国一间航空公司将每个头等机位的飞机餐减少一粒橄榄后，节省了约35万港元 
<br>

<br>

 &nbsp;&nbsp;&nbsp;7.很多人每朝起来都喝一杯咖啡提神，但其实一个苹果比一杯咖啡还有效 
<br>

<br>

 &nbsp;&nbsp;&nbsp;8.你的家中多数尘埃都是你的死皮 
<br>

<br>

 &nbsp;&nbsp;&nbsp;9.洋娃娃Barbie 全名是Barabra Millicent Roberts 
<br>

<br>

 &nbsp;&nbsp;&nbsp;10.希特拉的妈妈在怀有希特拉曾认真地考虑堕胎，不过被医说服，结果把他生下来 
<br>

<br>

 &nbsp;&nbsp;&nbsp;11.玛丽莲梦露有6只脚趾 
<br>


<br>


 &nbsp;&nbsp; 12.电影里，ET的脚步声是由一位工作人员用手将o者o里榨烂 
<br>

<br>

 &nbsp;&nbsp;&nbsp;13.珍珠在醋中会溶 
<br>

<br>

 &nbsp;&nbsp;&nbsp;14.登寻找情人广告中，有35%是已婚人士 
<br>

<br>

 &nbsp;&nbsp;&nbsp;15.你有可能将一只牛拉上楼梯，但牛是不懂下楼梯的 
<br>

<br>

 &nbsp;&nbsp;&nbsp;16.猪不能仰头望天空 
<br>

<br>

 &nbsp;&nbsp;&nbsp;17.'quick brown fox jumps over the lazy dog" 可以用尽26个字母 
<br>

<br>

 &nbsp;&nbsp;&nbsp;18.鸭的叫声是不会有回音的，暂时没有人知何解 
<br>

<br>

 &nbsp;&nbsp;&nbsp;19.蜗牛可不吃东西睡3年 
<br>

<br>

 &nbsp;&nbsp;&nbsp;20.著名影星Tommy Lee Jones与美国副总统曾经是哈佛大学同房 
<br>

<br>

 &nbsp;&nbsp;&nbsp;21.如果一个月中，第一天是星期日，那个月便出现黑色星期五 
<br>

<br>

 &nbsp;&nbsp;&nbsp;22.把石头放在微波炉中加热会爆炸 
<br>


<br>


 &nbsp;&nbsp; 23.1,111,111 x 1,111,111 = 1234567654321 
<br>

<br>

 &nbsp;&nbsp;&nbsp;24.唯一一个有15英文字母而又不会重复是的英文字'uncopyrightable' 
<br>

<br>

 &nbsp;&nbsp;&nbsp;25.猫可发出超过100个音，狗却只能发10个音 
<br>

<br>

 &nbsp;&nbsp;&nbsp;26.愈黑的环境下，猫的排尿次数会增加 
<br>

<br>

 &nbsp;&nbsp;&nbsp;27.将一个硬币向上抛1000次，字向上的次数是495次，不是500次，因为公较重 
<br>

<br>

 &nbsp;&nbsp;&nbsp;28.根据牛顿字典世界上最长的英文字是"pneumonoultramicroscopicsilicovolcanoconiosis' 
<br>

<br>

 &nbsp;&nbsp;&nbsp;29.人体的胃每2个星期便会更新一次分泌物，否则它会自我消化 
<br>


<br>


 &nbsp;&nbsp; 30.可乐原是绿色的 
<br>

<br>

 &nbsp;&nbsp;&nbsp;31.夏威夷文只得12个字母 
<br>

<br>

 &nbsp;&nbsp;&nbsp;32.走路上班的人最高比率的省是阿拉斯加 
<br>

<br>

 &nbsp;&nbsp;&nbsp;33.如果Barbie是人类，她是身形是39-23-33 
<br>


<br>


 &nbsp;&nbsp; 34.美国平均每小时在空中的人有61000人 
<br>

<br>

 &nbsp;&nbsp;&nbsp;35.只有一种食物不会变坏:蜜糖 
<br>

<br>

 &nbsp;&nbsp;&nbsp;36.在加勒比海附近有一种蚝是会爬榭的 
<br>

<br>

 &nbsp;&nbsp;&nbsp;37.世界上最年轻的父母在1910年出现，一个8岁及另一个9岁的中国人 
<br>

<br>

 &nbsp;&nbsp;&nbsp;38.人顃的鼻及耳是毕生都不断长大 
<br>

<br>

 &nbsp;&nbsp;&nbsp;39.日本有一种正方形的西瓜，为的是方便收藏 
<br>


<br>


 &nbsp;&nbsp; 40.海星有8只眼，每只脚都有一只 
<br>

<br>

 &nbsp;&nbsp;&nbsp;41.有些昆虫的眼是有毛 
<br>

<br>

 &nbsp;&nbsp;&nbsp;42.一条长颈鹿的舌头有2尺长 
<br>

<br>

 &nbsp;&nbsp;&nbsp;43.大象可用头来站立 
<br>

<br>

 &nbsp;&nbsp;&nbsp;44.蚂蚁早上醒来会抓痒 
<br>

<br>

 &nbsp;&nbsp;&nbsp;45.伟大发明家爱迪生是怕黑的 
<br>

<br>

 &nbsp;&nbsp;&nbsp;46.世上最老的金鱼是41岁，名叫Fred 
<br>

<br>

 &nbsp;&nbsp;&nbsp;47.爱因斯坦9岁时不能流利说话，他妈妈曾经一度以为他是弱智 
<br>

<br>

 &nbsp;&nbsp;&nbsp;48.阿拉伯的女人可以因为丈夫不为她倒咖啡而提出离婚 
<br>

<br>

 &nbsp;&nbsp;&nbsp;49.只有55%的美国人知道太阳是一个星体 
<br>

<br>

 &nbsp;&nbsp;&nbsp;50.多数唇膏是有鱼鳞的 
<br>

<br>

 &nbsp;&nbsp;&nbsp;51.长颈鹿没办法咳嗽 
<br>

<br>

 &nbsp;&nbsp;&nbsp;52.猫头鹰是唯一能够分辨蓝色的鸟类 
<br>

<br>

 &nbsp;&nbsp;&nbsp;53.一只鲸鱼一分钟心跳只有九下 
<br>

<br>

 &nbsp;&nbsp;&nbsp;54.我们喝到肚子里头的水已经有三亿岁了 
<br>

<br>

 &nbsp;&nbsp;&nbsp;55.只有百分之三十的人可以放大缩小自己的鼻孔 
<br>

<br>

 &nbsp;&nbsp;&nbsp;56.一只牡蛎的性别会由男变女，此后一生中还会变个几次 
<br>

<br>

 &nbsp;&nbsp;&nbsp;57.根据一项1845年由英国通过的法律，自杀是非常严重的罪，最重可以处以吊死的极刑 
<br>

<br>

 &nbsp;&nbsp;&nbsp;58.在太空中航天员是没办法哭的，因为没有地心引力，眼泪流不出来 
<br>

<br>

 &nbsp;&nbsp;&nbsp;59.一只变色龙的舌头是牠自己身体的两倍长 
<br>


<br>


 &nbsp;&nbsp; 60.最常用牙签的人是美国人 
<br>

<br>

 &nbsp;&nbsp;&nbsp;61.一个正常人的眼部肌肉一天平均要动上一万到一万五千次 
<br>

<br>

 &nbsp;&nbsp;&nbsp;62.大象死后还会保持站立姿势 
<br>

<br>

 &nbsp;&nbsp;&nbsp;63.有些昆虫没有头还可以再活上一年 
<br>

<br>

 &nbsp;&nbsp;&nbsp;64.达文西光是画蒙那莉萨的嘴唇就花上十二年 
<br>

<br>

 &nbsp;&nbsp;&nbsp;65.玻璃破掉时，玻璃碎片的时速最高可达每小时三千英哩 
<br>

<br>

 &nbsp;&nbsp;&nbsp;66.乳牛听音乐时可以供应更多牛奶 
<br>

<br>

 &nbsp;&nbsp;&nbsp;67.下午摘下的玫瑰比清晨摘下的玫瑰更能持久不枯萎 
<br>

<br>

 &nbsp;&nbsp;&nbsp;68.虎鲨的胚胎在母亲的子宫里需经过激烈的搏斗，胜利者就是可以活着出生的小虎鲨 
<br>

<br>

 &nbsp;&nbsp;&nbsp;69.一只70磅的章鱼可以穿过一个仅一枚银币大小的洞，因为他们没有脊椎 
<br>

<br>

 &nbsp;&nbsp;&nbsp;70.印度尼西亚竹节虫是全世界最大的昆虫，有些光是身长就有一呎长 
<br>

<br>

 &nbsp;&nbsp;&nbsp;71.其实，河马跑得比人快 
<br>


<br>


 &nbsp;&nbsp; 72.降落伞的发明人把第一次乘坐降落伞的机会让给了一只狗 
<br>

<br>
&nbsp;&nbsp; 74.一只日本大螃蟹可能长达12呎 
<br>

<br>

 &nbsp;&nbsp;&nbsp;75.刚出生的小火鸡要有爸爸妈妈教导如何吃东西，不然会饿死 
<br>

<br>

 &nbsp;&nbsp;&nbsp;76.一只鲨鱼可以侦测到水中仅百万分之一含量的血液 
<br>

<br>

 &nbsp;&nbsp;&nbsp;77.桑巴舞的森巴原来的意思是一起磨肚脐吧 
<br>

<br>

 &nbsp;&nbsp;&nbsp;78.小孩子在春天长得比较快 
<br>

<br>

 &nbsp;&nbsp;&nbsp;79.蝙蝠是唯一能飞的哺乳动物 
<br>

<br>

 &nbsp;&nbsp;&nbsp;80.一只毛虫身上有超过两千条的肌肉 
<br>

<br>

 &nbsp;&nbsp;&nbsp;81.人的心脏可以产生把血液喷出三十尺高的压力 
<br>

<br>

 &nbsp;&nbsp;&nbsp;82.公的合掌螳螂头还在身体上的时候没办法交配，所以，母的合掌螳螂在进行交配之前，先要把雄的头砍掉 
<br>

<br>

 &nbsp;&nbsp;&nbsp;83.虾米的心脏在头部 
<br>

<br>

 &nbsp;&nbsp;&nbsp;84.你永远不可能用你的舌头添到你的手肘 
<br>

<br>

 &nbsp;&nbsp;&nbsp;85.世界人口５０％的人从来都没有接过电话 
<br>

<br>

 &nbsp;&nbsp;&nbsp;86.老鼠和马不能呕吐 
<br>

<br>

 &nbsp;&nbsp;&nbsp;87."Sixth Sick Sheik"s Sixth Sheep"s Sick "是英文中最难以发言的一个句子
<br>

<br>

 &nbsp;&nbsp;&nbsp;88.打喷嚏过于强劲了，会导致胸腔破裂，但是如果你想要将这个喷嚏强行忍住，却会导致你头或者是脖子中某个血管的破裂，另外，在你打喷嚏的时候，如果你坚持睁着眼打，说不定也会把你的眼球给一起打出来
<br>

<br>

 &nbsp;&nbsp;&nbsp;89.如果你打电话超过一个小时，那么你耳朵里的耳屎会增加大概７００倍左右
<br>

<br>

 &nbsp;&nbsp;&nbsp;90.打火机是比火柴更早发明出来的
<br>

<br>
&nbsp;&nbsp; 92.据说，在你睡觉的时候，在你不知不觉中，你会吃入七十多种虫子和十多只蜘蛛
<br>

<br>

 &nbsp;&nbsp;&nbsp;93.据说猫的尿液是夜光的
<br>

<br>

 &nbsp;&nbsp;&nbsp;94.据说，７０％的看过这个文章的人，都试图进行过同一个动作：那就是用自己的舌头添 自己的手肘
<br>
<img src ="http://www.blogjava.net/briansun/aggbug/11445.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-08-29 15:08 <a href="http://www.blogjava.net/briansun/articles/11445.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>On Plug-ins and Extensible Architecture[转]</title><link>http://www.blogjava.net/briansun/articles/3148.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Mon, 11 Apr 2005 09:18:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/3148.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/3148.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/3148.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/3148.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/3148.html</trackback:ping><description><![CDATA[


<!-- start top nav-->
<h2>On Plug-ins and Extensible Architecture</h2>

<span class="small"><br>
From <a href="http://www.acmqueue.org/modules.php?name=Content&amp;pa=list_pages_issues&amp;issue_id=21">Software Updates</a><br> &nbsp; &nbsp; &nbsp; Vol. 3, No. 2 - March 2005</span>
<br>
<span class="content"><b><i>by Dorian Birsan, Eclipse</i></b></span><br>
<p>In
a world of increasingly complex computing requirements, we as software
developers are continually searching for that ultimate, universal
architecture that allows us to productively develop high-quality
applications. This quest has led to the adoption of many new
abstractions and tools. Some of the most promising recent developments
are the new pure plug-in architectures. </p>
<p>
What began as a callback mechanism to extend an application has become
the very foundation of applications themselves. Plug-ins are no longer
just add-ons to applications; today’s applications are made entirely of
plug-ins. This field has matured quite a bit in the past few years,
with significant contributions from a number of successful projects. </p>
<p>
This article identifies some of the concepts around the foundation of
pure plug-in architectures and how they affect various stakeholders
when taking a plug-in approach. The intention is to discuss the general
issues involved, but the article also presents some lessons learned
from Eclipse (www.eclipse.org) to better illustrate some of the
concepts. </p>


<h4> MOTIVATION FOR PLUG-INS</h4>

<p>
Customers’ requirements control the creation and deployment of
software. Customers demand more and better functionality, they want it
tailored to their needs, and they want it “yesterday.” Very often,
large shops prefer to develop their own in-house add-ons, or tweak and
replace existing functions. Nobody wants to reinvent the wheel, but
rather to integrate and build on existing work, by writing only the
specialized code that differentiates them from their competition. Newer
enterprise-class application suites consist of smaller stand-alone
products that must be integrated to produce the expected higher-level
functions and, at the same time, offer a consistent user experience.
The ability to respond quickly to rapid changes in requirements,
upgradeability, and support for integrating
other vendors’ components at any time all create an additional push for
flexible and extensible applications.</p>
Down in the trenches, developers must deal with complex
infrastructures, tools, and code. The last thing they need is to apply
more duct tape to an already complex code base, so that marketing can
sell the product with a straight face.
The new plug-in architectures are very attractive to developers because
they can focus on providing modular functionality to users. Anyone can
quickly customize
applications by mixing and matching the plug-ins they need, or write
new plug-ins for missing functions. The price to pay for such
flexibility is managing these plug-ins. We discuss this and other
issues later in the article, and you can decide if it is worth the
price.

<h4> TRADITIONAL PLUG-INS VERSUS PURE PLUG-INS</h4>

<p>
Most people are familiar with traditional plug-ins, downloadable
software bundles that extend the functionality of hosting applications
such as Web browsers or
text and graphical editors. They are not compiled into the application,
but linked via well-defined interfaces and extension mechanisms. Most
often, building a plug-in does not require access to the source code of
the application. Plug-ins implement functions that the host application
can recognize and activate when needed.</p>
<p>
In the new pure plug-in architectures, everything is a plug-in. The
role of the hosting application is reduced to a runtime engine for
running plug-ins, with no inherent end-user functionality. Without a
directive hosting application, what is left is a universe of federated
plug-ins, all playing by the rules of engagement defined by the
framework and/or by the plug-ins themselves. </p>
<p>
To support composing a larger system that is not prestructured, or to
extend it in ways you don’t foresee, the architecture must support the
extensibility
of plug-ins by plug-ins. In the absence of a hosting application,
plug-ins themselves become hosts to other plug-ins by providing
well-defined hook points where other
plug-ins can add functionality. These hook points are commonly known as
extension points. When a plug-in contributes an implementation for an
extension point,
we say that it adds an extension. Much like defining any contractual
obligation, an extension model provides a structured way for plug-ins
to describe the ways
they can be extended and for client plug-ins to describe the extensions
they supply.</p>

<p> In a simplified way, figure 1 illustrates the main structural difference between
traditional and pure plug-in architectures.</p>


<p>
<a href="http://www.acmqueue.org/figures/issue021/birsan_1.jpg">Click for figure</a>
</p>


<!--pagebreak-->

<h4> PLUG-IN RUNTIME CONSIDERATIONS</h4>

<p>
As already mentioned, plug-ins are not stand-alone programs; their
execution is orchestrated by a runtime engine. The plug-in runtime
engine—let’s
call it the kernel—is the core engine that is started when a user
launches an application. At a minimum, the kernel must provide runtime
support for the basic plug-in infrastructure by:
</p>

<ul>
<li>Finding, loading, and running the right plug-in code.</li><li>Maintaining a registry of installed plug-ins and the functions they provide.</li><li>Managing the plug-in extension model and inter-plug-in dependencies.</li>
</ul>

<p>Optionally, the kernel can supply other utility services, such as
logging, tracing, or security. The user should also be able to turn off
or remove parts of the application, or dynamically install new
functions. For obvious reasons, it is desirable for the kernel to be
small and simple, yet robust enough to build industrial-strength
functionality on top of it, without many (or any) hacks. </p>
<p>
To illustrate the basic workings of a plug-in environment, let’s take a
behind-the-scenes look at the Eclipse plug-in runtime structure and
control flow. While mostly known as a powerful Java integrated
development environment,
Eclipse is actually a universal plug-in architecture for creating
“anything, but nothing in particular.” The runtime engine itself is
implemented as a number of core plug-ins, except for a tiny bootstrap
code. This code starts
the core plug-ins to initialize the plug-in registry and the extension
model and to resolve plug-in dependencies. Other than the core
plug-ins, no other plug-in code is run at this time. All the needed
plug-in metadata is read from
the plug-in manifest files (plugin.xml and/or manifest.mf).</p>
<p>
Once the initialization is complete, the runtime kernel is ready to run
applications. The extension mechanism, shown in figure 2, kicks in and
an entire application is built progressively, from inside out, as
follows: </p>


<ol>
<li>The runtime core plug-in defines an applications extension point so
that any plug-in can declare itself an application by contributing an
extension to it. </li><li>An applications extension must provide a concrete implementation
for the extension point’s callback interface, IPlatformRunnable.</li><li>Eclipse’s default applications extension is contributed by the IDE
plug-in, by providing a concrete implementation class that, when called
by the
extension point handling code, creates the workbench graphical user
interface and runs the event loop until it exits.</li>
</ol>


<p>
<a href="http://www.acmqueue.org/figures/issue021/birsan_2.jpg">Click for figure</a>
</p>


<p>
This workbench window looks like any standard application: it has
menus, toolbars, views, and editors, and you can launch wizards, open
preference dialogs, and so on. The basic workbench by itself, however,
is just a frame for displaying visual parts and other user interface
elements. Its power comes from the extension points (e.g., views,
wizards, editors, action sets, help support) it defines,
to which other plug-ins, or the workbench plug-in itself, can
contribute extensions.
</p>
<p>In general, the plug-in that defines an extension point is
responsible for looking up its extenders (using the extension
registry), instantiating the associated
callback class, and invoking the appropriate interface methods. Under
the covers, the runtime kernel is responsible for providing the
extension registry lookup
functionality, creating a class loader for the extender plug-in,
loading it, and starting it. This ensures the extender plug-in is
initialized and active before its classes are created and run.</p>
<p>
Finally, it is worth noting that some extension points may require more
than one callback interface and others do not require any. For example,
the help system extension point toc is used for contributing
documentation tables of
contents and does not require any callbacks. When help is invoked, the
help plug-in processes the toc extensions by creating a larger,
integrated table of contents from all contributing plug-ins.</p>


<h4> CONFIGURING AND DISCOVERING PLUG-INS</h4>

<p>
An important consideration when deploying a plug-in system is
configuring and discovering the plug-ins. Unlike monolithic
applications that are typically
installed in one folder on a user’s machine, plug-in-based applications
may have a higher degree of freedom for installation layout and plug-in
discovery.
This flexibility can also be a source of major headaches for installers
and plug-in management.
</p>
<p>Consider a multiuser shared installation where the entire
product is installed by the central administrator on behalf of a
community of users. The individual users do not need to perform any
installation. They are simply given a local
“shortcut” to invoke the shared installation (the shortcut can be in
the form of a command-line invocation or a true desktop shortcut
encapsulating
the command-line invocation). If you’re like most users, you will want
to install some other cool new features, especially when the
third-party plug-in
offerings are plentiful (and often free). Obviously, the new plug-ins,
private to that user, cannot be installed in the read-only, shared
install location, so the product should allow users to install and
configure extra plug-ins in
a location where they have more privileges.
</p>
<p>Configuring only a subset of plug-ins for a particular user
based on access criteria, such as user roles, adds more challenges.
Other configuration issues arise in scenarios where a common set of
plug-ins is shared by many applications running on the same machine, or
where some plug-ins are not installed locally but run from a remote
location (e.g., an application server provider).
</p>
<p>In theory, the platform must find the available plug-ins on its
own and gracefully cope with missing plug-ins or those that are
dynamically coming and going. In practice, many solutions for these
problems involve predefined files and directory locations for key
configuration files or for the plug-ins themselves. More advanced
plug-in systems offer pluggable configuration and plug-in discovery
mechanisms.
Usually some basic bootstrap code is run to start a configurator
plug-in, which will then discover the other plug-ins based on its own
strategy. For example,
Eclipse provides an Update Manager configurator plug-in that picks up
plug-ins from the eclipse/plugins folder, as well as from other local
plug-in folders linked from the eclipse/links folder or dynamically
added when users install
new plug-ins to locations of their choice. Because the configurator is
pluggable, anyone can plug in another configurator, which can provision
and configure the
plug-ins from a remote server.</p>


<!--pagebreak-->

<h4> CHALLENGING ISSUES</h4>

<p>
Pressured by time, budgets, or slick marketing claims, you may be
tempted to adopt a pure plug-in architecture without being aware of its
potential pitfalls. Alternatively, you might truly believe in Murphy’s
law and therefore won’t use plug-ins because they’re doomed to fail,
anyway. I tend to follow those who walk the middle road: if something
can fail, then it first should
be understood and then fixed. The rest of the article presents issues
that are likely to pose some challenges when you employ plug-ins, and
that will help you ask questions or provide answers when evaluating a
plug-in architecture.
</p>
<p>
<b>Installing and updating.</b>Many modern products automatically
detect when they are out of date with respect to available service or
product version. Either on start-up, or as a result of an explicit
update action, the products compare
the current installation level against some network-based baseline. The
product then automatically downloads required fixes or upgrades and
applies them, often as part of the product execution. Additionally,
users can, and most often will, install additional plug-ins from
various sources to extend the functionality provided by their current
application.
</p>
<p>For plug-in-based applications, the installation and update
process can be a real nightmare: on the one hand, there are the
traditional installation issues that arise in any application—ability
to roll back changes, migrate existing program data and preferences, or
ensure the installation is not corrupted. On the other hand, because
plug-ins may originate from various providers that are
not related to each other, the resulting configuration has likely never
been tested. This poses a number of interesting challenges that we
address in the context of the other issues discussed in the next
sections.
</p>
<p>
<b>Security.</b>Systems can never be too secure, and you need to pay
particular attention to securing a system based on plug-ins. Since
arbitrary plug-ins can be installed—for example, by downloading them
from the Web—and are allowed unlimited access to the system they plug
into, security in a plug-in environment must be carefully planned. On
top of this, some plug-ins require support for executing custom install
code during installation, so they can have control over some parts of
their installation. To prevent software security accidents or failures,
the plug-in framework must address the issues of downloading from third
parties and controlling a plug-in’s access to other code and data.
Supporting digitally signed plug-ins or secure connections helps, but
it still relies on trusting the download source or the plug-in
provider. Some programming environments, such as Java, offer built-in
runtime security mechanisms that can be used effectively to close some
of the security gaps.
</p>
<p>The cold reality is that, unless you are careful about what you
install, it is almost impossible to be confident that the installed
plug-ins are not ill-intentioned. Of course, a pure plug-in
architecture also means that even a well-intentioned plug-in with
serious bugs can do as much damage as an ill-intentioned one when
installed.
</p>
<p>
<b>Concurrent plug-in version support.</b> Without a doubt, managing
concurrent plug-in versions and dependencies is one of those problems
that can keep architects, developers, and installation folks awake at
night. Most of you have probably
experienced “DLL hell” at some point and will look with suspicion on
something that has the potential of being a “plug-in hell.”
</p>
<p>Any serious plug-in model defines some versioning scheme, but
allowing multiple versions of a plug-in to be concurrently installed
and executed is an issue that must be considered early on in the
design, and it must be properly enforced by the install and update
processes.
</p>
<p>To illustrate the complexity of this area, let’s start by
considering the scenario of an application suite that integrates two
stand-alone plug-in products, each installed in a separate location. It
is possible to have the
same plug-in, at the same version or at different versions, installed
in two locations. The runtime kernel must deal with the two plug-in
instances by either running them both or dropping one. When both
versions are running, and the plug-ins contribute user interface
elements such as menus or preference pages, the result may be a very
confusing interface, with duplicate menu entries or preference
pages. There is more trouble: would the user need to be exposed to this
anomaly? How would you update or uninstall these plug-ins?
</p>
<p>The difficulty of the problem is amplified by the other
important role plug-in versions play here: they are part of plug-in
dependency specifications. Typically, a plug-in requires the
functionality provided by other plug-ins, and very often there are
strict criteria about what versions are required. For example, a
plug-in may require a certain level of an XML parser contributed by
another plug-in, or it may need to contribute an extension to a
particular version of an extension point only. Version dependency can
be in the form of a fixed version number such as 3.0.1, or as a range
of versions—say, 3.0.1 or newer. Properly resolving plug-in
dependencies at runtime is critical to the correct functioning of the
application. Managing plug-in dependency graphs is also critical to
ensure a consistent configuration state after installing or updating
plug-ins, as well
as for properly rolling back changes. The install/update process may
need to abort installation of plug-ins that leads to an unresolved
dependency, or search for and install the missing plug-ins. Either way,
it is possible to end up with multiple versions of the same plug-in, so
we’re back to the problem of managing concurrent versions.</p>


<!--pagebreak-->

<p>
There is no simple, general solution to managing concurrent versions of
plug-ins. Eclipse has adopted a reasonable trade-off convention for
concurrent plug-in versions: only versions of plug-ins that contribute
code libraries but no plug-in extensions (no user interface
contributions, no documentation, and so on) are allowed to coexist in
the same runtime instance. For all the other plug-ins, the latest
version is usually picked up, unless a configuration file precisely
defines what to run. The main advantage of this approach is that it
still allows various levels of the same code to coexist at runtime, but
hidden to the end users, who will get a consistent user interface. The
downside is that this will not cover all user scenarios, and that
plug-ins are not treated uniformly as elsewhere in Eclipse. This
special treatment of plug-ins is not just a runtime/install
issue, but also something that developers and product packagers must
consider.
</p>
<p>
<b>Scalability, up and down.</b> Another challenge of working with
plug-in architectures is scalability. Just as the problems associated
with multiple versions and dependencies can quickly escalate, so too
can the sheer number of interacting plug-ins quickly become a problem.
For example, when Eclipse was first designed, it was thought
that a product, a large one for that matter, would consist of a few
hundred plug-ins. A few releases later, some enterprise-class products
built on Eclipse are known to have passed the thousand plug-in mark, so
the platform goal has
been revisited to support scaling between 5,000 and10,000 plug-ins.
</p>
<p>When designing a plug-in system for scalability, developers
must consider various mechanisms that make start-up faster and have a
smaller memory footprint. A general principle of runtime is that the
end user should not pay a memory or
performance penalty for plug-ins that are installed but not used. A
plug-in can be installed and added to the registry, but the plug-in
will not be activated unless a function provided by the plug-in has
been requested according to the
user’s activity. In general, this requires support for plug-in
declarative functionality. It is often realized in practice via plug-in
manifest files, so no code has to be loaded for obtaining the function
contributed by plug-ins.
Caching of the plug-in registry and the plug-in manifests/declarations
can reduce processing during start-up in subsequent application
launches, improving response
time. What is gained in performance and memory footprint, however, is
lost in code complexity: more code needs to be written to cache the
data and to synchronize the cache with changes in the installation
configuration.
</p>
<p>Scalability problems almost always surface during plug-in
install/update operations. The larger the product, the larger the
download size of patches and upgrades. For product upgrades, the
download time can be improved by simply downloading only the plug-ins
that changed. Another installation scalability problem can arise during
an interactive install/update operation. Quite often plug-in boundaries
are established for development reasons (such as function reuse) and
present the wrong level of granularity in terms of what the user sees
as the unit of function, and therefore as an installation unit.
Considering that enterprise-level applications can scale up to hundreds
and thousands of plug-ins, with complex dependencies, the user can be
overwhelmed by various installation choices. A
possible solution is to introduce a packaging and installation
component that groups a number of plug-ins to offer a higher level of
function. For example,
in Eclipse, Update Manager does not install plug-ins directly; it
processes features. Features are bundles of plug-ins and are considered
deployment units with install/update semantics.
</p>
<p>The other side of scalability is scaling down, so products can
run on devices with limited resources, such as cellphones and PDAs.
This usually means rethinking
the core framework plug-ins to refactor them into smaller plug-ins,
some of them optionally deployable, so that one can run with a minimal
configuration.</p>



<h4> OVERCOMING THE BUMPS</h4>

<p>
General discussion about plug-in architecture and design issues may not
mean much for you or your company’s bottom line unless you’re a
participant or plan to be one—either by creating a plug-in framework or
developing plug-ins for fun and profit, or by using a plug-in-based
application. Employing a plug-in framework is not without bumps, but
they can be overcome with proper preparation. </p>
<p>
While traditional plug-ins have been around for some time, the pure
plug-in models have only recently emerged as robust, enterprise-level
quality application development environments. As many major industry
players are rapidly adopting plug-in technologies for their software
lines, we can expect further research and development into improving
the current architectures. Some of the areas that will receive
increased focus will be: </p>

<p> • Security at all levels, including installation, update, and runtime.</p>

<p> • Performance: speed and low resource usage.</p>

<p> • Improved tools for development, testing, packaging, and deployment of plug-ins.</p>

<p> • Improved installation and updates, especially by merging changes without taking the system down.</p>

<p> • Remote management of various processes (provisioning, configuration, and so on).</p>

<p> • Convergence, compatibility, or interoperability of various plug-in frameworks.</p>

<p> • Wider range of deployment platforms (from desktop PCs and high-end servers to digital mobile phones and embedded devices). </p>

<p> Increasingly, much of this effort will be happening in the open source domain or standards bodies. </p>

<table>
<tbody><tr><td bgcolor="#eeeeee"><span class="small"><strong>DORIAN BIRSAN</strong> has been working at the IBM Toronto Labs for
almost 10 years, leading a range of technical projects on application development
tools and writing a number of patents in the field. He has played an active
role in Eclipse since its inception, leading the user assistance and the update/install
teams. Mathematician at heart, turned computer scientist, and later husband
and father, he holds a B.Math. in computer science and combinatorics and optimization
from the University of Waterloo, as well as an M.Sc. in computer science from
the University of British Columbia, where he was a National Science and Engineering
Research Council of Canada Fellow.
</span></td></tr></tbody>
</table>

<p align="center"><a href="javascript:history.back(1)" onmouseover="status='Back to On Plug-ins and Extensible Architectures';return true;">Back to On Plug-ins and Extensible Architectures</a></p>

<!-- bottom banner ad start-->
<table cellpadding="5" cellspacing="5" width="100%">
<tbody><tr><td align="center">
<a href="http://www.acmqueue.org/phpAdsNew-rc42/adclick.php?bannerid=196&amp;zoneid=64&amp;source=&amp;dest=http%3A%2F%2Fwww.activestate.com%2Fenterprise.plex%3Futm_source%3DACMQueue%26utm_medium%3Dbanner%26utm_campaign%3DEE" target="_blank"><img style="visibility: hidden ! important;" src="file:///C:/Documents%20and%20Settings/Brian%20Sun/Application%20Data/Mozilla/Firefox/Profiles/qc16y5ld.default/maf/maftemp/1113210839291_106/1112921133113_645/index_files/750x100_activestate.gif" alt="" title="" border="0" height="100" width="750"></a><div id="beacon_196" style="position: absolute; left: 0px; top: 0px; visibility: hidden;"><img src="file:///C:/Documents%20and%20Settings/Brian%20Sun/Application%20Data/Mozilla/Firefox/Profiles/qc16y5ld.default/maf/maftemp/1113210839291_106/1112921133113_645/index_files/adlog_003.gif" alt="" style="width: 0px; height: 0px; visibility: hidden ! important;" height="0" width="0"></div></td></tr></tbody>
</table>

<!--bottom banner ad stop--><!--I/PRO Page Tagging--><!-- START Insight XE-->
<script language="JavaScript">
	var if_Site_ID = "ipro";
	var if_sid="1";
	var if_protocol=window.location.protocol;
	var mep1="&Site="+escape("acmqueue.com");
	</script>
<script language="JavaScript" src="file:///C:/Documents%20and%20Settings/Brian%20Sun/Application%20Data/Mozilla/Firefox/Profiles/qc16y5ld.default/maf/maftemp/1113210839291_106/1112921133113_645/index_files/ipro_if.js"></script>

	
	
	
	
	<!-- END Insight XE-->

<img src ="http://www.blogjava.net/briansun/aggbug/3148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-04-11 17:18 <a href="http://www.blogjava.net/briansun/articles/3148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何选择MBA院校[转]</title><link>http://www.blogjava.net/briansun/articles/3028.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Sat, 09 Apr 2005 04:40:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/3028.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/3028.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/3028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/3028.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/3028.html</trackback:ping><description><![CDATA[<table border="0" cellpadding="0" cellspacing="0" width="622">
<tbody><tr>
<td class="big" colspan="2" align="middle"><b>如何选择MBA院校</b></td></tr>
<tr>
<td class="text" colspan="2" align="middle"><br>
</td></tr>
<tr>
<td colspan="2" bgcolor="#999999" height="1"><br>
</td></tr>
<tr>
<td colspan="2" height="28" valign="top">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr align="left">
<td height="18"><a class="blue" href="http://www.cer.net/">http://www.cer.net</a><img src="http://www.blogjava.net/images/cer.net/blank.gif" width="6"><font class="blue">2003-04-07 
11:36</font><img src="http://www.blogjava.net/images/cer.net/blank.gif" width="6"><font color="#0000ff"><a href="http://www.people.com.cn/" target="blank">人民网</a></font></td>
<td class="blue" align="right" height="18">作者：韩冰</td></tr></tbody></table></td></tr>
<tr>
<td class="text" height="350" valign="top" width="617">
<p>&nbsp;&nbsp;&nbsp;
眼下读MBA，到底选洋的还是土的？北大国际MBA招生办主任张黎说，如果申请人希望未来成为“国际人”，经济实力又比较强，首选当然还是美国和欧洲的名
校，像美国《商业周刊》评选的商学院。美国的商学院已经有百年历史，其办学质量、师资、学生的素质和学院的管理都不是国内商学院现在就能比的。但国内商学
院的机会已经来了，从2000年起受经济影响，美国商学院学生的就业情况不好，国际学生就业就更差，连哈佛商学院毕业的国际学生在美都难寻工作。据可靠消
息，目前美国的顶级商学院，像芝加哥大学、沃顿商学院对国际学生的名额和助学金都做了严格限制，目的是减少国际学生，保证本国学生的就业，以保住在《商业
周刊》等排行榜上的地位。这也与今年哈佛商学院的中国毕业生全部回国，芝加哥大学等些一流商学院的一批中国毕业生回国就业互为例证。</p>
<p>&nbsp;&nbsp;&nbsp; 
从投入产出比看，上哈佛共需花费10万美元。二流商学院也要6～7万美元，在美国的中国学生一般都会贷款求学。而国际学生毕业后就业面窄，还受到还贷的压力，导致他们不去生产型企业，只能去跨国公司中的咨询公司和金融公司，这些公司目前提供的职位根本不能满足需求。<br><br>&nbsp;&nbsp;&nbsp; 
如果选择回国创业，就需要对中国文化、风土人情都很了解。中国经济发展如此迅速，在国外2～3年，回国后很难马上适应。所以创业这条路是艰难的路。<br><br>&nbsp;&nbsp;&nbsp;
如果选择国内商学院，常规MBA一般需花费10～12万元，合1.5万美元。职班的人也不用辞职，利用业余时间上课就行，投入就更小。从就业看，国产
MBA虽然在跨国公司的职位竞争上不占优势，但在民营、国企大公司的就业机会就很多。另外，跨国公司人才本土化的过程也推动了国产MBA的就业。<br><br>&nbsp;&nbsp;&nbsp; 
如果选择国内商学院，当然选一流的为好。目前中欧国际工商学院、北大国际MBA、北大光华管理学院、清华经管学院、长江商学院都是公认的一流商学院，各有特点。<br><br>&nbsp;&nbsp;&nbsp; 
作为申请人，可从三方面选择：<br><br>&nbsp;&nbsp;&nbsp; 一是选择什么样的学生群体(是来自外企圈还是来自国企圈)；<br><br>&nbsp;&nbsp;&nbsp; 
二是选择什么样的老师(是来自美国还是来自欧洲)；<br><br>&nbsp;&nbsp;&nbsp; 
三是课程(是否有学习方向，是否有本土案例)。建议申请人报名前先到自己中意的商学院进行实地考察，到课堂试听之后再决定。<br></p></td></tr></tbody>
</table>
<img src ="http://www.blogjava.net/briansun/aggbug/3028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-04-09 12:40 <a href="http://www.blogjava.net/briansun/articles/3028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样获得MBA学位[转]</title><link>http://www.blogjava.net/briansun/articles/3027.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Sat, 09 Apr 2005 04:39:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/3027.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/3027.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/3027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/3027.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/3027.html</trackback:ping><description><![CDATA[<table border="0" cellpadding="0" cellspacing="0" width="622">
<tbody><tr>
<td class="big" colspan="2" align="middle"><b>怎样获得MBA学位</b></td></tr>
<tr>
<td class="text" colspan="2" align="middle"><br>
</td></tr><tr><td colspan="2" bgcolor="#999999" height="1"><br>
</td></tr><tr><td colspan="2" height="28" valign="top"><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr align="left"><td height="18"><a class="blue" href="http://www.cer.net/">http://www.cer.net</a><img src="http://www.blogjava.net/images/cer.net/blank.gif" width="6"><font class="blue">2003-01-03 
14:06</font><img src="http://www.blogjava.net/images/cer.net/blank.gif" width="6"><font color="#0000ff"><a href="http://www.xinhuanet.com/" target="blank">新华网</a></font></td>
<td class="blue" align="right" height="18">作者：姜帆 
王攀</td></tr></tbody></table></td></tr>
<tr>
<td class="text" height="350" valign="top" width="617">
<p>　　要读MBA，对不同需求的考生来说，选择也应是不一样的。目前，在国内读MBA，有5种可供选择的模式。</p>
<p>　　第一种：参加全国联考，达到教育部和报考学校的分数线后入学。毕业颁发教育部承认的硕士学位和学历证书。这种考试要考高等数学和线性代数，考生
比较辛苦，但学费相对低廉，对工作经验的要求不是很严格。这种类型一般还分为春季班(脱产)、秋季班(在职)和经贸班(有学历无学位)等几种。</p>
<p>　　第二种：各个学校组织的培训性质的工商管理教育，入学不需要经过全国联考，学费较高，但形式多样。包括EMBA(高级管理人员班)、EDP(高
层经理培训课程)、MBA课程研修班、短期培训班、论坛(以报告会形式展开)等。后4种都没有考试，不需推荐，没有学位，对入学者工作经验的要求不严。</p>
<p>　　第三种：中外合作办学，毕业后发教育部认可的国外商学院的学位和文凭。北大、清华、复旦、南京大学、中山大学等都有此种形式，其中最有名的是北
大中国经济研究中心和美国26所商学院合办的项目。特点是英语和工作经验要求较高，不考数学，可脱产或在职学习。理论上说，学位在中美两地都有效，但学费
之高令人咋舌，而且还是美元。</p>
<p>　　第四种：来自世界各地的大学来华办的从学士(BBA)到博士(DBA)的各种工商管理的教育课程。有名校的，也有一般的学校，但无一例外，国家都不承认其学历学位。</p>
<p>　　第五种：中欧工商管理学院。该校的办学质量有很好的口碑，毕业生很受企业青睐，遗憾的是学费非常昂贵，国家还不承认学位。有人戏称：“中欧是那些英语足够好，钱足够多，但又去不了哈佛的人的最好选择。”</p>
<p>　　参加全国联考，是最为普遍的一种模式。根据教育部的规定，MBA联考报考人员必须是：研究生毕业后有2年以上工作经验者；大学本科毕业后有3年
以上工作经验者；大专毕业后有5年以上工作经验者；年龄一般不超过40周岁。各招生院校可在教育部规定的报考条件基础上规定本校报考条件。MBA联考的科
目为：英语、数学、管理、语文与逻辑、政治。前4科为统一命题，每年上半年教育部MBA联考指导委员会公布次年考试大纲及核定教材，政治理论课由各招生院
校单独命题、批卷。联考各科的内容每年都有所变化，总趋势是向实践性，综合性，灵活性的方向倾斜。死记硬背的概念、定义类的内容会逐渐减少，而着重点考察
考生的理解能力、综合分析解决问题能力。</p>
<p>　　联考分数达到报考院校的分数线后，再通过录取评审委员会对申请材料的评价以及差额面试，考生才能入学。</p>
<p>　　一些专业人士认为，目前的联考制度有待改进。在联考中考了高分的学生未必就有管理能力，而相当一部分有管理经验和管理潜力的学生因为在分数线以
下就只能和MBA擦肩而过。南京大学MBA中心的桑秉南主任说：“既要兼顾社会公平，又要选拔具备管理才能这种不可量化的资质的人才，MBA联考就成了两
难选择下不理想但不得不为的解决方法。”<br></p></td></tr></tbody>
</table>
<img src ="http://www.blogjava.net/briansun/aggbug/3027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-04-09 12:39 <a href="http://www.blogjava.net/briansun/articles/3027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[大师作品]提问的智慧[转]</title><link>http://www.blogjava.net/briansun/articles/2995.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Fri, 08 Apr 2005 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/2995.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/2995.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/2995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/2995.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/2995.html</trackback:ping><description><![CDATA[
<div class="article" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h1>提问的智慧</h1>
<br>
<span class="firstname">作者：</span></div>
<div>
<div class="author">
<h3 class="author"><span class="firstname">Eric</span> <span class="othername">Steven</span> <span class="surname">Raymond</span></h3>
<div class="affiliation"><span class="orgname"><a href="http://www.catb.org/%7Eesr/" target="_top"> Thyrsus Enterprises</a><br>
</span>
<div class="address">
<p><br>
&nbsp;&nbsp;&nbsp;&nbsp;<tt class="email">&lt;<a href="mailto:esr@thyrsus.com">esr@thyrsus.com</a>&gt;</tt><br>
&nbsp;&nbsp;&nbsp;&nbsp;</p>
</div>
</div>
</div>
</div>
<div>
<div class="author">
<h3 class="author"><span class="firstname">Rick</span> <span class="surname">Moen</span></h3>
<div class="affiliation">
<div class="address">
<p><br>
&nbsp;&nbsp;&nbsp;&nbsp;<tt class="email">&lt;<a href="mailto:rick@linuxmafia.com">rick@linuxmafia.com</a>&gt;</tt><br>
&nbsp;&nbsp;&nbsp;&nbsp;</p>
</div>
</div>
</div>
</div>
<div>
<p class="copyright">版权 © 2001 Eric S. Raymond</p>
</div>
<div>
<div class="revhistory">
<table summary="Revision history" border="1" width="100%">
  <tbody>
    <tr>
      <th colspan="3" align="left" valign="top"><b>修订历史</b></th>
    </tr>
    <tr>
      <td align="left">修订版 3.1</td>
      <td align="left">2004年10月28日<br>
      </td>
      <td align="left">esr</td>
    </tr>
    <tr>
      <td colspan="3" align="left">文档‘Google
是你的朋友！’ </td>
    </tr>
    <tr>
      <td align="left">修订版 3.0</td>
      <td align="left">2004年2月2日<br>
      </td>
      <td align="left">esr</td>
    </tr>
    <tr>
      <td colspan="3" align="left">主要增加网页论坛应有的礼节内容 </td>
    </tr>
  </tbody>
</table>
<span style="font-weight: bold;">原文</span>：<a href="http://www.catb.org/%7Eesr/faqs/smart-questions.html">How
To Ask
Questions The Smart Way</a><br>
翻译：王刚 &lt;<a href="mailto:yafrk@yahoo.com">yafrk@yahoo.com</a>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br>
时间：2004年11月2日</div>
</div>
</div>
<hr></div>
<div class="toc">
<p><b>内容<br>
</b></p>
<dl><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#translations">译文</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#disclaimer">弃权申明</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#intro">引言</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#before">提问前</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#asking">提问时</a></span></dt><dd>
    <dl><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#forum">仔细挑选论坛</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#usefora">面向新手的网页论坛和IRC通常响应最快</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#uselists">第二步，使用项目邮件列表</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#bespecific">使用明确而有意义的主题</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#easyreply">使之更易回复</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#writewell">使用清晰、语法与拼写正确的语句</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#formats">使用易懂的格式发送问题</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#beprecise">描述问题应准确且有内容</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#volume">多不等于准确</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#id3001405">别动辄声称找到臭虫</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#id3001578">低声下气不能代替自己应做之事</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#symptoms">描述问题症状而不是猜测</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#chronology">按时间先后罗列问题症状</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#goal">描述目的而不是步骤</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#noprivate">别要求私下回复</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#explicit">问题应明晰</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#homework">别张贴家庭作业</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#prune">删除无意义的问题</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#urgent">不要刻意标明问题紧急</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#courtesy">礼貌总是无害的</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#followup">问题解决后追加一条简要说明</a></span></dt></dl>
  </dd><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#answers">如何解读回答</a></span></dt><dd>
    <dl><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#rtfm">RTFM与STFW：如何知道你已完全搞砸 </a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#lesser">如果还不明白.</a></span></dt><dt><span class="sect2"><a href="http://www.fengnet.com/smart-questions.html#keepcool">对待无礼</a></span></dt></dl>
  </dd><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#not_losing">别象个失败者那样反应 </a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#classic">提问禁忌</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#examples">好问题与坏问题</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#id3002966">如果没有回复 </a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#id3003018">如何更好地回答问题</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#id3003109">相关资源</a></span></dt><dt><span class="sect1"><a href="http://www.fengnet.com/smart-questions.html#id3003139">鸣谢<br>
    </a></span></dt></dl>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="translations"></a>译文</h2>
</div>
</div>
</div>
<p>译文: <a href="http://stare.cz/otazky/index.html" target="_top">捷克语</a>
<a href="http://www.usenet.dk/netikette/udvdebatteknik.html" target="_top">丹麦语</a>
<a href="http://linux.ee/%7Ekala/smart-questions.html" target="_top">爱沙尼
亚语</a> <a href="http://www.gnurou.org/documents/smart-questions-fr.html" target="_top">法语</a> <a href="http://www.lugbz.org/documents/smart-questions_de.html" target="_top">德语</a> <a href="http://www.penguin.org.il/essays/smart-questions-he.html" target="_top">希伯来语</a> <a href="http://www.no.info.hu/%7Ekryss/gnu/esr/smart-questions_hu.html" target="_top">匈牙利语</a> <a href="http://members.xoom.virgilio.it/army1987/domande.html" target="_top">意大利语</a> <a href="http://www.ranvis.com/articles/smart-questions.ja.html" target="_top">日语</a> <a href="http://rtfm.killfile.pl/" target="_top">波
兰语</a> <a href="http://ln.com.ua/%7Eopenxs/articles/smart-questions-ru.html" target="_top">俄语</a> <a href="http://www.sindominio.net/ayuda/preguntas-inteligentes.html" target="_top">西班牙语</a> <a href="http://www.se.linux.org/dokumentation/howto/smartafragor" target="_top">瑞典语</a>
<a href="http://belgeler.org/howto/smart-questions.html" target="_top">土
耳其语</a>.
如果你想复制、镜像、翻译或引用本文，请参阅我的 <a href="http://www.catb.org/%7Eesr/copying.html" target="_top">复制须知</a>.
<br>
</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="disclaimer"></a>弃权申明</h2>
</div>
</div>
</div>
<p><span class="emphasis">许多项目的网站在
如何取得帮助的部分链接了本文，这没有关系，也是我们想要的。但如果你是该项目生成此链接的网管，请在链接附近显著位置注明“<span style="font-style: italic;">我们不是此项目的服务部！</span>”</span></p>
<p>我们已经遭受没有此说明带来的痛苦，不断受到一些白痴的骚扰。他们认为既然我们发表了此文，那么我们就有责任解决世上所有技术问题！</p>
<p>如果你因为需要帮助阅读了本文，然后带着可以直接从作者那取得帮助的印象离开，你就不幸成了那些白痴之一。不要向我们提问，我们不会理睬
的。
我们在这只是给你说明如何从那些真正懂得你软硬件问题的人那里取得帮助的方法，99%的时间我们不会是那些人。除非你确信此文作者是你遇到问题方面的专
家，
请不要打扰，这样大家都更开心一点。</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="intro"></a>引言</h2>
</div>
</div>
</div>
<p>在 <a href="http://www.catb.org/%7Eesr/faqs/hacker-howto.html" target="_top">黑客</a>
的世界，你所提技术问题的回答很大程度上取决于你提问的方式与解决此问题的难度，本文将教你如何提问才更有可能得到满意的答复。</p>
<p>开源程序的使用已经很广，你通常可以从其它更有经验的用户而不是黑客那里得到回答。这是好事，他们一般对新手常有的毛病更容忍一点。然尔，使用我们
介
绍的方法象对待黑客那样对待这些有经验的用户，通常能最有效地得到问题的解答。</p>
<p>第一件需要明白的事是黑客喜欢难题和激发思考的好问题。假如不是这样，我们也不会写本文了。如果你能提出一个有趣的问题让我们咀嚼玩味，我们会感激
你。
好的
问题是种激励与礼物，帮助我们发展认知，揭示没有注意或想过的问题。在黑客中，“好问题！”是非常真挚的赞许。</p>
<p>除此而外，黑客有遇到简单问题就表现出敌视或傲慢的名声，有时候我们看起来还对新手和愚蠢的家伙有条件反
射式的无礼，但并不真正是这样。</p>
<p>我们只是毫无歉意地敌视那些提问前
不愿思考、不做自己该做之事的人。这种人就象时间无底洞──他们只知道获取，不愿意付出，他们浪费了时间，这些时间本可用于其它更值得回答的人和
更有趣
的问题。我们将这种人叫做“失败者 (loser)” (由于历史原因，我们有时将“loser”拼为“lusers")</p>
<p>我们注意到许多人只想用我们写的软件，他们对学习技术细节没有兴趣。对大多数人而言，计算机只是种工具，是种达到目的的手段。他们要生活并且有更要
紧的事要做，我们承认这点，也从不指望每个人都对这些让我们着迷的技术问题感兴趣。不过，我们回答问题的风格是为了适应那些真正对此有兴趣并愿意主动参与
问题解决的
人，这一点不会变，也不该变。如果这都变了，我们就会在自己能做得最好的事情上不再那么犀利。<br>
</p>
<p>我们(多数)是自愿者，从自己繁忙的生活中抽时间来回答问题，有时会力不从心。因此，我们会无情地滤除问题，特别是那些看起来象是失败者的，以
便更有效地把回答问题的时间留给那些“胜利者”</p>
<p>如果你认为这种态度
令人憎恶、以施惠者自居或傲慢自大，请检查你的假设，我们并未要求你屈服──事实上，假如你做了该做的努力使之成为可能，我们中的
大多数人非常乐意平等地与你交流并欢迎你接纳我们的文化。试图去帮助那些不愿自救的人对我们简直没有效率，不懂没有关系，但愚蠢地行事不行。</p>
<p>所以，你不必在技术上很在行才能吸引我们的注意，但你<span style="font-weight: bold; font-style: italic;">必须</span>表现出能引导你在行的姿态──机
敏、思考、善于观察、乐于主动参与问题的解决。如果你
做不到这些使你与众不同的事情，我们建议你付钱跟别人签商业服务合同，而不是要求黑客无偿帮助。</p>
<p>如果你决定向我们求助，你不会想成为一名失败者，你也不想被看成一个失败者。得到快速有效回复的最好方法是使提问者看起来象个聪明、自
信的人，并且暗示只是碰巧在某一特别问题上需要帮助。</p>
<p>(欢迎对本文指正，可以将建议发至 <a href="mailto:esr@thyrsus.com" target="_top">esr@thyrsus.com</a>
。
请注意，本文不想成为一般性的 <a href="http://www.dtcc.edu/cs/rfc1855.html" target="_top">网络礼仪</a> 指南，我一般会拒绝那些与引出技术论坛中有用的回复不特别相关的建议)</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="before"></a>提问前</h2>
</div>
</div>
</div>
<p>在通过电子邮件、新闻组或网页论坛提技术问题之前，做以下事情：</p>
<div class="procedure">
<ol type="1"><li>
    <p>尝试搜索互联网以找到答案</p>
  </li><li>
    <p>尝试阅读手册以找到答案</p>
  </li><li>
    <p>尝试阅读FAQ(常见问题)文档以找到答案</p>
  </li><li>
    <p>尝试自己检查或试验以
找到答案</p>
  </li><li>
    <p>尝试请教懂行的朋友以找到答案</p>
  </li><li>
    <p>如果你是程序员，尝试阅读源代码以找到答案</p>
  </li></ol>
</div>
<p>提问时，请先表述你已经做了上述事情，这将有助于建立你不是寄生虫与浪费别人时间的印象。最好再表述你从中<span style="font-weight: bold; font-style: italic;">学到的东西</span>，我们喜欢
回答那些表现出能从答案中学习的人。</p>
<p>使用某些策略，比如用Google搜索你遇到的错误提示(既搜索网页也查查讨论组)，可能就直接找到了解决问题的文档或邮件列表线索。即使没有结
果，在电子邮件或新闻组张贴问题时提一句“我在Google中查过下列句子但没有找到什么有用的东西”也是件好事。</p>
<p>准备你的问题，彻底地思考。轻率的提问只能得到轻率的回答，或者压根没有。在提问时，越是表现出做过思考并在努力解
决问题，你越有可能得到
实际帮助。</p>
<p>注意别提错问题。如果提问基于错误的假设，某黑客多半会一边想”愚蠢的问题……“，一边用按照问题字面的无用答案回复你，并且希望这种只
是得到
字
面回答而不是真正所需的经历给你一个教训。</p>
<p>永远不要假设你<span style="font-weight: bold; font-style: italic;">有资格</span>得
到解答。你没有这种资格，毕竟你没有为此服务付费。如果你能够提出有内容、有趣和激励思考的问题──那种毫无疑问能够向社
区贡献经验而不仅仅是消极地要求从别人那获取知识的问题，你将“挣到”答案。</p>
<p>另一方面，表明你能够也乐意参与问题的解决是个很好的开端。“有没有
人能指个方向？”、“我这还漏点什么？”、“我应该查哪些网站？”通常要比
“请给出我可以用的完整步骤”更容易得到回复，因为你表明了只要有人能指个方向你就很乐意完成剩下的过程。</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="asking"></a>提问时</h2>
</div>
</div>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="forum"></a>仔细挑选论坛</h3>
</div>
</div>
</div>
<p>要对在哪提问留心，如果你做了下
述事情，多半会被一笔勾销或被看成“失败者”：</p>
<div class="itemizedlist">
<ul type="disc"><li>
    <p>张贴与论坛主题完全无关的问题</p>
  </li><li>
    <p>在面向高级技术问题的论坛上提非常
初浅的问题，或者反之。</p>
  </li><li>
    <p>在太多不同的新闻组同时交叉张贴</p>
  </li><li>
    <p>给既非熟人也没有义务解决你问题的个人张贴你私人的电子邮件</p>
  </li></ul>
</div>
<p>为保护通信的渠道不被无
关的东西淹没，黑客会除掉那些没有找对地方的问题，你不会想有这种经历的。</p>
<p>所以第一步是找对论坛，Google与其它搜索引擎还是你的朋友，可以用它们搜索与你遇到困难的软硬件问题最相关的项目的网站。那
里通常都有项目的FAQ列表、邮件列表及其文档的链接。如果你的努力(包括阅读FAQ)都没有结果，这些邮件列表就是最后能取得帮助
的地方。项目的网站也许还有报告臭虫的流程或链接，如果是这样，去看看。</p>
<p>向陌生的人或论坛发送邮件极有可能是在冒险。譬如，不要假设一个富含信息的网页的编写者想充当你的免费顾问，不要对你
的问题是否会受到欢迎做乐
观的
估计──如果你
不确定，向别处发或者根本别发。</p>
<p>在选择网页论坛、新闻组或邮件列表时，不要太相信名字，先看看FAQ或者许可书以明确你的问题
是否与其主题相关。张贴前先翻翻已有的帖
子可
以
帮助你感受一下那里行事的方式。事实上，张贴之前在新闻组或邮件列表中搜索与你问题相关的关键词是个很好的主意，也许就找到答案了。即使没有，也能帮助你
整理
出
更好的问题。</p>
<p>别象机关枪似的一次性“扫射”所有的帮助通
道，那就象大嚷大叫并使人不快。一个一个地来。<br>
</p>
<p>弄清楚你的主题！最典型的错误之一是在某种致立于跨Unix和Windows平台的语言、库或工具的论坛中提关于操作系统程序接口的问题。如果你不
明白为什么这是大错，最好在搞清楚概念前什么也别问。</p>
<p>一般来说，在仔细挑选的公共论坛中提问比在私有论坛中提同样的问题更容易得到有用的回复。有许多理由支持这一点，一是看潜在的回复者有多少，二是看
论
坛的参与者有多少，黑客更愿回答能启发多数人的问题。<br>
</p>
<p>可以理解，老练的黑客和一些流行软件的作者正在收到超出他们承受能力的不当消息。就象那根多出来就可以压垮骆驼背的稻草一样，你的
加入也可能会使情况走向极端──已经好几次了，一些流行软件的作者退出了对其软件的支持，因为伴随而来的涌向其私人邮箱的大量无用消息变得无法
忍受。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3><a name="usefora"></a>面向新手的网页论坛和IRC通常响应最快</h3>
</div>
</div>
</div>
<p>本地的用户组织或者你所用的Linux发行版也许正在宣传新手取得帮助的网页论坛或IRC(互联网中继聊天)
(在非英语国家，新手论坛很可能还是邮件列表)，这些
地
方
是开始提问的好去处，尤其是当你觉得遇到的也许只是相对简单或者一般的问题时。经过宣传的IRC通道是个公开邀请提问的地方，通常可以得到实时的回复。</p>
<p>事实上，如果出问题的程序来自某发行版(这很常见)，在程序的项目论坛或列表提问前最好先在发行版的论坛或列表中问问，(否则)项目的黑客可能仅仅
回复“用<span style="font-weight: bold; font-style: italic;">我们</span><span style="font-weight: bold; font-style: italic;">的</span>代码”</p>
<p>在任何网页论坛张贴之前，先看看是否有搜索功能。如果有，就试试用问题的几个关键词搜索一下，也许就有帮助。如果在此之前你已做过全面的网页搜索
(你应该这样做)，还是再搜索一下论坛，搜索引擎最近也许还没有索引此论坛的全部内容。</p>
<p>通过网页论坛或IRC频道提供项目的用户支持有增长的趋势，电子邮件交流则更多地为项目开发保留。先在网页论坛或IRC中寻求与项目相关的帮
助。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="uselists"></a>第二步，使用项目邮件列表</h3>
</div>
</div>
</div>
<p>当某项目存在开发者邮件列表时，即使你确信谁能最好地回答问题，也要向列表而不是其中的个体提问。检查项目的文档和主页，找到项目的邮件列表并使
用它。采用这种策略有几个好理由：</p>
<div class="itemizedlist">
<ul type="disc"><li>
    <p>任何向单个开发者提的足够好的问题也将对整个项目组有益。相反，如果你认为自己的问题对整个项目组来说太愚蠢，这也不能成为打扰
单个开发者的理由。</p>
  </li><li>
    <p>向列表提问可以平衡开发者的负担，单个开发者(特别是项目领导)也许太忙以至于无法回答你的问题。</p>
  </li><li>
    <p>大多数邮件列表有历史文档并被搜索引擎索引，其它人可以通过网页搜索找到你的问题和答案而不用再次在邮件列表中发问。</p>
  </li><li>
    <p>如果某些问题经常被问到，开发者可以利用此信息改进文档或软件本身以使其更清楚。如果只是私下提问，就没有人能看到最常见问题的完整
场景。</p>
  </li></ul>
</div>
<p>如果一个项目既有“用户”也有“开发者”(或“黑客”)邮件列表或网页论坛，而你又不摆弄那些代码，向“用户”列表或论坛提问。不要假设自己在开发
者列表中会受欢
迎，那些人多半会遭受你的噪音干扰。</p>
<p>然尔，如果你<span style="font-style: italic;">确信</span>你的问题不一般，而且在“用户”
列表或论坛中几天都没有回复，可以试试“开发者”列表或论坛。建议你在张贴前最好先暗暗地观察几天
以了解那的行事方式(事实上这是参与任何私有或半私有列表的好主意)</p>
<p>如果你找不到一个项目的邮件列表，而只能查到项目维护者的地址，只管向其发信。即便在这种情况下，也别假设(项目)邮件列表不存在。在你的电子邮
件中陈述你已
经试过但没有找到合适的邮件列表，也提及你不反对将自己的邮件转发给他人(许多人认为，即使没什么秘密，私人电子邮件也不应该被公开。通过允许将你的电子
邮件
转
发他人给
了相应人员处置你邮件的选择)。<br>
</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="bespecific"></a>使用明确而有意义的主题</h3>
</div>
</div>
</div>
<p>在邮件列表、新闻组或网页论坛中，主题是你在五十个或更少的字符以内吸引有资格的专家注意的黄金机会，不要用诸如“请帮我”(更别提大写的“请帮
我！！！！”，这种主题的消息会被条件反射式地删掉)之类的唠叨浪费机会。不要用你痛苦的深度来打动我们，相反，要在这点空间中使用超级简明扼要的问题
描述。</p>
<p>使用主题的好惯例是“对象──偏差”(式的描述)，许多技术支持组织就是这样做的。在“对象”部分指明是哪一个或哪一组东西有问题，在“偏差”部分
则描述与期望
行
为不一致的地方。</p>
<div class="variablelist">
<dl><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="strong"><span class="term"><span class="strong">愚蠢：</span></span></span></span><dt><span class="term"><span class="strong"></span> </span><br>
  </dt><dd>
    <p>救命啊！我的笔记本视频工作不正常！</p>
  </dd><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="strong"><span class="term"><span class="strong">明智：</span></span></span></span><dt><span class="term"><span class="strong"></span></span><br>
  </dt><dd>
    <p>XFree86 4.1扭曲鼠标光标，某显卡MV1005型号的芯片组</p>
  </dd><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="strong"><span class="term"><span class="strong">更明智：</span></span></span></span><dt><span class="term"><span class="strong"></span></span><br>
  </dt><dd>
    <p>使用某显卡MV1005型号芯片组的XFree86 4.1的鼠标光标被扭曲</p>
  </dd></dl>
</div>
<p>编写“对象──偏差”式描述的过程有助于你更具体地组织你的问题。是什么被影响了？仅仅是鼠标光标或者还有其它图形？只在XFree86中出现？或
只是在其4.1版中？是针对某显卡？或者只是其MV1005型号的芯片组？一个黑客只需描一眼就能够立即明白什么是你遇到的问题，什么是你自己的问题。</p>
<p>更一般地，想象一下在只显示主题的文档索引中查找。让你的主题更好地反映问题，可以使下一个搜索类似问题的人能够在文档中直接找到答案的线索而不用
再次张贴提问。</p>
<p>如果你想在回复中提问，确保改变主题以表明你是在问一个问题，一个主题象“re: 测试”或“re: 新臭虫”的消息不太可能引起足够的注意。同
时，将回复中与新主题不甚相关的引用内容尽量删除</p>
<p>对于列表消息，不要直接点击回复(按钮)来开始一个新的线索，这将限制你的观众。有些邮件阅读程序，比如mutt，允许用户按线索排序并通过折叠线
索来隐藏消息，
这样做的人永远看不到你发的消息。</p>
<p>仅仅改变主题还不够。mutt和其它邮件阅读程序还要检查主题以外的其它邮件头信息，以便为其指定线索，所以宁可发一
个全
新的邮件。</p>
<p>在网页论坛，因为消息与特定的线索紧密结合并且通常在线索之外不可见，好的提问方式略有不同，通过回复提问并不要紧(一些论坛甚至不允许在
回复中出现分离的主题，而且这样做了基本上没有人会去看)。不过通过回复提问本身就是令人怀疑的做法，因为它们只会被正在查看该
线索的人读到。所以，除非你只想在该线索当前活跃的人群中提问，还是另起炉灶比较好。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="easyreply"></a>使之更易回复</h3>
</div>
</div>
</div>
<p>以“请向……回复”来结束问题多半会使你得不到回答。如果你觉得花几秒钟在邮件客户端设置一下回复地址都麻烦，我们也觉得花几秒钟
考虑你的问题更麻烦。如果你的邮件客户端程序不支持这样做，换个好点的。如果是操作系统不支持所有这种邮件客户端程序，也换个好点的。</p>
<p>在网页论坛，要求通过电子邮件回复是完全无礼的，除非你确信回复的信息也许是机密的(而且有人会为了某种未知的原因只让你而不是整个论坛知道答
案)。如果
你只是想
在有人回复线索时得到电子邮件提醒，可以要求论坛发送。几乎所有论坛都提供诸如“留意本线索”、“有回复发送邮件”的功能。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="writewell"></a>使用清晰、语法与拼写正确的语句</h3>
</div>
</div>
</div>
<p>经验告诉我们，粗心与草率的作者通常也粗心与草率地思考和编程(我敢打赌)。为这些粗心与草率的思考者回答问题没有什么好处，我们宁可将
时间花在其它地方。</p>
<p>
清楚、完整地表达你的问题非常重要。如果你觉得这样做麻烦，我们也觉得注意(你的问题)麻烦。花点额外的精力斟酌一下字句，用不着太僵硬与正式──事实
上，黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它必须很<span style="font-weight: bold; font-style: italic;">准确</span>，而且有迹象表明你是在思考和关
注问题。</p>
<p>正确地拼写、使用标点和大小写，不要将“its”混淆为“it's”，“loose”搞成“lose”或者将“discrete”弄成
“discreet”。<span style="font-weight: bold;">不要全部用大写</span>，这会被看成无礼的大声嚷嚷
(全部小写也好不到哪去，因为不易阅读。Alan
Cox[注：著名黑客，Linux内核的重要参与者]也许可以这样做，但你不行 )。</p>
<p>一般而言，如果你写得象个半文盲似的傻子，多半得不到理睬。如果象个小孩似地乱写乱画那绝对是在找死，可以肯定没人会理你(或者最多
是给你一大堆指责与挖苦)。</p>
<p>如果在非母语论坛中提问，你的拼写与语法错误会得到有限的宽容，但懒惰完全不会被容忍(是的，我们通常看得出其中的差别)。同时，除非你知道回复者
使用
的语言，请使用
英语书写。繁忙的黑客一般会直接删除用他们看不懂语言写的消息。在互联网上英语是工作语言，用英语书写可以将你的问题不被
阅读就被直接删除的可能降到最低。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="formats"></a>使用易懂的格式发送问题</h3>
</div>
</div>
</div>
<p>如果你人为地将问题搞得难以阅读，它多半会被忽略，人们更愿读易懂的问题，所以：</p>
<div class="itemizedlist">
<ul type="disc"><li>
    <p>使用文本而不是HTML(超文本标注语言) ( <a href="http://expita.com/nomime.html" target="_top">关闭HTML</a> 并不难) </p>
  </li><li>
    <p> 使用MIME(多用途互联网邮件扩展)附件通常没有问题，前提是真正有内容(譬如附带的源文件或补丁)，而不仅仅是邮件客户端程序
生
成的模板(譬如只是消息内容的拷贝)。</p>
  </li><li>
    <p>不要发送整段只是单行句子但多次折回的邮件(这使得回复部分内容非常困难)。设想你的读者是在80个字符宽的文本终端阅读邮件，
设置你的行折回点小于80列。</p>
  </li><li>
    <p>但是，也<span style="font-weight: bold; font-style: italic;">不要</span>用
任何固定列折回数据(譬如直接传送的日
志文件或会话记录)。数据应该原样包含，使回复者确信他们看到的与你看到的东西一样。</p>
  </li><li>
    <p>在英语论坛中，不要使用'Quoted-Printable'
MIME编码发送消息。这种编码对于张贴非ASCII语言可能是必须的，但很多邮件代理程序并不支持。当它们分断时，那些文本中四处散布
的
“=20”符号既难看也分散注意力。 </p>
  </li><li>
    <p><span style="font-weight: bold; font-style: italic;">永远不要</span>指
望黑客们阅读使用封闭的专用格式编写的文档，诸如微软公司的Word或Excel文件等，大多数黑客对此的反应就象有人将还在冒热气的猪
粪倒在你门口时你的反应一样。即使他们能够处理，他们也很厌恶这么做。</p>
  </li><li>
    <p>如果你从使用视窗的电脑发送电子邮件，关闭微软愚蠢的“聪明引用”功能，以免在你的邮件中到处散布垃圾字符。 </p>
  </li><li>
    <p>在网页论坛，勿滥用“表情符号”和“html”功能(当它们提供时)。一两个表情符号通常没有问题，但花哨的彩色文本倾向于使人认为
你是个无能之辈。过滥地使用表情符号、色彩和字体会使你看来象个傻笑的小姑娘。这通常不是个好主意，除非你只是对性而不是有用的回复更有兴趣。</p>
  </li></ul>
</div>
<p>如果你使用图形用户界面的邮件客户端程序(如网景公司的Messenger、微软公司的Outlook或者其它类似的)，注意它们的缺省配置不一
定满足这些要求。大多数这类程序有基于菜单的“查看源码”命令，用它来检查发送文件夹中的消息，以确保发送的是没有多余杂质的纯文本文件。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="beprecise"></a>描述问题应准确且有内容</h3>
</div>
</div>
</div>
<div class="itemizedlist">
<ul type="disc"><li>
    <p>仔细、清楚地描述问题的症状 </p>
  </li><li>
    <p>描述问题发生的环境(主机，操作系统，应用程序，任何相关的)，提供销售商的发行版和版本号(如：“Fedora Core
2”、“Slackware 9.1”等) </p>
  </li><li>
    <p>描述提问前做过的研究及其理解。 </p>
  </li><li>
    <p>描述提问前为确定问题而采取的诊断步骤。 </p>
  </li><li>
    <p>描述最近对计算机或软件配置的任何相关改变。 </p>
  </li></ul>
</div>
<p>尽最大努力预测黑客会提到的问题，并提前备好答案。</p>
<p>Simon Tatham写过一篇叫 <a href="http://www.chiark.greenend.org.uk/%7Esgtatham/bugs.html" target="_top">如何有效报告臭虫</a> 的文章，我强烈推荐各位阅读。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="volume"></a>多不等于准确</h3>
</div>
</div>
</div>
<p>你应该(写得)准确且有内容，简单地将一大堆代码或数据“倾倒”在求助消息中达不到目的。如果你有一个很大且复杂的测试样例让程序崩溃，尝
试将其裁剪得越小越好。</p>
<p>至少有三个理由支持这点。第一，让别人看到你在努力简化问题使你更有可能得到回复。第二，简化问题使你更有可能得到<span style="font-style: italic; font-weight: bold;">有用的</span>回复。第三，在提纯臭虫
报告的过程中，你可能自己就找到了解决问题的方法或权宜之计。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="id3001405"></a>别动辄声称找到臭虫</h3>
</div>
</div>
</div>
<p>当你在一个软件中遇到问题，除非你<span style="font-weight: bold; font-style: italic;">非
常、非常</span>的有根据，不要动辄声称找到了臭虫。提示：除非你能提供解决问题的源代码补丁，或者对前一版本的回归测
试
表现出不正确的行为，否则你都多半不够完全确信。对于网页和文档也如此，如果你(声称)发现了文档的“臭虫”，你应该能提供相应位置的替代文本。</p>
<p>记住，还有许多其它用户未经历你遇到的问题，否则你在阅读文档或网页搜索时就应该发现了(你在报怨前已经做了这些，<a href="http://www.fengnet.com/smart-questions.html#before" title="Before You Ask">是吧</a>？)。这也意味着很有可能是你弄错了而不是软件本身有问
题。</p>
<p>编写软件的人通常非常辛苦地使它尽可能完美。如果你声称找到了臭虫，也就暗示他们做错了什么，而这几乎总会使人不快──即使你是对的，
在主题中嚷嚷“臭虫”也是特别不老练的。</p>
<p>提问时，即使你私下非常确信已经发现一个真正的臭虫，最好写得象是<span style="font-weight: bold; font-style: italic;">你</span>做
错了什么。如果真的有臭虫，你会在回复中看到这点。这么做的话，如果真有虫子，维护者就会向你道歉，这总比你弄
砸了然后欠别人一个道歉要强。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="id3001578"></a>低声下气不能代替自己应做之事</h3>
</div>
</div>
</div>
<p>有些人明白他们不应该粗鲁或傲慢地行事并要求得到答复，但他们退到相反的低声下气的极端，“我知道我只是个什么也不是、什么也不懂的失败者，
但……”。这既使人困扰也没有帮助，当伴随着对实际问题含糊的描述时还特别令人反感。</p>
<p>别用低级灵长类动物的策略浪费大家的时间，相反，尽量清楚地表述背景事实和你的问题，这比低声下气更好地摆正了你的位置。</p>
<p>有时，网页论坛设有单独的初学者提问区域，如果你真的认为遇到了初浅的问题，到那去就是了，但一样别低声下气。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="symptoms"></a>描述问题症状而不是猜测</h3>
</div>
</div>
</div>
<p>告诉黑客你认为是什么导致了问题是没有用的(如果你的诊断理论是了不起的东西，你还会向他人咨询求助吗？)。所以，确保只是告诉他们问题的原始
症状，而不是你的解释和理论，让他们来解释和诊断。如果你认为陈述你的猜测很重要，清楚地说明这只是你的猜测并描述为什么它们不起作用。</p>
<div class="variablelist">
<dl><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="strong"><span class="term"><span class="strong">愚蠢：</span></span></span></span><dt><span class="term"><span class="strong"></span> </span><br>
  </dt><dd>
    <p>我在编译内核时接连遇到SIG11错误，怀疑主板上的某根电路丝断了，找到它们的最好办法是什么？</p>
  </dd><dt><span class="term"><span class="strong">明智：</span> </span></dt><dd>
    <p>我组装的电脑(K6/233 CPU、FIC-PA2007主板(威盛Apollo VP2芯片组)、Corsair PC133
SDRAM 256Mb内
存)最近在开机20分钟左右、做内核编译时频繁地报SIG11错，但在头20分钟内从不出问题。重启动不会复位时钟，但整夜关机会。更换所有内存未解决问
题，相关的典型编译会话日志附后。</p>
  </dd></dl>
</div>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="chronology"></a>按时间先后罗列症状</h3>
</div>
</div>
</div>
<p>刚出问题之前发生的事情通常包含有解决问题最有效的线索。所以，记录中应准确地描述你及电脑在崩溃之前都做了些什么。在命令行处理的
情况下，有会话日志(如运行脚本工具生成的)并引用相关的若干(如20)行记录会非常有帮助。</p>
<p>如果崩溃的程序有诊断选项(如-v详述选项)，仔细考虑选择这些能在记录中增加排错信息的选项。</p>
<p>如果你的记录很长(如超过四段)，也许在开头简述问题随后按时间先后罗列详细过程更有用。这样做，黑客在读你的记录时就知道该查哪些内容了。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="goal"></a>描述目的而不是步骤</h3>
</div>
</div>
</div>
<p>如果你想弄清楚如何做某事(而不是报告一个臭虫)，在开头就描述你的目标，此后才描述为此采取的措施所遇到的问题。</p>
<p>经常有这种情况，寻求技术帮助的人在脑袋里有个更高层面的目标，他们在自以为能达到目标的特定道路上被卡住了，然后跑来问该怎么走，但
没有意识到这条路本身有问题，结果要费很大的劲才能通过。</p>
<div class="variablelist">
<dl><dt><span class="term"><span class="strong">愚蠢：</span> </span></dt><dd>
    <p>我怎样才能让某图形程序的颜色拾取器取得十六进制的RGB值？</p>
  </dd><dt><span class="term"><span class="strong">明智：</span> </span></dt><dd>
    <p>我正试图用自己选定数值的颜色替换一幅图片的颜色表，我现在唯一知道的方法是编辑每个表槽，但却无法让某图形程序的颜色拾取器取得十六进
制的RGB值。</p>
  </dd></dl>
</div>
<p>第二种提法是明智的，它使得建议采用更合适的工具完成任务的回复成为可能。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="noprivate"></a>别要求私下回复</h3>
</div>
</div>
</div>
<p>黑客们认为问题的解决过程应该公开、透明，此过程中如果更有才能的人注意到不完整或者不当之处，最初的回复才能够、也应该被更正。同时，作为
回复者也因为能力和学识被其它同行看到而得到某种回报。</p>
<p>当你要求私下回复时，此过程和回报都被中止。别这样做，让<span style="font-weight: bold; font-style: italic;">回复者</span>来决定是否私下回答──如果他
真这么做了，通常是因为他认为问题编写太差或者太肤浅
以
至于对其它人无意义。</p>
<p>对这条规则存在一条有限的例外，如果你确信提问可能会导致大量雷同的回复时，那么“给我发电子邮件，我将为小组归纳这些回复”将是神奇的句子。试图
将邮
件列表或新闻组从洪水般雷同的回复中解救出来是非常有礼貌的──但你应信守诺言。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="explicit"></a>问题应明晰<br>
</h3>
</div>
</div>
</div>
<p>漫无边际的问题通常也被视为没有明确限制的时间无底洞。最有可能给你有用答案的人通常也是最忙的人(假如只是因为他们承担了大多数工作的话)，这些
人
对于没
有限制的时间无底洞极其反感，所以他们也倾向于讨厌那些漫无边际的问题。</p>
<p>如果你明确了想让回复者做的事(如指点方向、发送代码、检查补丁或其它)，你更有可能得到有用的回复。这可以使他们集中精力并间接地设定了他们为帮
助你需要花费的时间和精力上限，这很好。</p>
<p>要想理解专家生活的世界，可以这样设想：那里有丰富的专长资源但稀缺的响应时间。你暗中要求他们奉献的时间越少，你越有可能从这些真正懂行也真正很
忙的专家
那里得到回答。</p>
<p>所以限定你的问题以使专家回答时需要付出的时间最少──这通常还与简化问题不一样。举个例，“请问可否指点一下哪有好一点的X解释？”通常要
比“请解释一下X”明智。如果你有什么代码不运行了，通常请别人看看哪有问题比叫他们帮你改正更明智。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="homework"></a>别张贴家庭作业<br>
</h3>
</div>
</div>
</div>
<p>黑客们善于发现“家庭作业”式的问题。我们大多数人已经做了自己的家庭作业，那是<span style="font-weight: bold; font-style: italic;">该你</span>做的，以便从其经历中学习。问一
下提示没有关系，但不是要求完整的解决方案。</p>
<p>如果你怀疑自己碰到了一个家庭作业式的问题，但仍然无法解决，尝试在用户组论坛或(作为最后一招)在项目的“用户”邮件列表或论坛中提问。尽管
黑客们会看出来，一些高级用户也许仍会给你提示。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="prune"></a>删除无意义的问题</h3>
</div>
</div>
</div>
<p>抵制在求助消息末尾加上诸如“有人能帮我吗？”或“有没有答案？”之类在语义上无任何意义东西的诱惑。第一，如果问题描述还不完整，这些附
加的东西最多也只能是多余的。第二，因为它们是多余的，黑客们会认为这些东西烦人──就很有可能用逻辑上无误但打发人的回复，诸如“是的，你可
以得到帮助”和“不，没有给你的帮助”</p>
<p>一般来说，避免提“是或否”类型的问题，除非你想得到 <a href="http://homepages.tesco.net/%7EJ.deBoynePollard/FGA/questions-with-yes-or-no-answers.html" target="_top">“是或否”类型的回答</a>。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="urgent"></a>不要刻意标明问题紧急</h3>
</div>
</div>
</div>
<p>这是你自己的问题，不要我们的。宣称“紧急”极有可能事与愿违：大多数黑客会直接删除这种消息，他们认为这是无礼和自私地企图得到即时与特殊的关
照。</p>
<p>有一点点局部的例外，如果你是在一些知名度很高、会使黑客们激动的地方使用程序，也许值得这样去做。在这种情况下，如果你有期限压力，也很有礼貌
地提到这点，人们也许会有足够的兴趣快一点回答。</p>
<p>当然，这是非常冒险的，因为黑客们对什么是令人激动的标准多半与你的不同。譬如从国际空间站这样张贴没有问题，但代表感觉良好的慈善或政治原
因这样做几乎肯定不行。事实上，张贴诸如“紧急：帮我救救这个毛绒绒的小海豹！”肯定会被黑客回避或光火，即使他们认为毛绒绒的小海豹很重要。</p>
<p>如果你觉得这不可思议，再把剩下的内容多读几遍，直到弄清楚了再发贴。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="courtesy"></a>礼貌总是无害的</h3>
</div>
</div>
</div>
<p>礼貌一点，使用“请”和“谢谢你的关注”或者“谢谢你的意见”，让别人明白你感谢他们无偿花时间帮助你。</p>
<p>坦率地说，这一点没有语法正确、文字清晰、准确、有内容和避免使用专用格式重要(同时也不能替代它们)。黑客们一般宁可读有点唐突但技术鲜明的臭
虫报告，而不是那种礼貌但含糊的报告。(如果这点让你不解，记住我们是按问题能教我们些什么来评价一个问题的)</p>
<p>然尔，如果你已经谈清楚了技术问题，客气一点肯定会增加你得到有用回复的机会。</p>
<p>(我们必须指出，本文唯一受到一些老黑客认真反对的地方是以前曾经推荐过的“提前谢了”，一些黑客认为这隐含着事后不用再感谢任何人的暗示。我们的
建议是
先说
“提前谢了”，事后再对回复者表示感谢。或者换种方式表达，譬如用“谢谢你的关注”或“谢谢你的意见”)。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="followup"></a>问题解决后追加一条简要说明</h3>
</div>
</div>
</div>
<p>问题解决后向所有帮助过的人追加一条消息，让他们知道问题是如何解决的并再次感谢。如果问题在邮件列表或新闻组中受到广泛关注，在那里追加此消息比
较恰当。</p>
<p>最理想的方式是向最初提问的线索回复此消息并在主题包含“已解决”、“已搞定”或其它同样意思的明显标记。在人来人往的邮件列表里，一个看见线索
“问题X”和“问题X-已解决”的潜在回复者就明白不用再浪费时间了(除非他个人觉得“问题X”有趣)，因此可以用此时间去解决其它
问题。</p>
<p>你追加的消息用不着太长太复杂，一条简单的“你好──是网线坏了！谢谢大家──比尔”就比什么都没有要强。事实上，除
非解决问题的技术真正高深，一条简短而亲切的总结比长篇大论要好。说明是什么行动解决了问题，用不着重演整个排错的故事。</p>
<p>对于有深度的问题，张贴排错历史的摘要是适当的。描述问题的最终状态，说明是什么解决了问题，在此<span style="font-weight: bold; font-style: italic;">之后</span>才指明可以避免的弯路。应避免的
弯路部分应放在正确的解决方案和其它总结材料之后，而不要将此消息搞成侦探推理小说。列出那些帮助过你的名字，那样你会交到朋友的。</p>
<p>除了有礼貌、有内容以外，这种类型的追帖将帮助其他人在邮件列表、新闻组或论坛文档中搜索到真正解决你问题的方案，从而也让他们受益。</p>
<p>除上述而外，此类追帖还让每位参与协助的人因问题的解决而产生一种满足感。如
果你自己
不是技术专家或黑客，相信我们，这种感觉对于你寻求帮助的老手和专家非常重要。问题叙述到最后不知所终总是令人沮丧的，黑客们痒
痒地渴望看到它们被解决。“挠痒痒”为你挣到的好报将对你下次再次张贴提问非常非常的有帮助。 </p>
<p>考虑一下怎样才能避免其他人将来也遇到类似的问题，问问自己编一份文档或FAQ补丁有没有帮助，如果有的话就将补丁发给维护者。</p>
<p>在黑客中，这种行为实际上比传统的礼貌更重要，也是你善待他人而赢得声誉的方式，这是非常有价值的财富。</p>
</div>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2><a name="answers"></a>如何解读回答</h2>
</div>
</div>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="rtfm"></a>RTFM和STFW：如何知道你已完全搞砸</h3>
</div>
</div>
</div>
<p>有一个古老而神圣的传统：如果你收到了“RTFM”的回复，发信人认为你应该去“读读该死的手册”。他多半是对的，去读一下吧。</p>
<p>RTFM有个年轻的亲戚，如果你收到“STFW”的回复，发信人认为你应该“搜搜该死的网络”。他多半也是对的，去搜一下吧。(更温和一点的说法是
“Google
是你的朋友！”)</p>
<p>在网页论坛，你也可能被要求去搜索论坛的文档。事实上，有人甚至可能热心地为你提供以前解决此问题的线索。但不要依赖这种好心，提问前应先搜索
一下文
档。</p>
<p>通常，叫你搜索的人已经打开了能解决你问题的手册或网页，正在一边看一边敲键盘。这些回复意味着他认为：第一，你要的信息很容易找到。第二，自已找
要比别人喂到嘴里能学得更多。</p>
<p>你不应该觉得这样就被冒犯了，按黑客的标准，他没有不理你就是在向你表示某种尊敬，你反而应该感谢他热切地想帮助你。</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="lesser"></a>如果还不明白</h3>
</div>
</div>
</div>
<p>如果你看不懂回复，不要马上回发一个要求说明的消息，先试试那些最初提问时用过的同样工具(手册、FAQ，网页、懂行的朋友等)试着搞懂回
复。如果还是需要说明，展现你已经明白的。</p>
<p>譬如，假如我告诉你：“听起来象是某输入项有问题，你需要清除它”，接着是个<span style="font-weight: bold; font-style: italic;">不好</span>的回帖：“什么是某输入项？”。
而这是一个<span style="font-weight: bold; font-style: italic;">好</span>的跟帖：“是
的，
我读了手册，某输入项只在-z和-p开关中被提到，但都没有提及清除某选项，你指的是哪一个还是我弄错了什么？”</p>
</div>
<div class="sect2" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="keepcool"></a>对待无礼</h3>
</div>
</div>
</div>
<p>很多黑客圈子中看似无礼的行为并不是存心冒犯。相反，它是直接了当、一刀见血式的交流风格，这种风格对于更关注解决问题而不是使别人感觉舒服而混乱
的人
是很自然的。</p>
<p>你如果觉得被冒犯，努力平静地反应。如果有人真的做了过格的事，邮件列表或新闻组或论坛中的前辈多半会招呼他。如果这<span style="font-weight: bold; font-style: italic;">没有</span>发生而你却发火了，那么你发火对
象的言语
可能在黑客社区中看起来是正常的，而<span style="font-weight: bold; font-style: italic;">你</span>将
被视为有错的一方，这将伤害到你获取信息或帮助的机会。</p>
<p>另一方面，你会偶而真的碰到无礼和无聊的言行。与上述相反，对真正的冒犯者狠狠地打击、用犀利的语言将其驳得体无完肤都是可以
接受的。然尔，在行事之前一定要非常非常的有根据。纠正无礼的言论与开始一场毫无意义的口水战仅一线之隔，黑客们自己莽撞地越线情况并不鲜见。如果你是新
手或外来者，避开这种莽撞的机会不高。如果你
想得到的是信息而不是消磨时光，这时最好不要把手放在键盘上以免冒险。</p>
<p>(有些人断言很多黑客都有轻度的自闭症或阿斯伯格综合症，一定缺少平滑人类社会“正常”交往所需的脑电路。这既可能是真也可能是假。如果你自己不是
黑客，兴许
你认为我
们脑袋有问题还能帮助你应付我们的古怪行为。只管这么干好了，我们不在乎。我们<span style="font-weight: bold; font-style: italic;">喜欢</span>我们现在这个样子，并且一般都对
临床诊断有相当的怀疑。)</p>
<p>在下一节，我们会谈到另一个问题，当你行为不当时会受到的“冒犯”</p>
</div>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2><a name="not_losing"></a>别象个失败者那样反应</h2>
</div>
</div>
</div>
<p>在黑客社区的论坛中有那么几次你会搞砸──以本文详述或类似的方式。你会被示众是如何搞砸的，也许言语中还会带点颜色。</p>
<p>这种事发生以后，你能做的最糟的事莫过于哀嚎你的遭遇、宣称被口头攻击、要求道歉、高声尖叫、憋闷气、威胁诉诸法律、向其雇主报怨、忘了关马桶盖等
等。相
反，你该这样去做：<br>
</p>
<p>熬过去，这很正常。事实上，它是有益健康与恰当的。</p>
<p>社区的标准不会自己维持，它们是通过参与者积极而<span style="font-weight: bold; font-style: italic;">公开</span>地执行来维持的。不要哭嚎所有的
批评都应该通过私下的邮件传送，这不是事情运作的方式。当有人批评你的
一些主张或者其看法不同时，坚持声称个人被侮辱也毫无用处，这些都是失败者的态度。</p>
<p>也有其它的黑客论坛，受太高礼节要求的误导，要求参与者禁止张贴任何对别人帖子挑毛病的消息，并被告知“如果你不想帮助用户就闭嘴”。有思路的参与
者纷纷
离
开
的结果只会使它们变成了毫无意义的唠叨与无用的技术论坛。</p>
<p>是夸张的“友谊”(以上述方式)还是有用？挑一个。</p>
<p>记住：当黑客说你搞砸了，并且(无论多么刺耳地)告诉你别再这样做时，他正在为关心你和他的社区而行动。对他而言，不理你并将你从他的生活中滤除要
容易得
多。如果你无法做到感谢，至少要有点尊严，别大声哀嚎，也别因为自己是个有戏剧性超级敏感的灵魂和自以为有资格的新来者，就指望别人象对待脆弱的洋娃娃
那样对你。</p>
<p>有时候，即使你没有搞砸(或者只是别人想象你搞砸了)， 有些人会无缘无故地攻击你本人。在这种情况下，报怨倒是<span style="font-weight: bold; font-style: italic;">真的</span>会把问题搞砸。</p>
<p>这些找茬者要么是什么也不懂但自以为是专家的不中用家伙，要么就是测试你是否真会搞砸的心理学家。其它读者要么不理睬，要么用自己的方式对付他们。
这些找茬者在给自己找麻烦，这点你不用操心。</p>
<p>也别让自己卷入口水战，大多数口水战最好不要理睬──当然是在你核实它们只是口水战、没有指出你搞砸的地方，而且没有巧妙地将问题真正的答案藏于其
中
(这也
是
可能的)之后。</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="classic"></a>提问禁忌</h2>
</div>
</div>
</div>
<p>下面是些典型的愚蠢问题和黑客不回答它们时的想法。</p>
<div class="qandaset">
<dl><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002488">我到哪可以找到程序或X资源？ </a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002514">我怎样用X做Y？</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002537">如何配置我的shell提示？</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002563">我可以用Bass-o-matic文件转换工具将AcmeCorp文档转为TeX格式
吗？</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002586">我的{程序、配置、SQL语句}不运行了</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002626">我的视窗电脑出问题了，你能帮忙吗？</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002657">我的程序不运行了，我认为系统工具X有问题</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002681">我安装Linux或X遇到困难，你能帮忙吗？</a></dt><dt>问： <a href="http://www.fengnet.com/smart-questions.html#id3002722">我如何才能破解超级用户口令/盗取频道操作员的特权/查看某人的电子邮件？</a></dt></dl>
<table summary="Q and A Set" border="0">
  <col align="left" width="1%"><tbody>
    <tr class="question">
      <td align="left" valign="top"><b>问：</b></td>
      <td align="left" valign="top">
      <p><a name="id3002488"></a>我到哪可以找到程序或X资源？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><b>答：</b></td>
      <td align="left" valign="top">
      <p>在我找到它的同样地方，笨旦──在网页搜索引擎上。上帝啊，难道还有人不知道如何使用 <a href="http://www.google.com/">Google</a> 吗？</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><b>问：</b></td>
      <td align="left" valign="top">
      <p><a name="id3002514"></a>我怎样用X做Y？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><b>答：</b></td>
      <td align="left" valign="top">
      <p>如果你想做的是Y，提问时别给出可能并不恰当的方法。这种问题说明提问者不但对X完全无知，也对要解决的Y问题糊涂，还被特定形势禁
锢了思维。等他们把问题弄
好再说。</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><b>问：</b></td>
      <td align="left" valign="top">
      <p><a name="id3002537"></a>如何配置我的shell提示？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><b>答：</b></td>
      <td align="left" valign="top">
      <p>如果你有足够的智慧提这个问题，你也该有足够的智慧去 <a href="file:///home/frank/work/tran/smart-questions-3.0-cn.html#rtfm">RTFM</a>，
然后自己去找。</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><span style="font-weight: bold;">问：</span><br>
      </td>
      <td align="left" valign="top">
      <p><a name="id3002563"></a>我可以用Bass-o-matic文件转换工具将AcmeCorp文档转为TeX格
式吗？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><span style="font-weight: bold;">答：</span><br>
      </td>
      <td align="left" valign="top">
      <p>试试就知道了。如果你试过，你既知道答案，又不用浪费我的时间了。</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><span style="font-weight: bold;">问：</span><br>
      </td>
      <td align="left" valign="top">
      <p><a name="id3002586"></a>我的{程序、配置、SQL语句}不运行了</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><span style="font-weight: bold;">答：</span><br>
      </td>
      <td align="left" valign="top">
      <p>这不是一个问题，我也没有兴趣去猜你有什么问题──我有更要紧的事要做。看到这种东西，我的反应一般如下：</p>
      <div class="itemizedlist">
      <ul type="disc"><li>
          <p>你还有什么补充吗？</p>
        </li><li>
          <p>噢，太糟了，希望你能搞定。</p>
        </li><li>
          <p>这跟我究竟有什么关系？</p>
        </li></ul>
      </div>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><span style="font-weight: bold;">问：</span><br>
      </td>
      <td align="left" valign="top">
      <p><a name="id3002626"></a>我的视窗电脑出问题了，你能帮忙吗？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><span style="font-weight: bold;">答：</span><br>
      </td>
      <td align="left" valign="top">
      <p>是的，把视窗垃圾删了，装个象Linux或BSD的开源操作系统吧。</p>
      <p>注意：如果程序有官方的视窗版或与视窗有交互(如Samba)，你<span style="font-weight: bold; font-style: italic;">可以</span>问与视窗电脑相关的问题，只是别
对问题是由视窗操作系统而不是程序本身造成的回复感
到惊讶，因
为视窗一般来说太差，这种说法一般都成立。</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><span style="font-weight: bold;">问：</span><br>
      </td>
      <td align="left" valign="top">
      <p><a name="id3002657"></a>我的程序不运行了，我认为系统工具X有问题</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><span style="font-weight: bold;">答：</span><br>
      </td>
      <td align="left" valign="top">
      <p>你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与库文件有明显缺陷的人，更有可能的是你完全没有根据。不同凡响的说法需
要不同凡响的证据，
当你这样
声称时，你必须有清楚而详尽的缺陷说明文档作后盾。</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><span style="font-weight: bold;">问：<a name="id3002681"></a></span><br>
      </td>
      <td align="left" valign="top">
      <p>我安装Linux或X遇到问题，你能帮忙吗？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><span style="font-weight: bold;">答：</span><br>
      </td>
      <td align="left" valign="top">
      <p>不行，我需要亲手操作你的电脑才能帮你排错，去向当地的Linux用户组寻求方便的帮助(你可以在 <a href="http://www.linux.org/groups/index.html">这里</a> 找到用户组列表)</p>
      <p>注意：在为某一Linux发行版服务的邮件列表或论坛或本地用户组织中提关于安装该发行版的问题也许是恰当的。此时，应描述问题的准确
细节。在此之前，先用
“linux”和<span style="font-weight: bold; font-style: italic;">所有</span>被怀
疑的硬件(为关键词)仔细搜索。</p>
      </td>
    </tr>
    <tr class="question">
      <td align="left" valign="top"><span style="font-weight: bold;">问：</span><br>
      </td>
      <td align="left" valign="top">
      <p><a name="id3002722"></a>我如何才能破解超级用户口令/盗取频道操作员的特权/查看某人的电子邮件？</p>
      </td>
    </tr>
    <tr class="answer">
      <td align="left" valign="top"><span style="font-weight: bold;">答：</span><br>
      </td>
      <td align="left" valign="top">
      <p>想做这种事情说明你是个卑劣的家伙，想让黑客教你做这种事情说明你是个白痴。</p>
      </td>
    </tr>
  </tbody>
</table>
</div>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="examples"></a>好问题与坏问题</h2>
</div>
</div>
</div>
<p>最后，我将通过举例来演示提问的智慧。同样的问题两种问法，一种愚蠢，另一种明智。</p>
<div class="variablelist">
<dl><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="term">愚蠢：我在哪能找到关于Foonly
Flurbamatic设备的东西？</span></span><dt><span class="term"> </span><br>
  </dt><dd>
    <p>这个问题在乞求得到 <a href="http://www.fengnet.com/smart-questions.html#rtfm">STFW</a>
式的回复。</p>
  </dd><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="term">明智：我用Google搜索过“Foonly
Flurbamatic
2600”，但没有找到什么有用的，有谁知道在哪能找到这种设备的编程信息？</span></span><dt><span class="term">
    </span><br>
  </dt><dd>
    <p>这个人已经搜索过网络了，而且听起来他可能真的遇到了问题。</p>
  </dd></dl>
</div>
<div class="variablelist">
<dl><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="term">愚蠢：我不能编译某项目的源代码，它为什
么这么破？</span></span><dt><span class="term"> </span><br>
  </dt><dd>
    <p>他假设是别人搞砸了，太自大了。</p>
  </dd><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="term">明智：某项目的源代码不能在某Linux
6.2版下编译。我读了常见问题文档，但其中没有与某Linux相关的问题。这是编译时的记录，我做错了什么吗？</span></span><dt><span class="term"> </span><br>
  </dt><dd>
    <p>他指明了运行环境，读了FAQ，列出了错误，也没有假设问题是别人的过错，这家伙值得注意。</p>
  </dd></dl>
</div>
<div class="variablelist">
<dl><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="term">愚蠢：我的主板有问题，谁能帮我？</span></span><dt><span class="term"> </span><br>
  </dt><dd>
    <p>某黑客对此的反应可能是：“是的，还需要帮你拍背和换尿布吗？”，然后是敲下删除键。</p>
  </dd><dt><span class="term"><span class="strong"></span></span><br>
  </dt><span class="term"><span class="term">明智：我在S2464主板上试过X、Y和
Z，当它们都失败后，又试了A、B和C。注意我试C时的奇怪症状，显然某某东西正在做某某事情，这不是期望的。通常
在Athlon MP主板上导致某某事情的原因是什么？有谁知道我还能再试点什么以确定问题？</span></span><dt><span class="term"></span><br>
  </dt><dd>
    <p>相反地，这个人看来值得回答。他展现了解决问题的能力而不是坐等天上掉馅饼。</p>
  </dd></dl>
</div>
<p>在最后那个问题中，注意“给我一个回复”与“请帮我看看我还能再做点什么测试以得到启发”之间细微但重要的差别。</p>
<p>事实上，最后那个问题基本上源于2001年8月Linux内核邮件列表(lkml)上的真实事件，是我(Eric)当时提了那个问题，我发现
Tyan
S2462 主板有神秘的死机现象，邮件列表成员给我提供了解决此问题的关键信息。<br>
</p>
<p>通过这种提问方式，我给了别人可以咀嚼玩味的东西。我设法使之对参与者既轻松又有吸引力，也表明了对同行能力的尊敬并邀请他们与我一起协商。通
过告诉
他们我已经走过的弯路，我还表明了对他们宝贵时间的尊重。</p>
<p>事后，当我感谢大家并评论这次良好的经历时，一个Linux内核邮件列表的成员谈到，他认为并不是因为我的名字在列表上，而是因为我正确的提问方式
才
得到了答
案。</p>
<p>黑客们在某种方面是非常不留情面的精英分子。我想他是对的，如果我表现得象个不劳而获的寄生虫，不管我是谁都会被忽略或斥责。他建议将整个事件作为
对其它
人
提问的指导直接导致了本文的编写。</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="id3002966"></a>如果没有回复</h2>
</div>
</div>
</div>
<p>如果得不到回答，请不要认为我们不想帮你，有时候只是因为小组成员的确不知道答案。没有回复不等于被忽略，当然必须承认从外面很难看出两者的差别。</p>
<p>一般来说，直接将问题再张贴一次不好，这会被视为毫无意义的骚扰。</p>
<p>还有其它资源可以寻求帮助，通常是在一些面向新手的资源中。</p>
<p>有许多在线与本地用户组织，虽然它们自己不编写任何软件，但是对软件很热心。这些用户组通常因互助和帮助新手而形成。</p>
<p>还有众多大小商业公司提供签约支持服务(红帽与Linuxcare是两家最出名的，还有许多其它的)。别因为要付点钱才有支持就感到沮丧！毕竟，如
果你车子的
汽缸垫烧了，你多半还得花钱找个修理店把它弄好。即使软件没花你一分钱，你总不能指望服务支持都是免费的。</p>
<p>象Linux这样流行的软件，每个开发者至少有一万个以上的用户，一个人不可能应付这么多用户的服务要求。记住，即使你必须付费才能得到支持，也比
你还得额外花钱买软件要少得多(而且对封闭源代码软件的服务支持与开源软件相比通常还要贵一点，也要差一点)</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="id3003018"></a>如何更好地回答
问题</h2>
</div>
</div>
</div>
<p><span class="emphasis"><em></em></span><span style="font-weight: bold; font-style: italic;">态度和善一点。</span>问题带来的压力常使人
显得无礼或愚蠢，其实并不是这样。</p>
<p><span class="emphasis"><em></em></span><span style="font-weight: bold; font-style: italic;">对初犯者私下回复。</span>对那些坦诚犯错
之人没有必要当众羞辱，一个真正的新手也许连怎么搜索或在哪找FAQ都不知道。</p>
<p><span class="emphasis"><em></em></span><span style="font-weight: bold; font-style: italic;">如果你不确定，一定要说出来！</span>一个听
起来权威的错误回复比没有还要糟，别因为听起来象个专家好玩就给别人乱指路。要谦虚和诚实，给提问者与同行都树个好榜样。</p>
<p><span class="emphasis"><em></em></span><span style="font-style: italic;"><span style="font-weight: bold;">如果帮不了忙，别妨
碍。</span></span>不要在具体步骤上开玩笑，那样也许会毁了用户的安装──有些可怜的呆瓜会把它当成真的指令。</p>
<p><span class="emphasis"><em></em></span><span style="font-weight: bold; font-style: italic;">探索性的反问以引出更多的细节</span>。如
果你做得好，提问者可以学到点东西──你也可以。试试将很差的问题转变成好问题，别忘了我们都曾是新手。</p>
<p>尽管对那些懒虫报怨一声RTFM是正当的，指出文档的位置(即使只是建议做个Google关键词搜索)会更好。</p>
<p><span class="emphasis"><em></em></span><span style="font-style: italic;"><span style="font-weight: bold;">如果你决意回答，给
出好的答案。</span></span>当别人正使用错误的工具或不当
的方法时别建议笨拙的权宜之计，应推荐更好的工具，重新组织问题。</p>
<p><span class="emphasis"><em></em></span><span style="font-style: italic;"><span style="font-weight: bold;">帮助你的社区从问题中
学习。</span></span>当回复一个好问题时，问问自己
“如何修改相关文件或FAQ文档以免再次解答同样的问题？”，接着再向文档维护者发一份补丁。</p>
<p>如果你的确是在研究一番后才做出的回答，<span style="font-weight: bold; font-style: italic;">展
现你的技巧而不是直接端出结果。</span>毕竟“授
人以鱼，不如授人以渔”。</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="id3003109"></a>相关资源</h2>
</div>
</div>
</div>
<p>如果还需要个人电脑、Unix和互联网如何工作的基础知识，参阅 <a href="http://en.tldp.org/HOWTO/Unix-and-Internet-Fundamentals-HOWTO/">Unix
和互联网如何工作的基本原理</a>
</p>
<p>当你发布软件或补丁时，尝试按 <a href="http://en.tldp.org/HOWTO/Software-Release-Practice-HOWTO/index.html">软
件发布实践</a> 指南进行。</p>
</div>
<div class="sect1" xml:lang="en" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both;"><a name="id3003139"></a>鸣谢</h2>
</div>
</div>
</div>
<p>Evelyn Mitchell 贡献了一些愚蠢问题样例并启发了编写“如何更好地回答问题”这一节，Mikhail
Ramendik 贡献了一些特别有价值的建议和改进。<br>
</p>
</div>
</div>

<br>
<br>
<br>

Powered&nbsp;by&nbsp;MessageSoft&nbsp;SMG&nbsp;<br>

SPAM,&nbsp;virus-free&nbsp;and&nbsp;secure&nbsp;email&nbsp;<br>

http://www.messagesoft.com&nbsp;<br>

<br>
<img src ="http://www.blogjava.net/briansun/aggbug/2995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-04-08 14:55 <a href="http://www.blogjava.net/briansun/articles/2995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse的前世今生?[转]</title><link>http://www.blogjava.net/briansun/articles/2867.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Tue, 05 Apr 2005 02:48:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/2867.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/2867.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/2867.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/2867.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/2867.html</trackback:ping><description><![CDATA[<h3><b><b>Eclipse的前世今生?[转]</b></b></h3>
<br>
Eclipse 最早来源于Object Technology International (OTI)于1994年开发的产品 IBM
VisualAge for Smalltalk，1996年又发布了IBM Visual Age for Java
。以上产品都是用Smalltalk写的，完全用Java编写的IDE则是后来推出的IBM VisualAge Micro
Edition这一产品，这也是Eclipse的主要基础，但这一产品对第三方组件的支持不够。后来经过一个小规模专家团队的研究，在总结过去开发经验的
前提下，提高了IDE的可扩展性，其产品就是Eclipse。2001年11月Eclipse开源项目正式建立，2005年3月24日的最新正式发布版本是
Eclipse3.0.2，稳定版本是Eclipse3.1M5。插件总数(据不完全统计)约742个，涉及软件开发的方方面面。插件分类如下：Bug
Tracker (6)、Code Generation (13)、Code mngt (73)、Database
(44)、Deployment (18)、Documentation (26)、Editor (16)、Electronics
(1)、Entertainment (36)、Graphics (5)、J2EE development platform
(35)、Languages (43)、Middleware (6)、Mobile/PDA (12)、Modelling
(16)、Network (11)、News (7)、Obsolete (3)、Patterns (4)、Profiling
(12)、Project management (4)、Research (3)、Rich Client
(5)、Safety-critical (2)、SCM (20)、Snipets (2)、Snipets/Modelling
(1)、Source Code Analyzer (21)、Team (6)、Testing (25)、Tomcat (5)、Tools
(51)、Tutorial (33)、UI (31)、UI components (9)、UML (20)、Utility (27)、Web
(39)、Web Service (19)、XML (32)。<br>
<img src ="http://www.blogjava.net/briansun/aggbug/2867.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-04-05 10:48 <a href="http://www.blogjava.net/briansun/articles/2867.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Best Practise for Risk-Free Deployment</title><link>http://www.blogjava.net/briansun/articles/2644.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Thu, 31 Mar 2005 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/2644.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/2644.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/2644.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/2644.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/2644.html</trackback:ping><description><![CDATA[<img src="http://www.theserverside.com/articles/content/BuildManagement/BuildManagement.gif" alt="Best Practices for Risk-Free Deployment" align="middle" border="0">

<br>

<br>

<br>

<b>March 2005</b>
<br>


<h2><b><a href="http://www.theserverside.com/news/thread.tss?thread_id=32929">Discussion</a></b></h2>

<br>





<h2>Overview</h2>

<p>The cost impact to a company of a failed project can be severe indeed. The
  impact on the reputation of the project manager can be disastrous.</p>

<p>Software project management is not easy, and it requires considerable skill
  to successfully manage the many different risks that conspire to de-rail a
  project:</p>

<p><img src="http://www.theserverside.com/articles/content/BuildManagement/IMG01.gif"></p>

<p>Numerous methodologies are available for mitigating these risks – PRINCE2,
RUP, DSDN, eXtreme programming – and these have helped to some extent.</p>

<p>This document introduces the 3D™ methodology – a set of best practices
  and quality tools developed by BuildMonkey, which can be summarised as.</p>

<p><strong> De-risk. Deploy. Deliver.</strong></p>

<p>In any software project, deployment is a milestone on the project plan that
  is usually associated with payment – or staged payment. Through the course
  of development, any number of problems can arise to derail efforts to reach
  this milestone.</p>

<p>The 3D™ methodology and supporting toolset is based on many years of
  experience at the sharp end of projects, understanding what has worked and
  what has not, and the lessons learned from each.</p>

<p>Competent practitioners, and experienced project staff, will find resonance
  with many of the contents of this document and may find themselves saying “<em>this
  is just common sense</em>”. This is certainly true, but the main problem
  with common sense is that it is not as common as people think it is.</p>

<p>This document, and the 3D™ methodology, is an attempt to bring that
  common sense together in a single location, as a coherent set of best practices
  supported by proven tools to help you to <strong><em>release on-time, on-budget,
with no defects</em></strong>.</p>

<h2>The Problem To Be Solved</h2>

<p>No methodology has yet focused on the component that all development projects
  share – the build.</p>

<p>One of the reasons for this is that the term “build” is interpreted
  differently by different people:</p>

<ul>
<li>The development team sees it as compilation and assembly;</li><li>The integration team see it as the bringing together of all of the components
  in the application in a format suitable for release;</li><li>The deployment team see it as something which produces the artifacts that
  they have to install and configure;</li><li>The testing team see it as something which produces the artifacts that
  they have to test;</li><li>The Project Manager sees it as an opaque step that nobody is entirely responsible
  for;;</li><li>The end customer should not see it at all;</li>
</ul>

<p>The BuildMonkey view is that the build is the combination of processes and
  technology that take software from design to deployment – _where the
  return on investment starts to be seen.</p>

<p>It is clear that a methodology is required to de-risk development projects
  and to standardise use of the term “Build Management”.</p>

<p><strong>Best Practice: “<em>Build Management</em>” encompasses
    everything from compilation, all the way through to release to the customer. </strong></p>

<h2>No Release, No Revenue</h2>

<p>Any Finance Director knows that development is just an activity that needs
  to be tolerated in order to produce something that will deliver a return on
  investment.</p>

<p>It may sound strange, but a large number of software developers do not appreciate
  and embrace this basic truth. This is in part due to their closeness to the
  application being constructed.</p>

<p>A common problem faced by development projects is therefore that it is the
  software developers who manage the build. This creates a situation where the
  build is focused on the needs of development, and is not geared towards releasing
  the output of coding such that business value can be realised.</p>

<p>Build Management should therefore focus on the end result of development – a
  return on investment – and ensure that all of the inputs to the process
  are incorporated in pursuit of this goal:</p>

<p>Best Practice: Focus on the end, and accommodate the inputs</p>

<h2>Software Tools Are Only Part of the Answer</h2>

<p>Software projects are a complex set of interdependent people and teams and
  can be likened to a convoy of ships. A convoy has to move at the rate of the
  slowest ship. Increasing the speed of a single ship in the convoy will not
  increase the speed of the convoy – it will simply increase the amount
  of wasted capacity in the speeded-up ship.</p>

<p>Speeding up the slowest ship will, however, have a positive effect since the
  whole convoy can now move faster.</p>

<p> Many Project Managers try to improve productivity by implementing some degree
  of automation in development projects – particularly in the area of the
  build – and often purchase “<em>magic bullet</em>” build
  software that provides this.</p>

<p>Simply using automated build software does not improve productivity any more
  than the example above improves convoy speed - as it only increases the speed
  of a single ship in the convoy.</p>

<p>There is no point in speeding up development, if the target production infrastructure
  cannot keep pace – this just increases the inefficiency. A lot of organisations
  make this mistake – highly agile development processes trying to feed
  into considerably less agile deployment processes. The result is inefficiency,
  waste and over-run.</p>

<p>Before considering using an automated build tool it is essential to ensure
  that the inputs to, and outputs from, the build can cope with the improved
  build speed. It is imperative to ensure that the processes and technology employed
  are geared towards taking the project to a successful conclusion – on-time
  and on-budget.</p>

<p>Best Practice: Don’t rely on software tools alone, they may solve symptoms
whilst creating problems elsewhere</p>

<h2>Configuration Management Best Practices</h2>

<p>Software Configuration Management (SCM) is a relatively mature discipline
  with much written about methodologies and techniques, and these will not be
  recreated here.</p>

<p>We will focus instead on leveraging the SCM repository, and the facilities
  that it offers, to further the goals of the project rather than to consider
  SCM in its own right.</p>

<h2>It All Starts Here</h2>

<p>The SCM repository - how it is managed and used – is the keystone of
  good build management and successful delivery of projects.</p>

<p>The SCM repository is the slave of the project, not the other way round. It
  should be solid and reliable, yet flexible enough to accommodate the needs
  of new projects. Project Managers should not have to retrofit their planning
  to accommodate an inflexible SCM setup.</p>

<p>If used correctly, the SCM repository will enhance productivity, and minimize
  risk, through being able to provide exactly what the project – and project
  management – require. If used incorrectly, it can cause delay and slippage
  through having to do things inefficiently further down the chain.</p>

<p>Best Practice: The SCM repository is the slave of the project, not the other
  way round.</p>

<h2>Configuration Management is not Version Control</h2>

<p>Most software developers regard the SCM repository as a massive storage area
  where they simply check versions in and out – a common cause of problems.</p>

<p>Simply checking things into an SCM repository is not Configuration Management
  any more than karaoke is opera.</p>

<p>A well-maintained SCM repository is so much more than version control, and
  should provide:</p>

<ul>
<li>The ability to recreate any identified baseline, at any time;</li><li>Meaningful statistics on what is changing, when and by whom;</li><li>Management information, such as “<em>how many new defects were introduced
      by the refactoring of component ‘X’?</em>”</li>
</ul>

<p>In order to be truly effective in a project, the SCM repository should store
  all of the artifacts that form part of a baseline or a release.</p>

<b>Source Code</b>
<p>Most development projects simply store the code that is being developed and
  their use of the SCM repository is no more sophisticated than this.</p>

<b>Data</b>
<p>Most applications nowadays are not just source code. Take the example of a
  modern computer game – the vast majority of the code base is made up
  of artifacts other than code such as audio clips, pictures and movie clips.</p>

<b>Database Structure and Contents</b>
<p>Where an application relies on a database this database will have a schema
  and structure that may change from release to release – this schema must
  be captured.</p>

<p>There will normally also be seed data for the database which should be considered
  as part of the baseline.</p>

<b>Application Configuration</b>
<p>In a large distributed application, the software being developed will sit
  atop a number of pieces of software (e.g. application servers, web servers
  and message queues).</p>

<p>The configuration of these underlying applications have an effect on the quality – or
  otherwise – of the software being developed and should, therefore, be
  considered part of the baseline for a release.</p>

<b>Environment Configuration</b>
<p>The underlying environment and infrastructure is a key component of the project,
  particularly in the case of distributed applications.</p>

<p>Such banal considerations as DNS zone files, user account information and
  system parameters have to be considered as some of the moving parts which affect
  the application and therefore be placed under configuration control.</p>

<p>This is of particular importance when there is more than one environment involved
  in the project (e.g. a development environment and a separate test environment)
  since the question of “<em>are these environments the same?</em>” crops
  up again and again.</p>

<p>Best Practice: Everything that can be changed, and affect the behaviour of
  the application, is a candidate for configuration control</p>

<h2>The Point of Labelling</h2>

<p>It is a common misconception that simply applying labels, or tags, to the
  SCM repository creates a baseline but this is only partly true without corresponding
  records of:</p>

<ul>
<li>What label has been applied;</li><li>When that label has been applied;</li><li>Why it has been applied (i.e. what milestone, or other external event,
    the label is associated with);</li>
</ul>

<p>The use of a naming convention for labels can deceive even further. For example,
  a project that uses a date-based labeling convention (<em>dd_mm_yyyy</em>)
  will have several labels of the form (<em>03_05_2004</em>, or <em>09_06_2004</em>)
  and will reasonably assume that they have some kind of record of the baseline
  on those dates.</p>

<p>But what was happening in the project on those dates? Was the <em>03_05_2004</em> label
  applied immediately before a release to test, or immediately after?</p>

<p>Best Practice: Labels should be used to identify and inform about events in
  the project</p>

<b>Don’t Label If There Is No Point</b>
<p>This may seem like stating the obvious, but there should be a reason for a
  label being applied – the whole purpose of labeling is to identify some
  event in the development cycle that may need to be re-visited.</p>

<p>To this end, labels can be divided into two categories:</p>

<ul>
<li>Point-in-time<br>
    Associates particular versions with a particular calendar date, or other
  event that is fixed in time (e.g. <em>MONTH_END_JAN_2004</em>, or <em>RELEASE_1_0_1</em>);</li><li>Point-in-process<br>
    Associates particular versions with events in the project that may recur
      at a later stage (e.g. <em>LATEST_RELEASE</em>, or <em>CURRENTLY_IN_UAT</em>);</li>
</ul>

<p>Best Practice: Every label should have a point, whether point-in-time or point-in-process</p>

<h2>Management Information</h2>

<p>The job of the Project Manager, ultimately, is to bring the project to a successful
  conclusion. If this were an easy task that happened by default, then there
  would be no need for a Project Manager.</p>

<p>In order to be able to do this job well, a Project Manager needs information.
  He needs to know what is going on in the project – who is doing what,
  who is working on which components, and a wealth of information can be obtained
  from a well-managed SCM repository:</p>

<ul>
<li>What is changing in the environment – what has changed since a given
    point in time or how often particular
  elements are changing;</li><li>Who is changing things in the environment;</li><li>Why things are changing in the environment;</li>
</ul>

<p>Of course, the final item in the list requires that committers are using descriptive
  comments to indicate why they are marking a particular change. A well-managed
  SCM repository should enforce this.</p>

<p>Best Practice: The SCM repository should provide meaningful, and accessible,
management information</p>

<h2>Build Best Practices</h2>

<p>As explained at the beginning of this document, the term “build” means
  different things to different people. The most common interpretation is the
  one used by developers, where the term “build” describes the compilation
  and assembly step of their development activities but this narrow interpretation
  is a common cause of problems and over-runs, on development projects.</p>

<h2>Building is not Compiling</h2>

<p>At the outset of the project, the Project Manager will ask the question “<em>how
    long to set up the build?</em>” and a developer – thinking of
    compilation and assembly – will answer something like “<em>1
    day”</em> – a task and duration which is then duly marked on
    the project plan and development begins.</p>

<p>Later in the project, when it is time to start deploying and testing the application,
  this “build” needs to be refactored to accommodate the deployment
  and test tasks. In doing so, it turns out that the way the application is being
  assembled is not conducive to it being deployed or tested correctly – so
  the compilation and assembly staged need to be refactored as well.</p>

<p>In the meantime, the development team sits on its hands whilst the “build” is
  refactored to accommodate the needs of the project – valuable time is
  lost whilst the deadline continues to advance.</p>

<p>Best Practice: Know what will be required of the build before starting to
  write the scripts</p>

<h2>Don’t Throw Out The Baby With The Bathwater</h2>

<p>From a build perspective, projects with similar architecture (both in terms
  of the team and the application) will have similar attributes. There will obviously
  be some changes required, but these will tend to follow the 80/20 rule to a
  large degree.</p>

<p>For example, a web application that is being developed by an in-house team
  and that will be deployed to a Tomcat servlet container and Oracle database
  will follow largely the same steps and require largely the same deployable
  artifacts.</p>

<p>A good SCM repository will enable the latest versions of boiler-plate build
  scripts for such an application to be found. These can be used almost off-the-shelf – meaning
  that development can start apace without having to wait on the build to be
  constructed for similar applications .</p>

<p>Best Practice: Well-crafted builds are re-usable and should be re-used</p>

<h2>The Architecture Drives The Build&lt;</h2>

<p>Following on from the previous section, it should be clear that the architecture
  of what is being developed – and the structure of the team(s) developing
  it – will dictate how the build should look.</p>

<p>There is little value to be gained in trying to retrofit build scripts for
  a computer game (developed by 12 people all in the same room) into a project
  to produce a large J2EE application with development occurring at six different
  sites around the world.</p>

<p>Best Practice: Well-crafted builds are flexible, but a “one-size-fits-all” approach
  can be costly</p>

<h2>Management Information</h2>

<p>There are a number of people who need information that the build can provide:</p>

<ul>
<li>The Project Manager needs to track overall progress against defined milestones – number
  of outstanding defects, whether a committed release date will be met etc;</li><li>Development leads need to be sure that the code is of the quality that
    they require – test reports, bug analysis patterns, code metrics, document
  and UML generation etc;</li><li>The deployment team need to know that the artifacts will work in their
    target environment, and that the environment is as the application expects
    it to be. They also need to know whether two (or more) environments are “<em>the
  same</em>”;</li><li>The test team need to have confidence that they are testing against a known
    baseline, and whether defects that they see have been rectified in development
  (or whether they are re-appearing after already being fixed);</li><li>Everybody needs to be able to communicate effectively using the same language,
    and have a common terminology for release versions – particularly if
  there are multiple threads of development;</li>
</ul>

<p>A good build infrastructure will provide all of the above information, and
  more besides.</p>

<p>Best Practice: The build should tell all project participants what they need
to know</p>

<h2>Deployment Best Practices</h2>

<p>Considering that it is generally an important milestone on a project plan,
  normally resulting in payment or a staged payment, deployment is one of the
  most overlooked areas of software development.</p>

<p>The normal course of events is:</p>

<ol>
<li>Release artifacts are created;</li><li>Some installation and release notes are cobbled together in the form of
  a README;</li><li>The deployment team work frantically to install and configure the application – the
    testing team (or, worse still, the customer) are idle and unproductive in
  the meantime;</li><li>Some symptoms are found which are suspected to be application defects;</li><li>The development team blame the environment;</li><li>The deployment team blame the application;</li><li>Repeat (5) and (6) <em>ad nauseam</em>.</li>
</ol>

<p>When a documentation team are also considered - responsible for creating documentation
  that the end user will need to install, configure and use the application – the
  situation becomes even more difficult.</p>

<p>This situation can be avoided by planning for deployment from the beginning.
  Deployment is an inevitable part of software development, yet it always seems
  to take people by surprise.</p>

<p>Best Practice: Know that deployment is inevitable, and incorporate it into
  the automated processes</p>

<h2>Deployment Is Not Installation</h2>

<p>As part of normal development activities, artifacts are installed into sandbox
  environments – and test environments – many times. But this is
  not deployment, this is installation.</p>

<p>In order to get an application into its production environment, be that an
  internal environment or on hosted-infrastructure, a number of hurdles must
  be overcome:</p>

<ul>
<li>The application must pass UAT;</li><li>The application must be installed and configured correctly:</li><li>All pre-requisites for the application must be satisfied;</li><li>The end customer must accept the handover;</li>
</ul>

<p>Deployment is that point in the life of an application where it starts to
  produce a return on investment. “<em>Launch</em>”, “<em>Go-live</em>”, “<em>Release</em>”, “<em>First
  Customer Shipment</em>” are all phrases which describe the same event.</p>

<p>Best Practice: Deployment is the point where an application starts to provide
  a return on the development investment.</p>

<h2>The Environment Is a Refactorable Component</h2>

<p>This point cannot be stressed enough, particularly in large distributed applications.</p>

<p>Every application, large or small, has a runtime environment in which it operates.
  In a simple desktop application, this is a standalone machine (such as a PC).
  In larger applications, this will be a combination of machines (e.g. an application
  server and a database) operating together to provide the runtime environment.</p>

<p>In either case, the application expects certain facilities to be available
  from the runtime environment and will function incorrectly – or cease
  to function – if these are not present .</p>

<p>The environment itself, whether standalone or a network, contains many moving
  parts that can be independently configured. IP addresses, or hostnames, can
  be changed. User privileges can be modified or revoked. Files and directories
  can be removed. Each of these can have an effect on the way that the application
  behaves.</p>

<p>In an environment that is owned and managed internally this can be bad enough.
  In an environment that is owned and managed by an external third party, and
  where project success is contingent upon successful UAT in that environment,
  this can be disastrous.</p>

<p>Best Practice: Be able to identify whether the deployment environment is as
  prescribed, and “<em>fit for deployment</em>”</p>

<b>Environment Verification Testing</b>
<p>One of the most common questions that arises in development projects containing
  more than one environment is, simply, “<em>are these environments the
  same?</em>” and its answer can be elusive.</p>

<p>It is essential to be able to answer that question – quickly and accurately – so
  that any perceived defects in the application can be categorised as “<em>defect</em>” or “<em>environmental</em>”.</p>

<p>This ability becomes particularly poignant where on or more of the environments
  are owned by different teams, or organisations.</p>

<p>Best Practice: Be able to prescribe what the deployment environment should
  look like, and have a capability to test it quickly.</p>

<b>Regression Testing</b>
<p>The environment, as explained earlier, is a refactorable component. It can
  be changed, and parts can be moved or deleted. However, unlike application
  code, changes may need to be made to the environment in response to external
  events (e.g. hardware failure, or security policies).</p>

<p>Applications, particularly complex ones, use regression tests to ensure that
  observed behaviour after a change is exactly as it was before the change was
  made. The same should be true of the environment.</p>

<p>Best Practice: Automated regression tests for the environment that will compare
  observed behaviour both before and after changes are made.</p>

<p>For example, suppose that a number of operating system patches or service
  packs are applied to an environment where the application has been, or will
  be, deployed. How are these tested? Do you wait for users, or testers, to start
  calling to say that there are problems?</p>

<p>Or do you make sure that you know what problems have been introduced before
  your users do?</p>

<b>Configuration Management</b>
<p>As stated earlier, the SCM repository should be used to store any artifact
  that can be changed and that may have an effect on the environment.</p>

<p>It may not seem obvious, but some of the most obscure environmental changes
  can cause an application to fail:</p>

<ul>
<li>Hostname resolution;</li><li>Non-existent user or group accounts;</li><li>IP and network connectivity;</li><li>Existence, or otherwise, of files and directories ;</li><li>Application or operating system configuration files;</li>
</ul>

<p>It is essential that these environmental variables be placed under configuration
  control and able to be identified as part of a baseline.</p>

<p>Best Practice: Environmental artifacts that are not part of the application
should be part of the baseline</p>

<h2>Automate, Automate, Automate</h2>

<p>Every single task that is performed as part of a development project – throughout
  the entire lifecycle – can be placed into one of two categories:</p>

<ol>
<li>Tasks which require some form of human judgment;</li><li>Tasks which do not;</li>
</ol>

<p>Tasks which fall into the first category can use some degree of automation,
  but should stop and wait for human intervention wherever judgment is required.</p>

<p>Tasks in the second category should be automated. There is no value in having
  expensive resources employed to do mechanical or repetitive tasks that a computer
  could do more quickly, accurately and consistently.</p>

<p>Best Practice: Automate anything that does not require human judgment</p>

<p>A note of caution - it may be tempting to think that automation will increase
  productivity on its own, but this is not necessarily the case. Automating an
  inefficient process will simply magnify its inefficiency – as explained
  in the section on <strong><em>Software Tools are Only Part of the Answer</em></strong>.</p>

<p>This, and it is worth repeating, is a common error – to assume that
  automated build software alone will improve productivity.</p>

<p>Best Practice: Do not automate inefficient processes, or you will only maximize
the inefficiency</p>

<h2>About BuildMonkey</h2>

<p>BuildMonkey is a division of Nemean Technology Limited - a leading technical
  innovator specialising in Agile Deployment and build management.</p>

<p>We have over a decade of experience in helping clients increase productivity
  in their build, integration and test cycles. We have a track record of massively
  reducing costs and defects through process automation and proven methodologies.</p>

<p>Formed in 1999, and profitable every quarter, we invented the discipline of
  BuildMaster - <strong>we are the original and the best.</strong></p>

<p>We provide specialist Build Management products and services - when all you
  do is Build Management, you get pretty good at Build Management. Our world-class
  Professional Services staff are the best in their field, complemented by original
  software products of the finest quality.</p>

<p>We aim to be the leading provider of Build Management products and services
  in the UK by providing excellent service to our customers, and by empowering
  Software Project Managers to aim for <strong><em>release on-time, on-budget,
  with no defects</em></strong>.</p>

<h2>About the Author</h2>

<p>John Birtley has been a specialist in Configuration and Build Management since
  1994 with a focus on deployment - particularly the packaging and installation
  of developed applications. He has worked for a number of blue-chip organisations
  including Sun Microsystems, Hewlett Packard, Sony and Ericsson in the transition
  from development to deployment. BuildMonkey was launched in January 2004, to
  package and commoditise this cumulative experience under the title of "Agile
  Deployment". He lives in Southampton, where dogs and children conspire to take
what little spare time he has. </p>



<p align="center">
<a href="http://www.theserverside.com/articles/content/BuildManagement/article.html">PRINTER FRIENDLY VERSION</a>
<br>
<img src="http://www.theserverside.com/images/tss_white.gif" align="middle">
</p>
<img src ="http://www.blogjava.net/briansun/aggbug/2644.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-03-31 11:12 <a href="http://www.blogjava.net/briansun/articles/2644.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CLR Loader and Java Class Loader Compared[转]</title><link>http://www.blogjava.net/briansun/articles/2520.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Mon, 28 Mar 2005 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/2520.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/2520.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/2520.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/2520.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/2520.html</trackback:ping><description><![CDATA[<div class="postText">
		<p class="MsoNormal" style="margin: 0in 0in 0pt;">Flier Lu<span style="font-family: 宋体;" lang="ZH-CN">问到</span>CLR Loader<span style="font-family: 宋体;" lang="ZH-CN">和</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">有什么不一样。要回答这个问题不容易，因为我对</span>Java<span style="font-family: 宋体;" lang="ZH-CN">一窍不通。但既然问题提出来了，打肿脸来充胖子也得回答啊。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">于是今天下午我在</span>google<span style="font-family: 宋体;" lang="ZH-CN">上逛了一圈，找了些关于</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">的文章看了看。我的结论是，和</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">类似的东东，在</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">里是不存在的。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">简单的说，</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">里不存在一个类似于</span>Java.Lang.ClassLoader<span style="font-family: 宋体;" lang="ZH-CN">的东西。所以你无法实现你自己的</span>CLR Loader<span style="font-family: 宋体;" lang="ZH-CN">。</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">里只有一个</span>Loader<span style="font-family: 宋体;" lang="ZH-CN">，那就是</span>CLR Loader<span style="font-family: 宋体;" lang="ZH-CN">。当然，</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">提供了自己独特的方式让你做动态装载。你所拥有的自由度是远比</span>Java<span style="font-family: 宋体;" lang="ZH-CN">要大得多。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">下面是具体分析。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">我对</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">的理解主要是从这两篇文章里来的。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;">“Inside Class Loader” by Andeas Schaefer (<a href="http://www.onjava.com/lpt/a/4337">http://www.onjava.com/lpt/a/4337</a>) <span style="font-family: 宋体;" lang="ZH-CN">和</span><span lang="ZH-CN"> </span>“The basics of Java Class Loaders” by Chuck McManis (<a href="http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth_p.html">http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth_p.html</a>)<span style="font-family: 宋体;" lang="ZH-CN">。我看了看</span>JVM Spec<span style="font-family: 宋体;" lang="ZH-CN">。但是我觉得不如上面两篇文章清楚。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">先说</span>Java<span style="font-family: 宋体;" lang="ZH-CN">里的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">吧。</span>Java<span style="font-family: 宋体;" lang="ZH-CN">里的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">就是</span>Class <span style="font-family: 宋体;" lang="ZH-CN">。</span>Class<span style="font-family: 宋体;" lang="ZH-CN">就是</span>Namespace + class name.<span style="">&nbsp; </span>Class<span style="font-family: 宋体;" lang="ZH-CN">通过</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">来装载的。</span>System Class Loader<span style="font-family: 宋体;" lang="ZH-CN">缺省的话只在</span>CLASSPATH<span style="font-family: 宋体;" lang="ZH-CN">中寻找</span>Class<span style="font-family: 宋体;" lang="ZH-CN">。如果你要在</span>CLASSPATH<span style="font-family: 宋体;" lang="ZH-CN">之外转载</span>Class<span style="font-family: 宋体;" lang="ZH-CN">的话，你就需要自己的</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">。如果两个</span>Class<span style="font-family: 宋体;" lang="ZH-CN">有相同的名字，并且在同一个</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">里，那么它们就被</span>JVM<span style="font-family: 宋体;" lang="ZH-CN">认为是相同的，可以互相赋值。如果有一个不一样的话，它们就被认为是不一样的。互相赋值会发生</span>ClassCaseException<span style="font-family: 宋体;" lang="ZH-CN">。换句话说，</span>Class name + Class Loader<span style="font-family: 宋体;" lang="ZH-CN">是一个</span>Type<span style="font-family: 宋体;" lang="ZH-CN">的独特的</span>ID<span style="font-family: 宋体;" lang="ZH-CN">。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;">Java<span style="font-family: 宋体;" lang="ZH-CN">的这个模型有很多问题。首先它把</span>Class name<span style="font-family: 宋体;" lang="ZH-CN">做为</span>Type<span style="font-family: 宋体;" lang="ZH-CN">的</span>ID<span style="font-family: 宋体;" lang="ZH-CN">。两个</span>Class<span style="font-family: 宋体;" lang="ZH-CN">如果有同样的名字，但是实际内容不一样的话，如果它们被同一个</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">装载，</span>JVM<span style="font-family: 宋体;" lang="ZH-CN">会认为它们是同一个</span> Type<span style="font-family: 宋体;" lang="ZH-CN">。这个太搞笑了。结果就是</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">必须要有一些特别的办法来管理</span>Class name<span style="font-family: 宋体;" lang="ZH-CN">。一般的办法是加一个前缀，比如说</span>Class<span style="font-family: 宋体;" lang="ZH-CN">的</span>URL<span style="font-family: 宋体;" lang="ZH-CN">。如果</span>Namespace<span style="font-family: 宋体;" lang="ZH-CN">管理不好的话，很容易就是安全漏洞。这是为什么</span>JVM Spec<span style="font-family: 宋体;" lang="ZH-CN">里提到</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">必须要让</span>Parent Class Loader<span style="font-family: 宋体;" lang="ZH-CN">先搜索</span>Class<span style="font-family: 宋体;" lang="ZH-CN">，再自己寻找。而且</span>Class loader<span style="font-family: 宋体;" lang="ZH-CN">必须要保存</span>Class resolution<span style="font-family: 宋体;" lang="ZH-CN">的结果，这样下次</span>Class resolution<span style="font-family: 宋体;" lang="ZH-CN">的时候，</span>Class loader<span style="font-family: 宋体;" lang="ZH-CN">会返回同样的结果。</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">有太多的限制，同时又有太多的责任。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">另一个问题是共享问题。如果同一个</span>Class<span style="font-family: 宋体;" lang="ZH-CN">被两个不同的</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">装载的话，</span>JVM<span style="font-family: 宋体;" lang="ZH-CN">认为这两个</span>Class<span style="font-family: 宋体;" lang="ZH-CN">不是同一个</span>Type<span style="font-family: 宋体;" lang="ZH-CN">，不能互相赋值。结果就是</span>Class<span style="font-family: 宋体;" lang="ZH-CN">无法共享。被不同</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">装载的</span>Class<span style="font-family: 宋体;" lang="ZH-CN">无法直接对话。直接对话会产生</span>linkage<span style="font-family: 宋体;" lang="ZH-CN">错误。它们只能间接对话，比如通过</span>Interface<span style="font-family: 宋体;" lang="ZH-CN">，或者共同的</span>Base Class<span style="font-family: 宋体;" lang="ZH-CN">。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">还有一个问题是</span>Versioning<span style="font-family: 宋体;" lang="ZH-CN">。因为</span>Java<span style="font-family: 宋体;" lang="ZH-CN">的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">里只有名字，所以当你看到一个</span>Type<span style="font-family: 宋体;" lang="ZH-CN">的时候，你无法知道它是第一版，还是第二版。所以如果你需要第二版，但是</span>Class loader<span style="font-family: 宋体;" lang="ZH-CN">给你装载了第一版的时候，祈祷吧。也许上帝能救你。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">现在回过头来看看</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">的模型。</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">包括两部分：</span>Class name + Assembly Name<span style="font-family: 宋体;" lang="ZH-CN">。</span>Class name<span style="font-family: 宋体;" lang="ZH-CN">是和</span> Java<span style="font-family: 宋体;" lang="ZH-CN">的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">类似的东西，就是</span>namespace<span style="font-family: 宋体;" lang="ZH-CN">。</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">是</span>Java<span style="font-family: 宋体;" lang="ZH-CN">没有的东西。</span>Assembly Name<span style="font-family: 宋体;" lang="ZH-CN">的属性包括</span>Name, Version, Culture, PublicKey(Token)<span style="font-family: 宋体;" lang="ZH-CN">。</span><span lang="ZH-CN"> </span><span style="font-family: 宋体;" lang="ZH-CN">如果两个</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">有一个属性不一样，那么它们就认为是不一样的。两个</span>Type<span style="font-family: 宋体;" lang="ZH-CN">如果有同样的</span>Class name<span style="font-family: 宋体;" lang="ZH-CN">，但是</span>Assembly Name<span style="font-family: 宋体;" lang="ZH-CN">不一样的话，它们也认为是不一样的。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;">CLR<span style="font-family: 宋体;" lang="ZH-CN">的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">引用总是包括</span>Class name <span style="font-family: 宋体;" lang="ZH-CN">和</span> Assembly Name<span style="font-family: 宋体;" lang="ZH-CN">的。所以</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">在寻找一个</span>Type<span style="font-family: 宋体;" lang="ZH-CN">的时候，主要是寻找</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">。找到了</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">之后，</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">看看这个</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">里有没有这个</span>Class<span style="font-family: 宋体;" lang="ZH-CN">。有的话就万事大吉，没有的话就是</span>TypeLoadException<span style="font-family: 宋体;" lang="ZH-CN">。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;">CLR<span style="font-family: 宋体;" lang="ZH-CN">区别</span>Type<span style="font-family: 宋体;" lang="ZH-CN">主要靠</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">。</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">有</span>PublicKey(Token)<span style="font-family: 宋体;" lang="ZH-CN">。别人无法冒充你。所以象</span>Java<span style="font-family: 宋体;" lang="ZH-CN">里的</span>namespace<span style="font-family: 宋体;" lang="ZH-CN">的问题就不存在了。</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">有自己的</span>Version<span style="font-family: 宋体;" lang="ZH-CN">。你要第二版的时候</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">不会装载第一版给你。所以象</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">那样的限制，责任和问题都不存在了。从这个角度上讲，这正是为什么</span>CLR<span style="font-family: 宋体;" lang="ZH-CN">里没有象</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">那样的东西。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">但并不是说你就不能动态装载了，而是说你动态装载的时候就不用考虑那些垃圾了。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">关于共享的问题，因为没有了你自己的</span>Class loader<span style="font-family: 宋体;" lang="ZH-CN">，所以任何</span>Type<span style="font-family: 宋体;" lang="ZH-CN">都可以直接对话。同样的</span>Type<span style="font-family: 宋体;" lang="ZH-CN">也不会因为</span>Class Loader<span style="font-family: 宋体;" lang="ZH-CN">不一样而被认为不一样。</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;">CLR Loader<span style="font-family: 宋体;" lang="ZH-CN">有自己的规则怎么寻找</span>Assembly<span style="font-family: 宋体;" lang="ZH-CN">。它先看</span>GAC<span style="font-family: 宋体;" lang="ZH-CN">，再看你的程序目录。都没有的话它还有一个</span>AssemblyResolveEvent<span style="font-family: 宋体;" lang="ZH-CN">去问你，看你能不能提供。如果你要动态装载的话，你有</span>Assembly.Load, Assembly.LoadFrom, Assembly.LoadFile, Assembly.Load(byte[])<span style="font-family: 宋体;" lang="ZH-CN">。你可以提供</span>privateBin<span style="font-family: 宋体;" lang="ZH-CN">，你也可以提供</span>codebase hint<span style="font-family: 宋体;" lang="ZH-CN">。你还能有</span>policy<span style="font-family: 宋体;" lang="ZH-CN">。总之，你想从哪找，就可以去哪找。细节问题我就不多说了。你可以去看</span><a href="http://msdn.microsoft.com/">MSDN</a><span style="font-family: 宋体;" lang="ZH-CN">，</span>Suzanne<span style="font-family: 宋体;" lang="ZH-CN">的</span><a href="http://weblogs.asp.net/suzcook">Blog</a><span style="font-family: 宋体;" lang="ZH-CN">，</span>Alan<span style="font-family: 宋体;" lang="ZH-CN">的</span><a href="http://weblogs.asp.net/alanshi">Blog</a><span style="font-family: 宋体;" lang="ZH-CN">，和我的英文</span><a href="http://weblogs.asp.net/junfeng">Blog</a>. </p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: 宋体;" lang="ZH-CN">结论，</span>CLR Loader<span style="font-family: 宋体;" lang="ZH-CN">远比</span>Java Class Loader<span style="font-family: 宋体;" lang="ZH-CN">要Secure, </span>Powerful and&nbsp;Flexible<span style="font-family: 宋体;" lang="ZH-CN">。</span></p>
	</div>

	<img src ="http://www.blogjava.net/briansun/aggbug/2520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-03-28 11:34 <a href="http://www.blogjava.net/briansun/articles/2520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CLR和JRE的运行机制的初步总结[转]</title><link>http://www.blogjava.net/briansun/articles/2517.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Mon, 28 Mar 2005 03:22:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/2517.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/2517.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/2517.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/2517.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/2517.html</trackback:ping><description><![CDATA[<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody><tr><td width="100%"><span class="postdetails">标题: CLR和JRE的运行机制的初步总结</span></td>
				<td nowrap="nowrap" valign="top"><a href="file:///C:/workplace/bacchus_doc/posting.php?mode=quote&amp;p=567&amp;sid=41b0cf50b4510221cfae9a122df5a850"><img src="file:///C:/workplace/bacchus_doc/templates/subSilver/images/lang_chinese_simplified/icon_quote.gif" alt="引用回复" title="引用回复" border="0"></a>    <a href="file:///C:/workplace/bacchus_doc/addblog.php?type=javaeye&amp;title=CLR%E5%92%8CJRE%E7%9A%84%E8%BF%90%E8%A1%8C%E6%9C%BA%E5%88%B6%E7%9A%84%E5%88%9D%E6%AD%A5%E6%80%BB%E7%BB%93&amp;t=146&amp;postdays=0&amp;postorder=asc&amp;start=0&amp;p=567&amp;sid=41b0cf50b4510221cfae9a122df5a850"><img src="file:///C:/workplace/bacchus_doc/templates/subSilver/images/icon_blog.gif" alt="将这个帖子加入我的Blog" title="将这个帖子加入我的Blog" border="0"></a></td>
			</tr>
			<tr>
				<td colspan="2"><hr></td>
			</tr>
			<tr>
				<td colspan="2"><span class="postbody">概念比较： 
<br>
Java C# 
<br>
byte code IL(字节码，中间语言) 
<br>
jvm.dll mscrolib.dll,mscrojit.dll(虚拟机) 
<br>
JRE CLR(运行环境) 
<br>
JDK .Net Framework(开发框架) 
<br>
package assembly(类库，程序集) 
<br>

<br>

<br>
一、关于类库的版本管理问题 
<br>

<br>
Java和C#代码运行要依靠其运行环境(JRE,CLR)和运行环境带的基础类库(C#称为配件或者程序集Assembly)，此外还会有一些第三方的
类库或者自己开发的类库。如果运行环境版本不一致，或者引用的类库版本不一致都会带来程序不能正常运行。比如一个Java程序是在JDK1.2上开发，如
果在JRE1.4上运行，一般情况下可以向下兼容，但也有例外，有些GUI程序在JDK1.4上面运行结果很可能会不同。 <br>

<br>
JRE的版本管理 
<br>

<br>
Java的解决办法是每个程序自己携带一套JRE。 
<br>
我的机器上已经被安装了好多套JRE和JDK了(JDK包括了同版本的JRE，此外还包括有编译器和其它工具)，它们分别是： 
<br>
BEA Weblogic Server 7.0 自带一套 JDK1.3.1_02 
<br>
我下载了一套最新的JDK1.4.1_02 
<br>
JBuilder9自带一套JKD1.4.1_02 
<br>
Oracle8.1.7自带一套JRE1.1.7 
<br>
Ration Rose自带一套JDK1.3 
<br>
DreamWeaver自带一套JDK1.3 
<br>
6套JRE，每套JRE都被各自安装到不同的目录，不会互相影响。当在控制台执行java.exe，操作系统寻找JRE的方式如下： 
<br>
先找当前目录下有没有JRE 
<br>
再找父目录下有没有JRE 
<br>
接着在PATH路径中找JRE 
<br>
注册表HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\ 查看CurrentVersion的键值指向哪个JRE 
<br>
最常用的是在PATH路径中找JRE，一般情况下，自己的程序运行之前都会先在批处理文件里面临时设置PATH，把自己用的JRE放到PATH路径最前面，所以肯定会运行自己带的JRE，不会造成版本混乱。 
<br>

<br>
.Net Framework的版本管理 
<br>

<br>
.Net
Framework被固定安装在C:\Winnt\Microsoft.NET\Framework\v版本号\目录下，听说刚发行的.Net
Framework1.1已经对1.0做了很多改进，也许在旧版本的.Net Framework开发的程序在往新版本上面迁移的时候需要部分修改。 <br>

<br>

<br>

<br>
JRE的基础类库 
<br>

<br>
JRE自带的基础类库主要是JRE\lib\rt.jar这个文件，包括了Java2平台标准版的所有类库。和JRE的版本一致。 
<br>

<br>
.Net Framekwork的核心类库 
<br>

<br>
.Net Framekwork的核心类库被放置在C:\Winnt\assembly\gac\目录下，按照不同的名称空间放在不同目录中，不像JRE打成了一个包。并且可以同时存在不同的版本，例如： 
<br>
某类库1.0版本 C:\Winnt\assembly\gac\名称\1.0\名称.dll 
<br>
某类库1.1版本 C:\Winnt\assembly\gac\名称\1.1\名称.dll 
<br>
这样做，虽然很灵活，可以随时把类库更新到最新的状态，但是很容易带来版本管理的复杂度，造成版本不一致。 
<br>

<br>

<br>

<br>
JRE类库的查找方法和版本管理 
<br>

<br>
JRE中由ClassLoader负责查找和加载程序引用到的类库，基础类库ClassLoader会到rt.jar中自动加载，其它的类库，
ClassLoader在环境变量CLASSPATH指定的路径中搜索，按照先来先到的原则，放在CLASSPATH前面的类库先被搜到，Java程序启
动之前建议先把PATH和CLASSPATH环境变量设好，OS通过PATH来找JRE，确定基础类库rt.jar的位置，JRE的
ClassLoader通过CLASSPATH找其它类库。但有时候会出现这样的情况，希望替换基础类库中的类库，那么也可以简单的通过-
Djava.endrosed.path=...参数传递给java.exe，于是ClassLoader会先于基础类库使用
java.endrosed.path参数指定路径的类库。因此Java的版本管理是非常简单有效的，也许很原始，不过很好用，简单就不容易出错。(所以
我很奇怪Eric Ramond为什么批评Java的类库管理机制，他还居然批评Java的接口，令人怀疑他对Java的了解程度) <br>

<br>
.Net Framework的类库管理机制 
<br>

<br>
.Net Framework的类库管理机制相当强大和复杂，分为私有类库和共享类库。 
<br>
私有类库就放在exe程序当前路径下，或其相对路径中，只有当前程序可见。 
<br>
共享类库需要在GAC(Global Assembly
Cache)中注册，注册过程比较复杂，首先要用工具生成公开/私有密钥对，然后结合密钥和类库版本号连编，最后使用工具注册到GAC中好以后,会被放在
"C:\Winnt\assembly\gac\类库的名称空间\版本号\"目录下，不同的类库版本在注册的时候会按照版本号分开放置： <br>
某类库1.0版本 C:\Winnt\assembly\gac\名称\1.0\名称.dll 
<br>
某类库1.1版本 C:\Winnt\assembly\gac\名称\1.1\名称.dll 
<br>

<br>
也就是可以同时存在一个类库的n个版本，至于在程序中用哪个版本，在程序的配置文件中声明，CLR会根据声明来调用相应的版本的类库。我觉得.Net实现
方法未免太复杂了一些，将所有共享类库都塞到一个系统目录下，并且同一个类库还有n个版本，将来.Net第三方开发的类库逐渐丰富起来以后，.Net类库
的GAC也会越来越庞大，会不会也搞得和Windows注册表一样难以维护？软件发布到服务器上的时候，类库要再注册一次，服务器会逐渐形成一个庞大的树
状的GAC，GAC里面存放着组件的n个版本。试想经过一段时间之后，C:\Winnt\assembly\gac\目录会越来越庞大，有的组件甚至有n
个版本都放在那里，你又不敢随便删除，不知道是不是有程序需要使用，我不明白MS为什么要把这么简单的事情搞到这么复杂？ <br>

<br>

<br>
综上所述，Java的版本管理方式简单而有效，C#的版本管理方式功能强大，不过是不是太复杂了？会不会搞成第二个注册表一样的东西？ 
<br>

<br>

<br>

<br>
二、虚拟机启动和加载类库的方式 
<br>

<br>

<br>
Java的虚拟机启动和加载类库 
<br>

<br>
在Console执行java.exe xxx命令以后，如前所述的寻找JRE，OS找到JRE目录，根据java.exe的传递参数，选择加载Server版的jvm.dll还是Client版的jvm.dll，然后加载jvm.dll，把控制权交给jvm.dll。 
<br>

<br>
接下来，jvm.dll进行初始化，分配内存等等动作，然后在CLASSPATH路径中寻找class，找到class以后，寻找class中的程序入口
点Main函数，然后从Main函数执行程序，在执行过程中，使用ClassLoader动态加载一系列引用到的类。当调用到native方法时，
jvm.dll告诉OS在JRE\bin目录下寻找某某DLL文件，调入内存，于是实现了JNI调用。 <br>

<br>

<br>
.Net的虚拟机的启动推测 
<br>

<br>
我对.Net的虚拟机的启动过程还一知半解，自己写了一些例程，并且用内存工具来检测观察，推测.Net的运行机制，先来抛砖引玉，请熟悉Windows平台编程的朋友指教。.Net有3个目录中的文件在执行的时候会被加载 
<br>

<br>
1、C:\WINNT\Microsoft.NET\Framework\v版本号\ 
<br>
该目录下的mscorlib.dll,mscorrsn.dll,mscorwsk.dll,mscorjit.dll是核心DLL，大概是运行虚拟机的
必要文件，其中mscrolib.dll是入口点。此外，该目录下还有一些.Net的System名称空间的IL类库，与C:\Winnt\
assembly\gac\相应目录下的IL类库完全一样，这些是最核心的基础类库。.Net的编译器，检查器等等工具软件也在该目录，推测System
名称空间的核心类库之所以在这个目录下copy一份是因为作为.Net的编译器等工具的私有类库之用。 <br>

<br>
2、C:\Winnt\assembly\gac\ 
<br>
该目录下放置.Net共享类库，如前所述 
<br>

<br>
3、C:\Winnt\assembly\nativeimages_.Net版本号\ 
<br>
在该目录下也有一些以System名称空间开头的核心类库，推测是MS为了加快CLR的执行效率把核心类库进行本地化，编译为native
image的同名DLL。可以观察到该目录下的同名DLL文件，比GAC目录下的同名DLL文件体积大，可能是因为link底层DLL库的缘故。 <br>
某核心类库 C:\Winnt\assembly\nativeimages_.Net版本号\名称空间\.Net版本号_散列码\名称.dll 
<br>

<br>
另外值得注意的地方是有两个mscorlib.dll 
<br>
1、C:\WINNT\Microsoft.NET\Framework\v版本号\mscrolib.dll (1.88MB) 
<br>
2、C:\WINNT\assembly\NativeImages1_v版本号\mscorlib\版本号__散列码\mscrolib.dll (3.07MB) 
<br>
mscrolib.dll (1.88MB)还是一个IL码的版本，所以映射了一个native的版本的mscrolib.dll (3.07MB)，来加快CLR的速度。 
<br>

<br>

<br>
当IL的exe程序被双击执行时，OS
Loader读入程序，识别出是IL，根据IL内部的引用定义，加载mscorlib.dll，而mscorlib.dll也是IL，内部引用C:\
winnt\system32\mscoree.dll，于是再加载mscoree.dll，然后把控制权交给mscoree.dll，
mscoree.dll接着加载mscrorsn.dll，mscrowsk.dll，mscrojit.dll，为了加快mscorlib.dll的调
用，加载mscorlib.dll的native
image版本，然后由mscorlib.dll接管控制权(不知道这两个mscorlib.dll是如何来上管IL，下连native
code的？)最后寻找IL码程序的入口点Main函数，开始执行程序，在执行过程中，使用Class
Loader动态加载一系列引用到的类，在当前路径下，在共享类库的GAC中查找等等。 <br>

<br>
这里和jvm.dll不同的一点是，jvm.dll加载的基础类库和加载其它类库方式完全一样，全部都是字节码的class。而mscrolib.dll
加载以System名称开头的核心类库的时候，使用了“不正当竞争手法”。mscrolib.dll从GAC中加载共享核心类库之后，又C:\Winnt
\assembly\nativeimages_.Net版本号\名称空间\
目录下加载了核心类库的native版本，这样一来，自然CLR运行起来要快多了。特别是图形图像类库全部都有native映射版本，所以CLR上运行
GUI焉能不快？ <br>

<br>
对比CLR和JRE的加载过程，比较不同的地方是mscorlib.dll和System核心类库都有一个native image，可能这是CLR运行速度比较快的一个主要原因吧。 
<br>

<br>
分析完以后有一个特别明显的感受，Java的底层运行机制设计的特别简单，而.Net的底层运行机制设计的特别复杂。但是在企业层刚好相反，J2EE设计的特别复杂，而.Net却设计的特别简单，真是有意思！ 
<br>

<br>
Java的底层机制设计虽然简单，但是很健壮，.Net设计使得它的CLR速度快，类库管理功能强大，但是不是比Java更优秀，还要等以后慢慢看了。<br>
      <br>
RE：<br>
      <br>
</span><span class="postbody">我查了一下《.Net Essential》这本书，上面提到这样的说法。 
<br>

<br>
MS更新了Windows各个版本的OS Loader程序，使得OS Loader可以识别.Net PE格式的exe文件，当执行Windows
Native PE格式的exe文件的时候，OS Loader按照以往的方式加载系统DLL。如果是.Net PE格式的exe文件，OS
Loader加载mscorlib.dll，然后把控制权交给mscorlib.dll。<br>
      <br>
      </span></td></tr></tbody>
</table>
<img src ="http://www.blogjava.net/briansun/aggbug/2517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-03-28 11:22 <a href="http://www.blogjava.net/briansun/articles/2517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AOP@Work: AOP tools comparison, Part 2</title><link>http://www.blogjava.net/briansun/articles/1424.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Tue, 22 Feb 2005 07:30:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/1424.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/1424.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/1424.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/1424.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/1424.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: AOP@Work: AOP tools comparison, Part 2Contents:Building aspectsWeaving and performancePerformance considerationsIDE integrationFeatures comparisonAround the cornerThe bottom line ConclusionResou...&nbsp;&nbsp;<a href='http://www.blogjava.net/briansun/articles/1424.html'>阅读全文</a><img src ="http://www.blogjava.net/briansun/aggbug/1424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-02-22 15:30 <a href="http://www.blogjava.net/briansun/articles/1424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AOP@Work: AOP tools comparison, Part 1</title><link>http://www.blogjava.net/briansun/articles/1423.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Tue, 22 Feb 2005 07:29:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/1423.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/1423.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/1423.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/1423.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/1423.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: AOP@Work: AOP tools comparison, Part 1Contents:Thinning the cropIt's all about join pointsAspect comparisonSyntactic differencesSemantic similaritiesLanguage mechanicsConclusionResourcesAbout th...&nbsp;&nbsp;<a href='http://www.blogjava.net/briansun/articles/1423.html'>阅读全文</a><img src ="http://www.blogjava.net/briansun/aggbug/1423.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-02-22 15:29 <a href="http://www.blogjava.net/briansun/articles/1423.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在时间的荒原中穿梭：漫谈电影中的时间旅行（转）</title><link>http://www.blogjava.net/briansun/articles/1110.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Sat, 12 Feb 2005 16:11:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/1110.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/1110.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/1110.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/1110.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/1110.html</trackback:ping><description><![CDATA[<span class="properhead"> 
            在时间的荒原中穿梭：漫谈电影中的时间旅行<br>
<br>
</span><span class="text14">http://newyouth.beida-online.com/data/data.php3?id=zsjdhyzcs&amp;db=movie<br><span class="text12"><br>
apple0622</span>            </span> 
        
         
           
                        
&nbsp;&nbsp;&nbsp; <br>

<br>

<br>

&nbsp;&nbsp;&nbsp; 时间旅行一直是科幻电影偏爱的主题，在无涯的时间荒原中穿梭的概念带给电影制作者们无尽的想象。最早的一部关于时间旅行的影片应该算是Frank
Lloyd 1933年执导的Berkeley
Square，讲述了一位年青的美国人回到美国独立战争时期的英国并拜访了他的祖先。1960年拍摄的根据H. G.
Wells1898年所著同名小说改编的Time
Machine是早期同类电影中最著名的，后又被多次翻拍，最近的一次是2002年。1990年代之后以时间旅行为题材的影片更是层出不穷。这里我只是就
我所看过的有限的一些影片略谈一些关于时间旅行的话题。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;时间旅行最有意思莫过于其对于原有的因果关系的影响。科学界有一个著名的祖父悖论(Grandfather
Paradox)：如果一个人回到过去，杀死了自己的祖父，那麽这个人就根本不可能存在了，那麽他又怎麽能回到过去呢？要想使一部关于时间旅行的电影引人
入胜又能自圆其说，关于因果关系的处理是最基本也是最重要的。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;在我看过的电影中最常见的时间旅行对因果关系的影响要属循环因果 (Circular
Causation)了。也就是说你企图回到过去拯救一个人的生命，却发觉那人仍是无可避免的死了，而你回到过去这一行为可能正是导致他死亡的原因。例如
1995年拍摄的《12猴子》(12
Monkeys)中正是因为布鲁斯韦利斯要调查造成人类大灾难的12猴子军团而回到过去。被抓到精神病院里后，他告诉了那里的病友布拉德皮特关于猴子和病
毒的事,才启发了皮特组织传播病毒的12猴子军团，并导致了这场地球和人类的大灾难。这是循环因果的一个非常好的例子。《终结者》I也是一个很典型的例
子。机器人T-800回到过去要杀死人类领袖约翰的母亲从而消灭约翰。约翰派雷斯回到过去阻止T-800，而正是雷斯成为了他的父亲。一切好像都是注定
的。就象Matrix
Reload里那个女巫说的，一切选择都是注定的，我们只是去知道自己为甚麽选择这个选择罢了。在这些片子里，历史是不能更改的，人们回到过去只是为了完
成历史的宿命。想要更改历史的人，得到的只会是失望。《时间机器》(Time
Machine)里男主角亚历山大•哈德金博士想回去救被抢劫的人杀死的女友，他避免了抢劫，女友却被车撞死了，他再回去，女友又是另一种死法，总之是死
路一条。他一次又一次地回去目睹他女友一次又一次地不同的死亡，那种绝望的心情可想而知。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;《回到未来》I可以说是循环因果和祖父悖论的混合。马丁回到过去他的父母还没有结婚的时候。他想帮父亲赢得母亲的爱，他的母亲却喜欢上
他，这同时也对他的存在造成了威胁。为了使自己不会消失，他必须千方百计地撮合自己的父母。换句话说，马丁为了避免祖父悖论，而拼命促成循环因果。但另一
方面，马丁的出现也带来了其他的后果。原来马丁的父亲十分懦弱，经长受上司贝夫的欺负。马丁回到过去的时候使他的父亲勇敢起来。等马丁又回到现在之后发
现，他的父亲成了一名成功者，而贝夫则成了擦车的佣 人。这有些接近观察者效应理论 (Observer Effect) ，
即一个人回到过去，并且成功改变了历史，但只有时间旅行者本身知道历史改变前後有什么不同。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;另一部更典型地以观察者效应理论为基础的电影是《黑洞频率》。男主角约翰沙勒文幼年丧父，30年后偶然间他打开了父亲生前用的无线电，由
于太阳风暴的缘故，他竟然和30年前的父亲取得了通话。而这正是发生在他父亲出事之前。在他的警告下，他的父亲避免了在救火时的事故，安然活了下来。然而
由于这一改变，带来了一系列的变化。沙勒文发现他有两种记忆，一种是他父亲在他幼时死去的记忆，一种是父亲没有死的记忆。但是他周围的亲友们却都只有一种
记忆，都变成了他父亲没有死的记忆。更令他惊恐的是，他发现他母亲在照片上消失了，父亲出现了。他明白了他和父亲改变了历史，而这将造成了他母亲和其他几
位护士的死亡。为了救他的母亲，沙勒文和父亲通过无线电超时空联络，引导父亲找到了凶手，最终一家团聚。片中除了沙勒文有关于历史改变前后的不同记忆外，
其他的人都只有一种记忆，即使是他的父亲，虽然知道历史改变了，但他只能经历一种，并且只有一种回忆。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;还有一部很另类的关于时间旅行的影片是2001年拍摄的《死亡幻觉》 (Donnie
Darko)。这部在IMDB排名第88的片子是导演理查德•凯利的电影处女作，而他拍摄此片时年仅25岁。说实话，这是一部很难理解的片子。影片的背景
是1988年美国的一个小镇。Donnie
Darko是一个敏感，聪明，寡言，有精神分裂倾向，还梦游的高中生。一天晚上，他听到了某种召唤，又梦游出家门，见到了带着兔子面具的Frank.
Frank告诉Donnie地球将会在28天6小42分12秒后毁灭。也是在同一天晚上，一架飞机的引擎坠落在Donnie家的屋顶上，正好砸在
Donnie的房间，而Donnie由于梦游不在屋内而幸免遇难。更奇怪的是查不出任何航线经过这里，也就是说不止这架飞机从何而来。接下来Donnie
不断地看到Frank，并产生幻觉。他试图弄明白Frank所说的关于地球毁灭的话，在这个过程中，他找到了一本关于时间旅行的书The
Philosophy of Time Travel，而书的作者正是他们镇上一个被认为精神有毛病的老人-Grandmother death.
在一系列古怪的事情发生后，在万圣节的夜晚，也是毁灭前的最后一天，Donnie带他的女朋友去找Grandmother
death。在Grandmother
death的屋子前，他的女朋友被一辆车撞死了。Donnie一气之下开枪打死了开车的人，而后他发现这个人正是Frank。此时Donnie妈妈和妹妹
正坐在回程的飞机上，而这架飞机就要坠毁。影片的结尾，为了阻止亲人和爱人的死亡，Donnie通过时空旅行回到了最初的那一天晚上，他躺在床上，静待引
擎坠落在他的屋子里，以自己的死改变了一切。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;《死亡幻觉》最基本的理论都记载在The Philosophy of Time
Travel里。但是在片中这些理论并没有很明确的阐述。它借用了平行宇宙的概念，即有一个代表真实生活的原发宇宙(Primary
Universe)，还有一个与之平行的离线宇宙(Tangent
Universe)。在片中当来自于未来的引擎坠落时，引发了离线宇宙的产生。它是不稳定的，会在28天后毁灭。而离线宇宙的毁灭会带来整个世界的毁灭，
因为它会把原发宇宙吞噬在一个黑洞里。Donnie是一个活体接受者(Living
Receiver)，需要把引擎送回去从而关闭离线宇宙的黑洞。而Frank则是死控体 (Manipulated Dead)
，而Donnie的女友及周围的人则是活控体 (Manipulated Living)
，共同负责引导活体接受者Donnie完成他的使命。总的来说，《死亡幻觉》比以往的大部分时间旅行电影探讨得更为深入，不仅仅是把时间旅行作为一个讲故
事的噱头。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;除了因果关系的处理，影响时间旅行的还有一个重要的因素，就是时间旅行的工具。时间旅行的物理原理是利用黑洞造成的时空扭曲，旅行者通过
蠕洞可以到达另一个时空。这个蠕洞也就是所谓的时间隧道。受Wells的 Time
Machine的影响，一般来说，大部分影片都采用某种时间机器。《回到未来》里的马丁所用的是一辆以钸为能源的不锈钢跑车。在车子加速到一定程度之后就
进入到时间隧道。2002年版的《时间机器》则看上去比较古老，一看就是蒸汽时代的机器，那段哈德金博士坐在时间机器中等待时光流逝的场面十分壮观。
《12猴子》中的时光机器好像不是很舒服，而且还会出错。Contact里朱迪福斯特所乘坐的时间机器要算是最复杂最酷的了。不像前几个是地球人自己研制
的，Contact里的时间机器的建造获得了来自外太空生命的指点。在另一些影片中则根本不需要时间机器，只需要找到时间隧道的入口，一个人就可以时空穿
梭了。当然这个入口不是什麽地方都有的，往往会在一些比较古怪的地方，并且只有在一定的时间内出现。例如在Kate and
Leopold里，Leopold在某个时间跳下了纽约的布鲁克林桥，就跳跃了一个世纪的时间。而象在《黑洞频率》中，主人公本人在物理意义上并没有穿越
时空，但是通过无线电可以和另一个时空中的人取得联系，交换信息。 <br>

&nbsp;&nbsp;&nbsp;&nbsp;
<br>

&nbsp;&nbsp;&nbsp;&nbsp;时间到底是什麽呢？这一直是哲学家和科学家们不断思考的问题。古罗马皇帝兼哲学家Marcus
Aurelius曾经说过，时间好像一条河，一条急流；刚刚看到某样东西，它就已经消逝了，而另一样东西取代了它的位置，接着它也消逝得缈无踪影了。同样
在中国，子在川上曰：逝者如斯夫，不舍昼夜。爱因斯坦说，时间只是时钟标示出的量；这个钟可以是行星的自转、沙漏里的沙粒，也可以是心跳或铯原子的振动。
霍金说：时间既有诞生的一天，也有死亡的一天。人类对于时间的思考涉及到了宗教，哲学，科学，文学等等各个领域，同样也反映在20世纪以来一个重要的文化
媒介??电影里。科学家未能实现的时间旅行在电影中梦想成真，科幻小说里描写的时空穿越在电影中被视觉化而异彩纷呈，哲学家们所探讨的终极问题成为众多电
影所探讨的主题。电影中的时间旅行载负着人类摆脱时间桎梏的梦想，在时间的荒原中自由地穿梭。<br>
<br>
<img src ="http://www.blogjava.net/briansun/aggbug/1110.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-02-13 00:11 <a href="http://www.blogjava.net/briansun/articles/1110.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>澳大利亚科学家欲造时间机器（转）</title><link>http://www.blogjava.net/briansun/articles/1109.html</link><dc:creator>Brian Sun</dc:creator><author>Brian Sun</author><pubDate>Sat, 12 Feb 2005 16:10:00 GMT</pubDate><guid>http://www.blogjava.net/briansun/articles/1109.html</guid><wfw:comment>http://www.blogjava.net/briansun/comments/1109.html</wfw:comment><comments>http://www.blogjava.net/briansun/articles/1109.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/briansun/comments/commentRss/1109.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/briansun/services/trackbacks/1109.html</trackback:ping><description><![CDATA[<h1>澳大利亚科学家欲造时间机器</h1>
http://tech.enorth.com.cn/system/2003/01/23/000495983.shtml<br>
<br>
<table align="center" cellpadding="0" cellspacing="20">
<tbody><tr align="center"><td><img src="http://tech.enorth.com.cn/images3/200301/30123001.jpg" border="1"></td></tr>
<tr align="center"><td>美国科幻影片《时间机器》剧照</td></tr>
</tbody>
</table>


<p>　　澳大利亚科学家保罗·戴维斯的科学研究包括黑洞、量子场论、宇宙起源、意识的本质和生命起源等诸多涉及人类和宇宙本源的问题。他曾经带领一个研
究小组，得出光速在变化的结论；他曾经写过不少关于时间的书；如果他设想的一切都成为现实，人可以回到过去见一见自己的老爷爷、老奶奶，也可以到未来看一
看自己的重孙子、重孙女，关于时空的基本定义就要改写，物理学的根基就会动摇。　　</p>


<p>　　<b>“有限时间旅行”肯定可行</b></p>


<p>　　人类乐于梦想，也盼望知晓过去和未来。若要将历史和命运活生生地展现在我们面前，时间旅行似乎是个最为简便的方法。然而，时间机器的制造仍然停
留在幻想阶段，而即便是幻想，也多产生于小说家和电影特效师的手中，少有人知科学家对时间机器的具体构想。保罗·戴维斯是享誉世界的理论物理学家，他决定
当第一个吃螃蟹的人，尝试制造时间机器，哪怕只是“理论上的制造”。</p>


<p>　　要制造时间机器首先需要弄清楚的问题是，你想回到过去还是飞到未来。在戴维斯看来，在时间中到未来旅行是很容易的，如果你接近于光速运动或者身处强大的引力场中，会感到时间流逝得比其他人更缓慢——你进入了他们的未来。</p>


<p>　　飞向未来的旅行又叫“有限时间旅行”。保罗·戴维斯在《怎样制造时间机器》的开头非常肯定的提出，“有限时间旅行”是可行的，但回到任何时代的“无限时间旅行”只是“有可能可行”。</p>


<p>　　<b>虫洞：回到过去的关键</b></p>


<p>　　爱因斯坦的相对论允许这一旅行发生在特定的时空结构里：一个旋转的宇宙，一个旋转的柱体，以及非常著名的虫洞——一条贯穿空间和时间的隧道。也就是说，只要能够建造一个稳定的虫洞，就可以跨越时间和空间。那么，到底什么是虫洞？它和黑洞有什么联系呢？</p>


<p>　　在斯蒂芬·霍金的《时间简史》里有这样的解释：虫洞是连接宇宙遥远区域间的时空细管，它可以把平行的宇宙或者婴儿宇宙连接起来，并提供时间旅行的可能性。而黑洞是时空的一个区域，那里引力是如此之强，以至于任何东西，甚至光都不能从该处逃逸出来。</p>


<p>　　在戴维斯的计划里，建造一个虫洞要分3步：</p>


<p>　　第一步，寻找或建立一个虫洞，开辟一个隧道用来连接太空中两个不同的区域。</p>


<p>　　第二步，使虫洞稳定下来。由量子产生的负能量，虫洞便允许信号和物体安全地穿越它。负能量会抵制虫洞变为密度无穷大或接近无穷大。换句话说，它阻止了虫洞演变成黑洞。</p>


<p>　　第三步是牵引虫洞。一艘具有高度先进技术的太空船将虫洞的入口互相分离开。如果两个端口都放置在空间中合适的地方，那么时间差将保持恒定状态。
假设这一差值是10年，一名宇航员从一个方向穿越虫洞，他将跳到10年后的未来，反之，宇航员若是从另一方向穿越虫洞，他将跳到10年前的过去。</p>


<p>　　<b>时间机器的悖论</b></p>


<p>　　假如技术上的诸多难题都被克服了，时间机器的生产将会打开充满悖论的潘多拉盒子。对于这些，戴维斯也表现出一丝忧虑。他说：“我本人不打算把我
描述的时间旅行和其它控制自然的行为区分开来。所有的技术都在以某种方式干预自然。在一些科幻小说里，有人通过回到过去而改变了现状。这种事出现在小说里
当然无伤大雅，但如果发生在现实中会带来严重的伦理问题。谁给你回到过去改变历史的权利？”</p>


<p>　　既然过去、现在和未来紧密联系，过去能影响现在，那么现在影响过去在逻辑上也说得通。如果不能想干什么就干什么，人好不容易有了在时间中穿梭的自由，却又失去了行动的自由，眼睁睁看着历史从身边滑过，却无力改变什么，岂不是一个巨大的损失？</p>


<p>　　对此，戴维斯给出的解决方案是“多宇宙”理论——世界不是只有一个，而是有许多平行的世界。你回到过去，但那不是你自己的世界，而是和你的历史相似的世界。这样，即便你打死了自己的母亲，她在那个世界也的确死了，但当你回到未来时，她依然活得好好的。</p>


<p>　　这种想法近乎疯狂，但除了戴维斯外还有许多著名物理学家相信有平行世界的存在。在《时间简史》里，霍金这样说：解决时间旅行的其他可能的方法是
选择历史假想。其思想是，当时间旅行者回到过去，他就进入和历史记载不同的另外的一个历史中去。这样，他们可以自由地行动，不受和原先的历史相一致的约
束。如果这样，回到过去和做一场梦又有什么区别？<br>
<br>
</p>

<img src ="http://www.blogjava.net/briansun/aggbug/1109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/briansun/" target="_blank">Brian Sun</a> 2005-02-13 00:10 <a href="http://www.blogjava.net/briansun/articles/1109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>