深入探讨5种单例模式
文章目录
- 一、对比总览
- 详细解释
- 二、代码
- 1. 饿汉式
- 2. 饱汉式
- 3. 饱汉式-双检锁
- 4. 静态内部类
- 5. 枚举单例
- 三、性能对比
一、对比总览
以下是不同单例模式实现方式的特性对比表格。表格从线程安全性、延迟加载、实现复杂度、反序列化安全性、防反射攻击性等多个方面进行考量。
特性 | 饿汉式 | 饱汉式 | 饱汉式-双检锁 | 静态内部类 | 枚举单例(推荐) |
---|---|---|---|---|---|
线程安全性 | √ | × | √ | √ | √ |
延迟加载 | × | √ | √ | √ | × |
实现复杂度 | √ | √ | × | √ | √ |
反序列化安全性 | × | × | × | × | √ |
防反射攻击性 | × | × | × | × | √ |
详细解释
-
线程安全性:
- 饿汉式:类加载时即创建实例(因为instance是static),线程安全。
- 饱汉式:未使用同步机制,线程不安全。
- 饱汉式-双检锁:使用同步块和双重检查锁,线程安全。
- 静态内部类:通过类加载机制,线程安全。
- 枚举单例:JVM确保线程安全。
-
延迟加载:
- 饿汉式:类加载时即创建实例,不具备延迟加载。
- 饱汉式:实例在首次使用时创建,具备延迟加载。
- 饱汉式-双检锁:实例在首次使用时创建,具备延迟加载。
- 静态内部类:实例在首次使用时创建(因为静态内部类只有在使用时才会加载),具备延迟加载。
- 枚举单例:类加载时即创建实例,不具备延迟加载。
-
实现复杂度:
- 饿汉式:实现简单。
- 饱汉式:实现简单。
- 饱汉式-双检锁:实现相对复杂。
- 静态内部类:实现简单。
- 枚举单例:实现简单。
-
反序列化安全性:
- 饿汉式、饱汉式、饱汉式-双检锁、静态内部类:需要实现
readResolve
方法以防止反序列化创建新实例。 - 枚举单例:天然防止反序列化创建新实例,JVM保证。
- 饿汉式、饱汉式、饱汉式-双检锁、静态内部类:需要实现
-
防反射攻击性:
- 饿汉式、饱汉式、饱汉式-双检锁、静态内部类:可能通过反射创建新实例。
- 枚举单例:防止反射攻击,创建新实例时抛出
IllegalArgumentException
。
二、代码
1. 饿汉式
public class OrderManager1 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();@Getterprivate static final OrderManager1 instance = new OrderManager1();/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
2. 饱汉式
public class OrderManager2 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static OrderManager2 instance;public static OrderManager2 getInstance(){if (instance == null){instance = new OrderManager2();}return instance;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
3. 饱汉式-双检锁
public class OrderManager3 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static OrderManager3 instance;public static OrderManager3 getInstance(){if (instance == null){synchronized (OrderManager3.class){if (instance == null){instance = new OrderManager3();}}instance = new OrderManager3();}return instance;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
4. 静态内部类
public class OrderManager4 {@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();private static class SingletonHelper{private static final OrderManager4 INSTANCE = new OrderManager4();}public static OrderManager4 getInstance(){return SingletonHelper.INSTANCE;}/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
5. 枚举单例
public enum OrderManager5 {INSTANCE;@Getter@Setterprivate Map<String, TradeOrder> orders = new HashMap<>();/*** 添加订单** @param order 顺序*/public void addOrder(TradeOrder order) {orders.put(order.getId(), order);}/*** 获取订单** @param orderId 订单id* @return {@link TradeOrder}*/public TradeOrder getOrder(String orderId) {return orders.get(orderId);}
}
三、性能对比
package org.dragon.singleton;import lombok.extern.slf4j.Slf4j;import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;@Slf4j
public class SingletonPerformanceTest {static long timeout = 20; // 超时时间,单位为秒static int testIterations = 10_000_000; // 测试次数static int threadCount = 1000; // 并发线程数static Map<String, HashMap<String, Long>> result = new HashMap<>();public static void main(String[] args) {/** 多次调用,结果是最后一次调用存入。为什么多次调用,因为单次test不准确,总是靠前的OrderManager跑的快,可能是因为Java某些机制导致的* 所以多次调用,逐渐平稳。* */firstCreationTest();mulAccessTest();mulAccessTest();mulAccessTest();ConcurrentAccessTest();ConcurrentAccessTest();printRes();ConcurrentAccessTest();printRes();ConcurrentAccessTest();printRes();}/*** 打印结果*/private static void printRes(){ArrayList<String> names = new ArrayList<>();names.add(OrderManager1.class.getSimpleName());names.add(OrderManager2.class.getSimpleName());names.add(OrderManager3.class.getSimpleName());names.add(OrderManager4.class.getSimpleName());names.add(OrderManager5.class.getSimpleName());// 表头System.out.printf("%-20s%-20s%-25s%-25s%-20s%n", "Singleton Type", "First Creation (ms)", "Multiple Access (ms)", "Concurrent Access (ms)", "Memory Used (MB)");System.out.println("---------------------------------------------------------------------------------------------------------------");for (String name : names) {// 打印结果,转换时间为毫秒System.out.printf("%-20s%-20.3f%-25.3f%-25.3f%-20.3f%n", name, result.get(name).get("firstCreation") / 1_000_000.0, result.get(name).get("mulAccess") / 1_000_000.0, result.get(name).get("ConcurrentAccess") / 1_000_000.0, 0 / (1024.0 * 1024.0));}}/*** 首次创建测试*/private static void firstCreationTest(){List<Runnable> tests = new ArrayList<>();tests.add(()->firstCreation(OrderManager1::getInstance));tests.add(()->firstCreation(OrderManager2::getInstance));tests.add(()->firstCreation(OrderManager3::getInstance));tests.add(()->firstCreation(OrderManager4::getInstance));tests.add(()->firstCreation(() -> OrderManager5.INSTANCE));// 随机化测试顺序Collections.shuffle(tests);//runfor (Runnable test : tests) {test.run();log.info("Complete one test");try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}}}/*** 多次访问测试*/private static void mulAccessTest(){List<Runnable> tests = new ArrayList<>();tests.add(()->mulAccess(OrderManager1::getInstance, testIterations));tests.add(()->mulAccess(OrderManager2::getInstance, testIterations));tests.add(()->mulAccess(OrderManager3::getInstance, testIterations));tests.add(()->mulAccess(OrderManager4::getInstance, testIterations));tests.add(()->mulAccess(() -> OrderManager5.INSTANCE, testIterations));// 随机化测试顺序Collections.shuffle(tests);//runfor (Runnable test : tests) {test.run();log.info("Complete one test");try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}}}/*** 多线程访问测试*/private static void ConcurrentAccessTest(){List<Runnable> tests = new ArrayList<>();tests.add(()->ConcurrentAccess(OrderManager1::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(OrderManager2::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(OrderManager3::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(OrderManager4::getInstance, testIterations, threadCount));tests.add(()->ConcurrentAccess(() -> OrderManager5.INSTANCE, testIterations, threadCount));// 随机化测试顺序Collections.shuffle(tests);//runfor (Runnable test : tests) {test.run();log.info("Complete one test");try {Thread.sleep(200);} catch (InterruptedException e) {throw new RuntimeException(e);}}}/*** 首次创建** @param singletonSupplier 单一供应商* @return long ns*/private static <T> long firstCreation(Supplier<T> singletonSupplier){// 测试首次创建时间long startTime = System.nanoTime();T instance = singletonSupplier.get();long endTime = System.nanoTime();long resTime = endTime - startTime;//save resString simpleName = instance.getClass().getSimpleName();HashMap<String, Long> resMap = result.computeIfAbsent(simpleName, k->new HashMap<>());resMap.put("firstCreation", resTime);return resTime;}/*** 多次访问** @param singletonSupplier 单一供应商* @param iterations 迭代* @return long ns*/private static <T> long mulAccess(Supplier<T> singletonSupplier, int iterations){//预热for (int i = 0; i < 100_000; i++) {T instance = singletonSupplier.get();}//计算long startTime = System.nanoTime();for (int i = 0; i < iterations; i++) {T instance = singletonSupplier.get();}long endTime = System.nanoTime();long resTime = endTime - startTime;//save resString simpleName = singletonSupplier.get().getClass().getSimpleName();HashMap<String, Long> resMap = result.computeIfAbsent(simpleName, k->new HashMap<>());resMap.put("mulAccess", resTime);return resTime;}/*** 并发访问** @param singletonSupplier 单一供应商* @param iterations 迭代* @param threadCount 线程数* @return long ns*/private static <T> long ConcurrentAccess(Supplier<T> singletonSupplier, int iterations, int threadCount){ExecutorService executorService = Executors.newFixedThreadPool(100);//预热CountDownLatch latch1 = new CountDownLatch(100);for (int i = 0; i < threadCount; i++) {executorService.submit(() -> {for (int j = 0; j < 100_000; j++) {T instance = singletonSupplier.get();}latch1.countDown();});}try {boolean completed = latch1.await(timeout, TimeUnit.SECONDS);if (!completed) {System.out.println("Concurrent access test for 预热" + singletonSupplier.get().getClass().getSimpleName() + " timed out!");}} catch (InterruptedException e) {e.printStackTrace();}//计算CountDownLatch latch2 = new CountDownLatch(threadCount);long startTime = System.nanoTime();for (int i = 0; i < threadCount; i++) {executorService.submit(() -> {for (int j = 0; j < iterations; j++) {T instance = singletonSupplier.get();}latch2.countDown();});}try {boolean completed = latch2.await(timeout, TimeUnit.SECONDS);if (!completed) {System.out.println("Concurrent access test for " + singletonSupplier.getClass().getSimpleName() + " timed out!");}} catch (InterruptedException e) {e.printStackTrace();}long endTime = System.nanoTime();long concurrentAccessTime = endTime - startTime;executorService.shutdown();//save resString simpleName = singletonSupplier.get().getClass().getSimpleName();HashMap<String, Long> resMap = result.computeIfAbsent(simpleName, k->new HashMap<>());resMap.put("ConcurrentAccess", concurrentAccessTime);return concurrentAccessTime;}
}
结果输出如下
[17:15:54.519] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:54.730] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:54.936] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:55.141] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:55.347] [INFO ] org.dragon.singleton.SingletonPerformanceTest 73 firstCreationTest - Complete one test
[17:15:55.554] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:55.782] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.007] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.227] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.445] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.669] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:56.906] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.146] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.376] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.598] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:57.818] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.054] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.276] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.495] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:58.716] [INFO ] org.dragon.singleton.SingletonPerformanceTest 97 mulAccessTest - Complete one test
[17:15:59.430] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:15:59.658] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:02.737] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:08.533] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:13.700] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:19.432] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:24.632] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:30.366] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:35.516] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:40.431] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
Singleton Type First Creation (ms) Multiple Access (ms) Concurrent Access (ms) Memory Used (MB)
---------------------------------------------------------------------------------------------------------------
OrderManager1 0.010 16.848 4928.236 0.000
OrderManager2 0.010 18.592 5504.781 0.000
OrderManager3 0.009 19.127 5513.309 0.000
OrderManager4 0.241 18.772 4920.940 0.000
OrderManager5 0.117 16.637 4704.835 0.000
[17:16:45.002] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:48.982] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:52.778] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:16:57.834] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:02.298] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
Singleton Type First Creation (ms) Multiple Access (ms) Concurrent Access (ms) Memory Used (MB)
---------------------------------------------------------------------------------------------------------------
OrderManager1 0.010 16.848 4217.333 0.000
OrderManager2 0.010 18.592 4340.869 0.000
OrderManager3 0.009 19.127 4824.581 0.000
OrderManager4 0.241 18.772 3743.032 0.000
OrderManager5 0.117 16.637 3558.995 0.000
[17:17:06.778] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:11.231] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:15.733] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:20.812] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
[17:17:25.837] [INFO ] org.dragon.singleton.SingletonPerformanceTest 121 ConcurrentAccessTest - Complete one test
Singleton Type First Creation (ms) Multiple Access (ms) Concurrent Access (ms) Memory Used (MB)
---------------------------------------------------------------------------------------------------------------
OrderManager1 0.010 16.848 4281.649 0.000
OrderManager2 0.010 18.592 4849.279 0.000
OrderManager3 0.009 19.127 4782.224 0.000
OrderManager4 0.241 18.772 4267.228 0.000
OrderManager5 0.117 16.637 4233.907 0.000 进程已结束,退出代码为 0
可以去多跑几次,基本上最后一种枚举单例,性能属于最好的一批。并且也最安全。
相关文章:

深入探讨5种单例模式
文章目录 一、对比总览详细解释 二、代码1. 饿汉式2. 饱汉式3. 饱汉式-双检锁4. 静态内部类5. 枚举单例 三、性能对比 一、对比总览 以下是不同单例模式实现方式的特性对比表格。表格从线程安全性、延迟加载、实现复杂度、反序列化安全性、防反射攻击性等多个方面进行考量。 …...
SPOOL
-----How to Pass UNIX Variable to SPOOL Command (Doc ID 1029440.6) setenv只有csh才有不行啊PROBLEM DESCRIPTION: You would like to put a file name in Unix and have SQL*Plus read that file name, instead of hardcoding it, because it will change.You want to pa…...

挑战绝对不可能:再证有长度不同的射线
黄小宁 一空间坐标系中有公共汽车A,A中各座位到司机处的距离h是随着座位的不同而不同的变数,例如5号座位到司机处的距离是h3,…h5,…。A移动了一段距离变为汽车B≌A,B中5号座位到司机处的距离h’h3,…h’h5…...

【机器学习】Python与深度学习的完美结合——深度学习在医学影像诊断中的惊人表现
🔥 个人主页:空白诗 文章目录 一、引言二、深度学习在医学影像诊断中的突破1. 技术原理2. 实际应用3. 性能表现 三、深度学习在医学影像诊断中的惊人表现1. 提高疾病诊断准确率2. 辅助制定治疗方案 四、深度学习对医疗行业的影响和推动作用 一、引言 随着…...

