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

理解链接:加载二进制动态库

理解链接:加载二进制动态库

文章目录

  • 理解链接:加载二进制动态库
    • 前情提要
    • 基本方式1 - 显式连接 dlopen
    • 基本方式 2 - 隐式链接 compile + link + ld
    • 衍生方式 3 - 弱链接 weak linking
    • 衍生方式 4 - dlmopen 加载到独立命名空间
    • 调试所有符号
  • 补充知识
    • 1. 动态库的创建与编译
    • 2. 动态库的搜索路径
    • 3. 符号可见性控制
    • 4. 动态库的版本控制
    • 5. 动态库的初始化与清理函数
    • 6. 调试工具
      • 7. 安全性注意事项

前情提要

之前做的 rev 题一般动态库都是直接在编译时 link 好了动态库,从反编译代码里看不出来调用的过程

机缘巧合仔细了解一下才发现二进制的调库原来跟 python, js 这种语言的依赖引用是很像的,把库以二进制 dll/so 的形式放在 path 下面,让系统能找到,然后用路径和名称调用符号就行了。

基本方式1 - 显式连接 dlopen

runtime linking / manually linking

通过 dlopen 可以打开任意动态库,然后通过函数指针使用里面的函数。

int main() {// 加载共享库,RTLD_LAZY 表示延迟解析符号(只有当实际调用时才解析)void *handle = dlopen("libm.so", RTLD_LAZY);if (!handle) {fprintf(stderr, "dlopen error: %s\n", dlerror());exit(EXIT_FAILURE);}// 清除之前的错误dlerror();// 从库中查找符号,例如查找数学库中的 cos 函数double (*cos_func)(double) = (double (*)(double)) dlsym(handle, "cos");char *error = dlerror();if (error != NULL) {fprintf(stderr, "dlsym error: %s\n", error);dlclose(handle);exit(EXIT_FAILURE);}// 调用动态加载的函数double result = cos_func(2.0);printf("cos(2.0) = %f\n", result);// 使用完毕后关闭共享库dlclose(handle);return 0;
}

基本方式 2 - 隐式链接 compile + link + ld

load time linking

在编译和链接阶段已经将动态库的依赖信息写入到可执行文件中,运行时,操作系统的动态链接器会自动加载这些库并解析其中的符号。

程序启动时,系统加载器(例如 /lib/ld-linux.so.*)自动读取 ELF 文件中的依赖信息,并加载所有必需的动态库。符号解析和重定位工作由动态链接器完成,开发者在代码中直接调用库函数即可

加载器如何识别依赖的动态库?链接器(通常是 ld)会在编译器把依赖的共享库的信息写入到最终生成的 ELF 文件中。这个信息主要记录在动态段 .dynamic 里,其中有一个重要的字段 DT_NEEDED,用于列出程序运行时所需要加载

衍生方式 3 - 弱链接 weak linking

弱链接允许在编译阶段声明某个符号为“可选”的(或说“弱”),这样在运行时即使目标动态库中不存在该符号,程序也不会链接失败。开发者可以在运行时检测该符号是否为 NULL,然后决定是否调用或使用备用实现。当应用需要兼容不同版本的库,某些新版本的 API 在旧版本中可能不存在时很有用。也可以用于实现缺失时回退到默认行为或其他实现。

在 GCC 中,可以这样声明一个函数为弱符号:

extern void some_optional_function() __attribute__((weak));int main() {if (some_optional_function) {some_optional_function();} else {// 使用备用方案}return 0;
}

这样,如果链接的库中没有 some_optional_function,程序依然可以运行,并根据检测结果选择调用。

衍生方式 4 - dlmopen 加载到独立命名空间

防止名称冲突的衍生系统调用

 // LM_ID_NEWLM 表示在一个新的命名空间中加载void *handle = dlmopen(LM_ID_NEWLM, "libexample.so", RTLD_LAZY);if (!handle) {fprintf(stderr, "dlmopen error: %s\n", dlerror());return -1;}double (*cos_func)(double) = (double (*)(double)) dlsym(handle, "cos");...
}

调试所有符号

#include <stdio.h>
#include <dlfcn.h>int main() {// 使用 RTLD_DEFAULT 搜索全局符号void (*printf_ptr)(const char*, ...) = dlsym(RTLD_DEFAULT, "printf");if (printf_ptr) {printf_ptr("Found printf via RTLD_DEFAULT\n");} else {fprintf(stderr, "Symbol not found: %s\n", dlerror());}return 0;
}

