java面试

一、java基础篇

1.接口和抽象类的区别

相似点:

(1)接口和抽象类都不能被实例化

(2)实现接口或继承抽象类的普通子类都必须实现这些抽象方法

不同点:

(1)抽象类可以包含普通方法和代码块,接口里只能包含抽象方法,静态方法和默认方法,

(2)抽象类可以有构造方法,而接口没有

(3)抽象类中的成员变量可以是各种类型的,接口的成员变量只能是 public static final 类型的,并且必须赋值

2.重载和重写的区别

(1)重载:发生在同一个类中,方法名相同、参数列表、返回类型、权限修饰符可以不同

(2)重写:发生在子类中,方法名、参数列表、返回类型都相同,权限修饰符要大于父类方法,声明异常范围要小于父类方法,但是final和private修饰的方法不可重写

3.== 和equals的区别

== 比较基本类型,比较的是值,equals比较引用类型,比较的是内存地址

equlas是Object类的方法,本质上与==一样,但是有些类重写了equals方法,比如String的equals被重写后,比较的是字符值,另外重写了equlas后,也必须重写hashcode()方法

4.异常处理机制

(1)使用try、catch、finaly捕获异常,finaly中的代码一定会执行,捕获异常后程序会继续执行

(2)使用throws声明该方法可能会抛出的异常类型,出现异常后,程序终止

5.HashMap原理

(1)HashMap在Jdk1.8以后是基于数组+链表+红黑树来实现的,特点是,key不能重复,可以为null,线程不安全

(2)HashMap的扩容机制:

HashMap的默认容量为16,默认的负载因子为0.75,当HashMap中元素个数超过容量乘以负载因子的个数时,就创建一个大小为前一次两倍的新数组,再将原来数组中的数据复制到新数组中。当数组长度到达64且链表长度大于8时,链表转为红黑树

(3)HashMap存取原理:

​ (1)计算key的hash值,然后进行二次hash,根据二次hash结果找到对应的索引位置

​ (2)如果这个位置有值,先进行equals比较,若结果为true则取代该元素,若结果为false,就使用高低位平移法将节点插入链表(JDK8以前使用头插法,但是头插法在并发扩容时可能会造成环形链表或数据丢失,而高低位平移发会发生数据覆盖的情况)

6.想要线程安全的HashMap怎么办?

(1)使用ConcurrentHashMap

(2)使用HashTable

(3)Collections.synchronizedHashMap()方法

7.ConcurrentHashMap原如何保证的线程安全?

JDK1.7:使用分段锁,将一个Map分为了16个段,每个段都是一个小的hashmap,每次操作只对其中一个段加锁

JDK1.8:采用CAS+Synchronized保证线程安全,每次插入数据时判断在当前数组下标是否是第一次插入,是就通过CAS方式插入,然后判断f.hash是否=-1,是的话就说明其他线程正在进行扩容,当前线程也会参与扩容;删除方法用了synchronized修饰,保证并发下移除元素安全

8.HashTable与HashMap的区别

(1)HashTable的每个方法都用synchronized修饰,因此是线程安全的,但同时读写效率很低

(2)HashTable的Key不允许为null

(3)HashTable只对key进行一次hash,HashMap进行了两次Hash

(4)HashTable底层使用的数组加链表

9.ArrayList和LinkedList的区别

ArratList的底层使用动态数组,默认容量为10,当元素数量到达容量时,生成一个新的数组,大小为前一次的1.5倍,然后将原来的数组copy过来;因为数组在内存中是连续的地址,所以ArrayList查找数据更快,由于扩容机制添加数据效率更低

LinkedList的底层使用链表,在内存中是离散的,没有扩容机制;LinkedList在查找数据时需要从头遍历,所以查找慢,但是添加数据效率更高

10.如何保证ArrayList的线程安全?

(1)使用collentions.synchronizedList()方法为ArrayList加锁

(2)使用Vector,Vector底层与Arraylist相同,但是每个方法都由synchronized修饰,速度很慢

