当前位置: 首页 > news >正文

Java面试之操作系统

1、冯诺依曼模型

运算器、控制器、存储器、输入设备、输出设备

32位和64位CPU最主要区别是一次性能计算多少字节数据,如果计算的数额不超过 32 位数字的情况下,32 位和 64 位 CPU 之间没什么区别的,只有当计算超过 32 位数字的情况下,64 位的优势才能体现出来

线路位宽  cpu能操作的内存大小 比如cpu想要操作4G的内存,就需要32条地址总线。2^32=4G

2、程序执行的基本过程

一个程序执行的时候,CPU 会根据程序计数器里的内存地址,从内存里面把需要执行的指令读取到指令寄存器里面执行,然后根据指令长度自增,开始顺序读取下一条指令。

3、指令的执行速度

程序的CPU执行时间=指令数*每条指令的平均时钟周期数*时钟周期时间

时钟周期时间=1/电脑主频  如1/2.4G

4、存储

寄存器

CPU cache SRAM 静态随机存储器  

  • 每个 CPU 核心都有一块属于自己的 L1 高速缓存,指令和数据在 L1 是分开存放的,所以 L1 高速缓存通常分成指令缓存数据缓存
  •  L2 高速缓存位置比 L1 高速缓存距离 CPU 核心 更远 大小比 L1 高速缓存更大
  • L3 高速缓存通常是多个 CPU 核心共用的

内存   DRAM (Dynamic Random Access Memory,动态随机存取存储器) 的芯片。数据会被存储在电容里,电容会不断漏电,所以需要「定时刷新」电容,才能保证数据不会被丢失

CPU 从 L1 Cache 读取数据的速度,相比从内存读取的速度,会快 100 多倍

硬盘

  • 固态硬盘:断电后数据还是存在的,而内存、寄存器、高速缓存断电后数据都会丢失。内存的读写速度比 SSD 大概快 10~1000 倍。
  • 机械硬盘:通过物理读写的方式来访问数据的,因此它访问速度是非常慢的,它的速度比内存慢 10W 倍左右。

每个存储器只和相邻的一层存储器设备打交道

5、如何写出让CPU 跑的快的代码

CPU Cache 的数据是从内存中读取过来的,它是以一小块一小块读取数据的

CPU L1 Cache 分为数据缓存和指令缓存,因而需要分别提高它们的缓存命中率:

  • 对于数据缓存,我们在遍历数据的时候,应该按照内存布局的顺序操作,这是因为 CPU Cache 是根据 CPU Cache Line 批量操作数据的,所以顺序地操作连续内存数据时,性能能得到有效的提升;
  • 对于指令缓存,有规律的条件分支语句能够让 CPU 的分支预测器发挥作用,进一步提高执行的效率;

对于多核 CPU 系统,线程可能在不同 CPU 核心来回切换,这样各个核心的缓存命中率就会受到影响,于是要想提高线程的缓存命中率,可以考虑把线程绑定 CPU 到某一个 CPU 核心。 

6、cpu缓存一致性

写数据

写直达 如果cache已经存在,则更新后写入内存  如果cache不存在,则把数据更新到内存

写回     对于已经缓存在 Cache 的数据的写入,只需要更新其数据就可以,不用写入到内存,只有在需要把缓存里面的脏数据交换出去的时候,才把数据同步到内存里,这种方式在缓存命中率高的情况,性能会更好

如何缓存一致

  • 写传播,也就是当某个 CPU 核心发生写入操作时,需要把该事件广播通知给其他核心;
  • 第二点是事物的串行化,顺序

 总线嗅探机制的 MESI 协议  已修改、独占、共享、已失效  

对于在「已修改」或者「独占」状态的 Cache Line,修改更新其数据不需要发送广播给其他 CPU 核心。

7、伪共享

CPU Cache Line 大小一般是 64 个字节 这种因为多个线程同时读写同一个 Cache Line 的不同变量时,而导致 CPU Cache 失效的现象称为伪共享 

如何避免?

 多个线程共享的热点数据,即经常会修改的数据,应该避免这些数据刚好在同一个 Cache Line 中,否则就会出现为伪共享的问题。

在 Linux 内核中存在 __cacheline_aligned_in_smp 宏定义,是用于解决伪共享的问题。是用空间换时间

字节填充

8、cpu选择线程

  • SCHED_DEADLINE:是按照 deadline 进行调度的,距离当前时间点最近的 deadline 的任务会被优先调度;实时任务总是会比普通任务优先被执行
  • SCHED_FIFO:对于相同优先级的任务,按先来先服务的原则,但是优先级更高的任务,可以抢占低优先级的任务,也就是优先级高的可以「插队」;
  • SCHED_RR:对于相同优先级的任务,轮流着运行,每个任务都有一定的时间片,当用完时间片的任务会被放到队列尾部,以保证相同优先级任务的公平性,但是高优先级的任务依然可以抢占低优先级的任务;

