当前位置: 首页 > news >正文

线程池与反射

目录

一、手动创建线程池

1.线程池的执行流程

2.案例

二、Reflection反射

1.Class类

1.1 概述

1.2 Class类

1.3 Class常用方法

一、手动创建线程池

1.线程池的执行流程

(1)提交一个新线程任务,线程池会在线程池中分配一个空闲线程,用于执行线程任务。

(2)如果线程池中不存在空闲线程,则线程池会判断当前”存活的线程数“是否小于核心线程数corePoolSize。

(3)如果小于核心线程数corePoolSize,线程池会创建一个新线程(核心线程)去处理新线程任务。如果大于核心线程数corePoolSize,线程池会检查工作队列。

(4)如果工作队列未满,则将该线程任务放入工作队列进行等待。线程池中如果出现空闲线程,将从工作队列中按照FIFO的规则取出1个线程任务并分配执行。如果工作队列已满,则判断线程数是否达到最大线程数maximumPoolSize。

(5)如果当前”存活线程数“没有达到最大线程数maximumPoolSize,则创建一个新线程(非核心线程)执行新线程任务。如果当前”存活线程数“已经达到最大线程数maximumPoolSize,直接采用拒绝策略处理新线程任务。

综上所述,执行顺序为:核心线程、工作队列、非核心线程、拒绝策略。

int corePoolSize, 核心线程数量>0
int maximumPoolSize, 最大线程数(核心+临时)>corePoolSize
long keepAliveTime, 临时线程存活时间
TimeUnit unit, 存活的时间单位
BlockingQueue<Runnable> workQueue, 等待队列
ThreadFactory threadFactory, 线程工厂
RejectedExecutionHandler handler 拒绝策略-----ThreadPoolExecutor.AbortPolicy() 默认拒绝策略--抛异常-----ThreadPoolExecutor.DiscardOldestPolicy() 丢弃等待时间最久的任务-----ThreadPoolExecutor.DiscardPolicy();  拒绝最后来的任务-----ThreadPoolExecutor.CallerRunsPolicy();让当前的线程进行任务执行

2.案例

案例1:

 ExecutorService es = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),Executors.defaultThreadFactory(),
//                new ThreadPoolExecutor.AbortPolicy()
//                new ThreadPoolExecutor.DiscardOldestPolicy()
//                new ThreadPoolExecutor.DiscardPolicy()new ThreadPoolExecutor.CallerRunsPolicy());//提交任务给es对象es.execute(new MyRun("任务1"));//提交一个任务给es对象es.submit(new MyRun("任务2"));es.submit(new MyRun("任务3"));es.submit(new MyRun("任务4"));//核心线程已满,进入等待队列es.submit(new MyRun("任务5"));es.submit(new MyRun("任务6"));es.submit(new MyRun("任务7"));//核心线程已满,等待队列已满,进入临时线程es.submit(new MyRun("任务8"));es.submit(new MyRun("任务9"));//核心线程已满,等待队列已满,临时线程已满,进入拒绝策略es.submit(new MyRun("任务10"));

ArrayBlockingQueue<>与LinkedBlockingQueue<>的使用:

public class Demo07 {public static void main(String[] args) {
//        ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<>(3);
//        abq.offer("张三");
//        abq.offer("李四");
//        abq.offer("王五");
//
//        System.out.println(abq);
////        abq.remove("张三");
//        //取出第一个元素并出栈
//        abq.poll();
//        //取出第一个元素,但不出栈
////        abq.peek();
//        abq.offer("赵六");
//        System.out.println(abq);LinkedBlockingQueue<String> lbq=new LinkedBlockingQueue<>();lbq.offer("张三");lbq.offer("李四");lbq.offer("王五");lbq.offer("赵六");System.out.println(lbq);}
}

案例2:重写线程工厂ThreadFactory和拒绝策略RejectedExecutionHandler

