算法学习原型如何补齐稳定性边界
原型阶段把状态放在全局内存里往往足够方便。进入服务阶段后,真正需要回答的问题变成:缓存丢失会不会影响正确性,容量满了怎么办,后台任务如何退出,多个请求如何共享状态。没有这些边界,功能即使跑通也很难稳定运行。
先决定缓存是不是事实来源
如果缓存只是加速层,重启或淘汰后应能从数据库、对象存储或重新计算中恢复;如果它保存了唯一状态,就要把持久化、备份和恢复方案写清楚。容量策略也要明确:拒绝新值、淘汰旧值,还是降级为不缓存,各自影响不同。
读多写少的本地缓存可以从互斥锁开始。不要因为看到RWMutex、跳表或 LRU 就默认其中一种更快,读写比例、键分布和对象大小才是选择依据。
func (c *Cache) Get(key string) ([]byte, bool) { c.mu.RLock() defer c.mu.RUnlock() v, ok := c.items[key] return append([]byte(nil), v...), ok }这里复制切片是为了避免调用方修改缓存里的底层数组;若值是不可变对象,可采用不同的表示方式。
把停止和观测当成功能的一部分
过期清理任务要接受取消信号,停止服务时能够等待退出。缓存需要暴露命中、淘汰、当前容量和清理耗时等指标,但不要把原始键写入日志。验收至少覆盖过期、满容量、并发读写、异常输入、重启和取消。压测报告应带上硬件、工作负载和持续时间;一次没有报错,不能说明不存在泄漏或死锁。