Hey, sorcererxw here.

I'm a software engineer that focuses on turning ideas into fantastic products. I share something I known through articles and the Telegram channel.

You can find me on GitHub and JIKE.

X

用 Image2 生成了 brand logo,太可爱了~ https://t.co/H6g6MOPobj

X

#每日一醉 我有一个数据分组聚合的需求,GPT5.5 觉得我输入过多数据给 LLM 成本太高了,当数据量大过一个阈值之后,直接用兜底代码处理不走 LLM 了。 我调试了半天,就说这聚合行为怪怪的,一查才知道还有这种逻辑。

X

用 goal 让 codex 自动评测+迭代 prompt,跑了一晚上,居然为了拟合评测点,完全不在 prompt 上下功夫,搞了一堆模板进来生成文本满足评测,无语了

X

一个技巧,如果你发现 codex/chatgpt thinking 卡着不动了,就尝试切一个同 region 的代理节点,只要网络一重连,agent 马上就活过来了

X

我花了一晚上,看 ai 用 goal 跑了 24 小时写出来的代码,typescript 真是不忍直视,unknown 满天飞,这代码质量不能忍,疯狂加 lint 打补丁。 😑 唉,typescript 这语言拉完了,又动了重写成 golang 的心思

X

今天调研接一个 TTS 服务,火山引擎豆包确实不错,价格也不贵,但是想来想去还是放弃了,我可不想为了接一个国内 TTS 服务还要上套内容安全策略。

Project

FeedContext

Feeds structured for your agent

X

基于 https://t.co/A3GSdf00go 的数据,想通过本地 skill 实现生成播客、长文。 实际效果太糟糕了。skill 没法强制 agent 开 subagent,如果 agent 在主流程当中做执行所有子任务,后面的任务就会因为上下文产生幻觉。 感觉还是得自己实现一套 workflow agent。

X

codex mobile 推送了,我将彻夜不眠和 grill me 畅聊🤪

X

研究了下,发现 cloudflare d1 对于写操作是整个实例级别串行,也就是说任何写操作都是库锁,这也太炸裂了 如果坚持用的话,得尽早对高写入的表分库,甚至还需要做库级别 sharding。

X

每周 codex 使用心路历程 第一天:穷怕了,要合理规划 token,5.5+medium 就好 第二天~第五天:tmd,这么慢,5.5+high+fast 拉满 第六天:就剩不到 10% 了,得省着用了,无关紧要的切到 5.3 spark 先顶一下 第七天:额度用完了,买点国产按需调用 coding plan 先用一天吧~

X

因为 Codex Pro 蹬完,充了点 Deepseek 想撑到明天 reset。 意外地发现 DS V4 Pro 的执行质量不输 GPT 5.5,而且速度快太多了(使用场景主要是执行通用 Agent 任务,非单纯编码)

X

有点陷入困境了。 原来在 agent 的沙盒环境中,skill 无法可靠地在本地持久化鉴权状态。 这意味着,如果 skill 的行为依赖带鉴权地访问服务端,那最终交付的就必须是 MCP,而不能只是一个 skill。

X

发现 Bun compile 模式已经让 TypeScript 输出单一二进制变得相当可用,再叠加各家都在把 TypeScript SDK 当一等公民,未来业务级 CLI 得优先用 TS。 系统级工具可以直接一步到位使用 Rust。 Go 在 CLI 领域的价值感会继续被压缩。

Telegram

发现 Bun compile 模式已经让 TypeScript 输出单一二进制变得相当可用,再叠加各家都在把 TypeScript SDK 当一等公民,未来业务级 CLI 得优先用 TS。 系统级工具可以直接一步到位使用 Rust。 Go 在 CLI 领域的价值会被持续压缩。

Telegram

