JavaSE-15笔记【注解(+2024新)】

文章目录

  • 1.注解概述
  • 2.几个常用的JDK内置的注解
    • 2.1 @Deprecated
    • 2.2 @Override
    • 2.3 @SuppressWarnings
    • 2.4 @FunctionalInterface
  • 3.自定义注解
    • 3.1 注解也可以定义属性
    • 3.2 注解的使用规则补充
  • 4.元注解
    • 4.1 @Retention
    • 4.2 @Target
    • 4.3 @Documented
    • 4.4 @Inherited
    • 4.5 @Repeatable
  • 5.通过反射获取注解
  • 6.一个小练习

1.注解概述

  • 什么是注解?
    ①注解是JDK1.5才引入的。
    ②注解可以标注在 类上,属性上,方法上 等。
    ③注解可以做到在不改变代码逻辑的前提下在代码中嵌入补充信息。

  • 注解与注释
    注释:给程序员看的,编译器编译时会忽略注释。
    注解:给编译器看的,或给其它程序看的,程序根据有没有这个注解来决定不同的处理方式。

  • 注解的重要性
    框架实现原理:框架 = 反射 + 注解 + 设计模式。

2.几个常用的JDK内置的注解

2.1 @Deprecated

@Deprecated用来标记过时的元素(比如类、方法、属性),在编译阶段遇到这个注解时会发出提醒警告,告诉开发者正在调用一个过时的元素比如过时的类、过时的方法、过时的属性等。

package annotationtest;

public class AnnotationTest01 {
    public static void main(String[] args) {
        MyClass01 myClass01 = new MyClass01();
        String m = myClass01.m;
        myClass01.doSome();
    }
}

@Deprecated
class MyClass01{
    @Deprecated
    public String m;

    @Deprecated
    public void doSome(){

    }
}

在IDEA中会有删除线及对应警告:
在这里插入图片描述

2.2 @Override

@Override只能修饰实例方法,被标注的方法必须是个重写方法,否则就会编译失败。

如下代码,尝试重写equals方法,但是传入的是String类型的参数,且标注在其他位置上也编译报错:

package annotationtest;

public class AnnotationTest02 {

    @Override
    public static int num = 100;


    @Override
//    public boolean equals(Object obj) {
    public boolean equals(String obj) {
        return super.equals(obj);
    }

    @Override
    public void m(){

    }
}

编译报错:
在这里插入图片描述

2.3 @SuppressWarnings

@SuppressWarnings(抑制警告的注解):在实际开发中,建议尽量不要忽略警告,而是真正的去解决警告。

该注解常见的属性值(并非所有):
① @SuppressWarnings(“rawtypes”):抑制未使用泛型的警告;
② @SuppressWarnings(“resource”):抑制未关闭资源的警告;
③ @SuppressWarnings(“deprecation”):抑制使用了已过时资源时的警告;
④ @SuppressWarnings(“all”):抑制所有警告。

package annotationtest;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("all")
public class AnnotationTest03 {
    public static void main(String[] args) throws Exception {
       @SuppressWarnings("rawtypes")
       List list = new ArrayList();

       @SuppressWarnings("resource")
       FileInputStream fileInputStream = new FileInputStream("D:\\1.txt");

       @SuppressWarnings("deprecation")
       MyClass01 myClass01 = new MyClass01();
    }
}

2.4 @FunctionalInterface

@FunctionalInterface“函数式接口”的注解,这个是 JDK1.8 版本引入的新特性。若一个接口使用@FunctionalInterface标注,则该接口就有且只能存在一个抽象方法,否则就会发生编译错误。(注意:接口中的默认方法或静态方法可以有多个。)

package annotationtest;

public class AnnotationTest04 {
    public static void main(String[] args) {

    }
}

@FunctionalInterface
interface Flyable{
     void fly();
     
     void run();
}

多于一个抽象方法则编译失败:
在这里插入图片描述
可以有其他默认方法和静态方法:
在这里插入图片描述

3.自定义注解

  • 使用 @interface来定义注解。
  • 默认情况下注解可以出现在类上、方法上、属性上、构造方法上、方法参数上等…
  • 所有自定义的注解,它的父类是:java.lang.annotation.Annotation

自定义注解:

package annotationtest;

