面经......

目录

vim用法:

数据库:

一、delete,truncate,drop有什么区别

二、介绍一下B树,B+树

三、为啥加了索引查询会变快?

四、数据库索引

五、事务的四大特性

六、悲观锁和乐观锁

七、union和union all区别?

八、数组和链表的区别

计算机网络:

一、输入www.baidu.com 发生了什么?

二、get和post的区别(delete,put(创建或者是更新资源))

三、常见的路由协议

四、http几个版本的区别

五、HTTP与HTTPS的区别

六、traceroute和ping的区别,ttl是什么?

七、各层有的协议:

八、常见协议端口号

九、HTTP状态码

操作系统:

零、lvs负载均衡

一、进程和线程的区别

进程间的调度算法

二、死锁

三、进程间常见的通信方式

四、top命令后load average 什么意思?

五、Linux启动顺序?

六、Linux 如何查看主机的cpu个数和总内存?

七、软硬链接的区别?

八、linux查看内核版本,系统版本,查看流量

九、linux启动过程(centos6)

十、Linux的运行等级(centos6)

十一、常见的io模型,阻塞,非阻塞,同步,异步,多路复用

十二、分页和分段的区别?

其他

一、算某时间到某时间过了多少天

二、产生随机32位密码

三、tomcat,nginx,apache区别



vim用法:

跳到最后一行(命令模式下输入$也就是按冒号):

:$

G(shift+g)(ESC进入普通模式)

跳到首行(命令模式下输入1也就是按冒号):

:1

 gg(ESC进入普通模式)

**************************************************************************************************************

行首:^

行尾:$

  • i: 在光标前插入;
  • a: 在光标后插入;
  • A: 在当前行最后插入;
  • o: 在下面新建一行插入;
  • O: 在上面新建一行插入;

数据库:

一、delete,truncate,drop有什么区别

1.delete 是DML语句,走事务,能回滚,一行一行删除,它其实没有真正删除数据,只是把删除的数据打了个标签为已删除,所以不会释放磁盘空间。但该空间还是可用的,可以被其他数据重用也就是覆盖。并且删除操作日志记录在redo和undo,以便回滚,会占用磁盘空间。
   delete from table;会删除所有数据行。在myaism中会立即释放磁盘空间,在innodb中不会释放磁盘空间
   delete from table where ...  ;对于myaism和innodb都不会释放磁盘空间。
   对于delete想释放磁盘空间的话,delete后执行一个optimize table 操作就可以了。
2.truncate是DDL语句,不走事务。不可回滚,删除所有数据,并立即释放磁盘空间。但表结构会保留。
3.drop是DDL语句,不走事务。不可回滚。删除所有数据,并立即释放磁盘空间。表结构也会删除。

二、介绍一下B树,B+树

B树所有节点都会存储相应的键值(索引值和data),而B+树只有叶子节点存储键值。
B树遍历是一层一层的遍历,B+树只遍历叶子节点。所以遍历速度比B树快,有利于数据库做全表扫描。
B+树查询的数据都在叶子节点上,所以每次遍历的次数是相同的,查询速度也就比B树更加稳定。
B+树的所有叶子节点相互连接,构成了有序链表,所以在范围查询更有优势。
如果经常访问的数据距离根节点近的话,B树非叶子节点本身就存有相关数据,所以这种检索要比B+树快。

三、为啥加了索引查询会变快?

因为索引使用了B+树数据结构来存储,利用了二分查找的原理,有效的减少的磁盘的IO消耗,所以性能会提升。

四、数据库索引

聚集索引:MySQL 会自动选择主键作为聚集索引列,没有主键会选择唯一键,如果都没有会生成隐藏的,叶子节点不仅存储列值,也会存储真实的数据行,一张表只能有一个聚集索引,因为物理存储只能有一个。
辅助索引:叶子节点存储列值,也会存储聚集索引列值,也就是主键id,如果查找时的数据全部命中索引,就会走覆盖索引,直接拿到数据,不用回表。
如果数据没有全部命中的话,就会再通过主键id去找到完整的行数据。
联合索引:把多列创建成一个索引。
最左前缀原则:对于联合索引,MySQL 会一直向右匹配直到遇到范围查询(> , < ,between,like)就停止匹配。如果索引全是等值查询的话顺序可以打乱,因为mysql优化器会自动帮你调整顺序成你建立索引的顺序。

五、事务的四大特性

原子性:一个事务开启后所有操作要么全部成功,要么全部失败。
一致性:事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。
隔离:各个事务相互不影响。
持久:事务成功后,对数据改变是永久性的。

六、悲观锁和乐观锁

首先锁是用来保护我们数据安全的机制和手段例如当我们有多个线程去访问修改共享变量的时候,我们可以给修改操作加锁(syncronized)。当多个用户修改表中同一数据时,我们可以给该行数据上锁(行锁)。因此,当程序中可能出现并发的情况时,我们就需要通过一定的手段来保证在并发情况下数据的准确性,通过这种手段保证了当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的。

