Linux进程详细解析
1.操作系统
概念
任何计算机系统都包含⼀个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
• 内核(进程管理,内存管理,文件管理,驱动管理)
• 其他程序(例如函数库,shell程序等等)
设计操作系统的目的
• 对下,与硬件交互,管理所有的软硬件资源
• 对上,为用户程序(应用程序)提供⼀个良好的执行环境
核心功能
- 进程管理:负责进程的创建、调度、同步、通信及销毁,合理分配 CPU 资源,确保多任务环境下各进程高效运行,提升系统整体效率。
- 内存管理:动态分配与回收内存空间,通过虚拟内存技术扩展内存能力,保障进程间地址空间相互独立,避免干扰,提高内存利用率。
- 文件系统管理:对文件的创建、删除、读写、权限控制等进行组织与管理,确保数据存储的安全性、一致性,方便用户及应用程序对文件的操作与访问。
- 驱动管理:协调与控制外部设备(如输入 / 输出设备、存储设备等),实现设备驱动程序的加载与运行,保障设备与系统的兼容性,提升设备使用效率。
如何理解"管理"
操作系统是怎么管理内部的文件呢?是直接管理资源还是通过一系列的接口来管理资源呢?
资源就像学生一样,学生有着年龄,专业,性别等等的属性,系统内的文件也有着许多属性,如大小,所在路径等等。
在学校里面,我们一般一整个学期都见不到几次校长,所以对于我们来说,是辅导员在直接管理我们,而不是校长直接管理我们。所以管理者和被管理者之间可以不同见面
那校长是怎么间接管理我们的呢?校长可以通过辅导员来获取学生的数据来管理我们,并不用平时亲自管理学生。所以管理者和被管理者可以通过数据进行管理,由于是通过辅导员来获取数据,所以可以由中间层来获取数据
学生的数据就如同数据结构中结点的数据一样。可以将学生的数据输入计算机的链表当中,将日常与学生的管理工作转化为对计算机中链表的管理工作
那么在计算机中,我们可以这样子来解释操作系统的管理过程,操作系统对数据进行建模,转化成数据结构,管理就变成了对数据结构的管理。
所以操作系统的管理重点是:先描述,再组织
总结:计算机管理硬件
1. 描述起来,用struct结构体
2. 组织起来,用链表或其他高效的数据结构
系统调用和库函数概念
• 在开发角度,操作系统对外会表现为⼀个整体,但是会暴露自己的部分接口,供上层开发使用, 这部分由操作系统提供的接口,叫做系统调用。
• 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部 分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行而次开 发。
那么我们为什么需要系统调用呢?
我们可以通过银行的管理模式来解释系统调用,我们在存钱取钱的时候,我们并不是我们自己进入银行金库中自己存钱取钱的,而是通过银行的窗口与工作人员进行交流再进行相应的操作,为什么需要与工作人员进行交流呢,因为银行不相信其他人,只能通过工作人员进行存钱取钱操作,害怕其他人做出出格的事情
系统调用也是如此,操作系统就是银行,系统调用就是工作人员,而我们就是其他人,操作系统不相信我们,我们无法直接与底层资源进行互动,害怕我们操作失误损坏数据,只能允许我们通过系统调用与底层资源进行互动
进程
基本概念与基本操作
• 课本概念:程序的⼀个执行实例,正在执行的程序等
• 内核观点:担当分配系统资源(CPU时间,内存)的实体。
描述进程-PCB
基本概念
• 进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
• 课本上称之为PCB(process control block),Linux操作系统下的PCB是:task_struct 。task_struct-PCB的⼀种
• 在Linux中描述进程的结构体叫做task_struct。
• task_struct是Linux内核的⼀种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
•进程=PCB+自己的代码和数据
进程的大致结构
struct xxx
{int a;int b;......struct xxx* next;struct mm_struct * node;
}
task_struct的数据结构就类似上面那段代码,只不过struct里面存放的是更加详细的进程信息,然后task_struct通过next指针链接起来形成一个链表。
那么怎么查找正在运行的代码和数据呢?task_struct中存在一个结构体指针struct mm_struct *,如同上面的那段代码相似,然后可以通过node指针找到正在运行的代码和数据。
所以进程的所有信息都可以通过task_struct间接或直接找到,所以对进程的管理就变成了对链表的增删查改
组织进程
可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里
查看进程
我们可以通过ls /proc来查看此时正在运行的进程。
这些数字就是进程号
通过系统调用获取进程标示符
• 进程id(PID)
• 父进程id(PPID)
我们可以通过两个函数来查看pid和ppid,分别是getpid()和getppid()。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{printf("pid: %d\n", getpid());printf("ppid: %d\n", getppid());return 0;
}
当我们运行上面那段代码后就会显示出我们的进程号和父进程号
此时我们可能会疑惑,为什么我们的代码为什么还会有父进程,代码并不是通过其他代码来调用的,我们来查看父进程的具体信息
我们可以看出父进程是bash开始运行的,bash就是我们的命令行
我们输入的命令实际上都是以字符串的形式给bash,前面的那段字符是bash打印出来的。后面的绿色光标就是bash等待我们的scanf,所以就停下来了
我们可以通过ll -1 /proc/进程号来查看进程的exe和cwd
我们可x以看到文件后面跟着一串路径,其中cwd是记录文件的所在路径,exe就是文件的实际路径
那这个cwd有什么作用呢?在使用c语言的fopen时不带路径只带文件名,就会在当前目录下自动创建文件,但是这是怎么判断当前目录的,这是由于进程启动时,cwd就会自动记录当前所在路径,程序会读取cwd路径来创建文件
但是我们可以通过一些代码来改变cwd
chdir("/root/a");
此时我们的cwd就会被修改成/root/a
创建子进程
初始fork
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{int ret = fork();if(ret < 0){perror("fork");return 1;}else if(ret == 0){ //childprintf("I am child : %d!, ret: %d\n", getpid(), ret);}else{ //fatherprintf("I am father : %d!, ret: %d\n", getpid(), ret);}sleep(1);return 0;
}
我们可以通过这段代码来帮助我们了解fork函数和子进程,代码的运行结果如下
这时候可能会疑惑,fork为什么会有两个返回值? 两个返回值各种给父子如何返回? ⼀个变量怎么能让 if 和 else if 同时成立这个问题
fork函数存在两个返回值的原因是因为fork会跟据父进程和子进程返回不同的结果,fork会给父进程返回子进程的pid,会给子进程返回0
为什么会出现不同的返回值呢:由于父进程:子进程=1:n,一个父进程可以有多个子进程,父进程需要通过不同的pid来区分不同的子进程,子进程不需要获取父进程的pid,本身就可以通过getppid来返回父进程的pid
那为什么fork会返回两次呢:我们可能会陷入一个误区,fork函数不仅会创建子进程,父进程也会运行fork函数,在fork函数内部,可能运行到一半的代码时,子进程可能已经被创建好甚至被调度了,所以在最后return语句时,不仅子进程会返回数据,父进程也会返回数据。
那为什么会输出两行内容呢,因为子进程被创建出来之后没有自己的代码和数据,只会自动执行父进程的代码,从子进程被创建出来的地方开始运行。
ret的值不同的原因涉及到了写时拷贝,在子进程创建出来的时候,子进程没有自己的代码和数据,所以它只会执行父进程的数据,所以子进程会指向父进程的代码和数据,此时子进程和父进程就指向了相同的内容,如果遇到修改数据的情况呢?此时系统就会为修改数据的进程重新开辟一个新的空间,将原先的代码和数据拷贝过去,这就是写时拷贝。
进程状态
操作系统对硬件的管理
操作系统如何对硬件资源做管理,先描述,再组织。先创建结构体,将对应硬件资源的数据填写完善,将对硬件资源的管理转化成对链表的管理
操作系统的基础状态
操作系统中存在着三种基础状态:运行,阻塞和挂起。
运行状态:只要进程在调度队列中
阻塞状态:等待某种设备或资源就绪,就像C++的cin等待输入一样,此时进程仍在内存中
挂起状态:进程被暂时停止执行,资源使用被限制或部分释放,可能由用户或系统强制触发
为什么会形成阻塞:当进程未等待到某种设备就绪的时候,操作系统会将进程从运行队列上拿取下来,然后将进程的pcb链入到等待输入的设备的等待队列中,不在运行队列里,就永远不会被调度,就形成了阻塞状态,在等待设备就绪过程中,进程并不能够知道设备时候就绪,而操作系统作为硬件资源的管理者,它能够第一时间反应设备状态发生改变,然后更改设备状态,并且检查设备的等待对列,如果不为空,将等待队列的状态设为运行,并重新将进程链入运行队列中
当计算机内存资源不足的时候,设备链表上不会被调度的进程交换到磁盘上,只有PCB没有代码和数据的进程叫做阻塞挂起
操作系统内部数据结构
为什么操作系统内部会存在多个数据结构,而数据的空间只有一份,那么操作系统是怎么解决的?
操作系统中存在多个类似代码的数据结构
struct list_head
{struct list_head *next *prev;
};
将他放入task_struct中
struct task_struct
{.......struct list_head link;.......
};
link的next和prev不会指向下一个或后一个的task_struct,而是指向下一个或后一个task_struct的link中的next或prev。
但是指向link的话我们如何去访问task_struct中的内容呢:我们可以通过类似下面代码的方式获取link的偏移量,通过将0强转成task_struct类型并访问其中的links,就可以知道结点的起始地址与links地址之间的偏移量,此时我们就可以访问结点中的任何信息了
list-&((struct task_struct*)0->link)
此时task_struct之间遍可以通过类似下图的形式将单个数据装换成多个数据结构 ,在同一个结点内可以有多个links,可以将结点通过links形成不同的数据结构,这就是为什么操作系统中存在一个结点可以被同时放在硬件的链表和运行队列中
Linux内核源代码状态
static const char *const task_state_array[] = {"R (running)", /*0 */"S (sleeping)", /*1 */"D (disk sleep)", /*2 */"T (stopped)", /*4 */"t (tracing stop)", /*8 */"X (dead)", /*16 */"Z (zombie)", /*32 */
};
在这里我们可以看到,在源代码中,进程状态用类似宏定义的整数表示。
• R运行状态(running):并不意味着进程⼀定在运行中,它表明进程要么是在运行中要么在运行 队列⾥。
• S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠 (interruptible sleep))。
• D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个 状态的进程通常会等待IO的结束。
• T停止状态(stopped): 可以通过发送SIGSTOP信号给进程来停止(T)进程。这个被暂停的 进程可以通过发送SIGCONT信号让进程继续运行。
• X死亡状态(dead):这个状态只是⼀个返回状态,你不会在任务列表里看到这个状态。
•Z僵尸状态(zombie):子进程等待父进程回收
这里我们可以着重了解D,T,Z三种状态
D状态:当进程向磁盘中写入数据,在写入数据的过程中,进程会在原地等待磁盘返回写入结果,但是如果在等待过程中,系统资源严重不足的话,操作系统会直接将进程杀掉,但是在杀掉进程之后,磁盘写入失败想要告诉进程,但是进程不见了,磁盘只能将写入的资源丢失,丢失资源用户不知道,容易造成严重后果,后面设计出D状态给等待磁盘返回结果的进程,表示操作系统不能直接杀掉D状态进程
T:我们可能不理解在什么情况下进程是停止状态,当我们在使用cgdb的断点在停止代码运行时,此时通过查看进程状态,能够发现进程状态为T
Z僵尸状态:我们创建子进程的目的是为了帮助父进程完成某些东西,一旦子进程运行完成后,父进程就得知道子进程的运行结果如何,但是如果父进程一直不回收信息,那么子进程就会一直存在,此时子进程的状态就是僵尸状态,这种状态会导致内存泄漏的问题。
但是如果父进程退出后子进程仍未退出,此时子进程的父进程就会变成1号进程,那么1号进程是什么东西,我们可以把它看成操作系统本身,为什么要领养:如果不被领养,子进程就会进入僵尸状态,从而造成内存泄漏无法解决,需要通过系统来解决问题,但是被1号进程接管后。子进程就会变成后台进程
进程优先级
基本概念
• cpu资源分配的先后顺序,就是指进程的优先权(priority)。
• 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性 能。
• 还可以把进程运行到指定的CPU上,这样⼀来,把不重要的进程安排到某个CPU,可以大改善 系统整体性能。
• 优先级是一种数字,值越低,优先级越高,反之越低
查看系统进程
我们可以使用ps -l命令显示当前系统中运行的进程信息
我们很容易注意到其中的几个重要信息,有下:
• UID:代表执行者的身份,在系统中并非通过用户名字来识别的拥有者,而是通过id来识别的,使用ls -ln即可查看用户对应的id
所以我们可以了解一下系统怎么知道我们访问文件的时候,是拥有者,所属组还是other?
用命令访问文件本质进程访问文件,进程在启动的时候会记录启动者的id,然后与文件的拥有者,所属组做对比,判断启动者的权限有哪些
• PID:代表这个进程的代号
• PPID:代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
• PRI:代表这个进程可被执行的优先级,其值越小越早被执行
• NI:代表这个进程的nice值
PRI and NI
• PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此 值越小进程的优先级别越高
• 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
• PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=80(默认优先级)+nice。
• 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快 被执行
• 所以,调整进程优先级,在Linux下,就是调整进程nice值
• nice其取值范围是-20到19,⼀共40个级别。为了保证公平,nice才会存在一定的范围,变化的幅度不会太大,所以优先级的范围在[60,99]
• PRI的默认值为80。
查看进程优先级的命令
可以通过top,nice,renice等命令来修改
概念-竞争、独立、并行、并发
• 竞争性:系统进程数目众多,而CPU资源只有少量,甚至只有1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
• 独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰
• 并行:多个进程在多个CPU下分别,同时进行运行,这称之为并行
• 并发:多个进程在⼀个CPU下采用进程切换的方式,在⼀段时间之内,让多个进程都得以推进,称 之为并发
进程切换
CPU上下文切换:
其实际含义是任务切换,或者CPU寄存器切换。当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态,也就是CPU寄存器中的全部内容。这些内容被保存在任务自己的堆栈中,入栈工作完成后就把下⼀个将要运行的任务的当前状况从该任务的栈中重新装入CPU寄存器,并开始下⼀个任务的运行,这⼀过程就是context switch。
1.寄存器
寄存器就是cpu内部的临时空间
寄存器是一份空间,而寄存器内的数据只是内容,可以随时替换,所以寄存器!=寄存器里面的数据
2.切换进程时的文件去哪了
task_struct中还存在着一个结构体TSS,文件会保存到TSS中
Linux2.6内核进程O(1)调度队列
我们通过这张图片来了解一下进程切换的大致内容
图片中存在队列:queue[140],他表示着140个优先级,其中0-99是实时优先级,100-139才是我们可以操作的优先级,在相应的优先级后面,queue[优先级]会存放着我们将要运行的进程,queue可以理解为一个hash表。
我们可以看到图片中有存在相同的变量我们可以将它理解为一个结构体数组array,分为array[0]和array[1],array[0]是活跃进程,array[1]是过期进程。图片中有两个指针,active指向array[0],expired指向array[1]。
bitmap[5]是通过位图操作来减少queue查找进程的时间复杂度,可以迅速的查找1的位置来锁定接下来要运行的进程,为什么大小是5呢?原因很简单,4过小,5过大。
现在有几个问题
1.遇到死循环进程的话后面的进程还会运行吗?
我们的操作系统采用的是分时操作系统,当死循环程序的时间片用完之后,操作系统就会将死循环进程从active中抓取出来,放到expired中
2.expired中的程序什么时候才会运行?
expired中的进程一般是刚开始的进程和过期进程,只有等待active里面的进程运行完成后,swap(active,expired),然后运行进程
3当我们新来一个进程后,是要放在expired中,与过期进程存放在一起?
这就是进程的就绪状态,但是随着硬件的更新,出来了内核优先级抢占问题,它能够直接将新进程直接插入到active中。
相关文章:
Linux进程详细解析
1.操作系统 概念 任何计算机系统都包含⼀个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括: • 内核(进程管理,内存管理,文件管理,驱动管理) • 其他程序(…...
Linux执行脚本报错
执行脚本报错:./startup.sh -bash: ./startup.sh: /bin/bash^M: bad interpreter: No such file or directory ./startup.sh -bash: ./startup.sh: /bin/bash^M: bad interpreter: No such file or directory可能的原因: 文件开头格式问题:…...
C++学习:六个月从基础到就业——模板编程:类模板
C学习:六个月从基础到就业——模板编程:类模板 本文是我C学习之旅系列的第三十三篇技术文章,也是第二阶段"C进阶特性"的第十一篇,主要介绍C中的类模板编程。查看完整系列目录了解更多内容。 目录 引言类模板的基本语法…...
Conda 虚拟环境复用
文章目录 一、导出环境配置二、克隆环境配置三、区别小结 一、导出环境配置 导出:将当前虚拟环境导出成一个yml配置文件。conda activate your_env conda env export > your_env.yml导入:基于yml文件创建新环境,会自动按照yml里的配置&am…...
Nacos简介—4.Nacos架构和原理三
大纲 1.Nacos的定位和优势 2.Nacos的整体架构 3.Nacos的配置模型 4.Nacos内核设计之一致性协议 5.Nacos内核设计之自研Distro协议 6.Nacos内核设计之通信通道 7.Nacos内核设计之寻址机制 8.服务注册发现模块的注册中心的设计原理 9.服务注册发现模块的注册中心的服务数…...
4月27日日记
现在想来,可以想到什么就记录下来,这也是网上写日记的一个好处,然后 今天英语课上看到一个有关迷信的视频,就是老师课件里的,感觉画风很不错,但是我贫瘠的语言形容不出来,就想到是不是世界上的…...
CentOS7.9安装OpenSSL 1.1.1t和OpenSSH9.9p1
一、临时开启telnet登录方式,避免升级失败无法登录系统 (注意telnet登录方式存在安全隐患,升级openssh相关服务后要记得关闭) 1.安装telnet服务 yum -y install xinetd telnet* 2.允许root用户通过telnet登陆,编辑…...
单例模式:全局唯一性在软件设计中的艺术实践
引言 在软件架构设计中,单例模式(Singleton Pattern)以其独特的实例控制能力,成为解决资源复用与全局访问矛盾的经典方案。该模式通过私有化构造方法、静态实例存储与全局访问接口三大核心机制,确保系统中特定类仅存在…...
Spring 与 ActiveMQ 的深度集成实践(三)
五、实战案例分析 5.1 案例背景与需求 假设我们正在开发一个电商系统,其中订单模块和库存模块是两个独立的子系统 。当用户下单后,订单模块需要通知库存模块进行库存扣减操作 。在传统的同步调用方式下,订单模块需要等待库存模块完成扣减操…...
30-算法打卡-字符串-重复的子字符串-leetcode(459)-第三十天
1 题目地址 459. 重复的子字符串 - 力扣(LeetCode)459. 重复的子字符串 - 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。 示例 1:输入: s "abab"输出: true解释: 可由子串 "ab" 重复两次构成…...
rocketmq一些异常记录
rocketmq一些异常记录 Product 设置不重复发送 发送 一次失败,不会在被发送到mq消息队列中,相当于消息丢失。 2、 Consumer 消费失败 重试三次消费 都失败 则消息消费失败,失败后 会放入 死信队列,可以手动处理在mq面板 处理死信队…...
SQLMesh 测试自动化:提升数据工程效率
在现代数据工程中,确保数据模型的准确性和可靠性至关重要。SQLMesh 提供了一套强大的测试工具,用于验证数据模型的输出是否符合预期。本文将深入探讨 SQLMesh 的测试功能,包括如何创建测试、支持的数据格式以及如何运行和调试测试。 SQLMesh …...
WPF使用SQLite与JSON文本文件结合存储体侧平衡数据的设计与实现
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
关系型数据库PostgreSQL vs MySQL 深度对比:专业术语+白话解析+实战案例
PostgreSQL 与 MySQL 的详细对比 PostgreSQL 和 MySQL 是两种最流行的开源关系型数据库,它们在设计理念、功能特性和适用场景上有显著差异。以下是它们的详细对比: 一、基本架构与设计理念 PostgreSQL:多进程架构,使用共享内存通…...
利用 SSRF 和 Redis 渗透
环境搭建 在本次实验中,我们使用 Docker 环境进行测试。 解压实验包,搭建 docker 环境。 docker环境 web的dockerfile 主要利用代码 : redis服务器 通过 docker-compose up -d 启动相关容器,初次启动失败。 发现 docker 版本问…...
脏读、幻读、可重复读
脏读 定义:一个事务读取了另一个事务尚未提交的数据 。比如事务 A 修改了某条数据但还没提交,此时事务 B 读取了这条被修改但未提交的数据。若事务 A 后续回滚,事务 B 读到的数据就是无效的,相当于读到了 “脏数据”。危害&#…...
第1讲、#PyTorch教学环境搭建与Tensor基础操作详解
引言 PyTorch是当前深度学习领域最流行的框架之一,因其动态计算图和直观的API而备受开发者青睐。本文将从零开始介绍PyTorch的环境搭建与基础操作,适合各种平台的用户和深度学习初学者。 1. 安装和环境搭建 macOS (Apple Silicon) 对于Mac M1/M2/M3用…...
【创新实训个人博客】数据库搭建
1.原因 为了降低模型使用以前训练的数据或者幻觉知识,我们在对话时需要提供相关内容的数据,同时由于需要最新的广告实时数据,实时爬取和版权问题。数据由团队在网上爬取,为了广告内容的有效性,如果长期使用࿰…...
《代码整洁之道》第6章 对象和数据结构 - 笔记
数据抽象 (Data Abstraction) 这个小节主要讲的是**面向对象编程(OOP)**的一种核心思想:对象应该隐藏它的内部数据,只暴露可以操作这些数据的“行为”(也就是方法/函数)。 大白话: 你创建一个…...
Python判断字符串中是否包含特殊字符
在 Python 中,判断一个字符串是否包含特殊字符可以通过多种方法实现。常见的特殊字符包括空格、感叹号、单引号、括号、星号、加号、逗号、斜杠、冒号、分号、等号、问号、 符号、方括号、花括号和 & 符号等。 为了判断字符串中是否包含这些特殊字符࿰…...
disruptor-spring-boot-start版本优化升级
文章目录 1.前言2.升级内容3.依赖4.总结 1.前言 由于之前写了一篇《disruptor-spring-boot-start生产实践导致pod节点CPU爆表100%的问题解决说明》的文章,里面说本地启动没有啥问题,后面我启动之前写的那个测试的controller发现,本地电脑的CP…...
复杂背景下无人机影像小目标检测:MPE-YOLO抗遮挡与抗背景干扰设计
目录 一、引言 二、挑战和贡献 密集小目标和遮挡 实时性要求与精度权衡 复杂背景 三、MPE-YOLO模型细节 多级特征集成器(MFI) 感知增强卷积(PEC) 增强范围C2f模块(ES-C2f) 四、Coovally AI模型训…...
项目实战 -- 状态管理
redux基础 还记得好久好久之前就想要实现的一个功能吗? 收起侧边栏折叠菜单,没错,现在才实现 因为不是父子通信,所以处理起来相对麻烦一点 可以使用状态树或者中间人模式 这就需要会redux了 Redux工作流: 异步就…...
基于单片机的智能药盒系统
标题:基于单片机的智能药盒系统 内容:1.摘要 本文聚焦于基于单片机的智能药盒系统。背景方面,随着人口老龄化加剧,老年人按时准确服药问题愈发凸显,同时现代快节奏生活也使人们容易遗忘服药时间。目的是设计并实现一个能帮助人们按时、按量服…...
【PyCharm- Python- ArcGIS】:安装一个和 ArcGIS 不冲突的独立 Python让PyCharm 使用 (解决全过程记录)
之前电脑上安装了anaconda3,python3和arcgis10.2.其中anaconda3带有python3,arcgis10.2自带python2.7。arcgis不能正常使用,之前为了使用arcgis,因此卸载了anaconda3和python3,PyCharm不能正常使用了 之前安装的卸载后…...
【C语言干货】回调函数
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、回调函数 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、回调函数 在 C 语言中,当你有一个函数并希望将其作…...
Redis使用总结
NoSQL 1.1为什么要用NoSQL 面对现在用户数据的急剧上升,我们需要对这些用户数据进行挖掘,传统的关系型数据库已经不适合这些 应用了.Nosql 的发展可以很了的处理这些大的数据. 1.2什么是NoSQL Not Only Sql->NoSQL(不仅仅是SQL) 非关系型数据库.随…...
现场问题排查-postgresql某表索引损坏导致指定数据无法更新影响卷宗材料上传
问题现象 今天突然被拉进一个群,说某地区友商推送编目结果报错,在我们自己的卷宗系统上传材料也一直转圈,也删除不了案件卷宗,重置模板也没用,只有个别案件有问题。虽然这事儿不属于我负责,但还是抽时间给…...
数字化转型的未来趋势:从工具到生态,聚焦生态合作、绿色转型与全球化布局
摘要 本文将深入探讨了数字化转型的演进路径,特别是从依赖单一数字化工具向构建和参与复杂商业生态系统的战略转变。分析表明,这一转变不仅是技术升级,更是商业模式、运营逻辑和价值创造方式的根本性变革。云计算、人工智能和大数据分析等 f…...
记录学习记录学习《手动学习深度学习》这本书的笔记(九)
马不停蹄地来到了第十二章:计算性能…… 感觉应该是讲并行计算方面的,比如GPU、CPU、CUDA那些。 第十二章:计算性能 12.1 编译器和解释器 这里先提出了命令式编程和符号式编程的概念。 命令式编程VS符号式编程 目前为止,本书…...
麒麟系统通过 Service 启动 JAR 包的完整指南
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...
【记录maven依赖规则-dependencyManagement,dependencies】
记录maven依赖规则-dependencyManagement,dependencies 依赖方式 直接依赖 间接依赖 依赖关系 直接依赖: 父级管理定义的版本,并且在中进行引用了的版本。 优先使用dependencyManagement定义的版本。 间接依赖: 如果间接依赖…...
macos下mysql 5.7/8.0版本切换
1、首先安装好mysql 5.7/8.0,可以用brew进行安装 5.7 的原始配置文件路径: /usr/local/Cellar/mysql5.7/5.7.44_1/homebrew.mxcl.mysql5.7.plist 配置内容如下: 对应的.cnf配置文件内容如下: 8.0 的原始配置文件路径࿱…...
FPGA时钟设计
实现功能:基于Verilog的动态显示时钟设计,支持整点(时:00:00)闪烁功能。代码包含时钟计数、动态扫描、整点检测和闪烁控制模块: module dynamic_clock(input clk, // 主时钟(假设50MHz࿰…...
【NVM】管理不同版本的node.js
目录 一、下载nvm 二、安装nvm 三、验证安装 四、配置下载镜像 五、使用NVM 前言:不同的node.js版本会让你在使用过程很费劲,nvm是一个node版本管理工具,通过它可以安装多种node版本并且可以快速、简单的切换node版本。 一、下载nvm htt…...
【今日三题】笨小猴(模拟) / 主持人调度(排序) / 分割等和子集(01背包)
⭐️个人主页:小羊 ⭐️所属专栏:每日两三题 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 笨小猴(模拟)主持人调度(排序)分割等和子集(01背包) 笨小猴(模拟) 笨小猴 #include <iostream> #include <string…...
android10 卸载应用出现回退栈异常问题
打开设置,打开APP1,使用adb uninstall 卸载APP1/或者杀掉APP1进程,没有回到设置而是回到了桌面 抓取eventlog,查看ams/wms打印,发现“am_focused_stack: appDied leftTaskHistoryEmpty”源码中搜索“leftTaskHistoryE…...
位置差在坐标系间的相互转换
1 NED转经纬高 (n 系下的北向、东向和垂向位置差异(单位 m)转化为纬度、经度和高程分量的差异) 2 基站坐标转换 纬度、经度、高程 到 ECEF %纬度、经度、高程 到 ECEF clc; clear; glvs; addpath(genpath(E:\GNSSINS\ACES)…...
在线重定义——分区表改造
在数据库管理过程中,随着数据量的不断增长,普通表的查询、维护成本不断上升。为了提升查询性能和管理效率,通常需要将大表进行分区处理。 本文介绍如何使用 Oracle 在线重定义(DBMS_REDEFINITION) 的方式对现有大表进行…...
day51—二分法—x 的平方根(LeetCode-69)
题目描述 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。 示例 …...
网络安全漏洞现状与风险管理分析
在当今数字化时代,网络安全已成为企业和组织不可忽视的核心问题。网络环境的日益复杂和攻击手段的不断升级,使得漏洞管理成为网络安全战略中的关键环节。下面将详细分析当前网络安全领域的漏洞现状及有效的风险管理策略。 当前网络安全面临的挑战 高危漏…...
二、Web服务常用的I/O操作
一、单个或者批量上传文件 前端: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>文件…...
Pinia——Vue的Store状态管理库
一、Store 是什么? Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有三个概念,state、getter 和…...
生成式人工智能认证(GAI认证)适合那些人考?
在人工智能浪潮席卷全球的今天,你是否曾思考过:当机器开始创作诗歌、设计建筑、撰写代码,甚至模拟人类思维时,我们该如何与这个“新物种”共处?更关键的是,当生成式人工智能(Generative AI)从实验室走向千行百业,谁将成为驾驭这场技术革命的“领航者”?答案或许藏在一…...
使用cmd来创建数据库和数据库表-简洁步骤
创建数据库和表: 1. 按WinR打开“运行”,输入cmd,回车 2. 登录数据库:mysql -u root -p 然后输入密码 3. 创建数据库create database myblog; myblog为数据库名(自定义你的数据库名) !注意分号不要漏了! …...
微博安卓版话题热度推荐算法与内容真实性分析
微博是目前最受欢迎的社交平台之一,它的推荐算法在推动话题热度和内容传播方面发挥着重要作用。然而,这一算法也引发了对于内容真实性的担忧。本文将通过分析微博安卓版的推荐机制,探讨其对话题热度的影响以及内容真实性问题。 微博的推荐算法…...
助力产业升级 | BMC安全启动方案上新了!
近日,OurBMC 社区联合其理事成员单位中移(苏州)软件技术有限公司,在产业化落地SIG发布计算机系统安全可信创新解决方案——《 BMC 安全启动方案》。该方案为开发者提供了清晰、可实现的技术实施路径,可有效助力开发者提…...
Python中使用Redis的参数
Python中使用Redis通常是通过redis-py这个库来实现的。redis-py是一个Python客户端,它提供了对Redis数据库的完整操作接口。在使用redis-py时,你需要通过连接参数来配置与Redis服务器的连接。下面是一些常用的连接参数及其解释: host 描述&…...
tensorflow使用详解
一、TensorFlow基础环境搭建 安装与验证 # 安装CPU版本 pip install tensorflow# 安装GPU版本(需CUDA 11.x和cuDNN 8.x) pip install tensorflow-gpu# 验证安装 python -c "import tensorflow as tf; print(tf.__version__)"核心概念 Tensor…...
FreeMarker语法深度解析与Node.js集成实践指南
一、FreeMarker核心语法体系 1.1 基础模板结构 <#-- 注释语法 --> ${expression} <#-- 输出表达式 --> <#directive paramvalue> <#-- 指令语法 -->1.2 数据类型处理 标量类型深度处理: <#assign num 123.45?floor> <#--…...