编程工具之Git
Git版本控制 尽管 Git 的接口有些丑陋,但是它的底层设计和思想却是非常优雅的。丑陋的接口只能靠死记硬背,而优雅的底层设计则非常容易被人理解。因此,我们将通过一种自底向上的方式像您介绍 Git。我们会从数据模型开始,最后再学习它的接口。一旦您搞懂了 Git 的数据模型,再学习其接口并理解这些接口是如何操作数据模型的就非常容易了。 ...
Git版本控制 尽管 Git 的接口有些丑陋,但是它的底层设计和思想却是非常优雅的。丑陋的接口只能靠死记硬背,而优雅的底层设计则非常容易被人理解。因此,我们将通过一种自底向上的方式像您介绍 Git。我们会从数据模型开始,最后再学习它的接口。一旦您搞懂了 Git 的数据模型,再学习其接口并理解这些接口是如何操作数据模型的就非常容易了。 ...
Vim编辑器 编辑模式 Vim的设计以大多数时间都花在阅读、浏览和进行少量编辑改动为基础,因此它具有多种操作模式: 正常模式:在文件中四处移动光标进行修改 插入模式:插入文本 替换模式:替换文本 可视化(一般,行,块)模式:选中文本块 命令模式:用于执行命令 在不同的操作模式下, 键盘敲击的含义也不同。比如,x 在插入模式会插入字母x,但是在正常模式 会删除当前光标所在下的字母,在可视模式下则会删除选中文块。 ...
最后一节课,我们回答学生提出的问题: 学习操作系统相关内容的推荐,比如进程,虚拟内存,中断,内存管理等 你会优先学习的工具有那些? 使用 Python VS Bash脚本 VS 其他语言? source script.sh 和 ./script.sh 有什么区别? 各种软件包和工具存储在哪里?引用过程是怎样的? /bin 或 /lib 是什么? 我应该用 apt-get install 还是 pip install 去下载软件包呢? 用于提高代码性能,简单好用的性能分析工具有哪些? 你使用那些浏览器插件? 有哪些有用的数据整理工具? Docker和虚拟机有什么区别? 不同操作系统的优缺点是什么,我们如何选择(比如选择最适用于我们需求的Linux发行版)? 使用 Vim 编辑器 VS Emacs 编辑器? 机器学习应用的提示或技巧? 还有更多的 Vim 小窍门吗? 2FA是什么,为什么我需要使用它? 对于不同的 Web 浏览器有什么评价? 参考 学习操作系统相关内容的推荐,比如进程,虚拟内存,中断,内存管理等 首先,不清楚你是不是真的需要了解这些更底层的话题。 当你开始编写更加底层的代码,比如实现或修改内核的时候,这些内容是很重要的。除了其他课程中简要介绍过的进程和信号量之外,大部分话题都不相关。 ...
安全和密码 熵(Entropy) 度量了不确定性并可以用来决定密码的强度。 熵的单位是 比特。对于一个均匀分布的随机离散变量,熵等于log_2(所有可能的个数,即n)。 扔一次硬币的熵是1比特。掷一次(六面)骰子的熵大约为2.58比特。 对称加密与非对称加密 当你运行ssh-keygen命令,它会生成一个非对称密钥对:公钥和私钥(public_key, private_key)。 生成过程中使用的随机数由系统提供的熵决定。这些熵可以来源于硬件事件(hardware events)等。 公钥最终会被分发,它可以直接明文存储。 但是为了防止泄露,私钥必须加密存储。ssh-keygen命令会提示用户输入一个密码,并将它输入密钥生成函数 产生一个密钥。最终,ssh-keygen使用对称加密算法和这个密钥加密私钥。 ...
代码不能完全按照您的想法运行,它只能完全按照您的写法运行,这是编程界的一条金科玉律。 让您的写法符合您的想法是非常困难的。在这节课中,我们会传授给您一些非常有用技术,帮您处理代码中的 bug 和程序性能问题。 调试代码 打印调试法与日志 “最有效的 debug 工具就是细致的分析,配合恰当位置的打印语句” — Brian Kernighan, Unix 新手入门。 ...
Linux内核支持用户进程和内核进程两种进程。内核进程指完全运行在内核空间的进程,这种进程主要处理内核事务;用户进程一般运行在用户态,需要使用内核资源时,通过系统调用进入内核态,系统调用结束后,重新返回用户态。 ###创建进程 可通过fork函数创建子进程,理论上,父子进程拥有各自独立的用户空间。但Linux为了提高效率,采用COW(copy on write)算法。 ...
进程是程序的一次运行过程,除了进程虚拟地址空间和文件描述符等,进程控制块中还存放了进程运行的环境信息,包括用户、用户组、父进程、进程组和会话等。 ###用户和用户组 //获得当前进程实际用户ID pid_t getuid(void); //获得当前进程有效用户ID pid_t geteuid(void); //获得当前进程实际用户组ID pid_t getgid(void); //获得当前进程有效用户组ID pid_t getegid(void); ###进程和进程组 获得父子进程ID //获得当前进程ID pid_t getpid(void); //获得父进程ID pid_t getppid(void); 进程组 有时,为了完成某个工作,需多个进程参与协作,为便于管理,可以将多个进程定义为一个进程组。一个进程组包含一个以上的进程,领头进程的进程ID等于进程组ID,进程组中不包含进程时,进程组自动消失。 ...
可执行程序是存储在磁盘设备上由代码和数据按某种格式组织的静态实体,而进程是可被调度的代码的动态运行。在Linux系统中,在一个进程的生命周期里,都有各自的运行环境和所需的资源,这些信息储存在各自的进程控制块中。 进程控制块主要结构如下: 用户标识 进程和会话标识 虚拟地址管理 文件描述符表 信号 ###进程地址空间 ...
Linux提供了应用编程接口,通过这些接口,进程可以向其他进程或进程组发送信号。root权限的进程可以向任何进程发送信号,非root权限的进程智能向属于同一个回话或同一个用户的进程发送信号。 ###发送信号 常用的函数原型如下 /* 向进程发送信号 pid>0 进程ID为pid的进程 pid=0 同一进程组的进程 pid<0 && pid!=-1 进程组ID为-pid的所有进程 pid=-1 除发送给进程自身外,还发送给所有进程ID>1的进程 成功返回0,否则-1 */ int kill(pid_t pid,int signo); /*向进程本身发送信号,等价于kill(getpid(),sig),成功返回0,否则-1*/ int raise(int signo); /*向进程发送SIGABORT信号,默认情况下进程会退出*/ void abort(void); /* 向进程发送实时信号 pid 接收信号的进程ID,只能向一个进程发送信号 sig 指定即将发送的信号 val指定信号传递的参数 成功返回0,否则-1 */ int sigqueue(pid_t pid,int sig,const union sigval val); union sigval { int sival_int; //传送一个整形数 void *sival_ptr; //传送任何数据结构的指针 }; typedef struct { int si_signo; int si_code; union sigval si_value; int si_errno; pid_t si_pid; uid_t si_uid; void *si_addr; int si_status; int si_band; } siginfo_t; 案例:使用sigqueue发送带参数的信号 ...
文件系统概述 Linux内核的各种真实文件系统、块设备和字符设备统一在虚拟文件系统的框架中,虚拟文件系统为应用提供了一组抽象的文件输入输出接口。 虚拟文件系统是对各种真实文件系统的抽象,在虚拟文件系统中定义了抽象的超级块、i节点和目录,它为真实文件系统提供了一种统一的框架接口。真实文件系统通过这些接口与虚拟文件系统相连接,真实文件系统是这些抽象接口的具体实现。 ...
信号是内核和进程之间通信的一种方式,信号是由内核产生,并发送给一个或一组进程的短消息,用不同特定的数字表示不同的信号,信号的作用是表示某种事件的发生。 信号简介 分类 非实时不可靠信号,值为1-31 实时的可靠信号,值为32-63 信号由内核生成,信号生成和事件的发生密切相关,可将事件发生源分为以下三类: ...
函数库介绍 函数库分为: 静态库 共享库(动态加载库) 应用程序在链接静态库时候,将使用的静态库对象嵌入至可执行映像文件中;而在链接共享库时,仅在可执行映像文件中保留加载目标对象所需的信息,在调用时,才真正将目标对象加载至内存。 静态库特点: 运行时无需外部库的支持,可执行文件中已经嵌入了所需的静态库目标对象,所以可执行文件可以脱离静态库独立运行。 较高的运行速度,运行时不需要加载其他目标对象 可执行文件体积较大 不容易维护,每次修改静态库,必须重新链接 共享库特点: ...
Shell 是一种命令行解释器,目前 Linux 下最常用的是 bash 解释器。Shell 不仅可以解释用户输入的命令,还可以解释执行基于命令的 Shell 脚本语言。 Shell 脚本是由命令、Shell 变量和控制语句灯语法元素构成的文本文件。默认情况下,Shell 对脚本中的内容逐行分析,并依次在不同的进程中解释执行。通常 Shell 脚本结构如下: ...