9、软中断 

中断处理程序的上部分和下半部可以理解为:

  • 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行;
  • 下半部是由内核触发,也就说软中断,主要是负责上半部未完成的工作,通常都是耗时比较长的事情,特点是延迟执行;

 Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型  软中断的处理是通过“ksoftirqd”内核线程来实现的

10、补码

有了补码,负数的加减法操作,实际上是和正数加减法操作一样的

十进制整数转二进制使用的是「除 2 取余法」,倒序     

十进制小数使用的是「乘 2 取整法」正序

计算机存小数 符号位 指数位 尾数位

小数计算不精确的原因

因为有的小数无法可以用「完整」的二进制来表示,所以计算机里只能采用近似数的方式来保存,那两个近似数相加,得到的必然也是一个近似数。

11、内核

内核作为应用连接硬件设备的桥梁

  • 进程调度
  • 内存管理
  • 为进程与硬件设备之间提供通信
  • 提供系统调用 应用程序要运行更高权限运行的服务,那么就需要有系统调用,它是用户程序与操作系统之间的接口。

linux内核设计的理念

  • 多任务  并发并行
  • 对称多处理  每个 CPU 的地位是相等的
  • 可执行文件链接格式   Linux 可执行文件格式叫作 ELF,Windows 可执行文件格式叫作 PE。
  • 宏内核    Linux 的内核是宏内核    Windows的内核设计是混合型内核,   

微内核,有一个最小版本的内核,一些模块和服务则由用户态管理;

混合内核,是宏内核和微内核的结合体,内核中抽象出了微内核的概念,也就是内核中会有一个小型的内核,其他模块就在这个基础上搭建,整个内核是个完整的程序;

宏内核,包含多个模块,整个内核像一个完整的程序;

12、虚拟内存

 操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。多进程之间地址冲突问题

虚拟内存还可以是的进程对运行内存超过物理内存的大小

页表里的页表项中除了物理地址之外,还有一些标记属性的比特,比如控制一个页的读写权限,标记该页是否存在等。在内存访问方面,操作系统提供了更好的安全性。

操作系统是如何管理虚拟地址与物理地址之间的关系? 

内存分段  虚拟地址是通过段表与物理地址进行映射的,分段机制会把程序的虚拟地址分成 4 个段,每个段在段表中有一个项,在这一项找到段的基地址,再加上偏移量,于是就能找到物理内存中的地址

问题:内存碎片   内存交换的效率低

  • 每个段的长度不固定,所以多个段未必能恰好使用所有的内存空间,会产生了多个不连续的小物理内存,导致新的程序无法被装载,所以会出现外部内存碎片的问题

内存分页 

分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小  在 Linux 下,每一页的大小为 4KB采用了分页,页与页之间是紧密排列的,所以不会有外部碎片。如果内存空间不够,操作系统会把其他正在运行的进程中的「最近没被使用」的内存页面给释放掉,也就是暂时写在硬盘上,称为换出Swap Out)。一旦需要的时候,再加载进来,称为换入Swap In)。所以,一次性写入磁盘的也只有少数的一个页或者几个页,不会花太多时间,内存交换的效率就相对比较高。

问题:页表会非常的庞大

解决方案:多级页表

问题:多了几道转换的工序,这显然就降低了这俩地址转换的速度

解决方案:在 CPU 芯片中,加入了一个专门存放程序最常访问的页表项的 Cache,这个 Cache 就是 TLB

13、malloc是如何分配内存的  

malloc() 源码里默认定义了一个阈值:

  • 如果用户分配的内存小于 128 KB,则通过 brk() 申请内存;
  • 如果用户分配的内存大于 128 KB,则通过 mmap() 申请内存;

malloc()分配的是虚拟内存  如果分配后的虚拟内存没有被访问的话,虚拟内存是不会映射到物理内存的,这样就不会占用物理内存了  只有在访问已分配的虚拟地址空间的时候,操作系统通过查找页表,发现虚拟内存对应的页没有在物理内存中,就会触发缺页中断,然后操作系统会建立虚拟内存和物理内存之间的映射关系。

malloc 申请的内存,free 释放内存会归还给操作系统吗?

  • malloc 通过 brk() 方式申请的内存,free 释放内存的时候,并不会把内存归还给操作系统,而是缓存在 malloc 的内存池中,待下次使用
  • malloc 通过 mmap() 方式申请的内存,free 释放内存的时候,会把内存归还给操作系统,内存得到真正的释放

mmap()是通过系统调用来实现的,会发生运行态的切换 

14、内存回收 

应用程序通过 malloc 函数申请内存的时候,实际上申请的是虚拟内存,此时并不会分配物理内存。

