【成神之路】Linux相关面试题

操作系统中虚拟地址、逻辑地址、线性地址、物理地址的概念及区别;

物理地址(physical address):用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。
——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到 最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样。所以,说它是“与 地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一对应,也是可以接受的。也许错误的理解更利于形而上的抽像。
逻辑地址(logical address):是指由程序产生的与段相关的偏移地址部分。例如,你在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址,不和绝对物理地址相干。
线性地址(linear address)或也叫虚拟地址(virtual address)
跟逻辑地址类似,它也是一个不真实的地址,如果逻辑地址是对应的硬件平台段式管理转换前地址的话,那么线性地址则对应了硬件页式内存的转换前地址。

内存的页面置换算法;

https://blog.csdn.net/qq_36132127/article/details/81126154

进程调度算法,操作系统是如何调度进程的;

调度算法是指:根据系统的资源分配策略所规定的资源分配算法。常见的进程调度算法有:

  1.先来先去服务

  2.时间片轮转法

  3.多级反馈队列算法

  4.最短进程优先

  5.最短剩余时间优先

  6.最高响应比优先

  7.多级反馈队列调度算法

一、先来先去服务

  先来先去服务调度算法是一种最简单的调度算法,也称为先进先出或严格排队方案。当每个进程就绪后,它加入就绪队列。当前正运行的进程停止执行,选择在就绪队列中存在时间最长的进程运行。该算法既可以用于作业调度,也可以用于进程调度。先来先去服务比较适合于常作业(进程),而不利于段作业(进程)。

二、时间片轮转法

  轮转法是基于适中的抢占策略的,以一个周期性间隔产生时钟中断,当中断发生后,当前正在运行的进程被置于就绪队列中,然后基于先来先去服务策略选择下一个就绪作业的运行。这种技术也称为时间片,因为每个进程再被抢占之前都给定一片时间。

三、最短进程优先

  最短进程优先是一个非抢占策略,他的原则是下一次选择预计处理时间最短的进程,因此短进程将会越过长作业,跳至队列头。该算法即可用于作业调度,也可用于进程调度。但是他对长作业不利,不能保证紧迫性作业(进程)被及时处理,作业的长短只是被估算出来的。

四、最短剩余时间优先

  最短剩余时间是针对最短进程优先增加了抢占机制的版本。在这种情况下,进程调度总是选择预期剩余时间最短的进程。当一个进程加入到就绪队列时,他可能比当前运行的进程具有更短的剩余时间,因此只要新进程就绪,调度程序就能可能抢占当前正在运行的进程。像最短进程优先一样,调度程序正在执行选择函数是必须有关于处理时间的估计,并且存在长进程饥饿的危险。

五、最高响应比优先

根据比率:R=(w+s)/s (R为响应比,w为等待处理的时间,s为预计的服务时间)

  如果该进程被立即调用,则R值等于归一化周转时间(周转时间和服务时间的比率)。R最小值为1.0,只有第一个进入系统的进程才能达到该值。调度规则为:当前进程完成或被阻塞时,选择R值最大的就绪进程,它说明了进程的年龄。当偏向短作业时,长进程由于得不到服务,等待时间不断增加,从而增加比值,最终在竞争中赢了短进程。

  和最短进程优先、最短剩余时间优先一样,使用最高响应比策略需要估计预计服务时间。

