【数据结构与算法】1、学习动态数组数据结构(基本模拟实现 Java 的 ArrayList 实现增删改查)

news2024/11/25 2:50:48

目录

  • 一、什么是数据结构
    • (1) 概念
    • (2) 分类
  • 二、线性表
  • 三、数组(Array)
    • (1) 数组的底层结构
    • (2) 数组缺点
  • 四、动态数组(Dynamic Array)接口设计
  • 五、动态数组的设计和基本代码实现
    • (1) 成员变量
    • (2) 代码
      • ① get ()
      • ② indexOf ()
      • ③ clear ()
  • 六、add 方法和扩容
    • (1) add (int element)
    • (2) 打印动态数组中的元素
    • (3) add (int index, int element)
    • (4) 数组越界异常的封装
    • (5) MyJunit(接口测试)
    • (6) 扩容【 ensureCapacity() 】
  • 七、remove (int index)
  • 八、仅能存储 int 类型的动态数组 ArrayListInt 完整代码
  • 九、泛型(让动态数组中能存放各种类型的数据)
    • (1) clear () 【对象数组】
    • (2) 对象的比较不用 【==】
    • (3) remove (int index) 清空最后一个元素
    • (4) null 值处理
    • (5) ArrayList 完整代码

一、什么是数据结构

(1) 概念

🍃 数据结构是计算机存储组织数据的方式

(2) 分类

🎉 线性结构
在这里插入图片描述

  • 线性表(数组、链表、栈、队列、哈希表)

🎉 树形结构
在这里插入图片描述

  • 二叉树
  • AVL 树
  • 红黑树
  • B 树
  • Trie
  • 哈夫曼树
  • 并查集

🎉 图形结构
在这里插入图片描述

  • 邻接矩阵
  • 邻接表

二、线性表

🎁 线性表是具有 n 个相同类型元素的有限序列(n >= 0)

在这里插入图片描述

  • a1 是首节点(首元素), an 是尾结点(尾元素)
  • a1 是 a2 的前驱
  • a2 是 a1 的后继

常见的线性表有:
🎗️ 数组
🎗️ 链表
🎗️ 栈
🎗️ 队列
🎗️ 哈希表(散列表)

三、数组(Array)

(1) 数组的底层结构

🎁 数组是一种顺序存储的线性表,全部元素的内存地址连续

// 【new】向堆空间申请一段存储空间
int[] array = new int[]{11, 22, 33};

在这里插入图片描述

(2) 数组缺点

  • 👓数组有个致命的缺点:无法动态修改容量
  • 👓数组创建完毕后,能够存储的数据就固定了
  • 👓数组操纵元素的方式不够面向对象

🎐 自己实现动态数组,弥补数组的缺点

四、动态数组(Dynamic Array)接口设计

public interface List<E> {
    /**
     * 元素的数量
     */
    int size();

    /**
     * 是否为空
     */
    boolean isEmpty();

    /**
     * 是否包含某个元素
     */
    boolean contains(E element);

    /**
     * 添加元素到最后面
     */
    void add(E element);

    /**
     * 返回 index 位置对应的元素
     */
    E get(int index);

    /**
     * 设置 index 位置的元素
     */
    E set(int index, E element);

    /**
     * 往 index 位置添加元素
     */
    void add(int index, E element);

    /**
     * 删除 index 位置对应的元素
     */
    E remove(int index);

    /**
     * 返回元素的下标
     */
    int indexOf(E element);

    /**
     * 清空数组
     */
    void clear();
}

五、动态数组的设计和基本代码实现

(1) 成员变量

在这里插入图片描述

Java 中的成员变量会自动初始化,比如:
🎑 int 类型自动初始化为 0
🎑 对象类型自动初始化为 null

🎑 size 记录动态数组中元素的个数
🎑 elements 用于实际存储数据
🎑 动态数组的底层是数组

(2) 代码

在这里插入图片描述

/**
 * 只支持存储 int 类型数据的动态数组
 */
public class ArrayListInt {
    private int size;
    private int[] elements;

    public static final int DEFAULT_CAPACITY = 10;
    public static final int ELEMENT_NOT_FOUND = -1;

