March 29, 2011

virtual function and template in C++

Object-oriented programming is based on three fundamental concepts: data abstraction, inheritance, and dynamic binding. In C++ we use classes for data abstraction and class derivation to inherit one class from another: A derived class inherits the members of its base class(es). Dynamic binding lets the compiler determine at run time whether to use a function defined in the base or derived class.

Inheritance and dynamic binding streamline our programs in two ways: They make it easier to define new classes that are similar, but not identical, to other classes, and they make it easier for us to write programs that can ignore the details of how those similar types differ.

By default, function calls in C++ do not use dynamic binding. To trigger dynamic binding, two conditions must be met: First, only member functions that are specified as virtual can be dynamically bound. By default, member functions are not virtual; nonvirtual functions are not dynamically bound. Second, the call must be made through a reference or a pointer to a base-class type.

In object-oriented programming, a virtual function or virtual method is a function or method whose behaviour can be overridden within an inheriting class by a function with the same signature. This concept is a very important part of the polymorphism portion of object-oriented programming (OOP). (Wikipage)

Virtual functions overcome the problems with the type-field solution by allowing the programmer to declare functions in a base class that can be redefined in each derived class. The distinction between virtual and non-virtual resolves this ambiguity. If the function in question is designated "virtual" in the base class then the derived class's function would be called (if it exists). If it is not virtual, the base class's function would be called. C++ non-virtual function calls are resolved at compile time with static binding, while virtual function calls are resolved at run time with dynamic binding

A destructor in base class need to be declared virtual.

Calling a method with an object pointer always invokes:
»     the most derived class function, if a method is virtual
»     the function implementation corresponding to the object pointer type (used to call the method), if a method is non-virtual

A virtual destructor works in the same way A destructor gets called when an object goes out of scope or when we call delete on an object pointer When any derived class object goes out of scope, the destructor of that derived class gets called first It then calls its parent class destructor so memory allocated to the object is properly released. But, if we call delete on a base pointer which points to a derived class object, the base class destructor gets called first (for non-virtual function). We should use virtual destructors if we call delete on a base class pointer which points to a derived class

=========

Templates are the foundation of generic programming, which involves writing code in a way that is independent of any particular type. The library containers and iterators are examples of generic programming. There is a single definition of each container, such as vector, but we can define many different kinds of vectors that differ by the element type that the vector contains. Similarly, we can, and have, used templates without understanding how they are defined.

A template is a blueprint or formula for creating a class or a function. A function template is a type-independent function that is used as a formula for generating a type-specific version of the function. For example, the standard library defines a single class template that defines what it means to be a vector. That template is used to generate any number of type-specific vector classesfor example, vector<int> or vector<string>.

reference <C++ primer>

March 23, 2011

update the latest version of firefox in ubuntu

The optimal source to get the package seems to be the PPA of firefox for ubuntu. The archive can be found here.

And the only modification for 10.10 is that, the Software Sources that mentioned in that page is to be found in System->Administration->Update Manager->Setting, and finally add the sources of "ppa:mozillateam/firefox-stable" in "Other Software".

cheers

March 19, 2011

How little you know, and some useful commands

All contents below come from here.
----------------

Every week, I still find new commands, new methods, and alternate ways to accomplish things. Below are a few items I found this week that you may also find helpful.

Connect directly to your serial console, and log the session.
# screen -L /dev/ttyS0 9600


Print a line-number for each line in a text file
$ cat -n file

Use ‘mtr’ when debugging network issues:
$ mtr www.google.com

Re-run a command changing a parameter quickly:
$ ls -l 500.*
-rw-r--r-- 1 nwilkens nwilkens 0 2011-03-13 11:32 500.lst
-rw-r--r-- 1 nwilkens nwilkens 0 2011-03-13 11:32 500.txt
$ ^500^600
ls -l 600.*
-rw-r--r-- 1 nwilkens nwilkens 0 2011-03-13 11:32 600.lst
-rw-r--r-- 1 nwilkens nwilkens 0 2011-03-13 11:32 600.txt

Return your current IP address:
$ curl ifconfig.me
n.n.n.n

Typing a long command on the command line? Convert it to your favorite editor using:
cntrl-x cntrl-e

Update the default editor on Ubuntu.
$ sudo update-alternatives --config editor
There are 6 choices for the alternative editor (providing /usr/bin/editor).

Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/ng 80 auto mode
1 /bin/ed -100 manual mode
2 /bin/nano 40 manual mode
3 /usr/bin/emacs23 0 manual mode
4 /usr/bin/ng 80 manual mode
* 5 /usr/bin/vim.basic 30 manual mode
6 /usr/bin/vim.tiny 10 manual mode
Press enter to keep the current choice[*], or type selection number:

Reflections after 15 hours continuous coding

a) I love coding, because it is systematic and predictable.
b) Given advanced algorithms, sorting always finds its way in the program:)
c) It feels nice to concentrate for a long period. And every time as I had a break, it is also enjoyable to have a cup of coffee, or just look outside.
d) "C Bible" and "Algorithm" acquire their well-known fame for reasons. Most of the time, they are even better than internet.
e) It is magic that I would never think of taking a cigarette while coding, even when I see the pack. In retrospect, I still cannot understand how or remember exactly when I quit smoking. But, after all, the result is that I quit, and furthermore, have no desire to resume to that habit.

来自《外滩画报》:向安迪・沃霍尔转型

专访詹姆斯・弗兰科:

向安迪・沃霍尔转型

詹姆斯・弗兰科
凭借《127小时》提名奥斯卡影帝,詹姆斯・弗兰科已经证明了自己是一个好演员,一学期62学分、平均3.5以上的绩点,这位耶鲁大学博士生也证明了自己是个好学生。至于小说家、艺术家、画家、导演等这些身份有待证明,恐怕还需要弗兰科好好思考他那篇关于“跨界媒体融合”的博士论文。
 
文/王奇婷,朱宜,翻译/ Edward   
 
“再见,洛杉矶!今晚很有趣,但我必须回去上课了。”詹姆斯・弗兰科在twitter上写道,并附上了一张大头照——嘴咬着吸管,喝着番茄伏特加,眼神迷离,似笑非笑,看起来说不清是疲惫,还是伤感。

距离第83届奥斯卡颁奖典礼结束不到几个小时,弗兰科便已经坐在飞往纽约的飞机上了。他甚至缺席了自己在好莱坞Supper Club亲手策划的庆功宴。

也许他已经没什么心情庆祝了。几个小时前,他和搭档安妮・海瑟薇首次担任颁奖典礼的主持,结果被批得伤痕累累——“弗兰科完全不在状态,根本没投入角色”、“安妮・海瑟薇好歹还试图载歌载舞取悦观众,弗兰科呢?感觉像在神游。”

来看看他俩在整场晚会上的唯一亮点——海瑟薇穿着燕尾服,独自在舞台上唱了一首改编自音乐剧《悲惨世界》里的歌曲:“他留下我一个人,但他那可以伸缩的机械爪子,却深深地留在了我心里。”她调侃的对象是《X战警》中的“金刚狼”休・杰克曼——原本海瑟薇邀请这位81届奥斯卡主持和她同台演唱,却遭到婉拒。一曲完毕,现场掀起了一个小高潮,此时,弗兰科穿着一身红色女装,假扮成“玛丽莲・梦露”走上舞台,冷冷地说了一句“你穿了燕尾服,那我只能穿这个了”。在零星的笑声中,两人匆匆下台。

按《华盛顿邮报》记者汉克・斯图尔福的说法,弗兰科“经过一段时间的奥斯卡前集训,他只是想在典礼上好好休息一番”。

弗兰科似乎没有多余的精力对付主持人的工作了。他已经是一名出色的演员,同时也在努力成为出色的小说家、艺术家、画家、导演和诗人。奥斯卡前夕,他刚带着自己去年的新片《嚎叫》出席了柏林电影节,并在那里出席了自己的第一个欧洲艺术展“The Dangerous Four Boys”。去年10月,他出版了一部短篇小说集《帕罗奥多》(Palo Alto)。此外,从去年9月起,弗兰科又开始在耶鲁大学攻读文学博士,并在罗德岛设计学院主修数码艺术。

