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

JUC面试(十一)——LockSupport

可重入锁

可重入锁又名递归锁

是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提,锁对象得是同一个对象),不会因为之前已经获取过的锁还没释放而阻塞。

Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁。

自己可以获取自己的内部锁,其实都是同一把锁

隐式锁synchronized验证

同步块:

/*** 可重入锁:可重复可递归调用的锁,在外层使用锁之后,在内层仍然* 可以使用,并且不发生死锁,这样的锁就叫做可重入锁** 在一个Synchronized修饰的方法或代码块的内部* 调用本类的其他Synchronized修饰的方法或代码块时,是永远可以得到锁的*/
public class ReEnterLockDemo {static Object objectLockA = new Object();public static void m1(){new Thread(() -> {synchronized ((objectLockA)){System.out.println(Thread.currentThread().getName() + "\t" + "外层锁");synchronized ((objectLockA)){System.out.println(Thread.currentThread().getName() + "\t" + "中层锁");synchronized ((objectLockA)){System.out.println(Thread.currentThread().getName() + "\t" + "内层锁");}}}}, "thread1").start();}public static void main(String[] args) {m1();}
}
thread1	外层锁
thread1	中层锁
thread1	内层锁

同步方法:

//锁的是类实例//synchronized修饰的方法或者代码块的内部//调用本类的其他synchronized修饰的方法或者代码块时,是可以得到锁的,都是同一把锁public synchronized void method1(){System.out.println(Thread.currentThread().getName() + "\t" + "外层锁");method2();}public synchronized void method2(){System.out.println(Thread.currentThread().getName() + "\t" + "中层锁");method3();}public synchronized void method3(){System.out.println(Thread.currentThread().getName() + "\t" + "内层锁");}
main	外层锁
main	中层锁
main	内层锁

原理:

每个锁对象拥有一个锁计数器和一个指向持有该锁的线程的指针。

当执行monitorenter时,如果目标锁对象的计数器为零,那么说明它没有被其他线程所持有,Java虚拟机会将该锁对象的持有线程设置为当前线程,并且将其计数器加i。

在目标锁对象的计数器不为零的情况下,如果锁对象的持有线程是当前线程,那么Java虚拟机可以将其计数器加1,否则需要等待,直至持有线程释放该锁。

当执行monitorexit时,Java虚拟机则需将锁对象的计数器减1。计数器为零代表锁已被释放。

显示锁ReentrantLock验证

public static void m2(){lock.lock();try {System.out.println(Thread.currentThread().getName() + "\t" + "外层锁");lock.lock();try {System.out.println(Thread.currentThread().getName() + "\t" + "内层锁");}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}
main	外层锁
main	内层锁

加锁和解锁两两配对,解锁多了抛异常,加锁多了出不来。

LockSupport是什么

juc.locks包下

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。

LockSupport中的park()和unpark()的作用分别是阻塞线程和解除阻塞线程。

Object的线程等待唤醒机制(wait/notify)的升级版

在这里插入图片描述

3种让线程等待和唤醒的方法

wait&notify

方式1: 使用Object中的wait()方法让线程等待, 使用Object中的notify()方法唤醒线程

细节:

wait和notify方法必须要在同步块或者方法里面且成对出现使用。

将notify放在wait方法前面,程序无法执行,无法唤醒。

    static Object objectLock = new Object();private static void synchronizedWaitNotify() {new Thread(() -> {synchronized (objectLock){System.out.println(Thread.currentThread().getName()+"\t"+"------come in");try {objectLock.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"\t"+"------被唤醒");}},"A").start();new Thread(() -> {synchronized (objectLock){objectLock.notify();System.out.println(Thread.currentThread().getName()+"\t"+"------通知");}},"B").start();}public static void main(String[] args) {synchronizedWaitNotify();}A	------come in
B	------通知
A	------被唤醒

await&signal

方式2: 使用JUC包中Condition的await()方法让线程等待,使用signal()方法唤醒线程

    static Object objectLock = new Object();static Lock lock = new ReentrantLock();static Condition condition = lock.newCondition();public static void main(String[] args) {new Thread(() -> {lock.lock();try {System.out.println(Thread.currentThread().getName() + "\t" + "------come in");try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "\t" + "------被唤醒");} finally {lock.unlock();}}, "A").start();new Thread(() -> {lock.lock();try {condition.signal();System.out.println(Thread.currentThread().getName() + "\t" + "------通知");} finally {lock.unlock();}}, "B").start();}A	------come in
