IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

后端

共 1964 篇文章

IT 2026-06-03 09:03:23 / 累计浏览 8

Gin + go:embed 实现静态资源嵌入

本文介绍了如何利用 Go 1.16 引入的 `go:embed` 特性,将前端静态资源文件在编译时嵌入 Go 程序,从而构建单文件部署的 Web 服务。通过声明 `//go:embed` 指令,可将指定目录或文件打包为 `embed.FS` 虚拟文件系统。结合 Gin 框架,开发者可以使用 `http.FS()` 包装该文件系统,并通过 `StaticFS` 或 `NoRoute` 方法将其作为静态资源提供。特别是利用 `NoRoute` 回调,可以在未匹配到 API 路由时自动将请求转发至静态文件服务器,从而省略路径前缀,实现 API 接口与静态资源的统一部署。这种方式简化了发布流程,并避免了跨域问题。

本机暂存
IT 2026-06-03 09:03:23 / 累计浏览 4

go:embed 嵌入 HTTPS 证书

这是一篇关于使用Go语言`go:embed`功能将HTTPS证书嵌入可执行文件的技术教程。文章首先阐述了为Web服务启用HTTPS的必要性,即使在内网环境中,以保障数据传输安全、完整性并规避浏览器限制。针对内网无域名的场景,文章重点介绍了使用`openssl`生成自签名证书的具体步骤。核心部分详细演示了如何利用`go:embed`指令在编译时将证书文件(`.crt`与`.key`或合并后的`.pem`)嵌入程序变量,并解决Gin框架无法直接加载嵌入式证书的问题。通过自定义`http.Server`的`TLSConfig`配置,成功加载字节形式的证书,最终实现了将静态资源与HTTPS证书一并打包、开箱即用的Gin HTTPS服务。教程明确了`RunTLS`方法不适用于此场景,并展示了最终效果。

本机暂存
IT 2026-06-03 09:03:23 / 累计浏览 5

Go Server HTTP 302 跳转 HTTPS

这篇笔记从Go服务器部署HTTPS后的实际问题切入,作者遇到了HTTP 400错误——当用户直接输入IP地址访问时,浏览器自动补充HTTP协议,与HTTPS服务冲突,导致服务器返回“Client sent an HTTP request to an HTTPS server”。根因在于Go官方没有内置HTTP到HTTPS的重定向功能,而手动修改协议方式不够便捷。 作者最初尝试在Gin中间件中检测TLS报文,但发现多次请求后识别不可靠。后来发现开源库 `hlfhr`,它通过劫持 `net.Conn` 实现自动重定向。具体方案是加载证书后,用 `hlfhr.New` 创建服务器并监听端口,实现访问HTTP时自动302跳转HTTPS。作者还fork项目调整状态码为307,避免POST请求被误转为GET,提升兼容性。 效果上,改造后用户访问HTTP地址会自动跳转至HTTPS,解决了体验痛点。对于Go开发者,这提供了一个轻量级的实现思路。

本机暂存
IT 2026-06-03 09:03:23 / 累计浏览 8

Web App: 从 HTML 到 Jamstack

本文梳理了Web应用技术从早期静态页面到现代Jamstack架构的演进脉络。其发展呈现出螺旋上升的趋势:起始于以PHP、JSP为代表的后端直出HTML模板阶段;随后,Ajax与Flash催生了富互联网应用,带来了初步的客户端交互;HTML5标准的成熟与SPA框架的普及,则使Web应用在交互体验上大幅逼近原生客户端,并推动了前后端分离的工程化模式。尽管SPA优化了用户体验,但其在SEO和初始加载方面存在局限,这促使了服务端渲染方案的回归与增强。最终,技术生态收敛于以JavaScript为核心的Jamstack架构,它将前端渲染(Markup)、业务逻辑(JavaScript)与数据获取(API)解耦,并通过SSR/SSG及边缘计算等技术,在提供动态应用体验的同时,重新强调了文档的开放性与可索引性。这标志着Web开发在新的技术层面上,对早期简洁的“生成HTML”模式的高级回归与统一。

