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

商业网站域名后缀/广州关键词排名推广

商业网站域名后缀,广州关键词排名推广,如果做网站报价,浏览器谷歌手机版下载什么是并发编程? 并行:在同一个时间节点上,多个线程同时执行(是真正意义上的同时执行) 并发:一个时间段内,多个线程依次执行。 并发编程:在例如买票、抢购、秒杀等等场景下,有大量的请求访问…

什么是并发编程

并行:在同一个时间节点上,多个线程同时执行(是真正意义上的同时执行)

并发:一个时间段内,多个线程依次执行。

并发编程:在例如买票、抢购、秒杀等等场景下,有大量的请求访问同一个资源。会出现线程安全的问题,所以需要通过编程来解决多个线程依次访问资源,称为并发编程。

并发编程的根本原因:

  1. 多核cpu的出现,真正意义上可以做到并行执行
  2. java内存模型(JMM)

java内存模型,规范了Java虚拟机与计算机内存是如何协同工作的。

将内存分为主内存和工作内存。两个线程同时操作,会导致出错,本质原因在于内存模型设计。

共享数据存储在主内存中,每个线程都有各自的工作内存。操作共享数据时,会将主内存中的数据复制一份到工作内存中操作,操作完成后,再写回到主内存中。

但是一旦两个线程同时进行操作,读取共享数据,两个线程各自在工作内存中修改后,同时又写到主内存,这样就会与预期的结果不同。(AB两个线程同时操作变量n)

一、并发编程核心问题

由于java内存模型的设计,多线程操作一些共享的数据时,出现以下3个问题:

(1)不可见性:A线程在工作内存中操作共享数据时,B线程不知道A线程已经修改了数据。

(2)无序性:为了优化性能,有时候会改变程序中语句的先后顺序,以提高速度。

int a = 10;

io.read();//从其他地方读数据

int b = 5;

int c=a+b;

但是为了优化,第2行需要从其他地方读数据 需要时间;系统可能将3行代码乱序执行,例如 1、3、2的顺序执行。

有时,看似没有关系的代码乱序执行,可能会对后面的代码产生影响。

(3)非原子性

一个或多个操作在CPU执行的过程中不被中断的特性,我们称为原子性。 原子性是拒绝多线程交叉操作的,同一时刻只能有一个线程来对它进行操作

高级语言里一条语句往往需要多条CPU指令完成。如 count++,至少需要三条CPU指令。

  • 首先,需要把变量 count 从主内存加载到工作内存;
  • 之后,在工作内存执行 +1 操作;
  • 最后,将结果写入主内存;

解决办法

  1. 让不可见变为可见
  2. 让无序变为有序
  3. 非原子执行变为原子(加锁),由于线程切换执行导致

缓存(工作内存) 带来了不可见性;指令重排优化带来了无序性;线程切换带来了非原子性。

volatile可以解决前两个问题,加锁可以解决所有问题。

二、volatile关键字

volatile修饰的共享变量(类的成员变量、类的静态成员变量),被一个线程修改后,可以同步更新到其他线程,让其他线程中立即可见。volatile修饰的共享变量,指令是有顺序的。

但是volatile不能解决原子性问题,原子性问题由于线程切换执行导致。

volatile底层实现原理:

使用内存屏障(指令)进行控制。

  • 有序性实现:volatile修饰的变量,在操作前添加内存屏障,来禁止指令重排序。
  • 可见性实现:volatile修饰的变量添加内存屏障之外,还通过缓存一致性协议(MESI)将数据写回到主内存,其他工作内存嗅探后,如果自己工作内存中的数据过期,重新从主内存读取最新的数据。

三、如何保证原子性

同一时刻只有一个线程执行,称之为互斥。如果我们能够保证对共享变量的修改是互斥的,那么就能保证原子性了。

1、锁

只有通过加锁的方式,让线程互斥执行,来保证一次只有一个线程对共享资源进行访问

synchronized:关键字;修饰代码块、方法;自动获取锁,自动释放锁

ReentrantLock:类;只能对某段代码修饰;需要手动加锁,手动释放锁

