JUC-3

上一篇讲了线程的状态和切换方法,还讲了 AQS 的关键概念。这一篇我打算学习 AQS 的常见实现、并发容器,还有阻塞队列和线程池。 AQS 的常见实现 上一篇提到 AQS 核心内容就是:state + 等待队列。接下来我会讲解 ReentrantLock、Semaphore、CountDownLatch 等常见实现。 ...

2026年9月10日 · 17 分钟 · 8311 字 · withdong02

JUC-2

上一篇的概念是真多,这一篇应该代码多,大头是 AQS。 Lock 接口 上一篇结尾讲到了 synchronized,但它由于设计上的原因,有几个无法满足灵活需求的特性: ...

2026年9月4日 · 11 分钟 · 5265 字 · withdong02

JUC-1

之前没有集中学习过线程、锁、并发容器和线程池等,学习时间一直很散,希望能通过这两三天的学习使自己对 java 并发编程的理解进一步加深。 我打算分三篇来记录,这是第一篇。 ...

2026年9月3日 · 6 分钟 · 2528 字 · withdong02

十种排序算法整理

十种排序算法 冒泡排序 一共进行 n - 1 轮,在每一轮排序中对相邻两元素进行比较,大的排在后面。 /** * 冒泡排序 * 时间复杂度:最优 O(n),最坏 O(n²),平均 O(n²) * 空间复杂度:O(1),原地排序 * 稳定性:稳定 */ private static void bubbleSort(int[] arr) { int n = arr.length; boolean flag = true; for (int i = 0; i < n - 1; i++) { flag = true; for (int j = 0; j < n - 1 - i; j++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1); flag = false; } } if (flag) break; } } 选择排序 同样进行 n - 1 轮,每一轮从待排序序列中挑出最小的元素,将其放至已排序序列的末尾。 ...

2026年4月16日 · 7 分钟 · 3164 字 · withdong02

笔试收获

参加了一次笔试,收获颇多。 不同的输入方法 和力扣不一样,一些大厂的笔试包括面试时的算法题都是 ACM 模式,也就是需要自己处理输入,然后对输入处理并输出,而力扣是核心代码模式,不用你管输入,只需要实现指定方法,平台自会调用你的方法。在参加之前,我去卡码网上了解了一下,发现还是 Scanner 那一套,也就没在意,但当我真正开始做的时候感到有点不对,Scanner 恐怕不太够用。这篇博客主要讲一下 Java 里的输入流。 ...

2026年3月29日 · 5 分钟 · 2059 字 · withdong02

LeetCode8.字符串转换整数

一切源于一道题目:8. 字符串转换整数 (atoi) - 力扣(LeetCode) 考虑这样一个问题:给你一个数字字符串,如何在32位环境下安全的处理可能超过[-2^31, 2^31 - 1]范围的数字,不能使用64位变量临时存储。 ...

2026年2月15日 · 2 分钟 · 807 字 · withdong02

Java集合源码阅读

先附上二哥网站上关于集合框架的结构图 版本为JDK21 ArrayList 扩容机制 先介绍一下 ArrayList 中的关键变量: transient Object[] elementData 底层用来存储元素的数组 private int size; 表示集合中元素的实际数量 private static final int DEFAULT_CAPACITY = 10; 默认初始容量 private static final Object[] EMPTY_ELEMENTDATA = {}; 当用户调用 new ArrayList(0) 时,elementData 会引用该数组。 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 当用户调用默认构造参数时会引用该数组。 private Object[] grow(int minCapacity) { int oldCapacity = elementData.length; if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, /* minimum growth */ oldCapacity >> 1 /* preferred growth */); return elementData = Arrays.copyOf(elementData, newCapacity); } else { return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)]; } } private Object[] grow() { return grow(size + 1); } 上面是有关扩容的源代码。 ...

2026年1月26日 · 8 分钟 · 3605 字 · withdong02

Java泛型

泛型定义 先看这样一个例子: public static void main(String[] args) { List list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); for (int i = 0; i < list.size(); i++) { System.out.println((String)list.get(i)); } } ArrayList集合中可以加入任何类型的对象,我本意是用这个集合来存储字符串(因为ArrayList默认存储的是Object类型的对象,所以输出时需要强转 ),但我粗心的写错了list.add(123),在我运行后发现报错java.lang.ClassCastException,显然报错原因就是输出时Integer类型并不能强转为String类型。那么如何避免这种情况呢,答案就是泛型。 ...

2025年10月14日 · 9 分钟 · 4469 字 · withdong02

正则表达式

介绍 正则表达式(regular expression),常简写为regex,用简单字符串来描述、匹配文中全部匹配指定格式的字符串。人话讲就是根据一些规则制定一个字符串,然后你可以用这个字符串来筛选满足规则的字符串。许多程序设计语言都支持用正则表达式操作字符串,这里主要介绍正则表达式在Java中的运用。 ...

2025年9月22日 · 7 分钟 · 3479 字 · withdong02

Java反射

什么是反射 在spring项目中,只需要写个@Service或者@Component,然后在别的地方用@Autowired声明一个接口变量,Spring就能返回给我们一个实现了该接口的具体对象。这是如何实现的呢?它不可能在编译时就知道加了注解的类与类之间的关系,所以只能是在程序启动运行时,Spring动态地发现了这些类,读取了他们的结构,然后创建对象。这背后的技术支撑又是什么?答案就是反射。 ...

2025年8月10日 · 7 分钟 · 3295 字 · withdong02