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

GORM实战避坑指南:从‘小白’到‘老鸟’必须知道的10个细节(含MySQL连接配置)

GORM实战避坑指南从‘小白’到‘老鸟’必须知道的10个细节含MySQL连接配置1. MySQL连接配置的隐藏陷阱charsetutf8mb4的必要性MySQL默认的utf8编码只支持最多3字节的字符而emoji表情等特殊字符需要4字节存储。若不指定utf8mb4存储这类字符时会直接报错。实际项目中遇到过用户昵称含emoji导致注册失败的案例// 错误示范可能无法存储emoji dsn : user:passtcp(127.0.0.1:3306)/dbname?charsetutf8 // 正确配置 dsn : user:passtcp(127.0.0.1:3306)/dbname?charsetutf8mb4parseTimeTruelocLocalparseTimeTrue的深层作用该参数确保数据库的datetime类型能正确映射到Go的time.Time。曾有个生产环境事故未开启此选项导致时间字段被解析为字符串引发排序混乱。locLocal的时区陷阱当数据库服务器与应用服务器位于不同时区时建议明确指定时区。某跨境项目曾因未设置时区导致订单时间显示比实际早8小时。关键参数组合建议charsetutf8mb4parseTimeTruelocAsia/Shanghai国内项目推荐上海时区避免夏令时问题2. 零值处理的三种武器对比GORM默认会忽略零值字段0, false, 这可能导致意外行为问题复现type Product struct { ID uint Price int // 默认0 OnSale bool // 默认false } db.Create(Product{}) // 生成的SQLINSERT INTO products DEFAULT VALUES解决方案对比表方案优点缺点适用场景指针类型直观零值明确需处理nil指针简单零值需求sql.NullXXX标准库支持代码稍显冗长需要区分NULL/零值gorm.DeletedAt风格内置支持仅适用特定类型软删除等特殊场景指针类型实战示例type User struct { Name *string gorm:default:匿名用户 Age *int } user : User{ Name: new(string), // 显式初始化为空字符串 Age: new(int), // 显式初始化为0 } db.Create(user) // 会明确插入空字符串和03. 软删除的七个注意事项GORM的DeletedAt看似简单但隐藏诸多细节1. 查询自动过滤默认会添加WHERE deleted_at IS NULL条件这可能导致联表查询时遗漏数据。需要特别注意关联模型的查询逻辑。2. 唯一索引冲突已软删除的记录仍占用唯一索引。解决方案-- 添加删除标记到唯一索引 ALTER TABLE users ADD UNIQUE (name, deleted_at)3. 性能影响大量软删除数据会降低查询效率。建议定期归档某电商平台曾因500万软删除订单导致列表查询超时。4. 恢复技巧db.Unscoped().Model(user).Update(deleted_at, nil)5. 关联删除需要手动处理关联表的软删除GORM不会自动级联db.Transaction(func(tx *gorm.DB) error { if err : tx.Delete(user).Error; err ! nil { return err } return tx.Model(user.Address).Update(deleted_at, time.Now()).Error })6. 审计追踪可结合gorm hook实现删除记录备份func (u *User) AfterDelete(tx *gorm.DB) error { return tx.Create(DeleteLog{ ModelName: User, RecordID: u.ID, Operator: getCurrentUser(), }).Error }7. 混合删除策略某些敏感数据可能需要物理删除if user.IsSensitive { db.Unscoped().Delete(user) } else { db.Delete(user) }4. 批量操作性能优化实战CreateInBatches的黄金法则每批100-1000条是经验值过大导致内存压力过小增加网络往返必须搭配事务使用性能对比测试数据批次大小10万条耗时内存峰值全单条78s1.2GB每批5042s800MB每批50028s650MB每批500031s1.5GB事务边界的最佳实践err : db.Transaction(func(tx *gorm.DB) error { // 先处理主表 if err : tx.CreateInBatches(products, 500).Error; err ! nil { return err } // 再处理关联表 return tx.CreateInBatches(productDetails, 500).Error })批量更新的坑直接使用Updates会触发全表扫描// 反例性能杀手 db.Model(User{}).Where(age ?, 18).Updates(map[string]interface{}{vip: true}) // 正解分批处理 for i : 0; i total; i 1000 { db.Model(User{}). Where(id BETWEEN ? AND ?, i, i999). Updates(map[string]interface{}{vip: true}) }5. 模型定义的十二个技巧1. 自定义表名黑科技func (User) TableName() string { if env.IsTest() { return test_users } return users }2. 字段标签的隐藏用法type APIRequestLog struct { ID uint gorm:primarykey Request string gorm:type:json // 自动序列化为JSON Headers Map gorm:type:json // 自定义类型 CreatedAt time.Time gorm:index:idx_api // 复合索引 }3. 智能默认值策略type Order struct { Status string gorm:default:pending SecretKey string gorm:default:uuid_generate_v4() // 使用数据库函数 }4. 复合索引优化// 多字段索引 db.Model(User{}).Index(idx_name_age, name, age) // 条件索引 db.Model(User{}).Index(idx_active_email, email).Where(is_active ?, true)5. 敏感字段自动加密func (u *User) BeforeSave(tx *gorm.DB) error { if u.PasswordChanged { hash, err : bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost) if err ! nil { return err } u.EncryptedPassword string(hash) } return nil }6. 版本控制实现type Document struct { ID uint Content string Version int gorm:default:1 } // 更新时自动增加版本号 db.Model(doc).Updates(map[string]interface{}{ content: newContent, version: gorm.Expr(version 1), })6. 查询优化的六个层级1. 字段选择艺术// 反例 db.Find(users) // 正解 db.Select(id, name).Find(users) // 动态选择 fields : getRequestedFields() db.Model(User{}).Select(fields).Find(users)2. 预加载的智能控制// 基本预加载 db.Preload(Orders.Items).Find(users) // 条件预加载 db.Preload(Orders, state ?, paid).Find(users) // 自定义预加载 db.Preload(Orders, func(db *gorm.DB) *gorm.DB { return db.Order(orders.created_at DESC).Limit(3) }).Find(users)3. 分页查询标准方案func Paginate(page, pageSize int) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { offset : (page - 1) * pageSize return db.Offset(offset).Limit(pageSize) } } db.Scopes(Paginate(1, 20)).Find(users)4. 避免N1查询的三种模式急加载(Eager Loading)批量查询(Batch Query)数据关联(Data Loader)5. 复杂查询的SQL构建db.Where(name LIKE ?, %张%). Where(db.Where(age ?, 20).Or(vip ?, true)). Not(id IN ?, []int{1,2,3}). Find(users)6. 查询缓存策略// 使用Redis缓存查询结果 func GetUsers(c *gin.Context) { cacheKey : fmt.Sprintf(users:%d, c.GetInt(page)) if data, err : redis.Get(cacheKey); err nil { c.JSON(200, data) return } var users []User if err : db.Scopes(Paginate(c)).Find(users).Error; err ! nil { c.AbortWithError(500, err) return } redis.SetEx(cacheKey, users, 5*time.Minute) c.JSON(200, users) }7. 事务处理的五种模式1. 自动事务模板func TransferMoney(db *gorm.DB, from, to uint, amount float64) error { return db.Transaction(func(tx *gorm.DB) error { // 扣款 if err : tx.Model(Account{}). Where(id ? AND balance ?, from, amount). Update(balance, gorm.Expr(balance - ?, amount)).Error; err ! nil { return err } // 存款 return tx.Model(Account{}). Where(id ?, to). Update(balance, gorm.Expr(balance ?, amount)).Error }) }2. 嵌套事务控制func ComplexOperation(db *gorm.DB) error { tx : db.Begin() defer func() { if r : recover(); r ! nil { tx.Rollback() } }() if err : Step1(tx); err ! nil { tx.Rollback() return err } if err : Step2(tx); err ! nil { tx.Rollback() return err } return tx.Commit().Error }3. 事务隔离级别设置// MySQL设置读已提交 db.Exec(SET TRANSACTION ISOLATION LEVEL READ COMMITTED)4. 乐观锁实现type Product struct { ID uint Version int Stock int } func BuyProduct(db *gorm.DB, id uint) error { return db.Transaction(func(tx *gorm.DB) error { var p Product if err : tx.First(p, id).Error; err ! nil { return err } if p.Stock 0 { return errors.New(库存不足) } result : tx.Model(Product{}). Where(id ? AND version ?, id, p.Version). Updates(map[string]interface{}{ stock: p.Stock - 1, version: p.Version 1, }) if result.RowsAffected 0 { return errors.New(并发冲突) } return nil }) }5. 分布式事务方案// 使用Saga模式示例 func PlaceOrder(db *gorm.DB, order *Order) error { saga : saga.NewSaga(create_order) saga.AddStep(saga.Step{ Name: create_order, Func: func() error { return db.Create(order).Error }, Compensate: func() error { return db.Delete(order).Error }, }) saga.AddStep(saga.Step{ Name: deduct_inventory, Func: func() error { return DeductInventory(db, order.Items) }, Compensate: func() error { return RestoreInventory(db, order.Items) }, }) return saga.Run() }8. 钩子函数的九个应用场景1. 数据校验func (u *User) BeforeCreate(tx *gorm.DB) error { if u.Age 18 { return errors.New(未成年人禁止注册) } return nil }2. 自动加密func (u *User) BeforeSave(tx *gorm.DB) error { if u.Password ! !strings.HasPrefix(u.Password, $2a$) { hashed, err : bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost) if err ! nil { return err } u.Password string(hashed) } return nil }3. 审计日志func (o *Order) AfterUpdate(tx *gorm.DB) error { changes : getFieldChanges(o) return tx.Create(AuditLog{ Model: Order, RecordID: o.ID, Action: update, Changes: changes, }).Error }4. 自动填充字段func (m *Model) BeforeCreate(tx *gorm.DB) error { if m.UUID { m.UUID uuid.New().String() } return nil }5. 关联数据处理func (u *User) AfterDelete(tx *gorm.DB) error { return tx.Model(LoginHistory{}). Where(user_id ?, u.ID). Update(deleted_at, time.Now()).Error }6. 缓存失效func (p *Product) AfterSave(tx *gorm.DB) error { return cache.Delete(fmt.Sprintf(product:%d, p.ID)) }7. 状态机控制func (o *Order) BeforeUpdate(tx *gorm.DB) error { var old Order if err : tx.First(old, o.ID).Error; err ! nil { return err } if !validStateTransition(old.Status, o.Status) { return errors.New(非法状态转换) } return nil }8. 数据脱敏func (u *User) AfterFind(tx *gorm.DB) error { if u.Phone ! { u.Phone maskPhone(u.Phone) } return nil }9. 并发控制func (a *Account) BeforeUpdate(tx *gorm.DB) error { if a.Balance 0 { return errors.New(余额不足) } return nil }9. 性能监控与调优1. 慢查询日志db.Callback().Query().Register(log_slow_query, func(db *gorm.DB) { if db.Statement.SQL.String() ! { elapsed : time.Since(db.Statement.StartTime) if elapsed 200*time.Millisecond { log.Printf(SLOW QUERY: %s (%v), db.Statement.SQL.String(), elapsed) } } })2. 连接池配置sqlDB, _ : db.DB() sqlDB.SetMaxIdleConns(10) // 空闲连接数 sqlDB.SetMaxOpenConns(100) // 最大连接数 sqlDB.SetConnMaxLifetime(time.Hour) // 连接生命周期3. 执行计划分析db.Debug().Where(name ?, 张三).Explain(FORMATJSON).Find(user)4. 批量操作指标start : time.Now() count : 0 db.Callback().Create().After(gorm:create).Register(count_inserts, func(db *gorm.DB) { count if count%1000 0 { log.Printf(已插入 %d 条耗时 %v, count, time.Since(start)) } })5. 索引使用分析-- 在MySQL中检查索引使用情况 EXPLAIN SELECT * FROM users WHERE name 张三;10. 生产环境最佳实践1. 配置管理type DBConfig struct { Host string env:DB_HOST MaxOpenConns int env:DB_MAX_CONNS envDefault:100 ConnMaxLifetime string env:DB_CONN_LIFETIME envDefault:1h } func NewGORM(cfg DBConfig) (*gorm.DB, error) { dsn : fmt.Sprintf(%s:%stcp(%s)/dbname?charsetutf8mb4parseTimeTruelocLocal, os.Getenv(DB_USER), os.Getenv(DB_PASS), cfg.Host, ) db, err : gorm.Open(mysql.Open(dsn), gorm.Config{ DisableForeignKeyConstraintWhenMigrating: true, }) sqlDB, _ : db.DB() sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) if lifetime, err : time.ParseDuration(cfg.ConnMaxLifetime); err nil { sqlDB.SetConnMaxLifetime(lifetime) } return db, err }2. 迁移策略// 使用版本控制迁移 migrator : migrate.NewMigrator(db, migrate.Options{ TableName: migrations, }) migrator.AddMigration(migrate.Migration{ ID: 202305010000, Migrate: func(tx *gorm.DB) error { return tx.AutoMigrate(User{}) }, Rollback: func(tx *gorm.DB) error { return tx.Migrator().DropTable(users) }, })3. 健康检查func HealthCheck(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx, cancel : context.WithTimeout(r.Context(), 2*time.Second) defer cancel() var ok int err : db.WithContext(ctx).Raw(SELECT 1).Scan(ok).Error if err ! nil || ok ! 1 { w.WriteHeader(http.StatusServiceUnavailable) fmt.Fprint(w, DB unhealthy) return } w.WriteHeader(http.StatusOK) fmt.Fprint(w, DB healthy) } }4. 混沌工程测试// 模拟网络延迟 db.Callback().Query().Before(gorm:query).Register(chaos_latency, func(db *gorm.DB) { if os.Getenv(CHAOS_MODE) true rand.Intn(100) 10 { // 10%概率 time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond) } }) // 模拟错误 db.Callback().Create().Before(gorm:create).Register(chaos_error, func(db *gorm.DB) { if os.Getenv(CHAOS_MODE) true rand.Intn(100) 5 { // 5%概率 db.AddError(errors.New(模拟数据库错误)) } })5. 多租户处理func SetTenantScope(tenantID string) func(db *gorm.DB) *gorm.DB { return func(db *gorm.DB) *gorm.DB { return db.Where(tenant_id ?, tenantID) } } // 使用示例 db.Scopes(SetTenantScope(acme-corp)).Find(users)

