Java基础面试(必须掌握的Java基础)

语言

1. Java语言有什么特点?

简单易学

面向对象(封装、继承、多态)

平台无关性(Java虚拟机实现平台无关性)

支持多线程

编译与解释并存

Wtrie Once,Run Anywhere一次编写,随处运行

2. JVM vs JDK vs JRE

JVM是运行Java字节码的虚拟机。JVM有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,他们都会给出相同的结果

JVM并不是只有一种,只要满足JVM规范,每个公司、组织或者个人都可以开发自己的专属JVM。也就是说我们平时接触到的HopSpot VM仅仅是JVM规范的一种实现而已

JDK(Java Development kit),功能齐全的Java SDK,拥有JRE所拥有的一切,还有编译器(Javac)和工具,它能够创建和编译程序。

JRE是Java运行时环境。他是运行已编译Java程序所需的所有内容的集合,包括Java虚拟机(JVM),Java类库,Java类库,Java命令和其他的一些基础构件。但是,他不能用于创建新程序

3. 什么是字节码?采用字节码的好处是什么?

JVM可以理解的代码就叫做字节码。直观来看就是扩展名为.class结尾的文件,他不面向任何特定的处理器,只面虚拟机。Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。

4. 为什么不全部使用AOT?

AOT可以提前编译节省启动时间,可能浪费内存。AOT就是预编译。AOT 可以指 Ahead-of-Time Compilation(预编译)

5. 为什么说Java语言编译和解释并存?

首先简单解释一下编译和解释,

编译是编译器将源代码一次性编译成机器码。

解释是将源代码一句一句解释为机器码。

java既有编译型的特征又具有解释型的特征,因为Java要经过先编译,后解释俩个步骤,由Java编写的程序需要先经过编译步骤,生成字节码(.class)文件,这种字节码必须由Java解释器来执行

6. Java和C++的区别?

  1. Java不提供指针来直接访问内存,程序内存更加安全
  2. Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承
  3. Java有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存

基本语法

1. 注释有哪几种形式?

单行注释、多行注释、文档注释

2. 标识符和关键字的区别是什么?

标识符就是一个名字,用来标识类、变量、方法等,而有些标识符,Java语言以及赋予了其特殊含义,只能用于特定地方,这些特殊的标识符就是关键字。简单来说,关键字是被赋予特殊含义的标识符。

3. 自增自减运算符?

符号在前先加减,符号在后就后加减

4. continue、break和return的区别是什么?

continue:跳出当前循环,继续下一次循环

break:跳出整个循环体

return:跳出所在方法

5. 成员变量和局部变量的区别?

生存时间来看,成员变量是对象的一部分,随着对象的创建而存在,局部变量随着方法的调用而自动生成,

存储方式来看,对象存储在堆内存,局部变量存在于栈内存

6. 静态变量有什么作用?(妙)

静态变量可以被类的所有实例共享,无论一个类创造了多少个对象,他们都共享同一份静态变量。静态变量一定是static修饰的

7. 字符型常量和字符串常量的区别?

字符型常量只能包含单个字符,而字符串常量可以包含零个或多个字符。在Java中,字符型常量是基本数据类型,而字符串常量是一个对象。

8. try-catch-finally中,如果catch中return了,finally还会执行吗?

当try和catch中有return时,finall仍然会执行

9. 什么是方法的返回值?方法有哪几种类型?

方法的返回值:是指我们获取的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。返回值的作用是接收出结果,使得它可以用于其他操作,分类可以用是否有参数,是否有返回值排列组合成四种。

10. 静态方法为什么不能调用非静态成员?

静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问

11. 静态方法和实例方法有什么不同?

调用方式不同,可以用类名.方法名。也可以使用对象.方法名。实例方法只能用对象.方法名。也就是说,调用静态方法可以无需创建对象。

12. 重载和重写有什么区别?

重载就是同一个方法能够根据不同的输入参数的不同,做出不同的处理。

重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类的方法。

基本数据类型

1. Java中的几种数据类型了解吗?

6种数字类型:byte, short,int, long, float, double

1种字符类型:char

1种布尔类型:boolean

2. 基本类型和包装类型的区别?

成员变量包装类型不赋值就是null,而基本类型有默认值且不是null

包装数据类型可用于泛型,而基本类型不可以

3. 包装类型的缓存机制了解么?

Java基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。Java中的 Integer、Long、Short、Byte、Character 这几个包装类在某些情况下会使用缓存机制。这些类中的对象,当它们的值在一定的范围内时,会被缓存起来以供重用,而不是每次都创建新的对象。这个范围通常是由 -128 到 127。因此,如果你创建一个在这个范围内的整数对象,Java可能会返回一个已经存在的对象,而不是新创建一个对象。

4. 自动装箱与拆箱了解吗?原理是什么?

装箱:将基本类型用它们对应的引用类型包装起来

