Java 基础面试题集

Java 基础面试题集

语言基础

  1. Java 中 ==equals() 方法有什么区别?

    • 【==是比较两个引用是否执行同一个对象(内存地址)
    • 基本类型比较值(int char double)
    • equale() 定义在Object 里面 默认实现和==一致,通常被类重写(String Integer ArrayList)用来比较内容是否相同,更适合对象见内容比较】
  2. String, StringBuilder, 和 StringBuffer 有什么区别?它们各自适用于什么场景?

    • 【String 不可变的字符串 每次修改都会创建新的字符串对象 不会改变原有的字符串内容 线程安全 适用场景 字符串内容不经常变化 多线程下共享使用 配置常量 参数名
    • StringBuilder 可变字符串 内部使用字符串数组存储 效率高 非线程安全 适用场景 字符串频繁修改 单线程场景 生成SQL 动态HTML
    • StringBuffer 可变字符串 与**StringBuilder**相同API 但是方法加了synchronized 性能比较低 适用场景: 多线程并发修改字符串
  3. Java 中的基本数据类型有哪些?它们对应的包装类是什么?为什么需要包装类?

    • 基本类型包装类(Wrapper Class)
      byteByte
      shortShort
      intInteger
      longLong
      floatFloat
      doubleDouble
      charCharacter
      booleanBoolean
      1. 集合类不能使用基本类型
      2. 提供了很多实用方法,包装类中提供了很多静态方法,例如字符串转数字
      3. 有些场景需要将基本类型作为对象传递,例如在泛型、反射、序列化、缓存等机制中。
  4. 简述 Java 中的自动装箱(Autoboxing)和自动拆箱(Unboxing),并说明可能带来的性能问题。

    • 名称含义
      自动装箱将基本类型自动转换为对应的包装类对象
      自动拆箱将包装类对象自动转换为对应的基本类型
    • 频繁装箱创建大量临时对象

    • 空对象拆箱导致空指针异常

    • 包装类使用 == 比较容易出错

  5. final 关键字在 Java 中可以修饰什么?分别有什么作用?

    • 修饰对象含义 / 作用
      变量(局部变量、成员变量、参数)值一旦赋值后不可改变
      方法子类不能重写该方法
      不能被继承
  6. static 关键字在 Java 中可以修饰什么?分别有什么作用?

    • 可修饰的对象作用说明
      变量(字段)所有对象共享同一个静态变量,称为静态变量(类变量)
      方法不依赖对象,可以通过类名直接调用,称为静态方法
      代码块在类加载时执行一次,称为静态代码块
      内部类(嵌套类)不依附外部类实例存在,可直接通过类名访问,称为静态内部类
  7. 解释 Java 中的访问权限修饰符:public, protected, default (包访问权限), private

    • 修饰符当前类同包(default)子类(不同包)其他包
      public
      protected
      default(无修饰)
      private

