Java面试题

1. int和Integer的区别?

int是基础数据类型,Integer是类型,是int的包装类。

装箱:把int包装成Integer(类似的还有Long和long,Float和float)

Integet a = 100;

拆箱:把Integer类型的对象简化成int类型

int a = new Integer(100);


2. StringBuilder和StringBuffer的区别?

StringBuffer是线程安全的,StringBuilder是Java SE5新引入的,速度更快,非线程安全。


3. Java的基本数据类型有哪些?

有8个,byte(1),short(2),int(4),long(8),float(4),double(8),char(2),boolean(1)

括号内是字节数。


4. 成员变量修饰符final和static的含义?

final修饰的变量声明后就不能被修改。

static修改的是静态变量,类的所有对象共享一个变量。


5. Error和Exception的区别?

Error是系统级别的错误,很难恢复,程序不必处理,如内存溢出。

Exception是程序应该捕获或处理的异常,是实现的问题。


6. 线程和进程的区别?

进程是运行的程序,有独立的内存空间。

线程是进程内部的一个执行序列,一个进程可以有多个线程,多个线程共享内存空间。


7. 创建一个线程的两种方式?哪种比较好?

继承Thread类和实现Runnable接口。

实现Runnable接口的方式比较好,因为继承意味着耦合,而且Java是单继承的机制,继承了Thread类意味着不能继承其他父类。

还有使用Excutor线程池的方式。


8. Java类的hashcode方法和equals方法?

所有Java都是继承自Object,如果没有重写equals方法,比较的是地址。

String等类型已经重写了equals方法,比较的是String的值。

这两个方法一般同时重写或都不重写。

equals相等的两个对象有相同的hashcode。

但两个对象有hashcode的时候equals不一定相等,可能是hashcode方法的实现有问题导致。


9. 两个对象或变量的==和equal方法的区别?

(1)基本数据类型:基本数据类型变量==比较的是值,没有equals方法

(2)非基本数据类型:==比较的是地址,equals方法要看是否重写了

(3)重写了equals方法:看方法的实现。String,Integer等包装类型Java已经重写了,比较的是值 

(4)没有重写equals方法:比较的是地址


10. PreparedStatement和Statement的对比

PreparedStatement有数据库预编译,能重用,提高查询效率

PreparedStatement能预防SQL注入攻击,数据库不会将参数视为SQL指令的一部分来处理,而是在编译完成后才套用参数

PreparedStatement能动态参数化查询,更灵活。


11. 堆内存和栈内存的区别

栈(stack):也叫堆栈,存取速度较快,仅次于CPU寄存器,存放基本数据类型变量和对象的引用

堆(heap):存放对象,由垃圾回收机制管理


12. static关键字的作用?类可以用static修饰吗?

static变量:静态变量,类的所有实例共享,只分配一块内存空间。

static方法:无需实例化即可调用的方法,static方法只能调用其他static方法(非static方法可以调用static方法),访问static变量。

static类:只有内部类可以声明为static,可以直接作为一个类来使用。

static代码块:JVM加载类的时候执行,只会执行一次。

内部类可以用static修饰。


13. final关键字的作用?

final常量:和变量相对,是不可变的。final基本类型常量表示其值不变,final对象表示其引用不变,只能指向初始化时的那个对象,但对象本身是可变的。

final参数:基本类型参数表示不可在方法中改变其值,对象参数表示不可在方法中改变其引用。主要用来向匿名内部类传递数据。

final方法:继承的类不可重写。过去还出于对效率的考虑。

                 类中private方法都隐式的指定为final。

final类:不能被继承。final类中的所有方法都隐式的指定为final。


14. 重载和重写的区别?

重写(override)也叫覆盖、覆写。

重写用于子类对父类某个方法的重新实现或类对接口的实现,可以用注解@Override来表示,如果加了注解又没有重写,编译器会报错;反之可以,即重写的方法不强制加@Override注解。

重载(overload)一般是指一个类中有两个或以上的方法,方法名相同而参数列表不同。


15. 向上转型和向下转型?

向上转型是指子类的对象转换成父类的对象,向下则相反。

向上转型是安全的,但可能会丢失子类特有的方法和属性,丢失的方法可以通过向下转型重新获得,向下转型需要强制转换,且可能抛出ClassCastException。

“是否有向上转型的需要”也可以用来判断类设计时是否要采用继承,比如需要在一个集合中操作一些不同类型的对象,就可以用继承:定义该集合存放基类,可以直接将子类对象放进去,这时向上转型,然后可以将对象取出来,向下转型成子类,重新获得子类特有的方法和属性。


