算法-常见数据结构设计

文章目录

    • 1. 带有setAll功能的哈希表
    • 2. LRU缓存结构
    • 3. O(1)时间插入删除随机(去重)
    • 4. O(1)时间插入删除随机(不去重)
    • 5. 快速获取数据流中的中位数
    • 6. 最大频率栈
    • 7. 全O(1)结构
    • 8. LFU缓存结构

本节的内容比较难, 大多是leetcodeHard难度级别的题目

1. 带有setAll功能的哈希表

哈希表常见的三个操作时put、get和containsKey,而且这三个操作的时间复杂度为O(1)。现在想加一个setAll功能,就是把所有记录value都设成统一的值。请设计并实现这种有setAll功能的哈希表,并且put、get、containsKey和setAll四个操作的时间复杂度都为O(1)。

在这里插入图片描述

思路分析 :
原始的哈希表的put,get,containsKey方法的时间复杂度都是O(1), 现在我们需要添加一个setAll方法, 把表中所有元素的值都改为一个特定的value,显然直接遍历的时间复杂度肯定不是O(1)
为了做到时间复杂度是O(1)我们采用时间戳计数的方法
给定一个属性time记录下本次操作的时间节点, 然后给定一个属性是setAllValue和setAllTime,记录下来我们的setAll调用时候是时间节点和设置的变量, 然后get方法返回的时候如果是大于该节点我们就进行返回原有的值, 如果小于该节点, 我们就返回setAllValue的值
代码实现如下…


/*** 下面这个高频的数据结构是带有setAll功能的HashMap实现* 原理就是传入一个时间戳, 然后进行模拟的判断*/
class HashMapConSetAll {//基础的HashMap结构private HashMap<Integer, int[]> map = new HashMap<>();//定义一个时间戳private int time = 0;//定义一个是用setAll方法的时间节点以及相关的值private int setAllValue = 0;private int setAllTime = -1;//给一个无参的构造方法public HashMapConSetAll() {}//我们实现的特殊HashMap的put方法public void put(int key, int value) {if (!map.containsKey(key)) {map.put(key, new int[]{value, time++});} else {int[] temp = map.get(key);temp[0] = value;temp[1] = time++;}}//我们实现的特殊的HashMap的get方法public int get(int key) {if (!map.containsKey(key)) {return -1;}//代码执行到这里说明我们的map里面没有这个元素int[] temp = map.get(key);if (temp[1] > setAllTime) {return temp[0];} else {return setAllValue;}}//特殊的containsKey方法public boolean containsKey(int key) {return map.containsKey(key);}//最重要的setAll方法public void setAll(int value) {this.setAllTime = time++;this.setAllValue = value;}
}

2. LRU缓存结构

在这里插入图片描述

该数据结构的实现借助的是哈希表加上双向链表的方式, 我们定义一个节点类Node, 里面的基础属性就是key与val, 我们的哈希表中的key就是节点中的key,我们的val就是该节点的地址, 为什么要用节点的地址作为val其实也非常的好理解, 用Node作为地址我们可以直接找到这个节点的位置然后进行操作,下面是我们的代码实现


