面试中一些比较尴尬的问题

今天是2020年6月17日,北京的疫情爆发了,非常时期但是却挡不住面试的步伐,就简单记录一下今天我遇到的一个面试经历吗吧
面试官是CTO,属于第二轮,我也没有去准备什么,直接就去了毫无防备的,是的很惨
问题如下,只说我记住的一些问题

1.Hadoop下如何杀死一个job

我顿时蒙了一下平时也没有怎么杀死过进程啊,当时只想着kill -9 咋地咋地的说了一下,面试官笑了

正确的应该是

查看当前正在执行的进程:

sh hadoop job -list

执行杀死进程的命令:

hadoop job -kill job_201212111628_11166

如果正确执行,则系统提示:

Killed job job_201212111628_11166

2.关于程序内存泄露

这个从我的出发点来说肯定是,看看你有木有报出错误啊,正常的程序员,使用完内存肯定是要对内存进行回收的啊,但是我面的也不是程序员啊

正确回答

使用mat工具来查看

1.初步判定是否存在内存泄漏问题,压测前后内存空间是否释放。使用命令:free –h

2.若存在内存泄漏,使用命令:jmap -dump:live,format=b,file=heap.hrof

pid是JVM进程的id,

heap.hrof

是生成的文件名称,在执行命令的目录下面。

备注:在JVM的配置参数中可以添加 -XX:+HeapDumpOnOutOfMemoryError 参数,当应用抛OutOfMemoryError 时自动生成dump文件。

然后查看详情,看看那个class 类调用了那个对象多少次,以及使用内存的情况,然后对程序进行优化

Mysql的慢查询一下问题

正确方式

说明开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。

首先打开慢查询
show variables like 'slow_query%';

show variables like 'long_query_time';

方法一:全局变量设置
将 slow_query_log 全局变量设置为“ON”状态

mysql> set global slow_query_log='ON';
设置慢查询日志存放的位置

mysql> set global slow_query_log_file='/usr/local/mysql/data/slow.log';
查询超过1秒就记录

mysql> set global long_query_time=1;

方法二:配置文件设置
修改配置文件my.cnf,在[mysqld]下的下方加入

[mysqld]
slow_query_log = ON
slow_query_log_file = /usr/local/mysql/data/slow.log
long_query_time = 1

3.重启MySQL服务

service mysqld restart

1.执行一条慢查询SQL语句

mysql> select sleep(2);

2.查看是否生成慢查询日志

ls /usr/local/mysql/data/slow.log

如果日志存在,MySQL开启慢查询设置成功!

另外
分析慢查询日志         
       直接分析mysql慢查询日志 ,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句

例如:执行EXPLAIN SELECT * FROM res_user ORDER BYmodifiedtime LIMIT 0,1000

得到如下结果: 显示结果分析:

table |  type | possible_keys | key |key_len  | ref | rows | Extra  EXPLAIN列的解释:

table                 显示这一行的数据是关于哪张表的

type                  这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL

rows                显示需要扫描行数

key                   使用的索引

常见的慢查询优化
 
 (1)索引没起作用的情况
    1. 使用LIKE关键字的查询语句

在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置索引才会起作用。

2. 使用多列索引的查询语句

MySQL可以为多个字段创建索引。一个索引最多可以包括16个字段。对于多列索引,只有查询条件使用了这些字段中的第一个字段时,索引才会被使用。

(2)优化数据库结构
        合理的数据库结构不仅可以使数据库占用更小的磁盘空间,而且能够使查询速度更快。数据库结构的设计,需要考虑数据冗余、查询和更新的速度、字段的数据类型是否合理等多方面的内容。

  1. 将字段很多的表分解成多个表

对于字段比较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。

  1. 增加中间表

对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。
(3)分解关联查询
将一个大的查询分解为多个小查询是很有必要的。

很多高性能的应用都会对关联查询进行分解,就是可以对每一个表进行一次单表查询,然后将查询结果在应用程序中进行关联,很多场景下这样会更高效

(4)优化LIMIT分页
      在系统中需要分页的操作通常会使用limit加上偏移量的方法实现,同时加上合适的order by 子句。如果有对应的索引,通常效率会不错,否则MySQL需要做大量的文件排序操作。

