别让 NULL 拖垮结果:MySQL COALESCE 空值兜底实战详解

5 月 23 日
阅读 9 分钟
541
简介COALESCE 是 MySQL 里非常常用的空值处理函数。它的作用很简单: {代码...} 最基础示例: {代码...} 结果: {代码...} 因为 'hello' 是第一个非 NULL 值,后面的 'world' 不会作为结果返回。如果所有参数都是 NULL: {代码...} 结果还是: {代码...} 一句话概括: {代码...} 它常用于这些场景:字段为空时显示默认文...

C#.NET YARP + OpenTelemetry:网关链路追踪实战

5 月 22 日
阅读 17 分钟
540
简介微服务项目里,接口慢了、报错了、偶发超时了,最怕的不是失败本身,而是不知道请求到底卡在哪一层。比如一个很常见的链路: {代码...} 如果只看普通日志,经常只能看到: {代码...} 但很难一眼看出:这几条日志是不是同一次请求产生的请求在网关花了多久转发到后端花了多久后端服务之间调用花了多久哪一段失败了Tra...

别再让 key 写成字符串:TypeScript keyof 从入门到实战

5 月 21 日
阅读 15 分钟
568
简介keyof 是 TypeScript 里的类型操作符,用来提取一个对象类型的所有 key,并组成一个联合类型。先看一个普通对象类型: {代码...} 使用 keyof: {代码...} 得到的结果相当于: {代码...} 一句话概括: {代码...} 它经常出现在这些场景里:根据字段名安全取值根据字段名安全赋值表格列配置表单字段校验接口字段映射Pic...
封面图

别再把对象类型写散了:TypeScript Record 从入门到实战

5 月 20 日
阅读 15 分钟
492
简介Record 是 TypeScript 内置的工具类型,用来描述一种很常见的数据结构: {代码...} 例如订单状态对应中文文案: {代码...} 这种对象在前端项目里很常见:状态码映射文案角色映射权限路由映射菜单表单字段映射错误信息接口列表转成 id -> 数据 的字典主题名映射主题配置Record 的作用就是给这种“键值映射对象”加上...
封面图

别只会写 IF:MySQL CASE WHEN 条件判断实战详解

5 月 19 日
阅读 10 分钟
577
简介CASE WHEN 是 MySQL 里用来做条件判断的表达式。它的作用很像编程语言里的 if...else 或 switch...case:满足不同条件时,返回不同结果。最常见的场景有这些:把状态码转成状态文字按年龄、金额、分数分段按条件统计数量自定义排序规则报表行转列批量更新不同值处理 NULL、空值、异常值一句话概括: {代码...} 例如...
封面图

C#.NET YARP 跨域配置详解:网关统一处理 CORS

5 月 18 日
阅读 14 分钟
586
浏览器页面从 http://localhost:5173 请求 http://localhost:5000/api/products,协议、域名、端口只要有一个不同,就属于跨域请求。
封面图

别再手写重复 CSS 了:SCSS 从入门到实战

5 月 14 日
阅读 12 分钟
546
普通 CSS 能写的内容,SCSS 基本都能直接写;在此基础上,SCSS 又加了变量、嵌套、混合、函数、循环、模块拆分等能力。浏览器并不直接执行 SCSS,项目构建时会先把 .scss 文件编译成普通 .css 文件,然后再交给浏览器使用。
封面图

别再误会 SELECT 1:MySQL 常量查询与存在性判断实战

5 月 14 日
阅读 6 分钟
506
简介SELECT 1 是 MySQL 里很常见的一句 SQL。它不是查询第一行,也不是查询第一列,更不是某种特殊语法。它的本质很简单: {代码...} 最基础写法如下: {代码...} 执行结果: {代码...} 这条 SQL 没有 FROM,所以不查任何业务表。MySQL 只需要解析 SQL,然后返回一个常量结果。类似写法还有: {代码...} 这些都属于“常量...

C#.NET YARP 认证授权实战:在网关层统一接入 JWT

