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

10 JVM内置锁

我们先想明白一个问题,什么是锁?
我们去给自己家锁门的时候,只有对应的一把钥匙能开锁。当用钥匙去开锁的时候,锁孔的内置型号会验证钥匙能不能对的上。能对上就能把锁打开,然后进到家里使用家里的资源。否则就在外面等着。

说到这里我们聊个题外话然后再转入正题

在中国传统的观念中,男性是外出做事业的,女性是守家的,这样男女组成一个家庭,并且女性也掌握着家里的资源。那么女人就是一把锁,锁能被别人开了,在外面打拼的男人肯定就要换了这把锁。那么把男人比喻成一把钥匙,钥匙能开别人的锁,其实只是心理上不适应,并没有经济上的损失。

所以很多人不明白为什么女性出轨基本上就是离,男性出轨离婚的概率小很多,就是这个原因。

而且易经上讲的乾卦和坤卦,对应的就是主从的关系。乾卦讲责任和担当,坤卦讲忠贞和顺从。领导和下属也是乾卦和坤卦的关系。君臣、父子都是乾坤卦的对应关系。

我们现在来看为什么我们这个年代的人离婚率这么高?一个是女性的开放,坤卦对应的忠贞和顺从位已经不复存在了。第二国内的教育教的是知识,并不教人思考问题的能力,很多男性意识不到自己的责任和担当位。那么我们乾卦的责任和担当位,坤卦的忠贞和顺从位不复存在,当然婚姻就会出很多的问题。总结就是乾坤位的错位,稳定的关系变的不稳定,然后离婚率就高了。

闲话少叙,我们切入正题。

在我们计算机里面,锁其实也是一样的。
现在的CPU一般都是多核的CPU,为了解决多核CPU并发的问题,一种常用的解决方案是在CPU内部添加一个控锁单元,该单元负责控制对共享资源的访问。
在实现基于总线的锁机制时,锁控制单元可以由一个锁定信号线和一个锁定控制器组成
当一个CPU需要访问共享资源时,它会向总线发送一个请求信号,并在锁定信号线上发送一个锁定请求
锁定控制器会检查其他CPU是否已经获得了锁,并阻止其他CPU访问共享资源直到当前CPU释放锁定
在实现基于缓存的锁机制时,锁控制单元通常由一个缓存控制器和一个锁定状态字组成
当一个CPU需要访问共享资源时,它会向缓存发送一个请求,并在锁定状态字上设置锁定标志
缓存控制器会检查其他CPU是否已经获得了锁,并阻止其他CPU访问共享资源直到当前CPU释放锁定

那么java的synchronized属于对象锁。
当synchronized基于java对象模型的monitor(监视器)。在java创建一个对象时同时生成一个monoitor用于锁的控制。当synchronized修饰静态方法时,monitor在方法区的class对象中,当修饰代码块时候,我们需要指定锁对象。

我们再聊一聊redis实现的分布式锁,我们在redis中添加一个key,往key里面放置一个uuid,当给给分布式锁加上一个锁时,一个线程会生成一个uuid放入该key中,其他线程想进入的时候需要对比该uuid是否和线程持有的uuid一致,不一致则不能进行共享资源的访问,如果想释放锁只能持有该uuid才能释放锁,让其他线程共享该资源。

我们通过以上的说明,可以知道锁的一个共同特点,有一个唯一的元素放着锁的锁孔,等待钥匙插入的比对,多个占用共享资源的钥匙去竞争打开锁孔,要进行钥匙型号和锁孔的比对。

我们重点讲下java的锁,其他的先一笔带过

Java内置锁是一个互斥锁,这就意味着最多只有一个线程能够获得该锁,当线程B尝试去获得线程A持有的内置锁时,线程B必须等待或者阻塞,直到线程A释放这个锁,如果线程A不释放这个锁,那么线程B将永远等待下去。

Java中每个对象都可以用作锁,这些锁称为内置锁。线程进入同步代码块或方法时会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁保护的同步代码块或方法。

线程安全问题

当多个线程并发访问某个Java对象(Object)时,无论系统如何调度这些线程,也无论这些线程将如何交替操作,这个对象都能表现出一致的、正确的行为,那么对这个对象的操作是线程安全的。如果这个对象表现出不一致的、错误的行为,那么对这个对象的操作不是线程安全的,发生了线程的安全问题。

如下边的代码:

import java.util.concurrent.CountDownLatch;
/**
* 用10个线程自增,最后结果汇总
*/
public class SelfPlusTest {private static final int THREAD_SIZE = 10;private static final int ADD_TIMES = 1000;public static void main(String[] args) throws InterruptedException {SelfPlus selfPlus = new SelfPlus();//用于让线程全部跑完(countDownLatch归0),才获取计算结果CountDownLatch countDownLatch = new CountDownLatch(THREAD_SIZE);for (int i = 0; i < THREAD_SIZE; i++) {new Thread(() -> {for (int j = 0; j < ADD_TIMES; j++) {selfPlus.selfAdd();}countDownLatch.countDown();}).start();}//等待所有线程跑完countDownLatch.await();long amount = selfPlus.getAmount();System.out.println("预期计算结果:" + THREAD_SIZE * ADD_TIMES);System.out.println("实际计算结果:" + amount);}
}
SelfPlus类package test.juc.safe;
public class SelfPlus {private Integer amount = 0;public void selfAdd() {amount++;}public Integer getAmount() {return amount;}
}

我们看下执行结果
在这里插入图片描述

我们在selfAdd方法前加synchronized关键字,再次执行结果就是我们预期的结果。

java对象结构的内置锁,如下图:

在这里插入图片描述

对象头:

对象头包括三个字段,第一个字段叫作Mark Word(标记字),用于存储自身运行时的数据,例如GC标志位、哈希码、锁状态等信息。
第二个字段叫作Class Pointer(类对象指针),用于存放方法区Class对象的地址,虚拟机通过这个指针来确定这个对象是哪个类的实例。
第三个字段叫作Array Length(数组长度)。如果对象是一个Java数组,那么此字段必须有,用于记录数组长度的数据;如果对象不是一个Java数组,那么此字段不存在,所以这是一个可选字段。

对象体:

对象体包含对象的实例变量(成员变量),用于成员属性值,包括父类的成员属性值。这部分内存按4字节对齐。

对齐字节:

对齐字节也叫作填充对齐,其作用是用来保证Java对象所占内存字节数为8的倍数HotSpot VM的内存管理要求对象起始地址必须是8字节的整数倍。对象头本身是8的倍数,当对象的实例变量数据不是8的倍数时,便需要填充数据来保证8字节的对齐。

当synchronized修饰普通方法时锁资源是放置对象头信息中,当修饰static方法时,锁信息放置方法区的类信息中。
同理我们的lock锁的锁信息也是放在同样的位置。我们把锁的基本原理讲清楚再去理解锁的时候就很好理解了。

我们接着讲讲java的其他锁,其实原理都一样。

我个人并不喜欢记这些概念性的东西,其实意义不大,我们知道原理,知道一些常用场景就可以了,而且我在面试的时候也很少问下面的18点,有些面试官喜欢装的会问。下面是从网上找的概念性的东西,大家简单了解下就可以了。主要能想明白他们的实现方式。不喜欢看的 直接跳过下面的18个概念,直接看后面的内容。

1.乐观锁

乐观锁是一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低,读数据时认为别的线程不会正在进行修改(所以没有上锁)。写数据时,判断当前 与期望值是否相同,如果相同则进行更新(更新期间加锁,保证是原子性的)。

Java中的乐观锁: CAS,比较并替换,比较当前值(主内存中的值),与预期值(当前线程中的值,主内存中值的一份拷贝)是否一样,一样则更新,否则继续进行CAS操作。

2.悲观锁

悲观锁是一种悲观思想,即认为写多读少,遇到并发写的可能性高,每次去拿数据的时候都认为其他线程会修改,所以每次读写数据都会认为其他线程会修改,所以每次读写数据时都会上锁。其他线程想要读写这个数据时,会被这个线程block,直到这个线程释放锁然后其他线程获取到锁。
Java中的悲观锁: synchronized修饰的方法和方法块、ReentrantLock。
如图所示,只能有一个线程进行读操作或者写操作,其他线程的读写操作均不能进行。

我们常用的redis的分布式锁就属于一种悲观锁,不管是悲观锁还是乐观锁,原理都一样。我们有个原子性的元素放置和钥匙配对的锁孔,能不能打开就看持有的钥匙的情况。然后我们实现策略不一样就有了不同概念的锁。

3.自旋锁

自旋锁是一种 为了让线程等待,我们只须让线程执行一个忙循环(自旋)。
现在绝大多数的个人电脑和服务器都是多路(核)处理器系统,如果物理机器有一个以上的处理器或者处理器核心,能让两个或以上的线程同时并行执行,就可以让后面请求锁的那个线程“稍等一会”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。
自旋锁的优点: 避免了线程切换的开销。挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给Java虚拟机的并发性能带来了很大的压力。
自旋锁的缺点: 占用处理器的时间,如果占用的时间很长,会白白消耗处理器资源,而不会做任何有价值的工作,带来性能的浪费。因此自旋等待的时间必须有一定的限度,如果自旋超过了限定的次数仍然没有成功获得锁,就应当使用传统的方式去挂起线程。
自旋次数默认值:10次,可以使用参数-XX:PreBlockSpin来自行更改。
自适应自旋: 自适应意味着自旋的时间不再是固定的,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定的。有了自适应自旋,随着程序运行时间的增长及性能监控信息的不断完善,虚拟机对程序锁的状态预测就会越来越精准。
Java中的自旋锁: CAS操作中的比较操作失败后的自旋等待。

4.可重入锁

任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞。
可重入锁的原理: 通过组合自定义同步器来实现锁的获取与释放。
再次获取锁:识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取。获取锁后,进行计数自增,
释放锁:释放锁时,进行计数自减。
Java中的可重入锁: ReentrantLock、synchronized修饰的方法或代码段。
可重入锁的作用: 避免死锁。

5.读写锁

通过ReentrantReadWriteLock类来实现。为了提高性能, Java 提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,如果没有写锁的情况下,读是无阻塞的,在一定程度上提高了程序的执行效率。读写锁分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由 jvm 自己控制的。

读锁: 允许多个线程获取读锁,同时访问同一个资源。 写锁: 只允许一个线程获取写锁,不允许同时访问同一个资源。

6.公平锁

多个线程按照申请锁的顺序来获取锁。在并发环境中,每个线程会先查看此锁维护的等待队列,如果当前等待队列为空,则占有锁,如果等待队列不为空,则加入到等待队列的末尾,按照FIFO的原则从队列中拿到线程,然后占有锁。

7.非公平锁

多个线程获取锁的顺序,不是按照先到先得的顺序,有可能后申请锁的线程比先申请的线程优先获取锁。

优点: 非公平锁的性能高于公平锁
缺点: 有可能造成线程饥饿(某个线程很长一段时间获取不到锁)
**Java中的非公平锁:**synchronized是非公平锁,ReentrantLock通过构造函数指定该锁是公平的还是非公平的,默认是非公平的。

8.共享锁

可以有多个线程获取读锁,以共享的方式持有锁。和乐观锁、读写锁同义。
Java中用到的共享锁: ReentrantReadWriteLock

9.独占锁

只能有一个线程获取锁,以独占的方式持有锁。和悲观锁、互斥锁同义
Java中用到的独占锁: synchronized,ReentrantLock

10.重量级锁

synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本身依赖底层的操作系统的 Mutex Lock来实现。操作系统实现线程的切换需要从用户态切换到核心态,成本非常高。这种依赖于操作系统 Mutex Lock来实现的锁称为重量级锁。为了优化synchonized,引入了轻量级锁,偏向锁
Java中的重量级锁: synchronized

11.轻量级锁

轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量。轻量级是相对于使用操作系统互斥量来实现的重量级锁而言的。轻量级锁在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。如果出现两条以上的线程争用同一个锁的情况,那轻量级锁将不会有效,必须膨胀为重量级锁

优点: 如果没有竞争,通过CAS操作成功避免了使用互斥量的开销
缺点: 如果存在竞争,除了互斥量本身的开销外,还额外产生了CAS操作的开销,因此在有竞争的情况下,轻量级锁比传统的重量级锁更慢。

12.偏向锁

在无竞争的情况下把整个同步都消除掉,连CAS操作都不去做了。偏是指偏心,它的意思是这个锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁一直没有被其他的线程获取,则持有偏向锁的线程将永远不需要再进行同步。持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再进行任何同步操作(例如加锁、解锁及对Mark Word的更新操作等)

优点: 把整个同步都消除掉,连CAS操作都不去做了,优于轻量级锁
缺点: 如果程序中大多数的锁都总是被多个不同的线程访问,那偏向锁就是多余的

13.分段锁

最好的例子来说明分段锁是ConcurrentHashMap。**ConcurrentHashMap原理:**它内部细分了若干个小的 HashMap,称之为段(Segment)。默认情况下一个 ConcurrentHashMap 被进一步细分为 16 个段,既就是锁的并发度。如果需要在 ConcurrentHashMap 添加一项key-value,并不是将整个 HashMap 加锁,而是首先根据 hashcode 得到该key-value应该存放在哪个段中,然后对该段加锁,并完成 put 操作。在多线程环境中,如果多个线程同时进行put操作,只要被加入的key-value不存放在同一个段中,则线程间可以做到真正的并行

**线程安全:**ConcurrentHashMap 是一个 Segment 数组, Segment 通过继承ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全

14.互斥锁

互斥锁与悲观锁、独占锁同义,表示某个资源只能被一个线程访问,其他线程不能访问
读-读互斥
读-写互斥
写-读互斥
写-写互斥
Java中的同步锁: synchronized

15.同步锁

同步锁与互斥锁同义

16.死锁

如线程A持有资源x,线程B持有资源y,线程A等待线程B释放资源y,线程B等待线程A释放资源x,两个线程都不释放自己持有的资源,则两个线程都获取不到对方的资源,就会造成死锁。
Java中的死锁不能自行打破,所以线程死锁后,线程不能进行响应。所以一定要注意程序的并发场景,避免造成死锁

17.锁粗化

如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作都是出现在循环体体之中,就算真的没有线程竞争,频繁地进行互斥同步操作将会导致不必要的性能损耗,所以就采取了一种方案:把加锁的范围扩展(粗化)到整个操作序列的外部,这样加锁解锁的频率就会大大降低,从而减少了性能损耗。

18.锁消除

锁消除
锁消除是一种优化技术: 就是把锁干掉。当Java虚拟机运行时发现有些共享数据不会被线程竞争时就可以进行锁消除。
那如何判断共享数据不会被线程竞争?
利用逃逸分析技术:分析对象的作用域,如果对象在A方法中定义后,被作为参数传递到B方法中,则称为方法逃逸;如果被其他线程访问,则称为线程逃逸。
在堆上的某个数据不会逃逸出去被其他线程访问到,就可以把它当作栈上数据对待,认为它是线程私有的,同步加锁就不需要了

synchronized和lock锁的区别

我们前面说过,这两个加锁的锁对象都是一样的,只是一个JVM帮我们实现好了,一个需要我们手动去控制。至于上面说的那些概念,很多我们可以通过lock锁自己去实现。
就想汽车的自动挡和手动挡的区别

相关文章:

10 JVM内置锁

我们先想明白一个问题&#xff0c;什么是锁&#xff1f; 我们去给自己家锁门的时候&#xff0c;只有对应的一把钥匙能开锁。当用钥匙去开锁的时候&#xff0c;锁孔的内置型号会验证钥匙能不能对的上。能对上就能把锁打开&#xff0c;然后进到家里使用家里的资源。否则就在外面等…...

前端项目部署方法

ngnix服务器部署 下载nignx&#xff0c;我下的是windows版本的 下载链接&#xff1a;[https://nginx.org/en/download.html](https://nginx.org/en/download.html) 解压文件 如果原本的80端口号被占用了&#xff0c;可以改为其他的端口号 可以点击nginx.exe文件启动nginx,它可能…...

【1.排序】

排序 笔记记录 1.排序的基本概念1.1 排序的定义 2. 插入排序2.1 直接插入排序2.2 折半插入排序2.3 希尔排序 3. 交换排序3.1 冒泡排序3.2 快速排序 4. 选择排序4.1 简单选择排序4.2 堆排序 5. 归并排序、基数排序和计数排序5.1 归并排序4.2 基数排序4.3 计数排序 6. 各种内部排…...

visual studio添加滚动条预览

如何在vs中添加如图的滚动条呢&#xff1f; 打开VS 工具栏 选项 - 文本编辑器 - C/C - 滚动条 行为-使用缩略图 -- 确定...

[SAP ABAP] ALV状态栏GUI STATUS的快速创建

使用事务码SE38进入到指定程序&#xff0c;点击"显示对象列表"按钮 鼠标右键&#xff0c;选择"GUI状态" 弹出【创建状态】窗口&#xff0c;填写状态以及短文本描述以后&#xff0c;点击按钮 点击"调整模板"&#xff0c;复制已有程序的状态栏 填…...

鸿蒙元服务项目实战:备忘录UI页面开发

前言 之前写过一篇关于元服务项目的上架流程&#xff0c;为了更好的了解及开发元服务&#xff0c;准备从0到1简单开发一个小项目&#xff0c;也希望能够帮助到刚刚介入到鸿蒙开发的同学&#xff0c;具体项目呢&#xff0c;也是十分的简单&#xff0c;就是一个小巧的备忘录项目&…...

【Java基础面试题022】什么是Java内部类?有什么作用?

回答重点 Java内部类是指&#xff1a;在一个类的内部定义的类&#xff0c;Java支持多种类型的内部类&#xff0c;包括成员内部类、局部内部类、匿名内部类和静态内部类。实际上内部类是一个编译层面的概念&#xff0c;像一个语法糖一样&#xff0c;经过编译器之后其实内部类会…...

量子芯片在新医疗领域的应用研究展望

一、引言 &#xff08;一&#xff09;研究背景 随着科技的不断发展&#xff0c;量子芯片在新医疗领域有望在多个技术方面实现创新突破&#xff0c;进而持续拓展其应用范围与深度。 在提高纠错能力方面&#xff0c;当前量子比特的易错性是制约量子芯片广泛应用的关键因素之一…...

不可重入锁与死锁

不可重入锁确实可能导致死锁&#xff0c;特别是在同一线程尝试多次获取同一把锁时。如果锁是不可重入的&#xff0c;那么线程在第二次尝试获取锁时会永远阻塞&#xff0c;从而导致死锁。 不可重入锁与死锁的关系 不可重入锁不允许同一个线程多次获取同一把锁。在以下情况下&am…...

Linux(Ubuntu)命令大全——已分类整理,学习、查看更加方便直观!(2024年最新编制)

Hello! 认真好学的小伙伴们&#xff0c;大家好呀&#xff08;Respect~&#xff09;&#xff01;我是 H u a z z i Huazzi Huazzi&#xff0c;欢迎观看本篇博客&#xff0c;接下来让我们一起来学习 Ubuntu命令大全 吧&#xff01;祝你有所收获&#xff01; 文章目录 前言&#x…...

画一颗随机数

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>codePen - Random Tree</title> </head> <body><canvas></canvas><script>const canvas doc…...

机器人变换关系

rigid 刚性变换&#xff08;平移、旋转&#xff09;&#xff1a; 只改变位置和方向&#xff0c;拥有6个自由度&#xff0c;保持变换物体的形状。 affine 仿射变换&#xff08;平移、旋转、缩放、倾斜等&#xff09;&#xff1a; 改变物体形状、位置、方向&#xff0c;拥有12…...

2024年企业中生成式 AI 的现状报告

从试点到生产&#xff0c;企业 AI 格局正在被实时改写。我们对 600 名美国企业 IT 决策者进行了调查&#xff0c;以揭示新兴的赢家和输家。 从试点到生产 2024 年标志着生成性人工智能成为企业关键任务的一年。这些数字讲述了一个戏剧性的故事&#xff1a;今年人工智能支出飙升…...

共创共建!葡萄城 SpreadJS 完成 HarmonyOS NEXT 操作系统兼容认证

最新技术资源&#xff08;建议收藏&#xff09; https://www.grapecity.com.cn/resources/ 近日&#xff0c;华为“企业工作必备应用鸿蒙化论坛”在北京圆满落幕&#xff0c;论坛汇聚了众多行业精英和合作伙伴&#xff0c;聚焦讨论企业数字化转型与原生鸿蒙生态融合等话题。葡萄…...

webAPI clean architecture

文章目录 项目地址一、Restaurants.Domain 核心业务层1.1 Entities实体层1.2 Repositories 数据操作EF的接口二、Restaurants.Infrastructure 基础设施层2.1 Persistence 数据EF CORE配置2.2 Repositories 数据查询实现2.3 Extensions 服务注册三、Restaurants.Application用例…...

JS使用random随机数实现简单的四则算数验证

1.效果图 2.代码实现 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</ti…...

在Linux中使用`scp`进行远程目录文件复制

在Linux系统中&#xff0c;scp&#xff08;安全复制协议&#xff09;是一个使用SSH&#xff08;安全外壳协议&#xff09;进行文件和目录安全传输的命令。它允许在远程主机之间复制文件和目录&#xff0c;具有很强的安全性&#xff0c;是一种常用的文件传输工具。以下是如何使用…...

【C++游记】string的使用和模拟实现

枫の个人主页 你不能改变过去&#xff0c;但你可以改变未来 算法/C/数据结构/C Hello&#xff0c;这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕&#xff0c;我们继续来学习C的内容呀。C是接近底层有比较经典的语言&#xff0c;因此学习起来注定枯燥无味&#xf…...

解决Linux访问HuggingFace的问题(操作记录)

目录 一、软件下载 二、软件使用 1、启动软件 2、设置网络 3、注意事项 三、linux命令行访问 1、问题分析 2、设置命令行代理 一、软件下载 MrQiguan/cfw-linux 二、软件使用 1、启动软件 ./cfw 注&#xff1a;先选择节点&#xff0c;再开启Start with Linux&#…...

《向量数据库指南》——Milvus Cloud 2.5:Sparse-BM25引领全文检索新时代

Milvus Cloud BM25:重塑全文检索的未来 在最新的Milvus Cloud 2.5版本中,我们自豪地引入了“全新”的全文检索能力,这一创新不仅巩固了Milvus Cloud在向量数据库领域的领先地位,更为用户提供了前所未有的灵活性和效率。作为大禹智库的向量数据库高级研究员,以及《向量数据…...

verilog+systemVerilog写代码bug总结

前言 此文用来记录我在写verilog项目时遇到的bug,方便回顾&#xff0c;也供大家参考。 语言&#xff1a;verilog、systemverilog 平台&#xff1a;vivado 2021.01 bug记录和解决 如何让计数从0开始&#xff0c;而不是从1开始&#xff1f; 情景描述&#xff1a;我现在要实现…...

【Java基础面试题014】for循环与增强for的区别是什么?

回答重点 for for是一种传统的循环结构&#xff0c;允许开发者控制循环的初始值&#xff0c;终止条件和步进方式 主要特点&#xff1a; 灵活性&#xff1a;可以控制循环的初始值、终止条件和步进方式使用于数组&#xff1a;可以通过索引访问&#xff0c;使用索引进行反向遍…...

2412d,d的8月会议

原文 总结 替换D的逃逸分析 Rikki说,他一个月前曾与Dennis讨论过简化D的逃逸分析,但没有结果.在BeerConf上,他再次提起了它,Dennis说他一直在考虑它. Rikki也与Walter谈过这件事,Walter曾说过DIP1000并没有完全如期工作,且有点太复杂了. 因此,Rikki想讨论按D逃逸分析方法替…...

如何在Qt中应用html美化控件

在Qt中应用HTML美化控件&#xff0c;主要可以通过以下几种方式&#xff1a; 使用QWebEngineView&#xff1a;QWebEngineView是基于Chromium引擎的控件&#xff0c;用于显示和交互HTML内容。它支持现代Web标准和技术&#xff0c;如HTML5、CSS3和JavaScript。你可以通过以下步骤…...

vue3实现商城系统详情页(前端实现)

目录 写在前面 预览 实现 图片部分 详情部分 代码 源码地址 总结 写在前面 笔者不是上一个月毕业了么&#xff1f;找工作没找到&#xff0c;准备在家躺平两个月。正好整理一下当时的毕业设计&#xff0c;是一个商城系统。还是写篇文章记录下吧 预览 商品图片切换显示…...

[Pro Git#4] 标签 | 理解 | 创建 | push

目录 一、理解标签 二、创建标签 三、操作标签 一、理解标签 标签定义&#xff1a;在Git中&#xff0c;标签&#xff08;tag&#xff09;是对某次提交&#xff08;commit&#xff09;的一个标识&#xff0c;相当于起了一个别名。应用场景示例&#xff1a; 在项目发布某个版…...

在M系列芯片的Mac上使用Uniapp开发的依赖安装指南

在M系列芯片的Mac上使用Uniapp开发的依赖安装指南 在基于M系列芯片&#xff08;例如M3、M4&#xff09;的Mac上进行Uniapp开发时&#xff0c;使用esbuild和rollup等依赖包时需要注意处理不同架构的支持。具体问题出现在darwin-arm64&#xff08;ARM架构&#xff09;和darwin-x…...

delve调试环境搭建—golang

原文地址&#xff1a;delve调试环境搭建—golang – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 由于平时不用 IDE 开发环境&#xff0c;习惯在 linux终端vim 环境下开发&#xff0c;所以找了golang的调试工具&#xff0c;delve类似gdb的调试界…...

暂停一下,给Next.js项目配置一下ESLint(Next+tailwind项目)

前提 之前开自己的GitHub项目&#xff0c;想着不是团队项目&#xff0c;偷懒没有配置eslint&#xff0c;后面发现还是不行。eslint的存在可以帮助我们规范代码格式&#xff0c;同时 ctrl s保存立即调整代码格式是真的很爽。 除此之外&#xff0c;团队使用eslint也是好处颇多…...

vscode 使用说明

文章目录 1、文档2、技巧显示与搜索宏定义和包含头文件 3、插件4、智能编写5、VSCode 与 C&#xff08;1&#xff09;安装&#xff08;2&#xff09;调试&#xff08;a&#xff09;使用 CMake 进行跨平台编译与调试&#xff08;b&#xff09;launch.json&#xff08;c&#xff…...

单片机:实现蜂鸣器数码管的显示(附带源码)

单片机实现蜂鸣器数码管显示 蜂鸣器和数码管在嵌入式系统中广泛应用。蜂鸣器可以发出声音警告或提示&#xff0c;而数码管则用于显示数字或字母。在本项目中&#xff0c;我们将通过8051单片机实现一个控制蜂鸣器和数码管显示的系统&#xff0c;结合使用蜂鸣器和数码管&#xf…...

Next.js v15-基于NextAuth进行身份验证

NextAuth.js 抽象化了管理会话、登录和注销以及身份验证的其他方面所涉及的大部分复杂性操作。虽然您可以手动实现这些功能&#xff0c;但该过程可能非常耗时且容易出错。NextAuth.js简化了流程&#xff0c;为 Next.js 应用程序中的身份验证提供了统一的解决方案。 步骤 通过…...

解锁Vue组件的奇妙世界

文章目录 一、Vue 组件概述&#xff08;一&#xff09;什么是 Vue 组件&#xff08;二&#xff09;Vue 组件的优点 二、Vue 组件的创建方式&#xff08;一&#xff09;全局注册&#xff08;二&#xff09;局部注册&#xff08;三&#xff09;单文件组件&#xff08;SFC&#xf…...

二分查找【Lecode_HOT100】

文章目录 1.搜索插入位置No.352.搜索二维矩阵No.743.在排序数组中查找元素的第一个和最后一个位置No.344.搜索旋转排序数组No.335.寻找旋转排序数组中的最小值No.153 1.搜索插入位置No.35 class Solution {public int searchInsert(int[] nums, int target) {int l 0;int r n…...

解决git clone时报错“authentication failed for huggingface repository”

问题1&#xff1a; 已经获取了模型的授权&#xff0c;但是git clone时&#xff0c;弹出弹窗 输入huggingface的用户名和密码后&#xff0c;报错如下 解决方式1&#xff1a; 阅读红框标注的说明&#xff0c;“password authentication in git is no longer supported.”&#…...

力扣-图论-16【算法学习day.66】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…...

【异常】GL-SFT1200路由器中继模式,TL-CPE1300D无法搜寻5G网问题分析

【异常】GL-SFT1200路由器中继模式,TL-CPE1300D无法搜寻5G网问题 情况实验结论情况 在用GL-SFT1200路由器切换中继模式时,由于web密码忘却,需要重置,但根据官网使用手册,或者对应的中文版手册,重置失败。通过跟商家联系,进行uboot刷机,提供了指导文档,尝试后刷机成功…...

LeetCode 热题 100_K 个一组翻转链表(31_25_困难_C++)(四指针法)

LeetCode 热题 100_K 个一组翻转链表&#xff08;31_25&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;四指针法&#xff09;&#xff1a; 代码实现代码实现&#xff08;思路一&#xff08;四指针法&#x…...

【LeetCode】35.搜索插入位置

目录 LeetCode35.搜索插入位置题解解题思路code1 暴力解法2 二分查找什么是二分查找&#xff1f;二分查找的原理二分查找图解二分查找的优缺点……更新中 LeetCode35.搜索插入位置题解 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如…...

拿到小米 Offer,却迷茫了。。

大家好&#xff0c;我是程序员鱼皮&#xff0c;12 月了&#xff0c;很多小伙伴也拿到了秋招的 Offer&#xff08;没拿到也不要灰心&#xff09;&#xff0c;但即使拿到 Offer&#xff0c;可能还会有一些其他的顾虑。今天分享我们编程导航一位鱼友的提问&#xff0c;给大家作为学…...

redis集群 服务器更换ip,怎么办,怎么更换redis集群的ip

redis集群 服务器更换ip&#xff0c;怎么办&#xff0c;怎么更换redis集群的ip 1、安装redis三主三从集群2、正常状态的redis集群3、更改redis集群服务器的ip 重启服务器 集群会down4、更改redis集群服务器的ip 重启服务器 集群down的原因5、更改redis集群服务器的ip后&#xf…...

运行 Mongodb Server

如何使用 mongod 命令通过配置文件启动 MongoDB Server 适用于通过 Homebrew 安装的 MongoDB Server 如果您的 MongoDB Server 是通过 Homebrew 安装的&#xff0c;则安装过程中会自动创建必要的文件夹和配置文件&#xff08;如 mongod.conf&#xff09;。您可以直接使用以下…...

“年轻科技旗舰”爱玛A7 Plus正式发布,全国售价4999元

12月18日&#xff0c;备受行业瞩目的“A7上场 一路超神”爱玛旗舰新品发布会在爱玛台州智造工厂盛大举行。 作为年末“压轴产品”的“两轮豪华轿跑”爱玛A7Plus重磅上场&#xff0c;以“快、稳、帅、炫、智、爽”六大超神技惊艳四座&#xff0c;不仅践行了爱玛科技的精品战略&…...

深入探索 C++ 编程技巧:从案例中学习高效实践

深入探索 C 编程技巧&#xff1a;从案例中学习高效实践 C 是一门功能强大且灵活的编程语言&#xff0c;被广泛应用于系统开发、高性能计算、游戏引擎等领域。然而&#xff0c;初学者和有经验的开发者常常会在代码优化、设计模式和语言特性中面临挑战。这篇文章将通过实际案例&…...

鸿蒙操作系统简介

华为鸿蒙系统&#xff08;HUAWEI HarmonyOS&#xff09;&#xff0c;是华为公司于2019年8月9日在东莞举行的华为开发者大会&#xff08;HDC.2019&#xff09;上正式发布的面向全场景的分布式操作系统&#xff0c;可以创造一个超级虚拟终端互联的世界&#xff0c;将人、设备、场…...

LabVIEW起落架震台检测

在现代飞机制造与维护过程中&#xff0c;起落架的性能测试是保障飞机安全的重要环节。通过LabVIEW开发的起落架小落震台检测系统&#xff0c;通过模拟飞机着陆过程&#xff0c;准确捕捉起落架在着陆时承受的各种动力学特性和应力响应&#xff0c;有效提升起落架设计的精度与可靠…...

git remote -v(--verbose)显示你的 Git 仓库配置的远程仓库的详细信息

git remote -v 是一个 Git 命令&#xff0c;用于显示你的 Git 仓库配置的远程仓库的详细信息。 当你执行 git remote -v 命令时&#xff0c;你会看到类似以下的输出&#xff1a; origin https://github.com/your-username/your-repo.git (fetch) origin https://github.com…...

Java基础知识(四) -- 面向对象(中)

1.包 1.3.1 包的作用 &#xff08;1&#xff09;可以避免类重名&#xff1a;有了包之后&#xff0c;类的全名称就变为&#xff1a;包.类名【便于使用】&#xff08;2&#xff09;分类组织管理众多的类【便于管理类】&#xff08;3&#xff09;可以控制某些类型或成员的可见范…...

RAG开发中,如何用Milvus 2.5 BM25算法实现混合搜索

01. 背景 混合搜索(Hybrid Search)作为RAG应用中Retrieve重要的一环&#xff0c;通常指的是将向量搜索与基于关键词的搜索&#xff08;全文检索&#xff09;相结合&#xff0c;并使用RRF算法合并、并重排两种不同检索的结果&#xff0c;最终来提高数据的召回率。全文检索与语义…...

RadiAnt DICOM - 基本主题 :从 PACS 服务器打开研究

正版序列号获取&#xff1a;https://r-g.io/42ZopE RadiAnt DICOM Viewer PACS 客户端功能允许您从 PACS 主机&#xff08;图片存档和通信系统&#xff09;搜索和下载研究。 在开始之前&#xff0c;您需要确保您的 PACS 服务器和 RadiAnt 已正确配置。有关配置说明&#xff0c…...