java阻塞队列小结

【README】

1,本文介绍了java的7个阻塞队列;

2,阻塞队列的作用

  • 做缓冲作用,如缓冲kafka消息,而不是直接发送给kafka,减少kafka集群的压力;

【1】阻塞队列 BlockingQueue 概述

1,队列是一种数据结构,先进先出;

2,阻塞队列的意思是:

  • 当阻塞队列为空时,线程1从队列取出元素会阻塞;直到线程2向队列添加了新值;
  • 但阻塞队列满时,线程1向队列添加元素会阻塞;直到线程2从队列取走了值(头部元素)

3,阻塞队列封装了 线程阻塞,线程唤醒的底层方法,不需要程序员编写这些代码,减少了开发量和代码简洁;


【2】阻塞队列介绍

【2.1】ArrayBlockingQueue 数组阻塞队列

0)类描述:

底层使用可重入锁 ReentrantLock 实现,每个操作前都会加锁,操作完成后解锁;所以仅允许一个线程串行操作阻塞队列中的任意一个方法;(线程1操作a方法,线程1退出前,线程2不能操作b方法,注意是b方法)

基于数组的有界阻塞队列

在创建该队列时,给定队列容量 capacity,一旦创建,capacity无法修改;

此类支持 排序等待生产者和消费者线程的可选公平策略。默认情况下,不保证此顺序。但是,在公平性设置为 true 的情况下构造的队列以 FIFO 顺序授予线程访问权限公平通常会降低吞吐量,但会减少可变性并避免饥饿

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。

1)类定义

public class ArrayBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {

2)构造器

public ArrayBlockingQueue(int capacity) {this(capacity, false);
}
// 带有公平性 
public ArrayBlockingQueue(int capacity, boolean fair) {if (capacity <= 0)throw new IllegalArgumentException();
// 基于数组实现的阻塞队列 this.items = new Object[capacity];lock = new ReentrantLock(fair);notEmpty = lock.newCondition();notFull =  lock.newCondition();
}
// 给定初始队列元素 
public ArrayBlockingQueue(int capacity, boolean fair,Collection<? extends E> c) {this(capacity, fair);final ReentrantLock lock = this.lock;lock.lock(); // Lock only for visibility, not mutual exclusiontry {int i = 0;try {for (E e : c) {checkNotNull(e);items[i++] = e;}} catch (ArrayIndexOutOfBoundsException ex) {throw new IllegalArgumentException();}count = i;putIndex = (i == capacity) ? 0 : i;} finally {lock.unlock();}
}

3)元素操作方法

  1. boolean add(E e):(底层调用offer(E e))插入元素e到队列;只要没有超过capacity,立即插入成功并返回true;若队列满,则抛出异常IllegalStateException ; 若元素e为空,报空指针;【不阻塞】
  2. boolean offer(E e):与add方法不同的是,若队列满,返回false,而不是抛出异常(add方法会抛出异常);【不阻塞】
  3. void put(E e) throws InterruptedException:插入元素e到队列;若队列满,则线程等待直到有可用空间;【阻塞】;线程等待可能抛中断异常;插入可能抛空指针异常,若e为null;
  4. boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException:若队列满,则线程等待给定时间直到有可用空间;【限时阻塞】
  5. E poll():从队列取出元素;若队列空,返回null;【不阻塞】
  6. E take() throws InterruptedException:从队列取出元素;若队列空,则线程阻塞;阻塞可能抛出中断异常;【阻塞】
  7. E poll(long timeout, TimeUnit unit) throws InterruptedException:从队列获取元素,若队列为空,则【限时阻塞】;
  8. E peek():从队列获取元素,但不出队,不阻塞,队列空获取null;

4)其他方法

  1. int size(): 获取队列元素个数;
  2. int remainingCapacity():还可以存储的元素个数;但它大于0,并不表示插入一定成功,因为有并发问题;

【2.2】LinkedBlockingQueue 链表阻塞队列

0)类描述

基于链表的可选有界队列, 可选的意思是,给定容量则有界,否则无界

基于链接节点的可选有界阻塞队列(基于链表的可选有界队列)。 此队列对元素 FIFO(先进先出)进行排序。 队列的头部是在队列中停留时间最长的那个元素。 队列的尾部是在队列中停留时间最短的那个元素。 新元素插入队列尾部,队列检索操作获取队列头部元素。

