📘 CodingMarble Learn

进阶编程与应用

进阶编程就是:选对数据结构(数组、链表、栈、队列),在IDE里写代码并测试,画图表和动画,使用电子表格函数,再把数据安全地存进关系数据库,并用SQL来查询。

🎬 分步故事

  1. 数组的格子数是固定的,这里有六格。大小一开始就定好了,装满以后就不能再加。
  2. 链表可以按需要变长。每个结点保存一个值和指向下一个结点的链接,最后一个结点指向空(null)。按“添加”试试。
  3. 栈就像一摞盘子。你只能在最上面放(push)和拿(pop)。最后放进去的最先出来。
  4. 队列就像排队买票。你站到队尾,从队头离开。最先进去的最先出来。
  5. 数据库把数据放在表里。两张表用一个键(id)连起来。SQL查询只挑出你要的行,这里是分数不低于50的行。
  6. 轮到你了。选择列表、栈或队列,按按钮来添加和删除数据。

提示:拖动3D画面可以旋转,用两根手指可以缩放。

🤔 常见疑问,一次讲清

为什么我不能给数组加第七个数据?

数组的大小在创建时就固定了。第0步里的六个格子就是整个数组。如果集合需要变大,就用列表。

链表把顺序记在哪里?

记在链接里。每个结点只知道下一个结点,所以你要顺着箭头走。看第1步。

为什么pop给出的是我最后加入的数据?

栈只有一个开口,就是栈顶。最新的数据在最上面,所以最先离开。看第2步。

队列和栈有什么不同?

队列是从队尾加入、从队头取出,所以最旧的先离开。在第3步里按按钮试试。

为什么用两张表,而不是一张?

这样每个事实只存一次。姓名放在一张表,成绩放在另一张表,再用id连起来。这样改一个名字只需要改一个地方。看第4步。

我应该用哪种结构?

需要固定大小、快速按下标访问:用数组。会增长的集合:用列表。撤销和后退:用栈。排队等候:用队列。在第5步里每种都试试。

数据结构:数组、链表、栈、队列

数据结构就是安排数据的方式,让程序能又快又方便地使用数据。

库里已经有这些工具。在Python中,list可以当栈用(append、pop),collections.deque可以当快速队列用。有现成的库就直接用,不要重新写。

stack = []
stack.append(5); stack.append(8)
stack.pop()      # gives 8
from collections import deque
q = deque([4, 9]); q.append(2)
q.popleft()      # gives 4

使用IDE:编写、运行、测试

IDE(集成开发环境)把编辑器、运行按钮、调试器和各种工具放在同一个地方。它会给代码上色、提示名字,还会在你输入时显示错误。

2D和3D可视化与动画

图像能帮我们看出规律。程序可以画图表(柱状图、折线图、散点图)、2D图形和3D场景。动画就是把同一幅画一遍又一遍地重画,每次只改变一点点(每秒大约30到60次)。简单的做法是:用一个变量,比如x,每一帧给它加一点,然后重画。本页的3D也是这样用3D库做出来的。

进阶电子表格函数

电子表格可以用函数完成像编程一样的工作:

关系数据库与SQL

关系数据库把数据放在由行和列组成的表里。每张表都有一个主键,这一列的值各不相同(比如id)。另一张表把这个值当作外键,用来连回这张表。好的设计让每个事实只存一次,这样就没有重复的数据。

SQL是用来提问和修改数据的语言:

SELECT name, score FROM students
JOIN marks ON students.id = marks.id
WHERE score >= 50 ORDER BY score DESC;

INSERT INTO marks (id, score) VALUES (5, 67);
UPDATE marks SET score = 55 WHERE id = 2;
DELETE FROM marks WHERE id = 5;

完整性是指数据始终正确:键是唯一的,外键必须对应一个真实存在的行,值的类型也必须正确。安全是指给用户设置密码,只给每个用户需要的权限,做好备份,而且绝不能把用户输入的文字直接拼进查询语句(要用参数),这样才能防止SQL注入。

为开放资源做贡献

很多工具和库是开源的:任何人都可以在许可证的规定下阅读、使用和改进它们。你可以修复一个错误、改进一份指南、翻译一个页面或者添加一个例子来帮忙。一定要先读许可证,注明来源,提出修改建议时要把话写得清楚而有礼貌。

试一试

在3D的第5步里,往栈里放入3个数据,再把它们取出来,写下顺序。队列也这样做一遍。然后先预测,再检查:加入4、9、2,再取出一个以后,队列的队头和栈的栈顶分别是哪个值?

重点公式和概念

例题讲解

1. 数据5、8、2按这个顺序压入栈。然后做两次pop。现在栈顶是什么?

压入后的栈:5、8、2(2在最上面)。pop先取走2,再取走8。剩下:5。栈顶 = 5。

2. 数据4、9、2按这个顺序加入队列。做一次dequeue。现在队头是哪一个?

最先进去的先离开,所以4被取走。队头是9。

3. 成绩表:id 1到4,分数是72、45、88、51。WHERE score >= 50 会返回多少行?

72、88和51不低于50。所以是3行。

4. 单元格B2:B5里是72、45、88、51。=SUMIF(B2:B5,">=50") 的结果是多少?

只把72、88和51相加:72 + 88 + 51 = 211。

5. 为什么可以用栈来检查表达式里的括号,比如 ( [ ] )?

每遇到一个左括号就压入栈。遇到右括号时,就弹出一个并检查它们是否配对。最近的左括号必须最先被关上(LIFO),而这正是栈的特点。如果最后栈是空的,括号就是配对的。

常见错误

练习测验

1. 哪种结构是LIFO?
2. 哪种结构靠链接,一次增加一个结点?
3. 在SQL中,哪个子句用来挑选符合条件的行?
4. 每一行的值都不相同的列叫做:
5. 调试器里的断点有什么作用?

练习:自己动手回答

输入或选择你的答案,然后点“检查”。卡住了就看提示;回答后会显示完整解答。

常见问题

数组和链表有什么区别?

数组大小固定,可以用下标直接跳到任何一项。链表可以变长或变短,但要找到某一项,必须顺着链接一个一个地走。

什么是主键和外键?

主键是让每一行都有唯一值的列,就像学号。外键是另一张表里保存这个值的列,用来把两张表连起来。

为什么SQL注入很危险?怎样防止?

如果把用户输入的文字直接拼进SQL命令,聪明的用户就能加入自己的命令,读取或删除数据。要使用参数化查询,这样输入的文字永远只会被当作数据。

先学这些

接着学