非科班出身的人学习编程不负责任指南

为什么要写这样一篇文章

来咱们这个实验室里读研的学生可能自历来到这里的第一天就以为本身的命运很苦逼。他们读本科时主修的是机械设计、制造以及自动化之类的专业,毕业时的简历上也顶可能是写写擅长 MS Word、PowerPoint、UGNX、AutoCAD 之类的应用软件。他们有限的学习生涯里,怎么也不会想到来到这里居然要首先从新学习 C 语言,而后还要学 C++,接下来还要学习 Python 或 Lua 什么的,并且居然还不让用 Windows,只能用连个 QQ 都没有而且常常出故障的 Linux……html

在他们内心,编程彷佛并非多么有趣的事,因此他们就以为编程很难。对此我有同感,你们都会玩的 Windows 里的挖雷与纸牌那样的小游戏,还有不少人会打的麻将,还有围棋,这些事我以为也挺难的。python

我曾经告诉他们,若是不会编程,那么他们就很难解决本身的研究方向上的那些问题,所以也就不可能写出有价值的论文,不可能顺利的毕业拿到学位,不可能找到很好的工做……这种功利性的『威胁』,对于有些人会有点效用,可是若是没有能力让他们自发的对编程产生足够的兴趣,这对于任何一个『好为人师』的人而言都是一种莫名其妙的羞辱。git

如今我试着去告诉他们,编程不只不难,并且会颇有趣,其中充满着值得深思的东西,而这些深思对于咱们人生也会产生许多增益。因而,就有了这篇文章。程序员

编程是什么

不管你是否是程序猿,每一天你都在编程,每一天你都被编程。编程,就是设计一些步骤,组织这些步骤,让这些步骤在当前环境中正确的运行,最终得出本身想要的结果。github

你的每一天都是在起床、喝水、吃饭、工做、上厕所、娱乐、睡觉等步骤的有序组织下运转的,你活在这个程序中,同时你在这个程序中为改善本身的生活而制定各类计划并努力去实现。web

机械设计,其实比编程还要编程。所谓的机械零件,就是数据结构。所谓的传动机制,就是应用程序接口(API)。所谓发动机,就是程序的内核。你将零件装配好,经过传动机制将它们接驳到发动机上,因而你就创造出来一部机器,通上电或者打着火,就可让它运转起来。算法

编程比机械设计来的更为简单,你不须要常常给本身所编写的程序添加润滑油,也不须要去对每一个数据结构进行复杂的力学分析,更不须要关注这些数据结构是否严丝合缝的相互配合,至少目前的计算机软件工程是这个样子的,它不像机械工程学科那样以坚实的物理定律为基础。机械的结构与运行规律老是可计算、可分析的,而软件的结构与运行过程却充满着太多不严格的环节。这种不严格,却给咱们营造了一个能够发挥天赋或工科实践经验的空间。显然,即便软件工程存在着各类不严格,可是咱们却可以经过编程模拟出机械工程的一切。事实上也是如此,现代的机械工程领域,软件已经无处不在。编程

机械设计有不少精妙的『算法』,像缝纫机、枪械、发动机之类的机构,设计它们其实要比计算机世界里的算法设计可贵多,并且这些机构对人类文明的发展每每可以产生巨大的推进做用。但愿你不要所以爱上机械设计……学会编程,你会对机械设计的理解更为深入。由于编程是将『设计』自己做为一种智力活动而对待的。你能够将机械工程领域的那些智力活动应用于编程,也能够将编程中的智力活动应用到任何设计之中小程序

clipboard.png

正如 SICP 一书的序言所言,教育者、将军、养分学家、心理学家以及父母们,他们作规划,而士兵、学生以及某些社群则被规划。克服大型的问题,要通过一系列的规划,其中大部分规划会运做于现实之中,由于这些规划老是与迫切处理的问题息息相关。若将规划这件事情自己做为一项智力活动来欣赏或研究,那么就必须转到计算机编程上面来。你须要阅读与编写计算机程序,并且要大量的作。程序是怎样的,它们的功能是什么,这些不过重要,重要的是它们的性能如何,它们之间可否精巧的相互配合从而构造更大规模的程序。segmentfault

入门书

学习编程以前,应该先问本身一个问题:我为何要学习编程?不要打我……我知道大家是被逼着去学习编程的,那就不妨被逼着思考『我为何要学习编程?』。