B	------通知
A	------被唤醒

synchronized和Lock实现等待唤醒通知的约束

  • 线程先要获得并持有锁,必须在锁块(synchronized或lock)中,不然报异常
  • 必须要先等待后唤醒,线程才能够被唤醒(顺序不能颠倒)

LockSupport

方式3: LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程

park等待和unpark唤醒

官网解释:

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。

LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,每个线程都有一个许可(permit)

permit只有两个值1和零,默认是零。

可以把许可看成是一种(0,1)信号量(Semaphore),但与Semaphore不同的是,许可的累加上限是1。

park()方法:

阻塞当前线程/阻塞传入的具体线程

在这里插入图片描述

permit默认是0,所以一开始调用park()方法,当前线程就会阻塞,直到别的线程将当前线程的permit设置为1时, park方法会被唤醒,然后会将permit再次设置为0并返回。

unpark(Thread thread)方法:

唤醒处于阻断状态的指定线程

在这里插入图片描述

调用unpark(thread)方法后,就会将thread线程的许可permit设置成1(注意多次调用unpark方法,不会累加,permit值还是1)会自动唤醒thread线程,即之前阻塞中的LockSupport.park()方法会立即返回。

public static void main(String[] args) {/**LockSupport:俗称 锁中断以前的两种方式:1.以前的等待唤醒通知机制必须synchronized里面有一个wait和notify2.lock里面有await和signal这上面这两个都必须要持有锁才能干,LockSupport它的解决的痛点1。LockSupport不用持有锁块,不用加锁,程序性能好,2。不用保证2个方法的先后顺序,不容易导致卡死*/Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + "\t ----come in "+System.currentTimeMillis());LockSupport.park();//阻塞当前线程System.out.println(Thread.currentThread().getName() + "\t ----被唤醒 "+ System.currentTimeMillis());}, "t1");t1.start();LockSupport.unpark(t1);System.out.println(Thread.currentThread().getName()+"\t 通知t1...");}
t1	 ----come in 1606459998675
main	 通知t1...
t1	 ----被唤醒 1606459998676

底层原理

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语(Unsafe类的native方法)。

LockSupport是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞,阻塞之后也有对应的唤醒方法。归根结底,LockSupport调用的Unsafe中的native代码。

LockSupport提供park()和unpark()方法实现阻塞线程和解除线程阻塞的过程,LockSupport和每个使用它的线程都有一个许可(permit)关联。permit相当于1,0的开关,默认是0,调用一次unpark就加1变成1,调用一次park会消费permit,也就是将1变成0,同时park立即返回。如再次调用park会变成阻塞(因为permit为零了会阻塞在这里,一直到permit变为1),这时调用unpark会把permit置为1。每个线程都有一个相关的permit, permit最多只有一个,重复调用unpark也不会积累凭证。

形象的理解:
线程阻塞需要消耗凭证(permit),这个凭证最多只有1个。
当调用park方法时
*如果有凭证,则会直接消耗掉这个凭证然后正常退出;
*如果无凭证,就必须阻塞等待凭证可用;
而unpark则相反,它会增加一个凭证,但凭证最多只能有1个,累加无效。

面试题

为什么可以先唤醒线程后阻塞线程?
因为unpark获得了一个凭证,之后再调用park方法,就可以名正言顺的凭证消费,故不会阻塞。

为什么唤醒两次后阻塞两次,但最终结果还会阻塞线程?
因为凭证的数量最多为1,连续调用两次unpark和调用一次unpark效果一样,只会增加一个凭证;
而调用两次park却需要消费两个凭证,证不够,不能放行。

public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + "\t ----come in "+System.currentTimeMillis());LockSupport.park();//阻塞当前线程System.out.println(Thread.currentThread().getName() + "\t ----被唤醒1 "+ System.currentTimeMillis());LockSupport.park();//阻塞当前线程System.out.println(Thread.currentThread().getName() + "\t ----被唤醒2 "+ System.currentTimeMillis());}, "t1");t1.start();TimeUnit.SECONDS.sleep(3L);LockSupport.unpark(t1);LockSupport.unpark(t1);System.out.println(Thread.currentThread().getName()+"\t 通知t1...");}
t1	 ----come in 1606460725978
main	 通知t1...
t1	 ----被唤醒1 1606460728978