链接队列通常比基于数组的队列具有更高的吞吐量,但在大多数并发应用程序中的可预测性较差。

可选的容量绑定构造函数参数是一种 防止队列过度扩展的方法。 如果未指定,容量等于 Integer.MAX_VALUE。 链接节点在每次插入时动态创建,除非这会使队列超过容量。

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。
此类是 Java 集合框架的成员。

1)类定义

public class LinkedBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {

2)构造器

2.1)链表节点-静态内部类

static class Node<E> {E item;/*** One of:* - the real successor Node* - this Node, meaning the successor is head.next* - null, meaning there is no successor (this is the last node)*/Node<E> next;Node(E x) { item = x; }
}
// 两把锁
/** 元素获取锁 */
private final ReentrantLock takeLock = new ReentrantLock();
/** 元素非空条件 */
private final Condition notEmpty = takeLock.newCondition();
/** 元素插入锁 */
private final ReentrantLock putLock = new ReentrantLock();
/** 元素非满条件 */
private final Condition notFull = putLock.newCondition();

2.2)构造器

// 构造器 
public LinkedBlockingQueue() {this(Integer.MAX_VALUE);
}// 给定队列大小 
public LinkedBlockingQueue(int capacity) {if (capacity <= 0) throw new IllegalArgumentException();this.capacity = capacity;last = head = new Node<E>(null); // 头节点 
}// 创建大小为 Integer.Max_value 的,用给定容器初始化元素的 队列
public LinkedBlockingQueue(Collection<? extends E> c) {this(Integer.MAX_VALUE);final ReentrantLock putLock = this.putLock;putLock.lock(); // Never contended, but necessary for visibilitytry {int n = 0;for (E e : c) {if (e == null)throw new NullPointerException();if (n == capacity)throw new IllegalStateException("Queue full");enqueue(new Node<E>(e));++n;}count.set(n);} finally {putLock.unlock();}
}

3)元素操作方法

同 ArrayBlockingQueue的元素操作方法,包括

  1. void put(E e) throws InterruptedException;
  2. boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException
  3. boolean offer(E e)
  4. E take() throws InterruptedException
  5. E poll(long timeout, TimeUnit unit) throws InterruptedException
  6. E poll()
  7. E peek()

【2.3】PriorityBlockingQueue 优先级阻塞队列 (底层使用数组)

0)类描述

它是一个基于数组的无界阻塞队列,自动扩容保证无界插入元素用不阻塞,获取元素阻塞(干货)

一个无界阻塞队列,它使用与 PriorityQueue 类相同的排序规则并提供阻塞检索操作。

虽然这个队列在逻辑上是无界的,但由于资源耗尽(导致 OutOfMemoryError),尝试添加可能会失败。此类不允许空元素。依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做会导致 ClassCastException)

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。方法 iterator() 中提供的 Iterator 不能保证以任何特定顺序遍历 PriorityBlockingQueue 的元素。如果您需要有序遍历,请考虑使用 Arrays.sort(pq.toArray())。此外,drainTo 方法可用于按优先级顺序删除部分或全部元素,并将它们放置在另一个集合中。

对此类的操作不保证具有相同优先级的元素的顺序。如果您需要强制排序,您可以定义自定义类或比较器,它们使用辅助键来打破主要优先级值之间的联系。例如,这是一个将先进先出打破平局应用于可比元素的类。要使用它,您需要插入一个新的 FIFOEntry(anEntry) 而不是普通的条目对象。

1)类定义

public class PriorityBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {

2)构造器

