精华内容
下载资源
问答
  • 举个例子:现在我要在A类中引用到B类,符号引用就是我只要知道B类的全类名是什么就可以了,而不用知道B类在内存中的那个具体位置(可能B类还没有被加载进内存呢)。直接引用就相当于是一个指针,能够直接或者间接...

    目录

    直接引用和符号引用简述:

    Class常量池

    局部变量的讨论

    拓展知识


    直接引用和符号引用简述:

    举个例子:现在我要在A类中引用到B类,符号引用就是我只要知道B类的全类名是什么就可以了,而不用知道B类在内存中的那个具体位置(有可能B类还没有被加载进内存呢)。直接引用就相当于是一个指针,能够直接或者间接的定位到内存中的B类的具体位置。将符号引用转换为直接引用简单来说就是:在A类中可以通过使用B类的全类名转换得到B类在内存中的具体位置。

    Class常量池

    常量池中主要存放两类数据,一是字面量、二是符号引用。

    字面量:比如String类型的字符串值或者定义为final类型的常量的值。

    符号引用:

    1. 类或接口的全限定名(包括他的父类和所实现的接口)
    2. 变量或方法的名称
    3. 变量或方法的描述信息
    4. this
    •     方法的描述:参数个数、参数类型、方法返回类型等等
    •     变量的描述信息:变量的返回值

    局部变量的讨论

    tip:网上有文章说不会将局部变量的变量名放入到常量池中?关于是否会将局部变量放入到常量池中,测试结果如下:

            ①.当在一个方法中有给局部变量赋值的语句时,会将局部变量名放入到常量池

            ②.当在方法中只是声明了一个局部变量,并没有为该局部变量的赋值操作时,不会将该局部变量名放入到常量池中

    代码示例:

    用下面这个简单的类来测试上面的结论:

    public class MyDemo extends Demo implements IDemo {
    
        private int a;
    
        public void method(){
            int b = 0;
        }
    }

    情况一:从上面的代码中可以看到我们声明了一个全局变量a,一个局部变量b,并且为局部变量b做了赋初值操作。使用javac将该类编译成字节码文件,得到MyDemo.class,使用javap -verbose MyDemo反编译字节码文件如下:

    情况二:

    我们将方法中的b = 0;不进行赋值操作,然后重新编译源代码,仍然使用Javap进行反编译,结果如下,发现常量池中并没有变量b。

    说明:一个类的class文件中并不会将他所继承的父类中的即使是Final类型的常量数据放入到常量池中,也不会将他所实现的接口中的常量放到常量池中。如果在该类中使用到了另一个类的编译期常量那么在编译时也会将该常量放入到常量池中。

    拓展知识

    来自:https://www.jianshu.com/p/cf78e68e3a99

    运行时常量池是方法区的一部分,所以也是全局共享的。我们知道,jvm在执行某个类的时候,必须经过加载、连接(验证,准备,解析)、初始化,在第一步的加载阶段,虚拟机需要完成下面3件事情:

    • 通过一个类的“全限定名”来获取此类的二进制字节流
    • 将这个字节流所代表的静态储存结构转化为方法区的运行时数据结构
    • 在内存中生成一个类代表这类的java.lang.Class对象,作为方法区这个类的各种数据访问的入口

      这里需要说明的一点是,类对象和普通的实例对象是不同的,类对象是在类加载的时候生成的,普通的实例对象一般是在调用new之后创建。

      上面第二条,将class字节流代表的静态储存结构转化为方法区的运行时数据结构,其中就包含了class文件常量池进入运行时常量池的过程。这里需要强调一下,不同的类共用一个运行时常量池,同时在进入运行时常量池的过程中,多个class文件中常量池中相同的字符串只会存在一份在运行时常量池中,这也是一种优化。

      运行时常量池的作用是存储 Java class文件常量池中的符号信息。运行时常量池 中保存着一些 class 文件中描述的符号引用,同时在类加载的“解析阶段”还会将这些符号引用所翻译出来的直接引用(直接指向实例对象的指针)存储在 运行时常量池 中。

      运行时常量池相对于 class 常量池一大特征就是其具有动态性,Java 规范并不要求常量只能在运行时才产生,也就是说运行时常量池中的内容并不全部来自 class 常量池,class 常量池并非运行时常量池的唯一数据输入口;在运行时可以通过代码生成常量并将其放入运行时常量池中,这种特性被用的较多的是String.intern()。

    展开全文
  • //红色部分为问题部分 section 结构 SECTIONS { ... secname start BLOCK(align) (NOLOAD) : AT ( ldadr ) { contents } >...//例子U-Boot.lds代码(根据上面的section的介绍,虽能大体看懂,但是还是些许..

    //红色部分为问题部分

    section 结构
    SECTIONS {
    ...
    secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
      { contents } >region :phdr =fill
    ...
    }
    secname:段名
    contents:决定哪些内容存放在此段
    start:本段的连接地址(实际运行地址)
    AT(ldadr):存储地址(加载的地址)

    //例子U-Boot.lds代码(根据上面的section的介绍,虽能大体看懂,但是还是有些许疑惑)
    SECTIONS
    {
        . = 0x00000000;      // ?????此处对应section结构中哪个标识,我觉得应该是存储地址吧?? 但却没有 AT 标识    
        . = ALIGN(4);        //此处应该是4字节对齐的意思,???? 但对应section结构中的哪个标志不是很明白
        .text      :            //此处应该是secname 段名
       {
             cpu/arm920t/start.o
            (.text)          //大括号,应该为contents段,指示该段存放的内容
            *(.text)
       }
       . = ALIGN(4);                    //以下类似
       .rodata : { *(.rodata) }
       . = ALIGN(4);
       .data : { *(.data) }
       . = ALIGN(4);
       .got : { *(.got) }
       . = .;

       __u_boot_cmd_start = .;
       .u_boot_cmd : { *(.u_boot_cmd) }
       __u_boot_cmd_end = .;

       . = ALIGN(4);
       __bss_start = .;
       .bss : { *(.bss) }
       _end = .;
    }

     

    问题1,二进制文件不包含BSS段,那把BSS段放在哪
    答:修改有1000个全局变量,难道要BIN里要存1000个0吗?在链接脚本里把BSS段组织在一起,记下它的起始地址、结束地址,重定位后把这块内存清0即可

    问题2:全局变量不初始化的话默认初始化为零,干嘛还要手动清零
    答:因为它是在BSS段的

    bss段:

    BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文BlockStarted by Symbol的简称。BSS段属于静态内存分配。

    data段:

    数据段(datasegment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

    text段:

    代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

    rodata段:

    存放C中的字符串和#define定义的常量

    heap堆:

    堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

    stack栈:

    是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

     

    常量段:

    常量段一般包含编译器产生的数据(与只读段包含用户定义的只读数据不同)。比如说由一个语句a=2+3编译器把2+3编译期就算出5,存成常量5在常量段中

     

    一般情况下,一个程序本质上都是由 bss段、data段、text段三个组成的——段概念是当前的计算机程序设计中是很重要的一个基本概念。而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。

    在采用段式内存管理的架构中(比如intel的80x86系统),bss段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss 段部分将会清零(bss段属于静态内存分配,即程序一开始就将其清零了)。

    比如,在C语言程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。   

    l          text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;

    l          而bss段不在可执行文件中,由系统初始化。

     

    编译两个小程序如下:

    程序1:

    int ar[30000];
    void main()
    {

        ......

    }

     

    程序2:

    int ar[300000] =  {1, 2, 3, 4, 5, 6 };
    void main()
    {

        ......

    }

        发现程序2编译之后所得的.exe文件比程序1的要大得多。 为什么?

    区别很明显,一个位于.bss段,而另一个位于.data段,两者的区别在于:

    l          全局的未初始化变量存在于.bss段中,具体体现为一个占位符;全局的已初始化变量存于.data段中;

    l          而函数内的自动变量都在栈上分配空间。

    l          .bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);

    l          而.data却需要占用,其内容由程序初始化,因此造成了上述情况。

     

    注意:

    l          bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。

    l          data(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。

    l          DATA段包含经过初始化的全局变量以及它们的值。

    l          BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段后面。当这个内存区进入程序的地址空间后全部清零。包含DATA和BSS段的整个区段此时通常称为数据区。

    展开全文
  • Java 小例子:如何使用 Enum

    千次阅读 2009-04-11 14:42:00
    因为一些参数只能取那么几个值,而从参数类型上又看不出来有哪些值可以取。从 1.5 开始 Java 引进了 Enum 枚举类型,并根据 Java 自身的特点将其进行了强化。实际上现在所有的常量都可以通过 Enum 来定义了。下面是...

    Java 在 1.5 以前,常量是个头疼的问题。因为一些参数只能取那么几个值,而从参数类型上又看不出来有哪些值可以取。从 1.5 开始 Java 引进了 Enum 枚举类型,并根据 Java 自身的特点将其进行了强化。实际上现在所有的常量都可以通过 Enum 来定义了。下面是一个例子,演示了 Enum 的基本用法,以及如何向 Enum 类型加入自定义属性。

    import java.util.Calendar;  
       
    /** 
     * 演示如何使用 Enum 
     */  
    public class EnumValue {  
       
        public static void main(String[] args) {  
       
            // 演示如何使用 Weekday  
            Weekday w = Weekday.Monday;  
            System.out.println("w = " + w.toString());  
            System.out.println("Monday compares to Friday = "  
                    + Weekday.Monday.compareTo(Weekday.Friday));  
       
            System.out.println("Enum value of 'Sunday' is " + Weekday.valueOf("Sunday"));  
       
            try {  
                System.out.println("Enum value of ''AnotherDay' is "  
                        + Weekday.valueOf("AnotherDay")); // 这里将会抛出 IllegalArgumentException  
            } catch (IllegalArgumentException e) {  
                System.out.println("exception: " + e.getMessage());  
            }  
            System.out.println();  
       
            // --------------------------------  
            // 演示如何使用 Month  
            System.out.println("The first month is " + Month.Jan);  
            System.out.println("The full name of the first month is " + Month.Jan.getFullName());  
            System.out.println("The fifth month is " + Month.valueByIndex(5).getFullName());  
            System.out.println("Index of August is " + Month.valueByFullName("August").getIndex());  
            System.out.println("Now is " + Month.thisMonth().getFullName());  
        }  
    }  
       
    /** 
     * 一个表示星期几的 enum (这是一个简单的例子) 
     */  
    enum Weekday {  
        Monday, Tuesday, Wednesday, Thirsday, Friday, Saturday, Sunday  
    }  
       
    /** 
     * 一个表示月份的 enum (这是一个稍微复杂的例子) 
     */  
    enum Month {  
       
        // 十二个月份  
        Jan("January"),  Feb("Febrary"),   Mar("March"),  
        Apr("April"),    May("May"),       June("June"),  
        July("July"),    Aug("August"),    Sept("September"),  
        Oct("October"),  Nov("November"),  Dec("December");  
       
        // 全名  
        private String fullName;  
       
        // 构造方法  
        Month(String fullName) {  
            this.fullName = fullName;  
        }  
       
        public String getFullName() {  
            return fullName;  
        }  
       
        // 获取当前 Enum 值是第几个月份。一月份则返回 1。  
        public int getIndex() {  
            return ordinal() + 1;  
        }  
       
        // 根据月数获得 enum 对象  
        public static Month valueByIndex(int index) {  
            for (Month month : Month.values()) {  
                if (month.getIndex() == index) {  
                    return month;  
                }  
            }  
            return null;  
        }  
       
        // 根据全名获得 enum 对象  
        public static Month valueByFullName(String fullName) {  
            for (Month month : Month.values()) {  
                if (month.getFullName().equals(fullName)) {  
                    return month;  
                }  
            }  
            return null;  
        }  
       
        public static Month thisMonth() {  
            // Calendar 的月份从 0 算起,而 Month 的月份从 1 算起  
            int index = Calendar.getInstance().get(Calendar.MONTH) + 1;  
            return valueByIndex(index);  
        }  
    }  


    展开全文
  • Java 知识点总结

    2019-06-28 16:20:11
    1、Object 对象的方法有哪些?分别有什么作用?该什么场景用? 2、Integer 的常量缓存池 3、Java 特性?什么是多态?举个例子 Object 的 hashcode 方法重写了,equals 方法要不要改? 4、重载重写的区别? ...

     

    Java 基础

    1、Object 对象的方法有哪些?分别有什么作用?该什么场景用?

    2、Integer 的常量缓存池

    3、Java 特性?什么是多态?举个例子

    Object 的 hashcode 方法重写了,equals 方法要不要改?

    4、重载重写的区别?

    Object 类中的方法

     equals hashcode toString,clone, notify() notifyAll(),wait()

    hashcode 和 equals 方法常用地方

    对象比较是否相同

    1.比较对象时, ==比较的是地址,而equals()比较的是对象内容

    2.重写equals()方法必须重写hashCode()

     

    Java线程池

    常见问答:

    线程池的原理,为什么要创建线程池?创建线程池的方式;

    为什么要创建线程池?

    1.线程切换需要上下文切换开销,同时线程池中的工作线程可以被重复利用,可以执行多个任务

    2. 可以根据实际需要设置线程池工作线程数目,避免内存消耗过多。

    ThreadLocal 了解吗?项目有用过吗?可以说说

    里面包含了一个ThreadLocalMap

     void createMap(Thread t, T firstValue) {
            t.threadLocals = new ThreadLocalMap(this, firstValue);
        }

    JUC 里面你还知道什么其他的类吗?比如 CountDownLatch、Condition

    从源码详细说下 Java 里面的线程池吧,使用线程池有什么要注意的地方?你们公司有规范吗?

     

    线程

    常见问答

    线程的生命周期,什么时候会出现僵死进程;

    僵尸进程(Zombie process)通俗来说指那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸。也就是说父进程没有结束,但是子进程结束了,父进程没死,没办法给子进程收尸,真的是只有父进程死了才能收尸

     

    说说线程安全问题,什么实现线程安全,如何实现线程安全;

    什么是线程安全?

    线程安全是指在多线程运行环境下,某个函数被多次调用,都能够正确处理各个线程的局部变量,并且程序功能正确。

    如何实现线程安全?

    有三种方式 

    1.使用ThreadLocal , 替每个线程维护线程安全的本地变量

    2.使用Synchronized和lock 为需要访问的资源加锁,进行同步控制。

    3.使用JUC下面的线程安全集合类 ConcurrentHashMap,Atomic原子类等

    volatile、ThreadLocal的使用场景和原理;

     

    ThreadLocal什么时候会出现OOM的情况?为什么?

    ThreadLocal中存在一个ThreadLocalMap,其中的key值是弱引用的,会被回收掉,但是value不会被自动回收

      static class Entry extends WeakReference<ThreadLocal<?>> {
                /** The value associated with this ThreadLocal. */
                Object value;
    
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }

     

    synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;

     作用域 :synchronized   可以加载方法,变量,代码块上

                     voliatile 只能加载变量上 

    线程阻塞

    volatile不会造成线程阻塞

    synchronized会造成线程阻塞

    可见性 原子性

    synchronized 可以保证原子性和可见性

    volatile 只能保证可见性

    模拟死锁场景

    public class DeadLockSynchronizedTest {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            Object a = new Object();
            Object b = new Object();
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    testA(a, b);
                }
            });
    
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    testB(a, b);
                }
            });
            t.start();
            t1.start();
    
        }
    
        /**
         * @param a
         * @param b
         */
        private static void testB(Object a, Object b) {
            System.out.println("Entering into testB");
            synchronized (b) {
                System.out.println(Thread.currentThread() + "获得 锁 b");
                synchronized (a) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "获得 锁 a");
                }
            }
    
        }
    
        /**
         * @param a
         * @param b
         */
        private static void testA(Object a, Object b) {
            System.out.println("Entering into testA");
            synchronized (a) {
                System.out.println(Thread.currentThread() + "获得 锁 a");
                synchronized (b) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread() + "获得 锁 b");
                }
            }
    
        }
    
    }
    

     

     

    Synchronized和ReentrantLock 区别

    讲下 Synchronized?

    Synchronized 和 RecentLock 有什么区别?这两个有没有深入了解源码?

    1讲下 Volatile 吧?他是怎样做到同步的?

    Volatile 为什么不支持原子性?举个例子

    1Atomic 怎么设计的?有用过里面的类吗?

    线程安全类和线程不安全的类,项目使用的时候你会怎么选择?怎么判断项目代码哪里会有线程不安全问题?

    synchronized、lock

    lock 需要主动释放锁

    lock实现 基于AbstractQueuedSynchronizer  队列同步器 CAS 实现的

     

    讲下 RecentLock 可重入锁? 什么是可重入锁?为什么要设计可重入锁?

     

    如何避免死锁?

    死锁的4个条件

    • 互斥条件:所谓互斥就是进程在某一时间内独占资源。
    • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 
    • 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。  
    • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    资源互斥是无法改变的,可以改变其他三个条件避免死锁

    1. 破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。
    2. 破坏”请求与保持条件“:第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源。第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源。
    3. 破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。

     

    JVM

    1、JAVA 类加载器

    线上服务 CPU 很高该怎么做?有哪些措施可以找到问题

    2、Java 内存结构(注:不是 Java 内存模型,别搞混)

    3、怎么判断对象是否可 GC?Java 对象有哪些引用类型?有什么区别?

    4、OOM 出现的有哪些场景?为什么会发生?

    5、Minor GC 和 Full GC 有什么区别?分析过 GC 日志吗?

    6、说下你知道的垃圾回收算法

    7、说下你知道的垃圾收集器

    8、CMS 和 G1 的区别知道吗?使用场景分别是?你项目中用的是哪个?

    CMS 并行收集器  G1 将堆分成一个个区域,判断哪个区域垃圾最多,优先回收

    9、你还知道哪些 JVM 调优参数?

    10、假如线上服务发生 OOM,有哪些措施可以找到问题?

    11、假如线上服务 CPU 很高该怎么做?有哪些措施可以找到问题?

    12、假如线上应用频繁发生 Full GC,有哪些措施可以找到问题?

    13、一般线上环境遇到 JVM 问题,你会使用哪些工具来分析?找到问题后又该如何去解决呢?

    GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?

    Eden空间不够,触发Minor GC

    老年代空间不够(新生代晋升,大对象进入),触发 Major GC 

    新生代一般采用 复制算法

    老年代垃圾回收一般采用的是 标记整理算法

     

    常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?

    jstatc -gc 

    jmap -histo:live pid 

    jmap -dump:live,format=b,file=dump.hprof 24971
    

    导出文件 使用Mat 分析,内存泄露,溢出等

    JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的

     内存划分   堆 永久代, 栈 (本地方法栈,虚拟机栈)程序计数器

        

     

     

    Java集合

    常见问答:

    HashMap内部的数据结构是什么?底层是怎么实现的?(还可能会延伸考察ConcurrentHashMap与HashMap、HashTable等,考察对技术细节的深入了解程度)

    HashMap 中怎么解决冲突的?

    使用链表

    ConcurrentHashMap 和 HashTable 中线程安全的区别?为啥建议用 ConcurrentHashMap ?能把 ConcurrentHashMap 里面的实现详细的讲下吗?

    5、画下 HashMap 的结构图?HashMap 、 HashTable 和 ConcurrentHashMap 的区别?使用场景分别是?

    8、保证线程安全的还有其他的方式吗?

    16、Map、List、Set 分别说下你了解到它们有的线程安全类和线程不安全的类?

    17、TreeSet 清楚吗?能详细说下吗?

    11、HashMap 和 hashTable 区别?

    13、Hashmap 线程不安全的出现场景

    ArrayList 和 LinkedList 区别

    17、如果存取相同的数据,ArrayList 和 LinkedList 谁占用空间更大?

    18、Set 存的顺序是有序的吗?

    19、常见 Set 的实现有哪些?

    TreeSet 对存入对数据有什么要求呢?

    HashSet 的底层实现呢?

    使用的是HashMap实现的

    TreeSet 底层源码有看过吗?

    HashSet 是不是线程安全的?为什么不是线程安全的?

    没加锁

    Java 中有哪些线程安全的 Map?

    Concurrenthashmap

    Concurrenthashmap 是怎么做到线程安全的?

    使用了synchronized 和CAS

        public V put(K key, V value) {
            return putVal(key, value, false);
        }
    
        /** Implementation for put and putIfAbsent */
        final V putVal(K key, V value, boolean onlyIfAbsent) {
            if (key == null || value == null) throw new NullPointerException();
            int hash = spread(key.hashCode());
            int binCount = 0;
            for (Node<K,V>[] tab = table;;) {
                Node<K,V> f; int n, i, fh;
                if (tab == null || (n = tab.length) == 0)
                    tab = initTable();
                else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                    if (casTabAt(tab, i, null,
                                 new Node<K,V>(hash, key, value, null)))
                        break;                   // no lock when adding to empty bin
                }
                else if ((fh = f.hash) == MOVED)
                    tab = helpTransfer(tab, f);
                else {
                    V oldVal = null;
                    // 修改某个节点时 采用了同步控制
                    synchronized (f) {
                        if (tabAt(tab, i) == f) {
                            if (fh >= 0) {
                                binCount = 1;
                                for (Node<K,V> e = f;; ++binCount) {
                                    K ek;
                                    if (e.hash == hash &&
                                        ((ek = e.key) == key ||
                                         (ek != null && key.equals(ek)))) {
                                        oldVal = e.val;
                                        if (!onlyIfAbsent)
                                            e.val = value;
                                        break;
                                    }
                                    Node<K,V> pred = e;
                                    if ((e = e.next) == null) {
                                        pred.next = new Node<K,V>(hash, key,
                                                                  value, null);
                                        break;
                                    }
                                }
                            }
                            else if (f instanceof TreeBin) {
                                Node<K,V> p;
                                binCount = 2;
                                if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                               value)) != null) {
                                    oldVal = p.val;
                                    if (!onlyIfAbsent)
                                        p.val = value;
                                }
                            }
                        }
                    }
                    if (binCount != 0) {
                        if (binCount >= TREEIFY_THRESHOLD)
                            treeifyBin(tab, i);
                        if (oldVal != null)
                            return oldVal;
                        break;
                    }
                }
            }
            addCount(1L, binCount);
            return null;
        }

    HashTable 你了解过吗?

    线程安全的Hash表,使用Synchronized同步控制

        public synchronized V put(K key, V value) {
            // Make sure the value is not null
            if (value == null) {
                throw new NullPointerException();
            }
    
            // Makes sure the key is not already in the hashtable.
            Entry<?,?> tab[] = table;
            int hash = key.hashCode();
            int index = (hash & 0x7FFFFFFF) % tab.length;
            @SuppressWarnings("unchecked")
            Entry<K,V> entry = (Entry<K,V>)tab[index];
            for(; entry != null ; entry = entry.next) {
                if ((entry.hash == hash) && entry.key.equals(key)) {
                    V old = entry.value;
                    entry.value = value;
                    return old;
                }
            }
    
            addEntry(hash, key, value, index);
            return null;
        }

    HashMap

    数据结构: 数组 +链表/红黑树

    线程不安全

    put

    get 

    HashTable实现原理

    数据结构: 数组+链表

    线程安全

    ConcurrentHashMap实现原理

    JDK1.6基于分段锁的

    JDK1.8 是基于 Synchronized和CAS的

    synchronized 的用处: put的时候,节点上加synchronized

    final V putVal(K key, V value, boolean onlyIfAbsent) {
            if (key == null || value == null) throw new NullPointerException();
            int hash = spread(key.hashCode());
            int binCount = 0;
            for (Node<K,V>[] tab = table;;) {
                Node<K,V> f; int n, i, fh;
                if (tab == null || (n = tab.length) == 0)
                    tab = initTable();
                else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                    if (casTabAt(tab, i, null,
                                 new Node<K,V>(hash, key, value, null)))
                        break;                   // no lock when adding to empty bin
                }
                else if ((fh = f.hash) == MOVED)
                    tab = helpTransfer(tab, f);
                else {
                    V oldVal = null;
                   // 节点加锁
                    synchronized (f) {
                        if (tabAt(tab, i) == f) {
                            if (fh >= 0) {
                                binCount = 1;
                                for (Node<K,V> e = f;; ++binCount) {
                                    K ek;
                                    if (e.hash == hash &&
                                        ((ek = e.key) == key ||
                                         (ek != null && key.equals(ek)))) {
                                        oldVal = e.val;
                                        if (!onlyIfAbsent)
                                            e.val = value;
                                        break;
                                    }
                                    Node<K,V> pred = e;
                                    if ((e = e.next) == null) {
                                        pred.next = new Node<K,V>(hash, key,
                                                                  value, null);
                                        break;
                                    }
                                }
                            }
                            else if (f instanceof TreeBin) {
                                Node<K,V> p;
                                binCount = 2;
                                if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                               value)) != null) {
                                    oldVal = p.val;
                                    if (!onlyIfAbsent)
                                        p.val = value;
                                }
                            }
                        }
                    }
                    if (binCount != 0) {
                        if (binCount >= TREEIFY_THRESHOLD)
                            treeifyBin(tab, i);
                        if (oldVal != null)
                            return oldVal;
                        break;
                    }
                }
            }
            addCount(1L, binCount);
            return null;
        }

    CAS 使用

        /**
         * Helps transfer if a resize is in progress.
         */
        final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
            Node<K,V>[] nextTab; int sc;
            if (tab != null && (f instanceof ForwardingNode) &&
                (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
                int rs = resizeStamp(tab.length);
                while (nextTab == nextTable && table == tab &&
                       (sc = sizeCtl) < 0) {
                    if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                        sc == rs + MAX_RESIZERS || transferIndex <= 0)
                        break;
                    // CAS 判断是否获得扩容权限
    //第一个参数是要修改的对象,第二个参数是对象中要修改变量的偏移量,第三个参数是修改之前的值,第四个参数是预想修改后的值....
                    if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {
                        transfer(tab, nextTab);
                        break;
                    }
                }
                return nextTab;
            }
            return table;
        }

     

    ConcurrentHashMap 数据结构

    问题: List 和 Map 区别,Arraylist 与 LinkedList 区别,ArrayList 与 Vector 区别;

    Arraylist

    数据结构: 数组

    扩容:1.5倍扩容

     private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }

    LinkedList

    数据结构:链表

    add 方法

     public boolean add(E e) {
            linkLast(e);
            return true;
        }
     
    void linkLast(E e) {
            final Node<E> l = last;
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
        }

    Vector

    数据结构:数组

    线程安全

    扩容: 2倍扩容

     private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                             capacityIncrement : oldCapacity);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            elementData = Arrays.copyOf(elementData, newCapacity);
        }

    add 方法

       public synchronized boolean add(E e) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }

     

    TreeMap

     

     

     

     

     

    NIO 

    NIO是什么?适用于何种场景?

    http://www.importnew.com/21341.html

    Java9比Java8改进了什么?

    增加了.jshell

    .改进了 Stream API

     

     

     

    反射

    说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;

    反射的用途

     

    说说自定义注解的场景及实现;

     

     

     

    Spring

    1、说下你对 Spring 生态的了解?

    2、说下你对 Spring AOP 和 IOC 的理解?看过实现原理吗?

    3、说下 Bean 在 Spring 中的生命周期?

    4、讲下你知道的 Spring 注解有哪些?该什么场景使用?

    5、Spring 事务知道吗?有了解过吗?

    6、说下你刚才说的 SpringBoot 吧,你觉得 SpringBoot 有什么优点?

    7、SpringBoot 自动化配置是怎么做的?有看过实现源码吗?

    8、Spring Boot 中最核心的注解 SpringBootApplication 有看过源码分析过吗?

    9、你的项目中 SpringBoot 用到了哪些和其他技术栈整合的?

    10、使用 Spring 或者 SpringBoot 有遇到过什么印象深刻的问题吗?当时是怎么解决的?

    Spring AOP的实现原理和场景?

     

    Spring bean的作用域和生命周期

    1.实例化

    2.按照 Spring 上下文对实例化的 Bean 进行配置, 也就是 IOC 注入。

    3.setBeanName 的实现,如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String)
    方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值

    4.BeanFactoryAware 实现,如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory,
    setBeanFactory(BeanFactory)传递的是 Spring 工厂自身(可以用这个方式来获取其它 Bean,
    只需在 Spring 配置文件中配置一个普通的 Bean 就可以

    5.ApplicationContextAware 实现
    如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用
    setApplicationContext(ApplicationContext)方法,传入 Spring 上下文(同样这个方式也
    可以实现步骤 4 的内容,但比 4 更好,因为 ApplicationContext 是 BeanFactory 的子接
    口,有更多的实现方法)

    6.postProcessBeforeInitialization 实现
    如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
    postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 经常被用
    作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用那个的方法,也可以被应
    用于内存或缓存技术

    7. init-methmod 方法如果 Bean 在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始化方法。

    8.postProcessAfterInitialization 实现
     如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
    postProcessAfterInitialization(Object obj, String s)方法。
    注: 以上工作完成以后就可以应用这个 Bean 了,那这个 Bean 是一个 Singleton 的,所以一
    般情况下我们调用同一个 id 的 Bean 会是在内容地址相同的实例,当然在 Spring 配置文件中
    也可以配置非 Singleton。

    9.Destroy 过期自动清理阶段
    当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调
    用那个其实现的 destroy()方法;

    10.destroy-method 自配置清理
    最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的
    销毁方法。

    bean标签有两个重要的属性(init-methmod和destroy-methmod).可以用他们自定义注解的初始化和注销方法,也有响应的注解(@PostConstruct和@PreDestroy)

    <bean id="" class="" init-methmod="初始化方法" destroy-methmod="销毁方法">

    Spring Boot比Spring做了哪些改进? Spring 5比Spring4做了哪些改进;

     

    如何自定义一个Spring Boot Starter?

     

    Spring IOC是什么?优点是什么?


    SpringMVC、动态代理、反射、AOP原理、

     

    六、中间件篇

    1、Dubbo的底层实现原理和机制

    2、描述一个服务从发布到被消费的详细过程

    3、分布式系统怎么做服务治理

    4、接口的幂等性的概念

    5、消息中间件如何解决消息丢失问题

    Dubbo的服务请求失败怎么处理

    DubboInvoker.doInvoke//为什么DubboInvoker是个protocol? 因为RegistryDirectory.refreshInvoker.toInvokers: protocol.refer

    7、重连机制会不会造成错误

    8、对分布式事务的理解

    9、如何实现负载均衡,有哪些算法可以实现?

    10、Zookeeper的用途,选举的原理是什么?

    11、数据的垂直拆分水平拆分。

    12、zookeeper原理和适用场景

    zookeeper watch机制

    允许客户端向服务端注册监听,当一些特定事件触发时,Zookeeper服务器将通知到感兴趣的客户端上去

    14、redis/zk节点宕机如何处

    15、分布式集群下如何做到唯一序列号

    16、如何做一个分布式锁

    Dubbo完整的一次调用链路介绍;

     

    Dubbo支持几种负载均衡策略?

     

    Dubbo Provider服务提供者要控制执行并发请求上限,具体怎么做?

     

    Dubbo启动的时候支持几种配置方式?

     

    了解几种消息中间件产品?各产品的优缺点介绍;

     

    消息中间件如何保证消息的一致性和如何进行消息的重试机制?

     

    Spring Cloud熔断机制介绍;

     

    Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?

     

    数据库

     

    事务的隔离级别?

    PROPAGATION_SUPPORTS --支持当前事务,如果当前没有事务,就以非事物的方式运行

    PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常

    PROPAGATION_REQUIRES_NEW 新建事务

    锁机制介绍:行锁、表锁、排他锁、共享锁;

     

    乐观锁的业务场景及实现方式;

     

    事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;

     

    MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

     

    MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;

     

    分布式事务的原理2阶段提交,同步\异步\阻塞\非阻塞;

     

    数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、JDBC如何实现事务、嵌套事务实现、分布式事务实现;

     

    SQL的整个解析、执行过程原理、SQL行转列;

     

    SQL 优化

     

    Redis

     

    Redis为什么这么快?redis采用多线程会有哪些问题?

    采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

     

    1.发送命令

    2.命令排队

    3.执行命令

    4.返回结果

    Redis支持哪几种数据结构;

     

    Redis跳跃表的问题;

    zset 使用的是hash 和跳表

    Redis单进程单线程的Redis如何能够高并发?

     

    Redis如何使用Redis实现分布式锁?

     

    Redis分布式锁操作的原子性,Redis内部是如何实现的?

    九、其他

     

    看过哪些源代码?然后会根据你说的源码问一些细节的问题?(这里主要考察面试者是否对技术有钻研的精神,还是只停留在表面,还是背了几道面经,这个对于很多有强迫症的面试官,如果你连源码都没看过,基本上是会pass掉的,比如我也是这样的!)

     

    项目中遇到了哪些比较有挑战性的问题,是如何解决的;(这个很有争议,一方面是你连一个复杂的问题都解决不了,要你过来干什么,还有就是我的能力牛逼啊,但是公司没有业务场景让我展示啊!这个就看你遇到的面试官了,祝你好运!)

     

    自我和项目相关

    1、自我介绍

    2、你觉得自己的优点是?你觉得自己有啥缺点?

    3、你有哪些 offer?

    4、你为什么要离开上家公司?你上家公司在xxx,我们公司在xxx,离这么远为什么要选择我们这里?

    5、上家公司的同事和领导是怎么评价你的?

    6、介绍下你的上家公司是做哪块的吧

    7、在上家公司你做了哪些项目?

    8、你在项目中是什么角色?

    9、这个项目的数据量和并发量多大?

    10、这个项目用的什么技术?

    11、项目过程中有遇到什么很印象深刻的问题吗?

    12、是怎么解决的这些问题?

    13、项目有没有还可以继续优化的地方?

    14、该怎么优化?有什么思路没?

    15、叫你设计一个并发xxx,数据存储量xxx 量级的系统,你该如何设计?从你知道的点尽可能的多说出些?

     

    数据库

    1、你的项目使用的是什么数据库?

    2、你对数据库了解多少?说下数据库的索引实现和非主键的二级索引

    3、说下 MySQL 的索引原理

    4、讲下 InnoDB 和 MyISAM 的区别?使用场景是?

    5、有和 ElasticSearch 的索引原理对比过吗?

    6、如何判断一个查询 sql 语句是否使用了索引?

    7、数据库事务特性和隔离级别

    8、项目数据库表是你设计的吗?一般要注意什么?如何考虑扩展性?

    9、项目 MySQL 的数据量和并发量有多大?量大后的影响有哪些,有考虑吗?SQL 调优有哪些技巧?

    10、说下你项目里面关于数据库印象最深的一个问题?当时是怎么解决的

    其他

    1、描述下网页一个 Http 请求,到后端的整个请求过程

    2、有比较过 Http 和 RPC 吗?如果叫你设计一个高性能的 Http 或者 RPC,你会从哪些方面考虑?

    3、项目中我看使用了 xxx (ElasticSearch、Hbase、Redis、Flink 等),有深入了解它们的原理和懂点调优技巧吗?

    4、项目中我看使用了 xxx (ElasticSearch、Hbase、Redis、Mysql 等),有深入了解它们数据同步是怎么做吗?

    5、项目中我看使用了 xxx (ElasticSearch、Hbase、Redis、Mysql 等),有深入了解它们常见的监控指标吗?

    6、如果叫你设计一个秒杀系统,你会从哪些方面考虑?

    7、如果叫你设计一个电商系统,你会从哪些方面考虑?

    8、如果叫你设计一个监控告警系统,你会从哪些方面考虑?

    总结

    本文的面试题以 HR & 技术官角度常问的面试题,技术方面从 Java 基础、JVM、Spring、数据库、拓展题等方面考察你,当然面试官可能还会问些其他的技术点,我一篇文章也难以概全。总的来说,还是得多准备充分,面试时灵活答辩,相信你最后能拿到满意的 offer!加油,骚年!

     

     

    电话一面

    1、自我介绍、自己做的项目和技术领域

    2、项目中的监控:那个监控指标常见的有哪些?

    3、微服务涉及到的技术以及需要注意的问题有哪些?

    4、注册中心你了解了哪些?

    5、consul 的可靠性你了解吗?

    6、consul 的机制你有没有具体深入过?有没有和其他的注册中心对比过?

    7、项目用 Spring 比较多,有没有了解 Spring 的原理?AOP 和 IOC 的原理

    8、Spring Boot除了自动配置,相比传统的 Spring 有什么其他的区别?

    9、Spring Cloud 有了解多少?

     

    15、JDK 中有哪几个线程池?顺带把线程池讲了个遍

    16、SQL 优化的常见方法有哪些

       SQL优化

    17、SQL 索引的顺序,字段的顺序

    18、查看 SQL 是不是使用了索引?(有什么工具)

    19、TCP 和 UDP 的区别?TCP 数据传输过程中怎么做到可靠的?

    20、说下你知道的排序算法吧

    21、查找一个数组的中位数?

    22、你有什么问题想问我的吗?


     

    电话二面(85 分钟)

    1、自我介绍、工作经历、技术栈

    2、项目中你学到了什么技术?(把三项目具体描述了很久)

    3、微服务划分的粒度

    4、微服务的高可用怎么保证的?

    5、常用的负载均衡,该怎么用,你能说下吗?

    6、网关能够为后端服务带来哪些好处?

    8、xml 中配置的 init、destroy 方法怎么可以做到调用具体的方法?

    9、反射的机制
     

     

    13、hashmap put 方法存放的时候怎么判断是否是重复的

    // equal 方法判断
    if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;

    14、Object toString 方法常用的地方,为什么要重写该方法

    POJO 类必须写 toString 方法。使用 IDE 的中工具: source> generate toString
    时,如果继承了另一个 POJO 类,注意在前面加一下 super.toString。
    说明: 在方法执行抛出异常时,可以直接调用 POJO 的 toString()方法打印其属性值,便于排
    查问题。

    Set 和 List 区别?

    Set是map改造得到的key值唯一 list 有数组和链表,key可以重复

     

    如何保证线程安全问题?

    1. ThreadLocal 

    2.同步控制

    3.原子变量

     

    abstract static class Sync extends AbstractQueuedSynchronizer {
            private static final long serialVersionUID = -5179523762034025860L;
    
            /**
             * Performs {@link Lock#lock}. The main reason for subclassing
             * is to allow fast path for nonfair version.
             */
            abstract void lock();
    
            /**
             * Performs non-fair tryLock.  tryAcquire is implemented in
             * subclasses, but both need nonfair try for trylock method.
             */
            final boolean nonfairTryAcquire(int acquires) {
                final Thread current = Thread.currentThread();
                int c = getState();
                if (c == 0) {
                    if (compareAndSetState(0, acquires)) {
                        setExclusiveOwnerThread(current);
                        return true;
                    }
                }
                else if (current == getExclusiveOwnerThread()) {
                    int nextc = c + acquires;
                    if (nextc < 0) // overflow
                        throw new Error("Maximum lock count exceeded");
                    setState(nextc);
                    return true;
                }
                return false;
            }
    
            protected final boolean tryRelease(int releases) {
                int c = getState() - releases;
                if (Thread.currentThread() != getExclusiveOwnerThread())
                    throw new IllegalMonitorStateException();
                boolean free = false;
                if (c == 0) {
                    free = true;
                    setExclusiveOwnerThread(null);
                }
                setState(c);
                return free;
            }

    29、volatile 的原子性问题?为什么 i++ 这种不支持原子性?从计算机原理的设计来讲下不能保证原子性的原因

     

    30、happens before 原理

    31、cas 操作

    32、lock 和 synchronized 的区别?

    33、公平锁和非公平锁

    34、Java 读写锁

    35、读写锁设计主要解决什么问题?

    36、你项目除了写 Java 代码,还有前端代码,那你知道前端有哪些框架吗?

    37、MySQL 分页查询语句

    38、MySQL 事务特性和隔离级别

    39、不可重复读会出现在什么场景?

    40、sql having 的使用场景

    41、前端浏览器地址的一个 http 请求到后端整个流程是怎么样?能够说下吗?

    42、http 默认端口,https 默认端口

    43、DNS 你知道是干嘛的吗?

    DNS 域名解析,大概有10个步骤

    1.浏览器检查缓存中有没有域名对应的Ip

    2. 如果缓存中没有,查找操作系统是否缓存了DNS解析结果,windows 下,一般在 /etc/hosts

    目录

    3.如何怎么知道域名服务器? 

    操作系统将域名发送到LDNS,这个DNS通常是指提供本地互联网的一个DNS解析服务

    4. 

    你们开发用的 ide 是啥?你能说下 idea 的常用几个快捷键吧?

    CTRL +F

    CTRK+H

    CTRL+K

    45、代码版本管理你们用的是啥?

    svn

    46、git rebase 和 merge 有什么区别?

     

    Spring 注解

    @Component就是跟<bean>一样,可以托管到Spring容器进行管理。

    @Service@Controller , @Repository = {@Component + 一些特定的功能}。这个就意味着这些注解在部分功能上是一样的。

    当然,下面三个注解被用于为我们的应用进行分层:

    @Controller注解类进行前端请求的处理,转发,重定向。包括调用Service层的方法 
    @Service注解类处理业务逻辑 
    @Repository注解类作为DAO对象(数据访问对象,Data Access Objects),这些类可以直接对数据库进行操作 
    有这些分层操作的话,代码之间就实现了松耦合,代码之间的调用也清晰明朗,便于项目的管理;假想一下,如果只用@Controller注解,那么所有的请求转发,业务处理,数据库操作代码都糅合在一个地方,那这样的代码该有多难拓展和维护。

     

    1、多个线程同时读写,读线程的数量远远大于写线程,你认为应该如何解决并发的问题?你会选择加什么样的锁?

    2、JAVA的AQS是否了了解,它是干嘛的?

    3、除了synchronized关键字之外,你是怎么来保障线程安全的?

    4、什么时候需要加volatile关键字?它能保证线程安全吗?

    5、线程池内的线程如果全部忙,提交一个新的任务,会发生什什么?队列6、全部塞满了之后,还是忙,再提交会发生什么?

    7、Tomcat本身的参数你⼀一般会怎么调整?

    8、synchronized关键字锁住的是什么东西?在字节码中是怎么表示的?在内存中的对象上表现为什么?

    9、wait/notify/notifyAll方法需不需要被包含在synchronized块中?这是为什么?

    10、ExecutorService你一般是怎么用的?是每个service放一个还是一个项目里面放一个?有什么好处?

    11、你有没有⽤用过Spring的AOP? 是用来干嘛的? 大概会怎么使用?

    12、如果⼀一个接口有2个不同的实现, 那么怎么来Autowire一个指定的实现?

    spring

     

    13、Spring的声明式事务 @Transaction注解一般写在什么位置? 抛出了14、异常会自动回滚吗?有没有办法控制不触发回滚?

    15、如果想在某个Bean生成并装配完毕后执行自己的逻辑,可以什么方式实现?

    16、SpringBoot没有放到web容器里为什么能跑HTTP服务?

    17、SpringBoot中如果你想使用自定义的配置文件而不仅仅是application.properties,应该怎么弄?

    18、SpringMVC中RequestMapping可以指定GET, POST方法么?怎么指定?

    19、SpringMVC如果希望把输出的Object(例如XXResult或者XXResponse)这种包装为JSON输出, 应该怎么处理?

    20、怎样拦截SpringMVC的异常,然后做自定义的处理,比如打日志或者包装成JSON

     

    MySQL

     

    21、如果有很多数据插入MYSQL 你会选择什么方式?

    22、如果查询很慢,你会想到的第一个方式是什么?索引是干嘛的?

    23、如果建了一个单列索引,查询的时候查出2列,会用到这个单列索引吗?

    24、如果建了一个包含多个列的索引,查询的时候只用了第一列,能不能用上这个索引?查三列呢?

    25、接上题,如果where条件后面带有一个 i + 5 < 100 会使用到这个索引吗?

    26、怎么看是否用到了了某个索引?

    27、like %aaa%会使用索引吗? like aaa%呢?

    28、drop、truncate、delete的区别?

    29、平时你们是怎么监控数据库的? 慢SQL是怎么排查的?

    30、你们数据库是否支持emoji表情,如果不支持,如何操作?

    31、你们的数据库单表数据量是多少?一般多大的时候开始出现查询性能急剧下降?

    32、查询死掉了,想要找出执行的查询进程用什么命令?找出来之后一般你会干嘛?

    33、读写分离是怎么做的?你认为中间件会怎么来操作?这样操作跟事务有什么关系?

    34、分库分表有没有做过?线上的迁移过程是怎么样的?如何确定数据是正确的?

     

    JVM性能优化

     

    35、你知道哪些或者你们线上使用什么GC策略? 它有什么优势,适用于什么场景?

    36、Java类加载器包括几种?它们之间的父子关系是怎么样的?双亲委派机制是什么意思?有什么好处?

    37、如何自定义一个类加载器?你使用过哪些或者你在什么场景下需要一个自定义的类加载器吗?

    38、堆内存设置的参数是什么?

    39、Perm Space中保存什么数据? 会引起OutOfMemory吗?

    40、做gc时,一个对象在内存各个Space中被移动的顺序是什么?

    41、你有没有遇到过OutOfMemory问题?你是怎么来处理这个问题的?42、处理过程中有哪些收获?

    43、1.8之后Perm Space有哪些变动? MetaSpace大小默认是无限的么? 还是你们会通过什么方式来指定大小?

    44、Jstack是干什么的? Jstat呢? 如果线上程序周期性地出现卡顿,你怀疑可能是gc导致的,你会怎么来排查这个问题?线程日志一般你会看其中的什么部分?

    45、StackOverFlow异常有没有遇到过?一般你猜测会在什么情况下被触发?如何指定一个线程的堆栈大小?一般你们写多少?

     

     

     

     

     

     

     

    想获得更多资源,请关注微信公众号:程序员开发者社区

     

     

     

     

    展开全文
  • 好处有哪些呢? final和static一起来使用 声名为常量。final常量凡是对成员变量或者本地变量(在方法中的或者代码块中的变量称为本地变量)声明为final的都叫作final变量。final变量经常和static关键字一起使用,作为...
  • 文章目录一、`iterator`接口介绍二、为什么需要iterator接口三、iterator接口相关接口3.1 ListIterator3.2 SpitIterator3.2.1 SpitIterator源码方法解析3.2.2 SpitIterator里面哪些特征常量有什么用呢?四、 ...
  • 子类与父类的初始化

    2019-12-30 22:40:55
    最近读了深入理解Java虚拟机这本书,在学习类加载机制的时候,突然反应过来,一些笔试题经常考的,子类继承了父类且子类和父类的构造器中均打印输出,让作答输出了哪些内容,其实考的知识点就是类加载的时机。...
  • Python的基础语法会有哪些呢?来看看Python基础语法的思维导图吧下面就详细介绍一下吧1、Python标识符所谓的标识符就是对变量、常量、函数、类等对象起的名字标识符命名规定大小写敏感只能以 字母 数字 下划线 组成...
  • js中的字面量概念我的理解就是:字体表面的常量 如:数字 100, 字符串 "ssss"或'ssss' ...具体有哪些,请自行上网上去查。 var tet ; alert(tet); 这个例子的结果是:tet is undifine 。 标示声明意思呢?...
  • Python之基础语法

    2020-12-17 23:22:00
    Python的基础语法会有哪些呢? 来看看Python基础语法的思维导图吧 下面就详细介绍一下吧 1、Python标识符 所谓的标识符就是对变量、常量、函数、类等对象起的名字 标识符命名规定 大小写敏感 只能以 字母 数字...
  • 在PHP手册中详细的例子。 数组与哈希表 数组与哈希表以同样的方法被支持。怎样运用取决于你怎样定义它们。你可以用list()或者array()来定义它们,也可以直接为数组赋值。数组的索引从0开始。虽然我在这里没有...
  • 常用的实用类

    2020-06-17 17:54:27
    生活中也很多类似的例子,比如说:性别,只有男和女,星期,周一到周日,也是不会改变的常量。 先来展示一下枚举的代码是由哪些东西构成的: [Modifier] enum enumName{ enumContantName1 [,enumConstantName2.....
  • 本期给大家聊下Go语言的数据类型有哪些,数据类型用于声明函数和变量。数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。Go 语言按类别...
  • Java的起源及应用 Java语言特点 变量与运算符 ...常用关键字有哪些; 变量命名规范及应如何定义并赋值; 变量之间的转化; 变量的作用域和生存期(给出一个例子);  3. 运算符的优先级别:
  • 目标明确,但Java应用越做越庞大,方法区的大小就常数百上千兆,里面的类、常量等更是恒河沙数,检查以这里为起源的引用需耗费大量时间。 主流Java虚拟机使用的都是准确式垃圾收集 ,直接得到哪些地方存放着对象...
  • 算术运算符:+、-、*、/、%(取余) 区别: /获取两个数据相除的商,%获取两个数据相除的余数 例子:6/4=1 ;6%4=2 注意:整数相除只能得到整数,想获得小数就得浮点数的参与。 System.out.println(6/4); //结果为1...
  • 哈希表(hash table)是比较常用的数据结构,它能提供接近常量时间复杂度的...举个简单的例子,比如我们手里有全班30个学生每个人的生日的数据表格,我要求快速的找出某一天有没有人,有哪些人过生日。最容易(或者说
  • C语言编程要点

    2017-09-18 00:10:37
    5.7. 与用#define指令说明常量相比,用enum关键字说明常量有什么好处? 81 5.8. 如何使部分程序在演示版中失效? 82 5.9. 什么时候应该用宏代替函数? 83 5.10. 使用宏更好,还是使用函数更好? 83 5.11. 在程序中加入...
  • 1.30如何判断哪些标识符可以使用,哪些被保留了? 初始化 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为“零”,它可否作为空指针或浮点零? 1.32 下面的代码为什么不能编译?...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    1.30 如何判断哪些标识符可以使用,哪些被保留了? 15 初始化 18 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为“零”,它可否作为空指针或浮点零? 18  1.32 下面的...
  • 1.30 如何判断哪些标识符可以使用,哪些被保留了? 15 初始化 18 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为“零”,它可否作为空指针或浮点零? 18  1.32 下面的...
  • 中文版Excel.2007高级VBA编程宝典 1/2

    热门讨论 2012-04-06 16:00:16
    完整清晰版 PDF ,目录。共 270MB,分为 2 个分卷 中文版Excel 2007 高级VBA编程 宝典 OFFICE2007 中文版Excel 2007高级VBA编程宝典 原价:99.99元 作者:(美)沃肯巴赫(Walkenbach,J) 著;冯飞,焦瑜净 译 ...
  • CruiseYoung提供的带详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐) 基本信息 原书名: Pro Oracle SQL 原出版社: ...
  • 不同编译器给出不同的结果, 的为 3, 的为 4, 哪个是正确的? o 4.4 这是个巧妙的表达式: a ^= b ^= a ^= b 它不需要临时变量就可以交换 a 和 b 的值。 o 4.5 我可否用括号来强制执行我所需要的计算顺序? o ...
  • CruiseYoung提供的带详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《Oracle SQL高级编程》的源代码 对应的书籍资料见: Oracle SQL高级编程(资深Oracle专家力作,...
  • 使用Arouter注意事项有哪些?如何让代码变得更加容易让人维护? 直接看我这篇博客:https://juejin.im/post/5c46e6fb6fb9a049a5713bcc 4.6 存在待解决问题 动态的管理组件,所以给每个组件添加几个生命周期...
  • 你必须知道的495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    2.11 为什么sizeof 返回的值大于结构的期望值, 是不是尾部填充? . . 9 2.12 如何确定域在结构中的字节偏移? . . . . . . . . . . . . . . . . . 9 2.13 怎样在运行时用名字访问结构中的域? . . . . . . . . . . ...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

常量有哪些例子