Java面试宝典-java基础09

81、String,Stringbuffer,StringBuilder 的区别

在这里插入图片描述

String:
• String 类一个不可变类,一旦创就不可以修改。
• String final 类,不能被继承
• String 实现了 equals()方法和 hashCode()方法

StringBuffer:
• 继承自 AbstractStringBuilder,可变类。
• StringBuffer 线程安全
• 可以通过 append 方法动态构造数据。

StringBuilder:
• 继承自 AbstractStringBuilder,可变类。
• StringBuilder 非线性安全。
• 执行效率比 StringBuffer 高。

区别:
关于String、StringBuffer、StringBuilder的区别,从四个角度来说明。

  • 第一个,可变性。

String内部的value值是final修饰的,所以它是不可变类。所以每次修改String的值,都会产生一个新的对象。
StringBuffer和StringBuilder是可变类,字符串的变更不会产生新的对象。

  • 第二个,线程安全性。

String是不可变类,所以它是线程安全的。
StringBuffer是线程安全的,因为它每个操作方法都加了synchronized同步关键字。StringBuilder不是线程安全的,所以在多线程环境下对字符串进行操作,应该使用StringBuffer,否则使用StringBuilder

  • 第三个,性能方面。

String的性能是最的低的,因为不可变意味着在做字符串拼接和修改的时候,需要重新创建新的对象以及分配内存。
其次是StringBuffer要比String性能高,因为它的可变性使得字符串可以直接被修改最后是StringBuilder,它比StringBuffer的性能高,因为StringBuffer加了同步锁。

  • 第四个,存储方面。

String存储在字符串常量池里面。
StringBuffer和StringBuilder存储在堆内存空间。

82、Comparator 与 Comparable 有什么区别

在这里插入图片描述

1、相同点

Comparable和Comparator都是Java中用于比较对象的接口。

2、不同点

  • 接口所在包不同:java.lang.Comparable、java.util.Comparator;
  • 比较逻辑不同:Comparable的在类中,Comparator可以在类中,也可以在类外,但在类中意义不大(简单来说,Comparable是内部比较器,Comparator是外部比较器);
  • 排序方法不同:Comparable重写方法compareTo(T o),Comparator重写方法compare(T o1, T o2);在Collections.sort()中使用不同:一个参数,默认是Comparable自然排序,二个参数,需要传入Comparator外部排序;
  • 排序规则数量限制不同:Comparable唯一,Comparator可以有多个;

总的来说,Comparable是对象自身的比较方式,而Comparator是外部定义的比较方式。

83、说说反射用途及实现原理,Java 获取反射三种方法

在这里插入图片描述

在这里插入图片描述

Java 获取反射三种方法:

  • 第一种,使用 Class.forName 静态方法。
  • 第二种,使用类.class 方法
  • 第三种,使用实例对象 getClass() 方法。

84、&和&&的区别

• 按位与, a&b 表示 a 和 b 都转换成二进制数,再进行与运算;

• &和&&都逻辑运算符号,&&又叫短路运算符

• 逻辑与,a&& b ,a&b 都表示当且仅当两个操作数均为 true 时,其结果才为true,否则为 false。

• 逻辑与跟短路与差别非常巨大,虽然二者都要求运算符左右两端布尔值都 true,整个表达式值才 true。但,&&之所以称为短路运算,因为如果&&左边表达式值 false,右边表达式会被短路掉,不会进行运算

85、Java 创建对象有几种方式

在Java中,创建对象的常见方式有以下几种:

  1. 使用new关键字。这是最常见的创建对象的方式。
MyClass obj = new MyClass();
  1. 使用反射机制。通过Class类的newInstance方法,可以创建一个类的新实例,但需要该类有无参的构造方法。
MyClass obj = MyClass.class.newInstance();
  1. 使用克隆方法。实现Cloneable接口并覆盖clone()方法。
MyClass obj = originalObj.clone();
  1. 使用工厂方法。通过专门的工厂类来创建对象。
MyClass obj = MyFactory.createInstance();
  1. 使用单例模式。一个类可以设计为单例,即全局只有一个实例。
MyClass obj = SingletonClass.getInstance();
  1. 使用枚举单例。Java 5引入了枚举,可以用来实现线程安全的单例。
MyClass obj = MyEnum.INSTANCE;
  1. 使用原始类加载器。通过自定义类加载器加载类,并创建实例。
MyClass obj = (MyClass) myClassLoader.loadClass("com.example.MyClass").newInstance();

这些是创建Java对象的常见方式,具体选择哪种方式取决于具体的应用场景和需求。

86、如何将 GB2312 编码字符串转换为 ISO-8859-1 编码字符串呢?

public static void main(String[] args) throws UnsupportedEncodingException {
    String str = "奥特曼";
    String strIso = new String(str.getBytes("GB2312"), "ISO-8859-1");
    System.out.println(strIso);
}

87、守护线程什么?用什么方法实现守护线程

守护线程,它是一种专门为用户线程提供服务的线程,它的生命周期依赖于用户线程。
只有JVM中仍然还存在用户线程正在运行的情况下,守护线程才会有存在的意义。

否则,一旦JVM进程结束,那守护线程也会随之结束。也就是说,守护线程不会阻止JVM的退出。但是用户线程会!