// 创建优先级阻塞度列,默认大小 Integer.max_value, 比较器为null,默认为字典序
public PriorityBlockingQueue() {this(DEFAULT_INITIAL_CAPACITY, null);
} // private static final int DEFAULT_INITIAL_CAPACITY = 11; 默认大小11 // 创建优先级阻塞度列,给定大小 , 比较器为null,默认为字典序
public PriorityBlockingQueue(int initialCapacity) {this(initialCapacity, null);
}// 创建优先级阻塞度列,给定大小 ,和比较器
public PriorityBlockingQueue(int initialCapacity,Comparator<? super E> comparator) {if (initialCapacity < 1)throw new IllegalArgumentException();this.lock = new ReentrantLock();this.notEmpty = lock.newCondition();this.comparator = comparator;this.queue = new Object[initialCapacity];
}
// 创建优先级阻塞队列,包含给定的集合c;若集合是 SortedSet 或 PriorityQueue,则创建后的队列的元素顺序不变,否则采用字典序
public PriorityBlockingQueue(Collection<? extends E> c) {this.lock = new ReentrantLock();this.notEmpty = lock.newCondition();boolean heapify = true; // true if not known to be in heap orderboolean screen = true;  // true if must screen for nullsif (c instanceof SortedSet<?>) {SortedSet<? extends E> ss = (SortedSet<? extends E>) c;this.comparator = (Comparator<? super E>) ss.comparator();heapify = false;}else if (c instanceof PriorityBlockingQueue<?>) {PriorityBlockingQueue<? extends E> pq =(PriorityBlockingQueue<? extends E>) c;this.comparator = (Comparator<? super E>) pq.comparator();screen = false;if (pq.getClass() == PriorityBlockingQueue.class) // exact matchheapify = false;}Object[] a = c.toArray();int n = a.length;// If c.toArray incorrectly doesn't return Object[], copy it.if (a.getClass() != Object[].class)a = Arrays.copyOf(a, n, Object[].class);if (screen && (n == 1 || this.comparator != null)) {for (int i = 0; i < n; ++i)if (a[i] == null)throw new NullPointerException();}this.queue = a;this.size = n;if (heapify)heapify();
}

3)元素操作方法

  1. boolean add(E e) {return offer(e);}:插入元素,调用 offer(e) 方法; 同 offer(e)
  2. boolean offer(E e) : 插入元素到优先级队列。因为队列是无界的,所以只会返回true,不会返回false;且插入元素到队列永远不会阻塞(是插入不会阻塞,而不是获取元素)
    1. 若给定元素不能与优先级队列中的元素进行比较,抛出ClassCastException 异常;
    2. 给定元素为null,报空指针异常;
  3. void put(E e) {offer(e);} : 同offer(e) 方法;
  4. E take() throws InterruptedException:获取元素;若队列为空,阻塞等待;等待中可能抛出中断异常;
  5. E poll(long timeout, TimeUnit unit) throws InterruptedException:获取元素;若队列为空,阻塞等待;最多等待timeout时间,等待中可能抛出中断异常;
  6. E peek():仅获取队列首部元素,但首部元素不出队;

【2.4】DelayQueue - 延迟队列

0)类描述

Delayed元素的无界阻塞队列,每个元素只能在其延迟到期时被取用;

其底层使用了优先级队列来实现;

Delayed 元素的无界阻塞队列,其中每个元素只能在其延迟到期时被取用

队列的头部是过去延迟过期最远的那个 Delayed 元素。 如果没有延迟到期,则没有 头部且 poll() 方法返回 null。

当元素的 getDelay(TimeUnit.NANOOSECONDS) 方法返回值小于或等于零的值时,就会发生过期。

尽管无法使用 take 或 poll()方法 取走(删除)未过期的元素,但它们仍被视为普通元素。 例如,size 方法返回过期和未过期元素的总个数。 此队列不允许空元素。

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。

方法 iterator() 中提供的 Iterator 不保证以任何特定顺序遍历 DelayQueue 的元素。

1)类定义

public class DelayQueue<E extends Delayed> extends AbstractQueue<E>implements BlockingQueue<E> {// 延迟队列底层使用 优先级队列 private final PriorityQueue<E> q = new PriorityQueue<E>();....... 
}
  • 1.1)Delayed 接口定义 

一个混合风格的接口,用于标记在给定延迟后应采取行动的对象
此接口的实现必须定义一个 compareTo 方法,以提供与其 getDelay 方法一致的排序。

// 延迟接口 
public interface Delayed extends Comparable<Delayed> {long getDelay(TimeUnit unit);
}// Comparable 接口
public interface Comparable<T> {public int compareTo(T o); // compareTo方法 
}
  • getDelay() 方法描述:

返回关联对象剩余的延迟时间;单位为unit;

2)构造器

// 创建一个空的延迟队列 
public DelayQueue() {}// 创建延迟队列,初始包含给定集合c 
public DelayQueue(Collection<? extends E> c) {this.addAll(c);}