public @interface MyAnnotation {
}

测试代码:

package annotationtest;

@MyAnnotation
public class AnnotationTest05 {
    @MyAnnotation
    private String name;

    @MyAnnotation
    public void doSome(){

    }

    public void toDO(@MyAnnotation String name, @MyAnnotation String password){

    }
}

3.1 注解也可以定义属性

  • 注解也可以定义属性,不过属性定义时,属性名后面必须加一个小括号。
    属性的类型只能是:
    byte,short,int,long,float,double,boolean,char、String、Class、枚举类型、注解类型,以及以上所有类型的一维数组形式。
  • 注解在使用时必须给属性赋值,除非你使用了default关键字为属性指定了默认值。

给注解加上属性:

package annotationtest;

public @interface MyAnnotation01 {

    byte b() default 1;

    short s();

    int i();

    long l();

    float f();

    double d();

    boolean flag() default true;

    char c();

    String name();

    Class clazz();

    Season season() default Season.AUTUMN;

    MyAnnotation annotation() default  @MyAnnotation;

    String[] words();
}

测试代码:

package annotationtest;

@MyAnnotation01(s=2,i=10,l=10l, f=20.1f,d=22.2,c=1, name="zhangsan",clazz=Integer.class,words={"day","month","year"})
public class AnnotationTest06 {
    
    @MyAnnotation01(s=2,i=10,l=10l, f=20.1f,d=22.2,c=1, name="zhangsan",clazz=Integer.class,words={"day","month","year"})
    private int m;
}

3.2 注解的使用规则补充

  • 如果属性只有一个,并且属性名是value时,使用注解时value可以省略不写。
  • 如果属性是一个数组,且名为value,使用注解时,数组值只有一个,数组的大括号是可以省略的。

定义注解Table,其中只有一个属性,且属性名为value:

package annotationtest;

public @interface Table {
    String value();
}

定义注解Parameter ,其中只有一个Strings数组属性,且名为value:

package annotationtest;

public @interface Parameter {
    String[] value();
}

测试代码:

package annotationtest;

@Table("t_user")
@Parameter("java")
public class AnnotationTest07 {

}

4.元注解

用来标注注解的注解叫做元注解。(也是JDK内置的注解。)

常用的元注解:

  • @Retention:设置注解的保持性
  • @Target:设置注解可以出现的位置
  • @Documented:设置注解是否可以生成到帮助文档中
  • @Inherited:设置注解是否支持继承
  • @Repeatable:设置注解在某一个元素上是否可以重复使用(Java8的新特性。)

4.1 @Retention

Retention英文意思有保留、保持的意思,它表示注解存在阶段是保留在源代码(编译期),字节码(类加载)或者运行时(JVM中运行)。
在@Retention注解中使用枚举属性RetentionPolicy来表示注解保留时期:

  • @Retention(RetentionPolicy.SOURCE):注解仅存在于源代码中,在字节码文件中不包含。
  • @Retention(RetentionPolicy.CLASS):注解在字节码文件中存在,但运行时无法获得(默认)。
  • @Retention(RetentionPolicy.RUNTIME):注解在字节码文件中存在,且运行时可通过反射获取。
package annotationtest.meta.meta01;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {
}

测试代码:

package annotationtest.meta.meta01;

import java.lang.annotation.Annotation;

@MyAnnotation
public class Test {
    public static void main(String[] args) throws Exception{
        //获取类
        Class clazz = Class.forName("annotationtest.meta.meta01.Test");

        //获取类上的注解
        Annotation annotation = clazz.getAnnotation(MyAnnotation.class);

        System.out.println(annotation);

    }
}

运行结果:
在这里插入图片描述
修改@Retention注解:

package annotationtest.meta.meta01;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}

再次测试结果:
在这里插入图片描述

4.2 @Target

