Java面试题大全(持续更新中)

转载请注明出处:https://blog.csdn.net/mythmayor/article/details/79487909

1.看下面的程序是否有问题,如果有问题,请指出并说明理由.

* byte b1 = 3;
* byte b2 = 4;
* byte b3 = b1 + b2;
	* 从两方面去回答这个题
	* b1和b2是两个变量,变量里面存储的值都是变化的,所以在程序运行中JVM是
	  无法判断里面具体的值
	* byte类型的变量在进行运算的时候,会自动类型提升为int类型 
* byte b4 = 3 + 4;
	* 3和4都是常量,java有常量优化机制,就是在编译的的时候直接把3和4的结果赋值给b4了 

2.看程序回答问题.

* byte b = 10;
* b++;  
* b = b + 1; 型
* 问哪句会报错,为什么 

b = b + 1;这句会报错.当byte与int进行混合运算的时候,会提升为int类型,
两个int相加的结果还是int,赋值给byte会损失精度;
而 b++;这条语句在底层会做强制转换,相当于 b = (byte)(b+1);所以不报错.

3.看下面的程序是否有问题,如果有问题,请指出并说明理由.

* (1)short s=1; s=s+1;
* (2)short s=1; s+=1;
(1):当short与int进行运算的时候,会提升为int类型,两个int类型相加的结果也是int类型.
(2):在底层会做强制类型转换,相当于 s=(short)(s+1);

4.实现两个整数的交换.

int a = 5;
int b = 3;
(1)用第三方变量://开发常用
int temp = x;
x = y;
y = x;
(2)不需要第三方变量://有弊端,有可能会超出int的取值范围
x = x + y;
y = x - y;
x = x - y;
(3)用位运算符交换两个数.
a = a ^ b;
b = a ^ b;
a = a ^ b;

5. 2 * 8最有效率的运算方式.

2 << 3;

6.switch 的表达式可以是什么?

byte short char int 枚举(jdk1.5) String(jdk1.7)

7.传值和传址

基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失
引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过地址继续访问

Java中到底是传值还是传址
1,既是传值,也是传地址,基本数据类型传递的值,引用数据类型传递的地址
2,java中只有传值,因为地址值也是值(出去面试都说这种,支持者是高司令(java之父))

8.面向对象特点及特征

特点: 1.是一个更符合人们思想习惯的思想;
2.将复杂的事情简单化;
3.从执行者变成指挥者;
特征: 1.封装 2.继承 3.多态

9.成员变量和局部变量的区别

  • A:在类中的位置不同

    • 成员变量:在类中方法外
    • 局部变量:在方法定义中或者方法声明上
  • B:在内存中的位置不同

    • 成员变量:在堆内存(成员变量属于对象,对象进堆内存)
    • 局部变量:在栈内存(局部变量属于方法,方法进栈内存)
  • C:生命周期不同

    • 成员变量:随着对象的创建而存在,随着对象的消失而消失
    • 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
  • D:初始化值不同

    • 成员变量:有默认初始化值
    • 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
  • 注意事项:

    • 局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
    • 基本数据类型变量包括哪些:byte,short,int,long,float,double,boolean,char
    • 引用数据类型变量包括哪些:数组,类,接口,枚举

10.static关键字

(1)static关键字的特点
* a:随着类的加载而加载
* b:优先于对象存在
* c:被类的所有对象共享
* d:可以通过类名调用
(2)static的注意事项
* a:在静态方法中是没有this关键字的
* 静态是随着类的加载而加载,this是随着对象的创建而存在。
* 静态比对象先存在。
* b:静态方法只能访问静态的成员变量和静态的成员方法
* 静态方法:
* 成员变量:只能访问静态变量
* 成员方法:只能访问静态成员方法
* 非静态方法:
* 成员变量:可以是静态的,也可以是非静态的
* 成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
* 简单记:
* 静态只能访问静态。

11.静态变量和成员变量的区别

* 静态变量也叫类变量  成员变量也叫对象变量
* A:所属不同
	* 静态变量属于类,所以也称为为类变量
	* 成员变量属于对象,所以也称为实例变量(对象变量)
* B:内存中位置不同
	* 静态变量存储于方法区的静态区
	* 成员变量存储于堆内存
* C:内存出现时间不同
	* 静态变量随着类的加载而加载,随着类的消失而消失
	* 成员变量随着对象的创建而存在,随着对象的消失而消失
