CS61A 计算机程序的构造与解释 课程介绍及课程学习总结

这是一门UCB开设的 CS 专业核心基础课程。

CS61A 计算机程序的构造与解释 课程介绍及课程学习总结_第1张图片

其前身是针对课程及课本:SICP: Structures and Interpretation of Computer Programs 的一门课程。能够学习到基本的编程概念,软件工程概念,程序设计概念。主要练习了 Python 编程,函数式编程,面向对象编程,LISP Scheme 语言。适合大一学习。我是在大二上学期才学的。。。历时3个月业余时间 (懒 + 过年…,大概百来个小时差不多)。有很多具备反馈的 lab 和交互式的 homework,有几个好玩的 project,最后一个 project 是用 python 实现一个  scheme 解释器很有意思,为后续各种学习都能做一个导论,比学校大一开的谭浩强c 语言指针都讲不到的PPT reading计导课不知道高到哪里去了,后悔没有早点跟这个学习。

课程具体的开发环境是 linux 下,hw、lab 都具备 ok 程序可以用来评判代码,使用时加 --local 禁止打开网页输入邮箱即可。

把总结学到的内容的概要放上来方便自己回顾。也能分享这门课能学到什么给有需要的人,可以观看下面的大纲初步了解这门课的一些内容。

学习课程链接:CS 61A Fall 2020

HOF

  1. 函数第一公民, dependency injection, 依赖注入(指函数作为参数)
  2. 熟悉lambda函数
  3. 柯里化的原理
  4. 装饰器(包装一个函数), 重点学习trace包装器和后面学到的尾递归优化包装器
  5. 变量的immutability
  6. scope与environment的概念
  7. 掌握GCD的递归解法 (辗转相除/减)
  8. 掌握牛顿法逼近零点(以及数值的求导)

递归和迭代的熟悉

  1. 掌握两种递归: 尾递归和先递归
  2. 编写递归的心情: 只关心什么关系(不用想太多)
  3. 掌握递归的immutable var 和 迭代的mutable var 区别
  4. helper 的作用
  5. Mutual recursion, 关注轮流的情况, 经典例子是fgh函数序列
  6. Tree recursion, Tree recursion 无法优化, 经典是DP的递归基练习, 找钱问题
  7. 迭代可以把不变量转为参数从而转为递归

设计准则

  1. 能抽象, 有必要抽象(封装等手段)请抽象, 本课程关注函数抽象
  2. 名词和动词的使用
  3. TDD

抽象

  1. 构造器和数据选择器
  2. 理解selectors 和properties 的区别(应当提供抽象和接口而不是内置实现)
  3. 行为和实现的隔离
  4. 理解函数也可以表示数据

非线性结构

  1. 广义列表就是树, 理解层次结构, 广义表是FP术语
  2. 理解数据的闭包属性(递归定义), 对比函数式的闭包(即通过变量生成函数内常量的方法)
  3. 熟悉了树形递归的base case编写
  4. 了解剪枝是什么(prune)
  5. 掌握permutation, 全排列的树状递归和剪枝

打字游戏编写

  1. 理解函数抽象对思考解决大问题的帮助
  2. 理解权值打分机制对程序自动决策的作用
  3. 掌握MED, 最小编辑距离的递归写法, 熟悉Leetcode的同题目的迭代/DP写法, 后面学习尾递归优化后, 练习尾递归写法

CS导论杂项

  1.  阅读了编码,
  2.  理解晶体管是什么, 掌握继电器版本的计算机构造法(略),
  3. 了解ASCII是有规律的0x3x是数字.

可变操作和可变数据和可变函数

  1. 理解副作用和引用透明
  2. 理解函数式编程的lazy computaion
  3. 了解了区间计算中的两个数据有依赖的难题(interval computation)
  4. 理解了为什么要有environment 和non-local 等区分.

通过迭代器理解迭代抽象

  1. 理解一次性导致的迭代器不应该在递归出现

OOP, OOD 以及通用的

  1. HAS-A, IS-A, LIKE-A 应该使用的OOP实现方法
  1. 学习了EMAIL服务器和客户端的十分粗糙的OOP模型
  2. 蚂蚁打蜜蜂项目: 深入理解抽象, 不能打破抽象,
    1. 理解什么应该抽象, 怎么抽象(复习大一JAVA课程)
    2. 基类方法对继承类来说很重要, 即使使用空的基类方法
    3. 掌握现代OOP语言中的迭代器的删除问题(十年前的面试题?)
  1. 练习分解问题的思维(decomposition)
  2. 吃一堑: while/if/else中出现的提前结束一定要return/break!

学习了链表和树结构的一些处理, 包括遍历等等.

  1. 链表继续熟悉 (都是老生常谈,对常规的问题再研究一些follow up 问题)
  2. 树要掌握一些树的遍历操作(复习一下二叉树表示的普通树的操作方法, 怎么通过操作访问二叉树去操作访问树)
  3. 复习了一遍has_cycle,  现在应该能写has_cycle和找entry的follow up了