没有做好并发控制,就可能导致脏读、幻读和不可重复读等问题

悲观锁: 就是很悲观,每次去拿数据的时候都认为别人会修改。所以每次在拿数据的时候都会上锁。这样别人想拿数据就被挡住,直到悲观锁被释放,悲观锁中的共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程

但是在效率方面,处理加锁的机制会产生额外的开销,还有增加产生死锁的机会。另外还会降低并行性,如果已经锁定了一个线程A,其他线程就必须等待该线程A处理完才可以处理

数据库中的行锁,表锁,读锁(共享锁),写锁(排他锁),以及syncronized实现的锁均为悲观锁

乐观锁(Optimistic Lock): 就是很乐观,每次去拿数据的时候都认为别人不会修改。所以不会上锁,但是如果想要更新数据,则会在更新前检查在读取至更新这段时间别人有没有修改过这个数据。如果修改过,则重新读取,再次尝试更新,循环上述步骤直到更新成功(当然也允许更新失败的线程放弃操作),乐观锁适用于多读的应用类型,这样可以提高吞吐量

相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本(version)或者是时间戳来实现。

说到乐观锁,就必须提到一个概念:CAS
什么是CAS呢?Compare-and-Swap,即比较并替换,也有叫做Compare-and-Set的,比较并设置。
1、比较:读取到了一个值A,在将其更新为B之前,检查原值是否仍为A(未被其他线程改动)。
2、设置:如果是,将A更新为B,结束。[1]如果不是,则什么都不做。
上面的两步操作是原子性的,可以简单地理解为瞬间完成,在CPU看来就是一步操作。
有了CAS,就可以实现一个乐观锁,允许多个线程同时读取(因为根本没有加锁操作),但是只有一个线程可以成功更新数据,并导致其他要更新数据的线程回滚重试。 CAS利用CPU指令,从硬件层面保证了操作的原子性,以达到类似于锁的效果。

ABA 问题:
如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。

ABA 问题解决:
我们需要加上一个版本号(Version),在每次提交的时候将版本号+1操作,那么下个线程去提交修改的时候,会带上版本号去判断,如果版本修改了,那么线程重试或者提示错误信息。

如何选择: 

悲观锁阻塞事务,乐观锁回滚重试,它们各有优缺点,不要认为一种一定好于另一种。像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。

但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

原文链接:https://blog.csdn.net/qq_14996421/article/details/106351873

七、union和union all区别?

union去重并排序,union all直接返回合并的结果,不去重也不排序;
所以union all比union性能好;

八、数组和链表的区别

数组在内存中是连续的,声明时就需要确定长度。

数组查找元素直接从首地址偏移就好了,时间复杂度是(1)。链表访问时需要从头节点遍历,时间复杂度是O(N)。
定义数组时它的内存空间是固定的,不能动态扩容和缩减,而链表可以。所以空间利用率链表比数组好。

数组在位于栈区,链表位于堆区。

计算机网络:

一、输入www.baidu.com 发生了什么?

1.浏览器看缓存
2.无缓存找本地host文件看看是否有域名解析

3.无的话对本地域名服务器进行递归查询
4.本地域名服务器找不到向根域名服务器找进行迭代查询
5.根域名服务器返回顶级域名服务器.com的ip地址
6.本地服务器向顶级域名服务器.com查找
7.顶级域名服务器.com返回二级域名baidu.com的ip地址
8.本地服务器向baidu.com找
9.baidu.com返回三级域名服务器www.baidu.com的ip地址
10.本地域名服务向www.baidu.com返回所查询主机的ip地址
11.本地域名服务器告诉本地主机查询结果。

12. 浏览器发出HTTP请求,请求百度首页
13.服务器通过HTTP响应把首页文件发送给浏览器
14.TCP连接释放
15. 浏览器将首页文件进行解析,并将Web页显示给用户。

二、get和post的区别(delete,put(创建或者是更新资源))

get是不安全的,因为在传输过程中,数据被放在请求的url中;post的操作对用户来说都是不可见的。

get放在url之后,post会把提交的数据放在请求体中。

一般来说,get的请求长度允许被发送的数据量比较小,而post请求则是没有大小限制的。

get一般用来从服务器上获取数据,post一般用来更新服务器上的数据

三、常见的路由协议

1、RIP(Routing Information Protocol):路由信息协议。

是一种比较简单的内部网关协议,主要用于规模较小的网络,比如校园网以及结构较简单的地区性网络。对于更为复杂的环境和大型网络,一般不使用RIP。