用于描述注解可以使用的位置,该注解使用ElementType枚举类型用于描述注解可以出现的位置,
ElementType有如下枚举值:

  • @Target(ElementType.TYPE):作用于接口、类、枚举、注解。
  • @Target(ElementType.FIELD):作用于属性、枚举的常量。
  • @Target(ElementType.METHOD):作用于方法。
  • @Target(ElementType.PARAMETER):作用于方法参数。
  • @Target(ElementType.CONSTRUCTOR):作用于构造方法。
  • @Target(ElementType.LOCAL_VARIABLE):作用于局部变量。
  • @Target(ElementType.ANNOTATION_TYPE):作用于注解。
  • @Target(ElementType.PACKAGE):作用于包。
  • @Target(ElementType.TYPE_PARAMETER):作用于泛型,即泛型方法、泛型类和泛型接口。
  • @Target(ElementType.TYPE_USE):作用于任意类型。

定义只能用于方法上的注解:

package annotationtest.meta.meta02;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
public @interface MyAnnotation {
}

测试(使用在类上时编译失败):
在这里插入图片描述

4.3 @Documented

Documented的英文意思是文档。使用javadoc.exe工具可以从程序源代码中抽取类、方法、属性等注释形成一个源代码配套的API帮助文档,而该工具抽取时默认不包括注解内容。如果使用的注解被@Documented标注,那么该注解就能被javadoc.exe工具提取到API文档。

4.4 @Inherited

Inherited的英文意思是继承,但是这个继承和我们平时理解的继承大同小异,一个被@Inherited注解了的注解修饰了一个父类,则它的子类也继承了父类的注解。

定义可继承注解:

package annotationtest.meta.meta03;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME) //这个例子中为了测试时能够获取Cat上的注解,所以需要设置保持性
@Inherited
public @interface MyAnnotation {
}

Animal 类上加注解:

package annotationtest.meta.meta03;

@MyAnnotation
public class Animal {
}

Cat类继承Animal类:

package annotationtest.meta.meta03;

public class Cat extends Animal {
}

测试代码:

package annotationtest.meta.meta03;

public class Test {
    public static void main(String[] args) {
        Class<Cat> catClass = Cat.class;
        MyAnnotation annotation = catClass.getAnnotation(MyAnnotation.class);
        System.out.println(annotation);
    }
}

运行结果:
在这里插入图片描述

4.5 @Repeatable

Repeatable表示可重复的含义,该注解属于JDK1.8版本的新特性,表示可以可以重复使用该注解。

定义可重复注解:

package annotationtest.meta.meta04;

import java.lang.annotation.Repeatable;

@Repeatable(Authors.class) //必须加上一个参数,这个参数也是一个注解,是一个以注解Author数组为属性的注解
public @interface Author {
    
    String name();
}

辅助注解:

package annotationtest.meta.meta04;

public @interface Authors {

    Author[] value(); //这里属性名必须为value

}

测试:
在这里插入图片描述

5.通过反射获取注解

1)获取类上的所有注解:Annotation[] annotations = clazz.getAnnotations();
2)获取类上指定的某个注解:
clazz.isAnnotationPresent(AnnotationTest01.class)
AnnotationTest01 an = clazz.getAnnotation(AnnotationTest01.class);
3)获取属性上的所有注解:Annotation[] annotations = field.getAnnotations();
4)获取属性上指定的某个注解:
field.isAnnotationPresent(AnnotationTest02.class)
AnnotationTest02 an = field.getAnnotation(AnnotationTest02.class);
5) 获取方法上的所有注解:Annotation[] annotations = method.getAnnotations();
6)获取方法上指定的某个注解:
method.isAnnotationPresent(AnnotationTest02.class)
AnnotationTest02 an = method.getAnnotation(AnnotationTest02.class);

Annotation1注解:

package annotationtest.reflectannotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target({ElementType.TYPE,ElementType.FIELD})
public @interface Annotation1 {

    String name();
    int age();

}

Annotation2注解:

package annotationtest.reflectannotation;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Annotation2 {
    String email();
}

测试代码:

package annotationtest.reflectannotation;

import SuperTest.superTest03.A;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

@Annotation1(name = "zhangsan",age = 23)
@Annotation2(email = "wewerwerer23@126.com")
public class ReflectAnnotationTest {
    @Annotation1(name = "lisi", age = 29)
    public int sum;

