...小于 1 分钟
- Java211
- 编程14
- 设计79
- DevOps8
- 数据结构和算法17
- 树6
- 综合17
- 线性表4
- 数据库114
- 网络19
- 分布式78
- 大数据32
- 软件工程3
- 工作8
- 笔记52
- JavaCore65
- JavaEE15
- 软件20
- 工具37
- 框架71
- 中间件9
- 编程范式4
- 编程语言3
- Python6
- 架构31
- 设计模式27
- 重构7
- DDD2
- UML4
- 监控2
- 数据库综合3
- 数据库中间件3
- 关系型数据库21
- 文档数据库12
- KV数据库18
- 列式数据库15
- 搜索引擎数据库22
- 网络综合8
- 网络协议6
- 网络技术4
- 操作系统13
- 操作系统应用2
- 分布式综合15
- 分布式协同18
- 分布式调度7
- 分布式通信29
- 分布式存储8
- flink9
- hadoop5
- hive9
- 人工智能1
- 基础特性18
- 高级特性7
- 容器7
- IO10
- 并发11
- JVM9
- 面试12
- JavaWeb6
- 服务器8
- 构建9
- IDE4
- 监控诊断6
- JavaBean2
- 模板引擎4
- 测试5
- 其他9
- Spring61
- ORM4
- 安全9
- 缓存5
- 流量控制2
- 微服务5
- 解决方案8
- Git3
- mysql15
- mongodb11
- redis19
- KV 数据库3
- hbase13
- elastic5
- elasticsearch16
- Linux11
- 命令1
- 分布式协同综合10
- ZooKeeper7
- RPC5
- MQ17
- 效能6
- 方法论2
- 规范3
- Tomcat6
- Maven7
- Spring综合5
- Spring核心24
- Spring数据10
- SpringWeb8
- SpringIO4
- Spring集成4
- Spring安全1
- Spring其他4
- MQ综合1
- Kafka10
- RocketMQ4
- 其他MQ1
Java IO 框架
📖 内容
📚 资料
...小于 1 分钟
Java 虚拟机面试二
垃圾收集
【困难】如何判断 Java 对象是否可以被回收?
判断 Java 对象是否可以被回收有两种方法:
- 引用计数法
- 可达性分析法
引用计数法
引用计数算法(Reference Counting)的原理是:在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。
引用计数算法简单高效,但是存在循环引用问题——两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。
...大约 22 分钟
MyBatis 面试
【简单】MyBatis 中 #{} 和 ${} 的区别是什么?
MyBatis 中 #{}
和 ${}
的区别对比
特性 | #{} (预编译占位符) |
${} (字符串拼接) |
---|---|---|
底层原理 | 使用 PreparedStatement ,生成带 ? 的 SQL,预编译防止注入。 |
直接拼接字符串到 SQL 中,无参数化处理。 |
SQL 注入风险 | ❌ 安全(自动转义特殊字符)。 | ✔️ 高风险(需手动过滤参数)。 |
适用场景 | 动态条件值(如 WHERE id = #{value} )。 |
动态表名、列名(如 ORDER BY ${column} )。 |
数据类型处理 | 自动识别 Java 类型,匹配 JDBC 类型(如 Date →TIMESTAMP )。 |
原样替换,可能导致语法错误(如字符串未加引号)。 |
性能 | 预编译 SQL 可复用,高效。 | 每次生成新 SQL,效率较低。 |
示例 | xml SELECT * FROM user WHERE name = #{name} |
xml SELECT * FROM ${tableName} |
...大约 7 分钟
《极客时间教程 - Java 核心技术面试精讲》笔记
开篇词 以面试题为切入点,有效提升你的 Java 内功
略
谈谈你对 Java 平台的理解?
【典型回答】
Java 最显著的特性:
- “书写一次,到处运行”(Write once, run anywhere)——跨平台
- 垃圾收集(GC, Garbage Collection)——回收、分配内存
Java 既是解释型语言,又是编译型语言
...大约 71 分钟
《极客时间教程 - Java 并发编程实战》笔记三
Immutability 模式:如何利用不变性解决并发问题?
解决并发问题,其实最简单的办法就是让共享变量只有读操作,而没有写操作。这个办法如此重要,以至于被上升到了一种解决并发问题的设计模式:不变性(Immutability)模式。所谓不变性,简单来讲,就是对象一旦被创建之后,状态就不再发生变化。换句话说,就是变量一旦被赋值,就不允许修改了(没有写操作);没有修改操作,也就是保持了不变性。
快速实现具备不可变性的类
...大约 40 分钟
《极客时间教程 - Java 并发编程实战》笔记四
案例分析(一):高性能限流器 Guava RateLimiter
Guava 是 Google 开源的 Java 类库,提供了一个工具类 RateLimiter。
【示例】使用 RateLimiter 限流
//限流器流速:2 个请求/秒
RateLimiter limiter = RateLimiter.create(2.0);
//执行任务的线程池
ExecutorService es = Executors.newFixedThreadPool(1);
//记录上一次执行时间
prev = System.nanoTime();
//测试执行 20 次
for (int i = 0; i < 20; i++) {
//限流器限流
limiter.acquire();
//提交任务异步执行
es.execute(() -> {
long cur = System.nanoTime();
//打印时间间隔:毫秒
System.out.println((cur - prev) / 1000_000);
prev = cur;
});
}
// 输出结果:
// ...
// 500
// 499
// 500
// 499
...大约 38 分钟
《极客时间教程 - Java 并发编程实战》笔记一
学习攻略 如何才能学好并发编程?

开篇词 你为什么需要学习并发编程?
并发编程可以总结为三个核心问题:分工、同步、互斥。
...大约 26 分钟
《极客时间教程 - Java 并发编程实战》笔记二
Lock 和 Condition(上):隐藏在并发包中的管程
再造管程的理由
已有 synchronized,还支持 Lock 的原因是,需要一把锁支持:
- 能够响应中断。synchronized 的问题是,持有锁 A 后,如果尝试获取锁 B 失败,那么线程就进入阻塞状态,一旦发生死锁,就没有任何机会来唤醒阻塞的线程。但如果阻塞状态的线程能够响应中断信号,也就是说当我们给阻塞的线程发送中断信号的时候,能够唤醒它,那它就有机会释放曾经持有的锁 A。这样就破坏了不可抢占条件了。
- 支持超时。如果线程在一段时间之内没有获取到锁,不是进入阻塞状态,而是返回一个错误,那这个线程也有机会释放曾经持有的锁。这样也能破坏不可抢占条件。
- 非阻塞地获取锁。如果尝试获取锁失败,并不进入阻塞状态,而是直接返回,那这个线程也有机会释放曾经持有的锁。这样也能破坏不可抢占条件。
...大约 43 分钟
《极客时间教程 - 深入拆解 Java 虚拟机》笔记
开篇词 为什么我们要学习 Java 虚拟机?

Java 代码是怎么运行的?
从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。
...大约 25 分钟
...