拆箱:将包装类型转换为基本数据类型

原理:

自动装箱和拆箱的原理都是通过Java编译器在编译时插入必要的代码来实现的。

自动装箱实际上调用了对应的 valueOf() 方法来创建包装类型的对象,而自动拆箱则调用了对应的 xxxValue() 方法来获取基本数据类型的值。

这些方法是编译器自动插入的,使得代码看起来更简洁,但实际上在底层仍然涉及到了对象的创建和转换。

5. 为什么浮点数运算的时候会有精度丢失的风险?

计算机内部使用二进制来表示浮点数,但某些十进制小数无法精确转换为有限的二进制表示,例如 0.1,在二进制中会变成一个无限循环小数。

6. 如何解决浮点数运算的精度丢失问题?

BigDecimal可以实现对浮点数的运算,不会造成精度丢失,大部分需要浮点数精确运算结果的业务场景都是通过BigDecimal来做的

7. 超过long整型的数据应该如何表示?

用BigInterger表示,其内部使用int[]数组来存储任意大小的整型数据。

面向对象

1. 面向对象和面向过程的区别?

俩者的主要区别在于解决问题的方式不同:

面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。

面向对象会先抽象出对象,然后用对象执行方法的方式解决问题。

2. 创建一个对象用什么运算符?对象实体与对象引用有何不同?

new运算符(堆内存)?对象引用指向对象实例,一个对象引用可以0或1个对象,一个对象可以有n个引用指向它

3. 对象的相等和引用相等的区别

对象的相等一般比较的是内存中存放的内容是否想等;引用相等一般比较他们引用的内存地址是否相等

4. 类的构造方法的作用是什么?

构造方法用于初始化新创建的对象的状态。在构造方法中,可以对对象的属性进行初始化操作,以确保对象在被创建时具有合适的初始值。

5. 如果一个类没有声明构造方法?该程序能正确执行吗?

可以,因为没有声明构造方法也会有默认的无参构造

6. 构造方法有哪些特点?是否可被override?

特点:名字与类名相同。没有返回值,不能用void声明构造函数,生成类的对象时自动执行,无需调用

构造方法不能被override(重写),但是可以overload(重载),所以会出现一个类中有多个构造函数的情况。

7. 面向对象的三大特征

  1. 封装:把数据和操作数据的方法放在一起,形成一个“黑盒”,对外部隐藏具体的实现细节,只暴露必要的接口。就像买一台电视,我们只需要知道如何打开和使用它,而不需要了解内部的工作原理。
  2. 继承:子类可以继承父类的属性和方法,使得代码可以重用,并且可以通过扩展父类的功能来创建新的类。就像孩子会继承父母的一些特征和基因一样。
  3. 多态:同一种操作作用于不同的对象上时,可以产生不同的行为。就像动物都能发出声音,但狗会叫“汪汪”,猫会叫“喵喵”,这就是多态的体现。

简单来说:

  • 封装:把相关的东西放在一起,不让外面的人碰。
  • 继承:子承父业,继承父类的属性和方法。
  • 多态:一种东西有多种形态,根据具体情况表现出不同的行为。

8. 接口和抽象类有什么共同点和区别?

共同点:

都不能被实例化

都可以包含抽象方法

区别:

接口主要是对类的行为进行约束,你实现了某个接口就具有了对应的行为,抽象类主要用于代码复用,强调的是所属关系

一个类只能继承一个类,但可以实现多个接口

接口中的成员变量只能是pubic static final类型的,不能被修改且必须有初始值,而抽象类的成员变量默认是default,可在子类中被重新定义,也可以被重新赋值。

9. 深拷贝和浅拷贝区别了解吗?什么是引用拷贝?

浅拷贝(Shallow Copy):

浅拷贝仅仅复制对象本身,而不会复制对象内部的引用对象。也就是说,新对象和原始对象共享相同的内部对象引用。如果原始对象中包含引用类型的成员变量,那么这些引用类型的成员变量在浅拷贝后,原始对象和拷贝对象将指向同一个引用对象。

深拷贝(Deep Copy):

深拷贝不仅复制对象本身,还会递归复制对象内部的所有引用对象,包括引用对象的所有引用对象,以此类推,直到所有引用对象都被复制。这样就会生成一个完全独立于原始对象的拷贝对象,原始对象和拷贝对象之间没有任何关联。

引用拷贝(Reference Copy):一般引用都是跟地址有关。

引用拷贝指的是将对象的引用(内存地址)复制给另一个变量,这样两个变量指向的是同一个对象。无论是修改其中一个变量的属性还是修改对象本身,另一个变量所指向的对象都会发生相应的变化。

简单理解:

浅拷贝就像是复制了一个对象的表面,内部的引用对象还是共享的。

深拷贝则是彻底复制了一个对象及其内部的所有引用对象,生成了一个全新的对象,不再共享任何引用对象。