相关文章:

GORM实战避坑指南:从‘小白’到‘老鸟’必须知道的10个细节(含MySQL连接配置)

GORM实战避坑指南:从‘小白’到‘老鸟’必须知道的10个细节(含MySQL连接配置) 1. MySQL连接配置的隐藏陷阱 charsetutf8mb4的必要性 MySQL默认的utf8编码只支持最多3字节的字符,而emoji表情等特殊字符需要4字节存储。若不指定utf8…...

Altium Designer16禁止区域设置避坑指南:为什么你的剪切块总是不生效?

Altium Designer 16禁止区域设置避坑指南:为什么你的剪切块总是不生效? 在PCB设计过程中,禁止区域(Keep-Out Region)的设置是确保电路板可靠性的重要环节。然而,许多Altium Designer 16用户在实际操作中经常遇到剪切块转换失败的问…...

告别玄学调参:在ADS里用Yield Analysis给你的射频滤波器设计上个‘保险’

射频滤波器设计的工程化验证:用ADS Yield Analysis实现稳健性设计 在Wi-Fi 6E和5G毫米波频段快速普及的今天,射频前端模块的性能直接决定了通信质量的上限。作为信号链路上的"守门人",滤波器设计不仅要满足理想仿真环境下的指标要求…...

C#实战:5分钟搞定Modbus RTU通讯(基于NModbus4库)