    public ArrayListInt() {
        this(DEFAULT_CAPACITY);
    }

    public ArrayListInt(int capacity) {
        capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;
        elements = new int[capacity];
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 获取 index 索引处的元素
     */
    public int get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("size: " + size + ", " + "index: " + index);
        }

        return elements[index];
    }

    /**
     * 设置 index 位置的元素
     *
     * @param index   下标
     * @param element 要设置的元素
     * @return 原来的元素ֵ
     */
    public int set(int index, int element) {
        // 获取 index 位置的元素
        int old = get(index);
        elements[index] = element;

        return old;
    }

    /**
     * 返回元素的索引
     */
    public int indexOf(int element) {
        // 如果数组为空, 直接找不到
        if (isEmpty()) return ELEMENT_NOT_FOUND;

        for (int i = 0; i < size; i++) {
            if (element == elements[i]) return i;
        }
        return ELEMENT_NOT_FOUND;
    }

    /**
     * 检查数组中是否包含 element 元素
     */
    public boolean contains(int element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    /**
     * 清除全部元素
     * 只要【size = 0】就无法获取到数组中的任何元素了
     */
    public void clear() {
        size = 0;
    }

}

① get ()

🎈 该方法的作用:获取 index 索引处的元素
🎈 数组可通过索引获取到元素
🎈 要做参数(index)校验

② indexOf ()

🎈 返回某个元素的索引
🎈 遍历每个下标的元素,拿数组中的每个元素和参数元素进行比较

③ clear ()

🎈 清除全部元素(清空数组)
🎈 在当前的代码中,只要【size = 0】就无法获取到数组中的任何元素了(就可以理解为清空了数组)

六、add 方法和扩容

🎈 add(int element):往数组的尾部添加元素 element
🎈 add(int index, int element):往数组的 index 索引位置添加元素 element

(1) add (int element)

在这里插入图片描述

🕰️ 每次往尾部添加元素的时候,是往数组的索引为 size 位置添加元素

public class ArrayListInt {

    /**
     * 往数组尾部添加元素
     */
    public void add(int element) {
        // TODO 扩容检测
        elements[size++] = element;
    }

}

(2) 打印动态数组中的元素

☆写法1:

public class ArrayListInt {

    /**
     * 遍历打印数组中的元素
     */
    public String printElements() {
        StringBuilder sb = new StringBuilder();
        sb.append("{size=").append(size).append(", [");

        for (int i = 0; i < size; i++) {
            sb.append(elements[i]);
            if (i != size - 1) {
                sb.append(", ");
            }
        }

        sb.append("]}");

        return sb.toString();
    }

}

🎨 遍历获取数组中的各个元素,然后进行拼接
🎨 Java 中大量字符串拼接用 StringBuilder 最好

☆写法2:

public class ArrayListInt {
 
    /**
     * 遍历打印数组中的元素
     */
    public String printElements() {
        StringBuilder sb = new StringBuilder();
        sb.append("{size=").append(size).append(", [");

        for (int i = 0; i < size; i++) {
            // 不是第 0 个元素就先拼接【, 】
            if (i != 0) {
                sb.append(", ");
            }

            sb.append(elements[i]);
        }

        sb.append("]}");

        return sb.toString();
    }

}

🎨 不是第 0 个元素就先拼接【, 】
🎨 相比写法1每次循环少了一次减法运算

在这里插入图片描述

(3) add (int index, int element)

在这里插入图片描述

☆ 往 index 位置插入元素 element
🎁 把 index 位置到 size - 1 位置【[index, size-1]】的元素往后挪动【空出 index 位置的元素】
🎁 把 element 元素赋值到 index 索引位置
🎁 从 索引为 size - 1 处开始挪动

public class ArrayListInt {

    /**
     * 在 index 位置插入元素 element
     */
    public void add(int index, int element) {
        // 当 index 等于 size 的时候, 是往数组的尾部添加元素
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("size: " + size + ", " + "index: " + index);
        }

        // TODO 扩容检测

