java双端队列原理(初学者java入门基础知识)

队列(Queue):与栈相对的一种数据结构,集合(Collection)的一个子类。队列允许在一端进行插入操作,而在另一端进行删除操作的线性表,栈的特点是后进先出,而队列的特点是先进先出。队列的用处很大,比如实现消息队列。Queue类关系图,如下图所示: 注:为了让读者更直观地理解,上图为精简版的Queue类关系图。本文如无特殊说明,内容都是基于Java1.8版本。 队列(Queue) 1)Que…

队列(Queue):与栈相对性的一种算法设计, 结合(Collection)的一个派生类。队列容许在一端开展插进实际操作,而在另一端开展移除使用的线性表,栈的特性是后进先出,而队列的特点是先进先出法。队列的用途非常大,例如完成信息队列。Queue 类关系图,如下图所示:

如何手撸一个Java队列?队列详解和面试题汇总(含答案)

注:为了更好地让大家更直接地了解,图中为精简的 Queue 类关系图。文中如无特别表明,內容是根据 Java 1.8 版本号。

队列(Queue)

1)Queue 归类

从图中可以看得出 Queue 大致可分成下列三类。

  1. 二端队列:双端队列(Deque)是 Queue 的派生类也是 Queue 的填补类,头顶部和尾端都适用元素插进和获得。
  2. 堵塞队列:阻塞队列指的是在元素实际操作时(加上或删掉),要是没有取得成功,会堵塞等候实行。例如,当加上元素时,假如队列元素已满,队列会堵塞等候直到有位置时再插进。
  3. 非堵塞队列:非阻塞队列和堵塞队列反过来,会立即返回实际操作的結果,并非堵塞等候。二端队列也是非堵塞队列。

2)Queue 方式表明

Queue 常见方式,如下图所示:

如何手撸一个Java队列?队列详解和面试题汇总(含答案)

方法表明:

  • add(E):加上元素到队列尾端,取得成功返回 true,队列超过时抛出异常;
  • offer(E):加上元素到队列尾端,取得成功返回 true,队列超过时返回 false;
  • remove():删掉元素,取得成功返回 true,不成功返回 false;
  • poll():获得并清除此队列的第一个元素,若队列为空,则返回 null;
  • peek():获得但不清除此队列的第一个元素,若队列为空,则返回 null;
  • element():获得但不清除此队列的第一个元素,若队列为空,则抛出现异常。

3)Queue 应用案例

Queue<String> linkedList = new LinkedList<>();
linkedList.add(\"Dog\");
linkedList.add(\"Camel\");
linkedList.add(\"Cat\");
while (!linkedList.isEmpty()) {
  System.out.println(linkedList.poll());
}

程序运行結果:

Dog

Camel

Cat

堵塞队列

1)BlockingQueue

BlockingQueue 在 java.util.concurrent 包下,别的堵塞类都完成自 BlockingQueue 插口,BlockingQueue 给予了线程安全的队列浏览方法,当向队列中插进数据信息时,假如队列已满,进程则会堵塞等候队列中元素被取下后再插进;当从队列中取数据信息时,假如队列为空,则进程会堵塞等候队列中有新元素再获得。BlockingQueue 关键方式插入方法:

  • add(E):加上元素到队列尾端,取得成功返回 true,队列超过时抛出异常;
  • offer(E):加上元素到队列尾端,取得成功返回 true,队列超过时返回 false ;
  • put(E):将元素插进到队列的尾端,假如该队列已满,则一直堵塞。

删掉方式:

  • remove(Object):清除特定元素,取得成功返回 true,不成功返回 false;
  • poll(): 获得并清除队列的第一个元素,假如队列为空,则返回 null;
  • take():获得并清除队列第一个元素,要是没有元素则一直堵塞。

查验方式:

  • peek():获得但不清除队列的第一个元素,若队列为空,则返回 null。

2)LinkedBlockingQueue

LinkedBlockingQueue 是一个由单链表完成的有限堵塞队列,容积初始值为 Integer.MAX_VALUE,还可以自定容积,提议特定容积尺寸,默认设置尺寸在加上速率超过删掉速率状况下有导致内存溢出的风险性,LinkedBlockingQueue 是先进先出法的形式储存元素。

3)ArrayBlockingQueue

