Thursday, December 17, 2009

/\13y3$-|-

其实我一直认为搞计算机的, 特别是那种顶级黑客, 骨子里都是有一种狂放不羁, 玩世不恭的态度的, 带着一些Hacker特有的幽默. 让我们来欣赏其中的一些吧.

0xDEADBEEF: 乍一看, 这只是一个普通的十六进制数, 但你再仔细看看那几个十六进制字母, 是否恍然大悟? 不要小看这样一个数字, 它可是有特殊用途的. 在早期的IBM RS/6000系列电脑里, 如果在内存中新分配了一块地址, 那这块地址中就全部使用"0xDEADBEEF"填充, 这样做可以很好地防止"heisenbug" (这个有趣的bug后面还会讲到) 的出现. 类似于这样的用法还有很多, 统称"Hexspeak", 也就是用十六进制来表示英语单词, 仅有的六个字母肯定不够用, 于是又用数字"0"来表示"O", "1"表示"I" (i的大写形式), "5"表示"S", "6"或者"9"表示"G"或者"g". 这种通过替换英文字母来表示的行为在网上很是流行, 术语叫做"leet", Google也有一个全部使用leet字母显示的神秘主页, 欢迎围观. 有关"0xDEADBEEF"的更多信息可以阅读Raymond的介绍.

heisenbug: 这名字很眼熟对吧? 其实从前有一个量子物理学家叫做Heisenberg... 噢, 这群人居然都敢开物理学家的玩笑了. 其实不然, 这个名字主要还是源于Heisenberg Uncertainty Principle (海森堡测不准原理), 这不禁让我想到高中时马老那闪烁着智慧光芒的眼镜. "heisenbug"用于描述那些当你试图去了解、探查时莫名消失或者改变的计算机软件bug, 在C语言中, 十有八九"heisenbug"都是由于未初始化的变量引起的.

Bohr bug: 这同样是来自于物理学, 不过这次是原子物理. "Bohr bug"是"heisenbug"的反义词, 这种bug很稳定, 不会到处乱跑, 不过通常也隐藏得比较深, 不容易被发现, 典型的是"缓冲区溢出".

schroedinbug: 还是物理学, 我几乎怀疑计算机学是否是由物理学家开创的. 这个bug源于著名的量子物理学实验: Schrödinger's cat (薛定谔的猫), 具体内容我就不细说了, 详情参见《The Big Bang Theory》第一季17集由Dr. Sheldon带来的权威解释, :) "schroedinbug"是一个神奇的bug, 它只会在你查看源代码或者在特定条件下运行程序时才会出现, 真够纠结的, 但这种bug的的确确是存在的.

还有很多这样的非常规bug, Wikipedia上有详细介绍. 无论怎样, Hacker绝对是这个世界上很有趣的一群动物之一.

Thursday, December 10, 2009

编程学习的本质是什么?

很早之前就想写这样一篇文章, 但因为种种原因而耽搁. 今天在思考怎样学习C++时又想到了这个问题, 把它写下来, 作为我自己的一些感想.

作为一个程序员, 真得好好想想我们在学习编程的时候什么是最重要的, 到底什么才是我们追寻的本质? 是把ASP.NET、PHP、JSP、Ruby、Python、C#、Java、C++都学会? 是可以纯熟地使用VS、GTK+、Qt、wxWidgets、Tk来编写图形界面? 是学会各种框架、各种库? 是可以利用JavaScript编写出各种网页特效? 是对于各种浏览器的插件开发了然于胸? 是可以利用系统API开发出各种应用? 在我看来, 这些都不是. 诚然, 以上这些都很有用, 也很重要, 但绝不是一个优秀程序员应该不停追求的.

为什么会有人认为我掌握了这门语言就成了编程高手? 君不见你学的这门语言10年前可能根本不存在, 并且10年后也极有可能不存在. 老有人说IT界知识更新速度太快, 的确, 如果你5年停止学习, 那你在5年后多半就成了一个"废人". 但有一样东西是不会变的, 那就是大师们常说的"内功". 为什么"内功"如此重要? 看看李开复读大学的例子, 1980年李开复在哥伦比亚大学读本科时, 流行的是Pascal和C语言, 以及Fortran, 再看看今天, 除了C语言依旧傲视群雄外, 其它两个早就划归到历史的长河中去了, 只能作为那个年代的特有记忆而保留着. 而30年前李开复在学算法, 在学操作系统, 在学计算机网络, 在学计算机体系结构, 在学离散数学, 30年后的我们依旧需要学习, 依旧需要掌握. 这才是一个程序员需要以及值得追寻的本质.

刘未鹏在"你应当如何学习C++(以及编程)(rev#1)"中提到"一般性的编码实践准则,以及基本的编程能力和基本功,乃至基本的程序设计理论以及算法设计。才是真正需要花时间掌握的东西。"这些都涉及到两个字: 基本. 计算机的基本功无非是刚才说的那几样, 再加上一点数学知识, 但这在很多人眼里却只是考试的时候 (包括找工作时的笔试和面试) 用用而已. 一个真正伟大的程序员会懂得如何通过加强自己的内功, 从而把编程能力发挥到极致.

刚才的言论难免会引来一些实用主义者的辩驳, 工程上的各种新技术、新框架肯定是需要的, 某种程度上来说是要用来吃饭的, 并且也必须借助那些技术才能应用到实际中来. 但凡事都有主次, 这个领域总会不断地冒出新奇的玩意出来, 吸引着好奇的人们去尝试. 就像这个世界也总是充满了各种诱惑, 每个人都可能像海藻那样飘浮不定, 随波逐流. 不过还是有着需要我们坚持的东西. 也许在10年后, 20年后, 你会发现, 你所坚持的东西是多么得宝贵.

Tuesday, December 1, 2009

Tuesday, November 24, 2009

Yet Another Gmail Row Highlight 0.0.1 Released! 键盘流的Gmail利器

昨天花了点时间写了一个Greasemonkey脚本, 功能和上一篇介绍的Gmail - Add Row Highlight (以下简称GARH) 很像, 只不过GARH是当鼠标滑过时高亮, 而我的这个脚本是在使用键盘浏览邮件时高亮小箭头指示的那行. 说得有点复杂, 上图:

Yet Another Gmail Row Highlight

脚本主页是: http://userscripts.org/scripts/show/62644, 不过目前Chrome/Chromium用户还无法使用.

大家多多提意见, 提交bug和建议请到: http://code.google.com/p/fancyweb/issues/list

推荐几个Chrome/Chromium使用的扩展和Greasemonkey脚本

介绍几个我正在使用的用于Chrome/Chromium的扩展和Greasemonkey脚本, 今天Google还公布了官方扩展网站, 相信不久之后Chrome/Chromium扩展将会迅速发展.

  1. Vimlike Smooziee

    Firefox下的Vimperator是我的大爱, 像Vim一样浏览网页, 这是一件既酷又便捷的事情. Vimlike Smooziee即是Chrome/Chromium下的Vimperator, 不过现在的功能还没有后者强大, 只支持基本的操作, 如j、k、H、L、d、u、f、F、gg、G、zi、zo、zz等. 让我们期待以后的发展吧.

  2. gPDF

    有时我们不想下载PDF文件, 而是直接在浏览器里打开看看, 以前的方法是安装Adobe Reader, 这样就会在点击PDF链接时自动使用Adobe Reader在浏览器中打开. 不过Adobe Reader实在是有点庞大, 每次打开都要花很长的时间. 现在使用gPDF扩展可以使用Google Docs来打开, 速度很快, gPDF还提供有Greasemonkey脚本Firefox扩展.

  3. Folders4Gmail

    Folder4Gmail

    这是一个Greasemonkey脚本, 和下一个将要介绍的一样, 属于Firefox扩展Better Gmail 2的其中一个组件. 最新版的Chrome/Chromium已经支持安装Greasemonkey脚本了, 不过还是会发生无法使用某些脚本的杯具. Folders4Gmail脚本的作用是利用Gmail的标签建立树形列表, 如图中所示, 将标签命名为"eBook/Biography", 这样"eBook"就是"Biography"的父目录. 这个脚本对于标签分类很有用处.

  4. Gmail - Add Row Highlight

    这个脚本可以让鼠标滑过的邮件高亮显示, 在邮件很多时可以不至于眼睛看花, XD

Saturday, November 21, 2009

让IPython支持清屏

IPython是一个增强型的Python Shell, 比Python自带的那个功能更强大. 在普通Python Shell里可以通过"Ctrl+l"来清屏, 可在IPython里这个快捷键就不起作用了. 为了达到这个目的, 我们需要对IPython进行一点设置.

这篇文章中我找到了方法, 需要修改"~/.ipython/ipythonrc"文件, 可现在IPython更推荐通过修改"~/.ipython/ipy_user_conf.py"文件来设置IPython. 打开"ipy_user_conf.py"应该可以看到一些示例, 我们需要做的是调用"parse_and_bind()"函数来增加新的键绑定. 在"main()"函数中添加以下语句, 注意你的配置文件中可能已经包含了部分语句, 只需要去掉注释符号就行了.
def main():   
    ...

    import readline
    readline.parse_and_bind('\C-l: clear-screen')
不过这样还不算完成, 需要检查一下"ipythonrc"文件中是否有相互冲突的配置, 比如在我的文件里包含下面一行:
readline_parse_and_bind "\C-l": possible-completions
注释掉即可, 现在进入IPython去试试吧.

Sunday, November 15, 2009

我的吉他手

IMG_9804

晚上7点, 省体门口沸沸扬扬, 有卖荧光棒的小贩, 有倒卖门票的黄牛, 还有手拿门票准备进场的歌迷. 即使提前一个小时还是排了很长的队伍, 原来有这么多喜欢老师的人.

黑色门帘的背后透着光, 似乎掀动它就会进入一个神奇的世界. 陆陆续续有人进场, 坐得有点稀疏, 一大块白布把舞台遮住, 大家都在等待幕布开启的那一刻.

晚上8点, 所有灯光熄灭, 随即就是一阵尖叫. 我拨通了珍妮的电话, 让他听听现场的声音, 问他待会儿想要听什么歌. 刚才的那块大白布现在充当着大荧幕的作用, 在舒缓音乐的伴奏下放映着优美的动画. 当幕布上出现倒计时时, 欢呼更加猛烈了, 在幕布落下的一瞬间, 我看到了老师.

那个穿着白色长裙, 抱着吉他的歌者就是陈绮贞, 原来长裙配吉他可以这样美丽. 低调的老师在唱了几首歌之后才和大家打了一个招呼, 小兰同学说老师说话的声音很甜美.

随后是一段王雁盟的手风琴独奏, 老师再次出现已经换上了英国风格的服饰, 不用说肯定是唱《下个星期去英国》了, 唱完后, 老师说这首歌是写给她曾经的朋友的.

在老师再次下场准备的间隙开始了小虎的吉他Solo, 弹得很是绚丽, 最后还来了一段《Godfather》的经典桥段.

这时灯光亮起, 老师出现在了舞台下方, 结果一群人都冲了上去. 竟然是《等待》, 以前在电脑上听超爱这首, 终于听到现场了, 不过现场的确不是很好唱. 在老师的鼓动下, 全场观众都站起来和老师一起又唱又跳. 在唱《1234567》时, 老师走下了台, 拿着相机给大家拍照.

当老师唱《灵感》, 说这是最后一首时, 全场都安静了, 我们静静地听完了这首歌. 在舞台灯光熄灭的一霎那, 所有人开始高喊老师的名字, 我们一起喊安可, 我觉得这场演唱会的真正高潮是从安可开始的.

终于等到《旅行的意义》了, 我拨通了珍妮的电话, 把手机向外举着. 每一次老师想要离开时我们都使劲地喊, 使劲地叫, 安可声响彻全场. 就这样, 我们换来了5个安可, 我们和老师一起唱, 一起跳.

最后一首, 《会不会》, 每当唱到"我想今夜就这样吧", 我们都会接上一句"不要", 真是默契. 但在老师挥手离开之后, 我们都知道这次是真的结束了, 每个人都选择了保留这份独特的意义.

晚上11点, 演唱会结束. 我几乎从头唱到尾, 再加上喊安可, 弄得嗓子最后疼得不行, 唯一的遗憾是在介绍奇哥时没有喊出"自然卷, 我爱你", :)

我用尽所有美好梦想, 只因你, 我的吉他手.

附上昨晚的演出者:
演唱者 & 吉他手: 陈绮贞
吉他手: 钟成虎、蔡坤奇 (奇哥)
贝司手: 林心怡
键盘: 陈建骐
鼓手: 陈柏州
手风琴: 王雁盟

Friday, November 13, 2009

Blogger解封!

上次是奥运会, 这次是Obama, 看来外国友人的面子就是大啊, 我们这些公民屁都算不上. 我已经很久没有这么畅快地不用代理进入自己的博客了, 嚯嚯~ 大家快来踊跃地评论吧, 哇哈哈~

昨晚看SHE同学女友拍的WCG开幕式以及现场的东东, 那叫一个热血沸腾, 真TM想马上冲到现场去. 世上最痛苦的事情莫过于明明就在我们学校附近, 可就是没机会去亲眼看一场. 算了, 明年去美国看算了, :)

