重读《黑客与画家》:编程是一种创造
这是一本值得反复阅读的书。
作者Paul Graham是硅谷著名程序员、创业投资人和思想家,也是全球顶尖科技孵化器 Y Combinator (YC) 的联合创始人,他的个人博客 https://paulgraham.com/ 看似简陋,甚至有点老土,但丝毫不影响其中思想的光辉。
最近又重读了一次《黑客与画家》,其中有不少观点依然让我很受触动,摘录一些有意思的内容,记录于此。
卷王 Michael Rabin
里面提到了一个有意思的人:Michael Rabin。
他是以色列计算机科学家,1976年图灵奖获得者。
第四章中,Paul Graham 写道:
Michael Rabin遇到难题的时候,会把问题重新定义成一个较简单的形式,同时,一定会假想一个对手正在与他比赛谁能更快地解决问题。
这段话里,其实包含了两种非常有意思的思维方式。
第一种:化繁为简,逐步求解
遇到一个复杂的问题,不一定非要一开始就解决它最完整、最困难的形式。
可以先把问题重新定义,降低它的复杂度,找到一个更容易解决的版本,然后快速尝试、验证,再逐步增加复杂度,最终逼近真正的问题。
我自己在编程工作中,也经常使用这种方法。
面对一个复杂需求,我通常不会试图一次性把所有东西都想清楚,而是先把问题拆开,找到一个最简单、能够运行的版本,先让它跑起来,再不断修改、验证和完善。
很多时候,真正的答案并不是想出来的,而是在不断尝试中逐渐逼近的。
第二种:假想竞争,保持压力
第二种方式就更有意思了。
谁没事总是妄想竞争对手呢?这不是典型的卷王嘛!
但仔细想想,这种方法其实非常有效。
当你假想有人正在和你竞争,就会产生一种紧迫感:如果我现在不努力,别人可能就会超过我。这种压力会转化成动力,让自己保持在一种持续思考、持续进步的状态。这让我想起一句话:生于忧患,死于安乐。
编程的本质:创作
《黑客与画家》中,我非常喜欢的一个观点是:编程的本质是创作,而不是科学。
第二章中,作者写道:
很长一段时间内我都为此事泪丧,就像小学里老师教我怎么拿铅笔,我却总是学不会的那种感觉。如果我那时看到其他创作领域,比如绘画或者建筑,我就会想到,自己的方法其实有一个正式的名称:打草稿。我现在认为,大学里教给我的编程方法都是错的。你把整个程序想清楚的时间点,应该是在编写代码的同时,而不是在编写代码之前,这与作家、画家和建筑师的做法完全一样。
这句话对我的触动非常大。
他说大学里教给的编程方法都是错的!谁错了?他还是大学的教育?
我大学学的也是计算机专业,直到工作很多年之后,我才慢慢意识到这个问题。
我就没有通过大学的教育学好编程,我的编程能力主要是工作以后靠自己练出来的,而不是学校教出来的。我对学校教的C/C++编程语言没有太大兴趣,但是,我后面自学了HTML、CSS、JavaScript、Java、Python和Go,我对WEB开发的兴趣非常大,我废寝忘食地学习一切我感兴趣的东西,不断地写各种软件。最终,我是靠自己的实践和坚持学会了编程。
现在回头看,我越来越认同 Paul Graham 的观点:编程和绘画、写作、建筑非常相似,它首先是一种创造。
如何学习编程
既然编程是一种创作,那么问题来了:我们究竟应该如何学习编程?
第二章中,Paul Graham 给出了一个非常直接的答案:
画家学习绘画的方法主要是动手去画,黑客学习编程的方法也理应如此。大多数黑客不是通过大学课程学会编程的,他们从实践中学习。
这句话其实已经把答案说得很清楚了:实践。
就是大量地写。得动手,多写,疯狂地写。
我们过去受到的传统教育,往往比较重视知识的学习,而轻视实践。于是,出现了一种奇怪的现象:一个学生可以熟练背诵各种语法规则,知道什么是变量、循环、函数、类和继承,但真正让他独立写一个稍微复杂一点的程序,却无从下手。这就是典型的:头重脚轻。知识很多,但缺少创造能力。
而编程恰恰是一项非常依赖实践的技能。
只有真正踩过坑,才能知道哪些方案容易出问题;只有真正维护过一个项目,才能理解什么叫“好的代码”。
所以,我现在越来越觉得:学习编程最好的方式,不是先把所有知识学完,再开始写程序,而是一边写程序,一边学习知识。
需要什么,就学什么。遇到问题,就解决什么。在实践中不断补充自己的知识体系。
除了实践之外,还有一种非常重要的学习方式:模仿优秀的范例。
Paul Graham 在书中提到了富兰克林学习写作的故事。富兰克林通过分析、模仿优秀作者的文章,逐渐提高了自己的写作能力。这其实不仅适用于写作,也适用于编程。学习编程的时候,我们完全可以去研究优秀的源代码。看看别人是怎么组织项目的、怎么定义函数的,看看别人为什么把一个功能拆成几个模块。
刚开始的时候,你不需要完全理解所有东西。先模仿,再理解;先实践,再总结。就像小孩子学习说话,并不是先学习语法,然后才开始说话。而是先听别人怎么说,然后模仿,再慢慢理解其中的规律。
写在最后
创造能力,很难单纯通过课堂传授。你需要大量实践、不断试错,需要研究优秀的作品,也需要在一次次真实的问题中成长。
这也解释了为什么有些人大学毕业时,掌握了很多计算机知识,却依然不会真正写程序;而另一些人,可能没有接受过系统的计算机教育,却能够通过长期实践,成长为非常优秀的程序员。