news 2026/10/24 3:58:40

MIT 6.005 软件构建讲义(七)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MIT 6.005 软件构建讲义(七)

parsePitch : String → Pitch(MusicLanguage.java:77) 通过解析pitch语法产生来返回一个Pitch。你应该能够理解递归 — 基本情况是什么?递归情况是什么?

阅读练习

parsePitch

parsePitch的基本情况处理这些输入中的哪些?

(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)

(缺少解释)

实现播放器

回想一下我们播放音乐的操作:

play : Music × SequencePlayer × double → void(Music.java:18) 在给定节拍延迟之后,使用给定的序列播放器播放音乐片段。

为什么这个操作要花费atBeat?为什么不直接现在播放音乐呢?

如果我们以这种方式定义play,那么除非我们实际上在play操作期间暂停,例如使用Thread.sleep,否则我们将无法随时间播放音符序列。我们的序列播放器的addNote操作已经设计好了以安排未来的音符 - 它处理延迟。

有了这个设计决定,就可以在每个Music变体中轻松实现play。

阅读并理解Note.play,Rest.play,以及Concat.play方法。

你应该能够理解它们的递归实现。

在我们准备好进行即兴演奏之前,再加一点实用代码:music.midi.MusicPlayer使用MidiSequencePlayer播放Music。Music不知道序列播放器的具体类型,因此我们需要一些代码将它们联系起来。

将所有内容整合在一起,让我们使用MusicADT:

阅读并理解music.examples.ScaleMusic代码。

运行ScaleMusic中的主方法。你应该再次听到同一个一个八度音阶。

那并不是很令人兴奋,所以阅读music.examples.RowYourBoatInitial并运行主方法。你应该听到Row, row, row your boat!

你能够从调用notes(..)到拥有Music实例再到递归play(..)调用再到单独的addNote(..)调用的代码流程吗?

阅读练习

音符

Row, row, row your boat中有 27 个音符。

根据实际实现,RowYourBoatInitial中的notes调用将创建多少个Music对象?

(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)

(缺少解释)

持续时间

rowYourBoat.duration()的结果应该是什么?

(缺少答案)

(缺少解释)

音乐

假设我们有

import music.*; import static music.Instrument.*; import static music.MusicLanguage.*;

并且

Music r = rest(1); Pitch p = new Pitch('A').transpose(6); Music n = note(1, p, GLOCKENSPIEL); List<Music> s = Arrays.asList(r, n);

以下哪个是有效的Music?

(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)

(缺少解释)

未完待续

弹奏Row, row, row your boat是非常令人兴奋的,但到目前为止,我们所做的最强大的事情并不是音乐语言,而是非常基础的音乐解析器。使用简化的 abc 记谱写音乐显然比一页页写addNoteaddNoteaddNote更易于理解,免受错误的影响,并且随时可以更改。

在课堂上,我们将扩展我们的音乐语言,并将其转化为一个构建和操纵复杂音乐结构的强大工具。

阅读 27:团队版本控制

6.005 中的软件

| 免受错误影响 | 易于理解 | 准备好变化 |

| — | — | — |

| 今天正确,未来也正确。 | 与未来的程序员清晰沟通,包括未来的自己。 | 设计以适应变化而无需重写。 |

目标
  • 复习 Git 基础知识和提交图

  • 练习多用户 Git 场景

Git 工作流程

您已经使用 Git 进行问题集和课堂练习一段时间了。大多数情况下,您不必与其他人协调推送和拉取到同一存储库,并且与您同时进行。对于团队项目,情况将发生变化。

在本阅读中,通过回顾您所了解的内容并熟悉一些命令,为课堂 Git 练习做好准备。现在您对 Git 基础知识更加熟悉,是时候回顾本学期初的一些资源了。

查看发明版本控制:一个开发人员,多个开发人员和分支。

如果需要,可以查看学习 Git 工作流程来自入门页面。

查看提交历史