ArrayBlockingQueue 是一个有界限的堵塞队列,它的里面完成是一个二维数组。它的存储容量是有局限的,大家一定在其复位的情况下特定它的容积尺寸,容积尺寸一旦特定就不能更改。ArrayBlockingQueue 也是先进先出法的形式存放数据信息,ArrayBlockingQueue 内部结构的堵塞队列是根据再入锁 ReenterLock 和 Condition 标准队列完成的,因而 ArrayBlockingQueue 中的元素存有公平公正浏览和非公平公正浏览的差别,针对公平公正浏览队列,被堵塞的进程可以依照堵塞的顺序浏览队列,即先堵塞的进程先浏览队列。并非公平公正队列,当队列可以用时,堵塞的进程将进到角逐浏览資源的市场竞争中,换句话说谁先抢得谁就实行,沒有稳固的顺序。实例编码如下所示:

// 默认设置非公平公正堵塞队列
ArrayBlockingQueue queue = new ArrayBlockingQueue(6);
// 公平公正堵塞队列
ArrayBlockingQueue queue2 = new ArrayBlockingQueue(6,true);
// ArrayBlockingQueue 源代码展现
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();}

4)DelayQueue

DelayQueue 是一个适用延迟获得元素的无边堵塞队列,队列中的元素务必完成 Delayed 插口,在建立元素时可以特定时间延迟,仅有抵达了延时的时间段以后,才可以得到到该元素。完成了 Delayed 插口务必重新写过2个方式 ,getDelay(TimeUnit) 和 compareTo(Delayed),如下所示编码所显示:

class DelayElement implements Delayed { 
  @Override        // 获得剩下的时间       
  public long getDelay(TimeUnit unit) {
    // do something       
  }
  @Override        // 队列里元素的排列根据
  public int compareTo(Delayed o) {            // do something 
  }  
}

DelayQueue 应用的详细实例,请参照下列编码:

public class DelayTest { 
  public static void main(String[] args) throws InterruptedException {  
    DelayQueue delayQueue = new DelayQueue(); 
    delayQueue.put(new DelayElement(1000));
    delayQueue.put(new DelayElement(3000)); 
    delayQueue.put(new DelayElement(5000)); 
    System.out.println(\"开始时间:\"    DateFormat.getDateTimeInstance().format(new Date())); 
    while (!delayQueue.isEmpty()){
      System.out.println(delayQueue.take());
    } 
    System.out.println(\"完毕時间:\"    DateFormat.getDateTimeInstance().format(new Date())); 
  } 
static class DelayElement implements Delayed {        // 延迟时间截止时间(单层:ms)
  long delayTime = System.currentTimeMillis(); 
public DelayElement(long delayTime) { 
  this.delayTime = (this.delayTime   delayTime); 
} 
@Override        // 获得剩下的时间 
public long getDelay(TimeUnit unit) {
  return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); 
} 
@Override        // 队列里元素的排列根据 
public int compareTo(Delayed o) { 
  if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) { 
    return 1;
  } else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) { 
    return -1;  
  } else {      
    return 0;      
  }   
}      
@Override      
public String toString() { 
  return DateFormat.getDateTimeInstance().format(new Date(delayTime)); 
} 
}
}

程序运行結果:

开始时间:2019-6-13 20:40:38 2019-6-13 20:40:39 2019-6-13 20:40:41 2019-6-13 20:40:43 完毕時间:2019-6-13 20:40:43

非阻塞队列