2、原子变量

在java中还提供一些原子类,在低并发情况下使用,是一种无锁实现。

JUC(java.util.concurrent包)中,里面的locks包和atomic包,它们可以解决原子性问题。

1.原子类原理(AtomicInteger 为例)

原子类的原子性是通过volatile+CAS实现原子操作的。

低并发情况下:使用原子类 AtomicInteger,底层有一个变量通过volatile关键字修饰的,结合CAS机制实现。

2.CAS(重点)

采用CAS机制(Compare-And-Swap比较并交换),是一种无锁实现,在低并发情况下使用。CAS是乐观锁的方式,采用的是自旋的思想。

采用自旋思想:

(1)第一次从内存中读到内存值V

(2)对数据进行修改,将改变后的值写入到内存时,需要重新读取内存中最新的值,作为预期值A

(3)在写入前比较预期值与内存值,看是否一致:

  • 如果一致,说明其他线程没有修改内存中的值,将更新后的值,写入到内存;
  • 如果不一致,说明其他线程修改了主内存中的值,就需要重新计算变量值,反复这一过程。--->自旋

优点:

  • 不加锁,所有的线程都可以对共享数据操作;
  • 适合低并发使用,因为所有线程不会进入阻塞状态

缺点:

  • 大并发时,不停自旋判断,导致cpu占用率高
3.ABA问题

ABA问题,即线程1读取到内存值,线程2将内存值由A改为了B,再由B改为了A。当线程1去判断时,预期值与内存值相同,无法分辨内存值是否发生过变化。

通过设置版本号,每次操作改变版本号来避免ABA问题。如原先的内存值为(A,1),线程修改为(B,2),再修改为(A,3)。此时另一个线程使用预期值(A,1)与内存值(A,3)进行比较,只需要比较版本号1和3,即可发现该主内存中的数据被更新过了。

四、java中的锁

一些锁的名称指的是锁的特性、设计、状态,并不是都是锁。

1、乐观锁/悲观锁

乐观锁:没有加锁,不加锁的方式是没有问题的。例如CAS机制

悲观锁:必须加锁。悲观的认为,不加锁的并发操作一定会出问题。

2、可重入锁

synchronized和ReentrantLock是可重入锁,可以避免死锁。

A方法和B方法是两个同步方法,在同一个类中,用同一把锁,先进入到同步方法A中,锁被使用,在方法A调用方法B依然可以进入到方法B。(此时方法A还没有释放锁)

如果不是可重入锁的话,方法B不会被当前线程执行。

3、读写锁

ReentrantReadWriteLock,里面有一个读锁和写锁。

  • 读读不互斥:只有读没有写,可以多个线程同时读
  • 读写互斥:一旦有写操作,读写不同同时进行。
  • 写写互斥:多个写互斥
4、分段锁

不是锁,是一种锁实现思想:用于将数据分段,并在每个分段上都会单独加锁,以提高并发效率。

举例:Hashtable是将整合hash表格锁住了,一次只能有一个线程操作并发量低,效率低。

ConcurrentHashMap将每个哈希位置当做一个锁,可以有多个线程对map进行操作,一次只能有一个线程操作一个位置.

5、自旋锁

不是锁。是自己重试,当线程抢锁失败后,重试几次,如果抢到锁了就继续,如果抢不到就阻塞线程。

6、共享锁/独占锁

共享锁:一个锁可被多个线程共享,例如读写锁中的 读锁。

独占锁:一次只能有一个线程操作。例如:Synchronized、ReentrantLock,读写锁中的 写锁。

7、公平锁/非公平锁

公平锁:按照请求的顺序执行(排队,先来来执行)。

非公平锁:不按照请求顺序执行,谁先抢到谁先执行。

synchronized是一种非公平锁。ReentrantLock默认是非公平锁,但是底层可以通过AQS来实现线程调度,使其变成公平锁。

五、synchronized锁

1、锁的状态

