同时开10个线程存入和取出100万的数据,结论如下:

DoubleBufferedQueue < ConcurrentLinkedQueue < ArrayBlockingQueue < LinkedBlockingQueue

执行结果如下:

100万 DoubleBufferedQueue入队时间:9510 出队时间:10771
100万 DoubleBufferedQueue入队时间:8169 出队时间:9789
1000万 DoubleBufferedQueue入队时间:98285 出队时间:101088
1000万 DoubleBufferedQueue入队时间:101859 出队时间:105964

100万 ConcurrentLinkedQueue入队时间:10557 出队时间:13716
100万 ConcurrentLinkedQueue入队时间:25298 出队时间:25332
1000万 ConcurrentLinkedQueue队列时间:121868 出队时间:136116
1000万 ConcurrentLinkedQueue队列时间:134306 出队时间:147893

100万 ArrayBlockingQueue入队时间:21080 出队时间:22025
100万 ArrayBlockingQueue入队时间:17689 出队时间:19654
1000万 ArrayBlockingQueue入队时间:194400 出队时间:205968
1000万 ArrayBlockingQueue入队时间:192268 出队时间:197982

100万 LinkedBlockingQueue入队时间:38236 出队时间:52555
100万 LinkedBlockingQueue入队时间:30646 出队时间:38573
1000万 LinkedBlockingQueue入队时间:375669 出队时间:391976
1000万 LinkedBlockingQueue入队时间:701363 出队时间:711217

doubleBufferedQueue:

package test.MoreThread.d;import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import test.MoreThread.l.linkedBlockingQueue;
import comrt.util.DoubleBufferedQueue;//DoubleBufferedQueue入队时间:9510  出队时间:10771
//DoubleBufferedQueue入队时间:8169  出队时间:9789
public class doubleBufferedQueue {private static final Logger log = LoggerFactory.getLogger(doubleBufferedQueue.class);public final static int size1 = 1000000;public static DoubleBufferedQueue<Object> queue = new DoubleBufferedQueue<Object>(size1);public final static int threadNumber = 10;public static boolean isOver = false;public static void main(String[] args) throws InterruptedException,ExecutionException {//        long timestart = System.currentTimeMillis();Thread thread1 = new Thread(new Runnable() {public void run() {ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService.submit(new ExecDoubleBufferedQueue());results.add(future);}long allTime = 0;for (Future<Long> fs : results) {try {allTime += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService.shutdown();}}doubleBufferedQueue.isOver = true;log.info("入队列总共执行时间:" + allTime);}});thread1.start();// log.info("主线程执行时间:" + (System.currentTimeMillis() - timestart));// ------------------------------Thread thread2 = new Thread(new Runnable() {public void run() {ExecutorService executorService2 = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results_out = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService2.submit(new ExecDoubleBufferedQueue_Out());results_out.add(future);}long allTime_out = 0;for (Future<Long> fs : results_out) {try {allTime_out += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService2.shutdown();}}log.info("出队列总共执行时间:" + allTime_out);}});thread2.start();}
}class ExecDoubleBufferedQueue implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(doubleBufferedQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();for (int i = 0; i < doubleBufferedQueue.size1; i++) {doubleBufferedQueue.queue.offer(i);}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}class ExecDoubleBufferedQueue_Out implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(doubleBufferedQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();while (!doubleBufferedQueue.isOver) {doubleBufferedQueue.queue.poll();}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}

concurrentLinkedQueue:

package test.MoreThread.c;import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;//ConcurrentLinkedQueue入队时间:10557  出队时间:13716
//ConcurrentLinkedQueue入队时间:25298  出队时间:25332
public class concurrentLinkedQueue {private static final Logger log = LoggerFactory.getLogger(concurrentLinkedQueue.class);public static ConcurrentLinkedQueue<Object> queue = new ConcurrentLinkedQueue<Object>();public final static int size1 = 1000000;public final static int threadNumber = 10;public static boolean isOver = false;public static void main(String[] args) throws InterruptedException,ExecutionException {// long timestart = System.currentTimeMillis();Thread thread1 = new Thread(new Runnable() {public void run() {ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService.submit(new Exec());results.add(future);}long allTime = 0;for (Future<Long> fs : results) {try {allTime += fs.get();
//                        log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService.shutdown();}}concurrentLinkedQueue.isOver = true;log.info("队列总共执行时间:" + allTime);}});thread1.start();// ------------------------------Thread thread2 = new Thread(new Runnable() {public void run() {ExecutorService executorService2 = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results_out = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService2.submit(new Exec_Out());results_out.add(future);}long allTime_out = 0;for (Future<Long> fs : results_out) {try {allTime_out += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService2.shutdown();}}log.info("出队列总共执行时间:" + allTime_out);}});thread2.start();// log.info("主线程执行时间:" + (System.currentTimeMillis() - timestart));
    }
}class Exec implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(concurrentLinkedQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();for (int i = 0; i < concurrentLinkedQueue.size1; i++) {concurrentLinkedQueue.queue.offer(i);}long time2 = System.currentTimeMillis() - time;
//        log.info("执行时间:" + time2);return time2;}
}class Exec_Out implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(concurrentLinkedQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();while (!concurrentLinkedQueue.isOver) {concurrentLinkedQueue.queue.poll();}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}

arrayBlockingQueue:

package test.MoreThread.a;import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;//ArrayBlockingQueue入队时间:21080  出队时间:22025
//ArrayBlockingQueue入队时间:17689  出队时间:19654
public class arrayBlockingQueue {private static final Logger log = LoggerFactory.getLogger(arrayBlockingQueue.class);public final static int size1 = 1000000;public static ArrayBlockingQueue<Object> queue = new ArrayBlockingQueue<Object>(size1);public final static int threadNumber = 10;public static boolean isOver = false;public static void main(String[] args) throws InterruptedException,ExecutionException {// long timestart = System.currentTimeMillis();Thread thread1 = new Thread(new Runnable() {public void run() {ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService.submit(new ExecArrayBlockingQueue());results.add(future);}long allTime = 0;for (Future<Long> fs : results) {try {allTime += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService.shutdown();}}arrayBlockingQueue.isOver = true;log.info("队列总共执行时间:" + allTime);}});thread1.start();// log.info("主线程执行时间:" + (System.currentTimeMillis() - timestart));// ------------------------------Thread thread2 = new Thread(new Runnable() {public void run() {ExecutorService executorService2 = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results_out = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService2.submit(new ExecArrayBlockingQueue_Out());results_out.add(future);}long allTime_out = 0;for (Future<Long> fs : results_out) {try {allTime_out += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService2.shutdown();}}log.info("出队列总共执行时间:" + allTime_out);}});thread2.start();}
}class ExecArrayBlockingQueue implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(arrayBlockingQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();for (int i = 0; i < arrayBlockingQueue.size1; i++) {arrayBlockingQueue.queue.offer(i);}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}class ExecArrayBlockingQueue_Out implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(arrayBlockingQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();while (!arrayBlockingQueue.isOver) {arrayBlockingQueue.queue.poll();}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}

linkedBlockingQueue:

package test.MoreThread.l;import java.util.ArrayList;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;//LinkedBlockingQueue入队时间:38236  出队时间:52555
//LinkedBlockingQueue入队时间:30646  出队时间:38573
public class linkedBlockingQueue {private static final Logger log = LoggerFactory.getLogger(linkedBlockingQueue.class);public final static int size1 = 1000000;public static LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(size1);public final static int threadNumber = 10;public static boolean isOver = false;public static void main(String[] args) throws InterruptedException,ExecutionException {long timestart = System.currentTimeMillis();Thread thread1 = new Thread(new Runnable() {public void run() {ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService.submit(new ExecLinkedBlockingQueue());results.add(future);}long allTime = 0;for (Future<Long> fs : results) {try {allTime += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService.shutdown();}}linkedBlockingQueue.isOver = true;log.info("入队列总共执行时间:" + allTime);}});thread1.start();// log.info("主线程执行时间:" + (System.currentTimeMillis() - timestart));
//        System.out.println(linkedBlockingQueue.queue.size());// ------------------------------
Thread thread2 = new Thread(new Runnable() {public void run() {ExecutorService executorService2 = Executors.newFixedThreadPool(threadNumber);ArrayList<Future<Long>> results_out = new ArrayList<Future<Long>>();for (int i = 0; i < threadNumber; i++) {Future<Long> future = executorService2.submit(new ExecLinkedBlockingQueue_Out());results_out.add(future);}long allTime_out = 0;for (Future<Long> fs : results_out) {try {allTime_out += fs.get();// log.info("" + fs.get());} catch (InterruptedException e) {log.info("" + e);return;} catch (ExecutionException e) {log.info("" + e);} finally {executorService2.shutdown();}}log.info("出队列总共执行时间:" + allTime_out);}});thread2.start();}
}class ExecLinkedBlockingQueue implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(linkedBlockingQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();for (int i = 0; i < linkedBlockingQueue.size1; i++) {linkedBlockingQueue.queue.offer(i);}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}class ExecLinkedBlockingQueue_Out implements Callable<Long> {private static final Logger log = LoggerFactory.getLogger(linkedBlockingQueue.class);@Overridepublic Long call() throws Exception {long time = System.currentTimeMillis();while (!linkedBlockingQueue.isOver) {linkedBlockingQueue.queue.poll();}long time2 = System.currentTimeMillis() - time;// log.info("执行时间:" + time2);return time2;}
}

DoubleBufferedQueue双缓冲队列

package comrt.util;import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;//双缓冲队列,线程安全
public class DoubleBufferedQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {private static final long serialVersionUID = 1011398447523020L;public static final int DEFAULT_QUEUE_CAPACITY = 5000000;public static final long DEFAULT_MAX_TIMEOUT = 0;public static final long DEFAULT_MAX_COUNT = 10;private Logger logger =    LoggerFactory.getLogger(DoubleBufferedQueue.class.getName());/** The queued items */private ReentrantLock readLock;// 写锁private ReentrantLock writeLock;// 是否满private Condition notFull;private Condition awake;// 读写数组private transient E[] writeArray;private transient E[] readArray;// 读写计数private volatile int writeCount;private volatile int readCount;// 写数组下标指针private int writeArrayTP;private int writeArrayHP;// 读数组下标指针private int readArrayTP;private int readArrayHP;private int capacity;public DoubleBufferedQueue(int capacity) {// 默认this.capacity = DEFAULT_QUEUE_CAPACITY;if (capacity > 0) {this.capacity = capacity;}readArray = (E[]) new Object[capacity];writeArray = (E[]) new Object[capacity];readLock = new ReentrantLock();writeLock = new ReentrantLock();notFull = writeLock.newCondition();awake = writeLock.newCondition();}private void insert(E e) {writeArray[writeArrayTP] = e;++writeArrayTP;++writeCount;}private E extract() {E e = readArray[readArrayHP];readArray[readArrayHP] = null;++readArrayHP;--readCount;return e;}/*** switch condition: read queue is empty && write queue is not empty* * Notice:This function can only be invoked after readLock is grabbed,or may* cause dead lock* * @param timeout* @param isInfinite*            : whether need to wait forever until some other thread awake*            it* @return* @throws InterruptedException*/private long queueSwap(long timeout, boolean isInfinite) throws InterruptedException {writeLock.lock();try {if (writeCount <= 0) {// logger.debug("Write Count:" + writeCount// + ", Write Queue is empty, do not switch!");try {// logger.debug("Queue is empty, need wait....");if (isInfinite && timeout <= 0) {awake.await();return -1;} else if (timeout > 0) {return awake.awaitNanos(timeout);} else {return 0;}} catch (InterruptedException ie) {awake.signal();throw ie;}} else {E[] tmpArray = readArray;readArray = writeArray;writeArray = tmpArray;readCount = writeCount;readArrayHP = 0;readArrayTP = writeArrayTP;writeCount = 0;writeArrayHP = readArrayHP;writeArrayTP = 0;notFull.signal();// logger.debug("Queue switch successfully!");return 0;}} finally {writeLock.unlock();}}@Overridepublic boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {if (e == null) {throw new NullPointerException();}long nanoTime = 0;if (timeout > 0) {nanoTime = unit.toNanos(timeout);}writeLock.lockInterruptibly();try {for (int i = 0; i < DEFAULT_MAX_COUNT; i++) {if (writeCount < writeArray.length) {insert(e);if (writeCount == 1) {awake.signal();}return true;}// Time outif (nanoTime <= 0) {// logger.debug("offer wait time out!");return false;}// keep waitingtry {// logger.debug("Queue is full, need wait....");nanoTime = notFull.awaitNanos(nanoTime);} catch (InterruptedException ie) {notFull.signal();throw ie;}}} finally {writeLock.unlock();}return false;}// 取
    @Overridepublic E poll(long timeout, TimeUnit unit) throws InterruptedException {long nanoTime = 0;if (timeout > 0) {nanoTime = unit.toNanos(timeout);}readLock.lockInterruptibly();try {if (nanoTime > 0) {for (int i = 0; i < DEFAULT_MAX_COUNT; i++) {if (readCount > 0) {return extract();}if (nanoTime <= 0) {// logger.debug("poll time out!");return null;}nanoTime = queueSwap(nanoTime, false);}} else {if (readCount > 0) {return extract();}queueSwap(nanoTime, false);if (readCount > 0) {return extract();} }} finally {readLock.unlock();}return null;}// 等待500毫秒
    @Overridepublic E poll() {E ret = null;try {ret = poll(DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);} catch (Exception e) {ret = null;}return ret;}// 查看
    @Overridepublic E peek() {E e = null;readLock.lock();try {if (readCount > 0) {e = readArray[readArrayHP];}} finally {readLock.unlock();}return e;}// 默认500毫秒
    @Overridepublic boolean offer(E e) {boolean ret = false;try {ret = offer(e, DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);} catch (Exception e2) {ret = false;}return ret;}@Overridepublic void put(E e) throws InterruptedException {// never need to // block
        offer(e, DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS); }@Overridepublic E take() throws InterruptedException {return poll(DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);}@Overridepublic int remainingCapacity() {return this.capacity;}@Overridepublic int drainTo(Collection<? super E> c) {return 0;}@Overridepublic int drainTo(Collection<? super E> c, int maxElements) {return 0;}@Overridepublic Iterator<E> iterator() {return null;}// 当前读队列中还有多少个
    @Overridepublic int size() {int size = 0;readLock.lock();try {size = readCount;} finally {readLock.unlock();}return size;}/*** 当前已写入的队列大小* */public int WriteSize() {int size = 0;writeLock.lock();try {size = writeCount;} finally {writeLock.unlock();}return size;}public int unsafeReadSize() {return readCount;}public int unsafeWriteSize() {return writeCount;}public int capacity() {return capacity;}public String toMemString() {return "--read: " + readCount + "/" + capacity + "--write: " + writeCount + "/" + capacity;}// 清理/** public void clear() { readLock.lock(); writeLock.lock(); try { readCount* = 0; readArrayHP = 0; writeCount = 0; writeArrayTP = 0;* //logger.debug("Queue clear successfully!"); } finally {* writeLock.unlock(); readLock.unlock(); } }*/
}

转载于:https://www.cnblogs.com/zhuawang/p/4158486.html

Java队列集合的性能测试相关推荐

  1. java异步刷新集合,同步和异步集合的性能测试,异步集合性能测试,package cn.o

    同步和异步集合的性能测试,异步集合性能测试,package cn.opackage cn.outofmemory.snippets.core;import java.util.ArrayList;im ...

  2. Java队列 Deque

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120828826 本文出自[赵彦军的博客] Java队列 Queue Java队列 ...

  3. Java队列 Queue

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120828046 本文出自[赵彦军的博客] Java队列 Queue Java队列 ...

  4. (7)Java数据结构--集合map,set,list详解

    MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...

  5. java 队列和堆栈_Java中的堆栈和队列

    java 队列和堆栈 我最近一直在研究一些需要堆栈和队列的Java代码. 使用的选择不是立即显而易见的. 有一个Queue接口,但没有明确的具体实现要使用. 还有一个Stack类,但是javadocs ...

  6. 发现大量Java原语集合处理

    在阅读博客文章5减少Java垃圾收集开销的技巧时 ,我想起了一个名为Trove的小型Java收集库,该库"为Java提供了高速的常规和原始收集". 我对应用Trove允许原始类型的 ...

  7. java队列 双队列_Java队列– Java队列

    java队列 双队列 Java Queue is an interface available in java.util package and extends java.util.Collectio ...

  8. Java的集合有什么?

    目录 常见的集合有哪些? List .Set和Map 的区别 ArrayList 了解吗? ArrayList 的扩容机制? 怎么在遍历 ArrayList 时移除一个元素? Arraylist 和 ...

  9. JAVA队列( Queue ) 详解

    什么是队列? 队列是一种特殊的线性表,遵循先入先出.后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删除:比如我们常用的 ...

最新文章

  1. ci框架 mysql_CodeIgniter (CI)框架中的数据库查询汇总
  2. sql server存储过程中SELECT 与 SET 对变量赋值的区别
  3. 鼠标绘图 c语言,c语言高级编程技术教程 图形显示方式与鼠标输入.doc
  4. http和socket之长连接和短连接区别
  5. 面码份量Java_JAVA语言(28道练习题)
  6. Cesium中的相机—YawPitchRoll
  7. 分布式事务实践 解决数据一致性 分布式事务实现:消息驱动模式
  8. Unsupported major.minor version 52.0解决办法
  9. VCSA6.7 备份和还原
  10. CeBIT 2017热点:从5G到AI和物联网
  11. (转)关于做android+J2ee系统集成开发的一点心得
  12. linux ssh端口是否打开,如何查看linux中的ssh端口开启状态
  13. 那些在大厂做外包的测试工程师,后来发展怎么样了?
  14. mysql libs 5.1.73_【MySQL案例】mysql-libs-5.1.73-3.el6
  15. SharePoint 用户配置文件服务
  16. 火狐翻译插件_阅读外文必备,浏览器实用的翻译插件推荐
  17. Docker简介及Linux下安装
  18. html武侠文字游戏源码,执剑行!最新武侠文字mud游戏
  19. Windows 7版本IE10浏览器11月中旬推出
  20. 企业研发人员配备比例_高新技术企业对研发技术人员占企业总职工人数的比例为多少?...

热门文章

  1. lambda中orElse(null)使用
  2. docker启动报错  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --
  3. 开发工具:收集12 个顶级 Bug 跟踪工具,值得收藏!
  4. mysql 5.7.17源码包_centos7 mysql5.7.17源码安装
  5. python datetime用法_python datetime用法学习笔记
  6. python中的拷贝
  7. ios 动画设计_动画和讲故事在设计中的力量
  8. 若川知乎高赞:有哪些必看的 JS 库?
  9. 资本冬天已至,开发者却可以着眼未来
  10. 手把手教你如何实现继承