简介:面向备战全国计算机三级「Linux应用与开发技术」的考生,这份知识点整理以计算机体系结构与操作系统为主线,把冯诺依曼结构、计算机系统层次、指令集与CISC/RISC、存储层次与Cache映射替换、MESI缓存一致性协议,以及操作系统特征、处理器管理等考点串成可复用的复习框架,适合基础梳理与考前查漏补缺。压缩包仅含1个docx文档,约231KB,篇幅集中、便于打印和标注,按章节条目化呈现,重点概念后附简要解释,可直接对照考纲勾画掌握程度。目前已有1126人学习下载。读者可据此快速建立从硬件结构到操作系统原理的知识地图,厘清并发与并行、时间局部性与空间局部性、写直达与写回等易混概念,并借助层级目录定位薄弱章节,提升复习效率。
1. 知识地图:三级 Linux 这张卷子的骨架长什么样
三级 Linux应用与开发技术 这份考纲最容易被名字带偏的地方在于:看到 Linux,就以为整张卷子都在考敲命令,但翻开第一章,迎面而来的是冯诺依曼、七层层次结构、指令集、Cache 映射和 MESI 协议,全是体系结构的内容。整门课其实是两段拼起来的:前一段讲“计算机凭什么能跑起来”,包括体系结构、存储系统和操作系统原理;后一段讲“Linux 怎么用起来”,包括命令格式、软件包管理、用户与文件、Shell 脚本和文本处理。两段之间的衔接点正是操作系统。它适合两类人:一类是正在备考三级、需要一个复习框架的考生;另一类是把 Linux 命令用得挺熟练,可一被问到“进程为什么有三种基本状态”“Cache 为什么还要管一致性”就答不上来的人。
2. 计算机体系结构与存储系统:冯诺依曼五部件到 MESI 四态
2.1 冯诺依曼的三个要点与“时空两域”
冯诺依曼体系有三个不可拆分的要点,考试里经常把它们拆成选择题来考。第一,数制采用二进制,这一点决定了后续所有地址、指令、数据的表示方式;第二,程序指令和数据统一存储,也就是常说的“存储程序”,指令和数据放在同一个主存里,没有物理上的区分,靠 CPU 取指时序来区分;第三,计算机按照程序规定的顺序执行指令,也就是顺序执行,这一条是后面理解中断、断点、程序计数器的前提。
按这个结构设计出来的计算机由五个部件组成:控制器、运算器、存储器、输入设备、输出设备。其中控制器和运算器合在一起构成中央处理器,也就是传统的单核 CPU。主存储器里存放着要执行的程序和要处理的数据,运行时 CPU 自动地、按顺序地把指令一条一条取出来执行。
| 部件 | 核心职责 | 归属 |
|---|---|---|
| 控制器 | 取指令、译码、发出控制信号 | CPU |
| 运算器 | 算术运算与逻辑运算 | CPU |
| 存储器 | 存放程序与数据 | 主存与辅存 |
| 输入设备 | 把外部信息送入系统 | 外设 |
| 输出设备 | 把处理结果送出系统 | 外设 |
梳理下来会发现一个很好记的类比:冯诺依曼结构映射现实世界的时空观,存储体系对应空间域,指令顺序执行的过程对应时间域。空间域管“东西放在哪”,时间域管“事情按什么次序发生”。后面讲存储层次、讲流水线、讲中断打断顺序执行,其实都是在补这两个维度上的漏洞。
2.2 七层层次结构与“谁在看哪一层”
计算机系统由软件和硬件组成一个复杂的有机整体,按功能可以切成多级层次结构。这种切法的意义在于:每一层只向上一层提供接口,下一层的实现细节对上一层透明,改一层不至于把整栋楼推倒。
| 层号 | 层次名称 | 这一层大致在做什么 |
|---|---|---|
| 第 0 层 | 数字逻辑层 | 门电路、触发器,硬件的最底层 |
| 第 1 层 | 微体系结构层 | 寄存器传输、微程序,硬件与软件的接缝 |
| 第 2 层 | 传统机器层 | 机器语言程序员看到的指令系统 |
| 第 3 层 | 操作系统层 | 资源管理与屏蔽硬件差异 |
| 第 4 层 | 汇编语言层 | 汇编指令与机器指令的对应 |
| 第 5 层 | 高级语言层 | 编译、解释,面向应用表达 |
| 第 6 层 | 应用程序层 | 最终用户直接使用的软件 |
这张表里最该盯住的是第 2 层。计算机系统结构设计者所关心的是机器语言或汇编语言程序员所看到的计算机结构,也就是第 2 层传统机器层,而不是最底下的数字逻辑层,也不是最上面的应用层。原因不难想:系统结构要定义的是“这台机器对外承诺什么指令、什么寻址方式、什么数据类型”,这些正是机器语言程序员每天面对的东西。而数字逻辑层属于微体系结构的实现细节,同一套指令系统完全可以用不同的微体系结构实现,这就把“结构”和“实现”分开了。
2.3 指令格式、寻址方式与 CISC/RISC 的分岔
指令集是一个计算机系统支持的所有机器指令的集合,它常常被看成软硬件之间的分界面。往上,编译器把高级语言翻译成它;往下,硬件照着它执行。正因为横跨两头,指令集体系结构才有 ISA 这个专门的名字,英文全称是 instruction set architecture。
最普遍的指令格式是“操作码 + 操作数(地址)”,用二进制数据表示。按操作数的数量不同,指令格式可以分为零地址指令、一地址指令、二地址指令、三地址指令和多地址指令。零地址指令一般出现在堆栈型机器里,操作数隐含在栈顶和次栈顶,指令里干脆不写地址;三地址指令表达力最强,一条指令就能完成“两个数相加、结果存到第三处”,代价是指令字变长。
寻址方式按指令的寻址空间来分,可以分为立即数寻址、寄存器寻址、主存寻址和堆栈寻址四种。这个分类标准要留个心眼:它按“操作数在哪个空间里”来切,并不是按“地址怎么算”来切。如果考的是“操作数就在指令里跟着指令一起来”,那就是立即数寻址;“操作数在寄存器里,指令只给寄存器号”,那是寄存器寻址;“指令给出主存地址”,那是主存寻址;“操作数隐含在栈顶”,那就是堆栈寻址。
从功能角度,常见指令类型包括数据传输指令、算术运算指令、逻辑运算指令、程序控制指令、输入输出指令、处理器控制和调试指令。程序控制指令这一类最难,因为它要负责跳转、调用、返回,也就是把顺序执行的单行道改成分岔路,中断机制、函数调用栈都建立在这类指令之上。
按指令系统的复杂程度不同,ISA 分为 CISC 和 RISC 两大阵营。
| 对比维度 | CISC(复杂指令系统计算机) | RISC(精简指令系统计算机) |
|---|---|---|
| 设计目标 | 强化指令功能,减少程序的指令条数 | 减少指令种类、规范指令格式、简化寻址 |
| 指令数量与长度 | 多,长度可变 | 少,长度规整 |
| 寻址方式 | 丰富,一条指令能直接访存 | 精简,尽量寄存器到寄存器 |
| 内部并行 | 指令复杂,并行处理不易 | 方便处理器内部的并行处理 |
| 性能来源 | 靠“一条顶多条” | 靠 VLSI 器件使用效率与流水线 |
RISC 的思路值得多看一眼:它通过减少指令种类、规范指令格式和简化寻址方式,方便处理器内部的并行处理,提高超大规模集成电路(VLSI)器件的使用效率,从而大幅提高处理器的性能。换句话说,RISC 把复杂度从硬件挪到了编译器身上,硬件保持简单规整,好让流水线跑得顺。
2.4 存储金字塔、三级体系与程序局部性
现代通用计算机的存储系统是分层的,一共五层。
| 层次 | 名称 | 特点 |
|---|---|---|
| 第一层 | 寄存器组 | 速度最快、容量最小、价格最高,在 CPU 内部 |
| 第二层 | 高速缓冲存储器 Cache | 缓解 CPU 与主存的速度差 |
| 第三层 | 主存储器 | 程序运行时的落脚点 |
| 第四层 | 辅助存储器 | 容量大、断电不丢,磁盘与固态盘 |
| 第五层 | 脱机存储器 | 磁带、光盘、离线备份 |
规律很直白:越往上速度越快、价格越高、容量越小;越往下容量越大、单位价格越低、速度越慢。这条规律决定了整个存储体系无法靠单一介质解决问题,只能靠层次搭配。
层次搭配能成立的理论依据是程序访问的局部性。时间局部性指最近访问过的内容很可能会在短期内被再次访问,典型例子是程序中的循环,循环体的指令要被反复执行;空间局部性指某个存储单元被访问后,短时间内它附近的存储单元也会被访问,典型例子是数组的顺序遍历、指令的顺序存放。局部性把“访问会集中在很小一块区域”这件事说清楚了,Cache 才有意义。
存储体系里最重要的三级是“Cache-主存-辅存”,通常拆成两个两级系统来看:Cache-主存 依据的是程序局部性,目标是缩小 CPU 与主存之间的速度差距;主存-辅存 构成虚拟存储系统,目标是扩大存储系统的容量。虚拟存储系统是为了满足应用程序对高速大容量主存的需求才被提出来的,它扩大了容量,代价是速度慢——一旦缺页,就得去辅存里把页面调进来,这个代价比 Cache 未命中高得多。把两个两级系统的“目的”对上号,是这一节最容易拿分也最容易记混的地方。
2.5 地址映射、替换算法与 MESI 一致性
Cache 与主存之间最基本的地址映射方式有三种:全相联映射、直接映射和组相联映射。它们的差别,本质上是“一个主存块能放到 Cache 的哪些位置”这个自由度不同。
- 全相联映射:主存任意一块可以放到 Cache 任意一行,自由度最高,冲突最少,但查找时要比较所有标记,硬件成本高。
- 直接映射:主存块只能放到唯一指定的 Cache 行,硬件最简单、查找最快,但冲突严重,容易抖动。
- 组相联映射:折中方案,先分组,组间直接映射,组内全相联,既控制成本又降低冲突。
在采用全相联映射和组相联映射的系统中,当主存向 Cache 传送一个新块而 Cache 已满时,就需要用替换算法把某一块换出去。常用替换算法有三种:随机法(RAND)、先进先出(FIFO)、最近最少使用法(LRU)。LRU 依据的正是时间局部性,它赌的是“最近没被用过的,将来也最不可能被用”。这里有一个容易漏掉的对应关系:直接映射因为位置固定,根本不需要替换算法,只有全相联和组相联才谈得上替换。
Cache 的读写过程会引出数据一致性问题。一致性指同一份数据在不同存储位置的多个拷贝应保持一致,它体现在两个方面:一是 Cache 和主存之间的数据一致性,二是各个处理器内核私有的 Cache 之间的数据一致性。前者通过 Cache 特定的写操作方式来保证——写直达(write through)每次写都同时写 Cache 和主存,实现简单但访存频繁;写回(write back)只写 Cache,等该块被换出时再写回主存,需要额外的脏位标记,效率高但控制复杂。
后者靠缓存一致性协议维护,最经典的是 MESI 协议。
| 状态 | 英文 | 含义 | 典型行为 |
|---|---|---|---|
| M | Modified | 已修改 | 本核独占且与主存不一致,其他核读不到 |
| E | Exclusive | 独占 | 本核独占且与主存一致,可直接转 M |
| S | Shared | 共享 | 多个核持有同一份,只读,写要先作废别人 |
| I | Invalid | 失效 | 该 Cache Line 不可用,需重新载入 |
四个状态的名字和缩写必须背熟,因为题目常常只给一个字母让你判断能不能写。判断逻辑可以简化成一句话:只有处于 M 或 E 状态时,本核才能直接写;处于 S 时要先发消息把其他核的副本置为 I,才能升级为 M;处于 I 时必须先从主存或其他核那里拿到数据。
3. 操作系统原理:四大特征、中断机制与进程状态机
3.1 四大特征,以及并发与并行的分界
操作系统是通用计算机系统中不可或缺的系统软件。现代通用操作系统一般具有并发、共享、虚拟和异步四个基本特征,这四个词经常被当成口号背下来,其实每一个都有明确的判分点。
并发指两个或多个事件在同一时间间隔内发生。这里的关键词是“时间间隔”,一个单核 CPU 上两个程序轮流跑,宏观上像是在同时推进,这就是并发。并行指两个或多个事件在同一时刻发生,多核机器上两个线程真正同时执行才叫并行。单核只能并发不能并行,多核既可以并行也包含并发。这一组概念的混淆率极高,考试里几乎年年出现。
共享指计算机系统中的软硬件资源可被多个并发执行的进程共同使用,而不是被一个进程独占。虚拟指把一个物理上的实体变为一个或多个逻辑上的对应物,虚拟存储器、虚拟处理器都是这个思路——物理上只有一份内存,逻辑上每个进程都觉得自己独占地址空间。异步又称随机性或不确定性,指在相同的计算机环境和初始条件下,在同一数据集上运行的同一程序,每次执行的顺序和所需时间都不一定相同,因为进程走走停停,谁先谁后取决于调度和资源竞争。
计算机系统的资源按其作用可大致分为四类:处理器、存储器、I/O 设备和文件。对这四类资源的管理就是操作系统内核的主要功能,四大特征正是从这些资源的共享与调度中长出来的。
3.2 特权指令、内核态用户态与五类中断
在处理器上运行的指令,按权限分两种。特权指令只能被操作系统内核使用,涉及改变机器状态、修改寄存器内容、启动设备等敏感操作;非特权指令所有程序都能使用。处理器的运行状态相应分为内核态和用户态:内核态下能执行所有指令,用户态下只能执行非特权指令。
用户态切换到内核态有三种方式:系统调用、异常、外围设备的中断。这三种方式都要通过中断机制发生,这一点很关键——很多题目会问“用户态程序想使用系统资源怎么办”,答案不是“直接访问”,而是“通过系统调用陷入内核”。
中断指 CPU 对系统发生的某个事件做出的一种反应,它使 CPU 暂停正在执行的程序,保留现场后自动执行相应的处理程序,处理该事件后,如被中断进程的优先级最高,则返回断点继续执行被“打断”的程序。几个名词要分清:引起中断的事件或发出中断请求的来源叫中断源;中断源向 CPU 提出的处理请求叫中断请求;发生中断时被打断程序的暂停点叫断点。中断概念的另一个发展是访管指令(访问管理指令,即系统调用)的使用。
按功能划分,所有中断源分为五类。
| 中断类型 | 触发来源 | 典型例子 |
|---|---|---|
| 机器故障中断 | 硬件执行过程中出现故障 | 电路检验错、电源故障、内存读错 |
| I/O 中断 | 通道或各种外部设备 | 打印结束、磁盘传输完成 |
| 外部中断 | 计算机系统外部的装置 | 计时器溢出、控制台按钮、他机信号 |
| 程序性中断 | 错误地使用指令或数据 | 非法操作码、无效地址、运算溢出 |
| 访管中断 | 执行访管指令(系统调用) | 用户程序请求操作系统提供服务 |
这里有一个经典的陷阱题:在配置了通道的计算机系统中,用户程序需要输入/输出时,引起的中断是访管中断,而不是 I/O 中断。原因是用户程序没有权限直接驱动设备,它只能发起系统调用请求操作系统代办,此时产生的是访管中断;等通道或设备真正完成传输后回报的,才是 I/O 中断。两个中断发生在不同阶段,一个是“我要”,一个是“我做完了”。
3.3 进程与线程:PCB、五状态转换
进程是计算机中的程序在某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。这个定义里的每个限定都不能丢:“某数据集合”决定了同一个程序在不同数据上跑就是不同进程,“一次运行活动”决定了它是有生命期的。
进程和程序是两个既有联系又有区别的概念,对比着记最省力。
| 对比项 | 进程 | 程序 |
|---|---|---|
| 动静 | 动态概念 | 静态概念 |
| 并发性 | 具有并发特征 | 没有并发特征 |
| 生命期 | 只在计算机运行期间存在 | 可在辅存上长期保存 |
| 对应关系 | 一个程序在不同数据集上对应多个进程 | 与进程不总是一一对应 |
| 组成 | 程序、数据和控制块 | 指令与数据的集合 |
为了描述进程的动态变化过程,系统引入了与进程相关联的进程控制块 PCB,根据它来感知进程的存在。PCB 是进程存在的唯一标志,这句话几乎是必考原句——进程可以没有名字、可以没有输出,但一旦 PCB 被撤销,进程就不存在了。
线程是被处理器调度运行的最小单位。线程被包含在进程之中,一条线程就是进程中一个单一顺序的控制流,在一个进程中可以并发多个线程,每条线程并行执行不同的任务。所以资源分配的単位是进程,调度运行的单位是线程,这两个“单位”不能互换。
进程的状态及转换是这一章的重头戏。三种基本状态是运行态(running)、就绪态(ready)、等待态(wait),等待态又称阻塞态(blocked)或睡眠态(sleep)。实际系统中还会增加两个状态:新建态(new)和终止态(exit)。
转换关系可以按“谁能动谁”来记:
- 就绪 → 运行:被调度程序选中,分配到 CPU。
- 运行 → 就绪:时间片用完,或被更高优先级的进程抢占。
- 运行 → 等待:请求资源得不到满足,或启动 I/O 等待结果。
- 等待 → 就绪:等待的事件发生了,比如 I/O 完成、资源被释放。
- 运行 → 终止:正常结束或异常终止。
最容易记错的两条是:等待态不能直接转到运行态,必须先回到就绪态排队等调度;已经获得除 CPU 以外的所有运行所需资源的进程处于就绪状态,而不是等待状态。判断“处于什么状态”的题,只要问一句“它还缺不缺 CPU 以外的东西”,缺就是等待,不缺就是就绪。
3.4 五大功能速览:存储、设备、文件与作业
从资源管理的角度看,操作系统具备五大基本功能:处理器管理、存储管理、设备管理、文件管理和作业管理。处理器管理的功能主要有两个:中断处理和进程管理,这两块上面已经展开,剩下四块要抓的是骨架。
存储管理。将用户源程序变为可在内存中执行的程序,要经过编译、链接、装入三步。存储器管理的主要功能有四项:内存空间的分配与回收、地址转换、内存空间的扩充、存储保护。地址转换是把逻辑地址变成物理地址,这是虚拟存储能成立的前提;存储保护则是防止一个进程越界访问别人的地盘。
设备管理。设备管理模块主要负责处理器内核与外部设备间的数据交互,包括把设备分配给某个请求使用该设备的进程、处理 CPU 和设备间的 I/O 通信、响应设备的中断请求、维护和回收设备。它和前面讲的中断机制是直连的:I/O 中断正是设备管理的输入。
文件管理。负责文件管理的部分称为文件系统,功能涉及文件的逻辑组织和物理组织、目录结构和管理等。常用的文件物理结构有三种:顺序结构、链表结构、索引结构。顺序结构寻道少、随机访问快但不易扩展;链表结构易扩展但只能顺序访问;索引结构用索引表换取了随机访问能力,代价是多一层查表。
作业管理。作业是用户在一次计算过程中或一个事务处理中要求计算机系统所做工作的总和,也是用户向计算机系统提交任务的基本单位,包括作业的输入输出以及作业的调度和控制。一个作业从交给计算机系统到执行结束退出系统,一般经历提交、后备、执行、完成四个状态。
4. Linux 使用与 Shell:命令格式、软件包、用户文件与文本三剑客
4.1 命令格式、提示符与命令行的四段结构
打开终端后看到的那一行[root@localhost ~]#,其实四个部分各自有含义,拆开看比整行背更牢。
| 片段 | 含义 |
|---|---|
| root | 当前登录用户 |
| localhost | 当前系统的简写主机名,完整名为 localhost.localdomain |
| ~ | 用户当前所在目录 |
| # | 命令提示符,超级用户为 #,普通用户为 $ |
家目录又称主目录,用户在登录后要有一个初始登录位置,这个位置就是用户的家目录。超级用户的家目录是 /root,普通用户的家目录是 /home/用户名。初始登录状态下,用户创建的文件都放入家目录,这也解释了为什么刚登录时提示符里显示的是 ~。切换目录用 cd。
Linux 命令的基本格式是:
# 基本格式:命令 [选项] [参数] ls -l /etc # 短格式选项用单个减号加英文简写,如 -l # 长格式选项用双减号加完整英文单词,如 --all ls --all /etc选项用于调整命令的执行方式,参数是这个命令的操作对象。区分方法很简单:去掉选项命令还能跑,只是行为变了;去掉参数命令往往跑不了或者跑错对象。这个判断在选择题里很好用。
4.2 软件包:源码包与二进制包,RPM 的安装升级卸载查询
Linux 的软件包可以细分为两种:源码包和二进制包。源码包需要自己编译,常见的打包压缩格式是 tar.gz,因此源码包又被称为 Tarball。两大主流的二进制包管理系统是 RPM 包管理系统和 DPKG 包管理系统。
RPM 包默认安装在几个固定路径下,最好不要手动指定安装路径,否则后续查询和卸载都可能出问题。
| 路径 | 存放内容 |
|---|---|
| /etc/ | 配置文件 |
| /usr/bin/ | 可执行命令 |
| /usr/lib/ | 库文件 |
| /usr/share/doc/ | 文档 |
| /usr/share/man/ | 手册页 |
安装、查询、卸载各有各的参数,写在一起容易混,实际敲一遍最清楚。
# 安装:-i 安装,-v 显示详细信息,-h 打印安装进度 # 涉及包全名的命令一定要注意路径,这里用 ./ 指定当前目录 rpm -ivh ./httpd-2.4.6.rpm # 一次安装多个包,用空格隔开 rpm -ivh a.rpm b.rpm c.rpm # 安装完启动服务:start 启动 / stop 停止 / restart 重启 / status 查看状态 service httpd start # 升级:-U 若没装过则直接安装,装过则升级到最新版 rpm -Uvh ./httpd-2.4.8.rpm # -F 则严格得多,没装过就不装,必须已有较低版本才升级 rpm -Fvh ./httpd-2.4.8.rpm # 查询是否安装,-q 后面跟包名,不是包全名 rpm -q httpd # 查询所有已装包,配合管道过滤 rpm -qa | grep httpd # 查询包的详细信息,-i 即 information rpm -qi httpd # 查询未安装的包,-p 即 package,必须用“绝对路径 + 包全名” rpm -qip /tmp/httpd-2.4.8.rpm # 列出已安装包包含的所有文件及安装位置,-l 即 list rpm -ql httpd # 反向查询:某个系统文件属于哪个包,-f 即 file rpm -qf /bin/ls卸载要特别小心依赖关系。假如先装了 httpd 软件包,后装了它的功能模块 mod_ssl,那么卸载时必须先卸 mod_ssl,再卸 httpd,否则会报错。反过来安装时顺序正好相反,先装被依赖的,再装依赖它的。卸载命令是rpm -e 包名,虽然支持--nodeps选项跳过依赖检测直接卸载,但这属于给自己埋雷,不推荐。
梳理下来会发现一个通用规则:凡是“包全名”出现的场合(安装、升级、查询未安装包),路径必须写全;凡是“包名”出现的场合(卸载、查询已安装包),只写名字不写路径。这条规则能挡掉一大半操作题失分。
4.3 用户与文件管理:passwd 七个字段与软硬链接
用户名和 ID 的对应关系存储在 /etc/passwd 文件中,默认情况下管理员创建一个用户,就会在 /home 目录下创建一个用户主目录。用户基本信息文件 /etc/passwd 的权限是 rw-r--r--,所有用户都可读;用户密码信息文件 /etc/shadow 的权限是 rw-------,只有 root 能碰。
/etc/passwd 每行划分为七个字段,顺序不能记错。
| 序号 | 字段 | 说明 |
|---|---|---|
| 1 | 用户名 | 字符串 |
| 2 | 密码 | 显示 x 表示设有密码,真正密码在 /etc/shadow |
| 3 | UID | 取值 0-65535,1-499 供系统程序使用,普通用户从 500 开始 |
| 4 | GID | 初始组只能一个,附加组可以多个 |
| 5 | 描述性信息 | 备注字段 |
| 6 | 主目录 | root 为 /root,普通用户为 /home/用户名 |
| 7 | 默认 shell | 通常为 /bin/bash |
useradd 的创建过程是一条完整的链条,理解了它,很多“为什么家目录里多了几个文件”的疑问就通了:系统先读取 /etc/login.defs 和 /etc/default/useradd,根据这两个配置文件中定义的规则添加用户,在 /etc/passwd、/etc/shadow、/etc/group、/etc/gshadow 四个文件中写入用户数据;然后在 /etc/default/useradd 设定的目录下建立用户主目录;最后把 /etc/skel 目录中的所有文件复制到这个主目录中。
# 添加用户,随后系统按上述链条自动完成四个文件写入与家目录创建 useradd tom # 修改密码,普通用户只能改自己的,且要先输旧密码;root 可改任何人且不用旧密码 passwd tom # 临时锁定与解锁用户 usermod -L tom usermod -U tom # 删除用户,-r 表示同时删除家目录,只有 root 能用 userdel -r tom # 切换用户,带 - 表示连工作环境(PATH、MAIL 等)一起切换 su - tomsu 后面带不带减号是两种完全不同的行为:带-表示在切换用户身份的同时,把当前使用的环境变量也切换成指定用户的环境;不带则只是临时切换身份,环境变量还是原来那套。环境变量用来定义操作系统环境,系统环境没跟着切换,很多命令会找不到路径,这就是“明明切过去了却跑不动命令”的原因。
文件方面,Linux 中所有文件和目录都被组织成从根节点“/”开始的倒置树状结构,文件系统按名访问文件。文件由数据项和文件控制块两部分组成,文件控制块被称为索引节点。按数据项是否具有结构,可分为无结构文件(字符流文件)和有结构文件(如目录文件);通常按类型划分为普通文件、目录文件、链接文件及设备文件。说明目录或文件名位置有两种方法:绝对路径从根目录写起,相对路径相对于当前路径写起。
链接是这一节的高频考点,软硬链接的区别必须一条条对上。
| 对比项 | 硬链接 | 软链接 |
|---|---|---|
| 本质 | 多个文件名指向同一个索引节点 | 一个存放目标路径的特殊文件 |
| 跨文件系统 | 不能 | 能 |
| 链接目录 | 不能 | 能 |
| 源文件删除后 | 数据仍在,仍可访问 | 链接失效,成为断链 |
| 建立命令 | ln 源文件 目标文件 | ln -s 源文件 目标文件 |
4.4 通配符、三种引号、重定向与命令执行操作符
文件名的扩展称为通配(Globbing),shell 里有一套专门的通配符。
| 通配符 | 含义 |
|---|---|
| * | 匹配任意字符的 0 次或多次出现 |
| ? | 匹配任意单个字符 |
| [ ] | 匹配该字符组所限定的任何一个字符 |
| [^ ] 或 [! ] | 匹配不在该字符组中的任何一个字符 |
| { string1,string2 } | 匹配其中一个指定的字符串 |
引用字符有三种,差别全在“保留哪些特殊含义”上。单引号引用一串字符,所有字符都当普通字符;双引号引用一串字符,但保留$、\和倒引号的特殊含义,其中 $ 代表引用变量的值,倒引号代表引用命令;倒引号引用的内容被 shell 解释为命令行,shell 会先执行该命令,并以其输出结果取代整个倒引号部分。转义字符\的作用也是这个逻辑:遇到特殊字符,加反斜线之前按特殊含义执行,加上之后按普通含义执行。
输入输出重定向改变的是数据的流动方向。标准输入是 stdin,文件描述符 0;标准输出是 stdout,1;错误输出是 stderr,2。完整写法是fd>file或fd>>file,不写 fd 时默认为 1。
# 覆盖写:file3 不存在会自动创建,存在则原内容被覆盖 cat file1 file2 > file3 # 追加写:保留原内容,新内容接在后面 echo "append line" >> file3 # 把标准输出和标准错误一起写进同一个文件 # 2>&1 之间不允许有空格,fd> 之间也不允许 grep li si file > result.log 2>&1 # 既不保存也不显示,直接丢进系统的“垃圾箱”,数据不可恢复 find / -name "*.conf" > /dev/null 2>&1 # 统计文件行数,用输入重定向把文件喂给命令 wc -l < file # << 用自定义分界符结束输入,替代默认的 Ctrl+D cat << EOF hello EOF命令执行操作符决定多条命令之间的关系:分号;是顺序执行,一条接一条不管成败;&&是逻辑与,只有前一条正确执行,后一条才执行;||是逻辑或,只有前一条执行错误,后一条才执行。实际写脚本时常用&&把“只有成功才继续”的语义表达清楚,比用分号安全得多。
小括号和大括号都能把若干命令括起来,逻辑上视为一条命令,区别在子 shell:当用户启动 shell 时,这个 shell 是交互的,执行完一条命令后接着显示另一个提示符,始终在前台等待用户;还有一种 shell 是非交互的,在交互 shell 中运行一个外部命令或执行一个脚本时,交互 shell 会创建一个子 shell,运行结束后子 shell 进程结束。后台进程在运行过程中与用户无交互,指的是不响应使用者的输入和终端控制信号,但在后台运行的命令一样会把结果输出到显示器上。
4.5 grep、sed、awk 的分工与典型用法
三个工具经常被摆在一起考,其实分工很清楚:grep 负责“找”,sed 负责“改”,awk 负责“按列算”。
grep 的全称是 global regular expressions print,在一个或多个文件中搜索某一特定的字符模式,此模式可以是单一的字符、字符串、单词或句子。正则表达式是描述一组字符串的一个模式,可以是一些纯文本文字,也可以是用来产生模式的一些特殊字符。这里最容易翻车的是:正则表达式里的特殊字符与通配符含义不同。比如c*在正则里匹配 0 个或多个字符 c,而不是“以 c 开头的文件名”。
| 正则符号 | 含义 |
|---|---|
| c* | 匹配 0 个或多个字符 c |
| . | 匹配任何一个字符,且只能是一个 |
| [xyz] | 匹配方括号中任意一个字符 |
| [^xyz] | 匹配方括号中字符以外的所有字符 |
| ^ | 行首定位符 |
| $ | 行尾定位符 |
sed 主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序。常用编辑命令是 p 打印匹配行、d 删除指定行、a 在匹配行后追加、i 在匹配行前插入、c 整行替换、r 读取文件内容、w 写入文件、s 字符串替换。选项里-n只显示匹配处理的行,-i直接在文件中修改而不是输出到屏幕,-e用于执行多个编辑命令(一般用分号代替)。
awk 更适合格式化文本,对文本进行较复杂的格式处理。它的主要特性之一是较强的处理文本文件中数据的能力,会自动给一行中的每个数据元素分配一个变量:$0 代表整个文本行,$1 代表第 1 个数据字段,$n 代表第 n 个数据字段。默认字段分隔符是任意空白字符,如空格或制表符,要换分隔符就用 -F 手动指定。
# 按行号显示,-n 在每行最前面列出行号 grep -n "error" app.log # 删除空行并直接写回文件,-i 是原地修改 sed -i '/^$/d' app.log # 把 old 全部替换成 new,g 表示行内全局 sed -i 's/old/new/g' app.log # 打印第一列,默认以空白分隔 awk '{print $1}' access.log # 用冒号作分隔符,打印第一列和第三列 awk -F: '{print $1, $3}' /etc/passwd # BEGIN 在处理前执行,END 在处理后执行 awk 'BEGIN {print "start"} {print $0} END {print "end"}' app.log5. 易漏点与易错点:五处踩过才知道疼的地方
5.1 并发与并行、就绪与等待
易漏点:四个基本特征里的并发,和进程状态里的就绪态,都是“差一个字就变味”的概念。并发是同一时间间隔内发生,并行是同一时刻发生;就绪是除 CPU 外资源都齐了,等待是还缺别的东西。
为什么漏:这两个词在日常语言里几乎同义,脑子里默认它们是一回事,做题时凭语感选,就会错。就绪和等待也是同理,看上去都像“没在跑”。
怎么补:给自己定两条硬判据。判断并发还是并行,只问“同一时刻还是同一时间段”,单核一律答并发。判断就绪还是等待,只问“除 CPU 之外还缺不缺东西”,缺就是等待,不缺就是就绪。把这两句话写在笔记第一页,比抄定义管用。
5.2 系统结构设计者关心哪一层
易漏点:七层结构里,系统结构设计者关心的是机器语言或汇编语言程序员所看到的计算机结构,即第 2 层传统机器层。很多人会顺手选第 1 层微体系结构层,因为“结构”听起来更底层。
为什么漏:层的编号是从 0 开始的,第 1 层看着像“第一层”,直觉上更接近硬件核心。加上“微体系结构”这个词里带“结构”二字,误导性很强。
怎么补:抓“谁看到的”这个主语。设计者要定义的是对程序员承诺的接口,所以是机器语言程序员看到的那一层;微体系结构是实现方式,同一套指令系统可以有多种微体系结构实现,属于实现而非结构。记住“结构与实现分离”这六个字,这道题就不会再错。
5.3 用户程序请求 I/O 引发的到底是哪种中断
易漏点:在配置了通道的系统中,用户程序需要输入/输出时引起的是访管中断,不是 I/O 中断。
为什么漏:题目里明明白白写着“输入/输出”,眼睛一扫就选了 I/O 中断,完全忽略了“用户程序”这个主语。用户态没有权限直接驱动设备,这是整个中断分层的根基。
怎么补:按阶段拆。用户程序发起请求,产生访管中断,CPU 从用户态转入管理态;通道或设备完成传输后回报,才是 I/O 中断。一个是“我要”,一个是“我做完了”,时间上先后分明。凡是题干里出现“用户程序需要 I/O”,先想权限,再想类型。
5.4 Cache 一致性的两个层面混为一谈
易漏点:Cache 一致性有两个层面,一是 Cache 和主存之间,靠写直达与写回保证;二是各处理器内核私有 Cache 之间,靠 MESI 之类的缓存一致性协议维护。答题时经常把两者揉成一句“用 MESI 保证一致性”。
为什么漏:两件事都叫“一致性”,教材又放在相邻段落,读的时候顺过去了,写的时候才发现说不清哪个对应哪个。
怎么补:画一条竖线隔开。左边写“单核内部:Cache-主存,手段是写策略(write through / write back)”;右边写“多核之间:Cache-Cache,手段是一致性协议(MESI 四态)”。再补一句 MESI 的判断口诀:只有 M 和 E 能直接写,S 要先作废别人,I 必须先取数。
5.5 重定向的空格与 RPM 的包名、包全名
易漏点:2>&1之间不允许有空格,fd>file之间也不允许;RPM 安装和查询未安装包要用带路径的包全名,卸载和查询已安装包只写包名。
为什么漏:这两处都属于“看起来无所谓、跑起来就报错”的细节。空格在 shell 里是分隔符,多一个空格,2>和&1就被拆成两个东西;包名多写或少写路径,命令不是报错就是查不到。
怎么补:把2>&1当成一个整体符号背下来,不要拆开理解。RPM 则记一条规则:出现 -p(package,指未安装的包)就必须配全名和路径,出现 -e(erase,卸载)和 -q 包名(查已安装)就只写名字。每次敲之前先问一句“这个包装没装”,装了就写名字,没装就写路径。
6. 复习清单:考前一周按这张表逐项过
到了冲刺阶段,最怕的不是不会,而是不知道自己哪里不会。我的做法是把整门课压成一张自测表,每一项都标注“能默写”“能讲清”“只能认出”三档,只复习前两档之外的。
| 模块 | 必会项 | 自测方式 |
|---|---|---|
| 体系结构 | 冯诺依曼三要点、五部件、七层结构 | 白纸默画层次表,标出设计者关心哪层 |
| 指令系统 | 指令格式分类、四种寻址、CISC/RISC 差异 | 口述两种阵营各三条差别 |
| 存储系统 | 五层金字塔、两种局部性、三级体系 | 画出金字塔并标出每层的“解决什么问题” |
| Cache | 三种映射、三种替换、两种写策略、MESI 四态 | 写出四态全称与“能不能直接写” |
| 操作系统 | 四大特征、五大功能 | 各说一句判据,不背原话 |
| 中断 | 特权指令、两态、三种切换方式、五类中断 | 举出每类中断一个例子 |
| 进程 | 进程与程序五点区别、PCB、五状态转换 | 手画状态图,箭头旁标触发条件 |
| 命令基础 | 提示符四段、命令格式、家目录 | 解释[root@localhost ~]#每一段 |
| 软件包 | 源码包与二进制包、RPM 安装升级卸载查询 | 说出哪些命令用包名、哪些用全名 |
| 用户文件 | passwd 七字段、useradd 链条、软硬链接 | 默写七字段顺序,说三条软硬链接差异 |
| Shell | 通配符、三种引号、重定向、执行操作符 | 手写2>&1并解释为什么不能有空格 |
| 文本处理 | grep 正则符号、sed 常用命令、awk 字段变量 | 各写一条最常用的命令 |
这张表里最值得反复过的是三处:进程五状态转换图、存储金字塔、MESI 四态。它们共同的特点是“图比文字好记”,而且一旦画得出来,相关的选择题基本不会失手。我的习惯是每天开考前先在一张白纸上把这三张图画一遍,画不出来的地方就是当天的复习重点,比从头翻书效率高得多。
具体操作上还有一个技巧:把命令按“增删改查”四类归档,而不是按章节顺序背。用户管理里,增是 useradd、删是 userdel、改是 usermod 和 passwd、查是查看 /etc/passwd;软件包里,增是 rpm -ivh、删是 rpm -e、改是 rpm -Uvh、查是 rpm -q 系列;文件操作里,增是 touch 和 mkdir、删是 rm 和 rmdir、改是 mv 和 sed、查是 cat、more、head、tail、grep。同一套动作在不同对象上重复出现,归类之后记忆量会明显下降。
踩过最疼的一次坑,是把rpm -e后面跟了包全名,命令直接报错,当时还以为是包有问题,查了半天才发现是路径写多了。从那以后我每次敲 RPM 命令之前都强制走一遍“装没装”的自问:装了写名字,没装写路径,涉及 -p 一定带绝对路径。这个习惯后来帮我省下的时间,远比多背十条命令多。
希望这份梳理能帮到你,考场上少翻一次车。
本文还有配套的精品资源,点击获取