news 2026/2/1 19:46:08

eBPF综合指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
eBPF综合指南

eBPF 综合指南

目录

  1. 简介
  2. 历史与演进
  3. eBPF 工作原理
  4. eBPF 架构
  5. eBPF 程序
  6. eBPF Maps
  7. 应用场景
  8. 工具与生态系统
  9. 安全考虑
  10. 性能特性
  11. 快速入门
  12. 未来发展方向

简介

eBPF(Extended Berkeley Packet Filter)是一项革命性技术,它允许在 Linux 内核中安全、高效、可编程地执行沙盒程序,而无需开发内核模块或修改内核源代码。

eBPF 使开发者能够动态扩展内核功能,提供前所未有的可观测性、安全性和网络功能,同时通过验证过程确保安全性。

核心特性

  • 安全性:程序在执行前经过验证,确保不会导致内核崩溃
  • 高效性:通过 JIT(即时编译)编译为本地机器码,实现接近原生的性能
  • 可扩展性:可挂载到各种内核子系统,无需修改内核代码
  • 可移植性:通过 CO-RE(Compile Once, Run Everywhere)支持在不同内核版本上运行
  • 可编程性:使用熟悉的编程模型,支持 C 或 Rust 语言

历史与演进

起源:BPF(1992年)

Berkeley Packet Filter 由 Steven McCanne 和 Van Jacobson 于 1992 年创建,作为 BSD 操作系统中高效的数据包过滤机制。BPF 使用虚拟机在内核空间过滤数据包,然后再将其复制到用户空间,相比之前的方法显著提高了性能。

演进为 eBPF(2014年)

2014年,Alexei Starovoitov 扩展了 BPF,引入了新功能,创建了 eBPF:

  • 扩展的寄存器集(从2个扩展到10个64位寄存器)
  • 新的数据类型和指令
  • 支持 maps(键值存储)
  • 能够挂载到除数据包之外的各种内核事件
  • JIT 编译支持

重要里程碑

年份里程碑
1992原始 BPF 引入
1997BPF 集成到 Linux 内核
2011Seccomp-BPF 用于安全计算
2014eBPF 合并到 Linux 内核(v3.18)
2017XDP(eXpress Data Path)引入
2019CO-RE(Compile Once, Run Everywhere)支持
2020LSM(Linux Security Modules)钩子
2021eBPF 成为 CNCF 孵化项目
2023Windows eBPF 预览版发布

eBPF 工作原理

执行流程

┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │ eBPF 字节 │ │ 验证器 │ │ JIT/VM │ │ 代码 │────▶│ (安全性 │────▶│ 编译器 │ │ │ │ 检查) │ │ │ └─────────────┘ └──────────────┘ └─────────────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ 本地 │ │ │ 执行 │ └─────────────────────────────▶│ 在内核中 │ └──────────────┘

逐步流程

  1. 程序编译:eBPF 程序使用 C(受限子集)或 Rust 编写,通过 LLVM/Clang 编译为 eBPF 字节码

  2. 加载:通过bpf()系统调用将字节码加载到内核

  3. 验证:内核验证器执行静态分析:

    • 确保程序终止(无无限循环)
    • 检查越界内存访问
    • 验证寄存器使用和类型
    • 验证只调用允许的内核函数
  4. JIT 编译:验证后的字节码被编译为主机架构的本地机器码

  5. 挂载:程序被挂载到特定的钩子点(tracepoint、kprobe、socket 等)

  6. 执行:当钩子被触发时,eBPF 程序在该事件的上下文中执行


eBPF 架构

组件

┌─────────────────────────────────────────────────────────────┐ │ 用户空间 │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ libbpf │ │ Cilium │ │ bcc │ │ bpftrace│ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ bpftool │ │ P4/eBPF │ │ XDP │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────┘ │ bpf() 系统调用 │ ┌─────────────────────────────────────────────────────────────┐ │ 内核空间 │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 验证器 │ │ JIT 引擎 │ │ Maps │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ 钩子点 │ │ │ ├─────────┬──────────┬─────────┬─────────┬─────────────┤ │ │ │ Kprobes │ Tracepts │ Network │ LSM │ Socket │ │ │ └─────────┴──────────┴─────────┴─────────┴─────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ eBPF 程序 (JITed) │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