(3)使用juc下的CopyOnWriterArrayList,该类实现了读操作不加锁,写操作时为list创建一个副本,期间其它线程读取的都是原本list,写操作都在副本中进行,写入完成后,再将指针指向副本。

11.String、StringBuffer、StringBuilder的区别

String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。

StringBuffer可变并且线程安全

StringBuiler可变但线程不安全

操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer。

12.hashCode和equals

hashCode()和equals()都是Obkect类的方法,hashCode()默认是通过地址来计算hash码,但是可能被重写过用内容来计算hash码,equals()默认通过地址判断两个对象是否相等,但是可能被重写用内容来比较两个对象

所以两个对象相等,他们的hashCode和equals一定相等,但是hashCode相等的两个对象未必相等

如果重写equals()必须重写hashCode(),比如在HashMap中,key如果是String类型,String如果只重写了equals()而没有重写hashcode()的话,则两个equals()比较为true的key,因为hashcode不同导致两个key没有出现在一个索引上,就会出现map中存在两个相同的key

13.面向对象和面向过程的区别

面向对象有封装、继承、多态性的特性,所以相比面向过程易维护、易复用、易扩展,但是因为类调用时要实例化,所以开销大性能比面向过程低

14.深拷贝和浅拷贝

浅拷贝:浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存
深拷贝:深拷贝会创造一个一摸一样的对象,新对象和原对象不共享内存,修改新对象不会改变原对对象。

15.多态的作用

多态的实现要有继承、重写,父类引用指向子类对象。它的好处是可以消除类型之间的耦合关系,增加类的可扩充性和灵活性。

16.什么是反射?

反射是通过获取类的class对象,然后动态的获取到这个类的内部结构,动态的去操作类的属性和方法。
应用场景有:要操作权限不够的类属性和方法时、实现自定义注解时、动态加载第三方jar包时、按需加载类,节省编译和初始化时间;获取class对象的方法有:class.forName(类路径),类.class(),对象的getClass()

17.Java创建对象得五种方式?

(1)new关键字

(2)Class.newInstance

(3)Constructor.newInstance

(4)Clone方法

(5)反序列化

二.Java多线程篇

1.进程和线程的区别,进程间如何通信

进程:系统运行的基本单位,进程在运行过程中都是相互独立,但是线程之间运行可以相互影响。

线程:独立运行的最小单位,一个进程包含多个线程且它们共享同一进程内的系统资源

进程间通过管道、 共享内存、信号量机制、消息队列通信

2. 什么是线程上下文切换

当一个线程被剥夺cpu使用权时,切换到另外一个线程执行

1.java面向对象有那些特征

​ 封装、继承、多态

2.java中线程的状态?

​ ①new 创建

​ ②runnable 就绪、运行

​ ③blocked 阻塞

​ ④wait 等待

​ ⑤timed_waiting 超时等待

​ ⑥terminated 结束

3.java中如何停止线程

​ ①sleep

​ ②共享变量

​ ③interrupt(与共享变量类似,但可以在wait、sleep时结束线程)

4.Java中sleep和wait方法的区别?

①sleep是threadLocal的一个静态方法,wait是一个属于object对象的方法。

​ ②sleep属于timed_waiting,会自动唤醒,wait属于waiting需要手动唤醒。

​ ③sleep在持有锁时执行,不会释放锁资源,wait在持有锁执行后,会释放锁资源。

​ ④sleep在持有锁或不持有锁时都可以执行,wait必须在持有锁的时候才可以执行

​ wait方法会将持有锁的线程从owner扔到WaitSet集合中,这个操作是在修改ObjectMonitor对象,没有持有synchronized锁的话,是无法操作ObjectMonitor对象的。

mysql数据库

java面试_第1张图片

java面试_第2张图片

Springboot接口开发

java面试_第3张图片

java面试_第4张图片

java面试_第5张图片

java面试_第6张图片

JSR303

java面试_第7张图片

事务

java面试_第8张图片

断点续传

java面试_第9张图片

你可能感兴趣的:(java,面试,开发语言)