MapStruct的用法总结及示例
MapStruct是一个代码生成器,它基于约定优于配置的原则,使用Java注解来简化从源对象到目标对象的映射过程。它主要用于减少样板代码,提高开发效率,并且通过编译时代码生成来保证性能。 我的个人实践方面是在2021年前那时候在项目中…...

redis 05 复制 ,哨兵
01.redis的复制功能,使用命令slaveof 2. 2.1 2.2 3. 3.1 3.1.1 3.1.2 3.1.3 4 4.1 4.2 例子 5.1 这里是从客户端发出的指令 5.2 套接字就是socket 这里是和redis事件相关的知识 5.3 ping一下...

强大的.NET的word模版引擎NVeloDocx
在Javer的世界里,存在了一些看起来还不错的模版引擎,比如poi-tl看起来就很不错,但是那是人家Javer们专属的,与我们.Neter关系不大。.NET的世界里Word模版引擎完全是一个空白。 很多人不得不采用使用Word XML结合其他的模版引擎来…...

MySQL中所有常见知识点汇总
存储引擎 这一张是关于整个存储引擎的汇总知识了。 MySQL体系结构 这里是MySQL的体系结构图: 一般将MySQL分为server层和存储引擎两个部分。 其实MySQL体系结构主要分为下面这几个部分: 连接器:负责跟客户端建立连 接、获取权限、维持和管理…...