从Pro Git中查看**2.3 查看提交历史**。

您不需要记住书中介绍的所有不同命令行选项!相反,了解可能的操作,这样当您需要时就知道要搜索什么。

从版本控制克隆示例存储库:

https://github.com/mit6005/fa16-ex05-hello-git.git

使用log命令确保您了解存储库的历史。

提交的图表

请记住,Git 存储库中记录的历史是一个有向无环图。存储库中任何特定分支(如默认的master分支)的历史始于某个初始提交,然后如果多个开发人员并行进行更改(或者单个开发人员在切换之前在两台不同的机器上工作而没有提交-推送-拉取),则其历史可能会分裂并重新汇合。

这是示例存储库的git lol输出,显示了一个 ASCII 艺术图:

* b0b54b3 (HEAD, origin/master, origin/HEAD, master) Greeting in Java * 3e62e60 Merge |\ | * 6400936 Greeting in Scheme * | 82e049e Greeting in Ruby |/ * 1255f4e Change the greeting * 41c4b8f Initial commit

这里是 DAG 的图表:

http://web.mit.edu/6.005/www/fa16/classes/27-team-version-control../05-version-control/figures/hello-git-history-trees.png

在ex05-hello-git示例存储库中,确保您能解释master历史何时分裂,何时重新汇合。

从版本控制阅读中查看合并。

您应该理解整个过程的每一步,以及它与示例存储库中的结果之间的关系。

查看合并部分,包括合并和合并冲突。

阅读练习

合并

Alice 和 Bob 都从相同的 Java 文件开始:

public class Hello { public static void greet(String name) { System.out.println(greeting() + ", " + name); } public static String greeting() { return "Hello"; } }

| Alice 更改greet(..):

public static void greet(String name) { System.out.println(greeting() + ", " + name + "!"); }

| Bob 改变greeting():

public static String greeting() { return "Ciao"; }

|

(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)

(缺失解释)

危险的合并在前方

相同的起始程序:

public class Hello { public static void greet(String name) { System.out.println(greeting() + ", " + name); } public static String greeting() { return "Hello"; } }

| Alice 改变greeting():

public static String greeting() { return "Ciao"; }

| Bob 改变了函数如何一起工作:

public static void greet(String name) { greeting(); System.out.println(", " + name); } public static void greeting() { System.out.println("Hello"); }

|

(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)

(缺失解释)

继续合并

相同的起始程序:

public class Hello { public static void greet(String name) { System.out.println(greeting() + ", " + name); } public static String greeting() { return "Hello"; } }

Alice 改变greet(..)以返回而不是打印:

public static String greet(String name) { return greeting() + ", " + name; }

Bob 创建了一个新文件,Main.java:

public class Main { public static void main(String[] args) { // print a greeting to Eve Hello.greet("Eve"); } }

(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)(缺失答案)

(缺失解释)

在团队中使用版本控制

每个团队都为版本控制制定了自己的标准,团队的规模和他们正在处理的项目是一个主要因素。以下是适用于你将在 6.005 中进行的小范围团队项目的一些指导方针:

  • 沟通。告诉您的队友您将要做什么。告诉他们您正在做这件事。告诉他们您已经做过了。沟通是避免浪费时间和精力清理破损代码的最佳方式。

  • 撰写规范。对于我们在 6.005 中关心的事项是必要的,也是良好沟通的一部分。

  • 编写测试。不要等待大量代码堆积起来才尝试进行测试。避免一个人编写测试,另一个人编写实现(除非实现是你计划放弃的原型)。首先编写测试以确保您对规范的理解一致。每个人都应对其代码的正确性负责。

  • 运行测试。如果不运行测试,测试是无法帮助您的。在开始工作之前运行它们,再次在提交之前运行它们。

