我于窗中窥月光,恰如仰头见“链表”(Java篇)

本篇会加入个人的所谓‘鱼式疯言’

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言
而是理解过并总结出来通俗易懂的大白话,
小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.
🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

前言

在上一篇文章中我们讲解了线性表中:顺序表和ArrayList

而在本篇文章中小编将带着大家讲解另外一种线性表:LinkedList与链表

而在本篇文章提及的链表是: 单链表

下面让我们看看我们要学习的章节吧 💖 💖 💖

目录

  1. 链表的初识
  2. 单链表的实现
  3. 单链表的优化

一. 链表的初识

1. ArrayList 的不足

在上一篇文章中我们已经熟悉了 ArrayList 的使用,并且进行了简单的模拟实现。

通过源码知道,ArrayList底层是使用数组来存储元素

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// ...
// 默认容量是10
private static final int DEFAULT_CAPACITY = 10;
//...
// 数组:用来存储元素
transient Object[] elementData; // non-private to simplify nested class access
// 有效元素个数
private int size;
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
// ...}

由于其底层是一段 连续空间 ,当在 ArrayList 任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为 O(n)效率比较低

因此 ArrayList不适合做任意位置插入和删除比较多的场景。因此:

java集合 中又引入了 LinkedList,即链表结构。

下面小编就介绍了我们今天的男一号选手 链表

2. 链表的概念

链表是一种 物理存储结构上非连续存储结构 ,数据元素的 逻辑顺 是通过链表中的引用 链接次序 实现的 。

在这里插入图片描述

我们平常说的 节点(又叫结点) 就是链表的基本单位,相当于上面这个火车的 每一节车厢

在这里插入图片描述

实际中链表的结构非常多样,那么链表组合起来一共有多少种结构呢 💥 💥 💥

3.链表的结构

实际中链表的结构非常多样,以下情况组合起来就有 8种链表结构

  1. 单向或者双向

在这里插入图片描述

  1. 带头或者不带头

在这里插入图片描述

  1. 循环或者非循环

在这里插入图片描述

虽然有这么多的链表的结构,但是我们重点掌握两种

第一种结构就是本篇文章要重点讲的

无头单向非循环链表(俗称 单链表 )

结构简单,一般不会单独用来存数据。 实际中更多是作为其他数据结构的子结构

在这里插入图片描述

哈希桶、图的邻接表 等等。

另外这种结构在 笔试面试 中出现很多。

第二种结构是下篇文章的重点内容哦,小伙伴们可以 期待 一下哦 💞 💞 💞

无头双向链表

在Java的集合框架库中 LinkedList底层 实现就是 无头双向循环链表

二. 单链表的实现

小伙伴们要理解链表就需要动手去 实现他们

所以这次就让小编带着小伙伴们来实现我们的 单链表 吧 💥💥💥

1. 框架搭建

<1>. 节点定义

