Java Collection源码分析(JDk corretto 11)
文章目录
- Collection 系列源码分析 (JDK Amazon corretto 11)
- Collection接口
- Iterable接口
- 子接口 Queue
- Queue的子接口 Deque双端队列
- 子接口List
- ArrayList 实现类
- 序列化与反序列化(后续解决)
- 获取Calss对象的方式 主要有三种:
- Arrays工具类
- System类
- LinkedList实现类
- transient关键字
- Vector实现类
- Stack
- ListIterator接口
- 子接口Set
- HashSet
Collection 系列源码分析 (JDK Amazon corretto 11)
Collection接口
//public interface Iterator<E> {} 支持遍历
public interface Collection<E> extends Iterable<E> {//主要抽象方法int size();boolean isEmpty();boolean contains(Object o);Object[] toArray();<T> T[] toArray(T[] a);boolean add(E e);boolean remove(Object o);boolean containsAll(Collection<?> c);boolean addAll(Collection<? extends E> c);boolean removeAll(Collection<?> c);void clear();//...
}
Iterable接口
Iterable<E> 接口
public interface Iterable<T> {Iterator<T> iterator();default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}}default Spliterator<T> spliterator() {return Spliterators.spliteratorUnknownSize(iterator(), 0);}
}
Iterator<E> 接口
public interface Iterator<E> {boolean hasNext();E next();default void remove() {throw new UnsupportedOperationException("remove");}default void forEachRemaining(Consumer<? super E> action) {Objects.requireNonNull(action);while (hasNext())action.accept(next());}
}//遍历Collection的三种方式
1.传统for循环
2.java forEach写法
3.通过 继承Iterable接口的容器集合方法 iterator()方法返回迭代对象Iterator<E>,通过hasNext()和next()进行迭代
子接口 Queue
public interface Queue<E> extends Collection<E> {//就只有这6个抽象方法//增boolean add(E e);boolean offer(E e);//删E remove();E poll();//返回队首元素E element();E peek();
}
// poll() peek()队列为空时返回null, remove() element() 抛出异常
Queue的子接口 Deque双端队列
public interface Deque<E> extends Queue<E> {void addFirst(E e);void addLast(E e);boolean offerFirst(E e);boolean offerLast(E e);E removeFirst();E removeLast();E pollFirst();E pollLast();E getFirst();E getLast();E peekFirst();E peekLast();boolean removeFirstOccurrence(Object o);boolean removeLastOccurrence(Object o);void push(E e);E pop();boolean remove(Object o); // 等价boolean removeFirstOccurrence(Object o);
}
子接口List
public interface List<E> extends Collection<E> {// default jdk8出现 可以在接口中定义默认方法与静态方法default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);ListIterator<E> i = this.listIterator();for (Object e : a) {i.next();i.set((E) e);}}E get(int index);E set(int index, E element);void add(int index, E element);E remove(int index);int indexOf(Object o);int lastIndexOf(Object o);//List Iterators ListIterator<E>继承Iterator<E> 功能更加强大ListIterator<E> listIterator(); //完整的List迭代ListIterator<E> listIterator(int index);//返回特定位置的迭代器,可以向前和向后遍历//返回子ListList<E> subList(int fromIndex, int toIndex);//迷惑操作 重载了12个of方法 前11个参数个数从0到10,第12个使用了可变长参数 static <E> List<E> of() {return ImmutableCollections.emptyList();}static <E> List<E> of(E e1) {return new ImmutableCollections.List12<>(e1);}static <E> List<E> of(E e1, E e2) {return new ImmutableCollections.List12<>(e1, e2);}// 省略@SafeVarargs@SuppressWarnings("varargs")static <E> List<E> of(E... elements) {switch (elements.length) { // implicit null check of elementscase 0:return ImmutableCollections.emptyList();case 1:return new ImmutableCollections.List12<>(elements[0]);case 2:return new ImmutableCollections.List12<>(elements[0], elements[1]);default:return new ImmutableCollections.ListN<>(elements);}}
}
ArrayList 实现类
/*
扩容机制
默认情况下,新的容量会是原容量的1.5倍。 新容量=旧容量右移一位(相当于除于2)在加上旧容量ArrayList 的底层是用动态数组来实现的。我们初始化一个空的ArrayList 集合还没有添加元素时,其实它是个空数组,只有当我们添加第一个元素时,内部会调用扩容方法并返回最小容量10,也就是说ArrayList 初始化容量为10。 当前数组长度小于最小容量的长度时(前期容量是10,当添加第11个元素时就就扩容),便开始可以扩容了,ArrayList 扩容的真正计算是在一个grow()里面,新数组大小是旧数组的1.5倍,如果扩容后的新数组大小还是小于最小容量,那新数组的大小就是最小容量的大小,后面会调用一个Arrays.copyof方法,这个方法是真正实现扩容的步骤。*/public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{//6个属性//序列化idprivate static final long serialVersionUID = 8683452581122892189L;/*** Default initial capacity. 默认容量大小为10*/private static final int DEFAULT_CAPACITY = 10;/*** Shared empty array instance used for empty instances.在传入初始容量的构造函数中如果给的初始化容量为0使用这个数组*/private static final Object[] EMPTY_ELEMENTDATA = {};/*** Shared empty array instance used for default sized empty instances. We* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when* first element is added.*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};/*** The array buffer into which the elements of the ArrayList are stored.* The capacity of the ArrayList is the length of this array buffer. Any* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA* will be expanded to DEFAULT_CAPACITY when the first element is added.具体的存储通过数组进行*/transient Object[] elementData; // non-private to simplify nested class access/*** The size of the ArrayList (the number of elements it contains).* 元素的数量 通过属性来确定* @serial*/private int size;//构造方法//1.空的构造public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}//2.给定容量public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {// 用到了6个属性之一this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}//3.通过其他集合创建ArrayListpublic ArrayList(Collection<? extends E> c) { // Collection<? extends E> ?为泛型中的通配符Object[] a = c.toArray();if ((size = a.length) != 0) {//类名.class获取这个类的Class对象。只是三种方式之一if (c.getClass() == ArrayList.class) {elementData = a;} else {elementData = Arrays.copyOf(a, size, Object[].class);}} else {// replace with empty array.elementData = EMPTY_ELEMENTDATA;}}// Integer.MAX_VALUE=0x7fffffff 4字节 1位符号位为0,然后全是1private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//将容量缩减到数组元素数目大小public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}//扩容用的方法private Object[] grow(int minCapacity) {return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));}private Object[] grow() {return grow(size + 1);}private int newCapacity(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity <= 0) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)return Math.max(DEFAULT_CAPACITY, minCapacity);if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return minCapacity;}return (newCapacity - MAX_ARRAY_SIZE <= 0)? newCapacity: hugeCapacity(minCapacity);}private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = grow();elementData[s] = e;size = s + 1;}public boolean add(E e) {modCount++;add(e, elementData, size);return true;}//...其他后续再看吧
}
ArrayList实现了Serializable接口:
序列化与反序列化(后续解决)
获取Calss对象的方式 主要有三种:
- 通过Class.forName(“类的全名称”)获取
- 通过已经实例化的对象获取,getClass()方法获取
- 通过类名.class获取
Arrays工具类
public class Arrays {// <<为左移 1左移13位private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;//copyOf 最终还是调用System.arraycopy,见下文public static <T> T[] copyOf(T[] original, int newLength) {return (T[]) copyOf(original, newLength, original.getClass());}
}
System类
public final class System {@HotSpotIntrinsicCandidatepublic static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
}
LinkedList实现类
//实现List<E> 和 Deque<E> 所以LinkedList是双向链表
public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{transient int size = 0;/*** Pointer to first node.*/transient Node<E> first;/*** Pointer to last node.*/transient Node<E> last;//Node<E> 是一个内部类,双向链表结构主要由Node来维护private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}/*** Links e as first element.将新元素链接到表头*/private void linkFirst(E e) {final Node<E> f = first;final Node<E> newNode = new Node<>(null, e, f);first = newNode;if (f == null)last = newNode;elsef.prev = newNode;size++;modCount++;}/*** Links e as last element.将新元素链接到表尾*/void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}/*** Inserts element e before non-null Node succ.链接到某个非空节点前面*/void linkBefore(E e, Node<E> succ) {// assert succ != null;final Node<E> pred = succ.prev;final Node<E> newNode = new Node<>(pred, e, succ);succ.prev = newNode;if (pred == null)first = newNode;elsepred.next = newNode;size++;modCount++;}/*** Unlinks non-null first node f.*/private E unlinkFirst(Node<E> f) {// assert f == first && f != null;final E element = f.item;final Node<E> next = f.next;f.item = null;f.next = null; // help GCfirst = next;if (next == null)last = null;elsenext.prev = null;size--;modCount++;return element;}/*** Unlinks non-null last node l.*/private E unlinkLast(Node<E> l) {// assert l == last && l != null;final E element = l.item;final Node<E> prev = l.prev;l.item = null;l.prev = null; // help GClast = prev;if (prev == null)first = null;elseprev.next = null;size--;modCount++;return element;}/*** Unlinks non-null node x.*/E unlink(Node<E> x) {// assert x != null;final E element = x.item;final Node<E> next = x.next;final Node<E> prev = x.prev;if (prev == null) {first = next;} else {prev.next = next;x.prev = null;}if (next == null) {last = prev;} else {next.prev = prev;x.next = null;}x.item = null;size--;modCount++;return element;}/*后面这6个方法都是对上面方法的封装*/public E getFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return f.item;}public E getLast() {final Node<E> l = last;if (l == null)throw new NoSuchElementException();return l.item;}public E removeFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return unlinkFirst(f);}public E removeLast() {final Node<E> l = last;if (l == null)throw new NoSuchElementException();return unlinkLast(l);}public void addFirst(E e) {linkFirst(e);}public void addLast(E e) {linkLast(e);}
}
transient关键字
Java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话来说就是,用transient关键字标记的成员变量不参与序列化过程
Vector实现类
//底层和ArrayList差不多都是基于数组实现
public class Vector<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{protected Object[] elementData;protected int elementCount;protected int capacityIncrement;/** use serialVersionUID from JDK 1.0.2 for interoperability */private static final long serialVersionUID = -2767605614048989439L;//4个构造方法public Vector(int initialCapacity, int capacityIncrement) {super();if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);this.elementData = new Object[initialCapacity];this.capacityIncrement = capacityIncrement;}public Vector(int initialCapacity) {this(initialCapacity, 0);}public Vector() {this(10);}public Vector(Collection<? extends E> c) {Object[] a = c.toArray();elementCount = a.length;if (c.getClass() == ArrayList.class) {elementData = a;} else {elementData = Arrays.copyOf(a, elementCount, Object[].class);}}private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;public int indexOf(Object o) {return indexOf(o, 0);}public synchronized int indexOf(Object o, int index) {if (o == null) {for (int i = index ; i < elementCount ; i++)if (elementData[i]==null)return i;} else {for (int i = index ; i < elementCount ; i++)if (o.equals(elementData[i]))return i;}return -1;}public synchronized int lastIndexOf(Object o) {return lastIndexOf(o, elementCount-1);}public synchronized int lastIndexOf(Object o, int index) {if (index >= elementCount)throw new IndexOutOfBoundsException(index + " >= "+ elementCount);if (o == null) {for (int i = index; i >= 0; i--)if (elementData[i]==null)return i;} else {for (int i = index; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}public synchronized E elementAt(int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);}return elementData(index);}public synchronized E firstElement() {if (elementCount == 0) {throw new NoSuchElementException();}return elementData(0);}public synchronized E lastElement() {if (elementCount == 0) {throw new NoSuchElementException();}return elementData(elementCount - 1);}public synchronized void setElementAt(E obj, int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);}elementData[index] = obj;}public synchronized void removeElementAt(int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);}else if (index < 0) {throw new ArrayIndexOutOfBoundsException(index);}int j = elementCount - index - 1;if (j > 0) {System.arraycopy(elementData, index + 1, elementData, index, j);}modCount++;elementCount--;elementData[elementCount] = null; /* to let gc do its work */}public synchronized void insertElementAt(E obj, int index) {if (index > elementCount) {throw new ArrayIndexOutOfBoundsException(index+ " > " + elementCount);}modCount++;final int s = elementCount;Object[] elementData = this.elementData;if (s == elementData.length)elementData = grow();System.arraycopy(elementData, index,elementData, index + 1,s - index);elementData[index] = obj;elementCount = s + 1;}public synchronized void addElement(E obj) {modCount++;add(obj, elementData, elementCount);}public synchronized boolean removeElement(Object obj) {modCount++;int i = indexOf(obj);if (i >= 0) {removeElementAt(i);return true;}return false;}public synchronized void removeAllElements() {final Object[] es = elementData;for (int to = elementCount, i = elementCount = 0; i < to; i++)es[i] = null;modCount++;}public synchronized E set(int index, E element) {}public synchronized boolean add(E e) {}public boolean remove(Object o) {return removeElement(o);}public void add(int index, E element) {insertElementAt(element, index);}public synchronized E remove(int index) {}public void clear() {removeAllElements();}
}
Stack
public
class Stack<E> extends Vector<E> {public Stack() {}public E push(E item) {addElement(item);return item;}public synchronized E pop() {E obj;int len = size();obj = peek();removeElementAt(len - 1);return obj;}public synchronized E peek() {int len = size();if (len == 0)throw new EmptyStackException();return elementAt(len - 1);}public boolean empty() {return size() == 0;}public synchronized int search(Object o) {int i = lastIndexOf(o);if (i >= 0) {return size() - i;}return -1;}
}
ListIterator接口
// ListIterator<E> 功能更加强大
// 对于有n的元素的列表 共有n+1个游标位置public interface ListIterator<E> extends Iterator<E> {boolean hasNext();//判断游标后有没有元素E next();//返回游标后的元素,并后移boolean hasPrevious();//判断游标前有没有元素E previous();//返回游标前的元素,并前移int nextIndex();//返回游标后边元素的索引位置int previousIndex();//返回游标前面元素的位置,初始时为 -1/*删除迭代器最后一次操作的元素,注意事项和 set 一样。*/void remove();/*更新迭代器最后一次操作的元素为 E,也就是更新最后一次调用 next() 或者 previous() 返回的元素。 注意,当没有迭代,也就是没有调用 next() 或者 previous() 直接调用 set 时会报 java.lang.IllegalStateException 错;*/void set(E e);void add(E e);//在游标 前面 插入一个元素。注意,是前面!!
}
子接口Set
public interface Set<E> extends Collection<E> {//没看出有什么新的东西
}
HashSet
//底层使用HashMap实现
public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, java.io.Serializable
{static final long serialVersionUID = -5024744406713321676L;//HashMap实现private transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();
}
相关文章:

Java Collection源码分析(JDk corretto 11)
文章目录 Collection 系列源码分析 (JDK Amazon corretto 11)Collection接口Iterable接口 子接口 QueueQueue的子接口 Deque双端队列 子接口ListArrayList 实现类序列化与反序列化(后续解决)获取Calss对象的方式 主要有三种:Arrays工具类System类 LinkedList实现类t…...

13种权重的计算方法
权重计算方法有很多种,不同的方法有不同的特点和适用情况。AHP层次分析法和熵值法在权重计算中属于比较常用的方法。除此之外,还有一些与权重计算相关的方法,今天一文总结了13种与权重计算相关的方法,大家可以对比选择使用。 一、…...

Devops和Gitops区别
一. 什么是devops DevOps 是一种开发(Dev)和运维(Ops)之间协作和沟通的文化、流程和工具的实践方法。它强调迭代、快速交付和持续集成/持续交付,旨在加速软件交付的速度、质量和稳定性。 DevOps 的核心目标是通过自动…...

拿下多家车企定点!4D毫米波雷达「域」系统首发出道
从1R、2R、3R到整车360感知方案,毫米波雷达的前装市场需求量依然保持着快速增长的态势。 高工智能汽车研究院监测数据显示,2022年中国市场(不含进出口)前装标配搭载ADAS毫米波雷达(前向后向盲区)交付1795.…...

