【iOS】编译和链接、动静态库及dyld的简单学习

文章目录

  • 编译和链接
    • 1️⃣核心结论:一句话区分
    • 2️⃣编译过程:从源代码到目标文件(.o)
      • 2.1 预处理(Preprocessing):“替换变量+复制粘贴”
      • 2.2 编译(Compilation):“翻译成机器能懂的语言”
      • 2.3 汇编(Assembly):“翻译成机器指令”
      • 2.4 实战:用命令行观察编译过程
  • 动态库和静态库
    • 1️⃣关于动态库和静态库核心结论:一句话区分
    • 2️⃣底层原理:编译链接过程的差异
      • 2.1 静态库(.a / .framework):“复制粘贴”到可执行文件
      • 2.2 动态库(.dylib / .framework / .tbd):“取件券”+ 运行时加载
    • 3️⃣核心差异对比:体积、内存、更新、依赖
    • 4️⃣实战:iOS 中的静态库与动态库
      • 4.1 静态库的典型应用
      • 4.2 动态库的典型应用
    • 5️⃣常见误区
      • 误区 1:动态库一定比静态库“好”
      • 误区 2:动态库体积一定小
      • 误区 3:iOS 中动态库无法直接使用
    • 6️⃣总结:如何选择?
  • DYLD
    • 1️⃣DYLD 是什么?核心职责
    • 2️⃣DYLD 的工作流程(以 iOS App 启动为例)
      • 2.1 准备阶段:收集依赖信息
      • 2.2 加载阶段:将动态库读入内存
      • 2.3 符号解析:找到函数的“实际地址”
      • 2.4 链接阶段:缝合程序与动态库
    • 3️⃣DYLD2:经典但逐渐落后的动态链接器
      • 3.1 DYLD2 的核心问题
        • (1)启动速度慢:串行加载 + 全量加载
        • (2)符号解析效率低:全局锁竞争
        • (3)内存碎片:重复加载相同库
    • 4️⃣DYLD3:苹果的“性能革命”动态链接器
      • 4.1 启动速度优化:并行加载 + 按需加载
        • (1)并行加载依赖库
        • (2)惰性加载(Lazy Binding)升级
      • 4.2 内存效率优化:共享缓存 + 惰性卸载
        • (1)共享缓存(`dyld shared cache`)
        • (2)惰性卸载(Lazy Unloading)
      • 4.3 新特性支持:适配现代系统
    • 5️⃣DYLD3 的底层技术细节
      • 5.1 依赖关系图分析(Dependency Graph)
      • 5.2 符号解析的“三级跳”
      • 5.3 内存管理的“智能回收”
    • 6️⃣开发者如何适配 DYLD3?
      • 6.1 检查当前使用的 DYLD 版本
      • 6.2 适配 DYLD3 的注意事项
        • (1)避免依赖加载顺序
        • (2)优化符号可见性
        • (3)减少动态库依赖
        • (4)适配 Swift 代码
    • 7️⃣总结

编译和链接

1️⃣核心结论:一句话区分

  • 编译:把“设计图纸”(源代码)翻译成“建筑零件”(目标文件),解决单个文件的“语法正确性”和“初步功能实现”。
  • 链接:把多个“建筑零件”(目标文件)和“标准建材”(库文件)组装成“完整房子”(可执行文件),解决多文件间的“依赖关系”和“符号解析”。

2️⃣编译过程:从源代码到目标文件(.o)

编译是将 单个源代码文件(.m/.c) 转换为 目标文件(.o,Object File) 的过程,本质是“翻译+初步加工”。它分为 4 个阶段,像“工厂流水线”一样逐步处理。

2.1 预处理(Preprocessing):“替换变量+复制粘贴”

