Linux 入门五:Makefile—— 从手动编译到工程自动化的蜕变
一、概述:Makefile—— 工程编译的 “智能指挥官”
1. 为什么需要 Makefile?
- 手动编译的痛点:当工程包含数十个源文件时,每次修改都需重复输入冗长的编译命令(如
gcc file1.c file2.c -o app
),且无法自动识别哪些文件需要重新编译。 - Makefile 的核心价值:通过定义 “目标 - 依赖 - 命令” 规则,实现自动化编译。只需执行
make
命令,即可根据文件修改时间智能判断编译顺序,避免重复工作,大幅提升开发效率。 - 本质:一个名为
Makefile
(或makefile
)的文本文件,存储编译规则,由make
命令解析执行。
2. 核心概念快速入门
- 目标(Target):要生成的文件(如可执行文件
app
)或伪操作(如清理编译产物的clean
)。 - 依赖(Prerequisites):生成目标所需的文件(如
app
依赖main.o
和func.o
)。 - 命令(Command):生成目标的具体操作,需以Tab 键开头(Makefile 严格要求)。
二、简单使用:从第一个 Makefile 起步
1. 创建与编辑 Makefile
# 创建文件
touch Makefile
# 用vim编辑(推荐用Visual Studio Code等IDE提升体验)
vim Makefile
2. 编写第一个编译规则:编译单文件程序
# 目标:生成可执行文件hello,依赖hello.c
hello: hello.c# 命令:用gcc编译,-o指定输出文件名,@禁止回显命令本身@echo "正在编译hello..."gcc hello.c -o hello# 伪目标:清理编译产物,.PHONY避免与同名文件冲突
.PHONY: clean
clean:@echo "清理编译产物..."rm -f hello # -f强制删除,即使文件不存在也不报错
3. 执行 Makefile
# 编译目标(首次执行会生成hello)
make
# 输出:
# 正在编译hello...
# (若命令前无@,会额外回显"gcc hello.c -o hello")# 清理产物
make clean
# 输出:清理编译产物...(同时删除hello文件)
4. 关键语法解析
- 注释:
#
开头的行,用于解释规则(如# 伪目标:清理编译产物
)。 - 自动推导:Makefile 默认知道
.c
文件可编译为.o
文件(如main.o
依赖main.c
,无需显式书写规则)。 - 伪目标:用
.PHONY
声明(如clean
),确保即使存在同名文件,make clean
也会执行命令。
三、变量:让 Makefile 告别 “硬编码”
1. 自定义变量:四种赋值方式对比
赋值符号 | 特性 | 示例 | 适用场景 |
---|---|---|---|
= | 递归展开(可引用后续定义的变量) | CFLAGS = -Wall\nOBJECTS = $(SRCS:.c=.o) | 需要动态计算值的场景 |
:= | 立即展开(定义时直接计算) | SRCS := $(wildcard *.c) | 避免递归引用导致的循环定义 |
+= | 追加值(在原有值后添加新内容) | LIBS += -lm (追加数学库) | 逐步构建复杂参数 |
?= | 惰性赋值(仅在未定义时生效) | CC ?= gcc (默认用 gcc,可被命令行覆盖) | 设置默认值 |
2. 自动变量:依赖文件的 “快捷引用”
在模式规则(如%.o: %.c
)中,自动变量可简化代码:
变量 | 含义 | 示例(目标main.o 依赖main.c ) |
---|---|---|
$@ | 当前目标文件名 | 命令中$@ 代表main.o |
$< | 第一个依赖文件 | 命令中$< 代表main.c |
$^ | 所有依赖文件(去重) | 依赖a.c b.c 时,$^ 代表a.c b.c |
$? | 比目标新的依赖文件 | 仅重新编译修改过的文件 |
示例:多文件编译(使用自动变量)
CC := gcc # 立即赋值,指定编译器
CFLAGS := -Wall -g # 编译选项:开启警告和调试信息
TARGET := app # 目标文件名
SRCS := main.c func.c # 显式列出源文件(或用wildcard函数自动收集)
OBJS := $(SRCS:.c=.o) # 将.c替换为.o,生成目标文件列表$(TARGET): $(OBJS)$(CC) $(OBJS) -o $(TARGET) # 链接所有.o文件%.o: %.c$(CC) $(CFLAGS) -c $< -o $@ # 编译单个.c到.o,$<是源文件,$@是目标文件.PHONY: clean
clean:@rm -f $(OBJS) $(TARGET)
3. 预定义变量:Makefile 的 “内置工具”
Makefile 自带常用工具变量,可直接使用:
CC
:C 编译器(默认cc
,通常设为gcc
)。AR
:归档工具(用于静态库,默认ar
)。RM
:删除命令(默认rm -f
,自动添加-f
强制删除)。CXX
:C++ 编译器(默认g++
)。
示例:使用预定义变量
main.o: main.c$(CC) -c main.c -o main.o # 等价于`gcc -c main.c -o main.o`(若CC=gcc)
四、函数:让 Makefile 更 “聪明”
1. 文件搜索函数:wildcard
- 功能:按模式匹配文件,返回匹配的文件列表(支持通配符
*
)。 - 语法:
$(wildcard 模式)
,如$(wildcard src/*.c)
获取src/
目录下所有.c
文件。 - 示例:自动收集所有源文件
SRCS := $(wildcard *.c) # 收集当前目录所有.c文件 OBJS := $(SRCS:.c=.o) # 转换为.o文件列表app: $(OBJS)$(CC) $(OBJS) -o app
2. 字符串替换函数:patsubst
- 功能:按指定模式替换字符串中的部分内容。
- 语法:
$(patsubst 原模式, 新模式, 字符串)
,如$(patsubst %.c, %.o, a.c b.cpp)
→a.o b.o
(需配合手动处理.cpp 文件)。 - 示例:灵活处理混合格式源文件
SRCS := a.c b.cpp c.c # 分别将.c和.cpp转换为.o(需分步处理) C_OBJS := $(patsubst %.c, %.o, $(filter %.c, $(SRCS))) CPP_OBJS := $(patsubst %.cpp, %.o, $(filter %.cpp, $(SRCS))) OBJS := $(C_OBJS) $(CPP_OBJS)
五、选项:扩展 make 命令的能力
1. -f:指定非默认Makefile
- 场景:项目存在多个 Makefile(如
Makefile.linux
和Makefile.win
),需显式指定。 - 用法:
make -f Makefile.linux # 执行指定文件中的规则,而非默认的Makefile
2. -C:切换目录执行
- 场景:工程分模块存放(如
src/
和lib/
目录各有独立 Makefile)。 - 用法:
# 总控Makefile,编译所有模块 all:@make -C src # 进入src目录,执行该目录下的Makefile@make -C lib # 进入lib目录,执行该目录下的Makefile.PHONY: clean clean:@make -C src clean # 清理src模块@make -C lib clean # 清理lib模块
3. 其他实用选项
选项 | 含义 | 示例 |
---|---|---|
-n | 干运行,仅打印命令不执行(调试用) | make -n 查看编译步骤是否正确 |
-s | 静默模式,不回显命令(仅显示输出) | make -s 隐藏编译命令,输出更简洁 |
-j N | 并行编译,N 为线程数(加快多核 CPU 编译速度) | make -j 4 使用 4 个线程编译 |
六、实战模板:三种常用 Makefile 写法
模板一:生成可执行文件(多文件编译)
# 一、变量定义
CC := gcc # C编译器
CFLAGS := -Wall -g -Iinclude # 编译选项:警告+调试+头文件路径
SRCS := $(wildcard src/*.c) # 自动收集src目录下所有.c文件
OBJS := $(patsubst src/%.c, obj/%.o, $(SRCS)) # 生成obj/目录下的.o文件# 二、目标规则
# 1. 最终目标:生成可执行文件app
app: $(OBJS)@echo "链接生成可执行文件..."$(CC) $(OBJS) -o app -Llib -lm # -L指定库路径,-lm链接数学库# 2. 模式规则:src/xxx.c → obj/xxx.o(自动创建obj目录)
obj/%.o: src/%.c@mkdir -p obj # 确保obj目录存在$(CC) $(CFLAGS) -c $< -o $@# 三、伪目标
.PHONY: clean
clean:@echo "清理编译产物..."@rm -f app $(OBJS) # 删除可执行文件和所有.o文件@rm -rf obj # 删除obj目录
模板二:生成动态库(.so 文件)
# 一、变量定义
SO_NAME := libmylib.so # 动态库名称
CC := gcc
CFLAGS := -fPIC -Wall # -fPIC生成位置无关代码(动态库必需)
SHLIB_FLAGS := -shared # 生成动态库的关键选项
SRCS := $(wildcard src/*.c)
OBJS := $(SRCS:.c=.o)# 二、目标规则
# 1. 生成动态库
$(SO_NAME): $(OBJS)$(CC) $(SHLIB_FLAGS) $(OBJS) -o $(SO_NAME)# 2. 编译.o文件(与可执行文件规则类似)
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 三、伪目标
.PHONY: clean
clean:@rm -f $(OBJS) $(SO_NAME)
模板三:生成静态库(.a 文件)
# 一、变量定义
A_NAME := libmylib.a # 静态库名称
AR := ar rcs # ar命令参数:r(添加)c(创建)s(生成索引)
CC := gcc
CFLAGS := -Wall
SRCS := $(wildcard src/*.c)
OBJS := $(SRCS:.c=.o)# 二、目标规则
# 1. 生成静态库(打包所有.o文件)
$(A_NAME): $(OBJS)$(AR) $(A_NAME) $(OBJS) # 将.o文件打包成静态库# 2. 编译.o文件
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 三、伪目标
.PHONY: clean
clean:@rm -f $(OBJS) $(A_NAME)
七、常见易错点与避坑指南
-
命令前必须用 Tab 键:
- 错误:命令行以空格开头,导致 “missing separator (did you mean TAB instead of 8 spaces?)” 错误。
- 正确:所有命令行必须以 Tab 键开头(可在编辑器中设置 Tab 为 4 个空格,但最终需确保是 Tab 符)。
-
伪目标未声明.PHONY:
- 后果:若当前目录存在名为
clean
的文件,make clean
会认为目标已存在,不执行清理命令。 - 正确:始终为清理等伪目标添加
.PHONY: clean
声明。
- 后果:若当前目录存在名为
-
变量引用格式错误:
- 错误:直接写
变量名
(如CC=gcc
),应使用$(CC)
引用变量。 - 正确:所有变量引用需用
$(变量名)
或${变量名}
格式。
- 错误:直接写
-
依赖关系遗漏:
- 后果:头文件(
.h
)修改后,未将其加入依赖,导致.o
文件未重新编译。 - 正确:在规则中显式依赖头文件(如
main.o: main.c defs.h
),或利用 Makefile 自动推导(需确保头文件包含正确)。
- 后果:头文件(
八、作业:从模仿到独立编写
1. 任务一:解析经典 Makefile
- 下载开源项目(如
nginx
或redis
)的 Makefile,分析以下内容:
① 如何定义编译选项(CFLAGS
、CXXFLAGS
)?
② 静态库 / 动态库的生成规则有何不同?
③clean
目标如何处理多层目录的编译产物?
2. 任务二:编写三个万能模板(强化版)
- 可执行文件模板:添加对 C++ 文件的支持(
.cpp
文件用g++
编译),使用wildcard
递归搜索子目录源文件(如src/**/*.c
)。 - 动态库模板:添加版本号(如
libmylib.so.1.0.0
),使用ln -s
创建软链接(如libmylib.so → libmylib.so.1.0.0
)。 - 静态库模板:支持多架构编译(如同时生成
x86
和arm
版本),通过变量ARCH
切换编译选项。
3. 任务三:实战复杂工程
创建一个包含以下结构的项目:
project/
├─ Makefile # 总控Makefile
├─ src/
│ ├─ main.c
│ ├─ func.c
│ └─ Makefile # 模块Makefile
├─ include/
│ └─ func.h
└─ lib/ # 编译生成的库文件存放目录
要求总控 Makefile 使用-C
选项调用src/
目录下的 Makefile,最终在lib/
目录生成可执行文件。
总结:Makefile 让工程编译 “化繁为简”
通过掌握 Makefile 的核心规则、变量、函数和选项,你将实现从手动编译到自动化编译的跨越。记住以下关键点:
- 规则是基础:每个目标必须明确依赖和命令,利用自动推导简化常规编译步骤。
- 变量提效率:自定义变量减少重复输入,自动变量和预定义变量提升代码简洁性。
- 函数增智能:
wildcard
和patsubst
自动处理文件列表,适应复杂工程结构。 - 选项扩场景:
-f
和-C
应对多 Makefile 和分模块编译,-j
加速编译过程。
现在,打开你的项目,用 Makefile 替代繁琐的手动命令,让编译过程从此高效、智能!
相关文章:
Linux 入门五:Makefile—— 从手动编译到工程自动化的蜕变
一、概述:Makefile—— 工程编译的 “智能指挥官” 1. 为什么需要 Makefile? 手动编译的痛点:当工程包含数十个源文件时,每次修改都需重复输入冗长的编译命令(如gcc file1.c file2.c -o app),…...
CST入门教程:如何从SYZ参数提取电容C和电感L --- 双端口
上期解释了单端口计算S参数,然后后处理很容易提取L或C,已经满足基本需求。 这期我们看复杂一点的情况,电路中放两个端口,比如S2P: 或集总电路: 或导入SPICE: 两个端口的Y和Z参数就是四个量了,Y…...
桌面版本及服务器版本怎么查看网络源软件包的url下载路径
服务器版本: ### 利用yumdownloader工具 - 首先安装yum-utils软件包,它包含yumdownloader工具。执行命令: bash yum install yum-utils - 安装完成后,使用yumdownloader --urls <package_name>命令来获取软件包的下载UR…...
汽车零部件产线节能提效,工业网关解锁数据采集 “密码”
在汽车零部件生产领域,高效的生产监控与精准的数据采集至关重要。工业网关作为智能工厂的关键枢纽,正发挥着不可替代的作用,助力产线实现电表等多种仪表数据的采集与高效监控。 背景简析 汽车零部件产线涉及众多设备与环节,各类电…...
量化策略分类、优劣势及对抗风险解析
一、常见量化策略分类及优劣势 1. 趋势跟踪策略(Trend Following) 原理:通过捕捉价格趋势(如均线突破、动量指标)进行交易。 代表模型:海龟交易法则、Dual Thrust。 优势: 在强趋势市场&am…...
Linux调试工具——gdb/cgdb
📝前言: 这篇文章我们来讲讲Linux调试工具——gdb/cgdb: 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀CSDN主页 愚润求学 🌄其他专栏:C学习笔记,C…...
SQLite + Redis = Redka
Redka 是一个基于 SQLite 实现的 Redis 替代产品,实现了 Redis 的核心功能,并且完全兼容 Redis API。它可以用于轻量级缓存、嵌入式系统、快速原型开发以及需要事务 ACID 特性的键值操作等场景。 功能特性 Redka 的主要特点包括: 使用 SQLi…...
使用 Terraform 部署 Azure landing zone
Azure 登陆区是架构完善的环境,遵循 Microsoft 针对 Azure 云架构的最佳实践。它们为团队运行工作负载提供了良好管理的基础,从而提供了可扩展性并促进了云的采用。 如果您有兴趣部署 Azure 登陆区,Terraform 是一个不错的选择。本教程概述的…...
【搭建博客网站】老旧笔记本“零成本逆袭”
写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言博客网站搭建免费域名本地主机安装虚拟机安装宝塔及配置花生壳内网穿透 磁盘扩容 …...
XHR、FetchAxios详解网络相关大片文件上传下载
以下是 XHR(XMLHttpRequest) 与 Fetch API 的全面对比分析,涵盖语法、功能、兼容性等核心差异: 一、语法与代码风格 XHR(基于事件驱动) 需要手动管理请求状态(如 onreadystatechange 事件)和错误处理,代码冗长且易出现回调地狱。 const xhr = new XMLHttpRequest(); x…...
共享内存(与消息队列相似)
目录 共享内存概述 共享内存函数 (1)shmget函数 功能概述 函数原型 参数解释 返回值 示例 结果 (2)shmat函数 功能概述 函数原型 参数解释 返回值 (3)shmdt函数 功能概述 函数原型 参数解释…...
【3D开发SDK】HOOPS SDKS如何在BIM行业运用?
Tech Soft 3D提供了支持核心功能的软件开发工具,使开发人员可以使用Windows,Linux,OSX和移动平台等广泛的平台来构建巨大而复杂的建筑和BIM应用程序。HOOPS SDK支持多种格式的CAD导入和3D查看技术。这些技术受到了Trimble,RIB&…...
纳米软件矿用电源模块自动化测试方案分享
矿用电源模块主要是用于矿井等危险环境的一种电源系统,它可以为矿井中的仪器提供充足的电力支持。由于矿用电源经常用在危险环境中,因此对于矿用电源的稳定性要求极为严格。 纳米软件矿用电源模块自动化测试方案 测试需求分析 矿用电源模块作为矿井作业…...
pycharm中安装Charm-Crypto
一、安装依赖 1、安装gcc、make、perl sudo apt-get install gcc sudo apt-get install make sudo apt-get install perl #检查版本 gcc -v make -v perl -v 2、安装依赖库m4、flex、bison(如果前面安装过pypbc的话,应该已经装过这些包了) sudo apt-get update sudo apt…...
RTX30系显卡运行Tensorflow 1.15 GPU版本
30系显卡只支持cuda11.0及以上版本,但很多tensorflow项目用的仍然是1.1x版本,这些版本需要cuda10或者以下版本,这就导致在30系显卡上无法正常运1.1x版本的tensorflow,最近几天我也因为这个问题头疼不已,网上一番搜索…...
adb|scrcpy的安装和配置方法|手机投屏电脑|手机声音投电脑|adb连接模拟器或手机
adb|scrcpy的安装和配置方法手机投屏电脑|手机声音投电脑|adb连接模拟器或手机或电视 引言 在数字设备交织的现代生活中,adb(Android Debug Bridge)与 scrcpy 宛如隐匿的强大工具,极大地拓展了我们操控手机、模拟器乃至智能电视等…...
LangChain4j(2):Chat、流式与文生图模型功能
本文将探讨 LangChain4j 的聊天对话、流式对话以及文生图这三种常见且实用的功能,以及实际代码示例 一、聊天对话(ChatLanguageModel) 在 LangChain4j 中,使用ChatLanguageModel进行基本的聊天对话简单直观。以下是一段示例代码&a…...
Uniapp当中的async/await的作用
一、原始代码的行为(使用 async/await) const getUserMessagePlan async () > {// 等待两个异步操作完成const tabsList await message.getTagesList(); // 等待获取标签列表const tagsStateList await message.getTagsStateList(); // 等…...
JS包装类型Array
reduce()函数 没有起始值的执行过程 有初始值的执行过程 计算对象 是对象数组的情况 数组类型 方法...
Cursor + MCP让Blender实现自动建模
先决条件 Blender 3.0 或更新版本 Python 3.10 或更高版本 uv Blender安装 && 插件安装 下载Blender,版本最好是3.x以上的版本,选择适合自己的平台,地址:Download — blender.org 安装插件 从https://g…...
websocket深入-webflux+websocket
文章目录 背景版本约定配置文件代码使用webflux使用websocket配置文件handler基类实现类注册路由 背景 基于更复杂的情况和更高的开发要求,我们可能会遇到必须同时要使用webflux和websocket的情况。 版本约定 JDK21Springboot 3.2.0Fastjson2lombok 配置文件 &…...
LangChain-输出解析器 (Output Parsers)
输出解析器是LangChain的重要组件,用于将语言模型的原始文本输出转换为结构化数据。本文档详细介绍了输出解析器的类型、功能和最佳实践。 概述 语言模型通常输出自然语言文本,但在应用开发中,我们经常需要将这些文本转换为结构化的数据格式…...
wsl2+ubuntu22.04安装blenderproc教程
本章教程,介绍如何在windows操作系统上通过wsl2+Ubuntu22.04上安装blenderproc。 一、pipi安装方式 推荐使用minconda3安装Python环境。 pip install Blenderproc二、源码安装 1、下载源码 git clone https://github.com/DLR-RM/BlenderProc2、安装依赖 cd BlenderProc &am…...
矩阵热图】】
一、基础热图绘制 import matplotlib.pyplot as plt import numpy as np# 模拟数据生成 matching_history [np.random.randint(0, 2, (5, 3)) for _ in range(4)] # 5个UE,3个边缘服务器,4次迭代# 绘制最终匹配矩阵 plt.figure(figsize(10, 6)) plt.i…...
opencv人脸性别年龄检测
一、引言 在计算机视觉领域,人脸分析是一个热门且应用广泛的研究方向。其中,人脸性别年龄检测能够自动识别图像或视频流中人脸的性别和年龄信息,具有诸多实际应用场景,如市场调研、安防监控、用户个性化体验等。OpenCV 作为一个强…...
idea里面不能运行 node 命令 cmd 里面可以运行咋回事啊
idea里面不能运行 node 命令 cmd 里面可以运行咋回事啊 在 IntelliJ IDEA(或其他 JetBrains 系列 IDE)中无法运行某些命令,但在系统的命令提示符(CMD)中可以正常运行,这种情况通常是由于以下原因之一导致的…...
【ROS】软件包后期添加依赖
【ROS】软件包后期添加依赖 前言整体思路修改 package.xml1. 构建依赖(build_depend)2. 构建导出依赖(build_export_depend)3. 运行依赖(exec_depend)如何修改 修改 CMakeLists.txt修改 find_package其他修…...
十三届蓝桥杯Java省赛 B组(持续更新..)
目录 十三届蓝桥杯Java省赛 B组第一题:星期计算第二题:山第三题:字符统计第四题:最少刷题数第五题:求阶乘第六题:最大子矩阵第七题:数组切分第八题:回忆迷宫第九题:红绿灯…...
生成式人工智能的价值回归:重塑技术、社会与个体的发展轨迹
在数字化浪潮的席卷之下,生成式人工智能(Generative AI)正以前所未有的速度重塑人类社会的面貌。这项技术不仅被视为人工智能发展的新阶段,更被赋予了推动生产力跃升、加速社会形态变革的历史使命。生成式人工智能的价值回归,不仅体现在技术本身的革新与突破,更在于其对个…...
【工具开发教程】通过批量OCR识别PDF扫描件中的文本,给PDF批量重命名,基于WPF和阿里云的实现方案,超详细
以下是基于WPF和阿里云实现批量OCR识别PDF扫描件中的文本,并给PDF批量重命名的项目方案,包含项目背景、界面设计、代码步骤和开发总结。 一、项目背景 在日常办公或学习中,处理大量PDF扫描件时,常常需要手动提取文件中的文本内容并重命名文件。这种方式效率低下且容易出错…...
AI 重构 Java 遗留系统:从静态方法到 Spring Bean 注入的自动化升级
在当今快速发展的软件行业中,许多企业都面临着 Java 遗留系统的维护和升级难题。这些老旧系统往往采用了大量静态方法,随着业务的不断发展,其局限性日益凸显。而飞算 JavaAI 作为一款强大的 AI 工具,为 Java 遗留系统的重构提供了…...
JS—同源策略:2分钟掌握同源策略
个人博客:haichenyi.com。感谢关注 一. 目录 一–目录二–什么是“同源”?三–同源策略的限制范围四–允许跨源的场景五–如何绕过同源策略(安全方式)六–同源策略的安全意义七–总结 二. 什么是“同源”? …...
【C++】关于scanf是否需要使用的快速记忆
在 C 语言中,scanf 函数用于从标准输入读取数据并存储到变量中。scanf 函数需要知道变量的内存地址,以便将输入的数据存储到正确的内存位置。这就是为什么在大多数情况下需要使用 & 符号的原因。 1. 为什么需要使用& & 符号用于获取变量的内…...
BUUCTF-web刷题篇(19)
28.CheckIn 源码: #index.php <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&q…...
国家优青ppt美化_青年科学基金项目B类ppt案例模板
国家优青 国家优青,全称“国家优秀青年基金获得者”。2025改名青年科学基金B类。 作为自然基金人才资助类型,支持青年学者在基础研究方面自主选择研究方向开展创新研究。它是通往更高层次科研荣誉的重要阶梯,是准杰青梯队。 / WordinPPT /…...
【HTML】动态背景效果前端页面
下面是一个带有多种动态背景效果的现代化前端页面,包含粒子效果、渐变波浪和星空背景三种可选动态背景。直接上代码!! <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name&quo…...
前端面试宝典---创建对象的配置
Object.create 对整个对象的多个属性值进行配置 创建对象 不可更改属性值 // 创建对象 不可更改属性值 let obj Object.create({}, {name: {value: lisi,writable: false,},age: {value: 20,writable: true,} })console.log(初始化obj, obj) obj.name wangwu console.log(…...
Linux重启命令(Linux Restart Command)
Linux重启命令:深入了解reboot、shutdown、init和systemctl 在Linux系统中,重启系统是一个常见的操作,可以通过多种命令来实现。以下是一些常用的重启命令及其区别: reboot 这是一个非常通用的命令,用于重启系统。 它…...
UML-饮料自助销售系统(饮料已售完)序列图
一、题目: 在饮料自动销售系统中,顾客选择想要的饮料。系统提示需要投入的金额,顾客从机器的前端钱币口投入钱币,钱币到达钱币记录仪,记录仪更新自己的选择。正常时记录仪通知分配器分发饮料到机器前端,但可…...
第7课:智能体安全与可靠性保障
智能体安全与可靠性保障:从攻击防御到隐私保护的全栈实践 一、引言:当智能体走向开放世界:安全为何成为协作的“生命线” 随着多智能体系统(MAS)在金融、医疗、自动驾驶等关键领域的落地,安全风险呈指数级…...
前端性能优化核弹级方案:CSS分层渲染+Wasm,首屏提速300%!
前端性能优化核弹级方案:CSS分层渲染Wasm实现首屏提速300%的终极指南 在当今Web应用日益复杂的背景下,性能优化已成为前端开发的核心竞争力。本文将深入剖析两种革命性的前端性能优化技术——CSS分层渲染与WebAssembly(Wasm)的协同应用,揭示…...
有一个服务器能做什么?
服务器对于程序员来说就是一个超级便利的机器,可以用自己的知识来做出许多的使用场景。 搭建网站和应用程序 个人网站:可以创建个人博客、作品集网站或简历网站等,用于展示个人才华、分享经验和知识。 企业网站:为企业搭建官方…...
华为RH2288H V3服务器极速重装:从RedHat到openEuler 24超详细重装指南
1 登录iBMC口 2 配置启动项 点击:配置,点击:系统启动项 点击:单次有效,选择:光驱,点击:保存 3 进Remote Contro 点击:远程控制,进入如下界面 点击࿱…...
AI集群设计
关键要素 硬件选型 计算节点:通常选用配备高性能 GPU(如 NVIDIA A100、H100 等)的服务器,以提供强大的并行计算能力,加速深度学习模型的训练和推理过程。网络设备:采用高速网络,如 InfiniBand …...
NginxWebUI:可视化 Nginx 配置管理工具,告别繁琐命令行!
文章目录 📌前言1. NginxWebUI 是什么?2. NginxWebUI 核心功能3. 如何安装 NginxWebUI?3.1 Docker 安装(推荐)3.2 Java Jar 运行 4. NginxWebUI 基本使用教程4.1 登录与初始化4.2 配置反向代理4.3 管理 SSL 证书4.4 查…...
深入理解 GLOG_minloglevel 与 GLOG_v:原理与使用示例
文章目录 深入理解 GLOG_minloglevel 与 GLOG_v:原理与使用示例1. GLOG_minloglevel:最低日志等级控制2. GLOG_v:控制 VLOG() 的详细输出等级3. GLOG_minloglevel 与 GLOG_v 的优先级关系4. 使用示例4.1 基础示例:不同日志等级4.2…...
移动端六大语言速记:第12部分 - 测试与优化
移动端六大语言速记:第12部分 - 测试与优化 本文将对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言在测试与优化方面的特性,帮助开发者理解和掌握各语言的测试框架和性能优化技巧。 12. 测试与优化 12.1 单元测试框架对比 各语言单元测试框架…...
ubuntu2204安装显卡驱动+多版本的cuda+cudnn+多版本tensorRT
cuda的版本更新速度很快,这也带动TensorRT的更新速度。TensorRT SDK的更新直接从版本8升级到版本10(其实有版本9,和8相比没有大的改变)。tensorRT部署模型的很多接口都发生了较大的改变。为了体验不同版本的cuda和tensorRT的推理,本文考虑在u…...
从One-Hot到TF-IDF:NLP词向量演进解析与业务实战指南
从One-Hot到TF-IDF:词向量演进之路 开场白: 想象一下,你试图用Excel表格分析《红楼梦》的情感倾向——每个字词都是孤立的单元格,计算机看到的只有冰冷的0和1,而“黛玉葬花”的凄美意境却消失得无影无踪。这就是NLP工…...
Ubuntu下载火狐浏览器
在 Ubuntu 中卸载 Firefox 浏览器的方法取决于其安装方式(通过 APT 包管理器 或 Snap)。以下是详细的步骤: 1. 确认 Firefox 的安装方式 首先检查 Firefox 是通过哪种方式安装的: # 检查 Snap 版本 snap list | grep firefox# 检…...