The Missing Semester

L0 Overview and Shell

1. shell

一些命令

命令 作用
cd- 可以切换回上一路径
< file 将输入流重定向为file中的内容
> file 将输出流重定向到file
| 管道运算符,将|前输出的内容作为输入,输入到管道后的命令中
ls -l 可以看文件的权限,r可读,w可写,x可执行,-表示没有相应的权限

2. root用户

root用户相当于管理员用户,权限很高,一些我不可读不可写的文件,root用户可以

sudo:“super do”,该程序允许我以root身份运行紧接着的命令

比如进入/sys去修改内核的参数,正常我是没有权限的,echo 500 > brightness修改亮度会报错,因为我没有写入brightness的权限。但如果试试sudo echo 500 > brightness呢,仍然会报错,因为sudo只是以管理员身份运行了echo,和brightness无关,因此仍无法写入。可以使用# echo 500 > brightness,这表示管理员身份运行命令;或echo 500 | sudo tee brightness,tee表示将输入输出到打开文件和标准输出

sudo su:进入管理员终端

L1 Shell Tools and Scripting

1. shell tools

tool function
find 可以查找制定的文件 find -name “***” -type d/f --exec
locate 找到所有包含子字符串的文件路径
grep 在某一文件或路径中查找是否包含某一字符串,如果是路径要加-R
tree 打印目录结构
tldr 和man命令相似,可以查看命令的使用信息,但tldr可以给出命令使用的例子

2. script

bash语言也是一门新的语言,想要写好脚本也需要认真学习bash的语法

赋值:在终端可以给变量赋值,可以通过$将变量展开

字符串:双引号和单引号有些区别,在“”中 $变量会展开,在’'中$变量不会展开

将一个命令的输出存储到变量中:variable=$(command)

$1~9为保留关键字参数,表示脚本接收到的的第1~9个参数

$_ 为上一个命令的最后一个参数

$? 为上一条报错代码

通配符*匹配任意数量字符,?只匹配一个字符

对脚本文件debug可以用shellback

L2 Vim

vim作为一个文本编辑工具,要想学会就要多去使用,但是本人由于常用vscode,所以暂时没有熟练vim的动力…

vim本身就是一种基于命令的编程语言,不同的键位组合产生不同的效果

1. mode

1.1 normal mode

进入该模式按键

按键或组合 移动方式
hjkl 分别对应左上下右
w 向前移动一个单词
b 向后移动一个单词
e 跳到单词末尾
0 移动到行开头
$ 移动到行末尾
ctrl U 向上滚动
ctrl D 向下滚动
G 移动到文本最底部
gg 移动到文本最顶部
f 在本行搜索字符
/ 在全文搜索字符
d and c 接一个移动操作,将对应位置的单词删除,c会进入insert mode
u 撤销操作

1.2 insert mode

进入该模式按键

1.3 replace mode

进入该模式按键

1.4 visual mode

进入该模式按键

按键 功能
y 选择文本后可以复制
p 粘贴
V 可以选择整行文本的模式
ctrl v 可以选择整块文本的模式

1.5 command-line mode

进入该模式按键<:>

sp:创建一个新的窗口

2. 配置Vim

配置.vimrc文件,可以使用很多插件,等待去探索

L3 Command-line Environment

1. Job control

涉及很多指令和信号,需要记忆

2. Terminal multiplexers

tmux 终端多路复用器

命令 功能
tmux new -t 开tmux并起名
+ 离开会话
+ <“”> 上下分屏
+ <%> 左右分屏
+ <箭头> 在分屏之间来回切换
+ 可以重新排列分屏
+ 最大化某一分屏,再次触发会返回之前状态
tmux a -t 连接到某一会话
+ 打开一个新的窗口,不同窗口之间可以切换,就像浏览器的标签页一样
+ <p/n> 在窗口之间前后切换

3. Dotfiles

别名alias,可以用短的字符串替代长的常用的命令字符串,可以节省很多时间,

L4 Vision Control – Git

1. 数据模型

首先理解git整理历史文件和文件夹的数据模型

文件夹称为trees,文件称为blobs,git追踪的目录为root

git使用有向无环图来模拟历史,每一个节点是一个对象,对象包含commit、tree、blob,对象包含特性parent、author、message、snapshot,在磁盘中会讲对象hash成一个40位的16进制字符串,该字符串又会被hash成一个人类可读的引用

2. 命令

2.1 创建Git仓库

1
2
3
git init
git add <file>
git commit -am <描述信息>

init运行git项目管理,add将要追踪的文件加入暂存区,commit将暂存区文件全部提交,如果只想部分提交,应该用-m file1, file2

1
2
git rm file
git commit -m <message>

通过以上取消git对文件的追踪,此时文件还是在暂存区,别忘了commit

1
2
git mv file_name file_new_name
git commit -m <message>

通过以上实现重命名和文件移动

2.2 查看日志

1
2
3
git log
git log --oneline
git log --all --gragh --decorate

可以查看提交信息,第二个的可以将提交哈希值和信息输出在同一行,此时哈希值只显示前7位,并且通常也只用前7位

第三个可以以图结构显示历史信息

1
2
3
git diff <file>
git diff <hash> <file>
git diff <hash> <hash> <file>

查看修改内容,与Head引用来比较,如果指定了hash,则与hash对应的历史文件比较

2.3 恢复历史修改

1
git restore <file>

撤销未提交的修改

1
git restore --staged <file>

取消add的暂存

1
2
git revert -n HEAD~3..HEAD
git commit -m <message>

