SQYBI.com

Change is a part of life, and takes part in finding us who we are.

2011年06月21日
by sqybi
2 Comments

TIGER × DRAGON 节选

节选自《TIGER × DRAGON》,第四卷第五章。

“高须同学,真——的是个,怎么说……很没用的家伙耶?”
“关你屁事!”
亚美还是气喘吁吁,边说边靠在岩壁上,擦去眼角的泪水…
“喳呢,那么没用的模样……譬如说一生气就拿油豆腐乱挥,我并不讨厌喔。喂、我说喂!别盯着油豆腐,听人家讲话!”
“我有在听。”
“我刚才不是说过实乃梨不适合高须同学吗?那可是认真的。因为高须同学不可能用油豆腐打实乃梨,也不会在实乃梨面前表演自恋狂的模样吧?”
亚美终于收起笑容,恢复平常冷酷的眼神。眼睛闪闪发光,定眼看着龙儿脚边:
“再说……高须同学是月亮。”
“……什么意思?”
实乃梨是太阳,待在她的身旁,只有燃烧殆尽,终究只剩消失一途……这是我的看法。只是憧憬她的话,永远无法对等。能够和你对等的人,举例来说——像是我这种人。”
“……我和你只有身高对等吧?”
我早就知道实乃梨是太阳了,一开始就知道了。因为她就有如太阳一般耀眼,我才会对她一见钟情、喜欢上她。这种事情不需要亚美提醒。
“……”
“我是这么认为的……如果是和高须同学在一起,我们就能够对等相处。”
亚美冰冷的手指不知几时缠上龙儿的手腕。她站在龙儿旁边,手指没有进一步的动作。只是脸上没有任何表情,抬头仰望龙儿——
“这已经和逢坂大河无关,只是我的想法……因为我这么想,所以才会这么说。你不用胡思乱想。”
瞬间离开龙儿身边,比刚才靠过来时还要快,仿佛跳舞翻身过去——伸手拨弄头发,露出天使笑容。

2011年06月17日
by sqybi
21 Comments

[Harmonica] Zzz

最近在追好多四月新番……其中有一部叫做《日常》,剧情也是真够日常的……
然后OP和ED都蛮好听,特别是ED。
蛋疼的是这个ED的名字叫做Zzz……果然够日常的名字啊!

稍微听了下谱子,不是很难,就拿出有段时间没用过的口琴练了练。
顺便录了一下,感觉还不错,传上来了。
因为有变调所以就不配伴奏了……

另外还在练《我们仍未知道那天所看见的花的名字。》的ED,《secret base ~君がくれたもの~》,不过这个蛮难的(练吐音的好曲子啊有木有!),高音孔还好,在低音孔那边就很难吹了……所以等练好了再录吧~

不扯了~另外提醒人人上看到这系列文章的童鞋们,那边是导入的RSS所以看不到传的音乐,要点进原文才行……

音频片段:需要 Adobe Flash Player(9 或以上版本)播放音频片段。 点击这里下载最新版本。您需要开启浏览器的 JavaScript 支持。

2011年05月08日
by sqybi
3 Comments

编译器和它的故事——自展与交叉编译

其实好久以前就想开始动手写这么一篇文章了,不过一直没有时间。现在正好刚考完最后一门期中考试,还是编译原理,就把这篇文章写出来。

要阅读本文,不需要太高深的编译原理知识,甚至不需要编译相关的知识。但是本文也不是面向对电脑一无所知的读者的,你至少要知道:
1. 不管是exe可执行文件还是Linux下的程序,都是一些二进制代码,我们称之为机器语言。这些代码的执行和系统以及CPU都有关。
2. 大部分情况下,编译器是一种将高级语言翻译成机器语言的程序。而任何程序本身也是一些机器语言的代码
3. 无论是高级语言、汇编语言还是机器语言,实际上都是等价的,唯一有区别的是,越高级的语言写起来越容易(所以我们倾向于尽量多书写高级语言代码);同时,机器语言是可以直接运行的
如果你觉得上面三条可以理解或者可以理解一部分,那么请继续阅读。

