当前位置: 首页 > news >正文

顺序表(C 语言)

目录

  • 一、线性表
  • 二、顺序表
    • 1. 静态顺序表
    • 2. 动态顺序表
      • 2.1 动态顺序表的实现分析
      • 2.2 动态顺序表的实现
      • 2.3 动态顺序表存在的问题
  • 三、与数组有关的面试题
    • 1. 移除元素
    • 2. 删除有序数组中的重复项

一、线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
在这里插入图片描述

二、顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表分为静态顺序表和动态顺序表,静态顺序表是数组大小固定,只能存储定量的数组,超出了就不能存储;动态顺序表使用一个指针管理动态数组,当数组不够存储时可以使用 realloc() 函数进行动态增容。

而一般情况下我们都是使用动态顺序表,因为静态顺序表大小固定,多了不够用,少了浪费空间。

1. 静态顺序表

这里这给出静态顺序表的大体框架,并不实现。

// 静态顺序表// 容量
#define CAPACITY 100// 数据类型
typedef int SSL_DataType;// 静态顺序表结构声明
typedef struct Static_SeqList
{SSL_DataType datas[CAPACITY];  // 数据size_t size;  // 当前数据个数
}SSeqList;// 操作// 初始化
void InitSSeqList(SSeqList* pssl);// 尾插
void SSeqListPushBack(SSeqList* pssl, SSL_DataType data);// 尾删
void SSeqListPopBack(SSeqList* pss1);// 头插
void SSeqListPushFront(SSeqList* pssl, SSL_DataType data);// 头删
void SSeqListPopFront(SSeqList* pssl, SSL_DataType data);// 查找
void SSeqListFind(SSeqList* pssl, SSL_DataType data);// 在 pos 位置插入
void SSeqListInsert(SSeqList* pssl, size_t pos, SSL_DataType data);// 删除 pos 位置的数据
void SSeqListErase(SSeqList* pssl, size_t pos, SSL_DataType data);// 打印
void SSeqListPrint(SSeqList* pssl);

如果需要使用静态顺序表,那么就在另一个 .c 文件中实现其操作功能,然后在主函数中调用即可。

2. 动态顺序表

相比于静态顺序表,动态顺序表增加了一个 capacity 成员表示容量,因为需要比较判断是否增容。还增加了几个操作功能,容量检查和销毁顺序表,销毁顺序表也就是释放动态内存。

2.1 动态顺序表的实现分析

(1)成员:动态申请数据 datas 的初始空间,当前数据的个数 size,容量的大小 capacity
(2)操作:
a. 初始化:申请数据空间,当前数据个数 size 归零,容量 capacity 设置为初始值
b. 检查容量:当执行插入操作的时候,需要检查当前顺序表是否需要增容
c. 头插:在表头插入数据
d. 头删:在表头删除数据
e. 尾插:在表尾插入数据
f. 尾删:在表尾删除数据
g. 查找:在表中查找指定数据,找到了返回下标,没找到返回 -1
h. 插入:在给定下标处插入数据,下标范围 0-size
i. 删除:在给定下标处删除数据,下标范围 0-size-1
j. 打印:打印顺序表的所有数据
k. 销毁:释放申请空间,size 和 capacity 归零

2.2 动态顺序表的实现

下面是顺序表的三个文件:

头文件:SeqList.h

// 动态顺序表// 数据类型
typedef int SL_DataType;// 初始容量
#define INIT_CAPACITY 2// 动态顺序表结构声明
typedef struct SeqList
{SL_DataType* datas;  // 数据size_t size;  // 当前数据个数size_t capacity;  // 当前容量
}SeqList;// 操作声明// 初始化
void SeqListInit(SeqList* psl);// 检查容量
void CheckCapacity(SeqList* psl);// 尾插
void SeqListPushBack(SeqList* psl, SL_DataType data);// 尾删
void SeqListPopBack(SeqList* psl);// 头插
void SeqListPushFront(SeqList* psl, SL_DataType data);// 头删
void SeqListPopFront(SeqList* psl);// 查找
int SeqListFind(SeqList* psl, SL_DataType data);// 在 pos 位置插入数据
void SeqListInsert(SeqList* psl, size_t pos, SL_DataType data);// 删除 pos 位置数据
void SeqListErase(SeqList* psl, size_t pos);// 打印顺序表
void SeqListPrint(SeqList* psl);// 销毁顺序表
void SeqListDestory(SeqList* psl);

操作实现文件:SeqList.c

