大家好,我是程序员小灰。
最近,小灰的一位读者在秋招提前批的时候,面试了字节的国际电商部门。这场面试考察得非常全面,涉及到了项目经验、数据结构、设计模式、数据库、Spring等等。
为了能帮助到更多程序员朋友,这位小伙伴把面试的过程详详细细做了记录和总结,希望大家能够从中获得启发。
背景介绍
先大概说一下我的背景吧,本科双非,研究生211,暑期在快手后端实习。
在秋招提前批的时候我投递了字节的国际电商部门,当时投递不久后就约了面试,一面的时候面试官是个和蔼的大叔,问的问题属于项目+基础知识都进行了拷打,面完第二天就喜提感谢信。
面试过程
1.项目拷打
刚进入飞书会议后我就紧张的等待面试官的上线,叮一声面试官进入了会议,紧张的面试开始~
面试官:我今天就先不让你自我介绍了,就直接按照你简历上的东西开始问吧
我:嗯嗯好的面试官
面试官:我看你简历上边写着你之前在快手实习过,你可以讲一下你的实习内容吗?
我:我在快手实习的时候是主要做的结算的相关业务,结算主要做一些是订单结算的流程,分别是订单相关流水参数校验、计费、结算等工作(吧啦吧啦讲了我的实习内容)。
面试官:你刚才说得有点快,你重点说一下在实习中主要参与了哪个部分的内容呢,你可以说你在这里边遇到的难点。
我:我主要负责的部分是做了一个订单结算优化的需求,还有一个数据同步的需求,其中我感觉比较难的地方在于整体的业务流程比较复杂,里边涉及到各种各样的分支流,还有就是数据的准确性一定需要保障好。
面试官:那你们的业务里边如果某次营销的数据发生了延时错误,导致了此时已经对这个订单进行了计费,现在应该怎么办呢
我:额。。。这个我还真的没接触过(原谅我对于这里的业务真的不太懂,还没了解这么多的,所以这个是真的不知道怎么解决)
面试官:我看你实习项目还写了mysql数据迁移到ES,那你说说你们迁移到ES的大概流程。
我:我们项目里边迁移Mysql数据到ES很重要的原因是Mysql中的数据在大批量导出的时候会容易阻塞,导致数据库慢查询,然后我们的优化思路是在写数据到数据库的时候同时监听数据库binlog到ES中,在写入时按照原来数据库中的主键索引去构建ES中每个文档的索引。
面试官:那你这里为什么要采用监听数据表binlog的方式去感知数据变动存储到ES呢,是否可以采用在写入数据库的时候再同时写入ES双写的方式呢?
我:这个应该是可以的,使用监听binlog的方式可以使得代码解耦,双写应该也没啥问题吧(说到这里面试官感觉似乎并不是他想要的答案了)。
项目总结:在回答项目的时候确实是对于项目的一些细节问题把握不够,只是停留在把这个东西做出来了,没有去深入的去分析为什么要这样子做,不同的方式实现起来有什么区别,同时也需要清楚自己做这个项目会带来怎样的收益。
2.基础挖掘
面试官:那我问问你基础知识吧,看你简历上边技术栈写的也不少。你了解HashMap吗,你讲一下HashMap的原理吧,
我:HashMap就是哈希表,java里边HashMap的初始哈希槽的大小为16,如果在某一个位置发生了哈希冲突可以用链表的方式将冲突的元素串起来,在链表的长度超过8的时候会将链表转为红黑树,使用红黑树可以增加查询的效率。
面试官:那为什么在刚开始的时候就不能采用红黑树存储呢,还要先用链表存然后再转成红黑树呢?
我:因为直接采用红黑树的话每次加入元素需要进行平衡,而在超过8时再旋转变为红黑树可以达成平衡,因为大部分哈希槽的元素个数正态分布在8个左右,所以此时变为红黑树也满足了查找的效率。(这里我觉得我自己掌握的还行,嘿嘿)
面试官:数据库你了解多吗,Mysql里边的存储引擎都有哪些呢,这些存储引擎又有什么区别呢?
我:存储引擎我比较了解的是InnoDB和MyIsam,其中InnoDB支持聚簇索引,并且支持外键、支持事务,而MyISam是非聚簇索引,不支持外键,也不支持事务,所以我们一般都选用的是InnoDB引擎。
面试官:如果是读多写少的场景,你觉得用什么引擎比较好呢
我:如果是读多写少的场景可以使用MyAsim引擎,因为InnoDB是属于聚簇索引,聚簇索引会由于索引与数据存放在一起,在同等的规模下非聚簇索引可以加载的更多,更加适合读取。
面试官:你平常会用spring对吧,在spring里你用到哪些注解呢?
我:我常用的注解一般是autowired、controller、requestmapping、service、bean这些注解。
面试官:你刚说了autowired注解,那你有用过resource注解吗,你知道它们二者的原理吗?
我:它们二者的主要区别是一个是按照name加载,一个是按照type加载,然后具体原理有些久远我有点忘了,我还记得现在推荐用resource注解(之前找实习的时候看过,时间久远这些就有点忘了哭了呜呜呜)
基础总结:回答基础问题的问题要准确把握面试官想要问的点,尽量想好再说,不要给面试官一种你的知识不太稳固的感觉,平常可以多在网上看看在相关基础细节,分类去准备:java的基础知识看看集合类、异常处理、多线程并发、JVM等知识;数据库的话就是索引、隔离级别、MVCC、锁、redo log、undo log、binlog等相关知识,这次面试官没有问我redis,建议redis也要做好知识储备,redis的数据结构、线程模型、分布式锁等也值得深入学习。
3.手撕代码
面试官:那我们写点代码吧,你了解设计模式吧,我看你简历上边有写了解单例模式,那你就写一下单例模式吧
我:单例模式有好几种实现,那我就都写一下吧(心理diy:这可碰到我的枪口上了,毕竟前一天刚把单例模式复习了一遍,先从最基础的单例开始写吧,嘿嘿嘿)
我:一顿噼里啪啦输出,写好了面试官
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
面试官:嗯~看着单例模式没啥问题,如果现在是个多线程竞争环境呢,这种方式有什么风险呢?
我:如果是多线程环境的话需要加锁,可以加synchronizd关键字便可以加锁,这样就可以确保创建的对象还是单例的了。
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
面试官:那你这里的synchronized加锁的对象是什么呢?
我:synchronized这里加锁的是类方法,也就是加锁在了类对象上。
面试官:好,那你有了解过synchronized的锁升级的过程吗,可以讲一下吧。
我:synchronized锁升级应该是刚开始在没有线程竞争的时候会使用偏向锁,然后在多个线程交替进入临界区的时候会升级为轻量级锁,在有多个线程同时进入临界区的时候会将锁升级为重量级锁,具体的锁升级的原理我有点忘了(此时心理有点后悔自己为啥面试前不好好再复习复习了)。
面试官:好吧,如果我现在不想让你改动刚刚写的原有的代码,但是还需要你去把这个类对象新建出来,应该怎么办呢
我:这个嘛这个嘛,让我思考思考哈(脑子里一团懵,代理、反射之类的知识从脑海闪现)
我:我有一个想法,但是可能比较偷懒,我先给您说一下吧。
面试官:行,那你说吧。
我:其实既然这个构造器现在是私有的,那么就可以想办法把这个构造器变成可见的,可以通过反射,使用setAccessed(true)去把构造器变成可见的,然后创建对象。
面试官:你的这个方法也不是不行,就是有点偷懒,不是我想要的答案,你可以再想想。
我:此时脑子很懵逼😳,不知道还有啥办法,无数可能得方式在脑海中闪过,直到想到自定义类加载器。。。)
我:是不是可以用自定义类加载器呢(试图确定的样子)
面试官:那你讲一下具体怎么样操作吧
我:应该是去重写loadClass方法吧,具体操作我也没操作过。
面试官:这里你还是没有说清楚,给你换个题目吧。
面试官:最后再问你一个开放的情景题吧,现在空间中有n个坐标点,怎么样判断是否可以组成一个凸出的多边形。
我:我想一下吧,我可以用纸吧(我用纸和笔画了半天硬是没画出来)
我:我觉得应该判断一下它有没有凸出部分吧,具体咋样操作我也没有想法了
面试官有点不耐烦地说好了,我看时间也差不多了,今天的面试就先到这里吧。
手撕代码总结:开始时以为是算法题,结果面试官没按常理出牌,让我写单例模式,我以为就把几种单例模式写了后就结束了,没想到写了第一个后面试官就直接打断问别的了,总之很灵活,还是需要多多准备,各个方面都要了解,也不能光刷算法题,最好对于一些常见的设计模式的样例代码自己也会写,而且还有就是可以了解一下常见的情景题,例如赛马问题等,要不然这些题当场想的时候真的在紧张的氛围下不太能想的出来。
4.反问阶段
面试官:你还有什么什么想问的吗?
我:我想问一下您就是因为我之前一直在实习,所以也没有时间再去复习基础知识,很多东西学的不太深入,所以可能回答的不太好,您是觉得业务更重要呢还是技术细节更重要呢?
面试官:我觉得这两个东西是技术是基础,业务是建立在基础上的,感觉你下去后可以在两个方面都再提升提升,我们搞技术的应该始终都是技术放在第一位。
我:嗯嗯好的,感谢面试官您的时间(感觉应该凉凉了,所以就没有再问面试结果多久可以通知)
复盘总结
这是秋招的第一场大厂面试,总结就是由于之前一直在实习,所以很多知识由于时间的原因总结的并不充分,吃一堑,长一智,在项目深度、基础知识、还有手撕代码环节都应该再多多提升啊。