什么是真正的编程能力

2016-01-18 转载自:知乎 开点工作室

问题:什么才算是真正的编程能力?

还在读书,也在实验室帮忙做了些东西,自己也搭过几个网站。在周围人看来似乎好像我很厉害,做了那么多东西,但是我发现这些东西虽然是我做的,但是实际上我手把手自己写的代码却并没有多少,很多都是用开源的东西,我写的代码无非是把别人的东西整合下,类似于胶水一样的工作。

我之前所认为的编程是全手动一行一行敲代码,但是现在我发现哪怕是工程上也有很多人是复制黏贴来解决问题的,并且提倡不要重复造轮子。

但是靠谷歌和复制别人的轮子,虽然我做出了很多东西,可是我并不觉得自己能力上有提升,倒是利用搜索引擎的能力的确提升了不少。而学校里另外一部分在搞ACM的人,他们每天都在刷题练算法,但单凭我个人的感受感觉他们似乎对工程上有些东西并不了解,或许算法的能力才算是实打实的编程能力?那”胶水”的能力和整合轮子的能力算不算编程能力呢?

所以我现在就很困惑,所谓的编程能力到底是什么,我该如何提升自己的编程能力?

回答:

作者:刘贺

链接:http://www.zhihu.com/question/31034164/answer/61625952
来源:知乎

非常好的一个问题。这可能是我在知乎见到过的问编程有关的问题中问得最好的一个了。我非常喜欢这个问题。

计算机科学有两类根本问题。一类是理论:算法,数据结构,复杂度,机器学习,模式识别,等等等。一类是系统:操作系统,网络系统,分布式系统,存储系统,游戏引擎,等等等等。

理论走的是深度,是在追问在给定的计算能力约束下如何把一个问题解决得更快更好。而系统走的是广度,是在追问对于一个现实的需求如何在众多的技术中设计出最多快好省的技术组合。

搞ACM的人,只练第一类。像你这样的更偏向于第二类。其实挺难得的,但很可惜的是第二类能力没有简单高效的测量考察方法,不像算法和数据结构有ACM竞赛,所以很多系统的苗子都因为缺少激励和正确引导慢慢就消隐了。

所以比尔盖茨才会说,看到现在学编程的人经常都把编程看作解各种脑筋急转弯的问题,他觉得很遗憾。

做系统,确实不提倡“重复发明轮子”。但注意,是不提倡“重复发明”,不是不提倡“重新制造”。恰恰相反的,我以为,系统的编程能力正体现在“重新制造”的能力。

能把已有的部件接起来,这很好。但当你恰好缺一种关键的胶水的时候,你能写出来吗?当一个已有的部件不完全符合你的需求的时候,你能改进它吗?如果你用的部件中有bug,你能把它修好吗?在网上繁多的类似功能的部件中,谁好谁坏?为什么?差别本质吗?一个开源代码库,你能把它从一个语言翻译到另一个语言吗?从一个平台移植到另一个平台吗?能准确估计自己翻译和移植的过程需要多少时间吗?能准确估计翻译和移植之后性能是会有提升还是会有所下降吗?

系统编程能力体现在把已有的代码拿来并变成更好的代码,体现在把没用的代码拿来并变成有用的代码,体现在把一个做好的轮子拿来能画出来轮子的设计蓝图,并用道理解释出设计蓝图中哪些地方是关键的,哪些地方是次要的,哪些地方是不容触碰的,哪些地方是还可以改进的。

如果你一点不懂理论,还是应该学点的。对于系统性能的设计上,算法和数据结构就像在自己手头的钱一样,它们不是万能的,但不懂是万万不行的。

怎么提高系统编程能力呢?土办法:多造轮子。就像学画画要画鸡蛋一样,不是这世界上没有人会画鸡蛋,但画鸡蛋能驯服手指,感受阴影线条和笔触。所以,自己多写点东西吧。写个编译器?渲染器?操作系统?web服务器?web浏览器?部件都一个个换成自己手写的,然后和已有的现成部件比一比,看看谁的性能好,谁的易用性好?好在哪儿?差在哪儿?为什么?

更聪明一点的办法:多拆轮子。多研究别人的代码是怎么写的。然而这个实践起来经常很难。原因:大部分工业上用的轮子可能设计上的思想和技术是好的,都设计和制造过程都很烂,里面乱成一团,让人乍一看毫无头绪,导致其对新手来说非常难拆。这种状况其实非常糟糕。所以,此办法一般只对比较简单的轮子好使,对于复杂的轮子,请量力而行。

轮子不好拆,其实是一个非常严重的问题。重复发明轮子固然是时间的浪费,但当轮子复杂而又不好拆的时候,尤其是原来造轮子的人已经不在场的时候,重新发明和建造轮子往往会成为无奈之下最好的选择。这是为什么工业界在明知道重复发明/制造轮子非常不好的情况下还在不断重复发明/制造轮子的根本原因。

程序本质是逻辑演绎的形式化表达,记载的是人类对这个世界的数字化理解。不能拆的轮子就像那一篇篇丢了曲谱的宋词一样,能读,却不能唱。

鄙人不才,正在自己研究怎么设计建造一种既好用又好拆的轮子。您没那么幸运,恐怕是等不到鄙人的技术做出来并发扬光大了。在那之前,多造轮子,多拆好拆的小轮子,应该是提高编程能力最好的办法了。

以上。嗯。
(文章属个人观点,与本人工作雇主无关。)

回答:

作者:家飞猫
链接:http://www.zhihu.com/question/31034164/answer/61625952
来源:知乎

编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。
编程能力是一种运用机器解决问题的能力。首先是要判断问题在什么程度上可被机器解决,比如理论计算机科学会告诉我们什么可做、什么理论上不可做、什么理论上可做实践上不可做。然后是让机器更好地理解问题,比如计算机都是(图灵-冯诺依曼模型)等价,但不同的问题可能会适用不同的编程语言。再后是让机器能更高效率地解决问题,比如同样的问题可能会有效率差别巨大的算法。
编程能力是一种抽象问题的能力。借用轮子是很好的办法,省力省时间。今天任何软件工程师都会有意无意地使用很多轮子,从操作系统编译器数据库网络到算法数据结构。想高效地借用轮子,就需要将问题分解再分解,抽象再抽象。任何一个实用的系统(不包括教科书上的示例程序和简单的脚本程序)都需要进行大量的分拆和组合。所以系统设计是编程能力里的高级技能,加合理的假设简化问题尤其有难度,此处不展开讨论。高手和新手的区别在于新手往往不知道轮子的适用范围,而高手的手上轮子数量多且熟知各种轮子的差异,所以对不同的问题可以轻松地找到合适的轮子,当实在找不到合适的轮子时可以自己动手改造现有的轮子。平时有时间拆装和改造已有的轮子会对水平提升有较大帮助。当然能知道怎样快速在搜索引擎里搜出轮子也是一种能力。
编程能力是一种需要考虑扩展性的能力。算法竞赛中的很多算法考虑的是单机的内存算法,计算模型经过高度抽象,在实践中机器的模型更为复杂。比如单机的多级结构带来的各种时间空间复杂度的取舍平衡,多机网络中如何能在提高单机性能外进一步优化整体性能。除了在机器端的扩展,在程序员一端的扩展也很重要。复杂的问题和工程往往意味着团队协同以及更长时间的开发维护,团队分工和设计沟通这里暂且不论。举个容易被忽视的例子,程序中的注释。高手会更在意完整且表达清楚的注释,因为这是写给现在和未来的团队(包括自己和其他成员)看的,直接影响到长期的整体开发维护效率。
编程能力是一种取舍的能力。局部的最优解未必是全局的最优解。如果一个美妙的解决方案需要将完工时间向后推迟一两个月,需要考虑是否先使用平凡方案解决问题,之后再进行优化。当你的工作延后会阻碍别人的工作时尤其如此。发现一个绝妙的优化方案时先想想这个优化是否真的有价值,如果只是系统中很小的部分,那么不要为了追求心理满足而花很多时间放一个漂亮的轮子上去(参考Amdahl定律)。
编程能力是一种预见未来的能力。目前的方案有哪些假设和局限性,在何种情形下会遇到问题甚至崩溃。在未来出现问题时问题是否需要重新定义,系统是否需要重新设计,代码是否需要重构或优化等等都需要未雨绸缪。
编程能力是一种工程能力。无它,唯手熟尔。

编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。
编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。
(重要的事情说三遍,重要的事情说三遍,重要的事情说三遍)

据说 JS 是世界上最好的编程语言?

作者:伯乐在线 – 伯小乐

网址:http://web.jobbole.com/84693/

【伯乐在线导读】:2016年1月中旬,Stack Overflow发起本年度的开发者调查。调查结果于近日公布,伯乐在线翻译组黄小非完整翻译了的调查报告。本文盘点 JS 开发者应该会关心的部分数据。

Stack Overflow 技术排行榜:

在2015年6月,JavaScript超越了Java成为Stack Overflow上最热门的标签。

Stack Overflow 技术趋势

新潮的Web开发技术,比如React,Node.js,还有AngularJS正在逐渐起势。

从 2013 至 2016 年,JS 四年蝉联最热门技术

程序员最想要的技术,Node 和 Angular 排第二和第三

全栈工程师最青睐的技术,JS 第一

前端开发者最青睐的技术,JS 自然第一

后端开发者最青睐的技术,JS 第一

学生程序员最青睐的技术,JS 第二

JavaScript 是这个星球上最受欢迎的编程语言。而且后端开发者甚至更喜欢使用JavaScript来工作。

多个相关的技术:

每一个开发者(在日常工作中)平均要使用四五种主流编程语言、框架或者技术。最常规的双技术组合是 JavaScript和 SQL。最常见的三技术组合是 JavaScript、PHP 和 SQL。

根据职业划分的技术栈

看到栈了没?全栈开发者选择使用PHP作为后端原因,比任何其他语言都多。(紧接着的是C#和Java)。

JavaScript是如此普及,以至于后端开发者不管用什么类型的3技术组合都包含了JavaScript。这也说明有很多后端开发者其实也就是披着后端外衣的全栈开发者。我们的内部统计显示,有60%的职业开发者实际上是在做全栈的工作的。

按职位分类看程序员的报酬:

在用 JS 的全栈工程师中

在用 JS 的前端工程师中,

按职位分类的报酬:

懂得使用JavaScript并在为云平台工作的全栈开发者,以及使用React或者Redis技术的开发者比其他的开发者报酬更多。

懂得使用JavaScript和React,Node或者Angular技术的前端开发者比其他前端开发者的报酬更高。

开发环境(2016):

根据职位分类的开发环境:

数据科学家使用Vim和Notepad++。全栈开发者使用Visual Studio和Sublime。学生则使用Notepad++和Visual Studio和Notepad++。

操作系统:

去年,在开发者们使用的操作系统中,Mac系统比Linux的份额多了一点点,排在第二名。今年形势则非常明朗而且操作系统的发展趋势也很明显。如果这种趋势依然保持下去的话,那么明年Windows系统的使用量将会低于50%。

开发者希望在工作中学到什么?

一旦开发者找到了工作,他们就会去尝试学习新东西或创造新东西。对于印度开发者来说,得到升职的优先级要比其他国家的开发者来得高。

工作中的挑战:

不切实际的预期,糟糕的文档,不够详细的需求,这些都是开发者日常要面对的烦心事。听上去熟悉吧?

《StackOverflow 2016 年开发者调查》完整版中还有关于女程序员的数据,请查看:http://blog.jobbole.com/98977/

程序员必读书单 1.0

作者:Lucida

原文链接:http://lucida.me/blog/developer-reading-list/

本文把程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍,必读书籍,以及延伸阅读。旨在成为最好最全面的程序员必读书单。

前言

Reading makes a full man; conference a ready man; and writing an exact man.

Francis Bacon

优秀的程序员应该具备两方面能力:

  • 良好的程序设计能力:
    • 掌握常用的数据结构和算法(例如链表,栈,堆,队列,排序和散列);
    • 理解计算机科学的核心概念(例如计算机系统结构、操作系统、编译原理和计算机网络);
    • 熟悉至少两门以上编程语言(例如C++,Java,C#,和Python);
  • 专业的软件开发素养:
    • 具备良好的编程实践,能够编写可测试(Testable),可扩展(Extensible),可维护(Maintainable)的代码;
    • 把握客户需求,按时交付客户所需要的软件产品;
    • 理解现代软件开发过程中的核心概念(例如面向对象程序设计,测试驱动开发,持续集成,和持续交付等等)。

和其它能力一样,程序设计能力和软件开发素养源自项目经验和书本知识。项目经验因人而异(来自不同领域的程序员,项目差异会很大);但书本知识是相通的——尤其是经典图书,它们都能够拓宽程序员的视野,提高程序员的成长速度。

在过去几年的学习和工作中,我阅读了大量的程序设计/软件开发书籍。随着阅读量的增长,我意识到:

  • 经典书籍需要不断被重读——每一次重读都会有新的体会;
  • 书籍并非读的越多越好——大多数书籍只是经典书籍中的概念延伸(有时甚至是照搬);

意识到这两点之后,我开始思考一个很功利的问题:如何从尽可能少的书中,获取尽可能多的关键知识?换句话说:

  • 优秀的程序员应该掌握哪些关键概念?
  • 哪些书籍来可以帮助程序员掌握这些关键概念?

这即是这篇文章的出发点——我试图通过程序员必读书单这篇文章来回答上面两个问题。

标准

进入必读书单之前,我先介绍下书单里的书籍选择标准和领域选择标准。当然你也点击这里直接跳转到书单开始阅读。

书籍选择标准

  1. 必读:什么是必读书籍呢?如果学习某项技术有一本书无论如何都不能错过,那么这本书就是必读书籍——例如Effective Java于Java,CLR via C#于C#;
    • 注意我没有使用“经典”这个词,因为经典计算机书籍往往和计算机科学联系在一起,而且经典往往需要10年甚至更长的时间进行考验;
  2. 注重实践,而非理论:所以这个书单不会包含过于原理性的书籍;
  3. 入门—必读—延伸:必读书籍的问题在于:1. 大多不适合入门;2. 不够全面。考虑到没有入门阅读和延伸阅读的阅读列表是不完整的——所以书单中每个关键概念都会由一本入门书籍,一本必读书籍(有时入门书籍和必读书籍是同一本),和若干延伸阅读书籍所构成。

概念选择标准

  1. 全面:全面覆盖软件开发中重要的概念;
  2. 通用:适用于每一个程序员,和领域特定方向无关;
  3. 注重基础,但不过于深入:优秀的程序员需要良好的计算机科学基础,但程序员并没必要掌握过于深入的计算机科学知识。以算法为例,每个程序员都应该掌握排序、链表、栈以及队列这些基本数据结构和算法,但计算几何、线性规划和网络流这些算法可能就不是每个程序员都需要掌握的了;

通过这几个标准,我把程序员应掌握的关键概念分为程序设计,软件开发,以及个人成长三大类,每一大类均由若干关键概念组成。

快速通道

自从开博以来,经常会有朋友在论坛,微博,和QQ上提问学习X技术读什么书合适(例如:学习Java读什么书合适?如何学习程序设计?)所以我在这 里列出了一个“快速通道”——把常见的问题集中在一起,点击问题,即可直接进入答案。(当然,如果你把本文从头读到尾帮助会更大 :–))

程序员必读书单

入门书籍

程序设计:

  1. 基础理论编码:隐匿在计算机软硬件背后的语言
  2. 编程语言
  3. 编程语言理论编程语言实现模式
  4. 程序设计程序设计方法
  5. 算法与数据结构算法(第4版)
  6. 程序调试调试九法——软硬件错误的排查之道

软件开发:

  1. 编程实践程序设计实践
  2. 面向对象程序设计Head First设计模式
  3. 重构重构
  4. 软件测试How to Break Software
  5. 项目管理极客与团队
  6. 专业开发程序员修炼之道:从小工到专家
  7. 大师之言奇思妙想:15位计算机天才及其重大发现
  8. 界面设计写给大家看的设计书
  9. 交互设计通用设计法则

个人成长:

  1. 职业规划软件开发者路线图
  2. 思维方式程序员的思维修炼:开发认知潜能的九堂课
  3. 求职面试金领简历:敲开苹果微软谷歌的大门
  4. 英语写作The Only Grammar Book You’ll Ever Need

必读书籍

程序设计:

  1. 基础理论深入理解计算机系统(第2版)
  2. 编程语言
  3. 编程语言理论程序设计语言——实践之路(第3版)
  4. 程序设计计算机程序的构造与解释(第2版)
  5. 算法与数据结构编程珠玑(第2版)
  6. 程序调试调试九法——软硬件错误的排查之道

软件开发:

  1. 编程实践代码大全(第2版)
  2. 面向对象程序设计设计模式
  3. 重构修改代码的艺术
  4. 软件测试xUnit Test Patterns
  5. 项目管理人月神话
  6. 专业开发程序员职业素养
  7. 大师之言编程人生:15位软件先驱访谈录
  8. 界面设计认知与设计:理解UI设计准则(第2版)
  9. 交互设计交互设计精髓(第3版)

个人成长:

  1. 职业规划软件开发者路线图
  2. 思维方式如何把事情做到最好
  3. 求职面试程序员面试金典(第5版)
  4. 英语写作风格的要素

这个阅读列表覆盖了软件开发各个关键领域的入门书籍和必读书籍,我相信它可以满足绝大多数程序员的需求,无论你是初学者,还是进阶者,都可以从中获益:

  • 基础理论包括了程序员应该掌握的计算机基础知识;
  • 编程语言对软件开发至关重要,我选择了CC++JavaC#Python,和JavaScript这六门主流编程语言进行介绍,如果想进一步理解编程语言,可以阅读编程语言理论里的书目;
  • 在理解编程语言的基础上,优秀的程序员还应该了解各种程序设计技巧,熟悉基本的算法数据结构,并且能够高效的进行程序调试
  • 良好的程序设计能力是成为优秀程序员的前提,但软件开发知识也是必不可少的:优秀的程序员应具备良好的编程实践,知道如何利用面向对象重构,和软件测试编写可复用,可扩展,可维护的代码,并具备软件项目管理知识和专业开发素养;
  • 就像我们可以从名人传记里学习名人的成功经验,程序员也可以通过追随优秀程序员的足迹使自己少走弯路。大师之言包含一系列对大师程序员/计算机科学家的访谈,任何程序员都可以从中获益良多;
  • 为了打造用户满意的软件产品,程序员应当掌握一定的界面设计知识和交互设计知识(是的,这些工作应该交给UI和UX,但如果你想独自打造一个产品呢?);
  • 专业程序员应当对自己进行职业规划,并熟悉程序员求职面试的流程,以便在职业道路上越走越远;
  • 软件开发是一项需要不断学习的技能,学习思维方式可以有效的提升学习能力和学习效率;
  • 软件开发是一项国际化的工作,为了让更多的人了解你的代码(工作),良好的英语写作能力必不可少。

尽管我尽可能的去完善这个书单,但受限于我的个人经历,这个书单难免会有所偏颇。所以如果你有不同的意见,或者认为这个书单漏掉了某些重要书籍,请在评论中指出,我会及时更新。:–)