RIP是一种基于距离矢量(Distance-Vector)算法的协议,它通过UDP报文进行路由信息的交换,使用的端口号为520。其使用跳数来衡量到达目的地址的距离,为了限制收敛时间,RIP规定度量值(该值等于从本网络到达目的网络间的路由器数量)为0到15之间的整数,大于等于16的跳数将会定义为网络或主机不可达,因此RIP不适合大型网络。

2、OSPF(Open Shortest Path First):开放式最短路径优先协议。

属于链路状态路由协议,OSPF提出了“区域(area)”的概念,每个区域中所有路由器维护着一个相同的链路状态数据库 (LSDB),其使用链路状态数据库,通过最短生成树算法(SPF算法)计算得到路由表,因此其收敛速度较快。目前OSPF协议在各种网络中广泛部署

3.ARP与RARP都属于网络层协议,但是他们是为了解决链路层的帧转发问题,ARP的功能是将IP解析成MAC地址,而RARP则相反。

四、http几个版本的区别

http1.0和http1.1

1、长链接

        HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接。

        HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用个长连接来发多个请求。

2、节约带宽
HTTP 1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接受到100,才开始把请求body发送到服务器。这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。

支持断点传输(把文件分成几部分):另外HTTP1.1还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只需要跟服务器请求另外的部分资源即可。

3、增加HOST域

以web server例如tomat,设置虚拟站点是非常常见的,也即是说,web server上的多个虚拟站点可以共享同一个ip和端口。

HTTP1.0是没有host域的,HTTP1.1才支持这个参数。

http1.x和http2.0

1.多路复用

1、HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。

当然HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。

TCP连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立好的连接,并且这个连接可以支持瞬时并发的请求。

2、数据压缩

HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

3、服务器推送

意思是说,当我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。

服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。

五、HTTP与HTTPS的区别

安全性上,HTTPS是安全超文本协议,在HTTP基础上有更强的安全性。简单来说,HTTPS是使用TLS/SSL加密的HTTP协议

申请证书上,HTTPS需要使用ca申请证书

传输协议上, HTTP是超文本传输协议,明文传输;HTTPS是具有安全性的 SSL 加密传输协议

连接方式与端口上,http的连接简单,是无状态的,端口是 80; https 在http的基础上使用了ssl协议进行加密传输,端口是 443

六、traceroute和ping的区别,ttl是什么?

Tracert:用来显示数据包到达目标主机所经过的路径,并显示到达每个节点的时间。命令功能同Ping类似,但它所获得的信息要比Ping命令详细得多,它把数据包所走的全部路径、节点的IP以及花费的时间都显示出来。

Tracert 先发送 TTL 为 1 的回应数据包,当数据包上的 TTL在路由器收到后TTL自动减1 ,一旦某个服务器将TTL减1后,等于了0,路由器应该将“ICMP Time Exceeded”的消息发回源计算机,源计算机就根据收到的信息判断达到的路由器和所用时间。下次再次发送数据包时,将TTL递增 1,继续上述测试,直到目标响应或 TTL 达到最大值,从而确定路由。通过检查中间路由器发回的“ICMP 已超时”的消息确定路由。某些路由器不经询问直接丢弃 TTL过期的数据包,这在 Tracert 实用程序中看不到,我们会显示请求超时的请求信息。

ping :是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。ping 使用的是ICMP协议,它发送icmp回送请求消息给目的主机。ICMP协议规定:目的主机必须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。

TTL:是该字段指定IP包被路由器丢弃之前允许通过的最大网段数量。TTL是IPv4包头的一个8 bit字段。例如IP包在服务器中发送前设置的TTL是64,你使用ping命令后,得到服务器反馈的信息,其中的TTL为56,说明途中一共经过了8道路由器的转发,每经过一个路由,TTL减1。

七、各层有的协议:

OSI7层模型:

应用层:网络服务与最终用户的一个接口。协议有:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP

表示层:数据的表示、安全、压缩。(在五层模型里面已经合并到了应用层)。格式有:JPEG、ASCll、EBCDIC、加密格式等

会话层:建立、管理、终止会话。(在五层模型里面已经合并到了应用层)。对应主机进程,指本地主机与远程主机正在进行的会话

传输层:定义传输数据的协议端口号,以及流控和差错校验。协议有:TCP UDP,数据包一旦离开网卡即进入网络传输层

网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。协议有:ICMP IGMP IP(IPV4 IPV6)

数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能。(由底层网络定义协议)。将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。

物理层:建立、维护、断开物理连接。

应用层:    
    : DHCP(动态主机分配协议)
    · DNS (域名解析)
    · FTP(File Transfer Protocol)文件传输协议
    · HTTP (Hypertext Transfer Protocol)超文本传输协议
    · POP3 (Post Office Protocol 3)即邮局协议的第3个版本
    · SMTP (Simple Mail Transfer Protocol)即简单邮件传输协议
    · SSH (Secure Shell)安全外壳协议
    · TELNET 远程登录协议
    · NTP (Network Time Protocol)网络校时协议
