Java 基础查漏补缺

1.深入解读:JDK与JRE的区别

JDK 提供了完整的Java开发工具和资源,包括编译器、调试器和其他开发工具,满足开发人员的各种需求。
JRE 则相对更为基础,它只提供了Java程序运行所需的环境,包含了Java虚拟机(JVM)和Java核心类库,不包含开发工具。在部署Java应用程序时,只需要安装JRE来运行程序即可。

JDK< JRE , 开发工具 >

JRE< JVM , 核心类库 >

2.Java 中 boolean 占多少字节?

《Java 虚拟机规范》提议:

如果 boolean 是 "单独使用":boolean 被编译为 int 类型,占 4 个字节

如果boolean 是以 "boolean 数组" 的形式使用:boolean 占 1 个字节 ,Java 虚拟机直接支持 boolean 数组,通过 newarray 指令创建 boolean 数组,然后通过 byte 数组指令 baload 和 bastore 来访问和修改 boolean 数组。
但是,具体占用大小仍然取决于每个虚拟机的具体实现是否按照规范来
其他基本数据类型占用字节数

char:2B;

byte-short-int- long:1-2-4-8B;

float-double:4-8B

3.用最有效率的方法计算 2 乘以 8

2 << 3位运算,数字的二进制位左移三位相当于乘以 2 的三次方。

4.为什么重写equals时必须重写hashcode方法

Object 的 hashcode 方法是本地方法,该方法直接返回对象的内存地址。如果没有重写hashCode(),则任何对象的hashCode()值都不相等。如果只重写equals没有重写hashCode(),就会导致相同的key值也被hashcode认为是不同的key值

5.为什么Java字符串是不可变的?有什么好处?

String 类被 final 关键字修饰,这就意味着没有子类可以重写它的方法。

String 类内部使用一个私有的字符数组来存储字符串数据。这个字符数组在创建字符串时被初始化,之后不允许被改变。
好处

-保证 String 对象的安全性 ,避免被篡改;

-保证哈希值不会频繁变更。以哈希表的键值来说,经常变更的话,哈希表的性能 会下降。在 String 类中,哈希值是在第一次计算时缓存的,后续对该哈希值的请求将直接使用缓存值;

-实现字符串常量池,Java 会将相同内容的字符串存储在字符串常量池中。这样,具有相同内容的字符串变量可以指向同一个 String 对象,节省内存空间。

6.Integer类的缓存机制

IntegerCache: Integer 类内部中内置了 256 个 Integer 类型的缓存数据,数据范围在 -128~127 之间。超过此范围,要比较Integer对象的数值是否相等,应该使用equals方法,而不是==运算符。

.

通过 Integer.valueOf() 方法获取整数对象时,会先检查该整数是否在 IntegerCache 中,如果在,则返回缓存中的对象,否则创建一个新的对象并缓存起来。

如果使用 new Integer() 创建对象,即使值在 -128 到 127 范围内,也不会被缓存,每次都会创建新的对象。【比如new Integer(10) == new Integer(10) :false】因此,推荐使用 Integer.valueOf() 方法获取整数对象。

.

相关补充:String 转成 Integer,主要有两个方法:Integer.parseInt(String s)、Integer.valueOf(String s)

7.异常

Throwable 是 Java 语言中所有错误和异常的基类。它有两个主要的子类:ErrorException
Error 类代表那些严重的错误,这类错误通常是程序无法处理的。比如,OutOfMemoryError 表示内存不足,StackOverflowError 表示栈溢出。这些错误通常与 JVM 的运行状态有关,一旦发生,应用程序通常无法恢复。
Exception 类代表程序可以处理的异常。它分为两大类:编译时异常运行时异常
编译时异常 在编译时必须被显式处理(捕获或声明抛出),比如IOException、SQLException 等。
运行时异常在运行时抛出,通常是由程序逻辑错误导致的,如 NullPointerException、ArrayIndexOutOfBoundsException 等。
NoClassDefFoundError 和 ClassNotFoundException 有什么区别

