Java数据结构 —— 手写线性结构(稀疏数组、栈、队列、链表)
目录
稀疏数组
顺序表
链表
单向顺序链表
双向链表
双向循环链表求解约瑟夫环(Joseph)
栈
顺序栈
队列
顺序队列
顺序循环队列
稀疏数组
当一个数组中大部分值为0,或者相同时,可以采用稀疏数组的方式来保存,从而节约存储空间,提高存储效率。
稀疏数组的存储格式为:
- 记录数组一共有几行几列,有多少不同的值
- 把具有不同值的元素的行和列以及值保存在一个小规模的数组中,实现压缩存储的效果
如下:
public class SparseArray {public static void keepData(int[][] arr) {ObjectOutputStream oos = null;try {oos = new ObjectOutputStream(new FileOutputStream("src\\sparseData.dat"));oos.writeObject(arr);} catch (IOException e) {e.printStackTrace();} finally {if(oos != null) {try {oos.close();} catch (IOException e) {e.printStackTrace();}}}}public static int[][] returnSparseData() {ObjectInputStream ois = null;int[][] data = null;try {ois = new ObjectInputStream(new FileInputStream("src\\sparseData.dat"));data = (int[][])ois.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();} finally {if(ois != null) {try {ois.close();} catch (IOException e) {e.printStackTrace();}}}return data;}public static void main(String[] args) {//已有的二维数组int row = 11;int col = 11;int[][] chessArr = new int[row][col];chessArr[1][2] = 1;chessArr[2][3] = 2;chessArr[5][5] = 5;//将以有的二维数组转换为稀疏数组节省存储空间int count = 0; //用于统计二维数组中非零元素的个数for (int[] arr : chessArr) {for (int data : arr) {if (0 != data) {count++;}}}//创建稀疏数组int[][] sparseArr = new int[count + 1][3];sparseArr[0][0] = row;sparseArr[0][1] = col;sparseArr[0][2] = count;//将二维数组中非零元素的值保存在稀疏数组中int rowOfSparse = 0;for (int i = 0; i < chessArr.length; i++) {for (int j = 0; j < chessArr[i].length; j++) {if (chessArr[i][j] != 0) {sparseArr[++rowOfSparse][0] = i;sparseArr[rowOfSparse][1] = j;sparseArr[rowOfSparse][2] = chessArr[i][j];}}}//将稀疏数组还原成二维数组int[][] objArr = new int[sparseArr[0][0]][sparseArr[0][1]];for (int i = 0; i < count; i++) {objArr[sparseArr[i+1][0]][sparseArr[i+1][1]] = sparseArr[i+1][2];}for(int[] arr : objArr) {for (int data : arr) {System.out.printf("%d\t",data);}System.out.println();}//将稀疏数组的数据保存到磁盘中keepData(sparseArr);//将磁盘中的稀疏数组进行恢复int[][] arrOriginal = returnSparseData();for (int[] arr : arrOriginal) {for (int data : arr) {System.out.printf("%d\t",data);}System.out.println();}}
}
顺序表
Java描述的顺序表
public class SequenceList_ {private int[] elements; //存放顺序表中的元素private int length; //顺序表的长度private final int maxSize;public void listSequence() {if (isEmpty()) {System.out.println("顺序表为空,无法进行遍历");}for (int i = 0; i < length; i++) {System.out.print(elements[i] + " ");}}public SequenceList_(int maxSize) {this.elements = new int[maxSize];this.length = 0;this.maxSize = maxSize;}public void clear() {this.length = 0;}public boolean isFull() {return length == maxSize;}public boolean isEmpty() {return length == 0;}public int getLength() {return length;}public int get(int index) {//对输入的index的范围进行检验if (index < 0 || index > maxSize - 1) {throw new ArrayIndexOutOfBoundsException("输入的索引位置不正确");}if (index > length - 1) {throw new ArrayIndexOutOfBoundsException("输入的索引位置还未插入元素!");}return elements[index];}public void addElement(int val) {if (isFull()) {System.out.println("线性表已满,无法继续插入元素!");}elements[length++] = val;}public void addElement(int val, int index) {if (isFull()) {System.out.println("线性表已满,无法继续添加!");}if (index < 0 || index > maxSize - 1) {System.out.println("索引位置不正确");}for (int i = length - 1; i >= index; i--) {elements[i + 1] = elements[i];}elements[index] = val;if (index > length - 1) {length = index + 1;} else {length++;}}public int indexOf(int val) {for (int i = 0; i < this.length; i++) {if (val == elements[i]) {return i;}}return -1;}public int remove(int index) throws Exception {if (index < 0 || index > maxSize - 1) {throw new Exception("索引位置不正确");}if (index > length - 1) {throw new Exception("在该位置没有元素");}int value = elements[index];for (int i = index; i < length - 1; i++) {elements[i] = elements[i + 1];}length--;return value;}public void updateElement(int val, int index) throws Exception {if (index < 0 || index > maxSize - 1) {throw new Exception("索引位置不正确");}if (index > length - 1) {throw new Exception("索引位置为空,无法更新");}elements[index] = val;}
}
链表
单向顺序链表
Java实现的单向顺序链表:
public class SingleLinkedList {private ListNode head;//链表的头结点private ListNode foot;//始终指向链表的末尾结点private boolean sequence;//链表是否有序public class ListNode { //表示链表节点的内部类public int val; //节点的数据域public ListNode next; //节点的指针域public ListNode(int val) {this.val = val;}}public SingleLinkedList() {this.head = new ListNode(0);//初始化头结点this.foot = this.head;}public SingleLinkedList(boolean sequence) {this.head = new ListNode(0);this.foot = head;this.sequence = true;}public void listLinkedElement() {ListNode temp = head.next;while (temp != null) {System.out.printf("%d\t", temp.val);temp = temp.next;}System.out.println();}public boolean isEmpty() {return head.next == null;}public int getSize() {int count = 0;ListNode listNode = head.next;while (listNode != null) {count++;listNode = listNode.next;}return count;}/*** 头插法插入元素** @param val 待插入节点数据域的值*/public void addElementAtHead(int val) {ListNode listNode = new ListNode(val);listNode.next = head.next;head.next = listNode;System.out.println("添加成功");}/*** 尾插法插入元素*/public void addElementAtFoot(int val) {ListNode listNode = new ListNode(val);foot.next = listNode;foot = listNode; //将foot指针指向尾结点System.out.println("添加成功");}public void addElementIndex(int index, int val) {//对插入位置进行检验if (index < 0 || index > getSize() + 1) {System.out.println("插入的位置不正确!");}ListNode listNode = new ListNode(val);//找到第index个元素前面的一个元素ListNode temp = head;for (int i = 0; i < index; i++) {temp = temp.next;}listNode.next = temp.next;temp.next = listNode;System.out.println("插入成功!");}public void deleteElementAtHead() {if (isEmpty()) {throw new RuntimeException("链表为空,无法继续删除!");}head.next = head.next.next; //删除链表的首个节点System.out.println("删除成功!");}public void deleteElementAtFoot() {if (isEmpty()) {throw new RuntimeException("链表为空,无法继续删除!");}ListNode temp = head;while (temp != null) {if (temp.next == foot) {foot = temp;foot.next = null;}temp = temp.next;}System.out.println("删除成功!");}/*** 按照索引删除元素** @param index*/public void deleteEmementIndex(int index) {//对index的值进行检验if (index < 0 || index > getSize()) {System.out.println("要删除元素的索引不正确!");}ListNode temp = head;for (int i = 0; i < index; i++) {temp = temp.next;}temp.next = temp.next.next;System.out.println("删除成功!");}public boolean contains(int value) {if (isEmpty()) {return false;}ListNode temp = head.next;while (temp != null) {if (temp.val == value) {return true;}temp = temp.next;}return false;}/*** 清空单链表中的数据*/public void clear() {head.next = null;foot = null;}public void addElementSequence(int val) {if (sequence) {ListNode listNode = new ListNode(val);ListNode temp = head;while (true) {if (temp.next == null) {temp.next = listNode;break;}if (temp.next.val > val) {listNode.next = temp.next;temp.next = listNode;break;}temp = temp.next;}System.out.println("添加成功!");} else {this.addElementAtFoot(val);}}
}
双向链表
Java描述的双向链表
public class DoubleLinkedList {public class ListNode_ {public int data;public ListNode_ next;public ListNode_ pre;public ListNode_() {}public ListNode_(int val) {this.data = val;}public ListNode_(int data, ListNode_ pre, ListNode_ next) {this.data = data;this.pre = pre;this.next = next;}}private ListNode_ head;private ListNode_ first; //记录头结点private ListNode_ last; //记录尾结点private int length; //记录链表的长度public DoubleLinkedList() {this.head = new ListNode_();this.last = null;this.first = null;this.length = 0;}public boolean isEmpty() {return head.next == null;}public ListNode_ getFirst() {return first;}public ListNode_ getLast() {return last;}public void insertInto(int val) {ListNode_ newNode = new ListNode_(val);ListNode_ oldLast = this.last;if (isEmpty()) {newNode.pre = head;head.next = newNode;this.first = newNode;this.last = newNode;length++;return;}//链表不为空newNode.pre = oldLast;oldLast.next = newNode;last = newNode;length++;}public void insertInto(int index, int val) {if (index < 0 || index > length) {System.out.println("插入的index位置大于链表的长度");return;}ListNode_ newNode = new ListNode_(val);//判断是否为最后一个节点if (index == length - 1) {ListNode_ oldLast = last;oldLast.next = newNode;newNode.pre = oldLast;last = newNode;} else if (index == 0) {ListNode_ oldFirst = first;head.next.pre = newNode;newNode.next = head.next;newNode.pre = head;head.next = newNode;} else {ListNode_ cur = head;for (int i = 0; i < index; i++) {cur = cur.next;}newNode.next = cur.next;newNode.pre = cur;cur.next.pre = newNode;cur.next = newNode;}length++;}public int get(int index) throws Exception {if (index < 0 || index > length - 1 || isEmpty()) {throw new Exception("index索引错误||链表为空");}ListNode_ cur = head.next;for (int i = 0; i < index; i++) {cur = cur.next;}return cur.data;}public int indexOf(int val) throws Exception {if (isEmpty()) {throw new Exception("链表为空");}ListNode_ cur = head.next;for (int i = 0; i < length; i++) {if (cur.data == val) {return i;}cur = cur.next;}return -1;}public int remove(int index) throws Exception {if (index < 0 || index > length - 1 || isEmpty()) {throw new Exception("链表中没有index索引||链表为空");}//最后一个节点if (index == length-- - 1) {ListNode_ oldLast = last;last = oldLast.pre;oldLast.pre.next = null;oldLast.pre = null;return oldLast.data;}//第一个节点if (index == 0) {ListNode_ oldFirst = first;oldFirst.next.pre = head;head.next = oldFirst.next;oldFirst.pre = oldFirst.next = null;first = head.next;return oldFirst.data;}ListNode_ cur = head.next;for (int i = 0; i < index; i++) {cur = cur.next;}cur.next.pre = cur.pre;cur.pre.next = cur.next;cur.next = cur.pre = null;return cur.data;}private void listDoubleLinkedList() {ListNode_ cur = head.next;while (cur != null) {System.out.print(cur.data + " ");cur = cur.next;}}public void listDoubleLinkedList(boolean reverse) {if (isEmpty()) {System.out.println("链表为空,无法遍历");return;}if (reverse) {ListNode_ cur = last;while (cur != head) {System.out.print(cur.data + " ");cur = cur.pre;}} else {listDoubleLinkedList();}System.out.println();}public int getLength() {return length;}
}
双向循环链表求解约瑟夫环(Joseph)
public class CircleSingleLinkedList {private BoyNode first;private int numOfBoy;public CircleSingleLinkedList(int num) {this.numOfBoy = num;this.addBoy(num);}private void addBoy(int num) {BoyNode last = null;for (int i = 1; i <= num; i++) {if (i == 1) {first = new BoyNode(i);last = first;last.setNext(first);continue;}BoyNode newNode = new BoyNode(i);last.setNext(newNode);newNode.setNext(first);last = newNode;}}public void showLinkedQueue() {BoyNode cur = first;while (true) {System.out.print(cur.getNo() + " ");cur = cur.getNext();if (cur == first) {break;}}}/*** @param k 从第几个人开始报数* @param m 报几个数*/public void removeFromLinkedList(int k, int m) {if (k < 1 || m < 0 || k > numOfBoy) {System.out.println("键入的数据不正确!");return;}//定义一个指针cur指向待出队的node节点,一个pre指针指向待出队节点的前一个节点BoyNode pre = first;BoyNode cur = first;while(pre.getNext() != first) {pre = pre.getNext();}//将pre和cur节点一项第k-1和第k个位置for (int i = 0; i < k - 1; i++) {pre = pre.getNext();}cur = pre.getNext();//循环出队System.out.print("出队序列: ");while (cur.getNext() != cur) {//将pre和cur分别指向待删除节点的前一个节点和待删除的节点for (int i = 0; i < m - 1; i++) {cur = cur.getNext();pre = pre.getNext();}//删除cur指向的节点System.out.print(cur.getNo() + " ");cur = cur.getNext();pre.setNext(cur);}System.out.print(cur.getNo());}
}class BoyNode {private int no;private BoyNode next;public BoyNode(int no) {this.no = no;}public BoyNode getNext() {return next;}public void setNext(BoyNode next) {this.next = next;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}
}
class Main {public static void main(String[] args) {CircleSingleLinkedList cll = new CircleSingleLinkedList(125);//环中总人数cll.showLinkedQueue();cll.removeFromLinkedList(10,20);}
}
思路:
- 创建两个引用pre和cur,初始状态下分别指向链表的最后一个节点和链表的首节点
- 得到k值后,将cur引用指向开始报数的节点,pre引用指向开始报数节点的前一个节点
- 报数m-1次,将pre和cur指针依次向后移动m-1次,删除cur指向的节点。(循环进行)
栈
顺序栈
Java描述的顺序栈:
public class ArrayStack {private int[] stack;private int top;private int maxSize;public ArrayStack(int maxSize) {this.maxSize = maxSize;stack = new int[maxSize];top = -1;}public boolean isFull() {return top == maxSize - 1;}public boolean isEmpty() {return top == -1;}public void push(int val) {if (isFull()) {System.out.println("栈满!无法添加");return;}stack[++top] = val;}public int pop() {if (isEmpty()) {throw new RuntimeException("栈空,无法取出元素!");}return stack[top--];}public void listStack() {if (isEmpty()) {System.out.println("栈为空,无法遍历!");}for (int i = top; i >= 0; i--) {System.out.printf("stack[%d] = %d\t", i, stack[i]);}}
}
链栈
队列
顺序队列
Java描述的顺序队列:
public class ArrayQueue {private int maxSize;private int front; //队列头部private int rear; //队列尾部private int[] arr; //队列数组public ArrayQueue(int maxSize) {this.maxSize = maxSize;arr = new int[maxSize];front = rear = -1;}/*** 判断队列是否满** @return 返回值*/public boolean isFull() {return rear == maxSize - 1;}/*** 判断队列是否为空** @return 返回值*/public boolean isEmpty() {return rear == front;}/*** 向队列中添加元素** @param val 待添加元素的值*/public void addElement(int val) {if (isFull()) {System.out.println("队列已满,无法继续添加!");}arr[++rear] = val;}/*** 获得队列中的数据** @return 返回队头元素*/public int getElement() {if (isEmpty()) {throw new RuntimeException("队列为空,无法取出数据");}return arr[++front];}/*** 显示当前队列的所有元素*/public void listQueue() {if (isEmpty()) {System.out.println("队列为空!");return;}for (int i = front+1; i < rear+1; i++) {System.out.printf(arr[i] + "\t");}}/*** 查询队列的队头元素** @return 返回查询元素*/public int headElement() {if (isEmpty()) {throw new RuntimeException("队列为空,无法取出数据");}return arr[front + 1];}
}
顺序循环队列
Java描述的顺序循环队列:
public class CircleArrayQueue {private int maxSize;private int front;private int rear;private int[] arr;public CircleArrayQueue(int maxSize) {this.maxSize = maxSize;front = 0;rear = 0;arr = new int[maxSize];}public boolean isEmpty() {return front == rear;}public boolean isFull() {return (rear + 1) % maxSize == front;}public void addElement(int val) {if (isFull()) {System.out.println("队列已满,无法添加!");return;}arr[rear] = val;rear = (rear + 1) % maxSize;System.out.println("元素添加成功!");}public int getElement() {if (isEmpty()) {throw new RuntimeException("队列为空,无法获取元素!");} else {int val = arr[front];front = (front + 1) % maxSize;return val;}}public int getElementSize() {return (rear + maxSize - front) % maxSize;}public void listQueue() {if (isEmpty()) {System.out.println("队列为空!");return;}for (int i = front; i < getElementSize() + front; i++) {System.out.printf("arr[%d] = %d\n", i % maxSize, arr[i % maxSize]);}
// int temp = front;
// while ((temp + 1) % maxSize != rear + 1) {
// System.out.printf("%d\t", arr[temp++]);
// }}
}
相关文章:

Java数据结构 —— 手写线性结构(稀疏数组、栈、队列、链表)
目录 稀疏数组 顺序表 链表 单向顺序链表 双向链表 双向循环链表求解约瑟夫环(Joseph) 栈 顺序栈 队列 顺序队列 顺序循环队列 稀疏数组 当一个数组中大部分值为0,或者相同时,可以采用稀疏数组的方式来保存,从而节约存储…...

docker部署gitlab过程中遇到的一些问题记录
文章目录用nginx代理docker部署的gitlab服务密码重置docker0网卡异常离线安装apt的包用nginx代理docker部署的gitlab服务 一般咱们不会去暴露很多端口给外面,所以部署完gitlab后,我希望能够用nginx来代理我们的gitlab服务。 gitlab的docker部署参考这个…...

数组的定义与使用
文章目录 数组的基本概念数组的基本用法数组与方法互操作一、数组的基本概念 数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。 注意:1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3. 每个空间有自己的编号࿰…...
SAP ABAP用程序删除开发KEY
在BASISI系统管理中,用户的开发Key存储在DEVACCESS表中,如果由于审计需要删除一些用户的开发Key,而系统有限制SM30, SE16 or SE16N 等事务码的使用,你就可以通过一个小程序去删除开发Key。 代码如下: REPORT ZBCDEV…...
安卓设备TF卡概率性无法识别问题
现象 使用t卡的设备出货前检测是正常的,放在仓库中或出货后再开机,有概率的机器无法识别,重新插拔或重启无效,拔下来放pc电脑上识别后再插回设备则恢复正常能识别。 设备信息 系统: Android 8.1.0 数量:抽检有12%的设备无法识别 TF卡:SanDisk Ultra 64GB 10 A1 microS…...

linux安装nodejs和微信小程序自动化部署操作
一.运行环境安装 Node.js 并且版本大于 8.0基础库版本为 2.7.3 及以上开发者工具版本为 1.02.1907232 及以上安装node.js(1).下载node包官网地址:https://nodejs.org/en/download/如果英文不好的,可以看中文网站:https://nodejs.org/zh-cn/download/点击上面的进行下载,当然,也…...

JavaScript高级 Proxy Reflect
1. Proxy 1. 监听对象的变化 有一个对象,我们希望监听这个对象中的属性被设置或获取的过程 我们可以通过 Object.defineProperty 来实现 const obj {name: "why",age: 18,height: 1.88 }// 需求: 监听对象属性的所有操作 // 监听属性的操作 // 1.针对…...

Eth-trunk :LACP模式链路聚合实战
Eth-trunk : LACP模式链路聚合实战 需求描述 PC1和PC3数据vlan10 ,网段为192.168.10.0 /24PC2和PC4数据vlan20 ,网段为192.168.20.0 /24确保设备之间互联互通,使用最大互联带宽并没有环路确保相同网段的PC可以互通判断交换机之间的每个端口…...
【第二章 - 线性表之顺序表】- 数据结构(八千字详解)
目录 一、线性表的定义和特点 二、线性表的顺序表示和实现 2.1 - 线性表的顺序存储表示 2.2 - 顺序表中基本操作的实现 三、练习 3.1 - 移除元素 3.2 - 删除有序数组中的重复项 3.3 - BC100 有序序列合并 3.4 - 88.合并两个有序数组 四、顺序表的问题及思考 线性表、…...
【史上最全面esp32教程】RGB彩灯篇
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录rgb彩灯的介绍使用方法连线库操作彩灯变换颜色实验彩灯呼吸灯效果总结提示:以下是本篇文章正文内容,下面案例可供参考 rgb彩灯的介绍 ESP32…...
大规模 IoT 边缘容器集群管理的几种架构-5-总结
前文回顾 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介大规模 IoT 边缘容器集群管理的几种架构-1-RancherK3s大规模 IoT 边缘容器集群管理的几种架构-2-HashiCorp 解决方案 Nomad大规模 IoT 边缘容器集群管理的几种架构-3-Portainer大规模 IoT 边缘容器集群管…...

逆风翻盘拿下感知实习offer,机会总是留给有准备的人
个人背景211本,985硕,本科是计算机科学与技术专业,研究生是自学计算机视觉方向,本科主要做C和python程序设计开发,java安卓开发,研究生主要做目标检测,现在在入门目标跟踪和3d目标检测。无论文&…...

SpringBoot整合阿里云OSS文件上传、下载、查看、删除
SpringBoot整合阿里云OSS文件上传、下载、查看、删除1、开发准备1.1 前置知识1.2 环境参数1.3 你能学到什么2. 使用阿里云OSS2.1 创建Bucket2.2 管理文件2.3 阿里云OSS文档3. 项目初始化3.1 创建SpringBoot项目3.2 Maven依赖3.3 安装lombok插件4. 后端服务编写4.1 阿里云OSS配置…...

对话数字化经营新模式:第2届22客户节(22Day)年猪宴圆满结束!
2023年2月22日,由杭州电子商务研究院联合贰贰网络(集团)、TO B总监联盟等发起举办的“第二届客户节22Day”暨2022年度爱名奖 AM AWARDS颁奖及22年猪宴沙龙活动圆满结束。 (主持人:杜灵芝) 本次沙龙邀请到浙江工业大学管理学院程志…...
数据结构——第二章 线性表(5)——双向循环链表
双向循环链表1.双向循环链表的定义2.双向循环链表的基本操作实现2.1 双向循环链表的初始化操作2.2.双向循环链表的插入操作2.3. 双向循环链表的删除操作1.双向循环链表的定义 单向链表便于查询后继结点,不便于查询前驱结点。为了方便两个方向的查询,可以…...

4面美团软件测试工程师,却忽略了这一点,直接让我前功尽弃
说一下我面试别人时候的思路 反过来理解,就是面试时候应该注意哪些东西;用加粗部分标注了 一般面试分为这么几个部分: 一、自我介绍 这部分一般人喜欢讲很多,其实没必要。大约5分钟内说清楚自己的职业经历,自己的核…...

robot remote server用这个server去远程获取ip
server端配置: 1、安装python环境 2、下载robot remote server 下载地址:https://pypi.python.org/pypi/robotremoteserver/(不要用pip下载,把robotremoteserver.py文件下载下来) 3、首先创建一个目录E:\rfremote\ &a…...
【WSL】Windows 上安装并启动
一、什么是 WSL Windows Subsystem for Linux 适用于 Linux 的 Windows 子系统 可以帮助我们自然、方便地在 Windows 上使用 Linux 子系统 二、安装 我们要安装的是 WSL2 , 因为其功能相对来说更加完善 1. 简化安装 — 本人亲测不好用 简化安装:高…...

SAFe(Scaled Agile Framework)学习笔记
1.SAFe 概述 SAFe(Scaled Agile Framework)是一种面向大型企业的敏捷开发框架,旨在协调多个团队和部门的协同工作,以实现高效的软件开发和交付。下面是SAFe框架的简单介绍总结: SAFe框架包括以下四个层次:…...

Redis 集群搭建
前缀参考文章1:Centos7 安装并启动 Redis-6.2.6 前缀参考文章2:Redis 主从复制-服务器搭建【薪火相传/哨兵模式】 管道符查看所有redis进程:ps -ef|grep redis 杀死所有redis进程:killall redis-server 1. 首先修改 redis.conf 配…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...