计算机
计算机基本结构有哪几种?
CPU,内存,输入设备,输出设备,总线
为什么计算机使用二进制?
1.实现简单,CPU的IC原件的管脚电压只有0V和5V,低电压表示0,高电压表示1
2.运算规则简单,有利于简化计算机内部结构,提高运算速度
3.二进制中只使用0和1两个数字,传输和处理时不易出错,因而可以保障计算机具有很高的可靠性。
4. 逻辑运算吻合
32位和64位CPU有什么区别?
- 最主要的区别在于一次能计算多少字节的数据
cpu是由哪些组件组成的?
控制器,运算器,时钟,寄存器
cpu位宽和线路位宽
一条地址总线一次只能传输0或者1,想要一次获取32位内存地址就需要32条地址总线,这就是线路位宽
32位的CPU一次最多处理32位,所以寻址空间最多2^32=4GB,最多可以操作4GB的内存
程序的执行过程
CPU根据程序计数器获取下一条指令的内存地址,从内存读取指令到寄存器里面,再经过指令译码,然后执行,指令执行过程中如有需要取数,则从内存地址中取数,最后再将结果写入到寄存器中。
a=1+2的过程:
CPU的GHz的参数是什么意思
1GHz是指时钟频率是1G,也就是1s内能有1G次时钟周期,越快说明时钟周期越短,工作速度越快。
内存,寄存器等存储结构的关系是什么样的?
CPU怎么知道要访问的内存数据在CPU Cache中呢?
直接映射Cache:把内存地址通过计算(类似于取模)固定映射在一个Cache Line上,
一个内存地址包括三部分:组标记、CPU索引行、偏移量,相当于用这三个参数组成一个key去Cache Line中获取val
cpu cache的缓存一致性
通过总线嗅探机制实现写传播
MESI协议实现事务的串行化
cache伪共享问题(可以不看)
怎么解决?
数据填充,让热点数据不要放在一个line中 比如int改成long
基本类型占用字节数
linux软中断和硬中断?
top命令排查软中断问题
为什么负数要补码?反码,补码,左移右移
虚拟内存是什么?
为了避免两个进程用同一个内存地址,设计了虚拟内存,让每个进程都能有一套自己的内存地址,然后由CPU中的MMU统一管理。
内存分段
什么时候发生swap?
- 当内存分配时,产生了内存碎片,通过将内存和磁盘空间swap的方式解决内存碎片的问题。
- 当内存不够时,内核会淘汰部分内存至磁盘(swap out),需要的时候再换进来(swap in)
CPU运行队列有哪几种?(可以不看)
进程和线程的区别?
进程是系统运行程序和资源分配的基本单位,进程的上下⽂切换不仅包含了虚拟内存、栈、全局变量等⽤户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。
线程是进程当中的⼀条执⾏流程。线程是CPU调度的基本单位。线程共享,不同的线程共享同一份内存地址空间(java里就是堆)、代码段、文件描述符等,而线程独有的是栈空间和寄存器等,所以上下文切换比进程轻很多
linux内核中,进程和线程都是用tark_struct结构体表示,调度的基本单位也是tark_struct
进程则是程序运行的基本单位
CPU调度线程的策略有哪些?
- FIFO
每次从就绪队列选择最先进⼊队列的进程,然后⼀直运⾏,直到进程退出或被阻塞,才会继续从队列中选择第⼀个进程接着运⾏。 - 最短作业优先 优先选择运⾏时间最短的进程来运⾏,会导致运行时间长的进程一直等待
- 高响应比优先调度 响应比高的优先执行,
- 时间片轮转(使用最多的一种)
- 最高优先级 在时间片轮转的基础上加了优先级
- 多级反馈队列调度 综合时间片和优先级
进程间通信
- 管道 所谓的管道,就是内核⾥⾯的⼀串缓存,linux中的 | 就是利用管道,效率低下,只能FIFO,一个写一个读
- 消息队列 消息队列是保存在内核中的消息链表,优点是可以频繁通信,效率高,缺点是:⼀是通信不及时,⼆是附件也有⼤⼩限制,三是用户态到内核态的数据拷贝
- 共享内存 共享内存的机制,就是拿出⼀块虚拟地址空间来,映射到相同的物理内存中。这样就不用拷贝了
- 信号量 共享内存可能会修改冲突,信号量其实是⼀个整型的计数器,主要⽤于实现进程间的互斥与同步,⽽不是⽤于缓存进程间通信的数据,jvm的信号量实现也是这样的
- 信号 对于异常情况下的⼯作模式,就需要⽤「信号」的⽅式来通知进程。比如kill。信号是唯⼀的异步通信机制
- socket 跨⽹络与不同主机上的进程之间通信,就需要 Socket 通信了
多线程互斥与同步
互斥
- 自旋锁 CAS+自旋锁(忙等待锁),由CPU提供的CAS函数实现,用户态实现,不需要切换,
- 互斥锁 无等待锁(利用等待队列,类似于AQS),对于互斥锁加锁失败⽽阻塞的现象,是由操作系统内核实现的,所以互斥锁加锁失败后会有用户态切换到内核态
同步
利用信号量机制。
锁
互斥锁和自旋锁的对比
- 互斥锁加锁后释放CPU
- 自旋锁一直CPU空转(while循环)等待
- 被锁住的代码执行时间短就用自旋锁,否则用互斥锁
乐观锁和悲观锁
互斥锁和自旋锁都是悲观锁,也就是获取资源前必须先获取锁
乐观锁: 先修改完共享资源,再验证这段时间内有没有发⽣冲突,如果没有其他线程在修改资源,那么操作完成,如果发现有其他线程已经修改过这个资源,就放弃本次操作。
键盘敲⼊A 字⺟时,操作系统期间发⽣了什么?
linux怎么进行网络IO收发
IO多路复用
进程可以通过⼀个系统调⽤函数(select/poll/epoll)从内核中一次性获取多个事件;
这块直接看文档:
DMA
省掉CPU的参与文件搬运的时间
mmap
省去了内核到用户空间的数据拷贝
page cache
前面图中的内核缓存区就是page cache,其实就相当于是磁盘的缓存,因为磁盘读的太慢了。
page cache主要有两个点:
- 缓存最近被访问的数据(LRU)
- 预读功能 但是大文件会占用掉所有的cache,所以在⾼并发的场景下,针对⼤⽂件的传输的⽅式,应该使⽤「异步 I/O + 直接 I/O(不使用page cache)」来替代零拷⻉技术。
零拷贝
零拷贝的终极方案
零拷⻉(Zero-copy)技术,因为我们没有在内存层⾯去拷⻉数据,也就是说全程没有通过
CPU 来搬运数据,所有的数据都是通过 DMA 来进⾏传输的。只需要 2次上下⽂切换和数据拷⻉次数,就可以完成⽂件的传输,⽽且 2 次的数据拷⻉过程,都不需要通过 CPU,2 次都是由 DMA 来搬运。
kafak和RocketMq都使用了这个技术。
Reactor
Reactor用来实现NIO的
- 单Reactor单线程/进程
redis使用
- 单Reactor多线程/进程
因为⼀个 Reactor 对象承担所有事件的监听和响应,⽽且只在主线程中运⾏,在⾯对瞬间⾼并发的场景时,容易成为性能的瓶颈的地⽅
- 多reactor多线程/进程
MainReactor只负责连接事件,SubReactor负责read和write事件
Netty就是使用这个模式
Proactor
Proactor用来实现AIO的
C10K问题
linux命令
ls -lh df -h top less awk netstat/ss -ntlp wc -l
linux文件的软链接和硬链接的区别?
小林coding