程序设计

1. 基础理论

编码:隐匿在计算机软硬件背后的语言

编码:隐匿在计算机软硬件背后的语言这本书其实不应该叫编码——它更应该叫“Petzold教你造计算机”——作者Charles Petzold创造性的以编码为主题,从电报机和手电筒讲到数字电路,然后利用数字电路中的逻辑门构造出加法器触发器,最后构造出一个完整的存储程序计算机。不要被这些电路概念吓到——编码使用大量形象贴切的类比简化了这些概念,使其成为最精彩最通俗易懂的计算机入门读物。

深入理解计算机系统(第2版)

深入理解计算机系统(第2版)这本书的全名是:Computer Systems:A Programmer’s Perspective(所以它又被称为CSAPP),我个人习惯把它翻译为程序员所需了解的计算机系统知识,尽管土了些,但更名副其实。

深入理解计算机系统是我读过的最优秀的计算机系统导论型作品,它创造性的把操作系统,计算机组成结构,数字电路,以及编译原理这些计算机基础学科中的核心概念汇集在一起,从而覆盖了指令集体系架构,汇编语言,代码优化,计算机存储体系架构,链接,装载,进程,以及虚拟内存这些程序员所需了解的关键计算机系统知识。如果想打下扎实的计算机基础又不想把操作系统计算机结构编译原理这些书统统读一遍,阅读深入理解计算机系统是最有效率的方式。

延伸阅读:

2. 编程语言

编程语言是程序员必不可少的日常工具。工欲善其事,必先利其器。我在这里给出了C,C++,Java,C#,JavaScript,和Python这六种常用编程语言的书单(我个人不熟悉Objective-C和PHP,因此它们不在其中)。

需要注意的是:我在这里给出的是编程语言(Programming Language)书籍,而非编程平台(Programming Platform)书籍。以Java为例,Effective Java属于编程语言书籍,而Android编程权威指南就属于编程平台书籍。

C

C和指针

忘记谭浩强那本糟糕不堪的C程序设计,C和指针才是C语言的最佳入门书籍。它详细但又不失简练的介绍了C语言以及C标准库的方方面面。

对于C语言初学者,最难的概念不仅仅是指针和数组,还有指向数组的指针和指向指针的指针。C和指针花了大量的篇幅和图示来把这些难懂但重要的概念讲的清清楚楚,这也是我推荐它作为C语言入门读物的原因。

C程序设计语言(第2版)

尽管C程序设计语言是二十多年前的书籍,但它仍然是C语言——以及计算机科学中最重要的书籍之一,它的重要性不仅仅在于它用清晰的语言和简练的代码描述了C语言全貌,而且在于它为之后的计算机书籍——尤其是编程语言书籍树立了新的标杆。以至于在很多计算机书籍的扉页,都会有“感谢Kernighan教会我写作”这样的字样。

延伸阅读:

  • C专家编程:不要被标题中的“专家”吓到,这实际是一本很轻松的书籍,它既包含了大量C语言技术细节和编程技巧,也包含了很多有趣的编程轶事;
  • C陷阱与缺陷:书如其名,这本书介绍了C语言中常见的坑和一些稀奇古怪的编程“技巧”,不少刁钻的C语言面试题都源自这本小册子;
  • C语言参考手册:全面且权威的C语言参考手册,而且覆盖C99,如果你打算成为C语言专家,那么这本书不可错过;
  • C标准库:给出了15个C标准库的设计思路,实现代码,以及测试代码,配合C程序设计语言阅读效果更佳;
  • C语言接口与实现:这本书展示了如何使用C语言实现可复用的数据结构,其中包含大量C语言高级技巧,以至于Amazon上排行第一的评论是“Probably the best advanced C book in existance”,而排行第二的评论则是“By far the most advanced C book I read”。

C++

C++程序设计原理与实践

作为C++的发明者,没有人能比Bjarne Stroustrup更理解C++。Bjarne在Texas A&M大学任教时使用C++为大学新生讲授编程,从而就有了C++程序设计原理与实践这本书——它面向编程初学者,既包含C++教程,也包含大量程序设计原则。它不但是我读过最好的C++入门书,也是我读过最好的编程入门书。

比较有趣的是,C++程序设计原理与实践直到全书过半都没有出现指针,我想这可能是Bjarne为了证明不学C也可以学好C++吧。

C++程序设计语言(第4版)

同样是Bjarne Stroustrup的作品,C++程序设计语言是C++最权威且最全面的书籍。第4版相对于之前的版本进行了全面的更新,覆盖了第二新的C++ 11标准,并砍掉了部分过时的内容。

延伸阅读:

  • A Tour of C++:如果你觉得C++程序设计语言过于庞大,但你又想快速的浏览一遍新版C++的语言特色,那么可以试试这本小红书;
  • C++语言的设计与演化:C++的“历史书”,讲述了C++是如何一步一步从C with Classes走到如今这一步,以及C++语言特性背后的故事;
  • C++标准库(第2版):相对于其它语言的标准库,C++标准库虽然强大,但学习曲线十分陡峭,这本书是学习C++标准库有力的补充;
  • 深度探索C++对象模型:这本书系统的讲解了C++是如何以最小的性能代价实现对象模型,很多C++面试题(包括被问烂的虚函数指针)都可以在这本书里找到答案;
  • Effective C++More Effective C++:由于C++的特性实在繁杂,因此很容易就掉到坑里。Effective系列既讲述了C++的良好编程实践,也包含C++的使用误区,从而帮你绕过这些坑。

Java

Java核心技术(第9版)

平心而论Java核心技术(即Core Java)并不算是一本特别出色的书籍:示例代码不够严谨,充斥着很多与C/C++的比较,语言也不够简洁——问题在于Java并没有一本很出色的入门书籍,与同类型的Java编程思想相比,Java核心技术至少做到了废话不多,与时俱进(Java编程思想还停留在Java 6之前),矮子里面选将军,Java核心技术算不错了。

Effective Java(第2版)

尽管Java没有什么出色的入门书籍,但这不代表Java没有出色的必读书籍。Effective Java是我读过的最好的编程书籍之一,它包含大量的优秀Java编程实践,并对泛型和并发这两个充满陷阱的Java特性给出了充满洞察力的建议,以至于Java之父James Gosling为这本书作序:“我很希望10年前就拥有这本书。可能有人认为我不需要任何Java方面的书籍,但是我需要这本书。”

延伸阅读:

  • 深入理解Java虚拟机(第2版):非常优秀且难得的国产佳作,系统的介绍了Java虚拟机和相关工具,并给出了一些调优建议;
  • Java程序员修炼之道:在这本书之前,并没有一本Java书籍系统详细的介绍Java 7的新特性(例如新的垃圾收集器,try using结构和invokedynamic指令),这本书填补了这个空白;
  • Java并发编程实践:系统全面的介绍了Java的并发,如何设计支持并发的数据结构,以及如何编写正确的并发程序;
  • Java Puzzlers:包含了大量的Java陷阱——以至于读这本书时我说的最多的一个词就是WTF,这本书的意义在于它是一个反模式大全,Effective Java告诉你如何写好的Java程序,而Java Puzzlers则告诉你糟糕的Java程序是什么样子。更有意思的是,这两本书的作者都是Joshua Bloch

视频教程:

  • Java语言学习极速之旅:系统全面的Java语言教程,6个阶段Java基础入门,循序渐进掌握Java面向对象精髓。3个Java进阶方向,Java SE、Java EE、Android开发,每一个都包含相应的知识点精讲和项目开发实例,快速上手。
  • Android 0基础极速养成计划:Android开发快速入门视频教程,通过对Android基础知识讲解,详细介绍Android开发环境搭建,同时包含Android实战案例解析,通过全新实战的Android课程,系统学习Android开发。

C#

精通C#(第6版)

可能你会疑问我为什么会推荐这本接近1200页的“巨著”用作C#入门,这是我的答案:

  1. C#的语言特性非常丰富,很难用简短的篇幅概括这些特性;
  2. 精通C#之所以有近1200页的篇幅,是因为它不但全面介绍了C#语言,而且还覆盖了ADO.NET,WCF,WF,WPF,以及ASP.NET这些.Net框架。你可以把这本书视为两本书——一本500多页的C#语言教程和一本600多页的.Net平台框架快速上手手册。
  3. 尽管标题带有“精通”两字,精通C#实际上是一本面向初学者的C#书籍,你甚至不需要太多编程知识,就可以读懂它。

CLR via C#(第4版)

CLR via C#是C#/.Net最重要的书籍,没有之一。它全面介绍了.Net的基石——CLR的运行原理,以及构建于CLR之上的C#类型系统,运行时关系,泛型,以及线程/并行等高级内容。任何一个以C#为工作内容的程序员都应该阅读此书。

延伸阅读:

  • 深入理解C#(第3版):C#进阶必读,这本书偏重于C#的语言特性,它系统的介绍了C#从1.0到C# 4.0的语言特性演化,并展示了如何利用C#的语言特性编写优雅的程序;
  • .NET设计规范(第2版):C#专业程序员必读,从变量命名规范讲到类型系统设计原则,这本书提供了一套完整的.Net编程规范,使得程序员可以编写出一致,严谨的代码,
  • C# 5.0权威指南:来自O’Reilly的C#参考手册,严谨的介绍了C#语法,使用,以及核心类库,C#程序员案头必备;
  • LINQ to Objects Using C# 4.0Async in C# 5.0:LINQ和async分别是.Net 3.5和.Net 4.5中所引入的最重要的语言特性,所以我认为有必要在它们上面花点功夫——这两本书是介绍LINQ和async编程的最佳读物。

JavaScript

JavaScript DOM编程艺术(第2版)

尽管JavaScript现在可以做到客户端服务器端通吃,尽管JQuery之类的前端框架使得一些人可以不懂JavaScript也可以编程,但我还是认为学习JavaScript从HTML DOM开始最为适合,因为这是JavaScript设计的初衷。JavaScript DOM编程艺术系统的介绍了如何使用JavaScript,HTML,以及CSS创建可用的Web页面,是一本前端入门佳作。

JavaScript语言精粹

JavaScript语言包含大量的陷阱和误区,但它却又有一些相当不错的特性,这也是为什么Douglas Crockford称JavaScript为世界上最被误解的语言,并编写了JavaScript语言精粹一书来帮助前端开发者绕开JavaScript中的陷阱。和同类书籍不同,JavaScript语言精粹用精炼的语言讲解了JavaScript语言中好的那部分(例如闭包,函数是头等对象,以及对象字面量),并建议读者不要使用其它不好的部分(例如混乱的类型转换,默认全局命名空间,以及奇葩的相等判断符),毕竟,用糟糕的特性编写出来的程序往往也是糟糕的。

延伸阅读:

Python

Python基础教程(第二版)

Python的入门书籍很多,而且据说质量大多不错,我推荐Python基础教程的原因是因为它是我的Python入门读物——简洁,全面,代码质量很不错,而且有几个很有趣的课后作业,使得我可以快速上手。

这里顺便多说一句,不要用Python学习手册作为Python入门——它的废话实在太多,你能想象它用了15页的篇幅去讲解if语句吗?尽管O’Reilly出了很多经典编程书,但这本Python学习手册绝对不在其中。

Python参考手册(第4版)

权威且实用的Python书籍,覆盖Python 2和Python 3。尽管它名为参考手册,但Python参考手册在Python语法和标准库基础之上对其实现机制也给出了深入的讲解,不容错过。

延伸阅读:

3. 编程语言理论

编程语言实现模式

大多数程序员并不需要从头编写一个编译器或解释器,因此龙书(编译原理)就显得过于重量级;然而多数程序员还是需要解析文本,处理配置文件,或者写一个小语言,编程语言实现模式很好的满足了这个需求。它把常用的文本解析/代码生成方法组织成一个个模式,并为每个模式给出了实例和应用场景。这本书既会提高你的动手能力,也会加深你对编程语言的理解。Python发明者Guido van Rossum甚至为这本书给出了“Throw away your compiler theory book!”这样的超高评价。

程序设计语言——实践之路(第3版)

程序员每天都要和编程语言打交道,但是思考编程语言为什么会被设计成这个样子的程序员并不多,程序设计语言——实践之路完美的回答了这个问题。这本书从编程语言的解析和运行开始讲起,系统了介绍了命名空间,作用域,控制流,数据类型以及方法(控制抽象)这些程序设计语言的核心概念,然后展示了这些概念是如何被应用到过程式语言,面向对象语言,函数式语言,脚本式,逻辑编程语言以及并发编程语言这些具有不同编程范式的编程语言之上。这本书或极大的拓宽你的视野——无论你使用什么编程语言,都会从这本书中获益良多。理解这一本书,胜过学习十门新的编程语言。

延伸阅读:

  • 七周七语言:理解多种编程范型:尽管我们在日常工作中可能只使用两三门编程语言,但是了解其它编程语言范式是很重要的。七周七语言一书用精简的篇幅介绍了Ruby,Io,Prolog,Scala,Erlang,Clojure,和Haskell这七种具有不同编程范式的语言——是的,你没法通过这本书变成这七种语言的专家,但你的视野会得到极大的拓宽;
  • 自制编程语言:另一本优秀的编译原理作品,自制编程语言通过从零开始制作一门无类型语言Crowbar和一门静态类型语言Diksam,把类型系统,垃圾回收,和代码生成等编程语言的关键概念讲的清清楚楚;
  • 计算的本质:深入剖析程序和计算机:披着Ruby外衣的计算理论入门书籍,使你对编程语言的理解更上一层楼。

4. 程序设计

程序设计方法

现代编程语言的语法大多很繁杂,初学者使用这些语言学习编程会导致花大量的时间在编程语言语法(诸如指针,引用和类型定义)而不是程序设计方法(诸如数据抽象和过程抽象)之上。程序设计方法解决了这个问题——它专注于程序设计方法,使得读者无需把大量时间花在编程语言上。这本书还有一个与之配套的教学开发环境DrScheme,这个环境会根据读者的程度变换编程语言的深度,使得读者可以始终把注意力集中在程序设计方法上。

我个人很奇怪程序设计方法这样的佳作为什么会绝版,而谭浩强C语言这样的垃圾却大行其道——好在是程序设计方法第二版已经被免费发布在网上。

计算机程序的构造与解释(第2版)

计算机程序的构造与解释是另一本被国内大学忽视(至少在我本科时很少有人知道这本书)的教材,这本书和程序设计方法有很多共同点——都使用Scheme)作为教学语言;都专注于程序设计方法而非编程语言本身;都拥有相当出色的课后题。相对于程序设计方法计算机程序的构造与解释要更加深入程序设计的本质(过程抽象,数据抽象,以及元语言抽象),以至于Google技术总监Peter Norvig给了这本书超高的评价

延伸阅读:

  • 编程原本STL作者的关于程序设计方法佳作——他把关系代数和群论引入编程之中,试图为程序设计提供一个坚实的理论基础,从而构建出更加稳固的软件。这本书是程序设计方法计算机程序的构造与解释的绝好补充——前者使用函数式语言(Scheme)讲授程序设计,而编程原本则使用命令式语言(C++);
  • 元素模式设计模式总结了面向对象程序设计中的模式,而元素模式这本书分析了程序设计中的常见模式的本质,阅读这本书会让你对程序设计有更深的理解;
  • The Science of Programming:会编程的人很多,但能够编写正确程序的人就少多了。The Science of Programming通过前条件——不变式——后条件以及逻辑谓词演算,为编写正确程序提供了强有力的理论基础,然后这本书通过实例阐述了如何应用这些理论到具体程序上。任何一个想大幅提高开发效率的程序员都应阅读此书。

5. 算法与数据结构

算法(第4版)

我在算法学习之路一文中提到我的算法入门教材是数据结构与算法分析:C语言描述,我曾经认为它是最好的算法入门教材,但自从我读到Sedgewick算法之后我就改变了观点——这本算法才是最好的算法入门教材:

  • 使用更为容易的Java语言作为教学语言;
  • 覆盖所有常用的数据结构和算法,并均给出其完整实现;
  • 包含大量的图示用于可视化算法——事实上这是我读过的图示最为丰富形象的书籍,这也是我称其为最好的算法入门书籍的原因。

