蚂蚁金服笔试题

Posted ZK_小姜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蚂蚁金服笔试题相关的知识,希望对你有一定的参考价值。

  • 题目一:
    提供一个懒汉模式的单实例类实现。
    要求:
    1.考虑线程安全。
    2.提供测试代码,测试线程安全性。
public class Singleton 
    public Singleton() 
    /**
     * 内部静态类实现单例
     */
    private static class SingletonHolder
        private static final Singleton INSTANCE = new Singleton();
    

    public static Singleton getInstance()
        return SingletonHolder.INSTANCE;
    

    public static void main(String[] args) 
        //测试代码,验证50个线程去获取单例是不是一个实例
        for (int i = 0; i < 50; i++) 
            new Thread(() -> System.out.println(Singleton.getInstance().hashCode())).start();
        
    
  • 题目二
    1.设计含最小函数min()、pop()、push()的栈AntMinStack,存储数据元素为int
    2.AntMinStack中数据存储使用Stack结构
    要求:
    1.AntMinStack实现测试,满足栈特性
    2.要求min、push、pop、的时间复杂度都是O(1)
public class AntMinStack 

    Stack<Integer> stack; //存储值
    Stack<Integer> min;//存储最小值

    public AntMinStack()
        stack = new Stack<>();
        min = new Stack<>();
    

    public void push(int data)
        stack.push(data);
        if (min.isEmpty() || data <= min.peek())
            min.push(data);
        
    
    public int pop() throws Exception
        if (stack.isEmpty())
            throw new Exception("EmptyStackException");
        
        if (stack.peek() == min.peek())
            min.pop();
        
        return stack.pop();
    
    public int min() throws Exception
        if (min.isEmpty())
            throw new Exception("EmptyStackException");
        
        return min.peek();
    

    public static void main(String[] args) throws Exception
        AntMinStack antMinStack = new AntMinStack();
        for (int i = 20; i >= 0; i--) 
            antMinStack.push(i);
            System.out.println("入栈:"+i+",最小值为:"+antMinStack.min());
        
        for (int i = 0; i < 19; i++) 
            System.out.println("出栈:"+antMinStack.pop()+"最小值为:"+antMinStack.min());
        
    
  • 题目三
    假设本地有一个文件夹,文件夹下面有若干文件(文件数大于50小于100),文件的存储格式是文本格式(后缀名是.txt),文件的大小每个文件不会超过100k
    文件格式如下:
    2000102,100,98.32000103,101,73.32000104,102,98.32000105,100,101.32000106,101,45.3……
    文件格式说明:文件每行都由三列构成,第一列是一个id,第二列是分组groupId, 第三列是指标quota。
    id的数据类型是String, groupId的数据类型String, quota的数据类型float。
    功能要求:1.把所有文件里面的内容按照分组进行排序,输出所有文件按照分组升序排序之后,每个分组下面的最小指标值。比如上面的数据输出结果为:100,2000102,98.3101,2000106,45.3102,2000104,98.3
    非功能要求:
    1.文件读取要有线程池来执行,线程池的大小固定为10,文件内容需要存储到指定的内容数据结构当中
    2.查找要求有独立线程来执行,直接消费读取线程池产生的内存数据结构。
    3.文件读取和排序要求并发作业,文件读取只要产生了数据,就可以把数据交给排序线程进行消费,计算最小值。
    代码要求
    1.重上面的要求语意里面抽象出合适的设计模式。
    2.需要考虑多线程的并发控制,同步机制。
    3.代码实现只能用JDK1.6或者1.8自带的工具类
/**  
 *     
 * 生产者线程
 * Author: Administrator   Date: 2018年8月28日  
 *       
 */
public class Producer implements Runnable

    private LinkedBlockingQueue<DataItem> queue;
    private File file;
    private CountDownLatch countDownLatch;
    public Producer(LinkedBlockingQueue<DataItem> queue,File file,CountDownLatch countDownLatch) 
        this.queue = queue;
        this.file = file;
        this.countDownLatch = countDownLatch;
    
    @Override
    public void run() 
        try 
            InputStreamReader read = new InputStreamReader(new FileInputStream(file));
            BufferedReader br=new BufferedReader(read);
            String line="";
            String[] arrs=null;
            while ((line=br.readLine())!=null) 
                if (line.equals("")) 
                    continue;
                
                arrs=line.split(",");
                DataItem dataItem = new DataItem();
                dataItem.setId(arrs[0]);
                dataItem.setGroupId(arrs[1]);
                dataItem.setQuota(new Float(arrs[2]));
                queue.add(dataItem);
            
            br.close();
            read.close();
            countDownLatch.countDown();
         catch (Exception e) 
            e.printStackTrace();
           

    

/**  
 *     
 * 消费者线程
 * Author: Administrator   Date: 2018年8月28日  
 *       
 */
public class Consumer implements Runnable

    private LinkedBlockingQueue<DataItem> queue;
    private TreeMap<String, DataItem> treeMap;
    private CountDownLatch countDownLatch;
    public Consumer(LinkedBlockingQueue<DataItem> queue,TreeMap<String, DataItem> treeMap,CountDownLatch countDownLatch) 
        this.queue = queue;
        this.treeMap = treeMap;
        this.countDownLatch = countDownLatch;
    
    @Override
    public void run() 
        try 
            while(true)
                if (!queue.isEmpty()) 
                    DataItem dataItem = queue.take();
                    DataItem mydataItem = treeMap.get(dataItem.getGroupId());
                    if (mydataItem == null) 
                        treeMap.put(dataItem.getGroupId(), dataItem);
                    else
                        if (dataItem.getQuota() < mydataItem.getQuota()) 
                            treeMap.put(dataItem.getGroupId(), dataItem);
                        
                    
                else
                    if(countDownLatch.getCount() <= 1)
                        countDownLatch.countDown();
                        break;
                    
                

            
         catch (Exception e) 
            e.printStackTrace();
        

    

