小米java开发二面复盘|发面经赞人品,求二面能过

二面(90min)

1.自我介绍
2.介绍项目
3.针对项目各种框架的问题
4.springMVC请求流程(不会,答适配器模式,json互相转换,就硬扯)
5.springboot自动配置原理(好多次问到我这个了,我是真的不会呀,八股文一背就会,一说就废)
6.spring事务(答,声明式事务,用一个注解就行了)
7.事务隔离级别(唯一会的一个)
8.事务传播途径(只知道required,其它都不清楚...)
9.事务回滚方式
10.定义了事务但是事务失效的场景(刚好项目碰到了,balabala了一堆)
11.aop
12.拦截器原理(不会)
13.mybatis插件管理(不会,只知道可以集成pagehelper这种插件,原理瞎扯了个过滤器)
14.mybatis动态SQL原理(不会)
15.Dubbo调用过程
16.已经在zookeeper中注册了的类,再次注册会怎样(知识盲区,不会)
17.Redis的5种数据类型以及底层数据结构
18.Redis持久化
19.分布式锁
------------------上面涉及到框架问题问了25分钟,基本都不会-----------------------

---------------开始问java基础了,终于可以不用一直沉默了----------------------------

1.ArrayList和LinkedList的区别和应用场景
2.上面的两个集合对应的线程安全类
3.LinkedBlockQueue源码
4.CopyOnWriteArrayList源码
5.HashMap源码
6.ConcurrentHashMap源码
7.问多线程了解吗(因为框架答得不好,就说了精通多线程,哈哈哈,头铁)
8.线程创建方式
9.FutureTask如何获取返回值
10.Java线程生命周期和操作系统生命周期
11.多线程的debug
12.如何解决并发问题
13.AQS源码
14.公平锁,非公平锁,可重入锁,不可重入锁怎么设计的
15.CountDownLatch源码
---------------------------上面问题持续25分钟------------------------

1.因为你说精通多线程了,那我就不考你算法了,手写一个线程池(???)

最后写了接近40分钟差不多写完了,中途面试官提了很多要求,写的快崩溃了

最后反问环节问了小米的主要业务场景

贴一份后来修改了1小时的代码

public class BlockingQueue<T> {
    // 1. 任务队列
    private Deque<T> queue = new ArrayDeque<>();
    // 2. 锁
    private ReentrantLock lock = new ReentrantLock();
    // 3. 生产者条件变量
    private Condition fullWaitSet = lock.newCondition();
    // 4. 消费者条件变量
    private Condition emptyWaitSet = lock.newCondition();
    // 5. 容量
    private int capcity;

    public BlockingQueue(int capcity) {
        this.capcity = capcity;
    }

    // 带超时阻塞获取
    public T poll(long timeout, TimeUnit unit) {
        lock.lock();
        try {
            // 将 timeout 统一转换为 纳秒
            long nanos = unit.toNanos(timeout);
            while (queue.isEmpty()) {
                try {
                    // 返回值是剩余时间
                    if (nanos <= 0) {
                        return null;
                    }
                    nanos = emptyWaitSet.awaitNanos(nanos);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            T t = queue.removeFirst();
            fullWaitSet.signal();
            return t;
        } finally {
            lock.unlock();
        }
    }

    // 阻塞获取
    public T take() {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                try {
                    emptyWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            T t = queue.removeFirst();
            fullWaitSet.signal();
            return t;
        } finally {
            lock.unlock();
        }
    }

    // 阻塞添加
    public void put(T task) {
        lock.lock();
        try {
            while (queue.size() == capcity) {
                try {
                    System.out.println("等待加入任务队列 {" + task + "} ...");
                    fullWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("加入任务队列 {" + task + "}");
            queue.addLast(task);
            emptyWaitSet.signal();
        } finally {
            lock.unlock();
        }
    }

    // 带超时时间阻塞添加
    public boolean offer(T task, long timeout, TimeUnit timeUnit) {
        lock.lock();
        try {
            long nanos = timeUnit.toNanos(timeout);
            while (queue.size() == capcity) {
                try {
                    if (nanos <= 0) {
                        return false;
                    }
                    System.out.println("等待加入任务队列 {" + task + "} ...");
                    nanos = fullWaitSet.awaitNanos(nanos);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("加入任务队列 {" + task + "}");
            queue.addLast(task);
            emptyWaitSet.signal();
            return true;
        } finally {
            lock.unlock();
        }
    }

    public int size() {
        lock.lock();
        try {
            return queue.size();
        } finally {
            lock.unlock();
        }
    }

    public void tryPut(RejectPolicy<T> rejectPolicy, T task) {
        lock.lock();
        try {
            // 判断队列是否满
            if (queue.size() == capcity) {
                rejectPolicy.reject(this, task);
            } else { // 有空闲
                System.out.println("加入任务队列 {" + task + "}");
                queue.addLast(task);
                emptyWaitSet.signal();
            }
        } finally {
            lock.unlock();
        }
    }
}

public class ThreadPool {
    // 任务队列
    private BlockingQueue<Runnable> taskQueue;
    // 线程集合
    private HashSet<Worker> workers = new HashSet<>();
    // 核心线程数
    private int coreSize;
    // 获取任务时的超时时间
    private long timeout;
    private TimeUnit timeUnit;
    private RejectPolicy<Runnable> rejectPolicy;

    // 执行任务
    public void execute(Runnable task) {
        // 当任务数没有超过 coreSize 时,直接交给 worker 对象执行
        // 如果任务数超过 coreSize 时,加入任务队列暂存
        synchronized (workers) {
            if (workers.size() < coreSize) {
                Worker worker = new Worker(task);
                System.out.println("新增 worker{" + worker + "}, {" + task + "}");
                workers.add(worker);
                worker.start();
            } else {
                // taskQueue.put(task);
                // 1) 死等
                // 2) 带超时等待
                // 3) 让调用者放弃任务执行
                // 4) 让调用者抛出异常
                // 5) 让调用者自己执行任务
                taskQueue.tryPut(rejectPolicy, task);
            }
        }
    }

    public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit, int queueCapcity,
                      RejectPolicy<Runnable> rejectPolicy) {
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.taskQueue = new BlockingQueue<>(queueCapcity);
        this.rejectPolicy = rejectPolicy;
    }

    class Worker extends Thread {
        private Runnable task;

        public Worker(Runnable task) {
            this.task = task;
        }

        @Override
        public void run() {
            // 执行任务
            // 1) 当 task 不为空,执行任务
            // 2) 当 task 执行完毕,再接着从任务队列获取任务并执行
            // while(task != null || (task = taskQueue.take()) != null) {
            while (task != null || (task = taskQueue.poll(timeout, timeUnit)) != null) {
                try {
                    System.out.println("正在执行...{" + task + "}");
                    task.run();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    task = null;
                }
            }
            synchronized (workers) {
                System.out.println("worker 被移除{" + this + "}");
                workers.remove(this);
            }
        }
    }
}

@FunctionalInterface // 拒绝策略
interface RejectPolicy<T> {
    void reject(BlockingQueue<T> queue, T task);
}
#小米面试##面经##小米##java工程师#

注意!此信息未认证,请谨慎判断信息的真实性!

全部评论
空

相关内容推荐

头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
2022-12-11 21:41
点赞 评论 收藏
转发
头像
2022-12-22 14:03
南京大学_2022
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像 头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
头像
点赞 评论 收藏
转发
2 11 评论
分享

全站热榜

正在热议