-
标记清除算法导致老年代内存碎片的核心原因是只回收垃圾对象而不移动存活对象,使空闲空间离散分布;老年代对象长期存活、数量多且体积大,无法采用复制算法,只能就地标记清除,最终因缺乏连续空间而频繁触发FullGC甚至OOM。
-
Java数组是引用类型,声明需明确元素类型和维数,推荐写法为int[]array;初始化分静态(如int[]arr={1,2,3})和动态(如int[]arr=newint[5])两种;访问越界抛ArrayIndexOutOfBoundsException。
-
重写clone()仍为浅拷贝,因Object.clone()仅复制字段值,对引用类型不递归拷贝;需手动深拷贝可变引用字段,否则修改副本会影响原对象。
-
volatile通过强制每次读取从主内存加载、每次写入立即刷回并使其他缓存失效,解决“修改不可见”问题;但它不保证复合操作原子性,也不能替代synchronized处理多步逻辑或状态协同。
-
字符串转数字前必须先校验合法性,避免直接解析抛异常;推荐用正则粗筛或ApacheCommonsNumberUtils等成熟工具,并注意各语言特性差异。
-
getDeclaredConstructor()找不到私有构造函数最常见的原因是参数类型不匹配(如int.class与Integer.class混淆)或目标构造器不在当前类声明中;必须用setAccessible(true)才能调用,且需注意Java9+模块封装和Android兼容性问题。
-
CompressedClassSpace是JVM中专用于存储压缩Klass指针的固定大小内存区域(默认1G),与Metaspace分离;其OOM表明该区域耗尽,常见于动态代理频繁、类加载器泄漏场景。
-
浮点数比较必须用带精度的断言,裸写==几乎总是错的,因IEEE754二进制表示存在固有精度损失(如0.1+0.2≠0.3),且编译器优化、平台差异等会放大偏差;iOS应使用XCTAssertEqualWithAccuracy,Pytest用pytest.approx,JUnit需借助AssertJ等第三方库;误差值须为正、匹配数值量级,避免整数隐式转换、单位混淆或未mock随机源。
-
groupingBy嵌套summarizingInt不能直接两层因后者返回IntSummaryStatistics而非Collector;正确做法是外层groupingBy分组、内层summarizingInt统计,结果为Map<String,IntSummaryStatistics>。
-
new出来的对象不一定在堆上,因逃逸分析可判定其是否逃逸:未逃逸时JVM可栈上分配或标量替换;方法逃逸或线程逃逸则必须堆分配。
-
必须通过反射获取theUnsafe字段并setAccessible(true),JDK9+还需--add-opens参数;allocateMemory返回的地址需手动管理生命周期,重复free或越界访问将导致JVM崩溃。
-
Java9起接口可用private方法抽取多个default方法共用逻辑,既复用代码又不暴露给实现类;它专用于接口内部封装校验、日志、格式化等重复行为,仅限本接口内default或static方法调用,不可被实现类访问或反射调用。
-
推荐组合优于继承,因其更契合业务可变性与可控性:组合明确区分“拥有什么功能”和“是什么类型”,避免继承的脆弱基类、单继承限制、语义失真及封装泄露问题,支持运行时切换、易测试与高内聚。
-
基本数据类型比较用==和!=,浮点数需考虑精度误差,推荐使用容差范围判断相等;大小比较可借助包装类的compareTo方法,但注意自动装箱影响性能,高频操作应优先使用原始类型和直接运算符。
-
观察者模式通过被观察者状态变化时自动通知所有依赖的观察者实现一对多更新,常用于事件处理、GUI交互与数据同步;核心为Subject维护Observer列表并触发update方法,Java中可通过自定义接口或过时的Observable类实现,适用于解耦事件源与处理逻辑,需注意性能与内存泄漏问题。