编程珠玑(第2版)

编程珠玑(第2版)是一本少见的实践型算法书籍——它并非一一介绍数据结构/算法的教材,而是实践性极强的算法应用手册。作者(Jon Bentley)从他多年的实际经验精选出一些有趣而又实用的问题,然后展示了他解决这些问题的过程(分析问题,选择合适的算法,解决问题,以及验证答案)。任何程序员都可以从中获益。

延伸阅读:

  • 编程珠玑(续):严格来说这本书并非编程珠玑的续作,而是一本类似于番外篇的编程技巧/实践手册;它不像编程珠玑那般重视算法的应用,而是全面覆盖了程序员所需的能力;
  • 算法导论(第3版):尽管我在这边文章开头提到会尽量避免理论性的书籍,但没有算法导论的算法阅读列表是不完整的,我想这本书就不需要我多介绍了; :–)
  • 算法设计与分析基础(第3版):侧重于算法设计,这本书创新的把常见算法分为分治,减治,变治三大类,并覆盖了动态规划,回溯,以及分支定界等高级算法设计方法,属于算法设计的入门佳作;

6. 程序调试

调试九法——软硬件错误的排查之道

一个让非编程从业人员惊讶的事实是程序员的绝大多时间都花在调试上,而不是写程序上,以至于Bob大叔调试时间占工作时间的比例作为衡量程序员开发能力的标准。调试九法——软硬件错误的排查之道既是调试领域的入门作品,也是必读经典之作。调试九法的作者是一个具有丰富实战经验的硬件工程师,他把他多年的调试经验总结成九条调试法则,并对每一条法则都给对应的实际案例。任何程序员都应通过阅读这本书改善调试效率,即便是非程序员,也可以从这本书中学到系统解决问题的方法。

延伸阅读:

  • Writing Solid Code最好的调试是不调试——Writing Solid Code介绍了断言,设计清晰的API,以及单步代码等技巧,用于编写健壮的代码,减少调试的时间;
  • 软件调试的艺术:调试工具书——这本书详细的介绍了常见的调试器工具,并通过具体案例展示了它们的使用技巧;

软件开发

1. 编程实践

程序设计实践

Brian Kernighan是这个星球上最好的计算机书籍作者:从上古时期的Software Tools,到早期的Unix编程环境C程序设计语言,再到这本程序设计实践,每本书都是必读之作。

尽管程序设计实践只有短短200余页,但它使用精炼的代码和简要的原则覆盖了程序设计的所有关键概念(包括编程风格,算法与数据结构,API设计,调试,测试,优化,移植,以及领域特定语言等概念)。如果你想快速掌握良好的编程实践,或者你觉着900多页的代码大全过于沉重,那么程序设计实践是你的不二之选。我第一次读这本书就被它简洁的语言和优雅的代码所吸引,以至于读研时我买了三本程序设计实践——一本放在学校实验室,一本放在宿舍,一本随身携带阅读。我想我至少把它读了十遍以上——每一次都有新的收获。

代码大全(第2版)

无论在哪个版本的程序员必读书单,代码大全都会高居首位。和其它程序设计书籍不同,代码大全用通俗清晰的语言覆盖了软件构建(Software Construction)中各个层次上所有的重要概念——从变量命名到类型设计,从控制循环到代码结构,从测试和调试到构建和集成,代码大全可谓无所不包,你可以把这本书看作为程序员的一站式(Once and for all)阅读手册。更珍贵的是,代码大全在每一章末尾都给出了价值很高的参考书目(参考我之前的如何阅读书籍一文),如果你是一个初出茅庐的程序员,代码大全是绝好的阅读起点。

延伸阅读:

  • 编写可读代码的艺术:专注于代码可读性(Code Readability),这本书来自Google的两位工程师对Google Code Readability的总结。它给出了大量命名,注释,代码结构,以及API设计等日常编码的最佳实践,并包含了很多看似细微但却可以显著提升代码可读性的编程技巧。这本书的翻译还不错,但如果你想体会书中的英语幽默(例如Tyrannosaurus——Stegosaurus——Thesaurus),建议阅读它的英文影印版
  • 卓有成效的程序员:专注于生产效率(Productivity),它既包含源自作者多年经验的高生产率原则,也包含大量的提高生产率的小工具,每个追求高生产率的程序员都应该阅读这本书;
  • UNIX编程艺术:专注于程序设计哲学,这本书首先总结出包括模块化,清晰化,可组合,可分离等17个Unix程序设计哲学,接下来通过Unix历史以及各种Unix编程工具展示了这些原则的应用。尽管个人觉的这本书有些过度拔高Unix且过度贬低Windows和M$,但书中的Unix设计哲学非常值得借鉴。

2. 面向对象程序设计

Head First设计模式

无论是在Amazon还是在Google上搜索设计模式相关书籍,Head First设计模式都会排在首位——它使用风趣的语言和诙谐的图示讲述了观察者,装饰者,抽象工厂,和单例等关键设计模式,使得初学者可以迅速的理解并掌握设计模式。Head First设计模式在Amazon上好评如潮,就连设计模式原书作者Erich Gamma都对它给出了很高的评价。

需要注意,Head First设计模式是非常好的设计模式入门书,但千万不要把这本书作为学习设计模式的唯一的书——是的,Head First设计模式拥有风趣的语言和诙谐的例子,但它既缺乏实际的工程范例,也没有给出设计模式的应用/适用场景。我个人建议是在读过这本书之后立即阅读“四人帮”)的设计模式Bob大叔敏捷软件开发,以便理解设计模式在实际中的应用。

设计模式

设计模式作为设计模式领域的开山之作,Erich Gamma,Richard Helm,Ralph Johnson等四位作者将各个领域面向对象程序开发的经验总结成三大类23种模式,并给出了每个模式的使用场景,变体,不足,以及如何克服这些不足。这本书行文严谨紧凑(四位作者都是PhD),并且代码源自实际项目,属于设计模式领域的必读之作。

需要注意:设计模式不适合初学者阅读——它更像是一篇博士论文而非技术书籍,加上它的范例都具有很强的领域背景(诸如GUI窗口系统和富文本编辑器),缺乏实际经验的程序员很难理解这本书。

延伸阅读:

3. 重构

重构

任何产品代码都不是一蹴而就,而是在反复不断的修改中进化而来。重构正是这样一本介绍如何改进代码的书籍——如何在保持代码行为的基础上,提升代码的质量(这也是重构的定义)。

我见过很多程序员,他们经常声称自己在重构代码,但他们实际只做了第二步(提升代码的质量),却没有保证第一步(保持代码行为),因此他们所谓的重构往往会适得其反——破坏现有代码或是引入新bug。这也是我推荐重构这本书的原因——它既介绍糟糕代码的特征(Bad smell)和改进代码的方法,也给出了重构的完整流程——1. 编写单元测试保持(Preserve)程序行为;2. 重构代码;3. 保证单元测试通过。重构还引入了一套重构术语(诸如封装字段,内联方法,和字段上移),以便程序员之间交流。只有理解了这三个方面,才能算是理解重构。

修改代码的艺术

这里再重复一遍重构的定义——在保持代码行为的基础上,提升代码的质量。重构专注于第二步,即如何提升代码的质量,而修改代码的艺术专注于第一步,即如何保持代码的行为。

提升代码质量并不困难,但保持代码行为就难多了,尤其是对没有测试的遗留代码(Legacy Code)而言——你需要首先引入测试,但遗留代码往往可测试性(Testability)很差,这时你就需要把代码变的可测试。修改代码的艺术包含大量的实用建议,用来把代码变的可测试(Testable),从而使重构变为可能,使提高代码质量变为可能。

延伸阅读:

  • 重构与模式:这本书的中文书名存在误导,它的原书书名是Refactoring to Patterns——通过重构,把模式引入代码。这本书阐述了重构和设计模式之间的关系,使得程序员可以在更高的层次上思考重构,进行重构。

4. 软件测试

How to Break Software

关于软件测试的书籍很多,但很少有一本测试书籍能像How to Break Software这般既有趣又实用。不同于传统的软件测试书籍(往往空话连篇,无法直接应用),How to Break Software非常实际——它从程序员的心理出发,分析软件错误/Bug最可能产生的路径,然后针对这些路径进行残酷的测试,以保证软件质量。

我在第一次阅读这本书时大呼作者太过“残忍”——连这些刁钻诡异的测试招数都能想出来。但这种毫不留情(Relentless)的测试风格正是每个专业程序员所应具备的心态。

注意:如果你是一个测试工程师,那么在阅读这本书前请三思——因为阅读它之后你会让你身边的程序员苦不堪言,甚至连掐死你的心都有 :-D。

xUnit Test Patterns

How to Break Software注重黑盒测试,而这本xUnit Test Patterns则注重白盒测试。正如书名所示,xUnit Test Patterns覆盖了单元测试的每个方面:从如何编写良好的单元测试,到如何设计可测试(Testable)的软件,再到如何重构测试——可以把它看作为单元测试的百科全书。

延伸阅读:

  • Practical Unit Testing with JUnit and Mockito:尽管xUnit Test Patterns覆盖了单元测试的方方面面,但它的问题在于不够与时俱进(07年出版)。Practical Unit Testing弥补了这个缺陷——它详细介绍了如何通过测试框架JUnit和Mock框架Mockito编写良好的单元测试,并给出了大量优秀单元测试的原则;
  • 单元测试的艺术(第2版):可以把这本书看作为前一本书的.Net版,适合.Net程序员;
  • Google软件测试之道:这本书详细介绍了Google如何测试软件——包括Google的软件测试流程以及Google软件测试工程师的日常工作/职业发展。需要注意的是:这本书中的测试流程在国内很可能行不通(国内企业缺乏像Google那般强大的基础设施(Infrastructure)),但它至少可以让国内企业有一个可以效仿的目标;
  • 探索式软件测试James Whittaker的另一本测试著作,不同于传统的黑盒/白盒测试,这本书创造性的把测试比喻为“探索”(Exploration),然后把不同的探索方式对应到不同的测试方式上,以便尽早发现更多的软件错误/Bug。

5. 项目管理

极客与团队

很多程序员都向往成为横扫千军(One-man Army)式的“编程英雄”,但卓越的软件并非一人之力,而是由团队合力而成。极客与团队就是这样一本写给程序员的如何在团队中工作的绝好书籍,它围绕着HRT三大原则(Humility谦逊,Respect尊重,和Trust信任),系统的介绍了如何融入团队,如何打造优秀的团队,如何领导团队,以及如何应对团队中的害群之马(Poisonous People)。这本书实用性极强,以至于Python之父Guido van Rossum都盛赞这本书“说出了我一直在做但总结不出来的东西”

人月神话

尽管人月神话成书于40年前,但它仍是软件项目管理重要的书籍。人月神话源自作者Fred Brooks领导并完成System/360OS/360这两个即是放到现在也是巨型软件项目的里程碑项目的经验总结。它覆盖了软件项目各个方面的关键概念:从工期管理(Brooks定律)到团队建设(外科团队),从程序设计(编程的本质是使用正确的数据结构)到架构设计(概念完整性),从原型设计(Plan to Throw one away)到团队交流(形式化文档+会议)。令人惊讶的是,即便40年之后,人月神话中的关键概念(包括焦油坑,Brooks定律概念完整性外科团队第二版效应等等)依然适用,而软件开发的核心复杂度仍然没有得到解决(没有银弹)。

延伸阅读:

  • 人件(原书第3版):从人的角度分析软件项目。人件从雇佣正确的人,创建健康的工作环境,以及打造高效的开发团队等角度阐述了如何改善人,从而改善软件项目;
  • 门后的秘密:卓越管理的故事:这本书生动的再现了软件项目管理工作的场景,并给出了各种实用管理技巧,如果你有意转向管理岗位,这本书不容错过;
  • 大教堂与集市:这本书从黑客的历史说起,系统而又风趣的讲述了开源运动的理论和实践,以及开源软件项目是如何运作并发展的。了解开源,从这本书开始。

6. 专业开发

程序员修炼之道:从小工到专家

不要被庸俗的译名迷惑,程序员修炼之道是一本价值极高的程序员成长手册。这本书并不局限于特定的编程语言或框架,而是提出了一套切实可行的实效(Pragmatic)开发哲学,并通过程序设计,测试,编程工具,以及项目管理等方面的实例展示了如何应用这套开发哲学,从而使得程序员更加高效专业。有人把这本书称之为迷你版代码大全——代码大全给出了大量的优秀程序设计实践,偏向术;而程序员修炼之道给出了程序设计实践背后的思想,注重道。

程序员职业素养

程序员修炼之道指出了如何成为专业程序员,这本程序员职业素养则指出了专业程序员应该是什么样子——承担责任;知道自己在做什么;知道何时说不/何时说是;在正确的时间编写正确的代码;懂得自我时间管理和工期预估;知道如何应对压力。如果你想成为专业程序员(Professional Developer)(而不是码农(Code Monkey)),这本书会为你指明前进的方向。

延伸阅读:

7. 大师之言

奇思妙想:15位计算机天才及其重大发现

奇思妙想:15位计算机天才及其重大发现是一本极具眼光的技术访谈书籍——在这本书访谈的15位计算机科学家中,竟出现了12位图灵奖获得者——要知道图灵奖从1966年设奖到现在也只有六十几位获奖者而已。

奇思妙想把计算机科学分为四大领域:编程语言;算法;架构;人工智能。并选取了每个领域下最具代表性的计算机科学家进行访谈。因为这些计算机科学家都是其所在领域的开拓者,因此他们能给出常人无法给出的深刻见解。通过这本书,你可以了解前三十年的计算机科学的发展历程——计算机科学家做了什么,而计算机又能做到/做不到什么。从而避免把时间浪费在前人已经解决的问题(或者根本无法解决的问题)上面。

编程人生:15位软件先驱访谈录

同样是访谈录,同样访谈15个人,编程人生把重点放在程序员(Coders at work)上。它从各个领域选取了15位顶尖的程序员,这些程序员既包括Ken ThompsonJamie Zawinski这些老牌Unix黑客,也包括Brad Fitzpatrick这样的80后新生代,还包括Frances AllenDonald Knuth这样的计算机科学家。这种多样性(Diversity)使得编程人生兼具严谨性和趣味性,无论你是什么类型的程序员,都能从中受益良多。

延伸阅读:

  • 图灵和ACM图灵奖(1966-2011):通过图灵奖介绍整个计算机科学发展史,非常难得的国产精品图书;
  • 编程大师访谈录:可以把这本书看作为二十年前的编程人生,被访谈者都是当时叱咤风云的人物(例如微软的创造者Bill Gates,Macintosh的发明者Jeff Raskin,以及Adobe的创始人John Warnock等等)。有趣的是这本书中大量的经验和建议到如今依然适用;
  • 编程大师智慧:类似于编程人生,不同的是被访谈者都是编程语言的设计者——这本书覆盖了除C语言以外的几乎所有主流编程语言。通过这本书,你可以从中学到编程语言背后的设计思想——编程语言为什么要被设计成这样,是什么促使设计者要在语言中加入这个特性(或拒绝那个特性)。从而提升对编程语言的理解。

8. 界面设计

写给大家看的设计书

书如其名,写给大家看的设计书是一本面向初学者的快速设计入门。它覆盖了版式,色彩,和字体这三个设计中的关键元素,并创造性的为版式设计总结出CRAP四大原则(Contrast对比,Repetition重复,Alignment对齐,Proximity亲密)。全书使用丰富生动的范例告诉读者什么是好的设计,什么是不好的设计,使得即便是对设计一无所知的人,也可以从这本书快速入门。

认知与设计:理解UI设计准则(第2版)

写给大家看的设计书强调实践,即如何做出好的设计;认知与设计:理解UI设计准则强调理论,即为什么我们会接受这样的设计而反感那样的设计。如果你想要搞清楚设计背后的心理学知识,但又不想阅读大部头的心理学著作,那么认知与设计是你的首选。

延伸阅读:

  • GUI设计禁忌 2.0:这本书指出了GUI设计的原则和常见误区,然后通过具体范例指出了如何避免这些误区。如果你的工作涉及到用户界面,那么这本书会为你减少很多麻烦;
  • 界面设计模式(第2版):这本书将用户界面中的常见元素/行为组织成彼此关联的模式,以便读者理解并举一反三,从而将其运用到自己的应用中;
  • 移动应用UI设计模式:类似于界面设计模式,但面向移动平台。它给出了iOS,Android,以及Windows Phones上常用的90余种界面设计模式,从而使得你不必把这些平台的应用挨个玩一遍也可以掌握各个平台的设计精髓。如果你主攻Android平台,那么Android应用UI设计模式会是更好的选择;
  • 配色设计原理版式设计原理:如果你读过写给大家看的设计书之后想继续深入学习设计,这两本书是不错的起点。

9. 交互设计

通用设计法则

书如其名,通用设计法则给出了重要的125个设计原则,并用简练的语言和范例展示了这些原则的实际应用。每个原则都有对应的参考文献,以便读者进一步学习。我之所以推荐这本书,是因为:1. 程序员需要对设计有全面的认识;2. 程序员并不需要知道这些设计原则是怎么来的,知道怎么用即可。这本书很好的满足了这两个要求。

交互设计精髓(第3版)

交互设计精髓是交互设计领域的圣经级著作。交互设计专家(以及VB之父)Alan Cooper在这本书中详细介绍了交互设计的原则,流程,以及方法,然后通过各种范例(主要来自桌面系统)展示了如何应用这些原则。

需要注意的是这本书的第4版已经出版,它在第三版的基础上增加了移动设计以及Web设计等内容。