引用拷贝就是多个变量指向同一个对象,修改其中一个会影响到其他所有指向该对象的变量。

10. 向上转型,向下转型?

父类引用指向子类实例为向上转型,子类引用指向父类实例为向下转型。

向上转型不用强转,但有类型丢失问题,向下转型要强转,但是有安全问题。

11. Java中是值传递还是引用传递,还是俩者共存

Java中传递的只有值

Java常见类

Object

1. Object类的常见方法有哪些?

getClass,clone,hashcode,equals,notify,notifyAll,wait,finalize,tostring

常用的

hashCode方法的作用是获取哈希码

equals方法的作用就是判断俩个对象是否相等(对象即内容跟)

getClass返回一个对象运行时的实例类

tostring返回该对象的字符串表示

2. ==和equals()的区别?

==对于基本类型来说,比较的是值。对于引用类型来说,==比较的是对象的内存地址

equals()不能用于判断基本数据类型的变量,只能用来判断俩个对象是否相等

3. hashCode()有什么用?

hashCode()的作用是获取哈希码(int整数),也称为散列码。这个哈希码的作用是确定该对象是否在哈希表中的索引位置,散列表存储的是键值对(K-V),他的特点是能根据键快速检索出对应的值,这其中就利用到了散列码,可以快速找到所需要的对象

4. 为什么要有hashCode?

hashCode()和equals()都是用于比较俩个对象是否相等。

实现对象的相等性比较:在 Java 中,通常需要重写 equals 方法来比较对象的相等性。而 hashCode 方法通常与 equals 方法一起使用,用于判断两个对象是否相等。如果两个对象相等,它们的哈希码也应该相等,但反之则不一定成立。

就是要绑定一起用,俩者判定都是true才能算true.

5. 为什么重写equals()时必须重写hashCode()方法?

因为俩个相等的对象的hashCode值必须相等,如果重写equals()时没有重写hashCode()方法的话可能会导致equals方法判断是相等的俩个对象,hashCode值却不相等

String

1. String、StringBuffer、StringBuilder的区别?

String适合操作少量的数据。

StringBuilder适用单线程操作字符串缓冲区下操作大量数据。

StringBuffer适用多线程操作字符串缓冲区下操作大量数据。

2. String为什么是不可变的?

String保存字符串的数组被final修饰且为私有的,并且String类没有提供修改这个字符串的方法。

String类被final修饰导致其不能被继承,进而避免了子类破坏String不可变。

3. 字符串拼接用'' + ''还是StringBuilder?

对于少量字符串拼接,可以使用 '' + '';对于大量字符串拼接,建议使用 StringBuilder。因为 + 的字符拼接方式,实际上是通过StringBuilder 调用append()方法实现的,拼接完成后调用toString得到一个String对象。

4. String#equals()和Object#equals()有何区别?

String中的equals方法是被重写过的,比较的是String字符串的值是否相等,Object的equals方法比较的是对象的内存地址。

5. 字符串常量池的作用了解吗?

字符串常量池是JVM为了提升性能和减少内存消耗针对字符串专门开辟的一块区域,主要目的是为了避免字符串的重复创建

6. String s1 = new String("abc");这句话创建了几个字符串对象?

会创建一或俩个。

  1. "abc" 字面量创建了一个字符串对象,并存储在常量池中。
  2. new String("abc") 创建了一个新的字符串对象,其值为"abc",但它存储在堆内存中。

如果abc已经实在常量池中,则只会创建一个

7. intern方法有什么作用?(保存引用)

String.intern()是一个native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为俩种情况:

如果字符串常量池中保存了对应的字符串对象的引用,就直接返回该引用。

如果字符串常量池没有保存对应字符串的引用,那就再常量池中创建一个指向该字符串对象的引用并返回。

8. String类型的变量和常量做 “+”运算时发生了什么?

使用 "+" 运算符:Java 编译器会自动优化为 StringBuilder 的形式进行字符串拼接。

无论使用哪种方式,最终都会得到一个新的 String 对象,其值为连接了输入字符串的结果。

异常

1. Java的异常体系

异常主要分error和exception俩种,都继承自throwable,error就是虚拟机异常,程序无法干预的致命错误,exception分为俩类,必须要显示处理的编译异常(e.g.FileNotFoundException)和不需要显示处理的运行时异常(e.g. NullPointException)

泛型

1. 什么是泛型?有什么作用?

Java泛型是语言新特性,使用泛型参数,可以增强代码的可读性以及稳定性。

2. 泛型的使用方式有哪几种?

泛型类、泛型接口、泛型方法。

3. 项目中用到了哪些泛型

自定义接口通用返回结果CommonResult<T> 通过参数T可具体的返回类型动态指定结果的数据类型

