面试题由23年8月开始记录,主要参考B站黑马程序员的视频(新版Java面试专题视频教程,java八股文面试全套真题+深度详解(含大厂高频面试真题)_哔哩哔哩_bilibili)和JavaGuide(项目介绍 | JavaGuide),并在多次面试中二次改进并增加题目。内容仅供参考,建议理解使用。
JAVA基础(没问过)
成员变量和局部变量
语法形式:从语法形式上看,成员变量是属于类的,而局部变量是在代码块或方法中定义的变量或是方法的参数;成员变量可以被 public
,private
,static
等修饰符所修饰,而局部变量不能被访问控制修饰符及 static
所修饰;但是,成员变量和局部变量都能被 final
所修饰。
存储方式:从变量在内存中的存储方式来看,如果成员变量是使用 static
修饰的,那么这个成员变量是属于类的,如果没有使用 static
修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存。
生存时间:从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡。
默认值:从变量是否有默认值来看,成员变量如果没有被赋初始值,则会自动以类型的默认值而赋值(一种情况例外:被 final
修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值。
基本类型和包装类型的区别
- 用途:除了定义一些常量和局部变量之外,我们在其他地方比如方法参数、对象属性中很少会使用基本类型来定义变量。并且,包装类型可用于泛型,而基本类型不可以。
- 存储方式:
基本数据类型
的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被static
修饰 )存放在 Java 虚拟机的堆中。包装类型
属于对象类型,我们知道几乎所有对象实例都存在于堆中。 - 占用空间:相比于包装类型(对象类型), 基本数据类型占用的空间往往非常小。
- 默认值:成员变量包装类型不赋值就是
null
,而基本类型有默认值且不是null
。 - 比较方式:对于基本数据类型来说,
==
比较的是值。对于包装数据类型来说,==
比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用equals()
方法
静态方法和实例方法有何不同?
1、调用方式
在外部调用静态方法时,可以使用 类名.方法名
的方式,也可以使用 对象.方法名
的方式,而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象 。
不过,需要注意的是一般不建议使用 对象.方法名
的方式来调用静态方法。这种方式非常容易造成混淆,静态方法不属于类的某个对象而是属于这个类。
因此,一般建议使用 类名.方法名
的方式来调用静态方法。
public class Person {
public void method() {
//......
}
public static void staicMethod(){
//......
}
public static void main(String[] args) {
Person person = new Person();
// 调用实例方法
person.method();
// 调用静态方法
Person.staicMethod()
}
}
2、访问类成员是否存在限制
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),不允许访问实例成员(即实例成员变量和实例方法),而实例方法不存在这个限制
Java多态
- 父类引用变量可以指向子类对象
Java泛型
- 限定传入的泛型参数
- 泛型类、泛型接口、泛型方法
- 泛型擦除、通配符
Java为什么不支持多继承?
- 避免多个父类中的同一方法出现错误引用
Java实现多继承会有什么问题呢?
- 引用复杂
接口和抽象类有什么区别呢?
- implement extends
- 接口可以多实现,抽象类不可以多继承
- 接口 is like a ,抽象类 is a
接口成员
变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类
中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
String为什么要把他设计成不可变?
- 为了安全(更多请见String 为什么是不可变的?)
创建对象的方式?
- 构造器new
- 克隆
- 反射
- 序列化
String s=new String("xyz") 涉及到几个对象(String s1 = new String("abc");这句话创建了几个字符串对象?)
-
String s=new String("xyz") 在运行时涉及到几个对象
- 2
-
String s=new String("xyz") 在类加载时涉及到几个对象
- 1
-
String s=new String("java") 在运行时涉及到几个对象
- 1
- 在sun.misc.Version#launcher_name中加载了java
异常类
-
Exception
- Checked Exception
- Unchecked Exception
-
Error
自定义异常类
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = 2359767895161832954L;
private final IResultCode resultCode;
public ServiceException(String message) {
super(message);
this.resultCode = ResultCode.FAILURE;
}
public ServiceException(IResultCode resultCode) {
super(resultCode.getMessage());
this.resultCode = resultCode;
}
public ServiceException(IResultCode resultCode, Throwable cause) {
super(cause);
this.resultCode = resultCode;
}
public Throwable fillInStackTrace() {
return this;
}
public Throwable doFillInStackTrace() {
return super.fillInStackTrace();
}
public IResultCode getResultCode() {
return this.resultCode;
}
}
Java集合(问的频率较高,多为list和map)
数据结构 - 数组
为什么数组索引从0开始呢?假如从1开始不行吗?
ArrayList底层的实现原理是什么
ArrayList list = new ArrayList(10)的list扩容几次
如何实现数组和List之间的转换
此处参考Kimi.AI
数组转换为List
-
使用Arrays类的asList方法:
String[] array = {"a", "b", "c"}; List<String> list = Arrays.asList(array);
注意,使用
Arrays.asList
创建的List是固定大小的,不能添加或删除元素。 -
使用Collections类中的addAll方法:
List<String> list = new ArrayList<>(); String[] array = {"a", "b", "c"}; Collections.addAll(list, array);
-
使用Java 8的Stream API:
String[] array = {"a", "b", "c"}; List<String> list = Arrays.stream(array).collect(Collectors.toList());
List转换为数组
-
使用List的toArray方法:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); String[] array = list.toArray(new String[0]);
注意,需要提供一个数组实例来接收转换后的元素。
-
使用Arrays类的copyOf方法:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); String[] array = Arrays.copyOf(list.toArray(), list.size(), String[].class);
-
使用Java 8的Stream API:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); String[] array = list.stream().toArray(String[]::new);
这些方法可以根据你的具体需求来选择使用。如果你需要一个可修改的List,建议使用Collections.addAll
或Stream API。如果你需要一个固定大小的List,可以使用Arrays.asList
。在将List转换为数组时,确保提供正确的数组类型和大小。
ArrayList和LinkedList的区别是什么?
本质上是链表和数组的区别,建议理解后回答,可参考ArrayList 与 LinkedList 区别?
List和Set互相转换的问题
- Set转List会乱序
- List转Set会丢失数据
HashMap
此处红黑树只作了解即可,初级面试暂未问到
![]()
![]()
说一下HaspMap的实现原理(建议理解后背诵,基本都问)
亦可参考HashMap 的底层实现
HashMap的put方法的具体流程
讲讲HashMap的扩容机制
hashMap的寻址算法(没问过)
haspMap在1.7情况下的多线程死循环问题
未完待续,有空继续