本笔记基于CS:APP3e,也就是Computer Systems: A programmer’s Perspective。

作为一名优秀的程序员,或者说要成为上个时代所谓真正名义上的“黑客”。这本书大约是必不可跳过的经典。

这本书的目的是让阅读者更好的理解什么是计算机,就这么简单。或这本书的直译是《程序员的角度理解计算机系统》。也就是为大部分软件开发者准备的。不过所有的笔记都是以我当前的视角来记录的。可能没有那么好理解。记录这个笔记也是为了让自己可以快速复习。相当于外置大脑了。

我看的书都是从第一张开始的,不过网上会有一些公开课之类的东西。在里面举了一些例子。对于现在的我而言是知道一些浅显的原因却不知道原理。例如用GDB执行几个简单的运算:

稍微学过C的都知道,int类型会有一个范围,大概是-2^32~2^32这么一个范围,如果超出之后就会出现错误。其原理是:

当数据是这样的时候,如果再+1则会变成-1.

本质上是系统或者说编译的时候对数值的处理上与人类的理解有所偏差。

还有一些有趣的C语言程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <time.h>

int src[2048][2048] = {0};
int dst1[2048][2048] = {0};
int dst2[2048][2048] = {0};

void copyij(int src[2048][2048], int dst[2048][2048]) {
for (int i = 0; i < 2048; i++) {
for (int j = 0; j < 2048; j++) {
dst[i][j] = src[i][j];
}
}
}

void copyji(int src[2048][2048], int dst[2048][2048]) {
for (int j = 0; j < 2048; j++) {
for (int i = 0; i < 2048; i++) {
dst[i][j] = src[i][j];
}
}
}

int main() {
clock_t start, end;
double time_ij, time_ji;

start = clock();
copyij(src, dst1);
end = clock();
printf("copyij 运行时间: %.2f 毫秒\n", ((double) (end - start)) / CLOCKS_PER_SEC * 1000);

start = clock();
copyji(src, dst2);
end = clock();
printf("copyji 运行时间: %.2f 毫秒\n", ((double) (end - start)) / CLOCKS_PER_SEC * 1000);

return 0;
}

会发现两种遍历交换的方式时间上相差至少两倍。

还有像是struct的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

typedef struct {
int a[2];
double d;
} struct_t;

double fun(int i) {
volatile struct_t s;
s.d = 3.14;
s.a[i] = 1073741824;
return s.d;
}

int main() {
for(int i=0;1;i++)
printf("i=%d 时返回值:%lf\n", i, fun(i));
return 0;
}

返回值出现错误的同时,程序会报错停止运行。

而学习csapp的目的就是,可以彻底的从软硬件,操作系统以及内存上去理解相关的东西。