数据结构*排序
排序的一些相关概念
稳定性
假设在待排序序列中,存在两个元素A和B,A和B的值相同。在排序后,A和B的相对位置没有变化,就说这排序是稳定的。反之不稳定。
内部排序与外部排序
内部排序:数据完全存储在内存中,排序过程无需访问外部存储设备(如硬盘),直接在内存中完成。
外部排序:数据量过大,无法一次性装入内存,需借助外部存储设备(如硬盘、U 盘),通过内存与外存的多次数据交换完成排序。
一些重要的排序算法
直接插入排序
网上找的动画演示可看一下,深刻理解直接插入的过程。
文字描述如下:
代码展示:
/*** 时间复杂度为:O(N^2)* 进行优化后,当数组本身有序,时间复杂度最好为:O(N)* 空间复杂度为:O(1)* 稳定性:稳定* @param array*/
public void directInsertionSort(int[] array) {for (int i = 1; i < array.length; i++) {int temp = array[i];int j = i - 1;//将比temp大的元素往后移while (j >=0 && array[j] > temp) {array[j + 1] = array[j];j--;}//此时j下标的值比temp小,插入到其前面array[j + 1] = temp;}
}
代码分析:
上述代码的时间复杂度为:O(N^2);空间复杂度为:O(1);稳定性:稳定。
当已是正序的情况下,代码不会进入内循环,此时时间复杂度为:O(N)。
所以说:元素集合越接近有序,直接插入法的时间效率就高。
希尔排序
希尔排序在直接插入排序的基础上,对数组进行了分块排序。先让数组元素尽可能地接近有序状态,最终使整个数组完全有序。
代码展示:
/**希尔排序*时间复杂度为:* 根据实际来确定的,一般认为在 O(N*1.3) ~ O(N*1.5)* 空间复杂度:O(1)* 稳定性:不稳定* @param array*/
public void shellSort(int[] array) {int gap = array.length;while (gap > 1) {gap = gap / 2;//每次缩小分组,让数组逐渐有序shell(array,gap);}
}
private void shell(int[] array,int gap) {//直接插入排序for (int i = gap; i < array.length; i++) {//这里i++,使得组与组之间交替进行插入排序//由于是组内的直接插入排序,所以元素与元素直接差值是gap,而不是1了。int temp = array[i];int j = i - gap;//将比temp大的元素往后移while (j >= 0 && array[j] > temp) {array[j + gap] = array[j];j = j - gap;}array[j + gap] = temp;}
}
代码分析:
这里相比于直接用直接插入排序,这里将数组逐渐有序起来,直接插入时间复杂度更低。其次,采用交叉分组的方式,将大的元素能放在数组后面,小的元素放在数组前面。
上述代码的时间复杂度为:不同情况不同结果;空间复杂度为:O(1);稳定性:不稳定。最坏时间复杂度为:O(N^2),平均情况下约为:O(N*1.3)
选择排序
将数据分为已排序的和未排序的。在未排序中找到最小(大)值的下标,然后和未排序的第一个进行交换,这样就能保证是有序的。
代码展示:
/*** 时间复杂度为:O(N^2)* 空间复杂度为:O(1)* 稳定性:不稳定* @param array*/
public void selectionSort(int[] array) {for (int i = 0; i < array.length; i++) {int minIndex = i;//minIndex初始为未排序的起始下标ifor (int j = i + 1; j < array.length; j++) {//从i + 1这个下标开始找最小值下标if(array[minIndex] > array[j]) {minIndex = j;//找到未排序中最小值的下标}}//交换未排序的第一个与最小值swap(array, minIndex, i);}
}
private void swap(int[] array, int a ,int b) {int temp = array[a];array[a] = array[b];array[b] = temp;
}
代码分析:
上述代码的时间复杂度为:O(N^2);空间复杂度为:O(1);稳定性:不稳定
堆排序
在堆的学习中有学习过
数据结构*堆
代码展示:
/*** 从小到大排序* 时间复杂度为:O(N*logN)* 空间复杂度为:O(1)* 稳定性:不稳定* @param array*/
public void heapSort(int[] array) {//先创建一个最大堆,时间复杂度为:O(N)for (int parent = ((array.length - 1) - 1) / 2; parent >= 0 ; parent--) {shiftDown(array,parent,array.length);}int end = array.length - 1;//进行排序,时间复杂度为:O(N*logN) <---- 有N次调整,每次调整的时间复杂度为:O(logN)while (end > 0) {swap(array,0,end);end--;shiftDown(array,0,end + 1);}
}
private void swap(int[] array,int a,int b) {int temp = array[a];array[a] = array[b];array[b] = temp;
}
private void shiftDown(int[] array ,int parent,int useSize) {int child = 2 * parent + 1;while (child < useSize) {if(child + 1 <useSize && array[child] < array[child + 1]) {child++;}if(array[parent] < array[child]) {swap(array,parent,child);parent = child;child = 2 * parent + 1;}else {break;}}
}
代码分析:
上述代码的时间复杂度为:O(N*logN);空间复杂度为:O(1);稳定性:不稳定
冒泡排序
是将数据两两比较,大的数据往后移(交换)。每趟就将最大的数据放到后面。一共要走N - 1趟。每趟元素从开头进行比较,比较到有序的数据就停止比较。
别人制作的冒泡排序视频
代码展示:
/*** 时间复杂度:O(N^2)* 进行优化后,当数组本身有序时间复杂度最好为:O(N)* 空间复杂度:O(1)* 稳定性:稳定* @param array*/
public void BubbleSort(int[] array) {//一共要走N - 1趟for (int i = 1; i < array.length; i++) {boolean flag = false;//每趟对未有序的数据进行比较交换for (int j = 0; j < array.length - i; j++) {if(array[j] > array[j + 1]) {swap(array,j,j + 1);flag = true;}}if(!flag) {//说明没有在进行交换了,已经有序了return;}}
}
private void swap(int[] array, int a ,int b) {int temp = array[a];array[a] = array[b];array[b] = temp;
}
代码分析:
上述代码的时间复杂度为:O(N^2);空间复杂度为:O(1);稳定性:稳定
快速排序
选择一个基准元素,使其左边都是小于基准元素的值,右边都是大于基准元素的值。再进行分区操作,重复这个过程。
代码展示:
/***时间复杂度为:* 最好情况下为:O(N*logN),每次找的基准都是中间的值* 最坏情况下为:O(N^2),正序或逆序(即是一棵单分支的树)* 空间复杂度:* 最好情况下为:O(logN),每次找的基准都是中间的值* 最坏情况下为:O(n),正序或逆序(即是一棵单分支的树)* 稳定性:不稳定* @param array*/
public void quickSort(int[] array) {quick(array,0,array.length - 1);
}
private void quick(int[] array,int start,int end) {if(start >= end) {return;}int par = standard(array,start,end);//standard()方法用来获得在区间范围内的基准,并使左边小于基准,右边大于基准quick(array,start,par - 1);quick(array,par + 1,end);
}
对于实现standard()方法有三种方法:
1、挖坑法:
private int standardDigging(int[] array,int low,int high) {int temp = array[low];while (low < high) {while (low < high && array[high] >= temp) {high--;}array[low] = array[high];while (low < high && array[low] <= temp) {low++;}array[high] = array[low];}array[low] = temp;return low;
}
2、Hoare法:
private int standardHoare(int[] array,int low,int high) {int pivot = array[low];int i = low;while (low < high) {while (low < high && array[high] >= pivot) {high--;}while (low < high && array[low] <= pivot) {low++;}swap(array,low,high);}swap(array,i,low);return low;
}
private void swap(int[] array, int a ,int b) {int temp = array[a];array[a] = array[b];array[b] = temp;
}
3、前后指针法:
private int standardPoint(int[] array,int low,int high) {int pivot = array[low];int prev = low;//prev用来标记小于等于基准值for(int cur = prev + 1;cur <= high;cur++) {//cur用来标记大于基准值if(array[cur] <= pivot) {prev++;//扩大小于等于基准值的区域swap(array,cur,prev);//将小于等于基准值的值放到前面来}}swap(array,low,prev);//将基准值放到最终位置return prev;//返回基准值索引
}
private void swap(int[] array, int a ,int b) {int temp = array[a];array[a] = array[b];array[b] = temp;
}
代码分析:
下图主要展示了排序的总逻辑:(类似二叉树的形式)
具体的实现“左边都是小于基准元素的,右边都是大于基准元素”,可以用挖坑法、Hoare法、前后指针法。(使用频率:挖坑法 > Hoare法 > 前后指针法)
上述代码的时间复杂度为:1、最好情况下为:O(N*logN) 2、最坏情况下为:O(N^2);空间复杂度:1、最好情况下为:O(logN) 2、最坏情况下为:O(n);稳定性:不稳定。
注意:
在找基准的方法中:
1、挖坑法代码中的while循环的条件那里需要有等号
while (low < high) {while (low < high && array[high] > temp) {少了等号high--;}array[low] = array[high];while (low < high && array[low] < temp) {//少了等号low++;}array[high] = array[low];
}
当原数组首元素和尾元素相等,就会导致一直交换这两个相同的元素,死循环。
2、在Hoare法代码中调整数组的while循环中要先high找小于基准值的值。
while (low < high) {while (low < high && array[low] <= pivot) {low++;}//错误while (low < high && array[high] >= pivot) {high--;}swap(array,low,high);
}
由于我们一开始是定义首元素为基准值,如果low先动的话,最后low和high相遇的值要比基准值大,导致并没有实现左边都是小于基准元素的值,右边都是大于基准元素的值。
代码优化:
1、三数取中
在最坏情况下(正序、逆序等),当我们取区间首元素为基准值时,这样分割不均匀。这时候我们可以在区间首元素、尾元素、中间元素中找到中间大的数字。
private void quick(int[] array,int start,int end) {if(start >= end) {return;}//三数取中int standard = medianOfNumbers(array,start,end);swap(array,start,standard);//找到了中间值,将它和原来定的标准值交换(标准值还在首下标)int par = standardDigging(array,start,end);quick(array,start,par - 1);quick(array,par + 1,end);
}
private int medianOfNumbers(int[] array,int low,int high) {int mid = (low + high) / 2;//确保array[low] <= array[high]if(array[low] > array[high]) {swap(array,low,high);}//确保array[low] <= array[mid]if(array[low] > array[mid]) {swap(array,low,mid);}//到这里说明array[low]是最小的//确保array[mid] <= array[high]if(array[mid] > array[high]) {swap(array,mid,high);}//说明array[mid]是中间值,返回mid下标return mid;
}
2、小数组优化
在排序到后面的时候,数组已趋于有序。此时数组被分成了许多小数组,但如果继续递归,效率会相比其他的排序低很多。这时候我们可以考虑使用插入排序来提高效率。
private void quick(int[] array,int start,int end) {if(start >= end) {return;}//小数组优化int VALUE = 10;if(end - start + 1 == VALUE) {//直接插入排序directInsertionSort(array,start,end);return;}//三数取中int standard = medianOfNumbers(array,start,end);swap(array,start,standard);int par = standardDigging(array,start,end);quick(array,start,par - 1);quick(array,par + 1,end);
}
public void directInsertionSort(int[] array,int start,int end) {for (int i = start + 1; i <= end; i++) {int temp = array[i];int j = i - 1;//将比temp大的元素往后移while (j >= 0 && array[j] > temp) {array[j + 1] = array[j];j--;}}
}
非递归实现快速排序
代码展示:
private void quickNor(int[] array,int start,int end) {int par = standardDigging(array,start,end);// 创建栈用于保存待排序子数组的左右边界Stack<Integer> stack = new Stack<>();//当分成的数组长度为1,1个元素本身就是有序的,无需继续分if(start < par - 1) {//分的数组长度大于等于二stack.push(start);stack.push(par - 1);}if(end > par + 1) {//分的数组长度大于等于二stack.push(par + 1);stack.push(end);}while (!stack.empty()) {end = stack.pop();//一开始弹出来的是后进去的endstart = stack.pop();//接下来就是重复上面的过程,直至栈为空,说明没有子数组需要排序了par = standardDigging(array,start,end);if(start < par - 1) {stack.push(start);stack.push(par - 1);}if(end > par + 1) {stack.push(par + 1);stack.push(end);}}
}
代码分析:
1、初始划分:
选择基准值,将数组分为【左半部分 ≤ 基准值】和【右半部分 ≥ 基准值】,获取基准值位置par。
2、栈管理子数组:
用栈保存待排序子数组的左右边界(start和end)。
先处理初始划分后的左右子数组(若长度≥2),将其边界压入栈。
3、迭代处理栈元素:
循环弹出栈顶子数组,对其进行划分,得到新基准值位置。
将新产生的左右子数组边界(若长度≥2)压入栈,确保所有子数组被处理。
4、终止条件:
栈空时,所有子数组排序完成。
归并排序
将数组不断地平分成两个数组,最后合并两个有序数组并排序。一开始合并是两个单元素数组合并。
代码展示:
/**归并排序* 时间复杂度:O(N*logN)* 空间复杂度:O(N)* 稳定性:稳定* @param array*/
public void mergeSort(int[] array) {mergeSortChild(array,0,array.length - 1);
}
private void mergeSortChild(int[] array,int left,int right) {if(left == right) {return;}int mid = (left + right) / 2;mergeSortChild(array,left,mid);mergeSortChild(array,mid + 1,right);//合并两个有序数组merge(array,left,mid,right);
}
private void merge(int[] array,int left,int mid,int right) {int s1 = left;int e1 = mid;int s2 = mid + 1;int e2 = right;int[] temp = new int[right - left + 1];int index = 0;while (s1 <= e1 && s2 <= e2) {if(array[s1] > array[s2]) {temp[index] = array[s2];s2++;}else {temp[index] = array[s1];s1++;}index++;}while (s2 <= e2) {temp[index] = array[s2];index++;s2++;}while (s1 <= e1) {temp[index] = array[s1];index++;s1++;}//此时temp数组就是排好序的数组for (int i = 0; i < temp.length; i++) {array[i + left] = temp[i];}
}
代码分析:
上述代码采用递归的方法,先完成左边数组的归并,在完成右边数组的归并。大致总逻辑如下图所示:
上述代码的时间复杂度为:O(N*logN);空间复杂度为:O(N);稳定性:稳定
非递归实现归并排序
代码展示:
public void mergeSortNor(int[] array) {int gap = 1;while (gap < array.length) {//当gap >= array.length,说明整个数组都完成了归并//遍历所有子数组for (int i = 0; i < array.length; i++) {int left = i;int mid = left + gap -1;//当gap很大的时候,mid下标可能越界if(mid >= array.length) {mid = array.length - 1;}int right = mid + gap;//当gap很大的时候,right下标可能越界if(right >= array.length) {right = array.length - 1;}merge(array,left,mid,right);}gap*=2;}
}
代码分析:
gap用来表示要排序的子数组大小,每次扩大子数组的大小。
总结:
排序名称 | 时间复杂度(最好) | 时间复杂度(最坏) | 空间复杂度 | 稳定性 | 使用场景 |
---|---|---|---|---|---|
直接插入排序 | O(N) | O(N^2) | O(1) | 稳定 | 数据量较小,数据本身基本有序。 |
希尔排序 | O(N) | O(N^2) | O(1) | 不稳定 | 适用于大规模数据排序。如对大型文件中的数据进行初步排序。 |
选择排序 | O(N^2) | O(N^2) | O(1) | 不稳定 | 数据量较小且对排序稳定性无要求时可使用。 |
堆排序 | O(N*logN) | O(N*logN) | O(1) | 不稳定 | 适合处理大量数据且要求时间复杂度为O(N*logN) 级别的场景。 |
冒泡排序 | O(N^2) | O(N^2) | O(1) | 稳定 | 数据量较少,或者数据基本有序的情况。 |
快速排序 | O(N*logN) | O(N^2) | O(logN) ~ O(N) | 不稳定 | 大量数据的排序场景,是实践中平均性能最优的排序算法之一。 |
归并排序 | O(N*logN) | O(N*logN) | O(N) | 稳定 | 当处理大规模数据且要求排序稳定时使用。 |
每一种排序都有适合场景,甚至可以采用多种排序组合实现最优解。
相关文章:
数据结构*排序
排序的一些相关概念 稳定性 假设在待排序序列中,存在两个元素A和B,A和B的值相同。在排序后,A和B的相对位置没有变化,就说这排序是稳定的。反之不稳定。 内部排序与外部排序 内部排序:数据完全存储在内存中…...
新浪《经济新闻》丨珈和科技联合蒲江政府打造“数字茶园+智能工厂+文旅综合体“创新模式
5月14日,新浪网《经济新闻》频道专题报道珈和科技在第十四届四川国际茶业博览会上的精彩亮相,并深度聚焦我司以数字技术赋能川茶产业高质量发展创新技术路径,及在成都市“茶业建圈强链”主题推介会上,珈和科技与蒲江县人民政府就智…...
【Linux】第二十三章 控制启动过程
1. 请简要说明 RHEL9的启动过程。 (1)计算机通电。系统固件 (UEFI 或 BIOS) 开机自检 (POST),并初始化部分硬件,然后,固件会寻找启动设备(如硬盘、USB、网络等),并将控制权交给引导…...
深信服golang面经
for range 中赋值的变量,这个变量指向的是真实的地址吗,还是临时变量 不是真实地址,是临时变量 package mainimport "fmt"func main() {slice : []int{4, 2, 3}for _, v : range slice {fmt.Println(v, &v) // 这里的 v 是临…...
基于 Netty + SpringBoot + Vue 的高并发实时聊天系统设计与实现
一、系统架构设计 1.1 整体架构图 ------------------ WebSocket (wss) ------------------ Netty TCP ------------------ | Vue前端 | <-------------------------> | SpringBoot网关 | <------------------> | Netty服务集…...
根据当前日期计算并选取上一个月和上一个季度的日期范围,用于日期控件的快捷选取功能
代码如下: <el-date-picker v-model"value" type"monthrange" align"right" unlink-panels range-separator"至"start-placeholder"开始月份" end-placeholder"结束月份" :picker-options"pic…...
Spring Boot 使用 jasypt配置明文密码加密
引入依赖 <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.4</version> </dependency>添加配置 jasypt:encryptor:password: pssw0rd&Hubt2ec…...
ubuntu下docker安装mongodb-支持单副本集
1.mogodb支持事务的前提 1) MongoDB 版本:确保 MongoDB 版本大于或等于 4.0,因为事务支持是在 4.0 版本中引入的。 2) 副本集配置:MongoDB 必须以副本集(Replica Set)模式运行,即使是单节点副本集&#x…...
科技赋能,开启现代健康养生新潮流
在科技与生活深度融合的当下,健康养生也迎来了全新的打开方式。无需传统医学的介入,借助现代科学与智能设备,我们能以更高效、精准的方式守护健康。 饮食管理步入精准化时代。利用手机上的营养计算 APP,录入每日饮食࿰…...
《安徽日报》聚焦珈和科技AI创新:智慧虫情测报护航夏粮提质丰产
5月7日,《安徽日报》焦点新闻版块以《高科技助力田管,确保夏粮丰收——为4300多万亩小麦守好防线》为题,深度报道了农业科技在夏粮生产中的关键作用。其中,珈和科技自主研发的AI虫情测报一体机作为绿色防控、农业智慧化的标杆被重…...
企业级 Go 多版本环境部署指南-Ubuntu CentOS Rocky全兼容实践20250520
🛠️ 企业级 Go 多版本环境部署指南-Ubuntu / CentOS / Rocky 全兼容实践 兼顾 多版本管理、安全合规、最小权限原则与 CI/CD 可复现性,本指南以 Go 官方 toolchain 为主,结合 asdf 实现跨语言统一管理,并剔除已过时的 GVM。支持 …...
MCP 协议传输机制大变身:抛弃 SSE,投入 Streamable HTTP 的怀抱
在技术的江湖里,变革的浪潮总是一波接着一波。最近,模型上下文协议(MCP)的传输机制就搞出了大动静,决定和传统的服务器发送事件(SSE)说拜拜,转身拥抱 Streamable HTTP,这…...
Windows 上配置 Docker,Docker 的基本原理和用途,以及如何在 Docker 中运行程序
Windows 系统上的 Docker 安装与使用指南 1. Windows 上配置 Docker 检查系统要求:使用 64 位 Windows 10/11,BIOS 已启用硬件虚拟化(VT-x/AMD-V)。Windows 版本最好更新到 2004 及以上(内部版本19041)&am…...
CBCharacteristic:是「特征」还是「数据通道」?
目录 名词困惑:两种中文译法的由来官方定义 & 开发者视角乐高类比:文件夹与文件智能手表实例:Characteristic 长什么样?iOS 代码实战:读 / 写 / 订阅小结 & Best Practice 1. 名词困惑:为什么有两…...
【JavaEE】多线程
线程 在Java中,鼓励多线程编程。进程可以满足并发编程,但是效率不高(创建、销毁、调度时间都比较长,这些都消耗在申请资源上了),而线程就不一样。 线程也叫“轻量级进程”,创建、销毁、调度都更…...
docker- Harbor 配置 HTTPS 协议的私有镜像仓库
Harbor通过配置 HTTPS 协议,可以确保镜像传输的安全性,防止数据被窃取或篡改。本文将详细介绍如何基于 Harbor 配置 HTTPS 协议的私有镜像仓库。 1.生成自建ca证书 [rootdocker01 ~]# mkdir -p /liux/softwares/harbor/certs/custom/{ca,server,client…...
[SpringBoot]Spring MVC(5.0)----留言板
Spring留言板实现 预期结果 可以发布并显示点击提交后,显示并清除输入框并且再次刷新后,不会清除下面的缓存 约定前后端交互接口 Ⅰ 发布留言 url : /message/publish . param(参数) : from,to,say . return : true / false . Ⅱ 查询留言 url : /messag…...
Jules 从私有预览阶段推向全球公测
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
vLLM框架高效原因分析
vLLM框架在模型推理中以高效出名,主要基于以下核心原理和技术优化,这些设计使其在处理大语言模型时显著提升性能: 一、PagedAttention:动态显存管理技术 vLLM的核心创新在于PagedAttention,灵感源自操作系统的虚拟内存…...
【Git】常用命令大全
以下是 Git 的常用命令大全,分为几个常见类别,便于理解和使用: 1. 初始化与克隆 初始化本地仓库:git init克隆远程仓库到本地:git clone <repository_url> 2. 添加与提交 添加指定文件到暂存区:git…...
pycharm无需科学上网工具下载插件的解决方案
以下是两种无需科学上网即可下载 PyCharm 插件的解决思路: 方法 1:设置 PyCharm 代理 打开 PyCharm选择菜单:File → Settings → Appearance & Behavior → System Settings → HTTP Proxy在代理设置中进行如下配置: 代理地…...
学习threejs,使用Physijs物理引擎,使用DOFConstraint自由度约束,模拟小车移动
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Physijs 物理引擎1.1.1 ☘️…...
仓颉开发语言入门教程:常见UI组件介绍和一些问题踩坑
幽蓝君发现一个问题,仓颉开发语言距离发布马上一年了,一些知名App已经使用仓颉开发了许多功能,但是网络上关于仓颉开发语言的教程少之又少,系统性的教程更是没有,仓颉官网的文档也远远不如ArkTS详尽。 现阶段对于想学…...
[Git] 初识 Git 与安装入门
告别文件噩梦:初识 Git 与安装入门 嘿,朋友!不知道你是不是也遇到过这样的情况:你在写一份重要的文档、报告,或者更常见的,一段代码时,为了安全起见,怕改错了回不去,或者…...
海康威视摄像头C#开发指南:从SDK对接到安全增强与高并发优化
一、海康威视SDK核心对接流程 1. 开发环境准备 官方SDK获取:从海康开放平台下载最新版SDK(如HCNetSDK.dll、PlayCtrl.dll)。依赖项安装:确保C运行库(如vcredist_x86.exe)与S…...
大语言模型 14 - Manus 超强智能体 开源版本 OpenManus 上手指南
写在前面 Manus 是由中国初创公司 Monica.im 于 2025 年 3 月推出的全球首款通用型 AI 智能体(AI Agent),旨在实现“知行合一”,即不仅具备强大的语言理解和推理能力,还能自主执行复杂任务,直接交付完整成…...
使用 LibreOffice 实现各种文档格式转换(支持任何开发语言调用 和 Linux + Windows 环境)[全网首发,保姆级教程,建议收藏]
以下能帮助你可以使用任何开发语言,在任何平台都能使用 LibreOffice 实现 Word、Excel、PPT 等文档的自动转换,目前展示在 ASP.NET Core 中为 PDF的实战案例,其他的文档格式转换逻辑同理。 📦 1. 安装 LibreOffice 🐧…...
CentOS Stream 9 中部署 MySQL 8.0 MGR(MySQL Group Replication)一主两从高可用集群
🐇明明跟你说过:个人主页 🏅个人专栏:《MySQL技术精粹》🏅 🔖行路有良友,便是天堂🔖 目录 一、前言 1、MySQL 8.0 中的高可用方案 2、适用场景 二、环境准备 1、系统环境说明…...
软考中级软件设计师——计算机网络篇
一、计算机网络体系结构 1.OSI七层模型 1. 物理层(Physical Layer) 功能:传输原始比特流(0和1),定义物理介质(如电缆、光纤)的电气、机械特性。 关键设备:中继器&#…...
RK3568 OH5.1 源码编译及问题
安装编译器和二进制工具 在源码根目录下执行prebuilts脚本,安装编译器及二进制工具。 bash build/prebuilts_download.sh在源码根目录执行如下指令安装hb编译工具: python3 -m pip install --user build/hb使用build.sh脚本编译源码 进入源码根目录&…...
【razor】回环结构导致的控制信令错位:例如发送端收到 SR的问题
一、razor的echo程序 根据对 yuanrongxi/razor 仓库的代码和 echo 测试程序相关实现的分析,下面详细解读 echo 程序中 RTCP sender report(SR)、receiver report(RR)回显的问题及项目的解决方式。 1. 问题背景 在 RTP/RTCP 体系下,SR(Sender Report)由发送端周期性发…...
leetcode hot100:三、解题思路大全:哈希(两数之和、字母异位词分组、最长连续序列)、双指针(移动零、盛最多水的容器、三数之和、接雨水)
哈希 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返…...
MySQL 8.0 OCP 1Z0-908 161-170题
Q161.Examine this command, which executes successfully: cluster.addInstance ( ‘:’,{recoveryMethod: ‘clone’ 1}) Which three statements are true? (Choose three.) A)The account used to perform this recovery needs the BACKUP_ ADMIN privilege. B)A target i…...
onlyoffice 源码 调试说明 -ARM和x86双模式安装支持
很多用户在调试onlyoffice源码最大的问题是如何搭建环境,这个难度很高,下面提供一键安装的方式,让普通用户也能快速调试源码。 OnlyOffice Document Server 基于源码运行的容器调试模式,凭借 Docker 容器化技术的核心优势,为开发者提供了跨平台、高兼容性…...
workflow:高效的流式工作架构
引言 workflow是sougou的一款开源框架 主要是以请求回应的模式解决各自网络/IO任务而发明的 一.workflow的任务流 1.workflow都封装了哪些任务流 以请求回应的模式来解释 ① 网络层 服务端 在服务端的request 相当于发送了一个获取客户端请求的请求,response相当…...
音视频之H.265/HEVC速率控制
H.265/HEVC系列文章: 1、音视频之H.265/HEVC编码框架及编码视频格式 2、音视频之H.265码流分析及解析 3、音视频之H.265/HEVC预测编码 4、音视频之H.265/HEVC变换编码 5、音视频之H.265/HEVC量化 6、音视频之H.265/HEVC环路后处理 7、音视频之H.265/HEVC熵编…...
jsmpeg+java+ffmpeg 调用摄像头RTSP流播放
原理就是这样,明白吧。本次用springboot netty起这个2个服务,执行拉代码执行即可 <!-- netty --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.68.Final</ver…...
深度剖析ZooKeeper
1. ZooKeeper架构总览 ZooKeeper 是一个分布式协调服务,广泛用于分布式系统中的配置管理、命名服务、分布式锁和领导选举等场景。以下是对 ZooKeeper 架构、通信机制、容错处理、数据一致性与可靠性等方面的详细剖析。 一、ZooKeeper 主从集群 ZooKeeper 采用 主从…...
Zookeeper 集群安装与脚本化管理详解
安装之前:先关闭所有服务器的防火墙!!!!!!!!!!!! systemctl stop firewalld 关闭防火墙 systemctl disable firewalld 开机不启动防火…...
第10天-Python操作MySQL数据库全攻略:从基础连接到高级应用
一、环境准备 1. 安装MySQL驱动 bash 复制 下载 # 官方推荐驱动 pip install mysql-connector-python# 或使用PyMySQL(兼容性更好) pip install pymysql 2. 创建测试数据库 sql 复制 下载 CREATE DATABASE python_db; USE python_db;CREATE TABLE users (id INT AU…...
Spring Cloud Gateway深度解析:原理、架构与生产实践
文章目录 前言一、概述二、核心架构设计及设计原理2.1 分层架构模型网络层(I/O模型)核心处理层 2.2 核心组件协作流程路由定位阶段过滤器执行阶段 2.3 响应式编程模型实现Reactor上下文传递背压处理机制 2.4 动态路由设计原理2.5 异常处理体系2.6 关键路…...
Trae 04.22版本深度解析:Agent能力升级与MCP市场对复杂任务执行的革新
我正在参加Trae「超级体验官」创意实践征文,本文所使用的 Trae 免费下载链接:Trae - AI 原生 IDE 目录 引言 一、Trae 04.22版本概览 二、统一对话体验的深度整合 2.1 Chat与Builder面板合并 2.2 统一对话的优势 三、上下文能力的显著增强 3.1 W…...
股指期货模型,简单易懂的套利策略
在股指期货投资领域,有不少实用的模型和策略,今天咱们就用大白话来唠唠其中几个重要的概念。 一、跨期套利:合约间的“差价游戏” 跨期套利简单来说,就是投资者以赚取期货合约之间的价差为目的,在同一个期货品种的不…...
MySQL 故障排查与生产环境优化
目录 1. MySQL单实例故障排查 2. MySQL 主从故障排查 3. MySQL 优化 3.1 硬件方面 3.2 MySQL 配置文件 3.3 SQL 方面 1. MySQL单实例故障排查 (1) 故障现象1 ERROR 2002 (HY000): Cant connect to local MySQL server through socket /data/mysql…...
Java泛型 的详细知识总结
一、泛型的核心作用 类型安全:在编译期检查类型匹配,避免运行时的ClassCastException。代码复用:通过泛型逻辑统一处理多种数据类型。消除强制转换:减少显式的类型转换代码。 二、泛型基础语法 1. 泛型类/接口 定义:…...
k8s 配置 Kafka SASL_SSL双重认证
说明 kafka提供了多种安全认证机制,主要分为SASL和SSL两大类。 SASL: 是一种身份验证机制,用于在客户端和服务器之间进行身份验证的过程,其中SASL/PLAIN是基于账号密码的认证方式。 SSL: 是一种加密协议,…...
电商虚拟户:重构资金管理逻辑,解锁高效归集与智能分账新范式
一、电商虚拟户的底层架构与核心价值 在数字经济浪潮下,电商交易的复杂性与日俱增,传统账户体系已难以满足平台企业对资金管理的精细化需求。电商虚拟户作为基于银行或持牌支付机构账户体系的创新解决方案,通过构建“主账户子账户”的虚拟账户…...
从混乱到高效:我们是如何重构 iOS 上架流程的(含 Appuploader实践)
从混乱到高效:我们是如何重构 iOS 上架流程的 在开发团队中,有一类看不见却至关重要的问题:环境依赖。 特别是 iOS App 的发布流程,往往牢牢绑死在一台特定的 Mac 上。每次需要发版本,都要找到“那台 Mac”ÿ…...
01 基本介绍及Pod基础
01 查看各种资源 01-1 查看K8s集群的内置资源 [rootmaster01 ~]# kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 …...
DAY31-文件的规范拆分和写法
知识点回顾 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 (一)文件拆分 思考:如何把一个文件,拆分成多个具有着独立功能的文件,然后通过import的方式,来调用这些文件。这样具有几个…...