补充知识

1. 动态库的创建与编译

动态库的生成步骤

# 编译为位置无关代码(-fPIC)
gcc -c -fPIC mylib.c -o mylib.o# 生成共享库(-shared)
gcc -shared -o libmylib.so mylib.o# 隐式链接时,编译主程序需指定链接库路径和名称
gcc main.c -L. -lmylib -o main
  • -fPIC:生成位置无关代码(Position-Independent Code),确保动态库可被加载到任意内存地址。
  • -shared:指示生成共享库(.so 文件)。
  • -L.:添加库搜索路径(此处为当前目录)。
  • -lmylib:链接名为 libmylib.so 的库。

2. 动态库的搜索路径

系统按以下顺序查找动态库:

  1. 编译时指定的 -rpath-rpath-link 路径。
  2. 环境变量 LD_LIBRARY_PATH 中的路径。
  3. /etc/ld.so.cache 中缓存的路径(通过 ldconfig 更新)。
  4. 默认路径:/lib, /usr/lib, /lib64, /usr/lib64 等。

示例:临时添加库路径:

export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
./main

3. 符号可见性控制

默认情况下,动态库会导出所有全局符号。可通过编译选项或源码属性限制符号导出,避免污染全局命名空间。

方法1:编译时隐藏符号
使用 -fvisibility=hidden,然后显式导出需要的符号:

// 在源码中声明导出符号
__attribute__((visibility("default"))) void public_func() { ... }

方法2:版本脚本
使用链接器脚本 libmylib.version 控制符号可见性:

gcc -shared -o libmylib.so mylib.o -Wl,--version-script=libmylib.version

脚本内容:

VERS_1.0 { global: public_func; local: *; 
};

4. 动态库的版本控制

通过 soname(Shared Object Name)管理兼容性:

# 编译时指定 soname
gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0 mylib.o# 创建软链接供程序查找
ln -s libmylib.so.1.0 libmylib.so.1
ln -s libmylib.so.1 libmylib.so
  • 主版本号(Major)libmylib.so.1,表示二进制兼容性。
  • 次版本号(Minor)libmylib.so.1.0,表示新增功能但兼容。
  • 发布版本(Release):可选,如 libmylib.so.1.0.0

5. 动态库的初始化与清理函数

可在库中定义构造函数(加载时执行)和析构函数(卸载时执行):

__attribute__((constructor)) void init() {printf("Library loaded!\n");
}__attribute__((destructor)) void cleanup() {printf("Library unloaded!\n");
}

6. 调试工具

  • ldd:查看程序的动态库依赖关系。
    ldd ./main
    
  • nm:列出库中的符号。
    nm -D libmylib.so
    
  • readelf:查看 ELF 文件详细信息。
    readelf -d libmylib.so  # 查看动态段(DT_NEEDED 等)
    
  • LD_DEBUG:启用动态链接器的调试输出。
    LD_DEBUG=files,libs ./main
    

7. 安全性注意事项

  • LD_PRELOAD:强制优先加载指定库,可用于劫持函数(慎用)。
    LD_PRELOAD=/path/to/malicious.so ./main
    
  • 符号冲突:若两个动态库导出同名符号,先加载的符号会被使用。

相关文章:

理解链接:加载二进制动态库

理解链接&#xff1a;加载二进制动态库 文章目录 理解链接&#xff1a;加载二进制动态库前情提要基本方式1 - 显式连接 dlopen基本方式 2 - 隐式链接 compile link ld衍生方式 3 - 弱链接 weak linking衍生方式 4 - dlmopen 加载到独立命名空间调试所有符号 补充知识1. 动态库…...

ASP.NET Core中Filter与Middleware的区别

中间件是ASP.NET Core这个基础提供的功能&#xff0c;而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是由MVC中间件提供的框架&#xff0c;而Filter属于MVC中间件提供的功能。 区别 中间件可以处理所有的请求&#xff0c;而Filter只能处理对控制器的请求&#x…...

《语义捕捉全解析:从“我爱自然语言处理”到嵌入向量的全过程》

首先讲在前面&#xff0c;介绍一些背景 RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09; 是一种结合了信息检索与语言生成模型的技术&#xff0c;通过从外部知识库中检索相关信息&#xff0c;并将其作为提示输入给大型语言模型&#xff…...

大规模多准则决策模型构建详细方案

