【Redis 原理】通信协议 内存回收
文章目录
- 通信协议--RESP
- 内存回收
- 内存过期策略
- 惰性删除
- 周期删除
- 内存淘汰策略
通信协议–RESP
Redis是一个CS架构的软件,通信一般分两步(不包括pipeline和PubSub):
- 客户端(client)向服务端(server)发送一条命令
- 服务端解析并执行命令,返回响应结果给客户端
因此客户端发送命令的格式、服务端响应结果的格式必须有一个规范,这个规范就是通信协议。
而在Redis中采用的是RESP
(Redis Serialization Protocol
)协议:
- Redis 1.2版本引入了RESP协议
- Redis 2.0版本中成为与Redis服务端通信的标准,称为RESP2
- Redis 6.0版本中,从RESP2升级到了RESP3协议,增加了更多数据类型并且支持6.0的新特性–客户端缓存
但目前,默认使用的依然是RESP2协议,也是我们要学习的协议版本(以下简称RESP)
在RESP中,通过首字节的字符来区分不同数据类型,常用的数据类型包括5种:
-
单行字符串:首字节是
+
,后面跟上单行字符串,以CRLF( "\r\n" )
结尾。例如返回OK
:+OK\r\n
由此可见:单行字符串中不能包含一些特殊字符(如\r\n
等),是非二进制安全的 -
错误(
Errors
):首字节是-
,与单行字符串格式一样,只是字符串是异常信息,例如:-Error message\r\n
-
数值:首字节是
:
,后面跟上数字格式的字符串,以CRLF
结尾。例如::10\r\n
-
多行字符串:首字节是
$
,表示二进制安全的字符串,最大支持512MB:
如果大小为0,则代表空字符串:$0\r\n\r\n
如果大小为-1,则代表不存在:$-1\r\n
-
数组:首字节是
*
,后面跟上数组元素个数,再跟上元素,元素数据类型不限
内存回收
Redis之所以性能强,最主要的原因就是基于内存存储。
然而单节点的Redis其内存大小不宜过大,会影响持久化或主从同步性能。
我们可以通过修改配置文件来设置Redis的最大内存:
# 格式:
# maxmemory <bytes>
# 例如:
maxmemory 1gb
当内存使用达到上限时,就无法存储更多数据了。
为了解决这个问题,Redis提供了一些策略实现内存回收:
内存过期策略 && 内存淘汰策略
内存过期策略
Redis可以通过expire命令给Redis的key设置TTL(存活时间):
可以发现,当key的TTL到期以后,再次访问name返回的是nil,说明这个key已经不存在了,对应的内存也得到释放。从而起到内存回收的目的。
但是这背后是怎么实现的?让我们从以下两个问题入手:
Q1:Redis是如何知道一个key是否过期呢?
Redis本身是一个典型的key-value内存存储数据库,因此所有的key、value都保存在之前学习过的Dict结构中。
并且在其database结构体中,有两个关键Dict:一个用来记录key-value
;另一个用来记录key-TTL
,定义如下:
typedef struct redisDb {dict *dict; /* 存放所有key及value的地方,也被称为keyspace*/dict *expires; /* 存放每一个key及其对应的TTL存活时间,只包含设置了TTL的key*/dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/dict *ready_keys; /* Blocked keys that received a PUSH */dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */int id; /* Database ID,0~15 */long long avg_ttl; /* 记录平均TTL时长 */unsigned long expires_cursor; /* expire检查时在dict中抽样的索引位置. */list *defrag_later; /* 等待碎片整理的key列表. */
} redisDb;
因此到这里我们可以解答Q1:利用两个Dict分别记录key-value对及key-ttl键值对,这样就可以查询一个key是否过期
Q2:是不是TTL到期就立即删除了呢?
NO,TTL到期的key并不是立即删除,而是采用如下策略:
惰性删除 && 周期删除
惰性删除
顾明思议并不是在TTL到期后就立刻删除,而是在访问一个key的时候,检查该key的存活时间,如果已经过期才执行删除。
核心代码片段如下:
// 查找一个key执行写操作
robj *lookupKeyWriteWithFlags(redisDb *db, robj *key, int flags) {// 检查key是否过期expireIfNeeded(db,key);return lookupKey(db,key,flags);
}
// 查找一个key执行读操作
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {robj *val;// 检查key是否过期 if (expireIfNeeded(db,key) == 1) {// ...略}return NULL;
}int expireIfNeeded(redisDb *db, robj *key) {// 判断是否过期,如果未过期直接结束并返回0if (!keyIsExpired(db,key)) return 0;// ... 略// 删除过期keydeleteExpiredKeyAndPropagate(db,key);return 1;
}
可以看到不论是查找一个key做读还是写操作,都会调用expireIfNeeded
函数来判断当前key是否过期,如果过期就会删除该key
那么这就有一个问题:如果一个key我们设置了TTL,并且它已经过期了,但是一直没有人去访问这个key,如果redis仅仅靠惰性删除的话,显然这个本该删除的key就永远不可能删除了。这显然是不合理的。因此有了下面的周期删除。
周期删除
通过一个定时任务,周期性的抽样部分过期的key,然后执行删除。执行周期有两种:
- Redis服务初始化函数
initServer()
中设置定时任务,按照server.hz的频率来执行过期key清理,模式为SLOW
,核心代码如下:
// server.c
void initServer(void){// ...// 创建定时器,关联回调函数serverCron,处理周期取决于server.hz,默认10aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL)
}// server.c
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {// 更新lruclock到当前时间,为后期的LRU和LFU做准备unsigned int lruclock = getLRUClock();atomicSet(server.lruclock,lruclock);// 执行database的数据清理,例如过期key处理databasesCron();
}void databasesCron(void) {// 尝试清理部分过期key,清理模式默认为SLOWactiveExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);
}
- Redis的每个事件循环前会调用
beforeSleep()
函数,执行过期key清理,模式为FAST
void beforeSleep(struct aeEventLoop *eventLoop){// ...// 尝试清理部分过期key,清理模式默认为FASTactiveExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST);
}
SLOW模式规则:
- 执行频率受server.hz影响,默认为10,即每秒执行10次,每个执行周期100ms。
- 执行清理耗时不超过一次执行周期的25%.默认slow模式耗时不超过25ms
- 逐个遍历db,逐个遍历db中的bucket,抽取20个key判断是否过期
- 如果没达到时间上限(25ms)并且过期key比例大于10%,再进行一次抽样,否则结束
FAST模式规则(过期key比例小于10%不执行 ):
- 执行频率受beforeSleep()调用频率影响,但两次FAST模式间隔不低于2ms
- 执行清理耗时不超过1ms
- 逐个遍历db,逐个遍历db中的bucket,抽取20个key判断是否过期
- 如果没达到时间上限(1ms)并且过期key比例大于10%,再进行一次抽样,否则结束
内存淘汰策略
当Redis内存使用达到设置的上限时,主动挑选部分key删除以释放更多内存的流程
Redis会在处理客户端命令的方法processCommand()
中尝试做内存淘汰:
int processCommand(client *c) {// 如果服务器设置了server.maxmemory属性,并且并未有执行lua脚本if (server.maxmemory && !server.lua_timedout) {// 尝试进行内存淘汰performEvictionsint out_of_memory = (performEvictions() == EVICT_FAIL);// ...if (out_of_memory && reject_cmd_on_oom) {rejectCommand(c, shared.oomerr);return C_OK;}// ....}
}
Redis支持8种不同策略来选择要删除的key:
noeviction
: 不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略volatile-ttl
: 对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰allkeys-random
:对全体key ,随机进行淘汰。也就是直接从db->dict中随机挑选volatile-random
:对设置了TTL的key ,随机进行淘汰。也就是从db->expires中随机挑选allkeys-lru
: 对全体key,基于LRU算法进行淘汰volatile-lru
: 对设置了TTL的key,基于LRU算法进行淘汰allkeys-lfu
: 对全体key,基于LFU算法进行淘汰volatile-lfu
: 对设置了TTL的key,基于LFU算法进行淘汰
比较容易混淆的有两个:
LRU(Least Recently Used)
,最少最近使用。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
LFU(Least Frequently Used)
,最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高。
对于上面的8种策略,可以通过如下字段设置具体的策略:
我们着重了解一下LRU和LFU的实现方式
我们都知道,Redis的数据都会被封装为RedisObject结构:
typedef struct redisObject {unsigned type:4; // 对象类型unsigned encoding:4; // 编码方式unsigned lru:LRU_BITS; // LRU:以秒为单位记录最近一次访问时间,长度24bit// LFU:高16位以分钟为单位记录最近一次访问时间,低8位记录逻辑访问次数int refcount; // 引用计数,计数为0则可以回收void *ptr; // 数据指针,指向真实数据
} robj;
其中 unsigned lru:LRU_BITS;
根据maxmemory-policy
可以设置具体的策略:
maxmemory-policy allkeys-lru
或maxmemory-policy volatile-lru
此时obj种的lru以秒为单位记录最近一次访问时间,长度24bitmaxmemory-policy allkeys-lfu
或maxmemory-policy volatile-lfu
此时obj种的lru的高16位以分钟为单位记录最近一次访问时间,低8位记录逻辑访问次数
问:何为逻辑访问次数?
答:LFU的访问次数之所以叫做逻辑访问次数,是因为并不是每次key被访问都计数,而是通过以下运算方式:
①生成0~1之间的随机数R
②计算 (旧次数 * lfu_log_factor + 1
),记录为P
③如果R < P
,则计数器 + 1,且最大不超过255
④访问次数会随时间衰减,距离上一次访问时间每隔lfu_decay_time
分钟(默认是1),计数器 -1
具体的淘汰策略如下图所示:
相关文章:
【Redis 原理】通信协议 内存回收
文章目录 通信协议--RESP内存回收内存过期策略惰性删除周期删除 内存淘汰策略 通信协议–RESP Redis是一个CS架构的软件,通信一般分两步(不包括pipeline和PubSub): 客户端(client)向服务端(se…...
AWS - Redshift - 外部表读取 Parquet 文件中 timestamp 类型的数据
问题: 通过 Redshift Spectrum 功能可以读取 S3 中的文件,当读取 Parquet 文件时,如果列格式设置为 timestamp, 通过 psql 客户端读取会出现以下错误: testdb# select * from myspectrum_schema_0219.test_ns; ERROR…...
H5--开发适配
在 H5 开发中,适配不同设备和屏幕尺寸至关重要,它能确保页面在各种环境下都有良好的显示效果和用户体验。以下介绍几种常见的 H5 开发适配方案: 视口(Viewport)设置 视口单位是相对于浏览器视口的尺寸进行度量的单位&…...
llama-factory部署微调方法(wsl-Ubuntu Windows)
llama-factory项目GitHub地址:GitHub - hiyouga/LLaMA-Factory: Unified Efficient Fine-Tuning of 100 LLMs & VLMs (ACL 2024) wsl-Ubuntu: 1.获取项目 git clone https://github.com/hiyouga/LLaMA-Factory.gitcd LLaMA-Factory/ 2.安装环境…...
【Unity】鱼群效果模拟
鱼群效果模拟 文章目录 鱼群效果模拟Boid算法实现方式version1_CPUversion2_GPUversion3_Multilaterationversion4_Bitonic_Sorting (GPU友好)version5_Skinning (TODO) 细节项优化项参考链接 Boid算法 Boid算法是一种模拟群体行…...
C++ 编程语言简介
C 是一种通用编程语言,它是作为 C 语言的增强而开发的,以包含面向对象的范例。它是一种命令式和编译语言。 C 是一种高级的通用编程语言,专为系统和应用程序编程而设计。它由贝尔实验室的 Bjarne Stroustrup 于 1983 年开发,作为…...
Day15-后端Web实战-登录认证——会话技术JWT令牌过滤器拦截器
目录 登录认证1. 登录功能1.1 需求1.2 接口文档1.3 思路分析1.4 功能开发1.5 测试 2. 登录校验2.1 问题分析2.2 会话技术2.2.1 会话技术介绍2.2.2 会话跟踪方案2.2.2.1 方案一 - Cookie2.2.2.2 方案二 - Session2.2.2.3 方案三 - 令牌技术 2.3 JWT令牌2.3.1 介绍2.3.2 生成和校…...
迪威模型:引领 3D 模型轻量化技术革新
在数字化时代,3D 模型的应用领域愈发广泛,从影视制作、游戏开发到工业设计、建筑仿真等,都离不开 3D 模型的支持。然而,随着模型复杂度的不断提高,文件体积也日益庞大,这给存储、传输和加载带来了极大的挑战…...
大学本科教务系统设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点
以下是大学本科教务系统的设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点: 大学本科教务系统设计方案 一、需求分析 1. 核心用户角色 角色功能需求学生选课/退课、成绩查询、课表查看、学分统计、考试报名、学业预警教师成绩录入、课程大纲上传、教学进度管理、…...
安装Liunx(CentOS-6-x86_64)系统
一:下载与安装Liunx(CentOS-7-x86_64) 1.下载: CentOS-6.10-x86_64-bin-DVD1.iso 2.安装: 按照自己的需求来 下载的镜像文件地址 加载完成后设置 查看网络和本地ip 3.配置仓库(用于yum下载࿰…...
DeepSeek开源周 Day01:从FlashMLA背后原理回顾KV Cache
FlashMLA 今天DeepSeek开源周第一天,开放了FlashMLA仓库,1小时内星标1.6k! FlashMLA 是一个高效的 MLA 解码内核,专为 Hopper GPU 优化,适用于可变长度序列。该项目目前发布了 BF16 和具有 64 块大小分页 kvcache 的功…...
java23种设计模式-工厂方法模式
工厂方法模式(Factory Method Pattern)学习笔记 🌟 定义 工厂方法模式属于创建型设计模式,定义一个创建对象的接口,但让子类决定实例化哪一个类。将类的实例化操作延迟到子类,是面向对象设计中"开闭…...
数据驱动未来!天合光能与永洪科技携手开启数字化新篇章
在信息化时代的今天,企业间的竞争早就超越了传统产品与服务的范畴,新的核心竞争力即——数据处理能力和信息技术的应用。作为数据技术领域的领军者,永洪科技凭借其深厚的技术积累和丰富的行业经验,成功助力天合光能实现数字化升级…...
【C++设计模式】工厂方法设计模式:深入解析从基础到进阶
1. 引言 在软件开发的世界里,设计模式如同巧妙的建筑蓝图,为解决常见问题提供了行之有效的方案。工厂方法模式作为一种广受欢迎的创建型设计模式,以其独特的优势在众多项目中得到广泛应用。它不仅能够为对象的创建提供通用且灵活的方式,还能有效隐藏实现细节,提升代码的可…...
Vue 3 + Vite 项目中配置代理解决开发环境中跨域请求问题
在 Vue 3 Vite 项目中,配置代理是解决开发环境中跨域请求问题的常见方法。通过在 Vite 的配置文件中设置代理,可以将前端请求转发到后端服务器,从而避免浏览器的同源策略限制。 1. 创建 Vue 3 Vite 项目 首先,确保你已经安装了…...
2.3 变量
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 变量是用来存放某个值的数据,它可以表示一个数字、一个字符串、一个结构、一个类等。变量包含名称、类型和值。在代码中…...
16、Python面试题解析:python中的浅拷贝和深拷贝
在 Python 中,浅拷贝(Shallow Copy) 和 深拷贝(Deep Copy) 是处理对象复制的两种重要机制,它们的区别主要体现在对嵌套对象的处理方式上。以下是详细解析: 1. 浅拷贝(Shallow Copy&a…...
BUUCTF-Web方向21-25wp
目录 [HCTF 2018]admin弱口令session伪造 [MRCTF2020]你传你🐎呢[护网杯 2018]easy_tornado[ZJCTF 2019]NiZhuanSiWei[MRCTF2020]Ez_bypass第一层第二层 [HCTF 2018]admin 打开环境,有三处提示,一个跳转链接,一个登录注册&#x…...
elementPlus 中表单验证方法(手机号、正整数、邮箱)
1、手机号验证 <el-form ref"formRef" :model"form" :rules"rule" label-width"100px"><el-form-item label"联系电话" prop"mobile"><el-input type"tel" v-model"form.mobile&q…...
阿里云 ACS:高效、弹性、低成本的容器计算解决方案
阿里云的 容器计算服务(Alibaba Cloud Container Service, ACS) 是一种 Serverless 容器计算 解决方案,提供高度弹性、低成本、易管理的 Kubernetes(K8s)容器运行环境。用户无需关注底层服务器资源,而是直接…...
启动Redis报错记录
突然启动Redis就报了个错:‘Could not create server TCP listening socket 127.0.0.1:6379: bind: 操作成功完成。‘ 查了下解决方案,应该是6379端口已绑定,服务没有关闭。 需要输入命令redis-cli 再输入shutdown 但又出现了新的问题&…...
springBoot统一响应类型2.0版本
前言: 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往…...
ubuntu离线安装Ollama并部署Llama3.1 70B INT4
文章目录 1.下载Ollama2. 下载安装Ollama的安装命令文件install.sh3.安装并验证Ollama4.下载所需要的大模型文件4.1 加载.GGUF文件(推荐、更容易)4.2 加载.Safetensors文件(不建议使用) 5.配置大模型文件 参考: 1、 如…...
Unity游戏制作中的C#基础(4)数组声明和使用
一、数组的声明 在 C# 中,声明数组有多种方式,每种方式都有其适用的场景,下面为你逐一详细介绍: 1. 直接初始化声明 这种方式直观且便捷,在声明数组的同时就为其赋初值,让数组从诞生之初就拥有了具体的数据…...
自定义SpringBoot Starter
✅自定义SpringBoot Starter SpringBoot 的 starter 可以帮我们简化配置,非常的方便,定义起来其实也不复杂,我的项目中定义了很多 starter,比如business-job就是一个 stater,以他为例,介绍下如何定义 star…...
电脑经常绿屏(蓝屏)怎么办(解决方法)?
一、排查系统与驱动问题 进入安全模式修复系统 强制重启电脑 3 次触发恢复环境,选择 疑难解答 > 高级选项 > 启动设置 > 重启,按 F5 或 5 进入带网络连接的安全模式3。 在安全模式下,尝试卸载最近安装的软件或更新,尤其…...
IO/网络IO基础全览
目录 IO基础CPU与外设1. 程序控制IO(轮询)2. 中断中断相关知识中断分类中断处理过程中断隐指令 3. DMA(Direct Memory Access) 缓冲区用户空间和内核空间IO操作的拷贝概念传统IO操作的4次拷贝减少一个CPU拷贝的mmap内存映射文件(m…...
DPVS-5: 后端服务监控原理与测试
后端监控原理 被动监测 DPVS自带了被动监控,通过监控后端服务对外部请求的响应情况,判断服务器是否可用。 DPVS的被动监测,并不能获取后端服务器的详细情况,仅仅通过丢包/拒绝情况来发觉后端服务是否可用。 TCP session state…...
前端基础知识
1. 变量和常量 1.1 变量 // 变量let name Jacklet age 20name lisiage 18 1.2 常量 // 常量const PI 3.14// PI 3.1415926 // error,常量不可重新赋值const articleList []const user {name: vue3,age: 10} 1.3 const 声明的数组和对象 因为数组和对象在…...
从零到一学习c++(基础篇--筑基期十一-类)
从零到一学习C(基础篇) 作者:羡鱼肘子 温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。 温馨提示2:本篇会尽量用更加通俗的语言介绍c的基础,用通俗的语言去…...
Linux 第三次脚本作业
源码编译安装httpd 2.4,提供系统服务管理脚本并测试(建议两种方法实现) 一、第一种方法 1、把 httpd-2.4.63.tar.gz 这个安装包上传到你的试验机上 2、 安装编译工具 (俺之前已经装好了) 3、解压httpd包 4、解压后的httpd包的文…...
C#与AI的交互(以DeepSeek为例)
C#与ai的交互 与AI的交互使用的Http请求的方式,通过发送请求,服务器响应ai生成的文本 下面是完整的代码,我这里使用的是Ollama本地部署的deepseek,在联网调用api时,则url会有不同 public class OllamaRequester {[Se…...
Sky Hackathon 清水湾的水 AI美食助手
这里写自定义目录标题 视频 视频 video...
基于SpringBoot的校园消费点评管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...
企业财务数据分析-投资回报指标ROA
上一篇文章主要介绍了关于投资回报的核心指标ROE,其实还有一个比较关键的指标资产回报率指标(ROA),资产收益率是用来衡量企业盈利能力的重要财务分析指标。资产收益率越高,说明企业资产的利用效率越高,利用…...
PostgreSQL 支持字段类型
PostgreSQL 支持多种字段类型,以下是常见的主要类别和具体类型的简要概述: 数值类型 SMALLINT:2字节整数,范围 -32768 到 32767 INTEGER:4字节整数,范围 -2147483648 到 2147483647 BIGINT:8字节…...
Deepseek引爆AI热潮 防静电地板如何守护数据中心安全
近期,Deepseek的爆火将人工智能推向了新的高度,也引发了人们对AI背后基础设施的关注。作为AI运行的“大脑”,数据中心承载着海量数据的存储、处理和传输,其安全稳定运行至关重要。而在这背后,防静电地板扮演着不可或缺…...
【ARM】MDK如何生成指定大小的bin文件,并指定空区域的填充数据
1、 文档目标 解决MDK如何生成指定大小的bin文件,并指定空区域的填充数据 2、 问题场景 客户有这样的需求,客户本身的工程编译生成bin文件后,bin文件大小为200k。整体芯片的内存有512k。客户想要最终生成的bin文件可以达到512k的一个情况&a…...
开源基准测试模拟器:BlueROV2 水下机器人的控制
拜读An Open-Source Benchmark Simulator: Control of a BlueROV2 Underwater Robot 非常感谢Esben Uth的帮助。 本文介绍了在 Simulink™ 中实现的常用且低成本的遥控潜水器 (ROV) BlueROV2 的仿真模型环境,该环境已针对水下航行器的基准控…...
Nginx 请求超时
Nginx 请求超时详解 在现代 Web 服务中,Nginx 作为一个高效的 Web 服务器和反向代理服务器,广泛应用于处理大量的 HTTP 请求。随着 Web 应用和服务的复杂性增加,Nginx 在处理客户端请求时,可能会出现超时问题。请求超时是指当客户…...
2022 年学习 Spring Boot 开发的最佳书籍
在我们之前的文章中,我们查看了学习 Java 编程的必读书籍我们在其中探索了一些您可以利用的资源来加快 Java 开发的速度。在此基础上,在用 vanilla Java 编写一段时间后,您将意识到组织文件和其他内容(例如设置 getter 和 setter、…...
JavaScript 前端面试 5()
十:new操作符 1:new操作符是什么 在JavaScript中new操作符是用于创建一个给定构造函数的实例对象 function Person(name,age){ this.name name; this.age age; } Person.protoype.sayName function (){ console,log(this.name) } cost person1 new…...
【Jenkins】显示 HTML 标签
需求 在 Jenkins 中显示 HTML 标签内容(例如格式化的文本、颜色、图标等)是一个常见的需求,如下,编译工程显示当前编译的分支: 但 Jenkins 默认会出于安全考虑(防止 XSS 攻击)转义 HTML 标签&a…...
DeepSeek R1模型提示语技巧:如何高效引导AI生成优质内容
文章目录 明确任务目标提供上下文使用结构化提示指定输出格式控制输出长度调整语气和风格提供示例迭代优化提示语避免歧义结合多轮对话总结 DeepSeek R1是一款基于大规模语言模型的AI工具,能够生成高质量的自然语言内容。为了充分发挥其潜力,用户需要掌握…...
UE5从入门到精通之多人游戏编程常用函数
文章目录 前言一、权限与身份判断函数1. 服务器/客户端判断2. 网络角色判断二、网络同步与复制函数1. 变量同步2. RPC调用三、连接与会话管理函数1. 玩家连接控制2. 网络模式判断四、实用工具函数前言 UE5给我们提供了非常强大的多人网路系统,让我们可以很方便的开发多人游戏…...
NGINX配置TCP负载均衡
前言 之前本人做项目需要用到nginx的tcp负载均衡,这里是当时配置做的笔记;欢迎收藏 关注,本人将会持续更新 文章目录 配置Nginx的负载均衡 配置Nginx的负载均衡 nginx编译安装需要先安装pcre、openssl、zlib等库,也可以直接编译…...
PyTorch torch.logsumexp 详解:数学原理、应用场景与性能优化(中英双语)
PyTorch torch.logsumexp 详解:数学原理、应用场景与性能优化 在深度学习和概率模型中,我们经常需要计算数值稳定的对数概率操作,特别是在处理 softmax 归一化、对数似然计算、损失函数优化 等任务时,直接求和再取对数可能会导致…...
【多模态大模型】端侧语音大模型minicpm-o:手机上的 GPT-4o 级多模态大模型
MiniCPM-o ,它是一款 开源、轻量级 的多模态大语言模型,目标是在手机等资源受限的环境中实现 GPT-4o 级别的多模态能力! 1. MiniCPM-o:小身材,大能量! MiniCPM-o 的名字已经暗示了它的核心特点:Mini (小巧) 和 CPM (中文预训练模型),最后的 “o” 则代表 Omnimodal …...
【Java 优选算法】模拟
欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 模拟算法的思路比较简单,根据题目描述列出流程,找出规律,将流程转化为代码 替换所有的问号 题目链接 解法 直接根据题目给出条件模拟 示例,找出规律 1.先找出字符?,再…...
计算机网络复习
目录 1. 前言 2.五层模型 1.应用层 2 传输层 3.网络层 4. 数据链路层 编辑5. 物理层 3.UDP/TCP协议 UDP协议 TCP协议 4. HTTP/HTTPS协议 1. 前言 博主目前大四, 备战春招, 复习一下计网, 大家也可以看看我的文章. 共同学习, 如有不足之处欢迎指正. 2.五层模型 在计…...