万能网站浏览器/知识营销案例

万能网站浏览器,知识营销案例,江苏建设厅网站更新,重庆专业网站开发服务1. 概述 为什么需要ConcurrentHashMap? 解决HashMap线程不安全问题:多线程put可能导致死循环(JDK7)、数据覆盖(JDK8) 优化HashTable性能:通过细粒度锁替代全局锁,提高并发度 对比…
 

1. 概述

为什么需要ConcurrentHashMap?

  • 解决HashMap线程不安全问题:多线程put可能导致死循环(JDK7)、数据覆盖(JDK8)

  • 优化HashTable性能:通过细粒度锁替代全局锁,提高并发度

对比表

特性HashMapHashTableConcurrentHashMap
线程安全
锁粒度无锁全局锁分段锁/CAS+synchronized
并发性能极低
Null键/值允许不允许不允许

JDK版本差异

  • JDK7:基于Segment分段锁(默认16段)

  • JDK8+:数组+链表+红黑树,使用CAS + synchronized锁头节点


2. 线程安全实现机制

JDK8的锁优化

final V putVal(K key, V value, boolean onlyIfAbsent) {// ...for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0)tab = initTable();else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {// CAS插入新节点(无锁)if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value)))break;}else if ((fh = f.hash) == MOVED)tab = helpTransfer(tab, f);else {synchronized (f) { // 锁住链表头节点// 处理链表/红黑树插入}}}// ...
}
  • CAS:用于无竞争情况下的快速插入(如空桶)

  • synchronized锁头节点:仅锁定当前哈希桶,不影响其他桶操作


3. 核心数据结构

Node节点结构

static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;volatile V val;volatile Node<K,V> next;// ...
}
  • volatile修饰:保证可见性,确保读线程能立即看到更新

  • 红黑树节点TreeNode继承Node,用于处理长链表(阈值=8)

扩容机制

  • 触发条件:元素数量超过sizeCtl

  • 多线程协助:通过ForwardingNode标记正在迁移的桶,其他线程可参与迁移


4. 关键源码解析

以下是对 ConcurrentHashMap 核心源码的深度解读,结合 JDK8 的实现进行分析:


4.1核心方法源码解析