若是不知道答案,也没有关系。反正这个问题与学习编程也没有太大关系。其实,咱们已经作了很是多的不须要回答为何的事了。咱们连『咱们为什么而存在』这样的问题都不知道答案,却依然糊里糊涂的活到了如今。

先推荐几本入门书以及阅读它们的方法。对于咱们而言,选对书很重要。国内科班出身的人所用的教科书对于咱们来讲每每不合适,由于这些教科书可能比较适合在课堂上使用,课堂上老是会有一个能读懂这些写的挺糟糕的教科书的老师,他极有可能不会按照教科书里的套路来说课,而教科书却能够扮演课堂笔记的角色。也就是说,大部分国产的编程书,它们比学生的课堂笔记强不了多少。非科班出身的人,没有课堂,没有老师,因此也就看不懂『课堂笔记』。好在,国外有一批优秀的书籍,课堂中的老师就在书中。

阅读方法也挺重要,由于学习编程最不须要就是将一本讲编程的书从头读到尾……对于非科班出身的人而言,编程不是考试,不必让本身所掌握的知识去覆盖全部的编程问题。人的精力极为有限,大部分人终其一辈子,能在一两个方向上有所建树已经很对得起本身了,所以几乎任何一本编程的书里总会有些东西是你不必去看的。老是不要忘记,咱们是非科班出身,没那么多的时间去挥霍,而节省时间的最好的办法就是只取本身所需,前提是你的方向与目标是明确的。因此在读书的过程当中,不要停下问本身,为何要学习编程?

我推荐的第一本书是《计算机程序的构造和解释》,英文名是《Structure and Interpretation of Computer Programs》,简称 SICP。英语阅读能力好的同窗,能够看英文版。中文阅读能力好的同窗,能够看中文译本,裘宗燕老师的文字素养与翻译的严谨程度基本上是可赞的(若是中文译本某些地方看不懂了,能够参照英文版)。这本书的阅读,建议分如下三个阶段:

  1. 阅读前两章,第一章是讲计算过程的抽象方法,第二章是讲基本数据类型(数据结构 + 运算)。这两章的内容涵盖了软件世界的『九年制义务教育』的所有内容,所用的教学语言也是很是成熟且设计精巧的 Scheme 语言的一个很小的子集。学习这两章内容的过程当中,能够穿插着阅读《Teach Yourself Scheme in Fixnum Days》的前 10 章,这份 Scheme 教程也有一份中文译本。SICP 的习题,即便不去作,也应该把题目看一下,动脑子想想,判断一下能不能作得出来。这些习题,在网络上很容易找到答案。

  2. 复习 C 语言,教材用 Kernighan 与 C 语言之父 Ritchie 合写的那本《C 程序设计语言》便可(学习期间,能够了解一下 C99 与 C11 标准)。这个阶段的设置,主要是面向咱们实验室内部。由于咱们实验室里的同窗在本科阶段一般是要修 C 语言这门课的,可是当时他们可能并未真正从学习编程的角度去学习,如今能够经过第一阶段由 Scheme 语言创建的编程观念去从新认识一下 C 语言,只有这样方能理解 C 语言的优势与缺点,而且去思考如何充分发挥 C 的优点,而后用 Scheme 来弥补 C 的不足。借助 GNU Guile 2,很容易实现 C 与 Scheme 复合编程。这个过程能够穿插阅读 Kernighan 写的《程序设计实践》。

  3. 阅读 SICP 的第 3 章,而后再找一本讲 C++ 的书,好比 C++ 世界中很是有名但我不觉得然的砖书《C++ Primer》,只学习基于类的数据抽象以及面向对象编程部分。SICP 的第 3 章阐述了面向对象编程与函数式编程两种范式。从 SICP 中得到的面向对象编程,能够在 C++ 的学习中获得一些强化,至于 C++ 中的泛型编程,初学者没必要过分深究,只需掌握 C++ 标准库的基本用法,等具有必定的编程经验以后,根据须要时另做打算。最后,记得将《Teach Yourself Scheme in Fixnum Days》剩下的内容看完。

C++ 的入门书,我更推荐《C++ Without Fear》,中文译本叫《好学的 C++》,如今应该是第 2 版。之因此不推荐你们认为是 C++ 四书五经之一的《C++ Primer》,是由于我总以为它像一本事无巨细的案头手册,比较适合那些已经有了编程经验甚至 C++ 经验的程序猿阅读。我心目中真正好的教材应该像小说那样,由一条或多条逻辑主线延展而成,这种教材对于非科班出身的人尤其重要。

