第1章 走进编程思维:像计算机科学家一样思考
第1章 走进编程思维:像计算机科学家一样思考
很多人一听到"编程思维"四个字,第一反应是:那是程序员的事,是写代码的人需要掌握的技能,与我无关。事实上,编程思维并不是某种只有程序员才能拥有的特殊才能,它是一套结构化的解决问题方法论——把一个看似模糊、复杂、无从下手的问题,拆解成可执行的、可验证的步骤,然后用清晰的语言或符号表达出来。无论你是否写代码,这套方法都能帮你把日常工作和生活中的混乱局面理出头绪。
本章将围绕一个核心问题展开:编程思维到底是什么?它和日常思考有什么不同? 我们会先破除编程的神秘感,再用做饭、出行等生活场景做类比,让你在熟悉的经验中感受到编程思维的真实形状;接着拆解编程思维的四大支柱——问题分解、模式识别、抽象建模、算法设计,并通过"整理书桌"和"规划周末出行"两个微型案例,让你亲眼看到这些支柱如何落地。最后给出本书的整体学习路线图,帮助你决定如何阅读、使用这本书。
1.1 破除编程神秘感:编程思维是一种通用的问题解决方法论
编程思维不是"写代码"
很多人把"编程"和"写代码"画上等号,于是把"编程思维"也理解成"写出代码的思维方式"。这是本书首先要纠正的认知偏差。编程的本质是解决问题,写代码只是解决问题时的一种表达工具。 同样一种思维方式,可以用来写 Python,也可以用来规划一次家庭旅行、安排一个项目的进度、甚至设计一次搬家流程。
举一个直观的例子。当你决定今晚要做一道番茄炒蛋时,你的脑子在做什么?你会先想"需要几个番茄、几个鸡蛋",然后想"是先炒蛋还是先炒番茄",再想"火候多大、放多少盐"。这一系列思考,本质上就是程序:原料是输入,步骤是顺序判断,最终端上桌的菜是输出。如果把你脑海中的流程写下来,几乎就是一份简易的算法描述。
再举一个反向例子。有些人学了几年编程语言,能写出语法漂亮的代码,但面对"为什么这个用户流失了""为什么这个月的销售额下滑"这类问题时依然无从下手。问题出在他只学会了"翻译"——把脑子里的步骤翻译成 Python 或 Java——却没有学会"思考"——如何把模糊的问题转化为可分析的对象。真正的编程思维发生在写代码之前,是关于"如何想清楚"的能力,而不是"如何敲出来"的能力。
编程思维的本质:把模糊变清晰
日常思考常常是跳跃的、发散的、依赖直觉的。比如你接到一个任务:"帮公司准备下一季度的市场推广方案。" 你可能会立刻开始想活动形式、预算、投放渠道,但很快发现每个方向都有说不清的地方,越想越乱。
编程思维训练你做的是另一件事:先把任务拆成可回答的问题。 推广方案的目标是什么?目标受众是谁?预算上限是多少?时间节点有哪些?竞争对手在做什么?历史数据中有哪些可以借鉴的规律?当你把这十几个问题列出来,原本一个模糊的大任务,就变成了一系列可以分别回答的小问题。回答完每一个小问题,再把它们综合起来,方案自然就浮现了。
这个"把模糊问题结构化"的过程,就是编程思维的核心。它有三个特征:
1. 可拆解:大问题可以分解成小问题。 2. 可命名:每一步都有明确的输入、输出、规则。 3. 可验证:每一步的结果可以被检查、对错可以判断。
任何具备这三个特征的问题,都可以套用编程思维来处理。换句话说,编程思维不是程序员的专属,而是面对任何复杂任务时都值得养成的一种思维习惯。
编程思维的现实价值
你可能会问:在 AI 已经能写代码的今天,还要不要学编程思维?答案是肯定的,而且比以往更重要。原因有三:
第一,AI 能写出语法正确的代码,但很难替你判断"这个问题该不该用程序解决、该怎么定义、边界在哪里"。这些判断恰好是编程思维要训练的能力。如果你没有结构化的思考能力,你甚至无法判断 AI 给出的方案是否合理。
第二,编程思维带来的副产品是可迁移的。它训练的是你分解、抽象、识别规律、安排步骤的能力,这些能力在做项目管理、做研究、写商业计划书、做家务规划时同样管用。
第三,编程思维让你更善于和"系统"打交道。无论是公司的报销系统、银行的客服流程,还是自动化办公工具,理解其背后的规则和逻辑,都能让你用得更好、修得更快。
所以无论你是想成为专业程序员,还是只想让自己处理问题更高效,编程思维都值得投入时间学习。
1.2 生活化类比理解:从做饭、出行等场景切入
编程思维听起来抽象,最快的入门方式是把它映射到你已经熟悉的生活场景。下面三个类比,覆盖了从日常琐事到中等复杂度的规划任务,可以帮你建立直观印象。
类比一:做菜 = 算法
做一道菜的过程,几乎完美对应一个算法的结构:
- **输入(原料)**:番茄两个、鸡蛋三个、葱一根、盐适量、油适量。
- **处理步骤**:洗番茄、切块、打蛋、热油、先炒蛋盛出、再炒番茄、倒回鸡蛋、加盐、起锅。
- **输出(结果)**:一盘番茄炒蛋。
- **判断与分支**:番茄太酸就加一点糖;喜欢嫩一点就缩短炒蛋时间。
- **循环**:如果做多人份,就按比例把原料乘以倍数。
任何一个会做饭的人,脑子里都已经天然在跑"算法"。差别只在于:菜谱把这套算法写成了文字,而程序员把这套算法写成了代码。把这个类比反过来用——以后你看到任何算法描述,都可以在脑海里想象它是一份菜谱。原料是什么?步骤是什么?有什么分支?输出长什么样?想清楚这四点,你就懂了这个算法的一半。
类比二:出行规划 = 问题分解
计划一次周末两天的短途旅行,是经典的"编程思维训练场"。原始需求可能是:"周末想去周边玩一下。" 这句话几乎不可执行,必须分解。
第一步,按时间维度拆:
- 周六上午出发还是下午出发?
- 周六晚上住哪里?
- 周日几点返回?
第二步,按内容维度拆:
- 去哪里?候选地点 A、B、C 各自的特色是什么?
- 交通方式?自驾、火车、跟团?
- 预算上限?
- 必去的景点 vs 可选景点?
- 餐饮偏好?
第三步,按风险维度拆:
- 天气不好怎么办?Plan B 是什么?
- 预订是否可取消?
- 紧急联系方式?
当这三类问题都拆完之后,原本模糊的"周末想出去玩"就变成了一个可执行清单:周六 8 点自驾出发到 A 地,10 点到访景点 X,午餐在 X 附近的 Y 餐厅,下午游景点 Z,傍晚入住 W 酒店,周日 9 点早餐后游 Q 景点,13 点午餐后返程。 整个过程,就是把一个不确定的需求分解、命名、排序、组合的过程——和软件工程师接到产品需求时做的事情别无二致。
类比三:整理房间 = 抽象与模式识别
再举一个更接地气的例子。整理一个乱七八糟的房间,听起来和编程无关,但你仔细看会发现,里面藏着大量"抽象"和"模式识别"。
抽象是把具体的物品按特征归类的过程。你不会一个一个物品决定放哪,而是先定义"类别"——书、衣服、电子产品、杂物——再按类别决定摆放位置。这就是从"具体事物"上升到"概念类别"的过程,正是抽象的核心。
模式识别是发现重复规律的过程。比如你发现每次整理完房间,三天之内书桌又会变乱,原因是书桌抽屉太浅、文具太多。识别出这个模式后,你就有了改进方案:换更深的抽屉,或者把常用文具挂到桌边,而不是反复整理。
整理房间是这样,写程序也是这样。程序员面对一个复杂系统,第一步永远是定义概念(这就是抽象),然后观察哪些问题反复出现(这就是模式识别),最后决定哪些模式要保留、哪些要消除。
类比的价值:降低学习阻力
之所以在介绍正式概念之前先讲类比,是因为编程思维的每一条原则都不是凭空发明的,它从人类几千年的生活经验中提炼出来。 你并不是在学一门新能力,而是在用一套更精确的语言描述你本来就会的东西。一旦你意识到这一点,学习阻力会大幅下降。
接下来,我们就把这些生活直觉正式化,看看编程思维的四大支柱到底分别是什么,又是怎么协作的。
1.3 编程思维四大支柱:分解、模式识别、抽象、算法设计
学界对"计算思维"或"编程思维"的拆解有多种版本,本书采用最经典也最易上手的四支柱模型:问题分解、模式识别、抽象建模、算法设计。这四个支柱不是孤立的技能,它们在每一次完整的思考过程中依次登场、相互嵌套。
下面是它们的核心关系:
```mermaid flowchart TD A[Programming Thinking] --> B[Decomposition] A --> C[Pattern Recognition] A --> D[Abstraction] A --> E[Algorithm Design] B --> F[Solve Complex Problems] C --> F D --> F E --> F E --> B E --> D ```
这张图给出了两个层次的含义。第一层:四大支柱共同支撑起"解决复杂问题"这一目标。第二层:算法设计这一支柱处于下游,它消费前三个支柱的产物——一个好的算法,往往建立在清晰的分解、扎实的模式识别、恰当的抽象之上。下面逐一展开。
支柱一:问题分解(Decomposition)
问题分解是把一个复杂、模糊的大问题,拆分成若干个可以独立解决的小问题的能力。 拆分的方法有两种常见思路:按时间顺序拆(先做什么、后做什么)和按结构拆(这件事由哪几部分组成)。
按时间顺序拆,得到的产物是"步骤序列"。比如搬家,第一步打包、第二步联系车辆、第三步搬运、第四步归位。按结构拆,得到的产物是"模块清单"。比如办一场婚礼,需要分解为场地、司仪、摄影、餐饮、流程设计、应急预案等模块。
判断分解是否到位,有一个简单的标准:拆分出来的每一小块,是否都能被独立理解、独立完成? 如果某一块还包含"再想想看""看情况而定"这种模糊语言,说明分解得还不够细,需要继续拆。
分解能力的培养,本书第 2 章到第 4 章会专门展开。
支柱二:模式识别(Pattern Recognition)
模式识别是在看似不同的事物之间,发现共通规律的能力。 同样的需求经常出现,意味着背后有规律;有规律,就可以用同一个办法处理。
最常见的模式识别有两种形式:
1. 重复模式:今天要按学号排序一份名单,明天要按工号排序一份员工表。看起来任务不同,本质都是"按某种关键字排序"。一旦识别出这是同一个模式,解决方案就能复用。 2. 差异模式:周一处理订单 A 发现要核对收货地址,周三处理订单 B 又要核对收货地址。重复出现意味着这是一个固定环节,应该被列入"订单处理标准流程"。
模式识别不是简单的"我见过",而是"我能提炼出规则"。识别模式之后,你应该能用一句话把规则说出来,比如"凡是涉及对外付款,都需要双人复核"。这句话就是规则,就可以变成流程、变成程序、变成检查清单。
支柱三:抽象建模(Abstraction)
抽象是把具体的细节剔除,只保留关键特征,并用一种新的、更简洁的方式表达出来的能力。 数学里学过的"提取公因子"是抽象;地图把真实地形简化成符号和线条,也是抽象。
在编程思维里,抽象通常表现为"建立模型"。例如你要写一个简单的记账程序,你不需要真的模拟每一张钞票、每一个钱包的物理状态,只需要建立一个抽象模型:每一笔交易有日期、金额、收支类型、备注四个字段。这就够了。任何交易都可以被装进这四个字段里进行处理。
抽象的关键判断是:保留什么、忽略什么? 保留得太多,模型臃肿不堪;保留得太少,模型无法反映真实情况。这个取舍能力,是从初学者走向高手的门槛。本书第 7 章到第 9 章会重点讨论抽象。
支柱四:算法设计(Algorithm Design)
算法是解决问题的具体步骤序列,它明确规定了每一步做什么、怎么做、什么情况下停止。 算法设计的任务,是把前面三个支柱的产物——分解后的小问题、识别出的模式、抽象出的模型——组装成一个可以执行的流程。
设计算法时,有几条基本要求:
- **确定性**:每一步的描述必须没有歧义,不同人读到的意思应该一致。
- **有限性**:算法必须在有限步骤内结束,不能无限循环。
- **可行性**:每一步都必须能在现实或系统内真正执行。
- **可验证**:算法执行完之后,必须能判断是否达到了预期效果。
菜谱、旅行规划、装修流程、报销流程,都是算法。区别只在于写在纸上、写在系统里、还是写在脑子里。本书第 10 章到第 12 章会系统介绍算法设计与分析的方法。
四大支柱的协作
四个支柱不是用一次就丢的。在真实的复杂任务中,它们往往要循环好几轮。第一轮分解之后,会识别出新的模式,于是调整分解方式;调整之后,又会发现需要更精细的抽象;最后基于更稳定的抽象,设计算法;算法实现过程中,又会发现新的分解需求……如此反复,直到问题被解决。
理解这一点很重要:编程思维不是线性的"先做 A,再做 B",而是迭代上升的过程。新手最常见的误区,就是试图第一次就把所有问题想清楚、把所有抽象都做对。事实上高手也是反复迭代,只是迭代得更快、更自觉。
1.4 实践案例:整理书桌与规划周末出行
理论再多,不如动手做一遍。下面用两个微型案例,把四大支柱完整演练一遍。建议你准备一张纸,跟着把每一步写下来。
案例一:整理书桌
原始任务:我的书桌很乱,需要整理一下。
这是一个典型的"听起来简单、做起来无从下手"的任务。下面用四大支柱来拆。
第一步:分解。 先问自己——"整理"具体包含哪些动作?大致可以分成:
- 清空桌面:把所有东西拿下来。
- 分类:把所有物品分成几类。
- 决定每类物品的去留与位置。
- 清洁桌面。
- 物品归位。
- 建立日常维护规则。
第二步:模式识别。 看一下清空后那一堆物品,你会注意到一些规律:有些物品几乎每天用(电脑、水杯、笔),有些每周用几次(充电器、耳机),有些一个月都用不了一次(旧发票、过期的便利贴)。这就是识别出了"使用频率"这一模式。
第三步:抽象。 基于使用频率,可以建立一个简单的物品模型:每个物品有三个属性——类别、频率、位置。借助这个模型,所有物品都可以归类到一个二维表里。
第四步:算法设计。 综合以上,写出明确的整理步骤:
1. 把桌面所有物品移到地面。 2. 用湿布擦桌面。 3. 把地面物品逐个判断:常用 / 偶尔用 / 几乎不用。 4. 常用物品放桌面伸手可及处;偶尔用物品放抽屉;几乎不用物品收入柜子深处或丢弃。 5. 每天晚上花 2 分钟归位常用物品。 6. 每周日花 5 分钟检查抽屉,丢掉本周新增的杂物。
执行完这六步,你的书桌就处于"整理完成 + 可持续维护"的状态。你看,原本一句"整理一下"的任务,现在变成了一份可执行、可验收、可维护的算法。这正是编程思维的价值。
案例二:规划周末出行
原始任务:周末想去周边玩两天。
第一步:分解。 把这个任务按维度拆开:
- 时间维度:周六上午出发、周日傍晚返回。
- 目的地维度:候选地点 A、B、C。
- 内容维度:景点、餐饮、住宿、交通。
- 资源维度:预算、参与人数、可用车、装备。
第二步:模式识别。 翻一翻你过去几次出行经历,你会发现一些模式:
- 出门晚 → 上午景点人多、体验差。
- 没有提前订住宿 → 周六晚临时找房价格翻倍。
- 行程太满 → 整天疲于奔命,没有享受感。
这些模式就是"经验规则"。本次规划可以直接复用:早出发、提前订、留白。
第三步:抽象。 把出行任务抽象为一个简单的模型:
- 行程 = 时间表 + 地点表 + 资源表。
- 每条时间表项 = 时间段 + 地点 + 活动 + 备注。
任何一天的行程,都可以填进这张表里。当模型稳定之后,规划过程就变成"填空"。
第四步:算法设计。 写出周六的具体算法(节选):
``` 06:30 起床、洗漱 07:00 早餐 07:30 出发 10:00 到达 A 镇,停车 10:15 步行至景点 X 10:30 - 12:00 游览景点 X 12:15 午餐(餐厅 Y,已订位) 13:30 - 15:30 游览景点 Z 16:00 入住酒店 W 17:00 周边散步 18:30 晚餐(餐厅 V 或自选) 20:00 回酒店休息 ```
这套算法有几个特点:
- 每一步都有明确时间和动作,没有"看情况"这样的模糊语言。
- 关键节点(订位、入住)标注了已确认状态。
- 流程有起点(06:30)和终点(20:00 休息),不会无限延伸。
到这里,"周末想出去玩"就从一个愿望变成了一份可执行方案。
两个案例的共通启示
对比整理书桌和规划出行,你会发现几个共通点:
1. 分解让任务可启动。原始问题之所以让人觉得无从下手,是因为它太模糊。分解之后,第一步可以立刻开始。 2. 模式识别让你不重复犯错。识别出"出门晚体验差"这种规律后,你会主动规避。 3. 抽象让你建立通用框架。一旦你有了"行程 = 时间表 + 地点表 + 资源表"这种模型,下次规划出行可以直接套用。 4. 算法设计让方案可执行、可验证。写出来之后,谁来执行都一样,结果可被检验。
这两个案例是本书所有后续案例的最小范本。第 4 章、第 8 章、第 11 章的复杂案例,都是这一范本的放大版。
给你的练习
完成本章的产出练习,请按下面三步来做:
1. 选一件你最近想做但迟迟没做的事(整理衣柜、规划一次聚会、准备一次汇报),用四大支柱走一遍,写下分解、模式、抽象、算法四份产出。 2. 把这份产出用思维导图工具(手绘、XMind、MindNode 都行)画出来,结构按"目标 → 四大支柱 → 具体步骤"展开。 3. 把这份笔记保存好,第 4 章我们会回过头来检查它,看看哪些地方可以再优化。
1.5 全书学习路线图与读者使用指南
本书共 15 章,按"思维基础 → 思维工具 → 思维实战"三段式递进。下面是每章的核心主题和预计收获,方便你决定阅读节奏。
第一段:思维基础(第 1 章到第 5 章)
- 第 1 章:走进编程思维——你已经读到这里。
- 第 2 章:逻辑基础——学习命题、判断、推理的基本规则,建立思考的"语法"。
- 第 3 章:流程与分支——理解顺序、分支、循环三种基本结构,这是所有算法的骨架。
- 第 4 章:问题分解实战——通过 5 个不同领域的中等案例,把分解能力练到熟练。
- 第 5 章:表达你的思路——学习用流程图、伪代码、结构化语言把想法写清楚。
第二段:思维工具(第 6 章到第 10 章)
- 第 6 章:模式识别——从重复中找规律,从差异中找原因。
- 第 7 章:抽象与建模——把现实世界"翻译"成可处理的对象。
- 第 8 章:数据视角——理解数据如何组织、存储、查询。
- 第 9 章:用函数封装思路——把可复用的步骤打包成模块。
- 第 10 章:算法的复杂度——