C/C++ 转 Java 的数据结构初阶对比指南

一、先遣了解和回顾

1、预览快速对比表格

数据结构​​C/C++ 实现​​Java 实现​​关键区别​
​数组​int arr[5];int[] arr = new int[5];语法类似,Java 数组是对象
​动态数组​vector<int> v;ArrayList<Integer> list = new ArrayList<>();C++:手动内存管理;Java:自动扩容+泛型
​链表​list<int> l; (双向链表)LinkedList<Integer> list = new LinkedList<>();Java链表实现迭代器更简洁
​栈​stack<int> s;Deque<Integer> stack = new ArrayDeque<>();​Java建议避免用 Stack 类(已过时)​
​队列​queue<int> q;Queue<Integer> queue = new LinkedList<>();都支持 FIFO,Java 接口更统一
​二叉树​需手动实现节点结构同左(需自定义 TreeNode无标准库,实现逻辑相似
​堆​priority_queue<int> pq;PriorityQueue<Integer> pq = new PriorityQueue<>();​C++默认大顶堆,Java 默认小顶堆!​
​排序​sort(v.begin(), v.end());Collections.sort(list);C++用迭代器,Java 用集合工具类
​映射unordered_map<string, int>HashMap<String, Integer> map = new HashMap<>();C++用 [] 访问,Java 用 put()/get()
​集合unordered_set<string>HashSet<String> set = new HashSet<>();Java的 Set 是接口

2、Java中的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

【1】装箱/装包:基本数据类型变为包装类型。Java 中的基本数据类型(如 int、double 等)是原始类型,而包装类型(如 Integer、Double 等)是类。

例如:

                Integer i = Integer.valueOf(i);    //显示装箱,通过包装类的静态方法 valueOf() 转换

                Integer n = 2025;     //自动装箱 ,编译器自动调用 Integer.valueOf() 方法

【2】拆箱/拆包:把包装类型变为基本数据类型

例如:

                int  a = n.intValue();    //显示拆箱,通过包装类的实例方法 intValue() 转换

                 int b = n;   //自动拆箱,编译器自动调用 n.intValue() 方法

补充说明:

(1)性能问题:自动装箱和拆箱虽然方便,但可能会带来性能开销。因为每次装箱都会创建一个新的对象,而每次拆箱都需要调用方法。如果在性能敏感的代码中,建议尽量避免频繁的装箱和拆箱操作。

(2)空指针异常:在使用自动拆箱时,如果包装类型变量为 null,调用拆箱方法会抛出 NullPointerException。例如:

Integer m = null;
int c = m; // 抛出 NullPointerException,因为 m 为 null

(3)缓存机制:Integer.valueOf() 方法有一个缓存机制。对于 -128 到 127 之间的整数,valueOf() 方法会直接返回缓存的对象,而不是每次创建新对象。例如:

Integer x = 100; // 自动装箱,使用缓存对象
Integer y = 100; // 自动装箱,使用相同的缓存对象
System.out.println(x == y); // 输出 true

但超出这个范围时,每次调用 valueOf() 都会创建新的对象:

Integer z = 2025;
Integer w = 2025;
System.out.println(z == w); // 输出 false

二、数据结构代码说明及其对比

1、数组(Array)

C/C++

C/C++ 中数组是一块连续的内存空间,声明方式如int arr[5];,可通过arr[i]访问元素

//原生数组
int arr[5] = {1, 2, 3, 4, 5}; // 静态数组
int size = sizeof(arr) / sizeof(arr[0]); // 获取数组大小

补充:在C++11起,可以使用标准库容器 std::array来读取数组大小,必须要使用<array>头文件。(所有 STL 容器(如 std::list, std::map, std::string 等)均支持 .size():)

#include <array>
std::array<int, 5> arr = {1, 2, 3, 4, 5};
size_t length = arr.size(); // size_t是C++中的无符号整型

Java

Java 中数组是对象,可用new关键字创建,如int[] arr = new int[5];,通过arr[i]访问元素。Java 数组有length属性获取长度,如arr.length

int[] arr = {1, 2, 3, 4, 5}; // 静态数组
int size = arr.length; // 获取数组大小

2、动态数组(Dynamic Array)

C++

C++中使用std::vector来实现动态数组。使用<vector>头文件。

#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> vec = { 1,2,3,4,5 };vec.push_back(6);  //1. 添加元素,在末尾cout << "添加元素后:";for (int n : vec) cout << n << " ";// 值传递(创建副本)遍历cout << endl;vec.insert(vec.begin() + 2, 712);  //2. 指定位置添加元素cout << "指定位置添加元素后:";for (auto it = vec.begin();it != vec.end();++it)  cout << *it << " ";//使用迭代器遍历cout << endl;vec.erase(vec.begin() + 3);  //3. 删除元素,索引为3的元素被删除cout << "删除第四个元素后:";for (int i = 0;i < vec.size();++i) cout << vec[i] << " ";cout << endl;cout << "获取长度:" << vec.size() << endl;  //4. 获取长度cout << "获取索引为3的元素:" << vec[3] << endl;  //5. 获取指定元素return 0;
}

