Browsed by
Category: 计算机与 Internet

史上最强!PC时代的20位英雄

史上最强!PC时代的20位英雄

   这是一个热爱英雄的时代。  回首PC20年,它的历史就是一部英雄的历史,一个个闪亮的名字,就像一颗颗璀璨的星星,为人羡慕、令人敬仰;他们对PC业的兴起,对计算机技术的繁荣,对人类的贡献是我们不应忘记的。当本文重现历史的一幕幕时,我们会看到什么?无疑,其中有光辉与荣耀,有财富与成就,当然,也有遗憾与悲怆……   电脑始祖   冯·诺依曼(John Von Neuman)凭他的天才和敏锐,在电脑初创期,高屋建瓴地提出了现代计算机的理论基础,从而规范和决定了电脑的发展方向。时至今日,我们所有的电脑又都叫“冯·诺依曼机器”,就是对这位数学天才最好的评价。   对于冯·诺依曼来说,人类第一台电脑造了一半时才参与开发,多少有些遗憾。但是,他刚好在那大机器程序存储问题无法解决的关键时刻出现,这使得冯·诺依曼的天才得到淋漓尽致的发挥。他明确指出:一定要彻底实现程序由外存储向内存储的转化,原有的设计必须作修改,经费不够再追加。在冯·诺依曼的影响下,整个研制工作取得了突破性的进展。冯·诺依曼提出了新的改进方案:一是用二进制代替十进制,进一步提高电子元件的运算速度;二是存储程序(Stored Program),即把程序放在计算机内部的存储器中,换言之,把能进行数据处理的程序放在数据处理系统内部,程序和该程序处理的数据用同样的方式储存,即把程序本身当作数据来对待。冯·诺依曼的改进方案被称为“爱达法克”(EDVAC),即离散变量自动电子计算机(Electronic Diserete Variable Computer)的简称。   1945年6月,他写了一篇题为《关于离散变量自动电子计算机的草案》的论文,第一次提出了在数字计算机内部的存储器中存放程序的概念(Stored Program Concept),这是所有现代电子计算机的范式,被称为“冯·诺依曼结构”。按这一结构建造的电脑称为存储程序计算机(Stored Program Computer),又称为通用计算机。时至今日,所有的电脑都逃脱不了冯·诺依曼的掌心,我们所有的电脑,都有一个共同的名字,叫“冯·诺依曼机器”,它超越了品牌、国界、速度和岁月。     摩尔定律   当人们不断追逐新款PC时,殊不知这后面有一只无形的大手在推动,那就是摩尔定律,而这著名定律的发明人就是高登·摩尔(Gordon Moore)。     高登·摩尔   1965年的一天,摩尔顺手拿了把尺子和一张纸,画了一张草图,纵坐标代表不断发展的集成电路,横坐标是时间。他在月份上逐个描点,得到一幅增长的曲线图。这条曲线显示出每24个月,集成电路由于内部晶体管数量的几何级数的增长,而使性能几乎翻倍提高,同时集成电路的价格也恰好减少一倍。后来高登·摩尔把时间调整为18个月。摩尔是在集成电路技术的早期作出结论的,那时候,超大规模集成电路技术还远未出现,所以他在1965年的预言并未引起世人的注意。   高登·摩尔的另一壮举是在1968年与罗伯特·诺伊斯带头“造反”,率领一群工程师离开仙童公司,成立了一家叫集成电子的公司,简称“Intel”,这就是今日名震世界的英特尔公司。     预言大师   凯的形象既不像傲慢自大、反潮流的黑客,也不同于一夜暴富的计算机富翁,更不像象牙塔里的计算机科学家。他时常穿着跑鞋和灯芯绒裤子,一小撮胡子,短短的、略微零乱的头发,使他看上去极为普通。即使他是你的老板,可能也不会给你留下多深的印象。但这也不是说他很谦逊,他喜欢引用自己的话,且经常以这样的词作为发言的开端:“凯的第一法则指出……”。   阿伦·凯(Alan Kay)不是一位公众人物,但在计算机界,尤其是技术圈内,他是能让大家都心服口服屈指可数的大师之一。成为硅谷的又一位亿万富翁或让他当麻省理工的院长,都无法激起他的兴奋,但他会有足够的耐性与一群8岁左右的孩子一起玩电脑。他最大的乐趣就是发明他喜欢的东西。   阿伦·凯是Smalltalk面向对象编程环境语言的发明人之一,也是面向对象编程思想的创始人之一,同时,他还是笔记本电脑最早的构想者和现代Windows GUI的建筑师。   近年来有一句话挺流行:“预测未来的最好办法,就是把它创造出来。”不少人误以为此言出自尼葛洛庞帝之口,实际上,这句话是阿伦·凯的名言。有很多人说布兰德是第一个使用PC一词的人,但布兰德说自己也是顺手牵羊,最早提出“PC”概念的就是阿伦·凯。20世纪90年代程序员设计的基本模式就是“面向对象”,发明这一术语的也是阿伦·凯。在20世纪70年代的一份备忘录上,阿伦·凯还正确预言到,“20世纪90年代将有成百万的个人计算机,而且都将连接到全球公用的信息设施上”,这不正是今天的互联网吗?     集成电路之父   硅谷是传奇人士扎堆之地。但是一个人要想在硅谷同时获得财富、威望和成就,实在比登天还难。举目远眺大概只有罗伯特·诺伊斯(Robort Noyce)才是惟一一位三位于一体式的人物。   作为集成电路的发明者,诺伊斯在科学史上已名垂青史,这个具有划时代意义的发明促成了历史的大转折。而且他还与别人共同创办了两家硅谷最伟大的公司,第一家是半导体工业的摇篮——仙童(Fairchild)公司,这已成为历史;第二家则仍跻身美国最大的公司之列,这就是英特尔公司。他带着特有的神圣和威严,让同行和对手都得永远敬仰。以尖刻著称的硅谷杂志《Upside》敢对硅谷任何一位大腕儿进行任何刺激,但对诺伊斯却只能毕恭毕敬,在诺伊斯去世前几天的采访录,甚至成为杂志社经常炫耀的一种荣光。   在仙童,诺伊斯最大的成就是发明了集成电路。当基尔比在德州仪器用锗晶片研制集成电路时,诺伊斯和摩尔已把眼光直接盯住了硅晶片,因为硅的商业前景要远远超出锗。1959年2月,诺伊斯为“微型电路”申请了专利,但没有为他用平面处理技术制造的集成电路申请专利,直到同年7月才补全了这一手续。而此前德州仪器公司已宣布生产集成电路的产品,该公司的基尔比拥有第一个专利,但他的设计不实际,而诺伊斯则是第二个提出该专利的人。于是整个60年代,仙童和德仪相互控告,最后法庭将集成电路的发明专利授予了基尔比,而将关键的内部连接技术专利授予诺伊斯。诺伊斯的专利使仙童公司在沉闷的70年代得以存活下来,这一时期的仙童成为硅谷最具神话色彩的历史。   当然诺伊斯成就的最高峰还是英特尔公司,他与高登·摩尔和安迪·葛鲁夫一同创业,而且构建了业界极为罕见、完美和谐的三人“执政”局面。三人的合作只能说是天作之合,缺任何一位可能都会让英特尔历史大幅改写。诺伊斯自然是最耀眼的人物,传奇式的发明家、仙童公司的总经理和半导体业的“政治家”,他是英特尔公司的“脸面”。而甘于默默无闻的高登·摩尔则是公司的“心脏”,没有摩尔,英特尔不可能有足够的力量和士气;而没有强硬的葛鲁夫,英特尔甚至不会成为一家著名的大公司。     微处理器之父   1971年1月,第一个可以运转的微处理器诞生了,定名为“4004型”。其中,第一个“4”是指以4位为单位的设计思想,后一个“4”是指由英特尔制造的第4种专用芯片,而它的发明人就是特德·霍夫。霍夫认为自己占了天时和地利之便:“如果我们没有在1971年发明4004微处理器,那么别人也会在一两年里发明它。”   在普遍认为大型机才是大有可为的时代,霍夫另辟蹊径,投入到微处理器的研制中。霍夫说服了刚从仙童公司跳槽的斯坦·麦卓尔与他合作,共同设计了一种比4004型更强大的微处理器,称为“8008型”,这是第一个真正意义的微处理器。   1973年8月,“8080型”微处理器问世,它首次使用了MOS(金属氧化物半导体)工艺,成为有史以来最成功的微处理器之一,这也是第一个通用微处理器,是20世纪最后25年里一项具有划时代意义的发明。   著名的《经济学家》杂志将霍夫称作是“第二次大战以来最有影响的7位科学家之一”。1978年,他被提升为英特尔研究员(至今一共只有两个人获得过类似的称号),这意味着他在研究方面具有很大的自主权。   在评价微处理器和PC时,霍夫说:“我对微处理器在个人计算机中的应用感到非常惊讶,我也没有想到人们会仅仅为了业余的爱好而买微机。随着影像游戏机的发展,个人计算机成为人们又一种娱乐工具,任何一位发明家如果能够创造出什么来提供给人们娱乐,他就能获得成功。”         PC之父   创造出世界上第一台微电脑的殊荣,现在一般都归到爱德华·罗伯茨(Edward Roberts)身上。   罗伯茨是位电脑爱好者,1974年,罗伯茨决定利用8080微处理器装配一种供黑客试验的计算机,《大众电子》杂志为寻找独家新闻,主动上门观看了罗伯茨的设计方案,之后决定让他制成一台原型机,由杂志社在封面予以报道。   1975年1月,《大众电子》封面刊出一台很小的计算机照片,大字标题写着:“世界上第一组堪与商业机相媲美的以成套形式提供的小型计算机——牛郎星8800”。根据杂志的介绍,“牛郎星”勉勉强强算是一台电脑,在金属制成的小盒内,罗伯茨装进两块集成电路,一块即8080微处理芯片,另一块是存储器芯片。既没有可输入数据的键盘,也没有显示计算结果的“面孔”。插上电源后,使用者需要用手按下面板上的8个开关,把二进制数“0”或“1”输进机器。计算完成后,面板上的几排小灯泡忽明忽灭,就像军舰上用灯光发信号那样表示输出的结果。   就是这样一个简单的装置,却引发了大地震。罗伯茨的“牛郎星”电脑问世后,美国出现了一个电脑业余爱好者购买散件、在家庭车库内组装微电脑的热潮。 尽管“牛郎星”十分原始,但它把计算机发展到大型机时代料想不到的辉煌阶段。         商用软件之父   个人电脑的真正飓风是由AppleⅡ刮起的,而AppleⅡ成功的重要推进器就是VisiCalc电子表格软件。因为售价3000美元的AppleⅡ对家庭并没有多少吸引力,但配备了电子表格的AppleⅡ,就足以让人们把VisiCalc作为惟一的理由而购买它。从某种意义上说,AppleⅡ就是一台VisiCalc机器。   VisiCalc的发明人就是丹·布莱克林(Dan Bricklin)。1973年毕业后,布莱克林进入DEC,与他人合作编制了DEC的第一个字处理软件WPS-8。26岁时,布莱克林进入哈佛商学院寻求新的职业生涯,他在哈佛的分时计算机系统上用BASIC编写软件,进行财务计算。当时他常遇到的问题是,对不同的题目必须重新编写程序,于是他便开始思考能否用一种通用的计算模式来解决该问题。布莱克林用一个周末的时间粗粗地做出了一个演示版本。虽然这个演示版本是用BASIC写成的,速度很慢,而且行列只能添满一屏,但它已经具备电子表格的许多基本功能,此时已是1978年初。由于AppleⅡ等个人电脑产品的问世,布莱克林和麻省理工的老朋友富兰克斯顿一起合作,成立了软件艺术公司(SA),决定为AppleⅡ开发VisiCalc,发行商是丹·弗莱斯特拉的公司叫Personal软件公司(PS),可以说这是最早的微机应用软件公司。   电子表格VisiCalc的出现将PC从业余爱好者手中的玩具变成了炙手可热的商业工具,独立地改变了PC业的发展方向。布莱克林创造的不仅仅是一个产品、一家公司,而是整个软件产业。VisiCalc引发了真正的PC革命,它极大地激励了软件开发者,并从此宣告了PC商用化的到来。     IBM PC之父   如果说个人电脑之火是由苹果引燃的,那么IBM的介入,才真正将这场大火燃遍全球,热度持续近20年而不减。而缔造IBM PC的,就是颇富个人魅力的唐·埃斯特利奇。   1980年中,IBM召集高层咨询会议,要对如火如荼的个人电脑浪潮作出应对。这时实验室主任洛伊站起来,提议打破常规,秘密组织一个精干小组,在一年内搞出PC来。 洛伊仅挑选了12名最优秀的工程师来演绎一段类似苹果公司经历过的传奇故事,担当这个名为“西洋棋”项目的负责人就是埃斯特利奇。以往,埃斯特利奇在工作上被认为“极不合作”,不听别人使唤,只凭自己的意思行事。而这种不合群的态度,正适合IBM PC计划,洛伊将它交给埃斯特利奇,事实证明这个选择十分英明。   1981年8月12日,IBM PC如人们预想的那样跨进了PC业,没有人惊奇和兴奋,因为要等一段时间,人们才真正明白PC时代的开始。在第一台PC发布前几个月,埃斯特利奇还着手下一代产品——PC XT的开发。XT的推出,再次把IBM推到PC科技的最前端,XT疯狂畅销,使IBM一举占有企业PC市场的75%。同时埃斯特利奇还启动另一计划,以PC攻打家庭市场,但推出时间太晚,错过了圣诞销售旺季,后来这个产品无疾而终。1982年,埃斯特利奇开始着手下一个大计划,即生产真正强劲的AT机。AT机象征着IBM是惟一能使用80286处理器的厂商。1984年 8月,AT机推出好几个月后,竞争对手才推出AT级产品。1984年, IBM PC的收入已达到40亿美元,这意味着光是PC一个部门就可以在美国工业公司中排名第74位,并可名列美国第三大计算机公司,仅次于IBM自己和DEC。埃斯特利奇还安排了一个争议性的计划,让经销商销售个人电脑,这是IBM产品第一次由非IBM业务代表的人销售, 从而开拓了电脑分销的先河。   1985年8月2日埃斯特利奇终于带着太太,去渡公司承诺已久的假期。两人乘坐的191航班试图在暴风雨中降落到达拉斯机场时,飞机失控,埃斯特利奇和太太玛丽不幸丧生。虽然他的生命结束于不幸的飞行事故,但打开昨日的篇章,历史永远会承认一个真正有贡献的人。     PC软件先锋…