它们都是由于系统运行时找不到要加载的类导致的,但是触发的原因不一样。
NoClassDefFoundError :当JVM在加载一个类的时候,这个类在编译时是可用的,但是在运行时找不到这个类的定义。原因可能是 jar 包缺失或者调用了初始化失败的类。
ClassNotFoundException:当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,没有在classpath中查找到指定的类。原因可能是要加载的类不存在或者类名写错了。
异常的处理主要有两种方式:抛出(throw,throws)捕获(try{} catch(){} finally{}
throw 和 throws 的区别

1)throws 关键字用于声明异常;而 throw 关键字用于显式的抛出异常。

2)throws 关键字后面跟的是异常的名字;而 throw 关键字后面跟的是异常的对象。

3)throws 关键字出现在方法签名上,而 throw 关键字出现在方法体里。

4)throws 关键字在声明异常的时候可以跟多个,用逗号隔开;而 throw 关键字每次只能抛出一个异常。
try 里的 return 先执行还是 finally 先执行?

finally 先执行。但是,在执行 finally 之前,JVM 会先将 return 的结果暂存起来,即使 finally 修改了 return 的变量值,返回值也不会改变。

8.BIO、NIO、AIO

BIO(Blocking I/O) :阻塞 I/O,基于流模型。线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少的场景。
NIO(New I/O 或 Non-blocking I/O) :非阻塞 I/O ,基于通道和缓冲区。线程在等待 I/O 时可执行其他任务,适用于连接数多但连接时间短的场景。NIO 的魅力主要体现在网络编程中,服务器可以用一个线程处理多个客户端连接,通过 Selector 监听多个 Channel 来实现多路复用 ,极大地提高了网络编程的性能。
AIO(Asynchronous I/O):异步 I/O ,引入了异步通道的概念,基于事件和回调机制。线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,适用于连接数多且连接时间长的场景。
补充:既然有了字节流,为什么还要有字符流?

其实字符流是由 Java 虚拟机将字节转换得到的,问题就在于这个过程比较耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口。

在计算机中,文本和视频都是按照字节存储的,只是如果是文本文件的话,我们可以通过字符流的形式去读取,这样更方面的我们进行直接处理。

9.序列化和反序列化

serialVersionUID 是标识类版本的唯一标识符,确保在序列化和反序列化过程中类的版本是兼容的;
Serializable 接口用于标记一个类可以被序列化;

序列化只会保存对象的状态,因此不包含静态变量

可以使用 transient 关键字修饰不想序列化的变量;

10.Java反射

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法
反射的原理:Java 程序的执行分为编译和运行两步,编译之后会生成字节码(.class)文件,JVM 进行类加载的时候,会加载字节码文件,将类型相关的所有信息加载进方法区,反射就是去获取这些信息,然后进行各种操作。

相关推荐
u0104058368 分钟前
如何在Java中实现自动化测试和集成测试
java·开发语言·集成测试
菜鸡且互啄6926 分钟前
Spring Boot Security自定义AuthenticationProvider
java·jvm·spring boot
寻找自己的自己36 分钟前
常用工具类
java
捕风捉你1 小时前
迭代器模式在金融业务中的应用及其框架实现
java·开发语言·迭代器模式
m0_571957581 小时前
Java | Leetcode Java题解之第218题天际线问题
java·leetcode·题解
一个小浪吴啊1 小时前
Java SpringBoot MongoPlus 使用MyBatisPlus的方式,优雅的操作MongoDB
java·spring boot·mongodb
InterestingFigure1 小时前
Java 使用sql查询mongodb
java·开发语言·数据库·sql·mongodb
Janebook1 小时前
Java技术栈总结:Spring框架篇
java·开发语言
香蕉你个不呐呐6351 小时前
io流 多线程
java·开发语言
肖哥弹架构1 小时前
12张图描述大厂秒杀项目的工作细节,必须收藏,面试必备
java·后端·架构