evol128[Blog]

I am the bone of my code

既然gcc是用c语言写的,那么我们是怎么编译gcc的?

 

今天看到一则新闻,gcc新版本引入c++实现的patch

忽然想起来,既然gcc是用c语言写的,那么人们是如何编译gcc的?

其实,大学里宋健健老师的教导我还依稀记得啦= =  为了确保准确性,我特地去翻了一下wikipedia,编译用X语言写的X编译器有以下几种方法:

1.最简单的方法,已经有别人用Y语言写了X的编译器,那你用它编译一下就好了

2.如果没有上面那种好事,那就只好自己用Y写一个了,譬如说,pascal最早的编译器是用fortran写的

3.上面方法的优化版本,用Y写的时候,你不用实现全部功能,只需要一个能够编译X编译器源代码的最低程度的子集就好了,然后用这个子集去编译X的编译器,Java和Haskell就是这样弄的

4.可以使用cross-compiler技术将别的平台上的X编译器迁移过来,C语言一般都是这样玩的

5.最牛逼的方法,先用X语言写一个X编译器,然后手动编译这个编译器(说白了就是直接写汇编,不过不需要完全优化),然后,用得到的结果去编译X编译器的源代码。

那么,gcc到底是如何编译的呢?

3个步骤:

1.在线编译第一个原始版本的编译器,这个编译器不管是效率也好功能也好都不完善

2. 用这个原始版本的编译器去编译gcc,这样我们得到了一个功能完善但是效率不怎么好的第二个编译器

3.用第二个编译器再次编译gcc,最终我们得到了完美优化过的第三个版本

感觉碉堡了吧,最后,列一下有自编译编译器的语言吧:

 

reference:http://en.wikipedia.org/wiki/Bootstrapping_(compilers)

 

[翻译]一个程序员的故事

 

原文链接:http://news.ycombinator.com/item?id=3102143

吐槽我的中文: 这里就可以了= =

大家好,