* D:调用不同
	* 静态变量可以通过类名调用,也可以通过对象调用
	* 成员变量只能通过对 象名调用

12.看程序写结果

class Student {
		static {
			System.out.println("Student 静态代码块");	//3
		}
		
		{
			System.out.println("Student 构造代码块");	//4  //6
		}
		
		public Student() {
			System.out.println("Student 构造方法");		//5  //7
		}
	}

class Demo2_Student {
	static {
		System.out.println("Demo2_Student静态代码块");	//1
	}
	
	public static void main(String[] args) {
		System.out.println("我是main方法");	//2
		
		Student s1 = new Student();
		Student s2 = new Student();
	}
}

13.看程序写结果

class Fu{
	public int num = 10;
	public Fu(){
		System.out.println("fu");
	}
}

class Zi extends Fu{
	public int num = 20;
	public Zi(){
		System.out.println("zi");
	}
	public void show(){
		int num = 30;
		System.out.println(num);
		System.out.println(this.num);
		System.out.println(super.num);
	}
}

class Test1_Extends {
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show();
	}
}
/*
	fu
	zi 
	30
	20
	10
*/

14.看程序写结果

class ExtendsTest {
	public static void main(String[] args) {
		Zi z = new Zi();
	}
	
	/*
		1,jvm调用了main方法,main进栈
		2,遇到Zi z = new Zi();会先将Fu.class和Zi.class分别加载进内存,
		再创建对象,当Fu.class加载进内存,父类的静态代码块会随着Fu.class
		一起加载,当Zi.class加载进内存,子类的静态代码块会随着Zi.class一起加载
		第一个输出,静态代码块Fu,第二个输出静态代码块Zi
		3,走Zi类的构造方法,因为java中是分层初始化的,先初始化父类,
		再初始化子类,所以先走的父类构造,但是在执行父类构造时,发现父类
		有构造代码块,构造代码块是优先于构造方法执行的所以
		第三个输出构造代码块Fu,第四个输出构造方法Fu
		4,Fu类初始化结束,子类初始化,第五个输出的是构造代码块Zi,构造方法Zi
	*/
}
class Fu {
	static {
		System.out.println("静态代码块Fu");		//1
	}

	{
		System.out.println("构造代码块Fu");		//3
	}

	public Fu() {
		System.out.println("构造方法Fu");		//4
	}
}

class Zi extends Fu {
	static {
		System.out.println("静态代码块Zi");		//2
	}

	{
		System.out.println("构造代码块Zi");		//5
	}

	public Zi() {
		System.out.println("构造方法Zi");		//6
	}
}

Zi z = new Zi(); 请执行结果。

15.方法重写的面试题

  • Override和Overload的区别?Overload能改变返回值类型吗?

  • overload可以改变返回值类型,只看参数列表

  • 方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一致(或者是子父类)的

  • 方法重载:在同一个类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

  • 子类对象调用方法的时候:

    • 先找子类本身,再找父类。

16.final关键字的面试题?

A:修饰局部变量
B:初始化时机
/*
A:
基本类型:值不能被改变。
引用类型:地址值不能被改变。对象中的属性可以改变。
B:
显式初始化
在对象构造完毕前即可
*/

17.一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?

  • 可以
  • 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成

18.abstract不能和哪些关键字共存

static final private
abstract和static
被abstract修饰的方法没有方法体
被static修饰的可以用类名.调用,但是类名.调用抽象方法是没有意义的
abstract和final
被abstract修饰的方法强制子类重写
被final修饰的不让子类重写,所以他俩是矛盾
abstract和private
被abstract修饰的是为了让子类看到并强制重写
被private修饰不让子类访问,所以他俩是矛盾的

19.看程序写结果

A:看下面程序是否有问题,如果没有,说出结果

class Fu {
	public void show() {
		System.out.println("fu show");
	}
}

class Zi extends Fu {
	public void show() {
		System.out.println("zi show");
	}

	public void method() {
		System.out.println("zi method");
	}
}

class Test1Demo {
	public static void main(String[] args) {
		Fu f = new Zi();
		f.method();
		f.show();
	}
}

//编译出错。编译看左边,而Fu类中没有method()方法。

B:看下面程序是否有问题,如果没有,说出结果

