用 embed.FS 配合 http.FS 把静态资源打进 Go 二进制并输出 Last-Modified
把前端构建产物(dist 目录)随 Go 服务一起发布时,最常见的做法是让运维额外同步一份静态目录,再用 http.FileServer(http.Dir("./dist")) 提供服务。这套方案在单机、内网、编译产物随手丢的场合能用,但一旦涉及容器镜像、多副本、跨环境发布,就会出现三类问题:镜像里漏拷静态文件导致 404;容器只读根文件系统时无法写入;多个
把前端构建产物(dist 目录)随 Go 服务一起发布时,最常见的做法是让运维额外同步一份静态目录,再用 http.FileServer(http.Dir("./dist")) 提供服务。这套方案在单机、内网、编译产物随手丢的场合能用,但一旦涉及容器镜像、多副本、跨环境发布,就会出现三类问题:镜像里漏拷静态文件导致 404;容器只读根文件系统时无法写入;多个
在 Java 里用文本块(text block)内嵌 YAML 配置,几乎所有人都会遇到同一个坑:代码里看上去缩进整齐的片段,拼进字符串后行尾多出空白、或者被 stripIndent 削掉关键缩进,最终 SnakeYAML 抛出的异常是 mapping values are not allowed here。而换一种写法,同样是 YAML,却又能正常解析。问
用 dataclass 建模时,经常遇到这种字段:调用方要么传一个值,要么传一组「原材料」让你在构造阶段算出来,而且算出来的结果必须满足某些约束,不满足要立刻报错。比如 price 和 tax_rate 二者必须给其一,另一个由默认税率推导;再比如 birthday 与 age 只能二选一,给了生日就反推年龄,给了年龄就反推生日年份。这类需求用普通 fiel
把 Pod 的 securityContext.readOnlyRootFilesystem 设为 true 之后,最快的反馈往往不是安全加固的成就感,而是一串启动失败:nginx 起不来、Java 进程报 /tmp 不可写、Node 应用在写日志时崩溃。原因很直接——容器根文件系统变成只读以后,所有原本"随手写到容器层"的路径都失效了,而镜像里绝大多数程序
在 ECMAScript 里用 Proxy 做数据校验、埋点拦截或响应式系统时,set trap 返回 false 是最容易被低估的一个细节:非严格模式下它静默失败,严格模式下它抛出 TypeError: 'set' on proxy: trap returned falsish。更麻烦的是,这道错误来自引擎内部([[Set]] 内部方法的断言),而不是来自
面试里常听到这样一句结论:「REQUIRES_NEW 会挂起外层事务、占用两条数据库连接,嵌套一两层就把连接池打满了。」这句话一半对一半错。对的部分是 REQUIRES_NEW 确实会新开连接;错的部分是——真正导致连接池耗尽的往往不是"多占一条连接",而是外层事务卡在等锁或等结果,内层又拿不到连接,形成互相等待的僵局。本文用一个可复现的工程,把"占用两条连
任务表充当轻量消息队列时,最常见的写法是 SELECT ... FOR UPDATE 配合 ORDER BY id LIMIT 1,再在同一个事务里把状态改成 processing。单进程下这套逻辑没有问题,一旦并发上去,问题就非常明显:多个 worker 的 SELECT 会排队等同一批行锁,谁先拿到锁谁先走,其余全部阻塞在 FOR UPDATE 上。更糟
写 Java 的 IO 代码时,多数人已经习惯用 try-with-resources 替代手写 finally 里的 close()。但真正遇到线上问题时,一个高频疑问是:主逻辑抛了异常,close() 也抛了异常,为什么日志里只看得到主异常?第二个异常去哪了?答案是被挂到了主异常的 suppressed 列表里,需要通过 Throwable.getSup
在运维脚本里跑外部命令,最常见的写法是 subprocess.run(cmd, shell=True, timeout=60)。命令正常结束当然没问题,一旦超时,subprocess.run 会抛 subprocess.TimeoutExpired,同时它内部只对直接子进程调用 kill(),然后 wait() 回收。问题就在这里:被 kill 的只是那个