0%

ConcurrentHashMap 深度解析(基于 JDK 8)

ConcurrentHashMap 是 Java 并发包(java.util.concurrent)中提供的线程安全的 Map 实现,专为高并发场景设计。它解决了传统 Hashtable 全表锁效率低下的问题,通过细粒度的同步机制(JDK 8 中为 CAS + synchronized)实现高效并发,是多线程环境下键值对存储的首选。

ConcurrentHashMap 核心特性

线程安全

通过细粒度同步机制(而非全表锁)保证多线程读写安全,不同桶(数组索引)的操作可并发执行,大幅提升并发效率。

高效并发

  • 读操作(get)无锁(依赖 volatile 保证可见性),性能接近 HashMap
  • 写操作(putremove)仅锁定哈希冲突的链表 / 红黑树头节点,不阻塞其他桶的操作。

不允许 null 键值

键(key)和值(value)均不能为 null,避免与 get 方法返回 null 的歧义(无法区分 “键不存在” 和 “值为 null”)。

支持原子操作

提供 putIfAbsentremove(带条件)、replace 等原子操作,无需额外同步即可实现线程安全的复合逻辑(如 “不存在则插入”“存在则更新”)。

弱一致性迭代器

迭代器遍历期间允许其他线程修改集合,不会抛出 ConcurrentModificationException(弱一致性),但可能无法实时反映最新修改。

底层结构与并发机制演变

ConcurrentHashMap 的底层结构随 JDK 版本演进,核心差异在于锁机制:

JDK 7:分段锁(Segment)

阅读全文 »

MapReduce 数据输出机制:OutputFormat 全面解析

在 MapReduce 框架中,数据输出阶段负责将 Reduce 任务的计算结果持久化到存储系统(如 HDFS)。OutputFormat 作为输出阶段的核心组件,决定了数据的输出格式、存储位置和写入方式。本文将从默认输出格式到自定义实现,深入解析 MapReduce 的数据输出机制。

OutputFormat 核心作用与架构

核心职责

OutputFormat 是 MapReduce 数据输出的抽象层,主要完成三项任务:

  • 数据写入:将 Reduce 输出的 <key, value> 键值对转换为目标格式(如文本、二进制);
  • 结果存储:将数据写入指定位置(如 HDFS 路径、本地文件系统);
  • 输出准备:创建输出目录、校验权限,确保输出路径不存在冲突。

架构层次

OutputFormat 采用抽象类 + 实现类的设计模式,层次结构如下:

1
2
3
4
5
6
7
OutputFormat(抽象类)  
├─ FileOutputFormat(文件输出基类)
│ ├─ TextOutputFormat(默认文本输出)
│ ├─ SequenceFileOutputFormat(序列文件输出)
│ ├─ MapFileOutputFormat(映射文件输出)
│ └─ MultipleOutputs(多路径输出)
└─ 自定义 OutputFormat(继承 FileOutputFormat 或 OutputFormat)

所有文件类输出格式均继承自 FileOutputFormat,它提供了文件输出的基础实现(如目录创建、路径校验),子类只需重写数据写入逻辑即可。

常用 OutputFormat 实现类详解

1. TextOutputFormat(默认文本输出)

阅读全文 »

JavaScript DOM 操作详解:节点操作与文档交互实战指南

DOM(Document Object Model,文档对象模型)是浏览器将 HTML 文档解析后形成的树形结构,JavaScript 通过 DOM 操作可以动态修改网页的内容、结构和样式。从 “DOM 基础概念→核心操作流程→实战场景→常见问题” 四个维度,系统讲解 DOM 操作的底层逻辑与实用技巧,帮你掌握动态网页开发的核心能力。

DOM 核心概念:节点与文档树

在进行 DOM 操作前,需先理解 “节点” 和 “文档树” 的基本概念 ——HTML 文档中所有内容(标签、属性、文本)都被抽象为 “节点”,这些节点按层级关系组成 “文档树”。

1. 三种核心节点类型

HTML 文档中的节点主要分为三类,每种节点的特性和用途不同:

节点类型 描述 示例(基于 <p title="remark">备注</p> 核心属性(nodeType/nodeName/nodeValue
元素节点 HTML 标签(如 <p><div><li>),是文档树的 “骨架”,可包含子节点 <p> 标签本身 nodeType: 1nodeName: 标签名大写(如 P);nodeValue: null(元素节点无此属性)
属性节点 元素节点的属性(如 titleidclass),依附于元素节点存在 title="remark" 属性 nodeType: 2nodeName: 属性名(如 title);nodeValue: 属性值(如 remark
文本节点 元素节点内的文本内容(如标签中的文字、空格、换行),是元素节点的子节点 <p> 标签内的 “备注” 文本 nodeType: 3nodeName: #textnodeValue: 文本内容(如 备注
关键补充:
  • 除上述三种外,DOM 还有注释节点(nodeType: 8)、文档节点(documentnodeType: 9)等,但日常开发中以 “元素 / 属性 / 文本节点” 为主;
  • 节点关系:元素节点可包含子节点(文本节点、其他元素节点),属性节点是元素节点的 “附属”,不参与文档树的层级关系。

2. 文档树结构

HTML 文档被解析后,节点按 “父子、兄弟” 关系组成树形结构,例如:

阅读全文 »

MapReduce 数据输入机制:InputFormat 深度解析

在 MapReduce 框架中,数据输入阶段是处理流程的起点,负责将原始数据读取、分片并转换为 Map 任务可处理的键值对。InputFormat 作为数据输入的核心组件,决定了数据如何分片、如何读取以及如何转换为键值对。本文将从 InputSplit 原理到具体实现类,全面解析 MapReduce 的数据输入机制。

InputFormat 核心作用与架构

核心职责

InputFormat 是 MapReduce 数据输入的抽象层,主要完成三项任务:

  • 数据分片:将输入数据分割为若干 InputSplit(逻辑分片),每个分片对应一个 MapTask;
  • 读取数据:通过 RecordReader 将 InputSplit 转换为 <key, value> 键值对,供 Map 函数处理;
  • 校验输入:检查输入路径的有效性,确保数据可访问。

架构层次

InputFormat 采用抽象类 + 实现类的设计模式,层次结构如下:

1
2
3
4
5
6
7
InputFormat(抽象类)  
├─ FileInputFormat(文件输入基类)
│ ├─ TextInputFormat(默认文本输入)
│ ├─ KeyValueTextInputFormat(键值分隔输入)
│ ├─ NLineInputFormat(按行数分片输入)
│ └─ CombineTextInputFormat(小文件合并输入)
└─ 自定义 InputFormat(继承 FileInputFormat 或 InputFormat)

所有文件类输入格式均继承自 FileInputFormat,它提供了文件分片的基础实现,子类只需重写数据读取逻辑即可。

InputSplit:逻辑分片的核心

InputSplit 本质

InputSplit 是 MapReduce 对输入数据的 逻辑分片,代表 MapTask 处理的数据范围。它并非实际存储数据,而是记录了数据的位置信息长度信息

  • 长度:分片的字节大小,用于排序分片(优化 MapTask 调度);
  • 位置:存储该分片数据的 DataNode 节点列表(用于本地化调度,优先将 MapTask 分配到数据所在节点)。
阅读全文 »

MapReduce深度解析:从原理到实践

MapReduce 是 Apache Hadoop 的核心计算框架,它通过将大规模数据处理任务分解为多个独立的小任务(Map 和 Reduce),实现了分布式并行计算。本文将从设计理念、工作流程到编程模型进行全面解析,并通过实际案例展示其应用。

MapReduce 设计理念:分而治之

核心思想

MapReduce 的设计灵感来源于函数式编程中的 MapReduce 操作:

  • Map:将输入数据解析为键值对(K-V),并对每个键值对进行独立处理;
  • Reduce:对 Map 输出的键值对按 key 分组,聚合处理相同 key 的所有 value。

这种 “分而治之” 的思想使得大规模数据处理可以并行化,显著提升效率。

适用场景

MapReduce 适合处理 海量数据的批处理任务,例如:

  • 日志分析(如统计访问量、错误率)
  • 数据挖掘(如词频统计、协同过滤)
  • 大规模数据聚合(如求和、平均值计算)
  • 数据转换(如格式转换、ETL 操作)

MapReduce 工作流程详解

整体架构

MapReduce 作业(Job)由三个核心组件协同完成:

  • MrAppMaster:负责作业调度、资源分配和状态监控;
  • MapTask:并行处理输入数据,生成中间结果;
  • ReduceTask:聚合 Map 输出的中间结果,生成最终输出。
阅读全文 »