// 头文件
#include "SeqList.h"
#include <assert.h>
#include <stdlib.h>// 操作定义// 初始化
void SeqListInit(SeqList* psl)
{// 检查空指针assert(psl);// 容量psl->capacity = INIT_CAPACITY;// 申请空间psl->datas = (SL_DataType*)malloc(sizeof(SL_DataType) * psl->capacity);// 判断是否申请成功if (NULL == psl->datas){perror("SeqListInit::malloc: ");return;}// 当前数据个数psl->size = 0;
}// 检查容量
void CheckCapacity(SeqList* psl)
{assert(psl);// 判断是否需要增容if (psl->size == psl->capacity){// 增容两倍SL_DataType* tmp = (SL_DataType*)realloc(psl->datas, sizeof(SL_DataType) * psl->capacity * 2);// 判断是否增容成功if (NULL == tmp){perror("CheckCapacity::realloc: ");return;}// 成功psl->datas = tmp;psl->capacity *= 2;tmp = NULL;}}// 尾插
void SeqListPushBack(SeqList* psl, SL_DataType data)
{assert(psl);// 检查增容CheckCapacity(psl);// 插入psl->datas[psl->size++] = data;
}// 尾删
void SeqListPopBack(SeqList* psl)
{assert(psl);// 检查当前表中是否有数据if (0 == psl->size){printf("There is no data!\n");return;}// 删除--psl->size;
}// 头插
void SeqListPushFront(SeqList* psl, SL_DataType data)
{assert(psl);// 判断增容CheckCapacity(psl);// 把所有元素往后挪动int i;for (i = (int)psl->size; i > 0; --i)psl->datas[i] = psl->datas[i - 1];// 插入psl->datas[0] = data;++psl->size;
}// 头删
void SeqListPopFront(SeqList* psl)
{assert(psl);// 检查当前表中是否有数据if (0 == psl->size){printf("There is no data!\n");return;}// 把后面 sz-1 个元素往前移int i;for (i = 1; i < psl->size; ++i)psl->datas[i - 1] = psl->datas[i];// 删除--psl->size;}// 查找
int SeqListFind(SeqList* psl, SL_DataType data)
{assert(psl);int i;for (i = 0; i < psl->size; ++i){// 找到了返回下标if (psl->datas[i] == data){return i;}}// 没找到返回 -1return -1;
}// 在 pos 位置插入数据
void SeqListInsert(SeqList* psl, size_t pos, SL_DataType data)
{assert(psl);// 判断下标是否合法if (pos<0 || pos > psl->size){printf("Illegal subscript!\n");return;}// 判断增容CheckCapacity(psl);// 把从该下标开始的元素都往后移一位int i;for (i = (int)psl->size; i > pos; --i){psl->datas[i] = psl->datas[i - 1];}// 插入psl->datas[pos] = data;++psl->size;
}// 删除 pos 位置数据
void SeqListErase(SeqList* psl, size_t pos)
{assert(psl);// 判断坐标是否合法if (pos < 0 || pos >= psl->size){printf("Illegal subscript!\n");return;}// 把从 pos+1 开始的元素都往前移int i;for (i = (int)pos + 1; i < psl->size; ++i)psl->datas[i - 1] = psl->datas[i];// 删除--psl->size;
}// 打印顺序表
void SeqListPrint(SeqList* psl)
{assert(psl);// 判断表中是否有数据if (0 == psl->size){printf("There is no data!\n");return;}// 打印int i;for (i = 0; i < psl->size; ++i)printf("%d ", psl->datas[i]);printf("\n");
}// 销毁顺序表
void SeqListDestory(SeqList* psl)
{assert(psl);// 释放空间free(psl->datas);psl->datas = NULL;psl->capacity = 0;psl->size = 0;
}

测试文件:test.c

// 头文件
#include "SeqList.h"// 头插头删测试
void test1(SeqList* PSL)
{// 头插加打印SeqListPushFront(PSL, 1);SeqListPrint(PSL);SeqListPushFront(PSL, 2);SeqListPrint(PSL);SeqListPushFront(PSL, 3);SeqListPrint(PSL);SeqListPushFront(PSL, 4);SeqListPrint(PSL);SeqListPushFront(PSL, 5);SeqListPrint(PSL);// 头删加打印SeqListPopFront(PSL);SeqListPrint(PSL);SeqListPopFront(PSL);SeqListPrint(PSL);SeqListPopFront(PSL);SeqListPrint(PSL);SeqListPopFront(PSL);SeqListPrint(PSL);SeqListPopFront(PSL);SeqListPrint(PSL);
}// 尾插尾删测试
void test2(SeqList* PSL)
{// 尾插加打印SeqListPushBack(PSL, 1);SeqListPrint(PSL);SeqListPushBack(PSL, 2);SeqListPrint(PSL);SeqListPushBack(PSL, 3);SeqListPrint(PSL);SeqListPushBack(PSL, 4);SeqListPrint(PSL);SeqListPushBack(PSL, 5);SeqListPrint(PSL);// 尾删加打印SeqListPopBack(PSL);SeqListPrint(PSL);SeqListPopBack(PSL);SeqListPrint(PSL);SeqListPopBack(PSL);SeqListPrint(PSL);SeqListPopBack(PSL);SeqListPrint(PSL);SeqListPopBack(PSL);SeqListPrint(PSL);
}// pos 位置插入删除测试
void test3(SeqList* PSL)
{// 在 pos 位置插入加打印SeqListInsert(PSL, 0, 1);SeqListPrint(PSL);SeqListInsert(PSL, 1, 9);SeqListPrint(PSL);SeqListInsert(PSL, 0, 8);SeqListPrint(PSL);SeqListInsert(PSL, 1, 3);SeqListPrint(PSL);SeqListInsert(PSL, 1, 7);SeqListPrint(PSL);SeqListInsert(PSL, 3, 6);SeqListPrint(PSL);// 在 pos 位置删除加打印SeqListErase(PSL, 0);SeqListPrint(PSL);SeqListErase(PSL, PSL->size - 1);SeqListPrint(PSL);SeqListErase(PSL, 1);SeqListPrint(PSL);SeqListErase(PSL, 1);SeqListPrint(PSL);SeqListErase(PSL, 0);SeqListPrint(PSL);SeqListErase(PSL, 0);SeqListPrint(PSL);
}// 查找功能测试
void test4(SeqList* PSL)
{// 插入数据SeqListPushBack(PSL, 1);SeqListPushBack(PSL, 3);SeqListPushBack(PSL, 5);SeqListPushBack(PSL, 7);SeqListPushBack(PSL, 9);SeqListPushBack(PSL, 10);SeqListPushBack(PSL, 8);SeqListPushBack(PSL, 6);SeqListPushBack(PSL, 4);SeqListPushBack(PSL, 2);// 打印SeqListPrint(PSL);// 查找int i;for (i = 1; i <= 10; ++i){printf("元素 %d 的下标为: %d\n", i, SeqListFind(PSL, i));}}int main()
{// 测试顺序表// 创建顺序表SeqList SL;// 初始化顺序表SeqListInit(&SL);// 头插头删测试printf("头插头删测试:\n");test1(&SL);// 尾插尾删测试printf("\n\n尾插尾删测试:\n");test2(&SL);// 在 pos 位置插入删除测试printf("\n\n在 pos 位置插入删除测试:\n");test3(&SL);// 查找功能测试printf("\n\n查找功能测试:\n");test4(&SL);// 销毁顺序表SeqListDestory(&SL);return 0;
}

该顺序表的每个功能作者都测试过,基本上没有问题。但是在调试的时候发现了动态内存的越界访问问题,经过调试发现,是扩容之后的容量 capacity 没有乘以 2。总得来说,顺序表的增删查改基本功能均已实现,如果大家发现了上述代码的错误,欢迎告知。

下面是在 x86 环境下,程序测试的结果:
在这里插入图片描述

2.3 动态顺序表存在的问题

通过对上述代码的学习发现动态顺序表存在以下问题:
(1)当进行头插、头删、插入和删除这四个操作的时候,需要挪动数组的数据,时间复杂度为 O(n)
(2)当容量不够的时候需要增容,每次增容后的容量是上一次的两倍,但是这样肯定会有空间的浪费。且增容需要申请新空间,拷贝数据,释放旧空间,这样会产生不小的时间消耗。

三、与数组有关的面试题

既然顺序表是在数组的基础上实现的,那么现在来看几道与数组有关的面试题。

1. 移除元素

题目描述: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:
(1)更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
(2)返回 k。

示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,,]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,,,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。

提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

题目OJ链接: 链接: link

题目解析: 这种在数组中原地删除数据的题目一般使用前后指针法,前指针 front,后指针 back。front 和 back 刚开始均指向数组首元素,只要 back 指向的元素的值不为 val,则 *front++ = *back++。要是后指针指向的元素的值为 val,则 front 不动,++back。重复上述步骤,直到 back 指向数组的尾后元素。最后返回 front 与数组首元素地址的差值。

图示过程:
在这里插入图片描述

可以发现最后要删除的数不是被后面的数覆盖了,就是跑到后面去了。而其他数都按照原来的顺序跑到前面去了。

代码如下:

// 移除元素
void remove_element(int* arr, int sz, int val)
{// 前后指针int* front = arr;int* back = arr;// 移除while (back < arr + sz){if (*back == val)++back;else*front++ = *back++;}// 返回return front - arr;
}

时间复杂度: O(n)
空间复杂度: O(1)

2. 删除有序数组中的重复项

题目描述: 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

(1)更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
(2)返回 k 。

示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

提示:
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 非严格递增 排列

题目OJ链接: link

题目思路: 本题也是使用前后指针法,前后指针刚开始都是指向数组首元素,若来指针指向的数组元素的值相同,那么 back 指针往后走,直到两个指针指向的值不同,然后先自增 front 指针,然后把 back 指向元素的值赋给 front 指向元素的值。重复上述步骤,直到 back 指向数组的尾后元素。最后返回 front 与数组首元素地址的差值。

图示过程:
在这里插入图片描述

代码如下:

// 删除有序数组中的重复项
int removeDuplicates(int* arr, int sz)
{// 前后指针int* front = arr;int* back = arr;// 开始删除while (back < arr + sz){if (*back == *front)++back;else*(++front) = *back;}// 返回return (int)(front - arr);
}

时间复杂度: O(n)
空间复杂度: O(1)

相关文章:

顺序表(C 语言)

目录 一、线性表二、顺序表1. 静态顺序表2. 动态顺序表2.1 动态顺序表的实现分析2.2 动态顺序表的实现2.3 动态顺序表存在的问题 三、与数组有关的面试题1. 移除元素2. 删除有序数组中的重复项 一、线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元…...

一:时序数据库-Influx应用

目录 0、版本号 1、登录页面 2、账号基本信息 3、数据库案例 4、可视化 5、java案例 0、版本号 InfluxDB v2.4.0 1、登录页面 http://127.0.0.1:8086/signin 账号&#xff1a;自己账号 密码&#xff1a;自己密码 2、账号基本信息 查看用户id和组织id&#xff01;&…...

Word文档丢失抢救方法:15 个 Word 文档恢复工具

MS Word 文档恢复的重要性 对于严重依赖 Microsoft Word 创建和编辑文档的个人和企业来说&#xff0c;MS Word 文档恢复是一个至关重要的方面。 文件损坏、系统崩溃和其他意外事件可能会导致 Word 文档中存储的重要数据丢失。 及时恢复这些文档有助于节省时间、精力和资源。 本…...

关于自动驾驶等级相关知识

本文主要介绍自动驾驶等级的一下知识&#xff0c;在介绍之前&#xff0c;首先要介绍一些基本知识&#xff0c;然后介绍自动驾驶不同等级 1、自动驾驶相关知识 监控和判断&#xff08;OEDA&#xff09;&#xff1a;指对车辆周围的物体和事件进行检测和感知&#xff0c;并给出应…...

Java中跳转结构

在Java中&#xff0c;跳转结构用于控制程序的执行流程。 2.4.1 break 用途: 用于终止当前循环&#xff08;for、while、do-while&#xff09;或switch语句。 public class BreakExample {public static void main(String[] args) {for (int i 0; i < 10; i) {if (i 5) …...

CNN-Attention分类预测 | Matlab实现多特征分类预测

CNN-Attention分类预测 | Matlab实现多特征分类预测 目录 CNN-Attention分类预测 | Matlab实现多特征分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现CNN-Attention卷积神经网络融合注意力机制多特征分类预测&#xff0c;运行环境Matlab2023b及以上…...

[java][基础]JSP

目标&#xff1a; 理解 JSP 及 JSP 原理 能在 JSP中使用 EL表达式 和 JSTL标签 理解 MVC模式 和 三层架构 能完成品牌数据的增删改查功能 1&#xff0c;JSP 概述 JSP&#xff08;全称&#xff1a;Java Server Pages&#xff09;&#xff1a;Java 服务端页面。是一种动态的…...

《测绘学报》

《测绘学报》 办刊宗旨&#xff1a;尊重科学、弘扬学术、追求卓越、求实创新。60多年来&#xff0c;《测绘学报》作为承载着测绘地理信息科学技术和科研成果的载体&#xff0c;作为测绘地理信息行业人才培养和学术交流的阵地&#xff0c;坚持把学术论文的质量放在期刊工作的重要…...

代码随想录之链表刷题总结

目录 1.链表理论基础 2.移除链表元素 3.设计链表 4.翻转链表 5.两两交换链表中的节点 6.删除链表中的第N个节点 7.链表相交 8.环形链表 1.链表理论基础 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域…...

Python爬虫的“京东大冒险”:揭秘商品类目信息

开篇&#xff1a;欢迎来到Python的奇幻森林 在这个数据驱动的时代&#xff0c;我们就像一群探险家&#xff0c;穿梭在数字的森林中&#xff0c;寻找着隐藏的宝藏——商品类目信息。今天&#xff0c;我们将带领你一起&#xff0c;用Python这把锋利的剑&#xff0c;深入京东的神…...

双目视觉标定——1原理与实践

0 前言 双目视觉定位是目前机器&#xff08;机器人&#xff09;等领域中使用得非常广泛的视觉定位技术&#xff0c;双目视觉是模拟人的视觉系统利用两个不同位置的摄像头的视差来确定物体的位置。由于有需要采集两个摄像头的图像共同参与计算&#xff0c;所以双目相机装配要求…...

【设计模式系列】代理模式(八)

一、什么是代理模式 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它为其他对象提供一种代理以控制对这个对象的访问。代理模式在不直接访问实际对象的情况下&#xff0c;提供了对目标对象的间接访问。通过引入一个代理对象来间接操作实际对…...

微服务架构设计的初次尝试——基于以太坊智能合约 + NestJS 微服务的游戏社区与任务市场系统:架构设计

TMDOG微服务架构设计的初次尝试——基于以太坊智能合约 NestJS 微服务的游戏社区与任务市场系统&#xff1a;架构设计 一、开发背景及目的 随着区块链技术的蓬勃发展以及去中心化概念的兴起&#xff0c;越来越多的开发者开始探索如何将区块链应用到实际业务场景中&#xff0…...

“北斗+实景三维”,助力全域社会治理

在国家治理体系和治理能力现代化的大背景下&#xff0c;全域社会治理成为提升国家治理效能的关键。“北斗实景三维”技术组合&#xff0c;为全域社会治理提供了新的技术支撑和解决方案。本文将探讨这一技术如何助力全域社会治理&#xff0c;以及其在实际应用中的潜力和挑战。 …...

#渗透测试#SRC漏洞挖掘# 信息收集-常见端口及谷歌语法

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

如何使用java雪花算法在分布式环境中生成唯一ID?

引言 在现代分布式系统中,生成唯一标识符(ID)是一个常见的需求。传统的自增ID在分布式环境中会导致冲突,因此需要一种能够在分布式系统中生成全局唯一ID的算法。 雪花算法(Snowflake)就是为了解决这个问题而提出的一种高效的ID生成算法。本文将详细介绍雪花算法的原理、…...

【php常用公共函数】php获取指定时间段相差几小时,几分钟,几秒

实现代码 <?php function diffTime($datetime1, $datetime2) {// 确保 $datetime1 总是小于或等于 $datetime2if (strtotime($datetime1) > strtotime($datetime2)) {$tmp $datetime2;$datetime2 $datetime1;$datetime1 $tmp;}// 转换为时间戳$timestamp1 strtotim…...

图文深入介绍Oracle DB link(一)

1. 引言&#xff1a; 本文图文深入介绍Oracle DB link&#xff0c;先介绍基本概念。 2.DB link的定义 数据库链接&#xff08;Database Link&#xff0c;简称 DB Link&#xff09;是 Oracle 数据库中的一个重要功能。它是一种在一个 Oracle 数据库实例中访问另一个 Oracle 数…...

Uniswap/v2-core使用及其交易流程

Uniswap是一个开源的去中心化的交易所&#xff0c;在github上面有以下重要仓库&#xff1a; uniswap-v2-core&#xff1a; 币对池pair的核心智能合约。这个repository包含了Uniswap的币对池pair的所有核心逻辑&#xff0c;增加流动性、减少流动性等。uniswap-v2-periphery&…...

clickhouse运维篇(二):多机器手动部署ck集群

熟悉流程并且有真正部署需求可以看一下我的另一篇简化部署的文章&#xff0c;因为多节点配置还是比较麻烦的先要jdk、zookeeper&#xff0c;再ck&#xff0c;还有各种配置文件登录不同机器上手动改配置文件还挺容易出错的。 clickhouse运维篇&#xff08;三&#xff09;&#x…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...