跳转至

如何学会编程语言

目前在大众刻意学习技能的领域裡面。我想最难的两个领域,应该是“学习编程语言”以及“学习外国语言”。

这两个课题,算是大家又想学,但实质上又很难学的两门技能。

你会好奇,这本书的方法:也可以拿来攻破这两门学习领域吗?

答案是可以的。甚至这两门方法学习方法可以是相通的。

编程的本质是“自动化”

大众对于这两门学问的共同恐惧就是:

  • 专有名词太多要背
  • 语法太艰深容易搞错

所以还不到学起来事倍功半的程度,就直接从入门到放弃的结果了。

但我认为,这是因为坊间绝大多书,都切错入门角度了,带大家绕远路了。

怎麽说呢。让我先问问各位读者,为什麽你想学编程语言?

很多人想学编程前第一个问题是:我该学哪一门语言好?

坊间热门领域有 Python, Ruby, JAVA, JavaScript, Objective-C / Swift。该选择哪一套。

已经入门的人,都会跟你说:

  • 学我这一套
  • 或者是看你的需求

但是这通常会造成几个结果:

初学者就不知道自己的需求是什麽了。怎麽知道要选什麽?更糟的是,他学了老半天,才发现学了这门语言才发现没办法做出他想要的东西。(比如说学了 Python 结果造不出手机程式,倒是学了一堆爬虫技术)

这通常就是学编程初学的死结。

另外,我们在训练编程新人时,也会遇到一个问题,对方明明熟练语法,他却不懂要如何实在商业逻辑所需要的代码,搞得老手非常头痛。

后来我才发现,想学编程的人,跟在教编程的人,都搞错了编程这门技术最大的重点:“自动化”。

是的,自动化。

我们谁学编程不是想要将自己手上重複的事情自动化呢?“自动化”才是我们真正想要做的不是吗?

这世界上的程式语言非常多种(是百量级左右)。但这些编程语言被发明并投入使用的关键目的,就是“自动化”。

如果你先从语法学起,而不是从“自动化”的流程学起。非常有可能事100倍功半。

如何学习自动化

我在上一本书“打造超人思维”裡面,有提到过编程思维这个概念。许多人认为“编程”是一套可以解决一个超大问题的神奇魔法。

实际上,编程更像是多套小工具,组起来的自动生产线。

资深程式设计师在实际上设计一套程式时,主要的原理,先是将问题先拆小,找到可以自动化的部分先完成,不能自动化的部分先用手动 Workround,再重新组装。

自动化的流程是输入、处理、输出

那麽自动化,又该怎麽实做呢?其实流程很单纯:就是“输入、处理、输出”循环执行。

2020 年我心血来潮。想来做一个更简单的编程课(直接就叫“不用写程式的程式课”),原本教材都写好了。但我不确定我写的教材适不适合大家用。

于是就发了一个问卷,问大家要解决什麽问题。结果问卷回收以后我惊呆了。大家想要解的问题,跟我想的完全不一样。自然我之前的教材都要作废了。

大家提出了一些想要解决的问题。

如:

  • 各种学会缴费单收到后,自动去缴钱
  • 印刷厂电话询价报价
  • 药师收到处方签配好药提醒病人回来拿药
  • 商务拜访,收到名片,后续跟进
  • 跟客户提案、安排老师教学,
  • 整理公司报帐单,分析预算花费
  • 病人看诊问诊,判断分类,后续卫教追踪
  • 旅游业客人报名,预定安排行程,通知出团

乍看这些问题千奇百怪,但实际上它们的结构都是一样的。

怎麽说呢?其实,当它们被经过整理,你会发现:

都是:输入、处理、输出。

“输入、处理、输出”这一个动作,其实有个名字叫“流程化”。

而我们认为的写程式,其实是

一般人向工程师说,他想学写程式时,重点往往会放在自动化

但一般人其实缺的是问题分解+流程化的思维。

而当你能将问题分解“流程化”以后,加上自动执行就变成了“自动化”。

而坊间种不同语言,有不同适合应用的场景,比如说 Python 适合做爬虫、Ruby 适合做网站、Swift 是 iPhone 专用语言,JavaScript 多半作为网页特效等等。

有时候我们解决一个问题,用的不是只有一套语言,甚至可能是多套语言。

但也别惊慌,我们解决周遭的事,并不需要学会那麽多套语言。更重要的是,我们如何找到“工具”把流程上的各种“问题”的“答案”,并将之串起来。

特别是网路上,关于一些最常用场景,几乎都有自动化服务以及套件了。

比如说,如果我想要把一本网路上买到的英文书,翻译成中文书。其实有好几种路径可以选择:

  1. 找工读生,看著整本书打字出来,再找人翻译成中文。
  2. OCR 整本书,自动把每个字都扫描进去辨识出来,再找人翻译成中文。
  3. 找到这本书的打字版本(如 epub),一篇一篇手动贴到 Google Translate 翻译成中文再拼接起来。
  4. 把书拆成一章一章,写程式自动送到 Google Translate 的 API,1 分钟完成翻译一本书。

写程式并非必要,关键在于你如何找到问题,并且拆小。通常精通编程的人如我,遇到问题也并非一上来就写程式。而是会想办法把真正问题拆解出来,然后找到这条关键路径上所有简单粗暴可行的方法,先拼起来,输出我要的结果。然后再逐一优化流程上每个节点,最终做到自动化。

当你抱持著这个观念去“学编程”之后。通常快乐就会增加很多,因为在这个过程中,你得到的会大多是正向反餽(解决问题的快感)。而非计较纠结于自己连语法都使不好,或代码写的难看。

