(之前一篇微博,反馈还不错,于是展开写了下。有点散,将就看吧 )
会了语法,写不好程序
《后会无期》里边有一句被引用过无数次的话。
不对,不是这句 是「听过了很多道理,却依然过不好这一生」。
一直有同学问我,为啥「 明明已经学会了语法,却总是写不好程序 」。
最开始我只是简单的认为,这可能是实践太少的原因,但后来慢慢发现,这可能是 编程教学中存在的一个普遍问题 。
一
编程教学并不等于语言教学
我大致扫了一下现在市面上免费的分享和收费的课程,发现它们可以分成两种。
一种是非常纯粹的语言教学 ,甚至内容都大同小异,基本是手册的翻版,再加上一些有用或者无用的例子。稍微好一点的,会加上一些实践课程,但因为课时和定位的原因,覆盖很难全面。
另一类则是相对零散的知识分享 ,比如「使用Swoole构建基于PHP的高性能微服务」、「Gin构建API Server的踩坑」。
不是说这两类内容没用,它们非常有用;但是,在通往写出、写好程序和软件的道路上,我们还缺失了一些东西。用图来表示的话,大概这样:
那么中间到底缺失了什么?我觉得主要缺两样东西, 写不出程序是缺「编程思维」,写不好程序是缺「领域知识」。
二
语言背后的领域知识
由于编程语言百家争鸣,我们往往过多的将注意力放到了语言上边。也可能是因为做语言课最简单还最好卖,所以课程也都集中在了语言这边。
但当你学会数种语言,写过N多程序以后,回过头来看时,会发现 它们其实都在解决同样的问题 。这就是 由大量类似需求构成的场景及其解决方案 ,这里我们暂且叫它「 领域知识 」吧。
这类知识有点类似于经验值,是在实战操作中累积下来的。比如你负责的项目需要用到微信支付,于是你花一周读文档,花一周开发,花一周上线,花一周修bug,再花一周读文档,最终弄明白了网络支付的流程和微信平台授权的套路。这些知识就是 领域知识 。
领域知识和语言的语法没太大关系,而 和你所出的行业密切相关 。有的领域知识,比如高性能架构和优化相关的,可能决定了你编程水平的高低;而有的领域知识,比如海外支付接口的接入,可能「用不到的时候没用,用到的时候不够用」。
三
编程思维
培养编程思维首先我觉得需要理解软件的 本质、分类和对应的构成 。
软件的本质
从商业角度讲,编写软件就是 在不断的制造「24小时不间断、并可以精准完成工作」的数字化的机器人 。人类的本质是复读机,软件的本质是更好的复读机。为什么软件能吞噬世界,因为它一直在不断取代人类,完成那些人类可以、甚至不可以完成的工作。
所以所谓 编程 , 其实就是抽象人类的重复劳动,将其封装为可重用的命令的过程 。现在因为机器人和IOT还不够发达,所以这部分工作还局限于电脑、手机之中。未来十到二十年,这些工作会进一步扩大,甚至有可能覆盖所有场所。现在所谓的「产业互联网」,就是想进一步扩散到工厂及其相关场景中。
而 编程思维就是从一堆的重复行为中抽象出函数的思维 。比如,你是一个前台,每天有一项工作就是检查下班后公司的灯有没有全部关掉。那么这个函数的输入就是下班时间时公司的灯的状况,过程就是没关的要想办法关,想办法也关不掉的要报告上级(抛出异常),函数的输出就是一个布尔值,关灯成功或者失败。
将问题细分下,就会变成 「如何获取输入」的问题 ,比如我们可以弄个摄像头来拍照,然后确认照片的颜色均值,也可以从智能插座的状态那里通过接口读取。以及 「如何输出的问题」 ,比如可以调用SMTP发送邮件,或者可以对接Server酱,推送通知到微信。
整个编程过程就由这样的小问题累积起来。
软件的分类和结构
分类方式甚多,但我比较喜欢将软件分为 单机软件和联机软件 。然后联机软件分为 B/S和C/S结构 ,大体可以对应「网站」和「APP」。
从实用角度讲,软件最核心的构成是 「界面」和「业务逻辑」 。界面获取输入、展示输出,是我们和机器打交道的地方。业务逻辑将输入进行加工,产生输出,是函数内部的实现。
为了更好的支持这些行为,我们还需要 「存储」 来持久化的存放数据,需要 「网络」 来进行数据传输。
「数据流动」 是整个软件的核心,我们如何获取数据、如何校验数据、如何加工数据、如何将其存储、如何对其查询、如何包装输出、如何使其可视化…… 弄清楚了这些知识,我们也就弄明白了如何写出程序。
四
网站和云的领域知识
在B/S和C/S结构里,C/S部分往往和对应的平台密切相关。比如苹果的应用开发,就需要用到大量iOS的知识和模式。我自己的背景主要在网站和云这边,所以这里简单列举下我觉得比较通用的领域知识。
软件/网站架构
输入校验 ( 前端和后端如何校验输入、正则表达式、错误提示、以及如何和多语言整合)
图片和大文件上传 ( 服务器端压缩、存储、以及稍后的按需展示;超大文件如何断点上传,服务器如何支持range,如何通过XSend之类方案处理带权限校验的大文件下载 )
认证 ( BASIC、OAUTH的基本知识和流程;JWT )
密码管理 ( 如何安全的存储密码,随机数和盐 )
路由设计 ( 服务器端和浏览器端(SPA)中的路由方案,参数如何传递、页面栈如何处理等 )
缓存 ( 整个数据流动中哪些地方可以添加缓存,缓存方案有哪些,缓存算法如何设计 )
错误处理 ( 如何简洁高效的处理错误,如何根据错误信息定位和调试问题,调用栈 )
多语言 ( 基本库的使用、前端和后端如何统一配合 )
数据库 ( 索引和优化、主从分离、分库分表 )
云架构
域名和DNS
CDN
负载均衡
反向代理
缓存
消息队列
弹性IP
私有网络
微服务架构
容器和Docker
API网关
服务发现
服务容错
服务部署
互联网应用架构实例
信息流
消息系统
视频和直播
LBS相关
推荐系统
物联网和智能硬件
清单就先简单写到这里,供大家查漏补缺找资料看。 欢迎在留言中补充。
话说其实学习新知识还是挺有趣的,之前看了下 draft.js 设计过程的分享视频,知道了很多关于富文本编辑器的细节 (坑) 。
技术总结
下边开始今天的技术总结。
语法教学不是编程教学的全部,只是开始
你需要掌握编程思维和领域知识来解决业务问题
分享对软件的个人理解,并尝试给出一个B/S方向的领域知识树
因为更新 太不规律 ,所以开一个订阅通道
扫码关注 即可订阅
「方糖气球:balloon:文章更新」