钩子点类型

钩子类型描述使用场景
Kprobes动态内核函数入口/返回函数跟踪、性能分析
Uprobes用户空间函数跟踪应用程序分析
Tracepoints静态内核检测点事件跟踪、调试
Socket FiltersSocket 上的数据包过滤网络监控、防火墙
XDPeXpress Data Path(最早的数据包处理)高性能网络、DDoS 防护
TC(流量控制)QoS 和数据包操作网络策略、负载均衡
cGroup每个 cgroup 的钩子资源监控、安全策略
LSM(Linux 安全模块)安全钩子访问控制、运行时安全
Perf Events性能监控事件CPU 分析、硬件计数器
Socket OperationsSocket 创建、连接等网络可观测性

eBPF 程序

程序类型

eBPF 支持多种程序类型,每种都为特定目的而设计:

enumbpf_prog_type{BPF_PROG_TYPE_SOCKET_FILTER,BPF_PROG_TYPE_KPROBE,BPF_PROG_TYPE_SCHED_CLS,BPF_PROG_TYPE_SCHED_ACT,BPF_PROG_TYPE_TRACEPOINT,BPF_PROG_TYPE_XDP,BPF_PROG_TYPE_PERF_EVENT,BPF_PROG_TYPE_CGROUP_SKB,BPF_PROG_TYPE_CGROUP_SOCK,BPF_PROG_TYPE_LWT_IN,BPF_PROG_TYPE_LWT_OUT,BPF_PROG_TYPE_LWT_XMIT,BPF_PROG_TYPE_SOCK_OPS,BPF_PROG_TYPE_SK_SKB,BPF_PROG_TYPE_CGROUP_DEVICE,BPF_PROG_TYPE_SK_MSG,BPF_PROG_TYPE_RAW_TRACEPOINT,BPF_PROG_TYPE_CGROUP_SOCK_ADDR,BPF_PROG_TYPE_LWT_SEG6LOCAL,BPF_PROG_TYPE_LIRC_MODE2,BPF_PROG_TYPE_SK_REUSEPORT,BPF_PROG_TYPE_FLOW_DISSECTOR,BPF_PROG_TYPE_CGROUP_SYSCTL,BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,BPF_PROG_TYPE_CGROUP_SOCKOPT,BPF_PROG_TYPE_TRACING,BPF_PROG_TYPE_STRUCT_OPS,BPF_PROG_TYPE_EXT,BPF_PROG_TYPE_LSM,BPF_PROG_TYPE_SK_LOOKUP,BPF_PROG_TYPE_SYSCALL,};

示例:简单的 XDP 程序

// xdp_drop.c#include<linux/bpf.h>#include<bpf/bpf_helpers.h>SEC("xdp")intxdp_drop_prog(structxdp_md*ctx){void*data_end=(void*)(long)ctx->data_end;void*data=(void*)(long)ctx->data;// 丢弃所有数据包returnXDP_DROP;}char_license[]SEC("license")="GPL";

示例:Kprobe 程序

// trace_open.c#include<linux/bpf.h>#include<bpf/bpf_helpers.h>#include<bpf/bpf_tracing.h>SEC("kprobe/do_sys_open")inttrace_do_sys_open(structpt_regs*ctx){// 记录文件打开事件bpf_printk("File opened: %s",PT_REGS_PARM1(ctx));return0;}char_license[]SEC("license")="GPL";

eBPF Maps

Map 类型

eBPF maps 是键值数据结构,允许在 eBPF 程序之间以及内核和用户空间之间共享数据:

enumbpf_map_type{BPF_MAP_TYPE_HASH,BPF_MAP_TYPE_ARRAY,BPF_MAP_TYPE_PERCPU_HASH,BPF_MAP_TYPE_PERCPU_ARRAY,BPF_MAP_TYPE_LRU_HASH,BPF_MAP_TYPE_LRU_PERCPU_HASH,BPF_MAP_TYPE_LPM_TRIE,BPF_MAP_TYPE_ARRAY_OF_MAPS,BPF_MAP_TYPE_HASH_OF_MAPS,BPF_MAP_TYPE_DEVMAP,BPF_MAP_TYPE_SOCKMAP,BPF_MAP_TYPE_CPUMAP,BPF_MAP_TYPE_XSKMAP,BPF_MAP_TYPE_SOCKHASH,BPF_MAP_TYPE_CGROUP_STORAGE,BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,BPF_MAP_TYPE_QUEUE,BPF_MAP_TYPE_STACK,BPF_MAP_TYPE_SK_STORAGE,BPF_MAP_TYPE_DEVMAP_HASH,BPF_MAP_TYPE_STRUCT_OPS,BPF_MAP_TYPE_RINGBUF,BPF_MAP_TYPE_INODE_STORAGE,BPF_MAP_TYPE_TASK_STORAGE,BPF_MAP_TYPE_BLOOM_FILTER,};

常用 Map 操作

// 创建一个哈希表structbpf_map_defSEC("maps"){.type=BPF_MAP_TYPE_HASH,.key_size=sizeof(__u32),.value_size=sizeof(__u64),.max_entries=1024,}my_map;// eBPF 程序中的 map 操作__u32 key=1;__u64 value=42;// 查找bpf_map_lookup_elem(&my_map,&key);// 更新bpf_map_update_elem(&my_map,&key,&value,BPF_ANY);// 删除bpf_map_delete_elem(&my_map,&key);

Map 对比

Map 类型描述使用场景
HASH通用哈希表通用查找
ARRAY固定大小数组索引数据、计数器
PERCPU_HASH每个 CPU 的哈希表无锁统计
LPM_TRIE最长前缀匹配树IP 路由、CIDR 匹配
RINGBUF环形缓冲区高吞吐量事件流
PERF_EVENT_ARRAY每个 CPU 的 perf 事件性能监控
SOCKMAPSocket 映射Socket 重定向、连接跟踪

应用场景

1. 可观测性和监控

eBPF 提供对系统行为的深度可见性,且开销极小:

  • 函数跟踪:跟踪任何内核或用户空间函数
  • 性能分析:CPU、内存、I/O 分析,开销极低
  • 网络监控:数据包级可见性、连接跟踪
  • 应用监控:无需修改代码即可跟踪应用行为

工具:bpftrace、bcc、Bumblebee、Parca

2. 网络

eBPF 彻底改变了网络数据包处理:

  • XDP(eXpress Data Path):在最早阶段处理数据包,实现高达 20M+ PPS
  • 负载均衡:实现自定义负载均衡算法
  • DDoS 防护:以线速过滤恶意流量
  • 服务网格:在内核中实现服务网格功能
  • 网络策略:实施细粒度的网络安全策略

项目:Cilium、Katran、Cilium Enterprise、Facebook Katran

3. 安全

eBPF 提供强大的安全功能:

  • 运行时安全:实时检测和阻止可疑行为
  • 文件系统监控:跟踪文件访问和修改
  • 进程跟踪:监控进程创建、执行和终止
  • 网络安全:实施入侵检测和防护
  • 容器安全:保护容器化环境

工具:Falco、Tracee、Tetragon、BPF Observer

4. 性能优化

  • TCP 拥塞控制:实现自定义拥塞控制算法
  • Socket 优化:优化 socket 缓冲区管理
  • Cgroup 感知调度:实现自定义调度策略
  • I/O 优化:优化块设备操作

5. 故障排除和调试

  • 内核跟踪:跟踪内核事件和函数
  • 应用调试:无需重启即可调试应用程序
  • 延迟分析:识别延迟瓶颈
  • 资源分析:跟踪资源使用模式

工具:bpftrace、bcc、drgn


工具与生态系统

核心库和工具

libbpf

用于加载和与 eBPF 程序交互的官方 C 库。提供:

  • eBPF 程序加载
  • Map 操作
  • CO-RE 支持
  • 骨架生成
