加载中

Java

文章分类

浏览该分类下的所有文章

237 篇文章 20

面试现场【Redis篇】

面试围绕 Redis 的核心特性展开。小邹说明 Redis 4.0 前采用单线程模型,凭借内存操作、高效数据结构和 I/O 多路复用实现高速;4.0 起在异步删除等场景加入多线程。为防止数据丢失,Redis 提供 AOF、RDB 与二者结合的混合持久化,分别介绍了写后日志和快照的实现原理、风险及 bgsave 的子进程写盘方式。高可用方案包括主从复制、哨兵自动故障转移以及 Cluster。Cluster 通过 CRC16 计算键的哈希值并取模 16384,按槽位将数据分配给不同 Master,实现写扩展和存储扩容。

每日一题(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 引用不变的前提下,使其输出由“abc”变为“abcd”。常规做法如使用 StringBuilder.append 或 String.replace 均不可行,因为它们不会修改原始 String 对象本身。正确方案是通过反射访问并修改 String 内部的 value 字段(char[]),示例代码利用 Field.setAccessible(true) 绕过访问检查,将其设为新字符数组实现修改。但在 JDK 11 及更高版本运行时,会因 value 字段是 final 且受 JVM 常量折叠优化而抛出 IllegalArgumentException,提示非法的反射访问。文章由此说明了反射修改 final 字段的局限性及其在新 JDK 中的安全限制。

Dubbo最佳实战

本文介绍了 Apache Dubbo 的基本概念、特性及服务治理,推荐使用 Zookeeper 作为注册中心,并详细演示了基于 Maven 的实战项目构建流程。首先创建统一的 API 模块定义接口(HelloService),随后在 provider 模块引入 API、Dubbo 依赖并使用 @Service 注解实现接口、配置 dubbo‑provider.properties、log4j 与 RegistryConfig,将服务注册到本地 Zookeeper。接着在 consumer 模块同样引入 API 与 Dubbo 依赖,使用 @Reference 注入接口并编写消费组件,配置 dubbo‑consumer.properties。最后分别启动 Zookeeper、Provider 主程序和 Consumer 主程序,回车即触发远程调用并输出结果。完整代码已上传 GitHub,供读者参考学习。

使用HashMap的注意事项

本文通过两个示例说明HashMap键唯一的特性,尤其在使用自定义类作为键时必须重写`hashCode`和`equals`方法,否则会出现键冲突导致数据异常。并简要介绍了HashMap的底层实现:JDK8 之前为数组+链表,之后在链表长度超过阈值时转为红黑树;它是非线程安全的,键和值均可为`null`,键唯一而值可重复。使用HashMap时务必确保键的`hashCode`与`equals`正确实现,以保证正确的键唯一性判断。

Elasticsearch7.x实战指南

Elasticsearch 7.x 主要变化包括:废弃 TransportClient,只能使用 REST High‑Level Client;type 统一为 _doc 并将在 8.x 删除;默认分片数改为 1、节点名为主机名;Lucene 升级至 8,加入 weak‑and 与 intervals 查询提升相关性与顺序控制;集群协调去掉 minimum_master_nodes,新增熔断机制防 OOM;刷新策略在空闲时可跳过。文中提供索引、映射、文档的 CRUD 示例,介绍 geo_point、动态映射、dynamic_templates 以及 Query DSL 基础用法,帮助实现完整的 ES7 实战。

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

本文介绍仿MyBatis持久层框架的实现思路与关键代码。通过 sqlMapConfig.xml 配置数据源,mapper.xml 定义 SQL 与唯一标识(namespace.id),使用 Resources 将配置文件读取为流。XMLConfigBuilder 利用 dom4j 解析流并封装为 Configuration(保存 DataSource 与 MappedStatement 映射)和 MappedStatement(保存 id、resultType、parameterType、sql)。SqlSessionFactoryBuilder 根据解析结果创建 DefaultSqlSessionFactory,openSession 获取 SqlSession 实例,提供 selectList、selectOne 等 CRUD 方法,内部封装 JDBC 执行。核心类包括 Configuration、MappedStatement、Resources、SqlSession、DefaultSqlSession、SqlSessionFactoryBuilder,涉及 Builder、工厂、代理等设计模式。文中示例包括建表脚本、实体类、Mapper、Maven 依赖及完整代码,演示从配置读取到数据库查询的完整流程。

LinkedList常用API详解

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

集合工具类Collections详解

Collections 是 JDK 中 java.util 包的工具类,提供一系列静态方法,便于对集合进行操作。常用功能包括:排序(reverse、shuffle、sort、swap)、查找(binarySearch、max、min、frequency、fill)、同步包装(synchronizedList 等)以在多线程环境下安全使用集合、创建不可变集合(empty、singleton、unmodifiable)以及其他实用方法(addAll、disjoint)。文中通过代码示例展示了这些方法的使用效果,并指出在并发场景应优先使用 CopyOnWriteArrayList、ConcurrentHashMap 等并发集合。作者强调深入源码学习 Collections 的设计,可提升编码水平,体现工具类背后的深厚技术价值。

equals方法该如何重写?

文章说明了何时需要重写Object的equals方法——主要用于判断对象的“逻辑相等”,如在Map、Set等集合中作为键使用的值类;同时列举了无需重写的情形,如枚举、私有类或已在超类实现的情况。随后阐述了equals的五大契约(自反、对称、传递、一致、非空),并通过Date 与 Timestamp 的对称性失效示例提醒遵守规则的重要性。最后以java.util.AbstractSet 的实现为例,总结高质量 equals 的编写要点:①先检查引用相等;②使用 instanceof 验证类型;③必要时比较集合大小;④通过 containsAll 逐元素比较;⑤必须同步重写 hashCode;⑥保持参数类型为 Object,避免重载。

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

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

CGLIB与JDK动态代理

CGLIB和JDK动态代理都是通过生成代理类实现方法拦截,但原理不同:JDK代理只能为实现接口的类生成基于接口的代理,需要InvocationHandler和反射;CGLIB利用ASM在运行时生成目标类的子类,覆盖非final方法,不要求实现接口。Spring默认:bean实现接口时使用JDK代理,未实现接口时使用CGLIB,也可强制指定。性能上,JDK在JDK6+经过优化,调用少时更快;大量调用时CGLIB曾占优,但在JDK8后JDK已超越。CGLIB不能代理final类或方法,使用时需确保目标类可继承。两者的选择取决于目标类是否有接口以及对性能的具体需求。