明晚是Cheer的演唱会, 从上个月就期待着了, 看网上公布的曲目, 那叫一个豪华, 几乎所有好听的歌都在里面, 外加5个encore, 真是要爽到爆, 啧啧~ 珍妮这个B有钱买CD都不来一起看, 真是的.

昨天刚刚考完试, 所以最近又有大量时间给我挥霍了. 今天看到Jetpack的邮件列表里已经有官方人士表明态度说关于Jetpack的bug都正在修复, 因此Jetpack还是很值得期待的. 附上一张Jetpack的初步发展路线图 (点击欣赏大图), 可以看到, 他们是准备完全取代现有的Firefox扩展机制的.

Jetpack Roadmap Preliminary

在"美剧达人"君文同学的影响下, 我渐渐养成了每周等待剧集更新的习惯. Heroes也持续看着, 暂时还没有传说中神作的感觉, 不过也有了点兴趣了.

最后, 请各位随时做好Blogger再次被封的准备, Twitter上已经有人建议Obama作为常驻中国大使了.

Thursday, November 12, 2009

Jetpack 0.6: 爱与恨之歌

Jetpack 0.6在10月7日隆重发布, 这一版本带来了两个激动人心的新特性: 菜单和用户配置. 意味着现在可以很方便地添加菜单, 不管是系统菜单, 还是上下文菜单. 而"用户配置"的加入也使得Jetpack扩展对用户来说拥有了可定制性. 这两个功能刚好我都需要用在SNS All in One的下一个版本里, 于是从Jetpack 0.6一发布就开始折腾, 弄了这么几天, 结果是越弄越没有信心. 第一件让人烦心的事我在[解决Jetpack 0.5以上版本在Shiretoko中出错的问题]中已经提到了, 不过我换成Firefox 3.5也就把问题解决了. 接下来才是真正恼火的事情, Jetpack 0.6的jQuery很是抽筋, 导致我以前的代码都得修改, 而且错误也是莫名其妙, 什么"context.createElement is not a function"之类的. 这里有人也遇到了同样的错误, 并且指出了怎样解决, 我就照着别人代码的样子试着改了一下我的代码, 解决了一部分问题, 但还有一部分是整死也解决不了, 这不禁让我开始怀念美好的Jetpack 0.4, 现在的bug真是多.

鉴于Jetpack现在的不稳定表现, 暂时停止SNS All in One的开发, 专心弄我的另一个小玩具, 那些新特性也只有等以后再添加了.

P.S. 今天在Jetpack的邮件列表里发现居然有人看了我的那篇[解决Jetpack 0.5以上版本在Shiretoko中出错的问题], 估计是用Google翻译了再看的.

SNS All in One 0.0.3 Released, 支持Jetpack 0.6

这个版本针对刚刚发布的Jetpack 0.6做了一点修改, 主要是因为Jetpack 0.6的API有点抽筋, 这个我会在下一篇文章中讲到. 此外还修复了一个豆瓣的链接bug.

由于Mozilla已经推出了官方的Jetpack扩展网站: Jetpack Gallery, 以前那个在Userscripts.org上的页面也就停止更新了, 全面转向新的页面: http://jetpackgallery.mozillalabs.com/jetpacks/80, 请以前安装了SNS All in One的各位先把以前的卸载了, 再到新的页面上安装. 卸载方法为: 打开"about:jetpack"页面, 在"Installed Features"标签里找到"SNS All in One", 点击"uninstall"即可. 然后升级到Jetpack 0.6, 到新的页面安装.

如果你是第一次使用SNS All in One, 推荐在安装后阅读"SNS All in One 用户指南".

更多版本信息, 请参阅"SNS All in One Release Notes".

Monday, November 9, 2009

解决Jetpack 0.5以上版本在Shiretoko中出错的问题

2009.10.11, 22:56更新:
经过测试, 发现Shiretoko中Jetpack的某些错误也存在于Firefox 3.5中, 看来这回又是Jetpack的问题了.

2009.10.9, 22:00更新:
经过实际测试之后发现用下面的方法还是不能完全修正Jetpack的错误, 比如jQuery的部分API可能失效, 暂时不推荐在Shiretoko中使用Jetpack 0.5及以上版本.

恐怕很多人还没听过Shiretoko, 一般不用Linux的话是不会察觉到Firefox其实还有一个名字. Shiretoko是Firefox的开发代号, 除了logo少了那只趴在地球上的狐狸外, 其它和Firefox没有差别. 我第一次遇见是在使用Arch的时候, 当时使用源安装的Firefox, 结果打开却叫做Shiretoko, 还以为安错了. 然后我现在使用的Ubuntu 9.04源里的Firefox 3.5也是叫做Shiretoko, 这其实没什么, 只是名字不同而已, 本质都是一样的, 可没想到这会影响Jetpack的使用.

以前我写过一篇叫做[SNS All in One在Jetpack 0.5中失效]的文章, 原因是在Jetpack 0.5中侧边栏无缘无故地消失了, 并且"about:jetpack"页面也有显示错误和链接点击错误, 如下图:
Jetpack Error
开始还以为是Mozilla官方在更新的时候出错了, 因为Jetpack 0.4都是好的. 前天Jetpack 0.6出来了, 当我更新完毕后发现错误依旧, 就开始怀疑是否仅仅是我这里有问题. 打开"Error Console", 一一排查起来.

进入"about:jetpack"页面的第一个错误是"XULApp is not defined", 指向了"file:///home/xiaogaozi/.mozilla/firefox-3.5/cavgighj.dev/extensions/jetpack@labs.mozilla.com/modules/xulapp.js Line: 127", 打开"xulapp.js", 简单分析了下代码, 发现如下的条件语句:
if (Application.name == "Firefox")
{
    XULApp = { ... };
}
else if (Application.name == "Thunderbird")
{
    XULApp = { ... };
}
看来是先判断了程序的类型后再给"XULApp"赋的值, 怪不得在我这里会出错, 因为我的是Shiretoko, 囧. 模仿前面的代码, 再写一个"else"分支, 把在"Firefox"分支中的语句都放到里面:
if (Application.name == "Firefox")
{
    /*
     * Firefox分支
     */
    XULApp = { ... };
}
else if (Application.name == "Thunderbird")
{
    XULApp = { ... };
}
else
{
    /*
     * 这里的代码与'Firefox分支'相同.
     */
    XULApp = { ... };
}
重启浏览器就一切正常了, 也终于可以享受Jetpack 0.6带来的新功能了.

P.S. 前天在发布Jetpack 0.6的同时, Mozilla也正式公布了Jetpack扩展的官方网站: Jetpack Gallery, 终于有了归属地了, 过几天会发布新的SNS All in One, 到时候也会转过去.

Monday, November 2, 2009

在Linux下操纵ARP缓存

直接输入arp命令可以查看当前ARP缓存列表:
$ arp
使用'-d'参数加上IP地址可以删除某个特定的ARP记录, 必须具有root权限:
$ sudo arp -d address
下面是用于清空ARP缓存的组合命令, 来自CU:
$ arp -n | awk '/^[1-9]/ { print "sudo arp -d "$1 }' | bash

Sunday, November 1, 2009

有趣的数学: Collatz conjecture

今天在TL上看到的讨论, 知道了这么一个猜想, 小研究了一下.

Collatz conjecture (考拉兹猜想) 又叫Kakutani's Problem (角谷猜想), 3n + 1 conjecture (3n + 1猜想). 最早由Lothar Collatz在1937年提出, 因此而得名. Collatz conjecture的主要内容是给一个大于0的数n, 如果n是偶数, 则除以2, 否则乘上3再加1, 也就是3n + 1, 如此循环反复, 最终都能等于1. 用Python代码表示如下:
def CollatzConjecture(n):
    """Collatz Conjecture"""
    t = 0
    while n != 1:
        t += 1
        if n % 2 == 0:
            n /= 2
        else:
            n = n * 3 + 1
    return t

2006年, 这个猜想被证明为recursively undecidable (递归不可判定). 下面是将2~9999代入Collatz conjecture得到的最大步骤的图形:

Collatz conjecture

看着还是有那么点规律的, 不知道什么时候才能被证明出来.

Tuesday, October 27, 2009

wxPython & py2exe & Python多线程编程

这两天一直在帮别人弄个小程序, 一个用于辩论赛的计时器. 以前有人做过一个, 但现在规则改了, 估计写程序那人也找不到了, 就打算重新做一个. 开始看了一下程序, 觉得功能挺简单的, 就答应了下来, 事后我还很纳闷地跟小兰同学说我怎么就把这么一个活给接下来了, 照我以前的思维, 这种Window$下的程序我应该直接推掉才是.

不过也管不了那么多了, 既然答应了下来, 就得按照我的风格完成. 首先是GUI库的选择, 他们想要的是那种不用安装就能直接运行的轻量级程序. 这样就最先把C#给淘汰了, 那庞大的.NET Framework是肯定不行的. 其实做这种Win下的小型程序最好的选择就是VC++了, Window$系统对于MFC良好的支持, 使得程序编好之后就可以到处运行. 不过MFC自从大二上学期学过之后, 我就再也没有碰过, 况且我的机器上连VS都没有... 我最想用的其实是Python的GUI库, 主要是我最近也在学这东西, 可以练练手. 如果不用微软的GUI库, 那剩下的选择就主要有wxWidgetsGTK+QtTk这四种了, 它们都是跨平台的, 并且都提供有Python的实现接口. 其中wxWidgets不同于其它三种, 它编写出来的程序具有系统的原生界面 (look and feel native), 而其它的则是在所有系统下都一个样. 于是我选定了wxWidgets作为GUI库, 对应的Python实现是wxPython. 但对于Python这种解释型语言来说最大的限制就在于目标机器上必须也有对应的解释器才行, 这样就跟C#一样了. 不过通过我在网上的进一步了解, 发现了一个叫做py2exe的东西, 它的目的主要就是将你的Python程序打包, 使得在没有安装Python的机器上也能运行. 这不正是我想要的结果吗?! 有了上面的准备, 更让我确定了要用Python去开发的决心.

学习wxPython可以从"How to Learn wxPython"开始, 同时wxPyWiki也有一定的参考价值. 然后就是不断地翻API了, wxPython官方提供的那个Python接口的API我觉得基本没有用处, 虽然全部都是Python的代码, 但由于对于接口的参数没有一点解释, 导致你看了也是白看, 只是知道了这个方法有什么参数而已. 还是看wxWidgets的文档好点, 即使里面是以C++作为实例, 其实很容易转换到Python的. wxWidgets也有类似于GTK+中的Glade的可视化界面绘制工具, 比如wxGlade (这个很明显是模仿的Glade), wxDesigner (这是收费的软件).

在编写过程中还遇到一个小意外, 因为我一直认为这个程序技术上没有什么难点, 只是图形界面我是第一次接触, 可能要花些时间. 结果在第一天就发现这个程序非得用多线程不可... 并且是至少3个线程一起跑. 这就麻烦了, 我根本就没有学过Python的多线程. 怀着搜一搜就会有结果的心态, 找到了Python的threading模块. 以前觉得Python官方的文档挺不错的, 每一个模块写得清清楚楚, 中间还穿插一些示例代码, 让人一下就知道该怎么用了. 但似乎这个threading是个例外, 不仅文字解释模模糊糊, 唯一的几小段示例代码也让人看不懂. 看来这次是碰到硬骨头了, 没办法, 当初自信满满地答应别人一定能在期限之内做完, 硬骨头也得使劲啃. 通常是通过继承threading模块的Thread类来构造线程, 同时你可能还需要重载基类的run()方法. 这些都还比较容易理解, 但我还需要让一个线程中途暂停下来, 等到主进程来激活它. 这个"暂停线程"就把我搞得有点恼火了, 开始一直不能理解为什么其中提供的wait()方法是不带参数的, 没有参数怎么知道该让哪个线程等待呢? 在看过几个例子和自己试验了几次之后, 终于发现wait()是从属于每一个Thread对象的, 看来面向对象的思想还是没有学好... 于是要让一个线程暂停就变得异常简单了:
import threading

class MyThread(threading.Thread):
    ...

    def run(self):
        ...
        self.event = threading.Event()
        self.event.wait()
这里使用的是Event类中的wait()方法. 激活的操作在主进程中进行:
self.thread.event.set()
但Python中不提供彻底终止线程的操作, 每一个线程必须正常执行完之后才能退出. 可以通过设置Thread对象的daemon属性值为True, 使得子线程可以在主进程退出的时候一同结束. 不过这样还是不够"干净", 在主线程没有结束之前, 那些子线程是一直都在运行的, 虽然表面上看不出来, 会白白浪费系统的资源. 于是可以采用让子线程在某种条件下自己结束自己, 具体内容请参考: Python 不支持杀死子线程.

程序写好之后就还剩下打包, 最开始我其实不是用的py2exe, 而是Pyinstaller. 原因在于Pyinstaller可以只生成一个exe文件, 这样程序看起来就会很简洁了. 但用Pyinstaller试过几次之后程序都莫名其妙地无法运行, 只好转战py2exe. 相比于Pyinstaller, py2exe提供了更灵活的配置机制, 但最后生成的文件夹里会包含很多dll和pyd文件, 看着稍微有点乱. 使用py2exe主要是setup.py的编写, 调用的是distutils.core标准库中的setup()函数. setup()函数的参数可以在这里查到, 同时py2exe也附加了一些参数, 其它信息可以参考General Tips and Tricks, 比如怎样自定义程序的图标. 不过故事总会出现波折, 就像公主虽然肯定是和王子在一起, 但也不排除那个王子可能一辈子都是青蛙. 我用py2exe生成的exe文件在没有安装Python的机器上再次出现错误, 在看了"尽量别使用 Py2exe for Python 2.6"这篇文章之后, 才知道是Python 2.6在作怪. 没办法, 为了生成一个通用的exe程序, 只有再去下载Python 2.5, 之后生成的程序就一切OK了, 同时记得把一些py2exe没有复制的dll文件拷过来.

