<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2chinesetwfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>将之典藏</title>
	
	<link>http://xiaobin.net</link>
	<description>一个社交恐惧症患者（俗称：宅男）的互联网从业生活</description>
	<lastBuildDate>Fri, 29 Jan 2010 08:01:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/zh_cn" /><feedburner:info uri="zh_cn" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license><meta xmlns="http://pipes.yahoo.com" name="pipes" content="noprocess" /><feedburner:emailServiceId>zh_cn</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fzh_cn" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>选好图，会对意</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/b2e9mv2ms70/</link>
		<comments>http://xiaobin.net/201001/choosing-a-good-chart/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 03:24:46 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://xiaobin.net/?p=255</guid>
		<description><![CDATA[关于沟通，一幅好图总是能胜过千言万语：

相关的一本书：《用图表说话》

选好图，会对意 &#124; 暂无评论，添加评论
本文网址：http://xiaobin.net/201001/choosing-a-good-chart/
将之典藏 - 厚积而薄发，© 2005-2010. 如无特别声明，适用署名-非商业性使用-相同方式共享 3.0授权，你可以署名使用全部或者部分内容用于非商业性目的。]]></description>
			<content:encoded><![CDATA[<p>关于沟通，一幅好图总是能胜过千言万语：</p>
<div id="attachment_258" class="wp-caption aligncenter" style="width: 708px"><a href="http://big5.cc/i/xbin/2010/01/chart-filter.jpg"><img class="size-full wp-image-258" title="选择正确的图表" src="http://big5.cc/i/xbin/2010/01/chart-filter.jpg" alt="" width="698" height="515" /></a><p class="wp-caption-text">(From: http://extremepresentation.typepad.com/blog/2006/09/choosing_a_good.html)</p></div>
<p style="text-align: center;">
<p style="text-align: left;">相关的一本书：《<a href="http://www.douban.com/subject/3137159/" target="_blank">用图表说话</a>》</p>
<hr />
<p><strong><a href="http://xiaobin.net/201001/choosing-a-good-chart/">选好图，会对意</a></strong> | 暂无评论，<a href="http://xiaobin.net/201001/choosing-a-good-chart/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/201001/choosing-a-good-chart/">http://xiaobin.net/201001/choosing-a-good-chart/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2010. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/b2e9mv2ms70" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/201001/choosing-a-good-chart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/201001/choosing-a-good-chart/</feedburner:origLink></item>
		<item>
		<title>使用trash代替rm</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/Nu-eWJ-sG5w/</link>
		<comments>http://xiaobin.net/200912/replace-rm-command-with-trash/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 09:15:20 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://xiaobin.net/?p=220</guid>
		<description><![CDATA[在/usr/bin/目录创建一个trash文件：
#! /bin/sh

DATE=`date +%Y%m%d`
TRASH="$HOME/.trash"

# Make sure the dest directionry is exists.
if [ ! -d $TRASH ]; then
    mkdir $TRASH
    if [ ! -z $SUDO_USER ]; then
        chown $SUDO_USER $TRASH
        chgrp $SUDO_GID $TRASH
    fi
fi

if [...]]]></description>
			<content:encoded><![CDATA[<p>在/usr/bin/目录创建一个trash文件：</p>
<pre>#! /bin/sh

DATE=`date +%Y%m%d`
TRASH="$HOME/.trash"

# Make sure the dest directionry is exists.
if [ ! -d $TRASH ]; then
    mkdir $TRASH
    if [ ! -z $SUDO_USER ]; then
        chown $SUDO_USER $TRASH
        chgrp $SUDO_GID $TRASH
    fi
fi

if [ ! -d $TRASH/$DATE ]; then
    mkdir $TRASH/$DATE
    if [ ! -z $SUDO_USER ]; then
        chown $SUDO_USER $TRASH/$DATE
        chgrp $SUDO_GID $TRASH/$DATE
    fi
fi

while [ $# -gt 0 ]
do
    if [ `expr substr $1 1 1` = "-" ]; then
        if [ $1 = "--" ]; then
            sift
            break
        fi
        shift
    else
        break
    fi
done
mv $* $TRASH/$DATE</pre>
<hr />
<p><strong><a href="http://xiaobin.net/200912/replace-rm-command-with-trash/">使用trash代替rm</a></strong> | 暂无评论，<a href="http://xiaobin.net/200912/replace-rm-command-with-trash/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200912/replace-rm-command-with-trash/">http://xiaobin.net/200912/replace-rm-command-with-trash/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/Nu-eWJ-sG5w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200912/replace-rm-command-with-trash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200912/replace-rm-command-with-trash/</feedburner:origLink></item>
		<item>
		<title>iptables应用实例</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/H3IAQojmyKY/</link>
		<comments>http://xiaobin.net/200912/iptables-example/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 09:23:12 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[iptables]]></category>

		<guid isPermaLink="false">http://xiaobin.net/?p=160</guid>
		<description><![CDATA[本机端口转发
将本机80端口的请求转发到8080端口：
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
如果需要本机也可以访问，则需要配置OUTPUT链：
iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
原因：外网访问需要经过PREROUTING链，但是localhost不经过该链，因此需要用OUTPUT，或者POSTROUTING。
以上规则可以通过 iptables -t nat -F PREROUTING(或者是OUTPUT)清除
两机之间的端口转发
将本机的81端口的请求全部转发到192.168.1.1:80
首先要启用ipv4的转发功能：
echo 1 &#62; /proc/sys/net/ipv4/ip_forward
或者是修改/etc/sysctl.conf (via)以便重启后也会启用转发，然后设定iptables(via)：
iptables -t nat -A PREROUTING -p tcp --dport 81 -j DNAT --to 192.168.1.1:80
iptables -t nat -A POSTROUTING -j MASQUERADE
如果开启了防火墙功能，注意要将80和81两个端口都打开。
禁止Ping入
允许内网(192.168.1.*)的ping入，允许ping出，禁止其它网段的ping入
iptables -A [...]]]></description>
			<content:encoded><![CDATA[<h3>本机端口转发</h3>
<p>将本机80端口的请求转发到8080端口：</p>
<pre>iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080</pre>
<p><span id="more-160"></span>如果需要本机也可以访问，则需要配置OUTPUT链：</p>
<pre>iptables -t nat -A OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080</pre>
<p>原因：外网访问需要经过PREROUTING链，但是localhost不经过该链，因此需要用OUTPUT，或者POSTROUTING。</p>
<p>以上规则可以通过 iptables -t nat -F PREROUTING<em><span style="color: #c0c0c0;">(或者是OUTPUT)</span></em>清除</p>
<h3>两机之间的端口转发</h3>
<p>将本机的81端口的请求全部转发到192.168.1.1:80</p>
<p>首先要启用ipv4的转发功能：</p>
<pre>echo 1 &gt; /proc/sys/net/ipv4/ip_forward</pre>
<p>或者是修改/etc/sysctl.conf (<a href="http://www.ducea.com/2006/08/01/how-to-enable-ip-forwarding-in-linux/" target="_blank">via</a>)以便重启后也会启用转发，然后设定iptables(<a href="http://serverfault.com/questions/27221/iptables-port-forwarding-on-debian" target="_blank">via</a>)：</p>
<pre>iptables -t nat -A PREROUTING -p tcp --dport <span style="color: #ff0000;">81</span> -j DNAT --to <span style="color: #ff0000;">192.168.1.1:80</span>
iptables -t nat -A POSTROUTING -j MASQUERADE</pre>
<p>如果开启了防火墙功能，注意要将80和81两个端口都打开。</p>
<h3>禁止Ping入</h3>
<p>允许内网(192.168.1.*)的ping入，允许ping出，禁止其它网段的ping入</p>
<pre>iptables -A INPUT -p icmp --icmp-type 8 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 8 -j DROP</pre>
<hr />
<p><strong><a href="http://xiaobin.net/200912/iptables-example/">iptables应用实例</a></strong> | 暂无评论，<a href="http://xiaobin.net/200912/iptables-example/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200912/iptables-example/">http://xiaobin.net/200912/iptables-example/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/H3IAQojmyKY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200912/iptables-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200912/iptables-example/</feedburner:origLink></item>
		<item>
		<title>关于Unix静态库和动态库的分析</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/PE5nctOpCLQ/</link>
		<comments>http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 07:09:43 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://xiaobin.net/?p=189</guid>
		<description><![CDATA[基本概念
库有动态与静态两种，动态通常用.so为后缀，静态用.a为后缀。 例如：libhello.so libhello.a
为了在同一系统中使用不同版本的库，可以在库文件名后加上版本号为后缀,例如： libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库，通常使用建立符号连接的方式。
ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so

1、使用库
当要使用静态的程序库时，连接器会找出程序所需的函数，然后将它们拷贝到执行文件，由于这种拷贝是完整的，所以一旦连接成功，静态程序库也就不再需要了。 然而，对动态库而言，就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时，首先必须载入这个库。由于动态库节省空间，linux下进行连接的 缺省操作是首先连接动态库，也就是说，如果同时存在静态和动态库，不特别指定的话，将与动态库相连接。
现在假设有一个叫hello的程序开发包，它提供一个静态库libhello.a 一个动态库libhello.so,一个头文件hello.h,头文件中提供sayhello()这个函数
/* hello.h */
void sayhello();
另外还有一些说明文档。
这一个典型的程序开发包结构 与动态库连接 linux默认的就是与动态库连接，下面这段程序testlib.c使用hello库中的sayhello()函数
/*testlib.c*/
#include "hello.h"
int main()
{
    sayhello();
    return 0;
}
使用如下命令进行编译
$gcc -c testlib.c -o testlib.o
用如下命令连接：
$gcc testlib.o -lhello -o testlib
连接时要注意，假设libhello.so 和libhello.a都在缺省的库搜索路径下/usr/lib下，如果在其它位置要加上-L参数。与静态库连接麻烦一些，主要是参数问题。还是上面的例 子：
$gcc testlib.o -o testlib -WI,-Bstatic -lhello
注：这个特别的&#8221;-WI,-Bstatic&#8221;参数，实际上是传给了连接器ld. 指示它与静态库连接，如果系统中只有静态库当然就不需要这个参数了。如果要和多个库相连接，而每个库的连接方式不一样，比如上面的程序既要和 libhello进行静态连接，又要和libbye进行动态连接，其命令应为：
$gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye
2、动态库的路径问题
为了让执行程序顺利找到动态库，有三种方法：

 把库拷贝到/usr/lib和/lib目录下。
在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库 libhello.so在/home/ting/lib目录下，以bash为例，使用命令： [...]]]></description>
			<content:encoded><![CDATA[<h3>基本概念</h3>
<p>库有动态与静态两种，动态通常用.so为后缀，静态用.a为后缀。 例如：libhello.so libhello.a</p>
<p>为了在同一系统中使用不同版本的库，可以在库文件名后加上版本号为后缀,例如： libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库，通常使用建立符号连接的方式。</p>
<pre>ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so</pre>
<p><span id="more-189"></span></p>
<h3>1、使用库</h3>
<p>当要使用静态的程序库时，连接器会找出程序所需的函数，然后将它们拷贝到执行文件，由于这种拷贝是完整的，所以<strong>一旦连接成功，静态程序库也就不再需要了</strong>。 然而，对动态库而言，就不是这样。<strong>动态库会在执行程序内留下一个标记指明当程序执行时，首先必须载入这个库</strong>。由于动态库节省空间，linux下进行连接的 缺省操作是首先连接动态库，也就是说，如果同时存在静态和动态库，不特别指定的话，将与动态库相连接。</p>
<p>现在假设有一个叫hello的程序开发包，它提供一个静态库libhello.a 一个动态库libhello.so,一个头文件hello.h,头文件中提供sayhello()这个函数</p>
<pre>/* hello.h */
void sayhello();</pre>
<p>另外还有一些说明文档。</p>
<p>这一个典型的程序开发包结构 与动态库连接 linux默认的就是与动态库连接，下面这段程序testlib.c使用hello库中的sayhello()函数</p>
<pre>/*testlib.c*/
#include "hello.h"
int main()
{
    sayhello();
    return 0;
}</pre>
<p>使用如下命令进行编译</p>
<pre>$gcc -c testlib.c -o testlib.o</pre>
<p>用如下命令连接：</p>
<pre>$gcc testlib.o -lhello -o testlib</pre>
<p>连接时要注意，假设libhello.so 和libhello.a都在缺省的库搜索路径下/usr/lib下，如果在其它位置要加上-L参数。与静态库连接麻烦一些，主要是参数问题。还是上面的例 子：</p>
<pre>$gcc testlib.o -o testlib -WI,-Bstatic -lhello</pre>
<p>注：这个特别的&#8221;-WI,-Bstatic&#8221;参数，实际上是传给了连接器ld. 指示它与静态库连接，如果系统中只有静态库当然就不需要这个参数了。如果要和多个库相连接，而每个库的连接方式不一样，比如上面的程序既要和 libhello进行静态连接，又要和libbye进行动态连接，其命令应为：</p>
<pre>$gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye</pre>
<h3>2、动态库的路径问题</h3>
<p>为了让执行程序顺利找到动态库，有三种方法：</p>
<ol>
<li> 把库拷贝到/usr/lib和/lib目录下。</li>
<li>在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库 libhello.so在/home/ting/lib目录下，以bash为例，使用命令： $export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib</li>
<li>修改/etc/ld.so.conf文件，把库所在的路径加到文件末尾，并执行ldconfig刷新。这样，加入的目录下的所有库文件都可见。</li>
</ol>
<p><strong>3、查看库中的符号</strong></p>
<p>有时候可能需要查看一个库中到底有哪些函数，nm工具可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多， 常见的有三种，一种是在库中被调用，但并没有在库中定义(表明需要其他库支持)，用U表示；一种是库中定义的函数，用T表示，这是最常见的；另外一种是所 谓的“弱态”符号，它们虽然在库中被定义，但是可能被其他库中的同名符号覆盖，用W表示。例如，假设开发者希望知道上文提到的hello库中是否引用了 printf():</p>
<pre>$nm libhello.so | grep printf U</pre>
<p>其中printf U表示符号printf被引用，但是并没有在函数内定义，由此可以推断，要正常使用hello库，必须有其它库支持，再使用ldd工具查看hello依赖于哪些库：</p>
<pre>$ldd hello
libc.so.6=&gt;/lib/libc.so.6(0x400la000)
/lib/ld-linux.so.2=&gt;/lib/ld-linux.so.2 (0x40000000)</pre>
<p>从上面的结果可以继续查看printf最终在哪里被定义，有兴趣可以go on</p>
<h3>4、生成库</h3>
<p>第一步要把源代码编绎成目标代码。以下面的代码为例，生成上面用到的hello库：</p>
<pre>/* hello.c */
#include "hello.h"
void sayhello()
{
    printf("hello,world ");
}</pre>
<p>用gcc编绎该文件，在编绎时可以使用任何合法的编绎参数，例如-g加入调试代码等：</p>
<pre>$gcc -c hello.c -o hello.o</pre>
<p>1.连接成静态库 连接成静态库使用ar工具，其实ar是archive的意思</p>
<pre>$ar cqs libhello.a hello.o</pre>
<p>2.连接成动态库 生成动态库用gcc来完成，由于可能存在多个版本，因此通常指定版本号：</p>
<pre>$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o</pre>
<p>另外再建立两个符号连接：</p>
<pre>$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so</pre>
<p>这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。 -Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上，每一个库都有一个soname，当连接器发现它正 在查找的程序库中有这样一个名称，连接器便会将soname嵌入连结中的二进制文件内，而不是它正在运行的实际文件名，在程序执行期间，程序会查找拥有 soname名字的文件，而不是库的文件名，换句话说，soname是库的区分标志。这样做的目的主要是允许系统中多个版本的库文件共存，习惯上在命名库 文件的时候通常与soname相同 libxxxx.so.major.minor 其中，xxxx是库的名字，major是主版本号，minor 是次版本号</p>
<h3>总结</h3>
<p>通过对LINUX库工作的分析，我们已经可以理解程序运行时如何去别的地方寻找“库”。</p>
<p>附上针对这个工程的Makefile:</p>
<pre># <a href="mailto:xiejingquan@gmail.com">xiejingquan@gmail.com</a>
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/C/lib

BIN_DIR=bin
LIB_DIR=lib
INC_DIR=inc
SRC_DIR=src

BIN=${BIN_DIR}/testlib
LIB=${LIB_DIR}/libhello.a ${LIB_DIR}/libhello.so

CC=gcc
AR=ar
DOC=doxygen

CFLAGS=-g -Wall -c -Iinc
LFLAGS=-lhello -L${LIB_DIR} -o
ARFLAGS=cqs
SOFLAGS=-shared -Wl,-soname,

all: ${BIN}

lib: ${LIB}

run: all
@./bin/testlib

clean:
rm -f ${BIN_DIR}/* ${LIB_DIR}/*

${BIN_DIR}/testlib: ${LIB_DIR}/testlib.o ${LIB}
${CC} $&lt; ${LFLAGS} $@

${LIB_DIR}/testlib.o: ${SRC_DIR}/testlib.c ${INC_DIR}/hello.h
${CC} ${CFLAGS} $&lt; -o $@

${LIB_DIR}/libhello.a: ${LIB_DIR}/hello.o
${AR} ${ARFLAGS} $@ $&lt;

${LIB_DIR}/libhello.so: ${LIB_DIR}/hello.o
${CC} ${SOFLAGS}libhello.so.1 -o ${LIB_DIR}/libhello.so.1.0 ${LIB_DIR}/hello.o
ln -s ${LIB_DIR}/libhello.so.1.0 ${LIB_DIR}/libhello.so.1
ln -s ${LIB_DIR}/libhello.so.1 ${LIB_DIR}/libhello.so

${LIB_DIR}/hello.o: ${SRC_DIR}/hello.c ${INC_DIR}/hello.h
${CC} ${CFLAGS} $&lt; -o $@</pre>
<p>附上文件的目录结构：</p>
<blockquote><p>|&#8211; bin<br />
|    `&#8211; testlib<br />
|&#8211; doc<br />
|&#8211; inc<br />
|    `&#8211; hello.h<br />
|&#8211; lib<br />
|    |&#8211; hello.o<br />
|    |&#8211; libhello.a<br />
|    |&#8211; libhello.so -&gt; lib/libhello.so.1<br />
|    |&#8211; libhello.so.1 -&gt; lib/libhello.so.1.0<br />
|    |&#8211; libhello.so.1.0<br />
|    `&#8211; testlib.o<br />
|&#8211; src<br />
|    |&#8211; hello.c<br />
|    `&#8211; testlib.c</p></blockquote>
<hr />说来也巧了，今天刚好在twitter上看到某大牛的推：</p>
<blockquote><p>Linux下动态链接库的查找顺序：①DT_RPATH、②LD_LIBRARY_PATH环境变量、③/etc/ld.so.conf文件及/etc/ld.so.cond.d/目录内的*.conf文件、④默认路径/usr/lib，如果改动了/etc/ld.so.conf 需要使用 <span style="font-size: x-small;">/sbin/ldconfig –v 来更新系统。<br />
</span></p></blockquote>
<hr />延伸阅读：</p>
<ol>
<li><a title="linux动态链接库的使用" href="http://student.csdn.net/space.php?uid=106412&amp;do=blog&amp;id=14788" target="_blank">linux动态链接库的使用</a>;</li>
<li><a title="linux 下链接库的生成使用" href="http://student.csdn.net/space.php?uid=106412&amp;do=blog&amp;id=14792" target="_blank">linux 下链接库的生成使用</a>;</li>
</ol>
<hr />
<p><strong><a href="http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/">关于Unix静态库和动态库的分析</a></strong> | 暂无评论，<a href="http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/">http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/PE5nctOpCLQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200911/analytics-on-unix-static-and-dynamic-library/</feedburner:origLink></item>
		<item>
		<title>tar: Removing leading `/’ from member names</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/xZrnCjHVnnA/</link>
		<comments>http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 11:23:43 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://xiaobin.net/?p=183</guid>
		<description><![CDATA[首先应该明确：*nix系统中，使用tar对文件打包时，一般不建议使用绝对路径。
通常是在两台环境相似的机器上进行同步复制的时候，才有需要使用绝对路径进行打包。使用绝对路径打包时如果不指定相应的参数，tar会产生一句警告信息：&#8221;tar: Removing leading `/&#8217; from member names&#8221;，并且实际产生的压缩包会将绝对路径转化为相对路径。
比如：
root@queen ~ # tar -czvf robin.tar.gz /home/robin
tar: Removing leading `/' from member names
/home/robin/
/home/robin/file1
/home/robin/file2
/home/robin/file3
root@queen ~ # tar -tzvf robin.tar.gz
drwxr-xr-x robin/root        0 2009-11-10 18:51:31 home/robin/
-rw-r--r-- robin/root        0 2009-11-10 18:51:28 home/robin/file1
-rw-r--r-- robin/root       [...]]]></description>
			<content:encoded><![CDATA[<p>首先应该明确：*nix系统中，使用tar对文件打包时，一般不建议使用绝对路径。</p>
<p>通常是在两台环境相似的机器上进行同步复制的时候，才有需要使用绝对路径进行打包。使用绝对路径打包时如果不指定相应的参数，tar会产生一句警告信息：&#8221;tar: Removing leading `/&#8217; from member names&#8221;，并且实际产生的压缩包会将绝对路径转化为相对路径。<span id="more-183"></span></p>
<p>比如：</p>
<pre>root@queen ~ # tar -czvf robin.tar.gz <span style="color: #ff0000;">/home/robin</span>
tar: Removing leading `/' from member names
/home/robin/
/home/robin/file1
/home/robin/file2
/home/robin/file3
root@queen ~ # tar -tzvf robin.tar.gz
drwxr-xr-x robin/root        0 2009-11-10 18:51:31 <span style="color: #ff0000;">home/robin/</span>
-rw-r--r-- robin/root        0 2009-11-10 18:51:28 home/robin/file1
-rw-r--r-- robin/root        0 2009-11-10 18:51:30 home/robin/file2
-rw-r--r-- robin/root        0 2009-11-10 18:51:31 home/robin/file3
root@queen ~ #</pre>
<p>这样的一个压缩包，如果我们再去解开，就会当前目录（也即此例中的“~”）下再新建出“./home/robin/” 两级目录。对于这样的压缩包，解压方法是使用参数 “-C”指解压的目录为根目录（“/”）：tar -xzvf robin.tar.gz -C /</p>
<p>更为可靠的方法是在打包和解开的时候都使用参数 <span style="color: #ff0000;">-P</span>：</p>
<pre>root@queen ~ # tar -czv<span style="color: #ff0000;"><strong>P</strong></span>f robin.tar.gz /home/robin/
/home/robin/
/home/robin/file1
/home/robin/file2
/home/robin/file3
root@queen ~ # tar tzvf robin.tar.gz
drwxr-xr-x robin/root        0 2009-11-10 18:51:31 /home/robin/
-rw-r--r-- robin/root        0 2009-11-10 18:51:28 /home/robin/file1
-rw-r--r-- robin/root        0 2009-11-10 18:51:30 /home/robin/file2
-rw-r--r-- robin/root        0 2009-11-10 18:51:31 /home/robin/file3
root@queen ~ # tar -xzv<span style="color: #ff0000;"><strong>P</strong></span>f robin.tar.gz
/home/robin/
/home/robin/file1
/home/robin/file2
/home/robin/file3
root@queen ~ #</pre>
<hr />
<p><strong><a href="http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/">tar: Removing leading `/&#8217; from member names</a></strong> | 暂无评论，<a href="http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/">http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/xZrnCjHVnnA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200911/tar-removing-leading-slash-from-member-name/</feedburner:origLink></item>
		<item>
		<title>CSS sprites两三事</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/EqKMrVjtuiE/</link>
		<comments>http://xiaobin.net/200909/something-about-css-sprites/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 16:28:33 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[前端]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://xiaobin.net/?p=96</guid>
		<description><![CDATA[首先，先介绍一款CSS sprites工具：SpriteMe(http://spriteme.org/)，这是由《High Performance Websites》的作者史蒂夫·桑德斯(Steve Souders)，开发的一款CSS Sprites产生工具。
SpriteMe的安装十分之简单，只要把这个链接拖动到你的浏览器收藏夹就可以：SpriteMe &#8211; 当然你也可以马上点击一下试用一下。
与其它的一些CSS Sprites工具不一样，SpriteMe具有下面几特性：

自动查找背景：SpriteMe有一个独门秘笈，可以容易的在页面内找出所使用的背景图片，同时会列出这些背景图片和使用它们的DOM元素。而不必像其它CSS sprites工具那样一个一个提交你的背景图。
将背景图片按分组来产生CSS sprites：想用好CSS sprites，其实它背后的逻辑还是挺复杂的：比如横向重复的背景图不能跟纵向重复的背景放在同一张CSS sprites云云，有很多规矩，不过现在有了SpriteMe就可以忘记这些复杂的逻辑了，SpriteMe会自动将那些能放在一张CSS sprites的背景图放在一组，每一组最终产生一张CSS sprites背景图。
会自动计算CSS的background-position。
可以将产生的代码应用到当前页面：以前测试CSS sprites通常要把背景图保存，然后改CSS，然后再通过浏览器看效果。SpriteMe就不需要这样，当你点击“make sprites”的时候，代码立刻就应用到当前页面，让你逃离那些无趣的流程。

Steve大概是最早提出通过CSS sprites来提升网页性能的人，在使用CSS sprites方面经验丰富。基于这一点，有理由相信他所带来的工具也是经过了深思熟虑，同时也是久经考验，可以满足绝大多数开发者的需要。
以上都是废话，SpriteMe很简单，谁用谁知道！
另外，SpriteMe是开源的：http://code.google.com/p/spriteme/，你也可以去下载源代码建立自己的镜像。
然后，转载一偏关于CSS sprites的技巧（来自：http://blog.tugai.net/2009/03/31/css-spriting-tips，原文：http://blog.mozilla.com/webdev/2009/03/27/css-spriting-tips/）：
提高网页显示速度最有效的一个方法是减少页面的HTTP请求次数，为了减少HTTP请求次数，最直接有效的方法是使用精灵图片（CSS sprites），精灵图片是把许多图片放到一张大图片里面，通过CSS来显示图片的一部分。
下面是一张精灵图片


本文的目的不是阐述精灵图片如何让网页下载更快，而是介绍在创建精灵图片时的一些实战经验。
不要等你完成所有工作后再开始使用CSS精灵
在网站全部完成后，你的CSS和图片也都已经创建好了，这时候你再使用CSS精灵，也就意味着你要返回重写CSS，并且还要把用到的一大堆图片再丢到Photoshop里拼合成一张图片，这是非常痛苦和乏味的。如果在刚开始构建页面时就着手使用CSS精灵，那么一切都会变得简单。
按图片显示相反的方向放置图片
这一条有点难以理解，我是在创建一张大的精灵图片中途失败后才意识到它的。假如一张图片应该出现在一个元素的左边，如下图

请将这张图片放在精灵的右边（看上面的示例精灵图片）。用这种方式处理后，当你用CSS移动背景图片时，不可能会有别的图片会（错误的）显示处理。
避免在CSS使用bottom或right定位
当定位CSS精灵中靠后的图片时，使用类似background-position: bottom -300px; 或者 background-position: right -200px;的方式定位非常容易。最初，这一切都能正常工作，但是，一旦你的CSS精灵宽度或高度增加时，你刚才使用的定位方式就发现了错误，因为图片相对右边或者底边的距离已经发生了变化。所以，请使用left和top来定位。
为每张图片留出足够空隙
正如你所看到文章中提供的例子精灵图片一样，许多小图片间都预留了很多空白。为什么不把图片挤得紧凑点让精灵图片尺寸更小点呢？因为使用元素的地方可能包含各种不同的内容，这些内容会导致容器变宽变高，预留了足够的空白的话，在容器大小发生变化时，可以避免其他的图片显示出来。
这有一个例子：

每个列表都使用一个数字图片作为背景。看看上面的示例CSS精灵，你会发现这几张图片是交错排列的，这样处理后，不管怎么增加，其他的图片都不会显示出来。
不要担心CSS精灵的尺寸大小
如果你有机会以标准的web设计来设计你的网站，那么你必定要将把很多图片放到精灵图片上，并且为这些图片预览出合适的空隙，这很好。精灵图片中的空白空隙不会增加太多文件的体积，在addons.mozilla.org网站上使用的精灵图片尺寸是1,000×2,000，但它仅16.7kb！
 
（注：事实上，这一点是有争议的：据称，使用CSS Sprites如果背景图片过大，渲染时需要大量的内存。）
background-position

CSS sprites两三事 &#124; 暂无评论，添加评论
本文网址：http://xiaobin.net/200909/something-about-css-sprites/
将之典藏 - 厚积而薄发，© 2005-2009. 如无特别声明，适用署名-非商业性使用-相同方式共享 3.0授权，你可以署名使用全部或者部分内容用于非商业性目的。]]></description>
			<content:encoded><![CDATA[<p><strong>首先</strong>，先介绍一款CSS sprites工具：SpriteMe(<a title="spriteme" href="http://spriteme.org/" target="_blank">http://spriteme.org/</a>)，这是由《High Performance Websites》的作者史蒂夫·桑德斯(<a href="http://stevesouders.com/" target="_blank">Steve Souders</a>)，开发的一款CSS Sprites产生工具。</p>
<p>SpriteMe的安装十分之简单，只要把这个链接拖动到你的浏览器收藏夹就可以：<strong><a href="javascript:(function(){spritemejs=document.createElement('SCRIPT');spritemejs.type='text/javascript';spritemejs.src='http://spriteme.org/spriteme.js';document.getElementsByTagName('head')[0].appendChild(spritemejs);})();">SpriteMe</a></strong> &#8211; 当然你也可以马上点击一下试用一下。<span id="more-96"></span></p>
<p>与其它的一些CSS Sprites工具不一样，SpriteMe具有下面几特性：</p>
<ol>
<li>自动查找背景：SpriteMe有一个独门秘笈，可以容易的在页面内找出所使用的背景图片，同时会列出这些背景图片和使用它们的DOM元素。而不必像其它CSS sprites工具那样一个一个提交你的背景图。</li>
<li>将背景图片按分组来产生CSS sprites：想用好CSS sprites，其实它背后的逻辑还是挺复杂的：比如横向重复的背景图不能跟纵向重复的背景放在同一张CSS sprites云云，有很多规矩，不过现在有了SpriteMe就可以忘记这些复杂的逻辑了，SpriteMe会自动将那些能放在一张CSS sprites的背景图放在一组，每一组最终产生一张CSS sprites背景图。</li>
<li>会自动计算CSS的background-position。</li>
<li>可以将产生的代码应用到当前页面：以前测试CSS sprites通常要把背景图保存，然后改CSS，然后再通过浏览器看效果。SpriteMe就不需要这样，当你点击“make sprites”的时候，代码立刻就应用到当前页面，让你逃离那些无趣的流程。</li>
</ol>
<p>Steve大概是最早提出通过CSS sprites来提升网页性能的人，在使用CSS sprites方面经验丰富。基于这一点，有理由相信他所带来的工具也是经过了深思熟虑，同时也是久经考验，可以满足绝大多数开发者的需要。</p>
<p>以上都是废话，SpriteMe很简单，谁用谁知道！</p>
<p>另外，SpriteMe是开源的：<a href="http://code.google.com/p/spriteme/" target="_blank">http://code.google.com/p/spriteme/</a>，你也可以去下载源代码建立自己的镜像。</p>
<p><strong>然后，</strong>转载一偏关于CSS sprites的技巧（来自：<a href="http://blog.tugai.net/2009/03/31/css-spriting-tips" target="_blank">http://blog.tugai.net/2009/03/31/css-spriting-tips</a>，原文：<a href="http://blog.mozilla.com/webdev/2009/03/27/css-spriting-tips/" target="_blank">http://blog.mozilla.com/webdev/2009/03/27/css-spriting-tips/</a>）：</p>
<blockquote><p>提高网页显示速度最有效的一个方法是减少页面的HTTP请求次数，为了减少HTTP请求次数，最直接有效的方法是使用精灵图片（CSS sprites），精灵图片是把许多图片放到一张大图片里面，通过CSS来显示图片的一部分。</p>
<p>下面是一张精灵图片</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-99" src="http://big5.cc/i/xbin/2009/09/main-sprites1.png" alt="" width="450" height="548" /></p>
<p style="text-align: center;">
<p>本文的目的不是阐述精灵图片如何让网页下载更快，而是介绍在创建精灵图片时的一些实战经验。</p>
<h5>不要等你完成所有工作后再开始使用CSS精灵</h5>
<p>在网站全部完成后，你的CSS和图片也都已经创建好了，这时候你再使用CSS精灵，也就意味着你要返回重写CSS，并且还要把用到的一大堆图片再丢到Photoshop里拼合成一张图片，这是非常痛苦和乏味的。如果在刚开始构建页面时就着手使用CSS精灵，那么一切都会变得简单。</p>
<h5>按图片显示相反的方向放置图片</h5>
<p>这一条有点难以理解，我是在创建一张大的精灵图片中途失败后才意识到它的。假如一张图片应该出现在一个元素的左边，如下图</p>
<p><img class="aligncenter size-full wp-image-100" title="appear-left" src="http://big5.cc/i/xbin/2009/09/appear-left.png" alt="appear-left" width="203" height="28" /></p>
<p>请将这张图片放在精灵的右边（看上面的示例精灵图片）。用这种方式处理后，当你用CSS移动背景图片时，不可能会有别的图片会（错误的）显示处理。</p>
<h5>避免在CSS使用bottom或right定位</h5>
<p>当定位CSS精灵中靠后的图片时，使用类似background-position: bottom -300px; 或者 background-position: right -200px;的方式定位非常容易。最初，这一切都能正常工作，但是，一旦你的CSS精灵宽度或高度增加时，你刚才使用的定位方式就发现了错误，因为图片相对右边或者底边的距离已经发生了变化。所以，请使用left和top来定位。</p>
<h5>为每张图片留出足够空隙</h5>
<p>正如你所看到文章中提供的例子精灵图片一样，许多小图片间都预留了很多空白。为什么不把图片挤得紧凑点让精灵图片尺寸更小点呢？因为使用元素的地方可能包含各种不同的内容，这些内容会导致容器变宽变高，预留了足够的空白的话，在容器大小发生变化时，可以避免其他的图片显示出来。</p>
<p>这有一个例子：</p>
<p><img class="aligncenter size-full wp-image-101" title="list" src="http://big5.cc/i/xbin/2009/09/list.png" alt="list" width="302" height="189" /></p>
<p>每个列表都使用一个数字图片作为背景。看看上面的示例CSS精灵，你会发现这几张图片是交错排列的，这样处理后，不管怎么增加，其他的图片都不会显示出来。</p>
<h5>不要担心CSS精灵的尺寸大小</h5>
<p>如果你有机会以标准的web设计来设计你的网站，那么你必定要将把很多图片放到精灵图片上，并且为这些图片预览出合适的空隙，这很好。精灵图片中的空白空隙不会增加太多文件的体积，在addons.mozilla.org网站上使用的精灵图片尺寸是1,000×2,000，但它仅16.7kb！<br />
<span style="color: #ff6600;"> </span></p>
<p><span style="color: #ff6600;">（注：事实上，这一点是有争议的：<a href="http://www.99css.com/2009/06/css-sprites.html">据称</a>，使用CSS Sprites如果背景图片过大，渲染时需要大量的内存。）</span></p></blockquote>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">background-position</div>
<hr />
<p><strong><a href="http://xiaobin.net/200909/something-about-css-sprites/">CSS sprites两三事</a></strong> | 暂无评论，<a href="http://xiaobin.net/200909/something-about-css-sprites/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200909/something-about-css-sprites/">http://xiaobin.net/200909/something-about-css-sprites/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/EqKMrVjtuiE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200909/something-about-css-sprites/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200909/something-about-css-sprites/</feedburner:origLink></item>
		<item>
		<title>FriendFeed释出私家Web服务器框架：Tornado</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/eyKK972R2XE/</link>
		<comments>http://xiaobin.net/200909/friendfeed-release-webserver-tornado/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 03:04:42 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[FriendFeed]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.amumu.com/?p=57</guid>
		<description><![CDATA[



令人振奋的消息：一个月前被Facebook收购的FriendFeed，在昨天放出了他们的私家Web服务器：名为Tornado的Web服务器框架。Facebook的开源产品阵营再添一员大将，此前这家位于硅谷的全球最大社交网站相继开放了他们的跨语言RPC框架(Thrift)、FBML引擎（Facebook Open Platform）、PHP调试工具(XHProf)等，每一个都是重量级产品。
Tornado由Python编写，是一款轻量级的Web服务器，同时又是一个开发框架。采用非阻塞I/O模型(epoll)，主要是为了应对高并发 访问量而被开发出来，尤其适用于comet应用。Python社区原本也有很多优秀的开源Web服务器和框架，但是FriendFeed出于对性能和一些 特性的需要，尤其是其业务上对实时性要求非常之高，主流的Web服务器和框架很难兼顾到这些业务特点，所以FriendFeed决定自己开发。
确 实，Tornado在性能上卓而不凡，有图为证：

Tornado有点像web.py 和  Google的 webapp，但是附加了很多工具，同时针对FriendFeed的业务特点，进行了一些优化从而带来非阻塞式Web服务器的优点，归纳起来Tornado有如下特性：

集成网站常用的基本组件：Tornado内建了很多组件，来使Web开发中复杂事情简单化，减少重复 劳动。这些组件包括：模板引擎、Cookies用户登录、认证、L10N、静态文件缓存、CSRF攻击防护、第三方登录（像Facebook Connect）。Tornado组件非常易用，同时即便你在Tornado Web服务器来运行其它的框架，也可以使用这些组件。
能够支撑实时应用：Tornado能够支撑大量的并发连接，用Tornado很容易开发需要长轮询(long polling)和HTTP流的应用。在FriendFeed，每一个活动用户与服务器之间甚至用长连接的方式居然也能承受。
高性能：与大多数Python框架相比，Tornado非常的快。FriendFeed拿Tornado和其它的一些主流框架做过压力测试，Tornado的吞吐量高出其它框架4倍之巨。

在Facebook的支持下，有理由相信Tornado会成为web.py、Django的有力竞争者。




FriendFeed释出私家Web服务器框架：Tornado &#124; 暂无评论，添加评论
本文网址：http://xiaobin.net/200909/friendfeed-release-webserver-tornado/
将之典藏 - 厚积而薄发，© 2005-2009. 如无特别声明，适用署名-非商业性使用-相同方式共享 3.0授权，你可以署名使用全部或者部分内容用于非商业性目的。]]></description>
			<content:encoded><![CDATA[<div>
<div>
<div>
<div>
<p>令人振奋的消息：一个月前被<a href="http://www.facebook.com/" target="_blank">Facebook</a>收购的<a href="http://friendfeed.com/" target="_blank">FriendFeed</a>，在昨天放出了他们的私家Web服务器：名为<a title="Tornado官网- 需翻墙" href="http://www.tornadoweb.org/" target="_blank">Tornado</a>的Web服务器框架。Facebook的开源产品阵营再添一员大将，此前这家位于硅谷的全球最大社交网站相继开放了他们的跨语言RPC框架(<a href="http://developers.facebook.com/thrift/" target="_blank">Thrift</a>)、FBML引擎（<a href="http://developers.facebook.com/fbopen/">Facebook Open Platform</a>）、PHP调试工具(<a href="http://pecl.php.net/package/xhprof">XHProf</a>)等，每一个都是重量级产品。</p>
<p>Tornado由Python编写，是一款轻量级的Web服务器，同时又是一个开发框架。采用非阻塞I/O模型(epoll)，主要是为了应对高并发 访问量而被开发出来，尤其适用于<a title="什么是comet" href="http://en.wikipedia.org/wiki/Comet_(programming)" target="_blank">comet</a>应用。Python社区原本也有很多优秀的开源Web服务器和框架，但是FriendFeed出于对性能和一些 特性的需要，尤其是其业务上对实时性要求非常之高，主流的Web服务器和框架很难兼顾到这些业务特点，所以FriendFeed决定自己开发。</p>
<p>确 实，Tornado在性能上卓而不凡，有图为证：</p>
<p style="text-align: center;"><img class="aligncenter" src="http://chart.apis.google.com/chart?chxt=y&amp;chd=t%3A100%2C40%2C27%2C25%2C9&amp;chco=609bcc&amp;chm=t+8213%2C000000%2C0%2C0%2C11%7Ct+3353%2C000000%2C0%2C1%2C11%7Ct+2223%2C000000%2C0%2C2%2C11%7Ct+2066%2C000000%2C0%2C3%2C11%7Ct+785%2C000000%2C0%2C4%2C11&amp;chs=600x175&amp;cht=bhs&amp;chtt=Web+server+requests%2Fsec+%28AMD+Opteron%2C+2.4GHz%2C+4+cores%29&amp;chxl=0%3A%7CCherryPy+%28standalone%29%7Cweb.py+%28Apache%2Fmod_wsgi%29%7CDjango+%28Apache%2Fmod_wsgi%29%7CTornado+%281+single-threaded+frontend%29%7CTornado+%28nginx%3B+4+frontends%29%7C" alt="Tornado benchmark" width="600" height="175" /></p>
<p>Tornado有点像<a href="http://webpy.org/" target="_blank">web.py</a> 和  Google的 <a title="适用于Google App Engine的Python开发框架" href="http://code.google.com/appengine/docs/python/tools/webapp/" target="_blank">webapp</a>，但是附加了很多工具，同时针对FriendFeed的业务特点，进行了一些优化从而带来非阻塞式Web服务器的优点，归纳起来Tornado有如下特性：</p>
<ul>
<li><strong>集成网站常用的基本组件</strong>：Tornado内建了很多组件，来使Web开发中复杂事情简单化，减少重复 劳动。这些组件包括：模板引擎、Cookies用户登录、认证、L10N、静态文件缓存、CSRF攻击防护、第三方登录（像<a title="类似OpenID的解决方案" href="http://developers.facebook.com/connect.php" target="_blank">Facebook Connect</a>）。Tornado组件非常易用，同时即便你在Tornado Web服务器来运行其它的框架，也可以使用这些组件。</li>
<li><strong>能够支撑实时应用</strong>：Tornado能够支撑大量的并发连接，用Tornado很容易开发需要长轮询(long polling)和HTTP流的应用。在FriendFeed，每一个活动用户与服务器之间甚至用长连接的方式居然也能承受。</li>
<li><strong>高性能</strong>：与大多数Python框架相比，Tornado非常的快。FriendFeed拿Tornado和其它的一些主流框架做过压力测试，Tornado的吞吐量高出其它框架4倍之巨。</li>
</ul>
<p>在Facebook的支持下，有理由相信Tornado会成为web.py、Django的有力竞争者。</p></div>
</div>
</div>
</div>
<hr />
<p><strong><a href="http://xiaobin.net/200909/friendfeed-release-webserver-tornado/">FriendFeed释出私家Web服务器框架：Tornado</a></strong> | 暂无评论，<a href="http://xiaobin.net/200909/friendfeed-release-webserver-tornado/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200909/friendfeed-release-webserver-tornado/">http://xiaobin.net/200909/friendfeed-release-webserver-tornado/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/eyKK972R2XE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200909/friendfeed-release-webserver-tornado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200909/friendfeed-release-webserver-tornado/</feedburner:origLink></item>
		<item>
		<title>招行“99积分抢兑”攻略</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/H1o0HFDVWGs/</link>
		<comments>http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 03:12:10 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[其它]]></category>

		<guid isPermaLink="false">http://blog.amumu.com/?p=27</guid>
		<description><![CDATA[昨天第一次参加招行信用卡的“99积分兑换”活动就顺利的抢了一套Lock&#38;Lock。前后在网上搜了一下，看到很多网友在骂招行，质疑活动存在暗箱操作。
是不是真的存在暗箱操作我不得而知。不过我昨天从早上就开始做功课，发现这个活动是有技巧的，只是大多数非IT从业人员不大会借助工具，所以觉得别人能在1分钟之内填信用卡信息提交表单觉得是一件难以想象的事。实际上，只要你掌握了本文所讲的技巧，相信你也可以做到“秒杀”。
好了，来，开始吧：
一、下载并安装GreenBrowser
我们制胜的法宝是：GreenBrowser，它是一个浏览器，跟Maxthon、世界之窗、TT等浏览器差不多，都是基于IE的内核的，但是GreenBrowser有一个特性：模拟按键。
看到这里，相信有些朋友已经恍然大悟了：抢兑成功的关键就是借助GreenBrowser来自动填写表单。因为招行的信用卡号、密码输入框与我们平时在一般网页上所见的输入框不一样，它是一种比较特殊的控件（ActiveX），其它浏览器均不具备填写这种控件的特性，所以我们才需要GreenBrowser。
下载GreenBrowser并安装好就可以了，安装过程比较简单，一路点击“下一步”就可以了。绿色版想来应该也能用，但是我没有测试过。
二、在未登录状态设定填表规则
我们预先需要设定自动填表规则。请务必确定你未登录招商银行信用卡俱乐部，如果是已登录状态的，应当先退出。
这是因为我们在抢兑进行时（第三步）， 也会在未登录状态下进行。已登录状态下打开支付页面，系统会去获取你名下的信用卡，这是一个时间杀手。在系统繁忙的情况下，获取信用卡信息通常要花2分钟 之巨，这两分钟，东西早被抢光了。所以记住，咱有了GreenBrowser自动填表，瞬间就能完成表单填写，不需要登录。

用GreeBrowser打开支付页面(https://ccclub.cmbchina.com//ccclub/Purchase/Pay.aspx)
填写“持卡人身份确认”，只要先选定“信用卡类型”、“登记证件号码”两个下拉框，如图：

填写“收货人信息”：

如果使用信用卡账单地址做为收货地址的话，只填写收货人联系手机，其它项暂时不管它们。这一步就完成。

如果使用非帐单地址做为收货地址，除了省份和城市两个下拉框不做选择之外，其它的表单项目都要先填写，如图：



确认已填写表单没有错误，按快捷键：Alt+1（是1234的“1”，不是“L”），将跳出如图的对话框，选择“确定”：

点击GreenBrowser菜单“工具”/“自动填表”/“设置表单数据….”：

 在弹出的窗口中，我们将进行最为关键的一些设置：

设定焦点项目，如图：

再点击“发送按键到页面”按钮，在弹出的窗口内输入
\t证件号码\t信用卡号\t查询密码\t有效月份\t有效年份\tCVV码
这里是关键中的关键，\t和数字之间完全是没有空格的，不能多输或少输“\t”，输入完毕之后点“确定”关闭输入窗口，再按“确定”保存规则。如图：



OK，填表规则已经设置完成了。我们来测试一下吧，按F5键刷新一下当前的这个页面，表单会被完全清空，然后再按一下 ALT + Q 键，怎么样？表单全部按你开始的设定填写好了吗？如果没有，建议按步骤重新检查一下。

三、抢购进行时
好了，一切准备好的话，那我们就可以进行抢购了。下面就是抢购的操作步骤，你就可以建议你预先演练多几遍，以熟悉这些操作：

关掉GreenBrowser的多余标签页，仅保留2个，分别打开你想抢兑的商品页面(如：http://ccclub.cmbchina.com//ccclub/productinfo.aspx?gid=2009072449556)和支付页面（https://ccclub.cmbchina.com//ccclub/Purchase/Pay.aspx），当时间到15:00的时候，点击“立即抢兑”（演练时可以忽略这一步骤，因为你点不了）
刷新支付页面（除非是你正在演练，要不然会看到最上面的购物车里出现你刚兑的商品），赶紧按ALT + Q键；
 按完Alt + Q 键后，表单基本都能填写完，唯有一、两个小地方填表工具没有办法帮我们填写的，还要手动点击一下：

如果你的收货地址正是你的账单地址，快速的勾选“按信用卡账单地址寄送”；
如果你的收货地址不是你的账单地址，你需要快速的选中收货的省份和城市两个下拉框；


迅速的点击支付页面底部的“立即付款”按钮，如果弹出“系统繁忙”的警告框，按回车键，再继续点击“立即付款”。
如果运气够好的话，你会看到你的订单号和付款成功字样。那么恭喜你了！！

抢兑开始前准备：
抢兑开始前，你应该花15分钟左右来做一些准备：

设置填表规则的第6步非常重要，务必再三确认你设定的身份证信息、卡号、密码一定没有输错。
确定你没有登录信用卡俱乐部，否则它会给你带来非常大的麻烦。
同步你的电脑时间，切记一定要同步电脑的时间，避免你的电脑走时不准。只校准你的手机、手表的时间是没用的。同步时间后，如果你的GreenBrowser正打开着商品页面（就是有倒计时的那个页面），最好刷新一下它。

静侯着15:00的到来吧。
后话
这里仅提供一个操作方法，由于本人表达能力有限、同时读者知识结构也不一样，并不保证该方法适用于每一个人、也不能保证每一个人都 能成功。同时请了解在浏览器内保存信用卡信息会存在一定的安全风险，务必在确保你的电脑没有木马病毒的情况下使用，在抢兑成功的情况下应尽快清除 GreenBrowser内保留的信用卡信息，即便抢兑不成功也应该尽快清除才是上策。
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;
10月31日更新：
虽然招行把调整了抢兑时间、更新了规则，但是抢兑流程、网页结构没有发生变化，以上攻略技巧经验证仍然还可用，全部过程耗时27秒完成——还包括了因为系统繁忙造成无法提交订单的延时。

招行“99积分抢兑”攻略 &#124; 评论数(13)，添加评论
本文网址：http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/
将之典藏 - 厚积而薄发，© 2005-2009. 如无特别声明，适用署名-非商业性使用-相同方式共享 3.0授权，你可以署名使用全部或者部分内容用于非商业性目的。]]></description>
			<content:encoded><![CDATA[<p>昨天第一次参加招行信用卡的“<a href="http://creditcard.cmbchina.com/jfplan/99jf.htm" target="_blank">99积分兑换</a>”活动就顺利的抢了一套Lock&amp;Lock。前后在网上搜了一下，看到很多网友在骂招行，质疑活动存在暗箱操作。</p>
<p>是不是真的存在暗箱操作我不得而知。不过我昨天从早上就开始做功课，发现这个活动是有技巧的，只是大多数非IT从业人员不大会借助工具，所以觉得别人能在1分钟之内填信用卡信息提交表单觉得是一件难以想象的事。实际上，只要你掌握了本文所讲的技巧，相信你也可以做到“秒杀”。</p>
<p>好了，来，开始吧：<span id="more-27"></span></p>
<h3 id="step1">一、下载并安装GreenBrowser</h3>
<p>我们制胜的法宝是：<a href="http://www.morequick.com/IndexGB.htm" target="_blank">GreenBrowser</a>，它是一个浏览器，跟Maxthon、世界之窗、TT等浏览器差不多，都是基于IE的内核的，但是GreenBrowser有一个特性：<a href="http://www.morequick.com/Skill/SendKeyToPage.htm" target="_blank">模拟按键</a>。</p>
<p>看到这里，相信有些朋友已经恍然大悟了：<strong>抢兑成功的关键就是借助GreenBrowser来自动填写表单</strong>。因为招行的信用卡号、密码输入框与我们平时在一般网页上所见的输入框不一样，它是一种比较特殊的控件（ActiveX），其它浏览器均不具备填写这种控件的特性，所以我们才需要GreenBrowser。</p>
<p><a href="http://down.5igb.com/GreenBrowserGBSetup.exe" target="_blank">下载GreenBrowser</a>并安装好就可以了，安装过程比较简单，一路点击“下一步”就可以了。<a href="http://down.5igb.com/GreenBrowserGB.zip" target="_blank">绿色版</a>想来应该也能用，但是我没有测试过。</p>
<h3 id="step2">二、在未登录状态设定填表规则</h3>
<p>我们预先需要设定自动填表规则。请务必确定你未登录招商银行信用卡俱乐部，如果是已登录状态的，应当先退出。</p>
<p>这是因为我们在抢兑进行时（<a href="#step3">第三步</a>）， 也会在未登录状态下进行。已登录状态下打开支付页面，系统会去获取你名下的信用卡，这是一个时间杀手。在系统繁忙的情况下，获取信用卡信息通常要花2分钟 之巨，这两分钟，东西早被抢光了。所以记住，咱有了GreenBrowser自动填表，瞬间就能完成表单填写，不需要登录。</p>
<ol>
<li>用GreeBrowser打开支付页面(<a href="https://ccclub.cmbchina.com//ccclub/Purchase/Pay.aspx" target="_blank">https://ccclub.cmbchina.com//ccclub/Purchase/Pay.aspx</a>)</li>
<li>填写“持卡人身份确认”，只要先选定“信用卡类型”、“登记证件号码”两个下拉框，如图：<br />
<img class="aligncenter size-full wp-image-34" title="持卡人身份确认" src="http://big5.cc/i/xbin/2009/09/step2.png" alt="持卡人身份确认" width="391" height="273" /></li>
<li>填写“收货人信息”：
<ul>
<li>如果<strong>使用信用卡账单地址做为收货地址的话</strong>，只填写收货人联系手机，其它项暂时不管它们。这一步就完成。<br />
<img class="aligncenter size-full wp-image-35" title="收货人信息" src="http://big5.cc/i/xbin/2009/09/step3-1.png" alt="收货人信息" width="516" height="348" /></li>
<li>如果<strong>使用<em>非</em>帐单地址做为收货地址</strong>，除了省份和城市两个下拉框不做选择之外，其它的表单项目都要先填写，如图：<br />
<img class="aligncenter size-full wp-image-36" title="收货人信息" src="http://big5.cc/i/xbin/2009/09/step3-2.png" alt="收货人信息" width="504" height="350" /></li>
</ul>
</li>
<li>确认已填写表单没有错误，按快捷键：<strong>Alt+1</strong>（是1234的“1”，不是“L”），将跳出如图的对话框，选择“确定”：<br />
<img class="aligncenter size-full wp-image-37" title="选择表单" src="http://big5.cc/i/xbin/2009/09/step4.png" alt="选择表单" width="351" height="313" /></li>
<li>点击GreenBrowser菜单“工具”/“自动填表”/“设置表单数据….”：<br />
<img class="aligncenter size-full wp-image-38" title="选择表单" src="http://big5.cc/i/xbin/2009/09/step5.png" alt="选择表单" width="326" height="461" /></li>
<li><span id="step2-6"> </span>在弹出的窗口中，我们将进行最为关键的一些设置：
<ol>
<li>设定焦点项目，如图：<br />
<img class="aligncenter size-full wp-image-39" title="设置表单焦点" src="http://big5.cc/i/xbin/2009/09/step6-1.png" alt="设置表单焦点" width="599" height="554" /></li>
<li>再点击“发送按键到页面”按钮，在弹出的窗口内输入
<pre>\t<span style="color: red;">证件号码</span>\t<span style="color: red;">信用卡号</span>\t<span style="color: red;">查询密码</span>\t<span style="color: red;">有效月份</span>\t<span style="color: red;">有效年份</span>\t<span style="color: red;">CVV码</span></pre>
<p style="text-align: center;">这里是关键中的关键，\t和数字之间完全是没有空格的，不能多输或少输“\t”，输入完毕之后点“确定”关闭输入窗口，再按“确定”保存规则。如图：<br />
<img class="aligncenter size-full wp-image-40" title="step6-2" src="http://big5.cc/i/xbin/2009/09/step6-2.png" alt="step6-2" width="599" height="554" /></li>
</ol>
</li>
<li>OK，填表规则已经设置完成了。我们来测试一下吧，按F5键刷新一下当前的这个页面，表单会被完全清空，然后再按一下 <strong>ALT + Q</strong> 键，怎么样？表单全部按你开始的设定填写好了吗？如果没有，建议按步骤重新检查一下。</li>
</ol>
<h3 id="step3">三、抢购进行时</h3>
<p>好了，一切准备好的话，那我们就可以进行抢购了。下面就是抢购的操作步骤，你就可以建议你预先演练多几遍，以熟悉这些操作：</p>
<ol>
<li>关掉GreenBrowser的多余标签页，仅保留2个，分别打开你想抢兑的商品页面(如：http://ccclub.cmbchina.com//ccclub/productinfo.aspx?gid=2009072449556)和支付页面（<a href="https://ccclub.cmbchina.com//ccclub/Purchase/Pay.aspx" target="_blank">https://ccclub.cmbchina.com//ccclub/Purchase/Pay.aspx</a>），当时间到15:00的时候，点击“立即抢兑”（演练时可以忽略这一步骤，因为你点不了）</li>
<li><strong>刷新支付页面</strong>（除非是你正在演练，要不然会看到最上面的购物车里出现你刚兑的商品），<strong>赶紧按ALT + Q键</strong>；</li>
<li> 按完Alt + Q 键后，表单基本都能填写完，唯有一、两个小地方填表工具没有办法帮我们填写的，还要手动点击一下：
<ul>
<li>如果你的<strong>收货地址正是你的账单地址</strong>，快速的勾选“按信用卡账单地址寄送”；</li>
<li>如果你的<strong>收货地址<em>不</em>是你的账单地址</strong>，你需要快速的选中收货的省份和城市两个下拉框；</li>
</ul>
</li>
<li><strong>迅速的点击支付页面底部的“立即付款”按钮</strong>，如果弹出“系统繁忙”的警告框，按回车键，再继续点击“立即付款”。</li>
<li>如果运气够好的话，你会看到你的订单号和付款成功字样。那么恭喜你了！！</li>
</ol>
<h3>抢兑开始前准备：</h3>
<p>抢兑开始前，你应该花15分钟左右来做一些准备：</p>
<ol>
<li>设置填表规则的<a href="#step2-6">第6步</a>非常重要，务必再三确认你设定的身份证信息、卡号、密码一定没有输错。</li>
<li>确定你没有登录信用卡俱乐部，否则它会给你带来非常大的麻烦。</li>
<li><a href="http://tech.ddvip.com/2007-07/118402150229049.html" target="_blank">同步</a>你的电脑时间，切记一定要同步电脑的时间，避免你的电脑走时不准。只校准你的手机、手表的时间是没用的。同步时间后，如果你的GreenBrowser正打开着商品页面（就是有倒计时的那个页面），最好刷新一下它。</li>
</ol>
<p>静侯着15:00的到来吧。</p>
<h3>后话</h3>
<p><strong>这里仅提供一个操作方法，由于本人表达能力有限、同时读者知识结构也不一样，并不保证该方法适用于每一个人、也不能保证每一个人都 能成功。同时请了解在浏览器内保存信用卡信息会存在一定的安全风险，务必在确保你的电脑没有木马病毒的情况下使用，在抢兑成功的情况下应尽快清除 GreenBrowser内保留的信用卡信息，即便抢兑不成功也应该尽快清除才是上策。</strong></p>
<p><strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</strong></p>
<p><strong>10月31日更新：</strong></p>
<p>虽然招行把调整了抢兑时间、更新了规则，但是抢兑流程、网页结构没有发生变化，以上攻略技巧经验证仍然还可用，全部过程耗时27秒完成——还包括了因为系统繁忙造成无法提交订单的延时。</p>
<hr />
<p><strong><a href="http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/">招行“99积分抢兑”攻略</a></strong> | 评论数(13)，<a href="http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/">http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/H1o0HFDVWGs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200908/cmbchina-points-exchange-tutorial/</feedburner:origLink></item>
		<item>
		<title>基于位运算的权限控制</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/XrezF1G6vTs/</link>
		<comments>http://xiaobin.net/200906/bitwise-permission/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 02:48:26 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[位运算]]></category>

		<guid isPermaLink="false">http://blog.amumu.com/?p=22</guid>
		<description><![CDATA[原理
在Linux文件系统中，一个用户对文件或目录所拥有的权限分为三种：&#8221;可读&#8221;、&#8221;可写&#8221;和&#8221;可执行&#8221;，分别用 1 、2 和 4 来表示，它们之间可以任意组合：有“可读”、“可写”权限就用 3 来表示（1 + 2 = 3）；有”可读“、”可执行“权限就用5来表示（1 + 4 = 5），三种权限全部拥有就用 7 表示（1 + 2 + 4 = 7）。
实际上，这种运算是基于二进制的。
假设可执行、可写、可读三种权限分别对应三个状态位，如果用户具有某种权限，那么将对应的状态位标识为“1”，反之则标识为“0”。如图：


如果只有“可读”权限，那么就对应二进制数：001，将这个二进制数转成十进制就得到1；如果同时具有“可读”、“可写”权限，二进制数则对应为： 011，转十进制得：3；同理，三种权限都有的，十进制就等于7。
实现
在PHP中，通过位运算符很容易就可以做到类似的权限控制：
&#60;?php
//定义权限
define('READ', 1&#60;&#60; 0);    // 把可读权限放在最右边
define('WRITE', 1&#60;&#60;1);    // 可读权限向左移一位
define('EXCUTE', 1&#60;&#60;2);   // 可执行权限向左移两位

//赋予权限
$user_permission = READ &#124; WRITE;

//验证权限
echo '可读：', ($user_permission &#38; READ) ? 'Yes' : 'No', [...]]]></description>
			<content:encoded><![CDATA[<h3>原理</h3>
<p>在Linux文件系统中，一个用户对文件或目录所拥有的权限分为三种：&#8221;可读&#8221;、&#8221;可写&#8221;和&#8221;可执行&#8221;，分别用 1 、2 和 4 来表示，它们之间可以任意组合：有“可读”、“可写”权限就用 3 来表示（1 + 2 = 3）；有”可读“、”可执行“权限就用5来表示（1 + 4 = 5），三种权限全部拥有就用 7 表示（1 + 2 + 4 = 7）。</p>
<p>实际上，这种运算是基于二进制的。<span id="more-22"></span></p>
<p>假设可执行、可写、可读三种权限分别对应三个状态位，如果用户具有某种权限，那么将对应的状态位标识为“1”，反之则标识为“0”。如图：</p>
<p><img class="aligncenter size-full wp-image-32" title="位运算与权限控制" src="http://big5.cc/i/xbin/2009/09/2442391910.png" alt="位运算与权限控制" width="231" height="180" /></p>
<p style="text-align: center;">
<p>如果只有“可读”权限，那么就对应二进制数：001，将这个二进制数转成十进制就得到1；如果同时具有“可读”、“可写”权限，二进制数则对应为： 011，转十进制得：3；同理，三种权限都有的，十进制就等于7。</p>
<h3>实现</h3>
<p>在PHP中，通过<a href="http://www.php.net/language.operators.bitwise" target="_blank">位运算符</a>很容易就可以做到类似的权限控制：</p>
<pre>&lt;?php
//定义权限
define('READ', 1&lt;&lt; 0);    // 把可读权限放在最右边
define('WRITE', 1&lt;&lt;1);    // 可读权限向左移一位
define('EXCUTE', 1&lt;&lt;2);   // 可执行权限向左移两位

//赋予权限
$user_permission = READ | WRITE;

//验证权限
echo '可读：', ($user_permission &amp; READ) ? 'Yes' : 'No', "\n";
echo '可写：', ($user_permission &amp; WRITE) ? 'Yes' : 'No', "\n";
echo '可执行：', ($user_permission &amp; EXCUTE) ? 'Yes' : 'No', "\n";
?&gt;</pre>
<p>PHP语言本身的<a href="http://www.php.net/error_reporting" target="_blank">错误控制</a> 也是用位运算来做的，它甚至还利用了<em>按位异或</em>和<em>按位非</em>，使得错误控制更加精确。</p>
<h3>优点和缺陷</h3>
<p>位运算的运算对象是二进制的位，速度快，效率高，而且节省存储空间，位运算做权限控制又相当地灵活。但是，位运算也有很大的局限，因为在32位计算机上，位移不能超过32次，这就要求权限数量不超过32种。</p>
<hr />延伸阅读：</p>
<ul>
<li>MySQL的<a href="http://dev.mysql.com/doc/refman/5.1/en/set.html" target="_blank">SET</a>类型，也是基于位运算的，恰当的运用，效果不错，可以参看<a href="http://dev.mysql.com/tech-resources/articles/mysql-set-datatype.html" target="_blank">教程</a></li>
</ul>
<hr />
<p><strong><a href="http://xiaobin.net/200906/bitwise-permission/">基于位运算的权限控制</a></strong> | 暂无评论，<a href="http://xiaobin.net/200906/bitwise-permission/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200906/bitwise-permission/">http://xiaobin.net/200906/bitwise-permission/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/XrezF1G6vTs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200906/bitwise-permission/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200906/bitwise-permission/</feedburner:origLink></item>
		<item>
		<title>Mysql复合主键自增长</title>
		<link>http://feedproxy.google.com/~r/zh_cn/~3/DJ-eT8fFr6k/</link>
		<comments>http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/#comments</comments>
		<pubDate>Sat, 30 May 2009 16:55:52 +0000</pubDate>
		<dc:creator>肖斌</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.amumu.com/?p=12</guid>
		<description><![CDATA[Google Analytics的ID一般形如：UA-18xxxxx-1，UA-18xxxxx-4,我们可以将它分成两段来看：字段1：UA-18XXXXX是指帐户的ID；字段2：字段1后附加的1、4，刚分别是指该帐户名下的两个网站。不过我一直不知道这种ID怎么产生的。
最近查阅到Mysql手册才发现，原来Mysql原生就很好的支持了这种含自动增长字段的复合主键，所以字段2是存储引擎自动计算出来的。计算方式：MAX(auto_increment_column) + 1 WHERE prefix=given-prefix [1]。
不多说，直接看SQL：
mysql&#62; CREATE TABLE `_test` (
    -&#62; `c1` varchar(20) NOT NULL DEFAULT '', -- 主键一：varchar
    -&#62; `c2` int(11) NOT NULL AUTO_INCREMENT, -- 主键二：自增序列
    -&#62; `c3` varchar(255) ,
    -&#62; PRIMARY KEY (`c1`,`c2`) -- 注意这里的先后顺序
    -&#62; ) [...]]]></description>
			<content:encoded><![CDATA[<p>Google Analytics的ID一般形如：UA-18xxxxx-<strong>1</strong>，UA-18xxxxx-<strong>4</strong>,我们可以将它分成两段来看：字段1：UA-18XXXXX是指帐户的ID；字段2：字段1后附加的1、4，刚分别是指该帐户名下的两个网站。不过我一直不知道这种ID怎么产生的。</p>
<p>最近查阅到Mysql手册才发现，原来Mysql原生就很好的支持了这种含自动增长字段的复合主键，所以字段2是存储引擎自动计算出来的。计算方式：MAX(<em>auto_increment_column</em>) + 1 WHERE prefix=<em>given-prefix</em> <sup><a href="#fn:mysql_manual">[1]</a></sup>。<span id="more-12"></span></p>
<p>不多说，直接看SQL：</p>
<pre>mysql&gt; CREATE TABLE `_test` (
    -&gt; `c1` varchar(20) NOT NULL DEFAULT '', -- 主键一：varchar
    -&gt; `c2` int(11) NOT NULL AUTO_INCREMENT, -- 主键二：自增序列
    -&gt; `c3` varchar(255) ,
    -&gt; PRIMARY KEY (`c1`,`c2`) -- <span style="color: #ff0000;">注意这里的先后顺序</span>
    -&gt; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.04 sec)

mysql&gt;
mysql&gt; INSERT INTO `_test` (`c1`,`c3`) VALUES ('AAA','Robin Home'),
    -&gt; ('AAA','Robin Blog'),
    -&gt; ('AAA','Robin Resume'),
    -&gt; ('BBB','Lily Home'),
    -&gt; ('BBB','Lily Blog');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql&gt;
mysql&gt; SELECT * FROM `_test`;
+-----+----+--------------+
| c1  | c2 | c3           |
+-----+----+--------------+
| AAA |  1 | Robin Home   |
| AAA |  2 | Robin Blog   |
| AAA |  3 | Robin Resume |
| BBB |  1 | Lily Home    |
| BBB |  2 | Lily Blog    |
+-----+----+--------------+
5 rows in set (0.00 sec)

mysql&gt;</pre>
<p>值得注意的是，MySQL的这种特性只适用于MyISAM和BDB引擎。</p>
<hr />参考资料：</p>
<ol>
<li id="fn:mysql_manual"><a rev="footnote" href="#fnref:mysql_manual"><strong>^</strong></a> <a href="http://dev.mysql.com/doc/refman/5.1/zh/tutorial.html#example-auto-increment" target="_blank">使用AUTO_INCREMENT</a> ，MySQL手册</li>
</ol>
<hr />
<p><strong><a href="http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/">Mysql复合主键自增长</a></strong> | 暂无评论，<a href="http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/#comments">添加评论</a>
<br>本文网址：<a href="http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/">http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/</a>
<br><a href="http://xiaobin.net">将之典藏</a> - 厚积而薄发，© 2005-2009. 如无特别声明，适用<a href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh" target="_blank">署名-非商业性使用-相同方式共享 3.0</a>授权，你可以署名使用全部或者部分内容用于非商业性目的。</p><img src="http://feeds.feedburner.com/~r/zh_cn/~4/DJ-eT8fFr6k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://xiaobin.net/200905/mysql-auto-increasement-and-multi-primary-key/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 0.404 seconds -->