预处理是编译的第一步,主要处理源代码中的 预处理指令(以 # 开头的行),类似“批量替换”和“文件拼接”。

常见预处理指令

  • #import/#include:复制头文件内容到当前文件(类似“粘贴”)——小心循环引用。
  • #define:定义宏(如 #define MAX(a,b) ((a)>(b)?(a):(b))),编译前替换代码中的宏调用(类似“批量替换”)。
  • #ifdef/#endif:条件编译(根据宏是否存在决定是否保留某段代码)。

例子
假设 Dog.h 内容为:

#define DOG_NAME @"小狗"
@interface Dog : NSObject
- (void)setName:(NSString *)name;
@end

Dog.m#import "Dog.h" 时,预处理会将 DOG_NAME 替换为 @"小狗",并将 Dog 类的声明复制到 Dog.m 中。

2.2 编译(Compilation):“翻译成机器能懂的语言”

预处理后的代码会被编译器(如 Clang)转换为 汇编代码.s 文件),这是“人类能读懂的机器语言”。

关键步骤

  • 语法检查:检查代码是否符合 OC 语法规则(如方法名是否正确、括号是否匹配)。如果报错(如“Expected ‘;’ after expression”),编译失败。
  • 语义分析:检查代码逻辑是否合理(如变量是否声明后使用、方法是否存在)。例如,调用 [dog fly]Dog 类没有 fly 方法,编译器会警告(但不会报错,因为 OC 是动态语言)。
  • 生成汇编:将 OC 代码转换为 CPU 能识别的汇编指令(如 movcall 等)。

2.3 汇编(Assembly):“翻译成机器指令”

汇编器(如 as)将汇编代码(.s)转换为 机器指令(二进制格式),生成 目标文件(.o)

目标文件(.o)的内容

  • 代码段(Text Section):存储机器指令(如方法的具体实现)。
  • 数据段(Data Section):存储全局变量、静态变量(如 static int count = 0)。
  • 符号表(Symbol Table):记录文件中定义的符号(如函数名、全局变量名)和引用的外部符号(如调用了其他文件的方法)。
  • 重定位表(Relocation Table):记录需要外部链接的位置(如调用了其他文件的方法,需要链接时修正地址)。

2.4 实战:用命令行观察编译过程

在 macOS 终端,用 clang 命令手动编译一个 OC 文件,观察中间产物:

# 编译 Dog.m 生成 Dog.o(目标文件)
clang -c Dog.m -o Dog.o# 查看 Dog.o 的符号表(包含定义和引用的符号)
nm Dog.o
# 输出类似:
#                 U _NSLog
#                 T _dogSayHello
# 0000000000000000

我们用 “工具包”“共享仓库” 的生活化场景,结合 iOS 开发中的实际案例,彻底讲透 静态库动态库 的区别与核心逻辑。

动态库和静态库

1️⃣关于动态库和静态库核心结论:一句话区分

  • 静态库:把“工具包”(代码)直接“塞进”你的工具箱(可执行文件),你的工具箱从此“自给自足”,但体积变大。
  • 动态库:把“工具包”放在“共享仓库”(系统目录),你的工具箱只留一张“取件券”(引用),需要时去仓库拿,体积小但依赖仓库。

2️⃣底层原理:编译链接过程的差异

2.1 静态库(.a / .framework):“复制粘贴”到可执行文件

静态库的本质是 一组目标文件(.o)的打包集合(用 ar 工具打包)。在编译链接阶段,编译器会把静态库中所有用到的代码 完整复制 到最终的可执行文件中。静态库通常以 .a(Unix、Linux)或 .lib(Windows)以及MacOS 独有的 .framework为扩展名。

关键步骤

  1. 编译源文件生成 .o 目标文件(如 Dog.o)。
  2. 链接器将 .o 文件和静态库(如 libDog.a)中需要的 .o 合并,生成可执行文件(如 App)。
  3. 可执行文件体积增大(包含静态库的所有代码),但运行时无需额外依赖。

2.2 动态库(.dylib / .framework / .tbd):“取件券”+ 运行时加载

动态库的本质是 独立的二进制文件,存储在系统或应用的特定目录中。编译链接阶段,编译器只记录动态库中用到的函数的“地址线索”(符号引用),不会复制代码到可执行文件中。动态库的格式有:.framework、.dylib、.tbd……