面向对象 (OOP)

  1. 面向对象的三大基本特征是什么?请简要解释每个特征。

    • 封装(Encapsulation)
      将数据(属性)和操作数据的方法(行为)绑定在一起,隐藏内部实现细节,仅通过公开的方法与外部交互。这样可以保护对象的状态不被随意更改,增强程序的安全性和可维护性。

      继承(Inheritance)
      子类可以继承父类的属性和方法,代码复用性高。Java 中使用 extends 关键字实现继承,支持单继承。继承也为实现多态打下基础。

      多态(Polymorphism)
      同一个方法调用在不同对象上可以表现出不同的行为(即“一个接口,多种实现”)。多态分为编译时多态(方法重载)和运行时多态(方法重写+动态绑定)。

  2. 什么是多态?Java 中如何实现多态?

    • 多态的定义:
      指同一个方法在不同对象上表现出不同的行为。多态提高了代码的扩展性和可维护性。

      Java 实现多态的方式有两种:

      1. 编译时多态(静态多态): 方法重载(Overloading)——同一个类中方法名相同但参数不同;
      2. 运行时多态(动态多态): 方法重写(Overriding) + 父类引用指向子类对象。
  3. 抽象类(abstract class)和接口(interface)有什么区别?在 Java 8 之后接口有什么新特性?

    • 特性抽象类 (abstract class)接口 (interface)
      是否支持方法体可以有抽象方法和普通方法Java 8 之前只能有抽象方法
      是否支持构造函数✅ 有构造器❌ 无构造器
      是否支持成员变量可以有成员变量(非 final只能有 public static final 常量
      多继承支持只能继承一个类可以实现多个接口
      是否可被实例化❌ 不可以❌ 不可以

      Java 8 之后接口新增特性:

      • 默认方法(default method): 接口可以包含具有默认实现的方法。
      • 静态方法(static method): 接口中可以定义静态工具方法。
      • Java 9 起还支持私有方法(用于辅助 default 或 static 方法复用代码)。
  4. 重载(Overload)和重写(Override)的区别是什么?

    • 比较点方法重载(Overload)方法重写(Override)
      定义位置同一个类中父类和子类之间
      方法名必须相同必须相同
      参数列表必须不同(数量或类型)必须完全相同
      返回类型可以不同(但不能仅靠它区分)必须相同或是父类返回类型的子类(协变返回类型)
      访问修饰符限制无限制子类不能降低访问权限
      异常抛出可任意子类方法不能抛出比父类方法更宽的异常

异常处理

  1. Java 中的异常体系结构是怎样的?ErrorException 有什么区别?

    • 【Java 异常体系结构(从 Throwable 开始):

      php复制编辑            Throwable
                     /   \
                 Error   Exception
                           /    \
             CheckedException  RuntimeException
      
      ✅ 区别:
      对比项ErrorException
      继承自ThrowableThrowable
      是否可捕获通常不捕获推荐捕获处理
      是否可恢复❌ 不可恢复,表示系统级问题✅ 通常是可预见、可恢复的问题
      常见子类OutOfMemoryErrorStackOverflowErrorIOExceptionSQLExceptionNullPointerException
      处理建议交给 JVM 处理程序员应处理(尤其是受检异常)
      ✅ Checked vs Unchecked 异常:
      • Checked Exception(受检异常):继承自 Exception 但不是 RuntimeException,如 IOExceptionSQLException,必须显式捕获或声明。
      • Unchecked Exception(运行时异常):继承自 RuntimeException,如 NullPointerExceptionIndexOutOfBoundsException,可以不强制捕获。
  2. try-catch-finally 块的作用是什么?finally 块一定会被执行吗?

    • 【✅ 作用说明:

      • try: 包含可能抛出异常的代码块;
      • catch: 捕获并处理 try 中发生的异常;
      • finally: 无论是否发生异常,都会执行,用于资源释放(如关闭连接、流等)。
      finally 块的执行情况:
      • 一般情况下 一定会执行
      • 即使 trycatch 中有 return 语句,finally 仍会在返回前执行
      • 只有极少数情况下不会执行
        • 程序在执行过程中被强行中止(如 System.exit(0)
        • JVM 崩溃或掉电等异常终止
        • 当前线程被杀死等
  3. throwthrows 有什么区别?

    • 对比项throwthrows
      作用主动抛出异常对象声明方法可能抛出的异常
      使用位置方法体内部方法声明处
      后面跟的内容是一个异常对象是异常类型(类名)
      数量只能抛出一个异常对象可声明多个异常类型,用逗号隔开

集合框架 (Collections Framework)

  1. 请简述 Java 集合框架的主要接口(如 Collection, List, Set, Map, Queue)及其常见实现类(如 ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap)。

    • 【✅ Java 集合体系结构:

      mathematica复制编辑             ┌────────── Collection(根接口) ─────────┐
                   ↓                                        ↓
                 List                                     Set
                 ↓                                        ↓
         ArrayList, LinkedList                    HashSet, TreeSet, LinkedHashSet
      
                   ┌────────── Map(键值对集合) ─────────────┐
                   ↓                                        ↓
               HashMap, TreeMap, LinkedHashMap        ConcurrentHashMap
      
                   ┌──────────── Queue(队列) ──────────────┐
                   ↓                                        ↓
              LinkedList, PriorityQueue, ArrayDeque      BlockingQueue 等
      
      ✅ 简要说明:
      接口/类特点
      Collection单列集合的根接口,子接口有 ListSetQueue
      List有序、可重复,如:ArrayListLinkedList
      Set无序、不可重复,如:HashSetTreeSet
      Map存储键值对,如:HashMapTreeMap
      QueueFIFO 队列,如:LinkedListPriorityQueue
  2. ArrayListLinkedList 有什么区别?它们各自适用于什么场景?

    • 对比项ArrayListLinkedList
      底层结构动态数组双向链表
      查找效率高,支持索引随机访问低,需遍历节点
      插入删除效率低,中间插入需移动元素高,修改指针即可
      内存占用较小(仅数据)较大(数据 + 前后指针)
      适合场景读多写少,随机访问写多读少,频繁插入/删除
  3. HashSet 是如何保证元素唯一性的?HashMap 的底层实现原理是什么?(涉及哈希表、哈希冲突解决)

    • HashSet 唯一性原理:

      • HashSet 内部是通过 HashMap 实现的。

      • 添加元素时,作为 key 存入 HashMap,值是一个固定对象 PRESENT

      • 所以唯一性依赖于 hashCode()equals()

        HashMap 底层原理(JDK 8+):
        1. 底层是数组 + 链表 + 红黑树结构;
        2. 根据 key.hashCode() 计算哈希值;
        3. 再通过哈希值定位数组下标(index = (n - 1) & hash);
        4. 发生哈希冲突时:
          • JDK7:使用链表
          • JDK8:链表长度超过 8 且数组长度 > 64,转为红黑树
        5. 扩容:当元素个数 > 负载因子(默认 0.75)× 容量时触发扩容为原来的两倍。
  4. HashMapHashtable 有什么区别?ConcurrentHashMap 是如何实现线程安全的?

    • 对比项HashMapHashtableConcurrentHashMap
      线程安全❌ 非线程安全✅ 方法加同步锁(synchronized)✅ 分段锁/红黑树/CAS
      是否支持 null✅ 允许 null 键/值❌ 不允许 null 键或值❌ 不允许 null 键或值
      性能高(单线程)低(全锁)较高(支持并发)
      适合场景单线程老版本线程安全需求多线程并发高效访问
      ConcurrentHashMap 线程安全实现方式:
      • JDK7:Segment(分段锁)
      • JDK8:取消 Segment,使用数组 + 链表/红黑树 + CAS + synchronized 实现精细化锁
      • 支持更高并发性能
  5. ComparableComparator 接口有什么区别?

    • 对比项ComparableComparator
      包名java.langjava.util
      使用方式被比较对象实现接口单独创建比较器
      方法int compareTo(T o)int compare(T o1, T o2)
      适合场景自然排序(类内定义)多种排序方式(类外定义)
      是否修改类✅ 需要修改类❌ 不修改原类
      示例TreeSetCollections.sort() 可直接用Collections.sort(list, comparator)

并发编程 (Concurrency)

  1. 什么是线程(Thread)和进程(Process)?它们之间有什么区别?

    • 【1. 什么是线程(Thread)和进程(Process)?它们之间有什么区别?
      • 进程是系统资源分配的基本单位,每个进程有独立的内存空间和系统资源。
      • 线程是进程中的执行单元,一个进程可以包含多个线程,共享进程内存和资源。
      • 区别:
        • 进程间相互独立,通信较复杂;线程共享进程资源,通信更方便但需同步。
        • 进程切换开销大,线程切换开销相对较小
  2. 创建线程有哪几种方式?推荐使用哪种方式,为什么?

    • 方式一:继承 Thread
    • 方式二:实现 Runnable 接口
    • 方式三:实现 Callable 接口 + FutureTask
    • 方式四:线程池(ExecutorService)管理线程(推荐)

    推荐使用实现 RunnableCallable 并结合线程池,因为:

    • 避免单继承限制,增强灵活性;

    • 线程池能复用线程,提升性能,便于统一管理和资源控制。

  3. 简述 synchronized 关键字的用法(修饰实例方法、静态方法、代码块)及其作用原理(监视器锁/Monitor)。

    • 【**修饰实例方法:**锁住当前实例对象(this)。
    • **修饰静态方法:**锁住类的 Class 对象。
    • **修饰代码块:**锁住括号里的对象。

    **作用原理:**基于对象监视器(Monitor),同一时刻只有一个线程持有该锁,其他线程阻塞等待。

  4. volatile 关键字有什么作用?它能保证原子性吗?

    • 【**作用:**保证变量的可见性和防止指令重排序。

      **不保证原子性:**对 volatile 变量的复合操作(如 i++)仍非原子操作。

  5. 什么是线程安全?如何保证线程安全?(列举几种方法)

    • 【**线程安全:**多线程环境下,代码执行结果不受线程调度顺序影响。
    • 保证方式:
      • 使用 synchronizedLock 锁机制;
      • 使用原子类(AtomicInteger 等);
      • 使用线程安全的集合(ConcurrentHashMap);
      • 避免共享变量(如使用局部变量);
      • 不可变对象设计。

其他

  1. Java 中的 Object 类有哪些常用方法?请说明 hashCode()equals() 方法之间的关系。

    • 【常用方法有:equals(), hashCode(), toString(), clone(), finalize(), getClass()

      关系:相等的对象必须具有相同的 hashCode(),否则哈希集合无法正确工作。

  2. Java 的反射(Reflection)是什么?有什么优缺点?

    • 【Java 反射(Reflection)是什么?优缺点?
      • **定义:**运行时动态获取类信息、创建对象、调用方法、访问字段的机制。
      • **优点:**灵活,适合框架开发(如 Spring)。
      • **缺点:**性能开销大,代码复杂,破坏封装。
  3. String s = new String("abc"); 这行代码创建了几个对象?分别是什么?

    • 【3. String s = new String("abc"); 创建几个对象?
      • 2个对象:
        • 字符串常量池中的 "abc"(已存在或新建)
        • 堆内存中新建的 String 对象 s
  4. Java 中的 IO 流分为哪两大类?请列举一些常用的流类。

    • 两大类:

      • 字节流(InputStream / OutputStream
      • 字符流(Reader / Writer

      常用流:

      • 字节流:FileInputStreamFileOutputStreamBufferedInputStreamBufferedOutputStream
      • 字符流:FileReaderFileWriterBufferedReaderBufferedWriter
  5. Java 中的泛型(Generics)是什么?有什么作用?

    • 【**定义:**Java 泛型允许定义类、接口、方法时使用类型参数,实现代码复用。

      **作用:**提供类型安全,避免强制类型转换,提高代码可读性。

  6. (设计题)如何实现一个单例(Singleton)模式?请写出一种线程安全的实现方式。

    • public class Singleton {
          private Singleton() {}
      
          private static class Holder {
              private static final Singleton INSTANCE = new Singleton();
          }
      
          public static Singleton getInstance() {
              return Holder.INSTANCE;
          }
      }
      
      
      • 利用静态内部类的延迟加载和类加载机制保证线程安全,且性能好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中國移动丶移不动

码农

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值