六、反馈法

  如果没有关于进程相对长度的任何信息,则最短进程优先,最短剩余时间、最高响应优先比都不能使用。另一种导致偏向短作业的方法是处罚运行时间较长的作业,换句话说,如果不能获得剩余的执行时间,那就关注已执行了的时间。

  方法为:调度基于被抢占原则(按时间片)并使用动态优先级机制。当一个进程第一次进入系统中时,他被放置在一个优先级队列中,当第一次被抢占后并返回就绪状态时,它被放置在下一个低优先级队列中,在随后的时间里,每当被抢占时,他被降级到下一个低优先级队列中。一个短进程很快被执行完,不会在就绪队列中降很多级,一个长进程会逐渐降级。因此先到的进程和短进程优先于长进程和老进程。在每个队列中,除了优先级在最低的队列中之外,都是用简单的先来先去服务机制,一旦一个进程处于优先级最低的队列中,它就不可能在降级,但会重复的返回该队列,直到运行结束。因此,该队列课按照轮转方式调度。

 七、多级反馈队列调度算法

  多级反馈队列算法,不必事先知道各种进程所需要执行的时间,他是当前被公认的一种较好的进程调度算法。其实施过程如下:

  1)设置多个就绪队列,并为各个队列赋予不同的优先级。在优先权越高的队列中,为每个进程所规定的执行时间片就越小。

  2)当一个新进程进入内存后,首先放入第一队列的末尾,按照先来先去原则排队等候调度。如果他能在一个时间片中完成,便可撤离;如果未完成,就转入第二队列的末尾,同样等待调度.....如此下去,当一个长作业(进程)从第一队列依次将到第n队列(最后队列)后,便按第n队列时间片轮转运行。

  3)仅当第一队列空闲的时候,调度程序才调度第二队列中的进程运行;仅当第1到(i-1)队列空时,才会调度第i队列中的进程运行,并执行相应的时间片轮转。

  4)如果处理机正在处理第i队列中某进程,又有新进程进入优先权较高的队列,则此新队列抢占正在运行的处理机,并把正在运行的进程放在第i队列的队尾。

父子进程、孤儿进程、僵死进程等概念;fork进程时的操作;

进程有这么多的种类,那么进程之间定是有相关性的,而这些有关联性的进程又是如何产生的,如何衍生的?

就比如我们启动了终端,就是启动了一个 bash 进程,我们可以在 bash 中再输入 bash 则会再启动一个 bash 的进程,此时第二个 bash 进程就是由第一个 bash 进程创建出来的,他们直接又是个什么关系?

我们一般称呼第一个 bash 进程是第二 bash 进程的父进程,第二 bash 进程是第一个 bash 进程的子进程,这层关系是如何得来的呢?

关于父进程与子进程便会提及这两个系统调用 fork() 与 exec()

fork-exec是由 Dennis M. Ritchie 创造的

fork() 是一个系统调用(system call),它的主要作用就是为当前的进程创建一个新的进程,这个新的进程就是它的子进程,这个子进程除了父进程的返回值和 PID 以外其他的都一模一样,如进程的执行代码段,内存信息,文件描述,寄存器状态等等

exec() 也是系统调用,作用是切换子进程中的执行程序也就是替换其从父进程复制过来的代码段与数据段

子进程就是父进程通过系统调用 fork() 而产生的复制品,fork() 就是把父进程的 PCB 等进程的数据结构信息直接复制过来,只是修改了 PID,所以一模一样,指挥在执行 exec()之后才会不同,而早先的 fork() 比较消耗资源后来进化成 vfork(),效率高了不少。

既然子进程是通过父进程而衍生出来的,那么子进程的退出与资源的回收定然与父进程有很大的相关性。当一个子进程要正常的终止运行时,或者该进程结束时它的主函数 main() 会执行 exit(n); 或者 return n,这里的返回值 n 是一个信号,系统会把这个 SIGCHLD 信号传给其父进程,当然若是异常终止也往往是因为这个信号。

而这个时候的子进程代码执行部分其实已经结束执行了,系统的资源也基本归还给系统了,但是其进程的进程控制块(PCB)仍驻留在内存中,而它的 PCB 还在,代表这个进程还存在(因为 PCB 就是进程存在的唯一标志,里面有 PID 等消息),并没有消亡,这样的进程称之为僵尸进程(Zombie)

正常情况下,父进程会收到两个返回值一个是 exit code 也是 SIGCHLD 信号与 reason for termination 之后,父进程会使用 wait(&status) 系统调用以获取子进程的退出状态,然后内核就可以从内存中释放已结束的子进程的 PCB;而如若父进程没有这么做的话,子进程的 PCB 就会一直驻留在内存中,一直留在系统中做为僵尸进程(Zombie)。

