计算机基础知识对程序员来说有多重要?( 二 )


哈希表 。用于实现索引节点、文件系统完整性检查等
红黑树用于调度、虚拟内存管理、跟踪文件描述符和目录条目等
Radix 树 。用于内存管理、NFS 相关查找和网络相关的功能
......
上面这些例子是关于数据结构的 。我再举一个算法的例子 。
同样的也来思考一个问题:计算机的缓存容量无论再大 。缓存满了还是要删除一些内容 。给新内容腾位置 。
那么删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存 。而把有用的数据继续留在缓存里 。方便之后继续使用 。那么 。什么样的数据 。我们判定为「有用的」的数据呢?
这个时候采取的策略就是 LRU 缓存淘汰算法 。
LRU 的全称是 Least Recently Used 。也就是说我们认为最近使用过的数据应该是是「有用的」 。很久都没用过的数据应该是无用的 。内存满了就优先删那些很久没用过的数据 。
具体的关于 LRU 缓存淘汰算法 的介绍可以看我之前写的一篇文章 。
二、操作系统
先来看一下操作系统都有哪些内容 。

计算机基础知识对程序员来说有多重要?

文章插图
现代计算机系统由一个或多个处理器、主存、打印机、键盘、鼠标、显示器、网络接口以及各种输入/输出设备构成 。
说实话 。程序员不可能会掌握所有计算机系统的细节 。所以在硬件的基础之上 。计算机安装了一层软件 。这层软件能够通过响应用户输入的指令达到控制硬件的效果 。从而满足用户需求 。这种软件称之为 操作系统。它的任务就是为用户程序提供一个更好、更简单、更清晰的计算机模型 。
我们依旧通过一个例子来解释操作系统在工作中的帮助 。
例子来源于 知乎大佬 @invalid s。
比如说 。做一个网络代理软件 。不过是从 socket 上收一个包然后转发给另一个 socket 而已 。这好像和操作系统没多大关系吧?
但真做了 。你会发现 。用一个线程处理网络 IO 。只要写对了 。那么哪怕系统压力很大 。只要 CPU 顶得住 。就可以保证引入的延迟总是在几个毫秒之内;但如果用了多线程分别处理收/发 。那么只要网络压力稍大 。引入的延迟就会增加 。很快额外延迟就可能突破几十个毫秒(这实际上已经完全不能用了) 。
想搞明白这是为什么 。对操作系统调度原理、时间片等概念没有足够深刻的理解 。是不可能的 。
尤其是 。当你突然遇到类似“系统压力一大网络延迟急剧升高”的 bug 时 。如果对操作系统没有深入理解 。你连准确描述都做不到 。连查资料、求帮助都不知道该往哪个方向努力 。更不用说 debug 了 。
换句话说 。你可以不造轮子 。但是你要知道这轮子是怎么造的 。否则你连问问题都不知道如何去描述 。
再降维一点 。你总要掌握如何安装 Windows 系统吧 。否则妹子让你去她房间里修电脑你都只能拒绝掉!
三、编译原理
众所周知 。编译技术是计算机科学史上的明珠之一 。
对于编译原理 。很多程序员的困惑就是:我也不会去设计一门新的编程语言 。有必要学习编译原理吗?学了有什么用呢?
实际上 。编译原理不是用于炫耀的屠龙技 。程序员在工作中经常会碰到需要编译技术的场景 。比如:
编写界面模板引擎;
为项目编写各种各样的 DSL;
深度理解甚至开发出 Spring、Hibernate、阿里巴巴 Druid 这样的工具 。
除此之外 。解析用户输入 。防止代码注入 。为前端工程师提供像 React 那样的 DSL 。像 TypeScript 那样把一门语言翻译成另一门语言 。像 CMake 和 Maven 那样通过配置文件来灵活工作 。运维工程师分析日志文件等等高级别的需求 。都会用到编译技术 。
当然 。说实话 。编译原理并非随随便便就能入门的!
换言之 。需要准备一些基础知识在学习 。
编译原理的学习和实践通常基于对计算机编译过程、计算机基本工作原理、甚至一定的数学知识有一定积累 。这些知识分别分布并应用在了编译原理的不同阶段 。
没有这些基本知识的积累 。很快就会在某个阶段由于功底不够而无法再继续后面的学习 。
所以不要一开始就去啃编译原理 。
四、计算机组成原理
计算机基础知识对程序员来说有多重要?

文章插图
从上面这张图可以看出来 。整个计算机组成原理 。就是围绕着计算机是如何组织运作展开的 。
我们依旧来举例子:)
每个程序员应该都知道 Ascii 码 。GB2312 。GBK 。Utf8 。Unicode 等编码格式 。如果你没接触过 。那总出现过文件压缩后解压乱码的情况吧?

推荐阅读