一个非常令人头疼问题就是当偏移量非常大的时候,例如可能是limit 10000,20这样的查询,这是mysql需要查询10020条然后只返回最后20条,前面的10000条记录都将被舍弃,这样的代价很高。

优化此类查询的一个最简单的方法是尽可能的使用索引覆盖扫描,而不是查询所有的列。然后根据需要做一次关联操作再返回所需的列。对于偏移量很大的时候这样做的效率会得到很大提升。

对于下面的查询:

select id,title from collect limit 90000,10;

该语句存在的最大问题在于limit M,N中偏移量M太大(我们暂不考虑筛选字段上要不要添加索引的影响),导致每次查询都要先从整个表中找到满足条件 的前M条记录,之后舍弃这M条记录并从第M+1条记录开始再依次找到N条满足条件的记录。如果表非常大,且筛选字段没有合适的索引,且M特别大那么这样的代价是非常高的。 试想,如我们下一次的查询能从前一次查询结束后标记的位置开始查找,找到满足条件的100条记录,并记下下一次查询应该开始的位置,以便于下一次查询能直接从该位置 开始,这样就不必每次查询都先从整个表中先找到满足条件的前M条记录,舍弃,在从M+1开始再找到100条满足条件的记录了。

(5)分析具体的SQL语句
 1、两个表选哪个为驱动表,表面是可以以数据量的大小作为依据,但是实际经验最好交给mysql查询优化器自己去判断。
  例如:  select * from a where id in (select id from b );  
        对于这条sql语句它的执行计划其实并不是先查询出b表的所有id,然后再与a表的id进行比较。
mysql会把in子查询转换成exists相关子查询,所以它实际等同于这条sql语句:select * from a where exists(select * from b where b.id=a.id );

而exists相关子查询的执行原理是: 循环取出a表的每一条记录与b表进行比较,比较的条件是a.id=b.id . 看a表的每条记录的id是否在b表存在,如果存在就行返回a表的这条记录。

exists查询有什么弊端?
      由exists执行原理可知,a表(外表)使用不了索引,必须全表扫描,因为是拿a表的数据到b表查。而且必须得使用a表的数据到b表中查(外表到里表中),顺序是固定死的。

如何优化?
      建索引。但是由上面分析可知,要建索引只能在b表的id字段建,不能在a表的id上,mysql利用不上。

这样优化够了吗?还差一些。
      由于exists查询它的执行计划只能拿着a表的数据到b表查(外表到里表中),虽然可以在b表的id字段建索引来提高查询效率。
但是并不能反过来拿着b表的数据到a表查,exists子查询的查询顺序是固定死的。

为什么要反过来?
       因为首先可以肯定的是反过来的结果也是一样的。这样就又引出了一个更细致的疑问:在双方两个表的id字段上都建有索引时,到底是a表查b表的效率高,还是b表查a表的效率高?

该如何进一步优化?
       把查询修改成inner join连接查询:select * from a inner join b on a.id=b.id; (但是仅此还不够,接着往下看)

为什么不用left join 和 right join?
       这时候表之间的连接的顺序就被固定住了,比如左连接就是必须先查左表全表扫描,然后一条一条的到另外表去查询,右连接同理。仍然不是最好的选择。

为什么使用inner join就可以?
       inner join中的两张表,如: a inner join b,但实际执行的顺序是跟写法的顺序没有半毛钱关系的,最终执行也可能会是b连接a,顺序不是固定死的。如果on条件字段有索引的情况下,同样可以使用上索引。

那我们又怎么能知道a和b什么样的执行顺序效率更高?
       你不知道,我也不知道。谁知道?mysql自己知道。让mysql自己去判断(查询优化器)。具体表的连接顺序和使用索引情况,mysql查询优化器会对每种情况做出成本评估,最终选择最优的那个做为执行计划。

在inner join的连接中,mysql会自己评估使用a表查b表的效率高还是b表查a表高,如果两个表都建有索引的情况下,mysql同样会评估使用a表条件字段上的索引效率高还是b表的。

