Java经典面试题汇总

本文汇总了Java面试中的常见问题,涵盖了Java基础、线程、反射、JVM、框架(Spring、Mybatis、Spring Boot)、微服务(SpringCloud)以及数据库相关知识点,包括集合、线程安全、锁机制、反射原理、垃圾回收算法、SSM框架、Spring Boot的使用以及微服务中的核心组件和设计原则,旨在帮助开发者准备面试,深入理解Java技术栈。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Java基础

(一)集合

  • List接口:有序可重复

    • LinkedList:基于链表实现,每个元素储存本身内存地址还储存下一个元素的地址。(增删快,查找慢)

    • ArrayList:基于数组实现,每次增删都要重新创建新的数组,但数组有索引。(增删慢,查找快)

    • Vector:基于数组,线程安全相关,效率低。

  • Set接口:不可重复

    • HashSet: 储存的元素无序,不可重复,底层是哈希表

    • LinkedHashSet:储存元素有序,不可重复,底层是哈希表和链表的结合

    • TreeSet:可以指定一个顺序,对象存入之后会按照指定的顺序排序。

  • Map接口:双列集合

    • HashMap:非线程安全,高效,支持null

    • LinkedHashMap:是HashMap的一个子类,保存了记录的插入顺序

    • HashTable:线程安全,低效,不支持null

    • TreeMap:能够把他保存的记录根据键排序,默认是键值的升序排序

1.HashMap和Hashtable有什么区别?

  • 存储: HashMap 运行key和value可为null,而Hashtable不允许。

  • 线程安全: Hashtable 是线程安全的,而HashMap是非线程安全的。

2.HashMap的实现原理

  • HashMap基于Hash算法实现的,我们通过put(key,value)存储,get(key)来获取;

  • 当传入key时,HashMap 会根据key. hashCode()计算出hash值,根据hash值将value保存在bucket里;

  • 当计算出的hash值相同时,我们称之为hash冲突,HashMap 的做法是用链表和红黑树存储相同hash值的value;

  • 当hash冲突的个数比较少时,使用链表否则使用红黑树。

3.ArrayList和LinkedList的区别是什么?

  • 数据结构实现: ArrayList是动态数组的数据结构实现,LinkedList是双向链表的数据结构实现。

  • 随机访问效率: ArrayList 比LinkedList 在随机访问的时候效率要高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。

  • 增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比ArrayList效率要高,因为ArrayList增删操作要影响数组内的其他数据的下标。

  • 综合来说,在需要频繁读取集合中的元素时,更推荐使ArrayList,而在插入和删除操作较多时,更推荐使用LinkedList。

4.ArrayList和Vector的区别是什么?

  • 线程安全: Vector使用了Synchronized 来实现线程同步,是线程安全的,而ArrayList是非线程安全的。

  • 性能: ArrayList在性能方面要优于Vector。

  • 扩容: ArrayList和Vector都会根据实际的需要动态的调整容量,只不过在Vector扩容每次会增加1倍,而ArrayList只会增加50%。

5.Array和ArrayList有何区别?

  • Array 可以存储基本数据类型和对象,ArrayList 只能存储对象。

  • Array 是指定固定大小的,而ArrayList大小是自动扩展的。

  • Array内置方法没有ArrayList多,比如addAll、 removeAll、 iteration等方法只有ArrayList有。

6.哪些集合类是线程安全的?

  • Vector、Hashtable、 Stack 都是线程安全的,而像HashMap则是非线程安全的;

  • 不过在JDK 1.5之后随着Java. util. concurrent并发包的出现,它们也有了自己对应的线程安全类,比如HashMap对应的线程安全类就是ConcurrentHashMap。

(二)线程

线程三种队列

LinkedBlockingDeque(链表同步阻塞队列)、ArrayBlockingQueue(数组同步阻塞队列)、SynchronousQueue(同步阻塞队列)

1.创建线程有三种方式

  • 继承Thread重写run方法;

  • 实现Runnable接口;

  • 实现Callable 接口。

  • runnable没有返回值,callable 可以拿到有返回值,callable 可以看作是runnable的补充。

2.线程的状态:

  • NEW尚未启动

  • RUNNABLE正在执行中

  • BLOCKED阻塞的(被同步锁或者I0锁阻塞)

  • WAITING 永久等待状态

  • TIMED_ WAITING 等待指定的时间重新被唤醒的状态

  • TERMINATED执行完成

3.线程池创建有七种方式,最核心的是最后一种:

  • newSingleThreadExecutor(): 它的特点在于工作线程数目被限制为1,操作一个无界的工作队列,所以它保证了所有任务的都是被顺序执行,最多会有一一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目;

  • newCachedThreadPool(): 它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过60秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使用SynchronousQueue作为工作队列;

  • newFixedThreadPol(int nThreads):重用指定数目(nThreads) 的线程,其背后使用的是无界的工作队列,任何时候最多有nThreads个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目nThreads;

  • newSingleThreadScheduledExecutor() :创建单线程池,返 回ScheduledExecutorService,可以进行定时或周期性的工作调度;

  • newScheduledThreadPool(intcorePoolSize)和 newSingleThreadScheduledExecutor()类似创建的是个ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值