Java面试题整理及答案解析(基础篇)

一、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

猜你喜欢

转载自blog.csdn.net/qq_39742510/article/details/94554725