纯技术文章

聚焦可落地的后端实现与工程细节,适合希望补齐底层能力和系统设计判断的开发者。

40 篇文章,围绕 纯技术 主题持续整理。

2025年8月21日

为什么有的人学了很多年的编程,还是只会【增删改查】?

为什么你写了多年代码,技术栈还停留在"增删改查"? 我们不妨从一个常见的开发者画像开始:工作数年,日常任务是理解需求、实现业务逻辑、提供数据接口。在熟悉的框架下,每天熟练地进行着数据库的增、删、改、查(CURD)操作,周而复始。 这套流程看…

2023年12月21日

Golang-常用限流算法实现

常用的限流算法有一下4中实现方式: 令牌桶 漏桶 计数器 滑动窗口 令牌桶以恒定的速度向桶里加入令牌,桶满了则不再加入令牌。当服务收到请求时尝试从桶中取出一个令牌,如果可以获取到令牌,则继续执行后续的业务,否则返回超限错误码或对应的错误页面…

2023年12月21日

Redis:数据结构

Redis有5种基本的数据类型: String(字符串)对象、List(列表)对象、Hash(哈希)对象、Set(集合)对象和 Zset(有序集合)对象 下图为数据类型对应的底层数据结构 list对象 在3.2版本后由quicklist实现

2023年12月21日

Redis:主从复制

为避免单机故障,需要将数据复制到其他服务器上,这样即使一台服务出现了问题,其他服务器也可以快速对外提供服务,Redis 提供了主从复制模式来保证多台服务器之间的数据一致性 主从服务器间的第一次同步的过程可分为三个阶段: 第一阶段是建立链接、…

2023年12月21日

Redis:哨兵

在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点(master)挂了,那么将没有主节点来服务客户端的写操作请求,也没有主节点给从节点(slave)进行数据同步了。哨兵的作用是实现主从节点故障转移 哨兵其实是一个运行在特殊模…

2023年12月21日

操作系统:计算机基本结构

计算机基本结构为 5 个部分,分别是运算器、控制器、存储器、输入设备、输出设备, 即冯诺依曼模型 程序和数据都是存储在内存,存储的区域是线性的 计算机数据存储中,存储数据的基本单位是字节(byte) ,1 字节等于 8 位(8 bit)。每…

2023年12月21日

操作系统:CPU缓存一致性

CPU 和内存的访问性能相差大,于是就在 CPU 内部嵌入了 CPU Cache(高速缓存),CPU Cache 离 CPU 核心相当近,因此它的访问速度是很快的,于是它充当了 CPU 与内存之间的缓存角色 CPU Cache 通常分为三级…

2023年12月21日

操作系统:内核(Linux)

计算机是由各种外部硬件设备组成的,比如内存、cpu、硬盘等,如果每个应用都要和这些硬件设备对接通信协议,那这样太累了,所以这个中间人就由内核来负责,让内核作为应用连接硬件设备的桥梁,应用程序只需关心与内核交互,不用关心硬件的细节 内核的能力…

2023年12月21日

操作系统:内存管理

如果 CPU 直接操作内存的「物理地址」,想在内存中同时运行两个程序是不可能的 如何解决: 操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。 如果程序要访问虚拟地址的时候,由操作系统转换成不同的物理地址,这样不同的…

2023年12月21日

操作系统:内存分配

在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分 每个进程都各自有独立的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内存。这样,进程切换到内核态后,就可以很方便地访问内核空间内存 用户空间分…

2023年12月21日

操作系统:进程

我们编写的代码只是一个存储在硬盘的静态文件,通过编译后就会生成二进制可执行文件,当我们运行这个可执行文件后,它会被装载到内存中,接着 CPU 会执行程序中的每一条指令,那么这个运行中的程序,就被称为「进程」(Process) 当进程要从硬盘…

2023年12月21日

操作系统:线程

线程是进程当中的一条执行流程 同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的 线程的优点: 一个进程中可以同时存在多个线程; 各个线程之间可以并…

2023年12月21日

操作系统:进程间通信

管道传输数据是单向的 所谓的管道,就是内核里面的一串缓存 缺点:效率低,FIFO 消息队列是保存在内核中的消息链表 在发送数据时,会分成一个一个独立的数据单元,也就是消息体(数据块),消息体是用户自定义的数据类型,消息的发送方和接收方要约定…

2023年12月21日

操作系统:零拷贝