传输层:
    ·TCP(Transmission Control Protocol)传输控制协议
    · UDP (User Datagram Protocol)用户数据报协议
网络层(ip层):
    IP(IPv4 · IPv6) Internet Protocol(网络之间互连的协议)
    ARP : Address Resolution Protocol即地址解析协议,实现通过IP地址得知其物理地址。
    RARP :Reverse Address Resolution Protocol 反向地址转换协议允许局域网的物理机器从网关服务器的 ARP 表或者缓存上请求其 IP 地址。
    ICMP(ICMPv6) :(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。
    IGMP :Internet 组管理协议(IGMP)是因特网协议家族中的一个组播协议,用于IP 主机向任一个直接相邻的路由器报告他们的组成员情况。
    OSPF : (Open Shortest Path First开放式最短路径优先).

数据链路层:
          802.11  · 802.16 · 
               Wi-Fi 


八、常见协议端口号

Telnet                23
SSH                22
FTP                20、21
HTTP                80
HTTPS                443
SMTP                25
DNS                53
NTP                123
POP3                110

九、HTTP状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
常见的状态码:
200 ok                客户端请求成功
400 Bad Request            客户端请求有语法错误,不能被服务端理解
401 Unauthorized            请求未经授权
403 Forbidden            请求被拒绝
404 Not Found            请求资源不存在,比如:输入到了错误的URl
500 Internal Server Error        服务器发生了不可预期的错误
503 Server Unavailable        服务器当前不能处理客户端的请求,一段时间后可能恢复正常

操作系统:

零、lvs负载均衡

 LVS(Linux Virtual Server)即Linux虚拟服务器,它是在Linux内核中实现了基于IP的数据请求负载均衡调度方案,互联网用户从外部访问公司的外部负载均衡服务器,用户的Web请求会发送给LVS调度器,调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器,比如,轮询算法可以将外部的请求平均分发给后端的所有服务器。

1、基于NAT的LVS模式负载均衡

      NAT(Network Address Translation)即网络地址转换,其作用是通过数据报头的修改,使得位于企业内部的私有IP地址可以访问外网,以及外部用用户可以访问位于公司内部的私有IP主机。VS/NAT工作模式拓扑结构如图2所示,LVS负载调度器可以使用两块网卡配置不同的IP地址,eth0设置为私钥IP与内部网络通过交换设备相互连接,eth1设备为外网IP与外部网络联通。

       第一步,用户通过互联网DNS服务器解析到公司负载均衡设备上面的外网地址,相对于真实服务器而言,LVS外网IP又称VIP(Virtual IP Address),用户通过访问VIP,即可连接后端的真实服务器(Real Server),而这一切对用户而言都是透明的,用户以为自己访问的就是真实服务器,但他并不知道自己访问的VIP仅仅是一个调度器。

   第二步,用户将请求发送至124.126.147.168,此时LVS将根据预设的算法选择后端的一台真实服务器(192.168.0.1~192.168.0.3),将数据请求包转发给真实服务器,并且在转发之前LVS会修改数据包中的目标地址以及目标端口,目标地址与目标端口将被修改为选出的真实服务器IP地址以及相应的端口。

    第三步,真实的服务器将响应数据包返回给LVS调度器,调度器在得到响应的数据包后会将源地址和源端口修改为VIP及调度器相应的端口,修改完成后,由调度器将响应数据包发送回终端用户。另外,由于LVS调度器有一个连接Hash表,该表中会记录连接请求及转发信息,当同一个连接的下一个数据包发送给调度器时,从该Hash表中可以直接找到之前的连接记录,并根据记录信息选出相同的真实服务器及端口信息。

2、基于TUN的LVS负载均衡

       在LVS(NAT)模式的集群环境中,由于所有的数据请求及响应的数据包都需要经过LVS调度器转发,如果后端服务器的数量大于10台,则调度器就会成为整个集群环境的瓶颈。我们知道,数据请求包往往远小于响应数据包的大小。因为响应数据包中包含有客户需要的具体数据,所以LVS(TUN)的思路就是将请求与响应数据分离,让调度器仅处理数据请求,而让真实服务器响应数据包直接返回给客户端。VS/TUN工作模式拓扑结构如图3所示。其中,IP隧道(IP tunning)是一种数据包封装技术,它可以将原始数据包封装并添加新的包头(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的VIP地址的数据包封装,通过隧道转发给后端的真实服务器(Real Server),通过将客户端发往调度器的原始数据包封装,并在其基础上添加新的数据包头(修改目标地址为调度器选择出来的真实服务器的IP地址及对应端口),LVS(TUN)模式要求真实服务器可以直接与外部网络连接,真实服务器在收到请求数据包后直接给客户端主机响应数据。
3、常见的调度算法

1.轮询调度

轮询调度(Round Robin 简称'RR')算法就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都一样的,调度器会将所有的请求平均分配给每个真实服务器。

2.加权轮询调度

加权轮询(Weight Round Robin 简称'WRR')算法主要是对轮询算法的一种优化与补充,LVS会考虑每台服务器的性能,并给每台服务器添加一个权值,如果服务器A的权值为1,服务器B的权值为2,则调度器调度到服务器B的请求会是服务器A的两倍。权值越高的服务器,处理的请求越多。

3.最小连接调度

最小连接调度(Least Connections 简称'LC')算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态的调度算法,它通过服务器当前活跃的连接数来估计服务器的情况。调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1;当连接中断或者超时,其连接数减1。

一、进程和线程的区别

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,线程所使用的资源来自其所属进程的资源,线程组之间只能共享资源。

包含关系:线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源

进程的三个状态:
就绪:进程处于可运行的状态,只是CPU时间片还没有轮转到该进程,则该进程处于就绪状态。
运行:进程处于可运行的状态,且CPU时间片轮转到该进程,该进程正在执行代码,则该进程处于运行状态。
阻塞:进程不具备运行条件,正在等待某个事件的完成

时间片概念:
现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统。所谓的多任务,就是操作系统可以同时运行多个任务。
操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。
这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发。


多线程:
在CPU比较繁忙,资源不足的时候(开启了很多进程),操作系统只为一个含有多线程的进程分配仅有的CPU资源,这些线程就会为自己尽量多抢时间片,这就是通过多线程实现并发,线程之间会竞争CPU资源争取执行机会。
在CPU资源比较充足的时候,一个进程内的多线程,可以被分配到不同的CPU资源,这就是通过多线程实现并行。
至于多线程实现的是并发还是并行?上面所说,所写多线程可能被分配到一个CPU内核中执行,也可能被分配到不同CPU执行,分配过程是操作系统所为,不可人为控制。所有,如果有人问我我所写的多线程是并发还是并行的?我会说,都有可能。
不管并发还是并行,都提高了程序对CPU资源的利用率,最大限度地利用CPU资源。

多核、多CPU与多线程、多进程的对应关系
多cpu的运行,对应进程的运行状态;多核cpu的运行,对应线程的运行状态。

操作系统会拆分CPU为一段段时间的运行片,轮流分配给不同的程序。对于多cpu,多个进程可以并行在多个cpu中计算,当然也会存在进程切换;对于单cpu,多个进程在这个单cpu中是并发运行,根据时间片读取上下文+执行程序+保存上下文。同一个进程同一时间段只能在一个cpu中运行,如果进程数小于cpu数,那么未使用的cpu将会空闲。

进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

对于多核cpu,进程中的多线程并行执行,执行过程中存在线程切换,线程切换开销较小。对于单核cpu,多线程在单cpu中并发执行,根据时间片切换线程。同一个线程同一时间段只能在一个cpu内核中运行,如果线程数小于cpu内核数,那么将有多余的内核空闲。

总结:
单CPU中进程只能是并发,多CPU计算机中进程可以并行。

单CPU单核中线程只能并发,单CPU多核中线程可以并行。

无论是并发还是并行,使用者来看,看到的是多进程,多线程。

进程间的调度算法

1.先来先服务:按进栈顺序执行

        缺点:有些短作业会被搁置太久

        短作业优先算法

2.要求时间短的优先执行

         缺点:对长作业不友好。

3.高响应比优先:总响应时间/要求时间的比例

        缺点:多了计算,增加系统开销

4.时间片轮询:雨露均沾,在各个进程间轮流切换。

        缺点:不分轻重缓急,全部切换增加开销。

5.优先级调度:按照进程优先级进行处理,高的先执行

        缺点:优先级高的多了,低的一直不被执行。

二、死锁

死锁概念及产生原理
    概念: 多个并发进程因争夺系统资源而产生相互等待的现象。
    本质原因:
        1)系统资源有限。
        2)进程推进顺序不合理。

