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

实操(不可重入函数、volatile、SIGCHLD、线程)Linux

1 不可重入函数

为什么会导致节点丢失内存泄露?main函数在执行insert,但是没执行完就被信号中断了,又进了这个函数里,所以这个insert函数在不同的执行流中,同一个函数被重复进入,如果没有问题,该函数被称为可重入函数,如果有问题,该函数被称为不可重入函数

如果一个函数符合以下条件之一则是不可重入的:

  • 调用了malloc或free,因为malloc也是用全局链表来管理堆的。
  • 调用了标准I/0库函数。标准I/0库的很多实现都以不可重入的方式使用全局数据结构。

2 volatile

一开始程序疯狂的卡在while循环,如果收到了2号信号(ctrl+c),quit由0变1,逻辑反条件就不满足,输出正常退出结果

makefile

mysignal:signal.cgcc -o $@ $^
.PHONY:clean
clean:rm -f mysignal

signal.c 

#include <stdio.h>
#include <signal.h>int quit = 0;void handler(int signo)
{printf("change quit from 0 to 1\n");quit = 1;printf("quit=%d\n", quit);
}
int main()
{signal(2, handler);while(!quit);  //注意这里故意没有携带while的代码块,故意让编译器认为在main中,quit只会被检测printf("main 正常退出\n");return 0;
}

 

  • 无论你在进程里面定义多少变量,最终想能够被访问,必须要加载到物理内存里,只不过是通过虚拟地址空间让我们找到它而已,定义的全局quit变量,当二进制程序开始执行,一定要在内存里把数据(代码)开辟好,所以quit毫无疑问在内存当中;循环判断的时候是一种计算,cpu匹配运算的种类,一种是算术运算(加减乘除取模、各种浮点数运算),一种是逻辑运算(真假判断、逻辑与、逻辑取反),while(!quit)是在CPU上跑,现在的问题是你要检测的数据开始的时候是在内存里,要计算的时候是在CPU内部,所以如果你想要计算,第一件事情是将内存中的数据通过某种方式load到CPU内,cpu中有对应的寄存器、pc指针,把quit=0放进寄存器,它才会对quit做真假判断,PC指针表征当前的进程执行到哪里,如果条件满足,pc指针继续执行while(!quit)代码,如果当前条件不满足,它会让PC指针向下移动,指向下一条语句,开始向后执行,整个逻辑就是这样子的,总结一下就三步,第一要把数据从内存加载到CPU里的寄存器,第二做判断运算,第三判断完成后更改PC指针(继续执行当前语句还是下一条语句)
  • 后面加了信号的捕捉,2号信号到来的时候调用handler方法,将quit改成1,后面的逻辑依旧是要做判断,CPU从内存里读取qiit=1,逻辑反之后判断条件满不满足,更改PC指针,这是我们之前退出的原因,数据一旦被修改就可以被while循环检测到,条件不满足就退出了

实际上c++在编译的时候是有优化级别的,查看man手册(man gcc),找到优化选项(/Optimization Options)

按了2号信号,quit改成1了却还不退出的现象,退出指令(ctrl+\)

makefile(在第二行加一个 O2选项)

mysignal:signal.cgcc -o $@ $^ -O2
.PHONY:clean
clean:rm -f mysignal 

显示 

  • 在刚刚的过程中,让计算机执行while循环,每一次都要尝试着把数据从内存加载到CPU,在main函数里,我发现quit是没有被修改的,只是在被检测,编译器编译的时候发现,quit变量没有被修改,为什么要重复做把数据加载到cpu里的动作呢,只需要在代码编译形成汇编代码时,把数据加载到CPU里的寄存器,往后循环检测时直接检测寄存器里的就行了,不用再去内存里面查quit,因为每次找结果都是一样的,好比你问某个人问了好几次不同的问题,他都说不知道,那你下次再想问他问题的时候,本来要张口的,心里想着说算了,反正他也不知道,那你对这个人的判断就是以后问他什么问题他都不知道,同样的,编译器就不需要在内存里找了,直接检测寄存器里的数据就可以了,编译器就这么认为的,它会将quit变量直接优化到CPU里的寄存器当中,只有第一次会将quit加载到寄存器里,往后判断时候只检测寄存器是否为真还是假,再决策对应的指针,相当于CPU遵循就近原则,只查寄存器的值而不查内存的值,叫做内存位置不可见了,这就是为什么加了优化,quit=1也执行了,最终这个循环却不退出的原因