【FATE联邦学习】FATE联邦学习使用GPU、指定cuda下标
问题 FATE框架1.x支持GPU训练吗? 寻找 先看了官网,搜官网,发现还是有的。 打开第一个后,里面可以用training param指定各个client的训练GPU,但是好像都是在large language model的。 而在文档中搜寻到的gpu…...

英文数字表达
1基数词 0 nought;zero;O 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 eight 9 nine 10 ten 11 eleven 12 twelve 13 thirteen 14 fourteen 15 fifteen 16 sixteen 17 seventeen 18 eighteen 19 nineteen 20 twenty21 twenty-one 22 twenty-two 23 twenty-three 30 th…...

第11届蓝桥杯省赛真题剖析-2020年6月21日Scratch编程初中级组
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第125讲。 第11届蓝桥杯省赛,这是2020年6月21日举办的省赛Scratch考试真题,原定于2020年3月7日…...

部署LVS-NAT群集实验
一、 实验准备 负载调度器:内网关 ens33:192.168.109.12,外网关 ens37:12.0.0.1外网 Web节点服务器1:192.168.109.13 Web节点服务器2:192.168.109.14 NFS服务器:192.168.109.11 客户端…...

对待工作的九个级别
只要是职场人,每天都要开展本职工作,有的人在职场上混得风生水起、平步青云,有的人却总是在原地踏步踏,总有一种怀才不遇的感叹,为什么呢?其实,差距就在于对待工作的态度上。 今天我们一起与各位…...

