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

进程与线程:05 内核级线程实现

内核级线程代码实现概述

这节课我们要讲内核级线程到底是怎么做出来的,实际上就是要深入探讨内核级线程的代码实现

在前两节课中,我们学习了用户级线程和内核级线程是如何进行切换的,以及实现切换的核心要点。那两节课讲述的内容,是内核级线程和用户级线程切换在理论层面的样子,也就是其原理,核心在于栈的切换,是由TCB(线程控制块)引发的栈切换。而这节课,我们将重点聚焦于内核级线程的代码实现

为什么这里主要强调内核级线程的代码实现呢?因为我们知道,进程实际上是由两部分组成的:一部分是资源,另一部分是执行序列,而执行序列实际上就是线程。由于进程必须进入内核,所以进程里的执行序列就是内核级线程。学会了内核级线程的代码实现,进程的代码实现就完成了大半,再加上资源管理(主要是内存管理)以及后面关于内存部分的内容,进程就可以在内核中,也就是在操作系统中得以实现。一旦完成进程在操作系统中的实现,一个完整的操作系统的雏形也就具备了。当然,要实现一个能完整运行的操作系统,你可以不支持内核级线程和用户级线程,但必须支持进程,因为只有支持进程,操作系统才能管理好CPU,否则就不能称之为操作系统。

简单来说,我们必须学会内核级线程的代码实现,再结合后面内存管理部分关于进程的代码实现,两部分结合,进程就能实现,而这就是整个操作系统框架中最核心的部分。我们一开始就说过,要具备编写一个基本操作系统的能力,所以这部分内容必不可少。

内核级线程实现原理回顾

接下来,我们看看内核级线程要实现代码编写,必须涉及哪些关键性代码。首先,再具体回顾一下,内核级线程要实现,在理论上应该是什么样的。
在这里插入图片描述

前面讲过,实现内核级线程的关键在于两套栈之间的切换。线程一旦进入内核,就使用内核栈,内核栈和用户栈通过int指令,经CPU解释后自动关联在一起。在内核中执行任务时,最终可能需要进行线程切换,也就是调度到另外一个线程去执行。

要调度到另一个线程,首先要进行TCB切换,线程控制块切换完成后,由于线程控制块里有内核栈的指针,所以内核栈也会随之切换。内核栈切换后,线程在内核栈上运行一段时间,处理完收尾工作,再通过iret指令,用户栈也跟着完成切换。

整个过程就是从用户栈到内核栈,再到TCB切换,然后内核栈切换,最后通过iret实现用户栈切换。从用户角度来看,他们看不到内核中这一系列操作,只感知到从一个栈到另一个栈的切换,同时对应的指令执行序列,即PC指针也会切换过去,整个过程包含五段,这就是我们所说的 五段论。这个图我反复讲过多次,希望大家牢记,只有在脑海中形成这个图像,后面的代码才能看懂,理解起来才会顺理成章

以fork系统调用为例分析代码实现

选择fork的原因

接下来开始讲解代码。一个用户程序进入内核依靠的是中断,更具体地说是系统调用。当然还有其他中断,如键盘中断、时钟中断等,但这些离我们当前的内容较远,像fork这种由系统调用引起的中断更为常见,所以我们就从这个中断入手
在这里插入图片描述
选择fork不仅因为它有可能引发线程切换,还因为fork是进入内核的操作,进程在内核中执行某些操作时,操作系统可能会判定当前进程不应继续执行而进行切换,比如执行到磁盘读写操作时。而且fork本身是创建进程的系统调用,进程由资源和执行序列组成,创建进程既要创建资源,也要创建执行序列,创建执行序列本质就是创建线程,所以fork对应的代码实际上就是创建线程的代码。从fork这个点切入,我们可以弄清楚两件事:一是线程如何切换,以及“五段论”在代码层面如何具体实现;二是创建一个内核级线程需要做哪些事情,是不是像前面说的,只要创造出能够切换的条件就可以。

中断入口:建立内核栈与用户栈关联

当用户程序执行到 fork 函数时,在代码层面,fork 会被编译成 int 0x80 指令。执行这条指令时,CPU 会自动进行一系列操作:找到当前的内核栈,并将当前的 SS(段选择子)和 ESP(栈指针),以及 CS(代码段寄存器)和 IP(指令指针)压入内核栈。此时,SS 和 SP 指向的是用户栈,因为 int 指令还未执行完,尚未进入内核态。这一步就完成了用户栈和内核栈的初步关联,也是 “五段论” 中的第一段。
在这里插入图片描述

