<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>DreamCode</title>
	<atom:link href="http://www.dreamcode.org/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dreamcode.org/blog</link>
	<description></description>
	<pubDate>Thu, 23 Oct 2008 03:48:51 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>解决 scim-python 无法使用 shift 切换中英文状态的问题</title>
		<link>http://www.dreamcode.org/blog/posts/38.html</link>
		<comments>http://www.dreamcode.org/blog/posts/38.html#comments</comments>
		<pubDate>Thu, 23 Oct 2008 03:41:29 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[troubleshooting]]></category>

		<guid isPermaLink="false">http://www.dreamcode.org/blog/?p=38</guid>
		<description><![CDATA[在某些系统下，scim-python 输入法会出现无法使用 shift 键切换中英文的情况。这种问题一般是由于 scim-bridge 引起的，一个简单的解决办法就是不是用 scim-bridge。输入命令：
sudo im-switch -c
出现以下信息：
[patrick@ubuntu:~]$ sudo im-switch -c
System wide default for zh_CN locale is marked with [+].

There are 5 alternatives which provide `xinput-zh_CN'.

  Selection    Alternative
-----------------------------------------------
          1    /etc/X11/xinit/xinput.d/scim-pinyin
         [...]]]></description>
			<content:encoded><![CDATA[<p>在某些系统下，scim-python 输入法会出现无法使用 shift 键切换中英文的情况。这种问题一般是由于 scim-bridge 引起的，一个简单的解决办法就是不是用 scim-bridge。输入命令：</p>
<pre>sudo im-switch -c</pre>
<p>出现以下信息：</p>
<pre>[patrick@ubuntu:~]$ sudo im-switch -c
System wide default for zh_CN locale is marked with [+].

There are 5 alternatives which provide `xinput-zh_CN'.

  Selection    Alternative
-----------------------------------------------
          1    /etc/X11/xinit/xinput.d/scim-pinyin
          2    /etc/X11/xinit/xinput.d/ibus
*         3    /etc/X11/xinit/xinput.d/scim
          4    /etc/X11/xinit/xinput.d/scim-immodule
+         5    /etc/X11/xinit/xinput.d/scim-bridge

Press enter to keep the default[*], or type selection number: 3</pre>
<p>选择 scim 而不是 scim-bridge，回车保存，再重新登录系统即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/38.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>升级 Ubuntu 8.10 后无法使用网络的问题</title>
		<link>http://www.dreamcode.org/blog/posts/32.html</link>
		<comments>http://www.dreamcode.org/blog/posts/32.html#comments</comments>
		<pubDate>Tue, 07 Oct 2008 16:09:27 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[troubleshooting]]></category>

		<guid isPermaLink="false">http://www.dreamcode.org/blog/?p=32</guid>
		<description><![CDATA[今天将系统从 Ubuntu 8.04 升级到 8.10 beta，基本上一切正常。只是本来在公司用得好好的网络链接，回到宿舍后却突然无法使用了。
使用 ifconfig 发现 eth0 没有从路由器上获得 IP 地址。在 /var/log/syslog 中看到系统不断地重复输出（3秒一次）
Oct  7 22:34:54 ubuntu NetworkManager: &#60;info&#62;  disconnected by the system bus.
Oct  7 22:34:57 ubuntu NetworkManager: &#60;WARN&#62;  nm_dbus_manager_start_service(): Could not acquire the NetworkManager service as it is already taken.
通过浏览日志发现，系统在启动的时候其实已经通过 DHCP 获得了 IP 地址，而且 Activation (eth0) Stage 的五个步骤也全部成功完成。但是随后输出一下日志
Oct  7 22:20:22 ubuntu NetworkManager: &#60;info&#62;  (eth0): [...]]]></description>
			<content:encoded><![CDATA[<p>今天将系统从 Ubuntu 8.04 升级到 8.10 beta，基本上一切正常。只是本来在公司用得好好的网络链接，回到宿舍后却突然无法使用了。</p>
<p>使用 <code>ifconfig</code> 发现 <code>eth0</code> 没有从路由器上获得 IP 地址。在 <em>/var/log/syslog</em> 中看到系统不断地重复输出（3秒一次）</p>
<blockquote><p>Oct  7 22:34:54 ubuntu NetworkManager: &lt;info&gt;  disconnected by the system bus.<br />
Oct  7 22:34:57 ubuntu NetworkManager: &lt;WARN&gt;  nm_dbus_manager_start_service(): Could not acquire the NetworkManager service as it is already taken.</p></blockquote>
<p>通过浏览日志发现，系统在启动的时候其实已经通过 DHCP 获得了 IP 地址，而且 Activation (eth0) Stage 的五个步骤也全部成功完成。但是随后输出一下日志</p>
<blockquote><p>Oct  7 22:20:22 ubuntu NetworkManager: &lt;info&gt;  (eth0): carrier now OFF (device state 8 )<br />
Oct  7 22:20:22 ubuntu NetworkManager: &lt;info&gt;  (eth0): device state change: 8 -&gt; 2<br />
Oct  7 22:20:22 ubuntu NetworkManager: &lt;info&gt;  (eth0): deactivating device.<br />
Oct  7 22:20:22 ubuntu NetworkManager: &lt;info&gt;  eth0: canceled DHCP transaction, dhcp client pid 6853</p></blockquote>
<p>不知道为什么会突然 carrier OFF。考虑到网上很多用户反映 Ubuntu 8.10 的 NetworkManager 不好用，不能排除新版本的 NetworkManager 依旧存在某些 bug。</p>
<p>如果需要快速恢复系统的网络链接，一个快捷的方法是编辑 <em>/etc/network/interfaces</em> 文件。我打开文件后发现其中内容只有 <code>lo</code> 的配置：</p>
<blockquote><p># This file describes the network interfaces available on your system<br />
# and how to activate them. For more information, see interfaces(5).</p>
<p># The loopback network interface<br />
auto lo<br />
iface lo inet loopback</p>
<p># The primary network interface</p></blockquote>
<p>于是为 <code>eth0</code>（有线链接）和 <code>eth1</code>（无线链接）加上配置，如下：</p>
<blockquote><p>auto eth0<br />
iface eth0 inet dhcp</p>
<p>auto eth1<br />
iface eth1 inet dhcp</p></blockquote>
<p>保存之后执行<br />
<code>sudo /etc/init.d/networking restart</code><br />
即可恢复。但是这时 NetworkManager 不再管理网络链接，点击其图标会提示 device is unmanaged。</p>
<p>如果希望保留 NetworkManager 的特性，还可以编辑 <em>/etc/NetworkManager/nm-system-settings.conf</em>，将其中的</p>
<blockquote><p>[ifupdown]<br />
managed=false</p></blockquote>
<p>修改成为</p>
<blockquote><p>[ifupdown]<br />
managed=true</p></blockquote>
<p>即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/32.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>My Thunderbird Add-ons</title>
		<link>http://www.dreamcode.org/blog/posts/25.html</link>
		<comments>http://www.dreamcode.org/blog/posts/25.html#comments</comments>
		<pubDate>Mon, 29 Sep 2008 15:07:44 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Sharpening Tools]]></category>

		<category><![CDATA[thunderbird]]></category>

		<category><![CDATA[扩展]]></category>

		<category><![CDATA[邮件客户端]]></category>

		<guid isPermaLink="false">http://www.dreamcode.org/blog/?p=25</guid>
		<description><![CDATA[Mozilla 出品的软件，最大的特点就是通过 add-on 可以不断地扩展软件的功能和特性。一般来说，能够提供额外有用信息和能够使的操作更方便的 add-on 是最值得使用的。
Attachment Reminder - 用户在发送邮件的时候偶尔会忘记添加附件，却又在 email 中说到“请看附件”之类的话，如果是发生在比较正式的场合，往往难免会比较尴尬。这个 add-on 的通过扫描邮件中的关键字，在发现有可能表示有附件的文字，发送时又没有添加附件的时候，给用户提醒一下。
Country Lookup - 显示邮件发送地的地理信息。
Display Mail User Agent - 显示用户客户端的信息。
Display mailing list header - 显示在 RFC 2369 文档中定义的 header 信息。
Enigmail - 使用 OpenPGP 加密邮件或者添加数字签名。
GmailUI - 添加一些 Gmail 中的特性，比如说 j/k 键用来上下翻阅邮件。
ImportExportTools - 增强的邮件导入导出功能。
Menehy - Country Lookup 和 Display mailing list header 依赖的扩展……
Nostalgy - 为切换邮件目录、拷贝移动邮件增加快捷键，同时提供目录路径自动完成的功能。
pasteCode - [...]]]></description>
			<content:encoded><![CDATA[<p>Mozilla 出品的软件，最大的特点就是通过 add-on 可以不断地扩展软件的功能和特性。一般来说，能够提供额外有用信息和能够使的操作更方便的 add-on 是最值得使用的。</p>
<p>Attachment Reminder - 用户在发送邮件的时候偶尔会忘记添加附件，却又在 email 中说到“请看附件”之类的话，如果是发生在比较正式的场合，往往难免会比较尴尬。这个 add-on 的通过扫描邮件中的关键字，在发现有可能表示有附件的文字，发送时又没有添加附件的时候，给用户提醒一下。</p>
<p>Country Lookup - 显示邮件发送地的地理信息。</p>
<p>Display Mail User Agent - 显示用户客户端的信息。</p>
<p>Display mailing list header - 显示在 RFC 2369 文档中定义的 header 信息。</p>
<p>Enigmail - 使用 OpenPGP 加密邮件或者添加数字签名。</p>
<p>GmailUI - 添加一些 Gmail 中的特性，比如说 j/k 键用来上下翻阅邮件。</p>
<p>ImportExportTools - 增强的邮件导入导出功能。</p>
<p>Menehy - Country Lookup 和 Display mailing list header 依赖的扩展……</p>
<p>Nostalgy - 为切换邮件目录、拷贝移动邮件增加快捷键，同时提供目录路径自动完成的功能。</p>
<p>pasteCode - 连带语法高亮信息地将代码拷贝到邮件中。</p>
<p>Quote Colors - 使用不同的颜色区分邮件中嵌套的引用（quote）。</p>
<p>Remove Duplicate Message (Alternate) - 删除重复的邮件。</p>
<p>Signature Switch - 可以根据收件人、新闻组、邮件列表的不同自动使用不同的签名档，支持 HTML 签名。</p>
<p>Stationery - 提供编辑 HTML 邮件源代码的功能。</p>
<p>Zindus - 自动同步本地通讯录与 Gmail 或者 Zimbra 通讯录。</p>
<p>最后来一张截图：</p>
<p style="text-align: center;"><a href="http://www.dreamcode.org/blog/wp-content/uploads/2008/10/screenshot2.png"><img class="aligncenter size-full wp-image-28" title="thunderbird with add-ons" src="http://www.dreamcode.org/blog/wp-content/uploads/2008/10/screenshot2.png" alt="" width="499" height="408" />（点击查看原尺寸图片）</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/25.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Ruby 技巧：如何高效读取大文件末尾的数据</title>
		<link>http://www.dreamcode.org/blog/posts/18.html</link>
		<comments>http://www.dreamcode.org/blog/posts/18.html#comments</comments>
		<pubDate>Tue, 09 Sep 2008 07:24:15 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Coding Tips]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[文件处理]]></category>

		<guid isPermaLink="false">http://www.dreamcode.org/blog/?p=18</guid>
		<description><![CDATA[在处理某些大文件（例如数以 G 计的文件）时，可以事先知道需要读取的数据即在文件的末尾部分（例如只需要知道文件最后大约5%的数据）。如果按照普通方法，从文件起始部分开始读取，将会花费大量时间在 IO 操作上。如果能像 *nix 的命令 tail 那样直接读取文件末尾的数据，将会大大提高处理程序的性能。在 Ruby 中，IO 类有如下三个常量用于指示从何处开始在 IO 流中搜寻数据：
SEEK_CUR：从当前位置开始
SEEK_END：从 IO 流末尾位置开始
SEEK_SET：从 IO 流起始位置开始（亦即”绝对位置“）
示例代码：


fileSize = File.size(fileName)
seeklen = ((0.05 * fileSize) * -1).to_i
file = File.open(ARGV[0)
file.seek(seeklen, IO::SEEK_END)
puts file.readlines

]]></description>
			<content:encoded><![CDATA[<p>在处理某些大文件（例如数以 G 计的文件）时，可以事先知道需要读取的数据即在文件的末尾部分（例如只需要知道文件最后大约5%的数据）。如果按照普通方法，从文件起始部分开始读取，将会花费大量时间在 IO 操作上。如果能像 *nix 的命令 tail 那样直接读取文件末尾的数据，将会大大提高处理程序的性能。在 Ruby 中，<code>IO</code> 类有如下三个常量用于指示从何处开始在 IO 流中搜寻数据：<br />
<code>SEEK_CUR</code>：从当前位置开始<br />
<code>SEEK_END</code>：从 IO 流末尾位置开始<br />
<code>SEEK_SET</code>：从 IO 流起始位置开始（亦即”绝对位置“）</p>
<p>示例代码：</p>
<pre name="code" class="ruby">

fileSize = File.size(fileName)
seeklen = ((0.05 * fileSize) * -1).to_i
file = File.open(ARGV[0)
file.seek(seeklen, IO::SEEK_END)
puts file.readlines
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/18.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Eclipse 3.4 (Ganymede) 发布</title>
		<link>http://www.dreamcode.org/blog/posts/10.html</link>
		<comments>http://www.dreamcode.org/blog/posts/10.html#comments</comments>
		<pubDate>Fri, 11 Jul 2008 05:32:20 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[eclipse]]></category>

		<category><![CDATA[IDE]]></category>

		<guid isPermaLink="false">http://sd.patrickhe.info/blog/?p=10</guid>
		<description><![CDATA[Eclipse 社区最近发布了今年的 Eclipse 版本，代号 Ganymede。在古希腊神话中，Ganymede 本是一位特洛伊王子，一日宙斯见着 Ganymede，即因他的英俊美貌而倾心，于是将 Ganymede 诱拐到奥林匹斯山上为众神司酒。木星（英文名为 Jupiter，古罗马神话中的主神，亦即古希腊神话中的 Zeus）的一颗卫星被命名为 Ganymede，它也是目前太阳系中已知的最大的卫星。
Eclipse Ganymede 包含的项目见下图：

更多信息在这里。
]]></description>
			<content:encoded><![CDATA[<p>Eclipse 社区最近发布了今年的 Eclipse 版本，代号 <a href="http://www.eclipse.org/ganymede/" target="_blank">Ganymede</a>。在古希腊神话中，<a href="http://en.wikipedia.org/wiki/Ganymede_(mythology)" target="_blank">Ganymede</a> 本是一位特洛伊王子，一日宙斯见着 Ganymede，即因他的英俊美貌而倾心，于是将 Ganymede 诱拐到奥林匹斯山上为众神司酒。木星（英文名为 Jupiter，古罗马神话中的主神，亦即古希腊神话中的 Zeus）的一颗卫星被命名为 <a href="http://en.wikipedia.org/wiki/Ganymede_(moon)" target="_blank">Ganymede</a>，它也是目前太阳系中已知的最大的卫星。</p>
<p>Eclipse Ganymede 包含的项目见下图：</p>
<p><a href="http://www.dreamcode.org/blog/wp-content/uploads/2008/07/screenshot11.png"><img class="alignnone size-full wp-image-11" title="Eclipse Projects" src="http://www.dreamcode.org/blog/wp-content/uploads/2008/07/screenshot11.png" alt="" width="500" height="376" /></a></p>
<p>更多信息在<a href="http://www.eclipse.org/ganymede/learn.php" target="_blank">这里</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/10.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Linux 系统性能监视工具</title>
		<link>http://www.dreamcode.org/blog/posts/9.html</link>
		<comments>http://www.dreamcode.org/blog/posts/9.html#comments</comments>
		<pubDate>Sat, 28 Jun 2008 16:26:29 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://sd.patrickhe.info/blog/?p=8</guid>
		<description><![CDATA[在 Linux 服务器上，有众多命令行小工具可以用于监控服务器性能和状态。这些工具对于快速判断服务器运行情况，非常有帮助。

top
top 是最常用的命令之一，用来持续显示系统资源的最新使用状况。
[patrick@ubuntu:~]$ top
top - 23:39:07 up  5:55,  3 users,  load average: 0.16, 0.22, 0.18
Tasks: 141 total,   2 running, 138 sleeping,   0 stopped,   1 zombie
Cpu(s):  3.1%us,  1.1%sy,  0.0%ni, 95.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2041888k total,  1314284k used,   727604k free,    57688k buffers
Swap:  1951856k total,        0k used,  1951856k free,   728052k cached
PID USER      PR  NI  VIRT  RES  [...]]]></description>
			<content:encoded><![CDATA[<p>在 Linux 服务器上，有众多命令行小工具可以用于监控服务器性能和状态。这些工具对于快速判断服务器运行情况，非常有帮助。</p>
<ul>
<li><strong><code>top</code></strong><br />
<code>top</code> 是最常用的命令之一，用来持续显示系统资源的最新使用状况。<br />
<code>[patrick@ubuntu:~]$ top<br />
top - 23:39:07 up  5:55,  3 users,  load average: 0.16, 0.22, 0.18<br />
Tasks: 141 total,   2 running, 138 sleeping,   0 stopped,   1 zombie<br />
Cpu(s):  3.1%us,  1.1%sy,  0.0%ni, 95.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st<br />
Mem:   2041888k total,  1314284k used,   727604k free,    57688k buffers<br />
Swap:  1951856k total,        0k used,  1951856k free,   728052k cached<br />
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND<br />
6043 root      20   0  855m  50m  13m R    3  2.5  12:11.37 Xorg<br />
2477 root      15  -5     0    0    0 S    1  0.0   0:02.28 scsi_eh_3<br />
7008 patrick   20   0 15648 4936 3948 S    1  0.2   0:10.46 gnome-screensav</code><br />
按 M 将会按照占用内存的大小排列进程，按 P 则会按照 CPU 占用率进行排列。<br />
VIRT 表示进程使用的内存总大小，包括进程实际使用的内存、映射过的文件、与其它进程共享的内存等。RES 表示实际使用中的内存大小，SHR 表示与其它进程共享的内存大小。</li>
<p><span id="more-9"></span></p>
<li><strong><code>uptime</code></strong><br />
<code>uptime</code> 最常用的作用是快速查看当时的系统负载情况。<br />
<code>[patrick@ubuntu:~]$ uptime<br />
23:48:26 up  6:04,  3 users,  load average: 0.76, 0.38, 0.24</code><br />
通常来说，负载值/CPU数目 &lt;= 1 的情况下，表示系统拥有足够的剩余处理能力，当负载值/CPU数目 &gt; 1 的时候，就表示有进程需要等待 CPU 了。</li>
<li><strong><code>vmstat</code></strong><br />
<code>vmstat</code> 会提供有关内存、交换分区、进程、IO、CPU 的报告。<br />
<code>[patrick@ubuntu:~]$ vmstat -S M<br />
procs &#8212;&#8212;&#8212;&#8211;memory&#8212;&#8212;&#8212;- &#8212;swap&#8211; &#8212;&#8211;io&#8212;- -system&#8211; &#8212;-cpu&#8212;-<br />
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa<br />
0  0      0    697     57    712    0    0    28    17  161  552  8  2 89  1<br />
</code></li>
<li><strong><code>iostat</code></strong><br />
<code>iostat</code> 提供有关 CPU 的平均使用情况，以及 IO 信息。<br />
<code>[patrick@ubuntu:~]$ iostat -x<br />
Linux 2.6.24-19-generic (ubuntu)     06/28/2008<br />
avg-cpu:  %user   %nice %system %iowait  %steal   %idle<br />
8.46    0.01    1.91    1.00    0.00   88.62<br />
Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util<br />
sda               0.70     2.88    1.48    1.97    56.64    38.80    27.66     0.07   21.16   3.31   1.14<br />
sdb               0.09     0.00    0.06    0.00     6.44     0.00   113.77     0.00   17.13   5.41   0.03</code></li>
<li><strong><code>mpstat</code></strong><br />
<code>mpstat</code> 提供全局与单个 CPU 使用情况的统计报告。<br />
<code>[patrick@ubuntu:~]$ mpstat -P ALL<br />
Linux 2.6.24-19-generic (ubuntu)     06/28/2008<br />
11:57:36 PM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s<br />
11:57:36 PM  all    8.48    0.01    1.69    0.99    0.05    0.17    0.00   88.61    183.99<br />
11:57:36 PM    0    8.63    0.02    1.66    1.08    0.08    0.28    0.00   88.25    152.05<br />
11:57:36 PM    1    8.33    0.00    1.73    0.90    0.02    0.07    0.00   88.95     31.93<br />
11:57:36 PM    2    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00</code></li>
<li><strong><code>netstat</code></strong><br />
<code>netstat</code> 可以用来显示活动的 TCP 连接、计算机侦听的端口、以太网统计信息、IP 路由表、IPv4 统计信息（对于 IP、ICMP、TCP 和 UDP 协议）以及 IPv6 统计信息（对于 IPv6、ICMPv6、通过 IPv6 的 TCP 以及通过 IPv6 的 UDP 协议）。<br />
<code>[patrick@ubuntu:~]$ netstat -a<br />
Active Internet connections (servers and established)<br />
Proto Recv-Q Send-Q Local Address           Foreign Address         State<br />
tcp        0      0 localhost:mysql         *:*                     LISTEN<br />
tcp        0      0 localhost:8118          *:*                     LISTEN<br />
tcp        0      0 localhost:ipp           *:*                     LISTEN<br />
tcp        0      0 localhost:9050          *:*                     LISTEN<br />
tcp        0      0 192.168.1.3:59421       by2msg1204111.gate:msnp ESTABLISHED<br />
</code></li>
<li><strong><code>ps</code></strong><br />
<code>ps</code> 可以提供一个当前运行的进程的列表。<br />
<code>[patrick@ubuntu:~]$ ps aux<br />
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND<br />
root         1  0.0  0.0   2844  1688 ?        Ss   Jun28   0:01 /sbin/init<br />
root         2  0.0  0.0      0     0 ?        S&lt;   Jun28   0:00 [kthreadd]<br />
root         3  0.0  0.0      0     0 ?        S&lt;   Jun28   0:00 [migration/0]<br />
root         4  0.0  0.0      0     0 ?        S&lt;   Jun28   0:00 [ksoftirqd/0]<br />
root         5  0.0  0.0      0     0 ?        S&lt;   Jun28   0:00 [watchdog/0]<br />
root         9  0.0  0.0      0     0 ?        S&lt;   Jun28   0:00 [events/0]<br />
</code></li>
<li><strong><code>pstree</code></strong><br />
<code>pstree</code> 会显示出当前运行中的进程之间的树状结构。<br />
<code>[patrick@ubuntu:~]$ pstree<br />
init─┬─/usr/bin/revela<br />
├─NetworkManager───{NetworkManager}<br />
├─NetworkManagerD<br />
├─gconfd-2<br />
├─gdm───gdm─┬─Xorg<br />
│           └─x-session-manag─┬─bluetooth-apple<br />
│                             ├─compiz───compiz.real───compiz-decorato───gtk-window-deco<br />
│                             ├─gnome-panel<br />
│                             ├─gnome-settings-─┬─pulseaudio─┬─gconf-helper<br />
│                             │                 │            └─2*[{pulseaudio}]<br />
│                             │                 └─{gnome-settings-}<br />
│                             ├─nautilus───{nautilus}<br />
│                             ├─nm-applet<br />
│                             ├─python<br />
│                             ├─scim<br />
│                             ├─seahorse-agent<br />
│                             ├─update-notifier<br />
│                             └─{x-session-manag}<br />
</code></li>
<li><strong><code>pgrep</code></strong><br />
<code>pgrep</code> 会根据提供的正则表达式查找进程。<br />
<code>[patrick@ubuntu:~]$ pgrep -l &#8217;scim&#8217;<br />
6966 scim<br />
7006 scim-launcher<br />
7046 scim-helper-man<br />
7047 scim-panel-gtk<br />
7049 scim-launcher<br />
7213 scim-bridge<br />
</code></li>
<li><strong><code>lsof</code></strong><br />
<code>lsof</code> 用于列出进程所打开的文件列表。<br />
<code>[patrick@ubuntu:~]$ lsof -p 12894<br />
COMMAND   PID    USER   FD   TYPE     DEVICE     SIZE    NODE NAME<br />
firefox 12894 patrick  cwd    DIR        8,7     4096 5423105 /home/patrick<br />
firefox 12894 patrick  rtd    DIR        8,5     4096       2 /<br />
firefox 12894 patrick  txt    REG        8,5    26924  557548 /usr/lib/firefox-3.0/firefox<br />
firefox 12894 patrick  mem    REG        8,5    17884  900100 /lib/tls/i686/cmov/libnss_dns-2.7.so<br />
firefox 12894 patrick  mem    REG        8,5     7552  899934 /lib/libnss_mdns4_minimal.so.2</code><br />
因为在 Linux 中，端口也是被视作文件的，所以也可以使用 <code>lsof -i</code> 显示计算机上所有打开的因特网地址。<br />
<code>[patrick@ubuntu:~]$ lsof -i<br />
COMMAND   PID    USER   FD   TYPE DEVICE SIZE NODE NAME<br />
pidgin  11114 patrick   14u  IPv4  58594       UDP 192.168.1.3:54865-&gt;reverse.gdsz.cncnet.net:8000<br />
pidgin  11114 patrick   15u  IPv4  57930       TCP 192.168.1.3:59421-&gt;by2msg1204111.phx.gbl:msnp (ESTABLISHED)</code></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/9.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Java 中子类是否只继承父类的非私有变量和方法？</title>
		<link>http://www.dreamcode.org/blog/posts/8.html</link>
		<comments>http://www.dreamcode.org/blog/posts/8.html#comments</comments>
		<pubDate>Fri, 27 Jun 2008 05:33:40 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[程序设计]]></category>

		<category><![CDATA[继承]]></category>

		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://sd.patrickhe.info/blog/?p=7</guid>
		<description><![CDATA[今天在 CSDN 论坛中见到有人问在 Java 中子类是否只继承父类的非私有变量和方法。大部分跟贴都认为这句话是正确的，但是对于这个问题背后的本质理解却是错误的。
首先我们明确一下“继承”一词的概念，在 Java 中，继承一词的意义是有限制的。一个子类只能继承其父类的可访问的成员，并且该子类没有覆盖或者说隐藏父类中的那些可访问成员。所以，一个类的成员就是指在这个类中所声明的属性和方法，再加上从其父类继承而来的属性和方法。也就是说，子类是不能继承父类的私有成员的。
虽然子类不继承父类中的私有成员，但是在父类中生命的这些私有成员仍然是子类类型对象的一部分。因为在实例化对象的时候，只初始化在当前类中所声明的属性明显是不足够的，还需要初始化其父类中所有声明的属性。在实例化的过程中，JVM 需要为对象的类及其父类中所有定义的属性分配空间，包括父类中声明的私有成员。
所以，我们可以说：子类不能从父类继承私有成员，但是子类的对象是包括子类所不能从父类中继承的私有成员的。
]]></description>
			<content:encoded><![CDATA[<p>今天在 CSDN 论坛中见到有人问<a href="http://community.csdn.net/Expert/TopicView3.asp?id=4281500">在 Java 中子类是否只继承父类的非私有变量和方法</a>。大部分跟贴都认为这句话是正确的，但是对于这个问题背后的本质理解却是错误的。</p>
<p>首先我们明确一下“继承”一词的概念，在 Java 中，继承一词的意义是有限制的。一个子类只能继承其父类的可访问的成员，并且该子类没有覆盖或者说隐藏父类中的那些可访问成员。所以，一个类的成员就是指在这个类中所声明的属性和方法，再加上从其父类继承而来的属性和方法。也就是说，子类是不能继承父类的私有成员的。</p>
<p>虽然子类不继承父类中的私有成员，但是在父类中生命的这些私有成员仍然是子类类型对象的一部分。因为在实例化对象的时候，只初始化在当前类中所声明的属性明显是不足够的，还需要初始化其父类中所有声明的属性。在实例化的过程中，JVM 需要为对象的类及其父类中所有定义的属性分配空间，包括父类中声明的私有成员。</p>
<p>所以，我们可以说：子类不能从父类继承私有成员，但是子类的对象是包括子类所不能从父类中继承的私有成员的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/8.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>怎样在从 Linux 服务器注销之后继续运行程序</title>
		<link>http://www.dreamcode.org/blog/posts/7.html</link>
		<comments>http://www.dreamcode.org/blog/posts/7.html#comments</comments>
		<pubDate>Fri, 27 Jun 2008 05:32:07 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[nohup]]></category>

		<guid isPermaLink="false">http://sd.patrickhe.info/blog/?p=6</guid>
		<description><![CDATA[一般来说，通过终端连接到 Unix/Linux/BSD 服务器上运行服务器的程序，如果终端和服务器之间的连接断开的话，通过该终端启动的服务器程序也会相应的终止运行。如果想要程序在用户从服务器注销之后继续运行，我们可以使用 nohup 命令来做到这一点。通过 nohup 启动的程序，将会忽略系统的挂起（hangup）信号，也就能够使得程序会在用户注销之后依然在后台运行下去。
]]></description>
			<content:encoded><![CDATA[<p>一般来说，通过终端连接到 Unix/Linux/BSD 服务器上运行服务器的程序，如果终端和服务器之间的连接断开的话，通过该终端启动的服务器程序也会相应的终止运行。如果想要程序在用户从服务器注销之后继续运行，我们可以使用 <code>nohup</code> 命令来做到这一点。通过 <code>nohup</code> 启动的程序，将会忽略系统的挂起（hangup）信号，也就能够使得程序会在用户注销之后依然在后台运行下去。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/7.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>如何编写函数的返回值</title>
		<link>http://www.dreamcode.org/blog/posts/6.html</link>
		<comments>http://www.dreamcode.org/blog/posts/6.html#comments</comments>
		<pubDate>Thu, 26 Jun 2008 15:12:46 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[程序设计]]></category>

		<category><![CDATA[函数]]></category>

		<category><![CDATA[编码]]></category>

		<guid isPermaLink="false">http://sd.patrickhe.info/blog/?p=5</guid>
		<description><![CDATA[朋友李卫公在他的 blog 中讨论了一个有关函数返回值的问题。其在文章中的初始问题，大致可以描述为：
需要编写一个函数，从 HTML 源代码中提取某个节点的文本，在提取失败的情况下，应当返回一个空字符串还是 null 值。
李卫公在文中说明了，如果在失败的情况下返回一个空字符串的话，对于该函数的调用者而言，是无法区分出该函数是从目标节点中提取到一个空字符串，还是实际上什么也没有提取到。
通常来说，一个函数所要返回的值，要么是一个数据（例如一个员工），要么是一组数据（例如所有女性员工）。
1. 对于第一种情况而言，函数的返回值类型应当是值（value）类型或者实体（entity）类型。例如，需要根据员工编号得到一个员工对象，我们可以编写一个这样的函数：


public Employee getEmployee(int id);

如果能找到具有该编号的员工，该函数返回一个 Employee 对象。否则返回 null 值，表示未找到指定 id 对应的员工；或者抛出一个 checked exception，函数的识别标志因此需要修改为：


public Employee getEmployee(int id) throws EmployeeNotFoundException;

由函数的调用者来捕获该异常，并根据需要进行处理。
2. 对于第二种情况而言，函数的返回值类型应当是 Collection 类型（包括 Map 类型）。例如，需要根据查询某月某部门迟到员工的列表，我们可以编写一个这样的函数：


public Set getLateEmployees(Month month, Department department);

如果查询结果是，在八月份技术部没有一位同学迟到，太好了，这个函数只需要简单地返回一个空 Set 对象即可。
对于第一种情况，假设我们选择的是让函数返回 null 值，如果在程序中有相当多的地方需要调用该函数，那么我们有可能会在代码中发现很多像


if (employee == null) ...{
...
}

这样的代码，这些代码通常并不是用来处理业务逻辑，编写它们的最主要目的可能仅仅只是为了防止出现 NullPointerException。倘若这种情况降低了程序的可读性或者可维护性，我们可以采用 Null Object 模式来消除这些遍处滋生的防御代码。
]]></description>
			<content:encoded><![CDATA[<p>朋友李卫公在他的 blog 中讨论了一个<a href="http://blog.donews.com/maverick/archive/2007/08/21/1201383.aspx">有关函数返回值的问题</a>。其在文章中的初始问题，大致可以描述为：<br />
需要编写一个函数，从 HTML 源代码中提取某个节点的文本，在提取失败的情况下，应当返回一个空字符串还是 <code>null</code> 值。<br />
李卫公在文中说明了，如果在失败的情况下返回一个空字符串的话，对于该函数的调用者而言，是无法区分出该函数是从目标节点中提取到一个空字符串，还是实际上什么也没有提取到。</p>
<p>通常来说，一个函数所要返回的值，要么是一个数据（例如一个员工），要么是一组数据（例如所有女性员工）。<span id="more-6"></span><br />
1. 对于第一种情况而言，函数的返回值类型应当是值（value）类型或者实体（entity）类型。例如，需要根据员工编号得到一个员工对象，我们可以编写一个这样的函数：</p>
<pre name="code" class="java">

public Employee getEmployee(int id);
</pre>
<p>如果能找到具有该编号的员工，该函数返回一个 <code>Employee</code> 对象。否则返回 <code>null</code> 值，表示未找到指定 id 对应的员工；或者抛出一个 checked exception，函数的识别标志因此需要修改为：</p>
<pre name="code" class="java">

public Employee getEmployee(int id) throws EmployeeNotFoundException;
</pre>
<p>由函数的调用者来捕获该异常，并根据需要进行处理。<br />
2. 对于第二种情况而言，函数的返回值类型应当是 <code>Collection</code> 类型（包括 <code>Map</code> 类型）。例如，需要根据查询某月某部门迟到员工的列表，我们可以编写一个这样的函数：</p>
<pre name="code" class="java">

public Set getLateEmployees(Month month, Department department);
</pre>
<p>如果查询结果是，在八月份技术部没有一位同学迟到，太好了，这个函数只需要简单地返回一个空 <code>Set</code> 对象即可。</p>
<p>对于第一种情况，假设我们选择的是让函数返回 <code>null</code> 值，如果在程序中有相当多的地方需要调用该函数，那么我们有可能会在代码中发现很多像</p>
<pre name="code" class="java">

if (employee == null) ...{
...
}
</pre>
<p>这样的代码，这些代码通常并不是用来处理业务逻辑，编写它们的最主要目的可能仅仅只是为了防止出现 <code>NullPointerException</code>。倘若这种情况降低了程序的可读性或者可维护性，我们可以采用 <a href="http://industriallogic.com/xp/refactoring/nullObject.html">Null Object 模式</a>来消除这些遍处滋生的防御代码。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/6.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>利用正则表达式反向选择数据</title>
		<link>http://www.dreamcode.org/blog/posts/5.html</link>
		<comments>http://www.dreamcode.org/blog/posts/5.html#comments</comments>
		<pubDate>Thu, 26 Jun 2008 14:36:29 +0000</pubDate>
		<dc:creator>Patrick</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[regex]]></category>

		<category><![CDATA[regular expression]]></category>

		<category><![CDATA[字符串处理]]></category>

		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://sd.patrickhe.info/blog/?p=3</guid>
		<description><![CDATA[最近有朋友问如何在文件中选择不包含诸如1900、1901、……1999字符串的行，目标文件中所有数据都是由数字字符组成。
如果使用 grep 这样的工具，只用写很一个非常简单的正则表达式就能解决问题：
grep -v '19\d\d' target_file
grep 的 -v 选项表示选择 target_file 中不匹配目标正则表达式的行。
对于诸如 Java 或者 Ruby 这样的程序设计语言，则没有提供类似的参数。我们需要直接使用正则表达式来匹配不包含以上字符串的行。解决这个问题的正则表达式如下：
^((?!19\d\d)\d)+$
其中 (?!19\d\d) 的作用是，一旦正则表达式引擎发现行内包含有符合 19\d\d 模式的数据，即判断该行不匹配此模式；如果一直没有发现符合 19\d\d 模式的数据，而且所有数据都是数字字符，则该行数据匹配此模式。这样就能选取到目标文件中所有不包含以上字符串的行。通常情况下，我们并不需要使用捕获型括号，以上表达式可以进一步修改成为：
^(?:(?!19\d\d)\d)+$
修改后的正则表达式的效率更高。
正则表达式是处理文本时的一个强有力的工具。最初的正则表达式出现于理论计算机科学的自动控制理论和形式语言理论中。如果需要学习正则表达式，倘若只是从网络上摘抄一星半点的实例或者读一些30分钟速成教程，是难以真正掌握这个强大工具的。有关正则表达式方面的最好的书籍之一应该是 Jeffery Friedl 的 Master Regular Expressions，国内既有第二版的影印版，也有余晟翻译的第三版译本。
]]></description>
			<content:encoded><![CDATA[<p>最近有朋友问如何在文件中选择不包含诸如1900、1901、……1999字符串的行，目标文件中所有数据都是由数字字符组成。<br />
如果使用 grep 这样的工具，只用写很一个非常简单的正则表达式就能解决问题：</p>
<pre>grep -v '19\d\d' <span style="font-style: italic;">target_file</span></pre>
<p>grep 的 -v 选项表示选择 <span style="font-style: italic;">target_file</span> 中不匹配目标正则表达式的行。<br />
对于诸如 Java 或者 Ruby 这样的程序设计语言，则没有提供类似的参数。我们需要直接使用正则表达式来匹配不包含以上字符串的行。解决这个问题的正则表达式如下：</p>
<pre>^((?!19\d\d)\d)+$</pre>
<p>其中 <code>(?!19\d\d)</code> 的作用是，一旦正则表达式引擎发现行内包含有符合 <code>19\d\d</code> 模式的数据，即判断该行不匹配此模式；如果一直没有发现符合 <code>19\d\d</code> 模式的数据，而且所有数据都是数字字符，则该行数据匹配此模式。这样就能选取到目标文件中所有不包含以上字符串的行。通常情况下，我们并不需要使用捕获型括号，以上表达式可以进一步修改成为：</p>
<pre>^(?:(?!19\d\d)\d)+$</pre>
<p>修改后的正则表达式的效率更高。</p>
<p>正则表达式是处理文本时的一个强有力的工具。最初的正则表达式出现于理论计算机科学的自动控制理论和形式语言理论中。如果需要学习正则表达式，倘若只是从网络上摘抄一星半点的实例或者读一些30分钟速成教程，是难以真正掌握这个强大工具的。有关正则表达式方面的最好的书籍之一应该是 <a href="http://regex.info/">Jeffery Friedl</a> 的 <em><a href="http://www.douban.com/subject/1872091/" target="_blank">Master Regular Expressions</a></em>，国内既有<a href="http://www.douban.com/subject/1450763/">第二版的影印版</a>，也有<a href="http://www.luanxiang.org/">余晟</a>翻译的<a href="http://www.douban.com/subject/2154713/">第三版译本</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dreamcode.org/blog/posts/5.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