第四章 存储结构与管理硬盘
第四章 存储结构与管理硬盘 一、一切从“/”开始 1、Linux系统中常见的目录名称以及相应内容 目录名称应放置文件的内容/boot开机所需文件——内核、开机菜单以及所需配置文件等/dev以文件形式存放任何设备与接口/etc配置文件/home用户主目录/bin存放单用户模式下还可以操作…...

【腾讯云-2】极简搭建边缘集群
1 创建 流程和https://blog.csdn.net/qq_47058489/article/details/130347795差不多,可参考 查看基本信息: 创建边缘集群的过程中会初始化master,说明包含一个托管master节点 但是没有其他节点 2 开启节点远程登录 通过 SSH 的方式远…...

在springboot中给mybatis加拦截器
拦截器的作用就是我们可以拦截某些方法的调用,在目标方法前后加上我们自己逻辑 Mybatis拦截器设计的一个初衷是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。 mybatis 自定义拦截器 1、实现Interceptor 接口,并添加拦截注解 I…...

[oeasy]python0139_尝试捕获异常_ try_except_traceback
尝试捕获异常 回忆上次内容 变量相加 整型数字变量可以相加字符串变量也可以拼接 但是 字符串 和 整型数字整型数字 和 字符串不能相加 怎么办? 转格式int(“1”)str(2) 可是 如果输入的苹果数量是 字符串"abc" int(“abc”)会发生什么?&…...

