📦 模块一:面向对象深入(⭐⭐⭐⭐⭐ 必考)

怎么理解面向对象?封装、继承、多态简单说说

面向对象:把现实世界中的事务抽象为对象

封装、继承、多态

封装:指将对象的属性(数据)和行为(方法)结合在一起,对外隐藏对象的内部细节,仅通过对象提供的接口与外界交互。

继承和多态:

继承 :子类自动共享父类数据结构和方法的机制

多态:多态是指允许不同类的对象对同一消息作出响应。

img

多态体现在哪几个方面?解决了什么问题?

重载 重写 和 接口与实现

重载 : 同名方法中不同的参数,根据传入参数的不同 不一样的实现

重写 : 子类 对父类的方法进行 改造实现

接口与实现:

多态也体现在接口的使用上,多个类可以实现同一个接口,并且用接口类型的引用来调用这些类的方法。这使得程序在面对不同具体实现时保持一贯的调用方式。 ◦ 示例:多个类(如 Dog, Cat)都实现了一个 Animal 接口,当用 Animal 类型的引用来调用 makeSound 方法时,会触发对应的实现。

向上转型 和向下转型

可以使用父类类型的引用指向子类对象,这是向上转型。通过这种方式,可以在运行时期采用不同的子类实现。

Map<String,String> a= new HashMap<String,String>();

◦ 向下转型是将父类引用转回其子类类型,但在执行前需要确认引用实际指向的对象类型以避免 ClassCastException

要确认这个 a 的对象到底是不是子类类型

值传递和引用传递的区别?Java到底是哪种

Java只有值传递,传递的是引用的副本

面向对象的设计原则你知道有哪些吗

原则一句话理解技术类比
SRP 单一职责一个类只做一件事Unix 工具链:grep 只搜索,sort 只排序,wc 只计数
OCP 开放封闭加新功能不改旧代码VS Code 插件:加新功能装扩展,不用改编辑器内核
LSP 里氏替换子类能无缝替代父类USB 规范:任何品牌的 U 盘插进 USB 口都能用
ISP 接口隔离接口要小而专微服务 API:用户服务只暴露用户接口,不暴露支付接口
DIP 依赖倒置依赖抽象不依赖具体操作系统驱动层:OS 通过驱动接口控制硬件,不直接操作硬件
LoD 最少知识只和直接朋友打交道网络 OSI 模型:应用层只跟传输层交互,不直接碰物理层

模块二:数据类型与运算细节(⭐⭐⭐⭐ 高频)

为什么金融计算用BigDecimal不用double

double 是二进制近似值,天生不精确;遇到0.1 这样的数只能用不断的近似

BigDecimal 是十进制精确值,

BigDecimal 内部只存两样东西:

  1. unscaled value(无标度值):一个超大整数

  2. scale(标度 / 小数点位数):小数点在第几位

存放12.34

1,先存1234 的一个整数 unscaledValue

2.小数 1 scale

模块三:核心关键字与修饰符(⭐⭐⭐⭐⭐ 必考)

final / static

static :修饰类的成员(变量、方法、代码块)和内部类 ,将成员与类本身关联,而非与类的实例(对象)关联

关键字含义归属数量能否修改
static静态只有 1 份可改
final最终变量 / 方法 / 类不可改 / 不可重写 / 不可继承
static final全局常量只有 1 份不可改

static 能不能访问非 static?

不能,因为 static 先存在,非 static 属于对象

final 变量必须初始化吗?

必须,声明时或构造器里

static 方法能不能重写?

不能,静态方法属于类,没有多态

String 为什么是 final?

安全、不可变、缓存哈希值

模块四:异常处理机制(⭐⭐⭐⭐⭐ 必考)

throwthrows 的区别?为什么有时不用throws

throw:方法里,真扔出一个异常对象

throws:方法头,声明我可能会扔异常

// throws:声明我可能抛 IOException
public void readFile() throws IOException {
    // throw:真的抛出异常对象
    throw new IOException("文件找不到");
}

Java异常体系分类(Error/Exception、Checked/Unchecked)

img

Throwable 是所有异常类的父类

Error (错误): 表示运行环境的错误,

Exception (异常): 表示程序本身可以处理的异常情况。

非运行时异常(受检异常,Checked Exception): 这类异常在编译时就必须被捕获或者声明抛出。

运行时异常(非受检异常,Unchecked Exception 或 RuntimeException): 这类异常特指 RuntimeException 及其子类。

  1. try{return "a"} finally{return "b"} 返回什么?为什么?

    (经典坑题:返回"b",finally覆盖try返回值)

📜 模块五:Object类与泛型基础(⭐⭐⭐⭐⭐ 必考)

  1. Object类有哪些常用方法? ⭐⭐⭐⭐⭐

方法作用
getClass()获取运行时类对象
hashCode()获取哈希码值
equals()判断对象是否相等
toString()转为字符串形式
clone()实现对象浅克隆
wait()线程等待释放锁
notify()唤醒单个等待线程
notifyAll()唤醒全部等待线程
finalize()GC 回收前执行(废弃)