3)元素操作方法

  1. boolean add(E e) { return offer(e);}: 插入元素e到延迟队列,同 offer(E e ) 方法;
  2. boolean offer(E e): 插入元素e到延迟队列;元素e为null报空指针异常;底层调用了 PriorityQueue.offer(e) 方法;
  3. void put(E e) { offer(e); } : 同offer(e);
  4. boolean offer(E e, long timeout, TimeUnit unit){ return offer(e);}: 插入元素,但永不阻塞,因为底层是优先级队列(无界);
  5. E poll(): 获取头部元素,若不存在没有延迟到期的元素,则返回 null。底层调用 优先级队列.poll() 方法;
  6. E take() throws InterruptedException: 获取头部元素,按需等待直到队列存在可用的延迟到期的元素;底层调用 优先级队列.poll() 方法;
  7. E poll(long timeout, TimeUnit unit) throws InterruptedException: 获取头部元素;如为空,则等待给定时间;若等待结束前扔不存在可用的延迟到期元素,则返回null;
  8. E peek(): 获取但不移除头部元素,若队列空,则返回null;与pool不同,若队列不存在到期元素,则返回下一个将要到期元素而不是 null,若存在下一个的话;

【2.5】SynchronousQueue 同步队列

0)类描述

一个阻塞队列,其中每个插入操作都必须等待另一个线程执行相应的移除操作,反之亦然。同步队列没有任何内部容量

  • 您无法查看同步队列,因为元素仅在您尝试删除它时才存在;
  • 你不能插入一个元素(使用任何方法),除非另一个线程试图删除它;
  • 你不能迭代,因为没有什么可以迭代的。

队列头部是第一个排队的插入线程试图添加到队列的元素;

如果没有这样的排队线程,则没有元素可用于删除,poll() 将返回 null。对于其他集合方法(例如包含),SynchronousQueue 充当空集合。此队列不允许空元素。

同步队列类似于 CSP 和 Ada 中使用的集合通道。

它们非常适合切换设计,在这种设计中,在一个线程中运行的对象必须与在另一个线程中运行的对象同步,以便将某些信息、事件或任务交给它。

该类支持可选的公平策略,用于对等待的生产者线程和消费者线程进行排序。默认情况下,不保证此顺序。但是,公平性设置为 true 的队列会以 FIFO 顺序授予线程访问权限(公平性,谁最先等待,谁最先操作)

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。

1)类定义

public class SynchronousQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {

2)构造器

public SynchronousQueue() {this(false);
}// 若公平性fair设置为true,则等待线程根据 FIFO 顺序竞争访问 
public SynchronousQueue(boolean fair) {transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}

3)方法描述

  1. void put(E e) throws InterruptedException: 把元素e添加到队列,必要时等待阻塞直到线程B接收它;元素为空抛空指针异常;等待阻塞可能抛中断异常;
  2. boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException: 把元素e添加到队列,必要时至多等待给定时间直到另一个线程接收它。若插入成功返回true;若消费者出现之前指定的等待时间已过,则返回false;
  3. boolean offer(E e):插入元素e到队列,如果正好有其他线程接收它;插入成功返回true,否则false;
  4. E take() throws InterruptedException: 查询并移除队列头部元素,必要时等待另一线程插入元素;
  5. E poll(long timeout, TimeUnit unit) throws InterruptedException: 检索并删除此队列的头部,必要时等待指定时长,以便另一个线程插入它。返回队列头部,或者在元素出现之前经过了指定的等待时间,返回 null ;
  6. E poll():若另一线程正在使元素可用,则检索并删除队列头部。返回队列头部,或者队列没有可用元素,返回null;
  7. E peek() { return null; }:总是返回null;

【2.6】LinkedTransferQueue 链表传输队列

0)类描述

基于链接节点的无界 TransferQueue。

该队列根据任何给定的生产者对元素 FIFO(先进先出)进行排序。队列的头部是某个生产者在队列中停留时间最长的元素。队列的尾部是某个生产者在队列中停留时间最短的那个元素。

请注意,与大多数集合不同,size 方法不是恒定时间操作。

 由于这些队列的异步特性,确定当前元素的数量需要遍历所有元素,因此如果在遍历期间修改此集合,则可能会报告不准确的结果

此外,批量操作 addAll、removeAll、retainAll、containsAll、equals 和 toArray 不能保证以原子方式执行。例如,与 addAll 操作同时运行的迭代器可能只查看一些添加的元素。

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。

与其他并发集合一样,线程中的操作在将对象放入LinkedTransferQueue之前发生——在另一个线程中的LinkedTransferQueue中访问或删除该元素之后发生操作。