奥斯卡颁奖礼后的第二天上午9点,弗兰科出现在耶鲁大学附近的一家星巴克里,拱着身子看书。他每天都离不开咖啡。他上身换上了一件低调的灰色运动衫,腿上还穿着前一天主持时穿的西裤。

9点25分,弗兰科在同学们惊讶的注视中,走进了教室。

“表演的关键在于放松”

詹姆斯・弗兰科的手臂卡在一块巨石下。

导演丹尼・博伊尔对他说:“现在我要开机了,你开始吧,别停下来。”

于是,弗兰科用尽力气,试图将被卡住的手臂从巨石下抽出来。他涨红了脸,努力地拔,或是用力敲打自己的肩膀。整整20分钟过去,他精疲力竭,手臂和肩膀上满是淤青。导演满意地喊了“cut”。

这是根据真人真事改编的《127小时》中的一幕。电影讲述了登山者阿伦・拉斯顿在犹他州一座峡谷里因右臂被石头压住被困,最终断臂自救的故事。他们拍摄的现场,就在同一座峡谷的巨石下。影片中除了拉斯顿最终断臂那一幕,都是弗兰科亲身体验困境后真实的表现。为此,他也获得了今年奥斯卡最佳男演员的提名。

影片拍摄前,博伊尔和弗兰科曾专门拜访了阿伦・拉斯顿。拉斯顿给弗兰科看了不少当时他拍的视频素材,还手把手教了他一些救生的基本动作。“这是一个必须接受死亡考验的角色,面对死亡时的心理斗争很复杂也很微妙。我很幸运能和阿伦交谈,并且看到他当时的亲身录影。”弗兰科说。

《127小时》最具有挑战性的地方在于,大部分时间里,电影只有一个场景、一个角色。弗兰科在那个岩洞足足呆了五个星期,每周六天,每天从早上九点到晚上九点。“除了上厕所,其他时间他都在那里。”博伊尔说道,“当时我很担心他是否还能保持神志清醒。”

后来,弗兰科告诉记者,他当时保持神志清醒的“秘诀”就是阅读马塞尔・普鲁斯特和学校课本,以此来分散自己的情绪。这一幕,熟悉弗兰科的朋友都不会陌生——他常常在拍戏的间歇阅读陀思妥耶夫斯基、詹姆斯・乔伊斯或是弗兰科・杰斯的小说。剧组人员偶尔会恶作剧般地从背后抽掉他的书,看看书页到底翻过没有。不过那些人从没有机会“得逞”。在拍摄《米尔克》的片场,他读完了《尤利西斯》和品钦的所有小说。“阅读能让我保持冷静。它能让我暂时逃离,让我的内心沉淀下来。” 弗兰科说道。

作为演员的弗兰科是最近几年才迅速走红的。几年前,他因在《蜘蛛侠》三部曲中扮演主人公彼得・帕克的朋友哈利・奥斯伯恩而广为人知。但事实上,弗兰科出道很早,1997年他在加州大学洛杉矶分校(UCLA)读大学期间,曾辍学去做全职演员,并在电视剧《呆子和怪胎》中给人留下深刻的印象。2001年,他在传记电影《詹姆斯・迪恩》中成功复制了美国上世纪50年代的文化偶像、著名演员詹姆斯・迪恩,获得了他人生中第一个金球奖。

2001年到2006年,是弗兰科所谓的“太把自己当回事的那几年”。曾在《呆子和怪胎》中与弗兰科搭档、如今的“青蜂侠”塞斯・罗根回忆道:“那些电影公司早就打起了算盘,‘瞧,一个帅小伙,先让他多拍几部动作片,10年后他就是另一个汤姆・克鲁斯。’”为此,弗兰科拍了很多自己不喜欢的动作片,他整天对着剧本苦思冥想,有时还会为了一些鸡毛蒜皮的小事和导演争执。
他根本无意做汤姆・克鲁斯的接班人。既然没有人认可他作为严肃演员的潜力,弗兰科干脆在2006年选择了重返校园。有趣的是,就当弗兰科把演戏当作一种课余爱好之后,他的表演事业却反而成功了。08年起,他凭借《菠萝快车》、《米尔克》、《嚎叫》等一系列影片,奠定了自己好莱坞一线男星的地位。

弗兰科自己也意识到,如果不是再度回到校园进行写作和学习,他便无法真正享受做演员的乐趣:“当初我太想证明自己适合做一名演员了,作为中途辍学的补偿。但后来发现,这没有用。表演的关键在于放松。”

“从杰克・吉伦哈尔变成安迪・沃霍尔”

T恤、书本、VHS录像带、午餐盒……一个房间内,这些东西被胡乱丢弃在地上,堆成了一座小山,就像一个脏乱不堪的12岁男孩的卧室。据纽约钟楼画廊馆长阿拉娜・海斯称,这些东西是从弗兰科家里原封不动地搬过来的。

“他试图通过这些来表达自己对从童年过渡到青春期、性与暴力、男性主义以及流行文化的看法。”海斯说。

这是弗兰科名为“The Dangerous Book Four Boys”艺术展中的一部分。展览的名字来自于一本名叫《The Dangerous Book For Boys》的畅销书,其中介绍了包括如何种水晶、如何根据手表看方向等男孩需要掌握的生活技巧和知识。而弗兰科则通过短片、摄影、随手涂鸦、雕塑和艺术装置等各种艺术形式,表现书中的部分章节。

如同那个脏乱不堪的卧室,弗兰科此次艺术展的许多作品都令人有些摸不着头脑,其中不乏生猛、先锋的表现方式。《纽约时报》艺术批评家洛贝塔・史密斯认为,这个“充斥着暴力、毁坏和各种性怪癖,并且女性完全缺失”的展览水平,介于无能和小有潜力之间。

海斯称,她之所以愿意为弗兰科办展览,并不是因为他的名气,而是因为“他特殊的视角——对大众媒体相互关系的理解”。而这也正是弗兰科博士论文的主题——“跨界媒体的融合”。他将要在论文中探讨“不同媒体如何联系”、“它们各自的边界在哪里”、“在每种媒介中如何表现起到的效果最好”等议题。

事实上,去年上映的《嚎叫》,便是这种“多媒介融合”的产物。弗兰科在片中饰演美国20世纪著名诗人艾伦・金斯堡。电影用动画、剧情,以及弗兰科的朗诵等多场景并行推进,用实验电影的形式诠释了金斯堡的同名诗集《嚎叫》。该片导演曾戏说:“弗兰科就像21世纪版垮掉的一代。从某种意义上来说,他们身上都带有对艺术实验的无限激情。”

即将满33岁的弗兰科,已经不仅仅满足于当好一个演员。他更想通过层层积累,让自己的内在丰满起来。“就像从杰克・吉伦哈尔变为了安迪・沃霍尔。”《纽约杂志》如此评价,“他的职业生涯已经开始脱离单一的局限,看起来更像一件多元化的艺术品。他已经在流行文化领域占据了自己的一席之地,就像Lady Gaga在流行音乐领域享有的影响力那样。”

在弗兰科的母亲贝特西看来,他这种“一个都不能少”的好胜心,在幼儿园时就展露无遗,“在搭积木时,他总不满足于手头的现成材料,而是一定要把房间里所有的木块全都拿来”。4岁时,小弗兰科曾因家里的一个朋友去世而难过不已。贝特西安慰他说,“他离开了我们,但这也是生命的一部分。”没想到弗兰科呜咽着说,“可我还不想死,我还有太多的事要做呢!”


J= Jan Janssen
F= 詹姆斯・弗兰科 James Franco

“深造学业让我的生活变扎实了”

J:你的表演事业又到了一个新的高度,而你去了耶鲁大学选择继续深造。这算不算一种表态?