延伸阅读:

  • The Design of Everyday Things:交互设计领域的另一本经典之作,它通过解读人类行动背后的心理活动,展示了设计问题的根源,并给出了一系列方法用以解决设计问题(需要注意,尽管这本书有中译版,但中译版对应的是02年的旧版,而非13年的新版);
  • The Inmates Are Running the AsylumAlan Cooper的另一本经典,这本书非常辛辣的指出让不具备人机交互知识的程序员直接编写面向用户的软件就像让精神病人管理疯人院(The Inmates Are Running the Asylum),然后给出了一套交互设计流程以挽救这个局面;
  • 简约至上:交互式设计四策略:专注于把产品变的更加简单易用。作者通过删除,组织,隐藏,和转移这四个策略,展示了如何创造出简约优质的用户体验。

个人成长

1. 职业规划

软件开发者路线图

软件开发者路线图是一本优秀且实用的程序员职业规划手册。这本书由若干个模式组成,每个模式都对应于程序员职业生涯中的特定阶段。通过这本书,读者可以很方便的找到自己目前所处的模式(阶段),应该做什么,目标是什么,以及下一个模式(阶段)会是什么。如果你时常感到迷茫,那么请阅读这本路线图,找到自己的位置,确定接下来的方向。

延伸阅读:

  • 卡耐基全集:非常著名的为人处世书籍。很多人把这本书归类到成功学,但我并不这么认为——在我看来,这本书教的更多的是如何成为一个让大家喜欢的人。作为天天和机器打交道的程序员,这套书会帮助我们与人打交道;
  • 沃顿商学院最受欢迎的谈判课:这本书不是教你去谈判,而是教你通过谈判(Negotiation)去得到更多(Getting more,这也是这本书的原书书名)。小到买菜砍价,大到争取项目,这本书中的谈判原则会让你收益良多;
  • 程序员健康指南:作为长期与计算机打交道的职业,程序员往往会受到各式各样疾病的困扰,这本书正是为了解决这个问题而出现:它从改善工作环境,调整饮食结构,预防头痛眼痛,以及进行室内/室外锻炼等方面出发,给出了一套全面且可行的程序员健康改善计划,以帮助程序员打造健康的身体。

2. 思维方式

程序员的思维修炼:开发认知潜能的九堂课

作为程序员,我们需要不断地学习——既要学习新技术,也要学习如何解决各种领域的问题。为了提升学习效率,我们需要学习如何学习程序员的思维修炼正是这样一本讲如何学习的书,它集合了认知科学,神经学,以及行为理论的最新研究成果,并系统的介绍了大脑的工作机制。通过这本书,你将学会如何高效的使用自己的大脑,从而提高思考能力,改善学习效率。

如何把事情做到最好

Mastery is not about perfection. It’s about a process, a journey. The master is the one who stays on the path day after day, year after year. The master is the one who is willing to try, and fail, and try again, for as long as he or she lives.

为什么同样资质的人,大多数人会碌碌无为,而只有极少数能做到登峰造极?如何在领域内做到顶尖?如何克服通往顶尖之路上的重重险阻?如何把事情做到最好回答了这些问题,并极具哲理的指出登峰造极并不是结果,而是一段永不停止的旅程。阅读这本书不会让你立刻脱胎换骨,但它会指引你走向正确的道路——通往登峰造极之路。

延伸阅读:

  • 怎样解题:数学思维的新方法:不要被标题中的“数学思维”吓到,它并不仅仅只是一本数学解题书,它所提出的四步解题法(理解题目->拟定方案->执行计划->总结反思)适用于任何领域;
  • 暗时间刘未鹏所写的关于学习思维方法的文章集,既包含了他对学习方法的思考,也包含了大量进一步阅读的资源;
  • 批判性思维:带你走出思维的误区:这本书系统的分析了人类思维的常见误区,并针对各个误区给出了解决方案,从而帮助程序员养成严谨正确的思考方式;
  • Conceptual Blockbusting: A Guide to Better Ideas:与批判性思维相反,这本书专注于创造性思维(Creative Thinking),它分析了阻碍创造性思维的常见思维障碍(Blockbuster)以及这些思维障碍背后的成因,并给出了各种方法以破除这些障碍。

3. 求职面试

金领简历:敲开苹果微软谷歌的大门

知己知彼,百战不殆。金领简历:敲开苹果微软谷歌的大门是程序员求职的必读书籍,它覆盖了程序员求职的方方面面:从开始准备到编写简历,从技术面试到薪酬谈判。由于该书作者曾在Google,微软,和苹果任职并进行过技术招聘,因此这本书的内容非常实用。

顺便吐个槽:这本书翻译的还不错,但我实在无法理解封面上的“进入顶级科技公司的葵花宝典”这段文字——找个工作而已,用不着切JJ这么凶残吧。-_–#

程序员面试金典(第5版)

同样是来自金领简历作者的作品,程序员面试金典(第5版)专注于技术面试题,它既包含了IT企业(诸如微软,Google,和苹果)的面试流程以及如何准备技术面试,也包含了大量(超过200道)常见技术面试题题目以及解题思路。无论你打算进入国内企业还是外企,你都应该把这本书的题目练一遍,以找到技术面试的感觉(我在求职时就曾经专门搞了一块白板,然后每二十分钟一道题的练习,效果很不错)。

延伸阅读:

  • 编程之美:微软技术面试心得:恐怕是国内技术面试第一书,这本书里面的多数题目都曾经是国内IT企业面试的必问题目。这本书的缺点是它太旧而且被用滥了(以至于一些企业开始避免使用这本书上的题目)——但你可以把它当成一本算法趣题来读;
  • 剑指Offer:名企面试官精讲典型编程题:相对于东拼西凑的XX面试宝典,剑指Offer是一本少见的国产精品技术面试书籍,尽管这本书的技术面试题目不多(60余道),但作者为大多数题目都给出了不同方式的解法,并分析了这些解法之间的优劣,此外作者还以面试官的视角分析了技术面试的各个环节,从而帮助读者把握技术面试;
  • 人人都有好工作:IT行业求职面试必读:可以把它看做金领简历的补充阅读——这本书的特点在于它给出了非常详细的简历/求职信/电子邮件编写技巧,而这正是不少国内程序员所缺乏的。

4. 英语写作

The Only Grammar Book You'll Ever Need

词汇量决定阅读能力,语法决定写作能力。计算机专业词汇并不多,但精确性非常重要,因此每个程序员都应具备良好的英语语法,但程序员并不需要过于专业的英语语法——掌握常用语法并把它用对就可以。The Only Grammar Book You’ll Ever Need正好可以满足这个需求,尽管它篇幅不大(不足200页),却覆盖了英语中的关键语法以及常见错误。把这本书读两遍,它会大幅度提高你的英语写作能力。

风格的要素

既是最畅销的英语写作书籍,也是计算机书籍中引用最多的非计算机书籍。风格的要素用极其简练的语言讲述了如何进行严肃精确清楚的英语写作。从这本书中,你不仅可以学到英语写作,更可以学到一种严谨至简的处事态度,而这正是专业开发所必需的。

延伸阅读:

  • 牛津英语用法指南(第3版):全面且权威的英语用法指南,它覆盖语法,词汇,发音,以及修辞等方面,并兼顾口语和书面语,以帮助读者掌握合理的英语用法(Proper English Usage)。不要被这本书的篇幅(1000多页)吓到——原书并没有这么厚,因为这本书被翻译成中文但又得保留原有的英文内容,所以它的篇幅几乎翻了一倍。考虑到这本书使用的词汇都很基础,所以我认为具有英语基础的读者直接阅读原版(Practical English Usage)会更合适;
  • 写作法宝:非虚构写作指南(30周年纪念版):详尽的非虚构(Non-Fiction)写作指南,无论你要写地方,技术,商务,运动,艺术,还是自传,你都可以从这本书中找到珍贵的建议;
  • 中式英语之鉴:中国人使用英语最大的问题就是会把中式思维掺杂其中,从而形成啰里啰嗦不伦不类的中式英语(Chinglish)。中式英语之鉴系统的探讨了中式英语以及其成因,然后根据成因对中式英语进行归类,并对每个类别给出了大量的实际案例以及修改建议。如果你想摆脱中式英语,那么这本书是绝好的起点。

如何使用这个书单

学而不思则罔,思而不学则殆。

不愤不启,不悱不发。举一隅不以三隅反,则不复也。

不闻不若闻之,闻之不若见之,见之不若知之,知之不若行之,学至于行之而止矣。

来自他人的书单

它山之石,可以攻玉。我在本文最后给出其他中外优秀程序员的书单,以便参考&补充。

刘未鹏(暗时间作者)

以下同一条目下用“/”隔开的表示任选,当然也可以都读。

  1. 编码:隐匿在计算机软硬件背后的语言
  2. 深入理解计算机系统 / Windows核心编程 / 程序员的自我修养
  3. 代码大全 / 程序员修炼之道
  4. 编程珠玑 / 算法概论 / 算法设计 / 编程之美
  5. C程序设计语言
  6. C++程序设计语言 / C++程序设计原理与实践 / Accelerated C++
  7. 计算机程序的构造与解释
  8. 代码整洁之道 / 实现模式
  9. 设计模式 / 敏捷软件开发(原则模式与实践)
  10. 重构

云风(中国游戏编程先行者,前网易游戏部门资深程序员,简悦创始人)

  1. C++编程思想
  2. Effective C++
  3. 深度探索C++对象模型
  4. C++语言的设计与演化
  5. C专家编程
  6. C陷阱与缺陷
  7. C语言接口与实现
  8. Lua程序设计
  9. 链接器和加载器
  10. COM本质论
  11. Windows核心编程
  12. 深入解析Windows操作系统
  13. 程序员修炼之道
  14. 代码大全
  15. UNIX编程艺术
  16. 设计模式
  17. 代码优化:有效使用内存
  18. 深入理解计算机系统
  19. 深入理解LINUX内核
  20. TCP/IP详解

洪强宁(豆瓣技术总监)

  1. 代码大全
  2. 人月神话
  3. 编码:隐匿在计算机软硬件背后的语言
  4. 计算机程序设计艺术
  5. 程序员修炼之道
  6. 设计模式
  7. 计算机程序的构造与解释
  8. 重构
  9. C程序设计语言
  10. 算法导论

陈皓(CoolShell博主)

  1. 点石成金:访客至上的Web和移动可用性设计秘笈
  2. 重来:更为简单有效的商业思维
  3. 黑客与画家
  4. 清醒思考的艺术
  5. TCP/IP详解
  6. UNIX环境高级编程
  7. UNIX网络编程

张峥(微软亚洲研究院副院长)

  1. 算法概论
  2. Data Structure and Algorithms
  3. C程序设计语言
  4. UNIX操作系统设计
  5. 编译原理
  6. 计算机体系结构:量化研究方法
  7. 当下的幸福
  8. 异类:不一样的成功启示录

Jeff Atwood(Stackoverflow联合创始人)

  1. 代码大全
  2. 人月神话
  3. 点石成金:访客至上的Web和移动可用性设计秘笈
  4. 快速软件开发
  5. 人件
  6. The Design of Everyday Things
  7. 交互设计精髓
  8. The Inmates Are Running the Asylum
  9. GUI设计禁忌 2.0
  10. 编程珠玑
  11. 程序员修炼之道
  12. 精通正则表达式

Joel Spolsky(Stackoverflow联合创始人)

软件项目管理

  1. 人件
  2. 人月神话
  3. 快速软件开发

编程技艺

  1. 代码大全
  2. 程序员修炼之道

编程哲学

  1. 禅与摩托车维修艺术
  2. 哥德尔、艾舍尔、巴赫:集异璧之大成
  3. 建筑模式语言

界面设计

  1. 点石成金:访客至上的Web和移动可用性设计秘笈
  2. 交互设计精髓
  3. The Design of Everyday Things

资本运作

  1. 漫步华尔街

图形设计

  1. 写给大家看的设计书

思维方式

  1. 影响力
  2. Helplessness On Depression, Development and Death

编程入门

  1. 编码:隐匿在计算机软硬件背后的语言
  2. C程序设计语言

DHH(Ruby on Rails创始人)

  1. Smalltalk Best Practice Patterns
  2. 重构
  3. 企业应用架构模式
  4. 领域驱动设计
  5. 你的灯亮着吗?发现问题的真正所在

参考

  1. 怎样花两年时间去面试一个人
  2. What is the single most influential book every programmer should read?
  3. Recommended Reading for Developers
  4. Book Reviews — Joel Spolsky
  5. The five programming books that meant most to me

 

 

作者:Lucida

原文链接:http://lucida.me/blog/developer-reading-list/

一个程序员的顿悟:这6点带来的差距真的不是一点点

来自:建造者说
链接:
http://guoze.me/2015/03/02/excellent-programmer/
作者:微博:@GavinBuildSomething

我算是靠坑蒙拐骗进了程序员的门,然后一路狂奔。26岁之前几乎没有任何写代码的经验,研究生毕业却意外选择了一家不可能提供培训的初创公司,在每日担忧公司倒闭、害怕被炒鱿鱼以及同事冷落白眼的三重压力下逆流而上,一年半后离职,已是拥有500万用户产品的后台主程。从前我对计算机技术心怀畏惧,认定技术高人一定有佛光笼罩,昼夜不息运键如飞日吐代码上万行。现在也算见过一些世面了,回首那段忐忑不安宛如初夜的过程,我却不发觉有任何的励志意味,而是视为一种理所当然。理想的程序员,和理想的建筑师、理想的财务师、理想的按摩师没有任何的差别,他们本质上都是一群手艺人。我相信理想的程序员人人皆可成为。

近三年总在互联网圈厮混,我认识过一些程序员,共事过一些程序员,领导过一些程序员,又面试过一些程序员。他们学历不同,有的来自北大,有的来自培训机构,有的是博士,有的是高中肄业;资历也不同,有的来自BAT,有的来自某破产基金公司(还是一个销售);年限也从 0 到 15年不等。但我认为程序员只需分三类:天才的程序员、理想的程序员、平庸的程序员。天才的程序员我只敢说接触过 3 个,这是天命。7分由你是颗精子的时候就已决定,拥有绝佳的数学天赋、冷静致密的逻辑、为解决难题宁愿不眠不休而深以为乐的技术热情;3分来自起步要早早早,恨不得同龄人玩泥巴的时候就得开始玩电脑,大学毕业前就突破一万小时法则,后面的已是游戏人生。

天才的程序员可遇不可求,更不能长有,我看到的90%仍是平庸的程序员。IT时代的膨胀,已让程序员如同文艺复兴时的印刷匠一样的普通,多数投入祖师爷门下的人,仅是为了更大的饭碗,更高的待遇,更好的生计。平庸的程序员编写腐烂的代码,没有规范和一致性,固守旧世界的语言,还好谈论大的架构和性能,说的比做的漂亮。而毫无例外的,他们认定技术没有出路,做产品、营销和管理的是更高大上的手艺,而他们当中的99%,又会自然的流露出自己恰巧具备了那方面的天赋,至于进程为什么会崩溃这样的小问题是不屑于去了解的。

而我最喜欢和理想的程序员相处,恨不得与他们同吃同住,如果允许,我希望我的队伍能插满他们的旗帜。理想的程序员心眼儿不坏(他们从来都不是办公室政治的宠儿,是一群单纯明亮快乐的手艺人),有天真烂漫的好奇心(他们的眼睛里经常闪着 「哇,这个是怎么做到的!」),永远精益求精(他们的口头禅是「我再研究一下」),还乐于分享(他们活跃于GitHub、各大问答社区和你的身边,舍得将 宝贵时间用于帮助新手)。是的,他们不需要被管理,只需要给一个大的方向,总能回报以意想不到的结果。

理想的程序员与平庸的程序员只有一墙之隔。两者的差距只有 6个一点点,而人与人的差距,正是在这日积月累的一点点中,被永远拉开了。有意思的是,我发现这 6个一点点都和意识有关,也就是程序员和其他一切新兴产业的工种一样,只需要意识加上时间的锤炼,人人皆可达到理想的阶段。理想的程序员必然也是一个优秀的problem-solver。

第1个一点点:专注眼下

见过太多心猿意马的程序员,我不得不把「专注眼下」作为天字第一条。他们往往有各式各样的小梦想,比如做个小茶农、做个小鹅贩、做产品、做销售、做投 资,却被程序员的高薪或是没有转行的魄力「耽误」了,而因为不专注,他们不在意做好自己的本分,不在意锤炼自己的技能,不在意学习新兴的技术。不可否认, 这世界上存在着伟大的产品(像乔老爷)、伟大的销售(像埃里森)、伟大的投资客(像彼得菲),而他们毫无例外都是程序员出身。可你听说过巴菲特评价盖茨的 话么,比尔盖茨如果转行去卖狗,那他一定是全世界最大的狗贩。我坚信除了少数的天才外,冥冥众生均可以在多个领域取得成功,只要保持足够的专注。而哪怕你 下一年就想卖狗去,程序员的经验仍然能训练你强大的逻辑、谨慎和耐心,放在哪个行业都是相当可观的竞争力。

第2个一点点:思考力与推动力

我认为处理bug、崩溃、调优、入侵等突发事件比编程本身更能体现平庸程序员与理想程序员的差距。当面对一个未知的问题时,如何定位复杂条件下的核心问 题、如何抽丝剥茧地分析问题的潜在原因、如何排除干扰还原一个最小的可验证场景、如何抓住关键数据验证自己的猜测与实验,都是体现程序员思考力的最好场 景。是的,在衡量理想程序员的标准上,思考力比经验更加重要。