        ExecutorService es = new ThreadPoolExecutor(3, 5, 60, TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),
//                Executors.defaultThreadFactory(),new MyThreadFactory("用户消费"),new MyRejectedHandler());//提交任务给es对象es.execute(new MyRun("任务1"));//提交一个任务给es对象es.execute(new MyRun("任务2"));es.execute(new MyRun("任务3"));es.execute(new MyRun("任务4"));//核心线程已满,进入等待队列es.execute(new MyRun("任务5"));es.execute(new MyRun("任务6"));es.execute(new MyRun("任务7"));//核心线程已满,等待队列已满,进入临时线程es.execute(new MyRun("任务8"));es.execute(new MyRun("任务9"));//核心线程已满,等待队列已满,临时线程已满,进入拒绝策略es.execute(new MyRun("任务10"));}
}
class MyThreadFactory implements ThreadFactory {//线程池名称前缀String namePrefix;public MyThreadFactory(String namePrefix) {this.namePrefix = namePrefix;}//具备原子性的Integer类型private AtomicInteger threadNumber=new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {return new Thread(r, namePrefix+"线程"+threadNumber.getAndIncrement());}
}
//重写拒绝策略
class MyRejectedHandler implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println("哎呦达到能执行任务的上线了,你待会再来!");}
}
class MyRun implements Runnable {String str;public MyRun(String str) {this.str = str;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "正在执行" + str);
//        try {
//            Thread.sleep(1000*5);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        System.out.println(Thread.currentThread().getName()+"执行结束"+str);while (true) {//死循环,目的验证线程池的执行流程}}
}

二、Reflection反射

1.Class类

1.1 概述

Java中,除了int等基本类型外,Java的其他类型全部都是class(包括interface)。例如:String、Object、Runnable、Exception、...

Java反射机制是Java语言的一个重要特性。在学习Java反射机制前,大家应该先了解两个概念:编译器和运行期。

编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程。在Java中也就是把Java代码编成class文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作。比如:检查语法错误。

运行期:是把编译后的文件交给计算机执行,直到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。在 Java 中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。

Java 反射机制在服务器程序和中间件程序中得到了广泛运用。在服务器端,往往需要根据客户的请求,动态调用某一个对象的特定方法或者为属性赋值。例如:在主流的 ORM 框架的实现中,运用 Java 反射机制可以读取任意一个 JavaBean 的所有属性,或者给这些属性赋值。

Java反射机制主要提供了以下功能,这些功能都位于java.lang.reflect包。

        在运行时判断任意一个对象所属的类。

        在运行时构造任意一个类的对象。

        在运行时判断任意一个类所具有的成员变量和方法。

        在运行时调用任意一个对象的方法。

        生成动态代理。

1.2 Class类

要想知道一个类的属性和方法,必须先获取到该类的字节码文件对象。获取类的信息时,使用的就是 Class 类中的方法。所以先要获取到每一个字节码文件(.class)对应的 Class 类型的对象。

class(包括interface)的本质是数据类型(Type)。class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。每加载一种classJVM就为其创建一个Class类型的实例,并关联起来。

注意:这里的Class类型是一个名叫Classclass,定义如下:

// final声明不允许继承
public final class Class {// 私有的构造方法private Class() {}
}

String类为例,当JVM加载String类时,它首先读取String.class文件到内存,然后,为String类创建一个Class实例并关联起来:

Class cls = new Class(String);

这个Class实例是JVM内部创建的,如果我们查看JDK源码,可以发现Class类的构造方法是private,只有JVM能创建Class实例,我们自己的Java程序是无法创建Class实例的。

所以,JVM持有的每个Class实例都指向一个数据类型(classinterface):

┌───────────────────────────┐
│      Class Instance       │──────> String
├───────────────────────────┤
│name = "java.lang.String"  │
└───────────────────────────┘
┌───────────────────────────┐
│      Class Instance       │──────> Random
├───────────────────────────┤
│name = "java.util.Random"  │
└───────────────────────────┘
┌───────────────────────────┐
│      Class Instance       │──────> Runnable
├───────────────────────────┤
│name = "java.lang.Runnable"│
└───────────────────────────┘

一个Class实例包含了该class的所有完整信息:

┌───────────────────────────┐
│      Class Instance       │──────> String
├───────────────────────────┤
│name = "java.lang.String"  │
├───────────────────────────┤
│package = "java.lang"      │
├───────────────────────────┤
│super = "java.lang.Object" │
├───────────────────────────┤
│interface = CharSequence...│
├───────────────────────────┤
│field = value[],hash,...   │
├───────────────────────────┤
│method = indexOf()...      │
└───────────────────────────┘

由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、所有方法、字段(成员变量)等,因此,如果获取了某个Class实例,我们就可以通过这个Class实例获取到该实例对应的class的所有信息。这种通过Class实例获取class信息的方法称为反射(Reflection)。

如何获取一个classClass实例?有三个方法:

方式一:直接通过一个class的静态变量class获取。

方式二:如果我们有一个实例变量,可以通过该实例变量提供的getClass()方法获取。

方式三:如果知道一个class的完整类名,可以通过静态方法Class.forName()获取。

        //1.获取类的字节码文件对象//方式1:直接通过一个class的静态变量class获取Class clazz1= Person.class;System.out.println(clazz1);//方式2:如果知道一个class的完整类名,可以通过静态方法Class.forName()获取Class clazz2=Class.forName("apesource.knowledge01.Person");System.out.println(clazz2);//方式3:通过具体的对象的getClass()方法获取Person p1=new Person();Class clazz3=p1.getClass();System.out.println(clazz3);

因为Class实例在JVM中是唯一的,所以,上述方法获取的Class实例是同一个实例。可以用==比较两个Class实例:

System.out.println(clazz1==clazz2);
System.out.println(clazz2==clazz3);

反射的目的是为了获得某个实例的信息。因此,当我们拿到某个Object实例时,我们可以通过反射获取该Objectclass信息:

void printObjectInfo(Object obj) {Class cls = obj.getClass();
}

要从Class实例获取获取的基本信息,参考下面的代码:

public class Demo02 {public static void main(String[] args) throws ClassNotFoundException {printClassInfo(Class.forName("apesource.knowledge01.Person"));}private static void printClassInfo(Class cls) {System.out.println("Class name:" + cls.getName());System.out.println("Simple name: " + cls.getSimpleName());if (cls.getPackage() != null) {System.out.println("Package name: " + cls.getPackage().getName());}System.out.println("is interface: " + cls.isInterface());System.out.println("is enum: " + cls.isEnum());System.out.println("is array: " + cls.isArray());System.out.println("is primitive: " + cls.isPrimitive());}
}
public class Person implements Serializable, Cloneable {String name;int age;public Person() {}public Person(String name) {this.name = name;}protected Person(int age) {this.age = age;}private Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

注意,数组(例如String[])也是一种类,而且不同于String.class,它的类名是[Ljava.lang.String;。此外,JVM为每一种基本类型如int也创建了Class实例,通过int.class访问。

如果获取到了一个Class实例,我们就可以通过该Class实例来创建对应类型的实例:

// 获取String的Class实例:
Class cls = String.class;// 创建一个String实例:
//要求实例时必须要有公开的无参构造方法,否则报错
String s = (String) cls.newInstance();
//Object o1=cls.newInstance();

上述代码相当于new String()。通过Class.newInstance()可以创建类实例,它的局限是:只能调用public的无参数构造方法。带参数的构造方法,或者非public的构造方法都无法通过Class.newInstance()被调用。

1.3 Class常用方法

类型

访问方法

返回值类型

说明

包路径

getPackage()

Package 对象

获取该类的存放路径

类名称

getName()

String 对象

获取该类的名称

继承类

getSuperclass()

Class 对象

获取该类继承的类

实现接口

getlnterfaces()

Class 型数组

获取该类实现的所有接口

构造方法

getConstructors()

Constructor 型数组

获取所有权限为 public 的构造方法

getDeclaredContruectors()

Constructor 对象

获取当前对象的所有构造方法

方法

getMethods()

Methods 型数组

获取所有权限为 public 的方法

getDeclaredMethods()

Methods 对象

获取当前对象的所有方法

成员变量

getFields()

Field 型数组

获取所有权限为 public 的成员变量

getDeclareFileds()

Field 对象

获取当前对象的所有成员变量

public class Demo03 {public static void main(String[] args) {Class clazz=Person.class;//包路径	getPackage()	Package对象	获取该类的存放路径Package pac=clazz.getPackage();System.out.println(pac);//类名称	getName()	String对象	获取该类的名称String strName=clazz.getName();System.out.println(strName);//继承类	getSuperclass()	Class对象	获取该类继承的类Class supclass=clazz.getSuperclass();System.out.println(supclass);//实现接口	getInterfaces()	Class型数组	获取该类实现的所有接口Class[] cles=clazz.getInterfaces();System.out.println(Arrays.toString(cles));}
}
public class Demo04RefConstructors {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//1.获取类的字节码文件对象Class clazz=Person.class;//2.获取构造方法// 2.1 getConstructors获取所有被public修饰的构造方法
//        Constructor[] cons=clazz.getConstructors();
//        for(Constructor con:cons){
//            System.out.println(con);
//        }//2.2 getDeclaredConstructors获取所有构造方法Constructor[] cons=clazz.getDeclaredConstructors();for(Constructor con:cons){System.out.println(con);}System.out.println("====================");//2.3 getConstructor获取某个被public修饰的构造方法Constructor con=clazz.getConstructor(String.class);System.out.println(con);//2.4 getDeclaredConstructor获取指定的某个构造方法Constructor<Person> con1=clazz.getDeclaredConstructor(String.class,int.class);System.out.println(con1);//3.解剖//包-0 public-1 private-2 protected-4int modifier=con1.getModifiers();System.out.println(modifier);System.out.println("权限修饰符是否是公共的:"+ Modifier.isPublic(modifier));//获取方法的形参Parameter[] pars=con1.getParameters();for(Parameter par:pars){System.out.println(par.getType()+"-"+par.getName());}//4.实例化对象con1.setAccessible(true);//临时取消权限校验符Person per=con1.newInstance("张三",12);System.out.println(per);}
}
import java.lang.reflect.Field;public class Demo05 {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {//1.获取类的字节码文件对象Class clazz = Dog.class;//2.获取成员变量//getFields()获取类中所有public修饰的成员变量(包括父类)
//        Field[] fields=clazz.getFields();
//        for(Field field:fields){
//            System.out.println(field);
//        }//getDeclaredFields()获取到本类中的所有的成员变量
//        Field[] fields=clazz.getDeclaredFields();
//        for(Field field:fields){
//            System.out.println(field);
//        }//getField()获取本类或父类中某个被public修饰的成员变量
//        Field field=clazz.getField("type");
//        System.out.println(field);//getDeclaredField获取到本类中某个成员变量Field field = clazz.getDeclaredField("color");System.out.println(field);//3.解剖//获取权限修饰符int modifiers = field.getModifiers();System.out.println("权限修饰符为:" + modifiers);//获取数据类型Class typeClass = field.getType();System.out.println("数据类型为:" + typeClass);//获取变量名String name = field.getName();System.out.println("此成员变量对象的变量名为:" + name);//4.应用Dog d2 = new Dog();Dog d1 = new Dog("小花", 1, "田园犬", 10.5, 20, "白色");
//        field.setAccessible(true);//临时取消权限修饰符//获取对象d1中此成员变量的值
//        Object obj = field.get(d1);
//        System.out.println("获取到成员变量type对应对象的值为:" + obj);//设置对象d1中此成员变量的值为黑白
//        field.set(d1, "黑白");
//        System.out.println(d1);//静态成员变量不依赖于对象field.setAccessible(true);//获取静态成员变量,不依赖于对象而存在,所以获取此成员变量的值时,可以不传对象Object obj = field.get(null);System.out.println("获取静态成员变量color对应的值为:" + obj);//设置成员变量值,静态成员变量共享一片空间,所以可以修改field.set(null, "黑白");System.out.println(d1);System.out.println(d2);}
}class Animal {public String name;private int age;public Animal() {}public Animal(String name, int age) {this.name = name;this.age = age;}
}class Dog extends Animal {public String type;protected double weight;int height;private static String color;@Overridepublic String toString() {return "Dog{" +"type='" + type + '\'' +", weight=" + weight +", height=" + height +", color='" + color + '\'' +'}';}public Dog() {}public Dog(String name, int age, String type, double weight, int height, String color) {super(name, age);this.type = type;this.weight = weight;this.height = height;this.color = color;}
}

案例:

public class Demo06 {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {ArrayList<Integer> list = new ArrayList<>();//获取list的成员变量elementData看长度Class clazz=list.getClass();Field field = clazz.getDeclaredField("elementData");field.setAccessible(true);Object[] obj=(Object[]) field.get(list);System.out.println(obj.length);//        list.add("123");//获取list的成员变量elementData看长度//        for (int i = 0; i < 20; i++) {
//            list.add(String.valueOf(i));
//            obj=(Object[]) field.get(list);
//            System.out.println("数组的长度为:"+obj.length+"元素个数"+list.size());
//        }//获取list的成员变量elementData看长度list.addAll(Arrays.asList(1,2,3,4,5,6,7,8,9,0,11));obj=(Object[]) field.get(list);System.out.println("数组的长度为:"+obj.length+"元素个数"+list.size());}
}

获取普通方法:

import java.lang.reflect.Method;public class Demo01 {public static void main(String[] args) throws NoSuchMethodException {//1.获取student类的字节码文件对象Class clazz = Student.class;//2.获取方法//getMethods获取本类和父类中所有被public修饰的方法
//        Method[] methods=clazz.getMethods();
//        for(Method method:methods){
//            System.out.println(method);
//        }//getDeclaredMethods获取本类中所有声明的方法
//        Method[] methods1=clazz.getDeclaredMethods();
//        for(Method method:methods1){
//            System.out.println(method);
//        }//getMethod,通过方法名和参数项获取本类或父类中某个被public修饰的方法
//        Method method=clazz.getMethod("eat",String.class);
//        System.out.println(method);//getDeclaredMethod,通过方法名和参数项获取本类中某个声明的方法Method method1 = clazz.getDeclaredMethod("eat", String.class);System.out.println(method1);}
}
public class Demo02 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {//1.获取student类的字节码文件对象Class clazz = Student.class;//2.getDeclaredMethod,通过方法名和参数项获取本类中某个声明的方法Method method = clazz.getDeclaredMethod("eat", String.class, int.class);//3.解剖//3.1 获取权限修饰符int number = method.getModifiers();System.out.println("权限修饰符为:" + number);//3.2 返回值类型Class returnType = method.getReturnType();System.out.println("返回值类型:" + returnType);//3.3方法名String methodName = method.getName();System.out.println("方法名为:" + methodName);//3.4参数项Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {System.out.println(parameter.getType() + "-" + parameter.getName());}//3.5异常信息Class[] classes = method.getExceptionTypes();for (int i = 0; i < classes.length; i++) {System.out.println("第" + (i + 1) + "个异常信息为:" + classes[i]);}//4.普通方法的调用//invoke(obj--对象,args--参数值)
//        Student s1=new Student();
//        s1.name="rosie";
//        method.setAccessible(true);//有返回值的方法调用
//        Object obj=method.invoke(s1,"小蛋糕",2);
//        System.out.println(obj);//5.静态方法的调用(不依赖于对象)Method method1 = Student.class.getDeclaredMethod("getUUID");Object uuid=method1.invoke(null);//静态方法,可以不传入对象System.out.println(uuid);}
}
import java.util.UUID;public class Student extends Person{private String name;private int age;private char gender;private double height;private String hobby;public Student() {}public Student(String name, int age, char gender, double height, String hobby) {super();this.name = name;this.age = age;this.gender = gender;this.height = height;this.hobby = hobby;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", gender=" + gender +", height=" + height +", hobby='" + hobby + '\'' +'}';}private void eat(){System.out.println("他喜欢吃垃圾食品");}private  String eat(String sth,int number) throws ClassCastException,IllegalAccessException,NullPointerException{return name+"喜欢吃"+sth+"每天"+number+"次";}protected static UUID getUUID(){return UUID.randomUUID();}void test(){System.out.println("这个是测试方法");}@Overridepublic void hello(){System.out.println("Student:hello");}
}

继承关系:Student继承自Person.

public class Person {public void hello(){System.out.println("Person:hello");}
}
public class Demo03 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {//1.获取Hello方法Method m1=Person.class.getMethod("hello");//对Person实例调用hello方法
//        Person p1=new Person();
//        m1.invoke(p1);//对Student实例调用hello方法Person p2=new Student();m1.invoke(p2);}
}

案例:

public class Teacher {private String name;private String subject;public void teach() {System.out.println("teach java");}public Teacher() {super();}public Teacher(String name, String subject) {super();this.name = name;this.subject = subject;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}@Overridepublic String toString() {return "Teacher [name=" + name + ", subject=" + subject + "]";}
}
//对于获取到的任意一个对象,请将对象中的所有的字段
public class Demo04 {public static void main(String[] args) throws IOException, IllegalAccessException {Student s1=new Student("rosie",20,'女',172,"唱跳");Teacher t1=new Teacher("彭王子","数据库");showMessage(t1);}//对于获取到的任意一个对象,请将对象中的所有字段和值保存到本地文件中,每个字段与其对应的值占用一行public static void showMessage(Object obj) throws IOException, IllegalAccessException {OutputStream os=new FileOutputStream("E:\\YuanJiuYuan\\IoTest\\a.txt");//请将对象中的所有字段和值保存到本地文件中,每个字段与其对应的值占用一行Class clazz=obj.getClass();Field[] fields=clazz.getDeclaredFields();for(Field field:fields){String name=field.getName();field.setAccessible(true);Object value=field.get(obj);os.write((name+"="+value+"\r\n").getBytes());}}
}

下面这段代码演示了Java反射机制的使用,通过读取配置文件动态加载类并调用指定方法,实现了程序的灵活性和可配置性。

public class Demo05 {public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {InputStream is=Demo05.class.getResourceAsStream("/prop.properties");Properties p1=new Properties();p1.load(is);System.out.println(p1.getProperty("classname"));System.out.println(p1.getProperty("method"));Class classname = Class.forName(p1.getProperty("classname"));Method method= Class.forName(p1.getProperty("classname")).getDeclaredMethod(p1.getProperty("method"));Object obj = classname.newInstance();method.invoke(obj);}
}

 

 

http://www.dtcms.com/a/323517.html

相关文章:

  • 动态规划(三维)直接按照题目条件
  • 基于STM32H5的循环GPDMA链表使用
  • Redis 事务机制
  • java基础(六)jvm
  • Vue3 路由
  • Chaos Monkey 故障注入工具使用介绍
  • Day37--动态规划--52. 携带研究材料(卡码网),518. 零钱兑换 II,377. 组合总和 Ⅳ,57. 爬楼梯(卡码网)
  • Web前端之 ECMAScript6
  • 【ros_humble】3.人脸检测python(服务通讯和参数通讯介绍)
  • 关于Linux软件编程1
  • leetcode 128. 最长连续序列 - java
  • 【网络与爬虫 51】Scrapy-Cluster分布式爬虫集群:企业级大规模数据采集解决方案
  • 卷积神经网络学习
  • 新手小白使用jQuery在实际开发中常用到的经验
  • 讯飞晓医-讯飞医疗推出的个人AI健康助手
  • 初学python的我开始Leetcode题15-2
  • Web自动化技术选择
  • SpringBoot日志关系
  • 【能碳建设1】用AI+开源打造物联网+能碳管理+交易SaaS系统的最短路径实施指南
  • C#:dnSpy
  • 【密码学】7. 数字签名
  • 聚众识别误报率↓78%:陌讯动态密度感知算法实战解析
  • CentOS7编译安装GCC
  • Python基础教程(六)条件判断:引爆思维Python条件判断的九层境界
  • Java Stream流详解:用法与常用API实战
  • Kotlin 协程线程切换机制详解
  • 规划是自动驾驶的“头脑”
  • 灰度测试(灰度发布、金丝雀发布)
  • 推荐系统学习笔记(十一)预估分数融合
  • leetcode-C语言-3479.水果成篮 III