从0开始linux(38)——线程(1)线程概念
欢迎来到博主专栏:从0开始linux
博主ID:代码小豪
文章目录
- 进程与线程
- 线程概念
- 线程的优点
- 线程的独立数据
进程与线程
如果要理解线程,那么进程将会时绕不开的点。首先我们回顾一下我们之前在进程章节当中是如何描述进程的?
进程=内核数据结构+代码和数据
代码和数据很好理解,我们在c/c++文件当中写的代码和数据,经过编译后形成的二进制可执行程序中,数据和指令都已二进制的形式保存在文件中。而内核数据结构指的是PCB(task_struct),mm_struct,vm_area_struct(进程地址空间),还有页表等等。这些存在于内核当中,描述与管理进程的相关数据结构。
那么线程是什么呢?
这里博主先从其中一个概念开始展开:线程是进程中的一个执行流,是进程的执行分支。
那么问题来了,什么是执行流呢?
我们可以将流看做是进程中连续的cpu指令,cpu在执行这些指令流,就叫做执行流。而根据进程地址空间,我们的cpu执行的指令、数据的地址,都是保存在进程地址空间当中的,而线程相当于是将这个进程地址空间的一部分切割开来,作为自己的地址空间,让cpu从中处理。那么此时进程就分为了两个执行流,继续执行主程序的,叫做主线程,而执行分支程序的,就是分支线程。
多说无益,我们尝试创建一个线程,创建线程用到的是C语言posix库中的函数pthread_create
,关于这posix库是什么,我们在下一篇章节再说,pthread_create的函数原型如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
这些参数博主先不多介绍,首先start_routine是一个函数指针,即分支线程开始的函数地址(我们可以看成是线程的main函数)。pthread_t是线程号,线程号我们后面再说。我们只需要传入一个pthread_t的参数的地址即可。
那么程序如下:
void* Thread1Run(void* addr)//分支线程的入口函数
{while(true){std::cout<<"hello 我是线程1"<<std::endl;sleep(1);}
}int main()
{pthread_t tid;//创建分支线程pthread_create(&tid,nullptr,Thread1Run,(void*)"thread-1");while(true){std::cout<<"hello 我是主线程"<<std::endl;sleep(1);}return 0;
}
这段程序的逻辑如下:当进程运行时,此时内部没有分支线程,当执行pthread_create后,创建出一个分支线程。该线程执行Thread1Run函数的逻辑。此时进程1内部就出现了两个执行流,主执行流继续执行主函数的代码,而分支线程执行Thread1Run的代码。
运行结果如下:
从这里可以看出,主线程和分支线程是并行的,如果不是并行的,那么主线程压根不会执行pthread_create中的代码。
线程概念
如果线程可以并行,那么一定是需要linux系统对线程进行调度的,就像进程调度那样。那么既然linux要对线程管理起来,linux是如何管理线程的呢?老生常谈,linux管理进程,是通过创建内核数据结构,描述进程,接着通过内核数据结构来进行管理,我们将这个操作称为:先描述,再组织
。
那么线程又要如何描述呢?我们先来思考这么一个问题:我们需要线程有什么?首先,线程要有描述符,这样操作系统才能通过描述符找到要操作的线程;接着,线程要有执行的代码和数据,因此要有自己的地址空间;线程也可以通信、因此还要有文件描述符表fd_array。线程还要能接收到信号,因此要有pending表、block表、handler表。咦,这么看下来线程的内核数据结构好像和进程的内核数据结构一模一样啊?
没错,线程和进程用的内核数据都是一样的,即task_struct!!!!
这么一搞、我们就要对一个问题进行思考了。线程是什么?进程又是什么?
首先博主为进程和线程先下一个定义:线程是操作系统调度的最小单位、进程是承载分配资源的基本实体。
在我们上一个例子中已经看到,cpu会在线程之间进行切换调度,其原理和进程之间的切换调度类似。那么如何理解进程时承载分配资源的基本实体呢?首先我们来思考,一个进程需要什么资源?
首先进程要有地址空间吧,代码、数据、堆区、栈区,这些都是实打实存在于内存当中的,第二个,进程会打开文件吧,这些文件都也是要加载到内存当中的。这些就叫做资源。
那么线程有没有这些呢?答案是有!但是为什么说进程承载资源,而不是线程承载资源呢?这是因为,由线程申请的资源,都是放到进程名下的!如何理解这句话呢?我们在前面不是说了吗?将进程空间的一部分代码、数据分割给分支线程,线程就创建出来了,那么我们逆推一下:进程=主线程+分支线程
!
我们之前所见过的进程,是不是没有线程呢?非也,而是这些进程当中只有一个主线程,因此,我们在前面所说的进程调度,本质上也是线程调度,只是这个线程只存在一个而已。那么现在我们知道了,线程申请的一切资源都是放在进程名下的,这也意味着,线程之间使用的资源都是共享的即,同一进程下的线程使用的地址空间是相同的,使用的文件描述表也是相同的!!那么理解了这个,对于线程和进程的关系就很明了了。
我们可以以现实举个例子,比如我们从寝室走到教室,那么我们这个人就是一个进程,执行的任务就是到达教室,而我们的左脚、右脚、左腿、右腿则是进程下的线程,各自执行自己的程序,但是目的都是为了完成一个进程的任务。这些线程所使用的资源是共享的,即人体身上的能量,你总不能说你的左腿运动和右腿运动消耗的能量不属于同一个人吧?
在linux中,线程和进程其实并没有太大的区别,因此在linux当中,线程被称为轻量级进程,又称LWP(light weight process)。所谓的cpu对进程的调度,无论是进程还是轻量级进程,它们的权重没有任何区别。而且我们还能查到轻量级进程的属性,通过指令:ps -aL
可以查看,但是考虑到让轻量级进程与进程之间有所区别,因此后面还是叫线程和进程。
线程的优点
- 创建⼀个新线程的代价要比创建⼀个新进程小得多
我们fork出一个新进程,由于进程之前具有独立性,因此新进程要有自己的地址空间,要有自己的内核数据结构。而线程之间都是共享进程的资源的,因此创建一个新线程,只需要创建一个新的内核数据结构来描述轻量级进程就行。
- 线程之间切换比进程之间切换的速度快
为什么呢?因为进程之间具有独立性,不同的进程,其代码数据不同,使用的进程地址空间也不同,页表不同,打开的文件也不同,这些东西都是要实打实加载到内存的。要加载,就是要让磁盘与内存之间做慢速I/O,因此速度变慢。
而且在CPU当中也有体现,不同的进程,其上下文也是不一样的,并不是说线程的上下文就相同,而是进程的上下文更复杂。因为在CPU当中存在两个东西,一个叫做TLB,一个叫做cache。这两个硬件都是用来做缓存的。TLB负责的是页表缓存,不同的进程拥有不同的页表,因此TLB肯定不能复用,因此切换进程的时候,TLB要重新作缓存,而线程之间由于使用的是相同的进程空间,因此在切换线程的时候,TLB就不用更新。
而cache我们还没认识过,现在我们就来讲讲。当一个进程运行时,我们要将进程中的数据和代码加载到内存当中,因为cpu与内存之间做交互的速度远快于cpu与磁盘做交互,但是cpu和内存之间的交互是最快的吗?当然不是,而是cpu与cache之间的交互才是最快的,因此,当cpu执行一个代码时,会将代码附近的所有数据都加载到cache当中,我们可以输入指令cat /proc/cpuinfo
可以查看到cpu信息,其中就包括cache的大小
我们可以看到,一个cached可以缓存40M左右的数据,因此当cpu执行一个指令时,首先会查该指令的地址是否在cache当中,如果没有,再去内存当中找,顺便在将cache当中缓存的数据更新成,新执行的指令附近40M的数据。
那么为什么说cache能提高效率呢?这其实是一个概率性的问题,因为当计算机执行完一个代码后,其第二条代码,大概率在该代码的下一条。因此将代码附近的数据加载到cache中,可以大大减少cpu访问内存的次数。但是如果你能写出让cpu访问的代码不停跳转的程序,那么这个cache就相当于是负优化了,因为cache不仅没有让你减少cpu访问内存的频率,还要不停地加载内存中的数据到cache当中,这个时间只会更长。因此,这个基于cache缓存以提高cpu效率的方法,我们称为局部性原理。因此我们所写的代码和数据,要尽可能的减少不必要的跳转,以提升程序的运行速度。
那么我们回到进程,由于进程使用的内存空间是不同的,因此cache缓存的数据,是基本不可能让两个进程一起用的。因此切换进程的时候,cache当中的数据也要更新一下,这不也导致了cpu效率变慢了吗?而线程之间由于使用的资源都是在一个进程当中的,因此cache缓存大概率不用更新,因此切换线程所需要的时间开销也会变小。
但是线程并非完全没有缺点。
• 性能损失
◦ ⼀个很少被外部事件阻塞的计算密集型线程往往⽆法与其它线程共享同⼀个处理器。如果计
算密集型线程的数量⽐可⽤的处理器多,那么可能会有较⼤的性能损失,这⾥的性能损失指
的是增加了额外的同步和调度开销,⽽可⽤的资源不变。
• 健壮性降低
◦ 编写多线程需要更全⾯更深⼊的考虑,在⼀个多线程程序⾥,因时间分配上的细微偏差或者
因共享了不该共享的变量⽽造成不良影响的可能性是很⼤的,换句话说线程之间是缺乏保护
的。
• 缺乏访问控制
◦ 进程是访问控制的基本粒度,在⼀个线程中调⽤某些OS函数会对整个进程造成影响。
这里我们做简单的了解,博主在后面的章节当中还会继续说明
线程的独立数据
进程当中有哪些资源是线程之间共享的?而线程之间又有什么资源是不互通的?
共享的资源有:
- 进程地址空间
- 信号:所有线程对于信号的处理方式,都是一致的
- 异常:如果一个线程出现了异常,那么整个进程都会崩溃
其实这也很好理解,比如广西周某偷了电瓶,总不能说是我的手偷的,而不是总体偷的,进而免除惩罚吧?由于线程作为进程的一部分,所有的线程的目的,都是为了让进程完成某个任务,因此如果一个线程出现了异常,那么进程的任务还能完成吗?因此将进程中所有线程一起处理,才是正确的处理方法。 - 文件描述符
不共享的资源有:
- LWP:线程ID
- 信号屏蔽字:即block表,虽然线程之间对待信号的处理方法一致,但是线程可以选择屏蔽掉啊
- 线程的上下文数据:虽然使用的资源是相同的,但是它们具体执行的指令可不同,因此cpu在切换线程时,它们的上下文数据也要进行切换(只是切换线程的复杂度远低于切换进程。)
- 栈
- errno
- 调度优先级
相关文章:
从0开始linux(38)——线程(1)线程概念
欢迎来到博主专栏:从0开始linux 博主ID:代码小豪 文章目录 进程与线程线程概念线程的优点线程的独立数据 进程与线程 如果要理解线程,那么进程将会时绕不开的点。首先我们回顾一下我们之前在进程章节当中是如何描述进程的? 进程&…...
【Linux系统编程】:进程池(简易版)
目录 1.制作游戏菜单 2.对管道进行描述和组织 3.初始化管道 3.1子进程执行任务slaver() 3.2检查管道是否创建有误 4.父进程向管道写入(控制子进程执行任务) 5.清理资源 修改初始化管道代码 6.完整代码: 1.制作游戏菜单 我们利用管道…...
uniapp实现小程序的版本更新
参考官方文档:uni.getUpdateManager() | uni-app官网 uni.getUpdateManager()是uniapp框架提供的一个API,用于管理小程序的版本更新。这个API返回一个全局唯一的版本更新管理器对象,该对象可以用于检测新版本、下载新版本以及提示用户重启应…...
嵌入式QT学习第4天:Qt 信号与槽
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章思维导图如下: 不使用 Qt Designer 的方式进行开发,用代码绘界面,可以锻炼我们的布局能力,和代码逻辑能力&#x…...
`asyncio.wait` 和 `asyncio.gather` 的区别
asyncio.wait 和 asyncio.gather 的区别 1. asyncio.wait2. asyncio.gather主要区别总结 在Python的异步编程中,asyncio.wait 和 asyncio.gather 都是用于等待多个异步任务完成的工具,但它们在功能和使用方式上有一些关键的区别。本文将详细解释这两个函…...
【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 , … ,…...