死锁产生的4个必要条件
    1、互斥: 某种资源每次只允许一个进程访问。
    2、请求与保持: 一个进程因请求资源而阻塞时,对已获得的资源保持不变。
    3、不可剥夺:进程已获得的资源,在未使用完之前,不能强行剥夺。
    4、循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。

死锁影响:发生死锁的进程无法进行下去,它们所持有的资源也无法释放。这样会导致CPU的吞吐量下降。所以死锁情况是会浪费系统资源和影响计算机的使用性能的。

1、死锁预防 ----- 确保系统永远不会进入死锁状态
     产生死锁需要四个条件,那么,只要这四个条件中至少有一个条件得不到满足,就不可能发生死锁了。由于互斥条件是非共享资源所必须的,不仅不能改变,还应加以保证,所以,主要是破坏产生死锁的其他三个条件。
a、破坏“请求与保持”条件
 方法1:所有的进程在开始运行之前,必须一次性地申请其在整个运行过程中所需要的全部资源。
         优点:简单易实施且安全。
         缺点:因为某项资源不满足,进程无法启动,而其他已经满足了的资源也不会得到利用,严重降低了资源的利用率,造成资源浪费。
                  使进程经常发生饥饿现象。
 方法2:该方法是对第一种方法的改进,允许进程只获得运行初期需要的资源,便开始运行,在运行过程中逐步释放掉分配到的已经使用完毕的资源,然后再去请求新的资源。这样的话,资源的利用率会得到提高, 也会减少进程的饥饿问题。
