7月24日JavaSE学习笔记

news2024/11/11 19:26:20

序列化版本控制

序列化:将内存对象转换成序列(流)的过程

反序列化:将对象序列读入程序,转换成对象的方式;反序列化的对象是一个新的对象

serialVersionUID 是一个类的序列化版本号

    private static final long serialVersionUID=1L;//版本号

如果序列化版本号没有定义,JDK会自动给予一个版本号,当该类发生变化时,序列化版本号会发生变化,反序列化就会失败;

java.io.InvalidClassException: com.easy724.Student; local class incompatible: stream classdesc serialVersionUID = -8506049007973969582, local class serialVersionUID = -401684047259788573

自定义版本号,只要该版本号不发生变化,即使该类中的属性或方法发生改变,该类的对象依旧可以反序列化。

注意:想要序列化,必须该类中的所有对象都是可序列化的(实现Serializable接口)


transient 关键字:暂存,禁止属性的值被序列化

    //transient 暂存,禁止属性的值被序列化
    private transient String sex;


flush方法

flush方法用于将输出流中的缓冲区内容立即写入目标设备,使得数据能够及时发送出去。

在Java中,几乎所有的输出流都具有flush方法。调用flush方法会强制将缓冲区中的数据写入目标设备,而不需要等到缓冲区被填满或者关闭流时才进行写入操作。

在使用输出流写入数据时,如果没有调用flush方法,写入的数据会先被缓存到缓冲区中,待到缓冲区填满或者手动调用flush方法时才会写入目标设备。但是,在某些情况下,我们需要立即将数据发送出去,例如需要实时更新数据时,可以调用flush方法来实现。

所有的输出流在结束之前都要执行一遍flush()方法


BIO、NIO、AIO

BIO、NIO、AIO 是 Java 编程语言中用于处理网络通信的三种不同的 I/O 模型。

BIO(Blocking I/O)是传统的同步阻塞式 I/O 模型。在这种模型中,每个连接都要创建一个线程进行处理,当有大量连接时,会导致线程数过多,资源消耗增加。

NIO(Non-blocking I/O)是一种基于事件驱动的同步非阻塞 I/O 模型。在这种模型中,I/O 操作不会阻塞线程,而是将 I/O 事件通知给选择器(Selector),然后通过一个或多个线程来处理这些事件。

AIO(Asynchronous I/O)是一种异步非阻塞 I/O 模型。它将数据的读写操作交给操作系统内核来处理,不需要通过线程池或者线程来阻塞等待结果,而是在操作完成后通过回调函数的方式来将数据返回给应用程序。

在高并发的场景下,NIO 和 AIO 的性能会比 BIO 更好。

同步与异步的区别在于:
同步:请求与响应同时进行,直到响应再返回结果;
异步:请求直接返回空结果,不会立即响应,但一定会有响应,通过通知、状态、回调函数响应

阻塞与非阻塞的区别在于:
阻塞:请求后一直等待
非阻塞:请求后,可以继续干其他事,直到响应


线程 Thread类

线程是指计算机中能够执行独立任务的最小单位。它是进程的一部分,一个进程可以包含多个线程。每个线程都是独立运行的,它们共享进程的资源,如内存空间和文件句柄等。线程之间可以通过共享内存进行通信,因此线程之间的切换开销较小。

进程是计算机中执行任务的基本单位,它是程序在执行过程中的一个实例。一个进程可以包含多个线程,每个线程执行不同的任务。进程之间是独立的,它们有自己独立的地址空间和资源。进程之间的通信需要经过额外的机制,如管道、消息队列等。

总结来说,线程是进程的一部分,是计算机中执行任务的最小单位。进程负责管理和分配资源,线程负责具体的任务执行。线程之间共享进程的资源,进程之间需要通过额外的机制进行通信。

常用方法

自定义线程 继承Thread,重写run方法,定义线程要执行的任务

子类抛出的异常只能比父类更精确,父类没有异常,子类的run不能抛出,要处理

1. 获取当前线程对象Thread.currentThread()

class ThreadA extends Thread{
    //重写run方法,定义线程要执行的任务
    @Override
    public void run(){
        for (int i=0;i<=20;i++){
            System.out.println(i+Thread.currentThread().getName());
        }
    }
}

2. 开启线程 start()

        //实例化线程对象
        ThreadA a = new ThreadA();
        ThreadA b = new ThreadA();
        //开启线程,多线程可能交叉执行
        a.start();
        b.start();
        //普通对象调用方法,通过main主线程依次执行