本机暂存
IT 2026-05-23 20:34:36 / 累计浏览 119

让 AI 把我的 PHP 博客重写成 Go

作者尝试将一个运行近20年的古老PHP博客系统重构为Go语言。项目启用了Claude Code的Superpowers插件,通过结构化问答明确了技术选型:采用Go的Gin框架、GORM作为ORM,并构建Vue 3 SPA前端,保持与原MySQL数据库100%兼容。AI助手在确认需求后,自动生成了包含项目结构、API设计等详细规划文档,并利用子代理驱动开发模式执行了约22个开发任务,最终生成一个约35MB的单文件可执行程序,集成了前端SPA。 实现过程并非一帆风顺,主要挑战在于处理历史遗留数据。最复杂的是对UBB标记语法的解析与渲染,因内容已含HTML实体转义且标签存在嵌套,作者编写了34个测试用例才覆盖所有边界情况。此外,需为三代不同的旧URL格式实现301重定向以保持外链有效,并调整了附件链接的解析逻辑以适配反向代理路径。数据库中的标签词频统计也因数据陈旧而改为通过关联查询实时计算。 最终项目产出包括约2800行Go后端代码和2000行Vue前端代码,实现了完整的REST API、JWT认证、防盗链等40余个端点。作者评价整个过程耗时约两三小时,主要负责需求反馈与测试,AI则负责编码、构建与部署,认为这种人机协作模式展现了AI在复杂工程任务中的实用潜力。

本机暂存
IT 2026-05-17 23:38:01 / 累计浏览 173

errno 的实现

POSIX标准对errno的定义从早期的外部变量演变为可修改左值的宏,旨在解决多线程环境下共享全局变量导致的错误码覆盖问题,确保线程安全。FreeBSD的具体实现采用函数指针间接调用模式:errno宏展开后会调用__error()函数获取int指针。在单线程场景下,__error()通过函数指针返回全局变量__libsys_errno的地址。当程序链接线程库libthr时,其构造函数会调用__set_error_selector,将函数指针切换至线程安全版本__error_threaded。该函数会检查线程初始化状态:若当前线程非初始线程,则返回该线程pthread结构体中独立的error字段地址;否则仍回退使用全局存储。这种设计既保证了主线程在线程库初始化前的可用性,又为每个工作线程提供了独立的错误存储。此外,libthr还通过弱符号引用提供了兼容路径,并将一系列可能阻塞的系统调用替换为线程化版本,以处理取消点等线程语义。

本机暂存
IT 2026-05-10 18:35:06 / 累计浏览 147

嵌入主线程消息循环的任务调度器

这篇文章聚焦于将基于多线程调度器的项目 `soluna`,移植到 WebAssembly 等非 Windows 平台时遇到的核心难题。作者从项目维护的实际需求出发,解释了为何在可能退化为单线程的环境中,模拟出 `ltask` 调度器的能力成为关键挑战。 文中介绍的核心实现思路颇具巧思:将原本独立的任务调度器巧妙地“嵌入”到主线程自身的消息循环里。这意味着主线程需要同时承担两份工作——既要处理自己的消息队列,又要扮演调度器的角色,为其他逻辑“线程”(通常是协程)分配执行机会。作者没有停留在理论层面,而是深入探讨了如何在单一线程上,通过协作式调度和精心设计的队列,来模拟多线程环境下的任务切换与调度行为。 这种设计确保了项目的多线程调度架构得以保留,其核心价值不因平台变化而丧失。文章清晰地展示了一个现实场景下的工程权衡与技术适配过程,对于需要处理类似跨平台移植问题,或是对单线程高并发模型感兴趣的开发者而言,提供了非常具体的实现参考。

