加载中

Java

文章分类

浏览该分类下的所有文章

237 篇文章 20

面试现场【Redis篇】

Redis 早期单线程、I/O 多路复用,避免锁竞争,4.0 起加入多线程用于异步删除。持久化有 AOF(追加日志)和 RDB(快照),4.0 增加混合持久化。AOF 写后日志易丢失且阻塞,RDB 通过 save(阻塞)和 bgsave(子进程)生成快照,bgsave 不阻塞写操作。高可用方式包括主从复制、哨兵自动故障转移和 Cluster。Cluster 将键经 CRC16 哈希映射到 16384 个槽位,由不同节点负责,实现写入、存储扩展。

每日一题(2022/1/20)

代码演示了 Java 中字符串比较的细节。`s1` 通过 `new String("xiaozou")` 在堆中创建了独立对象,`s2` 直接引用常量池中的字面量,两者地址不同,`s1 == s2` 为 `false`。调用 `s1.intern()` 时,若常量池已有相同内容的字符串,则返回该池中对象的引用,否则将其加入池中。因为常量池已经存在 `"xiaozou"`,`s3` 获得的正是 `s2` 的引用,故 `s2 == s3` 为 `true`。文章通过源码解释说明了 `intern()` 的工作原理及其在字符串共享中的作用。

每日一题(2022/1/19)

题目要求在不改变 `s` 引用的前提下,使 `System.out.println(s)` 输出 `abcd`。常规做法如 `StringBuilder.append()` 或 `String.replace()` 均无法实现,因为它们不会修改原 `String` 对象。正确方法是使用反射访问并修改 `String` 的私有 final 字段 `value`(字符数组),示例代码通过 `Field value = s.getClass().getDeclaredField("value"); value.setAccessible(true); value.set(s, "abcd".toCharArray());` 实现。需注意,在 JDK 11 及以后,修改 final 字段会触发非法反射访问并抛出 `IllegalArgumentException`,因为 JVM 对 `String` 常量做了编译期优化,禁止此类操作。

Dubbo最佳实战

本文概述了 Apache Dubbo 的定位、特性及服务治理,推荐使用 Zookeeper 作为注册中心,并通过一个完整的实战案例演示 Dubbo 的使用流程。案例采用 Maven 构建,分别创建 API、Provider、Consumer 三个模块,利用接口约定、@Service 与 @Reference 注解完成服务提供与调用,并给出相应的配置文件、启动类及运行步骤,展示了从注册中心注册、服务暴露到消费者调用的全链路实现,所有代码已托管于 GitHub。

使用HashMap的注意事项

HashMap 的键必须唯一,判断唯一性先比较 hashCode 再用 equals。对自定义类作键时必须重写这两个方法,否则即使属性相同也会被当作不同键。JDK8 及以后,HashMap 底层由数组、链表和冲突时的红黑树组成,支持键和值为 null,且键唯一、值可重复。示例代码演示了未覆写方法导致的重复键问题以及覆写后正常工作的情况。

Elasticsearch7.x实战指南

Elasticsearch7.x 实战指南概述了7.x 的核心改动与使用方法。指出 TransportClient 被废弃,推荐使用 High‑level REST client;type 被统一为 _doc,默认分片数改为 1,节点名为主机名;Lucene 升级至 8,加入 weak‑and 与 intervals 查询提升相关性;新增熔断机制、移除 minimum_master_nodes 参数。文档详述索引、映射、文档增删改查操作,并示例 geo_point、动态映射、dynamic_templates、Query DSL 等高级功能,帮助开发者快速上手并优化 ES7 集群。

自定义持久层框架(仿MyBatis)

本文介绍了仿 MyBatis 的自定义持久层框架实现思路。通过 sqlMapConfig.xml、mapper.xml 配置数据源和 SQL,使用 dom4j 将 XML 解析成 Configuration 与 MappedStatement 对象。核心类包括 SqlSessionFactoryBuilder、DefaultSqlSession、SqlSession 接口及其 CRUD 实现,封装 JDBC 完成查询。框架采用 Builder、Factory、Proxy 等设计模式,并给出完整的项目结构、依赖配置、实体类和示例 mapper 的代码示例,演示了从建表、配置到调用 selectList、selectOne 的完整流程。

LinkedList常用API详解

文章系统性介绍了 Java LinkedList 的常用 API,包括 peek/peekFirst/peekLast(获取头、首、尾元素但不删除)、poll/pollFirst/pollLast(获取并删除头、首、尾元素)、offer/offerFirst/offerLast(在尾部、头部或末尾插入元素)及其返回值含义。随后通过一个完整的示例代码展示了这些方法的具体调用及运行结果,帮助读者直观理解各 API 的行为和使用场景。

集合工具类Collections详解

Collections 是 JDK 提供的集合工具类,位于 java.util,封装了大量静态方法,方便对 List、Set 等进行常见操作。文章按功能划分介绍了:① 排序与置换(reverse、shuffle、sort、swap 等)并给出示例代码;② 查找与统计(binarySearch、max、min、frequency、fill),说明二分查找需先排序;③ 线程安全包装(synchronizedList 等),比较其实现与旧的 Vector/Hashtable,推荐使用并发包的 CopyOnWriteArrayList、ConcurrentHashMap;④ 不可变集合(emptyXxx、singletonXxx、unmodifiableXxx),演示调用后抛出 UnsupportedOperationException;⑤ 其他实用方法(addAll、disjoint)。最后强调阅读源码、理解 JDK 设计的重要性,认为 Collections 不仅是便利工具,更是提升编码水平的学习材料。

equals方法该如何重写?

在Java中,只有在需要判断对象的“逻辑相等”时才应重写equals,例如作为Map、Set的键或值类;若实例唯一、类私有或已继承合适实现,则无需重写。重写时必须遵守五大原则——自反、对称、传递、一致、非空——并同步重写hashCode,保持参数类型为Object,使用==检查同一实例、instanceof 验证类型、先比较大小提升性能,最后逐字段比较。违反这些规则会导致不对称等错误,如Date与Timestamp的equals示例所示。

如何使用Java程序读取zip文档?

本文介绍了在 Java 中使用 `ZipInputStream` 读取 ZIP 文档的基本方法。首先在 Maven 中加入 `commons-io` 依赖,然后通过 `ZipFile` 与 `ZipInputStream`(指定 GBK 编码)打开压缩包,使用 `getNextEntry()` 循环遍历每个 `ZipEntry`,打印路径并对非目录且以 `.txt` 结尾的文件读取内容,利用 `IOUtils.readLines` 将流转为字符串列表。代码示例展示了完整的文件读取、文本输出以及资源的安全关闭,运行后可在控制台打印出压缩包内所有文件及 txt 文件内容。

CGLIB与JDK动态代理

JDK 动态代理只能为实现接口的类生成代理,依赖 InvocationHandler 与反射,适用于有接口的目标对象;CGLIB 通过 ASM 生成目标类的子类,覆盖非 final 方法,可对没有接口的类进行代理。Spring 默认对实现接口的 bean 使用 JDK 代理,未实现接口时使用 CGLIB,也可在配置中强制使用 CGLIB。JDK 代理在 JDK6 以后性能得到优化,少量调用时更快;大量调用时 CGLIB 仍有优势,但在 JDK8 之后 JDK 已超越。CGLIB 不能代理 final 类或方法,且需额外库。两者的实现原理、使用场景及性能差异如上。