概念


概念是程序员要想流利使用一门语言所必须理解的内容。概念由概念练习来教授,并作为概念练习和实践练习的前置条件。概念展示给学生时,会被放到概念图上。

元数据

概念元数据定义在 config.json 文件的concepts键中。元数据定义了概念的 UUID、slug 等信息。

示例

{
  "concepts": [
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers"
    }
  ]
}

文件

在轨道的concepts目录中,每个概念都有自己的目录。概念目录的名称必须与概念的slug属性一致,该属性定义在 config.json 文件中。

概念有两种类型的文件:

文档文件

这些文件会展示给学生,用于帮助解释概念。

  • about.md:为已经完成对应概念练习的学生提供关于该概念的信息,供其学习和日后查阅(必需)
  • introduction.md:为尚未完成对应概念练习的学生提供简要介绍(必需)
  • links.json:提供有助于进一步阅读或了解某个概念的实用链接(必需)

元数据文件

这些文件不会展示给学生,而是用于定义概念的元数据。

  • .meta/config.json:包含概念的元信息(必需)

示例

concepts
└── numbers
    ├── .meta
    |   └── config.json
    ├── about.md
    ├── introduction.md
    └── links.json

文件:about.md

用途: 为已经完成对应概念练习的学生提供关于该概念更详细的信息,供其学习和日后查阅。

是否必需: 必需

完成对应的概念练习(也就是“学会”某个概念)后,概念页面将显示about.md文件的内容,而不再显示introduction.md文件。about.md文件应全面提供学生要流利掌握该概念所需了解的信息。至少,该文件应包含概念 introduction.md 文档中介绍的所有信息。

如果该概念引入了新语法,就应包含语法示例。学生不应为了获得文件想要传达的知识而点开大量链接。相反,about.md应包含足够的信息,使其在自身语境中就能被理解。

about.md文件并不局限于对应概念练习的范围。内容可以要求读者掌握之后才会介绍的其他概念。如果提到了其他概念,就应链接到它们各自的介绍文档(详见内部链接)。

以下是可能涵盖的一些示例。

  • 某个概念的常见用法
  • 使用某个概念时常见的坑(例如没有考虑线程安全)
  • 可能让毫无戒心的开发者栽跟头的使用限制
  • 其他概念中涉及的其他做法(例如递归概念可能会提到,高阶函数概念为类似问题提供了另一种做法)
  • 为便于学习或适应 Exercism 环境而做出的妥协,例如在单个文件中放入多个类
  • 该概念可能与之混淆的相似特性
  • 性能特点和内存占用,当它们在该语言中是常见考量时
  • 不要在正文中提及某道练习,因为该文件是在练习的语境之外展示的。

about.md文件的目的不在于提供关于该概念的一整套完整信息。举个例子,假设某门语言有一些较旧的特性,经验丰富的程序员(甚至可能是官方文档/规范)建议不再使用它们。详细介绍这类特性超出了about.md文件的范围,因为它们与获得流利度无关。不过,如果学生常常会在实际中遇到这些旧标准,维护者可以选择加上一小段来提及它们。但这一段应加以标注。

about.md文件必须结构清晰,尤其是在包含大量信息时。将来还会支持把某些部分标记为“进阶主题”,以便向感兴趣的学生指出这些内容,而不会给其他人造成负担。

示例

# About

There are two different kinds of numbers in Elixir - integers and floats.

Floats are numbers with one or more digits behind the decimal separator. They use the 64-bit double precision floating-point format.

```elixir
float = 3.45
# => 3.45
```

Elixir also supports the scientific notation for floats.

```elixir
1.25e-2
# => 0.0125
```

## Rounding errors

Floats are infamous for their rounding errors.

```elixir
0.1 + 0.2
# => 0.30000000000000004
```

However, those kind of errors are not specific to Elixir. They happen in all programming languages. This is because all data on our computers is stored and processed as binary code. In binary, only fractions whose denominator can be expressed as `2^n` (e.g. `1/4`, `3/8`, `5/16`) can be expressed exactly. Other fractions are expressed as estimations.

```elixir
# 3/4
Float.ratio(0.75)
# => {3, 4}

# 3/5
Float.ratio(0.6)
# => {5404319552844595, 9007199254740992}
```

You can learn more about this problem at [0.30000000000000004.com][0.30000000000000004.com]. The [Float Toy page][evanw.github.io-float-toy] has a nice, graphical explanation how a floating-point number's bits are converted to an actual floating-point value.

文件:introduction.md

用途: 为尚未完成对应概念练习的学生提供简要介绍。

是否必需: 必需

如果学生尚未完成对应的概念练习,就会展示这个文件。它应简要介绍该概念。

  • 只提供理解该概念基础所必需的信息。额外的信息应留给about.md文档。
  • 链接应尽量少用,最好不用。虽然解释递归这类复杂主题的链接可能有用,但对大多数概念来说,链接提供的信息会超出所需,因此目标应是直接在正文中简洁地解释清楚。
  • 应使用规范的技术术语,以便学生轻松搜索更多信息。
  • 只有在介绍新语法时才应使用代码示例(学生不应为了找语法示例而上网搜索)。其他情况下,应提供描述或链接,而不是代码。
  • 不要在正文中提及某道练习,因为该文件是在练习的语境之外展示的。

示例

# Introduction

One of the key aspects of working with numbers in C# is the distinction between integers and floating-point numbers (numbers with zero or more digits after the decimal separator).

The two most commonly used numeric types in C# are `int` (a 32-bit integer) and `double` (a 64-bit floating-point number).

```csharp
int i = 123;
double d = 54.29;
```

用途: 提供有助于进一步阅读或了解某个概念的实用链接。

是否必需: 必需

这些链接可能是官方文档、优秀的教程等。这些链接并不取代概念about.md文件中更具语境性的链接,而是为学生提供一组快速的总览性参考资料。

每个链接必须包含以下字段:

  • url:它指向的 URL。
  • description:链接的描述,会作为链接文字显示。

链接还可以选择性地包含icon_url字段,用于自定义链接显示时展示的图标。如果未指定,图标默认为网站图标。

[
  {
    "url": "https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/intro-to-csharp/numbers-in-csharp-local",
    "description": "Numbers in C#"
  },
  {
    "url": "https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types",
    "description": "Integral numeric types",
    "icon_url": "http://test.org/icon.png"
  }
]

文件:.meta/config.json

用途: 包含概念的元信息。

是否必需: 必需

该文件包含概念的元信息:

  • authors:该概念作者的 GitHub 用户名(必需)
    • 如果审阅者的审阅大幅改动了该概念(到了让人觉得“你们是一起完成的”那种程度),也包括这些审阅者
  • contributors:该概念贡献者的 GitHub 用户名(可选)
    • 如果审阅者的审阅有意义、可操作或已被采纳,也包括这些审阅者
  • blurb:该概念的简短描述。长度必须 <= 350。不支持 Markdown(必需)

如果某人既是作者又是贡献者,只把他列为作者。

示例

{
  "authors": ["FSharpForever"],
  "contributors": ["IWantToHelp"],
  "blurb": "F# has two types of numbers: integers and floating-point numbers."
}

注意:

  • 作者和贡献者的顺序并不重要,没有任何含义。