1)类定义

public class LinkedTransferQueue<E> extends AbstractQueue<E>implements TransferQueue<E>, java.io.Serializable {

2)构造器

// 创建空链表传输队列 
public LinkedTransferQueue() {
}// 创建包含给定集合c的链表传输队列 
public LinkedTransferQueue(Collection<? extends E> c) {this();addAll(c);
}

3)元素操作方法

/** Possible values for "how" argument in xfer method.*/
private static final int NOW   = 0; // for untimed poll, tryTransfer
private static final int ASYNC = 1; // for offer, put, add
private static final int SYNC  = 2; // for transfer, take
private static final int TIMED = 3; // for timed poll, tryTransfer
  1. void put(E e) { xfer(e, true, ASYNC, 0); }: 插入元素e到队列;因为队列无界,所以永不阻塞;但元素空,抛空指针;
  2. boolean offer(E e): 插入元素e到队列;因为队列无界,所以只会返回true或者元素e为null抛空指针;
  3. boolean offer(E e, long timeout, TimeUnit unit) : 同 offer(E),timeout 和 unit 参数没有使用;
  4. boolean add(E e): 底层实现同 offer(E e );
  5. E take() throws InterruptedException: 获取元素;获取到null抛出异常;
  6. E poll(long timeout, TimeUnit unit) throws InterruptedException: 获取元素,最多等待给定时间;获取到null抛出异常;
  7. E poll() { return xfer(null, false, NOW, 0);}:  获取元素,元素为null不抛出异常;
  8. E peek() {  return firstDataItem(); }:获取第一个元素但不出队;队列空返回null,不抛出异常;

【2.7】LinkedBlockingDeque 链表阻塞双端队列(注意是双端)

0)类描述

基于链表的可选有界阻塞双端队列

可选的容量提供了防止队列过度扩展的方法。

如果未指定,容量等于 Integer.MAX_VALUE(默认)。 链接节点在每次插入时动态创建,除非这会使双端队列超出容量。

大多数操作在恒定时间内运行(忽略阻塞所花费的时间)。 但 remove、removeFirstOccurrence、removeLastOccurrence、contains、iterator.remove() 和批量操作,所有这些都在线性时间内运行。

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。

1)类定义

public class LinkedBlockingDeque<E>extends AbstractQueue<E>implements BlockingDeque<E>, java.io.Serializable {

2)构造器