树的刷题,嗝
今天忘记带本子了,就没有学习java了,于是一心刷题,好烦遇到了两个奇怪的题目,我没跟题解写的,但是我是没想到奇怪的样例. no.1 617. 合并二叉树 难度简单1221收藏分享切换为英文接收动态反馈 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中…...

举个栗子~Tableau 技巧(253):让筛选器只显示全部以及需要的类别
用户反馈了一个需求:我的业务数据有很多类别,但其实经常查看的只有几个,Tableau 筛选器能不能设置一下,只显示全部和经常查看的那几个类别? 这个是可以实现的!如下示例,数据类别有:…...

服务器温度过高告警
今天巡检一套rac环境,发现节点二上有Error字样,逐行看完细节是服务器温度过高导致的,半夜又没啥业务的,查看硬件也没任何告警,哎,某品牌的品控确实越来越烂,log一下 Mar 21 02:53:21 hydb1 ker…...

反垃圾邮件产品测试评价方法示意图
声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品测试评价方法 测试环境 反垃圾邮件产品的典型测试环境如图1所示。 图1 反垃圾邮件产品典型测试环境示意图 测试设…...

基于vfw的局域网语音聊天室系统源码论文
语音视频聊天 UDP套接字的运用 在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,而UDP面向的是无连接的数据服务,其套接字的使用如图10所示。 图10 UDP套接字的使用 视频的捕获 利用VFW接口,视频捕获可以分为以下几个步骤: 建立视频采集窗口…...

GoogleTest : 测试框架(单元测试)
GoogleTest googletest: GoogleTest - Google Testing and Mocking Framework googletest 是一个由 Google 的测试技术团队开发的测试框架,它考虑到了谷歌的特定需求和限制。无论你使用的是 Linux、Windows 还是 Mac,只要你编写 C 代码,goo…...

