>> DAVID J.马兰：好的。
所以欢迎大家来首次 CS50死后来做个测试​​。
我们认为我们会开幕 这一传统在今年。
这将是一个机会 漫步
解决方案的测试。
我们会加快或基于放缓 对那些在这里的利益。
>> 所以你可能在这里，因为你 感兴趣的是如何你可以有或
应该回答一些 的这些问题。
那么我们为什么不来看看 在本节第一？
因此让字符串。
这给了你三个不同的版本 一个程序，是的，最终，
为了从用户获得一个字符串。
不论它这样做是 留给你来决定。
>> 我们问的问题0， 假设第1版
编译和执行。
为什么会程序出现段错误？
乍一看，有什么建​​议 至于为什么？
是啊。
>> 观众：所以我记得在看到这个 看着在前面的例子
的char * s和看到S的扫描和 看到因为它是一个指针，如何
没有它会影响您的扫描？
它是S或s的地址？
>> DAVID J.马兰：确定。
好。
所以，最后，任何问题的来源 大概是要减少
该变量s。
而且这的确是一个变量。
该变量的数据类型是 的char *，这意味着它要
包含一个字符的地址。
而这其中就有敏锐的洞察力。
它要包含的地址 一个字符，或者更一般地，本
在第一个字符的地址 字符的整个块。
>> 但美中不足的是，扫描秒，目的在 生活中，被赋予一个地址和给定的
格式的代码，如％s，读取 字符串转换成的块
存储在该地址。
但因为没有等号前 在第一次的分号
一行代码，因为我们实际上并不 分配任何内存
malloc的，其实是因为它没有 分配一些大小的数组，所有
你正在做的是读取用户 键盘输入到一些完整的
垃圾值， 是s中默认情况​​下。
所以赔率是你要出现段错误，如果 该地址并不仅仅如此发生
是一个值就可以了， 其实，写。
如此糟糕不分配 你的内存有。
>> 因此，在问题1中，我们问， 假设2版
编译和执行。
为什么会这个程序出现段错误？
所以这一块是bug更少。
而且也真的只有一个 显而易见的方法，你可以
这里触发段错误。
这是主题。
任何我们用c + +在内存中的时间，有什么 你能做些什么来诱发段错误
与第2版？
>> 观众：如果您使用的输入 一个字符串，它比49再
字符。
>> DAVID J.马兰：没错。
你看到的东西固定长度的任何时间 当它涉及到一个数组，你
雷达会熄灭，这可能是 有问题的，如果你不检查
阵列的界限。
这就是这里的问题。
我们仍然使用scanf函数。
我们还在用％s，这意味着尝试 从用户读取的字符串。
这就是它会被读成s，， 在这一点上，是有效的
内存块的地址 或同类产品。
这是一个数组的名字 的内存字符。
>> 但恰恰是，如果你读一个字符串 这是超过49个字符，49长
因为你需要的空间反斜线 0，你要溢出
该缓冲区。
你可能会得到幸运，能够 写一个字第51，第52，第53。
但在某些时候，操作系统 会说，没有。
这绝对不是内存 你不准碰。
并且程序将会出现段错误。
>> 因此，启发式应该有任何 你已经有了固定长度的时间，你有
确保你检查的长度 不管它是什么你想要
读了进去。
>> 观众：所以要解决这个问题，你可以 有一个说法实际上检查
为长度大于 大于或小于？
>> DAVID J.马兰：当然可以。
你只需要一个条件 那说，如果 -
或者说你不一定知道 提前多少个字符
用户将要输入时，因为 你有鸡和蛋。
直到你跟scanf函数读取它 你可以计算出它有多长。
但在这一点上，为时已晚， 因为你已经将它读入
一些内存块。
所以，作为一个在旁边，CS50库避免了 这个问题完全，召回
用龟etc。
它读取一个字符时， 针尖沿着八字，知道你
不能溢出一个字符，如果 你读一次。
>> 美中不足的是GetString的召回 我们必须不断地调整大小
那大块的内存，这 仅仅是一个痛苦。
这是一个很大的行 代码来做到这一点。
因此，另一种方法是将 实际使用的表弟，所以
说话scanf函数的。
有很多这样的变种 功能，实际上检查
的长度多少个字符 你可能会最大限度地阅读。
并且您可以指定，不读 超过50个字符。
所以这将是另一种方法，但 更大的投入较少宽松。
>> 所以，问题2问，假设版本 3编译和执行。
为什么会是程序出现段错误？
所以这一块实际上是相同的 回答，即使它
看起来有点票友。
我们正在使用的malloc，这感觉就像 我们正在给自己更多的选择。
然后我们释放了 存储在末尾。
它仍然只有50个字节的内存。
因此，我们可能仍然尝试读取 在51，52，1000字节。
它会出现段错误的 正是由于同样的原因。
>> 但还有另外一个原因了。
还有什么能malloc返回除了 内存块的地址？
它可能返回null。
而且因为我们不检查 这一点，我们可能会做一些
愚蠢的另一个原因，那就是 我们可能会告诉scanf函数，读取
用户从键盘输入 到0的位置，又名空。
而这，也一定会 触发段错误。
所以对于测验的目的，我们将 已接受或者那些作为的
正当理由。
一个是相同的。
一个是多了几分微妙。
>> 最后，相对于该节目的 使用的内存，怎么办第2版和
第3版有什么区别？
因此，对于它的价值，我们看到了一个 可能看似源源不绝
回答这个。
而人与人之间的答案，我们都 希望，但我们接受的其他
的东西，是一些提到的 事实上版本2使用
所谓堆栈。
版本3正在使用的堆。
而在功能上，这并没有真正 让所有的多大的差别。
在一天结束的时候，我们仍然 刚开50字节的内存。
>> 但是，这是可能的答案之一 我们在看。
但你会看到，当你得到你的测验 从转录因子回首，那我们做
接受其他讨论他们的 内存完全不同的用途。
但堆栈和堆本来 一个简单的答案去用。
有问题吗？
我给你抢。
>> ROB BOWDEN：所以问题4。
这是一个在那里你必须填写 在字节数出所有的
这些不同类型的使用。
我们看到那么第一件事情。
假设一个32-bit架构， 这样CS50设备。
所以对基本的事情之一 32位体系结构，它告诉我们
到底有多大的指针是怎么回事 是在体系结构。
>> 于是马上，我们知道，任何指针 类型是32位或4个字节。
所以看这个表， 节点*为指针类型。
这将是4个字节。
结构节点*，这是字面上 相同的节点明星。
所以那将是4个字节。
字符串，所以它看起来并不像一个 指针还，但自定义类型，一
字符串只是一个char *，这 为指针类型。
所以这将是4个字节。
>> 所以，这三个都是4个字节。
现在，节点和学生都 更复杂一点。
所以看着节点和学生，我们看到 节点为一个整数和一个指针。
和学生是两个指针 里面的它。
所以至少在我们的情况下在这里，该方法 我们最终计算的大小
这个结构是只加了一切 这就是结构体里面。
>> 因此，对于节点，我们有一个整数， 这是4个字节。
我们有一个指针，它是4个字节。
所以一个节点是怎么回事 占用8个字节。
同样的学生，我们有 指针，该指针是4字节而另一个
指针就是4个字节。
所以这将结束 最高为8个字节。
因此，节点和学生都是8个字节。
而这三项都是4个字节。
该问题？
是。
>> 观众：是它是一个64位 建筑，那会
加倍所有的人？
>> ROB BOWDEN：不会 加倍所有的人。
因此，64位架构，它再次， 的变化，根本的东西，一个
指针现在是64位。
是啊。
这样一个指针是8个字节。
因此，这些是分别为4个字节 都将是8个字节。
一个学生，这是两个指针， 好了，现在它要
是8个字节，8字节。
这将会使16个字节。
>> 但一个节点仍然是4个字节。
所以这个指针是怎么回事 为8字节。
这是4个字节。
所以一个节点只打算 为12个字节。
在那一个别的问题吗？
所以，下一个，这些都是 HTTP状态码。
而你必须描述的情况 根据这些威力
退还给您。
我听到有些同学一个问题 有是，他们试图使
错误是在客户端的结束。
所以，当我们试图提出要求 到服务器上，出了
错在我们这边。
但一般来说，这些代码是 服务器正在返回。
因此，我们要弄清楚这是怎么回事 错误或正确的服务器上
导致返回这些东西。
那么，为什么一个服务器返回 状态代码200？
有什么想法？
>> 是啊。
因此，一些关于成功 请求经历。
而且他们能够返回 不管你提出的要求。
所以，一切都很好。
怎么样302发现了什么？
是啊。
>> 观众：服务器一直在寻找 为你所要求的。
但无法找到它。
所以这是一个错误。
>> ROB BOWDEN：那么服务器是 找你想要的东西。
所以只是看这里，302发现， 它能够找到它。
>> 观众：我很抱歉。
发现意味着，他们没有找到它。
抱歉。
>> ROB BOWDEN：那么302个记录。
该服务器能够找到 你想要的东西。
>> 观众：但它不显示呢？
>> ROB BOWDEN：之间的区别 这个302和200的是，它
知道你想要什么。
但它是不完全的地方 你要问。
所以302是一个典型的重定向。
所以，你所请求的页面。
它知道，哦，我想 给你退货。
但是，这是在一个不同的URL。
所以，嘿，你真正想要的。
>> DAVID J.马兰：这是一块提到 我们给你们一个重定向
函数所使用的头功能 这，反过来，打印出来的位置，
冒号，然后到的URL 你要拒绝的用户。
即使你没看见302 明确存在，这就是PHP的
会奇迹般地插入的标头 说正是罗布说有 -
发现。
但到这里吧。
>> ROB BOWDEN：确定。
那么，关于403被禁止？
>> 观众：我认为这是服务器 基本上说，在客户端
无法访问主页。
>> ROB BOWDEN：所以，是的。
嗯，典型的答案我们 期待是一样的东西，这些文件
没有适当chmodded。
这可能是在什么情况下 你看见了他们。
但还有一个原因，客户端 可能是错在这里。
实际上，有另外一个状态代码 -
401。
因此，这些都是非常相似的。
>> 401是未经授权的。
而403是被禁止的。
所以你们擅自专 如果你没有登录。得到
但登录可能意味着 你被授权。
但如果你已经登录，并且您 仍然没有权限，然后
你也可以禁止。
所以，如果你登录并且没有 许可，严禁也是
有些东西你可以得到的。
>> DAVID J.马兰：而到了机制 这些问题通常是
解决了在服务器上是 通过什么命令？
文件模式，如果是，的确，一个权限 发出的文件或目录。
>> ROB BOWDEN：那404未找​​到。
是啊。
所以不像302的地方是不完全 在那里你问，但它知道什么
你想，这一点，它只是 不知道你想要什么。
而你没有请求 一些有效的。
418我是一个茶壶，然后 500内部服务器。
那么，为什么你明白了吗？
>> 所以出现段错误 -
我居然不知道该分级 标准这一点。
但是，如果你的PHP代码有一些东西 错了，从理论上讲，它可以
实际上段错误，在这种情况下，这 500内部服务器错误，东西
是错误的与您的服务器的 配置。
或者有语法错误 在你的PHP代码。
或坏事是怎么回事。
>> DAVID J.马兰：我们确实看到段错误 其中几个人的答案。
而在技术上，它可能发生。
但是这将是一个PHP的程序 其他人写的，实际上
segfaulted，只如果那些人 搞砸了，并在写bug的代码
他们的解释器 PHP本身出现段错误。
因此，即使500就像是一个段错误 在精神上，它几乎总是
配置文件问题的结果 与您的Web服务器，或如罗布说，
一个语法错误，像你 没有关闭的报价。
或者你在某处失去了一个分号。
>> 观众：所以对于班车PSET，我 认为当我做到了，一旦我点击
浏览器，但没有上来， 他们所谓的白页。
但它是因为代码。
我认为这是JavaScript的，对不对？
>> ROB BOWDEN：是啊。
>> 观众：请问这个错误 还是来了？
>> ROB BOWDEN：所以你就不会得到 这个错误，因为一切
从Web服务器的角度来看 是完全没问题。
但你要求的index.html。
你要求shuttle.js 和service.js。
它能够成功返回 给你所有这些事情 -
200。
确定。
只有当您的浏览器尝试 解释JavaScript代码
这就像，等待，这是不 有效的JavaScript错误。
还有没有其他问题？
好的。
>> DAVID J.马兰：那么下一个 时间为11号。
和11是最可怕的 对于很多人。
所以最重要的事情需要注意 是，这是，事实上，大约
一个双向链表。
但是，这并不等同于去年的 双向链表的问题，
它没有给你有条件的，就是 这个名单可以，其实是未排序。
>> 这样一个事实，即列表是排序的 而事实上，这个词是
有下划线是为了传达 这实际上是一种简化
什么否则会一直 更具挑战性的问题
和一个较长的一个。
所以这里一个常见的​​错误是已经把 您的最后一个年度的解决方案
寻呼机，然后就盲目地复制 跌的答案，这是正确的
回答不同的问题 类似的精神。
但这里的微妙之处 分别如下。
>> 因此，一个，我们有一个节点，并宣布 在这里以通常的方式来定义。
然后，我们定义列表是一个全球性的 指针初始化为null。
那么显然，有两个功能 我们有原型在这里，插入
并删除。
然后，我们这里有一些示例代码 的做了一堆插入的。
然后，我们要求你完成 下面的实施刀片以这样
一种方式，它插入n转换成列表 在固定的时间，还强调，
即使已经存在。
>> 因此能够插入美女 在常数时间是，它意味着
你必须插入 新的节点在哪里？
到前面。
所以它消除了，幸运的是，至少 的过去需要一个案件
甚至更多的代码行，像它那样 去年，甚至在上课的时候​​我们
通过这种事情谈 与人类和一些
语言伪代码。
所以在这里的解决方案，让我们跳过 到只是为了有一个视觉上的
在屏幕上。
>> 请注意，我们正在做以下。
同时也注意到另一种简化 是，即使是
已经存在的，所以这意味着即使 数已经是存在的，你可以
只是一味地插入另一 它的副本。
而这，太，本来是一个 简化，这样你可以
集中精力，说真的，一些比较 智力有趣的部分和
不只是一些额外的错误检查 在有限的时间。
>> 所以在这个示例解决方案，我们分配 在左侧的指针
这里边一个节点。
现在，认识到指针，如 罗布说，只有32位。
而实际上它并不包含 一个地址，直到你
分配给它的地址。
我们这样做的右手 通过malloc的一面。
像一个好公民，我们检查 malloc的是不是，事实上，空，从而使
我们不小心创建 这里一个段错误。
任何时候你在生活中使用malloc，你 应检查null，以免
你有一个微妙的错误。
>> 然后我们初始化由空 分配n和上一页和下一页。
而在这里这种情况下，我初始化 以前为null，因为这个新的
节点将是新的 开始我的名单。
所以有将是 什么才。
我想基本上追加 现有列表，由新的节点
接下来设置等于列表本身。
但我没有这样做，只是还没有。
所以，如果列表本身已经存在， 并且有至少有一个节点
已经到位，如果是这样的列表 在这里，我插入一个新的节点在这里，我
需要确保我的前任节点 向后指向我的新节点，
因为这是再一次 一个双向链表。
>> 所以我们做完整性检查。
如果列表不为空，如果有已经 一个或多个节点存在，则
添加反向引用可以这么说。
然后，我们需要的最后一件事 这样做实际上是更新全局
变量列表本身为指向 到该新节点。
是啊。
>> 观众：在指针箭头 [听不清]等于null，即不
处理列表中，因为 该列表为空？
>> DAVID J.马兰：不。
这简直是​​我正在积极 小心，因为如果这是我的
原来列表也许更多一些节点 在这里，我插入我的
在这里新的节点，还有的将 是什么在这里。
我希望捕获的想法 通过设置前，以
在新节点上无效。
想必，如果我的代码是正确的 并有插入没有其他办法
节点比这个功能以外， 据推测，即使列表已经有
在它的一个或多个节点，想必 列表中，在第一个节点，将具有
空本身先前的指针。
>> 观众：而就在跟进。
你把指针下一个等号的原因 列表是你正在做的指针
列表中，它的指向前 下一个，我猜 -
我鸵鸟政策 -
只是列出？
>> DAVID J.马兰：没错。
所以，让我们真正考虑两种情况 这里真的，即使
订单，我们会考虑他们是不是 不太一样的代码。
但在一个高的水平，如果该指 列表，这是一个32位的
指针，最简单的情况是 这是默认为空。
并假设我想插入 数字50是一个数字。
所以我要继续前进并分配 一个节点，它也会包含
三个领域 -
N，上一页和下一页。
>> 我打算把50号 在这里，因为这会为n。
这将是下一个。
而这将是以前的。
所以我该怎么在这种情况下呢？
好吧，我刚刚做1号线在这里。
指针n得到Ñ。
我接着说，以前的 应该得到空。
因此，这将是空。
然后我会说下 是会得到列表。
>> 而这只是工作搞好。
这是空。
所以我说，新节点的下一个 字段应该得到什么，这是。
让把另一个空在那里。
再过去的事情 我要做的就是在这里检查。
如果list不等于空，但它 等于空，所以我们跳过
干脆。
等等一切我下一步要做的就是获取列表 指针，它形象地导致
类似的图片。
所以这是一个情景。
>> 和一个你问的是有关 具体是这样的情况，
我们已经有一个单节点列表。
如果我回去了原 问题陈述，接下来我们将
插入说的是34，只为 就事论事。
所以我打算只方便 绘制在这里。
我刚刚malloced。
假设我检查null。
>> 现在，我要初始化 电量为34。
这将为n。
这将是下一个。
而这将是以前的。
让我们确保我没有 得到这个倒退。
上一页至上 在该定义中。
让我来解决这个问题。
这是以前的。
这是下一个。
尽管这些是相同的， 让我们保持一致。
>> 上一页。
这是下一个。
所以，我刚刚malloced我的注意，检查 为null，则分配34到节点。
上一页变空。
所以，让我说。
下一步得到列表。
所以列表是这样的。
所以这个现在是一样的绘画本 箭头，使它们指向一个
中是相同的。
然后我检查，如果列表 不等于空。
它不是这个时候。
那么我该怎么办名单 先前得到的指针。
>> 所以列表上得到的PTR。
所以这把的效果 这里的图形箭头。
这就是开始有点 波浪状的线条。
然后，我最后更新 列出指向指针。
所以，现在这个指向这个家伙。
现在，让我们做一个快速 完整性检查。
>> 这里的名单，这是 全局变量。
第一个节点是，事实上，34，因为 我下面的箭头。
这就是正确的，因为我想 插入在列表的开头
所有新的节点。
他的下一场让我这个家伙。
如果我坚持下去，我打接下来为空。
所以没有更多的列表。
如果我打以前，我得到 回到了我的期望。
>> 所以还是有几个指针， 显然，操纵。
但事实上，你被告知这样做 这在常数时间内只意味着你
有一个事物的有限数目 你可以这样做。
那是什么号码？
它可能是一个步骤。
这可能有两个。
这可能是1000步。
但它是有限的，这意味着你不能 有什么样的循环的事
在这里，没有递归，没有循环。
这只是必须是硬编码线 的代码，因为我们有这样的样本。
>> 所以接下来的问题12问我们 完成删除的实现
下面以这样一种方式，它消除 N从该列表中的线性时间。
所以，你必须多一点 现在回旋的余地。
你可以假设N，如果存在 在列表中，将存在
不超过一次。
而这也意味着是一个测验为基础的 简化的假设，因此
如果你发现数字50的地方 在列表中，你不还
担心继续 遍历，寻找一切可能的
50个拷贝，这将只是下放 为在有限的时间一些细节。
>> 因此，与删除，这其中肯定 更具挑战性和更
代码编写。
但乍一看，坦率地说，它可能 看起来喧宾夺主，喜欢的东西
有没有办法，你可以有 拿出了一个小测验。
但是，如果我们专注于各个步骤， 希望，它会突然
打击你，每个个体的 步骤做明显的感觉
回想起来。
因此，让我们一起来看看。
>> 因此，首先，我们初始化指针 是列表本身。
因为我想线性时间，那手段 我要去有一些循环。
和常见的方式来遍历 在列表结构或任何种类的节点
结构的迭代是采取 一个指针的数据的前
结构，然后就开始更新 它和走你的路
通过该数据结构中。
所以我打算这样做。
>> 虽然指针，我的临时变量， 不等于空，让我们
继续和检查。
难道我很幸运？
是我目前的节点n场 看着等于
数我在找？
如果是这样，让我们​​做一些事情。
现在，请注意这一点，如果条件 围绕整个
代码如下行。
这是我所关心的唯一的事情 - 发现了一些问题。
所以没有其他人，从而简化 概念上的东西一点点。
>> 但现在，我才明白，你可能有 只有思前想后意识到了这一点
它通过了一下，有 实际上2箱子这里。
一种是其中的节点是在 开头的列表，这是一个的
有点讨厌，因为这是一个 特殊情况，因为你必须处理
有了这个东西，这 是唯一的异常。
放眼天下，列表， 这是同样的事情。
有一个以前的节点和下一 节点，前一个节点，下一个节点。
不过这家伙有点特殊 如果他是在开始。
>> 因此，如果该指针等于列表 本身，因此，如果我在初
列表中，我发现N，我需要 做了几件事情。
一，我需要改变列表 指向下一个领域，50。
因此，假设我想 删除34。
原来这家伙的得走了 走一会儿就好了。
>> 所以我要说，列表 获取指针下一个。
那么，这是指针。
接着指向了这里。
所以，这种情况正在改变这个箭头向右 现在指向这个家伙在这里。
现在，请记住，我们有 一个临时变量。
所以我们并没有孤立的任何节点， 因为我也有这个家伙在我
执行删除的。
所以，现在，如果列表本身不为空， 我需要修复的一点心意。
>> 我现在需要确保这个箭头， 这是先前指向
从50到34，这得走了， 因为如果我试图摆脱
34，50，最好不要保留任何 一种反向引用它作为
箭头提示。
所以，我只是做了这一行。
所以后来我做。
这种情况下，实际上是非常容易的。
斩去列表的头部 相对来说比较简单。
>> 遗憾的是，这 恼人的else块。
所以，现在，我要考虑的情况下 那里有什么东西在中间。
但它不是太可怕了，除了 像这样的语法。
所以，如果我不在的开始 名单，我在中间某个地方。
而这条线在这里是说，开始 在任何节点你在。
前往上一个节点的下一个字段 并指出，在指针。
>> 让我们做这样形象地。
这是越来越复杂。
所以，如果我有一个以前的领域在这里 - 让我们做到这一点 - 下一个栏位在这里。
我要简化我的指针，而 比画出一大堆
东西来回往返奔波 对方。
现在，让我们只说这是1，2， 3为便于讨论，甚至
虽然不与排队 所讨论的问题。
>> 因此，这里是我的链接列表。
我想在此删除两个 特别版本的故事。
所以，我已经更新指针 是指向这个家伙。
因此，这是PTR。
他指指点点。
这是列表，其中存在 作为全球前。
而且他指指点点不管。
而现在，我试图删除两个。
>> 所以，如果指针指向这里，我 要遵循，显然，该
以前的指针，这使我在1。
我接着要说的话，下一个 场，这使我到这
框这里，将要 平等的指针下一个。
因此，如果这个指针，这是下一个。
这意味着，该箭头的需求 指向这个家伙。
>> 那么，这行代码刚 所做的就是这一点。
而现在，这看起来像一个 步在正确的方向。
我们基本上要剪断2出 的1和3的中间。
因此，它是有道理的，我们要 路线this指针周围。
因此，这下一行检查，如果指针 接下来是不是null，则
确实有人为2的右边， 这意味着我们还必须做
这里一点剪断。
>> 所以，我现在需要遵循这个指针 和更新先前的指针
这家伙做的一点点 解决办法在这里这里的重点。
而现在，在视觉上，这是很好的。
这是一个有点凌乱在有 没有人在2指点了。
2是指向左边。
和图2是指向右侧。
但他可以做任何他想做的，因为 他即将得到释放。
它什么都无所谓 这些值了。
>> 最重要的是，剩余的 家伙上面的路由
现在他之下。
事实上，这正是我们下一步的行动。
我们免费的指针，这意味着我们告诉 操作系统，欢迎你
回收这一点。
然后最后，我们返回。
否则含蓄，如果我们 还没有还回来，
我们必须继续寻找。
所以指针等于next指针刚 这里指移动这个家伙。
搬到这里这个家伙。
这里提出这个家伙的话，其实， 我们没有发现的数
我们正在寻找的呢。
>> 所以坦率地说，它看起来完全 铺天盖地，我认为，首先
一目了然，特别是如果你挣扎 与此测验中则见
这样的事情。
和你拍拍自己的背。
那么，有没有办法，我能有 想出，关于测验。
但我认为，你可以，如果你打破 它分解成这些个人
例，只是通过它走 小心，虽然，不可否认，在
压力的情况下。
>> 值得庆幸的是，画面制作 一切快乐。
你可以在此画 任何数量的方式。
你不必做交叉的 这里的事情。
你可以用直线做 线路是这样的。
但这个问题的要点，在 一般情况下，是要认识到，在
图片到底应该看起来有点 这样的事情，因为
固定的时间暗示你保持 干扰与抗干扰和干扰的
在开始新的节点 的列表。
有问题吗？
可能是最具挑战性的 肯定是编码的问题。
>> 观众：那么类似于清单 在头前面的例子。
>> DAVID J. MALAN：没错，没错。
只是不同的名称 一个全局变量。
世界各地的什么？
>> ROB BOWDEN：确定。
因此，这是一个在那里你 不得不写一段。
有些人撰写的论文 对于这个问题。
但是，你只需要使用这六个条款 描述发生的事情时，
你尝试联系facebook.com。
所以我就谈谈整个过程 使用所有这些条款。
所以在我们的浏览器，我们输入facebook.com 然后按Enter键。
因此，我们的浏览器将构建一个 HTTP请求，它将会发送
通过一些过程的Facebook Facebook来与回应我们
它的HTML页面。
>> 那么，什么是过程 该HTTP请求
实得到Facebook？
因此，首先我们需要翻译 Facebook.com。
因此，只要给定的名称Facebook.com， 其中实际执行HTTP请求
需要去？
因此，我们需要翻译Facebook.com 到一个IP地址，它唯一
标识实际上是什么，我们的机器 要将此请求发送到。
你的笔记本电脑都有一个IP地址。
任何连接到互联网 有一个IP地址。
>> 所以DNS，域名系统，也就是 这是怎么回事处理翻译
从facebook.com到一个IP地址， 你其实是要联系。
所以我们联系了DNS服务器和 比如说，什么是facebook.com？
它说，哦，它的IP地址190.212 什么，什么，什么的。
好的。
现在，我知道什么机器 我想联系。
>> 这样的话你把你的HTTP请求 在该机器。
那么它是怎样得到那台机器？
好了，该请求会从 路由器到路由器的反弹。
请记住这个例子在课堂上，在那里 我们居然看到了路由的
包了，当我们试图 进行通信。
我们看到它跳过去的大西洋 海洋在一个点或什么的。
>> 所以最后期限端口。
所以这是现在你的电脑上。
你可以有多个当前的事情 与互联网通信。
这样我就可以运行，例如，Skype公司。
我可能有一个Web浏览器中打开。
我可能有一些 torrenting文件。
因此，所有这些事情都 与通信
互联网以某种方式。
>> 所以，当您的计算机接收的一些数据 从互联网上，是怎么做的
知道什么是真正的应用 想要的数据？
它如何知道是否这个特殊的 数据，是为
torrenting应用程序，而不是 到web浏览器？
因此，这是在该端口的目的 所有这些应用都
要求您的计算机上的端口。
所以，你的网页浏览器说，哎， 我正在侦听端口1000。
和你的torrenting程序是在说， 我正在侦听端口3000。
和Skype说，我使用的是端口4000。
>> 所以，当你得到一些数据属于 一个这些应用程序，数据
标有哪个端口它实际上 沿途应该被发送。
所以这个说，哦，我是属于 到端口1000。
我知道，那么我就需要这个转发 跟着我的网页浏览器。
因此，它之所以与此有关 是Web服务器往往
侦听端口80。
所以，当我联系Facebook.com，我 配有人机通信。
但我需要说的是哪个端口 机器我要与之通信。
和Web服务器往往是 侦听端口80。
>> 如果他们想要的，他们可以将其设置 高达所以它会列出为端口7000。
然后在Web浏览器，我可以 手动输入Facebook.com：7000
将请求发送到端口7000 Facebook的Web服务器。
>> DAVID J. MALAN：而且在这种情况下，即使 虽然我们没有要求的人
提到这一点，在这种情况下，什么端口 会的要求，其实去？
请再试一次。
没错。
不找了，但一个微妙 那有没有最后一次。
>> ROB BOWDEN：所以HTTPS的，因为它是 听专门为
加密的，它在端口4430。
>> 观众：和电子邮件是25吧？
>> DAVID J.马兰：出站 电子邮件，25，是的。
>> ROB BOWDEN：我什至不知道大多数的 的 - 所有的较低的往往是
对于保留的东西。
我觉得一切都在 1024被保留。
>> 观众：你为什么说 3是打错电话了？
>> ROB BOWDEN：因为在一个IP地址， 有四组数字。
并且他们是从0到255。
所以192.168.2.1是一种常见的 本地网络的IP地址。
请注意，所有这些都小于255。
所以，当我开始用300，这 不可能有
一直是数字之一。
>> DAVID J.马兰：但是，这傻夹 从 - 这是CSI，在那里他们有一个
数字太大 为IP地址。
>> ROB BOWDEN：本有问题吗？
下一个，在如此彻底的改变 的话题，但是我们有这个PHP数组的
房子在四。
我们有一个无序列表。
我们想打印出每个列表项 只是含有的房子名字。
所以我们有一个foreach循环。
所以请记住，语法的foreach 数组作为项目的数组中。
因此，通过循环的每次迭代， 房子是要采取的一个
该数组内的值。
>> 在第一次迭代中，房子 将卡博特众议院。
在第二次迭代，房子会 是快递楼等。
因此，对于每一个为四家，我们是 只是要打印 -
你也可以呼应 -
列表项，然后房子的名字 然后关闭列表项。
花括号是可选的在这里。
>> 然后我们又在这个问题说 本身，记得关闭
无序列表标记。
因此，我们需要退出PHP模式 为了做到这一点。
或者，我们也可以呼应 关闭无序列表标记。
>> DAVID J.马兰：精也将在这里 一直使用旧的学校
循环使用$ I = 0，并使用计数 计算出射线的长度。
完全没问题，只要 有点wordier。
>> 观众：所以，如果你要 [听不清]，你会怎么做 -
我忘记了环[听不清]是什么。
你会$四架我？
>> DAVID J.马兰：没错。
是的，没错。
>> ROB BOWDEN：还有别的吗？
>> DAVID J.马兰：好的。
权衡。
因此，有答案的串 可以为每个这些。
我们真的只是寻找 对于一个颠倒和令人信服的东西
不利的一面。
和16号要求，验证用户的 输入客户端，使用JavaScript，
而不是服务器端，如使用PHP。
那么什么是一个颠倒 做客户端？
>> 好了，我们提出的事情之一是 你减少等待时间，因为你
不必费心接触 服务器，这可能需要几分钟
毫秒甚至几秒钟 通过避免和公正
验证用户的输入客户端通过 触发的提交和处理程序
只是检查，没有他们的类型 在对名称的东西？
难道他们输入一些内容 在电子邮件地址？
难道他们从中选择一个宿舍 下拉菜单？
>> 你可以给他们即时的反馈 使用千兆赫兹的电脑
或不管他们有那 其实自己的办公桌上。
所以它只是一个更好的用户 通常会遇到。
但在做客户端的缺点 验证，如果你这样做也没有
做服务器端验证是 大多数人现身CS50都知道
你可以直接发送你想要的任何数据 到服务器任何数目的方式。
坦率地说，在几乎所有的浏览器，你可以 单击各地在设置和公正
关闭JavaScript，这会， 因此，禁止任何形式的
验证。
>> 但您可能还记得，即使我 没有使用类的一些神秘的东西
telnet和实际假装 是一个浏览器通过发送GET
请求到服务器。
而这当然不是 使用任何JavaScript。
这只是我输入命令 在一个键盘。
所以真的，足够在任何程序员 舒适与Web和HTTP
可以发送任何数据，他或她想要的 到未经验证的服务器。
如果你的服务器是不是也检查， 没有他们给我一个名字，是
这实际上是一个有效的电子邮件地址，做 他们选择一个宿舍，你可能最终
向上插入伪造的或只是空白数据 进入你的数据库，这可能
不会是一件好事，如果 你假设它在那里。
>> 所以这是一个恼人的现实。
但在一般情况下，客户端 验证是很大的。
但它意味着两倍的工​​作。
虽然确实存在各 库的JavaScript库
例如，使这么多， 更不用说头痛。
并且可以重复使用一些代码 服务器端，客户端。
但一定要明白，这是典型的 额外的工作。
是啊。
>> 观众：所以，如果我们只是 说不太安全 -
>> DAVID J.马兰：[笑]
唉。
那些总是更难 那些作出裁决。
>> ROB BOWDEN：那倒 已被接受。
>> DAVID J.马兰：什么？
>> ROB BOWDEN：我创造了这个问题。
这将被接受。
>> DAVID J.马兰：是啊。
>> 观众：酷。
>> ROB BOWDEN：但我们不接受 第1 -
好了，我们要找的是 像你不必
与服务器通信。
我们不接受只是速度更快。
>> 观众：怎么样 不重新加载页面？
>> ROB BOWDEN：是的。
这是一个公认的答案。
>> DAVID J.马兰：凡是我们认为 它比不太可能更容易
你知道你是什么 说，这是一个艰难的
有时行画。
使用链接列表，而不是 阵列保持的
排序的整数列表。
所以，一个颠倒，我们经常引用与链接 这促使他们的整个列表
引入是你的活力。
他们可以成长。
他们可以收缩。
所以，你不必赴汤蹈火 实际创建更多的内存
与阵列。
或者你也不必只 说，对不起，用户。
阵列被充满。
列表中的那么强劲增长。
虽然链表的缺点？
>> 观众：它是线性的。
搜索关于链表是线性的 而不是你登录。
>> DAVID J.马兰：没错。
上搜索一个链表是线性的， 即使它的排序，因为你可以
只有遵循这些面包屑，这些 指针，从列表的开始
到结束。
你不能利用随机访问和， 因而，二进制搜索，即使它是
排序，您可以 做的一个数组。
还有还有另一个代价。
是啊。
>> 观众：内存效率低下？
>> DAVID J.马兰：是啊。
好吧，我不一定会 说效率低下。
但它确实花费你更多的内存， 因为你需要32位，每
节点为额外的指针，在 至少一个单向链表。
现在，如果你只是存储整数， 您要添加的指针，这是
种不平凡的实际。
这是加倍的内存量。
但在现实中，如果你存储一个 可能有结构的链表
8字节，16字节，甚至更 重要的是，也许是少
的边际成本。
但它的成本仍然。
因此，无论是那些已经会 被罚款的缺点。
>> 18。
使用PHP，而非C + +写 一个命令行程序。
所以在这里，它往往更快的使用 如PHP或Ruby或Python语言。
你只是迅速打开 一个文本编辑器。
你有更多的功能 提供给您。
PHP有功能的厨房水槽， 而在C中，你
有非常，非常小。
事实上，家伙知道硬盘的方式 那你没有哈希表。
你不用链表。
如果你想这些，你必须 实现它们自己。
>> PHP的这么一颠倒或任何真正 解释型语言是快速性
使用它可以编写代码。
但不利的一面，我们看到这个的时候我 迅速刮起了miss​​peller
使用PHP在讲座的实施，是 在使用一种解释语言
通常比较慢。
而且我们看到，明确与 0.3秒的时间增加至3
秒，因为该解释， 实际发生的情况。
>> 另一个上攻是你 不必编译。
因此，它也加快了发展 顺便说一句，因为你没有
两个步骤来运行的程序。
你只有一个。
所以这是相当 引人注目的为好。
使用SQL数据库，而不是 CSV文件来存储数据。
因此SQL数据库用于pset7。
CSV文件你没有使用太多。
但是你用它间接pset7为 以及通过交谈雅虎财经。
>> 但CSV就像一个Excel文件，但 超级简单，这里的列
只是划出由内而外逗号 否则一个文本文件中。
并使用SQL数据库 多了几分吸引力。
这是一个颠倒的，因为你得到的东西 像选择并插入和删除。
你会得到，据推测，该索引 MySQL和其他数据库一样，
甲骨文在内存中建立你的，这 意味着你的选择可能是不
将是线性从上到下。
它实际上将是什么 像二进制搜索什么
类似的精神。
所以他们普遍较快。
>> 但缺点是， 它只是更多的工作。
这是更多的努力。
你必须了解数据库。
你必须设置它。
你需要一个服务器来运行 该数据库。
你需要了解 如何配置它。
所以这些都只是这些 各种权衡。
而一个CSV文件，你可以 用gedit创建它。
和你去好。
有没有超出复杂性。
>> 用trie树代替了哈希表 有独立的链接来存储
话让人想起字典 的pset5。
所以试图上攻，在理论上 至少，是什么呢？
固定的时间，至少如果你是 散列上每个单独的
字母词，像你 可能对pset5。
这可能是五哈希，六 哈希值，如果有五六个
字母的单词。
并就不错了。
如果有一个上限如何 长你的话可能是，这是
的确渐近常数时间。
>> 而具有独立的哈希表 链，问题出在那里与
样的数据结构是 你的算法的性能通常
取决于事物的数量 已经在该数据结构中。
而这肯定与案件 链，从而使更多的东西你把
到哈希表中，这些长 链去，这意味着在最坏
情况下，你可能会寻找的东西 是所有的方式在一个的端
那些枷锁，有效的 转予弄成线性的。
>> 现在，在实践中，它可能完全 这样的话，与一个哈希表
链是比相应的快 特里实施。
但是，这是由于各种原因，其中 这是尝试使用了一大堆
内存可以，其实，慢的东西 下来，因为你没有得到很好的
一种叫做缓存的好处， 那里的东西都是靠在一起
在存储器中可被访问。 往往更快。
有时你能想出 一个真正好的哈希函数。
即使你有浪费一点 内存，则可能确实，能够
找东西快速而且效果不 那样糟糕线性。
>> 因此，在短，存在不一定是 与上述任何一种或两种的
我们正在寻找具体的事情。
真的什么说服力 作为上行和下行
一般吸引了我们的眼球。
>> ROB BOWDEN：所以对于上升空间，我们做 不接受它自己的“更快”。您
不得不说一些事情。
即使你更快地从理论上说， 我们知道那种你明白
它的0 1。
及哈希表，从理论上讲， 不为0的1。
提及在运行什么 一般把你的分。
但“快”，大部分的解决方案上 大板，分别是尝试
客观上比慢的解决方案 这是哈希表。
所以更快本身并 是不是真的。
>> DAVID J.马兰：DOM德DOM DOM。
我可能是唯一一个实现 这是怎么说的应该
发音，对不对？
>> ROB BOWDEN：我居然不知道。
>> DAVID J.马兰：这让 感觉在我的头上。
>> ROB BOWDEN：我做这一个。
确定。
因此，这是一个在那里你不得不动用 类似于你的图可能
看到过去的考试。
所以，就让我们看看这个。
所以从HTML节点，我们有两个 儿童的头部和主体。
因此，我们分支 - 头部和身体。
头部有一个标题标签。
因此，我们有一个标题。
>> 现在，有一件事很多人 忘了的是，这些文本节点
此树中的元素。
所以在这里我们碰巧吸引他们为椭圆形 从这些区分它们
类型的节点。
但公告同时在这里我们有顶， 中部和底部最终会被
文本节点。
所以，忘记那些有点 一个常见的​​错误。
>> 人体有三个孩子 - 这三个div的。
所以格，格，格，然后在文本 这些div的子节点。
这几乎是它 该问题。
>> DAVID J.马兰：而且这是值得注意的， 尽管我们不会对这些纠缠
在我们花费的时间细节 JavaScript中，该命令呢，
事实上，无论在技术上。
所以，如果头自带的身体之前，在 HTML，那么它应该出现在
在实际的DOM离开身体。
他是，在一般情况下，刚刚仅供参考， 一些所谓的文档顺序，其中
这非常重要。
如果你正在实施一个解析器， 一个程序，在建筑读取HTML
在内存中的树，说实话， 这就是直觉可能是你
无论如何做 - 从上到下， 左到右。
>> ROB BOWDEN：该问题？
我应该做的下一个？
>> DAVID J.马兰：当然可以。
>> ROB BOWDEN：确定。
因此，这是缓冲区溢出 攻击的问题。
最主要的是要在这里认识的是， 好了，怎么可能一个对手绝招
这个程序到执行 任意代码？
所以argv1，第一个命令行 参数传递给这个程序，那可以是
任意长。
但在这里，我们用memcpy复制 argv1，在这里是酒吧。
我们把它当作参数。
所以它采取的名字吧。
>> 因此，我们memcpying吧 这个缓冲液C。
我们有多少字节复制？
然而，良好的字节酒吧恰好 可以使用，这样的说法的长度。
但c是只有12个字节宽。
因此，如果我们输入命令行参数 这比12个字节长，我们
将这个溢出 特定的缓冲区。
现在，怎么可能对手的绝招 程序执行任意代码？
>> 所以请记住，在这里 主要是调用foo。
所以当时主要调用foo。
让我们得出这样的。
因此，我们有我们的堆栈。
与主有一个堆栈帧 在底部。
在某些时候，主要调用foo。
好了，马上，主要调用foo。
所以富都有自己的堆栈帧。
>> 现在，在某些时候，富 将要返回。
又走了foo返回了，我们需要知道在 哪些代码主要我们的内线
是为了知道在哪里 我们应该恢复在主。
我们可以从整个调用foo 一堆不同的地方。
我们怎么知道从哪里回来？
好了，我们需要存储在某个地方。
>> 所以，正确的地方在这里，我们存储 在这里我们还是要回到曾经
富回报。
这是返回地址。
因此，如何对手可能利用 的是这样的事实，即
这个缓冲区C存放，让我们 说，就在这里为c。
因此，我们已经有了12个字节对​​于C。
这是C。
这是Foo的堆栈环。
因此，如果恶意用户输入更多 超过12字节或者输入命令
行参数，这比12再 字符，那么我们要
溢出这个缓冲区。
>> 我们可以继续下去。
在某些时候，我们走多远 够了，我们开始
这个覆盖返回地址。
所以一旦我们覆盖返回地址， 这意味着，当富
返回时，我们返回的地方 恶意用户告诉它
任何值它进入，以任何 字符的用户输入。
所以，如果恶意用户正在 特别聪明，他能有这样的
返回到某处printDef 功能或某处的malloc
功能，只要在任何地方随心所欲。
>> 但更巧的是什么，如果他有 用户返回到这里。
然后你开始执行 由于这些代码行。
所以在这一点上，用户可以输入 任何他想要进入这一地区。
他有完全的控制 在你的计划。
该问题？
因此，接下来的问题是完全的 富的以这样的方式重新实现
它不再是脆弱的。
>> 因此，有几种方法 你可以这样做。
我们还有C只 是长度为12。
你可以改变这 作为解决方案的一部分。
我们还增加了一个检查，以 确保酒吧是不是null。
虽然你并不需要 对于全额贷款。
因此，我们先检查 酒吧的字符串的长度。
如果是大于12，则 实际上不做副本。
所以这就是修复它的方法之一。
>> 固定它的另一种方式是代替 有C只是长度为12，拥有它
是长度函数strlen（巴）。
固定它的另一种方式是 实际上只是返回。
所以，如果你刚刚摆脱了所有的 这一点，如果你刚刚删除了所有
行代码，你会得到 全额贷款，因为该功能
实际上并没有完成任何事情。
它的复制命令行 参数为一些阵列
它的栈帧。
然后事情就是返回。
此外，无论它成功的走了。
所以回报也足够 获得全部学分的方式。
>> DAVID J.马兰：不太精神 这个问题，但每可接受
规格书号仍然。
>> ROB BOWDEN：在任何的问题？
有一件事，你至少 需要已编译代码。
因此，即使在技术上你是不是 脆弱的，如果您的代码不
编译，我们不接受。
没有问题？
确定。
>> DAVID J.马兰：你想 说这个称号？
>> ROB BOWDEN：号
>> DAVID J.马兰：所以在这一块，这 无论是好消息还是坏消息。
这是字面上相同的问题 作为第一次测验。
而且它几乎是相同的 问题是PSET1。
但它被刻意简化为 一个更简单的金字塔，一个可
解决了用微 简单的迭代。
真的，我们都拿到在 这里是没有那么多的逻辑，
大概是因为，通过这一点，你 比你更舒适
在一个用for循环或循环为什么一周， 但真正捉弄除了那
你有点舒服的 概念，PHP是不只是什么
编程。
它实际上可以被用来作为一种语言 写命令行程序。
>> 事实上，这正是我们试图 提请你注意。
这是一个PHP命令行程序。
因此，这里的C代码，而正确的 在C中，不正确的PHP。
但是代码确实是相同的。
如果你比较对测验的解决方案 0反对测验1，你会发现，
它几乎是相同的，除了 一些美元符号和对
缺少数据类型。
特别是，如果我们看看这里， 你会看到，我们遍历，在这
情况下，从1到7。
>> 我们可以做它0指数。
但有时候，我认为这只是 精神上更容易思考的东西
从1到7。
如果你想有一个街区，然后两个 块，然后三，然后
点，点，点7。
我们已经j为初始化为1 然后指望达我。
而这里的一切 否则相同。
但值得注意的是 一对夫妇的事情。
我们给你这两条线，这首 1，goofily命名为家当
对于尖锐的爆炸。
而这只是指定的路径中， 文件夹，在其中一个程序可以
发现要使用 解释这个文件。
>> 和随后的线路之后， 当然，是指进入PHP模式。
和线在最底层 表示退出PHP模式。
而这个工程，在一般情况下，与 解释型语言。
这有点恼人，如果你写了一个 计划在一个名为foo.php文件。
然后你的用户要的只是 记住，好了，运行这个程序，我
必须输入“php空间foo.php。”样 恼人的，如果没有别的。
同时也表明你的程序 是用PHP编写的，这是不是所有的
该照射的用户。
>> 这样你就可以完全消除。PHP 从讲座召回。
而你实际上可以做。/ foo的，如果 你通过使已经chmodded它
可执行文件。
因此存取权限chmod a + X富会做的。
如果你也在这里添加家当。
不过说真的，这个问题是越来越在 打印出这样的事情。
没有HTML，没有C代码肯定， 只是一些PHP。
所以米洛然后在问题25返回。
而在25日，你被赋予以下 框架代码，这是一个
很简单的网页。
而多汁部分的HTML明智下跌 这里，我们有身体的内部
具有输入唯一ID的形式 其内部是两个输入，一个
同的名称，1的想法 与按钮的想法。
>> 第一个是文本类型的 类型的第二提交。
因此，我们给了你，其实，更 比你需要的，只是这样的成分
你们有选择与 来解决这个问题。
你并不需要严格 所有这些ID的。
但它可以让你解决 它以不同的方式。
并在顶部，注意 的目的是为了触发
像这样的窗口 -
您好，米洛！ -
使用弹出的浏览器 超级简单，如果
不丑，报警功能。
所以，最终，这归结 概念以某种方式监听
表单的客户端提交的材料 ，而不是服务器端的，不知何故
要答复意见书 抓住用户键入的值
在Name字段，然后 在警告的正文中显示它。
>> 所以，你可以做到这一点的方法之一是用 jQuery的，看起来有点
语法傻了眼在第一。
为此，您可以用纯DOM代码 - 通过ID document.getelement。
但是，让我们来看看这个版本。
我有几个重要的 行第一。
这么一句，我们这行，这是 相同的你可能已经看到
在，我相信，form2.html 从类中第9周。
这只是说，执行 下面的代码时，
该文件已准备就绪。
这是重要的，因为只有 HTML页面顶部读
底，左到右。
>> 因此，如果你尝试做 东西在这儿代码在一定的DOM
元素，一些HTML标签，这就是下降 在这里，你这样做为时过早，
因为这并没有什 被读入内存。
所以说这样的document.ready 行，我们在说，
这里的一些代码，浏览器。
但不执行此操作，直到整个 文档准备好，即在DOM
树存在于内存中。
这一个是多一点 直截了当，如果一个语法
有点不同，这里我说的，抢 在HTML元素，其独特的
标识符输入。
这就是散列标签 表示，唯一ID。
然后我打电话。提交。
>> 因此，这里提出的是一个函数，否则 已知作为一种方法，这就是
在左侧的对象的内 一边有，我没有强调。
所以，如果你想输入作为一个对象 在内存中 - 实际上它是。
这是在一个树中的节点 -
。提交的手段时，这种形式与 这个ID被提交后，执行
下面的代码。
我不在乎什么的名字 功能是我执行。
所以在这里我使用的，和以前一样，有什么 被称为lambda函数或
匿名函数。
它不是在所有智力 有趣以外它没有名字，
这是好的，如果你只 永远要调用它一次。
里边有我真正处理 提交表单。
我首先声明一个变量 所谓的价值。
然后这个是什么效果 这里突出部分吗？
这是什么做的一 高层给我吗？
>> 观众：它得到的值的 用户在下面的HTML没有。
它得到的ID，然后 发现它的价值。
>> DAVID J.马兰：没错。
它抓住节点，其独特的 标识符名称。
它得到了其中的价值，这 是，据推测，什么样的用户
键入他或她自己。
然后将其存储在该 变量称为价值。
顺便说一句，你可以有也 这样做有点不同。
通过做一些完全可以接受 谎言的VaR值，得到
的document.getElementById。
这就是为什么它是一个小 乏味，不使用jQuery的。
“名”。值。
所以完全可以接受的。
不同的方法来做到这一点。 jQuery的刚 往往是多了几分简洁和
肯定更受欢迎 间的程序员。
>> 现在，我正在做一个有点理智的 检查一下，因为在这个问题
声明中我们明确地说，如果 用户尚未键入他或她的
名，不显示一个警报。
但你可以检查，通过刚 检查一个空字符串
报价引文结束，如果有 什么居然还有。
但如果它不等于报价引文结束， 我想打电话报警。
这里最有趣的部分是， 我们使用加运算符，
在JavaScript中做什么？
串连。
所以它就像PHPS点运算符。
同样的想法，稍有不同的语法。
而我只是在创建字符串 你看到了屏幕截图 -
您好，某某。
>> 然后最后的细节是这样的。
为什么我返回false内 这个匿名函数？
>> 观众：有没有价值。
你把它的形式。
它只是说，如果值不 等于空白，然后再去做。
有在提交的一项空白。
>> DAVID J.马兰：确定。
小心，虽然。
有没有一个人在这里。
并且返回false是外 的if条件。
因此，这突出显示的行，返回false， 执行不管是什么时候
表单被提交。
什么是回国这里面的假 事件处理程序，因为它叫，
在有关活动 被提交？
>> 观众：因为它 只发生一次。
>> DAVID J.马兰：只发生一次。
不完全是。
是吗？
>> 观众：它防止表单 提交到默认的行为，
这样就会使页面重载。
>> DAVID J.马兰：没错。
所以我对超载提交一词在这里， 因为我说的，形式是
提交。
但如你所说，它实际上不是 在提交的真实的HTTP方法被。
当您点击提交，因为，我们的 onsubmit处理，我们正在拦截
该表单提交可以这么说。
我们然后做我们的事 与JavaScript代码。
但我故意返回false， 因为我不希望发生的一
一瞬间之后，是为整个表格 本身提交到网上
服务器与键值对通过改变 是类似的URL
Q =猫，或任何我们所做的， 例如，在课堂上。
我不希望这样的事情发生，因为 有没有这个问题的服务器监听
表单提交。
这是纯粹的JavaScript代码完成。
这就是为什么我什至没有一个 action属性的窗体上，因为我
没有为这个打算 曾经去到服务器。
>> 因此，它被提交。
但是我们截取该表单 提交并防止默认
的行为，这是实际 走一路到服务器。
>> 观众：所以保持它的客户端。
>> DAVID J.马兰：保持 它的客户端。
完全正确。
接下来是我的哦MySQL的。
>> ROB BOWDEN：确定。
所以这第一个问题通常是 粗糙的人。
虽然后来者去更好。
所以，你必须选择正确的数据 类型这两个列。
和这两个有一定 关于他们的事情，
做出选择很难。
所以整数是不是一个有效的 键入数字。
究其原因是一个12位帐号 数，一个int是不是足够大的
存储总位数。
因此，一个有效的选择将是一个很大的 如果你碰巧知道INT。
另一种选择可能是 长度12的字符字段。
因此，无论是那些会工作。
诠释不会。
>> 现在，平衡，回想着pset7。
所以我们专门用于十进制 储存的股份或价值 -
>> DAVID J.马兰：现金。
>> ROB BOWDEN：现金。
我们使用十进位存储量 现金用户目前拥有。
所以我们这样做的原因是 因为，记住，浮在水上。
有没有在精度浮点。
它不能精确地存储的现金 像我们想要的值在这里。
所以，十进制是能够精确地存储 东西，说，小数点后两位。
这就是为什么平衡，我们希望它 为十进制数，而不是浮动。
>> DAVID J.马兰：此外，他也一样，虽然 它可能在其他被聪明
上下文去思考，也许这 是一个int的机会。
我就继续跟踪 事情便士。
因为我们明确地显示了默认 的是100.00，值
意味着它可能仅仅是一个int。
而另一个微妙过与数 是，这并不意味着
是一个棘手的问题。
但记得，在MySQL的一个int， 像在C中，至少在
家电，是32位的。
而且即使我们不指望你来 确切地知道有多少位数的
手段，千万记得最多 你可以代表可能
一个32位数字大致是怎样的？
>> 什么号码我们老是说什么？
2至32，这是大约？
你不必知道准确。
但大致是在生活中有所帮助。
这是约4十亿。
因此，我们说了几次。
我知道我已经说过，几十倍。
它是约4十亿。
这就是一个很好的规则 拇指就知道了。
如果你有8位，256 是一个神奇的数字。
如果你有32位，4 十亿给予或采取。
所以，如果你只写下跌4十亿， 你会看到它的位数少于
12，表示这显然不 够表现来捕获
12位帐号。
>> ROB BOWDEN：确定。
所以其他的人去比较好。
因此，假设银行 规定了每月20元
维修收费标准上的所有帐户。
用什么SQL查询可以在银行 从每一个计数中扣除20元，就算
它会导致一些负面的余额？
因此，基本上，有四个 查询的主要类型 -
插入，选择，更新和删除。
那么，我们认为我们 要在这里使用？
更新。
>> 因此，让我们一起来看看。
所以在这里，我们要更新。
我们要更新什么表帐户？
所以更新账户。
然后语法说什么 帐户被我们更新？
好了，我们设置的平衡等于 余额减去20的电流值。
因此，这将更新所有行 帐户，减去
20美元的余额。
>> DAVID J.马兰：这里一个常见的​​错误， 即使我们有时会原谅它，
是实际上这里有PHP代码 调用查询功能，或将
周围的一切引号的 并不需要在那里。
>> ROB BOWDEN：请记住，MySQL是 从PHP一个独立的语言。
我们碰巧在PHP中要编写的MySQL。
和PHP，然后送它 在MySQL服务器。
但你不为了需要使用PHP 与MySQL服务器进行通信。
>> DAVID J.马兰：没错。
所以没有带美元符号变量 应于该上下文。
它可以做所有的数学 在数据库本身。
>> ROB BOWDEN：确定。
所以，下一个。
这是下一个？
是啊。
所以用什么SQL查询可以在银行 其检索的帐号
最丰富的客户，那些与 余额大于1,000？
所以这四个主要类型 我们要在这里想要什么？
选择。
所以，我们要选择。
我们究竟要选择？
我们想要怎样栏选择？
我们会特别希望 选择号码。
但是，如果你说的明星，我们 也接受这一点。
>> 那么从​​什么表中选择号码？
帐户。
然后条件，我们想要的吗？
凡结余超过1000人。
我们也接受更大 小于或等于。
最后一个。
用什么SQL查询可以在银行 接近，即删除每一个帐户
有$ 0的平衡？
因此，这四个是我们 会想使用？
删除。
所以，语法是什么？
从什么表中删除？
帐户。
然后在其上的条件 我们想删除 -
其中平衡等于零。
因此，从账户中删除所有行 当余额为零。
对上述任何一个问题？
要排队？
>> DAVID J.马兰：队列指南。
所以在这一块，我们给你一个有点 熟悉的结构，我们探索出了
在课堂位旁边的结构， 这是一个数据
结构中的精神有关。
虽然与队列的区别是 我们必须以某种方式记得是谁
是在队列的前面，在大 一部分这样我们就可以赚更多
有效地使用存储器，至少 如果我们用一个数组。
>> 因为召回，如果我们有一个数组，如果， 举例来说，这是前部
队列中，如果我进入队列这里， 然后有人得到一致
我，在我身后，在我身后，后面 一个人走出行，你
可以，因为我们看到了一些我们人类的 在课堂的志愿者，让每个人都
转向这种方式。
但在一般情况下，大家有做 自己是不是时间的最佳利用
在程序中，因为这意味着你的 算法在运行什么
渐近运行时间？
它是线性的。
>> 我觉得这是种愚蠢的。
如果下一人行是下一个 人谁的应该进入
商店，他们不都 一起移动。
只是让那人被人拔光了 在时机成熟时，例如。
这样既可以节省一点时间在那里。
所以要做到这一点，那就是说 该队列的头部或
该队列的前面是要 逐步移动越陷越深
到阵列中，并最终可能 实际上环绕，如果我们使用的是
数组来存储人 在此队列中。
所以你几乎可以想到的 数组作为循环数据
结构在这个意义上。
>> 所以，你无论如何都必须跟踪的 它的大小或它的真正结束
然后在那里它的开始是。
因此，我们建议您声明 一个这样的队列，呼叫
它Q，只是一个字母。
然后，我们建议把前面是 初始化为零，并且大小
初始化为零。
>> 所以现在，没有什么 里面的那个队列。
我们要求你完成 在下面执行的入队
这样一种方式，该函数将n到 q的末尾，然后返回true。
但是，如果q是满的或负的，本 函数应该改为返回false。
我们给你一对夫妇 假设。
但他们并不是真正的功能 相关的，刚才那布尔存在，
因为，从技术上讲，布尔不 存在于C，除非你有一个
某些头文件。
所以这只是确保有 没有了这是一招
问题之类的话。
>> 所以排队，我们的样本中提出的 解决方案来实现，如下所示。
一，我们首先检查方便， 低悬的果实。
如果队列已满或数 你试图插入小于
大于零，这是我们在所述 规范的问题应
不会被允许的，因为我们只想要 非负值，那么你应该
只是立即返回false。
因此，一些相对容易 错误检查。
如果你虽然想补充的是，实际 号，你不得不做一点
想在这里。
而这正是它是一个有点讨厌 弱智，因为你必须
弄清楚如何处理环绕。
>> 但这个想法的萌芽在这里，是的 我们感兴趣的是，环绕
往往意味着模运算和 mod运算符，百分比方面，
在那里你可以从一个较大的值 回零，然后一个及两个
3，然后绕回至零， 1和2和3等
一遍又一遍。
因此，我们建议这样做的方法是 那不是我们不想索引到
阵列被叫号码所在 我们的整数说谎。
但到那里，我们首先想要做的 无论队列的大小是但
然后添加到无论 在列表的前面是。
和其效果是把我们 在队列中合适的位置和
不要以为在线路的第一人 是在开始时，他或
她绝对可以，如果我们 也被转移大家。
但我们只是创建工作 为了我们自己，如果我们把
该特定路径。
>> 所以我们可以保持它相对简单。
我们必须记住，我们只是 添加一个int到队列中。
然后我们就返回true。
同时，在出队，我们问 你要做到以下几点。
实现它以这样一种方式，它 出队，那就是移除并返回，
整型在队列的前面。
要取出整数，它满足 忘记它。
你并不需要覆盖其位。
因此，它实际上仍然存在。
就像一个硬盘上的数据， 我们只是忽略了一个事实
它现在在那里。
而如果q是空的，我们应该 而不是返回负1。
所以这种感觉随心所欲。
为什么返回负1 而不是假的？
是啊。
>> 观众：Q被存储 正值。
既然你只存储正值 在第q，负是一个错误。
>> DAVID J. MALAN：好，真的。
所以，因为我们只存储正 值或者为零，那么它的罚款
返回一个负的值作为定点 值，特殊符号。
但你重写历史上， 因为我们是唯一的原因
返回非负值 是因为我们要
有一个标记值。
所以，更确切地说，为什么不干脆 在错误的情况下返回假的？
是啊。
>> 观众：你已经失败 返回一个整数。
>> DAVID J.马兰：没错。
这就是其中C得到 漂亮的制约。
如果你说你要去 返回一个int，你有
返回一个int。
你不能花哨，并开始返回 一个bool或浮或
字符串或类似的东西。
现在，与此同时，JavaScript和PHP和 其他一些语言可以，其实，
你有不同的返回 类型的值。
而这实际上是有用的，其中 你可以返回正整数，零，
负整数，或虚假或无效 甚至表示错误。
但是，我们没有这方面的 多功能性C.
>> 因此，与出队，我们什么 建议做的是 -
>> ROB BOWDEN：你可以返回false。
这只是虚假的散列 定义虚假为零。
所以，如果你返回false， 你返回零。
零是一个有效的事情在我们的队列中， 而负1是不是如果
假正好是负1。
但你应该甚至不 需要知道。
>> DAVID J.马兰：这是 为什么我没有说出来。
>> ROB BOWDEN：但它是不是真的 你不能返回false。
>> DAVID J.马兰：当然可以。
所以出队，发现我们接受 丧失作为它的参数。
那是因为我们不是 递东西英寸
我们只是要移除的元素 在队列的前面。
那么我们如何能够去这样做？
嗯，首先，让我们这样做 快速完整性检查。
如果队列大小为0，有 没有工作要做。
返回负1。
Done（完成）。
所以这是我的程序几行。
因此，只有四行依然存在。
>> 所以在这里我决定递减 的大小。
并有效地递减的大小 也就是说，我忘了
东西就在那里。
但我也有更新的地方 数字的前面是。
因此，要做到这一点，我需要 做两件事情。
我首先需要记住的数量 是在该队列的前面，
因为我需要返回那个东西。
所以我不想忘记意外 关于它，然后覆盖它。
我只是要记得在一个int。
>> 而现在，我要更新 q.front被q.front +1。
因此，如果这是在第一人称 行，现在，我想要做加1
指向下一个人行。
但是，我必须处理回绕。
如果能力是一个全局常量， 那将让我确定
当我点到最后的人 线，该模运算将带来
我回零的 前面的队列。
而且这里处理环绕。
然后我继续返回否。
>> 现在，严格地说，我没有 必须声明ñ。
我没有抓住它并将其存储 是暂时的，因为该值是
仍然存在。
所以我只能做正确的算术 返回前负责人
队列。
但我只是觉得这是更清晰 实际上抢整数，把它
以n，然后返回 为清晰起见，但
不是严格必要的。
嘘。
他们都是发音的在我的脑海。
>> ROB BOWDEN：所以第一个问题 是二叉树的问题。
所以，第一个问题是，我们是 考虑到这些数字。
我们希望以某种方式将它们插入到 这些节点，例如，它是一个
有效的二叉搜索树。
所以，有一点要记住的 二叉搜索树是它的不
刚才说的事情向左移 少与事
右边是更大的。
它需要整个树 左边是更小，并且在整个树
向右更大。
>> 所以，如果我把34在此间举行的顶部，然后 我把20在这里，所以这是有效的，
到目前为止，因为34在这里。
20是要在左边。
所以这是少。
但我不能再放入59在这里，因为 尽管图59是对20的右侧，
它仍然在34的左边。
因此，在这该约束时， 大概解决这个最简单的方法
问题是，只是排序 这些数字 -
所以20，34，36，52，59，106。
然后将这些 从左至右。
>> 所以20放在这里。
34放在这里。
36放在这里。
52，59，106。
你也可以想通了与 有些堵塞和实现，
哦，等一下，我没有足够的数字 填补这个在在这里。
所以我需要reshift我什么 路线音符将是。
但是请注意，在最后三，如果 你读从左至右，它是在
递增的顺序。
>> 所以，现在，我们想声明的是什么 结构将是为
在这棵树的节点。
所以，我们需要在一个二叉树是什么？
因此，我们有类型的值 整型，所以一些int值。
我不知道我们所谓的 它在溶液中 -
INT N。
我们需要一个指向左边的孩子 和一个指向右边的孩子。
所以它会看起来像这样。
它会实际上看前 什么时候的双向链接
列表的东西，所以通知 -
我将不得不滚动所有 方法回落到问题11。
>> 所以发现它看起来相同这一点， 除了我们只是碰巧调用这些
不同的名称。
我们还有一个整数 值和两个指针。
它是这样的态度对待这一点的 作为指针指向的下一件事
和以前的事情，我们正在处理 该指针指向一个左子
和右孩子。
确定。
所以这是我们的结构节点。
而现在，唯一的功能，我们需要 实施这是遍历，这
我们要越过树，印刷 从树上，以便这些值。
>> 所以在这里看，我们要打印 出20，34，36，52，59，和106。
我们如何实现这一目标？
所以这是非常相似的。
如果你在过去的考试，看到了问题 你想打印出
整个树用逗号之间 一切，它实际上是连
比这更容易。
因此，这里的解决方案。
这是显著更容易 如果你递归地做到了。
我不知道是否有人试图 要反复做。
>> 但首先，我们有我们的基本情况。
如果哪根是空？
然后，我们只是要回。
我们不希望打印出任何东西。
否则我们将遍历 递归下降。
打印整个左子树。
所以打印较少的一切 比我的当前值。
然后我要打印我自己。
然后，我要向下递归我 整个右子树，所以一切
比我的价值更大。
这是要打印 出一切为了。
这个实际上是怎样的问题 完成了吗？
>> 观众：我有一个问题 在[听不清]。
>> ROB BOWDEN：逼近所以单程 任何递归的问题是只是觉得
它喜欢你不得不思考 所有的角落案件。
因此认为，我们要 打印此整个树。
所以我们要专注于 就是这个特殊的节点 -
36。
递归调用，我们假装 那些只是工作。
所以在这里，这个递归调用 遍历，我们甚至没有想到
关于它，只是遍历左 3，假设已经打印20
34我们。
然后当我们最终递归 遍历调用的
右，这将正确打印 52，59，106我们。
>> 所以考虑到这可以打印20，34，和 另可打印52，59，108，
所有我们需要能够做的就是打印 我们自己在那中间。
因此，摆在我们面前打印出来的一切。
打印我们自己，所以当前节点的打印 36，定期的printf，然后
之后，我们打印了一切。
>> DAVID J.马兰：这是递归 变得非常漂亮。
这是信仰的这个惊人的飞跃，其中 你做的工作哪怕一丁点。
然后你让别人 别人做休息。
和别人 是，讽刺的是，你。
因此，对于严重的印象分，如果 你向上滚动的问题 -
>> ROB BOWDEN：在的问题呢？
>> DAVID J.马兰：上下了多大 这些数字，有没有人知道在哪里
这些数字从何而来？
>> ROB BOWDEN：我简直不知道。
>> DAVID J.马兰：他们似乎 整个测验。
>> 观众：他们是相同的号码？
>> DAVID J.马兰：这些数字。
有点复活节彩蛋。
因此，对于那些你在网上看 回家，如果你可以通过电子邮件告诉我们
heads@CS50.net什么意义 这些反复出现的六个号码是
整个测验1，我们将沐浴你 以惊人的注意力在最后
演讲和一个压力球。
美观大方，含蓄。
>> ROB BOWDEN：最后还有什么问题 关于测验什么？