== 与 equals 有什么区别?

== 比较地址 equlas 比较内容

== 在 Java 里其实是个非常简单粗暴的比较方式。如果你比较的是基本数据类型(比如 int、double),那它就直接比数值是不是相等,这个没啥问题。 但如果你比较的是对象(引用类型),那 == 比较的就不是对象里面装的内容了,而是比较这两个变量是不是指向内存中同一个对象,也就是地址是否相同。

String a = new String("hello");
String b = new String("hello");
​
System.out.println(a == b);  // 输出 false

== 在 Java 里其实是个非常简单粗暴的比较方式。如果你比较的是基本数据类型(比如 int、double),那它就直接比数值是不是相等,这个没啥问题。 但如果你比较的是对象(引用类型),那 == 比较的就不是对象里面装的内容了,而是比较这两个变量是不是指向内存中同一个对象,也就是地址是否相同。

String a = new String("hello");
String b = new String("hello");
​
System.out.println(a.equals(b));  // 输出 true
​

这里有个经典的面试陷阱,就是字符串常量池的问题。

String c = "hello";
String d = "hello";
​
System.out.println(c == d);  // 输出 true

这里为什么 == 比较也是 true 呢?因为当你直接用双引号创建字符串的时候,JVM 会把它扔到一个叫"字符串常量池"的地方。如果池子里已经有了 "hello",那 d 就直接复用 c 指向的那个对象,所以它俩地址是一样的,== 自然就返回 true 了。

2.hashCode()equals() 的关系?重写规范是什么?

如果两个对象equals 相等,它们的hashCode 必须相等

如果两个对象hashCode 相等,equals不一定相等(哈希碰撞)

如果 equals 不相等,hashCode可同可不同

规范:

重写equals()必须同时重写hashCode()

参与equals比较的属性,全部参与 hashCode 计算

保证属性相同的对象,哈希值一致

尽量让不同属性对象生成不同哈希值,减少碰撞

不遵守后果

存入HashSet、HashMap等哈希集合,会出现去重失败、查询不到数据

3.什么是泛型?类型擦除是什么?

4.String、StringBuffer、StringBuilder的区别和联系

特性StringStringBuilderStringBuffer
不可变性不可变可变可变
线程安全是(不可变保证)是(同步)
性能
适用场景静态字符串单线程频繁修改多线程频繁修改

// String的不可变性
String str = "abc";
str 
= str + "def"; // 新建对象,str指向新对象
​
// StringBuilder(单线程高效)
StringBuilder sb = new StringBuilder();
sb
.append("abc").append("def"); // 直接修改内部数组
​
// StringBuffer(多线程安全)
StringBuffer sbf = new StringBuffer();
sbf
.append("abc").append("def"); // 同步方法保证线程安全

🔍 模块六:反射、注解与对象创建(⭐⭐⭐ 进阶基础)

反射:

出现反射的历史原因:

解决的核心问题

实现框架底层逻辑

Spring、Mybatis、注解、动态代理等主流框架,全靠反射实现自动化。

统一通用操作

写一套代码,适配所有实体类,实现通用赋值、对象拷贝。

什么是反射

img

正常写法:编译期写死new 类名(),固定调用方法。

Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。

public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, ClassNotFoundException, InstantiationException {
    // 使用反射机制,根据这个字符串获得Class对象
    Class<?> c = Class.forName(getName("className"));
    System.out.println(c.getSimpleName());
    // 获取方法
    Method method = c.getDeclaredMethod(getName("methodName"));
    // 绕过安全检查
    method
.setAccessible(true);
    // 创建实例对象(Class.newInstance() 已过时,使用 Constructor.newInstance())
    TestInvoke testInvoke = (TestInvoke) c.getDeclaredConstructor().newInstance();
    // 调用方法
    method
.invoke(testInvoke);
​
}

应用场景 Spring IOC、MyBatis映射、JSON序列化

注解:

原理: 注解本质是一个 继承了 Annotation的特殊接口

元注解(修饰注解的注解)

  1. @Target:注解能用在类 / 方法 / 属性哪里

  2. @Retention

    核心

    ,控制注解存活阶段

    • SOURCE:只源码存在,编译丢弃

    • CLASS:编译存在,运行丢弃(默认)

    • RUNTIME:运行时保留,反射能读取

  3. @Documented:生成文档

  4. @Inherited:子类继承父类注解

class="copy-panel" id="text-panel-iframe" src="chrome-extension://ipodhnfligecindaieefnaafgajiceoj/panel.html" style="position: fixed; width: 200px; height: 300px; z-index: 999999; background: white; box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 1px; right: 10px; top: 50%; border-width: medium; border-style: none; border-color: currentcolor; border-image: initial; margin: 0px; padding: 0px; overflow: hidden; transform: translateY(-50%);">

更多推荐