F:(笑)除了表演,我得再找些事情来做。在我返回校园前,表演是我生活中唯一的事情,我把所有的精力都投入其中,几乎丧失了私人生活。
但我并不开心,我不喜欢生命中只有工作,我尽量不仅仅通过影片的评价或票房来评判自己。这有点失常,因为作为一个演员,你对于影片最终的成品并没有那么多控制力。当我想更自主地发挥创造力时,总觉得束手束脚。当时我的情绪真的很低落,我决定改变一下了。
继续深造学业让我的生活变扎实了。它让我接触到更多智慧的学者,他们上着我感兴趣的课程。以前,我会对一些不必要的事情感到焦虑,现在,我又重新聚焦在真正有用的东西上。

J:你一定很忙碌吧。

F:我的生活非常的繁忙,还有些精神分裂,不过我很喜欢。我对往返纽约和洛杉矶的往返班机时刻表了然于心,而我也学会更好地组织生活。我可没有许多时间浪费。
我不知道自己为什么要这样做。我不知道。我确实有一种古怪的执着个性,喜欢一下子做许多事情。当我还在表演学校时,我总是尽可能多地参与各种剧目。所以,也许我对许多事情都好奇吧。
我也很有精力去应付各种不同的事情。当我在各种不同的规则和媒介间穿插交错时,我发现它们会互相作用,互相传递精力。我现在觉得在自我表达上有了更多有创造力的方式——我导演了几部短片,写了一本书,做了许多不同的事情,仅仅因为我不再被表演事业所裹挟了。

J:你现在拍电影是不是更放松了?

F:我如今在片场更好相处了,因为我不再因为每一件事而担心。我的心态已经不同以往了,我不再把所有的压力都放在自己肩上,工作的时候不再可怜兮兮。这真的是很大的改变,我很享受现在的状态。

J:你是如何做到在纽约大学和耶鲁大学同时深造的同时,还一部接一部地拍戏呢?

F:冷血般地有效率!(笑)基本上,我往往在暑假里拍电影。2009年夏天我拍了《美食、祈祷与恋爱》,紧接着的寒假我拍了《嚎叫》,2010年夏天则去了《猿族崛起》剧组。我通常不休假,偶尔零星休几天。我没时间!

J:在《127小时》大部分时间里,你饰演一个完全孤立的人物,基本上镜头前就你一个人,这样的拍摄有多难?

F:当然,这只是拍电影,所以这种经历无法和阿伦(拉斯顿)的相提并论,但这确实是一部不同寻常的影片。和其他普通电影相比,它的拍摄要难许多。有几场戏我都精疲力竭,难以呼吸。

J:拍摄前,你见过阿伦・拉斯顿本人吗?

F:丹尼(博伊尔)、我和(编剧)西蒙・比尤弗伊在拍摄前一起见了阿伦。他和我们分享了那次经历的每一个细节,还给我们看了他当时卡在峡谷里时拍的视频。除了我们,他还没给别人看过那些视频。他当时对着摄像机说话,觉得那是自己的遗言……所以那些视频非常有震撼力,对于我去重现当时他濒临死亡时心里复杂的感情非常有帮助。

J:你和导演丹尼・博伊尔是如何决定拍摄那场近几年来最骇人听闻的一场戏(拉斯顿用刀自己切除了被卡的手臂)?有几位观众在影片第一次试映时当场就晕了。

F:丹尼真的已经为那场戏做了平衡。你可以走得很远,把它拍得极度血腥,就好像是部恐怖片。你也可以把它剪掉,让它变得可看性更强些,但那却会减弱原本的震撼力。你不能这么做,因为那是最关键的一场戏,讲述他是如何最终逃离困境自救的。

J:有没有特效参与?还是你对着一个假手臂在演?

F:我们有各种不同的假手臂,因为有不同的需求。当我们在拍断臂那段时,他们设计了一些纹理细节非常非常复杂的假肢,表面看上去完全可以以假乱真,而皮肤下面也都是假的肌肉组织。我们当时一共有三个这样的假肢,一个就可以拍10到15分钟的长镜头,因为这些假肢真的做得很像。我记得有一次去储藏室,那里陈列着许多以供使用的手臂,很可怕……就好像《德州电锯杀人狂》里的一幕。

“通过制造身份混淆的方式,把真实生活拉进了虚构的世界”

J:你曾在《美食、祈祷与恋爱》中与茱莉亚-罗伯茨演过对手戏。和她合作感觉如何?

F:和她相处非常愉快和有趣,如果不是因为她在其中,我也许不会接下这部电影。在影片拍摄前,我们有机会共度几天时光,聊聊天,熟悉彼此,这实在太美妙了。因为有时候,当你和某人拍摄比较私密的对手戏时,你事实上差不多一天前才刚刚见到她。

J:能谈谈你为什么想到做演员的?

F:还是小孩时,我总是在画画,而我的几个亲戚又做着和艺术相关的工作,所以我总是渴望成为一个艺术家。我也曾有过成为一名演员的想法,但我童年时成长的帕洛阿尔托距离洛杉矶可很远。当我有了驾驶执照后,我开始对电影产生了兴趣,我那时的女朋友会开车带我去旧金山,看许多艺术院线的电影。
后来,我一度和一群搞涂鸦、入店行窃这类事情的人混在一起,我知道那一定让我惹上大麻烦的。我的意思是,我已经因为醉酒等事被带进过警察局了。所以,我必须想办法走出这个圈子和状态。我问我爸妈是否可以出钱让我去读艺术学校,但他们拒绝了。
最后,我们达成了一致,他们同意送我去UCLA英语系读书。在我住在洛杉矶的那段时间里,我遇到了许多去参加试镜的人,还有一小部分在电视剧或电视电影里出演角色的人,通过他们我也对参加试镜及通过表演赚些生活费产生了兴趣。我在哥伦比亚大学的一位室友曾拿到过一个重要角色,这也间接导致了我后来的退学。我爸妈对我当时的决定可不满意。

J:当你在享受了作为演员的成功后,再次选择返回校园,是否是为了弥补当初退学的举动呢?

F:不,我不这么认为。我返回校园,是因为我想学习,通过非常基本的方式扩宽我的视野。我也许确实有点狼吞虎咽,选修了比普通人多许多的课程,还同时读了哥伦比亚和纽约大学的两个学位。我确信的是,作为演员的我想向别人证明,至少是向我的教授们证明,我可以在学业上尽职尽力。

J:如今你这样忙碌的日程安排,从某种意义上也宣告了你私人生活的结束。你想过结婚生子吗?

F:当然。我确信结婚需要花许多精力,但我感觉自己一定会经历这个过程。婚姻生活可不是你能计划的部分,它不像规划课程或拍什么电影那么简单。不过,当时机准确时,它自然而然会发生的。

弗兰科一起在哥大念书

第一次见到詹姆斯・弗兰科是在2008年的夏天,我刚入学哥伦比亚大学的戏剧系念编剧硕士。
那天中午,我们刚上完电影理论课,教授是李安的制片人和编剧詹姆斯・沙姆斯。一大群同学一起走下楼,在大厅里,身边一位同学突然说:“看,那人就是蛛蛛侠里的那个男配角。” 我使劲地想了想,隐约记起那个角色。顺着她指的方向望去,我看到一个穿着白色T恤,清瘦而苍白的男生不紧不慢走在人群里,周围的同学并无惊奇或上前搭话,让人觉得那只是一名普通学生罢了。

我有点不相信,走过去问:“嘿,你是蜘蛛侠里的那个演员?”“是啊。”他笑了笑。然后我俩便分道扬镳。直到出了校门在116街坐地铁,我才发现报刊亭摆着的最新一期GQ杂志封面便是他——那一瞬间才有了几分“我有个同学是明星”的感觉。第二天我得知,他也在哥大念硕士,是写作系的的硕士。

