LinkedList与链表

目录

一、Arraylist的缺陷

二、链表

        2.1 链表的概念和结构

        2.2 链表的实现

三、链表面试题

       3.1 删除链表中所有值为val的节点

       3.2 反转一个单链表 

       3.3 链表的中间节点

       3.4 将有序链表合并

       3.5 输出倒数第k个节点

       3.6 链表分割

       3.7 链表的回文结构   

       3.8 找两个链表的公共节点

       3.9 判断链表是否有环

       3.10 找链表入环的第一个节点

四、LinkedList的模拟实现

五、LinkedList的使用

        5.1 什么是LinkedList

        5.2 LinkedList的使用

六、ArrayList和LinkedList的区别


一、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; 
        // 有效元素个数
        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底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java集合中引入LinkedList,即链表结构。

二、链表

        2.1 链表的概念和结构

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

        链式结构在逻辑上连续,但在物理上不一定连续;节点一般都是从堆上申请出来的;从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续

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

        1. 单向或双向

        2. 带头或不带头

        3. 循环或非循环

        链表有很多,重点掌握两种:

        无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多
        

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

        2.2 链表的实现

//无头单向非循环链表实现
public class SingleLinkedList {
        //头插法
        public void addFirst(int data){
        }

        //尾插法
        public void addLast(int data){
        }

        //任意位置插入,第一个数据节点为0号下标
        public void addIndex(int index,int data){
        }

        //查找是否包含关键字key是否在单链表当中
        public boolean contains(int key){
                return false;
        }

        //删除第一次出现关键字为key的节点
        public void remove(int key){
        }

        //删除所有值为key的节点
        public void removeAllKey(int key){
        }

        //得到单链表的长度
        public int size(){
                return -1;
        }

        //清空

        public void clear() {
        }

        //打印

        public void display() {

        }
}

三、链表面试题

        3.1 删除链表中所有值为val的节点

        删除链表中等于给定值val的所有节点  链接​​​​​​

public class ListNode {

        int val;

         ListNode next;

        ListNode() {} ; 

        ListNode(int val) {

                this.val = val;

         }

        ListNode(int val, ListNode next) {

                this.val = val;

                this.next = next;

        }

}

        解法1:遍历整个链表,将其中值为val的节点删除(将要删除节点前的节点的next指向要删除节点后的第一个节点)

public ListNode removeElements(ListNode head, int val) {

        //原链表是空链表

        if(head==null)

            return head;

        ListNode cur=head;

        //从第二个节点判断

        while(cur.next!=null){

            //下一个节点的值

            if(cur.next.val==val){

                cur.next=cur.next.next;

            }

            else{

                cur=cur.next;

            }

        }

        //判断头节点

        if(head.val==val){

            head=head.next;

        }

        return head;

    }

        解法2:遍历整个链表,将所有值不是给定值val的节点放入新链表中,返回新链表。

public ListNode removeElements(ListNode head, int val) {
        //原链表是空链表
        if(head==null)
            return head;
        //新链表的头节点
        ListNode head1=new ListNode();
        //新链表的节点
        ListNode cur1=head1;
        //原来链表的节点
        ListNode cur=head;
        //遍历原来链表
        while(cur!=null){
            //当前节点的值
            if(cur.val==val)
                cur=cur.next;
            else{
                cur1.next=cur;
                cur=cur.next;
                cur1=cur1.next;
            }
        }
    //如果新链表的尾节点不是原来链表的尾节点,将next置空
        if(cur1.next!=null)
            cur1.next=null;
        return head1.next;
    }

         3.2 反转一个单链表 

        链接

public class ListNode {

         int val;

         ListNode next;

         ListNode() {}

         ListNode(int val) {

                this.val = val;

        }

        ListNode(int val, ListNode next) {

                this.val = val;

                this.next = next;

        }

}

public ListNode reverseList(ListNode head) {

        //原链表为空

        if(head==null)

            return null;

        //原链表只有一个节点

        if(head.next==null)

            return head;

        //原链表的第二个节点开始

        ListNode cur=head.next;

        head.next=null;

        //遍历链表

        while(cur!=null){

            //curNext为当前节点的下一个节点

            ListNode curNext=cur.next;

            //头插法插入节点

            cur.next=head;

            head=cur;

            //当前节点指向原链表位置的下一个节点

            cur=curNext;

        }

        return head;

    }

        3.3 链表的中间节点

        给一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点  链接

 public class ListNode {

        int val;

        ListNode next;

        ListNode() {}

        ListNode(int val) {

                 this.val = val;

         }

        ListNode(int val, ListNode next) {

                this.val = val;

                this.next = next;

        }

}

        解法1:先求链表长度,获取长度一半的节点

