Chapter 1 什么是编程思维?Why Programming Thinking Matters
一提到“编程思维”四个字,很多人的第一反应是皱眉头:是不是要背一堆枯燥的语法?是不是要数学特别好才能学?是不是只有天天写代码的程序员才需要这东西?如果你也有类似的疑问,那本章就是专门来给你“卸包袱”的——我们先把编程思维从神坛上拉下来,放到你每天都要接触的点外卖、规划旅行、甚至做家务这些生活场景里,看看它到底是个什么东西,又能给你带来什么实实在在的好处。
一、先破个误区:编程思维从来不是“写代码”
> 💡 电子版侧边栏提示:点击这里可以观看“编程思维 vs 写代码”的对比短视频,时长2分钟,帮你快速理解两者的核心区别。
很多人对编程思维的最大误解,就是把“写代码”和“编程思维”划等号:觉得会写Python、Java就是懂编程思维,不会写代码就完全和编程思维无关。这其实相当于把“会用笔写字”和“会写作”划了等号:你哪怕不会用钢笔、毛笔,只要会组织语言、表达逻辑,就是会写作;同样,你哪怕一行代码都不会写,只要会拆解问题、找规律、设计步骤,就是懂编程思维。
2006年,卡内基梅隆大学的周以真(Jeannette M. Wing)教授首次正式提出了计算思维(Computational Thinking)的概念,她给出的定义是:“计算思维是运用计算机科学的基础概念进行问题求解、系统设计、以及人类行为理解的思维过程。”[^1] 简单来说,编程思维的核心从来不是“写代码”,而是用计算机解决问题的逻辑,来解决现实世界的问题。
我们拿每个人每天都做的“点外卖”举例,来看看普通人是怎么做的,用编程思维的人又是怎么做的:
- 普通人的点外卖流程:打开APP,刷到哪个看哪个,觉得差不多就下单,要么超时,要么不好吃,要么价格超了预算,最后吐槽一句“今天运气真差”。
- 用编程思维的点外卖流程:
1. 先明确输入(Input):我的位置在朝阳区望京,预算30块以内,想要吃辣,要求30分钟内送到; 2. 再明确处理(Processing)的步骤:① 筛选配送时间≤30分钟的商家;② 在筛选结果里找价格≤30元的商家;③ 在符合条件的商家里找带“辣”标签的,没有的话选评分4.5以上的快餐;④ 叠加满减、红包,算最终价格,确认不超过30块;⑤ 下单支付; 3. 最后得到输出(Output):一份符合要求的外卖,30分钟内送到,口味是辣的,价格不超过30块。 4. 还要考虑边界条件(Edge Case):如果所有符合要求的商家都休息了怎么办?那就把配送时间放宽到45分钟,或者预算提高到35块,再重新筛选。
你看,整个过程你一行代码都没写,但每一步都符合编程思维的逻辑:明确输入输出、拆解步骤、考虑异常情况。哪怕你完全不会编程,只要按这个流程走,点外卖的满意度至少能提升80%。
二、编程思维的核心:四个不可少的支柱
周以真教授在提出计算思维的概念时,就明确了它的四个核心支柱,这也是所有编程思维训练的基础,我们一个个用生活案例讲透:
1. 问题分解(Decomposition):把大问题拆成小问题
你有没有遇到过这种场景:领导给你派了个活,“帮我做个用户增长的活动方案”,你听完直接懵了,完全不知道从哪下手。这就是你不会“问题分解”:一个看起来很大的问题,如果你直接上手做,肯定会被吓退,但如果你把它拆成一个个小问题,就简单多了。
用编程思维拆解“做用户增长活动方案”这个任务,可以拆成:
- 先明确活动的目标:是拉新1万用户,还是提升老用户复购率?拉新的话目标用户是谁?是大学生还是职场人?
- 再拆解约束条件:预算是多少?活动时间是多久?要对接哪些部门?比如预算10万,活动时间2周,要对接产品、设计、运营、客服四个部门。
- 再拆解子任务:① 活动规则设计;② 页面设计;③ 渠道投放;④ 数据埋点;⑤ 风险预案;⑥ 效果评估。
- 每个子任务再拆:比如活动规则设计,再拆成“目标用户激励规则”“拉新路径设计”“防作弊规则”,每个小任务都可以分配给不同的人做,最后拼起来就是完整的方案。
再举个更生活化的例子:你要办一场生日派对,看起来是个大工程,但拆解之后就很简单: ```mermaid graph TD A[办生日派对] --> B[确定时间/预算/人数] A --> C[场地预定] A --> D[餐饮安排] A --> E[邀请发出] A --> F[现场布置] A --> G[游戏/节目安排] B --> B1[时间选周末/预算2000/人数20] C --> C1[提前1个月订/选容纳30人的轰趴馆] D --> D1[提前2周定蛋糕/准备零食饮料] E --> E1[提前1周发邀请/统计人数] F --> F1[提前3天买装饰/当天提前2小时布置] G --> G1[提前1周准备游戏/安排朋友表演节目] ``` 你看,再大的问题,拆解成一个个10分钟就能完成的小任务,就没那么难了。问题分解的核心是:不要被问题的“整体规模”吓住,找到问题的“颗粒度”,把大问题拆成你能力范围内的一个个小问题。
2. 模式识别(Pattern Recognition):从经验里找规律
模式识别是编程思维里最“省力气”的部分:如果你能从过去的经验里找到通用的规律,以后遇到类似的问题就不用每次都从零开始想,直接复用规律就行。
我们拿买奶茶举例:你连续三次点奶茶,发现“少糖+少冰+珍珠”的搭配最好喝,第四次点的时候你不用再挨个试“全糖好不好喝”“多冰好不好喝”,直接按之前的模式点就行,这就是模式识别。
再举个工作中的例子:你做了10次电商大促的活动,发现每次活动的前3天流量最高,最后1天复购率最高,中间7天是平稳期,那下次做活动的时候,你就可以直接把之前的节奏搬过来:前3天上引流款,中间7天上利润款,最后1天上清仓款,不用再重新做测试,这就是模式识别的作用。
模式识别在编程里更常见:比如你要写一个程序统计1000个学生的成绩,你不用写1000次统计代码,只要找到“所有学生的成绩都存在一个列表里,只要遍历列表累加再除以总数”这个模式,写一段代码就能搞定所有情况。
模式识别的核心是:不要每次都从零开始,从过去的经验里找到通用的规律,复用规律就能大幅提升效率。
3. 抽象(Abstraction):把具体的例子提炼成通用规则
抽象是很多人觉得最难的部分,但也是编程思维里最有价值的部分:它的核心是忽略不必要的细节,抓住问题的核心本质,把具体的例子提炼成可以复用的通用规则。
我们拿做PPT举例:你每次做PPT,不管是工作汇报、产品介绍还是毕业答辩,其实核心结构都是“封面→目录→内容页→总结→致谢”,你不用每次做PPT都从零开始想“我第一页应该放什么”,直接按这个通用的结构填充内容就行,这个“通用的PPT结构”就是抽象出来的规则。
再举个编程里的例子:不管是Python、Java还是C++,所有编程语言里的“变量”都是“存储数据的容器”,你不用学每种语言的变量都要重新理解,只要抓住“变量就是存数据的盒子,盒子上有个名字,你可以往里面放数据,也可以把里面的数据拿出来用”这个核心本质,学任何语言的变量都是一分钟的事,这就是抽象的作用。
抽象还有个很常见的应用:分类。比如你要整理家里的衣服,你不用记住每一件衣服的样子,只要把它们抽象成“上衣、裤子、内衣、配饰”四个大类,每个大类再细分,比如上衣分成T恤、衬衫、外套,这样整理的时候就不用挨个看,直接按类别放就行。
抽象的核心是:不要被具体的细节困住,抓住问题的本质,提炼出可以复用的通用规则,以后遇到类似的问题直接套用就行。
4. 算法设计(Algorithm Design):把步骤固化成可复现的流程
算法这个词听起来很高大上,但其实你每天都在用:你每天早上起床的步骤“关闹钟→起床穿衣服→刷牙洗脸→吃早饭→出门上班”,这就是一个算法;你点外卖的筛选步骤,也是一个算法。算法本质上就是解决某个问题的、可复现的、有限的步骤集合。
算法设计的关键不是“步骤越多越好”,而是“步骤越简单、越通用、效率越高越好”。比如你要算1到100的和,普通人的算法是1+2+3+…+100,一步步加,很麻烦;但高斯小时候发现的算法是(1+100)×100÷2,一步就算出来了,这就是更优的算法。
再举个生活里的例子:你要整理衣柜里的100件衣服,普通的算法是“拿出衣服→看是不是要扔→叠好→放回去”,一件件来,要花1个小时;但更优的算法是“先把所有衣服分成三类:要留的、要扔的、要捐的,分完之后再挨个处理”,这样只需要20分钟就能搞定,这就是算法优化的作用。
算法设计的核心是:把解决问题的步骤固化成可复现的流程,并且不断优化流程,提升效率。
这四个支柱不是孤立存在的,而是互相配合的:你分解问题之后,会找到子问题里的模式,把模式抽象成通用规则,然后把这些规则组合成算法,执行之后如果结果不符合预期,再回去调整分解的方式、或者优化抽象出来的规则,形成闭环。我们可以用一个流程图来概括整个编程思维解决问题的过程: ```mermaid graph TD A[遇到问题] --> B[明确目标与约束条件] B --> C[分解问题为子问题] C --> D[识别子问题中的模式] D --> E[抽象通用规则] E --> F[设计可复现的算法步骤] F --> G[执行并验证结果] G --> H{结果符合预期?} H -->|是| I[完成] H -->|否| J[调整算法/约束条件] J --> F ```
三、普通线性思维 vs 编程思维:到底差在哪?
很多人会说“我也会拆解问题啊,我也会找规律啊,那我和编程思维有什么区别?”最大的区别就是:普通思维是“先执行再调整”,编程思维是“先规划再执行”。
我们拿“规划一次从成都到重庆的2天旅行”举例,看看两种思维的差异:
普通线性思维的解决方式:
1. 打开购票软件,搜成都到重庆的机票,看哪个便宜买哪个; 2. 到了重庆之后,打开小红书搜“重庆必去的景点”,挨个去打卡; 3. 走到哪算哪,饿了就找附近的小吃,累了就回酒店; 4. 最后算账的时候发现预算超了30%,很多想去的景点没时间去,还因为赶时间累得要死。
编程思维的解决方式:
1. 先明确输入(约束条件)
一提到“编程思维”四个字,很多人的第一反应是皱眉头:是不是要背一堆枯燥的语法?是不是要数学特别好才能学?是不是只有天天写代码的程序员才需要这东西?如果你也有类似的疑问,那本章就是专门来给你“卸包袱”的——我们先把编程思维从神坛上拉下来,放到你每天都要接触的点外卖、规划旅行、甚至做家务这些生活场景里,看看它到底是个什么东西,又能给你带来什么实实在在的好处。
> 💡 电子版侧边栏提示:点击这里可以观看「编程思维 vs 写代码」对比短视频(2分钟),快速理解两者的核心区别。
一、先破个误区:编程思维从来不是“写代码”
1.1 First, Bust a Myth: Programming Thinking is Never About Writing Code
很多人对编程思维的最大误解,就是把“写代码”和“编程思维”划等号:觉得会写Python、Java就是懂编程思维,不会写代码就完全和编程思维无关。这其实相当于把“会用笔写字”和“会写作”划了等号:你哪怕不会用钢笔、毛笔,只要会组织语言、表达逻辑,就是会写作;同样,你哪怕一行代码都不会写,只要会拆解问题、找规律、设计步骤,就是懂编程思维。
2006年,卡内基梅隆大学的周以真(Jeannette M. Wing)教授首次正式提出了计算思维(Computational Thinking)的概念,她给出的定义是:“计算思维是运用计算机科学的基础概念进行问题求解、系统设计、以及人类行为理解的思维过程。”[^1] 简单来说,编程思维的核心从来不是“写代码”,而是用计算机解决问题的逻辑,来解决现实世界的问题。
我们拿每个人每天都做的“点外卖”举例,来看看普通人是怎么做的,用编程思维的人又是怎么做的:
- 普通人的点外卖流程:打开APP,刷到哪个看哪个,觉得差不多就下单,要么超时,要么不好吃,要么价格超了预算,最后吐槽一句“今天运气真差”。
- 用编程思维的点外卖流程:
1. 先明确输入(Input):我的位置在朝阳区望京,预算30块以内,想要吃辣,要求30分钟内送到; 2. 再明确处理(Processing)的步骤:① 筛选配送时间≤30分钟的商家;② 在筛选结果里找价格≤30元的商家;③ 在符合条件的商家里找带“辣”标签的,没有的话选评分4.5以上的快餐;④ 叠加满减、红包,算最终价格,确认不超过30块;⑤ 下单支付; 3. 最后得到输出(Output):一份符合要求的外卖,30分钟内送到,口味是辣的,价格不超过30块; 4. 还要考虑边界条件(Edge Case):如果所有符合要求的商家都休息了怎么办?那就把配送时间放宽到45分钟,或者预算提高到35块,再重新筛选。
你看,整个过程你一行代码都没写,但每一步都符合编程思维的逻辑:明确输入输出、拆解步骤、考虑异常情况。哪怕你完全不会编程,只要按这个流程走,点外卖的满意度至少能提升80%。
1.2 编程思维的四个核心支柱 / Four Core Pillars of Programming Thinking
周以真教授在提出计算思维的概念时,就明确了它的四个核心支柱,这也是所有编程思维训练的基础,我们一个个用生活案例讲透:
1.2.1 问题分解(Decomposition):把大问题拆成小问题
你有没有遇到过这种场景:领导给你派了个活,“帮我做个用户增长的活动方案”,你听完直接懵了,完全不知道从哪下手。这就是你不会“问题分解”:一个看起来很大的问题,如果你直接上手做,肯定会被吓退,但如果你把它拆成一个个小问题,就简单多了。
用编程思维拆解“做用户增长活动方案”这个任务,可以拆成:
- 先明确活动的目标:是拉新1万用户,还是提升老用户复购率?拉新的话目标用户是谁?是大学生还是职场人?
- 再拆解约束条件:预算是多少?活动时间是多久?要对接哪些部门?比如预算10万,活动时间2周,要对接产品、设计、运营、客服四个部门。
- 再拆解子任务:① 活动规则设计;② 页面设计;③ 渠道投放;④ 数据埋点;⑤ 风险预案;⑥ 效果评估。
- 每个子任务再拆:比如活动规则设计,再拆成“目标用户激励规则”“拉新路径设计”“防作弊规则”,每个小任务都可以分配给不同的人做,最后拼起来就是完整的方案。
再举个更生活化的例子:你要办一场生日派对,看起来是个大工程,但拆解之后就很简单: ```mermaid graph TD A[办生日派对] --> B[确定时间/预算/人数] A --> C[场地预定] A --> D[餐饮安排] A --> E[邀请发出] A --> F[现场布置] A --> G[游戏/节目安排] B --> B1[时间选周末/预算2000/人数20] C --> C1[提前1个月订/选容纳30人的轰趴馆] D --> D1[提前2周定蛋糕/准备零食饮料] E --> E1[提前1周发邀请/统计人数] F --> F1[提前3天买装饰/当天提前2小时布置] G --> G1[提前1周准备游戏/安排朋友表演节目] ``` 你看,再大的问题,拆解成一个个10分钟就能完成的小任务,就没那么难了。问题分解的核心是:不要被问题的“整体规模”吓住,找到问题的“颗粒度”,把大问题拆成你能力范围内的一个个小问题。 > 📖 纸书排版提示:此处流程图适合居中印刷,作为章节核心插图。
1.2.2 模式识别(Pattern Recognition):从经验里找规律
模式识别是编程思维里最“省力气”的部分:如果你能从过去的经验里找到通用的规律,以后遇到类似的问题就不用每次都从零开始想,直接复用规律就行。
我们拿买奶茶举例:你连续三次点奶茶,发现“少糖+少冰+珍珠”的搭配最好喝,第四次点的时候你不用再挨个试“全糖好不好喝”“多冰好不好喝”,直接按之前的模式点就行,这就是模式识别。
再举个工作中的例子:你做了10次电商大促的活动,发现每次活动的前3天流量最高,最后1天复购率最高,中间7天是平稳期,那下次做活动的时候,你就可以直接把之前的节奏搬过来:前3天上引流款,中间7天上利润款,最后1天上清仓款,不用再重新做测试,这就是模式识别的作用。
模式识别在编程里更常见:比如你要写一个程序统计1000个学生的成绩,你不用写1000次统计代码,只要找到“所有学生的成绩都存在一个列表里,只要遍历列表累加再除以总数”这个模式,写一段代码就能搞定所有情况。
模式识别的核心是:不要每次都从零开始,从过去的经验里找到通用的规律,复用规律就能大幅提升效率。
1.2.3 抽象(Abstraction):把具体的例子提炼成通用规则
抽象是很多人觉得最难的部分,但也是编程思维里最有价值的部分:它的核心是忽略不必要的细节,抓住问题的核心本质,把具体的例子提炼成可以复用的通用规则。
我们拿做PPT举例:你每次做PPT,不管是工作汇报、产品介绍还是毕业答辩,其实核心结构都是“封面→目录→内容页→总结→致谢”,你不用每次做PPT都从零开始想“我第一页应该放什么”,直接按这个通用的结构填充内容就行,这个“通用的PPT结构”就是抽象出来的规则。
再举个编程里的例子:不管是Python、Java还是C++,所有编程语言里的“变量”都是“存储数据的容器”,你不用学每种语言的变量都要重新理解,只要抓住“变量就是存数据的盒子,盒子上有个名字,你可以往里面放数据,也可以把里面的数据拿出来用”这个核心本质,学任何语言的变量都是一分钟的事,这就是抽象的作用。
抽象还有个很常见的应用:分类。比如你要整理家里的衣服,你不用记住每一件衣服的样子,只要把它们抽象成“上衣、裤子、内衣、配饰”四个大类,每个大类再细分,比如上衣分成T恤、衬衫、外套,这样整理的时候就不用挨个看,直接按类别放就行。
抽象的核心是:不要被具体的细节困住,抓住问题的本质,提炼出可以复用的通用规则,以后遇到类似的问题直接套用就行。
1.2.4 算法设计(Algorithm Design):把步骤固化成可复现的流程
算法这个词听起来很高大上,但其实你每天都在用:你每天早上起床的步骤“关闹钟→起床穿衣服→刷牙洗脸→吃早饭→出门上班”,这就是一个算法;你点外卖的筛选步骤,也是一个算法。算法本质上就是解决某个问题的、可复现的、有限的步骤集合。
算法设计的关键不是“步骤越多越好”,而是