集合类(Collections): 我们使用了泛型来声明集合类,例如 List<T>、Map<K, V> 等。这样做可以确保集合中只能存储特定类型的对象,提高了类型安全性。

反射

1. 何谓反射?

在 Java 中,反射指的是在运行时检查、获取和操作类、对象、方法等的能力。通俗来说,就像是程序在运行时可以像查看镜子里的自己一样,看到和操作自己的结构和行为。

举个例子,假设你有一个箱子,但是你不知道里面有什么,也不知道箱子的样子,你只能在运行时去打开它、查看里面的东西,并且可以根据需要添加、删除或者修改里面的物品。

在 Java 中,通过反射,你可以在运行时获取类的信息(比如构造器、方法、字段等)、创建对象、调用方法、操作属性,而不需要在编码时硬编码这些信息。这样就使得程序更加灵活,可以适应各种不同的情况和需求。

2. 反射的优缺点?

反射可以让我们的代码更加灵活,为各种框架提供开箱即用的功能提供了便利

不过,反射让我们在运行时有了分析操作类的能力的同时,也增加了安全问题,比如可以无视泛型参数的安全检查。另外,反射的性能也要稍差点。

3. 反射的应用场景?

  1. 框架和库的实现:很多框架和库(如Spring框架)使用反射来实现依赖注入、AOP等功能,以提高程序的灵活性和可扩展性。
  2. 配置文件解析:通过反射可以动态地将配置文件中的属性映射到Java对象的字段上,从而实现配置文件的解析和加载。(Mapper层)
  3. 序列化和反序列化:一些序列化框架(如Jackson、Gson等)使用反射来动态地将Java对象转换成JSON或者XML格式,以及反之。(Swagger文档化)
  4. 注解处理器:一些注解处理器(如Lombok)使用反射来解析注解,并根据注解生成相应的代码。

4. 动态代理的几种方式(俩种,JDK,CGLIB)?

俩种,分别是JDK动态代理机制和CGLIB动态代理机制。JDK动态代理只能代理实现了接口的类或者直接代理接口,而CGLIB可以代理未实现任何接口的类。大部分情况下都是JDK动态代理更优秀。

5. 何谓注解?

在Java中,注解(Annotation)可以看作一种特殊的注释,主要用于修饰类、方法或者变量。注解以@符号开头,可以被应用于类、方法、字段等元素上,以实现不同的功能。

简而言之,注解就是一种用来给程序添加额外信息或者配置的工具,它可以在编译时、运行时或者在开发工具中被读取和处理,帮助程序实现更多的功能和特性。

6. 注解的解析方法有哪几种?

注解只有被解析之后才会生效,常见的解析方法有俩种:编译期直接扫描,运行期通过反射处理:

简而言之,编译期直接扫描是在编译时就处理注解,而运行期通过反射处理是在程序运行时通过反射来处理注解。

SPI

1. 何谓SPI?

Service Provider Interface(服务者提供的接口),我的理解是专门提供给服务提供者或者扩展框架功能的开发者去使用的一个接口

2. SPI和API有什么区别?

API(应用程序编程接口)

简而言之,API是一种规范和约定,定义了软件组件之间的交互方式,而SPI则是一种设计模式,允许通过插件的方式扩展和定制软件的功能

3. SPI的优缺点?

通过SPI机制能够大大地提高接口设计地灵活性,但是SPI机制也存在一些缺点。需要遍历加载所有地实现类,不能做到按需加载,降低地效率

IO

BIO/NIO/AIO有什么区别?

  1. BIO(Blocking IO):同步阻塞IO
    • 当程序向IO请求数据时,程序会被阻塞,直到数据准备就绪或者IO操作完成才能继续执行。
    • 这意味着当程序等待IO操作完成时,它无法执行其他任务,会造成程序的资源浪费和效率低下。
  1. NIO(New IO):同步非阻塞IO
    • NIO引入了通道(Channel)和缓冲区(Buffer)的概念,可以在单个线程中处理多个IO操作。
    • 当程序向IO请求数据时,程序不会被阻塞,而是立即返回,可以继续执行其他任务。程序需要通过轮询的方式来检查IO操作的就绪状态。
  1. AIO(Asynchronous IO):异步非阻塞IO
    • AIO是Java NIO的进一步增强,它提供了真正的异步IO操作。
    • 当程序向IO请求数据时,程序可以立即返回,并且会在数据准备就绪后通知程序,而不需要程序主动轮询IO操作的状态。
    • 这意味着程序可以继续执行其他任务,而不需要等待IO操作完成。

简而言之:

  • BIO是典型的阻塞式IO,需要等待IO操作完成后才能继续执行。
  • NIO是同步非阻塞IO,可以在等待IO操作完成的同时执行其他任务。
  • AIO是真正的异步非阻塞IO,可以在IO操作完成后通知程序,而不需要程序主动等待。
  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值