38 归档分页
370 留言互动
4 核心专题

操作系统(四)

Linux 内存管理包括硬件层次(寄存器、CPU 缓存、主存、外存)和软件机制。通过虚拟内存把连续的虚拟地址映射到离散的物理页,使用多级页表、TLB 与大页降低转换开销。内核将页划分为 ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM 等区域,并在 NUMA 系统中按节点独立管理。Page cache 缓解磁盘 I/O,匿名内存、回收、compact 与 OOM killer 负责内存碎片与不足的处理。段页机制实现地址空间隔离,分页提供细粒度映射;mmap 直接把文件映射到进程虚拟地址,省去 page cache 的二次拷贝。整体目标是提高访问效率、实现进程隔离并在内存紧张时保证系统稳定。

操作系统(五)

文章介绍了Linux的I/O模型,包括阻塞、同步非阻塞、IO多路复用、信号驱动和异步IO,并比较其优缺点;阐述了软链接与硬链接的概念、区别及使用场景;说明缺页中断的触发条件、处理流程以及与普通中断的差异;区分软中断与硬中断的产生方式、可屏蔽性和响应机制;最后解释了Copy‑On‑Write技术在fork等场景中的实现原理、优势和限制。

哈希

hashCode() 与 equals() 决定了键在 HashMap 中的定位与比较,若实现不当会导致冲突或误判相等,直接影响集合的准确性。HashMap 以键值对存储,使用键的 hashCode 计算数组下标并在冲突时通过链表或 JDK8 起的红黑树保存,支持 put/get 的快速访问;容量与负载因子决定扩容时机,扩容后桶数保持 2 的幂次。HashMap 不是同步的,key、value 可为 null,映射无序。构造一致性哈希时在 2³² 环上放置节点,按键的 hash 顺时针定位最近节点,提升扩缩容时的路由稳定性。作为键的对象必须保证 hashCode 在生命周期内不变。HashSet 仅保存唯一元素,内部基于 HashMap 实现,存取无序。

本文围绕树结构的常见面试考点展开,首先说明 TreeSet 与 TreeMap 在排序时分别要求元素或键实现 Comparable 接口,或在 Collections.sort 中提供 Comparator 实现自定义比较;随后给出实现 Comparable 的 Student 示例以及 TreeSet 的使用演示。接着介绍二叉树的层序遍历、深度求解(递归与非递归两种实现)以及计算任意两节点最长路径的思路,并提供相应的 Java 代码片段。最后简要比较 B+ 树与 B‑树:前者内部节点不存数据、叶层链表化、查询复杂度固定为 log n,适合外部存储和区间查询;后者键值同存、查询复杂度随键位置变化。

遍历

本文通过两个 Java 示例说明遍历的基本思想。第一个示例实现二叉树的 Z 字型层序遍历,利用队列逐层访问节点并通过布尔标记在奇偶层之间切换顺序,必要时对当前层结果进行反转。第二个示例演示文件系统的递归遍历,使用 `File` 类遍历指定目录,若遇文件直接输出名称,若遇子目录则递归调用以遍历其全部子文件,实现对整个文件夹及其子文件夹的完整遍历。两段代码均突出遍历的实现方式和常用技巧。

链表

本文围绕单向链表的常见面试题展开,首先介绍使用快慢指针判断链表是否成环的原理;随后指出在哈希桶中使用链表存储会导致查找、插入、删除效率低下;接着给出奇数位升序、偶数位降序链表转为整体升序的思路——按奇偶位拆分为两链表、将偶数链表逆序再合并,并提供完整实现代码;随后展示 O(1) 额外空间的随机指针链表复制算法;最后给出标准的单链表反转实现。整体阐述了链表环检测、性能缺陷、排序合并、深拷贝及反转等关键技术要点。

数组

本文介绍了几道常见的数组面试题及其核心思路:① 用层层交换实现二维矩阵顺时针旋转90°;② 利用全体异或找出唯一不成对的元素;③ 通过哈希表在 O(n) 时间内求和为 S 的两数下标;④ 使用 Kadane 算法求连续子数组最大和;⑤ 采用快排划分(或堆)实现前 K 大元素的快速查找。每个实现均给出关键代码示例。

排序

本文先给出Java实现的冒泡排序代码示例,随后列出常见排序算法分类:插入、交换、选择、归并、分配等,并简要说明各子类。接着阐述归并排序的分治合并过程、堆排序通过构建大(小)顶堆并不断取堆顶的原理。再介绍在数据流中实时获取中位数的做法:使用最大堆保存左半部分、最小堆保存右半部分,插入为O(log n),取中位数为O(1)。最后给出快速排序的划分思路及双指针交换过程。

堆与栈

文章阐述了 Java 内存划分:堆区存放对象实例,由所有线程共享,需通过 new 分配,由垃圾回收器回收;栈区为每线程私有,仅存基本类型值和对象引用,由编译器自动分配释放,访问速度快;方法区(静态区)存放类信息、static 与全局变量,同样共享。对比堆与栈:堆容量大、手动/GC 分配、访问相对慢;栈容量小、自动分配、后进先出、访问快。并通过字符串创建示例说明两者在实际使用中的差异。