虽然僵尸进程是已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,在进程列表中保留一个位置,记载该进程的退出状态等信息供其父进程收集,从而释放它。但是 Linux 系统中能使用的 PID 是有限的,如果系统中存在有大量的僵尸进程,系统将会因为没有可用的 PID 从而导致不能产生新的进程。

而另外如果父进程结束(非正常的结束),未能即使收回子进程,子进程仍在运行,这样的子进程称之为孤儿进程。在 Linux 系统中,孤儿进程一般会被 init 进程所“收养”,成为 init 的子进程。由 init 来做善后处理,所以它并不至于像僵尸进程那样无人问津,不管不顾,大量存在会有危害。

kill用法,某个进程杀不掉的原因

僵死进程;进入内核态,忽略kill信号;

a、该进程处于"Zombie"状态(使用ps命令返回defunct的进程)。此时进程已经释放所有资源,但还未得到其父进程的确认。"zombie"进程要等到下次重启时才会消失,但它的存在不会影响系统性能。
b、 该进程处于"kernel mode"(核心态)且在等待不可获得的资源。处于核心态的进程忽略所有信号处理,因此对于这些一直处于核心态的进程只能通过重启系统实现。进程在AIX 中会处于两种状态,即用户态和核心态。只有处于用户态的进程才可以用“kill”命令将其终止。

Linux的常用命令?

系统管理命令(如查看内存使用、网络情况);

1. 查看CPU使用情况的命令

每5秒刷新一次,最右侧有CPU的占用率的数据

$ vmstat 5

top 然后按Shift+P,按照进程处理器占用率排序

$ top

2. 查看内存使用情况的命令

用free命令查看内存占用情况

$ free

top 然后按Shift+M, 按照进程内存占用率排序

$ top

3. 查看网络流量

可以用工具iptraf工具

$ iptraf -g

针对某个Interface的网络流量可以通过比较两个时间网络接口的RX和TX数据来获得

$ date; ifconfig eth1

$ date; ifconfig eth1

4. 查看磁盘i/o

用iostat查看磁盘/dev/sdc3的磁盘i/o情况,每两秒刷新一次

$ iostat -d -x /dev/sdc3 2

用vmstat查看io部分的信息

Linux 查看CPU,内存,硬盘

1 查看CPU

1.1 查看CPU个数

# cat /proc/cpuinfo | grep "physical id" | uniq | wc -l

uniq命令:删除重复行;wc –l命令:统计行数**

1.2 查看CPU核数

# cat /proc/cpuinfo | grep "cpu cores" | uniq

cpu cores : 4

1.3 查看CPU型号

# cat /proc/cpuinfo | grep 'model name' |uniq

model name : Intel(R) Xeon(R) CPU E5630 @ 2.53GHz

总结:该服务器有2个4核CPU,型号Intel(R) Xeon(R) CPU E5630 @ 2.53GHz

2 查看内存

2.1 查看内存总数

#cat /proc/meminfo | grep MemTotal

MemTotal: 32941268 kB //内存32G

3 查看硬盘

3.1 查看硬盘大小

# fdisk -l | grep Disk

Disk /dev/cciss/c0d0: 146.7 GB, 146778685440 bytes

总结:硬盘大小146.7G,即厂商标称的160G

find命令、awk使用;

find / -name filename.txt 根据名称查找/目录下的filename.txt文件。

find . -name "*.xml" 递归查找所有的xml文件

find . -name "*" |xargs grep "hello" 递归查找所有文件内容中包含hello world的xml文件

find ./ -size 0 | xargs rm -f & 删除文件大小为零的文件

命令:awk

功能:通过正则表达式,得到需要的行,列信息

示例:

1. 用awk 打印所有包含有data字段的行

$awk ‘/data/’ install.log

