JAVA面试问答收集档案
1.JAVA基础
1.1 java知识点
1.1.1 Hashmap 源码级掌握,扩容,红黑树,最小树化容量,hash冲突解决,有些面试官会提出发自灵魂的审问,比如为什么是红黑树,别的树不可以吗;为什么8的时候树化,4不可以吗,等等
1.1.2 ArrayList 优势,扩容,什么时候用, LinkedList 优势,什么时候用,和arraylist的区别
答:A是实现了基于动态数组的数据结构,每个数据都在同一个地址上,根据下标就可以找到(O(1))所以查询更新起来很快,扩容条件是size > maxCapacity,所以一个A要加入N个数量只需要设置N大小的容量,就可以保证不进行动态扩容。L是基于双向链表的数据结构,每个数据都有不同的地址,它的优势在于增加删除快,只用修改目标位置节点的指向,不需要A那样移动目标位置前后所有数据+1-1。L不需要扩容。
1.1.3 String ,StringBuffer,StringBuilder哪个是安全的(StringBuffer用了synchronized,是安全的)
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
而如果是使用 StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
String S1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个
String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:
String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;
这时候 JVM 会规规矩矩的按照原来的方式去做
1.1.4 基本类型与包装类型的优劣对比,自动装箱与拆箱的原理?
https://juejin.im/post/5d8ff563f265da5bb252de76
补充知识:instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。然后里面POJO\DTO\VO也可了解,实际项目中这么设置会比较清晰。
补充问题:为什么范型不能使用基本数据类型?(从jvm角度解释一下,为什么会报错?其实关了编译阶段验证编辑就不会报错)
目前看到的答案是:假使范型使用基本数据类型,int和long所占用的内存不一样(int使用一个slot,long使用两个连续的slot),此外还要考虑数组的长度带来长度不确定问题。此外因为java是指传递不是引用传递,如果使用基本数据类型范型不仅会带来内存浪费而且从jvm层面几乎不可能实现。用包装类型可以完美的解决以上所有问题,但是把bug扔给了程序员自己处理(会有情况jvm处理不了自动拆装包)
1.1.5 什么是泛型,怎么用泛型
https://juejin.im/post/5b614848e51d45355d51f792#heading-14 深入理解泛型类(看明白了三种泛型方式的定义,后面的PECS原则还有问题)
这两者的区别在哪里,第一种是否有必要写呢?想问作者
Plate<? extends Fruit> plate = new Plate<Apple>(new Apple());
Plate<Fruit> plate1 = new Plate<>(new Apple());
1.1.6 多态的原理是什么
多态就是通过传递给父类对象引用不同的子类对象从而表现出不同的行为,多态可为程序提供更好的可扩展性,同样也可以代码重用。
(三个核心要点:1、父类的引用指向新建的子类对象。2、根据子类是否重写父类方法决定实例调用谁的方法。3、父类引用只能调用自己的扩展方法,除非向下转型?变成子类的引用指向子类对象)
JAVA四大特性:抽象性、封装性、继承性、多态性可参考网址:https://juejin.im/entry/59f292635188254115701364
1.1.7 Mybatis中的Dao接口和XML文件里的SQL是如何建立关系的(追问1:如果两个xml都关联一个dao接口会产生冲突吗?)
1、项目的配置文件中Mybatis配置文件的路径、实体类(entities)的路径以及mapper.xml的路径,当然spring和springboot的配置方法不一样,前者繁琐一些,这里不详细说。
2、Mybatis在初始化SqlSessionFactoryBean的时候,会找到mapperLocations路径去解析里面所有的XML文件
3、解析时,会根据xml中的sql类型标签生成一个MappedStatement对象,类似map结构,key就是sql标签,value则包括id、sqlSource对象等一系列属性,表明执行mapper接口方法时是根据 id 匹配xml的。
插一句:也正是这里可以回答追问1,答案是:不会,不管有几个XML和Dao建立关系,只要保证上面的id(相当于namespace+sql标签)
唯一即可。
4、接着会把每个sql封装成SqlSource对象,然后根据SQL语句的不同,会分为动态sql和静态sql,其中,静态SQL包含一段String类型的sql语句;而动态SQL则是由一个个SqlNode组成。
5、所有MappedStatement对象都会存在Configuration中,通过动态代理,会执行MapperProxy代理对象的invoke方法,循环每个sqlSource对象
6、最后通过sqlSessionProxy下的执行器excutor执行sql命令
提到四个点:
在搜索解答的时候,看到一位博主说“mybatis generator 已经过时了哦,太麻烦,耦合性高,建议使用通用Mapper,完美继承spring,springboot”,有兴趣这里再去了解一下,面试时也可以算作你的改进噢
1.1.8 Mybatis中${}和#{}的区别是什么,使用场景是什么?
1、前者表示sql被解析时,不对参数做任何处理就直接插入,而后者在解析时会预留占位符,并且根据带入参数的类型进行处理,比如传入参数为字符串时会自动为其添加双引号“ ”。
2、所以前者使用的场景一般是需要动态注入列名或者表名时,其他情况下为了更好避免sql注入问题, 都优先使用#{}方式。
1.1.9 @Autowired是按照什么策略来自动装配的呢?
答:是这样的,我看过一点源码,应该是默认会以ByType的策略进行匹配,如果发现存在多个相同的类型,那么还会根据ByName的方式或者检测某一个待注入Bean对象头上有无@Primary等注解来判断最终要装配哪一个Bean。
拿mybatis举个例子就是,比如有一个接口 UserMapper,对应的实现是UserMapper.xml,现在对该接口另外实现了一个UserMapperImpl,这时候在@Autowired UserMapper userMapper就会出问题,但是命名换成 UserMapper userMapperImpl或者userMapper就能够得到区分了
(花了一个小时,已验证,新实现的Impl忘记加@Compenent注解卡了好久)
1.2.0 mysql 自增id和UUID做主键的区别及性能分析?
自增id主键的特点:
1、占用储存空间小
2、自身有序
3、唯一性不明显,只能做到单表唯一
UUID主键的优势:
1、保证了全库唯一性,每生成一个都是独一无二的
2、非常占空间,且新建索引越多,查询速度越慢(因为普通索引是建立于主键索引之上,对于innodb来说)
3、作为字符,插入速度慢
从主流innodb引擎来说,自增id作为主键已经是最优选择,要注意的是:
了全局的唯一性,应该用其他逻辑主键做索引关联其他表或做外键。
1.2.0 mysql 查询行锁变表锁或者说索引查询变全表查询?
https://blog.csdn.net/xiaozhu0301/article/details/52605340
https://www.jianshu.com/p/0b381bd472d5
后面继续更新......