Java校招面试汇总
- 一、JavaSE
-
- Ⅰ、基础知识
- Ⅱ、字符串
- Ⅲ、集合
-
- 1、说说Java中常用的容器有哪些?
- 3、迭代器 Iterator 是什么?
- 4、如何边遍历边移除 Collection 中的元素?
- 5、Iterator 和 ListIterator 有什么区别?
- 6、如何实现数组和 List 之间的转换?
- 7、ArrayList和LinkedList的区别
- 8、ArrayList 和 Vector 的区别是什么?
- 9、插入数据时,ArrayList、LinkedList、Vector谁速度较快?
- 10、多线程场景下如何使用 ArrayList?
- 11、说一下HashSet的实现原理?
- 12、HashSet与HashMap的区别
- 10、HashMap的实现原理
- 11.说说HashMap的put方法执行流程?
- 12.说说HashMap的get方法执行流程?
- 13,哈希冲突有几种解决办法?
- 14、HashMap 与 HashTable的区别
- 15、ConcurrentHashMap 的实现原理
- 16、ConcurrentHashMap 不支持 key 或者 value 为 null 的原因?
- 17.说说ArrayList 的扩容机制?
- 18.Array和ArrayList有何区别?
- 19.comparable和comparator的区别?
- 20.Collection和Collections有什么区别?
- Ⅳ、异常
- Ⅴ、IO流
- 二、多线程
- 三、数据库
- 四、框架
-
- Ⅰ、Spring
-
- 1、使用Spring框架的好处是什么?
- 2、Spring的IOC理解
- 3、什么是DI?
- 4、什么是AOP?
- 5、Spring通知(Advice)有哪些类型?
- 6、Spring容器的启动流程
- 7、Spring框架使用了哪些设计模式?
- 8、BeanFactory和ApplicationContext有什么区别?
- 9、Spring Bean的生命周期?
- 10、Spring中bean的作用域
- 11、Spring框架中的Bean是线程安全的么?如果线程不安全,那么如何处理?
- 12、Spring基于xml注入bean的几种方式
- 13、Spring的自动装配
- 14、 springmvc常用到的注解,作用、原理是什么?
- 16、 SpringMVC执行流程和原理
- 17、有哪些重要的Spring注解?
- 18、Spring事务的实现方式和实现原理
- 19、Spring如何管理事务的?
- Ⅱ、 MyBaits
-
- MyBaits的优缺点
- 2、相对于JDBC,MyBatis做了哪些改进?
- 3、 MyBatis编程步骤
- 4、说说MyBatis的工作原理
- 5、MyBatis 的 Executor 接口是如何操作数据库的?
- 5、#{} 和 ${} 的区别是什么?
- 6、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
- 7、通常一个mapper.xml文件,都会对应一个Dao接口,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
- 8、MyBatis的Xml映射文件中,不同的xml映射文件,id是否可以重复?
- 9、Mybatis是如何进行分页的?分页插件的原理是什么?
- 10、 MyBatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 11、MyBatis是否支持延迟加载?如果支持,它的实现原理是什么?
- 12、MyBatis动态sql有什么用?执行原理?有哪些动态sql?
- 13、使用MyBatis的mapper接口调用时有哪些要求?
- 14、在mapper中如何传递多个参数?
- 15、 一对一,一对多的关联查询 ?
- 16、MyBatis实现一对一和一对多有几种方式?具体怎么操作的?
- 17、 什么是MyBatis的接口绑定?有哪些实现方式?
- Ⅲ、SpringBoot
-
- 1、SpringBoot 有哪些优点?
- 2、SpringBoot 的核心注解是哪个?它主要由哪几个注解组成的?
- 3、SpringBoot 的核心配置文件有哪几个?它们的区别是什么?
- 4、SpringBoot Starter的工作原理
- 5、 SpringBoot 配置加载顺序
- 6、 SpringBoot 有哪几种读取配置的方式?
- 7、 SpringBoot 实现热部署有哪几种方式?
- 8、 如何重新加载SpringBoot上的更改,而无需重新启动服务器?
- 9、SpringBoot事物的使用
- 10、什么是 JavaConfig?
- 11、SpringBoot 中如何实现定时任务 ?
- 12、 有哪些spring-boot-maven-plugin命令?
- 13、SpringBoot的自动配置原理是什么?
- 14、 什么是YAML? 它有哪些优点?
- 14、SpringBoot多数据源拆分的思路
- 15、SpringBoot多数据源事务如何管理?
- 16、SpringBoot 打成的 jar 和普通的 jar 有什么区别 ?
- 五、Git
- 六、Linux
- 七、redis面试题
一、JavaSE
Ⅰ、基础知识
1、Java中引用数据类型有哪些,它们与基本数据类型有什么区别?
只要不是基本数据类型,都是引用数据类型;
创建引用数据类型时,在栈内存中存储引用地址,在堆内存存储具体的值;
栈内存引用地址指向堆内存空间;
用equals()方法比较内存地址,==和!=是比较数值的。
2、Java中的自动装箱与拆箱
装箱就是自动将基本数据类型转换为包装器类型,拆箱就是自动将包装器类型转换为基本数据类型。
3、==和equals()的区别
-
==
基本类型:比较的是值是否相同; 引用类型:比较的是引用是否相同;
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true
-
equals()
equals 本质上就是 ==,String 和 Integer 等类重写了 equals 方法,把它变成了值比较; String、Date、File、包装类都重写了Object类的equals方法。
class Cat {
public Cat(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Cat c1 = new Cat("叶痕秋");
Cat c2 = new Cat("叶痕秋");
System.out.println(c1.equals(c2)); // false
4、static和final的区别
5、什么是内部类?内部类的作用
-
成员内部类
可以无条件访问外部类的所有成员,包括私有的和静态的; 当成员内部类拥有和外部类同名的成员时,访问时默认是成员内部类的成员。
-
局部内部类
定义在方法或者作用域里面的类,访问权限仅限于方法内或者该作用域内。
-
静态内部类
可以不依赖外部类而实例化,不可以有与外部类相同的成员,不可以访问外部类非静态的成员。
6、抽象类和接口的区别
1. 成员区别:
-
抽象类
抽象类有构造方法,可以用子类实例化; 既可以有成员变量也可以有常量; 成员方法既可以有抽象的也可以有非抽象的。
-
接口
接口没有构造方法,只能定义常量,默认修饰符:public static final; 可以用default和static修饰。
2. 关系区别:
抽象类可以继承类,可以单继承,不能多继承,但可以多层继承;
类实现借口,可以实现单接口,也可以实现多接口;
一个类在继承父类的同时,还可以实现多个接口;
接口继承接口,可以多继承,因为接口的方法一般默认是抽象的。
3. 使用原理不同:
当关注事物本质的时候,用抽象类;当关注操作的时候,用接口;
抽象类表示这个对象是什么,例如Student类和Teacher都是Person类,都有人类的共有属性,可以定义一个人类的抽象类;
接口表示这个对象能做什么,是对类行为的约束;
即它的实现类可以做什么,但实现类是什么,怎么做的,接口并不关心;
例如人类吃东西,鸟类也吃东西,它们都有一个“吃东西”的方法,可以定义一个“吃东西”的接口,让人类和鸟类都去实现它。
4. 功能不同:
抽象类的功能要远大于接口,由于一个类只能继承一个类,所以在一个抽象类中,你必须继承或编写其所有子类的所有共有属性;
虽然接口的功能较少,但接口只是对一个动作的描述,一个类可以实现多个接口,从而在设计阶段降低难度。
7、instanceof关键字的作用
instanceof严格来说是Java中一个双目运算符,用来判断一个对象是否为一个类的实例。用法如下:
boolean result = obj(对象)instanceof int i = 0;
System.out.println(i instanceof Integer);//编译不通过 i必须是引用类型,不能是基本类型System.out.println(i instanceof Object);//编译不通过
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
//false ,在 JavaSE规范 中对 instanceof 运算符的规定就是:如果 obj 为 null,那么将返回false。
System.out.println(null instanceof Object);
8、什么是泛型?泛型的好处
泛型是编写代码时可以规定一种通用的数据类型,而不是具体的;
比如ArrayList就是一种泛型,提高代码的复用性。
9、Java中创建对象的几种方式?
- 通过new。
- 通过反射机制Class类的newInstance()方法或者Constructor类中的newInstance()方法。
String str1 = String.Class.newInstance();
String str2 = String.Class.getConstructor().newInstance();
-
克隆
实现 Cloneable 接口,重写 Object 类的 clone() 方法; 没有实现 Cloneable 接口,会抛出CloneNotSupportedException异常; Object 类提供的 clone() 方法,访问权限是 protected,所以如果不重写 clone() 方法,是没有权限调用的。
-
通过对象的反序列化
String str1 = new String("反序列化一个对象");
// 序列化一个girlFriend
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("String.obj"));
objectOutputStream.writeObject(String1);
objectOutputStream.close();
// 反序列化出来
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("String.obj"));
String str2 = (String) objectInputStream.readObject();
objectInputStream.close();
10、Java的四种引用
-
强引用
在内存不足时也不会被回收,使用方法为:String str = new String("str");
-
软引用
在内存不足时会被回收,使用方法为: SoftReference<String> wrf = new SoftReference<String>(new String("str"));
-
弱引用
只要jvm垃圾回收器发现了它,就将其回收,使用方法为: WeakReference<String> wrf = new WeakReference<String>(str);
-
虚引用
和弱引用差不多,不同的是虚引用在被JVM回收之前会被放入ReferenceQueue中, 而其他引用是在被JVM回收之后放入ReferenceQueue。
11、Files的常用方法都有哪些?
Files. exists():检测文件路径是否存在。
Files. createFile():创建文件。
Files. createDirectory():创建文件夹。
Files. delete():删除一个文件或目录。
Files. copy():复制文件。
Files. move():移动文件。
Files. size():查看文件个数。
Files. read():读取文件。
Files. write():写入文件。
12、Java的反射机制
对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。
13、反射的实现方式
1、类名.class,不会对类进行任何初始化;
2、Class.forName(“类的路径”),对类进行静态初始化;
3、对象名.getClass(),对类进行静态和非静态初始化;
4、基本类型的包装类,调用包装类的Type属性来获得该包装类的Class对象
14、Java反射API有哪些?
1、Class:表示正在运行的Java应用程序中的类和接口,所有获取对象的信息都需要Class类来实现。
2、Field:提供有关类和接口的属性信息,以及对它的动态访问权限。
3、Constructor:提供关于类的单个构造方法的信息以及它的访问权限 4、Method:提供类或接口中某个方法的信息
15、反射机制的优缺点
-
优点:
能动态的获取类的实例,提高代码灵活性 -
缺点:
①反射性能较低,因为需要对字节码进行解析,对内存中的对象进行解析
解决方案:
- 通过setAccessible(true)关闭JDK的安全检查来提升反射速度;
- 多次创建一个类的实例时,有缓存会快很多
- ReflflectASM工具类,通过字节码生成的方式加快反射速度
②程序不安全,因为反射会获取类的私有属性和方法
16、如何利用反射创建对象?
- 使用 Class 对象的 newInstance()方法来创建该 Class 对象对应类的实例,但是这种方法要求该 Class 对象对应的类有默认的空构造器。
- 调用 Constructor 对象的 newInstance(),先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance()方法来创建 Class
对象对应类的实例,通过这种方法可以选定构造方法创建实例。
17、Java中哪些地方用到了反射?
- 工厂模式中的简单工厂模式优化
- 代理模式中的动态代理方式实现
- Java JDBC数据库操作
Ⅱ、字符串
1、String、StringBuffer和StringBuilder区别
-
数据可变
String 底层使用一个不可变的字符数组 private final char value[]; StringBuffer 和 StringBuilder 都继承了 AbstractStringBuilder, 底层使用的是可变字符数组: char[] value;
-
线程安全
StringBuilder 是线程不安全的,效率较高; 而 StringBuffer 是线程安全的,效率较低。 通过他们的 append() 方法看, StringBuffer 有同步锁,而 StringBuilder 没有。
2、String str=“i” 与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。
String str="i"的方式,Java 虚拟机会将其分配到常量池中;
而String str=new String("i") 则会被分到堆内存中。
代码示例:
String x = "叶痕秋";
String y = "叶痕秋";
String z = new String("叶痕秋");
System.out.println(x == y); // true
System.out.println(x == z); // false
String x = "叶痕秋" 的方式,Java 虚拟机会将其分配到常量池中,而常量池中没有重复的元素,
比如当执行“叶痕秋”时,java虚拟机会先在常量池中检索是否已经有“叶痕秋”,
如果有那么就将“叶痕秋”的地址赋给变量,如果没有就创建一个,然后在赋给变量;
而 String z = new String(“叶痕秋”) 则会被分到堆内存中,即使内容一样还是会创建新的对象。
3、String 类的常用方法都有那些?
indexOf():返回指定字符的索引
charAt():返回指定索引处的字符
replace():字符串替换
trim():去除字符串两端空白
split():分割字符串,返回一个分割后的字符串数组
getBytes():返回字符串的 byte 类型数组
length():返回字符串长度
toLowerCase():将字符串转成小写字母
toUpperCase():将字符串转成大写字符
substring():截取字符串
equals():字符串比较
4、String s = new String(“xyz”); 创建了几个StringObject?是否可以继承String类?
先判断字符串常量池里面有没有"xyz"字符串对象,
如果有,就不会在常量池里面创建"xyz"对象,但是会在堆内存里面创建一"xyz"个对象,
并将对象地址返回给 str 变量,这种情况创建一个对象;
如果常量字符串没有,就会现在常量池里面创建"xyz"字符串,
然后再在堆内存里面创建"xyz"字符串对象,这种情况会创建两个对象
至于String类是否继承,答案是否定的,因为String默认final修饰,是不可继承的。
5、String s = “a”+“b”+“c”+“d”; 创建了几个对象?
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");//flase
System.out.println(s3 == "ab");//true
这说明javac编译可以对字符串常量直接相加的表达式进行优化,
不必要等到运行期再去进行加法运算处理,而是在编译时去掉其中的加号,
直接将其编译成一个这些常量相连的结果。
String s = "a"+"b"+"c"+"d"; 相当于直接定义了一个”abcd”的字符串,
所以,上面的代码应该只创建了一个String对象。
String s ="a" + "b" +"c" + "d";
System.out.println(s== "abcd");//true
6、equals ()使用时的注意事项
常量和确定值要放在equals的左边,如果把不确定的值放在左边,不确定值为null时,就会报错。
String str = null;
System.out.println(str.equals("123"));
Ⅲ、集合
1、说说Java中常用的容器有哪些?
容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。
Collection
1、Set:
-
TreeSet
基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。 但是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。
-
HashSet:
基于HashMap实现,支持快速查找,但不支持有序性操作, 并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。
-
LinkedHashSet
是 HashSet 的子类,并且其内部通过 LinkedHashMap 来实现的, 内部使用双向链表维护元素的插入顺序。
2、List:
-
ArrayList
基于动态数组实现,支持随机访问。
-
Vector
和 ArrayList 类似,但它是线程安全的。
-
LinkedList
基于双向链表实现,只能顺序访问,但是可以快速地在链表中间插入和删除元素, 不仅如此,LinkedList 还可以用作栈、队列和双向队列。
Map
- TreeMap
- HashMap
数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较
大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间 - HashTable
数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的 - LinkedHashMap
继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加
了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的
操作,实现了访问顺序相关逻辑。
3、迭代器 Iterator 是什么?
Iterator 接口提供遍历任何 Collection 的接口,可以从一个 Collection 中使用迭代器方法来获取迭代器实例。
特点是只能单向遍历,但是更加安全,因为它可以确保在当前遍历的集合元素被更改
的时候,就会抛出 ConcurrentModificationException 异常。
4、如何边遍历边移除 Collection 中的元素?
使用 Iterator.remove() 方法,如下:
Iterator<Integer> it = list.iterator();
while(it.hasNext()){