经过这次体验, 深切体会到Window$下的快速GUI开发, 还得靠VS, 拖一拖就都搞定了, 怎一个爽字了得. py2exe虽然也很方便, 但还是尽量在机器上装上Python好点, 毕竟py2exe也不是万能的, 也许会发生某些无法预期的错误. 这个小程序的源代码已经放到了我的Google Code上.

P.S. 在下载Python 2.5的时候, 发现Python官方下载点已经被墙, 只好去其它地方寻觅, #fuckgfw

Tuesday, October 20, 2009

川岛饼干

今天我买了一袋叫"川岛"的饼干, 不知道有没有"津实"的呢? 写这篇博客纯粹是在君文同学的怂恿与鼓励下, 主要是今天一连看了几篇他写的, 有点心神向往, XD

在写下这些文字的时候我的肚子依然处于亚健康状态, 主要原因是今天和某同学闹了别扭, 而不想去食堂吃饭, 不然我也不会遇见"川岛". 觉得好像赌气绝食这种事情只有女人才干, 不过我也就今天试试, 明天是肯定会去食堂的, 否则我的肚子也要抗议了.

最近像预料之中的一样很忙, 白天忙着上课、看书, 晚上忙着写程序、准备讲座. 讲座的内容已经基本定型了, 不知道到时候那些大一的有没有兴趣, 听取了joy与Ray的建议, 适当地加入了一点实际的演示, 提问也相对简单, 接近于计算机常识. 这周主要是把幻灯片弄出来, 中途肯定会去搜集很多素材, 然后下周开始练习演讲. 这是我最担心的一部分, 演示那些什么的我还没什么, 那些东西驾轻就熟, 闭着眼睛都能搞定, 可演讲这东西就有点麻烦了, 这是同时考验我的口才与表演能力的时候. 我得承认我的口才不怎么样, 属于那种在网上可以跟别人说得天花乱坠, 但见了面就不怎么开口的人. 除非我那天晚上说兴奋了, 一般我说兴奋了就跟网上一样能吹了, 希望到时候不要不在状态, 但必要的练习还是需要的.

对了, 前几天"美剧达人"君文同学给我推荐了最新的美剧《未来闪影》(FlashForward), 然后就和TBBT一起下了下来, 看了第一集就被剧情吸引注了, 按君文同学的话来说就是"很有创意". 接着我本着"好东西大家分享, 有困难自己憋着"的精神把这部美剧又介绍给了鸡飞飞同学, 今天刚用QQ邮箱传给他了, 明天问他的观后感.

好久没这么痛快地书写了, 看看自己的博客, 满篇尽是技术文章, "不明真相的群众"看了还以为到了什么鬼地方呢. 我已经决定以后多写些生活上的事情了, 然后还要把君文同学拉来当观众, 呵呵~

Monday, October 19, 2009

Beamer初学小记

Beamer是专业的幻灯片制作工具, 基于LaTeX, 因此学习Beamer你需要首先具备一点LaTeX的知识. 最近要弄一个幻灯片, 遂折腾之, 小记一下.

Beamer其实就是LaTeX的一个文档类 (documentclass), 和普通LaTeX文件一样, 最需要折腾的就是导言区 (preamble), 不过对于中文用户来说, 还有一个额外的东西需要考虑: 怎样才能输出中文. CCT、CJK和xeCJK都行, 不过我们现在有了更方便的选择: CTeXKit, 关于CTeXKit的详细介绍, 可以参考我以前的文章[CTeXKit: 尽情享受中文排版]. 由于Beamer已经占用了文档类, 所以就只能用直接调用宏包的方式了.

建议先从别人的模板开始练习, 这里是Beamer官方提供的几个模板. 然后参考官方文档学习, 我觉得那个文档很不错, 看着很有意思, 其中用一个生动的例子把Beamer的一些要点都介绍了. Beamer不同于普通LaTeX文档的一点就是它可以设置主题, 访问这个网站, 上面有Beamer所有默认主题 (theme) 和颜色主题 (colortheme) 的截图, 方便大家的选择, 另外网上也有很多非官方的主题.

我在使用的时候还遇到一个小问题, 由于我用的是Emacs + AUCTeX, 在每次打开Beamer文件时, AUCTeX会很"贴心"地根据inputenc宏包的编码设置自动改变Emacs的编码, 而我一开始用的是Beamer的官方模板, 其中inputenc的编码配置为latin1, 直接导致我每次重新打开Emacs的时候都会发现其中的中文变成了火星文... 为了解决这个问题, 在网上找了很久, 最后才想到老外可能和天朝人民有点不同, 于是发现刚才说的问题.

相对于广泛使用的PowerPoint, Beamer显得朴素很多, 没有绚丽的动画, 没有五彩的背景, 但Beamer想要表达的是一段演讲的精彩不在于使用的幻灯片有多么得华丽, 幻灯片只是一个用来展示的辅助工具而已, 一切还在于演讲的人, 正如和菜头所说"PPT的流行意味着两件事:一、人们的听力理解能力下降了。二、人们的口头表达能力下降了。"

附上我的Beamer模板:
\documentclass[utf8]{beamer}    % Be care of 'utf8', change it depend on your system.

\mode<presentation>
{
  \usetheme{Darmstadt}
  \usecolortheme{seahorse}
  \setbeamercovered{transparent}
}

\usepackage[english]{babel}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amssymb}

\usepackage{ctex}

% Title Page
\title{\textbf{For Alist}}
% \subtitle{\textbf{}}
\author{Dreamseeker \\ \texttt{gaochangjian@gmail.com}}
\institute{反GFW小组}
\date{2007年12月1日}

% This is only inserted into the PDF information catalog.
% Can be left out. 
\subject{Talks}

% Logo
\pgfdeclareimage[height=1cm]{logo}{pic/logo.jpg}
\logo{\pgfuseimage{logo}}

% For LaN
\newcommand{\LaN}{L{\scriptsize\hspace{-0.47em}\raisebox{0.23em}{A}}\hspace{-0.1em}N}

% Delete this, if you do not want the table of contents
% to pop up at the beginning of each section and subsection:
\AtBeginSection[]
{
  \begin{frame}<beamer>{Outline}
    \tableofcontents[currentsection]
  \end{frame}
}
% \AtBeginSubsection[]
% {
%   \begin{frame}<beamer>{Outline}
%     \tableofcontents[currentsection,currentsubsection]
%   \end{frame}
% }

% % If you wish to uncover everything in a step-wise fashion,
% % uncomment the following command: 
% \beamerdefaultoverlayspecification{<+->}

\begin{document}

\begin{frame}
  \titlepage
\end{frame}

\begin{frame}{Outline}
  \tableofcontents
\end{frame}

\end{document}

Sunday, October 4, 2009

DEB打包指南 (仅针对解释型语言)

这几天一直在研究DEB打包的事情, 搞得有点头大, 这里总结下具体的过程. 我主要参考了PackagingGuide/Complete - Ubuntu Wiki, Debian New Maintainers' Guide这两篇文档, 另外由于我是打包的Python代码, 所以还参考了Ubuntu: Making a .deb package out of a python program, 下面的内容仅针对类似于Python这样的非编译型语言, 而C/C++之类的打包情况可能要复杂一点.

DEB打包的过程就是一个严格按照标准进行的过程. 每一步都有相应的标准, 所以一定要熟悉其中的规则.

  1. 建立一个新的文件夹, 文件夹的命名规则为: <packagename>-<version>, 然后把所有安装时需要的东西都拷进去, 比如: 源代码、图标、文档、版权信息、ChangeLog等. 最后把这个文件夹打包成.tar.gz格式的压缩包, 与该文件夹放在同一级目录下. 这里假设我建立的文件夹叫做alist-0.6.12, 压缩包叫alist-0.6.12.tar.gz, 后面都遵照这里的约定.

  2. 进入刚才新建的文件夹, 执行以下命令:
    ~/alist/alist-0.6.12$ dh_make -e your.maintainer@address -f ../alist-0.6.12.tar.gz -c gpl
    
    这里主要是对打包进行初始化, "-e"选项后跟的是维护这个DEB包的人的Email, "-f"则是指向了上一步建立的压缩包, "-c"指明你使用的证书. Ubuntu用户如果没有dh_make(8)命令, 请安装dh-make软件包.

    成功执行后将会在上一级目录中生成一个.orig.tar.gz结尾的文件, 比如这里是alist_0.6.12.orig.tar.gz, 这个压缩包里的内容和alist-0.6.12.tar.gz是一样的. 还会在当前目录下建立一个叫做"debian"的文件夹, 这里面包含的文件就是打包最关键的地方了.

    请一定注意, dh_make(8)只能执行一次, 如果你执行完一次之后发现有错误, 那就要重新回到第一步了, 切记不要重复执行dh_make(8), 否则可能发生无法预料的错误.

  3. 现在进入刚才自动建立的"debian"文件夹, 你应该会看到很多文件, 正如前面所说, 这是打包过程中最关键的一步.

    千万别被其中繁杂的文件吓着了, 其实很多都是用不上的, 根据你的实际需要, 保留一部分就行了. 最先需要筛选的就是那些以.ex和.EX结尾的文件, 这都是些示例 (example) 文件, 对于大部分人来说, 可以直接删除, 但是如果你需要用到man page、自启动脚本等其它的一些功能还是可以参考一下的. 我这里就是把这些文件都删除了.

    现在看起来是不是清爽多了? 接下来是"docs"和"README.Debian"这两个文件. "docs"主要用于告诉dh_installdocs(1)命令哪些文件需要放到/usr/share/doc/[packagename]下, 而"README.Debian"则说明了原始文件和打包后的文件有哪些差别, 如果你都不需要用到, 那这两个文件也可以直接删除.

    "copyright"文件很容易理解, 默认生成的文件中会有一些提示信息, 你照着填写就行了. 或者你可以选择不按照它的写法, 采用自己的版权信息文件.

    上面介绍的文件都是可有可无的, 剩下的则很重要了. 先来看看"changelog"文件, 下面是原始内容:
    alist (0.6.12-1) unstable; urgency=low
    
      * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>
    
     -- xiaogaozi <gaochangjian@gmail.com>  Thu, 01 Oct 2009 22:35:45 +0800
    
    我们从第一行开始看起, 首先是软件包名, 这个没什么问题, 接着括号里的是版本号: 0.6.12-1, 最后为什么多了一个"1"呢? 这是用来和原始版本号区分的, "1"代表包维护者的修改次数, 比如源文件没有变化, 仅仅是打包的时候某些地方改变了, 那就修改最后这个数字. "unstable"这部分填写适用于安装的发行版的名字, 比如Ubuntu就是jaunty、intrepid、hardy之类的. 最后的"urgency"一般保持不变.

    中间这部分就是详细写上该版本有哪些改动了, 格式同普通的ChangeLog一样, 每行的开头为两个空格 + 一个星号 + 一个空格.

    "changelog"的最后一行为包维护者的名字、Email和修改日期. 这里需要注意的是修改日期的格式必须为RFC822标准所规定的, 也就是date -R输出的格式. 可这个日期的格式书写起来着实复杂, 所以这里推荐使用dch(1)命令来编辑"changelog"文件, 它不仅会自动修改日期, 还会自动帮你加上星号. Ubuntu用户可以安装devscripts软件包来得到dch(1), devscripts软件包还包含了其它很多有用的工具.

    接着是"control"文件. 下面是原始内容:
    Source: alist
    Section: unknown
    Priority: extra
    Maintainer: xiaogaozi <gaochangjian@gmail.com>
    Build-Depends: debhelper (>= 7)
    Standards-Version: 3.8.0
    Homepage: <insert the upstream URL, if relevant>
    
    Package: alist
    Architecture: any
    Depends: ${shlibs:Depends}, ${misc:Depends}
    Description: <insert up to 60 chars description>
     <insert long description, indented with spaces>
    
    这里面包含的内容就是我们平常所看到的DEB包的简介了. 每一项的具体解释请看这里, 这里简单介绍下. "Section"为软件包的类别, 普通的应用程序可以填写"utils". "Architecture"对于Python这种平台独立的解释型语言可以填写"all", 而编译型的则需要具体一点.

    "rules"文件就是一个Makefile, 安装的时候全靠这个了. 根据实际情况修改"binary-arch"项, 把不需要的功能都注释掉. 其中用到了很多以"dh_"开头的命令, 这些都在debhelper软件包中, 你可以查看man page来了解命令的作用. 对于脚本语言, 因为不需要编译, 所以必须把包含"$(MAKE)"的行都注释掉. 下面重点是编辑"install"项, 因为刚才注释掉了"$(MAKE)", 所以现在必须手动建立一个目录用来存放安装后的文件, 在"$(MAKE)"下一行写上:
    mkdir -p $(CURDIR)/debian/[packagename]
    
    记得将"[packagename]"替换成你对应的名字, "$(CURDIR)"指代的是"debian"的上一级目录, 这里即是"alist-0.6.12"目录. 剩下的就看你的具体情况了, 比如你需要把源文件都放到/usr/share/[packagename]下, 就用cp写一行命令, 需要在菜单里放置一个图标, 就把[packagename].desktop文件放到/usr/share/applications下.

    现在还剩下两个文件: "dirs"和"compat". "dirs"填写的是那些make install时没有建立的目录, "compat"则是debhelper软件包的版本号, 一般不需要修改.

    看到这里, 关于"debian"目录下的文件已经全部了解了, 下面来完成打包的最后一步.

  4. 从"debian"目录中回到上一级目录, 执行以下命令:
    ~/alist/alist-0.6.12$ debuild -k8A94AB78
    
    上面的"-k"选项后跟的是你的PGP Public ID, 关于PGP的内容, 我会在下一篇日志中介绍. 执行完以后, 你就得到了梦寐以求的DEB包啦! 赶快试试安装的效果吧~