5 月 12 日
阅读 16 分钟
558
简介上一篇文章已经把 YARP 的基础反向代理、路由、负载均衡、健康检查、限流都串了一遍。这篇继续往下走,专门讲一个网关项目里很常见的能力:在 YARP Gateway 层统一接入 JWT 认证授权。也就是说,请求进来以后,先经过网关校验 JWT,校验通过后再转发到后端服务。请求链路大概是这样: {代码...} 这样做的好处很直接...

C#.NET YARP 详解:用 ASP.NET Core 打造高性能反向代理网关

5 月 9 日
阅读 18 分钟
630
所以它和 Nginx、Envoy 这类独立代理不太一样。YARP 更像一个“网关积木”,路由、负载均衡、请求头处理、认证授权、限流、健康检查这些能力都能放进 .NET 项目里统一控制。

终于不用手搓两级缓存了!C#.NET HybridCache 详解:L1 L2、标签失效与防击穿实战

5 月 7 日
阅读 12 分钟
556
简介很多项目一开始做缓存,通常都是这么写的: {代码...} 刚开始看起来没什么问题。但只要项目一复杂,这套逻辑很快就会变得又长又散:每个地方都在手写两级缓存本地缓存和 Redis 的过期时间不好统一并发一上来,容易缓存击穿对象序列化、反序列化到处都是删除缓存时,还得考虑本地层和分布式层一起失效这时候,.NET 官...

别再把 Redis 当黑盒了!C#.NET IDistributedCache 详解:官方分布式缓存接口从入门到实战

5 月 6 日
阅读 10 分钟
707
简介很多项目一提到缓存,第一反应就是:上 Redis存个字符串查不到就回数据库刚开始这样写没什么问题。但项目一复杂,几个现实问题就会很快冒出来:多实例部署后,本地缓存各存各的业务代码里到处散着 Redis key对象序列化、反序列化重复写了一堆过期时间全靠手抄想切换缓存底层实现时,影响一大片代码这时候就会碰到一...

别只会用 MemoryCache!C#.NET CacheManager 详解:多级缓存、Region 与 Redis 实战

5 月 5 日
阅读 28 分钟
672
简介一提到缓存,很多项目里最先出现的通常是这几样东西:IMemoryCacheIDistributedCacheRedis手写一套缓存工具类刚开始看起来都能用。但项目一复杂,问题就会慢慢冒出来:有的地方直接查内存缓存有的地方直接调 Redis有的地方缓存键命名完全不统一有的地方更新数据库以后,忘了删缓存有的地方想做“本地内存 + Redis”两...

内存为什么越来越高?C#.NET GC 详解:分代回收、LOH、终结器与性能优化实战

5 月 4 日
阅读 14 分钟
553
简介平时写 C#,很少会主动去碰内存管理。因为 .NET 已经把最麻烦的一层包掉了:对象分配不用手动 malloc对象释放不用手动 free大部分时候只管写业务,程序也能正常跑但只要项目一上量,GC 这个词迟早会冒出来:接口偶尔抖一下,排查看到 Gen2 GC内存一直涨,不确定是正常波动还是泄漏高频循环里 new 了很多对象,担心 G...

别再层层传参了!C#.NET AsyncLocal 异步上下文透传实战

5 月 1 日
阅读 9 分钟
612
简介异步代码一多,参数传递很快就会开始变味。最常见的场景是这样:入口层拿到了 TraceId服务层要打日志仓储层也想拿到同一个 TraceId调了好几层 await 以后,这个值还得一直跟着走如果每一层都靠方法参数往下传,代码会越来越啰嗦。这时候很多人会先想到:放静态变量里,不行,会串请求放 ThreadLocal<T> 里,不...
封面图

别再把增删改查写成一锅粥!C#.NET CQRS 从原理到实战

4 月 30 日
阅读 14 分钟
701
简介很多业务系统刚开始都差不多:一个 Service里面既有新增、修改、删除也有列表、详情、统计、搜索前期这样写很顺手。但只要项目稍微复杂一点,问题就会慢慢冒出来:读逻辑和写逻辑揉在一起一个接口改动,连带影响一堆查询写入要走校验、事务、领域规则查询却只想尽快把数据拿出来列表页、报表页、详情页要的数据结构...
封面图

