Golang 面试进阶指南:从 GMP 到 pprof,一份面向中高级岗位的系统复习手册
Golang 面试进阶指南:从 GMP 到 pprof,一份面向中高级岗位的系统复习手册如果你已经写过一两年 Go,会用 goroutine、channel,也能把一个 HTTP 服务跑起来,那么在准备中高级岗位面试时,大概率会发现:面试官问的已经不是“goroutine 怎么启动”,而是“一个阻塞的系统调用发生时,调度器会做什么”“nil 的 error 为什么不等于 nil”“线上 goroutine 数量一直涨,你怎么定位” 这类问题考察的不是背诵,而是你对运行时机制的理解,以及把机制翻译成工程判断的能力 这篇文章是一份按主题组织的复习手册 每个主题基本遵循同一个结构:典型面试题 → 参考回答思路 → 常见陷阱 → 简短的代码 内容覆盖调度器、goroutine 生命周期、channel、sync 原语、context、内存模型、GC 与逃逸分析、slice 与 map、interface、defer/panic/recover、泛型、错误处理、反射、并发模式、性能调优、工程实践,最后补充系统设计与行为面试的建议、速答表、学习路线和 FAQ

2026-10-14鱼鱼
并发之AQS全解析
并发之AQS全解析我们知道juc(java.util.concurrent)包下有很多实用的类,提供了很多并发工具,例如线程池、原子类、并发工具、信号量工具、锁等,可以说基本实现都为悲观锁,底层原理基本都使用了AQS(AbstractQueuedSynchronizer),AQS不是一种概念,是并发中实打实的工具类 本篇文章针对AQS做解析 AQS是多线程访问共享资源的同步器框架 AQS的资源可以是独占的也可以是共享的 我们先来简单看一下它的使用方式和ApI(因为是抽象类,是不能直接使用的),下图是AQS的整体脉络 AQS核心就是一个状态值state,同时维护了一个线程的阻塞队列,队列的节点为有两种状态:SHARED(共享)和EXCLUSIVE(独占),节点状态有五种:
![并发之AQS全解析]()
2021-03-12鱼鱼
ES快速入门(I)——分析分词器
ES快速入门(I)——分析分词器本文旨在快速入门Elasticsearch的分词,包括分词分析器的创建和介绍对比等,请确保在阅读前已经搭建好完备的集群 文章基于es7.0+,与稍旧版本的主要区别是没有type 在讨论分词前,我们先看一下es整体创建倒排的分词过程: 我们常说的分词器指的其实是“分析器”analyzer,es将以上常用的逻辑封装起来成为analyzer,但是语义上的分词器是指上面的tokenizer 经过了三层处理后拿到了terms数组建立最终的倒排索引: character filter:一般不会用到这个filter,是在分词前对原有的文档字段内容做转换,例如去除html的标签提取出正文内容,按正则清除和替换某些内容,你可以指定及自定义0个到多个character filter,他们将共同存在,一个文本流在经过character filter处理后,依然是文本流;
![ES快速入门(I)——分析分词器]()
2020-09-01鱼鱼
盘点redis中特殊的数据类型 HyperLogLog Bitmap
盘点redis中特殊的数据类型 HyperLogLog Bitmap 基数计数(cardinality counting)通常用来统计一个集合中不重复的元素个数,例如统计某个网站的UV,或者用户搜索网站的关键词数量 数据分析、网络监控及数据库优化等领域都会涉及到基数计数的需求 要实现基数计数,最简单的做法是记录集合中所有不重复的元素集合S_uSu,当新来一个元素x_ixi,若S_uSu中不包含元素x_ixi,则将x_ixi加入S_uSu,否则不加入,计数值就是S_uSu的元素数量 这种做法存在两个问题: 当统计的数据量变大时,相应的存储内存也会线性增长 当集合S_uSu变大,判断其是否包含新加入元素x_ixi的成本变大 大数据量背景下,要实现基数计数,首先需要确定存储统计数据的方案,以及如何根据存储的数据计算基数值;另外还有一些场景下需要融合多个独立统计的基数值,例如对一个网站分别统计了三天的UV,现在需要知道这三天的UV总量是多少,怎么融合多个统计值
![盘点redis中特殊的数据类型 HyperLogLog Bitmap]()
2022-01-12鱼鱼
Java排坑指南(I)jmap jstack jstat等的使用
Java排坑指南(I)jmap jstack jstat等的使用运用一些Java自带的可执行jar可以从内存的角度更轻松的排除项目中的问题,我们可能会遇到一些不常见却相对很致命的问题,例如: 某些web项目CPU跑到了100%并且飙高不下(一般来说,web应用都为IO密集应用,不太可能出现cpu高占用的情况) 项目中线程出现阻滞、阻塞(网络请求响应速度明显变慢,甚至因为死锁彻底出现阻塞等) 极可能由内存泄漏引发的不明原因的 OOM(没有预兆的或是基础逻辑问题的内存溢出) 当以上问题发生时,通过代码或是日志其实很难定位到原因所在,因为这一般是基于环境或资源导致的全局性问题,通常很难定位,这时可以通过使用Java自带的性能调优jar包更便捷的定位问题(如果没有配置环境变量,可以在jdk的bin目录下找到他们的jar包)