synchronized锁的底层实现中,提供4种锁的状态,又来区别对待。(锁的状态在同步锁对象的对象头中,有一个区域叫Mark Word中存储)

  1. 无锁状态:没有线程进入。
  2. 偏向锁:始终只有一个线程访问同步代码快,记录线程的编号,快速的获取锁。
  3. 轻量级锁:当锁状态为偏向锁时,还有其他线程访问,此时升级为轻量级锁。特点:当一个线程获取锁之后,其他线程不会阻塞,会通过自旋方式获取锁,提高效率。
  4. 重量级锁:当锁的状态为轻量级锁时,线程自旋达到一定的次数,还没有获取到锁,就会进入到阻塞状态,锁状态升级为重量级锁,等待操作系统调度。

2、对象结构

在Hotspot虚拟机中,对象在内存中分为三块区域:对象头、实例数据和对齐填充;synchronized使用的锁对象是存储在对象头里。

对象头中有一块为Mark Word,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程ID等等。

32位操作系统Mark Word为32bit,64 位操作系统Mark Word为64bit。下面就是对象头的一些信息:

3、synchronized锁实现

synchronized锁是依赖底层编译后的指令,添加锁的监视器实现,需要我们提供一个同步对象,来记录是否加锁、以及锁的状态。

六、AQS

全称为(AbstractQueuedSynchronizer),这个类在java.util.concurrent.locks包下面。抽象同步队列,是java代码实现线程同步非常重要的一个底层实现类。

思路:

  • 在类中定义了一个state变量(初始化为0,表示有没有线程访问共享资源)和一个双向链表队列(head结点代表当前占用的线程)。
  • 有线程访问时,第一个抢到执行权的线程放在头节点,将state加1。期间如果有其他的线程访问时,如果state=1,将其他线程添加到队列中,等待锁的释放。

state由于是多线程共享变量,所以定义成volatile,以保证state的可见性,但不能保证原子性,所以AQS提供了对state的原子操作方法,保证了线程安全。

队列由Node对象组成,Node是AQS中的内部类。

AQS 的锁模式分为:独占和共享

独占锁:每次只能有一个线程持有锁,比如ReentrantLock是以独占方式实现的。

共享锁:允许多个线程同时获取锁,并发访问共享资源,比如ReentrantReadWriteLock

ReentrantLock锁实现

ReentrantLock是java.util.concurrent.locks包下的类,实现Lock接口。

public class ReentrantLock implements Lock, java.io.Serializable{ }

ReentrantLock基于AQS,在并发编程中可以实现公平锁和非公平锁来对共享资源进行同步。ReentrantLock类内部总共存在Sync、NonfairSync、FairSync三个,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQueuedSynchronizer抽象类。

ReentrantLock构造方法

  • 无参构造方法默认是非公平实现
  • 有参构造方法可以选择,true—公平实现,false—非公平实现

NonfairSync类继承了Sync类,表示采用非公平策略获取锁,其实现了Sync类中抽象的lock方法。 

static final class NonfairSync extends Sync {
//若通过 CAS 设置变量 state 成功,就是获取锁成功,则将当前线程设置为独占线程。
//若通过 CAS 设置变量 state 失败,就是获取锁失败,则进入 acquire 方法进行后续处理。final void lock() {if (compareAndSetState(0, 1))//每个线程进入到lock方法时,会尝试获取锁,有可能获取到了setExclusiveOwnerThread(Thread.currentThread());else//获取不到,将线程添加到队列中,排队获取锁acquire(1);}//尝试获取锁,无论是否获得都立即返回protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}
}

FairSync类也继承了Sync类,表示采用公平策略获取锁,其实现了Sync类中的抽象lock方法。

