011 Linux进程

🦄 个人主页: 小米里的大麦-CSDN博客
🎏 所属专栏: Linux_小米里的大麦的博客-CSDN博客
🎁 GitHub主页: 小米里的大麦的 GitHub
⚙️ 操作环境: Visual Studio 2022

在这里插入图片描述

文章目录

    • 深入理解 Linux 进程管理
      • 一、管理哲学/本质:先描述,再组织(校长如何管理学校?)
      • 二、进程的定义与核心概念
        • 1. 什么是进程?
        • 2. 进程管理的核心:进程控制块(PCB)
      • 三、Linux 的 `task_struct` 详解(进程控制块的实现)
        • 1. `task_struct` 的结构(进程的 DNA)
          • 关键字段解析(下面详解):
        • 1. 标识符(Identity)
        • 2. 状态(State)
        • 3. 优先级(Priority)
        • 4. 程序计数器(Program Counter)
        • 5. 上下文(Context)
        • 6. 内存与资源信息
        • 7. I/O 状态
        • 8. 记账信息(Accounting)
        • 9. 其他信息
      • 四、组织进程
      • 五、查看进程
        • 1. 查看进程方法
          • 1. `ps` 相关命令
          • 2. `top` 相关命令(按 `q` 退出)
          • 3. `htop` 相关命令
          • 4. 其他进程相关命令
          • 5. `/proc` 文件系统
        • 2. 通过系统调用获取进程标识符
        • 3. `fork()` 创建进程详解
        • 1. 为什么 `fork()` 给子进程返回 `0`,给父进程返回子进程的 `PID`?
        • 2. `fork()` 作为一个函数为什么能返回两次?如何理解?
        • 3. 为什么同一个变量在父子进程里内容不同?
        • 4. `fork()` 究竟在干什么?系统中多了一个进程吗?
        • 5. 为什么要创建子进程?
        • 6. `fork() ` 后,谁先运行?
      • 六、扩展思考
        • Q1:为什么进程不需要直接与内核交互?
        • Q2:如何查看进程的 `task_struct`?
        • Q3:**多个进程如何共享 CPU**?
    • 共勉

深入理解 Linux 进程管理

一、管理哲学/本质:先描述,再组织(校长如何管理学校?)