2020-11-28鱼鱼
AI 补全和整段生成,我什么时候用哪种
AI 补全和整段生成,我什么时候用哪种用 AI 写代码久了,我会下意识把它分成两种节奏:一种是编辑器里那个“跟着你敲”的补全;另一种是对话框里“给我写一整段 / 一整文件”的生成 表面上都是 AI 在写,体感完全不一样 补全像有人在旁边帮你把下一句顺出来;整段生成像你把需求扔出去,过一会儿收回来一份成品 我早期几乎只用后者,觉得效率高;后来越写越觉得:很多时候,补全才是更省心的那一个 这篇就聊聊我现在怎么选 补全的好处很直观——上下文就在光标周围,你刚写的函数名、变量名、注释,它都能“看见” 你按 tab 接受一行,再敲两下,它继续跟 这种节奏很接近自己写,只是手变快了一点 我特别喜欢在这些场景用补全: 写样板代码:DTO 字段、简单的 getter/mapper、重复的校验

2026-10-14鱼鱼
MCP 协议入门:给 Agent 一个统一的“工具接口”
MCP 协议入门:给 Agent 一个统一的“工具接口”当 Agent 需要接入越来越多的外部能力——文件系统、数据库、GitHub、内部系统——每个工具都要自己写一套适配代码,非常繁琐 MCP(Model Context Protocol,模型上下文协议) 就是为了解决这个问题而提出的开放协议,由 Anthropic 发布,目标是让“AI 应用”和“外部工具/数据源”之间有一套统一的对接标准 本文从动机出发,讲清楚 MCP 的角色、能力、消息流程,带你用 SDK 写一个最小 Server,再用不依赖 SDK 的方式手写一遍协议交互来理解本质,最后总结安全注意事项、常见坑和 FAQ 从 N×M 到 N+M:Host、Client 与 Server 的分工