/*** LRU缓存结构* 实现的方法就是双向链表 + 哈希表, 可以直接通过哈希表在O(1)的时间复杂度下获取到位置节点的地址* 手写一个双向链表就行了*/
class LRUCache {// 首先定义的是双向链表的节点类public static class Node {int key;int val;Node prev;Node next;public Node(int key, int val) {this.key = key;this.val = val;}}// 双向链表的实现方式public static class DoubleLinkedList {// 链表的头部(代表的是最早操作的数据)public Node first;// 链表的尾部(代表的是最新操作的数据)public Node last;// 给一个无参数的构造方法public DoubleLinkedList() {first = null;last = null;}// 添加节点的方法public void addNode(Node node) {if (node == null) {return;}if (first == null && last == null) {first = node;last = node;return;}last.next = node;node.prev = last;last = node;}//重构一下remove()和removeToLast()方法public Node remove() {//没节点你删除个damn啊if (first == null && last == null) {return null;}//只有一个节点的情况Node node = first;if (first == last) {last = null;first = null;} else {Node next = first.next;first.next = null;first = next;next.prev = null;}return node;}//下面是重构的removeToLast方法public void removeToLast(Node node) {//首先排除掉特殊的情况if (node == null || first == null) {return;}//如果只有一个的话或者是尾巴节点if (first == last || node == last) {return;}//如果是头节点的节点 / 普通的节点if (node == first) {Node next = node.next;node.next = null;first = next;first.prev = null;} else {node.prev.next = node.next;node.next.prev = node.prev;node.prev = null;node.next = null;}//此时node节点完全是一个独立的节点last.next = node;node.prev = last;last = node;}}private HashMap<Integer, Node> map = new HashMap<>();DoubleLinkedList list = new DoubleLinkedList();private int capacity;public LRUCache(int capacity) {this.capacity = capacity;}public int get(int key) {if (!map.containsKey(key)) {return -1;}Node node = map.get(key);list.removeToLast(node);return node.val;}public void put(int key, int value) {if (map.containsKey(key)) {Node node = map.get(key);node.val = value;list.removeToLast(node);} else {Node node = new Node(key, value);if (map.size() < capacity) {map.put(key, node);list.addNode(node);} else {Node nde = list.remove();map.remove(nde.key);list.addNode(node);map.put(key, node);}}}public static void main(String[] args) {LRUCache lruCache = new LRUCache(2);lruCache.put(1, 0);lruCache.put(2, 2);int res = lruCache.get(1);lruCache.put(3, 3);int res1 = lruCache.get(2);lruCache.put(4, 4);int res2 = lruCache.get(1);int res3 = lruCache.get(3);int res4 = lruCache.get(4);}
}

3. O(1)时间插入删除随机(去重)

在这里插入图片描述

这个类的实现还是基于的哈希表, 外加上一个动态数组, key就是该数字, val是在动态数组里面的下标的位置, 如果删除元素, 动态数组中的那个空位置我们就用最后一个元素去填充, 然后删掉最后一个游戏(这样就保证了这个时间的复杂度O(1)), 同时在哈希表里面删除该值, 并该变最后一个元素的val为删除元素的之前的下标, 代码实现如下

class RandomizedSet {//其实现的方式是通过动态数组也就是我们的ArrayList跟HashMap共同实现的//其实从我们的经验可以了解到, 凡是涉及到O(1)的操作一般都是通过散列表的形式实现的HashMap<Integer, Integer> map = new HashMap<>();ArrayList<Integer> list = new ArrayList<>();//构造方法这里其实没什么用, 我们直接设置为空方法体的public RandomizedSet() {}//常规的insert方法, 我们的map结构第一个整数存储的就是值, 第二个是下标public boolean insert(int val) {if (!map.containsKey(val)) {list.add(val);map.put(val, list.size() - 1);return true;}return false;}//remove方法是一个比较重要的方法public boolean remove(int val) {if (map.containsKey(val)) {int valIndex = map.get(val);int endValue = list.get(list.size() - 1);map.put(endValue, valIndex);list.set(valIndex, endValue);map.remove(val);list.remove(list.size() - 1);return true;}return false;}public int getRandom() {int randIndex = (int) (Math.random() * list.size());return list.get(randIndex);}public static void main1(String[] args) {RandomizedSet randomizedSet = new RandomizedSet();randomizedSet.remove(0);randomizedSet.remove(0);randomizedSet.insert(0);int res = randomizedSet.getRandom();randomizedSet.remove(0);randomizedSet.insert(0);}
}

4. O(1)时间插入删除随机(不去重)

在这里插入图片描述

这个题目跟上一个题目只有一个不一样的地方就是这个哈希表的val是我们的HashSet,也就是一个下标集合, 我们进行元素删除的时候我们就随意选择一个待删除元素的下标进行删除即可, 我们的getRandom方法是用动态顺序表的数据进行返回的, 所以自带加权的功能, 代码实现如下