Java

Java中使用ArrayList来实现动态数组,功能类似。需要导入 java.util.ArrayList

动态数组不能使用.length而是要使用.size()获取长度!!! .length 是数组的属性​​,.size() 是ArrayList 的方法​​

import java.util.ArrayList;
import java.util.Arrays;public class FirstTest {public static void main(String[] args){ArrayList<Integer> number = new ArrayList<>(Arrays.asList(1,2,3,4,5));number.add(100);//1. 添加元素,会添加到最后System.out.println("添加后:"+number);number.add(1,711);//2. 在指定位置添加元素System.out.println("指定添加后:"+number);number.remove(1);//3. 删除第二个元素System.out.println("删除后:"+number);System.out.println("长度:"+number.size());//4. 获取长度System.out.println("索引为1(即第二个)的元素:"+number.get(1));//5. 获取指定元素}
}

3、链表(Linked List)

C/C++

链表通过指针连接节点,每个节点包含数据和指向下一节点的指针。

如定义单链表节点struct ListNode { int val; ListNode* next; };,需手动管理内存,通过malloc分配内存,free释放内存。

//C++代码
#include <iostream>
using namespace std;//单向链表节点结构体
struct ListNode {int val;  // 节点存储的数据ListNode* next;  // 指向下一个节点的指针explicit ListNode(int x):val(x),next(nullptr){}//定义了一个只允许显式调用的构造函数,用给定值初始化节点数据,并把 next 置空。
};//在链表头部插入节点
ListNode* addNode(ListNode*& head, int val) {ListNode* newNode = new ListNode(val);  // 创建新节点newNode->next = head;                   // 新节点指向原头节点return newNode;                         // 返回新的头节点
}
//打印链表
void printList(ListNode*& head) {for (ListNode* cur = head;cur;cur = cur->next) {cout << cur->val << " ";}cout << endl;
}int main()
{ListNode* head = nullptr;head = addNode(head, 3);head = addNode(head, 2);head = addNode(head, 1);printList(head);//输出1 2 3return 0;
}

Java

Java 中通过实现链表,无需手动管理内存,自动回收内存。

可定义class ListNode { int val; ListNode next; },使用new创建节点对象。

class ListNode {int val;          // 节点中保存的整数值ListNode next;    // 指向下一个节点的引用,若为空则表示链表结束// 构造方法:创建节点时只需给定 val,next 默认为 nullListNode(int val) {this.val = val;}
}public class LinkedList {/*** 在链表头部插入新节点* @param head 当前链表头节点* @param val  待插入的新值* @return 插入后的新链表头节点*/public static ListNode addNode(ListNode head, int val) {ListNode newNode = new ListNode(val); // 创建新节点newNode.next = head;                  // 新节点指向原头节点return newNode;                       // 新节点成为新头,返回}/*** 按顺序打印链表中的所有值* @param head 链表头节点*/public static void printList(ListNode head) {ListNode cur = head;while (cur != null) {                 // 遍历直到链表尾System.out.print(cur.val + " ");  // 打印当前节点值cur = cur.next;                   // 移动到下一个节点}System.out.println();}public static void main(String[] args) {ListNode head = null;     // 初始链表为空head = addNode(head, 3);  // 头部插入 3head = addNode(head, 2);  // 头部插入 2head = addNode(head, 1);  // 头部插入 1printList(head);          // 输出:1 2 3}
}

4、栈(Stack)

C/C++

可通过数组或链表实现栈,手动管理元素进出。

如用数组实现时,需定义栈顶指针,通过操作指针来实现压栈和弹栈操作。

//C++代码
#include <iostream>
#include <limits>
using namespace std;const int MAX_SIZE = 5;//栈的最大容量class ArrayStack {
private:int stackArray[MAX_SIZE];//存储栈元素的数组int topPointer;  //栈顶指针(索引位置)
public:ArrayStack() {topPointer = -1;//初始化栈顶指针为-1}//压栈操作void push(int value) {if (topPointer >= MAX_SIZE - 1) { //检查栈是否已满cout << "Stack Overflow! Cannot push " << value << endl;return;}stackArray[++topPointer] = value;//栈顶指针先加1,再将元素存入cout << "Pushed:" << value << endl;}//弹栈操作int pop() {if (isEmpty()) {cout << "Stack Underflow!" << endl;return INT_MIN; //返回错误码}int value = stackArray[topPointer--]; // 先取出栈顶元素,指针再减1cout << "Popped:" << value << endl;return value;}//获取栈顶元素(不弹出)int peek() {if (isEmpty()) {cout << "Stack is empty!" << endl;}return stackArray[topPointer];}//检查栈是否为空bool isEmpty() {return topPointer == -1;}//显示栈状态void display() {if (isEmpty()) {cout << "Stack:[](Empty)" << endl;return;}cout << "Stack:[";for (int i = 0;i <= topPointer;++i) {cout << stackArray[i] << " ";}cout << "]" << endl;}
};int main() {ArrayStack myStack;myStack.push(2025);//压入2025myStack.push(7);//压入7myStack.display();cout << "Top element:" << myStack.peek() << endl;//查看栈顶myStack.pop();myStack.push(13);myStack.push(14);myStack.push(15);myStack.push(16);//栈满myStack.push(17);//溢出错误myStack.display();return 0;
}

Java

Java 有java.util.Stack类,是Vector的子类,提供了push(压栈)、pop(弹栈)等方法。也可使用Deque接口的实现类如LinkedList来模拟栈,addFirst和removeFirst方法可分别实现压栈和弹栈功能。

(1)使用java.util.Stack
(2)使用LinkedList实现Deque接口
import java.util.Stack;
import java.util.LinkedList;
import java.util.Deque;public class StackDemo {public static void main(String[] args) {//方法一:使用java.util.StackSystem.out.println("Using java.util.Stack:");Stack<Integer>jdkStack = new Stack<>();//压栈操作Stack.push()jdkStack.push(2025);jdkStack.push(7);jdkStack.push(14);//弹栈操作Stack.pop()System.out.println("Popped:"+jdkStack.pop());//弹出14//查看栈顶元素,不移除Stack.peek()System.out.println("Top element:"+jdkStack.peek());//显示7//显示当前栈内容System.out.println("Stack contents:"+jdkStack);//方法二:使用LinkedList实现Deque接口System.out.println("Using LinkedList as Deque:");Deque<Integer>dequeStack = new LinkedList<>();//模拟压栈操作(添加到头部)addFirst()dequeStack.addFirst(2025);dequeStack.addFirst(10);dequeStack.addFirst(1);//模拟弹栈操作(移除头部)removeFirst()System.out.println("Popped:"+dequeStack.removeFirst());//弹出1//查看栈顶peekFirst()System.out.println("Top element:"+dequeStack.peekFirst());//显示10//显示当前栈状态System.out.println("DequeStack contents:"+dequeStack);}
}

5、队列(Queue)

C/C++

可以使用数组或链表实现队列结构。数组实现时建议采用循环队列来优化空间利用率,而链表实现则更为直观,只需维护队头和队尾两个指针即可。

(1)数组实现
#include <iostream>
using namespace std;class CircularQueue {
private:int* data;  //动态数组int front;  //队头下标int rear;   //队尾下标(指向即将入队的空位)int capacity; //数组容量int count;//当前元素个数
public://构造函数:申请数组并初始化指针explicit CircularQueue(int cap) :capacity(cap), front(0), rear(0), count(0) {data = new int[capacity];}//析构函数:释放动态数组~CircularQueue() {delete[] data;}//入队,O(1)bool enqueue(int val) {if (count == capacity) {cout << "队列已满," << val << "无法入队" << endl;return false;}data[rear] = val;  //放入数值rear = (rear + 1) % capacity; //循环后移++count;cout << val << "入队" << endl;return true;}//出队,O(1)bool dequeue(int& out) {if (count == 0) {cout << "队列为空,无法出队" << endl;return false;}out = data[front];front = (front + 1) % capacity;//循环后移--count;return true;}//查看队头,不删除bool peek(int& out)const {if (count == 0) return false;out = data[front];return true;}//当前元素数量int size()const { return count; }};int main() {CircularQueue q(3);q.enqueue(2025);q.enqueue(7);q.enqueue(18);q.enqueue(5);//提示队列已满int val;while (q.size()) {if (q.dequeue(val)) cout << val << "出队" << endl;}q.dequeue(val);return 0;
}

(2)链表实现
//C++代码
#include <iostream>
using namespace std;//链表节点:每个节点保存一个数据与下一个数据的指针
struct Node
{int data;   //存储节点的整数值Node* next; //指向下一个节点的指针Node(int val):data(val),next(nullptr){}//构造函数,接收一个整数参数val,用val初始化data,将next指针置空
};//链式队列,只维护“队头”与“队尾”两个指针即可
class LinkedQueue {
private:Node* front;Node* rear;
public:LinkedQueue():front(nullptr),rear(nullptr){}//初始化front和rear为空指针//入队:尾插法,时间复杂度O(1)void enqueue(int val) {Node* node = new Node(val);//在堆上新建节点if (!rear) {//若rear为空,则队列为空front = rear = node; //空队列时首尾指针都指向新节点}else {rear->next = node; //当前尾结点的next指向新节点rear = node; //更新尾指针,指向新的尾结点}cout << val << "入队" << endl;}//出队:头删法,时间复杂度O(1)bool dequeue(int& out) {  //dequeue函数,通过引用out带出出队值if (!front) {  //如果front为空,说明队列为空cout << "队列已空,无法出队" << endl;return false;}Node* tmp = front;//暂存当前队头节点地址out = tmp->data;  //取出当前队头值,存入outfront = front->next; //头指针后移,指向下一个节点if (!front) rear = nullptr; //若队列变为空,同步尾指针为空delete tmp;return true;}//查看队头但不删除,返回INT_MIN表示空队列int peek() {if (!front) {cout << "队列为空" << endl;return INT_MIN;}return front->data;}
};int main()
{LinkedQueue q;q.enqueue(2025);q.enqueue(7);q.enqueue(16);cout << "队头元素:" << q.peek() << endl; //查看队头元素,不删除int val; //接收 dequeue 弹出的那个队头元素if (q.dequeue(val)) cout << val << "出队" << endl;if (q.dequeue(val)) cout << val << "出队" << endl;if (q.dequeue(val)) cout << val << "出队" << endl;if (q.dequeue(val)) cout << val << "出队" << endl; //此时队已经为空return 0;	
}

Java

Java 有java.util.Queue接口,常用实现类有PriorityQueue和LinkedList。LinkedList实现了Queue接口,提供offer()方法进行入队操作,poll()方法进行出队操作。

(1)使用LinkedList

(先进先出)

import java.util.LinkedList;
import java.util.Queue;//例一:使用LinkedList实现队列(先进先出)
public class QueueDemo1 {public static void main(String[] args) {Queue<String> linkedListQueue = new LinkedList<>();//入队,添加到队尾linkedListQueue.offer("live");linkedListQueue.offer("towards");linkedListQueue.offer("death");System.out.println("LinkedList队列内容:"+linkedListQueue);//出队,移除并返回队列头部元素String firstItem = linkedListQueue.poll();System.out.println("出队元素:"+firstItem);System.out.println("出队后的队列:"+linkedListQueue);//查看队列头部元素,仅查看,不删除String peekItem = linkedListQueue.peek();System.out.println("查看当前队头:"+peekItem);}
}

(2)使用PriorityQueue

(按优先级排序,默认为自然序)

默认序:

                数字,按数值升序排列(例如 [1, 2, 3])。

                字符串,按字典序(Unicode 编码)升序排列(例如 ["apple", "banana", "cherry"])。

import java.util.PriorityQueue;
import java.util.Queue;//使用PriorityQueue
public class QueueDemo2 {public static void main(String[] args) {Queue<Integer> priorityQueue = new PriorityQueue<>();//乱序入队priorityQueue.offer(2025);priorityQueue.offer(7);priorityQueue.offer(17);System.out.println("PriorityQueue初始队列:"+priorityQueue);//按优先级出队(数值由小到大)System.out.println("按优先级出队结果:");while (!priorityQueue.isEmpty()){System.out.print("->"+priorityQueue.poll());}}
}

6、二叉树(Binary Tree)

用前序遍历为例

C/C++

二叉树节点通常定义为struct TreeNode { int val; TreeNode* left; TreeNode* right; };,通过指针连接左右子树,遍历等操作需递归或利用栈等辅助数据结构实现。

#include <iostream>
#include <vector>
using namespace std;struct TreeNode
{int val;  //节点存储的整数值TreeNode* left;  //指向左子节点的指针TreeNode* right; //指向右子节点的指针TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
};//前序遍历:根->左->右
void preorderTraversal(TreeNode* root, vector<int>& res)
{if (root == nullptr)return;//递归终止条件,当前节点为空res.push_back(root->val);  //访问根节点preorderTraversal(root->left, res); //递归遍历左子树preorderTraversal(root->right, res); //递归遍历右子树
}
int main(){//创建根节点TreeNode* root = new TreeNode(1);//第二层节点root->left = new TreeNode(2);root->right  = new TreeNode(3);//第三层节点root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);vector<int>result; //储存遍历结果的容器preorderTraversal(root, result);//执行前序遍历cout << "前序遍历结果:";for (int val : result) cout << val << " ";//内存释放,自底向上delete root->left->left;delete root->left->right;delete root->left;delete root->right;delete root;return 0;
}

Java

Java中定义二叉树节点类class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int val) { this.val = val; } },遍历方式与C++类似,但无需手动管理内存。

import java.util.ArrayList;
import java.util.List;class TreeNode{int val; //节点存储的整数值TreeNode left;TreeNode right;TreeNode(int val){this.val = val;}//节点构造函数
}public class BinaryTreeTraversal {private static void preorderTraversal(TreeNode root, List<Integer> res){if(root == null) return;//递归终止条件,当前节点为空res.add(root.val); //访问根节点preorderTraversal(root.left, res);  //遍历左子树preorderTraversal(root.right, res); //遍历右子树}public static void main(String[] args) {TreeNode root = new TreeNode(1);root.left = new TreeNode(2);root.right = new TreeNode(3);root.left.left = new TreeNode(4);root.left.right = new TreeNode(5);List<Integer> result = new ArrayList<>(); //存储遍历结果动态数组preorderTraversal(root,result); //执行前序遍历、System.out.println("前序遍历结果:");for(int val:result){System.out.print(val+" ");}//自动回收所有对象}
}

7、堆(Heap/PriorityQueue)

堆是堆是分为大顶堆和小顶堆的完全二叉树。

大顶堆:每个父节点的值大于等于对应的子节点的值

小顶堆:每个父节点的值小于等于对应的子节点的值

C++

std::priority_queue,默认大顶堆

#include <iostream>
#include <queue>
using namespace std;int main() {//默认大顶堆priority_queue<int> maxHeap;maxHeap.push(20);maxHeap.push(7);maxHeap.push(2025);while (!maxHeap.empty()) {cout << maxHeap.top() << " "; //2025 20 7maxHeap.pop();}return 0;
}

Java

java.util.PriorityQueue,默认小顶堆

import java.util.PriorityQueue;public class HeapDemo {public static void main(String[] args) {//默认小顶堆PriorityQueue<Integer> minHeap = new PriorityQueue<>();minHeap.offer(2025);minHeap.offer(7);minHeap.offer(20);while (!minHeap.isEmpty()) {System.out.print(minHeap.poll() + " ");//7 20 2025}}
}

8、排序(Sorting)

C++

<algorithm>里的sort

#include <iostream>
#include <algorithm>
#include <vector>using namespace std;int main()
{vector<int> v = { 2,0,5,7,3 };sort(v.begin(), v.end());  //升序排列for (int n : v) cout << n << " ";//0 2 3 5 7return 0;
}

Java

使用Collection.sort

import java.util.Arrays;
import java.util.Collections;
import java.util.List;public class SortDemo {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(2, 0, 5, 7, 3);Collections.sort(numbers); // 升序排序System.out.println(numbers);//[0, 2, 3, 5, 7]}
}

使用Arrays.sort

import java.util.Arrays;public class SortDemo {public static void main(String[] args) {int[] arr = {2,0,5,7,3};Arrays.sort(arr);  //升序排列for(int n:arr) System.out.print(n+" ");//0 2 3 5 7}
}

9、映射(Map)

键值对(Key-Value Pair)结构,支持快速查找。
键值对本质上就是一个名称(Key)对应一个内容(Value)。名称作为唯一标识,用于快速定位和访问对应的内容。

C++

std::unordered_map(哈希表)/std::map(红黑树)

#include <iostream>
#include <unordered_map>using namespace std;int main() {unordered_map<string, int> score;//哈希表score["Emma"] = 7;score["Ida"] = 25;cout << "Emma:" << score["Emma"] << endl;//Emma:7
}

Java

HashMap(哈希表)/TreeMap(红黑树)

import java.util.HashMap;public class MapDemo {public static void main(String[] args) {HashMap<String,Integer> score = new HashMap<>();score.put("Emma",7);score.put("Ida",25);System.out.println("Emma:"+score.get("Emma"));//Emma:7}
}

10、集合(Set)

只保存唯一元素,支持快速判重。

C++

std::unordered_set(哈希表)/std::set(红黑树)

#include <iostream>
#include <unordered_set>using namespace std;int main() {unordered_set<int> s; //哈希集合s.insert(7);s.insert(25);s.insert(7); //重复的7将会被忽略for (int n : s)cout << n << " "; //7 25return 0;
}

Java

HashSet(哈希表)/TreeSet(红黑树)

import java.util.HashSet;public class SetDemo {public static void main(String[] args) {HashSet<Integer> set = new HashSet<>();set.add(7);set.add(25);set.add(7); //重复的7将会被忽略for(int n:set) System.out.print(n+" "); //7 25}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/97940.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/97940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

长连接和短连接

在网络通信中&#xff0c;长连接&#xff08;Long Connection&#xff09;和短连接&#xff08;Short Connection&#xff09;是两种核心的连接管理策略&#xff0c;其区别主要体现在连接生命周期、资源占用和适用场景上。以下是两者的详细解析&#xff1a;一、核心概念对比特性…

Java:使用spring-cloud-gateway的应用报DnsNameResolverTimeoutException原因和解决方法

使用spring-cloud-gateway时&#xff0c;有时会报DnsNameResolverTimeoutException异常。堆栈信息类似&#xff1a;Caused by: java.net.UnknownHostException: Failed to resolve cloudconnector.linkup-sage.comat io.netty.resolver.dns.DnsResolveContext.finishResolve(Dn…

SpringCloud概述

目录 一、概念 1.1 微服务架构 1.2 SpringCloud概念 1.3 核心价值 1.4 能力边界 1.5 微服务总体架构图 二、生态圈 2.1 不同生态圈组件对比 2.2 组件介绍 2.2.1 服务发现与注册 2.2.2 配置管理 2.2.3 API网关 2.2.4 容错与熔断 2.2.5 客户端负载均衡 2.2.6 服务…

光伏电站环境监测仪—专为光伏电站设计的气象监测设备

光伏电站环境监测仪是专为光伏电站设计的气象监测设备&#xff0c;通过实时采集关键环境参数&#xff0c;为光伏系统的发电效率评估、运维决策和安全预警提供数据支撑。监测参数太阳辐射采用高精度总辐射表&#xff0c;测量水平面总辐射和倾斜面辐射&#xff0c;精度达 2% 以内…

Node.js ≥ 18 安装教程

Windows 安装 下载安装包&#xff1a;访问 Node.js官网&#xff0c;下载最新的 LTS 版本&#xff08;确保版本 ≥ 18&#xff09;运行安装程序&#xff1a;双击下载的安装文件&#xff0c;按照向导完成安装验证安装&#xff1a;打开命令提示符或PowerShell&#xff0c;输入以下…

电脑 hdmi 没有声音问题解决

问题现象&#xff1a;电脑耳机声音正常输出&#xff0c;使用hdmi连接电视后&#xff0c;没有声音输出。&#xff08;正常会通过hdmi 在电视上播放视频和声音&#xff09;解决方案:出现该情况很可能原因是 显卡的驱动不对。网上找了各种方法都没有解决&#xff0c;最后系统升级后…

学习日记-XML-day55-9.14

1.xml基本介绍知识点核心内容重点XML定义可扩展标记语言&#xff0c;用于数据存储和传输与HTML的区别&#xff08;HTML用于展示&#xff0c;XML用于结构化数据&#xff09;XML用途1. 配置文件&#xff08;Spring的beans.xml、Tomcat的server.xml&#xff09;;2. 数据交换&#…

【系统架构设计(27)】信息安全技术集成

文章目录一、本文知识覆盖范围二、信息安全基础要素详解1、机密性保障技术2、完整性验证技术3、可用性保障技术4、可控性管理技术5、可审查性追溯技术三、网络安全威胁与防护策略1、非授权访问防护2、拒绝服务攻击防护3、恶意软件传播防护四、加密技术体系与应用1、对称加密技术…

什么是 SaaS 安全?

什么是 SaaS 安全&#xff1f; SaaS 安全专注于保护云中的数据、应用程序和用户身份。它旨在应对基于云的软件所面临的挑战&#xff0c;以确保信息的安全性和可用性。SaaS 安全致力于降低未授权访问、数据泄露等风险&#xff0c;同时增强 SaaS 应用程序的安全性。 SaaS 安全不仅…

mysql和postgresql如何选择

h5打开以查看 简单来说&#xff1a; MySQL&#xff1a;更像是一个“快速、可靠的工匠”&#xff0c;注重速度、简单和稳定性&#xff0c;尤其在读操作密集的Web应用中是经典选择。 PostgreSQL&#xff1a;更像是一个“功能强大的学者”&#xff0c;追求功能的完备性、标准的符…

Redis最佳实践——安全与稳定性保障之数据持久化详解

Redis 在电商应用的安全与稳定性保障之数据持久化全面详解一、持久化机制深度解析 1. 持久化策略矩阵策略触发方式数据完整性恢复速度适用场景RDB定时快照分钟级快容灾备份/快速恢复AOF实时追加日志秒级慢金融交易/订单关键操作混合模式RDBAOF同时启用秒级中等高安全要求场景无…

Data Augmentation数据增强

目录 数据增强是什么 为什么数据增强 数组增强分类 有监督数据增强 无监督数据增强 数据增强是什么 数据增强又称数据扩增&#xff0c;是一种通过应用合理且随机的变换&#xff08;例如图像位移、旋转&#xff09;来增加训练集多样性的技术。让有限的数据产生等价于更多数…

OpenCV:特征提取

目录 一、特征提取核心概念&#xff1a;什么是图像特征&#xff1f; 二、实战 1&#xff1a;Harris 角点检测 1.1 角点的物理意义 1.2 Harris 算法原理 1.3 OpenCV 实战代码与解析 1.4 结果分析 三、实战 2&#xff1a;SIFT 特征提取 3.1 SIFT 算法核心优势 3.2 SIFT…

MySQL的查找加速器——索引

文章目录 目录 前言 一、基础概念&#xff1a;什么是 MySQL 索引&#xff1f; 二、底层数据结构&#xff1a;为什么 InnoDB 偏爱 B 树&#xff1f; B 树的结构特点&#xff08;以短链接表short_link的short_code索引为例&#xff09;&#xff1a; B 树的优势&#xff1a…

【Vue2手录11】Vue脚手架(@vue_cli)详解(环境搭建+项目开发示例)

一、前言&#xff1a;为什么需要 Vue 脚手架&#xff1f; 手动搭建 Vue 项目存在诸多痛点&#xff08;原笔记提及&#xff09;&#xff1a; 依赖管理复杂&#xff1a;需手动下载 Vue、Babel、Webpack 等工具&#xff0c;处理版本兼容性。配置繁琐&#xff1a;Webpack 配置、E…

自签发、CA机构签发、SSH、SCP、RSYNC,SUDO详解

一、为什么&#xff1f; 1. 自建CA为什么比Lets Encrypt强&#xff1f; 不能把CA放公网&#xff01;Lets Encrypt是给公网服务用的&#xff08;比如10.0.0.30的Web服务&#xff09;&#xff0c;但内网服务&#xff08;比如OpenVPN&#xff09;必须用自签CA。 CA私钥必须物理隔…

【Python】Python解决阿里云DataWorks导出数据1万条限制的问题

【Python】Python解决阿里云DataWorks导出数据1万条限制的问题一、前言二、脚本功能概述三、核心代码解析**1. 环境配置与安全设置****2. 用户配置区****3. 数据清洗函数****4. 核心逻辑**四、完整代码演示五、总结一、前言 在日常数据分析工作中&#xff0c;团队经常需要从阿…

计算机网络(一)基础概念

本篇文章为计算机网络相关知识点整理及扩展 基于B站计算机网络课程&#xff1a;https://www.bilibili.com/video/BV1p69tYZEvN/?spm_id_from333.1007.top_right_bar_window_history.content.click 如有错误&#xff0c;还望大家不吝指正 URL&#xff08;统一资源定位符&…

Git的工作区域和文件结构

Git的工作区域和文件结构 1. Git的工作区域2. Git的文件结构 打开.git文件&#xff0c;.git的文件结构如下&#xff1a; objects 存放已经提交的文件&#xff0c;也就是使用 git commit 进行操作后的文件。 index 存放已暂存的文件&#xff0c;也就是使用了 git add 进行操作后…

前端开发易错易忽略的 HTML 的 lang 属性

前言本文主要记录&#xff1a;前端开发中&#xff0c;一个本人错了好几年&#xff0c;看似无关紧要的小错误&#xff1a;HTML 的 lang 属性设置。正文HTML 的 lang 属性在HTML中&#xff0c;lang属性用于指定文档的语言。这对于搜索引擎优化&#xff08;SEO&#xff09;、屏幕阅…