//        a.run();
//        b.run();

3. 休眠的方法 sleep()

sleep 是一个Thread类的静态方法,传入一个long类型的参数表示当线程运行到这里时要休眠多少毫秒,休眠结束后会自动启动线程。

    //休眠的方法 sleep
    public static void threadSleep() throws InterruptedException {
        System.out.println("1---------");
        //让运行到该行代码的线程休眠5秒
        Thread.sleep(5000);
        System.out.println("2---------");
    }

4. 设置优先级 setPriority()

优先级最小为1,最大为10,默认5;

优先级越高,获取CUP资源(时间片)的几率越大

并不是谁的优先级高就执行谁,也会出现交叉

    public static void priority(){
        Thread a=new ThreadB();
        Thread b=new ThreadB();
        //设置优先级:最大10,最小1,默认5    设置其他值报非法参数异常
        a.setPriority(4);
        b.setPriority(6);
        //优先级越高,获取CUP资源的几率越大(时间片)
        a.start();
        b.start();
    }

5. 礼让 yield

作用:让出CPU资源,让CPU重新分配;

防止一条线程长时间占用资源,达到CPU合理分配的效果;

sleep(0)也可以达到重新分配CPU资源的效果

    @Override
    public void run(){
        for(int i=0;i<20;i++){
            if(i%3==0){
                System.out.println(this.getName()+"---执行了礼让");
                Thread.yield();
            }
            System.out.println(i+this.getName());
        }
    }

6. 加入(插队)join()

