分享一道蚂蚁金服的面试题

简介: 随着nums的增大,Lock+Condition的运行时长比Semaphore越短。看起来Lock+Condition的性能更好些。

这是一道蚂蚁金服二面的编程题


题目:交替打印零与奇偶数


给定一个数nums,然后交替打印出奇偶数。输出的长度为2nums,

你应该:至少用两种方法实现,并分析出优劣势。


举例:

输入:nums = 3

输出: "010203"


这道题与我之前分享的另外一道比较像 题目在这里 :阿里面试题分享(二)

但实际上比那道要简单些。因为没有要求写几个线程。


第一种解法:Lock+Condition


package com.oho.alg;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintNums {
  public final Lock lock = new ReentrantLock();
  public Condition c0 = lock.newCondition();
  public Condition c1 = lock.newCondition();
  public int flag = 0;
  private void print0(int num) {
    lock.lock();
    try {
      for (int i = 1; i <= num; i++) {
        if (flag == 0) {
          System.out.print(0);
          flag = 1;
          c1.signal();
          c0.await();
        }
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  private void print(int num) {
    lock.lock();
    try {
      for (int i = 1; i <= num; i++) {
        if (flag == 1) {
          System.out.print(i);
          flag = 0;
          c0.signal();
          if (i < num) {
            c1.await();
          }
        }
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  public void printNumsWithNum(int num) {
    long start = System.currentTimeMillis();
    Thread t1 = new Thread(() -> print0(num));
    Thread t2 = new Thread(() -> print(num));
    t1.start();
    t2.start();
    try {
      t1.join();
      t2.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println();
    System.out.println("===============================================");
    System.out.println("运行时长: " + (System.currentTimeMillis() - start));
  }
  public static void main(String[] args) {
    new PrintNums().printNumsWithNum(10);
  }
}


第二种解法:Semaphore


package com.oho.alg;
import java.util.concurrent.Semaphore;
public class PrintNumsUseSemaphore {
  public Semaphore s1 = new Semaphore(1);
  public Semaphore s2 = new Semaphore(0);
  private void print0(int num) {
    try {
      for (int i = 1; i <= num; i++) {
        //获取信号量,s1 - 1
        s1.acquire();
        System.out.print(0);
        //释放信号量,s2 + 1
        s2.release();
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  private void print(int num) {
    try {
      for (int i = 1; i <= num; i++) {
        //获取信号量,s2 - 1
        s2.acquire();
        System.out.print(i);
        //释放信号量,s1 + 1
        s1.release();
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  public void printNumsWithNum(int num) {
    long start = System.currentTimeMillis();
    Thread t1 = new Thread(() -> print0(num));
    Thread t2 = new Thread(() -> print(num));
    t1.start();
    t2.start();
    try {
      t1.join();
      t2.join();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println();
    System.out.println("===============================================");
    System.out.println("运行时长: " + (System.currentTimeMillis() - start));
  }
  public static void main(String[] args) {
    new PrintNumsUseSemaphore().printNumsWithNum(10);
  }
}


优劣势的话,如果在比较小的数据量下看不出来,我用nums = 800000,进行了测试:

Lock+Condition
运行时长: 9588 毫秒
Semaphore 运行时长: 9013 毫秒


随着nums的增大,Lock+Condition的运行时长比Semaphore越短。看起来Lock+Condition的性能更好些。至于为什么,因为涉及到锁的原理,这里就不多了,需要大家去看看源码,翻翻资料了。

相关文章
|
2月前
|
存储 前端开发 架构师
阿里资深架构师带你深入浅出JVM!
JVM = 类加载器(classloader) + 执行引擎(execution engine) + 运行时数据区域(runtime data area)
42 1
|
4月前
|
NoSQL Java 关系型数据库
阿里P7Java最全面试296题:阿里天猫、蚂蚁金服含答案文档解析
阿里天猫、蚂蚁、钉钉面试专题题目加答案】 不会做别着急:文末有答案以及视频讲解,架构师资料 1. junit用法,before,beforeClass,after, afterClass的执行顺序 2. 分布式锁
|
4月前
|
NoSQL Java 应用服务中间件
阿里巴巴最新最全500道Java后端面试大全(值得收藏)
进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全其中概括的知识点有:Java基础、spring、springmvc、springboot、springcloud、JVM、Tomcat、dubbo、netty、zookeeper共有500+道面试题
|
4月前
|
NoSQL 算法 Java
五面阿里技术专家岗,已拿offer,这些面试题你能答出多少
在面试前三面真的有点急促,一周内就面完了三次面试,接着就开始无尽的等待,整整等了三周左右,终于完成了四面和HR面。整个过程还是比较曲折的,技术面试还是挺考察技术深度的。现在已拿到offer。
阿里巴巴2022年最新最全500道Java后端面试大全(值得收藏)
进大厂是大部分程序员的梦想,而进大厂的门槛也是比较高的,所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全其中概括的知识点有:Java基础、spring、springmvc、springboot、springcloud、JVM、Tomcat、dubbo、netty、zookeeper共有500+道面试题 面试题整理十分全面,文末还有答案解析!(文章比较长,耐心看完,让你面试提升一大截!)
|
11月前
|
移动开发 前端开发 JavaScript
大厂面试-阿里
大厂面经-阿里
162 0
|
消息中间件 SQL NoSQL
再记一次止于三面的阿里面试之旅
Hello 大家好,我是阿粉,最近心情不是很好,因为阿粉面试阿里三面挂掉了, 当收到下面这封邮件的时候阿粉内心是拔凉拔凉的。阿粉被 “Unfortunately”,“another candidate” 这几个词深深的伤害到了。不过伤心归伤心,该自我总结还是得自我总结的,有机会再战。
阿里面试题分享(二)
synchronized与wait()和nitofy()/notifyAll()方法相结合可以实现等待/通知模型,ReentrantLock同样可以,但是需要借助Condition,且Condition有更好的灵活性,
阿里面试题分享(二)
|
消息中间件 云安全 运维
我们找阿里云资深技术专家李响聊了聊开源和云原生
在第十五届“开源中国开源世界”高峰论坛上,阿里云资深技术专家、etcd 创始人、CNCF TOC(Technical Oversight Committee,简称TOC)李响荣获2020中国开源杰出人物贡献奖。恭喜李响!
652 0
我们找阿里云资深技术专家李响聊了聊开源和云原生