一、Java基础
1、JDK 和 JRE 有什么区别?
JDK是面向开发人员,是java的开发工具包,包含各种类库和工具。提供了Java的开发环境和运行环境。
JRE是面向程序员使用,核心内容就是JVM及核心类库。
参考连接:https://blog.csdn.net/qq_39975542/article/details/81415225
2、== 和 equals 的区别是什么?
equals()是Object中的方法。== : 是操作符。
equals() 用来检测两个对象是否相等 ;== 用于比较引用和基本数据类型具有不同的功能.
运行角度上,equals() 运行速度比 == 慢,因为 == 只是比较引用。
equals():
自反性:对任意引用值X,x.equals(x)的返回值一定为true
对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true
传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
非空性:任何非空的引用值X,x.equals(null)的返回值一定为false
== :
比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
比较的是操作符两端的操作数是否是同一个对象。
源码展示:
//Object:
public boolean equals(Object obj) {
return (this == obj);
}
//Integer:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
//Long
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
//String:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
关于基本类型 == 的比较:
没有指明变量的类型,默认是double型,一些运算会自动转型,这是面试常考的。
public static void main(String[] args) {
System.out.println(1.0 == 1); //true
System.out.println(0.1 == 0.1); //true
System.out.println(1/10 == 0.1); //false
System.out.println(1/10 == 0); //true
System.out.println(2/10 == 0.2); //false
System.out.println(3/10 == 0.3); //false
System.out.println(0.1 + 0.2 == 0.3); //false
System.out.println(1 + 2 == 3); //true
System.out.println(2 - 1.1f == 0.9); //false
System.out.println(0.3f == 0.3); //false
System.out.println(getType(0.3f)); //class java.lang.Float
System.out.println(getType(0.3)); //class java.lang.Double
System.out.println(0.3f == 0.3F); //true
System.out.println(1 * 0.2 == 0.2); //true
System.out.println(1 + 0.2 == 1.2); //true
System.out.println(0.1 * 2 == 0.2); //true
System.out.println(0.1 / 10 == 0.01); //true
}
public static String getType(Object o) {
return o.getClass().toString();
}
3、两个对象的 hashCode()相同,则 equals()也一定为 true吗?
不一定.
类hashCode(), equals()都可以重写,返回值完全在于自己定义。hashCode()返回该对象的哈希码值;equals()返回两个对象是否相等。
一般规则:
a、两个对象用equals()比较返回true,那么两个对象的hashCode()方法必须返回相同的结果。
b、两个对象用equals()比较返回false,不要求hashCode()方法也一定返回不同的值,但是最好返回不同值,以提高哈希表性能。
c、重写equals()方法,必须重写hashCode()方法,以保证equals方法相等时两个对象hashcode返回相同的值。
4、Math库中方法
System.out.println(Math.round(-11.5)); //-11
package JavaBase;
public class MathTest {
public static void main(String[] args) {
//round: 四舍五入,float 返回int, double返回long
System.out.println(Math.round(11.2)); //11
System.out.println(Math.round(11.6)); //12
System.out.println(Math.round(-11.2)); //-11
System.out.println(Math.round(-11.6d)); //-12
System.out.println();
//rint: 四舍五入,返回double值 注意:5的时候取偶数
System.out.println(Math.rint(10.1)); //10.0
System.out.println(Math.rint(-10.1)); //-10.0
System.out.println(Math.rint(-10.95)); //-11.0
System.out.println(Math.rint(11.5)); //12.0
System.out.println(Math.rint(-11.5)); //-12.0
System.out.println(Math.rint(10.5)); //10.0
System.out.println(Math.rint(-10.5)); //-10.0
System.out.println();
//floor: 返回小的值
System.out.println(Math.floor(12.5)); //12.0
System.out.println(Math.floor(11.5)); //11.0
System.out.println(Math.floor(-12.5)); //-13.0
System.out.println(Math.floor(-11.5)); //-12.0
System.out.println(Math.floor(12.01)); //12.0
System.out.println(Math.floor(-11.25)); //-12.0
System.out.println();
//ceil: 返回大的数
System.out.println(Math.ceil(12.5)); //13.0
System.out.println(Math.ceil(11.5)); //12.0
System.out.println(Math.ceil(-12.5)); //-12.0
System.out.println(Math.ceil(-11.5)); //-11.0
System.out.println(Math.ceil(12.01)); //13.0
System.out.println(Math.ceil(-11.25)); //-12.0
System.out.println();
//abs:求绝对值
System.out.println(Math.abs(-12.5));
System.out.println(Math.abs(-11.5));
System.out.println(Math.abs(12.01));
System.out.println(Math.abs(-11.25));
System.out.println();
//sqrt: 计算平方根
System.out.println(Math.sqrt(16));
//cbrt: 计算立方根
System.out.println(Math.cbrt(125));
//pow: 计算a的b次方
System.out.println(getType(Math.pow(2,10)));
}
public static Object getType(Object o) {
return o.getClass().getName();
}
}
运行结果:
11
12
-11
-12
10.0
-10.0
-11.0
12.0
-12.0
10.0
-10.0
12.0
11.0
-13.0
-12.0
12.0
-12.0
13.0
12.0
-12.0
-11.0
13.0
-11.0
12.5
11.5
12.01
11.25
4.0
5.0
java.lang.Double
5、基本数据类型
/**
* Java Base data type;
*
* -----------------------------------------------------
* 类型 | 位数 | 占字节 (bit数) | 范围
* -----------------------------------------------------
* byte | 8 | 1 | -2^7 ~ 2^7 -1
* -----------------------------------------------------
* short | 16 | 2 | -2^15 ~ 2^15 -1
* -----------------------------------------------------
* int | 32 | 4 | -2^31 ~ 2^31 -1
* -----------------------------------------------------
* long | 64 | 8 | -2^63 ~ 2^63 -1
* -----------------------------------------------------
* float | 32 | 4
* -----------------------------------------------------
* double | 64 | 8
* -----------------------------------------------------
* char | 16 | 2
* -----------------------------------------------------
* boolean | 8 | 1
* -----------------------------------------------------
*
*
* 注:String 是个类,不是基本类型
*
*/
System.out.println("Byte max = " + Byte.MAX_VALUE);
System.out.println("Byte min = " + Byte.MIN_VALUE);
System.out.println("short max = " + Short.MAX_VALUE);
System.out.println("short min = " + Short.MIN_VALUE);
System.out.println("int max = " + Integer.MAX_VALUE);
System.out.println("int min = " + Integer.MIN_VALUE);
System.out.println("long max = " + Long.MAX_VALUE);
System.out.println("long min = " + Long.MIN_VALUE);
System.out.println("Float max = " + Float.MAX_VALUE);
System.out.println("Float min = " + Float.MIN_VALUE);
System.out.println("double max = " + Double.MAX_VALUE);
System.out.println("double min = " + Double.MIN_VALUE);
运行结果:
Byte max = 127
Byte min = -128
short max = 32767
short min = -32768
int max = 2147483647
int min = -2147483648
long max = 9223372036854775807
long min = -9223372036854775808
Float max = 3.4028235E38
Float min = 1.4E-45
double max = 1.7976931348623157E308
double min = 4.9E-324
6、a = a + b 与 a += b 的区别
+= 隐式的将加操作的结果类型强制转为持有结果的类型。a + b 操作会将a,b提升为int类型,然后将int类型赋值给a,假如a不是int 类型,可能会出现编译错误。但是 += 操作是没问题的。
public static void main(String[] args) {
byte a = 1;
byte b = 2;
System.out.println(getType(a + b)); //class java.lang.Integer
System.out.println(getType(a += b)); //class java.lang.Byte
}
public static String getType(Object o) {
return o.getClass().toString();
}
参考连接:https://blog.csdn.net/doujinlong1/article/details/80614158
7、32 位和 64 位的 JVM,int 类型变量的长度是多数?
32 位和 64 位的 JVM 中,int 类型变量的长度是相同的,都是 32 位或者 4 个字节。
关于32位和64位的JVM之间的区别 连接:https://www.cnblogs.com/jcj21/p/5225006.html
8、反码,补码,原码,位符号运算
原码:符号位加上真值的绝对值,即第一位表示符号位,其余位表示值。
反码:正数的反码是其本身。负数的反码是在其原码的基础上,符号位不变,其余各个位取反。
补码:正数的补码是其本身。负数的补码是在其原码的基础上,符号位不变,其余各个位取反,然后加1.
关于浮点型的二进制表示参考连接: https://blog.csdn.net/shuangchen/article/details/4941807
位运算:
public static void main(String[] args) throws Exception {
//位异或 运算(^): 两个数转为二进制,然后从高位比较如果相同就为0,不相同就为1.
System.out.println( 8 ^ 1); //9
//位与 运算( & ): 两个数转为二进制,然后从高位比较如果两个数为1则为1,否则为0
System.out.println( 8 & 1); //0
//位或 运算(|): 两个数转为二进制,然后从高位比较,两个数只要有一个为1则为1,否则为0
System.out.println( 8 | 1); //9
//位非 运算(~): 如果位为0则为1,如果是1则为0
System.out.println(~8); //-9
// 位左移 运算(<<) 针对二进制,转换成二进制后向左移位,后面用0补
System.out.println(8 << 3); //64
System.out.println(-8 << 2); //-32
// 位右移 运算(>>) 针对二进制,转换成二进制后向右移位,后面用0补
System.out.println(8 >> 2); //2
System.out.println(-8 >> 2); //-2
// 位无符号左移 运算(>>>)
// 10进制转二进制的时候,因为二进制数一般分8位、 16位、32位以及64位 表示一个十进制数,所以在转换过程中,最高位会补零。
// 在计算机中负数采用二进制的补码表示,10进制转为二进制得到的是源码,将源码按位取反得到的是反码,反码加1得到补码
// 二进制的最高位是符号位,0表示正,1表示负。
// >>>与>>唯一的不同是它无论原来的最左边是什么数,统统都用0填充。
// ——比如,byte是8位的,-1表示为byte型是11111111(补码表示法)
// b>>>4就是无符号右移4位,即00001111,这样结果就是15。
System.out.println(-16 >>> 2); //1073741820
System.out.println(16 >>> 2); //4
System.out.println(16 >> 2); //4
}
9、字符型常量和字符串常量的区别
a、形式上:
字符常量是单引号引起的一个字符,字符串常量是双引号引起的若干个字符
b、含义上:
字符常量相当于一个整形值(ASCII值),可以参加表达式运算,字符串常量代表一个地址值(该字符串在内存中存放位置)
c、占内存大小:
字符常量只占一个字节字符串常量占若干个字节(至少一个字符结束标志)
10、Java线程的生命周期
线程是操作系统能够进行运算的最小调度单位。线程的生命周期可以分为六中状态。
New(初始化状态),Runnable(可运行/运行状态),Blocked(阻塞状态),Waiting(无时间限制等待状态),Timed_Waiting(有时间限制等待状态),Terminated(终止状态)。
参考链接:https://baijiahao.baidu.com/s?id=1628531347800273249&wfr=spider&for=pc