关键步骤

  1. 编译源文件生成 .o 目标文件(如 Dog.o)。
  2. 链接器生成可执行文件时,仅记录动态库(如 libDog.dylib)的路径和符号引用(如 +[Dog bark])。
  3. 运行时,系统根据可执行文件中的“地址线索”,从动态库中加载所需代码到内存,供程序调用。

3️⃣核心差异对比:体积、内存、更新、依赖

对比项静态库动态库
体积可执行文件体积大(包含库代码)可执行文件体积小(仅存符号引用)
内存占用每个程序独立复制库代码,内存浪费多个程序共享同一份库代码,内存高效
更新维护库更新需重新编译所有依赖它的程序替换动态库文件即可,无需重新编译程序
依赖管理无外部依赖(库代码已嵌入)强依赖动态库路径(运行时需找到库文件)
典型场景需独立运行的工具(如命令行程序)系统框架(如 UIKit)、高频共享库

4️⃣实战:iOS 中的静态库与动态库

4.1 静态库的典型应用

  • 自定义静态库:开发者将常用功能(如网络请求、加密算法)打包为 .a.framework,提供给其他项目直接集成。
    ​优点​​:避免重复开发,保护代码隐私(静态库代码嵌入可执行文件,反编译难度更高)。
    ​缺点​​:每次更新库需重新编译宿主项目。

4.2 动态库的典型应用

  • 系统框架(如 UIKit、Foundation):iOS 系统自带的核心框架均为动态库,存储在 /System/Library/Frameworks 目录。
    ​优点​​:所有 App 共享同一份框架代码,大幅节省内存;系统升级时自动更新框架(如 iOS 17 升级后,UIKit 动态库同步更新)。
  • 第三方动态库(如微信 SDK、支付宝 SDK):部分 SDK 提供动态库版本(.framework.tbd),允许 App 直接调用,无需嵌入代码。

5️⃣常见误区

误区 1:动态库一定比静态库“好”

动态库的优势是节省内存和方便更新,但并非所有场景都适用:

  • 若需要 离线运行(如无网络环境下的工具类 App),静态库更可靠(无需依赖外部动态库)。
  • 若库代码需要 高度定制(如修改底层实现),静态库更灵活(直接修改源码重新编译)。

误区 2:动态库体积一定小

动态库本身的体积可能很大(如 UIKit 框架),但多个 App 共享时,内存总占用会远小于每个 App 都嵌入一份静态库的体积。

误区 3:iOS 中动态库无法直接使用

iOS 支持动态库,但需注意:

  • 自定义动态库需通过 Xcode 打包为 .framework(需设置 Install Path@executable_path/Frameworks)。
  • 上架 App Store 时,动态库需包含在 App 包内(否则无法加载),因此实际开发中静态库更常见于第三方 SDK。

6️⃣总结:如何选择?

  • 选静态库:需要独立运行、保护代码、避免外部依赖。
  • 选动态库:需要共享内存、频繁更新、节省资源。

一句话总结:静态库是“一次性买断的工具包”,动态库是“共享仓库的取件券”,根据需求选择最适合的复用方式。

DYLD

1️⃣DYLD 是什么?核心职责

DYLD(Dynamic Link Editor)是苹果为 macOS/iOS 设计的 动态链接器,负责解决程序运行时的 动态依赖 问题。它的核心职责可以概括为三个步骤:

  1. 加载动态库:将程序依赖的 .dylib.framework 或系统库从磁盘加载到内存。
  2. 解析符号:找到程序中调用的函数/变量在动态库中的实际内存地址(符号绑定)。
  3. 链接程序:将程序代码与动态库代码“缝合”,确保调用动态库函数时能正确跳转。

2️⃣DYLD 的工作流程(以 iOS App 启动为例)

无论 DYLD2 还是 DYLD3,核心流程都围绕 加载→解析→链接 展开,但具体实现细节差异巨大。以下是通用流程:

2.1 准备阶段:收集依赖信息

