尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
可执行文件装载与进程:虚拟地址空间和按需调页深度解析
十几年前第一次接触《程序员的自我修养》第六章我还是个只会把代码写“通”的初学者能编译、能运行但一旦被问到“你按下运行之后操作系统到底对你的可执行文件做了什么”脑子里基本是一片空白。第六章“可执行文件的装载与进程”就是在回答这个问题而且回答得相当透彻。读完全章上我有种之前写了个寂寞的感觉——原来一个进程被创建出来、被装进内存、开始执行第一条指令这中间隔着这么多环环相扣的机制进程映像、虚拟地址空间、段装载、页映射、缺页异常。这篇心得就是把我自己啃完这一章之后梳理清楚的东西用比较口语化、不绕弯的方式记下来。适合刚看完书但有点晕的人也适合还没看书、想先搞清楚“装载到底解决什么问题”的人。我会尽量把书里的内容拆碎、加进我自己实测踩到的细节让这篇既是复习笔记也是延伸理解。1. 先想明白一件事程序为什么要“装载”才能跑起来我们平时说的“运行一个程序”大多数人第一反应是“把文件读进内存然后 CPU 执行里面的机器指令”。这个说法没全错但离真相差着十万八千里。可执行文件不是一个可以简单“读进内存”的块状数据它里面有多个结构完全不同的段代码段、数据段、BSS 段、只读数据段等每个段对内存的需求不一样有的要求可执行但不可写有的要求可读写但不可执行有的根本不需要占用文件空间但需要在内存里占一大块区域并初始化为零。如果不经过装载这个过程直接把整个文件原封不动地塞进内存你会面临一堆问题内存被白白浪费文件里可能有很多未初始化的零页不需要真实存储、段的权限属性没法精细化设置、程序在磁盘上的布局和在内存中的布局完全无法对齐。书里把这个过程总结得非常清楚——装载的本质是“建立可执行文件与进程虚拟地址空间的映射关系”。注意是“映射”不是“拷贝”。为什么这么强调因为在 Linux 这类现代操作系统上装载大量依赖虚拟内存和按需调页文件的内容并不是一开始就全部在物理内存里而是先告诉操作系统“这块虚拟内存对应文件的哪一段”真正访问到哪一页才把哪一页从磁盘读进物理内存。这个思路和“把文件完整读进内存再执行”是天壤之别。我当时读到这个观点时最大的收获是装载不是一次性动作而是持续性的、和 CPU 执行过程纠缠在一起的。你在终端敲下./a.out只是启动了一个装载流程并不代表程序已经被“完整装入”了它只是拿到了一个可以开始运行的地址空间骨架。真正的内容是在后续一条条指令的执行过程中、在一个个页面访问中被“懒加载”进来的。还有一个容易忽略的点可执行文件本身的格式和布局与装入内存后的进程映像布局并不是一回事。这就是“链接视图”和“装载视图”的差别。链接视图关心的是如何把多个目标文件合并成一个可执行文件里面充满节Section的概念装载视图关心的是运行时内存布局里面用的是段Segment和程序头Program Header。同一个文件一边是描述静态结构的节表一边是描述运行映射的程序头表两套视角并行存在。这个认知一旦建立起来后面看装载细节就不会被绕晕。2. 进程从无到有一条创建链路上的关键动作书上讲进程创建没有只停留在“它被创建了”这个结果而是把过程拆得很细。我从最终呈现出来的角度看一个程序要跑起来至少要经历下面这几层逻辑上的大动作。2.1 从镜像到地址空间找到那个“胚子”进程的起点不是一句“创建进程”的抽象口号而是先要在磁盘上找到一份可以作为胎儿的可执行文件。这个文件首先要被内核读取文件头确认它是不是当前操作系统能识别的格式然后解析里面的关键结构。以 ELF 为例内核要关注的第一个东西就是 ELF 头里的e_type、e_machine和程序头表的入口位置。这一步决定了一件事这个文件能不能在当前内核下被装载以及该从哪个偏移开始去找段的信息。这里我读出一个很有价值的点进程不是“凭空产生的”它本质上是“从可执行文件这个模板里实例化出来的一个运行时对象”。模板提供了代码段的内容、数据段的初始值、BSS 段的尺寸要求、入口地址等但模板本身并不等于进程。进程是模板 运行时资源地址空间、页表、内核数据结构、文件描述符等组合出来的结果。理解这一点是后续理解 fork、exec、写时复制等一切机制的前提。2.2 创建地址空间画一块“预留地”接下来是创建进程的虚拟地址空间。在 Linux 上这一阶段的核心是建立一个新的mm_struct它负责描述这个进程的虚拟内存全貌哪些区域是代码段映射过来的哪些区域是堆哪些是栈各自的起始地址和大小是多少。这一阶段并不会为程序的所有段立刻分配物理页而是先建立虚拟地址区域的描述信息把“这张地图”画出来。这个“先画地图、后建房子”的思路是整章理解的关键之一。操作系统非常珍惜物理内存不可能在进程一创建时就把文件的所有内容统统搬进内存。它是先建立虚拟地址范围和文件偏移的映射关系等 CPU 真正访问到某个虚拟地址、发生缺页异常时才去分配物理页并填充内容。这也是虚拟内存和按需分页让装载如此“轻量”的原因。2.3 初始化关键数据结构让内核和进程形成“关联”进程要正常运行不只是有一块地址空间就够了它的内核侧还必须有一套完整的账本进程描述符里记录父进程关系、调度信息、信号处理状态、打开的文件表、当前目录等。建立这套账本的过程往往比装载文件内容本身更耗时。这也是为什么我以前有个误解——以为装载主要是磁盘 I/O后来才意识到其实很多开销花在了一堆看不见的内核数据结构初始化上。当你执行一个程序时内部线索大致是这样的execve系统调用进入内核内核根据可执行文件的路径找到文件然后开启“装载”流程。这个流程里有一个非常重要的细节是设置 CPU 状态通用寄存器清零当然 BP 和 SP 栈指针有特定规划、指令指针指向程序入口。只有当这些状态就绪后进程才真正具备“从第一行代码开始执行”的条件。2.4 入口点从内核态切回用户态的那个瞬间装载的最后一步是把控制权交还给用户态程序。入口点不是随便设的在静态链接的 ELF 可执行文件里它通常指向_start这个由 C 运行时库提供的启动函数在动态链接的可执行文件里情况要复杂一些——入口点往往不是程序主函数而是动态链接器的入口等动态链接器完成依赖库的装载和重定位后才会跳转到真正的程序入口。这个细节书上放到了动态链接相关章节但第六章上提到进程入口点时已经埋下了伏笔程序的第一个指令不一定是你写的代码。这些动作一条线串下来我对“装载”这个词的理解彻底变了它不是某个瞬间从磁盘到内存的搬运而是一整套“从文件到进程”的状态构建流程。3. 4GB 虚拟地址空间这块“画布”是怎么布局的讲到虚拟地址空间书里那张经典的内存布局图想必每个读者都印象深刻。我读完最大的感受是这张图不仅仅是用来背的它直接决定了我们理解进程行为的上限。我先用一段文字带你俯视一下 32 位系统下一个进程地址空间的“地块规划”这是整章的地基。3.1 经典布局顶天立地的内核区域在 32 位 Linux 的经典布局中整个 4GB 的虚拟地址空间被一刀切成两半高地址的 1GB 留给内核低地址的 3GB 是用户空间。“内核区域”是每个进程共享的、映射到同一份物理内核代码和数据结构的那部分地址。我们平时调用read、write、fork本质上是通过系统调用陷入内核然后在内核地址空间里完成工作。用户程序永远无法直接访问内核区域因为页表里对应的页被标记成了特权级访问。说“每个进程的 4GB 地址空间”其实有点偷懒——用户空间是每个进程私有的但内核空间对所有进程是同一个。所以我更愿意把这张图看作每个进程都配了一张虚拟地址地图地图的上半部分内容和别的进程完全一样下半部分才属于自己私有规划。理解了这一点再去看“进程隔离”就非常踏实了不是内存被分给谁独占而是页表把不相干的虚拟地址挡在外面了。3.2 从高到低看用户空间的地块用户空间的典型布局从上往下大致是这样地块地址方向典型内容主要特点栈区Stack高地址向下增长函数调用栈、局部变量、返回地址动态扩展从高往低共享库映射区位于栈下方libc.so等动态库的映射也用于mmap大块内存堆区Heap低地址向上增长malloc、new分配的空间从低往高扩展隔断在数据段之上BSS 段堆下方未初始化全局变量不占文件空间运行时初始为 0数据段Data可执行文件中的初始化数据已初始化全局变量编译期已有初始值来自文件代码段Text可执行文件中的指令全部机器指令只读可执行加载后固定这张表格在书里也用类似方式呈现过我这里用表格是为了把“地块间的相对位置”钉在心里。不同操作系统、不同架构下具体分布有差异比如有的系统栈不一定是严格的最高地址开始有的还有 64 位地址空间的巨大空洞。但核心思想一致进程地址空间是一个有规矩的功能分区不同区域有不同的属性和增长方向。这个“有不同的属性”非常关键——它让权限精细控制成为可能代码段页表项标记为只读可执行数据段标记为可读可写但不可执行这样即使缓冲区溢出把返回地址改成一块堆内存地址CPU 也会因为该页不可执行而拒绝执行这就是 NX 保护的基础。3.3 用一张动态“地图”做对照观察看书上的静态图容易脑补真正让我把这块知识钉死的是动手观察真实进程的地址空间。Linux 下/proc/{pid}/maps文件会按地址顺序列出目标进程所有虚拟内存区域每一行都是一个vm_area_struct的翻译结果格式大致是地址范围、权限、偏移、设备号、inode、路径。我拿一段简单的 C 程序做演示编译后运行然后查看它的/proc/{pid}/maps。你能清晰地看到从低地址向上依次出现的代码段映射权限r-xp、只读数据段r--p、数据段/BSS 段rw-p、堆区域的起点也是rw-p但没关联文件然后在地址空间的另一端能看到栈区和其他信息。这个对照过程让书本抽象的描述变成很具体的东西原来代码段那一行里的偏移值正好对应 ELF 程序头里段的p_offset原来权限位的x/w不是内核拍脑袋设的而是从程序头表每个段的属性里继承过来的。提示查看/proc/{pid}/maps时注意那行逗号分隔的权限字段比如r-xp中最后一个p表示“私有映射”后面还会看到s表示共享映射。这个字母直接关系到写时复制和共享库的映射方式。我第一次没在意这个字母导致分析共享库的映射时误判了很久。一个更有意思的观察点当你故意访问未映射的内存地址时进程会收到 SIGSEGV 段错误。这个“段错误”中的“段”其实不是编译产物里的代码段/数据段而是虚拟地址空间中某块vma虚拟内存区域。如果不合规则地跨越了 vma 的边界去访问页表里根本找不到对应的页表项硬件就会触发一个缺页异常内核检查后确认这不是合法缺页而是非法访问于是给进程发信号。所以很多我们熟悉的“崩溃”背后都是地址空间规则在起作用。4. 可执行文件进内存从段到页的映射过程前面铺垫完了“为什么装载”“往哪里装载”现在进入这一章最硬核的部分装载的具体机制。也就是说地图有了文件里的段怎么和地图上的地块一一对应起来以及为什么非要用“页”这个粒度。4.1 程序头表装载视图的地契可执行文件里描述装载信息的是程序头表Program Header Table也叫段表注意与 .text/.data 那种节表区分。每个表项是一个Elf32_Phdr/Elf64_Phdr结构里面的核心字段包括段的类型PT_LOAD代表需要装载段PT_DYNAMIC代表动态链接信息PT_INTERP指向解释器等、段的文件偏移p_offset、段的虚拟地址p_vaddr、段的物理地址p_paddr现代系统基本不用但结构里还留着、段的文件大小p_filesz、段在内存中的大小p_memsz、段的权限属性p_flags。我习惯把这个结构理解成一张“地契”上面写清楚了这段地段在文件里哪块位置p_offset、要盖到地址空间的哪个位置p_vaddr、这块地文件里有多大p_filesz、盖起来之后实际要占多大p_memsz、允许在上面干什么p_flags读、写、执行。内核装载器就是拿着这一摞地契一块块地建立从文件到虚拟地址空间的映射。4.2 分段装载文件布局不等于内存布局这里就会出现一个初学者最容易懵的点文件的段在文件里是连续排列的按顺序分别是代码段、只读数据、数据段等但它们在内存地址空间里并不是按文件顺序紧挨着的因为每个段都要在特定的虚拟地址上对齐。所以装载时内核并不“按文件顺序依次搬砖”而是“按程序头表里登记的每一项分别映射到它该去的虚拟地址”。举个例子方便理解假设有个可执行文件规模很小代码段从文件偏移 0x1000 到 0x2fff大小 0x2000 字节数据段从 0x3000 到 0x3fff大小 0x1000 字节。如果把它们原封不动前后脚放进内存看起来“连着”很省事但实际装载时代码段的虚拟地址分到了 0x08048000 才开始的地方数据段紧跟其后还是在 0x0804a 附近但它们各自在文件里的偏移和长度与内存地址并不是简单的平移关系。系统真正做的事是计算出“该文件哪一段要放到哪个虚拟地址范围”然后把整个映射关系登记到进程的 vma 链表和页表里。这种“文件排列”与“内存排列”的错位造成了装载视图和链接视图的明显差异。链接器在生成可执行文件时会产生一块“文件视图”里面每段按文件偏移排列、大小也是文件大小但内核装载看到的是“装载视图”里面每段按虚拟地址排列、大小是运行时所需大小。我读完这章后做的最重要的一件事就是反复区分这两套概念平时用readelf -l看程序头看到的是装载视图用readelf -S看节头看到的是链接视图。4.3 按需调页:装载的“懒”哲学段映射到虚拟地址空间并不代表每个段都马上被完整读入物理内存。这个“懒”的实现基于页表和缺页异常机制。页表是 CPU 做虚拟地址到物理地址翻译时的“字典”每个页表项记录了这个虚拟页是否有效、对应哪个物理页、权限属性是什么。刚开始映射时大量页表项被标记为无效或“不在内存中”。当 CPU 尝试访问一个虚拟页而页表项显示不在内存时MMU 会触发缺页异常陷入内核。内核在异常处理程序里检查这个虚拟地址是否属于某个 vm_area_struct如果属于说明是一次合法的缺页那就为它分配物理页、把对应的文件内容读进来然后更新页表返回到触发异常的指令继续执行。如果不属于那就判死刑——SIGSEGV。我第一次理解这个过程时脑子里冒出来的类比是图书馆查书你把书架的索引页表先给读者看读者按索引找到某个书格发现书格是空的于是找管理员内核去仓库磁盘取书填进书架物理内存然后继续读。整个过程中从来没翻开过的书页永远不用搬进书架这就是“按需调页”。这个机制直接带来一个推论进程创建和启动的成本可以很低。你启动一个大型编辑器可能一开始只需要真正加载代码段的前几页、数据段的一小部分其他部分等用到时再补。所以装载的性能瓶颈往往不在“I/O 总量”而在“缺页异常发生的频率和模式”。4.4 当段比页更小、更大时必须做的页对齐处理物理内存和虚拟内存的分配单位是页常见 4KB。而段的最小粒度也是页的整数倍吗不一定。代码段可能只有几百字节数据段可能有几 KB 但跨页边界。这里有个很细但很关键的规则装载时段必须在页边界对齐之后才能映射。也就是说段的起始虚拟地址 vaddr 要页对齐文件偏移 offset 也要页对齐否则映射就会出错。为什么必须这样因为映射的最小单位是页你不能只映射一个段内部的小碎片。如果某个段在文件里从偏移 0x1001 开始那么它所在的页的前 1 字节还属于上一个段。装载器必须按“页”为单位把整页映射进来所以实际映射的范围要向前向后做页取整。书里很清楚地讲了这一点我记得自己当时对着一个 ELF 文件手工算偏移对齐算了半晌才完全明白映射的起始地址 对 vaddr 向下取整到页边界文件偏移 对 offset 向下取整到页边界长度 向上取整覆盖到段的结束。这个“页对齐”操作几乎是所有手工分析装载细节的重头戏。4.5 BSS 段的特殊玩法不占文件空间但占内存还有一个极具迷惑性的段——BSS 段。它在文件里的大小p_filesz是 0或很小但在内存里的大小p_memsz可能很大。因为未初始化的全局变量不值得占磁盘空间它们的初始值全是 0。所以装载时内核根本不需要从文件里读它的内容只需在地址空间里预留对应大小的区域并保证这些页在第一次被访问时读出来是零。常见的做法是用“共享零页”映射所有 BSS 页先把页表项指向同一个全零物理页并标记为只读一旦程序往 BSS 里写数据写时复制机制会分配一个真实物理页并填零再允许写入。这个机制解答了我早年一个疑问为什么一个程序全局变量数组声明得很大可执行文件体积却一点没变大因为 BSS 压根没被写进文件。文件结构上的“空白”和内存结构中的“实体”之间的反差正是装载视图独立于链接视图的又一生动例证。5. 学习第六章上最容易忽略但后来回报极高的几个细节前几章把主线理完了这节记录的是我从实际动手过程中抠出来、以及重读好几遍才领会的几个细节。有些是书上提了但容易滑过去的有些是我后来用工具验证才明白的感觉价值不低于主线内容。5.1 装载地址 vs 装载偏移一个 “基址”两种含义分析 ELF 文件时你经常看到三个相关的量p_vaddr、p_paddr和实际装载地址。现代用户态程序里p_paddr基本是摆设但p_vaddr是不是就等于程序运行时的存储地址得分场景。对于传统静态链接的可执行文件装载器常常就是按p_vaddr指定的地址映射的这属于“固定地址装载”。但对于共享对象.so和启用地址空间随机化ASLR的系统装载器会把整个映像放到一个随机选择的基地址上然后通过重定位在运行时调整代码里的地址引用。这时实际装载地址 基地址 每个段相对基地址的偏移。这个“基地址”的概念极其重要它是连接静态装载和动态链接之间的一座桥。我只盯着p_vaddr看时死活想不通动态库为什么能做到“同一个 .so 可以被不同进程加载到不同地址”后来终于明白只要把文件在内存中的起始基址作为浮动原点所有相对引用通过重定位修正位置无关代码就能在任何地方运行。书上把“链接视图”和“装载视图”分开讲很大程度就是为这个打底。5.2 写时复制为什么 fork 之后还能共享同一份代码段讲到装载和进程创建Linux 绕不开 fork 的写时复制COW。第六上没大篇幅展开这一块但理解装载条件后写时复制的存在感就更强了。当父进程 fork 出子进程子进程并不会复制父进程的全部地址空间而是和父进程共享页只是把这些页表项标记为只读。无论是谁要写这些页缺页异常都会触发内核才把这一页复制出一份独立的物理页。代码段天然只读所以父子和孙辈一直共享同一物理内存省到极致。有意思的是这个机制和你前面理解的“段权限”叠加后会产生一个安全细节本来代码段页表项是“只读可执行”fork 之后内核只多标记一个“COW 待处理”性质上不会破坏权限模型。很多安全漏洞都试图在这个机制上做文章但那是后话。我的心得是装载章节里的“页权限”“页表项状态”不只是为了性能它和整个系统的安全模型也是一体的。5.3 为什么不能直接“ReadFile 全部读进来”来装载有个很自然的“朴素方案”既然进程需要的代码和数据都在文件里为什么不干脆一个系统调用把所有内容读进内存再执行除了前面讲的内存浪费和权限问题还有一个重要原因是文件的布局不等于运行时布局。文件里同一段可能由多个节拼接而成比如 .text 和 .rodata 连在一起但它们对内存页的要求不同文件里并不包含 BSS 这样的大块零填充区文件里可能还包含只对链接器有用、对运行时完全没用的调试信息和符号表。如果整体读入这些垃圾也占用内存并被错误地赋予权限。更关键的是整体读入无法做到按需装载。一个大程序没读完所有页面之前用户可能只用到 1% 的功能但你已经把所有代码页都加载了。按需调页的最大卖点就是让首次启动和其他场景的真实 I/O 量远小于文件体积。这一点是解释“为什么现代系统如此依赖分段、分页和映射而不是拷贝”的核心答案。5.4 用readelf -l/proc 手工验证装载过程我读完这一章后做了个小实验建议你也试一下特别有助于把“程序头表 → vma → 页表”这条链路串起来。实验步骤很简单写几段 C 程序分别包含全局变量、未初始化大数据数组、字符串字面量编译后执行readelf -l ./a.out查看程序头表记下每个 PT_LOAD 段的p_offset、p_vaddr、p_filesz、p_memsz、p_flags。运行程序用cat /proc/{pid}/maps观察地址空间。对照相同地址范围理论上/proc/PID/maps里的偏移列应与readelf -l的p_offset吻合权限列应与p_flags映射读 r、写 w、执行 x。这个实验我做得最顺手时几乎能在心里把/proc/{pid}/maps每一行对应回 ELF 程序头表的某一行。这种“动手对照”的意义在于你不再把装载当作抽象概念而是能看到一个进程出生时文件系统里的那些段是如何一块一块被安放到地址空间里的。数据结构的抽象性和真实世界的可观察性之间一旦建立了对应后面的堆、栈、内存管理都是水到渠成。5.5 核心转储里的“段”和装载视图的亲密关系可以留一个后续观察点这虽然不完全属于第六上但和它关联很深当程序崩溃并产生 core dump 时转储的内容主要就是进程地址空间里那些可读写的 vma 区域。你看核心转储能看到曾经的栈、堆、数据段和共享库映射唯独很难看到一个完整的、原始的可执行文件。这恰好反过来证明了一个观点进程运行时的状态早已不是文件那份静态拷贝而是映射 页 动态写入的混合体。理解装载视图之后再去看 core dump、调试器、perf 等工具都会觉得这些工具就是在“读一本地理考卷”——翻的是地址空间的底图而不是可执行文件本身的布局。6. 读完第六章上的几点“扎心”体会读这章之前我对“链接”和“装载”两个词的理解是混在一起的总感觉它们都是“把程序搞成可运行状态”的步骤。读完才意识到链接解决的是“多个目标文件怎么缝合成一个整体”而装载解决的是“这个整体怎么安置进运行环境”。这两件事的输入输出完全不同正确的思考顺序是先有链接的静态视图再有装载的动态视图。以前我老觉得自己懂了链接装了没懂现在反过来了——装载能讲清之后回头再想链接里的重定位、符号解析反而更清楚它们各自服务的最终目的。另外有一点很受用这章的标题叫“可执行文件的装载与进程”它的精髓不是给你背一堆术语而是让你建立起“进程 文件映像 运行时状态”的心智模型。可执行文件只是进程的“图纸”虚拟地址空间是“工地”装载器是“施工队”而缺页异常则是“按需运送建材”的巡检员。把这条主线穿起来后面无论学动态链接、共享库还是内存管理、调试器原理都会有一个稳定的大框架。我最后的一个建议是看完这章后别急着往下翻先自己打开终端把一个最简单的hello world程序编译出来用readelf -l看它的程序头再用/proc看它运行时的地址空间哪怕只看一次也绝对比单纯刷书印象深刻得多。这种“验证式学习”一旦形成习惯整本《程序员的自我修养》读下来每个抽象的机制都会变得可以触摸。
RELATED

