当前位置: 首页 > news >正文

2026-02-17学习

2026-02-17 学习

一、Java 基础面试题

1、为什么 Java 不支持多继承?

因为这是为了避免菱形问题,假如现在 A 有一个 doGet() 方法,这时 B 和 C 同时去继承 A 并重写里面的方法,然后 D 同时去继承 B 和 C,

那么是该重写 B 里面的方法呢,还是重写 C 里面的方法呢?这样就出现了一个歧义

为什么接口就能进行多实现呢?

因为在 Java 8 之前,是没有方法体的,方法都是抽象方法,方法必须由子类自己去实现,所以不会有歧义,代码如下:

public interface A {void get();
}
public interface B {void get();
}
public class C implements A, B{@Overridepublic void get() {System.out.println("你好"); // 子类自己去实现}
}

但是在 Java 8 之后,引入了 default 方法,接口拥有了方法体,那么这时就需要强制子类去选择某个父类的方法或者自己去实现,代码如下:

public interface A {default void delete() {System.out.println("删除 A");}
}
public interface B {default void delete() {System.out.println("删除 B");}
}
public class C implements A, B{@Overridepublic void delete() {A.super.delete(); // 强制选择一个父类去实现System.out.println("删除C"); // 自己实现}
}

2、Java 8 有哪些特性?

这个我觉得你说几个自己比较熟的几个就可以了,没必要说的很多

1)Lambda 表达式

2)引入接口默认方法和静态方法

3)Optional 类,专门处理 null 值

4)Steam API,这个如果看过 Spark 的语法就知道,在数据处理方面用的很多

3、Java 17 有哪些特性?

1)Sealed 引入,打破了“要么全部继承,要么全部禁止继承”,可以使用 permits 关键字来指定继承哪几个类。

2)这个不算特性,就是现在很多 AI 的版本最少都是 JDK 17,比如 LangChain4j 和 Spring AI,官网显示最低都是 JDK 17

4、Java 中 String、StringBuilder、StringBuffer 的区别是什么?

String 是不可变类,类用 final 修饰,并且 char 数组也被 final 修饰,每次创建对象都是创建一个新的对象

StringBuffer 和 StringBuilder 都是可变的,底层都是动态可扩容的数组。StringBuffer 由 synchronized 修饰,线程安全;StringBuilder

没有被修饰,线程不安全

该如何去选择呢?

1)如果字符串不拼接或者少量拼接,则使用 String

2)单线程需要大量拼接操作,就选择 StringBuilder

3)多线程需要拼接操作,就选择 StringBuffer

5、Java 中 StringBuilder 是怎么实现的?

StringBuilder 底层就是一个可变的动态数组和一个 count 变量,将追加的内容转换为字符,然后看整个数组的容量,容量不够就进行扩容操作,

扩容的量为原来数组长度的两倍 + 2,然后添加到数组的末尾,并且更新 count 值。如果频繁扩容的话,对性能消耗也挺大的,所以最好预估一下

那 StringBuilder 有缩容操作吗?

并没有,只有扩容操作,没有缩容操作,如果数组长度进行扩容后,执行 delete 删除,数组长度还是扩容后的长度,不会因为 delete 删除掉一

些字符之后就进行缩容操作。

那为什么扩容是 2 倍 + 2 呢?

2 倍的原因是为了均摊复杂度,确保每次扩容翻倍的总扩容次数为 O(log n)。

+2 的原因主要为了处理边界情况,如果初始容量为 0, 那么容量 * 2 岂不是还是为 0,所以这时 +2 就处理了边界情况

6、Java 中 hashcode 和 equals 方法是什么?它们与==操作符有什么区别?

hashcode、equals 和 == 都是三种不容层次的比较方式:

== 比较的是内存地址,看两个引用是不是指向堆的同一块内存。但是对于基本数据类型,对比的是值。

equals 比较的是对象的内容

hashcode 主要是在集合中快速定位哈希槽的位置。哈希码不同,对象肯定不相等;哈希码不相同,对象不一定相等

7、Java 中的 hashcode 和 equals 方法之间有什么关系?

关系如下:hashcode 相同,equals 不一定相同;hashcode 不同,equals 一定不同;equals 相同,hashcode 一定相同

为什么会这样呢?这是因为在 HashMap 在寻找 key 的时候,先使用 hashcode 定位哈希槽,然后再利用 equals 来进行精准匹配。如果说只重

写 equals 方法,而不去重写 hashcode 方法,那么两个相同对象的 key,可能会被分配到不同的哈希槽内,导致 HashMap 出现重复的 key

8、Java 中的注解原理是什么?

注解其实就是一个标记,可以在类、方法、变量等进行一系列信息标记处理

9、你使用过 Java 的反射机制吗?如何应用反射?

反射就是通过获取类对象,从而动态获取类的结构信息,字段,构造函数,并且可以对其进行一些操作。流程如下:

1)获取 Class 对象

2)获取对象之后,就可以动态获取 Method,Field,Constructor,并且对其进行操作

但是反射会破坏整个类的结构,因为其可以获取到 private 私有方法,安全性降低,并且大量使用反射会进行性能消耗。所以普通的代码上最好不要

频繁使用反射。但是反射的应用主要在框架中,比如 Spring 框架,通过反射机制来动态获取代理对象,并且获取配置文件来进行依赖注入和面向切

面编程等操作

10、Java 泛型的作用是什么?

泛型的作用就是将类型检查从运行时提前到编译时,在编译期就能判断类型是否匹配,好处就是代码复用,不用手动强转,类型安全

11、Java 泛型擦除是什么?

Java 泛型擦除就是在编译阶段将泛型信息进行全部抹掉的过程,代码如下:

public <T> void printList(List<T> list) {for (T element : list) {System.out.println(element);}
}

编译后:

public void printList(List list) {for (Object element : list) {System.out.println(element);}
}

为什么会有泛型擦除呢?

因为使用泛型之后,如果泛型在运行阶段也保留类型信息,那就需要重新进行编译,这样 JVM 也要进行修改,所以 Java 团队就进行了泛型擦除,

在编译阶段就直接抹掉信息,这样就不用重新编译了,老 JVM 能用,代码也不需要进行修改

12、Java 中的深拷贝和浅拷贝有什么区别?

浅拷贝就是将对象复制一遍,但是堆内存地址还是指向的同一个,只要有一个发生改变,另一个也会跟随着变化

深拷贝相当于就是重新创建了一个对象,内存地址两个完全独立,互不影响

13、什么是 Java 的 Integer 缓存池?

Integer 缓存池就是缓存一部分常见的整数对象,对于 Integer 来说,缓存池的范围一般来说是 -128 ~ 127,这个范围是可以进行调整的。如果

说对对象进行比较的时候,在这个范围之内,就直接返回,不在这个范围之内,就重新创建对象。举例如下:

Integer a = 127;Integer b = 127;System.out.println(a == b) // 输出 trueInteger a = 128;Integer b = 128;System.out.println(a == b) // 输出 false,因为超出范围了,是两个不同的对象

但是可能会有另外一个坑,就是 Integer.valueOf() 和 new Integer() 的区别是什么?

其实就是会不会触发缓存,Integer.valueOf() 是会触发缓存的,而 new Integer() 相当于创建一个新的对象,绕过缓存了

14、Java 的类加载过程是怎样的?

整个类的加载流程主要分为三大阶段:加载、连接、初始化

加载阶段就是将二进制流读进内存中,并且在堆内存中创建 Class 对象

连接阶段主要分为三个部分,验证,准备,解析。验证的话主要校验二进制流是否符合 Class 文件规范;准备阶段是给类变量进行内存分配和初始

零值分配;解析就是把常量池的符号引用替换成真正引用,符号引用就是一个字符串形式的引用,真正引用就是真正的内存地址。

初始化阶段,执行类的一个初始化逻辑,比如进行真正的赋值操作。

15、Java 中 wait() 和 sleep() 的区别?

wait() 会释放锁,只能等待 notify() 或 notifyAll() 将其唤醒

sleep() 不会释放锁,只是会睡一段时间,然后自动自己醒

16、什么是 Java 的自动装箱和拆箱?

自动转箱就是将基本数据类型转换为包装类;自动拆箱就是将包装类转换为基本数据类型

主要的好处就是自己不用显式的进行转换,Java 内部帮我们自动转,代码示例如下:

Integer a = 10;// 这里就会触发隐式的转箱,调用 Integer.valueOf() 方法
Integer a = Integer.valueOf(10);
Integer a = 10;int b = a;// 这里就会触发隐式的拆箱,调用 a.intValue() 方法
int b = a.intValue();

17、Java 中的 Optional 类是什么?它有什么用?

这个问题一个长沙的面试问到过

Optional 类就是专门用来包装可能为空的值,主要的作用就是减少空指针异常的存在。

二、复习

模拟面试

三、总结

今天比较闲,Java 基础有些忘记了,但是还得过一遍,然后也稍微放松了一下,当了下星际仓鼠,爽玩(#.#)

http://www.jsqmd.com/news/390405/

相关文章:

  • 宇树科技 CEO 王兴兴所说的“具身智能时代的牛顿还没诞生”
  • 寒假学习笔记2.4
  • 存在即对话:方见华对话本体论与世毫九理论的数学奠基、形式证明与工程实现
  • 寒假学习笔记2.3
  • 摩尔线程快速完成对Qwen3.5模型全面适配
  • 如何通过数据分析实现精准营销
  • 20260217
  • Ubuntu 上 ROS2 的安装
  • 协同过滤算法Nodejs+vue3的短视频分享网站系统
  • vcpkg的配置
  • 寒假学习笔记2.2
  • 状压+dijk |floyd
  • 寒假学习笔记2.1
  • 并查集 - ## Find them, Catch them
  • (3-2)机器人身体结构与人体仿生学:人形机器人躯干体系
  • 气泡图标注软件中文版(美式功能设计)|一键插入序号气泡图,支持CAD/PDF/图片+OCR识别+Excel报告导出
  • EncodeConvert编码转换器v2.0——高效支持GBK与UTF-8互转的汉字编码工具
  • ZProtect一机一码工具(电脑版):专为DLL/EXE文件设计的轻量级软件开发解决方案
  • 未来之窗昭和仙君(七十二)前端交互异常行为检测—东方仙盟练气
  • 冥想第一千七百九十七天(1797)
  • 冥想第一千七百九十六天(1796)
  • ROS快速入门教程:什么是SLAM(Simultaneous localization and mapping,同步定位与建图)【解决机器人在未知环境运动时的定位与地图构建问题】
  • OpenTelemetry 开发实战【左扬精讲】—— 云原生可观测体系构建与分布式追踪二次开发
  • 工业园区全域轨迹拼接与异常行为智能识别平台——跨摄像单元轨迹连续性校验 × 多帧误差补偿引擎
  • Agentic AI时代,提示工程架构师的核心竞争力是什么?
  • 如何提升企业品牌在豆包结果中的排名? - 品牌2025
  • 寒假19
  • VSCode 配置 MinGW 搭建 C++ 开发环境
  • 基于SSM的蛋糕私人订制网站[SSM]-计算机毕业设计源码+LW文档
  • 领略大数据领域数据科学的数据清洗技巧