所以为了解决这个问题,要告诉编译器保证每次检测都要尝试着从内存中进行数据读取,不要用寄存器中的数据,让内存数据可见!就有了volatile关键字,他的作用就是杜绝对quit变量做寄存器级别的优化,保证内存可见性        

 加volatile关键字,让main正常退出

volatile int quit = 0;

显示 

3 SIGCHLD

子进程退出的时候会向父进程发SIGCHLD信号,但是父进程默认处理动作是忽略的,所以我们为了证明它会发,我们可以自定义捕捉SIGCHLD信号(现象是子进程被创建出来,先正常运行5秒,期间父进程持续做自己的事情,当信号到来的时候会等待5秒钟,但是在等期间这个子进程已经退了,且会处于僵尸状态,因为父进程还没回收它,5秒之后wait它的时候,最终我们就会看到打印等待成功,僵尸状态也会随着消失)

makefile

mysignal:signal.cgcc -o $@ $^ #-O2
.PHONY:clean
clean:rm -f mysignal 

查看waitpid第一个参数说明(man waipid)

pid_t waitpid(pid_t pid, int *wstatus, int options);

  • 大于0代表你传的参数就是你要等的进程的id,-1代表等待任意一个子进程

signal.c

#include <stdio.h>
#include <signal.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>//id暂时定义成全局的,一会方便做对比,因为信号和main函数是两个执行流
pid_t id; void handler(int signo)
{ sleep(5);printf("捕捉到一个信号:%d,who:%d\n", signo, getpid());//-1表示等待任意一个子进程,退出结果不关心,阻塞式等待//虽然写了0,阻塞式等待,我们绝对不会被阻塞,因为我已经收到信号了//就证明当前的子进程肯定有退的,waitpid就可以返回了pid_t res = waitpid(-1, NULL, 0);if (res > 0){//等待成功返回子进程的pid//id 在父进程中存储的是子进程的 PIDprintf("wait success, res: %d, id: %d\n", res, id);}
}int main()
{signal(SIGCHLD, handler);id = fork();if (id == 0){int cnt = 5;while(cnt--){printf("我是子进程,我的pid:%d, ppid: %d\n", getpid(), getppid());sleep(1);}exit(1);}while(1){sleep(1);}return 0;
}

显示(while :; do ps axj | head -1&&ps axj | grep mysignal | grep -v grep; echo "---------------"; sleep 1; done)

现在来了一大堆的信号,pending位图比特位只有一个,比如第一个子进程退了,pending位设置1,第二个子进程来了,无非就是把1再置为1,此时信号不就相当于丢失了吗,相当于子进程退出发了10个信号,可能导致最终只回收了两三个子进程
signal.c

int main()
{signal(SIGCHLD, handler);int i = 1;for(; i <= 10; ++i){id = fork();if (id == 0){int cnt = 5; while(cnt--){printf("我是子进程,我的pid:%d, ppid: %d\n", getpid(), getppid());sleep(1);}exit(1);}}while(1){sleep(1);}return 0;
}

显示

  • 只回收了两个子进程

所以要while式的循环回收,你有几个进程我就回收几个进程

signal.c

