Java基础面试题必杀技(2024最新整理版)

一、String的十万个为什么(必考!)

1.1 ==和equals()的"塑料兄弟情"

(注意啦老铁们)这俩货看着像双胞胎,实际根本不是一个妈生的!

String s1 = new String("Hello"); String s2 = new String("Hello"); String s3 = "Hello"; String s4 = "Hello"; System.out.println(s1 == s2); // false(扎心!) System.out.println(s1.equals(s2)); // true System.out.println(s3 == s4); // true(惊喜!)

!!!重点来了:

  • == 比的是内存地址(身份证号)
  • equals() 比的是内容(长相)
  • 字符串常量池是个VIP休息室,直接赋值的字符串都在这儿候着

1.2 String、StringBuffer、StringBuilder的"三国杀"

(面试官超爱问这个)这三个货的区别就像三种外卖小哥:

String StringBuffer StringBuilder
可变性 石头人 橡皮泥 橡皮泥Pro
线程安全 无所谓 安全标兵 独行侠
性能 最慢 中等 最快

敲黑板!!适用场景:

  • 字符串不变:选String(比如数据库连接地址)
  • 频繁修改且要线程安全:StringBuffer(银行转账)
  • 频繁修改但单线程:StringBuilder(本地日志处理)

二、面向对象三大法宝(OOP核心)

2.1 抽象类 vs 接口的"世纪对决"

这俩的关系就像武侠小说的正邪两派:

// 抽象类版武林秘籍 abstract class KungFu { abstract void attack(); // 必杀技 void sleep() { // 通用技能 System.out.println("打坐回血"); } } // 接口版武功秘籍 interface Magic { void spell(); // 法术攻击 default void fly() { // 默认技能 System.out.println("御剑飞行"); } }

!!!区别总结:

  • 抽象类是"is-a"关系(比如:李小龙是武术家)
  • 接口是"can-do"关系(比如:李小龙会双截棍)
  • Java8开始接口也可以有默认方法(真香!)

2.2 多态的"七十二变"

(这个容易栽跟头)看代码:

class Animal { void speak() { System.out.println("动物叫"); } } class Cat extends Animal { @Override void speak() { System.out.println("喵喵喵"); } void scratch() { System.out.println("挠你!"); } } public static void main(String[] args) { Animal myPet = new Cat(); myPet.speak(); // 喵喵喵(正确!) myPet.scratch(); // 编译报错!(惊不惊喜?) }

多态三大原则:

  1. 编译看左边(Animal有的方法才能用)
  2. 运行看右边(实际执行子类方法)
  3. 属性没有多态(永远看左边)

三、集合框架的"修罗场"

3.1 ArrayList vs LinkedList的"速度与激情"

(实际开发经常踩坑)这俩的差别就像电动车和跑车:

ArrayList LinkedList
底层结构 动态数组 双向链表
随机访问 O(1)(闪电侠) O(n)(乌龟爬)
头尾插入
内存占用 较少 较多(每个节点带指针)

真实案例:某电商平台用ArrayList存百万级订单数据,结果分页查询卡成狗→换成LinkedList更卡→最终用数据库分页+缓存解决(血泪教训!)

3.2 HashMap的"八卦阵"

(面试必问!)JDK8的HashMap结构大升级:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

!!!灵魂拷问:

  • 为什么链表长度>8转红黑树?(答:统计学概率,泊松分布)
  • 扩容机制是怎样的?(答:2倍扩容,rehash)
  • 线程安全吗?(答:不是,要用ConcurrentHashMap)

四、异常处理的"求生指南"

4.1 try-with-resources黑科技

(拯救无数程序员)传统写法vs炫酷写法:

// 传统写法(容易漏关流) FileInputStream fis = null; try { fis = new FileInputStream("data.txt"); // 处理文件 } finally { if (fis != null) { fis.close(); // 可能又抛异常! } } // 炫酷写法(自动关流) try (FileInputStream fis = new FileInputStream("data.txt"); ZipInputStream zis = new ZipInputStream(fis)) { // 自动关闭所有资源 }

!!!使用条件:

  • 资源必须实现AutoCloseable接口
  • 多个资源按声明顺序反向关闭

五、多线程的"角斗场"

5.1 synchronized的"三重境界"

(并发编程基础)锁的进化史:

// 第一重:普通方法锁 public synchronized void method() {} // 第二重:代码块锁 public void method() { synchronized(this) {} } // 第三重:类级别锁 public void method() { synchronized(MyClass.class) {} }

5.2 volatile的"读心术"

(容易误解的关键字)三大特性:

  1. 可见性(修改立刻可见)
  2. 禁止指令重排序
  3. 不保证原子性(所以不能替代锁)

典型应用场景:状态标志位

class Worker implements Runnable { private volatile boolean running = true; public void run() { while (running) { // 干活... } } public void stop() { running = false; } }

六、JVM内存模型的"密室逃脱"

6.1 内存结构图

(面试常考脑补题)

┌───────────────────────┐ │ Method Area │ │ (类信息、常量、静态变量) │ ├───────────────────────┤ │ Heap │ │ (对象实例) │ ├───────────────────────┤ │ Stack │ │ (局部变量、方法调用) │ ├───────────────────────┤ │ Program Counter │ │ (线程执行位置) │ ├───────────────────────┤ │ Native Method Stack │ │ (本地方法调用) │ └───────────────────────┘

6.2 GC的"垃圾分类"

(调优必备知识)常见垃圾回收算法:

  • 标记-清除(会产生内存碎片)
  • 复制算法(新生代常用)
  • 标记-整理(老年代常用)
  • 分代收集(现在JVM主流方案)

七、新特性"尝鲜区"

7.1 Java17的switch表达式

(代码简洁度+++)

// 传统写法 String dayType; switch (day) { case MONDAY, FRIDAY -> dayType = "忙day"; case SATURDAY, SUNDAY -> dayType = "躺平"; default -> dayType = "普通"; } // 炫酷写法 String dayType = switch (day) { case MONDAY, FRIDAY -> "忙day"; case SATURDAY, SUNDAY -> { System.out.println("周末啦!"); yield "躺平"; // 注意这里用yield返回值 } default -> "普通"; };

面试实战技巧(划重点!)

  1. 遇到不会的问题:可以说"这个知识点我之前主要关注在应用层面,底层实现还需要再研究"(然后偷偷记下来)
  2. 手写代码时:先问清楚需求边界(比如要不要判空、处理异常)
  3. 设计题:多问面试官业务场景(并发量?数据规模?)
  4. 遇到压力面:保持微笑,把知道的清晰表达出来

最后送大家一句话:面试造火箭,工作拧螺丝。但能把螺丝拧出火箭水准的,才是真大佬!觉得有用的朋友记得点个赞(疯狂暗示)~

本文是转载文章,点击查看原文
如有侵权,请联系 lx@jishuguiji.net 删除。