public ListNode middleNode(ListNode head) {

            ListNode cur=head;

            //链表的长度

            int count=0;

            while(cur!=null){

                cur=cur.next;

                count++;

               

            }

            int BinaCount=count/2;

            ListNode ret=head;

            for(int i=0;i<BinaCount;i++){

                ret=ret.next;

            }

            return ret;

    }

        缺陷:需要两次遍历才能找到中间节点,当节点较多时,时间复杂度较大

        解法2:在一次遍历中找到中间节点,两个引用fast和slow分别走两步和一步

public ListNode middleNode(ListNode head) {

            ListNode fast=head;

            ListNode slow=head;

            while(fast!=null&&fast.next!=null){

                fast=fast.next.next;

                slow=slow.next;

            }

            return slow;

    }

          3.4 将有序链表合并

        将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的   链接

public class ListNode {
        int val;
        ListNode next;
        ListNode() {}
        ListNode(int val) {
                this.val = val;
        }
        ListNode(int val, ListNode next) {
                this.val = val;
                this.next = next;
        }
}

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {

            ListNode NewHead=new ListNode();

            //Newcur 新链表的尾节点

            ListNode Newcur=NewHead;

            while(list1!=null&&list2!=null){

                if(list1.val<list2.val){

                    Newcur.next=list1;

                    list1=list1.next;

                }else{

                    Newcur.next=list2;

                    list2=list2.next;

                }

                Newcur=Newcur.next;

            }

            //list1还有数

            if(list1!=null){

                Newcur.next=list1;

            }

            //list2还有数

            if(list2!=null){

                Newcur.next=list2;

            }

            return NewHead.next;

    }

       3.5 输出倒数第k个节点

        输入一个链表,输出该链表中倒数第k个结点  链接

public ListNode FindKthToTail(ListNode head,int k) {

        //链表为空或k太小

        if(k<=0||head==null){

            return null;

        }

        ListNode fast=head;

        //fast指向第k个节点

        while(k>1){

            fast=fast.next;

            //当k太大

            if(fast==null){

                return null;

            }  

            k--;

        }

        ListNode slow=head;

        //fast没有指向最后一个节点

        while(fast.next!=null){

            fast=fast.next;

            slow=slow.next;

        }

        return slow;

    }

        3.6 链表分割

        编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前        链接

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}

public ListNode partition(ListNode pHead, int x) {

        //pmin链表存小于x的节点

        ListNode pmin = null;

        //pin为pmin的尾节点

        ListNode pin = null;

        //pmin链表存大于等于x的节点

        ListNode pmax = null;

        //pax为pmax的尾节点

        ListNode pax = null;

        //遍历链表pHead,将小于x和大于等于x的存入pmin和pmax中

        ListNode cur = pHead;

        while (cur != null) {

            if (cur.val < x) {

                if (pmin == null) {

                    //pmin为空

                    pmin = cur;

                    pin = cur;

                } else {

                    //pmin不为空

                    pin.next = cur;

                    pin = pin.next;

                }

            } else {

                if (pmax == null) {

                    //pmax为空

                    pmax = cur;

                    pax = cur;

                } else {

                    //pmax不为空

                    pax.next = cur;

                    pax = pax.next;

                }

            }

            cur = cur.next;

        }

        if(pmin==null){

            //没有小于x的

            return pmax;

        }

        if(pmax==null){
            //没有大于等于x的

            return pmin;

        }

        //将pmin与pmax串联起来(pmin的尾节点指向pmax的头节点)

        pin.next=pmax;

        if(pax.next!=null){

            pax.next=null;

        }

        return pmin;

    }

       3.7 链表的回文结构   

         链接

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}

        反转:

public boolean chkPalindrome(ListNode A) {

        ListNode fast = A;

        //1、找中间节点slow

        ListNode slow = A;

        while (fast != null && fast.next != null) {

            fast = fast.next.next;

            slow = slow.next;

        }

        //2、中间节点之后的反转

        //cur是节点后的第一个节点

        ListNode cur = slow.next;

        slow.next=null;

        while (cur!= null) {

            //保存cur后的第一个节点

            ListNode curNext = cur.next;

            cur.next = slow;

            slow = cur;

            cur = curNext;

        }

        //反转结束后,slow指向最后一个节点

        //3、从第一个节点开始判断

        cur = A;

        while (cur != slow && cur.next != slow) {

            if (cur.val != slow.val) {

                return false;

            } else {

                cur = cur.next;

                slow = slow.next;

            }

        }

        return true;

    }

       3.8 找两个链表的公共节点

        输入两个链表,找出它们的第一个公共结点 链接

public class ListNode {

        int val;

        ListNode next;

        ListNode(int x) {

           val = x;

           next = null;

        }

}

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        //lenA、lenB分别为链表headA和链表headB的长度

        int lenA = 0;

        int lenB = 0;

        ListNode curA = headA;

        ListNode curB = headB;

        while(curA != null){

            lenA++;

            curA = curA.next;

        }

        while( curB != null){

            lenB++;

            curB = curB.next;

        }

        //pl指向最长链表,ps指向最短链表

        ListNode pl = headA;

        ListNode ps = headB;

        //长度差值len

        int len = lenA-lenB;

        if(len<0){

            //修正pl、ps、len

            pl = headB;

            ps = headA;

            len = lenB-lenA;

        }

        //pl走差值步

        while(len>0){

            pl = pl.next;

            len--;

        }

        //同步走

        while(pl != ps){

            pl = pl.next;

            ps = ps.next;

        }

        //pl为空,没有公共节点

        if(pl == null){

            return null;

        }

        return pl;

    }

       3.9 判断链表是否有环

        给定一个链表,判断链表中是否有环 链接

class ListNode {

        int val;

        ListNode next;

        ListNode(int x) {

            val = x;

            next = null;

        }

}

public boolean hasCycle(ListNode head) {

        //快慢指针

        ListNode fast = head;

        ListNode slow = head;

        while(fast!=null&&fast.next!=null){

            fast=fast.next.next;

            slow=slow.next;

            //相遇->有环

            if(fast==slow){

                return true;

            }

        }

        //循环结束->无环

        return false;

    }

        3.10 找链表入环的第一个节点

        给定一个链表,返回链表开始入环的第一个节点, 如果链表无环,则返回 NULL    链接

class ListNode {

        int val;

        ListNode next;

        ListNode(int x) {

            val = x;

            next = null;

        }

}

public ListNode detectCycle(ListNode head) {

        //快慢指针

        ListNode fast=head;

        ListNode slow=head;

        //找相遇节点

        while(fast!=null&&fast.next!=null){

            fast=fast.next.next;

            slow=slow.next;

            //相遇

            if(fast==slow){

                break;

            }

        }

        //fast=null或fast.next=bull->链表不为环,也就没有入环的第一个节点

        if(fast==null||fast.next==null){

            return null;

        }

        //慢指针从头开始

        slow=head;

        while(slow!=fast){

            slow=slow.next;

            fast=fast.next;

        }

        //循环结束,slow和fast都指向入环的第一个节点

        return slow;

    }

        结论:一个指针从链表起始位置开始走,同时让一个指针从判环时相遇点的位置开始走,两个指针每次均走一步,最终肯定会在环的入口点的位置相遇。

四、LinkedList的模拟实现

