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

<channel>
	<title>Liuw's Thinkpad</title>
	<atom:link href="http://blog.liuw.name/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.liuw.name</link>
	<description>想要赢就先学会输，想要成功就先学会失败</description>
	<pubDate>Thu, 02 Sep 2010 15:34:04 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>階段小結及新的計劃</title>
		<link>http://blog.liuw.name/784</link>
		<comments>http://blog.liuw.name/784#comments</comments>
		<pubDate>Thu, 02 Sep 2010 15:34:04 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[生活]]></category>

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

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

		<guid isPermaLink="false">http://liuw.72pines.com/?p=784</guid>
		<description><![CDATA[原來決定是暑假這段時間把ULK3看完的，事實上比原定的計劃晚了幾天。現在終於是把這本書草草地看完了。LDD3大概看了一轉，平時用不到，我更喜歡把它作為一本手冊來用。LKD2看了好幾遍了，穿插于那兩本之間，有的東西互相引證，每次看都會有新的收穫。
其實對於內核的理解，看完這幾本書之後也只能說是剛剛開始，我也希望能隨著項目的進一步深入去加強自己的理解，需求推動才是王道。新的學期，按照計劃應該是需要找一些小的安全點來實現一下，應該還是有機會會用到一些內核知識的，那就當是練手吧。
近來和朋友們聊天，發現自己對於應用的理解是很膚淺的，一些基本的概念都不知道。雖然暫時沒有搞應用的想法，但是一些基本概念瞭解一下還是有好處的。所以對自己的要求就是多向他們學習，開拓眼界。
坦白地說，我并不認為做底層比做應用更加高深。底層技術是收斂的，一些基本問題、基本模式已經很長時間沒有改變了，Challenging的地方在于底層系統關係複雜、難于調試和開發。個人覺得需要在底層方面得到突破是需要很長時間積累的，一是需要有發現問題的能力，二是需要有解決問題的能力。這兩個方面的能力，自認為還是很欠缺。應用技術則是發散的，更加貼近現實，貼近End User，需求會快速變化。而且，應用系統都是自成體系的，不同的系統，問題不一樣，Challenging的地方也不一樣。這就需要搞應用的人有很強的學習能力、分析能力，能夠適時而變。
就我自身來說，我一直以來不喜歡搞應用，就是因為我覺得這些一套套的框架、模式，學習起來太費時間，以后不一定可以用到。但是現實看來，我這樣的選擇，使自己知識面過小，不利于發散思維的培養。所以以后一個基本的定調還是，不會拒絕應用方面的知識，甚至是有意識地去做一些東西，發現一些自己從來沒有考慮過的問題。
再進一層的，既然是談研究生，我還是希望能夠得到一些理論上的進步。其實我基本不指望國內的學校能給我多少的東西，還是自學的靠譜。我考慮選取編譯原理、人工智能和數據挖掘作為下一階段的自學方向。編譯原理是基本理論，從我目前遇到的問題來說，很多都可以從編譯原理中得到思路，而且它也可以為後面兩個階段打基礎。人工智能和數據挖掘是搞“應用”中比較有意思的問題，所以值得去研究和學習。
目前的定調就是這樣的了，希望自己能按照計劃好好執行。
]]></description>
			<content:encoded><![CDATA[<p>原來決定是暑假這段時間把ULK3看完的，事實上比原定的計劃晚了幾天。現在終於是把這本書草草地看完了。LDD3大概看了一轉，平時用不到，我更喜歡把它作為一本手冊來用。LKD2看了好幾遍了，穿插于那兩本之間，有的東西互相引證，每次看都會有新的收穫。</p>
<p>其實對於內核的理解，看完這幾本書之後也只能說是剛剛開始，我也希望能隨著項目的進一步深入去加強自己的理解，需求推動才是王道。新的學期，按照計劃應該是需要找一些小的安全點來實現一下，應該還是有機會會用到一些內核知識的，那就當是練手吧。</p>
<p>近來和朋友們聊天，發現自己對於應用的理解是很膚淺的，一些基本的概念都不知道。雖然暫時沒有搞應用的想法，但是一些基本概念瞭解一下還是有好處的。所以對自己的要求就是多向他們學習，開拓眼界。</p>
<p>坦白地說，我并不認為做底層比做應用更加高深。底層技術是收斂的，一些基本問題、基本模式已經很長時間沒有改變了，Challenging的地方在于底層系統關係複雜、難于調試和開發。個人覺得需要在底層方面得到突破是需要很長時間積累的，一是需要有發現問題的能力，二是需要有解決問題的能力。這兩個方面的能力，自認為還是很欠缺。應用技術則是發散的，更加貼近現實，貼近End User，需求會快速變化。而且，應用系統都是自成體系的，不同的系統，問題不一樣，Challenging的地方也不一樣。這就需要搞應用的人有很強的學習能力、分析能力，能夠適時而變。</p>
<p>就我自身來說，我一直以來不喜歡搞應用，就是因為我覺得這些一套套的框架、模式，學習起來太費時間，以后不一定可以用到。但是現實看來，我這樣的選擇，使自己知識面過小，不利于發散思維的培養。所以以后一個基本的定調還是，不會拒絕應用方面的知識，甚至是有意識地去做一些東西，發現一些自己從來沒有考慮過的問題。</p>
<p>再進一層的，既然是談研究生，我還是希望能夠得到一些理論上的進步。其實我基本不指望國內的學校能給我多少的東西，還是自學的靠譜。我考慮選取編譯原理、人工智能和數據挖掘作為下一階段的自學方向。編譯原理是基本理論，從我目前遇到的問題來說，很多都可以從編譯原理中得到思路，而且它也可以為後面兩個階段打基礎。人工智能和數據挖掘是搞“應用”中比較有意思的問題，所以值得去研究和學習。</p>
<p>目前的定調就是這樣的了，希望自己能按照計劃好好執行。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/784/feed</wfw:commentRss>
		</item>
		<item>
		<title>沒有見過比這個更丑的Python程序了</title>
		<link>http://blog.liuw.name/779</link>
		<comments>http://blog.liuw.name/779#comments</comments>
		<pubDate>Tue, 31 Aug 2010 12:35:31 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[Algorithm]]></category>

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

		<category><![CDATA[exhaustive search]]></category>

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

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

		<guid isPermaLink="false">http://liuw.72pines.com/?p=779</guid>
		<description><![CDATA[可以大言不慚地吼著說：“我寫的！”
複用不好，很多冗餘代碼。設計不好，接口不明。寫法丑，不夠Pythonic。
唯一的優點是它確實能解決我的問題。數學建模一個題目“最佳陣容”，要算出所有得分會大于某個特定分數的出場陣容。
其實是一個0-1背包問題，但是約束條件比較多，算法自己又不在行，用回溯剪枝寫不出來。Lingo的規劃又只能做出一個解。
還好，動手算了一下，這個組合數也不過百萬級別，這對於現代的電腦完全是小case。所以用最丑的辦法寫了一個出來，當然，還是有點優化的。
程序我也不打算別人看懂，自己以后估計也不會再看，所以就不多解釋了。放這里做個留念，看看自己寫的程序有多丑。


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Liu Wei

def combination(items, n=None):
    if n is None:
        n = len(items)
    for i in xrange(len(items)):
        v = items[i:i+1]
        if n == [...]]]></description>
			<content:encoded><![CDATA[<p>可以大言不慚地吼著說：“我寫的！”</p>
<p>複用不好，很多冗餘代碼。設計不好，接口不明。寫法丑，不夠Pythonic。</p>
<p>唯一的優點是它確實能解決我的問題。數學建模一個題目“最佳陣容”，要算出所有得分會大于某個特定分數的出場陣容。</p>
<p>其實是一個0-1背包問題，但是約束條件比較多，算法自己又不在行，用回溯剪枝寫不出來。Lingo的規劃又只能做出一個解。</p>
<p>還好，動手算了一下，這個組合數也不過百萬級別，這對於現代的電腦完全是小case。所以用最丑的辦法寫了一個出來，當然，還是有點優化的。</p>
<p>程序我也不打算別人看懂，自己以后估計也不會再看，所以就不多解釋了。放這里做個留念，看看自己寫的程序有多丑。</p>
<pre name="code" class="python">

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Liu Wei

def combination(items, n=None):
    if n is None:
        n = len(items)
    for i in xrange(len(items)):
        v = items[i:i+1]
        if n == 1:
            yield v
        else:
            rest = items[i+1:]
            for c in combination(rest, n-1):
                yield v + c

def permutation(items, n=None):
    if n is None:
        n = len(items)
    for i in xrange(len(items)):
        v = items[i:i+1]
        if n == 1:
            yield v
        else:
            rest = items[:i] + items[i+i:]
            for p in permutation(rest, n-1):
                yield v + p

# highest score for each player
scores = [
    [9.4, 9.8, 10, 9.5, 9.4, 9.9, 10, 10, 9.4, 9.7],
    [10, 9.4, 9.5, 9.9, 9.7, 9.9, 10, 10, 9.8, 9.5],
    [9.8, 10, 9.4, 9.7, 9.3, 9.1, 9.3, 9.9, 10, 9.6],
    [9.9, 9.6, 10, 10, 9.9, 9.4, 9.8, 9.8, 9.9, 9.8]
    ]

# final array
array = [
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]

# sparse array for 6 cols
sparse_array = [
    [0, 0, 0, 0, 0, 0], \
    [0, 0, 0, 0, 0, 0], \
    [0, 0, 0, 0, 0, 0], \
    [0, 0, 0, 0, 0, 0], \
    ]

def __sparse_array_check_valid():
    global sparse_array
    # 6 cols
    for i in xrange(6):
        sum = 0
        for j in xrange(4):
            sum += sparse_array[j][i]
        if sum &gt; 3:
            return False
    return True

def __sparse_array_init():
    global sparse_array
    sparse_array =  [[0, 0, 0, 0, 0, 0], \
                    [0, 0, 0, 0, 0, 0], \
                    [0, 0, 0, 0, 0, 0], \
                    [0, 0, 0, 0, 0, 0], \
                    ]

def __sparse_array_set_row(p, r):
    global sparse_array
    a, b = p
    sparse_array[r][a] = 1
    sparse_array[r][b] = 1

def __sparse_array_clear_row(r):
    global sparse_array
    for i in xrange(len(sparse_array[r])):
        sparse_array[r][i] = 0

def sparse_array_output():
    global sparse_array
    print sparse_array

# generator for sparse arrays
def sparse_array_generator():
    global sparse_array
    # 4 rows
    __sparse_array_init()
    for r0 in combination(range(6), 2):
        __sparse_array_clear_row(0)
        __sparse_array_set_row(r0, 0)
        for r1 in combination(range(6), 2):
            __sparse_array_clear_row(1)
            __sparse_array_set_row(r1, 1)
            for r2 in combination(range(6), 2):
                __sparse_array_clear_row(2)
                __sparse_array_set_row(r2, 2)
                for r3 in combination(range(6), 2):
                    __sparse_array_clear_row(3)
                    __sparse_array_set_row(r3, 3)

                    if __sparse_array_check_valid():
                        yield sparse_array
                    #    sparse_array_output()

def __array_set_col(c):
    global array
    for i in xrange(len(array)):
        array[i][c] = 1

def __array_clean_col(c):
    global array
    for i in xrange(len(array)):
        array[i][c] = 0

def __array_init():
    global array
    array = [
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        ]

def set_allround_player(a):
    for i in a:
        __array_set_col(i)

def set_individual_player(sa, s):
    global array
    for i in range(4):
        for j in range(6):
            array[i][s[j]] = sa[i][j]

def array_generator():
    global array
    for g in combination(range(10), 4):
        # select cols for sparse array in big array
        s = [i for i in range(10) if i not in g]
        __array_init();
        # start to manipulate the array
        # first select all-round player
        set_allround_player(g)
        # then cope with individual event player
        for sa in sparse_array_generator():
            set_individual_player(sa, s)
            yield array

def calc_score(a):
    sum = 0
    for i in range(len(a)):
        for j in range(len(a[0])):
            sum += a[i][j] * scores[i][j]
    return sum

def final_generator():
    for a in array_generator():
        total_score = calc_score(a)
        if total_score &gt;= 236.2:
            yield [a, total_score]

import os
os.chdir(&quot;d:/liuw/&quot;)
f = file(&quot;output&quot;, &#039;a&#039;)
for solution, total_score in final_generator():
    f.write(str(solution))
    f.write(&#039;\n&#039;)
    f.write(str(total_score))
    f.write(&#039;\n\n&#039;)
f.close()
</pre>
<p>用到了大量的generator，因為怕會內存不足。但是總yield一個全局數組總覺得有點別扭。話說我們這次的做題目用到了Lingo、Python、Matlab和C，果然是程序員的命，全部學計算機的人組個隊還是有好處的。</p>
<p>最後在電腦上跑了5分鐘左右，結果就出來了。假如想再快點，還可以做雙核並行計算。不過自己這方面沒什麽研究，程序也要得比較急，就沒有多管。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/779/feed</wfw:commentRss>
		</item>
		<item>
		<title>Emacs中删除空行</title>
		<link>http://blog.liuw.name/777</link>
		<comments>http://blog.liuw.name/777#comments</comments>
		<pubDate>Tue, 31 Aug 2010 09:09:10 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[UNIX-like]]></category>

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

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

		<guid isPermaLink="false">http://liuw.72pines.com/?p=777</guid>
		<description><![CDATA[m-x flush-lines
^$
]]></description>
			<content:encoded><![CDATA[<p>m-x flush-lines<br />
^$</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/777/feed</wfw:commentRss>
		</item>
		<item>
		<title>跑腿記</title>
		<link>http://blog.liuw.name/771</link>
		<comments>http://blog.liuw.name/771#comments</comments>
		<pubDate>Sun, 29 Aug 2010 13:48:36 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[生活]]></category>

		<category><![CDATA[跑腿]]></category>

		<guid isPermaLink="false">http://liuw.72pines.com/?p=771</guid>
		<description><![CDATA[今天第一次去給老闆跑腿，圓滿了。得總結一下。
因為大部份人都是不喜歡跑腿的，所以看到老闆來電話一定要三思而後行，首先想好老闆在此特定時刻找你的所有可能性，並且想好說辭。不過今天我倒無所謂，因為也很久沒有出去運動過了，就當是去運動一下。
出去一定要帶點錢，因為老闆可能要買東西，而她給的錢是不一定夠的（因為她自己也沒什麽概念）。為了避免來來回回的麻煩，最好自己帶上一到兩百。不過這也是有風險的，老闆貴人事忙，萬一哪一天她忘記這回事了，那就是自己給老闆做貢獻了。
出去給老闆花什麽錢了，一定要有收據之類的東西，這樣大家都放心。這可以給老闆辦事認真細緻的印象，這種人才夠可靠。有什麽老闆吩咐外的事情，一定要打電話問清楚老闆的意思，有好的解決方案也得先讓她首肯，不然那就是自作聰明了。
細節決定成敗，不但要會做事，還要做得夠細緻。
再寫點題外的話，今天去到老闆的家，覺得挺亂的。成功人士也不是所有方面都那麼成功的，呵呵。
]]></description>
			<content:encoded><![CDATA[<p>今天第一次去給老闆跑腿，圓滿了。得總結一下。</p>
<p>因為大部份人都是不喜歡跑腿的，所以看到老闆來電話一定要三思而後行，首先想好老闆在此特定時刻找你的所有可能性，並且想好說辭。不過今天我倒無所謂，因為也很久沒有出去運動過了，就當是去運動一下。</p>
<p>出去一定要帶點錢，因為老闆可能要買東西，而她給的錢是不一定夠的（因為她自己也沒什麽概念）。為了避免來來回回的麻煩，最好自己帶上一到兩百。不過這也是有風險的，老闆貴人事忙，萬一哪一天她忘記這回事了，那就是自己給老闆做貢獻了。</p>
<p>出去給老闆花什麽錢了，一定要有收據之類的東西，這樣大家都放心。這可以給老闆辦事認真細緻的印象，這種人才夠可靠。有什麽老闆吩咐外的事情，一定要打電話問清楚老闆的意思，有好的解決方案也得先讓她首肯，不然那就是自作聰明了。</p>
<p>細節決定成敗，不但要會做事，還要做得夠細緻。</p>
<p>再寫點題外的話，今天去到老闆的家，覺得挺亂的。成功人士也不是所有方面都那麼成功的，呵呵。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/771/feed</wfw:commentRss>
		</item>
		<item>
		<title>用Grep去找Raw Data的一个小实验</title>
		<link>http://blog.liuw.name/769</link>
		<comments>http://blog.liuw.name/769#comments</comments>
		<pubDate>Sun, 29 Aug 2010 10:49:35 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[Security]]></category>

		<category><![CDATA[UNIX-like]]></category>

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

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

		<category><![CDATA[raw data]]></category>

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

		<guid isPermaLink="false">http://liuw.72pines.com/?p=769</guid>
		<description><![CDATA[在某处看到一篇文章，使用grep来找回没有分区表的硬盘中的文本文件内容。基本命令是：


grep &#34;keyword&#34; /dev/DEVICE

有可能需要加上其他的一些选项。
能这样做是因为在Unix中万物皆文件，即使没有Filesystem的信息，也可以通过bypass掉Filesystem的方法去读取block，得到raw data。
这个方法是有局限的。Filesystem处理数据时以block为单位，而多block的文件，block的分布不一定是连续的。也就是说grep也许能找到一部分数据，但是不大可能把所有的数据都找回来。当然，一个block一般是1K或者4K找回来的数据量对于一个文本文件来说也是相当可观的了。
为了证实我的想法，我做了以下的实验。


dd if=/dev/urandom of=hd.img bs=1M count=10

之所以用urandom而不是zero做输入，是为了增加数据，模拟真实的Filesystem。


losetup hd.img /dev/loop0

把这个文件连接到loop0，成为一个设备。


mkfs.ext3 -b 1024 /dev/loop0
mount /dev/loop0 /mnt
echo -e &#34;This is a small file for testing.\nsecond line\nthird line&#34; &#62; /mnt/f1
umount /mnt

建立block大小为1024的ext3分区，然后挂载，向里面写入少量数据（少于1个block）。


grep --binary-files=text -z &#34;file&#34; /dev/loop0

不用-z的话，只会grep一行。
这样确实可以看到原来文件的内容。假如文件修改过有几个版本的话，可能还可以看到几个版本的内容。也许这是一个提高Filesystem效率的措施。
再测试大于1 block的文件。


perl -e &#039;print &#34;string1 &#34; x 128; print &#34;string2 &#34; x 128&#039; &#62; /mnt/f2
perl -e &#039;print &#34;string3 &#34; x 128; print &#34;string4 &#34; [...]]]></description>
			<content:encoded><![CDATA[<p>在某处看到一篇文章，使用grep来找回没有分区表的硬盘中的文本文件内容。基本命令是：</p>
<pre name="code" class="c">

grep &quot;keyword&quot; /dev/DEVICE
</pre>
<p>有可能需要加上其他的一些选项。</p>
<p>能这样做是因为在Unix中万物皆文件，即使没有Filesystem的信息，也可以通过bypass掉Filesystem的方法去读取block，得到raw data。</p>
<p>这个方法是有局限的。Filesystem处理数据时以block为单位，而多block的文件，block的分布不一定是连续的。也就是说grep也许能找到一部分数据，但是不大可能把所有的数据都找回来。当然，一个block一般是1K或者4K找回来的数据量对于一个文本文件来说也是相当可观的了。</p>
<p>为了证实我的想法，我做了以下的实验。</p>
<pre name="code" class="c">

dd if=/dev/urandom of=hd.img bs=1M count=10
</pre>
<p>之所以用urandom而不是zero做输入，是为了增加数据，模拟真实的Filesystem。</p>
<pre name="code" class="c">

losetup hd.img /dev/loop0
</pre>
<p>把这个文件连接到loop0，成为一个设备。</p>
<pre name="code" class="c">

mkfs.ext3 -b 1024 /dev/loop0
mount /dev/loop0 /mnt
echo -e &quot;This is a small file for testing.\nsecond line\nthird line&quot; &gt; /mnt/f1
umount /mnt
</pre>
<p>建立block大小为1024的ext3分区，然后挂载，向里面写入少量数据（少于1个block）。</p>
<pre name="code" class="c">

grep --binary-files=text -z &quot;file&quot; /dev/loop0
</pre>
<p>不用-z的话，只会grep一行。</p>
<p>这样确实可以看到原来文件的内容。假如文件修改过有几个版本的话，可能还可以看到几个版本的内容。也许这是一个提高Filesystem效率的措施。</p>
<p>再测试大于1 block的文件。</p>
<pre name="code" class="c">

perl -e &#039;print &quot;string1 &quot; x 128; print &quot;string2 &quot; x 128&#039; &gt; /mnt/f2
perl -e &#039;print &quot;string3 &quot; x 128; print &quot;string4 &quot; x 128&#039; &gt; /mnt/f3
for i in `seq 4 9`; do echo &quot;$i&quot; &gt; &quot;f$i&quot; ; done
perl -e &#039;print &quot;paddin&quot; x 128&#039; &gt;&gt; /mnt/f2
perl -e &#039;print &quot; ssssss &quot; x 128&#039; &gt;&gt; /mnt/f2
...
</pre>
<p>上面其实进行了很多操作，这里就不一一列出了。block大小为1K，用stat可以看到它们的I/O block。之所以做多个文件，是为了防止ext3 bitmap在再次分配block的时候分配连续block，模拟真实环境。写完文件之后记得sync或者umount，把cache都flush到硬盘上。</p>
<p>再grep一次，可以发现各种数据是夹杂在一起的。</p>
<p>所以，最好还是注意保护自己的Filesystem吧。这些技巧只能解决小问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/769/feed</wfw:commentRss>
		</item>
		<item>
		<title>發一段以前寫的elisp</title>
		<link>http://blog.liuw.name/766</link>
		<comments>http://blog.liuw.name/766#comments</comments>
		<pubDate>Sat, 28 Aug 2010 03:00:35 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[生活]]></category>

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

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

		<guid isPermaLink="false">http://liuw.72pines.com/?p=766</guid>
		<description><![CDATA[無任何實用價值，無聊的時候寫的，做ASCII Art動畫。


(defun cinema (file fps)
  (interactive &#34;sFile: \nnFPS: &#34;)
  (let ((int-time (/ 1.0 fps)))
    (find-file file)
    (while t
      (scroll-up 25)
      (sit-for int-time))))

具體效果見 ASCII Art Bad Apple Emacs 。
]]></description>
			<content:encoded><![CDATA[<p>無任何實用價值，無聊的時候寫的，做ASCII Art動畫。</p>
<pre name="code" class="c">

(defun cinema (file fps)
  (interactive &quot;sFile: \nnFPS: &quot;)
  (let ((int-time (/ 1.0 fps)))
    (find-file file)
    (while t
      (scroll-up 25)
      (sit-for int-time))))
</pre>
<p>具體效果見 <a href="http://v.youku.com/v_show/id_XMTU0OTg4MjU2.html">ASCII Art Bad Apple Emacs</a> 。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/766/feed</wfw:commentRss>
		</item>
		<item>
		<title>近期收集的一些有趣的小東東</title>
		<link>http://blog.liuw.name/761</link>
		<comments>http://blog.liuw.name/761#comments</comments>
		<pubDate>Thu, 26 Aug 2010 11:00:15 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[UNIX-like]]></category>

		<category><![CDATA[分享]]></category>

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

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

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

		<guid isPermaLink="false">http://liuw.72pines.com/?p=761</guid>
		<description><![CDATA[近來比較少寫blog，實在是比較忙。用繁體寫是因為看簡體的字多了眼花，得換換口味了。
72pines的頁面很奇怪，假如我不用搜狗的全網加速功能去開，出來的頁面就沒有樣式了。可能它有一部份的伺服器被教育網墻掉了（？）。
在王亮先生的Emacs定制和擴展中，找到一個“能獲取root權限的輔助腳本”，解決了我一直頭痛的一個問題。原理挺簡單，使用TRAMP來完全的。以前一直以為TRAMP主要是用于遠程編輯文件的，沒有發現這個功能，沒仔細看Manual的後果。


(defun wl-sudo-find-file (file dir)
  (find-file (concat &#34;/sudo:localhost:&#34; (expand-file-name file dir))))

當然，其他的內容也很精彩。
第二個，是從Wowubuntu得來的三手信息。爲什麽說是三手呢，因為它也只是轉載的。主要是講Bash shell的一些奇技淫巧。
最牛B的 Linux Shell 命令 系列连载，有點標題黨了，呵呵。
比較有趣的是活用history功能的條目，比如說sudo執行前一條命令是：


$ sudo !!

兩個嘆號“!!”等價于“!-1”，數字換成其他也是可以的，不過誰記得了那麼多啊。
另外一個有趣的功能就是Bash的替換（原來它也有啊，呵呵）：


$ !!:s/foo/bar/

很熟悉的語法，只是從來沒有想到過還有這個功能，sigh。
文章提到上面兩個技巧都是出自The Definitive Guide to Bash Command Line History。
還有一些其他的技巧，不僅僅限於Bash本身，不一而足。由於有的要么知道了，要么對我自己用處不大，這里就不多記了。
]]></description>
			<content:encoded><![CDATA[<p>近來比較少寫blog，實在是比較忙。用繁體寫是因為看簡體的字多了眼花，得換換口味了。</p>
<p>72pines的頁面很奇怪，假如我不用搜狗的全網加速功能去開，出來的頁面就沒有樣式了。可能它有一部份的伺服器被教育網墻掉了（？）。</p>
<p>在王亮先生的<a href="http://www.wanglianghome.org/org/programming/emacsbook/emacs.html">Emacs定制和擴展</a>中，找到一個“能獲取root權限的輔助腳本”，解決了我一直頭痛的一個問題。原理挺簡單，使用TRAMP來完全的。以前一直以為TRAMP主要是用于遠程編輯文件的，沒有發現這個功能，沒仔細看Manual的後果。</p>
<pre name="code" class="c">

(defun wl-sudo-find-file (file dir)
  (find-file (concat &quot;/sudo:localhost:&quot; (expand-file-name file dir))))
</pre>
<p>當然，其他的內容也很精彩。</p>
<p>第二個，是從Wowubuntu得來的三手信息。爲什麽說是三手呢，因為它也只是轉載的。主要是講Bash shell的一些奇技淫巧。</p>
<p><a href="http://wowubuntu.com/linux_shell_1.html">最牛B的 Linux Shell 命令 系列连载</a>，有點標題黨了，呵呵。</p>
<p>比較有趣的是活用history功能的條目，比如說sudo執行前一條命令是：</p>
<pre name="code" class="c">

$ sudo !!
</pre>
<p>兩個嘆號“!!”等價于“!-1”，數字換成其他也是可以的，不過誰記得了那麼多啊。</p>
<p>另外一個有趣的功能就是Bash的替換（原來它也有啊，呵呵）：</p>
<pre name="code" class="c">

$ !!:s/foo/bar/
</pre>
<p>很熟悉的語法，只是從來沒有想到過還有這個功能，sigh。</p>
<p>文章提到上面兩個技巧都是出自The Definitive Guide to Bash Command Line History。</p>
<p>還有一些其他的技巧，不僅僅限於Bash本身，不一而足。由於有的要么知道了，要么對我自己用處不大，這里就不多記了。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/761/feed</wfw:commentRss>
		</item>
		<item>
		<title>五笔拆字约定</title>
		<link>http://blog.liuw.name/751</link>
		<comments>http://blog.liuw.name/751#comments</comments>
		<pubDate>Sun, 08 Aug 2010 01:34:35 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[分享]]></category>

		<category><![CDATA[五笔]]></category>

		<category><![CDATA[拆字]]></category>

		<guid isPermaLink="false">http://liuw.72pines.com/?p=751</guid>
		<description><![CDATA[1. 凡单笔画与字根相连或带点结构都视为杂全型，如“天”、“千”、“丸”、“太”。
2. 区分汉字结构时，按“能散不连”的原则来进行，如“矢”、“卡”、“严”、“走”都视为上下型。
3. 含两字根且相交者属杂合型，如“乐”、“串”、“电”、“本”。
4. 下含“走之”字为杂合型，如“进”、“过”、“这”、“边”。
5. 属于“连”和“交”的汉字一律视为杂合型。
]]></description>
			<content:encoded><![CDATA[<p>1. 凡单笔画与字根相连或带点结构都视为杂全型，如“天”、“千”、“丸”、“太”。</p>
<p>2. 区分汉字结构时，按“能散不连”的原则来进行，如“矢”、“卡”、“严”、“走”都视为上下型。</p>
<p>3. 含两字根且相交者属杂合型，如“乐”、“串”、“电”、“本”。</p>
<p>4. 下含“走之”字为杂合型，如“进”、“过”、“这”、“边”。</p>
<p>5. 属于“连”和“交”的汉字一律视为杂合型。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/751/feed</wfw:commentRss>
		</item>
		<item>
		<title>Building modules against installed kernel</title>
		<link>http://blog.liuw.name/737</link>
		<comments>http://blog.liuw.name/737#comments</comments>
		<pubDate>Fri, 16 Jul 2010 15:49:50 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[UNIX-like]]></category>

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

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

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

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

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

		<guid isPermaLink="false">http://blog.liuw.name/?p=737</guid>
		<description><![CDATA[I&#8217;ve been reading Linux Device Drivers 3rd for quite a long time, and once built a sacrifice system in VMWare. After I upgraded VMWare, the sacrifice kernel hangs, unable to discover root filesystem. It seems to be a driver issue. No matter how I compile my kernel, it hangs at the same place.
I finally give [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been reading Linux Device Drivers 3rd for quite a long time, and once built a sacrifice system in VMWare. After I upgraded VMWare, the sacrifice kernel hangs, unable to discover root filesystem. It seems to be a driver issue. No matter how I compile my kernel, it hangs at the same place.</p>
<p>I finally give up, I don&#8217;t want to waste my time any more. Maybe I should just dump that 2.6.10 and try new ones. No need to</p>
<p>I have a Debian system working as my development system. I just need to install kernel header to get a module building environment.</p>
<pre name="code" class="c">

# apt-get install linux-headers-`uname -r`
</pre>
<p>When it&#8217;s done, build directory should be found in</p>
<pre name="code" class="c">

# ls -d /lib/modules/`uname -r`/build
</pre>
<p>Here is a handy Makefile for modules.</p>
<pre name="code" class="c">

obj-m += hello.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/737/feed</wfw:commentRss>
		</item>
		<item>
		<title>Cheet sheet for locking</title>
		<link>http://blog.liuw.name/727</link>
		<comments>http://blog.liuw.name/727#comments</comments>
		<pubDate>Wed, 14 Jul 2010 06:04:06 +0000</pubDate>
		<dc:creator>liuw</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[UNIX-like]]></category>

		<category><![CDATA[cheet sheet]]></category>

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

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

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

		<guid isPermaLink="false">http://blog.liuw.name/?p=727</guid>
		<description><![CDATA[
Pete Zaitcev gives the following summary:



If you are in a process context (any syscall) and want to lock other process out, use a semaphore. You can take a semaphore and sleep ( copy_from_user* or kmalloc(x,GFP_KERNEL) ).


Otherwise (== data can be touched in an interrupt), use spin_lock_irqsave() and spin_unlock_irqrestore().


Avoid holding spinlock for more than 5 lines [...]]]></description>
			<content:encoded><![CDATA[<p>
Pete Zaitcev gives the following summary:
</p>
<ul>
<li>
If you are in a process context (any syscall) and want to lock other process out, use a semaphore. You can take a semaphore and sleep ( copy_from_user* or kmalloc(x,GFP_KERNEL) ).
</li>
<li>
Otherwise (== data can be touched in an interrupt), use spin_lock_irqsave() and spin_unlock_irqrestore().
</li>
<li>
Avoid holding spinlock for more than 5 lines of code and across any function call (except accessors like readb).</p>
</li>
</ul>
<p><span id="more-727"></span></p>
<p>The following table lists the <span style="text-decoration:underline">minimum</span> locking requirements between various contexts. In some cases, the same context can only be running on one CPU at a time, so no locking is required for that context (eg. a particular thread can only run on one CPU at a time, but if it needs shares data with another thread, locking is required).
</p>
<p>
Remember the advice above: you can always use spin_lock_irqsave(), which is a superset of all other spinlock primitives.
</p>
<li>sl stands for spin_lock()</li>
<li>slb stands for spin_lock_bh()</li>
<li>sli stands for spin_lock_irq()</li>
<li>slis stands for spin_lock_irqsave()</li>
<table border="4" cellspacing="1" cellpadding="1" rules="groups">
<col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col><col align="left"></col></p>
<thead>
<tr>
<th></th>
<th>IRQ Handler A</th>
<th>IRQ Handler B</th>
<th>Softirq A</th>
<th>Softirq B</th>
<th>Tasklet A</th>
<th>Tasklet B</th>
<th>Timer A</th>
<th>Timer B</th>
<th>UserContext A</th>
<th>UserContext B</th>
</tr>
</thead>
<tbody>
<tr>
<td>IRQ Handler A</td>
<td>None</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>IRQ Handler B</td>
<td>slis</td>
<td>None</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Softirq A</td>
<td>sli</td>
<td>sli</td>
<td>sl</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Softirq B</td>
<td>sli</td>
<td>sli</td>
<td>sl</td>
<td>sl</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Tasklet A</td>
<td>sli</td>
<td>sli</td>
<td>sl</td>
<td>sl</td>
<td>None</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Tasklet B</td>
<td>sli</td>
<td>sli</td>
<td>sl</td>
<td>sl</td>
<td>sl</td>
<td>None</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Timer A</td>
<td>sli</td>
<td>sli</td>
<td>sl</td>
<td>sl</td>
<td>sl</td>
<td>sl</td>
<td>None</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Timer B</td>
<td>sli</td>
<td>sli</td>
<td>sl</td>
<td>sl</td>
<td>sl</td>
<td>sl</td>
<td>sl</td>
<td>None</td>
<td></td>
<td></td>
</tr>
<tr>
<td>User Context A</td>
<td>sli</td>
<td>sli</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>None</td>
<td></td>
</tr>
<tr>
<td>User Context B</td>
<td>sli</td>
<td>sli</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>slb</td>
<td>di</td>
<td>None</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.liuw.name/727/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
