《程序是如何跑起来的》知识整理

简介: 《程序是如何跑起来的》知识整理

程序在计算机底层是如何运行的?


程序通常是我们所编写的代码块,这些代码块主要存储在磁盘空间内部,当需要运作的时候首先需要将其加载到内存当中,然后翻译成一条条机器指令,交给cpu去逐条执行。

假设我们需要执行一段代码实现0+1+2+...+100的求和。大致流程为:


public int count(){
    int sum=0;
    for(int i=0;i<=100;i++){
        sum += i;
    }
    return sum;
}
复制代码


1.cpu处于空闲状态,发送指令将程序加载到内存中。


2.内存中程序代码被翻译为一行行指令,并且将开头指令的地址存储到程序计数器中。


3.控制器将每行机器指令读入,然后交给alu(逻辑运算单元)执行。


4.执行过程中的临时变量(例如1,2,3这些)会被存放在通用寄存器中,循环中的一些累加变量(例如for(int i =1;i<=100;i++)里面的i)会被存储到累加寄存器中,每一次for循环的结尾都会执行一次jump指令重新进入for循环的开头,直到满足相关条件才会跳出for循环。


5.最后计算出来的结果会被存放到通用寄存器中。


如果我们在for循环的里面还需要执行一些比较类型的操作,那么还可能会使用到一些标志寄存器。(这是因为计算机底层对数据的比较是通过做差之后计算得出,得出结果是+ 或者 - 通常会被存放在标志寄存器中)


如果在for循环里面涉及到其它相关的函数调用,则会触发一条叫做call的指令,和return的指令。(call负责将被调用函数的地址压入栈中,同时更新程序计数器地址,return指令则是在函数执行结束之后将原先对函数发起调用的主函数地址压入栈中同时更新程序计数器的地址)。


编译


将高级语言转换为计算机可以识别的机器语言,这部分任务主要教给编译器去做,不同的语言的编译过程不同。例如Java,需要先转换为class文件然后让JVM去将class文件翻译为汇编指令,再转换为机器代码。有些语言例如C++,则是直接将C++的代码转换为汇编指令,再转换为机器代码。


编译执行和解释执行


简单理解编译执行就是一次性将代码全部翻译为本地代码,执行效率比较高,具体语言的代表有:Java,C++。


解释执行通常是执行一行代码则将对应的代码翻译为本地代码,虽然编译的成本低,但是运行过程中的成本较高。


内存与磁盘


在程序执行的过程中,难免会需要涉及到内存和磁盘之间的拷贝问题。


这里有两个概念我们需要了解下:


磁盘缓存


这是一种早期操作系统在设计上的思路,当某些数据从磁盘加载出来之后会被存放到内存中,当二次访问的时候就可以直接从内存中提取,而不是从磁盘中加载


虚拟内存


将部分磁盘用于存储内存数据,通常可以用于处于等待cpu状态中的内存数据,借助这项技术,我们可以尝试将一块128gb的磁盘中分出32gb的空间给计算机存储内存数据。(注意企业一般不会用这种技术,因为它非常卡顿)


内存和磁盘之间的数据拷贝常用到分段式和分页式的两种模式进行管理,由于虚拟内存在实际应用中数据拷贝存在一定的性能瓶颈,所以很容易导致操作系统出现卡顿的情况,因此不推荐使用。


磁盘的组成部分


磁盘的内部主要划分为例盘道和簇,各个磁道上又划分为了多个区间,它们统称为扇区。一块磁盘可以想象为一个圆形,然后将这个圆划分为多个同心圆,不同同心圆的间隔部分就是磁道。


存储的基本单位我们称之为簇,通常1簇可以是1kb也可以是0.5kb,在磁盘中一个扇区内可以有多个簇组成。 一份文件的实际大小为簇的成倍,一份文件不可能占用非成倍大小的簇,这是因为在数据删除的时候会按照簇为基本单位进行移除,如果文件的大小占用了0.5簇,剩余0.5簇用于存储其他文件数据,那么在删除过程中就会影响到其他数据的完整性  。


