昨天突然想到一个问题, 就是非计算机专业入门编程的时候, 为什么这么难

想了一下, 主要原因可能包括但不限于

  • 没有很好的导师
  • 没有持之以恒
  • 本身的能力
  • 学习方式
  • 实践方式

之前刚大一的时候, 入门是 C 语言, 大部分都是没有任何编程基础的. 那个时候, 根本不知道自己适不适合编程. 只是说, 专业选了这一门, 学不会也要硬着头皮去学这样的想法. 但是在后来学习的过程中, 我感觉自己就是天生的程序员. 入门之后, 我已经发现自己可以不靠任何人去接触一门全新的语言

到现在为止, 已经入门前端 (HTML + CSS + JavaScript) 和 PHP. 只是还没有开始接触中大型项目开发

去 bccn 看了一下新手提问的问题, 突然有点想法, 可能是他们根本没有深入理解编程模型 (非网上定义的编程模型). 于是, 立马把想法记录下来

上面说, 非网上定义的编程模型, 那么这里就需要按照本人自己的想法重新定义一下

1. 编程模型分支 - 语句

每一个语句, 到结束 (可能是分号, 当然有些高级语言可能不需要结束符) 为止, 都可以把它看作一条命令. 一个上司对于下属宣读的命令

这里, 你就是上司, 你的电脑 (或者说你用的编译器 IDE) 就是你的下属. 下属不得不服从上司的命令, 于是需要执行你宣布的每一条命令 (语句)

但是这个下属不蠢, 你让他吃屎, 它不会去吃屎 (语法错误). 它会去检查一下, 你给的这个东西 (语句) 到底是不是屎 (是否存在语法错误)

你让一个真人去吃屎, 正常人肯定不会干. 于是, 这个时候, 你的下属 (IDE) 给你报了个错, 老子不干了

直到你给出的语句, 每一句都是畅通的, 并且不存在语法错误. 这个时候, 你的命令是正常而且合理, 你的下属不得不服从你的命令, 于是开始执行

2. 编程模型分支 - 注释

很多人讨厌写注释, 我也讨厌

注释写给谁看? 又没有人去看你的代码, 你以为我的老师这么闲, 去看每个人的程序吗?

很多大学生刚入门编程的时候, 都是这个想法

现在你用不到, 这个是可以肯定的. 因为你自己开发的很多程序, 很多时候, 你自己都不需要去重新看, 写完就扔掉了. 更不会说, 有人会拿你写的程序去二次开发. 但是团队协作的时候, 就不一样了, 特别是那些不按常理出牌, 乱起名字的

你 var 个 a, 鬼知道你这是什么东西. 如果你真的不好好起名字, 注释是非常必要的

另外, 就算你好好起名字, 注释也是必要的

你写了个函数, 程序员去仔细阅读, 结合函数名其实可以猜出是用于干什么. 但是, 这会大大减少开发效率, 如果你直接写个注释告诉程序员, 你这段代码是用于干嘛的, 这个程序员阅读没问题的话, 可以在一秒钟读完. 比起花费几分钟去阅读代码, 这不是更好吗?

其实在日常生活中, 注释就相当于产品说明书. 你拿到一个你十分陌生, 不知道是什么东西, 你从来没有见过的, 你肯定不知道如何去使用, 某些功能用于干什么. 这个时候你就去阅读说明书, 假如没有说明书, 你就要一个一个功能去研究, 不但耗费时间, 还耗费你的脑力 (可能不会耗费我的脑力, 因为一般几分钟研究不出来我就直接砸掉... 开个玩笑). 比起你看说明书, 只要你认识字, 就基本不会出现看不懂的情况, 那么花费几秒钟去阅读和你根本研究不出来这是干嘛的或者花费几分钟去研究, 不是更好吗

从产品设计者的角度来说, 他们设计这个产品, 用途是什么他们肯定是清楚过我们的, 他们写说明书是给自己看的吗? 肯定不是. 说明书是写给别人看的. 去大街上随便买个产品, 就算没有纸质的说明书, 产品的包装上也会写明一些基本的使用方法

从产品说明书到代码注释, 其实反应的是同样一个问题. 我同样愿意相信, 很多产品设计者不想写产品说明书的情景

3. 编程模型分支 - 常量与变量

当你宣告一个常量和变量的时候, 必须用一个语句. 这个语句可能包括类型、名字、具体值

如果把这个映射在生活中, 你就可能发现, 很多地方都会有类似的地方 : 比如人

人身上一些地方反应了常量, 常量是不可能改变的. 那么, 你的出生地址, 出生时间. 你的姓名或者身份证号码原则上是不允许更改的, 但是在特殊情况下, 更改他们是没有问题的. 但是你有办法去更改你的出生地址和出生时间吗? 显然不可能

另外, 你的身高、体重和年龄等等, 这些都是在不断改变的, 这就是变量. 在一定条件下, 你可以对它进行适当的改变