商业银行财富管理“智能原生”能力呈阶梯化,AI助力商业模式趋向多元化发展
易观:金融业的财富管理从经营角度来看,是“客户与渠道管理场景运营产品研发”三位一体共同构建以客户为中心,数据驱动的业务经营体系。其中,“客户与渠道管理”是将客户利益作为核心目标,通过升级用户体验、客户全生命…...

2022年中国云市场份额:阿里云腾讯云下降
我是卢松松,点点上面的头像,欢迎关注我哦! 4月23日,IDC发布《中国公有云服务市场(2022下半年)跟踪》,占据前四的分别为阿里云(40.6%)、华为云(11.0%)、腾讯云(11.0%)、中国电信(8.7%)。咱们说重点,如下图所…...

Redis入门学习笔记【二】Redis缓存
目录 一、Redis缓存 二、Redis使用缓存遇到的问题 2.1 数据一致性 2.2缓存雪崩 2.3 缓存穿透 2.4 缓存击穿 一、Redis缓存 数据缓存是Redis最重要的一个场景,为缓存而生,在springboot中,一般有两种使用方式: 直接通过RedisT…...

go1.20环境安装以及beego框架配置
打开网址下载安装包选择对应安装包来下载安装(个人是windows,下载的1.20.3版本) 默认情况下会安装在C盘,但是我安装在了D盘目录 根据安装提示一步步next,直至完成 go get 在1.18版本之后就弃掉了,换成了install 配置自己的work…...

vue---组件逻辑复用方法:Mixin/HOC/Renderless组件
目录 1、Mixin 2、HOC 3、Renderless组件 下文通过表单校验来分别讲解Mixin/HOC/Renderless组件这三种方式。 1、Mixin 通过mixin将一个公用的validate函数同步到每一个组件中去 mixin使用详细介绍见:vue---mixin混入_maidu_xbd的博客-CSDN博客一个混入对象可…...

阳光万里,祝你上岸——免统考在职研究生
什么是在职研究生 在职研究生,是国家计划内,以在职人员身份,部分时间在职工作,部分时间在校学习的研究生教育的一种类型。在职攻读硕士方式有三种: 1.双证非全日制研究生:为普通高等教育研究生学历&#x…...

大孔树脂型号,A-722,ADS500,ADS600,ADS750,ADS800
一、产品介绍 基于吸附功能的聚苯乙烯特种树脂 Tulsimer ADS-600 是一款没有离子官能基的,由交联聚苯乙烯合成的功能强大的吸附型树脂。 Tulsimer ADS-600 主要应用于水溶液中吸附酚及其化合物,氯代烃等含氯物质,表面活性剂࿰…...

MATLAB在逐渐被Python淘汰吗?
Python和MATLAB都是常用的科学计算工具,但是它们有很多不同之处。 Python是一种通用编程语言,而MATLAB主要是用来做数值计算的。Python的基本数据类型和一般的编程语言一样普遍,但是离开了Numpy这个包,就不再有数组或者矩阵的数据…...

黑盒测试过程中【测试方法】讲解1-等价类,边界值,判定表
在黑盒测试过程中,有9种常用的方法:1.等价类划分 2.边界值分析 3.判定表法 4.正交实验法 5.流程图分析 6.因果图法 7.输入域覆盖法 8.输出域覆盖法 9.猜错法 我们一般用第1种和第2种方法最多。此处简单介绍一下这两种方法,详细介绍其…...

函数栈帧的创建和销毁
文章目录 main函数栈帧的创建为什么局部变量的值是随机值函数是怎么传参的?传参的顺序是什么?函数调用结束是怎么返回的 main函数栈帧的创建 先在栈帧里面为main函数开辟出一块空间,且这块空间由两个寄存器esp和ebp来进行维护,当在调用另一个函数时这两个寄存器就去维护为这…...

测试Ocr工具IronOCR(续:编写图片圈选程序)
上一篇文章学习了IronOCR的基本用法之后,计划做一个加载本地图片后,从图片中圈选某一位置的文字,然后调用IronOCR识别圈选区域文本的程序。本文实现从本地加载图片并完成圈选的功能。 主要的功能包括以下几点: 1ÿ…...