[操作系统] 进程地址空间管理
虚拟地址空间的初始化
缺页中断
缺页中断的概念
缺页中断(Page Fault Interrupt) 是指当程序访问的虚拟地址在页表中不存在有效映射(即该页未加载到内存中)时,CPU 会发出一个中断信号,请求操作系统加载所需的页面到内存。
这是现代操作系统实现 虚拟内存管理 的重要机制之一。
缺页中断的触发条件
缺页中断通常在以下情况下触发:
- 虚拟地址对应的页面不在内存中:
- 页表中找不到对应的物理页帧(页表条目为空或无效)。
- 常见于程序访问未加载到内存的代码段或数据段。
- 访问非法地址:
- 程序试图访问一个不存在的虚拟地址(如超出地址空间范围)。
- 操作系统会判断访问是否合法,非法访问将触发异常。
缺页中断的处理流程
以下是缺页中断的详细处理流程:
- 程序访问虚拟地址:
- CPU 将虚拟地址拆分为页号和页内偏移量,根据页号查询页表。
- 检测页表:
- 如果页表中没有找到对应的物理页帧(即页表项无效),触发缺页中断。
- 陷入内核:
- 缺页中断引发陷入操作系统内核,操作系统负责处理。
- 检查页面是否合法:
- 操作系统检查虚拟地址是否属于当前进程的合法地址范围:
- 如果地址非法(如访问未分配的堆空间),操作系统会终止进程,抛出段错误(Segmentation Fault)。
- 如果合法,进入下一步。
- 操作系统检查虚拟地址是否属于当前进程的合法地址范围:
- 分配页面:
- 操作系统为该虚拟页分配物理页帧。
- 如果内存不足,则触发页面置换算法(如LRU、FIFO),将某些页面换出到硬盘(即交换分区或页面文件)。
- 加载页面:
- 如果访问的页面是磁盘文件的一部分(如代码或数据),则将页面从磁盘加载到内存。
- 将分配的物理页帧的地址填入页表,并将页表项标记为有效。
- 恢复程序执行:
- 操作系统返回用户态,重新执行导致缺页的指令。
- 由于页面已加载到内存,访问可以正常完成。
缺页中断的示例
假设一个程序试图访问数组元素,但数组较大,未全部加载到内存。以下是可能的情景:
int arr[100000]; // 数组在内存中未完全加载
for (int i = 0; i < 100000; i++) {arr[i] = i; // 顺序访问
}
- 程序首次访问
arr[i]
时,CPU 查询页表,发现对应的虚拟页面未映射到物理内存,触发缺页中断。 - 操作系统加载对应页面到内存,并更新页表。
- 下一次访问已加载的页面时,程序可以直接读取,无需触发缺页中断。
示例总结
当一个应用程序数据过大的话,不会立即将所有的数据全部从硬盘上加载到物理内存中,会先加载一部分。但是在进程的虚拟地址空间中会将所有的数据对应的地址全部建立。于是当需要使用一个虚拟地址空间的时候会在页表中进行查找映射的物理地址,但是没有物理地址,还未加载进内存中。操作系统会动态加载数据,当需要的时候再申请物理空间,加载数据,然后建立映射关系。
即使加载到物理内存的数据是乱序存储的,通过页表的映射关系也可以进行有序的管理。
虚拟地址空间初始化
虚拟地址空间就是mm_struct
,在task_struct
中。作为对象,需要被初始化。
当一个新进程被创建(例如通过 fork
或 exec
系统调用)时,操作系统会:
- 创建虚拟地址空间:
- 为进程分配独立的虚拟地址空间,确保不同进程之间的地址空间隔离。
- 设置页表:
- 页表初始状态为“未映射”(即页面不在物理内存中),以支持按需加载。
- 加载程序的基础信息:
- 通过程序文件(如 ELF 文件)中的头部信息,划分代码段、数据段等区域。
- 堆区和栈区只初始化元信息(如起始地址),实际分配时动态增长。
- 所以大部分会在程序加载的时候就被初始化。
为什么要有进程地址空间
将地址从无需变有序
数据从磁盘加载到物理内存是动态加载的,顺序会变得无规则,甚至乱序。但是有了虚拟地址空间和页表,虚拟地址空间中各个区域的地址是有序的,然后通过页表进行映射,找到无序的物理内存地址,从而将物理地址进行有序管理。
地址转换时的合法性判定
当地址转换的时候,通过虚拟地址空间和页表可以对地址和操作进行合法性判定,防止直接操作物理内存造成损坏,进而保护物理内存。
页表中对于每一个映射关系也会有权限(rwx...
)存在,当进程又不合法操作的时候,操作系统会拒绝地址映射转换,甚至杀死进程。
野指针
从操作系统层面理解野指针:
- 未初始化指针与页表:当一个指针未初始化时,它指向的虚拟地址是随机的。这个随机地址很可能在页表中没有对应的映射项。因为正常的内存分配(如通过
malloc
、new
等操作)会由操作系统分配一段合法的虚拟地址,并在页表中建立映射。而未初始化的指针所指向的地址没有经过这样的分配过程,所以在页表中找不到对应的物理地址。 - 已释放指针与页表:指针所指向的内存被释放后,操作系统会将这块内存对应的页表项标记为未使用或者分配给其他进程。如果继续使用这个指针访问内存,操作系统在查找页表时会发现这个虚拟地址对应的页表项已经不再有效。例如,一个动态分配的内存块被
delete
或free
后,它所占用的虚拟地址范围在页表中的映射会被撤销或者改变,再次访问这个地址就会引发错误。 - 越界指针与页表:当指针越界时,它可能会指向虚拟地址空间中未分配的区域。比如,一个数组指针越界后指向了数组之外的地址,这个地址可能超出了操作系统为该数组分配的合法虚拟地址范围。在页表中,这个越界的地址没有合法的物理地址映射,因为操作系统只会在合法的内存分配范围内建立页表映射。
- 错误赋值指针与页表:如果指针被错误地赋值为一个非法的地址,这个地址在页表中很可能没有对应的映射。因为操作系统在进行正常的内存分配时,会确保分配的虚拟地址在页表中有合法的映射。而人为错误地给指针赋一个非法地址,打破了这种正常的映射关系。
查页表失败后,会反馈给操作系统,操作系统会处理进程,所以野指针会导致操作系统杀死进程,导致进程崩溃。
字符串常量为什么无法修改
常量字符串字面量(如<font style="color:rgb(6, 6, 7);">char* ptr = "Hello, World!"</font>
)通常被存储在代码段(Text Segment)中。这是因为常量字符串在程序的整个运行过程中不需要修改,将它们放在代码段可以利用代码段的只读特性来保护这些字符串不被意外修改。
这就是在地址转换的时候权限拒绝了对数据的写操作,所以无法修改。
解耦合!
简单回顾一下程序加载进内存的过程:
- 在虚拟地址空间申请指定大小的空间(调整区域划分)。
- 加载程序,申请物理空间。
- 在页表中进行虚拟地址和物理地址的映射构建。
完成后,此时的物理地址就转化为了虚拟地址。提供给上层使用,用户无需关心底层的物理地址是什么,物理内存中是如何加载的,只是使用虚拟地址就可以了。
作为进程也只是关心对于虚拟地址的使用,而不关心实际物理内存的存储。
如图所示。task_struct
和其中管理的mm_struct
所形成的关系对于进程来说只是负责进程的调度,而不关心如何管理调度的数据存储和加载。
而对于物理内存部分来说,只进行内存的管理,加载物理内存。
二者通过页表的映射关系来解耦合,让进程管理和内存管理进行一定程度的解耦合!
Tips
- 可以不加载代码和数据,只加载
task_struct
,mm_struct
(只拿到main
代码的起始地址),页表。
CPU在拿到起始地址后,当访问虚拟地址时,会有标识证明没有加载过物理内存,所以会缺页中断,然后开始加载物理内存。
- 创建进程的时候,先有
task_struct
,mm_struct
等,还是先加载代码和数据?
先有内核数据结构,然后再陆续加载物理内存。
- 如何理解进程挂起?
进程进入挂起状态时,操作系统找到对应的进程,清空页表的物理地址部分,将物理地址对应的数据全部换入磁盘swap
分区。只保留虚拟地址空间中的虚拟地址和页表的虚拟地址部分。
当挂起状态结束时,将swap
分区的数据全部换出加载到物理内存中,然后再页表中建立映射。这就是解耦的好处,将进程调度与内存管理完全解耦。
vm_area_struct
对于在程序中动态申请的空间来说,一般会申请在堆区中。但是在程序中可能会频繁的申请,难道对于虚拟地址空间中的堆区来说,不只有一个起始地址吗?可能是离散分布的吗?
虚拟空间的组织⽅式有两种:
- 当虚拟区较少时采取单链表,由mmap指针指向这个链表;
- 当虚拟区间多时采取红⿊树进⾏管理,由mm_rb指向这棵树。
mm_struct
并不是直接就是整个虚拟地址空间,而是包含了一个指向虚拟内存区域(VMA)列表的指针,这个列表是由 vm_area_struct
组成的。每个 vm_area_struct
表示进程地址空间中的一个连续区域,具有相同的权限和映射类型。所以离散申请的堆空间可以用vm_area_struct
进行管理,并且所有的区域都可以统一使用vm_area_struct
进行管理。
为了高效查找区域,所以用红黑树来进行管理——
struct rb_root mm_rb
。
struct mm_struct {// ... 其他成员 ...struct vm_area_struct *mmap; // 指向虚拟内存区域列表的指针struct rb_root mm_rb; // 红黑树,用于快速查找虚拟内存区域// ... 其他成员 ...
};
struct vm_area_struct {struct mm_struct *vm_mm; // 指向所属进程的mm_structunsigned long vm_start; // 虚拟内存区域的起始地址unsigned long vm_end; // 虚拟内存区域的结束地址pgprot_t vm_page_prot; // 页面保护标志unsigned long vm_flags; // 标志位,如VM_READ, VM_WRITE等// ... 其他成员,如链表指针、红黑树节点等 ...
};
因为存在vm_area_struct
这个数据结构,即使堆区频繁申请,但是每一段申请的空间都可以使用vm_area_struct
来进行管理,最后用建表进行管理所有的vm_area_struct
,在mm_struct
中用*mmap
作为链表的头指针。
进程地址空间管理(总结)
关于进程地址空间整体的管理结构如上图所示(虚拟区间较少情况下)。
task_struct
管理整体进程,其中包括管理进程地址空间的mm_struct
。在虚拟区间较少的情况下用在mm_struct
中的vm_area_struct *mmap;
指向由vm_area_struct
链接而成的链表。每个vm_area_struct
对应一段虚拟区间,而对于堆这种可能频繁申请的来说,堆这个区间会由多个vm_area_struct
组成,而其他的区域使用一个vm_area_struct
管理即可。
为什么要有进程地址空间(总结)
在早期的计算机中,程序直接操作物理内存,所有内存地址都是物理地址。当同时运行多个程序时,内存管理必须确保程序使用的内存总量小于物理内存。然而,这种直接操作物理内存的方式存在以下问题:
安全风险
- 直接操作物理内存允许每个进程访问任意内存空间。
- 恶意程序(如木马病毒)可以随意修改系统内存区域,导致设备瘫痪。
地址不确定性
- 编译完成的程序存储在硬盘上,运行时需加载到内存。
- 由于内存分配动态变化,程序的物理内存地址在不同运行时可能不同。
- 例如:第一次运行时,程序加载到地址
0x00000000
; - 第二次运行时,内存已被占用,加载地址可能变为其他位置。
- 例如:第一次运行时,程序加载到地址
效率低下
- 使用物理内存时,进程以整体内存块操作。
- 当物理内存不足时,将进程从内存拷贝到磁盘(交换分区)需要拷贝整个进程,耗时较长,效率低下。
虚拟地址空间与分页机制的优势
1. 内存安全
- 地址空间和页表由操作系统创建和维护。
- 所有地址空间和页表映射必须经过操作系统监管。
- 保护物理内存中的合法数据,防止非法访问。
2. 地址灵活性
- 地址空间和页表映射机制允许物理内存中的数据以任意位置加载。
- 内存分配与进程管理解耦,进程不再直接依赖物理内存地址。
3. 延迟分配
- 在C/C++中,通过
new
或malloc
申请的空间实际上分配在虚拟地址空间。 - 物理内存分配延迟到真正访问内存时执行。
- 操作系统自动完成内存分配和页表映射,用户或进程无需感知。
4. 提高效率
- 程序在物理内存中的加载可以是任意位置,通过页表实现虚拟地址与物理地址的映射。
- 虚拟地址空间使得进程内存分布在逻辑上保持有序,简化了程序管理。
总结
虚拟地址空间通过操作系统的地址空间管理和页表机制,解决了直接操作物理内存带来的安全性、灵活性和效率问题,使得内存管理更安全、更高效,同时简化了程序开发与运行。
相关文章:
[操作系统] 进程地址空间管理
虚拟地址空间的初始化 缺页中断 缺页中断的概念 缺页中断(Page Fault Interrupt) 是指当程序访问的虚拟地址在页表中不存在有效映射(即该页未加载到内存中)时,CPU 会发出一个中断信号,请求操作系统加载所…...
【fly-iot飞凡物联】(20):2025年总体规划,把物联网整套技术方案和实现并落地,完成项目开发和课程录制。
前言 fly-iot飞凡物联专栏: https://blog.csdn.net/freewebsys/category_12219758.html 1,开源项目地址进行项目开发 https://gitee.com/fly-iot/fly-iot-platform 完成项目开发,接口开发。 把相关内容总结成文档,并录制课程。…...
14-6-1C++STL的list
(一)list容器的基本概念 list容器简介: 1.list是一个双向链表容器,可高效地进行插入删除元素 2.list不可以随机存取元素,所以不支持at.(pos)函数与[ ]操作符 (二)list容器头部和尾部的操作 list对象的默…...
vue2和vue3指令
Vue 2 和 Vue 3 的指令系统非常相似,但 Vue 3 在指令方面进行了优化和扩展。以下是 Vue 2 和 Vue 3 中指令的对比: 1. 通用指令 这些指令在 Vue 2 和 Vue 3 中都可以使用,功能一致: 指令说明v-bind绑定 HTML 属性或组件 propsv-…...
求整数的和与均值(信息学奥赛一本通-1061)
【题目描述】 读入n(1≤n≤10000)个整数,求它们的和与均值。 【输入】 输入第一行是一个整数n,表示有n个整数。 第2~n1行每行包含1个整数。每个整数的绝对值均不超过10000。 【输出】 输出一行,先输出和,再输出平均值(保留到小数点…...
CodeForces 611:New Year and Domino ← 二维前缀和
【题目来源】 https://codeforces.com/contest/611/problem/C 【题目描述】 They say "years are like dominoes, tumbling one after the other". But would a year fit into a grid? I dont think so. Limak is a little polar bear who loves to play. He has r…...
【ROS2】RViz2界面类 VisualizationFrame 详解
1、简述 VisualizationFrame 继承自 QMainWindow 和 WindowManagerInterface; 窗口顶部是常规布局:菜单栏 和 工具栏 窗口中心是 RenderPanel,用来渲染3D画面 周围是dock区域,包括:DisplaysPanel、ViewsPanel、TimePanel、SelectionPanel 和 ToolPropertiesPanel Windo…...
梯度下降法 (Gradient Descent) 算法详解及案例分析
梯度下降法 (Gradient Descent) 算法详解及案例分析 目录 梯度下降法 (Gradient Descent) 算法详解及案例分析1. 引言2. 梯度下降法 (Gradient Descent) 算法原理2.1 基本概念2.2 算法步骤2.3 梯度下降法的变种3. 梯度下降法的优势与局限性3.1 优势3.2 局限性4. 案例分析4.1 案…...
【Flutter】旋转元素(Transform、RotatedBox )
这里写自定义目录标题 Transform旋转元素可以改变宽高约束的旋转 - RotatedBox Transform旋转元素 说明:Transform旋转操作改变了元素的方向,但并没有改变它的布局约束。因此,虽然视觉上元素看起来是旋转了,但它仍然遵循原始的宽…...
大数运算之C语言实现
一、 前言 在我们代码编程过程中,我们经常需要处理各种规模的数值。从日常工作中的一些简单算术在到科学研究中的复杂计算,数字无处不在。然而,当数值变的异常庞大时,就需要用到大数运算来进行实现。本文我们将介绍大数运算的基本…...
三高“高性能、高并发、高可靠”系统架构设计系列文章
目录 高并发系统的艺术:如何在流量洪峰中游刃有余 《数据密集型应用系统设计》读后感与高并发高性能实践案例 系统稳定性与高可用保障的几种思路 软件系统限流的底层原理解析 技术解决方案调研 延迟队列调研 重试调研 异步回调调研 分库分表调研 分布式事…...
Java设计模式 十八 状态模式 (State Pattern)
状态模式 (State Pattern) 状态模式是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。状态模式让一个对象在其状态改变时,其行为也随之改变,看起来就像是改变了对象的类。通过将状态的变化封装到不同的状态对象中,…...
Django创建纯净版项目并启动
1.Django的基本目录结构 2. 创建app项目 python manage.py startapp user# python manage.py 是固定的,代表python脚本,主要用于django中的项目管理 # startapp 创建app # user 你的app名字,也就是功能模块名称3.数据库 进入settings.…...
[b01lers2020]Life on Mars1
打开题目页面如下 看了旁边的链接,也没有什么注入点,是正常的科普 利用burp suite抓包,发现传参 访问一下 http://5edaec92-dd87-4fec-b0e3-501ff24d3650.node5.buuoj.cn:81/query?searchtharsis_rise 接下来进行sql注入 方法一…...
element-plus 的table section如何实现单选
如果是单选那么全新的按钮应该隐藏或者不可编辑的状态。但是我没找到改变成不可编辑的方法,只能采取隐藏 <template><!-- 注意要包一层div根元素,否则css样式可能会不生效,原因不详 --><div><el-table ref"proTab…...
利用Qt5.15.2编写Android程序时遇到的问题及解决方法
文章目录 背景1.文件读写 背景 目前我用的是Qt5.15.2来编写Qt程序,环境的配置看我这篇文章【Qt5.15.2配置Android开发环境】 项目中的一些配置的截图: 1.文件读写 假如直接用 QFileDialog::getExistingDirectory来获取路径的话,会得到类…...
奇怪的单词(快速扩张200个单词)
这是一些非常奇怪的单词: screw n.螺丝;螺丝钉 screwdriver n.起子,螺丝刀,改锥 copulation n.连接 copulate a.配合的 bonk n.撞击;猛击 v.轻击;碰撞ebony n.黑檀couple n.夫妇blonde n.金发女郎intimacy…...
three.js+WebGL踩坑经验合集(4.1):THREE.Line2的射线检测问题(注意本篇说的是Line2,同样也不是阈值方面的问题)
上篇大家消化得如何了? 笔者说过,1级编号不同的两篇博文相对独立,所以这里笔者还是先给出完整代码,哪怕跟(3)没有太大区别。 这里我们把线的粗细调成5(排除难选中的因素)ÿ…...
postgresql根据主键ID字段分批删除表数据
生产环境针对大表的处理相对比较麻烦。 方案1、直接truncate,可能会遇到系统卡主的情况,因为truncate的过程中会对表进行加锁,会导致数据不能正常的写入 方案2、创建一个同结构的表结构,rename旧表,不停业务rename表担…...
NIO 和 Netty 在 Spring Boot 中的集成与使用
Netty到底是个啥,有啥子作用 1. Netty 的本质:对 NIO 的封装 NIO 的原生问题: Java 的 NIO 提供了非阻塞 I/O 和多路复用机制,但其使用较为复杂(如 Selector、Channel、Buffer 的配置和管理)。开发者需要自…...
【AI论文】Sigma:对查询、键和值进行差分缩放,以实现高效语言模型
摘要:我们推出了Sigma,这是一个专为系统领域设计的高效大型语言模型,其独特之处在于采用了包括DiffQKV注意力机制在内的新型架构,并在我们精心收集的系统领域数据上进行了预训练。DiffQKV注意力机制通过根据查询(Q&…...
ThinkPHP 8请求处理-获取请求对象与请求上下文
【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用Composer初始化ThinkPHP 8应用_thinkphp8 compos…...
【设计模式】JAVA 策略 工厂 模式 彻底告别switch if 等
【设计模式】JAVA 策略 工厂 模式 彻底告别switch if 等 目录 【设计模式】JAVA 策略 工厂 模式 彻底告别switch if 等 优势 适用场景 项目结构 关键代码 优势 消除 switch:将分支逻辑分散到独立的策略类中。 开闭原则:新增类型只需添加新的 TypeHa…...
Pyecharts之词云图、面积图与堆叠面积图
在数据可视化的精彩世界里,我们可以运用各种各样的图表来展现数据的魅力,帮助我们更好地理解和分析数据。Pyecharts 作为一款功能强大的数据可视化工具,为我们提供了丰富的图表类型,今天我们将深入探讨词云图、面积图和堆叠面积图…...
SpringBoot3+Vue3开发学生选课管理系统
功能介绍 分三个角色登录:学生登录,老师登录,教务管理员登录,不同用户功能不同! 1.学生用户功能 选课记录,查看选课记录,退选。选课管理,进行选课。通知管理,查看通知消…...
71.在 Vue 3 中使用 OpenLayers 实现按住 Shift 拖拽、旋转和缩放效果
前言 在前端开发中,地图功能是一个常见的需求。OpenLayers 是一个强大的开源地图库,支持多种地图源和交互操作。本文将介绍如何在 Vue 3 中集成 OpenLayers,并实现按住 Shift 键拖拽、旋转和缩放地图的效果。 实现效果 按住 Shift 键&#…...
Mybatis——sql映射文件中的增删查改
映射文件内的增删查改 准备工作 准备一张数据表,用于进行数据库的相关操作。新建maven工程, 导入mysql-connector-java和mybatis依赖。新建一个实体类,类的字段要和数据表的数据对应编写接口编写mybatis主配置文件 public class User {priva…...
Git进阶笔记系列(01)Git核心架构原理 | 常用命令实战集合
读书笔记:卓越强迫症强大恐惧症,在亲子家庭、职场关系里尤其是纵向关系模型里,这两种状态很容易无缝衔接。尤其父母对子女、领导对下属,都有望子成龙、强将无弱兵的期望,然而在你的面前,他们才是永远强大的…...
立创开发板入门ESP32C3第八课 修改AI大模型接口为deepseek3接口
#原代码用的AI模型是minimax的API接口,现在试着改成最热门的deepseek3接口。# 首先按理解所得,在main文件夹下,有minimax.c和minimax.h, 它们是这个API接口的头文件和实现文件,然后在main.c中被调用。所以我们一步步更改。 申请…...
【云安全】云原生-Docker(五)容器逃逸之漏洞利用
漏洞利用逃逸 通过漏洞利用实现逃逸,主要分为以下两种方式: 1、操作系统层面的内核漏洞 这是利用宿主机操作系统内核中的安全漏洞,直接突破容器的隔离机制,获得宿主机的权限。 攻击原理:容器本质上是通过 Linux 的…...
为什么IDEA提示不推荐@Autowired❓️如果使用@Resource呢❓️
前言 在使用 Spring 框架时,依赖注入(DI)是一个非常重要的概念。通过注解,我们可以方便地将类的实例注入到其他类中,提升开发效率。Autowired又是被大家最为熟知的方式,但很多开发者在使用 IntelliJ IDEA …...
PHP:动态网站开发的强大引擎
在互联网技术日新月异的今天,PHP(Hypertext Preprocessor,超文本预处理器)作为一种开源的服务器端脚本语言,凭借其灵活性和易用性,依然是构建动态网站和Web应用程序的首选之一。从简单的个人博客到复杂的企…...
Linux 目录操作详解
Linux目录操作详解 1. 获取当前工作目录1.1 getcwd()1.2 get_current_dir_name() 2. 切换工作目录2.1 chdir() 3. 创建和删除目录3.1 mkdir()3.2 rmdir() 4. 获取目录中的文件列表4.1 opendir() 打开目录4.2 readdir() 读取目录内容4.3 closedir() 关闭目录 5. dirent 结构体6.…...
IMX6ull项目环境配置
文件解压缩: .tar.gz 格式解压为 tar -zxvf .tar.bz2 格式解压为 tar -jxvf 2.4版本后的U-boot.bin移植进SD卡后,通过串口启动配置开发板和虚拟机网络。 setenv ipaddr 192.168.2.230 setenv ethaddr 00:04:9f:…...
redis实现lamp架构缓存
redis服务器环境下mysql实现lamp架构缓存 ip角色环境192.168.242.49缓存服务器Redis2.2.7192.168.242.50mysql服务器mysql192.168.242.51web端php ***默认已安装好redis,mysql 三台服务器时间同步(非常重要) # 下载ntpdate yum -y install…...
与机器学习相关的概率论重要概念的介绍和说明
概率论一些重要概念的介绍和说明 1、 试验 (1)试验是指在特定条件下,对某种方法、技术、设备或产品(即,事物)进行测试或验证的过程。 (2)易混淆的概念是,实验。实验&…...
深度学习 Pytorch 单层神经网络
神经网络是模仿人类大脑结构所构建的算法,在人脑里,我们有轴突连接神经元,在算法中,我们用圆表示神经元,用线表示神经元之间的连接,数据从神经网络的左侧输入,让神经元处理之后,从右…...
常用集合-数据结构-MySql
目录 java核心: 常用集合与数据结构: 单例集合: 双列集合: 线程安全的集合: ConcurrentHashMap集合: HashTable集合: CopyOnWriteArrayList集合: CopyOnWriteArraySet集合: ConcurrentLinkedQueue队列: ConcurrentSkipListMap和ConcurrentSkipListSet&…...
策略模式 - 策略模式的使用
引言 在软件开发中,设计模式是解决常见问题的经典解决方案。策略模式(Strategy Pattern)是行为型设计模式之一,它允许在运行时选择算法的行为。通过将算法封装在独立的类中,策略模式使得算法可以独立于使用它的客户端…...
【贪心算法】在有盾牌的情况下能通过每轮伤害的最小值(亚马逊笔试题)
思路: 采用贪心算法,先计算出来所有的伤害值,然后再计算每轮在使用盾牌的情况下能减少伤害的最大值,最后用总的伤害值减去能减少的最大值就是最少的总伤害值 public static long getMinimumValue(List<Integer> power, int…...
零基础Vue学习1——Vue学习前环境准备
目录 环境准备 创建Vue项目 项目目录说明 后续开发过程中常用命令 环境准备 安装开发工具:vscode、webstorm、idea都可以安装node:V22以上版本即可安装pnpm 不知道怎么安装的可以私信我教你方法 创建Vue项目 本地新建一个文件夹,之后在文件夹下打开…...
小游戏源码开发搭建技术栈和服务器配置流程
近些年各种场景小游戏开发搭建版本层出不穷,山东布谷科技拥有多年海内外小游戏源码开发经验,现为从事小游戏源码开发或游戏运营的朋友们详细介绍小游戏开发及服务器配置流程。 一、可以对接到app的小游戏是如何开发的 1、小游戏源码开发的需求分析: 明…...
【Rust自学】15.3. Deref trait Pt.2:隐式解引用转化与可变性
喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 15.3.1. 函数和方法的隐式解引用转化(Deref Coercion) 隐式解引用转化(Deref Coercion)是为…...
SQL-leetcode—1174. 即时食物配送 II
1174. 即时食物配送 II 配送表: Delivery ------------------------------------ | Column Name | Type | ------------------------------------ | delivery_id | int | | customer_id | int | | order_date | date | | customer_pref_delivery_date | date | -------------…...
css3 svg制作404页面动画效果HTML源码
源码介绍 css3 svg制作404页面动画效果HTML源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果 效果预览 源码如下 <!doctype html> <html> <head> <meta charse…...
MATLAB提供的颜色映射表colormap——伪彩色
图像处理领域的一个习惯:不是真实的颜色,一般用伪彩色。一是说明不是物体本身的颜色,二是彩色更容易分辨。 MATLAB陆续提供了16种颜色映射表colormap。 之前的都很丑,近5年新增的4种还可以。总的说来还是丑。 这是一种鸟的名字。…...
2013年蓝桥杯第四届CC++大学B组真题及代码
目录 1A:高斯日记(日期计算) 2B:马虎的算式(暴力模拟) 3C:第39级台阶(dfs或dp) 4D:黄金连分数(递推大数运算) 5E:前缀…...
我的创作纪念日——1/23
机缘 想起写博客,其实是当时看鹏哥C语言时,他说通过写博客的方式来记录自己学习过程,有利于提升自己。尽管我只看了几集就没怎么看,但是写博客的习惯保留下来。 至于为什么,一方面单纯当作单个代码库,把自…...
C# Interlocked 类使用详解
总目录 前言 在多线程编程中,确保多个线程对共享资源的安全访问是一个关键挑战。C# 提供了多种同步机制来处理并发问题,其中 System.Threading.Interlocked 类提供了一种轻量级的方法来进行原子操作。它允许您执行一些常见的增量、减量、交换等操作&…...
SYN Flooding的攻击原理
SYN Flooding是一种常见的网络攻击方式,属于拒绝服务攻击(DoS)的一种,其攻击原理主要是利用了TCP协议的三次握手过程,以下是具体介绍: TCP三次握手正常流程 第一次握手:客户端向服务器发送一个…...