Jonny 的身高为 175

这句话如果在编程中, 可以如何表达呢?

Jonny stature = 175

Jonny 是一个类型, 某些值只能用于这个类型下

stature是一个变量名称

175 是变量具体对应值

4. 编程模型分支 - 数组

有时候, 需要把一些有相互关系的变量放在一起, 这个时候就需要用到数组

数组在编程中的用途十分广泛, 特别是高级语言中, 数组变得越来越方便

Swift 中有元组、数组、字典

PHP 中有数组、关联数组

如果把数组放在生活中呢? 你可以把数组看作一本书

在一本书中, 每一页之间的相互影响非常大吗? 好像又不是, 但是如果把每一页都分开, 分给不同的人看呢? 这样, 这些页数之间的关联可能就非常大了, 因为不同的人可能对每一页的单独理解都不同, 甚至根本看不懂

当把这些页数装订成一本书, 用一个封面去封装的时候, 再发给不同的人看呢? 这个时候相信很多人都可以读懂这本书

书的封面就相当于数组的名称, 书就是一个类型 (数组也是一个类型). 书的目录就相当于数组的索引, 目录对应的页面的具体内容就相当于数组的索引值

如果以这种方式去理解数组, 应该不会很难了吧

5. 编程模型分支 - 操作符

操作符是把变量之间进行组合, 组成一个新的变量. 可能不需要相同类型, 因为在 PHP 中, string 和 int 相加, 最后等于 int 类型变量的值 (string 类型对应的变量在相加的过程中相当于 0)

学过数学的人, 基本都会用操作符. 但是有多少人去想过, 生活中有哪些东西有着操作符的影子呢?

这里举个例子, 数据线

当你想把电脑里的照片导入手机的时候 (两个设备的照片相加, 存在一个设备里, 用表达式去表达 : a = a + b), 如果没有 AirDrop 和 网路传输, 就需要一个东西 --- 数据线

在编程中, 操作符就是那一根数据线, 你可以把两个变量通过操作符连通赋予到一个新的变量上 (这个时候需要两根数据线, 一根代表着操作符, 另外一根代表着 "=")

6. 编程模型分支 - 函数

在编程的时候, 当你开始学习函数, 你自己可能没有意识到, 你已经开始对你的代码进行封装. 只是在有需要的时候, 才进行调用. 而不是像你之前一样, 一大堆语句串在一起

函数会让你的代码更加清晰, 增加了代码的易读性 (因为很多函数, 直接从函数名字就可以知道函数的具体用途是什么) , 而且很多人并不会去跳转到函数的定义那边具体去阅读你的函数是如何实现的

其实函数在日常生活中, 就像一个按钮一样, 你要用到的时候, 去按一下就会自动启动. 这个按钮起动之后, 会自动帮你完成一些繁琐或者你做不到的事情. 你只需要知道按下去之后用于干什么, 而不需要知道这个按钮按下去之后有的功能具体是如何实现的

按钮其实就是对一些功能进行封装. 在编程中, 你同样需要对一些代码进行封装, 函数就是一个非常好的选择

在编程的过程中, 多使用函数, 可以让你在调试的时候, 省去很多时间

7. 编程模型分支 - 条件判断

绝大多数语言的条件判断其实就是四种

  • if
  • if ... else
  • if ... else if ... else
  • switch

目前我学过的, C、C++、PHP 和 Swift 的条件判断都是这四种

条件判断的模型, 仔细一想, 其实就是开关

单纯的 if 语句 和 if ... else 语句其实就是一个只有两边的开关, 要么上, 要么下. 多重的条件判断语句其实就是一个多重开关, 像手电筒的开关一样, 不同的地方有不同的模式

8. 编程模型分支 - 循环

一般入门一门新的计算机编程语言的时候, 一般的学习顺序是常量与变量 -> 条件判断 -> 循环

到循环这里, 可能会难住很多人. 这是第一个分水岭, 如果能跨过去, 后面的学习可能会轻松. 如果你跨不过去, 一直是处于一知半解的状态, 老师上课讲, 你听不懂, 下课又不去重新复习. 这样的状态下, 你很可能会与其他人从这里开始拉开差距, 最后到后面的枚举、结构体到类, 越来越难. 一开始只是简单的不会, 到后面什么都不会. 因为你会发现, 很多地方都是需要用到循环. 最后别人已经入门了, 你还在门外或者被门夹着, 导致你会放弃

其实循环真的理解了, 并不是非常难. 你可以想象成供电

在生活中, 电灯要想点亮, 首先必须要开启开关, 并且之后必须有源源不断的电源供电才可以保持常亮. 当你关掉了电灯的开关, 点电灯就熄灭了

这个简单的模型在编程中, 就是循环

开启开关就是循环进入的条件, 源源不断的电源就是在循环条件之内, 关闭开关就是循环条件超出预设, 跳出循环, 循环结束

