JavaThread线程

目录

程序--进程--线程

程序:

进程:

线程:

进程和线程的关系

创建线程 

单线程模式

代码

图解

运行

代码

运行 

创建线程

方式一

代码

运行 

方式二

代码

运行

总结:

Thread类中常用的方法

1、

代码 

运行 

2、

代码 

运行 

3、

代码 

运行

4、

代码 

运行

5、

代码 

运行

​编辑

线程优先级 

操作系统线程任务调度算法

线程状态

新建 

就绪

运行

阻塞

死亡

守护线程

代码

运行

多线程的概念

何时需要多线程

多线程的优点

多线程的缺点

线程同步

多线程同步

加锁方式1:

Thread类

修饰代码块

代码 

运行

修饰方法

代码

运行

Runnable类

修饰代码块

代码

运行

修饰方法

代码

运行

加锁方式2:

代码

运行

synchronized 与 ReentrantLock区别

相同点:

不同点:

线程通信

代码 

运行

新增创建线程方式

代码

运行


程序--进程--线程

程序:

为解决某种问题,通过计算机语言编写的一系列指令(代码)的集合。

线程中的程序特指的是静态的,安装在硬盘上的代码集合。

进程:

运行中的程序(被加载到内存中),是操作系统进行资源分配的最小单位。

线程:

进程可以进一步细化为线程,是进程内最小的执行单位(具体要做的事情),是cpu进行任务调度的最小单位 。

运行中的QQ就是一个进程,操作系统会为这个进程分配内存资源,一个聊天窗口就认为是一个线程,这多个聊天窗口可以同时被cpu执行,但是这些聊天窗口属于进程,线程是属于进程的。

早期没有线程,早期cpu在执行时是以进程为执行单位的,进程单位还是比较大的,当一个进程运行时,其他的进程就不能执行,所以后来,将进程中的多个任务,细化为线程。cpu执行单位,也从进程转为更小的线程。

进程和线程的关系

1、一个进程可以包含多个线程;

2、一个线程只能隶属于一个进程,线程不能脱离进程存在;

3、一个进行更中至少有一个线程(即主线程)java中的main方法,就是用来启动主线程;

4、在主线程可以创建并启动其他线程;

5、所以线程都共享进程的内存资源。

创建线程 

单线程模式

代码

package com.ffyc.javathread.demo1;

public class Demo {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println("循环1:" + i);
        }
        for (int i = 0; i < 10; i++) {
            System.out.println("循环2:" + i);
        }
    }
}

图解

运行

代码
package com.ffyc.javathread.demo1;

public class Demo2 {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println("循环1:" + i);
        }

        test();

        System.out.println("最后的代码");
    }
    public static void test(){
        for (int i = 0; i < 10; i++) {
            System.out.println("循环2:" + i);
        }
    }

}

运行 

需求:想在java程序中有几件不相关的事情同时有机会进行进行。

可以在java中创建线程,把一些要执行的任务放在线程中执行,这样的话,都拥有让cpu执行的权力 

创建线程

方式一

MyThread 继承 Thread(线程)
重写Thread类中run()方法,在run()方法中来编写我们需要执行的任务代码 

调用start()启动线程  

代码
package com.ffyc.javathread.demo1; 
public class MyThread extends Thread{

    //run方法是线程执行任务的方法
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("MyThread"+i);
        }
    }
}
package com.ffyc.javathread.demo1;

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        /*//切记不能直接调用run(),普通方法调用,并不是启动线程
        myThread.run();*/
        //启动线程,启动线程后,并不是会立即执行的,需要操作系统的调度
        myThread.start();

        for (int i = 0; i < 10000; i++) {
            System.out.println("Test"+i);
        }
    }
}
运行 

方式二

创建一个任务,实现Runnable接口,把这个类不能称为线程,是一个任务类
重写Runnable接口中的run方法

代码
package com.ffyc.javathread.demo2; 
public class MyTask implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("MyTask:"+i);
        }

    }
}

main方法是用来启动java主线程的 

package com.ffyc.javathread.demo2;

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

        //创建一个任务的对象
        MyTask myTask = new MyTask();

        //真正意义上的创建了一个线程
        Thread thread = new Thread(myTask);
        //启动线程,去执行mytask任务
        thread.start();

        for (int i = 0; i < 10000; i++) {
            System.out.println("main:"+i);
        }
    }
}
运行

总结:

两种方法后期使用率上,第二种相对更高一些

1、避免了单一继承的局限性,因为java是单继承的 ,继承了Thread类,就不能继承其他类

2、更适合多线程共享同一份资源的场景

Thread类中常用的方法

Thread类表示线程,提供了很多的方法,来对线程进行控制。

1、

run();线程要执行的任务在run方法中进行定义

start();启动java线程的

构造方法

new  Thread(Runnable  runnable);接收一个任务对象

代码 

package com.ffyc.javathread.demo1; 
public class MyThread extends Thread{ 
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("MyThread"+i);
        }
    }
}
package com.ffyc.javathread.demo1;

public class Test {
    public static void main(String[] args) {
        MyThread myThread = new MyThread(); 
        myThread.start();

        for (int i = 0; i < 10000; i++) {
            System.out.println("Test"+i);
        }
    }
}

运行 

2、

new  Thread(Runnable  runnable,String  name);接收一个任务对象,并为线程设置名字

setName("我的线程1");为线程设置名字

String  getName();获得线程的名字

Thread.currentThread();在任务中获得当前正在执行的线程

代码 

package com.ffyc.javathread.demo2;

public class MyTask_Name implements Runnable{
    @Override
    public void run() {
        //在任务中,我想知道当前是那个线程正在执行
        //在任务中,通过currentThread()获得当前正在执行的线程
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName());
    }
}
package com.ffyc.javathread.demo2;

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

        MyTask_Name myTask_name = new MyTask_Name();

        Thread thread1 = new Thread(myTask_name,"线程1");
        thread1.setName("我的线程1");
        thread1.start();

        //又创建了一个线程,把同一个任务交给线程去执行
        Thread thread2 = new Thread(myTask_name);
        thread2.start();
    }
}

运行 

3、

setPriority(int p);设置优先级  1-10之间  默认是5

getPriority();获得优先级

代码 

package com.ffyc.javathread.demo3;

public class MyTask implements Runnable{
    @Override
    public void run() {
        //获得当前正在执行对象
        Thread thread = Thread.currentThread();
        //获得线程优先级
        System.out.println(thread.getName()+":"+thread.getPriority());

    }
}
package com.ffyc.javathread.demo3;

public class Test {
    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        Thread t1 = new Thread(myTask,"线程1");
        Thread t2 = new Thread(myTask,"线程2");

        //设置线程优先级  1-10之间  默认是5
        t1.setPriority(8);
        t2.setPriority(2);

        t1.start();
        t2.start();

        System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());
    }

}

运行

4、

sleep(long m);让线程休眠指定的时间  毫秒单位

代码 

package com.ffyc.javathread.demo3;

public class MyTask implements Runnable{
    @Override
    public void run() {
        //获得当前正在执行对象
        Thread thread = Thread.currentThread();
        if (thread.getName().equals("线程1")) {
            try {
                //让线程休眠 1000毫秒
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //获得线程优先级
        System.out.println(thread.getName() + ":" + thread.getPriority());
    }
}
package com.ffyc.javathread.demo3;

public class Test {
    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        Thread t1 = new Thread(myTask,"线程1");
        Thread t2 = new Thread(myTask,"线程2");

        //设置线程优先级  1-10之间  默认是5
        t1.setPriority(8);
        t2.setPriority(2);

        t1.start();
        t2.start();

        System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());
    }

}

运行

5、

join();让其他线程等待当前线程结束

代码 

package com.ffyc.javathread.demo3;

public class MyTask implements Runnable{
    @Override
    public void run() {
        //获得当前正在执行对象
        Thread thread = Thread.currentThread(); 
        //获得线程优先级
        System.out.println(thread.getName() + ":" + thread.getPriority());
    }
}
package com.ffyc.javathread.demo3;

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyTask myTask = new MyTask();
        Thread t1 = new Thread(myTask,"线程1");
        Thread t2 = new Thread(myTask,"线程2"); 

        t2.start();
        //让其他线程等待当前线程结束后再执行
        t2.join();
        t1.start();

        System.out.println(Thread.currentThread().getName()+":"+Thread.currentThread().getPriority());
    }

}

运行

线程优先级 

事实上,计算机只有一个CPU,各个线程轮流获得CPU的使用权,才能 执行任务;

优先级较高的线程有更多获得CPU的机会,反之亦然;

优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级 都是5,但是也可以通过setPriority和getPriority方法来设置或返回优 先级;