相关文章:

[题解]P2015 二叉苹果树

P2015 二叉苹果树 树形dp,一般用dfs辅助解决。 当我们搜索到\(u\),此时剩下\(cnt\)条边可以用,也就是说\(u\)为根节点的子树最多可以保留\(cnt\)条边。 由于上一层的需求,我们显然需要枚举剩余边数\(i\)(\(1\leq i\leq cnt\))。接下来对于每个\(i\),我们考虑剩余的\(u\)…...

fd拦截请求,修改数据

连接:https://blog.51cto.com/u_15127606/4533282本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18162084...

与 Apollo 共创生态:Apollo 七周年大会给带来的震撼

文章目录 一、七年蛰伏,Apollo 迎来“智变”时刻二、Apollo 企业生态计划与开放平台2.1 Apollo X 企业自动驾驶解决方案2.2 Apollo 开放平台携手伙伴共创生态 三、个人感悟 一、七年蛰伏,Apollo 迎来“智变”时刻 让我们把时间倒回到 2013 年&#xff0…...

玩转MongoDB 从入门到实战 pdf mongodb从入门到商业实战pdf下载

玩转MongoDB 从入门到实战 pdf mongodb从入门到商业实战pdf下载 转载huatechinfo2023-09-14 20:28:05 文章标签mongodb数据库数据文章分类MongoDB数据库阅读数277目录MongoDB 数据库介绍01、MongoDB简介1、性能高 2、支持分布式 3、安装和部署容易 4、便于开发 5、NOSQL与SQL…...

Angular创建项目

Angular创建项目 文章目录 Angular创建项目1. 创建项目1.1 直接安装1.2 跳过npm i安装 2. 运行程序 1. 创建项目 ng new 项目名称 1.1 直接安装 ng new angulardemo --同时会安装依赖包,执行的命令就是npm i 1.2 跳过npm i安装 ng new angulardemo --skip-inst…...

多语言网站 根据用户语言进行跳转

近期在做一个项目的时候用户要求网站要中英两种语言。当时设想 中文则使用 /cn 二级目录,英文使用 /en 目录,而不加目录访问时根据用户计算机所使用的语言进行判断,并跳转至对应的目录下。起初做了一个根据用户安装语言进行判断的实例,但是在模拟蜘蛛抓取的时候发现百度总是…...

JUC面试(十一)——LockSupport

可重入锁 可重入锁又名递归锁 是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提,锁对象得是同一个对象),不会因为之前已经获取过的锁还没释放而阻塞。 Java中ReentrantLock和synchronized都是可重入锁&am…...

Datawhale 202301 设计模式 | 人工智能 现代方法 习题

Exercise 1 绪论 Q:用您自己的话来定义:(a)智能,(b)人工智能,(c)智能体,(d)理性,(e)逻…...

k8s安装dashboard面板

k8s dashboard github地址:https://github.com/kubernetes/dashboard注意:dashboard版本要和k8s版本匹配,具体参考release里的Compatibility:https://github.com/kubernetes/dashboard/releases安装命令wget https://raw.githubus…...

最详细、最仔细、最清晰的几道python习题及答案(建议收藏哦)

名字:阿玥的小东东 学习:python。c 主页:没了 今天阿玥带大家来看看更详细的python的练习题 目录 1. 在python中, list, tuple, dict, set有什么区别, 主要应用在什么样的场景? 2. 静态函数, 类函数, 成员函数、属性函数的区别? 2.1静态…...

逆水寒魔兽老兵服副本攻略及代码分析(英雄武林风云录,后续更新舞阳城、扬州、清明等副本攻略)

文章目录一、武林风云录1)老一:陈斩槐(只有四个机制,dps压力不大,留爆发打影子就行)(1)点名红色扇形区域(2)点名红色长条,注意最后还有一段大劈&a…...

