社招面试总结
Posted HelloWorld_EE
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了社招面试总结相关的知识,希望对你有一定的参考价值。
社招面试总结
本文首发在个人公众号:HelloWorldEE,欢迎扫码加入,以后将会不定期的更新Java、mysql等相关的知识。
前言
目前在考虑新的机会,面试了几家公司,趁今天周末,想想还是写篇面筋吧,希望对大家有所帮助。
在写这一篇面筋之前,自己也回去看了下2016年9月自己参加完校园招聘之后写的面筋内容。
发现对于基础知识部分,还是有很多相同的,但也有一些不同点。下面具体说一下
常见面试题
下面将从项目、Java基础、MySQL、Redis、Spring等几个方面来一一进行介绍。
项目
不用多说,项目这块在面试过程中肯定少不了,由于每个人所做的项目不一样,但是有几个通用问题值得说一下
1.在项目中遇到的最大难点和挑战是什么?无论是技术上的,还是业务上的
这个问题真的很难,需要好好思考好好准备。
2.在项目中你收获最大的是什么?
3.工作中有遇到什么线上故障,例如OOM等
Java基础
1.HashMap、ConcurrentHashMap的实现原理
常见的put、get方法的大致实现原理没什么说的,我想大家都应该都了解。
我在面试中,有两个面试官问到这样的问题,ConcurrentHashMap的put方法中什么情况下会加锁?什么情况下使用的是CAS操作,什么情况下使用的是synchronized关键字加锁?如果不使用synchronized加锁会有什么样的问题,可否举一个实际的例子来说明?
笔者本文在第一次被问到的时候是比较懵逼的,虽然以前看过ConcurrentHashMap的实现原理,还仅仅只是大致看了下,仅了解一个大概,而且好多也忘记了,面试过程确实尴尬。
一点感受:社招面试不仅仅要求大致看过源码懂得大致思路,而且还需要对相应的细节有一定的研究和了解。
2.ThreadLocal的具体实现以及在项目中的应用场景
面试了几家公司,发现这个类被问到的频率是相当高的,其实真正在我们项目开发中,被用到的场景其实是比较少的,笔者见过和使用过的具体场景如下:
- 为保证线程安全,变量被线程独享
通常在项目中我们都需要将时间转换为指定的格式,而且在项目中用到的地方很多,因此为了复用我们都会进行相应的封装提供静态方法。如下就是两种不同的写法,第二种写法就是使用ThrealLoca老保证线程安全。否则,在并发的情况下如果调用第一种方法,则会抛java.lang.NumberFormatException: multiple points 异常,更多看这里:https://www.cnblogs.com/huangwentian/p/6762143.html
public class DateUtils
//写法一:非线程安全
private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String format(long date)
return DAY_FORMAT.format(date);
//写法二:线程安全
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>()
@Override
protected DateFormat initialValue()
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
;
public static String format(long date)
return threadLocal.get().format(date);
- 传参,即传递上下文
有小伙伴可能会说:传参为什么要用到ThreadLocal呢?直接在方法中扩展一个参数不就可以了,确实如此,这是一种解决方法。而另外一种解决方法就是:将参数放在ThreadLocal中,有需要就到这里面来取就好。问题是:什么情况下使用ThreadLocal这种方法要更好呢? 答案是:1)此参数需要被传递的比较深,且并不是每个方法都需要此参数。
- 拼接响应信息,特别是异常提示信息。
这个和传递是类似的道理,但又有点不同。
3.volatile关键字的作用,如何来保证可见性的?说到可见性,就直接延伸到了Java内存模型。
这个也是被问到的频率相当相当之高。
4.类加载机制
说到类加载,我们肯定都知道 双亲委派机制,问题来了:1)双亲委派机制的目的是什么?2)如果没有双亲委派机制,只有一个类加载器,可不可以?
类加载延伸的问题:热部署问题,即如果一个类有一个小bug,如何来不使用打包部署这种比较重的方法来修这样一个bug?
对于热部署,由于笔者确实在工作中没有使用过,所以也比较懵逼,尴尬。
一点感受:社招面试确实有的问题还是比较深的。
5.Java内存分区以及相应的垃圾回收算法
相信这个题没什么好说的,都或多或少都稍微有点了解。
关于这个面试题的延伸:CMS和G1具体实现和区别。
第一次被问到这个,也是相当懵逼的,因为在工作中没有JVM调优相关的经验,自己也没有对具体垃圾回收器进行研究。
6.线程池原理
上面这些问题,都是被问的频率相当相当之高的Java基础题,其他当然还有一些,这里就不一一列举了。
除了Java基础,对于社招,问的最多的就是相关框架的原理了
MySQL相关
1.使用的数据结构是什么?
2.为什么会选择B+树,而不是B树?
3.聚簇索引和非聚簇索引?
4.联合索引是如何来存储的?
5.like a% 这种会不会走索引,like %a 这种会不会走索引?
6.不等于 会不会走索引?
7.优化器在什么场景下选择的索引不是最佳的?优化器在选择索引时会考虑哪些因素?
8.一条select语句的整个执行过程是什么样的?
9.工作中一般的慢查询,都是因为什么原因引起的?如何来修复?
10.如果你是DBA,如何来找出相应的慢sql?
11.MySQL的隔离级别,以及各个隔离级别有什么问题。
12.分库分表,这个问题必问
上面这些问题不太难,但是都需要你对MySQL有相应的研究。笔者在面试过程中,对MySQL这一块还算比较了解,因此这一块面试是比较轻松的。
redis相关
1.redis的常用数据结构以及内部实现。
说到redis的数据结构,记得面头条的时候有这样一道经典题,值得分享给大家,对话是这样
面试官:有一个链表,如何来找到一个目标值,时间复杂度是多少?
我:链表呀,只能从头到尾开始遍历,然后比较,找到目标值。时间复杂度为O(n)
面试官:如果这个链表是有序的呢?如果来找到一个目标值?
我:链表有序的呀?思考了一下下,也还是只能够从头到尾开始遍历,如果可以借助于外部容器,例如:数组,则可以使用二分查找之类的算法来实现。时间复杂度为:O(logn)
面试官:跳表有了解过吗?
我:尴尬,比较懵逼。。。
原来面试官的考点是想引起跳表呀,哈哈
回归正题,redis支持的数据结构:sorted list的底层实现就是借助跳表来实现的。
2.项目中使用redis的场景有哪些?
笔者在项目中仅利用redis来实现1)分布式锁,2)缓存相应的数据
因此延伸出了如下一系列的问题
1、redis 如何来实现分布式锁。
解决方案:setNX key value,value保证唯一性,避免线程A释放线程B拿到的锁。
2、实现分布式锁如果使用的是setNX命令,那么如果拿到锁的机器宕机了,其他服务不就拿不到锁了吗?
解决方案:设置过期时间。
3.如何来设置过期时间?先set key value ,再设置过期时间吗?
如果是两条命令,set key value成功,设置过期时间失败,一样存在如上的问题。那么如何来保证set key value 和 设置过期时间的原子操作?
解决方案:set命令提供了相应的原子命令来保证:set key value 和 设置过期时间的原子操作。
4.redis是使用的集群吗?如果是集群,当客户端执行 setNX 时redis集群 如何做才认为set成功?一半集群set成功,就认为成功吗?还是全部set成功才认为成功?
回答:肯定不是全部成功才认为成功,因为如果有一台机器挂了,就一直set不成功,不可用,那么一半集群成功?如果主节点挂了,如何从从节点中选出主节点。
解决方案:redis集群使用的是多主多从,当一半以上的主节点set成功,才算是set成功。
5.一半成功就算是成功,假设redis集群有a、b、c三个主节点,各有一个从节点,线程A在a、b主节点set成功,而在c主节点set失败,此时线程A获取到锁,而此时刚好b主节点宕机,而刚好数据还没有同步到其从节点,那么此时从节点b‘升级为主节点,那么线程B对相同的key执行set命令来获取锁,在b’和c节点set成功,这不同样可以获取到,此时又出现了多个线程获取到同一把锁?
解决方案:留给大家思考。
6、redis缓存,如何来完成更新
解决方案:先delete缓存,再更新DB,延时一段时间再delete缓存。or 先更新DB,延时一段时间再delete缓存。
为什么要延时一段时间?
因为如果A线程先delete缓存,此时B线程发现缓存中没有数据,则从DB中读出老的数据并reload到缓存,线程A更新数据库之后,则缓存与数据库中的数据不一致,因此需要延时一段时间执行删除。
如果删除失败呢?
解决方案:重试机制。
以上关于redis的常见面试题,一环接一环,还是比较经典的。经过redis的这次面试之后,关于如何来保证DB和缓存一致性写过一篇博文,在这里可以获取:https://mp.weixin.qq.com/s/fst1esfxtu5lPn4qreZZ_g
上面说到了redis,关于缓存,还有两个被问的频率相当高的问题,这里和大家分享
1.缓存雪崩如何避免?
2.缓存击穿如何来避免?
Spring相关
1.Spring Bean加载过程
2.Spring 如何来解决循环依赖
3.BeanFactory、FactoryBean的区别和应用场景。
4.Spring ioc,aop
关于aop有一个比较经典的面试题
面试官:类似于@Transactional在什么场景下有效,什么场景下无效呢?
我:平时在项目中我们从一个bean调用另一个bean带注释的方法,该注释就会生效。在一个类中,一个方法调用另一个带注解的方法,此注解就不会生效。
面试官:为什么呢?
我:因为从一个bean调用另一个bean带注释的方法这种方式借助了Spring的动态代理来实现的。动态代理Spring会生成一个代理类。代理类中会在方法头部和尾部做相应注解的事情。
面试官:在一个类中,一个方法调用另一个带注解的方法,我希望注解能够生效,有什么解决方法?
我:这种情况要注解生效呀?尴尬,不知道也
面试官:面试官提示获取其代理类即可。
我:恍然大悟,噢,只需要把Spring做的事情,我们自己来做就好了。
其他
1.手写算法题
这个即使是社招,也少不了。
说实话:个人还是比较反感写快排呀之类的算法的,没有太多意思。
2.rpc框架的原理
此问题必问,一般的回答都会说到
1)服务注册
2)服务发现
3)一次rpc调用过程是如何的
可能也会说到:负载均衡、异步同步、缓存、超时等等
延伸的问题:
1)如果服务的某一个节点异常挂掉了,注册中心是通过什么机制来将其摘除的?
2)负载均衡的算法有哪一些?随机、轮训、加权轮训?你会选择哪一种负载均衡算法?
这个问题比较经典,如果你说轮训、加权轮训,那么面试官会问:如果量级相当相当大,你还会选择轮训吗?答案留给大家思考。
3.消息MQ相关
如何来保证消息的有序、幂等呀?
4.CPU 100%的排查思路
小结
暂时就想到了这么多,以后有好的面试题,也会补充进行,希望对大家有所帮忙。
在整个找工作过程中,个人感觉就是:好好准备+机遇。
好好准备指的就是:该看面筋就看面筋,该刷题就刷题。虽然平时工作中可能用的不多。确实矛盾,是吧,但找工作就是如此。
机遇:遇到合适的面试官。
以上是关于社招面试总结的主要内容,如果未能解决你的问题,请参考以下文章