无头双向链表实现
public class MyLinkedList {
        //头插法
        public void addFirst(int data){ }
        //尾插法
        public void addLast(int data){}
        //任意位置插入,第一个数据节点为0号下标
        public void addIndex(int index,int data){}
        //查找是否包含关键字key是否在单链表当中
        public boolean contains(int key){}
        //删除第一次出现关键字为key的节点
        public void remove(int key){}
        //删除所有值为key的节点
        public void removeAllKey(int key){}
        //得到单链表的长度
        public int size(){}
        //打印链表
        public void display (){}
        //清空链表
        public void clear (){}
}
//无头双向链表的操作
public interface IOPeration {//头插法public void addFirst(int data);//尾插法public void addLast(int data);//任意位置插入,第一个数据节点为0号下标public boolean addIndex(int index,int data);//查找是否包含关键字key是否在单链表当中public boolean contains(int key);//删除第一次出现关键字为key的节点public void remove(int key);//删除所有值为key的节点public void removeAllKey(int key);//得到单链表的长度public int size();//打印链表public void display();//清空链表public void clear();
}
public class MySidesLinkList implements IOPeration{static class ListNode {int val;ListNode pre;ListNode next;public ListNode(int data){val=data;}}private int usedSize;private ListNode head;private  ListNode last;@Overridepublic void addFirst(int data) {ListNode node = new ListNode(data);if(head == null){head = node;last = node;}else {node.next = head;head.pre = node;head = node;}usedSize++;}@Overridepublic void addLast(int data) {ListNode node = new ListNode(data);if(last == null){head = node;last = node;}else {last.next = node;node.pre = last;last = node;}usedSize++;}@Overridepublic boolean addIndex(int index, int data) {if(index<0||index>usedSize){throw new IndexEception("下标异常:"+index);}if(index == 0){addFirst(data);return true;}if(index == usedSize){addLast(data);return  true;}ListNode cur=head;while(index>0){cur = cur.next;index--;}ListNode node = new ListNode(data);cur.pre.next = node;node.next=cur;node.pre = cur.pre;cur.pre = node;usedSize++;return true;}@Overridepublic boolean contains(int key) {ListNode cur = head;while(cur != null){if(cur.val == key){return  true;}else {cur=cur.next;}}return false;}@Overridepublic void remove(int key) {ListNode cur = head;while(cur != null){if(cur.val == key){if(cur == head){head = head.next;head.pre = null;cur.next = null;}else if(cur == last){last = last.pre;last.next = null;cur.pre = null;}else {cur.pre.next = cur.next;cur.next.pre = cur.pre;}usedSize--;return;}else {cur = cur.next;}}}@Overridepublic void removeAllKey(int key) {ListNode cur = head;while(cur != null){if(cur.val == key){ListNode curNext=cur.next;if(cur == head){head = head.next;head.pre = null;cur.next = null;}else if(cur == last){last = last.pre;last.next = null;cur.pre = null;}else {cur.pre.next = cur.next;cur.next.pre = cur.pre;}usedSize--;cur=curNext;}else {cur = cur.next;}}}@Overridepublic int size() {return usedSize;}@Overridepublic void display() {ListNode cur = head;while (cur != null){System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}@Overridepublic void clear() {ListNode cur = head;while (cur != null){ListNode curNext = cur.next;cur.pre = null;cur.next = null;cur=curNext;}head = null;last = null;}
}
//下标异常类
public class IndexEception extends RuntimeException{public IndexEception (String massage){super(massage);}
}

五、LinkedList的使用

        5.1 什么是LinkedList

        LinkedList的底层是双向链表结构,链表没有将元素存储在连续空间中,而是存储在单独的节 点中,通过引用将节点连接起来了,因此在任意位置插入或者删除元素时,不需要搬移元素,效率较高。

在集合框架中,LinkedList也实现了List接口:

        LinkedList实现了List接口,底层使用双向链表;没有实现RandomAccess接口,不支持随机访问;LinkedList在任意位置插入和删除效率较高,时间复杂度为O(1);适合任意位置插入的场景。

        5.2 LinkedList的使用

        1. LinkedList的构造

方法解释

public  LinkedList();

无参构造
public LinkedList(Collection<? extends E> c)使用其他集合容器中元素构造List
public static void main(String[] args) {LinkedList<Integer> list1 = new LinkedList<>();list1.addLast(1);list1.addLast(2);list1.addLast(3);//打印链表for (Integer x:list1) {System.out.print(x+" ");}System.out.println();/*使用list1中的元素构造list2* 其中list1的类型是与list2是同类型或是list2的子类类型* 存储元素的类型保持一致*/LinkedList<Integer> list2 = new LinkedList<>(list1);//打印链表for (Integer x:list2) {System.out.print(x+" ");}System.out.println();
}

        