Read More Read More

常成员函数

常成员函数

  使用const关键字进行说明的成员函数,称为常成员函数。只有常成员函数才有资格操作常量或常对象,没有使用const关键字说明的成员函数不能用来操作常对象。常成员函数说明格式如下:   <类型说明符> <函数名> (<参数表>) const; 其中,const是加在函数说明后面的类型修饰符,它是函数类型的一个组成部分,因此,在函数实现部分也要带const关键字。下面举一例子说明常成员函数的特征。 #includeclass R{public:R(int r1, int r2) { R1=r1; R2=r2; }void print();void print() const;private:int R1, R2;}; void R::print(){cout< } void R::print() const{cout< } void main(){R a(5, 4);a.print();const R b(20, 52);b.print();}   该例子的输出结果为:   5,4  20;52   该程序的类声明了两个成员函数,其类型是不同的(其实就是重载成员函数)。有带const修饰符的成员函数处理const常量,这也体现出函数重载的特点。

lua 学习笔记11

lua 学习笔记11

/*********************/       I/O 系统/*********************/lua中,I/O分为简单i/o模型和完整i/o模型。 简单i/o模型实际上是完整i/o模型的免文件参数版,它默认了操作的对象是stdin和stdout。 i/o模型可以操作的函数有:readwriteopen另外,还有一个我们常用于调试的print,它实际上是简单i/o模型的一种运用。 print和read的区别:write adds no extra characters to the output, such as tabs or newlines. Moreover, write uses the current output file, whereas print always uses the standard output. Finally, print automatically applies tostring to its arguments, so it can also show tables, functions, and nil. /******************/   I/O 中的open/******************/简单I/O就是open的不是普通的文件,所以它可以直接使用io.read(),io.write()来操作.如果要使用完整的I/O操作,就必须要先open一个文件.它的用法有:io.open("filename","parameter")filename: 文件名parameter: 参数That mode string may contain an `r′ for reading, a `w′ for writing (which also erases any previous content of the file), or an `a′ for appending,…

Read More Read More

lua 学习笔记10

lua 学习笔记10

/********************/ 调用数学库第一个例子/********************/  — 产生10个随机的1-10之间不重复的数  randTen = {}  for i=1,10 do randTen[i] = i end  function getARand()    for nowNumber=10,1,-1 do  local curIdx = math.random(1,nowNumber)  print(randTen[curIdx])  for next = curIdx,nowNumber – 1 do      randTen[next] = randTen[next + 1]        end    end end  getARand()   –[[ output:29110758436 ps:  不知道为什么,加上math.randomseed(os.time())后,反而出现随机数单一的情况 –]] 稍微修改下,成为任意数的版本 function getARand(randTen,max)    if(max == 0) then return end     local curIdx = math.random(1,max) print(randTen[curIdx]) for next = curIdx,max – 1 do  randTen[next] = randTen[next + 1]    end        getARand(randTen,max – 1) end  function randDifNumber(max)     local randTen = {}      for i=1,max do                randTen[i] = i     end       getARand(randTen ,max) end  randDifNumber(100)

lua 学习笔记9

lua 学习笔记9

/******************************/    面向对象基础–生成实例/******************************/在lua中,理所当然是利用table来实现oo的。 先看看以前的用法,如果用table来实现一个函数,函数里面要操作表格的一些数据。    Account = {balance = 0}    function Account.withdraw (v)      Account.balance = Account.balance – v    end 这里,总是要引用"Account."才能访问到内部的变量,如果把它当成一个类,这样做就没有办法生成对象,失去了oo的原则,那么,怎么做呢? 第一种方法是在函数里面加上一个参数,这个参数指向当前的表格,那么访问时就灵活多了。例如:    funciton Account.p(tableName , v)      tableName.balance = tableName.balance – v    end 第二种方法跟第一种一样,不过利用lua中内置的colon operator(实际上只是把类名这个参数省略掉了),例如:    function Account:withdraw (v)      self.balance = self.balance – v    end当调用时,直接使用"实例名:widthdraw(v)"就可以自动把当前的实例名当作参数传导函数里面的self里。需要注意的是,在这样的函数里,只能使用Account和self指向隐藏的参数类名 下面我写了一个例子,试试看生成一个实例的用法:classTest={}classTest.number = 1function classTest:addThenPrint(value) self.number = self.number + value print(self.number)end function getAClass(o) o= o or {} setmetatable(o,classTest) classTest.__index=classTest return oend t = getAClass({number = 10})t:addThenPrint(1)            t1 = getAClass({number = 20})t1:addThenPrint(1) print(t.number)print(t1.number) –[[ output:11211121–]]更进一步,可以把上面的程序改成:function classTest:getInstance(o) if(o == nil) then o = {} end if(type(o) ~= "table") then error("error…

Read More Read More

lua 学习笔记8

lua 学习笔记8

/**************/    只读表/**************/利用metaMetods我们还可以做到只读的表格.用前面的方法来实现效率上不是很高,所以,现在改成__index直接指向只读表格的内容,而修改__newindex为调用error信息.( 记住: 前面说过了,__index指向表格时,系统会自动查找表格中的key相等的元素,并返回) 下面是实现方法   — 此函数参数,是一个只读表格   function readOnly (t)      local proxy = {}      local mt = {       — create metatable        __index = t,        __newindex = function (t,k,v)          error("attempt to update a read-only table", 2)        end      }      setmetatable(proxy, mt)      return proxy    end 用法例如:     days = readOnly{"Sunday", "Monday", "Tuesday", "Wednesday",             "Thursday", "Friday", "Saturday"}        print(days[1])     –> Sunday    days[2] = "Noday"    stdin:1: attempt to update a read-only table /*****************/    设置环境/*****************/    Lua keeps all its global variables in a regular table, called…

Read More Read More

lua 学习笔记7

lua 学习笔记7

/*******************/  自定义数据文件/*******************/常常有大量数据需要引入,有没有更加人性化的输入方式呢?在lua中,可以采用下面的方式: 定义数据文件data:其格式如:    Entry{"Donald E. Knuth",          "Literate Programming",          "CSLI",          1992}        Entry{"Jon Bentley",          "More Programming Pearls",          "Addison-Wesley",          1990}ps:Entry{…} 和Entry({…})是一样的意思,调用Entry函数。 然后在需要引用数据的地方,采用dofile("data")来导入数据。 处理时,要预先加入function Entry(b)来对引用的数据进行处理 例如,我们需要统计上面的数据中第一项的个数    local count = 0    function Entry (b) count = count + 1 end    dofile("data")    print("number of entries: " .. count) /*******************/  保存表格的内容/*******************/ 有时候需要把lua中的表格内容保存到文件中,并且保存的格式是可以直接读取的语法形式,在表格中的引用也要相应的保存起来.     function basicSerialize (o)      if type(o) == "number" then        return tostring(o)      else   — assume it is a string        return string.format("%q", o)      end    end   function save (name, value, saved)      saved = saved or {}       — initial…

Read More Read More

lua 学习笔记6

lua 学习笔记6

/********************/    双向队列的练习/********************/看了lua有段时间,还没有实际写过程序,正好,这一章是关于建立双向队列的。看了书后,自己按照记忆复习了一遍。 — double quenue Practice doubleQueue = {} function doubleQueue.create () doubleQueue.q = {first = 0,last = 1}end function doubleQueue.pushLeft(value) local first = doubleQueue.q.first – 1 doubleQueue.q.first = first doubleQueue.q[first] = valueend function doubleQueue.pushRight(value) local last = doubleQueue.q.last + 1 doubleQueue.q.last = last doubleQueue.q[last] = valueend function doubleQueue.popLeft() local first = doubleQueue.q.first if first + 1 < doubleQueue.q.last then  doubleQueue.q.first = first + 1 else        error("list is empty") end local value = doubleQueue.q[first] doubleQueue.q[first] = nil return valueend function doubleQueue.popRight() local last = doubleQueue.q.last if last – 1 > doubleQueue.q.first then     doubleQueue.q.last = last – 1 else …

Read More Read More

lua 学习笔记5

lua 学习笔记5

/*********************/     载入外界库/*********************/The loadlib function loads the given library and links Lua to it. However, it does not open the library (that is, it does not call the initialization function); instead, it returns the initialization function as a Lua function, so that we can call it directly from Lua. If there is any error loading the library or finding the initialization function, loadlib returns nil plus an error message. We can improve our previous fragment so that it checks for errors…

Read More Read More

lua 学习笔记4

lua 学习笔记4

/**********************/  Proper Tail Calls/**********************/Proper Tail Calls有着类似goto的功能,不过它只能是调用函数。我们都知道,调用函数会占用栈资源,当频繁的在函数中互相调用时,很容易就会使得栈资源耗尽。在lua中,设计了一种用法,叫Proper Tail Calls,它可以时间函数调用,并且不会占用新的栈资源。用法:In Lua, only a call in the format return g(…) is a tail call. 例子:let us consider a simple maze game. The maze has several rooms, each with up to four doors: north, south, east, and west. At each step, the user enters a movement direction. If there is a door in that direction, the user goes to the corresponding room; otherwise, the program prints a warning. The goal is to go from…

Read More Read More