相关推荐

全志T153接口能力解析:嵌入式中等带宽通信的‘刚刚好’方案

全志T153接口能力解析:嵌入式中等带宽通信的‘刚刚好’方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/14 20:10:39
C# WCF与Web接口开发实战:从配置到跨域调用避坑指南

C# WCF与Web接口开发实战:从配置到跨域调用避坑指南

简介:这份资源面向具备一定.NET基础的开发者,聚焦C#中WCF与Web项目接口开发的实际案例,帮助读者理解如何用服务合同、数据契约与操作契约搭建可调用的分布式服务接口。内容围绕增删改查基础场景展开,涵盖服务定义、数据实体序列化…

📅 2026/10/14 20:10:39
Tiptop与Easyflow系统集成避坑指南:从PDF样例到生产落地

Tiptop与Easyflow系统集成避坑指南:从PDF样例到生产落地

简介:本资源是一份面向企业级ERP与OA系统集成工程师的Tiptop与Easyflow单据电子签核专项技术指南,聚焦制造业、流通业等使用Tiptop ERP并需对接Easyflow流程引擎的典型场景。文档系统梳理了从环境配置、数据表校验、AWS模块开发(含公共服务与…

📅 2026/10/14 20:05:32
MORE NEWS

更多资讯

📰

连续粉体进料与混合建模教程(3):连续直压产线解剖与时间尺度——物料流、三个串联混合单元与三段时间尺度

连续粉体进料与混合建模教程(3):连续直压产线解剖与时间尺度——物料流、三个串联混合单元与三段时间尺度版本声明块 工具/软件:matplotlib(产线结构图与时间尺度对比图);本系列的自研类 Powder…

📰

Sentinel哨兵启动踩坑记录:从控制台到客户端到规则落地的完整排查指南

1. 为什么这次我要把Sentinel哨兵拎出来单独写第一次把Sentinel哨兵引入项目组的时候,我以为最难的会是限流算法的参数调优,结果光是让控制台正常启动,就让组里三个人对着终端日志看了整整一个下午。后来接入客户端应用又踩了第二轮坑&#x…

📰

Positron 内置扩展目录结构、双输出构建与浏览器端启用实践指南

开发工具代码编辑器数据科学 【免费下载链接】positron Positron, a next-generation data science IDE 项目地址: https://gitcode.com/gh_mirrors/po/positron 点击查看 免费下载 本文围绕 Positron(基于 VS Code 架构的数据科学 IDE)仓库…

📰

基于Springboot高校多媒体信息共享平台【附源码+文档】

💕💕作者: 米罗学长 💕💕个人简介:混迹java圈十余年,精通Java、小程序、数据库等。 💕💕各类成品Java毕设 。ssm,springboot,vue等项目&#xff0…

📰

BurntSushi/toml 深度实战指南:Go 语言 TOML 解析库的解码、编码与元数据用法全解析

网络安全网络 【免费下载链接】dnscrypt-proxy dnscrypt-proxy 2 - A flexible DNS proxy, with support for encrypted DNS protocols. 项目地址: https://gitcode.com/gh_mirrors/dn/dnscrypt-proxy 点击查看 免费下载 BurntSushi/toml 是 Go 生态中最成熟的 TOM…

📰

MFC自绘柱状图控件:从GDI绘图到双缓冲完整实践指南

简介:面向MFC初学者的柱状图绘制示例工程,演示在单文档视图中通过画刷与图形设备接口(GDI)绘图,从TXT文本文件读取数据并渲染柱状图。压缩包共36个文件,大小约2.28MB,包含头文件、C源码、MFC工程…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