写作、戏剧、电影、视觉艺术这四个系都隶属于艺术学院,共享一栋名叫道奇的教学楼,所以课间买咖啡或者上下楼时经常能够遇到弗兰科。像哥大这样的常春藤盟校,又在艺术学院,学生们多少都有些自命不凡,指不定以后谁比谁更红。所以但凡和弗兰科打照面,都带着一份“同学+同行”的矜持。

然而,我也好几次目睹过这样的情景。同学们冷静地买完咖啡,离开,上楼,冲刺进教室后把门一关,对着旁边人就喊:“我刚刚遇到了詹姆斯・弗兰科!太帅了!”艺术学院的每个人都有一个和詹姆斯・弗兰科邂逅的故事,而这些故事都有一个共同点——当事人虽然心中万分激动,脸上却无穷克制。就连哥大校刊有一期谈论“Twitter的10项趣用”的文章中,其中一项竟然是“追踪詹姆斯・弗兰科”。即他每到一个教室上课,班上的同学便把教室号发上Twitter,这样大家就能掌握他一天的行程。

尽管有如此深厚的群众基础,但大家那时提起他,依然还习惯用“蜘蛛侠男配角”这个称呼。
渐渐半个学期过去了,当大家再谈论起这名半红不红的小明星时,语气突然开始有些不一样了。首先是他的学业传奇。他在UCLA时一学期修62个学分(规定是最多19个学分),并且以3.5以上的绩点毕业的故事本身就足够震撼,此后,他在哥大念写作MFA(艺术硕士)的同时,还在纽约大学的天赤(Tisch)学院念电影制作MFA,在布鲁克林学院念小说写作,还不时去北卡罗来纳州的华伦・威尔森学院作诗歌交流。一个普通人完成以上的任何一项,都得累个半死,熬夜赶作业是家常便饭,而他居然在一个个学位修完的同时,还拍了那么多电影。“他写得怎么样?”有一次和他写作系的同班同学一起吃饭时我问起。“真的很棒!”那个女生说。在纽约大学学电影的一个朋友说,弗兰科在入学面试时提前了一个小时,认认真真地在门口作准备。

大家对他完全刮目相看了,这绝不是一个在演艺事业低潮期跑到校园里来镀个金的“蜘蛛侠男配角”。与此同时,弗兰科的演艺事业也开始出现转机。先是他的巨型照片在纽约城的心脏——时代广场张贴了起来,那是他为Gucci代言的广告。然后,他又出演了《菠萝快线》、《米尔克》、《美食,祈祷与恋爱》等多部有影响力的影片,凭借《127小时》获今年奥斯卡男主角提名,并担任了主持人。我们目睹了他升起的整个过程,作为“矜持”的校友,在看奥斯卡直播时我们依然毒舌地嘲笑他的表现,但心里怀着的却是一种“村里那个和我们一起玩大的狗娃子出息了!”的亲切和自豪感。

我一直记得2009年春天,艺术学院的全体学生拍合影。大家高高兴兴地走到道奇大楼门前的空地上集合在一起,各系的人互相打招呼,整着队形。就在摄影师喊“CHEESE!”的时候,我抬头看见四楼教室里,弗兰科站在落地玻璃窗后,远远地望着我们。

如今他已毕业离校,我们这些人也在筹备毕业作品,虽然资金和规模都很小,但一个个都铆着劲。我偶尔想起那天的情景,感到那就像是一个隐喻:他远远地站在高处,偶尔上下楼之间与我们相遇;我们还在楼下整队,一切早晚就绪,而我们也将带着向上的志气前行。

(翻译/ Edward)
2011-03-10 总第 428 期

March 15, 2011

Lisp

A comparison between Scheme and Common Lisp--the author perfer scheme:)
To be fair enough, here is a comparison in favor of Common Lisp:)
An introductory article about Lisp: Features of Common Lisp. The next step will be comprehensive and advanced learning in this language.
Besides, via google searching, there are lots of comparison articles/ discussions and excellent introductions for both dialect languages. At last, I made up my mind: CL will be the next language after I conquer Clojure:)

ps. here is the Google Translate API. Furthermore, other APIs can be looked up in this Explorer.
p.ps. best paper awards list.

Update: A little bit digression, below is the digest of an interesting discussion about genius in Hacker News:
Genius is the act of solving a problem in a way no one has solved it before. It has nothing to do with winning a Nobel prize in physics or certain levels of schooling. It's about using human insight and initiative to find original solutions that matter.
Genius is actually the eventual public recognition of dozens (or hundreds) of failed attempts at solving a problem. Sometimes we fail in public, often we fail in private, but people who are doing creative work are constantly failing.
When the lizard brain kicks in and the resistance slows you down, the only correct response is to push back again and again and again with one failure after another. Sooner or later, the lizard will get bored and give up.

ps. sth about unix and bash file.
The basic bash file introduction could refer to here.
UNIX tips: Learn 10 good UNIX usage habits
UNIX tips: Learn 10 more good UNIX usage habits

pps. sth about Graphviz
1) First step is to install it and know the basic syntax of the command line;
2) Then, the 2nd step reading is also referred in the web page above;
Besides, "How to draw hash table" and some other complicated graphs are both good start points to learn its software and language.

March 10, 2011

Plan for the Spring break

Formal methods:
1. Complete the 3rd homework before next Tuesday;
2. Learn the basic syntax and methods about coding in Clojure;
3. Check the relationship between Clojure and data flow programming;
4. Write at least the abstract and introduction sections of the term paper.

Computer vision:
1. Learn how to run OpenCV and the codes from Josh and Birgi;
2. Figure out the inputs and outputs of each program;
3. Figure out how to deal with the video, such as: how to extract image? how to label or highlight some part of it? how to reproduce the stream of video via processed images? and etc.

Communication Network:
1. Rewrite the code of hw1 and hw2;
2. Begin to read the TCP/IP book.

sth should be done before on-site intv

1. Read Coding Interview twice;
2. Summarize Algorithm;
3. Try hard to complete the Effective C++;
4. Complete the writeup of self-intro;
5. Grab the main idea about operating system and compiler;
6. Look over the basic concepts about ComNtwk and DSP.
--if this is your shot, you have to perform perfect.

fixed point arithmetic

There is a good introduction in wikipedia, which includes several useful external links at the end of the article. The MATLAB also has quite a few functions dealing with this kind of problems, as well as a thorough introductory article. Besides, the comp.lang.c happen to take one inspiring discussion about it. All these things adding together shall definitely let me understand sufficient knowledge about this field of study.

In addition, there are other resources from TI and article written by Joe Lemieux directly concerning the fixed point C programming.

March 8, 2011

some reflections

These days, I did lots of parallel programming. Although sometimes this activity does suffer from low efficiency, it do help me a lot for further preparing and studying of coding. Like other routine work, the more both of us prepared, the more efficient work we will have. Besides, there are several points worth mentioning in retrospect:

1) Format matters. Tab is a much better choice than several blanks.
2) Comments also matter. It will help others know why I wrote in this manner and what the underlying idea for some blocks of code.
3) Multiple screens are necessary: put severl UI in one screen, references in one, and debug windows in one. Cross referring among different dialogs and different screens is one way to improve efficiency.
4) As long as employ oneself in the subject, it will be more straightforward to achieve goals. After all, coding is only time-consuming in one aspect.
5) The use of short-cuts in vim definitely will improve the efficiency, and also seems like more professional:)
6) People will only accept suggestions when they know nothing about it. So, at most of the time, the better choice is just keeping quite and getting your own work done.
7) Reading more, practice more, improve faster.

Update:

Below is something I read from a programmer's blog.