2. 查看df -h命令的第2列

$df -h | awk '{print $2}'

3. 查看df -h名ing的第2,5列

$df -h | awk '{print $2,$5}'

4. 显示install.log的第四行

$awk 'NR==4' install.log

5.打印install.log文件中包含data字段行的第二区域

$awk ‘/data/ {print $2}’ install.log

6. 列示月份及年份( 为换行符)

$date | awk ‘{print “Year:” $6 “ Month:” $2 }’

7. 在有/data关键字的行的第1列后面增加1个 制表符,并增加RedHat,第2列后面!字符

$awk ‘/data/{print $1 “ RedHat Linux”$2 “!” }’ install.log

8. 在有data关键字的行第1列前面增加1个 制表符,并增加RedHat,第2列后面!字符)

$awk ‘/data/{print “ RedHat Linux, “$1,$2 “!” }’ install.log

9. 在有noarch字段的行前增加记录号($0为行头前)

$awk ‘/noarch/{print NR, $0}’ install.log

10. 在有sda2字段的行前增加行的序号及显示第2列内容

$df -h | awk '/sda2/{print NR,$2}'

11. 匹配noarch字段,如果有,则显示整行

$awk ‘$2 ~ /noarch/’ install.log

12. 匹配不存在noarch字段的行,如果有,则显示整行

$awk ‘$2 !~ /noarch/’ install.log

Linux下排查某个死循环的线程;

使用jps 或者ps -ef 查找到相应的java进程或者使用top查看机器占用cpu比例高的进程

使用top -H查看线程,进程号:13432

将线程号:13432转换成十六进制:3478

查看dump文件或者使用jstack <pid> | grep <十六进制子进程号>

top显示出来的系统信息都是什么含义;(重要!)

https://www.cnblogs.com/sbaicl/articles/2752068.html

Linux静态链接和动态链接;

静态链接:

对于静态库,程序在编译链接时,将库的代码链接到可执行文件中,程序运行时不再需要静态库。在使用过程中只需要将库和我们的程序编译后的文件链接在一起就可形成一个可执行文件。

缺点:
1、内存和磁盘空间浪费:静态链接方式对于计算机内存和磁盘的空间浪费十分严重。假如一个c语言的静态库大小为1MB,系统中有100个需要使用到该库文件,采用静态链接的话,就要浪费进100M的内存,若数量再大,那浪费的也就更多。例如下图:程序1和程序2都需要用到Lib.o,采用静态链接的话,那么物理内存中就会存放两份对应此文件的拷贝。

动态链接:由于静态链接具有浪费内存和模块更新困难等问题,提出了动态链接。基本实现思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将他们链接在一起形成一个完整的程序,而不是像静态链接那样把所有的程序模块都链接成一个单独的可执行文件。所以动态链接是将链接过程推迟到了运行时才进行。
优点:①毋庸置疑的就是节省内存;②减少物理页面的换入换出;③在升级某个模块时,理论上只需要将对应旧的目标文件覆盖掉即可。新版本的目标文件会被自动装载到内存中并且链接起来;④程序在运行时可以动态的选择加载各种程序模块,实现程序的扩展。

Linux中的grep管道用处?

命令A|命令B,即命令1的正确输出作为命令B的操作对象

为什么要内存对齐;

https://blog.csdn.net/l_tudou/article/details/51999765

为什么会有大端小端,htol这一类函数的作用;

Linux地址空间,怎么样进行寻址的;

Linux如何查找目录或者文件的;

Linux各个目录有了解过吗?/etc、/bin、/dev、/lib、/sbin这些常见的目录主要作用是什么?

进程的内存分布;

如何查找一个进程打开所有的文件;

说一下常使用的协议及其对应的端口;

为什么会有内核态,保护模式你知道吗?

文件是怎么在磁盘上存储的?

文件系统,进程管理和调度,内存管理机制、虚地址保护模式;

https://blog.csdn.net/w372426096/article/details/82657497

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值