一个操作系统不仅仅只能运行一个进程,可以同时运行多个进程。操作系统的进程管理:先描述,在组织 → 任何一个进程。在操作系统中,管理任何对象,最终都可以转化成为对某种数据结构的增删查改。想象你是一所大学的校长,管理数万名学生。你不需要认识每个学生,只需通过 学生档案系统 管理:

  • 描述:每个学生有专属档案(学号、姓名、专业、成绩、宿舍号…)
  • 组织:档案按学院 → 专业 → 班级形成 链表结构
  • 管理:调整专业只需修改档案中的“专业”字段,开除学生只需删除对应档案(增删查改

操作系统管理进程同理

  1. 描述:为每个进程创建 task_struct(进程的“档案”)
  2. 组织:通过链表、队列等数据结构管理所有 task_struct
  3. 控制:调整优先级、终止进程等操作只需修改对应结构体

数据结构的作用

  • 学校:学生档案链表 → 管理学生 增删查改(如入学、转班、退学)。
  • 操作系统:进程 PCB 链表 → 管理进程的创建、调度、终止等。

二、进程的定义与核心概念

1. 什么是进程?
  • 进程 = 程序员自己写的代码和数据 + 内核 PCB 数据结构对象(描述进程的所有数据,process ctrl block → 进程控制块)
    • 程序:程序员编写的代码(如 hello.c 编译后的可执行文件 hello)。
    • 进程:程序被加载到内存中运行的实例(如运行 ./hello 后生成的进程)。
  • 关键点
    • 进程是动态的:程序本身是静态文件,进程是运行时的实体。
    • 每个进程都有自己的 PCB(进程控制块),存储进程的所有信息。
2. 进程管理的核心:进程控制块(PCB)
  • PCB 的作用:记录进程的所有属性,帮助内核管理进程。
  • Linux 中的 PCB:名为 task_struct 的结构体(C 语言中的结构体)。
  • 类比:就像学生的学籍档案,记录了学号、成绩、班级、状态等。

三、Linux 的 task_struct 详解(进程控制块的实现)

1. task_struct 的结构(进程的 DNA)

在 Linux 内核中,进程属性的集合 task_struct 是一个庞大的结构体(约有数百个字段),task_struct 是 Linux 内核的一种数据结构,它会被装载到 RAM(内存)里并且包含着进程的信息。

// 简化版 task_struct 结构(Linux内核真实结构复杂得多)
struct task_struct
{long pid;                		// 身份证号(进程唯一标识)volatile long state;      		// 当前状态(睡觉/跑步/待机)int priority;            		// VIP等级(优先级)struct mm_struct *mm;    		// 家庭住址(内存分配情况)struct files_struct *files; 	// 随身物品(打开的文件)// 相关指针信息:structPCB *nextstruct PCB *queuestruct PCB *xxxxx// ... 上百个字段
};
关键字段解析(下面详解):
字段类比作用
pid学号唯一标识进程(ps -ef 查看)
state学生状态(上课/请假)进程状态:运行(R)、睡眠(S)、僵尸(Z)等
priority奖学金等级优先级高的进程优先使用 CPU(nice 命令调整)
mm_struct宿舍分配表记录进程使用的内存空间(代码段、数据段、堆栈等)
files_struct书包里的书本记录进程打开的所有文件(lsof -p <pid> 查看)
上下文数据课堂笔记保存 CPU 寄存器的值,用于中断后恢复现场

1. 标识符(Identity)
  • pid(进程 ID):唯一标识符,类似学生的学号。每个进程有唯一的 PID,通过 ps 命令可见。
  • ppid(父进程 ID):记录该进程的父进程 PID,形成父子进程关系。类比:学生档案中记录班主任的工号。
2. 状态(State)
  • 进程状态:进程当前所处的阶段,包括:

    • 运行态(Running):正在 CPU 上执行。
    • 就绪态(Runnable):等待调度到 CPU 上运行。
    • 阻塞态(Blocked):等待 I/O(如读写文件)、等待信号等。
    • 终止态(Zombie):进程已结束,但父进程未回收其资源(成为“僵尸”)。
  • 字段示例

    volatile long state;  // 进程状态(如TASK_RUNNING, TASK_INTERRUPTIBLE)
    int exit_code;        // 进程退出时的返回值
    
3. 优先级(Priority)
  • 调度优先级:决定进程获得 CPU 时间的“权重”。

    • nice 值:用户可调整的优先级(值越低,优先级越高)。
    • 实时优先级:用于需要严格实时性的进程(如音频播放)。
  • 字段示例

    int nice;             // nice值(-20到19,默认0)
    unsigned long policy; // 调度策略(如SCHED_OTHER普通进程)
    
4. 程序计数器(Program Counter)
  • 寄存器状态:记录进程执行到的位置。
    • pc(程序计数器):指向当前指令的下一条指令的地址。
    • 其他寄存器:如栈指针(rsp)、基指针(rbp)等,保存进程执行现场。
  • 作用:当进程被中断(如切换到其他进程),内核会保存这些寄存器的值,以便恢复执行。
5. 上下文(Context)
  • 上下文数据:进程执行时的所有硬件寄存器的值。
    • 类比:学生临时离开教室前,记录自己写到哪页笔记、用哪支笔。
    • 保存场景:当进程被中断(如 I/O 请求),内核将寄存器值保存到 task_struct
    • 恢复场景:当进程重新调度到 CPU 时,内核恢复这些寄存器值,继续执行。
6. 内存与资源信息
  • 内存指针:记录进程的代码、数据、堆栈的内存地址。
    • 代码段(text 段):程序指令的内存区域。
    • 数据段(data 段):全局变量、堆栈等。
    • 共享内存:与其他进程共享的内存块指针。
  • 资源列表
    • 打开的文件描述符(如 /dev/sda)。
    • 分配的 I/O 设备(如 USB 设备)。
7. I/O 状态
  • I/O 请求队列:记录进程等待的 I/O 操作(如读取硬盘)。
  • 分配的设备:进程当前占用的硬件设备。
8. 记账信息(Accounting)
  • CPU 时间统计
    • utime:用户模式下消耗的 CPU 时间。
    • stime:内核模式下消耗的 CPU 时间。
  • 时间限制:如进程允许的最大运行时间。
  • 记账用户:记录进程属于哪个用户(如 root 或普通用户)。
9. 其他信息
  • 信号处理:记录进程如何处理信号(如 SIGTERM 终止信号)。
  • 线程信息:如果是多线程程序,记录线程组信息。
  • 调度队列指针:指向进程所在的就绪队列或阻塞队列。

四、组织进程

可以在内核源代码里找到它。所有运行在系统里的进程都以 task_struct 链表等非常复杂的数据结构的形式存在内核里。


五、查看进程

1. 查看进程方法

在 Linux 中,进程(Process)是正在运行的程序实例。查看进程的常用命令有:

  • ps:最常用的进程查看工具,适合快速查看进程快照(静态结果输出)。
  • top:动态监控进程,适合实时观察系统状态(动态查看进程变化,默认 5 秒更新)。
  • htop:增强版 top,界面更友好,适合交互式操作。
  • 其他命令:如 pgreppidof 等,适合精准定位进程。

1. ps 相关命令

当直接输入 ps 而不带任何参数时,命令会:

  • 仅显示当前终端会话中的进程,即与当前终端关联的进程。
  • 输出内容较为简洁,仅包含以下字段:
    • PID:进程 ID。
    • TTY:进程关联的终端(如 pts/0 表示伪终端)。
    • TIME:进程占用的 CPU 时间。
    • CMD:启动进程的命令名及参数。
命令/选项说明示例常用度
ps aux显示所有用户的进程,包含详细信息(用户、CPU、内存等)ps aux⭐⭐⭐⭐⭐
ps -ef显示全格式进程信息(更详细的进程信息,常用于系统管理和脚本,含 PPID)ps -ef⭐⭐⭐⭐⭐
ps -e显示所有进程ps -e⭐⭐⭐
ps -u <用户>显示指定用户的进程ps -u root⭐⭐⭐
ps -p <PID>显示指定 PID 的进程信息ps -p 1234⭐⭐⭐⭐
ps -o按需展示特定字段,常与 -p 结合使用(如 PID、PPID、CMD 等)ps -o pid,ppid,cmd,%mem,%cpu⭐⭐⭐⭐
ps aux --sort按指定字段排序(如内存、CPU)ps aux --sort=-%mem⭐⭐⭐⭐
ps auxf以树状结构显示进程ps auxf⭐⭐⭐⭐
2. top 相关命令(按 q 退出)
命令/选项说明示例常用度
top实时动态查看进程状态(类似任务管理器)top⭐⭐⭐⭐⭐
top -c显示完整命令路径top -c⭐⭐⭐⭐
top -p <PID>监控指定 PID 的进程top -p 1234⭐⭐⭐
top -u <用户>监控指定用户的进程top -u root⭐⭐⭐
top -b以批处理模式运行,输出到文件top -b -n 1 > top.log⭐⭐⭐
top -n <次数>指定刷新次数后退出top -n 3⭐⭐⭐
3. htop 相关命令
命令/选项说明示例常用度
htop增强版 top,支持鼠标操作和颜色高亮(需安装:yum install htophtop⭐⭐⭐⭐⭐
htop -u <用户>显示指定用户的进程htop -u root⭐⭐⭐⭐
htop -p <PID>显示指定 PID 的进程htop -p 1234⭐⭐⭐
htop -d <秒>设置刷新间隔时间htop -d 5⭐⭐⭐
4. 其他进程相关命令
命令/选项说明示例常用度
pgrep根据名称查找 PID(支持模糊匹配)pgrep sshd⭐⭐⭐⭐
pgrep -l显示进程名和 PIDpgrep -l ssh⭐⭐⭐⭐
pidof根据精确进程名查找 PIDpidof nginx⭐⭐⭐
pstree以树状结构显示进程关系(需安装:yum install psmiscpstree -p⭐⭐⭐
kill <PID>终止指定进程kill 1234⭐⭐⭐
kill -9 <PID>强制杀死进程kill -9 1234⭐⭐⭐⭐
5. /proc 文件系统
命令/路径说明示例常用度
/proc/[PID]/status查看进程的详细状态信息cat /proc/1234/status⭐⭐⭐⭐
/proc/[PID]/cmdline查看进程的启动命令cat /proc/1234/cmdline⭐⭐⭐
/proc/[PID]/exe查看进程对应的可执行文件ls -l /proc/1234/exe⭐⭐⭐
/proc/[PID]/fd查看进程打开的文件描述符ls -l /proc/1234/fd⭐⭐⭐

2. 通过系统调用获取进程标识符
  1. C 程序示例
#include <unistd.h>  // 提供 getpid(), getppid(), 和 sleep()
#include <stdio.h>int main()
{while (1){// 获取当前进程 IDpid_t pid = getpid();printf("当前进程 ID (PID): %d\n", pid);// 获取父进程 IDpid_t ppid = getppid();printf("父进程 ID (PPID): %d\n", ppid);// 睡眠 1 秒sleep(1);  }return 0;
}
  1. 编译
gcc -o getpid getpid.c
  1. 运行
./getpid
  1. 示例输出
当前进程 ID (PID): 1195
父进程 ID (PPID): 481

3. fork() 创建进程详解

摘自鸟哥的 Linux 私房菜基础学习篇(第四版)517页:

Linux 的程序调用通常成为 fork-and-exec 的流程。进程都会借父进程以复制(fork)的方式产生一个一模一样的子进程,然后被复制出来的子进程再以 exec 的方式来执行实际要执行的进程,最终就成为一个子进程。

  1. 基础示例代码
#include <unistd.h>
#include <stdio.h>int main()
{pid_t pid = fork();if (pid < 0){fprintf(stderr, "创建子进程失败");                             // 将标准错误输出的信息改为中文return 1;}else if (pid == 0){printf("子进程PID=%d, 父进程PPID=%d\n", getpid(), getppid());  // 子进程中打印的信息改为中文}else{printf("父进程PID=%d, 创建的子进程PID=%d\n", getpid(), pid);   // 父进程中打印的信息改为中文}return 0;
}
  1. 示例输出:
父进程PID=2744, 创建的子进程PID=2745
子进程PID=2745, 父进程PPID=2744

注意:输出顺序可能不固定,取决于系统调度,再看下面一个示例:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main()
{printf("begin: 我是一个进程,pid: %d, ppid: %d\n", getpid(), getppid());pid_t id = fork();if (id == 0){// 子进程while (1){printf("我是子进程,pid: %d, ppid: %d\n", getpid(), getppid());sleep(1);}}else if (id > 0){// 父进程while (1){printf("我是父进程,pid: %d, ppid: %d\n", getpid(), getppid());sleep(1);}}else{//error}return 0;
}

示例输出:

begin: 我是一个进程,pid: 3721, ppid: 481
我是父进程,pid: 3721, ppid: 481
我是子进程,pid: 3722, ppid: 3721
我是父进程,pid: 3721, ppid: 481
我是子进程,pid: 3722, ppid: 3721
我是子进程,pid: 3722, ppid: 3721
……

[!IMPORTANT]

1. 为什么 fork() 给子进程返回 0,给父进程返回子进程的 PID

fork() 的目的是创建一个 几乎完全相同 的子进程(一般而言 fork 之后的代码父子共享)。让父子进程执行不同的代码分支。通过返回值区分父子进程的身份:

  • 父进程:需要知道子进程的 PID,以便后续管理(如等待子进程退出、发送信号等)。
  • 子进程:无需知道自己的 PID(可通过 getpid() 获取),但需要明确自己是子进程(返回 0 是最直接的方式)。

实现意义

  • 父进程通过子进程 PID 可以追踪、控制子进程(如 waitpid())。
  • 子进程通过返回值 0 知道自己是被创建的一方,从而执行子进程独有的逻辑。

总结:父进程通过返回值区分子进程,子进程通过返回值确认自己是子进程。


2. fork() 作为一个函数为什么能返回两次?如何理解?

fork() 本质上只调用一次,但返回两次! fork() 调用后,操作系统会复制父进程,创建一个新的子进程。

  • 父进程:继续从 fork() 返回,得到子进程的 PID。

  • 子进程:从 fork() 返回,得到 0。

  • 示意图

    +----------------+
    | 父进程执行 fork() | --> 子进程诞生
    +----------------+|                  |v                  v
    返回子进程 PID            返回 0
    

看似一次调用返回两次,实际是两个独立的进程分别执行了 fork() 后的代码。可以把 fork() 想象成 一颗分叉的树:调用时是同一条路径,但执行后分成了两条路,各自独立运行。


3. 为什么同一个变量在父子进程里内容不同?

调用 fork() 时,子进程不会立即复制父进程的内存,而是共享同一份物理内存(标记为只读)。当父子进程 修改内存时,操作系统才会复制被修改的页(内存页的最小单位)。具体来说就是当 fork() 被调用时:

  1. 代码段(Code Segment): 父子进程共享这部分内存,不需要复制。毕竟代码是静态的,读操作不会影响对方。
  2. 数据段、堆、栈(Data, Heap, Stack): 父子进程“看起来”各自独立,但实际上,系统不会立刻复制这部分内存!取而代之的是:
    • COW 机制: 父子进程最开始共享同一片物理内存,这些内存页被标记为 只读(Read-Only)
    • 写时复制: 当父或子进程试图写入这片内存时,操作系统才会触发“页面复制”,分配新的内存页,供写操作独享。

这种机制大幅优化了 fork() 的性能,因为如果父子进程不修改内存,根本就不用复制,节省了大量资源。综上:fork() 之后,父子进程共享代码段,但数据、堆、栈在写操作时会触发“写时复制”。

举个例子:

#include <stdio.h>
#include <unistd.h>
int main()
{int x = 100;pid_t pid = fork();if (pid == 0){// 子进程printf("子进程 x = %d\n", x);                // 共享内存,输出 100x = 200;                                    // 写操作,触发写时复制,子进程独享这片内存printf("子进程修改后 x = %d\n", x);}else{// 父进程sleep(1);                                   // 让子进程先跑printf("父进程 x = %d\n", x);               // 父进程的 x 仍然是 100,未受子进程影响}return 0;
}输出:
子进程 x = 100
子进程修改后 x = 200
父进程 x = 100

解释:

  1. fork() 之后,父子进程共享内存,x 的初始值对父子都可见(100)。
  2. 子进程写入 x 时,触发 COW:
    • 系统为子进程分配新内存页,把原来内存页的值(100)复制过来。
    • 子进程修改自己的副本,父进程继续使用原来的内存页。
  3. 所以,父子进程的 x 从此各自独立,互不干扰。因为它们的内存空间已经分开,各玩各的!

注:如果想让父子进程共享数据,得用专门的共享内存机制(如 mmap())。


4. fork() 究竟在干什么?系统中多了一个进程吗?

是的,fork() 让系统里多了一个新进程!可通过 ps 命令观察到子进程的存在:ps -ef | grep <程序名>。它做了这几件事:

  1. 复制父进程的内存空间: 代码段、数据段、堆栈等全部复制,子进程看起来和父进程几乎一模一样。

    • 复制父进程的 进程控制块(PCB),生成子进程的 PCB。
    • 复制父进程的 虚拟地址空间(通过写时复制优化)。
  2. 分配新的进程 ID(PID): 子进程有独立的 PID,同时保留父进程的 PPID(Parent PID)。

  3. 独立调度: 子进程作为独立的进程被调度,和父进程各自执行,互不干扰。

所以,fork() 之后,系统里确实多了一个进程!但它们起点一致,只是接下来的执行路径可能不同。


5. 为什么要创建子进程?

创建子进程的目的是 并行执行不同的任务,常见用途有:

  1. 后台任务: 如守护进程、Web 服务器,父进程处理请求,子进程负责具体工作。
  2. 任务分解: 父进程分配工作,子进程完成任务。
  3. 隔离风险: 子进程失败不会影响父进程,避免整个程序崩溃。

简单来说,父进程管理,子进程干活,井井有条!


6. fork() 后,谁先运行?

这个是 不确定的!谁先运行完全取决于操作系统的调度策略:

  • 父子进程创建完成后,由操作系统的调度器决定执行顺序。
  • 可能父进程先运行,也可能子进程先运行,甚至交替执行

所以,谁先跑?随缘!操作系统说了算,让操作系统的调度器决定,它才是“调度大哥”!


六、扩展思考

Q1:为什么进程不需要直接与内核交互?

答:内核通过 task_struct 间接管理进程,就像校长通过学生档案管理学生。进程只需执行代码,内核通过数据结构记录状态并决策。

Q2:如何查看进程的 task_struct

答:用户态无法直接访问 task_struct,但可以通过以下命令间接查看:

  • ps:显示 PID、状态、CPU/内存使用。
  • /proc/[pid]/stat:虚拟文件系统,如 cat /proc/1234/stat 包含进程的详细信息(映射 task_struct 字段)。
Q3:多个进程如何共享 CPU

答:通过调度算法在 task_struct 间切换。

  • 完全公平调度(CFS):基于虚拟运行时间(vruntime)决定进程优先级。
  • 实时调度策略:如 SCHED_FIFO(先进先出)和 SCHED_RR(时间片轮转)。
  • 调度相关字段task_struct 中的 policy(调度策略)、prio(动态优先级)、static_prio(静态优先级)。

共勉

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88853.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

星型模型(Star Schema)

在数据仓库的体系概念中&#xff0c;星型模型&#xff08;Star Schema&#xff09;和雪花模型&#xff08;Snowflake Schema&#xff09;是两种常见的数据模型&#xff0c;用于组织和结构化数据&#xff0c;以支持高效的查询和分析。 今天我们先介绍星型模型&#xff08;Star …

【RAG面试题】如何获取准确的语义表示

目录 回答模板 语义表示是干什么的&#xff1f; 如何获取准确语义表示的关键步骤&#xff1f; 1. 选择合适的 Embedding 模型 2. 正确的文本预处理与切分 3. 文本清洗与标准化 4. 构建合理的向量库 5. 检索质量验证与优化 详细知识点覆盖 面试回答技巧 回答模板…

小程序 API 开发手册:从入门到高级应用一网打尽

在移动互联网浪潮中&#xff0c;小程序已经成为企业服务用户的“第二战场”。不论是微信小程序、支付宝小程序&#xff0c;还是抖音小程序&#xff0c;都在强调一个核心能力&#xff1a;快速响应用户需求。而支撑小程序灵活运行和丰富功能的关键技术之一&#xff0c;正是小程序…

iwebsec靶场sqli注入(2)

​​​​​​06-宽字节注入 1&#xff0c;该漏洞的根本原因是字符集处理不一致&#xff08;GBK双字节特性&#xff09;与不安全的转义方式&#xff08;addslashes&#xff09;共同导致。构造基础sql注入语句 1%df%27%20%23 漏洞原理 字符集设置&#xff1a;mysql_query("S…

小程序学习笔记:自定义组件创建、引用、应用场景及与页面的区别

在微信小程序开发中&#xff0c;自定义组件是一项极为实用的功能&#xff0c;它能有效提高代码的复用性&#xff0c;降低开发成本&#xff0c;提升开发效率。本文将深入剖析微信小程序自定义组件的各个关键方面&#xff0c;包括创建、引用、应用场景以及与页面的区别&#xff0…

开发数字化绿色低碳园区系统:分阶段实施指南

目录 摘要 背景 核心模块 阶段性开发 分阶段开发实施 第一阶段(3-6个月):搭建核心骨架 第二阶段(6-9个月):扩展功能 第三阶段(9-12个月):深度定制 技术选型 注意事项 实施计划表 小结 摘要 数字化绿色低碳园区系统通过物联网、能源管理和数据分析等技术,…

智能实验室革命:Deepoc大模型驱动全自动化科研新生态

自动化实验执行 自动化实验执行通过机器人技术与智能控制系统的深度融合&#xff0c;重构传统实验操作模式&#xff0c;其核心技术突破体现在以下层面&#xff1a; 1. ​​多模态任务分解与执行架构​​ 基于大模型的任务解析引擎可将复杂实验流程分解为可执行的原子操作序列…

还在手动部署?用Jenkins+Docker+Git实现自动化CI/CD

“每次发版都要手动打包上传&#xff0c;部署宕机了才发现出错&#xff1f;” 你还在重复“开发提测-打包部署-验证回归”的流水线操作&#xff1f;明明可以一键搞定的流程&#xff0c;为何还在亲力亲为&#xff1f;是时候了解并掌握 自动化 CI/CD 的真正威力了&#xff01; 手…

Stream流中间方法的使用

Stream流的中间方法详解 Stream流的中间方法指那些返回新Stream的操作&#xff0c;允许链式调用。这些方法通常用于数据过滤、映射、排序等操作&#xff0c;不会触发最终计算。 filter方法 filter用于筛选满足条件的元素&#xff0c;接受一个Predicate函数式接口参数。 Lis…

华为云Flexus+DeepSeek征文|华为云ModelArts结合FeedMe:开启AI驱动的RSS阅读新时代

华为云FlexusDeepSeek征文&#xff5c;华为云ModelArts结合FeedMe&#xff1a;开启AI驱动的RSS阅读新时代 前言一、华为云ModelArts Studio平台介绍1.1 ModelArts Studio介绍1.2 ModelArts Studio主要特点1.3 ModelArts Studio使用场景1.4 ModelArts Studio产品架构 二、FeedMe…

华为云Flexus+DeepSeek征文 | 华为云ModelArts Studio新手入门:DeepSeek服务的配置与使用详解

华为云FlexusDeepSeek征文 | 华为云ModelArts Studio新手入门&#xff1a;DeepSeek服务的配置与使用详解 前言一、ModelArts Studio介绍1. 华为云ModelArts Studio简介2. 华为云ModelArts Studio主要特点3. 华为云ModelArts Studio主要使用场景 二、ModelArts Studio平台开通De…

Note2:机器学习基本攻略(Machine Learning by Hung-yi Lee)

目录 基本思路 1.训练资料上loss很大 1.1 model bias 1.2 optimazation&#xff08;优化不够好&#xff09; 1.3如何确定是 model bias还是optimazation 解决方法 2.训练资料上loss很小 2.1 Overfitting 解决方案 1.使用更多训练资料 2.限制模型 2.2 Mismatch 3.…

使用ubuntu下的FAST和gfzrnx进行广播星历下载及版本之间的转换

使用FAST下载混合的广播星历文件 cd FAST_V3.00.03 (进入文件夹) chmod x FAST (授权) chmod x bin/* ./FAST1 下载&#xff1a;https://gnss.gfz.de/services/gfzrnx/download &#xff08;需注册&#xff09; 2 打开bash&#xff0c;依次输入 (其中gfzrnx_2.1.12_lx64为下载…

vue裁剪图片

有一个需求就是在你有俩张图片一样大小&#xff0c;一个亮色的&#xff0c;一个暗色的&#xff0c;亮色的根据后端返回的数据显示多高&#xff0c;这样就有一个感觉是慢慢往上走的&#xff0c;主要用到了css的一个属性 .my-info-image {width: 280px;height: 200px;position: a…

使用GDAL库统计不同分区内的灾害点分布情况,计算灾害相对密度等统计指标

主要功能是处理地理空间栅格数据&#xff08;TIFF文件&#xff09;和灾害点数据&#xff08;CSV文件&#xff09;&#xff0c;统计不同分区内的灾害点分布情况&#xff0c;并计算灾害相对密度等统计指标。 TIFF文件&#xff1a;已经重分类后的文件 CSV文件&#xff1a;灾害点…

jar 包如何下载

在 Javaweb - 2 中&#xff0c;我们导入了三那个 jar 包来进行服务端的 JSON 串格式转换&#xff0c;这个为大家做一个如何下载那三个 jar 包的教程~ 打开仓库网站 我们需要先打开一个仓库网址&#xff1a;Maven Repository: Search/Browse/Explore 这个网址中&#xff0c;几…

【vue3】打包配置webpack压缩,哈希值设置

压缩配置 依赖下载&#xff1a; npm i --save-dev compression-webpack-plugin vue.config.js配置 const CompressionWebpackPlugin require(compression-webpack-plugin);filenameHashing: true, // 打包后为文件名增加hash值// 配置webpackconfigureWebpack: config >…

vue3 + elementPlus 封装hook,检测form表单数据修改变更;示例用 script setup 语法使用

vue3 elementPlus 封装hook,检测form表单数据修改变更&#xff1b;示例 script setup 语法 原文&#xff1a;https://mp.weixin.qq.com/s/gCuqKskp-KBxdClxcpwFqw原文&#xff1a;https://mp.weixin.qq.com/s/gCuqKskp-KBxdClxcpwFqw原文&#xff1a;https://mp.weixin.qq.com…

Java-泛型类

一、泛型类的基本概念 1. 什么是泛型类 泛型类是指使用类型参数定义的类&#xff0c;可以在类定义时不指定具体类型&#xff0c;而在实例化时指定。 2. 泛型类的作用 类型安全&#xff1a;编译时检查类型匹配 消除强制转换&#xff1a;减少运行时ClassCastException风险 代…

信任边界的人生智慧

我曾经是个喜欢试探的人 总想知道朋友会不会在我困难时伸手&#xff0c;合作伙伴会不会在利益面前变脸&#xff0c;爱人会不会在诱惑下坚守 结果发现&#xff0c;每一次试探都像是在关系上撒盐 不是因为对方经不起考验&#xff0c;而是「考验」这个行为本身就充满了不信任的…