代码的编译和执行过程?
预处理 -> 编译 -> 汇编 -> 链接 -> (加载)
动态链接
Linux下查看符号表命令、查看端口占用命令、查看进程打开的文件命令:
nm, netstat,lsof
找出占用80端口的进程? netstat -nlp | grep 80
进程的通信方法?
管道,消息队列,信号,共享内存,socket
管道一般用于父子进程,就是fork出来的。
底层实现
锁实现
自旋锁CAS,mutex睡眠等待唤醒,rcu锁机制
mutex有fast path和slow path,要是没有冲突就直接返回了,如果有冲突的话就要使用futex。futex也会先在用户空间比较,如果没有冲突就返回,如果有的话就要进行系统调用,陷入内核。
容器
CGroup是怎么实现的
虚拟化和容器在资源隔离角度的理解?
虚拟化有guest,要trap指令,页表隔离。容器只是限制资源使用,更加轻量。
LRU算法如何实现?
Linux内存管理? 伙伴系统?为什么需要Slab?内存回收是什么过程?
确定一个最小的Limit,然后把内存组成成2n个块,每次分配内存的时候确定其最接近的2x,然后从链表中找,如果没有找到,就一直拆分更大的页直到有这么一个页出来。页面只能和自己的伙伴页进行合并,而不能与别人进行合并。
slab用于对象的分配。
虚拟内存
物理页的地址被存在多级的页表中,通过多次查表进行地址转换
Huge Pages
第三级页表允许直接映射2M的页面,第二级页表允许直接映射1G的页面。
Zones
ZONE_DMA
可以直接被设备访问的内存, ZONE_HIGHMEM
不能被映射到地址空间的内存 ZONE_NORMAL
能被正常映射的内存。
NUMA
每个处理器组有自己的内存,不同处理器对同一块内存访问的延时不一样,取决于处理器到内存的距离。这样的话每一个NUMA节点都会有一个内存管理的子结构。
Page Cache
读写文件时会进行缓存
Anonymous Memory
mmap产生的匿名内存
Kernel Samepage Merging
合并相同的页面
建议合并
int madvise(addr, length, MADV_MERGEABLE)
取消建议
int madvise(addr, length, MADV_UNMERGEABLE)
访问一个虚拟内存地址可能会有多少次内存访问?Linux几级页表?TLB?
amd64系统 9,9,9,9,12=48(线性地址)
cache命中了就不需要访存了。
访问一次虚拟内存需要多少次内存访问:
要查段表吗
TLB未命中,需要页表级数+1
TLB命中一次就行
查TLB和查cache是同时进行的,需要比较标记位来判断是不是命中了。
mmap机制了解吗?为什么mmap文件读写比read/write快?mmap的文件,写入中途断电会怎么样?
mmap 1. 分配大块内存 2. 读写文件 3. 共享内存
mmap会将文件映射到进程的虚拟地址空间,再实际读写中会触发缺页中断。
mmap只需一次系统调用,而read/write每次都是系统调用,减少了很多内核态和用户态之间的转换。read/write需要从文件到内核的page cache,再到用户空间,多了一次拷贝。但是好像内存之间的拷贝时间应该很短,主要应该还是用户态和内核态进行切换的开销。mmap的数据会在内存中,断电应该就没了。
进程和线程有什么区别?
- 进程(Process)是系统进行资源分配和调度的基本单位,线程(Thread)是CPU调度和分派的基本单位;
- 线程依赖于进程而存在,一个进程至少有一个线程;
- 进程有自己的独立地址空间,线程共享所属进程的地址空间;
- 进程是拥有系统资源的一个独立单位,而线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),和其他线程共享本进程的相关资源如内存、I/O、cpu等;
- 在进程切换时,涉及到整个当前进程CPU环境的保存环境的设置以及新被调度运行的CPU环境的设置,而线程切换只需保存和设置少量的寄存器的内容,并不涉及存储器管理方面的操作,可见,进程切换的开销远大于线程切换的开销;
- 线程之间的通信更方便,同一进程下的线程共享全局变量等数据,而进程之间的通信需要以进程间通信(IPC)的方式进行;
- 多线程程序只要有一个线程崩溃,整个程序就崩溃了,但多进程程序中一个进程崩溃并不会对其它进程造成影响,因为进程有自己的独立地址空间,因此多进程更加健壮。
前沿技术
RDMA MPK PIM