Java学习这件事

深夜两点半,IDEA的暗色主题像一口深井。我盯着断点处闪烁的光标,监视窗口里HashMap.Node.next的地址值像某种现代诗——0x7f3812c4,0x7f3813e0,0x7f3812c4。

死循环。

我往后仰,颈椎发出细碎的响声。这是本周第三次在红黑树的fixAfterInsertion里迷路。旋转逻辑的注释写着“case 2: uncle is red”,而我的uncle指针固执地指向null。空调外机在嗡鸣,我想起四小时前放弃的解法——那套基于2-3-4树的实现,优雅得像数学证明,可惜在删除操作里崩了,ConcurrentModificationException如墓碑般立在控制台。

自学Java的第七个月,我卡在自写容器的性能优化上。官方TreeMap的源码像迷宫,Entry嵌套EntryrotateLeft里三行代码我画了七页草稿纸才理解指针重定向。网上的“十分钟理解红黑树”都是谎言,真正的理解需要血淋淋的调试——我见过凌晨四点的rebalance,它冷酷如手术刀。

这不是最难的部分。最难的是语义鸿沟:课本说“HashMap线程不安全”,轻描淡写。直到我的爬虫项目在八核服务器上跑出数据错乱,查了三天日志才发现resize()时的链表情形。那种感觉像在解一道没有题干的选择题,选项是随机生成的。

上周我尝试读java.util.concurrent的源码。AQS队列的CAS操作像某种黑魔法,注释里写“借鉴自Mesa论文”。我去搜论文,摘要里满是“线性化点”“内存可见性”。突然意识到自己在追踪一条无穷的引用链:Java引用了C++的实现,C++引用了CPU的原子指令,CPU手册指向硅晶的能带理论。而我最初只是想给ArrayList写个线程安全的包装。

同事说“会用就行”。但漏洞总在“用”之外显现:那次生产环境Full GC停顿了四秒,我被迫去学G1的跨代引用和SATB算法。JVM像座冰山,Java代码只是浮在水面的那一角。

有时会怀念刚学System.out.println的日子。那时错误很仁慈:拼写错误、少个分号。现在的错误是形而上的——对象逃逸分析失效,锁粗化与锁消除的微妙平衡,伪共享导致缓存行踩踏。调试器显示的栈帧像考古地层,最底层是hotspot/src/share/vm的C++代码,我无权访问。

但我仍在凌晨三点按下F9。光标跳转,balanceDeletioncase 3分支终于被触发。控制台吐出{3=red, 5=black, 7=red},一棵合法的红黑树在内存中展开。没有欢呼,我只是保存代码,关掉IDE。窗外环卫车在收垃圾,嗡鸣声与空调共振。

学Java学到深处,其实是在学计算机本身。每一个NullPointerException背后,都是指针在内存荒原上的失语;每一次OutOfMemoryError,都是地址空间对逻辑世界的温柔反驳。语言只是入口,真正的洞穴在地下三百层,那里没有“精通”,只有手电筒光束里飞扬的尘埃。

而我还在向下走。

posted @ 2026-01-04 19:48  111阳  阅读(2)  评论(0)    收藏  举报