另外,本文中提到的无论是编译的过程还是语言的分类甚至是一些例子,都可以看做是一个简化的模型。实际上,很少有一个exe程序就可以运行的编译器,现代的编译器都是十分复杂的。不过,考虑这些简化模型对我们没有任何坏处,它们和实际情况相差并不很大。

首先我来详细解释一下高级语言和机器语言。

语言的所谓“高级”,实际上界定不是那么明确。不过我们可以确定的是:C++、Java、Python之流比汇编语言更高级,而汇编语言比机器语言更高级。
这里提到一个汇编语言和机器语言的区分。可能有些读者不明白这两个概念的区别,实际上很简单,汇编语言是我们会看到的那些MOV、JMP等命令组成的语言,而机器语言则纯粹是是各种01串。我想没有人会愿意写一个机器语言的程序——实际上,我们学校的计算机组成实验都是用Verilog HDL这种高级语言来完成的,而嵌入式原理实验也是用一种汇编语言完成的;即使是做处理器和单片机,也不会有人愿意去写机器语言,毕竟一大堆01串太坑爹了。
试想,让你用C++写一个从1输出到100的程序,几行代码就可以搞定;而汇编语言则可能需要几十行;机器语言呢,Oh my god,一大堆01000101110110101011111001……,看都看不懂,还写啥啊。

但是上面也提到了,机器语言和高级语言的区别是,它可以直接运行。比如exe程序,实际上它内部存储的就是一些机器语言的代码,机器可以直接阅读这些代码并在处理器中运行它们(这里说的不是完全准确,比如.NET编译出的exe程序实际上是一段中间代码,由CLR解释成机器代码才能运行——不过这可以暂且忽略,就当作我说的是一个简化的模型)。当然程序的运行是依赖机器架构和系统的,不然Wine什么的也就没有用了(什么是Wine?WINE = WINE Is Not an Emulator!有趣的名称递归定义还有很多,不过与本文无关,请自行Google)。
而实际上,是机器架构不同还是系统不同,并不是我们考虑的问题。我们考虑的问题只是,一段代码在A机器和X系统下能否运行,换到B机器和Y系统下又能否运行。就算在A机器和X系统下能运行,如果换成了A机器和Y系统之后不能运行了,那对于我们这也可以看做两台不同的机器(也就是说,A机器和Y系统实际上就可以看做一个新的机器B)。所以之后的描述中,我们不考虑操作系统的情况,而是只考虑机器,我们编号为a、b等,而它们上面可以运行的机器语言我们编号为A、B等。

以上几段的关键点是:
无论是机器语言还是高级语言,实际上都是代码。在之后的讨论中,我们不应该将它们区别对待。
虽然机器语言代码和高级语言略有不同,它可以直接在机器上运行,但是对于编译过程,它们没有任何区别。

上面的问题了解了之后,我再来简单说一下编译器。那编译器是什么?这要从两个方面来解释。

首先,编译器本身的功能是,将一种语言S的代码转化为一种语言T的代码。这里稍微了解编译器的读者可能有疑问了:我用的gcc之类的编译器,明明是把C语言代码编译成了一个exe程序,并不是把S语言的代码编译成了T语言的代码啊?如果你也有这个疑问,请重新阅读以上几段——我在前面已经提过了,“任何程序本身也是一些机器语言的代码”。也就是说,我们这里把机器语言也看作一种语言,只不过是很低级的语言;而编译器就可以将C语言这种高级语言S转化为机器语言这种低级语言T,恰好这种低级语言还是可以在机器t上直接运行的。
其次,大部分情况下,编译器自己也是一段程序,那么它也可以看做是一段代码。而编译器也会有它的源代码,这个源代码就是一种高级语言的代码,我们这时仍然叫它编译器。随便举个例子,对于gcc.exe,这个程序是一种机器语言A的代码,它可以直接在a机器上运行。而它的功能则是,将C语言的代码转化为机器语言A的代码(一个C语言的编译器),使得本身无法直接运行的C语言程序变得可以在a机器上运行。而在得到gcc.exe之前,我们一定也有一段代码,它是用来生成gcc.exe这个程序的,这段代码可能是一个高级语言的代码,比如汇编语言。那这时候,这段汇编语言的代码即使不能直接在电脑上运行,我们依然说这是一个C语言的编译器。

