2013年11月29日星期五

阮一峰的网络日志

阮一峰的网络日志


Stack的三种含义

Posted: 28 Nov 2013 06:57 PM PST

学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈"。

理解这个概念,对于理解程序的运行至关重要。容易混淆的是,这个词其实有三种含义,适用于不同的场合,必须加以区分。

含义一:数据结构

stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in, first out)。

数据结构stack

在这种数据结构中,数据像积木那样一层层堆起来,后面加入的数据就放在最上层。使用的时候,最上层的数据第一个被用掉,这就叫做"后进先出"。

与这种结构配套的,是一些特定的方法,主要为下面这些。

  • push:在最顶层加入数据。
  • pop:返回并移除最顶层的数据。
  • top:返回最顶层数据的值,但不移除它。
  • isempty:返回一个布尔值,表示当前stack是否为空栈。

含义二:代码运行方式

stack的第二种含义是"调用栈"(call stack),表示函数或子例程像堆积木一样存放,以实现层层调用。

下面以一段Java代码为例(来源)。

 class Student{     int age;                   String name;            public Student(int Age, String Name)     {         this.age = Age;         setName(Name);     }     public void setName(String Name)     {         this.name = Name;     } }  public class Main{     public static void main(String[] args) {             Student s;                        s = new Student(23,"Jonh");     } }  

上面这段代码运行的时候,首先调用main方法,里面需要生成一个Student的实例,于是又调用Student构造函数。在构造函数中,又调用到setName方法。

调用栈

这三次调用像积木一样堆起来,就叫做"调用栈"。程序运行的时候,总是先完成最上层的调用,然后将它的值返回到下一层调用,直至完成整个调用栈,返回最后的结果。

含义三:内存区域

stack的第三种含义是存放数据的一种内存区域。程序运行的时候,需要内存空间存放数据。一般来说,系统会划分出两种不同的内存空间:一种叫做stack(栈),另一种叫做heap(堆)。

内存区域stack

它们的主要区别是:stack是有结构的,每个区块按照一定次序存放,可以明确知道每个区块的大小;heap是没有结构的,数据可以任意存放。因此,stack的寻址速度要快于heap。

内存区域heap

其他的区别还有,一般来说,每个线程分配一个stack,每个进程分配一个heap,也就是说,stack是线程独占的,heap是线程共用的。此外,stack创建的时候,大小是确定的,数据超过这个大小,就发生stack overflow错误,而heap的大小是不确定的,需要的话可以不断增加。

根据上面这些区别,数据存放的规则是:只要是局部的、占用空间确定的数据,一般都存放在stack里面,否则就放在heap里面。请看下面这段代码(来源)。

 public void Method1() {     int i=4;      int y=2;      class1 cls1 = new class1(); }  

上面代码的Method1方法,共包含了三个变量:i, y 和 cls1。其中,i和y的值是整数,内存占用空间是确定的,而且是局部变量,只用在Method1区块之内,不会用于区块之外。cls1也是局部变量,但是类型为指针变量,指向一个对象的实例。指针变量占用的大小是确定的,但是对象实例以目前的信息无法确知所占用的内存空间大小。

这三个变量和一个对象实例在内存中的存放方式如下。

内存空间stack实例

从上图可以看到,i、y和cls1都存放在stack,因为它们占用内存空间都是确定的,而且本身也属于局部变量。但是,cls1指向的对象实例存放在heap,因为它的大小不确定。作为一条规则可以记住,所有的对象都存放在heap。

接下来的问题是,当Method1方法运行结束,会发生什么事?

回答是整个stack被清空,i、y和cls1这三个变量消失,因为它们是局部变量,区块一旦运行结束,就没必要再存在了。而heap之中的那个对象实例继续存在,直到系统的垃圾清理机制(garbage collector)将这块内存回收。因此,一般来说,内存泄漏都发生在heap,即某些内存空间不再被使用了,却因为种种原因,没有被系统回收。

(完)

文档信息

2013年11月10日星期日

阮一峰的网络日志

阮一峰的网络日志


向着未来而生----《黑客与画家(精装本)》序言

Posted: 09 Nov 2013 07:00 AM PST

《黑客与画家》再版了,刚刚上架。

内容没变,但是升级成了精装本,纸张好了许多。

《黑客与画家(精装本)》

《黑客与画家(精装本)》

《黑客与画家(精装本)》

想要收藏和送人的朋友,可以考虑购买(京东当当亚马逊china-pub)。

下面是我为再版写的序言。另外,《软件随想录》有希望明年再版。

=============================================

