腾讯面试——血与泪的教训
前言
又到了一周一度的学习总结了,本周可以算得上是非常神奇的一周了。从标题也不难看出,神奇之处就在于本周是笔者第一次参加一场面试,可谓是非常的紧张。经过一场面试也让我深刻地感受到闭门造车是行不通的,在面试之前总觉得自己把什么都准备好了,结果在两个小时的面试过程中,被面试官牵着鼻子走(狗头)。所以本周的总结主要集中在对面试的复盘方面,希望在完成这次周报之后能对我以后的学习有一定的帮助吧。
面试复盘
面试流程
首先就是面试官介绍自己的部门和我的自我介绍。
从舍友的评价来看,自我介绍环节就已经十分紧张了,说话也是结结巴巴,十分的不自信。
三道算法题。
题目倒不是很难,也不需要能够完全正确,只需要自己的思路对就OK了。
拷打项目,也是本次面试中笔者表现的最呆瓜的一个环节了。
面试官问我为什么要选择MySQL来作为数据库来存储信息。我竟然脑抽到回答说我只会MySQL。
除了拷打项目,就是一些比较简单的八股了,还是有待加强。
项目拷打总结
问题一
是否支持上传图片?图片是怎样进行存储的?怎么把图片和对应的文章正确地显示出来?
显然,对于并没有完全准备好的我来说,这三个问题已经足够干掉我了。
- 已经实现了上传和显示图片的功能。
- 应该将图片存储在对应的服务器中,现阶段的存储方式为把用户上传的图片放到一个专门的文件夹中。
- 由于图片存储为在固定的文件夹中,那么只需要将文件的路径放在文章的正确位置即可,这样在进行页面展示时,可以将图片进行正确的显示。
问题二
如果用户量太大,每个人都往其中存储文章,导致表中内容过多,该怎么解决?
在实际的应用开发中,数据量过大的MySQL表会导致查询的性能下降。解决方法如下:
- 分表分库
将单张数据量过大的表拆分成多个较小的表,每个表只存储一部分数据,以此来提高查询效率。
- 垂直拆分
如果单表的列比较多,但是并不是所有列都会频繁地使用,可以考虑将一些少用的列拆分到新的表中,从而减少单个表的数据量,减少磁盘空间的使用。
- 建立合适的索引
问题三
上一个问题提到,当数据量过大时可以采用分表策略,那要怎么进行文章的定位呢?
水平切分后同一张表会出现在多个数据库或表中,每个库和表的内容不同,对于水平分表后分库后,如何知道哪条数据在哪个库里或表里,则需要路由算法进行计算,这个算法会引入一定的复杂性。
- 范围路由
选取有序的数据列,如时间戳作为路由的条件,不同分段分散到不同的数据库表中,以最常见的用户ID为例,路由算法可以按照1000000的范围大小进行分段,1 ~ 9999999放到数据库1的表中,10000000~199999999放到数据库2的表中,以此累推。
范围路由设计的复杂点主要体现在分段大小的选取上,分段太小会导致切分后子表数量过多增加维护复杂度,分段太大可能会导致单表依然存在性能问题,按一般大老们的经验,分段大小100W至2000W之间,具体需要根据业务选 取合适的分段大小。
- 范围路由的优点
- 可以随着数据的增加平滑地扩充新的表或库,原有的数据不需要动。
- 单表大小可控
- 使用分片字段进行范围查找时,连续分片可快速定位查询,有效避免分片查询的问题。
热点数据成为性能瓶颈,连续分片可能存在数据热点,例如按时单字段分片,有些分片存储最近时间内的数据,可能会被频繁读写,而有些历史数据则很少被查询。
hash算法
选取某个列或几个列的值进行hash运算,然后根据hash的结果分散到不同的数据库表中,以用ID为例,假如我们一开始就规划10个数据库表,路由算法可以简单地用id % 10的值来表示数据所属的数据库编号,ID为985的用户放到编号为5的子表中。ID为10086编号放到编号为6的表中。
Hash路由设计的复杂点主要体现 在初始表数量的选取上,表数量太多维护比较麻烦,表数量太小又可能导致单表性能存在问题。而用Hash路由后,增加字表数量是非常麻烦的,所有数据都要重新分布。
Hash路由的优缺点与范围路由相反,Hash路由的优点是表分布比较均匀,缺点是扩容时很麻烦,所有数据均需要重新分布。
- 路由配置
配置路由就是路由表,用一张独立的表来记录路由信息。同样以用户ID为例,我们新增一张ROUTER表,这个表包含table_Id两列,根据user_id就可以查询对应的修改路由表就可以了。
配置路由设计简单,使用起来非常灵活,尤其是在扩充表的时候,只需要迁移指定的数据,然后修改路由表就可以了。
其缺点就是必须多查询一次,会影响整体性能,而且路由表本身如果太大,性能会成为瓶颈点,如果我们再将路由表分库分表,则又面临一个死循环。
问题四
如果实行分表,如何确保自增的文章ID不出现重复。或者有什么其他解决方案。
在本人的测试过程中发现,给ID设置为自增并不会影响用户自己设置ID。
关于分表后ID自增又会从1开始,我的解决方案是在需要进行分表时可以先获取前一个表的最后一篇文章,在得到这个文章的ID后,将新建的文章ID设置为上一篇文章的ID+1。
其他解决方案:如果采用hash算法进行分表的话,可以将设置文章ID和插入表分为两步操作,先根据自增将wenzhangID设置出来,再进行插入表的操作。
小结
总的来说,经过此次面试还是返现了学习上的不少漏洞,本篇文章只解决了在项目拷打环节的一些提问,关于八股文和一些算法方面的内容我想还是要分开来写。最后面试官也有提醒到项目还是可以增加一些功能。可问的点有很多,还是得把项目吃透。
从面试官所问的问题也不难看出,有关到项目的内容他们更想听到的是在实际中的各种情况和解决方案。