# 安装 libbpfsudoaptinstalllibbpf-dev# Ubuntu/Debiansudoyuminstalllibbpf-devel# RHEL/CentOS
bpftool

用于检查和管理 eBPF 程序和 maps 的官方工具:

# 列出所有 eBPF 程序sudobpftool prog list# 显示程序详细信息sudobpftool prog showid123# 转储程序指令sudobpftool prog dump xlatedid123# 列出 mapssudobpftool map list# 转储 map 内容sudobpftool map dumpid456
bcc(BPF Compiler Collection)

基于 Python 的框架,用于编写带有嵌入式 C 的 eBPF 程序:

frombccimportBPF# 定义 eBPF 程序bpf_text=""" #include <uapi/linux/ptrace.h> BPF_HASH(start, u32); int do_entry(struct pt_regs *ctx) { u32 pid = bpf_get_current_pid_tgid(); u64 ts = bpf_ktime_get_ns(); start.update(&pid, &ts); return 0; } """# 加载和挂载b=BPF(text=bpf_text)b.attach_kprobe(event="do_sys_open",fn_name="do_entry")
bpftrace

用于 eBPF 的高级跟踪语言:

# 按进程统计系统调用bpftrace -e'tracepoint:syscalls:sys_enter_* { @[comm] = count(); }'# 分析 CPUbpftrace -e'profile:hz:99 { @[stack] = count(); }'# 跟踪文件打开bpftrace -e'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'

现代框架

Cilium

基于 eBPF 的 Kubernetes 网络、安全和可观测性:

  • 使用 eBPF 的网络策略
  • 服务网格功能
  • 负载均衡
  • 可观测性(Hubble)
# 安装 Ciliumciliuminstall--cluster-name my-cluster
libbpf-bootstrap

使用 libbpf 和 CO-RE 开发 eBPF 应用程序的模板和示例:

gitclone https://github.com/libbpf/libbpf-bootstrapcdlibbpf-bootstrapmake
Aya

基于 Rust 的 eBPF 框架,专注于开发者体验:

useaya::{Bpf,programs::KProbe};#[no_mangle]pubunsafeextern"C"fntry_to_wake_up(_ctx:*mutc_void)->i32{0}// 加载和挂载letmutbpf=Bpf::load(&[])?;letprogram:&mutKProbe=bpf.program_mut("try_to_wake_up")?;program.load()?;program.attach("try_to_wake_up",0)?;

可观测性工具

工具语言使用场景
bpftracebpftrace临时跟踪和分析
bccPython复杂跟踪工具
BumblebeeGoKubernetes 可观测性
ParcaGo持续分析
PixieC++Kubernetes 可观测性
Ebpf-exporterGo从 eBPF 生成 Prometheus 指标

安全工具

工具描述
Falco运行时安全监控
TraceeLinux 安全可观测性
Tetragon安全可观测性和执行
BPF Observer安全监控平台

安全考虑

验证器

eBPF 验证器是 eBPF 安全的基石。它执行:

  1. 控制流分析:确保所有路径都终止
  2. 内存安全:验证所有内存访问
  3. 类型检查:强制类型安全
  4. 权限检查:验证只调用允许的辅助函数
  5. 指针跟踪:跟踪指针来源和边界

安全特性

  • 沙盒执行:程序在受限环境中运行
  • 无无限循环:保证有界执行
  • 无内核内存损坏:只有安全的内存访问
  • 权限分离:CAP_BPF 能力用于加载程序
  • 命名空间隔离:程序可以感知命名空间

最佳实践

  1. 使用最新内核:较新的内核具有增强的验证器功能
  2. 最小化复杂性:更简单的程序更容易验证
  3. 使用 CO-RE:确保跨内核版本的可移植性
  4. 遵循辅助函数限制:只使用允许的辅助函数
  5. 彻底测试:首先在安全环境中验证程序

安全顾虑

  • 信息泄露:程序可能泄露内核内存
  • 拒绝服务:复杂的程序可能减慢验证速度
  • 侧信道:在某些情况下可能存在时序攻击
  • 权限提升:谨慎使用 CAP_BPF 权限