有时候小伙伴跑过来,问我「提交了一个任务被卡住了,怎么办」的时候,我总觉得他可以做得更好。比如,可以检查试验别的任务,以排除代码自身的原因;可以通过 Web UI 检查异常(如果没有账号,可以让我提供);可以排查主机日志或删除缓存,再不济,总应该提供任务 ID和控制台日志给我。理想的程序员永远不会等事情前进,他们会用尽一切方法让事情前进。

第3个一点点:Never Say No

记得从前厂离职之前,找老板谈话,他说我最大的优点就是从来不和他说这个做不到。后来我发现在很多团队里,都存在一种技术和产品的对立,程序员往往以 「技术上无法实现」来挡产品的需求,而产品也往往以「Facebook可以为什么我们做不到」来奚落程序员。这两句话应该属于禁语,从根本上都不利于程序 猿和产品狗的相亲相爱。

一句「技术上无法实现」是容易出口,可有多少人在说出这句话的时候,心里是100% 肯定的?如果不肯定,为什么不能回去谷歌一下再回答?原本我以为程序员是充满想象力,在因为有想象力,才能诞生那么多改变我们生活的软件和互联网产品。见 识多了,才了解大部分程序员已经在与bug的对抗中变得保守而不愿担当风险,与此同时许多团队也不愿意宽容失败。于是「Say No」变成一种习惯性的抵触,还记得曾国藩为什么解散湘军么?他说那支军队已「暮气渐深」,不能打仗了。要做理想的程序员,就不能给自己滋生暮气的机会, 如果面对不合理的需求,可以把时间成本摆出来,把曲线救国方案亮出来,简单粗暴「Say No」是不可取的。

第4个一点点:投资未来

程序员是一个非常残忍的职业。你所学所用的语言、框架、模式,很可能在数年内就成昨日黄花了;你现在嘲笑的另一群程序员,可能马上就能转身来嘲笑你了。 所以理想的程序员除了做好自己的本分,还要花费时间来投资未来。什么是「投资」?投资就是你现在投入的时间,在未来会以更多的时间或者金钱(看看早几年学 习iOS的程序员现在的薪酬!)回报你。举我自己的领域 — 数据挖掘为例,08年左右Hadoop开始兴起,一时「大数据」概念火热,Hadoop工程师万金难求,各互联网公司纷纷把数据统计、数据分析和数据 挖掘的业务切换到分布式平台上。这几年眼看 Hadoop 还在不断迭代,Spark又异军突起,一举刷新了 Hadoop 保持的排序记录,以内存存储中间数据带来的性能优势和丰富的数据结构让人爱个不停,各种奇异的小 bug和陡峭的学习曲线又让人打退堂鼓。那么,明眼人都知道 Spark 是未来的趋势(内存会越来越便宜),在主业务放在 Hadoop的条件下,就可以适当把一些小模块切换到 Spark 上,同时留意 Spark 社区的发展。很快从 Spark 获得的性能收益就能把之前投入的学习时间挣回来。

第 5 个一点点:善用工具

善用工具可以分为4个层面:

  • 搜索引擎
  • 不相信重复
  • 代码片段
  • 自动化

我刚入行那会,一个计算机专业却当了公务员的朋友问我,你一点都没学过编程,平时怎么 写代码?我说,谷歌,于是遭到无情的耻笑,以至于我在哪里的账号都叫2shou,告诫自己是一个无耻的二手程序员。这是一个笑话,但如果现在问我,我还是 要回答谷歌。程序员的成长就像膨胀的圆饼,外面是无边无际的大海,圆饼越大,与大海接触的面也越大,懂的越多,不懂的越多,而计算机科学又是一门更新换代 异常迅速的学科,同时也是知识互联网化最好的学科,很难利用传统的科班式有教有学的方法,相反通过搜索引擎则很容易获取到最新的知识。

不相信重复,大师的话叫DRY原则(Dont repeat yourself),代码写多了,会有人为的直觉判断好的和烂的代码,我的标准是简洁和规范,简洁并不是美感上的标准,重复越少,给自己出错的机会也越少,后期维护的成本也越少。

如果你不幸丢了三周前的代码,也许你能凭着过人的记忆力把脑子里残余的片段复写出 来,但如果丢的是三个月前的代码,恐怕就没有那么好的运气了。理想的程序员会着力找寻有效的资料保存方式,把工作里灵光闪现写下的代码、脚本、配置、 经验等短的片段保存起来,以便任何时候都能复查。

理想的程序员必须懒惰。对他们来说,重复的步骤和重复的代码一样丑陋,如果意识到一项工作有可能长期要重复,那么自动化的时间总是越早越好。

第6个一点点:管理时间

之所以管理时间会对程序员这个行当特别重要,是因为在完成任务时你必须像荒野里的狼一样,「独行」。没有外界约束的情况下还能稳定控制自己,保证能高效率地工作和学习,那么日积月累你肯定会变得比一般人厉害。

程序员干的是高强度的脑力活,一般每天集中4-5 个小时应对本职工作就足够了,但工作之外,一定要安排时间用于学习。除了学习,留点时间放空自己也是必要的,利用泡茶或者喝咖啡的间隙,把弥足珍贵的时间留给自己,往前想往后想,事半功倍。

说了这么多,想必有人会问,费劲心思成为一个理想的程序员,又有什么用处?会有高薪吗?不。能升职吗?也不见得。迎娶白富美呢?不如去卖狗。

稻盛和夫曾经说过一个故事,明治时期的手艺人被天皇召见,虽然都是不读书的乡下人,但一辈子兢兢业业地做一件事情,自然有一股高贵的气质。理想的程序员,应该就是循着这种高贵的气质而去的吧。

CMU大师对软件工程师的系统建议

2016-04-16 新智元 新智元

 新智元翻译1

来源:Quora

【新智元导读】软件工程师想学机器学习,有什么好建议?机器学习专家、卡耐基梅隆大学教授、1-Page公司首席科学家 Alex Smola 在 Quora 上给出了系统、具体的回答,还列出了推荐图书和论文。当然,如果你认为还有其他值得推荐的内容,留下评论,欢迎补充!

 

问题:你对想要学习机器学习的软件工程师有哪些建议?(What would be your advice to a software engineer who wants to learn machine learning?)

Alex Smola: 这 很大程度上取决于软件工程师的背景及其具体想掌握机器学习的哪部分知识。简而言之,我们以一名拥有四年本科学位和一到两年行业经验的初级程序员为例,并假 设这位程序员希望学习计算广告学、自然语言处理、图像分析、社交网络以及搜索和排序。那么,我们先说掌握机器学习有哪些基本要求(致学术界同仁的免责声 明:下列内容并不完整,如果未列入你的论著,在此提前致歉)。

线性代数

机器学习以及数据统计和优化都需要这方面知识。这也是为什么GPU(图形处理器)远比CPU(中央处理器)适合进行机器学习。作为程序员,至少需要基本掌握以下内容:

  • 标量、向量、矩阵、张量
    把它们看作你可以组建并相互转换的零维、一维、二维、三维和更高维物体,有点像乐高玩具,它们使得基本的数据转换成为可能。
  • 特征向量、范数、矩阵近似、分解
    这些概念本质上是让你习惯线性代数的用法。如果你希望分析一个矩阵的情况(比如,检查为何循环神经网络中出现梯度消失,为何增强学习算法中控制器出现分歧(diverge)),你就必须要理解在应用矩阵和向量时可能出现的增长和减小范围是多少。如果你希望代码表现出色和稳定,那么低秩等矩阵近似算法或乔列斯基分解就很有用。
  • 数值线性代数

    如果你需要做很多最优化计算,那么这部分知识就很有用。对核方法和深度学习来说如此,对图像模型和采样器而言则不那么重要。

最优化(和基本演算)

在许多情况下,设置要问的问题是相当容易的,但得出答案却没没那么简单。举例来说,如果要对一些数据进行线性回归(即找到一条线),你可能希望尽量减少与观测值的距离平方的总和。同样,如果想获得一个好的点击率预测模型,你就得最大化对于人们点击广告概率预测的准确性。这意味着我们通常会有一些目标、一些参数和大量数据,而我们需要通过一种方式来解决问题。这一点很重要,尤其因为我们常常不会有一个闭合式解决方案。

凸优化

很多时候,在优化问题不存在许多局部解决方案的情况下是不错的。当问题为凸时就会发生这种情况。(若你能在一个集合内任意两点间画出一条直线且这条直线处于该集合内,则这一集合就是凸的。若你能在图上任意两点间画出一条直线且这条直线位于图形上方,则这一函数是凸的。)

也许这一领域的经典书籍是这本由Steven Boyd和Lieven Vandenberghe所撰写的 Convex Optimization 。本书免费且非常棒。(回复041501下载,共730页)此外,Boyd的课程里也有许多很不错的幻灯片集。Dimitri Bertsekas也已经编写了关于最优化、控制等的宝典。这些应该足以供任何人开始了解这个领域了。

随机梯度下降算法

这一算法早期在很大程度上只是凸优化的一种特殊情况(至少早期定理是这样的),但最近发展很大,并且绝非是由于数据的增多。原因是,想象一下你有一些数据要处理,而你的算法需要将所有的数据都浏览一遍后才能继续新的步骤。而如果我故意给你10份同样的数据,那么你就必须重复10次工作,却没有什么实质性用处。显然,现实情况不会如此糟糕,但如果你需要操作多次小的新步骤,而每个小步骤之后都需要观测,它就能帮上忙。这在机器学习领域带来了相当大的变革型影响。此外,许多关联算法都容易得多。

我们面临的挑战是如何将其并行化。也许这个方向的第一步之一就是我们2009年的 Slow Learners are Fast 论文(回复041502下载)。最新版本是无锁变异型,例如Niu等于2013年所著的Hogwild论文(回复041503下载)。简而言之,这些算法通过人工计算机计算局部梯度并以异步方式更新共识参数集来运作。