本机暂存
IT 2022-02-03 13:10:34 / 累计浏览 5,003

豆瓣是啥?

这篇讲的是豆瓣作为“匿名品味社区”的本质与演化路径。作者从博客时代切入,指出豆瓣早期通过“豆瓣秀”插件,让博主在侧边栏自动展示书影音记录,以极低门槛实现了口碑冷启动——这本质是让用户展演自己的文化资本。 文章的核心观点是:豆瓣构建的是“文化资本”而非社交资本。在匿名环境下,用户通过书影音记录塑造个人品味形象,形成精神层面的优越感与认同。这种对文化深度的追求,解释了豆瓣为何不像微博那样追逐热度和流量,也解释了其产品逻辑的诸多选择,例如早期对游戏条目的拒绝、以及对社区运营的克制态度。 作者也分析了豆瓣小组的爆发式增长与书影音社区的割裂,并点出阿北试图扮演“不运营的上帝”这一角色在现实中的矛盾。最终,文章将豆瓣定位为一个追求文化深度而非用户广度的产品,其影响深刻地塑造了许多人的文化消费选择,但也面临如何平衡社区活力与品味调性的长期挑战。

本机暂存
IT 2021-06-13 23:01:05 / 累计浏览 3,022

我对比特币的理解

这篇讲的是作者如何理解当前争议很大的比特币。文章没有直接下定论,而是用两个生动的故事作为切入点,层层剖析比特币的价值本质和价格逻辑。 作者首先通过“熊猫便便”的比喻,解释了价值如何从“局部共识”演变为“全局共识”,从而论证比特币并非“废纸”,而是一种已被部分人群认可的资产。接着,他指出其价格核心取决于交易与投资两方面的需求,并类比货币发行原理,说明了供需关系如何影响定价。 文章进一步拆解了比特币的需求来源:既有应对全球通胀的“类黄金”属性,也包含了散户投机的狂欢。作者通过一个具体的杠杆交易算账案例,直观地说明了投机的高风险,预判其长期投机属性会减弱,价格将趋于稳定。最后,文章也冷静地指出了监管政策与密码安全(包括潜在的量子计算威胁)两大核心风险。 整体来看,作者提供了一个理解比特币的系统性框架,从价值形成、定价机制到风险收益,有助于读者在狂热的市场讨论中建立自己的分析视角。

本机暂存
IT 2021-05-27 07:47:56 / 累计浏览 2,102

2020 年个人总结

这篇讲的是猿辅导一位技术管理者对2020年的坦诚回顾。作者从公司年内完成35亿美元融资、估值升至155亿美元的行业背景切入,分享了自己入职8周年的感触,以及如何在新业务孵化中,从熟悉的线上产品研发跨入陌生的硬件与线下内容领域。 文章的核心在于“变化中的成长”。作者详述了从建立硬件团队、学习供应商管理,到团队协作开发绘本等具体挑战,揭示了从舒适区步入“不舒适状态”后的学习曲线。同时,通过列出自己评分的15本年度读物(包括3本9分推荐),并分享股票交易“不做空”等心得,展现了在工作高压下仍坚持多维学习与复盘的个人习惯。 作者也坦诚面对了年初目标未完全达成的遗憾,比如读书数量与游泳频率。最后,他提出了更聚焦的2021年目标:每年读12本书、坚持游泳,并更加关注自身心理状态。整篇文章融合了职场成长、商业洞察与个人生活思考,勾勒出一位技术人在业务快速扩张期如何寻找平衡、沉淀价值的完整画像。

本机暂存
IT 2021-05-27 07:40:19 / 累计浏览 2,101

让服务器响应整个网段中的请求

