复习JUC的总结笔记
JUC基础
-
调用Thread的start方法会调用start0,start0会调用该Thread类的run方法。Thread类如果传入了Runnable,run方法里会调用Runnable的run方法,如果没有传入,则什么也不会做。也可以通过重写Thread的run方法,让start0调用重写的run方法。start 方法只是让线程进入就绪,里面代码不一定立刻运行(CPU 的时间片还没分给它)。每个线程对象的start方法只能调用一次,如果调用了多次会出现IllegalThreadStateException。
-
建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性. TimeUnit.SECONDS.sleep(2);
-
sleep结束后的线程也未必会立刻得到执行,等cpu调度。wait结束后也不一定立刻得到执行(不一定得到锁,wait结束后从waitSet队列中出来进入到entryList队列)
-
sleep、join、wait都是让线程处于阻塞状态,sleep、join是Thread的方法,wait是Object的方法,join的底层就是调用的Object的wait,并且带超时时间的join是应用的保护性暂停模式。
附加问题:既然join是通过wait实现的,调用wait前要先获取锁,join方法里怎么获取的锁?
join方法是加了synchronized修饰的,锁的是这个thread对象
-
join会使当前线程阻塞到这行代码。细节:join的作用是让当前线程等待另一个线程执行结束,达到同步的效果。但join方法可以设置等待时间,如果在给定的等待时间,另一个线程还没有执行完,则主线程会直接继续执行,不再等待另一个线程;如果在给定的时间提前结束了,则主线程也会继续执行,而不是非要等到给定的时间。
-
interrupt用于向线程发出中断信号,但不会直接强制停止线程的执行,不会改变线程的状态,只是设置线程的打断状态为true。interrupt是为了代替stop方法,是为了让线程更安全、优雅的退出,只是告诉线程,你该停止了,后续线程可以先关闭一些资源,释放锁等,然后再选择退出,而不是像stop那样直接暴力结束线程。
isInterrupted判断当前线程的打断标记。
interrupted是Thread的静态方法,作用于当前线程,返回当前的线程的打断状态,并将打断状态设为false。
interrupt打断正常运行的线程:
Thread t = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {// 执行任务System.out.println("运行中...");}System.out.println("线程收到中断信号,优雅退出");
});
t.start();// 稍后中断线程
Thread.sleep(1000);
t.interrupt();
interrupt打断阻塞的线程:
Thread t = new Thread(() -> {log.info("初始状态: {}", Thread.currentThread().isInterrupted()); // falsetry {Thread.sleep(10000);} catch (InterruptedException e) {log.info("异常捕获时状态: {}", Thread.currentThread().isInterrupted()); // false// 恢复中断状态Thread.currentThread().interrupt();log.info("手动恢复后状态: {}", Thread.currentThread().isInterrupted()); // true}});t.start();Thread.sleep(100);log.info("主线程调用interrupt()前状态: {}", t.isInterrupted()); // falset.interrupt();log.info("主线程调用interrupt()后状态: {}", t.isInterrupted()); // true (因为线程内已恢复)
重点解释:打断阻塞的线程详细变化过程
- 中断信号到达前:
- 线程正在执行阻塞操作(如
sleep()
,wait()
,join()
等) - 中断标志初始状态为
false
- 线程正在执行阻塞操作(如
- 调用
interrupt()
瞬间:- JVM 先将线程的中断标志临时设为
true
- 这个临时设置会触发阻塞操作立即抛出
InterruptedException
- JVM 先将线程的中断标志临时设为
- 异常抛出后:
- 在抛出
InterruptedException
之前,JVM 会自动将中断标志重置回false
- 所以当进入 catch 块时,中断标志已经是
false
- 在抛出
最佳实践
- 对运行中线程:
- 在循环中定期检查
isInterrupted()
- 执行耗时操作前检查中断状态
- 发现中断后执行清理工作再退出
- 在循环中定期检查
- 对阻塞中线程:
- 总是捕获
InterruptedException
- 通常需要调用interrupt恢复中断状态(除非确定要忽略中断)
- 在清理资源后合理退出
- 总是捕获
interrupt打断被park的线程:
Thread parkedThread = new Thread(() -> {log.info("即将进入park状态");LockSupport.park(); // 在此处阻塞log.info("从park返回,中断状态: {}", Thread.currentThread().isInterrupted());// 再次park测试log.info("再次park");LockSupport.park(); // 这次不会被park阻塞住,因为中断标志已设置为truelog.info("第二次从park返回");});parkedThread.start();Thread.sleep(1000);parkedThread.interrupt(); // 打断被park的线程
JMM
- 非volatile变量的修改不会立即反映到主内存,那是什么时候写入到主内存的?
首先,JMM并没有规定具体的时机,只是规定了happens-before规则。非volatile变量的写入时间点是不确定的。a. 锁的释放与获取
- 锁释放(Monitor Exit):线程退出
synchronized
块或释放锁时,会将工作内存中的修改强制刷新到主内存。 - 锁获取(Monitor Enter):线程进入
synchronized
块或获取锁时,会清空本地内存,从主内存重新加载变量。 - 这是
synchronized
关键字隐式实现可见性的原理。
b. 线程生命周期事件
- 线程终止时(如
Thread.join()
),其本地内存的修改可能被同步到主内存。 - 线程启动时(
Thread.start()
)可能触发父线程与子线程的内存同步。
c. Final字段的特殊规则
如果对象正确发布(如构造函数正常完成且未泄露this
引用),final
字段的初始化值对其他线程是可见的。
等等。。
- 周志明的《深入理解Java虚拟机》中的一句话是:如果在本线程内观察,所有操作都是天然有序的。如果在一个线程中观察另一个线程,所有操作都是无序的。 对这话的理解:
1. 线程内观察的有序性
-
“线程内表现为串行的语义”(Within-Thread As-If-Serial)
在单线程内部,无论实际的指令执行是否发生重排序(编译器或处理器的优化行为),程序的执行结果必须与代码顺序执行的结果一致。例如:int a = 1; // 操作1 int b = 2; // 操作2 int c = a + b; // 操作3
操作1和操作2可能被重排序,但操作3的结果必然为3,不会因重排序影响最终结果。这种“看似有序”的保证称为as-if-serial语义。
-
原因
单线程环境下,指令重排序的优化不会破坏程序的逻辑正确性
2. 线程间观察的无序性
-
“指令重排序”与“内存同步延迟”
在多线程环境下,一个线程对共享变量的修改可能以不可预测的顺序被其他线程观察到。例如:public class Example {int x = 0;boolean flag = false;// 线程1public void writer() {x = 1; // 操作Aflag = true; // 操作B}// 线程2public void reader() {if (flag) { // 操作Cint y = x; // 操作DSystem.out.println(y); // 可能输出0?}} }
线程2可能先读到
flag = true
(操作C),但读取x
时却得到0
(操作D)无序性的根源
- 指令重排序:编译器、处理器为了提高性能,可能调整指令顺序。
- 内存可见性延迟:线程的工作内存与主内存的同步存在延迟,导致其他线程无法立即看到修改。
从以上可以进而解释synchronized是怎么实现有序性的。synchronized是并不能禁止编译器和处理器的重排序的,而是通过锁的互斥性保证同步代码单线程串行执行和 Happens-Before 规则间接保证有序性。
- 双重检查实现单例模式出现空指针的诡异问题
/**双重检查单例模式* @author: 小手WA凉* @create: 2024-07-06*/
public class DoubleCheckSingletion {//这里最好加volatileprivate volatile static DoubleCheckSingletion doubleCheckSingletion=null;private DoubleCheckSingletion(){}//特点:安全且在多线程情况下能保持高性能public static DoubleCheckSingletion getInstance(){if(doubleCheckSingletion==null){synchronized (DoubleCheckSingletion.class){if(doubleCheckSingletion==null){doubleCheckSingletion=new DoubleCheckSingletion();}}}return doubleCheckSingletion;}
}
以上是经典的单例模式的实现,但doubleCheckSingletion如果没有volatile修饰,通过getInstance获取的对象singletion在后续调用其它方法时,如singletion.call()会出现空指针的诡异情况!
为什么?
我们假设t1、t2两个线程同时开始调用getInstance方法获取单例对象:step1:t1执行到⑤,开始实例化对象;step2:t2执行到②,判断不为null,然后执行⑨,返回doubleCheckSingletion;step3:t2拿到doubleCheckSingletion,开始后续调用,如doubleCheckSingletion.call()。
上面过程看着没什么问题,但在step3调用时可能会出现空指针异常!
之所以可能抛出空指针,是因为⑨获取的不是一个完整的对象。
分析一下new DoubleCheckSingletion()的大致流程:
1、虚拟机遇到new指令,到常量池定位到这个类的符号引用。2、检查符号引用代表的类是否被加载、解析、初始化过。3、虚拟机为对象分配内存。4、虚拟机将分配到的内存空间都初始化为零值。5、虚拟机对对象进行必要的设置。6、执行方法,成员变量进行初始化。 7、将对象的引用指向这个内存区域。
简化一下:a、JVM为对象分配一块内存M。b、在内存M上为对象进行初始化。c、将内存M的地址赋值给doubleCheckSingletion变量
但是,以上过程并不是一个原子的过程,并且可能会被编译器重排序,如果重排序为:
a、JVM为对象分配一块内存M。c、将内存M的地址赋值给doubleCheckSingletion变量。b、在内存M上为对象进行初始化。
也就是先给doubleCheckSingletion变量赋值,然后再进行后续的对象初始化,所以t2拿到的对象就不是一个完整的对象,当尝试使用这个对象时就可能发生空指针。
解决办法就是给doubleCheckSingletion变量加上volatile修饰,禁止对doubleCheckSingletion变量读写指令的重排序。
- hapends-before规则
hapend-before:如果一个操作A“happen-before”另一个操作B,那么A的结果对B是可见的。
程序次序规则:在同一个线程中,按照代码的书写顺序(即程序顺序),前面的操作 Happens-Before 后面的操作。这意味着,单线程内的代码执行结果必须与顺序执行的结果一致,即使实际发生了指令重排序。
int x = 1; // 操作1
int y = 2; // 操作2
int z = x + y; // 操作3
根据程序次序规则,操作1 Happens-Before 操作2,操作2 Happens-Before 操作3。
实际执行中:操作1和操作2可能被重排序(例如先执行操作2再执行操作1),但最终结果必须与顺序执行一致(z
必须为3)。也就是满足 as-if-serial 语义。
管程锁定规则(Monitor Lock Rule):对一个锁的解锁happens-before随后对这个锁的加锁。即在 synchronized代码块或方法中,释放锁之前的所有操作对于下一个获取这个锁的线程是可见的。
volatile变量规则(Volatile Variable Rule):对一个volatile字段的写操作happens-before任意后续对这个字段的读操作。即确保volatile变量的写操作对其他线程立即可见。
线程启动规则(Thread Start Rule):对线程的start()方法的调用happens-before该线程的每个动作。确保线程启动时,主线程中对共享变量的写操作对于新线程是可见的。
static int x = 1;
x = 10;
new Thread(()->{System.out.println(x);
},"t2").start();
打印的x一定是10。
线程终止规则(Thread Termination Rule):一个线程内的所有操作happens-before对这个线程结束后(比如调用join()方法),其它线程可见。
static int x = 1;
Thread t1 = new Thread(()->{x = 10;
},"t1");
t1.start();
t1.join();
System.out.println(x);
打印的x一定是10。
线程中断规则(Thread Interruption Rule):对线程的interrupt()方法的调用happens-before被中断线程检测到中断事件的发生。即线程的中断操作在被该线程检测到之前已经发生。
对象终结规则(Finalizer Rule):一个对象的初始化完成(构造函数执行结束)happens-before它的 finalize()方法的开始。即在对象被回收前,其构造过程已经完全结束。
还有,对变量默认值(0,false,null)的写,对其它线程对该变量的读可见。
传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。
的interrupt()方法的调用happens-before被中断线程检测到中断事件的发生。即线程的中断操作在被该线程检测到之前已经发生。
对象终结规则(Finalizer Rule):一个对象的初始化完成(构造函数执行结束)happens-before它的 finalize()方法的开始。即在对象被回收前,其构造过程已经完全结束。
还有,对变量默认值(0,false,null)的写,对其它线程对该变量的读可见。
传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。
相关文章:
复习JUC的总结笔记
JUC基础 调用Thread的start方法会调用start0,start0会调用该Thread类的run方法。Thread类如果传入了Runnable,run方法里会调用Runnable的run方法,如果没有传入,则什么也不会做。也可以通过重写Thread的run方法,让start…...
基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别,适合研究学习(Matlab完整源码和数据),附模型研究报告
基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别,适合研究学习(Matlab完整源码和数据),附模型研究报告 目录 基于MTF的1D-2D-CNN-GRU-Attention时序图像多模态融合的故障识别,适合研究学习(…...
5G 毫米波滤波器的最优选择是什么?
新的选择有很多,但到目前为止还没有明确的赢家。 蜂窝电话技术利用大量的带带,为移动用途提供不断增加的带宽。 其中的每一个频带都需要透过滤波器将信号与其他频带分开,但目前用于手机的滤波器技术可能无法扩展到5G所规划的全部毫米波&#…...
构造函数和析构函数
概念:对象的初始化和清理是非常重要的,一个对象在使用之前,需要进行初始化,使用完成后也需要及时清理数据,简单来说构造函数时用来初始化成员属性的,析构函数时用来清理数据的。 C中利用构造函数和析构函数…...
卷积神经网络(CNN)详解
文章目录 引言1.卷积神经网络(CNN)的诞生背景2.卷积神经网络(CNN)介绍2.1 什么是卷积神经网络?2.2 卷积神经网络(CNN)的基本特征2.2.1 局部感知(Local Connectivity)2.2.…...
NoSQl注入学习
文章目录 什么是NOSQL相关概念数据库文档集合 MongoDB 基础语法创建数据库创建集合插入文档更新文档查询文档 Nosql注入PHP 中的 MongoDB 注入重言式注入联合查询注入JavaScript 注入布尔盲注 Nodejs 中的 MongoDB 注入 从一道题中学习nosql注入 参考: Nosql 注入从…...
借助LlamaIndex实现简单Agent
借助LlamaIndex实现简单Agent 1 简介 智能体的构建发展是一个趋势,借助LlamaIndex简单实现Agent。本文主要借助LlamaIndex中的FunctionTool和Workflow。Workflow是使用事件流的方法实现。 2 构建公共类 由于LlamaIndex中的OpenAI无法直接连接国内大模型…...
MCGS昆仑通太屏笔记
4.3寸:4013ef/e1 7寸:7032kw 特点: 如果是使用组态屏进行调试使用,选择com1如果是实际项目使用,选择com2 操作步骤: 先创建设备窗口,再创建用户界面 在设备窗口界面,依次设置如下…...
纯FPGA控制AD9361的思路和实现之一 概述
我们知道PS通过内存映射方式方式用户的IP,具体是将用户的逻辑做成AXI_LITE_SALVE外设,PS做为AXI_LITE_MASTER去控制。 在ZYNQ系统中存在PS所以这个架构和思路很流行,ADI出的配置软件无线电子板的DEMO基本都是基于这样的架构。比如下图【上截…...
北斗短报文终端与5G融合:构建空天地海一体化通信新生态
随着北斗三号全球组网完成,短报文通信服务从区域覆盖迈向全球通达,其与5G技术的深度融合,正开创“空天地海一体化”通信新时代。深圳作为全国北斗产业高地,汇聚了遨游通讯等领军企业,其推出的北斗短报文终端通过技术创…...
Meteonorm8-免费使用教程(详细教程-免费)
Meteonorm介绍 Meteonorm 8 是一款专业的气象数据生成软件,广泛应用于太阳能、建筑能效、农业气候研究等领域。它提供全球范围内高精度的气象数据,支持多种数据源和插值方法,帮助用户获取特定地点的长期气象统计信息。 Meteonorm核心功能 …...
nohup的使用
最近远程连接服务器跑程序的时候,总是碰到本地电脑息屏或者ssh断开导致程序中断,往往一觉醒来不是程序跑完了而是因为各种原因本地中断了。为此想到了nohup这个命令,可以让程序在我本地电脑关机后也可以在远端服务器上面运行。 命令如下&…...
如何查看HTTP状态码?
目录 一、HTTP状态码查看方法 1. 浏览器开发者工具 2. 命令行工具 3. 服务器日志分析 二、HTTP状态码分类与核心含义 1. 信息类(1xx) 2. 成功类(2xx) 3. 重定向类(…...
2025.04.19【Chord diagram】| 弦图绘制技巧大全
Customization Apply customization to the circular chart: color, background, track height and more. Chart types Learn how to use other chart types like line chart, barcharts, vertical ablines and more. 文章目录 CustomizationChart types 什么是弦图ÿ…...
解码 Web Service:从技术原理到应用场景的深度剖析
Web Service 是一种基于网络的、分布式的计算技术,它允许不同的应用程序之间通过网络进行通信和交互。以下是关于 Web Service 的详细介绍: 一、定义与概念 Web Service 是一种可以通过 Web 协议(如 HTTP)进行访问的软件组件&am…...
hackmyvm-airbind
收集信息 arp-scan -l nmap -sS -v 192.168.195.162 访问扫描到的ip,直接跳转到登录页面,利用admin/admin弱口令登录 在settings.php中找到一处文件上传,上传一句话木马,上传成功 反弹shell 上传php-reverse-shell.php 抓包&am…...
[HCIP] OSPF 综合实验
题目 实验需求 1.R5为TSP,其上只能配置IP地址; R5与其他所有直连设备间均使用公有IP;环回地址为100.1.1.1/32 2.R4设备为企业出口路由器 3.整个OSPF环境IP基于172.16.0.0/16划分; 4.所有设备均可访问R5的环回; 5…...
arkTs:使用setTimeout / setInterval 实现透明度切换的轮播图
使用setTimeout / setInterval 实现透明度切换的轮播图 1 主要内容说明1.1 setTimeout1.2 setInterval1.3 表格 2 举例说明2.1 图片变化的内容说明2.2 源码相关内容说明2.3 源码A2.4源码A的运行效果展示2.4.1 效果截图2.4.2 效果视频 3.结语4.定位日期 1 主要内容说明 1.1 set…...
苍穹外卖项目中所涉及到的测试内容
1.使用JWT令牌封装用户令牌,并且设置相应的拦截器校验JWT的有效性,从而确保了项目的安全可靠 1.基本功能测试: 验证合法JWT是否能够正常通过拦截器的校验 验证非法的JWT能否正常通过拦截器的校验 2.可靠性测试: 3.易用性测试 …...
案例驱动的 IT 团队管理:创新与突破之路:第五章 创新管理:从机制设计到文化养成-5.2 技术决策民主化-5.2.3草根创新的孵化土壤构建
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 草根创新的孵化土壤构建:IT团队技术决策民主化的底层实践1. 背景与挑战:传统技术决策体系的失效1.1 行业现状与痛点1.2 草根创新的价值潜力 2. 机制设…...
探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍
重要的放前面 Python 工匠:案例、技巧与工程实践 探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍 在Python的编程世界中,从入门小白到技术大牛的进阶之路往往充满挑战。Python工匠:案例、技巧与工…...
【langchain4j】Springboot如何接入大模型以及实战开发-AI问答助手(一)
langchain4j介绍 官网地址:https://docs.langchain4j.dev/get-started langchain4j可以说是java和spring的关系,spring让我们开发java应用非常简单,那么langchain4j对应的就是java开发ai的 “Spring” 他集成了AI应用的多种场景,…...
解决Windows update服务启动拒绝访问的问题 | wuauserv 注册表拒绝访问的方法
在某些情况下,为了配置系统更新相关服务(例如禁用 Windows 自动更新),我们需要更改注册表中 wuauserv 项的权限。本教程将带你一步步操作,成功获取并修改权限。 修改注册表路径: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv 步骤一:打开注册表编辑…...
精益数据分析(5/126):解锁创业成功的关键密码
精益数据分析(5/126):解锁创业成功的关键密码 大家好!我一直坚信在技术与商业不断融合的当下,持续学习是保持进步的唯一途径。之前我们一起探讨了《精益数据分析》的部分内容,今天咱们接着深入学习&#x…...
Cribl 优化EC2 ip-host-region 数据
We’ve seen examples of using the magical powers of regex to customize Functions, extract fields, and filter events in real time. In this section, we’ll show you how to sprinkle your Lookups with regex magic. Lets walk through a Pipeline that demonstrates…...
【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
以下是桶排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、桶排序基础实现 原理 将数据分到有限数量的桶中,每个桶内部使用其他排序算法(如插入排序或快速排序)…...
栈(c++)
今天介绍两种在c中写“栈”方法 1. #include <bits/stdc.h> using namespace std;class mystack { private:int a[1000];int curr -1; public:void push(int);void pop();int top();bool empyt();int size(); };int main() {mystack n;while(true){int a;cout<<&…...
GraphRAG与RAG的区别和原理简介
第一章 图谱与向量的共生逻辑 1.1 知识载体的局限性 向量空间模型虽能高效捕捉文本语义相似性,却无法解析知识的深层关联。例如,当用户询问“特斯拉4680电池与续航里程的关系”,向量检索可能仅返回技术参数片段,而无法解释化学成…...
vue2技术练习-开发了一个宠物相关的前端静态商城网站-宠物商城网站
为了尽快学习掌握相关的前端技术,最近又实用 vue2做了一个宠物行业的前端静态网站商城。还是先给大家看一下相关的网站效果: 所以大家如果想快速的学习或者掌握一门编程语言,最好的方案就是通过学习了基础编程知识后,就开始利用…...
[每周一更]-(第140期):sync.Pool 使用详解:性能优化的利器
文章目录 一、什么是 sync.Pool?二、sync.Pool 的基本作用三、sync.Pool 的主要方法四、sync.Pool 的内部工作原理五、sync.Pool 适用场景六、使用示例示例 1:基本使用输出示例:示例 2:并发使用 七、一个基于 sync.Pool 的 **Benc…...
Prompt-Tuning 提示词微调
1. Hard Prompt 定义: Hard prompt 是一种更为具体和明确的提示,要求模型按照给定的信息生成精确的结果,通常用于需要模型提供准确答案的任务. 原理: Prompt Tuning原理如下图所示:冻结主模型全部参数,在…...
sqli-labs之Less-7 GET注入写shell
验证注入点:单引号报错,)) 根据提示,是想让我们试试写shell 第一个条件 secure_file_priv 写shell即MySQL需要对外写文件,但默认MySQL是不允许outfile来导出数据的,先动手在MySQL确认一下。 MySQL特性,se…...
数据库基础-B+树
查询类型 全表扫描,不提供索引,扫描所有集合中的数据。根据指定key值查询指定点范围查询,在指定区间内查询 有很多方法能够进行快速扫面数据,但是再快复杂度也是O(N),我们的目标是想办法将查询复杂度降低到O(logN)。…...
智能语音备忘录:SpeechRecognition与gTTS的奇妙融合
引言:智能语音备忘录的时代已经到来 在这个信息爆炸的时代,我们每天需要处理大量的事务和信息。传统的文字记录方式虽然可靠,但在效率上往往难以满足快节奏生活的需求。想象一下,如果你能在驾车、散步或是灵感突现的任何时刻&…...
C++项目 —— 基于多设计模式下的同步异步日志系统(3)(日志器类)
C项目 —— 基于多设计模式下的同步&异步日志系统(3)(日志器类) 整体思想设计日志消息的构造C语言式的不定参函数的作用函数的具体实现逻辑1. 日志等级检查2. 初始化可变参数列表3. 格式化日志消息4. 释放参数列表5. 序列化和…...
2025/4/19 数据库的流程控制函数
单行函数_流程函数 要点: 流程处理函数可以根据不同的条件 执行不同的处理流程 可以在SQL语句中实现不同的条件选择,MySQL中的流程处理函数主要包括if() ifnull() 和 case() 函数 多行函数_聚合函数 和单行函数的区别: 单行函数是作用在每一行 最终结果可能是多行结果 多行…...
代码随想录打家劫舍+树形DP入门
动态规划part07 198.打家劫舍 视频讲解:https://www.bilibili.com/video/BV1Te411N7SX https://programmercarl.com/0198.%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D.html dp数组:进入房屋i能够偷得得最大金额dp[i]递推公式:根据不相邻原则…...
Http基础
目录 定义 一、请求部分(Request) 1. 请求行(Request Line) 常见请求方法: 2. 请求头(Request Headers) 3. 请求体(Request Body) 二、响应部分(Respo…...
【Unity】bug记录——部分物体突然不受animator控制
博主烘焙完灯光后突然发现有的物体的动画失效了,不会动,测试发现是因为勾了static(但是有些勾了static的物体就没事),修改static为Contribute GI Static(只针对光照静态)就行...
Zephyr、FreeRTOS、RT-Thread 邮箱(Mailbox)对比分析
一、核心特性对比 特性ZephyrFreeRTOSRT-Thread消息类型支持指针或4字节数据(依赖架构)仅支持指针传递支持任意数据类型(需指定消息长度)容量固定容量(静态初始化配置)动态容量(基于队列长度&a…...
xilinx fpga中pll与mmcm的区别
Xilinx中的PLL(锁相环)和MMCM(混合模式时钟管理器)都是用于时钟管理的关键组件,但它们之间存在一些显著的区别。以下是对两者的详细比较: 1. 功能特性 PLL(锁相环): 主…...
Python语法系列博客 · 第8期[特殊字符] Lambda函数与高阶函数:函数式编程初体验
上一期小练习解答(第7期回顾) ✅ 练习1:找出1~100中能被3或5整除的数 result [x for x in range(1, 101) if x % 3 0 or x % 5 0]✅ 练习2:生成字符串长度字典 words ["apple", "banana", "grape…...
黑马商城(五)微服务保护和分布式事务
一、雪崩问题 二、雪崩-解决方案(服务保护方案) 请求限流: 线程隔离: 服务熔断: 服务保护组件: 三、Sentinel 引入依赖: <!--sentinel--> <dependency><groupId>com.aliba…...
Java 编译与反编译深度解析
Java 编译与反编译深度解析 1. 编译过程详解 (1) 完整编译流程 .java 文件 → 词法分析 → 语法分析 → 语义分析 → 字节码生成 → .class 文件│ │ │ │↓ ↓ ↓ ↓识别关键字 生成抽象语法树 类型…...
Java集合框架中的List、Map、Set详解
在Java开发中,集合框架是处理数据时不可或缺的工具之一。今天,我们来深入了解一下Java集合框架中的List、Map和Set,并探讨它们的常见方法操作。 目录 一、List集合 1.1 List集合介绍 1.2 List集合的常见方法 添加元素 获取元素 修改元素…...
国产的 Java Solon v3.2.0 发布(央企信创的优选)
Solon 框架! Solon 是新一代,Java 企业级应用开发框架。从零开始构建(No Java-EE),有灵活的接口规范与开放生态。采用商用友好的 Apache 2.0 开源协议,是“杭州无耳科技有限公司”开源的根级项目ÿ…...
机器学习决策树
一、何为决策树 决策树(Decision Tree)是一种分类和回归方法,是基于各种情况发生的所需条件构成决策树,以实现期望最大化的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。它的运行机制非常通俗易…...
Java集合及面试题学习
知识来源沉默王二、小林coding、javaguide 1、ArrayList list.add("66") list.get(2) list.remove(1) list.set(1,"55") List<String> listnew ArrayList<>(); 底层是动态数组 添加元素流程:判断是否扩容…...
【内置函数】84个Python内置函数全整理
Python 内置函数全集(完整分类 参数详解 示例) 文章目录 Python 内置函数全集(完整分类 参数详解 示例)一、数值与数学函数abs(x)divmod(a, b)pow(x, y, modNone)round(number[, ndigits])sum(iterable, /, start0)hash(obj) …...
【LeetCode 热题 100】双指针 系列
📁283. 移动零 对于该题目,需要注意的是两个地方,一是保持非零元素的相对顺序,以及O(1)的空间复杂度。 采用双指针的思路,将数组划分成3个区间,。 [0 , left]:该区间内元素全是非零元素。 [left1 , right…...