记录
以后每次写博客把当时的心路历程写下来,以备后来对自己曾经的嘲讽。????
本科什么课都是一知半解,既不系统,又不深入,令人汗颜。如今刚读研究生,一定要把必备的计组、网络、数据库、操作系统知识补齐。因为经过一段时间的java学习,我发现面试常考,工作常用,自己须知的几个java核心知识点都是上述的延申和交融。
- java多线程、并发与计组中的CPU组成,操作系统中的事务和锁密切相关。如Concurrent包的底层实现和操作系统中CAS实现有关,进程通信如果想要通过管道的方法就与操作系统中文件的组成和索引相关。
- 之前敲socket的demo也是一直半解,知道是一个网络的封装,简化网络编程但是要想深入学习socket,就得知道套接字是计算机网络中TCP和IP层之间的一个套接。socket的字段跟三次握手里面ACK那些密切相关。
- jdbc,面试喜欢问的MySQL索引,优化这些,不用说,跟数据库密切相关。
- java后端必备的Linux知识就不用说了。。
总之,任重道远,遇到什么学什么就完事了。不积跬步无以至千里。下面正文:
计算机系统的组成
内存
- 内存和缓存
上面这张图中,内存,Cache,主存的问题说法不一,但是总体上来说,CPU访问Cache比访问RAM更快,因为CPU运算特别快,然而CPU取得要操作的数据需要对内存(这里主要就是RAM)进行IO操作,这个操作相对CPU运算速度慢得多。通过Cache高速缓存,使得CPU减少了对内存(这里主要就是RAM)的IO操作,从而提高了系统性能。
这里在多CPU情况下会出现缓存一致性问题,所以就有了两种解决办法, 一是给总线加lock锁,因为CPU跟其他组件通信都是通过总线,给总线加锁就可以完成同步,但是这样的结果是其他CPU只能闲着。所以就出现了缓存一致性协议。最出名的就是Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。
它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。
这个和java中violatile关键字的实现也挺像。
- ROM
上图的ROM在PC中不怎么使用了,手机里所谓的64G,128G就是ROM,早期系统的BIOS写在ROM中,ROM读取比RAM慢,但是断电后依然不丢失数据。所以才能用在BIOS上嘛。
- 关于寄存器
虽然寄存器在CPU内部,但是总是被跟内存,缓存一起提到,也进行一下梳理。
这里一起提到一般指的都是CPU中的存储单元,这一点要知道,而且寄存器比其他这些都更要快,这跟CPU是干嘛的有关。下面梳理CPU的知识。
CPU组成
CPU 的根本任务就是执行指令。总的来说,CPU 从内存中一条一条地取出指令和相应的数据,按指令操作码的规定,对数据进行运算处理,直到程序执行完毕为止。具体过程可分为以下四步:
【1】取指令
CPU 控制器从内存读取一条指令并放入指令寄存器。指令的格式如下:
操作码:就是汇编语言里的 mov,add,jmp 等符号码;
操作数地址:说明该指令需要的操作数所在的地方,是在内存里还是在CPU的内部寄存器里。
【2】指令译码
指令寄存器中的指令经过译码,决定该指令应进行何种操作(就是指令里的操作码)、操作数在哪里(操作数的地址) 。
【3】 执行指令
执行指令分为两个阶段: 取操作数 和 进行运算 。
取操作数:CPU 通过寻址操作,从内存(数据段)中读取操作数到通用寄存器中,暂存起来。
进行运算:运算单元通过指令中的操作码,对寄存器中的操作数进行 mov,add,jmp 操作。
【4】 指令计数
修改指令计数器,决定下一条指令的地址 。CPU 重复上述三步操作,处于内存代码段的指令被逐个的执行,直到程序执行完毕为止。
一个问题更好的理解内存、CPU的关系
一个问题:为什么寄存器比内存快?
答:因为光速不够快~参考 http://www.ruanyifeng.com/blog/2013/10/register.html