ConcurrentLinkedQueue 是一个根据连接连接点的无边线程安全序列,它选用先进先出法的标准对连接点开展排列,在我们加上一个原素的情况下,它会加上到序列的尾端;在我们获得一个因素时,它会回到序列头顶部的原素。它的入队和出队实际操作均运用 CAS(Compare And Set)升级,那样容许好几个进程高并发实行,而且并不会由于上锁而堵塞进程,促使高并发特性更强。ConcurrentLinkedQueue 应用实例:

ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue();
concurrentLinkedQueue.add(\"Dog\");
concurrentLinkedQueue.add(\"Cat\");
while (!concurrentLinkedQueue.isEmpty()) { 
  System.out.println(concurrentLinkedQueue.poll());
}

实行結果:

Dog

Cat

可以看得出无论是阻塞队列还是是非非阻塞队列,操作方法全是相近的,差别是最底层的建立方法。

优先级队列

PriorityQueue 一个根据优先堆的无边优先级队列。优先级队列的原素依照其当然次序开展排列,或是依据结构序列时给予的 Comparator 开展排列,实际在于所采用的构造函数。优先级队列不允许应用 null 原素。PriorityQueue 编码应用实例

Queue<Integer> priorityQueue = new PriorityQueue(new Comparator<Integer>() {  
                                                 @Override    
                                                 public int compare(Integer o1, Integer o2) {
  // 非自然排列,数据倒序        return o2 - o1;    }});priorityQueue.add(3);priorityQueue.add(1);priorityQueue.add(2);while (!priorityQueue.isEmpty()) {    Integer i = priorityQueue.poll();    System.out.println(i);}

程序运行的結果是:

3

2

1

PriorityQueue 留意的点

  1. PriorityQueue 是是非非线程安全的,在线程同步状况下可应用 PriorityBlockingQueue 类取代;
  2. PriorityQueue 不允许插进 null 原素。

有关面试问题

1.ArrayBlockingQueue 和 LinkedBlockingQueue 的差异是啥?

答:ArrayBlockingQueue 和 LinkedBlockingQueue 都完成自阻塞队列 BlockingQueue,他们的差异具体反映在下述一些层面:

  • ArrayBlockingQueue 应用时务必特定容积值,LinkedBlockingQueue 可以无需特定;
  • ArrayBlockingQueue 的最高容积值是应用时特定的,而且特定以后就不允许改动;而 LinkedBlockingQueue 较大的容积为 Integer.MAX_VALUE;
  • ArrayBlockingQueue 数据储存器皿是选用二维数组储存的;而 LinkedBlockingQueue 选用的是 Node 连接点存放的。

2.LinkedList 中 add() 和 offer() 有什么关系?

答:add() 和 offer() 全是加上原素到序列尾端。offer 方式是根据 add 方式完成的,Offer 的源代码如下所示:

public boolean offer(E e) {    return add(e);}

3.Queue 和 Deque 有什么不同?

答:Queue 归属于一般序列,Deque 归属于双端队列。一般序列是先进先出法,也就是仅有优秀的才可以先出;而双端队列则是两边都能插进和删掉原素。

4.LinkedList 归属于一般序列或是双端队列?

答:LinkedList 完成了 Deque 归属于双端队列,因而有着 addFirst(E)、addLast(E)、getFirst()、getLast() 等方式。

5.下列表述不正确的是?

A:DelayQueue 内部结构是根据 PriorityQueue 完成的 B:PriorityBlockingQueue 并不是先进先出法的数据存储方式 C:LinkedBlockingQueue 容积是无穷大的 D:ArrayBlockingQueue 内部结构的数据存储器是二维数组,复位时务必特定序列容积 答:C 题型分析:LinkedBlockingQueue 默认设置容积是 Integer.MAX_VALUE,并并不是无穷大的,源代码如下图所示:

如何手撸一个Java队列?队列详解和面试题汇总(含答案)

6.有关 ArrayBlockingQueue 观点不正确的是?

A:ArrayBlockingQueue 是线程安全的 B:ArrayBlockingQueue 原素容许为 null C:ArrayBlockingQueue 关键应用领域是“经营者-顾客”实体模型 D:ArrayBlockingQueue 务必表明地设定容积 答:B 题型分析:ArrayBlockingQueue 不允许原素为 null,假如加上一个 null 原素,会抛 NullPointerException 出现异常。

7.下列程序运行的结论是啥?

PriorityQueue priorityQueue = new PriorityQueue();priorityQueue.add(null);
System.out.println(priorityQueue.size());

答:程序运行出错,PriorityQueue 不可以插进 null。

8.Java 中多见的阻塞队列有什么?

答:Java 中多见的阻塞队列如下所示:

  • ArrayBlockingQueue,由二维数组构造构成的有限阻塞队列;
  • PriorityBlockingQueue,适用优先级排序的无边阻塞队列;
  • SynchronousQueue,是一个不储存原素的阻塞队列,会立即将每日任务交到顾客,务必等序列中的增加原素被交易后能够再次加上新的原素;
  • LinkedBlockingQueue,由单链表构造构成的阻塞队列;
  • DelayQueue,适用延迟获得要素的无边阻塞队列。

9.有限序列和无边序列有什么差别?

答:有限序列和无边序列的差别如下所示:

  • 有限序列:有固定不动尺寸的序列称为有限序列,例如:new ArrayBlockingQueue(6),6 便是序列的尺寸。
  • 无边序列:指的是沒有设定固定不动尺寸的序列,这种序列的特性是可以立即入役,直到外溢。他们并没有确实无边,他们最高值通常为 Integer.MAXVALUE,仅仅平时非常少能使用这么大的容积(超出 Integer.MAXVALUE),因而从用户的感受上,就等同于 “无边”。

10.怎样手动式完成一个延迟时间线程池?

答:说到延迟时间线程池,大家应当可以第一时间想起要应用 DelayQueue 延迟时间序列来处理这个问题。完成构思,线程池分成经营者和顾客,经营者用以提升信息,顾客用以获得并交易信息,大家只必须经营者把信息放进到 DelayQueue 序列并设定时间延迟,顾客循环系统应用 take() 堵塞获得信息就可以。详细的建立源代码如下所示:

public class CustomDelayQueue {    // 信息序号 
  static AtomicInteger MESSAGENO = new AtomicInteger(1);
public static void main(String[] args) throws InterruptedException { 
  DelayQueue<DelayedElement> delayQueue = new DelayQueue<>();        // 经营者1    
  producer(delayQueue, \"生产者1\");        // 经营者2  
  producer(delayQueue, \"生产者2\");        // 顾客 
  consumer(delayQueue);    }    //生产者    
private static void producer(DelayQueue<DelayedElement> delayQueue, String name) {  
  new Thread(new Runnable() {   
             @Override       
             public void run() {             
    while (true) {                    // 造成 1~5 秒的随机数字           
      long time = 1000L * (new Random().nextInt(5)   1);       
      try {        
        Thread.sleep(time);          
      } catch (InterruptedException e) {      
        e.printStackTrace();          
      }                    // 组成信息体      
      String message = String.format(\"%s,消息序号:%s 推送時间:%s 延迟时间:%s 秒\",                            name, MESSAGENO.getAndIncrement(), DateFormat.getDateTimeInstance().format(new Date()), time / 1000);                    // 生产制造信息   
      delayQueue.put(new DelayedElement(message, time));      
    }   
  }    
}).start();   
}    //顾客   
private static void consumer(DelayQueue<DelayedElement> delayQueue) { 
  new Thread(new Runnable() {     
             @Override  
             public void run() { 
    while (true) {          
      DelayedElement element = null;     
      try {                        // 交易信息           
        element = delayQueue.take();        
        System.out.println(element);            
      } catch (InterruptedException e) {          
        e.printStackTrace();                  
      }           
    }         
  }     
}).start();    } 
// 延迟时间序列目标   
static class DelayedElement implements Delayed {     
  // 到期時间(企业:ms)     
  long time = System.currentTimeMillis();     
// 信息体     
String message;   
// 主要参数:delayTime 时间延迟(企业ms)  
public DelayedElement(String message, long delayTime) {      
  this.time  = delayTime;       
  this.message = message;       
}     
@Override     
// 获得到期時间        public long getDelay(TimeUnit unit) {            return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS);        }        @Override        // 序列原素排列        public int compareTo(Delayed o) {            if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS))                return 1;            else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS))                return -1;            else                return 0;        }        @Override        public String toString() {            // 打印消息            return message   \" |实行時间:\"   DateFormat.getDateTimeInstance().format(new Date());        }    }}

以上程序流程适用多生产者,实行的結果如下所示:

生产者1,信息序号:1 推送時间:2019-6-12 20:38:37 延迟时间:2 秒 |实行時间:2019-6-12 20:38:39 生产者2,信息序号:2 推送時间:2019-6-12 20:38:37 延迟时间:2 秒 |实行時间:2019-6-12 20:38:39 生产者1,信息序号:3 推送時间:2019-6-12 20:38:41 延迟时间:4 秒 |实行時间:2019-6-12 20:38:45 生产者1,信息序号:5 推送時间:2019-6-12 20:38:43 延迟时间:2 秒 |实行時间:2019-6-12 20:38:45 ……

汇总

序列(Queue)依照是不是堵塞可分成:阻塞队列 BlockingQueue 和 非阻塞队列。在其中,双端队列 Deque 也是非阻塞队列,双端队列除开有着序列的先进先出法的方式以外,还具有自身特有的方式,如 addFirst()、addLast()、getFirst()、getLast() 等,适用首未插进和删掉原素。序列中较为常见的2个序列也有 PriorityQueue(优先级队列)和 DelayQueue(延迟时间序列),可应用延迟时间序列来完成延迟时间线程池,这也是招聘面试中较为常见的问题之一。必须招聘面试好朋友对延迟时间序列一定要保证心里有数,动手能力写一个线程池也是十分需要的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年4月28日 下午1:52
下一篇 2022年4月28日 下午1:54

相关推荐

  • 哪些创业论坛比较好,几个小本创业论坛推荐

    “全民创新,万众创业”大潮中,中国第一部“创业舞剧”诞生了!中国第一部“股权话剧”出世啦!一个刻意不请企业大佬参加的创业论坛举办了!九月二十四日,天使投资机构真格基金在北京主办第二届“真格论坛”。论坛上午以创始人徐小平“领舞”的舞剧《青年.创世纪》揭幕,下午以联合创始人王强主演的“股权话剧”《武林.互联网外传》开场,为此起彼伏的京城各色创业创新论坛,吹来了一股令人捧腹大笑但又能引发思考的“创新”清…

    2022年5月19日
    870
  • 老人用什么智能手机好,老人手机排行榜10强

    有人说:你成功的速度一定要比父母老去的速度快,因为时光不等人,你只有加快的成功才能让父母早日看到你的成就。但是奋斗的过程太过漫长,在努力拼搏的过程中不知不觉就忽略了父母,忘记了他们脸上的皱纹,忘记了他们头上的白发,忘记了他们不再硬朗的身躯。就连寥寥无几的假期也是在东奔西跑中结束,而陪在父母身边的时间又有多少呢? 孝子之养也,乐其心,不违其志。——《礼记》 其实孝敬说大了挺大,说小其实也挺小,除了购…

    2022年7月6日
    610
  • 如何提高智能手机速度,提高手机速度的方法

    现在都在使用智能手机,智能手机给生活带来了更大的方便,但是即使性能再好的智能手机用过一段时间后,都会出现一种烦恼,那就是手机的速度越来越慢,看视频、听音乐、发微信越来越卡,这时候你会认为是手机老化了,或者是手机的寿命到了,准备更换手机,其实,这些都是小问题,和电脑一样,手机也是需要维护的,只有你好好的维护你的手机,手机才能给你最好的回报,以下几个小技巧如果掌握好了,一定给你的手机飞一样的速度。 1…

    2022年7月27日
    600
  • 商标注册怎么在网上申请,网上个人商标办理流程

    以个人名义和以公司名义都是可以注册商标的,但是归属权和使用权都是不一样的,所以在选择商标注册之时要考虑清楚,免得未来惹上一身麻烦。 一、个人申请商标注册的准备资料 1、申请人签名的商标注册申请书。 2、商标图样6张(申请书背面贴1张,交5张),要求图样清晰、规格为长和宽不小于5厘米并不大于10厘米。 3、申请人身份证复印件。 4、个体工商户营业执照复印件。 二、个人申请商标注册的办理流程 1.商标…

    2022年7月14日
    650
  • 什么牌子的手机好用(性能最好的手机推荐)

    导读:盘点目前“最好用”的3款手机,公认的性价比高,免得花冤枉钱! 在进入到2021年以后,各大智能手机厂家都陆续地发布了自己的年度旗舰手机,虽然说2021年因为芯片禁令等原因的影响,导致全球市场都出现了芯片短缺的情况,但是这也丝毫没有影响到各大智能手机厂家的发展计划,如今除了华为手机的销量下滑了不少以外,不少国产手机的销量都出现了逆势增长,这也说明国产手机正在快速的崛起,而在全球手机市场上,销量…

    2022年5月6日
    870
  • 微信号怎么加好友,微信快速加好友软件分享

    朋友认识,都会留个联系方式,方便联络和交流,过去是写个地址,然后留个电话,到现在最常用的,“来,加个微信吧”。 今天我们来分享一下,添加微信好友的2种方式。 方式一:扫码加好友 我们常说扫码扫码,这个码说的就是二维码,每个人的微信号都有一个独立的二维码,大家可以把这个二维码理解为微信给每个人发的一个小身份证。 扫码加好友是两个人操作,老张必须把自己的二维码,就是这个小身份证调出来,老陈用“扫一扫”…

    2022年7月14日
    480
  • 企业微信好用吗,企业微信的优点与缺点

    微信是大家比较熟悉的软件,但是企业微信相信大家都不是很了解。其中,企业微信在职场是比较常见的沟通工具,那么企业微信有什么用呢?下面就和小编一起来文章中具体的了解一下,顺便来说说企业微信和微信区别以及企业微信怎么注册,感兴趣的朋友一起来看看吧。 一、企业微信有什么用 企业微信有什么用?企业微信的用处是非常大的,例如可以实现整个团队的管理,工作汇报,实时沟通工作等到,以下是具体的说明。 1、连接微信 …

    2022年7月4日
    5980
  • 欧莱雅绝配无暇粉底液怎么样(欧莱雅口碑最好的产品之一)

    法国欧莱雅集团是世界上最大的化妆品公司之一,创办于1907年,是美妆行业中的佼佼者,旗下出品的各类产品更是受到国内外消费者的好评,而绝配无暇粉底液就是其中之一。 欧莱雅绝配无瑕粉底液 欧莱雅的这款粉底液一共有3个色系,分别是R1粉瓷色,R2麦其色,N1杏黄色,能完美地贴合亚洲女性的肌肤本色,瞬间融于肌肤,缔造清新自然通透的妆容,还能使肌肤滋润柔滑,是广大亚洲女性消费者的心头爱。 主要功效 柔滑配方…

    2022年9月25日
    630
  • 最新创业项目有哪些(2019特色创业项目分享)

    我们知道,在创业的过程中,如果总是固步自封,一成不变,终会被社会所淘汰。而那些能够突破创新的,总是可以久经不衰。这就证明创新是创业的一部分,且是必不可少的。那么,2019年创业新项目有哪些?下面小编为大家推荐几个不错的项目。 新能源汽车 传统的汽车需要消耗大量的汽油,汽油是一种消耗资源,越用越少,存量稀有不说而且汽油燃烧会生产出许多种有害的气体,危害自然环境和人体健康。新能源汽车不需要汽油,而是只…

    2022年5月20日
    630
  • 免费logo设计在线生成器,logo在线制作教程

    随着互联网技术的飞速发展,人们的生活与网络关系越来越密切。互联网时代可以称之为–E时代,是一种新的生活形态,身处其中的人们可以说是E人类了。作为其中的一分子,我们在充分享受互联网便捷、高效的服务时候,也想利用互联网助力我们的工作和事业,比如,我们可以利用在线网站制作符合自己兴趣、爱好或者行业特点的标识—logo,既便我们不是专业的logo制作美术人员,也同样可以制作较为专业、令自己满意的lo…

    2022年8月27日
    630

发表回复

登录后才能评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信