Go语言的缓存策略与实现

news2026/5/3 3:31:04
Go语言的缓存策略与实现1. 缓存简介缓存是一种在计算机系统中用于提高数据访问速度的技术它通过将频繁访问的数据存储在高速存储介质中减少对慢速存储介质的访问从而提高系统的响应速度和吞吐量。缓存的优势提高性能缓存可以显著减少数据访问时间提高系统响应速度降低负载减少对后端存储系统的访问降低其负载节省带宽减少数据传输量节省网络带宽提高可靠性在后端系统故障时缓存可以作为临时数据源缓存的类型本地缓存存储在应用程序内存中访问速度最快分布式缓存存储在独立的缓存服务器中可扩展性强浏览器缓存存储在用户浏览器中减少网络请求CDN缓存存储在CDN节点中减少源服务器负载2. 常见的缓存策略缓存更新策略LRU (Least Recently Used)淘汰最近最少使用的缓存项LFU (Least Frequently Used)淘汰访问频率最低的缓存项FIFO (First In First Out)按照缓存项的加入顺序淘汰TTL (Time To Live)为缓存项设置过期时间ARC (Adaptive Replacement Cache)结合LRU和LFU的优点自适应调整缓存策略缓存失效策略主动失效当数据发生变化时主动更新或删除缓存被动失效通过TTL或LRU等策略自动淘汰过期或不常用的缓存定时刷新定期更新缓存确保数据的新鲜度缓存穿透、击穿和雪崩缓存穿透查询不存在的数据导致请求直接打到后端存储缓存击穿热点数据过期导致大量请求同时打到后端存储缓存雪崩大量缓存同时过期导致后端存储压力骤增3. Go语言中的缓存库本地缓存库sync.MapGo 1.9内置的并发安全Map适合简单的缓存场景ristrettoDgraph公司开发的高性能缓存库支持LRU和LFU策略bigcache高性能的内存缓存库适合存储大量小对象groupcacheGoogle开发的分布式缓存库支持自动缓存填充分布式缓存库redis/go-redisRedis官方Go客户端go-redis/redis/v8支持Redis 6.0的Go客户端goredis/redis另一个流行的Redis Go客户端memcacheMemcached的Go客户端4. 本地缓存实现使用sync.Map实现简单缓存package main import ( fmt sync time ) // SimpleCache 简单的本地缓存 type SimpleCache struct { data map[string]cacheItem mu sync.RWMutex } // cacheItem 缓存项 type cacheItem struct { value interface{} expiration time.Time } // NewSimpleCache 创建新的缓存 func NewSimpleCache() *SimpleCache { cache : SimpleCache{ data: make(map[string]cacheItem), } // 启动清理过期缓存的协程 go cache.cleanExpired() return cache } // Set 设置缓存 func (c *SimpleCache) Set(key string, value interface{}, duration time.Duration) { c.mu.Lock() defer c.mu.Unlock() c.data[key] cacheItem{ value: value, expiration: time.Now().Add(duration), } } // Get 获取缓存 func (c *SimpleCache) Get(key string) (interface{}, bool) { c.mu.RLock() defer c.mu.RUnlock() item, exists : c.data[key] if !exists { return nil, false } // 检查是否过期 if time.Now().After(item.expiration) { return nil, false } return item.value, true } // Delete 删除缓存 func (c *SimpleCache) Delete(key string) { c.mu.Lock() defer c.mu.Unlock() delete(c.data, key) } // cleanExpired 清理过期缓存 func (c *SimpleCache) cleanExpired() { ticker : time.NewTicker(5 * time.Minute) defer ticker.Stop() for range ticker.C { c.mu.Lock() now : time.Now() for key, item : range c.data { if now.After(item.expiration) { delete(c.data, key) } } c.mu.Unlock() } } func main() { cache : NewSimpleCache() // 设置缓存 cache.Set(key1, value1, 10*time.Second) cache.Set(key2, value2, 30*time.Second) // 获取缓存 if value, exists : cache.Get(key1); exists { fmt.Printf(key1: %v\n, value) } // 等待缓存过期 time.Sleep(15 * time.Second) // 再次获取缓存 if value, exists : cache.Get(key1); exists { fmt.Printf(key1: %v\n, value) } else { fmt.Println(key1 has expired) } if value, exists : cache.Get(key2); exists { fmt.Printf(key2: %v\n, value) } }使用ristretto实现高性能缓存package main import ( fmt time github.com/dgraph-io/ristretto ) func main() { // 创建缓存 cache, err : ristretto.NewCache(ristretto.Config{ NumCounters: 10000, // 计数器数量 MaxCost: 100, // 最大成本可以是大小、数量等 BufferItems: 64, // 缓冲区大小 }) if err ! nil { panic(err) } // 设置缓存 cache.Set(key1, value1, 1) cache.Set(key2, value2, 1) // 获取缓存 if value, found : cache.Get(key1); found { fmt.Printf(key1: %v\n, value) } // 等待缓存稳定 time.Sleep(100 * time.Millisecond) // 删除缓存 cache.Del(key1) // 再次获取缓存 if value, found : cache.Get(key1); found { fmt.Printf(key1: %v\n, value) } else { fmt.Println(key1 not found) } // 关闭缓存 cache.Close() }5. 分布式缓存实现使用Redis实现分布式缓存package main import ( context fmt time github.com/go-redis/redis/v8 ) func main() { // 创建Redis客户端 rdb : redis.NewClient(redis.Options{ Addr: localhost:6379, Password: , // 无密码 DB: 0, // 默认DB }) ctx, cancel : context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 测试连接 pong, err : rdb.Ping(ctx).Result() if err ! nil { panic(err) } fmt.Println(pong) // 设置缓存 err rdb.Set(ctx, key1, value1, 10*time.Second).Err() if err ! nil { panic(err) } // 获取缓存 val, err : rdb.Get(ctx, key1).Result() if err redis.Nil { fmt.Println(key1 does not exist) } else if err ! nil { panic(err) } else { fmt.Printf(key1: %v\n, val) } // 设置哈希表 err rdb.HSet(ctx, user:1, map[string]interface{}{ name: John, age: 30, }).Err() if err ! nil { panic(err) } // 获取哈希表 user, err : rdb.HGetAll(ctx, user:1).Result() if err ! nil { panic(err) } fmt.Printf(user:1: %v\n, user) // 关闭连接 err rdb.Close() if err ! nil { panic(err) } }使用Redis实现缓存策略package main import ( context fmt time github.com/go-redis/redis/v8 ) // Cache Redis缓存封装 type Cache struct { rdb *redis.Client } // NewCache 创建新的缓存 func NewCache(addr string) *Cache { rdb : redis.NewClient(redis.Options{ Addr: addr, }) return Cache{rdb: rdb} } // Set 设置缓存 func (c *Cache) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error { return c.rdb.Set(ctx, key, value, expiration).Err() } // Get 获取缓存 func (c *Cache) Get(ctx context.Context, key string) (string, error) { return c.rdb.Get(ctx, key).Result() } // Delete 删除缓存 func (c *Cache) Delete(ctx context.Context, key string) error { return c.rdb.Del(ctx, key).Err() } // Exists 检查缓存是否存在 func (c *Cache) Exists(ctx context.Context, key string) (bool, error) { result, err : c.rdb.Exists(ctx, key).Result() return result 0, err } // SetWithTTL 设置缓存并指定TTL func (c *Cache) SetWithTTL(ctx context.Context, key string, value interface{}, ttl time.Duration) error { return c.rdb.Set(ctx, key, value, ttl).Err() } // Incr 原子递增 func (c *Cache) Incr(ctx context.Context, key string) (int64, error) { return c.rdb.Incr(ctx, key).Result() } // Close 关闭缓存连接 func (c *Cache) Close() error { return c.rdb.Close() } func main() { cache : NewCache(localhost:6379) defer cache.Close() ctx : context.Background() // 设置缓存 err : cache.Set(ctx, counter, 0, 24*time.Hour) if err ! nil { panic(err) } // 原子递增 for i : 0; i 5; i { count, err : cache.Incr(ctx, counter) if err ! nil { panic(err) } fmt.Printf(Counter: %d\n, count) } // 获取缓存 value, err : cache.Get(ctx, counter) if err ! nil { panic(err) } fmt.Printf(Final counter value: %s\n, value) }6. 缓存一致性缓存一致性策略Cache-Aside应用程序负责管理缓存和数据源Read-Through缓存负责从数据源加载数据Write-Through缓存负责将数据写入数据源Write-Behind缓存异步将数据写入数据源实现Cache-Aside策略package main import ( context fmt time github.com/go-redis/redis/v8 ) // CacheAside 实现Cache-Aside策略 type CacheAside struct { cache *Cache // 模拟数据库 db map[string]string } // NewCacheAside 创建新的CacheAside func NewCacheAside() *CacheAside { return CacheAside{ cache: NewCache(localhost:6379), db: make(map[string]string), } } // Get 获取数据 func (ca *CacheAside) Get(ctx context.Context, key string) (string, error) { // 先从缓存获取 value, err : ca.cache.Get(ctx, key) if err nil { fmt.Println(Cache hit) return value, nil } // 缓存未命中从数据库获取 fmt.Println(Cache miss, fetching from database) value, exists : ca.db[key] if !exists { return , fmt.Errorf(key not found) } // 将数据写入缓存 ca.cache.Set(ctx, key, value, 5*time.Minute) return value, nil } // Set 设置数据 func (ca *CacheAside) Set(ctx context.Context, key, value string) error { // 先更新数据库 ca.db[key] value // 再更新缓存 return ca.cache.Set(ctx, key, value, 5*time.Minute) } // Delete 删除数据 func (ca *CacheAside) Delete(ctx context.Context, key string) error { // 先删除数据库 delete(ca.db, key) // 再删除缓存 return ca.cache.Delete(ctx, key) } func main() { ca : NewCacheAside() defer ca.cache.Close() ctx : context.Background() // 设置数据 err : ca.Set(ctx, user:1, John Doe) if err ! nil { panic(err) } // 第一次获取应该从数据库加载 value, err : ca.Get(ctx, user:1) if err ! nil { panic(err) } fmt.Printf(Get user:1: %s\n, value) // 第二次获取应该从缓存加载 value, err ca.Get(ctx, user:1) if err ! nil { panic(err) } fmt.Printf(Get user:1 again: %s\n, value) // 更新数据 err ca.Set(ctx, user:1, Jane Doe) if err ! nil { panic(err) } // 获取更新后的数据 value, err ca.Get(ctx, user:1) if err ! nil { panic(err) } fmt.Printf(Get updated user:1: %s\n, value) }7. 缓存性能优化缓存键设计使用前缀为不同类型的缓存使用不同的前缀如user:,product:保持简洁缓存键应该简洁明了避免过长包含版本在缓存键中包含版本号便于缓存更新使用哈希对于复杂的缓存键使用哈希函数生成唯一键缓存大小管理设置合理的缓存大小根据系统内存和访问模式设置合适的缓存大小监控缓存命中率定期监控缓存命中率调整缓存策略使用多级缓存结合本地缓存和分布式缓存提高性能并发控制使用读写锁对于本地缓存使用读写锁提高并发性能使用原子操作对于计数器等简单操作使用原子操作避免缓存风暴使用分布式锁或随机退避避免缓存击穿序列化优化选择高效的序列化格式如Protocol Buffers、MessagePack等压缩数据对于大型缓存项使用压缩减少存储空间批量操作使用批量操作减少网络往返8. 实际应用案例电商商品缓存系统架构商品服务提供商品信息缓存服务缓存商品信息数据库存储商品信息代码示例package main import ( context encoding/json fmt time github.com/go-redis/redis/v8 ) // Product 商品信息 type Product struct { ID int json:id Name string json:name Price float64 json:price Description string json:description } // ProductService 商品服务 type ProductService struct { cache *Cache db map[int]Product } // NewProductService 创建商品服务 func NewProductService() *ProductService { return ProductService{ cache: NewCache(localhost:6379), db: map[int]Product{ 1: {ID: 1, Name: iPhone 13, Price: 7999, Description: Apple iPhone 13}, 2: {ID: 2, Name: Samsung Galaxy S21, Price: 6999, Description: Samsung Galaxy S21}, 3: {ID: 3, Name: Xiaomi Mi 11, Price: 4999, Description: Xiaomi Mi 11}, }, } } // GetProduct 获取商品信息 func (ps *ProductService) GetProduct(ctx context.Context, id int) (Product, error) { // 构建缓存键 key : fmt.Sprintf(product:%d, id) // 先从缓存获取 value, err : ps.cache.Get(ctx, key) if err nil { // 缓存命中反序列化 var product Product err json.Unmarshal([]byte(value), product) if err nil { fmt.Println(Cache hit for product, id) return product, nil } } // 缓存未命中从数据库获取 fmt.Println(Cache miss for product, id) product, exists : ps.db[id] if !exists { return Product{}, fmt.Errorf(product not found) } // 将数据写入缓存 productJSON, err : json.Marshal(product) if err nil { ps.cache.Set(ctx, key, string(productJSON), 10*time.Minute) } return product, nil } // UpdateProduct 更新商品信息 func (ps *ProductService) UpdateProduct(ctx context.Context, product Product) error { // 更新数据库 ps.db[product.ID] product // 更新缓存 key : fmt.Sprintf(product:%d, product.ID) productJSON, err : json.Marshal(product) if err ! nil { return err } return ps.cache.Set(ctx, key, string(productJSON), 10*time.Minute) } // DeleteProduct 删除商品 func (ps *ProductService) DeleteProduct(ctx context.Context, id int) error { // 删除数据库 delete(ps.db, id) // 删除缓存 key : fmt.Sprintf(product:%d, id) return ps.cache.Delete(ctx, key) } func main() { ps : NewProductService() defer ps.cache.Close() ctx : context.Background() // 获取商品第一次从数据库加载 product, err : ps.GetProduct(ctx, 1) if err ! nil { panic(err) } fmt.Printf(Product: %v\n, product) // 再次获取商品从缓存加载 product, err ps.GetProduct(ctx, 1) if err ! nil { panic(err) } fmt.Printf(Product from cache: %v\n, product) // 更新商品 product.Price 7499 err ps.UpdateProduct(ctx, product) if err ! nil { panic(err) } // 获取更新后的商品 product, err ps.GetProduct(ctx, 1) if err ! nil { panic(err) } fmt.Printf(Updated product: %v\n, product) }用户会话缓存系统架构认证服务处理用户登录和认证缓存服务缓存用户会话信息数据库存储用户信息代码示例package main import ( context encoding/json fmt time github.com/go-redis/redis/v8 ) // UserSession 用户会话 type UserSession struct { UserID int json:user_id Username string json:username Token string json:token ExpiresAt int64 json:expires_at } // SessionService 会话服务 type SessionService struct { cache *Cache db map[int]string // 模拟用户数据库 } // NewSessionService 创建会话服务 func NewSessionService() *SessionService { return SessionService{ cache: NewCache(localhost:6379), db: map[int]string{ 1: john, 2: jane, 3: bob, }, } } // CreateSession 创建会话 func (ss *SessionService) CreateSession(ctx context.Context, userID int) (UserSession, error) { // 检查用户是否存在 username, exists : ss.db[userID] if !exists { return UserSession{}, fmt.Errorf(user not found) } // 创建会话 token : fmt.Sprintf(token-%d-%d, userID, time.Now().Unix()) expiresAt : time.Now().Add(24 * time.Hour).Unix() session : UserSession{ UserID: userID, Username: username, Token: token, ExpiresAt: expiresAt, } // 缓存会话 sessionJSON, err : json.Marshal(session) if err ! nil { return UserSession{}, err } key : fmt.Sprintf(session:%s, token) err ss.cache.Set(ctx, key, string(sessionJSON), 24*time.Hour) if err ! nil { return UserSession{}, err } return session, nil } // GetSession 获取会话 func (ss *SessionService) GetSession(ctx context.Context, token string) (UserSession, error) { // 从缓存获取会话 key : fmt.Sprintf(session:%s, token) value, err : ss.cache.Get(ctx, key) if err ! nil { return UserSession{}, fmt.Errorf(invalid or expired session) } // 反序列化会话 var session UserSession err json.Unmarshal([]byte(value), session) if err ! nil { return UserSession{}, fmt.Errorf(invalid session data) } // 检查会话是否过期 if time.Now().Unix() session.ExpiresAt { // 删除过期会话 ss.cache.Delete(ctx, key) return UserSession{}, fmt.Errorf(session expired) } return session, nil } // InvalidateSession 使会话失效 func (ss *SessionService) InvalidateSession(ctx context.Context, token string) error { key : fmt.Sprintf(session:%s, token) return ss.cache.Delete(ctx, key) } func main() { ss : NewSessionService() defer ss.cache.Close() ctx : context.Background() // 创建会话 session, err : ss.CreateSession(ctx, 1) if err ! nil { panic(err) } fmt.Printf(Created session: %v\n, session) // 获取会话 retrievedSession, err : ss.GetSession(ctx, session.Token) if err ! nil { panic(err) } fmt.Printf(Retrieved session: %v\n, retrievedSession) // 使会话失效 err ss.InvalidateSession(ctx, session.Token) if err ! nil { panic(err) } fmt.Println(Session invalidated) // 尝试获取已失效的会话 _, err ss.GetSession(ctx, session.Token) if err ! nil { fmt.Printf(Expected error: %v\n, err) } }9. 代码优化建议1. 错误处理优化原始代码value, err : cache.Get(ctx, key) if err ! nil { // 缓存未命中从数据库获取 value, err db.Get(key) if err ! nil { return nil, err } // 将数据写入缓存 cache.Set(ctx, key, value, 5*time.Minute) } return value, nil优化建议value, err : cache.Get(ctx, key) if err nil { return value, nil } // 缓存未命中从数据库获取 value, err db.Get(key) if err ! nil { return nil, err } // 将数据写入缓存使用goroutine异步写入不阻塞主流程 go func() { _ cache.Set(context.Background(), key, value, 5*time.Minute) }() return value, nil2. 缓存键生成优化原始代码key : fmt.Sprintf(user:%d, userID)优化建议// 使用常量定义前缀 const ( userPrefix user: productPrefix product: ) // 使用函数生成缓存键 func userKey(userID int) string { return userPrefix strconv.Itoa(userID) } key : userKey(userID)3. 缓存过期时间管理原始代码cache.Set(ctx, key, value, 5*time.Minute)优化建议// 使用配置管理过期时间 const ( DefaultCacheTTL 5 * time.Minute LongCacheTTL 24 * time.Hour ShortCacheTTL 1 * time.Minute ) // 根据数据类型设置不同的过期时间 if isHotData(key) { cache.Set(ctx, key, value, ShortCacheTTL) } else { cache.Set(ctx, key, value, DefaultCacheTTL) }4. 缓存统计和监控原始代码func (c *Cache) Get(ctx context.Context, key string) (string, error) { return c.rdb.Get(ctx, key).Result() }优化建议// 缓存统计 type CacheStats struct { Hits int64 Misses int64 Mutex sync.Mutex } func (cs *CacheStats) RecordHit() { cs.Mutex.Lock() defer cs.Mutex.Unlock() cs.Hits } func (cs *CacheStats) RecordMiss() { cs.Mutex.Lock() defer cs.Mutex.Unlock() cs.Misses } func (cs *CacheStats) HitRate() float64 { cs.Mutex.Lock() defer cs.Mutex.Unlock() total : cs.Hits cs.Misses if total 0 { return 0 } return float64(cs.Hits) / float64(total) } // 缓存实现 func (c *Cache) Get(ctx context.Context, key string) (string, error) { value, err : c.rdb.Get(ctx, key).Result() if err nil { c.stats.RecordHit() } else { c.stats.RecordMiss() } return value, err }10. 总结缓存是提高系统性能的重要手段通过合理的缓存策略和实现可以显著提高系统的响应速度和吞吐量。在Go语言中我们可以使用多种缓存库来实现不同场景的缓存需求。通过本文的学习你应该掌握了缓存的基本概念和优势常见的缓存策略和算法Go语言中常用的缓存库本地缓存和分布式缓存的实现缓存一致性的保证缓存性能优化的方法实际应用案例和代码优化建议在实际项目中选择合适的缓存策略需要考虑以下因素数据访问模式数据的访问频率和模式数据一致性要求是否需要强一致性系统资源内存、网络带宽等资源限制性能要求响应时间和吞吐量要求可维护性缓存系统的维护成本通过合理使用缓存可以构建出更加高性能、可靠的系统为用户提供更好的体验。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…