2026-10-14鱼鱼
Java中的协程(虚拟线程)探究
Java中的协程(虚拟线程)探究在Java最新的LTS版本 21中,终于实装了协程这一特性 当然,在这些诸如python、golang等轻量级语言中被称为协程的东西,在Java中有个全新的代号——虚拟线程,为了将协程与线程做区分,在Java21中,原Thread被称之为平台线程 下文中,将统一使用线程/协程的方式称呼 我们都知道,Java中引入了线程的概念,区别于系统中的进程 作为并发执行的最小单元,在一定的条件下,使用多个线程同时运作可以有效提高程序的运转效率 而线程这一能力源于系统本身而并非JVM 之所以说是在一定条件下,是因为受限于机器配置情况(CPU的运作机制、核心数),线程的同时运作并不能线性的提升运行性能,单个cpu并不能同时处理多线程任务,实际的运作方式是基于时间片分片,各个线程抢占式执行代码,这样能减少一些无效的io等待(例如网络io、磁盘io实际是会阻塞等待io结果),同时在多核心场景下也能有效利用cpu
![Java中的协程(虚拟线程)探究]()
2024-10-28鱼鱼
Agent 的工具调用日志:出了问题我先看哪几行
Agent 的工具调用日志:出了问题我先看哪几行Agent 一跑起来,日志可以很热闹:思考摘要、工具名、参数、返回、重试、最终回答……出了问题时,若从头通读,既慢又容易被模型的“自信叙述”带偏 我逐渐养成一个习惯:先不看它怎么说,先看它调用了什么、参数是否离谱、返回是否被误解 这篇文章记我排查 Agent 故障时的日志阅读顺序 偏工程经验,不是某家产品的官方手册 失败时我最想看的其实不是最终答复 答复是渲染后的故事,故事会把中间的错误抹平 更常见的情况是: 所以我把最终答案降级成线索,把工具轨迹升级成证据 图:先证据后故事:工具轨迹优先于最终答复(原创示意图) 只看序列:读文件 → 搜代码 → 改文件 → 跑测试 这种骨架

2026-10-14鱼鱼
Agent 的工具返回太长怎么办:截断、分页与摘要的取舍
Agent 的工具返回太长怎么办:截断、分页与摘要的取舍自己写 Agent 的时候,我最早关心的是工具怎么定义、参数怎么描述、调用失败怎么处理 工具返回什么,反而想得很少:命令跑完了,stdout 拿回来,原样塞进上下文,不就行了? 后来有一次让 Agent 排查一个线上问题,它调了一下读日志的工具 那个日志文件几十兆,工具老老实实全读回来了 结果要么是请求直接超出上下文上限报错,要么是在我加了粗暴截断之后,它看到前面几千行正常日志,得出结论“日志里没有发现异常” 真正的报错在文件末尾,它根本没看到 这件事让我意识到:工具返回多长、怎么变短,是 Agent 设计里一个独立的问题,而且没有银弹 常见的三种办法——截断、分页、摘要——各有各的代价

2026-10-16鱼鱼
Kafka服务端集群原理
Kafka服务端集群原理kafka是家喻户晓的消息队列,也因“纯粹”而闻名(高性能高吞吐、扩展较少较为简单),此篇文章整理Kafka的基本架构,将按照Kafka的版本迭代分别展示架构的演进(截至版本3.0) 我们在这里暂且只讨论Kafka服务端,对于生产者和消费者的逻辑简单带过 扫盲一下Kafka的部分概念: Producer mq生产者通用叫法 作为消息的生产者,在生产完消息后需要将消息投送到指定的目的地(某个topic的某个partition) Producer可以根据指定选择partition的算法或者是随机方式来选择发布消息到哪个partition; Consumer mq生产者通用叫法 消息消费者,向Kafka broker读取消息的客户端;,负责订阅和消费消息

2022-03-10鱼鱼
给仓库写一份 AGENTS.md:让 AI 编程助手少走弯路
给仓库写一份 AGENTS.md:让 AI 编程助手少走弯路用 AI 编程助手久了,你大概会有一种“祥林嫂”式的疲惫:每开一个新会话,就得把同样的话再说一遍 “我们用 pnpm,不是 npm ”“跑测试要加这个参数,不然会连真实数据库 ”“generated 目录下的代码是自动生成的,别改 ”“提交信息要按这个格式写 ” 说一次两次还好,说到第十次,就会开始怀疑人生 更糟糕的是,你偶尔忘了说,AI 就会理直气壮地按自己的默认习惯来,然后你再花时间收拾 解决这个问题的办法其实很朴素:把这些话写下来,放进仓库,让 AI 每次开工前自己读 这就是 AGENTS.md 要干的事 图片来源:rawpixel.com(CC0 1.0) 一句话:给 AI 看的 README

2026-10-14鱼鱼