打包DEB的过程还是有点复杂的, 尤其是第一次接触, 会遇到很多陌生的知识. 相对来说, Arch的AUR就显得方便多了.

Saturday, September 26, 2009

批量获取Twitter好友feed的小程序

2010.1.19更新:
现在不推荐使用这种方法来获取Twitter好友的feed, 因为经过试验当好友数达到一定数目时, 获取的feed列表是不完全的.

曾经介绍过怎样通过Google Reader备份和搜索好友的Tweets, 其中关键的一步就是获取所有Twitter好友的feed, 这样就能通过Google Reader订阅了. 今天抽了点时间把以前那个code2string.py稍微改进了下, 现在只需要告诉程序你的Twitter用户名, 它就会自动完成获取feed和转换中文的工作了. 请猛击这里下载fetch_twitter_feed.py, 使用方法如下:
$ python fetch_twitter_feed.py username1 [username2 ...]
支持多用户名, 运行成功后会生成后缀为.opml的文件, 像以前一样, 导入Google Reader就行了.

Friday, September 25, 2009

Songbird无法启动的解决方法

今天在一台电脑上下载了最新的Songbird, 结果一运行就出现了严重的错误, 错误提示如下:
*** glibc detected *** ././songbird-bin: free(): invalid pointer: 0xb138bc20 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7d98604]
/lib/tls/i686/cmov/libc.so.6(cfree+0x96)[0xb7d9a5b6]
/usr/lib/libvisual-0.4.so.0(visual_mem_free+0x21)[0xb0dd3141]
/usr/lib/libvisual-0.4.so.0[0xb0dca407]
/usr/lib/libvisual-0.4.so.0(visual_plugin_get_list+0x73)[0xb0dca5e3]
/usr/lib/libvisual-0.4.so.0(visual_init+0x291)[0xb0dd9ec1]
/usr/lib/gstreamer-0.10/libgstlibvisual.so[0xb0e36273]
...
郁闷, 以前在我的电脑上明明一点错误都没有. 然后在这里找到了引发错误的原因, 只要删除一个软件就行了:
$ sudo apt-get remove libvisual-0.4-plugins
不清楚这里面的具体因素, 也许是那个库文件和Songbird调用的库文件有冲突吧.

Wednesday, September 23, 2009

程序员专用博客推荐: is-Programmer.com

那天在看OSD Lyrics作者之一的TigerSoldier博客时发现了这个网站: http://www.is-programmer.com/, 首先是被这个域名吸引的, 很有个性, 呵呵~ 接着注册了一个账户详细了解了一下, 发现这个博客还是挺强大的, 主要特色是代码高亮和LaTeX数学公式支持, 这些对于程序员来说都是挺重要的, 另外博客的定制性还不错. 具体效果可以看看我刚注册的博客: http://xiaogaozi.is-programmer.com/

P.S. 在看到OSD Lyrics后, 心又开始痒了, 想大学期间怎么也得做点东西出来. Ray, 我们好久一起开发哇?

Thursday, September 17, 2009

经典游戏推荐: NetHack

原文发表于「桃源」: http://linux.cuit.edu.cn/?p=571

NetHack是一款经典的D&D (Dungeons & Dragons, 龙与地下城) 类型的角色扮演游戏, 有着20多年的历史. NetHack的前身是Hack, 而Hack的前身是Rogue. NetHack名字中的Net并不代表这是一个联网的游戏, 而是表示这20多年的开发主要是通过网络的合作. NetHack影响了以后很多游戏的设计, 其中包括暴雪的经典游戏Diablo (暗黑破坏神). 有人说如果妳一生祇打算做一件事的話,玩 NetHack 。

NetHack本身是一个纯字符界面的游戏, 全部由键盘操作. 你一定觉得这会很困难, 其实NetHack上手是很容易的, 基本的按键操作和Vim类似. 正是因为这种大量使用键盘操作进行交互的模式, 使得以后采用类似键盘操作的软件都被叫做roguelike. NetHack具有丰富的内涵, 游戏中的对话、背景介绍、典故很多出自各种经典的奇幻与科幻小说, 如Tolkien的《The Lord of the Rings》 (魔戒), Douglas Adams的《The Hitchhiker's Guide to the Galaxy》 (银河系漫游指南) 等. 《The Cathedral and the Bazaar》 (大教堂和市集) 与《How To Become A Hacker》 (如何成为一名黑客) 的作者, 著名黑客Eric S. Raymond曾经在《The Art of UNIX Programming》中介绍了Rogue, 并且为NetHack写了一篇官方指南: A Guide to the Mazes of Menace (Guidebook for NetHack). 还有一篇有趣的指南, 叫做I Keep Dying And Dying And Dying, What Should I Do? (我死了又死继续死, 我到底做错了什么?).

NetHack一共有13种职业: Archeologist (考古学家), Barbarian (野蛮人), Caveman/Cavewoman (穴居人), Healer (治疗者), Knight (骑士), Monk (僧侣), Priest/Priestess (牧师), Rogue (盗贼), Ranger (游侠), Samural (武士), Tourist (旅行者), Valkyrie (女武神), Wizard (法师). 第一次玩需要简单地了解下基本的按键操作, 在游戏中按"?"可以显示帮助菜单. 对于新手来说, 建议玩NetHack的discovery mode, 这样可以"死后满状态原地复活", 只需要在命令行下加上"-X"参数就行了. 下面是一张NetHack的截图:

NetHack CLI

NetHack是一个跨平台的游戏, 支持Linux、Mac、Window$等, 还可以在Emacs里玩. 如果你不习惯纯字符的界面, NetHack还提供了2D和仿3D的图形界面. 如下图:

NetHack for Window$ Vulture's Eye

你可以在这里下载NetHack, Ubuntu用户可以使用以下命令安装纯字符版本:

$ sudo apt-get install nethack-console

SNS All in One在Jetpack 0.5中失效

今天升级到了最新的Jetpack 0.5, 结果发现SNS All in One失效了, 侧边栏也不见了. 经过一番调查, 发现是Jetpack 0.5自身的问题, 并且也有人和我一样遇到了类似的问题, 只能等待Mozilla来解决了. 如果已经升级到0.5了, 卸载之后重新安装Jetpack 0.4即可正常使用.

Saturday, September 12, 2009

doubanclaimff76e601cce066d3

豆瓣还真是麻烦, 认领个Blog还需要写篇日志, 并且必须包含'doubanclaimff76e601cce066d3'这样一串字符. 应该学习下Google, 验证的时候只需要在HTML里加一行代码就行了.

Wednesday, September 9, 2009

美国是怎样监管网络的?

今天在读Andrew S. Tanenbaum的著作《Computer Networks》时, 某页讲到美帝国主义使用一种叫做Carnivore的东西来监管网络, 顿时千头万绪涌上心来, 感动得热泪盈眶, 原来我们并不孤独... 我于是去详细了解了一下Carnivore到底是什么.

Carnivore由FBI (Federal Bureau of Investigation, 联邦调查局) 设计, 是美国的第三代网络监视软件, 前两代分别是Etherpeek和Omnivore (后来改名为DragonWare Suite). Carnivore的主要功能是监视互联网和电子邮件, 运行在Window$操作系统上, 由FBI放在每一个ISP (Internet Service Provider, 互联网服务提供商) 那里. 这样一个极容易侵犯个人隐私的东西在美国这个极讲究人权的国家是肯定会遭到反对和抗议的, FBI做出解释说Carnivore只是具备监视的功能, 但它并不会时刻监视所有的互联网信息, 而只会监视特定的对象, 监视的对象也必须由法院命令决定, 比如某些恐怖分子. 后来迫于舆论的压力, FBI将Carnivore改名为DCS1000 (Digital Collection System) 这样一个比较温和的名字. 2005年FBI宣布停止使用Carnivore, 但社会依然相信FBI只是把Carnivore替换成了其它类似的商业监控软件. 有关Carnivore更详细的介绍, 可以阅读博闻网的一篇文章: Carnivore网络监视软件的工作原理.

现在看来, 美帝国主义也不过如此, 还是比不上天朝的宇宙超级无敌河蟹墙: 金盾工程.

Wednesday, September 2, 2009

关于搭建ARM工具链 (ARM Toolchain)

以前写过一篇[怎样搭建ARM交叉编译环境?]的文章, 那时的我还以为arm-linux-gcc编译器是一个独立的软件, 可以直接获得. 但在Google搜索的结果里怎么也找不到一个独立的正式的页面, 只有些零散的下载点. 于是我有点怀疑自己的理解是否正确, 隐约记得有人通过编译的方式得到arm-linux-gcc, 这是不是和GCC有着某种联系呢? 接着又换了几个关键词进行查找, 发现原来平时使用的arm-linux-gcc就是由特定的编译参数编译GCC而得到的. 原来这一切没有现成的, 而是需要自己手动去编译呢. 不过这个编译过程实在是有点繁琐, 有兴趣的可以参考这两篇文章: Building a GNU/Linux ARM Toolchain, The GNU Toolchain for ARM targets HOWTO.

2010.5.26更新:
uClinux的网站上也发现了搭建ARM工具链的详细步骤 ("build-arm-linux-*"文件), 并且提供了搭建过程中所需的各种源码包, 算是比较齐全的吧, 推荐一下.

对于一般使用者来说, 实在是没有必要去自己编译, 我把3.4.14.3.2两个版本的ARM工具链放到了网上, 方便以后的使用.

Tuesday, September 1, 2009

ARM板烧写文件系统失败的总结

这几天一直被一个很恼火的问题纠结着, 需要给块板子烧写文件系统, 但使用我前段时间介绍过的Linux下的DNW试了很多次都失败了, 又试了一个老外写的s3c2410_boot_usb (这个传输速度比DNW慢很多) 还是不行, 在SHE电脑上的XP下用Win版的DNW依旧不行, 可用某师兄的电脑烧的时候又每次都可以, 囧. 另一个师兄笑说这是人品问题, 呵呵~ 不过我就是不相信有那么离奇, 没道理只能在别人的电脑上才能成功, 一定会有解决办法的. 终于让我发现了一个传输上的小细节: 地址, 这时我才想到每次烧的时候我都没有指定地址, 而是使用的程序内部的默认地址. 于是试着修改了一下dnw2的源码, 把地址替换了, 结果, 嘿嘿, 肯定是成功了三, 哇哈哈~~~ 不过困扰了几天的问题居然是这么一个小细节...

为了以后的使用方便, 我又进一步完善了dnw2的源码, 使得可以通过命令行参数来指定地址, 最新打包好的程序: dnw2_linux_fixed_20090901.tar.gz. 同时我的修改版也得到了原作者Fox的认可, 并放到了他的SVN仓库里. 最后需要特别感谢Fox的贡献.

Sunday, August 23, 2009

取消mget的提示

mget是FTP中批量下载文件的命令, 在使用的时候可能会在每一个文件下载之前都询问你是否下载, 这样太麻烦了, 得一直按着Y然后回车, 要有1000个那估计下完手都不是自己的了. 稍微看了一下ftp的man page, 其中有一个prompt命令, 就是专门用来切换使用mgetmput时是否提示的. 好了, prompt之后就可以放心地不去管mget了.

在Linux下使用DNW

2009.9.1更新: 请下载dnw2_linux_fixed_20090901.tar.gz, 详情请参见[ARM板烧写文件系统失败的总结].

DNW是通过USB烧写软件到ARM板的工具, 由三星公司开发, 可是这个软件只有Window$版本. 那天想把Linux内核烧进去, 就在网上找了很久看有没有Linux下的替代品. 最后在ARM9之家论坛上发现有人重写了个简单的命令行版本, 源代码可以从Google Code上下载: dnw2_linux_latest.tgz, 或者下载我的修正版本: dnw2_linux_fixed.tar.gz, 主要修正了一些编译警告. 编译的时候要依赖libusb-dev, Ubuntu用户可以直接安装:
$ sudo apt-get install libusb-dev

Tuesday, August 18, 2009

在Google Reader中备份和搜索好友的Tweets

Twitter in Google Reader

2010.1.19更新:
现在不推荐使用这种方法来获取Twitter好友的feed, 因为经过试验当好友数达到一定数目时, 获取的feed列表是不完全的.