At the time I was a fanatic chess player and my 'dream' was to build a chess program. Of course that was a fairly advanced thing to do, in the end my knowledge of computer programming, and my theoretical knowledge of chess, the memory of the computer, and the available time, they all limited me to writing a program that could do one of two end games (KQ vs K and KR vs K).
Looking back over all those years (I'm 45 now), I don't think there ever was a time when I wasn't programming or thinking about programming in some way or another since I gained that first little bit of insight into what makes a computer tick.

It's like a drug. I'm still fascinated by it, even almost 30 years to the day later I still read about languages, new ways to solve old problems, all kinds of developments in software and hardware, as though it is the first time that I hear about these things. It is a fascinating world, the world of software.
It has changed tremendously over that time, our 'small' computers of today are more powerful than the biggest 'big iron' that you could buy when I was a kid. Your average cell phone has more storage, computing power, and bandwidth available to it than a mainframe of 30 years ago. Programming itself has changed, from 'batch' programming to more and more interactive code, 'web' development and so on. But it has also - in essence - remained the same, small building blocks are piled on top of each other to create more complex constructs, which in turn can be used to create yet more complex constructs, and so on.

That process, the act of programming, is something that I need to do. Whether to make a living or to be fooling around with some idea, the bug is in my system and I highly doubt that it will ever leave me permanently. I can see myself taking a break, but I can't see myself ever stopping. All I'll end up doing then is to change my mode from work to play and eventually that will lead back to some form of work.

If you can't program yet, or if you think that it is 'complex', rest assured, there is nothing that can't be learned. Programming is not like playing a musical instrument, and it is not something that you have to have a genetic disposition for. The pay-off is in how much time you spend plugging away at it. Over time you'll get better, and at some point it will click. It may take a while (it took me more than a year to learn 'BASIC', which is a very simple language) and I gave up several times only to go back to it once more. Eventually, I got it, and I'm sure that everybody that can do basic arithmetic and that is able to put together a precise list of instructions on how to make coffee or a pizza can learn how to program.

Maybe you won't be the next Donald Knuth, but that's not what it takes, all you need to be is a little bit better than you were yesterday and to keep doing that for a long time.

Beware of that bug though, once it bites you, you'll be hooked for life.

March 7, 2011

advices about resume

Reading the articles written by Joel sometimes feels frustrated. But, anyway, they are also illustrated. Here is another post about how to write readable resume:
======

# Proofread everything a hundred times and have one other person proofread it. Someone who got really good grades in English.

# Write a personal cover letter that is customized for the job you are applying for. Try to sound like a human in the cover letter. You want people to think of you as a human being.

# Don't apply for too many jobs. I don't think there's ever a reason to apply for more than three or four jobs at a time. Résuméspam, or any sign that you're applying for 100 jobs, just makes you look desperate which makes you look unqualified. You want to look like you are good enough to be in heavy demand. You're going to decide where you want to work, because you're smart enough to have a choice in the matter, so you only need to apply for one or two jobs. A personalized cover letter that shows that you understand what the company does goes a long way to proving that you care enough to deserve a chance.

# What we're really looking for when we look at résumés is someone who is passionate and successful at whatever they try to do. We like people who are passionate about software. Writing a shareware app when you're a teenager is just as good a qualification to us as getting into MIT. This is your life story, and by the time you're applying for a job it's probably too late to change that.

# The number one best way to get someone to look at your resume closely: come across as a human being, not a list of jobs and programming languages.

March 6, 2011

Comparing file diff in Ubuntu

I am still familiar with the highlighted view for differences rather than the "diff" command, which produces the results in a "+/-" form. After a easy google, the Meld turns out be one good alternative solution for this purpose. Here is its web page.

Just one step to do:
$ sudo apt-get install meld

Then, you will find the Meld in Application->Programming directory.


Have fun.

March 4, 2011

some basic C/C++ questions

1) What are some of the main differences between a linked list and an array?
Arrays are faster in access than a link list for random access with index.
Arrays are not dynamic while a link list is.
Arrays are easier to sort than a link list.
The elements of link list can be deleted/inserted while arrays cannot.
Arrays occupy the same block of memory, while a link list is distributed.
Array objects are automatically created by a compiler, while link lists are not.
Arrays are part of most compilers, while link lists are not.
Arrays are syntactically simple to read.

2) What are the differences between struct, class and union?
Struct, class and union all contain data members and methods. However, a struct and union have their member’s public by default, while the class members are private by default. Also, a struct cannot contain an instance of itself. A union cannot be used as a base class in inheritance. None of a union's data members can be declared static and none of its functions can be virtual.


3) What are virtual functions?
Virtual functions are functions whose behavior is known at runtime rather than at compile time. Due to this behavior, it can be said that virtual functions implement Polymorphism. In other words, preceding a function name with virtual in the base class means that that function is intended to be re-implemented (overridden) in the sub-class.


4) Explain the mechanism of virtual functions and virtual function tables.
Whenever a class member function is declared as virtual, the compiler creates a virtual table in memory which contains all function pointers that are declared as virtual in that class. This enables run time polymorphism (i.e. finding out the desired function at run time). Virtual function tables also have an additional pointer in the object to the vtable. As this additional pointer and the vtable increases the size of the object, a class designer needs to be judicious about declaring functions virtual. The sequence of events upon calling a method on the base object pointer is:
Get vtable pointer (this vtable pointer points to the beginning of the vtable).
Get the function pointers in the vtable using offset.
Invoke the function indirectly through the vtable pointer.


5) Given a singly linked list and a pointer to a certain node in the list, how would you delete that node in constant time?
First of all, check if this node is the last node in the list. If not, copy the contents of the next node to the current node, and delete the next node.


6) What are recursive functions? What are the advantages and disadvantages of recursive algorithms?
A function that calls itself repeatedly, satisfying some condition, is called a Recursive Function. In my point of view, the recursive functions should be avioded at most of the time via the "while" loop sentence. However, on the other hand, some problems inherently are better suited for recursion, such as Fibonacci series generation.

Some advantages of recursive algorithms are: concise in terms of source code; and looking more elegant. The disadvantages of recursion include: requiring more of stack than non-recursive algorithms, due to several activation stacks for each call of the function; and correcting or testing recursive functions would require a lot of careful thinking.


7) What leads to code-bloating in C++?
Inline functions and templates, if not used properly, may lead to code bloating. Multiple Inheritance may also lead to code bloating (this is because the sub classes will end up getting members from all the base classes even if only few members will suffice).

Inline is great. Reasons: They look like functions, they act like functions, they're ever so much better than macros (Whenever you write a macro, you have to remember to parenthesize all the arguments in the macro body. Otherwise you can run into trouble when somebody calls the macro with an expression. On the contrary, inline funtions do not have that kind of troubles), and you can call them without having to incur the overhead of a function call. Moreover, as inlining a function, it may enable compilers to perform context-specific optimizations on the body of the function. Most compilers never perform such optimizations on "outlined" function calls.

However, the idea behind an inline function is to replace each call of that function with its code body, which is likely to increase the size of your object code. On machines with limited memory, overzealous inlining can give rise to programs that are too big for the available space. Even with virtual memory, inline-induced code bloat can lead to additional paging, a reduced instruction cache hit rate, and the performance penalties that accompany these things.

Solution: Initially, don't inline anything, or at least limit your inlining to those functions that must be inline (eg. functions defined inside a class which are implicitly declared inline) or are truly trivial (such as Person::age). By employing inlines cautiously, you facilitate your use of a debugger, but you also put inlining in its proper place: as a hand-applied optimization. Don't forget the empirically determined rule of 80-20, which states that a typical program spends 80% of its time executing only 20% of its code. It's an important rule, because it reminds you that your goal as a software developer is to identify the 20% of your code that can increase your program's overall performance. You can inline and otherwise tweak your functions until the cows come home, but it's wasted effort unless you're focusing on the right functions.


8) What are references in C++? Why do you need them when you have pointers?
Reference variables are internally implemented as a pointer; it’s just that programmers can't use it the way they use pointers. As a side note, a reference must refer to some object at all times, but a pointer can point to NULL. In this way, references can be more efficient when you know that you'll always have an object to point to, because you don't have to check against NULL.


9) How do you do dynamic memory allocation in C applications? List advantages and disadvantages of dynamic memory allocation vs. static memory allocation.
In C, malloc, calloc and realloc are used to allocate memory dynamically. In C++, new(), is usually used to allocate objects.