class A {
	public void show() {
		show2();
	}
	public void show2() {
		System.out.println("我");
	}
}
class B extends A {
	public void show2() {
		System.out.println("爱");
	}
}
class C extends B {
	public void show() {
		super.show();
	}
	public void show2() {
		System.out.println("你");
	}
}
public class Test2DuoTai {
	public static void main(String[] args) {
		A a = new B();
		a.show();
		
		B b = new C();
		b.show();
	}
}

//爱
//你

20.package,import,class有没有顺序关系

package放在有效代码的第一行,import放在中间,class放在三者最后。

21.要求:使用已知的变量,在控制台输出30,20,10。

class Outer {
	public int num = 10;
	class Inner {
		public int num = 20;
		public void show() {
			int num = 30;
			System.out.println(?);	//num
			System.out.println(??);	//this.num
			System.out.println(???);//Outer.this.num
		}
	}
}

class InnerClassTest {
	public static void main(String[] args) {
		Outer.Inner oi = new Outer().new Inner();
		oi.show();
	}	
}

22.按照要求,补齐代码

interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
	public static void main(String[] args) {
		  Outer.method().show();
	  }
}

要求在控制台输出”HelloWorld”

//需要补齐代码内容
public static Inter method() {
	return new Inter() {
		public void show() {
			System.out.println("HelloWorld");
		}
	};	
}

23.==号和equals方法的区别

相同点:都是作比较的,返回的都是布尔类型。
不同点:
(1)==:
* 是一个比较运算符号,既可以比较基本数据类型,也可以比较引用数据类型,
基本数据类型比较的是值, 引用数据类型比较的是地址值
(2)equals:
* equals方法是一个方法,只能比较引用数据类型,所有的对象都会继承Object类中的方法,
如果没有重写Object类中的equals方法,equals方法和
号比较引用数据类型无区别,
重写后的equals方法比较的是对象中的属性。

24.判断定义为String类型的s1和s2是否相等

* String s1 = "abc";
* String s2 = "abc";
* System.out.println(s1 == s2); //true					
* System.out.println(s1.equals(s2)); //true
//常量池中没有这个字符串对象,就创建一个,如果有直接用即可

25.下面这句话在内存中创建了几个对象?

* String s1 = new String("abc");
//创建几个对象
//创建两个对象,一个在常量池中,一个在堆内存中

26.判断定义为String类型的s1和s2是否相等

* String s1 = new String("abc");	//记录的是堆内存对象的地址值		
* String s2 = "abc";				//记录的是常量池中的地址值
* System.out.println(s1 == s2); ?		//false	
* System.out.println(s1.equals(s2)); ?	//true

27.判断定义为String类型的s1和s2是否相等

* String s1 = "a" + "b" + "c";	
* String s2 = "abc";			
* System.out.println(s1 == s2); ?		//true,java中有常量优化机制
* System.out.println(s1.equals(s2)); ?	//true

28.判断定义为String类型的s1和s2是否相等

* String s1 = "ab";
* String s2 = "abc";
* String s3 = s1 + "c";
* System.out.println(s3 == s2);			//false
* System.out.println(s3.equals(s2)); ?	//true

29.null与""的区别?

""是字符串常量,同时也是一个String类的对象,既然是对象当然可以调用String类中的方法
null是空常量,不能调用任何的方法,否则会出现空指针异常,null常量可以给任意的引用数据类型赋值

30.String,StringBuffer,StringBuilder的区别

(1)String:是一个不可变的字符序列
(2)StringBuffer:是一个可变的字符序列。是jdk1.0版本的,是线程安全的,效率低
(3) StringBuilder:是一个可变的字符序列。是jdk1.5版本的,是线程不安全的,效率高

31.Integer的面试题

看程序写结果

Integer i1 = new Integer(97);
Integer i2 = new Integer(97);
System.out.println(i1 == i2);        //false
System.out.println(i1.equals(i2));    //true
System.out.println("-----------");

Integer i3 = new Integer(197);
Integer i4 = new Integer(197);
System.out.println(i3 == i4);        //false
System.out.println(i3.equals(i4));    //true
System.out.println("-----------");

Integer i5 = 97;
Integer i6 = 97;
System.out.println(i5 == i6);        //true
System.out.println(i5.equals(i6));    //true
System.out.println("-----------");

Integer i7 = 197;                    
Integer i8 = 197;                    
System.out.println(i7 == i8);        //false
System.out.println(i7.equals(i8));    //true