这篇讲的是如何让一台服务器响应整个网段的所有IP地址请求。作者从实际需求出发,发现这个看似复杂的网络配置,核心方案其实异常简洁,仅需两步关键操作。 第一步是在路由器上为目标网段(如 172.16.0.0/16)添加静态路由,将其网关指向服务器的物理地址。第二步则是在服务器本机,使用一条 `ip route add local` 命令,将该网段绑定到本地回环接口(lo)上。作者特别指出,这样能确保服务器正确接收并回复所有来自该网段的数据包,且比使用 ARP 代理(如 tarpd、ndppd)的传统方式性能更优,不会导致网关和服务器的邻居表爆炸。 此外,作者还补充了该方法对 IPv6 同样有效,并提示路由应配置在 lo 而非 eth0 接口上以避免潜在问题。整体来看,这是一个高效、干净的解决方案,通过巧妙的路由表配置,用最小的改动实现了复杂需求,尤其适合开发测试或需要模拟多服务端点的场景。

本机暂存
IT 2021-05-26 22:53:10 / 累计浏览 1,963

内存的惰性初始化

这篇文章从一个 MMO 服务器压力测试的优化场景切入,探讨了当使用 A* 算法在一个巨大的三维网格(10MB 内存)中寻路时,如何解决初始化开销过大的矛盾。 实现者为避免每次调用都 memset 清零,采用在格点中记录版本号的技巧,实现了“用到时再判断”的惰性逻辑,但这依然需要全局保留这块内存。作者从更高层面指出,这本质上是一个用平坦内存空间模拟稀疏矩阵的权衡问题。 为此,他设计了一套惰性初始化的内存结构:以 64 字节(cacheline 大小)为单位划分内存,仅用一个二级标记树(总开销约 20KB)来记录哪些段落已被初始化。访问时检查标记,按需清零。这样,绝大多数未被访问的内存区域永远不会被初始化,将时间开销降至接近于零,同时空间代价极小。 文章结尾更提出了一个巧妙的延伸思路:对于这种障碍物静态且局部的寻路,与其在运行时寻路,不如用巨大的预计算空间将路径全部存储下来,实现 O(1) 查询。这为解决此类特定问题提供了不同的架构视角。

本机暂存
IT 2021-05-26 22:49:42 / 累计浏览 2,524

Golang socket 里面奇怪的 pipe 使用

这篇讲的是一个Go语言代理服务器在排查文件描述符时遇到的蹊跷事。 作者日常监控发现,一个TCP连接数两万多的服务,在系统的`/proc/pid/fd`目录下却有五万多个pipe文件描述符,数量远超socket本身。这不符合直觉,于是开始深挖源码。 根因最终指向了Go在Linux下对`net.Conn.readFrom`方法的优化。为了减少用户态内存拷贝,Go会尝试使用`splice`系统调用在内核态直接完成数据传输。而`splice`要求一方必须是管道,因此其实现略显“绕”:每次`readFrom`操作都会先通过`pipe2`创建一对临时管道,再分别进行`splice`操作,用完即关。这完美解释了那些额外pipe的来源。 作者也指出,尽管这种“管道中转”的实现看起来不甚优雅,但在像代理这样`readFrom`生命周期较长的场景中,其性能收益依然可观,因此通常无需优化。文章通过一次具体的生产现象,清晰揭示了Go网络库中一个精巧但隐蔽的内核级优化机制。

本机暂存
IT 2021-05-26 22:41:36 / 累计浏览 1,842

实现 go 的 goroutine 本地存储又一种方式

这篇讲的是Go语言中goroutine本地存储的一种新颖实现方案。 作者指出,Go本身没有提供便捷的goroutine本地存储,虽然可以通过`context`传递数据,但这要求在调用链上处处传递,侵入性较强。他发现Go标准库中用于性能剖析的`pprof`包里,隐藏着一个可以携带数据的`label`机制。 基于此,作者设计了一个巧妙的方案:利用其中一个label,通过一些底层技巧将一个`map`结构“塞”进去,从而在单个goroutine中携带所需的本地数据。同时,为了与标准库中基于`context`操作label的逻辑兼容,还做了相应的处理,防止数据被意外覆盖。 通过这种方式,作者将对原有pprof功能的干扰降到了最低。为此,他编写并开源了一个简洁的库:`github.com/xiezhenye/gls`,为需要goroutine本地状态的场景提供了一个侵入性较低的新选择。