紧接着,进入中断处理阶段,int 0x80 对应的中断处理函数是 system_call。在 system_call 函数中,还会进行一些压栈操作,目的是将用户态执行时的相关寄存器内容保存起来,以便后续能够从内核态返回到用户态时恢复现场。到这一步,用户态执行的相关信息都被保存在了内核栈中。

内核执行与调度判断

在完成上述操作后,会通过调用系统调用表(sys_call_table),进入到内核中具体处理 fork 的函数 sys_fork。在 sys_fork 执行过程中,可能会出现需要进行线程切换的情况。例如,当执行一些涉及 I/O 操作(如 read、write)的系统调用时,进程可能会因为等待 I/O 完成而被阻塞,此时就需要进行线程切换。在代码中,通过判断当前进程(current)的状态(state)来决定是否进行调度。如果 state 不为零(在 Linux 0.1 中,非零表示阻塞),就会调用 schedule 函数进行调度,这就涉及到了 “五段论” 中的中间三段。

调度与栈切换:中间三段的实现

当需要进行调度时,会执行 schedule 函数。在 schedule 函数中,首先会通过调度算法找到下一个要执行的进程(或内核级线程),这个过程我们会在后续专门讲解调度算法。找到下一个进程后,会执行 switch_to 函数来完成切换。
在这里插入图片描述

在 Linux 0.1 中,当前使用的切换方式是基于 TSS(任务段,Task Struct Segment)进行切换,不过我们实验的目标是将其改为基于内核栈的切换。基于 TSS 的切换,其原理是利用一条长跳转指令,通过修改任务段寄存器 TR 来实现。每个 TSS 段都有对应的描述符,TR 作为选择子,通过描述符找到 TSS 段。当执行长跳转指令时,会将当前 CPU 的所有寄存器状态保存到当前 TR 指向的 TSS 段中,然后将新的 TSS 段(对应下一个要执行的进程)的选择子赋给 TR,这样就完成了任务段的切换。由于 TSS 段中包含了 CPU 所有寄存器的信息,也就相当于完成了栈(ESP)和指令指针(EIP)等关键内容的切换,从而实现了线程的切换。但这种方式虽然代码编写相对简单,执行效率却比较低,这也是我们要进行改进的原因。

中断出口:完成用户栈切换

在这里插入图片描述

当调度完成,执行完 schedule 函数后,会返回到之前的调用点,接下来就到了中断返回阶段,这是 “五段论” 中的最后一段。在中断返回时,会执行一系列的 pop 操作,将之前保存在内核栈中的用户态寄存器内容弹出,恢复用户态的执行现场。最后执行 iret 指令,将内核栈中的 CS 和 EIP 弹出,切换回用户栈,完成整个线程切换过程,使得下一个线程能够从用户态继续执行。

fork 创建进程(线程)的具体实现

在这里插入图片描述

在 fork 执行过程中,调用 sys_fork 后,会进一步调用 copy_process 函数来创建子进程。copy_process 函数的参数来自于内核栈,这些参数包含了父进程在用户态执行时的相关信息,如 ESP(用户栈指针)等,通过这些参数,copy_process 函数能够创建出与父进程相似的子进程。
在这里插入图片描述

在 copy_process 函数中,首先会通过 get_free_page 函数获取一页内存,用于创建 PCB(进程控制块)。获取内存后,会进行一系列关键操作来设置 TSS:

设置内核栈: 将内核栈的栈顶指针设置为申请的内存页地址(p)加上 4K(PAGE_SIZE),即p + PAGE_SIZE,同时将内核数据段(这里内核数据段和内核堆栈段共用一个段)的选择子赋给 TSS 中的相关字段。

设置用户栈: 使用父进程传递过来的用户栈指针等信息,设置子进程的用户栈,使得子进程和父进程使用相同的用户栈(在用户态层面),但拥有独立的内核栈,这样在内核看来,它们是两个独立的进程(线程)。

关联与初始化: 通过这一系列操作,完成了 PCB、内核栈和用户栈的创建,并建立了它们之间的关联,同时也对 TSS 进行了初始化,为后续的线程切换做好了准备。
在这里插入图片描述

