1.JDK的组成
JRE(Java Runtime Environment):Java 运行时环境
JDK 内置完整的 JRE,是运行 Java 程序的基础,包含:
JVM(Java Virtual Machine):Java 虚拟机,核心组件,负责将字节码(.class 文件)解释 / 编译为本地机器码执行,实现 “一次编写,到处运行”。
核心类库(rt.jar 等):Java 基础 API,如
java.lang(Object、String、Integer)、java.util(集合)、java.io(IO 操作)等,是编写 Java 程序的基础。
开发工具(位于 JDK 的 bin 目录下)
这是 JDK 区别于 JRE 的核心,是开发阶段的关键工具,面试需重点列举核心工具:
javac:Java 编译器,将.java源文件编译为.class字节码文件。java:Java 运行工具,启动 JVM 并执行字节码文件。
2.开发java程序的步骤
(1)编写 Java 源文件(核心编码阶段)
使用文本编辑器(Notepad++)或 IDE(IntelliJ IDEA/Eclipse)编写代码,保存为
.java后缀的源文件;
(2)编译源文件(javac 编译)
使用 JDK 自带的
javac命令(或 IDE 自动编译)将.java源文件编译为 JVM 可识别的 字节码文件(.class);
(3)运行字节码程序(java 执行)
使用 JDK 自带的
java命令(或 IDE 运行按钮)启动 JVM,加载并执行.class字节码文件;
3.二进制转换为其他进制的方法
(1)二进制转换为十进制:每一位乘以对应2的次幂数
eg: 101=> 1*2的2次幂 + 0 2的1次幂 + 1 2的0次幂 = 3
(2)二进制转换为八进制:每3位二进制作为一个单元,最小数是0,最大数是7,0-7有8个数字,
eg: 01100001--->001,100,001---->141
(3)二进制转换为十六进制:每4位二进制作为一个单元,最小数是0,最大数是15
eg: 01100001 --->0110,0001-> 61
eg: 11111010 --->1111,1010-> FA
扩展:十进制转二进制呢?答:除2取余法(逆向排列)
4.说一说java中基本类型有哪些?
(1)字节byte 占1个字节,范围:-128~127
(2)短整型short 占2个字节,范围:-3万多~3万多
(3)整型int,注意写的数字默认就是整型, 占4个字节 范围:-21亿~21亿(10位数,大概42亿左右)
(4)长整型long,8个字节,范围:19位数字,结尾要写L或l结尾,推荐L
(5)单精度浮点数(小数)float,占4个字节,结尾必须是f或F,推荐F,注意这个类型不精准,精度为8位,超过会采用科学计算法或小数点后面舍去
(6)双精度浮点数(小数)double,占8个字节,也可以不写,默认小数就是double,结尾用D或d,推荐D 精度超过17位,超过会采用小数点后面四舍五入或科学计算法
(7)char字符类型,占2个字节,0-65535
(8)boolean布尔类型,占1个字节,true或false
5.方法可以重载
介绍:一个类中,出现多个方法的名称相同,但是它们的形参列表是不同的,那么这些方法就称为方法重载了。
注意:方法重载只关注参数类型不同、类型的个数不同、类型的顺序不同,与返回值、修饰符和参数名没有关系
6.什么是强制类型转换?以及什么时候需要用到强制类型转换?
首先,Java 中的强制类型转换,简单说就是主动将一种数据类型转换成另一种指定数据类型,语法上需要用 () 把目标类型括起来,放在要转换的变量 / 值前面。
它主要用在「大范围数据类型向小范围数据类型转换」的场景(也叫「向下转型」),因为 Java 只会自动完成「小范围向大范围」的转换(自动类型转换 / 向上转型,比如 int 转 double),反过来不会自动完成,必须手动强制转换。
举个简单例子:double 类型的数值 3.14 要转换成 int 类型,就不能直接赋值,必须写 (int) 3.14,这就是强制类型转换。
7.基本数据类型的强制转换可能会出现哪些问题?
基本数据类型的强制转换,主要会出现两个核心问题:精度丢失和数据溢出。
第一个问题是「精度丢失」,主要出现在浮点型转整型的时候。因为浮点型包含小数部分,强制转换成整型后,会直接舍弃小数部分(不是四舍五入),只保留整数部分。比如 double 类型的 5.99,强制转换成 int 就是 (int) 5.99,结果是 5,小数点后面的 .99 直接丢失了,这就是精度丢失。
第二个问题是「数据溢出」,主要出现在同类型但取值范围不同的整数之间转换(比如 long 转 int)。因为小范围类型存不下大范围类型的数值,会出现数值错乱。比如 long 类型的 2147483648(这个数比 int 的最大值 2147483647 大 1),强制转换成 int 后,结果会变成 -2147483648,出现数值溢出错乱。
还有一个小细节,布尔类型(boolean)不能和任何其他基本数据类型进行强制转换,这是 Java 语法不允许的。
面试官可能的追问:如何避免整数强制转换时的溢出问题?
基础阶段可以先判断大范围数值是否在小范围类型的取值范围内,再进行转换;进阶阶段可以使用 Integer.MAX_VALUE、Integer.MIN_VALUE 这些来做判断,比如先判断 long 数值是否小于等于 Integer.MAX_VALUE 且大于等于 Integer.MIN_VALUE,再转 int
8.JVM内存分布介绍
方法区(元空间):存放类(字节码文件)信息、常量,静态变量。
栈:存放正在执行的方法以及方法中定义的变量
堆:存储new出来的内容,例如:对象、数组
本地方法栈:存放native本地方法,和C语言对接。
程序计数器:记录程序执行的位置(地址)
9.Java 中的数组是什么?它的本质是什么?
Java 数组是一种固定长度、存储相同数据类型元素的容器。
本质:数组是一个引用数据类型(对象),存储在 JVM 的「堆」中(数组变量名存储在栈中,指向堆中的数组对象)。
关键特性:
长度固定:一旦初始化完成,长度无法修改(想要动态扩容,需手动创建新数组并复制元素,如
ArrayList的底层实现)。元素类型统一:只能存储声明类型的元素(基本数据类型或引用数据类型),不能混合存储。
索引从 0 开始:通过索引快速访问元素,访问时间复杂度为 O (1)。
10.Java 数组的初始化方式有哪几种?
静态初始化:直接指定数组元素,数组长度由元素个数隐式确定,无需手动指定长度。
动态初始化:只指定数组长度,元素由 JVM 赋予默认初始值,后续可手动修改。