class RandomizedCollection {// 这个其实原来的HashMap中的value不再是整数, 而是一个HashSet集合ArrayList<Integer> arr = new ArrayList<>();HashMap<Integer, HashSet<Integer>> map = new HashMap<>();public RandomizedCollection() {}//insert方法是比较简单的, 就是直接放入元素即可public boolean insert(int val) {HashSet<Integer> set = map.get(val);if(set == null){HashSet<Integer> tempSet = new HashSet<>();tempSet.add(arr.size());map.put(val,tempSet);arr.add(val);return true;}else{set.add(arr.size());arr.add(val);return false;}}public boolean remove(int val) {HashSet<Integer> set = map.get(val);if(set == null){return false;}int indexValue = set.iterator().next();int swapValue = arr.get(arr.size() - 1);int swapIndex = arr.size() - 1;if(swapValue == val){arr.remove(arr.size() - 1);set.remove(arr.size());}else{HashSet<Integer> end = map.get(swapValue);end.remove(swapIndex);end.add(indexValue);set.remove(indexValue);arr.set(indexValue,swapValue);arr.remove(swapIndex);}if(set.size() == 0){map.remove(val);}return true;}public int getRandom() {return arr.get((int) (Math.random() * arr.size()));}
}/*** Your RandomizedCollection object will be instantiated and called as such:* RandomizedCollection obj = new RandomizedCollection();* boolean param_1 = obj.insert(val);* boolean param_2 = obj.remove(val);* int param_3 = obj.getRandom();*/

5. 快速获取数据流中的中位数

在这里插入图片描述

该数据结构的实现就是通过我们的堆结构来实现的, 建立一个大根堆来装入小半部分的数据, 建立一个小根堆来建立大半部分的数据, 记住在装入数据的过程中我们要保持我们的堆中的元素的大小, 也就是通过一个balance方法, 来保持两边的数量差值不超过1, 获取中位数的时候我们, 如果两边数量不一致, 就返回多的哪一方的堆顶, 如果一致, 我们就返回两个堆顶的平均值, 代码实现如下

class MedianFinder {private PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});// 默认就是小根堆private PriorityQueue<Integer> minHeap = new PriorityQueue<>();public MedianFinder() {}public void addNum(int num) {if (maxHeap.isEmpty() || num < maxHeap.peek()) {maxHeap.offer(num);} else {minHeap.offer(num);}balance();}public double findMedian() {if (minHeap.size() == maxHeap.size()) {return (minHeap.peek() + maxHeap.peek()) / 2.0;} else if (maxHeap.size() < minHeap.size()) {return minHeap.peek();} else {return maxHeap.peek();}}// 平衡堆结构的方法private void balance() {if (Math.abs(minHeap.size() - maxHeap.size()) == 2) {if (minHeap.size() - maxHeap.size() == 2) {maxHeap.offer(minHeap.poll());} else {minHeap.offer(maxHeap.poll());}}}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();

6. 最大频率栈

在这里插入图片描述

这道题目的思路就是用两个哈希表, 第一个哈希表存储的是词频统计, 第二个哈希表是一个类似桶的结构, key就是出现的词频, val是一个动态的顺序表, 代码实现如下

class FreqStack {//本质就是通过哈希来模拟//哈希表的key是词频统计, val是一个动态的顺序表, 里面存放这该词频的数字HashMap<Integer,ArrayList<Integer>> map = new HashMap<>();//再创建一个哈希表用于词频的统计HashMap<Integer,Integer> frq = new HashMap<>();//最大的词频(用于pop()操作指示)private int maxFrq = 0;public FreqStack() {//构造方法里面不写东西}public void push(int val){//首先进行词频的统计frq.put(val,frq.getOrDefault(val,0) + 1);maxFrq = Math.max(maxFrq,frq.get(val));ArrayList res = map.get(frq.get(val));if(res == null){ArrayList<Integer> arr = new ArrayList<>();arr.add(val);map.put(frq.get(val),arr);}else{res.add(val);}}//pop方法的时候应该进行的元素的删除操作public int pop() {ArrayList<Integer> arr = map.get(maxFrq);if(arr.size() == 1){int temp = arr.remove(0);map.remove(maxFrq--);if(frq.get(temp) == 1){frq.remove(temp);}else{frq.put(temp,frq.get(temp) - 1);}return temp;}else{int temp = arr.remove(arr.size() - 1);if(frq.get(temp) == 1){frq.remove(temp);}else{frq.put(temp,frq.get(temp) - 1);}return temp;}}
}/*** Your FreqStack object will be instantiated and called as such:* FreqStack obj = new FreqStack();* obj.push(val);* int param_2 = obj.pop();*/