第二阶段&#xff1a;大规模多准则决策模型构建详细方案 目标 基于消费者群体偏好和个体交互数据&#xff0c;构建动态、可扩展的多准则决策模型&#xff0c;实现实时个性化产品排序。 一、技术架构设计 1. 系统架构图 [用户交互层] → (React前端) ↓ [API服务层] → (…...

Rust 语言:变革关键任务软件的新力量

软件无处不在&#xff0c;从手表、烤箱、汽车&#xff0c;甚至可能是牙刷中都有它的身影。更重要的是&#xff0c;软件控制着关乎生死的系统&#xff0c;如飞机、医疗设备、电网系统和银行基础设施等。如果软件工程师稍有疏忽&#xff0c;软件缺陷和漏洞可能导致数十亿美元的损…...

Linux特权组全解析:识别GID带来的权限提升风险

组ID&#xff08;Group ID&#xff0c;简称 GID&#xff09;是Linux系统中用来标识不同用户组的唯一数字标识符。每个用户组都有一个对应的 GID&#xff0c;通过 GID&#xff0c;系统能够区分并管理不同的用户组。 在Linux系统中&#xff0c;系统用户和组的配置文件通常包括以…...

安卓/ios脚本开发按键精灵经验小分享

1. 程序的切换 我们经常碰到这样的需求&#xff1a;打开最近的应用列表&#xff0c;选取我们想要的程序。但是每个手机为了自己的风格&#xff0c;样式都有区别&#xff0c;甚至连列表的滑动方向都不一样&#xff0c;我们很难通过模拟操作来识别点击&#xff0c;那么我们做的只…...

机器学习在癌症分子亚型分类中的应用

学习笔记&#xff1a;机器学习在癌症分子亚型分类中的应用——Cancer Cell 研究解析 1. 文章基本信息 标题&#xff1a;Classification of non-TCGA cancer samples to TCGA molecular subtypes using machine learning发表期刊&#xff1a;Cancer Cell发表时间&#xff1a;20…...

DeepSeek本地部署保姆级教程

由于DeepSeek近期遭受攻击&#xff0c;又加上用户访问量较大&#xff0c;导致总是服务不可用&#xff0c;让人十分窝火。有没有好的解决办法呢&#xff1f;答案是自己在电脑端部署一套&#xff0c;这样就不用和别人抢着用了。另外本地部署的好处还有保护隐私与减少延迟。 如果…...

无惧户外复杂环境,安科瑞 AKH-0.66/K-HW 开口式互感器准确测流

​安科瑞 吕梦怡 18706162527 1.产品特点 AKH-0.66/K-HW 系列互感器具有防水功能&#xff0c;可在户外使用&#xff0c;切面端口采用橡胶垫环绕可有效阻止雨水进入。互感器采用注塑技术&#xff0c;将互感器线圈直接在模具中进行注塑&#xff0c;同时二次侧引线采用防水端子…...

玩转Docker | 使用Docker部署httpd服务

玩转Docker | 使用Docker部署httpd服务 前言一、准备工作环境确认检查操作系统准备网站目录和配置文件二、拉取httpd镜像三、运行httpd容器运行容器命令检查容器状态四、验证httpd服务浏览器访问测试错误排查五、容器管理与维护查看容器状态停止和启动容器更新网站内容和配置六…...

MacOS 安装NVM

MacOS 安装NVM 方法一&#xff1a;使用Homebrew安装nvm 打开终端&#xff08;Terminal&#xff09;&#xff0c;输入以下命令安装Homebrew&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装nvm…...

Qt 数据库SQLite 使用【01】基本功能

1.开发背景 Qt 开发过程中难免需要存储数据&#xff0c;可以选择保存到本地文件&#xff0c;但是查找比较麻烦&#xff0c;所以就有了数据库&#xff0c;主要是方便查找数据&#xff0c;增删改查等操作&#xff0c;而 SqLite 属于数据库中轻量级的存在&#xff0c;适合本地数据…...

http状态码:请说说 503 Service Unavailable(服务不可用)的原因以及排查问题的思路

503 Service Unavailable&#xff08;服务不可用&#xff09; 是一种HTTP状态码&#xff0c;表示服务器当前无法处理请求&#xff0c;通常是由于临时性原因导致服务中断。以下是它的常见原因和排查思路&#xff1a; 一、503错误的常见原因 1. 服务器过载 场景&#xff1a;服务…...

58页PPT学习华为面向业务价值的数据治理实践

目录 1. 正文解读... 1 2. 华为数据质量管控的质量度量框架是怎样的?... 2 3. 如何在企业中实施类似华为的数据质量管控...