当你这个流程越熟练,你就随之越看得懂程式上面的错误讯息以及找到的 Google 资讯。

有了这个概念,接著你就可以把你想要解决的日常问题,也接入我们之前的“挖问题”“流程化”“上瘾迴圈”裡面了。

以积极的心态看待错误与反馈

学编程另外一个关键点,在于如何看待“错误与反餽”。

我过去在教编程的时候,发现一种特殊现象:

  • 如果曾经唸过资讯科系的人,学工作上用的新编程语言会很快
  • 反之,往往失败率会非常高

我曾经以为这是因为在大学时,曾经有接触计算机预备知识的差异。后来,与更多“想学编程的普通人”聊过才知道。关键不在于这些计算机预备知识。而是电脑发生错误时,对于讯息的反餽处理方式接受度有所不同。

对于程式设计师、唸过资讯科系的人,如果在学新编程语言时,如果画面跳出红字、错误。我们会认为这是正常反餽。

有可能我打错了字,有可能我档案放错位置,改一下就好了。但是普通人会理解为“我是 Loser,一直出错”。

因为普通人这辈子并没有面对过这麽频繁这麽密集的“出现错误讯息”。

但是作为程式设计师,我们在编程时,并不是写程式一次 OK 的。更精确的来说,对职业程式设计师来,写程式一次 OK 的机率是 0%。对,你没看错,就是 0%。

绝大多数程式设计师,用的是 Debug-Oriented Programming。就是写一小段程式(或从网路上複制一小段程式码),暴力跑。然后看自己有没有打错字,打错字就修错字。没错字再看刚刚写的这一小段程式(约20-50行)有没有跑出预期的行为。没有就修正,如果有就再写下一段。

所谓的编程行为,是程式设计师不断的写很多小代码段,然后组成大块代码块,然后再重新整理而成。

所以一天吃个 100 个 error 是超正常的。这也是为什麽资讯科系学生,出校园以后学习新语言新框架会特别快。不是因为“他们有基础”,而是他们心理上可以“无视 Error 带来的心灵创伤”。

如果初学者不瞭解这一点,在学习编程之路上,会很快的从入门到放弃。

而编程又为什麽那麽难学那麽容易让人放弃呢?

这是因为很多网上的课程,要不然就是老师不给程式码,学生必须一幕一幕的按暂停,试图去跟著老师萤幕上的代码一行一行敲。所以难免敲错字。 不然就是示范代码,不是版本环境过时,就是裡面有错字。学生跑不起来。

如此吃力的学习环境,又没有成就感,是正常人都放弃。

就连我在学习编程语言时,都会选择近一两年的教材且有複制贴上范例的教材。

因为

  • 编程世界迭代之快,有可能用到了三四年前的教材,什麽都跑不起来。
  • 学编程打错字可能会搞死新手。就算是我这种老手,学新语言也发生这种事,我也吃不消。

观察流程并练习小套路

世界上上百套程式语言,可以说它们底层是相通的,但其实适用场景上不同。

所谓的底层相通,指的是

  1. method 的构建流程 (method 指的是我们会将一连串代码,包装成一段可以呼叫的代码块,这样遇到类似功能,就不用重新複制一排,直接呼叫就可以了。)
  2. if / else (遇到什麽状况、就执行什麽结果)
  3. for 迴圈(重複执行一段程式码几次)

如果你真的非常有兴趣学习编程,并希望透过比较无痛的方式,练习这三个概念。推荐可以去学习苹果在 iPad 上出的一套编程游戏,叫 Learn to Code。这套教材写的非常棒,念小学的小朋友也可以一下就上手,学会 iOS 上怎麽编程。

但是,每一套语言有各自优势的程式库与开发流程。

比如说我擅长的 Ruby on Rails 这套网站框架好了。最小的基本流程是 CRUD。

  • Create 创建资料
  • Read 读取渲染资料
  • Update 更新资料
  • Destroy 删除资料

动态网站开发,多半与资料库有关。所以学打造网站,知道怎麽显示页面 (HTML)、美化页面 (CSS/ JavaScript)、读取变更资料 (资料库)是开发一个网站要瞭解的方向。

所以当你学习 Ruby on Rails,最小学习单位就是 CRUD。练熟这套流程,相关的知识就有办法搭建上去。

而 iOS 的主要流程是 Screen + API。

iOS 的最小单位是一个 Screen。也就是你看的手机每一个屏幕(切换),就是最小的一个单位。一套手机程式,是由无数的屏 Screen 连接起来的。

于是你要学习的就是如何构建一个一个的屏,然后把屏串起来。而有些屏上的资料,需要由外界来提供,而外界提供的方式就是使用 API 界接。API 格式有可能是 CSV、也有可能是 JSON。或其他格式。

总之,每一门语言都有一个主流程,以及构成这个主流程相关的“大”关键字。

要学会“编程语言”,重点不是去背术语。而是

  1. 解构你要解决的问题,找到能够解决这门的适用工具
  2. 如果找不到适用工具,才考虑去找适用的工具语言
  3. 先不要急著按书上面或教材上的练,可以先观察一下整套语言的“流程”与“关键字”
  4. 找到几套教材,能够让你练习最基础的流程套路。把这一套小流程练个两三遍,你可以用非常拙劣但不会“卡住”的方法,拼接出你要的结果。
  5. 随著你的程式不断的练习改版,你的学习成果自然就会有快速的进步,进入超级正迴圈