数据结构《MapSet哈希表》
文章目录
- 一、搜索树
- 1.1 定义
- 1.2 模拟实现搜索
- 二、Map
- 2.1 定义
- 2.2 Map.Entry
- 2.3 TreeMap的使用
- 2.4 Map的常用方法
- 三、Set
- 3.1 定义
- 3.2 TreeSet的使用
- 3.3 Set的常用方法
- 四、哈希表
- 4.1 哈希表的概念
- 4.2 冲突
- 4.2.1 冲突的概念
- 4.2.2 冲突的避免
- 1. 选择合适的哈希函数
- 2. 负载因子调节
- 4.2.3冲突的解决
- 1. 闭散列
- 2. 开散列
- 4.3 模拟实现
- 五、例题练习
- 总结
一、搜索树
1.1 定义
它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值。
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值。
它的左右子树也分别为二叉搜索树。
1.2 模拟实现搜索
public class MyBinarySearchTree {static class TreeNode{int key;TreeNode left;TreeNode right;public TreeNode(int key){this.key = key;}}private TreeNode root = null;/*** 查询节点* 查询是否有节点的key值为所需要找的,如果有返回这个节点,没有则返回null* @param key* @return TreeNode*/public TreeNode search(int key){if(root == null){return null;//如果树为空,不用查询直接返回null}TreeNode cur = root;while (cur != null){if(key == cur.key){return cur;}else if(key < cur.key){//如果查询的值比节点的值小,说明只能在左子树上找cur = cur.left;}else {cur = cur.right;}}return null;}/*** 插入数据* 如果树为空直接插入,如果比节点的值大,往右边走,小,往左走,相等则不插入* @param key* @return*/public boolean insert(int key){if(root == null){root = new TreeNode(key);return true;//树为空,直接插入并返回正确}TreeNode cur = root;TreeNode parent = null;//parent的存在,是为了让我们可以返回到上一个节点while (cur != null){if(key == cur.key){//如果要插入的数据已经存在,说明不需要插入return false;}else if(key < cur.key){//如果要插入的数据比节点值小,说明要往节点的左子树中插入parent = cur;cur = cur.left;}else {//如果要插入的数据比节点值大,说明要往节点的右子树中插入parent = cur;cur = cur.right;}}//到这里,说明我们cur已经为空,此时要插入的数据在parent的左子树或者右子树TreeNode treeNode = new TreeNode(key);if(key < parent.key){parent.left = treeNode;}else {parent.right = treeNode;}return true;}/*** 删除节点* 首先我们要找到这个删除的节点* @param key* @return*/public boolean remove(int key){//首先要先找到这个点if(root == null){return false;//树为空无法删除}TreeNode parent = null;TreeNode cur = root;while (cur != null){if(key < cur.key){parent = cur;cur = cur.left;}else if(key > cur.key){parent = cur;cur = cur.right;}else {//说明找到这个点了return removeNode(parent,cur);}}return false;}/*** 删除节点的真正方法* @param parent* @param cur* @return*/private boolean removeNode(TreeNode parent, TreeNode cur) {if(cur.left == null){//当要删除的节点左节点为空if(cur == root){//当节点为root时,那直接让root往右子树走即可root = cur.right;}else if(cur == parent.left){//节点不为root,说明cur为parent的左或者右孩子parent.left = cur.right;//因为cur左为空,所以父亲节点的左节点直接接上cur的右子树即可}else {parent.right = cur.right;}}else if(cur.right == null){//当要删除的节点右节点为空if(cur == root){//当节点为root时,那直接让root往左子树走即可root = cur.left;}else if(cur == parent.left){parent.left = cur.left;}else {parent.right = cur.left;}}else {//当要删除的节点左右均不为空//找这个节点的左子树的最右边的节点或者右子树最左边的节点来替换数值TreeNode targetParent = cur;TreeNode target = cur.left;while (target.right != null){targetParent = target;target = target.right;}cur.key = target.key;targetParent.right = target.left;}return true;}}
关于上述搜索树中其他的方法,比较简单,看代码大概可以了解如何实现,这里我们主要解释一下删除中的左右孩子节点都存在的情况下删除的原理
最后删除完的结果
测试用例
public class Test {public static void main(String[] args) {MyBinarySearchTree myBinarySearchTree = new MyBinarySearchTree();myBinarySearchTree.insert(5);myBinarySearchTree.insert(4);myBinarySearchTree.insert(6);myBinarySearchTree.insert(9);myBinarySearchTree.insert(3);myBinarySearchTree.insert(2);myBinarySearchTree.insert(7);myBinarySearchTree.insert(8);myBinarySearchTree.insert(10);MyBinarySearchTree.TreeNode treeNode = myBinarySearchTree.search(9);System.out.println(treeNode.key);System.out.println(myBinarySearchTree.remove(9));}
}
什么是键值对?
键(key):它是独一无二的标识符,用于快速定位和检索对应的值。在一个Map集合里,不允许有两个相同的键,就像现实生活中每个人都有唯一的身份证号。常见的数据类型都能充当键,比如String、Integer,不过要求键对象必须正确重写hashCode()和equals()方法,以此保证唯一性和一致性。
值(value):与键关联的数据,可以是任意类型,例如在统计单词出现次数的场景中,单词是键,出现的次数作为值,这个次数值就是Integer类型。一个键对应一个值,但不同键可以对应相同的值 。
二、Map
2.1 定义
Map是一个接口类,没有继承自Collection,该类中存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复。
注意:
- Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
- Map中存放键值对的key是唯一的,value是可以重复的
- 在TreeMap中插入键值对时,key不能为空,否则会抛出NullPointerException异常,value可以为空。但是HashMap的key和value都可以为空。
- Map中的key可以全部分离出来,存储到Set中来进行访问(因为key不能重复)。
- Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
- Map中键值对的key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。
2.2 Map.Entry
Map.Entry是一个接口,它表示Map接口中的一个键值对。每个实现了Map接口的类,例如HashMap、TreeMap等,内部都有对应的内部类实现了Map.Entry接口,用于封装单个的键值对元素,方便对Map进行遍历等操作。
方法 | 解释 |
---|---|
K getKey( ) | 返回entry中的key |
V getValue( ) | 返回entry中的value |
V setValue(V value) | 将键值对中的value替换掉 |
如在HashMap中
在TreeMap中
2.3 TreeMap的使用
put(key, value):插入key-value的键值对
如果key不存在,会将key-value的键值对插入到map中,返回null
如果key之前是存过的,会将新的value值作为返回值返回,同时会将新的value值与之前的进行替换
Map<String,Integer> map = new TreeMap<>();//放入不同的人以及他的分数map.put("zhangsan",90);map.put("lisi",80);map.put("wangwu",88);Integer m = map.put("zhaoliu",92);Integer n = map.put("zhaoliu",99);System.out.println("m "+m);System.out.println("n "+n);
map.size()//返回map中已经存的键值对的个数
get()
Map<String,Integer> map = new TreeMap<>();//放入不同的人以及他的分数map.put("zhangsan",90);map.put("lisi",80);map.put("wangwu",88);Integer m = map.put("zhaoliu",92);Integer n = map.put("zhaoliu",99);// get(key): 返回key所对应的value// 如果key存在,返回key所对应的value// 如果key不存在,返回nullSystem.out.println(map.get("zhangsan"));System.out.println(map.get("wangmm"));
getOrDefault()
//getOrDefault(): 如果key存在,返回与key所对应的value,如果key不存在,返回一个默认值System.out.println(map.getOrDefault("zhangsan", -100));System.out.println(map.getOrDefault("wangmm", -100));
containKey()
//containKey(key):检测key是否包含在Map中,时间复杂度:O(logN)// 按照红黑树的性质来进行查找// 找到返回true,否则返回falseSystem.out.println(map.containsKey("zhangsan"));System.out.println(map.containsKey("wangmm"));
containValue()
// containValue(value): 检测value是否包含在Map中,时间复杂度: O(N)// 找到返回true,否则返回falseSystem.out.println(map.containsValue(90));System.out.println(map.containsValue(100));
keySet()
返回类型: keySet()方法返回一个Set集合,因为Map中的键具有唯一性,所以用Set来存储很合适,Set集合会自动去除重复元素,保证每个键在集合里只出现一次。
遍历Map:获取到键的集合后,可以通过遍历这个Set,再配合Map的get方法,来遍历整个Map的键值对,这是一种常见的Map遍历方式。
// 打印所有的key// keySet是将map中的key放入在Set中返回的for (String key : map.keySet()) {System.out.println(key + " : " + map.get(key));}
values()
// 打印所有的value// values()是将map中的value放在collect的一个集合中返回的for(Integer integer : map.values()){System.out.print(integer + " ");}System.out.println();
entrySet()
// 打印所有的键值对// entrySet(): 将Map中的键值对放在Set中返回了for(Map.Entry<String, Integer> entry : map.entrySet()){System.out.println(entry.getKey() + ":" + entry.getValue());}System.out.println();
2.4 Map的常用方法
方法 | 解释 |
---|---|
V get(Object key) | 返回 key 对应的 value |
V getOrDefault(Object key, V defaultValue) | 返回key对应的value,key不存在,返回默认值 |
V put(K key, V value) | 设置 key 对应的 value |
V remove(Object key) | 删除key对应的映射关系 |
Set keySet() | 返回所有key的不重复集合 |
Collection values() | 返回所有value的可重复集合 |
Set<Map.Entry<K, V>> entrySet() | 返回所有的key-value映射关系 |
boolean containsKey(Object key) | 判断是否包含key |
boolean containsValue(Object value) | 判断是否包含valuel |
三、Set
3.1 定义
Set与Map主要的不同有两点:Set是继承自Collection的接口类,Set中只存储了Key。
注意:
-
Set是继承自Collection的一个接口类
-
Set中只存储了key,并且要求key一定要唯一
-
TreeSet的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
-
Set最大的功能就是对集合中的元素进行去重
-
实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
-
Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
-
TreeSet中不能插入null的key,HashSet可以。
3.2 TreeSet的使用
add()
TreeSet<String> treeSet = new TreeSet<>();// add(key): 如果key不存在,则插入,返回ture// 如果key存在,返回falsetreeSet.add("zhangsan");treeSet.add("lisi");treeSet.add("wangwu");boolean m = treeSet.add("zhaoliu");boolean n = treeSet.add("zhangsan");System.out.println(m);System.out.println(n);
size()
contains()
// contains(key): 如果key存在,返回true,否则返回falseSystem.out.println(treeSet.contains("zhangsan"));System.out.println(treeSet.contains("wangmm"));
3.3 Set的常用方法
方法 | 解释 |
---|---|
boolean add(E e) | 添加元素,但重复元素不会被添加成功 |
void clear() | 清空集合 |
boolean contains(Object o) | 判断·是否在集合中 |
Iteratoriterator0 | 返回迭代器 |
boolean remove(Object o) | 删除集合中的o |
int size() | 返回set中元素的个数 |
boolean isEmpty() | 检测set是否为空,空返回true,否则返回false |
Object[ toArray0 | 将set中的元素转换为数组返回 |
boolean containsAll(Collection<?> c) | 集合c中的元素是否在set中全部存在,是返回true,否则返回false |
boolean addAll(Collection<?extendsE>c) | 将集合c中的元素添加到set中,可以达到去重的效果 |
四、哈希表
4.1 哈希表的概念
哈希表是一种数据结构,它使用哈希函数将键(Key)映射到存储桶(Bucket)或槽(Slot),以便可以在平均情况下以O(1)的时间复杂度进行快速的插入、删除和查找操作。
基本原理:
- 哈希表由一个数组(也称为哈希表本身)和一个哈希函数组成。
- 哈希函数:将键作为输入,通过某种计算得到一个整数索引,这个索引就是存储键值对的存储桶的位置。例如,对于键 k,哈希函数 h(k) 会计算出一个整数 i,表示键值对 (k, v) 应该存储在数组的第 i 个位置。
4.2 冲突
4.2.1 冲突的概念
当两个不同的键通过哈希函数计算得到相同的哈希值时,会发生哈希冲突。
在上面我们给出的例子中,没有出现冲突,如果通过例子中的hash函数,我们再放入一个数为44,那么我们就会和4冲突
4.2.2 冲突的避免
1. 选择合适的哈希函数
选择哈希函数的考虑因素:
- 分布均匀性:
理想的哈希函数应该将键均匀地分布在哈希表的存储桶中,避免大量冲突。 - 计算速度:
哈希函数的计算应该快速,避免复杂的计算,尤其是对于大量的插入、查找操作。 - 抗碰撞性:
对于安全相关的应用,需要更高的抗碰撞性,使用加密哈希函数;对于普通的哈希表,可能更注重速度和分布均匀性。
常用的函数:
- 取模法: 对于一个整数键 k 和哈希表大小 m,哈希函数 h(k) = k % m
- 直接定制法:取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B
2. 负载因子调节
负载因子是哈希表中存储元素的数量与哈希表的容量(即存储桶的数量)的比值。
计算公式为:负载因子 = 元素数量 / 哈希表容量。
作用和意义:
- 它是一个重要的性能指标,用于衡量哈希表的填充程度。
- 在 Java 的 HashMap 中,负载因子决定了何时对哈希表进行扩容操作。
- 合理的负载因子可以平衡空间使用和性能,避免过多的哈希冲突。
常见的负载因子取值:
- 在 Java 的 HashMap 中,默认的负载因子是 0.75。
- 当元素数量达到 哈希表容量 * 负载因子 时,HashMap 会自动扩容,通常扩容为原来的两倍,并重新哈希元素。
4.2.3冲突的解决
1. 闭散列
闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,可以把key存放到冲突位置中的下一个空位置中去。
-
线性探测:如果发生冲突,顺序地检查下一个槽,直到找到一个空槽。
采用闭散列处理哈希冲突时,不能随便物理删除哈希表中已有的元素,若直接删除元素会影响其他元素的搜索。比如删除元素4,如果直接删除掉,44查找起来可能会受影响。因此线性探测采用标记的伪删除法来删除一个元素
-
二次探测(Quadratic Probing):使用二次函数来确定下一个检查的槽,比如检查h(k) + 1^2 ,h(k) + 2^2,h(k) + 3^2,等等。
闭散列性能受探测序列和负载因子影响,当负载因子较高时,性能下降明显,空间利用率低。
2. 开散列
开散列法又叫链地址法,首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。
哈希桶其实可以看作将大集合的搜索问题转化为小集合的搜索问题,那如果冲突严重,就意味着小集合的搜索性能其实也时不佳的,这个时候我们就可以将这个所谓的小集合搜索问题继续进行转化:
- 每个桶的背后是另一个哈希表
- 每个桶的背后是一棵搜索树
4.3 模拟实现
这里是我自己的一些理解,可能不是那么全面,如果有不对的地方,还望指正
节点的插入
数组的扩展
代码实现
public class HashTable<K,V> {private static final double DEFAULT_LOAD_FACTOR = 0.75f;static class Node<K,V>{public K key;public V value;public Node<K,V> next;public Node(K key,V value){this.key = key;this.value = value;}}//先定义一个数组来作为哈希表存放private Node<K,V>[] array = (Node<K,V>[])new Node[10];private int useSize = 0;public void push(K key,V value){int hashcode = key.hashCode();//获得哈希值int index = hashcode % array.length;Node<K,V> cur = array[index];while (cur != null){if(key.equals(cur.key)){//如果key在链表中存在,我们就更新它的value值,不新添节点,key唯一性cur.value = value;return;}cur = cur.next;}Node<K,V> node = new Node<>(key,value);node.next = array[index];array[index] = node;useSize++;if(doLoadFactor() > DEFAULT_LOAD_FACTOR){resize();}}private void resize() {Node<K,V>[] newarray = (Node<K,V>[])new Node[array.length*2];for (int i = 0; i < array.length; i++) {Node<K,V> cur = array[i];while (cur != null){int newHashcode = cur.key.hashCode();int newIndex = newHashcode % newarray.length;//重新计算位置Node<K,V> curN = cur.next;//记录节点的下一个节点cur.next = newarray[newIndex];newarray[newIndex] = cur;cur = curN;}}array = newarray;}private double doLoadFactor() {return useSize * 1.0 / array.length;}public V getVal(K key){int hashcode = key.hashCode();int index = hashcode % array.length;Node<K,V> cur = array[index];while (cur != null){if(cur.key.equals(key)){return cur.value;}cur = cur.next;}return null;}
}
当负载因子过大时,进行扩容
五、例题练习
例题1 字符串中的第一个唯一字符
通过HashMap来实现
class Solution {public int firstUniqChar(String s) {Map<Character,Integer> map = new HashMap<Character,Integer>();for(int i = 0; i < s.length(); i++){char ch = s.charAt(i);map.put(ch,map.getOrDefault(ch,0)+1);}for(int i = 0; i < s.length(); i++){if(map.get(s.charAt(i)) == 1){return i;}}return -1;}
}
例题2 只出现一次的数字
使用set
遍历数组,将数组中的数字放入set中,在放入之前判断set中是否存在这个数,如果存在,将set中的这个数出出去,最后遍历set中剩下的数便是出现一次的数
class Solution {public int singleNumber(int[] nums) {HashSet<Integer> set = new HashSet<>();for(int i = 0; i < nums.length; i++){if(set.contains(nums[i])){set.remove(nums[i]);}else{set.add(nums[i]);}}for(int i = 0; i < nums.length; i++){if(set.contains(nums[i])){return nums[i];}}return 0;}
}
例题3 随机链表的复制
class Solution {public Node copyRandomList(Node head) {HashMap<Node,Node> map = new HashMap<>();Node cur = head;while(cur != null){Node node = new Node(cur.val);map.put(cur,node);//key为老节点,value为新节点cur = cur.next;}cur = head;while(cur != null){map.get(cur).next = map.get(cur.next);map.get(cur).random = map.get(cur.random);cur = cur.next;}return map.get(head);}
}
例题4 宝石与石头
运用set存储宝石,然后看石头中在set中能不能找到
class Solution {public int numJewelsInStones(String jewels, String stones) {HashSet<Character> set = new HashSet<>();int count = 0;for(int i = 0; i < jewels.length(); i++){set.add(jewels.charAt(i));}for(int i = 0; i < stones.length(); i++){if(set.contains(stones.charAt(i))){count++;}}return count;}
}
例题5 旧键盘
将实际输入的字符串放入setReal中,然后从正确的字符串中一个一个取出字符看,实际输入的字符串中有没有,没有就打印并且将它放入已经判断后的set中,以防反复判断。
import java.util.Scanner;
import java.util.HashSet;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String strAct = in.nextLine();//正确的字符串String strBroken = in.nextLine();//实际输入的字符串strAct = strAct.toUpperCase();strBroken = strBroken.toUpperCase();HashSet<Character> hashSetReal = new HashSet<>();//实际输入的HashSet<Character> hashSetAlready = new HashSet<>();//已经判断过的for(int i = 0; i < strBroken.length(); i++){hashSetReal.add(strBroken.charAt(i));}for(int i = 0; i < strAct.length(); i++){char ch = strAct.charAt(i);if(!hashSetReal.contains(ch) && !hashSetAlready.contains(ch)){hashSetAlready.add(ch);System.out.print(ch);}}}
}
总结
本篇文章,介绍了有关Map和Set,以及哈希表相关的数据结构内容,如果有什么不正确不严谨的地方,还望指正,我会尽快更改,谢谢大家!!
相关文章:
数据结构《MapSet哈希表》
文章目录 一、搜索树1.1 定义1.2 模拟实现搜索 二、Map2.1 定义2.2 Map.Entry2.3 TreeMap的使用2.4 Map的常用方法 三、Set3.1 定义3.2 TreeSet的使用3.3 Set的常用方法 四、哈希表4.1 哈希表的概念4.2 冲突4.2.1 冲突的概念4.2.2 冲突的避免1. 选择合适的哈希函数2. 负载因子调…...
【PCL】sample_consensus 模块—— Random Sample Consensus model(随机样本一致性模型,RANSAC)
1、随机样本一致性模型(RANSAC)简介 在本教程中,我们将学习如何使用带有平面模型的随机样本一致性(RANSAC)来获取适合该模型的点云。 1.1理论背景 RANSAC 是“随机样本一致性”(RANdom SAmple Consensus…...
【MATLAB代码】CV和CA模型组成的IMM(滤波方式为UKF),可复制粘贴源代码
该代码实现了一维无迹卡尔曼滤波器(UKF)与交互式多模型(IMM)结合的状态估计。代码分为多个部分,主要功能包括参数定义、观测数据生成、状态估计、模型更新以及结果可视化。 文章目录 运行结果程序代码主要功能代码结构应用场景注意事项运行结果 程序代码 下方源代码直接粘…...
docker-compose部署kafka 3.3.1 kraft
一、服务器: 节点1:10.1.1.165 节点2:10.1.1.164 节点3:10.1.1.169二、添加环境地址解析 vim /etc/hosts kafka1 10.1.1.165 kafka2 10.1.1.164 kafka3 10.1.1.169三、节点配置 节点1 version: "3" services:kafka1:image: bitnami/kafka:3.3.1contain…...
Linux 串口检查状态的实用方法
在 Linux 系统中,串口通信是非常常见的操作,尤其在嵌入式系统、工业设备以及其他需要串行通信的场景中。为了确保串口设备的正常工作,检查串口的连接状态和配置信息是非常重要的。本篇文章将介绍如何在 Linux 上检查串口的连接状态࿰…...
使用FRP进行内网穿透
一、基本概念 内网穿透:它是一种网络技术或方法,旨在允许外部网络(如互联网)访问位于内部网络(内网)中的设备或服务。由于内部网络通常处于NAT(网络地址转换)、防火墙或其他安全机制…...
Ubuntu打开文件夹不显示文件
1.情况介绍 使用ubuntu打开文件夹不显示文件夹里面的内容,而是直接打开了资源查看器。 2.解决办法 命令行安装nautilus sudo apt-get install nautilus...
HarmonyOS NEXT应用开发边学边玩系列:从零实现一影视APP (三、影视搜索页功能实现)
在HarmonyOS NEXT开发环境中,可以使用nutpi/axios库来简化网络请求的操作。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库,从零开始实现一个简单的影视APP,主要关注影视搜索页的功能实现。 为什么选择nutpi/axios? nutpi…...
探秘 JMeter 前置处理器:让性能测试如虎添翼
想象一下,你是一位超级英雄,要对一个庞大的虚拟城市(Web 应用)进行全面的 “健康检查”。JMeter 就是你的神奇工具包,而其中的前置处理器,就像是这个工具包里的各种超级武器,能帮助你轻松应对各…...
如何在gitlab cicd中实现每月10号上午执行
在 GitLab CI/CD 中,可以通过设置定时触发器(Schedules)和脚本中的时间判断逻辑结合,确保任务只在每月 10 号的上午运行。 以下是实现的步骤: 1. 设置定时触发器 GitLab 提供了 Schedules 功能,可以指定每…...
深度学习基础知识
深度学习是人工智能(AI)和机器学习(ML)领域的一个重要分支,以下是对深度学习基础知识的归纳: 一、定义与原理 定义:深度学习是一种使计算机能够从经验中学习并以概念层次结构的方式理解世界的机…...
面试加分项:Android Framework AMS 全面概述和知识要点
第一章:AMS 的架构与组件 1.1 AMS 整体架构 在 Android 系统的庞大体系中,AMS(Activity Manager Service)就如同一个中枢神经系统,是整个系统的核心服务之一,对应用的性能和用户体验有着直接且关键的影响 。它的整体架构由 Client 端和 Service 端两大部分组成,这两端相…...
网安——CSS
一、CSS基础概念 CSS有两个重要的概念,分为样式和布局 CSS的样式分为两种,一种是文字的样式,一种是盒模型的样式 CSS的另一个重要的特质就是辅助页面布局,完成HTML不能完成的功能,比如并排显示或精确定位显示 从HT…...
知识图谱常见的主流图数据库
在知识图谱中,主流使用的图数据库包括以下几种: Neo4j:这是目前全球部署最广泛的图数据库之一,具有强大的查询性能和灵活的数据模型,适用于复杂关系数据的存储和查询。 JanusGraph:JanusGraph是一个开源的…...
阀井可燃气体监测仪,开启地下管网安全新篇章-旭华智能
在城市的脉络中,地下管网犹如隐秘的动脉,支撑着现代生活的运转。而在这庞大网络的关键节点上,阀井扮演着不可或缺的角色。然而,由于其密闭性和复杂性,阀井内部一旦发生可燃气体泄漏,将对公共安全构成严重威…...
【6】Word:海名公司文秘❗
目录 题目 List.docx Word.docx List.docx和Word.docx 题目 List.docx 选中1/4全角空格复制→选中全部文本→开始→替换:粘贴将1/4全角空格 替换成 空格选中全部文本→插入→表格→将文本转化成表格→勾选和布局→自动调整→勾选 选中第一列,单机右键…...
微信原生小程序自定义封装组件(以导航navbar为例)
封装 topnav.js const App getApp(); Component({// 组件的属性列表properties: {pageName: String, //中间的titleshowNav: { //判断是否显示左上角的按钮 type: Boolean,value: true},showHome: { //判断是否显示左上角的home按钮type: Boolean,value: true},showLocat…...
<OS 有关>Ubuntu 24 安装 openssh-server, tailscale+ssh 慢增加
更新日志: Created on 14Jan.2025 by Dave , added openssh-server, tailescape Updated on 15Jan.2025, added "tailescape - tailscape ssh" 前期准备: 1. 更新可用软件包的数据库 2. 升级系统中所有已安装的软件包到最新版本 3. 安装 cur…...
HQL(JPQL)和原生SQL实现查询自定义返回类
维修申请实例RepairApplyInstance: package com.byx.scaffold.common.entity.jpa;import com.byx.scaffold.common.entity.jpaEnum.RepairStatusConstant; import lombok.Data;import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence…...
微信小程序 实现拼图功能
微信小程序 实现拼图 效果示例功能描述代码示例 效果示例 微信小程序 碎片拼图 功能描述 在微信小程序中,实现一个简单的拼图小游戏。用户需要将四张碎片图片拖动到目标图片的正确位置,具体功能如下: 拖动功能: 用户可以通过手指…...
《C++11》并发库:简介与应用
在C11之前,C并没有提供原生的并发支持。开发者通常需要依赖于操作系统的API(如Windows的CreateThread或POSIX的pthread_create)或者第三方库(如Boost.Thread)来创建和管理线程。这些方式存在以下几个问题: …...
【RDMA学习笔记】1:RDMA(Remote Direct Memory Access)介绍
从帝国理工的PPT学习。 什么是RDMA Remote Direct Memory Access,也就是Remote的DMA,是一种硬件机制,能直接访问远端结点的内存,而不需要处理器介入。 其中: Remote:跨node进行数据传输Directÿ…...
Autodl转发端口,在本地机器上运行Autodl服务器中的ipynb文件
通过 SSH 隧道将远程端口转发到本地机器 输入服务器示例的SSH指令和密码,将远程的6006端口代理到本地 在服务器终端,激活conda虚拟环境 conda activate posecnnexport PYOPENGL_PLATFORMegljupyter notebook --no-browser --port6006 --allow-root从…...
【Linux】常见指令(一)
Linux常见指令 01.whoami02.pwd03.ls04.mkdir05.cd 本文LInux环境为,使用XShell远程登陆到Linux。 具体如何环境搭建,大家可以查看其他博客。 01.whoami whoami 指令用来查看当前账户是谁。 如上图所示,使用whoami指令,查看到现在…...
AI学习之自然语言处理(NLP)
自然语言处理(Natural Language Processing,NLP)是计算机科学、人工智能和语言学领域的交叉学科,旨在让计算机能够理解、处理和生成人类语言。以下为你详细介绍: 自然语言处理的关键技术 词法分析:将文本…...
全面解析锁服务设计:内存锁、数据库锁与分布式锁的选择与实现
在构建分布式系统时,锁服务通常用于控制多个线程或进程对共享资源的访问。为了灵活适配不同的锁实现方式,我们可以设计一个基础的锁服务接口,然后根据需求提供不同的实现。例如,内存锁、数据库锁和分布式锁。 1. 锁服务基础接口设…...
jenkins-系统配置概述
一. 引文: Jenkins除了强大的功能插件实现的持续交付集成外, 本身也是有一些比较重要的可配项。 接下来我们来看一看。 配置入口: 系统管理-->系统设置 二. 基础配置: 1.主目录(home directory): Jenkins所有的数据文件存放路径(可通过…...
《数据思维》之数据可视化_读书笔记
文章目录 系列文章目录前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 数据之道,路漫漫其修远兮,吾将上下而求索。 一、数据可视化 最基础的数据可视化方法就是统计图。一个好的统计图应该满足四个标准:准确、有…...
kafka消费堆积问题探索
背景 我们的商城项目用PHP写的,原本写日志方案用的是PHP的方案,但是,这个方案导致资源消耗一直降不下来,使用了20个CPU。后面考虑使用通过kafka的方案写日志,商城中把产生的日志丢到kafka中,在以go写的项目…...
一文掌握Docker
目录 1.快速入门 1.1.部署MySQL 1.2.命令解读 2.Docker基础 2.1.常见命令 2.1.1.命令介绍 2.1.2.演示 2.1.3.命令别名 2.2.数据卷 2.2.1.什么是数据卷 2.2.2.数据卷命令 2.2.3.挂载本地目录或文件 2.3.镜像 2.3.1.镜像结构 2.3.2.Dockerfile构建镜像 2.3.3.构建…...
慧集通(DataLinkX)iPaaS集成平台-系统管理之UI库管理、流程模板
UI库管理 UI库管理分为平台级和自建两种,其中平台级就是慧集通平台自己内置的一些ui库所有客户均可调用,自建则是平台支持使用者自己根据规则自己新增对应的UI库。具体界面如下: 自建UI库新增界面: 注:平台级UI库不支…...
【学习笔记】Macbook管理多个不同的Python版本
在MacBook上管理不同项目的不同Python版本,可以使用多种方法。以下是一些常见的方法: 1. 使用 pyenv pyenv 是一个非常流行的工具,可以让你轻松安装和切换多个Python版本。以下是安装和使用 pyenv 的步骤: 安装 pyenv 安装依赖…...
前端如何设计一个回溯用户操作的方案
同一个项目,为什么我本地无法复现,只有客户的设备才复现? 如何获取用户的操作路径呢? 两种方案:埋点和rrweb 埋点就很简单了,将所有可能操作的节点都进行预埋数据;但埋点简单并不省心ÿ…...
WPF、控件模板(ControlTemplate)和数据模板(DataTemplate)
前言 在 WPF 中,控件种类丰富且功能非常完善。一个显著的优点是 WPF 提供了强大的自定义能力和灵活的用户界面表现,能够满足各种复杂的应用需求。其中,ControlTemplate 和 DataTemplate 是两个非常重要的概念,分别用于自定义控件…...
MAC上安装Octave
1. 当前最新版Octave是9.3版本,需要把mac os系统升级到14版本(本人之前的版本是10版本) https://wiki.octave.org/Octave_for_macOS octave的历史版本参考此文档:Octave for macOS (outdated) - Octavehttps://wiki.octave.org/Oc…...
RabbitMQ(三)
RabbitMQ中的各模式及其用法 工作队列模式一、生产者代码1、封装工具类2、编写代码3、发送消息效果 二、消费者代码1、编写代码2、运行效果 发布订阅模式一、生产者代码二、消费者代码1、消费者1号2、消费者2号 三、运行效果四、小结 路由模式一、生产者代码二、消费者代码1、消…...
一体机cell服务器更换内存步骤
一体机cell服务器更换内存步骤: #1、确认grdidisk状态 cellcli -e list griddisk attribute name,asmmodestatus,asmdeactivationoutcome #2、offline griddisk cellcli -e alter griddisk all inactive #3、确认全部offline后进行关机操作 shutdown -h now #4、开…...
年后找工作需要注意的事项
大家好!我是 [数擎 AI],一位热爱探索新技术的前端开发者,在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | A…...
【网络 MAC 学习专栏 -- 如何理解 PHY 的 Link Up】
请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | ARM GCC | CSH】 文章目录 OverviewClause 22/Clause 45Clause 22Clause 45 PHY Link 状态的软件实现 转自: 开心果 Need Car 2022年10月20日 09:50 上海 Overview PHY…...
鸿蒙UI开发——文本级联选择器
1、概 述 ArkUI提供了一个文本选择器(showTextPickerDialog),可以方便的实现文本级联选择,例如:省->市->区,示意如下: 下面针对文本选择器做简单介绍。 2、接口介绍 定义文本滑动选择器…...
后盾人JS -- JS运算符与流程控制
嘻嘻 赋值运算符与算术运算符 没什么好说的,等号谁都会用 比较运算符注意事项 如果一个是字符一个是数字也是可以比较的() 是判断值和类型是否相等 <!DOCTYPE html> <html lang"en"><head><meta charset…...
Hive SQL必刷练习题:留存率问题
首次登录算作当天新增,第二天也登录了算作一日留存。可以理解为,在10月1号登陆了。在10月2号也登陆了,那这个人就可以算是在1号留存 今日留存率 (今日登录且明天也登录的用户数) / 今日登录的总用户数 * 100% 解决思…...
笔记本电脑 选购 回收 特权模式使用 指南
笔记本电脑 factor 无线网卡:有些笔记本无法检测到特定频段的信息,会导致连不上校园网 sudo iwlist wlp2s0 scan | grep Frequency > net.txt cat net.txt>表示用终端输出覆盖后续文件,>>表示添加到后续文件的末尾 一种更简…...
基于PyQt - 6的医疗多模态大模型医疗研究系统中的创新构建与应用(上 .文章部分)
一、引言 1.1 研究背景与意义 在当今数智化时代,医疗行业正经历着深刻的变革,对智能化、高效化的需求日益迫切。传统的医疗模式在面对海量的医疗数据、复杂的诊断流程以及个性化的治疗需求时,逐渐显露出局限性。随着人工智能技术的飞速发展,多模态大模型作为一种前沿技术…...
下载文件,浏览器阻止不安全下载
背景: 在项目开发中,遇到需要下载文件的情况,文件类型可能是图片、excell表、pdf、zip等文件类型,但浏览器会阻止不安全的下载链接。 效果展示: 下载文件的两种方式: 一、根据接口的相对url,拼…...
1.15学习
web ctfhub-网站源码 打开环境,查看源代码无任何作用,但是其提醒就在表面暗示我们用dirsearch进行目录扫描,登录kali的root端,利用终端输入dirsearch -u 网址的命令扫描该网址目录,扫描成功后获得信息,在…...
shell练习2
需求:判断192.168.1.0/24网络中,当前在线的ip有哪些,并编写脚本打印出来。 #!/bin/bashnmap -sn 192.168.1.0/24 | grep Nmap scan report for | awk {print $5} 注意:当运行 bash ip.sh 时出现 nmap: command not found 的错误…...
MySQL学习笔记5【SQL优化/视图/存储过程/触发器】
MySQL学习笔记 SQL优化 1. 插入数据优化 普通插入: 采用批量插入: 每次插入不建议超过1000条记录,这样可以减少事务开销,提高性能。示例: INSERT INTO tb_user (name, age) VALUES (Alice, 25), (Bob, 30), ...;手动提…...
C++单例模式的设计
单例模式(Singleton Pattern)是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在C中,单例模式通常用于管理全局资源或共享状态。 以下是C中实现单例模式的几种常见方式: 懒…...
【Linux系统编程】—— 自动化构建工具Makefile指南
文章目录 背景基本使用推导过程适度扩展语法 背景 Makefile 是衡量开发者是否具备完成大型工程能力的一个重要标志。在一个工程中,源文件的数量可能极多,这些文件会按照类型、功能或模块分布在多个目录中。Makefile 通过定义一系列规则,指定…...