static final class FairSync extends Sync {final void lock() {//公平锁,默认排队获取锁acquire(1);}
}

七、JUC常用类

1、ConcurrentHashMap

HashMap是线程不安全的,不能在多线程环境下使用

Hashtable是线程安全的,但是synchronized直接锁住的是整个方法,效率低(public synchronized V put(K key,V value{}))

ConcurrentHashMap是线程安全的,效率高于Hashtable。

不像Hashtable将整个方法锁起来,将每个位置的第一个节点当做锁对象,将锁的力度减小,进而提高了效率;同时可以有多个线程对ConcurrentHashMap进行操作,如果多个线程操作的是同一个位置,那么必须等待,因为用的是同一把锁。当算出的位置,第一个节点为null时,采用CAS机制添加。

Hashtable和ConcurrentHashMap不支持存储null键和null值。源码中看到为null,就报空指针异常。为什么这样设计呢?

为了消除歧义,因为无法分辨key的值为null还是key不存在返回的null,这在多线程里面是模糊不清的,所以压根就不让 put null。

2、CopyOnWriteArrayList

ArraayList是线程不安全的,在高并发情况下可能会出现问题;

Vector是线程安全的,get、add方法都加锁,读读都互斥,效率低。

CopyOnWriteArrayList在读的时候不加锁,写入也不会阻塞读取操作,只有同时写入和写入之间需要进行同步等待,提高了读的效率。

CopyOnWriteArrayList在进行add、set等修改操作时,是通过底层数组的副本实现的。先将底层数组进行复制,修改复制出来的数组,修改后将数据赋值给原来的底层数组。写入时,不影响其他线程读

3、CopyOnWriteArraySet

CopyOnWriteArraySet线程安全的,底层使用的是CopyOnWriteArrayList不能存储重复数据

4、辅助类 CountDownLatch

CountDownLatch允许一个线程 等待其他线程各自执行完毕后再执行。底层实现是通AQS来完成的,创建CountDownLatch对象时指定一个初始值(线程的数量)。每当一个线程执行完毕后,AQS内部的state就-1,当state的值为0时,表示所有线程都执行完毕,然后等待的线程就可以恢复工作了。

八、对象引用

在JDK1.2版之后,Java对引用的概念进行了扩充,将引用分为:

  • 强引用
  • 软引用(SoftReference)
  • 弱引用(WeakReference)
  • 虚引用(PhantomReference)

这4种引用强度依次逐渐减弱。除强引用外,其他3种引用均可以在java.lang.ref包中找到它们的身影。

1、强引用(不是垃圾)

有引用指向该对象,Object obj = new Object(); 这种情况下new出来的对象不能被垃圾回收的。

软引用、弱引用、虚引用都是用来标记对象的一种状态。当一些对象称为垃圾后,通过不同的状态来判断什么时候被清理。可以继承SoftReference、WeakReference、PhantomReference或者把自己的对象添加到软、弱、虚的对象中。

2、软引用(内存不足时回收)

被软引用关联的对象,被判定为垃圾时,可以不用立即回收;直到垃圾回收后内存仍然不够用时,才会回收软引用关联的对象。

Object obj = new Object();// 声明强引用
SoftReference<Object> sf = new SoftReference<>(obj);
obj = null; //销毁强引用

3、弱引用(发现时回收)

弱引用管理的对象,只能存活到下一次垃圾回收。

4、虚引用(对象回收跟踪)

最弱的引用,对对象的生命周期没有任何的影响,跟踪对象是否被回收(如果对象被回收后,会给队列返回信息)

Object obj = new Object();
ReferenceQueue phantomQueue = new ReferenceQueue();//声明引用队列
PhantomReference<Object> sf = new PhantomReference<>(obj,phantomQueue);//声明虚引用(还需要传入引用队列),如果对象被回收后,会给队列返回信息
obj = null;

九、线程池

1、池的概念

如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,频繁创建线程和销毁线程需要时间。 可以事先创建出一些连接对象,每次使用时,从集合中直接获取,用完不销毁。减少频繁创建、销毁。

在 JDK5 版本中增加了内置线程池实现 ThreadPoolExecutor,同时提供了Executors来创建不同类型的线程池。

池的好处:减少频繁创建销毁时间,统一管理线程,提高速度。

2、ThreadPoolExecutor类

Java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类。

ThreadPoolExecutor继承了AbstractExecutorService类,并提供了四个构造器,但是前三个构造器都是调用的第四个构造器进行的初始化工作。

3、构造器中各个参数的含义

1.corePoolSize

核心池的大小,一旦创建不会被销毁的;非核心池中的线程,在没有被使用时,可以被回收。

2.maximumPoolSize

线程池最大线程数量,包含核心池中的数量。

3.keepAliveTime

非核心线程池中的线程,在不被使用后,多久就终止。(假如核心线程池5个,最大数量10,但是任务少的情况下,核心线程池够用了,等多长时间,就把非核心线程池中的线程终止)

4.unit

为keepAliveTime设置时间单位,有7种取值。

5.workQueue

一个阻塞队列,用来存储执行的任务。有以下工作队列:

  1. ArrayBlockingQueue:数组实现的有界阻塞队列,创建时必须设置长度,按FIFO排序。
  2. LinkedBlockingQueue:链表结构的阻塞队列,按FIFO排序任务,容量可以选择进行设置,不设置是一个最大长度为 Integer.MAX_VALUE;
6.threadFactory

创建线程的工厂

7.handler

拒绝策略。当线程池中的核心池、阻塞队列、非核心池已满时,如果有任务继续到达,如何执行。有以下四种拒绝策略:

  1. AbortPolicy();直接抛出异常,拒绝执行。
  2. CallerRunsPolicy();交由当前提交任务的线程执行(如果任务被拒绝了,则由提交任务的线程(例如:main)直接执行此任务)
  3. DiscardOldestPolicy();丢弃等待时间最长的任务。
  4. DiscardPolicy();直接丢弃,不执行。

4、线程池的执行

创建完成ThreadPoolExecutor之后,当向线程池提交任务时,通常使用execute方法。 execute方法的执行流程图如下:

当请求到来时,如果核心线程池没有满,就提交到核心线程池,如果核心线程池已满,则添加到队列中(前提是队列没有满);如果队列中已满,则在非核心线程中创建线程,直到到达最大线程数量;如果非核心线程池也已经满了,那么则使用适当的拒绝策略处理。

execute与submit的区别

  • execute() 提交任务,没有返回值
  • submit() 提交任务,可以有返回值(任务需要实现callable接口)

关闭线程池