对于大部分编程任务而言,上述书所涉及的知识已经足够用了,并且上面的这几本书也是很是耐读的书,只要你不是那么着急的将它们读完,它们老是颇有趣。我很喜欢 SICP 与《程序设计实践》这两本书,由于太喜欢了,因此一直都不舍得把它们读完。

注:会有人嘲笑,又有人又给你们推荐了连他本身都没看完的书!事实上,SICP 与《程序设计实践》这两本书我读完过。SICP 看了 1.x 遍(由于我对写编译器这种事不是很感兴趣,因此第四章与第五章只是粗读,前三章我看了不下三遍)。相似的,《程序设计实践》也看了 1.x 遍。我之因此说『不舍得把它们读完』,想表达的是每次重读它们时,我都当本身没读过。

让实践有些难度

书是要看的,可是看书的过程当中最好开动你的双手。因此,你不该该停下来问本身:为什么要学习编程?

我但愿总有一天,你能给本身找到一个答案,那就是你想写一个 XXX 程序。这个程序至少应该对你是有用,亦即它的主要功能不与你的系统里的其余程序存在着重复。若是你能明确这一点,那么你所创造的程序就有了意义,你的学习就有了意义。

为什么要学习编程?由于你要创造一些历来没有的软件,并且它可以帮助你作一些你认为是很重要的事!凡是你认为重要的事,对于不少人而言,颇有可能也是很重要的,所以你所创造的东西就能够帮助更多的人,这意味着会有一些你可能不认识的人须要你,这就是你的价值所在。

编程是基于现实生活的创造。这种创造是渐进的,你在创造之初可能也没法预料到结果会是如何,这是任何创造性活动的基本属性。编程的实践,应该将它做为探索未知世界的智力活动,应该从书中跳出来,将本身从那些示例中得到的经验用于解决现实中的问题。若是你以为,现实中根本不存在什么问题须要你去解决。那么……请你回答一下『你为什么而存在』这个问题吧。

看书,是从前人正确的经验中学习。实践,是从本身的失败中学习。既然决定要实践了,因此仍是给本身找一些比较难走的路走走看吧,让失败多一些,让失败早一些。

以我我的比较感兴趣的几个东西为例,能够写一个基于 TeX 的现代文学编程语言,经过它不只能够历练编程能力,也会对编译原理中的语法分析环节有一些实际的认识。也能够尝试去写一个三维几何库,可以完成凸包、Delaunay剖分以及 Voronoi 图等计算,不求大而全,只求小而精,之后漫长的时间里能够慢慢的去改进它。还能够去找一个本身喜欢的开源项目,去阅读它的源代码,了解它所用的项目构建系统,分析项目结构,试着去修改它的代码……我如今最感兴趣的是 LuaTeX。

问题是最重要的

假如你已经有了很是屡次的实践上的失败,而且你已经大体掌握了 Scheme 与 C/C++ 这样的语言,那么每一年学一门新的语言,这并不是难事。可能你会对网络上常常发生的语言之战以为奇怪。

是问题决定了语言,是问题决定了编程范式,是问题决定了信仰。若是你能很明确的认识到这些,那么你就不会陷入某种语言宗教的泥淖之中。对于许多事都是如此……搞机械的人,也常常信仰 UGNX,CATIA,PROE 这些『宗教』的……

若是非要给本身找一种信仰,那么我信仰个人存在就是为了解决问题的

若是在我用的 Linux 系统上作一些自动化程度高一些的维护任务,我不会厌憎佶屈聱牙的 Bash 脚本,而是很是欣赏它像胶水同样快速的将几个原本是独立运行的程序链接起来替我完成复杂的任务。

若是我要临时的作一些文本处理工做,我能够用 python 3,由于它对 UTF-8 支持的挺好,并且字符串库功能齐备。若是只是进行一些文本的替换,emacs 或 sed 之类现成的工具也够用了。

若是我要写一个严肃的程序,严肃到了它的生命可能要好久,那我会选择一门成熟稳定的语言来实现它,即便用 C,我也不会烦弃它的繁琐的代码,我会尽力凝练程序中要实现的功能。

人生中原本就面临着许多选择,可是很是多的人在选择以前并未认真的去考察本身面对的问题。