C#.NET ThreadLocal 深入解析:线程独享数据、性能收益与实战边界

4 月 29 日
阅读 9 分钟
605
简介多线程代码里最麻烦的一个点,不是“怎么开线程”,而是“数据到底该不该共享”。很多并发问题,本质上都不是线程太多,而是:好几个线程同时改同一份数据于是开始加锁锁一多,性能又掉下去这时候就会发现,有些数据其实根本没必要共享。比如:每个线程自己的计数器每个线程自己的 Random每个线程临时复用的 StringBuild...
封面图

C#.NET MediatR 深入解析:进程内消息分发、CQRS、通知事件与管道行为实战

4 月 28 日
阅读 16 分钟
637
简介MediatR 是 .NET 里很常见的进程内消息分发库。它做的事情不复杂:调用方发出一个请求,MediatR 找到对应的处理器执行。这听起来像“多绕了一层”,但在业务代码越来越复杂时,这一层很有用。没有 MediatR 时,控制器、服务类里经常会堆很多依赖: {代码...} 一开始还好,后面新增库存、支付、优惠券、消息通知、审计...
封面图

C#.NET MemoryMarshal 深入解析:零拷贝内存重解释、二进制读写与使用边界

4 月 27 日
阅读 13 分钟
434
简介在 .NET 高性能内存编程里,Span<T> 解决了一个很实际的问题:不复制数据,也能操作一段连续内存。但 Span<T> 本身还是比较“规矩”的。比如:Span<byte> 就是按字节看;Span<int> 就是按整数看;ReadOnlyMemory<T> 背后到底是不是数组,不一定直接暴露;想把一段字节当成结构体读出来...
封面图

C#.NET TaskCompletionSource 深入解析:手动控制 Task、桥接回调事件与实战避坑

4 月 22 日
阅读 13 分钟
622
简介在 .NET 异步编程里,Task 大多数时候都是“自动完成”的。比如:async 方法执行完了,返回的 Task 自动完成;HttpClient.GetAsync 底层 I/O 完成了,Task 自动完成;Task.Run 里的委托跑完了,Task 自动完成。但还有一类场景,不是“代码块执行完就结束”,而是:某个回调什么时候被触发,不确定;某个事件什么时候到来...
封面图

C#.NET Task 与 async await 深入解析:底层原理、执行流程与实战误区

4 月 21 日
阅读 9 分钟
802
简介Task 和 async/await 是 C# 异步编程的核心,也是最容易被表面化理解的一组概念。开发中常见的说法往往是:Task 就是线程;await 会新开一个线程;只要用了 async,方法就变快了;代码卡了,包一层 Task.Run 就行。这些说法并不完全错误,但都不够准确。如果理解只停留在“会写”这一层,项目一复杂,问题就会马上出现...
封面图

C#.NET ValueTaskSource 深入解析:零分配异步与使用边界

4 月 17 日
阅读 9 分钟
556
简介在 .NET 异步里,如果你顺着这条线往下学:TaskValueTaskIValueTaskSource会发现难度是明显跳跃的。Task 还是大多数业务代码的默认答案。 ValueTask 已经开始涉及“减少分配、减少状态对象”的优化。 到了 ValueTaskSource,就基本进入了 .NET 异步底层设施这一层。这个知识点最容易被写得很玄:“零分配异步”“高性能神...
封面图

C#.NET ObjectPool 深入解析:对象复用、池化策略与使用边界

4 月 16 日
阅读 6 分钟
567
简介在 .NET 里做性能优化时,很多人第一反应是:少分配少 GC少临时对象这个方向本身没有问题。但问题在于,优化一旦开始,很容易走偏成另外一种极端:看到对象创建就想池化觉得池化一定比 new 更快把对象池当成一种“万能缓存”ObjectPool 这类工具,真正值钱的地方不是“把所有对象都放进池里”,而是:对某些创建成本不算...
封面图