/**  
 *     
 * 数据仓库
 * Author: Administrator   Date: 2018年8月29日  
 *       
 */
public class DataWareHouse 

    private static final int THREAD_POOL_SIZE = 10;
    private LinkedBlockingQueue<DataItem> queue;//缓存生产者线程从文件读取的数据
    private TreeMap<String, DataItem> treeMap;//存储消费者线程处理后的数据(排序、获取同组指标最小的数据)
    private ExecutorService threadPool;//线程池
    public DataWareHouse() 
        queue = new LinkedBlockingQueue<>();
        treeMap = new TreeMap<>(new Comparator<String>() 

            @Override
            public int compare(String o1, String o2) 
                return Long.valueOf(o1).compareTo(Long.valueOf(o2));
            
        );
        threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    
    public LinkedBlockingQueue<DataItem> getQueue() 
        return queue;
    
    public void setQueue(LinkedBlockingQueue<DataItem> queue) 
        this.queue = queue;
    
    public TreeMap<String, DataItem> getTreeMap() 
        return treeMap;
    
    public void setTreeMap(TreeMap<String, DataItem> treeMap) 
        this.treeMap = treeMap;
    
    public ExecutorService getThreadPool() 
        return threadPool;
    
    public void setThreadPool(ExecutorService threadPool) 
        this.threadPool = threadPool;
    

/**  
 *     
 *  
 * Author: Administrator   Date: 2018年8月28日  
 *       
 */
public class DataItem 

    /**
     * id
     */
    private String id;
    /**
     * 分组
     */
    private String groupId;
    /**
     * 指标
     */
    private Float quota;

    public String getId() 
        return id;
    
    public void setId(String id) 
        this.id = id;
    
    public String getGroupId() 
        return groupId;
    
    public void setGroupId(String groupId) 
        this.groupId = groupId;
    
    public Float getQuota() 
        return quota;
    
    public void setQuota(Float quota) 
        this.quota = quota;
    

public class Main 

    public static void main(String[] args) 
        String dirPath = "src/main/resources/files";
        File dirFile = new File(dirPath);
        File[] files = dirFile.listFiles();
        DataWareHouse dataWareHouse = new DataWareHouse();
        CountDownLatch countDownLatch = new CountDownLatch(files.length + 1);
        for(File file : files)
            Producer producer = new Producer(dataWareHouse.getQueue(), file,countDownLatch);
            //生产者线程使用线程池
            dataWareHouse.getThreadPool().execute(producer);
        
        Consumer consumer = new Consumer(dataWareHouse.getQueue(), dataWareHouse.getTreeMap(),countDownLatch);
        //一个消费者线程消费
        new Thread(consumer).start();
        try 
            //生产者线程和消费者线程执行完成,关闭线程池,输出结果
            countDownLatch.await();
            dataWareHouse.getThreadPool().shutdownNow();
         catch (Exception e) 
            e.printStackTrace();
        
        Iterator<Entry<String, DataItem>> it = dataWareHouse.getTreeMap().entrySet().iterator();
        while(it.hasNext()) 
            Entry<String, DataItem> entry = it.next();
            DataItem dataItem = entry.getValue();
            System.out.println(dataItem.getGroupId() + "," + dataItem.getId()+","+dataItem.getQuota());
        
    
/**     
 * 创建测试数据
 * @author jiangpan 
 * @title CreateDataTest.java
 * @date 2018年8月29日 
 *     
 */
public class CreateDataTest 

    public static void main(String[] args) throws IOException 
        String path = "src/main/resources/files/";
        for (int i = 1; i < 100; i++) 
            File file = new File(path+i+".txt");
            if(!file.exists())
                file.createNewFile();
            
            FileWriter fileWriter = new FileWriter(file);
            BufferedWriter br = new BufferedWriter(fileWriter);
            for (int j = 0; j < 5000; j++) 
                br.write(getRandomData());
                br.newLine();
            
            br.close();
            fileWriter.close();

        
        System.out.println("success");
    

    private static String getRandomData()
        Integer id = (int)(Math.random() * 1000000) + 1000000;
        Integer groupId = (int)(Math.random() * 1000) + 100;
        Float quota = (int)(Math.random() * 1000)/10.0f+60;
        return id+","+groupId+","+quota;
    

以上是关于蚂蚁金服笔试题的主要内容,如果未能解决你的问题,请参考以下文章

2019 蚂蚁金服java面试笔试题 (含面试题解析)

最新JAVA面试合集:熬夜整理蚂蚁金服Java高级笔试题

前端面试(蚂蚁金服笔试)

蚂蚁金服测试开发工程师面试

31岁大龄程序员竟然拿到了蚂蚁金服offer,竟然是熬夜吃透300道Java面试题手册

蚂蚁金服换将!新任CEO:区块链是蚂蚁金服金融科技应用底盘之一