如何压缩我们的文件?


rle算法

例如AAAABBCC会被压缩为A4B2C2。但是这种算法存在不足点:例如ABCD会被压缩为A1B1C1D1,反而体积更大了。


哈夫曼编码算法

比较成熟且高效。


如何实现随机数

线性同余算法

公式:Ri+1=((Ri * a )+ b) % c,abc分别代表了不同的随机种子,Ri表示第i个随机数。如果随机种子是固定的话,产生的只能是周期性随机数,如果希望有完全随机的话,可以将任意种子变成时间戳即可。


最后我在文末贴上一张思维导图,希望对有需要的读者能有帮助:


网络异常,图片无法展示
|

目录
相关文章
ArkTS基础——Component自定义组件——【坚果派——红目香薰】
ArkTS基础——Component自定义组件——【坚果派——红目香薰】
280 0
|
2月前
|
SQL 运维 自然语言处理
Dataphin智能化重磅升级!编码难题一扫光,开发运维更高效!
Dataphin重磅推出三大核心智能化能力:智能代码助手提升SQL开发效率;智能运维助手实现移动化任务管理;智能分析通过自然语言生成SQL,助力数据价值释放。未来将持续开放智能ETL、安全助手等能力,助力企业构建高效、稳定的数据资产体系。
311 0
|
算法 C# C++
HALCON error #1201: Wrong type of control parameter: 1 in operator threshold
HALCON error #1201: Wrong type of control parameter: 1 in operator threshold
|
2月前
|
API Android开发 数据安全/隐私保护
|
2月前
|
SQL 人工智能 Rust
Java 开发中Stream的toMap与Map 使用技巧
本文深入解析了 Java 中 `toMap()` 方法的三大问题:重复键抛出异常、`null` 值带来的风险以及并行流中的性能陷阱,并提供了多种替代方案,如使用 `groupingBy`、`toConcurrentMap` 及自定义收集器,帮助开发者更安全高效地进行数据处理。
164 0
|
12月前
|
存储 Java 数据库
javax.security.auth.login.LoginException: Message stream modified (41)
`亲测可用,之前搜索了很多博客,啥样的都有,就是不介绍报错以及配置用处,根本不懂照抄那些配置是干啥的,稀里糊涂的按照博客搭完也跑不起来,因此记录这个。` `项目背景`:公司项目当前采用http协议+shiro+mysql的登录认证方式,而现在想支持ldap协议认证登录然后能够访问自己公司的项目网站。 `举例说明`:假设我们公司有自己的门户网站,现在我们收购了一家公司,他们数据库采用ldap存储用户数据,那么为了他们账户能登陆我们公司项目所以需要集成,而不是再把他们的账户重新在mysql再创建一遍,万一人家有1W个账户呢,不累死了且也不现实啊。
179 7
|
11月前
|
SQL 分布式计算 大数据
大数据-91 Spark 集群 RDD 编程-高阶 RDD广播变量 RDD累加器 Spark程序优化
大数据-91 Spark 集群 RDD 编程-高阶 RDD广播变量 RDD累加器 Spark程序优化
144 0
|
索引 Python
NumPy 快速入门:数组操作基础
【8月更文第30天】NumPy 是 Python 中一个非常重要的科学计算库,它提供了高性能的多维数组对象以及用于操作这些数组的工具。NumPy 数组(也称为 `ndarray`)是 NumPy 库的核心,它比 Python 内置的列表类型更高效,特别是在处理大型数据集时。本文将介绍 NumPy 数组的基本概念、创建方法以及一些常用的数组操作。
231 2
|
人工智能 安全 网络安全
LDAP学习笔记之三:389-DS(RHDS) 之TLS配置
LDAP学习笔记之三:389-DS(RHDS) 之TLS配置
|
移动开发
在使用钉钉H5微应用时,通过消息通知链接跳转到特定页面可能会出现一些问题
在使用钉钉H5微应用时,通过消息通知链接跳转到特定页面可能会出现一些问题
567 2