移动端六大语言速记:第9部分 - 并发与多线程
移动端六大语言速记:第9部分 - 并发与多线程
本文将对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言在并发与多线程方面的特性,帮助开发者理解和掌握各语言的并发编程机制。
9. 并发与多线程
9.1 线程与进程
各语言线程与进程的创建和管理方式对比:
语言 | 线程创建方式 | 进程创建方式 | 线程池支持 | 线程生命周期管理 |
---|---|---|---|---|
Java | Thread 类, Runnable 接口 | ProcessBuilder | ExecutorService | 状态管理,中断机制 |
Kotlin | 继承Java线程模型,协程 | 继承Java进程模型 | ExecutorService ,协程调度器 | 协程作用域,Job管理 |
Dart | Isolate (类似进程) | 不直接支持 | 无原生线程池 | Isolate控制,Stream |
Python | threading 模块 | multiprocessing 模块 | concurrent.futures | 守护线程,join方法 |
ArkTS | Worker (类似Web Worker) | 不直接支持 | 不直接支持 | Worker生命周期管理 |
Swift | Thread , Operation | Process | OperationQueue | 取消操作,依赖管理 |
示例对比
Java:
// 使用Thread类创建线程
Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("线程1运行中...");try {Thread.sleep(1000); // 休眠1秒} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程1完成");}
});
thread1.start(); // 启动线程// 使用lambda表达式简化
Thread thread2 = new Thread(() -> {System.out.println("线程2运行中...");System.out.println("线程2完成");
});
thread2.start();// 线程池示例
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;ExecutorService executor = Executors.newFixedThreadPool(5); // 创建固定大小为5的线程池
for (int i = 0; i < 10; i++) {final int taskId = i;executor.execute(() -> {System.out.println("任务" + taskId + "由线程" + Thread.currentThread().getName() + "执行");});
}
executor.shutdown(); // 关闭线程池// 进程创建示例
try {ProcessBuilder processBuilder = new ProcessBuilder("notepad.exe");Process process = processBuilder.start();// 等待进程结束int exitCode = process.waitFor();System.out.println("进程退出码: " + exitCode);
} catch (Exception e) {e.printStackTrace();
}
Kotlin:
// 使用Thread类创建线程
val thread1 = Thread {println("线程1运行中...")Thread.sleep(1000) // 休眠1秒println("线程1完成")
}
thread1.start() // 启动线程// 使用协程
import kotlinx.coroutines.*// 在主线程中启动协程
fun main() = runBlocking { // 创建一个阻塞协程,通常用于main函数launch { // 在当前协程作用域中启动新协程println("协程1运行中...")delay(1000) // 非阻塞休眠1秒println("协程1完成")}launch {println("协程2运行中...")delay(500)println("协程2完成")}println("主协程等待子协程完成")
} // runBlocking会等待内部所有协程完成// 协程作用域和取消示例
val job = GlobalScope.launch {try {println("长时间运行的任务开始")repeat(1000) { i ->println("任务进度: $i")delay(100)}} catch (e: CancellationException) {println("任务被取消")} finally {println("清理资源")}
}// 5秒后取消任务
delay(5000)
job.cancel()
job.join() // 等待任务完成取消// 使用协程调度器
val dispatcher = Dispatchers.IO // IO密集型任务的调度器
val job2 = GlobalScope.launch(dispatcher) {// 在IO线程池中执行println("在IO线程池中执行: ${Thread.currentThread().name}")
}
Dart:
// Dart使用Isolate而非线程
import 'dart:isolate';
import 'dart:async';// 在新Isolate中执行的函数
void isolateFunction(SendPort sendPort) {sendPort.send('Hello from isolate!');
}// 创建和使用Isolate
Future<void> createIsolate() async {// 创建通信通道final receivePort = ReceivePort();// 启动新的Isolateawait Isolate.spawn(isolateFunction, receivePort.sendPort);// 接收消息receivePort.listen((message) {print('收到消息: $message');receivePort.close(); // 关闭通信端口});
}// 在Flutter中使用compute函数在后台Isolate中执行计算密集型任务
import 'package:flutter/foundation.dart';// 计算密集型函数
int computeFactorial(int n) {int result = 1;for (int i = 2; i <= n; i++) {result *= i;}return result;
}// 在UI中调用
void calculateInBackground() async {final result = await compute(computeFactorial, 20);print('20的阶乘是: $result');
}
Python:
# 使用threading模块创建线程
import threading
import timedef task(name, delay):print(f"{name}开始运行")time.sleep(delay) # 模拟耗时操作print(f"{name}完成")# 创建线程
thread1 = threading.Thread(target=task, args=("线程1", 2))
thread2 = threading.Thread(target=task, args=("线程2", 1))# 启动线程
thread1.start()
thread2.start()# 等待线程完成
thread1.join()
thread2.join()
print("所有线程完成")# 使用线程池
from concurrent.futures import ThreadPoolExecutordef worker(num):print(f"任务{num}开始")time.sleep(1)return f"任务{num}的结果"# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:# 提交任务并获取Future对象futures = [executor.submit(worker, i) for i in range(5)]# 获取结果for future in futures:print(future.result())# 使用multiprocessing模块创建进程
from multiprocessing import Processdef process_task():print(f"进程{Process.current().pid}运行中")time.sleep(2)print(f"进程{Process.current().pid}完成")if __name__ == "__main__": # 在Windows上必须有这个保护# 创建进程process = Process(target=process_task)process.start()process.join()print("主进程继续执行")
ArkTS:
// 使用Worker在后台线程执行任务
import worker from '@ohos.worker';// 创建Worker
function createWorker() {// 创建Worker实例,指定Worker脚本文件路径const workerInstance = new worker.Worker('workers/worker.ts');// 监听Worker消息workerInstance.onmessage = (message) => {console.log(`从Worker收到消息: ${message.data}`);};// 监听Worker错误workerInstance.onerror = (error) => {console.error(`Worker错误: ${error.message}`);};// 向Worker发送消息workerInstance.postMessage('开始计算');// 一段时间后终止WorkersetTimeout(() => {workerInstance.terminate();console.log('Worker已终止');}, 5000);
}// worker.ts文件内容
// 接收主线程消息
onmessage = (message) => {console.log(`Worker收到消息: ${message.data}`);// 执行耗时计算let result = 0;for (let i = 0; i < 10000000; i++) {result += i;}// 向主线程发送结果postMessage(`计算结果: ${result}`);
};
Swift:
// 使用Thread创建线程
import Foundation// 创建线程
let thread = Thread {print("线程运行中...")Thread.sleep(forTimeInterval: 1) // 休眠1秒print("线程完成")
}
thread.start() // 启动线程// 使用Operation和OperationQueue
import Foundation// 创建自定义Operation
class CustomOperation: Operation {let taskID: Intinit(taskID: Int) {self.taskID = taskIDsuper.init()}override func main() {// 检查是否被取消if isCancelled {return}print("任务\(taskID)开始执行")// 模拟耗时操作Thread.sleep(forTimeInterval: 2)print("任务\(taskID)完成")}
}// 创建OperationQueue
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 2 // 设置最大并发数// 添加操作到队列
for i in 1...5 {let operation = CustomOperation(taskID: i)queue.addOperation(operation)
}// 添加操作完成块
let completionOperation = BlockOperation {print("所有任务完成")
}// 设置依赖关系,completionOperation会在队列中所有操作完成后执行
for operation in queue.operations {completionOperation.addDependency(operation)
}
queue.addOperation(completionOperation)// 使用Process创建进程
let process = Process()
process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
process.arguments = ["ls", "-la"]let pipe = Pipe()
process.standardOutput = pipetry {try process.run()let data = pipe.fileHandleForReading.readDataToEndOfFile()if let output = String(data: data, encoding: .utf8) {print(output)}
} catch {print("Error: \(error)")
}
9.2 同步机制
各语言同步机制的对比:
语言 | 互斥锁 | 读写锁 | 信号量 | 条件变量 | 原子操作 |
---|---|---|---|---|---|
Java | synchronized , Lock | ReadWriteLock | Semaphore | Condition | AtomicInteger 等 |
Kotlin | 继承Java同步机制,协程互斥 | 继承Java读写锁 | 继承Java信号量 | 继承Java条件变量 | 继承Java原子类 |
Dart | Lock (package:synchronized) | 无原生支持 | 无原生支持 | 无原生支持 | 无原生支持 |
Python | Lock , RLock | 无原生支持 | Semaphore , BoundedSemaphore | Condition | 无原生支持 |
ArkTS | 不直接支持,通过Worker通信 | 不直接支持 | 不直接支持 | 不直接支持 | 不直接支持 |
Swift | NSLock , os_unfair_lock | pthread_rwlock_t | DispatchSemaphore | NSCondition | 原子操作函数 |
示例对比
Java:
// 使用synchronized关键字
class Counter {private int count = 0;// 同步方法public synchronized void increment() {count++;}public synchronized int getCount() {return count;}
}// 使用显式锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class BankAccount {private double balance;private final Lock lock = new ReentrantLock();public void deposit(double amount) {lock.lock();try {balance += amount;} finally {lock
相关文章:
移动端六大语言速记:第9部分 - 并发与多线程
移动端六大语言速记:第9部分 - 并发与多线程 本文将对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言在并发与多线程方面的特性,帮助开发者理解和掌握各语言的并发编程机制。 9. 并发与多线程 9.1 线程与进程 各语言线程与进程的创建和管理方…...
基于大模型的ALS预测与手术优化系统技术方案
目录 技术方案文档:基于大模型的ALS预测与手术优化系统1. 数据预处理与特征工程模块流程图伪代码2. 多模态融合预测模型模型架构图伪代码3. 术中实时监测与动态干预系统系统流程图伪代码4. 统计验证与可解释性模块验证流程图伪代码示例(SHAP分析)5. 健康教育与交互系统系统架…...
【Vue3知识】组件间通信的方式
组件间通信的方式 概述**1. 父子组件通信****父组件向子组件传递数据(Props)****子组件向父组件发送事件(自定义事件)** **2. 兄弟组件通信****通过父组件中转****使用全局状态管理(如 Pinia 或 Vuex)** **…...
【数据挖掘】岭回归(Ridge Regression)和线性回归(Linear Regression)对比实验
这是一个非常实用的 岭回归(Ridge Regression)和线性回归(Linear Regression)对比实验,使用了 scikit-learn 中的 California Housing 数据集 来预测房价。 📦 第一步:导入必要的库 import num…...
RuntimeError: Error(s) in loading state_dict for ChartParser
一 bug错误 最近使用千问大模型有一个bug,报错信息如下 raise RuntimeError(Error(s) in loading state_dict for {}:\n\t{}.format( RuntimeError: Error(s) in loading state_dict for ChartParser:Unexpected key(s) in state_dict: "pretrained_model.em…...
汽车无钥匙启动125KHz低频发射天线工作原理
汽车智能钥匙低频天线是无钥匙进入(PE)及无钥匙启动(PS)系统的一部分,主要负责发送低频信号,探测智能钥匙与各低频天线间的相对位置,判断车内是否存在智能钥匙。 支持PEPS系统实现便捷操作 无…...
【Docker基础-镜像】--查阅笔记2
目录 Docker镜像概述base镜像镜像的分层结构镜像的理解镜像的构建docker commit 制作镜像DockerfileDockerfile 指令FROMLABELRUNARGENVADDCOPYWORKDIRUSERVOLUMEEXPOSECMD 和 ENTRYPOINT Docker镜像概述 镜像是Docker容器的基石,容器是镜像的运行实例,…...
LeetCode 第47题:旋转数组
LeetCode 第47题:旋转数组 题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例1: 输入…...
数据库管理工具实战:IDEA 与 DBeaver 连接 TDengine(二)
五、DBeaver 连接 TDengine 实战 5.1 安装 DBeaver 下载安装包:访问 DBeaver 官方网站(https://dbeaver.io/download/ ),根据你的操作系统选择合适的安装包。如果是 Windows 系统,下载.exe 格式的安装文件࿱…...
4S店汽车维修保养管理系统 (源码+lw+部署文档+讲解),源码可白嫖!
摘要 二十一世纪我们的社会进入了信息时代,信息管理系统的建立,大大提高了人们信息化水平。传统的管理方式已经与当今4S店汽车维修保养管理系统的业务需求不相适应,也与4S店汽车维修保养管理系统化建设的发展趋势不相适应。本文针对这一需求设计并实现了…...
【Mysql】主从复制部署(保姆级)
本次部署用到三台Ubuntu虚拟机(一主两从): Master服务器:192.168.166.107 Slave1服务器:192.168.166.101 Slave2服务器:192.168.166.103 一、部署思路 首先我们要先捋清主从复制的部署思路…...
华为AR1200密码忘记
1、通过Console口连接设备并重启设备。在设备启动过程中,看到提示信息“Press CtrlB to break auto startup...”时,在三秒内按下CtrlB,输入BootLoader密码后,默认密码:Adminhuawei ,进入BootLoader主菜单…...
高级java每日一道面试题-2025年3月26日-微服务篇[Nacos篇]-在Spring Cloud项目中如何集成Nacos?
如果有遗漏,评论区告诉我进行补充 面试官: 在Spring Cloud项目中如何集成Nacos? 我回答: 在Spring Cloud项目中集成Nacos,可以充分利用Nacos作为服务注册与发现中心以及配置管理中心的功能。以下是详细的步骤和说明,帮助你完成这一集成过程…...
YOLO-LLTS:低光照实时交通标志检测算法详解
论文地址:https://arxiv.org/pdf/2503.13883 目录 一、论文概述 1.1 研究背景 1.2 论文结构 二、核心创新点 2.1 CNTSSS数据集 2.2 HRFM-TOD模块 2.3 MFIA模块 2.4 PGFE模块 三、实验与结果 3.1 实验设置 3.2 性能对比 编辑3.3 消融实验 四、代码复现建议 4.…...
golang 性能优化分析工具 pprof
pprof简介 pprof 是 Go 语言标准库提供的一个强大的性能分析工具,它能帮助开发者深入了解程序的运行时行为,找出性能瓶颈,进而对代码进行优化。下面从多个方面对 pprof 进行详细介绍: 主要功能 CPU 性能分析:能够记…...
机器学习 Day09 线性回归
1.线性回归简介 线性回归知识讲解 定义与公式 定义:线性回归是利用回归方程(函数)对自变量(特征值)和因变量(目标值)之间关系进行建模的分析方式 。自变量只有一个时是单变量回归,…...
2025高频面试算法总结篇【字符串】
文章目录 直接刷题链接直达如何找出一个字符串中的最大不重复子串给定一个数,删除K位得到最大值字符串的排列至少有K个重复字符的最长子串 直接刷题链接直达 如何找出一个字符串中的最大不重复子串 滑动窗口 --> 滑动窗口直到最后一个元素,每当碰到重…...
JavaScript性能优化(上)
1. 减少 DOM 操作 减少 DOM 操作是优化 JavaScript 性能的重要方法,因为频繁的 DOM 操作会导致浏览器重绘和重排,从而影响性能。以下是一些具体的策略和技术,可以帮助有效减少 DOM 操作: 1.1. 批量更新 DOM 亲切与母体ÿ…...
数据结构与算法——链表OJ题详解(1)
文章目录 一、前言二、OJ题分享2.1移除链表元素——非val尾插法2.2反转链表2.2.1头插法2.2.2三指针法 2.3链表的中间结点——快慢指针法2.4合并两个有序链表2.4.1空链表法2.4.2非空链表法 2.5链表的回文结构2.5.1投机取巧数组法2.5.2反转链表法 三、总结 一、前言 前几天博主已…...
sedex认证2025年变化重点
近日,SEDEX突然宣布:2025年7月1日起,全通知审核正式退出历史舞台,取而代之的是至少3周窗口期的半通知突击审核。这场被业内称为“供应链透明化革命”的调整,或将重塑全球工厂合规生态。 三大变化划重点: 1…...
Scala课后总结(8)
集合计算高级函数 过滤(filter) 从集合里挑出符合特定条件元素组成新集合 。比如从整数集合里选出偶数, list.filter(x > x % 2 0) ,就是筛选出能被2整除的元素。 转化/映射(map) 对集合每个元素应…...
老硬件也能运行的Win11 IoT LTSC (OEM)物联网版
#记录工作 Windows 11 IoT Enterprise LTSC 2024 属于物联网相关的版本。 Windows 11 IoT Enterprise 是为物联网设备和场景设计的操作系统版本。它通常针对特定的工业控制、智能设备等物联网应用进行了优化和定制,以满足这些领域对稳定性、安全性和长期支持的需求…...
蓝桥杯冲刺题单--二分
二分 知识点 二分: 1.序列二分:在序列中查找(不怎么考,会比较难?) 序列二分应用的序列必须是递增或递减,但可以非严格 只要r是mid-1,就对应mid(lr1)/2 2.答…...
计网 2025/4/8
CDMA? CRC循环冗余检验 PPP协议的帧格式 字节填充(异步传输、7E->7D5E)零比特填充(同步传输、确保不会出现连续6个1) CSMA/CD协议 多点接入载波监听碰撞检测 一些概念: 争用期 一些公式: 最短有效帧…...
java设计模式-工厂模式
工厂模式 简单工厂模式 请看类: org.xwb.springcloud.factory.simple.PizzaStore 1、简单工厂模式是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实力。简单来工厂模式就是工厂模式家族中最简单最…...
2025年客运从业资格证备考刷题题库
题库中通常包含大量的题目,以全面覆盖考试的知识点。通过做大量的题目,考生可以熟悉各种考试题型和命题方式,提高答题的速度和准确性,同时也能发现自己在知识掌握上的薄弱环节,有针对性地进行复习和强化训练。 1、驾驶…...
Zephyr、FreeRTOS、RT-Thread 任务创建对比分析
一、任务模型与核心概念 特性ZephyrFreeRTOSRT-Thread任务术语线程(Thread)任务(Task)线程(Thread)执行单元线程(单地址空间)任务(共享内存空间)线程&#x…...
RK-realtime Linux
rk3562实时性数据:最大76us rk3568实时性数据:最大126us rk3588实时性数据:最大30us 注意事项 (1)RK3568 需要使用RT版本的BL31,实时性能更好 a)rkbin需要更新到最新,且包含这个补丁:...
Ubuntu 22 Linux上部署DeepSeek+RAG知识库操作详解(Dify方式)之1
一、安装Docker 1. 更新你的包索引 首先,确保你的包列表是最新的。打开终端并运行以下命令: sudo apt update 2. 安装必要的依赖项 安装Docker之前,你需要安装一些必要的依赖项。运行以下命令来安装它们: sudo apt install apt…...
将飞帆制作的网页作为 div 集成到自己的网页中
并且自己的网页可以和飞帆中的控件相互调用函数。效果: 上链接 将飞帆制作的网页作为 div 集成到自己的网页中 - 文贝 进入可以复制、运行代码...
【C++游戏引擎开发】《几何算法》(3)AABB/OBB碰撞检测
一、AABB(轴对齐包围盒) 1.1 定义 最小点: m i n = ( x min , y min , z min ) \mathbf{min} = (x_{\text{min}}, y_{\text{min}}, z_{\text{min}}) min=(xmin,ymin,zmin)最大点: m a x = ( x max , y max , z max ) \mathbf{max} = (x_{\text{max}}, y_{\text{…...
基于人工智能的高中教育评价体系重构研究
基于人工智能的高中教育评价体系重构研究 一、引言 1.1 研究背景 在科技飞速发展的当下,人工智能技术已广泛渗透至各个领域,教育领域亦不例外。人工智能凭借其强大的数据处理能力、智能分析能力和个性化服务能力,为教育评价体系的创新与发…...
【C++游戏引擎开发】数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南
写在前面 两天都没手搓实现可用的凸包生成算法相关的代码,自觉无法手搓相关数学库,遂改为使用成熟数学库。 一、GLM库安装与介绍 1.1 vcpkg安装GLM 跨平台C包管理利器vcpkg完全指南 在PowerShell中执行命令: vcpkg install glm# 集成到系…...
Python 字典和集合(常见的映射方法)
本章内容的大纲如下: 常见的字典方法 如何处理查找不到的键 标准库中 dict 类型的变种set 和 frozenset 类型 散列表的工作原理 散列表带来的潜在影响(什么样的数据类型可作为键、不可预知的 顺序,等等) 常见的映射方法 映射类型…...
Qt 自带的QSqlDatabase 模块中使用的 SQLite 和 SQLite 官方提供的 C 语言版本(sqlite.org)对比
Qt 自带的 QSqlDatabase 模块中使用的 SQLite 和 SQLite 官方提供的 C 语言版本(sqlite.org)在核心功能上是相同的,但它们在集成方式、API 封装、功能支持以及版本更新上存在一些区别。以下是主要区别: 1. 核心 SQLite 引擎 Qt 的…...
按键长按代码
这些代码都存放在定时器中断中。中断为100ms中断一次。 数据判断,看的懂就看吧...
zk源码—3.单机和集群通信原理一
大纲 1.单机版的zk服务端的启动过程 (1)预启动阶段 (2)初始化阶段 2.集群版的zk服务端的启动过程 (1)预启动阶段 (2)初始化阶段 (3)Leader选举阶段 (4)Leader和Follower启动阶段 1.单机版的zk服务端的启动过程 (1)预启动阶段 (2)初始化阶段 单机版zk服务端的启动&…...
车企数字化转型:从“制造工厂”到“移动科技平台”的升维路径
一、战略重构:政策与产业变革的双重倒逼 中国《智能网联汽车技术路线图2.0》明确要求2030年L4级自动驾驶新车渗透率达20%,而麦肯锡数据显示,全球车企数字化投入占比已从2018年的7%跃升至2025年的18%。当前车企面临三大核心挑战:用…...
C++-Mongoose(2)-https-server-openssl
OpenSSL生成HTTPS自签名证书 - 简书 1.Openssl windowsubuntu下载http://www.openssl.vip/download1.VS2019编译OpenSSL 2.VS2019编译第一个OpenSSL项目 1.ubuntu编译OpenSSL 3.0 2.编写第一个OpenSSL 1.windows下编译OpenSSL 安装vs2019 perl nasm安装activePerl…...
nginx正向代理https
一、需求 公司内部服务器向外访问腾讯接口:https://qyapi.weixin.qq.com/cgi-bin,不能使用http直接访问。并且不支持域名,还需要设置互联网出口-出向白名单ip。 如何在尽量少改动代码的情况下实现应用的出向访问链接,考虑使用正向…...
Flask中的蓝图(Blueprint)浅讲
BluePrint Flask中的蓝图(Blueprint)是一种强大的组织工具,能够将大型应用拆分为可重用的模块化组件 1. 模块化组织 用途:将应用按功能拆分为独立模块,提升代码可维护性。示例: # user/views.py fr…...
虚拟表、TDgpt、JDBC 异步写入…TDengine 3.3.6.0 版本 8 大升级亮点
近日,TDengine 3.3.6.0 版本正式发布。除了此前已亮相的时序数据分析 AI 智能体 TDgpt,本次更新还带来了多个针对性能与易用性的重要增强:虚拟表全面上线,支持更灵活的一设备一表建模;JDBC 写入机制全新升级࿰…...
大型语言模型智能应用Coze、Dify、FastGPT、MaxKB 对比,选择合适自己的LLM工具
大型语言模型智能应用Coze、Dify、FastGPT、MaxKB 对比,选择合适自己的LLM工具 Coze、Dify、FastGPT 和 MaxKB 都是旨在帮助用户构建基于大型语言模型 (LLM) 的智能应用的平台。它们各自拥有独特的功能和侧重点,以下是对它们的简要对比: Coz…...
WEB安全--XSS--DOM破坏
一、前言 继XSS基础篇后,我们知道了三种类型的XSS,这篇文章主要针对DOM型XSS的原理进行深入解析。 二、DOM型XSS原理 2.1、什么是DOM 以一个形象的比喻: 网页就像是一座房子,而 **DOM** 就是这座房子的“蓝图”或者“结构图”。…...
持续集成:GitLab CI/CD 与 Jenkins CI/CD 的全面剖析
一、引言 在当今快速迭代的软件开发领域,持续集成(Continuous Integration,CI)已成为保障软件质量、加速开发流程的关键实践。通过频繁地将代码集成到共享仓库,并自动进行构建和测试,持续集成能够尽早发现并解决代码冲突和缺陷。而 GitLab CI/CD 和 Jenkins CI/CD 作为两…...
Go语言sync.Mutex包源码解读
互斥锁sync.Mutex是在并发程序中对共享资源进行访问控制的主要手段,对此Go语言提供了非常简单易用的机制。sync.Mutex为结构体类型,对外暴露Lock()、Unlock()、TryLock()三种方法,分别用于阻塞加锁、解锁、非阻塞加锁操作(加锁失败…...
FreeRTOS软件定时器
软件定时器就是"闹钟",你可以设置闹钟, 用软件定时器的话USE_TIMER要设置为1 在30分钟后让你起床工作每隔1小时让你例行检查机器运行情况 软件定时器也可以完成两类事情: 在"未来"某个时间点,运行函数周期…...
Selenium三大等待
一、强制等待 1.设置完等待后不管有没有找到元素,都会执行等待,等待结束后才会执行下一步 2.实例: driver webdriver.Chrome()driver.get("https://www.baidu.com")time.sleep(3) # 设置强制等待driver.quit() 二、隐性等待 …...
【Ansible自动化运维】一、初步了解,开启自动化运维之旅
在当今数字化时代,随着企业 IT 基础设施规模的不断扩大,传统的手工运维方式逐渐显得力不从心。自动化运维技术应运而生,其中 Ansible 凭借其简洁易用、功能强大的特点,成为众多运维工程师和开发人员的首选工具。本篇文章将从基础概…...
雪花算法、md5加密
雪花算法生成ID是一个64位长整型(但是也可以通过优化简短位数) 组成部分: 时间戳 机器ID 序列号 用途: 分布式系统唯一ID生成:解决数据库自增ID在分布式环境下的唯一性问题、避免UUID的无序性和性能问题 有序性…...