16.compareTo方法和compare方法的区别?

compareTo是Comparable接口的一个方法,主要用于方法的比较、排序(容器中)等。

compare是Comparator接口的一个方法,用于定义两个对象的比较结果。

compareTo方法的使用:

public class User implements Comparable<Object> { // 实现了Comparable接口
	
	private int id;
	
	private String name;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 重写compareTo方法,定义两个对象的比较
	 */
	public int compareTo(Object arg0) {
		if (this == arg0) {
			return 0;
		} else {
			if (arg0 != null && arg0 instanceof User) {
				User user = (User) arg0;
				if (this.id > user.getId()) {
					return 1;
				} else if (this.id == user.getId()) {
					return 0;
				} else {
					return -1;
				}
			} else {
				return -1;
			}
		}
	}
}
public class Test {
	
	/**
	 * 定义比较器comparator
	 */
	private static Comparator<User> userComparator = new Comparator<User>() {
		public int compare(User arg0, User arg1) {
			if (arg0.getId() > arg1.getId()) {
				return 1;
			} else if (arg0.getId() == arg1.getId()) {
				return 0;
			} else {
				return -1;
			}
		}
	};
	
	public static void main(String[] args) {
		User user1 = new User();
		User user2 = new User();
		User user3 = new User();
		user1.setName("user1");
		user2.setId(2);
		user2.setName("user2");
		user3.setId(3);
		user3.setName("user3");
		List<User> users = new ArrayList<User>();
		users.add(user1);
		users.add(user3);
		users.add(user2);
		users.sort(userComparator); // 使用自定义的比较器进行排序
		for (User user : users) {
			System.out.println(user.getName());
		}
	}
}

17.Class.forName()方法的作用?

(1)Class.forName()用于加载类,可以在程序运行时动态生成类的对象,比如:

ClassA a = (ClassA)Class.forName(className).newInstance();
传入className,即类的名称,生成该类的对象,为多态提供了很好的支持,即ClassA设计成一个基类或接口,而className是继承了基类或实现了接口的多个不同的子类的名称。

(2)Class.forName()还可以用于加载数据库驱动。

(3)类被加载的时候静态代码段会被执行。

18.什么是可变参数?

可变参数是指一个方法的形参允许传入个数不确定的类型参数,如下函数test,可传入一个或多个int。

public class Test {
	
	public static void main(String[] args) {
		test(1);
		test(1, 2);
	} 
	
	public static void test(int ... numbers) {
		for (int a : numbers) {
			System.out.println(a);
		}
	}

}

19. 数组和List容器的区别,之间的相互转换

(1)数组长度固定,容器可变

(2)数组只能存储指定类型的对象,容器可以存储任意类型对象

(3)数组效率较高,访问很快,容器开销较大,效率较低

数组和List的相互转换:

// 数组转换为List
public static void arrayToList() {
	String[] stringArray = new String[]{"a", "b"};
	List<String> stringList = Arrays.asList(stringArray);
	for (String str : stringList) {
		System.out.println(str);
	}
}
	
// List转换为数组
public static void listToArray() {
	@SuppressWarnings("serial")
	List<String> stringList = new ArrayList<String>(){{
		add("a");
		add("b");
	}};
	String[] stringArray = (String[]) stringList.toArray(new String[0]); // List有两个toArray方法
	for (String str : stringArray) {
		System.out.println(str);
	}
}

List的toArray()方法有带参数和不带参数两个重载。

如果调用不带参数的方法,会抛出ClassCastException:[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;,数组也是一种类型,[Ljava.lang.Object类型不能转化为[Ljava.lang.String类型。

带参数的toArray()方法会构造一个长度和list一样的空数组。

20. 深复制和浅复制的区别?

也叫深克隆和浅克隆。

浅复制只复制当前的对象,不复制对象所引用的其他对象。

深复制要把复制的对象所引用的其他所有对象也复制一份。


21. 什么是Native方法?

native方法是原生的函数,即用C/C++实现的,被编译成DLL,由Java去调用。


22. String类为什么是final的?

出于“安全性”和“效率”。

final修饰的类不能被继承,所以不会被修改,保证了安全性。

String使用非常频繁,定义成final可以提高效率。


23. ArrayList和LinkedList的区别?

ArrayList的实现基于动态数组,LinkedList的实现基于链表。

ArrayList随机访问较快。

LinkedList插入较快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值