向着未来而生

阮一峰 / 2013-03-29

《黑客与画家(精装本)》

不久前,收到朱巍编辑的来信。她说《黑客与画家》即将出版精装本,希望我作为译者,能写一些感言。

我这才惊觉,距离我动手翻译,已经过去了3年。真是时光催人老,三年前我坐在同一张书桌前,使用同一个键盘,一字一字地输入译文,宛如发生在昨日。

回想起来,那时心里没有把握,不知道中文版会不会被中国读者接受。因为IT图书的生命周期很短,三四年前的出版物往往已经过时,《黑客与画家》的英文版出版于2004年,其中不少文章写于2001年。现在推出中文版会不会太迟了?

事实证明,我的担心是多余的。中文版上市后,引起了巨大的反响,在国内IT业界受到广泛的肯定,很多程序员和项目经理读后表示深受启发,很多计算机系的老师将此书列为学生的推荐读物。我也收到了许多读者来信,摘录几封:

"......我这两天一直在看,有醍醐灌顶的感觉。"

"......我觉得自己看得好还不过瘾,又向学校图书馆荐购了。"

"......我们团队人手一本《黑客与画家》,并且至今共赠送了近百本给我们的用户。"

我一方面很高兴,另一方面也很赞叹Paul Graham。他是怎么做到的,让一本技术类书籍吸引10年后的读者?

后来,我总结出两个原因。第一,他写的不是技术,而是技术背后的思想。就像数学一样,正确的思想是不会过时的。第二,他的着眼点是长远的未来。文章内容主要不是分析现状,更不是总结过去,而是展望未来,以未来指导现在。举例来说,第11章《一百年后的编程语言》就是研究一百年后人们会怎么编程,从而推导到我们现在应该如何编程。除了他以外,我没见过其他人有这种视角。另一个证据是,Paul Graham最大的成就就是建立创业孵化器Y Combinator。这说明他对未来有精准的眼光,只有知道未来会怎样,才能选出最值得投资的创业公司。

正是因为这两个原因,《黑客与画家》完全没有过时。10年后的读者,一方面被已经实现的预言震撼(比如,Paul在2001年说,如果苹果公司将iPod升级成能上网的手机,就能战胜微软公司),另一方面又被那些还没实现的预言说动(比如,Lisp语言将成为主流),思考自己的选择。这是此书成功的最大原因:这是一本能帮你看清道路的书。

德国哲学家海德格尔说过一句著名的话:人应该"向死而生"(Being-toward-death)。意思是人面对死亡,才会停止那些无谓琐碎的关注和困扰,体会到什么是重要的事情,从而达到真正的存在。借用这种说法,我觉得Paul Graham的哲学是"向着未来而生"(Being-toward-future)。也就是说,我们的目光应该盯着未来的世界,以此决定人生应该怎么走。

说到未来的世界,我想起去年年底,美国国家情报委员会(National Intelligence Council,缩写NIC)发表了提交给总统的报告《全球趋势2030》下载)。其中一个主要结论是:

"......到了2030年,没有一个国家----无论是美国、中国或任何其他大国----将成为超级霸权。相反地,权力在国家之间变得分散,而且会从国家手中向非正式的网络、以及个人扩散,产生深刻的影响。......个人和小团体的力量将进一步被增强,更易获得各种调用资源的能力,在解决全球性挑战方面可能更有力。"

如果这种预测是正确的,就意味着未来20年里,政府的力量将缩小,个人和小团体将崛起,成为推动社会前进的主要力量。在这个过程中,互联网和计算机必然将扮演重要角色,因为正是它们将个体的影响力指数式地提升。

对于网络创业者来说,这是最好的时代。只要把握大趋势,技术会把个人送到难以想象的高度。

