java面经查缺补漏之三十六天(前天面试完美团,不知道是否凉凉,今天主要学生产者消费者模型)

1.手写一个生产者消费者模型?

参考:https://blog.csdn.net/u010983881/article/details/78554671?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4

查了一下,这篇讲的是最好的!一共有三种方式,阻塞队列,synchronized的,lock的

最简单的一个,基于阻塞队列的:

import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;

public class producerByBq {
    private static final int CAPACITY = 5;
    public static void main(String[] args)
    {
        LinkedBlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>(CAPACITY);
        Thread producer1 = new producer("P-1", blockingQueue);
        Thread producer2 = new producer("P-2", blockingQueue);
        Thread consumer1 = new consumer("C1", blockingQueue);
        Thread consumer2 = new consumer("C2", blockingQueue);
        Thread consumer3 = new consumer("C3", blockingQueue);
        producer1.start();
        producer2.start();
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }
    public static class producer extends Thread
    {
        private LinkedBlockingQueue<Integer> blockingQueue;
        private String name;
        private int i=0;
        public producer(String name,LinkedBlockingQueue<Integer> blockingQueue)
        {
            //这个supername是干什么的
            super(name);
            this.blockingQueue=blockingQueue;
            this.name=name;
        }
        public void run()
        {
            while(true)
            {
                try {
                    blockingQueue.put(i);
                    System.out.println("[" + name + "] Producing value : +" + i);
                    i++;
                    Thread.sleep(new Random().nextInt(1000));
                }catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }

    }
    public static class consumer extends Thread
    {
        private LinkedBlockingQueue<Integer> blockingQueue;
        private String name;
        public consumer(String name,LinkedBlockingQueue<Integer> blockingQueue)
        {
            super(name);
            this.blockingQueue=blockingQueue;
            this.name=name;
        }
        public void run()
        {
            while(true)
            {
                try {
                    int x=blockingQueue.take();
                    System.out.println("[" + name + "] Consuming : " + x);
                    Thread.sleep(new Random().nextInt(1000));
                }catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

第二个,基于synchronized的

import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

public class producerBySyn {
    private static final int CAPACITY = 5;
    public static void main(String[] args)
    {
        Queue<Integer> queue = new LinkedList<Integer>();
        Thread producer1 = new producer("P-1", queue,CAPACITY);
        Thread producer2 = new producer("P-2", queue,CAPACITY);
        Thread consumer1 = new consumer("C1", queue);
        Thread consumer2 = new consumer("C2", queue);
        Thread consumer3 = new consumer("C3", queue);
        producer1.start();
        producer2.start();
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }
    public static class producer extends Thread
    {
        private final Queue<Integer> queue;
        private String name;
        private int maxSize;
        private int i=0;
        public producer(String name,Queue<Integer> queue,int maxSize)
        {
            super(name);
            this.queue=queue;
            this.name=name;
            this.maxSize=maxSize;
        }
        public void run()
        {
            while(true)
            {
                synchronized (queue)
                {
                    while(queue.size()==maxSize)
                    {
                        try {
                            System.out .println("Queue is full, Producer[" + name + "] thread waiting for " + "consumer to take something from queue.");
                            queue.wait();
                        }catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("[" + name + "] Producing value : +" + i);
                    queue.offer(i++);
                    queue.notifyAll();
                    try {
                        Thread.sleep(new Random().nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }
    public static class consumer extends Thread
    {
        private final Queue<Integer> queue;
        private String name;
        public consumer(String name,Queue<Integer> queue)
        {
            super(name);
            this.queue=queue;
            this.name=name;
        }
        public void run()
        {
            while(true)
            {
                synchronized (queue)
                {
                    while(queue.size()==0)
                    {
                        try {
                            System.out.println("Queue is empty, Consumer[" + name + "] thread is waiting for Producer");
                            queue.wait();
                        }catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                    int x = queue.poll();
                    System.out.println("[" + name + "] Consuming value : " + x);
                    queue.notifyAll();
                    try {
                        Thread.sleep(new Random().nextInt(1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

 第三个,基于Lock和condition的

import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class producerByLock {
    private static final int CAPACITY = 5;
    private static final Lock lock = new ReentrantLock();
    private static final Condition fullCondition = lock.newCondition();     //队列满的条件
    private static final Condition emptyCondition = lock.newCondition();        //队列空的条件
    public static void main(String[] args)
    {
        Queue<Integer> queue = new LinkedList<Integer>();
        Thread producer1 = new producer("P-1", queue,CAPACITY);
        Thread producer2 = new producer("P-2", queue,CAPACITY);
        Thread consumer1 = new consumer("C1", queue);
        Thread consumer2 = new consumer("C2", queue);
        Thread consumer3 = new consumer("C3", queue);
        producer1.start();
        producer2.start();
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }
    public static class producer extends Thread
    {
        private final Queue<Integer> queue;
        private String name;
        private int maxSize;
        private int i=0;
        public producer(String name,Queue<Integer> queue,int maxSize)
        {
            super(name);
            this.queue=queue;
            this.name=name;
            this.maxSize=maxSize;
        }
        public void run()
        {
            while(true)
            {
                lock.lock();
                while(queue.size() == maxSize){
                    try {
                        System.out .println("Queue is full, Producer[" + name + "] thread waiting for " + "consumer to take something from queue.");
                        //条件不满足,生产阻塞
                        fullCondition.await();
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
                System.out.println("[" + name + "] Producing value : +" + i);
                queue.offer(i++);

                //唤醒其他所有生产者、消费者
                fullCondition.signalAll();
                emptyCondition.signalAll();

                //释放锁
                lock.unlock();

                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    public static class consumer extends Thread
    {
        private final Queue<Integer> queue;
        private String name;
        public consumer(String name,Queue<Integer> queue)
        {
            super(name);
            this.queue=queue;
            this.name=name;
        }
        public void run()
        {
            while(true)
            {
                lock.lock();

                while(queue.isEmpty()){
                    try {
                        System.out.println("Queue is empty, Consumer[" + name + "] thread is waiting for Producer");
                        //条件不满足,消费阻塞
                        emptyCondition.await();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                int x = queue.poll();
                System.out.println("[" + name + "] Consuming value : " + x);

                //唤醒其他所有生产者、消费者
                fullCondition.signalAll();
                emptyCondition.signalAll();

                //释放锁
                lock.unlock();

                try {
                    Thread.sleep(new Random().nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.Java多线程notify/notifyAll唤醒的是谁?

参考:https://blog.csdn.net/q5706503/article/details/84591159

3.什么是时间片轮转?

时间片轮转说的是操作系统的一种调度算法,用于交互式系统,每一个进程都给分配一个时间片,然后进行快速的切换,但是速度很快,人看不到这些切换。另外还有优先级调度算法,多级反馈队列算法(既有优先级又有时间片)

4.什么是分布式事务?

参考:https://blog.csdn.net/bjweimengshu/article/details/79607522

分布式事务用于在分布式系统中保证不同节点之间的数据一致性。

XA两阶段提交:

(1)在XA分布式事务的第一阶段,作为事务协调者的节点会首先向所有的参与者节点发送Prepare请求。在接到Prepare请求之后,每一个参与者节点会各自执行与事务有关的数据更新,写入Undo Log和Redo Log。如果参与者执行成功,暂时不提交事务,而是向事务协调节点返回“完成”消息。当事务协调者接到了所有参与者的返回消息,整个分布式事务将会进入第二阶段。

(2)作为事务协调者的节点给所有事务参与者发出Commit请求。接到Commit请求之后,事务参与者节点会各自进行本地的事务提交,并释放锁资源。当本地事务完成提交后,将会向事务协调者返回“完成”消息。当事务协调者接收到所有事务参与者的“完成”反馈,整个分布式事务完成。

在XA的第一阶段,如果某个事务参与者反馈失败消息,说明该节点的本地事务执行不成功,必须回滚。

于是在第二阶段,事务协调节点向所有的事务参与者发送Abort请求。接收到Abort请求之后,各个事务参与者节点需要在本地进行事务的回滚操作,回滚操作依照Undo Log来进行。

5.常见的负载均衡算法?

(1)轮询
将所有请求,依次分发到每台服务器上,适合服务器硬件相同的场景。
优点:服务器请求数目相同;

缺点:服务器压力不一样,不适合服务器配置不同的情况;

(2)随机
请求随机分配到各台服务器上。
优点:使用简单;

缺点:不适合机器配置不同的场景

(3)最少链接
将请求分配到连接数最少的服务器上(目前处理请求最少的服务器)。
优点:根据服务器当前的请求处理情况,动态分配;

缺点:算法实现相对复杂,需要监控服务器请求连接数;

(4)Hash(源地址散列)
根据IP地址进行Hash计算,得到IP地址。
优点:将来自同一IP地址的请求,同一会话期内,转发到相同的服务器;实现会话粘滞。

缺点:目标服务器宕机后,会话会丢失;

(5)加权
在轮询,随机,最少链接,Hash等算法的基础上,通过加权的方式,进行负载服务器分配。

优点:根据权重,调节转发服务器的请求数目;

缺点:使用相对复杂;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章