另一个挑战是如何应对控制过度拟合的各种方法,例如通过正则化来实现。对于凸罚函数来说,有一种所谓近端梯度算法。一种比较流行的选择是Amir Beck和Marc Teboulle的FISTA算法。部分代码参见Francis Bach的SPAM toolbox(http://spams-devel.gforge.inria.fr/)。

非凸方法

许多机器学习问题都是非凸问题。从本质上来说,任何与深度学习相关的问题都是。但聚类、主题模型和几乎任何潜变量方法和当前几乎所有在机器学习领域有意思的问题也都是。部分加速技术可以提供帮助。例如,我的学生 Sashank Reddy最近展示了在这种情况下如何获得收敛的良好比率。

有许多被称为谱方法的技术可以使用。 Anima Anandkumar在她最近的Quora session中已经非常详尽地回答了这一问题。请参阅她的回复,因为其回复无比详细(https://www.quora.com/profile/Anima-Anandkumar-1)。概括地说,凸问题并非唯一能够确切解决的问题。在某些情况下,可以得出一个难题的数学表达式以显示只有某一组特定的参数能找到所有的集群、主题、相关比例、神经元或所有数据中的任何东西。这仅在你有能力且愿意花很多数学的功夫时才有效。

在培训深层网络方面(Deep Networks),最近有许多新技巧。我会在后面的内容中提及这些,但在某些情况下,目标不仅仅是优化,而是制定出一套具体的解决方案(几乎像是那本题为The Journey is the goal《旅程即是目的》的书)。

系统

机器学习正在成为大部分有关于人、测量、传感器和数据的关键要素,这与过去十年标度算法(scaling algorithms)的突破密不可分。Jeff Dean去年出了六套机器学习教程,也并非偶然。如果有人过了十年与世隔绝的生活,在这里给补充一下,他就是MapReduce、谷歌文件系统、BigTable和其他十多项成就了谷歌的关键技术背后的男人。

说笑归说笑,关于系统的研究为解决分布、异步、容错、可扩展和简易问题提供了宝贵的工具。后者是机器学习研究人员常常忽视的一点。简易是一种特性,不是一个错误。一些基本的技巧将带给你很多:

分布式哈希表

这实质上是如分布式缓存(memcached)、dynamo、 pastry和orceph等方法

构建的基础。它们都解决同一个问题——如何在避免访问之前数据输往的中央储存库的情况下向多台机器发布数据。为了达到这一目的,你需要将地址以一种随机又确定的方式编码(也就是哈希)。此外,你需要解决如果任何一台机器出现故障时谁将负责处理。

这就是我们在参数服务器(Parameter Server)中使用的数据布局。我的学生李沐是这个项目背后的智囊。工具组合参见DMLC(http://dmlc.ml/)。

一致性和信息传送

所有这一切的教父是Leslie Lamport的PAXOS 协议。它解决了在不是所有机器任何时候都可用或有些机器出现故障时如何达成共识的问题(是的,我在这儿就一句带过了)。如果你曾经使用过版本控制,你可能靠直觉知道它是如何工作的——大量机器(或开发者)产生更新(或代码段),而你希望将这些都结合成有意义的信息(例如,你不该两次运用微分),但又不需要所有机器与其他所有机器一直传递着信息。

在系统中,解决方案是使用向量时钟(参见例子:谷歌的Chubby)。我们在参数服务器中使用它的一种变体。关键的区别在于(均引自李沐)在参数范围内使用向量时钟。这可以确保不会因为时间标识耗尽内存,就像一个文件系统并不需要为每一个字节都记录一个时间标识。

容错、Scaling和云


最简单的自学方法就是在亚马逊AWS、谷歌GWC、微软Azure, 或你可以找到的各个其他平台上运行算法。当你第一次启动1000个服务器,意识到你正在向一个实际上的合法僵尸网络发送大量指令时,还是很令人激动的。我在谷歌工作时,我们控制了欧洲某处了5000个高端机器,用于主题模型中的推理。我们所调用的能源价值如果和一个核电站相比,也要占很大的比重了。我的经理当时把我叫到一旁,说这真是个昂贵的实验……

或许最容易起步的是学习docker。为了让scaling更容易,人们热火朝天地开发了不少工具。Docker Machine和Docker Cloud或许是近来最好的新工具,使你能像更换打印机驱动一样方便地连接不同的云端。

硬件


这似乎显而易见,但如果你了解自己算法所运行的硬件,的确会很有帮助。这会让你知道你写的代码是否已经接近峰值性能。初学者可以阅读Jeff Dean的Numbers every engineer should know一书。我在面试时最喜欢问的问题(曾经)是,应聘者的电脑有多快。知道算法的局限大有裨益:是缓存、内存带宽、延迟时间还是硬盘等等。Anandtech上有非常棒的介绍性文章,以及对微处理器架构等相关内容的测评。只要英特尔、ARM、AMD发布新硬件时,都可以去看一看。

统计学


我特意把这点留到最后。因为每个人都知道这是关键(的确如此),然后就忽略了其他所有东西。统计学确保你能问出好问题,同时帮助你理解自己在数据建模时用了多少估算。
从图像模型、核方法到深度学习等等,很多改进其实来自提出对的问题,也即定义了合理的优化目标,从而进行最优化。

Statistics Proper


Larry Wasserman的《统计学完全教程》(All of Statistics)是不错的入门教材。另外也可以看一下 David McKay 的 Machine Learning 一书。该书免费(篇幅很长、内容全面,回复041504下载)。其他还有不少好书,比如说 Kevin Murphy, Chris Bishop, Trevor Hastie, RobTibshirani 以及 Jerome Friedman 的著作The Elements of Statistical Learning:Data Mining, Inference, and Prediction。是的,Bernhard Scholkopf 和我也写了一本Learning with Kernels

随机算法和概率统计


本质上就是用计算机科学解决一样的问题,关键区别在于他们是设计算法的一种工具,而非用来适配参数的一个问题。我特别喜欢 Michael Mitzenmacher 和Eli Upfal 写的书Probability and Computing: Randomized Algorithms and Probabilistic Analysis ,非常易读但同时谈到了许多深刻的问题。如果你想更深入地了解这些工具,还有 Rajeev Motwani 和 Prabhakar Raghavan 的书Randomized Algorithms,写得很好,不过如果你没有较好的统计学背景,可能较难读懂。

我的回答可能已经够长了,很少有人会一直读到这里。所以我接下来说得比较简短。网上有许多非常棒的视频资料。许多教授现在有自己YouTube频道,并上传自己的课程视频。如果你在学习比较复杂的工具,这些视频会有所帮助。我的视频在这里(https://www.youtube.com/user/smolix/playlists),Nando de Freitas的要好很多。

 

其他还有一些工具。DMLC是好的起点,其中有许多用于分布式可扩展推理的算法,包括基于MXNET的神经网络。

 

还有很多没谈到的:编程语言、数据源等等。但这个回答已经太长了,我会在其他问题中继续讨论。

附录,Alex Smola 著书:

  • G. Bakir, T. Hofmann, B. Schölkopf, A.J. Smola, B. Taskar, and S.V.N. Vishwanathan, editors. Predicting Structured Data. MIT Press, Cambridge, MA, 2006.
  • S. Mendelson and A. J. Smola, editors. Machine Learning, Proceedings of the Summer School 2002, Australian National University, volume 2600 of Lecture Notes in Computer Science. Springer, 2003.
  • B. Schölkopf and A. J. Smola. Learning with Kernels. MIT Press, 2002.
  • B. Schölkopf, C. J. C. Burges, and A. J. Smola, editors. Advances in Kernel Methods–Support Vector Learning. MIT Press, Cambridge, MA, 1999.
  • A. J. Smola, P. L. Bartlett, B. Schölkopf, and D. Schuurmans, editors. Advances in Large Margin Classifiers. MIT Press, Cambridge, MA, 2000.

Slow Learners are Fast 论文(回复041502下载)。最新版本是无锁变异型,例如Niu等于2013年所著的Hogwild论文(回复041503下载)

关于这一讨论,你认为还有其他值得推荐的内容?留下评论,欢迎补充!

购书可扫二维码或点击 阅读原文 获取促销链接

How Many Programming Technologies Can You Really Master?

Andrew Wulf , Aug 6, 2015

I keep seeing companies or their recruiters advertising they are looking for people “with significant experience developing iOS and Android applications from scratch and will have a mastery of modern mobile and web technologies, including Java, HTML5, CSS3, JavaScript, JSON and AJAX”.

There is no such person. You can master one and be mediocre in the others; you can master one and then move on to another and forget a lot of the prior; you can simply fool enough people into thinking you can do it and hope you can figure it out just in time.

Programming today in any major area is highly complex, constantly changing, and generally done with a lot of time pressure. None of these allow you to devote a lot of non-programming time to learn even the most recent changes, much less master everything from scratch. You can really only learn a new environment by doing real projects, and how many people can simultaneously write large native Android, native iOS and responsive web clients all at the same time?

During my 34 years being a programmer I’ve only rarely worked in more than one major area. My first job was on a supermini and then 6502 assembly on Apple and Pascal on a PC, my two startups were for Mac in C, I worked some more for other people (including Apple) for Mac in C, a little C++ then Objective-C/WebObjects transitioning to web in Java on both client and server though only rarely both, some JavaScript, then C++ game programming on Mac and Windows and finally Objective-C and iOS. For each transition it was a lot of learning on the fly followed by years of mastering all the new stuff.

If for some reason someone can actually do both Android and iOS—much less web—at a real master level, they should be making way more money than most companies are willing to pay. What companies want is to hire few people who are then able to do everything and at the lowest pay level they can get. Yet I cannot fathom anyone being able to be an expert on so many things simultaneously and how they can write multiple apps in multiple technologies and keep up. I’ve known people who were incredibly brilliant but I can’t remember anyone being so good they could actually juggle unrelated technologies at the same time and produce masterful applications.

Maybe there are exceptions. But I still think most people can’t do it. People can of course master one thing then move on to master another but in the process you inevitably forget things from the first. Last year during my months of not having anything to do waiting for my layoff (I was one of the last layoffs for no apparent reason as all of our technology was already replaced prior to the final sale of the brand) I spent a month working on C++, then node.js and finally Swift. Going back to each this year (since all I had done in my new job was Objective-C) I found I had forgotten much of what I learned. If you don’t use something regularly the memories seem to fall out the back of your head. In rewriting this blog engine in PHP I got all those languages mixed up in my head.

Now if you are writing in Objective-C and then Swift on iOS at least there is some overlap. But Android is not just a different language from iOS, everything is different from the tools to how you do layouts to supporting multiple major OS releases to the 24,000 or so different devices. Just keeping up with all the new changes in this years WWDC in June is taking a lot of effort; not helping is that sample code Apple released then is already uncompilable in the latest XCode beta. Even if you wrote no code and just watched videos and read documentation and sample code all day, how could you say you are an expert with a straight face?

Add to two different mobile OS environments all the complex mess that is modern web development, especially with Javascript frameworks that appear one day and then vanish the next. You’d need three heads to keep up with it. The Javascript programmers I worked with couldn’t do more than keep up with one (in this case AngularJS).

So finding a single person who can write iOS, Android and mobile/desktop web in Javascript, using modern APIs and yet supporting older OS versions, understanding the plusses and minuses of different approaches to design and UI and the subtleties of all the different browsers and Android devices especially, and deliver bug-free results in record time, is fantasy. Oh yeah and work for less than market rates.

When I started programming things were extremely primitive and I only had to know one language and one OS and no frameworks at all. Even during my two startups I only had to master C, Inside Macintosh and some occasional 68K assembly. Today is not then. Yet we still only have one brain and brains aren’t subject to Moore’s Law. They can’t be upgraded.

So if you (honestly) can do Android, iOS and mobile web simultaneously and deliver masterful results, I salute you! But I sure hope you are making 3X money too.

创业不等于职业生涯加成

作者:余晟

微信公众号:余晟以为

 

最近面试了很多技术人员,其中不少之前的工作履历还不错。但是,因为他们之前的创业经历,我并不能发offer。

看到这里先别着急下结论,让我仔细说说理由。

这样的人员的经历比较类似:在大公司做过五六年,有了比较充分的工作经验和工作习惯,具有一定的管理能力——然后出去创业,过了不到一年,开始找工作。

刚开始我很好奇,为什么刚创业一年就找工作呢?答案几乎前篇一律:营销不行、产品不行。辛辛苦苦做了大半年,技术上的问题都解决了,可就是找不到用户。找不到用户就没有收入,没有收入就难以证明商业模式。加上如今风投行情渐冷,拿投资的难度高了很多,不得已,只能出来找工作,希望做回原来的角色。

于是我问起专业技术的问题,然后只能遗憾的发现,创业的经历对这些候选人来说并不能加分。虽然身处创业公司,他们的角色和之前大公司并没有太多差别:定技术架构、管技术团队、盯开发进度。对他们来说,这些任务已经像条件反射一样轻车熟路。于是,下面的问题也很难答上来:

  • 基于你们公司的具体情况,在选型和技术架构上有什么需要特别考虑的吗?
  • 你们在具体工作中有没有遇到之前没遇到的技术问题,这种问题是创业公司的通病吗?人家是怎么解决的?
  • 你觉得产品不好,营销不好,那么你觉得从产品和营销上可以做哪些改进?你和产品、营销的负责人谈过吗?

如果问这些问题得不到满意的回答,多半可以判断这段创业经历对候选人来说没什么特别,本质上是平移之前的工作经验和解决方案,虽说换了环境,做的还是同样的事情。既没有深入思考不同场景下的技术方案,也没有了解行业的情况,更没有展现出创业公司需要的所有者意识。这段经历给他们留下深刻印象的是:资源太少,工作太累,什么事都要自己做。

更加不幸的是,即便对专业技术,这段创业经历也没有太多的加分。做开发的还是做开发,充其量对不熟悉的领域有了一些了解,却因为忙碌而不够深入。而且因为行政管理上花了不少时间精力,对基础技术已经不再敏锐,与新技术、新思维也拉开不小的距离。

最终的局面就相当尴尬:创业经历对他们来说,技术上没有什么提升,业务上也没有什么提升,只是多了一些行政管理的经验而已。然而一旦离开创业公司,他们期望拿到更高的薪水,相当多的人有“我有创业经历”或者“补偿创业期间低薪损失”的想法;结果甚至无法保持自己创业之前的薪酬水平,因为这样的技能组合并不是非初创公司迫切需要的。对这样的职业生涯经历,我们只能称其为“失败”。

所以我通常还会问最后一个问题:“你当时为什么决定去创业呢?”

因为我想知道,是什么诱使这些候选人做出了职业生涯的重大牺牲。可惜的是,答案五花八门:想勇敢尝试的,想帮同学和熟人忙的,之前领导叫自己一起的,其他人给画了一张大饼…… 只有极少数人能回答“我想清楚了,我就想做这件事情”,这种答案是要加分的。

从公司的角度出发,我们很难和这样的候选人谈得拢;从行业同仁的角度出发,我想郑重告诉大家创业的风险很高,创业本身成功率就很低,更可能耽误自己的职业生涯发展,赔了夫人又折兵。根据我的经验,这里有几点建议给大家参考。

创业是风险极高的投入。媒体上渲染的成功者有几十几百,你看不到的失败者就有几万几十万。而且,那几十几百成功者的素质,未必强过失败的几万几十万。运气这回事,成功者不愿意承认,媒体不愿意总结,但又是任何创业者都必须面对的。所以在你决定投身创业之前,一定要做好直面运气、承认运气的准备。

投入创业最好以自己认同创业目标为前提。除非你已经有了相当的资本或者积累,否则“帮朋友忙”这类理由根本不足以支撑做出创业的决定。因为在创业过程中,身处绝境、走投无路乃是常事。如果没有对最终目标的坚定信念,半途而废是常见的结局。

创业是对人品和人性的严峻考验。不要以为这只是“能共患难不能同享福”那么简单,更不要天真地以为靠制度就可以保障自己“同享福”的权益。而且退一步说,很多时候大家还没到享福的阶段,就已经因为计较彼此对患难的承担“不公平”而分崩离析了。这种计较未必只源于他人,自己身处煎熬之中会是怎么表现,只有亲身经历了才知道,谁也不能预知。稍好一点的情况是,虽然度过了最艰苦的时期,大家没有撕破脸皮,内心却留下了抹不去的阴影,长期来看这种心理状况并不健康,自己生活也不会快乐。当然,如果你自己极度认同创业目标,或许能避免这种风险。

即便在创业公司也不应当忽略自己的职业生涯建设,避免出现“两头不沾”的悲剧。与上面提到的那些候选人不同,我见过一些经历过创业失败的人,他们或者掌握了跨领域和部门沟通协调、全面解决问题的经验,或者具备了从整个行业观察和思考的能力——总之,创业经历对他们来说是大大加分的,由专变能,具备了解决复杂任务的能力,这种机会在规范公司并不常见。结果即便创业不成功,他们再出去找工作,也可以得到比之前更好的职位和待遇。相反,如果忽略职业生涯建设,在创业公司事情做了不少,却只积累了一堆不相干的打杂经历,拿不出更有力的职业技能组合,又没有收到应有的回报,这是最大的悲剧。

身为普通技术人员,如果不具备产品、管理、营销等经验,在投身创业之前应当仔细读读与创业有关的书籍。即便它们不能保证你怎样能成功,起码能让你知道怎样做不会成功。“辛辛苦苦把产品做出来,却根本找不到用户”这样的悲剧,已经发生过很多次了,我们作为后人应当尽量早地发现,尽量早地避免。

当然,我不是希望给大家的创业激情泼冷水,我只希望大家在投身创业之前能仔细思考。尤其是在各项社会保障不健全,行业又高速发展的情况下,创业的风险可能被放大若干倍,作用到自己身上。所以,如果你只是“为创业而创业”的话,一定要谨记:创业不等于职业生涯加成。

 

内容转载自公众号

余晟以为
余晟以为

 

算法与算法工程师,技术与技术人员

作者:伯乐在线 – 水石头stone

网址:http://blog.jobbole.com/89500/

点击“阅读原文”,加入伯乐在线专栏作者

在和刘同学长谈之后,我再次对前一段时间的想法进行了反思,结合聊天中的新感受,整理在这里。

(注:标题里的算法,指机器学习算法,或者说“算法工程师”这个职位名称里的“算法”,不是“算法与数据结构”里的那个算法。谁能告诉我有没有什么更好的名字来区别这它们,或许是“机器学习算法”与“传统算法”?)

算法与算法工程师

先来一段我在知乎里回答“做算法工程师是一种怎样的体验?”的答案(其中的思想并非原创,而是山寨自新加坡某大学一门Quantitative Investment课程的ppt)

理想中的算法工程师:提出假设->收集数据->训练模型->解释结果。

实际中的算法工程师:提出假设->收集数据->预处理->预处理->训练模型->调试->调试->重新收集数据->预处理->收集更多数据->调试->调试->调试->…->放弃。

这个答案被点了几十个 zan,在24个答案中排在第二位,说明具有一定的普遍性。排名第一的有 100+ 顶,而他的观点是:每天最重要的就是跑数据!

这不是段子,而是事实。为什么“高大上”的算法工程师实际上是个数据民工,要寻找这种理想与现实的差距的原因,首先要理解一个事实:只有人能够理解数据,机器不能。

不管我们用什么机器学习算法——无论是LR,SVM,k-means,EM——对于它们来说,输入数据都是一堆浮点数组成的矩阵而以(如果说的更本质一点,只是一堆01序列)。如果有一个特征是“小时”,而它出现了25,任何一个智商正常的人类都能明白,这是一个错误,然后在数据清洗的时候把这样的数据排除。但是机器就无法理解这一点。要具备小时的概念,又要理解什么是时间,一天有多少个小时…机器怎么能自动化完成这样的数据清洗工作?更进一步,如果人发现“小时”这个特征中大部分数据是0到12,而混入少量13(但13的数量又不是太少以至不能被当成离群点排除),人就会怀疑,是不是使用了12小时制而13是一个错误。机器目前是无法做到这一点的。

再说人肉特征。一个是特征变换,比如需要一个特征是某两列数据的比率,这种除法是线性模型不能涵盖的。当然可以增大模型的假设空间,但是太小涵盖不了需要的变换,太大又容易过拟合。另一个是加特征,比如我认为点击率和屏幕分辨率有关系。于是我去找屏幕分辨率数据加入特征,如果没有还要想办法采集。这些机器都做不了。

但是,人一但把数据准备好,接下来就是机器学习算法发挥的时候了。但是,算法工程师的主要工作不在这里,这是因为软件有个特点,可以近乎无成本的复制。只要这个世界上有一个人实现了LR(知识产权的问题这里不考虑,更何况开源软件很多),其他需要用LR的人都可以拿过来用了。显然,这些算法工程师们也正是这么做的。

然而,等算法输出结果以后,又需要人的工作了——怎样用结果解释实际问题,应用到业务中去。显然这个过程和前面数据清洗、人肉特征的性质类似,都是只有人能完成,机器做不到的任务。

做过数学建模的同学对这个过程可能很熟悉——如何把一个问题描述成数学问题,再如何把结果应用到实际问题上。这有点类似于通信中的“最后一公里”问题,主干网的光纤建设的很强大,而最终用户的接入却成了一个麻烦事。对于机器学习的应用问题来说,算法和相应的软件包都是标准化、通用化的,像骨干网;而数据如何“接入”,则是只能由人完成。因为,只有人能够理解数据。

技术与技术人员

这个问题可以推广到整个计算机领域。把算法工程师代换成程序员,把机器学习算法代换成软件,这个观点就变成了:大部分程序员所解决的,是通用的计算机工具和具体的实际业务之间的“最后一公里”接入问题。

为什么这么说,我们先来看历史:计算机技术发展了几十年,程序员的入门门槛是逐步降低的。最初的程序,要在裸机上写汇编。后来有了unix,c语言,程序员至少不用亲自调度进程了。java出现之后,连内存都不用管了。而(世界上最伟大的)php出现之后,网络编程的门槛进一步降低,任何人都可以在短时间内搭建一个网站。

原来的那些问题去哪儿了呢?被少数造“”轮子的程序员们解决了——那些写操作系统、编译器、虚拟机、运行时环境、框架…等等的程序员们。这个趋势一直在持续——新兴的rust、golang等语言试图解决多核时代出现的并发问题,hadoop、spark、mesos试图屏蔽分布式系统底层的细节……可以预见,以后的并行编程和分布式编程门槛将会大大降低。这个过程是必然的,因为一项技术的发展,就是为了让更多的人能更方便的使用它。

而这些计算机工具不能直接应用于业务,因为计算机不能理解人类的语言,所以就有了大量的程度员存在,把人类的语言“翻译”成计算机语言。这些程序员是使用“轮子”的。当然这之间并不是非黑即白的,一个软件在多大程度上可以被称为轮子,取决于它的复用性。如果一段代码只能在一个地方使用,它显然不能称为轮子。而事实是,大部分为具体的业务逻辑所写的代码,复用程度很低。

对于把通用计算机工具应用到具体业务这个过程,中间到底有多少问题是技术性的?大部分技术困难被操作系统、编译器、虚拟机解决掉了,剩下的主要是大型软件(如果这是个大型软件)的复杂性控制——而这个问题又主要由少数高级别的架构师负责。对于写具体代码的程序员,剩下的技术性困难已经很少了。

举一个我供职过的公司,这是一家互联网公司,整个网站99%的代码是php,基本上没有java。没有专门的前端工程师,php、html和javascript代码混在一起。测试几乎等于没有,基本都是开发人员自测。上线流程只是个形式,质量控制部门唯二的作用就是向服务器上同步代码和出现事故之后给开发人员定责任。我曾经和另一个部门合作,他调用我提供的接口,而他在我的接口没上线的时候就上线了,导致一场事故。我本来是算法工程师,写php只是客串,而在这个过程中,没有任何上线依赖的控制,连提示也没有,甚至没有人对我进行上线流程的培训。然而,这是一家中等规模的互联网公司,己经发展了十来年,占据了所在细分市场领域的头号份额,并且己经上市。

我举这个例子并不是要黑它,而是想用事实支持上面的观点:大部分程序员,大部分所谓的“科技”公司,所面临的技术问题比想象的要少的多(这也许是那家公司没有CTO的原因)。

这不是个别情况,大多数公司都存在类似的问题——从技术角度看,它就是个渣,你会很奇怪它怎么还没死。然而事实是,它不但没死,反而活的生机勃勃,甚至上市了。公司的拥有者们早已实现了屌丝逆袭迎娶白富美的理想,而辱骂他们的程序员们还在苦苦的为房贷或者首付挣扎。这里面,有大量的非技术因素起着关键作用,尽管它们都自称科技公司。

越来越多的人意识到了技术的局限性。年初,一个同学找工作,他向来是个“纯技术流”的工程师,曾经写过很好的技术博客,甚至发起过开源项目。然而这次他说,“不想再做最底层的工程师了”,希望能做一些“高层的、能看到项目整体的”、以及“和人打交道,能够把自己的想法向外推动,并产生价值”的工作。于是,他去某公司负责带几个小弟去了。当我把这些转述给另一个同学的时候,他的反应是“我最近也有这样的想法”。还有个同学,说写了几年C++,技术上没学到多少,反而是接触的业务知识比较多。再比如我之前的leader,他是数学博士出身,曾经对算法有一种近乎天真的信仰;在我离职的时候,他已经完全转型为业务和产品导向了。而某个几年前就开始淡化技术,聚会时大讲“软实力”的同学,早已在BAT做了Team Leader,生活滋润,终日以跑步为乐。为何?其实原因很简单:公司里没有那么多技术问题需要解决。

《代码大全》里有个比喻,如果你的问题是给自己的爱犬造一个小窝,那么动手做就是了,如果出了什么错误,大不了重做一个,最多浪费一下午的时间。而造一个摩天大楼就不同了。所以,如果写一份“狗窝”级别的程序,算法、数据结构、设计模式这些又有多大意义呢?甚至违反了DRY原则也没关系,反正一段代码也拷贝不了几次,出了bug就改,大不了重写一次,最多浪费一下午。而且,说不定这个项目两周之后就被砍掉了。如果你做的是一份“造狗窝”的工作,就算你有造摩天大楼的技术,和屠龙之技又有什么分别呢?唯一的“好处”就是你会据此向老板提出更多的加薪要求,以至于老板对你“另眼相看”。

程序员应当破除对技术不切实际的幻想——这不是说技术不重要,而是说要实事求是的分清,哪些是造狗窝的工作,哪些是建普通楼房的工作,哪些是造摩天大楼的工作。

再谈算法

同理,算法工程师应当破除对算法不切实际的幻想,把注意力集中到数据的理解、清洗、预处理、人肉特征、业务应用(而这些往往和屌丝、苦逼等形容词联系在一起)上来。

未来,机器学习工具将更加标准化、平台化、通用化,并且进一步降低使用门槛。与算法本质无关的工程细节,比如数据存储方式、梯度下降过程、并行化、分布式计算等,将被制造“轮子”的程序员们屏蔽。算法工程师可能只需用类似Hive的方式,写几个类似SQL的语句就可以完成模型的训练、交叉验证、参数优化等工作。

而机器唯一不能替代的就是对数据的理解,这是算法工程师存在的价值。而数据是和业务强相关的,算法工程师将更加接近产品经理的角色,而不是程序员。深入理解数据、业务和产品,寻找模型和它们的结合点,将成为算法工程师的核心竞争力。

插一句,相对于本文的观点,Deep Learning在某种程度上是一种的例外。它试图解决特征工程的问题,也就是在某种程度上代替人提取特征。当然,它还比较初级,另外它最多只能解决特征变换问题,仍然处理不了数据清洗和预处理中需要用到领域知识的情况。

这里刘同学提出一个问题,那就是算法工程师对算法需要理解到何种程度?事实是,即使从算法的应用出发,工程师也需要掌握模型的优缺点、适用场景、模型选择、参数调优等技术。这是毫无疑问的,从这一点上说,算法工程师需要一定的技术能力,这点又和产品经理不同。

但是这就有另外一个问题:模型选择和参数调优技术,是否是通用的?还是和具体的数据高度相关的?比如,是否存在这样的现象,同样的调优技术,在(比如说)电商数据上表现很好,到了社交数据上就不行了?这个问题我暂时没有答案,如果谁知道,请告诉我。不过,一个现象是,目前做机器学习模型相关的项目,在改进的时候,基本上都采用试错的方式,就是先做出改动,然后上线观察效果;如果不好,就换种方法;如果效果有所改进,也往往没有人知道为什么。如果存在一种通用的判断模型优劣的技术,我们为什么还要采取这种近乎穷举的方式呢?

从“IT精英”到“IT民工”或者“码农”,这种称呼上的转变并非笑谈,而是真实的反应了计算机编程领域门槛逐步降低的过程。所以,我们应当给听上去高大上的“算法工程师”或者“数据科学家”起一个类似的外号,比如“数据民工”、“机农”或者“蒜农”之类,以免不明真相的孩子们被“高大上”的称号吸引而误入歧途。

其它

看的出我是一个比较纯粹的技术人员,因为对于非技术的东西,我了解不够,说不出那是什么,只能用“其它”一词概括。

这“其它”,基本上是“人”的问题——比如前面提到的“如何推动自己的想法”,“软实力”之类,大的包括机遇,小到“发邮件应该抄送给谁”这种细节。

当然,如果你是个对技术本身感兴趣的人,这些讨论不适用,因为对于这类人,技术本身就是目的,不是手段。这里的视角,仅仅是社会普遍意义上的职业发展角度。无论是想在公司内部获得升迁,还是通过跳槽而得到晋升,还是自行创业而实现人生目标,技术都只是你的一种技能。如果再想想大部分公司里提供的是一份“造狗窝”级别的职位,这种技能起的作用又有多大呢?

不过多说一句,要求程序员“对技术感兴趣”,甚至“在业余时间以写代码为消遣”,是一种相当荒谬的事情。试想,招聘销售人员的时候,从未有人要求求职者“对喝酒应酬感兴趣”;招聘财务人员的时候,也没有人要求“对加减数字感兴趣”;招聘外科医生的时候,也绝不会要求“平时以解剖人体为消遣”。为什么程序员这种职业就要搞特殊?

究其原因,大概是大家还沉浸在对技术的一种非理性崇拜之中(当然崇拜和亵渎往往并存)——“技术改变世界”这句话常常被提到。这句话没错,但是要搞清楚,“技术改变世界”不等于“每一项技术都能改变世界”,更不等于“每一个技术人员都能改变世界”。其实,程序员这一行和其它任何一个需要专业技能的行业没什么区别,只是一种谋生的手段而已。

大部分所谓的“科技公司”也并不是真正的科技公司,最多是“使用科技的公司”。其实,在金融领域,对IT的要求要高多了,各大银行也有自己的软件开发部门,但是没人把它们归到IT行业,而是属于金融行业。然而,那些开商店的,开饭店的,卖房子的,给人说媒的,集资的,他们似乎只要做个网站,就成了“科技公司”了,这难道不是很荒谬吗?(当然,像亚马逊这种从一个卖书的起家,居然后来搞起了云计算、推荐系统、无人飞行器等技术创新的,不在此列。)在这些公司当中,技术到底起多大作用呢?

也许相当一部分程序员们会自以为技术很重要,他们沉浸在对技术的憧憬和信仰中,内心深处坚定的相信自己可以通过技术能力的提升,来谋取更高的职位,走向人生巅峰。然而,大多数时候这只是一种自欺欺人的幻想罢了。天朝的程序员们有一种矛盾心态,一方面自称“民工”,认为编程是一种只适合30岁之前的年轻人从事的体力劳动,而另一方面却又把技术看的非常重要,甚至在业余时间也喜欢大谈技术,或者以攻击其他程序员使用的技术为乐。如此抱着技术不放,并不是因为多么热爱技术,而是因为他们只会技术。没有人愿意在别人面前展示自己的劣势。把技术的地位抬的越高,仿佛自己就显得越重要,而那些在需要人际交往、推动自己的想法、和产品经理讨论需求的时候所表现出的能力低下,似乎就不重要了。

这是人性的弱点——对自己某种能力盲目而过分的自信,甚至把它作为自己的精神支柱。也许他在这个方面的确很擅长,但是自我评估却比实际更高。诚然,自信是必要的,也是人生存和立足的精神基础之一。然而自信是把双刃剑——不切实际的自信(也许应该叫自大了),会蒙蔽人的双眼,扭曲事实。

那么我们应该怎么做呢?首先比较悲观的一点是,如果你从事着一份技术上处于“造狗窝”级别的工作,那么很遗憾,提高自己的技术水平恐怕对于在公司内部的职业发展没什么帮助。

如果你是一个真正对技术有兴趣的人,可以考虑一下《黑客与画家》里提到的一类“真正的程序员”的工作方式:他们求的一份“白天的工作”,这份工作仅仅用来生存,而在业余时间写一些“真正有价值”的代码。

恐怕大部分程序员都不是对技术有兴趣的吧?如果你的目标是事业上的发展,无非是跟人混和创业两种方式。跟人混,要么内部晋升,要么通过跳槽。前者需要老板认为你牛逼;后者需要别的公司的老板认为你牛逼。注意,这里有个关键词“认为”,因为人的主观印象和客观事实之间总是有差距的,而且这个差距往往超乎人的想象。所以重点是制造一种“牛逼”的印象,而实际上牛不牛逼并不重要,牛逼更好,不牛逼也可。

如果你想走技术路线,可以考虑去找一份“建造大楼”级别的工作,在那里,技术成为决定产品成败的主要因素。这种级别的项目,一般只有大公司做的起。老板对于员工技术能力的评估,还是比较容易做到客观的,因为代码在那里,牛不牛逼,一运行便知。但是对于所谓“软实力”,往往就不好评判了,主观性很大。

也正因如此,往往有很多人觉得自己很牛逼,而老板不这么认为(错的不一定是老板,也可能是这个人自大),所以一怒之下走上创业的道路。自己给自己当老板,终于不用在意老板的印象和事实之间的差距。然而这条路往往更为艰难,它对人的综合素质要求比较高。如果一个程序员在工作中不能和同事顺利的合作,那很难想象他能够满足创业者所需要的各种素质。所以,要走这条路,得有心理准备。

总结

技术是为人服务的,IT业的发展过程,是在逐步降低计算机的使用门槛,使得越来越多的人能够使用这种工具。这是好的,但它同时也降低了程序员这种职业的技术含量。如果真的想做技术,那么去做一些真正的技术。否则,就需要多多关注技术以外的东西,单纯寄希望于技术,只能用来安慰自己,而不能获得真正的职业发展。

你可以培养下一个乔布斯吗?

编者按:中西方文化和教育在很多方面大相径庭。海外的华人父母常常感概,不仅是孩子,自己也需要在文化适应方面作出大的努力。

如何培养孩子尊重规则又不失去创造和想象的动力,是很多父母面临的育儿难题。受幼年乔布斯故事的触动,一位旅美中国妈妈反思了对三个孩子的抚养,指出了传统教育中禁锢孩子潜在成长的相关问题。

文/ 李青原 (本公号创刊专栏作者) 三个充满了好奇心、能量无穷男孩的妈妈。 毕业于上海外国语大学,随后继续到美国深造。在北美金融投资业闯荡十五年后,终于在2014年决定辞去投资业工作,力争专心做个妈妈,且同时在寻找一份可寄予爱心和为社会做出更直接贡献的事业。


最近读了沃特·伊沙克森的乔布斯传,感触很深。苹果的创始人乔布斯是现代社会无可非议的创造力和应用想象力的代表。他不但将Pixer和苹果创建成为世界一流的公司,而且对个人电脑,动画,音乐,电话,平板电脑,电子发行六大行业做出前所未有的改革。

面对着书中那个桀骜不驯,藐视权威,玩世不恭的儿时的乔布斯,我不禁问自己:“如果我有一个这样的儿子,他是否能成为乔布斯?” 答案是,可能性很小。之所以这样想,是因为传统的教育模式和社会期望会让我把孩子的创造性和想象力给扼杀了。 换句话说,如果幸运的话,他也许会有一份不错的工作,但他很难成为像乔布斯一样的创新人物和社会进步的推动力量。

读到幼年的乔布斯的篇章,触动我反思自己的育儿方式以及东西方社会的教育理念。无论是中国还是西方的父母都可能碰到以下几个方面的问题和困惑。希望以此文,来展开对相关问题的讨论。

奖惩分明(关于奖励)?

大家常说,教育孩子应以奖励为主。当我们的孩子们做对了一道题,做好了一件事时,我们常会奖励他们,比如说一张粘纸,一颗星星,或者是加分。一旦他们做错了什么,我们就会严厉批评。奖励也就因此成为孩子做事的动力。

然而,现代心里科学研究却发现,频繁的奖励对孩子的创造力和情商有很大负面影响。 首先,奖励是外界刺激。一旦失去外界刺激,人的行为很可能又回到刺激以前的样子。关键是要理解孩子,激发他们内在动力,这样的结果才能长久稳定。第二,过多的奖励与创造力和冒险精神成反比。比如说,当他们知道一种解题方法能给他们带来频频奖励时,他们就不愿意冒险去尝试一个新的方法。第三,频频奖励会让孩子们计较得失,急于求成,养成了功利心。

成功的道路是漫长的,艰苦的,可能要经历无数次的失败。在奖励中成长起来的孩子,能有毅力和耐性承受住这样的寂寞与煎熬吗? 再者,有很多人为别人,为社会,默默无闻几十年如一日地做好事,做义工,而不求报酬。在奖励下培养出的、做任何事都可能有功力心的孩子,会有这样一颗无私心和博大的胸怀吗?

满满的时间表?

放学后,孩子要练钢琴,念中文,做补充作业,阅读和游泳。到了周末,他们的日程安排更紧张,做课外作业,参加球队训练,上中文课,上钢琴课,学跆拳道,上课外辅导班,学画画,学下棋….,我们没有为孩子们留下足够的时间以让他们自行去经历,观察,总结,幻想,去热爱并体验大自然。他们更没有时间投入到自己的爱好与特长中,做自己喜欢的事情。他们的大脑和身体都被紧紧地囚禁在我们家长制定的框架中。在这种环境下长大的孩子即使有乔布斯和比尔·盖茨的智商,也很难将自己的特长和爱好发扬光大,更别提有时间去钻研创造了。

敬畏师长?

我们总是要求孩子从小就要听话,要服从父母和师长,不能和长辈顶嘴,更不能说长辈是错的。我们到处找有关教育的书,目的之一就是能让我们的孩子听话。作为家长的我们也为有尊师守纪的孩子而欣慰,为不听话的孩子而焦虑。 我们最常用的批评孩子(特别是对男孩子的)的话就是:“你怎么那么不听话!”

有一次我对四岁的二儿子说他应听话,因为听话的孩子人人喜欢。他疑惑地问我:“Why? Mummy, how do you know what you said is correct? “ (孩子回问:妈咪,你怎么知道你说的就全对呢?) 我当时不知道该怎样回答。仔细一想,他反问的不无道理!我们大人说的每句话、做的每件事就都是对的吗?有时候我们觉得他们不听话时,他们其实并没有做错什么,他们只是做了我们大人不喜欢的或认为不妥当的事罢了。

教育孩子尊敬他人是非常重要的,但尊敬不等于畏惧, 不管那个人是何种权威。记得几年前我的公司招了十几个刚从研究生院毕业的硕博士,其中一半是中国学生。 这些年轻人大多来自牛津,伦敦商学院,哈佛,斯坦福等世界著名学府。 但是,很明显的是,相比中国学生的内敛和拘谨,外国的年轻人更加勇于向领导提出建议,指出问题,表达创新意见,甚至试图去影响他们的管理人员。同样交上去一份报告,外国年轻人敢于每天敦促老板给他回复,而中国学生却被动地等待反馈。

怕他们犯错误?

孩子们做作业的时候,特别是男孩子,总是不专心。 于是,我们一有空就坐在他们身边陪同,不停地敦促他们。一看见他们做得有错,遇到难题,就忍不住指出并帮助。他们在做其他任何事的时候,我们也都是尽可能地予以关注,一见到他们遇到困难,就忍不住帮他们一把,以免他们犯错误。

记得我父亲常常对我说:“我天天敦促你,就是为了你少走弯路,甚至不走弯路。”但我们都知道,不走弯路是不可能的。关键不是不让孩子在幼年时做错事,而是通过幼年时的种种小“错误”,让他们学会思考,分析,自己寻找解决的办法,懂得无论做什么事情都需要承担责任和后果。我们不能保证孩子今后在社会上、工作上,不走弯路,不犯错误;我们所能做的是,教给他们处理和解决问题的能力。这样他们在社会上才能少犯错误,少走弯路。即使犯了错,走了弯路,也能很快认识及时纠正。

帮他们做选择?

作为家长的我们经常不由自主地对孩子的事务包揽包管,小到每天穿什么,吃什么,作文该写什么;大到上什么样的学校,做什么样的工作,交什么样的朋友。这样长久以来我们的孩子就不仅失去了主动性,更形成了依赖性。我们都知道人生就是无数选择的组合,要让我们的孩子有一个良好的未来,我们必须让他们学会在不同的环境中作出合适的选择。

最近和一位有过二十多年教育经验,并在世界各国(包括中国)帮助开设十几所国际学校的美国教育界人士谈起选择。他的观点是,相比起亚洲国家,西方国家,特别是美国的社会自由度太大了。他认为,如果孩子从小没有得到对事物分析能力和选择能力的培养,他们在稍大以后,会有困难抗拒不良的朋辈压力(peer pressure),做出不适当的决择,因此可能导致一系列问题,包括吸毒和患上忧郁症等。

选择的能力从小就要锻炼起来,但是这不等于娇惯他们让他们随心所欲。一开始的时候,可以限制他们的选择范围,随着年龄的增长,这个范围可以渐渐扩大。还有一点需要再次强调的是,要让他们对他们的选择结果负责,特别是错误的选择。在这个过程中我们可以帮助他们分析,但最终还是由他们做出选择,承受结果。

比如说早上穿衣服,他们要自己挑衣服。这时,做父母的可以拿出两到三件他们喜欢的,让他们在一定时间中(比如3分钟里)做出选择。父母可以告诉他们说:“你有两个选择。第一,你可以自己在这些衣服里选;第二,如果你们在三分钟内还选不好,我就要选一套给你了。” 很重要的是,三分钟内如果选不好,不管孩子怎么哭闹,他们都要穿上你给他选的衣服。

再比如,如果一个十几岁的孩子上学总迟到,你就可以给他这样的选择:1. 如果他能按时走,父母可以用车送他;2. 如果他晚了,他必须用自己的零花钱叫出租去上学。

总而言之,传统的教育方式在很大程度上禁锢了孩子的创造力,主动性,责任感。我认为,教育不仅要让孩子学会课本上的知识,更重要的是培养他们独立自主和处理事物的能力和责任感。因此,我们应该在一定范围内多给孩子自由和选择的空间,并且要让孩子学会对自己的选择和行为负责;鼓励他们敢于提问,不要害怕权威;不要怕孩子摔跤,要让他们学会在一次次摔跤后重新勇敢地站起来。

正如儿童发展研究领域先驱、美国心理学家和儿科医生阿诺德·格塞尔博士(Arnold Lucius Gesell,1880  – 1961)说的,孩子们的智慧会自我展现。他提出,如果我们给孩子提供一个可适度激发他们身心发育的环境,并且花合理的时间和他们在一起,那么他们将会按需学习并成长,他们的心智也将因此得到完善。

编辑: 王冬莹、韩桦

公号原创文章,欢迎转发分享

转载请务必注明出处 (作者/编辑 + 公众号名称)

为什么世界一流大学不爱招中国学生?

2016-04-14 财经

一方面必须改变教育理念和教育方式,把幼儿园到大学的教育重点放在“做人”的通识与思辨训练上;另一方面要走出儒家名分等级秩序的文化制约,不能再把“顺从听话”机器人作为我们的楷模。

作者:陈志武

最近,两件事再次引发我对中国教育的担忧。一是,前不久跟一位美国名牌大学金融教授谈博士研究生招生政策,他说他们今后可能不再招收中国博士研究生了。

这不是种族歧视问题,他自己也是中国人,而是因为过去多年的中国学生,开始学习成绩都好,后来做博士论文研究时虽然未必突出,但还可以,可是等到毕业上学术市场找教职岗位时,都表现不好,没办法找到一流大学教职。所以,他们不想再浪费时间培养中国学生了。

实际上,不只是他们大学有这个打算,即使我所在的耶鲁和其他大学,也讨论过同样的问题,虽然我们没有决定完全停招中国学生,但从那以后,就有意识地少招或者偶尔不招。

以2015年为例,美国的前30名金融系毕业的博士中,来自中国的不少,但找教职岗位最成功的是去了加州理工学院,那个大学当然不错,可是,这么多中国博士生中没有一个被前10名或前15名金融系招聘。

由于这些博士都毕业于顶尖金融院系,这一结果很让人失望,各学校投入的资源和教授精力那么多,并没有得到相应的回报。

二是,在美国金融和硅谷高科技行业中,印度裔高管远超华裔。大家熟悉的谷歌、微软、Adobe、软银、花旗集团等公司的CEO都是印度人,在这种级别的美国公司中似乎想不起一个中国人CEO。公司副总裁一级的印度人就更多了。

而且,不只是美国企业界里中国人和印度人的反差这么大,在大学里也如此。比如,几年前美国主要商学院中,有12个在选拔招聘商学院院长,其中有10个给了印度裔聘书,没有一个给中国裔。尽管后来一些印度裔谢绝了,但这本身也反映出中国和印度之间在教育、文化上的差距。

中国人天赋好,又聪明勤奋,但为什么结果会如此失望,跟美国、印度和其他国家的人差别那么大呢?答案主要在两方面,一是教育理念、教育方法,包括中国父母对子女的养育方式;另一方面是儒家文化,尤其是坏在我们推崇的“顺从听话”和孝道文化上,这些文化烙印实际是中国人一辈子的包袱,走到哪里都无法丢掉,到哪里都吃亏。

 

先谈教育   

我在大学教书至今26年,见过的学生也算不少,其中两个故事让我难以忘记。

张三(匿名)出生于国内大城市,高中毕业轻易考上北大清华,等他到耶鲁读博士时,哪怕再难的数理经济模型对他来说都太容易。在我的博士生课堂上他毫无疑问一直最优秀,即使在耶鲁这样的世界各地天才会聚的地方,他的聪明才华照样遥遥领先。

可是,两年后的一天,正当他全力以赴深入做研究而且已经有出色成果的时候,张三找我私聊,说他在考虑是否退学回国去做PE投资基金,因为他父母好友愿意出资5000万美元由他去负责管理,机会难得。

震惊之余,我问他:“你的天赋如此出色,我一直认为你最有希望出类拔萃,出一流学术成就。告诉我,你是否真的对学术研究、学术生涯有兴趣、有激情?”

多年的经历让我清楚,一个人如果对他从事的工作没兴趣、无激情,尤其当他做的是学术研究时,那么,要他做好、要他做出别人想不到的创造性成绩,那等于是赶鸭子上架,难!每天做自己没兴趣的事情,只会是应付,不会钻进去的,那样他自己也会痛苦、很累。

张三回答说:“对学术研究谈不上有兴趣。我可以做,也可以写学术论文,但这不是我的兴趣与激情所在。”这下好了,我跟同事原来期许厚望的博士生,对我们的专业也就是如此。我接着问他:“那你为什么要申请金融博士研究生呢?”他的回答不奇怪:“因为父母要我这样做,而且看到其他同学都这样做。”

第二个故事更具戏剧性。这回是国内顶尖大学的经济史博士生,到耶鲁来访问一年。我原以为他对经济史这么投入,正好也可以协助我收集史料、研究一些经济史话题。到耶鲁后,他无比兴奋:要选修15门耶鲁戏剧学院的表演课程!耶鲁戏剧学院是世界一流,机会难得可以理解,只是我们没有学生会一个学期选五六门以上课程。看到他对表演这么有激情,知道他实际上对经济史和经济学没太多热情,所以,我没有阻止他去戏剧学院上课。

他那一年把耶鲁戏剧学院的所有表演课都上完,很是兴奋,那些表演系老师对他评价也非常高,觉得他真有表演天赋和激情。后来,我问:“很显然,你的激情在戏剧和表演。你在国内上大学、读研究生怎么没有申请艺术学院呢?” 答:“我父母不让呀。他们要我学经济学,好找工作!”

这么多年教过的中国学生中,真正因为自己喜欢而研读经济学、金融学的是极少数,绝大多数是因为父母的压力和安排。既然他们都不是因为自己真实的兴趣而为,出现上面我们谈到的,那么多读金融博士、经济学博士的中国学生最后在职场上表现一般甚至更差,就不足为奇。赶鸭子也许可以上架,但上不了高架的。

中国父母都关心子女教育,即使没有百分之百的“望子成龙”,也想儿女去尽可能好的学校,将来有一份好的职业与收入,能够一辈子过上幸福的生活。所以,就有了众多中国父母起早摸黑,不分周中周末,一年到头为了子女上学的事情奔波,甚至常年离开丈夫、家人和朋友到外地或国外陪子女上学。

也为了让子女上“最好”的学校,经常想尽办法找关系、开后门,使用所有能想到的招法,就是为了子女能得到“最好的教育”,为了不让子女“输在起跑线上”!在专业方面,都倾向于要求甚至不惜逼迫子女学金融这样光鲜的专业,或者学会计这样容易找工作的实用专业。

可是,很多父母可能从来没有问过,更没有想过“什么是最好的学校”“什么是最好的教育”。学过优化理论的人都知道,“好”“不好”“较好”“最好”这些价值判断都只能是相对的,必须首先搞清楚的是“相对于谁”“相对于什么”,因为不存在没有度量指标、没有参照系的“好”和“最好”。

于是,在不问不想的情况下,往往是根据父母自己认为“好”的标准去选择“最好”的学校和专业,等于让子女去过一种父母认为好但子女自己未必认为好的职业和生活。有时候,这实际上是迫使子女去实现父母自己没有能实现的专业梦。

或者,就是一窝蜂随大流,去追求大家都认为最好的哈佛、耶鲁或者北大、清华。如果你问他们“为什么哈佛耶鲁好、北大清华好”时,他们也说不上来。

好与不好,只有基于子女的个人兴趣、偏好、个性和天赋才有意义。

否则,不仅没有意义,而且很容易造成天赋与人才的浪费,结果只会是子女学习、工作没有热情,无精打采,每天因为在做自己没有感觉的学习或工作而特别累,而且会时常抱怨,对生活、工作失去兴趣。

父母也会觉得难受,因为他们尽了那么大的力,陪读那么多年,花了那么多钱,找了那么多人情关系,到最后也没有见到子女有出息!而对于社会,这同样是最糟糕的局面,因为如果多数甚至所有家庭都这样不顾子女兴趣去选择学校和职业,结果会是,社会中的各项工作都是那些对此并没有兴趣、更谈不上热情的人在做,这不仅导致人力资源的整体浪费,而且各项事业都无法做好,更不会有突出的创新。

在任何社会中,人才资源是各项资源中最为重要的,因此,把每个人的兴趣和天赋跟其专业尽量配置得一致,是整个经济中最为关键的一部分,也是决定一个国家整体资源配置效率的最关键因素。

我们想象一下:一个社会中,每个人在做自己并没有兴趣但为了养家糊口又不得不做的事,而且每件工作都是由那些并没有兴趣的人在做;在另一个社会里,每个人都选择做自己有激情的事情,而且每份工作都是由对其有兴趣的人在做。那么,这两个社会中,哪个社会的整体幸福感更高、效率和创造力也更高呢?

答案显然是后者。这就是中国社会和美国社会的差别,这些差别表现在子女的学校选择、专业选择、职业选择、工作选择和婚姻对象选择上。

经常有朋友咨询子女教育的事情,一个普遍的说法是:“我就想女儿读完大学,立即读研究生,拿到硕士博士学位、完成学习任务后,再去工作、结婚成家。”

我就问:“为什么非要有读硕士、博士的任务呢?为什么不能大学毕业后先工作几年,让他比较一下工作和读书的差别,感受一下自己到底喜欢工作还是学习,喜欢什么专业、什么工作呢?”

他们当然没有想过“为什么要读硕士博士”的问题,因为他们觉得反正大家都要子女读研究生,所以理所当然自己的孩子也要读。他们没想到也许自己的子女根本就不适合读研究生,也可能对学术和读书没任何兴趣,在这种情况下,如果还要他们去读书,对子女是劳命,对父母是伤财,对社会是浪费资源。

这些朋友就说:“万一他去工作后不再想回学校读书了,那不就不好了吗?”我说:“如果是那样,那就更说明大学毕业后先工作是对的!否则,他们会浪费那么多青春在自己不喜欢的事情上!”

在物质产能过剩、物质这么丰富的今天,温饱不再是个问题。父母可以给子女最重要的礼物是给他们提供经济条件,让他们追求自己的兴趣、选自己有激情的事业。把自己的喜好强加给子女的父母显得太自私、太不尊重子女,这包括学校、专业、工作和婚姻恋爱。

职业和做人 

下面这个故事很流行:一家硅谷公司招来三个实习生,分别是中国人、印度人和美国人。美国实习生只求把事情做完就好,一到下班立马走人。他对一些问题尽管一知半解但也能侃侃而谈,一分钟可以讲完的问题,能讲五分钟。中国实习生很努力,活干得最多最好,但不爱多说话。

印度实习生工作做得没有中国实习生精细,但也不差。虽然讲话带有口音,但最爱发问,擅长表达自己。在实习期间,学到东西最多的是中国实习生,但是,最后人们最能记住的是那位印度学生。

这个故事当然是中国人喜欢讲的,因为中国人看重“硬本事”、看轻“软本事”;按照这种我们熟悉的价值观,这个故事实际是想抬高中国人、贬低印度人,也包括贬低美国人,很符合中国人的口味。

但问题也恰恰出在这里,因为我们这种看重“硬本事”的文化取向造就了中国人只能干苦力活、不能像印度人那样在硅谷和美国大学等领域成为领袖人物;也正因为美国和印度社会既看重“硬本事”也看重“软本事”,所以,反馈到文化和教育领域,就变成了不只是要强调数理化,也要强调人文社会科学,在判断人才时不只是看他的硬技能,也看他的表达能力、沟通能力,看他是否是一个风趣的人。

比较极端的是,不少中国父母在子女好不容易到美国大学读书后,又偏偏要他们花大学四年学会计,这的确是“硬技术”,对找工作最便利。但是,他们没有想到,实际上中国会计规则跟美国不完全相同,学完美国会计规则,到了国内还要补课才能做会计。而且像会计这种职业性这么强的专业,根本不需要到美国大学去花钱学四年,在国内的技校就可以学到,然后在国内考会计资格,那样既省钱又更实用。

这些朋友说,他们担心子女毕业后不好找工作,会计好找工作。如果是这样,国内技校不是更好吗?而且,退一步讲,如果只是为了找工作,麦当劳不是有很多工作机会吗?

实际上,这里关键还是在于对“教育”的理解和认识问题。教育有两项主要功能:一是为了职业,一是为了做人,尤其是为了做一个有意思、有趣味、有意义的人。职业培养是为了饭碗,而“做人”的教育是为了让人不只是职业工具,而更重要的是做人。

许多朋友一听到自己子女想学历史、文学、艺术,或者心理学、政治学、社会学,就很生气,认为这些“软本事”没任何用,不便于找工作,等等。但是,他们不知道,这些“软本事”恰恰是使一个人更加有意思、有趣味的基础。

世界需要“硬本事”的人,但世界是由那些能说会道、知识渊博的人领导的。即使我们走出企业领导、政府领导阶层,在社会生活中,那些除了职业以外还了解我们历史、社会、政治和经济是怎么来的人也是更加有趣的人,同时更可能是社会中的成功人士。

随着互联网资源的丰富膨胀,各类专业技术通过谷歌随时随地可以查到,获得“硬本事”的方式可以是技校、大学,也可以是通过上网就行。所以,“硬本事”的相对价值在降低。但,全球一体化的社会对于软知识、软本事的需求比以前大增。

在这样的背景下,如果中国人不在“软本事”方面追赶美国和印度,我们可能只能继续以苦力活、以低利润活为主,把高利润、高收入的工作继续由美国和印度人控制。

就每个人的生活而言,从幼儿园到小学、中学和大学都应该强化通识教育,也是为了让自己能一辈子活到老幸福到老。通识教育不仅能让一个人增加“软本事”,而且还会让你接触了解各种不同学科领域的知识与研究,激发你方方面面的好奇心和兴趣。

一旦你对许多东西有好奇和兴趣后,一辈子中的不同时段总会有让你感兴趣、让你激动的追求和话题,不会过得枯燥,而会充实生命中每个阶段的生活内容,最大化一辈子的幸福感。

也谈文化 

 

之所以中国人跟美国人、印度人的差别这么大,也当然跟中庸和孝道文化紧密相关。在中国长大的过程中,父母等周边的人都教你“乖乖听话”、听长辈的话。不管走到哪里,只要见到比自己年长的,都要小声讲话,要顺从听话,不能挑战长者和权威的言论。

正因为从出生开始,二三十年之内,周边大多数人都比自己年长,都是自己必须要顺从听话的对象,所以,每个人在成长的二三十年里都会被驯化得乖乖的,没机会锻炼讲话辩论,长大后即使想学习辩论、学习作报告演讲技巧,也很难改变从小被迫养成的“听话不作声”习惯。

在中国,别人说“你的孩子好听话”是对你子女的表扬,父母也会因此而欣慰。而我在美国生活的30年里,从来没有听到美国人以这种话去夸奖人家孩子的,因为美国人会认为“听话”“顺从”是贬义,是没有个性的表现,因此,没有人愿意被这样评价的。

 

由于三纲五常,长辈、年龄是中国社会名分等级秩序的最重要组织维度,这种等级秩序压制个性的表达,使我们长大后本能地安静、讲话谨慎又谨慎。美国社会是另一极端,没有鲜明的基于年龄、长幼的等级秩序,大家以理服人,而非以年龄大小压人,所以,就更加促长美国人辩论能力、表达能力的发展。

印度则是介于中国和美国之间,他们对长辈也会敬重,但不像中国社会那么绝对,再加上印度被英国殖民统治100多年,多少也淡化了印度人对长者的顺从程度,不再像原来那么论年龄,而是更加讲理,以理服人。这些文化特点是上面三个硅谷实习生故事背后的重要原因。

中庸逻辑要求你不能声张,不能过多表达自己,什么都要适度。即使是讲道理、辩论,也不要那么认真,那么“打破沙锅问到底”,什么事情“差不多”就行了。这种文化熏陶出来的人,当然倾向于不会表达,即使表达或者争辩,也不会太认真,否则,内心会感到不自在,会内疚。

再加上这些年在中国,许多做母亲的不知道溺爱会害了孩子,让自己孩子永远长不大。比如,在我原来任教的一个大学里,一位中国教授已经30岁出头,没有结婚成家。尽管他已经拿到终身教授职位,但还是不成熟,因为他母亲还是每天跟着他、盯着管着他的一举一动,结果她儿子就没机会长大成人。

根据六年前我女儿用的一本美国中学教材的一些研究估算,中国大学生的成熟度平均比美国同龄人要低3.5年左右,原因就在于儒家文化和中国父母育子方式,在该放手的时候不能放手让孩子独立。

而成熟度跟领导力又高度关联,没有成熟就无法有领导力,就难以竞争谷歌、微软、花旗等公司的CEO岗位。

许多人在解释为什么中国学生在美国不能更成功、中国人不如印度人那么突出的时候,都喜欢以中国人英语差、印度人英语好作为主要理由。

语言当然是中国人的弱项,但实际上更根本的原因不是语言,而是儒家的名分等级秩序,这个秩序使我们每个人在成长过程中被持续不断地压抑,任何有个性的表达和质疑都会招致重罚,以至于等我们长大成型时,我们每个人都成了只会做事、不会作声的人,只有干苦力的“硬本事”,没有“软本事”。

今天的世界已经高度一体化了,为了让我们的后代有机会在国际竞争中更能胜出,一方面必须改变教育理念和教育方式,把幼儿园到大学的教育重点放在“做人”的通识与思辨训练上;另一方面要走出儒家名分等级秩序的文化制约,不能再把“顺从听话”机器人作为我们的楷模。

来源:《财经》杂志 ;作者为耶鲁大学教授、北京大学经济学院特聘教授)