直接内存访问(Direct Memory Access) 在进行 I/O 设备和内存的数据传输的时候,数据搬运的工作全部交给 DMA 控制器,而 CPU 不再参与任何与数据搬运相关的事情,这样 CPU 就可以去处理别的事务 用户进程调用 r…

2023年12月21日

MySQL:数据的存储和读取

MySQL 的架构共分为两层:Server 层和存储引擎层 连接的过程需要先经过 TCP 三次握手,因为 MySQL 是基于 TCP 协议进行传输的 完成 TCP 连接的建立后,连接器就要开始验证你的用户名和密码,如果用户名或密码不对,就收…

2023年12月21日

go-zero 使用 Consul 作为注册中心

go-zero 默认使用etcd作为注册中心,如果我们的业务使用的consul, 可以使用zero-contrib中的consul包进行替代 文件位置:ect/**.yaml 增加consul配置 服务启动后即可在conusl/ui上查看到…

2023年12月21日

go-zero:zrpc

zrpc是go-zero的rpc部分,简单易用可直接用于生产的企业级rpc框架 zRPC底层依赖gRPC,内置了服务注册、负载均衡、拦截器等模块,其中还包括自适应降载,自适应熔断,限流等微服务治理方案 zRPC主要有以下几个模块组成: di…

2023年12月21日

MySQL:慢查询优化

最左前缀匹配原则 \=和in可以乱序 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*) 索引列不能参与计算,保持列"干净" 尽量扩展索引,不要新建索引 先运行看看是否真的很慢,注意设置SQ…

2023年12月21日

Go 设计模式:对象池模式

Object pool Pattern, 对象被预先初始化并存储于对象池中,当需要时,客户端可以从对象池中请求一个对象并使用,然后将其返回对象池中 组成: 对象池: 类,主要用于维护可用对象的列表和已从对象池中请求的对象集合 客户端:调用对…

2023年12月21日

Go 设计模式:适配器

Adpater Pattern 是指将一个类的接口转换成客户端希望的另一个接口,使原本因接口不兼容而不能一起工作的类可以一起工作 组成如下: 目标:定义客户端所需的接口 适配器:适配器可以调另一个接口,是一个转换器,主要用于对适配器类和目标…

2023年12月21日

MySQL:buffer pool

Innodb 存储引擎设计了一个缓冲池(Buffer Pool) ,来提高数据库的读写性能,当数据从磁盘中取出后,缓存内存中,下次查询同样的数据的时候,直接从内存中读取 有了缓冲池后: 当读取数据时,如果数据存在于 Buffer Pool…

2023年12月21日

go-zero:workergroup

goroutine 太多仍会导致调度性能下降、GC 频繁、内存暴涨, 引发一系列问题。在面临这样的场景时, 限制 goroutine 的数量、重用 goroutine 显然很有价值 主要是用chan来控制goruntine的数量 lang.…

2023年12月21日

MySQL:日志

undo log(回滚日志) :是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC。 redo log(重做日志) :是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢…

2023年12月21日

网络:TCP(1)

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议 面向连接:一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的; 可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保…

2023年12月21日

网络:TCP(2)

在 TCP 中,当发送端的数据到达接收主机时,接收端主机会返回一个确认应答消息,表示已收到消息 常见的重传机制: 超时重传 快速重传 SACK D-SACK 重传机制的其中一个方式,就是在发送数据时,设定一个定时器,当超过指定的时间后,没有…

2023年12月21日

Service Mesh:如何屏蔽服务治理细节

微服务需要解决的问题和对应的中间件 用 RPC 框架解决服务通信的问题; 用注册中心解决服务注册和发现的问题; 使用分布式 Trace 中间件,排查跨服务调用慢请求; 使用负载均衡服务器,解决服务扩展性的问题; 在 API 网关中植入服务熔…

2023年12月21日

MySQL:数据迁移如何实现

简单的实现方案: 通过 MySQL 主从同步的方式做到准实时的数据拷贝 通过 mysqldump 工具将源库的数据导出再导入到新库 存在的问题: 这两种方式只能支持单库到单库的迁移,无法支持单库到多库多表的场景 迁移的同时还有数据写入 平滑…

2023年12月21日

静态资源加速

在我们的系统中存在着大量的静态资源请求: 对于移动 APP 来说,这些静态资源主要是图片、视频和流媒体信息; 对于 Web 网站来说,则包括了 JavaScript 文件、CSS 文件、静态 HTML 文件等等 读请求量极大并且对访问速度的…

2023年12月21日

一场 ChatGPT 模拟面试

最近体验了下chatgpt, 真的太强了,体验了下使用chatgat进行一场服务端的面试,以下是chatgpt的发挥~ 微服务是一种面向服务架构(SOA)的一种变体,指的是将业务应用按照业务领域拆分成多个自治的服务单元,通过服务之间的协作来…

2023年12月21日

go-zero:链路追踪

横跨几十个分布式组件的慢请求要如何排查,我们可能会想到用request_id将多个服务器上的日志串起来,但仅仅依靠 requestId 很难表达清楚服务之间的调用关系,所以从日志中就无法了解服务之间是谁在调用谁 因此,我们采用 traceI…

2023年12月21日

go-zero:Prometheus 监控

Prometheus是一款最受欢迎的开源监控系统之一,它由SoundCloud开发,目的是收集各种应用程序的度量数据并将其存储在时间序列数据库中,从而可以进行数据可视化和警报 数据模型 Prometheus数据模型的关键组件是时间序列。时间…

2023年12月21日

MySQL:大表在线更新字段

某一日 大厂面试官:线上有一张数据量级为几千万的表,需要新增一个字段,该如何处理呢 葫芦:目前还没有接触过类似的场景,大概的想法是建一张新表,双写的形式... 大厂面试官: 回去等通知 稀碎.... ps: 以下内容为参考网上大佬们的实现方…

2023年12月21日

关于 ChatGPT 辅助读源码的那些事

chatgpt的出现可以说对程序员这个职业造成了很大的冲击,除了可以自动生成代码外,也可以理解代码,尝试了下用chatgpt去辅助阅读源码 以kratos的limit为例 下面我会将bbr limit 中的每个方法直接复制给chatgpt,…

2023年12月21日

关于hotkey的那些事儿

某一日, 葫芦去面试,面试官-十三 十三: 你们项目中的热key是如何处理的 葫芦: 热key我们会放到缓存中,如果不存在,用单飞从redis获取,在加载到缓存,缓存用的go-cache 十三: 那你了解go-cache的实现原理吗 葫芦:…

2023年12月21日

关于 ChatGPT 辅助代码质量的那些事

最近 chatgpt 大火,加上最近几日使用chatgpt辅助阅读一些开源项目的源码参考此文章,体验很好,所以葫芦尝试下使用chatgpt来发现代码中的问题,提高代码质量 代码段一 下面是葫芦以前写极验sdk中的一段代码,功能很简单,就是一…

2023年12月21日

关于内存逃逸那些事儿

又某一日,葫芦被十三问的Golang基础知识吊打 十三: 葫芦你知道Golang的内存逃逸么,举几个栗子,以及你在项目中如何优化的 葫芦: Golang会自己进行内存分配,开发者不需要关系内存分配到哪了。内存逃逸指的是内存从栈上逃到了堆上…

2023年12月21日

关于连接池的那些事儿

某一日,葫芦正在写一个简单的CURD代码,十三不知何时悄悄的来到身后 十三: 葫芦,你知道db的 conn 如何管理的 葫芦一哆嗦 葫芦: 通过池化技术,通过maxIdleConns 和 maxOpenConns 参数来决定池子的大小 十三…

2023年12月21日

Go 设计模式:策略模式

策略模式可以让开发者定义一系列算法,并且将每种算法分别放入独立的类,从而使得算法的对象可以相互替换 组成; 上下文(Context): 维护指向具体策略引用的类,并且仅通过策略接口与该引用进行交流 策略(Stategy): 实现上下文所用算…

2023年12月21日

Go 设计模式:责任链

责任链模式允许开发者将请求沿着链进行发送,直至其中一个处理者对象对其进行处理。 责任链模式可以将请求的发送者和接收者解耦 责任链模式允许多个处理者对象对请求进行处理,无须让发送者类与具体的接收者类相耦合 组成: 处理者(handler):…

2023年12月21日

敏捷故事-背景一

基本原则: 不要在项目开始阶段就做一套完善的,包罗万象的决策 把各个决策分散在项目过程中 用户故事描述了对用户、软件或软件购买者有价值的功能 由以下三个方面组成: 一份书面的故事描述,用于做计划和提示 有关故事的对话,用于具体化故事细节 测…