面经

(美团)

一、网络每层的协议

601454bfe5f0b4a2ab49842efccd3c2770b.jpg

物理层:比特

数据链路层:帧 (网桥,交换机)

网络层:数据报 (路由器)

运输层:报文段/用户数据报

应用层:报文

 

二、RPC和Restful的区别,serviceMatch是什么

RPC:调用本地服务(方法)一样调用服务器的服务(方法),RPC框架需要考虑解决通讯(长短连接)、寻址(IP、端口、方法名)、序列化与反序列化(二进制数据的序列化和反序列化);

Restful:基于HTTP协议,通过HTTP协议定义的通用动词方法(GET、PUT、DELETE、POST) ,以URI对网络资源进行唯一标识;

区别:

1、从使用来看,Http接口只关注服务提供方(服务端),对于客户端怎么调用,调用方式怎样并不关心;而RPC服务则需要客户端接口与服务端保持一致,服务端提供一个方法,客户端通过接口直接发起调用;

2、 从性能角度看,使用Http时,Http本身提供了丰富的状态功能与扩展功能,但也正由于Http提供的功能过多,导致在网络传输时,需要携带的信息更多,从性能角度上讲,较为低效。而RPC服务网络传输上仅传输与业务内容相关的数据,传输数据更小,性能更高;

三、死锁产生的原因

什么是死锁

死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进

死锁产生的条件

  • 互斥:一个资源每次只能被一个进程使用。
  • 请求与保持:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不可剥夺:进程已获得的资源,在末使用完之前,不能强行剥夺。
  • 循环等待:若干进程之间形成一种头尾相接的循环等待资源关系。

打破死锁的方法

  • 打破互斥条件:将独占式资源改为虚拟资源(不太可行)
  • 打破请求与保持条件:采用资源预分配策略,即进程运行前申请全部资源,满足则运行
  • 打破不可剥夺条件:当一个进程占有一独占性资源又申请另一独占性资源而无法满足时,则放出原占有的资源
  • 打破循环等待条件:实现资源有序分配策略

四、CPU占用升高的原因

首先我们通过top命令查看当前CPU消耗过高的进程是哪个,从而得到进程id;然后通过top -Hp <pid>来查看该进程中有哪些线程CPU过高,一般超过80%就是比较高的,80%左右是合理情况。这样我们就能得到CPU消耗比较高的线程id。接着通过该线程id的十六进制表示(printf "%x\n" )在jstack(jstack 进程ID|grep tid(16进制线程小写英文)-A60)日志中查看当前线程具体的堆栈信息。

在这里我们就可以区分导致CPU过高的原因具体是Full GC次数过多还是代码中有比较耗时的计算了。如果是Full GC次数过多,那么通过jstack得到的线程信息会是类似于VM Thread之类的线程,而如果是代码中有比较耗时的计算,那么我们得到的就是一个线程的具体堆栈信息。如下是一个代码中有比较耗时的计算,导致CPU过高的线程信息:

001a746f3f73b86307286fc1268f55d15be.jpg

参考:https://blog.csdn.net/u013256816/article/details/94518811

(小米)

五、索引失效的情况

  • 不在索引列上做任何操作(计算,函数,(自动或者手动)类型装换),会导致索引失效而导致全表扫描;
  • 使用不等于(!= 或者<>)的时候,无法使用索引,会导致索引失效
  • 使用is not null 或者 is null会导致无法使用索引
  • like查询是以%开头,索引会失效变成全表扫描,覆盖索引。
  • 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)。要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
  • 如果mysql使用全表扫描要比使用索引快,则不会使用到索引

查看一条SQL是否使用了索引,可以在前面加上EXPLAIN关键字

6ec63bc8e9eb938b1500c90ebb793276581.jpg

e66128f79552870471ab5cfe021ff249653.jpg

上图为使用了索引,下图没有。只要type类型不是ALL,就是使用了索引。其他类型可参照 https://www.cnblogs.com/david97/p/8072164.html

复合索引的生效规则

最佳左前缀原则——从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引起作用,断点后面的索引不起作用

(0)    select * from mytable where a=3 and b=5 and c=4;
abc三个索引都在where条件里面用到了,而且都发挥了作用
(1)    select * from mytable where  c=4 and b=6 and a=3;
这条语句列出来只想说明 mysql没有那么笨,where里面的条件顺序在查询之前会被mysql自动优化,效果跟上一句一样
(2)    select * from mytable where a=3 and c=7;
a用到索引,b没有用,所以c是没有用到索引效果的
(3)    select * from mytable where a=3 and b>7 and c=3;
a用到了,b也用到了,c没有用到,这个地方b是范围值,也算断点,只不过自身用到了索引
(4)    select * from mytable where b=3 and c=4;
因为a索引没有使用,所以这里 bc都没有用上索引效果
(5)    select * from mytable where a>4 and b=7 and c=9;
a用到了  b没有使用,c没有使用
(6)    select * from mytable where a=3 order by b;
a用到了索引,b在结果排序中也用到了索引的效果,前面说了,a下面任意一段的b是排好序的
(7)    select * from mytable where a=3 order by c;
a用到了索引,但是这个地方c没有发挥排序效果,因为中间断点了,使用 explain 可以看到 filesort
(8)    select * from mytable where b=3 order by a;
b没有用到索引,排序中a也没有发挥索引效果

MySQL主要提供2种方式的索引:B-Tree索引,Hash索引

B树索引具有范围查找和前缀查找的能力,对于有N节点的B树,检索一条记录的复杂度为O(LogN)。相当于二分查找。

哈希索引只能做等于查找,但是无论多大的Hash表,查找复杂度都是O(1)。

显然,如果值的差异性大,并且以等值查找(=、 <、>、in)为主,Hash索引是更高效的选择,它有O(1)的查找复杂度。

如果值的差异性相对较差,并且以范围查找为主,B树是更好的选择,它支持范围查找。

六、Mybatis中 ${} 和 #{} 的区别

使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用 ? 作占位符,并且在使用#{}时形成的sql语句,已经带有引号,也就是说默认当成字符串处理;

使用${}时的sql不会当做字符串处理,是什么就是什么。

所以,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如,

select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序。

 

 

转载于:https://my.oschina.net/u/2286010/blog/3099161

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值