Java 集合源码深度解析 —— ArrayList、LinkedList、HashMap、Set 设计内幕
前言Java 集合是面试八股文的必争之地。本文从源码视角出发,串联 ArrayList、LinkedList、HashMap、Set 等核心集合类的设计内幕,帮你理解它们为什么这样设计,而不仅仅是”记住”结论。 一、ArrayList 的底层真相:elementData1.1 核心结构1transient Object[] elementData; ArrayList 的所有元素都存储在这个 Object[] 数组中。你调用的 add(E e)、get(int index)、remove(int index) 等方法,本质上都是在操作这个数组: 1234public E get(int index) { Objects.checkIndex(index, size); return (E) elementData[index]; // 直接从数组取,O(1)} 1.2 为什么用 Object[] 而不是 E[]?Java 的泛型擦除机制决定了 JVM 层面不存在 E[]。编译后 E 就是 Object,所以底层直接用 Object[] 存储...
给 EduMind 项目做生产级加固:从审计到落地的完整复盘
前言前几天我干了一件事:对 EduMind做了一次多维度生产级审计。结果说实话不太好——六个 Critical、二十多个 High。 但审计本身不是目的,修才是。今天花了一天时间,挑了开发阶段真正值得修的问题逐一落地。这篇文章记录每个决策的考量:为什么选中它、思路是什么、做到什么程度停手。 一、什么该修,什么不该修审计报告里的问题不是每一条都值得立刻动手。我的筛选标准就一条: 这个问题在当前开发阶段会不会实际造成麻烦? 按照这个标准: 立刻修:可观测性(出问题没法排查)、核心逻辑没测试(改了不知道坏了)、API 层不统一(排查问题多一个变量) 顺便修:DTO 校验(加几个注解的事)、安全头(也是几行配置) 上线前修:JWT 密钥轮换、HTTPS、Redis 密码——这些本地用不上,但上线不能缺 不着急:Dashboard 改 Composition API、前端 i18n——纯代码清洁度问题 好,开工。 二、可观测性:从”盲飞”到”看见”为什么第一个修它审计时最让我震惊的不是安全问题,而是整个项目只有一行监控配置: 1management.endpoints.web....
第一次给开源项目提 PR?从"不敢交"到"被合并"的完整指南
我昨天给归藏的 guizang-ppt-skill 提了一个 PR,从满心忐忑到顺利发出,整个过程踩了不少坑,也学到了很多。这篇文章把完整的 PR 提交流程和踩坑经验分享出来,希望能帮到想做开源贡献但不敢迈出第一步的人。 背景我本地有一个 Claude Code Skill 的仓库,做了一些功能增强——WYSIWYG 编辑面板、PPTX 导出、文档提取器,加起来 1600 多行代码。我想把这些改动词贡献回上游,但有几个心理障碍: “我才改了这么点东西,好意思交吗?” “1600 行会不会太多,作者会烦吗?” “我直接推到一个新仓库算不算偷别人的代码?” “英文不好,commit message 写英文还是中文?” 如果你也有类似的顾虑,往下看。 第一步:搞清楚许可证,别怕”偷代码”很多新手以为”拿了别人的代码改名发布就是盗窃”——这是最大的误解。 去仓库根目录找 LICENSE 文件。guizang-ppt-skill 用的是 AGPL-3.0,这意味着: ✅ 可以 fork ✅ 可以修改 ✅ 可以重新发布、甚至改名 ⚠️ 必须保留原始版权声明和许可证 ⚠️ 衍生作品也必须...
从零搭建 CI/CD 流水线 — GitHub Actions 实战指南
前言最近我给一个 Spring Boot 4 + Vue 3 的前后端项目补全了测试和 CI/CD 体系。在这个过程中,CI 流水线经历了多次调试才全部通过。这些问题覆盖了环境一致性、平台差异、依赖冲突等几乎所有新手都会遇到的坑。 本文将以这次实战为线索,带你从零搭建一套完整的 CI/CD 流水线。读完你将能够: 理解 CI/CD 的概念和必要性 为自己的项目写出第一个 GitHub Actions 工作流 知道常见的坑和应对方法 一、CI/CD 是什么?为什么需要它?一句话理解1你 push 代码 → GitHub Actions 自动执行检查 → 全绿就放心了 CI(Continuous Integration,持续集成):每次提交代码,自动编译、测试、检查代码质量。确保”新代码没有搞坏旧功能”。 CD(Continuous Delivery / Deployment,持续交付/部署):CI 通过后,自动把代码部署到服务器。 一张图理解 CI/CD 在项目中的位置 PR(Pull Request...
AI 教学助手多课程支持——基于动态 Prompt 预设的 Agent 架构设计
问题:一个 Agent 怎么教多门课?我们有一个 AI 教学助手”海克斯”,基于 OpenClaw Agent 框架搭建,最初只服务于 C 语言课程。现在系统要扩展到多班级多课程——Python、Java、数据结构甚至数学、英语——问题来了: 每个课程的 System Prompt 都不一样。 C 语言需要引导指针和内存管理,Python 需要强调标准库和 pip 生态,数据结构需要聚焦算法复杂度。 最直接的想法:每门课创建一个独立的 Agent。但 OpenClaw 创建 Agent 需要命令行操作,让老师去敲 CLI?这门槛太高了。 我们需要一种方案:老师不需要碰命令行,在 Web 页面就能创建新课、配置 AI 行为。同时 Agent 本身只维护一套,不用新增。 核心思路:Agent 人格与课程知识的三层解耦1234567891011121314151617181920┌─────────────────────────────────────────────────┐│ OpenClaw ││...
Hexo Butterfly 美化
前言博客文章质量是内核,但视觉效果是第一印象。Butterfly 主题本身已经很能打,但默认配置下还有大量优化空间。这次一口气做了 10 项美化改动,每一项都只需要改配置或加几行 CSS,不需要改主题源码,不会影响后续升级。 最终效果:https://www.lkl-zero.top 一、预加载动画(Preloader)作用:页面首次加载时展示全屏 loading 动画,避免白屏和布局闪烁,大幅提升首屏体验。 1234# _config.butterfly.ymlpreloader: enable: true source: 1 # 1 = 全屏动画,2 = 进度条 二、点击涟漪效果作用:鼠标点击页面任意位置产生水波纹扩散,替代默认无反馈的点击体验,有质感但不喧宾夺主。 相比烟花和爱心特效,涟漪更克制、更耐看,适合技术博客。 JS123456789101112// source/js/click-ripple.jsdocument.addEventListener('click', function(e) { if (e.target...
Hexo Butterfly 接入 Twikoo 评论系统全流程——从零部署到填坑实战
为什么选 TwikooHexo Butterfly 支持的评论系统很多,选 Twikoo 的理由很简单: Butterfly 社区首选 — 教程多、踩坑成本低,遇到问题搜一下就能找到答案 MongoDB Atlas 免费 512MB — 纯文本评论用一辈子,且还在接受新用户(LeanCloud 已经对新用户关门了) Vercel 一键部署 — 不用买服务器,不用写一行后端代码 访客无需登录 — 填个昵称就能评论,对国内读者友好 内嵌管理面板 — 直接在评论区里管理,不用切到独立后台 全套方案完全免费,唯一的硬性要求是有个自定义域名——后面会说为什么。 整体架构1234567用户浏览器 ──→ 你的博客 (GitHub Pages) │ ├── 加载 twikoo JS (jsdelivr CDN) │ └── POST 请求 ──→ twikoo.你的域名.com (Vercel) ...
作业批改系统 · Java 八股速查清单(项目代码即题库)
阅读指南原则:代码是你写的,看一眼就能想起来。每道题 5 分钟足够。 一、Spring 核心(3 题)1. Spring Boot 自动配置原理?(文件:main.ts / DemoApplication)一句话:@SpringBootApplication 包含 @EnableAutoConfiguration → AutoConfigurationImportSelector 扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports → 按条件注解加载配置类。 你项目里:MybatisPlusAutoConfiguration、RedisAutoConfiguration、SecurityAutoConfiguration 都是这么加载的。 追问 “条件注解有哪些?”:@ConditionalOnClass(有 Redisson 才加载)、@ConditionalOnMissingBean(用户没自定义才加载)、@ConditionalOnProperty...
MCP 与 Function Calling 深度辨析——概念、关系与手写实现
开篇:一个常见的混淆做 AI 应用开发时,”MCP” 和 “Function Calling” 这两个词经常被混用。有人觉得它们是同一个东西,有人说 MCP 就是 Function Calling 的升级版。 都不对。它们不是替代关系,而是分工关系。 先给一个一句话结论,然后我们再拆开细讲: Function Calling 是 LLM 的”决策能力”(它决定要调哪个工具),MCP 是”通信协议”(定义了工具如何被发现和调用)。前者是脑力,后者是神经传导系统。 一、Function Calling:LLM 的”脑力”1.1 它到底是什么?Function Calling 是 LLM 的一项内置能力——模型在推理时,除了生成文本,还可以输出一个结构化的 “我想调这个函数” 的意图: 12345678{ "function": { "name": "searchKnowledge", "arguments": { "query"...
将一个 Spring Boot 项目从 4 分打磨到 6.5 分的生产级优化实录
项目背景一个基于 Spring Boot 4.0.4 + MyBatis-Plus + PostgreSQL + Redis + Vue 3 的 C 语言作业批改与教学管理平台。功能很完整——AI 批改、知识库 RAG、热力图分析、QQ Bot 通知、教案生成——但离生产级差距不小。 初始评估:4.0 / 10.0 一、安全加固1.1 JWT Token 泄露到日志JwtAuthenticationFilter.java 中三处把 token 完整或部分打印到了日志: 12345// 坏味道:完整打印 tokenlog.info("提取的token: {}", token);// 坏味道:打印 token 前 20 字符log.warn("Token验证失败,token: {}", token.substring(0, 20) + "..."); 修复:日志中只记录 path 和方法名,永远不输出 token 内容。同时发现该文件错误 import 了 reactor...









