学了 7 天 Linux,才敢说"操作系统"不是个黑箱
📌 程序基石 · 每日一学 | 阶段一 · 语言与环境热身 | 操作系统理论入门 + 周总结 | 90 天从零入门计算机底层世界
先说个真事
我们学习群里有个同学,就叫他老周吧。入群第一天,他在自我介绍里写了句话,我到现在都记得:
"操作系统?我点了图标程序就跑,至于谁让它跑的、内存怎么分的,我一概不知道。它对我来说就是个黑箱。"
老周不是科班出身,是转行自学,白天上班,晚上看书,进度比谁都慢。
七天后,就在昨天,他在群里发了条消息,说自己能对着"进程和线程的区别"这个面试题讲三分钟了。讲什么?"进程是被调度器选中才拿到 CPU 的""程序访问内存要过页表""用户态和内核态之间隔着一道系统调用"。
虽然还粗浅,但已经从"黑箱"进化成"能说出原理了"。
我说:老周,你这七天,值了。
差距哪来的?没什么玄机,就是每天一章、亲手敲命令、每天写几行笔记积累出来的。他白天上班,每天晚上的时间雷打不动砸在学习上。没有一夜暴富式的顿悟,只有一天一小步的累积。
今天 D7,第一周收尾。咱们把这一周散落的珠子,串成一条线。
进程 vs 线程:到底差在哪
这是操作系统第一课,也是面试第一题,先把最核心的讲透。
- 进程:运行中的程序,拥有独立的内存空间。像一栋独立别墅,各住各家,互不打扰;
- 线程:进程内的执行单元,共享进程的内存。像别墅里的家人,共用客厅厨房,吵起来也快。
一句话:进程是资源分配的单位,线程是 CPU 调度的单位。
什么意思?你开一个 Chrome,是一个进程;Chrome 里每个标签页、每个渲染任务,是它内部的线程。进程之间隔着墙,线程之间共用一屋。
切换进程要换整个"别墅"(地址空间),开销大;切换线程只换"房间"(执行上下文),开销小。所以高并发服务器普遍用"多线程"而不是"多进程"——切换快。
但线程也有代价:共享内存意味着数据竞争。两个线程同时改同一个变量,谁先谁后说不准,结果可能面目全非。这就得上锁——那是 D25 的内容,今天先记住"共享带来竞争,竞争需要锁"。
记住这个"别墅 vs 家人"的比喻,后面讲协程(D43)时还要用它对比。协程比线程还轻,到时候你就懂了,为什么它们是"别墅→家人→同居室友"的递进关系。
用户态与内核态
这俩概念是理解操作系统安全的基础,也面试必考。
普通程序跑在用户态,想动硬件(读文件、发网络包、分配内存)必须通过系统调用进入内核态。
像公司:普通员工(用户态)不能进机房,有事走流程申请(系统调用),管理层(内核态)才能动设备。
为什么要隔离?
因为一个程序出错,不能让它把整个系统搞垮。你写了个死循环,最多你的进程卡死;要是能直接操作硬件,那整个电脑都得重启。
CPU 自己就设计了"特权级":RISC-V 有 machine/supervisor/user 三级,x86 有 ring0-ring3。内核跑在高特权级,用户程序跑在低特权级。低特权级的程序想干高特权的事,只能通过一条"合法的桥"——系统调用。
这就是为什么系统调用是你 D11 要学的重点,也是后面 xv6 会天天跟它打交道的东西。可以说,理解了用户态和内核态的边界,你就理解了操作系统的半壁江山。
调度器:谁拿到 CPU 谁干活
进程讲完了,顺便把"调度"也串一下,因为这是进程概念的自然延伸。
CPU 只有那么几个核,进程可能有几百个。谁先跑?这就是调度器的活。
常见策略有几种:
- FCFS(先来先服务):排队,先到的先跑,公平但可能饿死短任务;
- 时间片轮转(Round Robin):每人跑一小段时间片,轮流来,谁也不饿死;
- 优先级调度:优先级高的先跑,但低优先级可能被饿死。
现代操作系统用的是"多级反馈队列"这类混合策略——新任务先给高优先级,跑得久了降级,又公平又高效。
这跟你没关系吗?有关系。你写的程序"卡了""没响应",很多时候不是代码的问题,是它在排队等 CPU。理解了调度,你就理解了为什么"卡"不一定是死循环。
面试常问:进程切换(上下文切换)到底要保存什么?答案:寄存器、程序计数器、栈指针、页表——把"现场"完整保存,下次切回来才能接着跑。这也是为什么进程切换比线程切换贵——进程要换页表(整个别墅),线程只要换寄存器(换间房)。
新增小节:文件系统与"一切皆文件"
操作系统全景图里,还有一个角色必须露个脸——文件系统。
Linux 有个哲学叫**"一切皆文件"**:普通文件是文件,目录是文件,socket 是文件,管道是文件,设备(键盘、显示器)也是文件。你 cat 一个文件,cat /dev/random,read 一个 socket——底层都是同一套"打开→读写→关闭"的流程。
为什么这么设计?因为统一接口。你学会了一套文件操作 API(open/read/write/close),就等于学会了操作一切资源。学一次,用一生,这买卖太划算了。
这跟你之前学的有什么关系?关系太大了——D6 你写的 Socket,在 Linux 里就是个文件描述符;D9 你要学的管道,也是文件描述符。所以 xv6 的 Lab 里,管道的实现本质上就是"把一个文件对象的读写端接到两个进程上"。
把这个概念记牢了,后面你学 xv6 的文件系统 Lab 时,会觉得似曾相识:原来内核里 file 结构体后面挂着一堆"操作方法指针",这就是"一切皆文件"的落地实现。
一周知识串联
来,回顾这 7 天:
- D1:Linux 命令 + 装环境——在"操作系统"里打转;
- D2:C 指针 + 内存布局——懂了程序怎么操作数据;
- D3-D4:C++ 类与智能指针——会管理内存了;
- D5-D6:TCP 三次握手 + Socket——理解了网络从哪来;
- 今天:进程/线程/内核态——把这些串成操作系统全景。
写周总结的时候,试着画一张图:
程序 → 进程 → 内存 → 文件 → 网络
能不能把每一步的"谁在管"写出来?写不出来,就是这周的漏洞,趁今天补上。
给你个我的方法:把这张图贴在你书桌前的墙上,每天瞄一眼。一个星期后你再看,会发现原来模模糊糊的地方,全都清晰了。画图是整理知识最便宜的方式,没有之一。
新增小节:为什么第一周要学这些"不搭边"的东西
你可能心里犯嘀咕:又是 C 指针、又是 C++、又是网络、又是 Socket,跟"操作系统"有什么关系?
关系太大了。
操作系统不是一门孤立的课,它是所有东西的"舞台"。你学的指针,是在操作系统的内存舞台上跳舞;你学的 Socket,是在操作系统的网络栈上调 API;你学的 C++ 智能指针,背后是操作系统给你分配的堆内存。
换句话说:C 语言教你怎么操作内存,C++ 教你怎么管理内存,网络教你怎么通信,而操作系统,管着这一切的秩序。
这就像你要去一个城市生活。先得学会开车(C),学会装修(C++),学会打电话(网络),最后——你得看懂这个城市的交通规则(操作系统),才知道车怎么开、楼怎么盖、电话怎么打。
第一周的热身,不是浪费,是在给你的 90 天"铺地基"。地基不牢,后面 xv6 那 21 天,你连代码都看不下去。
今日任务清单
- 写周总结笔记(把"程序→进程→内存→文件→网络"的图画出来)
自检一下,答得上才算过关
- 进程和线程的区别?资源 vs 调度,别墅 vs 家人?
最后说两句掏心窝的话
七天前,你可能连 ls 都陌生;七天后,你能对着面试题讲三分钟。这个进步,是真的,别小看。
我见过太多人学操作系统,第一天就啃最难的调度算法,啃了两天放弃了。我劝你别这样。知识是有骨架的,先搭骨架,再填肉。进程、线程、用户态、内核态、调度器——这是骨架。具体的算法细节,等骨架立起来了再往里填。
接下来是最硬核的 21 天:亲手扩展一个真实操作系统(xv6)。这是整个 90 天里,最能让你"脱胎换骨"的一段路。很多人在这段路上崩溃,但走下来的人,没有一个后悔的。
环境今天就可以先配起来——相信我,明天的内容会让很多人崩溃,而你已经提前准备好了。
明天 D8,开始 xv6 之旅。
📅 明日预告:D8 · xv6 环境配置:QEMU 与评分体系,开启 21 天 OS 攻坚。