【Linux庖丁解牛】—程序地址空间【进程地址空间 | 虚拟地址空间】
1. 再谈空间分布图
我们之前在学C/C++的时候必然学过上面的空间分布图。
可是我们对他并不理解!这里先对其进行各区域分布验证:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_unval;
int g_val = 100;
int main(int argc, char *argv[], char *env[])
{const char *str = "helloworld";printf("code addr: %p\n", main);printf("init global addr: %p\n", &g_val);printf("uninit global addr: %p\n", &g_unval);static int test = 10;char *heap_mem = (char*)malloc(10);char *heap_mem1 = (char*)malloc(10);char *heap_mem2 = (char*)malloc(10);char *heap_mem3 = (char*)malloc(10);printf("heap addr: %p\n", heap_mem); //heap_mem(0), &heap_mem(1)printf("heap addr: %p\n", heap_mem1); //heap_mem(0), &heap_mem(1)printf("heap addr: %p\n", heap_mem2); //heap_mem(0), &heap_mem(1)printf("heap addr: %p\n", heap_mem3); //heap_mem(0), &heap_mem(1)printf("test static addr: %p\n", &test); //heap_mem(0), &heap_mem(1)printf("stack addr: %p\n", &heap_mem); //heap_mem(0), &heap_mem(1)printf("stack addr: %p\n", &heap_mem1); //heap_mem(0), &heap_mem(1)printf("stack addr: %p\n", &heap_mem2); //heap_mem(0), &heap_mem(1)printf("stack addr: %p\n", &heap_mem3); //heap_mem(0), &heap_mem(1)printf("read only string addr: %p\n", str);for(int i = 0 ;i < argc; i++){printf("argv[%d]: %p\n", i, argv[i]);}for(int i = 0; env[i]; i++){printf("env[%d]: %p\n", i, env[i]);}return 0;
}
结果如下:
我们首先看到字符串常量的地址和代码区的地址非常相近。所以字符串常量就在代码段当中,因为字符串常量是只读的,且代码也是只读的,所以将它们放在一起也是合理的!
我们还看到static修饰的test变量在函数内部,其作用域在函数内部,但生命周期是全局的。原因就在于test和我们定义在全局定义的global地址相近。
其他的堆区啊,栈区啊都没有什么问题。但这里我想问大家一个问题:程序地址空间是内存吗?
先说答案:不是内存!
其实程序地址空间更准确的说应该是:进程地址空间 | 虚拟地址空间。他是一个系统级的概念,而不是语言层的概念。我们以前叫他程序地址空间是为了我们在语言层学习的时候更加容易接受,但我们其实还未真正的理解何为进程地址空间!
你说不是内存就不是内存吗?下面我就来做一个实验证明进程地址空间不是真正的物理空间【内存】!
下面这段代码,我创建了一个子进程,我们前面已经知道了,虽然父子进程共享同一段代码和数据,但是当其中任何一方修改数据时,就会反生写时拷贝,为其中一方提供额外的一份数据!
所以我们运行下面的代码,父子进程中的gval是两份不同的数据,如果进程地址空间就是实际的物理空间,那么这两份数据的地址必然不会相同!
运行结果如下:
我们居然惊奇的发现两份数据的地址竟然一模一样!那么这就说明进程地址空间必然不是实际的物理空间了【内存】,而实际上,我们之前C/C++指针用到的地址都是虚拟地址。那程序地址空间到底是什么,而这两份数据的地址又为什么一样呢?
2. 引入新概念,简单解释以上问题
2.1 一个进程一个虚拟地址空间
虚拟地址空间在32位机器下有2^32个地址,也就是又4GB空间。其中有1GB空间是给内核使用的,另外3GB地址空间用户拿到地址就可以直接访问。
而64位机器下则有2^64个地址,16GB空间。
2.2一个进程一套页表
页表是用来做虚拟地址和物理地址映射的。
在上面的问题当中,gval在虚拟地址空间一定有个地址【假设该地址为0x111111】,而在内存当中也势必会有一个地址【我们假设为0x112233】。而每一个进程都会有一套对应的页表,页表当中一个虚拟地址映射一个内存地址,通过这样的方式,系统就可以通过虚拟地址找到内存当中真正存储数据的物理空间。
有了上面的理解,接下来我们就来理解一下父子进程关系中为什么在任何一方数据不发生变化时,父子进程会共享同一块数据?
因为每个进程都有一张页表,所以父进程在创建子进程时,子进程会浅拷贝一份父进程的页表信息,此时,这两份页表信息完全相同【即它们的虚拟地址和物理地址的映射关系完全相同】,所以它们的数据是共享的。
但是,当任何一方的数据发生修改时,操作系统先说你先等一下,此时,操作系统会在物理地址当中重新开辟一份空间【该空间存储修改后的数据】,假设是子进程修改数据,那么子进程的页表的物理地址就会指向新开辟的空间,而虚拟地址就不会发生变化,这就是写时拷贝。至此,我们也就明白了,为什么我们会看到不同的数据居然会指向同一个地址,因为我们看到的是虚拟地址,而它们的物理地址实际上是不一样的。【那我们能不能看到它们的物理地址呢,答案是不能!】
明白了以上的原理后,我们之前有一个无法解释的问题【为什么一个变量,即==0,又>0?导致if else同时成立???】,现在就可以解释了。
因为父子进程虽然执行同一份代码,但是它们在看自己的数据时,是通过自己的页表映射找到自己的数据【即使它们的变量名相同,但它们的实际存储的物理地址却是不相同的】。
3. 什么是进程虚拟地址空间
每个进程都有一个虚拟地址空间,为了管理这些虚拟地址空间,在操作系统中势必会有某种数据结构将这些虚拟地址空间管理起来。
这里就直接说了,在Linux中,某个进程的虚拟地址空间用mm_struct的结构体描述,在进程的task_struct中有一个指向mm_struct结构体的指针。
struct task_struct
{/*...*/struct mm_struct *mm; //对于普通的⽤⼾进程来说该字段指向他的
虚拟地址空间的⽤⼾空间部分,对于内核线程来说这部分为NULL。 struct mm_struct *active_mm; // 该字段是内核线程使⽤的。当该
进程是内核线程时,它的mm字段为NULL,表⽰没有内存地址空间,可也并不是真正的没有,这是因为所
有进程关于内核的映射都是⼀样的,内核线程可以使⽤任意进程的地址空间。 /*...*/
}
所以进程虚拟地址空间就是内核数据结构!
4. 如何描述一个进程虚拟地址空间
我们可以看到,在进程虚拟地址空间中划分了许多区域。那结构体mm_struct是如何做到这一点的呢?答案就是:我们只需要确认区域的开始和结束即可!
所以在结构体mm_struct中势必有许多整形类型的变量来记录这些值!事实也是如此!
struct mm_struct
{/*...*/struct vm_area_struct *mmap; /* 指向虚拟区间(VMA)链表 */ struct rb_root mm_rb; /* red_black树 */ unsigned long task_size; /*具有该结构体的进程的虚拟地址空间的⼤⼩*/ /*...*/// 代码段、数据段、堆栈段、参数段及环境段的起始和结束地址。 unsigned long start_code, end_code, start_data, end_data;unsigned long start_brk, brk, start_stack;unsigned long arg_start, arg_end, env_start, env_end;/*...*/
}
而当系统要调整区域时,仅需对这些整形变量进行加减操作即可!
但是,当进程被调度时,task_struct被创建,其中的mm_struct也会先开辟空间,但是各区域中的初始化值是从哪里来的呢?
直说了:就是从进程加载到内存时,进行初始化!
我们知道进程虚拟空间中大多数区域都是连续的【数据段|代码段|栈区】,但是按照我们以前的理解,堆区开辟的空间并不是连续的,甚至有时候它们的地址相差很大。可是这和我们现在理解的进程虚拟空间矛盾啊!
其实并不矛盾,在mm_struct中维护了一个链表mmap,改链表的节点为vm_area_struct的结构体,每个结构体记录了每个区域的开始结束位置,因为堆区有多份【更细的划分】,所以有多个vm_area_struct的结构体维护了多个堆区!而在mm_struct中维护的是整体堆区的范围!
下图只画了一个堆区,但实际上堆区并不止一份!
5. 为什么要有进程虚拟地址空间和页表
1. 有了上面的理解,我们就知道进程的代码和数据在物理地址空间上是可以随意分布的,也就是无序的,但是通过页表的映射关系,我们就可以找到每个进程的代码和数据并且在虚拟地址空间中,这些地址是连续且有序的。
所以,进程虚拟地址空间和页表可以让地址从无序变有序!
2. 地址转换的过程中,也可以对你的地址和操作进行合法性判定,进而保护物理内存!
a.什么是野指针?【重新理解野指针】
指针就是地址,当指针【地址】在页表中无法找到时该指针也就成为了野指针,此时,系统可能就会杀掉有野指针的进程导致进程崩溃!
b. char *str=“helloworld"; *str='K';
但我们编译运行以上代码时,程序就会崩溃。以我们之前的理解,str在字符常量区,所以str不可修改。而现在我们终于可以从本质上理解它了:其实页表之中还有一个权限的标记位,在页表的地址映射关系中,有些地址是只读的,比如字符常量区,所以系统在对改地址进行操作时判断出我们要对该地址进行写的操作,与其权限矛盾,那么系统就会拦截我们写的行为从而导致进程崩溃!
3. 让进程和内存管理,进行一定程度的解耦合!
有了进程虚拟地址空间和页表,进程的调度和切换与数据代码加载到内存当中没有强相关!
相关文章:
【Linux庖丁解牛】—程序地址空间【进程地址空间 | 虚拟地址空间】
1. 再谈空间分布图 我们之前在学C/C的时候必然学过上面的空间分布图。 可是我们对他并不理解!这里先对其进行各区域分布验证: #include <stdio.h> #include <unistd.h> #include <stdlib.h> int g_unval; int g_val 100; int ma…...
nginx 上传文件,413 request entity too large
目录 1 问题2 解决 1 问题 前端后端项目,上传文件,接口没问题,但是就是上传不成功 ,然后打开f12 ,发现这个接口出现413 request entity too large 这个报错 2 解决 1.1 修改nginx配置文件 在Nginx中,cli…...
Nacos源码—5.Nacos配置中心实现分析二
大纲 1.关于Nacos配置中心的几个问题 2.Nacos如何整合SpringBoot读取远程配置 3.Nacos加载读取远程配置数据的源码分析 4.客户端如何感知远程配置数据的变更 5.集群架构下节点间如何同步配置数据 4.客户端如何感知远程配置数据的变更 (1)ConfigService对象使用介绍 (2)客…...
数智管理学(八)
四、未来管理学可能的新拓展方向 (一)人工智能与机器学习的融合形成智能决策管理职能 随着人工智能和机器学习技术的不断发展,它们将在管理学中得到更广泛的应用。传统决策方法难以快速处理海量数据并准确把握复杂的市场动态。人工智能与机…...
Compose Multiplatform iOS 稳定版发布:可用于生产环境,并支持 hotload
随着 Compose Multiplatform 1.8.0 的发布,iOS 版本也引来的第一个稳定版本,按照官方的原话:「iOS Is Stable and Production-Ready」 ,而 1.8.0 版本,也让 Kotlin 和 Compose 在移动端有了完整的支持。 在 2023 年 4 …...
spark基本介绍
一、Spark概述 Spark是一种基于内存的快速、通用、可拓展的大数据分析计算引擎。 Hadoop是一个分布式系统结构的基础架构。 二、Spark与Hadoop相比较的优势: 1. 处理速度:Hadoop:数据处理速度相对较慢 Spark:速度比Hadoop快很…...
DeepSeek智能时空数据分析(九):NL2SQL绘制河流名字-如何给轨迹添加说明文字
序言:时空数据分析很有用,但是GIS/时空数据库技术门槛太高 时空数据分析在优化业务运营中至关重要,然而,三大挑战仍制约其发展:技术门槛高,需融合GIS理论、SQL开发与时空数据库等多领域知识;空…...
管家婆实用贴-如何在Excel中清除空格
我们在使用管家婆软件时,经常会用到Excel表格导入导出数据,在使用Excel整理数据时,数据中的空格可能会导致计算和分析出现问题。无论是多余的前导空格、尾部空格还是单元格中的不必要空格,清除它们都是确保数据准确性的关键。今天…...
《软件项目管理》笔记一
软件项目管理概述 项目管理属于软件工程的组成之一,另外两部分为:软件开发,过程改进。 参考书如下: 1.1 项目与软件项目 1、项目: 为了创造一个唯一的产品或提供一个唯一的服务而进行 的临时性的努力。 2、项目的…...
前端线上错误日志收集与定位指南
想象一下:你的Web应用上线后,用户反馈“按钮点不动”或“页面白屏”,但你却无从下手!前端线上错误如JavaScript异常、网络失败,稍不注意就让用户流失,业务受损。令人抓狂的是,80%的错误悄无声息…...
可视化魔法指南
🎨 ECharts数据可视化魔法指南 🌟 ECharts:数据的艺术画笔 #mermaid-svg-ARwFHUrXBJ03Gpo9 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ARwFHUrXBJ03Gpo9 .error-icon{fill:#552222;}#mermaid-svg-ARwFHUr…...
使用ffmpeg截取MP3等音频片段
可以使用以下命令通过 ffmpeg 截取 MP3 音频文件的指定片段: ffmpeg的安装方法参考:linux 安装包方式安装ffmpeg,并在环境中设定或指定ffmpeg地址_linux 通过ffmpeg访问地址-CSDN博客 ffmpeg -ss [start_time] -i input.mp3 -to [end_time] -codec copy output.mp3 参数说…...
FFmpeg(7.1版本)编译生成ffplay
FFmpeg在编译的时候,没有生成ffplay,怎么办? 1. 按照上一篇文章:FFmpeg(7.1版本)在Ubuntu18.04上的编译_ffmpeg-7.1-CSDN博客 在build.sh脚本里配置了ffplay 但是,实际上却没有生成ffplay,会是什么原因呢? 2. 原因是编译ffplay的时候,需要一些依赖库 sudo apt-get i…...
CAN学习之--不使用收发器进行通讯测试
在实际调试或者学习CAN通讯过程中,在需要进行CAN调试的时候,但是手头有只有MCU的评估板,没有CAN的收发器,比如ATA6561、MCP2518这类芯片的时候,该怎么办呢? 因为我们知道,CAN收发器只是做信号的…...
律所项目管理全攻略:人力分配 / 案件管控 / 知识沉淀三维度解析(附专用工具清单)
引言:律所项目管理破局 ——从经验驱动到体系化运营 在法律服务行业数字化转型加速的背景下,律所项目管理能力已成为决定服务质量、客户满意度及团队效能的核心竞争力。从人力分配失衡导致的效率损耗,到案件流程模糊引发的客户信任危机&…...
Linux电源管理(7)_Wakeup events framework
原文链接:Linux电源管理(7)_Wakeup events framework 1. 前言 本文继续“Linux电源管理(6)_Generic PM之Suspend功能”中有关suspend同步以及PM wakeup的话题。这个话题,是近几年Linux kernel最具争议的话题之一,在国外Linux开发论坛&…...
Nvidia-smi 运行失败(Failed to initialize NVML: Driver/library version mismatch)
问题排查 在linux服务器上运行 nvidia-smi 命令,提示以下错误: Failed to initialize NVML: Driver/library version mismatch 首先查看内核驱动版本: cat /proc/driver/nvidia/version然后查看当前NVIDIA驱动版本: sudo dpkg …...
算法设计与分析实验题-序列对齐
基于 C 的序列最大对齐得分算法实现 在生物信息学和文本处理领域,序列对齐是一种常见的需求。本文将介绍如何使用 C 实现一个序列最大对齐得分算法,该算法可以计算两个序列在最优对齐方式下的最大得分。 问题描述 给定两个序列 S1 和 S2,我…...
第8章-1 查询性能优化-优化数据访问
上一篇:《 下一篇:《第7章-3 维护索引和表》》 在前面的章节中,我们介绍了如何设计最优的库表结构、如何建立最好的索引,这些对于提高性能来说是必不可少的。但这些还不够——还需要合理地设计查询。如果查询写得很糟糕&a…...
每日一题洛谷P1025 [NOIP 2001 提高组] 数的划分c++
P1025 [NOIP 2001 提高组] 数的划分 - 洛谷 (luogu.com.cn) #include<iostream> using namespace std; int n, k; int res 0; void dfs(int num,int step,int sum) {//判断if (sum n) {if (step k) {res;return;}}if (sum > n || step k)return;//搜索for (int i …...
【python】使用Python和BERT进行文本摘要:从数据预处理到模型训练与生成
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着信息爆炸时代的到来,海量文本数据的高效处理与理解成为亟待解决的问题。文本摘要作为自然语言处理(NLP)中的关键任务,旨在自动生成…...
WHAT - Rust 智能指针
文章目录 常见的智能指针类型1. Box<T> — 堆上分配的数据2. Rc<T> — 引用计数的共享所有权(单线程)3. Arc<T> — 原子引用计数(多线程)4. RefCell<T> — 运行时可变借用(单线程)…...
用go从零构建写一个RPC(仿gRPC,tRPC)--- 版本1(Client端)
这里我们来实现这个RPC的client端 为了实现RPC的效果,我们调用的Hello方法,即server端的方法,应该是由代理来调用,让proxy里面封装网络请求,消息的发送和接受处理。而上一篇文章提到的服务端的代理已经在.rpc.go文件中…...
CentOS 安装 Zellij 终端复用器教程
CentOS 安装 Zellij 终端复用器教程 简介 Zellij 是一个现代化的终端复用器,使用 Rust 语言编写。它提供了类似 tmux 的功能,但具有更友好的用户界面和更现代化的特性。本教程将详细介绍如何在 CentOS 7.9 系统上安装 Zellij。 前置条件 CentOS 7.9 …...
基于 SpringBoot + Vue 的校园管理系统设计与实现
一、项目简介 本系统以校园组织管理为主线,结合用户权限分离机制与模块化设计,实现对“单位类别、单位、通知推送、投票信息、用户回复”等内容的全流程管理,广泛适用于教育局、高校及下属组织的信息管理工作。 🎯 项目亮点&…...
如何减少锁竞争并细化锁粒度以提高 Rust 多线程程序的性能?
在并发编程中,锁(Lock)是一种常用的同步机制,用于保护共享数据免受多个线程同时访问造成的竞态条件(Race Condition)。然而,不合理的锁使用会导致严重的性能瓶颈,特别是在高并发场景…...
【人工智能agent】--dify通过mcp协议调用工具
MCP Client 发起工具调用的实体,也就是 Dify 工作流或 Agent。它通过 Dify 平台提供的标准化接口(工具节点)来请求服务。 MCP Server / Host 提供实际服务的端点。在这个例子中,就是模拟 API 服务器 上的各个API (/api/pump/st…...
Review --- Redis
Redis redis是什么? Redis是一个开源的,使用C语言编写的,支持网络交互的,key-value数据结构存储系统,支持多种语言的一种非关系型数据库,它可以用作数据库(存储一些简单的数据,例如新闻点赞量),**缓存(秒…...
Sql刷题日志(day8)
一、笔试 1、right:提取字符串右侧指定数量的字符 right(string,length) /*string:要操作的字符串。length:要从右侧提取的字符数 */ 2、curdate():返回当前日期,格式通常为 YYYY-MM-DD 二、面试 1、自变量是不良体验反馈,因…...
【Science Advances】普林斯顿大学利用非相干光打造可重构纳米光子神经网络
(导读 ) 人工智能对计算性能需求剧增,电子微处理器发展受功耗限制。光学计算有望解决这些问题,光学神经网络(ONNs)成为研究热点,但现有 ONNs 因设计缺陷,在图像分类任务中精度远低于现代电子神经网络&#…...
2025-05-07 Unity 网络基础8——UDP同步异步通信
文章目录 1 UDP 概述1.1 通信流程1.2 TCP 与 UDP1.3 UDP 分包1.4 UDP 黏包 2 同步通信2.1 服务端2.2 客户端2.3 测试 3 异步通信3.1 Bgin / End 方法3.2 Async 方法 1 UDP 概述 1.1 通信流程 客户端和服务端的流程如下: 创建套接字 Socket。用 Bind() 方法将套…...
K8S - 金丝雀发布实战 - Argo Rollouts 流量控制解析
一、金丝雀发布概述 1.1 什么是金丝雀发布? 金丝雀发布(Canary Release)是一种渐进式部署策略,通过逐步将生产流量从旧版本迁移至新版本,结合实时指标验证,在最小化风险的前提下完成版本迭代。其核心逻辑…...
手持小风扇方案解说---【其利天下技术】
春去夏来,酷暑时节,小风扇成为外出必备的解暑工具,近年来,随着无刷电机的成本急剧下降,小风扇也逐步从有刷变无刷化了。 数量最大的如一箱无刷马达,其次三相低压无刷电机也大量被一些中高端风扇大量采用。…...
Qt开发:枚举的介绍和使用
文章目录 一、概述二、Qt 中定义和使用枚举2.1 普通枚举的定义方式2.2 使用枚举 三、配合 Qt 元对象系统使用枚举3.1 使用 Q_ENUM(Qt 5.5 及以上)3.2 示例:枚举值转字符串3.4 示例:字符串转枚举值 四、枚举与字符串相互转换五、枚…...
HarmonyOS运动开发:如何集成百度地图SDK、运动跟随与运动公里数记录
前言 在开发运动类应用时,集成地图功能以及实时记录运动轨迹和公里数是核心需求之一。本文将详细介绍如何在 HarmonyOS 应用中集成百度地图 SDK,实现运动跟随以及运动公里数的记录。 一、集成百度地图 SDK 1.引入依赖 首先,需要在项目的文…...
“胖都来”商标申请可以通过注册不!
近日“胖都来”被网友认为是蹭“胖东来”品牌流量在互联网上引起争议,看到许多自媒体说浙江这家公司已拿到“胖都来”的注册商标,普推知产商标老杨经检索后发现是没有的,只是申请受理。 对于商城类主要类别是在35类广告销售,核心是…...
【Django】中间件
Django 中间件是 Django 框架里一个轻量级、可插拔的组件,它能在全局范围内对 Django 的请求和响应进行处理。中间件处于 Django 的请求处理流程之中,在请求抵达视图函数之前以及视图函数返回响应之后执行特定操作。以下是关于 Django 中间件的详细介绍&…...
电子电器架构 --- 48V架构的一丢丢事情
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
什么是Blender?怎么获取下载Blender格式文件模型
glbxz.com glbxz.com 官方可以下载Blender格式文件模型 BlenderBlender 是一个免费的开源程序,用于建模和动画,最初由一家名为 Neo Geo 的动画工作室作为内部应用程序开发,后来作为自己的程序发布。这是一个称职的程序,近年来由于…...
Ubuntu安装pgsql
一、通过 APT 安装(推荐) 更新软件包列表 sudo apt update 安装 PostgreSQL 核心包及工具 sudo apt install postgresql postgresql-client postgresql-contrib • postgresql:数据库服务端 • postgresql-client:命令行…...
Qwen2-VL详解
一、引言 在人工智能领域,多模态大模型的发展备受关注。Qwen2-VL 作为一款先进的多模态模型,致力于克服现有方法在处理图像和视频数据时存在的不足,显著提升多模态信息的理解与交互能力。本文将全面且深入地阐述 Qwen2-VL 的创新理念、精妙的模型架构、严谨的训练流程、卓越…...
定长滑动窗口---初阶篇
目录 滑动窗口核心思想 定长滑动窗口套路 定长滑动窗口习题剖析 1456. 定长子串中元音的最大数目 643. 子数组最大平均数 I 1343. 大小为 K 且平均值大于等于阈值的子数组数目 2090. 半径为 k 的子数组平均值 2379. 得到 K 个黑块的最少涂色次数 2841. 几乎唯一子数组…...
以pytest_addoption 为例,讲解pytest框架中钩子函数的应用
钩子函数(Hook Function)的概念 钩子函数(Hook Function)是软件框架中预定义的回调接口,允许开发者在程序执行的特定阶段插入自定义逻辑,以扩展或修改框架的默认行为。在 pytest 中,钩子函数覆…...
数据智能重塑工业控制:神经网络在 MPC 中的四大落地范式与避坑指南
一、引言:工业控制的范式革命 在工业 4.0 的浪潮中,传统基于物理模型的控制方法(如 PID、线性二次型调节器 LQR)正面临前所未有的挑战。以石化行业为例,某炼油厂的催化裂化装置(FCCU)因反应机理…...
AB测试面试题
AB测试面试题 常考AB测试问答题(1)AB测试的优缺点是什么?(2)AB测试的一般流程/介绍一下日常工作中你是如何做A/B实验的?(3)第一类错误 vs 第二类错误 vs 你怎么理解AB测试中的第一、二类错误?(4)统计显著=实际显著?(5)AB测试效果统计上不显著?(6)实验组优于对…...
phpstudy升级新版apache
1.首先下载要升级到的apache版本,这里apache版本为Apache 2.4.63-250207 Win64下载地址:Apache VS17 binaries and modules download 2.将phpstudy中原始apache复制备份Apache2.4.39_origin 3.将1中下载apache解压, 将Apache24复制一份到ph…...
民宿管理系统6
普通管理员管理: 新增普通管理员: 前端效果: 前端代码: <body> <div class"layui-fluid"><div class"layui-row"><div class"layui-form"><div class"layui-f…...
【iOS】源码阅读(三)——内存对齐原理
文章目录 前言获取内存大小的三种常用方式sizeofclass_getInstanceSizemalloc_size 总结 前言 之前学习alloc相关源码,涉及到内存对齐的相关内容,今天笔者详细学习了一下相关内容并写了此篇博客。 获取内存大小的三种常用方式 获取内存大小的方式有很多…...
在 Ubuntu 中配置 Samba 实现「特定用户可写,其他用户只读」的共享目录
需求目标 所有认证用户可访问 Samba 共享目录 /path/to/home;**仅特定用户(如 developer)**拥有写权限;其他用户仅允许读取;禁止匿名访问。 配置步骤 1. 设置文件系统权限 将目录 /home3/guest 的所有权设为 develo…...
配置指定地址的conda虚拟Python环境
创建指定路径的 Conda 环境 在创建环境时,使用 --prefix 参数指定自定义路径: conda create --prefix/your/custom/path/my_env python3.8 说明: /your/custom/path/my_env:替换为你希望存放环境的路径(如 D:\projec…...