文章目录
- 一、JVM、JRE及JDK的关系
- 二、JAVA语言特点
- 三、JAVA和C++的区别
- 四、Java的基本数据类型
- 五、隐式(自动)类型转换和显示(强制)类型转换
- 六、Java的自动装箱与拆箱
- 七、Java中的string的不可改变性
- 八、Java中的String类的常用方法都有那些
- 九、Java中的String和StringBuffer、StringBulider的区别是什么?
- 十、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上
- 十一、Java中的final、finally、finalize区别
- 十二、面向对象的三大特性(封装、继承、多态)
- 十三、Java程序的执行过程
- 十四、除了Java和javac以外,你还接触过那些工具?
- 十五、Java的gc机制
- 十六、==和equals的区别
- 十七、为什么重写equals方法要重写hashcode
- 十八、深拷贝和浅拷贝
- 十九、Java中的this和super的区别
- 二十、LikedList和ArrayList有什么区别
- 总结
一、JVM、JRE及JDK的关系
JDK(Java development kit)是针对java开发员的产品,是整个Java的核心,包括了Java的运行环境JRE、Java工具和Java基础类库。
JRE(Java runtime environment)是运行Java程序所必须的环境的集合,包括JVM标准实现及Java核心类库。
JVM(Java Virtual machine)是Java虚拟机的缩写,是整个Java实现跨平台的最核心的部分,能够运行Java语言写作的软件程序。
直白的说,就是jdk是Java的开发工具,jre是开发程序运行所需要的环境,JVM是Java虚拟机,他们之间的关系是jdk包含jre和jvm,jre包含jvm。
二、JAVA语言特点
- Java是一种面向对象的语言
- Java通过Java虚拟机实现了平台无关性,一次编译,到处运行
- 支持多线程
- 支持网络编程
- 具有较高的安全性和可靠性
三、JAVA和C++的区别
面试时记住前面四个就行
- Java通过虚拟机从而实现跨平台特性,但是C++依赖于特定的平台。
- Java没有指针,它的引用可以理解为安全指针,而C++具有和C一样的指针。
- Java支持自动垃圾回收,而C++需要手动回收。
- Java不支持多重继承,只能通过实现多个接口来达到相同目的,而C++支持多重继承。
- Java不支持操作符重载,虽然可以对两个string对象通过执行加法运算,但是这是语言内置支持的操作,不属于操作符重载,而C++可以。
- Java的goto是保留字,但是不可用,C++可以使用goto。
四、Java的基本数据类型
注意String不是Java的基本数据类型,易混淆
类型 | 关键字 | 包装器类型 | 占用内存(字节) (重要) | 取值范围 | 默认值 |
---|---|---|---|---|---|
字节型 | byte | Byte | 1 | -128(-2^7) ~ 127(2^7-1) | 0 |
短整型 | short | Short | 2 | -2^15 ~ 2^15-1 | 0 |
整型 | int | Integer | 4 | -2^31 ~ 2^31-1 | 0 |
长整型 | long | Long | 8 | -2^63 ~ 2^63-1 | 0L |
单精度浮点型 | float | Float | 4 | 3.4e-45 ~ 1.4e38 | 0.0F |
双精度浮点型 | double | Double | 8 | 4.9e-324 ~ 1.8e308 | 0.0D |
字符型 | char | Character | 2 | ‘\u0000’ | |
布尔型 | boolean | Boolean | 1 | true/flase | flase |
五、隐式(自动)类型转换和显示(强制)类型转换
-
隐式类型转换(自动):从存储范围小的类型到存储范围大的类型。
byte→short(char)→int→long→float→double
-
显示类型转换(强制):从存储范围大的类型到存储范围小的类型。
double→float→long→int→short(char)→byte
该类类型转换很可能存在精度的损失
例如:
short s =1;
s = s + 1;
运行报错,原因:这里的1
是int
型,s+1
会自动转换成int
型,将int
型直接赋值给short
型会报错。
修改(自动进行强制转换):
short s =1;
s += 1;
或
short s = 1; s = (short)(s + 1);
六、Java的自动装箱与拆箱
Java的自动装箱:将基本类型用包装器类型包装起来
Java的自动拆箱:将包装器类型转换成基本类型
1、下程序的运行结果
public class Main {
public static void main(String[] args) {
Long l1 = 128L;
Long l2 = 128L;
System.out.print(l1 == l2); //1
System.out.print(l1 == 128L); //2
Long l3 = 127L;
Long l4 = 127L;
System.out.print(l3 == l4); //3
System.out.print(l3 == 127L); //
}
}
运行结果:
false
true
true
true
分析:
对于注释1的语句,Long包装类型常量cache为-128到127
之间,所以l1和l2
变量是两个对象,== 比较的是对象的地址
,所以打印为false。
对于注释2的语句,由于包装类型在表达式中且表达式中至少有一个不是包
装类型,所以Longl1==128L中l1自动拆箱退化为基本类型比较
,所以数值
比较为true。
对于注释3的语句,Long包装类型-128到127
之间的值维护在一个常量池
中,所以l3和l4引用同一个对象,故打印true。
对于注释4的语句类似注释2语句,所以打印为true。
2、java是否存在使得语句i>j||i<=j结果为false的i、j值?(没机会见到应该。太恶心了)
Double a = Double.NaN;
Double b = Double.NaN;
System.out.println(a>b||a<=b)
分析:
java中的NaN代表 Not A Nubmer 一个不是数字的数字 (这个题想吐,巨
恶心)。
3、java1.5的自动装箱拆箱机制是编译特性还是虚拟机运行时特性?分 别是怎么实现的?
java1.5
开始的自动装箱拆箱机制其实是编译时自动完成替换的,装箱阶段
自动替换为了valueOf
方法,拆箱阶段自动替换为了xxxValue
方法。
对于Integer、Short、Byte、Character、Long
类型的valueOf
方法,参数
如果是-128~127
之间的值会直接返回内部缓存池中已经存在对象的引用,
参数是其他范围值则返回新建对象;
而Double、Float
类型与Integer
类型类似,一样会调用Double、Float
的
valueOf
方法,但是不管传入的参数值是多少都会new
一个对象来表达该数
值,因为在某个范围内的整型数值的个数是有限的,而浮点数却不是。
4、java语句Integer i=1;i+=1;做了哪些事情?
首先 Integer i = 1; 做了自动装箱(使用 Integer.valueOf() 方法将 int 装箱
为 Integer 类型),接着 i += 1; 先将 Integer 类型的 i 自动拆箱成 int(使
用Integer.intValue() 方法将 Integer 拆箱为 int),完成加法运行之后的 i
再装箱成 Integer 类型。
5、问:下面程序的运行结果是什么?
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
注意:new Integer(xxx)这种创建对象的方法不是自动装箱,没有用到
cache,因此i1 == i2是false。
6、谈谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别。
1)第一种方式不会触发自动装箱的过程;而第二种方式会触发。
2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在
一般性情况下要优于第一种情况(注意这并不是绝对的),因为会用到
cache
七、Java中的string的不可改变性
在Java 8 中,string
内部使用char
数组存储数据,并且被声明为final
,因此它的不可被继承。
public final class String implements java.io.Serializable, Comparable, CharSequence {
private final char value[];
}
不可变性的好处:
1.可以缓存hash值
因为String
的hash
值经常被使用,例如String
用作HashMap
的key
。不可变得特性可以使得hash
值变得不可变,因此只需要进行一次计算。
2.常量池优化
String
对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的作用。
3.线程安全
String
不可变性天生具备线程安全,可以在多个线程中安全使用。
八、Java中的String类的常用方法都有那些
length()
:返回字符串的长度charAt()
:返回指定索引处的字符substring()
:截取字符串trim()
:去除字符串两端空白split()
:分割字符串,返回一个分割后的字符串数组replace()
:字符串替换indexOf()
:返回指定的字符索引toLowerCase()
:将字符串转换成小写字符toUpperCase()
:将字符串转成大写字符
九、Java中的String和StringBuffer、StringBulider的区别是什么?
如图所示:
可变性 | 线程安全性 | 性能 | |
---|---|---|---|
String | 不可变 | 安全 | 低 |
StringBuffer | 可变 | 不安全 | 高 |
StringBulider | 可变 | 安全 | 较高 |
十、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上
switch
可以作用在char
byte
short
int
及它们对应的包装类型,switch
不可以作用于long
double
float
boolean
及它们的包装类型。在jdk1.5
之后可以作用于枚举
类型,在jdk1.7
之后可以作用于String
类型。
十一、Java中的final、finally、finalize区别
final
主要用于修饰类、变量和方法finally
一般作用在finally
代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally
中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。finalize
是一个属于object类
的一个方法,该方法一般由 垃圾回收器来调用,当我们调用System.gc()
方法的时候,由垃圾回收器调用finalize()
,回收垃圾,但Java语言规范并不保证inalize
方法会被及时的执行,而根本不会保证它们会被执行。
十二、面向对象的三大特性(封装、继承、多态)
1.封装
封装就是将一个对象内部的属性
封装起来,对外提供公共的方法进行访问
和修改
封装的意义:
1.保证对象内部的安全性,属性不能随意修改
2.可以在修改和访问属性的时候,做额外的操作
public void setxxx(int age){
this.age = age;
sout("年龄修改为了:xxx");
}
2.继承
对现实生活中的父子关系进行了抽象化
在子类对象里面开辟一个父类空间,用来保存父类的相关信息
如果要使用某个成员变量或成员方法的时候,先去子类对象中找有没有,然后才去父类空间中找。
this -> 当前对象
super -> 父类空间
3.多态
一个东西的不同表现方式
运行时多态:
父类引用指向子类对象 向上转型
Fu fu = new Zi()
需要满足的条件
1.继承
2.子类重写父类方法
3.父类引用指向子类对象
多态的意义
1.可扩展性
因为一个接口/类可能有很多的实现类/子类,使用多态的话就避免使用子类的特有的方法,当需要切换一个实现类/子类使用的时候,避免修改以前的代码
2.灵活性
十三、Java程序的执行过程
.java -> java.exe -> .class -> jvm运行
编译 -> 编写 -> 编译 -> 运行
十四、除了Java和javac以外,你还接触过那些工具?
1.jar.exe
把javase项目打包成jar包 web项目打包成war包,部署一个web项目,直接把war包放在webapps这个文件下面
2.Javadoc.exe
如果我的项目按照Javadoc的标准来编写注释的话,javadoc就会自动帮你生成api文档
api文档很重要!后端提供数据 前端调用后端接口来访问数据,中间通过json进行数据交换
3.javap.exe
.class文件反编译 .class文件交给jvm运行的时候,会变成一条条的指令进行执行。
十五、Java的gc机制
1.垃圾的意义
没有引用指向的对象。
2.什么时候触发gc?
jvm内存满了就触发,没满就不会触发。
3.gc机制会调用什么?
Object超类的一个方法finalize()
4.jvisualvm.exe
监视JVM的运行情况,从而发现gc,堆内存存在的问题。
十六、==和equals的区别
==
对于基本数据类型,==
比较的是值;对于引用类型,==
比较的是内存地址。
equals
对于重写equals
方法的类,equals
方法和==
作用类似;对于重写过equals
方法的类,equals
比较的是值。
十七、为什么重写equals方法要重写hashcode
1.因为如果不重写hashcode可能会出现两个相等的对象,有不一样的hash值。
2.如果不重写的话,hashmap不可用。
十八、深拷贝和浅拷贝
浅拷贝:复制出来的对象在新的地址里,但是里面的引用数据类型和以前的对象一样。
深拷贝:复制出来的对象和以前的对象没有任何关系。
十九、Java中的this和super的区别
- 不同点:
super()
主要是对父类构造函数的调用,this()
是对重载构造函数的调用super()
主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;this()
主要是在同一类的不同构造函数中的使用 - 相同点:
super()
和this()
都必须在构造函数的第一行进行调用,否则就是错误的this()
和super()
都指的是对象,所以,均不可以在static
环境中使用。
this()和super()为什么必须写在第一行?
因为:super()不写在第一行的话,相当于子类都开始执行方法了,父类空间还没生成
二十、LikedList和ArrayList有什么区别
- 底层实现不同: LinkedList是双向循环链表,ArrayList是动态数组
- 与ArrayList相比,LinkedList的增删操作效率更高,而查改操作效率
较低。
总结
都看到这里了,点个赞呗!
关注,持续更新