Flink 基于 TDMQ Apache Pulsar 的离线场景使用实践
背景 Apache Flink 是一个开源的流处理和批处理框架,具有高吞吐量、低延迟的流式引擎,支持事件时间处理和状态管理,以及确保在机器故障时的容错性和一次性语义。Flink 的核心是一个分布式流数据处理引擎,支持 Java、Scala、Pytho…...

远程访问及控制
SSH协议 是一种安全通道协议 对通信数据进行了加密处理,用于远程管理 OpenSSH(SSH由OpenSSH提供) 服务名称:sshd 服务端控制程序: /usr/sbin/sshd 服务端配置文件: /etc/ssh/sshd_config ssh存放的客户端的配置文件 ssh是服务端额…...
【代码随想录训练营】【Day 44】【动态规划-4】| 卡码 46, Leetcode 416
【代码随想录训练营】【Day 44】【动态规划-4】| 卡码 46, Leetcode 416 需强化知识点 背包理论知识 题目 卡码 46. 携带研究材料 01 背包理论基础01 背包理论基础(滚动数组)01 背包 二维版本:dp[i][j] 表示从下标为[0-i]的物…...

html5实现个人网站源码
文章目录 1.设计来源1.1 网站首页页面1.2 个人工具页面1.3 个人日志页面1.4 个人相册页面1.5 给我留言页面 2.效果和源码2.1 动态效果2.2 目录结构 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/139564407 ht…...