电脑开机提示按f1原因分析及终极解决方法来了

经常有网友问到一个问题&#xff0c;我电脑开机后提示按f1怎么解决&#xff1f;不管理是台式电脑&#xff0c;还是笔记本&#xff0c;都有可能会遇到开机需要按F1&#xff0c;才能进入系统的问题&#xff0c;引起这个问题的原因比较多&#xff0c;今天小编在这里给大家列举了比…...

DeepSeek模型构建与训练

在完成数据预处理之后,下一步就是构建和训练深度学习模型。DeepSeek提供了简洁而强大的API,使得模型构建和训练变得非常直观。无论是简单的全连接网络,还是复杂的卷积神经网络(CNN)或循环神经网络(RNN),DeepSeek都能轻松应对。本文将带你一步步构建一个深度学习模型,并…...

ProxySQL实现mysql8主从同步读写分离

一、ProxySQL基本介绍 ProxySQL是 MySQL 的高性能、高可用性、协议感知代理。 简单介绍下ProxySQL及其功能和配置&#xff0c;主要包括&#xff1a; 最基本的读/写分离&#xff0c;且方式有多种&#xff1b;可定制基于用户、基于schema、基于语句的规则对SQL语句进行路由&…...

Day38-【13003】短文,树的基本概念,用广义表表示树

文章目录 第五章 树与二叉树第一节 树的基本概念用广义表&#xff0c;也就是集合表示发&#xff0c;来表示树 第五章 树与二叉树 第一节 树的基本概念 因为树是一种层次结构&#xff0c;所以它是一种非线性结构&#xff0c;在实际应用中具有广泛的用途。 日常生活中&#xff…...

LabVIEW与PLC交互

一、写法 写命令立即读出 写命令后立即读出&#xff0c;在同一时间不能有多个地方写入&#xff0c;因此需要在整个写入后读出过程加锁 项目中会存在多个循环并行执行该VI&#xff0c;轮询PLC指令 在锁内耗时&#xff0c;就是TCP读写的实际耗时为5-8ms&#xff0c;在主VI六个…...

MySQL第四次作业

新建数据库 新建表 student表 2.course表 3.sc表 修改Student 表中年龄(sage)字段属性&#xff0c;数据类型由int 改变为smallint alter table student modify sage smallint; 为Course表中Cno 课程号字段设置索引&#xff0c;并查看索引 create index index_cno on cou…...

栈和队列的实现(C语言)

1&#xff1a;栈 1&#xff1a;概念和结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只运行在固定的一段进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守先进后出的原则。 压栈&#xff1a;在栈里面插入…...

(四)QT——QMainWindow——界面菜单设计

目录 前言 QMainWindow 结构 菜单栏 工具栏 状态栏 停靠部件 核心部件 UI 文件创建窗口 总结 前言 QMainWindow 是 Qt 框架中的一个类&#xff0c;主要用于创建桌面应用程序的主窗口。它提供了一个标准的窗口布局&#xff0c;包含菜单、工具栏、状态栏和中心小部件等功…...

MySQL InnoDB引擎 脏读、不可重复读和幻读

在 MySQL 的 InnoDB 存储引擎中&#xff0c;脏读、不可重复读和幻读是并发事务操作时可能出现的数据不一致问题&#xff0c;不同的事务隔离级别对这些问题有不同的处理方式。 1、脏读&#xff08;Dirty Read&#xff09; 定义&#xff1a;一个尚未提交的数据变更的事务&#…...

初阶数据结构:树---堆

目录 一、树的概念 二、树的构成 &#xff08;一&#xff09;、树的基本组成成分 &#xff08;二&#xff09;、树的实现方法 三、树的特殊结构------二叉树 &#xff08;一&#xff09;、二叉树的概念 &#xff08;二&#xff09;、二叉树的性质 &#xff08;三&#…...

判断192.168.1.0/24网络中,当前在线的ip有哪些

需求&#xff1a;判断192.168.1.0/24网络中&#xff0c;当前在线的ip有哪些&#xff0c;并编写脚本打印出来。 [rootopenEuler ~]# cat 1.sh #!/bin/bash for ip in $(seq 1 254); do ping -c 1 -W 1 "192.168.1.$ip" > /dev/null 2>&1 if [ $? …...

初始JavaEE篇 —— Spring Web MVC入门(上)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 RequestMappingg 注解介绍 Postman的介绍与使用 PostMapping 与 GetMapping 注解 构造并接收请求 接收简单参数 接收对象…...