来自Lifehacker的文章: Backup and Search Your Friends' Tweets with Google Reader [Twitter], 介绍了怎样在Google Reader中备份和搜索好友的Tweets.

  1. 首先打开这个网址: http://tw.opml.org/get?user=xiaogaozi&folder=1, 把user改为你的Twitter用户名, 然后将网页的源代码保存为.xml或者.opml文件.
  2. 进入Google Reader中的"Manage subscriptions"页面, 在"Import/Export"标签页中将刚才保存的文件上传上去就行了.

这时你所有Following的好友都会显示在Google Reader中, 你能看到他们以往的Tweets, 也能通过Google强大的搜索功能进行检索.

不过如果好友名是中文的话, 就会被转换为Unicode代码, 我写了个脚本可以将Unicode代码转换回字符: code2string.py. 假设你刚才保存的文件名为xiaogaozi_twitter.opml, 那么执行:
$ python code2string.py xiaogaozi_twitter.opml
然后会生成一个trans_xiaogaozi_twitter.opml文件, 上传这个就行了. 如果没法执行这个脚本, 还有一种简便的方法, 直接在Google中搜索那串Unicode代码就行了, Google会自动将它转换为字符, 百度无此功能.

Saturday, August 15, 2009

SNS All in One 0.0.2 Released

校内改名人人了, 以前的http://m.xiaonei.com/也用不了了, 这个版本把校内的网址改成了: http://m.renren.com/, 如果你以前安装的时候勾选了"Auto-update this feature", 那过一段时间Jetpack会自动更新的, 可以不用管. 或者可以到这里重新安装最新版本.

Saturday, August 8, 2009

Open Web Tools Directory

Open Web Tools Directory
Open Web Tools Directory是Mozilla Labs推出的用来收集各种Web开发工具的网站, 网站采用HTML 5中的canvas技术编写, 动画效果很是绚丽, 如果你的浏览器还不支持HTML 5, 也可以查看普通页面. 同时你可以通过这个表单提交那些没有包含在网站上的工具, 我已经把Vim提交上去了. 网站后续还会加入社会化的功能, 比如打分、排名之类的, 值得收藏.

Friday, August 7, 2009

SNS All in One 0.0.1 Released

以前总在想, 能否像TwitterFox那样方便地更新我的校内, 查看校内好友的新鲜事和豆瓣的友邻广播呢? 我需要实现这样一种功能, 能够在我想看的时候很方便很快速地看到, 而其它时间则隐藏起来. 自从了解了Jetpack, 我就在思考着能否实现这个想法. 经过几天的编写, 就有了SNS All in One这个Jetpack扩展.

SNS All in One是一个Jetpack扩展, 主要使用Jetpack的slide bar (侧边栏) 特性, 现在实现的功能就像上面说的一样, 可以查看手机校内的所有内容, 以及豆瓣的友邻广播. 截图如下:

SNS All in One - 豆瓣
查看豆瓣友邻广播

SNS All in One - 校内
查看手机校内

功能很简单, 点击侧边栏的图标可以刷新页面. 由于侧边栏不能复制链接, 可以选择拖动链接到Firefox主窗口中打开. 不过需要注意下, 这个扩展只支持Firefox 3.5及以上版本.

欢迎提供各种反馈, 请将意见提交到Google Code或者Userscripts.org的Discussions页面上, 也可以给我发送邮件: gaochangjian[at]gmail[dot]com, Because it's your web.

Introduction to Jetpack

Jetpack
JetpackMozilla Labs推出的一种全新的Firefox扩展方式, 官方的一句话很好地解释了Jetpack的作用:
In short, Jetpack is an API for allowing you to write Firefox add-ons using the web technologies you already know.
这篇文章旨在全面但不深入地介绍Jetpack的特性, 帮助用户和开发人员更好地了解Jetpack.

抄袭下可能吧的经典绿条, 希望Jason Ng同学不要介意.

一、怎样获得Jetpack?

不管你是运行还是开发Jetpack扩展, 都需要首先安装Jetpack的Firefox扩展 (这句话有点绕, 可以把后一个扩展看作是Jetpack的API包), 就像平时安装Firefox扩展一样, 下载安装完毕后重启Firefox就行了.

二、对于普通用户, Jetpack该怎样使用?

只要你安装了刚才的扩展, 当打开包含Jetpack程序的页面时Firefox就会自动提醒你是否安装:
Install Jetpack

点击"Install..."以后, 可能会转到一个Firefox的警告页:
Jetpack Warning
不用紧张, 只要你是从可信赖的站点安装的就没有问题, 这时需要等到代码加载完毕, 然后就可以点击按钮安装了, 也可以勾选上"Auto-update this feature", 以便自动更新.

当显示"Installation Successful"之后, 一个Jetpack扩展就算安装完毕了, 这同时也是Jetpack不同于普通Firefox扩展的一点: 安装后不需要重启, 删除也是.

在哪里查看所有安装的Jetpack扩展呢? 请打开about:jetpack页面, "Installed Features"里就显示了全部信息, 点击"uninstall"即可删除扩展.

由于现在Mozilla还没有专门为Jetpack建立扩展页面, 所以目前推荐到Userscripts.org的Jetpack页面查找扩展.

三、开发人员指南

如果你是一名Web开发人员, 或者有过Web开发的经验, 那你基本上已经具备了开发一个完整的Jetpack扩展的能力. 开发Jetpack扩展所需的技术和工具有: JavaScript, HTML, CSS, jQuery, Firebug, 以及你喜爱的编辑器.

如果你想快速直观地了解Jetpack的功能, 可以观看官方的这个视频:

Mozilla Labs Jetpack - Intro & Tutorial from Aza Raskin on Vimeo.

Jetpack现在还处于发展阶段, 只能实现一些比较小的功能, 比如对剪贴板 (clipboard), 消息提示 (notification), 侧边栏 (slide bar), 状态栏 (status bar), 菜单栏 (menu bar), 标签 (tab)等的操作. 同时, Jetpack包含了jQuery和封装好的Twitter库, 以及实现JS的跨域访问.

about:jetpack里有完整的API索引与示例, Jetpack Demos也包含了各种示例, MozillaWikiLabs/Jetpack版块有很多关于Jetpack的资料和示例代码, 还有Jetpack的Google Groups与IRC (#jetpack@irc.mozilla.org) 供大家讨论.

四、结语

Userscripts.org网站底部有这样一句话: Because it's your web. 期待Jetpack的发展, 让Web变得越来越舒适.

Monday, July 27, 2009

CTeXKit: 尽情享受中文排版

这是一个始于2003年的古老项目, 那时的人们只是在零零散散地为LaTeX中文排版做着贡献. 2009年5月, CTeX正式在Google Code上建立ctex-kit项目, 标志着整合中文排版的开始.

作为汉语使用者, 一定会为在TeX/LaTeX中排版中文伤透脑筋, 幸好还有很多默默奉献的人们, 他们的努力为我们解决了这些苦恼. CJK, CCT, xeCJK, 这些熟悉的名字, 到现在我还能记得当初用上xeCJK时的喜悦与兴奋. 当我又发现了CTeXKit时, 我知道, 中文排版的荣耀来临了. CTeXKit带给我的是从未有过的舒适, 一切都是这样自然、平滑, 我豁然发现, 原来中文排版是如此值得享受的一件事情.

以下是CTeXKit的简介:
CTeXKit提供了一个统一的中文LaTeX文档框架, 底层支持CCT、CJK和xeCJK三种中文LaTeX系统. CTeXKit提供了编写中文LaTeX文档常用的一些宏定义和命令.
说简单一点, CTeXKit整合了现在几乎所有的中文排版宏包, 使得中文排版不再是一件费力的事情.

安装CTeXKit的步骤很简单, 先从Google Code上下载:
$ cd ~/texmf/tex/latex/
$ svn checkout http://ctex-kit.googlecode.com/svn/trunk/ ctex-kit-read-only
$ sudo mktexlsr
然后看你是用的CCT, CJK, 还是xeCJK, 这里只讲下我使用的xeCJK. 刚才svn下来的CTeXKit包含了最新版的xeCJK, 但需要XeTeX 0.9995.0以后版本才能使用. 我安装的TeX Live 2008里的XeTeX的版本为0.999.6 (很奇怪的版本号, 不知道该怎么和前面的比较...), 编译会报错, 应该是版本太低了, 可以到这里下载xeCJK 2.2.15, 这个版本是支持小于0.9995.0的最后一版xeCJK. 再把刚才svn里的xeCJK删了就行了, 所有步骤如下:
$ cd ~/texmf/tex/latex/
$ unzip ~/xecjk-2_2_15.zip
$ cd ctex-kit-read-only
$ svn rm xecjk
$ sudo mktexlsr

该如何使用呢? CTeXKit提供了三种额外的document class: ctexart, ctexbook, ctexrep, 你既可以直接使用这三种, 也可以调用相应的宏包:
\documentclass{ctexart}  % 推荐使用这种

或者

\documentclass{article}
\usepackage{ctex}
然后是字体设置, 默认的配置在ctex/cfg/ctexopts.cfg.template文件中, 共有4种字体选项: nofonts, cjkfonts, winfonts, adobefonts. 注意你的系统中一定要有相应的字体文件, 比如说使用adobefonts就必须有Adobe的四套中文字体: Adobe Song Std, Adobe Heiti Std, Adobe Kaiti Std, Adobe Fangsong Std. 以上都搞定以后, 就可以编译了. 同时CTeXKit还提供了很多选项可以设置, 详细内容请参考ctex/doc/ctex.pdf文件.

这里有一份我的TeX文件模板, 可以作为参考. 顺便预告下, 近期将会推出LaTeX Tips专题.

Saturday, July 25, 2009

通过Minicom接收文件的临时解决方法

前段时间我写了一篇[Minicom传送文件问题], 解决了通过minicom把文件传送到ARM板的问题. 前天SHE同学需要一些数据, 因此我要把ARM板上的文件传到我的电脑上. 本来以为在有了以前的设置之后, 接收文件 (receive file) 应该是顺理成章的事, 结果我把zmodem, ymodem, xmodem, kermit, ascii全部试完都不行. 真是恼火, 在网上搜了很久也没有发现什么好的方法可以解决. 暂时用的这个邮件列表里的方法:
$ cat < /dev/ttyUSB0 > data
不过这只对于纯文本有效, 要是想传二进制的就不行了. 不过也有人提出了使用uuencode将二进制文件先转化为纯文本文件的方法:
$ uuencode binary_file /dev/stdout > uu_file
$ uudecode -o binary_file uu_file
这样就能用刚才的方法传送二进制文件了. 不过还是没有直接通过minicom传送方便快捷, 希望以后能找到好的解决方法.

注: Ubuntu使用uuencodeuudecode需要安装sharutils软件包.

2009.9.1 更新:
如果板子上有网线接口的话可以选择通过FTP的方式传输, 这种方法既满足了传, 也满足了接, 还是很不错的. 不过我一般比较懒, 不想把我的网线拔来拔去的, 不到万不得已是不会用这招的, 呵呵~ 还有, U盘、SD卡也行, 只要板子满足条件.

Thursday, July 23, 2009

调教Firefox 3.5

昨天换上了Firefox 3.5 (以下简称FF 3.5), 是因为昨天才发现比较好的过渡方法, 是不是有点out了...
$ sudo apt-get install firefox-3.5

当我怀着兴奋与喜悦的心情打开FF 3.5时, 我不禁发现这页面是不是有点走样了. 如下图:
New Tab Button
那个打开新标签的图标很碍眼地挡在了第一个和第二个标签之间, 而且由于Vimperator的缘故, 当打开新标签的时候, 那个加号图标不会像正常的那样一直跟着走, 不过对于Vimperator来说这个图标也用不上. 于是我想把它隐藏了, 还原成以前的样子. 在这篇帖子的帮助下解决.

首先进入你的Firefox的Profile folder, 比如我的是: ~/.mozilla/firefox-3.5/5p41abxo.default, 然后修改chrome子目录下的userChrome.css文件, 没有则新建. 添加以下内容:
.tabs-newtab-button
{
  display: none;
}
重启浏览器即可.

接下来出现问题的是"我最喜爱的Firefox扩展"之一的TwitterFox, 很可恶的, FF 3.5的隐私模式 (后面还会再次谈到它) 的快捷键和TwitterFox默认的弹出窗口快捷键是一样的. 不过更可恶的是当我想要改变TwitterFox的默认快捷键时, 它却一直弹出这样一句话: New keyboard shortcut affects only new windows. 没怎么搞懂这句话是什么意思, 反正就是改不了. 在Twitter上发了问题, 不过没人回我. 但我还不想就这样罢休, 终于让我找到了方法. 打开"about:config", 搜索"twitternotifier.togglePopup", 将Value改为"P,,control alt"就行了, 你可以根据你自己的情况修改一下, 我这里把快捷键改为了Ctrl+Alt+P.

最后来说说FF 3.5新增的隐私模式 (Private Browsing). 在我看来, 这是一个完全鸡肋的功能. 虽然我很喜欢隐私模式的浏览方式, 但是FF 3.5设定的这种方式简直太"别出心裁"了, 每次从隐私模式退回来的时候原来的所有标签都要重新加载一次, 这个不仅浪费了时间, 还可能因此丢失掉以前页面上的一些东西, 所以说是完完全全的鸡肋. 相比之下, 我就更喜欢Chrome/Chromium的隐私模式 (incognito), 而且那个图标也挺酷的. 这里有一篇详细比较FF 3.5和Chrome 3的隐私模式的文章.

继续试用FF 3.5中, 昨天TX因为FF 3.5频繁假死已经快抓狂了...

Saturday, July 18, 2009

怎样搭建ARM交叉编译环境?

2009.9.12 更新:
请转到[关于搭建ARM工具链 (ARM Toolchain)]查看.

今天师兄叫我再传一份当初我搭好的交叉编译环境时, 才发现以前都没记下来, 害的今天又去网上找了好久才找到原来的方法. 这里简记之.

我搭的这个ARM交叉编译环境很简单, 可以支持C和C++的编译. 先在这里下载以arm-linux-gcc开头的压缩包, 然后解压放到对应的目录就行了.

然后你可以选择修改PATH变量的方式把bin目录添加进去, 或者像我一样在现有的PATH里面放上符号链接. 这样就算搭建完毕了.

Minicom传送文件问题

好了, 有了上一篇文章的方法, 现在可以好好来调试程序了. 该怎么把PC上的文件放到板上去呢? 方法倒是很多啦, 由于板上自带了USB和SD卡接口, 所以可以通过U盘和SD卡拷过去. 板上还有一个网线接口, 通过网络也行, 挂载PC的NFS. 但是... 最简单的方法当然是通过minicom直接传送啦! (我以前怎么没想到...)

可我在选定好文件, 确定传送之后, 画面就一直卡在那了, 看来是不能传送. 这次又是LinuxSir.Org帮助了我, 请看: minicom无法上传文件,需要做什么设置吗?, 荣耀属于话语精简的3楼:
$ sudo apt-get install lrzsz
原来是缺少了一个软件, 这下好了, 障碍基本上扫清了, enjoy coding!

USB转串口线在Linux下的使用问题

由于这台台式电脑上神奇般的没有串口接口, 导致我调试ARM板那是相当得麻烦, 昨天从师兄那借了跟USB转串口的线, 就方便多了, 哇哈哈~ 不过这线很贵的说...

师兄跟我说在Win下需要先安装驱动, 我就在想了, 就这么一根线居然还要驱动... 于是有点担心没有Linux下的, 到官网上去看了看, 还挺不错的, Win、Linux、Mac都提供有. 下了几个试试 (因为不知道这根线的具体型号), 结果都出现了严重的编译错误, 在试着修正了一番后, 还是没有安上, 囧.

抱着试一试的心态去Google了下, 发现还真的有. 来自LinuxSir.Org的帖子: 在linux下如何驱动usb转串口线?, 6楼的回复道出了真谛啊~ Linux根本就不需要再额外安装驱动了! 当你把USB线插上时, 请输入以下命令:
$ dmesg | grep 'usb'
...
[14364.501032] usb 6-2: new full speed USB device using ohci_hcd and address 3
[14364.672886] usb 6-2: configuration #1 chosen from 1 choice
[14364.673609] usb 6-2: Detected FT232BM
[14364.673667] usb 6-2: FTDI USB Serial Device converter now attached to ttyUSB0
看到最后一句没? 现在就找到了设备名了, 然后再设置一下minicom就行了.

从这个故事我们了解到, 有时候看看内核的输出还是很有好处的, :)