        2. LinkedList其他常用方法

方法解释
boolean  add(E e)尾插 e
void add(int index, E element) 将 e 插入到 index 位置
boolean addAll(Collection<? extends E> c) 尾插 c 中的元素
E remove(int index)删除 index 位置元素
boolean remove(Object o) 删除第一个 o
E get(int index) 获取下标 index 位置元素
E set(int index, E element)将下标 index 位置 元素设置为 element
void clear()清空
boolean contains(Object o) 判断 o 是否在链表中
int indexOf(Object o)
返回第一个 o 所在下标
int lastIndexOf (Object o)
返回最后一个 o 的下标
List<E> subList(int fromIndex, int toIndex)
截取部分 list
public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(1);//尾插list.add(2);list.add(3);list.add(4);list.add(5);System.out.println(list.size());    //5System.out.println(list);   //[1, 2, 3, 4, 5]System.out.println("====");list.add(2,10);//在 index 位置插入元素list.addFirst(10);//头插list.addLast(10);//尾插System.out.println(list);   //[10, 1, 2, 10, 3, 4, 5, 10]System.out.println("====");list.remove();//默认删除第一个元素System.out.println(list);       //[1, 2, 10, 3, 4, 5, 10]list.removeFirst();//删除第一个元素System.out.println(list);       //[2, 10, 3, 4, 5, 10]list.removeLast();//删除最后一个元素System.out.println(list);       //[2, 10, 3, 4, 5]list.remove(1);//删除index位置的元素System.out.println(list);    //[2, 3, 4, 5]System.out.println("====");//contains(elem)判断elem元素是否存在System.out.println(list.contains(5));//true//从前向后找第一个elem出现的位置System.out.println(list.indexOf(3));//从后向前找第一个elem出现的位置System.out.println(list.lastIndexOf(4));System.out.println("====");//获取index位置的元素int elem = list.get(0);//set设置index位置的值为elemlist.set(0,100);System.out.println(list);      //[100, 3, 4, 5]System.out.println("====");//subList截取部分(左闭右开)并返回,返回值类型为List<E>List<Integer> list2 = list.subList(0,2);System.out.println(list2);  //[100, 3]
}

        3. LinkedList的遍历

public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);//遍历链表//foreach遍历for (int x:list) {System.out.print(x+" ");//1 2 3 4 5}System.out.println();//迭代器遍历ListIterator<Integer> it = list.listIterator();while (it.hasNext()){System.out.print(it.next()+" ");//1 2 3 4 5}System.out.println();//反向迭代器遍历ListIterator<Integer> reverseIt = list.listIterator(list.size());while (reverseIt.hasPrevious()){System.out.print(reverseIt.previous()+" ");//5 4 3 2 1 }
}

六、ArrayList和LinkedList的区别

不同点ArrayListLinkedList
存储空间上物理上一定连续逻辑上连续,但物理上不一定连续
随机访问支持O(1)不支持O(N)
头插需要移动元素,效率低O(N)只需修改引用的指向,O(1)
插入空间不够需要扩容没有容量的概念
应用场景元素高效存储、频繁访问任意位置插入和删除频繁

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

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

相关文章

现场直击|亚数TrustAsia精彩亮相IOTE深圳物联网展,CSA联盟展台等你来!

2023年9月20日&#xff0c;IOTE 2023第二十届深圳国际物联网展在深圳国际会展中心&#xff08;宝安&#xff09;顺利开幕。作为物联网领域年度最重要的行业盛会之一&#xff0c;本次展会汇聚全球来自工业、物流、基建、智慧城市、智慧零售等领域的600企业、10万行业人士&#x…

严重影响Windows使用体验的一些建议

1内存不够用&#xff1a;通过观察我发现我的电脑已经评价到了90%的内存使用率 没有内存什么程序运行起来都会卡的&#xff0c;所以一定要把不用的PROGRAME给他删除掉。特别是那些自动启动的软件&#xff0c;如果实在不行&#xff0c;就把杀毒也给他卸载掉。 不良具体表现&…

Java基础面试题精选:深入探讨哈希表、链表和接口等

目录 1.ArrayList和LinkedList有什么区别&#xff1f;&#x1f512; 2.ArrayList和Vector有什么区别&#xff1f;&#x1f512; 3.抽象类和普通类有什么区别&#xff1f;&#x1f512; 4.抽象类和接口有什么区别&#xff1f;&#x1f512; 5.HashMap和Hashtable有什么区别&…

Ubuntu为什么键盘会出现乱字符

今天上午起来只是要简单打一个命令&#xff0c;需要输入一个"双引号&#xff0c;但是总是显示&#xff0c;我一开始以为是中了病毒&#xff0c;把键盘给改了&#xff0c;后来发现虚惊一场&#xff1a;出现这个原因是因为ubuntu的键盘设置有问题。 我把键盘设置为英国英语…

【C++进阶(六)】STL大法--栈和队列深度剖析优先级队列适配器原理

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 栈和队列 1. 前言2. 栈和队列的接口函数熟悉3. …

欧伟杰博士:突破算力边界,YashanDB实现理论与工程双重突围