b、破坏“不可剥夺”条件
 方法: 当一个已经持有了一些资源的进程在提出新的资源请求没有得到满足时,它必须释放已经保持的所有资源,待以后需要使用的时候再重新申请。这就意味着进程已占有的资源会被短暂地释放或者说是被抢占了。
        缺点:该种方法实现起来比较复杂,且代价也比较大。释放已经保持的资源很有可能会导致进程之前的工作实效等,反复的申请和释放资源会导致进程的执行被无限的推迟,这不仅会延长进程的周转周期,还会影响系统的吞吐量。
c、破坏“循环等待”条件
方法:可以通过定义资源类型的线性顺序来预防,可将每个资源编号,当一个进程占有编号为i的资源时,那么它下一次申请资源只能申请编号大于i的资源。

      缺点:这样虽然避免了循环等待,但是这种方法是比较低效的,资源的执行速度回变慢,并且可能在没有必要的情况下拒绝资源的访问,比如说,进程c想要申请资源1,如果资源1并没有被其他进程占有,此时将它分配个进程c是没有问题的,但是为了避免产生循环等待,该申请会被拒绝,这样就降低了资源的利用率

2、避免死锁 ----- 在使用前进行判断,只允许不会产生死锁的进程申请资源
的死锁避免是利用额外的检验信息,在分配资源时判断是否会出现死锁,只在不会出现死锁的情况下才分配资源。
两种避免办法:
    1、 如果一个进程的请求会导致死锁,则不启动该进程
    2、 如果一个进程的增加资源请求会导致死锁 ,则拒绝该申请。
避免死锁的具体实现通常利用银行家算法

死锁的解除:
如果利用死锁检测算法检测出系统已经出现了死锁 ,那么,此时就需要对系统采取相应的措施。常用的解除死锁的方法:
1、抢占资源:从一个或多个进程中抢占足够数量的资源分配给死锁进程,以解除死锁状态。
2、终止(或撤销)进程:终止或撤销系统中的一个或多个死锁进程,直至打破死锁状态。
    a、终止所有的死锁进程。这种方式简单粗暴,但是代价很大,很有可能会导致一些已经运行了很久的进程前功尽弃。
     b、逐个终止进程,直至死锁状态解除。该方法的代价也很大,因为每终止一个进程就需要使用死锁检测来检测系统当前是否处于死锁状态。另外,每次终止进程的时候终止那个进程呢?每次都应该采用最优策略来选择一个“代价最小”的进程来解除死锁状态。一般根据如下几个方面来决定终止哪个进程:
    进程的优先级
    进程已运行时间以及运行完成还需要的时间
    进程已占用系统资源
    进程运行完成还需要的资源
    终止进程数目
    进程是交互还是批处理   

三、进程间常见的通信方式

进程之间的通信方式有:
1、管道
2、消息队列
3、共享内存
4、信号量
5、Socket
我们来看一条 Linux 的语句

netstat -tulnp | grep 8080
学过 Linux 命名的估计都懂这条语句的含义,其中”|“是管道的意思,它的作用就是把前一条命令的输出作为后一条命令的输入。在这里就是把 netstat -tulnp 的输出结果作为 grep 8080 这条命令的输入。如果两个进程要进行通信的话,就可以用这种管道来进行通信了,并且我们可以知道这条竖线是没有名字的,所以我们把这种通信方式称之为匿名管道。
并且这种通信方式是单向的,只能把第一个命令的输出作为第二个命令的输入,如果进程之间想要互相通信的话,那么需要创建两个管道。
居然有匿名管道,那也意味着有命名管道,下面我们来创建一个命名管道。
mkfifo  test
这条命令创建了一个名字为 test 的命名管道。
接下来我们用一个进程向这个管道里面写数据,然后有另外一个进程把里面的数据读出来。
echo "this is a pipe" > test   // 写数据
这个时候管道的内容没有被读出的话,那么这个命令就会一直停在这里,只有当另外一个进程把 test 里面的内容读出来的时候这条命令才会结束。接下来我们用另外一个进程来读取
cat < test  // 读数据
我们可以看到,test 里面的数据被读取出来了。上一条命令也执行结束了。
从上面的例子可以看出,管道的通知机制类似于缓存,就像一个进程把数据放在某个缓存区域,然后等着另外一个进程去拿,并且是管道是单向传输的。
这种通信方式有什么缺点呢?显然,这种通信方式效率低下,你看,a 进程给 b 进程传输数据,只能等待 b 进程取了数据之后 a 进程才能返回。
所以管道不适合频繁通信的进程。当然,他也有它的优点,例如比较简单,能够保证我们的数据已经真的被其他进程拿走了。我们平时用 Linux 的时候,也算是经常用。
2、消息队列
那我们能不能把进程的数据放在某个内存之后就马上让进程返回呢?无需等待其他进程来取就返回呢?