1. 初始化:initTable()
private final Node<K,V>[] initTable() {Node<K,V>[] tab; int sc;while ((tab = table) == null || tab.length == 0) {// sizeCtl < 0 表示其他线程正在初始化if ((sc = sizeCtl) < 0)Thread.yield(); // 让出 CPU,等待初始化完成else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) { // CAS 抢锁try {// 双重检查,防止重复初始化if ((tab = table) == null || tab.length == 0) {int n = (sc > 0) ? sc : DEFAULT_CAPACITY;Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];table = tab = nt;sc = n - (n >>> 2); // 计算扩容阈值(0.75n)}} finally {sizeCtl = sc; // 释放锁,设置阈值}break;}}return tab;
}
  • CAS 抢锁:通过 sizeCtl 标记初始化状态(-1 表示初始化中)。

  • 双重检查:避免多线程重复初始化。

  • 负载因子固定为 0.75:通过 sc = n - (n >>> 2) 实现。


2. put 方法:putVal()
final V putVal(K key, V value, boolean onlyIfAbsent) {if (key == null || value == null) throw new NullPointerException();int hash = spread(key.hashCode()); // 计算哈希(高位参与运算)int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0)tab = initTable(); // 懒初始化else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) { // 桶为空if (casTabAt(tab, i, null, new Node<>(hash, key, value))) // CAS 插入break;} else if ((fh = f.hash) == MOVED) // 正在扩容tab = helpTransfer(tab, f); // 协助扩容else {V oldVal = null;synchronized (f) { // 锁住头节点if (tabAt(tab, i) == f) { // 再次验证头节点未变if (fh >= 0) { // 链表节点binCount = 1;for (Node<K,V> e = f;; ++binCount) {K ek;if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) {oldVal = e.val;if (!onlyIfAbsent)e.val = value; // 更新值break;}Node<K,V> pred = e;if ((e = e.next) == null) {pred.next = new Node<>(hash, key, value); // 追加到链表尾部break;}}} else if (f instanceof TreeBin) { // 红黑树节点Node<K,V> p;binCount = 2;if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, value)) != null) {oldVal = p.val;if (!onlyIfAbsent)p.val = value;}}}}if (binCount != 0) {if (binCount >= TREEIFY_THRESHOLD) // 链表长度 >=8treeifyBin(tab, i); // 可能树化if (oldVal != null)return oldVal;break;}}}addCount(1L, binCount); // 更新元素计数return null;
}

关键逻辑

  1. 哈希计算spread() 方法通过 (h ^ (h >>> 16)) & HASH_BITS 保证哈希值为正数。

  2. CAS 插入空桶:若桶为空,直接通过 casTabAt 插入新节点(无锁优化)。

  3. 锁头节点处理冲突:对非空桶使用 synchronized 锁定头节点,处理链表或红黑树。

  4. 树化条件:链表长度 >=8 且数组长度 >=64 时树化,否则优先扩容。

  5. 并发扩容协作:若发现桶正在迁移(MOVED 标记),当前线程会协助迁移。


3. 扩容机制:transfer()
private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {int n = tab.length, stride;// 计算每个线程处理的桶区间(最小 16)if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)stride = MIN_TRANSFER_STRIDE;if (nextTab == null) { // 初始化新数组try {Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];nextTab = nt;} catch (Throwable ex) { sizeCtl = Integer.MAX_VALUE; return; }nextTable = nextTab;transferIndex = n; // 迁移起点为旧数组末尾}// 多线程协同迁移逻辑ForwardingNode<K,V> fwd = new ForwardingNode<>(nextTab);boolean advance = true;boolean finishing = false;for (int i = 0, bound = 0;;) {Node<K,V> f; int fh;while (advance) {int nextIndex, nextBound;if (--i >= bound || finishing)advance = false;else if ((nextIndex = transferIndex) <= 0) {i = -1;advance = false;} else if (U.compareAndSwapInt(this, TRANSFERINDEX, nextIndex,nextBound = (nextIndex > stride ? nextIndex - stride : 0))) {bound = nextBound;i = nextIndex - 1;advance = false;}}// 实际迁移逻辑(略,处理链表/树拆分到新数组)}
}

核心设计

  1. 多线程任务分配:通过 transferIndex 全局指针分配迁移区间(类似“工作窃取”)。

  2. ForwardingNode 占位符:迁移中的桶会被标记为 ForwardingNode,读请求会转发到新数组。

  3. 链表拆分优化:根据哈希值的高位决定节点留在旧桶还是迁移到新桶(newIndex = oldIndex + oldCap)。


4. 无锁读:get()
public V get(Object key) {Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;int h = spread(key.hashCode());if ((tab = table) != null && (n = tab.length) > 0 &&(e = tabAt(tab, (n - 1) & h)) != null) {if ((eh = e.hash) == h) {if ((ek = e.key) == key || (ek != null && key.equals(ek)))return e.val; // 命中头节点} else if (eh < 0) // 特殊节点(红黑树或 ForwardingNode)return (p = e.find(h, key)) != null ? p.val : null;while ((e = e.next) != null) { // 遍历链表if (e.hash == h && ((ek = e.key) == key || (ek != null && key.equals(ek))))return e.val;}}return null;
}

无锁保障

  • tabAt() 使用 Unsafe.getObjectVolatile 保证读取最新内存值。

  • 链表遍历期间依赖 volatile 修饰的 next 指针保证可见性。

  • 遇到 ForwardingNode 时自动跳转到新数组查询。


4.2.关键优化总结

优化点实现方式
锁粒度仅锁单个桶的头节点(JDK8),替代 JDK7 的分段锁
CAS 无锁插入空桶通过 casTabAt 直接插入,避免锁竞争
多线程协作扩容通过 ForwardingNodetransferIndex 分配任务区间
计数优化使用 CounterCell[] 分散竞争,避免 size() 成为性能瓶颈
红黑树退化机制当树节点 <=6 时退化为链表,避免频繁树化开销

4.3源码分析的思考题

  1. 为什么在链表长度超过 8 时可能选择扩容而不是直接树化?

    • 数组较短时(<64),扩容能更有效减少哈希冲突。

  2. 如何保证扩容期间读操作的正确性?

    • 通过 ForwardingNode 将读请求转发到新数组,写操作会等待迁移完成。

  3. size() 方法为什么不是精确值?

    • 高并发场景下精确统计代价过高,采用分片计数(CounterCell)近似值。


5. 并发操作分析

扩容期间读写协调

  • 读操作:遇到ForwardingNode时转到新表查询

  • 写操作:协助迁移当前桶后再执行插入

线程协作扩容

private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {// 每个线程处理一个区间,完成后再领取新区间
}
  • 通过stride步长划分任务区间

  • 使用transferIndex指针协调多线程任务分配


6. 总结

设计亮点

  • 锁分离:降低锁竞争概率

  • 乐观锁优先:CAS无锁化尝试

  • 粒度细化:从分段锁到桶级别锁

  • 无锁读:volatile变量保证可见性

7.面试回答模板

面试官:请说一下ConcurrentHashMap的实现原理。 回答

ConcurrentHashMap在JDK1.8中采用了数组+链表/红黑树的结构,通过CAS和synchronized实现高并发。

  1. 写操作:如果桶为空,用CAS插入头节点;否则锁住头节点处理链表或红黑树。

  2. 读操作:完全无锁,依赖volatile保证可见性。

  3. 扩容:多线程协作迁移数据,通过ForwardingNode标记已处理的桶。

  4. 线程安全:锁粒度细化到单个桶,结合CAS减少竞争。 对比HashTable,它的并发性能更高,且支持更高的并发度。


8.源码分析技巧

  1. 关注核心方法putValgettransfer(扩容)、helpTransfer

  2. 调试参数:通过-XX:+PrintConcurrentLocks观察锁竞争情况。

  3. 结合JMM:分析volatile变量(如tablesizeCtl)的内存可见性保证。

9.常见面试题

以下是关于 Java ConcurrentHashMap 的常见面试题及其详细解答,涵盖底层实现、线程安全机制、性能优化等核心内容:


1. ConcurrentHashMap 如何实现线程安全?

回答要点

  • JDK7 的分段锁(Segment): 将整个哈希表分成多个段(默认 16 段),每个段独立加锁,不同段的操作可以并发执行。

    • 优点:降低锁粒度,减少竞争。

    • 缺点:内存占用较高(每个段独立维护数组),并发度受段数限制。

  • JDK8 的 CAS + synchronized 锁优化

    • CAS 无锁插入:当桶为空时,直接通过 CAS 插入新节点,避免加锁。

    • synchronized 锁头节点:当桶非空时,仅锁住链表或红黑树的头节点,锁粒度细化到单个桶。

    • 扩容协作:多线程可以协同迁移数据,减少扩容时间。


2. ConcurrentHashMap 与 HashMap、HashTable 的区别?

特性HashMapHashTableConcurrentHashMap
线程安全非线程安全全局锁(方法级同步)CAS + 细粒度锁(桶级别)
Null 键/值允许禁止禁止
性能高(无锁)极低(全局锁)高(并发优化)
迭代器一致性快速失败快速失败弱一致性
实现机制数组+链表+红黑树数组+链表数组+链表+红黑树(JDK8+)

3. JDK7 和 JDK8 的 ConcurrentHashMap 实现差异?

  • JDK7

    • 基于 分段锁(Segment),每个段类似一个独立的哈希表。

    • 默认 16 段,并发度固定,无法动态扩展。

    • 内存占用较高(每个段维护独立的数组)。

  • JDK8

    • 抛弃分段锁,采用 CAS + synchronized 锁头节点,锁粒度细化到单个桶。

    • 引入 红黑树,当链表长度 >=8 且数组长度 >=64 时树化,提升查询效率。

    • 内存利用率更高(共享一个数组),并发度动态扩展。

    • 支持 多线程协作扩容,迁移效率更高。


4. ConcurrentHashMap 的 put 方法流程?

  1. 计算哈希spread(key.hashCode())(保证哈希值为正数)。

  2. 懒初始化:若数组为空,调用 initTable() 初始化。

  3. 定位桶(n-1) & hash 计算桶下标。

  4. CAS 插入空桶:若桶为空,直接通过 CAS 插入新节点。

  5. 处理哈希冲突

    • 若桶正在迁移(ForwardingNode),当前线程协助迁移。

    • 非空桶锁住头节点,处理链表或红黑树的插入/更新。

  6. 树化检查:链表长度 >=8 时可能触发树化。

  7. 更新计数:调用 addCount() 更新元素总数(基于 CounterCell[] 分片计数)。


5. ConcurrentHashMap 的 size() 方法为什么不是完全精确的?

  • 分片计数优化: 使用 CounterCell[] 数组分散计数更新,避免多线程竞争同一变量。

    • 当无竞争时,直接更新 baseCount

    • 当检测到竞争时,使用 CounterCell 分片统计,最终结果为 baseCount + ∑CounterCell[i]

  • 设计权衡: 高并发场景下,精确统计需要全局锁,性能代价过高。size() 返回的是一个近似值,但实际开发中足够使用。


6. 如何保证 get() 操作的无锁和高性能?

  • volatile 变量: 桶数组和节点的 valnext 字段用 volatile 修饰,保证可见性。

  • 无锁读设计

    • tabAt() 使用 Unsafe.getObjectVolatile 直接读取内存最新值。

    • 遍历链表或红黑树时不加锁,依赖 volatile 保证数据可见性。

  • 扩容期间的读操作: 遇到 ForwardingNode 时,自动跳转到新数组查询数据。


7. ConcurrentHashMap 的扩容机制如何实现?

核心步骤

  1. 触发条件:元素数量超过 sizeCtl(扩容阈值 = 0.75 * 数组长度)。

  2. 多线程协作

    • 首个线程创建新数组(长度翻倍),并分配迁移任务区间。

    • 其他线程通过 transferIndex 领取迁移任务(步长 stride)。

  3. 迁移逻辑

    • 将旧数组的桶拆分为高低位链表,高位链表迁移到 旧下标 + 旧容量 的位置。

    • 迁移完成的桶用 ForwardingNode 占位,表示已处理。

  4. 读写协调

    • 读操作:遇到 ForwardingNode 时跳转到新数组查询。

    • 写操作:先协助迁移当前桶,再执行插入。


8. 链表何时会转为红黑树?何时会退化为链表?

  • 树化条件

    • 链表长度 >=8(TREEIFY_THRESHOLD)。

    • 数组长度 >=64(MIN_TREEIFY_CAPACITY),否则优先扩容。

  • 退化条件

    • 红黑树节点数 <=6(UNTREEIFY_THRESHOLD)时退化为链表。

  • 设计目的: 平衡查询效率和空间占用,避免极端情况下的性能问题。


9. ConcurrentHashMap 为什么不允许 Null 键或 Null 值?

  • 歧义性问题get(key) 返回 null 时,无法区分是键不存在还是键对应的值为 null

  • 线程安全风险: 若允许 null,可能因并发操作导致隐式的 NullPointerException(如 containsKey(key)get(key) 之间的竞争)。

  • 设计一致性ConcurrentHashMap 的设计目标是为并发场景提供明确的语义,禁止 null 可减少不确定性。


10. ConcurrentHashMap 的迭代器是强一致性还是弱一致性?

  • 弱一致性: 迭代器在遍历时不会锁定整个哈希表,可能反映部分已完成的更新操作。

    • 迭代过程中可能看到新增、删除或修改的键值对,但不保证完全一致。

    • 设计目的是避免迭代期间阻塞其他线程,提升并发性能。

  • 对比其他集合HashMap 的迭代器是快速失败的(fail-fast),而 ConcurrentHashMap 的迭代器是安全的(fail-safe)。


11. 为什么 JDK8 改用 synchronized 而不是 ReentrantLock?

  • 锁粒度细化synchronized 在 JDK6 后进行了大量优化(如偏向锁、轻量级锁),性能与 ReentrantLock 接近。

  • 内存消耗ReentrantLock 需要额外维护 AQS 队列,内存开销更大。

  • 代码简洁性synchronized 语法更简洁,无需手动释放锁,减少编码错误。


12. ConcurrentHashMap 是否完全线程安全?

  • 基本操作线程安全putgetremove 等单操作是原子的,线程安全。

  • 组合操作非原子

    if (!map.containsKey(key)) map.put(key, value); // 非原子操作

    此类组合操作需使用 putIfAbsent() 或外部同步。

  • 迭代器弱一致性: 迭代期间可能看到其他线程的修改,但不会抛出 ConcurrentModificationException


13. 如何理解 sizeCtl 字段的作用?

sizeCtl 是一个控制状态变量,具体含义:

  • >0:表示下一次扩容的阈值(0.75 * 当前容量)。

  • =0:默认初始状态。

  • =-1:表示哈希表正在初始化。

  • <-1:表示正在扩容,高 16 位表示扩容标识戳,低 16 位表示参与扩容的线程数 +1。


14. ConcurrentHashMap 的应用场景?

  • 高并发缓存:如缓存用户会话信息、商品库存等。

  • 实时统计:如多线程计数(需结合 addCount() 机制)。

  • 替代 HashTable:所有需要线程安全哈希表的场景,性能更优。

  • 分布式计算:如 MapReduce 任务中的局部结果聚合。


15. 如何设计一个线程安全的哈希表?

  • 锁粒度优化: 从全局锁 → 分段锁 → 桶级别锁,逐步减少竞争。

  • 无锁化尝试: 优先使用 CAS 处理无竞争场景(如空桶插入)。

  • 并发扩容协作: 允许多线程协同迁移数据,提升扩容效率。

  • 数据结构优化: 引入红黑树平衡查询效率,动态退化避免空间浪费。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/71332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lua | 每日一练 (5)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (5)题目参考答案浅拷贝深拷贝使用场景…

JavaEE--计算机是如何工作的

一、一台计算机的组成部分 1.CPU&#xff08;中央处理器&#xff09; 2.主板&#xff08;一个大插座&#xff09; 3.内存&#xff08;存储数据的主要模板&#xff09; 4.硬盘&#xff08;存储数据的主要模板&#xff09; 内存和硬盘对比&#xff1a; 内存硬盘读写速度快慢存…

电源测试系统有哪些可以利用AI工具的科技??

AI技术的发展对电源模块测试系统的影响是深远的&#xff0c;不仅协助系统提升了测试效率和精度&#xff0c;还推动了测试方法的创新和智能化。那么在电源测试系统中哪些模块可以利用AI工具实现自动化测试? 1. 自动化测试与效率提升 智能测试流程优化 AI算法可以自动优化测试…

通过多线程同时获取H264和H265码流

目录 一.RV1126 VI采集摄像头数据并同时编码H264、H265的大概流程​编辑​编辑 1.1初始化VI模块&#xff1a; 1.2H264、H265的VENC模块初始化&#xff1a; 1.3VI分别绑定H264的VENC层和H265的VENC层&#xff1a; ​​​​​​​1.4开启H264线程采集H264的VENC数据&#xff…

unity lua属性绑定刷新

我们现在有一个 角色属性类叫heroModel,内容如下,当heroModel中的等级发生变化的时候&#xff0c;我们需要刷新界面显示等级信息&#xff0c;通常我们是在收到等级升级成功的协议的时候&#xff0c;发送一个事件&#xff0c;UI界面接受到这个事件的时候&#xff0c;刷新一下等级…

vscode+vue前端开发环境配置

目录 一、安装Vue二、使用vue新建项目 一、安装Vue 在node.js安装好之后&#xff0c; npm config set registry https://registry.npmmirror.com# 安装vue相关工具&#xff0c;webpack用来项目构建、打包、资源整合等。 npm install webpack -g# 安装vue-cli脚手架 npm insta…

《白帽子讲 Web 安全》之文件操作安全

目录 引言 &#xff08;一&#xff09;文件上传与下载漏洞概述 1.文件上传的常见安全隐患 1.1前端校验的脆弱性与服务端脚本执行危机在文件上传流程中&#xff0c;部分开发者可能会在前端使用 JavaScript 代码对文件后缀名进行简单校验&#xff0c;试图以此阻止非法文件上传…

vector习题

完数和盈数 题目 完数VS盈数_牛客题霸_牛客网 一个数如果恰好等于它的各因子(该数本身除外)之和&#xff0c;如&#xff1a;6321。则称其为“完数”&#xff1b;若因子之和大于该数&#xff0c;则称其为“盈数”。 求出2到60之间所有“完数”和“盈数”。 输入描述&#xff…

cesium+vue3自定义HTML实体弹窗、加高德路网、防实体漂浮、让用户画圆、鹰眼

一、基础使用&#xff1a;Cesium.js基础使用&#xff08;vue&#xff09;-CSDN博客 1、基础路径 为 Cesium 库设置一个全局变量 CESIUM_BASE_URL&#xff0c;用于指定 Cesium 的资源文件&#xff08;如 WebGL shaders、纹理、字体等&#xff09;的 示例场景&#xff1a;假设你…

安全运营的“黄金4小时“:如何突破告警疲劳困局

在当今复杂多变的网络安全环境中&#xff0c;安全团队面临着前所未有的挑战。尤其是面对高级持续性威胁&#xff08;APT&#xff09;时&#xff0c;最初的“黄金4小时”成为决定成败的关键窗口。在这段时间内&#xff0c;快速而准确地响应可以极大地降低损失&#xff0c;然而&a…

[BUUCTF]web--wp(持续更新中)

ps:文章所引用知识点链接&#xff0c;如有侵权&#xff0c;请联系删除 [极客大挑战 2019]EasySQL 题目类型&#xff1a;简单SQL注入 发现是登录页面&#xff0c;用万能登录方法测试&#xff0c;两种语句均能解出flag [极客大挑战 2019]Havefun 题目类型&#xff1a;代码审计…

MySQL数据库的数据类型

1.设置MySQL服务器的默认储存引擎 set default_storage_engineMYISAM2. 数值类型 整数类型 TINYINT&#xff1a;1字节&#xff0c;范围&#xff1a;-128~127&#xff08;有符号&#xff09;&#xff0c;0~255&#xff08;无符号&#xff09;。适用于状态码、布尔值&#xff08…

探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(二)

文章目录 2.3.3 极化编码巴氏参数与信道可靠性比特混合生成矩阵编码举例 2.3.4 极化译码最小单元译码串行抵消译码&#xff08;SC译码&#xff09;算法SCL译码算法 2.3.5 总结**Polar 码的优势****Polar 码的主要问题****Polar 码的应用前景** 2.3.6 **参考文档** 本博客为系列…

VirtualBox虚拟机转VM虚拟机

前言&#xff1a;部分靶机只适用于VirtualBox&#xff0c;VM打不开VirtualBox的文件&#xff0c;所以需要进行转换 前置条件&#xff1a;本机已经下载VM和VirtualBox 第一步&#xff1a;文件转换 找到VirtualBox.exe所在位置&#xff0c;启动cmd窗口 文件转换的命令&#xf…

DeepSeek API使用及私有化部署

DeepSeek 大模型概述 DeepSeek 是一款参数量高达 671B 的大语言模型&#xff0c;其模型参数文件规模庞大&#xff0c;即使是经过优化的版本&#xff0c;参数文件也有数十 GB。这种庞大的参数量赋予了 DeepSeek 强大的自然语言处理能力&#xff0c;使其能够处理复杂的语言任务&…

动态扩缩容引发的JVM堆内存震荡:从原理到实践的GC调优指南

目录 一、典型案例&#xff1a;系统发布后的GC雪崩事件 &#xff08;一&#xff09;故障现象 1. 刚刚启动时 GC 次数较多 2. 堆内存锯齿状波动 3. GC日志特征&#xff1a;Allocation Failure &#xff08;二&#xff09;问题定位 二、原理深度解析&#xff1a;JVM内存弹…

IDEA 使用codeGPT+deepseek

一、环境准备 1、IDEA 版本要求 安装之前确保 IDEA 处于 2023.x 及以上的较新版本。 2、Python 环境 安装 Python 3.8 或更高版本 为了确保 DeepSeek 助手能够顺利运行&#xff0c;您需要在操作系统中预先配置 Python 环境。具体来说&#xff0c;您需要安装 Python 3.8 或更高…

vue These dependencies were not found

These dependencies were not found: * vxe-table in ./src/main.js * vxe-table/lib/style.css in ./src/main.js To install them, you can run: npm install --save vxe-table vxe-table/lib/style.css 解决&#xff1a; nodejs执行以下语句 npm install --save vxe-t…

【三.大模型实战应用篇】【4.智能学员辅导系统:docx转PDF的自动化流程】

去年团队庆功宴上,我司CTO端着酒杯过来:“老王啊,咱们现在文档解析做得挺溜了,但老师们总抱怨下载的作业格式乱码…” 我看了眼手机里凌晨三点收到的崩溃警报,把杯里的可乐一饮而尽——得,新的副本又开了。 一、为什么PDF转换比想象中难十倍? 某次用户调研中,数学教研…

安卓基础组件Looper - 03 java层面的剖析

文章目录 workflow工作线程 准备Looper创建LooperActivity主线程其他情况 Looper.prepare()大体流程java申请Loopernew LooperMessageQueue初始化 nativejniNativeMessageQueue Looper.loop()大体流程java获取Looper获取msg&#xff0c;处理msgLooper.loop()Looper.loopOnce &a…