C#实战:5分钟搞定Modbus RTU通讯(基于NModbus4库) 工业自动化领域的数据采集离不开设备通讯协议的支持,而Modbus RTU作为最广泛应用的串行通信协议之一,几乎成为工控开发者的必修课。今天我们就用C#和NModbus4库&#…...

告别第三方工具:用Cloudflare官方测速文件快速检测你的网络性能

告别第三方工具:用Cloudflare官方测速文件快速检测你的网络性能 你是否遇到过这样的场景:视频缓冲转圈、文件下载龟速、在线会议卡顿,却不知道是网络问题还是服务商的问题?传统的测速工具要么需要安装软件,要么广告满天…...

多人对话录音整理神器:ClearerVoice-Studio语音分离功能详细教程

多人对话录音整理神器:ClearerVoice-Studio语音分离功能详细教程 1. 引言:告别混乱的多人录音 你是否经常需要整理会议录音、访谈记录或多人讨论内容?传统的录音文件往往混杂着多个人的声音,背景噪音干扰严重,整理起…...

提示工程架构师用Agentic AI,为智能城市提升品质生活

提示工程架构师:借助Agentic AI提升智慧城市品质生活 一、引言 (Introduction) 钩子 (The Hook) 想象一下,你生活在这样一个城市:每天清晨,你的智能设备会根据当天的天气、你的日程安排,精准推荐最适宜的衣物和出行方式…...