搓了一个实验性的 skill:可以把我的 RSS feed 自动整理成一篇经过 AI 筛选和聚合的网页。 目前有两种输出形态: 一种是流畅的长文,把多条新闻无缝组织在一起,有点像播客口播稿;另一种是按主题分组,方便快速浏览重点。 它能明显缓解资讯阅读的负担,也能减少信息积压带来的 FOMO。 更有意思的是,在 AI 的加持下,传统推荐算法也许有机会也变成 BYO 模式:不再由平台决定你该看什么,而是由你带着自己的信息源、偏好和筛选逻辑来生成属于自己的信息流。 (源文件在评论区⬇️

X

#codex 支持 side chat 了,终于可以不开 worktree,直接在另一会话共享上下文了,可以在另外一个会话审查主会话的结论,或者并行发散多个问题 https://t.co/IeHlytdYGk

Project

Hopter

Remote control for your own coding agents

X

使用 spec coding,被几个 agent 追着盘问,感觉每天都是开不完技术方案评审会

X

找到一个快速推进项目的方式 功能阶段:想到一个功能就拉起一个 codex 5.5会话出方案,然后对话确认方案,然后落地实现。疯狂加功能,先不要管UIUX等一系列问题 修缮阶段:使用 codex5.3 spark 怼着界面疯狂微操,一个一个细节调整,把一堆功能完成产品化 说白了,人的精力有限,一个阶段只干一件事

Project

造声 Noisemake

给文本注入一些小错误,让它更像手工写出来的

Telegram

看到 brew 终于有 Trae 的 cask 了,安装一个试试看。之前体验过AI生成生成前端的工具,但是从来没有尝试过生成一个正儿八经的小工具。今天试试看用 Trae builder 模式“复刻”了下我的一年前的写的小工具,可以用来计算免息分期的实际价值。 老版本 https://0apr.sorcererxw.com/ 新版本 https://0apr-ai.sorcererxw.com/ 整个开发过程全是 AI (Claude-3.5-sonnet),没有改过一行代码,看着效果还不错,甚至胜过我之前的版本 同时也供君品鉴AI写的代码:https://github.com/sorcererxw/0apr-ai

Telegram

有了推理模型之后,工作中一些复杂算法代码,目前都是交给 LLM 去生成。深刻感受到,之前鼓吹了很久 TDD,在 AI 编码之后变得非常容易: 1. 根据描述,让 AI 生成一组事无巨细的 test cases。 2. 然后让 AI 生成具体代码逻辑就行,根本不需要 review 内部逻辑,单测出错了就让它一直改到对为止,必要的时候给点提示。 颇有产品经理使唤 QA 和 RD 的感觉。

Telegram

手上的一个需求,需要保存一个巨型结构体到数据库当中,得选用一个序列化方式进行存储,需要尽可能保证数据体积小。 这个结构体当中最多的就是大量的 int64 数字,很显然这种情况下使用 protobuf 相比 json 有优势,如果再搭配上压缩算法就更极致了。 一顿折腾测试了下,发现 pb 数据体积确实远小于 json 序列化,但是两者经过 zstd 压缩之后,体积居然相差无几。 那不如直接 json + zstd 就好了,还省得定义 schema。

Telegram

最近在写一个 TUI 的程序,深度使用了一下风很大的 bubbletea,锐评一下: 1. 易于构建大型复杂界面 将界面上每一个元素抽象为 model,拆分逻辑执行函数 Update 和视图渲染函数 View,在组件 Update 当中可以消费全局各种消息更新自身状态,View 当中专注渲染画面,很像 MVVM 架构。通过这种方式可以很容易创造出事件驱动的 UI 架构,对于构建复杂的交互程序很有帮助。 2. 存在界面刷新闪烁问题 可能因为封装比较浅,每一个组件渲染是输出字符串,框架视角下每次渲染是获取整个页面的字符串,很难做到根据变更区域按需要渲染,每次发生元素变更可能导致整行或者整页刷新,页面会闪烁一下,体验比较差。 对比我常用的 TUI 工具,在相同的terminal+shell下,zellij、lazygit、bottom 等,它们并有类似的情况。

Telegram

https://planetscale.com/docs/concepts/hobby-plan-deprecation-faq PlanetScale 居然开始全面收费了,原来的免费实例会自动休眠。我有几个定时任务还在依赖 PlanetScale 的 MySQL,刚发现已经好些天没有成功运行了。研究了半天,我才发现是 Planetscale 的 DB 挂了,太无语了。 https://planetscale.com/blog/planetscale-forever 估计对于 PS 来说,云数据库 SaaS 业务增长基本到头了,再深入得横向扩展很多业务。倒不如砍掉营销和销售,保持一个收支平衡的状态,专注服务好当前的企业客户就好。

Telegram

意识到这个模式,使用 iPhone 或者 AppleTV 替换 Mac 也可以实现。因为 AppleTV 不方便插网线,故选择了一台闲置的 iPhone12 搭配 lighting 以太网适配器进行测试。碰到两个问题: lighting 接口理论带宽有 480Mbps,因为在一个接口上下载并转发,实际吞吐还得打 5 折。实际测试下载,最高下载速率只有 10MB/s,实在不够看。 有一个workaround,让iPhone同时接入Wifi,因为有线网卡和无线网卡是不一样的MAC地址,可以分配不同的IP,软路由侧对这两个 IP 负载均衡,那么就可以实现低延迟需求走有线,高带宽需求走无线。 因为经过一层转发,Surge无法识别请求来源设备了,所有来源地址都是软路由。之前使用 SRC-IP 来识别 XBOX 让游戏通通走低延迟的机场,现在没法实现了。

Telegram

有一台闲置的 mac,打算用来当作家里的网络代理服务器。有几个方案: - (现状)在软路由里面安装 Clash,指定部分设备流量走 Clash,实现透明代理 - 缺点:手机电脑日常使用 Surge,只有路由器使用 Clash,需要额外维护一份 Clash 配置,麻烦 - 使用 Mac Surge 接管 DHCP,让流量走 Surge 过,实现透明代理 - 缺点:稳定性差,一旦 Mac 挂了,整个网络就瘫痪了 - 特定设备主动配置代理服务器为 Mac Surge - 缺点:不是透明代理,可能部分设备无法设置 Proxy - 在方案一的基础上,让 Clash 直接将所用流量通过 socks5 转发到 Mac Surge,Clash 当中只需要配置一条固定的 socks5 策略 目前来看,最后一个方案既能实现透明代理,又不会影响稳定性,还能实现全设备使用 Surge。

Telegram

https://github.com/valkey-io/valkey/issues/18 看到 Linux 基金会分叉了 Redis 建立了 Valkey,想起前几天另外一个 Redis 分叉 Redict,好奇两个分叉是什么关系,特地去搜了下。 看到这个 issue,Redict 维护者疯狂推销他们的许可证以及 FOSS 协作工具,尝试合并两个开发者社区。而 Valkey 维护者显然更加务实, 不接受更换代码托管和证书。 管窥开源社区的政治生态,挺有意思的。

Telegram

最近退订了Github两项付费订阅:GitHub Pro($4/m) 和 GitHub Copilot($10/m) GitHub Pro: 一开始订阅诉求是更多的 Codespaces 的单位时间额度,临时开发一些东西可以直接云端编码。 但是用着用着发现机器配置很不灵活,2C8G 和4C16G 的机器只有 32GB 磁盘空间,大一点的仓库下载一下依赖就占满了并禁止磁盘写入了。 如果想要更大的空间,8C32GB 的机器起步开始提供 64GB 的磁盘空间,这样一来 CPU 单位时间配额马上就用完了。 目前使用 Gitpod 了,无法选择 region,网络连接不如 Codespaces,但是配置足够用,实际开发体验可以接受。 GitHub Copilot: 大模型代码补全也发展好几年了,在大多数场景下,各类竞品完全能够提供不输 Copilot 的体验。 促成我寻找替代品的关键是,在远程开发模式下,Copilot 插件总是无法稳定使用 vscode 或者 goland 的 proxy 配置,导致国内的开发机无法正常补全代码。 目前转向使用 Codeium 了,提示速度、质量都非常好,还在代码内行内提供了一些预先配置好的 prompts 用来快速修复错误/重构/注释,功能上更加丰富。

Project

免息分期值多少钱

免息分期非常诱人,节省下来的现金流可以通过投资获取额外的收益,但到底免息分期相当于多少钱呢?希望这个工具可以帮助您理性消费。

Telegram

https://blog.jetbrains.com/go/2024/01/18/goland-2024-1-eap-program-and-roadmap/ Goland 2024.1 Beta 更新了,日志上明确提升了性能和 remote dev 稳定性。 今天使用 Gateway 连接了开发机新版的 Goland,整体流畅度相比 2023.3 确实明显提升。之前版本在切换文件或者打开 UI 组件的时候经常会有明显的掉帧,在新版上少了很多类似的情况。 确实可堪一用了,终于不需要使用 VSCode Remote 了。 不过性能开销似乎没啥提升,32c64g 的开发机日常是 20% CPU load + 90% 的内存占用。。。

Telegram

试着使用 GPT4 把博客的内容国际化了一下,半个月下来,Google 搜索展示量有了明显的上涨。 因为所有内容是富文本,甚至是 markdown 超集,想要翻译并保留格式必然要定义一些 DSL,这个时候就不得不依赖下 GPT4 较强的逻辑推理能力,保证输出的结果可靠性。 不过调试过程中,反复调整 prompt,GPT4 的开销太高了,有点吃不消。还是等后面 GPT4 turbo 放开使用了,考虑自动监控内容变更,自动更新翻译内容。

Telegram

最终还是自己整了一套 OpenTelemetry 系统,使用 Otelcol 统一收集上报数据,使用 Prometheus 存 metrics,Tempo 存 trace。最终所有数据在 Grafana 上统一查看,也可以在 Grafana 实现报警的能力。 考虑 PaaS(Railway) 已经提供了免费的日志存储,就不再自己维护了,只需要保证日志当中包含 trace id,方便关联追溯即可。 所有组件都只用 Docker 部署了单实例,除了 Prometheus 占用了内存比较高,整体开销不大,相比购买第三方的 SaaS 服务,比较合算。

Writing

放弃从 Next.js 迁移到 Astro.js

分享使用 Astro.js 从迁移到放弃的心路历程

Writing

Go 类型内嵌在反序列化中的妙用与陷阱

Go语言中的结构体嵌入的用法和技巧,包括替换字段类型和处理JSON反序列化。需要注意在处理嵌套结构体的JSON反序列化时的一些陷阱。

Telegram

https://www.recursive.design/ 太喜欢 Recursive 这款可变字体了。 作为 UI 字体,我最喜欢的一点是,固定 font-family(sans/mono)的情况下,调整字重,字体宽度不受影响。在前端开发的时候,如果我们 hover 的时候调整对应元素的 font-weight,往往会出现抖动,需要使用 shadow 来替换 font-weight 来实现相同的效果。如果使用 Recursive 就能很优雅地避免这个问题。 因为支持 monospace 的变种,目前我也使用 Recursive 作为我的代码编辑器的字体,非常好看。

Telegram

几周前,我给自己的服务加上构建通知能力:CI/CD完成后,用Telegram Bot给我通知。今天我把这个 bot 设置为 mute 了,因为往往是积压了很多未读消息,我都懒得看...... 其实是很奇怪的心理: - 完全不发通知吧,根本不知道部署状况 - 只发送部署失败的通知,没收到消息也不能保证肯定成功了,搞不好连 CI/CD 流程都没触发 - 全部都发吧,有效信息比例太低了,看都懒得看

Writing

Telegram 的富文本渲染机制浅析

对 Telegram 的 TDLib API 的分析,包括富文本数据的数据结构与渲染方案。

Telegram

忽然想到,使用类似 Protocol Buffers(protobuf)或者 Thrift 这样的 IDL 声明接口,往往允许修改字段名称,只要保证不修改字段类型和序号,保证数据结构内存结构一致,就不会出现客户端和服务器不一致而冲突的情况。 但如果通过 grpc-gateway 或者 Connect 这样的框架,基于 protobuf,来与前端通过 JSON 而非二进制数据做数据交互,就是另一种情况。在这种情况下,可以随便修改序号,但是绝不能修改字段名称。 如果同时兼容 JSON 和二进制(原生 grpc)两种数据传输,那么就意味着这个 IDL 上的一个字段也不能更改。本质上,这是由于两种模式使用不同的字段索引方式造成的。

Telegram

【新产品介绍】OpenObserve 是 Rust 开发的一站式 Logs, Metrics, Traces 可观测产品,去年该团队开发了 ElasticSearch 轻量级替代品 zincsearch 迅速获得 15000+ star,并获得 460 万美金种子轮融资,后来转型专注于新的可观测产品 ZincObserve,最近改名为 OpenObserve。 https://openobserve.ai/

Telegram

还是看看各种 analytics SaaS 吧。除了 Google Analytics,几乎所有类似的服务,价格都不算便宜,Vercel/Cloudflare 之类的都是 20刀一个月,单纯只是网站数据统计的话,感觉意义不是很大,毕竟流量不大,自建 umami 之类的一个月成本也就2刀以内。 对于我来说,更大的痛点其实是服务端的可观测性,自建一套 prometheus/Influxdb + grafana 维护起来蛮麻烦的。所以打算找个原生支持 OpenTelemetry 的 Analytics SaaS,我直接将前端后端数据都通过 OpenTelemetry 打通接入。 最最理想的状态,是能够把 log/metrics/trace/alert 全部依赖一个平台接入。 找了一圈,要不是价格很贵,要不功能不完善,要就不兼容 OpenTelemetry。 想想也是,这类数据统计一旦统计的数据维度多一点,很容易出现统计数据的流量是业务流量好几倍的放大现象。工作中也在维护一个统计服务,也是整个系统的成本怪兽。也能理解为什么各类数据统计 SaaS 这么贵。

Telegram

最近把自建的 umami 从 1.x 升级到 2.x。根据文档,顺利地升级了 postgres 当中的表结构和数据,但是 2.x 的实例起来之后,一直都无法读取数据库中的数据,看了眼日志,大概是 prisma 处理数据报错了。 无奈,尝试把旧数据清空,原来的报错倒是没了,但是网页上报的数据一直没有正确消费写入。 累了,也懒得回退到 1.x,不太想继续用 umami。

Telegram

最近工作上有一个需求,处理一批数据,需要各种展开分析统计数值,原始数据量非常庞大,笛卡尔积一下大概是每小时要处理 10^15 条数据。因为数据规模实在太大了,完全没法在线实时统计,只能离线慢慢算。 开个 Spark 定时调度任务,每小时跑一次上个小时的数据,单次计算上千核+几TB内存还要跑几十分钟。 作为后端开发,一直只实现各种实时计算,对于各种计算成本精打细算,很少接触离线数据分析。 哪里见过这种场景,一段 SQL 丢进去,就是无脑暴力跑,太震撼了。

Telegram

早上尝试在家通过 Surge 作为跳板访问公司内网,发现规则模式下怎么都访问不通。 发现所有请求都直接使用了 Final 的兜底规则,通过机场去访问了公司内网,那肯定是不通的呀,光 DNS 就没法成功(需要使用内网 DNS)。 研究了半天,发现原来是因为自己在内网规则前加了一个 IP-CIDR 规则,整体规则如下的: IP-CIDR,10.0.0.0/8,PROXY DOMAIN-SUFFIX,company.org,COMPANY FINAL,PROXY,dns-failed 根据 Surge 文档所说:在进行规则判定时,Surge 自上往下依次尝试匹配每条规则,如果遇到了一条 IP 类型的规则,那么 Surge 将进行 DNS 解析后再进行匹配。 1. 当处理内网请求的时候,先碰到了 IP-CIDR 规则,当场开始 DNS 查询域名的地址,但是内网 DNS 本地显然访问不通,最后解析失败。 2. 根据 dns-failed 规则使用了 FINAL 的 PROXY 策略,选择了使用机场兜底。 最后把 IP-CIDR 规则移到下方之后,就解决了问题。老实说这个设定确实蛮坑的......

Telegram

mac(尤其是 intel 的),在唤醒之后常常会碰到 kernal_task 跑满 CPU 的情况,猜测是得把缓存到磁盘的数据读回到内存中,期间会非常卡。 https://discussions.apple.com/thread/5497235 各种办法都试了,效果都不明显。现在找到一个不错的办法,就是开个终端,执行 caffeinate -s,只要我不中止这个进程,系统完全不会休眠,这样就避免了唤醒的问题。

Telegram

最终返璞归真,在 Github 上开了个仓库存了各种配置文件,clone 到本地手动 ln -s 创建软链接。 这类不是天天都要变动的配置文件,确实没有必要用 icloud 之类云盘实时同步。 分享下重写的 .zshrc,用在我的多个 macos/linux 环境下,使用 Github Action 从我的配置仓库当中自动同步到 Gist,https://gist.github.com/sorcererxw/238f7068c18ba148337f32f9a08d0dbd

Telegram

昨晚折腾了一晚上的 jetbrains gateway,想着用 goland 远程开发。 整体体验下来就是烂,各种功能和插件需要区分 Host 和 Client,有些插件需要两侧同时安装才能使用,心智负担很高;很多插件本身就是面向客户端模式设计的,在这种前后端分离模式下根本没法使用。 性能的话倒是可以接受,开个 golang 的 monorepo,8c16g 的开发机,索引的时候会打满 CPU,平峰期差不多占用 2c8g。 总的来说,我宁愿使用 neovim 来远程开发,各种体验至少是原生的。

Telegram

周末倒腾了一下 Surge5 新加入的 Ponte 组网能力。相比一直在使用的 Tailscale 有一个明显的优势,就是不需要自己搭建 DERP 中转服务器了,可以直接使用机场作为中转服务器。 我是用的香港节点作为中转,在公司访问家中mac延迟稳定低于 100ms。因为机场往往是不限速的,使用 VNC 开远程桌面也不需要压缩画质。 通过一些简单的规则就可以实现在外访问家中内网服务: HOME = select, DIRECT, DEVICE:mymac IP-CIDR,192.168.50.0/24,HOME 反过来,也可以在家直接通过公司的 mac 作为跳板访问公司内网,非常方便。

Telegram

之前使用 mackup 把 mac 上的各种配置文件备份到 icloud 了,今天发现 icloud 中的 mackup 目录被错误删除了,在 icloud 上使用文件恢复也找不到……然后 icloud 默默同步文件把本地版本也给删除了,各类配置都是软链接到 icloud 目录的,导致本地所有配置都没了 现在看着唯一一个还开着的加载了之前 .zshrc 的 zsh,再犹豫要不要放弃恢复重新配置一份 .zshrc,积累了几年的配置全都没了😩

Telegram

connect server 支持 HTTP GET 了,只需要设置幂等级别为无副作用,就会自动为对应 method 配置 GET router。 service ElizaService { rpc Say(stream SayRequest) returns (SayResponse) { option idempotency_level = NO_SIDE_EFFECTS; } } idempotency_level 是 protobuf 内置的 method 属性,分为 unknown/idempotent/no_side_effects,后两者都是幂等的意思。 在 RPC 场景中,只要是幂等就代表 Client 端可以安全地重试 RPC 调用,至于是否有副作用指导意义不强。 但是放到 http restful 接口上,GET 往往就等价于无副作用,以此判断是否支持 HTTP GET 还是比较合理且巧妙的。 https://github.com/bufbuild/connect-go/releases/tag/v1.7.0

Telegram

最近要在 Redis 上做一个超大 QPS 的指标统计功能。考虑到重试幂等,没法直接用 INCR 来累加。于是想用 Set 结构存储,用 SCARD 查总量。这就涉及到占用过大的存储空间的问题。然后就各种折腾,写了一堆代码逻辑来尽可能降低存储占用,还把 Redis 换成了磁盘大容量存储的类 Redis 存储。 刚才和 ChatGPT 讨论的时候,被指出可以使用 HyperLogLog。雀食 🙈。技术还是得常用常新,不用不复习太容易忘。

Telegram

发现自己各种后端服务部署有点混乱,在 Vercel、Railway、Digital Ocean 等 PaaS 上都有部署,对应了不一样的羊毛使用场景。但是发现服务间互相调用会非常麻烦,代码里面需要关心目标服务的具体位置,维护成本和心智负担都不小。 于是写了个“服务发现”机制。使用一个服务发现服务 Discovery Service,通过 Vercel、Railway、Digital Ocean 的 API,不断拉取部署相应平台上部署信息,并存储下来。然后每一个服务会定时从 Discovery 上获取全量的服务列表,然后根据服务的唯一标识映射获取对应的公网地址。这样以来只要保证在 PaaS 上部署服务并暴露公网,客户端就能通过服务名称直接访问。

Telegram

之前通过 DHCP,把全家的所有设备的网关指向软路由(openclash),从而实现翻墙。不过最近发现 homekit 的稳定性不太好,家居中枢经常掉线。想了一下大概是 openclash 连接代理服务器本身稳定性不够。 于是在路由器上通过 dnsmasq,调整了 DHCP 配置,只将部分设备的网关指向软路由。考虑 homekit 本身可能也有翻墙需要,故两个家居中枢,一个(homepod)留在了墙内,一个(apple tv)开启了翻墙。 这样一来,整体稳定多了。

Telegram

前几天对信用卡账单的时候,惊讶地发现上个月 MongoDB Atlas 托管数据库扣了将近 200 刀。可能是因为上个月部署了些 cronjob,对数据库用量比较大。但几个小服务产生这么高的消费还是不能接受的。 想着 MongoDB Atlas 是用不起了。但暂时找不到 MongoDB 托管的替代品,试着在 Railway 上起了台 MongoDB 托管实例。把老数据 dump 过去并重启了所有相关服务,完成迁移也就十分钟。 刚看了一眼 Railway 的 Usage 统计,根据每分钟的 CPU/MEM 的平均用量,预估了当月费用,一个月不超过 5 刀 🫠 (比根据读写次数计费划算多了)。 不过如之前所说,Railway 对数据库的可用性没有强的保证,也没有显式的数据备份解决方案。打算先用 Github Action 写个定时 dump 数据库保存到 S3 的脚本,临时先用着。

Telegram

停更几年的 Wikipedia 增强插件 Wikiwand 最近 更新了2.0版本 。除了更现代化的 UI 设计,还增加一个基于 GPT-3 的 TLDR 模式,假设读者是儿童来让 AI 总结词条。用了几周,刷Wikipedia堪称享受了。

Telegram

BFF 这个概念,宣传上要接管各种仅为前端服务的脏活累活,让业务服务专注运行逻辑。但是实践上 BFF 层又推崇尽可能薄。 往往会能看到两个极端。业务服务定义了一堆专为前端服务的 RPC 接口,BFF 沦为 API Gateway。或者是 BFF 包含了非常重的业务逻辑,业务服务沦为 CRUD 执行器。

Telegram

最近体验 railway.app ,试着部署了些服务,说一些感受: ⁃ 类似 Heroku,服务实例不会被销毁,不会出现冷启动的问题。 ⁃ 计费是按照 CPU 和内存用量+耗时来计算,每个月消费低于 $5 不收费。 ⁃ 不启用付费计划(绑定信用卡)的话,每个月也有 $5 的额度,但是会限制实例每月总在线时长 500 小时(21 天),也就是说想长期部署服务必须启用付费计划。 ⁃ 可以部署数据库 (PG、MySQL、Redis、MongoDB),还支持在前端访问和操作数据库。不过目前没有看到数据库扩容、备份等功能,感觉就是单纯的提供一个数据库容器实例,不适合用于生产。 ⁃ Railway 当中有 Project 的概念,一个 Project 可以有多套环境、部署多个服务/数据库,很像 K8S 的 Namespace,适合用来做业务隔离。 ⁃ 会自动识别项目中的 Dockerfile 构建镜像部署,构建速度也比较快。 ⁃ 和 Vercel 一样,不支持 VPC,也就是说如果做服务间调用,服务只能通过公网域名来互相访问,比较不安全。不过这个功能在 roadmap 中已经是 WIP 状态,可期。 ⁃ 不保留历史日志,需要依赖像 logtail 这类外部日志服务做日志存储。 ⁃ 不支持 cronjob,文档里给的解决方案是起一个实例自己调度…… 总的来说,对于个人开发来说,Railway 体验还可以。但毕竟是一家只有两年的创业公司,平台功能和文档建设还是不够完善。

Telegram

最新 Next.js13 appdir文档 中, Vercel 引入 Comments 组件,只需要登录 Vercel,就能在页面的任意位置评论。非常像 Figma 的评论系统,只不过把画布换成了网页。 Vercel 也将这个能力开发给了 Vercel 用户,所有 Preview Deployment(非主分支)可以直接开启。默认情况下,只有当前 Deployment 所属组织的成员才能评论,也可以开放权限到任意用户。 一旦发生评论,Vercel 会将评论同步到对应分支的 PR 下面,可以很自然地融入开发流程。 做一个这种模式 Disqus 服务,似乎非常有意思?

Telegram

最近需要在数据库存储一批复杂的配置文件,需要原子化更新配置的内部字段的能力。一开始打算用 MySQL,有两个方案: 1. 整个数据结构序列化后塞在一行的一个字段里面。更新的时候在开事务(上行锁)整个读出来更新好写回去。 2. 根据数据结构,老老实实建模,各种 list 表,relation 表,每一个字段都是一列……多数情况下不需要用事务就能单独更新内部字段。 前者省事,但是不优雅;后者足够教条,但太麻烦了。 最后,还是换成了用 MongoDB,整个配置作为 document 写到库里,想怎么原子更新子字段就 怎么更新。虽然 MongoDB 更新文档本质上也是单行事务,但局部更新的语义支持确实比 MySQL 优雅。

Telegram

https://vercel.com/analytics Vercel 收购了 Splitbee,把访客分析集成到了自家的 Analytics。对于个人项目来说也不需要专门去引入 Google Analytics 了。 一直想试试看 Splitbee,喜欢它的产品调性,现在省事了。

Telegram

正儿八经地用 Github Codespaces 写了一段时间的代码,把本地开发环境用 Github Dotfiles 配置了一遍。 不得不说体验非常不好,期间无数次压住 clone 代码到本地直接用 IDE 打开的念头。 一方面我非常不习惯使用 VSCode 开发,即便是 VSC 强项前端开发,我也觉得是不如 Goland 智能响应快的。其实也试过通过 Goland 直接 SSH 到 Codespaces 开发,但这就有点脱裤子放屁了。 另一方面是网络不够稳定。虽然大多数时候是稳定的,但一旦碰到连接中断,可能会发现本地变更代码压根没法 commit,刷新一下网页,代码可能直接丢了。开发的时候无时无刻都会焦虑网络问题。 也好,彻底打消了购入 iPad Pro 念头。

Telegram

最近实现了一个更加优雅的方案,就是将所有网页上面的 notion block (img/video/...)的 src 指向 /api/resource/{block-id} ,这个接口每次被请求的时候都会请求 Notion API 去获取最新的 S3 链接,最后返回客户端 HTTP 307 重定向到资源地址,并使用 Cache-Control 保证最近一段时间内都不需要重新获取。 这样一来,每一次浏览器都能跳转到未过期的资源链接,就不再需要任何外部 cronjob 去主动触发刷新了。

Telegram

Cloudflare 发布消息队列内测 从Worker开始,Cloudflare为帮助开发者构建大型、可靠的应用程序,不断开发所需基础设施,当遇到不需要立即获得结果,但并发量又需要进行控制时,差不多就需要消息队列上场了 限制 队列个数 10个/每账号 消息大小 ≤128KB 消息重试次数 ≤100次 批量提交消息数 ≤100条 批处理等待时间 ≤30秒 消息吞吐量 ≤100条/每秒 *Cloudflare Queues 与Cloudflare Workers集成,收发消息目前必须使用 Worker,后续将支持其它API接口 *部分限制可能会在后续测试调整、放宽或取消 定价 按每月总操作次数收费;每写入、读取或删除 64 KB 的数据,就计为一次操作,没有带宽流量费用 每月前一百万次操作免费,后续每百万次操作 0.4$ 完整传递一条消息需要 3 次操作:1 次写入、1 次读取和 1 次删除 月账单估算公式为: (消息总数-1000000)*3*/1000000*0.4$ *在内测期间试用免费 >>申请内测 🗂文档 Cloudflare Queues Cloudflare Queues: globally distributed queues without the egress fees #消息队列 Via @Cloudflare_CN

Telegram

最近一个体会是个人玩票项目 side project,尽量用一两个简单的工具完成核心功能就好了。千万不要引入一堆组件、工具链、外部依赖去达成一些炫酷的能力,产品为技术让一下步,鬼知道三个月后还能不能跑起来。

Telegram

https://hnpredictions.github.io/ 通过爬虫抓取了 hacker news 上所有 prediction 发言。算是某种意义上的“自动挖坟”。得益于 HN 的高质量用户群体,看看几年前用户对科技政治经济的预测,还是蛮有意思的。

Telegram

https://www.jetbrains.com/idea/whatsnew/ Jetbrains 全家桶 2022.2 发了,更新了一下 Goland,新功能乏善可陈,本期最大的更新应该是 runtime 从 jre11 切换到 jre17 了,得益于使用了 macOS Metal API,体感上确实流畅了一点。

Telegram

我有一个服务,反向代理了机场的Clash/Surge规则,并在输出的时候在其中加入了一些自定义的 proxy/rule(比如内网跳板、开发机、屏蔽host)。所有设备上的客户端只需要订阅这个反代地址,就能在所有设备上同步相同的配置。 对于我个人来说这还是非常实用的,不知道如果有这么一个 SaaS 服务会不会有受众?

Telegram

最近发现服务器用量忽然上涨,查了半天发现 Redis 缓存逻辑根本没执行。 查了一下 Redis,惊讶的发现 Redis 里面居然是空的。尝试 Set 一个不会过期的值过了一会儿就消失了。 猜测是因为 Redis 没设置密码,直接在公网上被扫描到了,然后被执行了 flushall。 因为 Redis 里面就是一些计算缓存,不是很重要所以直接都没做鉴权。看来无论如何还是不能忘记设置密码。

Telegram

无意当中看到这个 issue。当我们使用 Notion 作为 CMS 搭建网站的时候,绕不开 Notion 的 S3 图片链接会过期的问题。因为图片会过期,静态生成的网页常常会加载不出图片。哪怕现在去看 Railway blog 依然可以发现有些图片加载不出来。 最简单的避免这个问题方法就是不要将图片 host 在 Notion 上,而是使用外链塞到 Notion 当中,但是比较麻烦,需要先上传图床再做插入。 Issue 帖主选择放弃 SSG,使用 SSR 渲染,可以保证每次下发的图片链接都是最新的,这肯定会导致网页加载慢(不能套 CDN,套了 CDN 就无法保证页面最新了)。 我的主页也是使用 Notion 搭建,但是在服务端做了非常多的预渲染工作,SSR 肯定是无法接受的。我目前的方案是使用 cronjob 拉取网站的 sitemap,使用 Next.js 的 revalidate 功能定期重新生成每一个页面,并保证新渲染出的页面被 Vercel 的 CDN 缓存下来。非常粗暴的方案,但目前来看是能正常工作,前端加载速度也非常快。 不过我还有另外一个未验证的办法:既然我们为了方便,不可避免地直接将图片 host 在 Notion 上。那么我们可以通过 Notion API 定期扫描页面,将 host 在 Notion 上的图片下载下来上传到图床,并替换原图片。虽然看起来在源头上解决了问题,不过似乎也不太省事。

Telegram

自己的一些服务用需要 redis,直接用了 upstash,一开始以为每天 10k 的 request quota 妥妥够用,没想到放开了用分分钟超额。 最后还是乖乖地在自己的服务器上跑了一个 redis 容器,只作缓存,稳定性低一点,数据丢就丢吧。

Telegram

一年一度地重构了一遍我基于 Notion 搭建的 个人网站, 从使用 Notion 前端私有接口切换到 Notion 的开放接口, 可以尽量避免接口发生 Breaking Change. Notion 的私有接口经常发生变动导致我需要重新适配, 非常恼人. 另外, Notion 接口当中很多 Block 类型字段不完整或者不满足定制化的前端渲染需要, 比如: - 部分类型 Block 需要二次查询子节点 - 代码块需要异步渲染高亮 - 多媒体文件需要额外多鉴权 - 需要异步生成 LQIP - bookmark 类型不包含 opengraph 信息 - 等等…… 放弃了在前端直接使用 Notion SDK 提供的数据结构, 而是使用 Protobuf 自定义一套数据结构, 并搭建了一个 BFF 服务来做数据聚合, 把所有需要异步完成的工作全在服务端一次性完成. 这样只需要在 SSG 的时候拉取数据不需要在端上额外计算就能渲染出页面, 无论是对于 SEO 还是性能都能带来提升. (提前优化爱好者就是我本人了

Telegram

https://developer.chrome.com/blog/auto-dark-theme/ 原来 Chrome 已经内建了自动夜间模式了, 目测在不久的将来会向普通用户开放。 测试了一下,总体效果不错,相比 Dark Reader 还差一点。 这一改动估计能够让不少设计师和开发者脱离维护 Dark Mode 的苦海,只需要对部分元素定制深色配色,其他全部交给算法就好了。 之后个人项目的前端页面,也不打算花心思为 Dark Mode 定制 Palette 了(面向未来编程😁

Telegram

使用 Encore 的时候, 使用 Google 登录给了一个提示告诉我当前邮箱有另一个账号在使用, 可以选择合并或者另开账号. 才想起原来一年前我就用 Github 注册过 encore 了呀. 个人认为体验非常好, 每次登录一个服务的时候, 如果这个网站提供了多个第三方登录方式, 如 Google / Github / Twitter 等, 我常常会非常困惑, 忘了之前用的是哪个方式, 担心选错了会创建出一个无用的账号. Encore 的做法避免了这种情况, 但也不阻止你另开账号. 技术上实现猜测并不难: 在用户表上存下用户不同平台的 open id (唯一索引), 以及相应的 email (非唯一索引), 在用户注册的时候都拿用户邮箱去检索比对. 我在个人项目当中去对接第三方登录的时候, 为了精简权限 (第三方登录流程中, 获取用户邮箱往往是需要额外权限的) 和数据库表设计, 往往只会存下 open id, 但在未来扩展其他登录方式的时候, 就失去了账号聚合的可能性了.

Telegram

平时预览 JSON 我一般使用命令行工具 jless (类似 jq, 但能实现折叠) curl https://example.com/demo.json | jless 常见的场景是从 Chrome DevTool 当中拷贝 curl 出来调用一下并预览, 所以这个时候直接使用 jsonhero 并不方便 所以我写了一个类似 jq 的命令行工具 https://github.com/sorcererxw/jsonhero 来实现将 JSON 输出到 jsonhero 上查看 go install github.com/sorcererxw/jsonhero@latest curl https://example.com/demo.json | jsonhero

Telegram

在 Product Hunt 发现个神器 jsonhero, 可以结构化地查看 JSON 内容, 甚至对于一些特殊格式的字符串定制了相应的视图: ⁃ 预览 URL 内容 (多媒体可以直接播放, JSON 可以进一步探查) ⁃ 时间字段 (ISO8601) 可以展示日历 ⁃ RGB Hex 可以预览颜色 ⁃ 内嵌的 JSON 字符串也可以结构化预览 (这个最实用!) 他们也刚刚推出了 Chrome 插件, 在 JSON 数据的页面 (当前页面的 URL 的 content-type 为 application/json)上, 点击插件就能跳转到 jsonhero 上查看

Telegram

https://buf.build/blog/connect-a-better-grpc Protobuf 管理工具 Buf 团队发布名为 Connect 的 RPC 套件. 他们罗列了一些 gRPC 的问题: ⁃ 过于复杂, 难以调试, 而且庞大的代码库容易出现漏洞 ⁃ 不使用 net/http 标准库 ⁃ 不支持浏览器 而 Connect 是在 gRPC 的基础上, 对其进行优化, 一些特性: ⁃ 精简代码, 包括生成的代码也更加可读 ⁃ 使用 net/http 标准库, 兼容性更好 ⁃ 支持 gRPC/gRPC-Web/Connect 三种协议 ⁃ 只支持 HTTP POST 方法, 同时支持 HTTP/1.1 和 HTTP/2, 同时支持 pb 和 json 两种数据格式 ⁃ 支持完整的 gRPC 协议, 包括 server reflectionhealth checks. 相比 Twitch 家的 twirp, Connect 还是兼容了 gRPC 协议, 而 twirp 更像是一套基于 Protobuf generator 的 JSON-RPC. 看起来 Connect 确实是 “A better gRPC”, 既能兼顾高性能的场景, 也能对受限的环境(浏览器/调试)做 fallback.

Telegram

工作中大量遇到的情况: 用着 Protobuf/Thrift/Golang 等各种强类型工具, 却又为了灵(tou)活(lan), 把各种字段都包在 object 里面序列化成字符串来传递. 为了解析这个 object 又写了各种 util 去提取里面的值, 真是迷惑行为.

Telegram

这段时间 Bionic Reading 这个概念又火了一把, 猜测原因是有团队在 HN 上分享了他们制作的一款名为 Jiffy Reader 的 Bionic Reading Chrome Extension. https://news.ycombinator.com/item?id=31475420 最早接触 Bionic Reading 是在 Reeder 上, 个人认为原理大概如此: 按比例将每个单词开头的几个字母加粗加黑, 以让眼睛能够快速地在单词间定位, 提高效率避免走神, 对于英文文章阅读确实效果不错. 不过 Jiffy Reader 似乎尚未发布, 在 Chrome 商店上找到另一款 Bionic Reading 的插件, 体验还是不错的, 可以自定义高亮字母的字重和比例, 推荐. https://chrome.google.com/webstore/detail/bionic-reading-digest-pas/lbmambbnglofgbcaphmokiadbfdicddj/related

Telegram

刚在 HN 上看到的 https://indigostack.app/ 一键在本地配置开发环境, 包括反向代理配置 SSL/数据库等, 确实能节省不少工作. 界面上将所有组件展示为机架上的一个主机, 也很有意思. 目前测试了一下, 发现软件包非常大有 1.6GB, 猜测是将所有依赖软件都打包进来了. 另外由于还未正式发布, 还是存在 BUG, 不能用于实际生产.

Telegram

#golang 据我所见,字节的 Go 后端是彻底 polyrepo,一个仓库只会是一个服务,多个服务的公共逻辑会拆成各种包来复用。在我看来是不如 monorepo 来得便利高效的,但也不否认 polyrepo 可以简化权限控制、CI 等各种基建工作。没有绝对的正确选择,这取决不同组织架构。 如果选择 polyrepo,日常开发的时候往往会出现一个需求需要改动多个 repo。如果存在 go mod 依赖,还需要先将依赖 push 到仓库,再在调用方仓库通过 git commit hash 拉新的版本。可以算是比较麻烦的了。 好在 Go 1.18 终于加入了workspace 功能,可以通过 go.work 在本地直接将某一个包指向另一个目录,本地改动代码另一边马上就能调用了,大大降低了跨仓库开发的麻烦。 . └── gitlab/ ├── biz_1/ │ ├── svc_1/ │ │ └── go.mod │ └── svc_2/ │ └── go.mod ├── biz_2/ │ └── svc_3/ │ └── go.mod ├── common/ │ ├── pkg_1/ │ │ └── go.mod │ └── pkg_2/ │ └── go.mod └── go.work 这样一来,只需要用 IDE 打开整个代码根目录并配置好 go.work,立马就能获得与 monorepo 几乎一样的开发体验!

Telegram

虽然发帖公开展示IP地址这个功能本身不值得大惊小怪,但是出发点还是有点令人不适。 不清楚未来会不会蔓延到所有平台,给代理加上了规则也算一种抗议了。

Telegram

HTML embed 是一个非常有意思的功能,它允许用户将某一个动态内嵌到任意第三方网站上展示。 为了方便访客查看,源网站必须要让 embed 资源支持匿名访问。这简直就是爬虫小子的天堂。只需要通过动态 ID 推断出 embed URL 就能爬到动态内容。 恰恰在海外的互联网生态当中,embed 是一个重要的流量入口,很多网站都会提供这样的功能。 反爬如 Instagram 也能够通过这个方式爬取动态内容。 当然这也不是不可绕过。比如 Linkedin 就对 embed ID 和动态 ID 做了区隔。用户只有在 Linkedin 端内才能通过动态 ID 获取 embed URL,这样就能避免爬虫大规模的爬取数据了。

Telegram

https://danpetrov.xyz/programming/2021/12/30/telegram-google-translate.html 这一篇文章还挺有意思的,讲的是 Telegram 引入基于 Google Translate 翻译功能,但是使用 私有 API 来薅 Google 羊毛。 这个 API 是用来给 Chrome 浏览器实现文本翻译的,免费提供给用户使用,自然是可以匿名访问的。调用方只需要使用各种方式模拟出一个请求,欺骗 Google 让其认为这是一个来自普通用户的请求。

Telegram

因为 Go 的 error 不带错误栈,如果希望追溯错误来源,原生的方法就是每一次 error 抛出的配上一段 message 来 wrap。 因为嫌弃这种做法太麻烦了,一直都使用 pkg/errors 来在 error 当中封装原始 error 的运行栈。但是这不得不让我在最终的错误收集、日志输出上做定制以实现监控。 现在好了,直接让 Copilot 生成 wrap message 就好了。 Copilot 让“大道至简”变得真的简单易用。

Telegram

对 gRPC-web 祛魅了,gRPC-web 所有请求都使用 POST 发送,导致所有读请求都无法被浏览器/CDN 缓存,对于性能来说还是有比较大的影响的。 参考 https://github.com/grpc/grpc/issues/7945 目前看来在 client 端做一层封装,识别请求体并做缓存可以缓解,但毕竟不是 HTTP 协议的原生实现,并不优雅。 但是,基于 IDL 生成 Client 和 Server Stub 实在是太爽了,目前来看还是会继续使用 gRPC web 的。

Telegram

最近字节的汽水音乐发布了,想体验了一下。打算先跑个脚本把在 Spotify 上的歌单同步一份过去。 不同于 Moo 只支持微信登录,汽水音乐提供了手机号登录的方式,这就给了通过脚本获取 token 机会。 尝试用 Proxyman 抓一下包看看各个接口详情,发现一启动 MITM,汽水就没法正常工作了。猜测是客户端启用了SSL pinning,禁止了中间人攻击。 经过一番折腾,终于绕过了 SSL pinning。尝试去抓登录接口,发现请求参数里面部分关键字段被加密了… 虽然客户端加密也是绝对能破解的,但实在是太折腾了,还是放弃了。

Telegram

体验了 arctype,又是一个“协作+X”思路的基础工具。 作为一个本地 SQL Client,素质还是非常不错的,相比 DataGrip 响应速度快,相比Sequel Ace 界面更好看。 另外,arctype 还支持直接连接 PlanetScale 数据库(不需要本地启端口转发),对于 PlanetScale 用户(包括我)非常友好。

Telegram

苦于 Vercel Serverless 函数上使用 ffmpeg 麻烦: - 无法预装 ffmpeg(配置 lambda layer 感觉很麻烦) - 限制编译产物体积上限,压缩后 (tar.gz) 需要控制在 50MB 以内 Node 当中可以使用 ffmpeg-static,不过对应到 Go 并没有好的方案。 于是最近封装了一个库 github.com/go-ffstatic/ffstatic 。类似 ffmpeg-static 的方案———包含完整的 ffmpeg 可执行文件在库内。不过,我为了使用更简单,直接将 ffmpeg 整个 embed 到 Go 编译产物当中,启动的时候再把它们导出到 tmp 目录中。 不过目前还是有点小问题,ffmpeg 4.x 的 x64 版本的 ffmpeg 和 ffprobe 都有 70+MB,一起封装起来压缩完依然有 50+MB,超过了 Vercel 的限制。 不太可能自己去编译个精简的 ffmpeg 出来,目前考虑使用 ffmpeg 3.x 版本来降低体积。另外,也可以考虑通过编译参数来选择是否打包 ffprobe。

Telegram

最近把梅林路由器的翻墙代理从 fancyss 切换到了 MerlinClash,不但稳定性提升了非常多,还支持使用 Clash 规则了,强推! https://t.me/merlinclashcat

Telegram

研究了一下 github.com/samber/lo 这个 Go 泛型工具库,看到了这段代码……可以说有点魔怔了,这就是为什么之前这么多人反对给 Go 加入泛型。

Writing

使用 gRPC 与前端交互

使用 gRPC 与前端交互。gRPC-Gateway 适用于同时支持 rest 和 grpc 两套接口,使既有系统可以从 rest 平滑迁移到 grpc;gRPC-Web 适用于前后端直接使用 gRPC 协议交互,为 HTTP/1.x 提供支持。支持 Unary 和 Server Streaming,但不支持 Bi-directional Streaming 和 Client Streaming。

Writing

服务端实时"动画"渲染

在本文中,作者分享了一种在网页上实时更新一部分数据的方法:使用 multipart/X-Mixed-Replace 格式来渲染 MJPEG 图片。作者通过实现服务端渲染 Game of Life 的服务 来展示这种方法的可行性。

Writing

在生产环境使用 gRPC

本文总结了在生产环境使用 gRPC 的过程,包括使用 gRPC-Gateway 兼容 HTTP/JSON 接口、定义 ProtoBuf RPC 接口映射、挂载 gRPC-Gateway、为前端提供接口等。同时也提到了一些可能遇到的陷阱,例如多态类型和空值处理。

Project

imgggg

Capture and share anything as imagggge~

Writing

自定义即刻 Yellow Page 域名

使用 Cloudflare Worker 实现即刻 Yellow Page 的自定义域名,让你享受到自己的成就感。这个过程其实是一个通用的使用 Cloudflare Worker 实现反向代理的流程。

Writing

尝鲜 Go1.18

了解如何安装 Go1.18beta1 以及如何解决 vscode 无法解析包含泛型的代码的问题。

Writing

思考 ProtoBuf 中的可选与必选字段

ProtoBuf 中的可选与必选字段,尤其是 optional 关键字的重新引入,对于扩展性的考虑和类型安全的保障带来了哪些变化?本文总结了使用 TypeScript 和 Go 的 gRPC 做的一些实验,提出了可选字段的两种实现方法。通过对比,可以更好地理解 optional 的作用和意义。

Writing

对博客网页加载体积的一点优化

本文介绍了对博客网页加载体积进行优化的方法,包括对 Syntax Highlighter、lodash 和 Chakra UI 的优化,以及如何控制 NEXT_DATA 的大小。通过这些优化,网页的体积得到了明显的降低,首次加载网页的 JS 体积从 200+KB 降低到 70+KB。

Writing

理解 Go singleflight 中的异常处理

理解 Go singleflight 中的异常处理,介绍了 Go 的 singleflight 库的使用方法及其异常处理方式。

Writing

深入理解 Go Comparable Type

本文主要介绍了 Go 语言中的 Comparable 类型,包括 Go 内置类型的比较规则、reflect 包中的实现方式以及相关陷阱和应用。文章指出,除了 Map、Slice 和 Func 之外,Go 中的大多数类型都是 Comparable 的,其中 Struct 和 Array 得看成员类型的支持。为避免相关问题,建议使用无法被伪造的指针类型或 Struct 类型作为 Context 的 Key。

Writing

Go sync.Once 原理

了解 Go 中 sync.Once 的工作原理。通过 atomic 和 Mutex 实现双检锁单例模式,确保一段任务只会执行一次。

Writing

gRPC 与『面向扩展编程』

本文探讨了如何通过 gRPC 实现向后兼容和可扩展性,包括一切字段皆可选、UnimplementedServer 的使用、输入输出必须为结构体、每个 RPC 专属的输入输出类型等。文章旨在帮助我们创建更易于维护和扩展的接口。

Writing

Go 的 String Interning

介绍 Go 的 String Interning 技术,可以在特定场景下降低内存占用,提高性能。使用 String Interning 的技巧已被广泛使用,如 easyjson 可以在反序列化时引入 String Interning。

Writing

在 Vercel 优雅地搭建 Go 微服务

本文介绍了如何在 Vercel 上搭建 Go 微服务,包括编写代码、自定义路由、Monorepo、RPC、定时任务、日志监控、数据库和 Integrations 等。相比于自建 K8S 集群或 AWS Lambda,使用 Vercel 的云函数可以降低很多的维护成本,但需要注意 Vercel 的功能有限。

Project

Figshot

Dynamically convert Figma frames to image links, insert them into websites, articles, and anywhere else, and sync automatically.

Writing

Server-Side Events: 简单高效的服务端推送

Server-Side Events 是一种简单高效的服务端推送机制,比传统轮询和长轮询更实时,网络开销更小,使用 HTTP 实现,对于服务端来说实现更为简单轻量。适合用于前端展示的消息订阅。

Writing

Go Echo 如何正确地处理错误

本文介绍了在 Go Echo 中正确处理错误的方法,涉及到了 Echo 中 error 的处理流程、HTTPErrorHandler 和 Error Handle Middleware 的区别、以及 middleware 的顺序等问题。文章详细阐述了如何避免错误导致的 HTTP/500 错误,确保最终响应能符合预期,同时提供了一些建议,如何正确使用 middleware。

Writing

Golang 在即刻后端的实践

本文介绍了即刻后端服务重构的过程和实践,以及重构后的成果和方案。通过 Go 语言的优点和即刻后端服务的优化,新版服务的开销得到了显著降低。文章还介绍了仓库结构、持续集成与构建的实践经验。

Writing

Got a New Keyboard

介绍了作者购买新键盘的经历,比较了几个备选方案,最终选择了 Niz 66。该键盘支持蓝牙连接和双模,键位丰富,静音,手感好。总结:购买新键盘。

Writing

Use GSuite Like a PRO

使用 Google App Script 做更多事情。Google App Script 是一种基于 JavaScript 的编程语言,可以轻松访问 G Suite 应用程序的 API。本文介绍了 Google App Script 的优缺点以及如何使用它来构建更强大的应用程序。

Writing

对 Go 编程哲学的一点理解

Go 编程哲学:显式错误、严格类型、简洁源码、无泛型、低心智负担。

Writing

Go 中 struct 初始化

本文讲解了 Go 语言中 struct 的初始化方式、多种数据类型和结构体组合方式等问题。文章总结了不同的初始化方式及其区别,介绍了内嵌结构体的初始化以及 slice、map、channel 等需要 make 的类型的初始化方式。

Writing

MongoDB 读写分离踩坑

MongoDB 读写分离踩坑。主从复制导致写操作不实时返回,解决方案包括 Write Concern 机制等。详见文章。

Writing

PlantUML as a document

使用 PlantUML 在 Markdown 文档中绘制 UML 图表。PlantUML 是一种依赖于 DSL 进行 UML 图表绘制的工具。该工具支持许多类型的图表,可以在中文文档中找到相关资料。可以使用 PlantUML 服务器渲染出图片提供给前端显示。该工具与代码同步使用 Git 进行管理,非常适合工程文档的管理。

Writing

从 Google passports 换到 1Password

从 Google Passwords 切换到 1Password,解决了密码管理的痛点,同时也带来了更多功能。不过删除旧密码时遇到了问题,只能通过脚本一条一条删除。

Writing

JWT 的一些思考

JWT的优点和缺点,以及设计思路和实现方式,包括AccessToken+RefreshToken的组合,AccessToken和RefreshToken应该包含哪些信息,以及是否需要使用不同KeyPair。同时,讨论了如何对一组Token进行拉黑和实现零延迟地强制下线。

Writing

使用 dotfiles 管理 Windows

使用 dotfiles 管理 Windows,将配置流程数据化,通过 Git 和软链接实现快速备份和迁移设备。推荐使用 dotfiles 管理 PowerShell 样式文件、启动脚本、Telegram 字体配置文件、VSCode 配置文件等。附上我的 dotfiles 仓库地址。

Writing

个人项目架构的思考

个人项目架构的思考:在微服务和前后端分离流行的当下,为什么要这么做?对于个人开发来说,本身就没有分工难题,这么做反而给我带来了很多不必要的麻烦。对于简单的个人项目,如果前端只是后端数据基础的CRUD展示,也没有必要进行分离。将整个系统进行“压缩”之后,我可以一条命令就将整个项目打包成 docker 镜像,或者直接就在 AppEngine 上线,不必再为后续的维护头疼。

Writing

优雅地分享即刻消息给 Telegram 好友

优雅地分享即刻消息给 Telegram 好友。使用 Jikeview Bot 解析即刻链接,转换成对 Telegram 用户最友好的图文内容,支持动图、视频和多图。快来体验!

Writing

Surface Go 上手

"Surface Go 上手"是一篇介绍 Surface Go 使用体验的文章,主要关注于其轻便和续航等优点,但是也提到了触屏体验和性能方面的问题。文章介绍了选购经验和使用技巧,并总结了 Surface Go 适合需要一台便携设备用于办公和学习的用户。

Writing

尝试实时渲染“截图“

本文介绍了如何使用 HTML 和 CSS 在文章中实时渲染截图。文章中详细讲解了如何渲染 HTML 和 CSS,包括行内样式、<style> 标签和 CSS 文件加载,以及实例演示。

Writing

使用 Notion 搭建博客

使用 Notion 搭建博客,解决了其他平台上的问题,包括无法自定义域名、体验不好、静态博客麻烦等等。Notion 的 API 是半公开的,可以通过 API 来创建网页,将 Notion 当作和 Wordpress 一样的 CMS 来管理博客。通过后端渲染和 CDN 服务提高了页面加载速度,同时使用了 Cloudflare 的服务提高 SEO 效率。配置 Table Page,建立相应的列和视图,控制文章内容和展示。最终实现了使用 Notion 搭建博客的目标。

Writing

谈谈「重构」

介绍重构的理念,如何平时重构代码。文章触动较大的是作者对于重构的理念,强调重构是一个大工程,但应该将这个工程穿插在日常开发当中,保证未来系统的强健。同时,文章提到开发过程中需要分为两个方面,功能开发和代码重构,两者不能同时进行。这一点很重要,因为两者的目标不同,同时进行会导致代码成为一团乱麻。

Writing

记一次 Google Cloud 封禁

Google Cloud 封禁的经历,使用 Docker Image 时,授权文件被公开,项目被停用。需要注意管理授权文件的方式和将私钥放在项目目录当中的风险。

Writing

几个 2018 年喜欢的产品

几个 2018 年喜欢的产品:Windows Subsystem Linux 和 Notion。

Writing

Bitbucket Pipeline + Docker + Gradle 自动部署实践

Bitbucket Pipeline + Docker + Gradle 自动部署实践。使用 Bitbucket Pipeline 服务实现持续集成,并将项目打包成 docker 镜像,通过拉取最新的镜像来进行更新代码。使用 Gradle Docker Build 处理 Docker 打包,使用 GCR 托管镜像,使用 vps 实例部署。通过编写 Pipeline 脚本实现自动部署。

Writing

浙大路由器配置指南

浙大路由器配置指南,介绍了在校园网环境下使用路由器的方法。包括使用 Linux 客户端和模拟登录两种方式,以及一个校网验证脚本的使用方法。

Writing

Github Pages 反向代理跨域实践

使用 nginx 反向代理和 letsencrypt 进行配置,实现 Github Pages 上web app 的跨域问题。通过将前端流量转发到 nginx 服务器,然后再通过 nginx 反向代理将前端代理到 Github Pages,api 代理到后端服务器。同时,通过 letsencrypt 的 certbot 进行配置,实现 Https 跳转。

Writing

记一次 GitHub Pages 部署

这篇文章主要介绍了作者如何将自己使用React写的小玩具部署到Github Pages上。文章详细介绍了部署过程中遇到的问题以及解决方法,对于需要将自己的项目部署到Github Pages上的开发者来说,非常实用。

Writing

RxActivityResult 原理浅析

本文介绍了 RxActivityResult 库的原理和源码分析,通过启动一个代理 Activity 来实现两个 Activity 之间的数据交互。通过打包 Intent 和回调接口,启动 HolderActivity 并将 Request 提供给它,然后 HolderActivity 启动目标 Activity 并接受返回结果,最后通过回调将结果传递给订阅者。另外,文章也提到了类似的库 RxPermissions。

Project

Sorcery Icon Pack

An icon pack with thousands of Material-Design icons for Android. The first app can replace Pixel Launcher icon with Root and system icon with Xposed.

Project

Notion Blog

Use Notion as my blog CMS.

Project

WHAT THE JIKE!

Working In Progress...

Project

ilove.works

A simple web app to flash the slogans of hard work.

Project

Intent Interceptor

Use Xposed to intercept all intent in system.

Project

Jikeview

Telegram bot that converts Jike posts to Telegram messages.