  • shutdownNow() 直接关闭,对还未开始执行的任务全部取消
  • shutdown() 等待任务执行完关闭
//任务
public class MyTask implements Runnable {private int taskNum;public MyTask(int num) {this.taskNum = num;}@Overridepublic void run() {try {Thread.currentThread().sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":task "+taskNum+"执行完毕");}
}
public class Test {public static void main(String[] args) {//创建线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(2,5, 200,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());executor.prestartAllCoreThreads();for(int i=1;i<=8;i++){MyTask myTask = new MyTask(i);executor.execute(myTask);//添加任务到线程池//Future<?> submit = executor.submit(myTask);//submit.get();//返回值}executor.shutdown();}
}

十、ThreadLocal

本地线程变量,可以为每个线程都创建一个属于自己的变量副本,使得多个线程之间隔离,不影响。(在每一个线程里都有一个自己的localNum)

package com.ffyc.javapro.thread.threadlocal;public class ThreadLocalDemo {//创建一个ThreadLocal对象,复制保用来为每个线程会存一份变量,实现线程封闭private  static ThreadLocal<Integer> localNum = new ThreadLocal<Integer>(){@Overrideprotected Integer initialValue() {return 0;}};public static void main(String[] args) {new Thread(){@Overridepublic void run() {localNum.set(1);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}localNum.set(localNum.get()+10);System.out.println(Thread.currentThread().getName()+":"+localNum.get());//11}}.start();new Thread(){@Overridepublic void run() {localNum.set(3);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}localNum.set(localNum.get()+20);System.out.println(Thread.currentThread().getName()+":"+localNum.get());//23}}.start();System.out.println(Thread.currentThread().getName()+":"+localNum.get());//0(main线程)}
}

ThreadLocal底层实现:

在一个线程中使用ThreadLocal时,为每个当前线程创建了一个ThreadLocalMap,看似用唯一的ThreadLocal对象作为键,其实每个线程中都有一个属于自己的ThreadLocalMap,所以每个线程中都有一个自己的变量副本。

ThreadLocal会造成内存泄漏:

由于ThreadLocal被弱引用关联,有可能在下一次垃圾回收时被回收掉,会导致key为null,而value还存在着强引用。但是value却被Entry对象关联,Entry又被ThreadLocalMap关联,ThreadLocalMap又被Thread关联,要是当前线程长期不结束,value就不能被销毁,但是key有可能已被回收,就获取不到value造成内存泄漏。

正确的使用:不再使用这个本地线程变量后,将其主动删除掉,调用remove方法删除。

相关文章:

并发编程

什么是并发编程&#xff1f; 并行&#xff1a;在同一个时间节点上&#xff0c;多个线程同时执行(是真正意义上的同时执行) 并发&#xff1a;一个时间段内&#xff0c;多个线程依次执行。 并发编程&#xff1a;在例如买票、抢购、秒杀等等场景下&#xff0c;有大量的请求访问…...

Lauterbach使用指南之RunTime功能

Lauterbach使用指南之RunTime功能 前言 首先&#xff0c;请问大家几个小小问题&#xff0c;你清楚&#xff1a; Lauterbach这个工具是干什么用的吗&#xff1f;在软件运行过程中如何测量两个运行point之间的runtime时间呢&#xff1f;Lauterbach的RunTime功能具体应当如何来操…...

GaussDB数据库管理系统介绍

1.GaussDB的发展 2.GaussDB的生态 内部&#xff1a; 云化自动化方案。通过数据库运行基础设施的云化将DBA(数据库管理员)和运维人员的日常工作 自动化。外部&#xff1a; 采用与数据库周边生态伙伴对接与认证的生态连接融合方案&#xff0c;解决开发者/DBA难获取、应用难对接等…...

使用docker部署lnmp多站点

1. 创建一个 Docker 网络 以便容器可以在同一网络上进行通信 docker network create lnmpnetwork2. 运行 MySQL 容器&#xff1a; 运行 MySQL 容器并将其连接到创建的网络。确保将 MySQL 的端口映射到宿主机上&#xff0c;以便您可以从宿主机访问数据库。 将mysql的配置和数…...

实例详解:Java使用JWT和Redis实现高效单点登录(SSO)

前言 单点登录&#xff08;Single Sign-On&#xff0c;简称SSO&#xff09;是一种身份验证和访问控制机制&#xff0c;允许用户使用一组凭证&#xff08;如登录名和密码&#xff09;登录到多个应用程序中&#xff0c;而无需为每个应用程序单独进行身份验证。用户只需要登录一次…...

SQL中使用ROLLUP和CUBE函数轻松生成汇总行

在数据分析和报表制作中&#xff0c;通常需要对数据进行汇总和分组&#xff0c;我们常用的就是GROUP BY汇总数据&#xff0c;当我们想按照不同维度汇总时&#xff0c;往往需要编写多个GROUP BY预计&#xff0c;而借助ROLLUP 和 CUBE 函数可以一次性生成子总计和总计行&#xff…...

CentOS 7 安装和配置java环境

1 安装包准备 安装包可以通过下面地址进行版本选择安装&#xff1a; https://www.oracle.com/java/technologies/downloads/#java8 2 正式开始安装 本次分享的安装方法直接通过编辑/etc/profile文件实现java的安装 2.1 新建安装包存放目录 mkdir /java cd /java/ 2.2 解压安…...

「实验记录」CS144 Lab0 networking warmup

文章目录 一、Motivation二、SolutionsS1 - Writing webgetS2 - An in-memory reliable byte stream 三、Results四、Source 一、Motivation 第一个小测试 webget 是想让我们体验并模拟一下在浏览器中键入 URL 后获得远程服务器传来的内容&#xff0c;这并没有太大的难度&…...

html5怎么实现语音搜索

html5怎么实现语音搜索 谷歌的网站在他们首页发现了HTML5的新玩法——语音搜索。 注意&#xff1a; 只有webkit核心的浏览器才能使用 用法很简单 只需要在input添加属性x-webkit-speech即可&#xff0c;例子如下&#xff1a; 代码如下: <input type"text" x-…...

吴恩达《机器学习》1-2:什么是机器学习?

一、什么是机器学习&#xff1f; Arthur Samuel&#xff08;1959&#xff09;&#xff1a; 他定义机器学习为&#xff0c;在进行特定编程的情况下&#xff0c;给予计算机学习能力的领域。 Tom Mitchell&#xff08;1998&#xff09;&#xff1a; 他定义的机器学习是&#xff0c…...

基于STC系列单片机实现定时器扫描数码管显示定时器/计数器产生频率的功能

#define uchar unsigned char//自定义无符号字符型为uchar #define uint unsigned int//自定义无符号整数型为uint #define NixieTubeSegmentCode P0//自定义数码管段码为单片机P0组引脚 #define NixieTubeBitCode P2//自定义数码管位码为单片机P2组引脚 sbit LED P1^0;//位定义…...

Linux环境开发工具yum、makefile的使用 【Linux】

文章目录 Linux软件包管理器 - yumLinux下安装软件的方式yum查找软件包如何实现本地机器和云服务器之间的文件互传卸载软件Linux编译器 - gcc/g 程序的翻译过程1.预编译&#xff08;预处理&#xff09;2.编译&#xff08;生成汇编&#xff09;3.汇编&#xff08;生成机器可识别…...

第六章(6):Python中的函数—闭包和装饰器

1.闭包 在Python中,闭包是指函数与其相关的自由变量的一个整体。当一个函数返回了一个内部函数时,这个内部函数可以访问其定义所在的外部函数中的变量,即使这个外部函数已经返回了。这种特性就叫做闭包。 代码示意: def funca():x = 250def funcb():print(我仍然可以访问…...

Linux--安装与配置虚拟机及虚拟机服务器坏境配置与连接---超详细教学

一&#xff0c;操作系统介绍 1.1.什么是操作系统 操作系统&#xff08;Operating System&#xff0c;简称OS&#xff09;是一种系统软件&#xff0c;它是计算机硬件和应用软件之间的桥梁。它管理计算机的硬件和软件资源&#xff0c;为应用程序提供接口和服务&#xff0c;并协调…...

基于SSM的个性化美食推荐系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

Django 全局配置 settings 详解

文章目录 1 概述1.1 Django 目录结构 2 常用配置&#xff1a;settings.py2.1 注册 APP&#xff1a;INSTALLED_APPS2.2 模板路径&#xff1a;TEMPLATES2.3 静态文件&#xff1a;STATICFILES_DIRS2.4 数据库&#xff1a;DATABASES2.5 允许访问的主机&#xff1a;ALLOWED_HOSTS 1 …...

uniapp接口请求api封装,规范化调用

封装规范和vue中的差不多&#xff0c;都是统一封装成一个request对象&#xff0c;然后在api.js里面调用。 先创建一个utils文件夹&#xff0c;然后里面创建一个request.js&#xff0c;代码如下&#xff1a; export const baseURL 基础url地址const request (options) > …...

色彩校正及OpenCV mcc模块介绍

一、术语 1.光&#xff1a;是电磁波&#xff0c;可见光是可被人眼感知的电磁波。可见光大约在400-700nm波段。光子携带的能量与波长成反比&#xff0c;400nm--700nm之间的单色光的颜色从紫色渐变成红色。 2.光谱&#xff1a;除了太阳光源外&#xff0c;LED灯、白炽灯等各种照明…...

2023mathorcup大数据数学建模竞赛A题坑洼道路识别67页完整高质量原创论文

大家好&#xff0c;从昨天肝到现在&#xff0c;终于完成了本次mathorcup大数据数学建模竞赛A题基于计算机视觉的坑洼道路检测和识别的完整论文了。 给大家看一下目录吧&#xff1a; 摘 要&#xff1a; 10 一、问题重述 12 二&#xff0e;问题分析 13 2.1问题一 13 2.2问题…...

【k8s】5、资源管理命令-声明式

目录 一、 yaml和json介绍 1、yuml语言介绍 2、k8s支持的文件格式 3、yaml和json的主要区别 二、声明式对象管理 1、命令式对象配置 2、声明式对象配置 3、声明式对象管理命令介绍 三、编写资源配置清单 1、 编写yaml文件 2、 启动并查看资源 3、创建service服务对外…...

信息系统项目管理师教程 第四版【第6章-项目管理概论-思维导图】

信息系统项目管理师教程 第四版【第6章-项目管理概论-思维导图】 课本里章节里所有蓝色字体的思维导图...

【Flutter】Flutter 中的图片管理 图片优化的最佳实践

【Flutter】Flutter 中的图片管理 图片优化的最佳实践 文章目录 一、前言二、图片资源的重要性1. 对于项目复杂性的影响2. 性能和资源优化3. 国际化和多平台支持4. UI/UX 的角度看图片管理5. 图片资源与应用安全三、Flutter 中的图片资源分类1. Asset 图片2. 网络图片3. 本地文…...

dash--项目的前端展示简单基础

1.前置工作 创建虚拟环境&#xff1a; sudo apt-get install python3-venv # 安装 python3 -m venv venv # 在本目录下创建venv虚拟环境&#xff08;也是一个文件夹。如果用不到这个虚拟环境以后就rm -rf venv&#xff09; source venv/bin/activate # 激活虚拟环境临时使用清华…...

LeetCode 面试题 16.06. 最小差

文章目录 一、题目二、C# 题解 一、题目 给定两个整数数组 a 和 b&#xff0c;计算具有最小差绝对值的一对数值&#xff08;每个数组中取一个值&#xff09;&#xff0c;并返回该对数值的差 示例&#xff1a; 输入&#xff1a;{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8} 输出&…...

css-表格样式

滑动表格 外层嵌套一个盒子设置固定大小&#xff0c;并添加overflow:hidden auto只有y轴滑动&#xff0c;隐藏x轴滑动 表头固定不滑动可以添加position:sticky;top:0 <div style"width:878px;height:685px;overflow:hidden auto" class"tableDiv">…...

Linux对网络通信的实现

一、NIO为什么很少注册OP_WRITE事件 1、OP_WRITE触发条件&#xff1a;当操作系统写缓冲区有空闲时就绪。一般情况下写缓冲区都有空闲空间&#xff0c;小块数据直接写入即可&#xff0c;没必要注册该操作类型&#xff0c;否则该条件不断就绪浪费cpu&#xff1b;但如果是写密集型…...

【开源】基于SpringBoot的车险自助理赔系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 车辆档案模块2.4 车辆理赔模块2.5 理赔照片模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 车辆表3.2.3 理赔表3.2.4 理赔照片表 四、系统展示五、核心代码5.1 查询车…...

减少磁盘读/写中延迟时间的方法(交替编号,错位命名)

目录 1.延迟时间的优化空间2.交替编号3.磁盘地址结构的设计1.若物理地址结构是&#xff08;盘面号&#xff0c;柱面号&#xff0c;扇区号&#xff09;2.若物理地址结构是&#xff08;柱面号&#xff0c;盘面号&#xff0c;扇区号) 4.错位命名 关于磁盘延迟时间的概念请看博主的…...

Perl爬虫程序

以下是一个使用Perl爬虫程序&#xff0c;用于爬取图像。每行代码的中文解释如下&#xff1a; #!/usr/bin/perl ​ use strict; use warnings; use Mojo::UserAgent; use JSON; ​ # 创建一个Mojo::UserAgent实例 my $ua Mojo::UserAgent->new; ​ # 使用获取代理 my $prox…...

UE5使用Dash插件实现程序化地形场景制作

目录 0 dash下载后激活 1 初步使用 2 导入bridge的资产路径 3 练习成果 4 参考链接 0 dash下载后激活 1 初步使用 Dash插件点击蓝色的A&#xff0c;可以使用。 通过输入不同提示命令&#xff0c;来激活不同的功能。 2 导入bridge的资产路径 这里需要注意是UAsserts…...