国产AI 调用量反超美国,22个免费大模型API集结,DMXAPI 成开发者首选

据 OpenRouter 最新数据,2026 年 3 月中国 AI 大模型周调用量达 4.69 万亿 Token,连续两周超越美国,全球调用量前三席位被小米 MiMo-V2-Pro、阶跃星辰 Step 3.5 Flash、MiniMax M2.5 包揽,国产模型凭性能与性价比获全球开发者认可…...

掌握BepInEx:Unity游戏扩展全家桶的零门槛实践指南

掌握BepInEx:Unity游戏扩展全家桶的零门槛实践指南 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx 🔍 游戏模组管理的行业痛点与解决方案 在Unity游戏生态…...

淘宝母婴购物数据可视化分析:从数据清洗到商业洞察

1. 淘宝母婴数据清洗实战:从原始数据到分析就绪 做数据分析最头疼的就是拿到一堆乱七八糟的原始数据,淘宝母婴数据也不例外。我最近处理过一批天池比赛的脱敏数据,光是清洗环节就踩了不少坑。先说说最基础的CSV导入,用pandas的rea…...

pkNX:定制宝可梦游戏体验的全能编辑工具指南

pkNX:定制宝可梦游戏体验的全能编辑工具指南 【免费下载链接】pkNX Pokmon (Nintendo Switch) ROM Editor & Randomizer 项目地址: https://gitcode.com/gh_mirrors/pk/pkNX 你是否曾想过在宝可梦游戏中拥有独一无二的精灵阵容?是否希望调整训…...