App 启动时,内核(kernel)会读取可执行文件的 头部信息Mach-O 头),获取其依赖的动态库列表(如 libSystem.dylibUIKit.framework)。

关键数据结构

  • dyld_image_info:记录每个动态库的路径、加载地址、依赖关系等信息。

2.2 加载阶段:将动态库读入内存

根据依赖列表,DYLD 从磁盘或共享缓存(dyld shared cache)中加载动态库到内存。

DYLD2 的加载方式

  • 串行加载:按依赖顺序逐个加载(如先加载 A.dylib,再加载依赖 AB.dylib)。
  • 全量加载:即使动态库未被立即使用,也会完整加载到内存(可能导致内存浪费)。

2.3 符号解析:找到函数的“实际地址”

程序中调用的函数(如 [UIView addSubview:])在编译时只是符号(如 _objc_msgSend),DYLD 需要将其映射到动态库中的真实内存地址。

DYLD2 的符号解析

  • 全局锁阻塞:所有符号解析需竞争同一把全局锁(dyld lock),多线程场景下容易成为瓶颈。
  • 懒解析(Lazy Binding):部分符号延迟到首次调用时解析(减少启动时的计算量)。

2.4 链接阶段:缝合程序与动态库

将程序的代码段(__TEXT)与动态库的代码段(__TEXT)通过 内存地址重定位 关联,确保调用指令(如 call)能正确跳转到动态库的函数入口。

3️⃣DYLD2:经典但逐渐落后的动态链接器

DYLD2 是苹果早期的动态链接器(随 macOS 10.4/Tiger 引入),在 iOS 13 前是默认实现。它的设计思路是 稳定优先,但在性能和内存效率上存在明显短板。

3.1 DYLD2 的核心问题

(1)启动速度慢:串行加载 + 全量加载
  • 串行加载:依赖链越长(如复杂 App 可能有数百个动态库),加载时间越长。例如,一个依赖 100 个动态库的 App,DYLD2 需执行 100 次磁盘读取和内存分配。
  • 全量加载:即使动态库仅在后台使用(如统计 SDK),也会在启动时完整加载,占用宝贵的内存资源(尤其是 iOS 设备内存有限)。
(2)符号解析效率低:全局锁竞争

DYLD2 使用全局锁(dyld lock)保证符号解析的线程安全,但多线程场景下(如 App 启动时同时初始化多个模块),锁竞争会导致大量线程阻塞,延长启动时间。

(3)内存碎片:重复加载相同库

多个进程(如同时运行的微信、支付宝)若依赖同一动态库(如 libSystem.dylib),DYLD2 会为每个进程单独加载一份,导致内存冗余(同一库在内存中存在多份副本)。

4️⃣DYLD3:苹果的“性能革命”动态链接器

DYLD3 随 iOS 13/macOS 10.15 引入,目标是 大幅提升启动速度、降低内存占用。它针对 DYLD2 的痛点进行了全面重构,核心改进体现在以下方面:

4.1 启动速度优化:并行加载 + 按需加载

(1)并行加载依赖库

DYLD3 通过 依赖关系图分析dependency graph),识别无冲突的动态库(即彼此无依赖的库),并 并发加载 它们。例如,若 A.dylibB.dylib 无依赖关系,DYLD3 可同时加载这两个库,将加载时间从串行的 T1+T2 缩短为 max(T1, T2)

技术实现

  • 使用 dispatch_grouppthread 实现多线程加载。
  • 通过 dyld3 私有 API 与内核协作,优化磁盘读取(如预读取相邻磁盘块)。
(2)惰性加载(Lazy Binding)升级

DYLD3 将“懒解析”从“部分符号”扩展到“大部分符号”,仅在函数 首次调用时 执行符号解析和地址重定位。例如,一个包含 1000 个函数的动态库,若启动时仅调用其中 10 个,DYLD3 仅解析这 10 个函数的地址,其余 990 个延迟到调用时处理。

4.2 内存效率优化:共享缓存 + 惰性卸载