数学思维与抽象, 代价评估

  1. 理解同构是什么
  2. 学习了算法和问题也有同构的思想方法(神奇的卡特兰数)
  3. 掌握使用二分法求指数的方法

LISP 语言语法学习

  1. LISP (list processing) 的精髓是所有东西都是一个 list, procedure 和 data 都是 list.
  2. Symbolic Programing, 理解用程序编写程序的思想方法, 程序生成程序也就是 meta programing
  3. 所有的 while 都可以转换成一个带参数递归函数来编写
  4. 再次复习引用透明的含义以及Cherch-rosser theorem, 无论是 call by value (参数先计算) 还是 call by name (procedure 名 先计算), 都有参数先计算再计算 procedure 值的顺序 (参数在被传入 procedure 计算时先求得参数的值).

控制流的概念

  1. 对于连续的控制流, 没有中断和跳转
  2. 错误的种类 等
    1. runtime
    2. syntax
    3. value
    4. type

程序解释

  1. 元语言抽象 metalinguistic abstraction 是化解复杂度的方法, 通过创建一个DSL或者 tailored script 来继续简化表达.
  2. 区分语法syntax和语义semantics, 一个是建立语法树的结构形式, 没有内容, 语义是拥有含义的语法, 语义错误可能是执行错误或者类型错误.
  3. 一门语言必须有一个canonical implementation 作为标准, 就是一个标准解释器.
  4. 解释过程经过lexical 文法分析分离关键字, syntactic 语法分析tokens得到表达式(描述语句的结构).
  5. token 解析的时候使用 buffer 抽象一个从输入中获取行和过滤的方法, 避免直接操作字符输入缓冲区.
  6. 了解递归语法分析和递归下降语法分析, 这要求语言是LL(1)文法, 具备一个递归结构.
  7. Homoiconic 同像的概念, Lisp 就是同像的把数据和程序共用一种列表表述.
  8. 语法上可以把表达式分为 primitive expression  和 call expression, 符合递归的分类.
  9. 用语法树来表达分析结果符合递归的表达式.
  10. 递归下降法解释程序, 使用 eval 和 apply 实现, 两个函数相互调用, 这是因为 eval 的表达式中可能需要 apply, apply 要实现又必须 eval 所有的参数以及 proceudre 名字.
  11. 栈的实现, 怎么继承命名空间, 最简单的是通过一个字典副本.

基本 SQL


课程中练习到的一些编程经验归纳方便回顾

算法解题

  1. GCD 计算方法, 大数减/模小数, 小数和结果迭代
  2. 牛顿迭代求零点, 用于开方可证明. xn+1 = xn - f(xn) - f'(xn)
  3. Count-partition 分区递归基础及DP转换, 学习状态转移方程, 不关心怎么做. 递归解题中 helper 的作用.
  4. MED, 最小编辑距离, 递归解法和 DP 解法, 不遗漏的分类以及等价类简化.
  5. Permutaion 学习回溯法中的 state restore
  6. Catalan Number 与同构问题分析法.
  7. 二分法求指数以及memo fib, 学习时空复杂度的优化.
  8. 链表判断 has cycle 的双指针法

编程要点

  1. dependency injection 实现模块分离.
  2. decorator 思想来添加功能, 继承的思想, 中间层思想, 兼容思想.
  3. 轮流递归 Mutual recursion 的用法, 可以实现分类的递归.
  4. Data/Function Abstraction 通过抽象减少程序编写的复杂度, 有必要抽象就抽象.
  5. 命名方法, noun & verb
  6. TDD 减少 Debug 烦躁
  7. Selectors & properties 辨析, properties 不应该直接访问, 违反了 barrier. 隔离 isolation 的实现
  8. 权值评估机制, 如打字游戏 accuracy 定义和 wpm 定义, autocorrect 中 grade system 以及 MED 最小编辑距离. 评分机制能用来实现决策.
  9. 决策上限 limit , 对于涉及复杂计算的决策过程, 或者是最优化过程, 可以限制最优化程度, 达到一个平衡, 平衡最优和性价比.
  10. Tree 结构的子树 pruning 剪枝算法, 以及剪枝对于算法优化, 问题解决的过程中的一个尽早抛弃思想.
  11. Email server 的 CS 模式, 以及 OOP 编写一个 CS 系统的 toy.
  12. 模块化设计 modular design 的思想, 减少编写的复杂度, 降低耦合. (模块内高内聚)
  13. OOP 类设计的一些方法:
    1. 类抽象, 需要用什么样的类来表达什么概念, 各种类各自要解决什么样的问题, 进行什么样的动作.
    2. Attributes 的选择, 哪些 atributes 是可变的, 哪些是固有的, 决定是类的变量还是实例的变量. 属性是类内的数据形式, 对外应该展现为选择器.
    3. 基类应该尽可能地提供通用的方法, 甚至是提供空的方法, 让子类 inherit 或者 override.

BUG FREE 要点

  1. TDD
  2. while 里面提前 break 或者 continue (原来我不论在哪都犯这个错误)

你可能感兴趣的:(概述性笔记,sicp,python,函数式编程)