目录
一 JDK 和 JRE 的区分
二 简述编码的作用以及记事本的实现原理
三 基本类型有哪些?分别占据多少空间?
四 java中布尔类型的空间大小是怎么定下来的?为什么不是1bit, 把考虑因素说一下
五 int类型和float类型哪一个精度更好一些,为什么?
六 Float的内部存储原理是什么?
七 Final修饰的数组是否可以更改内部值?
八 int[]类型是不是基本类型?
九 什么是128陷阱?什么是装箱?什么是拆箱?为什么要有包装类?
十 位运算有哪几种?
十一 “>>”和”>>>”的区别是什么?,
十二 String类的常用函数有哪些?列举十种。
十三 String和StringBuffer,StringBuilder的区别有哪些?所有类名包含Buffer的类的内部实现原理是什么?有什么优势?
十四 String字符串的不可变是指哪里不可变?
十五 字符串常量池是什么?不同的JDK版本都分别位于哪个区域?
十六 Java异常类有哪些?分别管理什么异常?
十七 Java反射获取类信息的方式有哪几种?分别是什么?
十八 Java代理的主要方法有哪几种?列举代理的使用场景2个。
十九 == 和 equals 的区别是什么?
二十 重写和重载的区别是什么
二十一 子类构造方法调用父类构造方法的注意事项有哪些?
二十二 子类实例初始化是否触发发父类实例初始化?
二十三 instanceof关键字的作用是什么?
二十四 什么是 java 序列化?什么情况下需要序列化?
二十五 Java 和 C++的区别?
二十六 continue、break、和 return 的区别是什么?
二十七 static的作用是什么?详细介绍一些
二十八 反射可以获取类的哪些信息?
二十九 解释一下Java三大特性
三十 反射获取 Class 对象的方
一 JDK 和 JRE 的区分
JRE是Java运行时环境,负责将.class文件编译为操作系统可运行的文件,包括Java虚拟机(JVM)和Java类库,只能提供Java运行所需环境,不能用于编写Java应用程序。
JDK是Java开发包,可以用于编写Java程序,负责将.java文件编译为.class文件,包括Java编译器、Java虚拟机、Java类库以及其他开发工具。
二 简述编码的作用以及记事本的实现原理
编码的作用是将不同的文字信息按照编码表表示为0和1存储在计算机中,以便文本在计算机中存储并通过网络进行传递。
记事本获得由0和1构成的编码信息后,会根据指定的编码方式将编码进行解码,将所获得的坐标和RGB值形成的点阵信息映射出来,显示成为字符的形状。
三 基本类型有哪些?分别占据多少空间?
Java中的基本数据类型包括byte、short、int、long、float、double、char、boolean八种。其中byte型占8bit,short占16bit,int占32bit,long占64bit,float占32bit,double占64bit,char占8bit或16bit或32bit,根据编码方式不同而不同,boolean占32bit。
四 java中布尔类型的空间大小是怎么定下来的?为什么不是1bit, 把考虑因素说一下
布尔类型在JVM中没有专用的字节指令,只有true和false两个值,在编译后都会使用int数据类型中的1和0进行替代,因此其空间大小与int型一致。
五 int类型和float类型哪一个精度更好一些,为什么?
int的精度更好,因为在Java中int和float类型均占用4字节,但相比于int型,float类型包含了一位符号位和8位指数位,因此当数值较大时,float类型可用于表示的位数更少,精度更低,在int型数值转换成float型时会丢失精度。
六 Float的内部存储原理是什么?
首先将数值转化为二进制形式,再将其进行左移或右移操作,直至其转化成规格化形式。将小数点右边的数字依次存储到第0~22位中,多出部分则丢弃。其次再根据左移或右移的位数决定指数位的大小:若进行左移,则将其左移的位数减去1后放入23~29位,第30位为1;若进行右移,则将其右移的位数取补码放入23~29位,第30位为0。最后根据数值符号决定第31位,为正数则置0,否则置1。
七 Final修饰的数组是否可以更改内部值?
可以,final修饰引用数据类型,指的是这个引用数据类型的地址确定了,final修饰的数组首地址是放在栈中的,实际数组是放在堆中的,final表明这个指向堆的这个位置是确定的,而在堆上存储的数组的值是可以改变的。
八 int[]类型是不是基本类型?
int[]类型不是基本类型,int[]是存放int型数据的数组,属于引用类型。
九 什么是128陷阱?什么是装箱?什么是拆箱?为什么要有包装类?
128陷阱指两个-128~127范围内的Integer类型数据使用==判断时会返回true的结果。在Java中,使用==运算符比较的是两个变量的地址值是否相同,Integer类型属于引用类型,理论上尽管两个Integer类型的数据值相同,地址也会不同,使用==判定应该会返回false。而之所以会返回true,是因为在Integer的valueOf()方法中, -128-127范围内数值都存储在有一个数组中,该数组相当于一个缓存,当我们在-128-127之间进行自动装箱的时候,我们就直接返回该值在内存当中的地址,所以在-128-127之间的数值用==进行比较是相等的。而不在这个区间的数,需要新开辟一个内存空间,所以不相等。
装箱是指将基本类型封装为包装类,通常可以使用包装类的构造器实现。拆箱是指将包装类中包装的数据获取出来获得基本数据类型的变量。
Java属于面向对象的语言,而基本数据类型不属于对象,无法调用方法,数据大小也受限,因此在实际使用时,通常会使用对应基本数据类型的包装类,使变量具有类的特点,可以调用相关方法。
十 位运算有哪几种?
位运算符共7种,具体包括:&按位与,|按位或,~按位非,^按位异或,>>右位移运算符,<<左位移运算符,>>>无符号右移运算符。
十一 “>>”和”>>>”的区别是什么?,
>>是右移运算符,如果该数为正,则高位补0,若为负数,则高位补1;
>>>是无符号右移运算符,指逻辑右移,无论待位移数字的符号,右移后高位均补0。
十二 String类的常用函数有哪些?列举十种。
1)length() 获取字符串长度,返回值为int类型
2)charAt(int index) 获取指定索引位置的字符,返回值为char类型
3)indexOf(String str) 获取字符串段str在字符串中第一次出现的位置,返回值类型为int
4)contains(String str) 判断字符串中是否包括字符串段str,返回值类型为boolean
5)isEmpty() 判断字符串是否为空,返回值类型为boolean
6)equals(str) 判断两个字符串是否相等,返回值类型为boolean
7)toCharArray() 将字符串转换为字符型数组,返回值为一个存储char类型变量的数组
8)replace(oldchar,newchar) 使用newchar替代oldchar,返回新字符串,如果oldchar不存在,则返回原字符串
9)split(regex) 按照regex切割字符串,返回一个储存String类型变量的数组
10)toUpperCase()和toLowerCase() 将字符串内容转换为全部大写(或小写),返回值类型为String
十三 String和StringBuffer,StringBuilder的区别有哪些?所有类名包含Buffer的类的内部实现原理是什么?有什么优势?
String类型的数据会存放在字符串常量池中,默认为常量形式,每一个新的String变量被创建,都会先在字符串常量池中搜索是否存在该字符串,如果存在,则指向该地址,如果不存在,则在常量池创建一个新的数据。这导致了程序的执行速度非常慢,但也是线程安全最高的。
StringBuffer和StringBuilder两者并无本质不同,相比于String速度更快,区别在于StringBuffer适用于多线程环境下的操作,线程安全,但执行速度相比于StringBuilder稍慢,而StringBuilder线程不安全,适用于单线程环境。
Buffer即缓冲区,指在内存中预留出指定大小的存储空间,然后对输入/输出进行数据的临时存储,是包含一定数量数据的容器,它的本质是一个定长数组,其长度创建的时候指定。
Java中提供了7种类型的Buffer,每一种类型的Buffer根据分配内存的方式不同又可以分为直接缓冲区和非直接缓冲区。非直接缓冲区的内存分配在JVM内存当中,而直接缓冲区使用物理内存映射,直接在物理内存中分配缓冲区。
通过Buffer,CPU无需直接读取磁盘中的数据,而是首先在Buffer中初始化磁盘数据,CPU查询时,不直接请求磁盘,而是在Buffer进行,降低了运行时间。通过Buffer类,可以使得物理磁盘的读取减少,加快运行速度,同时也可以减少动态分配和回收内存的次数。
十四 String字符串的不可变是指哪里不可变?
String字符串的不可变是指String类中的value属性在栈中的引用地址不可变。在Java中String类型的字符串统一存储在字符串常量池中,使用final修饰,即字符串属于常量不可更改。每一个新的String变量被创建,都会先在字符串常量池中搜索是否存在该字符串,如果存在,则指向该地址,如果不存在,则在常量池创建一个新的数据。在我们改变变量的值时,该变量只会指向新字符串所在位置的地址,而不会改变原有地址中存放的字符串内容,保证了安全性。
十五 字符串常量池是什么?不同的JDK版本都分别位于哪个区域?
Java的字符串常量池是Java中用于存储字符串常量的一块内存区域,通过字符串常量池可以使得相同的字符串被共享使用,节省内存空间。
在JDK6.0及之前版本,字符串常量池位于方法区中,JDK7.0版本开始,字符串常量池位于堆中。
十六 Java异常类有哪些?分别管理什么异常?
Java异常类有分为检查异常和运行时异常。
检查异常指编译器要求必须处置的异常,即程序在运行时由于外界因素造成的一般性异常,具体包括:
1)java.lang.ClassNotFoundExeption:没有找到具有指定名称的类异常。
2)java.lang.FileNotFoundException:访问不存在的文件异常。
3)java.lang.IO Exception:操作文件时发生的异常。
4)java.sql.SQL Exception:操作数据库时发生的异常。
运行时异常指编译器不要求强制处置的异常,一般是指因设计或实现方式不当而导致的问题,具体包括:
1)NullPointerException: 空指针异常,一般出现于数组,空对象的变量和方法
2)ArrayIndexOutOfBoundsException: 数组越界异常
3)ArrayStoreException: 数据存储异常
4)NoClassDefFoundException: java运行时系统找不到所引用的类
5)ArithmeticException: 算数异常,一般在被除数是0中
6)ClassCastException: 类型转换异常
7)IllegalArgumentException: 非法参数异常
8)IllegalThreadStateException: 非法线程状态异常
9)NumberFormatException: 数据格式异常
10)OutOfMemoryException: 内存溢出异常
11)PatternSyntaxException: 正则异常
十七 Java反射获取类信息的方式有哪几种?分别是什么?
Java反射获取类信息的方式以下几种:
1)通过调用具体类.class属性获取;
2)通过Class.forName("类的全局定名")获取,全局定名为包名+类名;
3)通过对象的方法getClass()获取;
4)通过类加载器ClassLoader.loadClass()传入类路径获取
十八 Java代理的主要方法有哪几种?列举代理的使用场景2个。
代理的主要方法有:
1)定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类;
2)在JDK中生成代理对象的API,动态的在内存中构建代理对象;
3)在内存中构建一个子类对象,从而实现对目标对象功能的扩展
代理的使用场景很多,如不修改实际对象的情况下添加一些额外的功能或对象需要在不同的环境中进行不同的处理的情况,具体例如日志记录、性能监控、权限控制、事务管理等。
十九 == 和 equals 的区别是什么?
1)对于基本类型,==比较的是值;
2)对于引用类型,==比较的是地址;
3)equals不能用于基本类型的比较;
4)如果没有重写equals,equals就相当于==;
5)如果重写了equals方法,equals比较的是对象的内容;
二十 重写和重载的区别是什么
重写是指在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,其方法名,参数列表,返回类型均与父类相同,但方法体不同。
重载是指方法名相同,但是参数列表不同,包括参数类型不同、参数个数不同甚至是参数顺序不同,即为重载。
方法的重载和重写都是实现多态的方式,但重载实现的是编译时的多态性,而重写实现的是运行时的多态性。重载发生在同一个类中,同名的方法如果有不同的参数列表则视为重载,对返回类型没有特殊的要求;重写发生在子类与父类之间,要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,访问修饰符的限制一定要大于被重写方法的访问修饰符,不能比父类被重写方法声明更多的异常。
二十一 子类构造方法调用父类构造方法的注意事项有哪些?
1)子类无法访问父类的private字段或者private方法;2)子类的构造方法必须先调用父类的构造方法。如果没有明确的调用父类的构造方法,编译器会自动使用super()调用父类的无参构造器。但如果父类没有默认的构造方法,子类必须在首句显示地调用super()并给出参数;3)子类不会继承任何父类的构造方法,子类默认的构造方法是编译器自动生成的,不是继承的。
二十二 子类实例初始化是否触发发父类实例初始化?
子类的实例初始化触发父类实例初始化,且父类初始化顺序优先于子类。因为子类继承父类时默认含有父类的公共成员方法和公共成员变量,这些方法和变量不再重复声明。
二十三 instanceof关键字的作用是什么?
instanceof的作用是判断左边的对象是否是右边类或是它的子类的一个实例,其左边的变量通常是一个引用类型的变量,右边的变量通常是一个类或是接口,返回值为boolean类型的数据。
二十四 什么是 java 序列化?什么情况下需要序列化?
序列化就是一种用来处理对象流的机制。将对象的内容流化,将流化后的对象传输于网络之间。
序列化是通过实现serializable接口,该接口没有需要实现的方法,implement Serializable只是为了标注该对象是可被序列化的,使用一个输出流(FileOutputStream)来构造一个ObjectOutputStream对象,接着使用ObjectOutputStream对象的writeObejct(Object object)方法就可以将参数的obj对象到磁盘,需要恢复的时候使用输入流。
序列化是将对象转换为容易传输的格式的过程。
例如,可以序列化一个对象,然后通过HTTP通过Internet在客户端和服务器之间传输该对象。在另一端,反序列化将从流中心构造成对象。
一般程序在运行时,产生对象,这些对象随着程序的停止而消失,但我们想将某些对象保存下来,这时,我们就可以通过序列化将对象保存在磁盘,需要使用的时候通过反序列化获取到。
对象序列化的最主要目的就是传递和保存对象,保存对象的完整性和可传递性。
譬如通过网络传输或者把一个对象保存成本地一个文件的时候,需要使用序列化。
二十五 Java 和 C++的区别?
- 都是面向对象的语言,都支持封装、继承和多态
- Java 不提供指针来直接访问内存,程序内存更加安全
- Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
- Java 有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存
- 在 C 语言中,字符串或字符数组最后都会有一个额外的字符`'\0'`来表示结束。但是,Java 语言中没有结束符这一概念。
二十六 continue、break、和 return 的区别是什么?
在循环结构中,当循环条件不满足或者循环次数达到要求时,循环会正常结束。但是,有时候可能需要在循环的过程中,当发生了某种条件之后 ,提前终止循环,这就需要用到下面几个关键词:
1. continue :指跳出当前的这一次循环,继续下一次循环。
2. break :指跳出整个循环体,继续执行循环下面的语句。
return 用于跳出所在方法,结束该方法的运行。return 一般有两种用法:
1. `return;`:直接使用 return 结束方法执行,用于没有返回值函数的方法
2. `return value;` :return 一个特定值,用于有返回值函数的方法
二十七 static的作用是什么?详细介绍一些
1)在函数体中一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2)在模块内、函数体外,一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问,是一个本地的全局变量。
3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。
二十八 反射可以获取类的哪些信息?
反射可以获得类中的一切信息,包括注解、属性、方法、构造方法、属性类型、属性名字、属性修饰、方法类型、方法名字、入参数据、入参类型。
二十九 解释一下Java三大特性
1.封装性
封装指属性私有化,隐藏具体属性和实现细节,仅对外开放接口,控制程序中属性的访问级别,需要提供setter和getter方法来访问属性。
目的:增强安全性和简化编程,使用者不必在意具体实现细节,而只是通过外部接口即可访问类的成员。
public class Demo_2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s1 = new Student();
// 对公共属性可以直接赋值和获取
s1.name = "zhangsan";
System.out.println(s1.name);
// 对私有属性只能调用get/set方法进行访问、更改
s1.setAge(18);
s1.setNo(001);
s1.setSex("男");
System.out.println("学生的年龄是:"+s1.getAge()+",学号是:"+s1.getNo());
}
}
class Student{
String name;
private int age;
private String sex;
private int no;
// 获取和设置私有属性的方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
}
2.继承性
继承是指将多个相同的属性和方法提取出来形成一个父类。一个类只能继承一个父类,且只能继承访问权限非private的属性和方法。 子类可以重写父类中的方法。
目的:实现代码复用。
import java.util.*;
class Animals {//定义父类
public void getName() {//定义一个公共方法
System.out.println("父类");
}
}
class Dog extends Animals {//定义子类Dog,继承了父类Animals
public void getName() {
System.out.println("子类狗");
}
public void getNameA() {
this.getName();//调用本类的方法
super.getName();//调用父类的方法
}
}
class Cat extends Animals {//定义子类Cat,继承了父类Animals
public void getName() {
System.out.println("子类猫");
}
public void getNameA() {
this.getName();//调用本类的方法
super.getName();//调用父类的方法
}
}
public class Forever {
public static void main(String[] args){
Animals a=new Animals();
a.getName();
Dog b=new Dog();
b.getNameA();
Cat c=new Cat();
c.getNameA();
}
}
3.多态性
多态分为两种:设计时多态和运行时多态。 设计时多态即重载,是指Java允许方法名相同而参数不同(返回值可以相同也可以不相同)。 运行时多态即重写,是指Java运行根据调用该方法的类型决定调用哪个方法。
多态目的:增加代码的灵活度。
三十 反射获取 Class 对象的方式
Java 提供了四种方式获取 Class 对象:
1.知道具体类的情况下可以使用:
Class alunbarClass = TargetObject.class;
2.通过 Class.forName()传入类的路径获取:
Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");
3.通过对象实例instance.getClass()获取:
Employee e = new Employee();
Class alunbarClass2 = e.getClass();
4.通过类加载器xxxClassLoader.loadClass()传入类路径获取
class clazz = ClassLoader.LoadClass("cn.javaguide.TargetObject");