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

[OS_9] C 标准库和实现 | musl libc | offset

在你感觉有困难的时候,计算机 一定有解决办法

操作系统为我们提供了对象和操作它们的 API:我们学习了进程管理的 fork, execve, exit, waitpid;内存管理的 mmap;文件 (对象) 管理的 open, read, write, dup, close, pipe, ……

  • 大家观察到这些 API 的设计有一个有趣的原则:“非必要不实现” (“机制与策略分离”、“最小完备性原则”):但凡应用程序能自己搞定的功能,操作系统就不需要提供——在一定程度上
  • 这样的设计能防止 “包揽一切” 导致代码膨胀,甚至在长期演化的过程中成为历史的包袱。

本文内容

在操作系统 API 之上,为了服务应用程序,毋庸置疑需要有一套 “好用” 的库函数。

虽然 libc 在今天的确谈不上 “好用”,但成就了 C 语言今天 “高级的汇编语言” 的可移植地位,以 ISO 标准的形式支撑了操作系统生态上的万千应用。

9.1 libc 简介

从 “最小” 的 C 程序出发

void _start() {__asm__("mov $60, %eax\n"  // syscall: exit"xor %edi, %edi\n" // status: 0"syscall");
}

我们可以构建 “整个应用世界”

  • C 的语言机制
    • 指针、数组、结构体、函数……
  • 系统调用
    • fork, execve, mmap, open, ...

系统调用是地基,C 语言是框架

C 语言:世界上 “最通用” 的高级语言

  • C 是一种 “高级汇编语言”
    • 作为对比,C++ 更好用,但也更难移植
  • 系统调用的一层 “浅封装”
  • C语言具有非常好的可移植性

C23: 演进没有完全停止

constexpr int n = 5 + 4;  // ???
typeof(n) arr[n];  // ???[[maybe_unused]] auto* ptr = foo();  // ???
ptr = nullptr;  // ???

解释

// 定义编译期常量n,值为5+4=9(constexpr确保编译时计算)
constexpr int n = 5 + 4;  // 等效于 constexpr int n = 9;// 创建n个元素的数组(typeof(n)推导为int,实际等效于int arr[9])
// 注意:typeof是GCC扩展语法,标准C++建议用decltype(n)或直接写int
typeof(n) arr[n];  // 最终展开:int arr[9]// [[maybe_unused]]属性消除未使用变量的警告
// auto* 自动推导foo()返回的指针类型(假设foo()返回某种指针)
[[maybe_unused]] auto* ptr = foo();  // 等效于 int* ptr = foo()(假设返回int*)// 显式置空指针,避免野指针风险
// 注意:此处赋值nullptr会覆盖之前从foo()获取的指针
ptr = nullptr;  

我们现在讲的就是 kernel 部分,shell 部分在脚本语言专栏有串讲

当然:没有库函数,寸步难行

就算有系统调用,也没法编程啊

  • 道理上可行,工程上不行
int read(int fd, void *buf, size_t count);
int write(int fd, const void *buf, size_t count);int main() {int a = ???; // 读入 aint b = ???; // 读入 bint sum = a + b;// 输出 sum ???
}

The C Standard Library

语言机制上的运行库

  • 大部分可以用 C 语言本身实现
  • 少部分需要一些 “底层支持”
    • 例子:体系结构相关的内联汇编

库也被标准化

  • ISO IEC 标准的一部分
  • POSIX --C Library 的子集
    • 稳定、可靠 (不用担心升级版本会破坏实现)
    • 极佳的移植性:包括你自己的操作系统!

关于 posix:基于 C 语言对汇编的封装,在 C 语言专栏中有介绍过,平时我们也经常用到


Prompt: 为什么称 C 语言是高级的汇编语言?

C语言被称为“高级的汇编语言”,主要因其兼具高级语言的抽象能力和接近硬件的底层控制特性:

  1. 硬件级操作
    C语言支持指针、直接内存访问和位操作,能精准控制硬件资源(如寄存器、内存地址),这与汇编语言相似。
  2. 高效性
    C代码经编译后生成的机器指令效率接近汇编,且可通过内联汇编进一步优化关键代码,适合系统级开发。
  3. 结构化抽象
    相比汇编的指令式编程,C语言提供函数、循环、条件分支等结构化语法,显著提升了代码可读性和可维护性。
  4. 跨平台与可移植
    C语言通过编译器实现硬件适配,避免了汇编语言对特定架构的强依赖,同时保留了对底层细节的控制权。

这一设计使C语言成为操作系统、嵌入式系统等对性能和(A why) 底层控制要求较高场景的理想选择。


如何 “实现” 一个 libc?

借助 cursor 来实现


minilibc: 一个用于教育目的的 C 标准库的简化实现 (claude-3.7-sonnet Cursor IDE),展示了 C 库的核心组件,包括程序的启动和结束、基本的内存管理、字符串操作以及简化的 I/O 功能。该库实现了 _start 函数以设置环境,并提供了简单的 malloc, free, strlenstrcpy。构建该库只需运行 make 命令,生成静态库和测试程序。

可见 cursor 专栏中的实现和踩坑


Prompt: 我希望学习 libc 中一些重要函数的实现,但 glibc 太复杂了。有哪些更简单的 libc,让我能链接、调试库的代码?
 

推荐以下几个轻量级 libc 实现,适合学习核心函数源码:

  1. musl-libc(推荐这个)
    ✅ 代码简洁规范,模块化设计
    ✅ 支持动态/静态链接,调试符号完整
    ✅ 常用函数如 malloc, strlen 实现清晰
    使用:gcc -static -nostdlib -I musl/include -L musl/lib 链接

  1. dietlibc
    ✅ 极简设计(约 100KB)
    ✅ 适合嵌入式场景,POSIX 兼容
    ✅ 提供 diet 工具链简化编译
    示例:diet gcc -o program program.c

  1. pdclib (Public Domain C Library)
    ✅ 专为教学设计的微型实现
    ✅ 仅实现 ISO C 标准函数
    ✅ 代码注释详细,适合逐行分析

调试建议

  • 编译时添加 -g 保留调试符号
  • 使用 gdb 单步跟踪函数调用
  • objdump -d 反汇编观察指令级实现
  • 结合标准文档 (如 POSIX) 对照源码理解设计逻辑

9.2 基础编程机制的抽象

学习已有 libc 的实现

调试 glibc?

  • 不,你不想
  • glibc 的代码有非常沉重的历史包袱
    • 以及非常多的优化——都是对 “理解原理” 的阻碍
    • 新手阅读体验极差

基本原则:总有办法的

  • 让 AI Copilot 帮你解释代码 (这个可以有)
  • 是否有比 glibc 更适合学习的 libc 实现?
    • (人的知识储备是跟不上 AI 的,更跟不上有 RAG 的 AI)
    • 幸好我还做了正确的选择:musl


学习已有 libc 的实现 (cont'd)

下载源码不难,难的是怎么 “使用” 下载的 libc

  • 我们知道可以使用 gcc 和 ld
  • 到底应该用什么编译选项?

如何使用我自己的 clang、musl 替代 glibc 编译程序?

  • 当然,我们还是选择自己编译
    • 比较重要的选项
      • -O1: 减少优化级别,便于查看状态
      • -g3: 增加调试信息
    • 使用 musl-gcc 静态编译
  • 后面章节,我们会讲到动态链接的巧妙

调试


基础数据的体系结构无关抽象

Freestanding 环境下也可以使用的定义

  • stddef.h - size_t
    • 还有一个有趣的 “offsetof” (Demo; 遍历手册的乐趣)
  • stdint.h - int32_t, uint64_t
  • stdbool.h - bool, true, false
  • float.h
  • limits.h
  • stdarg.h
  • inttypes.h
    • 打印 intptr_t 变量 printf 的格式字符串是什么?

字符串和数组操作

string.h: 字符串/数组操作

  • memcpy, memmove, strcpy, ...

stdlib.h: 常用功能

  • rand, abort, atexit, system, atoi, ...
  • 看起来就不像是人用的
// C
void qsort(void*, size_t, size_t, int (*)(const void*, const void*));// C++
std::ranges::sort(xs, [](const auto& x, const auto& y) { ... });

这些 api 在 C 语言专栏我们许多都用到过,感兴趣的可以去看看~

在 AI 的指导下阅读手册

  • 更多的 stdlib.h 中的例子
    • atoi, atol, atoll, strtoull, ...
    • rand (注意线程安全), ...
  • math.h
    • FP8: E4M3/E5M2; Quantization
    • 一个原本就深奥的课题;AI 时代变得更复杂困难
  • setjmp.h
    • 这个好玩!要用状态机去理解
  • 实现库函数 = C 语言课程习题🙂

talk with ai 专栏中有讨论过

关于 AI 擅长做什么、不擅长做什么

“Attention is all you need.”

  • 你需要给他 “关键词” (prompt engineering)
  • 推理模型降低了对 “关键词” 的依赖
    • 但 “神来之笔” 的关键词仍然能起决定性的作用


Prompt: 解释 C 标准库中的 offsetof,以及它有什么应用?
offsetof 是 C 标准库中的一个宏,定义在 <stddef.h> 头文件中。它用于计算结构体中某个成员的偏移量(相对于结构体起始地址的字节数)。

语法:

offsetof(type, member)

参数:

  • type:结构体类型。
  • member:结构体中的成员名称。

返回值: 返回 membertype 中的偏移量,类型为 size_t

应用:

  1. 内存布局分析:用于了解结构体内部的内存布局,便于调试或优化。
  2. 低级编程:在需要直接操作内存或与硬件交互时,计算偏移量可以避免硬编码
  3. 序列化/反序列化:在将结构体数据转换为字节流时,可以利用偏移量精确访问特定字段。

看越多的书之后,会发现许多知识之间都是环环相扣的,我们应始终坚信“源码之下无秘密”

示例:

#include <stdio.h>
#include <stddef.h>struct Example {int a;char b;double c;
};int main() {printf("Offset of 'a': %zu\n", offsetof(struct Example, a)); // 输出 0 //占用4字节  0-3printf("Offset of 'b': %zu\n", offsetof(struct Example, b)); // 输出 4//占用1字节 4//填充 5-7//因为 char 内存对齐 要为8的倍数printf("Offset of 'c': %zu\n", offsetof(struct Example, c)); // 输出 8return 0;
}

这个宏在需要精确控制内存布局或进行底层操作时非常有用。

至于为什么偏移这么多,C 语言内存对齐部分有详细讲过

19.(C进阶)结构体(全)

  • 总的来说,结构体的内存对齐是拿空间来换取时间的做法
  • 还有 Redis 中的 bitfield 和 C 中的位域,非常相似的!!

这里简要概述一下,结构体内存偏移现象由 数据对齐规则编译器内存填充 共同导致:


一、核心原因

  1. 对齐规则(Alignment)
    • int 类型通常需要4字节对齐(地址是4的倍数)
    • double 类型通常需要8字节对齐(地址是8的倍数)
    • char 类型无对齐要求(地址任意)
  1. 编译器填充(Padding)
    编译器会在成员之间插入空白字节,确保下一个成员满足对齐要求。

二、内存布局详解

内存地址 | 成员 | 占用字节 | 说明
----------------------------------------
0x00     | a    | 4字节    | int从0开始对齐(满足4字节对齐)
0x04     | b    | 1字节    | char无需对齐
0x05-0x07| 填充 | 3字节    | 确保下一个double从8开始(满足8对齐)
0x08     | c    | 8字节    | double对齐完成
  • 结构体总大小
    总内存 = 4(int) + 1(char) + 3(填充) + 8(double) = 16字节

三、编译指令控制对齐

可通过 #pragma pack 修改对齐规则(慎用,可能影响性能):

#pragma pack(1) // 强制1字节对齐(无填充)
struct PackedExample {int a;      // 0-3char b;     // 4double c;   // 5-12(但访问会有性能损耗)
}; // 总大小=13字节

再来看文档中的这个例子,就变得很清晰了

运行:

相关文章:

[OS_9] C 标准库和实现 | musl libc | offset

在你感觉有困难的时候&#xff0c;计算机 一定有解决办法 操作系统为我们提供了对象和操作它们的 API&#xff1a;我们学习了进程管理的 fork, execve, exit, waitpid&#xff1b;内存管理的 mmap&#xff1b;文件 (对象) 管理的 open, read, write, dup, close, pipe, …… 大…...

【氮化镓】质子辐照对 GaN-on-GaN PiN 二极管电导调制的影响

2025 年,中国科学技术大学的 Xuan Xie 等人采用实验研究的方法,深入探究了 10-MeV 和 50-MeV 质子辐照( fluence 最高达 11014 cm−2)对 kV 级垂直 GaN-on-GaN PiN 二极管的导电调制影响。研究背景在于空间应用中的功率电子电路易受质子、α 粒子和重离子等影响而降级甚至失…...

深入浅出限流算法(一):简单但有“坑”的固定窗口计数器

在现代分布式系统和 API 设计中&#xff0c;限流 (Rate Limiting) 是一个不可或缺的环节。它像一个尽职的门卫&#xff0c;保护着我们的服务资源&#xff0c;防止因突发流量或恶意攻击导致系统过载&#xff0c;同时也能确保资源的公平分配。 实现限流的算法多种多样&#xff0…...

项目上线流程梳理(Linux宝塔面板)

项目部署&#xff08;Linux宝塔面板&#xff09; 一、准备工作 1、 后端项目 梳理配置添加application-prod.yml使用maven进行打包生成jar包 2、前端项目 修改request.ts请求的后端端口&#xff08;服务器地址&#xff09;打包 二、服务器 1、服务器环境安装 2、初始化数…...

MCP Servers玩玩WebUI自动化

MCP Servers快速了解 一文搞懂 MCP Servers mcp server网站 https://mcpservers.orghttps://mcp.sohttps://glama.ai/mcp/servershttps://www.pulsemcp.com 一、安装&配置mcp clients mcp clients可以使用客户端&#xff08;常见claude desktop&#xff0c;但claude需…...

永磁同步电机控制算法-转速环电流环SMC控制器

一、原理介绍 为改进传统PI转速环电流环控制器易超调、抗干扰性能差的问题&#xff0c;转速环采用一阶滑模控制器&#xff0c;电流环采用二阶滑模控制器。 二、仿真验证 在MATLAB/simulink里面验证所提算法&#xff0c;采用和实验中一致的控制周期1e-4&#xff0c;电机部分计…...

Nginx支持HTTP2/HTTP3的并用CURL测试

对比HTTP2和HTTP3 HTTP/3 相比 HTTP/2 的主要优势&#xff1a; 项目HTTP/2HTTP/3传输层基于 TCP&#xff08; TLS&#xff09;基于 QUIC&#xff08;内置 TLS&#xff09;建立连接速度慢&#xff0c;至少 2~3 次握手&#xff08;TCP TLS&#xff09;快&#xff0c;只需 1 次握…...

阅读MySQL实战45讲第11天

目录 引言&#xff1a; 基本原理 排序方式 索引排序 文件排序&#xff08;File Sort&#xff09; 优化建议 一、全字段排序 二、rowid 排序 如果 MySQL 认为排序的单行长度太大会怎么做呢&#xff1f; 1. 使用磁盘临时表 2. 分阶段排序 3. 产生警告或错误 三、全字段排序 VS ro…...

linux 使用nginx部署vue、react项目

前言 本文基于&#xff1a;操作系统 CentOS Stream 8 使用工具&#xff1a;Xshell8、Xftp8 1.安装依赖 安装gcc、gcc-c yum install gcc gcc-c -y安装pcre、pcre-devel yum install pcre pcre-devel -y安装zlib、zlib-devel yum install zlib zlib-devel -y安装openssl、…...

逆向设计——CWDM_splitter

一、创建结构 switchtolayout; selectall; delete;## SIM PARAMS num_wg = 4; wg_width = 0.5e-6; out_wg_dist = 1e-6; mode_width = 3*wg_width; total_wg_h = num_wg*wg_width + (num_wg-1)*out_wg_dist;opt_size_x=6e-6; opt_size_y=6e-6;size_x=opt_size_x+1e-6; size_y=o…...

单片机-89C51部分:7、中断

飞书文档https://x509p6c8to.feishu.cn/wiki/A5gcwyL5giq1JOkkcsscn8eLnzf 一、中断的作用 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的&#xff0c;中断功能的存在&#xff0c;很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功…...

小波变换和图像的融合

看到一篇比较有趣的文章&#xff0c;是将小波变换融入到图像配准过程中。论文题目是Deformable medical image registration based on wavelet transform and linear attention。论文提出了一种基于小波变换和线性注意力的可变形医学图像配准方法&#xff0c;通过小波下采样模块…...

2799. 统计完全子数组的数目

给你一个由 正 整数组成的数组 nums 。 如果数组中的某个子数组满足下述条件&#xff0c;则称之为 完全子数组 &#xff1a; 子数组中 不同 元素的数目等于整个数组不同元素的数目。 返回数组中 完全子数组 的数目。 子数组 是数组中的一个连续非空序列。 示例 1&#xff…...

docker镜像构建常用参数

要退出出去ctrlpq&#xff0c;或者直接输入exit也可以直接退出 这样就生成了可以这么用&#xff0c;但安全性比较差&#xff0c;不利于审计 企业里构建的镜像这样&#xff1a; “.”是构建的地点是当前的意思&#xff1b;构建了一层在[2/2]RUN touch /leefile里面 发现有我…...

如何用postman进行批量操作

业务场景&#xff1a; 有些时候&#xff0c;我们会需要批量的将SAP B1系统中的几千条的数据删除或者取消单据&#xff0c;这个时候&#xff0c;一条条去操作&#xff0c;指定是到猴年马月了。SAP Business One本身提供了DTW这个工具&#xff0c;但是这个更新&#xff0c;可以操…...

【MCP】第三篇:Cline工具链路追踪——解码“协议引擎“的神经传导奥秘

【MCP】第三篇&#xff1a;Cline工具链路追踪——解码"协议引擎"的神经传导奥秘 一、引言二、CloudFlare AI Gateway2.1 核心定位2.2 核心能力2.3 与MCP协议逆向的深度契合 三、VSCode Cline与CloudFlare联调实战3.1 CloudFlare配置3.2 VSCode Cline配置3.3 联调实战…...

HTML标记语言_@拉钩教育【笔记】

目录 1.文本标签 2.格式化标签 3.图片标签 4.超链接标签 5.表格标签 6表单标签 6.1 6.2 6.3 7.行内框架(超链接内套一个页面) 8.多媒体标签(音/视频) 1.文本标签 2.格式化标签 3.图片标签 4.超链接标签 5.表格标签 6表单标签 6.1 6.2 6.3 7.行内框架(超链接内套一个…...

SDK游戏盾、高防IP、高防CDN三者的区别与选型指南

在网络安全防护领域&#xff0c;SDK游戏盾、高防IP和高防CDN是常见的解决方案&#xff0c;但各自的功能定位、技术实现和适用场景差异显著。本文将通过对比核心差异&#xff0c;帮助您快速理解三者特点并选择适合的防护方案。 一、核心功能定位 SDK游戏盾 功能核心&#xff1a…...

C++中的格式化字符串

C中的格式化字符串 fmt 库简介 {fmt}是一个开源的、现代化的C格式化库&#xff0c;由Victor Zverovich创建。它提供了一种安全、快速且方便的字符串格式化方式&#xff0c;其设计理念受到了Python的str.format()的启发 fmt库的主要特点 易用性&#xff1a;使用简洁的语法&a…...

民办生从零学C的第十二天:指针(1)

每日励志&#xff1a;拼搏十年&#xff0c;征战沙场&#xff0c;不忘初心&#xff0c;努力成为一个浑身充满铜臭味的有钱人。 一.内存和地址 1.内存 计算机内存是一系列存储单元的集合&#xff0c;每个存储单元都有唯一的地址来标识。这些存储单元用于存储程序的数据和指令。…...

复习Vue136~180

1.使用create-vue创建项目 npm init vuelatest 项目目录和关键文件&#xff1a; new Vue() 创建一个应用实例 > createApp()、createRouter() createStore() 、将创建实例进行了封装&#xff0c;保证每个实例的独立封闭性。 禁用vue2的插件vuter 使用vue3的插件volar scrip…...

高炉项目中DeviceNET到Ethernet的转换奥秘

在工业自动化的世界中&#xff0c;高炉项目中的数据通信至关重要。其中DeviceNET和Ethernet作为两种主流的网络协议&#xff0c;扮演着不可或缺的角色。它们之间的转换不仅仅是技术上的桥梁&#xff0c;更是实现信息高效传递的关键。今天&#xff0c;我们就来揭开从DeviceNET到…...

awk之使用详解(Detailed Explanation of Using AWK)

awk使用详解 1. 入门 1.1 什么是 awk&#xff1f; ①Awk是一种文本处理工具&#xff0c;适用于处理结构化数据&#xff0c;例如表格数据。 ②它可以读取一个或多个文本文件&#xff0c;并执行模式扫描和处理等指定的操作。 ③基本逻辑涉及数据的提取&#xff0c;排序和计算…...

TDR阻抗会爬坡? 别担心,不是你的错,你只是不够了解TDR!

在背板系统或任何长走线设计里&#xff0c;你大概都碰过这画面&#xff1a; TDR 曲线一开始乖乖在 92 Ω&#xff0c;但越往末端、阻抗越爬越高&#xff0c;来到最高 97 Ω&#xff0c;心里瞬间凉半截 &#x1f612; &#xff0c;「难不成... 板厂又翻车了吗&#xff1f;」 然…...

TypeScript之基础知识

基础知识 1. 基本类型 类型描述string字符串&#xff08;如 "hello"&#xff09;number数字&#xff08;整数或浮点数&#xff0c;支持二进制、八进制、十六进制&#xff09;boolean布尔值&#xff08;true/false&#xff09;null空值&#xff08;需显式声明&#x…...

SNMP协议之详解(Detailed Explanation of SNMP Protocol)

SNMP协议之详解 一、前言 SNMP&#xff0c;被形象地喻为网络世界大的工具箱&#xff0c;使他们能的“智慧守护者”&#xff0c;它为网络管理员装备了一套功能强够实现对网络设备状态的实时监控、性能数据的全面收集、远程配置的灵活管理以及故障事件的即时响应。借助SNMP&…...

机器学习-入门-线性模型(2)

机器学习-入门-线性模型(2) 3.4广义线性回归 一般形式&#xff1a; y g − 1 ( w T x b ) y g^{-1} \left( w^T x b \right) yg−1(wTxb) 单调可微的联系函数 (link function) 令 g ( ⋅ ) ln ⁡ ( ⋅ ) g(\cdot) \ln (\cdot) g(⋅)ln(⋅) 则得到对数线性回归 ln ⁡…...

【问题】docker容器修改环境变量的方式

问题 启动n8n之后&#xff0c;docker容器提示&#xff1a; There is a deprecation related to your environment variables. Please take the recommended actions to update your configuration: 2025-04-28 09:20:08 - N8N_RUNNERS_ENABLED -> Running n8n without tas…...

基于 Spring Boot 瑞吉外卖系统开发(八)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;八&#xff09; 自动填充公共字段 MyBatis-Plus公共字段自动填充&#xff0c;也就是在插入或者更新的时候为指定字段赋予指定的值&#xff0c;使用它的好处就是可以统一对这些字段进行处理&#xff0c;降低了冗余代码的数量。本…...

LeetCode热题100--560.和为K的子数组(前缀和)--中等

1.题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2 示例 2&#xff1a; 输入&#xff1a;nums […...

搭建 Spark YARN 模式集群指南

在大数据处理领域&#xff0c;Apache Spark 凭借其卓越的性能和易用性广受青睐。而 YARN&#xff08;Yet Another Resource Negotiator&#xff09;作为 Hadoop 的资源管理框架&#xff0c;能高效管理集群资源。将 Spark 与 YARN 结合&#xff0c;以 YARN 模式搭建集群&#xf…...

服务器部署,Nginx安装和配置

Nginx简介 Nginx是一款轻量级和高性能的web服务器、反向代理服务器和电子邮件代理服务器。你可以使用Nginx实现网页的部署&#xff0c;解决跨域问题实现邮件服务器&#xff0c;甚至Nginx也可以实现音视频推流拉流服务器&#xff0c;Nginx可以实现的功能远超你的想象&#xff0…...

Java后端接口调用拦截处理:注解与拦截器的实现

在Java开发中&#xff0c;对后端接口调用进行拦截处理是一种常见的需求&#xff0c;通常用于权限验证、Token校验、状态更新等操作。本文将围绕 Spring框架的拦截器&#xff08;Interceptor&#xff09;、Spring AOP&#xff08;面向切面编程&#xff09; 和 Spring Security 三…...

C++(初阶)(十四)——多态

多态 面向对象的其中一大特征。 多态多态的定义及构成多态的构成条件多态的实现条件多态的分类编译时多态性运行时的多态性 虚函数定义不能成为虚函数的函数 虚函数重写&#xff08;覆盖&#xff09;选择题虚函数重写的其他问题析构函数的重写override 和final关键字重载/重写…...

PyQt6基础_QThread

目录 前置 代码&#xff1a; 运行 正常运行 QThread运行报错 视频 前置 1 PySide6.QtCore.QThread - Qt for Python QThread官方文档 2 长时间任务可以放到QThread中执行&#xff0c;避免占用主线程导致界面卡顿无法操作 代码&#xff1a; import traceback,sys fro…...

工业通讯现场中关于EtherCAT转TCPIP网关的现场应用

在当今工业自动化的浪潮中&#xff0c;EtherCAT技术以其高效、实时的特性成为了众多制造业的首选。然而&#xff0c;随着工业互联网的发展&#xff0c;对于数据的远程访问和云平台集成的需求日益增长&#xff0c;这就需要将EtherCAT协议转化为更为通用的TCP/IP协议。于是开疆智…...

vite创建vue3项目并进行配置

创建项目 方式一 执行以下命令 之后输入项目名称 选择框架 选择语言 例如 pnpm create vite此方式创建的项目较为干净 0手起步 只包含一些基础依赖 例如vue vite等 项目目录如下 "scripts": {"dev": "vite","build": "vue-tsc -…...

LeetCode 热题 100_最小路径和(92_64_中等_C++)(多维动态规划)

LeetCode 热题 100_最小路径和&#xff08;92_64&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;多维动态规划&#xff09;&#xff1a; 代码实现代码实现&#xff08;思路一&#xff08;多维动态规划&…...

关于常量指针和指向常量的指针

关于指针&#xff0c;对于常量指针和指向常量的指针也是傻傻分不清。看到定义时&#xff0c;不知道是指针不能变&#xff0c;还是指针指向的内容不能变量。 先看形式&#xff1a; const char * A; char * const B; 这两种有什么区别&#xff1f;傻傻分不清。 A这种定义&am…...

新时代下的存储过程开发实践与优化

随着现代应用系统的复杂度不断增加&#xff0c;数据库作为核心的数据存储和处理引擎&#xff0c;其性能和可靠性显得尤为重要。存储过程&#xff08;Stored Procedure&#xff09;作为一种封装在数据库中的应用逻辑&#xff0c;使得开发者能够在数据库层面实现数据操作、数据校…...

4月28日日记

2025年4月28日 星期一 晴 今天过得格外充实&#xff0c;也充满了收获与喜悦。 下午&#xff0c;我参加了学校的五四述职大会。各个学院的团委书记依次上台&#xff0c;汇报过去一年的工作成果。看着大家在台上分享着各自学院的精彩故事&#xff0c;我深受触动。他们所展示的活…...

大模型性能测试

当我们部署了大模型并对外提供服务时&#xff0c;我们通常都想了解一下大模型能够支持多少个并发访问&#xff0c;在不同的并发数下&#xff0c;模型的性能如何。了解这些信息有助于我们更好的对算力进行评估&#xff0c;为用户带来更好的性能体验。 大模型通常是通过API接口的…...

利用 Google Earth Engine 探索江宁区 2010 - 2020 年 EVI 时空变化

引言 增强型植被指数&#xff08;Enhanced Vegetation Index&#xff0c;EVI&#xff09;是一种用于量化植被生长状态和覆盖程度的重要指标&#xff0c;它在监测植被动态、生态环境评估以及气候变化研究等领域发挥着关键作用。Google Earth Engine&#xff08;GEE&#xff09;…...

IEC 61850标准协议解读 2.基于Java的MMS实现

专栏文章目录 第一章 IEC 61850标准协议解读 0.导言 第二章 IEC 61850标准协议解读 1.建模讲解 第三章 IEC 61850标准协议解读 2.基于Java的MMS实现 目录 专栏文章目录前言1 依赖库引入2 创建服务端3 创建客户端4 读写模型4.1 服务端读写4.2 客户端读写 5.报告6 文件服务6.1 读…...

花费7元训练自己的GPT 2模型

在上一篇博客中&#xff0c;我介绍了用Tensorflow来重现GPT 1的模型和训练的过程。这次我打算用Pytorch来重现GPT 2的模型并从头进行训练。 GPT 2的模型相比GPT 1的改进并不多&#xff0c;主要在以下方面&#xff1a; 1. GPT 2把layer normalization放在每个decoder block的前…...

【android bluetooth 协议分析 06】【l2cap详解 10】【通过avdtp连接流程,感受l2cap通道的生命周期变化】

本篇我们通过分析一个具体的实例&#xff0c;来直观感受一下 l2cap 中通道的 状态变化。 1. 环境描述&#xff1a; 车机&#xff1a; a2dp sink手机: a2dp source场景&#xff1a; 手机主动 触发 连车机 声明一下&#xff1a; 分析的btsnoop 和 logcat 还有源码&#xff0c;…...

如何在idea中写spark程序。

要在IntelliJ IDEA中编写Spark程序&#xff0c;你可以按照以下步骤进行&#xff1a; 1. 安装和配置Java&#xff1a;确保你的计算机上已经安装了Java Development Kit (JDK)&#xff0c;并且已配置好 JAVA_HOME 环境变量。 2. 安装IntelliJ IDEA&#xff1a;下载并安装Inte…...

Pytest-mark使用详解(跳过、标记、参数 化)

1.前言 在工作中我们经常使用pytest.mark.XXXX进行装饰器修饰&#xff0c;后面的XXX的不同&#xff0c;在pytest中有不同的作 用&#xff0c;其整体使用相对复杂&#xff0c;我们单独将其抽取出来做详细的讲解。 2.pytest.mark.skip()/skipif()跳过用例 import pytest #无条…...

[Android] GKD v1.10.3

[Android] GKD 链接&#xff1a;https://pan.xunlei.com/s/VOOwKvmwpLoLl7fLi6wJZKK-A1?pwd8mey# GKD&#xff08;详情请戳 作者项目地址&#xff09;是一款免费开源简洁多规则的自动跳过广告的软件&#xff0c;整体基于kotlin开发&#xff0c;免root即可使用。简而言之&am…...

C22-作业练习之最大公约数与最小公倍数

作业练习之最大公约数与最小公倍数 代码 #include <stdio.h> int main() {//变量初始化int m,n;int i,gcd,lcm;//数据录入printf("请输入两个整数:");scanf("%d %d",&m,&n);//求最大公约数int min(m<n)?m:n; //找m与n的最小值for(imi…...