操作系统线程任务调度算法

先来先服务(FCFS)调度算法

短作业优先(SJF)调度算法

优先级调度算法

时间片轮转调度算法

高响应比优先级调度算法

多级反馈队列调度算法(集合了前几种算法的优点)

线程状态

线程再它的生命周期中会处于不同的状态;

线程生命周期,线程从创建到销毁,期间经历5个状态:

新建 

new  Thread();处于新建状态,此状态还不能被执行。

调用start()启动线程,让线程进入到就绪状态,

就绪

获得到cpu执行权后,线程进入到cpu执行

运行

运行中的线程可以被切换,又回到就绪状态,也可能因为休眠等原因进入到阻塞状态

阻塞

线程休眠时间到了  回到就绪状态

死亡

当线程中所有的任务执行完了,线程也就自动销毁

守护线程

守护线程也是线程中的一种,区别在于他的结束,如何一个线程是守护线程,那么它会等java中其他线程任务结束后,自动终止。

守护线程是为其他线程提供服务的,例如jvm中的垃圾回收线程,就是一个守护线程

代码

package com.ffyc.javathread.demo4;

public class Task implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("我是守护线程,我为大家服务");
        }
    }
}
package com.ffyc.javathread.demo4;

public class Test {
    public static void main(String[] args) {
        Task task = new Task();
        Thread thread = new Thread(task);
        //设置线程为守护线程,设置守护线程必须在启动前设置。
        thread.setDaemon(true);
        thread.start();

        for (int i = 0; i < 10000; i++) {
            System.out.println("main"+i);
        }
    }
}

运行

多线程的概念

多线程是指程序中包含多个执行单元,即在一个程序中可以同时运行多 个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行 执行的线程来完成各自的任务。

何时需要多线程

程序需要同时执行两个或多个任务。 

程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、 网络操作、搜索等。

多线程的优点

提高程序的处理能力,效率提高了.

提高CPU的利用率.

改善程序结构,将复杂任务分为多个线程,独立运行

多线程的缺点

线程也是程序,所以线程需要占用内存,线程越多占用内存也越多(小问题  可提升硬件设备);

多线程需要协调和管理,所以需要跟踪管理线程,使得cpu开销变大;

线程之间同时对共享资源的访问会相互影响,如果不加以控制会导致数据 出错.

线程同步

确保一个时间点只有一个线程访问共享资源。可以给共享资源加一把锁,哪个 线程获取了这把锁,才有权利访问该共享资源。

多线程同步

多个线程同时读写同一份共享资源时,可能会引起冲突。所以引入线程“同步”机制, 即各线程间要有先来后到;

同步 = 排队 + 锁  一次只能由一个线程访问共享资源

加锁方式1:

多个线程访问同一个共享的数据,如果不加以控制,在理论上就会出现问题

Thread类

使用synchronized关键字

修饰代码块

同步对象要求:

锁对象,必须多个线程对应的是同一个对象,可以是java中任何类的对象

作用:可以记录有没有线程进入到同步代码块中

synchronized (锁对象){ 
         使用锁对象的对象头中的一块空间来记录锁的状态
         同步代码块
}  

代码 
package com.ffyc.javathread.demo5;

public class TicketThread extends Thread{
    String name; 
    //静态变量,在内存中只有一份,两个线程对象共用同一个
    static int num = 10;
    //必须确保多个线程对应的是同一个对象即可
    static String s = new String();

    @Override
    public void run() {
        while (true){
            synchronized (s){
                if(num > 0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"买到了:"+num--);
                }else{
                    break;
                }
            }
        }
    }
}
package com.ffyc.javathread.demo5;

public class Test {
    public static void main(String[] args) { 
        TicketThread t1 = new TicketThread();
        t1.setName("窗口1");
        TicketThread t2 = new TicketThread();
        t2.setName("窗口2");

        t1.start();
        t2.start();
    }
}
运行

修饰方法

1、锁不需要我们提供了,会默认提供锁对象

2、synchronized如果修饰的是非静态的方法,锁对象是this

      synchronized如果修饰的是静态方法,锁对象是类的Class对象

      一个类只有一个Class类对象

代码
package com.ffyc.javathread.demo5;

public class TicketThread extends Thread{
    String name;
    //静态变量,在内存中只有一份,两个线程对象共用同一个
    static int num = 10; 

