达美乐的面试(部分)(未完全解析)

14 篇文章 0 订阅
9 篇文章 0 订阅
  • Java如何保证非线程安全的数据结构(比如HashMap)的原子性?读多写少时用哪种锁好? A: 方法1:CAS等乐观锁机制,方法2:如果读多写少,可以使用读写锁(ReentrantReadWriteLock)
  • 如何判断线上程序发生死锁?参考答案:jstack。Q:jstack具体如何操作和分析?
    实操答案(系统Windows10, 本文基本参考1):
    Java代码:
public class DeadLockCase {
    public static void main(String[] args){
        Object o1 = new Object();
        Object o2 = new Object();
        new Thread(new SyncThread(o1, o2),  "t1").start();
        new Thread(new SyncThread(o2, o1),  "t2").start();
    }

    static class SyncThread implements Runnable {
        private Object lock1;
        private Object lock2;

        public SyncThread(Object o1, Object o2){
            this.lock1 = o1;
            this.lock2 = o2;
        }

        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            System.out.println(name + " acquiring lock on " + lock1);
            synchronized (lock1) {
                System.out.println(name + " acquired lock on " + lock1);
                work();
                System.out.println(name + " acquiring lock on " + lock2);
                synchronized (lock2) {
                    System.out.println(name + " acquired lock on " + lock2);
                    work();
                }
                System.out.println(name + " released lock on " + lock2);
            }
            System.out.println(name + " released lock on " + lock1);
        }

        private void work() {
            try {
                //模拟死锁的关键,保证线程1只能获取一个锁,而线程2能获取到另一个锁
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 用jps命令查看当前系统中所有正在运行的 Java 进程,以及这些进程的 PID 等信息:jps -l:
    在这里插入图片描述
  2. jstack <pid>命令可以输出对应Java进程的线程快照信息:
    运行jstack 10524 后得到的部分关键结果的截屏如下两图。可以看到各线程的状态、线程已占用的锁和正申请的锁、以及死锁信息。
    在这里插入图片描述
    。。。
    在这里插入图片描述
  • 如何解决RabbitMQ重复消费的问题

  • spring有个注解@Async能实现异步处理,有用过吗?Answer by new bing: 是的,@Async注解可以让Spring中的方法异步执行。使用该注解后,Spring会将该方法放到一个线程池中执行,而不是在调用该方法的线程中执行。这样可以避免阻塞调用线程,提高系统的并发能力。

  • 起一个线程耗多少内存,可以通过JVM的什么参数来控制吗? Answer by new bing: 可以使用-Xss参数来设置每个线程的栈大小。默认情况下,每条线程的栈大小为1M。

  • Spring事务传播机制。我有一个业务类,它有两个方法,方法A是REQUIRED,方法B是REQUIRES_NEW,方法A调用方法B,外部调用方法A,会启动几个事务?Q:如果两个方法不在同一个类呢?

  • Redis List底层的数据结构是什么? 参考答案:

    • Redis3.2之前(此段参考new bing以及2,3),Redis List底层的数据结构有两种:压缩列表(ziplist)和双向链表(linkedlist). Redis在创建新的List时,会优先考虑使用压缩列表. 在满足条件(1,试图往列表添加一个字符串值,这个字符串的长度超过某个值; 或者2,ziplist 包含的节点超过某个值)时,才从压缩列表实现转换到双向链表实现。

ziplist 是一个特殊的双向链表
特殊之处在于:没有维护双向指针:prev next;而是存储上一个 entry的长度和当前entry的长度,通过长度推算下一个元素在什么地方。

    • Redis3.2版本开始对列表数据结构进行了改造,使用 quicklist 代替了 ziplist 和 linkedlist.
      quicklist 实际上是 zipList 和 linkedList 的混合体,它将 linkedList 按段切分,每一段使用 zipList 来紧凑存储,多个 zipList 之间使用双向指针串接起来。4
  • Redis如果采用AOF持久化方式,每隔5秒持久化一次,那它持久化时会影响其它读写线程吗?会不会阻塞主线程?参考答案5,6:AOF采用everysec时,Redis使用另一条线程每秒执行fsync同步硬盘。主线程在执行时候如果发现上一次的fsync操作还没有返回(对比上一次的fsync操作时间,大于2秒),主线程就会阻塞。 如图所示:
    在这里插入图片描述

当系统硬盘资源繁忙时,会造成Redis主线程阻塞

简单来说,如果系统fsync缓慢,将会导致Redis主线程阻塞。

Q:Redis里存了几百个Key,遍历读取它们的值可能需要一两秒,有没有效率更高的方法?参考答案:

  1. 方法1,mget;
  2. 方法2,pipeline。

值得注意的是:

  1. 性能上7,8: MGET 》PIPELINE》GET
  2. mget等命令可以保证原子性,pipeline 无法保证9
  3. 与 mget、mset 相同的是,pipeline 操作也无法在原生的集群模式下工作9

Q:使用redis pipeline有什么需要注意的?参考答案(主要参考new bing):在使用Redis Pipeline时,需要注意以下几点:

  1. 每次Pipeline携带数量不推荐过大,否则会影响网络性能,也会消耗更多redis的内存占用。
  2. Pipeline每次只能作用在一个Redis节点上(就是上文提到的pipeline无法在原生的集群模式下工作)。

  1. jstack分析线程快照的三步曲及CPU占用过高和死锁问题的排查-CSDN博客 ↩︎

  2. Redis官网:The ziplist representation ↩︎

  3. 知乎:Redis列表list 底层原理 ↩︎

  4. Redis数据结构——快速列表(quicklist) ↩︎

  5. Redis 分享-AOF的阻塞简单记录 ↩︎

  6. Redis AOF 追加阻塞问题分析处理 ↩︎

  7. Performance benchmarks - redis get vs mget ↩︎

  8. Sharing: Redis get pipeline vs mget ↩︎

  9. 如何通过批量操作提升 redis 性能 ↩︎ ↩︎

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_23204557

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

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

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

打赏作者

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

抵扣说明:

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

余额充值