1.1 Java 语言有哪些特点?
- 简单易学;2. 面向对象(封装,继承,多态);3. 平台无关性( Java 虚拟机实现平台无关性);4. 可靠性;5. 安全性;6. 支持多线程;7. 支持网络编程并且很方便;8. 编译与解释并存;
1.2 关于 JVM JDK 和 JRE 最详细通俗的解答
1.2.1 JVM
java虚拟机(JVM)是运行Java字节码的虚拟机,能识别不同平台的字节码
什么是字节码?在 Java 中,采用字节码的好处是什么?
在Java中,能被JVM识别的代码就是字节码,它不面向任何特定的处理器,只面向虚拟机。由于字节码不针对特定的机器,所以Java程序无需重新编译即可在不同的操作系统上运行。
Java 程序从源代码到运行一般有下面 3 步:
后面引进了JIT编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。所以 Java 是编译与解释共存的语言。
1.2.2 JDK 和 JRE
JDK: 它拥有 JRE 所拥有的一切,还有编译器
(javac)和工具(如 javadoc 和 jdb)。它能够创建和编译程序。
JRE:Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,java 命令和其他的一些基础构件。但是,它不能用于创建新程序。
1.3 Java 和 C++的区别
1.Java不支持指针直接访问内存。
2.Java是单继承,C++是多重继承。
3.Java有自动内存管理机制,无需手动释放无用内存。
4.C语言中,字符串和字符数组最后都有结束符‘\0’。
1.4 字符型常量和字符串常量的区别?
字符型常量由‘’引起,相当于一个整型值(ASCLL值),大小为2字节。
字符串常量由“”引起,代表该字符串在内存中存放的位置,大小为若干字节。
1.5标识符和关键字的区别是什么?
关键字是特殊的标识符,Java已经赋予了其特殊的含义,标识符必须以字母、数字、下划线组成;不能以数字开头。不能包含空格、美元符。
1.6 自增自减运算符
++在前先自增,再赋值;++在后先赋值,再自增。
例如,当“b=++a”时,先自增(自己增加1),再赋值(赋值给 b);当“b=a++”时,先赋值(赋值给 b),再自增(自己增加 1)。也
1.7 continue、break、和return的区别是什么?
- continue :指跳出当前的这一次循环,继续下一次循环。
- break :指跳出整个循环体,继续执行循环下面的语句。
return 用于跳出所在方法,结束该方法的运行。return 一般有两种用法: - return; :直接使用 return 结束方法执行,用于没有返回值函数的方法。
- return value; :return 一个特定值,用于有返回值函数的方法。
1.8 泛型了解么?什么是类型擦除?介绍一下常用的通配符?
Java 泛型(generics)泛型提供了编译时类型安全检测机制,该机制允许编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
Java的泛型是伪泛型,因为Java在编译期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除 。
泛型一般有三种使用方式:泛型类、泛型接口、泛型方法。
1.泛型类:
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{
private T key;
public Generic(T key) {
this.key = key; }
public T getKey(){
return key;
}
}
如何实例化泛型类:
Generic<Integer> genericInteger = new Generic<Integer>(123456);
2.泛型接口 :
public interface Generator<T> {
public T method();
}
实现泛型接口,不指定类型:
class GeneratorImpl<T> implements Generator<T>{
@Override
public T method() {
return null; }
}
实现泛型接口,指定类型:
class GeneratorImpl<T> implements Generator<String>{
@Override
public String method() {
return "hello"; }
}
3.泛型方法 :
public static < E > void printArray( E[] inputArray ) {
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}
使用:
//创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3 };
String[] stringArray = { "Hello", "World" };
printArray( intArray );
printArray( stringArray );
常用的通配符为: T,E,K,V,?
? 表示不确定的 java 类型
T (type) 表示具体的一个java类型
K V (key value) 分别代表java键值中的Key Value
E (element) 代表Element
1.9 ==和equals的区别
==:基本数据类型比较的是对象的值;引用数据类型比较对象的内存地址。
equals() 方法存在两种使用情况:
情况 1:类没有覆盖 equals() 方法。比较的是对象的内存地址。默认使用 Object 类 equals() 方法。
情况 2:类覆盖了 equals() 方法。比较两个对象的内容是否相等;
说明:
String 中的 equals 方法是被重写过的,因为 Object 的 equals 方法是比较的对象的内存地
址,而 String 的 equals 方法比较的是对象的值。
1.9.1 hashCode()与 equals()
hashCode()介绍
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
为什么要有 hashCode
我们以“ HashSet 如何检查重复”为例子来说明为什么要有 hashCode?
当对象加入 HashSet 时, HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用equals() 来判断是否真的相同。相同则不会插入成功。也就是说 hashcode 只是用来缩小查找成本。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
为什么重写 equals 时必须重写 hashCode 方法?
如果两个对象相等,则 hashcode 一定也是相同的。两个对象相等,对两个对象分别调用 equals 方法都返回 true。但是,两个对象有相同的 hashcode 值,它们也不一定是相等的 。因此,equals 方法被覆 盖过,则 hashCode 方法也必须被覆盖。
为什么两个对象有相同的 hashcode 值,它们也不一定是相等的?
因为 hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。
2.1 基本数据类型
2.1.1 自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;
2.1.2 8种基本类型的包装类和常量池
Java 基本类型的包装类的大部分都实现了常量池技术,即
Byte,Short,Integer,Long,Character,Boolean;前面 4 种包装类默认创建了数值[-128,127] 的相应类型的缓存数据,Character创建了数值在[0,127]范围的缓存数据,Boolean 直接返回True OrFalse。如果超出对应范围仍然会去创建新的对象。
2.2 方法(函数)
2.2.1 什么是方法的返回值?返回值在类的方法里的作用是什么?
方法的返回值是指接收某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。使得它可以用于其他的操作!
2.2.2 为什么 Java 中只有值传递?
Java 采用按值调用。也就是说,方法得到的是参数值的一个拷贝,不能修改传递给它的任何参数变量的内容。
2.2.3 重载和重写的区别
重载(编译期):同名不同参数,根据不同的传参来执行不同的逻辑处理。
重写(运行期):子类对父类方法的重新改造,外部样子不能改变,内部逻辑可以改变
2.3 深拷贝 vs 浅拷贝
浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。