当应用程序读写了这块虚拟内存,CPU 就会去访问这个虚拟内存, 这时会发现这个虚拟内存没有映射到物理内存, CPU 就会产生缺页中断,进程会从用户态切换到内核态,并将缺页中断交给内核的 Page Fault Handler (缺页中断函数)处理。

缺页中断处理函数会看是否有空闲的物理内存:

  • 如果有,就直接分配物理内存,并建立虚拟内存与物理内存之间的映射关系。
  • 如果没有空闲的物理内存,那么内核就会开始进行回收内存 (opens new window)的工作,如果回收内存工作结束后,空闲的物理内存仍然无法满足此次物理内存的申请,那么内核就会放最后的大招了触发 OOM (Out of Memory)机制。

后台内存回收 异步

直接内存回收 同步

  • 文件页的回收:对于干净页是直接释放内存,这个操作不会影响性能,而对于脏页会先写回到磁盘再释放内存,这个操作会发生磁盘 I/O 的,这个操作是会影响系统性能的。
  • 匿名页的回收:如果开启了 Swap 机制,那么 Swap 机制会将不常访问的匿名页换出到磁盘中,下次访问时,再从磁盘换入到内存中,这个操作是会影响系统性能的。

直接回收 但是空闲的物理内存仍然无法满足此次物理内存的申请,那么内核就会触发 OOM 机制

针对回收内存导致的性能影响,常见的解决方式。

  • 设置 /proc/sys/vm/swappiness,调整文件页和匿名页的回收倾向,尽量倾向于回收文件页;
  • 设置 /proc/sys/vm/min_free_kbytes,调整 kswapd 内核线程异步回收内存的时机;
  • 设置 /proc/sys/vm/zone_reclaim_mode,调整 NUMA 架构下内存回收策略,建议设置为 0,这样在回收本地内存之前,会在其他 Node 寻找空闲内存,从而避免在系统还有很多空闲内存的情况下,因本地 Node 的本地内存不足,发生频繁直接内存回收导致性能下降的问题;

15、 在4G物理内存的机器上,申请8G内存会怎么样

  • 在 32 位操作系统,因为进程理论上最大能申请 3 GB 大小的虚拟内存,所以直接申请 8G 内存,会申请失败。
  • 在 64位 位操作系统,因为进程理论上最大能申请 128 TB 大小的虚拟内存,即使物理内存只有 4GB,申请 8G 内存也是没问题,因为申请的内存是虚拟内存。如果这块虚拟内存被访问了,要看系统有没有 Swap 分区:
    • 如果没有 Swap 分区,因为物理空间不够,进程会被操作系统杀掉,原因是 OOM(内存溢出);
    • 如果有 Swap 分区,即使物理内存只有 4GB,程序也能正常使用 8GB 的内存,进程可以正常运行;

 

http://www.lryc.cn/news/416052.html

相关文章:

  • springboot船舶维保管理系统--论文源码调试讲解
  • 【机器学习西瓜书学习笔记——神经网络】
  • 安装 electron 报错解决
  • 【Material-UI】Icon Button 组件详解
  • 51单片机-第七节-DS1302实时时钟
  • Java毕业设计 基于SSM和Vue的图书馆座位预约系统小程序
  • 【C++11】:lambda表达式function包装器
  • [io]进程间通信 -有名、无名管道 区别
  • pywinauto:Windows桌面应用自动化测试(七)
  • RGB++是什么;UTXO是什么;Nervos网络;CKB区块链;
  • 轻闪PDF v2.14.9 解锁版下载与安装教程 (全能PDF转换器)
  • mysql 5.7 解析binlog日志,并统计每个类型语句(insert、update、delete)、每个表的执行次数
  • MySQL案例:MHA实现主备切换(主从架构)万字详解
  • 81.SAP ME - SAP SMGW Getway Monitor
  • SAPUI5基础知识24 - 如何向manifest.json中添加模型(小结)
  • 操作系统---文件管理
  • C语言指针详解(三)目录版
  • 【AI资讯早报】AI科技前沿资讯概览:2024年8月6日早报
  • 等保测评中的密码技术与密钥管理
  • go语言flag库学习
  • 2024年必备技能:智联招聘岗位信息采集技巧全解析
  • 《机器学习by周志华》学习笔记-决策树-02
  • centos Python3.6升级3.8
  • 文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于竞价空间预测的虚拟电厂日前竞价策略》
  • Simulink模型开发中的一些自动化方法
  • RabbitMQ消费者消费消息失败处理
  • Apache Kylin分布式的分析数据仓库
  • informer中DeltaFIFO机制的实现分析与源码解读
  • 树莓派下,centos7amr64下,搭建目标检测开发环境,java语言
  • SpringBoot+Redis 发布与订阅