        // 挪动元素(从最后一个元素开始挪动)
        for (int i = size - 1; i >= index; i--) {
            elements[i + 1] = elements[i];
        }

        // 把元素 element 赋值到 index 索引位置
        elements[index] = element;
        size++; // 数组元素加1
    }

}

(4) 数组越界异常的封装

public class ArrayListInt {

    public void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("index: " + index + " size: " + size);
    }

    public void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }

    public void rangeCheck4Add(int index) {
        if (index < 0 || index > size) {
            outOfBounds(index);
        }
    }

}

✏️ outOfBounds(int index):封装抛异常的方法
✏️ rangeCheck(int index):索引 index 不能小于 0 或 大于等于 size,否则都会数组越界
✏️ rangeCheck4Add(int index):添加元素的时候 index 是可以等于 size 的(此时是往数组的最后添加元素)

(5) MyJunit(接口测试)

🍃使用异常知识进行接口测试:当测试不通过的时候,会抛异常
🍃测试通过的时候,打印 Success!

public class MyJunit {

    public static void test(boolean boolean_) {
        try {
            if (!boolean_) throw new Exception("测试不通过");
            System.out.println("\nSuccess!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

(6) 扩容【 ensureCapacity() 】

在这里插入图片描述

📖① 申请全新的数组空间(容量适宜)
📖② 把就数据的数据复制到全新的数组中
📔 添加的时候才会考虑扩容操作

    /**
     * 扩容检测
     *
     * @param capacity 数组容量至少是 capacity
     */
    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        // 如果所需容量足够, 则不扩容
        if (oldCapacity >= capacity) return;

        // 申请全新的数组空间(新容量是旧容量的 1.5 倍)
        capacity = oldCapacity + (oldCapacity >> 1);
        int[] newElements = new int[capacity];

        // 把旧数组中的数据复制到新数组中
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[i];
        }

        // elements 指针指向新数组
        elements = newElements;

        System.out.println(oldCapacity + "扩容为" + capacity);
    }

七、remove (int index)

📔 作用:删除 index 索引处的元素,返回之前 index 索引处的元素

在这里插入图片描述

📙 思路:① 用后面的元素把要 删除的索引 index 位置的元素覆盖掉
📙 ② 数组 size 减 1
📙 ③ 如何覆盖❓ 遍历

public class ArrayListInt {

    /**
     * 删除 index 位置的元素
     *
     * @param index 下标
     * @return 原来的元素
     */
    public int remove(int index) {
        // 取出 index 索引处原来的元素
        int old = get(index);

        // 覆盖掉 index 索引处的元素
        for (int i = index; i < size; i++) {
            elements[i] = elements[i + 1];
        }

        // 最后一个元素不被访问到的关键代码
        size--;

        return old;
    }

}

八、仅能存储 int 类型的动态数组 ArrayListInt 完整代码

/**
 * 只支持存储 int 类型数据的动态数组
 */
@SuppressWarnings("all")
public class ArrayListInt {
    private int size;
    private int[] elements;

    public static final int DEFAULT_CAPACITY = 10;
    public static final int ELEMENT_NOT_FOUND = -1;

    public ArrayListInt() {
        this(DEFAULT_CAPACITY);
    }

    public ArrayListInt(int capacity) {
        capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;
        elements = new int[capacity];
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 获取 index 索引处的元素
     */
    public int get(int index) {
        rangeCheck(index);

        return elements[index];
    }

    /**
     * 设置 index 位置的元素
     *
     * @param index   下标
     * @param element 要设置的元素
     * @return 原来的元素ֵ
     */
    public int set(int index, int element) {
        // 获取 index 位置的元素
        int old = get(index);
        elements[index] = element;

        return old;
    }

    /**
     * 返回元素的索引
     */
    public int indexOf(int element) {  
        for (int i = 0; i < size; i++) {
            if (element == elements[i]) return i;
        }
        return ELEMENT_NOT_FOUND;
    }

    /**
     * 检查数组中是否包含 element 元素
     */
    public boolean contains(int element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    /**
     * 清除全部元素
     * 只要【size = 0】就无法获取到数组中的任何元素了
     */
    public void clear() {
        size = 0;
    }

    /**
     * 往数组尾部添加元素
     */
    public void add(int element) {
        add(size, element);
    }


    /**
     * 在 index 位置插入元素 element
     */
    public void add(int index, int element) {
        rangeCheck4Add(index);

        // 扩容检测, 保证容量至少是【size+1】
        ensureCapacity(size + 1);

        // 挪动元素(从最后一个元素开始挪动)
        for (int i = size - 1; i >= index; i--) {
            elements[i + 1] = elements[i];
        }

        // 把元素 element 赋值到 index 索引位置
        elements[index] = element;
        size++; // 数组元素加1
    }

    /**
     * 扩容检测
     *
     * @param capacity 数组容量至少是 capacity
     */
    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        // 如果所需容量足够, 则不扩容
        if (oldCapacity >= capacity) return;

        // 申请全新的数组空间(新容量是旧容量的 1.5 倍)
        capacity = oldCapacity + (oldCapacity >> 1);
        int[] newElements = new int[capacity];

        // 把旧数组中的数据复制到新数组中
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[i];
        }

        // elements 指针指向新数组
        elements = newElements;

        System.out.println(oldCapacity + "扩容为" + capacity);
    }

    /**
     * 删除 index 位置的元素
     *
     * @param index 下标
     * @return 原来的元素
     */
    public int remove(int index) {
        // 取出 index 索引处原来的元素
        int old = get(index);

        // 覆盖掉 index 索引处的元素
        for (int i = index; i < size - 1; i++) {
            elements[i] = elements[i + 1];
        }

        // 最后一个元素不被访问到的关键代码
        size--;

        return old;
    }

    public void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("index: " + index + " size: " + size);
    }

    public void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }

    public void rangeCheck4Add(int index) {
        if (index < 0 || index > size) {
            outOfBounds(index);
        }
    }

    /**
     * 遍历打印数组中的元素
     */
    public String printElements() {
        StringBuilder sb = new StringBuilder();
        sb.append("{size=").append(size).append(", [");

        for (int i = 0; i < size; i++) {
            // 不是第 0 个元素就拼接【, 】
            if (i != 0) {
                sb.append(", ");
            }

            sb.append(elements[i]);
        }

        sb.append("]}");

        return sb.toString();
    }

}

九、泛型(让动态数组中能存放各种类型的数据)

🎁 可使用 Java 中的泛型让动态数据更加通用(在动态数组中能存放任何数据类型的数据)

在这里插入图片描述

(1) clear () 【对象数组】

在这里插入图片描述

🧣 当动态数组中可以存储任何类型的时候,对于 clear() 方法,仅仅把 size 设置为 0 是不够的
🧣 把 size 设置为 0 后,虽然使用动态数组的人无法获取到任何数据,但这些数据仍然存活在内存中【这些数据依然存在,只是你无法使用它而已】
🧣 最佳的方式是:把 size 设置为 0,并把这些内存都回收掉(置为 null)

    /**
     * 清除全部元素
     */
    public void clear() {
        // 销毁堆空间的对象数据
        for (int i = 0; i < elements.length; i++) {
            elements[i] = null;
        }
        
        size = 0;
    }

(2) 对象的比较不用 【==】

🎁 两个 对象用 == 运算符进行比较的时候,比较的是两个对象的内存地址
🎁 若不想比较两个对象的内存地址,需要用 equals() 方法

    public int indexOf(E element) {
        if (element == null) return ELEMENT_NOT_FOUND;

        // 如果数组为空, 直接找不到
        if (isEmpty()) return ELEMENT_NOT_FOUND;

        for (int i = 0; i < size; i++) {
            if (element.equals(elements[i])) return i;
        }
        return ELEMENT_NOT_FOUND;
    }

(3) remove (int index) 清空最后一个元素

在这里插入图片描述

    /**
     * 删除 index 位置的元素
     *
     * @param index 下标
     * @return 原来的元素
     */
    public E remove(int index) {
        // 取出 index 索引处原来的元素
        E old = get(index);

        // 覆盖掉 index 索引处的元素
        for (int i = index + 1; i < size; i++) {
            elements[i - 1] = elements[i];
        }

        // 把最后一个元素置空
        elements[--size] = null;

        return old;
    }

