编程基础自查清单:从语句、函数到算法与数据结构

发布时间:2026/10/18 15:47:49
编程基础自查清单:从语句、函数到算法与数据结构 1. 从零建立编程认知为什么这五节课值得反复刷很多人学编程的路径是“先选语言、再啃语法”结果变量、循环、函数学了一堆脑子里却始终没有一张完整的“程序是怎么跑起来的”地图。《计算机科学速成课》第10到14集正好补的就是这张地图——它不教你写某个具体语言的代码而是把编程语言的设计逻辑、语句的执行方式、函数的调用机制、算法的评估标准、数据结构的选择依据这几件事串成一条线讲清楚。我把这五集反复看了三遍边看边记越记越觉得这套内容的价值被低估了。大部分人把它当“科普动画”刷一遍就过去了但它其实是一份极好的编程基础自查清单如果你能把这五集里的每个概念用自己的话讲出来并且能对应到自己写过的代码上说明你的基础是扎实的如果讲不出来那大概率你写代码时是靠记忆和模仿而不是靠理解。这篇笔记面向三类人一是刚接触编程、还没形成体系认知的新手二是学了一段时间但总觉得“知其然不知其所以然”的进阶者三是想给别人讲编程入门、需要一套清晰讲解框架的人。我会按“这集讲了什么—背后的原理是什么—对应到实际写代码时怎么用—我踩过的坑”这个结构来展开尽量把动画里一笔带过的细节补全。需要先说明一点速成课为了控制时长很多地方是高度压缩的。比如它讲“函数”时只用了两三分钟但函数背后的调用栈、参数传递、返回值处理每一个都值得单独展开。我在笔记里会把动画没讲透的部分补上这些补充来自我自己的实践和常见的编程教学共识不是原片内容我会标注清楚。2. 编程语言与语句第10集的核心拆解2.1 为什么先讲“语言”而不是直接讲“写代码”第10集的主题是编程语言和语句。它没有一上来就让你写Hello World而是先问了一个问题为什么需要编程语言这个问题看似废话但仔细想答案并不简单。计算机的底层是晶体管开关能理解的只有“通电/断电”两种状态也就是二进制。如果让人直接写二进制指令理论上可行但实际不可维护——你写一个加法可能要几十位二进制改一个逻辑要重新数一遍0和1。所以编程语言的核心作用是在人类可读的表达和机器可执行的指令之间建立一层翻译。这层翻译有两种实现方式编译和解释。速成课里用了一个很直观的类比编译就像把一整本外文书一次性翻译成中文再出版解释就像请一个同声传译你说一句他翻一句。这个类比抓住了核心差异但实际工程中的区别更细维度编译型解释型执行前需要完整编译成机器码不需要边读边执行执行速度通常更快通常更慢跨平台性需要为不同平台分别编译有解释器就能跑调试体验编译期能发现部分错误运行时才暴露错误典型代表C、C、RustPython、JavaScript我刚开始学的时候有个误区觉得“编译型比解释型高级”。后来实际做项目才发现选哪种完全看场景写一个需要极致性能的图像处理模块编译型是首选写一个快速验证想法的脚本解释型能让你五分钟出结果。没有优劣只有适配。2.2 语句的本质让计算机按顺序做事的指令单元速成课把“语句”定义为程序中最小的执行单元。这个定义没错但太抽象。我自己的理解是语句就是你对计算机下达的一条命令比如“把这个值存到那个位置”“比较这两个数”“跳到那一行继续执行”。第10集重点讲了几类基本语句赋值语句把某个值存到变量里。看起来简单但这里有个关键点——变量不是“盒子”而是“标签”。x 5不是把5放进叫x的盒子里而是给5贴了一个叫x的标签。这个区别在讲引用类型时特别重要后面第12集讲数据结构时会用到。条件语句根据条件决定走哪条路。if-else的本质是改变程序的执行流让程序不再是从上到下一条路走到黑。循环语句重复执行某段代码。循环的核心要素是初始状态、终止条件、状态更新缺一个就会出问题。我见过太多新手写循环时忘了更新状态变量导致死循环。这里补充一个速成课没展开但非常重要的点语句的执行顺序。程序默认是顺序执行的但条件语句和循环语句会打破这个顺序。理解这一点后面学函数调用、递归、异步编程时才不会晕。你可以把程序想象成一条河顺序执行是河水自然往下流条件语句是遇到分叉口选一条循环是在某个地方转圈函数调用是暂时拐进一条支流再回来。2.3 从语句到程序我总结的三个检查点学完第10集后我给自己定了一个规矩每写一段代码都问三个问题。第一这段代码的执行顺序是什么从第一行到最后一行有没有分支、有没有循环、有没有跳转。把这个顺序在脑子里过一遍很多逻辑错误在写之前就能发现。第二每个变量的值在每一步是什么这是手动模拟程序执行的过程。新手最常犯的错误就是“以为变量是某个值实际是另一个值”。手动跟踪一遍比调试器还管用。第三这段代码的输入和输出分别是什么输入不只是函数参数还包括全局变量、文件、网络请求等输出也不只是返回值还包括打印、写文件、修改全局状态等。把输入输出理清楚代码的边界就清晰了。这三个检查点看起来笨但实测下来能省掉大量调试时间。我刚开始学编程时总想快点写完跑起来看结果后来发现想清楚再写比写完再改快得多。3. 函数与调用机制第11集的深层逻辑3.1 函数不只是“代码复用”更是“问题分解”第11集讲函数。大部分教材讲函数时强调“复用”这没错但只讲了一半。函数更核心的价值是把一个大问题分解成若干个小问题每个小问题用一个函数解决最后组合起来。速成课里用了一个“做三明治”的类比你不会把所有步骤写在一个大段落里而是分成“拿面包”“涂酱”“放菜”“合起来”几个步骤。每个步骤就是一个函数。这个类比的好处是让你看到函数是思考工具不只是代码组织工具。我在实际写代码时有个习惯如果一个函数的代码超过一屏大约40行我就会想能不能拆。拆的依据不是行数而是这个函数是否只做一件事。如果一个函数既在解析数据又在格式化输出那它做了两件事应该拆成两个。这个原则在软件工程里叫“单一职责”速成课没提这个词但讲的就是这个意思。3.2 调用栈函数执行背后的“记忆机制”这是第11集最容易被忽略但最重要的部分。速成课用了一个“叠盘子”的动画来展示函数调用主程序调用函数A函数A调用函数B函数B调用函数C然后C返回BB返回AA返回主程序。这个“叠盘子”就是调用栈。调用栈的核心作用是记住每个函数执行到哪了、局部变量是什么值。每次调用一个函数系统就在栈上压入一个“栈帧”里面存着这个函数的参数、局部变量和返回地址。函数返回时栈帧弹出控制权回到调用它的地方。为什么理解调用栈重要因为递归完全依赖它。第11集后面讲递归时很多人看不懂就是因为没理解调用栈。递归的本质是“函数调用自己”每次调用都会压入一个新的栈帧每个栈帧有自己的参数值。如果递归没有终止条件栈会一直增长最后栈溢出。我踩过的一个坑写递归时以为“函数调用自己”就是回到函数开头重新执行局部变量会重置。实际上不是——每次调用都是独立的栈帧局部变量互不影响。理解这一点后递归的写法就清晰了把问题分解成更小的同类问题用参数传递状态用返回值组合结果。3.3 参数传递值传递与引用传递的实际影响速成课在讲函数时提到了参数传递但讲得比较简略。实际编程中参数传递方式直接影响代码行为这里展开说一下。值传递把实参的值复制一份传给形参。函数内修改形参不影响外面的实参。这是最直观的方式C语言的基本类型、Python的整数和字符串都是这种。引用传递把实参的地址传给形参。函数内修改形参外面的实参也会变。C语言的指针、Python的列表和字典、Java的对象都是这种。这里有个容易混淆的点Python的变量传递常被说成“传对象引用”但实际行为取决于对象是否可变。不可变对象整数、字符串、元组表现得像值传递可变对象列表、字典、集合表现得像引用传递。我刚开始学Python时写了一个函数修改列表发现外面的列表也变了当时很困惑。后来才明白函数收到的是列表的引用修改列表内容会影响原列表但重新赋值不会。def modify_list(lst): lst.append(4) # 会影响外面的列表 lst [5, 6, 7] # 不会影响外面的列表只是让局部变量指向新列表 my_list [1, 2, 3] modify_list(my_list) print(my_list) # 输出 [1, 2, 3, 4]这个例子我建议每个学Python的人都亲手跑一遍跑完就理解了。3.4 返回值函数与外界沟通的桥梁速成课讲返回值时强调“函数可以把结果返回给调用者”。这个说法没错但实际编程中返回值的设计有很多讲究。首先一个函数应该返回什么理想情况下函数应该返回一个明确的结果。如果函数既修改外部状态又返回结果调用者会困惑。我见过一些代码函数内部打印了日志、修改了全局变量、又返回了一个值这种函数很难测试和复用。其次什么时候不返回有些函数就是用来执行动作的比如打印、写文件、发送请求这类函数通常不返回值或者返回None。这不是问题但要明确区分“查询型函数”和“动作型函数”。最后返回多个值怎么办Python支持返回元组其他语言可能需要返回对象或使用输出参数。我个人的经验是如果函数需要返回超过三个值大概率是这个函数职责太多了应该考虑拆分。4. 算法与复杂度第12集的思维框架4.1 算法不是“数学”是“解决问题的步骤”第12集讲算法。很多人看到“算法”两个字就想到数学公式和证明其实速成课讲得很清楚算法就是解决问题的步骤。你早上起床先刷牙再洗脸还是先洗脸再刷牙这也是一个算法只是效率不同。速成课在这一集重点讲了排序和查找两个经典问题用它们来展示不同算法的效率差异。排序讲了选择排序和归并排序查找讲了线性查找和二分查找。这些具体算法当然重要但更重要的是背后的复杂度思维。4.2 大O表示法衡量算法效率的标尺速成课用了一个很直观的方式解释大O当输入规模变大时算法的执行时间如何增长。它没有用严格的数学定义而是用“操作次数”来估算。我自己的理解是大O表示法是一种忽略常数、只看趋势的评估方式。比如一个算法需要3n 5次操作大O记作O(n)因为当n很大时3和5的影响可以忽略。这不是精确计算而是量级判断。常见的复杂度从快到慢复杂度名称典型场景输入规模1000时的操作量级O(1)常数数组按索引访问1O(log n)对数二分查找约10O(n)线性遍历数组1000O(n log n)线性对数归并排序约10000O(n²)平方嵌套循环1000000O(2ⁿ)指数暴力枚举子集天文数字这张表我建议贴在显示器旁边。每次写代码时想一下我的算法在哪个量级如果输入规模翻倍执行时间会变成多少这个习惯能帮你避开很多性能坑。4.3 二分查找为什么它比线性查找快那么多速成课用了一个“猜数字”的游戏来演示二分查找1到100之间想一个数每次猜中间值根据“大了”还是“小了”缩小范围。最多7次就能猜中而线性查找最坏要100次。二分查找的核心前提是数据必须有序。如果数据没排序二分查找用不了。这引出一个重要 trade-off排序需要时间但排序后查找更快。如果只需要查找一次排序可能不划算如果需要查找很多次排序就值得。我踩过的一个坑写二分查找时边界条件搞错导致死循环或漏掉元素。后来总结了一个模板基本不会错def binary_search(arr, target): left, right 0, len(arr) - 1 while left right: mid (left right) // 2 if arr[mid] target: return mid elif arr[mid] target: left mid 1 else: right mid - 1 return -1关键点left right而不是left rightmid 1和mid - 1而不是mid。这两个细节决定了边界处理是否正确。4.4 排序算法选择排序与归并排序的对比速成课对比了选择排序和归并排序。选择排序的思路是每次从未排序部分找出最小的放到已排序部分的末尾。归并排序的思路是把数组分成两半分别排序然后合并两个有序数组。选择排序的时间复杂度是O(n²)归并排序是O(n log n)。当n1000时选择排序大约需要100万次操作归并排序大约需要1万次。差距是100倍。当n10000时差距是1000倍。但归并排序有一个缺点需要额外的内存空间来合并两个子数组。选择排序是原地排序不需要额外空间。这就是算法设计中的时间-空间权衡用空间换时间或者用时间换空间。实际编程中大部分语言内置的排序函数用的是混合算法比如TimSortPython的排序算法结合了归并排序和插入排序在部分有序的数据上表现更好。你不需要自己实现排序但理解这些算法的差异能帮你在需要自定义排序时做出正确选择。5. 数据结构第13-14集的核心工具5.1 数据结构是“数据的组织方式”第13集和第14集讲数据结构。速成课从数组开始然后讲链表、栈、队列、哈希表、树、图。这些名词听起来多但核心问题只有一个如何组织数据才能让特定的操作更快。数组的特点是连续存储、按索引访问快、插入删除慢。因为数组在内存里是一整块连续空间知道起始地址和索引就能直接算出目标地址所以访问是O(1)。但插入一个元素需要把后面的元素都往后挪删除需要往前挪所以是O(n)。链表的特点是分散存储、按索引访问慢、插入删除快。链表的每个节点存着数据和下一个节点的地址访问第k个元素需要从头开始走k步所以是O(n)。但插入和删除只需要改几个指针不需要挪动其他元素所以是O(1)前提是已经找到位置。这个对比是理解数据结构的起点。没有一种数据结构在所有操作上都快选择哪种取决于你的操作模式读多写少用数组写多读少用链表。5.2 栈与队列受限但高效的线性结构栈和队列都是线性结构但加了限制。栈是后进先出只能在顶部插入和删除。队列是先进先出只能在一端插入、另一端删除。速成课用“叠盘子”和“排队”来类比很直观。但实际编程中栈和队列的应用场景非常广栈函数调用调用栈、括号匹配、表达式求值、撤销操作。队列任务调度、消息队列、广度优先搜索、打印队列。我刚开始学的时候觉得“限制了操作不是更弱了吗”后来才明白限制带来的是可预测性和效率。因为栈只在一端操作所以实现简单、速度快因为队列保证顺序所以适合需要公平调度的场景。5.3 哈希表用空间换时间的典型哈希表是速成课第14集的重点。它的核心思想是通过一个哈希函数把键映射到数组的某个位置从而实现平均O(1)的查找、插入和删除。哈希函数的质量直接影响性能。好的哈希函数应该均匀分布让不同的键尽量映射到不同的位置。如果很多键映射到同一个位置就发生冲突。解决冲突的常见方法有链地址法每个位置存一个链表和开放地址法冲突时找下一个空位。哈希表的平均复杂度是O(1)但最坏情况是O(n)所有键都冲突。实际使用中只要哈希函数不太差冲突不会太严重。大部分语言的内置字典/映射类型都是哈希表实现比如Python的dict、Java的HashMap。我踩过的一个坑用可变对象作为哈希表的键。比如用列表作为dict的键Python会报错因为列表是可变的哈希值会变。哈希表的键必须是不可变的这是硬性要求。5.4 树与图处理层次和关系的数据结构树是一种层次结构每个节点有零个或多个子节点没有父节点的叫根节点。树的应用包括文件系统、DOM树、组织架构、决策树等。图是一种关系结构由节点和边组成边可以有方向也可以无方向。图的应用包括社交网络、地图导航、依赖关系、状态机等。速成课在这部分讲得比较简略因为树和图的内容可以单独开一门课。但有两个概念值得记住二叉搜索树左子树所有节点小于根右子树所有节点大于根。查找、插入、删除平均O(log n)但最坏O(n)退化成链表。平衡二叉搜索树如AVL树、红黑树能保证O(log n)。图的遍历深度优先搜索DFS用栈广度优先搜索BFS用队列。这两种遍历方式是很多图算法的基础。5.5 数据结构选择速查表操作数组链表栈队列哈希表二叉搜索树按索引访问O(1)O(n)----查找O(n)O(n)--O(1)平均O(log n)平均插入O(n)O(1)O(1)O(1)O(1)平均O(log n)平均删除O(n)O(1)O(1)O(1)O(1)平均O(log n)平均适用场景读多写少写多读少后进先出先进先出快速查找有序数据这张表不是让你背的而是让你在选数据结构时有个参考。实际项目中我通常会先想清楚最频繁的操作是什么然后选在这个操作上最快的数据结构。6. 常见问题与排查技巧实录6.1 循环写不对先检查这三个地方新手写循环最常见的三个问题死循环、差一错误、循环变量作用域。死循环循环条件永远为真或者状态变量没有更新。排查方法在循环体内打印状态变量看它是否在向终止条件靠近。差一错误循环多执行一次或少执行一次。比如遍历数组时用i len(arr)而不是i len(arr)导致索引越界。排查方法用边界值测试比如空数组、单元素数组。循环变量作用域在循环外使用循环变量但循环变量在循环结束后可能已经变了。排查方法如果需要在循环外使用某个值在循环内把它存到另一个变量里。6.2 递归栈溢出检查终止条件和递归深度递归栈溢出通常有两个原因没有终止条件或者递归深度太大。没有终止条件时递归会一直调用自己直到栈空间耗尽。排查方法确保每个递归分支都有终止条件并且终止条件一定能达到。递归深度太大时即使有终止条件也可能因为输入规模太大而溢出。比如计算斐波那契数列的朴素递归n50时就会很慢n1000时直接溢出。解决方法改用迭代或者用记忆化把已计算的结果存起来。# 朴素递归n40时就很慢 def fib(n): if n 1: return n return fib(n-1) fib(n-2) # 记忆化递归快很多 memo {} def fib_memo(n): if n in memo: return memo[n] if n 1: return n memo[n] fib_memo(n-1) fib_memo(n-2) return memo[n]6.3 哈希表冲突太多检查哈希函数和负载因子哈希表性能下降通常是冲突太多。排查方向哈希函数是否均匀负载因子是否过高。负载因子是元素数量除以桶数量。负载因子越高冲突概率越大。大部分哈希表实现会在负载因子超过某个阈值如0.75时自动扩容。如果你自己实现哈希表记得扩容。哈希函数的问题通常是分布不均匀。比如用字符串长度作为哈希值所有长度相同的字符串都会冲突。好的哈希函数会考虑所有字符。6.4 常见问题速查表问题现象可能原因排查方法解决方案程序卡死死循环打印循环变量检查循环条件和状态更新索引越界差一错误检查边界值用而不是栈溢出递归太深打印递归深度改迭代或加记忆化哈希表变慢冲突太多检查负载因子扩容或换哈希函数函数修改了外部变量引用传递检查参数类型传副本或明确文档排序结果不对比较函数错误测试边界情况检查比较逻辑7. 我总结的编程基础自查清单学完这五集后我整理了一份自查清单。如果你能对每个问题给出肯定的回答说明你的编程基础是扎实的。语言与语句层面你能解释编译和解释的区别吗你能说出至少三种语句类型吗你能手动跟踪一段代码的执行顺序吗函数层面你能解释调用栈的工作原理吗你能区分值传递和引用传递吗你能写出一个正确的递归函数吗算法层面你能用大O表示法评估一个算法的复杂度吗你能写出二分查找吗你能解释归并排序为什么比选择排序快吗数据结构层面你能说出数组和链表的区别吗你能解释栈和队列的应用场景吗你能说出哈希表的平均复杂度和最坏复杂度吗这份清单我每隔一段时间就会拿出来过一遍。每次过的时候都会发现有些地方理解更深了有些地方又模糊了。编程基础不是学一遍就完事的而是需要反复回顾和强化的。最后分享一个我自己的学习习惯每学一个新概念我都会尝试用三句话把它讲清楚——第一句说它是什么第二句说它解决什么问题第三句说它怎么用。如果三句话讲不清楚说明我还没真正理解。这个习惯逼着我把模糊的直觉变成清晰的表达效果很好。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询