All posts by dotte
如何清晰地思考:近一年来业余阅读的关于思维方面的知识结构整理(附大幅思维导图)
一年前一个偶然的机会我遇到了一本书——《影响力》,看完这本书之后对我们如何思维产生了极大的兴趣,于是在一年的时间里面密集地阅读了以下一些方面的经典著作:社会心理学、认知科学、神经科学、进化心理学、行为经济学、机器学习、人工智能、自然语言处理、问题求解、辩论法(Argumentation Theory)、Critical Thinking、判断与决策。以及大量的 Wikipedia 条目。
这一年来,对以上这些领域的阅读和思考给我带来了极大的价值,我相信他们也会给你带来巨大的收益。
关于为什么我认为我们都需要学习这方面的知识,我曾在博客中写到:
另外还有一些我认为是 essential knowledge 的例子:分析问题解决问题的思维方法(这个东西很难读一两本书就掌握,需要很长时间的锻炼和反思)、判断与决策的方法(生活中需要进行判断与决策的地方远远多于我们的想象),波普尔曾经说过:All Life is Problem-Solving。而判断与决策又是其中最常见的一类Problem Solving。尽管生活中面临重大决策的时候并不多,但另一方面我们时时刻刻都在进行最重大的决策:如:决定自己的日常时间到底投入到什么地方去。如:你能想象有人宁可天天花时间剪报纸上的优惠券,却对于房价的1%的优惠无动于衷吗?(《别做正常的傻瓜》、《Predictably Irrational》)如:你知道为什么当手头股票的股价不可抑止地滑向深渊时我们却一边揪着头发一边愣是不肯撤出吗?(是的,我们适应远古时代的心理机制根本不适应金融市场。)糟糕的判断与决策令我们的生活变得糟糕,这还不是最关键的,最关键的是我们从来不会去质疑自己的判断,而是总是能“找到”其他为自己辩护的理由(《错不在我(Mistakes were made, but not by me)》)又,现在是一个信息泛滥的时代,于是另一个问题也出现:如何在海洋中有效筛选好的信息,以及避免被不好的信息左右我们的大脑(Critical Thinking)关于以上提到的几点我在豆瓣上有一个专门的豆列(“学会思考”),希望有一天我能够积累出足够多的认识对这个主题展开一些详细介绍。
人类的大脑和思维是目前已知最为复杂的系统,对这个系统的研究不仅自身是一件极其迷人的事情,对于像我们这样的芸芸众生来说即便不去做研究,学习一些这方面的科普知识,对于学会正确地思考有极大的益处。
你的大脑是你唯一的工具,要正确利用这个工具,唯一的途径就是去了解它。与很多人的直觉相反,实际上我们的思维有着各种各样的缺陷和陷阱(keyword: cognitive bias),我们解决日常问题的思维方式也并不总是最优的(keyword: bounded rationality),这里摘抄一段我在豆列上的导言:
我们的思维有很多很多的弱点,我一向认为,正确的思维方式,是一切高效学习的基础。比如参见如下2个例子,错误的思维方式得到的结论有大得多的可能性是谬误。
人总喜欢沿袭以往习得的经验,并通过类比来进行外推。我第一次在一个地铁终点站坐地铁的时候,看着从远方开来的地铁,我心生疑惑——“这车每节车厢都这么长,待会怎么调头呢(我心说没看到铁轨终点有一个大大的供调头的 U 形弯啊)?”,当车开始开的时候我终于意识到原来车是可以往两头方向开的。 人喜欢从关联当中寻找因果,有一次我我老婆去银行取款,到了 ATM 室的自动门口,我开玩笑地拿着手头的饭卡去刷了一下,然后——门居然开了。我顿时来了劲,立即得出一个结论:这个刷卡装置不安全,至少不是能够专门识别银联的卡的。我甚至飞快地泛化出了一个更具一般性的理论来解释这个现象:即可能所有带有磁性的卡都可以用来开门。老婆看我得意洋洋,就泼过来一盘冷水:不一定是你的卡刷开的啊,你不刷卡试试看。我不信,说怎么可能呢,心想我刷卡,门就开了,还有比这更明显的因果关系嘛。但出乎我意料的是,我走出门,这次没刷卡,门也开了——原来是感应门——原先这个 ATM 室的确是刷卡门,但后来改成了感应门,刷卡的那个装置只不过没拆掉残留在那里而已。总的来说
人类的思维充满着各种各样的捷径,每一条捷径都是一把双刃剑。一方面,它降低了大脑的认知复杂性(笼统的看一个问题要比细致的分析简单得多),有助于迅速做出绝大部分时候都正确的判断;但另一方面,它也常常导致人们把大部分情况下成立的法则当成了放之四海而皆准的。可以说,有多少捷径,就有多少条谬误。 人类的情绪也在很大程度上影响着人的思考。比如,如果你憎恶一个人,你往往就会反对他的所有立场。反之亦成立。 人类大脑经过长时间的进化,先天就具备一些特定的“思维定势”,以使得人类能够在面对进化过程中经常出现的适应性问题时能够不假思索的做出迅速的反应。然而,在现代社会,这类思维定势已经不适应了。 人类不可避免的受着各种各样的偏见的影响,这些偏见有些是有一定适应价值的“思维定势”(如事后聪明式偏见),而有些则是大脑的认知机制的“缺陷”。以上,构成了人类思维中的种种谬误。而学会思考,就是学会认识到这些谬误。
Critical-Thinking 在西方拥有悠久的历史,早到古希腊时代,亚里士多德就已经对人类语言中的各种各样的谬误有了一定的认识(譬如,“我们无法讨论不存在的东西,所以所有的事物都是真实的”),并对辩论之中存在的各种各样的谬误进行了归类。然而令人遗憾的是,在中国的文化里面,理性思维似乎是一直被抑制的,中国文人传统都是非理性思考者;所谓非理性思考,主要包括联想、比方等形式,这些思维方式作为人类天生具有的思维方式的一种,一方面当然有它的好处(比如在科研方面,联想往往能够启发新思路;类比也有助于用新颖的方式来解决既有问题),然而另一方面,这样的思维方式同样也充满了各种各样致命的谬误。在大众知识领域,自中国古代文人思维习惯流传下来的影响深刻地左右着人们的语言习惯,随处可见的不靠谱的类比和文字游戏就是证明(例如,严格来说,类比的一般形式是,A具有X、Y、Z三个属性,B具有X、Y属性(类似于A),所以B具有Z属性。这个类比要成立,必须要满足一个前提,即X、Y属性对于Z属性的有无必须是有关的。然而这个前提被根本忽视了,详见 False Analogy)。
这个豆列中的书,有一些是介绍人类思维工作的机制的,认识这些机制是正确思考的大前提;有许多是关于人类推理(Reasoning)过程中的形形色色的谬误的,因为唯有认识到 这些谬误,才能避免它们。唯有避免了思维的谬误,才能进行正确的思考。
注:
一个最完整的认知偏见(cognitive bias)列表见: http://en.wikipedia.org/wiki/List_of_cognitive_biases 一个完整的 Fallacies 列表见: http://en.wikipedia.org/wiki/Fallacies Wikipedia 上关于 Critical Thinking 的条目见: http://en.wikipedia.org/wiki/Critical_thinking另:
人类在思考问题的过程中,自身的思维习惯、性格、知识积累无不都在悄悄地影响着思维的过程,所以,一些心理学的知识也非常有助于帮助正确的思考。更多心理学方面的推荐,参考:http://www.douban.com/doulist/46003/
文章末尾将贴出的是我这一年来学习的知识结构总揽(用 XMind 画的思维导图)。注:这只是一个整体的知识结构,或者说“寻路图”,其中固然包含一些例子(用 “e.g.” 标出),但最重要的是从各个分支引申出去的延伸阅读,后者包含上百个很有价值的 wikipedia 条目,不下 50 本经典的著作(大部分我已经读过,小部分经过我的仔细考察,正在阅读中或者肯定是有价值的)。
如何获得这些延伸出去的阅读,有两个办法:
-
在总揽图中抽出关键字到 Wikipedia&Google 上查找,如:informal fallacy,cognitive biases, bounded rationality, critical thinking, argumentation theory, behavioral economics, problem solving 等等(以上这些关键字你都会在思维导图中看到)。注:阅读 Wikipedia 时要严重注意每个条目后面的 Reference ,一般来说这些参考资料本身也都非常经典,其价值不亚于 Wikipedia 条目本身。
-
查看我整理的四个豆列:
以上四个豆列中整理的绝大多数都是我阅读过的,你也可以参考我的整个“思维”标签下的书。如何获得这些书(尤其是其中包含大量的无中文翻译版的英文书)请参考李笑来老师的笔记。
这个领域的新知识是如此的纷至沓来,以至于我只有时间不断地阅读和思考,以及不时在我的 Google Notebook 里做一些笔记,而完全没有时间一本书一本书,一个子领域一个子领域地写具体的 Introduction (目前具体的荐书只是在 TopLanguage 上零散的推荐了几本,还没有专题介绍)。既便如此,仍然还是在博客上写了很多相关的东西,它们就是这一年来的学习的收获的证明:-),因此如果你想快速判断上面列出的一些书籍是否对你有价值,有多大的价值,不妨参考一下我写的这些文章,这些文章很大程度上是在这一年的学习过程当中的感悟或总结。注:第 3 部分(关于学习、记忆与思考)的文章基本上是领域无关的:
-
关于 Problem Solving 的
-
关于机器学习的(机器学习和人工智能领域对于理解我们的思维方式也提供了极好的参考)
-
关于学习、记忆与思考的
好在我并不打算零星的一本一本推荐:D 所以我就花了点时间将整个的知识体系整理了一番,画了下面这张结构图,请按图索骥,如下(有三个版本,1. 至 xMind Share 的超链接,2. 内嵌在该页面中的幻灯片,如果无法载入请参考 1 。3. 图片版(注:图很大,请下载浏览或打印))
我在前面写学习习惯的时候曾经提到:
8. 学习一项知识,必须问自己三个重要问题:1. 它的本质是什么。2. 它的第一原则是什么。3. 它的知识结构是怎样的。
有朋友问我具体的例子,好吧,那么这张思维导图便是第三点——知识结构——的一个很好的例子:)
1. 至 XMind Share 的超链接:http://share.xmind.net/pongba/how-to-think-straight-4/
2. 嵌入的幻灯片(如加载失败请直接点击上面的 XMind Share 超链接至 XMind 浏览):
3. 图片版(此为缩略版,完整版请至相册下载:google picasa 的 ,或 csdn 相册的)(最后提醒一下,别忘了这幅图只是大量书籍和 Wikipedia 条目的“藏宝图”,如何延伸阅读请参考前文所述的方法)
from:http://blog.csdn.net/pongba/article/details/3549560
编程语言漫谈
写在前边:我们知道现有语言的编程范式有:过程式,面向对象,函数式,逻辑式。随着软件工业化程度的普及,以及软件的复杂度越来越高,编程语言的发展历程 也是从最初的过程式(命令式)语言c,发展到以java语言为代表的面向对象编程语言。而逻辑编程语言(以prolog为代表)和函数式语言(lisp系 列)还多用在学术和人工智能领域中。近几年,随着多核,云计算时代的到来。函数式编程语言逐渐浮出水面,最经典的语言以scheme,common- lisp,ml,clojure,go为代表.而且最近的jdk8也逐步加入了functional,closure,lambda等语法,而且 scala的作者也越来越推崇编码者以函数式语言的思维来coding。可见编程语言的发展也是满足时代的变化不断变化着。从其中的发展历程中我们可以看 到:技术的发展都是在围绕着解决“软件的复杂度”这个基本的需求而发展的。
一、 编程语言概述
编程语言是计算机的符号,是人和计算机交流的语言。我们学习一门新的编程语言时,应该观察这门语言的那些特性呢?《SICP》一书的作者列举了一下三点:
* primitive elements. (基本元素)
* means of combination. (组合手段)
* means of abstraction. (抽象手段)
以上3个特性,基本上涵盖了所有编程语言的特性,并且也是一个语言设计者从开始就要考虑的。我对这三点的理解:primitive elements表示语言的基本符号(基本数据类型,关键字等)也就是词法部分。means of combination利用基本元素通过组合的过程构建大型程序的手段,不同的语言提供的组合手段是不同的。means of abstraction表示抽象,抽象是解决软件复杂度的重要手段,让软件的可读性,可扩展,可重复利用等得到提升。下边会从组合元素和抽象手段来对比语言特性。
二、 组合手段
汇编语言:算是最简单的词法和语法形式了,被称作低级语言。汇编器通过直译的过程将汇编代码翻译为native code(cpu指令集)。 提供的primitive elements有:数字,字符,-,+,*,/ , case,if, break, go,指令等基本元素;通过这些元素组合成计算机执行序列符号。
c语言相比汇编语言更高级,让程序员脱离和cpu,寄存器,内存直接打交道的工作,提供了更多的组合手段:比如数组,结构体等数据结构。
java语言自称是面向对象语言,所以比c语言更进一步,通过强大的类型系统手段来组合属性和方法。
go语言和ML语言非常相仿,“接口”,”高阶函数“,”闭包“,”duck type”,”返回多值”,并提供goroutine等来组合。
prolog语言完全是模式匹配的逻辑语言。他的思想基于:世间所有的定理都给予一个最简单的定理推理而来,就像数学的基础是“1+1=2”,然后才能推导出“万有引力”,“相对论”等定律。
lisp方言以s-expression(著名的S表达式)来组合数据和函数。在lisp中不区分数据和函数,一切皆为数据。
题外话:lisp方言是和图灵机的思想一脉相承的,编码的时候完全感受不到计算机体系结构。而其他语言更多的是冯·洛伊曼的计算,存储思想而设计,要么是“堆栈”结构,要么是“寄存器”结构;
三、 抽象手段
从c语言开始,以函数为单元提供了对程序的抽象。这样大大的提高了程序的可复用,模块化等。让团队合作编码也成为可能。
面向对象编程:基本上隐藏了计算机的细节,开发者通过对象来抽象具体业务。但严格意义上来说java也属于imperative-lang的范畴而且都是传值调用。相比来说,python,ruby更面向对象一些,python融合了面向对象和函数式编程范式,更接近自然语言些。
以lisp为代表的函数式语言:以函数为基本和唯一的抽象;common-lisp也基于宏开发了一套object-oriented的编程方式。我比较倾向于函数式编程理念:函数的无副作用(不用考虑线程安全,特别是对于变态的Haskell),高阶函数,闭包,lambda等。
四、 类型系统
大家平时经常会说:javascript是一个弱类型的语言,java语言是强类型的语言。将编程语言从类型系统的角度区分语言也很有趣。一般来说弱类型语言更偏向自然语言一些,语法也很自由活泼些。而现今语言的走势也趋向与弱类型方向.
计算机是结构化很强的,堆栈上一个二进制位的错误就会导致溢出,bus等错误。所以语言层面的自由得益于编译器或者解释器的功劳。比如java,c等语言有很强的编译时类型检测机制,强类型的好处驱使编码人员写出很少有语法,语义错误的代码,对IDE的支持也便捷,是大型技术团队的合作基石。
弱类型语言让我们获取了自由(不需要类型信息),让程序员少敲了许多键盘。自由是有代价的,编译器或解释器中内含类型推理(infer type); (类型推理是利用归一方法,基于上下文中的变量显式类型,操作符,返回值等信息,利用栈和逐渐替换的过程来推到出类型。) 弱类型虽然可以轻松编译通过(或者不需要编译而是解释执行),但也是有类型检查过程的,只是将此过程延迟到运行时了。所以弱类型语言结构化不强,编码时很难确保类型无误,IDE支持较难。但是通过一些分析器可以不断的检测语法,语义错误,相当于达到了强类型语言的IDE效果。近几年语言的方向朝着逐渐脱离计算机体系结构,向自然语言方向在演进,程序员像艺术家一样用代码自由描绘。
五、编译/解释
java语言是解释型还是编译型的呢? 这个很难说,从java source code -> class byte code 的过程式javac编译器的过程。但是byte code 在jvm上执行的过程可能是解释执行也可能是编译执行的。解释型和编译型的内部都遵从编译原理的过程:词法分析-> 语法分析->语义解析 -> 编译器后端-> native code的过程。 但有各自的优点:
解释器:加载code速度快;解释器需要维护运行时上下文等信息。所以加载必要的代码,片段解释执行。但是对于相同的代码都经过编译过程就很多余,造成时间浪费。
编译器:执行速度快。而且编译器后端也更容易优化中间代码,因为优化过程式一个结构化过程:往往需要遍历整个中间代码,整体优化代码,提高运行效率。
runtime:一般来说解释型语言需要在内存维护运行时上下文信息,服务于运行过程中变量的查找,绑定,scope等。 而编译语言基于寄存器堆栈模型执行代码,基本上数据绑定都在栈结构中完成,运行速度稍微快一些;
hotspot-jvm结合了解释和编译的各自优点;最先解释执行过程,如果方法被频繁执行,而且达到热点(hotspot),jvm会启动编译过程,将次代码编译为native-code,然后缓存起来,下一次的调用直接执行即可。hotspot-jvm执行基于堆栈指令bytecode, 这一点也是基于跨平台的考虑而牺牲了寄存器指令; (而基于android操作系统上的dalvik虚拟机是基于寄存器指令的);
所以说,语言的设计往往是一个权衡过程;获取的“自由”越多,”牺牲“也更大。
六、 总结:
最初从图灵为了解决莱布尼茨提出的:是否存在一个通用模型来解决一切计算任务这个命题,发明了图灵机理论。到冯洛伊曼仿真人脑神经元思考过程产生第一台基 于存储器,运算器的计算机ENIAC,至今,计算机硬件技术并没有实质性的变化,只是随着摩尔定律的破灭,人们发展了多级高速缓存,多核,多cpu技术来 支撑越来越大的计算任务。 在这个过程中,随着人们对逻辑学,符号学,算法的不断研究,用来和计算机交互的语言也越来越抽象和丰富。我们通过这个形象的符号来抽象时间和空间,通过这 个形象的符号来解决软件的复杂性问题,通过这个符号来和计算机传达我们的思想。
from:http://tech.youzan.com/programming-language/
简述百年计算机科学
计算机科学和数学的论文读起来向来很具有挑战性,但读完后收获也不小。我也并不总能够完全理解论文中的每一个批注,有时都无法完全明白作者的结论,但阅读它们仍然大大地开阔了我的眼界。
我是比较晚才开始意识到阅读学术论文的重要性的。当还是学生的时候,我记得我只读过两篇论文,其中一篇下面我会提到。作为程序员,我并没有很强的计算机理论背景。学术论文对我来说非常生涩和遥远。因而,我花了很长时间才意识到没有阅读这些论文对我的损失有多大。
我有些同事知道了我最近对学术论文有所研究后,都在问我建议他们从哪里开始。看了Michaels Feathers和Fogus做的一张类似的清单后,我也编辑了一份自认为代表了过去100年计算机科学发展历程的清单。在编辑的时候,我采用了如下的选择标准:
- 这篇论文必须改变了世界
- 这篇论文必须颠覆了我当时的既有观点
- 每十年只能有一篇入选
这样的选择标准一定是非常苛刻也非常主观的。如果你认为我漏掉了什么,也许你也可以编辑一份你的论文清单。
直觉主义的建立早于“计算理论”,但前者对后者的建立至关重要。Luitzen Egbertus Jan Brouwer的早期构想其实是对证明法的一个批判,但是Arend Heyting在后来的工作中把直觉主义结合应用到了数理逻辑中。
我选择Brouwer的论文是因为它抛弃排中律强调价值的建设。Brouwer并不认为一个命题如果不为假,则必为真。他认为,命题必须要被严谨地正面证明为真才对。
作为一名程序员,计算一个值和仅仅表示这个值的存在两者之间之间的区别是非常紧密相关的。更重要的是,起源于Brouwer想法的构造数学在随后的类型论发展中起了至关重要的作用。
Alan Turing之所以在编程社区之外被众所周知,是因为他在第二次世界大战中破解了密码系统,和他所遭到的迫害而且最后自杀身亡。这篇论文诞生于战争之前,当时他还是个年轻的博士生。
我发现自己很难用直觉来理解图灵所描述的一个现象——不可计算数。我对于认为计算本身有硬性限制,这种说法既让人费解,又充满魅力。
在著名的判定性问题上,尽管图灵机和Alonzo Church的λ演算都被证明了是不朽的模拟计算方法,Turing的文章还是因为勉强打败了Church提出的解决方案被出版。
《通信的数学理论(1948)》
我清楚得记得还在念大学的时候读到这篇论文时的震撼。我之前认为信息就跟幽默感和美感一样,是无形的。这篇论文让信息突然变成了准确而可量化的了。
Claude E. Shannon是信息论的鼻祖,他让现代信息和通讯技术成为了可能。
《非合作博弈(1950)》
这篇并不是跟计算相关的,严格意义上它甚至都不能算作一篇论文。John Nash的博士学位论文整整26页却只有2个引用,其中一个还是引用他自己以前的一篇论文。在这篇文章中,Nash阐述了一个基于非合作博弈的数学理论。这个理论在经济学和冷战策略上有着深远的影响,并且最终带给了Nash诺贝尔经济学奖。
就算你仅仅想看看Nash因为无法用当时的打字机打出来而手写的那些数学符号,这篇论文已经很值得一读了。
《递归函数下的符号表达式及计算机器(第一部分)(1960)》
给出John McCarthy)这篇Lisp的开山之作不足为奇。这篇文章把编程原理讲解地细致到了原子级别。
Carl Sagan说过要想完完全全从零开始做一个苹果派,你先得创造一个宇宙。McCarthy在这篇文章告诉我们,要想完完全全从零开始做计算,你只需要先创造S表达式。
《分布式系统中的时间,时钟和事件顺序(1978)》
Leslie Lamport在这篇文章里研究了同步和因果关系的极限,可以说能让人想起爱因斯坦的相对论。虽然他的文章在互联网出现之前就有了(论文参考了ARPA net),但是这篇论文开始谈及到与现代分布式系统密切相关的协调问题。
Lamport在2013年获得了图灵奖。有个笑话是:每个人都知道他早就该得图灵奖了,但大家用了很长时间才达成了“同步”一致。
《概率加密(1983)》
现代加密方法往往依赖于陷门函数 —— 它们的计算量不大,但几乎无法被逆推。这使得人们可以花费很小的代价加密数据,并且可以很有信心的说这是不可逆转的过程,而且在不知道关键信息的情况下解密数据是不可能的。RSA非对称密码体系)就是一个著名的例子。
但这类方法有个漏洞,即它们仍然允许密码破译者获得加密数据的部分信息。在这篇文章中, Shafi Goldwasser和Silvio Micali提出且证明了一种弥补这个漏洞的方法——用随机的方式使加密过程不确定。
《编写自成长的语言(1998)》
编写代码是非常有意思的,开发一门语言同样如此。在这篇论文中,Guy Steele一开始让单词只有一种意思,然后再让单词同时具有多种意思。他提出了一个很好的观点,成长是一门语言的关键,其能力应该能随着时间的推移而改变,在人们编写代码的时候就能够诞生新的特性。
《实用的拜占庭容错和实时恢复(2002)》
互联网是个很可怕的地方。网络和服务不仅可能完全无法使用,有时也会出现各种奇怪或恶意的行为,甚至互相损害。
做一个可容错的分布式系统常常会被称为“拜占庭将军难题”——意思是假想好几只军队需要协同合作才能成功攻城,但领导他们的将军们却并不完全可靠。
在这篇文章里,Miguel Castro和Barbara Liskov描述了一个很有效率的算法,来保证即使三分之一的节点以任何恶意的形式失效,系统仍然是健康的。
对今天的分布式系统而言,这类算法非常有用。比如比特币系统,用了这种算法它只要没失去一半以上的计算能力,都可保证可用。
《命题类型(2014)》
Philip Wadler的任何一篇论文都可以上榜。这篇论文在我写作的时候仍然是草稿,却可谓是新的经典之作,论文中Walder的引用范围从电影独立日到乐团双杰,他揭露了Curry-Howard同构性这种精妙对称性的本质。
同构性记录了逻辑命题和函数式程序种类之间非同寻常的关系。更重要的是,论文的开篇引用了Brouwer在1923年的论文中提出的直觉主义,作为函数对应于传统的直觉主义的构造性证明,这篇论文验证了直觉主义的重要性。
本文在我心中占有特殊的地位,因为在Wadlerd发布最新起草的文章的那个早上,我正好在做关于Curry-Howard同构性的演讲。但幸运的是,其内容没有什么实质性的改变,因而我没有给观众过时的信息。)
总结
我开始写这篇文章的时候正在抱怨我所在行业的短视。尽管我们这个行业的历史不长,从业者仍然对历史很不熟悉。我之前听说,有人问Bjarne Stroustrup,把lambda表达式引入C++是不是因为lambda表达式是个新潮的玩意儿——lambda演算可以追溯到20世纪30年代,比C++要年纪大多了。
但当回顾这份清单上的计算机科学家们的背景时,我不得不为自己的短视感到惊讶。上面说的这12个科学家中,有10个都是男性,且为白人。
因此,我想总结说,除非我有严重的偏见,我们仅仅用到了人类才华总和中很小的一部分。当我思考过去百年我们在计算机科学里走了多远的时候,我无法想象如果能调用更多的聪明才智,下个百年我们会有多么伟大的成就。
from:http://www.techug.com/100-years-of-computer-science
Java语言速览:StackOverflow
关于 java
Java(请不要与 JavaScript 搞混)是一种设计为与 Java 虚拟机 (JVM) 一起使用的多用途编程语言。一般将安装了相关工具可以开发并运行 Java 程序的电脑系统称为 “Java 运行平台”。使用这个标签可以(在StackOverflow上)查找有关 Java 编程语言或者 Java 平台工具的问题。
Java 是一种高性能、跨平台、面向对象的编程语言和运行环境。Java 大部分语法起源于 C 和 C++,但是其对象模型比 C++ 简单,并且减少了底层功能。Java 应用均被编译为字节码(被称为 class 文件),可以被 JVM(Java 虚拟机)执行,并独立于不同的计算机体系。JVM 通过一个垃圾收集器(查看 garbage-collection)帮助管理内存,当对象不再使用时可以将其从内存中移除。Java 的系统类型是静态、强类型、安全、声明类型和显式的。Java 支持反射、接口等与 C 和 C++ 相似的功能,例如 JNI(The Java Native Interface)。
Java 被设计为尽可能减少与电脑系统的依赖关系,可以允许应用开发者 “一处编写,处处运行”(WORA):在一个平台上执行的代码不需重新编译就能在其他机器上运行。Java 最初由 James Gosling 在 Sun Mircosystems 公司(2009年4月20日已被 Oracle 并购)设计,最初是于 1995 年作为 Sun Microsystems公司 Java 运行平台的核心组件发行。
安装工具用于开发和运行 Java 的计算机系统被 Sun(现为 Oracle)命名为 Java 平台。各种具有平台特性的工具可以帮助开发者更有效率地使用 Java 程序语言开发。
平台包含两个基本的软件包:
- Java 运行环境(JRE):用于运行 Java 应用和程序;
- Java 开发工具包(JDK):用于开发 Java 应用和程序。JDK 总是伴随着一个 JRE。
在本节中,我们将进一步探讨这两个软件包作为 Java 平台的组成部分产生的作用。
背景
作为参考的大部分 Java 实现方式都是开源的(OpenJDK),由包括 Oracle、Apple、SAP 与 IBM 在内的大型企业提供支持。
极少的电脑可以直接运行 Java 程序。因此,Java 环境通常要求安装合适的软件组件。在 Windows 系统上,一般可以从 java.com 下载免费的 Java 运行环境(JRE)。在 Macintosh 系统上,当应用需要 Java 运行环境时,会在启动时请求用户下载 Java。在类 Linux 系统上,Java 一般通过包管理器安装。
Windows 和 Mac 平台的开发者经常需要额外的工具,使用工具所需的免费 Java 开发包(JDK)必须从 Oracle下载并手动安装。
Java 会被编译为字节码,然后由 JVM 通过编译为原生代码进行解析。编译技术为即时编译(JIT)。最初这被视为降低性能的做法,但是随着 JVM 和 JIT 的发展,担忧逐渐减少。在某些情况下,例如当一个旧版本的处理器需要向后兼容时,JVM 甚至快于原生代码编译速度。
注意:也有其他供应商存在,然而大部分都有授权费。对于 linux 和其他平台,请查阅相关的操作系统文档。
版本
主要的 Java 版本、代号和发布时间:
- JDK 1.0 (1996/01/23)
- JDK 1.1 (1997/02/19)
- J2SE 1.2 [Playground] (1998/12/08)
- J2SE 1.3 [Kestrel] (2000/05/08)
- J2SE 1.4 [Merlin] (2002/02/06)
- J2SE 5.0 [Tiger] (2004/09/30)
- Java SE 6 [Mustang] (2006/12/11)
- Java SE 7 [Dolphin] (2011/07/28)
- Java SE 8 [JSR 337] (2014/03/18)
- Java SE 9 [TBD ] (未发布)
最新的稳定版本:
- Java Standard Edition 8 Update 51 (1.8.0_51) – (2015/07/14)
- Java Standard Edition 7 Update 79 (1.7.0_79) – (2015/04/14)
更多的代号及发布日期请访问 J2SE Code Names。要查看 JDK 的版本发布日志请访问 Wikipedia 的 Java 版本历史文章。
Java SE 8 正在发布并且可下载。
公共更新的结束日期(以前称为生命周期终止)为:
- J2SE 1.4 – 2008/10
- J2SE 5.0 – 2009/10
- Java SE 6 – 2013/02
- Java SE 7 – 2015/04
- Java SE 8 – 2017/09
新手帮助
你是 Java 初学者或者需要帮助使你的第一个 Java 程序运行?请参看 Oracle Java 教程开始部分。
询问问题前,请使用右上角的搜索栏查找是否已被询问(我们有很多相似的问题),并且阅读《如何提出一个好的问题》,学习怎样吸引 Jon Skeet 回答你的问题。
命名规范
Java 程序需要坚持下列的命名规范以提高可读性并降低意外错误出现的可能性。遵守这些命名规范,可以使他人阅读你的代码和帮助你时更加轻松。
类型名(类、接口、枚举等等)应以大写字母开头,随后的每个单词首字母大写。例如:String、
ThreadLocal
和 NullPointerException
。有时被称为 pascal case(帕斯卡命名法)。
方法名应使用 camelCased(驼峰式命名法),即它们应以小写字母开头,随后的每个单词首字母大写。例如:indexOf、printStackTrace、interrupt。
字段名应使用和方法名一样的驼峰式命名法。
常量表达式命名(static final
不可变对象)应被写为 ALL_CAPS形式,使用下划线分割每个单词。例如:YELLOW
、DO_NOTHING_ON_CLOSE
。这同样适用于枚举类(Enum
)的变量命名。然而,static final
修饰可变对象时应使用驼峰式命名。
Hello World:你的第一个程序
Hello World 程序代码为:
1
2
3
4
5
|
public class HelloWorld { public static void main(String[] args) { System.out.println( "Hello, World!" ); } } |
编译和调用 Hello world 程序:
1
2
|
javac -d . HelloWorld.java java - cp . HelloWorld |
Java 源代码被编译为中间代码(针对 Java 虚拟机 的字节码指令),然后可以被 java
命令执行。
更多信息:
开发Java常用的IDE
- Eclipse IDE
- NetBeans IDE
- IntelliJ IDEA
- Spring Tool Suite(基于 Eclipse,包含用于 Spring 的插件)
- JDeveloper IDE
- Android Studio(基于 IntelliJ IDEA,主要用于 Android 项目开发)
- BlueJ
初学者资源
- Oracle 的 Java 教程 :在 Windows、Linux、Mac 上从零开始,覆盖大部分标准库。
- Generics
- Coding Bat (Java) :学习部分基础之后,通过 Coding Bat 磨练和完善你的 Java 技术。
- Java 编程规范
- Stanford Java 视频课程
- Udemy Java 免费课程
- Edx 课程:Java 编程导论
日常帮助资源
进阶资源
免费 Java 编程图书与资源
- 《Linux 开发 Java 应用》(Carl Albing 与 Michael Schwarz 合著,PDF)
- 《如何像一名电脑科学家一样思考》
- 《Spring IO Guides》
- 《The Java EE7 Tutorial》(PDF)
- 《Java Thin-Client Programming》
- 《Oracle’s Java Tutorials》
- 《Thinking in Java》
- 《OSGi in Practice》(PDF)
- 《Category wise tutorials – J2EE》
- 《Java Example Codes and Tutorials – J2EE》
- 《Java Design Pattern Video Training》
常见问题
人们常问的 Java 问题:
一般问题:
环境变量:
String
,StringBuilder
与 toString
:
- 在 Java 中如何比较字符串?
- Java 中的 StringBuilder 与 StringBuffer
- 为什么当我在自己的 Java 项目中打印时得到
SomeType@2f92e0f4
? - Java 中的字符串常量
equals
与 hashCode
:
Java Platform SE API:
- 使用
nextInt()
后跳过nextLine()
- 在 Java 中比较日期
- Java:在迭代集合的过程中做高效地删除操作
- 如何排序
Map<Key, Value>
中的值 - 什么时候使用
LinkedList<>
而不是ArrayList<>
- 说明
Arrays.asList()
HashMap
与Hashtable
之间的区别
泛型:
类与对象:
算法与转换:
调试:
NullPointerException
是什么,我应该如何修复?- 堆栈追踪是什么?我应该如何使用才能调试自己的应用错误?
- 我应该如何避免检查 null?
- 为什么会出现
NoClassDefFoundError
错误? - Java 中的
NoSuchMethodError
Thread
与多线程:
与操作系统交互:
(提交者们,请仅仅列出经常被询问的问题。)
聊天室
原文链接: stackoverflow 翻译: ImportNew.com – honoka
译文链接: http://www.importnew.com/16689.html