不过,对问题自己的考察,须要一套基本的工具集。没有听诊器、手术刀或 X 光,再厉害的医生也没法分析人体的内部发生了什么。对于编程而言,我认为上述我推荐的书中所涉及的知识已经足够用来洞察软件世界的各类问题了,以此为基础,咱们只需再保持心态的开放,随时汲取所需的知识就能够了。例如,虽然上述几本书没有一本是讲 Web 开发的,可是若是你熟悉 Scheme,就能够发现 JavaScript、HTML 五、CSS 3 之类的语言并无超出 Scheme 的范畴,你能够很快的就掌握它们。

算法

解决问题须要算法。既然编程无处不在,那么算法也是无处不在的。可是,若是随便拿起一本讲算法的书,随便一本,可能都会让你以为头昏脑胀。也许你会担忧,连算法的书都看不懂,还怎么写程序?

当初我刚学习编程的时候,写过二十四点、汉诺塔、八皇后、俄罗斯方块之类的小程序。后来,在现实的项目里,也写过堆排序、快速排序、矩阵的 LU 与 SVD 分解、无向连通图的最小生成树及最短路径之类的程序。可是如今,随便拿一个让我去实现,我仍是不得不去翻书看懂算法,而后再去写程序……

我想说的是,若是你正在阅读一本讲算法的书,书里有些算法或它的示例是你一时没法看懂的,能够跳过去。不少专门讲算法的书里,充斥着心智游戏。若是你没法将本身代入到这些游戏的情境中,这个游戏的玩法天然就是不明了的。如今看起来,这是很天然的事,然而当初我却一遍又一遍的怀疑本身的智商,特别是看到网络上不少人像喝白开水同样的谈论着这些心智游戏,我一度怀疑,我不适合作编程方面的事。

幸亏,这个世界足够稳定,以致于咱们不须要了解相对论与量子力学也可以很好的生活下去。大部分人,连牛顿力学都不须要了解……算法也是这样,特别是如今已经存在了至关多的实现,例如几乎任何一种编程语言的标准库中都提供一维数据的快速排序算法的实现。基本上,只要是对现实中的问题很是重要的算法,你老是可以找到它们的既有实现,取而用之。

当你走在街上,那些高高矗立恢宏建筑,建筑工人建造它们的过程当中可曾用了极高心智的技术?编程,本质上也是如此,工程经验的重要性大于心智。甚至在编程中,过多的运用心智,反而会拔苗助长。

我不是说学习算法没有必要,我只是强调不要被一时难以理解的算法挡住你。你天生就拥有一些无比强大的算法,它们是穷举、贪婪与分治,还有最强大的『演化』与『神经网络』。那些专门讲算法的书,只不过是是了很蹩脚的语言、符号以及示例将你天生的直觉刻画出来而已。只要你在现实中遇到问题,你老是可以找到求解这个问题的方法,而不是只有读懂了某本讲算法的书你才能解决这个问题。

不少算法书,都是我看不懂的。它们的第一章就是让我复习数学概括法,第二章就是让我学习算法的时间与空间复杂度分析……而我属于对数学缺少直觉的人,对我而言,这些书的惟一价值就是故意不让我去读它。即便是我心目中的大神 Knuth 的传世之做《计算机编程艺术》,它惟一的目的彷佛就是让我以为我不是搞艺术的。

好久以后,我在学校图书馆闲逛的时候,发现了《如何求解问题:现代启发式方法》这本书,翻了翻,就开始叹息,为何一开始不知道这本书?

加强对计算机的理解

有时间与精力能够阅读一些专业性强一些的计算机理论的书籍,譬如操做系统原理、编译原理、算法与数据结构之类。看不懂太专业的书,或者没那么多时间和精力,能够看看计算机科学的一些科普著做。有本《通灵芯片》值得一看,薄薄的小册子,三五天的业余时间就能够看完。有本《编码:隐匿在计算机软硬件背后的语言》,算是《通灵芯片》的增强版,也值得一看。有一本《深刻理解计算机系统》,以程序员的视角来看计算机的软硬件系统,也是一本很好的书,不过就是要读完它,须要一些耐心与时间,因此不必一次性看完。也能够继续将 SICP 的第4、五章看完。