本机暂存
IT 2020-02-07 14:18:40 / 累计浏览 3,085

内网穿透神器frp

这篇讲的是内网穿透工具frp,它解决了开发者常遇到的一个痛点:如何让内网服务(比如公司内网的调试接口、家里的树莓派)安全便捷地暴露到公网。作者对比了之前流行的ngrok,指出其国内访问慢、配置复杂的问题,而frp凭借开源、速度快、配置简单的特点脱颖而出。 文章的核心是手把手教读者搭建frp。作者先解释了frp的基本架构:在外网服务器部署服务端(frpc),在内网设备部署客户端(frpc),通过简单的配置文件建立隧道。接着,文章展示了配置服务端监听端口和客户端代理SSH、HTTP服务的具体示例,整个过程清晰明了。 作者通过实际搭建经验(服务端跑在Google Cloud上,客户端连家里树莓派)验证了frp的效能,并提到该项目在GitHub上已有过万Star。最终,frp只需十分钟即可完成部署的便捷性,使其成为解决内网穿透问题的高效选择。

本机暂存
IT 2020-02-05 15:19:07 / 累计浏览 2,181

Python:一切皆对象

“Python中一切皆对象”是很多开发者耳熟能详的一句话,但这句话究竟意味着什么?这篇深度解析文章从对象的基本定义出发,带我们重新审视这个核心概念。 作者首先对比了不同编程语言对“对象”的理解:有些要求对象必须具备方法和属性,有些则要求可子类化。Python的定义则更为灵活——一切皆对象,意味着任何东西都可以被赋值给变量或作为函数参数传递,即便它没有属性和方法。文章接着剖析了Python对象的三个根本特征:唯一标识(ID)、不可更改的类型,以及内容。根据内容是否可修改,对象被清晰地划分为可变与不可变两类。 更进一步,文章探讨了对象的扩展特征,如方法和名称,并着重厘清了“命名”与“赋值”的运作机制。它指出,名称(变量名)并不存在于对象内部,而是存储在命名空间(如字典)中。而赋值操作,例如`x = 10`,本质上只是修改了命名空间,让名称`x`指向一个新的整型对象,而非修改对象本身。理解这一点,对于弄清Python的变量模型和可变性问题至关重要。 通过对这些底层机制的梳理,这篇文章将一句抽象的口号变得具体可感,能有效帮助开发者构建更清晰的Python心智模型。

本机暂存
IT 2020-02-05 15:13:31 / 累计浏览 2,045

浅谈 Web 应用的内存优化

这篇讲的是在复杂Web应用和Node.js服务端环境中,为何以及如何进行JavaScript内存优化。 作者从Web应用复杂度提升、需长时间运行的背景出发,点明了自动内存管理机制下常被忽视的内存问题。文章不仅梳理了深拷贝、闭包等基础概念,更将重点放在了开发实践中的具体注意事项上。 摘要需要体现的核心是那六条实用建议:避免无意创建全局变量(可借助严格模式)、用完大型数据后及时解除引用、减少循环中的频繁对象创建(可借鉴享元模式)、区分内存与缓存并设定过期机制、警惕复杂递归导致的栈溢出,以及对IndexedDB等本地存储进行定期清理,避免浏览器因数据膨胀而崩溃。 文章特色在于它并非泛泛而谈理论,而是紧密结合前端编码场景,通过具体代码示例揭示了常见的内存消耗陷阱。这些基于实际案例的优化要点,能帮助开发者在编码时形成更好的内存意识,从而构建更稳定、流畅的Web应用。

