Archive for 2009
Ubuntu下编译Linux-xen的问题
在Ubuntu下编译Linux-xen时碰到arch/i386/kernel/head-xen.o无法找到的问题,而该目录下有head-xen.S这个文件,说明make之前的的工作并没有把这个.S文件编译成.o。而同样的代码,在ArchLinux和Fedora上svn checkout后编译没有任何问题。
最后发现问题在于Ubuntu默认会把/bin/sh指向/bin/dash,在scripts/Makefile.build里面加上一行SHELL=/bin/bash指定$(shell)使用bash即可。后来还搜了一下为什么Ubuntu使用dash而不是bash,其理由是dash的执行效率更高,但不可否认的是这个改动也导致了一些项目无法成功编译,虽然无法成功编译的原因可能是Makefile里使用了一些bash的特性而非POSIX shell所提供的那些。
另外在debug过程中在网上找到了一些debug Makefile的技巧:
make -n 可以仅仅打印出将要被执行的命令,而不去实际执行
make -np 可以打印出更多的信息(使用的规则和变量),并执行每一条命令
remake也是个不错的选择:“remake is a patched and modernized version of GNU make utility that adds improved error reporting, the ability to trace execution in a comprehensible way, and a debugger.”
在检查shell命令的时候,可以使用set -x使得所有shell命令在执行前都能被输出。
Chomp游戏
把一堆石子排成n行m列,两人轮流从里面取出石子,条件是取出一个石子后所有在它右边和上面的石子也要被取走。谁取走最后一个石子就算输。以3*5的棋盘举例来说,先手取了(2,5),因此(3,5)也要被取走;后手取了(3,3),同时也要取走(3,4)。现在棋盘的状态如下(O代表这个位子的石子还没被取走,x代表已经被取走):
3 O O x x x 2 O O O O x 1 O O O O O 1 2 3 4 5
接下来先手又取了(2,1),于是第二排和第三排就一颗石子都不剩了
3 x x x x x 2 x x x x x 1 O O O O O 1 2 3 4 5
后手取(1,2)
3 x x x x x 2 x x x x x 1 O x x x x 1 2 3 4 5
接下来先手就只能取最后一个石子了,后手胜。
这个游戏像是Nim Game的二维版本。于是问题也来了,能不能保证先手或者后手有必胜策略呢?
答案是除了1*1的棋盘,对于其他大小的棋盘,先手总能赢。有一个很巧妙的证明可以保证先手存在必胜策略,可惜这个证明不是构造性的,也就是说没有给出先手怎么下才能赢。证明如下:
如果后手能赢,也就是说后手有必胜策略,使得无论先手第一次取哪个石子,后手都能获得最后的胜利。那么现在假设先手取最右上角的石子(n,m),接下来后手通过某种取法使得自己进入必胜的局面。但事实上,先手在第一次取的时候就可以和后手这次取的一样,进入必胜局面了,与假设矛盾。
另外这个证明是基于Zermelo’s theory,这个理论保证在这样一种游戏中(两人博弈,信息完全公开,不存在偶然事件且能在有限步里面决出胜负),先手或后手肯定存在一种必胜策略。
相关链接:
http://en.wikipedia.org/wiki/Zermelo’s_theorem_(game_theory)
Emacs中对不同项目指定不同的风格
我的Emacs配置里C语言默认的缩进风格是用4个空格,最近要修改Chromium的代码,而Google的C/C++风格统一为2个空格缩进,所以改代码的时候要把c-basic-offset设置为2。这样在不同项目间切换的时候很不方便。
在stackoverflow上发帖求助后发现了Emacs 23.1一个很好用的新功能,Per-Directory Local Variables,只需要在项目主目录下放一个.dir-locals.el文件,里面设置该项目特有的变量值,就能应用到整个项目了。
以我的Chromium为例,Google已经提供了一份C/C++风格的配置,只需要在~/chromius/src/.dir-locals.el里把google-c-style常量粘贴进去即可。另外我不知道为啥加上c-offsets-alist那段后Emacs缩进会变得很奇怪,所以我把它删了。附修改后的.dir-locals.el
((c++-mode . ((c-recognize-knr-p . nil)
(c-enable-xemacs-performance-kludge-p . t) ; speed up indentation in XEmacs
(c-basic-offset . 2)
(indent-tabs-mode . nil)
(c-comment-only-line-offset . 0)
(c-hanging-braces-alist . ((defun-open after)
(defun-close before after)
(class-open after)
(class-close before after)
(namespace-open after)
(inline-open after)
(inline-close before after)
(block-open after)
(block-close . c-snug-do-while)
(extern-lang-open after)
(extern-lang-close after)
(statement-case-open after)
(substatement-open after)))
(c-hanging-colons-alist . ((case-label)
(label after)
(access-label after)
(member-init-intro before)
(inher-intro)))
(c-hanging-semi&comma-criteria
. (c-semi&comma-no-newlines-for-oneline-inliners
c-semi&comma-inside-parenlist
c-semi&comma-no-newlines-before-nonblanks))
(c-indent-comments-syntactically-p . nil)
(comment-column . 40)
(c-cleanup-list . (brace-else-brace
brace-elseif-brace
brace-catch-brace
empty-defun-braces
defun-close-semi
list-close-comma
scope-operator)))))
NoteExpress and BibTex
最近写了篇survey,分享下用NoteExpress一些经验
1. bibtex 关键字设置:
工具->样式->选择当前输出样式,选择BibTex,然后就能在题录的字段中找到bibtex 关键字一项了
2. 导出bibtex时选择ANSI编码,如果设置为UTF-8貌似编译latex时会给出类似You’re missing an entry type—line 1 of file xxx.bib的提示。
3. 导出引用的网页:我的解决方法是在BibTex样式->题录->模版里新增一个网页模版,然后右键编辑区选择从模版通用复制,并在里面增加一条`***`Howpublished = {\url{`链接`}}, 这样就能使用howpublished字段导出网页链接了。不过好像这样网页地址不会换行,于是我最后还是用手动断行改了下.bib。
4. 另外提下,把png/jpg转成eps,我用的是sam2p,aur上就有。
在git中修改之前提交的内容
其实这个问题我以前在Stackoverflow上回答过别人http://stackoverflow.com/questions/1186535/how-to-modify-a-specified-commit,不过现在自己反而忘了,还是贴在这下次查起来方便点
先用git rebase bbc643cd^ –interactive 退回到要修改的commit的前一个点,这里bbc643cd就是要修改的commit,执行后git会调用默认的编辑器显示该次commit到最新commit的所有记录,在这里我们把要修改的那一项的行首的pick改成edit。
接下来运行git commit –amend,使用默认编辑器修改这次commit。
最后执行git rebase –continue就能提交修改后的commit并且返回到原来的commit了。
新装硬盘空间只有31B/32MB的解决方案
这周买了块西数的1T硬盘,用来放各种美剧/高清电影。装好进入Win7后提示检测到新硬盘,然后进入磁盘管理一看发现磁盘大小只有31兆,重启进入BIOS看到的磁盘容量是0MB。换了一台电脑问题依然存在。
于是求助superuser,发现了这篇文章http://www.pcstats.com/articleview.cfm?articleid=1139&page=12,貌似是LBA(Logical Block Addressing)相关的问题,下载了个HDD Capacity Restore Tool修复后问题解决。
附该软件下载地址:http://hdd-tools.com/products/cr/download/crsetup.exe
推荐个iPhone/iPod Touch上的时间管理工具
以前一直用TODO和Saisuke做时间管理,前者用来同步toodledo.com的待办事项,后者可以和Google Calendar同步日程安排。不过最近不知怎么的Saisuke没法和Google Calendar同步了,每次同步都报错“Turn off Airplane Mode or use Wi-Fi to access Network”,于是只能去App Store上找替代品。
这里推荐下Pocket Informant,用下来感觉很不错。同时支持tooledo.com和Google Calendar,Today视图上可以查看今天的Calendar安排以及近期的TODO事项。不过好像不支持TODO的标签功能,我现在拿context当tag用。另外weiphone上也有人说它速度有点慢,不过我没发现。
破解版俺这里就不提供下载了,appulous和weiphone上搜一下就能找到。
几个有趣的Quine变种
Quine是指一类能生成自己的程序,例如下面这个C程序运行后就能把自己的源码完整的打印出来:
char*f="char*f=%c%s%c;main()
{printf(f,34,f,34,10);}%c";
main(){printf(f,34,f,34,10);}
这类程序的构造方法计算理论导引或者其他相关的书籍中都有涉及,这里不再赘述。这个月看到几个Quine的变种,都挺有趣的。
首先是sigfpe构造出来的三阶Quine,这是一个只有两行的Haskell程序:
q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']
main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end"
这段程序牛逼在哪里呢?运行后这个程序首先会输出一个Python程序,然后再运行这个Python程序会输出一段Ruby代码,最后这个Ruby代码的运行结果是原来的程序。或者说
$ runhaskell quine.hs | python | ruby
的运行结果就是这段程序本身。
另外两个Quine变种都和zip有关。一个是解压得到自己的gzip文件;另一个看起来更强大一点(不过是真的“更强大”吗?),解压自己能得到一个图片和自己本身,基于lz77算法。
两个zip quine的下载地址分别是http://upload-001.yo2cdn.com/wp-content/uploads/74/7487/2009/09/selfgz.rar和http://steike.com/code/useless/zip-file-quine/droste.zip。
博客转移
很抱歉再一次发这样的帖子
主要原因是之前的主页提供商九州未来科技的质量实在不怎么样,一方面经常会有连不上的问题,另一方面客服解决问题的态度很差。前几天我发现服务器的 时间设置错误,UTC时间被设置成了CST时间,也就是快了8个小时,于是联系客服希望能够调整下时间,我想调整时间也无非是一行date命令而已。结果再三交涉后从技术人员那里得到的答复竟然是“你不能改服务器时间的话,你可以修改你自己的程序呀”,无语。此外还有一个比较严重的安全隐患。
于是把博客搬到了Dreamhost合租的空间上,然后在godaddy买了个域名。新的博客地址是
http://techblog.iamzellux.com/
也就是您现在访问的这个地址
原来的空间我应该会再租一个月,麻烦订阅了原来博客的朋友把订阅列表中RSS换成 http://techblog.iamzellux.com/feed/ 吧
Dreamhost上编译php5
Dreamhost提供的php有不少限制,昨天折腾了一个晚上终于成功地在自己的虚拟主机上编译了php5。
Why
用下来,发现使用自己编译的php5有这么几个好处:
1. 可以自定义内存分配上限,默认只有32M,通过wordpress安装插件的时候经常出现内存不够的问题。
2. 上传文件大小限制也能改,默认只有2M,基本没法通过wordpress传音乐之类的比较大的文件。
3. 使用自己的php后解释执行的进程uid也是自己了,这样就避免了很多nobody用户访问/修改/增加文件所带来的问题。
How to compile
编译和安装的大部分步骤可以参考http://wiki.dreamhost.com/index.php/Installing_PHP5,这里补充一点我碰到的问题和解决方法。
因为我这台dreamhost虚拟主机用的是x86_64,而通过下载的php5的configure文件默认查找的是/usr/lib/下面的共享库,通过–with-libdir=lib64设置查找路径后却无法找到openssl库了,于是我用了个很山寨的方法,把configure脚本里查找libmysqlclient时的路径临时改成了/usr/lib64,然后再改回/usr/lib。
安装脚本开头定义的几个包的名字可能也要修改下,如果下载出现错误的话去上级目录看下最新的包的名字是什么就行了。另外脚本中解压.Z和.tar.gz文件用的是uncompress命令,似乎在我的这个主机上没有安装,改成tar zxf就行了。
How to use
最后说下编译成功后怎么使用,具体方法那个网页上也讲过了,只要把编译后的php.cgi放到/cgi-bin/下然后改下.htaccess即可。
对于子域名,比如我这个techblog.iamzellux.com,参照网页上的说明把整个cgi-bin用符号链接的方式link到子域名的根目录下是最方便的方案,当然别忘了修改.htaccess。