STM32的HAL库开发-通用定时器输入捕获实验

一、通用定时器输入捕获部分框图介绍 1、捕获/比较通道的输入部分(通道1) 首先设置 TIM_CCMR1的CC1S[1:0]位&#xff0c;设置成01&#xff0c;那么IC1来自于TI1&#xff0c;也就是说连接到TI1FP1上边。设置成10&#xff0c;那个IC1来自于TI2&#xff0c;连接到TI2FP1上。设置成…...

nodejs:express + js-mdict 网页查询英汉词典,能播放.spx 声音

向 DeepSeek R1 提问&#xff1a; 我想写一个Web 前端网页&#xff0c;后台用 nodejs js-mdict , 实现在线查询英语单词&#xff0c;并能播放.spx 声音文件 1. 项目结构 首先&#xff0c;创建一个项目目录&#xff0c;结构如下&#xff1a; mydict-app/ ├── public/ │ …...

【蓝桥杯嵌入式】5_PWM

全部代码网盘自取 链接&#xff1a;https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取码&#xff1a;3ii2 1、PWM占空比可调 以往届的赛题举例 将PA6、PA7分别设置为TIM16_CH1和TIM17_CH1 打开TIM16和TIM17&#xff0c;并设置PWM输出模式及其频率 设置占空比初…...

ESM-IF1:从AF2的预测结构中学习逆折叠

作者研究了从蛋白质骨干原子坐标预测蛋白质序列的问题。迄今为止&#xff0c;机器学习解决此问题的方法一直受限于可用的实验测定蛋白质结构的数量。作者使用AlphaFold2为1200万个蛋白质序列预测的结构&#xff0c;从而将训练数据扩充了近三个数量级。相比现有方法&#xff0c;…...

kafka服务端之控制器

文章目录 概述控制器的选举与故障恢复控制器的选举故障恢复 优雅关闭分区leader的选举 概述 在Kafka集群中会有一个或多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controler&#xff09;&#xff0c;它负责管理整个集群中所有分区和副本的状态。…...

Redis双写一致性(数据库与redis数据一致性)

一 什么是双写一致性&#xff1f; 当修改了数据库&#xff08;MySQL&#xff09;中的数据&#xff0c;也要同时更新缓存&#xff08;redis&#xff09;中的数据&#xff0c;缓存中的数据要和数据库中的数据保持一致 双写一致性&#xff0c;根据业务对时间上的要求&#xff0c;…...

feign Api接口中注解问题:not annotated with HTTP method type (ex. GET, POST)

Bug Description 在调用Feign api时&#xff0c;出现如下异常&#xff1a; java.lang.IllegalStateException: Method PayFeignSentinelApi#getPayByOrderNo(String) not annotated with HTTPReproduciton Steps 1.启动nacos-pay-provider服务&#xff0c;并启动nacos-pay-c…...

开源2+1链动模式AI智能名片S2B2C商城小程序:突破流量与创意困境的新路径

摘要&#xff1a;本文深入剖析当前互联网行业中流量集中于巨头以及创意边际效应递减的困境&#xff0c;并探讨开源21链动模式AI智能名片S2B2C商城小程序在应对这些困境时所展现的独特优势与应用策略。通过对行业现状的分析以及该小程序功能特点的研究&#xff0c;旨在为企业在艰…...

python编程-内置函数compile(),exec(),complex(),eval()详解

1. compile() 函数 ‌用途‌&#xff1a;将一个字符串源代码编译为字节码对象&#xff0c;这样可以直接被Python解释器执行&#xff0c;或者通过exec()或eval()函数来执行。 ‌参数‌&#xff1a; source&#xff1a;一个字符串或AST&#xff08;抽象语法树&#xff09;对象&am…...

websocket自动重连封装

websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…...

解锁C/C++:链表数据结构的奇幻之旅

目录 一、引言二、链表基础概念2.1 链表是什么2.2 链表的类型三、C 语言实现链表3.1 定义链表节点3.2 创建链表3.3 链表操作3.3.1 遍历链表3.3.2 插入节点3.3.3 删除节点3.3.4 查找节点3.4 完整示例代码四、C++ 实现链表4.1 定义链表节点类4.2 创建链表4.3 链表操作4.3.1 遍历链…...

x64、aarch64、arm与RISC-V64:详解四种处理器架构

