Java面试黄金宝典6
1. 什么是 CAS
- 原理:
- CAS (Compare-And-Swap)是一种硬件级别的原子操作指令,在 Java 并发编程中常被用于实现无锁算法。其核心逻辑是:在进行数据更新时,会先将内存位置
V
的值与预期原值A
进行比较,如果二者相等,就把内存位置V
的值更新为新值B
;若不相等,则说明在这期间有其他线程对该内存位置的值进行了修改,此时不会执行更新操作。 - 在 Java 里,
sun.misc.Unsafe
类提供了对 CAS 操作的支持。不过,Unsafe
类的使用具有一定的风险性,所以 Java 又在java.util.concurrent.atomic
包下提供了一系列基于 CAS 实现的原子类,像AtomicInteger
、AtomicLong
等。
- CAS (Compare-And-Swap)是一种硬件级别的原子操作指令,在 Java 并发编程中常被用于实现无锁算法。其核心逻辑是:在进行数据更新时,会先将内存位置
- 要点:
- 原子性:CAS 操作由硬件指令直接保障其原子性,在执行过程中不会被其他线程中断,能有效避免多线程环境下的数据竞争问题。
- 无锁机制:与传统的加锁机制不同,CAS 操作无需加锁,这样就避免了线程阻塞和上下文切换带来的开销,从而提升了并发性能。
- ABA 问题:这是 CAS 操作面临的主要问题。当一个值从
A
变为B
后又变回A
时,CAS 操作会认为值没有发生改变,进而继续执行更新操作,然而实际上该值已经经历了变化。
- 应用:
- 解决 ABA 问题:可以借助带有时间戳的原子引用
AtomicStampedReference
来解决 ABA 问题。AtomicStampedReference
不仅会比较值是否相等,还会比较时间戳是否一致,只有当值和时间戳都匹配时才会执行更新操作。 - 应用场景:CAS 广泛应用于并发容器、原子类以及一些无锁算法的实现中,例如 Java 中的
ConcurrentHashMap
在部分操作上就运用了 CAS 来保证并发安全。
- 解决 ABA 问题:可以借助带有时间戳的原子引用
2. 什么是可重入锁 ReentrantLock
- 原理:
ReentrantLock
是java.util.concurrent.locks
包下的一个类,它实现了Lock
接口,是一种可重入的互斥锁。可重入意味着同一个线程能够多次获取同一把锁而不会被阻塞。每获取一次锁,锁的内部计数器就会加 1;每释放一次锁,计数器就会减 1。当计数器的值变为 0 时,锁才会被完全释放。ReentrantLock
内部通过AbstractQueuedSynchronizer
(AQS)来实现锁的状态管理和线程的排队等待。
- 要点:
- 手动锁管理:与
synchronized
不同,ReentrantLock
需要手动调用lock()
方法来获取锁,调用unlock()
方法来释放锁,通常要在finally
块中调用unlock()
以确保锁一定会被释放。 - 灵活性:
ReentrantLock
提供了更多的灵活性,比如可以选择实现公平锁或非公平锁,还支持中断锁等待、限时锁等待等功能。 - 条件变量:
ReentrantLock
可以配合Condition
对象使用,实现更精细的线程间通信和同步。
- 手动锁管理:与
- 应用:
- 公平锁和非公平锁的选择:公平锁能够保证线程获取锁的公平性,但会增加线程上下文切换的开销;非公平锁虽然可能导致某些线程长时间得不到锁,但可以提高系统的吞吐量。在实际应用中,需要根据具体的业务场景来选择合适的锁类型。
- 与
synchronized
的性能比较:在竞争不激烈的情况下,synchronized
和ReentrantLock
的性能相差不大;但在竞争激烈的场景下,ReentrantLock
的性能可能会更优。
3. 什么是乐观锁和悲观锁,阻塞锁,自旋锁,偏向锁,轻量锁,重量锁,公平锁,非公平锁,有哪些区别
- 乐观锁和悲观锁
- 原理:
- 乐观锁:它假定数据在大多数情况下不会发生冲突,所以在操作数据时不会加锁,而是在更新数据时检查数据是否被其他线程修改过。通常是通过版本号或时间戳等机制来实现。
- 悲观锁:它假定数据很容易发生冲突,因此在操作数据之前会先加锁,防止其他线程访问,确保在自己操作数据期间数据不会被其他线程修改。
- 区别:
- 适用场景:乐观锁适用于读多写少的场景,因为在这种场景下数据发生冲突的概率较低,使用乐观锁可以减少加锁和解锁的开销;悲观锁适用于写多读少的场景,因为在这种场景下数据发生冲突的概率较高,使用悲观锁可以保证数据的一致性。
- 性能:乐观锁的开销较小,因为它不需要加锁和解锁的操作;悲观锁的开销较大,因为它需要进行加锁和解锁操作,并且可能会导致线程阻塞和上下文切换。
- 原理:
- 阻塞锁和自旋锁
- 原理:
- 阻塞锁:当一个线程获取不到锁时,会被阻塞进入等待状态,直到锁被释放。此时线程会让出 CPU 资源,进入睡眠状态,等待其他线程释放锁后再被唤醒。
- 自旋锁:当一个线程获取不到锁时,不会进入阻塞状态,而是不断地循环尝试获取锁,在这个过程中线程会一直占用 CPU 资源。
- 区别:
- CPU 资源占用:阻塞锁会让出 CPU 资源,不会一直占用 CPU;自旋锁会一直占用 CPU 资源,直到获取到锁或达到自旋的最大次数。
- 适用场景:阻塞锁适用于锁的持有时间较长的场景,因为在这种情况下线程阻塞等待可以避免 CPU 资源的浪费;自旋锁适用于锁的持有时间较短的场景,因为在这种情况下线程不断自旋尝试获取锁的开销相对较小。
- 原理:
- 偏向锁、轻量锁和重量锁
- 原理:
- 偏向锁:在只有一个线程访问同步块时,会将锁偏向该线程。当该线程再次进入同步块时,无需进行任何同步操作,直接进入同步块执行代码,这样可以减少加锁和解锁的开销。
- 轻量锁:当有多个线程交替访问同步块时,会使用轻量锁。轻量锁通过 CAS 操作来获取和释放锁,避免了使用操作系统的互斥量,从而减少了线程阻塞和上下文切换的开销。
- 重量锁:当多个线程同时竞争锁时,轻量锁会升级为重量锁。重量锁使用操作系统的互斥量来实现同步,会导致线程阻塞和上下文切换,开销较大。
- 区别:
- 适用场景:偏向锁适用于单线程场景,开销最小;轻量锁适用于多线程交替访问场景,开销较小;重量锁适用于多线程同时竞争场景,开销最大。
- 锁的升级:锁的状态会根据线程的竞争情况进行升级,即从偏向锁升级为轻量锁,再升级为重量锁,但锁的状态不会降级。
- 原理:
- 公平锁和非公平锁
- 原理:
- 公平锁:多个线程按照申请锁的顺序来获取锁,先到先得。当一个线程释放锁后,会从等待队列中选择最早申请锁的线程来获取锁。
- 非公平锁:多个线程获取锁的顺序是不确定的,可能后申请的线程先获取到锁。当一个线程释放锁后,任何一个等待的线程都有机会获取锁。
- 区别:
- 公平性:公平锁可以保证线程获取锁的公平性,避免某些线程长时间得不到锁;非公平锁可能会导致某些线程长时间得不到锁。
- 性能:公平锁会增加线程上下文切换的开销,因为每次释放锁后都需要从等待队列中选择下一个线程;非公平锁可以提高系统的吞吐量,因为它减少了线程上下文切换的次数。
- 原理:
4. 什么是 ReentrantLock 和 synchronized,有什么区别
- 原理:
- synchronized:它是 Java 中的关键字,是一种内置的锁机制。当
synchronized
修饰实例方法时,使用的是对象锁;当修饰静态方法时,使用的是类锁;当修饰代码块时,需要指定锁对象。synchronized
会在进入同步块或同步方法时自动获取锁,在退出时自动释放锁。 - ReentrantLock:它是 Java 中的一个类,实现了
Lock
接口,是一种可重入的互斥锁。通过调用lock()
方法来获取锁,调用unlock()
方法来释放锁。
- synchronized:它是 Java 中的关键字,是一种内置的锁机制。当
- 区别
- 锁的获取和释放方式:
synchronized
是自动获取和释放锁,由 Java 虚拟机负责管理锁的生命周期,使用起来比较简单。ReentrantLock
需要手动获取和释放锁,使用时需要在finally
块中调用unlock()
方法,以确保锁一定会被释放,否则可能会导致死锁。
- 锁的灵活性:
synchronized
是一种比较简单的锁机制,缺乏灵活性,只能实现非公平锁,并且不支持中断锁等待和限时锁等待等功能。ReentrantLock
提供了更多的灵活性,可以选择实现公平锁或非公平锁,支持中断锁等待、限时锁等待等功能,还可以配合Condition
对象实现更精细的线程间通信和同步。
- 性能:
- 在竞争不激烈的情况下,
synchronized
和ReentrantLock
的性能相差不大,因为 Java 虚拟机对synchronized
进行了很多优化,如偏向锁、轻量锁等。 - 在竞争激烈的情况下,
ReentrantLock
的性能可能会更好,因为它可以根据具体的业务场景选择合适的锁类型,并且可以避免一些不必要的线程阻塞和上下文切换。
- 在竞争不激烈的情况下,
- 锁的获取和释放方式:
5. 重入锁、对象锁、类锁的关系
- 重入锁:
- 重入锁指的是同一个线程能够多次获取同一把锁而不会被阻塞。
ReentrantLock
和synchronized
都是可重入锁。当一个线程第一次获取锁时,锁的计数器会加 1,之后该线程再次获取同一把锁时,计数器会继续加 1;每次释放锁时,计数器会减 1,当计数器为 0 时,锁才会被完全释放。
- 重入锁指的是同一个线程能够多次获取同一把锁而不会被阻塞。
- 对象锁:
- 当
synchronized
修饰实例方法或代码块时使用的是对象锁。同一时刻只有一个线程可以访问该对象的被synchronized
修饰的方法或代码块。不同的对象实例拥有各自独立的对象锁,一个线程可以同时获取多个不同对象的对象锁。
- 当
- 类锁:
- 当
synchronized
修饰静态方法或代码块时使用的是类锁。类锁是基于类的Class
对象实现的,同一时刻只有一个线程可以访问该类的被synchronized
修饰的静态方法或代码块。所有该类的对象实例共享同一个类锁。
- 当
- 关系:
- 对象锁和类锁都是基于重入锁的机制实现的,它们的区别在于锁的范围不同。对象锁是针对对象实例的,不同的对象实例可以同时执行被
synchronized
修饰的实例方法或代码块;类锁是针对类的,所有该类的对象实例都需要竞争同一个类锁。
- 对象锁和类锁都是基于重入锁的机制实现的,它们的区别在于锁的范围不同。对象锁是针对对象实例的,不同的对象实例可以同时执行被
6. 如何创建线程?哪种好?
- 创建线程的方式
- 继承
Thread
类:- 创建一个类继承
Thread
类,并重写run()
方法,run()
方法中包含了线程要执行的代码。然后创建该类的实例并调用start()
方法启动线程。
- 创建一个类继承
- 继承
java
class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}
}
- 实现
Runnable
接口:- 创建一个类实现
Runnable
接口,实现run()
方法。然后创建该类的实例并将其作为参数传递给Thread
类的构造函数,最后调用start()
方法启动线程。
- 创建一个类实现
java
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Thread is running");}
}public class Main {public static void main(String[] args) {MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();}
}
- 实现
Callable
接口:- 创建一个类实现
Callable
接口,实现call()
方法,call()
方法可以有返回值。然后使用FutureTask
类将Callable
对象包装起来,再将FutureTask
对象作为参数传递给Thread
类的构造函数,最后调用start()
方法启动线程。可以通过FutureTask
的get()
方法获取call()
方法的返回值。
- 创建一个类实现
java
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {return 1 + 2;}
}public class Main {public static void main(String[] args) throws Exception {MyCallable callable = new MyCallable();FutureTask<Integer> futureTask = new FutureTask<>(callable);Thread thread = new Thread(futureTask);thread.start();System.out.println(futureTask.get());}
}
- 哪种好:
- 实现
Runnable
接口和Callable
接口的方式更好。因为 Java 是单继承的,继承Thread
类会限制类的扩展性,一个类一旦继承了Thread
类,就不能再继承其他类了。而实现Runnable
接口和Callable
接口可以让类继承其他类,同时还能实现多线程功能。此外,实现Runnable
接口和Callable
接口的方式可以更好地实现资源共享,多个线程可以共享同一个Runnable
或Callable
对象。
- 实现
7. 线程具体有哪些状态
Java 中的线程有以下六种状态,定义在 Thread.State
枚举中:
- NEW:线程刚被创建,但还没有调用
start()
方法。此时线程还没有进入运行状态,只是在 Java 虚拟机中分配了一些内存空间。 - RUNNABLE:线程正在 Java 虚拟机中执行,或者准备执行。它包含了操作系统线程状态中的就绪和运行两种状态。当线程调用
start()
方法后,会进入RUNNABLE
状态,此时线程可能正在 CPU 上执行,也可能在等待 CPU 资源。 - BLOCKED:线程正在等待获取一个监视器锁,进入同步块或同步方法时被阻塞。当一个线程试图进入一个已经被其他线程占用的同步块或同步方法时,会进入
BLOCKED
状态,直到获取到锁为止。 - WAITING:线程处于等待状态,需要其他线程显式地唤醒。例如调用
Object.wait()
、Thread.join()
或LockSupport.park()
方法会使线程进入WAITING
状态。在这种状态下,线程会释放持有的锁,直到被其他线程调用Object.notify()
、Object.notifyAll()
或LockSupport.unpark()
方法唤醒。 - TIMED_WAITING:线程处于定时等待状态,在指定的时间后会自动唤醒。例如调用
Thread.sleep(long millis)
、Object.wait(long timeout)
或LockSupport.parkNanos()
等方法会使线程进入TIMED_WAITING
状态。在这种状态下,线程也会释放持有的锁,等待指定的时间后会自动唤醒继续执行。 - TERMINATED:线程已经执行完毕,生命周期结束。当线程的
run()
方法执行完毕或者抛出未捕获的异常时,线程会进入TERMINATED
状态,此时线程占用的资源会被释放。
8. 一般线程和守护线程的区别
- 一般线程:也称为用户线程,是执行用户程序的主要线程。当所有用户线程执行完毕后,Java 虚拟机才会退出。用户线程可以通过继承
Thread
类、实现Runnable
接口或Callable
接口来创建。 - 守护线程:是一种为其他线程提供服务的线程,当所有用户线程执行完毕后,守护线程会自动终止,即使守护线程的任务还没有完成。守护线程通常用于执行一些后台任务,如垃圾回收线程、日志记录线程等。
- 区别:
- 生命周期:用户线程会影响 Java 虚拟机的退出,只有当所有用户线程都执行完毕后,Java 虚拟机才会退出;守护线程不会影响 Java 虚拟机的退出,当所有用户线程执行完毕后,守护线程会自动终止。
- 设置方式:可以通过
Thread.setDaemon(true)
方法将一个线程设置为守护线程,但必须在调用start()
方法之前设置,否则会抛出IllegalThreadStateException
异常。
9. 什么是 sleep wait yield notify notifyAll join,有什么区别
- sleep:
Thread.sleep(long millis)
是Thread
类的静态方法,用于让当前线程暂停执行指定的时间,线程进入TIMED_WAITING
状态。在睡眠期间,线程不会释放对象锁,其他线程无法获取该对象的锁。- 例如:
java
public class SleepExample {public static void main(String[] args) {Thread thread = new Thread(() -> {try {System.out.println("Thread is sleeping");Thread.sleep(2000);System.out.println("Thread wakes up");} catch (InterruptedException e) {e.printStackTrace();}});thread.start();}
}
- wait:
Object.wait()
是Object
类的方法,用于让当前线程进入等待状态,线程进入WAITING
或TIMED_WAITING
状态。当调用wait()
方法时,线程会释放对象锁,其他线程可以获取该对象的锁。需要其他线程调用notify()
或notifyAll()
方法来唤醒等待的线程。- 例如:
java
public class WaitExample {public static void main(String[] args) {final Object lock = new Object();Thread thread1 = new Thread(() -> {synchronized (lock) {try {System.out.println("Thread 1 is waiting");lock.wait();System.out.println("Thread 1 wakes up");} catch (InterruptedException e) {e.printStackTrace();}}});Thread thread2 = new Thread(() -> {synchronized (lock) {System.out.println("Thread 2 is notifying");lock.notify();}});thread1.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}thread2.start();}
}
- yield:
Thread.yield()
是Thread
类的静态方法,用于让当前线程放弃 CPU 时间片,进入就绪状态,让其他线程有机会执行,但不保证一定会让出 CPU。调用yield()
方法后,线程不会释放对象锁。- 例如:
java
public class YieldExample {public static void main(String[] args) {Thread thread1 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("Thread 1: " + i);Thread.yield();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("Thread 2: " + i);}});thread1.start();thread2.start();}
}
- notify:
Object.notify()
是Object
类的方法,用于唤醒在此对象监视器上等待的单个线程。如果有多个线程在等待,只会随机唤醒一个线程。
- notifyAll:
Object.notifyAll()
是Object
类的方法,用于唤醒在此对象监视器上等待的所有线程。被唤醒的线程会竞争对象锁,只有获得锁的线程才能继续执行。
- join:
Thread.join()
是Thread
类的方法,用于等待调用该方法的线程执行完毕。例如,thread.join()
会让当前线程等待thread
线程执行完毕后再继续执行。- 例如:
java
public class JoinExample {public static void main(String[] args) {Thread thread = new Thread(() -> {try {System.out.println("Thread is running");Thread.sleep(2000);System.out.println("Thread is finished");} catch (InterruptedException e) {e.printStackTrace();}});thread.start();try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Main thread continues");}
}
10. 什么是中断线程
中断线程是指一个线程向另一个线程发送中断信号,通知它应该停止执行。在 Java 中,可以通过调用 Thread.interrupt()
方法来中断一个线程。被中断的线程可以通过 Thread.interrupted()
或 Thread.isInterrupted()
方法来检查自己是否被中断。
Thread.interrupt()
:用于中断线程,设置线程的中断标志位。当调用interrupt()
方法时,如果线程处于WAITING
、TIMED_WAITING
或SLEEPING
状态,会抛出InterruptedException
异常,并清除中断标志位;如果线程处于其他状态,只会设置中断标志位。Thread.interrupted()
:是Thread
类的静态方法,用于检查当前线程是否被中断,并清除中断标志位。如果当前线程被中断,返回true
,否则返回false
。Thread.isInterrupted()
:是Thread
类的实例方法,用于检查线程是否被中断,不会清除中断标志位。如果线程被中断,返回true
,否则返回false
。
需要注意的是,调用 interrupt()
方法并不会立即终止线程,而是给线程一个中断信号,线程可以根据自己的逻辑来处理这个信号。例如,线程可以在捕获到 InterruptedException
异常时进行相应的处理,或者在适当的时机检查中断标志位,根据标志位的值来决定是否退出线程。
java
public class InterruptExample {public static void main(String[] args) {Thread thread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println("Thread is running");try {Thread.sleep(1000);} catch (InterruptedException e) {Thread.currentThread().interrupt(); // 重新设置中断标志位}}System.out.println("Thread is interrupted");});thread.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt();}
}
在这个例子中,线程会不断检查自己的中断标志位,当主线程调用 thread.interrupt()
方法时,线程会捕获到 InterruptedException
异常,然后重新设置中断标志位,最终退出循环。
友情提示:本文已经整理成文档,可以到如下链接免积分下载阅读
https://download.csdn.net/download/ylfhpy/90498450
相关文章:
Java面试黄金宝典6
1. 什么是 CAS 原理: CAS (Compare-And-Swap)是一种硬件级别的原子操作指令,在 Java 并发编程中常被用于实现无锁算法。其核心逻辑是:在进行数据更新时,会先将内存位置 V 的值与预期原值 A 进行比较&#x…...
【计算机网络】网络编程
文章目录 1. 客户端/服务器2. TCP/UDP协议3. 网络编程套接字-socket3.1 API的使用3.1 DatagramScoket类3.1 DatagramScoket类 4. 通过UDP实现回显服务器程序4.1 服务器代码4.2 客户端代码4.3 代码执行过程4.4 通过UDP实现翻译客户端 5. 通过TCP实现回显服务器5.1 服务器代码5.2…...
算法刷题整理合集(七)·【算法赛】
本篇博客旨在记录自已的算法刷题练习成长,里面注有详细的代码注释以及和个人的思路想法,希望可以给同道之人些许帮助。本人也是算法小白,水平有限,如果文章中有什么错误或遗漏之处,望各位可以在评论区指正出来…...
【开源宝藏】30天学会CSS - DAY6 第六课 流光文字动画
第 0 步:项目结构 lighting-text/├─ index.html└─ style.cssindex.html:包含列表 <ul>,其中每个 <li> 放一个字母或符号。style.css:设置背景、文字样式,以及关键帧动画(lighting…...
C#与西门子PLC的六大通信库
C#与西门子PLC的六大通信库: 一、S7.NET S7.NET是一款开源的S7协议通信库,支持西门子S7通信。 二、Sharp7 Sharp7与S7.NET一样,是一款.NET版本的S7通信库。 三、Snap7 Snap7是一个开源的C通信库,支持西门子S7通信。 四、Prodave P…...
VScode
由于centos停止了维护 ,后面使用ubuntu 在Ubuntu中用vscode 充当记事本的作用 替代了centos中vim的作用 后面使用vscode编辑 vscode中继续使用makefile , xshell中的cgdb进行debug (半图形写 ,半命令行debug&&运行) 官网下载地址:https://code.visuals…...
Linux文件系统与磁盘管理
文件系统和磁盘管理是Linux系统管理的核心组成部分,直接影响系统的性能、数据安全性和存储效率。本文将从Linux文件系统的基本概念出发,深入探讨其架构、类型、管理工具以及实际操作技巧,帮助读者全面理解并掌握这一关键领域。 第一章&#x…...
【云馨AI-大模型】大模型的开发和应用中,Python、PyTorch和vLLM关系概括
说明 1. Python 定位:基础编程语言。作用:Python 是大模型生态系统的核心语言,几乎所有深度学习框架(如 PyTorch、TensorFlow)和工具链(如 vLLM)都通过 Python 接口提供服务。特点:…...
AWS SAP学习笔记-概念
1、什么是ETL应用程序,举个例子说明? ETL(Extract, Transform, Load)应用程序是一种用于数据处理和迁移的工具或程序,它主要负责从多个数据源提取数据,对数据进行转换和清洗,然后将处理后的数据…...
kotlin知识体系(三) : Android Kotlin 中的函数式编程实践指南
前言 Kotlin以函数式编程革新了Android开发,通过高阶函数、扩展函数等特性,帮助开发者构建高可维护性代码。接下来我们来看一下Kotlin 中的函数式编程的各个特性。 1. 高阶函数与 Lambda 表达式:函数作为参数或返回值 在 Kotlin 中&#x…...
SpringBoot3+Vue3实战(Vue3快速开发登录注册页面并对接后端接口、表单项自定义校验规则、Hutool工具类)(4)
目录 一、SpringBoot3Vue3实现基本增删改查。前后端通信交互、配置后端跨域请求。数据批量删除。(博客链接) 二、SpringBoot3Vue3快速开发登录、注册页面并实现对接。 (1)操作数据表employee(员工信息表)。 <1>修改employee表的字段组成。 <2&g…...
OpenCV图像拼接项目指南
引言 图像拼接是计算机视觉领域中的一个重要应用,它可以将多张有重叠区域的图像拼接成一张全景图。这项技术广泛应用于虚拟现实、医学影像、卫星图像处理等领域。OpenCV作为一个强大的开源计算机视觉库,提供了丰富的工具和函数来实现图像拼接。本文将详…...
机器学习--DBSCAN聚类算法详解
目录 引言 1. 什么是DBSCAN聚类? 2. DBSCAN聚类算法的原理 3. DBSCAN算法的核心概念 3.1 邻域(Neighborhood) 3.2 核心点(Core Point) 3.3 直接密度可达(Directly Density-Reachable) 3…...
使用 Docker 构建 LangChain 开发环镜及 ChatOllama 示例
文章目录 Github官网简介Dockerfilerequirements.txt构建 LangChain 镜像ChatOllama 示例Ollama 示例模拟 tools Github https://github.com/langchain-ai/langchain 官网 https://python.langchain.com/docs/introduction/ 简介 LangChain 是一个用于构建 LLM 驱动的应用…...
持续集成与持续交付:这里有从开发到部署的全流程优化
阅读原文 在上一篇中,我们深入探讨了安全测试的核心内容,强调了它在发现安全漏洞和提升系统安全性中的重要作用。接下来,我们将聚焦于持续集成(CI)与持续交付(CD),这是现代软件开发…...
CH32V208蓝牙内部带运放32位RISC-V工业级微控制器CH32V208CBU6、CH32V208GBU6开发板原理图和PCB
开发板 CH32V208CBU6立创格式的开发板上述链接可下载,官方文件进行了转换,使用前请仔细核对。 CH32V208CBU6原理图,上述图片为芯片部分。已进行DRC。 CH32V208CBU6 PCB三维图,上述图片为芯片部分。已进行DRC。 CH32V208GBU6开发…...
机器臂运动控制算法工程师面试
大厂的经验总结: 一、基础概念理解 请解释机器臂运动学正解和逆解的概念,并分别说明其用途。 正解:已知机器臂各关节的角度(或位移),通过运动学模型计算出机器臂末端执行器在笛卡尔空间中的位置和姿态。用途在于可以根据给定的关节驱动值,预测末端的实际位置,用于运动…...
【一起来学kubernetes】21、Secret使用详解
Secret 的详细介绍 Secret 是 Kubernetes 中用于存储和管理敏感信息(如密码、令牌、密钥等)的资源对象。Secret的设计目的是为了安全地存储和传输敏感信息,如密码、API密钥、证书等。这些信息通常不应该直接硬编码在配置文件或镜像中&#x…...
Java架构师成长之路
概述 本教程主要从6个方面,全面讲解Java技术栈的知识。 1.性能调优 深入理解MySQL底层原理、索引逻辑,数据结构与算法。使用Explain进行优化分析MVCC原理剖析日志机制解析 2.框架源码 掌握Spring底层原理带你手写一个Spring解析IOC、AOP源码、以及事…...
Cyberchef实用功能之-json line格式文件美化和查询
本文将介绍一下如何使用cyberchef对json line格式数据进行美化方便阅读,以及json line格式数据的批量查询操作。 之前的文章介绍了json格式数据的美化和查询,即Cyberchef实用功能之-json解析美化和转换,Cyberchef实用功能之-批量提取json数据…...
span与span之间的空白如何解决?
<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>标题</title> <style>div{background: yellow;}span:first-of-type{background: red;}span:last-of-type{background: blue;}</styl…...
2024年MathorCup数学建模B题甲骨文智能识别中原始拓片单字自动分割与识别研究解题全过程文档加程序
2024年第十四届MathorCup高校数学建模挑战赛 B题 甲骨文智能识别中原始拓片单字自动分割与识别研究 原题再现: 甲骨文是我国目前已知的最早成熟的文字系统,它是一种刻在龟甲或兽骨上的古老文字。甲骨文具有极其重要的研究价值,不仅对中国文…...
3.23学习总结
字符串 String java.lang,String 类代表字符串,Java程序中所有的字符串文字都为此类的对象 字符串的内容是不会发生改变的,它的对象在创建之后不能呗更改 字符串的内存模型 当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。 …...
RT-Thread CI编译产物artifacts自动上传功能介绍
近期在RT-Thread开源项目中,我们引入了一项实用的功能改进——将每次CI(持续集成)编译生成的产物(artifacts)自动上传到GitHub,方便开发者和用户能够更便捷地获取和测试最新的编译结果。 参考链接…...
Android adb调试应用程序
启动app 有的时候app不是预先安装的,也不能从界面start一个app,这时需要后台拉起app。 $adb shell am start package.name/Activity.name 例如,android原生camera app, 包名为com.android.camera2, mainActivity名为…...
仅靠prompt,Agent难以自救
Alexander的观点很明确:未来 AI 智能体的发展方向还得是模型本身,而不是工作流(Work Flow)。还拿目前很火的 Manus 作为案例:他认为像 Manus 这样基于「预先编排好的提示词与工具路径」构成的工作流智能体,…...
【嵌入式学习2】函数
目录 ## 函数 ## 函数分类 ## 函数定义 1、无参数无返回值 2、有参数无返回值 3、有参数有返回值 ## 函数声明 ## 局部变量和全局变量 ## 多文件编程 如何避免把同一个头文件 include 多次,或者头文件嵌套包含? 命令行编译文件 头文件包含的…...
平芯微PW5012应用电路
PW5012应用电路板介绍: 1.1 单节和两节锂电池升压 12V 或 9V, 1A 至 3A 电路板, 1.2 应用: 升压电压转换板 1.3 VIN 输入电压: 3V-9V 1.4 VOUT 输出电压: 9V 2A(VIN3.7V) ࿰…...
Langchain4J框架相关面试题
以下是关于Langchain4J框架的面试题目及答案 ### Langchain4J基础概念类 1. **Langchain4J框架是什么?它的核心功能有哪些?** Langchain4J是一个用于构建语言模型应用的Java框架,它为开发者提供了一套简洁高效的API,使得在Jav…...
【MySQL】用户管理
目录 一、用户1.1 用户信息1.2 创建用户1.3 删除用户1.4 修改用户密码1.4.1 用户修改自己密码1.4.2 root用户修改指定用户的密码 二、数据库的权限2.1 给用户授权2.2 回收用户权限 结尾 一、用户 1.1 用户信息 MySQL中的用户,都存储在系统数据库mysql的user表中。…...
5.高频加热的原理与常用集成电路介绍
一、高频加热的类型 利用高频电源加热通常由两种方法:电介质加热(被加热物体绝缘)与感应加热(被加热物体导电),详细解释如下: 电介质加热(利用高频电压的高频电场导致物体自身分子摩…...
Elasticsearch:可配置的推理 API 端点分块设置
作者:来自 Elastic Daniel Rubinstein Elasticsearch 开放推理 API 现已支持可配置的分块,以便在文档摄取时处理语义文本字段。 Elasticsearch 推理 API 允许用户利用各种提供商的机器学习模型执行推理操作。其中一个常见用例是在索引中支持用于语义搜索…...
从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.1.2多头注意力扩展与掩码机制(因果掩码与填充掩码)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.1.2 多头注意力扩展与掩码机制(`因果掩码与填充掩码`)1. 多头注意力机制:分治策略的数学实现1.1 多头注意力核心公式2. 逐行代码实现2.1 多头拆分与合并3. 掩码机制:注意力控制的核心技术3.1 因果…...
Scikit-learn模型评估全流程解析:从数据划分到交叉验证优化
模型评估的步骤、scikit-learn函数及实例说明 1. 数据划分(Train-Test Split) 函数:train_test_split使用场景:将数据分为训练集和测试集,避免模型过拟合。作用:确保模型在未见过的数据上验证性能。示例&…...
大模型量化框架GPTQModel的基本使用方法
接上一篇博客:AutoGPTQ报torch._C._LinAlgError: linalg.cholesky: The factorization could not be completed的解决办法-CSDN博客 如果Llama factory量化一直报错,可以改用其他的量化框架,例如GPTQ:https://github.com/ModelCl…...
HTTP长连接与短连接的前世今生
HTTP长连接与短连接的前世今生 大家好!作为一名在互联网摸爬滚打多年的开发者,今天想跟大家聊聊HTTP中的长连接和短连接这个话题。 记得我刚入行时,对这些概念一头雾水,希望这篇文章能帮助新入行的朋友少走些弯路。 什么是HTTP…...
线程控制学习
1、线程创建: int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine)(void*), void *arg); 参数 thread:返回线程ID;attr:设置线程的属性,attr为nullptr表示使用默认属性(一般…...
使用 Node.js 从零搭建 Kafka 生产消费系统
目录 一、Kafka 核心概念速览 二、环境准备 三、生产者实现:发送消息 四、消费者实现:处理消息 五、高级配置与最佳实践 六、常见问题解决 七、应用场景示例 总结 Apache Kafka 作为高吞吐、分布式的消息队列系统,在实时数据流处理中…...
【Linux系统】Linux权限讲解!!!超详细!!!
目录 Linux文件类型 区分方法 文件类型 Linux用户 用户创建与删除 用户之间的转换 su指令 普通用户->超级用户(root) 超级用户(root) ->普通用户 普通账户->普通账户 普通用户的权限提高 sudo指令 注: Linux权限 定义 权限操作 1、修改文…...
Ubuntu安装TensorFlow 2.13-GPU版全流程指南(anaconda)
目录 一、安装前准备1.版本选择依据2.创建独立环境 二、详细安装步骤1.通过conda自动安装依赖2.手动验证依赖版本 三、补充说明1.组件依赖关系表2.常见问题解决方案3.性能验证脚本 一、安装前准备 1.版本选择依据 当前最新稳定版:TensorFlow 2.13&a…...
Spring事务管理
介绍了事务的概念,事务的特性,JDBC 事务管理的步骤和操作过程,以及Spring事务管理的两种实现方式:编程式事务管理和声明式事务管理。 1.事务的概念 事务(Transaction)就是将一系列的数据库操作作为一个整体…...
避雷 :C语言中 scanf() 函数的错误❌使用!!!
1. 返回值说明 scanf函数会返回成功匹配并赋值的输入项个数,而不是返回输入的数据。 可以通过检查返回值数量来确认输入是否成功。若返回值与预期不符,就表明输入存在问题。 #include <stdio.h>int main() {int num;if (scanf("%d", …...
判断一个操作是不是允许
一、目的 简单探索一个URL请求是不是允许的。 二、具体过程 (一)系统的初始化 系统数据库有账户"admin",密码是"123"。 账号"admin"的角色是管理员"manager"。 假设管理员身份设定的权限是: 1、对于/user/开头的…...
【FPGA开发】Cordic原理推导、Xilinx PG105手册解读
目录 Cordic原理推导PG105手册解读IP核总览核心计算功能总览基本握手信号非阻塞模式 NonBlocking Mode阻塞模式 Block Mode 数据格式数据映射 本文针对Cordic算法本身,以及Xilinx官方CORDIC IP做学习记录,如有纰漏,欢迎指正! Cord…...
数据结构与算法:宽度优先遍历
前言 进入图论部分难度明显提升了一大截,思路想不到一点…… 一、宽度优先遍历 1.内容 宽度优先遍历主要用于在图上求最短路。 (1)特点 宽度优先遍历的特点就是逐层扩展,最短路即层数 (2)使用条件 …...
PyTorch 面试题及参考答案(精选100道)
目录 PyTorch 的动态计算图与 TensorFlow 的静态计算图有何区别?动态图的优势是什么? 解释张量(Tensor)与 NumPy 数组的异同,为何 PyTorch 选择张量作为核心数据结构? 什么是 torch.autograd 模块?它在反向传播中的作用是什么? 如何理解 PyTorch 中的 nn.Module 类?…...
【数理基础】【概率论与数理统计】概率论与数理统计本科课程总结、资料汇总、个人理解
1 前言 概率论与数理统计是数学系核心的基础专业课,我本科的时候,是拆开上的,对应工科专业的高数中的概率论与数理统计,在量子力学,机器学习,计算机领域深度学习,大模型,机器人控制…...
美制 / 英制单位换算/公制/帝国制 单位转换速查表
文章目录 💡Introduction📏 英制(美制)单位与公制换算速查表🧱 一、长度(Length)🧴 二、体积(Volume / Liquid Measure)⚖️ 三、质量 / 重量(Wei…...
ENSP学习day9
ACL访问控制列表实验 ACL(Access Control List,访问控制列表)是一种用于控制用户或系统对资源(如文件、文件夹、网络等)访问权限的机制。通过ACL,系统管理员可以定义哪些用户或系统可以访问特定资源&#x…...
我爱学算法之——滑动窗口攻克子数组和子串难题(中)
学习算法,继续加油!!! 一、将 x 减到 0 的最小操作数 题目解析 来看这一道题,题目给定一个数组nums和一个整数x;我们可以在数组nums的左边或者右边进行操作(x减去该位置的值)&#…...