作者介绍 *全文4767个字&#xff0c;阅读时长约12分钟。 背景 随着数字化进程的加速&#xff0c;数据处理的规模和速度需求持续攀升。传统数据库系统在处理大规模数据时&#xff0c;存在单表记录数不超过500万条的限制&#xff0c;这已成为业务发展的瓶颈。为了解决此问题&…

No146.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

MySQL5.7高级函数:JSON_ARRAYAGG和JSON_OBJECT的使用

前置准备 DROP TABLE IF EXISTS t_user; CREATE TABLE t_user (id bigint(20) NOT NULL,name varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci …

杀掉进程但是fastapi程序还在运行

两个脚本&#xff0c;一个运行fastapi服务&#xff0c;一个重启服务&#xff1a; 启动服务先&#xff1a; 发现问题&#xff0c;杀掉 server.sh 后&#xff0c;依旧有&#xff1a; 不知道为什么会出现这个&#xff0c;直接kill吧&#xff1a; server.sh: #!/bin/bashparpath/…

led灯什么牌子的质量好?Led护眼台灯排行榜

现在我们很多家长对自己孩子的视力十分关心&#xff0c;生怕自己的孩子是近视、远视、弱视等等。对于父母而言&#xff0c;在孩子读书压力大课业重的关键时期&#xff0c;为孩子选择合适的桌椅&#xff0c;保护灯具从而保护孩子的眼睛是非常重要的事情!那么买给孩子读书做功课的…

Matlab绘图函数subplot、tiledlayout、plot和scatter

一、绘图函数subplot subplot(m,n,p)将当前图窗划分为 mn 网格&#xff0c;并在 p 指定的位置创建坐标区。MATLAB按行号对子图位置进行编号。第一个子图是第一行的第一列&#xff0c;第二个子图是第一行的第二列&#xff0c;依此类推。如果指定的位置已存在坐标区&#xff0c;…

基于Java的音乐网站管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&…

前端uniapp防止页面整体滑动页面顶部以上,设置固定想要固定区域宽高

解决&#xff1a;设置固定想要固定区域宽高 目录 未改前图未改样式改后图改后样式 未改前图 未改样式 .main {display: flex;flex-direction: row;// justify-content: space-between;width: 100vw;// 防止全部移动到上面位置&#xff01;&#xff01;&#xff01;&#xff01…

No147.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【在Ubuntu部署Docker项目】— PROJECT#1

一、说明 让我们深入了解 Docker。用docker构建web服务器。我们正在计划开发JavaScript API&#xff0c;建立MySQL数据库&#xff0c;并创建一个 PHP 网站使用 API 服务。Php Node.js Mysql — DockerSeries — Episode#1 二、系统架构概述 我们要构建的容器&#xff0c;是三…

Qt_C++读写NFC标签Ntag支持windows国产linux操作系统

本示例使用的发卡器&#xff1a;Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) ntag2标签存储结构说明 #include "mainwindow.h" #include "./ui_mainwindow.h" #include <QDebug> #include "QLibrary&…

队列的使用以及模拟实现(C++版本)

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;强烈推荐优质专栏: &#x1f354;&#x1f35f;&#x1f32f;C的世界(持续更新中) &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;…

【每日一题】2703. 返回传递的参数的长度

2703. 返回传递的参数的长度 - 力扣&#xff08;LeetCode&#xff09; 请你编写一个函数 argumentsLength&#xff0c;返回传递给该函数的参数数量。 示例 1&#xff1a; 输入&#xff1a;args [5] 输出&#xff1a;1 解释&#xff1a; argumentsLength(5); // 1只传递了一个值…

OpenHarmony应用核心技术理念与需求机遇简析

一、核心技术理念 图片来源&#xff1a;OpenHarmony官方网站 二、需求机遇简析 新的万物互联智能世界代表着新规则、新赛道、新切入点、新财富机会;各WEB网站、客户端( 苹果APP、安卓APK)、微信小程序等上的组织、企业、商户等;OpenHarmony既是一次机遇、同时又是一次大的挑战&…

【python+appium】自动化测试

pythonappium自动化测试系列就要告一段落了&#xff0c;本篇博客咱们做个小结。 首先想要说明一下&#xff0c;APP自动化测试可能很多公司不用&#xff0c;但也是大部分自动化测试工程师、高级测试工程师岗位招聘信息上要求的&#xff0c;所以为了更好的待遇&#xff0c;我们还…