有了这两点,我们就可以总结出一个编译器的特征:
1. 本身是一段代码,假设是A语言的代码,A可以是机器语言,也可以不是;
2. 可以接收一段代码,假设是S语言的代码,S一般来说是高级语言,但理论上也可以不是;
3. 可以将接收到的S语言代码在内部转换后输出一段代码,假设是T语言的代码,T有可能是机器语言,但也有可能是一种高级语言。
这样,一个编译器就可以被表示为A(S –> T),表示编译器本身的代码是A语言,可以接受一个S语言代码作为输入,同时产生相同功能的T语言代码作为输出。之后我们的编译器都会这么表示,请务必牢记。

以上几段的关键点是:
编译器是什么?从本质上看是一段代码,而从功能上看可以将一段代码等价地转化为另一段代码。
所以,我们用A(S –> T)表示一个编译器,这个编译器本身是由A语言写成的,它的功能是将S语言代码等价地转换为T语言代码。当A语言是机器语言的时候,这个编译器就是可以使用的。

有了之前的知识基础,终于可以开始讲自展了。

不知道读了之前的内容,你有没有这样一个疑问:既然编译器本身是一段代码,那么如果想编译一个编译器,就需要更早的编译器来进行编译操作。而编译这个更早的编译器还需要更更早的编译器——长此以往,第一个编译器是怎么产生的呢?难道是直接用机器语言书写的?
如果能这么想,那么你就猜对了。第一个编译器一定是用机器语言写出的。实际上,很久以前的程序员还在纸带上打孔编程呢,他们也照样乐在其中。机器语言只是很难书写,并不是不能书写。
但是,毕竟用这么难书写的语言写一个C++编译器,谁都不会愿意去干。所以,第一个编译器的功能一定是很简单的。而人们会用这很简单的编译器的语言,去写一个稍微复杂一些的编译器;然后再用这个新的编译器,去写一个更复杂的编译器;最终得到一个很复杂的编译器,比如C++编译器——好了,如果能够理解这个过程,那么你实际上几乎就理解了自展。

所谓自展,实际上就是用一个功能不太完善的编译器支持的语言写代码,然后放到这个编译器上去编译,产生一个比自己更完善的编译器的过程。用一个不太恰当的例子来描述,就是我们已经有了一个C语言的编译器,然后我们用C语言写一个C++的编译器代码,并用C语言编译器编译这个代码生成可以运行的C++编译器(之所以不太恰当,是因为C语言不是C++语言的严格子集)。
也就是说,我们有一个编译器A(C –> A),现在写一个编译器C(C++ –> A),将后者放入前者中进行编译,即A(C(C++ –> A) –> A),得到一个可以执行的编译器A(C++ –> A)。

以上几段的关键点是:
自展过程,实际上就是用低级语言先实现一个简单的编译器,然后用这个编译器的语言再去编写一个更高级的编译器——这个新编译器是旧编译器的扩展——的过程。

自展很简单?那下面就是本文的重头戏——交叉编译了。

交叉编译这个概念,没有自展这个概念那么准确。所以先看一个问题:如果你想写一个手机系统上的程序,你会怎么做呢?我们可能会想到,开发一个手机上的编译器,然后把程序放到上面编译成手机可以运行的机器代码。但是这样就有一个很大的问题了,那就是手机的运行速度和电脑相比十分缓慢(虽然现在手机的CPU已经很强悍了,但是手机的内存一向很小,不太足以运行编译器)。
实际上,在现实中我们的做法是,在电脑上完成编译过程,然后直接把在手机上可以运行的机器代码拷贝到手机内。这样就不受限于编译时手机的内存和CPU限制了。这样一个过程,就叫做交叉编译。
当然交叉编译也有其它的应用,比如有时候我们也需要在一台电脑a上生成另外一台电脑b上同一个语言的编译器,比如在Windows下编译一个Linux的编译器。这个问题比前面的问题还要多一步编译操作,我们不妨在后面的讨论中将这两个问题称作问题1(前者)和问题2(后者)。