    public static void main(String[] args) throws Exception {
        //获取类
        Class<ReflectAnnotationTest> aClass = ReflectAnnotationTest.class;

        System.out.println("获取本类上所有注解:");
        //获取类上所有注解
        Annotation[] annotations = aClass.getAnnotations();

        //遍历
        for (Annotation annotation: annotations) {
            System.out.println(annotation);
        }

        System.out.println("\n获取类上的Annotation1注解:");
        //判断类上是否有某个注解
        if(aClass.isAnnotationPresent(Annotation1.class)){
            //获取对应注解及属性
            Annotation1 annotation = aClass.getAnnotation(Annotation1.class);
            System.out.println(annotation);
            System.out.println(annotation.age());
            System.out.println(annotation.name());
        }

        //获取属性上的注解
        //1.先获取属性
        Field field = aClass.getDeclaredField("sum");

        System.out.println("\n获取属性"+ field.getName() +"上的Annotation1注解:");

        //2.判断该属性上是否有某个注解
        if(field.isAnnotationPresent(Annotation1.class)){
            //3.获取属性上的注解及其属性
            Annotation1 annotation1 = field.getAnnotation(Annotation1.class);
            System.out.println(annotation1);
            System.out.println(annotation1.name());
            System.out.println(annotation1.age());
        }
    }
}

运行结果:
在这里插入图片描述

6.一个小练习

  1. 储备知识:
    数据库是用来组织数据的,数据库使用表来组织数据。
    一张表应该有表名,例如:t_user
    一张表中应该有很多字段,每个字段有字段名和数据类型,例如age字段是int类型。
    数据库中整数对应的类型是:int。字符串对应的类型是:varchar。
    建表语句如下:
    在这里插入图片描述

编写程序扫描一个包下所有的类,凡是被 @Table 注解标注的类都要生成一条建表语句,表名在 @Table 注解中指定。被@Table 标注的类中的属性被 @Column 注解标注,在 @Column 注解中描述字段的名称和字段的数据类型。

Table注解:

package finaltest.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 凡是被@Table注解标注的类需要生成建表语句
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
    /**
     * 用来指定表名
     * @return 表名
     */
    String value();
}

Column注解:

package finaltest.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 该注解用于标注一个类中的属性,被标注的属性参与建表
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    /**
     * 字段的名字
     * @return 字段的名字
     */
    String name() default "";

    /**
     * 字段的数据类型
     * @return 字段的数据类型
     */
    String type() default "varchar";
}

User类:

package finaltest.a;

import finaltest.annotation.Column;
import finaltest.annotation.Table;

@Table("t_user")
public class User {

    @Column(name = "cid")
    private String uid;

    @Column(name = "uname")
    private String uname;

    @Column(name = "password")
    private String password;

    @Column(name = "age", type = "int")
    private int age;

    private String eamil;
}

Customer类:

package finaltest.c;

import finaltest.annotation.Column;
import finaltest.annotation.Table;

@Table("t_customer")
public class Customer {

    @Column(name = "cid")
    private String cid;

    @Column(name = "name")
    private String name;

    @Column(name = "age", type = "int")
    private int  age;

    private String address;
}

Vip类:

package finaltest.a.b;

import finaltest.annotation.Column;
import finaltest.annotation.Table;

@Table("t_vip")
public class Vip {
    @Column(name="vid")
    private String vid;

    @Column(name="name")
    private String name;

    @Column(name="grade")
    private String grade;
}

测试类:

package finaltest;

import finaltest.annotation.Column;
import finaltest.annotation.Table;

import java.io.File;
import java.lang.reflect.Field;

public class Test {
    private static String rootPath;
    private static StringBuilder sb = new StringBuilder(); //定义成全局变量更合理