当子进程被调度执行时,通过 switch_to 函数,会将 TSS 中初始化好的内容加载到 CPU 寄存器中,其中 EIP 被设置为父进程中 int 指令执行完后的下一条指令地址,eax 被设置为 0(这是区分父子进程执行不同代码的关键)。这样,当子进程开始执行时,会根据 eax 的值(子进程为 0,父进程不为 0),执行不同的代码分支,从而实现了父子进程的不同执行逻辑,形成了 “叉子” 的两股。

exec 系统调用实现代码替换

在这里插入图片描述

我们前面讲过,创建线程后,还需要让线程执行特定的函数。在 Linux 0.1 中,虽然不直接支持创建线程执行指定函数的功能,但进程执行时可以通过 exec 系统调用实现类似效果。

当调用 exec 系统调用进入内核后,在 exec 尚未执行实际工作之前,子进程和父进程执行的是相同的代码。而 exec 的作用,就是替换子进程的执行代码。那么它是如何做到的呢?
在这里插入图片描述
在这里插入图片描述

在 exec 系统调用对应的内核函数执行过程中,会进行一些关键操作。首先会进行压栈操作,压入的内容包括参数、当前栈指针(ESP)和一个偏移量(用于计算 EIP 地址)。通过将 ESP 加上特定的偏移量(如 0x1c,十进制为 28),可以得到要执行的新代码的入口地址(entry),将这个地址赋给 EIP。这个入口地址通常来自于可执行文件的文件头,是在编译和链接阶段写入的。在内核栈设置好相关内容后,当执行中断返回的 iret 指令时,会从内核栈中弹出 EIP 的值,赋给 CPU 的指令指针寄存器,这样 CPU 就会从新的入口地址开始执行代码,从而实现了代码的替换,使得子进程能够执行新的程序(如 ls 命令对应的程序)。
在这里插入图片描述

通过以上对 fork 和 exec 系统调用的分析,我们可以看到内核级线程的代码实现涉及到多个方面,包括中断处理、栈切换、进程创建与调度、代码替换等。这些操作虽然复杂,但核心代码其实并不多,主要就是 int 指令相关操作、switch_to 中的长跳转指令(或基于内核栈切换的相关代码)以及 iret 指令,再加上一些辅助代码。只要理解了这些核心代码和整体的执行逻辑,我们就能够掌握内核级线程的代码实现,进而为编写操作系统的核心部分打下坚实的基础。希望大家通过学习和实验,能够深入理解并熟练掌握这些内容,逐步实现自己的操作系统梦想。

相关文章:

进程与线程:05 内核级线程实现

内核级线程代码实现概述 这节课我们要讲内核级线程到底是怎么做出来的,实际上就是要深入探讨内核级线程的代码实现。 在前两节课中,我们学习了用户级线程和内核级线程是如何进行切换的,以及实现切换的核心要点。那两节课讲述的内容&#xf…...

Laravel 12 实现 API 登录令牌认证

Laravel 12 实现 API 登录令牌认证 在 Laravel 12 中实现基于令牌(Token)的 API 认证,可以使用 Laravel Sanctum 或 Laravel Passport。以下是两种方式的实现方法: 方法一:使用 Laravel Sanctum (轻量级 API 认证) 1. 安装 Sanctum compo…...

【Git】万字详解 Git 的原理与使用(上)

🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. 初识 Git1.1 Git 是什么?1.2 为什么要有 Git 2. 安装 Git2.1 Linux-Ubuntu 安装 Git2.2 Windo…...

Python高级爬虫之JS逆向+安卓逆向1.7节: 面向对象

目录 引言: 1.7.1 先理解面向过程 1.7.2 再理解面向对象 1.7.3 面向对象的三大特征 1.7.4 类属性,类方法,静态方法 1.7.5 构造函数,对象属性,对象方法 1.7.6 爬虫接单实现了雪糕自由 引言: 大神薯条老师的高级爬虫+安卓逆向教程: 这套爬虫教程会系统讲解爬虫的初…...

SpringBoot基础(原理、项目搭建、yaml)

SpringBoot:javaweb的一个框架,基于Spring开发,SpringBoot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷的开发新一代基于Spring框架的应用程序,它与Spring框架紧密结合用于提升Spring开发者体验的…...

