技术拾遗
Created|Updated|Java
|Word Count:189|Reading Time:1mins|Post Views:
Java
Java 8
Lambda
Java 8 Lambdas - A Peek Under the Hood
What does $$ in javac generated name mean?
-
lambda 表达式并不总是持有外部 enclosing object 的引用,如果它不访问任何外部变量,即不持有这样的引用。只要设计一个对比实验,就会发现引用过外部变量的lambda实例才会产生一个 arg 的隐式参数引用。而内部类内部总是含有一个
this$0。 -
lambda表达式是词法作用域的-意思是不产生新的作用域,不产生任何shadowing问题。它可以无缝访问外部作用域的东西,就好像从一个 if block 里访问一个方法里的其他变量一样。但,同样地,不能声明新变量。
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2026-05-18
从 Java 8 到 Java 25 的迁移与 Spring 升级指南
Java 8 发布于 2014 年,距今已逾十年。尽管 Oracle 对 Java 8 的商业支持延续至 2030 年,但语言特性、运行时性能、安全补丁以及生态兼容性已显著落后于当前主流版本。Spring Boot 3.0 起将基线提升至 Java 17,Spring Framework 6 全面转向 Jakarta EE 命名空间,这意味着继续使用 Java 8 的团队将在框架升级、依赖兼容性以及云原生部署方面面临越来越高的隐性成本。 本文梳理从 Java 8 迁移到 Java 25(当前最新 LTS)的完整路径,并同步覆盖 Spring Boot 2.x 到 3.x 的升级要点。内容基于 Oracle 官方迁移指南、Spring 项目 Wiki、OpenJDK JEP 文档以及生产环境的实际迁移案例。 LTS 版本路线图与迁移节奏 Java 采用严格的半年发布周期,每三年指定一个 LTS(Long-Term Support)版本。从 Java 8 到 Java 25,历经四个 LTS 节点: 版本 发布时间 LTS 状态 关键特性 Java 8 2014-0...