利用explain字段查看执行时运用到的key(索引)
       而我们要做的就是:把两个表的连接条件的两个字段都各自建立上索引,然后explain 一下,查看执行计划,看mysql到底利用了哪个索引,最后再把没有使用索引的表的字段索引给去掉就行了。
关于这部分希望你能滔滔不绝的说,但是要有理有据.
还有一点就是去mysql的交集 记住 cross join inner join 这些不经常使用的
其中关于mysql面试官还问题15s内mysql可以查询的数据量有多大??
我觉得百万级以内单表还是可以的呀

Redis单机访问量能优化到多少怎么做到的说说它的QPS
我说我之前做的单机集群可以达到百万级别的读写,他貌似不太相信,然后问怎么实现的

其实最主要的还是

高效的数据结构

多路复用 IO 模型

事件机制
唉不说那么多了来点实际的

直接对它来一个压力测试呗

1、用100个线程发送10万个请求:

redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

默认是测试发送3个字节,最后可见qps结果达到了8万多,还是相当高的

2、自定义字节数压测(定义字节数为100):

redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100

3、对某些单独的命令进行压测,如下对set和lpush命令压测,不写就测试全部命令:

redis-benchmark -t set,lpush -n 100000 –q

4、对某一具体操作进行压测:

redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"

其实Redis的QPS基本在10w以内
测算redis处理实际生产请求的QPS/TPS在实际生产中,我们需要关心这个指标,在我们的应用场景中,
redis能够处理的最大的(QPS/TPS)是多少?
测量redis QPS的方式有两种:

估计生产的报文大小,使用benchmark工具指定-d数据块大小来模拟;
使用redis-cli中info统计信息计算差值;
redis-cli的info命令中有一项total_commands_processed表示:从启动到现在处理的所有命令总数,可以通过统计两次info指令间的差值来计算QPS:

生产环境统计
redis-cli -h 127.0.0.1 -p 6379 info |grep -i total_commands_processed | awk -F ':' '{print "'$(date +%H:%M:%S)' " $2}'

使用watch -n1 每秒查看一次 这样状态就回每秒更新
watch -n1 redis-cli -h 127.0.0.1 -p 6379 info stats

还有一些问题就是Nginx的响应时间是多少,能支持多少同时访问,怎么做到的

还有就是抓包的问题了,怎么抓包怎么分析,使用什么工具
我一般使用tcpdump 和 fiddler 不说了
我又发现一个阿里云写的一个比较好的脚本 是用来监控CPU的 下载地址Linux
http://img01.taobaocdn.com/tfscom/TB1qE_WHFXXXXbuaXXXXXXXXXXX.rar?spm=a2c4g.11186623.2.3.yvWHgL&file=TB1qE_WHFXXXXbuaXXXXXXXXXXX.rar
使用方法
下载该文件解压后,上传到 /tmp 目录中。

运行 cd 切换到/tmp目录。

执行: nohup bash get_cpu_mem_info.sh &

该工具会在 /tmp 目录下生成一个日志文件,记录实时监控系统的 CPU、内存的使用情况,等到系统异常时可以用于分析日志。
Windows的
阿里云下载地址http://img01.taobaocdn.com/tfscom/TB1G2AAHFXXXXXBXXXXXXXXXXXX.rar?spm=a2c4g.11186623.2.4.yvWHgL&file=TB1G2AAHFXXXXXBXXXXXXXXXXXX.rar

使用方法:

下载该文件解压后,上传到c:目录中。

双击打开运行后。不要关闭,最小化即可。

该工具会在 C: 目录下生成一个日志文件,记录实时监控系统的性能状态,等到系统异常时可以用于分析日志。

最后在说一个,跟客户安装操作系统之前需要哪些优化
没想到吧会问这???
安全方面de
yum源的优化
以及系统时间
远程连接的优化等唉

面试的过程也是一个学习的过程,没次面试之后都要学会总结,如果你面过很多,有总结了很多,这难道不是一种自我成长的经历吗
我们本是站在巨人肩上的人
所以我们要珍惜每次面试
对的起自己去面试的时间,也对的起每一位面试官对你的面试
感谢每一位面试官让我不断成长

原文地址:https://www.cnblogs.com/zhuhuibiao/p/13155445.html