7. 全O(1)结构

在这里插入图片描述

这个就是哈希表加上双向链表桶的思路, 哈希表中保存的是该字符串的所在桶的地址, 桶里面存放的是该词频的字符串的情况, 代码实现如下, 下面有一个LFU缓存也是这样的一个结构, 双向链表(桶), 桶里面再嵌套一个双向链表实现的堆结构…

class RandomizedCollection {//这个其实原来的HashMap中的value不再是整数, 而是一个HashSet集合ArrayList<Integer> arr = new ArrayList<>();HashMap<Integer, HashSet<Integer>> map = new HashMap<>();public RandomizedCollection() {}//insert方法是比较简单的, 就是直接放入元素即可public boolean insert(int val) {HashSet<Integer> set = map.get(val);if (set == null) {HashSet<Integer> tempSet = new HashSet<>();tempSet.add(arr.size());map.put(val, tempSet);arr.add(val);return true;} else {set.add(arr.size());arr.add(val);return false;}}public boolean remove(int val) {HashSet<Integer> set = map.get(val);if (set == null) {return false;}int indexValue = set.iterator().next();int swapValue = arr.get(arr.size() - 1);int swapIndex = arr.size() - 1;if (swapValue == val) {arr.remove(arr.size() - 1);set.remove(arr.size());} else {HashSet<Integer> end = map.get(swapValue);end.remove(swapIndex);end.add(indexValue);set.remove(indexValue);arr.set(indexValue, swapValue);arr.remove(swapIndex);}if (set.size() == 0) {map.remove(val);}return true;}public int getRandom() {return arr.get((int) (Math.random() * arr.size()));}public static void main(String[] args) {RandomizedCollection set = new RandomizedCollection();set.insert(1);set.remove(1);set.insert(1);}
}

8. LFU缓存结构