Thursday, July 16, 2009

飞檐走壁

中国的网民真幸福, 能在不知不觉中练就各种"神功", 渐渐得我们拥有了高强的武艺.

这真是一个复杂的国度, 昨晚跟小淫魔讨论了很久逃脱这里的方法, 今天看到Picobird的Ubuntu 中 UltraVPN 以及 AlonWeb的配置和笑来的域名被114劫持的解决方案之一, 还有很萌的绿坝娘T-shirt. 哪里才是自由的归宿? 这里混沌一片, 想起TX以前的邪恶轴心, 挺搞的~

现在的我已经学会好几套"神功"了, 代理、VPN、修改hosts, 反正换着用, 期待逃离的那一天...

Tuesday, July 14, 2009

Chromium极速安装指南

$ sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 4E5E17B5
$ cat /etc/apt/source.list.d/chromium.list
# Chromium Daily Builds
deb http://ppa.launchpad.net/chromium-daily/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/chromium-daily/ppa/ubuntu jaunty main
$ sudo apt-get update
$ sudo apt-get install chromium-browser

设置GNOME Terminal启动的大小

我有个习惯, 开机第一个启动的程序就是Terminal, 而默认的窗口太小, 于是我还要加上另一个重复性的操作: 调整窗口的大小. 一直在想要是能自动调整大小就爽了, 那天去找了下, 在这篇文章中找到了方法.

点击菜单System -> Preferences -> Preferred Applications, 将System选项卡下的Terminal Emulator改为Custom, 然后在Command处填写:
gnome-terminal --geometry=132x43

当然, 这只是针对用快捷键来打开Terminal的, 你要是用鼠标点的话, 直接加上后面的参数就行了.

javascript:void(0);

如果你想在网页上放一个链接, 但又不想点击的时候让浏览器跳转, 大部分人的做法都是:
<a href="javascript:void(0);" onclick="someFoo();">Click!</a>

我也是. 不过那天在网上搜的时候无意发现了这篇文章: a href=”javascript:void(0);” — avoid the void, 文章作者说他以前一直都是用上面的方法来实现, 不过有一天他发现在IE中会导致错误, 于是他本着生命在于折腾的原则, 花费了半天大好青春来寻求解决方法, 最后在微软的网站上找到了一条建议: 请避免使用这种方法! 正确的做法是:
<a href="#" onclick="someFoo(); return false;">Click!</a>
关键就在于那个"return false;"所起的作用.

有没有人遇到过相同的情况?

为Blog增加了"划词搜索"

在安装SmarterFox这个扩展时发现官方网站上还提供了一个有用的Widget: FinderFox, 可以实现鼠标选定一些词之后在Google、Wikipedia、Twitter等中搜索, 或者Tweet选定的部分, 如下图:
FinderFox

于是把这个功能加到了我的Blogger上, 在模板里添加以下JS代码:
<script type="text/javascript">
var finderfoxConfig = {
version: "1.0.0",
key: "ed1abb67243a4ca30000012276fecd47"
};
document.write(unescape('%3Cscript type="text/javascript" src="'+
('https:'==document.location.protocol?'https://ssl.':'http://')+
'finderfox.smarterfox.com/finderfox.js"%3E%3C/script%3E'));
</script>
此外, 还可以到网站上自己去定制一些搜索引擎.

Tuesday, June 30, 2009

不翻墙观看YouTube的方法

荣耀属于: 不用翻墙访问YouTube的方法[可行][转]

方法是修改本地host文件, 将YouTube的地址解析到谷歌中国的IP, 即这样几行:
203.208.39.104 www.youtube.com
203.208.39.104 gdata.youtube.com
203.208.39.104 upload.youtube.com
203.208.39.104 insight.youtube.com
203.208.39.104 help.youtube.com
203.208.39.104 youtube.com
  1. Linux

  2. 修改/etc/hosts文件, 添加上面几行, 然后重启浏览器.
    $ sudo ifdown eth0
    $ sudo ifup eth0


    7月6日更新:
    Ubuntu 9.04默认使用上面的命令会出现找不到eth0的错误提示, 原因在于ifdownifup这两个命令的配置文件 (/etc/network/interfaces) 里没有对于eth0的定义. 修改一下即可:
    $ cat /etc/network/interfaces
    iface eth0 inet dhcp
    上面的inetdhcp请根据你具体的网络环境设置, 详细参数可以参见man interfaces.


    7月6日再更新:
    刚才重启了下, 发现在改了上面那个文件之后电脑不会自动连上宽带了, 于是又改了回来... 暂时还不知道这是为什么. 大家还是用下面的命令吧:
    $ sudo ifconfig eth0 down
    $ sudo ifconfig eth0 up


  3. Window$

  4. 修改%SystemRoot%\system32\drivers\etc\hosts文件, 同样添加上面几行, 然后也是重启浏览器.... 禁用本地连接后再重开应该能行, 重启电脑也行, 我没试过, 有知道的各位麻烦说下.

YouTube

Monday, June 29, 2009

转到FeedBurner了

为了更好地统计RSS, 昨天转到了FeedBurner上, 请各位都换成新的Feed地址: http://feeds.feedburner.com/xiaogaozi. 用FeedBurner还有一个附加功能, 那就是可以翻墙看Blogger了, 嘿嘿~ 只是如果要想评论的话, 还是得手工翻墙才行. 昨天发现Blogger也有邮件提醒新评论功能的, 如下图:
reply

比较有名的同类服务还包括国内的Feedsky, 只是Feedsky不会翻墙...

Saturday, June 27, 2009

MySQL的自动补全

今天在群上和双眼波同学讨论了下MySQL的自动补全, 我们想要达到的功能是既能补全数据库和表名, 还要能补全SQL语句.

然后就去搜索了下, 在这里发现了一个选项: --auto-rehash, 说是可以实现, 看了下man page的描述确实也是. 于是就加上了试试, 结果刚开始一直不行, 在一个偶然的情况下, 发现只有在使用USE命令后, 自动补全才会开启.

另外刚才那个选项MySQL默认是加上了的, 所以也没必要再人工写出来了.

Friday, June 26, 2009

怎样修改MAC地址?

前段时间小妮子的电脑出现了一个很神奇的问题, 校园网连上几分钟就会自动断开, 需要重新连接才行. 并且在Window$和Linux下都有这样的问题, 在进行了各种排错工作——还包括一次重装Win——之后, 问题依旧. 最后请了一个高手来看看, 高手先捣鼓了一阵, 然后就决定改下MAC地址试试, 结果就这样奇迹般地好了.

这是什么原因呢? OK, 我想这个问题恐怕也只有我们学校的人能解决了. 这既不是一个软件问题, 也不是一个硬件问题, 这是一个很操蛋的问题... 伟大的学校网络中心可能最近在抽筋, 就一不小心把小妮子电脑的MAC地址封了, 或者是分配的IP和某人的冲突, 反正当发现原来问题是这个的时候, 我很无语...

不过这次也学到了怎么改MAC地址, 在Win下的方法我还真没见过以前, 比之前用某软件改方便多了. 方法就是在"设备管理器"里的网卡属性里"高级"选项卡里有一个叫做"Locally Administered Address"的东东, 它的值就是MAC地址, 只是少了分号间隔.

Linux下的就交给我了, 在参考了"[精彩] 如何修改mac地址让它一直生效?"这篇文章后, 成功修改. 永久修改的方法是在/etc/rc.local这个文件里添加如下信息:
/sbin/ifconfig eth0 down
/sbin/ifconfig eth0 hw ether 00:11:22:33:44:55
/sbin/ifconfig eth0 up
eth0是你的网卡编号, 如果你只有一个网卡, 那就是eth0了. 如果只是想暂时修改, 就直接依次运行上面的命令就行了.

Tuesday, June 23, 2009

隆重推荐VC精华资源: 计算机科学经典著作

今天无意发现的, 这个资源绝对称得上重量级, 不知道发布者收集了好久...

里面包含了几乎所有你知道的和你不知道的经典书籍, 大部分为PDF格式, 少数为CHM. 不多说了, 反正不下会后悔的: 《计算机科学经典著作》

Monday, June 22, 2009

收集你的Firefox扩展

Amo Fox
前段时间Mozilla在Firefox扩展网站上添加了一个新功能: Collections. 这是一个为注册用户提供的个性化服务, 将你喜欢的Firefox扩展都添加到你自己创建的Collections里, 同时还能把这些分享给别人.

觉得这样很方便, 以后走到哪都可以看到我的常用扩展了. 这是小高子的Collections, 右侧的"小高子的Web 2.0"栏目里也添加了这个链接. 同时从侧面显示了我是一个Firefox重度依赖者, 希望Chrome也能有好的扩展出现.

Sunday, June 21, 2009

我喜欢顺藤摸瓜

前几天听Dew的翻唱专辑, 听到一首《Daisy》, 就去查原唱是谁, 然后就找到了Bonnie Pink, 在看了点简介后就又去把Bonnie Pink的精选下了. 原唱和Dew的翻唱区别还是有点大的, Dew的伴着钢琴的点缀很舒缓, 有着慵懒下午的感觉, Bonnie Pink则是木吉他加上架子鼓, 歌声很悠扬.

发现我一直都有这样的习惯, 喜欢一个东西就会沿着某种线索一直找下去. 今天在Ray那看到李开复的Twitter, 进去发现了Blog地址, 就又进去顺便放到Google Reader里. 这里面隐含着一种牛人欣赏的多半也是牛人, 精华收集的一定也是精华的思想, 这能帮助我找到很多有价值且高质量的资源. "物以类聚, 人以群分", 这样也难免把自己局限在某个特定领域, 我还是比较欣赏不同领域的人共同交流而蹦出的火花, 像华裔数学家陶哲轩 (虽然他本人不认为自己是华人...) 就很喜欢同不同领域的人一起合作, 他得菲尔兹奖的成果是属于数论范畴, 而他自己却是一个调和分析以及偏微分方程领域的专家, 原因在于他乐意同其它研究领域的人合作. 顺带想起了《Beautiful Mind》里Nash调侃说数学家千万别跟搞生物的一起讨论.

