文章目录
- 一、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的增删操作效率更高,而查改操作效率
较低。
总结
都看到这里了,点个赞呗!
关注,持续更新