Scratch3.0离线编辑器安装指南:一步步教你轻松搞定

1. 为什么你需要Scratch3.0离线编辑器 Scratch作为全球最受欢迎的少儿编程工具,它的在线版本虽然方便,但经常会遇到网络不稳定、加载缓慢的问题。我去年给小学生上课时就遇到过这种情况——全班40个孩子同时登录在线编辑器,结果服务器直接卡死…...

高效解决Magpie插件更新难题:完全掌握图像增强功能升级指南

高效解决Magpie插件更新难题:完全掌握图像增强功能升级指南 【免费下载链接】Magpie An all-purpose window upscaler for Windows 10/11. 项目地址: https://gitcode.com/gh_mirrors/mag/Magpie 识别插件更新需求:为何及时升级至关重要 在使用M…...

【HFP】规范精讲[15]: HFP蓝牙特有AT命令:免提场景专属功能的控制语言

在蓝牙HFP的命令体系中,除了复用自传统移动通信标准的AT命令,还有一类专门为蓝牙免提场景设计的专属AT命令。这些命令就像为蓝牙免提设备量身定制的方言,针对无线音频传输、设备间状态同步、蓝牙特有功能等场景进行了精准优化,是实…...

别再只会用滑动平均了!用Python从零实现数字陷波器,精准滤除50Hz工频干扰

从零构建Python数字陷波器:精准滤除50Hz工频干扰的工程实践 当你在深夜调试一个心爱的传感器项目时,突然发现采集到的数据波形上叠加了一个顽固的50Hz正弦波——这种经历想必不少硬件开发者都深有体会。工频干扰就像电子世界中的背景噪音,无…...

别再死记硬背!用拖拽和右键菜单玩转汇川CodeSys网络与硬件组态

汇川CodeSys图形化组态实战:拖拽与右键菜单的高效玩法 第一次打开汇川CodeSys的组态界面时,那些密密麻麻的菜单和复杂的参数设置确实让人望而生畏。但当我发现可以用鼠标拖拽完成90%的配置工作时,整个PLC编程体验彻底改变了——就像从DOS命令…...

别再死记硬背了!用Halcon的vector_angle_to_rigid算子搞定视觉定位,附完整代码

视觉定位实战:用Halcon的vector_angle_to_rigid算子避开几何变换的三大误区 在工业视觉项目中,刚体变换是坐标转换的核心技术,但许多工程师在使用Halcon的vector_angle_to_rigid算子时,常陷入三个致命误区:误认为旋转…...

Tomcat服务没启动?手把手解决127.0.0.1拒绝连接问题(附端口排查技巧)

Tomcat服务没启动?手把手解决127.0.0.1拒绝连接问题(附端口排查技巧) 当你满怀期待地在浏览器输入http://127.0.0.1:8080准备测试刚部署的Java Web应用时,屏幕上冰冷的"拒绝连接"提示就像一盆冷水浇下来。这种情况我见过…...

5分钟搞定Qwen2-7B本地部署:从GGUF下载到API调用的保姆级教程

5分钟极速部署Qwen2-7B:从模型下载到API调用的实战手册 在人工智能技术快速迭代的今天,能够在本地高效运行大语言模型已成为开发者的一项核心竞争力。Qwen2-7B作为当前最受关注的中等规模开源模型之一,以其出色的中文理解能力和适中的硬件需求…...