(4) null 值处理

动态数组中应该要能够存放 null 值

    /**
     * 返回元素的索引
     */
    public int indexOf(E element) {
        if (null == element) {
            for (int i = 0; i < size; i++) {
                if (elements[i] == null) return i;
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (element.equals(elements[i])) return i;
            }
        }

        return ELEMENT_NOT_FOUND;
    }

(5) ArrayList 完整代码

/**
 * 泛型让动态数组中能存放任何数据类型的数据
 */
@SuppressWarnings("all")
public class ArrayList<E> {
    private int size;
    private E[] elements;

    public static final int DEFAULT_CAPACITY = 10;
    public static final int ELEMENT_NOT_FOUND = -1;

    public ArrayList() {
        this(DEFAULT_CAPACITY);
    }

    public ArrayList(int capacity) {
        capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;

        elements = (E[]) new Object[capacity];
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 获取 index 索引处的元素
     */
    public E get(int index) {
        rangeCheck(index);

        return elements[index];
    }

    /**
     * 设置 index 位置的元素
     *
     * @param index   下标
     * @param element 要设置的元素
     * @return 原来的元素ֵ
     */
    public E set(int index, E element) {
        // 获取 index 位置的元素
        E old = get(index);
        elements[index] = element;

        return old;
    }

    /**
     * 返回元素的索引
     */
    public int indexOf(E element) {
        if (null == element) {
            for (int i = 0; i < size; i++) {
                if (elements[i] == null) return i;
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (element.equals(elements[i])) return i;
            }
        }

        return ELEMENT_NOT_FOUND;
    }

    /**
     * 检查数组中是否包含 element 元素
     */
    public boolean contains(E element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    /**
     * 清除全部元素
     */
    public void clear() {
        // 销毁堆空间的对象数据
        for (int i = 0; i < elements.length; i++) {
            elements[i] = null;
        }

        size = 0;
    }

    /**
     * 往数组尾部添加元素
     */
    public void add(E element) {
        add(size, element);
    }

    /**
     * 在 index 位置插入元素 element
     */
    public void add(int index, E element) {
        rangeCheck4Add(index);

        // 扩容检测, 保证容量至少是【size + 1】
        ensureCapacity(size + 1);

        // 挪动元素(从最后一个元素开始挪动)
        for (int i = size - 1; i >= index; i--) {
            elements[i + 1] = elements[i];
        }

        // 把元素 element 赋值到 index 索引位置
        elements[index] = element;
        size++; // 数组元素加1
    }


    /**
     * 扩容检测
     *
     * @param capacity 数组容量至少是 capacity
     */
    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        // 如果所需容量足够, 则不扩容
        if (oldCapacity >= capacity) return;

        // 申请全新的数组空间(新容量是旧容量的 1.5 倍)
        capacity = oldCapacity + (oldCapacity >> 1);
        E[] newElements = (E[]) new Object[capacity];

        // 把旧数组中的数据复制到新数组中
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[i];
        }

        // elements 指针指向新数组
        elements = newElements;

        System.out.println(oldCapacity + "扩容为" + capacity);
    }

    /**
     * 删除 index 位置的元素
     *
     * @param index 下标
     * @return 原来的元素
     */
    public E remove(int index) {
        // 取出 index 索引处原来的元素
        E old = get(index);

        // 覆盖掉 index 索引处的元素
        for (int i = index + 1; i < size; i++) {
            elements[i - 1] = elements[i];
        }

        // 把最后一个元素置空
        elements[--size] = null;

        return old;
    }

    public void outOfBounds(int index) {
        throw new IndexOutOfBoundsException("index: " + index + " size: " + size);
    }

    public void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }

    public void rangeCheck4Add(int index) {
        if (index < 0 || index > size) {
            outOfBounds(index);
        }
    }

    /**
     * 遍历打印数组中的元素
     */
    public String printElements() {
        StringBuilder sb = new StringBuilder();
        sb.append("{size=").append(size).append(", [");

        for (int i = 0; i < size; i++) {
            // 不是第 0 个元素就拼接【, 】
            if (i != 0) {
                sb.append(", ");
            }

            sb.append(elements[i]);
        }

        sb.append("]}");

        return sb.toString();
    }

}

