朋熙面试(部分)

一面

  • Spring源码有什么可借鉴之处?Spring bean的生命周期?Spring容器近似是个什么数据结构?A:Spring容器是一个Map类型的数据结构,其中key是Bean的名称,value是Bean的实例。

  • 索引优化应该从哪些方面考虑?Answer by newBing:
    首先应考虑在 where 及 order by涉及的列上建立索引;
    应尽量避免在 where 子句中使用 !=或<> 操作符,否则将引擎放弃使用索引而进行全表扫描;
    索引长度以及区分度;
    联合索引需要考虑索引先后顺序(最左前缀匹配);
    索引覆盖是指,如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据(即避免回表)。

  • Reentrantlock公平锁、非公平锁。相关知识:本博----一些AQS相关的知识

  • 为什么不同的隔离级别读到的数据不一样?了解MySQL MVCC的Read View吗?相关知识可参考本博----《高性能Mysql 第三版》笔记中MVCC的部分

  • 数据库如何回滚?A:undo log. Q: 如果你来设计undo log,你怎么做? 参考上个回答中的内容

  • kafka的消息,是按什么算法,决定它被分配到哪个partition的?参考答案1,2
    If a partition is specified in the record, use it 指定了partition,则消息投递到指定的partition
    If no partition is specified but a key is present choose a partition based on a hash of the key 未指定partition,但指定了key, 则基于hash(key)取模选择一个分区
    If no partition or key is present choose a partition in a round-robin fashion 分区编号和key均未指定,则轮询选择,round-robin

二面

  • 两个线程同时对HashMap进行写操作,会有什么线程安全的问题吗?举例说明。后面在聊ConcurrentHashMap在JDK1.8之后锁的变化,我聊到锁粒度变小,面试官问有没有粒度变大的情形,比如扩容时?结合3等文和面试官最后的总结来看,应该是没有
  • synchronized锁升级过程。Q:锁升级的意义?为什么没有锁降级?相关知识:我还是倾向于认为没有锁降级,从https://segmentfault.com/q/1010000020803904来看有过锁降级的提案 JEP draft: Concurrent Monitor Deflation,但是似乎被否了。
  • Monitor。相关知识4在这里插入图片描述
    通俗来说就是调用了wait()方法的线程就会进入waitset。(下图来自 https://www.artima.com/insidejvm/ed2/threadsynch.html,有时间可看看)。但是对比了JavaGuide pdf中的《Java 线程状态变迁图》后,感觉下图有点小问题,wait set中的线程被notify/notifyAll唤醒后,不一定能抢到锁,如果没有就应该进入此图中的Entry Set:
    在这里插入图片描述
    在这里插入图片描述

注:OS线程中的Running、Ready两状态都对应于Java线程中的Runnable状态。

5这里提个会使人困惑的问题: 使用socket时,调用accept(),read() 等阻塞方法时,线程处于什么状态?
答案是java线程处于RUNNABLE状态,OS线程处于WAITING状态。因为在jvm层面,等待cpu时间片和等待io资源是等价的。

扩展与类比:接口java.util.concurrent.locks.Condition的注释:

Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations.Where a Lock replaces the use of synchronized methodsand statements, a Condition replaces the use of the Object monitor methods.

  • AQS的原理?除了CLH同步队列,没有其它队列吗?参考答案6:条件队列。更准确点应该是Lock的Condition会有条件队列。
    类AbstractQueuedSynchronizer里的static final class Node是CLH同步队列的结点类,从下面Node类的一段注释,以及AQS里用到的ConditionObject类的代码都可以看出,它同时也是条件队列的结点类:

Threads waiting on Conditions use the same nodes, but use an additional link. Conditions only need to link nodes in simple (non-concurrent) linked queues because they are only accessed when exclusively held. Upon await, a node is inserted into a condition queue. Upon signal, the node is transferred to the main queue. A special value of status field is used to mark which queue a node is on.

 public class ConditionObject implements Condition, java.io.Serializable {
        ...
        /** First node of condition queue. */
        private transient Node firstWaiter;
        /** Last node of condition queue. */
        private transient Node lastWaiter;

        ...

        /**
         * Adds a new waiter to wait queue.
         * @return its new wait node
         */
        private Node addConditionWaiter() {
            if (!isHeldExclusively())
                throw new IllegalMonitorStateException();
            Node t = lastWaiter;
            // If lastWaiter is cancelled, clean out.
            if (t != null && t.waitStatus != Node.CONDITION) {
                unlinkCancelledWaiters();
                t = lastWaiter;
            }

            Node node = new Node(Node.CONDITION);

            if (t == null)
                firstWaiter = node;
            else
                t.nextWaiter = node;
            lastWaiter = node;
            return node;
        }

		...
        public final void await() throws InterruptedException {
            if (Thread.interrupted())
                throw new InterruptedException();
            Node node = addConditionWaiter();
            ...
        }

Condition的条件队列像极了Monitor的Wait Set。区别是Condition更灵活,因为一个Lock可以有多个Condition,也就可以有多条条件队列,但是一个Monitor有且只有一个Wait Set。唯一的疑惑是Condition.await方法是否会删除同步队列里的头节点。从代码和注释里我没有找到删除的证据,但是我倾向于删了,因为这动作事实上会造成该线程阻塞,似乎不应该再留它当头节点。而且上段引用中提到:A special value of status field is used to mark which queue a node is on,而static final int CONDITION的注释为 /** waitStatus value to indicate thread is waiting on condition. */

    • BlockingQueue的offer方法,底层如何实现的?相关知识:ArrayBlockingQueue的源码:一个Lock及它的两个Condition:
    final ReentrantLock lock;

    /** Condition for waiting takes */
    private final Condition notEmpty;

    /** Condition for waiting puts */
    private final Condition notFull;
    ...
    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();
    }
    • 线程池应该用ArrayBlockingQueue还是LinkedBlockingQueue好?相关知识:LinkedBlockingQueue相对于ArrayBlockingQueue来说,具有更高的吞吐量,因为它实现了更加细粒度的锁操作。LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费用的是takeLock。这样可以在高并发情况下减少锁竞争,提高吞吐量。LinkedBlockingQueue缺点在于没有限定长度,有内存溢出风险
  • 一个接口响应慢,可能是哪些原因?网络延迟、数据库负载过高、代码问题、缓存失效、第三方服务故障、被限速等.

  • 有遇到过MQ消息堆积的情况吗

主管面


  1. 本博----《专题四 服务化改造》之《第三章 【补充资料】常见消息中间件应用详解》之《第十节 Kafka》 ↩︎

  2. kafka-partition分配的策略 ↩︎

  3. 深入解析ConcurrentHashMap:感受并发编程智慧 ↩︎

  4. Java并发编程之Monitor工作原理(有图解) ↩︎

  5. Java 锁与线程的那些事 - 有赞技术团队 ↩︎

  6. AQS之条件队列Condition (更推荐,含实例等)
    AQS同步队列与条件队列的关系 ↩︎

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_23204557

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值