【八股战神篇】Java高频基础面试题

1 面向对象编程有哪些特性?

面向对象编程(Object-Oriented Programming,简称 OOP)是一种以对象为核心的编程范式,它通过模拟现实世界中的事物及其关系来组织代码。OOP 具有三大核心特性:封装、继承、多态。接下来我会逐一详细说明这些特性。

第一,封装

封装是指将数据(属性)和行为(方法)捆绑在一起,并对外隐藏对象的内部实现细节。通过访问修饰符(如 private、protected 和 public),我们可以控制哪些部分是对外可见的,哪些是内部私有的。这种机制提高了代码的安全性和可维护性。例如,在 Java 中,我们通常会将类的属性设置为 private,并通过 getter 和 setter 方法提供受控的访问方式。

第二,继承

继承允许一个类(子类)基于另一个类(父类)来构建,从而复用父类的属性和方法。通过继承,子类不仅可以拥有父类的功能,还可以扩展或重写父类的行为。Java 中使用 extends 关键字实现继承。例如,我们可以通过定义一个通用的 Animal 类,然后让 Dog 和 Cat 类继承它,这样就避免重复编写相同的代码。

第三,多态

多态是指同一个方法调用可以根据对象的实际类型表现出不同的行为。多态分为两种形式:编译时多态(方法重载)和运行时多态(方法重写)。运行时多态是通过动态绑定实现的,即程序在运行时决定调用哪个方法。例如,如果父类 Animal 有一个 eat() 方法,子类 Dog 和 Cat 可以分别重写这个方法,当调用 animal.eat() 时,具体执行的是 Dog 或 Cat 的实现。多态使得代码更加灵活和可扩展。

延伸

面向对象和面向过程的区别

(1)面向对象编程(OOP)

定义:面向对象编程是一种以对象为核心的编程范式,它将现实世界中的事物抽象为对象,并通过对象之间的交互来完成任务。OOP 的核心思想是“万物皆对象”。

特点:

以对象为中心,强调数据和行为的封装。

使用类(Class)作为模板来创建对象(Object)。

支持三大特性:封装、继承和多态。

优点:

模块化:代码结构清晰,易于维护和扩展。

复用性高:通过继承和组合可以复用已有代码。

灵活性强:支持多态,能够适应复杂需求的变化。

可读性强:贴近现实世界的思维方式,便于理解和协作。

缺点:

性能开销较大:由于引入了类、对象等概念,运行效率可能不如面向过程高效。

学习曲线较陡:需要理解类、对象、继承等概念,初学者可能觉得复杂。

(2)面向过程编程(POP)

定义:

面向过程编程是一种以过程(函数)为核心的编程范式,它将程序分解为一系列函数或步骤,按照顺序执行任务。

特点:

以函数为中心,强调逻辑流程。

数据和函数分离,通常通过参数传递数据。

程序由一个个独立的函数组成,函数之间通过调用关系协作。

优点:

简单直接:逻辑清晰,适合小型项目或简单任务。

性能较高:没有额外的对象开销,运行效率更高。

易于实现:不需要复杂的类设计,开发速度快。

缺点:

扩展性差:随着项目规模增大,代码容易变得混乱,难以维护。

复用性低:函数之间的耦合度高,难以复用代码。

不适合复杂系统:面对复杂业务逻辑时,代码会显得冗长且难以管理。