本文初发于校内, 由于严重不满校内的火星编辑器, 今天跑去给校内客服提建议去了, 看什么时候才能有回复. 很久以前也提过一次, 从此没有音讯...
我提交的校内建议

以FastCGI的方式运行PHP

让PHP以FastCGI的方式运行可以最多提高10倍左右的速度, 还是很诱人的, 那天为了测试这个性能提升有多少, 就在Ubuntu里配置了一下.

首先需要安装一个软件包, 如果按上一篇文章[使用Ubuntu源安装LAMP]里讲的过程安装好的话其实就已经不用再安了, 需要的就是php5-cgi这么一个包.

然后需要打开Apache的actions模块, 因为后面的配置需要用到. 以下操作基于源安装的Apache:
$ cd /etc/apache2/mods-enabled/
$ sudo ln -s ../mods-available/actions.* .

最后就是修改配置文件了, 参考了FastCGI的官方文档. 添加如下配置:
# FastCGI for PHP
FastCgiServer /usr/lib/cgi-bin/php
AddHandler php-fastcgi .php
Action php-fastcgi /cgi-bin/php
需要注意, 最后一句中的/cgi-bin/是一个别名, 即下面一行配置指定的:
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
经过上面的一系列配置, 当php后缀的文件运行时就会自动以FastCGI的方式运行了. 还可以使用php_sapi_name这个函数测试是否配置成功, 如果运行输出的是cgi-fcgi就证明成功了, 失败通常输出apache2handler.

运行的时候需要注意两点, 一是要给PHP文件加上可执行 (x) 权限, 另一个就是PHP文件所在目录需要在Apache中设置+ExecCGI选项:
Options +ExecCGI

这时就可以使用ab工具来测试了:
$ ab -c 50 -n 1000 http://localhost/fcgi-bin/test.php
经测试, 一个简单的字符串输出的PHP程序才只有处理复杂操作的C++程序性能的2/3, 看来差距还是挺大的.

使用Ubuntu源安装LAMP

以前写过一个编译安装LAMP的文档, 放在我的Google Code的texsky项目里 (关于texsky的详细介绍参见以前的一篇文章[又建了一个项目 -- texsky]), 前段时间觉得有源还是用源好点, 毕竟更新会更加方便.

用源就简单了, 只需要记住软件包名就行了, 以下包名在9.04下测试通过:
$ sudo apt-get install apache2.2-common mysql-server php5 php5-cgi php5-cli php5-mysql
真怀疑为了一点扩展性和性能提升去折腾编译值不值得...

如果还需要FastCGI的支持, 再加上两个软件包:
$ sudo apt-get install libapache2-mod-fastcgi libfcgi-dev
顺便提一下libfcgi-dev这个包, 刚开始以为这个包只是编译的时候需要用到, 因为它的描述是: Header files of FastCGI, 所以误以为只有头文件而已. 结果运行的时候由于没安这个包就出错了, 研究了一下才发现这个包里还包含了一些so文件 (好阴险), 自然是运行时需要用到的了, 安上以后运行一切正常.

Friday, June 19, 2009

Ubuntu下安装Bugzilla

Buggie
今天整了一下Bugzilla, 过程那叫一个痛苦, 缘起还得从MySQL讲起.

由于Bugzilla依赖MySQL, 偏偏9.04里面依赖的版本是5.0, 而我以前装的是MySQL 5.1... 好吧, 肯定是免不了要把以前的MySQL卸载了的, 那就装个5.0吧 (埋怨自己干嘛非得追新...). 这时一件很悲剧的事情发生了, dpkg错误, 这是我最不愿意看到的东西, 依稀仿佛记得以前整AUCTeX的时候也遇到过类似的情况, 当时因为错误严重, 差点就重装了. 好了, 这次算我运气好, 咱又遇上了:
Aborting downgrade from (at least) 5.1 to 5.0.
dpkg: error processing /var/cache/apt/archives/mysql-server-5.0_5.1.30really5.0.75-0ubuntu10.2_i386.deb (--unpack):
subprocess pre-installation script returned error exit status 1
Selecting previously deselected package mysql-server.
Unpacking mysql-server (from .../mysql-server_5.1.30really5.0.75-0ubuntu10.2_all.deb) ...
Processing triggers for man-db ...
Errors were encountered while processing:
/var/cache/apt/archives/mysql-server-5.0_5.1.30really5.0.75-0ubuntu10.2_i386.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
咱可是那种遇到困难就退缩的人? 显然不是! 俗话说"困难像弹簧, 你弱他就强", 这等小事算个啥啊, 在无敌的Google大法面前颤抖吧, 哇哈哈~ 下面隆重介绍Google大神的答案:
$ sudo rm /var/lib/mysql/debian-5.1.flag
主要原因是这个文件影响了MySQL的降级. 然后重新安装MySQL就行了, 我用的是下面的命令:
$ sudo apt-get -f install

经历了MySQL的煎熬, 现在开始安装Bugzilla, 中途会有对话框弹出来叫你设置, 需要输入MySQL中root用户的密码 (这就得要求安装的时候MySQL是启动的, 因为它会去建数据库和表), MySQL中新建的用户bugzilla3的密码, Bugzilla管理员的邮箱 (同时也是账户), 管理员的密码. 顺利完成之后, 麻烦事才刚刚开始.

先来讲讲怎么用Bugzilla. 首先你需要一个Web服务器, 我用的Apache. 如果你没有修改Apache的默认配置的话, 通过网址http://localhost/cgi-bin/bugzilla3/index.cgi就可以访问了. 但现在显示出来的只有文字, 图片、CSS什么的都不能访问, 这时就需要在你在Apache下设置的网站根目录下放置一个链接, 指向/usr/share/bugzilla3/web/:
$ ln -s /usr/share/bugzilla3/web/ bugzilla3
这个链接的名字是固定的.

修正: Bugzilla安装好之后会在/etc/apache2/conf.d下放置一个叫做bugzilla3的链接指向/usr/share/doc/bugzilla3/examples/basic.conf, 这是一个包含VirtualHost的配置文件, 经测试, 会影响其它VirtualHost的访问. 于是我将那个文件的内容合并到了最初始的配置文件里, 并移除了链接, 同时删除其中一行:
Alias /cgi-bin/bugzilla3 /usr/lib/cgi-bin/bugzilla3

使用刚才安装时输入的邮箱就可以登录管理员账户了, 当然, 会有一系列的东西等着你去设置, 毕竟默认配置都是不完美的.

Bugzilla使用邮箱作为账户, 如果有人来注册新账户, 在输入自己的邮箱之后, 服务器就会发送一封邮件给刚才的邮箱进行确认. 这时才发现我电脑上的邮件服务器还没配好, 就顺便折腾了一下. 我用的是Postfix, 不知道为什么, Ubuntu源里安装好的Postfix在用sendmail发邮件的时候会找不到main.cf这个配置文件, 到/etc/postfix下一看才发现根本就没有... 我也懒得自己去配了, 就用的别人的一个例子, 需要安装postfix-doc这个包, 安好之后会有/usr/share/doc/postfix-doc/examples/main.cf.default.gz这么一个文件, 解压, 把文件拷过去重命名就行了. 注意: 不要使用/usr/share/postfix/main.cf.dist这个文件, 里面的配置是不完全的, 我最开始就是用的这个, 结果运行的时候出现了一堆错误. 这时再用sendmail试试, 又发现了一个新错误:
postdrop: warning: unable to look up public/pickup: No such file or directory
在Ubuntu官方论坛的一篇帖子里找到了解决方法:
$ sudo mkfifo /var/spool/postfix/public/pickup
$ sudo /etc/init.d/postfix restart
这下就可以顺利通过sendmail发送邮件了, 不过我电脑上发出去的邮件地址还有点难看, 等有时间再弄一弄, 呵呵~

Bugzilla刚用, 配置等以后再研究了, 到时候肯定还会写一篇讲配置的.

P.S. 这是我目前为止用的标签最多的一篇文章.

Tuesday, June 9, 2009

使用Minicom的几个问题

Minicom是Linux下调试嵌入式板的利器, 和Window$下的超级终端属于同一类软件.

刚开始用的时候遇到了两个问题, 一个是中文问题. 如果你的默认环境是中文的话, 安装好的minicom会自动使用中文界面, 但是用中文显示会有一些比较严重的问题, 还是用英文好点. 我起先把环境变量LANG设置成en_US.UTF-8, 结果还是显示的中文, 在看过一篇文章后有了解决方法:
$ env LANG=en_US minicom
不知道这个为啥就行... 做成alias最好, 免得每次都输这么多.

第二个问题是键盘输入问题, 默认情况下minicom是不会响应键盘的, 在另一篇文章中知道了原因, 原来需要修改一个配置, 将Serial port setup下的Hardware Flow Control改成No就行了.

Monday, May 18, 2009

Songbird, Living in the Music

Jetpack
首先恭喜下Blogger成功再次被墙, 致使我现在都得翻墙才能写日志了, 草泥马的河蟹!

今天要推荐下我用了一段时间的音乐播放器Songbird, 强大的Metadata修改, 方便的歌曲库管理, 和Firefox一脉相承的Add-ons功能, 都让我在使用中倍感舒适. 下面是截图:
Songbird

现在我使用的插件有:
  • LyricMaster, 显示歌词, 对中文歌曲支持不是太好, 我电脑上的中文歌只有一首显示了...
  • MediaFlow, 显示专辑图片, 如上图, 很好看, 和iPod很像
  • Song Notifier, 歌曲变换时会有提示

Friday, May 8, 2009

让SVN忽略特定的文件

修改~/.subversion/config文件中的global-ignores选项即可, 顺便记下Linux下的通用匹配格式:
$ man 7 glob

Saturday, May 2, 2009

Ubuntu中安装iBus输入法框架

首先到这个页面下载iBus的OpenPGP key, 验证以后设置第三方源, 下面的是9.04的, 其它的可以到刚才那个页面看:
# iBus
deb http://ppa.launchpad.net/ibus-dev/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/ibus-dev/ppa/ubuntu jaunty main
安装如下的软件包:
$ sudo apt-get install ibus ibus-pinyin ibus-gtk
ibus-gtk很重要, 否则就没有光标跟随了. 最后将默认输入法换成ibus:
$ im-switch -c
正确选择以后, 重启就行了.

9.04的新功能: 改进版screen

screen
screen是一个很强大的工具, 可以模拟多个终端. 刚安好的screen看上去和普通终端没有什么区别, 但利用高可配置性, 便能展现出强大的一面. 由于screen配置的某些语法晦涩难懂, 非一般人所能折腾也. 这下好了, Ubuntu 9.04带来了已配置好的screen, 并且还能通过提供的菜单添加/删除一些功能.

Ubuntu中文论坛的roylez金主席也提供一个很不错的配置, 有兴趣的可以参考下.
P.S. 这位是一个CLI狂人.

在Linux下使用IE的两种方法

Internet Explorer 6
由于老妈需要在IE中处理一些事情, 但家里的电脑又被我折腾得只有一个Ubuntu了, 在老妈的强烈要求下, 我研究了下怎么在Linux下用IE. 这里我们无视IE 8.

本来使用IE最简单同时也是最完美的方法就是装一个虚拟机, 但这无形中又增加了老妈的学习难度, 对于她来说, 最好的方法就是在桌面上放一个经典的e图标, 然后双击就行了, 这就得请Wine出场了.

1. IEs4Linux
这是最著名的直接使用IE的方法, 安装步骤也很简单, 可谓人性化. 需要注意的是官网上写的在Ubuntu下安装的方法已经很久没有更新了, 其实不必设置文中提到的第三方源, 直接用官方源安装好winecabextract以后, 下载最新的IEs4Linux, 解压运行其中的ies4linux安装脚本就行了.

现在的IEs4Linux可以安装IE 5, 5.5, 6, 7这4种版本, 但IE 7使用的是IE 6的界面, 貌似是因为作者也还没搞定怎么才能用上IE 7的界面.

2. 直接Wine原生IE 7
也许你认为一开始我们就应该用这种方法了, 干嘛还要绕那么大个圈去用什么IEs4Linux. 可是如果你曾经试过直接Wine个IE 7的话, 你就会知道那可是一个很麻烦的事情, 完全不同于Wine普通的软件, IE 7果然是非同一般...

具体步骤可以参考国外的一篇文章[Wine Review: IE 7 on Linux with Wine], 并且需要用到最新版本的Wine, 就不能用Ubuntu官方源了, 换上Wine的第三方源 (仅适用于Ubuntu 9.04):
$ wget -q http://wine.budgetdedicated.com/apt/387EE263.gpg -O- | sudo apt-key add -
$ sudo wget http://wine.budgetdedicated.com/apt/sources.list.d/jaunty.list \
> -O /etc/apt/sources.list.d/winehq.list
$ sudo apt-get update
$ sudo apt-get install wine
其它版本的Ubuntu源可以参照这篇文章中的说明. 另外上面那篇国外的文章中提到的需要到XP中拷贝的dll文件也可以到这个网站下载.

用这种方法安装的IE 7虽然拥有了好的界面 (一些细节还是有问题), 但由于在我的电脑上经常无响应, 并且显示中文也有点问题, 就弃用了.

最后献上最强大的Internet Explorer for Mac

Monday, April 27, 2009

美化了一下下Ubuntu

