欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

面试必考:Java基础面试题(二)

程序员文章站 2022-06-10 10:42:28
...

10.Java序列化的方式。

A: 实现Serializable接口(隐式序列化)
通过实现Serializable接口,这种是隐式序列化(不需要手动),这种是最简单的序列化方式,会自动序列化所有非static和 transient关键字修饰的成员变量。直接创建输入输出流运行即可
B:实现Externalizable接口。(显式序列化)
Externalizable接口继承自Serializable, 我们在实现该接口时,必须实现writeExternal()和readExternal()方法,而且只能通过手动进行序列化,并且两个方法是自动调用的,因此,这个序列化过程是可控的,可以自己选择哪些部分序列化
C:实现Serializable接口+添加writeObject()和readObject()方法。(显+隐序列化)
1,添加的方法必须要被private修饰 ----->才能被调用
2,第一行调用默认的defaultRead/WriteObject(); ----->隐式序列化非static和transient
3,调用read/writeObject()将获得的值赋给相应的值 —>显式序列化
stream.defaultReadObject();
age = stream.readInt();

11.传值和传引用的区别

传值:传递的是值的副本。方法中对副本的修改,不会影响到调用方。
传引用:传递的是引用的副本,共用一个内存,会影响到调用方。此时,形参和实参指向同一个内存地址。对引用副本本身(对象地址)的修改,如设置为null,重新指向其他对象,不会影响到调用方。

12.一个ArrayList在循环过程中删除,会不会出问题,为什么。

会删除元素“222”,当循环到下标为1的元素的的时候,发现此位置上的元素是“222”,此处元素应该删除,根据上图中的元素移动可知,在删除元素后面的所有元素都要向前移动一个位置,那么移动之后,原来下标为2的元素“222”,此时下标为1,这是在i = 1,时的循环操作,在下一次的循环中,i = 2,此时就遗漏了第二个元素“222”。
可以用迭代器的iterator.remove();解决,单是迭代器的while(iterator.next())循环直接调用remove还是调用的ArrayList的删除,还是会出问题

[email protected]注解在什么情况下会失效,为什么。

A:@Transactional注解只能应用到public可见度的方法上。如果应用在protected、private或者package可见度的方法上,也不会报错,不过事务设置不会起作用。
B:默认情况下,Spirng会对unchecked异常进行事务回滚;如果是checked异常则不回滚。
什么是unchecked异常,什么是checked异常?
java里面将派生于Error或者RuntimeException(比如空指针,1/0)的异常成为unchecked异常,其他继承自java.lang.Exception的异常统称为checked Exception,如IOException、TimeOutException等
通俗点讲就是,写的代码出现了空指针异常,会被回滚,而文件读写,网络出问题,spring就没法回滚了。
写代码的时候,有些IOException我们的编译器能够检测到的,所以说叫checked异常,写代码的时候空指针异常时检测不到的,所以叫unchecked异常。
C:数据库引擎要支持事务,如果是Mysql,注意表要使用支持事务的引擎,比如innaodb,如果是myisam,事务是不起作用的
D:是否开启了对注解的解析:TX:…
E:spring是否扫描到你使用注解事务的这个类所在的包:Context:…
F:异常是不是被catch住了

14.hashcode相等两个类一定相等吗?equals呢?相反呢?

hashCode相等,equals也不一定相等, 两个类也不一定相等
equals相同, 说明是同一个对象, 那么hashCode一定相同

15.介绍一下集合框架?Collection接口含有迭代器

A:继承了Collection接口,List列表在数据结构上可以被看做线性表,常用的有ArrayList和LinkList(不常用的有Vector(类似于ArrayList)),他们的底层存储结构有所不同,一个是数组,一个是链表;
B:继承了Collection接口,Set集合,存储的元素不能重复,其通过equals的方法,来判断元素是否重复;HashSet、LinkedHashSet、TreeSet
C:Map是一种映射,用于存储关系型数据,保存着两种值,一组用于保存key,另外一组用于保存value。TreeMap,HashMap,LinkedHashMap

16.hashmap和treemap什么区别?低层数据结构是什么?

TreeMap:基于红黑二叉树的NavigableMap的实现,线程非安全,不允许null,key不可以重复,value允许重复,存入TreeMap的元素应当实现Comparable接口或者实现Comparator接口,
会按照排序后的顺序迭代元素,两个相比较的key不得抛出classCastException。主要用于存入元素的时候对元素进行自动排序,迭代输出的时候就按排序顺序输出
HashMap:底层数组+链表实现,可以存储null键和null值,线程不安全
初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂
扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入
插入元素后才判断该不该扩容,有可能无效扩容(插入后如果扩容,如果没有再次插入,就会产生无效扩容)
当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀
计算index方法:index = hash & (tab.length – 1)

17.synchronized和Lock什么区别?synchronized 什么情况情况是对象锁? 什么时候是全局锁为什么?

区别:
首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可中断、可公平(两者皆可)
Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
全局锁和对象锁的区分
synchronized(this)以及非static的synchronized方法,锁住的是括号里()的对象,如果要锁全局,就用synchronized(对象.class)。
static 的synchronized方法,static方法可以直接类名.方法名()调用,无法使用this,所以它锁的不是this,而是类的Class对象。所以静态方法也相当于全局锁,锁住了代码段。

18.ThreadLocal 是什么底层如何实现?写一个例子呗?

底层实现
先,在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。初始时,在Thread里面,threadLocals为空,当通过ThreadLocal变量调用get()方法或者set()方法,就会对Thread类中的threadLocals进行初始化,并且以当前ThreadLocal变量为键值,以ThreadLocal要保存的副本变量为value,存到threadLocals。然后在当前线程里面,如果要使用副本变量,就可以通过get方法在threadLocals里面查找。
例子

private static ThreadLocal<Connection> connectionHolder= new ThreadLocal<Connection>() {
	public Connection initialValue() {
    	return DriverManager.getConnection(DB_URL);
	}
};
public static Connection getConnection() {
	return connectionHolder.get();
}