数据结构——反射、枚举以及lambda表达式

1. 反射

Java的反射(reflection)机制是在运⾏时检查、访问和修改类、接⼝、字段和⽅法的机制;这种动态获取信息以及动态调⽤对象⽅法的功能称为java语⾔的反射(reflection)机制。
用途
1. 框架开发
2. 注解处理
3. 动态代理
4. 配置⽂件解析
5. 等等

1. 反射相关的类

2. Class类(反射机制的起源 )

类 |API 参考 |Android 开发人员 代表类的实体,在运⾏的Java应⽤程序中表⽰类和接⼝

1. Java程序运行的生命周期

  1. 编译阶段

    • Java源代码(.java文件)经过javac编译器编译

    • 生成与平台无关的字节码文件(.class文件)

    • 字节码文件包含类的结构信息和方法指令

  2. 类加载阶段

    • JVM通过类加载器(ClassLoader)读取.class文件

    • 将字节码数据转换为JVM内部的数据结构

    • 创建对应的java.lang.Class对象

  3. Class对象的作用

    • 每个加载的类在JVM中都有唯一的Class对象

    • Class对象包含类的完整元数据:

      • 类名、修饰符、包信息

      • 字段(属性)信息

      • 方法信息

      • 构造器信息

      • 注解信息

  4. 反射机制

    • 通过Class对象可以获取类的运行时信息

    • 动态操作类的能力包括:

      • 创建类的实例

      • 调用方法和访问字段

      • 修改访问权限

      • 动态代理

2. 获得Class对象的三种⽅式

