超棒的课程推荐:南大《软件分析》(附我的完整学习路线)

作业全 AC 太开心,为此做个总结与回顾。

# 背景

一直以来想认真学习编译相关的东西(后面就指 PL 吧)感觉无从下手。 几年前看了动手实现 Lua,后面又看了几本 LLVM 相关书籍,期间运气爆棚还提了个 PR D112911 (opens new window) ,但一边推测相关的概念是啥,一遍胡乱调试给了我不好的体验。我意识到我得多补充一些知识才能继续整下去。

社区提供了不少学习资源,比如 CS 6120: Advanced Compilers (opens new window) 从目录上看还不错,这个课程内容虽然不错,但是我理解起来却很辛苦😭,有一种“看我灵魂画手的图,你懂我意思吧?”。

直到遇到 lattice 相关的内容,这回真不懂了,我只好搜索一些辅助材料,正巧看到了《软件分析》这门课。

# 软件分析这门课怎么样?

棒! 不论从教学视频、教学课件还有课后作业来看,能强烈感觉到:

  • 内容详实,又不枯燥
  • 容易上手,但也给了很多思考的地方

这也是为数不多的同时公开视频、课件和作业的课程了。

也可能是我的见识少,上过的课太少了,毕竟我没有本科学历。🐶

以往我非常不喜欢视频课程,因为我觉得一门课程能讲多少东西?又能讲的多透彻? 我发现只要课程足够好,上面的问题都能解决 (并不是课程时长够长,大雾)

# 学习这门课的方式?

仅供非学生参考,换句话说后面的内容只供一个人自学使用。

这门课的链接为:

对应龙书(《Compilers - Principles, Techniques, & Tools》)的参考内容:

  • 6 Intermediate-Code Generation
    • 6.2 Three-Address Code
  • 8 Code Generation
    • 8.4 Basic Blocks and Flow Graphs
    • 9.5 Optimization of Basic Blocks
  • 9 Machine-Independent Optimizations
  • 12 Interprocedural Analysis(这一章我还没看)

🌝 每个人的生活环境不同,方式应该也不同,我的通勤时间比较长,所以我利用上下班这段时间看视频,我每天通勤时间不到 4 个小时,算上换乘、发呆、划水,再补上倍速播放,7 月初终于看完了。(这很休闲的,就当看了十来场电影)

正好作业也公开了,这两周利用周末和下班时间也完成了。

建议分两步走:

第一步:看完全部视频课程,耐心把视频课程完整看完(再投个币?)。由于日常还需要工作,所以最好先把视频课程都看完(拖得越久和上一次课关联起来就越费劲)。

第二步:完成作业,你可以带着所有课程的理解去完成每个作业。

尽管老师们讲的很细心,但每个人理解的方式不同,所以遇到疑惑的点,可以选择以下几种解决方案:

  • 再耐心看几遍
  • 搜索一些课程笔记
  • 搜索相关的资料
  • 参考龙书对应的内容

举个例子,我一直想不明白到 Reaching Definitions 为什么是 Safe 的。直到看了龙书,放一个 dummy 定义,去看一个 dummy 是否能走到一个 use。 (换句话说,我理解是否 Safe 要结合具体的应用场景来看)。

# 作业全 AC 的方法?

这两周我一有时间就去肛作业,在 GitHub 上一些 Issues 帮助下,我过了几个卡了我好几天的的测试用例。

由于作业之间有一定关联性,一定要按顺序完成。 不必为了达不成 AC 过于沮丧,当 OJ 通过率达到 70-80% 的时候,说明你提交的答案在基本上已经没问题了,就差一些边界场景调整。

但没有 AC 说明以下两个问题:

  • 没有认真审题,作业上很多妥协的地方,你要处理好这些边界场景,可以试试多看几遍作业说明
  • 疏忽了一些算法上的边界场景
  • 使用了奇怪的实现,比如一般情况不要修改返回值的内容,避免产生副作用

PL 是门非常严谨的学科,边界场景和一些“小”错误是非常要紧的。不必沮丧,但要重视。

但当你非常想获得 AC 又拿不到的时候(顺便还是提了十几次,错误用例个数不变的情况),那应该是不太开心的。所以我将因为我写了一些幺蛾子代码导致的各种问题作为提示记录在 Tai-e-assignments-tips (opens new window) 中。如果你苦思不得其解,可以来这里看看。

对了,作业中提到不必追求效率应当指的是,你可以在 Work List 中添加重复的任务,这能避免写了一些错误的优化影响通过率。可以在 AC 后再来优化。

🌝 短期来看,我不会放出我的解答,原因如下:

  • 遵守通用规则
  • 我还没怎么学过 Java,再加上很多地方考虑不周,写的还很烂

# 我的完整学习路线

学完这门课,我认为算是在 PL 上有个入门了吧,借此我总结了一下我的过往学习路线和下一步计划。

最佳建议:去考个 CMU 什么的吧。

如果你和我一样无法完成上面的最佳建议,可以来看看我的路线了,即看书,内容如下:

  • Crafting Interpreters
  • 程序员的自我修养:链接、装载与库
  • Compilers - Principles, Techniques, & Tools
  • LLVM Techniques, Tips, and Best Practices Clang and Middle-End Libraries
  • Learn LLVM 12: A Beginner's Guide to Learning LLVM Compiler Tools and Core Libraries With C++

还有一些书籍我觉得写的比较晦涩难懂,不太建议看了。

下一步:

  • 将龙书作为总体指导,展开后面的课程/书籍学习
  • 课程中提到的发表一些 PL 相关的 Papers 的网站
  • 看看 LLVM 上都在贡献啥代码,能不能学到点啥

以上的缺点如下:

  • 想知道下一步该怎么办,不太容易,没有人会指导你
  • 找到合适的学习材料,这也不太容易
  • 没有学习氛围
  • 没有一个学位证书什么的东西帮你认可你的学习成果,不过你可以选择自己认可自己
  • 无法投入充足的时间,这意味着别人一个学期就能完成的量,你可以需要一年甚至更久

最后最重要的一点,打好计算机基础,如果是非科班这很重要,这部分我选择 Teach Yourself Computer Science (opens new window) 作为相关的学习路线,这里的书籍质量非常高,我正在努力一本一本看完。如果你也打算学习这里面的书籍,可以来看看 https://www.v2ex.com/t/84532 (opens new window)