计算机教育中缺失的一课 - MIT - L8 - 元编程

https://missing.csail.mit.edu/
https://missing-semester-cn.g...
https://www.bilibili.com/vide...

思否主页:https://segmentfault.com/u/wi...

笔记

元编程通常又指 用于操作程序的程序,讲座中讨论的更多是关于开发流程

构建系统

“构建系统”帮助我们执行一系列的“构建过程”。构建过程包括:目标(targets),依赖(dependencies),规则(rules)。您必须告诉构建系统您具体的构建目标,系统的任务则是找到构建这些目标所需要的依赖,并根据规则构建所需的中间产物,直到最终目标被构建出来。

理想的情况下,如果目标的依赖没有发生改动,并且我们可以从之前的构建中复用这些依赖,那么与其相关的构建规则并不会被执行。

make 是最常用的构建系统之一,您会发现它通常被安装到了几乎所有基于UNIX的系统中。make 的教程可以参考阮一峰的这篇文章:Make 命令教程

其他常见的构建系统/工具:

  • C 与 C++:Cmake,可以参考 CMake 入门实战
  • Java:Maven,Ant,Gradle
  • 前端开发:Grunt,Gulp,Webpack
  • Ruby:Rake
  • Rust:Cargo

依赖管理

软件仓库

  • Ubuntu:可以通过 apt 这个工具来访问 Ubuntu 软件包仓库
  • CentOS,Redhat:通过 yum 这个工具来访问软件仓库
  • Archlinux/Manjaro:通过 pacman 工具访问 Archlinux 软件仓库和 Arch 用户软件仓库(AUR,Arch User Repository)
  • Ruby:通过 gem 工具访问 RubyGems
  • Python:通过 pip 工具访问 Pypi

版本号

不同项目所用的版本号其具体含义并不完全相同,但是一个相对比较常用的标准是语义版本号,这种版本号具有不同的语义,它的格式是这样的:major.minor.patch(主版本号.次版本号.补丁号)。相关规则有:

  • 如果新的版本没有改变 API,请将补丁号递增;
  • 如果您添加了 API 并且该改动是向后兼容的,请将次版本号递增;
  • 如果您修改了 API 但是它并不向后兼容,请将主版本号递增。

这样做有很多好处,例如如果我们的项目是基于您的项目构建的,那么只要最新版本的主版本号只要没变就是安全的,次版本号不低于之前我们使用的版本即可。换句话说,如果我依赖的版本是1.3.7,那么使用1.3.81.6.1,甚至是1.3.0都是可以的。如果版本号是 2.2.4 就不一定能用了,因为它的主版本号增加了。

持续集成系统

持续集成,或者叫做 CI 是一种雨伞术语(umbrella term),它指的是那些“当您的代码变动时,自动运行的东西”,可以认为是一种云端构建系统。

市场上有很多提供各式各样 CI 工具的公司,例如 Travis CI、Azure Pipelines 和 GitHub Actions。

它们使用方法大同小异:在代码仓库中添加一个文件(recipe),在其中编写规则,规则包括 events 和 actions。

最常见的规则是:如果有人提交代码,执行测试套。当这个事件被触发时,CI 提供方会启动一个(或多个)虚拟机,执行您制定的规则,并且通常会记录下相关的执行结果。您可以进行某些设置,这样当测试套失败时您能够收到通知或者当测试全部通过时,您的仓库主页会显示一个徽标。

Github 还有一个维护依赖关系的 CI 工具 Dependabot

GitHub Pages 是一个很好的例子。Pages 在每次master有代码更新时,会执行 Jekyll 博客软件,然后使您的站点可以通过某个 GitHub 域名来访问。对于我们来说这些事情太琐碎了,我现在我们只需要在本地进行修改,然后使用 git 提交代码,发布到远端。CI 会自动帮我们处理后续的事情。

测试

  • 测试套(Test suite):所有测试的统称
  • 单元测试(Unit test):一个“微型测试”,用于对某个封装的特性进行测试
  • 集成测试(Integration test): 一个“宏观测试”,针对系统的某一大部分进行,测试其不同的特性或组件是否能协同工作。
  • 回归测试(Regression test):用于保证之前引起问题的 bug 不会再次出现
  • 模拟(Mocking): 使用一个假的实现来替换函数、模块或类型,屏蔽那些和测试不相关的内容。例如,您可能会“模拟网络连接” 或 “模拟硬盘”

课后练习

习题 1

一些有用的 make 构建目标(例如本题用到了 phony)。

.PHONY: clean
clean:
      git ls-files -o | xargs rm
      # 这样还会删掉 gitignore 中的文件,例如一些编辑器配置文件
      # 此题也可以这样做
      # rm plot-*.png
      # rm paper.pdf

习题 3

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.

# Redirect output to stderr.
exec 1>&2

if (! make)
then
    cat <<\EOF
Error: make failed.

Excuting 'make paper.pdf'.
EOF
    make paper.pdf
    exit 1
fi

习题 4

基于 GitHub Pages 创建任意一个可以自动发布的页面。添加一个GitHub Action 到该仓库,对仓库中的所有 shell 文件执行 shellcheck(方法之一)。

习题 5

构建属于您的 GitHub action,对仓库中所有的.md文件执行proselintwrite-good,在您的仓库中开启这一功能,提交一个包含错误的文件看看该功能是否生效。

你可能感兴趣的:(计算机教育中缺失的一课 - MIT - L8 - 元编程)