    public static void main(String[] args) {
        //获取当前类路径的根路径
        rootPath = Thread.currentThread().getContextClassLoader().getResource(".").getPath();

        File file = new File(rootPath);

        try {
            generateCreateStatement(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void generateCreateStatement(File file) throws Exception {
        if(file.isFile()){ //file是一个文件的时候递归结束
            String classFileAbsolutePath = file.getAbsolutePath();
            //只针对字节码文件操作
            if(classFileAbsolutePath.endsWith(".class")){
                String className = classFileAbsolutePath
                                    .substring(rootPath.length()-1, classFileAbsolutePath.length() - ".class".length())
                                    .replace("\\",".");
                Class clazz = Class.forName(className);

                //判断类上是否有Table注解
                if (clazz.isAnnotationPresent(Table.class)){
                    Table tableAnnotation = (Table) clazz.getAnnotation(Table.class);
                    //获取表名
                    String tableName = tableAnnotation.value();

                    sb.append("create table ");
                    sb.append(tableName);
                    sb.append("(\n");

                    //获取所有声明的属性
                    Field[] fields = clazz.getDeclaredFields();

                    //遍历
                    for (Field field: fields) {
                        //判断属性上是否有Column属性
                        if(field.isAnnotationPresent(Column.class)){
                            Column columnAnnotation = field.getAnnotation(Column.class);
                            //属性名
                            String fieldName = columnAnnotation.name();
                            //属性类型
                            String fieldType = columnAnnotation.type();
                            sb.append("\t");
                            sb.append(fieldName);
                            sb.append(" ");
                            sb.append(fieldType);
                            sb.append(",\n");
                        }
                    }
                    //删除当前拼接的最后一个逗号
                    sb.deleteCharAt(sb.length()-2);
                    sb.append(");\n");
                }
            }
            System.out.println(sb);
            return;
        }

        //获取当前目录下所有文件
        File[] files = file.listFiles();
        for (File f : files){
            //递归
            generateCreateStatement(f);
        }
    }
}

运行结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker环境搭建

项目环境搭建 1、安装 Linux 虚拟机 &#xff08;1&#xff09;下载安装&#xff1a; VM VirtualBox 下载安装&#xff1a;Downloads – Oracle VM VirtualBox&#xff0c;要先开启CPU虚拟化 &#xff08;2&#xff09;通过vagrant&#xff0c;在VirtualBox中安装虚拟机 下…

500道Python毕业设计题目推荐,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【Java基础】21.重写(Override)与重载(Overload)

文章目录 一、重写(Override)1.方法重写2.方法的重写规则3.Super 关键字的使用 二、重载(Overload)1.方法重载2.重载规则3.实例 三、重写与重载之间的区别 一、重写(Override) 1.方法重写 重写&#xff08;Override&#xff09;是指子类定义了一个与其父类中具有相同名称、参…

LeetCode - 150. 逆波兰表达式求值

LeetCode - 150. 逆波兰表达式求值 解题思路&#xff1a; 想要解决该题目&#xff0c;我们首先需要知道什么是逆波兰表达式&#xff0c;逆波兰表达式是一种后缀表达式&#xff0c;所谓后缀就是指算符写在后面。 我们平常使用的算式则是一种中缀表达式&#xff0c;如( 1 2 …

Spring基础 SpringAOP

前言 我们都知道Spring中最经典的两个功能就是IOC和AOP 我们之前也谈过SpringIOC的思想 容器编程思想了 今天我们来谈谈SpringAOP的思想 首先AOP被称之为面向切面编程 实际上面向切面编程是面向对象的编程的补充和完善 重点就是对某一类问题的集中处理 前面我们写的统一异常管理…

React Router 6 + Ant Design:构建基于角色的动态路由和菜单

要根据用户的角色生成不同的路由菜单并实现权限控制,你可以采取以下步骤: 定义路由配置 首先,你需要定义一个包含所有可能路由的配置文件,例如: const routes [{path: /dashboard,element: <DashboardPage />,roles: [admin, manager, user]},{path: /users,element:…

设计模式——模板方法

1)模板方法模式(Template Method Pattem)&#xff0c;又叫模板模式(Template Patern)&#xff0c;在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现&#xff0c;但调用将以抽象类中定义的方式进行。 2)简单说&#xff0c;模板方法模式 定义一个操作中…

Splashtop Cloud RADIUS 解决方案入围教育技术奖

2024年4月17日 加利福尼亚州库比蒂诺 Splashtop 在简化随处办公的远程解决方案领域处于领先地位&#xff0c;该公司自豪地宣布最近入围了《教育技术文摘》&#xff08;EdTech Digest&#xff09;的“2024年教育技术奖”的“炫酷工具”决赛。教育科技奖成立于2010年&#xff0c…

都2024 年了,可以卸载的VS Code 插件

在 VS Code 中&#xff0c;庞大的插件市场提供了丰富多样的扩展功能&#xff0c;以增强编码体验和效率。然而&#xff0c;如果你安装了很多插件&#xff0c;就可能会导致&#xff1a; 性能下降&#xff1a;过多的插件可能导致 VS Code 的启动速度变慢&#xff0c;特别是在启动或…

【自动驾驶车辆-运动控制】运动学模型(Kinematic Model) | 手写数学推导公式 by.Akaxi

【前言】 在设计自动驾驶规控算法时&#xff0c;常常需要获取车辆的各种位姿、角度等信息&#xff0c;要控制车辆的运动&#xff0c;首先要对车辆的运动建立数字化模型&#xff0c;模型建立的越准确&#xff0c;对车辆运动的描述越准确&#xff0c;对车辆的跟踪控制的效果就越…

【Leetcode笔记】236.二叉树的最近公共祖先

文章目录 题目要求ACM运行结果 题目要求 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能…

过滤器Filter和拦截器Interceptor心得

上一篇文章讲了监听器Listener&#xff0c;下面我们来讲一下过滤器和拦截器。 一、过滤器Filter。 首先&#xff0c;servlet容器&#xff08;比如tomcat&#xff09;肯定的要有servlet才能发挥它的光彩。在上古jsp时代&#xff0c;我们会写各种servlet通过不同的请求来实现我…

浅说深度优先搜索(中)——回溯

写在最前 相信在你们不懈的努力之下&#xff0c;基本的递归一定可以写出来了&#xff0c;那么我们现在就来看看递归的升级版——回溯怎么写吧&#xff01; 简说回溯 递归是一种特别重要的解题策略。大部分题目需要找到最优解&#xff0c;而这个求解过程可能存在一定的规律性…

排序算法之基数排序

目录 一、简介二、代码实现三、应用场景 一、简介 算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度排序方式稳定性基数排序O(n*k)O(n*k)O(n*k)O(nk)Out-place稳定 稳定&#xff1a;如果A原本在B前面&#xff0c;而AB&#xff0c;排序之后A仍然在B的前面&#xff1b…

03-为啥大模型LLM还没能完全替代你?

1 不具备记忆能力的 它是零状态的&#xff0c;我们平常在使用一些大模型产品&#xff0c;尤其在使用他们的API的时候&#xff0c;我们会发现那你和它对话&#xff0c;尤其是多轮对话的时候&#xff0c;经过一些轮次后&#xff0c;这些记忆就消失了&#xff0c;因为它也记不住那…

笔记本电脑坏了硬盘数据会丢失吗 笔记本电脑坏了如何取出硬盘的资料 数据恢复软件

笔记本电脑对我们真的非常重要了&#xff0c;是实现无纸化办公和学习的重要工具&#xff0c;但是如果笔记本电脑坏了我们存储在电脑里的资料该怎么办&#xff1f;笔记本电脑坏了硬盘数据会丢失吗&#xff1f;相信有许多朋友都会有这样的担忧。本文今天就为大家解决笔记本电脑坏…

Docker 的基本管理

一. 云的相关知识 1. 关于云 云端服务器都有哪些提供商&#xff1a; 国内&#xff1a; 阿里云&#xff08;Alibaba Cloud&#xff09;&#xff1a; 提供ECS&#xff08;Elastic Compute Service&#xff09;弹性计算服务&#xff0c;包括通用型、计算型、内存型等多种实例…

CodeGemma初探

什么是 CodeGemma CodeGemma是一系列强大而轻量级的模型的集合&#xff0c;可以执行各种编码任务&#xff0c;包括填充中间代码补全、代码生成、自然语言理解、数学推理和指令跟随。 版本&#xff1a; instruct&#xff1a;7B, 这个版本专门针对自然语言到代码聊天和指令跟随…

【Linux高性能服务器编程】——高性能服务器框架

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之高性能服务器框架介绍&#xff0c;在这篇文章中&#xff0c;你将会学习到高效的创建自己的高性能服务器&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图来帮助大家来理解&…

解锁EDM设计秘籍:关键要素一览,邮件如何设计?

一个成功的EDM邮件需要包含多个关键元素&#xff0c;从内容、设计到呼唤行动&#xff0c;每个环节都至关重要。今天&#xff0c;我们就来探讨EDM邮件中应包含的关键元素&#xff1f;以及如何设计邮件&#xff1f; 一、EDM必备关键要素 1、吸引眼球的主题行 主题行应该简短明了…