答是可以的,我们可以用消息队列的通信模式来解决这个问题,例如 a 进程要给 b 进程发送消息,只需要把消息放在对应的消息队列里就行了,b 进程需要的时候再去对应的
消息队列里取出来。同理,b 进程要个 a 进程发送消息也是一样。这种通信方式也类似于缓存吧。

这种通信方式有缺点吗?答是有的,如果 a 进程发送的数据占的内存比较大,并且两个进程之间的通信特别频繁的话,消息队列模型就不大适合了。因为 a 发送的数据很大的话,意味**发送消息(拷贝)**这个过程需要花很多时间来读内存。

哪有没有什么解决方案呢?答是有的,请继续往下看。

3、共享内存
共享内存这个通信方式就可以很好着解决拷贝所消耗的时间了。

这个可能有人会问了,每个进程不是有自己的独立内存吗?两个进程怎么就可以共享一块内存了?

我们都知道,系统加载一个进程的时候,分配给进程的内存并不是实际物理内存,而是虚拟内存空间。那么我们可以让两个进程各自拿出一块虚拟地址空间来,然后映射到相同的物理内存中,这样,两个进程虽然有着独立的虚拟内存空间,但有一部分却是映射到相同的物理内存,这就完成了内存共享机制了。

4、信号量
共享内存最大的问题是什么?没错,就是多进程竞争内存的问题,就像类似于我们平时说的线程安全问题。如何解决这个问题?这个时候我们的信号量就上场了。

信号量的本质就是一个计数器,用来实现进程之间的互斥与同步。例如信号量的初始值是 1,然后 a 进程来访问内存1的时候,我们就把信号量的值设为 0,然后进程b 也要来访问内存1的时候,看到信号量的值为 0 就知道已经有进程在访问内存1了,这个时候进程 b 就会访问不了内存1。所以说,信号量也是进程之间的一种通信方式。

5、Socket
上面我们说的共享内存、管道、信号量、消息队列,他们都是多个进程在一台主机之间的通信,那两个相隔几千里的进程能够进行通信吗?

答是必须的,这个时候 Socket 这家伙就派上用场了,例如我们平时通过浏览器发起一个 http 请求,然后服务器给你返回对应的数据,这种就是采用 Socket 的通信方式了。

四、top命令后load average 什么意思?

系统负载,即任务队列的平均长度,三个数值分别是1分钟,5分钟,15分钟到现在的平均值,如果这个数除以逻辑CPU的数量大于5,说明已经超负荷运载了。
正在运行的进程,睡眠的进程,停止的进程,僵尸进程
孤儿进程:
一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。
孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工作。
由于孤儿进程会被 init 进程收养,所以孤儿进程不会对系统造成危害。
僵尸进程:
一个子进程的进程描述符在子进程退出时不会释放,只有当父进程通过 wait() 或 waitpid() 获取了子进程信息后才会释放。如果子进程退出,而父进程并没有调用 wait() 或 waitpid(),那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵尸进程。
僵尸进程通过 ps 命令显示出来的状态为 Z(zombie)。
系统所能使用的进程号是有限的,如果产生大量僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。
要消灭系统中大量的僵尸进程,只需要将其父进程杀死,此时僵尸进程就会变成孤儿进程,从而被 init 所收养,这样 init 就会释放所有的僵尸进程所占有的资源,从而结束僵尸进程
或者子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程

五、Linux启动顺序?

BIOS 上电自检(POST)
引导装载程序 (GRUB2)
内核初始化
启动 systemd,其是所有进程之父。

六、Linux 如何查看主机的cpu个数和总内存?

第一种方法:top命令法
在top命令的显示界面,按数字键1cat /proc/cpuinfo 
processor     逻辑处理器的id。一个id代表一个核
physical id    物理封装的处理器的id。一个id代表一个cpu

七、软硬链接的区别?

硬链接文件和源文件的inode节点相同,软连接的是不同的
硬链接不能对目录,软连接可以
硬链接不能对不存在的文件创建,软连接可以
硬链接block存放的是源文件的数据信息,软连接block存放的是源文件的路径信息。
删除源文件,硬链接还可以继续访问源数据,软连接就会失效,访问不了数据,因为linux删除文件是删除文件inode节点的链接数,直到0才会被回收数据。