2018-10-13
卡表和 RSet
卡表和 RSet 问题定义:为什么需要跨区域引用记录 JVM 垃圾收集器的核心工作之一是确定 live set——哪些对象仍然存活、不可回收。确定 live set 的标准做法是从 GC Roots(栈帧中的局部变量、静态字段等)出发,沿引用链遍历所有可达对象。 问题在于:当堆被划分为多个区域(代、Region)并且只回收其中一部分时,如何高效地找到从"不回收区域"指向"回收区域"的引用? 以 Young GC 为例:只回收新生代,但老年代中可能持有指向新生代对象的引用。如果不处理这些跨代引用,就会错误地回收仍被老年代引用的新生代对象。最朴素的做法是扫描整个老年代来找出这些引用——但老年代通常远大于新生代,这样做的代价过高,违背了分代收集"只回收一部分堆"的初衷。 卡表(Card Table)和 RSet(Remembered Set)正是为解决这个问题而设计的辅助数据结构。二者的关系并非互相替代,而是层次不同、协作互补:卡表是底层的脏标记机制,RSet 是建立在卡表之上的更高层索引结构。 核心概念速览 在深入细节之前,...
2026-05-21
lambda 演算入门:函数为什么足够表达计算
图灵机用纸带、读写头和指令循环描述计算。lambda 演算换了一条路:它不用可变纸带,也不用状态跳转,只保留函数定义、函数调用和变量替换。 这个模型看起来比图灵机更不像机器,却和图灵机有同等表达能力。图灵机强调“有限控制怎样改写存储”,lambda 演算强调“表达式怎样通过函数应用逐步化简”。从工程角度看,它把计算从指令循环翻译成表达式重写。 本文先建立 lambda 演算的最小语法,用 Python 表示变量、函数和调用,再通过一个小例子展示函数怎样返回函数、调用怎样变成替换。 三种表达式 lambda 演算的核心语法只有三种。 形式 示例 含义 变量 x 一个名字 函数 x -> x 接收参数 x,返回表达式 x 调用 (x -> x) a 把函数应用到参数 a 函数也叫抽象,调用也叫应用。为了贴近 Java 程序员熟悉的形式,本文用 x -> x 表示 lambda 表达式,而不用希腊字母写法。 最小模型可以写成一棵表达式树: 1234Expression = Variable(name) | Function(param...
2017-10-23
昂贵的异常
抛出问题 Joshua Bloch 在《Effective Java》的 Item 57 里明确地提到过,不要试图用 Exception 的跳转来代替正常的程序控制流。他列举了很多原因,但特别提到了抛出异常会使得整个程序运行变慢。抛出异常远比普通的 return、break 等操作对控制流、数据流的性能影响要大,它就只适合拿来作异常分支的控制语句,而不能拿来编写正常的逻辑。 Throwing exception is expensive. 这句话在 Java 的程序员世界里面已经成为老生常谈,却很少有人谈及到底抛出异常比正常的程序跳转返回慢在哪里,有多慢。"不要滥用异常"好像一个猴子定律,人们知道不能这么做,却不明白为什么不能这么做。 此前读了一位同事写的好文《Java虚拟机是如何处理异常的》,深入地分析了 JVM 对异常跳转的处理过程:JVM 会通过异常表的机制,优化异常抛出和正常返回之间的性能差异。仅从程序计数器的移动上来讲,抛出一个异常对栈帧的弹栈并不比直接返回更昂贵。写在前头的结论是:"try-catch 语句块几乎不会影响程序运行性能!...
2021-10-09
JDK 的广泛分支
Oracle Hospot JDK java 8 特定版本以后就不再免费了。 现有的JDK8,2019.1之前的更新都可以免费获取正常使用。 Oracle JDK11是一个长期支持的版本,用于商业环境需要付费。 Azul Zulu builds of OpenJDK Zulu 是Azul公司基于OpenJDK发布的Java SE产品,它没有Oracle JDK对使用场景上的诸多限制,可以放心免费下载和使用。它的核心部分就是原汁原味的OpenJDK,没有任何额外的改动——Azul有时候也会对OpenJDK做bug fix,但这些都是通过提交回到OpenJDK去然后再进入到Zulu Java SE产品中的。它与“自己下载OpenJDK源码,自己build”的最大区别是:Azul会在每次发布Zulu产品之前进行充分的测试,build出来的二进制版本符合Java的兼容性测试;同时,Azul有与Oracle签订合作协议,在critical security fix的方面会比公开发布的OpenJDK源码要更早获得补丁,提前做好build与测试工作,基本上可以跟Oracle在同一时...
2020-02-27
hive 汇总
Hive 操作符和函数汇总 Hive 架构概述 Hive 是构建在 Hadoop 之上的数据仓库基础设施,提供类 SQL 的查询语言 HQL,将查询转换为 MapReduce、Tez 或 Spark 任务执行。 核心组件 MetaStore 存储表的元数据信息,包括表结构、分区、列类型、序列化/反序列化规则等 支持多种存储后端:Derby(默认)、MySQL、PostgreSQL 可配置为远程服务模式,支持多客户端并发访问 Driver 接收查询请求,生成执行计划 编译器:解析 HQL,生成语法树,进行语义分析 优化器:基于规则和成本的查询优化 执行引擎:将逻辑计划转换为物理执行计划 执行引擎 MapReduce:早期默认引擎,适合大规模批处理 Tez:基于 DAG 的执行引擎,减少中间结果落盘 Spark:基于内存计算,显著提升查询性能 Hive 数据模型 Database 数据库是命名空间的逻辑容器,对应 HDFS 上的目录路径。 Table Hive 表分为两种类型: 管理表(内部表):删除表时删除元数据和数据 外部表:删除表时仅删除元数据,保留数据 Par...
Contents