JDK 中内置了动态数组类:java.util.ArrayList

如有错误和疑问,欢迎和我交流

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

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

相关文章

嵌入式实时操作系统的设计与开发New(二)

轮询系统 轮询系统也称为简单循环控制系统&#xff0c;是一种最简单嵌入式实时软件体系结构模型。 在单个微处理情况下&#xff0c;系统由多个函数完成&#xff0c;每个函数负责该系统的一部分功能。 这些函数被循环调用执行&#xff0c;即它们按照一个执行顺序构成一个单向的…

nand flash 介绍

flash名称由来 Flash的擦除操作是以block块为单位的&#xff0c;与此相对应的是其他很多存储设备&#xff0c;是以bit位为最小读取/写入的单位&#xff0c;Flash是一次性地擦除整个块&#xff1a;在发送一个擦除命令后&#xff0c;一次性地将一个block&#xff0c;常见的块的大…

如何在VMware Workstation虚拟机上快速部署AntDB社区版

AntDB社区版采用了一键部署架构&#xff0c;步骤简单&#xff0c;耗时短&#xff0c;部署快&#xff0c;为大家的快速体验提供了极大便利。 这里将通过环境准备、下载AntDB社区版、部署AntDB社区版三个部分跟大家一起体验如何快速完成AntDB社区版在VMware Workstation虚拟机上…

(十二)反射与特性 -反射与预定义特性(1)

一、反射 1、什么是反射 了解反射之前&#xff0c;要先了解一下元数据。元数据指保存在程序集中的一些有关程序及其类型的数据&#xff0c;包括类、结构、委托、接口和枚举等&#xff09;的成员和成员的信息。 程序在运行时&#xff0c;可以查看程序集以及其本身的元数据&…

babycrypt 自己出的第一道逆向题目 WP

Patch掉反调试 先进行了Base32解密&#xff0c;之后是RC4加密 Base32编码表是RC4加密后存储的&#xff0c;动调得到 动调可以看出&#xff0c;经过base32编码密文会在首部添加M7WGC76B 之后密文进行RC4加密 动调得到第二处RC4加密的密钥 解密过程 def rc4(data, key): S l…

面试题:分布式事务有哪些方案及运用场景

一、分布式事务概述 分布式事务是指涉及多个不同资源或数据库的事务处理&#xff0c;这些资源或数据库分布在不同的网络节点上&#xff0c;通过协调器将多个事务组合成一个分布式事务。分布式事务的目的是确保多个事务操作要么全部成功&#xff0c;要么全部失败&#xff0c;保…

白嫖Tesla T4 GPU玩转Stable Diffusion Webui

想要玩stable diffusion&#xff0c;算力不可少&#xff0c;白嫖google colab Tesla T4 GPU 玩转Stable Diffusion Webui 1、google colab上安装stable diffusion webui https://colab.research.google.com/drive/1qL5eD2VESnop8mrbFcHzMmfzqzmRMMF4?uspsharing 在google col…

提高代码调试能力——IDEA debug技巧

一、文章概述 idea debug调试的一些方法 二、按键简单介绍 如上如是debug时的按钮&#xff0c;标上序号便于说明。 1、重新开始调试 图中是已开是debug模式&#xff0c;不管你此时调试到哪个地方&#xff0c;此时点击1就可以重新开始运行程序调试&#xff1a;等价于&#x…

vue配置反向代理的使用

反向代理&#xff1a;常用于生产环境&#xff0c;项目部署时服务器的配置。 反向代理&#xff1a;同样创建一个代理服务器&#xff0c;用于接收客户端发送的请求&#xff0c;再将请求转发给内部网络上的服务器&#xff0c;从服务器中获取数据并返回给客户端。也就是 代理服务端…

一文了解:计算机视觉领域下自监督学习方法原理