八、linux查看内核版本,系统版本,查看流量

查看内核版本:cat /proc/version

                         uname -a

查看系统版本lsb_release -a,即可列出所有版本信息,

                         cat /etc/issue此命令也适用于所有的Linux发行版。

查看流量:iftop -i (指定网卡)  eth0  -F(指定网段)-B以Byte显示

九、linux启动过程(centos6)

1. BIOS启动引导:主要是加电自检,检查硬件,读取硬盘的MBR(主引导记录)的BootLoader(主引导程序)。

2.    GRUB(内核引导程序)启动引导:GRUB程序加载执行并引导kernel(内核)程序,grub引导阶段的文件都在/boot/grub/目录下

3.     加载内核:通过内存中的虚拟根文件系统,加载驱动,然后切换到真正的根文件系统,并执行/sbin/init程序。

4.    init初始化阶段(又叫系统初始化阶段):/sbin/init程序会读取/etc/inittab文件确认运行级别,然后执行/etc/rc.d/rc脚本,根据确认的运行级别启动对应/etc/rc.d/rc#.d/目录下的服务(#为0~6),与此同时执行系统初始化脚本/etc/rc.sysinit(软链接,指向/etc/rc.d/rc.sysinit),还会加载/etc/rc.local(软链接,指向/etc/rc.d/rc.local文件)用户自定义服务(脚本)。

5. 启动终端  :用户登陆

十、Linux的运行等级(centos6)

0:关机

1:单用户模式

2:无网络支持的多用户模式

3:有网络支持的多用户模式

4:保留,未使用

5:有网络支持图形界面的多用户模式

6:重新引导系统,即重启

十一、常见的io模型,阻塞,非阻塞,同步,异步,多路复用

阻塞:调用方法要等有数据了才返回就是阻塞。

非阻塞:是用户进程在内核准备数据的阶段需要不断的主动询问数据好了没有。(文件描述符缓冲区是否就绪),当数据报准备好的时候,就进行拷贝数据报的操作。当数据报没有准备好的时候,也不阻塞程序,内核直接返回未准备就绪的信号,等待用户程序的下一次轮询。

同步:  同步需要主动读写数据,在读写数据的过程中还是会阻塞,因为没数据的话,它会等待。

异步:  并不主动读写数据,调用完相关函数就可以直接返回了,不会阻塞,由操作系统内核完成数据的读写,完成后内核会给用户进程发送一个signal,告诉它相应操作完成了。

IO多路复用模型:对多个文件描述符进行循环监听,当某个文件描述符就绪的时候,就对这个文件描述符进行处理。优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。

十二、分页和分段的区别?

1、页是信息的物理单位,分页是为了实现离散分配方式,以消减内存的外零头,提高内存的利用率。分页仅仅是由于系统管理的需要而不是用户的需要; 段是信息的逻辑单位,分段的目的是为了能更好地满足用户的需要

2、 页的大小固定,由系统把逻辑地址划分为页号和页内地址两部分;段的长度却不固定,决定于用户所编写的程序

3 、分页的作业地址空间是一维的,即单一的线性地址空间。 分段的作业地址空间是二维的 在标识一个地址时,即需给出段名,又需给出段内地址

其他

一、算某时间到某时间过了多少天

#!/bin/bash
a="2021-1-1"
b="2021-4-24"
now_year_first_day=$(date -d $a +%s)
today=`date -d "$b" +%s`
days=$((($today-$now_year_first_day)/86400))
echo "从$a到$b已经过了$days天了"
echo "今天是今年的第$(($days+1))天"

二、产生随机32位密码

cat /dev/urandom|tr -dc 'a-zA-Z0-9'|fold -w 32|head -1   -c对后面取差集 -d删除后面的   -cd  'a-zA-Z0-9' 相当删除了除了大小写字母以及数字的其他字符  fold  -w 是把文件弄成每行多少列
QNvh84ueITwFi19h7YHXgaHKywSFMBMS

cat /dev/urandom|head -1|md5sum |head -c 30
57075ff80a0b05277d5f95f0db771fopenssl  rand -base64 32|head -c 32

三、tomcat,nginx,apache区别

Tomcat :它既可以处理动态内容,也可以处理静态内容。不过,tomcat的最大优势在于处理动态请求,处理静态内容的能力不如apache和nginx,并且经过测试发现,tomcat在高并发的场景下,其接受的最大并发连接数是有限制的,连接数过多会导致tomcat处于"僵死"状态,因此,在这种情况下,我们可以利用nginx的高并发,低消耗的特点与tomcat一起使用。

apache是同步阻塞模型,一个连接对应一个进程。处理静态文件是它的优势,速度快。

nginx是异步非阻塞的,多个连接(万级别)可以对应一个进程,适合负载均衡、反向代理、处理静态文件优势


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值