(1)共享缓存(dyld shared cache

DYLD3 引入 全局共享缓存,将常用动态库(如 libSystem.dylibUIKit.framework)的解析结果(符号地址、加载路径等)缓存到系统级内存中。多个进程(如微信、支付宝)调用同一库时,直接从共享缓存中读取,避免重复加载和解析。

数据验证

  • 共享缓存可减少 30%-50% 的动态库加载时间(苹果官方测试数据)。
(2)惰性卸载(Lazy Unloading)

DYLD3 允许未使用的动态库在内存紧张时被卸载(回收内存),并在需要时重新加载。例如,一个后台统计库在 App 切到前台时未被使用,DYLD3 可将其卸载,释放内存给前台模块。

4.3 新特性支持:适配现代系统

DYLD3 针对 iOS 13+ 和 macOS 10.15+ 的新特性做了深度优化:

特性DYLD3 支持细节
Swift 动态链接优化 Swift 符号的绑定(如泛型、协议扩展),减少 Swift 代码的启动延迟(比 DYLD2 快 20%+)。
arm64e 架构针对苹果自研芯片(如 A12+)优化指令集适配,提升 ARM64e 代码的执行效率。
App Sandbox 安全增强对动态库的签名验证(检查 LC_CODE_SIGNATURE),防止恶意库注入(仅允许加载已签名库)。

5️⃣DYLD3 的底层技术细节

5.1 依赖关系图分析(Dependency Graph)

DYLD3 在加载前会构建 依赖关系图(有向无环图,DAG),通过拓扑排序确定加载顺序。例如:

App → A.dylib → B.dylib  
App → C.dylib → B.dylib  

此时,B.dylibAC 的共同依赖,DYLD3 会先加载 B.dylib,再并行加载 AC

5.2 符号解析的“三级跳”

DYLD3 的符号解析分为三个阶段,逐步细化:

  1. 预解析(Prebinding):在加载阶段,通过共享缓存快速查找符号的大致地址范围(减少后续搜索时间)。
  2. 精确解析(Binding):首次调用符号时,通过 dyld_stub_binder 函数精确计算符号的内存地址(更新 __DATA 段的指针)。
  3. 缓存优化(Caching):将解析结果存入共享缓存,后续调用直接读取缓存(避免重复计算)。

5.3 内存管理的“智能回收”

DYLD3 使用 引用计数 + LRU(最近最少使用) 策略管理动态库内存:

  • 每个动态库被加载后,引用计数加 1(进程持有)。
  • 当内存紧张时,DYLD3 优先卸载引用计数低且长时间未使用的库(LRU 策略)。

6️⃣开发者如何适配 DYLD3?

6.1 检查当前使用的 DYLD 版本

  • 通过日志:运行应用时添加环境变量 DYLD_PRINT_VERSION=1,日志会输出 dyld: version 3.x(DYLD3)或 dyld: version 2.x(DYLD2)。
  • 通过系统版本:iOS 13+ 和 macOS 10.15+ 默认启用 DYLD3(除非强制指定 DYLD2)。

6.2 适配 DYLD3 的注意事项

(1)避免依赖加载顺序

DYLD3 的并行加载可能改变动态库的加载顺序,若代码依赖特定顺序(如 +load 方法中调用其他库的函数),可能导致崩溃。需确保 +load 方法无外部依赖。

(2)优化符号可见性

DYLD3 对未导出的符号(如 static 函数)解析更严格,需通过 __attribute__((visibility("default"))) 显式导出:

// 显式导出符号,避免 DYLD3 无法解析
__attribute__((visibility("default")))
void myFunction() {// ...
}
(3)减少动态库依赖

DYLD3 虽然优化了加载效率,但过多的动态库仍会增加依赖图复杂度。尽量合并功能到少量动态库,或使用静态库(仅当需要离线运行时)。

(4)适配 Swift 代码

DYLD3 对 Swift 的支持更友好,但仍需注意:

  • 避免使用 @_transparent 等私有属性(可能影响符号可见性)。
  • 确保 Swift 模块的 swiftmodule 目录结构正确(DYLD3 依赖此结构解析符号)。

7️⃣总结

DYLD 从 DYLD2 到 DYLD3 的演进,本质是苹果对 启动速度内存效率 的极致追求。DYLD3 通过并行加载、共享缓存、惰性解析等技术,将动态链接的瓶颈从“启动时间”转移到“运行时效率”,为现代 iOS 应用的高性能运行提供了底层保障。

开发者行动建议

  • 优先适配 DYLD3(目标系统为 iOS 13+),利用其性能优势。
  • 优化动态库依赖,减少不必要的加载。
  • 关注苹果官方文档,及时适配新特性(如 Swift 动态链接优化)。

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

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

相关文章

金山办公WPS项目产品总监陈智新受邀为第十四届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会珠海金山办公软件有限公司WPS项目产品总监 陈智新先生 受邀为“PMO评论”主办的2025第十四届中国PMO大会演讲嘉宾,演讲议题为:中小团队PMO的成长之路,敬请关注!议题简要:在竞争激烈、需求多变的…

web安全 | docker复杂环境下的内网打点

本文作者:Track-syst1m一.前言本文涉及的相关漏洞均已修复、本文中技术和方法仅用于教育目的;文中讨论的所有案例和技术均旨在帮助读者更好地理解相关安全问题,并采取适当的防护措施来保护自身系统免受攻击。二.大概流程1. 外网打点• 漏洞利…

iTwin 几何属性获取

面积体积半径获取几何属性,如面积,体积,半径,可以使用getMassProperties这个接口async onGetMassProperty(){const vp IModelApp.viewManager.selectedView;const iModel vp?.iModel;if (!iModel) return;console.log("iM…

OpenLayers 快速入门(九)Extent 介绍

看过的知识不等于学会。唯有用心总结、系统记录,并通过温故知新反复实践,才能真正掌握一二 作为一名摸爬滚打三年的前端开发,开源社区给了我饭碗,我也将所学的知识体系回馈给大家,助你少走弯路! OpenLayers…

LeetCode 121. 买卖股票的最佳时机 LeetCode 122. 买卖股票的最佳时机II LeetCode 123.买卖股票的最佳时机III

LeetCode 121. 买卖股票的最佳时机尝试一:暴力解决方法常用两个指针去遍历prices数组,dp[i]用于记录在第i天所获得的最大利润。时间复杂度是O(N^2),超出时间限制。Codeclass Solution(object):def maxProfit(self, prices):"""…

【LeNet网络架构】——深度学习.卷积神经网络

目录 1 MLP 2 LeNet简介 3 Minst数据集 3.1 MINST数据集简介 3.2 MNIST数据集的预处理 4 LeNet手写数字识别 LeNet由Yann Lecun 提出,是一种经典的卷积神经网络,是现代卷积神经网络的起源之一。Yann将该网络用于邮局的邮政的邮政编码识别&#xff…

Python笔记完整版

常用pip源 (1)阿里云 http://mirrors.aliyun.com/pypi/simple/(2)豆瓣 http://pypi.douban.com/simple/(3)清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/(4)中国科学技术大学…

2025 鸿蒙创新赛又来了,万少教你如何强势切入 HarmonyOS AI特性

2025 鸿蒙创新赛又来了,万少教你如何强势切入 前言 ​ 2025 华为HarmonyOS 创新赛又来了,创新赛是鸿蒙生态最大规模开发者官方赛事,最高获百万激励。 参赛资格 面向所有开发者开放以队伍的形式来参加,可以一个人报名一个队伍&a…

【智能模型系列】Unity通过访问Ollama调用DeepSeek模型进行本地部署

【智能模型系列】Unity通过访问Ollama调用DeepSeek模型进行本地部署 目录 一、前言 二、环境准备 三、核心代码解析 1、参数配置 2. CallDeepSeek.cs - API交互控制器 3、 MainPanel.cs - 用户界面控制器 四、源码 一、前言 在本教程中,我将分享如何在Unity中集成本地…

什么是5G-A三防平板?有什么特点?哪些领域能用到?

在工业自动化与数字化转型浪潮中,三防平板电脑已成为“危、急、特”场景的核心工具。这类设备不仅具备坚固耐用的物理防护特性,更融合了先进的通信技术与智能处理能力。而随着5G技术向5G-A阶段演进,新一代三防平板正为行业应用注入全新动能。…

Flink实时流量统计:基于窗口函数与Redis Sink的每小时PV监控系统(学习记录)

题目:利用flink统计网站浏览量,并写入redis。利用窗口函数以及算子实现每小时PV(网站的页面浏览量)统计,对统计后结果数据格式进行设计,存储至Redis中(利用sink将处理后结果数据输出到redis数据…

使用Imgui和SDL2做的一个弹球小游戏-Bounze

使用Imgui和SDL2做的一个弹球小游戏-Bounze 油管上面TheCherno博主分享的一个视频FIRST GAME in C! Did He Do a Good Job? // Code Review (C/SDL2)里面分享了一个Github项目: https://github.com/staticaron/Bounze 使用了Imgui和SDL2,并且可以设置音…

SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法

SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法 CASE WHEN 是 SQL 中非常实用的条件表达式,它允许你在查询中实现条件逻辑。以下是详细的用法说明: 1. 基本语法结构 CASE WHEN condition1 THEN result1WHEN condition2 THEN result2...ELSE default_resul…

CentOS 7 Linux 基础知识点汇总

🐧 CentOS 7 Linux 基础知识点汇总为方便初学者快速掌握 CentOS 7 系统的核心操作,本文档整理了常用系统命令、快捷键、目录结构及文件后缀名等基础内容,适合入门参考。 一、常见系统命令 🔍 命令行提示符说明 终端中的提示符包含…

突发限制下的破局之路:国产之光 Lynx 重构 AI 开发安全壁垒

继 Pro 套餐 “明升暗降” 争议后,Cursor 本周再掀波澜 —— 包括 Claude 系列、GPT-4 在内的主流模型一夜之间对中国用户全面封禁。开发者社群瞬间沸腾,“付费却用不了”“项目数据导不出” 的焦虑刷屏,境外工具的政策波动再次给行业敲响警钟…

渗透测试实战 | docker复杂环境下的内网打点

本文作者:Track-syst1m一.前言本文涉及的相关漏洞均已修复、本文中技术和方法仅用于教育目的;文中讨论的所有案例和技术均旨在帮助读者更好地理解相关安全问题,并采取适当的防护措施来保护自身系统免受攻击。二.大概流程1. 外网打点漏洞利用•…

阿里云服务器 CentOS 7 安装 MySQL 8.4 超详细指南

阿里云服务器 CentOS 7 安装 MySQL 8.4 超详细指南 一、准备工作 系统要求: CentOS 7.9 64位2 核(vCPU)2 GiBroot 用户权限 服务器连接工具: FinalShell 下载安装包: 访问 MySQL 官网选择版本:MySQL 8.4.0…

解决 Electron 中 window.open 打开新窗口的各种“坑”

嘿,各位开发者们!今天我们要聊聊在使用 Electron 时遇到的一个经典问题:如何正确地使用 window.open 来打开新窗口? 这听起来似乎很简单,但实际上却充满了各种“惊喜”(或者说“惊吓”)。别担心…

朝歌智慧盘古信息:以IMS MOM V6重构国产化智能终端新生态

随着5G、云计算、AI、大数据等技术深度渗透,智能终端行业正迎来场景化创新的爆发期。面对市场需求升级与技术迭代压力,国产化智能终端领域领军企业——广东朝歌智慧互联科技有限公司(以下简称“朝歌智慧”),基于集团“…

docker 离线安装postgres+postgis实践

文章目录前言一、离线安装docker二、导出导入PG镜像1.导出2.导入三、启动容器四、验证与测试前言 在企业内网环境中部署地理信息系统(GIS)时,常常面临网络隔离导致无法在线拉取 Docker 镜像的问题。 本文将详细介绍如何通过离线方式完成 Pos…