Showing preview only (1,419K chars total). Download the full file or copy to clipboard to get everything.
Repository: 1c7/Crash-Course-Computer-Science-Chinese
Branch: master
Commit: 65fcc9cfc95a
Files: 50
Total size: 1.3 MB
Directory structure:
gitextract_yvlrnkpn/
├── (字幕)全40集中英字幕文本/
│ ├── 01. 计算机早期历史-Early Computing.ass.txt
│ ├── 02. 电子计算机-Electronic Computing.ass.txt
│ ├── 03. 布尔逻辑 和 逻辑门-Boolean Logic & Logic Gates.ass.txt
│ ├── 04. 二进制-Representing Numbers and Letters with Binary.ass.txt
│ ├── 05. 算术逻辑单元-How Computers Calculate-the ALU.ass.txt
│ ├── 06. 寄存器 & 内存-Registers and RAM.ass.txt
│ ├── 07. 中央处理器-The Central Processing Unit(CPU).ass.txt
│ ├── 08. 指令和程序-Instructions & Programs.ass.txt
│ ├── 09. 高级CPU设计-Advanced CPU Designs.ass.txt
│ ├── 10. 早期的编程方式-Early Programming.ass.txt
│ ├── 11. 编程语言发展史-The First Programming Languages.ass.txt
│ ├── 12. 编程原理-语句和函数-Programming Basics - Statements & Functions.ass.txt
│ ├── 13. 算法入门 - Intro to Algorithms.ass.txt
│ ├── 14. 数据结构-Data Structures.ass.txt
│ ├── 15. 阿兰·图灵-Alan Turing.ass.txt
│ ├── 16. 软件工程-Software Engineering.ass.txt
│ ├── 17. 集成电路&摩尔定律-Integrated Circuits & Moore’s Law.ass.txt
│ ├── 18. 操作系统-Operating Systems.ass.txt
│ ├── 19. 内存&储存介质-Memory & Storage.mp4.ass.txt
│ ├── 20. 文件系统-Files & File Systems.ass.txt
│ ├── 21. 压缩-Compression.ass.txt
│ ├── 22. 命令行界面-Keyboards & Command Line Interfaces.ass.txt
│ ├── 23. 屏幕&2D 图形显示-Screens&2D Graphics.ass.txt
│ ├── 24. 冷战和消费主义-The Cold War and Consumerism.ass.txt
│ ├── 25. 个人计算机革命-The Personal Computer Revolution.ass.txt
│ ├── 26. 图形用户界面-Graphical User Interfaces.ass.txt
│ ├── 27. 3D 图形-3D Graphics.ass.txt
│ ├── 28. 计算机网络-Computer Networks.ass.txt
│ ├── 29. 互联网-The Internet.ass.txt
│ ├── 30. 万维网-The World Wide Web.ass.txt
│ ├── 31. 计算机安全-Cybersecurity.ass.txt
│ ├── 32. 黑客&攻击-Hackers & Cyber Attacks.ass.txt
│ ├── 33. 加密-Cryptography.ass.txt
│ ├── 34. 机器学习&人工智能-Machine Learning & Artificial Intelligence.ass.txt
│ ├── 35. 计算机视觉-Computer Vision.ass.txt
│ ├── 36. 自然语言处理-Natural Language Processing.ass.txt
│ ├── 37. 机器人-Robots.ass.txt
│ ├── 38. 计算机心理学 - Psychology of Computing.ass.txt
│ ├── 39. 教育科技-Educational Technology.ass.txt
│ └── 40. 奇点,天网,计算机的未来-The Singularity, Skynet, and the Future of Computing.ass.txt
├── (字幕)全40集中英字幕文本.txt
├── .gitignore
├── 1. screenshot.py
├── README-about-subtitle.md
├── README.md
└── extract_from_ass_subtitle/
├── 2. extract_head.js
├── 3. extract_ass_to_txt.js
├── README.md
├── common.js
└── package.json
================================================
FILE CONTENTS
================================================
================================================
FILE: (字幕)全40集中英字幕文本/01. 计算机早期历史-Early Computing.ass.txt
================================================
Hello world, I'm Carrie Anne, and welcome to Crash Course Computer Science!
Hello world!我是 Carrie Anne,欢迎收看计算机科学速成课!
Over the course of this series, we're going to go from bits, bytes, transistors and logic gates,
在这个系列中,我们会学习 Bits(位),Bytes(字节),晶体管, 逻辑门,
all the way to Operating Systems, Virtual Reality and Robots!
一直到操作系统,虚拟现实和机器人!
We're going to cover a lot, but just to clear things up
我们要学很多东西,但预先说明
we ARE NOT going to teach you how to program.
我们 *不会* 教你怎么编程
Instead, we're going to explore a range of computing topics as a discipline and a technology.
我们会从高层次上纵览一系列计算机话题
Computers are the lifeblood of today's world.
计算机是当今世界的命脉
If they were to suddenly turn off, all at once,
如果突然关掉所有的计算机
the power grid would shut down, cars would crash, planes would fall,
电网会关闭,车辆会相撞,飞机会坠毁
water treatment plants would stop, stock markets would freeze,
净水厂会关闭,证券市场会停止运作
trucks with food wouldn't know where to deliver, and employees wouldn't get paid.
装满食物的卡车不知运往何方,员工得不到薪水
Even many non-computer objects -like DFTBA shirts and the chair I'm sitting on-
甚至很多和计算机无关的东西,例如 DFTBA 的 T 恤和我现在坐的椅子
are made in factories run by computers.
也都是在计算机管理的工厂中制造的
Computing really has transformed nearly every aspect of our lives.
计算机改变了我们生活中几乎所有方面
And this isn't the first time we've seen this sort of technology-driven global change.
我们也不是第一次遇到推动全球发展的科技了
Advances in manufacturing during the Industrial Revolution
工业革命中生产能力的提高
brought a new scale to human civilization - in agriculture, industry and domestic life.
大幅提升了农业,工业,畜牧业的规模
Mechanization meant superior harvests and more food, mass produced goods,
机械化导致更好的收成,更多的食物,商品可以大批量生产
cheaper and faster travel and communication, and usually a better quality of life.
旅行和通讯变得更便宜更快,生活质量变得更好.
And computing technology is doing the same right now
计算机和工业革命有一样的影响
- from automated farming and medical equipment,
从自动化农业和医疗设备
to global telecommunications and educational opportunities,
到全球通信和教育机会
and new frontiers like Virtual Reality and Self Driving Cars.
还有 虚拟现实 和 无人驾驶汽车 等新领域
We are living in a time likely to be remembered as the Electronic Age.
现在这个时代很可能会被后人总结成 "信息时代"
And with billions of transistors in just your smartphones, computers can seem pretty complicated,
你的智能手机中有数十亿个晶体管,看起来好像很复杂
but really, they're just simple machines
但实际上它是很简单的机器
that perform complex actions through many layers of abstraction.
通过一层层的抽象 来做出复杂操作
So in this series, we're going break down those layers,
在这个系列中,我们会一层层讲解,
and build up from simple 1's and 0's, to logic units, CPUs,
从最底层的1和0,到逻辑门,CPU
operating systems, the entire internet and beyond.
操作系统,整个互联网,以及更多~~
And don't worry, in the same way someone buying t-shirts on a webpage
不用担心,正如在网上买T恤的人 不用知道网站代码是怎么写的
doesn't need to know how that webpage was programmed,
不用担心,正如在网上买T恤的人 不用知道网站代码是怎么写的
or the web designer doesn't need to know how all the packets are routed,
设计师不用知道数据包是怎么传输的
or router engineers don't need to know about transistor logic,
设计路由器的工程师不用理解晶体管的逻辑
this series will build on previous episodes but not be dependent on them.
本系列中每个视频会接着上集继续讲,但并不依赖前面的视频
By the end of this series,
等这个系列结束后
I hope that you can better contextualize computing's role both in your own life and society,
希望你能了解计算机在你的人生 以及社会中扮演什么角色
and how humanity's (arguably) greatest invention is just in its infancy,
以及这个人类史上最伟大的发明(可以这样说啦)是怎么开始的,
with its biggest impacts yet to come.
它对未来还会有更大的影响
But before we get into all that, we should start at computing's origins,
但深入之前,我们应该从计算的起源讲起,
because although electronic computers are relatively new, the need for computation is not.
虽然电子计算机才出现不久,但人类对计算的需求早就有了
The earliest recognized device for computing was the abacus,
公认最早的计算设备是 算盘
invented in Mesopotamia around 2500 BCE.
发明于"美索不达米亚",大约公元前 2500 年
It's essentially a hand operated calculator,
它是手动计算器,用来帮助加减数字
that helps add and subtract many numbers.
它是手动计算器,用来帮助加减数字
It also stores the current state of the computation, much like your hard drive does today.
它存储着当前的计算状态,类似于如今的硬盘
The abacus was created because,
人们制造算盘是因为
the scale of society had become greater than
社会的规模已经超出个人心算的能力
what a single person could keep and manipulate in their mind.
社会的规模已经超出个人心算的能力
There might be thousands of people in a village or tens of thousands of cattle.
一个村庄可能有上千个人和上万头牛
There are many variants of the abacus,
算盘有很多变种
but let's look at a really basic version with each row representing a different power of ten.
但我们来看一个基础版,每行代表 10 的不同次方
So each bead on the bottom row represents a single unit,
最底下那行,一个珠子代表 10 的 0 次方,也就是 1,
in the next row they represent 10, the row above 100, and so on.
再上面一行是 10 的 1 次方(也就是 10) \N 再上面一行是 10 的 2 次方 (以此类推)
Let's say we have 3 heads of cattle represented by 3 beads on the bottom row on the right side.
假设最底部的 3 颗珠子,代表 3 头牛
If we were to buy 4 more cattle we would just slide 4 more beads to the right for a total of 7.
假设再买 4 头牛,只需要向右移动 4 颗珠子,共 7 个珠子
But if we were to add 5 more after the first 3 we would run out of beads,
但如果再买 5 头,珠子就不够用了
so we would slide everything back to the left,
所以把所有珠子移回左边
slide one bead on the second row to the right, representing ten,
在第二排把 1 颗珠子向右移动,代表 10
and then add the final 2 beads on the bottom row for a total of 12.
然后最底下那行,向右移动 2 颗珠子,代表 12
This is particularly useful with large numbers.
这种方法处理大数字很有效
So if we were to add 1,251
假设要表示 1251
we would just add 1 to the bottom row, 5 to the second row, 2 to the third row, and 1 to the fourth row
从下往上:\N第一行移 1 个,第二行移 5 个\N第三行移 2 个,第四行移 1 个
- we don't have to add in our head and the abacus stores the total for us.
我们不用记在脑子里,算盘会记住.
Over the next 4000 years, humans developed all sorts of clever computing devices,
在接下来 4000 年,人类发明了各种巧妙的计算设备
like the astrolabe, which enabled ships to calculate their latitude at sea.
比如星盘,让船只可以在海上计算纬度
Or the slide rule, for assisting with multiplication and division.
或计算尺,帮助计算乘法和除法
And there are literally hundred of types of clocks created
人们还创造了上百种时钟
that could be used to calculate sunrise, tides, positions of celestial bodies, and even just the time.
算日出,潮汐,天体的位置,或纯粹拿来计时
Each one of these devices made something that was previously laborious to calculate much faster,
这些设备让原先很费力的事变得更快,更简单,更精确
easier, and often more accurate
这些设备让原先很费力的事变得更快,更简单,更精确
- it lowered the barrier to entry,
降低了门槛
and at the same time, amplified our mental abilities -
加强了我们的能力
take note, this is a theme we're going to touch on a lot in this series.
记笔记!(敲黑板)这个系列会多次提到这一点
As early computer pioneer Charles Babbage said:
计算机先驱 Charles Babbage 说过:
"At each increase of knowledge, as well as on the contrivance of every new tool,
"随着知识的增长和新工具的诞生,人工劳力会越来越少"
human labour becomes abridged."
"随着知识的增长和新工具的诞生,人工劳力会越来越少"
However, none of these devices were called "computers".
然而,这些设备那时都不叫 "计算机"
The earliest documented use of the word "computer" is from 1613, in a book by Richard Braithwait.
最早使用 "计算机" 一词的文献 \N 来自 1613 年的一本书,作者 Richard Braithwait
And it wasn't a machine at all - it was a job title.
然而指的不是机器,而是一种职业
Braithwait said,
Braithwait 说:
"I have read the truest computer of times,
"我听说过的计算者里最厉害的,能把好几天的工作量大大缩减"
and the best arithmetician that ever breathed, and he reduceth thy dayes into a short number".
"我听说过的计算者里最厉害的,能把好几天的工作量大大缩减"
In those days, computer was a person who did calculations,
那时, "Computer" 指负责计算的人
sometimes with the help of machines, but often not.
"Computer" 偶尔会用机器帮忙,但大部分时候靠自己
This job title persisted until the late 1800s,
这个职位一直到 1800 年代还存在
when the meaning of computer started shifting to refer to devices.
之后 "Computer" 逐渐开始代表机器
Notable among these devices was the Step Reckoner,
其中"步进计算器"最有名
built by German polymath Gottfried Leibniz in 1694.
由德国博学家 戈特弗里德·莱布尼茨 建造于 1694 年
Leibniz said "... it is beneath the dignity of excellent men to waste their time in calculation
莱布尼茨说过 "... 让优秀的人浪费时间算数简直侮辱尊严
when any peasant could do the work just as accurately with the aid of a machine."
农民用机器能算得一样准"
It worked kind of like the odometer in your car,
"步进计算器"有点像汽车里的里程表,不断累加里程数
which is really just a machine for adding up the number of miles your car has driven.
"步进计算器"有点像汽车里的里程表,不断累加里程数
The device had a series of gears that turned;
它有一连串可以转动的齿轮
each gear had ten teeth, to represent the digits from 0 to 9.
每个齿轮有十个齿,代表数字0到9
Whenever a gear bypassed nine, it rotated back to 0 and advanced the adjacent gear by one tooth.
每当一个齿轮转过 9,它会转回 0,同时让旁边的齿轮前进 1 个齿
Kind of like when hitting 10 on that basic abacus.
就像算盘超过 10 一样.
This worked in reverse when doing subtraction, too.
做减法时,机器会反向运作.
With some clever mechanical tricks,
利用一些巧妙的机械结构
the Step Reckoner was also able to multiply and divide numbers.
步进计算器也能做乘法和除法
Multiplications and divisions are really just many additions and subtractions.
乘法和除法 实际上只是多个加法和减法
For example, if we want to divide 17 by 5, we just subtract 5, then 5, then 5 again,
举例,17除以5,我们只要减5,减5,再减5
and then we can't subtract any more 5's… so we know 5 goes into 17 three times, with 2 left over.
直到不能再减 5,就知道了 17=5x3+2
The Step Reckoner was able to do this in an automated way,
步进计算器 可以自动完成这种操作
and was the first machine that could do all four of these operations.
它是第一台能做"加减乘除"全部四种运算的机器
And this design was so successful it was used for the next three centuries of calculator design.
它的设计非常成功,以至于沿用了 3 个世纪.
Unfortunately, even with mechanical calculators,
不幸的是,即使有机械计算器
most real world problems required many steps of computation before an answer was determined.
许多现实问题 依然需要很多步
It could take hours or days to generate a single result.
算一个结果可能要几小时甚至几天
Also, these hand-crafted machines were expensive, and not accessible to most of the population.
而且这些手工制作的机器非常昂贵,大部分人买不起
So, before 20th century,
所以在 20 世纪以前
most people experienced computing through pre-computed tables
大部分人会用预先算好的计算表
assembled by those amazing "human computers" we talked about.
这些计算表由之前说的 "人力计算器" 编撰
So if you needed to know the square root of 8 million 6 hundred and 75 thousand 3 hundred and 9,
如果你想知道 867,5309 的平方根
instead of spending all day hand-cranking your step reckoner,
与其花一整天来手摇 "步进计算器"
you could look it up in a huge book full of square root tables in a minute or so.
你可以花一分钟在表里找答案
Speed and accuracy is particularly important on the battlefield,
速度和准确性在战场上尤为重要
and so militaries were among the first to apply computing to complex problems.
因此军队很早就开始用计算解决复杂问题
A particularly difficult problem is accurately firing artillery shells,
如何精确瞄准炮弹是一个很难的问题
which by the 1800s could travel well over a kilometer (or a bit more than half a mile).
19世纪,这些炮弹的射程可以达到 1 公里以上(比半英里多一点)
Add to this varying wind conditions, temperature, and atmospheric pressure,
因为风力,温度,大气压力会不断变化
and even hitting something as large as a ship was difficult.
想打中船一样大的物体也非常困难
Range Tables were created that allowed gunners to look up environmental conditions
于是出现了射程表,炮手可以查环境条件和射击距离
and the distance they wanted to fire,
于是出现了射程表,炮手可以查环境条件和射击距离
and the table would tell them the angle to set the canon.
然后这张表会告诉他们,角度要设成多少
These Range Tables worked so well, they were used well into World War Two.
这些射程表很管用,二战中被广泛应用
The problem was, if you changed the design of the cannon or of the shell,
问题是如果改了大炮或炮弹的设计,就要算一张新表
a whole new table had to be computed,
问题是如果改了大炮或炮弹的设计,就要算一张新表
which was massively time consuming and inevitably led to errors.
这样很耗时而且会出错
Charles Babbage acknowledged this problem in 1822
Charles Babbage 在 1822 年写了一篇论文
in a paper to the Royal Astronomical Society entitled:
向皇家天文学会指出了这个问题
"Note on the application of machinery to the computation of astronomical and mathematical tables".
标题叫: "机械在天文与计算表中的应用"
Let's go to the thought bubble.
让我们进入思想泡泡
Charles Babbage proposed a new mechanical device called the Difference Engine,
Charles Babbage 提出了一种新型机械装置叫 "差分机"
a much more complex machine that could approximate polynomials.
一个更复杂的机器,能近似多项式.
Polynomials describe the relationship between several variables
多项式描述了几个变量之间的关系
- like range and air pressure, or amount of pizza Carrie Anne eats and happiness.
比如射程和大气压力,或者 Carrie Anne 要吃多少披萨才开心
Polynomials could also be used to approximate logarithmic and trigonometric functions,
多项式也可以用于近似对数和三角函数
which are a real hassle to calculate by hand.
这些函数手算相当麻烦
Babbage started construction in 1823,
Charles Babbage 在 1823 年开始建造差分机
and over the next two decades, tried to fabricate and assemble the 25,000 components,
并在接下来二十年,试图制造和组装 25,000 个零件
collectively weighing around 15 tons.
总重接近 15 吨
Unfortunately, the project was ultimately abandoned.
不幸的是,该项目最终放弃了
But, in 1991,
但在 1991 年
historians finished constructing a Difference Engine based on Babbage's drawings and writings
历史学家根据 Charles Babbage 的草稿做了一个差分机
- and it worked!
而且它还管用!
But more importantly, during construction of the Difference Engine,
但更重要的是,在差分机的建造期间
Babbage imagined an even more complex machine - the Analytical Engine.
Charles Babbage 构想了一个更复杂的机器 - 分析机
Unlike the Difference Engine,
不像差分机,步进计算器 和以前的其他计算设备
Step Reckoner and all other computational devices before it
不像差分机,步进计算器 和以前的其他计算设备
- the Analytical Engine was a "general purpose computer".
分析机是 "通用计算机"
It could be used for many things, not just one particular computation;
它可以做很多事情,不只是一种特定运算
it could be given data and run operations in sequence;
甚至可以给它数据,然后按顺序执行一系列操作
it had memory and even a primitive printer.
它有内存 甚至一个很原始的打印机
Like the Difference Engine, it was ahead of its time, and was never fully constructed.
就像差分机,这台机器太超前了,所以没有建成
However, the idea of an "automatic computer"
然而,这种 "自动计算机" 的概念
- one that could guide itself through a series of operations automatically,
-计算机可以自动完成一系列操作
was a huge deal, and would foreshadow computer programs.
是个跨时代的概念,预示着计算机程序的诞生
English mathematician Ada Lovelace wrote hypothetical programs for the Analytical Engine, saying,
英国数学家 Ada Lovelace 给分析机写了假想的程序,她说:
"A new, a vast, and a powerful language is developed for the future use of analysis."
"未来会诞生一门全新的,强大的,专为分析所用的语言"
For her work, Ada is often considered the world's first programmer.
因此 Ada 被认为是世上第一位程序员.
The Analytical Engine would inspire, arguably, the first generation of computer scientists,
分析机激励了(可以这么讲)第一代计算机科学家
who incorporated many of Babbage's ideas in their machines.
这些计算机科学家 \N 把很多 Charles Babbage 的点子融入到他们的机器
This is why Babbage is often considered the "father of computing".
所以 Charles Babbage 经常被认为是 "计算之父"
Thanks! Thought Bubble
谢啦!思想泡泡
So by the end of the 19th century,
到了 19 世纪末
computing devices were used for special purpose tasks in the sciences and engineering,
科学和工程领域中的特定任务 会用上计算设备
but rarely seen in business, government or domestic life.
但公司,政府,家庭中很少见到计算设备
However, the US government faced a serious problem for its 1890 census
然而,美国政府在 1890 年的人口普查中面临着严重的问题
that demanded the kind of efficiency that only computers could provide.
只有计算机能提供所需的效率
The US Constitution requires that a census be conducted every ten years,
美国宪法要求 10 年进行一次人口普查
for the purposes of distributing federal funds, representation in congress, and good stuff like that.
目的是分配联邦资金,国会代表,等等
And by 1880s, the US population was booming, mostly due to immigration.
到 1880 年代,美国人口迅速增长,大部分因为移民
That census took seven years to manually compile
人口普查要七年时间来手工编制,等做完都过时了
and by the time it was completed, it was already out of date
人口普查要七年时间来手工编制,等做完都过时了
- and it was predicted that the 1890 census would take 13 years to compute.
而且 1890 年的人口普查,预计要 13 年完成
That's a little problematic when it's required every decade!
但人口普查可是 10 年一次啊!
The Census bureau turned to Herman Hollerith, who had built a tabulating machine.
人口普查局找了 Herman Hollerith,他发明了打孔卡片制表机
His machine was "electro-mechanical"
他的机器是 "电动机械的"
- it used traditional mechanical systems for keeping count,
- 用传统机械来计数
like Leibniz's Step Reckoner - but coupled them with electrically-powered components.
结构类似莱布尼茨的乘法器,但用电动结构连接其他组件
Hollerith's machine used punch cards
Hollerith 的机器用打孔卡
which were paper cards with a grid of locations that can be punched out to represent data.
一种纸卡,上面有网格,用打孔来表示数据.
For example, there was a series of holes for marital status.
举个例子,有一连串孔代表婚姻状况
If you were married, you would punch out the married spot,
如果你结婚了,就在 "结婚" 的位置打孔
then when the card was inserted into Hollerith's machine, little metal pins would come down over the card
当卡插入 Hollerith 的机器时,小金属针会到卡片上
- if a spot was punched out, the pin would pass through the hole in the paper
-如果有个地方打孔了,针会穿过孔
and into a little vial of mercury, which completed the circuit.
泡入一小瓶汞,联通电路
This now completed circuit powered an electric motor,
电路会驱动电机
which turned a gear to add one, in this case, to the "married" total.
然后给 "已婚" 的齿轮 + 1
Hollerith's machine was roughly 10x faster than manual tabulations,
Hollerith 的机器速度是手动的 10 倍左右
and the Census was completed in just two and a half years
使人口普查在短短两年半内完成
- saving the census office millions of dollars.
给人口普查办公室省了上百万美元
Businesses began recognizing the value of computing,
企业开始意识到计算机的价值
and saw its potential to boost profits by improving labor- and data-intensive tasks,
可以提升劳动力以及数据密集型任务 来提升利润
like accounting, insurance appraisals, and inventory management.
比如会计,保险评估和库存管理等行业
To meet this demand, Hollerith founded The Tabulating Machine Company,
为了满足这一需求,Hollerith 成立了制表机器公司
which later merged with other machine makers in 1924
这家公司后来在 1924 年与其它机械制造商合并
to become The International Business Machines Corporation or IBM
成为了 "国际商业机器公司",简称 IBM
- which you've probably heard of.
-你可能听过 IBM
These electro-mechanical "business machines" were a huge success, transforming commerce and government,
这些电子机械的 "商业机器" 取得了巨大成功,改变了商业和政府.
and by the mid-1900s, the explosion in world population and the rise of globalized trade
到了 1900 年代中叶,世界人口的爆炸和全球贸易的兴起
demanded even faster and more flexible tools for processing data,
要求更快,更灵活的工具来处理数据
setting the stage for digital computers,
为电子计算机的发展奠定了基础
which we'll talk about next week.
我们下周讨论
================================================
FILE: (字幕)全40集中英字幕文本/02. 电子计算机-Electronic Computing.ass.txt
================================================
Our last episode brought us to the start of the 20th century,
上集讲到 20 世纪初
where early, special purpose computing devices, like tabulating machines,
当时的早期计算设备都针对特定用途 比如 制表机
were a huge boon to governments and business
大大推进了政府和企业
- aiding, and sometimes replacing, rote manual tasks.
它们帮助, 甚至代替了人工
But the scale of human systems continued to increase at an unprecedented rate.
然而人类社会的规模 在以前所未有的速度增长
The first half of the 20th century saw the world's population almost double.
20世纪上半叶,世界人口几乎翻倍
World War 1 mobilized 70 million people, and World War 2 involved more than 100 million.
一战动员7千万人,二战1亿多人
Global trade and transit networks became interconnected like never before,
全球贸易和运输更加紧密
and the sophistication of our engineering and scientific endeavors reached new heights
工程和科学的复杂度也达到新高
- we even started to seriously consider visiting other planets.
- 我们甚至开始考虑造访其他行星
And it was this explosion of complexity, bureaucracy, and ultimately data,
复杂度的增高导致数据量暴增
that drove an increasing need for automation and computation.
人们需要更多自动化 更强的计算能力
Soon those cabinet-sized electro-mechanical computers grew into room-sized behemoths
很快,柜子大小的计算机变成房间大小
that were expensive to maintain and prone to errors.
维护费用高 而且容易出错
And it was these machines that would set the stage for future innovation.
而正是这些机器 为未来的创新打下基础
One of the largest electro-mechanical computers built was the Harvard Mark I,
最大的机电计算机之一是 哈佛马克一号
completed in 1944 by IBM for the Allies during World War 2.
IBM 在 1944 完成建造,给二战同盟国建造的.
It contained 765,000 components, three million connections, and five hundred miles of wire.
它有76万5千个组件,300万个连接点和500英里长的导线
To keep its internal mechanics synchronized,
为了保持内部机械装置同步
it used a 50-foot shaft running right through the machine driven by a five horsepower motor.
它有一个50英尺的传动轴,由一个 5 马力的电机驱动
One of the earliest uses for this technology was running simulations for the Manhattan Project.
这台机器最早的用途之一 是给"曼哈顿计划"跑模拟
The brains of these huge electro-mechanical beasts were relays:
这台机器的大脑是"继电器"
electrically-controlled mechanical switches.
继电器是:用电控制的机械开关
In a relay, there is a control wire that determines whether a circuit is opened or closed.
继电器里,有根"控制线路",控制电路是开还是关
The control wire connects to a coil of wire inside the relay.
"控制线路" 连着一个线圈
When current flows through the coil, an electromagnetic field is created,
当电流流过线圈,线圈产生电磁场
which in turn, attracts a metal arm inside the relay, snapping it shut and completing the circuit.
吸引金属臂,从而闭合电路
You can think of a relay like a water faucet.
你可以把继电器 想成水龙头
The control wire is like the faucet handle.
把控制线路 想成水龙头把
Open the faucet, and water flows through the pipe.
打开水龙头,水会流出来
Close the faucet, and the flow of water stops.
关闭水龙头,水就没有了
Relays are doing the same thing, just with electrons instead of water.
继电器是一样的,只不过控制的是电子 而不是水
The controlled circuit can then connect to other circuits, or to something like a motor,
这个控制电路可以连到其他电路,比如马达
which might increment a count on a gear,
马达让计数齿轮 +1
like in Hollerith's tabulating machine we talked about last episode.
就像上集中 Hollerith 的制表机一样
Unfortunately, the mechanical arm inside of a relay *has mass*,
不幸的是,继电器内的机械臂 *有质量*
and therefore can't move instantly between opened and closed states.
因此无法快速开关
A good relay in the 1940's might be able to flick back and forth fifty times in a second.
1940 年代一个好的继电器 1 秒能翻转 50 次
That might seem pretty fast, but it's not fast enough to be useful at solving large, complex problems.
看起来好像很快,但还不够快,不足以解决复杂的大问题
The Harvard Mark I could do 3 additions or subtractions per second;
哈佛马克一号,1 秒能做 3 次加法或减法运算
multiplications took 6 seconds, and divisions took 15.
一次乘法要花 6 秒,除法要花 15 秒
And more complex operations, like a trigonometric function, could take over a minute.
更复杂的操作 比如三角函数,可能要一分钟以上
In addition to slow switching speed, another limitation was wear and tear.
除了速度慢,另一个限制是齿轮磨损
Anything mechanical that moves will wear over time.
任何会动的机械都会随时间磨损
Some things break entirely, and other things start getting sticky, slow, and just plain unreliable.
有些部件会完全损坏,有些则是变黏,变慢,变得不可靠
And as the number of relays increases, the probability of a failure increases too.
并且随着继电器数量增加,故障概率也会增加
The Harvard Mark I had roughly 3500 relays.
哈佛马克一号 有大约 3500 个继电器
Even if you assume a relay has an operational life of 10 years,
哪怕假设继电器的使用寿命是 10 年
this would mean you'd have to replace, on average, one faulty relay every day!
也意味着平均每天得换一个故障继电器!
That's a big problem when you are in the middle of running some important, multi-day calculation.
这个问题很严重,因为有些重要运算要运行好几天
And that's not all engineers had to contend with.
而且还有更多其他问题要考虑
These huge, dark, and warm machines also attracted insects.
这些巨大,黑色,温暖的机器也会吸引昆虫
In September 1947, operators on the Harvard Mark II pulled a dead moth from a malfunctioning relay.
1947年9月,哈佛马克2型的操作员从故障继电器中,拔出一只死虫
Grace Hopper who we'll talk more about in a later episode noted,
Grace Hopper(这位我们以后还会提到)曾说
"From then on, when anything went wrong with a computer,
"从那时起,每当电脑出了问题,
we said it had bugs in it."
我们就说它出了 bug(虫子)"
And that's where we get the term computer bug.
这就是术语 "bug" 的来源
It was clear that a faster, more reliable alternative to electro-mechanical relays was needed
显然,如果想进一步提高计算能力
if computing was going to advance further,
我们需要更快更可靠的东西,来替代继电器
and fortunately that alternative already existed!
幸运的是,替代品已经存在了!
In 1904, English physicist John Ambrose Fleming
在 1904 年,英国物理学家 "约翰·安布罗斯·弗莱明"
developed a new electrical component called a thermionic valve,
开发了一种新的电子组件,叫"热电子管"
which housed two electrodes inside an airtight glass bulb
把两个电极装在一个气密的玻璃灯泡里
- this was the first vacuum tube.
-这是世上第一个真空管
One of the electrodes could be heated, which would cause it to emit electrons
其中一个电极可以加热,从而发射电子
– a process called thermionic emission.
-这叫 "热电子发射"
The other electrode could then attract these electrons to create the flow of our electric faucet,
另一个电极会吸引电子,形成"电龙头"的电流
but only if it was positively charged
但只有带正电才行
- if it had a negative or neutral charge, the electrons would no longer be attracted across the vacuum
- 如果带负电荷或中性电荷,电子就没办法被吸引,越过真空区域
so no current would flow.
因此没有电流
An electronic component that permits the one-way flow of current is called a diode,
电流只能单向流动的电子部件叫 "二极管"
but what was really needed was a switch to help turn this flow on and off.
但我们需要的是,一个能开关电流的东西
Luckily, shortly after, in 1906, American inventor Lee de Forest
幸运的是,不久之后在 1906 年,美国发明家 "李·德富雷斯特"
added a third "control" electrode that sits between the two electrodes in Fleming's design.
他在"弗莱明"设计的两个电极之间,加入了第三个 "控制" 电极
By applying a positive charge to the control electrode, it would permit the flow of electrons as before.
向"控制"电极施加正电荷,它会允许电子流动
But if the control electrode was given a negative charge,
但如果施加负电荷
it would prevent the flow of electrons.
它会阻止电子流动
So by manipulating the control wire, one could open or close the circuit.
因此通过控制线路,可以断开或闭合电路
It's pretty much the same thing as a relay
和继电器的功能一样
- but importantly, vacuum tubes have no moving parts.
- 但重要的是,真空管内没有会动的组件
This meant there was less wear,
这意味着更少的磨损
and more importantly, they could switch thousands of times per second.
更重要的是,每秒可以开闭数千次
These triode vacuum tubes would become the basis of radio, long distance telephone,
因此这些"三极真空管"成为了无线电,长途电话
and many other electronic devices for nearly a half century.
以及其他电子设备的基础,持续了接近半个世纪
I should note here that vacuum tubes weren't perfect
我应该提到,真空管不是完美的
- they're kind of fragile, and can burn out like light bulbs,
-它们有点脆弱,并且像灯泡一样会烧坏
they were a big improvement over mechanical relays.
但比起机械继电器是一次巨大进步
Also, initially vacuum tubes were expensive
起初,真空管非常昂贵
– a radio set often used just one,
收音机一般只用一个
but a computer might require hundreds or thousands of electrical switches.
但计算机可能要上百甚至上千个电气开关
But by the 1940s,
但到了 1940 年代
their cost and reliability had improved to the point where they became feasible for use in computers….
它的成本和可靠性得到改进,可以用在计算机里
at least by people with deep pockets, like governments.
至少有钱人负担得起,比如政府
This marked the shift from electro-mechanical computing to electronic computing.
这标志着计算机 从机电转向电子
Let's go to the Thought Bubble.
我们来进入思想泡泡
The first large-scale use of vacuum tubes for computing was the Colossus MK 1,
第一个大规模使用真空管的计算机是 "巨人1号"
designed by engineer Tommy Flowers and completed in December of 1943.
由工程师 Tommy Flowers 设计,完工于1943年12月
The Colossus was installed at Bletchley Park, in the UK,
巨人1号 在英国的"布莱切利园", 用于破解纳粹通信
and helped to decrypt Nazi communications.
巨人1号 在英国的"布莱切利园", 用于破解纳粹通信
This may sound familiar because two years prior Alan Turing,
听起来可能有点熟,因为 2 年前 阿兰·图灵
often called the father of computer science,
他经常被称为"计算机科学之父"
had created an electromechanical device, also at Bletchley Park, called the Bombe.
图灵也在"布莱切利园"做了台机电装置,叫 "Bombe"
It was an electromechanical machine designed to break Nazi Enigma codes,
这台机器的设计目的是 破解纳粹"英格码"通讯加密设备
but the Bombe wasn't technically a computer,
但 Bombe 严格来说不算计算机
and we'll get to Alan Turing's contributions later.
我们之后会讨论"阿兰·图灵"的贡献
Anyway, the first version of Colossus contained 1,600 vacuum tubes,
总之,巨人1号有 1600 个真空管
and in total, ten Colossi were built to help with code-breaking.
总共造了 10 台巨人计算机,来帮助破解密码
Colossus is regarded as the first programmable, electronic computer.
巨人 被认为是第一个可编程的电子计算机
Programming was done by plugging hundreds of wires into plugboards,
编程的方法是把几百根电线插入插板
sort of like old school telephone switchboards,
有点像老电话交换机
in order to set up the computer to perform the right operations.
这是为了让计算机执行正确操作
So while "programmable", it still had to be configured to perform a specific computation.
虽然"可编程" ,但还是要配置它
Enter the The Electronic Numerical Integrator and Calculator - or ENIAC -
电子数值积分计算机 "ENIAC"
completed a few years later in 1946 at the University of Pennsylvania.
几年后在 1946 年,在"宾夕法尼亚大学"完成建造
Designed by John Mauchly and J. Presper Eckert,
设计者是 John Mauchly 和 J. Presper Eckert
this was the world's first truly general purpose, programmable, electronic computer.
这是世上第一个真正的通用,可编程,电子计算机
ENIAC could perform 5000 ten-digit additions or subtractions per second,
ENIAC 每秒可执行 5000 次十位数加减法
many, many times faster than any machine that came before it.
比前辈快了很多倍
It was operational for ten years,
它运作了十年
and is estimated to have done more arithmetic than the entire human race up to that point.
据估计,它完成的运算,比全人类加起来还多
But with that many vacuum tubes failures were common,
因为真空管很多,所以故障很常见
and ENIAC was generally only operational for about half a day at a time before breaking down.
ENIAC 运行半天左右就会出一次故障
Thanks Thought Bubble.
谢了 思想泡泡
By the 1950's, even vacuum-tube-based computing was reaching its limits.
到 1950 年代,真空管计算机都达到了极限
The US Air Force's AN/FSQ-7 computer, which was completed in 1955,
美国空军的 AN/FSQ-7 计算机于 1955 年完成
was part of the "SAGE" air defense computer system,
是 "SAGE" 防空计算机系统的一部分
which we'll talk more about in a later episode.
之后的视频还会提到.
To reduce cost and size, as well as improve reliability and speed,
为了降低成本和大小,同时提高可靠性和速度
a radical new electronic switch would be needed.
我们需要一种新的电子开关
In 1947, Bell Laboratory scientists John Bardeen, Walter Brattain, and William Shockley
1947 年,贝尔实验室科学家 \N John Bardeen,Walter Brattain,William Shockley
invented the transistor,
发明了晶体管
and with it, a whole new era of computing was born!
一个全新的计算机时代诞生了!
The physics behind transistors is pretty complex, relying on quantum mechanics,
晶体管的物理学相当复杂,牵扯到量子力学
so we're going to stick to the basics.
所以我们只讲基础
A transistor is just like a relay or vacuum tube
晶体管 就像之前提过的"继电器"或"真空管"
- it's a switch that can be opened or closed by applying electrical power via a control wire.
-它是一个开关,可以用控制线路来控制开或关
Typically, transistors have two electrodes separated by a material that sometimes can conduct electricity,
晶体管有两个电极,\N 电极之间有一种材料隔开它们,这种材料有时候导电
and other times resist it
有时候不导电
- a semiconductor.
- 这叫"半导体"
In this case, the control wire attaches to a "gate" electrode.
控制线连到一个 "门" 电极
By changing the electrical charge of the gate,
通过改变 "门" 的电荷
the conductivity of the semiconducting material can be manipulated,
我们可以控制半导体材料的导电性
allowing current to flow or be stopped
来允许或不允许 电流流动
- like the water faucet analogy we discussed earlier.
- 就像之前的水龙头比喻
Even the very first transistor at Bell Labs showed tremendous promise
贝尔实验室的第一个晶体管就展示了巨大的潜力
- it could switch between on and off states 10,000 times per second.
每秒可以开关 10,000 次
Further, unlike vacuum tubes made of glass and with carefully suspended, fragile components,
而且,比起玻璃制成,小心易碎的真空管
transistors were solid material known as a solid state component.
晶体管是固态的
Almost immediately, transistors could be made smaller than the smallest possible relays or vacuum tubes.
晶体管可以远远小于继电器或真空管
This led to dramatically smaller and cheaper computers, like the IBM 608, released in 1957
导致更小更便宜的计算机,比如1957年发布的IBM 608
– the first fully transistor-powered, commercially-available computer.
- 第一个完全用晶体管,而且消费者也可以买到的计算机
It contained 3000 transistors and could perform 4,500 additions,
它有 3000 个晶体管,每秒执行 4500 次加法
or roughly 80 multiplications or divisions, every second.
每秒能执行 80 次左右的乘除法
IBM soon transitioned all of its computing products to transistors,
IBM 很快把所有产品都转向了晶体管
bringing transistor-based computers into offices, and eventually, homes.
把晶体管计算机带入办公室,最终引入家庭
Today, computers use transistors that are smaller than 50 nanometers in size
如今,计算机里的晶体管小于 50 纳米
- for reference, a sheet of paper is roughly 100,000 nanometers thick.
- 而一张纸的厚度大概是 10 万纳米
And they're not only incredibly small, they're super fast
晶体管不仅小,还超级快
- they can switch states millions of times per second, and can run for decades.
- 每秒可以切换上百万次,并且能工作几十年
A lot of this transistor and semiconductor development happened
很多晶体管和半导体的开发在"圣克拉拉谷"
in the Santa Clara Valley, between San Francisco and San Jose, California.
这个地方在加州,位于"旧金山"和"圣荷西"之间
As the most common material used to create semiconductors is silicon,
而生产半导体最常见的材料是 "硅"
this region soon became known as Silicon Valley.
所以这个地区被称为 "硅谷"
Even William Shockley moved there, founding Shockley Semiconductor,
甚至 William Shockley 都搬了过去,创立了"肖克利半导体"
whose employees later founded Fairchild Semiconductors,
里面的员工后来成立了"仙童半导体"
whose employees later founded Intel - the world's largest computer chip maker today.
这里面的员工后来创立了英特尔 - 当今世界上最大的计算机芯片制造商
Ok, so we've gone from relays to vacuum tubes to transistors.
好了,我们从"继电器"到"真空管"到"晶体管"
We can turn electricity on and off really, really, really fast.
我们可以让电路开闭得非常非常快
But how do we get from transistors to actually computing something,
但我们是如何用晶体管做计算的?
especially if we don't have motors and gears?
我们没有马达和齿轮啊?
That's what we're going to cover over the next few episodes.
我们接下来几集会讲
Thanks for watching. See you next week.
感谢观看 下周见
================================================
FILE: (字幕)全40集中英字幕文本/03. 布尔逻辑 和 逻辑门-Boolean Logic & Logic Gates.ass.txt
================================================
Hi, I'm Carrie Anne and welcome to Crash Course Computer Science!
嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
Today we start our journey up the ladder of abstraction,
今天我们开始"抽象"的旅程
where we leave behind the simplicity of being able to see every switch and gear,
不用管底层细节,把精力用来构建更复杂的系统
but gain the ability to assemble increasingly complex systems.
不用管底层细节,把精力用来构建更复杂的系统
Last episode, we talked about how computers evolved from electromechanical devices,
上集,我们谈了计算机最早是机电设备
that often had decimal representations of numbers
一般用十进制计数
- like those represented by teeth on a gear
- 比如用齿轮数来代表十进制
- to electronic computers with transistors that can turn the flow of electricity on or off.
- 再到晶体管计算机
And fortunately, even with just two states of electricity,
幸运的是,只用 开/关 两种状态也可以代表信息
we can represent important information.
幸运的是,只用 开/关 两种状态也可以代表信息
We call this representation Binary
这叫 二进制
-- which literally means "of two states",
- 意思是"用两种状态表示"
in the same way a bicycle has two wheels or a biped has two legs.
就像自行车有两个轮,双足动物有两条腿
You might think two states isn't a lot to work with, and you'd be right!
你可能觉得两种状态不多,你是对的!
But, it's exactly what you need for representing the values "true" and "false".
但如果只需要表示 true 和 false,两个值就够了
In computers, an "on" state, when electricity is flowing, represents true.
电路闭合,电流流过,代表 "真"
The off state, no electricity flowing, represents false.
电路断开,无电流流过,代表"假"
We can also write binary as 1's and 0's instead of true's and false's
二进制也可以写成 1 和 0 而不是 true 和 false
- they are just different expressions of the same signal
- 只是不同的表达方式罢了
- but we'll talk more about that in the next episode.
- 我们下集会讲更多细节
Now it is actually possible to use transistors for more than just turning electrical current on and off,
晶体管的确可以不只是 开/关,还可以让不同大小的电流通过
and to allow for different levels of current.
晶体管的确可以不只是 开/关,还可以让不同大小的电流通过
Some early electronic computers were ternary, that's three states,
一些早期电子计算机是三进制的,有 3 种状态
and even quinary, using 5 states.
甚至五进制,5 种状态
The problem is, the more intermediate states there are,
问题是,状态越多,越难区分信号
the harder it is to keep them all seperate
问题是,状态越多,越难区分信号
-- if your smartphone battery starts running low or there's electrical noise
- 如果手机快没电了或者附近有电噪音
because someone's running a microwave nearby,
因为有人在用微波炉,
the signals can get mixed up...
信号可能会混在一起...
and this problem only gets worse with transistors changing states millions of times per second!
而每秒百万次变化的晶体管会让这个问题变得更糟!
So, placing two signals as far apart as possible
所以我们把两种信号尽可能分开
- using just 'on and off' - gives us the most distinct signal to minimize these issues.
- 只用"开"和"关"两种状态,可以尽可能减少这类问题
Another reason computers use binary
计算机用二进制的另一个原因是
is that an entire branch of mathematics already existed that dealt exclusively with true and false values.
有一整个数学分支存在,专门处理"真"和"假"
And it had figured out all of the necessary rules and operations for manipulating them.
它已经解决了所有法则和运算
It's called Boolean Algebra!
叫"布尔代数"!
George Boole, from which Boolean Algebra later got its name,
乔治·布尔(George Boole)是布尔二字的由来
was a self-taught English mathematician in the 1800s.
是一位 19 世纪自学成才的英国数学家
He was interested in representing logical statements that went "under, over, and beyond"
他有兴趣用数学式子 扩展亚里士多德基于哲学的逻辑方法
Aristotle's approach to logic, which was, unsurprisingly, grounded in philosophy.
他有兴趣用数学式子 扩展亚里士多德基于哲学的逻辑方法
Boole's approach allowed truth to be systematically and formally proven, through logic equations
布尔用 逻辑方程 系统而正式的证明真理(truth)
which he introduced in his first book, "The Mathematical Analysis of Logic" in 1847.
他在 1847 年的第一本书"逻辑的数学分析"中介绍过
In "regular" algebra -- the type you probably learned in high school -- the values of variables
在"常规"代数里 - 你在高中学的那种 - 变量的值
are numbers, and operations on those numbers are things like addition and multiplication.
是数字,可以进行加法或乘法之类的操作
But in Boolean Algebra, the values of variables are true and false, and the operations are logical.
但在布尔代数中,变量的值是 true 和 false,\N 能进行逻辑操作
There are three fundamental operations in Boolean Algebra: a NOT, an AND, and an OR operation.
布尔代数中有三个基本操作:NOT, AND 和 OR
And these operations turn out to be really useful so we're going to look at them individually.
这些操作非常有用,我们一个个来看
A NOT takes a single boolean value, either true or false, and negates it.
NOT 操作把布尔值反转,\N把 true 进行 NOT 就会变成 false,反之亦然
It flips true to false, and false to true.
NOT 操作把布尔值反转,\N把 true 进行 NOT 就会变成 false,反之亦然
We can write out a little logic table that shows the original value under Input,
我们可以根据 NOT 操作的输入和输出,做出这个表
and the outcome after applying the operation under Output.
我们可以根据 NOT 操作的输入和输出,做出这个表
Now here's the cool part -- we can easily build boolean logic out of transistors.
酷的地方是 - 用晶体管可以轻松实现这个逻辑
As we discussed last episode, transistors are really just little electrically controlled switches.
上集说过,晶体管只是电控制的开关
They have three wires: two electrodes and one control wire.
有 3 根线:2 根电极和 1 根控制线
When you apply electricity to the control wire,
控制线通电时
it lets current flow through from one electrode, through the transistor, to the other electrode.
电流就可以从一个电极流到另一个电极
This is a lot like a spigot on a pipe
就像水龙头一样
-- open the tap, water flows,
- 打开水龙头,就有水流出来
close the tap, water shuts off.
关掉水龙头,就没水了
You can think of the control wire as an input,
可以把控制线,当做输入 ( input ) \N 底部的电极,当做输出(output)
and the wire coming from the bottom electrode as the output.
可以把控制线,当做输入 ( input ) \N 底部的电极,当做输出(output)
So with a single transistor, we have one input and one output.
所以 1 个晶体管,有一个输入和一个输出
If we turn the input on, the output is also on because the current can flow through it.
如果我们打开输入(input on) \N 输出也会打开(output on) \N 因为电流可以流过
If we turn the input off, the output is also off and the current can no longer pass through.
如果关闭输入(input off) \N 输出也会关闭(output off)\N 因为电流无法通过
Or in boolean terms, when the input is true, the output is true.
或者用布尔术语来说\N 输入为 真,输出为 真
And when the input is false, the output is also false.
输入为 假 \N 输出为 假
Which again we can show on a logic table.
我们也可以把这个做成"真值表"
This isn't a very exciting circuit though because its not doing anything
这个电路没什么意思,因为它没做什么事
-- the input and output are the same.
- 输入和输出是一样的
But, we can modify this circuit just a little bit to create a NOT.
但我们可以稍加修改,实现 NOT
Instead of having the output wire at the end of the transistor, we can move it before.
与其把下面那根线当做 输出,我们可以把 输出 放到上面
If we turn the input on, the transistor allows current to pass through it to the "ground",
如果打开 输入,电流可以流过然后 "接地"
and the output wire won't receive that current
输出就没有电流,所以输出是 off
- so it will be off.
输出就没有电流,所以输出是 off
In our water metaphor grounding would be like
如果用水来举例
if all the water in your house was flowing out of a huge hose
就像家里的水都从一个大管子流走了
so there wasn't any water pressure left for your shower.
打开淋浴头一点水也没有
So in this case if the input is on, output is off.
如果输入是 on,输出是 off
When we turn off the transistor, though, current is prevented from flowing down it to the ground,
当输入是 off,电流没法接地,就流过了输出,所以输出是 on
so instead, current flows through the output wire.
当输入是 off,电流没法接地,就流过了输出,所以输出是 on
So the input will be off and the output will be on.
如果输入是 off,输出是 on
And this matches our logic table for NOT, so congrats, we just built a circuit that computes NOT!
和 NOT 操作表一样!太棒了!我们做了个有点用的电路!
We call them NOT gates - we call them gates because they're controlling the path of our current.
我们叫它 "NOT 门" \N 之所以叫 "门",是因为它能控制电流的路径
The AND Boolean operation takes two inputs, but still has a single output.
"AND"操作有 2 个输入,1 个输出
In this case the output is only true if both inputs are true.
如果 2 个输入都是 true,输出才是 true
Think about it like telling the truth.
你可以想成是 说真话
You're only being completely honest if you don't lie even a little.
如果完全不说谎,才是诚实
For example, let's take the statement,
举例,看如下这个句子
"My name is Carrie Anne AND I'm wearing a blue dress".
我叫 Carrie Anne "而且"我穿着蓝色的衣服
Both of those facts are true, so the whole statement is true.
2 个都是真的,所以整个是真的
But if I said, "My name is Carrie Anne AND I'm wearing pants" that would be false,
但如果说,我叫 Carrie Anne"而且"我穿了裤子, 就是假的
because I'm not wearing pants.
因为我没穿裤子
Or trousers.
或长裤,如果你是英国人你会用这个词……(英/美单词不同梗)
If you're in England.
或长裤,如果你是英国人你会用这个词……(英/美单词不同梗)
The Carrie Anne part is true, but a true AND a false, is still false.
虽然前半句是真的,但是 真 "AND" 假,还是假
If I were to reverse that statement it would still obviously be false,
就算把前后顺序反过来,也依然是 假
and if I were to tell you two complete lies that is also false,
如果我说 2 个假的事情,那么结果是假。
and again we can write all of these combinations out in a table.
和上次一样,可以给"AND"做个表
To build an AND gate, we need two transistors connected together
为了实现 "AND 门",我们需要 2 个晶体管连在一起
so we have our two inputs and one output.
这样有 2 个输入和 1 个输出
If we turn on just transistor A, current won't flow because the current is stopped by transistor B.
如果只打开 A,不打开 B \N 电流无法流到 output,所以输出是 false
Alternatively, if transistor B is on, but the transistor A is off,
如果只打开 B,不打开 A ,也一样,电流无法流到 output
the same thing, the current can't get through.
如果只打开 B,不打开 A ,也一样,电流无法流到 output
Only if transistor A AND transistor B are on does the output wire have current.
只有 A 和 B 都打开了,output 才有电流
The last boolean operation is OR
最后一个是 OR (前面讲了 NOT 和 AND)
-- where only one input has to be true for the output to be true.
只要 2 个输入里,其中 1 个是 true,输出就是 true
For example, my name is Margaret Hamilton OR I'm wearing a blue dress.
比如,我叫 Margaret Hamilton"或"我穿着蓝色衣服
This is a true statement because although I'm not Margaret Hamilton unfortunately,
结果是 true,虽然我不是 Margaret Hamilton
I am wearing a blue dress, so the overall statement is true.
但是我穿着蓝色衣服,所以结果是 true
An OR statement is also true if both facts are true.
对于"OR 操作"来说,\N如果 2 个 输入都是 true,输出也是 true
The only time an OR statement is false is if both inputs are false.
只有 2 个输入都是 false,OR 的结果才是 false
Building an OR gate from transistors needs a few extra wires.
实现 "OR 门" 除了晶体管还要额外的线
Instead of having two transistors in series -- one after the other --
不是串联起来。而是并联
we have them in parallel.
不是串联起来。而是并联
We run wires from the current source to both transistors.
然后左边这条线有电流输入
We use this little arc to note that the wires jump over one another and aren't connected,
我们用"小拱门"代表 2 条线没连在一起,只是跨过而已
even though they look like they cross.
虽然看起来像连在一起
If both transistors are turned off, the current is prevented from flowing to the output,
如果 A 和 B 都是 off,电流无法流过
so the output is also off.
所以输出是 off
Now, if we turn on just Transistor A, current can flow to the output.
如果打开 A,电流可以流过。输出是 on
Same thing if transistor A is off, but Transistor B in on.
如果只打开 B 也一样
Basically if A OR B is on, the output is also on.
只要 A OR B 是 on, 输出就是 on
Also, if both transistors are on, the output is still on.
如果 A 和 B 都 on,结果是 on
Ok, now that we've got NOT, AND, and OR gates,
好,现在 NOT 门, AND 门, OR 门 都搞定了
and we can leave behind the constituent transistors and move up a layer of abstraction.
我们可以进行一次抽象
The standard engineers use for these gates are a triangle with a dot for a NOT,
NOT 门的画法是三角形前面一个圆点
a D for the AND, and a spaceship for the OR.
AND 门用 D 表示 ,OR 门用太空船表示
Those aren't the official names, but that's howI like to think of them.
"D 形状和太空船"不是标准叫法, 只是我喜欢这样叫而已
Representing them and thinking about them this way allows us to build even bigger components
我们可以用这种方法表示它们,构建更大的组件
while keeping the overall complexity relatively the same
就不会变得很复杂
- just remember that that mess of transistors and wires is still there.
- 晶体管和电线依然在那里,我们只是用符号来代表而已
For example, another useful boolean operation in computation is called an Exclusive OR
除了前面说的三个\N 另一个有用的布尔操作叫 "异或"
- or XOR for short.
- 简称 XOR
XOR is like a regular OR, but with one difference:
XOR 就像普通 OR,但有一个区别:
if both inputs are true, the XOR is false.
如果 2 个输入都是 true,XOR 输出 false
The only time an XOR is true is when one input is true and the other input is false.
想要 XOR 输出 true \N 一个输入必须是 true,另一个必须是 false
It's like when you go out to dinner and your meal comes with a side salad OR a soup
就像你出去吃晚饭,你点的饭要么配沙拉,要么配汤
- sadly, you can't have both!
- 你不能两个都要!
And building this from transistors is pretty confusing,
用晶体管实现 XOR 门有点烧脑子
but we can show how an XOR is created from our three basic boolean gates.
但我可以展示一下\N 怎么用前面提到的 3 种门来做 XOR 门
We know we have two inputs again -- A and B -- and one output.
我们有 2 个输入,A 和 B ,还有 1 个输出.
Let's start with an OR gate, since the logic table looks almost identical to an OR.
我们先放一个 OR 门. 因为 OR 和 XOR 的逻辑表很像
There's only one problem - when A and B are true, the logic is different from OR,
只有 1 个问题 - 当 A 和 B 都是 true 时 \N OR 的输出和想要的 XOR 输出不一样
and we need to output "false".
我们想要 false
And XOR turns out to be a very useful component,
XOR 超有用的
and we'll get to it in another episode,
我们下次再说它
so useful in fact engineers gave it its own symbol too -- an OR gate with a smile :)
因为超有用,\N 工程师给了它一个符号,一个 OR 门 + 一个笑脸
But most importantly, we can now put XOR into our metaphorical toolbox
重要的是,现在可以把 XOR 放入"工具箱"了
and not have to worry about the individual logic gates that make it up,
不用担心 XOR 具体用了几个门
or the transistors that make up those gates,
这几个门又是怎么用晶体管拼的
or how electrons are flowing through a semiconductor.
或电子是怎么流过半导体的
Moving up another layer of abstraction.
再次向上抽象
When computer engineers are designing processors, they rarely work at the transistor level,
工程师设计处理器时,很少在晶体管的层面上思考,
and instead work with much larger blocks, like logic gates, and even larger components
而是用更大的组件,比如逻辑门,或者由逻辑门组成的更大组件,
made up of logic gates, which we'll discuss in future episodes.
我们以后会讲
And even if you are a professional computer programmer,
就算是专业程序员
it's not often that you think about
也不用考虑逻辑是怎样在物理层面实现的
how the logic that you are programming is actually implemented
也不用考虑逻辑是怎样在物理层面实现的
in the physical world by these teeny tiny components.
也不用考虑逻辑是怎样在物理层面实现的
We've also moved from thinking about raw electrical signals to our first representation of data
我们从电信号开始,到现在第一次表示数据
- true and false - and we've even gotten a little taste of computation.
- 真和假 - 开始有点"计算"的感觉了
With just the logic gates in this episode,
仅用这集讲的 逻辑门
we could build a machine that evaluates complex logic statements,
我们可以判断复杂的语句 比如:
like if "Name is John Green AND after 5pm OR is Weekend AND near Pizza Hut",
[如果是 John Green] AND [下午 5 点后] \N OR [周末] AND [在比萨店附近]
then "John will want pizza" equals true.
那么 "John 想要比萨" = 真
And with that, I'm starving, I'll see you next week.
我都说饿了,下周见
================================================
FILE: (字幕)全40集中英字幕文本/04. 二进制-Representing Numbers and Letters with Binary.ass.txt
================================================
Hi I'm Carrie Anne, this is Crash Course Computer Science
嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
and today we're going to talk about how computers store and represent numerical data.
今天,我们讲计算机如何存储和表示数字
Which means we've got to talk about Math!
所以会有一些数学
But don't worry.
不过别担心
Every single one of you already knows exactly what you need to know to follow along.
你们的数学水平绝对够用了
So, last episode we talked about how transistors can be used to build logic gates,
上集我们讲了,怎么用晶体管做逻辑门
which can evaluate boolean statements.
逻辑门可以判断布尔语句
And in boolean algebra, there are only two, binary values: true and false.
布尔代数只有两个值:True 和 False
But if we only have two values,
但如果只有两个值,我们怎么表达更多东西?
how in the world do we represent information beyond just these two values?
但如果只有两个值,我们怎么表达更多东西?
That's where the Math comes in.
这就需要数学了
So, as we mentioned last episode, a single binary value can be used to represent a number.
上集提到,1 个二进制值可以代表 1 个数
Instead of true and false, we can call these two states 1 and 0 which is actually incredibly useful.
我们可以把真和假 ,当做 1 和 0
And if we want to represent larger things we just need to add more binary digits.
如果想表示更多东西,加位数就行了
This works exactly the same way as the decimal numbers that we're all familiar with.
和我们熟悉的十进制一样
With decimal numbers there are "only" 10 possible values a single digit can be; 0 through 9,
十进制只有 10 个数(0到9)
and to get numbers larger than 9 we just start adding more digits to the front.
要表示大于 9 的数,加位数就行了
We can do the same with binary.
二进制也可以这样玩
For example, let's take the number two hundred and sixty three.
拿 263 举例
What does this number actually represent?
这个数字 "实际" 代表什么?
Well, it means we've got 2 one-hundreds, 6 tens, and 3 ones.
2 个 100 \N6 个 10 \N 3 个 1
If you add those all together, we've got 263.
加在一起,就是 263
Notice how each column has a different multiplier.
注意每列有不同的乘数
In this case, it's 100, 10, and 1.
100, 10, 1
Each multiplier is ten times larger than the one to the right.
每个乘数都比右边大十倍
That's because each column has ten possible digits to work with, 0 through 9,
因为每列有 10 个可能的数字(0到9)
after which you have to carry one to the next column.
如果超过 9,要在下一列进 1.
For this reason, it's called base-ten notation, also called decimal since deci means ten.
因此叫 "基于十的表示法" 或十进制
AND Binary works exactly the same way, it's just base-two.
二进制也一样,只不过是基于 2 而已
That's because there are only two possible digits in binary - 1 and 0.
因为二进制只有两个可能的数, 1 和 0
This means that each multiplier has to be two times larger than the column to its right.
意味着每个乘数必须是右侧乘数的两倍
Instead of hundreds, tens, and ones, we now have fours, twos and ones.
就不是之前的 100, 10, 1 \N 而是 4, 2, 1
Take for example the binary number: 101.
拿二进制数 101 举例
This means we have 1 four, 0 twos, and 1 one.
意味着有\N 1个 "4" \N 0个 "2" \N 1个 "1"
Add those all together and we've got the number 5 in base ten.
加在一起,得到十进制的 5
But to represent larger numbers, binary needs a lot more digits.
为了表示更大的数字,二进制需要更多位数
Take this number in binary 10110111.
拿二进制数 10110111 举例
We can convert it to decimal in the same way.
我们可以用相同的方法转成十进制
We have 1 x 128, 0 x 64, 1 x 32, 1 x 16, 0 x 8, 1 x 4, 1 x 2, and 1 x 1.
1 x 128 ,0 x 64 ,1 x 32 ,1 x 16 \N 0 x 8 ,1 x 4 ,1 x 2 ,1 x 1
Which all adds up to 183.
加起来等于 183
Math with binary numbers isn't hard either.
二进制数的计算也不难
Take for example decimal addition of 183 plus 19.
以十进制数 183 加 19 举例
First we add 3 + 9, that's 12, so we put 2 as the sum and carry 1 to the ten's column.
首先 3 + 9,得到 12,然后位数记作 2,向前进 1
Now we add 8 plus 1 plus the 1 we carried, thats 10, so the sum is 0 carry 1.
现在算 8+1+1=10,所以位数记作0,再向前进 1
Finally we add 1 plus the 1 we carried, which equals 2.
最后 1+1=2,位数记作2
So the total sum is 202.
所以和是202
Here's the same sum but in binary.
二进制也一样
Just as before, we start with the ones column.
和之前一样,从个位开始
Adding 1+1 results in 2, even in binary.
1+1=2,在二进制中也是如此
But, there is no symbol "2" so we use 10 and put 0 as our sum and carry the 1.
但二进制中没有 2,所以位数记作 0 ,进 1
Just like in our decimal example.
就像十进制的例子一样
1 plus 1, plus the 1 carried,
1+1,再加上进位的1
equals 3 or 11 in binary,
等于 3,用二进制表示是 11
so we put the sum as 1 and we carry 1 again, and so on.
所以位数记作 1,再进 1,以此类推
We end up with this number, which is the same as the number 202 in base ten.
最后得到这个数字,跟十进制 202 是一样的
Each of these binary digits, 1 or 0, is called a "bit".
二进制中,一个 1 或 0 叫一"位"
So in these last few examples, we were using 8-bit numbers with their lowest value of zero
上个例子我们用了 8 位 , 8 位能表示的最小数是 0, 8位都是0
and highest value is 255, which requires all 8 bits to be set to 1.
最大数是 255,8 位都是 1
Thats 256 different values, or 2 to the 8th power.
能表示 256 个不同的值,2 的 8 次方
You might have heard of 8-bit computers, or 8-bit graphics or audio.
你可能听过 8 位机,8 位图像,8 位音乐
These were computers that did most of their operations in chunks of 8 bits.
意思是计算机里\N 大部分操作都是 8 位 8 位这样处理的
But 256 different values isn't a lot to work with, so it meant things like 8-bit games
但 256 个值不算多,意味着 8位游戏只能用 256 种颜色
were limited to 256 different colors for their graphics.
但 256 个值不算多,意味着 8位游戏只能用 256 种颜色
And 8-bits is such a common size in computing, it has a special word: a byte.
8 位是如此常见,以至于有专门的名字:字节
A byte is 8 bits.
1 字节 = 8 位 \N 1 bytes = 8 bits
If you've got 10 bytes, it means you've really got 80 bits.
如果有 10 个字节,意味着有 80 位
You've heard of kilobytes, megabytes, gigabytes and so on.
你听过 千字节(KB)兆字节(MB)千兆字节(GB)等等
These prefixes denote different scales of data.
不同前缀代表不同数量级
Just like one kilogram is a thousand grams,
就像 1 千克 = 1000 克,1 千字节 = 1000 字节
1 kilobyte is a thousand bytes.
就像 1 千克 = 1000 克,1 千字节 = 1000 字节
or really 8000 bits.
或 8000 位
Mega is a million bytes (MB), and giga is a billion bytes (GB).
Mega 是百万字节(MB), Giga 是十亿字节(GB)
Today you might even have a hard drive that has 1 terabyte (TB) of storage.
如今你可能有 1 TB 的硬盘
That's 8 trillion ones and zeros.
8 万亿个1和0
But hold on!
等等,我们有另一种计算方法
That's not always true.
等等,我们有另一种计算方法
In binary, a kilobyte has two to the power of 10 bytes, or 1024.
二进制里,1 千字节 = 2的10次方 = 1024 字节
1000 is also right when talking about kilobytes,
1000 也是千字节(KB)的正确单位
but we should acknowledge it isn't the only correct definition.
1000 和 1024 都对
You've probably also heard the term 32-bit or 64-bit computers
你可能听过 32 位 或 64 位计算机
you're almost certainly using one right now.
你现在用的电脑几乎肯定是其中一种
What this means is that they operate in chunks of 32 or 64 bits.
意思是一块块处理数据,每块是 32 位或 64 位
That's a lot of bits!
这可是很多位
The largest number you can represent with 32 bits is just under 4.3 billion.
32 位能表示的最大数,是 43 亿左右
Which is thirty-two 1's in binary.
也就是 32 个 1
This is why our Instagram photos are so smooth and pretty
所以 Instagram 照片很清晰
- they are composed of millions of colors,
- 它们有上百万种颜色
because computers today use 32-bit color graphics
因为如今都用 32 位颜色
Of course, not everything is a positive number
当然,不是所有数都是正数
- like my bank account in college.
比如我上大学时的银行账户 T_T
So we need a way to represent positive and negative numbers.
我们需要有方法表示正数和负数
Most computers use the first bit for the sign:
大部分计算机用第一位表示正负:
1 for negative, 0 for positive numbers,
1 是负,0 是正
and then use the remaining 31 bits for the number itself.
用剩下 31 位来表示符号外的数值
That gives us a range of roughly plus or minus two billion.
能表示的数的范围大约是正 20 亿到负 20 亿
While this is a pretty big range of numbers, it's not enough for many tasks.
虽然是很大的数,但许多情况下还不够用
There are 7 billion people on the earth, and the US national debt is almost 20 trillion dollars after all.
全球有 70 亿人口,美国国债近 20 万亿美元
This is why 64-bit numbers are useful.
所以 64 位数很有用
The largest value a 64-bit number can represent is around 9.2 quintillion!
64 位能表达最大数大约是 9.2×10 ^ 18
That's a lot of possible numbers and will hopefully stay above the US national debt for a while!
希望美国国债在一段时间内不会超过这个数!
Most importantly, as we'll discuss in a later episode,
重要的是(我们之后的视频会深入讲)
computers must label locations in their memory,
计算机必须给内存中每一个位置,做一个 "标记"
known as addresses, in order to store and retrieve values.
这个标记叫 "地址", 目的是为了方便存取数据
As computer memory has grown to gigabytes and terabytes - that's trillions of bytes
如今硬盘已经增长到 GB 和 TB,上万亿个字节!
it was necessary to have 64-bit memory addresses as well.
内存地址也应该有 64 位
In addition to negative and positive numbers,
除了负数和正数,计算机也要处理非整数
computers must deal with numbers that are not whole numbers,
除了负数和正数,计算机也要处理非整数
like 12.7 and 3.14, or maybe even stardate: 43989.1.
比如 12.7 和 3.14,或"星历 43989.1"
These are called "floating point" numbers,
这叫 浮点数
because the decimal point can float around in the middle of number.
因为小数点可以在数字间浮动
Several methods have been developed to represent floating point numbers.
有好几种方法 表示浮点数
The most common of which is the IEEE 754 standard.
最常见的是 IEEE 754 标准
And you thought historians were the only people bad at naming things!
你以为只有历史学家取名很烂吗?
In essence, this standard stores decimal values sort of like scientific notation.
它用类似科学计数法的方法,来存十进制值
For example, 625.9 can be written as 0.6259 x 10^3.
例如,625.9 可以写成 0.6259×10 ^ 3
There are two important numbers here: the .6259 is called the significand.
这里有两个重要的数:.6259 叫 "有效位数" , 3 是指数
And 3 is the exponent.
这里有两个重要的数:.6259 叫 "有效位数" , 3 是指数
In a 32-bit floating point number,
在 32 位浮点数中
the first bit is used for the sign of the number -- positive or negative.
第 1 位表示数的符号——正或负
The next 8 bits are used to store the exponent
接下来 8 位存指数
and the remaining 23 bits are used to store the significand.
剩下 23 位存有效位数
Ok, we've talked a lot about numbers, but your name is probably composed of letters,
好了,聊够数了,但你的名字是字母组成的
so it's really useful for computers to also have a way to represent text.
所以我们也要表示文字
However, rather than have a special form of storage for letters,
与其用特殊方式来表示字母 \N 计算机可以用数表示字母
computers simply use numbers to represent letters.
与其用特殊方式来表示字母 \N 计算机可以用数表示字母
The most straightforward approach might be to simply number the letters of the alphabet:
最直接的方法是给字母编号:
A being 1, B being 2, C 3, and so on.
A是1,B是2,C是3,以此类推
In fact, Francis Bacon, the famous English writer,
著名英国作家 弗朗西斯·培根(Francis Bacon)
used five-bit sequences to encode all 26 letters of the English alphabet
曾用 5位序列 来编码英文的 26 个字母
to send secret messages back in the 1600s.
在十六世纪传递机密信件
And five bits can store 32 possible values - so that's enough for the 26 letters,
五位(bit)可以存 32 个可能值(2^5) - 这对26个字母够了
but not enough for punctuation, digits, and upper and lower case letters.
但不能表示 标点符号,数字和大小写字母
Enter ASCII, the American Standard Code for Information Interchange.
ASCII,美国信息交换标准代码
Invented in 1963, ASCII was a 7-bit code, enough to store 128 different values.
发明于 1963 年,ASCII 是 7 位代码,足够存 128 个不同值
With this expanded range, it could encode capital letters, lowercase letters,
范围扩大之后,可以表示大写字母,小写字母,
digits 0 through 9, and symbols like the @ sign and punctuation marks.
数字 0 到 9, @ 这样的符号, 以及标点符号
For example, a lowercase 'a' is represented by the number 97, while a capital 'A' is 65.
举例,小写字母 a 用数字 97 表示,大写字母 A 是 65
A colon is 58 and a closed parenthesis is 41.
: 是58 \n ) 是41
ASCII even had a selection of special command codes,
ASCII 甚至有特殊命令符号
such as a newline character to tell the computer where to wrap a line to the next row.
比如换行符,用来告诉计算机换行
In older computer systems,
在老计算机系统中
the line of text would literally continue off the edge of the screen if you didn't include a new line character!
如果没换行符,文字会超出屏幕
Because ASCII was such an early standard,
因为 ASCII 是个很早的标准
it became widely used,
所以它被广泛使用
and critically, allowed different computers built by different companies to exchange data.
让不同公司制作的计算机,能互相交换数据
This ability to universally exchange information is called "interoperability".
这种通用交换信息的能力叫 "互操作性"
However, it did have a major limitation: it was really only designed for English.
但有个限制:它是为英语设计的
Fortunately, there are 8 bits in a byte, not 7,
幸运的是,一个字节有8位,而不是7位
and it soon became popular to use codes 128 through 255,
128 到 255 的字符渐渐变得常用
previously unused, for "national" characters.
这些字符以前是空的,是给各个国家自己 "保留使用的"
In the US, those extra numbers were largely used to encode additional symbols,
在美国,这些额外的数字主要用于编码附加符号
like mathematical notation, graphical elements, and common accented characters.
比如数学符号,图形元素和常用的重音字符
On the other hand, while the Latin characters were used universally,
另一方面,虽然拉丁字符被普遍使用
Russian computers used the extra codes to encode Cyrillic characters,
在俄罗斯,他们用这些额外的字符表示西里尔字符
and Greek computers, Greek letters, and so on.
而希腊电脑用希腊字母,等等
And national character codes worked pretty well for most countries.
这些保留下来给每个国家自己安排的空位,\N 对大部分国家都够用
The problem was,
问题是
if you opened an email written in Latvian on a Turkish computer,
如果在 土耳其 电脑上打开 拉脱维亚语 写的电子邮件
the result was completely incomprehensible.
会显示乱码
And things totally broke with the rise of computing in Asia,
随着计算机在亚洲兴起,这种做法彻底失效了
as languages like Chinese and Japanese have thousands of characters.
中文和日文这样的语言有数千个字符
There was no way to encode all those characters in 8-bits!
根本没办法用 8 位来表示所有字符!
In response, each country invented multi-byte encoding schemes,
为了解决这个问题,每个国家都发明了多字节编码方案
all of which were mutually incompatible.
但相互不兼容
The Japanese were so familiar with this encoding problem that they had a special name for it:
日本人总是碰到编码问题,以至于专门有词来称呼:
"mojibake", which means "scrambled text".
"mojibake" 意思是 乱码
And so it was born - Unicode - one format to rule them all.
所以 Unicode 诞生了 - 统一所有编码的标准
Devised in 1992 to finally do away with all of the different international schemes
设计于 1992 年,解决了不同国家不同标准的问题
it replaced them with one universal encoding scheme.
Unicode 用一个统一编码方案
The most common version of Unicode uses 16 bits with space for over a million codes -
最常见的 Unicode 是 16 位的,有超过一百万个位置 -
enough for every single character from every language ever used
对所有语言的每个字符都够了
more than 120,000 of them in over 100 types of script
100 多种字母表加起来占了 12 万个位置。
plus space for mathematical symbols and even graphical characters like Emoji.
还有位置放数学符号,甚至 Emoji
And in the same way that ASCII defines a scheme for encoding letters as binary numbers,
就像 ASCII 用二进制来表示字母一样
other file formats - like MP3s or GIFs -
其他格式 - 比如 MP3 或 GIF -
use binary numbers to encode sounds or colors of a pixel in our photos, movies, and music.
用二进制编码声音/颜色,表示照片,电影,音乐
Most importantly, under the hood it all comes down to long sequences of bits.
重要的是,这些标准归根到底是一长串位
Text messages, this YouTube video, every webpage on the internet,
短信,这个 YouTube 视频,互联网上的每个网页
and even your computer's operating system, are nothing but long sequences of 1s and 0s.
甚至操作系统,只不过是一长串 1 和 0
So next week,
下周
we'll start talking about how your computer starts manipulating those binary sequences,
我们会聊计算机怎么操作二进制
for our first true taste of computation.
初尝"计算"的滋味
Thanks for watching. See you next week.
感谢观看,下周见
================================================
FILE: (字幕)全40集中英字幕文本/05. 算术逻辑单元-How Computers Calculate-the ALU.ass.txt
================================================
Hi, I'm Carrie Ann and this is Crash Course Computer Science.
嗨,我是 Carrie Anne,欢迎收看计算机科学速成课
So last episode, we talked about how numbers can be represented in binary.
上集,我们谈了如何用二进制表示数字
Representing Like, 00101010 is 42 in decimal.
比如二进制 00101010 是十进制的 42
Representing and storing numbers is an important function of a computer,
表示和存储数字是计算机的重要功能
but the real goal is computation, or manipulating numbers in a structured and purposeful way,
但真正的目标是计算,有意义的处理数字
like adding two numbers together.
比如把两个数字相加
These operations are handled by a computer's Arithmetic and Logic Unit,
这些操作由计算机的 "算术逻辑单元 "处理
but most people call it by its street name:
但大家会简称:ALU
the ALU.
但大家会简称:ALU
The ALU is the mathematical brain of a computer.
ALU 是计算机的数学大脑
When you understand an ALU's design and function,
等你理解了 ALU 的设计和功能之后
you'll understand a fundamental part of modern computers.
你就理解了现代计算机的基石
It is THE thing that does all of the computation in a computer,
ALU *就是* 计算机里负责运算的组件\N 基本其他所有部件都用到了它
so basically everything uses it.
ALU *就是* 计算机里负责运算的组件\N 基本其他所有部件都用到了它
First though, look at this beauty.
先来看看这个美人
This is perhaps the most famous ALU ever, the Intel 74181.
这可能是最著名的 ALU,英特尔 74181
When it was released in 1970,
1970 年发布时,它是第一个封装在单个芯片内的完整 ALU
it was It was the first complete ALU that fit entirely inside of a single chip -
1970 年发布时,它是第一个封装在单个芯片内的完整 ALU
Which was a huge engineering feat at the time.
这在当时是惊人的工程壮举
So today we're going to take those Boolean logic gates we learned about last week
今天我们用上周学的布尔逻辑门
to build a simple ALU circuit with much of the same functionality as the 74181.
做一个简单的 ALU 电路,功能和 74181 一样
And over the next few episodes we'll use this to construct a computer from scratch.
然后接下来几集,用它从头做出一台电脑
So it's going to get a little bit complicated,
所以会有点复杂
but I think you guys can handle it.
但我觉得你们搞的定
An ALU is really two units in one
ALU 有 2 个单元,1 个算术单元和 1 个逻辑单元
-- there's an arithmetic unit and a logic unit.
ALU 有 2 个单元,1 个算术单元和 1 个逻辑单元
Let's start with the arithmetic unit,
我们先讲"算术单元",它负责计算机里的所有数字操作
which is responsible for handling all numerical operations in a computer,
我们先讲"算术单元",它负责计算机里的所有数字操作
like addition and subtraction.
比如加减法
It also does a bunch of other simple things like add one to a number,
它还做很多其他事情,比如给某个数字+1
which is called an increment operation, but we'll talk about those later.
这叫增量运算,我们之后会说
Today, we're going to focus on the piece of rsistance, the crme de la crme of operations
今天的重点是一切的根本 - "把两个数字相加"
that underlies almost everything else a computer does - adding two numbers together.
今天的重点是一切的根本 - "把两个数字相加"
We could build this circuit entirely out of individual transistors,
我们可以用单个晶体管一个个拼,把这个电路做出来,\N 但很快就会复杂的难以理解
but that would get confusing really fast.
我们可以用单个晶体管一个个拼,把这个电路做出来,\N 但很快就会复杂的难以理解
So instead as we talked about in Episode 3
所以与其用晶体管,我们会像第 3 集
- we can use a high-level of abstraction and build our components out of logic gates,
- 用更高层的抽象,用逻辑门来做
in this case: AND, OR, NOT and XOR gates.
我们会用到 AND,OR,NOT 和 XOR 逻辑门
The simplest adding circuit that we can build takes two binary digits, and adds them together.
最简单的加法电路, \N 是拿 2 个 bit 加在一起(bit 是 0 或 1)
So we have two inputs, A and B, and one output, which is the sum of those two digits.
有 2 个输入:A 和 B, 1 个输出:就是两个数字的和
Just to clarify: A, B and the output are all single bits.
需要注意的是:A, B, 输出,这3个都是单个 Bit ( 0 或 1 )
There are only four possible input combinations.
输入只有四种可能
The first three are: 0+0 = 0
前三个是\N 0 + 0 = 0 \N 1 + 0 = 1 \N 0 + 1 = 1
1+0 = 1 0+1 = 1
前三个是\N 0 + 0 = 0 \N 1 + 0 = 1 \N 0 + 1 = 1
Remember that in binary, 1 is the same as true, and 0 is the same as false.
记住二进制里,1 与 true 相同,0 与 false 相同
So this set of inputs exactly matches the boolean logic of an XOR gate,
这组输入和输出,和 XOR 门的逻辑完全一样
and we can use it as our 1-bit adder.
所以我们可以把 XOR 用作 1 位加法器(adder)
But the fourth input combination, 1 + 1, is a special case. 1 + 1 is 2 (obviously)
但第四个输入组合,1+1,是个特例 \N 1+1=2(显然)
but there's no 2 digit in binary,
但二进制里没有 2
so as we talked about last episode, the result is 0 and the 1 is carried to the next column.
上集说过,二进制 1+1 的结果是0,1进到下一位
So the sum is really 10 in binary.
和是 10 (二进制)
Now, the output of our XOR gate is partially correct - 1 plus 1, outputs 0.
XOR 门的输出,只对了一部分, 1+1 输出 0
But, we need an extra output wire for that carry bit.
但我们需要一根额外的线代表 "进位"
The carry bit is only "true" when the inputs are 1 AND 1,
只有输入是 1 和 1 时,进位才是 "true"
because that's the only time when the result (two) is bigger than 1 bit can store
因为算出来的结果用 1 个 bit 存不下
and conveniently we have a gate for that!
方便的是,我们刚好有个逻辑门能做这个事!
It's not that complicated - just two logic gates -
没那么复杂 - 就两个逻辑门而已
but let's abstract away even this level of detail
让我们抽象化
and encapsulate our newly minted half adder as its own component,
把 "半加器" 封装成一个单独组件
with two inputs - bits A and B - and two outputs, the sum and the carry bits.
两个输入 A 和 B 都是 1 位 \N 两个输出 "总和" 与 "进位"
This takes us to another level of abstraction
这进入了另一层抽象
heh I feel like I say that a lot.
我好像说了很多次,说不定会变成一个梗
I wonder if this is going to become a thing.
我好像说了很多次,说不定会变成一个梗
Anyway, If you want to add more than 1 + 1
如果想处理超过 1+1 的运算,我们需要"全加器"
we're going to need a "Full Adder."
如果想处理超过 1+1 的运算,我们需要"全加器"
That half-adder left us with a carry bit as output.
半加器 输出了进位
That means that when we move on to the next column in a multi-column addition,
意味着,我们算下一列的时候
and every column after that, we are going to have to add three bits together, no two.
还有之后的每一列,我们得加 3 个位在一起,并不是 2 个
A full adder is a bit more complicated
全加器复杂了一点点
全加器表格
- it takes three bits as inputs: A, B and C.
有 3 个输入:A, B, C (都是 1 个 bit)
So the maximum possible input is 1 + 1 + 1,
所以最大的可能是 1 + 1 + 1
which equals 1 carry out 1, so we still only need two output wires: sum and carry.
"总和"1 "进位"1 \N 所以要两条输出线: "总和"和"进位"
We can build a full adder using half adders.
我们可以用 半加器 做 全加器
To do this, we use a half adder to add A plus B
我们先用半加器将 A 和 B 相加
just like before - but then feed that result and input C into a second half adder.
然后把 C 输入到第二个半加器
Lastly, we need a OR gate to check if either one of the carry bits was true.
最后用一个 OR 门检查进位是不是 true
That's it, we just made a full adder!
这样就做出了一个全加器!
Again,we can go up a level of abstraction and wrap up this full adder as its own component.
我们可以再提升一层抽象,把全加器作为独立组件
It takes three inputs, adds them, and outputs the sum and the carry, if there is one.
全加器会把 A,B,C 三个输入加起来 \N 输出 "总和" 和 "进位"
Armed with our new components, we can now build a circuit that takes two, 8-bit numbers
现在有了新组件,我们可以相加两个 8 位数字
Let's call them A and B and adds them together.
叫两个数字叫 A 和 B 好了
Let's start with the very first bit of A and B,
我们从 A 和 B 的第一位开始
which we'll call A0 and B0.
叫 A0 和 B0 好了
At this point, there is no carry bit to deal with,
现在不用处理任何进位,因为是第一次加法
because this is our first addition.
现在不用处理任何进位,因为是第一次加法
So we can use our half adder to add these two bits together.
所以我们可以用半加器,来加这2个数字
The output is sum0.
输出叫 sum0
Now we want to add A1 and B1 together.
现在加 A1 和 B1
It's possible there was a carry from the previous addition of A0 and B0,
因为 A0 和 B0 的结果有可能进位
so this time we need to use a full adder that also inputs the carry bit.
所以这次要用全加器,除了 A1 和 B1,还要连上进位
We output this result as sum1.
输出叫 sum1
Then, we take any carry from this full adder,
然后,把这个全加器的进位 \N 连到下个全加器的输入,处理 A2 和 B2
and run it into the next full adder that handles A2 and B2.
然后,把这个全加器的进位 \N 连到下个全加器的输入,处理 A2 和 B2
And we just keep doing this in a big chain until all 8 bits have been added.
以此类推,把 8 个 bit 都搞定
Notice how the carry bits ripple forward to each subsequent adder.
注意每个进位是怎么连到下一个全加器的
For this reason, this is called an 8-bit ripple carry adder.
所以叫 "8位行波进位加法器"
Notice how our last full adder has a carry out.
注意最后一个全加器有 "进位" 的输出
If there is a carry into the 9th bit, it means the sum of the two numbers is too large to fit into 8-bits.
如果第 9 位有进位,代表着 2 个数字的和太大了,超过了 8 位
This is called an overflow.
这叫 "溢出" (overflow)
In general, an overflow occurs when the result of an addition is too large
一般来说 "溢出" 的意思是, 两个数字的和太大了
to be represented by the number of bits you are using.
超过了用来表示的位数
This can usually cause errors and unexpected behavior.
这会导致错误和不可预期的结果
Famously, the original PacMan arcade game used 8 bits to keep track of what level you were on.
著名的例子是,吃豆人用 8 位存当前关卡数
This meant that if you made it past level 255 - the largest number storablein 8 bits - to level 256,
如果你玩到了第 256 关( 8 位 bit 最大表示 255)
the ALU overflowed.
ALU 会溢出
This caused a bunch of errors and glitches making the level unbeatable.
造成一连串错误和乱码,使得该关卡无法进行
The bug became a rite of passage for the greatest PacMan players.
这个 bug 成了厉害吃豆人玩家的代表
So if we want to avoid overflows,
如果想避免溢出
we can extend our circuit with more full adders, allowing us to add 16 or 32 bit numbers.
我们可以加更多全加器,可以操作 16 或 32 位数字
This makes overflows less likely to happen, but at the expense of more gates.
让溢出更难发生,但代价是更多逻辑门
An additional downside is that it takes a little bit of time for each of the carries to ripple forward.
另外一个缺点是,每次进位都要一点时间
Admittedly, not very much time, electrons move pretty fast,
当然时间不久,因为电子移动的很快
so we're talking about billionths of a second,
但如今的量级是每秒几十亿次运算,所以会造成影响
but that's enough to make a difference in today's fast computers.
但如今的量级是每秒几十亿次运算,所以会造成影响
For this reason, modern computers use a slightly different adding circuit
所以,现代计算机用的加法电路有点不同
called a 'carry-look-ahead' adder
叫 "超前进位加法器"
which is faster, but ultimately does exactly the same thing
它更快,做的事情是一样的 - 把二进制数相加
-- adds binary numbers.
它更快,做的事情是一样的 - 把二进制数相加
The ALU's arithmetic unit also has circuits for other math operations
ALU 的算术单元,也能做一些其他数学运算
and in general these 8 operations are always supported.
一般支持这 8 个操作
And like our adder, these other operations are built from individual logic gates.
就像加法器一样,这些操作也是由逻辑门构成的
Interestingly, you may have noticed that there are no multiply and divide operations.
有趣的是,你可能注意到没有乘法和除法
That's because simple ALUs don't have a circuit for this,
因为简单的 ALU 没有专门的电路来处理
and instead just perform a series of additions.
而是把乘法用多次加法来实现
Let's say you want to multiply 12 by 5.
假设想算 12x5
That's the same thing as adding 12 to itself 5 times.
这和把 "12" 加 5 次是一样的
So it would take 5 passes through the ALU to do this one multiplication.
所以要 5 次 ALU 操作来实现这个乘法
And this is how many simple processors,
很多简单处理器都是这样做的
like those in your thermostat, TV remote, and microwave, do multiplication.
比如恒温器,电视遥控器和微波炉
It's slow, but it gets the job done.
慢是慢,但是搞的定
However, fancier processors, like those in your laptop or smartphone,
然而笔记本和手机有更好的处理器
have arithmetic units with dedicated circuits for multiplication.
有专门做乘法的算术单元
And as you might expect, the circuit is more complicated than addition
你可能猜到了,乘法电路比加法复杂
-- there's no magic, it just takes a lot more logic gates
- 没什么魔法,只是更多逻辑门
which is why less expensive processors don't have this feature.
所以便宜的处理器没有.
Ok, let's move on to the other half of the ALU:
好了,我们现在讲 ALU 的另一半:逻辑单元
the Logic Unit.
好了,我们现在讲 ALU 的另一半:逻辑单元
Instead of arithmetic operations, the Logic Unit performs well...
逻辑单元执行逻辑操作
logical operations, like AND, OR and NOT, which we've talked about previously.
比如之前讨论过的 AND,OR 和 NOT 操作
It also performs simple numerical tests,
它也能做简单的数值测试
like checking if a number is negative.
比如一个数字是不是负数
For example, here's a circuit that tests if the output of the ALU is zero.
例如,这是检查 ALU 输出是否为 0 的电路
It does this using a bunch of OR gates to see if any of the bits are 1.
它用一堆 OR 门检查其中一位是否为 1
Even if one single bit is 1,
哪怕只有一个 Bit (位) 是1,
we know the number can't be zero and then we use a final NOT gate to flip this input
我们就知道那个数字肯定不是 0,然后用一个 NOT 门取反
so the output is 1 only if the input number is 0.
所以只有输入的数字是 0,输出才为 1
So that's a high level overview of what makes up an ALU.
以上就是 ALU 的一个高层次概括
We even built several of the main components from scratch, like our ripple adder.
我们甚至从零做了几个主要组件,比如行波进位加法器
As you saw, it's just a big bunch of logic gates connected in clever ways.
它们只是一大堆逻辑门巧妙的连在一起而已.
Which brings us back to that ALU you admired so much at the beginning of the episode.
让我们回到视频开始时的 ALU,英特尔 74181
The Intel 74181.
让我们回到视频开始时的 ALU,英特尔 74181
Unlike the 8-bit ALU we made today, the 74181 could only handle 4-bit inputs,
和我们刚刚做的 8 位 ALU 不同,74181 只能处理 4 位输入
which means
也就是说
YOU BUILT AN ALU THAT'S LIKE TWICE AS GOOD AS THAT SUPER FAMOUS ONE. WITH YOUR MIND!
你刚做了一个比英特尔 74181 还好的 ALU !
Well.. sort of.
其实 差不多啦..
We didn't build the whole thing
我们虽然没有全部造出来
but you get the idea.
但你理解了整体概念
The 74181 used about 70 logic gates, and it couldn't multiply or divide.
74181 用了大概 70 个逻辑门,但不能执行乘除.
But it was a huge step forward in miniaturization,
但它向小型化迈出了一大步
opening the doors to more capable and less expensive computers.
让计算机可以更强大更便宜
This 4-bit ALU circuit is already a lot to take in,
4 位 ALU 已经要很多逻辑门了
but our 8-bit ALU would require hundreds of logic gates to fully build
但我们的 8 位 ALU 会需要数百个逻辑门
and engineers don't want to see all that complexity when using an ALU,
工程师不想在用 ALU 时去想那些事情,
so they came up with a special symbol to wrap it all up, which looks like a big V'.
所以想了一个特殊符号来代表它,看起来像一个大 "V"
Just another level of abstraction!
又一层抽象!
Our 8-bit ALU has two inputs, A and B, each with 8 bits.
我们的 8 位 ALU 有两个输入,A和B,都是 8 位 (bits)
We also need a way to specify what operation the ALU should perform,
我们还需要告诉 ALU 执行什么操作
for example, addition or subtraction.
例如加法或减法
For that, we use a 4-bit operation code.
所以我们用 4 位的操作代码
We'll talk about this more in a later episode,
我们之后的视频会再细说
but in brief, 1000 might be the command to add, while 1100 is the command for subtract.
简言之,"1000"可能代表加法命令 \N "1100"代表减法命令
Basically, the operation code tells the ALU what operation to perform.
操作代码告诉 ALU 执行什么操作
And the result of that operation on inputs A and B is an 8-bit output.
输出结果是 8 位的
ALUs also output a series of Flags,
ALU 还会输出一堆标志(Flag)
which are 1-bit outputs for particular states and statuses.
"标志"是1位的,代表特定状态.
For example, if we subtract two numbers, and the result is 0,
比如相减两个数字,结果为 0
our zero-testing circuit, the one we made earlier, sets the Zero Flag to True (1).
我们的零测试电路(前面做的)\N 会将零标志设为 True(1)
This is useful if we are trying to determine if two numbers are are equal.
如果想知道两个数字是否相等,这个非常有用
If we wanted to test if A was less than B,
如果想知道: A 是否小于 B
we can use the ALU to calculate A subtract B and look to see if the Negative Flag was set to true.
可以用 ALU 来算 A 减 B,看负标志是否为 true
If it was, we know that A was smaller than B.
如果是 true,我们就知道 A 小于 B
And finally, there's also a wire attached to the carry out on the adder we built,
最后,还有一条线连到加法器的进位
so if there is an overflow, we'll know about it.
如果有溢出,我们就知道
This is called the Overflow Flag.
这叫溢出标志
Fancier ALUs will have more flags,
高级 ALU 有更多标志
but these three flags are universal and frequently used.
但这 3 个标志是 ALU 普遍用的
In fact, we'll be using them soon in a future episode.
其实,我们之后的视频会用到它们
So now you know how your computer does all its basic mathematical operations digitally
现在你知道了\N 计算机是怎样在没有齿轮或杠杆的情况下 进行运算
with no gears or levers required.
现在你知道了\N 计算机是怎样在没有齿轮或杠杆的情况下 进行运算
We're going to use this ALU when we construct our CPU two episodes from now.
接下来两集 我们会用 ALU 做 CPU
But before that, our computer is going to need some memory!
但在此之前,计算机需要一些 "记忆" !
We'll talk about that next week.
我们下周会讲
================================================
FILE: (字幕)全40集中英字幕文本/06. 寄存器 & 内存-Registers and RAM.ass.txt
================================================
Hi, I'm Carrie Anne and welcome to Crash Course Computer Science.
嗨,我是 Carrie Anne,欢迎收看计算机科学速成课
So last episode, using just logic gates, we built a simple ALU,
上集,我们用逻辑门做了个简单 ALU
which performs arithmetic and logic operations, hence the 'A' and the 'L'.
它能执行算术(Arithmetic)和逻辑(Logic)运算 \N ALU 里的 A 和 L 因此得名
But of course, there's not much point in calculating a result only to throw it away
当然,算出来之后如果扔掉就没什么意义了
- it would be useful to store that value somehow,
得找个方法存起来
and maybe even run several operations in a row.
可能还要进行多个连续操作
That's where computer memory comes in!
这就用到计算机内存了
If you've ever been in the middle of a long RPG campaign on your console,
如果你在主机上打过一场长时间的对局
or slogging through a difficult level on Minesweeper on your desktop,
或玩困难模式的 "扫雷"
and your dog came by, tripped and pulled the power cord out of the wall,
然后狗跑过来,被电源线绊倒,把插头拔了出来
you know the agony of losing all your progress.
你知道失去进度的痛苦
Condolences.
真同情你 :(
But the reason for your loss is that your console, your laptop and your computers
你损失数据的原因是 \N 电脑用的是"随机存取存储器",简称"RAM"
make use of Random Access Memory, or RAM,
你损失数据的原因是 \N 电脑用的是"随机存取存储器",简称"RAM"
which stores things like game state - as long as the power stays on.
它只能在有电的情况下存储东西,比如游戏状态
Another type of memory, called persistent memory, can survive without power,
另一种存储 (memory) 叫持久存储,电源关闭时数据也不会丢失
and it's used for different things;
它用来存其他东西.
We'll talk about the persistence of memory in a later episode.
我们之后会讨论存储 (memory) 的持久性问题
Today, we're going to start small
今天我们从简单开始
- literally by building a circuit that can store one.. single.. bit of information.
- 做只能存储 1 位的电路
After that, we'll scale up, and build our very own memory module,
之后再扩大,做出我们的内存模块
and we'll combine it with our ALU next time, when we finally build our very own CPU!
下次和 ALU 结合起来,做出 CPU!
All of the logic circuits we've discussed so far go in one direction
我们至今说过的电路都是单向的
- always flowing forward.
- 总是向前流动
like our 8-bit ripple adder from last episode.
比如上集的 8 位 "脉动进位加法器"
But we can also create circuits that loop back on themselves.
但也可以做回向电路,把输出连回输入
Let's try taking an ordinary OR gate, and feed the output back into one of its inputs
我们拿一个 OR 门试试,把输出连回输入
and see what happens.
看看会发生什么
First, let's set both inputs to 0.
首先,两个输入都设为 0
So 0 OR 0 is 0, and so this circuit always outputs 0.
"0 OR 0" 是 0,所以电路输出0
If we were to flip input A to 1.
如果将 A 变成1
1 OR 0 is 1, so now the output of the OR gate is 1.
"1 OR 0" 为 1,所以输出 1
A fraction of a second later, that loops back around into input B,
一转眼的功夫,输出回到 B
so the OR gate sees that both of its inputs are now 1.
OR 门看到两个输入都是 1
1 OR 1 is still 1, so there is no change in output.
"1 OR 1" 仍然为1,所以输出不变
If we flip input A back to 0, the OR gate still outputs 1.
如果将 A 变成 0,OR 门依然输出 1
So now we've got a circuit that records a "1" for us.
现在我们有个电路能记录 "1"
Except, we've got a teensy tiny problem - this change is permanent!
然而有个小问题:这是永久的!
No matter how hard we try, there's no way to get this circuit to flip back from a 1 to a 0.
无论怎么试,都没法从 1 变回 0
Now let's look at this same circuit, but with an AND gate instead.
我们换成 AND 门看看会怎样
We'll start inputs A and B both at 1.
开始时,A 和 B 都设 1
1 AND 1 outputs 1 forever.
"1 AND 1" 永远输出 1
But, if we then flip input A to 0, because it's an AND gate, the output will go to 0.
如果之后 A 设为 0,由于是 AND 门,输出会变成 0
So this circuit records a 0, the opposite of our other circuit.
这个电路能记录 0,和之前那个相反
Like before, no matter what input we apply to input A afterwards, the circuit will always output 0.
就像之前,无论 A 设什么值,电路始终输出 0
Now we've got circuits that can record both 0s and 1s.
现在有了能存 0 和 1 的电路
The key to making this a useful piece of memory is to combine our two circuits into what is
为了做出有用的存储 (memory) \N 我们把两个电路结合起来
called the AND-OR Latch.
这叫 "AND-OR 锁存器"
It has two inputs, a "set" input, which sets the output to a 1,\Ncalled the AND-OR Latch.
It has two inputs, a "set" input, which sets the output to a 1,
它有两个输入\N "设置"输入, 把输出变成 1\N "复位"输入, 把输出变成 0
and a "reset" input, which resets the output to a 0.
它有两个输入\N "设置"输入, 把输出变成 1\N "复位"输入, 把输出变成 0
If set and reset are both 0, the circuit just outputs whatever was last put in it.
如果"设置"和"复位"都是 0,电路会输出最后放入的内容
In other words, it remembers a single bit of information!
也就是说,它存住了 1 位的信息!
Memory!
存储!
This is called a "latch" because it "latches onto" a particular value and stays that way.
这叫"锁存", 因为它"锁定"了一个值
The action of putting data into memory is called writing, whereas getting the data out is called reading.
放入数据的动作叫 "写入" ,拿出数据的动作叫 "读取"
Ok, so we've got a way to store a single bit of information!
现在我们终于有办法存一个位了!
Great!
超棒!
Unfortunately, having two different wires for input - set and reset - is a bit confusing.
麻烦的是, 用两条线 "设置"和"复位" 来输入, 有点难理解
To make this a little easier to use, we really want a single wire to input data,
为了更容易用,我们希望只有一条输入线
that we can set to either 0 or 1 to store the value.
将它设为 0 或 1 来存储值
Additionally, we are going to need a wire that enables the memory
还需要一根线来"启用"内存
to be either available for writing or "locked" down
启用时允许写入,没启用时就 "锁定"
- which is called the write enable line.
- 这条线叫 "允许写入线"
By adding a few extra logic gates, we can build this circuit,
加一些额外逻辑门,可以做出这个电路
which is called a Gated Latch since the "gate" can be opened or closed.
这叫"门锁",因为门可以打开和关上
Now this circuit is starting to get a little complicated.
现在有点复杂了
We don't want to have to deal with all the individual logic gates...
我们不想关心单独的逻辑门
so as before, we're going to bump up a level of abstraction,
所以我们提升一层抽象
and put our whole Gated Latch circuit in a box -- a box that stores one bit.
把 "门锁" 放到盒子里 - 这个盒子能存一个 bit
Let's test out our new component!
我们来测一下新组件!
Let's start everything at 0.
一切从 0 开始
If we toggle the Data wire from 0 to 1 or 1 to 0,
数据输入从0换到1, 从1换到0
nothing happens - the output stays at 0.
什么也不会发生 - 输出依然是 0
That's because the write enable wire is off, which prevents any change to the memory.
因为 "允许写入线" 是关闭的,所以内容不会变化
So we need to "open" the "gate" by turning the write enable wire to 1.
所以要给 "允许写入线" 输入 1, "打开" 门
Now we can put a 1 on the data line to save the value 1 to our latch.
现在往 "数据线" 放 1,1 就能存起来了
Notice how the output is now 1.\NNow we can put a 1 on the data line to save the value 1 to our latch.
Notice how the output is now 1.
注意输出现在是 1 了
Success!
成功!
We can turn off the enable line and the output stays as 1.
现在可以关掉 "允许写入线" ,输出会保持 1
Once again, we can toggle the value on the data line all we want,
现在不管给 "数据线" 什么值
but the output will stay the same.
输出都不会变
The value is saved in memory.
值存起来了
Now let's turn the enable line on again use our data line to set the latch to 0.
现在又打开 "允许写入线" \N "数据线" 设为0
Done.
完成
Enable line off, and the output is 0.
"允许写入线" 关闭,输出 0
And it works!
成功了!
Now, of course, computer memory that only stores one bit of information isn't very useful
当然,只能存 1 bit 没什么大用
-- definitely not enough to run Frogger.
- 肯定玩不了游戏
Or anything, really.
或做其它事情
But we're not limited to using only one latch.
但我们没限制只能用一个锁存器
If we put 8 latches side-by-side, we can store 8 bits of information like an 8-bit number.
如果我们并排放 8 个锁存器,\N 可以存 8 位信息,比如一个 8 bit 数字
A group of latches operating like this is called a register,
一组这样的锁存器叫 "寄存器"
which holds a single number, and the number of bits in a register is called its width.
寄存器能存一个数字,这个数字有多少位,叫"位宽"
Early computers had 8-bit registers, then 16, 32,
早期电脑用 8 位寄存器,然后是 16 位,32 位
and today, many computers have registers that are 64-bits wide.
如今许多计算机都有 64 位宽的寄存器
To write to our register, we first have to enable all of the latches.
写入寄存器前,要先启用里面所有锁存器
We can do this with a single wire that connects to all of their enable inputs, which we set to 1.
我们可以用一根线连接所有 "允许输入线", 把它设为 1
We then send our data in using the 8 data wires, and then set enable back to 0,
然后用 8 条数据线发数据,然后将 "允许写入线" 设回 0
and the 8 bit value is now saved in memory.
现在 8 位的值就存起来了
Putting latches side-by-side works ok for a small-ish number of bits.
如果只有很少的位(bits),把锁存器并排放置,也勉强够用了.
A 64-bit register would need 64 wires running to the data pins, and 64 wires running to the outputs.
64 位寄存器要 64 根数据线,64 根连到输出端
Luckily we only need 1 wire to enable all the latches, but that's still 129 wires.
幸运的是,我们只要 1 根线启用所有锁存器 \N 但加起来也有 129 条线了
For 256 bits, we end up with 513 wires!
如果存 256 位要 513 条线!
The solution is a matrix!
解决方法是矩阵!
In this matrix, we don't arrange our latches in a row,
在矩阵中,我们不并列排放锁存器
we put them in a grid.
而是做成网格
For 256 bits, we need a 16 by 16 grid of latches with 16 rows and columns of wires.
存 256 位,我们用 16x16 网格的锁存器,有 16 行 16 列
To activate any one latch, we must turn on the corresponding row AND column wire.
要启用某个锁存器,就打开相应的 行线 和 列线
Let's zoom in and see how this works.
放大看看怎么做的
We only want the latch at the intersection of the two active wires to be enabled,
我们只想打开交叉处 锁存器的 "允许写入线"
but all of the other latches should stay disabled.
所有其他锁存器,保持关闭
For this, we can use our trusty AND gate!
我们可以用 AND 门!
The AND gate will output a 1 only if the row and the column wires are both 1.
只有 行线和列线 均为 1 ,AND 门才输出 1
So we can use this signal to uniquely select a single latch.
所以可以用选择单个锁存器
This row/column setup connects all our latches with a single, shared, write enable wire.
这种行/列排列法,用一根 "允许写入线" 连所有锁存器
In order for a latch to become write enabled,
为了让锁存器变成 "允许写入"
the row wire, the column wire, and the write enable wire must all be 1.
行线,列线和 "允许写入线" 都必须是 1
That should only ever be true for one single latch at any given time.
每次只有 1 个锁存器会这样
This means we can use a single, shared wire for data.
代表我们可以只用一根 "数据线" \N 连所有锁存器来传数据
Because only one latch will ever be write enabled, only one will ever save the data
因为只有一个锁存器会启用,只有那个会存数据
-- the rest of the latches will simply ignore values on the data wire because they are not write enabled.
其他锁存器会忽略数据线上的值,因为没有 "允许写入"
We can use the same trick with a read enable wire to read the data later,
我们可以用类似的技巧, 做"允许读取线"来读数据
to get the data out of one specific latch.
从一个指定的锁存器,读取数据
This means in total, for 256 bits of memory,
所以对于 256 位的存储
we only need 35 wires - 1 data wire, 1 write enable wire, 1 read enable wire,
只要 35 条线 \N1条"数据线", 1条"允许写入线", 1条"允许读取线"
and 16 rows and columns for the selection.
还有16行16列的线用于选择锁存器 \N (16+16=32, 32+3=35)
That's significant wire savings!
这省了好多线!
But we need a way to uniquely specify each intersection.
但我们需要某种方法来 唯一指定 交叉路口
We can think of this like a city,
我们可以想成城市
where you might want to meet someone at 12th avenue and 8th street
你可能想和别人 在第 12 大道和第 8 街的交界碰面
-- that's an address that defines an intersection.
- 这是一个交叉点的地址
The latch we just saved our one bit into has an address of row 12 and column 8.
我们刚刚存了一位的地址是 "12行 8列"
Since there is a maximum of 16 rows, we store the row address in a 4 bit number.
由于最多 16 行, 用 4 位就够了
12 is 1100 in binary.
12 用二进制表示为 1100
We can do the same for the column address: 8 is 1000 in binary.
列地址也可以这样: 8 用二进制表示为 1000
So the address for the particular latch we just used can be written as 11001000.
刚才说的"12行 8列"可以写成 11001000
To convert from an address into something that selects the right row or column,
为了将地址转成 行和列
we need a special component called a multiplexer
我们需要 "多路复用器"
-- which is the computer component with a pretty cool name at least compared to the ALU.
- 这个名字起码比 ALU 酷一点
Multiplexers come in all different sizes,
多路复用器有不同大小
but because we have 16 rows, we need a 1 to 16 multiplexer.
因为有 16 行,我们需要 1 到 16 多路复用器
It works like this.
工作方式是
You feed it a 4 bit number, and it connects the input line to a corresponding output line.
输入一个 4 位数字,它会把那根线,连到相应的输出线
So if we pass in 0000, it will select the very first column for us.
如果输入 0000,它会选择第一列
If we pass in 0001, the next column is selected, and so on.
如果输入 0001,会选择下一列,依此类推
We need one multiplexer to handle our rows and another multiplexer to handle the columns.
一个多路复用器处理行(row) \N 另一个多路复用器处理列(column)
Ok, it's starting to get complicated again,
好吧,开始有点复杂了
so let's make our 256-bit memory its own component.
那么把 256 位内存当成一个整体好了
Once again a new level of abstraction!
又提升了一层抽象!
It takes an 8-bit address for input - the 4 bits for the column and 4 for the row.
它输入一个 8 位地址:4 位代表列,4 位代表行
We also need write and read enable wires.
我们还需要 "允许写入线" 和 "允许读取线"
And finally, we need just one data wire, which can be used to read or write data.
最后,还需要一条数据线,用于读/写数据
Unfortunately, even 256-bits of memory isn't enough to run much of anything,
不幸的是, 256 位的内存也没法做什么事
so we need to scale up even more!
所以还要扩大规模
We're going to put them in a row.
把它们并排放置
Just like with the registers.
就像寄存器一样
We'll make a row of 8 of them, so we can store an 8 bit number - also known as a byte.
一行8个,可以存一个 8 位数字 \N 8 位也叫一个字节(byte)
To do this, we feed the exact same address into all 8 of our 256-bit memory components at the same time,
为了存一个 8 位数字,我们同时给 8 个 256 位内存一样的地址
and each one saves one bit of the number.
每个地址存 1 位
That means the component we just made can store 256 bytes at 256 different addresses.
意味着这里总共能存 256 个字节 (byte)
Again, to keep things simple, we want to leave behind this inner complexity.
再次,为了简单,我们不管内部
Instead of thinking of this as a series of individual memory modules and circuits,
不看作是一堆独立的存储模块和电路
we'll think of it as a uniform bank of addressable memory.
而是看成一个整体的可寻址内存
We have 256 addresses,
我们有 256 个地址
and at each address, we can read or write an 8-bit value.
每个地址能读或写一个 8 位值
We're going to use this memory component next episode when we build our CPU.
我们下集做 CPU 时会用到这个内存
The way that modern computers scale to megabytes and gigabytes of memory
现代计算机的内存 \N 扩展到上兆字节(MB)和千兆字节(GB)的方式
is by doing the same thing we've been doing here
和我们这里做的一样
-- keep packaging up little bundles of memory into larger, and larger, and larger arrangements.
不断把内存打包到更大规模
As the number of memory locations grow, our addresses have to grow as well.
随着内存地址增多,内存地址也必须增长
8 bits hold enough numbers to provide addresses for 256 bytes of our memory,
8 位最多能代表 256 个内存地址 \N(1111 1111 是255,0~255 一共 256 个数字)
but that's all.
只有这么多
To address a gigabyte - or a billion bytes of memory - we need 32-bit addresses.
要给千兆或十亿字节的内存寻址,需要 32 位的地址
An important property of this memory is that we can access any memory location, at any time, and in a random order.
内存的一个重要特性是:可以随时访问任何位置
For this reason, it's called Random-Access Memory or RAM.
因此叫 "随机存取存储器" ,简称 RAM
When you hear people talking about how much RAM a computer has
当你听到有人说 RAM 有多大
- that's the computer's memory.
他的意思是内存有多大
RAM is like a human's short term or working memory,
RAM 就像人类的短期记忆
where you keep track of things going on right now
记录当前在做什么事
- like whether or not you had lunch or paid your phone bill.
比如吃了午饭没,或有没有交电话费
Here's an actual stick of RAM - with 8 memory modules soldered onto the board.
这是一条真的内存,上面焊了 8 个内存模块
If we carefully opened up one of these modules and zoomed in,
如果打开其中一个,然后放大
The first thing you would see are 32 squares of memory.
会看到 32 个内存方块
Zoom into one of those squares, and we can see each one is comprised of 4 smaller blocks.
放大其中一个方块,可以看到有 4 个小块
If we zoom in again, we get down to the matrix of individual bits.
如果再放大,可以看到存一个"位"的矩阵
This is a matrix of 128 by 64 bits.
这个矩阵是 128 位 x 64 位
That's 8192 bits in total.
总共 8192 位
Each of our 32 squares has 4 matrices, so that's 32 thousand, 7 hundred and 68 bits.
每个方格 4 个矩阵 \N 所以一个方格有 32768 个位 (8192 x 4 = 32768)
And there are 32 squares in total.
而一共 32 个方格
So all in all, that's roughly 1 million bits of memory in each chip.
总而言之,1 个芯片大约存 100 万位
Our RAM stick has 8 of these chips, so in total, this RAM can store 8 millions bits,
RAM 有 8 个芯片,所以总共 800 万位
otherwise known as 1 megabyte.
也就是 1 兆字节(1 MB)
That's not a lot of memory these days -- this is a RAM module from the 1980's.
1 MB 如今不算大 - 这是 1980 年代的 RAM
Today you can buy RAM that has a gigabyte or more of memory
如今你可以买到千兆字节(GB)的 RAM
- that's billions of bytes of memory.
那可是数十亿字节的内存
So, today, we built a piece of SRAM - Static Random-Access Memory - which uses latches.
今天,我们用锁存器做了一块 SRAM(静态随机存取存储器)
There are other types of RAM, such as DRAM, Flash memory, and NVRAM.
还有其他类型的 RAM,如 DRAM,闪存和 NVRAM
These are very similar in function to SRAM,
它们在功能上与 SRAM 相似
but use different circuits to store the individual bits
但用不同的电路存单个位
- for example, using different logic gates, capacitors, charge traps, or memristors.
- 比如用不同的逻辑门,电容器,电荷捕获或忆阻器
But fundamentally, all of these technologies store bits of information
但根本上 这些技术都是矩阵层层嵌套,来存储大量信息
in massively nested matrices of memory cells.
但根本上 这些技术都是矩阵层层嵌套,来存储大量信息
Like many things in computing, the fundamental operation is relatively simple.
就像计算机中的很多事情,底层其实都很简单
it's the layers and layers of abstraction that's mind blowing
让人难以理解的,是一层层精妙的抽象
-- like a russian doll that keeps getting smaller and smaller and smaller.
像一个越来越小的俄罗斯套娃
I'll see you next week.
下周见
================================================
FILE: (字幕)全40集中英字幕文本/07. 中央处理器-The Central Processing Unit(CPU).ass.txt
================================================
Hi, I'm Carrie Anne, this is Crash Course Computer Science
嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
and today, we're talking about processors.
今天我们讲 处理器
Just a warning though - this is probably the most complicated episode in the series.
提示下 - 这集可能是最难的一集
So once you get this, you're golden.
所以一旦你理解了,就会变得超厉害der~
We've already made a Arithmetic and Logic Unit,
我们已经做了一个算术逻辑单元(ALU)
which takes in binary numbers and performs calculations,
输入二进制,它会执行计算
and we've made two types of computer memory:
我们还做了两种内存:
Registers -- small, linear chunks of memory, useful for storing a single value
寄存器 - 很小的一块内存,能存一个值
and then we scaled up, and made some RAM,
之后我们增大做出了 RAM
a larger bank of memory that can store a lot of numbers located at different addresses.
RAM 是一大块内存,能在不同地址存大量数字
Now it's time to put it all together and build ourselves the heart of any computer,
现在是时候把这些放在一起,组建计算机的 "心脏" 了
but without any of the emotional baggage that comes with human hearts.
但这个 "心脏" 不会有任何包袱,比如人类情感.
For computers, this is the Central Processing Unit, most commonly called the CPU.
计算机的心脏是"中央处理单元",简称 "CPU"
A CPU's job is to execute programs.
CPU 负责执行程序
Programs, like Microsoft Office, Safari, or your beloved copy of Half Life: 2,
比如 Office,Safari 浏览器,你最爱的 《半条命2》
are made up of a series of individual operations,
程序由一个个操作组成
called instructions, because they "instruct" the computer what to do.
这些操作叫"指令"(Instruction) \N 因为它们"指示"计算机要做什么
If these are mathematical instructions, like add or subtract,
如果是数学指令,比如加/减
the CPU will configure its ALU to do the mathematical operation.
CPU 会让 ALU 进行数学运算
Or it might be a memory instruction,
也可能是内存指令,CPU 会和内存通信,然后读/写值
in which case the CPU will talk with memory to read and write values.
也可能是内存指令,CPU 会和内存通信,然后读/写值
There are a lot of parts in a CPU,
CPU 里有很多组件.
so we're going to lay it out piece by piece, building up as we go.
所以我们一边说一边建
We'll focus on functional blocks, rather than showing every single wire.
我们把重点放在功能,而不是一根根线具体怎么连
When we do connect two components with a line,
当我们用一条线连接两个组件时
this is an abstraction for all of the necessary wires.
这条线只是所有必须线路的一个抽象
This high level view is called the microarchitecture.
这种高层次视角叫 "微体系架构"
OK, first, we're going to need some memory.
好,我们首先要一些内存,把上集做的 RAM 拿来就行
Lets drop in the RAM module we created last episode.
好,我们首先要一些内存,把上集做的 RAM 拿来就行
To keep things simple, we'll assume it only has 16 memory locations, each containing 8 bits.
为了保持简单,假设它只有 16 个位置,每个位置存 8 位
Let's also give our processor four, 8-bit memory registers, labeled A, B, C and D
再来四个 8 位寄存器,叫 A,B,C,D
which will be used to temporarily store and manipulate values.
寄存器用来 临时存数据 和 操作数据
We already know that data can be stored in memory as binary values
我们已经知道数据 是以二进制值存在内存里
and programs can be stored in memory too.
程序也可以存在内存里
We can assign an ID to each instruction supported by our CPU.
我们可以给 CPU 支持的所有指令,分配一个 ID
指令表
指令
描述
4位操作码
地址或寄存器
In our hypothetical example, we use the first four bits to store the "operation code",
在这个假设的例子 \N 我们用前四位存 "操作代码" (operation code)
or opcode for short.
简称 "操作码" (opcode)
The final four bits specify where the data for that operation should come from -
后四位代表数据来自哪里
this could be registers or an address in memory.
- 可以是寄存器或内存地址
We also need two more registers to complete our CPU.
我们还需要两个寄存器,来完成 CPU.
First, we need a register to keep track of where we are in a program.
1. 一个寄存器追踪程序运行到哪里了,我们叫它 "指令地址寄存器"
For this, we use an instruction address register,
1. 一个寄存器追踪程序运行到哪里了,我们叫它 "指令地址寄存器"
which as the name suggests, stores the memory address of the current instruction.
顾名思义,存当前指令的内存地址
And then we need the other register to store the current instruction,
2. 另一个寄存器存当前指令,叫 "指令寄存器"
which we'll call the instruction register.
2. 另一个寄存器存当前指令,叫 "指令寄存器"
When we first boot up our computer, all of our registers start at 0.
当启动计算机时,所有寄存器从 0 开始
As an example, we've initialized our RAM with a simple computer program that we'll to through today.
为了举例,我们在 RAM 里放了一个程序,我们今天会过一遍
The first phase of a CPU's operation is called the fetch phase.
CPU 的第一个阶段叫 "取指令阶段"
This is where we retrieve our first instruction.
负责拿到指令
First, we wire our Instruction Address Register to our RAM module.
首先,将 "指令地址寄存器" 连到 RAM
The register's value is 0, so the RAM returns whatever value is stored in address 0.
寄存器的值为 0,因此 RAM 返回地址 0 的值
In this case, 0010 1110.
0010 1110 会复制到 "指令寄存器" 里
Then this value is copied into our instruction register.
0010 1110 会复制到 "指令寄存器" 里
Now that we've fetched an instruction from memory,
现在指令拿到了
we need to figure out what that instruction is
要弄清是什么指令,才能执行(execute)
so we can execute it.
要弄清是什么指令,才能执行(execute)
That is run it.
而不是杀死(kill)它
Not kill it.
而不是杀死(kill)它
This is called the decode phase.
这是 "解码阶段"
指令表
指令
描述
4位操作码
地址或寄存器
In this case the opcode, which is the first four bits, is: 0010.
前 4 位 0010 是 LOAD A 指令
This opcode corresponds to the "LOAD A" instruction,
前 4 位 0010 是 LOAD A 指令
which loads a value from RAM into Register A.
意思是,把 RAM 的值放入寄存器 A
The RAM address is the last four bits of our instruction which are 1110, or 14 in decimal.
后 4 位 1110 是 RAM 的地址, 转成十进制是 14
Next, instructions are decoded and interpreted by a Control Unit.
接下来,指令由 "控制单元" 进行解码
Like everything else we've built, it too is made out of logic gates.
就像之前的所有东西 \N "控制单元" 也是逻辑门组成的
For example, to recognize a LOAD A instruction,
比如,为了识别 "LOAD A" 指令
we need a circuit that checks if the opcode matches 0010
需要一个电路,检查操作码是不是 0010
which we can do with a handful of logic gates.
我们可以用很少的逻辑门来实现.
Now that we know what instruction we're dealing with,
现在知道了是什么指令
we can go ahead and perform that instruction which is the beginning of the execute phase!
就可以开始执行了,开始 "执行阶段"
Using the output of our LOAD_A checking circuit,
用 "检查是否 LOAD_A 指令的电路"
we can turn on the RAM's read enable line and send in address 14.
可以打开 RAM 的 "允许读取线", 把地址 14 传过去
The RAM retrieves the value at that address, which is 00000011, or 3 in decimal.
RAM 拿到值,0000 0011,十进制的 3
Now, because this is a LOAD_A instruction,
因为是 LOAD_A 指令 \N 我们想把这个值只放到寄存器 A,其他寄存器不受影响
we want that value to only be saved into Register A and not any of the other registers.
因为是 LOAD_A 指令 \N 我们想把这个值只放到寄存器 A,其他寄存器不受影响
So if we connect the RAM's data wires to our four data registers,
所以需要一根线,把 RAM 连到 4 个寄存器
we can use our LOAD_A check circuit to enable the write enable only for Register A.
用 "检查是否 LOAD_A 指令的电路" \N 启用寄存器 A 的 "允许写入线"
And there you have it
这就成功了
-- we've successfully loaded the value at RAM address 14 into Register A.
- 把 RAM 地址 14 的值,放到了寄存器 A.
We've completed the instruction, so we can turn all of our wires off,
既然指令完成了,我们可以关掉所有线路
and we are ready to fetch the next instruction in memory.
去拿下一条指令
To do this, we increment the Instruction Address Register by 1 which completes the execute phase.
我们把 "指令地址寄存器"+1,"执行阶段"就此结束.
LOAD_A is just one of several possible instructions that our CPU can execute.
LOAD_A 只是 CPU 可以执行的各种指令之一
Different instructions are decoded by different logic circuits,
不同指令由不同逻辑电路解码
which configure the CPU's components to perform that action.
这些逻辑电路会配置 CPU 内的组件来执行对应操作
Looking at all those individual decode circuits is too much detail,
具体分析这些解码电路太繁琐了
so since we looked at one example,
既然已经看了 1 个例子,
we're going to go head and package them all up as a single Control Unit to keep things simple.
干脆把 "控制单元 "包成一个整体,简洁一些.
That's right a new level of abstraction.
没错,一层新抽象
The Control Unit is comparable to the conductor of an orchestra,
控制单元就像管弦乐队的指挥
directing all of the different parts of the CPU.
"指挥" CPU 的所有组件
Having completed one full fetch/decode/execute cycle,
"取指令→解码→执行" 完成后
we're ready to start all over again, beginning with the fetch phase.
现在可以再来一次,从 "取指令" 开始
The Instruction Address Register now has the value 1 in it,
"指令地址寄存器" 现在的值是 1
so the RAM gives us the value stored at address 1, which is 0001 1111.
所以 RAM 返回地址 1 里的值:0001 1111
On to the decode phase!
到 "解码" 阶段!
0001 is the "LOAD B" instruction, which moves a value from RAM into Register B.
0001 是 LOAD B 指令 \N 从 RAM 里把一个值复制到寄存器 B
The memory location this time is 1111, which is 15 in decimal.
这次内存地址是 1111,十进制的 15
Now to the execute phase!
现在到 "执行阶段"!
The Control Unit configures the RAM to read address 15 and configures Register B to receive the data.
"控制单元" 叫 RAM 读地址 15,并配置寄存器 B 接收数据
Bingo, we just saved the value 00001110, or the number 14 in decimal, into Register B.
成功,我们把值 0000 1110 \N 也就是十进制的 14 存到了寄存器 B
Last thing to do is increment our instruction address register by 1,
最后一件事是 "指令地址寄存器" +1
and we're done with another cycle.
我们又完成了一个循环
Our next instruction is a bit different.
下一条指令有点不同
Let's fetch it.
来取它吧
1000 0100.
1000 0100
That opcode 1000 is an ADD instruction.
1000 是 ADD 指令
Instead of an 4-bit RAM address, this instruction uses two sets of 2 bits.
这次后面的 4 位不是 RAM 地址,\N 而是 2 位 2 位分别代表 2 个寄存器
Remember that 2 bits can encode 4 values,
2 位可以表示 4 个值
so 2 bits is enough to select any one of our 4 registers.
所以足够表示 4 个寄存器
The first set of 2 bits is 01, which in this case corresponds to Register B,
第一个地址是 01, 代表寄存器B
and 00, which is Register A.
第二个地址是 00, 代表寄存器A
So "1000 01 00" is the instruction for adding the value in Register B into the value in register A.
因此,1000 0100,代表把寄存器 B 的值,加到寄存器 A 里
So to execute this instruction, we need to integrate the ALU we made in Episode 5 into our CPU.
为了执行这个指令,我们要整合第 5 集的 ALU
The Control Unit is responsible for selecting the right registers to pass in as inputs,
"控制单元" 负责选择正确的寄存器作为输入
and configuring the ALU to perform the right operation.
并配置 ALU 执行正确的操作
For this ADD instruction, the Control Unit enables Register B
对于 "ADD" 指令, "控制单元" 会
and feeds its value into the first input of the ALU.
启用寄存器 B,作为 ALU 的第一个输入
It also enables Register A and feeds it into the second ALU input.
还启用寄存器 A,作为 ALU 的第二个输入
As we already discussed, the ALU itself can perform several different operations,
之前说过,ALU 可以执行不同操作
so the Control Unit must configure it to perform an ADD operation by passing in the ADD opcode.
所以控制单元必须传递 ADD 操作码告诉它要做什么
Finally, the output should be saved into Register A.
最后,结果应该存到寄存器 A
But it can't be written directly
但不能直接写入寄存器 A
because the new value would ripple back into the ALU and then keep adding to itself.
这样新值会进入 ALU ,不断和自己相加
So the Control Unit uses an internal register to temporarily save the output,
因此,控制单元用一个自己的寄存器暂时保存结果
turn off the ALU, and then write the value into the proper destination register.
关闭 ALU,然后把值写入正确的寄存器
In this case, our inputs were 3 and 14, and so the sum is 17, or 00010001 in binary,
这里 3+14=17,二进制是 0001 0001
which is now sitting in Register A.
现在存到了寄存器 A
As before, the last thing to do is increment our instruction address by 1,
和之前一样,最后一件事是把指令地址 + 1
and another cycle is complete.
这个循环就完成了
Okay, so let's fetch one last instruction: 0100 1101.
好,来看最后一个指令:0100 1101
When we decode it we see that 0100 is a STORE_A instruction, with a RAM address of 13.
解码得知是 STORE A 指令(把寄存器 A 的值放入内存) \N RAM 地址 13
As usual, we pass the address to the RAM module,
接下来,把地址传给 RAM
but instead of read-enabling the memory, we write-enable it.
但这次不是 "允许读取" ,而是 "允许写入"
At the same time, we read-enable Register A.
同时,打开寄存器 A 的 "允许读取"
This allows us to use the data line to pass in the value stored in register A.
这样就可以把寄存器 A 里的值,传给 RAM
Congrats, we just ran our first computer program!
恭喜,我们刚运行了第一个电脑程序!
It loaded two values from memory, added them together,
它从内存中加载两个值,相加,然后把结果放回内存
and then saved that sum back into memory.
它从内存中加载两个值,相加,然后把结果放回内存
Of course, by me talking you through the individual steps,
刚刚是我一步步来讲的,
I was manually transitioning the CPU through its fetch, decode and execute phases.
我们人工切换 CPU 的状态 "取指令→解码→执行"
But there isn't a mini Carrie Anne inside of every computer.
但不是每台电脑里都有一个迷你 Carrie Anne
So the responsibility of keeping the CPU ticking along falls to a component called the clock.
其实是 "时钟" 来负责管理 CPU 的节奏
As it's name suggests, the clock triggers an electrical signal at a precise and regular interval.
时钟以精确的间隔 触发电信号
Its signal is used by the Control Unit to advance the internal operation of the CPU,
控制单元会用这个信号,推进 CPU 的内部操作
keeping everything in lock-step
确保一切按步骤进行
- like the dude on a Roman galley drumming rhythmically at the front,
- 就像罗马帆船的船头,有一个人负责按节奏的击鼓,
keeping all the rowers synchronized... or a metronome.
让所有划船的人同步... 就像节拍器一样
Of course you can't go too fast,
节奏不能太快
because even electricity takes some time to travel down wires and for the signal to settle.
因为就算是电也要一定时间来传输
The speed at which a CPU can carry out each step of the fetch-decode-execute cycle
CPU "取指令→解码→执行" 的速度叫 "时钟速度"
is called its Clock Speed.
CPU "取指令→解码→执行" 的速度叫 "时钟速度"
This speed is measured in Hertz - a unit of frequency.
单位是赫兹 - 赫兹是用来表示频率的单位
One Hertz means one cycle per second.
1 赫兹代表一秒 1 个周期
Given that it took me about 6 minutes to talk you through 4 instructions
因为我花了大概 6 分钟,给你讲了 4 条指令
LOAD, LOAD, ADD and STORE
读取→读取→相加→存储
that means I have an effective clock speed of roughly .03 Hertz.
所以我的时钟速度大概是 0.03 赫兹
Admittedly, I'm not a great computer
我承认我算数不快
but even someone handy with math might only be able to do one calculation in their head every second or 1 Hertz.
但哪怕有人算数很快,最多也就是一秒一次,或 1 赫兹
The very first, single-chip CPU was the Intel 4004, a 4-bit CPU released in 1971.
第一个单芯片 CPU 是 "英特尔 4004" \N 1971 年发布的 4 位CPU
It's microarchitecture is actually pretty similar to our example CPU.
它的微架构 很像我们之前说的 CPU
Despite being the first processor of its kind,
虽然是第一个单芯片的处理器
it had a mind-blowing clock speed of 740 Kilohertz
但它的时钟速度达到了 740 千赫兹 - 每秒 74 万次
-- that's 740 thousand cycles per second.
但它的时钟速度达到了 740 千赫兹 - 每秒 74 万次
You might think that's fast,
你可能觉得很快
but it's nothing compared to the processors that we use today.
但和如今的处理器相比不值一提
One megahertz is one million clock cycles per second,
一兆赫兹是 1 秒 1 百万个时钟周期
and the computer or even phone that you are watching this video on right now is no doubt a few gigahertz
你现在看视频的电脑或手机,肯定有几千兆赫兹
-- that's BILLIONs of CPU cycles every single... second.
- 1 秒 10 亿次时钟周期
Also, you may have heard of people overclocking their computers.
你可能听过有人会把计算机超频
This is when you modify the clock to speed up the tempo of the CPU
意思是修改时钟速度,加快 CPU 的速度
-- like when the drummer speeds up when the Roman Galley needs to ram another ship.
- 就像罗马帆船要撞另一艘船时,鼓手会加快敲鼓速度
Chip makers often design CPUs with enough tolerance to handle a little bit of overclocking,
芯片制造商经常给 CPU 留一点余地,可以接受一点超频
but too much can either overheat the CPU,
但超频太多会让 CPU 过热
or produce gobbledygook as the signals fall behind the clock.
或产生乱码,因为信号跟不上时钟
And although you don't hear very much about underclocking,
你可能很少听说降频
it's actually super useful.
但降频其实很有用
Sometimes it's not necessary to run the processor at full speed...
有时没必要让处理器全速运行
maybe the user has stepped away, or just not running a particularly demanding program.
可能用户走开了,或者在跑一个性能要求较低的程序
By slowing the CPU down, you can save a lot of power,
把 CPU 的速度降下来,可以省很多电
which is important for computers that run on batteries, like laptops and smartphones.
省电对用电池的设备很重要,比如笔记本和手机
To meet these needs,
为了尽可能省电
many modern processors can increase or decrease their clock speed based on demand,
很多现代处理器可以按需求 加快或减慢时钟速度
which is called dynamic frequency scaling.
这叫 "动态调整频率"
So, with the addition of a clock, our CPU is complete.
加上时钟后,CPU 才是完整的.
We can now put a box around it, and make it its own component.
现在可以放到盒子里,变成一个独立组件
Yup.
对
A new level of abstraction!
一层新的抽象!
RAM, as I showed you last episode,
RAM,上集说过,是在 CPU 外面的独立组件
lies outside the CPU as its own component,
RAM,上集说过,是在 CPU 外面的独立组件
and they communicate with each other using address, data and enable wires.
CPU 和 RAM 之间 \N 用 "地址线" "数据线" 和 "允许读/写线" 进行通信
Although the CPU we designed today is a simplified example,
虽然今天我们设计的 CPU 是简化版的,
many of the basic mechanics we discussed are still found in modern processors.
但我们提到的很多机制,依然存在于现代处理器里
Next episode, we're going to beef up our CPU,
下一集,我们要加强 CPU,给它扩展更多指令.
extending it with more instructions as we take our first baby steps into software.
同时开始讲软件.
I'll see you next week.
下周见
================================================
FILE: (字幕)全40集中英字幕文本/08. 指令和程序-Instructions & Programs.ass.txt
================================================
Hi, I’m Carrie Anne and this is Crash Course Computer Science!
(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
Last episode, we combined an ALU, control unit, some memory, and a clock together to
上集我们把 ALU, 控制单元, RAM, 时钟 结合在一起
make a basic, but functional Central Processing Unit – or CPU
做了个基本,但可用的"中央处理单元", 简称 CPU
– the beating, ticking heart of a computer.
它是计算机的核心
We’ve done all the hard work of building many of these components from the electronic
我们已经用电路做了很多组件.
circuits up, and now it’s time to give our CPU some actual instructions to process!
这次我们给 CPU 一些指令来运行!
The thing that makes a CPU powerful is the fact that it is programmable –
CPU 之所以强大,是因为它是可编程的 -
if you write a different sequence of instructions, then the CPU will perform a different task.
如果写入不同指令,就会执行不同任务
So the CPU is a piece of hardware which is controlled by easy-to-modify software!
CPU 是一块硬件,可以被软件控制!
Let’s quickly revisit the simple program that we stepped through last episode.
我们重新看一下上集的简单程序
The computer memory looked like this.
内存里有这些值
Each address contained 8 bits of data.
每个地址可以存 8 位数据
For our hypothetical CPU, the first four bits specified the operation code, or opcode, and
因为我们的 CPU 是假设的,这里前4位是"操作码"
the second set of four bits specified an address or registers.
后4位指定一个内存地址,或寄存器.
In memory address zero we have 0010 1110.
内存地址 0 是 0010 1110
Again, those first four bits are our opcode which corresponds to a "LOAD_A" instruction.
前 4 位代表 LOAD_A 指令
This instruction reads data from a location of memory specified in those last four bits
意思是:把后 4 位指定的内存地址的值,放入寄存器 A
of the instruction and saves it into Register A. In this case, 1110, or 14 in decimal.
后 4 位是 1110,十进制的 14
So let’s not think of this of memory address 0 as "0010 1110", but rather as the instruction
我们来把 0010 1110 看成 "LOAD_A 14" 指令
"LOAD_A 14".
我们来把 0010 1110 看成 "LOAD_A 14" 指令
That’s much easier to read and understand!
这样更好理解!
And for me to say!
也更方便说清楚
And we can do the same thing for the rest of the data in memory.
可以对内存里剩下的数也这样转换.
In this case, our program is just four instructions long,
这里,我们的程序只有4个指令
and we’ve put some numbers into memory too, 3 and 14.
还有数字 3 和 14
So now let’s step through this program:
现在一步步看
First is LOAD_A 14, which takes the value in address 14, which is the number 3,
"LOAD_A 14" 是从地址 14 中拿到数字3,放入寄存器A
and stores it into Register A.
"LOAD_A 14" 是从地址 14 中拿到数字3,放入寄存器A
Then we have a "LOAD_B 15" instruction, which takes the value in memory location 15,
"LOAD_B 15" 是从地址 15 中拿到数字14,放入寄存器B
which is the number 14, and saves it into Register B.
"LOAD_B 15" 是从地址 15 中拿到数字14,放入寄存器B
Okay.
好.
Easy enough.
挺简单的!
But now we have an "ADD" instruction.
下一个是 ADD 指令
This tells the processor to use the ALU to add two registers together,
"ADD B A" 告诉 ALU \N 把寄存器 B 和寄存器 A 里的数字加起来
in this case, B and A are specified.
"ADD B A" 告诉 ALU \N 把寄存器 B 和寄存器 A 里的数字加起来
The ordering is important, because the resulting sum is saved into the second register that’s specified.
(B和A的)顺序很重要,因为结果会存在第二个寄存器
So in this case, the resulting sum is saved into Register A.
也就是寄存器 A
And finally, our last instruction is "STORE_A 13", which instructs the CPU to write whatever
最后一条指令是 "STORE_A 13" \N 把寄存器 A 的值存入内存地址 13
value is in Register A into memory location 13.
最后一条指令是 "STORE_A 13" \N 把寄存器 A 的值存入内存地址 13
Yesss!
好棒!
Our program adds two numbers together.
我们把 2 个数加在了一起!
That’s about as exciting as it gets when we only have four instructions to play with.
毕竟只有4个指令,也只能做这个了.
So let’s add some more!
加多一些指令吧!
Now we’ve got a subtract function, which like ADD, specifies two registers to operate on.
SUB 是减法,和 ADD 一样也要 2 个寄存器来操作.
We’ve also got a fancy new instruction called JUMP.
还有 JUMP(跳转)
As the name implies, this causes the program to "jump" to a new location.
让程序跳转到新位置
This is useful if we want to change the order of instructions, or choose to skip some instructions.
如果想改变指令顺序,或跳过一些指令,这个很实用
For example, a JUMP 0, would cause the program to go back to the beginning.
举例, JUMP 0 可以跳回开头
At a low level, this is done by writing the value specified in the last four bits into
JUMP 在底层的实现方式是 \N 把指令后 4 位代表的内存地址的值
the instruction address register, overwriting the current value.
覆盖掉 "指令地址寄存器" 里的值
We’ve also added a special version of JUMP called JUMP_NEGATIVE.
还有一个特别版的 JUMP 叫 JUMP_NEGATIVE
"This only jumps the program if the ALU’s negative flag is set to true.
它只在 ALU 的 "负数标志" 为真时,进行 JUMP
As we talked about in Episode 5, the negative flag is only set
第5集讲过,算术结果为负,"负数标志"才是真
when the result of an arithmetic operation is negative.
第5集讲过,算术结果为负,"负数标志"才是真
If the result of the arithmetic was zero or positive, the negative flag would not be set.
结果不是负数时, "负数标志"为假
So the JUMP NEGATIVE won’t jump anywhere, and the CPU will just continue on to the next instruction.
如果是假,JUMP_NEGATIVE 就不会执行 \N 程序照常进行
Our previous program really should have looked like this to be correct,
我们之前的例子程序,其实应该是这样,才能正确工作.
otherwise the CPU would have just continued on after the STORE instruction, processing all those 0’s.
否则跑完 STORE_A 13 之后,\N CPU 会不停运行下去,处理后面的 0
But there is no instruction with an opcode of 0, and so the computer would have crashed!
因为 0 不是操作码,所以电脑会崩掉!
It’s important to point out here that we’re storing
我还想指出一点,指令和数据都是存在同一个内存里的.
both instructions and data in the same memory.
我还想指出一点,指令和数据都是存在同一个内存里的.
There is no difference fundamentally -- it’s all just binary numbers.
它们在根本层面上毫无区别 - 都是二进制数
So the HALT instruction is really important because it allows us to separate the two.
HALT 很重要,能区分指令和数据
Okay, so let’s make our program a bit more interesting, by adding a JUMP.
好,现在用 JUMP 让程序更有趣一些.
We’ll also modify our two starting values in memory to 1 and 1.
我们还把内存中 3 和 14 两个数字,改成 1 和 1
Lets step through this program just as our CPU would.
现在来从 CPU 的视角走一遍程序
First, LOAD_A 14 loads the value 1 into Register A.
首先 LOAD_A 14,把 1 存入寄存器A \N(因为地址 14 里的值是 1)
Next, LOAD_B 15 loads the value 1 into Register B.
然后 LOAD_B 15,把 1 存入寄存器B\N(因为地址 15 里的值也是 1)
As before, we ADD registers B and A together, with the sum going into Register A. 1+1 = 2,
然后 ADD B A 把寄存器 B 和 A 相加 \N 结果放到寄存器 A 里
so now Register A has the value 2 in it (stored in binary of course)
现在寄存器 A 的值是 2 \N (当然是以二进制存的)
Then the STORE instruction saves that into memory location 13.
然后 STORE_A 13 指令,把寄存器 A 的值存入内存地址 13
Now we hit a "JUMP 2" instruction.
现在遇到 JUMP 2 指令
This causes the processor to overwrite the value in the instruction address register,
CPU 会把"指令地址寄存器"的值,现在是 4,改成 2
which is currently 4, with the new value, 2.
CPU 会把"指令地址寄存器"的值,现在是 4,改成 2
Now, on the processor’s next fetch cycle, we don’t fetch HALT,
因此下一步不再是 HALT
instead we fetch the instruction at memory location 2, which is ADD B A.
而是读内存地址 2 里的指令,也就是 ADD B A
We’ve jumped!
我们跳转了!
Register A contains the value 2, and register B contains the value 1.
寄存器 A 里是 2,寄存器 B 里是 1
So 1+2 = 3, so now Register A has the value 3.
1+2=3,寄存器 A 变成 3
We store that into memory.
存入内存
And we’ve hit the JUMP again, back to ADD B A.
又碰到 JUMP 2,又回到 ADD B A.
1+3=4
1+3=4
So now register A has the value 4.
现在寄存器 A 是 4
See what's happening here?
发现了吗?
Every loop, we’re adding one.
每次循环都+1
Its counting up!
不断增多
Cooooool.
酷
But notice there’s no way to ever escape.
但没法结束啊
We’re never.. ever.. going to get to that halt instruction,
永远不会碰到 HALT
because we’re always going to hit that JUMP.
总是会碰到 JUMP
This is called an infinite loop – a program that runs forever… ever… ever… ever…
这叫无限循环 - 这个程序会永远跑下去.. 下去.. 下去.. 下去
ever
下去
To break the loop, we need a conditional jump.
为了停下来,我们需要有条件的 JUMP
A jump that only happens if a certain condition is met.
只有特定条件满足了,才执行 JUMP.
Our JUMP_NEGATIVE is one example of a conditional jump,
比如 JUMP NEGATIVE 就是条件跳转的一个例子
but computers have other types too - like JUMP IF EQUAL and JUMP IF GREATER.
还有其他类型的条件跳转,比如\N JUMP IF EQUAL(如果相等)\N JUMP IF GREATER(如果更大)
So let’s make our code a little fancier and step through it.
现在把代码弄花哨一点,再过一遍代码
Like before, the program starts by loading values from memory into registers A and B.
就像之前,程序先把内存值放入寄存器 A 和 B.
In this example, the number 11 gets loaded into Register A, and 5 gets loaded into Register B.
寄存器 A 是 11,寄存器 B 是 5
Now we subtract register B from register A. That’s 11 minus 5, which is 6,
SUB B A,用 A 减 B,11-5=6
and so 6 gets saved into Register A.
6 存入寄存器 A
Now we hit our JUMP NEGATIVE.
JUMP NEGATIVE 出场
The last ALU result was 6.
上一次 ALU 运算的结果是 6
That’s a positive number, so the the negative flag is false.
是正数,所以 "负数标志" 是假
That means the processor does not jump.
因此处理器不会执行 JUMP
So we continue on to the next instruction...
继续下一条指令
...which is a JUMP 2.
JUMP 2
No conditional on this one, so we jump to instruction 2 no matter what.
JUMP 2 没有条件,直接执行!
Ok, so we’re back at our SUBTRACT Register B from Register A. 6 minus 5 equals 1.
又回到寄存器 A-B,6-5=1
So 1 gets saved into register A.
A 变成 1
Next instruction.
下一条指令
We’re back again at our JUMP NEGATIVE.
又是 JUMP NEGATIVE
1 is also a positive number, so the CPU continues on to the JUMP 2, looping back around again
因为 1 还是正数,因此 JUMP NEGATIVE 不会执行 \N 来到下一条指令,JUMP 2
to the SUBTRACT instruction.
又来减一次
This time is different though.
这次就不一样了
1 minus 5 is negative 4.
1-5=-4
And so the ALU sets its negative flag to true for the first time.
这次ALU的 "负数标志" 是真
Now, when we advance to the next instruction,
现在下一条指令
JUMP_NEGATIVE 5, the CPU executes the jump to memory location 5.
JUMP NEGATIVE 5, CPU 的执行跳到内存地址 5
We’re out of the infinite loop!
跳出了无限循环!
Now we have a ADD B to A. Negative 4 plus 5, is positive 1, and we save that into Register A.
现在的指令是 ADD B A,-4+5=1,1 存入寄存器 A
Next we have a STORE instruction that saves Register A into memory address 13.
下一条指令 STORE_A 13,把 A 的值存入内存地址 13
Lastly, we hit our HALT instruction and the computer rests.
最后碰到 HALT 指令,停下来.
So even though this program is only 7 instructions long, the CPU ended up executing 13 instructions,
虽然程序只有 7 个指令,但 CPU 执行了 13 个指令,
and that's because it looped twice internally.
因为在内部循环了 2 次.
This code calculated the remainder if we divide 5 into 11, which is one.
这些代码其实是算余数的,11除5余1
With a few extra lines of code, we could also keep track of how many loops we did, the count
如果加多几行指令,我们还可以跟踪循环了多少次
of which would be how many times 5 went into 11… we did two loops, so that means 5 goes
11除5,循环2次
into 11 two times... with a remainder of 1.
余1
And of course this code could work for any two numbers, which we can just change in memory
当然,我们可以用任意2个数,7和81,18和54,什么都行
to whatever we want: 7 and 81, 18 and 54, it doesn’t matter
当然,我们可以用任意2个数,7和81,18和54,什么都行
-- that’s the power of software!
这就是软件的强大之处
Software also allowed us to do something our hardware could not.
软件还让我们做到硬件做不到的事
Remember, our ALU didn’t have the functionality to divide two numbers,
ALU 可没有除法功能
instead it’s the program we made that gave us that functionality.
是程序给了我们这个功能.
And then other programs can use our divide program to do even fancier things.
别的程序也可以用我们的除法程序,来做其他事情
And you know what that means.
这意味着 一层新抽象!
New levels of abstraction!
这意味着 一层新抽象!
So, our hypothetical CPU is very basic – all of its instructions are 8 bits long,
我们这里假设的 CPU 很基础,所有指令都是 8 位,
with the opcode occupying only the first four bits.
操作码只占了前面 4 位
So even if we used every combination of 4 bits, our CPU would only be able to support
即便用尽 4 位,也只能代表 16 个指令
a maximum of 16 different instructions.
即便用尽 4 位,也只能代表 16 个指令
On top of that, several of our instructions used the last 4 bits to specify a memory location.
而且我们有几条指令,是用后 4 位来指定内存地址
But again, 4 bits can only encode 16 different values,
因为 4 位最多只能表示 16 个值,
meaning we can address a maximum of 16 memory locations - that’s not a lot to work with.
所以我们只能操作 16 个地址,这可不多.
For example, we couldn’t even JUMP to location 17,
我们甚至不能 JUMP 17
because we literally can’t fit the number 17 into 4 bits.
因为 4 位二进制无法表示数字 17
For this reason, real, modern CPUs use two strategies.
因此,真正的现代 CPU 用两种策略
The most straightforward approach is just to have bigger instructions, with more bits,
最直接的方法是用更多位来代表指令,比如 32 位或 64 位
like 32 or 64 bits.
最直接的方法是用更多位来代表指令,比如 32 位或 64 位
This is called the instruction length.
这叫 指令长度
Unsurprisingly.
毫不意外
The second approach is to use variable length instructions.
第二个策略是 "可变指令长度"
For example, imagine a CPU that uses 8 bit opcodes.
举个例子,比如某个 CPU 用 8 位长度的操作码
When the CPU sees an instruction that needs no extra values, like the HALT instruction,
如果看到 HALT 指令,HALT 不需要额外数据
it can just execute it immediately.
那么会马上执行.
However, if it sees something like a JUMP instruction, it knows it must also fetch
如果看到 JUMP,它得知道位置值
the address to jump to, which is saved immediately behind the JUMP instruction in memory.
这个值在 JUMP 的后面
This is called, logically enough, an Immediate Value.
这叫 "立即值"
In such processor designs, instructions can be any number of bytes long,
这样设计,指令可以是任意长度
which makes the fetch cycle of the CPU a tad more complicated.
但会让读取阶段复杂一点点
Now, our example CPU and instruction set is hypothetical,
要说明的是,我们拿来举例的 CPU 和指令集都是假设的,
designed to illustrate key working principles.
是为了展示核心原理
So I want to leave you with a real CPU example.
所以我们来看个真的 CPU 例子.
In 1971, Intel released the 4004 processor.
1971年,英特尔发布了 4004 处理器.
It was the first CPU put all into a single chip
这是第一次把 CPU 做成一个芯片 \N 给后来的英特尔处理器打下了基础
and paved the path to the intel processors we know and love today.
这是第一次把 CPU 做成一个芯片 \N 给后来的英特尔处理器打下了基础
It supported 46 instructions, shown here.
它支持 46 个指令
Which was enough to build an entire working computer.
足够做一台能用的电脑
And it used many of the instructions we’ve talked about like JUMP ADD SUBTRACT and LOAD.
它用了很多我们说过的指令,比如 JUMP ADD SUB LOAD
It also uses 8-bit immediate values, like we just talked about, for things like JUMPs,
它也用 8 位的"立即值"来执行 JUMP, 以表示更多内存地址.
in order to address more memory.
它也用 8 位的"立即值"来执行 JUMP, 以表示更多内存地址.
And processors have come a long way since 1971.
处理器从 1971 年到现在发展巨大.
A modern computer processor, like an Intel Core i7, has thousands of different instructions
现代 CPU, 比如英特尔酷睿 i7, 有上千个指令和指令变种
and instruction variants, ranging from one to fifteen bytes long.
长度从1到15个字节.
For example, there’s over a dozens different opcodes just for variants of ADD!
举例,光 ADD 指令就有很多变种!
And this huge growth in instruction set size is due in large part to extra bells and whistles
指令越来越多,是因为给 CPU 设计了越来越多功能
that have been added to processor designs overtime, which we’ll talk about next episode.
下集我们会讲
See you next week!
下周见
================================================
FILE: (字幕)全40集中英字幕文本/09. 高级CPU设计-Advanced CPU Designs.ass.txt
================================================
Hi, I’m Carrie Anne and welcome to CrashCourse Computer Science!
(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
As we’ve discussed throughout the series, computers have come a long way from mechanical devices
随着本系列进展,我们知道计算机进步巨大
capable of maybe one calculation per second,
从 1 秒 1 次运算,到现在有千赫甚至兆赫的CPU
to CPUs running at kilohertz and megahertz speeds.
从 1 秒 1 次运算,到现在有千赫甚至兆赫的CPU
The device you’re watching this video on right now is almost certainly running at Gigahertz speeds
你现在看视频的设备八成也有 GHz 速度
- that’s billions of instructions executed every second.
1 秒十亿条指令
Which, trust me, is a lot of computation!
这是很大的计算量!
In the early days of electronic computing, processors were typically made faster by
早期计算机的提速方式是 减少晶体管的切换时间.
improving the switching time of the transistors inside the chip
早期计算机的提速方式是 减少晶体管的切换时间.
- the ones that make up all the logic gates, ALUs
晶体管组成了逻辑门,ALU 以及前几集的其他组件
and other stuff we’ve talked about over the past few episodes.
晶体管组成了逻辑门,ALU 以及前几集的其他组件
But just making transistors faster and more efficient only went so far, so processor designers
但这种提速方法最终会碰到瓶颈,所以处理器厂商
have developed various techniques to boost performance allowing not only simple instructions
发明各种新技术来提升性能,不但让简单指令运行更快
to run fast, but also performing much more sophisticated operations.
也让它能进行更复杂的运算
Last episode, we created a small program for our CPU that allowed us to divide two numbers.
上集我们写了个做除法的程序,给 CPU 执行
We did this by doing many subtractions in a row... so, for example, 16 divided by 4
方法是做一连串减法,比如16除4 会变成
could be broken down into the smaller problem of 16 minus 4, minus 4, minus 4, minus 4.
16-4 -4 -4 -4
When we hit zero, or a negative number, we knew that we we’re done.
碰到 0 或负数才停下.
But this approach gobbles up a lot of clock cycles, and isn’t particularly efficient.
但这种方法要多个时钟周期,很低效
So most computer processors today have divide as one of the instructions
所以现代 CPU 直接在硬件层面设计了除法 \N 可以直接给 ALU 除法指令
that the ALU can perform in hardware.
所以现代 CPU 直接在硬件层面设计了除法 \N 可以直接给 ALU 除法指令
Of course, this extra circuitry makes the ALU bigger and more complicated to design,
这让 ALU 更大也更复杂一些
but also more capable - a complexity-for-speed tradeoff that
但也更厉害 - \N 复杂度 vs 速度 的平衡在计算机发展史上经常出现
has been made many times in computing history.
但也更厉害 - \N 复杂度 vs 速度 的平衡在计算机发展史上经常出现
For instance, modern computer processors now have special circuits for things like
举例,现代处理器有专门电路来处理 \N 图形操作, 解码压缩视频, 加密文档 等等
graphics operations, decoding compressed video, and encrypting files
举例,现代处理器有专门电路来处理 \N 图形操作, 解码压缩视频, 加密文档 等等
all of which are operations that would take many many many clock cycles to perform with standard operations.
如果用标准操作来实现,要很多个时钟周期.
You may have even heard of processors with MMX, 3DNow!, or SSE.
你可能听过某些处理器有 MMX, 3DNOW, SSE
These are processors with additional, fancy circuits that allow them to
它们有额外电路做更复杂的操作
execute additional fancy instructions - for things like gaming and encryption.
用于游戏和加密等场景
These extensions to the instruction set have grown, and grown over time, and once people
指令不断增加,人们一旦习惯了它的便利就很难删掉
have written programs to take advantage of them, it’s hard to remove them.
指令不断增加,人们一旦习惯了它的便利就很难删掉
So instruction sets tend to keep getting larger and larger keeping all the old opcodes around for backwards compatibility.
所以为了兼容旧指令集,指令数量越来越多
The Intel 4004, the first truly integrated CPU, had 46 instructions
英特尔 4004,第一个集成CPU,有 46 条指令
- which was enough to build a fully functional computer.
足够做一台能用的计算机
But a modern computer processor has thousands of different instructions,
但现代处理器有上千条指令,有各种巧妙复杂的电路
which utilize all sorts of clever and complex internal circuitry.
但现代处理器有上千条指令,有各种巧妙复杂的电路
Now, high clock speeds and fancy instruction sets lead to another problem
超高的时钟速度带来另一个问题
- getting data in and out of the CPU quickly enough.
- 如何快速传递数据给 CPU
It’s like having a powerful steam locomotive, but no way to shovel in coal fast enough.
就像有强大的蒸汽机 但无法快速加煤
In this case, the bottleneck is RAM.
RAM 成了瓶颈
RAM is typically a memory module that lies outside the CPU.
RAM 是 CPU 之外的独立组件
This means that data has to be transmitted to and from RAM along sets of data wires,
意味着数据要用线来传递,叫"总线"
called a bus.
意味着数据要用线来传递,叫"总线"
This bus might only be a few centimeters long,
总线可能只有几厘米
and remember those electrical signals are traveling near the speed of light,
别忘了电信号的传输接近光速
but when you are operating at gigahertz speeds
但 CPU 每秒可以处理上亿条指令
– that’s billionths of a second – even this small delay starts to become problematic.
很小的延迟也会造成问题
It also takes time for RAM itself to lookup the address, retrieve the data
RAM 还需要时间找地址 \N 取数据,配置,输出数据
and configure itself for output.
RAM 还需要时间找地址 \N 取数据,配置,输出数据
So a “load from RAM” instruction might take dozens of clock cycles to complete, and during
一条"从内存读数据"的指令可能要多个时钟周期
this time the processor is just sitting there idly waiting for the data.
CPU 空等数据
One solution is to put a little piece of RAM right on the CPU -- called a cache.
解决延迟的方法之一是 \N 给 CPU 加一点 RAM - 叫"缓存"
There isn’t a lot of space on a processor’s chip,
因为处理器里空间不大,所以缓存一般只有 KB 或 MB
so most caches are just kilobytes or maybe megabytes in size,
因为处理器里空间不大,所以缓存一般只有 KB 或 MB
where RAM is usually gigabytes.
而 RAM 都是 GB 起步
Having a cache speeds things up in a clever way.
缓存提高了速度
When the CPU requests a memory location from RAM, the RAM can transmit
CPU 从 RAM 拿数据时 \N RAM 不用传一个,可以传一批
not just one single value, but a whole block of data.
CPU 从 RAM 拿数据时 \N RAM 不用传一个,可以传一批
This takes only a little bit more time,
虽然花的时间久一点,但数据可以存在缓存
but it allows this data block to be saved into the cache.
虽然花的时间久一点,但数据可以存在缓存
This tends to be really useful because computer data is often arranged and processed sequentially.
这很实用,因为数据常常是一个个按顺序处理
For example, let say the processor is totalling up daily sales for a restaurant.
举个例子,算餐厅的当日收入
It starts by fetching the first transaction from RAM at memory location 100.
先取 RAM 地址 100 的交易额
The RAM, instead of sending back just that one value, sends a block of data, from memory
RAM 与其只给1个值,直接给一批值
location 100 through 200, which are then all copied into the cache.
把地址100到200都复制到缓存
Now, when the processor requests the next transaction to add to its running total, the
当处理器要下一个交易额时
value at address 101, the cache will say “Oh, I’ve already got that value right here,
地址 101,缓存会说:"我已经有了,现在就给你"
so I can give it to you right away!”
地址 101,缓存会说:"我已经有了,现在就给你"
And there’s no need to go all the way to RAM.
不用去 RAM 取数据
Because the cache is so close to the processor,
因为缓存离 CPU 近, 一个时钟周期就能给数据 - CPU 不用空等!
it can typically provide the data in a single clock cycle -- no waiting required.
因为缓存离 CPU 近, 一个时钟周期就能给数据 - CPU 不用空等!
This speeds things up tremendously over having to go back and forth to RAM every single time.
比反复去 RAM 拿数据快得多
When data requested in RAM is already stored in the cache like this it’s called a
如果想要的数据已经在缓存,叫 缓存命中
cache hit,
如果想要的数据已经在缓存,叫 缓存命中
and if the data requested isn’t in the cache, so you have to go to RAM, it’s a called
如果想要的数据不在缓存,叫 缓存未命中
a cache miss.
如果想要的数据不在缓存,叫 缓存未命中
The cache can also be used like a scratch space,
缓存也可以当临时空间,存一些中间值,适合长/复杂的运算
storing intermediate values when performing a longer, or more complicated calculation.
缓存也可以当临时空间,存一些中间值,适合长/复杂的运算
Continuing our restaurant example, let’s say the processor has finished totalling up
继续餐馆的例子,假设 CPU 算完了一天的销售额
all of the sales for the day, and wants to store the result in memory address 150.
想把结果存到地址 150
Like before, instead of going back all the way to RAM to save that value,
就像之前,数据不是直接存到 RAM
it can be stored in cached copy, which is faster to save to,
而是存在缓存,这样不但存起来快一些
and also faster to access later if more calculations are needed.
如果还要接着算,取值也快一些
But this introduces an interesting problem -
但这样带来了一个有趣的问题
- the cache’s copy of the data is now different to the real version stored in RAM.
缓存和 RAM 不一致了.
This mismatch has to be recorded, so that at some point everything can get synced up.
这种不一致必须记录下来,之后要同步
For this purpose, the cache has a special flag for each block of memory it stores, called
因此缓存里每块空间 有一个特殊标记
the dirty bit
叫 "脏位"
-- which might just be the best term computer scientists have ever invented.
- 这可能是计算机科学家取的最贴切的名字
Most often this synchronization happens when the cache is full,
同步一般发生在 当缓存满了而 CPU 又要缓存时
but a new block of memory is being requested by the processor.
同步一般发生在 当缓存满了而 CPU 又要缓存时
Before the cache erases the old block to free up space, it checks its dirty bit,
在清理缓存腾出空间之前,会先检查 "脏位"
and if it’s dirty, the old block of data is written back to RAM before loading in the new block.
如果是"脏"的, 在加载新内容之前, 会把数据写回 RAM
Another trick to boost cpu performance is called instruction pipelining.
另一种提升性能的方法叫 "指令流水线"
Imagine you have to wash an entire hotel’s worth of sheets,
想象下你要洗一整个酒店的床单
but you’ve only got one washing machine and one dryer.
但只有 1 个洗衣机, 1 个干燥机
One option is to do it all sequentially: put a batch of sheets in the washer
选择1:按顺序来,放洗衣机等 30 分钟洗完
and wait 30 minutes for it to finish.
选择1:按顺序来,放洗衣机等 30 分钟洗完
Then take the wet sheets out and put them in the dryer and wait another 30 minutes for that to finish.
然后拿出湿床单,放进干燥机等 30 分钟烘干
This allows you to do one batch of sheets every hour.
这样1小时洗一批
Side note: if you have a dryer that can dry a load of laundry in 30 minutes,
另外一说:如果你有 30 分钟就能烘干的干燥机
Please tell me the brand and model in the comments, because I’m living with 90 minute dry times, minimum.
请留言告诉我是什么牌子,我的至少要 90 分钟.
But, even with this magic clothes dryer,
即使有这样的神奇干燥机, \N 我们可以用"并行处理"进一步提高效率
you can speed things up even more if you parallelize your operation.
即使有这样的神奇干燥机, \N 我们可以用"并行处理"进一步提高效率
As before, you start off putting one batch of sheets in the washer.
就像之前,先放一批床单到洗衣机
You wait 30 minutes for it to finish.
等 30 分钟洗完
Then you take the wet sheets out and put them in the dryer.
然后把湿床单放进干燥机
But this time, instead of just waiting 30 minutes for the dryer to finish,
但这次,与其干等 30 分钟烘干,\N 可以放另一批进洗衣机
you simultaneously start another load in the washing machine.
但这次,与其干等 30 分钟烘干,\N 可以放另一批进洗衣机
Now you’ve got both machines going at once.
让两台机器同时工作
Wait 30 minutes, and one batch is now done, one batch is half done,
30 分钟后,一批床单完成, 另一批完成一半
and another is ready to go in.
另一批准备开始
This effectively doubles your throughput.
效率x2!
Processor designs can apply the same idea.
处理器也可以这样设计
In episode 7, our example processor performed the fetch-decode-execute cycle sequentially
第7集,我们演示了 CPU 按序处理
and in a continuous loop: Fetch-decode-execute, fetch-decode-execute, fetch-decode-execute, and so on
取指 → 解码 → 执行, 不断重复
This meant our design required three clock cycles to execute one instruction.
这种设计,三个时钟周期执行 1 条指令
But each of these stages uses a different part of the CPU,
但因为每个阶段用的是 CPU 的不同部分
meaning there is an opportunity to parallelize!
意味着可以并行处理!
While one instruction is getting executed, the next instruction could be getting decoded,
"执行"一个指令时,同时"解码"下一个指令
and the instruction beyond that fetched from memory.
"读取"下下个指令
All of these separate processes can overlap
不同任务重叠进行,同时用上 CPU 里所有部分.
so that all parts of the CPU are active at any given time.
不同任务重叠进行,同时用上 CPU 里所有部分.
In this pipelined design, an instruction is executed every single clock cycle
这样的流水线 每个时钟周期执行1个指令
which triples the throughput.
吞吐量 x 3
But just like with caching this can lead to some tricky problems.
和缓存一样,这也会带来一些问题
A big hazard is a dependency in the instructions.
第一个问题是 指令之间的依赖关系
For example, you might fetch something that the currently executing instruction is just about to modify,
举个例子,你在读某个数据 \N 而正在执行的指令会改这个数据
which means you’ll end up with the old value in the pipeline.
也就是说拿的是旧数据
To compensate for this, pipelined processors have to look ahead for data dependencies,
因此流水线处理器 要先弄清数据依赖性
and if necessary, stall their pipelines to avoid problems.
必要时停止流水线,避免出问题
High end processors, like those found in laptops and smartphones,
高端 CPU,比如笔记本和手机里那种
go one step further and can dynamically reorder instructions with dependencies
会更进一步,动态排序 有依赖关系的指令
in order to minimize stalls and keep the pipeline moving,
最小化流水线的停工时间
which is called out-of-order execution.
这叫 "乱序执行"
As you might imagine, the circuits that figure this all out are incredibly complicated.
和你猜的一样,这种电路非常复杂
Nonetheless, pipelining is tremendously effective and almost all processors implement it today.
但因为非常高效,几乎所有现代处理器都有流水线
Another big hazard are conditional jump instructions -- we talked about one example, a JUMP NEGATIVE,last episode.
第二个问题是 "条件跳转",比如上集的 JUMP NEGATIVE
These instructions can change the execution flow of a program depending on a value.
这些指令会改变程序的执行流
A simple pipelined processor will perform a long stall when it sees a jump instruction,
简单的流水线处理器,看到 JUMP 指令会停一会儿 \N 等待条件值确定下来
waiting for the value to be finalized.
简单的流水线处理器,看到 JUMP 指令会停一会儿 \N 等待条件值确定下来
Only once the jump outcome is known, does the processor start refilling its pipeline.
一旦 JUMP 的结果出了,处理器就继续流水线
But, this can produce long delays, so high-end processors have some tricks to deal with this problem too.
因为空等会造成延迟,所以高端处理器会用一些技巧
Imagine an upcoming jump instruction as a fork in a road - a branch.
可以把 JUMP 想成是 "岔路口"
Advanced CPUs guess which way they are going to go, and start filling their pipeline with
高端 CPU 会猜哪条路的可能性大一些
instructions based off that guess – a technique called speculative execution.
然后提前把指令放进流水线,这叫 "推测执行"
When the jump instruction is finally resolved, if the CPU guessed correctly,
当 JUMP 的结果出了,如果 CPU 猜对了
then the pipeline is already full of the correct instructions and it can motor along without delay.
流水线已经塞满正确指令,可以马上运行
However, if the CPU guessed wrong, it has to discard all its speculative results and
如果 CPU 猜错了,就要清空流水线
perform a pipeline flush - sort of like when you miss a turn and have to do a u-turn to
就像走错路掉头
get back on route, and stop your GPS’s insistent shouting.
让 GPS 不要再!叫!了!
To minimize the effects of these flushes, CPU manufacturers have developed sophisticated
为了尽可能减少清空流水线的次数,CPU 厂商开发了复杂的方法
ways to guess which way branches will go, called branch prediction.
来猜测哪条分支更有可能,叫"分支预测"
Instead of being a 50/50 guess, today’s processors can often guess with over 90% accuracy!
现代 CPU 的正确率超过 90%
In an ideal case, pipelining lets you complete one instruction every single clock cycle,
理想情况下,流水线一个时钟周期完成 1 个指令
but then superscalar processors came along
然后"超标量处理器"出现了,一个时钟周期完成多个指令
which can execute more than one instruction per clock cycle.
然后"超标量处理器"出现了,一个时钟周期完成多个指令
During the execute phase even in a pipelined design,
即便有流水线设计,在指令执行阶段
whole areas of the processor might be totally idle.
处理器里有些区域还是可能会空闲
For example, while executing an instruction that fetches a value from memory,
比如,执行一个 "从内存取值" 指令期间
the ALU is just going to be sitting there, not doing a thing.
ALU 会闲置
So why not fetch-and-decode several instructions at once, and whenever possible, execute instructions
所以一次性处理多条指令(取指令+解码) 会更好.
that require different parts of the CPU all at the same time
如果多条指令要 ALU 的不同部分,就多条同时执行
But we can take this one step further and add duplicate circuitry
我们可以再进一步,加多几个相同的电路 \N 执行出现频次很高的指令
for popular instructions.
我们可以再进一步,加多几个相同的电路 \N 执行出现频次很高的指令
For example, many processors will have four, eight or more identical ALUs,
举例,很多 CPU 有四个, 八个甚至更多 完全相同的ALU
so they can execute many mathematical instructions all in parallel!
可以同时执行多个数学运算
Ok, the techniques we’ve discussed so far primarily optimize the execution throughput
好了,目前说过的方法,都是优化 1 个指令流的吞吐量
of a single stream of instructions,
好了,目前说过的方法,都是优化 1 个指令流的吞吐量
but another way to increase performance is to run several streams of instructions at once
另一个提升性能的方法是 同时运行多个指令流
with multi-core processors.
用多核处理器
You might have heard of dual core or quad core processors.
你应该听过双核或四核处理器
This means there are multiple independent processing units inside of a single CPU chip.
意思是一个 CPU 芯片里,有多个独立处理单元
In many ways, this is very much like having multiple separate CPUs,
很像是有多个独立 CPU
but because they’re tightly integrated, they can share some resources,
但因为它们整合紧密,可以共享一些资源
like cache, allowing the cores to work together on shared computations.
比如缓存,使得多核可以合作运算
But, when more cores just isn’t enough, you can build computers with multiple independent CPUs!
但多核不够时,可以用多个 CPU
High end computers, like the servers streaming this video from YouTube’s datacenter, often
高端计算机,比如现在给你传视频的 Youtube 服务器
need the extra horsepower to keep it silky smooth for the hundreds of people watching simultaneously.
需要更多马力,让上百人能同时流畅观看
Two- and four-processor configuration are the most common right now,
2个或4个CPU是最常见的
but every now and again even that much processing power isn’t enough.
但有时人们有更高的性能要求
So we humans get extra ambitious and build ourselves a supercomputer!
所以造了超级计算机!
If you’re looking to do some really monster calculations
如果要做怪兽级运算
– like simulating the formation of the universe - you’ll need some pretty serious compute power.
比如模拟宇宙形成,你需要强大的计算能力
A few extra processors in a desktop computer just isn’t going to cut it.
给普通台式机加几个 CPU 没什么用
You’re going to need a lot of processors.
你需要很多处理器!
No.. no... even more than that.
不…不…还要更多
A lot more!
更多
When this video was made, the world’s fastest computer was located in
截止至视频发布,世上最快的计算机在
The National Supercomputing Center in Wuxi, China.
中国无锡的国家超算中心
The Sunway TaihuLight contains a brain-melting 40,960 CPUs, each with 256 cores!
神威·太湖之光有 40960 个CPU,每个 CPU 有 256 个核心
Thats over ten million cores in total... and each one of those cores runs at 1.45 gigahertz.
总共超过1千万个核心,每个核心的频率是 1.45GHz
In total, this machine can process 93 Quadrillion -- that’s 93 million-billions
每秒可以进行 9.3 亿亿次浮点数运算
floating point math operations per second, knows as FLOPS.
也叫 每秒浮点运算次数 (FLOPS)
And trust me, that’s a lot of FLOPS!!
相信我 这个速度很可怕
No word on whether it can run Crysis at max settings, but I suspect it might.
没人试过跑最高画质的《孤岛危机》但我估计没问题
So long story short, not only have computer processors gotten a lot faster over the years,
长话短说,这些年处理器不但大大提高了速度
but also a lot more sophisticated, employing all sorts of clever tricks to squeeze out
而且也变得更复杂,用各种技巧
more and more computation per clock cycle.
榨干每个时钟周期 做尽可能多运算
Our job is to wield that incredible processing power to do cool and useful things.
我们的任务是利用这些运算能力,做又酷又实用的事
That’s the essence of programming, which we’ll start discussing next episode.
编程就是为了这个,我们下集说
See you next week.
下周见
================================================
FILE: (字幕)全40集中英字幕文本/10. 早期的编程方式-Early Programming.ass.txt
================================================
Hi, I'm Carrie Anne and welcome to Crash Course Computer Science.
(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
Over the last few episodes,
前几集我们把重点放在计算机的原理
We've talked a lot about the mechanics of how computers work.
前几集我们把重点放在计算机的原理
How they use complex circuits to save and retrieve values from memory,
怎么从内存读写数据,执行操作
and perform operations on those values
怎么从内存读写数据,执行操作
like adding two numbers together.
比如把两个数字加在一起
We've even briefly talked about sequences of operations,
还简单讲了下指令的执行,也就是计算机程序
which is a computer program
还简单讲了下指令的执行,也就是计算机程序
What we haven't talked about is how a program gets into a computer?
但我们还没讲的是:程序如何"进入"计算机
You might remember in episode 7 and 8 ,
你应该记得在第 7, 8 集,我们一步步讲了例子程序
we step through some simple example programs for the CPU that we had created
你应该记得在第 7, 8 集,我们一步步讲了例子程序
For simplicity, we just waved our hands and said that the program was already magically in memory
当时为了简单,我们假设程序已经魔法般在内存里了
But in reality, programs have to be loaded into a computer's memory.
但事实是,程序需要加载进内存
It's not magic. It's computer science
这不是魔法,是计算机科学!
The need to program machines existed way before the development of computers.
给机器编程这个需求,早在计算机出现之前就有了
The most famous example of this was in textile manufacturing
最著名的例子来自纺织业
If you just wanted to weave a big red tablecloth
如果你只想织一块红色大桌布
You could simply feed red thread into a loom and let it run
可以直接放红线进织布机
What about if you wanted the cloth to have a pattern like stripes or plaid?
但如果想要图案怎么办? 比如条纹或者方格
Workers would have to periodically reconfigure the loom as dictated by the pattern,
工人要每隔一会儿 调整一次织布机
but this was labor intensive which made patterned fabrics expensive.
因为非常消耗劳动力,所以图案纺织品很贵
The presence or absence of a hole in the card determined if a specific thread was held high or low in the loom
特定位置有没有穿孔,决定了线是高是低
Such as the cross thread, called the weft, passed above or below the thread
横线是从上/从下穿过
To vary the pattern across rows these punch cards were arranged in long chains
为了让每行图案不同,纸卡连成长条
Forming a sequence of commands for the loom.
形成连续指令
Sound familiar?
听起来很熟?
Many consider Jacquard loom to be one of the earliest forms of programming.
很多人认为雅卡尔织布机是最早的编程
Punched cards, turned out to be a cheap, reliable, fairly human-readable way to store data.
事实证明 穿孔纸卡便宜、可靠、也易懂
Nearly a century later,
近一个世纪后
punch cards were used to help tabulate the 1890 US census
穿孔纸卡用于 1890 年美国人口普查
which we talked about in episode 1
我们在第一集提过
Each card held an individual person's data.
一张卡存一个人的信息
things like race
比如种族
marital status
婚姻状况
number of children
子女数量
country of birth and so on
出生国家 等等
for each demographic question
针对每个问题,人口普查工作者会在对应位置打孔
a census worker would punch out a hole of the appropriate position
针对每个问题,人口普查工作者会在对应位置打孔
when a card was fed into the tabulating machine
当卡片插入汇总机
a hole would cause the running total for that specific answer to be increased by one
孔会让对应总和值+1
in this way you could afeed the entire counties worth of people
可以插入整个国家人口的卡片
and at the end you'd have running totals for all of the questions that you ask
在结束后得到各个总值
It is important to note here that early tabulating machines were not truly computers
值得注意的是,早期汇总机不算计算机
as they can only do one thing-tabulate
因为它们只做一件事 - 汇总数据
their operation was fixed and not programmable
操作是固定的,不能编程
punched cards stored data, but not a program
穿孔纸卡存的是数据,不是程序.
over the next 60 years, these business machines grew in capability
之后60年,这些机器被加强,可以做减、乘、除
Adding features to subtract multiply divide
之后60年,这些机器被加强,可以做减、乘、除
and even make simple decisions about when to perform certain operations.
甚至可以做一些小决定,决定何时执行某指令
To trigger these functions appropriately
为了正确执行不同计算,程序员需要某种控制面板
so that different calculations could be performed, a programmer accessed a control panel
为了正确执行不同计算,程序员需要某种控制面板
this panel was full of little sockets into which a programmer would plug cables
面板有很多小插孔,程序员可以插电线
to pass values and signals between different parts of the machine
让机器的不同部分 互相传数据和信号
for this reason they were also called plug boards
因此也叫 "插线板"
Unfortunately this meant having to rewire the machine each time a different program needed to be run
不幸的是, 这意味着 运行不同程序要重新接线
And so by the 1920s these plug boards were made swappable
所以到 1920 年代,控制面板变成了可拔插
This not only made programming a lot more comfortable
让编程更方便
but also allowed for different programs be plugged into a machine
可以给机器插入不同程序
For example one board might be wired to calculate sales tax
比如,一个插线板算销售税,另一个算工资单
While another helps with payroll
比如,一个插线板算销售税,另一个算工资单
But plug boards were fiendishly complicated to program
但给插线板编程很复杂
This tangle of wires is a program for calculating a profit loss summary using an IBM 402 accounting machine
图中乱成一团的线 负责算盈亏总额 \N 用于 IBM 402 核算机
which were popular in the 1940s
在 1940 年代这样做很流行
And this style of plug board programming wasn't unique through electromechanical computers
用插线板编程 不只在机电计算机流行
The world's first general-purpose electronic computer, the ENIAC, completed in 1946
世上第一台通用电子计算机,ENIAC,完成于 1946 年
used a ton of them
用了一大堆插线板
Even after a program had been completely figured out on paper
程序在纸上设计好之后
Physically wiring up the ENIAC and getting the program to run could take upwards of three weeks
给 ENIAC 连线,最多可能花三个星期
Given the enormous cost of these early computers, weeks of downtime simply to switch programs was unacceptable
因为早期计算机非常昂贵 \N 停机几个星期只为换程序 完全无法接受
and the new faster more flexible way to program machines was badly needed
人们急需更快、更灵活的新方式来编程
Fortunately by the late 1940s and into the 50s
幸运的是,到 1940 年代晚期 1950 年代初
electronic memory was becoming feasible
内存变得可行
As costs fell, memory size grew, instead of storing a program as a physical plug board of wires
价格下降, 容量上升. 与其把程序存在插线板
it became possible to store a program entirely in a computer's memory
存在内存变得可行
where it could be easily changed by programmers and quickly accessed by the CPU
这样程序易于修改、方便 CPU 快速读取
these machines were called Stored-program Computers
这类机器叫 "存储程序计算机"
With enough computer memory you could store not only the program you wanted to run
如果内存足够,不仅可以存要运行的程序
but also any data your program would need
还可以存程序需要的数据
including new values it created along the way
包括程序运行时产生的新数据
Unifying the program and data into a single shared memory is called the Von Neumann Architecture
程序和数据都存在一个地方,叫 "冯诺依曼结构"
named after John Von Neumann
命名自 约翰·冯·诺依曼
a prominent mathematician and physicist who worked on the Manhattan project and several early electronic computers
杰出的数学家和物理学家 \N 参与了曼哈顿计划和早期电子计算机项目
and once said I am thinking about something much more important than Bombs
他曾说:我在思考比炸弹重要得多的东西
I'm thinking about computers
计算机
The hallmarks of a Von Neumann computer are a processing unit containing an arithmetic logic unit
冯诺依曼计算机的标志是,一个处理器(有算术逻辑单元)+
data registers and instruction register and instruction address register
数据寄存器+指令寄存器+指令地址寄存器
And finally a memory to store both data and instructions
+内存(负责存数据和指令)
Hopefully this sounds familiar
希望这听起来很耳熟
Because we actually built a Von Neumann computer in episode 7
因为第7集我们造了一个冯诺依曼计算机
The very first Von Neumann Architecture Stored-program computer
第一台冯诺依曼架构的"储存程序计算机"
was constructed in 1948 by the University of Manchester, nicknamed Baby.
由曼彻斯特大学于 1948 年建造完成,绰号"宝宝"
and even the computer you are watching this video right now
甚至你现在看视频的计算机,也在用一样的架构
uses the same architecture
甚至你现在看视频的计算机,也在用一样的架构
Now electronic computer memory is great and all
虽然有内存很棒
but you still have to load the program and data into the computer before it can run
但程序和数据 依然需要某种方式输入计算机
and for this reason punch cards were used
所以用穿孔纸卡
Let's get to the Thought bubbles
让我们进入 思维泡泡
Well into the 1980s almost all computers have a punch card reader
到1980年代,几乎所有的计算机都有穿孔纸卡读取器
which could suck in a single punch card at a time
可以吸入一张卡片,把卡片内容写进内存
and write the contents of the card into the computer's memory
可以吸入一张卡片,把卡片内容写进内存
If you load it in a stack of punch cards,
如果放了一叠卡片,读取器会一个个写进内存
the reader would load them all into memory sequentially as a big block
如果放了一叠卡片,读取器会一个个写进内存
once the program and data were in memory, the computer would be told to execute it
一旦程序和数据写入完毕,电脑会开始执行
Of course even simple computer programs might have hundreds of instructions
即便简单程序也有几百条指令,要用一叠纸卡来存
which meant that programs were stored as stacks of punch cards
即便简单程序也有几百条指令,要用一叠纸卡来存
So if you ever have the misfortune of accidentally dropping your program on the floor
如果不小心摔倒弄撒了
it could take you hours days or even weeks to put the code back in the right order
要花上几小时、几天、甚至几周来整理
A common trick was to draw a diagonal line on the side of the card stack called striping,
有个小技巧是 在卡片侧面画对角线
so you'd have at least some clue how to get it back into the right order
如果弄散了,整理起来会方便很多
The largest program ever punched into punch cards was the US Air Force's SAGE air defense system, completed in 1955.
用纸卡的最大型程序 \N 是美国空军的 SAGE 防空系统,于 1955 年完成
and its peak, the project is said to have employed 20% of the world's programmers
据称顶峰时期 雇佣了世上 20% 程序员
Its main control program was stored on a whopping 62,500 punch cards
主控制程序用了 62500 张穿孔纸卡
which is equivalent to roughly 5 megabytes of data
等同于大约 5MB 的数据
Pretty underwhelming by today's standards
以如今的标准,不值一提
And punch cards weren't only useful for getting data into computers
穿孔纸卡不仅可以往计算机放数据
but also getting data out of them
还可以取出数据
At the end of a program results could be written out of computer memory and onto punch cards by, well, punching cards
程序运行到最后,结果可以输到纸卡上,方式嘛,当然是打孔
then this data could be analyzed by humans or loaded into a second program for additional computation
然后人可以分析结果,或者再次放进计算机,做进一步计算
Thanks, thought-bubble
谢了 思维泡泡
A close cousin to punch cards was punched paper tape
穿孔纸卡 的亲戚是纸带
Which is basically the same idea, but continuous instead of being on individual cards
基本是一回事,只不过更连续,不是一张张卡.
And of course we haven't talked about Hard Drives, CD-ROMs, DVDs, USB-Thumb drives and other similar goodies
当然我们还没提硬盘, 只读光盘, DVD, U盘等等
We'll get to those more advanced types of data storage in a future episode
以后我们会讲这些更先进的存储方法
Finally in addition to plug boards and punch paper
最后,除了插线板和穿孔纸卡
there was another common way to program and control computers in pre-1980
在 1980 年代前,还有一种常见编程方式
Panel programming
面板编程
Rather than having to physically plug in cables to activate certain functions
与其插一堆线到插线板
this could also be done with huge panels full of switches and buttons
可以用一大堆开关和按钮,做到一样的效果
And there were indicator lights to display the status of various functions and values in memory
面板上有指示灯,代表各种函数的状态和内存中的值
Computers of the 50s and 60s often featured huge control consoles that look like this
50和60年代的计算机,一般都有这样巨大的控制台
Although it was rare to input a whole program using just switches,it was possible
很少有人只用开关来输入一整个程序,但技术上是可行的
And early home computers made for the hobbyist market use switches extensively
早期针对计算机爱好者的家用计算机,大量使用了开关
because most home users couldn't afford expensive peripherals like punch card readers
因为大多数家庭用户负担不起昂贵的外围设备 \N 比如穿孔纸卡读取器
The first commercially successful home computer was the Altair 8800
第一款取得商业成功的家用计算机是 Altair 8800
which sold in two versions: Pre-assembled and the Kit
有两种版本可以买: \N 1. 预先装好的整机 \N 2. 需要组装的组件
the Kit which was popular with amateur computing enthusiasts,
计算机爱好者 喜欢买组件版
sold for the then unprecedented low price are around $400 in 1975
售价极低,在 1975 年卖 400 美元左右
Or about $2,000 in 2017
相当于 2017 年的 2000 美元
To program the 8800, you'd literally toggle the switches on the front panel
为了给 8800 编程,你要拨动面板上的开关
to enter the binary op-codes for the instruction you wanted
输入二进制操作码
Then you press the deposit button to write that value into memory
然后按 "存储键" 把值存入内存
Then in the next location in memory you toggle the switches again
然后会到下一个内存位置 \N 你可以再次拨开关,写下一个指令
for your next instruction deposit it and so on
重复这样做
When you finally entered your whole program into memory
把整个程序都写入内存之后
you would toggle the switches moves back to memory address 0
可以推动开关,回到内存地址0
press the run button and watch the little lights blink
然后按运行按钮,灯会闪烁
That was home computing in 1975, Wow.
这就是 1975 年的家用计算机, 哇.
Whether it was plug board, switches or punched paper
不管是插线板、开关或穿孔纸卡
Programming these early computers was the realm of experts
早期编程都是专家活
either professionals who did this for living or technology enthusiasts
不管是全职还是技术控,都要非常了解底层硬件
you needed intimate knowledge of the underlying hardware,
不管是全职还是技术控,都要非常了解底层硬件
so things like processor op-codes and register wits, to write programs
比如 操作码, 寄存器等, 才能写程序
This meant programming was hard and tedious and even professional engineers
所以编程很难,很烦
and scientists struggled to take full advantage of what computing could offer
哪怕工程师和科学家都无法 完全发挥计算机的能力
What was needed was a simpler way to tell computers what to do,
我们需要一种更简单方式 告诉计算机要做什么
a simpler way to write programs
一种更简单的编程方式
And that brings us to programming languages, which we'll talk about next episode
这带领我们到下一个话题 - 编程语言, 我们下集会讲
See you next week
下周见
================================================
FILE: (字幕)全40集中英字幕文本/11. 编程语言发展史-The First Programming Languages.ass.txt
================================================
This episode is brought to you by CuriosityStream.
本集由 CuriosityStream 赞助播出
Hi, I'm Carrie Anne and welcome to Crash Course Computer Science!
(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
So far, for most of this series, we've focused on hardware
之前我们把重点放在硬件 - 组成计算机的物理组件
-- the physical components of computing --
之前我们把重点放在硬件 - 组成计算机的物理组件
things like: electricity and circuits, registers and RAM, ALUs and CPUs.
比如电,电路,寄存器,RAM,ALU,CPU
But programming at the hardware level is cumbersome and inflexible,
但在硬件层面编程非常麻烦
so programmers wanted a more versatile way to program computers
所以程序员想要一种更通用的方法编程
- what you might call a "softer" medium.
- 一种"更软的"媒介
That's right, we're going to talk about Software!
没错,我们要讲软件!
In episode 8, we walked through a simple program for the CPU we designed.
第 8 集我们一步步讲了一个简单程序
The very first instruction to be executed, the one at memory address 0, was 0010 1110.
第一条指令在内存地址 0:0010 1110
As we discussed, the first four bits of an instruction is the operation code,
之前说过,前 4 位是操作码
or OPCODE for short.
简称 OPCODE
On our hypothetical CPU, 0010 indicated a LOAD_A instruction
对于这个假设 CPU,0010 代表 LOAD_A 指令
-- which moves a value from memory into Register A.
- 把值从内存复制到寄存器 A
The second set of four bits defines the memory location,
后 4 位是内存地址,1110 是十进制的 14
in this case, 1110, which is 14 in decimal.
后 4 位是内存地址,1110 是十进制的 14
So what these eight numbers really mean is "LOAD Address 14 into Register A".
所以这 8 位表达的意思是 \N "读内存地址 14,放入寄存器 A"
We're just using two different languages.
只是用了两种不同语言
You can think of it like English and Morse Code.
可以想成是英语和摩尔斯码的区别
"Hello" and ".... . .-.. .-.. ---" mean the same thing -- hello! --
"你好" 和 ".... . .-.. .-.. ---" 是一个意思:你好
they're just encoded differently.
只是编码方式不同
English and Morse Code also have different levels of complexity.
英语和摩尔斯码的复杂度也不同
English has 26 different letters in its alphabet and way more possible sounds.
英文有 26 个字母以及各种发音
Morse only has dots and dashes.
摩尔斯码只有"点"和"线"
But, they can convey the same information, and computer languages are similar.
但它们可以传达相同的信息,计算机语言也类似.
As we've seen, computer hardware can only handle raw, binary instructions.
计算机能处理二进制,二进制是处理器的"母语"
This is the "language" computer processors natively speak.
计算机能处理二进制,二进制是处理器的"母语"
In fact, it's the only language they're able to speak.
事实上,它们*只能*理解二进制
It's called Machine Language or Machine Code.
这叫"机器语言"或"机器码"
In the early days of computing, people had to write entire programs in machine code.
在计算机早期阶段,必须用机器码写程序
More specifically, they'd first write a high-level version of a program on paper, in English,
具体来讲,会先在纸上用英语写一个"高层次版"
For example "retrieve the next sale from memory,
举例:"从内存取下一个销售额,
then add this to the running total for the day, week and year,
然后加到天、周、年的总和
then calculate any tax to be added"
然后算税"
...and so on.
等等...
An informal, high-level description of a program like this is called Pseudo-Code.
这种对程序的高层次描述,叫 "伪代码"
Then, when the program was all figured out on paper,
在纸上写好后
they'd painstakingly expand and translate it into binary machine code by hand,
用"操作码表"把伪代码转成二进制机器码
using things like opcode tables.
用"操作码表"把伪代码转成二进制机器码
After the translation was complete, the program could be fed into the computer and run.
翻译完成后,程序可以喂入计算机并运行
As you might imagine, people quickly got fed up with this process.
你可能猜到了,很快人们就厌烦了
So, by the late 1940s and into the 50s,
所以在 1940~1950 年代
programmers had developed slightly higher-level languages that were more human-readable.
程序员开发出一种新语言, 更可读 更高层次
Opcodes were given simple names, called mnemonics,
每个操作码分配一个简单名字,叫"助记符"
which were followed by operands, to form instructions.
"助记符"后面紧跟数据,形成完整指令
So instead of having to write instructions as a bunch of 1's and 0's,
与其用 1 和 0 写代码,程序员可以写"LOAD_A 14"
programmers could write something like "LOAD_A 14".
与其用 1 和 0 写代码,程序员可以写"LOAD_A 14"
We used this mnemonic in Episode 8 because it's so much easier to understand!
我们在第 8 集用过这个助记符,因为容易理解得多!
Of course, a CPU has no idea what "LOAD_A 14" is.
当然,CPU 不知道 LOAD_A 14 是什么
It doesn't understand text-based language, only binary.
它不能理解文字,只能理解二进制
And so programmers came up with a clever trick.
所以程序员想了一个技巧,写二进制程序来帮忙
They created reusable helper programs, in binary,
所以程序员想了一个技巧,写二进制程序来帮忙
that read in text-based instructions,
它可以读懂文字指令,自动转成二进制指令
and assemble them into the corresponding binary instructions automatically.
它可以读懂文字指令,自动转成二进制指令
This program is called
这种程序叫
-- you guessed it --
你可能猜到了
an Assembler.
汇编器
It reads in a program written in an Assembly Language
汇编器读取用"汇编语言"写的程序,然后转成"机器码"
and converts it to native machine code.
汇编器读取用"汇编语言"写的程序,然后转成"机器码"
"LOAD_A 14" is one example of an assembly instruction.
"LOAD_A 14" 是一个汇编指令的例子
Over time, Assemblers gained new features that made programming even easier.
随着时间推移,汇编器有越来越多功能,让编程更容易
One nifty feature is automatically figuring out JUMP addresses.
其中一个功能是自动分析 JUMP 地址
This was an example program I used in episode 8:
这里有一个第8集用过的例子:
Notice how our JUMP NEGATIVE instruction jumps to address 5,
注意, JUMP NEGATIVE 指令跳到地址 5
and our regular JUMP goes to address 2.
JUMP 指令跳到地址 2
The problem is, if we add more code to the beginning of this program,
问题是,如果在程序开头多加一些代码
all of the addresses would change.
所有地址都会变
That's a huge pain if you ever want to update your program!
更新程序会很痛苦!
And so an assembler does away with raw jump addresses,
所以汇编器不用固定跳转地址
and lets you insert little labels that can be jumped to.
而是让你插入可跳转的标签
When this program is passed into the assembler,
当程序被传入汇编器,汇编器会自己搞定跳转地址
it does the work of figuring out all of the jump addresses.
当程序被传入汇编器,汇编器会自己搞定跳转地址
Now the programmer can focus more on programming
程序员可以专心编程,不用管底层细节
and less on the underlying mechanics under the hood
程序员可以专心编程,不用管底层细节
enabling more sophisticated things to be built by hiding unnecessary complexity.
隐藏不必要细节来做更复杂的工作
As we've done many times in this series,
我们又提升了一层抽象
we're once again moving up another level of abstraction.
我们又提升了一层抽象
However, even with nifty assembler features like auto-linking JUMPs to labels,
然而,即使汇编器有这些厉害功能,比如自动跳转
Assembly Languages are still a thin veneer over machine code.
汇编只是修饰了一下机器码
In general, each assembly language instruction converts directly
一般来说,一条汇编指令对应一条机器指令
to a corresponding machine instruction - a one-to-one mapping -
一般来说,一条汇编指令对应一条机器指令
so it's inherently tied to the underlying hardware.
所以汇编码和底层硬件的连接很紧密
And the assembler still forces programmers to think about
汇编器仍然强迫程序员思考 用什么寄存器和内存地址
which registers and memory locations they will use.
汇编器仍然强迫程序员思考 用什么寄存器和内存地址
If you suddenly needed an extra value,
如果你突然要一个额外的数,可能要改很多代码
you might have to change a lot of code to fit it in.
如果你突然要一个额外的数,可能要改很多代码
Let's go to the Thought Bubble.
让我们进入思考泡泡
This problem did not escape Dr. Grace Hopper.
葛丽丝·霍普博士 也遇到了这个问题
As a US naval officer, she was one of the first programmers on the Harvard Mark 1 computer,
作为美国海军军官,她是哈佛1号计算机的首批程序员之一
which we talked about in Episode 2.
这台机器我们在第 2 集提过
This was a colossal, electro-mechanical beast
这台巨大机电野兽在 1944 年战时建造完成,帮助盟军作战
completed in 1944 as part of the allied war effort.
这台巨大机电野兽在 1944 年战时建造完成,帮助盟军作战
Programs were stored and fed into the computer on punched paper tape.
程序写在打孔纸带上,放进计算机执行
By the way, as you can see,
顺便一说,如果程序里有漏洞
they "patched" some bugs in this program
顺便一说,如果程序里有漏洞
by literally putting patches of paper over the holes on the punch tape.
真的就 直接用胶带来补"漏洞"
The Mark 1's instruction set was so primitive,
Mark 1 的指令集非常原始,甚至没有 JUMP 指令
there weren't even JUMP instructions.
Mark 1 的指令集非常原始,甚至没有 JUMP 指令
To create code that repeated the same operation multiple times,
如果代码要跑不止一次
you'd tape the two ends of the punched tape together, creating a physical loop.
得把带子的两端连起来 做成循环
In other words, programming the Mark 1 was kind of a nightmare!
换句话说,给 Mark 1 编程简直是噩梦!
After the war, Hopper continued to work at the forefront of computing.
战后,霍普继续在计算机前沿工作
To unleash the potential of computers,
为了释放电脑的潜力
she designed a high-level programming language called "Arithmetic Language Version 0",
她设计了一个高级编程语言,叫"算术语言版本 0"
or A-0 for short.
简称"A-0"
Assembly languages have direct, one-to-one mapping to machine instructions.
汇编与机器指令是一一对应的
But, a single line of a high-level programming language
但一行高级编程语言 可能会转成几十条二进制指令
might result in dozens of instructions being executed by the CPU.
但一行高级编程语言 可能会转成几十条二进制指令
To perform this complex translation, Hopper built the first compiler in 1952.
为了做到这种复杂转换 \N Hopper 在 1952 年创造了第一个编译器
This is a specialized program
编译器专门把高级语言 转成低级语言
that transforms "source" code written in a programming language into a low-level language,
编译器专门把高级语言 转成低级语言
like assembly or the binary "machine code" that the CPU can directly process.
比如汇编或机器码(CPU 可以直接执行机器码)
Thanks, Thought Bubble.
谢了 思想泡泡
So, despite the promise of easier programming,
尽管"使编程更简单"很诱人
many people were skeptical of Hopper's idea.
但很多人对霍普的点子持怀疑态度
She once said, "I had a running compiler and nobody would touch it.
她曾说"我有能用的编译器,但没人愿意用
they carefully told me, computers could only do arithmetic;
他们告诉我计算机只能做算术,不能运行程序"
they could not do programs."
他们告诉我计算机只能做算术,不能运行程序"
But the idea was a good one,
但这个点子是好的
and soon many efforts were underway to craft new programming languages
不久,很多人尝试创造新编程语言
-- today there are hundreds!
- 如今有上百种语言!
Sadly, there are no surviving examples of A-0 code,
可惜的是,没有任何 A-0 的代码遗留下来
so we'll use Python, a modern programming language, as an example.
所以我们用 Python 举例(一门现代编程语言)
Let's say we want to add two numbers and save that value.
假设我们想相加两个数字,保存结果
Remember, in assembly code,
记住,如果用汇编代码
we had to fetch values from memory, deal with registers, and other low-level details.
我们得从内存取值,和寄存器打交道,以及其他底层细节
But this same program can be written in python like so:
但同样的程序可以用 Python 这样写:
Notice how there are no registers or memory locations to deal with
不用管寄存器或内存位置
-- the compiler takes care of that stuff, abstracting away a lot of low-level and unnecessary complexity.
- 编译器会搞定这些细节,不用管底层细节
The programmer just creates abstractions for needed memory locations, known as variables,
程序员只需要创建 代表内存地址的抽象,叫"变量"
and gives them names.
给变量取名字
So now we can just take our two numbers, store them in variables we give names to
现在可以把两个数 存在变量里
-- in this case, I picked a and b but those variables could be anything -
这里取名 A 和 B, 实际编程时你可以随便取名
and then add those together, saving the result in c, another variable I created.
然后相加两个数,把结果存在变量 C
It might be that the compiler assigns Register A under the hood to store the value in a,
底层操作时,编译器可能把变量 A 存在寄存器 A
but I don't need to know about it!
但我不需要知道这些!
Out of sight, out of mind!
眼不见心不烦
It was an important historical milestone,
这是个重要历史里程碑
but A-0 and its later variants weren't widely used.
但 A-0 和之后的版本没有广泛使用
FORTRAN, derived from "Formula Translation",
FORTRAN,名字来自 "公式翻译"
was released by IBM a few years later, in 1957,
这门语言数年后由 IBM 在 1957 年发布
and came to dominate early computer programming.
主宰了早期计算机编程
John Backus, the FORTRAN project director,
FORTRAN 项目总监 John Backus 说过
said: "Much of my work has come from being lazy.
"我做的大部分工作都是因为懒
I didn't like writing programs,
我不喜欢写程序
and so ... I started work on a programming system to make it easier to write programs."
所以我写这门语言,让编程更容易"
You know, typical lazy person.
你懂的,典型的"懒人"
They're always creating their own programming systems.
(白眼)创造自己的编程语言
Anyway, on average, programs written in FORTRAN
平均来说,FORTRAN 写的程序
were 20 times shorter than equivalent handwritten assembly code.
比等同的手写汇编代码短 20 倍
Then the FORTRAN Compiler would translate and expand that into native machine code.
然后 FORTRAN 编译器会把代码转成机器码
The community was skeptical that the performance would be as good as hand written code,
人们怀疑性能是否比得上手写代码
but the fact that programmers could write more code more quickly,
但因为能让程序员写程序更快,所以成了一个更经济的选择
made it an easy choice economically:
但因为能让程序员写程序更快,所以成了一个更经济的选择
trading a small increase in computation time for a significant decrease in programmer time.
运行速度慢一点点,编程速度大大加快
Of course, IBM was in the business of selling computers,
当时 IBM 在卖计算机
and so initially, FORTRAN code could only be compiled and run on IBM computers.
因此最初 FORTRAN 代码只能跑在 IBM 计算机上
And most programing languages and compilers of the 1950s
1950 年代大多数编程语言和编译器
could only run on a single type of computer.
只能运行在一种计算机上
So, if you upgraded your computer,
如果升级电脑
you'd often have to re-write all the code too!
可能要重写所有代码!
In response, computer experts from industry,
因此工业界,学术界,政府的计算机专家 \N 在 1959 年组建了一个联盟
academia and government formed a consortium in 1959
因此工业界,学术界,政府的计算机专家 \N 在 1959 年组建了一个联盟
-- the Committee on Data Systems Languages, advised by our friend Grace Hopper --
- 数据系统语言委员会,Grace Hopper 担任顾问
to guide the development of a common programming language
开发一种通用编程语言,可以在不同机器上通用
that could be used across different machines.
开发一种通用编程语言,可以在不同机器上通用
The result was the high-level, easy to use,
最后诞生了一门高级,易于使用,
Common Business-Oriented Language, or COBOL for short.
"普通面向商业语言",简称 COBOL
To deal with different underlying hardware,
为了兼容不同底层硬件
each computing architecture needed its own COBOL compiler.
每个计算架构需要一个 COBOL 编译器
But critically, these compilers could all accept the same COBOL source code,
最重要的是,这些编译器都可以接收相同 COBOL 代码
no matter what computer it was run on.
不管是什么电脑
This notion is called write once, run anywhere.
这叫"一次编写,到处运行"
It's true of most programming languages today,
如今大多数编程语言都是这样
a benefit of moving away from assembly and machine code,
不必接触 CPU 特有的汇编码和机器码
which is still CPU specific.
不必接触 CPU 特有的汇编码和机器码
The biggest impact of all this was reducing computing's barrier to entry.
减小了使用门槛
Before high level programming languages existed,
在高级编程语言出现之前
it was a realm exclusive to computer experts and enthusiasts.
编程只是计算机专家和爱好者才会做的事
And it was often their full time profession.
而且通常是主职
But now, scientists, engineers, doctors, economists, teachers,
但现在,科学家,工程师,医生,经济学家,教师
and many others could incorporate computation into their work .
等等,都可以把计算机用于工作
Thanks to these languages,
感谢这些语言
computing went from a cumbersome and esoteric discipline
计算机科学从深奥学科 变成了大众化工具
to a general purpose and accessible tool.
计算机科学从深奥学科 变成了大众化工具
At the same time, abstraction in programming allowed those computer experts
同时,编程的抽象也让计算机专家
- now "professional programmers" -
现在叫"专业程序员"
to create increasingly sophisticated programs,
制作更复杂的程序
which would have taken millions, tens of millions, or even more lines of assembly code.
如果用汇编写可能要上百万行
Now, this history didn't end in 1959.
当然,计算机的历史没有在 1959 年结束
In fact, a golden era in programming language design jump started,
编程语言设计的黄金时代才刚刚开始
evolving in lockstep with dramatic advances in computer hardware.
和硬件一起飞速发展
In the 1960s, we had languages like ALGOL, LISP and BASIC.
在 1960 年代,有 ALGOL, LISP 和 BASIC 等语言
In the 70's: Pascal, C and Smalltalk were released.
70年代有:Pascal,C 和 Smalltalk
The 80s gave us C++, Objective-C, and Perl.
80年代有:C++,Objective-C 和 Perl
And the 90's: python, ruby, and Java.
90年代有:Python,Ruby 和 Java
And the new millennium has seen the rise of Swift, C#, and Go
新千年 Swift, C#, Go 在崛起
- not to be confused with Let it Go and Pokemon Go.
不要把 Go 和\N 《冰雪奇缘》的 Let it Go 和游戏 Pokemon Go 弄混
Anyway, some of these might sound familiar
有些语言你可能听起来耳熟 - 很多现在还存在
-- many are still around today.
有些语言你可能听起来耳熟 - 很多现在还存在
It's extremely likely that the web browser you're using right now
你现在用的浏览器很可能是 C++ 或 Objective-C 写的
was written in C++ or Objective-C.
你现在用的浏览器很可能是 C++ 或 Objective-C 写的
That list I just gave is the tip of the iceberg.
我刚才说的编程语言名字 只是冰山一角
And languages with fancy, new features are proposed all the time.
新的编程语言在不断诞生
Each new language attempts to leverage new and clever abstractions
新语言想用更聪明的抽象
to make some aspect of programming easier or more powerful,
让某些方面更容易或更强大
or take advantage of emerging technologies and platforms,
或利用新技术和新平台带来的优势
so that more people can do more amazing things, more quickly.
让更多人能快速做出美妙的事情
Many consider the holy grail of programming to be the use of "plain ol' English",
许多人认为编程的"圣杯"是直接用英文
where you can literally just speak what you want the computer to do,
直接对计算机说话,然后它会理解并执行
it figures it out, and executes it.
直接对计算机说话,然后它会理解并执行
This kind of intelligent system is science fiction for now.
这种智能系统目前只存在于科幻小说
And fans of 2001: A Space Odyssey may be okay with that.
"2001:太空漫游" 的粉丝可能没什么意见
Now that you know all about programming languages,
现在你理解了编程语言,
we're going to deep dive for the next couple of episodes,
接下来几集 我们会深入了解
and we'll continue to build your understanding
接下来几集 我们会深入了解
of how programming languages, and the software they create,
编程语言和用语言写的软件
are used to do cool and unbelievable things.
是怎么做到那些酷事
See you next week.
下周见
(给 Curiosity Stream 打广告)
================================================
FILE: (字幕)全40集中英字幕文本/12. 编程原理-语句和函数-Programming Basics - Statements & Functions.ass.txt
================================================
Hi, I’m Carrie Anne, and welcome to CrashCourse Computer Science!
(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
Last episode we discussed how writing programs in native machine code,
上集讲到用机器码写程序,
and having to contend with so many low level details, was a huge impediment to writing complex programs.
还要处理那么多底层细节 对写大型程序是个巨大障碍
To abstract away many of these low-level details, Programming Languages were developed that
为了脱离底层细节,开发了编程语言
let programmers concentrate on solving a problem with computation, and less on nitty gritty hardware details.
让程序员专心解决问题,不用管硬件细节
So today, we’re going to continue that discussion, and introduce some fundamental building blocks
今天我们讨论 大多数编程语言都有的基本元素
that almost all programming languages provide.
今天我们讨论 大多数编程语言都有的基本元素
Just like spoken languages, programming languages have statements.
就像口语一样,编程语言有"语句"
These are individual complete thoughts, like "I want tea" or "it is raining".
语句表达单个完整思想,比如"我想要茶"或者"在下雨"
By using different words, we can change the meaning;
用不同词汇可以代表不同含义 \N 比如"我想要茶"变成"我想要独角兽"
for example, "I want tea" to "I want unicorns".
用不同词汇可以代表不同含义 \N 比如"我想要茶"变成"我想要独角兽"
But we can’t change "I want tea" to "I want raining" - that doesn’t make grammatical sense.
但没法把"我想要茶"改成"我想要雨"- 语法毫无意义
The set of rules that govern the structure and composition of statements in a language
规定句子结构的一系列规则 叫语法
is called syntax.
规定句子结构的一系列规则 叫语法
The English language has syntax, and so do all programming languages.
英语有语法,所有编程语言也都有语法
"a = 5" is a programming language statement.
a=5 是一个编程语言语句
In this case, the statement says a variable named A has the number 5 stored in it.
意思是创建一个叫 a 的变量,把数字 5 放里面.
This is called an assignment statement because we're assigning a value to a variable.
这叫"赋值语句",把一个值赋给一个变量
To express more complex things, we need a series of statements,
为了表达更复杂的含义,需要更多语句
like "A is 5, B is 10, C equals A plus B"
比如 \Na=5 \N b=10 \Nc=a+b
This program tells the computer to set variable ‘A’ equal to 5, variable ‘B’ to 10,
意思是,变量 a 设为5,变量 b 设为10
and finally to add ‘A’ and ‘B’ together, and put that result, which is 15, into -- you guessed it -- variable C.
把 a 和 b 加起来,把结果 15 放进变量 c
Note that we can call variables whatever we want.
注意,变量名可以随意取
Instead of A, B and C, it could be apples, pears, and fruits.
除了 a b c,也可以叫苹果、梨、水果
The computer doesn’t care, as long as variables are uniquely named.
计算机不在乎你取什么名,只要不重名就行
But it’s probably best practice to name them things that make sense
当然取名最好还是有点意义,方便别人读懂
in case someone else is trying to understand your code.
当然取名最好还是有点意义,方便别人读懂
A program, which is a list of instructions, is a bit like a recipe:
程序由一个个指令组成,有点像菜谱:
boil water, add noodles, wait 10 minutes, drain and enjoy.
烧水、加面,等10分钟,捞出来就可以吃了
In the same way, the program starts at the first statement
程序也是这样,从第一条语句开始
and runs down one at a time until it hits the end.
一句一句运行到结尾
So far, we’ve added two numbers together.
刚才我们只是把两个数字加在一起
Boring.
无聊
Let’s make a video game instead!
我们来做一款游戏吧
Of course, it’s way too early to think about coding an entire game,
当然,现在这个学习阶段 \N来编写一整个游戏还太早了
so instead, we’ll use our example to write little snippets of code
所以我们只写一小段一小段的代码
that cover some programming fundamentals.
来讲解一些基础知识
Imagine we’re building an old-school arcade game where Grace Hopper has to capture bugs
假设我们在写一款老派街机游戏:Grace Hopper 拍虫子
before they get into the Harvard Mark 1 and crash the computer!
阻止虫子飞进计算机造成故障
On every level, the number of bugs increases.
关卡越高,虫子越多
Grace has to catch them before they wear out any relays in the machine.
Grace 要在虫子损坏继电器之前 抓住虫子
Fortunately, she has a few extra relays for repairs.
好消息是 她有几个备用继电器
To get started, we’ll need to keep track of a bunch of values that are important for gameplay
开始编写时,我们需要一些值 来保存游戏数据
like what level the player is on, the score, the number of bugs remaining,
比如当前关卡数、分数、剩余虫子数、
as well as the number of spare relays in Grace’s inventory.
Grace 还剩几个备用继电器
So, we must "initialize" our variables, that is, set their initial value:
所以我们要"初始化"变量 \N "初始化"的意思是设置最开始的值.
"level equals 1, score equals 0, bugs equals 5, spare relays equals 4, and player name equals "Andre".
关卡=1 分数=0 虫子数=5 \N 备用继电器=4 玩家名=Andre
To create an interactive game, we need to control the flow of the program
为了做成交互式游戏,程序的执行顺序要更灵活
beyond just running from top to bottom.
不只是从上到下执行
To do this, we use Control Flow Statements.
因此用 "控制流语句"
There are several types, but If Statements are the most common.
控制流语句有好几种,最常见的是 if 语句
You can think of them as "If X is true, then do Y".
可以想成是 "如果 X 为真,那么执行 Y"
An English language example is: "If I am tired, then get tea"
用英语举例就是 "如果累了, 就去喝茶"
So if "I am tired" is a true statement, then I will go get tea
如果 "累了" 为真,就去喝茶
If "I am tired" is false, then I will not go get tea.
如果 "累了" 为假,就不喝茶
An IF statement is like a fork in the road.
if 语句就像岔路口
Which path you take is conditional on whether the expression is true or false
走哪条路 取决于 "表达式" 的真假,
so these expressions are called Conditional Statements.
因此这些表达式又叫 "条件语句"
In most programming languages, an if statement looks something like
在大多数编程语言中,if 语句看起来像这样:
"If, expression, then, some code, then end the if statement".
if [条件], then [一些代码],结束 if 语句.
For example, if "level" is 1, then we set the score to zero, because the player is just starting.
比如,if [第一关],then [分数设为0] \N 因为玩家才刚开始游戏
We also set the number of bugs to 1, to keep it easy for now.
同时把虫子数设为 1,让游戏简单些
Notice the lines of code that are conditional on the if-statement are nested between the
注意, 依赖于 if 条件的代码,要放在 IF 和 END IF 之间
IF and END IF.
注意, 依赖于 if 条件的代码,要放在 IF 和 END IF 之间
Of course, we can change the conditional expression to whatever we want to test, like
当然,条件表达式 可以改成别的,比如:
"is score greater than 10" or "is bugs less than 1".
"分数 >10" 或者 "虫子数 <1"
And If-Statements can be combined with an ELSE statement, which acts as a catch-all if the expression is false.
if 还可以和 else 结合使用 \N 条件为假会执行 else 里的代码
If the level is not 1, the code inside the ELSE block will be executed instead, and the
如果不是第1关,else 里的指令就会被执行
number of bugs that Grace has to battle is set to 3 times the level number.
Grace 要抓的虫子数,是当前关卡数 * 3
So on level 2, it would be six bugs, and on level 3 there’s 9, and so on.
所以第 2 关有 6 个虫子,第 3 关有 9 个虫子,以此类推
Score isn’t modified in the ELSE block, so Grace gets to keep any points earned.
else 中没有改分数,所以 Grace 的分数不会变
Here are some examples of if-then-else statements from some popular programming languages
这里列了一些热门编程语言 if-then-else 的具体语法
-- you can see the syntax varies a little, but the underlying structure is roughly the same.
具体语法略有不同,但主体结构一样
If-statements are executed once, a conditional path is chosen, and the program moves on.
if 语句 根据条件执行一次
To repeat some statements many times, we need to create a conditional loop.
如果希望根据条件执行多次,需要"条件循环"
One way is a while statement, also called a while loop.
比如 while 语句,也叫 "while 循环"
As you might have guessed, this loops a piece of code "while" a condition is true.
当 while 条件为真,代码会重复执行
Regardless of the programming language, they look something like this:
不管是哪种编程语言,结构都是这样
In our game, let’s say at certain points, a friendly colleague restocks Grace with relays!
假设到达一定分数会冒出一个同事,给 Grace 补充继电器
Hooray!
棒极了!
To animate him replenishing our stock back up to a maximum of 4, we can use a while loop.
把继电器补满到最大数 4 个 \N 我们可以用 while 语句来做
Let’s walk through this code.
来过一遍代码
First we’ll assume that Grace only has 1 tube left when her colleague enters.
假设同事入场时, Grace 只剩一个继电器
When we enter the while loop, the first thing the computer does is test its conditional…
当执行 while 循环,第一件事是检查条件
is relays less than 4?
继电器数量<4?
Well, relays is currently 1, so yes.
继电器数量现在是1,所以是真
Now we enter the loop!
进入循环!
Then, we hit the line of code: "relays equals relays plus 1".
碰到这一行:继电器数量=继电器数量+1
This is a bit confusing because the variable is using itself in an assignment statement,
看起来有点怪,变量的赋值用到了自己
so let's unpack it.
我们讲下这个
You always start by figuring out the right side of the equals sign first,
总是从等号右边开始,
so what does "relays plus 1" come out to be?
"继电器数量+1" 是多少?
Well, relays is currently the value 1, so 1 plus 1 equals 2.
当前值是1,所以 1+1=2
Then, this result gets saved back into the variable relays, writing over the old value,
结果存到"继电器数量",覆盖旧的值
so now relays stores the value 2.
所以现在继电器数量是 2
We’ve hit the end of the while loop, which jumps the program back up.
现在到了结尾,跳回开始点
Just as before, we test the conditional to see if we’re going to enter the loop.
和之前一样,先判断条件,看要不要进入循环
Is relays less than 4?
继电器数量<4?
Well, yes, relays now equals 2, so we enter the loop again!
是,继电器数量是2,所以再次进入循环!
2 plus 1 equals 3.
2+1=3
so 3 is saved into relays.
3 存入"继电器数量"
Loop again.
回到开头
Is 3 less than 4?
3<4?
Yes it is!
是!
Into the loop again.
进入循环
3 plus 1 equals 4.
3+1=4
So we save 4 into relays.
4 存入"继电器数量"
Loop again.
回到开头
Is 4 less than 4?....
4<4?
No!
不!
So the condition is now false, and thus we exit the loop and move on to any remaining code
现在条件为假,退出循环,执行后面的代码
That’s how a while loop works!
while 循环就是这样运作的!
There’s also the common For Loop.
另一种常见的叫 "for 循环"
Instead of being a condition-controlled loop that can repeat forever until the condition is false
不判断条件,判断次数,会循环特定次数
a FOR loop is count-controlled; it repeats a specific number of times.
不判断条件,判断次数,会循环特定次数
They look something like this:
看起来像上图
Now, let’s put in some real values.
现在放些真正的值进去
This example loops 10 times, because we’ve specified that variable ‘i’
上图例子会循环10次,因为设了变量 i
starts at the value 1 and goes up to 10.
从 1 开始,一直到 10
The unique thing about a FOR loop is that each time it hits NEXT, it adds one to ‘i’.
for 的特点是,每次结束, i 会 +1
When ‘i’ equals 10, the computer knows it’s been looped 10 times, and the loop exits
当 i 等于10,就知道循环了10次,然后退出.
We can set the number to whatever we want -- 10, 42, or a billion -- it’s up to us.
我们可以用任何数字,10, 42, 10 亿
Let’s say we want to give the player a bonus at the end of each level
假设每关结束后 给玩家一些奖励分
for the number of vacuum relays they have left over.
奖励分多少取决于 继电器剩余数量
As the game gets harder, it takes more skill to have unused relays,
随着难度增加,剩下继电器会越来越难
so we want the bonus to go up exponentially based on the level.
因此奖励分会根据当前关卡数,指数级增长
We need to write a piece of code that calculates exponents -
我们要写一小段代码来算指数
that is, multiplying a number by itself a specific number of times.
指数是一个数乘自己,乘特定次数
A loop is perfect for this!
用循环来实现简直完美!
First lets initialize a new variable called "bonus" and set it to 1.
首先,创建一个叫"奖励分"的新变量,设为 1 (看上图)
Then, we create a FOR loop starting at 1, and looping up to the level number.
然后 for 循环,从 1 到 [当前关卡数]
Inside that loop, we multiply bonus times the number of relays,
[奖励分] x [继电器剩余数],结果存入 [奖励分]
and save that new value back into bonus.
[奖励分] x [继电器剩余数],结果存入 [奖励分]
For example, let’s say relays equals 2, and level equals 3.
比如继电器数是2,关卡数是3
So the FOR loop will loop three times, which means bonus is going to get multiplied by
for 会循环3次,奖励分会乘
relays... by relays... by relays.
继电器数量 x 继电器数量 x 继电器数量
Or in this case, times 2, times 2, times 2, which is a bonus of 8!
也就是1×2×2×2,奖励分是8,2的3次方
That’s 2 to the 3rd power!
也就是1×2×2×2,奖励分是8,2的3次方
This exponent code is useful, and we might want to use it in other parts of our code.
这个指数代码很实用,其他地方可能会用到
It’d be annoying to copy and paste this everywhere, and have to update the variable names each time.
如果每次想用就复制粘贴,会很麻烦,每次都要改变量名
Also, if we found a bug, we’d have to hunt around and update every place we used it.
如果代码发现问题,要补漏洞时 \N 要把每一个复制黏贴过的地方都找出来改
It also makes code more confusing to look at.
而且会让代码更难懂
Less is more!
少即是多!
What we want is a way to package up our exponent code so we can use it, get the result, and
我们想要某种方法,把代码"打包" \N 可以直接使用,得出结果,
not have to see all the internal complexity.
不用管内部复杂度.
We’re once again moving up a new level of abstraction!
这又提升了一层抽象!
To compartmentalize and hide complexity,
为了隐藏复杂度
programming languages can package pieces of code into named functions,
可以把代码打包成 "函数"
also called methods or subroutines in different programming languages.
也叫 "方法" 或 "子程序"\N(有些编程语言这么叫)
These functions can then be used by any other part of that program just by calling its name.
其他地方想用这个函数,直接写函数名就可以了
Let’s turn our exponent code into a function! First, we should name it.
现在我们把指数代码变成函数. 第一步,取名.
We can call it anything we want, like HappyUnicorn,
叫什么都行,比如"快乐独角兽"
but since our code calculates exponents, let’s call it exponent.
但因为是算指数, 直接叫"指数"合适一些
Also, instead of using specific variable names, like "relays" and "levels",
还有,与其用特定变量名,比如 "继电器" 和 "关卡数"
we specify generic variable names, like Base and Exp,
用更通用的名字,比如 底数(Base) 和 指数(Exp)
whose initial values are going to be "passed" into our function from some other part of the program.
Base 和 Exp 的初始值需要外部传入
The rest of our code is the same as before
剩余代码和之前一样
Now tucked into our function and with new variable names.
现在完成了,有函数名和新变量名.
Finally, we need to send the result of our exponent code back to the part of the program that requested it.
最后, 我们还需要把结果 交给使用这个函数的代码
For this, we use a RETURN statement, and specify that the value in ‘result’ be returned.
所以用 RETURN 语句,指明返回什么.
So our full function code looks like this:
完整版代码是这样
Now we can use this function anywhere in our program,
现在可以随意用这个函数
simply by calling its name and passing in two numbers.
只需要写出名字 然后传入2个数字 就可以了
For example, if we want to calculate 2 to the 44th power, we can just call "exponent 2 comma 44."
如果要算 2 的 44 次方,写 exponent(2,44)
and like 18 trillion comes back.
结果是 18 万亿左右
Behind the scenes, 2 and 44 get saved into variables Base and Exp inside the function,
幕后原理是,2 和 44 存进 Base 和 Exp
it does all its loops as necessary, and then the function returns with the result.
跑循环,然后返回结果
Let’s use our newly minted function to calculate a score bonus.
我们来用这个新函数 算奖励分
First, we initialize bonus to 0.
首先,奖励分初始化为 0
Then we check if the player has any remaining relays with an if-statement.
然后用 if 语句,看剩不剩继电器(看上图的 > 0)
If they do, we call our exponent function, passing in relays and level,
如果还剩,用指数函数,传入 [继电器数] 和 [关卡数]
which calculates relays to the power of level, and returns the result, which we save into bonus.
它会算 [继电器数]的[关卡数]次方, 存入奖励分
This bonus calculating code might be useful later, so let’s wrap it up as a function too!
这段算奖励分的代码,之后可能还会用,也打包成一个函数
Yes, a function that calls a function!
没错,这个函数 (CalcBonus) \N 会调用另一个函数 (Exponent)
And then, wait for it…. we can use this function in an even more complex function.
还有!这个 CalcBonus 函数,可以用在其他更复杂的函数
Let’s write one that gets called everytime the player finishes a level.
我们来写一个函数, 每一关结束后都会调用
We’ll call it "LevelFinished"
叫 LevelFinished (关卡结束)
- it needs to know the number of relays left, what level it was, and the current score;
需要传入 [剩余继电器数] [关卡数] [当前分]
those values have to get passed in.
这些数据必须传入.
Inside our function, we’ll calculate the bonus, using our CalcBonus function,
里面用 CalcBonus 算奖励分,并加进总分
and add that to the running score.
里面用 CalcBonus 算奖励分,并加进总分
Also, if the current score is higher than the game’s high score,
还有,如果当前分 > 游戏最高分
we save the new high score and the players name.
把新高分和玩家名 存起来
Now we’re getting pretty fancy.
现在代码变得蛮"花哨"了
Functions are calling functions are calling functions!
函数调函数调函数
When we call a single line of code, like this the complexity is hidden.
我们写这样一行代码时,复杂度都隐藏起来了
We don’t see all the internal loops and variables,
不需要知道内部的循环和变量
we just see the result come back as if by magic…. a total score of 53.
只知道结果会像魔术一样返回,总分 53
But it’s not magic, it’s the power of abstraction!
但是这不是魔术,是抽象的力量
If you understand this example, then you understand the power of functions,
如果你理解了这个例子,就明白了函数的强大之处
and the entire essence of modern programming.
和现代编程的核心
It’s not feasible to write, for example, a web browser as one gigantically long list of statements.
比如浏览器这样的复杂程序,用一长串语句来写是不可能的
It would be millions of lines long and impossible to comprehend!
会有几百万行代码,没人能理解
So instead, software consists of thousands of smaller functions,
所以现代软件由上千个函数组成
each responsible for different features.
每个负责不同的事
In modern programming, it’s uncommon to see functions longer than around 100 lines of code
如今超过100行代码的函数很少见
because by then, there’s probably something that
如果多于 100 行,应该有东西可以拆出来做成一个函数
should be pulled out and made into its own function.
如果多于 100 行,应该有东西可以拆出来做成一个函数
Modularizing programs into functions not only allows a single programmer to write an entire app
模块化编程 不仅可以让单个程序员独立制作 App
but also allows teams of people to work efficiently on even bigger programs.
也让团队协作可以写更大型的程序
Different programmers can work on different functions,
不同程序员写不同函数
and if everyone makes sure their code works correctly,
只需要确保自己的代码工作正常
then when everything is put together, the whole program should work too!
把所有人的拼起来,整个程序也应该能正常运作!
And in the real world, programmers aren’t wasting time writing things like exponents.
现实中,程序员不会浪费时间写指数函数这种东西
Modern programming languages come with huge bundles of pre-written functions, called Libraries.
现代编程语言 有很多预先写好的函数集合,叫 "库"
These are written by expert coders, made efficient and rigorously tested, and then given to everyone.
由专业人员编写,不仅效率高,而且经过了仔细检查
There are libraries for almost everything, including networking, graphics, and sound
几乎做所有事情都有库,网络、图像、声音
-- topics we’ll discuss in future episodes.
我们之后会讲这些主题.
But before we get to those, we need to talk about Algorithms.
但在此之前,我们先讲算法
Intrigued?
好奇吗?
You should be.
你应该才是!
I’ll see you next week.
下周见
================================================
FILE: (字幕)全40集中英字幕文本/13. 算法入门 - Intro to Algorithms.ass.txt
================================================
Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!
(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!
Over the past two episodes, we got our first taste of programming in a high-level language,
前两集,我们"初尝"了高级编程语言\N (比如 Python 和 Java)
like Python or Java.
前两集,我们"初尝"了高级编程语言\N (比如 Python 和 Java)
We talked about different types of programming language statements
我们讨论了几种语句 - 赋值语句,if 语句,循环语句
- like assignments, ifs, and loops -
我们讨论了几种语句 - 赋值语句,if 语句,循环语句
as well as putting statements into functions that perform a computation,
以及把代码打包成 "函数"
like calculating an exponent.
比如算指数
Importantly, the function we wrote to calculate exponents is only one possible solution.
重要的是,之前写的指数函数 \N 只是无数解决方案的一种
There are other ways to write this function
还有其它方案
- using different statements in different orders -
- 用不同顺序写不同语句 也能得到一样结果
that achieve exactly the same numerical result.
- 用不同顺序写不同语句 也能得到一样结果
The difference between them is the algorithm,
不同的是 "算法",意思是:解决问题的具体步骤
that is the specific steps used to complete the computation.
不同的是 "算法",意思是:解决问题的具体步骤
Some algorithms are better than others even if they produce equal results.
即使结果一致,有些算法会更好
Generally, the fewer steps it takes to compute, the better it is,
一般来说,所需步骤越少越好
though sometimes we care about other factors, like how much memory it uses.
不过有时我们也会关心其他因素,比如占多少内存
The term algorithm comes from Persian polymath Muhammad ibn Musa al-Khwarizmi
"算法" 一词来自 波斯博识者 阿尔·花拉子密
who was one of the fathers of algebra more than a millennium ago.
1000 多年前的代数之父之一
The crafting of efficient algorithms
如何想出高效算法 - 是早在计算机出现前就有的问题
- a problem that existed long before modern computers -
如何想出高效算法 - 是早在计算机出现前就有的问题
led to a whole science surrounding computation,
诞生了专门研究计算的领域,然后发展成一门现代学科
which evolved into the modern discipline of...
诞生了专门研究计算的领域,然后发展成一门现代学科
you guessed it!
你猜对了!
Computer Science!
计算机科学!
One of the most storied algorithmic problems in all of computer science is sorting
记载最多的算法之一是"排序"
as in sorting names or sorting numbers.
比如给名字、数字排序
Computers sort all the time.
排序到处都是
Looking for the cheapest airfare,
找最便宜的机票
arranging your email by most recently sent,
按最新时间排邮件
or scrolling your contacts by last name
按姓氏排联系人
-- those all require sorting.
-这些都要排序
You might think
你可能想"排序看起来不怎么难… 能有几种算法呢?"
"sorting isn't so tough how many algorithms can there possibly be?"
你可能想"排序看起来不怎么难… 能有几种算法呢?"
The answer is: a lot.
答案是超多
Computer Scientists have spent decades inventing algorithms for sorting,
计算机科学家花了数十年发明各种排序算法
with cool names like Bubble Sort and Spaghetti Sort.
还起了酷酷的名字,"冒泡排序""意面排序"
Let's try sorting!
我们来试试排序!
Imagine we have a set of airfare prices to Indianapolis.
试想有一堆机票价格,都飞往 印第安纳波利斯 (美国地名)
We'll talk about how data like this is represented in memory next week,
数据具体怎么在内存中表示 下周再说
but for now, a series of items like this is called an array.
上图的这样一组数据 叫"数组"(Array)
Let's take a look at these numbers to help see how we might sort this programmatically.
来看看怎么排序
We'll start with a simple algorithm.
先从一种简单算法开始
First, let's scan down the array to find the smallest number.
先找到最小数,从最上面的 307 开始
Starting at the top with 307.
先找到最小数,从最上面的 307 开始
It's the only number we've seen, so it's also the smallest.
因为现在只看了这一个,所以它是最小数
The next is 239, that's smaller than 307,
下一个是 239,比 307 小
so it becomes our new smallest number.
所以新的最小数变成 239
Next is 214, our new smallest number.
下一个是 214 ,新的最小数
250 is not, neither is 384, 299, 223 or 312.
250 不是,384, 299, 223, 312 都不是
So we've finished scanning all numbers,
现在扫完了所有数字
and 214 is the smallest.
214 是最小的
To put this into ascending order,
为了升序排列(从小到大排序)
we swap 214 with the number in the top location.
把 214 和最上面的数字,交换位置
Great! We sorted one number!
好棒! 刚排序了一个数字!
Now we repeat the same procedure,
现在重复同样的过程
but instead of starting at the top, we can start one spot below.
这次不从最上面开始,从第 2 个数开始
First we see 239, which we save as our new smallest number.
先看到 239,我们当作是 "最小数"
Scanning the rest of the array, we find 223 is the next smallest,
扫描剩下的部分,发现 223 最小
so we swap this with the number in the second spot.
所以把它和第 2 位交换
Now we repeat again, starting from the third number down.
重复这个过程,从第 3 位数字开始
This time, we swap 239 with 307.
让 239 和 307 互换位置
This process continues until we get to the very last number,
重复直到最后一个数字
and voila, the array is sorted and you're ready to book that flight to Indianapolis!
瞧,数字排好了,可以买机票了!
The process we just walked through is one way
刚刚这种方法,或者说算法,
- or one algorithm - for sorting an array.
刚刚这种方法,或者说算法,
It's called Selection sort - and it's pretty basic.
叫 选择排序 - 非常基础的一种算法
Here's the pseudo-code.
以下是"伪代码"
This function can be used to sort 8, 80, or 80 million numbers
这个函数可以排序8个, 80个或8千万个数字
- and once you've written the function, you can use it over and over again.
函数写好了就可以重复使用
With this sort algorithm, we loop through each position in the array, from top to bottom,
这里用循环 遍历数组
and then for each of those positions,
每个数组位置都跑一遍循环,找最小数然后互换位置
we have to loop through the array to find the smallest number to swap.
每个数组位置都跑一遍循环,找最小数然后互换位置
You can see this in the code, where one FOR loop is nested inside of another FOR loop.
可以在代码中看到这一点 \N (一个 for 循环套另一个 for 循环)
This means, very roughly, that if we want to sort N items, we have to loop N times,
这意味着,大致来说,如果要排 N 个东西,要循环 N 次,
inside of which, we loop N times, for a grand total of roughly N times N loops, or N squared.
每次循环中再循环 N 次,共 N*N, 或 N
This relationship of input size to the number of steps the algorithm takes to run
算法的 输入大小 和 运行步骤 之间的关系
characterizes the complexity of the Selection Sort algorithm.
叫算法的 复杂度
It gives you an approximation of how fast, or slow, an algorithm is going to be.
表示运行速度的量级
Computer Scientists write this order of growth in something known as - no joke -
计算机科学家们把算法复杂度叫 - 没开玩笑
"big O notation".
大 O 表示法
N squared is not particularly efficient.
算法复杂度 O(N ) 效率不高
Our example array had n = 8 items, and 8 squared is 64.
前面的例子有 8 个元素(n=8), 8 = 64
If we increase the size of our array from 8 items to 80,
如果 8 个变 80 个
the running time is now 80 squared, which is 6,400.
运行时间变成 80 = 6400
So although our array only grew by 10 times - from 8 to 80 -
虽然大小只增长了 10 倍(8 到 80)
the running time increased by 100 times - from 64 to 6,400!
但运行时间增加了 100 倍!(64 到 6400 )
This effect magnifies as the array gets larger.
随着数组增大,对效率的影响会越来越大
That's a big problem for a company like Google,
这对大公司来说是个问题,比如 谷歌
which has to sort arrays with millions or billions of entries.
要对几十亿条信息排序
So, you might ask,
作为未来的计算机科学家你可能会问:有没有更高效的排序算法?
as a burgeoning computer scientist, is there a more efficient sorting algorithm?
作为未来的计算机科学家你可能会问:有没有更高效的排序算法?
Let's go back to our old, unsorted array
回到未排序的数组
and try a different algorithm, merge sort.
试另一个算法 "归并排序"
The first thing merge sort does is check if the size of the array is greater than 1.
第一件事是检查数组大小是否 > 1
If it is, it splits the array into two halves.
如果是,就把数组分成两半
Since our array is size 8, it gets split into two arrays of size 4.
因为数组大小是 8,所以分成两个数组,大小是 4
These are still bigger than size 1, so they get split again, into arrays of size 2,
但依然大于 1,所以再分成大小是 2 的数组
and finally they split into 8 arrays with 1 item in each.
最后变成 8 个数组,每个大小为 1
Now we are ready to merge, which is how "merge sort" gets its name.
现在可以"归并"了,"归并排序"因此得名
Starting with the first two arrays, we read the first - and only - value in them,
从前两个数组开始,读第一个(也是唯一一个)值
in this case, 307 and 239.
307 和 239
239 is smaller, so we take that value first.
239 更小,所以放前面
The only number left is 307, so we put that value second.
剩下的唯一数字是 307 ,所以放第二位
We've successfully merged two arrays.
成功合并了两个数组
We now repeat this process for the remaining pairs, putting them each in sorted order.
重复这个过程,按序排列
Then the merge process repeats.
然后再归并一次
Again, we take the first two arrays, and we compare the first numbers in them.
同样,取前两个数组,比较第一个数
This time its 239 and 214.
239 和 214
214 is lowest, so we take that number first.
214 更小,放前面
Now we look again at the first two numbers in both arrays: 239 and 250.
再看两个数组里的第一个数:239 和 250
239 is lower, so we take that number next.
239 更小,所以放下一位
Now we look at the next two numbers: 307 and 250.
看剩下两个数:307 和 250
250 is lower, so we take that.
250 更小,所以放下一位
Finally, we're left with just 307, so that gets added last.
最后剩下 307 ,所以放最后
In every case, we start with two arrays,
每次都以 2 个数组开始
each individually sorted, and merge them into a larger sorted array.
然后合并成更大的有序数组
We repeat the exact same merging process for the two remainin
gitextract_yvlrnkpn/
├── (字幕)全40集中英字幕文本/
│ ├── 01. 计算机早期历史-Early Computing.ass.txt
│ ├── 02. 电子计算机-Electronic Computing.ass.txt
│ ├── 03. 布尔逻辑 和 逻辑门-Boolean Logic & Logic Gates.ass.txt
│ ├── 04. 二进制-Representing Numbers and Letters with Binary.ass.txt
│ ├── 05. 算术逻辑单元-How Computers Calculate-the ALU.ass.txt
│ ├── 06. 寄存器 & 内存-Registers and RAM.ass.txt
│ ├── 07. 中央处理器-The Central Processing Unit(CPU).ass.txt
│ ├── 08. 指令和程序-Instructions & Programs.ass.txt
│ ├── 09. 高级CPU设计-Advanced CPU Designs.ass.txt
│ ├── 10. 早期的编程方式-Early Programming.ass.txt
│ ├── 11. 编程语言发展史-The First Programming Languages.ass.txt
│ ├── 12. 编程原理-语句和函数-Programming Basics - Statements & Functions.ass.txt
│ ├── 13. 算法入门 - Intro to Algorithms.ass.txt
│ ├── 14. 数据结构-Data Structures.ass.txt
│ ├── 15. 阿兰·图灵-Alan Turing.ass.txt
│ ├── 16. 软件工程-Software Engineering.ass.txt
│ ├── 17. 集成电路&摩尔定律-Integrated Circuits & Moore’s Law.ass.txt
│ ├── 18. 操作系统-Operating Systems.ass.txt
│ ├── 19. 内存&储存介质-Memory & Storage.mp4.ass.txt
│ ├── 20. 文件系统-Files & File Systems.ass.txt
│ ├── 21. 压缩-Compression.ass.txt
│ ├── 22. 命令行界面-Keyboards & Command Line Interfaces.ass.txt
│ ├── 23. 屏幕&2D 图形显示-Screens&2D Graphics.ass.txt
│ ├── 24. 冷战和消费主义-The Cold War and Consumerism.ass.txt
│ ├── 25. 个人计算机革命-The Personal Computer Revolution.ass.txt
│ ├── 26. 图形用户界面-Graphical User Interfaces.ass.txt
│ ├── 27. 3D 图形-3D Graphics.ass.txt
│ ├── 28. 计算机网络-Computer Networks.ass.txt
│ ├── 29. 互联网-The Internet.ass.txt
│ ├── 30. 万维网-The World Wide Web.ass.txt
│ ├── 31. 计算机安全-Cybersecurity.ass.txt
│ ├── 32. 黑客&攻击-Hackers & Cyber Attacks.ass.txt
│ ├── 33. 加密-Cryptography.ass.txt
│ ├── 34. 机器学习&人工智能-Machine Learning & Artificial Intelligence.ass.txt
│ ├── 35. 计算机视觉-Computer Vision.ass.txt
│ ├── 36. 自然语言处理-Natural Language Processing.ass.txt
│ ├── 37. 机器人-Robots.ass.txt
│ ├── 38. 计算机心理学 - Psychology of Computing.ass.txt
│ ├── 39. 教育科技-Educational Technology.ass.txt
│ └── 40. 奇点,天网,计算机的未来-The Singularity, Skynet, and the Future of Computing.ass.txt
├── (字幕)全40集中英字幕文本.txt
├── .gitignore
├── 1. screenshot.py
├── README-about-subtitle.md
├── README.md
└── extract_from_ass_subtitle/
├── 2. extract_head.js
├── 3. extract_ass_to_txt.js
├── README.md
├── common.js
└── package.json
SYMBOL INDEX (6 symbols across 3 files)
FILE: extract_from_ass_subtitle/2. extract_head.js
function loop_current_folder_ass_file_in_order (line 33) | function loop_current_folder_ass_file_in_order(){
function extract_main_point (line 48) | function extract_main_point(file, number){
FILE: extract_from_ass_subtitle/3. extract_ass_to_txt.js
function loop_current_folder_ass_file_in_order (line 12) | function loop_current_folder_ass_file_in_order(){
function extract_main_point (line 27) | function extract_main_point(file, number){
FILE: extract_from_ass_subtitle/common.js
function remove_curly_brace_keep_text (line 4) | function remove_curly_brace_keep_text(str) {
function convertHTML (line 8) | function convertHTML(str) {
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,474K chars).
[
{
"path": "(字幕)全40集中英字幕文本/01. 计算机早期历史-Early Computing.ass.txt",
"chars": 17766,
"preview": "Hello world, I'm Carrie Anne, and welcome to Crash Course Computer Science!\nHello world!我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nOv"
},
{
"path": "(字幕)全40集中英字幕文本/02. 电子计算机-Electronic Computing.ass.txt",
"chars": 14618,
"preview": "Our last episode brought us to the start of the 20th century,\n上集讲到 20 世纪初\n\nwhere early, special purpose computing device"
},
{
"path": "(字幕)全40集中英字幕文本/03. 布尔逻辑 和 逻辑门-Boolean Logic & Logic Gates.ass.txt",
"chars": 14355,
"preview": "Hi, I'm Carrie Anne and welcome to Crash Course Computer Science!\n嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nToday we start our jou"
},
{
"path": "(字幕)全40集中英字幕文本/04. 二进制-Representing Numbers and Letters with Binary.ass.txt",
"chars": 14646,
"preview": "Hi I'm Carrie Anne, this is Crash Course Computer Science\n嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nand today we're going to talk "
},
{
"path": "(字幕)全40集中英字幕文本/05. 算术逻辑单元-How Computers Calculate-the ALU.ass.txt",
"chars": 15329,
"preview": "Hi, I'm Carrie Ann and this is Crash Course Computer Science.\n嗨,我是 Carrie Anne,欢迎收看计算机科学速成课\n\nSo last episode, we talked "
},
{
"path": "(字幕)全40集中英字幕文本/06. 寄存器 & 内存-Registers and RAM.ass.txt",
"chars": 16798,
"preview": "Hi, I'm Carrie Anne and welcome to Crash Course Computer Science.\n嗨,我是 Carrie Anne,欢迎收看计算机科学速成课\n\nSo last episode, using "
},
{
"path": "(字幕)全40集中英字幕文本/07. 中央处理器-The Central Processing Unit(CPU).ass.txt",
"chars": 16086,
"preview": "Hi, I'm Carrie Anne, this is Crash Course Computer Science\n嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nand today, we're talking abou"
},
{
"path": "(字幕)全40集中英字幕文本/08. 指令和程序-Instructions & Programs.ass.txt",
"chars": 14434,
"preview": "Hi, I’m Carrie Anne and this is Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nLast episode, we "
},
{
"path": "(字幕)全40集中英字幕文本/09. 高级CPU设计-Advanced CPU Designs.ass.txt",
"chars": 18303,
"preview": "Hi, I’m Carrie Anne and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nAs we’ve discus"
},
{
"path": "(字幕)全40集中英字幕文本/10. 早期的编程方式-Early Programming.ass.txt",
"chars": 12905,
"preview": "Hi, I'm Carrie Anne and welcome to Crash Course Computer Science.\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nOver the last "
},
{
"path": "(字幕)全40集中英字幕文本/11. 编程语言发展史-The First Programming Languages.ass.txt",
"chars": 16677,
"preview": "This episode is brought to you by CuriosityStream.\n本集由 CuriosityStream 赞助播出\n\nHi, I'm Carrie Anne and welcome to Crash Co"
},
{
"path": "(字幕)全40集中英字幕文本/12. 编程原理-语句和函数-Programming Basics - Statements & Functions.ass.txt",
"chars": 17412,
"preview": "Hi, I’m Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nLast episode w"
},
{
"path": "(字幕)全40集中英字幕文本/13. 算法入门 - Intro to Algorithms.ass.txt",
"chars": 16623,
"preview": "Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nOver the past "
},
{
"path": "(字幕)全40集中英字幕文本/14. 数据结构-Data Structures.ass.txt",
"chars": 15120,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nLast episode,"
},
{
"path": "(字幕)全40集中英字幕文本/15. 阿兰·图灵-Alan Turing.ass.txt",
"chars": 20105,
"preview": "Hi, I'm Carrie Anne and welcome to Crash Course computer science.\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nOver the past "
},
{
"path": "(字幕)全40集中英字幕文本/16. 软件工程-Software Engineering.ass.txt",
"chars": 16516,
"preview": "Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nSo we've talke"
},
{
"path": "(字幕)全40集中英字幕文本/17. 集成电路&摩尔定律-Integrated Circuits & Moore’s Law.ass.txt",
"chars": 20739,
"preview": "This episode is brought to you by Curiosity Stream.\n本集由 Curiosity Stream 赞助播出\n\nHi, I’m Carrie Anne, and welcome to Crash"
},
{
"path": "(字幕)全40集中英字幕文本/18. 操作系统-Operating Systems.ass.txt",
"chars": 20091,
"preview": "This episode is supported by Hover.\n本集由 Hover 赞助播出\n\nHi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n("
},
{
"path": "(字幕)全40集中英字幕文本/19. 内存&储存介质-Memory & Storage.mp4.ass.txt",
"chars": 18606,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nWe've talked "
},
{
"path": "(字幕)全40集中英字幕文本/20. 文件系统-Files & File Systems.ass.txt",
"chars": 17764,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nLast episode "
},
{
"path": "(字幕)全40集中英字幕文本/21. 压缩-Compression.ass.txt",
"chars": 17209,
"preview": "This episode is brought to you by Curiosity Stream.\n本集由 Curiosity Stream 赞助播出\n\nHi, I'm Carrie Anne, and welcome to Crash"
},
{
"path": "(字幕)全40集中英字幕文本/22. 命令行界面-Keyboards & Command Line Interfaces.ass.txt",
"chars": 17441,
"preview": "Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nWe've talked a"
},
{
"path": "(字幕)全40集中英字幕文本/23. 屏幕&2D 图形显示-Screens&2D Graphics.ass.txt",
"chars": 17323,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nThis 1960 PDP"
},
{
"path": "(字幕)全40集中英字幕文本/24. 冷战和消费主义-The Cold War and Consumerism.ass.txt",
"chars": 17066,
"preview": "Hi, I'm Carrie Anne and welcome to Crash Course Computer Science.\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nEarly in th"
},
{
"path": "(字幕)全40集中英字幕文本/25. 个人计算机革命-The Personal Computer Revolution.ass.txt",
"chars": 15180,
"preview": "Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nAs we discu"
},
{
"path": "(字幕)全40集中英字幕文本/26. 图形用户界面-Graphical User Interfaces.ass.txt",
"chars": 19591,
"preview": "Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨 我是 Carrie Anne 欢迎收看计算机科学速成课\n\nWe ended last e"
},
{
"path": "(字幕)全40集中英字幕文本/27. 3D 图形-3D Graphics.ass.txt",
"chars": 17666,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nOver the past five"
},
{
"path": "(字幕)全40集中英字幕文本/28. 计算机网络-Computer Networks.ass.txt",
"chars": 19342,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nThe internet "
},
{
"path": "(字幕)全40集中英字幕文本/29. 互联网-The Internet.ass.txt",
"chars": 18656,
"preview": "Hi, I’m Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nAs we talke"
},
{
"path": "(字幕)全40集中英字幕文本/30. 万维网-The World Wide Web.ass.txt",
"chars": 17790,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science.\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nOver the p"
},
{
"path": "(字幕)全40集中英字幕文本/31. 计算机安全-Cybersecurity.ass.txt",
"chars": 18892,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nOver the l"
},
{
"path": "(字幕)全40集中英字幕文本/32. 黑客&攻击-Hackers & Cyber Attacks.ass.txt",
"chars": 17327,
"preview": "Hi, I’m Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nLast episode, "
},
{
"path": "(字幕)全40集中英字幕文本/33. 加密-Cryptography.ass.txt",
"chars": 17942,
"preview": "Hi, I'm Carrie Anne, and welcome to CrashCourse Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nOver the past "
},
{
"path": "(字幕)全40集中英字幕文本/34. 机器学习&人工智能-Machine Learning & Artificial Intelligence.ass.txt",
"chars": 17461,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nAs we've touc"
},
{
"path": "(字幕)全40集中英字幕文本/35. 计算机视觉-Computer Vision.ass.txt",
"chars": 16007,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨 我是Carrie Anne,欢迎收看计算机科学速成课\n\nToday, let's st"
},
{
"path": "(字幕)全40集中英字幕文本/36. 自然语言处理-Natural Language Processing.ass.txt",
"chars": 16654,
"preview": "Hi, I'm Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨 我是Carrie Anne,欢迎收看计算机科学速成课\n\nLast episode we"
},
{
"path": "(字幕)全40集中英字幕文本/37. 机器人-Robots.ass.txt",
"chars": 18191,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science!\n嗨,我是 Carrie Anne,欢迎收看计算机速成课\n\nToday we’re going to tal"
},
{
"path": "(字幕)全40集中英字幕文本/38. 计算机心理学 - Psychology of Computing.ass.txt",
"chars": 19091,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nSo, over t"
},
{
"path": "(字幕)全40集中英字幕文本/39. 教育科技-Educational Technology.ass.txt",
"chars": 18311,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\\N\n\nOne of t"
},
{
"path": "(字幕)全40集中英字幕文本/40. 奇点,天网,计算机的未来-The Singularity, Skynet, and the Future of Computing.ass.txt",
"chars": 18301,
"preview": "Hi, I’m Carrie Anne, and welcome to Crash Course Computer Science!\n(。・∀・)ノ゙嗨,我是 Carrie Anne \\N 欢迎收看计算机科学速成课!\n\nWe’re here"
},
{
"path": "(字幕)全40集中英字幕文本.txt",
"chars": 690334,
"preview": "Hello world, I'm Carrie Anne, and welcome to Crash Course Computer Science!\nHello world!我是 Carrie Anne,欢迎收看计算机科学速成课!\n\nOv"
},
{
"path": ".gitignore",
"chars": 94,
"preview": "extract_from_ass_subtitle/node_modules\nextract_from_ass_subtitle/package-lock.json\n*.DS_Store\n"
},
{
"path": "1. screenshot.py",
"chars": 637,
"preview": "# Crash Course Computer Science\n# 这里的程序只是为了截图视频开头 00:00:00 的时间表\n# 最后的输出结果:40张 jpg 图片\n\nimport os\n\nfiles = [f for f in os."
},
{
"path": "README-about-subtitle.md",
"chars": 1342,
"preview": "## 1. 关于公开字幕的一些说明\n公开字幕是为了方便大家学习 \n因为字幕是可以搜索的,而视频是没法搜索的 \n这里只公开了 txt 格式 \n\n* `(字幕)全40集中英字幕文本.txt` 这个 txt 文件\n* `(字幕)全"
},
{
"path": "README.md",
"chars": 20433,
"preview": "## 计算机科学速成课 :fire: 2018年5月1号 - 全40集完结撒花\n\n### 精校版: \nhttps://www.bilibili.com/video/av21376839/ \n\n<br/>\n\n![bilibi"
},
{
"path": "extract_from_ass_subtitle/2. extract_head.js",
"chars": 2631,
"preview": "const assParser = require('ass-parser');\nconst fs = require('fs');\nconst common = require('./common.js');\nconst path = r"
},
{
"path": "extract_from_ass_subtitle/3. extract_ass_to_txt.js",
"chars": 1764,
"preview": "// ass to txt\n// 不写注释了,参考 2. extract_head.js 即可\n\nconst assParser = require('ass-parser');\nconst fs = require('fs');\ncons"
},
{
"path": "extract_from_ass_subtitle/README.md",
"chars": 332,
"preview": "## 这里是一些 Node.js 代码\n\n## 用途\n抽取 ass 字幕文件的信息 \n\n## 说明\n针对计算机速成课的 ass 字幕 \n不通用(不能随便把什么 .ass 都拿来当输入),就是快速 h"
},
{
"path": "extract_from_ass_subtitle/common.js",
"chars": 849,
"preview": "// Remove all {}\n// Input: \"{\\c&HCC9933&}Subtitles by {\\c\\c&HFFFFFF &}MemoryOnSmells{\\c} {\\c&HCC9933&}Exclusive for http"
},
{
"path": "extract_from_ass_subtitle/package.json",
"chars": 257,
"preview": "{\n \"name\": \"cc_nodejs\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"ec"
}
]
About this extraction
This page contains the full source code of the 1c7/Crash-Course-Computer-Science-Chinese GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 50 files (1.3 MB), approximately 482.2k tokens, and a symbol index with 6 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.