-128到127是byte的取值范围,在这个取值范围内,自动装箱
就不会新创建对象,而是从常量池中获取,如果超出了byte取值
范围就会重新创建对象

32.注意:String和StringBuffer分别作为参数传递

* A:形式参数问题
    * String作为参数传递
    * StringBuffer作为参数传递 
    基本数据类型的值传递,不改变其值。引用数据类型的值传递,改变其值。
    String类虽然是引用数据类型,但当它当做参数传递时和基本数据类型一样。

33.JDK1.5新特性:

  泛型,枚举,增强for,自动拆装箱,静态导入,可变参数

34.并发修改异常产生的原因及解决方案

产生原因:用迭代器遍历集合的时候又使用集合改变了集合的结构
解决方案:(1)用普通for循环
(2)用列表迭代器ListIterator

35.HashMap和Hashtable的区别

 * 共同点: 
     底层都是哈希算法,都是双列集合
 * HashMap:
       线程不安全,效率高,JDK1.2版本
       可以存储null键和null值
 * Hashtable:
       线程安全,效率低,JDK1.0版本
       不可以存储null键  

36.Collection和Collections的区别:

Collection是单列集合的顶层接口,里面定义了单列集合的共性内容。
Collections是操作集合的工具类,里面提供了一些查找、排序等常用集合功能。

37.final,finally和finalize的区别

  • final
    修饰类,不能被继承
    修饰方法,不能被重写
    修饰变量,只能赋值一次
  • finally
    是try语句中的一个语句体,不能单独使用,用来释放资源
  • finalize
    是一个方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

38.如果catch里面有return语句,请问finally的代码还会执行吗?

如果会,请问是在return前还是return后?
return 会先建立返回路径,然后执行finally内的语句,然后再由return返回
会执行,在return后(return – finally – return)

39.throws和throw的区别

* a:throws
	* 用在方法声明后面,跟的是异常类名
	* 可以跟多个异常类名,用逗号隔开
	* 表示抛出异常,由该方法的调用者来处理
* b:throw
	* 用在方法体内,跟的是异常对象名
	* 只能抛出一个异常对象名
	* 表示抛出异常,由方法体内的语句处理

40.内存输出流面试题

  • 定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)
//创建字节输入流,关联a.txt
FileInputStream fis = new FileInputStream("a.txt");
//创建内存输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//创建字节数组,大小为5
byte[] arr = new byte[5];
int len;
//将文件上的数据读到字节数组中
while((len = fis.read(arr)) != -1) {
	//将字节数组的数据写到内存缓冲区中
	baos.write(arr, 0, len);
}
//将内存缓冲区的内容转换为字符串打印
System.out.println(baos);
fis.close();

41.实现多线程两种方式的区别

  • 查看源码的区别:

    • a.继承Thread : 由于子类重写了Thread类的run(), 当调用start()时, 直接找子类的run()方法
    • b.实现Runnable : 构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run()方法时内部判断成员变量Runnable的引用是否为空, 不为空编译时看的是Runnable的run(),运行时执行的是子类的run()方法
  • 继承Thread

    • 好处是:可以直接使用Thread类中的方法,代码简单
    • 弊端是:如果已经有了父类,就不能用这种方法
  • 实现Runnable接口

    • 好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的
    • 弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码复杂

42.面试题

  • 在同步代码块中,用哪个对象锁,就用哪个对象调用wait()方法

  • 为什么wait()方法和notify()方法定义在Object类中

  • 因为锁对象可以使任意对象,而Object是所有类的超类,所以wait()方法和notify()方法需要定义在Object类中

  • sleep方法和wait方法的区别

  • a.sleep方法必须传入参数,参数就是时间,时间到了自动醒来

  • wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待

  • b.sleep方法在同步函数或者同步代码块中,不释放锁。睡着了也抱着锁睡。

  • wait方法在同步函数或者同步代码块中,释放锁。

参考:
sleep方法和wait方法的区别?
sleep是Thread里面的方法,而wait是Object类里面的方法。
sleep方法让线程在指定时间内处于休眠状态,时间到了后继续向下执行
wait 方法让线程处于阻塞状态,必须在得到notify或者notifyAll的通知后才能继续向下执行
sleep方法没有释放锁,其他线程不能进入同步代码块或者同步方法
wait 方法释放了锁,使得其他线程可以进入同步代码块或者同步方法。

43.线程的五种状态

* 新建,就绪,运行,阻塞,死亡

这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值