// 默认容量的构造器 
public LinkedBlockingDeque() {this(Integer.MAX_VALUE);}// 给定容量的构造器
public LinkedBlockingDeque(int capacity) {if (capacity <= 0) throw new IllegalArgumentException();this.capacity = capacity;}
// 创建一个包含 指定容器中所有元素 的双端队列
public LinkedBlockingDeque(Collection<? extends E> c) {this(Integer.MAX_VALUE);final ReentrantLock lock = this.lock;lock.lock(); // Never contended, but necessary for visibilitytry {for (E e : c) {if (e == null)throw new NullPointerException();if (!linkLast(new Node<E>(e)))throw new IllegalStateException("Deque full");}} finally {lock.unlock();}}

底层使用了 Node节点,包括 上一个 下一个指针;

static final class Node<E> {        E item;// 节点值 // 上一个节点Node<E> prev;// 下一个节点 Node<E> next;// 节点构造器 Node(E x) {item = x;}}

3)元素操作方法

  1. void addFirst(E e): 头部添加元素,底层调用offerFirst(e),队列满则抛出异常;
  2. void addLast(E e):操作尾部,其余同上;
  3. boolean offerFirst(E e) :头部添加元素; 底层调用 linkFirst(node);元素为null,抛出异常;
  4. boolean offerLast(E e):操作尾部,其余同上;
  5. void putFirst(E e) throws InterruptedException:头部添加元素; 底层调用 linkFirst(node);队列满则阻塞等待;
  6. void putLast(E e) throws InterruptedException:操作尾部,其余同上;
  7. boolean offerFirst(E e, long timeout, TimeUnit unit):头部添加元素; 底层调用 linkFirst(node);队列满则阻塞等待;但阻塞时间不超过timeout;
  8. boolean offerLast(E e, long timeout, TimeUnit unit):操作尾部,其余同上;
  9. E pollFirst():获取头部元素,底层调用 unlinkFirst();队列为空返回null;
  10. E pollLast():操作尾部,其余同上;
  11. E takeFirst() throws InterruptedException: 获取头部元素,底层调用 unlinkFirst(),队列空则阻塞;
  12. E takeLast() throws InterruptedException: 操作尾部,其余同上;  
  13. E pollFirst(long timeout, TimeUnit unit): 获取头部元素,底层调用 unlinkFirst();队列为空则阻塞等待给定时间;
  14. E pollLast(long timeout, TimeUnit unit):操作尾部,其余同上;
  15. E getFirst():获取首部元素,底层调用 peekFirst(),但不出队;不阻塞;
  16. E getLast(): 操作尾部,其余同上;
  17. E peekFirst():获取首部元素,不出队,不阻塞;为空返回null;
  18. E peekLast() :操作尾部,其余同上;

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

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

相关文章

来自.NET FM的感谢信

掐指一算&#xff0c;我们的播客 .NET FM 已经上线一周了&#xff01;&#xff01;&#xff01;不过瞅下节节攀升的流量&#xff0c;二位主播一边感叹 .NET 中文社区的热情&#xff0c;一边摸了摸瘪下去的荷包&#xff1a; • 首日访问 > 2000人次 • 五日访问 > 5000人次…

并发场景下MySQL存在的问题及解决思路

转载自 并发场景下MySQL存在的问题及解决思路 目录1、背景2、表锁导致的慢查询的问题3、线上修改表结构有哪些风险&#xff1f;4、一个死锁问题的分析5、锁等待问题的分析6、小结 一、背景对于数据库系统来说在多用户并发条件下提高并发性的同时又要保证数据的一致性一直是数据…

python queue 生产者 消费者_【python】-- 队列(Queue)、生产者消费者模型

队列(Queue)在多个线程之间安全的交换数据信息&#xff0c;队列在多线程编程中特别有用队列的好处&#xff1a;提高双方的效率&#xff0c;你只需要把数据放到队列中&#xff0c;中间去干别的事情。完成了程序的解耦性&#xff0c;两者关系依赖性没有不大。一、队列的类型&…

关于.NET技术前途问题的讨论

我去年曾经在论坛发起过关于.NET技术前途问题这个话题的讨论&#xff0c;也引起了很多同行和朋友的回复&#xff0c;时间过去大半年&#xff0c;自己也有了一些新的理解。本文的目的就是将其中一些精彩的观点整理出来并谈谈自己的观点。 引子 我们都知道微软.NET技术更新速度快…

用枚举enum实现单例

【README】 1&#xff0c;effectivejava 讲到使用 枚举类实现单例的例子&#xff0c;非常好用&#xff1b;2&#xff0c;好处如下&#xff1a; 不用定义私有构造器&#xff1b;不用定义获取单例的方法&#xff0c;如 getInstance() &#xff1b;通过 枚举类.INSTANCE() 就可以…

前端面试常考系列一

转载自 前端面试常考系列一 一、简述HTML5的优点和缺点&#xff1f; 优点&#xff1a; 1、网络标准统一、HTML5是由W3C推出的。 2、多设备、跨平台 &#xff0c;移植性强。 3、自适应网页设计。 4、即时更新。 5、新增了几个标签&#xff0c;有助于开发人员定义重要的内容&…

基于轻量型Web服务器Raspkate的RESTful API的实现

在上一篇文章《Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器》中&#xff0c;我们已经了解了Raspkate这一轻量型Web服务器&#xff0c;今天&#xff0c;我们再一起了解下如何基于Raspkate实现简单的RESTful API。 模块 首先让我们了解一下“模块”的概念。Raspkate的…

python股票自动买卖视频教程_十分钟学会用Python交易股票

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼本文通过讲述 [单股票均线策略] 在 Ricequant 量化平台的实现&#xff0c;熟悉平台并快速入门、创建自己的量化策略代码 。难易度&#xff1a;入门级.从一下几点说起&#xff1b;1 确定框架&#xff1a;[单股票均线策略] 的主要策略…

前端面试常考系列二

转载自 前端面试常考系列二 一、外部引用CSS有几种方式&#xff0c;有何区别 外部引用CSS的方式有两种分别是link和import。 区别如下&#xff1a; 1、link是XHTML标签&#xff0c;除了加载CSS外&#xff0c;还可以定义RSS等其它事务&#xff1b;import属于CSS范畴&#xff0c;…

3分钟看完Build2016 Day 1 Keynote

Build 2016 Day 1 Keynote 直播结束&#xff0c;M姐不得不说&#xff0c;没看直播的真心错过了一大波黑科技和充值我软信仰的大好时机&#xff0c;不过别后悔&#xff0c;M姐精选了干货&#xff0c;一次性让你补充信仰。没看的真心会被甩开八条街&#xff01;&#xff01; 言归…

js动态给按钮赋id_如何给SHOPIFY店铺添加“立即购买”动态结账按钮

动态结账按钮会根据店铺后台所支持的第三方快速结账付款方式和顾客设备浏览器的记录动态展示快速结帐按钮&#xff0c;比如PayPal Express Checkout、Apple Pay等。当然如果浏览器没有记录或者店铺后台没有支持的快速结帐付款方式&#xff0c;按钮则会显示为“buy it now”。Dy…

java序列化与深度拷贝

【README】 1&#xff0c; 为啥要序列化或序列化的意义&#xff1f;2&#xff0c;系统间调用的报文格式&#xff0c;大多数是Json字符串&#xff08;或字节数组&#xff09;&#xff1b;接收方接收json&#xff1b;3&#xff0c;但当系统调用如RMI&#xff0c;客户端请求服务器…

微软Build 2016开发者大会--兑换承诺

微软的Build开发者大会已经成为它向我们宣布其在未来一年里的战略方向的一个最大平台。不像苹果的发布大会&#xff0c;微软之所以要召开这个会议并不是要发布什么产品&#xff0c;而是像众多业内人士所分析的那样&#xff0c;希望通过介绍公司的努力来说服它最重要的听众——开…

前端面试常考系列三

转载自 前端面试常考系列三 一、简述一下src与href的区别 href 表示超文本引用&#xff0c;在 link和a 等元素上使用。src 表示来源地址&#xff0c;指向外部资源所在位置&#xff0c;在 img、script、iframe 等元素上。src 的内容&#xff0c;是页面的一部分&#xff0c;是引入…

java内部类小结

【README】 1&#xff0c;本文总结了java4种内部类&#xff0c;包括 成员内部类&#xff1a;在外部类内部定义的非静态类&#xff1b;成员内部类不能独立存在&#xff0c;如 UML中类间的组合关联关系&#xff1b;静态内部类&#xff1a;在外部类内部定义的静态类&#xff1b;…

python内置模块有哪些_python中那些小众但有用的内置模块

今天带来的是python里一些小众但是却比较实用的python库&#xff0c;一起来看看吧&#xff01;pprint&#xff1a;更清晰的打印pprint 是 pretty printer 的缩写&#xff0c;用来打印 Python 数据结构&#xff0c;与 print 相比&#xff0c;它打印出来的结构更加整齐&#xff0…

微软想让你跟机器人说句话就把事办了

也别猜错&#xff0c;微软可没有像 Google 一样打算让四只脚能跑 60 迈和两只脚能穿行森林的机器人大军占领你的家。他们家的机器人不是 Robot&#xff0c;而叫 Bot&#xff0c;可能是 chatbot 的简称&#xff0c;也就是聊天机器人。 具体来说&#xff0c;微软在自然语言处理的…

转:Spring Boot 获取 HttpServletRequest 的方法

转自&#xff1a; Spring Boot 获取 HttpServletRequest 的方法 - 简书本文介绍 Spring Boot 2 获取 HttpServletRequest 的方法。 目录 概述 方法Controller 方法参数属性自动注入手动方法调用借助 Mo...https://www.jianshu.com/p/b7a7d66c4ef2 本文介绍 Spring Boot 2 获取…

前端面试常考系列四

转载自 前端面试常考系列四 一、CSS盒子模型有哪些用处 css中的盒子模型是为了理解divcss模型的定位功能&#xff0c;它利用盒子模型这样的布局方式代替了传统的表格布局方式。盒子模型是在学习divcss布局方式中必须要学习的一个模型&#xff0c;通过这个模型可以明白网页中di…

python线性加权模型_局部加权之线性回归(1) - Python实现

1 #局部加权线性回归2 #交叉验证计算泛化误差最小点345 importnumpy6 from matplotlib importpyplot as plt789 #待拟合不含噪声之目标函数10 deforiFunc(x):11 y numpy.exp(-x) * numpy.sin(10*x)12 returny13 #待拟合包含噪声之目标函数14 def traFunc(x, sigma0.03):15 y …