加载中

Java

文章分类

浏览该分类下的所有文章

237 篇文章 20

哈希

hashCode() 与 equals() 是 HashMap 正确定位键值对的关键,未正确实现会导致冲突或误判相等,影响集合的精确性。HashMap 以键的 hash 值定位桶,JDK7 采用数组+链表(头插),JDK8 在链表长度超过阈值后转为红黑树(尾插),容量为 2 的 n 次幂,扩容依据初始容量和加载因子(默认 0.75)。HashMap 是非同步的键值对散列表,key、value 可为 null,映射无序。构造一致性哈希时在 2^32 环上放置节点并顺时针寻找最近节点,实现高伸缩性且最小化迁移。作为键的 Object 必须保证 hashCode 不变。HashSet 仅保存唯一元素且无序。

本文围绕 Java 中的树结构及其算法要点展开。说明 TreeSet、TreeMap 必须存放实现 Comparable 的对象,Collections.sort 可使用对象自身的 compareTo 或外部 Comparator 实现排序,并给出 Student 实现 Comparable 的示例。随后介绍二叉树的常见操作:层序遍历(返回数组或逐层换行)、递归与非递归求树深度、利用层次遍历求最大路径长度。最后简要比较 B+ 树和 B‑树:前者内部节点不存数据、叶节点链式连接、适合外部存储及区间查询;后者键值同存,查询复杂度受键位置影响。

遍历

本文展示了两类遍历的实现示例。第一段给出二叉树的 Z 字型层序遍历算法,利用队列按层遍历并通过布尔标记控制奇偶层的顺序逆转,实现左右交替输出。第二段实现了文件系统的递归遍历,使用 `File.listFiles()` 获取目录内容,区分文件与子目录,对文件直接打印名称,对目录则递归调用,以遍历指定文件夹及其所有子文件夹中的所有文件。两段代码均突出遍历思路的核心要点。

链表

本文围绕单向链表的典型面试题展开,首先介绍利用快慢指针判断链表是否成环的思路;随后指出在哈希桶中使用链表存储的缺点——查找慢且频繁插删性能低。接着给出奇数位升序、偶数位降序链表转为整体升序的解法:按奇偶位拆分为两链表、反转偶数链、再合并。随后展示复制含随机指针的链表的三遍遍历实现,以及最常见的单链表反转算法(遍历中逐节点翻转指针)。全文提供了对应的 Java 实现代码示例。

数组

本文列举了多个常见的数组面试题并给出 Java 实现思路:① 通过层层交换实现矩阵顺时针 90° 旋转;② 利用全部元素异或找出唯一出现一次的数;③ 使用哈希表求和为目标值的两数配对;④ 采用 Kadane 算法求连续子数组的最大和;⑤ 通过快速选择(基于快排划分)获取数组前 K 大元素或第 K 大值。每段代码均标明考点与核心算法要点。

排序

文章先给出Java实现的冒泡排序示例,然后列出常见排序算法分类:插入、交换、选择、归并、分配等。接着阐述归并排序的分治合并过程、堆排序利用大顶堆/小顶堆的建堆与调整。随后介绍在数据流中通过最大堆和最小堆维护左右两侧数据,以 O(log n) 插入、O(1) 取中位数的思路求中位数。最后简要说明快速排序的分区策略及其时间复杂度。

堆与栈

文章阐述了 JVM 内存的三大区域及其作用:堆(heap)存放所有对象实例,由程序员通过 new 创建,垃圾回收自动释放;栈(stack)为每个线程独有,仅保存基本类型变量和对象引用,由编译器自动分配回收,遵循后进先出;方法区/静态区(static area)与堆共享,保存类信息、static 变量和全局常量。对比堆栈,堆空间大、动态分配但访问慢,需手动申请;栈空间小、自动管理、访问快但生存期受限。通过示例说明了对象创建、引用存放及字符串常量池的不同存储方式。

队列

PriorityQueue 是基于堆实现的无界队列,元素按自然顺序或自定义比较器排序。它不接受 null,非线程安全,入队和出队的时间复杂度均为 O(log n)。

高级算法

本文围绕几类常见算法展开说明。首先介绍 LRU(最近最少使用)缓存的原理、核心 get/put 接口、实现要点及其命中率、复杂度和空间成本。随后阐述后缀(逆波兰)表达式无需括号即可表达运算优先级的优势。接着给出基于 MD5 的 URL 压缩思路:先对原链接做 32 位 MD5 加密,再加工生成短链。随后详细解释 SnowFlake 分布式唯一自增 ID 的 64 位结构(符号位、41 位时间戳、10 位机器码、12 位序列)及其优缺点。最后提供 LFU(最不常用)缓存的 O(1) 实现方案,包括节点与项的双向链表设计、频率提升与淘汰逻辑的完整代码示例。

设计模式

本文介绍了面向对象设计的六大原则——单一职责、里氏替换、依赖倒置、接口隔离、迪米特、开闭原则,阐述其含义与作用,重点说明开闭原则对复用、维护、灵活性和测试的提升。随后给出单例模式的饿汉式、懒汉式及线程安全实现代码示例。最后分析工厂模式的概念,分别展示简单工厂和工厂方法的实现思路与示例代码,强调将对象创建职责抽象化、分离的优势。

场景题

微信红包采用实时内存计算、随机分配算法,使用Redis缓存和CAS更新防超额;秒杀系统通过独立库存库、动态URL、页面静态化、Redis集群、Nginx、限流、异步下单等手段解决超卖和高并发;扫码登录基于 token,PC 生成二维码 ID,移动端扫码绑定一次性 token,确认后下发正式 token 完成登录;单点登录依赖认证中心生成授权令牌,子系统校验后创建局部会话,实现统一登录与注销;本地缓存设计关注数据结构、容量上限、LRU/FIFO 等清除策略、过期时间及线程安全。

UML

UML提供多种图形化符号用于描述系统的静态结构和动态行为,常见的包括用例图、类图、时序图、协作图、状态图、活动图、构件图和部署图等。其中,用例图用于捕获需求、展示系统功能模块及其关系;类图描述类及类间关联,帮助快速了解系统的结构;时序图刻画对象之间的交互及执行顺序,展示对象可接收的消息和提供的服务。这三类图被视为UML中最核心的。