回滚3次到历史版本

1
git show <hash>:<file>

回滚特定文件到历史版本,状态是提交之后

1
2
3
git checkpoint <hash> -- <file>
git add <file>
git commit -m <message>

回滚到某一状态,但仍需要add和commit

2.4 分支与合并

当你开发一个项目时,可能某一时间既要添加新的特性,又要修复一个bug,git可以使开发线分出两个分支去分别完成不同的事情,最后再将两个分支合并在一起

1
git branch

查看当前存在的分支

1
git branch <name>

新建一个分支的指针,但是指向当前快照

1
git checkout <name>

将Head转到其他分支

1
git merge <name>

分支与目前所在分支合并,但是可能会存在冲突,需要自行手动修改

1
git merge --continue

继续merge

2.5 远程仓库

1
git remote

列出所有的远程仓库

1
git remote add <name> <url>

添加远程仓库

1
git push <name> <branch>:<branch>

将本地branch推送到远程仓库

1
git pull == git fetch + git merge

在另一台机器上实现追踪,获取所有更改并更新

2.6 Github

Github是在线托管Git仓库的网站

1
2
git remote add origin http://github.com/<username>/folder.git
git push -u origin master

通过以上命令连接本地仓库和github仓库,然后将所有内容push到仓库中,之后就只用git push就行

L5 Debugging and Profiling

1. print and log调试

一种非常常用的调试方法,log相比于print的好处是可以自定义危险等级

2. ipython调试器

1
python -m ipdb *.py

l:可以列出所有代码

s:可以逐行执行代码

c:继续执行

p:打印变量

q:退出调试器

b:打断点

3. 静态分析工具

静态分析工具可以提前分析出语法错误等,很多IDE和插件都包含这个功能,工具有:pyflakes、mypy等

4. 性能

实际时间:程序开始运行到结束运行的总时间

用户时间:CPU执行用户级别代码所用的时间

系统时间:CPU执行内核级别指令所用的时间

分析器(profiler):一般指CPU分析器,cProfile

跟踪分析器:每运行一段程序就会报告这段程序运行所需的时间,会和程序一起运行

采样分析器:每过一段时间就会停止程序并报告目前所在的位置

du:disk usage可以查看磁盘使用情况

L6 Metaprogramming

1. 构建系统

将构建目标所需要的命令写到一个工具中,其中依赖项是构建目标所需要的东西

工具:make

在makefile中构建一系列目标和依赖项,最终运行make会寻找目录中的makefile文件,然后运行

2. 版本号

版本号的作用:方便其他人针对某一版本构建依赖,防止更新库之后,对应的依赖项会失效

如python 3.11.4

3表示主要版本,11表示次要版本,4表示补丁版本

只做完全backward compatible的更改,不增加、不删除、不重命名任何东西,只改变补丁号

如果增加了某些东西,则改变次要版本号,并把补丁号置为0

如果删除或重命名某些东西,则要改变主要版本号

持续集成:云构建系统

3. 测试

测试套件

单元测试:只测试非常小的一个功能

集成测试:测试程序中不同子系统的交互

回归测试:测试过去出现过问题的东西

L7 Security and Cryptography

1. 熵

可以量化密码的随机性,单位为bit,熵越大,密码越安全

2. 哈希函数

将任何一个文件映射为一段固定长度的字符串,具有不可逆和抗碰撞性,很难找到两个输入的哈希值是相等的

承诺方案

比如说,在没有硬币的情况下玩抛硬币游戏,在脑子里抛无论如何都很不公平,但是如果用哈希函数,先将哈希输出告诉你,猜完之后,再去检验。因为哈希结果是一一对应的,所以无法作弊

3. 密钥生成函数

这个函数通常运行起来比较慢,因为一般用户运行的时候一次就够了,但是如果黑客想要破解密钥的话,就需要运行上百万次,这就大大减缓了破解的速度

4. 对称加密

由密钥生成函数、加密函数和解密函数组成

密钥生成函数会生成一个密钥key

加密函数将明文和密钥加密成密文

解密函数将蜜文和密钥解密成明文

工具

openssl是一种对称加密工具,可以对文件进行加密

加密盐

有些攻击者在破解了大量的密码和哈希之后,构建了密码和哈希对应的彩虹表

这时可以生成一个盐值(随机字符串),加到密码后面再做哈希 ,因此在加入不同的盐的相同的密码哈希值是不同的

5. 非对称加密

密钥生成函数生成一个公钥和一个私钥

加密函数将公钥和明文加密成密文

解密函数将私钥和密文解密成明文

签名方案

sign:输入消息和私钥生成签名

verify:输入消息、签名和公钥检验签名是否正确

L8 Potpourri

1. keyboard-remapping

可以把一个按键或组合映射到一个操作,合理的按键设置有时会很方便操作

2. 守护进程

该类程序通常以d结尾,程序在守护进程的监听下才能正常运行

3. 备份

用一些软件或者云服务,对重要的文件养成良好的备份习惯

4. API

curl

提供一个URL,curl会返回获取到的JSON

5. VPN

可以更改互联网提供商,但如果涉及机密你要考虑是否信任这个VPN提供商

6. Hammerspoon

可以允许你在不同的环境下自动设置不同的桌面布局

7. 容器

创建隔离环境,用于测试、开发和探索,之后会继续学习Docker,敬请期待


The Missing Semester
https://markouv.github.io/2023/09/07/CS/Missing Semester/
作者
Kov
发布于
2023年9月7日
许可协议