文章列表
1000 万短信 1 小时发完,怎么设计线程池?
技术分享
设计一个能在一小时内稳定发送一千万条短信的线程池,绝不仅仅是设置几个参数那么简单。这是一个典型的**高并发、IO密集型**任务,需要从架构层面进行系统性设计,以确保高性能、高可靠和系统稳定。 以下是完整的设计方案: ### 🎯 核心目标与约束 首先,明确我们的目标: * **总量**: 10,000,000 条短信 * **时限**: 1 小时 (3600 秒) * **平均速率**: `10,000,000 / 3600 ≈ 2778` 条/秒 这意味着我们的系统需要稳定地维持近 2800 QPS 的发送能力。 ### 🛠️ 线程池核心配置 在生产环境中,严禁使用 `Executors.newFixedThreadPool()` 等方式创建线程池,因为它们使用无界队列,在海量任务下极易导致内存溢出(OOM)。我们必须手动创建 `ThreadPoolExecutor` 并进行精细化配置...
阅读更多Tailwind CSS 完整字典/速查表(前端开发常用)
技术分享
## 📐 布局 Layout | 类别 | 常用类 | 说明 | |:---|:---|:---| | **容器** | `container` `mx-auto` `px-4` | 居中容器 | | **显示** | `block` `inline` `inline-block` `hidden` `flex` `grid` `table` | 显示模式 | | **定位** | `static` `relative` `absolute` `fixed` `sticky` | 定位方式 | | **层级** | `z-0` ~ `z-50` | z-index | --- ## 📊 Flexbox 弹性布局 | 属性 | 类名 | 示例 | |:---|:---|:---| | 方向 | `flex-row` `flex-col` `flex-row-reverse` | 主轴方向...
阅读更多Vue 3 异步请求控制:串行与并行的优雅实践
技术分享
在 Vue 3 的开发中,处理异步请求是家常便饭。我们经常遇到这样的场景:需要等待一个或多个 API 请求完成后,才能进行下一步的数据处理或页面渲染。如何清晰、高效地控制这些请求的执行顺序,是构建健壮应用的关键。 本文将探讨在 Vue 3 中控制异步请求的两种核心模式:**串行执行**和**并行执行**,并结合 `async/await`、`Promise.all` 等现代 JavaScript 特性,提供清晰、可维护的解决方案。 #### 🎯 场景一:串行执行,处理请求依赖 当一个请求的执行依赖于前一个请求的返回结果时,我们必须确保它们按顺序执行。例如,先获取用户 ID,再根据 ID 获取用户的详细信息和订单列表。 在 Vue 3 的 ` 加载中...
阅读更多SQL 性能避坑:为什么阿里强制禁用 ORDER BY RAND()?
技术分享
在阿里巴巴的《Java 开发手册》及众多高并发系统的数据库规范中,**`ORDER BY RAND()`** 被列为**强制禁止**的写法。这并非因为语法错误,而是因为它在数据量稍大时,会引发严重的性能问题,甚至导致数据库雪崩。 以下是其被禁用的核心原因、底层机制分析及推荐的替代方案: ### 1. 核心痛点:为什么 `ORDER BY RAND()` 是“性能毒药”? 当执行 `SELECT * FROM table_name ORDER BY RAND() LIMIT N;` 时,MySQL 的执行过程极其低效,主要包含以下三个致命步骤: 1. **全表扫描与逐行计算**: MySQL 必须扫描表中的**每一行数据**,并为每一行调用一次 `RAND()` 函数生成一个随机数。这意味着即使你只需要 1 条数据,如果表里有 100 万行,它也要计算 100 万次随机数。 2.
阅读更多HashMap 是不是线程安全的?如果让你来实现一个线程安全的 HashMap 你要怎么设计?如果不用加锁你要怎么设计?
技术分享
HashMap 的线程安全性是多线程编程中的一个重要问题,下面我将为你详细解答,并探讨线程安全 HashMap 的设计方案。 # 🔒 HashMap 的线程安全性分析 ## HashMap 的非线程安全本质 HashMap 在设计上**不是线程安全**的。当多个线程同时访问和修改同一个 HashMap 实例时,会导致不可预知的行为。 ### 并发环境下的主要问题: - **数据竞争**:多个线程同时执行 put/remove 操作可能导致数据丢失或覆盖 - **死循环**:在扩容过程中,多线程可能导致链表形成环,引发 CPU 100% 问题 - **大小不一致**:size() 方法返回的结果可能不准确 ### 特例分析 需要注意的是,当 HashMap 作为**方法内的局部变量**,且每个线程拥有独立实例时,不存在线程安全问题。 # 🛠️ 实现线程安全 HashMap 的设计方案 #...
阅读更多Trie树介绍
技术分享
### 🌲 Trie树的核心特性 Trie树有三个基本性质: 1. **根节点不包含字符**,它作为所有字符串的起点。 2. 从根节点到任意一个节点的路径上,经过的所有字符连接起来,就是该节点对应的字符串(或前缀)。 3. 每个节点的所有子节点所包含的字符都互不相同。 它的核心思想是 **空间换时间**,通过将字符串的公共前缀合并存储,避免了大量无谓的字符串比较,使得查询效率在很多情况下优于哈希表。 ### 🧱 结构与基本操作 一个典型的Trie树节点(TrieNode)通常包含两部分信息: * **子节点指针**:可以是固定大小的数组(如处理26个小写英文字母时使用长度为26的数组)或更灵活的映射(如`Map`),用于指向下一个字符节点。 * **结束标记**:一个布尔值(如`isEndOfWord`),标记从根节点到当前节点的路径是否构成了一个完整的单词(而不仅仅是前缀)。...
阅读更多评论脏词过滤:基于DFA算法的高性能动态过滤方案
技术分享
评论系统是内容平台和社交应用的核心功能之一,而脏词过滤是保障内容安全、维护社区氛围的关键技术。本文将详细介绍如何在SpringBoot中实现一个**高性能、支持动态更新**的脏词过滤系统。 ## 一、背景与需求分析 随着Web应用的发展,用户生成内容(UGC)面临着严峻的内容安全挑战。脏词过滤系统需要满足以下核心需求: - **高性能**:处理海量用户评论时不能成为系统瓶颈 - **动态更新**:脏词库需要支持实时更新,无需重启服务 - **准确性**:准确识别敏感词,同时控制误判率 - **灵活性**:支持多种处理策略(替换、拒绝、审核) ## 二、核心技术选型:为何选择DFA算法? 在脏词过滤场景下,**DFA(确定有限状态自动机)算法**相比传统方法有显著优势。 ### 2.1 传统方法的瓶颈 - **暴力匹配**:遍历每个脏词检查文本是否包含,时间复杂度O(n*m),随脏词数量增加...
阅读更多MySQL如何解决深度分页问题?
技术分享
在MySQL开发中,除了计数场景,深度分页(即`LIMIT offset, size`中`offset`值极大的分页查询)也是高频遇到的性能问题。比如“查询第1000页数据,每页10条”(`LIMIT 9990, 10`),常会出现查询缓慢的情况。下面详细讲解深度分页的问题根源及解决方案。 ### 1. 深度分页的问题根源 先明确常规分页的实现方式:使用`LIMIT offset, size`,其中`offset`表示跳过前N条数据,`size`表示取N条数据。 问题核心:当`offset`极大时(如9990),MySQL需要先扫描并跳过前9990条数据,再取10条数据。即使查询条件有索引,也需要遍历索引到第9990条位置,才能定位到目标数据,导致IO开销大、查询效率低。 示例(低效查询): ```sql -- 查询第1000页数据,每页10条,offset=9990 SELECT id,...
阅读更多MySQL中count(*)、count(1)与count(字段名)的区别详解?
技术分享
在MySQL开发中,计数是高频操作,而`count(*)`、`count(1)`和`count(字段名)`这三种常见的计数方式,常常让开发者混淆——它们的计数结果是否一致?执行效率有差异吗?该如何选择?本文将从核心逻辑、具体区别、效率对比、实践建议四个维度,彻底讲清三者的差异,帮你避开使用误区。 ## 一、先明确核心:count()函数的本质 首先要厘清一个基础认知:`count()`是MySQL的聚合函数,核心作用是**统计查询结果集中符合条件的行数**。三者的差异根源,在于「统计范围」和「MySQL对其的优化逻辑」不同,而非函数本身的功能差异。 ## 二、三者的具体区别:逻辑+示例验证 为了更直观地对比,我们先创建一张测试表并插入测试数据(包含NULL值,模拟真实业务场景): ```sql -- 创建测试表 CREATE TABLE test_count ( id INT COMMEN...
阅读更多