一面(50~60min)
1.介绍项目
2.4种序列化的区别
3.MySQ的事务,读已提交解决了什么(脏读),重复读解决了什么(不可重复读,MVCC实现),介绍MVCC
4.索引,有哪几种索引,为什么用B+,什么时候用B+什么时候用hash索引?
5.b+树的好处,索引什么时候失效,最左前缀匹配是什么,联合索引a,b,查询时先b再a,会走索引吗?(a,b,c索引时,cba会走(优化),bca不会)
6.网络五层模型,ip转发在哪一层
7.介绍一下集合分类
8.ArrayList和LinkedList有什么区别
9.HashMap的结构,put的流程,多线程情况下会产生什么状况,能详细介绍一下具体的状况吗?多线程的情况用什么代替,ConCurrentHashMap的结构,为什么比HashTable效率高,什么是锁升级
10.Spring或者SpringMVC的原理流程,介绍一个吧
11.volatile的作用,volatile修饰的i++线程安全吗,为什么
12.sleep(0),synchronized锁升级机制
13.项目如何完成对接?get和post区别,应用场景
14.单例模式了解吗?手写一个单例模式。
面试问题都比较常规,但是有些问题面试官拓展的比较深,一面超级紧张,在这里为商业化正一下名,因为是第一次面试,面试前在网上看了看商业化的评价,说面试官很凶,但是我这个面试官非常好,一直引导我,试图让我不紧张。
感谢感谢感谢!
下面是我结合网上的资料加个人理解。针对我这次的部分题目做的总结,有错误的地方希望大家友好指出
1.为什么用B+(存的数据多,且IO压力小,并适合范围查找)
首先说红黑树为什么不行:(红黑树的优点:红黑树常用于存储内存中的有序数据,增删很快,维护结构代价小)
1.红黑树必须存在内存里的,数据库表太大了,存不进去。?(不建议答,直接答红字)
2.即使你找到了把红黑树存进硬盘的方法,红黑树查找一个节点最多要查logN层,每一层都是一个内存页(虽然你只是想找一个节点,但硬盘必须一次读一个页。。),那么一共logN次IO,伤不起阿!
总结(减少IO,b+树一次读差不多的大小的一页结点)
注意磁盘读数据读一个字节和读10个字节和读一页时间相差不大的(因为磁盘查找时间大多数都花在寻道上,旋转基本不费时(预读原理))
先讲下b树和b+树的区别:
b树的所有节点都是数据节点,但b+树只有叶子节点是数据节点,非叶子(内部)节点只起导向作用,不存储实际数据。
b+树的所有数据节点都在最下层(叶子节点层),相邻节点有链表相连。
再说b树为什么不如b+树:
1.b树的内部节点都是存储实际数据的,比如一个节点是一个页4096字节,其中每条数据128字节,那么一个节点只能存32个数据项,那么对应的孩子节点数最多为33个,这显然不够用。而b+树内部节点只作为导向作用,只存一个整数就可以,4096/4=1024个数据项。这样b+树的每个节点的孩子数更多,整个树的高度就更低,大大增加查询效率。
2.b+树的叶子节点有链表相连,适合范围查询,因为相邻页直接读取就好了。但b树做不到这一点。
总结:1.B+树非叶子结点只做导向不存数据,因此可以存更多的数据。2.叶子结点有链表相连,适合范围查询
2.什么时候用B+什么时候用hash
大多数情况下,通常B+数据的查询时间为log(n),而利用Hash时间为o(1),那为什么还要用B+树呢?
Hash需要把数据一次性读到内存中,耗内存。hash只适合做单值查询不适合做范围查询
3.什么时候不走索引
1.联合索引时不符合最左前缀
2.or有条件无索引(版本问题,有可能会走)或者like '%a'不会走索引,但是'a%'会走
3.mysql认为全表扫比走索引快,如只有一行数据
4.集合分类
1.Collection接口:Set,List,Queue三大接口
2.Map:HashTable,HashMap,LinkedHashMap
Set和Map接口下分别还有一个SortedSet和SortMap接口,分别有TreeSet和TreeMap实现类
5.HashMap1.8的多线程会产生什么问题
1.判断桶结点为空,其实已经线程已经加数据进去了
2.++size线程不安全,导致扩容错乱
3.A线程操作hashmap过程中出现了resize。而这时候B线程(没有触发resize)仍在向hashmap中put数据。最后结果就是出现的线程安全问题。
6.volatile修饰的i++线程安全吗
volatile不保证原子性,i++不是原子操作,对应的字节码是多步操作,多线程会错乱
原子类是通过cas+自旋实现的
7.Spring,SpringBoot,Spring的原理流程
1.SpringBoot自动装配原理:
1.启动run方***进入一个refreshContext方法刷新容器
2.此后会扫描注解,找到我们@SpringBootApplication注解下的 @EnableAutoConfiguration注解,此注解会帮我们import导入 AutoConfigurationImportSelector.class
3.此类中有个selectImports()方***扫描所有具有META-INF/spring.factories的jar包
4.此配置文件中是key--value的形式,key,EnableAutoConfiguration的value中存在很多个自动配置类
5.而这些自动配置类会有一些Conditional条件注解来判断是否生效
6.而这些配置类会与自己对应的Properties结尾命名的类进行默认属性绑定,以注册到容器中
2.SpringIOC原理
3.MyBatis缓存:MyBatis 的缓存分为一级缓存和二级缓存,一级缓存放是伴随sqlSession的生命周期的,默认就有。二级缓存放在它的命名空间里,默认是不打开的。
执行原理:
1.读取配置文件缓存到Configuration对象,通过工厂创建对象的build方法来创建SqlSessionFactory
2.可以通过SqlSessionFactory去获取SqlSession对象
3.SqlSession可以执行我们在xml中配置的crud方法(动态代理)
8.synchronized锁升级机制
首先分为4类锁,无锁,偏向锁,轻量级锁,重量级锁
0.首先在无锁状态时,CAS来获取锁,将对象头中的线程id改为当前线程id,变为偏向锁
1.偏向锁会记录上一次获取锁的线程id,不会有解锁等操作,下次该线程来获取锁只需要验证markword存储的线程id是否是该线程id即可,节省了解锁加锁的开销
2.有其他线程竞争时,上个线程会释放偏向锁,此时偏向锁升级为轻量级锁,当前线程再尝试CAS改对象头,如果成功,则获取;如果失败,表示有其他线程在竞争,则尝试自旋来获得锁,如果在自旋的过程中再来线程竞争(自选次数超过设置的界限,等待线程超过设置的边界),就会升级为重量级锁(交给我们的操作系统管理)
9.get和post区别及应用场景
1.get通过url传输,post通过request body来传输(post相对来说更安全)
2.get有长度限制,post没有
3.get产生一会tcp数据包,post两个,先发一个header包,服务器返回100,再发一个data包(为什么发两次:分开发,在网络环境差的时候更好验证数据的完整性)
全部评论
(2) 回帖