9. 编程模型分支 - 对象

对象在编程中非常重要, 有一个思想叫做面向对象

当然这了对于入门的来说, 也是一个分水岭

不过学完对象, 可能会有这样一个感觉 : 没什么用... 还是那句话, 现在没什么用不代表将来没什么用

对象是最重要的编程模型, 你在生活中看到一部 法拉利跑车, 你会自然而然想到车的模型; 你在生活中看到一部 iPhone, 你肯定也会想到手机这个模型. 手机和车其实都是一个大类, iPhone 和 法拉利 其实是大类中不断延伸和拓展的产物

在面向对象编程的过程中, 你可以设置对象属性和方法的来构建对象的基础模型. 之后可以通过继承的方式不断丰富对象. 在这个过程中, 我们可以拿房子来举例子

在 PHP 编程中, 有一个抽象类. 这个就相当于房子的地基, 你写出的抽象类是为了之后的类打基础. 之后你会去继承抽象类完成里面的函数, 这个过程可以看成是建立房子的初始内部结构. 里面有两个特殊的方法 --- 构造方法和析构方法. 这两个就相当房子的买卖, 当你想要买入房子的时候, 就相当于执行一次构造方法. 当你想要卖掉房子的时候, 就相当于执行一次析构方法. 你构造之后, 房子就归属于你 (这里可以把房子看成一个类, 你看作是 <?php?>); 你析构之后, 房子就不属于你, 相应的变量在内存中被销毁

然后你不断地为房子进行装修和添置家具. 这个过程就是你为类创建新的属性和方法. 你想要房子豪华, 你的类属性可能会很多; 你想要房子的家具多, 就相当于你的类方法会很丰富

之后, 对于已经居住很久的房子, 你突然想要为其添加新的家具, 例如钢琴、游戏厅和音乐室等等, 你可以进行继承. 钢琴就是你继承类中新的属性, 这个属性是父类里面没有的. 游戏厅和音乐室就相当于重写父类中已经存在的函数

完成之后, 进行宣告, 你就可以使用这个对象并且用于各种用途. 这就相当于你开始入住并且开始享受这个新房子给你带来的便利

这个就是面向对象的思想, 其实在很多程序员眼里, 万物都可以是对象. 万物都可以被拆成属性和方法

10. 编程模型组合 - 函数内包含条件判断和循环

综合应用编程语言的语法是每个程序员的基本功, 可以说绝大多数程序仅仅靠单个分支几乎是不可能完成的. 总有一些地方需要进行组合之后才能实现理想的功能

在这里只举一个例子, 就是函数内包含条件判断和循环在编程模型中, 可以如何进行想象

你有 10 张废纸, 需要你将它们全部扔进垃圾箱并且正确分类

你扔垃圾, 其实就是一个函数的模型. 因为我们经常做, 所以知道如何去做. 如果交给机器人呢? 那么就要调用扔垃圾的函数

那么这个函数如何去实现呢?

正确分类和 10 张废纸就包含了条件选择和循环的模型

10 张废纸都是属于可回收垃圾, 那么肯定要扔进可回收垃圾对应的垃圾桶. 如果对应的垃圾不是可回收的, 就扔进另外的垃圾桶; 如果是有害的, 那么扔到有害垃圾回收的垃圾桶. 这里有三个选择, 编程的时候可以选择 if ... else if ... else 语句. 10 张废纸都需要扔, 那么这里就有一个循环, 条件开始是第一张废纸, 条件结束是 10 张废纸都被扔完了, 没有废纸了. 在编程的过程中, 三个基本循环语句都可以采用

11. 编程模型思想 - 分解

如果让我去说什么是编程, 我会说 : 用语句去告诉计算机如何一步一步去做

一步一步去做, 即分解

如果我们要用程序解决一个问题, 可以分解这个大问题为 n 个小问题, 然后分别用不同的函数和部分去解决

例如, 我要做一个程序, 实现两个人在有网络的情况下可以相互聊天

这个聊天程序就是一个大问题, 我们需要分解成 n 个小问题去解决

举几个例子 :

  • 两个人如何聊天 --- 聊天窗口
  • 数据如何传输 --- 从 A 用户客户端传输到服务器, 再由服务器传输到 B 用户的客户端
  • 数据如何保存 --- 服务端利用日志文件去保存

你还可以在此基础上建立更多的问题分支, 越多的问题分支就代表你的程序功能越丰富

接下来我们需要一步一步去用代码解决这些问题, 当全部都解决, 并且封装成一个程序的时候, 客户端就完成了

上面是一条就是我所总结的编程模型

如果新手真正按照上面的模型去理解编程, 我相信几乎所有智商正常的人都能入门编程, 即使是像 C 一样比较难的语言

纯手打难免会出现一些字打少或者打多、语病和错别字, 欢迎指出