【内存管理】内存布局
ARM32位系统的内存布局图 32位操作系统的内存布局很经典,很多书籍都是以32位系统为例子去讲解的。32位的系统可访问的地址空间为4GB,用户空间为1GB ~ 3GB,内核空间为3GB ~ 4GB。 为什么要划分为用户空间和内核空间呢? 一般处理器…...

软件试运行方案(Word)
软件试运行方案(直接套用实际项目,原件获取通过本文末个人名片直接获取。) 一、试运行目的 二、试运行的准备 三、试运行时间 四、试运行制度 五、试运行具体内容与要求...

Redis原理篇——哨兵机制
Redis原理篇——哨兵机制 1.Redis哨兵2.哨兵工作原理2.1.哨兵作用2.2.状态监控2.3.选举leader2.4.failover 1.Redis哨兵 主从结构中master节点的作用非常重要,一旦故障就会导致集群不可用。那么有什么办法能保证主从集群的高可用性呢? 2.哨兵工作原理 …...
web前端的MySQL:跨领域之旅的探索与困惑
web前端的MySQL:跨领域之旅的探索与困惑 在数字化浪潮的推动下,web前端与MySQL数据库似乎成为了两个不可或缺的领域。然而,当我们将这两者放在一起,尝试探索web前端与MySQL之间的交互与关联时,却发现这是一次充满困惑…...

Postgresql源码(135)生成执行计划——Var的调整set_plan_references
1 总结 set_plan_references主要有两个功能: 拉平:生成拉平后的RTE列表(add_rtes_to_flat_rtable)。调整:调整前每一层计划中varno的引用都是相对于本层RTE的偏移量。放在一个整体计划后,需要指向一个统一…...

Python魔法之旅专栏(导航)
目录 推荐阅读 1、Python筑基之旅 2、Python函数之旅 3、Python算法之旅 4、博客个人主页 首先,感谢老铁们一直以来对我的支持与厚爱,让我能坚持把Python魔法方法专栏更新完毕! 其次,为了方便大家查阅,我将此专栏…...

Python第二语言(五、Python文件相关操作)
目录 1. 文件编码的概念 2. 文件的读取操作 2.1 什么是文件 2.2 open()打开函数 2.3 mode常用的三种基础访问模式 2.4 文件操作及案例 3. 文件的写入操作及刷新文件:write与flush 4. 文件的追加操作 5. 文件操作的综合案例(文件备份操作&#x…...
Vue3 组合式 API:依赖注入(四)
provide() provide() 函数是用于依赖注入的一个关键部分。这个函数允许你在组件树中提供一个值或对象,使得任何子组件(无论层级多深)都能够通过 inject() 函数来访问这些值。 import { provide, ref } from vue; export default { setup(…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...