二叉树(堆)
目录
- 一、什么是堆?
- 二、堆的实现
- 2.1 结构体变量的声明
- 2.2 堆的初始化
- 2.3 堆的销毁
- 2.4 插入数据
- 2.5 删除数据
- 2.6 堆内有效数据的数目
- 2.7 取堆顶元素
- 2.8 判断堆是否为空
- 2.9 代码汇总
- 三、经典“TopK”问题
一、什么是堆?
heap 是一个抽象的数据结构,也可以说堆是逻辑上的数据结构,是我们人为想象出来的一种数据结构,并不是一个物理上真实存在的数据结构,堆的底层其实是用数组来实现的。
heap 其实有很多种实现方式,但是面试最常考的,也是最经典的,就是 binary heap 二叉堆,也就是用一棵完全二叉树来实现的。
那这颗完全二叉树怎么实现呢?其实它并没有那么难,底层就是用一个动态开辟的数组来实现的。
那是不是所有的二叉树都可以用数组来存储呢?本质上是可以的,但是如果不是完全二叉树,那就不适合用数组来存储了,因为完全二叉树的性质是除了最后一层之外,其他层的结点都是满的,并且最后一层的结点从左到右是连续的,这就决定了这颗完全二叉树的每一个结点都是连续的,而数组刚好就是一块连续的空间,所以用数组实现完全二叉树是适合的。但是如果不是完全二叉树,那每一个地方都有可能是空结点,那就会导致浪费了大量的空间,所以非完全二叉树就不适合用数组实现。
堆的特点:
1、堆是一棵完全二叉树;
2、堆序性 (heap order): 任意节点的优先级都优于它的所有孩子。
a.如果是任意节点都大于等于它的所有孩子,这样的堆叫大堆;
b. 如果是任意节点都小于等于它的所有孩子,这样的堆叫小堆;
c.堆是用数组来实现的,那么我们可以找到每个节点和它的父母/孩子之间的关系,从而可以直接访问到它们。
堆的父节点和子节点的下标存在以下关系:
1、leftchild=parent * 2+1;
2、rightchild=parent * 2+2;
3、parent=(child-1)/2;
二、堆的实现
2.1 结构体变量的声明
typedef int HeapDataType;typedef struct Heap
{//堆的结构体的内部就是一个动态开辟的数组HeapDataType* a;//记录有效数据的个数int sz;//记录数组的容量,方便增容int capacity;}HP;
2.2 堆的初始化
这个地方就是顺序表的初始化,大家应该都老生熟路了。
void HeapInit(HP* php)
{assert(php);php->a = (HeapDataType*)malloc(sizeof(HeapDataType) * 4);if (php->a == NULL){perror("malloc fail");return;}php->sz = 0;php->capacity = 4;
}
2.3 堆的销毁
void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->sz = php->capacity = 0;
}
2.4 插入数据
这里的插入数据可以随机插入吗??明显是不能的,因为堆是一种具有特殊性质的数据结构,每一个数据在哪一个位置都是有要求的,如果支持任意位置插入的话,那这个堆也就乱了,所以插入数据是在堆的最后一个位置插入的,插入之后你要保证这个堆还是原来的大/小堆啊,但是新插入的这个数据不一定满足原来堆的大小关系的,所以需要我们稍加调整才能让它继续保持插入前的堆的性质。这里描述为向上调整。
这里插入了一个3,通过观察可以看到,这个3只会影响从它开始一路往根节点的这条路径上的结点,而不会影响其它结点,其他结点还是保留着本来的特性(大堆/小堆),也就是说向上调整只需要从3开始往根节点这条路径上的结点做调整,因为这里是大堆,所以大的结点应该做父节点。调整后的结果如下:
如果插入的数据是6,那么结果如下:
向上调整代码:
void swap(HeapDataType* a, HeapDataType* b)
{HeapDataType tmp = *a;*a = *b;*b = tmp;
}
void AdjustUp(HeapDataType* arr, int child)
{//根据堆的性质求父子结点之间的关系int parent = (child - 1) / 2;while (child > 0)//当子节点的下标都为0了,那么循环就结束了{//子节点大于父节点就交换,建大堆if (arr[child] > arr[parent]){swap(&arr[child], &arr[parent]);//交换后需要往上迭代,参考以上描述和图片child = parent;parent = (child - 1) / 2;}else{//往上都符合大堆的性质,就breakbreak;}}
}
void HeapPush(HP* php, HeapDataType x)
{assert(php);if (php->sz == php->capacity){//增容HeapDataType* tmp = (HeapDataType*)realloc(php->a, sizeof(HeapDataType) * (php->capacity * 2));if (tmp == NULL){perror("realloc fail");return;}php->a = tmp;php->capacity *= 2;}php->a[php->sz] = x;php->sz++;//向上调整AdjustUp(php->a, php->sz - 1);}
2.5 删除数据
堆的删除只能从堆顶处删除,不能删除其他位置的数据,这也是堆的性质决定的。删除数据也是不能像顺序表那样简单地直接把后面的数据往前覆盖就可以实现的,那样的话父子结点之间的下标关系也是全部都乱套了的,这里用到了一种非常牛的方法,“替换法”。
具体操作就是用第一个结点和最后一个结点交换,然后删掉最后一个结点(注意:这里的最后一个结点本质上已经变成了原来堆顶的数据了,也就是完成了对堆顶数据的删除)。这时原本的最后一个结点已然变成了堆顶结点,但是这个数据不一定就是不一定是最大的(这里是大堆),所以需要往下调整保持原来大堆的性质(所有的父节点都大于等于自己的子节点),但是父节点可能存在左右子节点,那我们应该选取大的结点进行交换,以保证交换上来的子结点比另一个子节点大。迭代往下调整,直到到达叶子节点(中间遇到不需要交换的时候就可以break)。
先用堆顶元素和最后一个元素交换:
交换后删除最后一个元素:
从根节点开始向下调整(找大的子树):
void AdjustDown(HeapDataType* arr, int parent, int sz)
{int child = parent * 2 + 1;while (child < sz)//child的下标不能大于或者等于size(最后一个元素下标的下一个){//找子树中数据大的结点(注意child+1也不能越界)if (child + 1 < sz && arr[child] < arr[child + 1])//(child+1<sz必须先判断,不然如果右子树不存在,arr[child+1]会越界){child++;}//大堆是父节点大,所以子节点大于父节点就要交换if (arr[child] > arr[parent]){swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 + 1;}//没交换就可以break了else{break;}}
}
void HeapPop(HP* php)
{assert(php);swap(&php->a[0], &php->a[php->sz - 1]);//php->sz--就把数据删除了php->sz--;//从根节点开始向下调整保证堆的性质AdjustDown(php->a, 0, php->sz);}
2.6 堆内有效数据的数目
size_t HeapSize(HP* php)
{assert(php);return php->sz;}
2.7 取堆顶元素
HeapDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}
2.8 判断堆是否为空
bool HeapEmpty(HP* php)
{assert(php);return php->sz == 0;
}
2.9 代码汇总
Heap.h
#pragma once//Heap.h#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>typedef int HeapDataType;typedef struct Heap
{HeapDataType* a;int sz;int capacity;}HP;extern void HeapInit(HP* php);
extern void HeapDestroy(HP* php);
extern void HeapPush(HP* php, HeapDataType x);
extern void HeapPop(HP* php);
extern HeapDataType HeapTop(HP* php);
extern size_t HeapSize(HP* php);
extern bool HeapEmpty(HP* php);
extern void HeapCreate(HP* php, HeapDataType* arr, int n);void AdjustDown(HeapDataType* arr, int parent, int sz);
void AdjustUp(HeapDataType* arr, int child);
Heap.c
#define _CRT_SECURE_NO_WARNINGS 1//Heap.c#include "Heap.h"void HeapInit(HP* php)
{assert(php);php->a = (HeapDataType*)malloc(sizeof(HeapDataType) * 4);if (php->a == NULL){perror("malloc fail");return;}php->sz = 0;php->capacity = 4;
}void HeapCreate(HP* php, HeapDataType* arr, int n)
{assert(php);//建堆int i = 0;for (i = 0; i < n; i++){HeapPush(php, arr[i]);}
}void HeapDestroy(HP* php)
{assert(php);free(php->a);php->a = NULL;php->sz = php->capacity = 0;
}void swap(HeapDataType* a, HeapDataType* b)
{HeapDataType tmp = *a;*a = *b;*b = tmp;
}void HeapPush(HP* php, HeapDataType x)
{assert(php);if (php->sz == php->capacity){HeapDataType* tmp = (HeapDataType*)realloc(php->a, sizeof(HeapDataType) * (php->capacity * 2));if (tmp == NULL){perror("realloc fail");return;}php->a = tmp;php->capacity *= 2;}php->a[php->sz] = x;php->sz++;AdjustUp(php->a, php->sz - 1);}bool HeapEmpty(HP* php)
{assert(php);return php->sz == 0;
}void HeapPop(HP* php)
{assert(php);swap(&php->a[0], &php->a[php->sz - 1]);php->sz--;AdjustDown(php->a, 0, php->sz);}HeapDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}size_t HeapSize(HP* php)
{assert(php);return php->sz;}void AdjustDown(HeapDataType* arr, int parent, int sz)
{int child = parent * 2 + 1;while (child < sz){if (child + 1 < sz && arr[child] < arr[child + 1]){child++;}if (arr[child] > arr[parent]){swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}void AdjustUp(HeapDataType* arr, int child)
{int parent = (child - 1) / 2;while (child > 0){if (arr[child] > arr[parent]){swap(&arr[child], &arr[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}
三、经典“TopK”问题
- 学到堆这个数据结构怎么可能少得了“TopK”问题呢?非程序员可能不一定听过这个名词,但是在这个世界上的万事万物都存在着“TopK”问题,“TopK”问题就是经典的选数问题,选取最大的K个数,就举一个很简单的生活中的例子:假如说你现在饿了,想要点个外卖,那你怎么点呢?打开美团或者饿了么,你肯定点好吃的店吧!!那美团上有那么多的外卖店,你怎么选到好吃的店呢?是不是可以通过好评率来选取啊,好评率前五的店肯定不错吧!那你怎么看到这几家好评率前五的店呢?这就是经典的“TopK”问题。
- 有没有发现我们的堆天生就是用来干这事的?大堆的堆顶不就是最大的数吗?不也就是好评率最高的店吗?得到了这个堆顶的元素后pop一下第二大的数不也就到达了堆顶的位置了吗?以此类推,前K个最大的数不就选出来了!
- 把一堆数插入到一个大(小)堆里确实可以做到选取前K个最大(小)的数,但是你有没有想过,如果现在有一百亿个数据,让你选取前K个最大的数呢?要建一个一百亿个数据的堆是不是要把这一百亿个数据存在内存中,显然,内存的大小是有限的,无法存储过多的数据,那这种直接建堆选数的方法就走不通了。
- 有人就发明了这样的一个方法:我建一个k个数的堆,然后把剩下的存在磁盘中的数依次和堆顶的元素进行比较,比它大就插入到这个堆中(因为是选最大的前K个数),最后得到的这个堆不就是最大的前K个数吗?
但是这里还有一个小细节需要注意的哦,那就是选取最大的前K个数是建一个K个数的大堆呢还是小堆呢?思考5秒钟。很多人会认为,这是什么问题啊?选最大的前K个数那肯定是建大堆啊,这还用想?那我告诉你,如果真的是这样的话,我也就不会让你思考了,事实上,这里是建小堆。为什么呢?
你试想一下,如果建大堆,这一百亿个数中第一个数就是最大的数,那它就一定在这个大堆的堆顶,那其它的数来跟它比较的时候,全都比这个堆顶的元素小,所以其它的元素就不可能进得了这个堆了,所以最后这个堆里的数也就不是最大的前K个数。
但是建小堆就不一样了,剩下的在磁盘中的数据比堆顶的元素大就进堆,但是由于这个是小堆,所以这个堆顶的大的数一定会往下沉的,即不会堵在堆顶,这个数越大就在堆的越底下,所以等所有的数都对比完了之后堆里的k个数也就是最大的前K个数了。是不是很妙啊!这就是大佬的思维!!!!
接下来的难点就是建堆了,别人随便给你一个磁盘,里面有一百亿个数据,叫你找出最大的前K个,你需要随便拿取K个数,然后建一个小堆,再把一百亿个数遍历一遍,插入到这个小堆中,得到这K个数,但是你现在没有这个堆的数据结构啊,你不可能每次选数都手撕一个堆的增删查改的数据结构吧!这样也太慢了,其实这里只是让你选取这最大的前K个数而已,并不需要堆的其它功能,所以没必要写一个堆的数据结构,并且人家还可能要求你不能另外开辟空间呢!
基于这个原因,大佬们又想了一个原地建堆的方法,不用写堆的数据结构,就通过操作这个数组,使它变成堆,然后再把其它数插进来就可以了。
分别是以下两种方法:
1、向上调整建堆:从第二个数开始,往后的每一个数都向上调整一遍,就建成了一个小堆。
见下图:
向上调整的时间复杂度为:O(N*logN) (以2为底),证明如下:
2、向下调整建堆:可不可以从堆顶的元素开始向下调整呢?答案是不可以的,因为向下调整的要求是每一颗子树都得是一个小堆,所以从堆顶的元素开始向下调整是会有问题的。
所以大佬又想出了从最后一个叶子结点的父节点开始往上迭代,每一个结点都向下调整,形成一个个的小堆,直到堆顶的元素。
最后整体就是一个小堆。(注意,这里是建一个小堆,所以向下调整应该和子节点中小的那个交换,才能保证堆的性质)。
见下图:
向下调整的时间复杂度为:O(N)(以2为底),证明如下:
所以用数组建堆的的话建议用向下调整,能够大大地提高效率,因为O(N)和O(N*logN)的差距还是挺大的。
TopK参考代码:
void test_TopK(void)
{srand((unsigned int)time(NULL));//写文件int i = 0;FILE* fout = fopen("test_TopK.txt", "w");if (fout == NULL){perror("open fail");return;}int n = 1000;for (i = 0; i < n; i++){int ret = rand() % 1000;fprintf(fout, "%d\n", ret);}fclose(fout);fout = NULL;//读文件并且建堆FILE* fin = fopen("test_TopK.txt", "r");if (fin == NULL){perror("fin fail");return;}int val = 0;int k = 0;scanf("%d", &k);int* a = (int*)malloc(sizeof(int) * k);for (i = 0; i < k; i++){fscanf(fin, "%d", &a[i]);}for (i = (k - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, i, k);}//选取前TopK个数while (fscanf(fin, "%d", &val) != EOF){if (val > a[0]){a[0] = val;AdjustDown(a, 0, k);}}//这个数组的k个数就是最大的前K个数了//这样就选出来了。for (i = 0; i < k; i++){printf("%d ", a[i]);}printf("\n");fclose(fin);fin = NULL;free(a);a = NULL;}
int main()
{test_TopK();return 0;
}
你学会了吗?如果喜欢的话,请送上你的小心心和点点关注呗,后期会持续更新数据就够的相关知识哦,关注博主不迷路!!!
相关文章:
lc2
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。1 # Definition for singly-linked lis…...
Linux用户及用户组管理
用户管理添加用户 useradd [选项] 用户名 #需要root权限,或sudo passwd 用户名删除用户 userdel [-r] 用户名 #-r作用是把用户的主目录一起删除修改用户 usermod [选项] 用户名用户口令管理 用户刚刚创建时没创建口令,被系统锁定,无法使用,需 passwd [选项] 用户名 #为用户…...
探索 去中心化的Web3.0
随着区块链技术的日益成熟和普及,Web3(Web 3.0)已经成为一个无法忽视的趋势。Web3不仅仅是一个技术概念,更是一个去中心化、透明、用户数据拥有权归还给用户的互联网新时代。在这篇文章中,我们将深入探讨Web3技术的核心…...
可审批可审计追溯的单网络导出文件方案,了解一下!
在物理隔离状态下,单网络导出文件是一个重要的安全需求,特别是在处理敏感数据时。在这种环境下,数据导出需要采取特殊的安全措施,以确保数据传输的安全性和合规性。需要考虑以下因素: 安全性:确保传输过程加密,防止数据在传输过程中被截获。 性能:对于大文件或大量数据…...
数据可视化(四):Pandas技术的高级操作案例,豆瓣电影数据也能轻松分析!
Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊! 喜欢我的博客的话,记得…...
ps/lr如何为一个型号相机的raw使用其他相机的预设
首先单独下载camera raw,进到C:\ProgramData\Adobe\CameraRaw\CameraProfiles\Camera中获取想要的相机型号的预设dcp文件 去 https://liquidtelecom.dl.sourceforge.net/project/dcptool/dcptool/dcpTool V1.11.0/dcpTool_1_11_0.zip?viasf=1 下载dcp编译工具dcpTool cd C:\U…...
二叉树(堆)
目录一、什么是堆?二、堆的实现2.1 结构体变量的声明2.2 堆的初始化2.3 堆的销毁2.4 插入数据2.5 删除数据2.6 堆内有效数据的数目2.7 取堆顶元素2.8 判断堆是否为空2.9 代码汇总三、经典“TopK”问题一、什么是堆? heap 是一个抽象的数据结构ÿ…...
从矩阵理论角度理解偏最小二乘回归,以及在脑科学中(脑影像与行为、基因表达的关系)的应用举例
偏最小二乘法 (PLS) 是一种多元数据驱动的统计技术,旨在提取表示最大大脑行为关联的潜在变量(或潜在成分 latent components [LC])。 从矩阵理论角度理解偏最小二乘回归,以及在脑科学中(脑影像与行为、基因表达的关系)的应用举例 矩阵理论角度理解偏最小二乘回归偏最小二…...
dp 就 dp ,数位dp是什么意思 ?
💧 dp 就 dp ,数位dp是什么意思 ?💧 🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微风撞见云的博客🎐 🐳 数据结构与算法专栏的文章图文并茂🦕生动…...
MySQL面试必看
1.MySQL中的索引用的是什么数据结构 Innodb使用B树数据结构 1.Hash表:等值查询效率比较高、但是不支持范围查询。 2.二叉树:时间复杂度log2n 缺点:有可能产生不平衡 类似于链表的结构 时间复杂度为o(n)。 3.平衡二叉树avl/红黑树:…...
2023年全国最新道路运输从业人员精选真题及答案34
百分百题库提供道路运输安全员考试试题、道路运输从业人员考试预测题、道路安全员考试真题、道路运输从业人员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 28.根据《放射性物品运输安全管理条例》规定,运输放…...
python -- 科研论文海洋气象科学绘图的配色汇总
海洋气象科学科研绘图中常用的配色[1、ColorBrewer 彩色地图,默认情况下包含在 matplotlib 中](https://colorbrewer2.org/#typesequential&schemeBuGn&n3)[2、proplot package 自带的色系](https://proplot.readthedocs.io/en/latest/colormaps.html#ug-pe…...
Prometheus监控实战系列二: 安装部署
Prometheus支持多种操作系统,例如Linux、Windows和Max OSX等。在产品官网上提供了独立的二进制文件进行下载,可下载对应的tar包并在相应系统的服务器上进行安装部署。当然,做为与容器有着紧密联系的监控系统,Promethesu也可以很方…...
欧莱雅校招负责人张泽宇:拥抱Z世代,探索新玩法
作为校招HR,你在雇主品牌创新实践的路上做过什么尝试? 2020年,欧莱雅正式推出了全新的雇主品牌价值主张 —— 敢为敢超越,就是欧莱雅(Freedom to go beyond, thats the beauty of L’ORAL),鼓励…...
安装python教程并解决Python安装完没有Scripts文件夹问题
安装python教程 并解决Python安装完没有Scripts文件夹问题 ** 一背景 **首先要了解这个出现的原因是下载安装的版本问题 系統是32 bit 的版本还是 64bit 的 web-based: 透过网络安装的,就是执行安装后才透过网络下载python executable: 可執行文件的ÿ…...
牛客论坛项目总结
目录 1.请简要介绍一下你的项目? 1.如何实现项目的注册问题 2.项目如何实现用户唯一性检验 3.登录状态保存在哪 4.用户登陆上之后怎么显示登录页面 5.拦截器(Interceptor) 6.ThreadLocal(线程安全) 7.md5原理知…...
【Python学习笔记】b站@同济子豪兄 用pytorch搭建全连接神经网络,对Fashion-MNIST数据集中的时尚物品进行分类
【Python学习笔记】原作b站同济子豪兄 用pytorch搭建全连接神经网络,对Fashion-MNIST数据集中的时尚物品进行分类 跟着b站同济子豪兄的视频自学写的代码,内容是用pytorch搭建全连接神经网络,对Fashion-MNIST数据集中的时尚物品进行分类 视频…...
2年功能测试月薪9.5K,100多天自学自动化,跳槽涨薪4k后我的路还很长...
前言 其实最开始我并不是互联网从业者,是经历了一场六个月的培训才入的行,这个经历仿佛就是一个遮羞布,不能让任何人知道,就算有面试的时候被问到你是不是被培训的,我还是不能承认这段历史。我是为了生存,…...
【IoT 毕业设计】Ruff硬件+阿里云IoT+微信小程序构建环境监控系统
0.技术架构 IoT 物联网毕业设计实战采用 Ruff 开发板,串口连接温湿度传感器DHT11和空气质量传感器SDS011,每5分钟采集一次数据,通过MQTT协议发送到阿里云 IoT 物联网平台,写入云端的设备影子中。微信小程序调用阿里云函数计算FC…...
【VUE3】计算属性及其缓存特性
计算属性 基础示例 模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象: const author reactive({name: John Doe,b…...
【计算机网络】从输入网址到网页显示,期间发生了什么?
【计算机网络】从输入网址到网页显示,期间发生了什么? 接下来以下图较简单的网络拓扑模型作为例子,探究探究其间发生了什么? 文章目录【计算机网络】从输入网址到网页显示,期间发生了什么?一:孤…...
【vue2】近期bug收集与整理01
🥳博 主:初映CY的前说(前端领域) 🌞个人信条:想要变成得到,中间还有做到! 🤘本文核心:记录博主在vue2中遇到过的坑,本文是博主的学习使用总结 目录 1登陆token的问…...
JSON和AJAX
JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式,而且很多语言都提供了对json的支持(包括C,C,C#,Java,JavaScript…...
Python入门到精通【精品】第六章 - 函数
Python入门到精通【精品】第六章 - 函数 1. 如何理解函数2. 函数的定义3. 函数的使用3.1. 函数的调用3.2. 实参与形参3.3. 函数的返回3.4. 完整的函数设计3.5. 位置参数和关键参数1. 如何理解函数 当你第一次接触到“函数”这个概念的时候,你肯定会不由自主的联想到数学里面也…...
春招大盘点:找工作除了招聘网站还有哪些渠道?
又是一年毕业季,估计同学们都正在写论文、找工作两头忙,很多同学和小C“诉苦”说现在找实习的渠道太少了,招聘网站都刷完了,也没看到很合适的岗位。那找工作除了招聘网站还有什么渠道呢?其实是有的,今天就为…...
雷电4模拟器安装xposed框架(2022年)
别问我都2202年了为什么还在用雷电4安卓7。我特么哪知道Xposed的相关资料这么难找啊,只能搜到一些老旧的资料,尝试在老旧的平台上实现了。 最初的Xposed框架现在已经停止更新了,只支持到安卓8。如果要在更高版本的安卓系统上使用Xposed得看看…...
Gartner发布CNAPP市场指南 腾讯云为国内唯一入选云厂商
近日,国际研究机构Gartner发布《Market Guide for Cloud-Native Application Protection Platforms》(《云原生应用保护平台(CNAPP)市场指南》)(以下简称《市场指南》),腾讯云凭借集…...
数字藏品应用场景分析
数字藏品应用场景广泛,个人资料图片(PFP)元宇宙、艺术收藏、游戏、体育、文物、音乐等等都可以上链,以数字藏品的形式发行。国际市场中,个人资料图片占大多数,国内多以艺术收藏、文物藏品等为主。 数字藏品…...
spring boot项目:实现与数据库的连接
步骤【写在前面】定义数据库连接信息:引入数据库驱动:创建数据源:创建JdbcTemplate:编写DAO层:使用Service注解标注Service层:使用RestController注解标注Controller层:示例代码:app…...
解析vue中的process.env
一、介绍 1、process process是 nodejs 下的一个全局变量,它存储着 nodejs 中进程有关的信息。 2、process.env env 是 environment 的简称,process.env属性返回一个包含用户环境的对象。 3、dotenv Dotenv 是一个零依赖的模块,它能将环境变…...
ESP32 开启 Wi-Fi 热点与手机端 Iperf 测试 APP 来测试 ESP32 Wi-Fi AP 速率的流程
# 测试需求: ESP32 开启 WiFi AP Server 模式手机连接 ESP32 WiFi AP 热点通过手机端 Iperf 测试 APP 测试 ESP32 WiFi 热点的 Iperf 速率 测试用例: 可以基于 “esp-idf/examples/wifi/iperf” 例程进行测试。ESP32 设备下载 Iperf 例程后࿰…...
msfconsole之制作windows木马并成功获取shell
msfconsole之制作windows木马并成功获取shell 一、工具简介 msfconsole 简称 msf 是一款常用的安全测试工具,包含了常见的漏洞利用模块和生成各种木马,其提供了一个一体化的集中控制台,通过msfconsole,你可以访问和使用所…...
【小杨带你玩转C语言】(入门篇)初识C语言(下)
本章目录 每篇前言1.导语 2.目标 3.知识点 一,常见关键字 1,认识关键字 2,关键字分类 2.1,数据类型关键字 2.1.1,基本数据类型关键字 2.…...
一文快速回顾 Java 操作数据库的方式-JDBC
前言 数据库的重要性不言而喻,不管是什么系统,什么应用软件,也不管它们是 Windows 上的应用程序,还是 Web 应用程序,存储(持久化)和查询(检索)数据都是核心的功能。 大…...
92年程序员发帖晒薪资称自己很迷茫,网友:老弟你可以了
当下,是一个“向钱看,向厚赚”的社会。快节奏的生活下,家庭、工作各方面压力很容易使年轻人陷入迷茫和焦虑。 与其他行业相比,程序员的高薪让人羡慕。那么,对于那些真正达到这么多收入的人来说,他们是怎么…...
太敢说了,编程如果这么自学,培训班都得倒闭,直接省去上万元的学费
写了20多年的代码,之前做过阿里的高级架构师,在技术这条路上跌跌撞撞了很多,我今天分享一些我个人的自学方法给各位。现在在网上报个正经点的班得花几千块钱,线下就更夸张,都是万元起步,我的这些学习方法如果你能用好&…...
别急着给中国版ChatGPT唱赞歌:“追风者”无缘“星辰大海”
文心一言发布十余天后,争论仍未有止歇的迹象。 有人给出了“拉垮”的评价,相比于多轮迭代的ChatGPT,文心一言在逻辑推理、多轮对话等方面的表现不尽如人意;也有人认为给文心一言值得肯定,原因是填补了中文互联网的空白…...
异常:Error和Exception
异常机制(Exception) 什么是异常 实际工作中,遇到的情况不可能是非常完美的。比如:你写的某个模块,用户输入不一定符合你的要求、你的程序要打开某个文件,这个文件可能不存在或者文件格式不对,…...
Python满屏表白代码
目录 前言 爱心界面 无限弹窗 前言 人生苦短,我用Python!又是新的一周啦,本期博主给大家带来了一个全新的作品:满屏表白代码,无限弹窗版!快快收藏起来送给她吧~ 爱心界面 def Heart(): roottk.Tk…...
Unity --- Transform类
1.一个很有意思的事实是Transform类不仅用来管理游戏物体的位置缩放旋转,还用来管理游戏物体的父物体与子物体之间的关系 当游戏物体A的trasnform类a是游戏物体B的transform类b的父类的话,游戏物体A就是游戏物体B的父物体 2.如何访问脚本当前挂载的游戏…...
ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29‘ not found
Bug描述 今天主要解决一个 Bug:libstdc.so.6: version GLIBCXX_3.4.29 not found 主要是和 libstc版本问题相关,找了很多方法,其他很多方法都是直接修改libstc.so的版本,但是直接修改这种可能被多个共享库依赖的库版本将会牵一发…...
Unity IL2CPP 游戏分析入门
一、目标 很多时候App加密本身并不难,难得是他用了一套新玩意,天生自带加密光环。例如PC时代的VB,直接ida的话,汇编代码能把你看懵。 但是要是搞明白了他的玩法,VB Decompiler一上,那妥妥的就是源码。 U…...
设置鼠标右键打开方式,添加IDEA的打开方式
一、问题描述 已下载IDEA,但是右键打开之前保存的项目文件,无法显示以IDEA方式打开。 二、解决步骤 1. 打开注册表 winR键输入regedit 2、查找路径为计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell (我找了半天没看到Class…...
手机(Android)刷NetHunter安装指南,无需ssh执行kali命令, NetHunter支持的无线网卡列表!
一、安装NetHunter 前提:确保手机已经root,已装上magisk。如果没有root,可用尝试magisk root 后执行此文 1、下载Nethunter:Get Kali | Kali Linux 然后push 到sdcard 里, 2、打开magisk,选择刚刚下好的…...
Maven和Eclipse联合开发
Maven和Eclipse联合开发 java list 对象个数 size java List 取第一个对象.get(0) baseCrmSpecialclient.get(0).getFxid() System.out.print 换行 System.out.print(item.getCode()"\r\n"); java for循环用法 https://blog.csdn.net/rank/list/total Java for-ea…...
宝塔面板部署node+vue项目注意事项
宝塔面板部署nodevue项目注意事项 宝塔连接云服务器 如果服务器上没有安装宝塔面板,需要先安装,安装流程如下: 从宝塔官网主页进去,点击下载安装,然后点击在线安装 输入服务器IP和密码在服务器上安装宝塔面板 等待一…...
MATLAB | R2023a更新了哪些好玩的东西
R2023a来啦!!废话不多说看看新版本有啥有趣的玩意和好玩的特性叭!!把绘图放最前面叭,有图的内容看的人多。。 1 区域填充 可以使用xregion及yregion进行区域填充啦!! x -10:0.25:10; y x.^…...
MySQL对表操作
目录 CRUD 增加(Create) 查询(Retrieve) 全列查询 指定列查询 查询字段为表达式 别名 去重:DISTINCT 排序:ORDER BY 条件查询:WHERE 逻辑运算符: 修改(Update) 删除&…...
Downie 4 4.6.12 MAC上最好的一款视频下载工具
Downie for Mac 简介 Downie是Mac下一个简单的下载管理器,可以让您快速将不同的视频网站上的视频下载并保存到电脑磁盘里然后使用您的默认媒体播放器观看它们。 Downie 4 Downie 4 for Mac Downie 4 for Mac软件特点 支持许多站点 -当前支持1000多个不同的站点&…...
使用Android高性能音频--OpenSL ES和AAudio
AAudio的概念介绍: AAudio 是作为 OpenSL ES 库的轻量级原生 Android 替代项而开发。 与 OpenSL ES 相比,AAudio API 不仅较小,而且容易使用。 AAudio 是在 Android O 版本中引入的全新 Android C API。 因此 API 是专为需要低延迟的高性能音频应用而设…...
eNSP 构建基本WLAN
配置项配置参数AP组 名称:hcia-group 应用模板:域管理模板hcia-domain、VAP模板hcia-vap 域管理模板 名称:hcia-domain 国家码:cn SSID模板 名称:hcia-ssid SSID名称:hcia-wlan 安全模板 名称:h…...
记录一次C#/.NET以及VB p-code/native的逆向破解
记录一次C#/.NET以及VB p-code/native的逆向破解 玩了5份样本,2份dotnet的,2份native的和1份pcode的。 dotnet framework程序 dotnet的相对会简单,只需要使用dnspy工具打开目标程序,找到逻辑点后,点编辑函数࿰…...
IO-操作系统
用户态和内核态 现代操作系统,为了保护系统的安全,都会划分出内核空间和用户空间,或者我们经常说的内核态和用户态。简单来说,就是划分为内核态和用户态两个等级,运行在用户态的进程大都是一些应用程序,能够…...
Elasticsearch基本查询语法
先造点数据 基于elasticsearch7.10.0 POST /hotel {"mappings":{"properties":{"title":{"type":"text"},"city":{"type":"keyword"},"price":{"type":"double&q…...
百度地图入门
百度地图官网百度api 进入官网选择javascript API 里面有详细的教程, 跟着教程先登录注册一个个人开发账号 并创建一个应用获取ak 创建时js需要填白名单,如果是在本地运行填写localhost就好了 当你在控制台看到这个界面是代表创建成功了,…...
Endor Labs:2023年十大开源安全风险
近日,Endor Labs发布了一份新报告,确定了2023年的十大开源安全风险。报告显示,许多软件公司依赖于开源软件代码,但在如何衡量和处理与开源软件相关的风险和漏洞方面缺乏一致性。调查发现,在应用程序中超过80%的代码可能…...
【WEEK9】学习目标及总结【Spring Boot】【中文版】
学习目标: 学习SpringBoot 学习内容: 参考视频教程【狂神说Java】SpringBoot最新教程IDEA版通俗易懂YAML配置注入JSR303数据校验多环境切换自动配置原理Web开发探究的思考 学习时间及产出: 第九周MON~FRI 2024.4.22【WEEK9】 【DAY1】YAML…...
部署zookeeper+kafka
目录 一、二进制安装 1.安装jdk (1)yum 安装 (2)二进制安装 2.部署 zookeeper 3.部署kafka 01.安装 02.常用命令 03.示例 创建topic 创建 Kafka 生产者 创建Kafka消费者 运行示例 二、 docker 安装 1.搭建zookeepe…...
Python数据权限的管理通常涉及到几个关键组件:身份验证,、授权和访问控制。这通常是通过使用数据库、ORM(对象关系映射)框架、API框架和中间件
在Python中,数据权限的管理通常涉及到几个关键组件:身份验证,、授权和访问控制。这通常是通过使用数据库、ORM(对象关系映射)框架、API框架和中间件等技术来实现的。以下是一些建议的步骤和工具,用于在Pyth…...
SpringCloud系列(15)--Eureka自我保护
前言:在上一章节中我们说明了一些关于Eureka的服务发现功能,也用这个功能进行接口的实现,在本章节则介绍一些关于Eureka的自我保护 1、Eureka保护模式概述 保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。默认情况…...
【学习】人工智能在软件测试中的作用有哪些
随着科技的飞速发展,人工智能(AI)已经渗透到各个领域,并发挥着不可或缺的作用。其中,在软件测试方面,AI的应用也愈发普遍。本文将探讨人工智能在软件测试领域的关键作用以及其带来的积极影响。 一、提升测…...
docker-MySQL 8 主从搭建
一.目录结构: 我是在/home目录下,建立个sql文件夹: 二、配置文件 1.mysql配置 mysql-master下.conf文件配置 ###### [mysqld] server-id1 # 启用二进制日志 log-binmaster-bin # 指定需要复制的数据库 binlog-do-dbtest_db # 指定二进制日…...