欢迎大家来到”面试”系列,Blue在这个系列中将带领大家探究热门面试题背后的知识和原理,欢迎大家关注我,精彩内容不错过,如果碰到感兴趣的题目想讨论,欢迎大家通过留言告诉我,谢谢,但请记住:
面试或许可以应付,但不要糊弄自己,彻底掌握知识本身才是提升的关键
—— 我说的
内存是所有计算设备的基础,同时也是程序存储数据的重要场所,我们每天都要接触,但是内存或者说随机存储(Random Access Memory-RAM)到底是怎么工作的,我们的程序究竟如何使用内存?这次Blue就带大家一起来研究一下,欢迎点赞、收藏、评论、转发
内容大纲
- 内存的原理,如何存放数据
- 内存如何进行寻址、门电路如何组成内存、内存位宽与容量的关系
- 地址是什么?指针是什么?
- 数组不同位置的访问速度一样吗?
从面试题开始
有一道很简单的面试题,从它开始今天的话题
数组里面有10万个数据,取第一个元素和第10万个元素的时间相差多少
复制代码
答案显而易见,因为数组中无论访问第几个元素,时间是一样的,所以答案是:一样的
问题是解决了,但数组在内存中究竟是如何存放的?数组究竟是什么?
RAM内存的原理
我们平常说的”内存”其实应该叫”Random Access Memory”,即”随机访问存储”,它的名字其实已经说明一切了,你可以随机的访问任意一个位置,速度是一样的,但是,为什么?
想象中的内存?
在想象内存时,很多人脑子里会蹦出这幅图:
其实上面的图错的最离谱,因为内存是一个一个小格子的感觉没错,但它不是二维的,硬要说的话,更接近一维的数组,长这样其实还准确一些
上面这张图如果只是说明内存的一些特性其实倒也够了,不过既然今天咱们打算彻底弄明白内存的访问原理,那么,来看看这个
内存的原理?
其实最接近实际情况的内存示意图,大概长得跟棵树似的,在内存中,存在很多”门”(不是俗称,还真就叫门),假如我们的内存只有2字节,那么它长这样:
这里有两个控制位
- a(address的简称)代表要访问哪个字节,0代表0号字节,1代表1号字节
- w代表写入标志,0是读取,1是写入(当然,还涉及到寄存器操作,这里省略了)
我们的内存当然不只2字节,那么稍微扩展一下,4字节内存长这样
因为有4字节,所以一个a就不够了,这时我们需要2位,a0和a1
这也顺便带给我们2个有意思的现象
- 内存的容量一定是2的n次方(寻址位数),比如1024(1K)、2048、……、1048576(1M)、……、1073741824(1G)、2147483648(2G)等,你无法让内存的容量是其他值
- 内存寻址能力(也就是存储上限)受限于主板和操作系统位宽,比如32位系统最大内存寻址上限为4294967296,也就是4GB,这就是为啥32位的Windows XP系统无法使用超过4G内存的根本原因
真实的内存寻址过程
劝退警告,你可以完全忽略此节继续查看其它内容,如果对自己的头发有信心,那么让我们开始吧?
目前人类的计算机使用了一种称为门的逻辑元件(其实就是三极管堆出来的啦),它能帮我们触发指定的操作,而这里,对我们最重要的是”与”(AND)和”非”(NOT)这两种门,先看个门,呸,看个图(图片引自nutsvolts)
这个图简单到一眼就能看懂,那个黑点是输入/输出,圆圈是非操作(NOT),不过为了便于理解,我们来个例子试试
假设我的输入是A=0,B=1,那么A会经过非操作(NOT)变成1,也就是说,最后做的是1&1操作,结果是1
好的,门搞明白了(吗?),接下来继续搞内存,它到底怎么寻址的?很简单
我们只需要多来几个门,看上图我们可以知道,第0字节在A=00时触发,也就是说,地址0触发了第0字节的操作;第1字节在A=01是触发,也就是说,地址1触发了第1字节的操作,是不是很简单?
顺便一说,门上的输入数量(A的数量)就是寻址宽度,一般俗称位宽,也就是我们内存的容量上限
这跟问题有什么关系?
说了这么多,其实就是为了告诉大家,你访问哪个位置,仅仅跟你Address的值有关,而设置Address其实需要的时间是相同的,比如赋值操作,a=12
和a=9999
其实时间一样,那么,这跟数组有什么关系?
数组在内存中如何存储
数组在内存中占用一段连续的空间(废话,不连续的那叫链表谢谢),而我们在变量中其实就会保存数组的首地址(也就是所占内存的起点),这个地址的值(比如这里的87)被称为指针
那么,我们想要arr[1]
是如何操作的?很简单:arr[0]
是87号位置,那arr[1]
呢?小学生,不对,幼儿园都能算出来是88对吧
再试一个,arr[99]
呢?这个有点难,得小学生才会了,87+99=…,186对吧?
那么问题来了,访问A=87和A=186的时间一样吗?上面就说过,都是给Address赋值,一样的
所以我们的结论是,访问数组的任何一位,时间完全相同
结论
是时候梳理一遍Blue讲过的东西了,那么首先
我们来总结一下,这次说到的内容:
- 内存通过地址(Address)访问,不同的地址访问时间完全相同
- 进而,数组不论哪一位,访问时间都是相同的
- 指针就是存在变量里的内存地址(Address)
- 内存寻址宽度(位宽)限制了它的容量上限
有bug?想补充?
感谢大家观看这篇教程,有任何问题或想和我交流,请直接留言,发现文章有任何不妥之处,也请指出,提前感谢