在A线程中执行了B.join(),B线程运行完毕,A线程再运行

    @Override
    public void run(){
        for(int i=0;i<200;i++){
            if(i==10&&t!=null&&t.isAlive()){
                System.out.println(this.getName()+"----执行了JION");
                try {
                    t.join();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println(i+this.getName());
        }
    }

关闭线程:

1.执行stop方法 不推荐

2.调用interrupt()设置中断状态,这个线程不会直接中断, 我们需要在线程内部通过isInterrupted判断中断状态是否被设置,然后执行中断操作

    @Override
    public void run(){
        for(int i=0;i<100;i++){
            if(Thread.currentThread().isInterrupted()){//判断中断状态
                break;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(i);
        }
    }

3.自定义一个状态属性,在线程外部设置此属性,影响线程内部的运行

class ThreadG extends Thread{
    volatile boolean stop=false;//不稳定的,声明这个属性的值可能发生变化
    @Override
    public void run(){
        while (!stop){
            //System.out.println("A");
        }
    }
}

这里需要用到volatile关键字:不稳定的,易变的,声明这个属性的值可能发生变化

volatile关键字用于修饰变量,表示该变量是易变的(volatile变量)。当一个变量被声明为volatile时,它会告知编译器和虚拟机该变量可能会被多个线程同时访问并修改,因此需要特别注意线程可见性和指令重排序等问题。

对于使用了volatile修饰的变量,在线程外部对其进行修改后,其他线程在访问该变量时能够立即看到最新的值,而不会使用缓存中的旧值。

使用volatile关键字的一个常见应用场景是用于控制线程的停止标志。例如,我们可以定义一个volatile变量作为线程的停止标志,在外部设置该变量的值为true时,线程内部通过检查该变量的值来决定是否停止执行。

    public static void stopThread(){
        ThreadG a = new ThreadG();
        a.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        a.stop = true;
        System.out.println("设置关闭");
    }

volatile关键字在多线程编程中起到了两个主要作用:

  1. 可见性:如果一个变量被声明为volatile,当一个线程修改了该变量的值,其他线程可以立即看到变量的最新值。普通的变量在多线程环境下可能存在数据不一致的问题,因为线程A修改了变量的值,但是线程B在此之前已经缓存了该变量的旧值,导致线程B读取的是一个过期的值。使用volatile关键字可以避免这种情况发生,保证变量的可见性。

  2. 有序性:普通的变量在多线程环境下可能存在指令重排序的问题。指令重排序是指处理器为了提高执行效率,可能会对指令进行重新排序执行,但是重排序可能会导致代码的执行顺序与预期不一致。使用volatile关键字可以禁止指令重排序,保证代码的执行顺序与程序员编写的顺序一致

需要使用volatile关键字的主要原因是多线程环境下的可见性和有序性问题。在多线程编程中,为了保证数据的一致性和正确性,需要使用volatile关键字来解决这些问题。


线程的生命周期

线程的生命周期可以简要概括为以下几个状态:

  1. 新建(New):线程被创建但尚未开始执行。
  2. 就绪(Runnable):线程处于可运行状态,等待被分配CPU时间片以执行。此时可能有多个线程处于就绪状态,但只有一个线程能够获得CPU时间片执行。
  3. 运行(Running):线程获得了CPU时间片,正在执行线程体中的代码。
  4. 阻塞(Blocked):线程因为某些原因被阻塞,暂时停止执行。可能的原因包括等待某个操作完成、等待输入/输出、等待锁等。当阻塞条件满足时,线程会重新进入就绪状态。
  5. 等待(Waiting):线程因为调用了wait()方法,主动让出CPU并进入等待状态,直到其他线程调用了相同对象的notify()notifyAll()方法才能被唤醒。
  6. 超时等待(Timed Waiting):线程因为调用了带有超时参数的wait()join()sleep()方法,进入具有超时等待时间的等待状态。当超时时间到达或其他线程唤醒它时,线程会重新进入就绪状态。
  7. 终止(Terminated):线程执行完了所有的代码或者出现了未捕获的异常而意外终止。

线程安全

线程安全是多个线程操作一个对象,不会出现结果错乱的情况(不是指顺序不一致,是结果缺失)

同步(Synchronous)指的是线程按照顺序依次执行,前一个线程执行完毕后,下一个线程才能开始执行同步可以保证线程之间的操作按照一定的顺序和规则进行,从而避免竞争条件和数据不一致的问题。常用的同步机制包括使用锁(如synchronized关键字)、信号量、互斥量等。

异步(Asynchronous)指的是线程在执行任务时,不需要等待上一个任务的完成,而是同时执行多个任务。异步通常通过回调函数、事件驱动等方式实现。异步执行可以提高程序的性能和响应速度,但也需要考虑线程安全问题。

StringBuilder是线程不安全的,StringBuffer是线程安全的

//实现Runnable接口,是实现线程的一种方式,是一个任务,不是线程类
class RunA implements Runnable{
    StringBuffer strB;
    public RunA(StringBuffer strB){
        this.strB = strB;
    }
    @Override
    public void run() {
        for(int i=0;i<1000;i++){
            strB.append("0");
        }
    }
}

不继承Thread,通过实现Runnable接口也可以使用线程操作运行。

  1. 通过传入Runnable接口实现类的对象,可以将多个线程所需执行的任务抽象为一个统一的接口,避免了重复编写相同的代码。可以让多个线程对同一个对象操作。

  2. 在Java中,一个类只能继承自一个父类,但是可以实现多个接口。通过传入Runnable接口实现类对象,可以将线程任务类继承自其他的类,并且实现Runnable接口,提高灵活性。
        StringBuffer strB = new StringBuffer();
        RunA r=new RunA(strB);
        Thread a=new Thread(r);
        a.start();
        Thread b=new Thread(r);
        b.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(strB.length());
    }

StringBuilder当多个线程同时操作时,可能出现同时操作数组同一个位置的情况,导致数据缺失。

StringBuffer中的方法用synchronized修饰,同一时间内只允许一个线程执行


synchronized 同步

要做到线程安全,我们可以使用synchronized对方法或者代码块加锁,达到线程同步的效果;

使用synchronized关键字修饰的方法或代码,同一时间内,只允许一个线程执行此代码。

synchronized修饰方法:

    public static synchronized void test(){
        try {
            System.out.println("----进入方法----"+Thread.currentThread().getName());
            Thread.sleep(1000);
            System.out.println("----执行完毕----"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

修饰代码块:

    //同步代码块
    public static void testA(){
        System.out.println("进入方法"+Thread.currentThread().getName());
        synchronized (SyncThreadB.class){
            System.out.println("进入同步代码块"+Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("结束同步代码块"+Thread.currentThread().getName());
        }
    }

锁对象

在Java中,synchronized关键字用于实现线程同步,保证共享资源的安全访问。当一个线程请求进入synchronized代码块时,它必须先获得锁对象(也称为监视器对象、互斥锁),只有获得锁对象的线程才能进入临界区(synchronized代码块)执行代码。其他线程在未获取到锁对象时会进入等待状态,直到锁对象被释放。

锁对象可以是任意Java对象,可以是共享资源本身,也可以是一个专门用于控制同步访问的对象。当某个线程获得锁对象后,其他线程就无法同时进入相同的synchronized代码块,只能等待锁对象被释放。这样就保证了同一时间只有一个线程能够访问共享资源,从而避免了多线程并发访问带来的数据不一致或竞争条件的问题。

使用synchronized需要指定锁对象:

synchronized修饰成员方法时,锁对象就是 this(当前对象)

修饰静态方法时,锁对象是 类的类对象 如 obj.getClass() 或者 类名.class

类对象:用来描述一个类中定义的内容的对象。


锁的分类

以下是几种常见的锁分类:

  1. 悲观锁和乐观锁:悲观锁认为在并发情况下会发生冲突,所以默认加锁来保护共享资源。乐观锁则认为并发冲突的概率较低,采用无锁或轻量级锁的方式来实现并发控制。悲观锁有锁对象,乐观锁没有锁对象。

  2. 公平锁和非公平锁:公平锁按照线程请求锁的顺序进行获取,保证了先来后到的公平性。非公平锁则允许线程插队,不保证获取锁的顺序,提高了吞吐量。

  3. 可重入锁和不可重入锁:可重入锁允许同一个线程多次获取同一个锁对象的锁。当线程已经持有锁时,再次获取锁时不会被阻塞,而是增加锁的计数。不可重入锁则不允许同一个线程多次获取同一个锁。(可重入锁在同步代码块中遇到相同的锁对象的同步代码块,不需要再获取锁对象的权限,直接进入执行;Java里面全部都是可重入锁)

  4. 偏向锁,轻量级锁(自旋锁)和重量级锁:偏向锁适用于只有一个线程访问同步代码块的情况;轻量级锁适用于多个线程竞争同步代码块的情况,但竞争不激烈的场景;而重量级锁适用于竞争激烈的场景,多个线程频繁竞争同步代码块的情况。

偏向锁是一种针对线程访问同步代码块的优化手段。当一个线程获取了一个同步代码块的锁之后,如果没有其他线程竞争该锁,则持有锁的线程会偏向于该锁,在以后的访问中无需再经过同步操作,提高了性能。

轻量级锁(自旋锁)是一种针对多个线程竞争同步代码块的优化手段。当一个线程尝试获取一个同步代码块的锁时,如果当前锁处于偏向状态且偏向线程是当前线程,则可以直接获取锁而无需进入阻塞状态。如果当前锁不处于偏向状态,或者处于偏向状态但是偏向线程不是当前线程,则需要使用自旋等待锁的释放,而不阻塞线程。

重量级锁是一种针对多个线程竞争同步代码块的一种常规锁机制。当多个线程尝试获取同一个锁时,除了自旋等待锁的释放外,还会将未获取到锁的线程阻塞起来,直到锁的持有者释放锁,被阻塞的线程才能继续执行。


synchronized是什么锁?

synchronized关键字可以被看作是一种悲观锁,使用锁对象来实现线程同步。它确保在同一时间只有一个线程可以获取到锁对象,并进入synchronized代码块执行。其他线程需要等待锁对象被释放后才能进入。

synchronized关键字默认是非公平锁,也就是说,不会按照线程的启动顺序来获取锁,而是随机的。当多个线程同时竞争锁时,并不保证先尝试获取锁的线程一定会获得锁。

synchronized关键字是可重入锁,同一个线程可以重复获取锁对象。在同步代码块中,遇到相同的锁对象的同步代码块,不需要再次获取锁对象的权限,而是直接进入执行。

关于synchronized的锁类型,涉及到锁的状态。当没有竞争时,synchronized使用偏向锁来优化,如果有竞争,升级为轻量级锁(自旋锁),如果自旋不成功,则进一步升级为重量级锁。

综上所述,synchronized关键字可以被看作是一种悲观锁,使用锁对象实现线程同步。它是非公平锁,支持可重入性,并且在不同的竞争情况下可能升级为不同的锁类型。


乐观锁的实现方式?

乐观锁是一种并发控制机制,用于解决多线程同时访问共享资源可能导致的数据不一致问题。乐观锁的实现方式有两种常见的方式:CAS(Compare and Swap)和版本号控制

CAS(比较并交换)是一种无锁并发控制方式,它通过比较共享资源的当前值与期望值是否相等来判断其他线程是否修改了该值。如果相等,则将共享资源的值更新为新值,如果不相等,则表示有其他线程已经修改了该值,此时需要重新读取共享资源的值并重试。CAS操作是原子的,因此可以确保并发安全。

版本号控制是通过为共享资源增加一个版本号来实现的。每次修改共享资源时,都会更新版本号。当一个线程要修改共享资源时,首先读取共享资源的版本号,并保存为当前版本号。如果其他线程在此期间已经修改了共享资源,则当前版本号与保存的版本号不相等,此时需要放弃修改操作。通过版本号的比较,可以确保只有最新的修改才能成功。

两种方式各有优缺点。CAS方式由于没有锁的开销,在低并发情况下性能较好,但在高并发情况下会导致大量的重试,降低效率。版本号控制方式则可以避免重试,但需要维护额外的版本号字段,增加了存储和计算开销。

综上所述,选择使用哪种乐观锁实现方式,需要根据具体的应用场景和性能需求来决定。

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

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

相关文章

77.WEB渗透测试-信息收集-框架组件识别利用(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;76.WEB渗透测试-信息收集- WAF、框架组件识别&#xff08;16&#xff09; java&#xff…

The Llama 3 Herd of Models.Llama 3 模型论文全文

现代人工智能(AI)系统是由基础模型驱动的。本文提出了一套新的基础模型,称为Llama 3。它是一组语言模型,支持多语言、编码、推理和工具使用。我们最大的模型是一个密集的Transformer,具有405B个参数和多达128K个tokens的上下文窗口。本文对Llama 3进行了广泛的实证评价。我们…

【Django】前端技术HTML常用标签(开发环境vscode)

文章目录 安装两个常用插件HTML常用标签定义文档类型DOCTYPE网页的结构html/head//title/body/div标题h1/h2/h3/h4/h5分割线hr段落 p列表ul/li&#xff0c;ol/li超链接a文本span图片img按钮button表格table&#xff08;table、tr、th、td&#xff09;表单form 安装两个常用插件…

深度学习环境配置——总结下近期遇到的”坑“

文章目录 1. 问题1&#xff1a;硬件选择的误区2. 问题2&#xff1a;操作系统的适配难题3. 问题3&#xff1a;深度学习框架的安装陷阱4. 问题4&#xff1a;CUDA与cuDNN的版本匹配问题5. 问题5&#xff1a;网络配置的瓶颈6. 问题6&#xff1a;数据预处理的技巧7. 问题7&#xff1…

CVPR`24 | 4D编辑哪家强?浙大首次提出通用指导4D编辑框架:Instruct 4D-to-4D

文章链接&#xff1a;https://arxiv.org/pdf/2406.09402 项目地址&#xff1a;https://immortalco.github.io/Instruct-4D-to-4D/ 今天和大家一起学习的是Instruct 4D-to-4D&#xff0c;可以通过2D扩散模型实现4D感知和时空一致性&#xff0c;以生成高质量的指令引导的动态场景…

用户使用算力共享平台流程

目录 用户使用算力共享平台流程 一、用户注册与认证 二、接入算力资源 三、任务发布与管理 四、商业调度与资源分配 五、任务执行与结果验证 六、支付与结算 七、评价与信誉建立 算力架构概述 “以案赋能” | 首届“华彩杯”算力应用创新大赛全国总决赛获奖案例选编

【JUC】Java锁介绍

文章目录 阿里锁开发规范乐观锁和悲观锁悲观锁乐观锁 synchronized 类锁、对象锁synchronized有三种应用方式锁相关的8种案例演示&#xff08;对象锁、类锁&#xff09;标准访问ab两个线程&#xff0c;请问先打印邮件还是短信&#xff1f;sendEmail钟加入暂停3秒钟&#xff0c;…

【Python机器学习】决策树的构造——递归构建决策树

我们可以采用递归的原则处理数据集&#xff0c;递归结束的条件是&#xff1a;程序遍历完所有划分数据集的属性&#xff0c;或者每个分支下的所有实例都具有相同的分类。如果所有实例具有相同的分类&#xff0c;则得到一个叶子节点或者终止块。任何到达叶子节点的数据必然属于叶…

软考:软件设计师 — 7.软件工程

七. 软件工程 1. 软件工程概述 &#xff08;1&#xff09;软件生存周期 &#xff08;2&#xff09;软件过程 软件开发中所遵循的路线图称为 "软件过程"。 针对管理软件开发的整个过程&#xff0c;提出了两个模型&#xff1a;能力成熟度模型&#xff08;CMM&#…

uniapp引入自定义图标

目录 一、选择图标&#xff0c;加入购物车 二、下载到本地 三、导入项目 四、修改字体引用路径 五、开始使用 这里以扩展iconfont图标为例 官网&#xff1a;iconfont-阿里巴巴矢量图标库 一、选择图标&#xff0c;加入购物车 二、下载到本地 直接点击下载素材&#xff0…

mysql中You can’t specify target table for update in FROM clause错误

mysql中You can’t specify target table for update in FROM clause错误 You cannot update a table and select directly from the same table in a subquery. mysql官网中有这句话&#xff0c;我们不能在一个语句中先在子查询中从某张表查出一些值&#xff0c;再update这张表…

matplotlib 画图函数,最常用的

并排显示2个图片 import os import numpy as np from PIL import Image import matplotlib.pyplot as pltimage1 Image.open(a.png) image2 Image.open(a2.png)# Create a figure with two subplots (1 row, 2 columns) fig, axes plt.subplots(1, 2, figsize(10, 5))# Di…

使用Log4Net和中间件记录接口访问日志

一、功能概述 Log4Net log4net 是一个用于.NET应用程序的日志记录框架。它允许开发人员在他们的应用程序中记录各种信息&#xff0c;以便追踪应用程序的运行状态、排查问题和分析性能。log4net的主要作用包括&#xff1a; 日志记录: 记录应用程序的运行时信息&#xff0c;如调…

【单片机毕业设计选题24081】-路灯无线数据采集器

系统功能: 手机开启2.4G WiFi热点后再给系统上电 系统操作说明&#xff1a; 上电后OLED显示 “欢迎使用智能路灯系统请稍后”&#xff0c;两秒后显示Connecting...表示 正在连接阿里云&#xff0c;正常连接阿里云后显示第一页面&#xff0c;如长时间显示Connecting...请 检…

复现open-mmlab的mmsegmentation详细细节

复现open-mmlab的mmsegmentation详细细节 1.配置环境2.数据处理3.训练 1.配置环境 stage1&#xff1a;创建python环境 conda create --name openmmlab python3.8 -y conda activate openmmlabstage2&#xff1a;安装pytorch&#xff08;这里我是以torch1.10.0为例&#xff09…

昇思25天学习打卡营第22天|Pix2Pix实现图像转换

Pix2Pix图像转换学习总结 概述 Pix2Pix是一种基于条件生成对抗网络&#xff08;cGAN&#xff09;的深度学习模型&#xff0c;旨在实现不同图像风格之间的转换&#xff0c;如从语义标签到真实图像、灰度图到彩色图、航拍图到地图等。这一模型由Phillip Isola等人在2017年提出&…

《0基础》学习Python——第二十四讲__爬虫/<7>深度爬取

一、深度爬取 深度爬取是指在网络爬虫中&#xff0c;获取网页上的所有链接并递归地访问这些链接&#xff0c;以获取更深层次的页面数据。 通常&#xff0c;一个简单的爬虫只会获取到初始页面上的链接&#xff0c;并不会进一步访问这些链接上的其他页面。而深度爬取则会不断地获…

vue3 父组件 props 异步传值,子组件接收不到或接收错误

1. 使用场景 我们在子组件中通常需要调用父组件的数据&#xff0c;此时需要使用 vue3 的 props 进行父子组件通信传值。 2. 问题描述 那么此时问题来了&#xff0c;在使用 props 进行父子组件通信时&#xff0c;因为数据传递是异步的&#xff0c;导致子组件无法成功获取数据…

idea设置类注释模板作者、日期、描述等信息

文章目录 前言一、新建类的时候自动添加类注释1.打开设置2.模版配置示例如下3.实际生成效果 前言 由于每次换电脑时都需要重新对idea进行设置&#xff0c;为了方便大家的开发配置&#xff0c;同时也为自己以后配置留一份记录&#xff08;毕竟每次换环境都需要重新配置一遍&…

DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null

文章目录 一、报错内容二、原因三、DB2中的VARCHAR(100)类型能存储多少汉字&#xff1f; 一、报错内容 Cause: com.ibm.db2.jcc.am.mo: DB2 SQL Error: SQLCODE-302, SQLSTATE22001, SQLERRMCnull, DRIVER3.58.82 ; DB2 SQL Error: SQLCODE-302, SQLSTATE22001, SQLERRMCnull,…