  • 自动化。您已经使用像 JUnit 这样的工具自动化了您的测试,但现在您希望在项目更改时自动运行这些测试。对于 6.005 组项目,我们提供 Didit 作为一种在团队成员向 Athena 推送时自动运行测试的方式。这也消除了“它在我的机器上运行正常”的问题:它要么在自动构建中正常工作,要么需要修复。

  • 检查您提交的内容。使用git diff --staged或 GUI 程序查看您即将提交的内容。运行测试。不要使用commit -a,这是填充您的仓库与println和其他您不打算提交的内容的绝佳方式。不要通过提交无法编译、产生调试输出、实际上未使用等代码来惹恼您的队友。

  • 开始工作前先拉取最新版本。否则,您可能没有最新版本作为起点 —— 您正在编辑旧版本的代码!您肯定要稍后合并您的更改,并且有可能浪费时间解决合并冲突。

  • 同步。在一天结束或工作会话结束时,确保每个人都已推送和拉取所有更改,大家都处于相同的提交状态,并且每个人对项目状态满意。

我们不建议在 6.005 大型项目中使用分支或变基等功能。

我们强烈建议在同一时间、同一地点一起工作,特别是如果这是你第一次进行团队软件工程体验。

阅读练习

团队版本控制

这些哪些展示了良好的团队软件开发实践?

(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)(缺少答案)

(缺少解释)

团队项目

项目阶段的大部分课时将用于团队合作。

这些课程是必修课,就像普通课程一样,你必须在课堂上与你的项目导师 TA 进行沟通。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 6:45:11

循环队列实现与面试全攻略:从环形数组到边界处理

如果你在准备面试&#xff0c;拿到“循环队列怎么实现”这道题&#xff0c;恭喜你&#xff0c;这是一道性价比极高的常考题——前提是你真把它想明白了。我第一次在美团一面碰到这题时&#xff0c;第一反应是“教科书上的数组队列改一改就完事”&#xff0c;结果在“队空和队满…

作者头像 李华
网站建设 2026/10/14 21:19:31

dll缺失修复全攻略:避开全家桶陷阱,官方工具与实操步骤详解

你用着正欢的软件突然弹窗“由于找不到 xxx.dll&#xff0c;无法继续执行代码”&#xff0c;或者游戏启动时提示“缺少 d3dcompiler_47.dll”&#xff0c;大概率会先一愣&#xff1a;dll 是个啥&#xff1f;为啥会缺&#xff1f;更烦人的是百度一搜“dll修复工具”&#xff0c;…

作者头像 李华
网站建设 2026/10/19 17:23:13

Python程序员必会的Linux命令实战:从部署到排查

我认识的大部分Python程序员&#xff0c;真正开始啃Linux命令往往是被一次线上事故逼出来的。本地跑得好好的脚本&#xff0c;一上服务器就报ModuleNotFoundError&#xff1b;代码部署完进程找不到踪影&#xff1b;端口被占用了翻遍日志也没头绪。这时候才会意识到&#xff0c;…

作者头像 李华
网站建设 2026/10/15 5:18:34

.NET MAUI版本详解:从.NET 6到.NET 9的选型与迁移指南

做.NET客户端开发的朋友&#xff0c;这两年应该没少听到.NET MAUI这个名字。不管是新项目选型&#xff0c;还是老项目从Xamarin.Forms迁移&#xff0c;最终都会绕到同一个问题上&#xff1a;MAUI各个版本到底都有啥用&#xff1f;我见过太多人一上来就选.NET 8&#xff0c;结果…

作者头像 李华
网站建设 2026/10/15 11:23:39

ntpwedit 0.7 源码解析:C++ 离线修改 Windows SAM 密码哈希实战

简介&#xff1a;NTPWEdit 0.7 是一款通过直接修改 SAM 文件来重置或删除本地系统账户密码的开机密码更改工具&#xff0c;本资源为其完整 C 源码包&#xff0c;面向需要研究 Windows 密码机制、二次开发或定制 PE 维护工具的开发者与系统运维人员。压缩包共 85 个文件&#xf…

作者头像 李华