我曾经发了这篇帖子(http://news.ycombinator.com/item?id=2374271)

最终,我辞去了我的工作。我希望我可以说“这是我做的最正确的事情”或者“为什么我不早点辞掉呢”。但是,我不会这么说的,我经历的正好是另外一面。因为这样说不诚实,我也不会发神经去说谎。好吧,认真的说,我失去了什么?

辞去工作是个坏主意。我搬回去和我父母一块儿住,我从事的自由职业很少能挣钱,我在贫困线边缘挣扎,我绝望的都想要去自杀了。我天天得忍受老爸骂我是个辞去高薪工作的蠢才,我的朋友们取笑我做了个脑残的决定。除了编程我别的什么都做不了,找份新的工作太难了,我得从我失败的地方从头再来,我甚至不知道我想要什么。

我曾以为我会获得自由,但实际上,我变得更不自由了。

我不知道该如何改变这屎一样的现状。让事情变得更糟的是,我20岁了,没有大学文凭,也没有高中文凭,完全搞不清楚状况。

我根本是个傻逼。我发这篇文章主要是想提醒和我有相似遭遇的人,放弃辞职吧。这可不像你想的那么好玩。It's not like Office Space(看不懂)。我不是说你们不应该辞职,而是,你们在辞职前得认真考虑一下。

辞职以后,我有足够4个月的生活费。我想了很多,甚至去从事金融之类的。我很努力的尝试独自生活,经过4个月后,我放弃了,我付不起房租。

辞职看起来不是什么灵丹妙药,这让我觉得很痛苦。

 

看到第一个回复我震惊了:

我辞去了我的工作

我也这么做过,还做过很多次。大概有一半时间这样感觉很好。至于另一半,和你的经历一样操蛋。你不是一个人。

我在贫困线边缘挣扎

那么去找份工作吧,任何工作。并不需要是编程。它将使你能够从父母那儿搬出去,让你认识更多的人,并且往你的口袋里塞上点儿零钱。如果你足够热爱编程,你将会有足够的时间让一切步入正轨。

我绝望的都想要去自杀了

不要这样做。随时可以联系我(联系方式在profile里)。 When things are going well, they're never as good as they seem. When they are going poorly, they're never as bad as they seem.(求文艺女青年来翻这句)

我天天得忍受老爸骂我是个辞去高薪工作的蠢才

父亲有时候是错的。你这情况,很明显他错了。不要把他的话放在心上。

我的朋友们取笑我做了个脑残的决定

患难见真情。我知道这不是安慰你的话,但这事儿就发生在你身上了。我很高兴这替你省了很多时间和精力,那些取笑你的人不再是你的朋友了,只是熟人而已。

除了编程我别的什么都做不了,找份新的工作太难了,我得从我失败的地方从头再来,我甚至不知道我想要什么

请不要说“做不到”,这不是事实。你可以的。仅仅只要先找份工作,从那儿开始就可以了。你先匍匐前行,然后开始向前慢慢走,最后加速飞奔。我们中的很多人都经历了这些。你也可以做到的。

我曾以为我会获得自由,但实际上,我变得更不自由了

这只是你现在的看法而已。你正在经历这事,所以有些事情你看不到,这只是漫长旅途的第一步而已。我从没听说过有人可以只走几步路就成功的。我们都经历过这些。看起来这似乎是你人生中经历的第一件大事,所以你才会这么受伤。

我20岁了,没有大学文凭,也没有高中文凭...

这些全都不重要,真正重要的是你的内心。当你开始做积极的行动时,你就知道了。

我根本是个傻逼

请再不要说这话了。你不是,而且我有证据:如果你真的很笨,那你就不会把你的经历发到这儿来了。

辞职看起来不是什么灵丹妙药,这让我觉得很痛苦

谢谢你的提醒。你这篇文章可能使很多人免去经受你这样的痛苦。

同时,谢谢你的故事。我也曾经经历过(还很多次),我觉得其他人也一定经历过。事情会好起来的。我保证。但是你要停止感伤,开始积极的一步。在这儿发文章是第一步;在线下和我们中某个人交谈也许是第二步;从父母家里搬出来,找一份工作,任何工作,这将是你的第三步。

请关注我们后面的讨论。我们哪也不会去,我们关心你,真的。

 

后面还有很多精彩的评论,让人觉得受益匪浅,不过呢。。。我懒了= = 大家自个儿去原文看吧

Vim攻略 Catalog

<1> Overview

<2> Basic Operations

<3> Configuration

<4> Windows

<5> Registers

<6> mapping

<7> Pattern

<8> Macro

<9> Scripting

 

我呢,其实一点都不擅长写教程啦,这个系列算是欠某人的吧。现在,一切都over了,我也得向前move on了。

farewell

 

Update:

09/05/2012: 和预想的一样,我懒了= =好歹更新完了,虽然后面都是贴manual....

08/28/2012: Finish(误) <6><7>   OK, I'm a very very lazy guy...

08/23/2012: Finish <4> <5>

08/07/2012 : Finish <1>, update <2> and <3>

08/06/2012 : Finish <3>

08/05/2012 : Finish <2>

Vim攻略 <3> Configuration

<1>仍然没有写完,上班太累了。。。

使用方法: 在command模式下输入命令

 

 

" 界面优化

set ruler               " 在屏幕下方显示

set showcmd             " 显示你正在敲的command

set incsearch           " 搜索每敲一个字符,都会跳至匹配  (这项不要开,跳来跳去太人了)

set showmatch           " 输入 } ) ], 高亮对应的左括号

set number              "显示行号

 

" 自定义样式

set term=xterm-color " 设置终端颜色

syntax on               " 高亮

color derek             " 设置颜色题,用户定制主题放在~/.vim/colors/下

set guifont=inconsolata\ 12  "字体\字号,用字体放在~/.fonts/下

 

" 缩进

set expandtab         " 用空格代替tab

set shiftwidth=4        " <<>> command缩进距离

set softtabstop=4       " 输入tab后的缩进距离

set tabstop=8           " \t字符所占的字符数(不要和上面弄混了)

set smarttab            " 当开启这项功能后,在一行开始入tab,会根据shiftwidth来决定缩进距离,无softtabstop或者tabstop

set columns=88 终端宽

set lines=49 " 终端高度

set autoindent " 自动缩进

set cindent          " 根据C语法缩进

 

" 代折叠

setlocal foldmethod=indent "折叠方式(根据缩进来折叠

autocmd FileType c setlocal foldmethod=syntax "于C source file,根据法来折叠

autocmd FileType cpp setlocal foldmethod=syntax "对于cpp source file,根据语法来折叠

set foldnestmax=10      " 最多折叠10

set foldenable        " 折叠

 

如果设置了某个功能,想要取消怎么办? 只要输入set no[config]就可以了,e.g. set noincsearch 关闭渐进搜索

不过呢,上面这些设置,只针对某个特定的vim实例,关掉vim以后就会消失的。如果想要永久设置该怎么办?很简单,把对应的command写到~/.vimrc文件里就可以了

最后,推建一个好用的主题: wombat  好用的字体: inconsolata 

最后效果大概是这样子的:

 

Vim攻略 <2> Basic Operations

好吧,其实<1>差不多写完了,只是我对自个儿的文笔非常不满意,所以等润色下再发

下面这张列表,是笔者使用vim editor时经常用回到的一些按键,可以说,这些已经涵盖了90%的日常使用

虽然是用英文写的,不过原作者一定肯定坚决是我~ 吐槽我的英语:evol128@gmail.com

 

[n]<key>   means that this command takes an numeric argument, which repeats the function of the command by n times. n can be omitted. e.g. 3w means move cursor to the beginning of 3rd next words.

<key>· means this key should be followed by another key

# means a line number

All commands except Ctrl commands are case sensitive.

 

mode selection

esc normal mode

v viusal mode

i insert mode

: command mode

 

movement

h move 1 char left

l move 1 char right

j move 1 char down

k move 1 char up

当然,十字键也是同样的效果,那为什么我们需要这四个按键呢?我的理解,用这四个键可以省去把手从字母区移开的时间,将工作效率提升至极限

0 begin of line

$ end of line

同样,和home/end是重复的

[n]w move cursor to the begin of next word

[n]e move cursor to the end of current word

G go to last line

#G go to # line

gg go to first line

Ctrl+d scroll half window down

Ctrl+u scroll half window up

Ctrl+f scroll full window down

Ctrl+b scroll full window up

%  if coursor on (,),[,] or{,}, go to corresponding braket. else search backwards for the first (, [, or {

简单来讲就是找括号。。。

 

edit

x delete a char at cursor

used with movement operation, delete from cursor to the movement char. e.g. d$ delete from cursor to end of line 

s change a char at cursor

used with movement operation, delete from cursor position to the movement char,then get into insert mode. e.g. c3w changes from cursor position to next 3 words

i  enter insert mode, then you can insert chars into file

 

undo/redo

u undo

ctrl+r redo

 

copy/paste

y yank(copy)

p paste

*y/*p yank/paste from clipboard

 

search/replace

/<pattern> search for pattern

?<pattern> search for pattern backwards

n goto next occurrence of search pattern

N goto previous occurrence of search pattern

%s/<old>/<new>/g replace old pattern with new pattern

 

file operation

:q  quit

:q! quit without save

:w [filename]  save file

 

最后送大家一张图吧  基本上上面这些都标出来了

Vim攻略 <1>Overview

先给大家道个歉,过去一年,一直在忙于私事,所以都没有时间来打理博客。现在,一切都结束了,我也终于有时间来写点东西了

 

为什么我们需要文本编辑器?

简而言之,fast,strong & convenient

和诸如visual studio, eclipse之类重量级的ide比起来,text editor更加专注在文本编辑这单一的功能上,操作简便(不是简单= =),功能强大,速度飞快。可以说,当你习惯于使用vim或者emacs之后,你的编码效率会有大幅提高

为什么是vim?

其实世上好用的text editor还是挺多的,不过大部分都ask for money,免费的无非就只有vim和emacs而已。这两种编辑器各有优劣吧,vim的单键多模式 vs emacs的单模式组合键(真心不想扯太多,不然要战起来的)。根据o‘reilly的数据,vim教材的销量大概是emacs的2倍多,再加上一点点私人原因(好吧,我承认私人原因是主要原因= =),所以,我就选用vim啦

为什么你要写这篇文章?

首先我想说,vim自带的帮助文件,内容非常详尽,如果有时间的话,请务必去看一下呢。使用方法很简单,在vim中输入:help就好了。只是,这个doc实在是很长很长,而其中的大部分功能,对我们这样的初学者来说,是难得用到一次的。所以,我打算在工作之余,抽出点spare time帮大家把vim中的重要功能都一一整理出来。我的计划是花6-7篇文章的篇幅,由浅入深带着大家在浏览一遍vim的各种feature,之后么,就靠大家自个努力了。

Main Feature: Modes

在vim中,根据所处的mode不同,每个按键的作用也不同,所以,学习vim,第一步是弄清楚vim到底有哪些常用的mode

normal mode (进入方法: esc)

normal mode是vim中最常用的一个mode,文件操作,光标移动,以及大部分的文件编辑都需要在normal mode中进行。

insert mode (进入方法: i或者其他插入操作)

顾名思义,在insert mode中,用户可以向文本光标处输入字符。

visual mode (进入方法: v)

在visual mode中,可以通过移动光标来选择文本

 

command mode (进入方法: 冒号)

所有命令,都得在command模式中输入。另外,在command mode中还可以通过!来调用外部程序

此外,还有一些其他的mode,因为不是很经常用,就不在这儿介绍了

这世界,没有任何一件事情是理所应当的

大家还记得我以前写过的安全的个人密码系统吗?当初我写这篇日志的时候还沾沾自喜了一段时间呢。可是当我看到了Jeff Atwood的文章Cutting the Gordian Knot of Web Identity,我忽然觉得自己实在是too young too simple了。比起“设计复杂的密码”,Jeff提倡的是“让计算机来为我们完成这一切”,一键注册,通用tag,云存储密码,这些idea都是我从来都未想到过的。

 

对于同样的问题,为何我和他的解决方案有如此之大的差异?我不由开始反省自己:

在思考问题的时候,我是不是太保守了?

我有没有去思考过深层次的原因?

我是不是应该从low level或者source level开始思考?

“一直以来的传统” 难道我不能打破它吗?

 

我很庆幸,在自己还不算太老的时候,能够看到Jeff的文章。

这世界,没有什么事情是理所当然的——努力去怀疑一切,思考一切,然后创造一切吧^_^

 

自言自语

 

 
最近在各方面都诸多不顺啦……百无聊赖,写篇博客消遣消遣。
 
Q:为什么你会想要做程序员?当初你是为什么学这个专业的?
A:嘛,其实最初的动机也是挺单纯的啦,熟悉我的人都知道我是个重度游戏宅,中学时候觉得做了程序员就可以创造出各种各样好玩的游戏来,于是乎,就报名参加了学校的编程兴趣小组,一边学编程,还可以借机用电脑玩游戏,一举两得。后来发现做游戏好麻烦..就放弃了,不过却因此喜欢上了编程呢。非要说的话,我很享受用程序创造万物的那种感觉吧~
 
Q:你觉得成为一个优秀的程序员需要具备哪些素质?
A:Larry Wall总结的很好:懒惰,急躁,傲慢。具体说来,一个优秀的程序员因该倾向于用程序而不是人力来解决问题;迫切地想要解决问题并且能够享受解决问题那一刹那的快感;最重要的一点,相信自己是最好的。
P.S. db同学和Larry在同一家公司工作呢,想要签名的赶快联系他啊^_^
 
Q:如何才能成为一个优秀的程序员?
A:这个问题很难回答呢,因为我不知道自己是否够得上“优秀”这个词。就我看来,一个人的思维模式对其能力的影响很大。我觉得一个逻辑清晰的人在解决问题时应该要做到下面几步:
1. 怀疑:不要轻易相信从外界获取的信息,特别是“别人说的话” <-- 没有比这个更不靠谱的东西了。
2. 思考:对于每一个细小的问题,都要去思考其可能性。
3. 假设: 对于一个事物的起因,经过,结果,提出一些合理的假设。
4. 验证:不管证明还是证伪,你都得去验证你的假设,否则毫无意义。
5. 如果1-4不能解决问题,回去睡一觉,然后goto step 1,从头开始重来一遍。
6. 看到这里,如果你开始怀疑我的方法是否正确,恭喜你已经踏入了第一步。
 
Q:能对当前的各种主流平台技术做个评价么?
A:我就评价一下language吧
        C:气质型美女,最能打动我心的那种风格吧
        C++:才华横溢,只是太难相处了
        Java:清新的小可爱,也是我喜欢的类型啦
        Perl/Python/Php:感觉像3个小loli呢,各有千秋,好难取舍啊……
        Ruby:据说比上面三个都可爱,可惜我没见过……
        C#:美丽性感,可是缺乏内涵,这样的美女一点都不能打动我的心呢
        LISP:我不太方便评价火星人……
        Javascript:谁把猩猩给混进来了……
 
Q:你的对于未来的期许是什么?
A:说实话,对于未来会怎么样,我完全没有概念——只要能让我继续写程序就好了,哪怕是做最浅薄最蹩脚的程序员。
 
Q:换个问法,现在你的梦想是什么?
A:很遗憾我对成为海贼王火影忍者通灵王赏金王什么的没有太大兴趣,喂马,劈柴,周游世界——能够得到平凡的幸福的话,我就很满足了。
 
Q:你的想法似乎有点天真?
A:比起那些捐钱给aiww,投票给好庄严,认为转发几条微博就可以改变社会的家伙们来说,我觉得我很现实了。
 
Q:你的文笔似乎有待提高呢?
A:因为没有妹子来帮我修改润色。
 
Q:最后有什么想说的吗?
A:给我一台电脑,我可以创造世界。

 

收集的一些Geek漫画

根据DRY原则,贴上链接http://photo.renren.com/photo/ap/Qml8do2lg5

出处全部为网络,希望大家补充

[扫盲]为什么浮点数运算会有误差

在开始阅读本文之前,请猜测一下下面程序的输出结果:

float a=0.0f;
for(int i=0;i<10;i++){
    a+=0.1;
}
cout<<(a==1.0);

true? You're too young, too simple, sometimes naive.

虽然乍看上去很不可思议,但是0.1叠加10遍的确是和1.0不等的。这种诡异的情况是由于浮点数的计算误差引起的。

既然是扫盲贴,我就稍微罗嗦一点,先从浮点数的格式讲起吧。

在IEEE标准中,浮点数是由符号位(1 bit),指数位(8 bits of float and 11 bits of double)以及精度位(23 bits of float and 52bits of double)组成的。

不放假设符号位是sym,指数位是exp,精度位是pre,那么一个浮点数的值就等于(sym==1? - : +) 1.pre * 2^(exp-2^k)。其中,k=指数位的位数-1,即是说,k=7 of float, k=10 of double。

举个例子1 10000001 11010010001000000000000表示一个float number,它的值是-1.11010010001000000000000*2^(129-2^7) = -1.11010010001000000000000*2。

但是,2进制的浮点数表示有一个很大的问题——它并不可以精确表示所有实数。说得更准确一点,只有可以写成2^a+2^b+2^c+...这种形式并且精度不能太多的实数才可以用浮点数来精确表示。而大多数实数仅仅保存了一个四舍五入后的近似值而已。譬如,0.1在单精度浮点数中实际值为0.100000001490116119384765625。

正是这种非精确的表示形式,造成了浮点数运算的误差。不管加减乘除,只要涉及到了浮点数,你都得心里清楚:结果不是精确值,只是近似罢了。所以,在浮点数的运算中,请尽量避免用==比较结果,可以用 a+b<某个很小的数 来代替。

顺带提一下,0和无穷大在浮点数中是可以精确表示的,IEEE规定,除了符号位外全0表示0,除符号位全1表示正负无穷。

好吧,把话题扯回来。由于浮点数运算有误差,浮点数的四则运算不具备结合律分配率

看一个wiki上的例子:

 a = 1234.567, b = 45.67834, c = 0.0004
 

 (a + b) + c:
     1234.567   (a)
   +   45.67834 (b)
   ____________
     1280.24534   rounds to   1280.245


    1280.245  (a + b)
   +   0.0004 (c)
   ____________
    1280.2454   rounds to   1280.245  <--- (a + b) + c
 

 a + (b + c):
   45.67834 (b)
 +  0.0004  (c)
 ____________
   45.67874
     45.67874 (b + c)
 + 1234.567   (a)
 ____________
   1280.24574   rounds to   1280.246 <--- a + (b + c)

 

另一个例子:

 1234.567 × 3.333333 = 4115.223
 1.234567 × 3.333333 = 4.115223
                       4115.223 + 4.115223 = 4119.338
 but
 1234.567 + 1.234567 = 1235.802
                       1235.802 × 3.333333 = 4119.340

 

总结:懒得写。非要说点什么的话,谢谢大家捧场^_^

Reference: http://en.wikipedia.org/wiki/Floating_point