未来就在眼前,伸手可及。《黑客与画家》就是这次旅程的指南,为你指出通往那扇门的方向。正如Paul Graham所说,你要做的就是"活在未来,然后造出现在还没有的部分"(Live in the future, then build what's missing)。

(完)

文档信息

2013年11月4日星期一

阮一峰的网络日志

阮一峰的网络日志


柯文哲《生死的智慧》

Posted: 03 Nov 2013 07:13 AM PST

三天前,柯文哲医师在今年Ted Taipei的演讲《生死的智慧》,放上了Youtube

这段短短18分钟的演讲,异常精彩,发人深思。我忍不住把它整理出来,希望更多的人看到。

=================================================

生死的智慧

演讲人:柯文哲

时间地点:2013年9月28日 / 台北

视频:Youtube / 优酷 / 土豆

[介绍]

柯文哲(1959-),外科医师,台湾大学医学院附设医院"创伤医学部"主任,台湾大学医学院教授,专长为外伤、急救、器官移植等。

[正文]

1.

01.jpg

我大概是见过死人最多的台湾医生,很合适来谈生死的问题。

2.

02.jpg

让我从叶克膜开始讲起。

有一个笑话,谁是台湾最有名的医生。一个民众跑到柳营奇美医院,说要找叶医师。急症处的人说,没有啊,我们这里没有姓叶的。民众说,有的,他叫叶克膜,当年邵晓玲就是被他救起来的。

叶克膜其实很简单,就是静脉血引流出来,经过一个血液泵(人工心脏),再经过一个氧合器(人工肺脏),送回身体。它用来暂时取代心肺功能。

3.

03.jpg

真正的叶克膜大概就是这个样子,一个主机当人工心脏,旁边是一个氧合器,把血液送回去。

4.

04.jpg

叶克膜的确有非常成功的案例。这是一个周杰伦的舞群,有一天突发猛暴性心肌炎,心脏不跳了。

5.

05.jpg

当时,她的眼睛大大地看着荧幕,荧幕上的信号全是平的。

6.

06.jpg

这是她的心肌病理切片,放大了100倍。

7.

07.jpg

100倍还不是看得很清楚,放大400倍就很明显了,一个个蓝点就是淋巴球。这是很厉害的猛暴性心肌炎,整个心脏都被淋巴球浸润了。

8.

08.jpg

可是,九天之后,她就进行了心脏和肾脏移植。不到一个月,又回去跳舞了。

医学文献上,CPR(心肺复苏术)时间最长、还能被救回来的,就是这个案例。她从国泰医院一路CPR到台大医院,要装叶克膜的时候,发现强心剂已经打了100支了,股动脉和股静脉已经缩得比铅笔还细了,管子放不进去,只好继续用CPR,到开刀房直接锯胸,从上面放叶克膜。

这个案例听起来很神奇,我每次都说这是现代医学的奇迹。一个人经历了4个小时的CPR,九天没有心脏功能,还能救回来。

9.

09.jpg

这是另外一个案例,报纸写"全球首例,台湾奇迹,男无心脏活16天"。

10.

10.jpg

这是一个56岁的男子,因为蛀牙,细菌跑到血液里面,再跑到心脏,后来就化脓。在其他医院,打开心脏一看,发现有的地方烂掉了,就给他剪一剪,最后整个心脏都被剪掉了。

怎么办?只好转到台大医院。

11.

11.jpg

到台大医院的时候,因为几乎没有心脏功能,就用了两台叶克膜。图片上有两台主机。

12.

12.jpg

刚才那个案例是有心脏不会跳,这个更厉害,连心脏都没有了,剪掉了,心电图干脆就一条线了。

13.

13.jpg

这是他的电脑断层扫描,理论上,胸腔里应该有一颗心脏,可是现在没有心脏,只看到一些管子。

14.

14.jpg

十六天以后,我们给这个病人做心脏移植。

这是心脏外科教授王水深给我看的。他说,锯胸以后,没有看到心脏,只看到一些塑胶管子,接到外面的叶克膜上。

15.

15.jpg

这个病人做了心脏移植,最后还是很清醒地回家了。这是新加坡《海峡日报》的报道《Sixteen Days Without A Heart》。

16.

16.jpg

还有一个案例。一个26岁的原住民,酒醉以后去游泳,被水呛到,得了严重的肺炎,叶克膜用了117天。

17.

17.jpg

可以看到,他得了很严重的肺炎(又称急性呼吸窘迫征),整个肺都白掉了。

18.

18.jpg

他用了117天叶克膜。这个图可以看得很清楚,差不多长达一个月,他的肺通气量不到100cc。不过,最后还是慢慢恢复了。

上面这些案例,使用叶克膜以后,可以撑到9天、16天、甚至100多天,然后再进行心脏移植、心肺移植,或者自己好起来。这实在是太神奇了。所以,在媒体的炒作下,叶克膜在台湾变得这么有名,确实有一些很成功的案例。

19.

19.jpg

可是,媒体通常只报道成功的案例,不报道失败的案例。作为一个医生,看到成功的案例当然很高兴,但是也不能不看到失败的案例。

这是一个出生一个半月、先天性心脏病的婴儿,心脏手术以后,没有办法脱离心肺机,所以就装了叶克膜。

20.

20.jpg

可是不到三天,他的脚就黑掉了。这时候,医生就面临一个选择。你是要把他的双脚剁掉,继续再救,还是算了,不再努力了?这是很大的压力。

21.

21.jpg

如果上面的案例,你都很困难做决定。那么这一个案例,就更难了。

这是一个七岁的男孩,得了肺炎双球菌败血症,引起呼吸窘迫,后来装了叶克膜。

22.

22.jpg

装了以后,出现并发症,四肢都黑掉了。他眼镜大大地看着你,意识清楚,会讨水喝。可是作为一个医生,你面临选择。如果要救他,就要把四肢剁掉,如果不救,就要把机器关掉。

你想想看,在生死之间,病人头脑清楚,我怎么跟他讲:"小弟弟,如果你要活下去,我们要剁掉你的四肢。或者算了,你不要再活了。"你如何跟一个7岁的男孩,讲这种生死的问题?

23.

23.jpg

这就是我当一个重症医学专家的心路历程。

三十几岁,我就当上了主任,觉得医学很厉害,什么都可以解决。可是到了40岁以后,常常有装了叶克膜还是失败的案例,家属问我:"为什么别人救得回来,我们的亲人救不回来?"我也不晓得怎么回答。为什么病人的四肢会黑掉?我要是知道,就可以避免了,就是不知道啊。

24.

24.jpg

慢慢地到了50岁以后,我终于想通一个道理。医生是人不是神,我们只能尽力,仅此而已。

不管医学如何发达,还是有其极限。以现在的科技,没有心、肺、肾,还可以存活,但是难道就这样装着机器过一辈子吗?

大自然有春夏秋冬,园丁能不能改变这种规律?当然没有办法,园丁只能让花在春夏秋冬里面开得好看一点。一个医生有办法改变生老病死吗?很困难。医生只是让人在生老病死之间活得好看一点,仅此而已。

25.

25.jpg

医师只是生命花园的园丁,他到底如何面对草木的枯荣,面对死亡呢?

从科学上讲,一切物理化学反应,都应该趋向最低能量、最大乱度,也就是越来越混乱。人的存在是违反这种趋向的。这是一个很重要的概念,任何有组织的团体都是不稳定的,必须破坏环境,才能使得总的趋向是最低能量、最大乱度。有一天,我再不能破坏环境,就只好破坏我自己,这就叫死亡。

26.

26.jpg

有一天,我在巡房的时候,突然大彻大悟。人生的结局只有两种:插管和不插管,但都是死。

你问我,什么是死亡?我的回答是,怎样才算活着?你问我,什么是人生,我的回答是,追求这个问题的答案就是这个问题的答案。

因为人一定会死,所以死亡不是人生的目的,人生就是一个过程,我们在这个过程中不断去追寻一个问题,这就是人生。

27.

27.jpg

最近,我常常讲"一坨大便"的启示。

有一次,我的老师退休了,我就请老师和学长吃饭。我们三个人到喜来登饭店二楼的法国餐厅,结果吃了26000元,平均每人9000元!我看到帐单的时候,脸都绿了,怎么这么贵!我没有去过这种地方,都是乱点的,也不晓得点了什么菜要26000元。第二天早上,我上厕所,一直在看我的大便,这个花了我9000元才制造出来的东西,看来看去,跟我平时去台大医院地下室吃70元一顿的自助餐,看不出差别。我在厕所里面,突然悟到,人生的荣华富贵不过就是一坨大便。

28.

28.jpg

中国人最重要的思想是儒家学说,可是《论语》说"未知生,焉知死"、"未能事人、焉能事鬼"、"生,事之以礼;死,葬之以礼,祭之以礼",总之就是不想谈论死亡。如果你一直追问,它就说"舍生取义"、"朝闻道夕可死矣"。儒家对生死问题采取一种逃避的态度,就是不想讨论。

这种做法积极的一面,当然是让人们重视活着的时候,可是终究没有回答死亡。

29.

29.jpg

我的个人看法是"置于死地而后生",我们唯有面对死亡,才能看清人生到底是什么。人终究会死,人生只是一个追求人生意义的过程。

人生应该像a的n次方。如果a大于1,a的n次方就无限大;如果a小于1,a的n次方很快就趋近于零。你知道这是什么意思?我对社会的付出多于索取,就代表a大于1,每个人都如此,社会就会越来越好,如果每个人对社会都是索取大于付出,就代表a小于1,社会很快就会崩溃。

我用下面这句话,作为今天的结束语:"最困难的不是面对各种挫折打击,而是面对各种挫折打击,却不失去对人世的热情。"

谢谢各位。

(完)

文档信息