感谢大鹏和杨杨同学的推荐, Ubuntu Studio的图标不错, usplash很大很震撼.
$ sudo apt-get install ubuntustudio-theme ubuntustudio-icon-theme ubuntustudio-gdm-theme \
> ubuntustudio-wallpapers usplash-theme-ubuntustudio

另外推荐下现在使用的GDM: Arc-Colors GDM-Walls, 见下图, 来自LinuxTOY的推荐.
Arc-Brave GDM

近期的一些杂感

由于这几周都在忙着做事, 有好几篇blog想发却一直搁置着, 今天就把它们都写到一起吧.

先说攻防吧, 最近又出新题了还没去看, 对于注入这种层次的题目暂时不想了, 其它的什么编程题还能应付下, 无奈比例不大, 不能让队伍再靠前一点. 因为某题需要用到PHP的编程, 于是在重拾Emacs时发现默认是不支持PHP的高亮的, 这种事情肯定有人想到并解决了的, 安装php-mode就行了, Ubuntu可以直接apt-get install php-mode, 也可以自己到SF上去下载, 然后修改.emacs:
;; PHP mode for Emacs.
(require 'php-mode)
(add-hook 'php-mode-user-hook 'turn-on-font-lock)

以前的文章[参加三叶草Linux方向考核的一些总结]中介绍了一个叫做template的Emacs插件, 可以实现新建特定扩展名的文件时自动加载模板的功能, 像现在的某些IDE一样. SHE同学前段时间因为用Vim写汇编时必须重复地输入那些又长又难记的SEGMENT而苦恼, 问我Vim是否能自动加载模板. 查了一下, 还挺简单的, 这个不需要任何插件就能实现了. 修改.vimrc:
" Template for Vim.
autocmd BufNewFile *.asm 0r ~/.vim/templates/template.asm
注意中间那个是数字0, 而不是字母o. 把你的模板放在相应的文件里, 如果需要其它类型的模板修改扩展名就行了. 以上方法来自LinuxSir.Org.

由于最近需要经常测试网页, 愈发觉得用当前的Firefox调试很麻烦. 最让人痛苦的一点就是如果调试页面崩溃了, 还要连带影响我的正常浏览页面, 不得不一次又一次地重启. 实在是忍受不了之后 (看来我还是一个很能忍的人), 决定来一个专业一点的调试方法. 来自Mozilla的一篇文章:
Setting up an extension development environment
介绍了如何利用Firefox打造调试环境, 解决我前面那个问题的方法就是使用多用户配置文件, 实话说, 用了这么久Firefox还真不知道可以多用户运行的... 使用如下命令启动Firefox:
$ firefox -no-remote -P dev
这时应该会弹一个选择用户配置文件的窗口, 因为以前没有dev这个配置文件, 需要新建一个才行. 建好以后再用上面的命令运行的时候就会使用dev, 而不是默认的default了, 这样新开的浏览器与我之前打开的就不会相互影响了. 那篇文章还介绍了Firefox的一些配置调整以适应调试的需求和一些有用的调试插件, 这里强烈推荐Firebug, 看网页结构那叫一个爽.

最后, 那天看到一个很搞的命令: vrms. 为什么说它搞呢? 先看看这个缩写的全称吧: Virtual Richard M. Stallman. 那这个命令是用来干什么的呢? 号称可以找出你电脑上所有的非自由 (non-free) 软件, 晒下我的结果, ORZ... 内核也算?
                Non-free packages installed on LAN

fglrx-amdcccle Catalyst Control Center for the ATI graphics accelerat
fglrx-kernel-source Kernel module source for the ATI graphics accelerators
fglrx-modaliases Identifiers supported by the ATI graphics driver
human-icon-theme Human Icon theme
linux-generic Complete Generic Linux kernel
linux-restricted-modules- Non-free Linux 2.6.27 modules helper script
linux-restricted-modules- Restricted Linux modules for generic kernels
nvidia-173-modaliases Modaliases for the NVIDIA binary X.Org driver
nvidia-177-modaliases Modaliases for the NVIDIA binary X.Org driver
nvidia-71-modaliases Modaliases for the NVIDIA binary X.Org driver
nvidia-96-modaliases Modaliases for the NVIDIA binary X.Org driver
rar Archiver for .rar files
tangerine-icon-theme Tangerine Icon theme
tango-icon-theme Tango Icon theme
Reason: Creative Commons Attribution-ShareAlike 2.5 License
xorg-driver-fglrx Video driver for the ATI graphics accelerators

Contrib packages installed on LAN

msttcorefonts Installer for Microsoft TrueType core fonts
nvidia-common Find obsolete NVIDIA drivers

15 non-free packages, 0.9% of 1628 installed packages.
2 contrib packages, 0.1% of 1628 installed packages.

Wednesday, April 15, 2009

WebQQ rocks!

我真的火星了, 今天突然想去试试传说中的WebQQ. Wow! 那一瞬间我就做了一个决定, 不用客户端了. 它已经具备了我想要的所有功能, 包括邮件、动态表情. 虽然聊天记录不能自动保存, 不过也好过那个只能记录50条的设计. 我也不需要发图片和传文件, 视频就更不用了. 这下又多一个常驻我的浏览器的标签了, 顺便抱怨下Vimperator 2.0不能支持FF主题的问题, 只能用默认的了...

Wednesday, April 8, 2009

MySQL与空格、中文的不解之缘

学了那么久数据库, 昨天才开始用MySQL折腾, 我忏悔. 结果刚用上就遇到很多问题, 第一个比较难解决的就是中文问题, 待我从头说起.

这件事情的起因是我想批量把数据导入到表中, 于是用了LOAD DATA LOCAL, 结果居然编译的时候没有开启这个功能... 在这篇文档的说明下, 发现需要添加--enable-local-infile编译参数, 于是又重新编译安装了一次. 然后继续导入, 还是出错, 怀疑是数据文件中用的是空格而不是tab分隔的关系, 又把空格全部替换为tab. 依然不能通过, 这次貌似是中文问题, 好吧, 我去Google, 又在另一篇文档中找到了解决, 这次需要修改MySQL的配置文件, 在其中的[mysql]组中添加default-character-set = utf8. 这样总算行了吧? 非也, 还是有错. 又把思路放在了那些tab上, 是不是只能有一个tab啊? 因为我用的是两个. 结果只保留一个之后, 我靠, 真的就行了! 这也太变态了吧, 不能用空格也就算了, tab还只能用一个, 多了少了都不行, 这下总算见识了.

Monday, March 30, 2009

如何利用网络学习

来自Lifehacker的文章: Top 10 Tools for a Free Online Education [Lifehacker Top 10], 文中介绍了Google Code University, 适合CS (Computer Science) 专业学生学习. 通过Personal MBA网站来学习MBA课程. 如果你是一个Linux新手, 那么可以看看Ubuntu Guide, 里面详细介绍了Linux下的各种软件和一些历史故事. Mango Languages的课程可以帮助你学习11门外语 (其实还有一门是汉语...). Lifehacker的另一篇文章还收集了各种乐器的网上教程, 前提是你的听力得很好, XD. 最后是包括MIT (麻省理工学院), Stanford University (斯坦福大学), Carnegie Mellon University (卡耐基梅隆大学), University of California, Berkeley (加州大学伯克利分校), Princeton University (普林斯顿大学), University of Washington (华盛顿大学) 等众多学校的各种网络课程, 顺便抱怨下为何中国的高校如此封闭.

Saturday, March 28, 2009

Gmail也能用Twitter!


上篇介绍了Twitter的一个桌面客户端, 昨天猛然发现Gmail也能用Twitter! 来自Lifehacker的介绍, TwitterGadget满足了我的需求, 除了没有提醒功能以外, 其它都比桌面客户端好上不少.

如果你想使用的话, 需要先打开Gmail Labs中的Add any gadget by URL功能, 然后在Settings的Gadgets里添加以下网址: http://www.twittergadget.com/gadget_gmail.xml, 这样就可以使用了.

Friday, March 27, 2009

Twitter桌面客户端——Gwibber

Gwibber
自从开始用Twitter, 就用上了LinuxTOY上介绍的Gwibber, 但默认主题不是很好看, 又换上了一老外制作的主题: Gilouche, 还挺漂亮的.

Ubuntu用户可以参考官方Wiki进行安装, 用的是Launchpad的PPA源. 并且Gwibber已经进入了9.04的官方源, 这下可方便多了.

免费字体网站

Lifehacker的文章Killer Typography Tools and Free Font Downloads [Fonts]里收集的, 发现好看的英文真是多, 相比之下中文就要少很多了, 毕竟中文文字既复杂又繁多.
我比较喜欢第二个和第三个网站, 第二个的字体都很好看, 第三个则很有趣, 都是些电影标题的字体, 比如我去下了个The Lord of the Rings的.

对blog布局的一点小改进

把原来长长的标签列表替换成了标签云, 其实早就想弄了, 可是因为懒, 一直没弄... 早上闲来无事, 就下决心弄了. 代码全部参考这篇文章的, 只有颜色和字体部分修改了下. 啧啧~ 这下可以节省很多空间了.

然后就是把常用的Web 2.0服务聚合在一起了, 这样访问起来也方便点, 至少方便了我自己, XD

下面是标签云的代码, 因为那篇文章没有排版, 所以就贴一下, 代码的具体位置还是要参考原文:
/* Label Cloud Styles
----------------------------------------------- */
#labelCloud
{
  text-align: center;
  font-family: sans, arial, sans-serif;
}

#labelCloud .label-cloud li
{
  display: inline;
  background-image: none !important;
  padding: 0 5px;
  margin: 0;
  vertical-align: baseline !important;
  border: 0 !important;
}

#labelCloud ul
{
  list-style-type: none;
  margin: 0 auto;
  padding: 0;
}

#labelCloud a img
{
  border: 0;
  display: inline;
  margin: 0 0 0 3px;
  padding: 0
}

#labelCloud a
{
  text-decoration: none
}

#labelCloud a:hover
{
  text-decoration: underline
}

#labelCloud li a {}

#labelCloud .label-cloud {}

#labelCloud .label-count
{
  padding-left: 0.2em;
  font-size: 9px;
  color: #000;
}

#labelCloud .label-cloud li:before
{
  content: "" !important;
}

...

<script type='text/javascript'>
  // Label Cloud
  var lcBlogURL = "http://xiaogaozi.blogspot.com";
  var maxFontSize = 25;
  var maxColor = [23,92,162];
  var minFontSize = 15;
  var minColor = [82,139,197];
  var lcShowCount = false;
</script>

...

<b:widget id='Label1' locked='false' title='Cloud' type='Label'>
  <b:includable id='main'>
    <b:if cond='data:title'>
      <h2><data:title/></h2>
    </b:if>
    <div class='widget-content'>
      <div id='labelCloud'/>
      <script type='text/javascript'>
        function s(a, b, i, x)
        {
          if(a &gt; b)
          {
            var m = (a - b) / Math.log(x), v = a - Math.floor(Math.log(i) * m);
          }
          else
          {
            var m = (b - a) / Math.log(x), v = Math.floor(Math.log(i) * m + a);
          }
          return v;
        }
        var ta = 0;
        var c = [];
        var labelCount = new Array();
        var ts = new Object;
        <b:loop values='data:labels' var='label'>
          var theName = &quot;<data:label.name/>&quot;;
          ts[theName] = <data:label.count/>;
        </b:loop>
        for (t in ts)
        {
          if (!labelCount[ts[t]])
          {
            labelCount[ts[t]] = new Array(ts[t]);
          }
        }
        tz = labelCount.length-1;
        lc2 = document.getElementById('labelCloud');
        ul = document.createElement('ul');
        ul.className = 'label-cloud';
        for(var t in ts)
        {
          for (var i = 0; 3 &gt; i; i++)
          {
            c[i] = s(minColor[i], maxColor[i], ts[t] - ta, tz);
          }
          var fs = s(minFontSize, maxFontSize, ts[t] - ta, tz);
          li = document.createElement('li');
          li.style.fontSize = fs + 'px';
          li.style.lineHeight = '1';
          a = document.createElement('a');
          a.title = ts[t] + ' Posts in ' + t;
          a.style.color = 'rgb('+c[0]+','+c[1]+','+c[2]+')';
          a.href = lcBlogURL + '/search/label/' + encodeURIComponent(t);
          if (lcShowCount)
          {
            span = document.createElement('span');
            span.innerHTML = '('+ts[t]+') ';
            span.className = 'label-count';
            a.appendChild(document.createTextNode(t));
            li.appendChild(a);
            li.appendChild(span);
          }
          else
          {
            a.appendChild(document.createTextNode(t));
            li.appendChild(a);
          }
          ul.appendChild(li);
          abnk = document.createTextNode(' ');
          ul.appendChild(abnk);
        }
        lc2.appendChild(ul);
      </script>
      <noscript>
        <ul>
          <b:loop values='data:labels' var='label'>
            <li>
              <b:if cond='data:blog.url == data:label.url'>
                <data:label.name/>
                <b:else/>
                <a expr:href='data:label.url'><data:label.name/></a>
              </b:if>
              (<data:label.count/>)
            </li>
          </b:loop>
        </ul>
      </noscript>
      <b:include name='quickedit'/>
    </div>
  </b:includable>
</b:widget>

Blogger的定制性还是很强的, 只要你懂HTML或者JavaScript, 对于我这样暂时不想去折腾个人网站的人来说足够了.