所有文章列表

打勾图示

使用 Testcontainers 实现后端集成测试

前端测试主要重点在与浏览器打交道(Jsdom、Headless Browser)且通常只与单一后端进行沟通,而后端测试则是面临截然不同的难题:分散服务与状态。这篇文章介绍实战上我如何透过 Testcontainers 创建 Docker 测试环境来达成完整的后端整合测试流程。

Passkey 图示

实战 FIDO 验证实现无密码登录

不同网站的密码需要管理,不仅容易忘记,也存在被窃取或重复使用的风险。如果只需要扫描指纹或使用面部识别,就能立即完成注册与登录——这正是 FIDO(Fast IDentity Online)所推动的“无密码身份验证”愿景。

表格符号

Go 测试的地道写法:Table Driven Test

最近在写 Go 测试时发现官方与社群中有一种大力推崇的惯例:TableDrivenTest,我一直以为测试应该要保持简单愚蠢,但这种做法让我想到程式人的三大美德之一:「懒惰」。可能是因为这种模式通常只是测试框架包装下的方便手段,而 Go 社群文化下人人对于追求简单程式有一种莫名的执着。

扳手图示

Go Set 数据结构的地道写法

纪录近期从 JavaScript 迁移到 Go 的过程中实践 Set 资料结构的方式。先前代码使用 JavaScript Set 来实现不重复资料定义,但在 Go 语言当中并没有实践 Set 资料结构,但我们可以透过改造 map 来实践。

人与各种形状图示

通过 go:embed 在编译时将文件嵌入

纪录使用到其中一项 Go 1.16 的 embed 功能,可以把任何档案在编译时就包进去,进而不用烦恼路径与环境问题。如果资料需要在 runtime 被修改,那就不适合使用 embed,但如果它是「版本的一部分」,那 embed 是更安全的选择。

节点连接符号

P vs NP 问题探讨问题解法的难度

P 与 NP 用来描述解决问题的难度所需的时间为:polynomial time 或 non-deterministic polynomial time。将问题分类为 P 或 NP,有助于理解一个问题是否有可能在合理的时间内被解决——即执行时间不会随着输入规模的增长而爆炸性膨胀。

旗帜图标

4 种 Feature Flag 与使用时机

先前探讨到:什么是 Feature Flag 以及它解决什么问题?了解 Feature Flag 存在的价值后,今天了解更多关于 4 种类型的 Feature Flag 以及实战上的用途。不同目的的 Flag,在设计方式、生命周期、动态程度与管理策略上都有明显差异。

旗子符号

通过 OpenFeature 实践稳定产品功能发布

我一直觉得事情可以保持简单就好,有问题改程式码或环境变数切换就好,何必导入更复杂的套件管理与第三方服务呢?但真实情境当问题发生时不会有空闲慢慢部署与除错,就有必要透过更完善的 Feature Flag 规划来降低推送功能的风险,也能减少心脏病发作的机率。

盒子图示

熟悉使用 Go Module 与 Package

从 JavaScript 转写 Go 我其实还是不太熟悉 Go 如何模组化处理代码,虽然它们有大致相似的地方,但使用体验感觉非常简单甚至到简陋的程度,当然简单并不意味着「容易」或「没用」,Go 简单且固执己见的哲学在各方面都感受得到。

数据库符号

数据库查询性能问题:N+1 问题

很早以前接触资料库就有听说过「N+1 问题」,不过一直没有写下笔记认真思考过一次,这次撰写问题成因与详细解方与图表。透过:资料结构设计(去正规化)、在 DB 层完成关联资料查询、批次查询并在应用层组装、ORM ODM Eager Loading 来解决。

资料图示

Go 进行数据序列化与 Marshal 名称的起源

处理传递资料时都快忘了有「序列化与反序列化资料」这个步骤,因为都被套件像是:Axios 抽象掉了,近期在写后端也重新温习相关知识,也延续先前文章:Go Struct Tag 是什么?如何透过 reflect 动态处理栏位?探讨 Go 如何处理序列化资料。

堆疊图示

程式如何记忆:Stack 与 Heap

学习高阶程序语言通常都会接受一个观念是:「没用到的变量会自动被垃圾回收掉」。不过越接近底层或开始探讨性能问题,发现自己对于程序语言核心的记忆体概念 Heap 与 Stack 并没有那么清楚。程序语言究竟是如何分配与管理记忆体的?所谓的垃圾回收(Garbage Collection, GC)具体来说又做了哪些事情?