联想X3650M5服务器双模式切换实战:UEFI与Legacy BIOS自由转换技巧

联想X3650M5服务器双模式切换实战:UEFI与Legacy BIOS自由转换技巧 在企业级IT基础设施中,服务器启动模式的灵活配置往往是系统部署的关键第一步。联想X3650M5作为主流机架式服务器,其双模式切换功能直接影响着操作系统兼容性、磁盘性能表现乃…...

OpenClaw+GLM-4.7-Flash:科研数据收集与处理自动化方案

OpenClawGLM-4.7-Flash:科研数据收集与处理自动化方案 1. 为什么科研需要自动化助手 去年冬天,我在整理一篇跨学科综述论文时,经历了连续三周每天14小时的手动文献筛选和数据提取。当我在凌晨三点对着第237篇PDF文件发呆时,突然…...

基于遗忘因子递推最小二乘法的电池模型参数在线辨识与优化

1. 电池模型参数辨识为什么需要FFRLS算法 我第一次接触电池参数辨识是在开发一款智能硬件时,当时发现传统最小二乘法有个致命问题——它会把所有历史数据同等对待。这就像用算盘计算平均数时,不管数据是昨天还是去年的,都按相同权重处理。但在…...

从YOLO到DeepLab:盘点CV任务中那些‘神级’特征融合技巧与避坑指南

从YOLO到DeepLab:盘点CV任务中那些‘神级’特征融合技巧与避坑指南 在计算机视觉领域,特征融合技术就像一位隐形的调音师,默默协调着神经网络中不同层次、不同来源的信息流。当你在目标检测任务中遇到小目标识别率低的问题,或在图…...

Python量化交易入门:利用Baostock API高效获取股票历史数据

1. 为什么选择Baostock获取股票数据? 第一次接触量化交易时,最头疼的就是数据来源问题。市面上的数据接口要么收费昂贵,要么数据质量参差不齐。直到发现了Baostock这个宝藏工具,我的量化研究才真正走上正轨。 Baostock最大的优势在…...

手把手调试Linux DRM:如何用ftrace和debugfs深入connector的生命周期

深入Linux DRM调试:用ftrace与debugfs剖析connector全生命周期 当一块崭新的显示板卡接入系统时,DRM驱动中的connector如同一位尽职的接线员,负责建立显示设备与内核之间的通信桥梁。但在实际开发中,我们常会遇到热插拔检测失灵、…...

MAD与标准差:鲁棒统计中的抗噪利器

1. 为什么我们需要抗噪统计量? 在日常数据分析中,我们经常会遇到一些"不听话"的数据点。比如分析员工薪资时突然冒出几个高管的天价年薪,或者测量温度时混入几个明显错误的极端值。这时候如果直接用传统的标准差来计算离散程度&…...

OpenClaw+GLM-4.7-Flash数据助手:Excel报表自动生成与分析

OpenClawGLM-4.7-Flash数据助手:Excel报表自动生成与分析 1. 为什么需要自动化数据助手 作为一位经常与Excel报表打交道的分析师,我每天要花大量时间重复执行数据清洗、格式转换和基础分析。最痛苦的是每月底需要手动合并十几个分公司的销售数据&#…...

Emu3.5 视觉 tokenizer 及其 decoder 的训练过程

下面我把 Emu3.5 视觉 tokenizer 及其 decoder 的训练完整过程,按照“论文明确写到的部分”“公开代码能对上的部分”“需要用开源近似路线复现的部分”三层重新整理。先给结论: 结论:Emu3.5 的视觉部分其实不是“一次性训练完一个模块”,而是至少分成两条链路: 第一条是…...

泛微E9 OA流程表单右上角加按钮?用Ecode 5分钟搞定(附完整代码)

泛微E9流程表单5分钟极速加装功能按钮实战指南 每次接到"明天就要上线"的需求时,IT部门的咖啡机总是格外忙碌。上周三下午4点,我正收拾背包准备下班,业务部门的小王火急火燎地冲进办公室:"老师!采购流程…...

Acode:重新定义Android移动代码编辑体验

Acode:重新定义Android移动代码编辑体验 【免费下载链接】Acode Acode - powerful text/code editor for android 项目地址: https://gitcode.com/gh_mirrors/ac/Acode 在移动开发日益普及的今天,拥有一款高效的移动代码编辑器成为开发者的迫切需…...