MTV-SCA:基于多试向量的正弦余弦算法

3 正弦余弦算法 (SCA) 正弦余弦算法(SCA)是为全局优化而开发的,并受到两个函数,正弦和余弦的启发。与其他基于启发式种群的算法一样,SCA在问题的预设最小值和最大值边界内随机生成候选解。然后,通过应用方…...

STL之vector容器

vector的介绍 1.vector是可变大小数组的容器 2.像数组一样,采用连续的空间存储,也就意味着可以通过下标去访问,但它的大小可以动态改变 3.每次的插入都要开空间吗?开空间就要意味着先开临时空间,然后在拷贝旧的到新…...

Android学习总结之jetpack组件间的联系

在传统安卓开发中,UI 组件(Activity/Fragment)常面临三个核心问题: 生命周期混乱:手动管理 UI 与数据的绑定 / 解绑,易导致内存泄漏(如 Activity 销毁后回调仍在触发)。数据断层&am…...

linux的信号量初识

Linux下的信号量(Semaphore)深度解析 在多线程或多进程并发编程的领域中,确保对共享资源的安全访问和协调不同执行单元的同步至关重要。信号量(Semaphore)作为经典的同步原语之一,在 Linux 系统中扮演着核心角色。本文将深入探讨…...

【安装指南】Centos7 在 Docker 上安装 RabbitMQ4.0.x

目录 前置知识:RabbitMQ 的介绍 一、单机安装 RabbitMQ 4.0.7版本 1.1 在线拉取镜像 二、延迟插件的安装 2.1 安装延迟插件 步骤一:下载延迟插件 步骤二:将延迟插件放到插件目录 步骤三:启动延迟插件 步骤四:重启 RabbitMQ 服务 步骤五:验收成果 步骤六:手动…...

Android和iOS测试的区别有哪些?