/*** LFU缓存 :* 1. 首先定义一个节点的对象, 里面保存的是该传入数据的key和value(ListNode)* 这个东西也是一个双向链表的结构(模拟队列使用) --> 不可以用LinkedList(源码的remove方法是遍历删除的结构)* 2. 其次我们定义一个桶结构, 里面有一个val用来保存操作的次数, 还有一个双向的链表(也就是我们的上面定义的队列结构)* 这个桶的结构也是类似于双端的链表(模拟双向链表使用)* 3. 然后我们需要定义两个哈希表* 第一个HashMap中的val保存的是该数字的所在桶的地址(方便定位桶的位置进行操作)* 第二个HashMap中的val保存的是该数字本身的ListNode的地址(方便进行删除操作)* 4. 返回使用量最小的元素就去最左边的桶里面拿队列中的first元素* 5. 桶的左右两侧我们定义了0操作次数, 以及Integer.MAX_VALUE桶, 减少了边界位置的判断*/class LFUCache {/*** 基础的节点的元素定义*/static class Node {int key;int val;Node prev;Node next;public Node(int key, int val) {this.key = key;this.val = val;}}/*** 模拟的队列的实现类*/static class MQueue {//属性定义为这样是为了和下面的桶结构区分开Node head;Node tail;int size;//无参数的构造方法public MQueue() {this.head = null;this.tail = null;}//remove方法用来移除掉指定位置的节点public Node remove(Node node) {if (head == null || tail == null) {throw new RuntimeException("没有节点无法移动");}if (head == tail) {tail = null;head = null;} else if (node == this.head) {Node temp = this.head.next;this.head.next = null;this.head = temp;this.head.prev = null;} else if (node == tail) {Node temp = tail.prev;tail.prev = null;tail = temp;tail.next = null;} else {node.prev.next = node.next;node.next.prev = node.prev;node.next = null;node.prev = null;}size--;return node;}//下面是我们的pop方法public Node pop() {return remove(head);}//下面是我们的offer()方法public void offer(Node node) {if (head == null && tail == null) {head = node;tail = node;size++;return;}tail.next = node;node.prev = tail;tail = node;size++;}}/*** 下面我们要完成我们的桶结构的实现(桶结构的val是出现的次数, 桶结构里面有一个我们手写的一个队列结构)*/static class Bucket {//出现的频率int time;//我们想要的队列结构MQueue mQueue;//模拟双向链表必须的实现Bucket prev;Bucket next;//构造方法public Bucket(int time) {this.time = time;mQueue = new MQueue();}}static class MBucket {//用作基石的两个桶Bucket min = new Bucket(0);Bucket max = new Bucket(Integer.MAX_VALUE);public MBucket(){min.next = max;max.prev = min;}//桶的插入插入操作(cur是参照结构)public void insert(Bucket cur, Bucket pos) {cur.next.prev = pos;pos.next = cur.next;cur.next = pos;pos.prev = cur;}//桶的删除操作public void remove(Bucket cur) {cur.prev.next = cur.next;cur.next.prev = cur.prev;}}//那个容量大小int capacity;//两个重要的HashMap结构HashMap<Integer, Node> nodeIndexMap = new HashMap<>();HashMap<Integer, Bucket> bucketIndexMap = new HashMap<>();MBucket mBucket = new MBucket();public LFUCache(int capacity) {this.capacity = capacity;}public int get(int key) {if (!nodeIndexMap.containsKey(key)) {return -1;} else {Bucket curBucket = bucketIndexMap.get(key);Node curNode = nodeIndexMap.get(key);if (curBucket.next.time > curBucket.time + 1) {Bucket newBucket = new Bucket(curBucket.time + 1);mBucket.insert(curBucket, newBucket);curBucket.mQueue.remove(curNode);newBucket.mQueue.offer(curNode);} else {curBucket.mQueue.remove(curNode);curBucket.next.mQueue.offer(curNode);}bucketIndexMap.put(key, curBucket.next);//判断先前的那个桶是不是空的(是空桶就删掉)if (curBucket.mQueue.size == 0) {mBucket.remove(curBucket);}return curNode.val;}}public void put(int key, int value) {if (nodeIndexMap.containsKey(key)) {Node curNode = nodeIndexMap.get(key);Bucket curBucket = bucketIndexMap.get(key);curNode.val = value;if (curBucket.next.time > curBucket.time + 1) {Bucket newBucket = new Bucket(curBucket.time + 1);mBucket.insert(curBucket, newBucket);curBucket.mQueue.remove(curNode);newBucket.mQueue.offer(curNode);} else {curBucket.mQueue.remove(curNode);curBucket.next.mQueue.offer(curNode);}bucketIndexMap.put(key, curBucket.next);//判断先前的那个桶是不是空的(是空桶就删掉)if (curBucket.mQueue.size == 0) {mBucket.remove(curBucket);}} else {Node newNode = new Node(key, value);if (nodeIndexMap.size() < capacity) {if (mBucket.min.next.time != 1) {Bucket newBucket = new Bucket(1);newBucket.mQueue.offer(newNode);mBucket.insert(mBucket.min, newBucket);nodeIndexMap.put(key, newNode);bucketIndexMap.put(key, newBucket);} else {Bucket oneBucket = mBucket.min.next;oneBucket.mQueue.offer(newNode);nodeIndexMap.put(key, newNode);bucketIndexMap.put(key, oneBucket);}} else {Node removeNode = mBucket.min.next.mQueue.pop();nodeIndexMap.remove(removeNode.key);bucketIndexMap.remove(removeNode.key);if(mBucket.min.next.mQueue.size == 0){mBucket.remove(mBucket.min.next);}if(mBucket.min.next.time != 1){Bucket newBucket = new Bucket(1);newBucket.mQueue.offer(newNode);mBucket.insert(mBucket.min, newBucket);nodeIndexMap.put(key, newNode);bucketIndexMap.put(key, newBucket);}else{Bucket oneBucket = mBucket.min.next;oneBucket.mQueue.offer(newNode);nodeIndexMap.put(key, newNode);bucketIndexMap.put(key, oneBucket);}}}}public static void main(String[] args) {LFUCache lfu = new LFUCache(2);lfu.put(1,1);lfu.put(2,2);lfu.get(1);lfu.put(3,3);lfu.get(2);lfu.get(3);lfu.put(4,4);lfu.get(1);lfu.get(3);lfu.get(4);}
}

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

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

相关文章

智能交通(3)——Learning Phase Competition for Traffic Signal Control

论文分享 https://dl.acm.org/doi/pdf/10.1145/3357384.3357900https://dl.acm.org/doi/pdf/10.1145/3357384.3357900 论文代码 https://github.com/gjzheng93/frap-pubhttps://github.com/gjzheng93/frap-pub 摘要 越来越多可用的城市数据和先进的学习技术使人们能够提…

【2024_CUMCM】时间序列算法ARMA

目录 2023-c-问题二 问题分析 介绍 单位根检验 白噪声检验 自相关和偏自相关图 利用信息准则定阶 构建AMIMA模型 D-W检验 预测 代码 2023-c-问题二 问题分析 ARMA适合多个领域的时间序列分析&#xff0c;不同时间的定价策略属于这类问题。 介绍 ARMA模型&…

《python程序语言设计》2018版第5章第52题利用turtle绘制sin函数

这道题是送分题。因为循环方式已经写到很清楚&#xff0c;大家照抄就可以了。 但是如果说光照抄可是会有问题。比如我们来演示一下。 import turtleturtle.penup() turtle.goto(-175, 50 * math.sin((-175 / 100 * 2 * math.pi))) turtle.pendown() for x in range(-175, 176…

芯片封装简介

1、背景 所谓“封装技术”是一种将集成电路用绝缘的塑料或陶瓷材料打包的技术。以CPU为例&#xff0c;实际看到的体积和外观并不是真正的CPU内核的大小和面貌&#xff0c;而是CPU内核等元件经过封装后的产品。封装技术对于芯片来说是必须的&#xff0c;也是至关重要的。因为芯片…

鸿蒙开发管理:【@ohos.account.distributedAccount (分布式帐号管理)】

分布式帐号管理 本模块提供管理分布式帐号的一些基础功能&#xff0c;主要包括查询和更新帐号登录状态。 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff…

【扩散模型】LCM LoRA:一个通用的Stable Diffusion加速模块

潜在一致性模型&#xff1a;[2310.04378] Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (arxiv.org) 原文&#xff1a;Paper page - Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (…

【数据结构】经典链表题目详解集合(反转链表、相交链表、链表的中间节点、回文链表)

文章目录 一、反转链表1、程序详解2、代码 二、相交链表1、程序详解2、代码 三、链表的中间节点1、程序详解2、代码 四、回文链表1、程序详解2、代码 一、反转链表 1、程序详解 题目&#xff1a;给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链…

聚焦大模型应用落地,2024全球数字经济大会人工智能专题论坛在京举办

7月1日下午&#xff0c;2024全球数字经济大会人工智能专题论坛在中关村国家自主创新示范区会议中心举办。论坛紧扣大模型应用落地这一热点&#xff0c;以“应用即未来——大模型赋能千行百业&#xff0c;新生态拥抱产业未来”为主题&#xff0c;备受社会各界关注。 一、北京已…

Canal架构以及使用规范

Canal架构以及使用规范 一、Canal的作用 相关文档&#xff1a;GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 MySQL主备复制原理 MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events&#xff0c;可…

Docker:Docker网络

Docker Network 是 Docker 平台中的一项功能&#xff0c;允许容器相互通信以及与外界通信。它提供了一种在 Docker 环境中创建和管理虚拟网络的方法。Docker 网络使容器能够连接到一个或多个网络&#xff0c;从而使它们能够安全地共享信息和资源。 预备知识 推荐先看视频先有…

SQL Server 2022 中的 Tempdb 性能改进非常显著

无论是在我的会话中还是在我写的博客中&#xff0c;Tempdb 始终是我的话题。然而&#xff0c;当谈到 SQL Server 2022 中引入的重大性能变化时&#xff0c;我从未如此兴奋过。他们解决了我们最大的性能瓶颈之一&#xff0c;即系统页面闩锁并发。 在 SQL Server 2019 中&#x…

Go语言--复合类型之map、结构体

map Go 语言中的 map(映射、字典)是一种内置的数据结构&#xff0c;它是一个无序的 key-value 对的集合&#xff0c;比如以身份证号作为唯一键来标识一个人的信息。 格式 map [keyType]valueType 在一个 map 里所有的键都是唯一的&#xff0c;而且必须是支持和!操作符的类型…

Git仓库介绍

1. Github GitHub 本身是一个基于云端的代码托管平台&#xff0c;它提供的是远程服务&#xff0c;而不是一个可以安装在本地局域网的应用程序。因此&#xff0c;GitHub 不可以直接在本地局域网进行安装。 简介&#xff1a;GitHub是最流行的代码托管平台&#xff0c;提供了大量…

【MySQL】4.MySQL 的数据类型

MySQL 的数据类型 一.数据类型分类在这里插入图片描述二.注意点1.char VS varchar2.datetime VS timestamp3.enum 和 set 的使用方法 一.数据类型分类 二.注意点 1.char VS varchar char 的意义是直接开辟固定大小的空间&#xff0c;浪费磁盘空间&#xff0c;但是效率高varcha…

孟德尔随机化与痛风3

写在前面 检索检索&#xff0c;刚好发现一篇分区还挺高&#xff0c;但结果内容看上去还挺熟悉的文章&#xff0c;特记录一下。 文章 Exploring the mechanism underlying hyperuricemia using comprehensive research on multi-omics Sci Rep IF:3.8中科院分区:2区 综合性期…

基于ESP32 IDF的WebServer实现以及OTA固件升级实现记录(三)

经过前面两篇的前序铺垫&#xff0c;对webserver以及restful api架构有了大体了解后本篇描述下最终的ota实现的代码以及调试中遇到的诡异bug。 eps32的实际ota实现过程其实esp32官方都已经基本实现好了&#xff0c;我们要做到无非就是把要升级的固件搬运到对应ota flash分区里面…

数据结构之“队列”(全方位认识)

&#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;数据结构 前言 上期博客介绍了” 栈 “这个数据结构&#xff0c;他具有先进后出的特点。本期介绍“ 队列 ”这个数据结构&#xff0c;他具有先进先出的特点。 目录…

通信协议_C#实现自定义ModbusRTU主站

背景知识&#xff1a;modbus协议介绍 相关工具 mbslave:充当从站。虚拟串口工具:虚拟出一对串口。VS2022。 实现过程以及Demo 打开虚拟串口工具: 打开mbslave: 此处从站连接COM1口。 Demo实现 创建DLL库&#xff0c;创建ModbusRTU类,进行实现&#xff1a; using Syste…

【JVM-04】线上CPU100%

【JVM-04】线上CPU100% 1. 如何排查2. 再举一个例子 1. 如何排查 ⼀般CPU100%疯狂GC&#xff0c;都是死循环的锅&#xff0c;那怎么排查呢&#xff1f;先进服务器&#xff0c;⽤top -c 命令找出当前进程的运⾏列表按⼀下 P 可以按照CPU使⽤率进⾏排序显示Java进程 PID 为 2609…

轻松驾驭开发之旅:Maven配置阿里云CodeUp远程私有仓库全攻略

文章目录 引言一、为什么选择阿里云CodeUp作为远程私有仓库&#xff1f;二、Maven配置阿里云CodeUp远程私有仓库的步骤准备工作配置Maven的settings.xml文件配置项目的pom.xml文件验证配置是否成功 三、使用阿里云CodeUp远程私有仓库的注意事项 引言 在软件开发的世界里&#…