-
Java工具类应追求“用得越少越稳”,Objects.equals()防空指针、Collections.emptyList()避免误修改、StringUtils.isBlank()专注无副作用判空,核心是职责收敛与契约明确。
-
Java变量不应以下划线开头,因违反官方驼峰命名规范,易与自动生成代码混淆,触发IDE警告及静态检查工具报错,并可能干扰序列化/反射;正确写法为userId、maxRetryCount等,例外仅限对接外部协议时通过注解映射。
-
应优先通过jstat监控OU/MU持续上涨及unloaded为0定位内存泄漏,配合HeapDumpOnOutOfMemoryError生成堆转储,用MAT的DominatorTree分析RetainedHeap,重点排查ThreadLocal、静态集合及动态代理类加载器持有问题。
-
@Async默认不生效,因需显式启用@EnableAsync且必须通过Spring代理调用;常见失效原因包括未启用异步支持、本类内直接调用、方法非public、使用this调用等。
-
Future.get()必须带超时参数,否则会无限阻塞;cancel(true)仅对可中断任务有效;CompletableFuture回调需避免同步阻塞;异常需显式调用get()或handle()才能捕获。
-
受检异常是编译期契约而非强制加锁,用于显式建模外部依赖的不确定性;适用于可预见且可恢复的失败(如IO、SQL异常),需try-catch或throws处理,空catch、泛化捕获、盲目throws属典型误用。
-
Android自4.4引入打印框架起,系统PrintManager就强制要求调用必须发生在Activity上下文中;Service、Application或BroadcastReceiver等非Activity组件调用会抛出IllegalStateException,该限制在Android11及更高版本中依然严格生效。
-
ConcurrentHashMap1.7通过Segment数组实现分段锁,每个Segment是独立的ReentrantLock+小型哈希表,put仅锁定对应Segment,get完全无锁;但存在哈希倾斜退化、size()阻塞等问题,故1.8改用CAS+synchronized锁单个Node并引入树化优化。
-
throw是实际抛出异常对象,throws是声明可能抛出的异常类型;throw后接new创建的异常实例,throws后接异常类名;一个方法可多处throw,但throws只在方法签名中声明一次。
-
类加载器间是委托链而非继承关系,通过构造参数传递父加载器引用实现双亲委派;自定义加载器默认父为AppClassLoader,Bootstrap无父且由JVM用C/C++实现。
-
应选Java17或21(LTS)版本,优先下载EclipseTemurin或BellSoftLiberica的OpenJDK安装包;Windows选.msi、macOS选.pkg、Linux注意确认JAVA_HOME路径;配置时JAVA_HOME须指向JDK根目录,PATH添加$JAVA_HOME/bin;验证需java-version与javac-version双命令一致;IDE需单独配置SDK。
-
Java标签必须紧跟冒号且仅用于for、while、do-while前,是语法锚点;命名同变量规则;带标签break仅向上跳转至同名标签语句,仅适用于多层循环提前退出。
-
Class对象由JVM类加载时自动创建,不可new;获取方式有String.class、obj.getClass()、Class.forName();反射调用需区分getMethod与getDeclaredMethod;Field操作性能差且易空指针;转型须校验类型防ClassCastException。
-
EnumMap的get/put是O(1)且无哈希开销,因其直接用枚举ordinal()作数组下标访问内部values数组,省去HashMap全套哈希计算与结构维护流程。
-
top找出Java进程PID后,为什么top-H显示的线程ID和jstack里的nid对不上因为top-H默认显示的是Linux线程的十进制TID(ThreadID),而jstack输出里nid=0x...是十六进制的nativethreadID。直接比对会漏掉真凶。用printf"%x\n"把top-H看到的十进制TID转成小写十六进制,再和jstack输出里的nid=0x7f8a对照注意:JDK8u60+默认