作为移动端测试工程师,Android 和 iOS 的测试差异直接影响测试策略设计。本文从测试环境、工具链、兼容性、发布流程等维度全面解析,并附实战建议。 1. 测试环境差异 维度AndroidiOS设备碎片化高(厂商/分辨率/系统版本多样)低(仅苹果设备,版本集中)系统开放性开放(可Ro…...

spring中的@PostConstruct注解详解

基本概念 PostConstruct 是 Java EE 规范的一部分,后来也被纳入到 Spring 框架中。它是一个标记注解,用于指示一个方法应该在依赖注入完成后被自动调用。 主要特点 生命周期回调:PostConstruct 标记的方法会在对象初始化完成、依赖注入完成…...

大模型开发学习笔记

文章目录 大模型基础大模型的使用大模型训练的阶段大模型的特点及分类大模型的工作流程分词化(tokenization)与词表映射 大模型的应用 进阶agent的组成和概念planning规划子任务分解ReAct框架 memory记忆Tools工具\工具集的使用langchain认知框架ReAct框架plan-and-Execute计划…...

【android Framework 探究】pixel 5 内核编译

相关文章: 【android Framework 探究】android 13 aosp编译全记录 【android Framework 探究】android 13 aosp 全记录 - 烧录 一,环境 主机 -> Ubuntu 18.04.6 LTS 内存 -> 16GB 手机 -> pixel 5 代号redfin。kernel代号redbull 二&#xf…...

PowerBI实现点击空白处隐藏弹窗(详细教程)

PowerBI点击空白处隐藏弹窗 第五届PowerBI可视化大赛中亚军作品:金融企业智慧经营分析看板 有个功能挺好玩的:点击空白处隐藏弹窗,gif动图如下: 我们以一个案例分享下实现步骤: 第一步, 先添加一个显示按钮&#xff…...

【git】获取特定分支和所有分支

1 特定分支 1.1 克隆指定分支&#xff08;默认只下载该分支&#xff09; git clone -b <分支名> --single-branch <仓库URL> 示例&#xff08;克隆 某一个 分支&#xff09;&#xff1a; git clone -b xxxxxx --single-branch xxxxxxx -b &#xff1a;指定分支…...

Windows配置grpc

Windows配置grpc 方法一1. 使用git下载grph下载速度慢可以使用国内镜像1.1 更新子模块 2. 使用Cmake进行编译2.1 GUI编译2.2 命令行直接编译 3. 使用Visual Studio 生成解决方法 方法二1. 安装 vcpkg3.配置vckg的环境变量2. 使用 vcpkg 安装 gRPC3. 安装 Protobuf4. 配置 CMake…...

【学习笔记】深入理解Java虚拟机学习笔记——第2章 Java内存区域与内存溢出异常

第2章 Java内存区域与内存溢出异常 2.1 概述 略 2.2 运行时数据区域 2.2.1 程序计数器 线程私有&#xff0c;记录执行的字节码位置 2.2.2 Java 虚拟机栈 线程私有&#xff0c;存储一个一个的栈帧&#xff0c;通过栈帧的出入栈来控制方法执行。 -栈帧&#xff1a;对应一个…...

数字智慧方案6189丨智慧应急综合解决方案(46页PPT)(文末有下载方式)

资料解读&#xff1a;智慧应急综合解决方案 详细资料请看本解读文章的最后内容。 在当前社会环境下&#xff0c;应急管理的重要性愈发凸显。国务院发布的《“十四五” 国家应急体系规划》以及 “十四五” 智慧应急专项规划&#xff0c;明确了应急管理体系建设的方向和重点&…...

解决 3D Gaussian Splatting 中 SIBR 可视化组件报错 uv_mesh.vert 缺失问题【2025最新版!】

一、&#x1f4cc; 引言 在使用 3D Gaussian Splatting&#xff08;3DGS&#xff09;进行三维重建和可视化的过程&#xff0c;SIBR_gaussianViewer_app 是一款官方推荐的本地可视化工具&#xff0c;允许我们在 GPU 上实时浏览重建结果。然而&#xff0c;许多用户在启动该工具时…...

见多识广4:Buffer与Cache,神经网络加速器的Buffer

目录 前言传统意义上的Buffer与Cache一言以蔽之定义与主要功能BufferCache 数据存储策略二者对比 神经网络加速器的bufferInput BufferWeight BufferOutput Buffer与传统buffer的核心区别总结 前言 知识主要由Qwen和Kimi提供&#xff0c;我主要做笔记。 参考文献&#xff1a; …...

微服务中组件扫描(ComponentScan)的工作原理

微服务中组件扫描(ComponentScan)的工作原理 你的问题涉及到Spring框架中ComponentScan的工作原理以及Maven依赖管理的影响。我来解释为什么能够扫描到common模块的bean而扫描不到其他模块的bean。 根本原因 关键在于**类路径(Classpath)**的包含情况&#xff1a; Maven依赖…...

C++之类和对象基础

⾯向对象三⼤特性&#xff1a;封装、继承、多态 类和对象 一.类的定义1. 类的定义格式2.类域 二.实例化1.对象2.对象的大小 三.this指针 在 C 的世界里&#xff0c;类和对象构成了面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;的核心框架&…...

【DIY小记】新手小白超频遇到黑屏问题解决分享

最近玩FPS游戏的时候&#xff0c;发现以前一顿操作超频之后的电脑&#xff0c;有一定概率会出问题。具体表现比如一种是&#xff0c;电脑显示器直接黑屏&#xff0c;所有键盘交互没有响应&#xff0c;只能直接重启电脑&#xff0c;还有一种是偶现卡顿&#xff0c;直接死机或者卡…...

虚幻引擎 IK Retargeter 编辑器界面解析

我来为您详细解释这段关于虚幻引擎IK Retargeter编辑器界面的文本&#xff0c;它描述了动画重定向系统的核心组件和工作原理。 Retarget Phases (重定向阶段) 这部分介绍了动画重定向过程中的三个关键计算阶段&#xff0c;每个阶段都可以单独启用或禁用&#xff0c;这对于调试…...

uc系统中常用命令、标准C库函数和系统调用

目录 一、常用命令 env echo $name 键值 export name unset name gcc -c xxx.c ar 命令 ar -r libxxx.a xxx1.o xxx2.o gcc -c -fpic xxx.c gcc -shared -fpic xxx1.c xxx2.c -o libxxx.so kill [-信号] PID kill -l 软链接&#xff1a;ln -s xxx yyy 硬链接&…...

OpenHarmony - 驱动使用指南,HDF驱动开发流程

OpenHarmony - HDF驱动开发流程 概述 HDF&#xff08;Hardware Driver Foundation&#xff09;驱动框架&#xff0c;为驱动开发者提供驱动框架能力&#xff0c;包括驱动加载、驱动服务管理、驱动消息机制和配置管理。并以组件化驱动模型作为核心设计思路&#xff0c;让驱动开发…...

C++负载均衡远程调用学习之UDP SERVER功能

目录 1.LARSV0.9-配置功能 2.LARSV0.10-upd-server的实现 3.LARSV0.10-udp-client的实现 1.LARSV0.9-配置功能 2.LARSV0.10-upd-server的实现 3.LARSV0.10-udp-client的实现...

word交叉引用图片、表格——只引用编号的处理方法

交叉引用图片/表格 在“引用”选项卡上的“题注”组中&#xff0c;单击“插入题注”。勾选【从题注中排除标签】。在文中插入题注。 【注 意】 这时候插入的题注只有编号项了。然后手动打上标签【TABLE】&#xff0c;并在标签和编号项之间加上【样式分隔符&#xff0c;AltCt…...

平台介绍-开放API接口-鉴权

平台的理念是一个组织内部只建一套系统。但是现实情况是&#xff0c;组织内部已经建立了很多系统&#xff0c;是不能一次性替代的&#xff0c;只能先搭起平台&#xff0c;然后逐步开始替换。这样就不可避免的存在其他系统和平台进行交互的问题。 平台为此设计了开放API接口。其…...

【Bootstrap V4系列】 学习入门教程之 组件-警告框(Alert)

Bootstrap V4 学习入门教程之 组件-警告框&#xff08;Alert&#xff09; 警告框&#xff08;Alert&#xff09;一、示例二、链接的颜色三、添加其它内容四、关闭警告框 通过 JavaScript 触发行为触发器本组件所暴露的事件 警告框&#xff08;Alert&#xff09; 通过精炼且灵活…...

【服务器通信-socket】——int socket(int domain, int type, int protocol);

#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); domain: AF_INET 这是大多数用来产生socket的协议&#xff0c;使用TCP或UDP来传输&#xff0c;用IPv4的地址 AF_INET6 与上面类似&#xff0c;不过是来用IPv6的地…...

洛谷P1014(Cantor 表[NOIP 1999 普及组])题解

题目大意&#xff1a;求Cantor表&#xff08;按照Z字形排列&#xff08;如第一项是1/1&#xff0c;然后是1/2&#xff0c;2/1&#xff0c;3/1&#xff0c;2/2&#xff09;&#xff09;的第N项。 那么&#xff0c;我们需要找出Cantor表的排列规律。根据题目中的Z字形描述&#x…...

【愚公系列】《Manus极简入门》012-自我认知顾问:“内在探索向导”

&#x1f31f;【技术大咖愚公搬代码&#xff1a;全栈专家的成长之路&#xff0c;你关注的宝藏博主在这里&#xff01;】&#x1f31f; &#x1f4e3;开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主&#xff01; &#x1f…...

密码学_加密

目录 密码学 01 密码基础进制与计量 02 加解密基操 替换 移位 编码 编码 置换 移位 加解密强度 03 对称加密算法(私钥) 工作过程 缺陷 对称加密算法列举&#xff1f; DES DES算法架构 DES分组加密公式 DES中ECB-CBC两种加密方式 3DES 由于DES密钥太短&#xf…...

w317汽车维修预约服务系统设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…...

云盘系统设计

需求背景 网盘面向大量C端用户 1000w用户 DAU 20% 每天10次 QPS: 1000w * 0.2 * 10 / 100k 500 峰值估计&#xff1a;500 * 5 2500 功能需求 支持上传&#xff0c;下载&#xff0c;多端共同在线编辑&#xff0c;数据冲突处理 非功能需求 1.latency 20s左右 2.可用性与…...

西电雨课堂《知识产权法》课后作业答案

目录 第 1 章 1.1 课后作业 1.2 课后作业 第 2 章 2.1 课后作业 2.2 课后作业 2.3 课后作业 2.4 课后作业 2.5 课后作业 2.6 课后作业 2.7 课后作业 2.8 课后作业 2.9 课后作业 2.10 课后作业 第 3 章 3.1 课后作业 3.2 课后作业 3.3 课后作业 3…...

通信协议记录仪-产品规格书

以下是为 ​​通信协议记录仪(ProtoLogger Pro)​​ 的​​详细产品规格书​​,覆盖 ​​技术细节、场景需求、竞品差异化​​,确保可作为产品开发、市场营销及竞品分析的核心依据。 ​​通信协议记录仪产品规格书​​ ​​产品名称​​:ProtoLogger Pro(中文名称:蹲守…...

订单系统冷热分离方案:优化性能与降低存储成本

随着时间推移&#xff0c;订单数据不断积累。在电商平台或者服务型应用中&#xff0c;订单数据是核心数据之一。然而&#xff0c;随着数据量的增长&#xff0c;如何高效存储、管理和查询这些数据成为了系统架构设计的重要问题。在大多数情况下&#xff0c;订单数据的处理不仅涉…...

数据结构学习笔记

第 1 章 绪论 【考纲内容】 &#xff08;一&#xff09;数据结构的基本概念 &#xff08;二&#xff09;算法的基本概念 算法的时间复杂度和空间复杂度 【知识框架】 【复习提示】 本章内容是数据结构概述&#xff0c;并不在考研大纲中。读者可通过对本章的学习&#xff0c;初步…...

读懂 Vue3 路由:从入门到实战

在构建现代化单页应用&#xff08;SPA&#xff09;时&#xff0c;Vue3 凭借其简洁高效的特性成为众多开发者的首选。 而 Vue3 路由&#xff08;Vue Router&#xff09;则是 Vue3 生态中不可或缺的一部分&#xff0c;它就像是单页应用的 “导航地图”&#xff0c;帮助用户在不同…...

Aws S3上传优化

上传大约 3.4GB 的 JSON 文件&#xff0c;zip算法压缩后约为 395MB&#xff0c;上传至 S3 效率优化&#xff0c;有一些优化方案可以提高上传速率。下面是几种可能的优化方式&#xff0c;包括选择压缩算法、调整上传方式、以及其他可能的方案。 方案 1. 选择更好的压缩算法 压…...

Python 数据智能实战 (8):基于LLM的个性化营销文案

写在前面 —— 告别群发轰炸,拥抱精准沟通:用 LLM 为你的用户量身定制营销信息 在前面的篇章中,我们学习了如何利用 LLM 增强用户理解(智能分群)、挖掘商品关联(语义购物篮)、提升预测精度(融合文本特征的流失预警)。我们不断地从数据中提取更深层次的洞察。 然而,…...

html:table表格

表格代码示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!-- 标准表格。 --><table border"5"cellspacing&qu…...

2.maven 手动安装 jar包

1.背景 有的时候&#xff0c;maven仓库无法下载&#xff0c;可以手动安装。本文以pentaho-aggdesigner-algorithm-5.1.5-jhyde.jar为例。 2.预先准备 下载文件到本地指定位置。 2.1.安装pom mvn install:install-file \-Dfile/home/wind/tmp/pentaho-aggdesigner-5.1.5-jh…...

C++ unordered_set unordered_map

上篇文章我们讲解了哈希表的实现&#xff0c;这节尝试使用哈希表来封装unordered_set/map 1. unordered_set/map的框架 封装的过程实际上与set/map类似&#xff0c;在unordered_set/map层传递一个仿函数&#xff0c;用于取出key值 由于我们平常使用的都是unordered_set/map&…...

第37课 绘制原理图——放置离页连接符

什么是离页连接符&#xff1f; 前边我们介绍了网络标签&#xff08;Net Lable&#xff09;&#xff0c;可以让两根导线“隔空相连”&#xff0c;使原理图更加清爽简洁。 但是网络标签的使用也具有一定的局限性&#xff0c;对于两张不同Sheet上的导线&#xff0c;网络标签就不…...

< 自用文 Texas style Smoker > 美式德克萨斯烟熏炉 从设计到实现 (第一部分:烹饪室与燃烧室)

原因&#xff1a; 没钱还馋&#xff01; 但有手艺。 预计目标&#xff1a; 常见的两种偏置式烟熏炉&#xff08;Offset Smoker&#xff09; 左边边是标准偏置式&#xff08;Standard Offset&#xff09;&#xff0c;右边是反向流动式&#xff08;Reverse Flow Offset&#x…...

【现代深度学习技术】现代循环神经网络03:深度循环神经网络

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…...