计算机视觉领域下自监督学习方法原理 导语为什么在计算机视觉领域中进行自我监督学习&#xff1f; 自监督学习方法Generative methodsBEiT 架构 Predictive methodsContrastive methodsBootstraping methodsSimply Extra Regularization methods 导语 自监督学习是一种机器学习…

【NLP】从双曲面到双曲几何庞加莱盘

一、说明 在研究双曲空间的时候,不能不遇到双曲面的问题。双曲几何在什么样的双曲面建立?其它几何元素在双曲面的表现。庞加莱盘不是双曲几何的一部分,而是一个投影平面,自然语言处理中,图网络不是卷积神经网络。本篇从双曲方程开始,展开双曲空间的探讨。 二、双曲面总论…

数据库系统概述——第四章 数据库安全性(知识点复习+练习题)

&#x1f31f;博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;离散数学考前复习&#xff08;知识点题&#xff09; &#x1f353;专栏&#xff1a;概率论期末速成&#xff08;一套卷&#xff09; &#x1f433;专栏&#xff1a;数字电路考前复习 &#x1f99a;专栏&am…

【汤4操作系统】深入掌握操作系统-输入输出系统篇

第五章 输入输出系统 I/O系统简介 设备管理对象&#xff1a;主要是IO设备 设备管理的基本任务&#xff1a;完成用户提出的IO请求&#xff0c;提高IO速率以及改善IO设备的利用率 主要功能有&#xff1a; 隐藏物理设备细节。IO系统对IO设备进行适当的抽象&#xff0c;以隐藏掉物…

selenium 要点击的元素被其他元素遮挡 or 无法找到非可视范围内的元素

selenium 无法找到非可视范围内的元素 org.openqa.selenium.StaleElementReferenceException: The element reference of is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed se…

Java根据word模板生成word文档并转成PDF文件

1. 处理word模板 1.1 定义word模版 1.2 定义完我们的模板之后&#xff0c;我们要将文档保存为xml的格式 定义完我们的模板之后&#xff0c;我们要将文档保存为xml的格式 1.3 xml格式化 生成的xml格式看起来比较乱,没有层次感, 所以需要格式化一下 格式化 1.4 修改xml 基础信息…

TestNG官方文档中文版

TestNG官方文档中文版(1) -介绍 T e s t NG 的 官 方 文 档 请 见 :http://testng.org/doc/documentation-main.html 1 介绍 T e s t N G 是 一 个 设 计 用 来 简 化 广 泛 的 测 试 需 求 的 测 试 框 架 &#xff0c; 从 单 元 测 试 (隔 离测试- 个类)到集成测试(测试由有…

Visio2013绘制任意曲线

曲线上蓝色的‘弯曲点‘&#xff0c;随着拉伸曲线&#xff0c;它自己会增减&#xff0c;这里要和’连接点‘区分开&#xff0c;连接点是用来连接别的图形的。

git通过ssh代理连接github(gitee不支持),并更改端口

文章目录 需求github使用ssh代理的方案gitee无法实现ssh代理gitee的暂时解决方案 参考 需求 git clone github/gitee远程仓库&#xff0c;使用ssh协议&#xff0c;并且走本地的http代理(端口3128)。 运行环境是Ubuntu 20.04。 github使用ssh代理的方案 修改~/.ssh/config文…

解决containerd+k8s集群搭建镜像拉取不到的问题

解决containerdk8s集群搭建镜像拉取不到的问题 下载离线镜像导入镜像初始化集群安装calico插件安装MetalLB部署一个nginx应用并暴露端口 之前我写了一篇containerdk8s搭建集群的文章&#xff0c;文章地址&#xff1a; https://blog.csdn.net/m0_51510236/article/details/1308…

系统架构设计师-系统工程与信息系统基础(3)

一、企业信息化与电子商务 1、企业资源计划&#xff08;ERP&#xff09; ERP是由MRP&#xff08;物料需求计划&#xff09;、MRPll&#xff08;制造资源计划&#xff09;一步步演化而来。 MARPll&#xff1a;核心是物流&#xff0c;主线是计划。 ERP&#xff1a;打通了供应链&a…