为了方便起见,我们把这两个问题用之前的表示方法来书写一下。
首先,将电脑看做是机器a,手机看作是机器b。我们现在手里拥有的是某语言S在a机器上的编译器A(S –> A)。对于问题1,我们需要最终生成一个在a机器上编译b机器代码的编译器,即A(S –> B)。而对于问题2,我们则是需要一个在b机器上生成b机器代码的编译器,B(S –> B)。
而我们可以做到的是,用高级语言S写一个自身的编译器(可以是a机器的也可以是b机器的,不过这个问题中只有后者会被用到),即S(S –> B)。
好,现在我们就有了两个代码,A(S –> A)和S(S –> B),其中只有第一个代码是可以在a机器上运行的。我们要从这两个代码中得到两个新的代码,那就是A(S –> B)和B(S –> B)。

首先先考虑如何得到一个A(S –> B),即一个在a机器上运行的可以将S语言代码编译为b机器代码的编译器。
其实写成现在的形式,这一点如何做到已经很简单了。那就是将S(S –> B)放入A(S –> A)中编译,即A(S(S –> B) –> A),这样就可以得到A(S –> B)。这一步因为使用的编译器是A(S –> A),所以只需要在A机器上执行。
这时,可以发现第一个问题已经解决了。我们这时就可以利用得到的A(S –> B)在a机器(电脑)上编译b机器(手机)的代码了。

然后在考虑如何得到一个B(S –> B)。
可以看到,我们之前一步的时候有了一个A(S –> B),而最开始还拥有一个S(S –> B)。这样,我们只需要将S(S –> B)放入A(S –> B)中编译,即A(S(S –> B) –> B),这样就可以得到一个B(S –> B)了。
这样,我们用前一步得到的编译器A(S –> B),在a机器(Windows)上运行,又得到了一个新的编译器B(S –> B),它可以在b机器(Linux)下编译b机器(Linux)的代码。

可以看到,我们从最开始的编译器A(S –> A)和代码S(S –> B)得到最终代码B(S –> B)的过程中,所有的步骤都是在A机器上运行的,完全没有用到B机器。这就是交叉编译的有趣之处!使用交叉编译,可以在很多情况下省去不少的麻烦。

另外解释一个问题,为什么不直接编写一个A(S –> B)?因为A是机器代码,而之前也提到过了,“我们倾向于尽量多书写高级语言代码”,因为机器语言十分难以理解和书写。所以,我们写了一个高级语言代码S(S –> B),将它放到已有的A(S –> A)上去编译(为什么是已有的?这个问题实际上不需要回答,因为这里假设a机器是一台很常用的机器(比如安装了Windows系统的PC机),所以A(S –> A)是一个很普通的编译器,它的存在性无需证明;A(S –> A)的书写可以利用之前提到的自展完成),最终得到了一个需要的B(S –> B)。

以上几段的关键点是:
关键点太多了有木有!!!这个怎么总结呢……
如果看不太懂交叉编译的过程的话,可以暂且把a机器当作一个安装了Windows的PC机,把b机器当作一台手机或者一个装了Linux的PC机,然后再带着这个理解重新阅读整个过程。
实际上,交叉编译解决的两个问题分别都只需要一步操作,所以交叉编译没有听起来那么复杂!不要自己吓到自己就好了~

拍了快两个小时,这篇文章终于完成了。文章是否容易理解?有没有出现什么技术性错误?欢迎各位留言讨论!
神犇们就不要来bs内容太简单了……

2011年04月24日
by sqybi
0 comments

[Harmonica & 翻唱] Sing 4 U

这次交大十大歌手大赛的主题歌,嗯嗯。

纯属闲的蛋疼录着玩,从开始录到结束不超过二十分钟。
前一半是口琴,后一半是演唱,不过各种走音严重。口琴部分还吹错一个音,直接被华仔bs。
btw,华仔是这首歌的原唱,这首歌的MV见这个视频。
感觉都已经录了放在硬盘里放着也不爽,就干脆扔到网站上。