Advantage is that memory is allocated on an as-needed basis, which helps remove the inefficiencies inherent to static memory allocation, that is when the amount of memory needed is not known at compile time and one has to make a guess.

Disadvantages: 1) dynamic memory allocation is slower than static memory allocation, because dynamic memory allocation happens in the heap area; 2) dynamic memory needs to be carefully deleted after use, because they are created in non-contiguous area of memory segment, and if not properly handled, the operations would cause memory fragmentation; 3) dynamic memory allocation causes contention between threads, so it degrades performance when it happens in a thread.


10) What are constructors and destructors?
Constructors and destructors are provisions for initialization and cleanup of objects.
A constructor is a special member function with the same name as the Class. It is invoked automatically when the object is created. It usually contains initialization code for member variables and allocation of memory. There can be multiple overloaded constructors, with different input arguments, used to initialize the object in a variety of ways.

A destructor is a special member function that is called just before an object is destroyed. For example, when the object variable goes out of scope. It is used to perform cleanup. There can be only one destructor. Its name is ‘~’ followed by the class name.


11) What happens if an error occurs in a constructor or destructor?
Constructors don't have a return type, so it's not possible to use error codes. The best way to signal constructor failure is therefore to throw an exception. However, keep in mind that the memory for the object itself is released, and the destructors for all sub-objects (i.e. members and base classes) whose constructors have successfully run to completion will be called, which will consquently cause memory leak by the object pointer.


12) Differentiate between a copy constructor and an assignment operator.
The copy constructor is used to copy an object to a newly created object. This is used during initialization and not during ordinary assignment. The copy constructor is invoked whenever a new object is created and initialized to an existing object of the same kind.
In other words, the assignment operator handles assigning one object to another of the same class. If a statement creates a new object it is using initialization. If it alters the value of an existing object it is assignment.


13) What are virtual destructors?
Destructor implemented by declaring a base class’s destructor with the keyword virtual is called a virtual destructor. A virtual destructor ensures that, when delete is applied to a base class pointer or reference, it calls the destructor implemented in the derived class, if an implementation exists.
Let’s take the simplest polymorphic relation: A - base class, B - class derived from A. If we've got a pointer (or reference) to class A, but under the hood it is an object of type B, and we're trying to delete the object, declaration of virtual destructor in class A ensures that the destructor of class B will be called.
B* b = new B;
A* a = b //due to polymorphism!
delete a; // both A and B destructors are called.


14) What is multiple inheritance? What are the potential pitfalls of multiple inheritance? How would you avoid multiple inheritance?
Deriving a class from more than one direct base class is called multiple inheritance. Note that the order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.

Potential pitfalls of Multiple Inheritance are: 1) Ambiguity; 2) slow; 3) The “Common Ancestor” problem: For example, if class B and class C derived from class A and if class D derived from class B and class C, then class D will have 2 copies of class A that might lead to inconsistency, as the class doesn't know which copy it is viewing.


15) What is exception handling? What are the advantages of exception handling?
Exceptions are an alternative to function return values. The big differences are: 1) Exceptions cannot be ignored. They must be caught or the app will crash. It is a way of forcing the caller of a function to deal with an exceptional condition. 2) It is also an improvement over return values, because you can put all possible values of your return type to good use, instead of having to dedicate one or more values as the "invalid" value. 3) In addition, exceptions allow you to jump out of deeply nested function calls conveniently, avoiding a lot of return type checking and conditional statements.


16) What is the difference between new()/delete() and malloc()/free ()?
The main difference is that malloc() and free() don't know anything about constructors and destructors, where as new and delete do. The following lists the main differences: 1) new automatically computes the size of the data object. In malloc you would have to use the sizeof operator. 2) new automatically returns the correct pointer type. In malloc you would have to use a type cast. 3) with new you can initialize the object while creating the object. 4) new and delete can be overloaded. 5) It's safe to delete a NULL pointer, but you'll get core dump to free a NULL pointer.


17) Describe different types of polymorphism available in C++.
1. Compile time polymorphism; 2. Runtime Polymorphism. Operator overloading and Function Overloading are the examples for compile time polymorphism. Using Virtual Functions we will achieve run time polymorphism.

Computer Network

The Internet Protocol (IP) is a key part of the mechanism for transferring data across the internet. Information is broken into small packets, and the IP is responsible for relaying and routing them around the system by identifying and locating hosts. The current version is IPv4, and because it is made up in sets of 32 bits, it is limited to having just under 4.3 billion addresses. It seems like a lot but they are almost all used up.

March 3, 2011

interview at the point of interviewer

also comes from Joel on software

How do you detect smart in an interview? The first good sign is that you don’t have to explain things over and over again. The conversation just flows. Often, the candidate says something that shows real insight, or brains, or mental acuity. So an important part of the interview is creating a situation where someone can show you how smart they are. Remember, smart does not mean “knows the answer to trivia questions.” Anyway, software teams want to hire people with aptitude, not a particular skill set. Any skill set that people can bring to the job will be technologically obsolete in a couple of years, anyway, so it’s better to hire people that are going to be able to learn any new technology rather than people who happen to know how to make JDBC talk to a MySQL database right this minute. In general, the way to learn the most about a person is to let them do the talking. Give them open-ended questions and problems.

That’s just a list of questions that I want to ask. Here’s a typical plan for interviewing a programmer:

1. Introduction
2. Question about recent project candidate worked on
3. Easy Programming Question
4. Pointer/Recursion Question
5. Are you satisfied?
6. Do you have any questions?

What should you look for during the open ended questions?

One: Look for passion. Smart people are passionate about the projects they work on. They get very excited talking about the subject. They talk quickly, and get animated. Being passionately negative can be just as good a sign. “My last boss wanted to do everything on VAX computers because it was all he understood. What a dope!” There are far too many people around that can work on something and not really care one way or the other. It’s hard to get people like this motivated about anything.

Bad candidates just don’t care and will not get enthusiastic at all during the interview. A really good sign that a candidate is passionate about something is that when they are talking about it, they will forget for a moment that they are in an interview. Sometimes a candidate comes in who is very nervous about being in an interview situation—this is normal, of course, and I always ignore it. But then when you get them talking about Computational Monochromatic Art they will get extremely excited and lose all signs of nervousness. Good. I like passionate people who really care. (To see an example of Computational Monochromatic Art try unplugging your monitor.) You can challenge them on something (try it—wait for them to say something that’s probably true and say “that couldn’t be true”) and they will defend themselves, even if they were sweating five minutes ago, because they care so much they forget that you are going to be making Major Decisions About Their Life soon.

Two: Good candidates are careful to explain things well, at whatever level. I have rejected candidates because when they talked about their previous project, they couldn’t explain it in terms that a normal person could understand. Often CS majors will just assume that everyone knows what Bates Theorem is or what O(log n) means. If they start doing this, stop them for a minute and say, “could you do me a favor, just for the sake of the exercise, could you please explain this in terms my grandmother could understand.” At this point many people will still continue to use jargon and will completely fail to make themselves understood. Gong! You don’t want to hire them, basically, because they are not smart enough to comprehend what it takes to make other people understand their ideas.

Three: If the project was a team project, look for signs that they took a leadership role. A candidate might say, “We were working on X, but the boss said Y and the client said Z.” I’ll ask, “So what did you do?” A good answer to this might be “I got together with the other members of the team and wrote a proposal…” A bad answer might be, “Well, there was nothing I could do. It was an impossible situation.” Remember, Smart and Gets Things Done. The only way you’re going to be able to tell if somebody Gets Things Done is to see if historically they have tended to get things done in the past. In fact, you can even ask them directly to give you an example from their recent past when they took a leadership role and got something done—overcoming some institutional inertia, for example.