虽然你的编程技能不会由于读了这些讲述计算机原理的书而日新月异,可是这些书可让你理解你的程序是在一个什么样的世界里运行的。虽然你不知道本身为什么而存在,可是你知道这个程序为什么而存在。你不只知道它为什么而存在,还知道它怎样存在,而且也知道怎样让它更好的存在。这样,也就不必在那些所谓的『XXX 箴言』、『XXX 之道』、『XXX 之禅』的书籍上浪费你有限的生命。

有时间,也能够复习一下《黑客帝国》,它的导演虽然不是程序猿,但胜似程序猿。看完黑客帝国,也能够看看 Steven Levy 写的《黑客:计算机革命的英雄》。从技术层面跃迁到人文层面,也许那时你会对本身的人生有着更为深入的认识。计算机,是人类为本身创造出来的最好的一面镜子。咱们如今没有能力了解自身,可是咱们能够制造与发展计算机来逐步了解本身。

从其余领域寻找答案

有必要阅读一些哲学、物理、生物之类的书籍,若是没时间或者基础也很差,能够看科普书籍,并且我比较推荐看后者。看这些书,对编程技能没有太直接的帮助,可是它们每每会让你对身处的这个世界有所反思,甚至能够得到一些新的认识,让本身的意志更为笃定。

若是从未想过去看哲学的书,我推荐一本 14 岁的少男少女就应该阅读的《苏菲的世界》。罗素的那本《西方哲学史》虽然出自他我的的视角,可是显然咱们对哲学的理解也很难达到他那样的高度,鉴于咱们也不是打算去在哲学上有所成就,《西方哲学史》足够咱们看的了。我不认为这个世界上真正存在『正确』的哲学。

复习物理。《费恩曼物理学讲义》第一卷就很好,人类所能感知到的这个世界,费恩曼像讲故事同样的差很少一网打尽了。若是连费曼的书都看不懂,不妨看看《时间的形状》+《量子物理史话》,它们是近年来在相对论及其以后的物理学方面中国人写的很是优秀的科普书。还有一本是我大学时常常看的《从一到无穷大》,虽然年代已颇为久远,但依然不失为极好的物理科普著做。

生物学,这门课在中学时是我最讨厌的课程之一。由于我实在是看不懂书里的插图,乡村中学连个显微镜与真实的标本都没有,因此长期以来,我一直都是个生物盲。不少常见的花草树木鸟兽虫鱼,我连它们的名字都叫不上来,更不要说它们具体属于哪一个门纲目科属种了。可是有一本生物学的书我仍是能看懂的——《漫画玩转遗传学》,这是本很是好的遗传学科普书。当时我是由于学习遗传算法而买来的,结果从它从第一页开始就把个人眼睛抓住了。

这些书你都看过么?

都看过,可是有一些也没有看完。有些书是看完了,可是时间久了,有些遗忘,一直想找点时间再重读一遍。

有些书是由于实在太好,不忍心一下都看完。这样说,有些矫情,但事实就是如此。像《费恩曼物理学讲义》,虽然有着物理学界小飞侠之称的费恩曼已经将深邃的物理学变成了我可以读懂的人类语言,可是一方面我不是专业研究物理学的人,我没有必要赶进度似的将他的书完全读完。学物理专业的人,可能也不会去将《计算机程序的构造和解释》与《计算机编程实践》看完的,不然他们就不会那么酷爱 python 了。

有些书对我而言是由于太难,即便我以为已经看完了,但过一段时间发现,跟没看过是同样的。这些书,我也只能归类为没有看完的书。

凡是我看的书,都是我认为在书中所涉及的方向上,做者比我走的更为深远。不过,我也不自卑,由于他们如今已经无法走了……

后记

本文写于一个深秋又寂寞的下午,目的只是为个人小伙伴们学习编程指出一条道路。从 SICP 开始,可能有许多人以为不靠谱,可是考虑到这些小伙伴一个一个都是研究生,考研期间通过了高数、线代、几率以及英语的『洗礼』,研一也会修数值分析与矩阵分析这两门数学课。即便他们之前从未接触过编程,可是他们的状况,SICP 仍是挺适合他们的。若是他们连 SICP 的前两章都搞不定,这只能说明他们连 MIT 大一的学生都不如了……

对于我不知道底细又打算学编程的同窗,这篇文章可能不会太靠谱,因此我只能在题目中写上『不负责任』。不过,文章中出现的这些书,我以为还都是挺不错的,有时间看一下,应该不是浪费时间。

相关文章
相关标签/搜索