真心想听这首歌的还是去看上面链接里那个视频吧……就不要听我这个折磨耳朵的版本了。

音频片段:需要 Adobe Flash Player(9 或以上版本)播放音频片段。 点击这里下载最新版本。您需要开启浏览器的 JavaScript 支持。

这个blog真的像layla姐说的那样越来越生活化了啊,干脆重新开一个blog写点专业的东西算了……

突然发现混音的时候似乎放错了音轨,这段口琴是第一次吹的时候录的,各种sb错误……罢了罢了,懒得改了……

2011年04月18日
by sqybi
22 Comments

高效率写作利器 —— 几款写作软件对比

几点说明

  • 欢迎转载,转载请注明出自SQYBI.com,并附上原文链接(最好Trackback 一下)。
  • 本文所提及的软件,并非那种“自动生成作文”的所谓“写作软件”——自己尽心尽力写出的文字才是最好的文字。所谓“写作软件”,自然是文字处理软件的意思。
  • 为什么不用Word?Word的确是很多职业作家的选择,但是它的界面过于臃肿,有很多在写作中根本用不到的功能——或者说,它的大部分功能都是在写作过程中根本用不到的。
  • 为什么不用TeX/LaTeX?TeX的确是用于科技论文写作的好软件,不过在文学写作上,用它实在是太屈才了。而且对于文学写作这种感性的创作,WYSIWYG(What You See Is What You Get,所见即所得)的编辑器往往比一长串像代码一样的东西更容易激发人们的写作灵感和写作热情。我想没有人愿意对着一大串代码想象两个人的恋爱的故事该如何继续进行。
  • 为什么不用记事本/VIM/Emacs/etc.?本文的标题是“高效率写作利器”——而文中介绍的几个软件都有这样一个特点,那就是排除一切干扰,让作者专心于写作。具体的实现方法是,程序全屏、没有多余的菜单和按钮、有纯色背景或风景图片背景、有背景音乐等等(这里插一句题外话,记得上次查字典,“等”的意思是“只有以上这些”,“等等”的意思是“除了以上这些还有别的”,希望没记错……)。因为我是个VIM党,所以我对Emacs并不熟悉,不能妄加评论,不过我想VIM应该是不能简单地实现这些功能的。毕竟要想着各种命令就很烦人了……
  • 因为作者的测试环境是Windows,所以只评测有Windows版本的软件。似乎Mac上有一些非跨平台的软件,有兴趣的读者可以自行搜索。
  • 本文中得出的任何结论都是作者个人的推荐,如果想知道哪一个软件更适合你,最好还是亲自试用一下。

测试环境

  • 计算机:Dell Studio 1450,Core2 Duo P8700,4G,ATI Raedon HD 4530
  • 系统:Windows 7 Ultimate 64-bit
  • 显示器:双屏;外接Philips显示器作为主屏,分辨率1920*1080;笔记本显示器作为副屏,分辨率1366*768。

写在前面

前几天偶然在GR上看到小众软件发表了一篇关于OmmWriter的介绍文章。正好我之前苦寻此类软件未果,就试用了一下,但是个人感觉体验并不是很好。
之后又在这篇文章的评论下面看到有很多人推荐各种各样的写作软件,于是依次试用了一下。后来一想,既然已经尝试了这么多款软件,为什么不写一个评测,让更多的人知道这类软件的存在呢。
于是就有了这篇文章。

这些软件的一个共同特点是,可以让写作者集中精神于自己的工作。利用简单的界面,或者清爽的音乐,营造一种轻松专注的氛围,这是我在这里介绍它们的原因。如果不需要这个特性,那么Word或者记事本(甚至VIM?)会更适合你。
因为之前发预告文章的时候很多人都在说VIM之类的更好,所以这里特别说明一下。此外,我个人认为VIM十分不适合文学写作。

如果你是从人人网上看到这篇文章的,推荐来看原文,人人网上RSS的图片显示可能会有问题。

Continue Reading →