Most of the time in the interview, though, should be spent letting the candidate prove that they can write code. Reassure candidates that you understand that it’s hard to write code without an editor, and you will forgive them if the whiteboard gets really messy. Also you understand that it’s hard to write bug-free code without a compiler, and you will take that into account.

These softball questions seem too easy, so when I first started asking them, I had to admit that I really expected everyone to sail right through them. What I discovered was that everybody solved the problem, but there was a lot of variation in how long it took them to solve. That reminded me of why I couldn’t trade bonds for a living (http://www.joelonsoftware.com/articles/GuerrillaInterviewing3.html), which means that if the basic concepts aren’t so easy that you don’t even have to think about them, you’re not going to get the big concepts. You see, if you can’t whiz through the easy stuff at 100 m.p.h., you’re never gonna get the advanced stuff.

15 years of experience interviewing programmers has convinced me that the best programmers all have an easy aptitude for dealing with multiple levels of abstraction simultaneously. In programming, that means specifically that they have no problem with recursion (which involves holding in your head multiple levels of the call stack at the same time) or complex pointer-based algorithms (where the address of an object is sort of like an abstract representation of the object itself). Furthermore, I’ve come to realize that understanding pointers in C is not a skill, it’s an aptitude. Pointers require a complex form of doubly-indirected thinking that some people just can’t do, and it’s pretty crucial to good programming. A lot of the “script jocks” who started programming by copying JavaScript snippets into their web pages and went on to learn Perl never learned about pointers, and they can never quite produce code of the quality you need.

That’s the source of all these famous interview questions you hear about, like “reversing a linked list” or “detect loops in a tree structure.” Even though the format of the interview is, superficially, just a candidate writing some code on the whiteboard, my real goal here is to have a conversation about it. “Why did you do it that way?” “What are the performance characteristics of your algorithm?” “What did you forget?” “Where’s your bug?”

That means I don’t really mind giving programming problems that are too hard, as long as the candidate has some chance of starting out, and then I’m happy to dole out little hints along the way, little toeholds, so to speak. I might ask someone, say, to project a triangle onto a plane, a typical graphics problem, and I don’t mind helping them with the trig (SOH-CAH-TOA, baby!), and when I ask them how to speed it up, I might drop little hints about look-up tables. Notice that the kinds of hints I’m happy to provide are really just answers to trivia questions—the kinds of things that you find on Google.

Inevitably, you will see a bug in their function. So we come to question five from my interview plan: “Are you satisfied with that code?” You may want to ask, “OK, so where’s the bug?” The quintessential Open Ended Question From Hell. All programmers make mistakes, there’s nothing wrong with that, they just have to be able to find them. With string functions in C, most college kids forget to null-terminate the new string. With almost any function, they are likely to have off-by-one errors. They will forget semicolons sometimes. Their function won’t work correctly on 0 length strings, or it will GPF if malloc fails… Very, very rarely, you will find a candidate that doesn’t have any bugs the first time. In this case, this question is even more fun. When you say, “There’s a bug in that code,” they will review their code carefully, and then you get to see if they can be diplomatic yet firm in asserting that the code is perfect.

XML is a Dumb Format For Storing Data

originally wrote by Joel Spolsky

I'm not sure why XML got so sexy. It has its advantages; it's sure a good idea for data interchange or for all those little files you need to store settings. But for real work it just can't do what a solid, multiuser, relational database can do. The next time some uninformed analyst at Gartner or Giga or Forrester tells you "in the future, everything will be XML," ask them how to do "SELECT author FROM books" fast with XML. Hint: you can't. It has to be slow. XML is not the way to store a lot of data. Now tell me how to insert a new book at the beginning of the table without massive bitblts. Of course, I doubt if there is an analyst in one of those companies who would even understand that sentence, but that's life. Now lets look at the books table in XML.

<?xml blah blah>
<books>
    <book>
        <title>UI Design for Programmers</title>
        <author>Joel Spolsky</author>
    </book>
    <book>
        <title>The Chop Suey Club</title>
        <author>Bruce Weber</author>
    </book>
</books>

Quick question. What is the code to move to the next record?

Uh...

At this point a good programmer would say, well, let's parse the XML into a tree in memory so that we can operate on it reasonably quickly. The amount of work that has to be done here by the CPU to SELECT author FROM books will bore you absolutely to tears. As every compiler writer knows, lexing and parsing are the slowest part of compiling. Suffice it to say that it involves a lot of string stuff, which we discovered is slow, and a lot of memory allocation stuff, which we discovered is slow, as we lex, parse, and build an abstract syntax tree in memory. That assumes that you have enough memory to load the whole thing at once. With relational databases, the performance of moving from record to record is fixed and is, in fact, one CPU instruction. That's very much by design. And thanks to memory mapped files you only have to load the pages of disk that you are actually going to use. With XML, if you preparse, the performance of moving from record to record is fixed but there's a huge startup time, and if you don't preparse, the performance of moving from record to record varies based on the length of the record before it and is still hundreds of CPU instructions long.

What this means to me is that you can't use XML if you need performance and have lots of data. If you have a little bit of data, or if what you're doing doesn't have to be fast, XML is a fine format. And if you really want the best of both worlds, you have to come up with a way to store metadata next to your XML, something like Pascal strings' byte count, which give you hints about where things are in the file so that you don't have to parse and scan for them. But of course then you can't use text editors to edit the file because that messes up the metadata, so it's not really XML anymore.

------
By the way, when I published this digest from Joel, I have no idea how to put the HTML code in my blog contents. Here is the solution, and the full table of escape characters are here.

March 2, 2011

some advices about low-level programming

see also <Back to Basic>
reference <Advice for Computer Science College Students>


Learn how to write

The difference between a tolerable programmer and a great programmer is not how many programming languages they know, and it's not whether they prefer Python or Java. It's whether they can communicate their ideas. By persuading other people, they get leverage. By writing clear comments and technical specs, they let other programmers understand their code, which means other programmers can use and work with their code instead of rewriting it. Absent this, their code is worthless. By writing clear technical documentation for end users, they allow people to figure out what their code is supposed to do, which is the only way those users can see the value in their code. There's a lot of wonderful, useful code buried on sourceforge somewhere that nobody uses because it was created by programmers who don't write very well (or don't write at all), and so nobody knows what they've done and their brilliant code languishes.

If you can write, wherever you get hired, you'll soon find that you're getting asked to write the specifications and that means you're already leveraging your influence and getting noticed by management. Start a journal or weblog. The more you write, the easier it will be, and the easier it is to write, the more you'll write, in a virtuous circle.

Learn C

C. Notice I didn't say C++. Although C is becoming increasingly rare, it is still the lingua franca of working programmers. It is the language they use to communicate with one another, and, more importantly, it is much closer to the machine than "modern" languages that you'll be taught in college like ML, Java, Python, whatever trendy junk they teach these days. You need to spend at least a semester getting close to the machine or you'll never be able to create efficient code in higher level languages. You'll never be able to work on compilers and operating systems, which are some of the best programming jobs around. You'll never be trusted to create architectures for large scale projects. I don't care how much you know about continuations and closures and exception handling: if you can't explain why "while (*s++ = *t++);" copies a string, or if that isn't the most natural thing in the world to you, well, you're programming based on superstition, as far as I'm concerned: a medical doctor who doesn't know basic anatomy, passing out prescriptions based on what the pharma sales babe said would work.

some special cases to indicate this point
char bigString[1000];     /* I never know how much to allocate... */

bigString[0] = '\0';
strcat(bigString,"John, ");
strcat(bigString,"Paul, ");

strcat(bigString,"George, ");

strcat(bigString,"Joel ");

The time consumption will increase as the n^2, where n indicates the number of characters that have already in the char array, for the reason that every time the strcat will begin to search at the beginning of the array. To reduce the runtime decrease as linear as input number of values:
char* mystrcat( char* dest, char* src )

{
     while (*dest) dest++;

     while (*dest++ = *src++);
     return --dest;
}
char bigString[1000];     /* I never know how much to allocate... */
char *p = bigString;

bigString[0] = '\0';

p = mystrcat(p,"John, ");
p = mystrcat(p,"Paul, ");

p = mystrcat(p,"George, ");
p = mystrcat(p,"Joel ");

The designers of Pascal were aware of this problem and "fixed" it by storing a byte count in the first byte of the string. These are called Pascal Strings. They can contain zeros and are not null terminated. Because a byte can only store numbers between 0 and 255, Pascal strings are limited to 255 bytes in length, but because they are not null terminated they occupy the same amount of memory as ASCIZ strings. The great thing about Pascal strings is that you never have to have a loop just to figure out the length of your string. Finding the length of a string in Pascal is one assembly instruction instead of a whole loop. It is monumentally faster.

The old Macintosh operating system used Pascal strings everywhere. Many C programmers on other platforms used Pascal strings for speed. Excel uses Pascal strings internally which is why strings in many places in Excel are limited to 255 bytes, and it's also one reason Excel is blazingly fast.

For a long time, if you wanted to put a Pascal string literal in your C code, you had to write:

char* str = "\006Hello!";

Yep, you had to count the bytes by hand, yourself, and hardcode it into the first byte of your string. Lazy programmers would do this, and have slow programs:

char* str = "*Hello!";
str[0] = strlen(str) - 1;

Notice in this case you've got a string that is null terminated (the compiler did that) as well as a Pascal string. I used to call these fucked strings because it's easier than calling them null terminated pascal strings but this is a rated-G channel so you will have use the longer name.

Well, since we're looking at the bits today I shouldn't have ignored this. I should have done this correctly: figured out how many bytes I needed and allocated the right amount of memory. Shouldn't I have?

Because otherwise, you see, a clever hacker will read my code and notice that I'm only allocating 1000 bytes and hoping it will be enough, and they'll find some clever way to trick me into strcatting a 1100 byte string into my 1000 bytes of memory, thus overwriting the stack frame and changing the return address so that when this function returns, it executes some code which the hacker himself wrote. This is what they're talking about when they say that a particular program has a buffer overflow susceptibility. It was the number one cause of hacks and worms in the olden days before Microsoft Outlook made hacking easy enough for teenagers to do.

(bold malloc...)How does the malloc work? The nature of malloc is that it has a long linked list of available blocks of memory called the free chain. When you call malloc, it walks the linked list looking for a block of memory that is big enough for your request. Then it cuts that block into two blocks -- one the size you asked for, the other with the extra bytes, and gives you the block you asked for, and puts the leftover block (if any) back into the linked list. When you call free, it adds the block you freed onto the free chain. Eventually, the free chain gets chopped up into little pieces and you ask for a big piece and there are no big pieces available the size you want. So malloc calls a timeout and starts rummaging around the free chain, sorting things out, and merging adjacent small free blocks into larger blocks. This takes 3 1/2 days. The end result of all this mess is that the performance characteristic of malloc is that it's never very fast (it always walks the free chain), and sometimes, unpredictably, it's shockingly slow while it cleans up. (This is, incidentally, the same performance characteristic of garbage collected systems, surprise surprise, so all the claims people make about how garbage collection imposes a performance penalty are not entirely true, since typical malloc implementations had the same kind of performance penalty, albeit milder.)

Smart programmers minimize the potential distruption of malloc by always allocating blocks of memory that are powers of 2 in size. You know, 4 bytes, 8 bytes, 16 bytes, 18446744073709551616 bytes, etc. For reasons that should be intuitive to anyone who plays with Lego, this minimizes the amount of weird fragmentation that goes on in the free chain. Although it may seem like this wastes space, it is also easy to see how it never wastes more than 50% of the space. So your program uses no more than twice as much memory as it needs to, which is not that big a deal. Furthermore, when you call realloc, you should always double the size of memory that was previously allocated. That means that you never have to call realloc more than lg n times, which has decent performance characteristics even for huge strings, and you never waste more than 50% of your memory.

March 1, 2011

tree search algorithm (cont.)

 The previous post is here
============
struct treeNode{
    int element;
    struct treeNode *left;
    struct treeNode *right;
}:
typedef struct treeNode *searchTree;


searchTree makeEmpty(searchTree T){
    if(T!=NULL){
        MakeEmpty(T->left);
        MakeEmpty(T->right);
        free(T);
    }
    return NULL;
}


searchTree findVal(int val, searchTree T){
    if(T==NULL)
        return NULL;
    if(valelement)
        return findVal(val, T->left);
    else if(val>T->element)
        return findVal(val, T->right);
    else
        return T;
}


searchTree findMin(searchTree T){
    if(T!=NULL)
        while(T->left!=NULL)
            T = T->left;
    return T;
}


searchTree insertVal(int val, searchTree T){
    if(T==NULL){
        T=(searchTree)malloc(sizeof(struct treeNode));
        if(T==NULL){
            printf("Error! There is no new memory to allocate.\n");
            exit(0);
        }
        T->element = val;
        T->left = T->right = NULL;
    }
    else{
        if(valelement)
            T->left = insertVal(val, T->left);
        else if(val>T->element)
            T->right = insertVal(val, T->right);
        else
            printf("The element has already in this tree.\n");
    }
    return T;
}


searchTree deleteVal( int val, searchTree T){
    searchTree temp;
    if(T==NULL){
        printf("The element is not found.\n");
        return NULL;
    }
    else if(valelement)
        T->left = deleteVal(val, T->left);
    else if(val>T->element)
        T->right = deleteVal(val, T->right);
    else{        // here, find the specific element
        if(T->left && T->right){
            temp = findMin(T->right);
            T->element = tmp->element;
            T->right = deleteVal(tmp->element, T->right);
        }
        else{
            temp = T;
            if(T->left == NULL)
                T = T->right;
            else if(T->right==NULL)
                T = T->left;
            free(temp);
        }
        return T;
    }
}

// the functions below returns node which element is closest
// and larger in the Tree. We could call it "next"
// assumption1: the inputs are inquiry val and the root node
searchTree nextLarger(int val, searchTree T){
    searchTree temp;
    if(T==NULL){
        printf("There is no tree.\n");
        return NULL;
    }
    if(valelement){
        if(T->left!=NULL){
            temp = T->left;
            while(valelement && temp->left!=NULL){
                T = temp;
                temp = temp->left;
            }
            // This case indicate "temp->left==NULL" causes stop
            // so temp should be the return value
            if(valelement)
                T = temp;
            // otherwise, result might in a new right tree
            // . or the parent node in this layer
            else{
                if (temp->right!=NULL){
                    temp = nextLarger(val, temp->right);
                    if (temp!=NULL)
                        T = temp;
                }
            }
        }
        return T;
    }
    else{
        while(val>=T->element && T->right!=NULL)
            T = T->right;
        if(valelement){
            T = nextLarger(val, T);
            return T;
        }
        else
            return NULL;
    }
}


// assumption2: the input value is a given node in the tree.
// In this case, we might have to trace back.
// As a resutl, the original struct needs a little modification
struct treeNode{
    int element;
    struct treeNode *left;
    struct treeNode *right;
    struct treeNode *parenet;    // to trace back
}:
typedef struct treeNode *searchTree;

searchTree nextLarger2(searchTree start){
    searchTree temp, record;
    if(start==NULL){
        printf("There is not a valid input.\n");
        return NULL;
    }
   
    if(start->right!=NULL){
        start = findMin(start->right);
        return start;
    }
    else if(start->parent!=NULL){
        if(start == start->parent->left)
            return start;
        else{
            while(start->parent!=NULL && start!=start->parent->left)
                start = start->parent;
            if(start==start->parent->left)
                return start;
            else
                return NULL;
        }
    }
}



// references: <Introduction to algorithms>, <Coding Interviews>

// I just did some terrible interviews these days. Yes, some, and terrible.
// So, I wanna record everything here, 

// no matter how stupid and rudimentary it is.
// Also as a means to push myself, everyday a step further.

Days of our lives

Daisypath Anniversary tickers