Thumbnail image

编程语言学习笔记

我在2021年秋季PL(编程语言)期末考试前学习的笔记。


堆管理/垃圾回收

1. 引用计数器(快速方法)

  • 在每个单元格中维护一个计数器,存储当前指向该单元格的指针数 指向该单元格的指针数
  • 当计数器下降到 0 时,回收单元格

2. 标记和扫描(懒惰法)

  • 递归跟踪所有实时指针,将其标记为有用指针
  • 扫过整个堆,回收未标记的单元格
  • 同时关闭标记

3. 停止并复制(懒惰法)

  • 将堆分成两半,所有新的分配都进入活动的一半
  • 递归跟踪所有活指针,将发现的结构复制到 现在这一半成为活动堆
  • 非活动半部分现在只包含垃圾;可以回收

4. 代际复制

  • 跟踪单元生命周期,减少收集长生命周期结构的频率 收集频率
    • 生命周期:它们存活的次数

5. 逃逸分析

  • 指针的生命周期是否仅限于当前过程?
    • 是:值可以存储在堆栈中,不需要分配或释放。

覆盖与重载

1. 重载

  • 重载实现了运行时多态性(虚拟)
  • 发生在超类和子类之间
  • 方法具有相同的签名(相同的名称和参数)
  • 运行时根据对象时间决定调用的方法

2. 重载

  • 重载实现了编译时的多态性
  • 发生在同一类中的方法之间
  • 方法名称相同,参数不同
  • 编译时决定调用的方法

静态绑定与动态绑定

1. 静态绑定

  • 静态绑定在编译时发生并保持不变
  • 通过默认约定指定类型
  • 未明确声明的静态类型(如 auto)
  • int x" - 在源代码中提供类型信息,编译时已知

2. 动态绑定

  • 动态绑定发生在运行时(执行过程中),可以改变
  • 通过运行时多态性指定类型
    • 变量赋值时与类型绑定
  • 高成本:运行时类型检查和解释

Prolog

% Tail recursion for length of list
len_acc([], Acc, Acc) :- !.
len_acc([_|T], Acc, Result) :-  Acc2 is Acc + 1,
                                len_acc(Tail, Acc2, Result).
len(Lst, Result) :- len_acc(Lst, 0, Result).
% Tail recursion for factorial
fac_acc(0, Acc, Acc) :- !.
fac_acc(N, Result, Acc) :-  N2 is N - 1,
                            Acc2 is N * Acc,
                            fac_acc(N2, Result, Acc2).
fac(N, Result) :- fac_acc(N, Result, 1).
% Max of list
max_acc([], Acc, Acc]) :- !.
max_acc([Head|Tail], Result, Acc) :-  Head > Acc,
                                      max_acc(Tail, Result, Head).
max_acc([Head|Tail], Result, Acc) :-  Head <= Acc,
                                      max_acc(Tail, Result, Acc).
max([H|T], Result) :- max_acc([H|T], Result, H).

Related Posts