void handler(int signo)
{ printf("捕捉到一个信号:%d,who:%d\n", signo, getpid());sleep(5);while(1){//-1表示等待任意一个子进程,退出结果不关心,阻塞式等待//虽然写了0,阻塞式等待,我们绝对不会被阻塞,因为我已经收到信号了//就证明当前的子进程肯定有退的,waitpid就可以返回了 pid_t res = waitpid(-1, NULL, 0);if (res > 0){//等待成功返回子进程的pid, id 在父进程中存储的是子进程的 PIDprintf("wait success, res: %d, id: %d\n", res, id);}   else break; //如果没有子进程了}printf("handler done...\n");
}

显示

假如有五个子进程退出五个子进程没退出,waitpid一直循环回收,它总会碰到没有退出的子进程,就会一直处于阻塞状态,导致handler无法返回,代码没办法再向后运行,所以要将它改成非阻塞等待,pid_t res = waitpid(-1, NULL, WNOHANG);完整代码

#include <stdio.h>
#include <signal.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h> //id暂时定义成全局的,一会方便做对比,因为信号和main函数是两个执行流
pid_t id; void waitProcess(int signo)
{ printf("捕捉到一个信号:%d,who:%d\n", signo, getpid());sleep(5);while(1){//-1表示等待任意一个子进程,退出结果不关心,阻塞式等待//虽然写了0,阻塞式等待,我们绝对不会被阻塞,因为我已经收到信号了//就证明当前的子进程肯定有退的,waitpid就可以返回了 //pid_t res = waitpid(-1, NULL, 0);//非阻塞等待,有就回收,没有就出错返回pid_t res = waitpid(-1, NULL, WNOHANG);if (res > 0){//等待成功返回子进程的pid, id 在父进程中存储的是子进程的 PIDprintf("wait success, res: %d, id: %d\n", res, id);}   else break; //如果没有子进程了}printf("handler done...\n");
}int main()
{signal(SIGCHLD, waitProcess);int i = 1;for(; i <= 10; ++i){id = fork();if (id == 0){int cnt = 5; while(cnt--){printf("我是子进程,我的pid:%d, ppid: %d\n", getpid(), getppid());sleep(1);}exit(1);}}while(1){sleep(1);}return 0;
}
  • 一个基于信号版的回收子进程的代码

显示

要想不产生僵尸进程,还有另一种办法,父进程调用sigaction将SIGCHLD的处理动作置为SIG_IGN,往后创建的子进程在退出时就会被操作系统自动清理,不会产生僵尸进程,也不会通知父进程

signal.c(signal(SIGCHLD, waitProcess);)改成

signal(SIGCHLD, SIG_IGN);

显示

 

子进程退了,会给父进程发信号,父进程默认对该信号的处理动作是忽略,为什么还要再调一下这个signal函数呢

这其实是一种特殊情况,可以理解成在signal方法里,父进程调用signal的时候,如果他检测到你是SIGCHLD, SIG_IGN这种组合,除了设置SIGCHLD信号为忽略之外,他还会修改父进程PCB的状态位,因为子进程的状态是按父进程来的,父进程相当于可以给自己打一个标签,假设我创建的子进程以后就不要僵尸,这个标志位就会在fork的时候被子进程继承下去,所当子进程退出的时候,操作系统发现子进程退了,检测标志时发现这个进程早就设置过了标志位,你退了就直接把你释放掉了,相当于在信号handler表当中,默认是SIG_IGN,他就执行默认动作,如果你自己手动调了signal或sigaction,它是系统调用,会修改未来创建子进程的一些状态位,方便操作系统识别进而直接回收它;也可以这样理解,以前对子进程退出信号的默认动作是SIG_DFL,什么都不做,现在设置成SIG_IGN,操作系统就把它回收掉了

4 线程(看看现象)

makefile

mysignal:signal.cgcc -o $@ $^ -lpthread
.PHONY:clean
clean:rm -f mysignal 

signal.c

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>void *thread1_run(void *args)
{while(1){printf("我是线程1,我正在运行\n");sleep(1);}
}void *thread2_run(void *args)
{while(1){printf("我是线程2,我正在运行\n");sleep(1);}
}void *thread3_run(void *args)
{while(1){printf("我是线程3,我正在运行\n");sleep(1);}
}int main()
{pthread_t t1, t2, t3;pthread_create(&t1, NULL, thread1_run, NULL);pthread_create(&t2, NULL, thread2_run, NULL);pthread_create(&t3, NULL, thread3_run, NULL);while(1) {printf("我是主线程,我正在运行\n");sleep(1);}
}

查看线程(ps -aL | head -1&&ps -aL | grep mysignal)

  • 可以看出他们是属于同一个进程的,因为他们的PID都是一样的,LWP叫做轻量级进程,第一行执行流他的PID和LWP数字是一样的,那操作系统调度的时候如何区分呢,所以真正意义上,操作系统调度的时候,看的是LWP,所以CPU调度的时候,根据LWP,调度不同的线程去运行,以前我们说根据PID也没有错,因为当你的进程当中只有一个执行流时,PID和LWP数字是一样的,看哪个都行 

相关文章:

实操(不可重入函数、volatile、SIGCHLD、线程)Linux

1 不可重入函数 为什么会导致节点丢失内存泄露&#xff1f;main函数在执行insert&#xff0c;但是没执行完就被信号中断了&#xff0c;又进了这个函数里&#xff0c;所以这个insert函数在不同的执行流中&#xff0c;同一个函数被重复进入&#xff0c;如果没有问题&#xff0c;…...

如何在Linux系统上通过命令调用AI大模型?

如何在Linux系统上通过命令调用AI大模型&#xff1f; 文章目录 如何在Linux系统上通过命令调用AI大模型&#xff1f;一、准备工作二、编写API调用脚本三、配置命令行工具 使用AI命令帮我做一个文档总结提问技术问题编写简单的shell脚本帮我写一个docker-compose 在这个AI技术飞…...

数据分析-Excel-学习笔记Day1

Day1 复现报表聚合函数&#xff1a;日期联动快速定位区域SUMIF函数SUMIFS函数环比、同比计算IFERROR函数混合引用单元格格式总结汇报 拿到一个Excel表格&#xff0c;首先要看这个表格的构成&#xff08;包含了哪些数据&#xff09;&#xff0c;几行几列&#xff0c;每一列的名称…...

负载均衡是什么,Kubernetes如何自动实现负载均衡

负载均衡是什么&#xff1f; 负载均衡&#xff08;Load Balancing&#xff09; 是一种网络技术&#xff0c;用于将网络流量&#xff08;如 HTTP 请求、TCP 连接等&#xff09;分发到多个服务器或服务实例上&#xff0c;以避免单个服务器过载&#xff0c;提高系统的可用性、可扩…...

洞察 Linux 进程管理

一、进程和线程的概念 1.进程 &#xff08;1&#xff09;概念 进程是程序在操作系统中的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位。进程是程序的执行实例&#xff0c;拥有独立的资源&#xff08;如内存、文件描述符等&#xff09;。每个进程在创建时会被…...

http协议版本的区别 -- 2和3

目录 http2和http3的区别 传输层协议 QUIC协议 介绍 连接建立与握手 建立安全连接的过程 RTT 建连为什么需要两个过程 原因 解决 QUIC协议的1-RTT 建连 必要性 连接过程 第一次握手(Client Hello) 版本号 key_share 其他 第二次握手 介绍 Server Hello 身…...

Vue2-实现elementUI的select全选功能

文章目录 使用 Element UI 的全选功能自定义选项来模拟全选 在使用 Element UI 的 el-select组件时&#xff0c;实现“全选”功能&#xff0c;通常有两种方式&#xff1a;一种是使用内置的全选功能&#xff0c;另一种是通过自定义选项来模拟全选。 使用 Element UI 的全选功能…...

Spring Boot 与 TDengine 的深度集成实践(四)

优化与扩展 批量插入数据 在实际应用中&#xff0c;当需要插入大量数据时&#xff0c;逐条插入会导致性能低下&#xff0c;因为每次插入都需要建立数据库连接、解析 SQL 语句等操作&#xff0c;这些操作会带来额外的开销 。为了提高数据插入效率&#xff0c;我们可以采用批量…...

2025年【山东省安全员C证】考试题及山东省安全员C证考试内容

在当今建筑行业蓬勃发展的背景下&#xff0c;安全生产已成为企业生存与发展的基石。安全员作为施工现场安全管理的直接责任人&#xff0c;其专业能力和资质认证显得尤为重要。山东省安全员C证作为衡量安全员专业水平的重要标准&#xff0c;不仅关乎个人职业发展&#xff0c;更直…...

提升Spring Boot开发效率的Idea插件:Spring Boot Helper

一、Spring Boot Helper插件介绍 Spring Boot Helper是一款专为Spring Boot开发者设计的IntelliJ IDEA插件&#xff0c;它提供了丰富的功能来简化和加速Spring Boot应用程序的开发过程。 该插件能够智能识别Spring Boot项目结构&#xff0c;提供专属的代码生成、配置辅助和运…...

【USTC 计算机网络】第三章:传输层 - 面向连接的传输:TCP

本文介绍了面向连接的传输协议&#xff1a;TCP&#xff0c;首先介绍 TCP 报文段的结构以及如何设置超时定时器&#xff0c;接着介绍 TCP 如何实现可靠数据传输以及流量控制&#xff0c;最后介绍 TCP 中最重要的三次握手与四次挥手的连接建立与关闭过程。 1. TCP 概述与段结构 …...

Linux主要开发工具之gcc、gdb与make

此系列还有两篇&#xff0c;大家想完整掌握可以阅读另外两篇 Linux文本编辑与shell程序设计-CSDN博客 Linux基础知识详解与命令大全&#xff08;超详细&#xff09;-CSDN博客 1.gcc编译系统 1.1 文件名后缀 文件名后缀 文 件 类 型 文件名后缀 文 件 类 型 .c C源…...

23种设计模式-行为型模式-观察者

文章目录 简介问题解决代码关键实现说明 总结 简介 观察者是一种行为设计模式&#xff0c; 允许你定义一种订阅通知机制&#xff0c; 可在事件发生时通知多个“观察/订阅”该对象的其他对象。 问题 假如你有两种类型的对象: 顾客和商店。顾客对某个新品非常感兴趣&#xff0…...

去中心化预测市场

去中心化预测市场 核心概念 预测市场类型&#xff1a; 类别型市场&#xff1a;二元结果&#xff08;YES/NO&#xff09;&#xff0c;例如“BTC在2024年突破10万美元&#xff1f;” 多选型市场&#xff1a;多个选项&#xff08;如总统候选人&#xff09;&#xff0c;赔付基于…...

springboot-ai接入DeepSeek

1、引入pom依赖 <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId> </dependency><dependencyManagement><dependencies><dependency><groupId>o…...

【C语言】数据在内存中的储存(整形)

目录 前言&#xff1a; 预备知识 整数在内存中的储存 原码 反码 补码 总结&#xff1a; 前言&#xff1a; 在上两章中讲解了五大内存函数&#xff0c;其中memchr函数&#xff0c;这个函数考察到数据内存的存储。 接下来为大家讲解整数在内存中的储存。 预备知识 认识…...

PCL 树木树干粗提取(地基数据,TLS)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 主要的思路如下: 1、首先,使用之前的CSF算法提取点云的地面点,在提取的过程中我们可以得到一个布料结构(地面模型)。 2、在得到这个布料结构之后,我们也就可以得到整个地面模型的高度了,之后我们只需要遍历每…...

Spring 中的 IOC

&#x1f331; 一、什么是 IOC&#xff1f; &#x1f4d6; 定义&#xff08;通俗理解&#xff09;&#xff1a; IOC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09; 是一种设计思想&#xff1a;对象不再由你自己创建和管理&#xff0c;而是交给 Spring 容器…...

尚硅谷2019版Java集合和泛型

第十一章 Java集合框架 集合框架全景图 mindmaproot((Java集合))Collection单列List有序可重复ArrayListLinkedListVectorSet无序唯一HashSetLinkedHashSetTreeSetMap双列HashMapLinkedHashMapTreeMapHashtablePropertiesToolsCollectionsArrays三大核心接口对比 特性ListSe…...

车载诊断架构 --- 整车重启先后顺序带来的思考

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...

华为eNSP:实验 配置单区域集成ISIS

单区域集成ISIS是一种基于中间系统到中间系统&#xff08;IS-IS&#xff09;协议的网络架构优化方案&#xff0c;主要用于简化网络设计并提升数据传输效率。其核心特点包括&#xff1a; ‌单一区域部署‌ ISIS协议在单一逻辑区域内运行&#xff0c;消除多区域间的分层复杂性&am…...

常见框架漏洞(五)----中间件IIS6

一、【PUT漏洞】 漏洞描述&#xff1a;IIS Server 在 Web 服务扩展中开启了 WebDAV &#xff0c;配置了可以写⼊的权限&#xff0c;造成任意⽂件上传。 版本&#xff1a;IIS 6.0 1. 环境 fofa搜素环境&#xff1a;"IIS-6.0" 或者环境搭建&#xff1a;本地搭建2003…...

leetcode221.最大正方形

class Solution {public int maximalSquare(char[][] matrix) {int result 0; // 记录正方形边长int m matrix.length, n matrix[0].length;int[][] dp new int[m 1][n 1];// 动态规划for (int i 1; i < m; i) {for (int j 1; j < n; j) {if (matrix[i - 1][j - …...

C++实现AVL树

一 AVL树的概念 上上节我们学习了二叉搜索树&#xff0c;他的理想查找的时间复杂度是o(log n)&#xff0c;但是如果是下面这种情况&#xff0c;那么它的时间复杂度就会变成o(n). 这种情况就是出现一边高的那种&#xff0c;它的个数和它的高度相差不大。 那么这样就会把二叉搜索…...

Linux系统安全及应用

目录 一.账号安全措施 1.1系统账号清理 1.1.1将非登录用户的shell设为无法登录 1.1.2删除无用用户 userdel 1.1.3锁定账号文件 1.1.4锁定长期不使用的账号 1.2密码安全控制 1.2.1 对新建用户 1.2.2对已有用户 1.3命令历史限制 1.3.1临时清除历史命令 1.3.2限制命令…...

JAVA反序列化深入学习(十三):Spring2

让我们回到Spring Spring2 在 Spring1 的触发链上有所变换&#xff1a; 替换了 spring-beans 的 ObjectFactoryDelegatingInvocationHandler使用了 spring-aop 的 JdkDynamicAopProxy &#xff0c;并完成了后续触发 TemplatesImpl 的流程 简而言之&#xff0c;换了一个chain&am…...

迭代器运算详解(四十二)

1. 迭代器的随机访问运算 对于 vector 和 string 这样的容器&#xff0c;它们的迭代器支持以下随机访问运算符&#xff1a; 运算符说明iter n返回一个新的迭代器&#xff0c;该迭代器比原来的迭代器 iter 向前移动了 n 个位置&#xff08;即指向后面的第 n 个元素&#xff0…...

Linux中Squid服务常用操作

在 Linux 中 Squid 服务常用操作介绍 1. Squid 基础操作 启动 Squid # 前台启动&#xff08;调试用&#xff09; squid -N -d 1# 后台启动&#xff08;-s 表示将日志输出到 syslog&#xff09; squid -s停止 Squid # 安全停止&#xff08;需配置 pid_file&#xff09; squid…...

Linux操作系统--进程的概念

目录 1.了解进程前的前景知识 冯诺依曼体系结构 操作系统(OS) 2.进程 2.1进程的概念 2.2描述进程-PCB 2.2.1task_struct 2.3查看进程 2.4通过系统调用获取进程的标识符 2.5认识fork()--创建进程 该专栏会持续更新 更新时间一周一更。下周更新内容进程状态 1.了解进程前…...

C++假期练习

思维导图 牛客练习...

HTML零基础入门笔记:狂神版

前言 本笔记是学习狂神的java教程&#xff0c;建议配合视频&#xff0c;学习体验更佳。 【狂神说Java】HTML5完整教学通俗易懂_哔哩哔哩_bilibili 第1-2章&#xff1a;Java零基础入门笔记&#xff1a;(1-2)入门&#xff08;简介、基础知识&#xff09;-CSDN博客 第3章&…...

算法竞赛备赛——【图论】链式前向星

图论 图的存储方式&#xff1a; 通用的三种&#xff1a;邻接矩阵、邻接表、边集数组 有向图&#xff1a;十字链表 无向图&#xff1a;多重邻接表 刷题常用&#xff1a;邻接矩阵、链式前向星&#xff08;邻接表变形&#xff09; 链式前向星 算法题常用: 邻接矩阵、二维vector模…...

JAVA_类和对象

目录 1.面向对象的初步认知 1.1.什么是面向对象 1.2.面向对象与面向过程 2.类的定义和使用 2.1.简单认识类 2.2类的定义格式 2.3.练习 学生类 动物类&#xff08;可爱猫猫&#x1f431;&#xff09; 3.类的实例化 3.1.什么是实例化 3.2.类和对象的说明 4.this引用…...

高频面试题(含笔试高频算法整理)基本总结回顾65

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…...

数据库系统-数据库控制

并发控制 事务的ACID特性&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务包含的所有操作要么全部成功&#xff08;commit提交&#xff09;&#xff0c;要么全部失败&#xff08;rollback回滚&#xff09;一致性&#xff08;Consistency&#xff09;&a…...

Python Cookbook-5.3 根据对象的属性将对象列表排序

任务 需要根据各个对象的某个属性来完成对整个对象列表的排序。 解决方案 DSU方法仍然一如既往地有效: def sort_by_attr(sed,attr):intermed [ (getattr(x,attr),i,x) for i,x in enumerate(seg)]intermed.sort()return [ x[-1] for x in intermed def sort_by_attr_inpl…...

Java MCP SDK 开发笔记(一)

MCP 简介 AI 大模型诞生之初&#xff0c;其高度模拟人的对话之能力惊为天人。但我们肯定不希望止步于此—— 工具化就是我们希望 AI 能够完成的目标&#xff0c;由此可以从单纯的对话发展为代替繁复人力的“干活”。这条道路上毋庸置疑 AI 大模型任重道远。而 MCP(Model Contr…...

AF3 OpenFoldDataLoader类_prep_batch_properties_probs方法解读

AlphaFold3 data_modules 模块的 OpenFoldDataLoader 类的 _prep_batch_properties_probs 方法是为每个批次数据准备 recycling 维度 的概率分布。它将根据配置文件中的设定为每个批次数据生成 recycling 轮次的概率分布,并存储到 prop_probs_tensor 中,用于后续抽样选择特定…...

寻找字符串数组中的最长共同前缀字符串

问题描述&#xff1a;给定一个字符串数组 strs&#xff0c;编写一个函数来找到这些字符串的最长公共前缀字符串&#xff0c;如果没有则返回空字符串"" 算法思路 横向扫描法&#xff1a; 从数组的第一个字符串开始&#xff0c;逐个和后面的字符串比较&#xff0c;逐…...

leetcode_数组 56. 合并区间

56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;int…...

Jenkins学习(B站教程)

文章目录 1.持续集成CI2.持续交付CD3.持续部署4.持续集成的操作流程5.jenkins简介6.后续安装部署&#xff0c;见视频 bilibili视频 Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;起源于Hudson&#xff08;Hudson是商用的&#xff09;&#xff0c;主要用…...

学习笔记—C++—类和对象(一)

目录 类和对象 类的定义 类定义格式 访问限定符 类域 实例化 实例化概念 对象的大小 this指针 C和C语言实现Stack对比 类和对象 类的定义 类定义格式 ● class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后…...

PyTorch 深度学习 || 6. Transformer | Ch6.3 Transformer 简单案例

1. 简单案例 这个代码是一个简单的 Transformer 模型的实现,这个例子展示了一个基本的序列到序列(seq2seq)任务,比如将一个数字序列转换为另一个数字序列。可以用于学习和理解 Transformer 的基本结构和工作原理。 import torch import torch.nn as nn import math# 位置…...

体育风暴篮球足球体育球员综合资讯网站模板

源码名称&#xff1a;篮球足球体育球员综合资讯网站模板 开发环境&#xff1a;帝国cms7.5 空间支持&#xff1a;phpmysql 带软件采集&#xff0c;可以挂着自动采集发布&#xff0c;无需人工操作&#xff01; 演示地址&#xff1a;https://www.52muban.com/shop/184016.html …...

Visual Studio Code SSH 连接超时对策( keep SSH alive)

文章目录 问题解决方法一&#xff1a;配置服务端关于ClientAliveInterval和ClientAliveCountMax1、打开终端&#xff0c;打开SSH配置文件&#xff1a;输入以下命令&#xff1a;2、打开配置文件后&#xff0c;添加以下内容&#xff1a;3、添加后&#xff0c;Esc按 <Enter>…...

Docker容器中的ubuntu apt update报错 解决办法

问题现象 # apt update Get:1 http://archive.ubuntu.com/ubuntu noble InRelease [256 kB] Get:2 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB] Err:2 http://security.ubuntu.com/ubuntu noble-security InRelease At least one invalid signa…...

CV - 目标检测

物体检测 目标检测和图片分类的区别&#xff1a; 图像分类&#xff08;Image Classification&#xff09; 目的&#xff1a;图像分类的目的是识别出图像中主要物体的类别。它试图回答“图像是什么&#xff1f;”的问题。 输出&#xff1a;通常输出是一个标签或一组概率值&am…...

linux提权 corn 提权

corn提权 corn的基本使用方法 corn的作用就是可以定时的完成一下任务&#xff08;如备份一下log 或者清除一下日志文件 这些就是运维人员用的&#xff09; 先找一下定时任务的工作表 cat /bin/corntab 这个是普通用户 我们直接看都看不了 说明什么说明这个 是root高权限执…...

1Panel安装失败 国内docker安装失败

本文仅针对学习交流&#xff0c;只为了帮助计算机相关专业大学生个人技能实操而记录 非学习目的严禁学习&#xff01;&#xff01;&#xff01;否则后果自负 1、离线安装1Panel&#xff08;不需要手动安装docker&#xff0c;离线安装包里包括了docker&#xff09; 离线包下载地…...

Excel + VBA 实现“准实时“数据的方法

Excel 本身是静态数据处理工具,但结合 VBA(Visual Basic for Applications) 可以实现 准实时数据更新,不过严格意义上的 实时数据(如毫秒级刷新)仍然受限。以下是详细分析: 1. Excel + VBA 实现“准实时”数据的方法 (1) 定时刷新(Timer 或 Application.OnTime) Appl…...