public class MySingleLinkedList implements ISingleLinkList{public ListNode head;public static  class ListNode {// 存放数据public  int val;// 指向下一个节点的nextpublic ListNode next;public ListNode(int val) {this.val = val;}}public MySingleLinkedList() {this.head = new ListNode(1);}
}

我们先定义一个

在这个类中再定义一个 内部类 ,一个个内部类就代表我们一个个 节点 ,用我们的 next 的引用来指向,另外在添加一个自身数据的 val

还需要定义个接口来 整合功能

<2>. 功能接口

package singlinklist;
public interface ISingleLinkList {// 打印数据public void display();// 尾删数据public void removeLast();// 头删public void removeFirst();// 指定位置删除数据public void remove(int pos);// 删除指定数据public void removeVal(int val);// 删除指定的所有数据public void removeValAll(int val);// 头插public void insertFirst(int val);// 尾插数据public void insertLast(int val);// 指定位置插入数据public void insert(int pos,int val);// 确定数据是否存在public boolean contains(int val);// 修改数据public void modify(int pos ,int val);// 清空单链表public void clear();// 链表长度public int length();}

2. 功能实现

从上面的接口中我们就可以知道,咱们功能主要是四大板块: 增删查改

package singlinklist;public class MySingleLinkedList implements ISingleLinkList{public ListNode head;public static  class ListNode {// 存放数据public  int val;// 指向下一个节点的nextpublic ListNode next;public ListNode(int val) {this.val = val;}}public MySingleLinkedList() {this.head = new ListNode(1);}// 打印单链表@Overridepublic void display() {checknull();ListNode cur=head;while (cur != null) {System.out.print(cur.val+" ");cur=cur.next;}System.out.println();}@Overridepublic void insertFirst(int val) {checknull();ListNode node=new ListNode(val);node.next=head;head=node;}@Overridepublic void insertLast(int val) {checknull();ListNode cur=head;while (cur.next !=null) {cur=cur.next;}ListNode node =new ListNode(val);//       本身 cur.next=null  这行可加可不加
//        node.next=cur.next;cur.next=node;}// 指定位置插入@Overridepublic void insert(int pos, int val) {checknull();if (pos==0) {insertFirst(val);return;}if (pos==length()) {insertLast(val);return;}ListNode des= indexFind(pos);if (des==null) {return;}ListNode cur=head;while (cur.next != des) {cur=cur.next;}ListNode node=new ListNode(val);node.next=des;cur.next=node;}@Overridepublic void removeLast() {checknull();if (isEmpty()) {return;}ListNode cur=head;if (cur.next==null) {head=null;return;}while (cur.next.next != null) {cur=cur.next;}cur.next=null;}@Overridepublic void removeFirst() {checknull();if (isEmpty()) {return;}ListNode cur=head;head=head.next;cur=null;}@Overridepublic void remove(int pos) {checknull();if (isEmpty()) {return;}if (pos==0) {removeFirst();return;}ListNode dec=indexFind(pos);if (dec==null) {return;}ListNode cur=head;while (cur.next !=dec) {cur=cur.next;}cur.next=cur.next.next;}// 删除特定数据@Overridepublic void removeVal(int val) {checknull();if (isEmpty()) {return;}ListNode cur=head;if (cur.val==val) {removeFirst();return;}while (cur.next != null) {if (cur.next.val==val) {cur.next=cur.next.next;return;}cur=cur.next;}}// 删除特定的所有数据@Overridepublic void removeValAll(int val) {checknull();if (isEmpty()) {return;}ListNode cur=head.next;ListNode pre=head;while (cur != null) {if (cur.val == val) {cur=cur.next;} else {pre.next=cur;pre=pre.next;cur=cur.next;}}pre.next=null;if (head.val==val) {removeFirst();}}//    //删除单链表中所有的keyword
方法一:
//    public void removeValAll(int val){
//        ListNode cur=head;
//
//        while(cur.next!=null){
//            if(cur.next.val==val){
//                ListNode ret=cur.next;
//                cur.next=ret.next;//这里ret.next和直接写cur.next.next是一样的;
//            } else {
//                cur=cur.next;
//
//            }
//            if(cur==null){
//                break;
//            }
//        }
//
//        if(head.val==val){
//            head=head.next;
//        }
//    }// 搜索是否含有该数据@Overridepublic boolean contains(int val) {checknull();ListNode cur=head;while (cur != null) {if (cur.val==val) {return true;}cur=cur.next;}return false;}@Overridepublic void modify(int pos, int val) {checknull();if (isEmpty()) {return;}ListNode des=indexFind(pos);if (des==null) {return;}des.val=val;}@Overridepublic void clear() {head=null;}private void  checknull() {if (head==null) {System.out.println("单链表为null");}}private  ListNode indexFind(int pos) {try {chackIdex(pos);}catch (IndexOutOfBoundsException e) {e.printStackTrace();return null;}ListNode cur=head;for (int i = 0; i < pos; i++) {cur=cur.next;}return cur;}@Overridepublic int length() {int count=0;ListNode cur=head;while (cur != null) {count++;cur=cur.next;}return count;}// 检查链表是否长度为 0private  boolean isEmpty() {return length()==0;}// 检查下标是否合法private void chackIdex(int pos) throws IndexOutOfBoundsException {if (pos <0 || pos >= length()) {throw  new  IndexNotLegalException();}}}

在这里插入图片描述

是不是看着眼花缭乱的,不妨不妨下面让小编来细细讲解一下我们 增删查改 的主要内容吧 💥💥💥

<1>. 增加功能

指定位置 插入为例

 // 指定位置插入@Overridepublic void insert(int pos, int val) {checknull();if (pos==0) {insertFirst(val);return;}if (pos==length()) {insertLast(val);return;}ListNode des= indexFind(pos);if (des==null) {return;}ListNode cur=head;while (cur.next != des) {cur=cur.next;}ListNode node=new ListNode(val);node.next=des;cur.next=node;}

我们先找到 pos 位置,把新的 nodenext 修改成修改指向 pos 位置的节点的

在将 pos-1 位置的 next 修改指向为 node

请添加图片描述

鱼式疯言

在插入中需要特别考虑以下三种情况

  1. pos 可能不合法
  try {chackIdex(pos);}catch (IndexOutOfBoundsException e) {e.printStackTrace();return null;}
  1. 头位置 插入
if (pos==0) {insertFirst(val);return;
}
  1. 尾位置 插入
  if (pos==length()) {insertLast(val);return;}

<2>. 删除功能

指定找到 pos 位置,并把 pos-1 的节点和 pos+1 的节点用 next 进行连接

@Overridepublic void remove(int pos) {checknull();if (isEmpty()) {return;}if (pos==0) {removeFirst();return;}ListNode dec=indexFind(pos);if (dec==null) {return;}ListNode cur=head;while (cur.next !=dec) {cur=cur.next;}cur.next=cur.next.next;}

请添加图片描述

鱼式疯言

需要注意的点

  1. 当pos 位置不合法时
  try {chackIdex(pos);}catch (IndexOutOfBoundsException e) {e.printStackTrace();return null;}
  1. 如果链表为空 时
 if (isEmpty()) {return;}
  1. 头部位置删除时
 if (pos==0) {removeFirst();return;}

<3>. 查找功能

查找功能主要是查找是否含有该数据以及下标的功能

主要过程是先 从头节点开始遍历 ,当找到该数据就返回 true下标位置

// 搜索是否含有该数据@Override
public boolean contains(int val) {checknull();ListNode cur=head;while (cur != null) {if (cur.val==val) {return true;}cur=cur.next;}return false;
}

请添加图片描述

是的

这里就可以 很清楚的寻找到对应数据的位置

鱼式疯言

如果数据为 ,我们就不需要修改

<4>. 修改功能

主要过程是先 从头节点开始遍历 ,当找到该数据就返回 下标位置

然后找到该小标位置就返回该节点,对这个 节点 的数据进行 修改

@Override
public void modify(int pos, int val) {checknull();if (isEmpty()) {return;}ListNode des=indexFind(pos);if (des==null) {return;}des.val=val;
}

鱼式疯言

如果链表为 ,我们就 不需要修改

if (des==null) {return;
}

基本单链表的的框架我们讲完了,但小爱同学就思考了,我们这种链表在val
中只能放整型数据么? 不可以放其他类型的数据吗?

答案自然是 可以的

3.其他处理

  • 自定义一个异常来检查下标合法性
package singlinklist;
public class IndexNotLegalException extends RuntimeException{public IndexNotLegalException() {}public IndexNotLegalException(String message) {super(message);}
}
  • 主函数逻辑的实现
package singlinklist;public class Test {public static void main(String[] args) {ISingleLinkList msl =new MySingleLinkedList();// 插入System.out.println("=====插入========");// 尾插msl.insertFirst(1);msl.insertLast(1);msl.insertLast(1);msl.insertLast(1);msl.insertLast(1);msl.insertLast(6);msl.insertLast(1);msl.insertLast(1);msl.insertLast(2);msl.insertLast(1);msl.insertLast(3);msl.insertLast(1);msl.insertLast(1);msl.display();//        System.out.println("======删除=======");
//
//        msl.remove(3);
//        msl.removeFirst();
//        msl.removeLast();
//        msl.display();
//
//
//        System.out.println("======修改=====");
//        msl.modify(1,2);
//        msl.display();
//
//
//        System.out.println("=====查找=====");
//        System.out.println(msl.contains(2));
//        System.out.println(msl.contains(3));
//        System.out.println(msl.length());
//
//        msl.clear();System.out.println("=======");
//        msl.removeVal(0);
//        msl.removeVal(1);
//        msl.removeVal(2);
//        msl.removeVal(3);
//        msl.display();msl.removeValAll(1);msl.display();msl.insertLast(2);msl.insertLast(3);msl.insert(3,9);msl.insertFirst(0);msl.display();System.out.println("======删除=======");msl.remove(3);msl.removeFirst();msl.removeLast();msl.display();System.out.println("======修改=====");msl.modify(1,2);msl.display();System.out.println("=====查找=====");System.out.println(msl.contains(2));System.out.println(msl.contains(3));System.out.println(msl.length());msl.clear();}
}

三. 单链表的优化

单链表如果 限定死了 ,只能存放 整型或者 浮点型 那就太单一了

所以如果我们要对 单链表优化 的话,那么我们不得不请出我们的 泛型

1.功能接口

package generarraysinglinklist;public interface IGSingleLinkList<T> {// 打印数据public void display();// 尾删数据public void removeLast();// 头删public void removeFirst();// 指定位置删除数据public void remove(int pos);// 删除指定数据public void removeVal(T val);// 删除指定的所有数据public void removeValAll(T val);// 头插public void insertFirst(T val);// 尾插数据public void insertLast(T val);// 指定位置插入数据public void insert(int pos,T val);// 确定数据是否存在public boolean contains(T val);// 修改数据public void modify(int pos ,T val);// 清空单链表public void clear();// 链表长度public int length();}

2. 功能实现

package generarraysinglinklist;import singlinklist.ISingleLinkList;
import singlinklist.IndexNotLegalException;public class GMySingleLinkedList<T> implements IGSingleLinkList<T> {public ListNode head;public static  class ListNode<T> {// 存放数据public  T val;// 指向下一个节点的nextpublic ListNode<T> next;public ListNode(T val) {this.val = val;}}public GMySingleLinkedList(T val) {this.head = new ListNode<T>(val);}// 打印单链表@Overridepublic void display() {checknull();ListNode cur=head;while (cur != null) {System.out.print(cur.val+" ");cur=cur.next;}System.out.println();}@Overridepublic void insertFirst(T val) {checknull();ListNode node=new ListNode(val);node.next=head;head=node;}@Overridepublic void insertLast(T val) {checknull();ListNode cur=head;while (cur.next !=null) {cur=cur.next;}ListNode node =new ListNode(val);//       本身 cur.next=null  这行可加可不加
//        node.next=cur.next;cur.next=node;}// 指定位置插入@Overridepublic void insert(int pos, T val) {checknull();if (pos==0) {insertFirst(val);return;}if (pos==length()) {insertLast(val);return;}ListNode des= indexFind(pos);if (des==null) {return;}ListNode cur=head;while (cur.next != des) {cur=cur.next;}ListNode node=new ListNode(val);node.next=des;cur.next=node;}@Overridepublic void removeLast() {checknull();if (isEmpty()) {return;}ListNode cur=head;if (cur.next==null) {head=null;return;}while (cur.next.next != null) {cur=cur.next;}cur.next=null;}@Overridepublic void removeFirst() {checknull();if (isEmpty()) {return;}ListNode cur=head;head=head.next;cur=null;}@Overridepublic void remove(int pos) {checknull();if (isEmpty()) {return;}if (pos==0) {removeFirst();return;}ListNode dec=indexFind(pos);if (dec==null) {return;}ListNode cur=head;while (cur.next !=dec) {cur=cur.next;}cur.next=cur.next.next;}// 删除特定数据@Overridepublic void removeVal(T val) {checknull();if (isEmpty()) {return;}ListNode cur=head;if (cur.val.equals(val)) {removeFirst();return;}while (cur.next != null) {if (cur.next.val.equals(val)) {cur.next=cur.next.next;return;}cur=cur.next;}}// 删除特定的所有数据@Overridepublic void removeValAll(T val) {checknull();if (isEmpty()) {return;}ListNode cur=head.next;ListNode pre=head;while (cur != null) {if (cur.val .equals(val) ) {cur=cur.next;} else {pre.next=cur;pre=pre.next;cur=cur.next;}}pre.next=null;if (head.val.equals(val)) {removeFirst();}}//    //删除单链表中所有的keyword
方法一:
//    public void removeValAll(int val){
//        ListNode cur=head;
//
//        while(cur.next!=null){
//            if(cur.next.val.equals(val)){
//                ListNode ret=cur.next;
//                cur.next=ret.next;//这里ret.next和直接写cur.next.next是一样的;
//            } else {
//                cur=cur.next;
//
//            }
//            if(cur==null){
//                break;
//            }
//        }
//
//        if(head.val.equals(val)){
//            head=head.next;
//        }
//    }// 搜索是否含有该数据@Overridepublic boolean contains(T val) {checknull();ListNode cur=head;while (cur != null) {if (cur.val.equals(val)) {return true;}cur=cur.next;}return false;}@Overridepublic void modify(int pos, T val) {checknull();if (isEmpty()) {return;}ListNode des=indexFind(pos);if (des==null) {return;}des.val=val;}@Overridepublic void clear() {ListNode<T> cur=head;while (cur != null) {cur.val=null;cur=cur.next;}head=null;}private void  checknull() {if (head==null) {System.out.println("单链表为null");}}private  ListNode indexFind(int pos) {try {chackIdex(pos);}catch (IndexOutOfBoundsException e) {e.printStackTrace();return null;}ListNode cur=head;for (int i = 0; i < pos; i++) {cur=cur.next;}return cur;}@Overridepublic int length() {int count=0;ListNode cur=head;while (cur != null) {count++;cur=cur.next;}return count;}// 检查链表是否长度为 0private  boolean isEmpty() {return length()==0;}// 检查下标是否合法private void chackIdex(int pos) throws IndexOutOfBoundsException {if (pos <0 || pos >= length()) {throw  new IndexNotLegalException();}}}

3. 其他处理

package generarraysinglinklist;import generarraylist.GMyArrayList;
import generarraylist.IGList;import java.util.List;public class Test {public static void main(String[] args) {IGSingleLinkList<String> c=new GMySingleLinkedList<>("1");System.out.println("--------增加数据----------");c.insertLast("1");c.insertLast("3");c.insert(1,"2");c.insert(1,"2");c.insert(1,"2");c.insert(1,"2");c.insert(1,"2");c.insert(1,"2");c.insert(1,"2");c.insertFirst("0");c.display();System.out.println("--------删除数据-----------");c.removeValAll("2");c.removeLast();c.display();System.out.println("--------查找数据-------------");String str= "0";boolean b= c.contains(str);System.out.println(b);System.out.println("---------修改数据-----------");c.modify(1,"2");c.display();}
}

在这里插入图片描述

  • 自定义一个异常来检查下标合法性
package singlinklist;
public class IndexNotLegalException extends RuntimeException{public IndexNotLegalException() {}public IndexNotLegalException(String message) {super(message);}
}

在前面小编已经详细介绍了 底层原理 ,这里小编就 不重复赘述 了,

心细的小伙伴是不是发现了只需要把 int 类型改成 T 即可完成我们的需求

具体泛型的理解期待博主下一篇文章的详解哦,在这里小伙伴们只需要记住一点:

泛型是可以接收并使用任何类型的

总结

  1. 链表的初识: 从我们的ArrayList 引出我们链表的概念以及多种结构的了解
  2. 单链表的实现: 单链表节点如何实现创建和连接并进行增删查改的详细说明
  3. 单链表的优化: 我们讲解了泛型的引入可以使单链表的可以增加不同类型的

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

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

相关文章

java项目通用Dockerfile

创建Dockerfile文件&#xff0c;放到项目根目录下和pom.xml同级别 仅需修改为自己项目端口号即可&#xff0c;其他的无需改动 FROM openjdk:11.0.11-jre-slimCOPY target/*.jar .EXPOSE 8080ENTRYPOINT java -jar *.jar构建语句(注意末尾的点 . ) docker build -t container…

Android Studio Iguana | 2023.2.1 补丁 1

Android Studio Iguana | 2023.2.1 Canary 3 已修复的问题Android Gradle 插件 问题 295205663 将 AGP 从 8.0.2 更新到 8.1.0 后&#xff0c;任务“:app:mergeReleaseClasses”执行失败 问题 298008231 [Gradle 8.4][升级] 由于使用 kotlin gradle 插件中已废弃的功能&#…

C语言例1-3:设 int a; ,语句 for(a=0;a==0;a++); 和语句 for(a=0;a=0;a++); 执行的循环次数分别是

答案&#xff1a;1,0 代码如下&#xff1a; #include<stdio.h> int main(void) {int a;for(a0;a0;a){printf("1\n");} return 0; } 结果如下&#xff1a; 代码如下&#xff1a; #include<stdio.h> int main(void) {int a;for(a0;a0;a){printf("…

京东云8核16G服务器配置租用优惠价格1198元1年、4688元三年

京东云轻量云主机8核16G服务器租用优惠价格1198元1年、4688元三年&#xff0c;配置为8C16G-270G SSD系统盘-5M带宽-500G月流量&#xff0c;华北-北京地域。京东云8核16G服务器活动页面 yunfuwuqiba.com/go/jd 活动链接打开如下图&#xff1a; 京东云8核16G服务器优惠价格 京东云…

杰理芯片AC79——物联网远程点亮/关闭LED灯

杰理芯片的封装简直太香了&#xff08;比STM32香多了&#xff09;&#xff0c;SDK也封装得很好&#xff0c;对于我这种手残党简直不要太友好。赶紧学起来&#xff0c;快速实现你想要的功能吧&#xff01; 芯片选型 杰理AC79 资料文档 环境搭建以及点亮第一盏灯请访问&#x…

【一】DDR3基础知识与IMG IP

【一】DDR3基础知识与IMG IP 一、DDR3的基本知识 1、DDR3全称为第三代双倍速率同步动态随机存储器 特点&#xff1a;掉电无法保存数据&#xff0c;需要周期性的刷新&#xff1b;时钟上升沿和下降沿都在传输数据&#xff1b;突发传输&#xff0c;突发长度burtst length一般为…

Error: Cannot find module ‘@rollup/rollup-win32-x64-msvc‘

1.背景 新项目需要使用vite搭建一个v3项目,之前也弄过,但项目创建后却一直无法跑起来,大聪明的我一直没有注意到这个问题 2.解决步骤 方案1:删除node_modules和package-lock.json文件重新npm install下包,部分码农通过这个步骤可解决 方案2:node版本或者npm版本不对,或者没…

Vue3:快速上手路由器

本人在B站上关于vue3的尚硅谷的课程&#xff0c;以下是整理一些笔记。 一.路由器和路由的概念 在 Vue 3 中&#xff0c;路由&#xff08;Router&#xff09;和路由器&#xff08;Router&#xff09;是两个相关但不同的概念。 1. 路由&#xff08;Router&#xff09;&#xff…

LeetCode.2908. 元素和最小的山形三元组 I

题目 2908. 元素和最小的山形三元组 I 分析 首先&#xff0c;看到这道题&#xff0c;第一反应就是暴力方法&#xff0c;三层for循环&#xff0c;枚举每一种情况&#xff0c;代码如下 class Solution {public int minimumSum(int[] nums) {int min Integer.MAX_VALUE;for(i…

基于Springboot的学生选课系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的学生选课系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

线程池详解、核心参数、拒绝策略

什么是线程池 线程池是一种池化技术&#xff0c;它预先创建一组线程&#xff0c;用于执行异步任务。当有新任务到来时&#xff0c;线程池可以立即分配一个线程来处理&#xff0c;而不需要临时创建。这样可以减少因为频繁创建和销毁线程而导致的开销。 线程池的应用场景 高并…

2024年腾讯云4核8G12M轻量应用服务器测评_CPU内存带宽系统盘

腾讯云4核8G服务器价格&#xff1a;轻量4核8G12M优惠价格646元15个月、CVM S5服务器4核8G配置1437元买1年送3个月。腾讯云4核8G服务器支持多少人同时在线&#xff1f;支持30个并发数&#xff0c;可容纳日均1万IP人数访问。腾讯云百科txybk.com整理4核8G服务器支持多少人同时在线…

什么是技术分析和EA技术?澳福一个提醒丰厚收益

技术分析是指根据炒外汇市场汇率走势的过去表现&#xff0c;借助技术分析工具预测汇率的未来趋势并确定入市、出市策略的预测分析方法。 它是以预测市场价格变化的未来趋势为目的&#xff0c;以市场行为(外汇市场的价格和交易量)的图形、图表、形态、指标为手段&#xff0c;使用…

docker通过已有镜像打包执行

1、查看已有镜像 docker images 2、制作dockerfile FROM python LABEL maintainer"JETZ" add . / WORKDIR /3、新建镜像 docker build -t python3.7.13 .4、打包导出镜像 docker save python3.7.13 -o /opt/python3.7.13.tar5、重新加载镜像 cd /opt docker l…

电商系列之取消订单

> 插&#xff1a;AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

SOA-面向服务架构

SOA-面向服务架构 1.概述2.SOA的设计原则包括&#xff1a;3. SOA实现方法1.Web Service2. 服务注册表3. 企业服务总线 细讲 超赞笔记 1.概述 SOA &#xff08;Service-Oriented Architecture&#xff0c;SOA&#xff09;&#xff0c;从应用和原理的角度&#xff0c;目前有2种…

Matlab之提高交叉定位点的定位精度

通过测向交叉定位的方法&#xff0c;按理只需2根测向线即可得出定位点的位置。但由于误差的存在&#xff0c;求出的定位点位置存在一定的偏差。为了得到更加精确的定位点位置&#xff0c;需要对定位点进行冗余测量&#xff0c;从而得到多个定位点&#xff0c;然后通过定位点估计…

GRE和MGRE综合实验

实验拓扑图 实验思路 根据图中所属网段&#xff0c;配置ip地址和网关R1,R2,R3,R4配置缺省路由&#xff0c;可以是公网互通使用ppp验证&#xff0c;R1与R5为PAP验证&#xff0c;R5:aaa地址池&#xff0c;创建用户名以及密码&#xff0c;同时进行pap服务认证&#xff0c;同时在…

使用nvm管理nodejs版本

文章目录 1、下载NVM2、选择NVM安装3 、查询版本号&常用命令4、nvm命令安装指定版本node4.1 安装指定node4.2 查看是否安装成功4.3 切换node版本到你想要的版本4.4 再次查看nvm版本列表4.5 nvm其他常用命令 这个是每个全能前端经常会用到的&#xff0c;之前用过现在重装了&…

BitVM2:比特币上的无需许可验证

1. 引言 前序博客有&#xff1a; 基于BitVM的乐观 BTC bridgeBitVM&#xff1a;Bitcoin的链下合约Bitcoin Bridge&#xff1a;治愈还是诅咒&#xff1f; 最初的 BitVM 设计仅限于两方设置。BitVM2结合了并行和冗余实例&#xff0c;以引入基于 1-of-n 诚实假设的多方配置。这…