Java校招面试汇总

Java校招面试汇总

一、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的区别

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区别

  1. 数据可变

    String 底层使用一个不可变的字符数组 private final char value[];
    StringBuffer 和 StringBuilder 都继承了 AbstractStringBuilder,
    底层使用的是可变字符数组: char[] value;
    
  2. 线程安全

    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()){
   
		
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值