性能特性

性能优势

  • 接近原生速度:JIT 编译产生高效的本地代码
  • 零拷贝:XDP 可以在不复制的情况下处理数据包
  • 低开销:内核和用户空间之间的上下文切换最少
  • 可扩展:每个 CPU 的 maps 实现无锁操作

性能基准

使用场景性能备注
XDP Drop20-40 MPPS以线速丢弃数据包
Socket Filter10-20 Gbps数据包过滤
Kprobe Tracing<1% 开销最小的性能影响
Hash Map Lookup~50ns快速键值操作

优化技术

  1. 使用每个 CPU 的 Maps:消除锁争用
  2. 批量操作:尽可能使用批量辅助函数
  3. 提前退出:尽可能提前返回
  4. 避免循环:首选展开代码或有界循环
  5. 使用环形缓冲区:高吞吐量事件流

快速入门

前置条件

# 检查内核版本(推荐 4.10+)uname-r# 安装所需工具sudoaptupdatesudoaptinstall-y\clang\llvm\libbpf-dev\linux-headers-$(uname-r)\bpfcc-tools\linux-tools-$(uname-r)\bpftool

Hello World 示例

1. 创建 eBPF 程序(hello.bpf.c
#include"vmlinux.h"#include<bpf/bpf_helpers.h>#include<bpf/bpf_tracing.h>SEC("tp/syscalls/sys_enter_execve")inthandle_execve(void*ctx){charcomm[16];bpf_get_current_comm(&comm,sizeof(comm));bpf_printk("Hello, eBPF! Process: %s",comm);return0;}charLICENSE[]SEC("license")="GPL";
2. 创建加载器(hello.c
#include<stdio.h>#include<unistd.h>#include<bpf/libbpf.h>#include<bpf/bpf.h>intmain(){structbpf_object*obj;structbpf_program*prog;interr;// 打开 eBPF 对象文件obj=bpf_object__open_file("hello.bpf.o",NULL);if(libbpf_get_error(obj)){fprintf(stderr,"Failed to open eBPF object\n");return1;}// 加载 eBPF 程序err=bpf_object__load(obj);if(err){fprintf(stderr,"Failed to load eBPF object\n");return1;}// 查找程序prog=bpf_object__find_program_by_name(obj,"handle_execve");if(!prog){fprintf(stderr,"Program not found\n");return1;}// 挂载程序err=bpf_program__attach(prog);if(err){fprintf(stderr,"Failed to attach program\n");return1;}printf("eBPF program loaded! Press Ctrl+C to exit.\n");// 保持程序运行for(;;){sleep(1);}return0;}
3. 编译和运行
# 编译 eBPF 程序clang -g -O2 -target bpf -D__TARGET_ARCH_x86 -c hello.bpf.c -o hello.bpf.o# 编译加载器clang -g -O2 hello.c -o hello -lbpf -lelf# 运行sudo./hello# 在另一个终端,查看日志sudocat/sys/kernel/debug/tracing/trace_pipe

使用 bpftrace 进行快速实验

# 按进程统计系统调用sudobpftrace -e'tracepoint:syscalls:sys_enter_* { @[comm] = count(); }'# 分析 CPU 使用情况sudobpftrace -e'profile:hz:99 { @[stack] = count(); }'# 跟踪文件打开sudobpftrace -e'tracepoint:syscalls:sys_enter_openat { printf("%s opened %s\n", comm, str(args->filename)); }'

未来发展方向

新兴趋势

  1. Windows eBPF:Microsoft 正在开发 Windows 的 eBPF 支持
  2. 用户空间 eBPF:在用户空间运行 eBPF 程序(ubpf)
  3. 硬件卸载:将 eBPF 卸载到 NIC 和其他硬件
  4. 基于 eBPF 的服务:更多完全基于 eBPF 构建的服务
  5. 改进的工具:更好的开发工具和调试支持

活跃开发领域

  • CO-RE 改进:更好的跨内核版本可移植性
  • 新的钩子点:更多用于各种用例的挂载点
  • 增强的验证器:更快、功能更强的验证
  • Map 增强:新的 map 类型和操作
  • 文档:改进的文档和学习资源

行业采用

eBPF 正被主要公司采用:

  • Meta:使用 eBPF 进行负载均衡(Katran)和监控
  • Google:在 GKE 中使用 eBPF 进行安全和网络
  • Netflix:使用 eBPF 进行可观测性和安全
  • Cloudflare:使用 eBPF 进行 DDoS 防护和网络
  • Isovalent:由 Cilium 创始人创立,推动 eBPF 采用

资源

官方文档

  • Linux Kernel eBPF 文档
  • libbpf GitHub
  • Cilium 文档

学习资源

  • eBPF.io - eBPF 官方社区网站
  • BPF 性能工具书籍
  • Linux Observability with BPF

工具和项目

  • bcc - BPF 编译器集合
  • bpftrace - 高级跟踪语言
  • Cilium - 基于 eBPF 的网络和安全
  • libbpf-bootstrap - libbpf 入门指南

社区

  • eBPF Slack
  • eBPF 峰会
  • CNCF eBPF 工作组

结论

eBPF 代表了我们与 Linux 内核交互方式的范式转变。通过提供安全、高效和可编程的内核内部接口,eBPF 使我们在可观测性、网络、安全和性能优化方面能够实现前所未有的能力。

随着生态系统的不断成熟和采用的增长,eBPF 注定要成为云原生基础设施的基础技术,使开发者能够在不修改内核代码的情况下构建更高效、安全和可观测的系统。

eBPF 的未来是光明的,持续的开发正在扩展其在操作系统和用例方面的能力。无论您是构建监控工具、保护容器还是优化网络性能,eBPF 都为创新提供了强大的基础。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/30 19:10:55

打造全能在线表单系统源码,自定义字段+在线支付

温馨提示&#xff1a;文末有资源获取方式在数字化转型的今天&#xff0c;无论是客户预约、活动报名、服务登记还是在线收款&#xff0c;一个功能强大、灵活易用的表单系统已成为企业高效运营的刚需。今天&#xff0c;我们为您深度解析一款功能全面、支持高度自定义的万能表单解…

作者头像 李华
网站建设 2026/1/30 16:53:23

一次写入,永久锁定!OTP存储操作需谨慎

今天&#xff0c;我们一起来聊聊LuatOS中的OTP功能。 OTP&#xff08;One-Time Programmable Memory&#xff09;是一次性可编程存储。其核心特点是 “一次写入&#xff0c;永久锁定” &#xff0c;数据在物理层面无法再被修改或擦除。 典型应用场景&#xff1a; 设备身份标识…

作者头像 李华
网站建设 2026/2/1 19:49:33

mswinsck.ocx文件丢失找不到未注册问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/2/1 19:49:30

KindEditor源码解析:WORD图片复制功能如何实现?

震惊&#xff01;Java程序员遭遇"680元预算做Office全家桶Plus"的奇幻漂流 大家好&#xff0c;我是北京某Java码农老李&#xff08;头发比Spring的版本号还少的那种&#xff09;。最近接了个CMS项目&#xff0c;客户要求把Word、Excel、PPT、PDF甚至微信公众号内容统…

作者头像 李华
网站建设 2026/2/1 19:49:28

全网最全9个AI论文平台,研究生高效写作必备!

全网最全9个AI论文平台&#xff0c;研究生高效写作必备&#xff01; AI 工具如何重塑研究生的论文写作之路 在当今学术研究日益数字化的背景下&#xff0c;AI 工具正逐渐成为研究生们不可或缺的助手。尤其是在论文写作过程中&#xff0c;AI 不仅能够显著降低 AIGC&#xff08…

作者头像 李华
网站建设 2026/2/1 19:49:26

python微信小程序的新生报道报到系统

文章目录微信小程序新生报到系统摘要核心功能模块技术实现要点应用价值--nodejs技术栈--结论源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;微信小程序新生报到系统摘要 基于Python开发的微信小程序新生报到系统&#xff0c;旨在简化高…

作者头像 李华