【JavaEE】多线程(2)
一、线程安全
1.1 线程安全的概念
线程是随机调度执行的,如果多线程环境下的程序运行的结果符合我们预期则说明线程安全,反之,如果遇到其他结果甚至引起了bug则说明线程不安全
1.2 经典例子与解释
下面举一个经典的线程不安全的例子:
public class Demo2 {private static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count++;}});Thread t2 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count++;}});t1.start();t2.start();t1.join();t2.join();System.out.println("count = "+ count);}
}
上述代码中t1和t2两个线程对count进行累加操作,在主线程中启动这两个线程然后通过join等待这两个线程都执行完后打印count,预期结果为100000,但打印结果如下:
上述结果不符合我们的预期,这便是产生了线程安全问题
接下来我们通过CPU指令的方式解释上述原因
count++这个行代码可以看作3个CPU指令:
- 把内存count总的值读取到CPU寄存器中 => load
- 把寄存器中的值+1,此时任然在寄存器中 =>add
- 把上述寄存器计算后的值写回到内存count里 =>save
由于线程随机调度,所以两个线程的CPU指令执行顺序也是随机的。
例如下图:
(画图,时间轴。。。。。。。。。。)
首先t1线程和t2线程分别将1加载到CPU寄存器中(假设此时count的值为1),然后在寄存器中将其加1变为2,最后t1先将2加载回内存中,t2也把2加载回内存中,所以两次加1操作只加了一次1
当然上述执行顺序只是无数可能中的一种,可能t1的一组指令还没有执行完,t2就执行了好几组
下面来总结一下线程不安全的原因
1.3 线程不安全的原因
- 线程是随机调度,抢占式执行的
- 修改共享数据,多个线程修改同一个变量
- 多个线程修改共享数据的操作不是原子性,(count++是3个CPU指令,但是赋值操作就是原子性的)
- 内存可见性问题
- 指令重排序
4和5后面再解释
1.4 解决线程安全问题
根据上述原因下手
原因1:无法干预
原因2:可以干预,但并不是一个普适的做法,因为有些代码就是要修改同一个变量
原因3:这是一个普适的做法,我们可以将一系列非原子的操作打包成一个原子性的操作->加锁
1.4.1什么是锁
锁是在多线程编程中用来控制线程对共享资源访问的一种机制
1.针对锁主要有这两个操作:
- 加锁:线程t1加上锁之后,t2也尝试使用同一个锁进行加锁,就会阻塞等待
问:什么叫“t2也尝试使用同一个锁进行加锁”?
答:你可以理解为我们给t2里的操作加上了一种机制,这个机制就是必须加上锁才能进行操作,t1拿了一个锁,加锁后进行它的操作,如果t2也想拿这个锁来加锁就必须等t1操作完成解锁之后,再拿这个锁进行加锁进行它的操作,在此之前t2要阻塞等待,当然,如果t2选择拿别的锁进行加锁就不会阻塞等待(假设只有t1和t2两个线程)
比如,A在餐厅里定了一个包间,把门上锁之后来用餐,这样B来了就不会影响A用餐的过程;也就是t2不会对t1修改count的过程进行干扰,这样就保证了操作的原子性
- 解锁:t1解锁之后,t2才有可能拿到锁,因为尝试竞争锁的线程可能不只一个
2. 锁的主要特性:互斥,一个线程获取到锁之后,另一个线程也尝试加这个锁,就会阻塞等待,这种现象叫锁竞争或锁冲突,代码中也可以有多个锁,只有多个线程竞争同一个锁才会发生锁竞争,竞争不同的锁则不会发生锁竞争
1.5 synchronized关键字
1.5.1 synchronized解读
使用synchronized关键字,synchronized关键字解读:
synchronized (locker) {count++;
}
- 这是一个Java的关键字,不是方法
- synchronized后面括号里面写的是锁对象
- 锁对象的用途:用来区分两个线程是否针对同一个对象加锁,如果是,就会出现锁竞争/互斥就会引起阻塞等待,如果不是就不会出现锁竞争,也就不会阻塞等待
-
synchronized的{ }:进入到代码块,就是对上述锁对象进行加锁操作,当出了代码块,就是对锁对象进行解锁
我们可以让t1和t2都使用同一个锁对象locker来对count变量的修改操作进行上锁
private static int count = 0;
public static void main(String[] args) throws InterruptedException {Object locker = new Object(); //锁对象Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {synchronized (locker) {count++;}}});Thread t2 = new Thread(() -> {for (int i = 0; i < 50000; i++) {synchronized (locker) {count++;}}});t1.start();t2.start();t1.join();t2.join();System.out.println("count = "+ count);
}
这样,虽然两个线程仍然是抢占式执行的,但是保证了count++;这个操作的原子性,结果为:count = 100000
Java中随便拿一个对象,都可以作为加锁的对象
1.5.2 synchronized使用示例
1)修饰代码块:指定锁哪个对象,也就是可以锁任意对象
public class SynchronizedDemo {private Object locker = new Object();public void method() {synchronized (locker) {}}
}
锁当前对象:()里直接写this
public class SynchronizedDemo {public void method() {synchronized (this) {}}
}
2)修饰普通方法:锁的SynchronizedDemo对象,谁调用method()方法,就锁谁(可以有多个)
public class SynchronizedDemo {public synchronized void methond() {}
}
3)修饰静态方法:锁的SynchronizedDemo类对象(一个java进程中,一个类只有唯一一个类对象)
public class SynchronizedDemo {public synchronized static void method() {}
}
1.5.3 synchronized特性
1)互斥
某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象,synchronized就会阻塞等待
2)可重入
for (int i = 0; i < 50000; i++) {synchronized (locker) {synchronized (locker) {count++;}}
}
上述线程先对locker进行第一次加锁,在第二次加锁的时候,locker对象已经被锁住了,按照之前的理解,尝试针对一个已经被锁的对象加锁时,就会阻塞等待,这种情况就叫死锁
但synchronized是可重入锁,可重入锁的内部包含了线程持有者和计数器
- 如果某个线程加锁的时候,发现这个锁已经被别人占用,但是恰好占用的是自己,那么仍然可以继续获取到锁,并让计数器自增
- 解锁的时候(也就是每走出一个代码块)计数器就会递减,当减到0时才真正释放锁
这种机制就叫可重入锁
1.6 死锁
1.6.1 两个常见的场景
死锁有两个比较典型的场景
场景一:不可重入锁引起的死锁
一个线程对一个线程连续加锁两次且这个锁是不可重入锁就会引起死锁
场景二:两个线程两把锁
public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();Object locker2 = new Object();Thread t1 = new Thread(() -> {synchronized(locker1) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2) {System.out.println("t1获取了两把锁");}}});Thread t2 = new Thread(() -> {synchronized(locker2) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker1) {System.out.println("t2获取了两把锁");}}});t1.start();t2.start();System.out.println("死锁ing....");}
上述代码中,locker1被t1占用,locker2被t2占用,接下来t1需要locker2,t2需要locker1,这样就陷入了死锁
运行结果显示程序一直没有结束:
1.6.2 如何避免死锁
死锁产生的四个必要条件:
1)锁具有互斥性
2)锁不可抢占:一个线程拿到锁之后,除非它主动释放锁,否则别人抢不走
以上这两点是锁的基本特性,无法干预
3)请求和保持:一个线程拿到一把锁之后,不释放这个锁的前提下,在尝试获取其他锁(嵌套加锁)
解决方法就是不要让两个sychronized嵌套式的占用两个不同的锁对象进行加锁
4)循环等待:多个线程获取多个锁的过程中,出现了循环等待,A等待B,B又等待A
这一点只要我们提前约定好获取锁的顺序,即使出现了嵌套也不会引起死锁,如下述代码t1和t2线程都先获取locker1再获取locker2,这样就不会出现死锁
public static void main(String[] args) throws InterruptedException {Object locker1 = new Object();Object locker2 = new Object();Thread t1 = new Thread(() -> {synchronized(locker1) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2) {System.out.println("t1获取了两把锁");}}});Thread t2 = new Thread(() -> {synchronized(locker1) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2) {System.out.println("t2获取了两把锁");}}});t1.start();t2.start();}
任何一个死锁的场景,都必须同时具备上述四点,缺少一点都不会构成死锁
🙉本篇文章到此结束,下篇文章将继续对线程安全的知识进行讲解
相关文章:
【JavaEE】多线程(2)
一、线程安全 1.1 线程安全的概念 线程是随机调度执行的,如果多线程环境下的程序运行的结果符合我们预期则说明线程安全,反之,如果遇到其他结果甚至引起了bug则说明线程不安全 1.2 经典例子与解释 下面举一个经典的线程不安全的例子&…...
虚拟地址空间与物理内存(Linux系统)
个人主页:敲上瘾-CSDN博客 个人专栏:Linux学习、游戏、数据结构、c语言基础、c学习、算法 目录 问题引入 一、什么是虚拟内存 二、虚拟内存的描述与组织 三、页表的优势 四、虚拟内存区域划分 问题引入 为引入今天的话题,我们先来看下面…...
iOS Arkit机器学习相关
最近在搞追踪运动物体,然后Arkit识别3d模型和图片,静止状态还不错,运动时候效果还是有点差,所以搞了下苹果的CoreML,苹果官网也有一些训练好的模型 苹果模型列表,自己参考或者使用,提供一个数据…...
Maven CMD命令
打包测试命令 在当前文件中 >mvn clean package -D maven.test.skiptrue 基本命令 mvn clean 清理目标目录(target)中的输出文件。 mvn compile 编译主源代码路径(src/main/java)下的 Java 代码。 mvn test-compile 编译测试源…...
DM-VIO(ROS)+t265配置运行记录(ubuntu18.04+ros melodic)
在工作中需要对DM-VIO算法进行测试,于是配置并记录了一下: 首先运行ros接口的dm-vio,一定要先配置源码 https://github.com/lukasvst/dm-vio在这个网址把源码下载下来并解压,并安装一下依赖: sudo apt-get install …...
DETR:一种新颖的端到端目标检测与分割框架
DETR:一种新颖的端到端目标检测与分割框架 摘要: 随着深度学习技术的发展,目标检测和图像分割任务取得了显著的进步。然而,传统的基于区域提名的方法在处理这些问题时存在一定的局限性。为此,Facebook AI Research&am…...
Android 输入事件拦截机制
Keyboard产生按键事件后,会通过notifyKey开始传递: frameworks\native\services\inputflinger\InputDispatcher.cpp void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {...uint32_t policyFlags args->policyFlags;//只关注policyFlags…...
【Figma】中文版安装
一、软件安装包下载 打开官网链接https://www.figma.com/downloads/下载相应安装包 或使用我已下载好的链接: FigmaSetup.exe 链接: https://pan.baidu.com/s/113eQ8JRETdeOwUp2B3uieA?pwd4vep 二、安装流程 1.点击安装包 2.选择在浏览器登录 3.输入账号密码&a…...
SolarCube: 高分辨率太阳辐照预测基准数据集
太阳能作为清洁能源在减缓气候变化中的作用日益凸显,其稳定的供应对电网管理至关重要。然而,太阳辐照受云层和天气变化的影响波动较大,给光伏电力的管理带来挑战,尤其是在调度、储能和备用系统管理方面。因此,精确的太…...
arkTS:持久化储存UI状态的基本用法(PersistentStorage)
arkUI:持久化储存UI状态的基本用法(PersistentStorage) 1 主要内容说明2 例子2.1 持久化储存UI状态的基本用法(PersistentStorage)2.1.1 源码1的相关说明2.1.1.1 数据存储2.1.1.2 数据读取2.1.1.3 动态更新2.1.1.4 显示…...
【Canvas与雷达】点鼠标可暂停金边蓝屏雷达显示屏
【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>点鼠标可暂停金边蓝屏雷达显示屏 Draft1</title><style typ…...
第二部分shell----二、shell 条件测试
一、基本语法 在shell程序中,用户可以使用测试语句来测试指定的条件表达式的条件的真或假。当指定的条件为 真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值。 1.test<测试表…...
node修改文件名称
node修改名称 var fs require(fs); const events require(events); var path require(path);init(); function init() {//要遍历的文件夹所在的路径const dirPath path.resolve(__dirname, "data");//遍历目录fileDisplay(dirPath); }/*** 文件遍历* param dirP…...
Vue教程|搭建vue项目|Vue-CLI新版脚手架
一、安装Node环境 安装Node及Npm环境 Node下载地址:Node.js — Run JavaScript EverywhereNode.js is a JavaScript runtime built on Chromes V8 JavaScript engine.https://nodejs.org/en/ 安装完成后,检查安装是否成功,并检查版本,命令如下: node -v npm -v mac@Macd…...
Java设计模式
Java设计模式 一、观察者设计模式1.1 概述1.2 结构1.3 特点1. 优点2. 缺点3. 使用场景 1.4 JDK中的实现1. Observable 类2. Observer 接口3. 例子 二、模板设计模式三、单例设计模式一、懒汉式单例二、饿汉式单例 四、Builder模式4.1 概述4.2 结构4.3 具体实现4.4 使用场景 一、…...
java 接口防抖
防抖:防止重复提交 在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。要针对用户的误操作,前端通常会实现按钮的l…...
[C++并发编程] 线程基础
线程发起 最简单的发起一个线程。 void thread_work(std::string str) {std::cout << "str: " << std << std::endl; } //初始化并启动一个线程 std::thread t1(thread, wangzn2016); 线程等待: 线程发起后,可能新的线…...
基于若依框架和Vue2 + Element-UI 实现图片上传组件的重写与优化
背景 在使用 若依分离版Element-UI 的图片上传组件时,需要根据业务需求进行定制化处理,比如: 需要传递额外的业务参数到后端需要对上传路径进行修改需要对上传组件进行样式定制 实现步骤 1. 创建本地组件 首先在业务模块下创建本地的图片上传组件: src/views/xxx/compone…...
自定义类型: 结构体、枚举 、联合
目录 结构体 结构体类型的声明 匿名结构体 结构的自引用 结构体变量的定义和初始化 结构体成员变量的访问 结构体内存对齐 结构体传参 位段 位段类型的声明 位段的内存分配 位段的跨平台问题 位段的应用 枚举 枚举类型的定义 枚举的优点 联合体(共用体) 联合…...
力扣98:验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1: 输入…...
Java Stream reduce 函数,聚合数据
Stream.reduce() 是 Stream 的一个聚合方法,它可以把一个 Stream 的所有元素按照自定义聚合逻辑,聚合成一个结果。 先看一个简单数字求和: public class Main {public static void main(String[] args){int sum Stream.of(1, 2…...
npm install -g@vue/cli报错解决:npm error code ENOENT npm error syscall open
这里写目录标题 报错信息1解决方案 报错信息2解决方案 报错信息1 使用npm install -gvue/cli时,发生报错,报错图片如下: 根据报错信息可以知道,缺少package.json文件。 解决方案 缺什么补什么,这里我们使用命令npm…...
阿里云服务器(centos7.6)部署前后端分离项目(MAC环境)
Jdk17安装部署 下载地址:https://www.oracle.com/java/technologies/downloads/ 选择自己需要的jdk版本进行下载。 通过mac终端scp命令上传下载好的jdk17到服务器的/usr/local目录下 scp -r Downloads/jdk-17.0.13_linux-x64_bin.tar.gz 用户名服务器ip地址:/us…...
【机器学习】机器学习基础
什么是机器学习? 机器学习(Machine Learning, ML)是一种人工智能(AI)的分支,指计算机通过数据学习规律并做出预测或决策,而无需明确编程。它的核心目标是让机器能够从经验中学习,逐…...
BUUCTF—Reverse—Java逆向解密(10)
程序员小张不小心弄丢了加密文件用的秘钥,已知还好小张曾经编写了一个秘钥验证算法,聪明的你能帮小张找到秘钥吗? 注意:得到的 flag 请包上 flag{} 提交 需要用专门的Java反编译软件:jd-gui 下载文件,发现是个class文…...
基于JSP+MySQL的网上招聘系统的设计与实现
摘要 在这样一个经济飞速发展的时代,人们的生存与生活问题已成为当代社会需要关注的一个焦点。对于一个刚刚 踏入社会的年轻人来说,他对就业市场和形势了解的不够详细,同时对自己的职业规划也很模糊,这就导致大量的 时间被花费在…...
js 中 file 文件 应用
文章目录 文件上传File 对象基本属性文件上传大文件上传文件格式校验通过 type 属性校验图片格式通过文件名扩展名校验 文件解析一、处理图片文件流(以 Blob 格式接收文件流为例)二、处理文本文件流三、处理 PDF 文件流(借助 PDF.js 库来展示…...
Java 泛型详细解析
泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair,它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以给这个 T 指定任何实际的类型,比如下面所示,就指定了实际类型为 LocalDate…...
「Mac畅玩鸿蒙与硬件33」UI互动应用篇10 - 数字猜谜游戏
本篇将带你实现一个简单的数字猜谜游戏。用户输入一个数字,应用会判断是否接近目标数字,并提供提示“高一点”或“低一点”,直到用户猜中目标数字。这个小游戏结合状态管理和用户交互,是一个入门级的互动应用示例。 关键词 UI互…...
自然语言处理期末试题汇总
建议自己做,写完再来对答案。答案可能存在极小部分错误,不保证一定正确。 一、选择题 1-10、C A D B D B C D A A 11-20、A A A C A B D B B A 21-30、B C C D D A C A C B 31-40、B B B C D A B B A A 41-50、B D B C A B B B B C 51-60、A D D …...
记录Threadlocal使用
编写ThreadLocal工具类 package com.jjking.jplan.context;public class BaseContext<T> {public static final ThreadLocal threadLocal new ThreadLocal();//存储用户public static void set(Object t) {threadLocal.set(t);}//获取用户public static <T> T ge…...
利用 SpringBoot 开发的新冠密接者跟踪系统:医疗机构疫情防控辅助方案
摘 要 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古…...
vue 2 父组件根据注册事件,控制相关按钮显隐
目标效果 我不注册事件,那么就不显示相关的按钮 注册了事件,才会显示相关内容 实现思路 组件在 mounted 的时候可以拿到父组件注册监听的方法 拿到这个就可以做事情了 mounted() {console.log(this.$listeners, this.$listeners);this.show.search !…...
【深度学习基础】一篇入门模型评估指标(分类篇)
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀深度学习_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 模…...
hls视频流学习
hls格式播放的依赖安装: <!-- 新增hls播放库 -->npm install hls.js 组件封装: <template><div class"hls-player-cls"><video ref" video" controls style"width: 100%; max-width: 800px;">…...
【electron-vite】搭建electron+vue3框架基础
一、拉取项目 electron-vite 中文文档地址: https://cn-evite.netlify.app/guide/ 官网网址:https://evite.netlify.app/ 版本 vue版本:vue3 构建工具:vite 框架类型:Electron JS语法:TypeScript &…...
第三方Express 路由和路由中间件
文章目录 1、Express 应用使用回调函数的参数: request 和 response 对象来处理请求和响应的数据。2、Express路由1.路由方法2.路由路径3.路由处理程序 3. 模块化路由4. Express中间件1.中间件简介2.中间件分类3.自定义中间件 1、Express 应用使用回调函数的参数&am…...
WPF 常用的5个布局容器控件介绍
1. Grid Grid 是最常用的布局容器之一,它允许开发者以表格的方式对控件进行组织和布局。Grid 使用行和列来划分区域,可以精确控制控件的位置和大小。 特点: 行列定义:Grid 使用 RowDefinitions 和 ColumnDefinitions 来定义行和…...
【JAVA] 杂谈: java中的拷贝(克隆方法)
这篇文章我们来介绍什么是拷贝,并且实现浅拷贝到深拷贝。 目录 一、浅拷贝 1.1 clone 方法 1.2 实现浅拷贝: 1.2.1 重写 clone方法 1.2.2 实现接口 Cloneable 1.2.3 调用克隆方法 1.2.4 原理图: 1.3 浅拷贝的不足 1.3.1 增加引用…...
同时多平台git配置:GitHub和Gitee生成不同的SSH Key
文章目录 GitHub和Gitee生成不同的SSH Key步骤1:生成SSH Key步骤2:配置SSH配置文件步骤3:查看SSH公钥步骤4:将SSH公钥添加到GitHub和Gitee步骤5:测试SSH连接步骤6:添加remote远程库 GitHub和Gitee生成不同的…...
flink1.6集成doris,并从mysql同步数据到doris
使用 Apache Flink 1.6 集成 Doris,并从 MySQL 同步数据到 Doris 是一个复杂的任务,但可以通过以下步骤实现。Doris 是一个现代化的 MPP(大规模并行处理)SQL 数据库,支持实时分析和交互式查询。Flink 可以作为实时数据…...
手搓一个不用中间件的分表策略
场景:针对一些特别的项目,不用中间件,以月为维度进行分表,代码详细设计方案 1. 定义分片策略 首先,定义一个分片策略类,用于决定数据存储在哪个分表中 import java.time.LocalDate; import java.time.fo…...
AI前景分析展望——GPTo1 SoraAI
引言 人工智能(AI)领域的飞速发展已不仅仅局限于学术研究,它已渗透到各个行业,影响着从生产制造到创意产业的方方面面。在这场技术革新的浪潮中,一些领先的AI模型,像Sora和OpenAI的O1,凭借其强大…...
损失函数Hinge Loss介绍
Hinge Loss 是一种损失函数,广泛用于 支持向量机(SVM, Support Vector Machine) 和一些分类问题中。它特别适合用于 二分类问题,主要目标是让模型的预测值(通常是经过线性变换的原始分数)与真实标签之间的间隔尽可能大,从而提高分类的鲁棒性。 Hinge Loss 的定义 Hinge…...
多维高斯分布(Multivariate Gaussian Distribution)以及协方差矩阵:解析与应用
多维高斯分布:全面解析及其应用 1. 什么是多维高斯分布? 多维高斯分布(Multivariate Gaussian Distribution),也称多元正态分布,是高斯分布在高维空间中的推广。它描述了随机向量 ( x ( x 1 , x 2 , … ,…...
前端开发常用快捷键
浏览器 ctrl e 光标定位在搜索框ctrl r 刷新ctrl t 新打开tabctrl tab 向右切换tabctrl shift tab 向左切换tab vscode ctrl p 全局搜索文件ctrl f 当前文件搜索alt 光标左键向下拖动:竖向选中多行文本ctrl b 切换侧边栏显示隐藏ctrl shift p 显示命…...
用MATLAB符号工具建立机器人的动力学模型
目录 介绍代码功能演示拉格朗日方法回顾求解符号表达式数值求解 介绍 开发机器人过程中经常需要用牛顿-拉格朗日法建立机器人的动力学模型,表示为二阶微分方程组。本文以一个二杆系统为例,介绍如何用MATLAB符号工具得到微分方程表达式,只需要…...
全面解析 MySQL 常见问题的排查与解决方法
目录 前言1. 查看 MySQL 日志信息1.1 日志文件的种类与路径1.2 查看日志内容的方法1.3 日志分析的关键点 2. 查看 MySQL 服务状态2.1 查看服务状态2.2 检查进程运行情况2.3 常见启动失败问题与解决 3. 检查 MySQL 配置信息3.1 配置文件的路径与内容3.2 验证配置文件的正确性 4.…...
泷羽Sec-星河飞雪-BurpSuite之解码、日志、对比模块基础使用
免责声明 学习视频来自 B 站up主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 泷羽sec官网:http…...
【小白学机器学习34】基础统计2种方法:用numpy的方法np().mean()等进行统计,pd.DataFrame.groupby() 分组统计
目录 1 用 numpy 快速求数组的各种统计量:mean, var, std 1.1 数据准备 1.2 直接用np的公式求解 1.3 注意问题 1.4 用print() 输出内容,显示效果 2 为了验证公式的背后的理解,下面是详细的展开公式的求法 2.1 均值mean的详细 2.2 方差…...