(3)举例

  • 面向过程:实现一个简单计算器,用函数依次处理加减乘除。
  • public class Calculator {public static int add(int a, int b) {return a + b;}public static int subtract(int a, int b) {return a - b;}public static void main(String[] args) {System.out.println(add(3, 5)); // 输出 8}
    }
    
  • 面向对象:为计算器定义一个类,通过实例化对象调用方法。
  • public class Calculator {private int result;public void add(int a) {result += a;}public int getResult() {return result;}public static void main(String[] args) {Calculator calc = new Calculator();calc.add(5);System.out.println(calc.getResult()); // 输出 5}
    }
    

2 接口、普通类和抽象类的区别和共同点

在 Java 中,接口、普通类和抽象类是构建面向对象程序的三种重要结构。我会从定义、方法实现、继承关系以及成员变量这4个方面详细讲解它们的区别,然后再总结它们的共同点。

第一个是定义上的区别

普通类是一个完整的、具体的类,可以直接实例化为对象。它包含属性和方法,并且可以有构造方法。

抽象类是一个不能直接实例化的类,通常用来作为其他类的基类。它可以包含抽象方法(没有实现的方法)和具体方法(有实现的方法)。

接口是一种完全抽象的结构,用于定义行为规范。它只包含抽象方法(Java 8 之后可以包含默认方法和静态方法)。

第二个是方法实现上的区别

普通类的所有方法都可以有具体实现(即方法体)。

抽象类可以包含具体方法和抽象方法。

接口默认只包含抽象方法(Java 8 后可以包含默认方法和静态方法)。

第三是继承关系上的区别

普通类支持单继承(一个类只能继承一个父类)。

抽象类也支持单继承(一个类只能继承一个抽象类)。

接口支持多实现(一个类可以实现多个接口)。

第四是成员变量上的区别

普通类和抽象类都可以有各种类型的成员变量(实例变量、静态变量等)。

接口只能有常量(public static final)。

最后是共同点,一共有3点

首先,它们都是面向对象编程的基础结构,都可以用来组织代码,实现封装、继承和多态等特性。

其次,它们都可以包含方法,尽管接口中的方法默认是抽象的。

最后,它们都可以被继承或实现,普通类可以通过继承扩展功能,抽象类和接口则需要子类继承或实现后才能使用。

3 深拷贝和浅拷贝区别

深拷贝和浅拷贝的核心区别在于是否递归地复制对象内部的引用类型数据,接下来,我会从定义、实现方式以及使用场景三个方面详细讲解它们的区别。

首先是定义上的区别,

浅拷贝是指创建一个新对象,但新对象中的引用类型字段仍然指向原对象中引用类型的内存地址。换句话说,浅拷贝只复制了对象本身,而没有复制对象内部的引用类型数据。修改新对象中的引用类型数据会影响原对象。

深拷贝是指创建一个新对象,并且递归地复制对象内部的所有引用类型数据。换句话说,深拷贝不仅复制了对象本身,还复制了对象内部的所有引用类型数据。修改新对象中的引用类型数据不会影响原对象。

其次是实现方式上的区别,

浅拷贝可以使用 Object 类的 clone() 方法,也可以使用实现 Cloneable 接口并重写 clone() 的方法。

深拷贝可以手动对引用类型字段进行递归拷贝,也可以使用序列化(Serialization)的方式将对象序列化为字节流,再反序列化为新对象。

最后是使用场景上的区别,

浅拷贝适用于当对象内部的引用类型数据不需要独立复制的情况。

深拷贝适用于当对象内部的引用类型数据需要完全独立的情况。

延伸

1,浅拷贝使用方法 

public class Resume implements Cloneable {public Object clone() {try {return (Resume) super.clone();} catch (Exception e) {e.printStackTrace();return null;}}
}

2,深拷贝使用方法

class Student implements Cloneable {String name;int age;Professor p;Student(String name, int age, Professor p) {this.name = name;this.age = age;this.p = p;}public Object clone() {Student o = null;try {o = (Student) super.clone();} catch (CloneNotSupportedException e) {System.out.println(e.toString());}o.p = (Professor) p.clone();return o;}
}

4 int和Integer的区别

Integer 和 int 的区别如下:

类型

int 是基本数据类型,存储的是数值。

Integer 是 int 的包装类,是一个对象,存储的是 int 值的引用。

内存分配

int 存储在栈中,效率高,直接存储数值。

Integer 是对象,存储在堆中,效率相对较低。

用途

int 用于基本的数值运算。

Integer 提供了更多功能,比如可以与集合类(List、Map 等)一起使用,因为集合类只能存储对象。

延伸

1 自动装箱和拆箱

从 Java 5 开始,Java 提供了自动装箱和拆箱功能,Java 自动支持基本类型与其包装类之间的转换(自动装箱和拆箱)。

装箱:int 转换为 Integer。

拆箱:Integer 转换为 int。

自动装箱是指将基本数据类型(如 int、double、boolean 等)自动转换为对应的包装类对象(如 Integer、Double、Boolean 等)。这个过程由编译器自动完成,无需手动调用包装类的构造方法或静态方法。

当存储一个基本数据类型到需要用到对象的场景中(例如集合),Java 编译器会检测到基本数据类型需要被转换为包装类对象,编译器会自动调用包装类的 valueOf() 方法来创建对应的包装类对象,生成的对象会被存储到目标位置。

自动拆箱是指将包装类对象(如 Integer、Double、Boolean 等)自动转换为对应的基本数据类型(如 int、double、boolean 等)。同样,这个过程也是由编译器自动完成的。

当你从一个需要对象的场景中取出值并赋给基本数据类型时,Java 编译器会检测到目标变量是一个基本数据类型。编译器会自动调用包装类的 xxxValue() 方法,比如 intValue()、doubleValue() 等,来获取基本数据类型的值。返回的基本数据类型值会被赋给目标变量。

2 内存分配
int:

存储在栈内存中,直接保存值,效率高。

Integer:

是一个对象,存储在堆内存中,包含元数据(如值和方法),占用更多内存。

3 Integer 缓存机制
Java 对于 -128 到 127 之间的 Integer 对象进行了缓存。

当值在该范围内时,会直接返回缓存中的对象。

如果值超出范围,会创建新的对象。

public class Main {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;
​
System.out.println(a b); // true,使用缓存
System.out.println(c d); // false,超出缓存范围
}
}
输出结果:true
false

4 与集合的结合使用

int 不能直接存储在集合中,必须使用 Integer。

5 重载和重写的区别

重载(Overloading)和重写(Overriding)是 Java 中两个非常重要的概念,用于实现多态。它们的区别如下:

  1. 定义
    • 重载:同一个类中方法名称相同,但参数列表(参数个数或类型)不同。
    • 重写:子类对父类方法进行重新定义,方法名、参数列表都相同。
  2. 作用域
    • 重载:只发生在同一个类中。
    • 重写:发生在子类和父类之间。
  3. 方法签名
    • 重载:方法名相同,参数列表不同。
    • 重写:方法名、参数列表相同。
  4. 返回值
    • 重载:返回值可以相同或不同。
    • 重写:返回值必须与父类方法兼容(从 Java 5 开始可以是协变返回类型)。
  5. 访问修饰符
    • 重载:不受访问修饰符限制。
    • 重写:子类方法的访问修饰符不能比父类方法的访问修饰符更严格。
  6. 关键字
    • 重写:需要用到 @Override 注解。
    • 重载:无需特殊注解。

延伸

1.什么是重载?

重载是指在同一个类中,允许存在多个同名方法,但这些方法的参数列表必须不同。重载的核心在于方法签名的不同,而返回值类型不影响重载。

当定义一个重载方法时,

首先,方法名必须相同。

其次,参数列表必须不同,包括参数的数量、类型或顺序。

然后,返回值类型可以相同也可以不同,但它不影响重载的判断。

最后,访问修饰符(如 publicprivate 等)和异常声明也不影响重载。

2.什么是重写?

重写是指子类对父类中已有的方法进行重新定义,以提供特定的实现。重写的核心在于**继承关系**,并且要求方法签名完全一致。

当定义一个重写方法时,

首先,方法名必须与父类中的方法名相同。

其次,参数列表必须与父类中的方法完全一致。

然后,返回值类型必须相同或是父类返回值类型的子类型(协变返回类型)。

最后,访问修饰符不能比父类更严格(例如,父类方法是 protected,子类方法可以是 protected 或 public,但不能是 private)。

3.重载的细节

重载是方法的编译时多态,即方法的调用在编译期由参数列表决定。以下是一个示例:

public class OverloadingExample {public int add(int a, int b) {return a + b;}public double add(double a, double b) {return a + b;}public String add(String a, String b) {return a + b;}
}这里 add 方法重载了三次,分别接收不同类型的参数。
在编译时,编译器会根据传入的参数类型选择对应的方法。

    4.重写的细节

    重写是方法的运行时多态,由子类在运行期决定具体调用哪个方法。以下是一个示例:

    class Parent {public void display() {System.out.println("Parent display method");}
    }class Child extends Parent {@Overridepublic void display() {System.out.println("Child display method");}
    }
    public class OverridingExample {public static void main(String[] args) {Parent obj = new Child();obj.display();  // 输出:Child display method}
    }
    这里 Child 类重写了 Parent 类的 display 方法。
    在运行时,即使引用类型是 Parent,实际调用的是子类的 display 方法。

    6 ==和 equals 的区别

    1. == 比较的是 两个变量的内存地址,即是否引用了同一个对象。如果是基本数据类型,== 比较的是它们的值。
    2. equals()是 对象的比较方法,默认实现(在 Object 类中)是比较内存地址,和 == 类似。但是,大多数类(例如 StringInteger 等)会重写 equals() 方法,用于比较内容(值)是否相同。

    示例代码:

    public class Main {public static void main(String[] args) {String str1 = new String("hello");String str2 = new String("hello");String str3 = "hello";String str4 = "hello";// == 比较System.out.println(str1 == str2); // false,两个对象的内存地址不同System.out.println(str3 == str4); // true,字符串常量池优化// equals 比较System.out.println(str1.equals(str2)); // true,内容相同System.out.println(str3.equals(str4)); // true,内容相同}
    }
    

    延伸

    1.为什么需要重写 equals() 方法?

    • 默认的equals()方法比较的是对象地址,而在许多场景下,我们需要比较对象的内容是否相等。例如:比较两个 Person 对象的 name 和 age 是否相等。
    • 当你重写 equals() 方法时,一般还需要重写 hashCode() 方法,保证逻辑一致。

    2.hashCode() 和 equals() 的关系

    • 如果两个对象通过 equals() 方法相等,它们的 hashCode() 必须相等。
    • 如果两个对象的 hashCode() 相等,它们未必通过 equals() 方法相等。
    • 这条规则对于集合(如 HashMap 和 HashSet)非常重要。

    示例:hashCode() 与 equals() 的一致性

    class Person {private String name;public Person(String name) {this.name = name;}@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Person person = (Person) obj;return name.equals(person.name);}@Overridepublic int hashCode() {return name.hashCode();}
    }
    

    3.hashCode() 的作用

    hashCode() 是 Java 中 Object 类的一个方法,用于返回对象的哈希码(Hash Code),它是一个整数值。这个哈希码的主要作用是确定对象在基于哈希表的数据结构中的存储位置。

    (1) 哈希码的核心作用:定位对象

    快速定位:

    在基于哈希表的数据结构(如 HashMap、HashSet 和 Hashtable)中,hashCode() 被用来计算对象的存储位置。

    哈希表通过将对象的哈希值映射到特定的“桶”(Bucket)中,从而实现高效的插入、查找和删除操作。

    这种机制使得哈希表的时间复杂度通常为 O(1),即常数时间复杂度,极大提升了性能。

    7 什么是泛型?有什么作用?

    泛型(Generics) 是 Java 中的一种语言特性,允许我们在类、接口和方法中使用参数化类型。它提供了一种在编译时检测类型安全的机制,从而减少运行时的类型转换错误。泛型的主要目的是使代码更加类型安全可读性强通用性高

    泛型的作用主要有4点

    第一点是提高代码的复用性,它允许我们编写与类型无关的通用代码。

    第二点是增强类型安全性在没有泛型的情况下,集合类(如 ArrayList)默认存储的是 Object 类型,取出元素时需要手动进行类型转换,容易引发 ClassCastException。而泛型在编译时就会进行类型检查,避免了运行时的类型错误。

    第三点是简化代码使用泛型后,我们无需显式地进行类型转换,减少了冗余代码,提高了代码的可读性和维护性。

    第四点是支持复杂的类型约束泛型可以通过通配符(如 ? extends T 和 ? super T)实现更复杂的类型限制,满足特定场景下的需求。

    延伸

    1.泛型的语法与使用

    泛型类 泛型可以用于定义类,使类可以处理多种数据类型。

    例子:

    public class Box<T> {private T value;public T getValue() {return value;}public void setValue(T value) {this.value = value;}
    }public class Example {public static void main(String[] args) {Box<String> stringBox = new Box<>();stringBox.setValue("Hello");System.out.println(stringBox.getValue()); // 输出:HelloBox<Integer> intBox = new Box<>();intBox.setValue(123);System.out.println(intBox.getValue()); // 输出:123}
    }
    T 是一个类型参数,表示该类可以接受任意类型。
    使用时,通过指定具体类型(如String、Integer)实现类型安全。

    泛型方法 泛型也可以用于方法,使方法可以接受不同类型的参数。

    例子:

    public class Example {// 泛型方法public static <T> void printArray(T[] array) {for (T element : array) {System.out.println(element);}}public static void main(String[] args) {Integer[] intArray = {1, 2, 3};String[] strArray = {"A", "B", "C"};printArray(intArray); // 输出:1 2 3printArray(strArray); // 输出:A B C}
    }方法前面的<T>表示这是一个泛型方法,T是类型参数。
    方法可以接受任意类型的数组作为参数。

    泛型接口 泛型可以用于接口,使接口适配不同的实现类型。

    例子:

    public interface Pair<K, V> {K getKey();V getValue();
    }public class KeyValue<K, V> implements Pair<K, V> {private K key;private V value;public KeyValue(K key, V value) {this.key = key;this.value = value;}public K getKey() {return key;}public V getValue() {return value;}
    }public class Example {public static void main(String[] args) {Pair<String, Integer> pair = new KeyValue<>("Age", 25);System.out.println("Key: " + pair.getKey());   // 输出:Key: AgeSystem.out.println("Value: " + pair.getValue()); // 输出:Value: 25}
    }
    泛型接口允许在实现时指定不同的类型参数。

     通配符:泛型可以使用通配符(?)来表示未知类型

    1. 通配符的使用:

    • ? extends T:表示类型是TT的子类(用于读取)。
    • ? super T:表示类型是TT的父类(用于写入)。
    • ?:表示任意类型。

      例子:

      import java.util.ArrayList;
      import java.util.List;public class Example {public static void printNumbers(List<? extends Number> list) {for (Number number : list) {System.out.println(number);}}public static void main(String[] args) {List<Integer> intList = new ArrayList<>();intList.add(1);intList.add(2);List<Double> doubleList = new ArrayList<>();doubleList.add(1.1);doubleList.add(2.2);printNumbers(intList); // 输出:1 2printNumbers(doubleList); // 输出:1.1 2.2}
      }? extends Number 表示列表中的元素必须是Number或其子类,保证类型安全。

    2.泛型的限制

    • Java 的泛型是通过类型擦除(Type Erasure)实现的,泛型信息只存在于编译阶段,运行时被擦除为Object
    • 例如,List<Integer>List<String>在运行时实际上是相同的类型。

      例子:

    List<String> list1 = new ArrayList<>();
    List<Integer> list2 = new ArrayList<>();
    System.out.println(list1.getClass() == list2.getClass()); // 输出:true
    

    3.泛型不能使用基本数据类型

    • 泛型不支持基本数据类型(如intdouble等),只能使用包装类(如IntegerDouble等)。
    • 解决方案:自动装箱和拆箱。

    4.泛型数组的创建

    不能直接创建泛型数组,如T[],因为类型信息在运行时被擦除。

    8 什么是反射?应用?

    反射是一种在运行时动态获取类信息的能力。通过反射,我们可以在程序运行时加载类、获取类的结构(如字段、方法、构造器等),甚至可以调用类的方法或修改字段的值。

    反射主要应用在这5个场景

    第一个是框架开发,很多 Java 框架都有使用反射,比如如 Spring、Hibernate 等。

    第二个是动态代理,动态代理是反射的一个重要应用,常用于 AOP(面向切面编程)。通过反射,我们可以在运行时动态生成代理类,拦截方法调用并添加额外逻辑。

    第三个是注解处理,注解本身不会对程序产生任何影响,但通过反射,我们可以在运行时读取注解信息并执行相应的逻辑。

    第四个是插件化开发,在某些场景下,我们需要动态加载外部的类或模块。反射可以帮助我们在运行时加载这些类并调用其方法,从而实现插件化开发。

    第五个是测试工具,单元测试框架(如 JUnit)利用反射来发现和运行测试方法,而无需手动指定每个测试用例。

    延伸

    1.为什么引入反射

    在传统的 Java 编程中,所有的类和方法调用必须在编译时确定。 这种模式虽然安全且高效,但在某些场景下显得不够灵活。而Java 引入反射是为了在运行时动态获取类的信息并操作类或对象,包括获取类的结构、创建对象、调用方法、访问 / 修改字段等,从而增强程序的灵活性和可扩展性。

    2.反射的优缺点

    优点:

            灵活性强:允许程序动态操作未知类,非常适合框架开发或插件化设计。

            动态性:反射支持运行时动态加载类和调用方法,避免了硬编码。

            代码复用性高:通过反射,可以写出通用代码,减少重复。

    缺点:

            性能开销大:反射的调用比直接调用慢得多,因为需要进行许多运行时检查和处理。

            安全风险:反射能绕过 Java 的访问控制机制,如访问私有字段或方法,可能导致安全问题。

            代码可读性差:反射的代码往往复杂且难以维护,尤其对于大型项目而言。

            编译时安全性降低:使用反射时,编译器无法验证被调用的方法或字段是否存在。

    9 StringBuffer 的特点

    StringBuffer 是一个可变的字符序列,与 String 不同,StringBuffer 的内容是可以被修改的。它的核心特点是线程安全和高效的字符串操作。

    StringBuffer有四个特点:

    第一个是它具有可变性,我们可以在原有对象上直接修改字符串内容,而无需创建新的对象。

    第二个它是线程安全的,StringBuffer 的所有方法都通过 synchronized 关键字修饰,因此它是线程安全的。 在多线程环境下,多个线程可以同时操作同一个 StringBuffer 对象,而不会引发数据竞争或不一致问题。

    第三个是性能相对较好,StringBuffer 内部使用一个可扩容的字符数组来存储数据,当容量不足时会自动扩展。相比于 String 的不可变性(每次修改都会生成新对象),StringBuffer 在频繁修改字符串时性能更高。而相比于非线程安全的 StringBuilder ,性能略低。

    第四个是包含丰富的 API,比如:append():追加内容到字符串末尾。 insert():在指定位置插入内容。delete():删除指定范围的内容。 reverse():反转字符串内容。 toString():将 StringBuffer 转换为 String。

    延伸

    1.String、StringBuffer、StringBuilder 的区别?

    1. String
      • 不可变String 是不可变类,每次对字符串的修改都会生成新的字符串对象。
      • 线程安全:因为不可变,所以天然线程安全。
      • 性能:由于每次修改都会创建新对象,频繁操作时效率较低。
    2. StringBuilder
      • 可变StringBuilder 是可变类,对字符串的操作会直接在原对象上修改。
      • 线程不安全:不适用于多线程场景。
      • 性能:在单线程环境中,操作效率比 String 和 StringBuffer 高。
    3. StringBuffer
      • 可变:和 StringBuilder 类似,也是可变类。
      • 线程安全:通过同步方法实现线程安全,适用于多线程场景。
      • 性能:由于线程安全机制的开销,操作效率比 StringBuilder 略低。

    适用场景:

    • 如果字符串内容 不会改变,用 String
    • 如果字符串内容会频繁修改,且在 单线程 环境下使用,选 StringBuilder
    • 如果字符串内容会频繁修改,且在 多线程 环境下使用,选 StringBuffer

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/905824.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    科学养生指南:解锁健康生活新方式

    在快节奏的现代生活中&#xff0c;健康养生成为人们关注的焦点。想要拥有良好的身体状态&#xff0c;无需依赖复杂的传统理论&#xff0c;通过科学的生活方式&#xff0c;就能轻松实现养生目标。​ 规律运动是健康的基石。每周进行 150 分钟以上的中等强度有氧运动&#xff0c…

    OpenCV阈值处理完全指南:从基础到高级应用

    引言 阈值处理是图像处理中最基础、最常用的技术之一&#xff0c;它能够将灰度图像转换为二值图像&#xff0c;为后续的图像分析和处理奠定基础。本文将全面介绍OpenCV中的各种阈值处理方法&#xff0c;包括原理讲解、代码实现和实际应用场景。 一、什么是阈值处理&#xff1…

    Java8到24新特性整理

    本文整理了 Java 8 至 Java 24 各版本的新特性&#xff0c;内容包括每个版本的新增功能分类&#xff08;如语法增强、性能优化、工具支持等&#xff09;、详细的代码示例&#xff0c;并结合官方文档资料&#xff0c;分析每项特性的应用场景及优缺点。Java 8 发布于 2014 年&…

    轮询仲裁器

    参考视频 https://www.bilibili.com/video/BV1VQ4y1w7Rr/?spm_id_from333.337.search-card.all.click&vd_sourceaedd69dc9740e91cdd85c0dfaf25304b 算法原理

    Armijo rule

    非精线搜索步长规则Armijo规则&Goldstein规则&Wolfe规则_armijo rule-CSDN博客 [原创]用“人话”解释不精确线搜索中的Armijo-Goldstein准则及Wolfe-Powell准则 – 编码无悔 / Intent & Focused

    力扣HOT100之二叉树:102. 二叉树的层序遍历

    这道题太简单了&#xff0c;相当于基础的模板题&#xff0c;但凡涉及到层序遍历一定会用到队列来实现&#xff0c;其他的倒没啥好说的&#xff0c;用两层while循环来层序遍历&#xff0c;外层while循环用于控制访问二叉树的每一层&#xff0c;而内层while循环则负责收割每一层的…

    Ubuntu24.04 安装 5080显卡驱动以及cuda

    前言 之前使用Ubuntu22.04版本一直报错,然后换了24.04版本才能正常安装 一. 配置基础环境 Linux系统进行环境开发环境配置-CSDN博客 二. 安装显卡驱动 1.安装驱动 按以下步骤来&#xff1a; sudo apt update && sudo apt upgrade -y#下载最新内核并安装 sudo add…

    WAS和Tomcat的对比

    一、WAS和Tomcat的对比 WebSphere Application Server (WAS) 和 Apache Tomcat 是两款常用的 Java 应用服务器&#xff0c;但它们有许多显著的区别。在企业级应用中&#xff0c;它们扮演不同的角色&#xff0c;各自有其特点和适用场景。以下是它们在多个维度上的详细对比&…

    asp.net IHttpHandler 对分块传输编码的支持,IIs web服务器后端技术

    IHttpHandler&#xff0c;不支持分块传输编码&#xff08;Chunked Transfer&#xff09;吧&#xff1f; IHttpHandler 对分块传输编码的支持 实际上&#xff0c;IHttpHandler 完全支持分块传输编码&#xff08;Chunked Transfer Encoding&#xff09;&#xff0c;但具体行为取…

    为什么elasticsearch配置文件JVM配置31G最佳

    Elasticsearch的JVM堆内存配置为32GB被视为最佳实践&#xff0c;主要基于以下综合技术原理和性能优化考量&#xff1a; 1. ‌JVM指针压缩机制优化内存效率‌ 当堆内存≤32GB时&#xff0c;JVM启用‌对象指针压缩&#xff08;Compressed Ordinary Object Pointers, COOP&#…

    Systemd基础

    1. 概述 Systemd 是一系列工具的集合&#xff0c;其作用也远远不仅是启动操作系统&#xff0c;它还接管了后台服务、结束、状态查询&#xff0c;以及日志归档、设备管理、电源管理、定时任务等许多职责&#xff0c;并支持通过特定事件&#xff08;如插入特定 USB 设备&#xf…

    AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月16日第79弹

    从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀6-8个和值&#xff0c;可以做到100-300注左右。 (1)定…

    CentOS高手之路:从进阶实战到企业级优化

    一、系统深度优化与性能调优 1. 内核参数调优 通过修改/etc/sysctl.conf文件调整内核参数&#xff0c;可显著提升服务器性能。例如&#xff1a; net.ipv4.tcp_fin_timeout30&#xff08;快速释放TCP连接&#xff09; vm.swappiness10&#xff08;减少交换分区使用&#xff0…

    Docker 无法拉取镜像解决办法

    问题 在linux终端中通过 docker pull 命令拉取镜像&#xff0c;报错无法拉取镜像&#xff0c;这是因为 Docker 客户端无法连接到 Docker 镜像仓库&#xff08;Docker Hub&#xff09; 解决方法 1、配置国内可用的 Docker镜像加速器&#xff0c;这些镜像加速器用于提高从Docke…

    【Linux】序列化与反序列化、会话与进程组、守护进程

    一.序列化和反序列化 协议其实就是结构化的数据。但是再网络通信中&#xff0c;我们不直接发送结构化的数据给对方。我们一般会将结构化的数据序列化成字符串/字节流&#xff0c;然后通过网络在发送出去。而接收方收到之后&#xff0c;要对收到的字符串/流式数据进行反序列化&…

    提权脚本Powerup命令备忘单

    1. 获取与加载 从 GitHub 下载&#xff1a;(New-Object Net.WebClient).DownloadFile("https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Privesc/PowerUp.ps1", "C:\Temp\PowerUp.ps1")本地加载&#xff1a;Import-Module .\Power…

    2025年Ai写PPT工具推荐,这5款Ai工具可以一键生成专业PPT

    上个月给客户做产品宣讲时&#xff0c;我对着空白 PPT 页面熬到凌晨一点&#xff0c;光是调整文字排版就改了十几版&#xff0c;最后还是被吐槽 "内容零散没重点"。后来同事分享了几款 ai 写 PPT 工具&#xff0c;试完发现简直打开了新世界的大门 —— 不用手动写大纲…

    部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name

    参考了https://blog.csdn.net/m0_74216612/article/details/144145127 这篇文章&#xff0c;关闭了centos的防火墙&#xff0c;也修改了redis.conf文件&#xff0c;还是一直显示Failed to connect to any host resolved for DNS name。最终发现是腾讯云服务器那一层防火墙没…

    QML元素 - OpacityMask

    QML 的 OpacityMask 用于通过遮罩元素的 透明度&#xff08;Alpha 通道&#xff09; 裁剪源元素的可见区域&#xff0c;适用于创建不规则形状的 UI 元素&#xff08;如圆形头像、波浪形进度条&#xff09;或复杂视觉效果。以下是详细使用技巧和常见场景示例&#xff1a; 1. 基本…

    麒麟桌面系统文件保险箱快捷访问指南:让重要文件夹一键直达桌面!

    往期文章链接&#xff1a;统信操作系统自定义快捷键配置音量调节功能指南 Hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇麒麟桌面操作系统上配置文件保险箱内文件夹桌面快捷方式的文章&#xff0c;欢迎大家分享点赞&#xff0c;点个在看和关注吧&#xff01;在日常…