package reflection;public class Student {//私有属性private String name = "zhangshan";//公有属性public int age = 18;//不带参数的共有构造方法public Student(){System.out.println("student()");}//带一个参数的公有构造方法public Student(String name){this.name = name;System.out.println("Student(name)");}//带一个参数的私有构造方法private Student(int age){this.age = age;System.out.println("Student(age)");}//带两个参数的私有构造方法private Student(String name,int age){this.name = name;this.age = age;System.out.println("Student(name,age)");}//公有方法public void sleep(){System.out.println("I am sleepy");}//私有方法private void eat(String food){System.out.println("I love delicious food");}private void run(){System.out.println("Run fast");}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}public static void main(String[] args) {Student student = new Student();System.out.println(student);}
}
1. 使⽤ Class.forName("类的全路径名"); 静态⽅法。
前提:已明确类的全路径名。
2. 使⽤ .class ⽅法。
说明:仅适合在编译前就已经明确要操作的 Class
3. 使⽤类对象的 getClass() ⽅法; 已经加载的类的对象实例
//获得Class对象的三种⽅式
class Main {public static void main(String[] args) {//1. 通过Class.forName获取class对象Class<?> c1 = null;try{c1 = Class.forName("reflection.Student");}catch(ClassNotFoundException e){e.printStackTrace();}//2.直接通过 类名.class 的⽅式得到,该⽅法最为安全可靠,程序性能更⾼//这说明任何⼀个类都有⼀个隐含的静态成员变量 classClass<?> c2 = Student.class;//3. 通过getClass获取Class对象Student s3 = new Student();//创建对象Class<?> c3 = s3.getClass();//⼀个类在 JVM 中只会有⼀个 Class 实例,即我们对上⾯获取的//c1,c2,c3进⾏ equals ⽐较,发现都是trueSystem.out.println(c1.equals(c2));System.out.println(c1.equals(c3));System.out.println(c2.equals(c3));}
}

3. Class类中的相关⽅法

1. 获取类信息
方法返回值用途示例
Class.forName("全限定类名")Class<?>动态加载类Class.forName("java.lang.String")
对象.getClass()Class<?>获取对象的 Class 对象"hello".getClass()
类名.classClass<?>直接获取类的 Class 对象String.class
clazz.getName()String获取全限定类名(如 "java.lang.String"String.class.getName()
clazz.getSimpleName()String获取简单类名(如 "String"String.class.getSimpleName()
clazz.getPackage()Package获取包信息String.class.getPackage()
clazz.getModifiers()int获取修饰符(需用 Modifier 解析)Modifier.isPublic(modifiers)
clazz.getSuperclass()Class<?>获取父类Integer.class.getSuperclass()
clazz.getInterfaces()Class<?>[]获取实现的接口List.class.getInterfaces()
2. 常⽤获得类相关的⽅法:

3. 获取注解(Annotation)
方法返回值用途示例
clazz.getAnnotations()Annotation[]获取类上的所有注解clazz.getAnnotations()
clazz.getAnnotation(注解类)Annotation获取类上的指定注解clazz.getAnnotation(Deprecated.class)
field.getAnnotations()Annotation[]获取字段上的所有注解field.getAnnotations()
method.getAnnotations()Annotation[]获取方法上的所有注解method.getAnnotations()
constructor.getAnnotations()Annotation[]获取构造方法上的所有注解constructor.getAnnotations()
4. 获取构造方法(Constructor)
方法返回值用途示例
clazz.getDeclaredConstructors()Constructor<?>[]获取所有声明的构造方法(包括私有)clazz.getDeclaredConstructors()
clazz.getConstructors()Constructor<?>[]获取所有公共构造方法clazz.getConstructors()
clazz.getDeclaredConstructor(参数类型...)Constructor<?>获取指定参数类型的构造方法(包括私有)clazz.getDeclaredConstructor(String.class)
clazz.getConstructor(参数类型...)Constructor<?>获取指定参数类型的公共构造方法clazz.getConstructor()
constructor.setAccessible(true)void设置私有构造方法可访问constructor.setAccessible(true)
constructor.newInstance(参数...)Object通过构造方法创建实例constructor.newInstance("Tom")
5. 获取属性(Field)
方法返回值用途示例
clazz.getDeclaredFields()Field[]获取所有声明的属性(包括私有)clazz.getDeclaredFields()
clazz.getFields()Field[]获取所有公共属性(包括继承的)clazz.getFields()
clazz.getDeclaredField("name")Field获取指定名称的属性(包括私有)clazz.getDeclaredField("age")
clazz.getField("name")Field获取指定名称的公共属性clazz.getField("name")
field.setAccessible(true)void设置私有属性可访问field.setAccessible(true)
field.get(obj)Object获取属性值field.get(user)
field.set(obj, value)void设置属性值field.set(user, "Tom")

6. 获取方法(Method)
方法返回值用途示例
clazz.getDeclaredMethods()Method[]获取所有声明的方法(包括私有)clazz.getDeclaredMethods()
clazz.getMethods()Method[]获取所有公共方法(包括继承的)clazz.getMethods()
clazz.getDeclaredMethod("方法名", 参数类型...)Method获取指定方法(包括私有)clazz.getDeclaredMethod("setName", String.class)
clazz.getMethod("方法名", 参数类型...)Method获取指定公共方法clazz.getMethod("toString")
method.setAccessible(true)void设置私有方法可访问method.setAccessible(true)
method.invoke(obj, 参数...)Object调用方法method.invoke(user, "Tom")
package reflection;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Test{//类的实例化public static void reflectNewInstance(){try{Class<?> classStudent = Class.forName("reflection.Student");Object objectStudent = classStudent.newInstance();//Student student = (Student) objectStudent;System.out.println("获得学生对象:"+objectStudent);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}//获取类的公有(public)带一个参数构造方法并实例化public static void reflectPublicConstructor(){try{Class<?> classStudent = Class.forName("reflection.Student");//获取类的公有(public)无参构造方法Constructor<?> con = classStudent.getConstructor(String.class);//利用构造方法进行实例化Object studentNewInstance = con.newInstance("wangwu");//Student student = (Student) studentNewInstance;System.out.println("获得公有带一个参数构造方法并修改姓名:"+studentNewInstance);} catch (Exception e) {throw new RuntimeException(e);}}//获取类的私有(private)带一个参数构造方法并实例化public static void reflectPrivateConstructor(){try{Class<?> classStudnt = Class.forName("reflection.Student");//获取类的私有(private)带一个参数构造方法Constructor<?> con = classStudnt.getDeclaredConstructor(int.class);//绕过 Java 的访问控制检查,允许你访问或调用原本不可见的成员(如 private 构造方法、方法或字段)。con.setAccessible(true);//实例化Object studentNewInstance = con.newInstance(20);System.out.println("获得私有带一个参数构造方法并修改年龄:"+studentNewInstance);} catch (Exception e) {throw new RuntimeException(e);}}//获取类的所有构造方法并实例化public static void reflectionConstructor(){try{Class<?> classStudent = Class.forName("reflection.Student");//取类的所有构造方法Constructor<?>[] con = classStudent.getDeclaredConstructors();//使所有构造方法绕过 Java 的访问控制检查,允许访问或调用原本不可见的成员for(Constructor<?> constructor:con){constructor.setAccessible(true);}//实例化Object s1 = con[3].newInstance();Object s2 = con[0].newInstance("lihua",23);System.out.println("获得公有带一个参数构造方法并修改姓名:"+s1);System.out.println("获得私有带两个参数构造方法并修改姓名和年龄:"+s2);} catch (Exception e) {throw new RuntimeException(e);}}//获取私有属性public static void reflectPrivateField(){try {Class<?> classStudent = Class.forName("reflection.Student");//实例化Object s1 = classStudent.newInstance();//获取私有属性Field field = classStudent.getDeclaredField("name");field.setAccessible(true);//修改私有属性field.set(s1,"xh");//获取修改后的私有属性String name = (String) field.get(s1);System.out.println("修改之后的私有属性:"+name);} catch (Exception e) {throw new RuntimeException(e);}}//获取私有方法public static void reflectPrivateMethod(){try {Class<?> classStudent = Class.forName("reflection.Student");//获取私有方法Method method = classStudent.getDeclaredMethod("eat",String.class);System.out.println("获取私有⽅法的⽅法名为:"+method.getName());method.setAccessible(true);//实例化Object s1 = classStudent.newInstance();//方法调用method.invoke(s1,"vegetable");} catch (Exception e) {throw new RuntimeException(e);}}public static void main(String[] args) {reflectNewInstance();reflectPublicConstructor();reflectPrivateConstructor();reflectionConstructor();reflectPrivateField();

3. 反射优点和缺点

1. 优点

1. 动态性(运行时操作类)

  • 无需在编译时确定类,可以在运行时动态加载类、调用方法、访问属性。

2. 访问私有成员

  • 通过 setAccessible(true) 可以绕过 Java 的访问控制,访问 private 方法、属性和构造方法。

3. 泛型擦除时获取真实类型

  • 由于 Java 泛型在运行时会被擦除(Type Erasure),可以通过反射获取泛型的实际类型。

4. 注解处理

  • 反射可以读取类、方法、字段上的注解,实现灵活的配置和扩展。

5. 动态创建和操作对象

  • 可以在运行时动态创建对象、调用方法,适用于 高度灵活 的场景。

2. 缺点

大家都说 Java 反射效率低,你知道原因在哪里么_慕课手记

1. 性能较差

  • 反射比直接调用慢 10~100 倍,主要因为:

    • JVM 无法优化反射调用(如方法内联)。

    • 需要额外的安全检查(如 AccessibleObject.setAccessible())。

  • 影响场景

    • 高频调用的代码(如循环内使用反射)。

    • 高性能要求的系统(如交易系统、游戏引擎)。

2. 破坏封装性

  • setAccessible(true) 可以绕过 private 限制,导致:

    • 代码安全性降低(恶意代码可能篡改私有数据)。

    • 破坏面向对象的封装原则(如 final 字段被修改)。

3. 代码可读性和维护性差

  • 反射代码通常 冗长、难以调试,IDE 也无法提供智能提示。

4. 编译时检查失效

  • 反射调用在 编译期不会检查错误(如方法名拼写错误、参数类型不匹配),只能在运行时抛出异常。

5. 安全问题

  • 反射可以 绕过安全管理器(SecurityManager),可能导致:

    • 私有 API 被非法调用。

    • 敏感数据泄露(如通过反射获取 Password 字段)。

通过 getDeclaredMethods()getDeclaredFields() 或 getDeclaredConstructors() 获取的方法、属性或构造方法的顺序是不确定的,具体顺序取决于 JVM 的实现(如 OpenJDK 和 Oracle JDK 可能不同)。所以我们可以使用 Arrays.sort 按名称、修饰符、参数类型等自行排序。
优点缺点
动态加载和操作类性能差(比直接调用慢 10~100 倍)
可访问私有成员破坏封装性
支持泛型擦除时的类型获取代码可读性差
强大的注解处理能力编译时检查失效
适用于框架和灵活架构可能引发安全问题

2. 枚举

1. 背景及定义

枚举是在JDK1.5以后引⼊的。主要⽤途是:将⼀组常量组织起来,在这之前表⽰⼀组常量通常使⽤定义常量的⽅式:
public static final int RED = 1;
public static final int GREEN = 2;
public static final int WHITE = 3;
但是常量举例有不好的地⽅,例如:可能碰巧有个数字1,但是他有可能误会为是RED,现在我们可以直接⽤枚举来进⾏组织,这样⼀来,就拥有了类型,枚举类型。⽽不是普通的整形1
优点:将常量组织起来统⼀进⾏管理
场景:错误状态码,消息类型,颜⾊的划分,状态机等等....
本质:是 java.lang.Enum 的⼦类,也就是说,⾃⼰写的枚举类,就算没有显⽰的继承 Enum ,但 是其默认继承了这个类。

2. Enum 类的常⽤⽅法

枚举可以像普通类一样定义字段、构造方法和普通方法。此时,枚举常量必须调用相应的构造方法:

3. 关键点:

  1. 枚举常量必须放在枚举类的最前面,并用逗号 , 分隔,最后一个常量后用分号 ; ,后面才能定义字段和方法。。

  2. 枚举的构造方法是自动调用的,构造方法必须与枚举常量的参数匹配(无参常量 → 无参构造方法;带参常量 → 带参构造方法)。

  3. 构造方法默认是 private,不能声明为 public 或 protected(因为枚举的实例只能由枚举自身创建)。

  4. 构造方法调用是隐式的,当枚举类被 JVM 加载时,所有枚举常量会被初始化,并自动调用对应的构造方法(不能手动调用构造方法),例如 WHITE("White",5);

  5. 枚举常量是单例的构造方法只会被调用一次

  6. 每个枚举常量本质上是一个静态实例,相当于:

public static final EnumDom WHITE = new EnumDom("White",10);

(枚举类型(enum)的构造方法默认是私有的(private),这意味着你不能直接使用new关键字来创建枚举实例。 枚举常量必须通过枚举类型本身隐式创建。例如 WHITE("White",5);

7. 在Java中,枚举常量的引用不可变,但若设计不当(含非 final 字段),其内部状态可能被修改。强烈建议将枚举设计为完全不可变

4. 使用

public enum EnumDom {RED,//无参枚举常量GREEN("Green"),//带一个参数的枚举常量WHITE("White",5);//带两个参数的枚举常量//枚举类型(enum)的构造方法默认是私有的(private),这意味着你不能直接使用new关键字来创建枚举实例。// 枚举常量必须通过枚举类型本身隐式创建。//public static final EnumDom WHITE = new EnumDom("White",10);//构造方法必须匹配枚举常量的参数类型和数量//无参构造方法(可不写,java会自动提供)private EnumDom(){}public String name;public int code;//带一个参数的构造方法private EnumDom(String name){this.name = name;}//带两个参数的构造方法private EnumDom(String name,int code){this.name = name;this.code = code;System.out.println(this.name+" "+this.code);}//方法private void color(String name){this.name = name;//非final字段,可以修改System.out.println(this.name);}//    @Override
//    public String toString() {
//        return "EnumDom{" +
//                "name='" + name + '\'' +
//                ", code=" + code +
//                '}';
//    }public static void main(String[] args) {//直接调用枚举常量//枚举常量在类加载时通过构造方法初始化,且仅初始化一次(线程安全)。EnumDom w1 = EnumDom.WHITE;EnumDom w2 = EnumDom.WHITE;System.out.println(w1);System.out.println(w2);System.out.println(w1==w2);//同一个WHITE//以数组形式返回枚举类型的所有成员EnumDom[] enumDom = EnumDom.values();for(EnumDom e: enumDom){System.out.print(e+" ");//获取枚举成员的索引位置System.out.println(e.ordinal());}//将普通字符串转换为枚举实例EnumDom e1 = EnumDom.valueOf("RED");System.out.println(e1);//比较两个枚举成员在定义时的顺序System.out.println(enumDom[0].compareTo(enumDom[2]));//方法调用enumDom[0].color("red");enumDom[1].color("green");}
}

5. 枚举和反射

通过反射我们可以获取枚举常量本身,非final字段,方法,构造方法信息,注解信息

不可以获取/操作的内容:

  1. 无法通过构造方法创建新的枚举实例

    • 尝试反射调用构造方法会抛出IllegalArgumentException: Cannot reflectively create enum objects

  2. 无法修改final字段(除非使用特殊技巧)

    • 常规反射无法修改final字段

    • 需要先修改Field的modifiers字段(不推荐)

  3. 无法获取编译器生成的某些特殊方法

    • values()valueOf()方法在字节码中是编译器生成的

  4. 无法改变枚举常量的顺序(ordinal)

    • ordinal是final的且由编译器决定

  5. 无法删除或添加枚举常量

    • 枚举集合在运行时是固定的

package enumeration;import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class Test {public static void main(String[] args) {try{Class<?> clazz = Class.forName("enumeration.EnumDom");//获取所有枚举常量并调用对应的构造方法Object[] enumDoms = clazz.getEnumConstants();//打印所有枚举成员for(Object em :enumDoms ){System.out.println(em);}//获取枚举构造方法Constructor<?>[] con = clazz.getDeclaredConstructors();for(Constructor<?> constructor:con){constructor.setAccessible(true);}//获取指定枚举构造方法,包含继承的Enum的构造方法的参数Constructor<?> con1 = clazz.getDeclaredConstructor(String.class,int.class,String.class);//无法通过反射创建新实例//Object e1 = con[0].newInstance();//抛出异常 Cannot reflectively create enum objects//System.out.println(e1);//获取枚举类的方法Method method = clazz.getDeclaredMethod("color",String.class);method.setAccessible(true);method.invoke(EnumDom.RED,"red");//在反射中可以直接调用枚举常量method.invoke(enumDoms[1],"green");} catch (Exception e) {throw new RuntimeException(e);}}
}

3. Lambda表达式

1. 背景

Lambda表达式是Java SE 8中⼀个重要的新特性。lambda表达式允许你通过表达式来代替功能接⼝。 lambda表达式就和⽅法⼀样,它提供了⼀个正常的参数列表和⼀个使⽤这些参数的主体(body,可以是⼀个表达式或⼀个代码块)。 Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure) 。

2. Lambda表达式的语法

(parameters) -> expression
(parameters) ->{ statements; }
Lambda表达式由三部分组成:
1. paramaters:类似⽅法中的形参列表,这⾥的参数是函数式接⼝⾥的参数(可以包含零个或多个) 。这⾥的参数类型可以明确的声明也可不声明⽽由JVM隐含的推断。另外当只有⼀个参数且无参数类型时可以省略掉圆括号。
2. ->:可理解为“被⽤于”的意思,将参数与方法体分开
3. ⽅法体:可以是单个表达式或代码块,是函数式接⼝⾥⽅法的实现。代码块可返回⼀个值或者什么都不返回,这⾥的代码块等同于⽅法的⽅法体。如果是表达式,也可以返回⼀个值或者什么都不返回。单个表达式或不用return关键字 直接返回表达式结果可以省略大括号{}。

3. 函数式接⼝

⼀个接⼝有且只有⼀个抽象⽅法 。
注意:
1. 如果⼀个接⼝只有⼀个抽象⽅法,那么该接⼝就是⼀个函数式接⼝
2. 如果我们在某个接⼝上声明了 @FunctionalInterface 注解,那么编译器就会按照函数式接⼝的定义来要求该接⼝,这样如果有两个抽象⽅法,程序编译就会报错的。所以,从某种意义上来说,只要你保证你的接⼝中只有⼀个抽象⽅法,你可以不加这个注解。加上就会⾃动进⾏检测的。
//⽆返回值⽆参数
@FunctionalInterface
interface NoParameterNoReturn {void test();
}
//⽆返回值⼀个参数
@FunctionalInterface
interface OneParameterNoReturn {void test(int a);
}
//⽆返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {void test(int a,int b);
}
//有返回值⽆参数
@FunctionalInterface
interface NoParameterReturn {int test();
}
//有返回值⼀个参数
@FunctionalInterface
interface OneParameterReturn {int test(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {int test(int a,int b);
}
public class Test {public static void main(String[] args) {//内部类NoParameterNoReturn noParameterNoReturn1 = new NoParameterNoReturn() {@Overridepublic void test() {System.out.println("⽆返回值⽆参数1");}};noParameterNoReturn1.test();NoParameterNoReturn noParameterNoReturn =()->System.out.println("⽆返回值⽆参数2");noParameterNoReturn.test();//当只有一个参数时,无参数类型,可以不需要()OneParameterNoReturn oneParameterNoReturn = x->{System.out.print("⽆返回值一个参数:");System.out.println(x);};oneParameterNoReturn.test(10);MoreParameterNoReturn moreParameterNoReturn = (x,y)->{System.out.print("⽆返回值多个参数:");System.out.println(x+y);};moreParameterNoReturn.test(10,20);//当 Lambda 体不使用 return 语句时,直接返回表达式结果不需要大括号NoParameterReturn noParameterReturn = ()->100;System.out.print("有返回值无参数:");System.out.println(noParameterReturn.test());//当 Lambda 体使用 return 语句时,必须使用大括号 {} 包裹代码块OneParameterReturn oneParameterReturn = (int x)->{return x;};System.out.print("有返回值一个参数:");System.out.println(oneParameterReturn.test(200));MoreParameterReturn moreParameterReturn = (x,y)->{System.out.print("有返回值多个参数:");return x+y;};System.out.println(moreParameterReturn.test(300,400));}
}

4. Lambda 表达式和匿名内部类

特性Lambda 表达式匿名内部类
引入版本Java 8Java 1.1
语法简洁性更简洁相对冗长
适用场景仅适用于函数式接口(单个抽象方法)适用于任何接口或抽象类
生成类文件不生成额外.class文件生成外部类$数字.class文件
this关键字含义指向外部类实例指向内部类自身实例

1. 变量捕获

Lambda 表达式可以捕获外部作用域的变量,这种特性称为"变量捕获"(Variable Capture)。这是 Lambda 表达式强大功能之一,但也需要遵循特定规则。

1. 局部变量捕获

Lambda 可以捕获方法中的局部变量,但有严格限制:

  • 被捕获的局部变量必须是 final 或 effectively final(即初始化后不再修改)

  • 原因:Lambda 可能在原始变量生命周期结束后执行,Java 需要保证值的一致性

2. 实例变量捕获

Lambda 可以自由捕获所在类的实例变量:

  • 可以读取

  • 可以修改

  • 不需要是 final

3. 静态变量捕获

Lambda 可以自由捕获静态变量:

  • 可以读取

  • 可以修改

  • 不需要是 final

变量类型可读性可修改性final要求
局部变量必须effectively final
实例变量不需要
静态变量不需要
interface Student{void fun();
}
public class Test2 {public int a = 10;//实例变量public static int b = 20;//静态变量public void fuction(){int c = 30;//局部变量Student student = ()->{a = 40;b = 50;//被捕获的局部变量必须final 或 effectively final(即初始化后不再修改)//c = 60;//err System.out.println(a);//40System.out.println(b);//50System.out.println(c);//30};student.fun();}public static void main(String[] args) {Test2 test2 = new Test2();test2.fuction();}
}

5. Lambda在集合当中的使⽤

注意:Collection的 forEach()⽅法是从接⼝ java.lang.Iterable 拿过来的。

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

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

相关文章

C语言教程(十):C 语言函数详解

一、引言 在 C 语言中&#xff0c;函数是一组执行特定任务的代码块。通过将复杂的程序逻辑划分为多个函数&#xff0c;不仅能提高代码的可读性、可维护性&#xff0c;还便于代码的复用。无论是简单的数学计算&#xff0c;还是复杂的系统操作&#xff0c;函数都发挥着核心作用。…

力扣面试150题--有效的字母异位词和字母异位词分组

Day 24 题目描述 思路 初次思路&#xff1a;如果两个字符串为异位词&#xff0c;说明它们长度相同并且字母出现的次数相同&#xff0c;于是有以下做法&#xff1a; 定义一个map&#xff0c;来保存s中每个字符的出现次数处理特殊情况&#xff0c;如果长度不同&#xff0c;直接…

数理逻辑(Mathematical Logic)综论与跨学科应用

李升伟 整理 数理逻辑&#xff08;Mathematical Logic&#xff09;是现代逻辑学与数学交叉的核心学科&#xff0c;以严格的数学方法研究逻辑推理的形式与规律。其发展深刻影响了数学基础、计算机科学、语言哲学等领域。以下从多个维度综论数理逻辑&#xff1a; 1. 核心分支 命…

高性能内存kv数据库Redis(续)

目录 四.主从同步与对象模型 1.Redis 淘汰策略 2.Redis 如何做到 持久化 2.1 redis为什么要实现持久化 2.2fork进程的写时复制机制 2.3大Key的影响 2.4redis做持久化的方式 2.5 aof 2.6 rdb 2.7 redis 持久化方式的优缺点 3.redis里面的高可用体现在哪里&#xff1f; 3.1r…

泛型算法——只读算法(一)

在 C 标准库中&#xff0c;泛型算法的“只读算法”指那些 不会改变它们所操作的容器中的元素&#xff0c;仅用于访问或获取信息的算法&#xff0c;例如查找、计数、遍历等操作。 accumulate std::accumulate()是 C 标准库**numeric**头文件中提供的算法&#xff0c;用于对序列…

SvelteKit 最新中文文档教程(21)—— 最佳实践之图片

前言 Svelte&#xff0c;一个语法简洁、入门容易&#xff0c;面向未来的前端框架。 从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte …

健康养生:开启活力生活的密钥

当我们在健身房看到年逾六旬却身形矫健的老人&#xff0c;在公园偶遇精神矍铄、步伐轻快的长者&#xff0c;总会惊叹于他们的健康状态。其实&#xff0c;这些都得益于长期坚持科学的养生之道。健康养生并非遥不可及的玄学&#xff0c;而是融入生活细节的智慧。​ 在饮食的世界…

Linux信号三部曲:产生机制、处理方式与内核接口

Linux系列 文章目录 Linux系列前言一、背景知识铺垫1.1 信号的基本概念1.2 进程对信号的处理 二、信号的产生2.1 前台进程和后台进程2.2 键盘组合键2.3 kill 命令2.4 系统调用2.4.1 signal()接口2.4.2 kill()接口2.4.3 raise()接口2.4.4 abort()接口 总结 前言 Linux中&#x…

win7/win10/macos如何切换DNS,提升网络稳定性

本篇教程教您如何在Windows10、Windows8.1、Windows7、MacOS操作系统切换DNS&#xff0c;以提升系统的稳定性&#xff0c;获得更好的操作体验。 Windows10及Windows8.1 1、右键单击“此计算机”&#xff0c;然后选择“属性”。进入Windows系统界面后&#xff0c;选择左侧的“…

移动硬盘突然打不开紧急救援指南:从排查到完整恢复‌

突发状况的典型特征‌ 当移动硬盘突然打不开时&#xff0c;用户常会遇到多种异常表现&#xff1a;接入电脑后硬盘指示灯虽亮但无法识别、系统反复提示“设备未连接成功”或弹出“磁盘结构损坏”的警告。部分情况下&#xff0c;资源管理器中的盘符虽可见&#xff0c;但双击后显示…

华为OD机试真题——统计匹配的二元组个数(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《统计匹配…

半导体制造如何数字化转型

半导体制造的数字化转型正通过技术融合与流程重构&#xff0c;推动着这个精密产业的全面革新。全球芯片短缺与工艺复杂度指数级增长的双重压力下&#xff0c;头部企业已构建起四大转型支柱&#xff1a; 1. 数据中枢重构产线生态 台积电的「智慧工厂4.0」部署着30万物联网传感器…

[Spark]深入解密Spark SQL源码:Catalyst框架如何优雅地解析你的SQL

本文内容组织形式 总结具体例子执行语句解析层优化层物理计划层执行层 猜你喜欢PS 总结 先写个总结&#xff0c;接下来会分别产出各个部分的源码解析&#xff0c;Spark SQL主要分为以下五个执行部分。 具体例子 接下来举个具体的例子来说明 执行语句 SELECT name, age FR…

【数据结构】4.单链表实现通讯录

在上一篇文章我们学会了用单链表来实现各种方法&#xff0c;在这一篇文章我们将在单链表的基础上实现通讯录。 0、准备工作 实现通讯录之前&#xff0c;我们还需要在单链表的基础上添加2个文件&#xff0c;头文件Contact.h和源文件Contact.c。Contact.c来实现通讯录方法的声明…

【bash】.bashrc

查看当前路径文件数量 alias file_num"ls -l | grep ^- | wc -l"查看文件大小 alias file_size"du -sh"alias ll alias ll"ls -ltrh"cd的同时执行ll alias cdcdls; function cdls() {builtin cd "$1" && ll }自定义prompt…

微信小程序实战案例 - 餐馆点餐系统 阶段 2 – 购物车

阶段 2 – 购物车&#xff08;超详细版&#xff09; 目标 把“加入购物车”做成 全局状态&#xff0c;任何页面都能读写在本地 持久化&#xff08;关闭小程序后购物车仍在&#xff09;新建 购物车页&#xff1a;数量增减、总价实时计算、去结算入口打 Git Tag v2.0‑cart 1. …

从红黑树到哈希表:原理对比与典型场景应用解析(分布式以及布隆过滤器)

在数据结构的世界里&#xff0c;红黑树一直以「自平衡二叉查找树」的身份备受赞誉。凭借红黑节点的精妙设计&#xff0c;它能将插入、删除、查找的时间复杂度稳定控制在 ( log ⁡ n ) (\log n) (logn)&#xff0c;成为处理有序数据的经典方案。然而&#xff0c;当业务场景对「…

游戏报错?MFC140.dll怎么安装才能解决问题?提供多种MFC140.dll丢失修复方案

MFC140.dll 是 Microsoft Visual C 2015 运行库的重要组成部分&#xff0c;许多软件和游戏依赖它才能正常运行。如果你的电脑提示 "MFC140.dll 丢失" 或 "MFC140.dll 未找到"&#xff0c;说明系统缺少该文件&#xff0c;导致程序无法启动。本文将详细介绍 …

《电子类专业:通往科技未来的钥匙》

一、电子类专业全景概览 在当今科技飞速发展的时代,电子类专业无疑占据着现代科技体系中基础与核心的重要地位。从我们日常生活中不可或缺的智能手机、电脑,到推动社会进步的人工智能、大数据技术,再到探索宇宙奥秘的航天航空设备,电子类专业的身影无处不在。它就像一把万…

Java--批量删除

前端部分 前端代码主要负责收集用户选择的学生记录的 id&#xff0c;并将这些 id 发送给后端的 DeleteMoreServlet 进行处理。 批量删除按钮绑定点击事件 $(".deleteMore").on("click",function(){// ... }); 当用户点击 “批量删除” 按钮时&#xff…