x64、aarch64、arm与RISC-V64:详解四种处理器架构 x64架构aarch64架构ARM架构RISC-V64架构总结与展望在计算机科学领域,处理器架构是构建计算机系统的基石,它决定了计算机如何执行指令、管理内存和处理数据。x64、aarch64、arm与RISC-V64是当前主流的四种处理器架构,它们在…...

nuxt3中报错: `setInterval` should not be used on the server.

那是因为在后端渲染没有浏览器的执行环境&#xff0c;一些浏览器环境提供的对象和方法都无法使用&#xff0c;代码判断下就行。 if (import.meta.client) {setInterval(() > {}, 1000) }Import meta Nuxt API...

python编程-集合内置函数和filter(),集合常见操作

在Python中&#xff0c;列表、集合、字典是三种常用的数据结构&#xff0c;它们各自拥有一些内置函数&#xff0c;用于执行各种操作。 一、列表的常用内置函数 #‌1、append(obj)‌: 在列表末尾添加新的对象。list_a [1, 2, 3] list_a.append(4) print(list_a) # 输出: [1,…...

三极管的截止、放大、饱和区

三极管的几个区&#xff0c;都有什么用&#xff1a; 截止区&#xff1a;晶体管不导通&#xff0c;用于开关电路的“关”状态。 放大区&#xff1a;晶体管用于信号放大&#xff0c;集电极电流与基极电流成正比。 饱和区&#xff1a;晶体管完全导通&#xff0c;用于开关电路的“…...

python爬虫--简单登录

1&#xff0c;使用flask框架搭建一个简易网站 后端代码app.py from flask import Flask, render_template, request, redirect, url_for, sessionapp Flask(__name__) app.secret_key 123456789 # 用于加密会话数据# 模拟用户数据库 users {user1: {password: password1}…...

苹果公司宣布正式开源 Xcode 引擎 Swift Build145

2025 年 2 月 1 日&#xff0c;苹果公司宣布正式开源 Xcode 引擎 Swift Build145。 Swift 是苹果公司于 2014 年推出的一种开源编程语言&#xff0c;用于开发 iOS、iPadOS、macOS、watchOS 和 tvOS 等平台的应用程序。 发展历程 诞生&#xff1a;2014 年&#xff0c;苹果在全球…...

齿轮减速机和平行轴减速机有何区别?

减速机是传动系统中重要的组成部分&#xff0c;常用的减速机有四大系列&#xff0c;分别是平行轴减速机、同轴减速机、直角减速机和齿轮减速机。那么大家知道齿轮减速机和平行轴减速机投什么区别吗&#xff1f; 齿轮减速机的轴不一定是平行的&#xff0c;还可能存在相交轴或交错…...

基于Hexo实现一个静态的博客网站

原文首发&#xff1a;https://blog.liuzijian.com/post/8iu7g5e3r6y.html 目录 引言1.初始化Hexo2.整合主题Fluid3.部署评论系统Waline4.采用Nginx部署 引言 Hexo是中国台湾开发者Charlie在2012年创建的一个开源项目&#xff0c;旨在提供一个简单、快速且易于扩展的静态博客生…...

MIT6.824 Lecture 1-Introduction

balance&#xff1a;性能和容错 Faulty tolerance&#xff1a; Availablity、Recoverability、NV storage&#xff08;非易失性存储&#xff0c;比较贵&#xff09;、Replication&#xff08;多个数据副本&#xff09; consistency&#xff1a; Put&#xff08;key&#xff0c;…...

【Redis实战】投票功能

1. 前言 现在就来实践一下如何使用 Redis 来解决实际问题&#xff0c;市面上很多网站都提供了投票功能&#xff0c;比如 Stack OverFlow 以及 Reddit 网站都提供了根据文章的发布时间以及投票数计算出一个评分&#xff0c;然后根据这个评分进行文章的展示顺序。本文就简单演示…...

1Panel应用推荐:WordPress开源博客软件和内容管理系统

1Panel&#xff08;github.com/1Panel-dev/1Panel&#xff09;是一款现代化、开源的Linux服务器运维管理面板&#xff0c;它致力于通过开源的方式&#xff0c;帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用&#xff0c;1Panel特别开通应用商店&am…...

GGML、GGUF、GPTQ 都是啥?

GGML、GGUF和GPTQ是三种与大型语言模型(LLM)量化和优化相关的技术和格式。它们各自有不同的特点和应用场景,下面将详细解释: 1. GGML(GPT-Generated Model Language) 定义:GGML是一种专为机器学习设计的张量库,由Georgi Gerganov创建。它最初的目标是通过单一文件格式…...