三步解决所有编程领域问题
Kaffa 发布于 最后修改
问题解决是否有通用方法?
当然,先看看几个典型。
一、解数学题
我们做过很多的数学题,证明、计算、应用题,我们解数学题时通常需要:
- 先读懂题,了解已知条件与未知
- 如果从已知条件加上解题经验就可以抵达答案
- 是,即完成解题;
- 否则,则需要引入新知识;
- 验证是否解决
- 如果未解决,则跳到第1步
一图胜千言
从图上看解题家的能力在于读题能力和解题锦囊的大小,其中玄妙的一步在于“引入新知”。
二、造火箭
Musk 成功了领导了猎鹰运载和重载火箭的制造,如果解决造火箭这个问题具有通用方法,那么将领导者换作其它人,使用这个通用方法,是否可以制造一枚火箭呢?
理论上也许可行,但实操上几乎没人相信。
这里的第一个问题是提问不清晰:
制造一枚火箭这个问题很模糊,没有定义是模型,还是能飞上天的,还是能飞上火星的?
如果假设是能上火星的,还存在人的问题:
是一个人造,还是一个团队造?
假设是由笔者带上专家团队,还有新问题:
笔者是否具备管理团队的技能,会如何管理团队?
- 专家和其他团队成员、外界,与各利益方怎么沟通?
- 风险怎么管理?问题怎么处理?
- 进度、成本怎么控制?
- 质量怎么控制?
这些问题的答案指向——曼哈顿计划 [1] 在上世纪40年代,运用了一套通用方法论,现名为“项目管理”知识体系,它为解决类似造火箭的武器工程问题提供了一个解决方案,曼哈顿计划也是常被公认的第一个全面应用项目管理理念和技术的大型项目。当然,除了项目管理方法论,如果曼哈顿计划是属于炼金活动,可能还需要向炼金炉中投入至少一个 Einstein 和一个 Oppenheimer 吧。
《项目管理知识体系指南》(《PMBOK® 指南》)第六版中,定义的生命周期通常如下:
其中阶段间并没有明显的分割点,每个阶段又包含一些过程组:启动、规划、执行、监控、收尾。实际上是一些拆分的工作,这些工作又可以从10大知识领域去理解,即:整合、范围、进度、成本、质量、资源、沟通、风险、采购、相关方。
所以,造火箭所需要的是有投资方、人和组织资源的方法论。
三、打仗
如何在一场战争中获胜,显然和解一道数学题、造一枚火箭所使用的方法不一样。打仗不仅使用武器,还需掌握信息,使用兵法,进行决策。
“不战而屈人之兵”是战的最高境界,为达到这个境界,需要深入考察研究五个对象:道天地将法。简单地说:道是自然规律,天地是客观条件,将和法适配在项目上,就是项目管理方法论。
共性是什么?
看起来,从解数学题,到造火箭,再到打仗,复杂程度递增,这里想说的是三者之间的联系,如果将打仗比看作生物体,解数学题就是细胞,造火箭就是组织。打仗所需要的思路和能力,并不超出解数学题和造火箭。
在不同复杂程度上的 Problem,都有解决方法论。对于 problem-solving,我能想到的最深刻的模式就是学习和理解本身,更可以说所有问题的解决会回归到一个字——懂。
如果把最能解决问题的人定义为“懂王”,那么阻碍大家成为懂王的最大的障碍就是绝对难度。
在解数学题的层面上,一个未知因素会导致绝对难度的产生,这个未知因素往往是带着一些“折叠的结构”,比如一种快速开平方的方法,一种求最大公约数的欧几里德算法(Euclidean algorithm),这些翻译中通常有叫做 Method。
在造火箭的层面上,基础科学的问题,人的能力的问题会成为绝对难度。
在打仗的层面上,战略决策,优先级和最优解是绝对难度。
但在这三个领域都有做得非常棒的人,这说明两点:
- 在TA们的思维中建立了领域问题解决的通用方法;
- 在TA们的经验中,有足够的“折叠的结构”以解决复杂度。
编程领域的问题解决是否有通用方法?
从抽象到具体,在编程领域的问题解决是否有通用方法?
首先说我的结论,编程领域的问题难有通用解法,主要因为“编程领域”是一个经典概念。语言学中,经典概念属于人与人交流中的模糊地带,并没有明确的范围,很难说编程中遇到的某个问题是属于编程领域,还是非编程领域。所以,严格来说,编程领域的问题没有通解。
其次,虽然没有通用解法,但存在有效方法。有效方法是指,一个问题采用一种方法后,可验证是否解决。所以,我们讨论的“编程领域”问题虽然没有通解,但可以采用经验去推演,或者在已知解空间去搜索。
为什么会有编程领域的难题?
现实世界很复杂,编程是世界的抽象和理想模型,理想和现实的差距存在于细节上,编程经常会遇到这些细节带来的鸿沟。
那有效方法是什么?
我的方法提炼就剩下三个字:懂、干、议
- 懂
如何衡量懂,窍门在于依赖自我认知,补全假设,然后提问。
内求:可以自问,独立思考后推演后自答;
参考书 《思考的艺术》
一般来讲,大多数问题都是读的太少而想的太多带来的。我接触到的编程领域,从计算机系统结构,到网络,到编程语言,到软件工程,在时间允许的情况下,我总推荐独立阅读和思考的方式来解决。
外求:可以通过寻找能解决的人群和社区,逐步搜索,然后提问,找到合适的人,追问。
参考书 《学会提问》
为了解决一个具体问题,第一步是将问题定义清楚,第二步将问题复杂度降维,例如采用正交的方式分解。在决定向外部求助时,首选当然是浏览官方网站文档,毫无疑问,这是最新一手参考资料。如果再推荐一个有效而快速的解决,无疑是 StackOverFlow 和 ChatGPT
- 干
- 议
采用搜索解决问题的捷径是知识树
- 按平台和设备
- 桌面系统
- Windows:最佳效率桌面系统,更能打
- macOS:更有设计
- GUN/Linux:建议玩 Debian 或 Ubuntu
- Debian:以服务稳定闻名
- Ubuntu:最流行易用
- openSUSE:界面好看
- Fedora:RHEL创新实验田
- CentOS:以前是一个靠谱的服务器版选择
- CentOS Stream:若有选择,可不选它
- Arch Linux:有品位的专家玩家爱用
- Gentoo:开局一堆码,功能全靠编
- Manjaro:不失为一个好选择
- Raspbian:极客爱玩
- Deepin:中文玩家适用
- 中标麒麟:政府采购较多
- Unix
- FreeBSD:玩BSD桌面首选
- OpenBSD:最安全的系统
- NetBSD:多CPU架构
- Chrome OS:基于浏览器的计算环境
- Xfce:轻量级多媒体桌面
- 移动设备
- Android:移动设备半边天
- iOS:昂贵流畅的算力
- Windows Phone:输在放弃
- Firefox OS:低端机好用,已弃
- Sailfish/Meego:寄予厚望却错过时代
- Sybian/WinCE/PalmOS/NucleusOS:已是历史
- 纯血鸿蒙:孕育中
- 穿戴设备
- watchOS:目前最成功的手表OS
- Android Wear:没有机会用,也不打算用
- 平板设备
- iPad:打破PC思维,基于场景的资讯、娱乐和媒体平台
- Android Tablet:生产力平板
- Kindle:读书人最好
- Windows RT:不能运行传统程序的 Windows 大家不买单
- 浏览器
- Trident:作古
- Webkit:将作古
- Gecko:作古
- Presto:有前景
- Servo:有前景
- Blink:有前景
- Web
- Java:对程序员友好的平台
- .Net:一种相对优秀的方案
- PHP:互联网内容基础,开源成品程序最多
- Python:并不快,但相伴金融、科学和 AI 友好
- Rust:未来的基础设施
- Go:介于 C 和 Rust 之间
- Ruby:爱用的人最爱用
- 按语言:
- 按类型模型
- 强类型
- 弱类型
- 按范式
- 面向对象
- 函数式
- 过程式
- 多范式
- 按交互
- 编译型
- 解释型
- 按热度
- 不会不好意思打招呼系列
- JavaScript / ECMAScript
- HTML / XML
- CSS
- 大公司都用系列
- C/C++
- Java
- 创业公司都用系列
- PHP
- Python
- 聪明系列
- C#
- Delphi
- 敏捷系列
- Ruby / RoR
- PHP / Laravel
- Python / Django
- 有钱景/有局限/不好用系列
- Rust
- Go
- TypeScript
- Kotlin
- Swift
- 科研系列
- F#
- R
- Matlab
- 极客系列
- Clojure
- Scala
- Perl
- Assembly
- Rust
编程领域问题的根本难度
编程领域问题不仅仅只有分类,金字塔原理,分类是一种通用且重要的思维模式,解决问题最终依赖的是网状的知识图谱。从长远来看问题的解决最终依赖于自我的学习力,而决定编程领域问题的根本难度可能在于:
- 语言障碍
语言学习本身不是短时间能解决的问题,所以如果当待解决的问题所依赖的知识与提问的人之间存在语言障碍,那么解决此问题将会面临一个较高难度。
- 自我认知
有一本书叫做《提问的艺术》可以参考。从测试的角度上,一个好提问,需给回答的人创造一个条件,方便回答者重现或进入问题的场景,一个自我认知好的人容易提好问题。
结论
- 计算理论是经证明的,编程领域属于应用领域,并不存在绝对难度的问题,只有对资源的权衡和妥协。
- 编程领域问题最难的不在事,而在人。
- 编程领域没有通用解法,只有相对有效的方法。
- 如果三步能解决所有编程领域的问题那就是:一、懂;二、干;三、循环一和二直到完成。
脚注
[1] | 曼哈顿计划:美国陆军部于1942年6月开始利用核裂变反应来研制原子弹的计划。 |