SpringMVC总结

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。SpringMVC是一种web层的mvc框架,用于替代servlet(处理响应请求,获取表单参数,表单验…...

二进制部署kubernetes高可用集群

二进制部署kubernetes高可用集群 一、单节点部署 1、集群节点规划(均是24位掩码) 负载均衡节点Master节点Node节点Harbor私有仓库节点nginx110.4.7.23master110.4.7.11node110.4.7.2110.4.7.200nginx210.4.7.24master210.4.7.12node210.4.7.22 2、基本…...

机器学习(七):Azure机器学习模型搭建实验

文章目录 Azure机器学习模型搭建实验 前言 Azure平台简介 Azure机器学习实验 Azure机器学习模型搭建实验 前言 了解Azure机器学习平台,知道机器学习流程。 Azure平台简介 Azure Machine Learning(简称“AML”)是微软在其公有云Azure上推…...

第二类换元法倒代换专项训练

前置知识:第二类换元法 题1: 计算∫1x10xdx\int\dfrac{1}{x^{10}x}dx∫x10x1​dx 解: \qquad令x1tx\dfrac 1txt1​,t1xt\dfrac 1xtx1​,dx−1t2dtdx-\dfrac{1}{t^2}dtdx−t21​dt \qquad原式∫11t101t⋅(−1t2)dt−∫…...

VMware虚拟机无法向宿主机拖放文件

宿主机环境: Windows 10 x64专业工作站版 VMware workstation pro 17 TotalCommander 9.21a 虚拟机环境: Windows 10 x64专业工作站版 TotalCommander 9.21a 现象: 从虚拟机的TC向宿主机TC拖放文件时,光标显示为禁止drop的图…...

Java基础语法——运算符与表达式

目录 Eclipse下载 安装 使用 运算符 键盘录入 Eclipse下载 安装 使用 Eclipse的概述(磨刀不误砍柴工)——是一个IDE(集成开发环境)Eclipse的特点描述(1)免费 (2)纯Java语言编写 (3)免安装 &#xff08…...

连通性1(Tarjan 理论版)

目录 一、无向图割点、桥、双连通分量 Tarjan 算法求割点和桥(割边) “割点”代码 边双和点双连通分量 边双连通分量 和 点双连通分量 的缩点 二、有向图强连通分量 1.有向图的弱连通与强连通 2.强连通分量 Kosaraju算法 Tarjan 算法&#xff08…...

数据库02_函数依赖,数据库范式,SQL语句关键字,数据库新技术---软考高级系统架构师009

1.首先我们来看这个,给定一个X,能确定一个Y那么就说,X确定Y,或者Y依赖x,那么 比如y = x * x 就是x确定y,或者y依赖于x 2.然后再来看图,那么左边的部分函数依赖,就是,通过A和B能决定C,那么如果A只用给就能决定C,那么就是部分函数依赖. 3.然后再来看,可以看到,A可以决定B,那么…...

王者荣耀入门技能树-解答

前言 前段时间写了一篇关于王者荣耀入门技能树的习题,今天来给大家解答一下。 职业 以下哪个不属于王者荣耀中的职业: 射手法师辅助亚瑟 这道题选:亚瑟 王者荣耀中有6大职业分类,分别是:坦克、战士、刺客、法师、…...

java基础学习 day37 (集合)

集合与数组的区别 长度:数组长度固定,一旦创建完成,就不能改变。集合长度可变,根据添加和删除元素,自动扩容或自动收缩,(添加几个元素就扩容多少,删除几个元素就收缩多少&#xff0…...

C语言:数组

往期文章 C语言:初识C语言C语言:分支语句和循环语句C语言:函数 目录往期文章前言1. 一维数组的创建和初始化1.1 数组的创建1.2 数组的初始化2. 一维数组的使用3. 一维数组在内存中的存储4. 二维数组的创建和初始化4.1 二维数组的创建4.2 二维…...

斐波那契数列的--------5种算法(又称“兔子数列”)

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:…...

【计算机网络(考研版)】第一站:计算机网络概述(二)

目录 四、OSI参考模型和TCP/IP模型 1.ISO/0SI参考模型 2.TCP/IP模型 3.OSI/RM参考模型和TCP/IP参考模型的区别和联系 4.五层教学模型 5.数据流动示意图 四、OSI参考模型和TCP/IP模型 前面我们已经讨论了体系结构的基木概念,在具体的实施中有两个重要的网络体系…...

Python内置包Tkinter的重要控件(下)

本文将接着介绍剩下的五个重要的控件,包括Canvas,Messagebox,Listbox,Checkbutton,Radiobutton。 目录 前言 控件 1. Canvas 2. Messagebox 3. Listbox 4. Radiobutton 5. Checkbutton 总结 前言 包括但不…...

(Java高级教程)第四章必备前端基础知识-第二节2:CSS属性

文章目录一:CSS属性一览表二:常用属性详解(1)字体属性(2)文本属性(3)背景属性一:CSS属性一览表 W3C:元素属性 A: align-content规定弹性容器内…...

听障人士亲述:我们在VRChat用手语交流,成员规模5000人

如果你在B站上搜索VRChat,排在前面的热门视频几乎都是与老外聊天的内容。除了练习语言、交文化流外,你还能在VRChat上遇到不少哇哇乱叫的小孩。作为一款VR社交应用,除了有趣的小游戏外,说话聊天也是VRChat关键的玩法之一。而有这么…...

设计一个70W在线人数的弹幕系统

背景: 直播业务中增加弹幕系统,支持单房间百万用户同时在线。 问题分析: 带宽压力: 假如说每3秒促达用户一次,那么每次内容至少需要有15条才能做到视觉无卡顿。15条弹幕http包头的大小将超过3k,那么每秒…...

一起自学SLAM算法:第9章-视觉SLAM系统

连载文章,长期更新,欢迎关注: 上一章介绍了以激光雷达做为数据输入的激光SLAM系统,激光雷达的优点在于数据稳定性好、测距精度高、扫描范围广,但缺点是价格昂贵、数据信息量低、安装部署位置不能有遮挡、雨天烟雾等环境…...

LeetCode 437. 路径总和 III

LeetCode 437. 路径总和 III 给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的&#xff…...

LinuxC—高级IO

高级IO 1 非阻塞IO/有限状态机编程 1.1 基本概念 定义 有限状态机(Finite State Machine) 缩写为 FSM,状态机有 3 个组成部分:状态、事件、动作。 状态:所有可能存在的状态。包括当前状态和条件满足后要迁移的状态。事件:也称为…...

WebSocket 入门:简易聊天室

大家好,我是前端西瓜哥,今天我们用 WebSocket 来实现一个简单的聊天室。 WebSocket 是一个应用层协议,有点类似 HTTP。但和 HTTP 不一样的是,它支持真正的全双工,即不仅客户端可以主动发消息给服务端,服务…...

Windows10添加WebDav地址时报错“输入的文件夹无效,请选择另一个”

一、问题描述在使用Windows10添加WebDav网络地址时,报错“输入的文件夹无效,请选择另一个”,如下图所示:二、问题分析这是由于Windows10的WebDav默认只支持https协议,没有支持http协议导致的。三、解决办法3.1、修改注…...

Cadence PCB仿真使用Allegro PCB SI生成串扰总结报告Crosstalk Summary Report及报告导读图文教程

🏡《Cadence 开发合集目录》   🏡《Cadence PCB 仿真宝典目录》 目录 1,概述2,生成报告3,报告导读4,总结1,概述 Crosstalk Summary Report是各种串扰问题的一个简要总结报告。本文简单介绍使用Allegro PCB SI生成Crosstalk Summary Report报告的方法,及其要点导读。…...

【5-卷积神经网络】北京大学TensorFlow2.0

课程地址:【北京大学】Tensorflow2.0_哔哩哔哩_bilibiliPython3.7和TensorFlow2.1六讲:神经网络计算:神经网络的计算过程,搭建第一个神经网络模型神经网络优化:神经网络的优化方法,掌握学习率、激活函数、损…...

C++初阶:vector类

文章目录1 vector介绍2 实现vector2.1 类的定义2.2 默认成员函数2.2.1 构造函数2.2.2 析构函数2.2.3 拷贝构造2.2.4 赋值重载2.3访问接口2.4 容量接口2.5 修改接口2.5.1 尾插尾删2.5.2 任意位置插入2.5.3 任意位置删除2.6 其他接口1 vector介绍 1 vector是表示可变大小数组的序…...

机器学习中软投票和硬投票的不同含义和理解

设置一个场景,比如对于今天音乐会韩红会出现的概率三个人三个观点 A:韩红出现的概率为47% B:韩红出现的概率为57% C:韩红出现的概率为97% 软投票:软投票会认为韩红出现的概率为1/3*(47%57%97%)67% 硬投票:…...

Linux系统之网络客户端工具

Linux系统之网络客户端工具一、Links工具1.Links工具介绍2.安装Links软件3.Links工具的使用4.打印网页源码输出5.打印url版本到标准格式输出二、wget工具1.wget工具介绍2.安装wget软件3.wget工具的使用三、curl工具1.curl工具的介绍2.curl的常用参数3.curl的基本使用四、scp工具…...

c++函数(2)

这里写自定义目录标题默认参数函数重载递归函数变量周期默认参数 可为形参指定默认值,如果在函数调用时,没有指定与形参对应的实参时,就自动使用默认值。 默认参数可简化复杂函数的调用。 默认参数在函数名第一次出现在程序中指定&#xff0…...

HackTheBox Stocker API滥用,CVE-2020-24815获取用户shell,目录遍历提权

靶机地址: https://app.hackthebox.com/machines/Stocker枚举 使用nmap枚举靶机 nmap -sC -sV 10.10.11.196机子开放了22,80端口,我们本地解析一下这个域名 echo "10.10.11.196 stocker.htb" >> /etc/hosts 去浏览器访问…...

Java线程池应用实例

线程池的学习基本概念好处应用场景ThreadPoolExecutor实例理解:执行流程自定义线程池4大核心参数测试demo结论:ExecutorService常用方法思考获取ExecutorService代码示例ScheduleExecutorService常用获取方式如下ScheduledExecutorService常用方法如下:代…...

数字签名技术

介绍数字签名 数字签名是一种用于确认数据的完整性、确认发送者身份的技术。 签名主要包含两个过程:做摘要、进行非对称加密。 做摘要:签名者使用消息摘要算法对消息做摘要;进行非对称加密,得到签名值:签名者使用私…...

WPF-3D图形

WPF-3D图形 WPF的3D功能可以在不编写任何c#代码的情况下进行绘制,只需要使用xaml即可完成3D图形的渲染。本文主要讲述了WPF-3D中的关键概念, 以及常用到的命中测试、2d控件如何在3D对象中进行渲染,除此之外,还演示了如何导入外部…...

返回值的理解

前言 我们写的函数是怎么返回的,该如何返回一个临时变量,临时变量不是出栈就销毁了吗,为什么可以传递给调用方?返回对象的大小对使用的方式有影响吗?本文将带你探究这些问题,阅读本文需要对函数栈帧有一定…...

前端布局神器display:flex

Flexbox,一种CSS3的布局模式,也叫做弹性盒子模型,用来为盒装模型提供最大的灵活性。首先举一个栗子,之前我们是这样实现一个div盒子水平垂直居中的。在知道对象高宽的情况下,对居中元素绝对百分比定位,然后…...

【Typescript学习】使用 React 和 TypeScript 构建web应用(三)所有组件

教程来自freecodeCamp:【英字】使用 React 和 TypeScript 构建应用程序 跟做,仅记录用 其他资料:https://www.freecodecamp.org/chinese/news/learn-typescript-beginners-guide/ 第三天 以下是视频(0:40-0:60) 的内容 目录第三天1 创建Todo…...

7.3 矩阵范数

定义 向量有范数,矩阵也有范数,定义和向量范数类似,不过多了一条要求。它的定义如下: 正定性positivity,∥A∥≥0\parallel A\parallel\ge 0∥A∥≥0,只有A0A0A0时才取等号;非负齐次性homogeneity或scalin…...

Jetpack架构组件库:Hilt

Hilt Hilt 是基于 Dagger2 的依赖注入框架,Google团队将其专门为Android开发打造了一种纯注解的使用方式,相比 Dagger2 而言使用起来更加简单。 依赖注入框架的主要作用就是控制反转(IOC, Inversion of Control), 那么什么是控制…...

InstanceNorm LayerNorm

InstanceNorm && LayerNorm author: SUFEHeisenberg date: 2023/01/26 先说结论: 将Transformer类比于RNN:一个token就是一层layer,对一整句不如token有意义原生Bert代码或huggingface中用的都是InstanceNorm instead of LayerNorm&#xff…...

数据结构---堆

堆 定义 基本操作 建堆 堆排序 优先队列 一、堆的定义: 堆必须是一个完全二叉树 还得满足堆序性 什么是完全二叉树呢? 完全二叉树只允许最后一行不为满 且最后一行必须从左到右排序 最后一行元素之间不可有间隔,中间不可有空缺 如下几棵树…...

3小时精通opencv(五) 利用TrackBar进行颜色检测

3小时精通opencv(五) 利用TrackBar进行颜色检测 参考视频资源:3h精通Opencv-Python 本章内容介绍如何利用TrackBar调节色域, 手动提取到我们需要的颜色 文章目录3小时精通opencv(五) 利用TrackBar进行颜色检测创建Trackbar色彩检测创建Trackbar 在opencv中使用createTrackbar函…...

学习记录673@项目管理之进度管理案例

本文主要是进度管理之关键链路法的案例。 案例 Perfect 项目的建设方要求必须按合同规定的期限交付系统,承建方项目经理李某决定严格执行项目进度管理,以保证项目按期完成。他决定使用关键路径法来编制项目进度网络图。在对工作分解结构进行认真分析后&…...

【设计模式】结构型模式·组合模式

学习汇总入口【23种设计模式】学习汇总(数万字讲解体系思维导图) 写作不易,如果您觉得写的不错,欢迎给博主来一波点赞、收藏~让博主更有动力吧! 一.概述 又称为部分整体模式,用于把一组相似的对象当作一个单一的对象。组合模式依…...

Vue-Router详解

1、前端路由的发展历程 1.1、认识前端路由 路由其实是网络工程中的一个术语: 在架构一个网络时,非常重要的两个设备就是路由器和交换机。当然,目前在我们生活中路由器也是越来越被大家所熟知,因为我们生活中都会用到路由器&…...

Eclipse中的Build Path

Eclipse中的Build Path简介如果修改了Build Path中的中的JRE版本,记得还需要同步修改Java编译器的版本,如下图红框所示简介 Build Path是Java工程包含的资源属性合集,用来管理和配置此Java工程中【除当前工程自身代码以外的其他资源】的引用…...

Python与Matlab混合编程案例

前言因为项目需要,需要批处理很多Matlab的.m文件,从每个文件中提取结果合并到一个文件中。 很明显,如果手工统计,几百个文件会累死的。 因此立即想到了Python在批处理方面的优势,因此就在网上找了相关资料,…...

序列化及方式对比分析

什么是序列化和反序列化? 如果需要持久化Java对象比如将Java对象保存在文件中, 或在网络传输Java对象, 这些场景需要使用到序列化. 序列化 将数据结构或对象转化成二进制字节流的过程 反序列化 将在序列化过程中所产生的二进制字节流转换成数据结构或者对象的过程 目的 …...

重仓比特币

作者:Arthur Hayes Co-Founder of 100x. 编译:liam ccvalue (下文中表达的任何观点均为作者的个人观点,不应作为投资决策的依据,也不应被视为参与投资交易的建议或意见)。 我们中断牛市常规节目,为您播报这…...

01、创建型-单例模式--只有一个实例

文章目录 前言一、基本介绍1.1 什么是单例模式1.2 为什么要用单例模式1.3 应用场景1.4 单例优缺点 二、单例模式的实现方式2.1 饿汉式单例2.1.1 静态变量方式2.1.2 静态代码块 2.2 懒汉式单例2.2.1 懒汉式单例2.2.2 懒汉式优化①-线程安全2.2.2 懒汉式优化②-双重检查锁2.2.3 懒…...

深度学习从入门到精通—Transformer

1.绪论介绍 1.1 传统的RNN网络 传统的RNN(递归神经网络)主要存在以下几个问题: 梯度消失和梯度爆炸:这是RNN最主要的问题。由于序列的长距离依赖,当错误通过层传播时,梯度可以变得非常小(消失…...

CSS详解(二)

接上篇CSS详解(一)-CSDN博客 1、网页布局本质 网页布局的本质是通过 CSS 将各种 HTML 元素(即“盒子”)摆放到页面中合适的位置。这包括设置元素的尺寸、位置、边距、填充、对齐方式、浮动等。这些盒子通过 CSS 的各种布局机制进…...

vue:使用:element 中弹框中获取table高度无效

场景:dialog 弹框中想要获取里面table的高度,但是直接用 tableRef.value?.$el.offsetHeight 获取无效。 原因:dialog中有个弹框打开的加载动画。需要用监听 opeined 【Dialog 打开动画结束时的回调】等动画加载后然后进行高度获取 一、dem…...