C#.NET Mapperly 深入解析:源生成映射、安装使用与工程化取舍

4 月 15 日
阅读 9 分钟
719
简介在 .NET 项目里,只要分层稍微清晰一点,就绕不开这类代码:Entity -> DtoRequest -> CommandCommand -> AggregateGrpc Message -> Application Model一开始大家通常是手写: {代码...} 少量场景这么写没问题,代码也最直接。但映射一多,问题也很快出现:代码重复改字段时容易漏嵌套对象和集合一多就开...
封面图

C#.NET IL 中间码 深入解析:从 C# 编译结果到 CLR 执行链路

4 月 13 日
阅读 11 分钟
587
简介很多人第一次认真看 IL,通常不是因为“想学一门汇编”,而是因为碰到了这些问题:同一段 C#,编译之后到底变成了什么async/await、yield、lock 这些语法糖到底被编译成了什么样为什么有些代码看着简单,运行时却没你想的那么直接JIT 优化、装箱、虚调用这些事,真正发生在什么阶段这时候,IL 往往就会进入视野。一句...
封面图

C#.NET Monitor 与 Mutex 深入解析:进程内同步、跨进程互斥与使用边界

4 月 9 日
阅读 6 分钟
618
简介在 .NET 里提到同步,很多人第一反应通常是: {代码...} 这没问题。但只要你继续往下挖,很快就会碰到两个更底层的名字: {代码...} 它们都能做“互斥”,但解决的问题并不是同一类。一句话先说透:Monitor 是进程内线程同步的默认基础设施,Mutex 则更偏跨进程互斥的操作系统级工具。所以这篇文章重点不是只列 API,...

C#.NET gRPC 深入解析:Proto 定义、流式调用与服务间通信取舍

4 月 8 日
阅读 14 分钟
790
简介很多人第一次认真看 gRPC,通常不是因为“想学一个新协议”,而是因为项目已经出现了这些信号:服务和服务之间调用越来越多REST 的 JSON 体积、契约漂移、字段随意扩张开始让人烦想要更明确的接口定义想做流式推送,又不想自己再拼一套长连接协议这时候,gRPC 往往就会进入视野。一句话先说透:gRPC 本质上是一种基于 ...
封面图

C#.NET TPL Dataflow 深入解析:数据流管道、背压控制与实战取舍

4 月 7 日
阅读 11 分钟
634
简介很多人第一次接触 TPL Dataflow,往往是在这种场景里:有一批数据要按阶段处理每个阶段都可能是异步的有的阶段想并行,有的阶段又想限流生产速度和消费速度不一致还希望上游结束时,下游也能优雅收尾这类问题,用最直接的写法当然也能做:自己起几个 Task手写几个 ConcurrentQueue再配上 SemaphoreSlim最后自己维护...
封面图

C#.NET 分布式事务 深入解析:TCC、Saga、Outbox 与落地取舍

4 月 2 日
阅读 13 分钟
931
简介只要你的 .NET 系统开始从单体走向微服务,很快就会遇到这个问题: {代码...} 这时候你会发现,单库事务那套熟悉的心智模型开始失效了。在单体应用里,你可以靠:SqlTransactionDbTransactionTransactionScope把多步操作包成一个本地事务。但当业务已经跨:多个服务多个数据库多种存储消息队列本地事务就不够了。这...
封面图

C#.NET Consul + Steeltoe 深入解析:服务注册发现、健康检查与微服务接入

3 月 31 日
阅读 10 分钟
508
简介在 .NET 微服务里,只要你开始拆服务,很快就会遇到这几个现实问题:服务实例越来越多,地址不固定调用方不能再把 IP:Port 写死某个实例挂了,调用方最好别继续打过去配置、注册、发现、负载均衡这些事,不能全靠手写这时候经常会一起出现两个名字: {代码...} 一句话先说透:Consul 是服务注册发现和健康检查的基础...
封面图