程序员小扎比特跳动公司的一面

故事发生在很平淡的一个早上,一本正经的小扎正端坐在自己的电脑桌前,眼神迷离,因为今天早上要和比特公司进行视频一面,昨晚上紧张的没睡好,为了今天的面试还和领导请了个假,谎称身体不舒服,“求老天保佑”,小扎内心祈祷,毕竟自己也为这次面试准备了好久。

小扎盯着时间,呼吸越来紧促,因为还剩几秒就到约定的面试时间了,6,5,4,3,2,1,叮铃铃,对方拨起了视频邀请,小扎接受了邀请,“你好,我是今天的面试官”,“你好,你好”小扎连忙应答到。

面试官:你先做个自我介绍吧。小扎:你好,我叫小扎,19年毕业于...

数据库篇

面试官:我看你的简历说到你熟悉MySQL,那我先来问问MySQL相关的知识吧。小扎:好的。面试官:现在有张成绩表(grade),它的结构如下,请你统计出平均成绩大于80的同学姓名和平均成绩。小扎:(我去,一上来直接写sql...)好的,小扎思考一下(看来这题面试官想考我having和groupby的用法,不过这简单,难不倒我),过了一会小扎写出以下sql。

selectname,avg(score)asavgScorefromgradehavingavgScore80groupbyname

面试官看了看sql,于是说到:你们平时用的什么引擎?小扎:InnoDB存储引擎(我猜他要问我几种存储引擎的区别了)面试官:那InndoDB和Myisam的区别是什么?小扎:(果然不出所料,还好平时八股文看的不少)

InndoDB是支持事务的,Myisam是不支持的InnoDB支持外键,而Myisam不支持InnoDB的数据是存储在B+树的叶子节点的,而Myisam的叶子节点只是存储指向数据的指针

面试官:等等,我打断一下,索引这里能在讲清楚点吗,比如聚集索引和非聚集索引分别是怎样存的。小扎:这里是这样的,对于InnoDB来说,它的聚集索引叶子节点存的是整行数据,而非聚集索引的叶子节点存的是主键id,因此在非聚集索引上查不到的字段时需要通过id回表,而Myisam是没有聚集索引之说的,不管是主键id索引还是普通索引,叶子节点存的不是整行数据或者主键id,而是指向行数据的指针,所以在Myisam中通过普通索引查数据没有回表一说。面试官:那你继续说。小扎:好的,InnoDB不保存表的具体行数,比如执行selectcount(*)fromtable时需要全表扫描。而Myisam用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快。面试官:对于Myisam,如果我执行了一下sql,它要全表扫描?

selectcount(*)fromxxwherename=xx

小扎:首先带where条件的,肯定是不会用到那个行变量的,这时得分情况,如果name没有索引,那么是要全表的扫的,如果name有索引,应该是会走name索引的。面试官:那对于InnoDB一定每次都是全表扫吗?小扎:不一定,某些情况下,MySQL会选择走覆盖索引面试官:那为什么会选择走覆盖索引呢?小扎:覆盖索引话,只需要存索引字段本身和主键id值,因此对于同一页来说,可以存放更多的行,那么扫描的页就会少,速度就会更快。面试官:那两种存储引擎还有其他区别吗?小扎:InnoDB支持表、行级锁,而MyISAM支持表级锁。InnoDB表必须有主键,如果没有设置主键会尝试找到表中的唯一索引来当主键,如果唯一索引也没有,那么会默认一个row_id来当主键,而Myisam可以没有。面试官:这里能说下myisam为什么可以没有吗?小扎:前面说了,对于myisam,它的主键索引和普通索引区别不大,叶子节点都是指向整行数据的指针。这个从存储文件上就可以看出:

Innodb:两个文件,frm是表定义文件,ibd是数据文件Myisam:三个文件,frm是表定义文件,myd是数据文件,myi是索引文件。

大概它们的区别就是这么多。

面试官:就这么多吗?不是说InnoDB不支持全文索引,而Myisam支持吗,这个难道不是区别吗?小扎:(尼玛,不知道这面试官是真不知道还是假不知道),这个是这样的,5.6版本之后InnoDB存储引擎开始支持全文索引,5.7版本之后通过使用ngram插件开始支持中文,所以对于高版本InnoDB引擎的MySQL,是支持全文索引的。(这都几点了,还在问区别,myisam都快淘汰了,我xxx)

面试官:(还行,接着炸他看看),知道查询缓存吗?小扎:知道,某些执行过的语句及其结果可能会以key-value对的形式被直接缓存在内存中。key是查询的语句,value是查询的结果,这样当同样的SQL来查询的时候,如果缓存中有,可以从缓存中获取。面试官:那你知道其实MySQL8.0开始就废弃这个模块了吗?查询缓存不是挺好的吗,为啥要废弃?小扎:这个了解点,因为对于某些更新频繁的数据表来说,查询缓存太容易失效了,比如刚刚缓存一个数据,可能因为下一个查询,导致这个缓存被踢出去了,那么就白白浪费了一次缓存操作。面试官:那你说说什么时候需要垂直分表,什么时候需要水平分表?小扎:如果一张表的字段很多,而且比如有一些text类型字段,建议将其拆出去,让一些不经常被查询的字段不占用解析开销、带宽开销,这是垂直分表,而对于水平分表那就是一张表的数据越来越多的时候,建议多分几张表,这样不会因为一张表越来越大导致查询变慢。

网络篇

面试:(还行,数据库就先不问了吧),接下来我考考你网络相关的知识吧。小扎:(来吧!谁怕谁)好的,好的。

面试官:先说说


转载请注明:http://www.aierlanlan.com/grrz/4905.html