我们应不应该深入学习计算机基础
前言
这里的计算机基础指的是经典四大件(操作系统、网络、组成原理、数据结构) 大部分同学都是做软件开发的,要不就是前端后端,要不就是Java、C艹、go等后端开发。 就拿Java举例,大部分同学都是springboot工程师,开发就在pom文件引入个依赖,写写配置文件,sql,或者调用各种API去实现某个功能。程序就轻而易举地跑起来了,什么内核、寄存器、堆栈?没听说过! 尤其是现在的AI时代,拷打AI写代码已经成了一种常态,技术似乎不再值钱,相应地,这些计算机底层技术,操作系统、网络、组成原理、数据结构等似乎也变得苍白无力了。 反正找工作嘛,写两个项目,被被八股文就结束了。 面对计算机基础,大厂选手可能还有理由深入底层提高竞争力,对于大部分只能去小公司的同学,谈论计算机基础,属实是有些。
故事
先不谈论那些繁琐的计算机基础。就拿八股文举例,相信编程导航很多同学都是面试鸭的用户,或者在别的什么八股学习平台,或多或少你都得准备八股,尤其是redis 和 MySQL这两大技术。
以MySQL举例,为什么MySQL要先写redo log。 首先是为了事务的持久化,能实现崩溃恢复;其次是redo log 顺序I/O 比 buffer pool的随机I/O 操作快。
再拿回表举例 大部分同学都知道回表要再查一次表,性能查,但回表还有一个问题是随机I/O,因为二级索引存储的索引字段并不是在磁盘中不是连续的。
看到这有什么问题?我作为初学者,好像看不懂什么随机I/O,顺序I/O,所以也根本记不住 但是后来了解了磁盘的结构,我大概知道磁盘需要有一个磁头,有磁道、扇区等部分。如果存储在磁盘上的同一个磁道且相邻的扇区,那么根据磁盘的磁头的运行轨迹,读/写速度就很快,省略寻道时间,甚至能和内存比划比划(^_^)。 所以为什么我们需要从设计上就避免随机I/O的产生。 类似的设计思路有RocketMQ的commitlog,就是持久化数据的一个日志。也是顺序I/O。 至此,当你理解了这个原理,面对八股文里的各种描述,你才记忆深刻,畅通无阻。 这是技术深度的提升。
再拿JVM里的Java虚拟机栈解释
这是运行时数据区的一个组成部分,其核心是栈帧 ,一个栈帧从入栈到出栈, 描述的是一个方法从执行到返回的全部流程。巧了,操作系统运行时栈的描述也差不多,如果你先学过JVM,或者先学过操作系统,你会发现很多概念一脉相承,很好理解。 并且你发现,如果我们知道一个函数栈帧的位置,可以通过偏移量寻址访问这个函数的全部局部状态,说人话,就是可以实现栈追踪,这是实现bug排查工具的一个重要技术,为什么监控程序能够定位到问题代码具体位置,这是答案;你还可以说,去维护这个栈帧需要访问开销,很多追求性能的项目可能会禁用。 这能提升你对技术的广度。
再说为什么应用程序从用户态到内核态的切换,开销很大 你会知道用户态的权限低,内核态的权限高。权限校验的开销不少吧。
对硬盘这种硬件执行操作时(read、write、open),用户态不能直接访问,而是切换到内核态去访问,这就意味着,此时用户态的程序是被挂起的。 用户态进程需要保存现场,等底层内核态进程访问完硬件后,将数据拷贝一份到内核缓冲区,再让用户态进程读取。
内核在运作时本身也是要保存各种上下文。
所以现代计算机软件,尽量将程序的执行放在用户态,少量对安全性有挑战的操作会放在内核处理。典型的例子可以说JAVA的虚拟线程优化,避免频繁的线程上下文切换。
还有很多底层的技术,学完后你发现很多和上层技术几乎是共通的。 宏内核到微内核的转变,就好像系统从单体架构跨到微服务架构。 TCP为什么三次握手,因为放在历史重复连接,对应消息队列里解决重复消息的问题。
学习底层的好处
很多同学,打开八股文,看到很多非常陌生的概念,感到阻力很大,每次看八股都很痛苦。或者稍微深入一点的扩展知识,无从下手,感觉背了忘,忘了背。很大程度上,深入了解计算机基础,能给你不一样的启发。
学习时机
学习计算机基础并非要你一开始就拿着书在那啃。相反,初学者更应该去跑通一段段代码,去先把技术栈补全,把项目做好,把常见的八股都过几遍,这时你发现瓶颈了,再回头看计算机基础,很多内容你才会针对性的去学习,才有动力将其啃下来。
