Java的特点

可移植性:

Java编译器将源代码编译成字节码(bytecode),该字节码可以在任何安装了Java虚拟机(JVM)的系统上运行

面向对象:

java 是一门面向对象的语言,几乎所有的都是对象,oop的特性使得代码易维护

内存管理:

java有自己的垃圾回收机制,自动管理和回收不再使用的对象

java的优与劣

优:oop编程 一次编译到处运行,生态完善spring等各种框架和工具

劣: 性能开销较大,启动时间不如其他原生编译语言(c++,Rust)微服务场景下,可能不如Go之类的快

JVM、JDK、JRE三者之间的关系

  • JVM是Java虚拟机,是Java程序运行的环境。JVM提供了内存管理、垃圾回收、安全性等功能,使得Java程序具备跨平台性

  • JDK是Java开发工具包,是开发Java程序所需的工具集合。JDK提供了开发、编译、调试和运行Java程序所需的全部工具和环境

  • JRE是Java运行时环境,是Java程序运行所需的最小环境。JRE不包含开发工具,只提供Java程序运行所需的运行环境

重写和重载的区别

  1. 重载发生在本类,重写发生在父类与子类之间

  2. 重载方法名必须相同,参数列表不同 ;重写的方法名相同且返回值类型必须相同,参数列表也必须相同

  3. 构造方法不能被重写

接口和抽象类的区别

  1. 接口要被实现 implement 抽象类要被子类继承

  2. 接口可以被多继承(多是实现)抽象类只能够单继承

  3. 接口不能有构造方法,只有声明变量(final修饰) 抽象类可以有构造器,可以有成员变量

  4. 抽象类不能被 new instance 不能被实例化 ,它和普通的java类没有区别

  5. 接口只能是public 修饰 抽象类方法可以有 public default protected

浅拷贝和深拷贝的理解

两者都是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用

:指挥拷贝基本数据类型的值,以及实例对象的引用地址,并不会复制一份引用地址所指向的对象

:既会拷贝基本数据类型,也会针对实例对象的引用地址所指向的对象进行复制,深拷贝出来的对象,内部类指向的不是同一个对象

两者的实现方法:

//浅
//直接**.clone()**即可,也可以实现 Cloneable 接口并简单重写 clone() 方法
​
//实现 Cloneable 接口
​
class Address implements Cloneable {
    private String street;
    
    public Address(String street) { this.street = street; }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 浅拷贝 Address 对象
    }
//深 重写clone()方法后,手动实现深拷贝
//City 是最内层的对象,只需要实现基本的浅拷贝 Address 包含 City 对象,因此需要在 clone() 中递归拷贝 City
class City implements Cloneable {
    private String name;
​
    public City(String name) {
        this.name = name;
    }
​
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 浅拷贝 City(仅复制 name 字段)
    }
}
class Address implements Cloneable {
    private String street;
    private City city;
​
    public Address(String street, City city) {
        this.street = street;
        this.city = city;
    }
​
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 1. 先调用父类 clone() 复制基本类型(street)
        Address cloned = (Address) super.clone();
        // 2. 递归拷贝引用类型(city):调用 City 的 clone() 方法
        cloned.city = (City) this.city.clone();
        return cloned;
    }
}

sleep 和 wait 的区别

方法 定义 常见用途
wait() 释放锁并且进入等待状态,直到被其他线程 notify()notifyAll() 唤醒 线程间协作,等待某个条件的发生
sleep() 暂停当前线程一段时间,但不释放锁 模拟延迟,控制线程执行节奏

区别:

特性 wait() sleep()
所属类 Object Thread
锁释放 释放当前锁 不释放锁
唤醒方式 notify()/notifyAll() 唤醒 固定时间后自动唤醒
使用场景 线程协作(等待条件) 简单延迟
同步要求 必须在同步块(synchronized)中调用 可在任何位置调用

wait() 用法(生产者-消费者)

public class ProducerConsumer {
    private final Object lock = new Object();
    private boolean resourceAvailable = false;
​
    public void produce() throws InterruptedException {
        synchronized (lock) {
            while (resourceAvailable) {
                lock.wait(); // 等待消费者消费,释放锁
            }
            // 生产资源
            resourceAvailable = true;
            lock.notify(); // 唤醒消费者
        }
    }
​
    public void consume() throws InterruptedException {
        synchronized (lock) {
            while (!resourceAvailable) {
                lock.wait(); // 等待生产者生产,释放锁
            }
            // 消费资源
            resourceAvailable = false;
            lock.notify(); // 唤醒生产者
        }
    }
}

sleep() 用法(简单延迟)

  Thread.sleep(1000); // 延迟 1 秒,不释放锁
 

自动拆装箱,int和 Integer 有什么区别

自动装箱(Autoboxing)自动拆箱(Unboxing) 是 Java 为了简化基本类型和包装类型之间的转换而引入的机制

为什么会有这个功能呢?主要是用于java集合中,

List<Inteter> list=new ArrayList<Integer>();list集合如果要放整数的话,只能放对象,不能放基本类型,因此需要将整数自动装箱成对象

自动装箱(Autoboxing):将 基本类型 转换为 对应的包装类型。int primitiveInt = 10; Integer wrappedInt = primitiveInt;

自动拆箱(Unboxing):将 包装类型 转换为 对应的基本类型。Integer wrappedInt = 20; int primitiveInt = wrappedInt;

Integer缓存 机制

Integer-128 到 127 之间的值会 缓存,在这个范围内的 Integer 对象会复用已有实例,超出这个范围的值则会创建新的实例。

==和equals区别

特性 == equals()
比较内容 比较引用地址(基本类型比较值) 默认比较引用地址,可重写后比较
适用类型 基本数据类型和引用类型 仅适用于引用类型
性能 更快 较慢(涉及方法调用)
可重写性 不可重写 可在类中重写
空指针安全 安全 可能抛出 NullPointerException

String*特殊情况*

虽然 String 是引用类型,但在某些情况下可以直接使用 == 进行比较,这是因为 String 具有常量池机制。但String还是建议使用.equals()去比较字符串,也可使用Objects.equals()避免空指针异常。

String 常量池(String Constant Pool)是 Java 在方法区(JDK 7+ 是堆)中专门为字符串优化的内存区域。

主要特点:

  • 相同内容的字符串只存储一份,节省内存。

  • 编译时确定的字符串会自动放入常量池。

  • 运行时可以手动将字符串添加到常量池中。

public class StringPoolExample {
    public static void main(String[] args) {
        String s1 = "hello";       // 存入常量池
        String s2 = "hello";       // 复用常量池中的 "hello"
        String s3 = new String("hello");  // 创建新对象,不在常量池
        String s4 = s3.intern();   // 将 s3 放入常量池
    System.out.println(s1 == s2);  // true, 指向常量池同一地址
    System.out.println(s1 == s3);  // false, 不同引用
    System.out.println(s1 == s4);  // true, intern() 返回常量池中的引用
}
}

StringBuffer 和 StringBuilder
StringBufferStringBuilder 是 可变字符串类,用于处理需要频繁修改字符串的场景

拼接、插入、删除

特性 StringBuffer StringBuilder
线程安全性 线程安全(方法用 synchronized 同步) 非线程安全(无同步机制)
性能 多线程环境下安全,但单线程有额外同步开销 单线程环境下更快(无同步开销)
适用场景 多线程共享变量的字符串操作 单线程下的字符串操作(如循环拼接)
历史背景 JDK 1.0 就存在 JDK 5.0 新增(弥补 StringBuffer 单线程低效)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