    @Override
    public void run() {
        while (true){
            if(num <= 0){
                break;
            }
            TicketThread.printTicket();
        }
    } 
    public static synchronized void printTicket(){
        if(num > 0){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"买到了:"+num--);
        }
    }
}
package com.ffyc.javathread.demo5;

public class Test {
    public static void main(String[] args) { 
        TicketThread t1 = new TicketThread();
        t1.setName("窗口1");
        TicketThread t2 = new TicketThread();
        t2.setName("窗口2");

        t1.start();
        t2.start();
    }
}
运行

Runnable类

修饰代码块
代码
package com.ffyc.javathread.demo6;

import com.ffyc.javathread.demo5.TicketThread;

public class Ticket implements Runnable{
    //对于多个线程来说,票数只有一份
    int num = 10;
    @Override
    public void run() {
        while (true){
            //this只有一个
            synchronized (this){
                if(num > 0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"买到了:"+num--);
                }else{
                    break;
                }
            }
        }
    }
}
package com.ffyc.javathread.demo6;

public class Test {

    public static void main(String[] args) {
        //创建了一个出票的任务
        Ticket ticket = new Ticket();

        Thread t1 = new Thread(ticket,"窗口1");
        Thread t2 = new Thread(ticket,"窗口2");
        t1.start();
        t2.start();
    }
}
运行

修饰方法
代码
package com.ffyc.javathread.demo6;

import com.ffyc.javathread.demo5.TicketThread;

public class Ticket implements Runnable{
    //对于多个线程来说,票数只有一份
    int num = 10;
    @Override
    public void run() {
        while (true){
            if(num <= 0){
                break;
            }
            printTicket();
        }
    }

    public synchronized void printTicket(){
        if(num > 0){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"买到了:"+num--);
        }
    }
}
package com.ffyc.javathread.demo6;

public class Test {

    public static void main(String[] args) {
        //创建了一个出票的任务
        Ticket ticket = new Ticket();

        Thread t1 = new Thread(ticket,"窗口1");
        Thread t2 = new Thread(ticket,"窗口2");
        t1.start();
        t2.start();
    }
}
运行

加锁方式2:

使用jdk中提供的ReentrantLock类实现加锁

ReentrantLock只能对某一段代码块加锁,不能对整个方法加锁

代码
package com.ffyc.javathread.demo7;

import java.util.concurrent.locks.ReentrantLock;

public class TicketTask implements Runnable{

    int num = 10;
    //提供一个实现加锁的对象
    ReentrantLock reentrantLock = new ReentrantLock();

    @Override
    public void run() {
        while (true){
            //加锁
            reentrantLock.lock();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                if(num > 0){
                    System.out.println(Thread.currentThread().getName()+":买到了"+num--);
                }else {
                    break;
                }
            }finally {//在finally块中保证锁必须释放
                //释放锁
                reentrantLock.unlock();
            }
        }
    }
}
package com.ffyc.javathread.demo7;

public class Test {
    public static void main(String[] args) {
        TicketTask ticketTask = new TicketTask();

        Thread t1 = new Thread(ticketTask,"窗口1");
        Thread t2 = new Thread(ticketTask,"窗口2");
        t1.start();
        t2.start();
    }
}

运行

synchronized 与 ReentrantLock区别

相同点:

都实现了加锁的功能

不同点:

1、synchronized是一个关键字,ReentrantLock是一个类

2、synchronized修饰代码块和方法ReentrantLock只能修饰代码块

3、synchronized可以隐式的加锁和释放锁,运行过程中如果出现了异常可以自动释放

     ReentrantLock需要手动的添加锁和释放锁,建议在finally代码块中释放锁。

线程通信

线程间的通信(在同步代码块的基础上,使用wait,notify来对线程进行控制) 

      wait(); notify();  notifyAll();
      这三个方法都是Object类中定义的方法
      这三个方法必须在同步代码块中使用
      这三个方法必须通过为锁的对象调用

代码 

package com.ffyc.javathread.demo8;

public class PrintNumThread extends Thread{
    static int num = 0;
    static Object o = new Object(); 