守护线程和用户线程的创建方式是完全相同的,我们只需要调用用户线程里面的setDaemon方法并且设置成true,就表示这个线程是守护线程。

因为守护线程拥有自己结束自己生命的特性,所以它适合用在一些后台的通用服务场景里面。

比如JVM里面的垃圾回收线程,就是典型的使用场景。这个场景的特殊之处在于,当JVM进程技术的时候,内存回收线程存在的意义也就不存在了。所以不能因为正在进行垃圾回收导致JVM进程无法技术的问题。

但是守护线程不能用在线程池或者一些IO任务的场景里面,因为一旦JVM退出之后,守护线程也会直接退出。就会可能导致任务没有执行完或者资源没有正确释放的问题。

88、notify()和 notifyAll()有什么区别?

• notify 唤醒一个处于该对象 wait 线程,而 notifyAll 唤醒所有处于该对
象wait 线程。

• 但唤醒不等于就能执行了,需要得到锁对象才能有权利继续执行,而锁只有一✃,
所以多个线程被唤醒时需要争取该锁。

89、JDK 动态代理与 cglib 实现的区别

• java 动态代理利用反射机制生成一个实现代理接口匿名类,在调用具体方法
前调用 InvokeHandler 来处理。

• cglib 动态代理利用 asm 开源包,对代理对象类 class 文件加载进来,通过
修改其字节码生成子类来处理。

• JDK 动态代理只能对实现了接口类生成代理,而不能针对类

• cglib 针对类实现代理,主要对指定类生成一个子类,覆盖其中方法。因
为继承,所以该类或方法最好不要声明成 final。

区别:

第1点:JDK Proxy是实现目标对象的接口,而GGLib是继承目标对象。
第2点:JDK Proxy和CGLib都是在运行期生成字节码。
第3点:JJDK Proxy是通过反射调用目标对象的方法,而CGLib是采用FastClass机制来调用。

90、说说你熟悉的设计模式有哪些?

设计模式分为三大类:
• 创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式(5 种)

• 结构型模式:适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式。(7 种)

• 行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。(11 种)

  1. 工厂方法模式(Factory Method)

定义一个用于创建对象的接口,让子类决定实例化哪个类。Factory Method 使一个类的实例化延迟到其子类。

public interface Vehicle {
    void drive();
}
 
public class Car implements Vehicle {
    public void drive() {
        System.out.println("Car is driving.");
    }
}
 
public class VehicleFactory {
    public Vehicle createVehicle() {
        return new Car();
    }
}
 
public class Main {
    public static void main(String[] args) {
        VehicleFactory factory = new VehicleFactory();
        Vehicle vehicle = factory.createVehicle();
        vehicle.drive();
    }
}
  1. 抽象工厂模式(Abstract Factory)

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

public interface Engine {
    void start();
}
 
public class V8Engine implements Engine {
    public void start() {
        System.out.println("V8 Engine starting.");
    }
}
 
public interface CarFactory {
    Engine createEngine();
}
 
public class V8CarFactory implements CarFactory {
    public Engine createEngine() {
        return new V8Engine();
    }
}
 
public class Main {
    public static void main(String[] args) {
        CarFactory factory = new V8CarFactory();
        Engine engine = factory.createEngine();
        engine.start();
    }
}
  1. 单例模式(Singleton)

确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例。

public class DatabaseConnection {
    private static DatabaseConnection instance = null;
 
    private DatabaseConnection() {
        // initialization
    }
 
    public static synchronized DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
}
  1. 建造者模式(Builder)

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

// 产品类
public class Product {
    private String partA;
    private String partB;
    private String partC;
 
    public void setPartA(String partA) {
        this.partA = partA;
    }
 
    public void setPartB(String partB) {
        this.partB = partB;
    }
 
    public void setPartC(String partC) {
        this.partC = partC;
    }
 
    @Override
    public String toString() {
        return "Product{" +
                "partA='" + partA + '\'' +
                ", partB='" + partB + '\'' +
                ", partC='" + partC + '\'' +
                '}';
    }
}
 
// 建造者接口
public interface Builder {
    void buildPartA();
    void buildPartB();
    void buildPartC();
    Product getResult();
}
 
// 具体建造者
public class ConcreteBuilder implements Builder {
    private Product product = new Product();
 
    @Override
    public void buildPartA() {
        product.setPartA("建造 PartA");
    }
 
    @Override
    public void buildPartB() {
        product.setPartB("建造 PartB");
    }
 
    @Override
    public void buildPartC() {
        product.setPartC("建造 PartC");
    }
 
    @Override
    public Product getResult() {
        return product;
    }
}
 
// 调用
public class Director {
    public Product constructProduct(Builder builder) {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}
 
public class Client {
    public static void main(String[] args) {
        Director director = new Director();
        Builder builder = new ConcreteBuilder();
        Product product = director.constructProduct(builder);
        System.out.println(product);
    }
}
  1. 原型模式(Prototype Pattern)

原型模式用于复制一个已有对象。

// 需要实现Cloneable接口,并重写clone方法
public class Prototype implements Cloneable {
    private String name;
 
    public Prototype(String name) {
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
 
// 调用
public class Client {
    public static void main(String[] args) {
        try {
            Prototype prototype = new Prototype("原型");
            Prototype copiedPrototype = (Prototype) prototype.clone();
            System.out.println(copiedPrototype.getName());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小七蒙恩

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值