<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>鬼の领地 &#187; 探究学习</title>
	<atom:link href="http://blog.upsuper.org/category/%e6%8e%a2%e7%a9%b6%e5%ad%a6%e4%b9%a0/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.upsuper.org</link>
	<description>the place where there are some ghost appearing...</description>
	<lastBuildDate>Wed, 19 Oct 2011 13:21:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>动态切换 Linux 使用的 CPU 数量</title>
		<link>http://blog.upsuper.org/dynamic-modify-cpu-number/</link>
		<comments>http://blog.upsuper.org/dynamic-modify-cpu-number/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 06:03:36 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[多核]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1220</guid>
		<description><![CDATA[由于要测试一些代码，其运行结果会受到多核并行的影响，所以希望能够调整使用的 CPU 数量。网络上之前看到的方法是在内核的启动参数上添加一个 maxcpus，但是如果这样的话每切换一次都要重启一次，是在太麻烦了。想想 Linux 应该是很强大的，所以可以动态修改 CPU 数量才对。 无意中看到 Linux 代码的 Documentation 文件夹下有个文件叫做 cpu-hotplug.txt，于是就看了一下，发现可以在 /sys/devices/system/cpu 看到代表各 CPU 的文件夹按照 cpuX 的命名方式，如 cpu0、cpu1、cpu2 等。这些文件夹里面有一个 online 文件，如果其值为0则禁用该 CPU，如果为1则启用该 CPU。注意，这里需要 root 权限哦。 因为我只要在单核和多核之间切换，所以我写了两个脚本放在 /usr/local/sbin 里面： singlecore 1 2 3 4 5 6 7 8 9 10 11 12 #!/bin/bash &#160; cpus_dir=&#34;/sys/devices/system/cpu&#34; &#160; for cpu in $&#40;ls &#34;$cpus_dir&#34; &#124; grep [...]]]></description>
			<content:encoded><![CDATA[<p>由于要测试一些代码，其运行结果会受到多核并行的影响，所以希望能够调整使用的 CPU 数量。网络上之前看到的方法是在内核的启动参数上添加一个 maxcpus，但是如果这样的话每切换一次都要重启一次，是在太麻烦了。想想 Linux 应该是很强大的，所以可以动态修改 CPU 数量才对。</p>
<p>无意中看到 Linux 代码的 Documentation 文件夹下有个文件叫做 cpu-hotplug.txt，于是就看了一下，发现可以在 /sys/devices/system/cpu 看到代表各 CPU 的文件夹按照 cpuX 的命名方式，如 cpu0、cpu1、cpu2 等。这些文件夹里面有一个 online 文件，如果其值为0则禁用该 CPU，如果为1则启用该 CPU。注意，这里需要 root 权限哦。</p>
<p>因为我只要在单核和多核之间切换，所以我写了两个脚本放在 /usr/local/sbin 里面：</p>
<p>singlecore</p>

<div class="wp_codebox"><table><tr id="p12203"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1220code3"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #007800;">cpus_dir</span>=<span style="color: #ff0000;">&quot;/sys/devices/system/cpu&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> cpu <span style="color: #000000; font-weight: bold;">in</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpus_dir</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'cpu[0-9]\+'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #007800;">cpu_online</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpus_dir</span>/<span style="color: #007800;">$cpu</span>/online&quot;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpu_online</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$cpu_online</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000;">0</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpu_online</span>&quot;</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></td></tr></table></div>

<p>multicore</p>

<div class="wp_codebox"><table><tr id="p12204"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1220code4"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #007800;">cpus_dir</span>=<span style="color: #ff0000;">&quot;/sys/devices/system/cpu&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> cpu <span style="color: #000000; font-weight: bold;">in</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpus_dir</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'cpu[0-9]\+'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #007800;">cpu_online</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpus_dir</span>/<span style="color: #007800;">$cpu</span>/online&quot;</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpu_online</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$cpu_online</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$cpu_online</span>&quot;</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></td></tr></table></div>

<p>之后需要切换的时候，只要运行 sudo singlecore 或者 sudo multicore 就可以了~</p>
<p>顺便说一句，我当时在想，如果我禁用了所有的 CPU 会怎么样呢？结果发现 cpu0 是没有 online 文件的，也就是 Linux 至少保证一个 CPU 处于可用状态。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/dynamic-modify-cpu-number/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>安装配置 LXR</title>
		<link>http://blog.upsuper.org/setup-lxr/</link>
		<comments>http://blog.upsuper.org/setup-lxr/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 07:07:02 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[LXR]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1215</guid>
		<description><![CDATA[专业课学习操作系统，满心欢喜地以为可以是 Linux 代码导读，结果选用了一本八十年代的教材，介绍 UNIX v6 的。于是自己从图书馆借来了内核开发的入门读物《Linux 内核设计与实现》。既然是介绍内核的书，自然少不了代码，但是书中又不可能将每个提到的代码的相关信息全部写出来，这时就得自己去查看代码。查看代码的话，虽然 Linux 的代码可以很容易地得到，但那来看终归有些麻烦，各种调用需要查找半天。于是想起了很有名的一个网站 LXR：http://lxr.linux.no，Linux 交叉引用。这个网站好是好，就是网络原因速度太慢，于是就想自己装一个。 先说一句，下面的安装环境都是64位 Gentoo。 最开始找到了 LXR Cross Referencer 这个项目，一看最后更新时间还挺新，看起来是一直都还在维护的。然后在 Gentoo 的网站上查到 LXR 是可以直接用 portage 安装的，于是安装，安装相关的包，最后放弃了。出于什么原因我也不记得了，最后一个原因肯定是不好看，肯定达不到上面那个网站的效果，所以就放弃了，到那个网站上去下载 LXR 分出来的版本 LXRng。（话说这个 ng 不会是表示 next generation 吧？） 安装支持库 首先从 LXR 的网站上用 git 把代码下载下来， 1 git clone git://lxr.linux.no/git/lxrng.git 然后我打开了里面的 INSTALL 文件，里面写着好多好多库。先说结论吧，在 Gentoo 的官方源里面，有两个库是没有的，分别是 Search-Xapian 和 CGI-Ajax，这两个最后安装。 最首要的是先安装 PostgreSQL，由于 LXR 是用 Perl [...]]]></description>
			<content:encoded><![CDATA[<p>专业课学习操作系统，满心欢喜地以为可以是 Linux 代码导读，结果选用了一本八十年代的教材，介绍 UNIX v6 的。于是自己从图书馆借来了内核开发的入门读物《Linux 内核设计与实现》。既然是介绍内核的书，自然少不了代码，但是书中又不可能将每个提到的代码的相关信息全部写出来，这时就得自己去查看代码。查看代码的话，虽然 Linux 的代码可以很容易地得到，但那来看终归有些麻烦，各种调用需要查找半天。于是想起了很有名的一个网站 LXR：<a href="http://lxr.linux.no">http://lxr.linux.no</a>，Linux 交叉引用。这个网站好是好，就是网络原因速度太慢，于是就想自己装一个。</p>
<p>先说一句，下面的安装环境都是64位 Gentoo。</p>
<p>最开始找到了 <a href="http://sourceforge.net/projects/lxr/">LXR Cross Referencer</a> 这个项目，一看最后更新时间还挺新，看起来是一直都还在维护的。然后在 Gentoo 的网站上查到 LXR 是可以直接用 portage 安装的，于是安装，安装相关的包，最后放弃了。出于什么原因我也不记得了，最后一个原因肯定是不好看，肯定达不到上面那个网站的效果，所以就放弃了，到那个网站上去下载 LXR 分出来的版本 LXRng。（话说这个 ng 不会是表示 next generation 吧？）<br />
<span id="more-1215"></span></p>
<h3>安装支持库</h3>
<p>首先从 LXR 的网站上用 git 把代码下载下来，</p>

<div class="wp_codebox"><table><tr id="p121523"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1215code23"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>lxr.linux.no<span style="color: #000000; font-weight: bold;">/</span>git<span style="color: #000000; font-weight: bold;">/</span>lxrng.git</pre></td></tr></table></div>

<p>然后我打开了里面的 INSTALL 文件，里面写着好多好多库。先说结论吧，在 Gentoo 的官方源里面，有两个库是没有的，分别是 Search-Xapian 和 CGI-Ajax，这两个最后安装。</p>
<p>最首要的是先安装 PostgreSQL，由于 LXR 是用 Perl 写成的，所以在 USE 里面加入了 Perl，然后安装。安装完成以后，安装 PostgreSQL 的 Perl 库 DBD-Pg。接下去安装 Cgi-Simple、HTML-Parser、HTML-Entities、Term-ProgressBar、Devel-Size、Template-Toolkit，这些都很容易，直接安装就可以了。（虽然我确定这些包的名称还费了些时间）</p>
<p>然后是 Apache 和它的 mod_perl，因为之前安装了，并没有太大困难，这里也不详述了。</p>
<p>最麻烦的问题来了，对于源里没有的 Search-Xapian 和 CGI-Ajax 怎么办呢？先把 Xapian 的主要部分给安装了吧。</p>
<p>安装 xapian 和 xapian-bindings 这两个包。因为这两个包的最新版本对 amd64 平台都是 unstable 的，所以要在 /etc/portage/package.keywords 里面加入</p>

<div class="wp_codebox"><table><tr id="p121524"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1215code24"><pre class="text" style="font-family:monospace;">=dev-libs/xapian-1.2.7-r1 ~amd64
=dev-libs/xapian-bindings-1.2.7-r2 ~amd64</pre></td></tr></table></div>

<p>（是的，在 Gentoo 的查询系统上显示，xapian 的 1.2.5 是稳定版本，我也曾经试图安装那个版本，然后仅安装非稳定版的 -bindings，但是之后安装的 Search-Xapian 还是会要求新的 1.2.7，所以就这样吧。另外一般状况下，最前面是写 >= 的，但是我出于个人喜好和完美主义，写了 =。）接下去直接安装这两个包即可。记得检查已经在 USE 里面加入了 perl。</p>
<p>接下去安装那两个包。</p>
<p>Gentoo 有个很神奇的工具，也是我这次才发现的，叫做 g-cpan，可以把 CPAN 上面的包自动打包安装为 portage 的包。不过如果是第一次使用必须要先配置一下，在 /etc/make.conf 最后加上</p>

<div class="wp_codebox"><table><tr id="p121525"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1215code25"><pre class="text" style="font-family:monospace;">ACCEPT_KEYWORDS=&quot;amd64&quot;
PORTDIR_OVERLAY=&quot;/usr/local/portage&quot;</pre></td></tr></table></div>

<p>（虽然这个配置看过去很简单，不过因为一开始忽略了这件事情，所以纠结了很长时间……）</p>
<p>接下去用 g-cpan 安装就可以了</p>

<div class="wp_codebox"><table><tr id="p121526"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1215code26"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> g-cpan <span style="color: #660033;">-g</span> CGI::Ajax Search::Xapian
<span style="color: #c20cb9; font-weight: bold;">sudo</span> emerge CGI-Ajax Search-Xapian</pre></td></tr></table></div>

<p>至此需要安装的东西就已经全部装完了，下面进入第二阶段~</p>
<h3>配置数据库</h3>
<p>这个很简单了，不过在配置之前要先把自己将会用到的用户加入到 postgres 组里以保证可以访问。最重要的是要把之后的 apache 用户加入到 postgres 组里，否则后面会出现一些状况。</p>
<p>然后 su 到 postgres 用户里，添加用户 root，并把 root 设置为管理员（因为之后生成的时候需要用到）</p>

<div class="wp_codebox"><table><tr id="p121527"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1215code27"><pre class="bash" style="font-family:monospace;">createuser root</pre></td></tr></table></div>

<p>然后创建 LXR 的数据库</p>

<div class="wp_codebox"><table><tr id="p121528"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1215code28"><pre class="bash" style="font-family:monospace;">createdb lxrng</pre></td></tr></table></div>

<p>大体上这样就没问题了。</p>
<h3>调整配置文件并建立工作目录</h3>
<p>我出于完美主义的原因，将 LXR 的工作目录放在了 /var/lib/lxrng 里面，如果你没有那些奇怪的癖好，完全可以直接在自己的文件夹下面放置这些东西。</p>
<p>首先要设置配置文件，将 LXR 根目录下的 lxrng.conf-dist 复制为 lxrng.conf，然后打开修改。里面大体上还是比较清晰的，如果只是要做一个 Linux 代码的交叉引用的话，大体上按照里面的配置，修改第10行</p>

<div class="wp_codebox"><table><tr id="p121529"><td class="line_numbers"><pre>10
11
12
13
</pre></td><td class="code" id="p1215code29"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gitrepo</span> <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Git</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'/var/lib/lxrng/repos/linux-2.6/.git'</span><span style="color: #339933;">,</span>
	  release_re <span style="color: #339933;">=&gt;</span> <span style="color: #009966; font-style: italic;">qr/^v[^-]*$/</span><span style="color: #339933;">,</span>
	  author_timestamp <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>里面的那个路径，使其指向你放置代码的 git 源（一般是代码文件夹下的 .git）。</p>
<p>如果你没有使用 git 来抓取代码，而是直接下载某个版本的代码，如 v3.1，可以放置到比如 /var/lib/lxrng/repos/linux/v3.1，那么这个部分就修改为</p>

<div class="wp_codebox"><table><tr id="p121530"><td class="line_numbers"><pre>10
11
12
</pre></td><td class="code" id="p1215code30"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Plain</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$plainrepo</span> <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Plain</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'/var/lib/lxrng/repos/linux'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>即可。（注意上面的 $gitrepo 在下面还有使用过一次，如果修改的话需要一并修改）</p>
<p>接下去是第19行</p>

<div class="wp_codebox"><table><tr id="p121531"><td class="line_numbers"><pre>19
</pre></td><td class="code" id="p1215code31"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$search</span>  <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Search</span><span style="color: #339933;">::</span><span style="color: #006600;">Xapian</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'/var/lib/lxrng/text-db/linux-2.6'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>需要在某个位置建立一个 text-db 文件夹，然后将上面的路径修改为你建立的那个文件夹的路径即可。同样的操作也发生在第29行</p>

<div class="wp_codebox"><table><tr id="p121532"><td class="line_numbers"><pre>28
29
</pre></td><td class="code" id="p1215code32"><pre class="perl" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;"># Must be writable by httpd user:</span>
	<span style="color: #ff0000;">'cache'</span>	      <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/var/lib/lxrng/cache'</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>注意这个文件夹需要对 apache:apache 可写。我的做法是把这个文件夹的组设置为 apache，然后设置权限为0775，当然也可以直接把所有者设置为 apache 然后保留原来权限。</p>
<p>注释掉下面这行</p>

<div class="wp_codebox"><table><tr id="p121533"><td class="line_numbers"><pre>36
</pre></td><td class="code" id="p1215code33"><pre class="perl" style="font-family:monospace;">	<span style="color: #ff0000;">'ctags_flags'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">&quot;-I<span style="color: #000099; font-weight: bold;">\@</span>$LXRng::ROOT/lxr-ctags-quirks&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>不要问我为什么，这个我真不知道，总之如果部注释掉一会儿会出错。</p>
<p>最后是要生成引用的版本和默认显示的版本：</p>

<div class="wp_codebox"><table><tr id="p121534"><td class="line_numbers"><pre>37
38
39
</pre></td><td class="code" id="p1215code34"><pre class="perl" style="font-family:monospace;"><span style="color: #ff0000;">'ver_list'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$gitrepo</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">allversions</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
<span style="color: #ff0000;">'ver_default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'v2.6.20.3'</span><span style="color: #339933;">,</span></pre></td></tr></table></div>

<p>我强烈建议你将 $gitrepo->allversions 修改为你想看的几个版本，甚至于只有一个版本也是没有问题的即使你有完整的历史记录，因为每个版本都需要生成很长时间，而且似乎过程很不稳定，如果没有特别的原因，最好不要生成太多版本。如果是不用 git 源的话，只要把你放在那个文件夹里的对应版本号填进去就可以了，最后修改默认显示的版本。</p>
<p>如果还想添加其他的代码，只要把代码最后 return 的大括号里面的部分复制一遍，根据需要修改就可以了。</p>
<h3>初始化数据库及生成交叉引用</h3>
<p>首先要添加一个符号链接</p>

<div class="wp_codebox"><table><tr id="p121535"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1215code35"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>exuberants-ctags <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ctags-exuberants</pre></td></tr></table></div>

<p>接下去没什么太大的差别，就是进入程序所在目录，然后</p>

<div class="wp_codebox"><table><tr id="p121536"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1215code36"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>lxr-db-admin linux <span style="color: #660033;">--init</span>
.<span style="color: #000000; font-weight: bold;">/</span>lxr-genref linux</pre></td></tr></table></div>

<p>值得一说的是，这个过程非常非常非常漫长，在我的 i7 本上的虚拟机里，一跑至少三四个小时，而且看起来还很不稳定，不时会自动强制退出，而且退出以后可能会出现一些问题导致无法继续。这个问题比较严重，遇到这个问题如何解决放到之后的部分再来说吧。</p>
<h3>配置 Apache </h3>
<p>最后来配置 Apache。直接把文件夹下的 apache2-site.conf-dist-mod_perl 复制到 /etc/apache/vhosts.d/10_lxrng.con，然后打开这个文件，将里面的所有 @@LXRROOT@@ 和 @@LXRURL@@ 根据自己的情况替换为相应的路径就可以了。然后重新启动 Apache</p>

<div class="wp_codebox"><table><tr id="p121537"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1215code37"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rc.d<span style="color: #000000; font-weight: bold;">/</span>apache restart</pre></td></tr></table></div>

<h3>问题解决</h3>
<p>由于原来的版本在我这里基本上没什么希望能生成结束，所以我对这个程序做了一些修改，这个修改后的版本可以直接在我的 GitHub 上面找到：<a href="https://github.com/upsuper/lxrng" title="upsuper/lxrng - GitHub" target="_blank">upsuper/lxrng</a>。如果需要的话，可以不使用原来官方的代码而直接使用我修改过的代码。主要的差别有几点：一是消除了生成交叉引用时过大量的输出信息；二是增加了交叉引用生成时刷写 Xapian 索引的频率，以减少退出重做时可能出现的错误；三是修正了一些最后浏览时可能遇到的问题。</p>
<p>当然生成的时候还是可能会出错，这我也没办法。如果生成时被意外中断，重新执行又出现错误，可以将我修改的那个程序里面的 lxr-genref 第336行</p>

<div class="wp_codebox"><table><tr id="p121538"><td class="line_numbers"><pre>336
</pre></td><td class="code" id="p1215code38"><pre class="perl" style="font-family:monospace;">	<span style="color: #666666; font-style: italic;">#warn(&quot;here $docid\n&quot;);</span></pre></td></tr></table></div>

<p>的注释符去掉，重新运行 lxr-genref，然后查看当程序报错时停止的那个编号，比如 12345。然后执行 psql lxrng 进入 lxrng 数据库，执行</p>

<div class="wp_codebox"><table><tr id="p121539"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1215code39"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> hashed_documents <span style="color: #993333; font-weight: bold;">WHERE</span> doc_id<span style="color: #66cc66;">&gt;=</span><span style="color: #cc66cc;">12345</span></pre></td></tr></table></div>

<p>然后再次执行 lxr-genref。这个过程可能反复一两次，直到不会报错位置。</p>
<p>如果用原始版本的话，最后在浏览的时候使用搜索，有可能会出现500错误以及无法显示出来的情况，如果出现，可以参考我做的修改。</p>
<h3>后记</h3>
<p>配置这个 LXR 真是折腾死我了，费了好大功夫，最后也总算是成功了。</p>
<p>另外真是很久很久没有在这里写东西了。也正因为这个过程实在太麻烦了，所以来写一写，权当一个记录。不过现在有 GitHub 这种东西，倒是好得多了。</p>
<h3>参考文档</h3>
<ul>
<li><a href="http://mohammadthalif.wordpress.com/2010/07/24/how-to-setup-lxr-%E2%80%93-step-by-step-guide-3/" target="_blank">How to setup LXR – Step by Step guide &laquo; Mohamed Thalib&#039;s Blog</a></li>
<li><a href="http://www.kernelchina.org/node/241" target="_blank">在自己的计算机上建立lxr源代码检索服务器 | kernelchina</a></li>
<li><a href="http://wenku.baidu.com/view/8150646727d3240c8447ef2d.html" target="_blank">lxrng.install-gentoo_百度文库</a></li>
<li><a href="http://www.gentoo.org/proj/en/perl/g-cpan.xml" target="_blank">Gentoo Linux Documentation &#8212; g-cpan Guide</a></li>
</ul>
<p>（貌似还有些别的参考资料，不记得是什么了……）</p>
<h3>参考配置文件</h3>
<p>最后最后贴一下自己的配置文件吧。配置文件里面声明了两个代码，一个是 Liunx 的，一个是 UNIX v6 的，Linux 是用 git，UNIX 是代码。程序全部放在 /var/lib/lxrng 里面，代码放在 /var/lig/lxrng/repos 里。</p>

<div class="wp_codebox"><table><tr id="p121540"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
</pre></td><td class="code" id="p1215code40"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># -*- mode: perl -*-</span>
<span style="color: #666666; font-style: italic;"># Configuration file</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># </span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Index</span><span style="color: #339933;">::</span><span style="color: #006600;">PgBatch</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Git</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Plain</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Search</span><span style="color: #339933;">::</span><span style="color: #006600;">Xapian</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$linuxrepo</span> <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Git</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'/var/lib/lxrng/repos/linux.git'</span><span style="color: #339933;">,</span>
	  release_re <span style="color: #339933;">=&gt;</span> <span style="color: #009966; font-style: italic;">qr/^v[^-]*$/</span><span style="color: #339933;">,</span>
	  author_timestamp <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$unixrepo</span> <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Repo</span><span style="color: #339933;">::</span><span style="color: #006600;">Plain</span>
    <span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'/var/lib/lxrng/repos/unix'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$index</span>   <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Index</span><span style="color: #339933;">::</span><span style="color: #006600;">PgBatch</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>db_spec <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'dbname=lxrng;port=5432'</span><span style="color: #339933;">,</span> 
					 db_user <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #339933;">,</span> db_pass <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;&quot;</span><span style="color: #339933;">,</span>
					 <span style="color: #666666; font-style: italic;"># table_prefix =&gt; 'lxr'</span>
					 <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$search</span>  <span style="color: #339933;">=</span> LXRng<span style="color: #339933;">::</span><span style="color: #006600;">Search</span><span style="color: #339933;">::</span><span style="color: #006600;">Xapian</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'/var/lib/lxrng/text-db'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">return</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #ff0000;">'linux'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #ff0000;">'repository'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$linuxrepo</span><span style="color: #339933;">,</span>
	<span style="color: #ff0000;">'index'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$index</span><span style="color: #339933;">,</span>
	<span style="color: #ff0000;">'search'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$search</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'base_url'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'http://upsuper-gentoo/lxr'</span><span style="color: #339933;">,</span>
	<span style="color: #666666; font-style: italic;"># Must be writable by httpd user:</span>
	<span style="color: #ff0000;">'cache'</span>	      <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/var/lib/lxrng/cache/linux'</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'fs_charset'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'iso-8859-1'</span><span style="color: #339933;">,</span>
	<span style="color: #666666; font-style: italic;"># Tried successively</span>
	<span style="color: #ff0000;">'content_charset'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'utf-8'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'iso-8859-1'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'languages'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'C'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'GnuAsm'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'Kconfig'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	<span style="color: #666666; font-style: italic;">#'ctags_flags' =&gt; [&quot;-I\@$LXRng::ROOT/lxr-ctags-quirks&quot;],</span>
	<span style="color: #666666; font-style: italic;">#'ver_list'    =&gt; [$gitrepo-&gt;allversions],</span>
	<span style="color: #ff0000;">'ver_list'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'v2.6.34'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'v3.0'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'ver_default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'v2.6.34'</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'include_maps'</span> <span style="color: #339933;">=&gt;</span> 
	    <span style="color: #009900;">&#91;</span>
	     <span style="color: #009900;">&#91;</span><span style="color: #000066;">qr</span><span style="color: #339933;">|^</span>arch<span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*?</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/|,</span> <span style="color: #000066;">qr</span><span style="color: #339933;">|^</span>asm<span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|,</span>
	      <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;include/asm-$_[0]/$_[1]&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	     <span style="color: #009900;">&#91;</span><span style="color: #000066;">qr</span><span style="color: #339933;">|^</span>include<span style="color: #339933;">/</span>asm<span style="color: #339933;">-</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*?</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/|,</span> <span style="color: #000066;">qr</span><span style="color: #339933;">|^</span>asm<span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|,</span>
	      <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;include/asm-$_[0]/$_[1]&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	     <span style="color: #009900;">&#91;</span><span style="color: #000066;">qr</span><span style="color: #339933;">|^|,</span> <span style="color: #000066;">qr</span><span style="color: #339933;">|^</span>asm<span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|,</span>
	      <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">map</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;include/asm-$_/$_[0]&quot;</span> <span style="color: #009900;">&#125;</span>
		    <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>i386 x86_64<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	     <span style="color: #009900;">&#91;</span><span style="color: #000066;">qr</span><span style="color: #339933;">|^|,</span> <span style="color: #000066;">qr</span><span style="color: #339933;">|</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|,</span>
	      <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;include/$_[0]&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	     <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #ff0000;">'unix'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #ff0000;">'repository'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$unixrepo</span><span style="color: #339933;">,</span>
	<span style="color: #ff0000;">'index'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$index</span><span style="color: #339933;">,</span>
	<span style="color: #ff0000;">'search'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$search</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'base_url'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'http://upsuper-gentoo/lxr'</span><span style="color: #339933;">,</span>
	<span style="color: #666666; font-style: italic;"># Must be writable by httpd user:</span>
	<span style="color: #ff0000;">'cache'</span>	      <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/var/lib/lxrng/cache/unix'</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'fs_charset'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'iso-8859-1'</span><span style="color: #339933;">,</span>
	<span style="color: #666666; font-style: italic;"># Tried successively</span>
	<span style="color: #ff0000;">'content_charset'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'utf-8'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'iso-8859-1'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'languages'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'C'</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'GnuAsm'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	<span style="color: #666666; font-style: italic;">#'ctags_flags' =&gt; [&quot;-I\@$LXRng::ROOT/lxr-ctags-quirks&quot;],</span>
	<span style="color: #ff0000;">'ver_list'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'v6'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'ver_default'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'v6'</span><span style="color: #339933;">,</span>
&nbsp;
	<span style="color: #ff0000;">'include_maps'</span> <span style="color: #339933;">=&gt;</span> 
	    <span style="color: #009900;">&#91;</span>
	     <span style="color: #009900;">&#91;</span><span style="color: #000066;">qr</span><span style="color: #339933;">|^|,</span> <span style="color: #000066;">qr</span><span style="color: #339933;">|</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">.*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">|,</span>
	      <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;sys/$_[0]&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	     <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/setup-lxr/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Gmail的超级子邮箱功能</title>
		<link>http://blog.upsuper.org/gmail-super-sub-mailbox/</link>
		<comments>http://blog.upsuper.org/gmail-super-sub-mailbox/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 14:11:22 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1209</guid>
		<description><![CDATA[如果你也用 Gmail，他可以让你轻易拥有无限多的子邮箱，发给这些邮箱也就等于发给你的邮箱。这有什么意义呢？很简单，你可以在每个地方注册的时候都使用不同的邮箱，这样当你收到垃圾邮件广告邮件，你就可以知道是从哪里来的了~再结合 Gmail 强大的过滤器，你也可以针对性的进行屏蔽~ Gmail 事实上支持两种方式来扩张你的邮箱，第一种是在你的用户名后面加上“+”和任意字符串，比如我的邮箱 quanxunzhen@gmail.com（我这邮箱无所谓了已经嗯），如果我想要识别不同的网站，比如豆瓣，我可以直接在豆瓣的注册邮箱里填写 quanxunzhen+douban@gmail.com，所有验证邮件都可以发给我，我如果不想申请一个新邮箱却想注册个豆瓣小号，也可以再写 quanxunzhen+douban2@gmail.com。 当然，支持上面的方式固然是最好的，但遗憾的是很多网站并不支持带加号的邮箱，那就要稍稍麻烦点了。 根据 @fanzeyi 的说法，Gmail 的邮箱是自动忽略点，也就是“.”的，也就是说对于我上面的邮箱，如果写为 quan.xun.zhen@gmail.com，或者 ..quanxunzhen..@gmail.com，我照样可以收到。而且这样写法的邮箱通常不会被屏蔽，因为点毕竟是邮箱必备的部分。 但是这样加点有一个问题，就是我们无法像第一种方式那样很容易的区分来源，因此我们不得不进行某种编码。 顺序编码 第一种编码的思想大体上是按照传统的数据库中记录的自增 ID，转为二进制表示，具体的说就是，比如我这个邮箱有11位，那么我们可以以中间有打点或者没有打点作为二进制位中的0和1，比如就可以如下表示： 1 2 3 4 5 0 quanxunzhen 1 quanxunzhen. 2 quanxunzhe.n 3 quanxunzhe.n. 29 quanxun.z.h.en. 这样…… 但是这样总编码数也就 2^len(email)+1 种，对于我邮箱这么长，也仅仅4096种，总归有点少。（其实也不少了吧喂……） 于是我们考虑一下扩张的方法。 其实扩张很简单，因为任意两个字母之间可以插入的点是任意多的，我们可以利用这一点按照一定的协议来编码，比如我们规定第一个字符之前如果有 n 个点，则之后每个字母之间最多可以有 n+1 个点，这样当第一个字符前有 n 个点时，最大可以编码 (n+2)^len(email) 种，如果规定这里每次数字都是从上一次结束的数字开始，编码就不会重复了，而且可编码的范围大大增加，却又没有太多的增加点的数量。对于我的邮箱来说，前面一个点也没有时可以有 2048 种，有一个点时可以有 177147+2048 种，有两个点时可以有 4194304+177147+2048 种，我相信是用不完的了…… [...]]]></description>
			<content:encoded><![CDATA[<p>如果你也用 Gmail，他可以让你轻易拥有无限多的子邮箱，发给这些邮箱也就等于发给你的邮箱。这有什么意义呢？很简单，你可以在每个地方注册的时候都使用不同的邮箱，这样当你收到垃圾邮件广告邮件，你就可以知道是从哪里来的了~再结合 Gmail 强大的过滤器，你也可以针对性的进行屏蔽~</p>
<p>Gmail 事实上支持两种方式来扩张你的邮箱，第一种是在你的用户名后面加上“+”和任意字符串，比如我的邮箱 quanxunzhen@gmail.com（我这邮箱无所谓了已经嗯），如果我想要识别不同的网站，比如豆瓣，我可以直接在豆瓣的注册邮箱里填写 quanxunzhen+douban@gmail.com，所有验证邮件都可以发给我，我如果不想申请一个新邮箱却想注册个豆瓣小号，也可以再写 quanxunzhen+douban2@gmail.com。</p>
<p>当然，支持上面的方式固然是最好的，但遗憾的是很多网站并不支持带加号的邮箱，那就要稍稍麻烦点了。</p>
<p>根据 @<a href="http://fanfou.com/fanzeyi">fanzeyi</a> 的说法，Gmail 的邮箱是自动忽略点，也就是“.”的，也就是说对于我上面的邮箱，如果写为 quan.xun.zhen@gmail.com，或者 ..quanxunzhen..@gmail.com，我照样可以收到。而且这样写法的邮箱通常不会被屏蔽，因为点毕竟是邮箱必备的部分。</p>
<p>但是这样加点有一个问题，就是我们无法像第一种方式那样很容易的区分来源，因此我们不得不进行某种编码。</p>
<h3>顺序编码</h3>
<p>第一种编码的思想大体上是按照传统的数据库中记录的自增 ID，转为二进制表示，具体的说就是，比如我这个邮箱有11位，那么我们可以以中间有打点或者没有打点作为二进制位中的0和1，比如就可以如下表示：</p>

<div class="wp_codebox"><table><tr id="p120945"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1209code45"><pre class="text" style="font-family:monospace;">0 quanxunzhen
1 quanxunzhen.
2 quanxunzhe.n
3 quanxunzhe.n.
29 quanxun.z.h.en.</pre></td></tr></table></div>

<p>这样……</p>
<p>但是这样总编码数也就 2<span style="display:none">^</span><sup>len(email)+1</sup> 种，对于我邮箱这么长，也仅仅4096种，总归有点少。（其实也不少了吧喂……）</p>
<p>于是我们考虑一下扩张的方法。</p>
<p>其实扩张很简单，因为任意两个字母之间可以插入的点是任意多的，我们可以利用这一点按照一定的协议来编码，比如我们规定第一个字符之前如果有 n 个点，则之后每个字母之间最多可以有 n+1 个点，这样当第一个字符前有 n 个点时，最大可以编码 (n+2)<span style="display:none">^</span><sup>len(email)</sup> 种，如果规定这里每次数字都是从上一次结束的数字开始，编码就不会重复了，而且可编码的范围大大增加，却又没有太多的增加点的数量。对于我的邮箱来说，前面一个点也没有时可以有 2048 种，有一个点时可以有 177147+2048 种，有两个点时可以有 4194304+177147+2048 种，我相信是用不完的了……</p>
<p>事实上基于此还可以延伸出各种各样的编码方式~</p>
<h3>字符编码</h3>
<p>不过上面的方法总归不那么直观，而且如果想追踪来源，还要建表，表的同步还是个问题，所以这个问题还是挺大的……于是我有了第二种想法，可以把注册地的名字嵌入到里面~</p>
<p>最基本的想法是根据字母序，比如在 Arch 论坛注册我们可以把 Arch 变成数字串 0 17 2 7，插入进去变成：</p>

<div class="wp_codebox"><table><tr id="p120946"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1209code46"><pre class="text" style="font-family:monospace;">qu.................a..n.......xunzhen</pre></td></tr></table></div>

<p>不过我们可以明显的感觉到很蛋疼……Arch 还算好的，如果是新浪（Sina -> 18 8 13 0）或者淫淫网（Renren -> 17 4 13 17 4 13）就更蛋疼了……</p>
<p>但是我们感觉到不是这样的，我们完全不需要那么多字母其实也可以认出他们来不是么？比如淫淫网我们可以用 rr，或者原名校内的 xn，新浪就 sn 什么的，这样需要的字母就少了，我们就可以利用变换进制的优势了~26对于二进制位需要5位，对于3进制恰好只要3位，当然算起来如果你的邮箱够长肯定还是用二进制可以增加的更短一些，对于我来说就是如此，比如上面的就可以这样变化了：</p>

<div class="wp_codebox"><table><tr id="p120947"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1209code47"><pre class="text" style="font-family:monospace;">rr -&gt; 17 17 -&gt; 10001 10001 -&gt; q.uanx.u.nzhe.n
xn -&gt; 23 13 -&gt; 10111 01101 -&gt; q.ua.n.x.un.z.he.n
sn -&gt; 18 13 -&gt; 10010 01101 -&gt; q.uan.xun.z.he.n</pre></td></tr></table></div>

<p>如果三进制的话，我的 upsuper 也可以容下了：</p>

<div class="wp_codebox"><table><tr id="p120948"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1209code48"><pre class="text" style="font-family:monospace;">rr -&gt; 17 17 -&gt; 122 122 -&gt; u.p..s..u.p..e..r
xn -&gt; 23 13 -&gt; 212 111 -&gt; u..p.s..u.p.e.r
sn -&gt; 18 13 -&gt; 200 111 -&gt; u..psu.p.e.r</pre></td></tr></table></div>

<p>看过去好多了~</p>
<p>我们还可以发挥其它的想象力，比如找寻标识中的字母频率然后构建一个霍夫曼编码树什么的~</p>
<p>我能想到的暂时只有这么多了，各位还有什么更有意思的想法么？</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/gmail-super-sub-mailbox/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>增强版的Bash提示符</title>
		<link>http://blog.upsuper.org/advanced-prompt-string-of-bash/</link>
		<comments>http://blog.upsuper.org/advanced-prompt-string-of-bash/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 06:39:30 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1200</guid>
		<description><![CDATA[上周六参加了好久没有参加的的 SHLUG 月聚，恰逢 TualatriX 也带团来上海。自由讨论的时候，我看到 TualatriX 的终端十分色彩斑斓，便询问，他给我们展示了他的 bash 的两个特色功能：1、当上一条命令返回结果不为0时显示返回值并高亮显示提示符；2、自动检测git分支。他说这个在他的博客上都可以找到，今天想起来去找了一下，发现了这篇：史上最强的PS1 &#124; I&#8217;m TualatriX，感觉满强大的。 不过，说实话，我觉的这个还不够完美，原因有二：一是我发觉高亮显示的时候那个配色相当不怎么样，二是我本来就讨厌提示符太长，这样一下就更长了……于是我就想起 ghosTM 的 zsh 里面有一些信息是放在右边的，我想把返回值也扔右边去，并且是右边上移一行。此外，由于很少使用 git，所以检测 git 分支的功能也就不需要了~ 先放一个最终效果图： 然后直接写出了我的新的 PS1： 1 PS1='`a=$?;if [ $a -ne 0 ]; then a=&#34; &#34;$a; echo -ne &#34;\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]&#34;; fi`\[\e[1;32m\]\u@\h:\[\e[0m\e[1;34m\]\W\[\e[1;34m\]\$ \[\e[0m\]' 非常复杂唉……让我自己再看一次都头晕…… 分解这个提示符 上面看到这个 PS1 写的非常之复杂，不过其实拆解开来也没什么了不起的，只不过看起来蛋疼罢了~ 这个 PS1 可以分为两个部分，第一个部分是： 1 `a=$?;if &#91; $a -ne 0 &#93;; then a=&#34; [...]]]></description>
			<content:encoded><![CDATA[<p>上周六参加了好久没有参加的的 SHLUG 月聚，恰逢 <a href="http://imtx.me/">TualatriX</a> 也带团来上海。自由讨论的时候，我看到 TualatriX 的终端十分色彩斑斓，便询问，他给我们展示了他的 bash 的两个特色功能：1、当上一条命令返回结果不为0时显示返回值并高亮显示提示符；2、自动检测git分支。他说这个在他的博客上都可以找到，今天想起来去找了一下，发现了这篇：<a href="http://imtx.me/archives/1298.html">史上最强的PS1 | I&#8217;m TualatriX</a>，感觉满强大的。</p>
<p>不过，说实话，我觉的这个还不够完美，原因有二：一是我发觉高亮显示的时候那个配色相当不怎么样，二是我本来就讨厌提示符太长，这样一下就更长了……于是我就想起 ghosTM 的 zsh 里面有一些信息是放在右边的，我想把返回值也扔右边去，并且是右边上移一行。此外，由于很少使用 git，所以检测 git 分支的功能也就不需要了~</p>
<p>先放一个最终效果图：<br />
<a href="http://blog.upsuper.org/wp-content/uploads/2011/02/031-upsuper@upsuper-laptop-.png"><img src="http://blog.upsuper.org/wp-content/uploads/2011/02/031-upsuper@upsuper-laptop-.png" alt="" title="031-upsuper@upsuper-laptop: ~" width="644" height="433" class="alignnone size-full wp-image-1207" /></a></p>
<p>然后直接写出了我的新的 PS1：</p>

<div class="wp_codebox"><table><tr id="p120055"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1200code55"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">PS1</span>=<span style="color: #ff0000;">'`a=$?;if [ $a -ne 0 ]; then a=&quot;  &quot;$a; echo -ne &quot;\[\e[s\e[1A\e[$((COLUMNS-2))G\e[31m\e[1;41m${a:(-3)}\e[u\]\[\e[0m\e[7m\e[2m\]&quot;; fi`\[\e[1;32m\]\u@\h:\[\e[0m\e[1;34m\]\W\[\e[1;34m\]\$ \[\e[0m\]'</span></pre></td></tr></table></div>

<p>非常复杂唉……让我自己再看一次都头晕……<br />
<span id="more-1200"></span></p>
<h3>分解这个提示符</h3>
<p>上面看到这个 PS1 写的非常之复杂，不过其实拆解开来也没什么了不起的，只不过看起来蛋疼罢了~</p>
<p>这个 PS1 可以分为两个部分，第一个部分是：</p>

<div class="wp_codebox"><table><tr id="p120056"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1200code56"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">`</span><span style="color: #007800;">a</span>=<span style="color: #007800;">$?</span>;<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$a</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #007800;">a</span>=<span style="color: #ff0000;">&quot;  &quot;</span><span style="color: #007800;">$a</span>; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-ne</span> <span style="color: #ff0000;">&quot;\[\e[s\e[1A\e[<span style="color: #007800;">$((COLUMNS-2)</span>)G\e[31m\e[1;41m<span style="color: #007800;">${a:(-3)}</span>\e[u\]\[\e[0m\e[7m\e[2m\]&quot;</span>; <span style="color: #000000; font-weight: bold;">fi</span><span style="color: #000000; font-weight: bold;">`</span></pre></td></tr></table></div>

<p>第二个部分是：</p>

<div class="wp_codebox"><table><tr id="p120057"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1200code57"><pre class="bash" style="font-family:monospace;">\<span style="color: #7a0874; font-weight: bold;">&#91;</span>\e<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span>;32m\<span style="color: #7a0874; font-weight: bold;">&#93;</span>\u<span style="color: #000000; font-weight: bold;">@</span>\h:\<span style="color: #7a0874; font-weight: bold;">&#91;</span>\e<span style="color: #7a0874; font-weight: bold;">&#91;</span>0m\e<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span>;34m\<span style="color: #7a0874; font-weight: bold;">&#93;</span>\W\<span style="color: #7a0874; font-weight: bold;">&#91;</span>\e<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span>;34m\<span style="color: #7a0874; font-weight: bold;">&#93;</span>\$ \<span style="color: #7a0874; font-weight: bold;">&#91;</span>\e<span style="color: #7a0874; font-weight: bold;">&#91;</span>0m\<span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></td></tr></table></div>

<p>我们先来研究第二部份，这个部分看起来比较简短。其中我们可以看到一个 PS1 里面非常基本的结构：\u@\h:\W\$ ，这个结构在我的电脑里就显示为 upsuper@upsuper-laptop:~$ 大家大概可以猜到里面是什么意思了吧。</p>
<p>这个基本骨架理出来，剩下的是看过去最蛋疼的那堆莫名其妙的符号了~我们看到很多 \e[ 这样的东西，事实上这个叫做 ANSI 控制码，在 Linux 和 Windows 的命令行里面都是通用的，\e 是 Escape 键的键码，\e[ 是一切 ANSI 控制码的开头。首先来到 \e[1;32m 这个控制码，这表示设置这个符号之后的字符为亮绿色，而 \e[0m 则是清除所有格式，这样看有没有一点清晰了呢？更多用法可以参考维基百科条目<a href="http://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes">ANSI escape code</a>。</p>
<p>之后还有两个东西不清楚，就是 \[ 和 \]，这两个并不是 ANSI 控制码，而是 Bash 提供的转义符。他们的解释说实话我没看太懂，不过我的理解大概就是，夹在 \[ 和 \] 之间的部分 Bash 假定他们的宽度为0，不正确地标注这两个符号会导致 Bash 的换行错误。总之在所有控制符两侧都加上这两个就对了~</p>
<p>第二个部分解决了，下面来看蛋疼的第一部份</p>

<div class="wp_codebox"><table><tr id="p120058"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1200code58"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">`</span><span style="color: #007800;">a</span>=<span style="color: #007800;">$?</span>;<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$a</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #007800;">a</span>=<span style="color: #ff0000;">&quot;  &quot;</span><span style="color: #007800;">$a</span>; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-ne</span> <span style="color: #ff0000;">&quot;\[\e[s\e[1A\e[<span style="color: #007800;">$((COLUMNS-2)</span>)G\e[31m\e[1;41m<span style="color: #007800;">${a:(-3)}</span>\e[u\]\[\e[0m\e[7m\e[2m\]&quot;</span>; <span style="color: #000000; font-weight: bold;">fi</span><span style="color: #000000; font-weight: bold;">`</span></pre></td></tr></table></div>

<p>很明显，整个结构被一个正引号引起来，表示执行并返回其中的结果。这样我们就可以把这个部分分解开来了：</p>

<div class="wp_codebox"><table><tr id="p120059"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1200code59"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">a</span>=<span style="color: #007800;">$?</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$a</span> <span style="color: #660033;">-ne</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">a</span>=<span style="color: #ff0000;">&quot;  &quot;</span><span style="color: #007800;">$a</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-ne</span> <span style="color: #ff0000;">&quot;\[\e[s\e[1A\e[<span style="color: #007800;">$((COLUMNS-2)</span>)G\e[31m\e[1;41m<span style="color: #007800;">${a:(-3)}</span>\e[u\]\[\e[0m\e[7m\e[2m\]&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></td></tr></table></div>

<p>稍微懂点编程就会觉得这也没什么技术含量嘛，其中 $? 就是上一个程序运行的返回值，我们获取并判断他，如果不为零就进行下面的操作。a=”  “$a 这句我们待会而再看，先看下面那个 echo -ne 的语句。echo 我们知道是显示字符串，而 -ne 实际上是两个参数 -n 和 -e，-n 表示输出字符串后不输出换行符，-e 表示解析后面的转义符。</p>
<p>最后就剩分析那个打印的东西了。我们发现主要部分其实和上面是一样的，无非就是一些设置格式的事情，我们去掉格式设置，发现主要是这样的：</p>

<div class="wp_codebox"><table><tr id="p120060"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1200code60"><pre class="bash" style="font-family:monospace;">\e<span style="color: #7a0874; font-weight: bold;">&#91;</span>s\e<span style="color: #7a0874; font-weight: bold;">&#91;</span>1A\e<span style="color: #7a0874; font-weight: bold;">&#91;</span>$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>COLUMNS-<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>G<span style="color: #800000;">${a:(-3)}</span>\e<span style="color: #7a0874; font-weight: bold;">&#91;</span>u</pre></td></tr></table></div>

<p>这个部分仍然包含许多 ANSI 控制符，第一个是 \e[s，表示保存当前光标位置，与最后一个表示恢复光标位置的控制符 \e[u 遥相呼应，由于我们需要大规模移动光标，所以我们要备份一下位置。然后我们看到 \e[1A，这个控制符表示将光标上移一行。然后之后有一个很复杂的东西 \e[$((COLUMNS-2))G，这个对应的控制符是 \e[*G，表示设置光标到第几列，而 $((COLUMNS-2)) 表示这个列数为当前可显示的最大列数-2。后面有一个 ${a:(-3)}，也就是取前面的后三位显示（返回值的范围是0-255）。</p>
<p>现在我们回到前面的 a=”  “$a，发现这个的目的其实是和 ${a:(-3)} 对应，让这个部分无论如何保证有三个字符可以出现。事实上最初我并不是这么写的，而是写 $((COLUMNS-${#a}+1))，表示 $a 有多长就显示多长。但这样感觉不美观，就改成了固定3字符长。</p>
<p>到这里也就结束了，然后我们发现，其实看过去很复杂的东西，拆开来还是挺简单的嘛~</p>
<h3>参考资料</h3>
<ul>
<li><a href="http://imtx.me/archives/1298.html">史上最强的PS1 | I&#8217;m TualatriX</a></li>
<li><a href="http://hi.baidu.com/shappen/blog/item/4171f5ef57e6e434adafd5aa.html">Bash颜色控制_宠辱不惊，看庭前花开花落；去留无意，望天空云卷云舒_百度空间</a></li>
<li><a href="http://en.wikipedia.org/wiki/ANSI_escape_code">ANSI escape code &#8211; Wikipedia, the free encyclopedia</a></li>
<li><a href="http://www.issociate.de/board/post/434218/Mimic_zsh%27s_right_prompt_in_bash.html">Mimic zsh&#8217;s right prompt in bash</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/advanced-prompt-string-of-bash/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>当小白鼠还真是一件得耐得住折腾的事情——记装 Ubuntu 10.10 RC</title>
		<link>http://blog.upsuper.org/note-for-installing-ubuntu-10-10-rc/</link>
		<comments>http://blog.upsuper.org/note-for-installing-ubuntu-10-10-rc/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 03:08:25 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[小白鼠]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1176</guid>
		<description><![CDATA[当小白鼠绝对是一件得耐得住折腾的事情……当然，这看起来和RC不RC似乎并没有太大的关系，作为在普罗大众之前开始接触桌面Linux的一员，绝对可谓是小白鼠了。 说 Ubuntu 10.10 的安装界面确实是做的不错了，而且还能自动识别需要的私有驱动。不过有一点让我比较无语的是，在我还没有联网的时候，他找到我的无线网卡的私有驱动，但是下载安装不了……所以我不得不接上网线安装。安装过程比较顺利，除了似乎选择硬盘分区的时候十分卡以外，其它的地方还是很满意的，包括一边复制文件一边询问一些详细配置、一边复制文件一边给出 Ubuntu 的特性介绍这样。另外，正如 Canonical 公司之前承诺的那样，中文成为了 Ubuntu 10.10 的官方语言，安装完成后，全部中文界面，并且自动安装好了 ibus-pinyin。不过，Firefox 却意外的成为异类，仍然是英文（先在不知道什么时候已经突然变成中文了）。此外还有一点就是，很希望 ibus-sunpinyin 能尽快成为默认的，因为确实比 ibus-pinyin 好很多的感觉。 一安装完问题就来了，没法启动！后来几经周折，发现原因是安装的时候莫名其妙的把我的安装U盘识别为 sda 而硬盘识别为 sdb，并且安装程序还把这个写进了 fstab 里面。理论上说 Ubuntu 应该自动写入 fstab 的都是 UUID 才对，这次却写了 /dev/sdXY 进去，着实让人感到奇怪。通过我的修复盘手动修改了 fstab 以后终于成功进入了，后面就改成了使用 UUID 了，保证不会出问题……我去网上一搜，没有发现有人遇到同样的问题，我就到 Launchpad 报告了 bug：installer identified hard drive as sdb led to the new system unbootablity。话说我的英文这么差，各位看到有什么语法错误之类的，那也是很正常的了……提交 bug 也算是我对开源的一点贡献了吧…… 然后安装了 nVidia 的私有驱动 [...]]]></description>
			<content:encoded><![CDATA[<p>当小白鼠绝对是一件得耐得住折腾的事情……当然，这看起来和RC不RC似乎并没有太大的关系，作为在普罗大众之前开始接触桌面Linux的一员，绝对可谓是小白鼠了。</p>
<p>说 Ubuntu 10.10 的安装界面确实是做的不错了，而且还能自动识别需要的私有驱动。不过有一点让我比较无语的是，在我还没有联网的时候，他找到我的无线网卡的私有驱动，但是下载安装不了……所以我不得不接上网线安装。安装过程比较顺利，除了似乎选择硬盘分区的时候十分卡以外，其它的地方还是很满意的，包括一边复制文件一边询问一些详细配置、一边复制文件一边给出 Ubuntu 的特性介绍这样。另外，正如 Canonical 公司之前承诺的那样，中文成为了 Ubuntu 10.10 的官方语言，安装完成后，全部中文界面，并且自动安装好了 ibus-pinyin。不过，Firefox 却意外的成为异类，仍然是英文（先在不知道什么时候已经突然变成中文了）。此外还有一点就是，很希望 ibus-sunpinyin 能尽快成为默认的，因为确实比 ibus-pinyin 好很多的感觉。</p>
<p>一安装完问题就来了，没法启动！后来几经周折，发现原因是安装的时候莫名其妙的把我的安装U盘识别为 sda 而硬盘识别为 sdb，并且安装程序还把这个写进了 fstab 里面。理论上说 Ubuntu 应该自动写入 fstab 的都是 UUID 才对，这次却写了 /dev/sdXY 进去，着实让人感到奇怪。通过我的修复盘手动修改了 fstab 以后终于成功进入了，后面就改成了使用 UUID 了，保证不会出问题……我去网上一搜，没有发现有人遇到同样的问题，我就到 Launchpad 报告了 bug：<a href="https://bugs.launchpad.net/ubuntu/+source/partman-target/+bug/653880">installer identified hard drive as sdb led to the new system unbootablity</a>。话说我的英文这么差，各位看到有什么语法错误之类的，那也是很正常的了……提交 bug 也算是我对开源的一点贡献了吧……</p>
<p>然后安装了 nVidia 的私有驱动 256.53，成功开启了各种 Compiz 特效，非常赞，而且效果相当不错。不过问题也随之而来：开机画面惨不忍睹……这是个很纠结的问题，你说那么漂亮的一个开机画面，怎么就被个驱动整成那模样……接着就在 Ubuntu 中文论坛上找到了解决方案。这个方案比较复杂，我就直接给链接好了：<a href="http://forum.ubuntu.org.cn/viewtopic.php?f=42&#038;t=269452&#038;start=0">Ubuntu 10.04 安装Nvidia显卡后开机花屏完美解决（图解）</a>，可以看到这是 10.04 时代遗留下来的问题……不过这个方案解决还算完美，至少开机画面是漂亮了不少的。不过这个事情有一个副作用，就是切入切出 tty 变得格外缓慢。于是在这栋楼的47楼发现了解决方法，这个就简单了。因为那个作者没有写出详细的做法，我就简单说一下。在解决的第一步肯定要用到 hwinfo &#8211;framebuffer 这个命令，先在仍然用这个命令，察看你选择的那个分辨率的编号，比如我选择的模式是“Mode 0&#215;0318: 1024&#215;768 (+4096), 24 bits”，那么我需要的编号就是 0&#215;0318 = 792，就是十六进制和十进制的转换咯。然后修改 /etc/default/grub，把刚才改过的</p>

<div class="wp_codebox"><table><tr id="p117664"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1176code64"><pre class="text" style="font-family:monospace;">GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet splash nomodeset video=uvesafb:mode_option=1024x768-24,mtrr=3,scroll=ywrap&quot;</pre></td></tr></table></div>

<p>修改为</p>

<div class="wp_codebox"><table><tr id="p117665"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1176code65"><pre class="text" style="font-family:monospace;">GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet splash nomodeset video=uvesafb:mtrr=3,scroll=ywrap vga=792&quot;</pre></td></tr></table></div>

<p>然后打开 /etc/initramfs-tools/module，同样去掉 mode_option=&#8230;. 的那个部分保存。然后还是</p>

<div class="wp_codebox"><table><tr id="p117666"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1176code66"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> update-initramfs <span style="color: #660033;">-u</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> update-grub</pre></td></tr></table></div>

<p>就可以了。然后再重启以后，切换 tty 慢的问题也算是初步解决了。</p>
<p>接下来遇到的问题就更囧了，gVim 和 OpenOffice.org 里面各种花屏，字体混乱。这个问题倒是很多人遇到过了，在 Launchpad 这个 bug 已经被先后3次提交到了不同的软件包，包括 <a href="https://bugs.launchpad.net/nvidia-drivers-ubuntu/+bug/568492">nvidia 驱动包</a>、<a href="https://bugs.launchpad.net/ubuntu/+source/openoffice.org/+bug/567719">openoffice.org 包</a>和 <a href="https://bugs.launchpad.net/ubuntu/+source/vim/+bug/572863">vim 包</a>……看了一遍里面的各种提示，发现有两种方法可以解决这个问题：第一种是使用 metacity 替换 compiz，具体的做法就是 Alt-F2，输入“metacity &#8211;replace”，替换速度还是挺快的，替换后就解决问题了，缺点是切换过去以后各种桌面效果就没有了。当然，想要切换回 compiz 感受桌面效果的时候，再按 Alt-F2，输入“compiz &#8211;replace”就可以了。第二种是调整字体配置，也就是在 系统/首选项/外观/字体 里，把下面的次像素平滑修改为上面的最佳形状。说实话，最佳形状看过去没有次像素平滑漂亮，不过问题是可以解决的。后来在那个 bug 反馈中有人提出，在选择最佳形状后点击“细节”，在微调内选择“轻微”可以改善显示效果，并且不会导致 gVim 和 OpenOffice.org 花屏了，我试了一下确实如此，不过总觉得是不是可能还有问题……现在暂时使用这个了……</p>
<p>嗷……现在暂时遇到了这些问题，很纠结的呢……所以说当小白鼠还真是一件得耐得住折腾的事情呢……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/note-for-installing-ubuntu-10-10-rc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>半完美解决 zip 文件中中文文件名乱码的问题</title>
		<link>http://blog.upsuper.org/a-half-perfect-solution-for-irrecognizable-encoded-chinese-filename-in-zip-file/</link>
		<comments>http://blog.upsuper.org/a-half-perfect-solution-for-irrecognizable-encoded-chinese-filename-in-zip-file/#comments</comments>
		<pubDate>Mon, 10 May 2010 14:33:46 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[zip]]></category>
		<category><![CDATA[乱码]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1154</guid>
		<description><![CDATA[前一段由于收了某个 zip 文件，用 Ubuntu 自带的归档管理器打开，哎呦，那真不是一般的蛋疼……因为里面全是中文文件名，那个乱码啊…… 于是我就下决心要解决这个问题。 虽然我的系统还在 9.10，但看到网上一篇文章教人如何在 10.04 中解决这个问题，我就了解了，这个问题至今没有解决。那么什么叫做“半完美”呢？大概意思就是说，对我来说差不多完美了，不过还是很可能出问题的…… 命令行方法 一般的方法是利用命令行的方式： 1 2 LANG=C 7z x xxxx.zip convmv -f gbk -t utf8 * 用这个方法，我就写了一个 unzip 的小脚本： 1 2 #! /bin/sh LANG=C /usr/lib/p7zip/7z x -y &#34;$1&#34; &#124; sed -n 's/^Extracting //p' &#124; sed '1!G;h;$!d' &#124; xargs convmv -f gbk -t utf8 --notest &#62;\dev\null 2&#62;\dev\null 功能就是 [...]]]></description>
			<content:encoded><![CDATA[<p>前一段由于收了某个 zip 文件，用 Ubuntu 自带的归档管理器打开，哎呦，那真不是一般的蛋疼……因为里面全是中文文件名，那个乱码啊……</p>
<p>于是我就下决心要解决这个问题。</p>
<p>虽然我的系统还在 9.10，但看到网上一篇文章教人如何在 10.04 中解决这个问题，我就了解了，这个问题至今没有解决。那么什么叫做“半完美”呢？大概意思就是说，对我来说差不多完美了，不过还是很可能出问题的……<br />
<span id="more-1154"></span></p>
<h3>命令行方法</h3>
<p>一般的方法是利用命令行的方式：</p>

<div class="wp_codebox"><table><tr id="p115472"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1154code72"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">LANG</span>=C 7z x xxxx.zip
convmv <span style="color: #660033;">-f</span> gbk <span style="color: #660033;">-t</span> utf8 <span style="color: #000000; font-weight: bold;">*</span></pre></td></tr></table></div>

<p>用这个方法，我就写了一个 unzip 的小脚本：</p>

<div class="wp_codebox"><table><tr id="p115473"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1154code73"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/sh</span>
<span style="color: #007800;">LANG</span>=C <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>p7zip<span style="color: #000000; font-weight: bold;">/</span>7z x <span style="color: #660033;">-y</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">'s/^Extracting  //p'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'1!G;h;$!d'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> convmv <span style="color: #660033;">-f</span> gbk <span style="color: #660033;">-t</span> utf8 <span style="color: #660033;">--notest</span> <span style="color: #000000; font-weight: bold;">&gt;</span>\dev\null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span>\dev\null</pre></td></tr></table></div>

<p>功能就是 unzip xxxx.zip 能够自动转码。内部机理我就不详细解释了，其实也不复杂。而且由于我不大会用 sed，所以用了两段，但我相信是不需要的。</p>
<p>不过这个不完美，为什么呢？因为这样我用归档管理器打开还是乱码，根本没有解决任何问题！</p>
<h3>我的半完美方法</h3>
<p>于是我就开始打 7z 程序的主意……当然最后是成功了的，这里先放对比图哈~<br />
<a href="http://blog.upsuper.org/wp-content/uploads/2010/05/Screenshot.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/05/Screenshot-300x197.png" alt="" title="Screenshot" width="300" height="197" class="alignnone size-medium wp-image-1155" /></a></p>
<p>现在做了一个 Ubuntu 的 patch 出来，需要的童鞋可以在这里下载：<a href="http://down.upsuper.org/p7zip_9.04~dfsg.1-1chinese.diff.gz">p7zip_9.04~dfsg.1-1chinese.diff.gz</a> (1.1KB)。不要看是 9.04 的，据我观察在 lucid 当中版本号还是这个，p7zip 一直没有变化过……</p>
<p>下载完以后再找个目录获取 p7zip 的代码：</p>

<div class="wp_codebox"><table><tr id="p115474"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1154code74"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #7a0874; font-weight: bold;">source</span> p7zip-full</pre></td></tr></table></div>

<p>注意这里不需要 sudo 权限，因为获取源代码是自由的~</p>
<p>然后把刚才下载的那个 patch 文件放进代码目录，一般来说应该是 p7zip-9.04~dfsg.1 目录。然后执行下面代码：</p>

<div class="wp_codebox"><table><tr id="p115475"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1154code75"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">gzip</span> <span style="color: #660033;">-cd</span> p7zip_9.04~dfsg.1-1chinese.diff.gz <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">patch</span> <span style="color: #660033;">-p1</span></pre></td></tr></table></div>

<p>然后就常规了：</p>

<div class="wp_codebox"><table><tr id="p115476"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1154code76"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">make</span> all3
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span></pre></td></tr></table></div>

<p>需要注意的是，这里安装完以后并没有覆盖原来 p7zip 包的文件，但是放在了一个更优先访问的位置，所以以后执行 7z 相关的操作都会访问这里安装的。</p>
<p>由于编译需要很长很长时间，所以我这里编译好了一份：<a href="http://down.upsuper.org/p7z-bin.tar.bz2">p7z-bin.tar.bz2</a> (1.6M)，是 Ubuntu i386 版本的，如果你也是 i386 的就可以直接下载这个，用里面的程序覆盖掉 /usr/lib/p7zip/ 里面的程序，就可以了~</p>
<p>当然，最好把相同功能的 unzip 先卸掉……</p>
<p>现在，在系统里面以任何方式查看或解压任何 zip，理论上应该不会出现乱码了，我想是这样……</p>
<h3>解决思路</h3>
<p>好了，对于只想解决问题的人，看到这里就够了。现在我想写写如何做到的。</p>
<p>我看了一下 p7zip 的代码，还算是条理相当清晰，其中最重要的部分是 ZipIn.cpp 里面的 ReadFileName 函数，我在里面读取文件名之后插入了一段使用 iconv 函数转换编码的代码。</p>
<p>其后我发现不能这样简单的转换编码，因为在 Linux 下面打包的 zip 文件，文件名是用 utf8 而非 gb18030 储存的，这样在转换的时候反而出现乱码。我观察了一下，WinRAR 能够正常读出这些文件名的编码。因此我又在另外一些相关的函数中加入了判断打包平台的代码，以确认是否要转换编码。</p>
<p>此外，由于 gb18030 是硬编码进去的，显然不太好，但我暂时想不出什么更好的解决方法。我想这对于目前的国内自己用应该是足够了，不过考虑到开源软件一向喜欢的国际化，我就实在没什么办法了……如果有人有办法，请一定告诉我！</p>
<p>不过为了平衡，我最后在 config.h 里面加入了 MY_ENCODING 宏，这样可以修改这个以改变硬编码的文字编码值，也算是一点点努力吧……</p>
<h3>一点抱怨</h3>
<p>由于是在上网本上做的，而且我不想折磨我可怜的 SSD 或者移动硬盘，因此我不得不在内存盘中进行编译。每次都是心惊胆战的，生怕内存不够用开始吃交换区……当然最后还是没有……</p>
<p>话说 Windows 混乱的内码转换害死人啊……</p>
<h3>参考资料</h3>
<ul>
<li><a href="http://linux.cn/home/space-5812-do-thread-id-3019.html">使用ubuntu 10.04中的中文乱码问题解决 &#8211; kyohand &#8211; Linux中国</a></li>
<li><a href="http://qq164587043.blog.51cto.com/261469/63349">使用iconv命令轻松实现linux下字符集编码的转换 &#8211; 国产0与1 &#8211; 51CTO技术博客</a></li>
<li><a href="http://www.ibm.com/developerworks/cn/linux/l-diffp/index.html">用Diff和Patch工具维护源码</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/a-half-perfect-solution-for-irrecognizable-encoded-chinese-filename-in-zip-file/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>对比一下 Python 和 Erlang</title>
		<link>http://blog.upsuper.org/comparsion-between-python-and-erlang/</link>
		<comments>http://blog.upsuper.org/comparsion-between-python-and-erlang/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 11:10:39 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1134</guid>
		<description><![CDATA[今天突然有兴致来对比一下我在过去的一年中主要学习的两种语言，Python 和 Erlang，他们都是很神奇的语言。不过，在我看来，更神奇的是，这两种语言几乎是完全对立的！ 下面我弄了张表格来对比他们： 名称 Python Erlang 主要范型 面向对象 函数式、面向并发 开发者 Python 基金会 商业公司 爱立信 文件编码 在 Python 2 中默认为 ASCII，Python 3 中默认为 UTF-8，但都可以制定任意编码。 默认为 Latin-1，不允许指定文件编码。不过事实上编译器并不会在意文件中是否存在“不正确”的字符。 变量 几乎什么都是变量，变量都可以不断变化，无论是值还是类型。甚至你可以改变 True 和 False，让他们颠倒。（当然，也有例外，如 None，我至今没找到改变他的方法） 且不说原子是显然不可变的，任何一个变量被赋值之后，他的值也是不可变的，这是所谓变量绑定。（单次赋值） 字符串 拥有完善的字符串支持，在 Python 3 中这更是发挥到了极致。 根本不存在字符串类型，一切字符串都是字符列表，因此就更没有什么强大的字符串处理函数了。 列表 可以根据下标索引快速获取列表任意位置的内容。 考虑效率的话，只能从列表的头部摘取内容。 模块 依据文件系统的文件分布构建层级式的模块体系，使用模块前必须声明将模块引入当前名字空间。 所有模块是平行的，在同一层中，模块名称强制与文件名相同。使用模块时模块必须已经被编译，Erlang 将会自动寻找模块并读取。 并行 通过 GIL 这一全局锁将所有多线程操作退化为单线程操作，不存在任何并发性。（不过 Python 正在尝试加入新的模块来改变这一问题） 天生就是面向并发的……用他仅做顺序编程是一种莫大的浪费…… C 接口 [...]]]></description>
			<content:encoded><![CDATA[<p>今天突然有兴致来对比一下我在过去的一年中主要学习的两种语言，Python 和 Erlang，他们都是很神奇的语言。不过，在我看来，更神奇的是，这两种语言几乎是完全对立的！</p>
<p>下面我弄了张表格来对比他们：</p>
<table>
<tr>
<th width="20%">名称</th>
<th width="40%">Python</th>
<th width="40%">Erlang</th>
</tr>
<tr>
<th>主要范型</th>
<td>面向对象</td>
<td>函数式、面向并发</td>
</tr>
<tr>
<th>开发者</th>
<td>Python 基金会</td>
<td>商业公司 爱立信</td>
</tr>
<tr>
<th>文件编码</th>
<td>在 Python 2 中默认为 ASCII，Python 3 中默认为 UTF-8，但都可以制定任意编码。</td>
<td>默认为 Latin-1，不允许指定文件编码。不过事实上编译器并不会在意文件中是否存在“不正确”的字符。</td>
</tr>
<tr>
<th>变量</th>
<td>几乎什么都是变量，变量都可以不断变化，无论是值还是类型。甚至你可以改变 True 和 False，让他们颠倒。（当然，也有例外，如 None，我至今没找到改变他的方法）</td>
<td>且不说原子是显然不可变的，任何一个变量被赋值之后，他的值也是不可变的，这是所谓变量绑定。（单次赋值）</td>
</tr>
<tr>
<th>字符串</th>
<td>拥有完善的字符串支持，在 Python 3 中这更是发挥到了极致。</td>
<td>根本不存在字符串类型，一切字符串都是字符列表，因此就更没有什么强大的字符串处理函数了。</td>
</th>
<tr>
<th>列表</th>
<td>可以根据下标索引快速获取列表任意位置的内容。</td>
<td>考虑效率的话，只能从列表的头部摘取内容。</td>
</tr>
<tr>
<th>模块</th>
<td>依据文件系统的文件分布构建层级式的模块体系，使用模块前必须声明将模块引入当前名字空间。</td>
<td>所有模块是平行的，在同一层中，模块名称强制与文件名相同。使用模块时模块必须已经被编译，Erlang 将会自动寻找模块并读取。</td>
</tr>
<tr>
<th>并行</th>
<td>通过 GIL 这一全局锁将所有多线程操作退化为单线程操作，不存在任何并发性。（不过 Python 正在尝试加入新的模块来改变这一问题）</td>
<td>天生就是面向并发的……用他仅做顺序编程是一种莫大的浪费……</td>
</tr>
<tr>
<th>C 接口</th>
<td>使用 Python.h 编写接口，编译为动态链接库，运行时调入 Python 内使用。</td>
<td>编写外部程序，通过标准输入输出与 Erlang 主进程交换数据，在 Erlang 进程空间外单独运行。（也有一种在进程空间内运行的接口，不过不推荐使用）</td>
<tr>
<th>函数重载</th>
<td>不支持任何形式的函数重载，但支持可选参数。</td>
<td>支持参数数量不同的同名函数，但不支持可选参数。而且基于模式匹配，支持同一函数的不同分支的定义。</td>
</tr>
<tr>
<th>数据库</th>
<td>内置了通用的 SQLite 数据库支持，可以通过 SQL 语句进行数据库操作，储存的信息限制在文本、数字等几种。</td>
<td>内置了专用的 Mnesia，可以与 Erlang 无缝衔接地储存任何内容，通过 Erlang 的 qlc 模块不使用 SQL 语句进行数据库操作。（NoSQL）</td>
</tr>
<tr>
<th>代码热替换</th>
<td>支持使用 reload 函数重新载入一个模块。</td>
<td>模块的新版本被编译后任何调用即采用新的代码。</td>
</tr>
</table>
<p>可以看到这两种语言真的是非常非常不同，我想这和他们的设计初衷和适用范围是很有关系的：Python 大多数时候被用于快速的原型开发、用作胶水语言、创建小型桌面级应用程序；而 Erlang 则在一开始就被用在电信，这一对容错、并发要求较苛刻的领域。</p>
<p>不过我还是觉得，这两种语言都是非常优美的，以他们自己的专长而言。不过 Python 已经非常不错了，Erlang 在我看来则还有很大的发展空间~</p>
<p><em>PS：以上仅仅是就我自己的了解给出的一些对比，疏漏和错误在所难免，也希望看到了及时告诉我~</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/comparsion-between-python-and-erlang/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>今天写了个小小的 vc-fix</title>
		<link>http://blog.upsuper.org/write-a-little-vc-fix-today/</link>
		<comments>http://blog.upsuper.org/write-a-little-vc-fix-today/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 02:39:51 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[兼容性]]></category>
		<category><![CDATA[微软]]></category>
		<category><![CDATA[标准化]]></category>
		<category><![CDATA[编译器]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1119</guid>
		<description><![CDATA[我们的 C++ 老师给我布置了 C++ 的大作业来替代其他同学交的无聊题目。大作业的第一题就是完整的高精度库，并且要求使用运算符重载。因为原来用 C 写过，这次写，思路上没有太大问题，不过全部程序被我 C++ 化了，代码看过去很诡异……呃…… 我自己的机子上，自然使用 g++ 编译，不过我猜老师会要求 VC6 能够编译……我就用上次安装的 VC6 编译了一下，发现好几个错误和无数警告……其实也是我意料之中的。 其中我觉得最讨厌的莫过于 for 循环的循环变量不被视为 for 循环的局部变量这一点，导致大量变量被其认为是重复定义，这个是 VC6 和标准就语言上相去最远的问题了……不想每个都去改，麻烦死了。 在网上一找，还真找到一个简单的方法： 1 #define for if(0) ; else for 其实我也不知道这个是什么机理，不过真的很管用！ 另外一个就是 VC6 的标准库中没有 max 和 min 函数，这个也很囧，于是也自己写了一个。 以前做网页的时候经常写 ie-fix.css 文件，今天我弄 VC6 遇到这些问题，于是我也写了个 vc-fix.h 文件。M$ 真是一个需要 fix 的公司，什么时候出一个 m$-fix.com 好了…… 最后贴出我的 vc-fix.h，主要解决 VC6 下 [...]]]></description>
			<content:encoded><![CDATA[<p>我们的 C++ 老师给我布置了 C++ 的大作业来替代其他同学交的无聊题目。大作业的第一题就是完整的高精度库，并且要求使用运算符重载。因为原来用 C 写过，这次写，思路上没有太大问题，不过全部程序被我 C++ 化了，代码看过去很诡异……呃……</p>
<p>我自己的机子上，自然使用 g++ 编译，不过我猜老师会要求 VC6 能够编译……我就用<a href="http://blog.upsuper.org/a-simple-script-for-using-vc6-compiler-conveniently/">上次安装的 VC6</a> 编译了一下，发现好几个错误和无数警告……其实也是我意料之中的。<br />
<span id="more-1119"></span><br />
其中我觉得最讨厌的莫过于 for 循环的循环变量不被视为 for 循环的局部变量这一点，导致大量变量被其认为是重复定义，这个是 VC6 和标准就语言上相去最远的问题了……不想每个都去改，麻烦死了。</p>
<p>在网上一找，还真找到一个简单的方法：</p>

<div class="wp_codebox"><table><tr id="p111980"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1119code80"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define for if(0) ; else for</span></pre></td></tr></table></div>

<p>其实我也不知道这个是什么机理，不过真的很管用！</p>
<p>另外一个就是 VC6 的标准库中没有 max 和 min 函数，这个也很囧，于是也自己写了一个。</p>
<p>以前做网页的时候经常写 ie-fix.css 文件，今天我弄 VC6 遇到这些问题，于是我也写了个 vc-fix.h 文件。M$ 真是一个需要 fix 的公司，什么时候出一个 m$-fix.com 好了……</p>
<p>最后贴出我的 vc-fix.h，主要解决 VC6 下 for 循环变量的问题和 max、min 函数未定义的问题：</p>

<div class="wp_codebox"><table><tr id="p111981"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code" id="p1119code81"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef _H_UPSUPER_VC_FIX_</span>
<span style="color: #339900;">#define _H_UPSUPER_VC_FIX_</span>
&nbsp;
<span style="color: #339900;">#ifdef _MSC_VER</span>
<span style="color: #339900;">#   if _MSC_VER &lt;= 1200</span>
<span style="color: #339900;">#       define for if (0); else for</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> a <span style="color: #000080;">&gt;</span> b <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> a <span style="color: #000080;">&lt;</span> b <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T, <span style="color: #0000ff;">class</span> Compare<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b, Compare comp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> comp<span style="color: #008000;">&#40;</span>a, b<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> b <span style="color: #008080;">:</span> a<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T, <span style="color: #0000ff;">class</span> Compare<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b, Compare comp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> comp<span style="color: #008000;">&#40;</span>a, b<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #339900;">#   endif</span>
<span style="color: #339900;">#endif</span>
&nbsp;
<span style="color: #339900;">#endif // _H_UPSUPER_VC_FIX_</span></pre></td></tr></table></div>

<p>最后要解决的就是警告的问题。其实我很无语的是，所有的警告都是在 VC6 自己的头文件里面的……VC6 自己提示可以添加 /GX 来消除那些警告。于是我不得不再次修改我的编译脚本：</p>

<div class="wp_codebox"><table><tr id="p111982"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p1119code82"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># - * - coding: UTF-8 - * -</span>
&nbsp;
<span style="color: #007800;">VC6_DIR</span>=<span style="color: #ff0000;">&quot;这里写上VC6的安装地址&quot;</span>
&nbsp;
<span style="color: #007800;">BIN</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$VC6_DIR</span>/VC98/Bin&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">INCLUDE</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$VC6_DIR</span>/VC98/Include&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LIB</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$VC6_DIR</span>/VC98/Lib&quot;</span> 
&nbsp;
<span style="color: #007800;">ARGS</span>=
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">getopts</span> <span style="color: #ff0000;">&quot;o:cG:&quot;</span> optname
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$optname</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
    <span style="color: #ff0000;">&quot;o&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">ARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ARGS</span> /o<span style="color: #007800;">$OPTARG</span>&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">ARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ARGS</span> /c&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #ff0000;">&quot;G&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">ARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ARGS</span> /G<span style="color: #007800;">$OPTARG</span>&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
wine <span style="color: #ff0000;">&quot;<span style="color: #007800;">$BIN</span>/CL.EXE&quot;</span> <span style="color: #007800;">$ARGS</span> <span style="color: #800000;">${@:$OPTIND}</span></pre></td></tr></table></div>

<p>到了最后，再补充一点点吧。VC6 发现了两个额外的错误，我觉得应该不是不兼容的问题。就是我重载的 operator++ 和 operator&#8211; 不小心忘记写 return *this; 了，g++ 没有给我任何提示的编译通过了，而 VC6 则将这个视为错误。</p>
<p>在这个问题上，我同意 VC6 的看法，虽然我怀疑可能 g++ 自己加上了那句话，不过我觉得这个应该至少给出一个警告而非什么都不说。当然，可能一个 fatal error 太过了点……</p>
<p>参考资料：</p>
<ul>
<li><a href="http://www.rugesy.cn/it/u20091012_22_34fe5127-ddfe-44fe-86f1-13afc360a794.html">VC6中FOR语句的变量声明问题</a> 回复的7楼</li>
<li><a href="http://topic.csdn.net/t/20041101/19/3511737.html">如何在程序调试阶段，判断当前的编译器是vc6的编译器还是intel8.0的编译器？ &#8211; CSDN社区</a></li>
<li><a href="http://www.cplusplus.com/reference/algorithm/max/">max &#8211; C++ Reference</a></li>
<li><a href="http://panpan.blog.51cto.com/489034/103074/">VC6.0不支持标准库函数max和min &#8211; C++技术 &#8211; 51CTO技术博客</a></li>
<li><a href="http://topic.csdn.net/t/20040909/19/3357414.html">warning C4530:C++ exception handler used, but unwind semantics are not enabled. Specify -GX &#8211; CSDN社区</a></li>
<li><a href="http://baike.baidu.com/view/1276757.html">_MSC_VER_百度百科</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/write-a-little-vc-fix-today/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>BMP to HTML 小程序</title>
		<link>http://blog.upsuper.org/bmp-to-html-tool/</link>
		<comments>http://blog.upsuper.org/bmp-to-html-tool/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 09:46:23 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[BMP]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[HTML]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1093</guid>
		<description><![CDATA[什么叫 BMP 到 HTML 呢……？就是生成一个网页，里面用不同颜色的字符拼出那个图片……很无聊的功能嗯，而且原理上说，生成的 HTML 文件如果要表现整个 BMP 的所有细节，大小肯定大大超过原 BMP 文件…… 为什么会做这个呢？主要是受到我们 C++ 老师的启发，尝试去做的。不过我没有用 C++ 写，而是选用了寒假学的 Erlang，这也是我写的第一个 Erlang 程序。 为什么会选用 Erlang 呢？主要是基于两点原因：1、寒假学了半天，一点都没有练过，就拿这个来练练；2、看中了 Erlang 强大的模式匹配和比特语法。比特语法在 Erlang 里面原来是用来解决网络传输协议中的二进制数据的，不过这里拿来处理二进制文件着实是一个很好的选择~不过其实 Erlang 真正最重要的特性：面向并发，我完全没有用到，而是继续使用了顺序编程。主要是，BMP to HTML 没什么可以并发化的，而且就算并发了，也是大传输小计算，并没有什么很大的优势。因为是第一次写 Erlang 程序，如果有 Erlang 高手路过，还请多多指点咯~ 另外一点，为什么选用 BMP 这种几乎被人抛弃的格式呢？因为最容易呗……而且我这里还用了 BMP 中最简单的一种：真彩色无压缩格式。这是最直接的图形表示方式了，就是一个点一个点的，每个点三个字节表示一种颜色。所以还是很简单的。 先看看最后的效果： 下面说干就干。 BMP 文件结构 首先要知道的就是 BMP 的格式。在维基百科里的相关条目有很详细的记载，甚至于文件头的 C 结构都已经直接给出来了。不过这个当然对我没有很大的用途，因为用的是 Erlang 嘛~识别文件头要比 C 方便多了~下面我先说说 BMP 的文件结构： [...]]]></description>
			<content:encoded><![CDATA[<p>什么叫 BMP 到 HTML 呢……？就是生成一个网页，里面用不同颜色的字符拼出那个图片……很无聊的功能嗯，而且原理上说，生成的 HTML 文件如果要表现整个 BMP 的所有细节，大小肯定大大超过原 BMP 文件……</p>
<p>为什么会做这个呢？主要是受到我们 C++ 老师的启发，尝试去做的。不过我没有用 C++ 写，而是选用了寒假学的 Erlang，这也是我写的第一个 Erlang 程序。</p>
<p>为什么会选用 Erlang 呢？主要是基于两点原因：1、寒假学了半天，一点都没有练过，就拿这个来练练；2、看中了 Erlang 强大的模式匹配和比特语法。比特语法在 Erlang 里面原来是用来解决网络传输协议中的二进制数据的，不过这里拿来处理二进制文件着实是一个很好的选择~不过其实 Erlang 真正最重要的特性：面向并发，我完全没有用到，而是继续使用了顺序编程。主要是，BMP to HTML 没什么可以并发化的，而且就算并发了，也是大传输小计算，并没有什么很大的优势。因为是第一次写 Erlang 程序，如果有 Erlang 高手路过，还请多多指点咯~</p>
<p>另外一点，为什么选用 BMP 这种几乎被人抛弃的格式呢？因为最容易呗……而且我这里还用了 BMP 中最简单的一种：真彩色无压缩格式。这是最直接的图形表示方式了，就是一个点一个点的，每个点三个字节表示一种颜色。所以还是很简单的。</p>
<p>先看看最后的效果：<br />
<a href="http://blog.upsuper.org/wp-content/uploads/2010/03/1268197208685.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/03/1268197208685.png" alt="" title="_1268197208685" width="120" height="35" class="alignnone size-full wp-image-1098" /></a></p>
<p>下面说干就干。<br />
<span id="more-1093"></span></p>
<h3>BMP 文件结构</h3>
<p>首先要知道的就是 BMP 的格式。在维基百科里的相关条目有很详细的记载，甚至于文件头的 C 结构都已经直接给出来了。不过这个当然对我没有很大的用途，因为用的是 Erlang 嘛~识别文件头要比 C 方便多了~下面我先说说 BMP 的文件结构：</p>
<h4>BMP 文件头</h4>
<p>一个 BMP 文件最开始是 BMP 文件头。这个文件头的大小是固定的14字节，包含 BMP 文件的 Magic Number (魔术数字，即文件识别码) 2字节、整个文件大小4字节、保留区4字节、图像数据在文件中的起始位置4字节。</p>
<p>其中 Magic Number 我们最常见的是 Windows BMP 文件的 <em>BM</em>，除此之外，还有 <em>BA</em>、<em>CI</em>、<em>CP</em>、<em>IC</em>、<em>PT</em> 这几种，应该是不太常见吧。</p>
<p>整个文件的大小其实我觉得在这里是没有什么用途的，而整整4字节的保留区也是令我很难理解的。整个14字节的头当中，最重要的应该就是图像数据的偏移。如果这个偏移量是相对于整个文件而言的，因此直接把读取指针指向偏移量的位置就是图像数据。</p>
<h4>DIB 头</h4>
<p>这个信息其实是关于图像描述最有意义的部分。这里面将会描述这张图片几乎一切你需要的信息。</p>
<p>DIB 头最开始的32位，也就是4个字节，描述了 DIB 头的长度。根据 DIB 头的长度不同，共有4种 BMP 图片：</p>
<ul>
<li><strong>12字节</strong> &#8211; OS/2 V1 格式，OS/2 和 Windows 3.0 以后所有版本支持</li>
<li><strong>64字节</strong> &#8211; OS/2 V2 格式</li>
<li><strong>40字节</strong> &#8211; Windows V3，Windows 3.0 以后所有版本支持</li>
<li><strong>108字节</strong> &#8211; Windows V4，Windows 95/NT4 以后所有版本支持</li>
<li><strong>124字节</strong> &#8211; Windows V5，Windows 98/2000 以后所有版本支持</li>
</ul>
<p>鉴于 Windows V4、V5 都与 V3 的格式兼容，我在程序里面事实上仅仅实现了 V3 的头识别。</p>
<p>V3 头的40字节分布，我觉得已经很复杂了……分别是：</p>
<ul>
<li>DIB 头大小，4字节，这里为40</li>
<li>图像宽度，4字节</li>
<li>图像高度，4字节</li>
<li>Color planes (不知道是什么东西)，2字节，必须为1</li>
<li>颜色位数，2字节，可以为1、4、8、16、24、32，我的程序中只识别24位色</li>
<li>压缩方式，4字节，我的程序里只能识别不压缩的……值为0</li>
<li>图像信息大小，4字节，与整个文件大小不一样，这里表示的是图像信息那块数据的大小</li>
<li>横向分辨率，4字节，单位像素/米</li>
<li>纵向分辨率，4字节，单位像素/米</li>
<li>调色板颜色数，4字节，如果为0则默认为2<sup>n</sup></li>
<li>重要颜色数量，4字节，不知道干什么用的，直接忽略好了……</li>
</ul>
<p>介绍完了这个 DIB 头，其实很很没意思就是了。真正有用的，也就这么几个：长度、宽度。如果要识别能力强一点，识别一下调色板相关的，也就差不多了。</p>
<h4>调色板</h4>
<p>因为我没有用到调色板，所以也没有细看这块内容，直接跳过……</p>
<h4>图像数据</h4>
<p>显然对于我的最基本选择要求：24位色、无压缩，图像信息是很简单的，就是每个像素占3个字节。</p>
<p>不过仍然有两点需要注意：1、颜色储存依次是是蓝、绿、红，而非红、绿、蓝；2、每行的字节数必须是4的整倍数。也就是 BMP 文件每行最后会有1-3个字节用于补足，这个补足用字节数正是宽度除以4的余数。</p>
<h3>Erlang 程序</h3>
<p>BMP 图片的基本信息探究清楚了，下面就可以开始写咯~</p>
<h4>导出函数</h4>
<p>第一部分就是模块的声明和导出函数：</p>

<div class="wp_codebox"><table><tr id="p109387"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code" id="p1093code87"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>bmp<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>bmp_to_html<span style="color: #014ea4;">/</span><span style="color: #ff9600;">2</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">define</span><span style="color: #109ab8;">&#40;</span><span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span> unsigned<span style="color: #014ea4;">-</span><span style="color: #9d4f37;">little</span><span style="color: #014ea4;">-</span><span style="color: #fa6fff;">integer</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">bmp_to_html</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bmp</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Html</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff3c00;">bmp_to_html</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bmp</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">write_file</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Html</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">Error</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Bmp</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Error</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">bmp_to_html</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">File</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">open</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">File</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>read<span style="color: #6bb810;">,</span> <span style="color: #fa6fff;">binary</span><span style="color: #6bb810;">,</span> raw<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff7800;">&quot;&lt;span style=<span style="color: #000099; font-weight: bold;">\&quot;</span>font-size: 1px; line-height: 1px;<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span><span style="color: #6bb810;">,</span>
                    <span style="color: #ff3c00;">convert_bmp</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;&lt;/span&gt;&quot;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">Error</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">File</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Error</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></td></tr></table></div>

<p>我在 bmp 模块内导出了一个 bmp_to_html 的函数，他读取一个 bmp 文件，转换并写入一个 html 文件。中间定义了一个宏 ULI，很容易理解的~其实定义这个的主要原因是那个 little……由于 Erlang 最初是为网络协议做的这个比特语法，因此默认是 Big endian 的，而 x86 系的 CPU 却总是使用 Little endian 的……</p>
<h4>读取 BMP 文件信息</h4>

<div class="wp_codebox"><table><tr id="p109388"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code" id="p1093code88"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">convert_bmp</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Size</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">read_header</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Size</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #45b3e6;">L</span> <span style="color: #014ea4;">=</span> <span style="color: #fa6fff;">binary_to_list</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">L</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">read_header</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">14</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #186895;">case</span> <span style="color: #45b3e6;">Bin</span> <span style="color: #186895;">of</span>
        <span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;BM&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_FileSize</span>:  <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                <span style="color: #45b3e6;">_Creator</span>:   <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                <span style="color: #45b3e6;">Offs</span><span style="color: #ff4e18;">et</span>:     <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span>
        <span style="color: #ee3800;">&gt;&gt;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Offset</span><span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">read_dib_header</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">_Other</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> unsupported<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Other</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">read_dib_header</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">14</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">4</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #186895;">case</span> <span style="color: #45b3e6;">Bin</span> <span style="color: #186895;">of</span>
        <span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff9600;">40</span>:<span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #ee3800;">&gt;&gt;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #ee3800;">&lt;&lt;</span> <span style="color: #45b3e6;">Width</span>:  <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                    <span style="color: #45b3e6;">Height</span>: <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                    <span style="color: #45b3e6;">_</span>:      <span style="color: #ff9600;">16</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                    <span style="color: #45b3e6;">_</span>:      <span style="color: #ff9600;">16</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                    <span style="color: #ff9600;">0</span>:      <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span><span style="color: #6bb810;">,</span>
                    <span style="color: #45b3e6;">Size</span>:   <span style="color: #ff9600;">32</span><span style="color: #014ea4;">/</span>?<span style="color: #6941fd;">ULI</span>
            <span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">file</span>:<span style="color: #ff3c00;">pread</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">F</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">18</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">20</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Size</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">_Other</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> unsupported<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Other</span><span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></td></tr></table></div>

<p>很明显，为了简化程序，BMP 文件头和 DIB 头的识别都只写了一点点，够用就行~</p>
<h4>转换图像数据</h4>
<p>这是最后的部分了，将图像数据转换为 HTML 代码~</p>

<div class="wp_codebox"><table><tr id="p109389"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code" id="p1093code89"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Output</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Output</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Output</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">NewBin</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">drop_begin</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span> <span style="color: #014ea4;">rem</span> <span style="color: #ff9600;">4</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #45b3e6;">NewOutput</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff3c00;">new_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> | <span style="color: #45b3e6;">Output</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span><span style="color: #014ea4;">-</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewBin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewOutput</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Output</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Output</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">X</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Output</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">B</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">G</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">R</span>|NewBin<span style="color: #109ab8;">&#93;</span> <span style="color: #014ea4;">=</span> <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span>
    <span style="color: #45b3e6;">NewOutput</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff3c00;">to_html</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">R</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">G</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">B</span><span style="color: #109ab8;">&#41;</span> | <span style="color: #45b3e6;">Output</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span>
    <span style="color: #ff3c00;">each_pixel</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">X</span><span style="color: #014ea4;">-</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Y</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Width</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Height</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewBin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">NewOutput</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">drop_begin</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">drop_begin</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_</span>|Bin<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Num</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">drop_begin</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Bin</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Num</span><span style="color: #014ea4;">-</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">new_line</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#91;</span><span style="color: #ff7800;">&quot;&lt;br&gt;&quot;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">to_html</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">R</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">G</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">B</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">io_lib</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;&lt;font color=<span style="color: #000099; font-weight: bold;">\&quot;</span>#~.16B~.16B~.16B<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;█&lt;/font&gt;&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">R</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">G</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">B</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></td></tr></table></div>

<p>这是最后的部分了~其中字符选用了一个非常黑的字符“█”嗯~</p>
<p>至于为什么用 font 这个不推荐的标签，其实是我觉得这个文件本身就很冗长了，再变成样式就……所以……</p>
<h4>使用</h4>
<p>差不多了，整个程序全部拼在一起，就出来了~</p>
<p>最后，在 Erlang 的命令行中输入：</p>

<div class="wp_codebox"><table><tr id="p109390"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1093code90"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">c</span><span style="color: #109ab8;">&#40;</span>bmp<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
bmp:<span style="color: #ff3c00;">bmp_to_html</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;BMP 文件&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;HTML 文件&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></td></tr></table></div>

<p>就好了~</p>
<p>我用了一个 2.6KB 的 BMP 文件，转换出了一个 26.3KB 的 HTML 文件……真够大……</p>
<p>最后，给出这两个文件：</p>
<ul>
<li><a href="http://down.upsuper.org/u_noalpha.bmp">u_noalpha.bmp</a> (2.6KB)</li>
<li><a href="http://down.upsuper.org/u_noalpha.html">u_noalpha.html</a> (26.3KB)</li>
</ul>
<h3>参考资料</h3>
<ul>
<li><a href="http://en.wikipedia.org/wiki/BMP_file_format">BMP file format &#8211; Wikipedia, the free encyclopedia</a></li>
<li><a href="http://www.trapexit.org/Converting_Between_Octal_and_Hex">Erlang Community &#8211; Converting Between Octal and Hex &#8211; Trapexit</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/bmp-to-html-tool/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apache 的 Rewrite 模块 Bug 一则</title>
		<link>http://blog.upsuper.org/a-bug-of-rewrite-module-in-apache/</link>
		<comments>http://blog.upsuper.org/a-bug-of-rewrite-module-in-apache/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 11:20:54 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Rewrite]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1086</guid>
		<description><![CDATA[我发觉研究的东西多了，就会看到各种神奇的 Bug…… 今天写的这个 Bug 是关于 Apache 的 Rewrite 模块的。先来看一个很正常的 Rewrite 规则： 1 2 RewriteCond %{REQUEST_URI} \.u$ RewriteRule ^(.*)\.u$ $1 这个什么意思呢？用过的人一定看得出来，就是把一个 .t 结尾的请求发送到一个去掉 .t 的文件上面。比如我如果请求 upsuper.u 就会自动调用 upsuper 这个文件来返回。这没有什么疑问。 然后，我们发现，.u 文件浏览器不知道是什么，而 upsuper 这个文件在服务器上又是没有类型的，于是 Apache 不知道告诉浏览器（或者错误地告诉了一个）MIME-Type。这样即使这个文件是个网页，浏览器上也会出现下载提示或者当作纯文本直接输出。 翻阅了一下 Rewrite 模块的资料，我们了解到可以使用 T 这个标志符来强制指定 MIME-Type 类型，于是规则变成了下面这样： 1 2 RewriteCond %{REQUEST_URI} \.u$ RewriteRule ^(.*)\.u$ $1 [T=text/html] 可是无效！ Bug 开始出现了~ 在 Apache [...]]]></description>
			<content:encoded><![CDATA[<p>我发觉研究的东西多了，就会看到各种神奇的 Bug……</p>
<p>今天写的这个 Bug 是关于 Apache 的 Rewrite 模块的。先来看一个很正常的 Rewrite 规则：</p>

<div class="wp_codebox"><table><tr id="p108696"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1086code96"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} \.u$
<span style="color: #00007f;">RewriteRule</span> ^(.*)\.u$ $<span style="color: #ff0000;">1</span></pre></td></tr></table></div>

<p>这个什么意思呢？用过的人一定看得出来，就是把一个 .t 结尾的请求发送到一个去掉 .t 的文件上面。比如我如果请求 upsuper.u 就会自动调用 upsuper 这个文件来返回。这没有什么疑问。</p>
<p>然后，我们发现，.u 文件浏览器不知道是什么，而 upsuper 这个文件在服务器上又是没有类型的，于是 Apache 不知道告诉浏览器（或者错误地告诉了一个）MIME-Type。这样即使这个文件是个网页，浏览器上也会出现下载提示或者当作纯文本直接输出。</p>
<p>翻阅了一下 <a href="http://httpd.apache.org/docs/2.2/rewrite/">Rewrite 模块的资料</a>，我们了解到可以使用 T 这个标志符来强制指定 MIME-Type 类型，于是规则变成了下面这样：</p>

<div class="wp_codebox"><table><tr id="p108697"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1086code97"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} \.u$
<span style="color: #00007f;">RewriteRule</span> ^(.*)\.u$ $<span style="color: #ff0000;">1</span> [T=text/html]</pre></td></tr></table></div>

<p>可是无效！</p>
<p>Bug 开始出现了~<br />
<span id="more-1086"></span><br />
在 Apache 基金会的 Bugzilla 里面翻到了<a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=36590">关于这个 Bug 的内容</a>。然后看一看日期，OMG，2005年的 Bug，很跨10个年头没有解决！</p>
<p>看了一下，里面有一个可能是开发人员，说这一问题可能是由于引发了一个内部跳转导致的。并且提供了一种解决方法，我参照该解决方法再次修改我的 Rewrite 规则，变成下面这样：</p>

<div class="wp_codebox"><table><tr id="p108698"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1086code98"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} \.u$
<span style="color: #00007f;">RewriteRule</span> ^(.*)\.u$ $<span style="color: #ff0000;">1</span>
<span style="color: #00007f;">RewriteRule</span> . - [T=text/html]</pre></td></tr></table></div>

<p>成功了！泪流满面……</p>
<p>不过，有趣的还没结束~仅能变出 MIME-Type 为 text/html 本来就不是我最初的想法。我的想法更大胆一些：识别 URL 中的一部分作为 MIME-Type！</p>
<p>我发现 Rewrite 规则中，标志 E 可以修改环境变量，而且在后面的过程中还可以使用~我觉得那这个来当中间变量是一个很好的想法，于是就动手了：</p>

<div class="wp_codebox"><table><tr id="p108699"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1086code99"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} \.u$
<span style="color: #00007f;">RewriteRule</span> ^([a-zA-Z]+/[a-zA-Z-]+)/(.*)\.u$ $<span style="color: #ff0000;">2</span> [E=MIMETYPE:$<span style="color: #ff0000;">1</span>]
<span style="color: #00007f;">RewriteRule</span> . - [T=%{ENV:MIMETYPE}]</pre></td></tr></table></div>

<p>稍加辨别不难看出，“([a-zA-Z]+/[a-zA-Z-]+)”部分正是识别一个 MIME-Type，在而后的 [E=MIMETYPE:$1] 将这一部分存入了 MIMETYPE 这一环境变量，然后在第三行将这个环境变量的值作为 MIME-Type。</p>
<p>可是，当我们尝试访问 text/html/upsuper.u 的时候，这个文件再次被直接输出了，MIME-Type 根本没有被指定！疯了……</p>
<p>看看 RewriteLog 里面都写了些什么（已去除无关部分）：</p>

<div class="wp_codebox"><table><tr id="p1086100"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p1086code100"><pre class="text" style="font-family:monospace;">[rid#21e031f8/initial] (3) add path info postfix: ~/web/test/text -&gt; ~/web/test/text/html/upsuper.u
[rid#21e031f8/initial] (3) strip per-dir prefix: ~/web/test/text/html/upsuper.u -&gt; text/html/upsuper.u
[rid#21e031f8/initial] (3) applying pattern '^([a-zA-Z]+/[a-zA-Z-]+)/(.*)\.u$' to uri 'text/html/upsuper.u'
[rid#21e031f8/initial] (2) rewrite 'text/html/upsuper.u' -&gt; 'upsuper'
[rid#21e031f8/initial] (3) add per-dir prefix: upsuper -&gt; ~/web/test/upsuper
[rid#21e031f8/initial] (3) add path info postfix: ~/web/test/upsuper -&gt; ~/web/test/upsuper/html/upsuper.u
[rid#21e031f8/initial] (3) strip per-dir prefix: ~/web/test/upsuper/html/upsuper.u -&gt; upsuper/html/upsuper.u
[rid#21e031f8/initial] (3) applying pattern '.' to uri 'upsuper/html/upsuper.u'
[rid#21e031f8/initial] (2) remember ~/web/test/upsuper to have MIME-type 'text/html'
[rid#21e031f8/initial] (2) strip document_root prefix: ~/web/test/upsuper -&gt; /test/upsuper
[rid#21e031f8/initial] (1) internal redirect with /test/upsuper [INTERNAL REDIRECT]
[rid#21e031f8/initial] (1) force filename redirect:/test/upsuper to have MIME-type 'text/html'
[rid#21e08c80/initial/redir#1] (3) strip per-dir prefix: ~/web/test/upsuper -&gt; upsuper
[rid#21e08c80/initial/redir#1] (3) applying pattern '^([a-zA-Z]+/[a-zA-Z-]+)/(.*)\.u$' to uri 'upsuper'
[rid#21e08c80/initial/redir#1] (3) strip per-dir prefix: ~/web/test/upsuper -&gt; upsuper
[rid#21e08c80/initial/redir#1] (3) applying pattern '.' to uri 'upsuper'
[rid#21e08c80/initial/redir#1] (1) pass through ~/web/test/upsuper</pre></td></tr></table></div>

<p>注意看第9行，在这里 MIME-Type 已经被正确地设置了，但随后开始了内部重定向……orz</p>
<p>本质上说，最后这样修改和前面一次没有很大的本质不同，最后一句都是除了修改 MIME-Type 没有修改任何网址内容。可是表现却有如此大的不同，究竟是为什么呢？</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/a-bug-of-rewrite-module-in-apache/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>新空间</title>
		<link>http://blog.upsuper.org/my-new-web-space/</link>
		<comments>http://blog.upsuper.org/my-new-web-space/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 15:11:20 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[CGI]]></category>
		<category><![CDATA[My Blog]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[和谐]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1069</guid>
		<description><![CDATA[由于某些众所周知的原因，我准备将空间搬到米国去了。由于另一个众所周知的原因，现在的域名也将很快停止使用。 我已经申请好了新的空间，近期可能就要搬过去了。先做个广告：在此诚招空间合租者一位，无限空间无限流量，PHP、Python、Perl、RoR、CGI、CGI-BIN、MySQL、PgSQL 全功能 Linux 空间，可自定义 php.ini，提供域名对应的邮箱储存、邮箱别名服务，支持 POP3、IMAP、邮件列表，独立 FTP 管理，带免费自签名证书的 SSL 服务，含一个免费域名及一个独立 IP，3年共计525元RMB。有意者邮箱联系 quanxunzhen@gmail.com 不过因为新空间还没摸索清楚，还在研究搬迁事宜。 下面讲讲今天的探索……这个新空间的 PHP 用了 CGI 的模式，而不是传统（或者说我熟悉的）PHP Module 的模式，而且作为 CGI 的 php 解析程序和 php.ini 配置文件也是放在网站的 cgi-bin 目录里面的，因此我怀疑可玩性很高，甚至可以自己编译 PHP 放上去用。不过这个空间有一个很麻烦的，就是不支持自动的泛域名匹配，这大大的不如现在的这个空间方便。不过经过一番研究，也并不是没有办法的。今天才算是第一次体会到了 Apache mod_rewrite 的强大！ 本来以为 rewrite 不能实现那样功能的，因为似乎 rewrite 不能把主机名弄进来匹配，结果发现我想错了。参考了一些 Apache 的官方资料，我发现 Apache 的官方文档里有一种很有趣的方式间接实现泛域名到子文件夹的匹配，大约是这个样子的： 1 2 3 4 RewriteEngine on RewriteCond %{HTTP_HOST} ^www\.[^.]+\.host\.com$ RewriteRule ^(.+) %{HTTP_HOST}$1 [...]]]></description>
			<content:encoded><![CDATA[<p>由于某些众所周知的原因，我准备将空间搬到米国去了。由于另一个众所周知的原因，现在的域名也将很快停止使用。</p>
<p>我已经申请好了新的空间，近期可能就要搬过去了。先做个广告：<strong>在此诚招空间合租者一位，无限空间无限流量，PHP、Python、Perl、RoR、CGI、CGI-BIN、MySQL、PgSQL 全功能 Linux 空间，可自定义 php.ini，提供域名对应的邮箱储存、邮箱别名服务，支持 POP3、IMAP、邮件列表，独立 FTP 管理，带免费自签名证书的 SSL 服务，含一个免费域名及一个独立 IP，3年共计525元RMB。有意者邮箱联系 <a href="mailto:quanxunzhen@gmail.com">quanxunzhen@gmail.com</a></strong></p>
<p>不过因为新空间还没摸索清楚，还在研究搬迁事宜。<br />
<span id="more-1069"></span><br />
下面讲讲今天的探索……这个新空间的 PHP 用了 CGI 的模式，而不是传统（或者说我熟悉的）PHP Module 的模式，而且作为 CGI 的 php 解析程序和 php.ini 配置文件也是放在网站的 cgi-bin 目录里面的，因此我怀疑可玩性很高，甚至可以自己编译 PHP 放上去用。不过这个空间有一个很麻烦的，就是不支持自动的泛域名匹配，这大大的不如现在的这个空间方便。不过经过一番研究，也并不是没有办法的。今天才算是第一次体会到了 Apache mod_rewrite 的强大！</p>
<p>本来以为 rewrite 不能实现那样功能的，因为似乎 rewrite 不能把主机名弄进来匹配，结果发现我想错了。参考了一些 Apache 的官方资料，我发现 Apache 的官方文档里有一种很有趣的方式间接实现泛域名到子文件夹的匹配，大约是这个样子的：</p>

<div class="wp_codebox"><table><tr id="p1069105"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p1069code105"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">on</span>
<span style="color: #00007f;">RewriteCond</span>   %{HTTP_HOST}                 ^www\.[^.]+\.host\.com$
<span style="color: #00007f;">RewriteRule</span>   ^(.+)                        %{HTTP_HOST}$<span style="color: #ff0000;">1</span>          [C]
<span style="color: #00007f;">RewriteRule</span>   ^www\.([^.]+)\.host\.com(.*) /home/$<span style="color: #ff0000;">1</span>$<span style="color: #ff0000;">2</span></pre></td></tr></table></div>

<p>惊叹于这种其实妙想！这个恐怕能实现的功能比那个 VirtualHost 的模块还要强大了吧~</p>
<p>不过这个代码似乎是不能用的囧……做一个适合的修改就发生 500 错误……经过思考，我想起了很早以前说过的，mod_rewrite 是会把修改过的网址再次注入 rewrite 的，因此如果这样那么这个网址可能会不断的经过这个 rewrite 过程，造成死循环，最后被 Apache 以 500 强制结束。</p>
<p>看来想在网站根目录下像现在这样搞是不行了……不过，办法总是有的，其实有的时候我觉得自己还是蛮聪明的~我就在根目录下建立了一个名叫 www 的文件夹，然后给出了下面这样的 .htaccess：</p>

<div class="wp_codebox"><table><tr id="p1069106"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1069code106"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span>
<span style="color: #00007f;">RewriteCond</span> %{HTTP_HOST} ^[^\.]+\.upsuper\.org\.cn$
<span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} !^/www/
<span style="color: #00007f;">RewriteRule</span> ^(.*)$ %{HTTP_HOST}/$<span style="color: #ff0000;">1</span>
<span style="color: #00007f;">RewriteRule</span> ^([^\.]+)\.upsuper\.org\.cn/(.*)$ /www/$<span style="color: #ff0000;">1</span>/$<span style="color: #ff0000;">2</span></pre></td></tr></table></div>

<p>OK，现在已经非常正常了，网页可以正常访问了~不过新的问题再度出现！所有的 PHP 都显示 404 错误……我汗！404？！那个 PHP 明明在那里凭啥 404 呢？</p>
<p>后来在空间商的 FAQ 里面偶然看到，解析 PHP 用的东西储存在已经被我删掉的 cgi-bin 文件夹里面……呃……马上把所有内容删掉恢复原来的内容。然后再放上这个，还是 404……其中必有问题……那么问题一定出在 cgi-bin 文件夹上……难道 Apache 最后也要通过自己访问 CGI 接口？其实其中奥妙我也不是很了解，不过最后又加了一条针对 cgi-bin 的 rewrite 规则，成功解决。关于 Apache 和 PHP 通过 CGI 接口的机制看来还是很值得好好研究研究的嗯……下面是最后的代码：</p>

<div class="wp_codebox"><table><tr id="p1069107"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p1069code107"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span>
<span style="color: #00007f;">RewriteCond</span> %{HTTP_HOST} ^[^\.]+\.upsuper\.org\.cn$
<span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} !^/www/
<span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} !^/cgi-bin/
<span style="color: #00007f;">RewriteRule</span> ^(.*)$ %{HTTP_HOST}/$<span style="color: #ff0000;">1</span>
<span style="color: #00007f;">RewriteRule</span> ^([^\.]+)\.upsuper\.org\.cn/(.*)$ /www/$<span style="color: #ff0000;">1</span>/$<span style="color: #ff0000;">2</span></pre></td></tr></table></div>

<p>最后还有一个小小的问题，就是遇到找不到的 PHP，服务器虽然返回了 404 的头，不过显示的内容却是“No input file specified.”，而不是我指定的 404 页面（当然，IE 用户肯定什么都看不到，因为 IE 已经默认为他们准备好了一个“友好”的 404 页面）。这个虽然不是什么大问题，不过也还是很烦人的，有搜索了一番，最后在 rewrite 规则里面又加了两行解决问题：</p>

<div class="wp_codebox"><table><tr id="p1069108"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1069code108"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">RewriteCond</span> %{DOCUMENT_ROOT}/$<span style="color: #ff0000;">1</span> !-f
<span style="color: #00007f;">RewriteRule</span> ^(.*\.php)$ - [T=text/html]</pre></td></tr></table></div>

<p>稍微想一想肯定看出来，这个代码不是没有问题的，不过我想我应该不会遇到吧……嗯……</p>
<p>最后就是关于 php.ini，php.ini 里面不小心撇到了 mbstring 的设置，发现默认语言竟然是 Japanese……呃……马上改成了 Chinese，并且把下面的默认编码 EUC-JP 也改成了 EUC-CN，真是无语……不知道这个是 PHP 的默认配置，还是那个客服看我英语这么差以为我是日本人“帮”我设置的呢？</p>
<p>参考资料：</p>
<ul>
<li><a href="http://httpd.apache.org/docs/2.2/rewrite/rewrite_guide.html">URL Rewriting Guide &#8211; Apache HTTP Server</a></li>
<li><a href="http://jenseng.com/archives/000035.html">“No input file specified” | jenseng.com</a> <a href="http://www.panuworld.net/">panuworld</a> 的回复</li>
</ul>
<p>还想讲一点买空间的事情。因为这个空间商支持支付宝，我就决定用支付宝。而且支付宝不是支持 Linux 么，很好的嘛。今天中午就跑到邮局去汇款给我很早以前申请了但一直没用的支付宝账户充钱。然后充完跑回来打开上网本登录支付宝充值……为什么要打开上网本？因为台机的 Arch Linux 已经把 Firefox 升级到了 3.6，而支付宝唯一支持 Linux 的插件，是不兼容 Firefox 3.6 的……幸好上网本的 Ubuntu 9.10 很乖巧的使用了 Firefox 3.5.8，还能用那个支付宝插件。很期待支付宝能快些支持 Firefox 3.6，这样我以后也可以网购了~这年头天朝的银行不厚道，几乎完全不支持我家 Linux……还是支付宝好嗯~</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/my-new-web-space/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Firefox 的 DOM Bug 一则</title>
		<link>http://blog.upsuper.org/a-dom-bug-of-firefox/</link>
		<comments>http://blog.upsuper.org/a-dom-bug-of-firefox/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 11:19:51 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Firefox]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1042</guid>
		<description><![CDATA[做完了上次那个音乐征集系统的投票平台，又积累了些新的东西。因为投票平台的一些设计这么早发出来不大好，所以就先发一个发现~ IE 的 Bug 已经说太多了，今天转过来，看看这次做的过程中发现的一个 Firefox 的 Bug~这个 Bug 的触发条件我已经初步探明了。 考察下面这个 HTML 文件： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 &#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62; &#60;html [...]]]></description>
			<content:encoded><![CDATA[<p>做完了上次那个音乐征集系统的投票平台，又积累了些新的东西。因为投票平台的一些设计这么早发出来不大好，所以就先发一个发现~</p>
<p>IE 的 Bug 已经说太多了，今天转过来，看看这次做的过程中发现的一个 Firefox 的 Bug~这个 Bug 的触发条件我已经初步探明了。<br />
<span id="more-1042"></span><br />
考察下面这个 HTML 文件：</p>

<div class="wp_codebox"><table><tr id="p1042111"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code" id="p1042code111"><pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span> xmlns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span style="color: #000066;">lang</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;en&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html;charset=UTF-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>Bug of Firefox<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;all&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;a.css&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;test&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">style</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span>&gt;</span>
    body { background: #ccc; }
    #x { float: left; height: 3em; width: 10em; margin-right: 1em; }
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">style</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span>
    var t = 0;
    function $(id) {
      return document.getElementById(id);
    }
    function doit() {
      t = (t + 1) % 2;
      var $x = $('x');
      $('test').href = ['a.css', 'b.css'][t];
      style = window.getComputedStyle ? window.getComputedStyle($x, null)
                                      : $x.currentStyle;
      $('back').innerHTML = style.backgroundColor;
      $('color').innerHTML = style.color;
    }
  <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
  <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;x&quot;</span> <span style="color: #000066;">onclick</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;doit()&quot;</span>&gt;</span>Hello!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
  background: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;back&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
  color: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;color&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>下面考察两个 CSS 文件：</p>

<div class="wp_codebox"><table><tr id="p1042112"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1042code112"><pre class="css" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* a.css */</span>
<span style="color: #cc00cc;">#x</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* b.css */</span>
<span style="color: #cc00cc;">#x</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span> <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>很明显，这个页面就是点击那个 div，然后交替变换样式表，这就是我做网页即时换肤的重要方法。那么这有什么问题呢？</p>
<p>问题就在，第一次点击那个 div 后。我们先猜测一下，第一次点击那个 div 后，background: 后面应该出现 #000 或一个与其等效的颜色值，而 color: 后面则应该出现 #fff 或一个与其等效的颜色值。下面我们来看一下结果：<br />
<a href="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_fx.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_fx-300x45.png" alt="" title="Bug of Firefox_fx" width="300" height="45" class="alignnone size-medium wp-image-1049" /></a><a href="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_cr.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_cr-300x45.png" alt="" title="Bug of Firefox_cr" width="300" height="45" class="alignnone size-medium wp-image-1048" /></a><a href="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_op.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_op-300x45.png" alt="" title="Bug of Firefox_op" width="300" height="45" class="alignnone size-medium wp-image-1051" /></a><a href="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_ie.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/02/Bug-of-Firefox_ie-300x45.png" alt="" title="Bug of Firefox_ie" width="300" height="45" class="alignnone size-medium wp-image-1050" /></a></p>
<p>上面这些截图从左到右从上到下依次是：Firefox 3.5.7 for Ubuntu、Chromium 5.0.320.0 for Ubuntu、Opera 10.00 for Linux 和 Internet Explorer 6.0.2800.1106。可以非常明显的看出，除了 Firefox，其他几个浏览器都返回了完全正确的结果！Firefox 啊 Firefox……</p>
<p><del datetime="2010-02-11T13:21:53+00:00">不知道这个 Bug 有没有人发现并提交过呢？反正这个 Bug 以我的英文水平我肯定是描述不清楚的……哪位大大帮我提交一下吧，谢了嗯~</del></p>
<p><del datetime="2010-02-11T12:32:02+00:00">不过这个 Bug 是否仅在 Linux 版出现我还不是非常清楚，甚至是不是仅仅在我的机子上出现，我都不了解……因此各位用 Firefox for Windows 的人也可以测试一下。</del></p>
<p><del datetime="2010-02-12T01:18:33+00:00">经过测试，Firefox 3.6 for Windows 也存在这一 Bug，看来是没人提交过……</p>
<p>我已经向 Mozilla 提交了这一 Bug：<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=545636">Bug 545636</a>，不知道表达的好不好……</del></p>
<p>此 Bug 已经被标明无效，原因是一名开发者发现在远程的情况下 Opera 和 Safari 等其他浏览器给出了同 Firefox 一样的结果，而导致这种结果的原因在于在异步的文件请求还未处理完成的情况下立即要求所需值。</p>
<p>经过实验，如果远程访问，并且样式表与网页分离的情况下，似乎各个浏览器都会出现类似问题，即因为异步访问照成延迟。但当测试一个人提交的<a href="https://bugzilla.mozilla.org/attachment.cgi?id=426498">将样式表嵌入网页的版本</a>后，Chromium 会偶然出现反馈错误，Firefox 总是出现错误，Opera 没有出现错误……我毛估 IE6 不支持那种写法，就不测试了。但在本地测试的情况下，永远只有 Firefox 出错。</p>
<p>我想这或许正如那个开发者所认为的，不能算是 Bug，但这至少说明 Firefox 在某些位置的效率也是差到一种境界了……</p>
<p>关于 IE6 非标准的 CSS 读取方法参考了：<a href="http://www.jb51.net/article/16128.htm">用javascript getComputedStyle获取和设置style的原理_javascript技巧_脚本之家</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/a-dom-bug-of-firefox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox 3.5 对 PNG 图像颜色处理的问题</title>
		<link>http://blog.upsuper.org/problem-of-processing-color-of-png-image-in-firefox-35/</link>
		<comments>http://blog.upsuper.org/problem-of-processing-color-of-png-image-in-firefox-35/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 11:37:16 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Bug]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[标准化]]></category>
		<category><![CDATA[颜色]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1012</guid>
		<description><![CDATA[今天做投票系统的界面的时候又遇到了那个问题：用图片表示的部分和纯色部分衔接有问题。我开始还以为是我当时编写的时候就有问题，由于显示器的缘故儿没有发现。今天想解决一下这个问题，找找原因。 我先打开了 GIMP，把用的背景图片打开，取了颜色，发现颜色就是其他部分的颜色。我就奇怪了，从数值上说应该是一样的才对。然后我就取了 Firefox 里面的色，发现 Firefox 里面图片对应位置的颜色被修改了？！ 下面是一个关于这一 bug 的演示： 如果你看了觉得看到的是一个完全的纯色的区域，那么说明你没有遇到这一问题。但如果你看到不是一个纯色区域，那么就说明你也遇到了同样的问题……找了一圈，没有发现相关的中文资料，觉得非常无语，难道都没人发现这么严重的问题么…… 在英文资料中我倒是找到了些头绪。首先，Mozilla 表示这是一个 Feature 而非一个 Bug！他们声称这是在 Firefox 3.0 中引入了默认的颜色管理 (Color Management) 和颜色矫正 (Color Correction)，但默认被禁用，而在 Firefox 3.5 中由于效率的改进将其默认设置改为对于部分图片打开了。根据 Mozilla 官方的资料来看，这无疑是一个很好的进步，因为它使得 Firefox 显示的色彩可以和这一图片反映的真实色彩一致，使得这一图片无论在任何平台或者任何显示、输出设备上得到的颜色都是一样的。可是可是，问题是，如果 Firefox 和 GIMP 上显示的效果不一样，而 Firefox 又是正确的，那么 GIMP 作为可以在大部分场合取代 Photoshop 的图片处理软件的颜面何存呢？所以显然错的是 Firefox…… 在官方文档的最后，我们终于找到了，Mozilla 承认这是一个 bug，并且辩称仅仅是因为只支持到了 ICC 第二版，而没有支持到第四版导致的“图片可能偏暗” (This may result in images being too dark.)……Firefox [...]]]></description>
			<content:encoded><![CDATA[<p>今天做投票系统的界面的时候又遇到了那个问题：用图片表示的部分和纯色部分衔接有问题。我开始还以为是我当时编写的时候就有问题，由于显示器的缘故儿没有发现。今天想解决一下这个问题，找找原因。</p>
<p>我先打开了 GIMP，把用的背景图片打开，取了颜色，发现颜色就是其他部分的颜色。我就奇怪了，从数值上说应该是一样的才对。然后我就取了 Firefox 里面的色，发现 Firefox 里面图片对应位置的颜色被修改了？！</p>
<p>下面是一个关于这一 bug 的演示：</p>
<div style="background-color: #5190d3; text-align: center; vertical-align: middle; width: 100px; height: 100px; padding: 20px; margin-left: auto; margin-right: auto;"><img src="http://blog.upsuper.org/wp-content/uploads/2010/02/pure.png" alt="" title="pure" width="100" height="100" class="alignnone size-full wp-image-1013" style="border: 0" /></div>
<p>如果你看了觉得看到的是一个完全的纯色的区域，那么说明你没有遇到这一问题。但如果你看到不是一个纯色区域，那么就说明你也遇到了同样的问题……找了一圈，没有发现相关的中文资料，觉得非常无语，难道都没人发现这么严重的问题么……<br />
<span id="more-1012"></span><br />
在英文资料中我倒是找到了些头绪。首先，Mozilla 表示这是一个 Feature 而非一个 Bug！他们声称这是在 Firefox 3.0 中引入了默认的颜色管理 (Color Management) 和颜色矫正 (Color Correction)，但默认被禁用，而在 Firefox 3.5 中由于效率的改进将其默认设置改为对于部分图片打开了。根据 Mozilla 官方的资料来看，这无疑是一个很好的进步，因为它使得 Firefox 显示的色彩可以和这一图片反映的真实色彩一致，使得这一图片无论在任何平台或者任何显示、输出设备上得到的颜色都是一样的。可是可是，问题是，如果 Firefox 和 GIMP 上显示的效果不一样，而 Firefox 又是正确的，那么 GIMP 作为可以在大部分场合取代 Photoshop 的图片处理软件的颜面何存呢？所以显然错的是 Firefox……</p>
<p>在官方文档的最后，我们终于找到了，Mozilla 承认这是一个 bug，并且辩称仅仅是因为只支持到了 ICC 第二版，而没有支持到第四版导致的“图片可能偏暗” (This may result in images being too dark.)……Firefox 啊 Firefox，真不是我说你，ICC 第四版早在2001年就发布了，你既然准备支持了还不直接支持到完全，结果搞出这么个莫名其妙的 bug 还好意思说是 Feature……</p>
<p>说的差不多了……最后是解决的办法：对于用户来说，如果遇到这种情况，可以直接在 Firefox 的设置里面调整使之不自作聪明的进行错误的颜色矫正。只要打开 about:config，然后找到 gfx.color_management.mode 一项，将其值修改为 0 并重新启动 Firefox 即可。至于网站制作者，可以通过去除所有可能激活 Firefox 颜色矫正机制的信息来解决，对于 png 图片来说，就是安装 pngcrush 软件，然后对图片运行下面命令：</p>

<div class="wp_codebox"><table><tr id="p1012114"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1012code114"><pre class="bash" style="font-family:monospace;">pngcrush <span style="color: #660033;">-rem</span> gAMA <span style="color: #660033;">-rem</span> cHRM <span style="color: #660033;">-rem</span> iCCP <span style="color: #660033;">-rem</span> sRGB 输入文件.png 输出文件.png</pre></td></tr></table></div>

<p>这件事呢，不禁让我想起了当年 IE 浏览器（8以下）对于 gamma 值的误读，也是自作聪明地来矫正颜色。这次 Firefox 的做法和当年的 IE 几乎如出一辙，实在是不能不让人感到失望啊。</p>
<p>参考资料：</p>
<ul>
<li><a href="https://developer.mozilla.org/En/ICC_color_correction_in_Firefox">ICC color correction in Firefox &#8211; MDC</a></li>
<li><a href="http://hacks.mozilla.org/2009/06/color-correction/">color correction for images in Firefox 3.5 &#10025; Mozilla Hacks</a></li>
<li><a href="http://en.wikipedia.org/wiki/ICC_profile">ICC profile &#8211; Wikipedia</a></li>
<li><a href="http://f6design.com/journal/2006/12/01/fixing-png-gamma/">Pixel Acres &raquo; Fixing PNG Gamma</a></li>
</ul>
<p>最后，来看看<a href="http://www.color.org/version4html.xalter">你的浏览器和系统是否支持 ICC 标准了？</a>里面还有<a href="http://www.color.org/version4pdf.pdf">一个 PDF 文件</a>用于测试你的 PDF 阅读器。根据我的测试，Firefox 3.5（被我调整过设置的）、Chromium 5.0、Opera 10.0 无一支持 ICC，Firefox 3.5（默认设置）倒是可以正常的显示下半部分（ICC version 2），不过 Ubuntu 默认的 PDF 阅读器 Evince 倒是支持的很正常，看来 GNOME 还是很牛X的~</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/problem-of-processing-color-of-png-image-in-firefox-35/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>支持 Haiti 的小网站</title>
		<link>http://blog.upsuper.org/a-small-site-for-haiti/</link>
		<comments>http://blog.upsuper.org/a-small-site-for-haiti/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 13:03:24 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[公益]]></category>
		<category><![CDATA[兼容性]]></category>
		<category><![CDATA[地震]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=987</guid>
		<description><![CDATA[17号的时候虫子向我求助，想要我帮忙做一个支持海地的小网站。大体的思路就是，在上面的放一个大地图，然后大家可以留言、上传照片什么的，然后就在地图上出现亮点，然后亮点点进去可以看到留言和照片~这个网站已经进入公测了，大家可以在这里查看：Haiti]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.upsuper.org/wp-content/uploads/2010/01/Haiti-3_1264924757767.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/01/Haiti-3_1264924757767-300x211.png" alt="" title="Haiti &lt;3_1264924757767" width="300" height="211" class="alignright size-medium wp-image-1000" /></a>17号的时候虫子向我求助，想要我帮忙做一个支持海地的小网站。大体的思路就是，在上面的放一个大地图，然后大家可以留言、上传照片什么的，然后就在地图上出现亮点，然后亮点点进去可以看到留言和照片~这个网站已经进入公测了，大家可以在这里查看：<a href="http://haiti.dnand.org/">Haiti <3</a>（话说我曾经问虫子“<3”是什么意思，她告诉我，是爱心的意思~）</p>
<p>我猜从来没做过网站的人一定会觉得这个很简单，但我觉得一点都不简单……不过似乎可以实现~这种无疑又是对我技术的一次挑战！<br />
<span id="more-987"></span><br />
一开始，我想用一种十分取巧的方式——直接用 Google Maps~探究了一段时间的 Google Maps。结果虫子要求：一是地图要暗，二是要出来的是亮点。想想，Google Maps 还是算了呃……（话说其实也不是不可以，不过实现了，很多数据从客户端走，也不大好）。不过像 Google Maps 这样极好的地图图片来源实在是太难得了！于是就直接用了~</p>
<p>首先要攻克的第一个问题是，如果我们知道来访者的经纬度，如何知道把他的点点在地图的什么位置？这是一个很神奇的问题，想想经纬度是为球面设计的，现在要把它转换到一个平面上。说来也巧，原来参与过天文软件 Stellarium 某个版本的翻译工作，正好翻译了其中被称作地图投影的部分。因为有好几个不同的投影方式，我渐渐就明白了，那个就是把球面图形映射到平面的方法！于是就找到了地图投影，经过查询，发现 Google Maps 使用的是 <a href="http://en.wikipedia.org/wiki/Mercator_projection">Mercator projection</a> (<a href="http://zh.wikipedia.org/zh-cn/%E9%BA%A5%E5%8D%A1%E6%89%98%E6%8A%95%E5%BD%B1%E6%B3%95">麦卡托投影法/墨卡托投影法/正轴等角圆柱投影</a>)。找到了投影法的名称，自然转换公式不是难事~不过这个公式看不懂……呃……算了，那些公式显然不在我现在的数学水平能够理解的范围之内，直接用好了……</p>
<p>用前面探究到的 Google Maps 的东西，写了个网页，对比了一下 Google Maps 转换的坐标和我的程序转换的坐标之间的情况，发现基本相等，有一部分会出现 1px 的差异，我就直接忽略之了~在调试这个程序的过程中，比较重要的大概就是 PHP 里面的三角函数相关的函数使用的都是弧度，而我们习惯上使用的经纬度都是角度，这样就需要一点点的转换了……好在 PHP 提供了 deg2rad 这样方便的函数~话说我的地图投影这个程序我把它单独分了一个文件出来，主要是里面定义了各种地图转换需要的常数，如果和别的功能合在一起大约看过去会比较乱……</p>
<p>下面遇到第二个重大的问题是：我们如何知道来访者所在的经纬度？！这个问题似乎比上面那个更复杂了……当然你可以直接请来访者告诉你，不过更好的方法显然是根据 IP 地址识别一下。不过说到 IP 地址的识别精度，那我也无奈了。我猜想在 IPv6 普及前，想要准确根据 IP 地址识别出位置大约是不可能的了。不过，可以接受的精度还是可以实现的~国内的 IP 数据库如纯真这样的，提供的都是一个字符串地址，那个是只能给人看的，电脑可不知道那些东西表示什么……于是就转向了国外的 IP 数据库。果然找到了些有趣的数据库，里面能包含 IP 可能对应的经度和纬度，而且还提供 CSV 下载，可好了~这里可以找到这个好东西：<a href="http://ipinfodb.com/ip_database.php">IP address geolocation SQL database :: IPInfoDB</a>。然后我需要一个可以提供 PHP 快速查找的文件。其实这个事情第一次做音乐投票系统的时候，为了限制投票 IP 在福建境内，就做过这个东西。思路也很简单：把每个 IP 段的数据变成定长的二进制数据，然后需要的时候二分查找~于是有了下面的转换用 Python 脚本：</p>

<div class="wp_codebox"><table><tr id="p987116"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p987code116"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;"># - * - coding: UTF-8 - * -</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">csv</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
fin = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ip_group_city.csv'</span>, <span style="color: #483d8b;">'r'</span><span style="color: black;">&#41;</span>
c = <span style="color: #dc143c;">csv</span>.<span style="color: black;">reader</span><span style="color: black;">&#40;</span>fin, delimiter=<span style="color: #483d8b;">';'</span>, quotechar=<span style="color: #483d8b;">'&quot;'</span><span style="color: black;">&#41;</span>
fout = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ipdata.dat'</span>, <span style="color: #483d8b;">'wb'</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
a = <span style="color: #ff4500;">0</span>
s = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> r <span style="color: #ff7700;font-weight:bold;">in</span> c:
  a += <span style="color: #ff4500;">1</span>
  s.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&gt;Iff2sh'</span>,
      <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>r<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
      <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>r<span style="color: black;">&#91;</span><span style="color: #ff4500;">7</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, <span style="color: #008000;">float</span><span style="color: black;">&#40;</span>r<span style="color: black;">&#91;</span><span style="color: #ff4500;">8</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
      r<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">float</span><span style="color: black;">&#40;</span>r<span style="color: black;">&#91;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">'0'</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">if</span> a <span style="color: #66cc66;">%</span> <span style="color: #ff4500;">10000</span> == <span style="color: #ff4500;">0</span>:
    fout.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    s = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>, a,
fout.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #66cc66;">&gt;&gt;</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>, a
fin.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
fout.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>这样，就当获取经纬度差不多了吧~嗯~虽然那个精度实在不敢恭维……不过根据那个网站自己的数据，至少国家是不会弄错的（准确度 90%+），只是城市就不跟你保证了~（那个数据貌似显示，这个数据库中城市在中国只有 71% 左右是正确的……）。</p>
<p>最后是关于地图的最后一个问题……如何绘制？</p>
<p>经过考察，这个小网站未来要放的那个服务器是不支持 ImageMagick 的，于是只能用 GD 库了……</p>
<p>那个小点点，其实就是圆咯。于是我一开始用 imageFilledEllipse 函数在地图上画直径为 3px 的圆。不过那个的效果实在是不大行……另外一件事就是关于上传照片的问题，某些相机比较囧的都把照片方向弄在 Exif 里面……虽然 PHP 有很方便的库可以直接读取 Exif，但旋转和翻转就麻烦了……</p>
<p>关于 GD 库，有一件事我觉得很无语，那就是有好几个比较有趣的函数，如 imageAntiAlias、imageRotate 下面都写着：<br />
<blockquote>
    <strong>Note:</strong> This function is only available if PHP is compiled with the bundled version of the GD library.
</p></blockquote>
<p>于是就各种囧的不能在我自己机子上调试……目标服务器的 GD 库倒是符合条件，不过我发现其实想要通用还有一种很好的方法：在 Notes 里面找！通常不能通用的函数在 Notes 里面都有相应的通用解决方案~这次我在 Notes 里面找到了图片翻转、旋转、判断 Exif 方向、平滑绘制圆的函数~我觉得有些时候，下面的 Notes 比上面的文档要有意义的多……平滑绘制圆的函数，我为了半透明又改了一点。当然，改的不完美，也就不敢拿出来献丑了，勉强能用就是了~</p>
<p>此外，还抄来了 WordPress 里面一段创建不同大小图片和创建缩略图的代码，很好用嗯~话说，太久没写 PHP，很多东西都忘的差不多了，比如说输入的数据中有单引号会自动被 PHP escape 掉，这还让我苦恼了一下呃……</p>
<p>另外就是，设计中虫子给我提出了一个神奇的要求：跟 twitter。为了这件事，我进行了各种不和谐的活动，以了解 twitter 的 APIs……然后用了一个带缓冲的转接程序弄好了。</p>
<p>至于客户端部分，我再次使用了 jQuery，jQuery 果然是个好东西。而且为了上传，我又使用了 Uploadify。有赖于<a href="http://blog.upsuper.org/2009-recommend-platform-of-music-recruiter-for-fuzhou-no1-middle-school/">上一次做音乐征集系统</a>的经验，这次少走了不少弯路，而且大量的 IE6 的 bug 也被我巧妙地解决了~而且我发现 IE6 的某些莫名其妙的 bug （比如我在制作过程中遇到了一个 div 明明 right 是 0，却超出右边界很多）都可以通过设置 zoom: 1; 来解决……不知道 IE6 这种莫名其妙的浏览器到底是什么样 SB 的团队制作出来的。IE 曾经是带领万维网发展的，现在却成为了严重的阻碍者！用 IE 的孩子们赶快觉醒吧……我真得不想在为了 IE 花掉大把的时间调试了……</p>
<p>顺便说一下新发现的 IE6 的 bug（其实我也不知道是不是我新发现的……）：还是隐藏显示的问题。是用 AlphaImageLoader 这个 filter 的元素隐藏后显示，这个 filter 的效果会消失，也就是没用了……为了这个 bug，这次不得不在脚本中都加入了 ie-fix……而且，更严重的是，如果你在显示后再设置这个 filter，又会出现另外一个 bug：这个时候，被设置这个 filter 的元素内部的所有元素可见，但变成不可用，也就是好像点不到一样！我估计是这个 filter 变成了一个在元素内部最上层的一个东西，于是就挡住了其他所有的元素。我汗啊，IE6 的 QA 是干什么吃的啊……这个的解决办法说来也简单，另外弄一个 div，设置在同样的位置，同样的长宽，对他用那个 filter 就行了……</p>
<p>对了对了！说到 AlphaImageLoader 这个 filter，我又想起来一件事，证明了百度不适合用来搜索技术资料，至少比 Google 逊太多了：你分别在这两个搜索引擎里面输入“filter:progid:DXImageTransform.Microsoft.AlphaImageLoader”，我把结果贴出来：</p>
<div style="width: 100%; text-align: center;"><a href="http://blog.upsuper.org/wp-content/uploads/2010/01/_filterprogidDXImageTransform.Microsoft.AlphaImageLoader_1264941140183-e1264941753180.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/01/_filterprogidDXImageTransform.Microsoft.AlphaImageLoader_1264941140183-e1264941753180-190x300.png" alt="" title="百度搜索_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader_1264941140183" width="190" height="300" class="alignnone size-medium wp-image-998" /></a><a href="http://blog.upsuper.org/wp-content/uploads/2010/01/filterprogidDXImageTransform.Microsoft.AlphaImageLoader-Google-搜索_1264941161008.png"><img src="http://blog.upsuper.org/wp-content/uploads/2010/01/filterprogidDXImageTransform.Microsoft.AlphaImageLoader-Google-搜索_1264941161008-163x300.png" alt="" title="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader - Google 搜索_1264941161008" width="163" height="300" class="alignnone size-medium wp-image-995" /></a></div>
<p>请认真对比我的关键词和两个引擎的结果，你会发现：百度第一页没一个是我要找的，甚至连一个完整匹配的关键词都没有！难道是我的关键词是我瞎编的？不，你看 Google 的结果吧……嗯……事实胜于雄辩，百度众自重……</p>
<p>整个网站的代码，可能在经过完善以后会公布，也可能不公布。由于这次的东西不是做给自己的，所以不能完全我自己说的算了……</p>
<p>参考资料：</p>
<ul>
<li><a href="http://code.google.com/intl/zh-CN/apis/maps/">Google 地图 API &#8211; Google 代码</a></li>
<li><a href="https://groups.google.com/group/Google-Maps-API/msg/8222b18e7921f6e6">What type of map projection does Google use for Google Maps &#8211; Google Groups</a></li>
<li><a href="http://mathworld.wolfram.com/MercatorProjection.html">Mercator Projection &#8212; from Wolfram MathWorld</a></li>
<li><a href="http://www.maxmind.com/app/city_accuracy">MaxMind &#8211; GeoIP City Accuracy for Selected Countries</a></li>
<li><a href="http://apiwiki.twitter.com/">Twitter API Wiki</a> (请自备专用工具访问)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/a-small-site-for-haiti/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>wine 在终端下中文显示的问题</title>
		<link>http://blog.upsuper.org/how-to-display-chinese-for-wined-program-in-terminal/</link>
		<comments>http://blog.upsuper.org/how-to-display-chinese-for-wined-program-in-terminal/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 08:13:22 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Wine]]></category>
		<category><![CDATA[编码]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=959</guid>
		<description><![CDATA[众所周知，Windows 下的中文程序使用的是 GBK 或 GB18030 编码，而 Linux 下则默认是 UTF-8 编码。对于图形界面的程序，wine 对中文的处理似乎已经做的不错了，但对于文字界面就无能为力了…… 在网上找了找，发现很多人的方法是改 .profile 或者 .bashrc，在里面把 LANG 和 LC_ALL 设置为 zh_CN.gbk 或 zh_CN.gb18030。这种方法对于只在 Windows 下用终端连接 Linux 的用户当然没问题，可是对于像我这样惯用 Linux 的人怎么办？ 于是乎我就找到这么一篇文章：ubuntu下如何让terminal编码自动切换 根据这篇的做法，我先执行了 1 2 3 4 sudo mkdir /usr/lib/X11/locale sudo ln -s /usr/share/X11/locale/locale.alias /usr/lib/X11/locale/ sudo mkdir -p /usr/lib/X11/fonts/encoding/ sudo ln -s /usr/share/X11/fonts/encodings/encoding.dir /usr/lib/X11/fonts/encoding/ 然后再用 1 luit -encoding [...]]]></description>
			<content:encoded><![CDATA[<p>众所周知，Windows 下的中文程序使用的是 GBK 或 GB18030 编码，而 Linux 下则默认是 UTF-8 编码。对于图形界面的程序，wine 对中文的处理似乎已经做的不错了，但对于文字界面就无能为力了……</p>
<p>在网上找了找，发现很多人的方法是改 .profile 或者 .bashrc，在里面把 LANG 和 LC_ALL 设置为 zh_CN.gbk 或 zh_CN.gb18030。这种方法对于只在 Windows 下用终端连接 Linux 的用户当然没问题，可是对于像我这样惯用 Linux 的人怎么办？<br />
<span id="more-959"></span><br />
于是乎我就找到这么一篇文章：<a href="http://doc.linuxpk.com/40459.html">ubuntu下如何让terminal编码自动切换</a></p>
<p>根据这篇的做法，我先执行了</p>

<div class="wp_codebox"><table><tr id="p959120"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p959code120"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>locale
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>locale<span style="color: #000000; font-weight: bold;">/</span>locale.alias <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>locale<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>fonts<span style="color: #000000; font-weight: bold;">/</span>encoding<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>fonts<span style="color: #000000; font-weight: bold;">/</span>encodings<span style="color: #000000; font-weight: bold;">/</span>encoding.dir <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>X11<span style="color: #000000; font-weight: bold;">/</span>fonts<span style="color: #000000; font-weight: bold;">/</span>encoding<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

<p>然后再用</p>

<div class="wp_codebox"><table><tr id="p959121"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p959code121"><pre class="bash" style="font-family:monospace;">luit <span style="color: #660033;">-encoding</span> gb18030 wine program.exe</pre></td></tr></table></div>

<p>就可以正常显示中文了！</p>
<p>不过好生麻烦啊……</p>
<p>于是进一步的，把 ~/.bash_aliases 文件（不存在就新建）里面加上一行：</p>

<div class="wp_codebox"><table><tr id="p959122"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p959code122"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">wine</span>=<span style="color: #ff0000;">'luit -encoding gb18030 wine'</span></pre></td></tr></table></div>

<p>从此以后，只要在使用 windows 命令行程序的时候使用 wine program.exe 这种形式，就可以正常显示中文啦~</p>
<p>话说回来，这个方法有一个很大的问题，就是载入和退出似乎特别慢……不过能显示中文才是王道哈~</p>
<p>另外，经过特别的努力，我的 twitter 也终于申请到了，大家可以 follow <a href="http://twitter.com/upsuperx">@upsuperx</a>……</p>
<p>话说，这些资料都是 Google.cn 里面找的……如果 Google 真的退出中国，我应该去哪找资料啊……百度在技术资料这块简直是废物啊……Google 你快回来……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/how-to-display-chinese-for-wined-program-in-terminal/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>基于 jQuery 的 CSS 更换术</title>
		<link>http://blog.upsuper.org/replace-css-based-on-jquery/</link>
		<comments>http://blog.upsuper.org/replace-css-based-on-jquery/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 12:56:39 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=854</guid>
		<description><![CDATA[最近开始写一中的新选歌系统，这次要大改，顺便练手。 想加入换肤功能（不然女生肯定觉得老是蓝色不好……），而且我想到的换肤，最简单的方式就是换 CSS，把界面颜色、图形相关的内容放入皮肤的 CSS 中就很容易了~不过问题是换肤呢？ 正好新系统中因为客户端代码可能非常强大，准备引入 jQuery 框架来简化开发，便学了一些。于是我就想，能不能通过 jQuery 来解决呢？ 首先，我给出了下面这个简单的页面： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 &#60;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&#34;&#62; &#60;html xmlns=&#34;http://www.w3.org/1999/xhtml&#34; xml:lang=&#34;zh-CN&#34;&#62; &#60;head profile=&#34;http://gmpg.org/xfn/11&#34;&#62; &#60;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=UTF-8&#34; /&#62; &#60;title&#62;福州一中 学校音乐征集&#60;/title&#62; &#60;link rel=&#34;stylesheet&#34; href=&#34;&#34; id=&#34;theme&#34; type=&#34;text/css&#34; media=&#34;all&#34; /&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>最近开始写一中的新选歌系统，这次要大改，顺便练手。</p>
<p>想加入换肤功能（不然女生肯定觉得老是蓝色不好……），而且我想到的换肤，最简单的方式就是换 CSS，把界面颜色、图形相关的内容放入皮肤的 CSS 中就很容易了~不过问题是换肤呢？</p>
<p>正好新系统中因为客户端代码可能非常强大，准备引入 jQuery 框架来简化开发，便学了一些。于是我就想，能不能通过 jQuery 来解决呢？</p>
<p>首先，我给出了下面这个简单的页面：</p>

<div class="wp_codebox"><table><tr id="p854130"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p854code130"><pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span> xmlns<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span> xml:<span style="color: #000066;">lang</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;zh-CN&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span> <span style="color: #000066;">profile</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://gmpg.org/xfn/11&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>福州一中 学校音乐征集<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;theme&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;all&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;theme.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">style</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span>&gt;</span>
html, body { height: 100%; width: 100%; }
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">style</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
Hello world!
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>然后我开始用了一段 jQuery 手册里的<a href="http://docs.jquery.com/Core/jQuery#htmlownerDocument">某段示例代码</a>：</p>

<div class="wp_codebox"><table><tr id="p854131"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p854code131"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;link rel=&quot;stylesheet&quot; href=&quot;'</span> <span style="color: #339933;">+</span> 
    <span style="color: #009900;">&#40;</span>t<span style="color: #339933;">++</span> <span style="color: #339933;">&amp;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.css&quot; id=&quot;theme&quot; type=&quot;text/css&quot; media=&quot;all&quot; /&gt;'</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'head'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>成功了，不过查看处理后的代码，发现大量冗余代码出现在 head 尾部……又查了查，发现了 jQuery 里面的<a href="http://docs.jquery.com/Manipulation/replaceAll#selector">另外一个好用的函数</a>，于是上面代码就改为：</p>

<div class="wp_codebox"><table><tr id="p854132"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p854code132"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;link rel=&quot;stylesheet&quot; href=&quot;'</span> <span style="color: #339933;">+</span> 
    <span style="color: #009900;">&#40;</span>t<span style="color: #339933;">++</span> <span style="color: #339933;">&amp;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.css&quot; id=&quot;theme&quot; type=&quot;text/css&quot; media=&quot;all&quot; /&gt;'</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #660066;">replaceAll</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#theme&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>没有冗余代码出现，而且 IE6 都可以正常使用！jQuery 的兼容性果然超群……</p>
<p>然后我们想，这样每次都要重建标签，会不会很慢呢？如果能直接改属性或许不错~再查查，我们发现下面方法：</p>

<div class="wp_codebox"><table><tr id="p854133"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p854code133"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#theme&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> href<span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>t<span style="color: #339933;">++</span> <span style="color: #339933;">&amp;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.css'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>又简洁看过去又高效~再试试 IE6，仍然没有问题哦~<br />
<span id="more-854"></span><br />
最后给出实验用各完整代码：</p>

<div class="wp_codebox"><table><tr id="p854134"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p854code134"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> t <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  $<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#theme&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> href<span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>t<span style="color: #339933;">++</span> <span style="color: #339933;">&amp;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.css'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p854135"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p854code135"><pre class="css" style="font-family:monospace;">body <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">blue</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">yellow</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p854136"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p854code136"><pre class="css" style="font-family:monospace;">body <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#000</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/replace-css-based-on-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>闰年判断的优化及其他</title>
		<link>http://blog.upsuper.org/optimize-leap-year-checking-and-other/</link>
		<comments>http://blog.upsuper.org/optimize-leap-year-checking-and-other/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 13:10:37 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[Javran]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=833</guid>
		<description><![CDATA[今天 Javran 发来短信给了一个短小的论年判断代码，并且问我是否认为有更简单的表达。下面是他最初给的代码： 1 return &#40;&#40;y &#38; 3 != 0&#41; ^ &#40;y % 100 == 0&#41; ^ &#40;y % 400 != 0&#41;&#41;; 一切的探究就从这个代码开始了。 当然，这个代码是错的，因为疏忽了运算符的优先级，为达到本来的目的，这段代码大概应该这样改（测试代码3）： 1 return &#40;&#40;&#40;y &#38; 3&#41; != 0&#41; ^ &#40;y % 100 == 0&#41; ^ &#40;y % 400 != 0&#41;&#41;; 接着，我将其中“!=0”和“==0”可以进一步缩短，现在代码现在变成这样（测试代码4）： 1 return !!&#40;y &#38; 3&#41; ^ !&#40;y % 100&#41; ^ !!&#40;y [...]]]></description>
			<content:encoded><![CDATA[<p>今天 Javran 发来短信给了一个短小的论年判断代码，并且问我是否认为有更简单的表达。下面是他最初给的代码：</p>

<div class="wp_codebox"><table><tr id="p833149"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p833code149"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>一切的探究就从这个代码开始了。<br />
<span id="more-833"></span></p>
<p>当然，这个代码是错的，因为疏忽了运算符的优先级，为达到本来的目的，这段代码大概应该这样改（测试代码3）：</p>

<div class="wp_codebox"><table><tr id="p833150"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p833code150"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>接着，我将其中“!=0”和“==0”可以进一步缩短，现在代码现在变成这样（测试代码4）：</p>

<div class="wp_codebox"><table><tr id="p833151"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p833code151"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #339933;">!!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #339933;">!!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>OK，对于抑或得到的思路，精简到这里差不多了。Javran 随后又给我了一个代码：</p>

<div class="wp_codebox"><table><tr id="p833152"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p833code152"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">25</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #339933;">!!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">25</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>我说这比我的代码长，他解释说这段代码模的规模比较小，应该快一些。我说再快快不过 if 句。话说，经过实验，这条语句似乎是错误的……</p>
<p>不过，这让我突然想起了对于 &#038;&#038; 和 || 这样逻辑运算符的优化，我便想看看这个判断最快能至何~</p>
<p>我们先看看最传统的判断代码（测试代码1）：</p>

<div class="wp_codebox"><table><tr id="p833153"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p833code153"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">4</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>然后我们做点小小的优化（测试代码2）：</p>

<div class="wp_codebox"><table><tr id="p833154"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p833code154"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>接着我就按着这个的判断方式的思路进行一点缩减：</p>

<div class="wp_codebox"><table><tr id="p833155"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p833code155"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">||</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>然后根据前面的方式缩短行（测试代码5）：</p>

<div class="wp_codebox"><table><tr id="p833156"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p833code156"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>可以看出，这是目前最短的一个判断方式。</p>
<p>下面我做了30轮，每轮每个代码执行2,000,000次，取最短时间，得到如下结果：</p>

<div class="wp_codebox"><table><tr id="p833157"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p833code157"><pre class="text" style="font-family:monospace;">1: 0.043275
2: 0.043562
3: 0.093261
4: 0.093184
5: 0.036421</pre></td></tr></table></div>

<p>首先我们观察到，我最后推出的那个最短的式子是最快的，为什么？这是源于逻辑运算符的运算规则：对于 &#038;&#038;，如果前面项为假则不计算后项；对于 ||，如果前项为真则不计算后项。这就像 if 语句的递推作用：不做无谓的计算。而很显然，3和4的速度很慢，因为使用了异或运算，由于异或运算本身无法预测结果，必须把每一项都计算出来才行，因此慢了很多（比传统算法慢了一倍）。事实上按位运算应该都是这样。</p>
<p>接着我们看到，我对 Javran 最初代码的优化版本效率有一定提高，可能是因为将减法（比较运算实质是做减法）化为了位操作吧。而对传统代码的优化却反而减慢了它，或许是修改规则导致的副作用吧……不过我的最终优化代码还是快了不少，原因不明，或许 if 并不快？</p>
<p>应该有人会觉得奇怪，为什么要取最短时间，而不是平均值呢？事实上，我想在进行效率测试的时候，应该看最短时间。我们考虑测量效率时引入的误差出现在什么地方：CPU 肯定不会因为某个函数突然超频加速。那么有什么问题呢？因为我们用的都是分时系统，系统会不断的调度不同的线程使用 CPU。误差就在这里：时间会因为任务的切换而变长！因此测量结果只可能比实际值长，不可能比实际值短。所以要取最短时间。</p>
<p>OK，对闰年的探索暂告一段落。我们突然想起前面 Javran 所给出的“缩小模的规模带来效率提升”的论断。</p>
<p>因此我的测试程序增加了3个测试代码（测试代码6-8）：</p>

<div class="wp_codebox"><table><tr id="p833158"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p833code158"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">return</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">25</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>得到的结果让人吃惊：</p>

<div class="wp_codebox"><table><tr id="p833159"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p833code159"><pre class="text" style="font-family:monospace;">6: 0.106022
7: 0.098434
8: 0.098487</pre></td></tr></table></div>

<p>模25最慢，400次之，而100最快，一样原因不明。看起来难道模的速度和模的数有关系？</p>
<p>嗯，讨论了这么多，其实最初的问题——闰年判断的简化和优化——比较无聊，因为这段代码本身就不长，也几乎不可能被用于热点处。不过从这个过程中，我们看到了一些有趣的优化方式，虽然不能如算法改进那样降低复杂度，但这里有的时候常数也很重要，不是么？此外，还有一些关于效率测试的讨论。最后，我们还看到了一点神奇的结果，有待进一步探究咯~</p>
<p>最后贴出测试代码：</p>

<div class="wp_codebox"><table><tr id="p833160"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
</pre></td><td class="code" id="p833code160"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/time.h&gt;</span>
&nbsp;
<span style="color: #339933;">#define TRUE  1</span>
<span style="color: #339933;">#define FALSE 0</span>
&nbsp;
<span style="color: #339933;">#define CHECK(NUM)  if (check##NUM(i) != a) printf(#NUM)</span>
&nbsp;
<span style="color: #339933;">#define YEAR_AMOUNT 2000000</span>
<span style="color: #339933;">#define TEST(NUM) \
  gettimeofday(&amp;tv_s, &amp;tz); \
  for (j = 1; j &lt;= YEAR_AMOUNT; ++j) \
    check##NUM(j); \
  gettimeofday(&amp;tv_e, &amp;tz); \
  timeval_subtract(&amp;tv_d, &amp;tv_e, &amp;tv_s); \
  if (mtime[NUM].tv_sec == 0 &amp;&amp; \
      mtime[NUM].tv_usec == 0 || \
      tv_d.tv_sec &lt; mtime[NUM].tv_sec || \
      tv_d.tv_sec == mtime[NUM].tv_sec &amp;&amp; \
      tv_d.tv_usec &lt; mtime[NUM].tv_usec) \
    mtime[NUM] = tv_d; \
  printf(#NUM &quot; &quot;)</span>
&nbsp;
<span style="color: #993333;">int</span> y<span style="color: #339933;">;</span>
<span style="color: #993333;">struct</span> timeval mtime<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">struct</span> timezone tz<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> check1<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">4</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> TRUE<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">return</span> TRUE<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check2<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> TRUE<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> TRUE<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">return</span> FALSE<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check3<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check4<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #339933;">!!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #339933;">!!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check5<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">&amp;</span> <span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check6<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">25</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check7<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> check8<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> y<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> y <span style="color: #339933;">%</span> <span style="color: #0000dd;">400</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 时间减法</span>
<span style="color: #993333;">int</span> timeval_subtract<span style="color: #009900;">&#40;</span>result<span style="color: #339933;">,</span> x<span style="color: #339933;">,</span> y<span style="color: #009900;">&#41;</span>
       <span style="color: #993333;">struct</span> timeval <span style="color: #339933;">*</span>result<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>x<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>y<span style="color: #339933;">;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">&lt;</span> y<span style="color: #339933;">-&gt;</span>tv_usec<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> nsec <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>y<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">-</span> x<span style="color: #339933;">-&gt;</span>tv_usec<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #0000dd;">1000000</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
    y<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">-=</span> <span style="color: #0000dd;">1000000</span> <span style="color: #339933;">*</span> nsec<span style="color: #339933;">;</span>
    y<span style="color: #339933;">-&gt;</span>tv_sec <span style="color: #339933;">+=</span> nsec<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">-</span> y<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">&gt;</span> <span style="color: #0000dd;">1000000</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> nsec <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>x<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">-</span> y<span style="color: #339933;">-&gt;</span>tv_usec<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #0000dd;">1000000</span><span style="color: #339933;">;</span>
    y<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">+=</span> <span style="color: #0000dd;">1000000</span> <span style="color: #339933;">*</span> nsec<span style="color: #339933;">;</span>
    y<span style="color: #339933;">-&gt;</span>tv_sec <span style="color: #339933;">-=</span> nsec<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  result<span style="color: #339933;">-&gt;</span>tv_sec <span style="color: #339933;">=</span> x<span style="color: #339933;">-&gt;</span>tv_sec <span style="color: #339933;">-</span> y<span style="color: #339933;">-&gt;</span>tv_sec<span style="color: #339933;">;</span>
  result<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">=</span> x<span style="color: #339933;">-&gt;</span>tv_usec <span style="color: #339933;">-</span> y<span style="color: #339933;">-&gt;</span>tv_usec<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> x<span style="color: #339933;">-&gt;</span>tv_sec <span style="color: #339933;">&lt;</span> y<span style="color: #339933;">-&gt;</span>tv_sec<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">int</span> i<span style="color: #339933;">,</span> j<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// 验证代码正确性</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;=</span> YEAR_AMOUNT<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> a<span style="color: #339933;">;</span>
    a <span style="color: #339933;">=</span> check1<span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    CHECK<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> CHECK<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> CHECK<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> CHECK<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Check complete!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// 开始计时</span>
  <span style="color: #993333;">struct</span> timeval tv_s<span style="color: #339933;">,</span> tv_e<span style="color: #339933;">;</span>
  <span style="color: #993333;">struct</span> timeval tv_d<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d: &quot;</span><span style="color: #339933;">,</span> i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">6</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TEST<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// 输出结果</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;=</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d: %ld.%06ld<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> mtime<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">tv_sec</span><span style="color: #339933;">,</span> mtime<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">tv_usec</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>很久没写这种东西了……唉……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/optimize-leap-year-checking-and-other/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CHM 查看器</title>
		<link>http://blog.upsuper.org/chm-viewer/</link>
		<comments>http://blog.upsuper.org/chm-viewer/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 02:05:26 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[CHM]]></category>
		<category><![CDATA[SSD]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=829</guid>
		<description><![CDATA[说实话，本来 CHM 的查看器很早以前就不是个问题了，但由于不记得到底哪个才是最好用的（最没有乱码的），每次都要把知道的查看器一个一个试过去，于是今天我就想把它记下来，以后直接翻我自己的日志就可以了…… 目前为止试用的最好用的是：chmsee。 gnochm 在我的使用中，从索引打开显示正常，但一旦点内部链接跳转就出现乱码。至于网络上看到的 KDE 下的 kchmviewer 我就更无语了，只要是文件地址中有中文，点连接就不正常了，看来也是编码没做好。 另外，chmsee 在 ubuntu-tweak 的 PPA 列表上有，可以更新到更新的版本。更新的版本上面允许全屏，在我这个10寸的上网本上看的可爽了~当然，如果能把那个标签也去掉就更好了~ 此外，这个版本（还是这个软件？）会把 chm 解压到 ~/.chmsee/bookshelf 内。不过我心疼我的 SSD，于是就想把那个目录改到 tmpfs 的 /tmp 下，但却发现那个显示解压地址的框框是不让改的，只是给你看看逗你玩罢了……如果这是在 Windows 下，特别是在非 NTFS 文件系统下，这一切就只好作罢了。但 Linux 不同，我们有符号链接！ 1 2 rm -r ~/.chmsee/bookshelf ln -s /tmp ~/.chmsee/bookshelf 解决问题。 以后 chmsee 的临时文件就全部去 tmpfs 了，应该可以有一点效率提升吧？至少不会对我的 SSD 有影响……]]></description>
			<content:encoded><![CDATA[<p>说实话，本来 CHM 的查看器很早以前就不是个问题了，但由于不记得到底哪个才是最好用的（最没有乱码的），每次都要把知道的查看器一个一个试过去，于是今天我就想把它记下来，以后直接翻我自己的日志就可以了……</p>
<p>目前为止试用的最好用的是：chmsee。</p>
<p>gnochm 在我的使用中，从索引打开显示正常，但一旦点内部链接跳转就出现乱码。至于网络上看到的 KDE 下的 kchmviewer 我就更无语了，只要是文件地址中有中文，点连接就不正常了，看来也是编码没做好。</p>
<p>另外，chmsee 在 ubuntu-tweak 的 PPA 列表上有，可以更新到更新的版本。更新的版本上面允许全屏，在我这个10寸的上网本上看的可爽了~当然，如果能把那个标签也去掉就更好了~</p>
<p>此外，这个版本（还是这个软件？）会把 chm 解压到 ~/.chmsee/bookshelf 内。不过我心疼我的 SSD，于是就想把那个目录改到 tmpfs 的 /tmp 下，但却发现那个显示解压地址的框框是不让改的，只是给你看看逗你玩罢了……如果这是在 Windows 下，特别是在非 NTFS 文件系统下，这一切就只好作罢了。但 Linux 不同，我们有符号链接！</p>

<div class="wp_codebox"><table><tr id="p829162"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p829code162"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-r</span> ~<span style="color: #000000; font-weight: bold;">/</span>.chmsee<span style="color: #000000; font-weight: bold;">/</span>bookshelf
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>tmp ~<span style="color: #000000; font-weight: bold;">/</span>.chmsee<span style="color: #000000; font-weight: bold;">/</span>bookshelf</pre></td></tr></table></div>

<p>解决问题。</p>
<p>以后 chmsee 的临时文件就全部去 tmpfs 了，应该可以有一点效率提升吧？至少不会对我的 SSD 有影响……</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/chm-viewer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于桌面 Linux 分区的一点看法</title>
		<link>http://blog.upsuper.org/a-view-of-partition-in-linux-for-desktop/</link>
		<comments>http://blog.upsuper.org/a-view-of-partition-in-linux-for-desktop/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 14:05:52 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[分区]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=808</guid>
		<description><![CDATA[今天看了 LinuxToy 上推荐的《Arch Linux 安装指南》，看到其中关于分区的部分，我突然想写篇文章来讨论一下 Linux 中应该怎么分区、应该怎么选文件系统、应该怎么配置才会比较不错。 第一个问题是哪些东西单独分区比较好。我在 Ubuntu 的社区上看到的建议有很多种，比如最基本的把 /boot、/home 单独分出来的，也有把 /tmp、/var 或 /usr 也单独分出来的。不过根据我的观察以及设想来说，我觉得，而且我个人采用的是把 /boot、/tmp 及 /home 单独分区，为什么这样选择呢？ 首先是 /boot 区，由于装载的是启动器，一般来说比较建议单独分区，这样可以减小损坏导致完全不能启动的风险，而且由于单独分区，在磁盘上的区域较集中，对于启动效率也有一定改善吧~下面是 /tmp 区，这个区我觉得是一定要分出来的，因为这几乎是 Linux 里面操作最频繁的一个区了，各种杂七杂八的临时文件装在里面。最后是 /home 区，把这个区单独分有一个最重要的好处就是，每次重装不需要额外的备份操作，直接沿用原来的分区就可以了~此外，还有比较喜欢更多分区的人也可以考虑把 /var 也单独分出来，这个作为日志及某些服务的资料储存地的操作频繁度也是与根目录相当不同的。至于把 /usr 单独分出来，我觉得是毫无道理的……个人看法~最后，我们还有一个区，就是 swap 区，无论内存多大，都建议建一个 swap 区！ 接下来我们的问题是，每个分区该有多大？说实话，这并不是一个十分难办的问题，因为现在的 GParted 等软件能够很轻松安全的改变分区大小，如果设不好大不了花一点时间调整咯。不过还是要稍微讨论一下的。 /boot 区是一个对空间要求非常宽松的分区，一般来说可以根据自己硬盘的宽裕程度给他分 50MB-200MB 都是没什么问题的，就一堆启动文件嘛~至于 /tmp 区，据说如果要刻录 DVD，至少要给这个区留 4.2GB 以上的空间。我个人是没有 DVD 刻录机的，因此对这个不太了解，不过如果这样的话那以后刻蓝光难道要预留 25GB？我是留了 1GB 的空间，据观察利用率并不高，通常维持在 10% [...]]]></description>
			<content:encoded><![CDATA[<p>今天看了 LinuxToy 上推荐的《<a href="http://linuxtoy.org/archives/install-guide-for-arch-linux.html">Arch Linux 安装指南</a>》，看到其中关于分区的部分，我突然想写篇文章来讨论一下 Linux 中应该怎么分区、应该怎么选文件系统、应该怎么配置才会比较不错。<br />
<span id="more-808"></span><br />
第一个问题是哪些东西单独分区比较好。我在 Ubuntu 的社区上看到的建议有很多种，比如最基本的把 /boot、/home 单独分出来的，也有把 /tmp、/var 或 /usr 也单独分出来的。不过根据我的观察以及设想来说，我觉得，而且我个人采用的是把 /boot、/tmp 及 /home 单独分区，为什么这样选择呢？</p>
<p>首先是 /boot 区，由于装载的是启动器，一般来说比较建议单独分区，这样可以减小损坏导致完全不能启动的风险，而且由于单独分区，在磁盘上的区域较集中，对于启动效率也有一定改善吧~下面是 /tmp 区，这个区我觉得是一定要分出来的，因为这几乎是 Linux 里面操作最频繁的一个区了，各种杂七杂八的临时文件装在里面。最后是 /home 区，把这个区单独分有一个最重要的好处就是，每次重装不需要额外的备份操作，直接沿用原来的分区就可以了~此外，还有比较喜欢更多分区的人也可以考虑把 /var 也单独分出来，这个作为日志及某些服务的资料储存地的操作频繁度也是与根目录相当不同的。至于把 /usr 单独分出来，我觉得是毫无道理的……个人看法~最后，我们还有一个区，就是 swap 区，无论内存多大，都建议建一个 swap 区！</p>
<p>接下来我们的问题是，每个分区该有多大？说实话，这并不是一个十分难办的问题，因为现在的 GParted 等软件能够很轻松安全的改变分区大小，如果设不好大不了花一点时间调整咯。不过还是要稍微讨论一下的。</p>
<p>/boot 区是一个对空间要求非常宽松的分区，一般来说可以根据自己硬盘的宽裕程度给他分 50MB-200MB 都是没什么问题的，就一堆启动文件嘛~至于 /tmp 区，据说如果要刻录 DVD，至少要给这个区留 4.2GB 以上的空间。我个人是没有 DVD 刻录机的，因此对这个不太了解，不过如果这样的话那以后刻蓝光难道要预留 25GB？我是留了 1GB 的空间，据观察利用率并不高，通常维持在 10% 以下，但考虑到某些时候说不定会突然暴增，维持一定量给它总没什么坏处吧……然后是 swap 区，这个前人总结的很多了，这里转引一下，一般来说就是内存 1GB 以下的设为两倍内存，1GB 及以上的给个 1GB 就差不多了，当然，如果想要能够使用休眠这个功能，swap 区至少要和内存一样大，这个问题上就看个人喜好自己权衡咯。根目录依自己的情况给个 10GB、20GB 的应该是足够了，硬盘大得蛋疼的给个 50GB 我看一般来说也差不多了，我给了 20GB，安装各种软件，至今也只用了 55%。剩下的就是给 /home 目录了，各种资料尽存其中~至于部分人可能愿意分出来的 /var 区，刚刚查了一下我自己的情况，我估计要给个 1G-2G，特别是对于那些用 Debian 系却从来不清里安装包缓存的人，更要分大一点。</p>
<p>现在的问题就是，我们需要什么样的文件系统？现在主流的桌面级文件系统大概有这几个：ext3、ext4、reiserfs、jfs。其他的文件系统大体上不是淘汰过时就是支持不完善，或者难以使用。</p>
<p>这几个文件系统可谓各有千秋，首先说说 ext3，这是 Linux 中这几个文件系统经历最长时间考验的，因此应该说稳定性是很优秀的，重要的东西放在这里面自然比较安心一些，但为了能从 ext2 平稳升级，沿用了线性目录储存的方式，效率自然打了些折扣。而 ext4 刚刚进入稳定版不久，说实话，我对开源界的稳定版感觉相当不好，Ubuntu 9.04 正式版出来不到一周后我下载安装，就增加了数十个安全更新……而 ext4 亦在稳定不久后<a href="http://linuxtoy.org/archives/ext4-data-loss.html">爆出了丢失数据的 bug</a>。因此，对于 ext4 的稳定性我想还有待进一步的检验，我猜也正是这个原因 Ubuntu 9.04 最终没选择这个作为默认文件系统。但其效率确实是有提高的，我想作为一些不需要经常修改的东西存放的地方还是很好的。下面来看看 reiserfs，这是一个很优秀的文件系统，可惜作者被抓起来了……这个文件系统对于小文件的存取具有很大的优势，并且在许多测试中有不俗表现。最后是 jfs，这是一个企业级的文件系统，似乎是有很稳定的性能，不过总体性能似乎不强。</p>
<p>好了，分析完这些文件系统的特性，我们大概可以知道应该怎么做了。当然，swap 区一定要用 swap 文件系统是必然的了。我想先看看 /tmp 所在的区，我想这里面大多是小文件，而且存在时间不长，加之重启就可以消掉，对稳定性要求不高，但如果比较高效是不错的，因此我个人选择了 reiserfs。当然，有人内存够大直接把 /tmp 挂到内存里做个 tmpfs 对效率提高很有好处。然后是 /home 区，我想 ext3 作为一个成熟和稳定的文件系统，放在 /home 再合适不过了，而且 /home 区里面通常一个文件夹我们都不会存太多文件导致其效率严重下降。至于根目录，我想 ext4 和 reiserfs 应该都不是太差的选择，而 ext3 显得就不太优越了，因为根目录里面一个目录下有成百上千的文件是很常见的（如 /usr/bin、/usr/lib 之类的……），而且大多数文件是小文件，ext3 的效率实在堪忧。而相比之下，ext4 也对小文件的访问做了一些优化，而且默认开启了对树型数据结构的支持，使得其管理文件的效率也有一定的提高。至于 reiserfs 前面也说过了，显然在这里都是合适的~至于 /boot 区，我想不应该选 reiserfs 和 ext4 这样支持 extents 的文件系统，即使可以支持效率也高不了。其实我一直在想弄一个不需要载入 GRUB stage 1.5 的应该是最快的了~最后 /var 区我没有经验，就不说了……</p>
<p>最后是不是非常重要的一个问题，怎么排顺序？我们都知道在传统机械硬盘上，分区越靠前意味着寻道时间越短，也即速度越快，因此我们显然要将经常要的放前面，以提高整体效率。此外我们都知道另外一个事实，如果你的内存比较大，Linux 几乎是不使用 swap 区的。因此我一向很反对把 swap 区放在前面，取而代之我觉得应该把 /tmp 放在最前面，根目录放其次，我想内存大于 1G 的可以把 swap 扔到第三个，再大的直接扔最后一个都无所谓……这里我还基于另外一个猜想：减慢 swap 访问速度有助于在有程序异常占用内存的时候减缓其扩张进程，给我们留一点时间解决这些程序……当然，这个猜想不一定是对的哈~</p>
<p>好了，上面都是关于传统机械硬盘的，我也想谈谈固态硬盘的问题。我的上网本就是配了个 16GB SSD……</p>
<p>对于 SSD，显然应该把频繁写入的东西移走，我的基本方案就是：把 /tmp、/var/log、/var/tmp 这类文件夹直接移入内存挂载为 tmpfs，然后整个硬盘分成两个区：一个 swap，一个根目录。显然在这么小的盘里你想放什么东西几乎是不可能的，因此我挂了一个外部硬盘作为我主文件夹的一个子目录，就不把 /home 单独分出来了。而且此处使用了 ext4，因为据说 ext4 是为 SSD 优化过的。至于为什么还要给 swap，这个上面也解释过了，虽然看起来很矛盾 _-b 不过这也是没有办法的……</p>
<p>很久没写这么长的东西了……仅是小弟我的个人意见，肯定有许多不正确和不完善之处，还请各位高手多多指教。</p>
<p>参考：</p>
<ul>
<li><a href="http://www.linuxsir.org/main/?q=node/115">Linux 文件系统概述 | LinuxSir.Org</a></li>
<li><a href="http://www.ibm.com/developerworks/cn/linux/l-jfs/">Linux日志文件系统及性能分析</a></li>
<li><a href="http://wiki.debian.org.hk/w/Filesystems_supported_by_GNU/Linux">GNU/Linux 支援的檔案系統 &#8211; OSWikiHK</a></li>
<li><a href="http://en.wikipedia.org/wiki/Ext4">ext4 &#8211; Wikipedia, the free encyclopedia</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/a-view-of-partition-in-linux-for-desktop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>解决vim退出后终端乱码的问题</title>
		<link>http://blog.upsuper.org/solve-the-problem-of-terminal-becoming-messy-after-exit-vim/</link>
		<comments>http://blog.upsuper.org/solve-the-problem-of-terminal-becoming-messy-after-exit-vim/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 12:53:12 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=805</guid>
		<description><![CDATA[这个问题很早就有了，一直没解决，而且也不知道很多人所说的“reset”命令，每次都是关掉重开。最近几天因为编辑新首页的缘故，实在不满于这个问题，于是便想办法解决了，在这里写出来，给大家也给自己以后做个参考。 网上有很多诡异的做法，其中最诡异的莫过于在默认标题前后加上空格，而且很多人称这很有效，但我试了却没有用。找了半天，发现一个帖子有一个比较奇特的解决方法：vim编辑退出后提示符乱码解决 &#8211; LinuxSir.Org 其中提到了重设vim连接到的程序。我根据man手册里vim相关的命令给出下面几个命令： 1 2 3 4 sudo update-alternatives --config vim sudo update-alternatives --config vi sudo update-alternatives --config ex sudo update-alternatives --config view 每个命令中都选择“/usr/bin/vim.basic”，结果就可以了…… 看来是gvim的问题。当然，如果从来不用，直接 1 sudo apt-get remove vim-gnome 或许是最直接简便的方案~]]></description>
			<content:encoded><![CDATA[<p>这个问题很早就有了，一直没解决，而且也不知道很多人所说的“reset”命令，每次都是关掉重开。最近几天因为编辑新首页的缘故，实在不满于这个问题，于是便想办法解决了，在这里写出来，给大家也给自己以后做个参考。</p>
<p>网上有很多诡异的做法，其中最诡异的莫过于在默认标题前后加上空格，而且很多人称这很有效，但我试了却没有用。找了半天，发现一个帖子有一个比较奇特的解决方法：<a href="http://www.linuxsir.com/bbs/thread333819.html">vim编辑退出后提示符乱码解决 &#8211; LinuxSir.Org</a></p>
<p>其中提到了重设vim连接到的程序。我根据man手册里vim相关的命令给出下面几个命令：</p>

<div class="wp_codebox"><table><tr id="p805165"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p805code165"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> update-alternatives <span style="color: #660033;">--config</span> <span style="color: #c20cb9; font-weight: bold;">vim</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> update-alternatives <span style="color: #660033;">--config</span> <span style="color: #c20cb9; font-weight: bold;">vi</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> update-alternatives <span style="color: #660033;">--config</span> ex
<span style="color: #c20cb9; font-weight: bold;">sudo</span> update-alternatives <span style="color: #660033;">--config</span> view</pre></td></tr></table></div>

<p>每个命令中都选择“/usr/bin/vim.basic”，结果就可以了……</p>
<p>看来是gvim的问题。当然，如果从来不用，直接</p>

<div class="wp_codebox"><table><tr id="p805166"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p805code166"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> remove vim-gnome</pre></td></tr></table></div>

<p>或许是最直接简便的方案~</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/solve-the-problem-of-terminal-becoming-messy-after-exit-vim/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Linux 死机了该怎么办？</title>
		<link>http://blog.upsuper.org/what-to-do-if-linux-crash/</link>
		<comments>http://blog.upsuper.org/what-to-do-if-linux-crash/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 15:20:07 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[死机]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=788</guid>
		<description><![CDATA[Linux 会死机么？我可以很肯定地说，会！如何？很简单，我的上一篇日志就介绍了一种方法~要让 Linux 死机很容易，但难的是在死机以后如何安全的让他摆脱死机状态。 Linux 死机有很多种情况，最常见的是系统负载过高导致的。如上次介绍的 fork 炸弹就是这个原理，此外还可以运行内存耗用极大的程序（如虚拟机），也会迅速提升系统负载。由于系统负载过高导致的卡死，一定是解决的越快越好！此时必须记住的是，不能再试图依赖任何图形界面的东西，如 Gnome 的系统监视器（这是我从 Windows 遗留下来的愚昧习惯……），这只会继续加重这种卡死的局面。那怎么办？ 不要怕，Linux 最初就是不需要图形界面的，因为有一个很强大的文字界面。按 Ctrl-Alt-F1（F1-F6 一般来说都可以），然后等一会儿，就会切换到 tty，也就是所谓的文字界面。这个时候需要用用户名密码登入。注意，可能键盘输入的速度比较慢，不过应该还是可以忍受的。下面在提示符后面输入 top 回车，这时会看到一张动态的表，上面列出了耗用资源最多的进程。观察它刷新一两次，按q退出，然后输入 kill ，其中的 PID 你可以在 top 里面看到。这个时候应该会快了不少，如果你发现没有成功结束掉，就再输入 kill -KILL ，这次基本上就没问题了。 除了上面这种情况外，一些底层软件的 bug 也可能导致一些奇怪的死机问题。我某位同学近日就因为莫名其妙的死机强制重启把 ext4 的分区给伤了。（最后是 sysreccd 修复了，貌似是分区表部分损坏）据其说，死机是键鼠均无反应。一般来说，系统负载高导致的死机，在可怕键盘也会有反应，有人说如果死机到键盘无响应“负载都无限大了”，亦有人说这可能是 X Server 与驱动配合有问题导致的。不过我们考虑一下遇到这种情况怎么办？ OK，这是今天才学到的方法，叫做 reisub，这个方法可以在各种情况下安全地重启计算机。大家在键盘上找，可以找到一个叫做“Sys Rq”的键，在台机的键盘上通常与 Prt Sc 共键，在笔记本可能在其他位置，如 Delete。以台机为例，要使用这种方法需要按住 Alt-Print(Sys Rq)，然后依次按下 reisub 这几个键，按完 b 系统就会重启。 下面解释一下这个方法：其实 Sys Rq 是一种叫做系统请求的东西，按住 [...]]]></description>
			<content:encoded><![CDATA[<p>Linux 会死机么？我可以很肯定地说，会！如何？很简单，<a href="http://blog.upsuper.org/fork-bomb/">我的上一篇日志</a>就介绍了一种方法~要让 Linux 死机很容易，但难的是在死机以后如何安全的让他摆脱死机状态。</p>
<p>Linux 死机有很多种情况，最常见的是系统负载过高导致的。如上次介绍的 fork 炸弹就是这个原理，此外还可以运行内存耗用极大的程序（如虚拟机），也会迅速提升系统负载。由于系统负载过高导致的卡死，一定是解决的越快越好！此时必须记住的是，<strong>不能再试图依赖任何图形界面的东西</strong>，如 Gnome 的系统监视器（这是我从 Windows 遗留下来的愚昧习惯……），这只会继续加重这种卡死的局面。那怎么办？<br />
<span id="more-788"></span><br />
不要怕，Linux 最初就是不需要图形界面的，因为有一个很强大的文字界面。按 Ctrl-Alt-F1（F1-F6 一般来说都可以），然后等一会儿，就会切换到 tty，也就是所谓的文字界面。这个时候需要用用户名密码登入。注意，可能键盘输入的速度比较慢，不过应该还是可以忍受的。下面在提示符后面输入 top 回车，这时会看到一张动态的表，上面列出了耗用资源最多的进程。观察它刷新一两次，按q退出，然后输入 kill <PID>，其中的 PID 你可以在 top 里面看到。这个时候应该会快了不少，如果你发现没有成功结束掉，就再输入 kill -KILL <PID>，这次基本上就没问题了。</p>
<p>除了上面这种情况外，一些底层软件的 bug 也可能导致一些奇怪的死机问题。我某位同学近日就因为莫名其妙的死机强制重启把 ext4 的分区给伤了。（最后是 sysreccd 修复了，貌似是分区表部分损坏）据其说，死机是键鼠均无反应。一般来说，系统负载高导致的死机，在可怕键盘也会有反应，有人说如果死机到键盘无响应“负载都无限大了”，亦有人说这可能是 X Server 与驱动配合有问题导致的。不过我们考虑一下遇到这种情况怎么办？</p>
<p>OK，这是今天才学到的方法，叫做 reisub，这个方法可以在各种情况下安全地重启计算机。大家在键盘上找，可以找到一个叫做“Sys Rq”的键，在台机的键盘上通常与 Prt Sc 共键，在笔记本可能在其他位置，如 Delete。以台机为例，要使用这种方法需要<em>按住</em> Alt-Print(Sys Rq)，然后依次按下 reisub 这几个键，按完 b 系统就会重启。</p>
<p>下面解释一下这个方法：其实 Sys Rq 是一种叫做系统请求的东西，按住 Alt-Print 的时候就相当于按住了 Sys Rq 键，这个时候输入的一切都会直接由 Linux 内核来处理，它可以进行许多低级操作。这个时候 reisub 中的每一个字母都是一个独立操作，他们分别表示：</p>
<pre>
un<strong>R</strong>aw      将键盘控制从 X Server 那里抢回来
 t<strong>E</strong>rminate 给所有进程发送 SIGTERM 信号，让他们自己解决善后
 k<strong>I</strong>ll      给所有进程发送 SIGKILL 信号，强制他们马上关闭
  <strong>S</strong>ync     将所有数据同步至磁盘
  <strong>U</strong>nmount  将所有分区挂载为只读模式
re<strong>B</strong>oot     重启
</pre>
<p>这6个字母的顺序是不可以记错的。那怎么记呢？这里提供一个个人认为比较好的方法：单词 busier（busy 的比较级，更忙）倒过来就是了。</p>
<p>基本上就这样了，Linux 的死机本来就不多见，现在见了也可以安全解决，多好~</p>
<p>参考资料：<br />
<a href="http://en.wikipedia.org/wiki/Magic_SysRq_key">Magic SysRq key &#8211; Wikipedia, the free encyclopedia</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/what-to-do-if-linux-crash/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>探秘 Linux 权限控制</title>
		<link>http://blog.upsuper.org/explore-access-control-of-linux/</link>
		<comments>http://blog.upsuper.org/explore-access-control-of-linux/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 08:09:37 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[安全]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=778</guid>
		<description><![CDATA[众所周知，Linux 的权限控制虽然很简单，但却十分严格和有效的。（和 Windows 复杂却没用的权限控制形成鲜明对比……）由于最近编写测评机，希望利用 Linux 的高安全性做运行级恶意代码防护，因此就顺带地研究了一下 Linux 的权限控制。经过这次探秘，我对 Linux 的权限有了更新的认识，确实是一个很强大的东西啊！ 由于本人的能力有限，文章中的不足和谬误也请大家多多指教！ 我想，稍微接触过一段时间 Linux 的人都会对 Linux 的权限有些许了解，其中最重要的莫过于——很多命令需要加 sudo 才能运行，而且我们也知道，sudo 几乎无所不能——不能删的就 sudo rm、不能复制 sudo cp、不能移动 sudo mv……（目前我仅发现在部分虚拟文件系统中 sudo 也没有权限做这些事情……）那么，sudo 究竟是何方神圣，Linux 又是如何确定这些权限的呢？ 说到 Linux 下的权限，一定要先说的是 Linux 下文件权限的控制。在 Linux 下，每个文件都有“所有者”和“所在组”这两个基本属性，而各种权限也是根据所有者、所在组和其他人划分的。每个文件的权限，最简单的情况下可以表示为一个3位八进制数，每一位八进制数表示一系列人的权限，如八进制数751就标示所有者有7的权限，所在组的其他人有5的权限，而既不是所有者也不在所在组的人只有1的权限。至于一位的八进制数表示的意义，我们应该将其进一步转换为3位二进制数，如7对应111，5对应101，1对应001。在这个二进制数上最高位如果为1则表示有读权限，第二位表示写权限，而最后一位表示执行权限。（说到这里我就想再插一句了，Linux 的文件是什么类型或可不可以执行，几乎完全不是根据扩展名，只有有执行权限的文件才能执行，而文件类型也是根据 MIME Type 来决定的。） 由于 Linux 里面大量的东西都可以转化为文件操作，因此这一简洁明了的设计解决了大多数权限控制的问题。不过文件归文件，那文件夹呢？文件夹应该说也是一类特殊的文件，因此也有权限控制。可对于文件夹，什么样叫“可读”，什么样叫“可写”？最奇怪的是，“可执行”？对于文件夹来说，可读就是可以列举文件列表，也就是 Linux 下的 ls 命令可以列出东西；可写就是可以在文件夹中创建文件（或许有人会问，为什么不是文件夹中文件可写？想一想~）；可执行是比较奇怪的……就是将这个文件夹当作当前文件夹的权限，在 Linux 命令中表现为 cd 是否可以使用。 好了，说完文件们，再来看看进程们。 进程的权限控制就更简单了，说白了就一句话：一个进程不能控制与其不是同一个用户下运行的进程，除非被控制的是它的子进程。事实上，一个进程有至少两个 UID 和 [...]]]></description>
			<content:encoded><![CDATA[<p>众所周知，Linux 的权限控制虽然很简单，但却十分严格和有效的。（和 Windows 复杂却没用的权限控制形成鲜明对比……）由于最近编写测评机，希望利用 Linux 的高安全性做运行级恶意代码防护，因此就顺带地研究了一下 Linux 的权限控制。经过这次探秘，我对 Linux 的权限有了更新的认识，确实是一个很强大的东西啊！</p>
<p>由于本人的能力有限，文章中的不足和谬误也请大家多多指教！<br />
<span id="more-778"></span><br />
我想，稍微接触过一段时间 Linux 的人都会对 Linux 的权限有些许了解，其中最重要的莫过于——很多命令需要加 sudo 才能运行，而且我们也知道，sudo 几乎无所不能——不能删的就 sudo rm、不能复制 sudo cp、不能移动 sudo mv……（目前我仅发现在部分虚拟文件系统中 sudo 也没有权限做这些事情……）那么，sudo 究竟是何方神圣，Linux 又是如何确定这些权限的呢？</p>
<p>说到 Linux 下的权限，一定要先说的是 Linux 下文件权限的控制。在 Linux 下，每个文件都有“所有者”和“所在组”这两个基本属性，而各种权限也是根据所有者、所在组和其他人划分的。每个文件的权限，最简单的情况下可以表示为一个3位八进制数，每一位八进制数表示一系列人的权限，如八进制数751就标示所有者有7的权限，所在组的其他人有5的权限，而既不是所有者也不在所在组的人只有1的权限。至于一位的八进制数表示的意义，我们应该将其进一步转换为3位二进制数，如7对应111，5对应101，1对应001。在这个二进制数上最高位如果为1则表示有读权限，第二位表示写权限，而最后一位表示执行权限。（说到这里我就想再插一句了，Linux 的文件是什么类型或可不可以执行，几乎完全不是根据扩展名，只有有执行权限的文件才能执行，而文件类型也是根据 MIME Type 来决定的。）</p>
<p>由于 Linux 里面大量的东西都可以转化为文件操作，因此这一简洁明了的设计解决了大多数权限控制的问题。不过文件归文件，那文件夹呢？文件夹应该说也是一类特殊的文件，因此也有权限控制。可对于文件夹，什么样叫“可读”，什么样叫“可写”？最奇怪的是，“可执行”？对于文件夹来说，可读就是可以列举文件列表，也就是 Linux 下的 ls 命令可以列出东西；可写就是可以在文件夹中创建文件（或许有人会问，为什么不是文件夹中文件可写？想一想~）；可执行是比较奇怪的……就是将这个文件夹当作当前文件夹的权限，在 Linux 命令中表现为 cd 是否可以使用。</p>
<p>好了，说完文件们，再来看看进程们。</p>
<p>进程的权限控制就更简单了，说白了就一句话：一个进程不能控制与其不是同一个用户下运行的进程，除非被控制的是它的子进程。事实上，一个进程有至少两个 UID 和 GID，它们分别是 EUID、RUID 和 EGID、RGID，其中，E 表示 effective，即所有权限控制参考的是 EUID 和 EGID，进程创建的文件的所有者和所在组也是 EUID 和 EGID 表示的用户和组。那么有人就问，R- 的那两个又是拿来干什么的呢？打酱油？非也，R 表示 real，即运行者的信息。其实一个进程可以改变自己这些 UID 和 GID，而 E- 可以修改为的值为其本身和对应的 R- 的值。不过一个程序在加载的时候 E- 和 R- 的值似乎都根据运行者的信息设置了相同的值，看起来好像没什么用，是吗？我们这里暂且不管他。</p>
<p>下面我们深入一步，看看进程调度中的 nice 值和进程的资源限制。不知道大家有没有用系统监视器调整过进程的 nice 值，nice 值是 Linux 核心调度进程的一个参考值，nice 值越高表示这个进程越不重要，优先级越低，越可以慢慢来；nice 值越低表示这个进程越重要，越要快些做。调过 nice 的人就知道，将可以控制的某个进程的 nice 值调高（优先级降低）是随便做的，但要把一个进程的 nice 值调低（提高优先级）却要输入密码（进入 root）。做过一些 Linux 相关的编程的人也应该知道，调紧一个可控进程的资源限制是可以随意调的，但调宽松也要由 root 来进行。</p>
<p>啊，root 出现了！root 是什么？root 对于 Linux 来说就是神。为什么这么说？你上面看到的所有权限控制，在 root 面前都是没用的，root 在 Linux 里可以为所欲为。是的，root 是一个完全不受权限限制的用户，这就是它可怕的地方。比如，我们在前面看到进程只能将 EUID 调整为 EUID 或 RUID，但如果 EUID 为 0（即为 root），这个进程将可以把 EUID 和 RUID 调整为任意值；同样的，这个进程将可以把 EGID 和 RGID 调整为任意值。</p>
<p>我们知道 Linux 内核加载的时候开始执行的进程 init 是以 root 运行的，而后 init 加载各个启动脚本，把各项服务封入单独的用户运作，最后根据登入信息加载用户进程。这整个过程中，只有由上而下，由 root 到普通用户的过程。理由就是 root 可以任意调整 E- 和 R-。不过如果仅是这样，这个系统估计什么也干不了……</p>
<p>我在原来的<a href="http://blog.upsuper.org/summary-of-ujudger-base-0-1-programming/">一篇日志</a>中提到过 Linux 创建子进程和运行程序的方法——fork 和 exec* 函数：fork 运行成功返回两次，一次在生成的子进程中返回0，另一次在调用的父进程中返回子进程的 pid。此时，子进程迅速继承了父进程的所有权限、变量等等等等。（Linux 的子进程采用 copy-on-write 技术分享父进程的内存）而我们前面又知道，一个进程只能让自己从 root 到普通用户，优先级从高到低，资源限制从宽到严，就像水只能从高流向低一样。但，人是往高出走的，有时我们需要 root 的权限，问：路在何方？</p>
<p>就在这时候，sudo 出现了！sudo 在 Linux 中可为无人不知无人不晓。对于 sudo 来说，只要你这个用户在 sudoer 的列表中，输入你的密码就可以让你成为 root 了，或者你输入其他用户的密码可以让你使用其他用户。可是，我们前面刚刚说过，进程只能让自己从 root 变成普通用户，那这 sudo 又是哪冒出来的呢？</p>
<p>这又要回到文件权限设置了。其实，文件权限实际上有4位八进制数。我们原来说的是3位，那还有一位是什么呢？那一位对应的3个二进制位又是三个开关，分别标示 SUID、SGID 和粘着位。SUID 是什么？它表示 saved set-user-ID，设置了它的程序在运行时有了新的选择——程序所有者的权限！也就是说，EUID 的取值在 EUID、RUID 之外多了一个选择——SUID。事实上，有设置 SUID 的程序在执行时都会自动将 EUID 设置为 SUID，这时 EUID 和 RUID 就不再是同一个值了，我们前面又知道，只要 EUID 为0这个程序就无敌了。这个过程在 fork 中无法完成，我猜想是在 exec* 函数的调用过程中进行的。我们看到，sudo 这个程序的所有者是 root，而又有设置 SUID，这表示，我们一运行 sudo，它就以 root 在运行了！很神奇不是么？通过 SUID 这种特别的机制，原来许多不可能的事成为了可能。SGID 表示的含义亦是类似的；而至于粘着位表示这个文件对于任何人都可写，但只有所有者能删除。</p>
<p>到这里，我把 Linux 基本的权限控制机制都说了一番。当然，为了更精确地进行权限控制，Linux 内核还引入了 Linux 安全模块，并可以加入 SELinux 和 AppArmor 等增强的安全机制，这让 Linux 更加安全和坚不可摧。（Windows 的权限控制在这些面前简直就是幼稚园小孩在大学教授面前……）这些我就不细致展开了，更多的信息网上很容易找到。</p>
<p>参考资料：</p>
<ul>
<li><a href="http://linuxtoy.org/docs/guide/ch17s08.html">权限管理 &#8211; 开源世界旅行手册</a></li>
<li><a href="http://www.cndw.com/tech/server/2006040430540.asp">Solaris下究竟如何使用setuid/seteuid/setreuid</a></li>
<li><a href="http://lxr.linux.no/">the Linux Cross Reference</a></li>
<li><a href="http://tech.ccidnet.com/art/741/20090623/1806969_1.html">Linux系统进程的几个用户ID及其转换方法</a></li>
<li><a href="http://idcnews.net/html/edu/20070101/291393.html">用户信息 /etc/passwd，getuid(), getpwuid()</a></li>
<li><a href="http://hi.baidu.com/phps/blog/item/7e3ba44410cf9580b3b7dc81.html">C语言系统资源控制（getrlimit &#038;&#038; setrlimit)</a></li>
<li><a href="http://bytes.com/groups/python/36126-permission-problem-os-setuid">permission problem with os.setuid</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/explore-access-control-of-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>探索 Python 之 变量、类型和引用</title>
		<link>http://blog.upsuper.org/explore-python-variable-type-and-refrence/</link>
		<comments>http://blog.upsuper.org/explore-python-variable-type-and-refrence/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 14:23:15 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=775</guid>
		<description><![CDATA[我一开始为 Python 的强大和简洁所震撼，看了些 Python 的教程，学了不少东西。前面那些探索就以后再写吧……今天先讲讲今天知道的东西。 在探索到 Python 函数的参数传递的时候，我不禁赞叹 Python 灵活的参数设计，但慢慢的，开始迷惑与传递参数的修改和返回。 众所周知，在 C++ 中传递参数分为传值和传引用两种，但 Python 没有，那到底传进去的东西，修改一下，能不能传出来呢？这是一个很奇怪和让人费解的问题，不是么？在查阅了一些资料后，对 Python 关于变量、类型和引用的一些基本方式有了一些了解，进而基于这种理解并结合实验，了解了参数传递的奥妙。 Python 的变量是没有类型的，这与以往看到的大部分语言都不一样。但 Python 却是区分类型的，那类型在哪里呢？事实是，类型是跟着内存中的对象走的。Python 的所有变量其实都是指向内存中的对象的一个指针，所有的变量都是！此外，对象还分两类：一类是可修改的，一类是不可修改的。 现在，我插入在此先说说函数参数的问题，我们有下面一个实验： 1 2 3 4 5 6 7 8 def func1&#40;a&#41;: a += 1 def func2&#40;a&#41;: a&#91;0&#93; = 0 t1 = 0 func1&#40;t1&#41; print t1 t2 = &#91;1, 2, 3&#93; func2&#40;t2&#41; print t2 [...]]]></description>
			<content:encoded><![CDATA[<p>我一开始为 Python 的强大和简洁所震撼，看了些 Python 的教程，学了不少东西。前面那些探索就以后再写吧……今天先讲讲今天知道的东西。</p>
<p>在探索到 Python 函数的参数传递的时候，我不禁赞叹 Python 灵活的参数设计，但慢慢的，开始迷惑与传递参数的修改和返回。</p>
<p>众所周知，在 C++ 中传递参数分为传值和传引用两种，但 Python 没有，那到底传进去的东西，修改一下，能不能传出来呢？这是一个很奇怪和让人费解的问题，不是么？在查阅了一些资料后，对 Python 关于变量、类型和引用的一些基本方式有了一些了解，进而基于这种理解并结合实验，了解了参数传递的奥妙。<br />
<span id="more-775"></span><br />
Python 的变量是没有类型的，这与以往看到的大部分语言都不一样。但 Python 却是区分类型的，那类型在哪里呢？事实是，类型是跟着内存中的对象走的。Python 的所有变量其实都是指向内存中的对象的一个指针，所有的变量都是！此外，对象还分两类：一类是可修改的，一类是不可修改的。</p>
<p>现在，我插入在此先说说函数参数的问题，我们有下面一个实验：</p>

<div class="wp_codebox"><table><tr id="p775174"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p775code174"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> func1<span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span>: a += <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">def</span> func2<span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span>: a<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">0</span>
t1 = <span style="color: #ff4500;">0</span>
func1<span style="color: black;">&#40;</span>t1<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> t1
t2 = <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>
func2<span style="color: black;">&#40;</span>t2<span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> t2</pre></td></tr></table></div>

<p>结果是：</p>

<div class="wp_codebox"><table><tr id="p775175"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p775code175"><pre class="text" style="font-family:monospace;">0
[0, 2, 3]</pre></td></tr></table></div>

<p>看看结果会不会很惊异？第一个看起来像传值，第二个看起来却像传引用？看到这里你是不是觉得 Python 是一种莫名其妙的语言？其实当时我也有这种想法……但 Python 果然没哟让我失望，它如同 UNIX 一样，一开始设计得就如此优美。继续往下看~</p>
<p>不可修改的对象是我们最常用和最熟悉，几乎在任何一个语言中都能看到的——整数、实数、字符串和元组。有人说，怎么不可变啊？我随便给他们赋值！是的，在 Python 里几乎一切都是可以改变的，甚至有人说“如果你愿意，None 的值也是可以变的”（当然我不知道怎么变……）。但是如果注意观察，会发现所谓的改变其实是——<strong>扔了旧的建个新的！</strong>验证这个的实验很简单：</p>

<div class="wp_codebox"><table><tr id="p775176"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p775code176"><pre class="python" style="font-family:monospace;">a = <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span>
a += <span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">id</span><span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>类似的实验想怎么做怎么做，只要那两个是不可变对象，你就一定会发现 id 变了！为什么？因为对象不可变。那什么可变？变量的引用是可变的！</p>
<p>好，那么自然剩下的就是可变的对象了，上面的实验亦可以很容易的证实字典、列表、集合和类实例等对象是可变的。那么，这意味着什么呢？</p>
<p>下面，我们回到函数传值的问题。我们知道了可变对象和不可变对象的区别，不是吗？对于可变对象，对于对象的操作不会重建对象，而对于不可变对象，每一次操作就重建新的对象。那么函数参数到底是个什么东西呢？<strong>其实说白了也简单，就是把参数里传入的东西对相应对象的引用依次赋给对应的内部变量</strong>（有点晕吗？）。看看第一个实验，有没有明白些什么？其实都是将一个指向对象的引用传个一个名为“参数”的本地变量，所以 func1 中给 a 的是一个值为 0 的整数对象的引用，但我们知道，整数对象是不可变的，所以当 func1 对 a 进行修改的时候，实际上是修改本地变量 a 的引用到一个新的值为 1 的整数对象的引用。那么很显然，func2 修改的是一个可变的对象，也就是说即使 func2 修改了 a，本地变量 a 和全局变量 t2 指向的还是同一个对象，虽然他们不是同一个变量！这样一切情况都明了了，不是么？不明了的话再看看下面这个实验：</p>

<div class="wp_codebox"><table><tr id="p775177"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p775code177"><pre class="python" style="font-family:monospace;">a = <span style="color: black;">&#91;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">5</span>, <span style="color: #ff4500;">6</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
b = a<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
b<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">print</span> a</pre></td></tr></table></div>

<p>输出一定是：</p>

<div class="wp_codebox"><table><tr id="p775178"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p775code178"><pre class="text" style="font-family:monospace;">[[0, 2, 3], [4, 5, 6]]</pre></td></tr></table></div>

<p>其实原理和参数的传递是一致的。</p>
<p>我们下面来看看全局变量和本地变量的问题。如果一个函数里面使用了一个变量，那么 Python 会先看看有没有对应的本地变量，如果没有找到，但找到一个全局变量，那么 Python 会把<strong>那个全局变量的引用赋给一个新的本地变量</strong>。所以，现在在函数里的那个变量和全局变量其实不是同一个变量，他们只不过暂时有了相同的引用。这样其实可以看作 Python 为你做了隐式的参数传递。因此我们发现，他和参数一样，传值传引用表面上看过去漂移不定。那么如何修改一个指向不可变全局变量的值呢？靠返回值显然不那么优美。好在 Python 像 PHP 那样提供了一个叫 global 的语法，被 global 的变量使得<strong>本地变量成为相应全局变量的一个别名</strong>，也就是说这个语句使他们成为同一个变量，这一点很重要！</p>
<p>现在看到了 Python 优美的设计。那下面的问题是，如果我们一定要复制一个可变对象的副本怎么办？简单的等号赋值显然被证明无效了。Python 也提供了方法——copy 模块。copy 模块是每一个 Python 都有的，专门用于生成可变对象的副本。copy 模块中有两个函数：copy.copy 和 copy.deepcopy。其中 copy 叫做潜复制，它仅仅复制了第一你给它的东西，下面的不管了。而 deepcopy 叫做深复制，它将所有能复制的都复制了。这样说比较抽象，我们来看下面实验：</p>

<div class="wp_codebox"><table><tr id="p775179"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p775code179"><pre class="python" style="font-family:monospace;">a = <span style="color: black;">&#91;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span>, <span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span>, <span style="color: #ff4500;">5</span>, <span style="color: #ff4500;">6</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
b = a
c = <span style="color: #dc143c;">copy</span>.<span style="color: #dc143c;">copy</span><span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span>
d = <span style="color: #dc143c;">copy</span>.<span style="color: black;">deepcopy</span><span style="color: black;">&#40;</span>a<span style="color: black;">&#41;</span>
a.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">15</span><span style="color: black;">&#41;</span>
a<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">10</span>
<span style="color: #ff7700;font-weight:bold;">print</span> a
<span style="color: #ff7700;font-weight:bold;">print</span> b
<span style="color: #ff7700;font-weight:bold;">print</span> c
<span style="color: #ff7700;font-weight:bold;">print</span> d</pre></td></tr></table></div>

<p>输出结果：</p>

<div class="wp_codebox"><table><tr id="p775180"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p775code180"><pre class="text" style="font-family:monospace;">[[1, 2, 3], [4, 5, 10], 15]
[[1, 2, 3], [4, 5, 10], 15]
[[1, 2, 3], [4, 5, 10]]
[[1, 2, 3], [4, 5, 6]]</pre></td></tr></table></div>

<p>我想，效果不言而喻了。</p>
<p>此外，我还看到一个叫做弱引用 (weakref) 的模块，暂时不知道是干嘛的……下次研究了再说……</p>
<p>参考：</p>
<ul>
<li><a href="http://blog.csdn.net/winterTTr/archive/2008/06/27/2590741.aspx">Python的函数参数传递：传值？引用？</a></li>
<li><a href="http://www.jb51.net/article/15714.htm">Python 拷贝对象（深拷贝deepcopy与浅拷贝copy）</a></li>
<li><a href="http://www.cnblogs.com/sislcb/archive/2008/09/05/1284828.html">Python 学习笔记 &#8211; 8.引用(Reference)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/explore-python-variable-type-and-refrence/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ubuntu之旅（十一）——探索VIM</title>
		<link>http://blog.upsuper.org/ubuntu-trip-11-explore-vim/</link>
		<comments>http://blog.upsuper.org/ubuntu-trip-11-explore-vim/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 10:37:50 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=772</guid>
		<description><![CDATA[很久没写日志了，前段时间本来想写一个安装 CoreAVC for Linux 的，结果它未能成功拯救我的福音战士新剧场版1080P，于是就放下了…… 这次由于对 Scribes 测试版 bug 重重的不满和随时可能丢失修改的担忧，在看了一部分《开源世界旅行手册》后，毅然决定试一试传说中的 vim。 vim 在传说中是强大的，不过说起来也还是不那么容易入门的。查了很多关于 vim 配置和操作的文章。在操作方面，vim 自带的指导、开源世界旅行手册中的相关章节和 LinuxToy 上的《高效率编辑器 VIM》让我受益匪浅。vim 自带的指导只要在终端里输入 vimtutor 就可以了，一边看着指导一边操作，学得还是挺快的，只不过指导只有繁体中文，看了不大舒服，幸好还都看懂了…… 至于配置，也看了不少地方，现在的配置文件大概是这样的： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 filetype indent on set nocompatible set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936 syntax on colorscheme freya set [...]]]></description>
			<content:encoded><![CDATA[<p>很久没写日志了，前段时间本来想写一个安装 CoreAVC for Linux 的，结果它未能成功拯救我的福音战士新剧场版1080P，于是就放下了……</p>
<p>这次由于对 Scribes 测试版 bug 重重的不满和随时可能丢失修改的担忧，在看了一部分《<a href="http://linuxtoy.org/docs/guide/">开源世界旅行手册</a>》后，毅然决定试一试传说中的 vim。<br />
<span id="more-772"></span><br />
vim 在传说中是强大的，不过说起来也还是不那么容易入门的。查了很多关于 vim 配置和操作的文章。在操作方面，vim 自带的指导、开源世界旅行手册中的<a href="http://linuxtoy.org/docs/guide/ch24.html">相关章节</a>和 <a href="http://linuxtoy.org">LinuxToy</a> 上的《<a href="http://linuxtoy.org/archives/efficient-editing-with-vim.html">高效率编辑器 VIM</a>》让我受益匪浅。vim 自带的指导只要在终端里输入 vimtutor 就可以了，一边看着指导一边操作，学得还是挺快的，只不过指导只有繁体中文，看了不大舒服，幸好还都看懂了……</p>
<p>至于配置，也看了不少地方，现在的配置文件大概是这样的：</p>

<div class="wp_codebox"><table><tr id="p772182"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p772code182"><pre class="vim" style="font-family:monospace;"><span style="color: #804040;">filetype</span> <span style="color: #25BB4D;">indent</span> <span style="color: #25BB4D;">on</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">nocompatible</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">fileencodings</span>=utf<span style="color: #000000;">-</span><span style="color: #000000; font-weight:bold;">8</span>,ucs<span style="color: #000000;">-</span>bom,gb18030,gbk,gb2312,cp936
<span style="color: #804040;">syntax</span> <span style="color: #25BB4D;">on</span>
<span style="color: #804040;">colorscheme</span> freya
<span style="color: #804040;">set</span> <span style="color: #668080;">shortmess</span>=atI
<span style="color: #804040;">set</span> <span style="color: #668080;">autoindent</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">complete</span>=<span style="color: #000000;">.</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">smartindent</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">smarttab</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">expandtab</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">tabstop</span>=<span style="color: #000000; font-weight:bold;">2</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">softtabstop</span>=<span style="color: #000000; font-weight:bold;">2</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">shiftwidth</span>=<span style="color: #000000; font-weight:bold;">2</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">foldmethod</span>=<span style="color: #25BB4D;">indent</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">number</span>
<span style="color: #804040;">set</span> <span style="color: #668080;">ambiwidth</span>=double
&nbsp;
nmap <span style="color: #668080;">&lt;F2&gt;</span> <span style="color: #000000;">:</span>tabprevious<span style="color: #000000;">&lt;</span>CR<span style="color: #000000;">&gt;</span>
nmap <span style="color: #668080;">&lt;F3&gt;</span> <span style="color: #000000;">:</span>tabnext<span style="color: #000000;">&lt;</span>CR<span style="color: #000000;">&gt;</span></pre></td></tr></table></div>

<p>其实到处都有很多 vim 的配置文件，我现在这个还算很短的，而且很简陋的，估计还会不断增加，暂且放在这里做一个纪念吧，看看以后会到怎样的境界……</p>
<p>现在用 vim 慢慢适应了不用方向键的操作了，不过不知道到底是好是坏呢……只能慢慢适应咯</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/ubuntu-trip-11-explore-vim/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ubuntu 下安装 Blitz for PHP</title>
		<link>http://blog.upsuper.org/ubuntu-installed-blitz-for-php/</link>
		<comments>http://blog.upsuper.org/ubuntu-installed-blitz-for-php/#comments</comments>
		<pubDate>Fri, 22 May 2009 15:21:16 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=764</guid>
		<description><![CDATA[Blitz 是为 PHP 设计的一个高效模板系统，关于这个模板系统的高效程度和更多内容参见其英文主页。因为安装这个还是比较麻烦的，上次安装过这次又忘记了怎么做…… 非常无奈地，这个程序不仅没有进入 Ubuntu 的源，而且也没有看到编译好的 deb 包，所以首先，我先从 SourceForge 上下载了它的源代码。然后开始安装。 解压后，我一直以为源码包的默认安装方式：./configure &#8211; make &#8211; make install 错了！第一步就提示找不到 ./configure……看看 README，发现需要先执行一条命令叫做“phpize”。我在终端中输入 phpize，提示找不到命令，而且没有提示什么软件包中包含这个命令。在网上查到需要安装 php5-dev 包，于是就用 apt-get 安装了 php5-dev 包。再执行 phpize，发现目录里瞬间多出了许多文件。然后，执行 ./configure，make，make install。安装完成。 重启 apache2 查看 phpinfo，发现 blitz 没有出现！怎么会这样呢……突然看到 phpinfo 里面的“additional .ini files parsed”一栏里面都是形如“/etc/php5/apache2/conf.d/插件的名称.ini”，所以就找到 /etc/php5/apache2/conf.d/ 目录，查看了里面随便一个文件，发现其实格式很简单，就是 1 extension=插件名.so 于是就添加了一个文件“blitz.ini”，内容为 1 extension=blitz.so 保存。再次重启 apache2，查看 phpinfo，终于看到 blitz 了！]]></description>
			<content:encoded><![CDATA[<p>Blitz 是为 PHP 设计的一个高效模板系统，关于这个模板系统的高效程度和更多内容参见<a href="http://alexeyrybak.com/blitz/blitz_en.html">其英文主页</a>。因为安装这个还是比较麻烦的，上次安装过这次又忘记了怎么做……</p>
<p>非常无奈地，这个程序不仅没有进入 Ubuntu 的源，而且也没有看到编译好的 deb 包，所以首先，我先从 <a href="http://sourceforge.net/projects/blitz-templates/">SourceForge</a> 上下载了它的源代码。然后开始安装。<br />
<span id="more-764"></span><br />
解压后，我一直以为源码包的默认安装方式：./configure &#8211; make &#8211; make install 错了！第一步就提示找不到 ./configure……看看 README，发现需要先执行一条命令叫做“phpize”。我在终端中输入 phpize，提示找不到命令，而且没有提示什么软件包中包含这个命令。在<a href="http://ubuntuforums.org/showthread.php?t=354278">网上查到</a>需要安装 php5-dev 包，于是就用 apt-get 安装了 php5-dev 包。再执行 phpize，发现目录里瞬间多出了许多文件。然后，执行 ./configure，make，make install。安装完成。</p>
<p>重启 apache2 查看 phpinfo，发现 blitz 没有出现！怎么会这样呢……突然看到 phpinfo 里面的“additional .ini files parsed”一栏里面都是形如“/etc/php5/apache2/conf.d/插件的名称.ini”，所以就找到 /etc/php5/apache2/conf.d/ 目录，查看了里面随便一个文件，发现其实格式很简单，就是</p>

<div class="wp_codebox"><table><tr id="p764185"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p764code185"><pre class="text" style="font-family:monospace;">extension=插件名.so</pre></td></tr></table></div>

<p>于是就添加了一个文件“blitz.ini”，内容为</p>

<div class="wp_codebox"><table><tr id="p764186"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p764code186"><pre class="text" style="font-family:monospace;">extension=blitz.so</pre></td></tr></table></div>

<p>保存。再次重启 apache2，查看 phpinfo，终于看到 blitz 了！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/ubuntu-installed-blitz-for-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于 PHP 常数的定义和范围</title>
		<link>http://blog.upsuper.org/about-php-constants-definition-and-scope/</link>
		<comments>http://blog.upsuper.org/about-php-constants-definition-and-scope/#comments</comments>
		<pubDate>Sun, 17 May 2009 04:03:12 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[我的计划]]></category>
		<category><![CDATA[探究学习]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=760</guid>
		<description><![CDATA[PHP 的常数还是很有趣的。作为一个脚本语言，常数在 PHP 中成为了一种十分灵活的东西。没有细究 PHP 的文档，自己做了个实验来看看 PHP 到底时怎么处理常数的。实验代码如下： 1 2 3 4 5 6 7 8 function a&#40;$t&#41; &#123; define&#40;'T', $t&#41;; echo T; &#125; &#160; a&#40;'a'&#41;; echo T; a&#40;'b'&#41;; 结果发现，输出的三个字符都是 a，而且没有报错。这说明，无论常数在哪里声明，都是全局有效的，而且定义后不可再被更改了（废话……不然还叫常数）。从定义发生的时机看，确实是第一次调用函数 a() 的时候被定义的，而后再次调用函数 a() 时没有被修改也没有报错。还真是有趣的说~ 话说今天发现 PHP 的 link 函数的文档中写着“5.3.0 This function is now available on Windows platforms.”！十分好奇，Windows 下也有文件硬链接？载来 PHP 5.3.0 RC2（又一惊，5.3.0 已经到 RC2 了！）的代码，细细观赏一番，发现在 [...]]]></description>
			<content:encoded><![CDATA[<p>PHP 的常数还是很有趣的。作为一个脚本语言，常数在 PHP 中成为了一种十分灵活的东西。没有细究 PHP 的文档，自己做了个实验来看看 PHP 到底时怎么处理常数的。实验代码如下：</p>

<div class="wp_codebox"><table><tr id="p760189"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p760code189"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> a<span style="color: #009900;">&#40;</span><span style="color: #000088;">$t</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'T'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$t</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">echo</span> T<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
a<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> T<span style="color: #339933;">;</span>
a<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'b'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>结果发现，输出的三个字符都是 a，而且没有报错。这说明，无论常数在哪里声明，都是全局有效的，而且定义后不可再被更改了（废话……不然还叫常数）。从定义发生的时机看，确实是第一次调用函数 a() 的时候被定义的，而后再次调用函数 a() 时没有被修改也没有报错。还真是有趣的说~<br />
<span id="more-760"></span><br />
话说今天发现 PHP 的 link 函数的文档中写着“5.3.0  	 This function is now available on Windows platforms.”！十分好奇，Windows 下也有文件硬链接？载来 PHP 5.3.0 RC2（又一惊，5.3.0 已经到 RC2 了！）的代码，细细观赏一番，发现在 ext/standard 下有一个文件叫 link_win32.c，打开看到如下代码：</p>

<div class="wp_codebox"><table><tr id="p760190"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p760code190"><pre class="c" style="font-family:monospace;">PHP_FUNCTION<span style="color: #009900;">&#40;</span>link<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #808080; font-style: italic;">/* ... 此处省略数行 ... */</span>
<span style="color: #339933;">#ifndef ZTS</span>
	ret <span style="color: #339933;">=</span> CreateHardLinkA<span style="color: #009900;">&#40;</span>topath<span style="color: #339933;">,</span> frompath<span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">#else </span>
	ret <span style="color: #339933;">=</span> CreateHardLinkA<span style="color: #009900;">&#40;</span>dest_p<span style="color: #339933;">,</span> source_p<span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	
<span style="color: #339933;">#endif	</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ret <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		php_error_docref<span style="color: #009900;">&#40;</span>NULL TSRMLS_CC<span style="color: #339933;">,</span> E_WARNING<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;%s&quot;</span><span style="color: #339933;">,</span> strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		RETURN_FALSE<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	RETURN_TRUE<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>CreateHardLinkA 难道是一个 API 函数？再一查，发现 MSDN 上有文档：<a href="http://msdn.microsoft.com/en-us/library/aa363860(VS.85).aspx">CreateHardLink Function (Windows)</a>，上面还写着“Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only for files, not directories.”，只有 NTFS 才能用。看来只好认为是学 Linux 的了……竟然支持，真是不可思议，不过 Windows 为什么默认却没有办法在 GUI 中使用这个功能呢？</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/about-php-constants-definition-and-scope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>我的 lab2（一）——Windows 下的 Linux</title>
		<link>http://blog.upsuper.org/my-lab2-1-linux-under-windows/</link>
		<comments>http://blog.upsuper.org/my-lab2-1-linux-under-windows/#comments</comments>
		<pubDate>Thu, 14 May 2009 07:02:18 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[虚拟机]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=755</guid>
		<description><![CDATA[在开源界，总是有很多不可思议的东西，在没有虚拟化技术的机子中的 Windows 下跑 Linux 可以以 Native 的速度似乎很早就已经成功了。使用的是一个叫做 coLinux 的程序，它将整个 Linux 系统当做 Windows 的一个进程，其高得惊人的执行效率伴随着是相当小的资源占用。 前面其实用过 coLinux，当时使用了官方网站上提供的 Debian 镜像，可以直接使用。但这次由于某些原因，不得不使用 Ubuntu，于是就用前一段载的 DVD 安装了一个。虽然只装了基本系统，过程还是相当艰难的…… 对于没用过 coLinux 的，首先要到 SourceForge.net 上下载 coLinux-stable 和下面任意一个制作好的硬盘镜像。这些镜像除了预装系统不同外，其大小也不同，ArchLinux 的是 256MB，Debian 是 1GB，Ubuntu 是 2GB。如果空间充裕建议下 Ubuntu 版的吧，这样以后可以做的事情比较多~ 接下去安装什么的都很简单了，下载的 coLinux 安装程序按照过程安好，然后把刚才载的镜像解压到安装文件夹。你还可以在这里根据你想要的大小下载一个 Swap 的镜像，同样放到那个目录。 其实编辑一下 example.conf，把对应的文件名填上就可以打开了。不过这样不好玩，不是么？ 现在准备好 Ubuntu 9.04 DVD 的 ISO 镜像，新建一个文件叫做 ubuntu.conf，然后从 ISO 当中的 install 目录提取出 initrd.gz，备份安装文件夹中的同名文件备用。接下来新建一个文件叫做 [...]]]></description>
			<content:encoded><![CDATA[<p>在开源界，总是有很多不可思议的东西，在没有虚拟化技术的机子中的 Windows 下跑 Linux 可以以 Native 的速度似乎很早就已经成功了。使用的是一个叫做 coLinux 的程序，它将整个 Linux 系统当做 Windows 的一个进程，其高得惊人的执行效率伴随着是相当小的资源占用。<br />
<span id="more-755"></span><br />
前面其实用过 coLinux，当时使用了官方网站上提供的 Debian 镜像，可以直接使用。但这次由于某些原因，不得不使用 Ubuntu，于是就用前一段载的 DVD 安装了一个。虽然只装了基本系统，过程还是相当艰难的……</p>
<p>对于没用过 coLinux 的，首先要到 <a href="http://sourceforge.net/project/showfiles.php?group_id=98788">SourceForge.net</a> 上下载 coLinux-stable 和下面任意一个制作好的硬盘镜像。这些镜像除了预装系统不同外，其大小也不同，ArchLinux 的是 256MB，Debian 是 1GB，Ubuntu 是 2GB。如果空间充裕建议下 Ubuntu 版的吧，这样以后可以做的事情比较多~</p>
<p>接下去安装什么的都很简单了，下载的 coLinux 安装程序按照过程安好，然后把刚才载的镜像解压到安装文件夹。你还可以在<a href="http://gniarf.nerim.net/colinux/swap/">这里</a>根据你想要的大小下载一个 Swap 的镜像，同样放到那个目录。</p>
<p>其实编辑一下 example.conf，把对应的文件名填上就可以打开了。不过这样不好玩，不是么？</p>
<p>现在准备好 Ubuntu 9.04 DVD 的 ISO 镜像，新建一个文件叫做 ubuntu.conf，然后从 ISO 当中的 install 目录提取出 initrd.gz，备份安装文件夹中的同名文件备用。接下来新建一个文件叫做 ubuntu.conf，内容按照如下模版填写：</p>

<div class="wp_codebox"><table><tr id="p755200"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code" id="p755code200"><pre class="text" style="font-family:monospace;"># c:\coLinux 换成你的安装目录
kernel=&quot;c:\coLinux\vmlinux&quot;
# 这里写上你下载的镜像的文件名
cobd0=&quot;ubuntu.ext3.1gb&quot;
# 这是 swap 区的镜像的文件名，没有就可以不写了
cobd1=&quot;swap_256Mb&quot;
# 这个是 DVD 镜像的位置
cobd2=&quot;d:\share\ubuntu-9.04-dvd-i386.iso&quot;
# 以光盘启动
root=/dev/cobd2
ro
initrd=&quot;initrd.gz&quot;
#内存大小，单位 MB，如果内存大的可以适量加大，我这里总物理内存只有 256，所以才给这么些
mem=64
# 安装之前先不要启用网络，否则就后果自负了……
#eth0=pcap-bridge, &quot;colinux&quot;</pre></td></tr></table></div>

<p>接下去执行 colinux-daemon.exe @ubuntu.conf，进入安装。</p>
<p>由于 Ubuntu 的安装程序不能正确格式化磁盘，因此我们要先帮它格式化好。先点 Alt+F2 进入控制台，输入下面命令预格式化：</p>

<div class="wp_codebox"><table><tr id="p755201"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p755code201"><pre class="bash" style="font-family:monospace;">mke2fs <span style="color: #660033;">-j</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>cobd0
mkswap <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>cobd1</pre></td></tr></table></div>

<p>重启在此进入安装，此时根据提示安装即可。但有几个地方需要注意，一是可能遇到说找不到光驱，此时选择不加载外部驱动，手动指定，然后输入 /dev/cobd2 加载 DVD 镜像；问是否不加载内核模块而继续时选是；在划分磁盘时选择手动，将刚刚格式化过的 /dev/cobd0 选择使用为 ext3，保留数据挂载为 /。安装的时候最好什么额外的包都不要选，特别是 Desktop 那些，先安个基本系统就好了。最后，不要安装 grub 和 lilo，装了也会出错……所以就直接忽略就好了。</p>
<p>安装过程可能持续相当的时间，如果刚才不禁掉网络可能就跟囧了……</p>
<p>安装好以在 Monitor 菜单中选择 Power off 关机。编辑 ubuntu.conf，将 root=/dev/cobd2 修改为 root=/dev/cobd0，去掉 eth0=pcap-bridge, “colinux” 前的注释符，并把刚才备份的 initrd.gz 覆盖从 ISO 中提取出来的文件。在此执行 colinux-daemon.exe @ubuntu.conf，至此就进入了 Ubuntu 9.04。</p>
<p>登入，下面先设置更新源。我发现，如果设置了 DVD 作为更新源，绝大多数常用的软件包都不需要上网下载。现在我们知道，DVD 已经被在 /dev/cobd2 上了。现在，执行下面命令，添加 DVD 源：</p>

<div class="wp_codebox"><table><tr id="p755202"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p755code202"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mount</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>cobd2 <span style="color: #000000; font-weight: bold;">/</span>cdrom
<span style="color: #c20cb9; font-weight: bold;">sudo</span> apt-cdrom add</pre></td></tr></table></div>

<p>然后就 sudo apt-get update 一下就可以用了~</p>
<p>因为我个人习惯于是用 vim 而非 nano，因此我必经这步安装了个 vim，然后开始编辑网络。</p>

<div class="wp_codebox"><table><tr id="p755203"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p755code203"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">vim</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>network<span style="color: #000000; font-weight: bold;">/</span>interfaces</pre></td></tr></table></div>

<p>在其中写入相关的网络配置：</p>

<div class="wp_codebox"><table><tr id="p755204"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p755code204"><pre class="text" style="font-family:monospace;">auto eth0
iface eth0 inet static
	address IP地址
	netmask 255.255.255.0
	gateway 网关</pre></td></tr></table></div>

<p>由于我们选择了桥接模式，现在这个虚拟机和你的宿主机在网络上是平级的，因此可根据自己的网络配置设置。如果有需要设置 DNS 服务器的话，应该新建 /etc/resolv.conf，并按照下面格式添加 DNS 服务器：</p>

<div class="wp_codebox"><table><tr id="p755205"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p755code205"><pre class="text" style="font-family:monospace;">nameserver 218.85.157.99
nameserver 202.101.98.55</pre></td></tr></table></div>

<p>下面就运行下面的命令重开网络：</p>

<div class="wp_codebox"><table><tr id="p755206"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p755code206"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ifdown</span> eth0
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">ifup</span> eth0</pre></td></tr></table></div>

<p>就可以使用了。</p>
<p>安装东西的时刻来临了！</p>
<p>不过还有一个需要的东西，就是 Xming。有了这个，你就可以实现在 Windows 下无缝使用 Linux 的界面程序了！首先要在虚拟机中安装 xterm，并在 Windows 下从<a href="http://www.straightrunning.com/XmingNotes/">这个地方</a>下载 Xming 和 Xming-fonts 并安装。</p>
<p>完成 Xming 的安装后，进入其安装目录，编辑 X0.hosts 文件，在 localhost 下面再加一行你的虚拟机的 IP 地址，最后启动 Xming。</p>
<p>在 Linux 下，你必须在输入下面命令：</p>

<div class="wp_codebox"><table><tr id="p755207"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p755code207"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">DISPLAY</span>=IP地址:<span style="color: #000000;">0</span>
xterm <span style="color: #000000; font-weight: bold;">&amp;</span></pre></td></tr></table></div>

<p>其中 IP 地址为你宿主机的 IP 地址。这时你将看到一个白色背景的终端窗口，这说明你已经成功了！现在运行任何有界面的程序，就可以在 Windows 下看到看似原生环境的界面了。</p>
<p>当然，在疯狂的安装过程中，可能会发现空间变得越来越紧张，特别是像我这样一开始选用了 1GB 的镜像来安装 Ubuntu 的人……</p>
<p>要扩大镜像文件，首先需要一个叫做 mkFile.exe 的程序，因为似乎不好找，所以就自己预编译了一个，可以点击这里下载：<a href="http://down.upsuper.org/mkFile.rar">mkFile.rar</a> (326.57KB)</p>
<p>在关闭虚拟机的情况下，执行“mkFile.exe -r -g 你的镜像文件 2”就可以将镜像文件扩大到 2GB。重新开启虚拟机，在虚拟机中执行</p>

<div class="wp_codebox"><table><tr id="p755208"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p755code208"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> resize2fs <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>cobd0</pre></td></tr></table></div>

<p>稍等片刻就完成了。</p>
<p>下面是一张我在 coLinux 中编译安装并运行出 Scribes 的截图~其实我今天做这番事最根本的动机是为了在 Windows 下看看 Scribes 的……其实还是很完美的~虽然慢了一点……<br />
<a href="http://blog.upsuper.org/wp-content/uploads/2009/05/scribes_in_colinux.png"><img src="http://blog.upsuper.org/wp-content/uploads/2009/05/scribes_in_colinux-300x225.png" alt="scribes_in_colinux" title="scribes_in_colinux" width="300" height="225" class="alignnone size-medium wp-image-757" /></a></p>
<hr />
<p>参考：<a href="http://blog.csdn.net/jnstone3/archive/2008/10/02/3010040.aspx">CoLinux入门教程</a>、<a href="http://sheng.javaeye.com/blog/360766">在coLinux上安装Ubuntu8.04</a>、<a href="http://blog.frosty-geek.net/2009/04/ext3-online-resize-with-ubuntu-810.html">ext3 online resize with Ubuntu 8.10 Intrepid</a>、<a href="http://www.oklinux.cn/html/Basic/jyjq/20081011/62040.html">将Ubuntu DVD做软件源</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/my-lab2-1-linux-under-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>体验 Ubuntu 9.04 之配置</title>
		<link>http://blog.upsuper.org/ubuntu-904-experience-configuration/</link>
		<comments>http://blog.upsuper.org/ubuntu-904-experience-configuration/#comments</comments>
		<pubDate>Sat, 02 May 2009 15:22:58 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[输入法]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=724</guid>
		<description><![CDATA[Ubuntu 安装完要让他好用，最重要的莫过于配置了，要把 Ubuntu 配置成一个好用的系统虽说不难，不过也并不简单。 开机的第一个感觉，就是 9.04 的启动速度确实有一定提升，而且整个系统的效率感觉也相当不错，不过这个应该很大程度是由于新装系统东西少的缘故吧……不知道像原来的系统用那么久以后能不能保持。 照例是用 apt。先按照 Ubuntu 中文 Wiki 上的 9.04 的源列表配置好源。我照例选择了网易、LUPA 和台湾的源。配置完本想安装那些软件的，可 Ubuntu 自己先开始了升级大业，一大列的升级列表，足以说明 Ubuntu 9.04 发布之仓储，短短一周就有如此多的更新，不知道下面还要有多少更新。而且近一段时间，各个源的速度都不快，估计是由于新版本刚发布，各个源压力都很大的缘故，连网易这样原来可以上 MB/s 级的源也只有每秒 50kB 这样。不过最可怕的还是我使用了 ibus 在 PPA 上的源升级！那个 ibus-pinyin 下了我几个小时，在此期间完全不能打中文（没想去用 scim……），幸好 Google 对拼音的识别还是相当不错的，找资料没有遇到太大的困难，同时在这个过程中还断断续续安装了不少其他软件。 由于怕麻烦，这次没有安装 blubuntu，因为发现安装 blubuntu 要卸掉好多东西……接下来，按照很多地方的指示，在 /etc/sysctl.conf 文件最后添加一行 vm.swappiness = 5 以进一步减小交换区的使用频率。 这里推荐一个很好的文本编辑器——scribes，我强烈推荐用这个软件代替 gedit。它不仅有代码高亮、缩进这些 gedit 的功能，而且还有智能的代码补全和完善的模板系统。不过要用这个东西还有点麻烦，和 geany 一样的，如果已经打开了一个 scribes，如果再双击用 scribes 开一个文件，窗口列表里就会出现“打开 ***”，即使已经打开了也要很长时间才会消掉，最讨厌的是鼠标也会变成忙碌。这个解决的办法就是编辑 /usr/share/applications/scribes.desktop [...]]]></description>
			<content:encoded><![CDATA[<p>Ubuntu 安装完要让他好用，最重要的莫过于配置了，要把 Ubuntu 配置成一个好用的系统虽说不难，不过也并不简单。</p>
<p>开机的第一个感觉，就是 9.04 的启动速度确实有一定提升，而且整个系统的效率感觉也相当不错，不过这个应该很大程度是由于新装系统东西少的缘故吧……不知道像原来的系统用那么久以后能不能保持。<br />
<span id="more-724"></span><br />
照例是用 apt。先按照 <a href="http://wiki.ubuntu.org.cn/">Ubuntu 中文 Wiki</a> 上的 <a href="http://wiki.ubuntu.org.cn/index.php?title=Template:9.04source">9.04 的源列表</a>配置好源。我照例选择了网易、LUPA 和台湾的源。配置完本想安装那些软件的，可 Ubuntu 自己先开始了升级大业，一大列的升级列表，足以说明 Ubuntu 9.04 发布之仓储，短短一周就有如此多的更新，不知道下面还要有多少更新。而且近一段时间，各个源的速度都不快，估计是由于新版本刚发布，各个源压力都很大的缘故，连网易这样原来可以上 MB/s 级的源也只有每秒 50kB 这样。不过最可怕的还是我使用了 ibus 在 PPA 上的源升级！那个 ibus-pinyin 下了我几个小时，在此期间完全不能打中文（没想去用 scim……），幸好 Google 对拼音的识别还是相当不错的，找资料没有遇到太大的困难，同时在这个过程中还断断续续安装了不少其他软件。</p>
<p>由于怕麻烦，这次没有安装 blubuntu，因为发现安装 blubuntu 要卸掉好多东西……接下来，按照很多地方的指示，在 /etc/sysctl.conf 文件最后添加一行 vm.swappiness = 5 以进一步减小交换区的使用频率。</p>
<p>这里推荐一个很好的文本编辑器——scribes，我强烈推荐用这个软件代替 gedit。它不仅有代码高亮、缩进这些 gedit 的功能，而且还有智能的代码补全和完善的模板系统。不过要用这个东西还有点麻烦，和 geany 一样的，如果已经打开了一个 scribes，如果再双击用 scribes 开一个文件，窗口列表里就会出现“打开 ***”，即使已经打开了也要很长时间才会消掉，最讨厌的是鼠标也会变成忙碌。这个解决的办法就是编辑 /usr/share/applications/scribes.desktop 文件，将 StartupNotify=true 改成 StartupNotify=false 保存，就可以了。这样就可以设定它在所有文本类型的文件上代替 gedit 了~</p>
<p>接下去又是 smplayer，这个是功能十分强大的播放器前端，远比 Ubuntu 自带的 totem 强多了，我建议直接把 totem 全部卸掉就行了，然后安装 smplayer，这样各个影像格式就不会自动用 totem 了。还有，推荐用 Deluge 代替 Ubuntu 自带的 Transmission 作为 BT 客户端。</p>
<p><strong>请不要尝试下面内容，可能造成无法关机！</strong></p>
<p><del datetime="2009-05-13T11:23:29+00:00">然后又配置了 zhcon。原来在 8.10 的时候不知什么缘故，zhcon 十分异常，但这次配置却十分成功。我参考了<a href="http://chenjihua.javaeye.com/blog/240014">Ubuntu下配置tty全过程</a>，首先在 /etc/initramfs-tools/modules 文件末尾添加了三行：</p>

<div class="wp_codebox"><table><tr id="p724213"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p724code213"><pre class="text" style="font-family:monospace;">fbcon
vesafb
vga16fb</pre></td></tr></table></div>

<p>接下来注释掉了 /etc/modprobe.d/blacklist-framebuffer 文件中的</p>

<div class="wp_codebox"><table><tr id="p724214"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p724code214"><pre class="text" style="font-family:monospace;"># blacklist vesafb
# blacklist vga16fb</pre></td></tr></table></div>

<p>接下来，在 bash 中执行</p>

<div class="wp_codebox"><table><tr id="p724215"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p724code215"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> update-initramfs <span style="color: #660033;">-u</span></pre></td></tr></table></div>

<p>跟新自动加载的模块。</p>
<p>最后在 ~/.bashrc 最后一行添加</p>

<div class="wp_codebox"><table><tr id="p724216"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p724code216"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span>tty<span style="color: #7a0874; font-weight: bold;">&#41;</span> == \<span style="color: #000000; font-weight: bold;">/</span>dev\<span style="color: #000000; font-weight: bold;">/</span>tty<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span>-<span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">*</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> zhcon</pre></td></tr></table></div>

<p>以在 tty 中自动启动。</p>
<p>关于 tty 分辨率的问题，我还没有做更多实验，有了结果再来这里更新。</del></p>
<p>这个时候突然发现输入法不能用了……不管我怎么按 Ctrl+Space 都调不出我的 ibus，换成 scim 也不行，试了好久，注销、重启了几次也没有解决。因为当时 zhcon 已经配置好了，我在 tty1 下写下“这是怎样的一种觉悟&#8230;”……在图形界面输入不了中文在文字界面却可以……最后想到可能是语言支持没有安装完全，就在 系统/系统管理/语言支持 里面取消了“使用输入法引擎”又再次选中，果然提示安装一个包！安装完注销、重新进入，就可以输入了。</p>
<p>剩下的部分 Ubuntu 中文 Wiki 上的<a href="http://wiki.ubuntu.org.cn/index.php?title=Qref/Jaunty">速配指南</a>和<a href="http://wiki.ubuntu.org.cn/index.php?title=Qref/More">热门设置</a>还是相当完善的，我的很多软件还是按照这两个里面提供的参考配置的。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/ubuntu-904-experience-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>体验 Ubuntu 9.04 之安装</title>
		<link>http://blog.upsuper.org/ubuntu-904-experience-installation/</link>
		<comments>http://blog.upsuper.org/ubuntu-904-experience-installation/#comments</comments>
		<pubDate>Fri, 01 May 2009 15:42:34 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=722</guid>
		<description><![CDATA[虽然 Ubuntu 9.04 在4月23日就出来了，而且当天我就用 BT 下载了 9.04 的 x86 desktop 的 iso，不过我还是没有去装的。主要是考虑到上次安装 8.10 的时候诡异的不能关机的 bug，说明 Ubuntu 的新版本总是问题多多的。虽然说这个不好，不过事实是这样，说句实话，我觉得 Ubuntu 的一个正式版大概相当于 Windows 的一个 RC 什么的，而 LTS 还比较像样一点。算起来，其实时间也差不多…… 闲话不说了，还是说说我的 Ubuntu 9.04 吧。 前几天用 eMule 下载了 Ubuntu 9.04 的 DVD，信息中心的老师很大方的给了我一张 DVD+R 的盘并提供刻录机。说实话，这是我第一次刻录 DVD，在 Windows 下用 Nero 刻录的，刻录过程相当顺利，比我第一次刻 CDR 还顺利，几分钟就好了。我很早就在校内上的状态说5月再装 9.04。不过显然我是那种耐不住性子的人，不过一言既出驷马难追，所以还是等到今天——5月的第一天，就迫不及待的安装了。 昨晚花了很长时间把主目录下的资料备份到新买的移动硬盘里。我这次完全重装的很大原因也是因为第一次装不懂，结果就分了一个区挂载在根文件夹，这是非常不好的，也因此我不得不找一个移动硬盘来备份。高达 7GB 多的资料拷了近两个小时！昨晚关机的时候，我就在想：这个系统见不到明天的太阳了。 第二天一开机，就把 DVD 盘塞进去，开始了 Ubuntu 9.04 之旅。按照我的习惯，我都会选择体验而不安装，然后进入图形界面慢慢安装，顺便上上网查查资料什么的。一点就看到当年那个熟悉的提示，原来仍然没有解决 [...]]]></description>
			<content:encoded><![CDATA[<p>虽然 Ubuntu 9.04 在4月23日就出来了，而且当天我就用 BT 下载了 9.04 的 x86 desktop 的 iso，不过我还是没有去装的。主要是考虑到上次安装 8.10 的时候诡异的不能关机的 bug，说明 Ubuntu 的新版本总是问题多多的。虽然说这个不好，不过事实是这样，说句实话，我觉得 Ubuntu 的一个正式版大概相当于 Windows 的一个 RC 什么的，而 LTS 还比较像样一点。算起来，其实时间也差不多……</p>
<p>闲话不说了，还是说说我的 Ubuntu 9.04 吧。</p>
<p>前几天用 eMule 下载了 Ubuntu 9.04 的 DVD，信息中心的老师很大方的给了我一张 DVD+R 的盘并提供刻录机。说实话，这是我第一次刻录 DVD，在 Windows 下用 Nero 刻录的，刻录过程相当顺利，比我第一次刻 CDR 还顺利，几分钟就好了。我很早就在校内上的状态说5月再装 9.04。不过显然我是那种耐不住性子的人，不过一言既出驷马难追，所以还是等到今天——5月的第一天，就迫不及待的安装了。</p>
<p>昨晚花了很长时间把主目录下的资料备份到新买的移动硬盘里。我这次完全重装的很大原因也是因为第一次装不懂，结果就分了一个区挂载在根文件夹，这是非常不好的，也因此我不得不找一个移动硬盘来备份。高达 7GB 多的资料拷了近两个小时！昨晚关机的时候，我就在想：这个系统见不到明天的太阳了。<br />
<span id="more-722"></span><br />
第二天一开机，就把 DVD 盘塞进去，开始了 Ubuntu 9.04 之旅。按照我的习惯，我都会选择体验而不安装，然后进入图形界面慢慢安装，顺便上上网查查资料什么的。一点就看到<a href="http://blog.upsuper.org/ubuntu-trip-3-fully-into-the-ubuntu/">当年那个熟悉的提示</a>，原来仍然没有解决 noapic 的问题啊……重新启动，在光盘引导的第一个页面按下 F6 修改启动选项，突然发现变成菜单式的了！选中里面的 noapic 就可以正常启动了，除了速度慢一点，其他还是很正常的。光盘嘛，还是可以理解的。关于这个菜单式的启动选项，我觉得非常不错，不过我觉得能够无障碍自动识别要有什么选项就更好了。</p>
<p>进入光盘引导的系统，觉得背景相当漂亮。我点“系统/系统管理/系统测试中”对系统兼容性进行了一次测试，发现适应得相当好，Compiz 的特效也自动开到正常水平，效率相当 OK。这次奇怪的是，安装不在桌面上！？我很惊奇，不过最后还是在系统管理当中看到了，于是我开始了安装。当安到一半，突然系统黑屏，完全没反应了！我不知道是怎么回事，只得重启。这次选择了安装。进入图形安装界面，运行到一半又出了奇奇怪怪的问题。无奈最后选择了文字界面安装。</p>
<p>这是我第一次用文字界面安装系统。一步一步按着提示，看到了许多从未见过的选项，如是否加密主文件夹，是否安装grub2等等……好复杂……害得我一边安装一边用另一台机子查到底那些是什么意思……第一次安装是失败的，原因是没有断网……<strong>在中国这种网络环境下用文字界面安装一定要断网，不然就等着安装 Ubuntu 的时候停在那里吧。</strong>我觉得，Ubuntu 依赖网络，本来不是件坏事，但在一个宽带网络还不够发达的地方过度依赖网络，必然成为后退。第二次安装断了网，一直到进入了一个软件包选择的界面，我把光标移动到 Ubuntu Desktop，然后不小心按下回车，框框消失，开始安装。我就想，不会给我安装了一个空系统吧？结果安装完，还真是个空系统，连图形界面都没有……直接再次重新安装。</p>
<p>这次更奇怪了，速度奇慢无比。实在等不下去了，觉得不对劲，把光盘拿出来，用眼睛布擦了擦，觉得盘很烫，就放在旁边凉。过了一会儿等光盘凉下来了，再次放回光驱，这次一切正常，终于安装完成了。</p>
<p>现在说说我的分区。我这次用了自以为相当完美的分区模式，5分区的方式，第一个分区 200MB，ext3 格式，这是出于稳定的需要，即使系统完全 broken 了，至少还有个启动器（_-b，如果系统真 broken 了，要个启动器干什么……），第二个分区 20GB，ext4 挂载根文件夹，因为据说 ext4 的效率好过 ext3，并可以加快启动速度，放在根文件夹这种地方最好了。下面是挂载 /tmp 的分区，2GB，reiserfs，因为我感觉在 Linux 下 tmp 其实比 Swap 更经常访问，就把它放在了前面，而且 tmp 是不需要太好的稳定性，不需要保存资料，但对小文件一类的处理需要比较好的效率，因此选择了 reiserfs。然后就是 swap 区了，1GB（和我的内存一样大，这样我还可以启用休眠）。最后剩下的所有空间全部给了 /home，还是 ext3，这种地方，稳定胜过一切啊。</p>
<p>再说说前面遇到的那些奇怪的选项，加密主文件夹，我看还是算了。虽然说我开始是觉得怕如果系统坏了就再也解不开那个密了，不过更重要的是我看到了 <a href="http://www.phoronix.com/scan.php?page=article&#038;item=ubuntu_jaunty_encrypt&#038;num=1">Phoronix 上的一份性能测试</a>，虽然前面几页的结果都表明性能损失不大，但看到<a href="http://www.phoronix.com/scan.php?page=article&#038;item=ubuntu_jaunty_encrypt&#038;num=4">第四页的数据</a>，发现差异极其明显，最终打消了我使用的念头，更况且 Ubuntu 默认也是不选择的。至于 grub2，安装程序自己都提示了还是试验性的，当然直接不敢安装了。平时使用的系统，当然还是稳定一些比较好，不要整天出奇怪的问题……</p>
<p>今天先写这么多了……总体上说，今天对 Ubuntu 9.04 安装程序的稳定性有一些失望，不过安完感觉还是不错的，这个就留到明天写啦~</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/ubuntu-904-experience-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