    @Override
    public void run() {
         while (true){
              synchronized (o){
                  //唤醒等待中的线程
                  o.notify();
                  if(num < 100){
                      System.out.println(Thread.currentThread().getName()+":"+ ++num);
                  }else {
                      break;
                  }
                  try {
                      //让线程等待,同时释放锁,等待的线程不能自己醒来,必须让另一个线程唤醒
                      o.wait();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
         }
    }
}
package com.ffyc.javathread.demo8;

public class Test {
    public static void main(String[] args) {
        PrintNumThread p1 = new PrintNumThread();
        p1.setName("线程1");
        PrintNumThread p2 = new PrintNumThread();
        p2.setName("线程2");

        p1.start();
        p2.start();
    }
}

运行

......

新增创建线程方式

实现Callable接口,重写call()方法

call()可以有返回值,可以抛出异常,还可以自定义返回结果的类型

代码

package com.ffyc.javathread.demo10;

import java.util.concurrent.Callable;

public class SumTask<T> implements Callable<T> {

    @Override
    public T call() throws Exception {
         Integer i = 0;
        for (int j = 0; j < 10; j++) {
            i+=j;
        }
        return (T)i;
    }
}
package com.ffyc.javathread.demo10;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Test {
    public static void main(String[] args) {
        SumTask<Integer> sumTask = new SumTask<>();
        FutureTask<Integer> futureTask = new FutureTask(sumTask);
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            //获取到线程执行结果
            Integer integer = futureTask.get();
            System.out.println(integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

运行

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

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

相关文章

python统计分析——一般线性回归模型

参考资料&#xff1a;python统计分析【托马斯】 当我想用一个或多个其他的变量预测一个变量的时候&#xff0c;我们可以用线性回归的方法。 例如&#xff0c;当我们寻找给定数据集的最佳拟合线的时候&#xff0c;我们是在寻找让下式的残差平方和最小的参数(k,d)&#xff1a; 其…

YooAsset快速入门

文章目录 YooAsset快速入门指南&#xff1a;YooAsset学习核心要掌握的要点主要包括以下几个方面&#xff1a;基于YooAsset进行游戏资源管理的应用实例 YooAsset快速入门指南&#xff1a; YooAsset是一款专为游戏开发设计的资产管理和分发系统&#xff0c;它能够帮助开发者高效…

服务器挖矿病毒解决ponscan,定时任务解决

服务器挖矿病毒解决ponscan&#xff0c;定时任务解决 挖矿病毒会隐藏chattr的操作权限&#xff0c;让我们无法删除病毒文件&#xff0c;杀掉病毒进程。所以要去下载chattr.c的文件&#xff0c;编译成a.out。然后再对原来的chattr文件的权限进行修改。然后覆盖掉它。 chattr.c …

Redis Pipelining 底层原理分析及实践

作者&#xff1a;vivo 互联网服务器团队-Wang Fei Redis是一种基于客户端-服务端模型以及请求/响应的TCP服务。在遇到批处理命令执行时&#xff0c;Redis提供了Pipelining(管道)来提升批处理性能。本文结合实践分析了Spring Boot框架下Redis的Lettuce客户端和Redisson客户端对P…

openlayers 入门教程(六):controls 篇

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

curl: (60) Peer‘s Certificate issuer is not recognized curl请求报错

此种情况多发生在自签名的证书或者证书和域名不对&#xff0c;报错含义是签发证书机构未经认证&#xff0c;无法识别。解决办法就是替换证书&#xff08;补充证书机构&#xff09;文件就好&#xff0c;如果没有可用的证书可以去Gworg申请一个。

从零到部署指南:Ubuntu上安装Boost和Crow库

1.安装boost 在安装Crow之前&#xff0c;需要确保您的系统中已经安装了Boost库。以下是Boost库安装步骤&#xff1a; 首先&#xff0c;从Boost官方网站或通过特定的链接下载Boost的源码&#xff0c;boost源码具体可参看这个链接&#xff1a; https://blog.csdn.net/duan199201…

Mongodb入门--头歌实验MongoDB 数据库基本操作

MongoDB 中聚合( aggregate )主要用于处理数据(诸如统计平均值,求和等)&#xff0c;并返回计算后的数据结果&#xff0c;通常由聚合管道操作符和聚合表达式组合&#xff0c;完成数据处理。功能有点类似 Sql 语句中的 sum()、agv() 等。 一、聚合管道操作符将文档定制格式输出&…

如何在 MySQL 中开启日志记录并排查操作记录

在数据库管理中&#xff0c;能够追踪和审查操作记录是至关重要的。这不仅有助于识别和分析正常的数据库活动&#xff0c;还可以在数据泄露或未经授权的更改发生时进行调查和响应。本文将介绍如何在 MySQL 中开启通用日志记录&#xff0c;并如何排查操作记录。 开启 MySQL 通用…

使用 EFCore 和 PostgreSQL 实现向量存储及检索

随着 ChatGPT 的兴起及其背后的 AIGC 产业不断升温,向量数据库已成为备受业界瞩目的领域。FAISS、Milvus、Pinecone、Chroma、Qdrant 等产品层出不穷。市场调研公司 MarketsandMarkets 的数据显示,全球向量数据库市场规模预计将从 2020 年的 3.2 亿美元增长至 2025 年的 10.5…

机器学习—无量纲化和降维(四)

什么是特征预处理&#xff1f; 通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程 1包含内容 数值型数据的无量纲化&#xff1a; 归一化标准化 2特征预处理API sklearn. preprocessing为什么要进行归一化 or 标准化&#xff1f; 特征的单位或者大小相差较大…

MATLAB | 这些美丽大方的弦图居然都是用MATLAB画的?

什么&#xff1f;这些美丽大方的弦图都是MATLAB画的&#xff1f;&#xff1f;&#xff1f; 没错都是由我本人开发的弦图绘制工具包实现的&#xff1a; chord chart 弦图https://www.mathworks.com/matlabcentral/fileexchange/116550-chord-chartDigraph chord chart 有向弦图…

【c语言】自定义类型:结构体详解

目录 自定义类型&#xff1a;结构体 结构体类型的声明 结构体变量的创建和初始化 结构的特殊声明 结构的自引用 结构体内存对齐 对其规则 为什么存在内存对齐&#xff1f; 修改默认对⻬数 结构体传参 结构体实现位段 位段的内存分配 位段的跨平台问题 位段的应用…

vue3新手笔记

setup&#xff08;&#xff09;{}函数&#xff0c;是启动页面后&#xff0c;自动执行的一个函数。所有数据&#xff08;常量、变量&#xff09;、函数等等&#xff0c;都要return 出去。 ref函数(可用于基本数据类型&#xff0c;也可以用于复杂数据类型)&#xff1a;让页面上的…

Java Set基础篇

目录 前言一、常用Set1.1 Set1.1.1 特点 1.2 HashSet1.2.1 特点1.2.2 使用 1.3 TreeSet1.3.1 特点1.3.2 使用 1.4 LinkedHashSet1.4.1 特点1.4.2 使用 二、对比总结 目录 前言 一、常用Set 1.1 Set Set是一个继承自Collection的接口&#xff1a; public interface Set<…

位图布隆过滤器的原理及实现

目录 位图的概念&#xff1a; 位图的前置知识&#xff1a;位运算 位图的实现&#xff1a; 位图的基本参数和构造方法&#xff1a; 位图的插入&#xff1a; 位图的查找&#xff1a; 位图的删除&#xff1a; 布隆过滤器概念&#xff1a; 布隆过滤器的实现&#xff1a; …

【软件测试之边界值法】

【软件测试之边界值法】(蓝桥杯学习笔记) 我们先来看一个 Java 小程序&#xff0c;如下图所示。 运行这个程序会发生什么事情呢&#xff1f;在这个程序中&#xff0c;目标是为了创建一个有 10 个元素的一维数组&#xff0c;但是&#xff0c;在 Java 语言中&#xff0c;当一个数…

win7无法升级win11,win7无法升级win11系统版本怎么解决

自动微软推出win11后,有不少小伙伴升级安装了。但是,有一些win7用户却安装win11失败,想知道有什么办法能让win7顺利升级win11。关于win7无法升级win11这个问题,最主要原因可能是你的电脑配置不够,毕竟升级win11的门槛要比升级win10还要高,而且还需要支持UEFI安全启动和TP…

Java项目:基于SSM+vue框架实现的人力资源管理系统设计与实现(源码+数据库+毕业论文+任务书)

一、项目简介 本项目是一套基于SSM框架实现的人力资源管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…

局域网tcp通信实验

两台windows系统计算机简单TCP通信测试_两台计算机tcp通信-CSDN博客 使用这篇文章的小工具。 环境&#xff1a; 我和同学的两台笔记本电脑。 使用我的手机开热点&#xff0c;两台电脑连接热点。 我的&#xff1a; IPv4 地址 . . . . . . . . . . . . : 192.168.92.79 子…