本机暂存
IT 2020-02-03 12:38:46 / 累计浏览 1,982

让 lua 运行时动态切换操作系统线程

这篇讲的是开发者在构建跨平台游戏引擎时,如何巧妙解决一个操作系统级的线程调度矛盾。作者从 iOS 的一个严苛限制出发:系统要求窗口消息循环必须运行在主线程,否则程序可能被杀;而引擎为了隔离耗时的业务逻辑,又必须把窗口管理模块与用户主逻辑分到不同线程。 矛盾在于,用户的业务代码期望运行在 Lua 解释器启动时的主虚拟机(VM)中,窗口模块期望在独立线程,同时窗口模块还必须占据操作系统意义上的“主线程”。作者最初认为这无解,除非像 Skynet 那样深度定制 Lua 运行时,让 VM 能自由迁移。 真正的转机来自一个巧妙的 API 设计:`thread.fork`。它通常让 func1 在当前 VM,func2 在新建 VM 和线程上并行。但作者反其道而行,让 func1(用户主逻辑)在**新线程**上运行,而让 func2(窗口模块的新 VM)继续留在**当前线程**(即操作系统主线程)上执行。由于两者都通过 `pcall` 被限制在各自作用域内,用户代码完全感知不到自身线程已切换,而窗口模块则恰好满足了系统对主线程的要求。 这个方案的巧妙之处在于,没有去硬撼操作系统的规则,而是通过“偷梁换柱”——交换两个执行流所在线程的位置,让看似不可调和的约束在架构层得到了圆满解决。

本机暂存
IT 2020-02-02 10:55:04 / 累计浏览 3,043

直播/点播中HTTP Live Streaming(HLS)协议的简介与使用

这篇讲的是HLS协议在直播与点播场景中的应用。作者从基本概念切入,梳理了推流与拉流的过程,并点明HLS是拉流环节的关键协议。 HLS由苹果提出,核心特点是将连续流切分为小段TS文件,通过m3u8索引文件进行分发。它的优势在于完全基于HTTP,易于利用CDN分发,且支持客户端根据网络状况自适应选择码率。不过,这种分段机制也带来了延迟较高的缺点。文章详细说明了其工作模式:客户端先下载m3u8索引,再按列表顺序请求并播放TS片段。对于点播,文件列表固定;对于直播,索引文件则持续更新。 在实践部分,文章给出了用ffmpeg创建HLS流的命令示例,并探讨了加密与防盗链。HLS支持AES-128加密,但静态密钥安全性不足,更可靠的方案是结合用户信息动态生成密钥。最后,文章将HLS与新兴的MPEG-DASH标准进行了对比,指出DASH使用MPD描述文件且更倾向于支持fMP4分片,是国内如B站等平台选用的方案之一。 整篇内容从原理到实践,清晰展现了HLS协议的工作全貌与技术权衡。

本机暂存
IT 2020-02-01 15:07:16 / 累计浏览 1,942

一文读懂分布式系统CAP定理

这篇讲的是分布式系统中著名的CAP定理,作者从自己初遇概念时的困惑出发,试图用更直白的方式把这个“看不见的手”讲明白。文章核心指出,在分布式环境中,一致性(C)、可用性(A)和分区容错性(P)三者不可兼得,必须做出权衡。 作者通过具体的MySQL集群案例,对比了三种典型选择:追求CA时,如基于主键的分库分表,能保证强一致和高可用,但无法应对网络分区;选择CP时,如严格的主从复制模式,数据一致性得到保障,但分区会导致写操作不可用;而倾向AP时,如允许异步复制的集群,则优先保证服务不中断,但可能读到过时数据。 文章最后自然引出了BASE思想,这是许多高并发系统在CAP约束下的实际选择——优先保障基本可用,接受临时数据不一致,最终达到一致。作者用面试经历和自学过程串联全文,让理论落地到实际架构的考量中。

本机暂存