-
最稳妥的方式是使用BlockingQueue而非手写wait/notify,因其天然线程安全、阻塞语义明确、边界处理完整;手写易出现唤醒丢失、虚假唤醒、未用while循环检查条件及锁粒度不合理等问题。
-
Java支持Unicode,可直接在字符串中使用Unicode字符(如"你好""?"),需确保源文件为UTF-8编码;也可用\u转义序列(如\u4F60)表示任意Unicode字符;超出BMP的字符(如emoji)可用代理对(\uD83C\uDDFA)或直接输入;处理码点时应使用codePointCount()和codePointAt()方法准确计数与访问。推荐使用UTF-8编码并优先直接书写Unicode字符以提升可读性。
-
ReadWriteLock允许多个读线程并发访问,写线程独占访问,适用于读多写少场景;其核心为ReentrantReadWriteLock实现,提供readLock()和writeLock(),遵循读读不互斥、读写互斥、写写互斥原则,支持锁降级与可重入,建议在finally中释放锁,可通过构造函数选择公平或非公平模式以平衡吞吐与饥饿问题。
-
相同单词未合并是因为未统一大小写、未清除标点及空格残留,导致“Hello!”与“hello”等被视为不同键;需toLowerCase()、正则清理、判空后计数,并慎用Scanner分隔符。
-
JNA比JNI更适合纯Java项目调用本地库,因其无需编写C头文件、编译或打包.so/.dll,仅需Java接口+注解即可运行时自动解析符号;但要求函数签名严格匹配,存在性能开销与内存控制限制。
-
不建议用异常控制正常业务流程,因性能开销大、掩盖设计问题;应将可预期失败转为返回值或状态码,异常仅用于真正意外场景,并需分层定义、规范日志与处理。
-
推荐使用Objects.isNull(str)||str.isBlank()(Java11+)或StringUtils.isBlank(str)(Java8),二者均安全、简洁且正确识别null、空字符串及全空白字符,避免NPE与逻辑空遗漏。
-
泛型类通过类型参数实现类型安全的代码复用,如Box<T>可指定T为String等具体类型;泛型方法在声明中引入类型参数,如printArray<T>(T[]array)可处理不同类型的数组;Java泛型通过类型擦除实现,运行时泛型信息被擦除,导致不能newT()或使用instanceof检查泛型类型;通配符?配合边界extends和super限制类型范围,提升API灵活性与安全性。掌握泛型需多练习定义与使用类型参数。
-
Collectors.toList()返回可变ArrayList,支持重复和null;toSet()返回无序去重Set,遇null抛NPE;toMap()遇重复key抛DuplicateKeyException;joining()遇null直接抛NPE;应依约束选方法。
-
工厂模式解决对象创建的耦合问题,通过工厂统一生成实例,符合开闭原则;策略模式封装可变的行为算法,实现运行时动态切换,避免冗长条件判断。两者结合时,常由工厂创建具体策略对象,既解耦创建过程,又灵活替换行为,提升代码可维护性与扩展性。
-
重写clone()仍为浅拷贝,因Object.clone()仅复制字段值,对引用类型不递归拷贝;需手动深拷贝可变引用字段,否则修改副本会影响原对象。
-
volatile通过强制每次读取从主内存加载、每次写入立即刷回并使其他缓存失效,解决“修改不可见”问题;但它不保证复合操作原子性,也不能替代synchronized处理多步逻辑或状态协同。
-
字符串转数字前必须先校验合法性,避免直接解析抛异常;推荐用正则粗筛或ApacheCommonsNumberUtils等成熟工具,并注意各语言特性差异。
-
getDeclaredConstructor()找不到私有构造函数最常见的原因是参数类型不匹配(如int.class与Integer.class混淆)或目标构造器不在当前类声明中;必须用setAccessible(true)才能调用,且需注意Java9+模块封装和Android兼容性问题。
-
CompressedClassSpace是JVM中专用于存储压缩Klass指针的固定大小内存区域(默认1G),与Metaspace分离;其OOM表明该区域耗尽,常见于动态代理频繁、类加载器泄漏场景。