Java面试题汇总

面试题
汇总:Java 初级面试题及答案
总汇:分享下最近面试二十多家公司总结的java高级面试题
(一)Java基础部分
1.Java中有哪些基本数据类型?String是基本数据类型吗?String类是否能够继承?
答:1.java定义了4中类8种基本类型:
            整型:byte、short、int、long
            浮点型:float、double
            布尔型: boolean
            字符型: char
        2.String不是基本数据类型,String属于引用类型。
        3.String类是一个final类,因此不能被继承。
2.简述++i和i++的区别?
答:

  int i=0;
  System.out.print("++i先自加1再赋值得到结果是=");
  System.out.println(++i);
  控制台打印:++i先自加1再赋值得到结果是=1
  ----------------------------------------
  int i=0;
  System.out.print("i++先赋值,然后再自加1得到结果=");
  System.out.println(i++);
  控制台打印:i++先赋值,然后再自加1得到结果=0

3.short s=1;s=s+1;有什么错?short s=1;s+=1;有什么错?
答:1.对于short s=1;s=s+1;由于short数据类型和int数据类型表示范围不一样,所以需要进行类型转换,解决方案是:要么将short改为int,要么强制类型转换(short)s+1。
      2.对于 short s=1;s+=1;由于+=是Java的规定运算符,Java编译器会对它进行特殊处理,因此可以正确编译。
4.Integer和int的区别?
答:参考博客 Integer是一个封装int类型的封装类,默认值为null,int是Java中8中数据类型之一,默认值为0.
5.&和&&的区别?
答:当&运算符两边的表达式的结果都为true时,整个运算结果才为true。而&&运算符第一个表达式为false时,则结果为false,不再计算第二个表达式。
6.使用最有效的方式计算出2乘以4等于几?
答:使用位运算:2<<2
7.String s=new String(“xyz”)创建了几个对象?
答:创建2个String对象,一个是=null的s,一个是=“xyz”的string。
8. 静态变量和实例变量的区别?
答:1.在语法上的区别:静态变量前需要加static关键字,而实例变量不需要加。
       2.静态变量不是某一个实例对象的属性,它属于类属性,只要程序加载类的字节码,不需要创建任何实例对象静态变量就可以分配空间从而被使用。必须先创建实例对象,实例变量才会被分配空间,才能使用这个实例变量。
       3. 无论创建多少实例对象,永远只分配一个静态变量。创建一个实例对象静态变量会加1,但是每创建一个实例对象就会分配一个实例变量,每个实例变量的值只会自加1.

public class TestProblem {
	static int a=0;
	int b=0;
	public TestProblem() {
		a++;
		b++;
		System.out.println("静态变量数值:"+a);
		System.out.println("实例变量数值:"+b);
	}
	public static void main(String[] args) {
		 
		TestProblem testProblem=new  TestProblem();
		System.out.println("------------");
		 
		TestProblem testProblem1=new  TestProblem();
	  
	}
}
控制台打印结果:
   静态变量数值:1
   实例变量数值:1
   ------------
   静态变量数值:2
   实例变量数值:1

9.switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
答:1.switch常量表达式的值必须是整型(必须是int)或字符型。
     2.在.switch表达式中,括号表达式只能是一个整型表达式或枚举常量整数表达式可以是int基本数据类型会Integer包装类型。由于byte、short、char都可以隐式转换为int,所以这些基本数据类型及其包装类型都可以。
          3.long和String无法隐式转换为int类型所以不能在switch中使用。
10.简述String、StringBuffer 和 StringBuilder 区别
答:1.String和StringBuffer的区别:它们都是用于存储和操作字符串,01.String是一个final类表示的类容不可改变。StringBuffer表示的内容可以修改。02.String实现了equals()方法,StringBuffer没有。
        2.StringBuffer 和 StringBuilder 区别:01.StringBuffer是线程安全的可以在多线程中使用。 StringBuilder是线程不安全的,但是运行效率非常高!
          3.参考博客String、StringBuffer 和 StringBuilder 区别
11.简述自动装箱和自动拆箱
答: 参考:深入剖析Java中的装箱和拆箱
12.简述Java中实现多态的机制是什么?
答:重载(overloading)、重写(overriding)
       1.重载(overloading):是一个类中多态的表现,比如一个类中定义多个同名的方法,但它们具有不同的参数或不同参数类型都称之为重载。
       2.重写(overriding):子类定义一个方法和父类的方法名称参数都相同,那么父类的方法被重写。
       3.参考:理解java的三大特性之多态
13.简述Java反射机制及其作用?
答:1.Reflection:是Java被视为一种动态语言的一个关键性质,这个机制允许程序在运行时通过Reflection API获取任意一个已知名称Class的内部信息。并可在运行时改变字段内容,唤起methods。
       2.参考:Java反射机制详解
       3.Java API:Class类中的方法

14.简述java中super()和this()、super和this的区别?
答:super()和this()区别:

  • super():调用父类无形参的构造方法;

  • super(形参):调用父类中某个带形参的构造方法;

  • this(形参):调用本类中另一种形式的构造方法

  • 注意:放在方法的首行;
       2.super和this的区别:

  • super.父类的成员变量;

  • super.父类的方法;

  • super:当子类中的成员变量、方法和父类的相同时,实现调用父类的成员变量和方法;

  • this:代表当前的对象;

  • 使用的地方:若函数的形参和成员变量同名时,需要用this.成员变量名

15.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

public class Main {
 
    static int test(){
        int x = 1;
        System.out.println("111111111");
        try{
            System.out.println("22222222");
            return x;
        }finally {
            System.out.println("333333333");
            x = 2;
            System.out.println(x);
            System.out.println("444444444");
        }
    }
 
    public static void main(String[] args) {
        System.out.println(new Main() .test());
    }
}
结果:111111111
22222222
333333333
2
444444444
1

16. 以下输出结果为

class A{
    static {
        System.out.println("1");
    }
    public A(){
        System.out.println("2");
    }
    {
        System.out.println("3");
    }
}
class B extends A{
    static {
        System.out.println("4");
    }
    public B(){
        System.out.println("5");
    }
    {
        System.out.println("6");
    }
}
public class Test {
    public static void main(String[] args) {
       new B();
    }
}
1 4 3 2 6 5

(二)java集合基础面试

1.简述ArrayList和LinkedList的区别?
答:1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于双向链表的数据结构。
       2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
       3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
       4.参考:ArrayList和LinkedList的区别
2.简述HashMap的工作原理及HashMap和Hashtable的区别?
答:1.参考:HashMap的工作原理
       2.参考:参考:HashMap的工作原理
       3.参考:HashMap和Hashtable的区别
       4.参考:深入探讨HashMap的结构实现和功能原理。
       5.参考:按位与 按位或
3.arrayList和vector的区别

  1. ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
  2. Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
  3. LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
  4. vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。
  5. 如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
  6. 如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而
    如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用Linkedlist,因为它移动一个指定位置的数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!
  7. 笼统来说:LinkedList:增删改快 ArrayList:查询快(有索引的存在)

4.List和 Map区别?
List:是存储单列数据的集合,存储的数据是有序并且是可以重复的
Map:存储双列数据的集合,通过键值对存储数据,存储的数据是无序的,Key值不能重复,value值可以重复
5.HashMap如何扩容?
参考:深入理解HashMap的扩容机制
JDK1.8之前HashMap的数据结构:数据+单向链表,默认容量16,加载因子0.75,向HashMap添加键值对时,当添加的数据个数大于等于(默认容量*加载因子),立马进行扩容。
6.HashMap底层实现原理?
参考:Java HashMap工作原理及实现
视频:阿里架构师带你分析HashMap源码实现原理
7.java中Collections.sort()和Arrays.sort()底层所采用的排序算法?
参考:Java中Collections.sort()和Arrays.sort()所采用的排序算法
8.为什么Java8中HashMap链表使用红黑树而不是AVL树?
参考:为什么Java8中HashMap链表使用红黑树而不是AVL树
9.说一下你对ConcurrentHashMap底层原理的理解
参考视频:BAT面试必备之ConcurrentHashMap原理分析
参考:ConcurrentHashMap深入理解

(三)Java并发编程
1.Java面试题目汇总(一)

2.Java面试题目汇总(二)
3.死锁产生的条件以及如何避免死锁的发生?
参考:Java中死锁的简单例子及其避免
参考:Java 实例 - 死锁及解决方法

/**
 * 一个简单的死锁类
 * 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒
 * 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒
 * td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定;
 * td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定;
 * td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而导致死锁。
 */

@Slf4j
public class DeadLock implements Runnable {
    public int flag = 1;
    //静态对象是类的所有对象共享的
    private static Object o1 = new Object(), o2 = new Object();

    @Override
    public void run() {
        log.info("flag:{}", flag);
        if (flag == 1) {
            synchronized (o1) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (o2) {
                    log.info("1");
                }
            }
        }
        if (flag == 0) {
            synchronized (o2) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (o1) {
                    log.info("0");
                }
            }
        }
    }

    public static void main(String[] args) {
        DeadLock td1 = new DeadLock();
        DeadLock td2 = new DeadLock();
        td1.flag = 1;
        td2.flag = 0;
        //td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。
        //td2的run()可能在td1的run()之前运行
        new Thread(td1).start();
        new Thread(td2).start();
    }
}

4.CAS实现原理以及ABA问题的解决方法?
参考:详细解读 CAS 实现原理
CAS简述:
CAS(Compare And Swap/Set)比较并交换,CAS 算法的过程是这样:它包含 3 个参数CAS(V,E,N)。V 表示要更新的变量(内存值),E 表示预期值(旧的),N 表示新值。当且仅当 V 值等于 E 值时,才会将 V 的值设为 N,如果 V 值和 E 值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。最后,CAS 返回当前 V 的真实值。

CAS 操作是抱着乐观的态度进行的(乐观锁),它总是认为自己可以成功完成操作。当多个线程同时使用 CAS 操作一个变量时,只有一个会胜出,并成功更新,其余均会败。失败的线程不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。基于这样的原理,CAS 操作即使没有锁,也可以发现其他线程对当前线程的干扰,并进行恰当的处理。

ABA问题:
CAS 会导致“ABA 问题”。CAS 算法实现一个重要前提需要取出内存中某时刻的数据,而在下时刻比较并替换,那么在这个时间差类会导致数据的变化。

比如说一个线程 one 从内存位置 V 中取出 A,这时候另一个线程 two 也从内存中取出 A,并且two 进行了一些操作变成了 B,然后 two 又将 V 位置的数据变成 A,这时候线程 one 进行 CAS 操作发现内存中仍然是 A,然后 one 操作成功。尽管线程 one 的 CAS 操作成功,但是不代表这个过程就是没有问题的。

部分乐观锁的实现是通过版本号(version)的方式来解决 ABA 问题,乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行+1 操作,否则就执行失败。因为每次操作的版本号都会随之增加,所以不会出现 ABA 问题,因为版本号只会增加不会减少。
5.讲讲你对ThreadLocal的一些理解
参考:手撕面试题ThreadLocal
6.线程池复用技术的实现原理?
参考:线程池原理浅析
参考:线程池的执行流程
参考: 深入源码分析Java线程池的实现原理
参考:线程池的实现原理、优点与风险、四种线程池实现
7.synchronized 和 和 ReentrantLock 的区别?
共同点:

  1. 都是用来协调多线程对共享对象、变量的访问
  2. 都是可重入锁,同一线程可以多次获得同一个锁
  3. 都保证了可见性和互斥性

不同点:

  1. ReentrantLock 显示的获得、释放锁,synchronized 隐式获得释放锁
  2. ReentrantLock 可响应中断、可轮回,synchronized 是不可以响应中断的,为处理锁的不可用性提供了更高的灵活性
  3. ReentrantLock 是 API 级别的,synchronized 是 JVM 级别的
  4. ReentrantLock 可以实现公平锁
  5. ReentrantLock 通过 Condition 可以绑定多个条件
  6. 底层实现不一样, synchronized 是同步阻塞,使用的是悲观并发策略,lock 是同步非阻塞,采用的是乐观并发策略
  7. Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现。
  8. synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁。
  9. Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用 synchronized 时,等待的线程会一直等待下去,不能够响应中断
  10. 通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到
  11. Lock 可以提高多个线程进行读操作的效率,既就是实现读写锁等。

8.ReentrantLock公平锁和非公平锁的区别,可以从性能方面讲?
参考:ReentrantLock中公平锁/非公平锁详解
9.ConcurrentHashMap的底层实现原理?
参考:JAVA ConcurrentHashMap底层实现
10.谈一下volatile关键字你是怎么理解的?能否保证原子性?比较synchronized关键字不同
1.volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。
但是volatile关键字只能用于变量,而synchronized关键字可以修饰方法以及代码块。
synchronized关键字在JavaSE1.6之后进行了优化,主要包括为了减少获得锁和释放锁带来的性能
消耗而引入的偏向锁和轻量级锁以及其它各种优化,执行效率有了显著提升,实际开发中使
用 synchronized 关键字的场景还是更多一些。
2.多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。
3.volatile关键字能保证数据的可见性,但不能保证数据的原子性。
synchronized关键字两者都能保证。
4.volatile关键字主要用于解决变量在多个线程之间的可见性,
而synchronized关键字解决的是多个线程之间访问资源的同步性。
11.谈一下乐观锁和悲观锁?
参考:面试必备乐观锁和悲观锁

12.以下程序打印结果为

class A implements Runnable{
    @Override
    public void run() {
        System.out.println("aaaaaa");
    }
}
public class Test {
    public static void main(String[] args) {
        A a =new A();
       Thread thread = new Thread(a){
           @Override
           public void run() {
               System.out.println("bbbbbb");
           }
       };
       thread.start();
    }
}
//打印结果为:bbbbbb

13.一下程序的输出结果?如何保证先打印1,后打印2?如何保证先打印2后打印1?

class ThreadTest{
    public  void test() throws InterruptedException {
        Thread t = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("1");
                    }
                }
        );
        t.start(); //1.保证“1”会被打印
        t.join();  //2.保证“1”先打印,“2”后打印 
        //3.如果线程没有调用start()、join()只打印“2”
        System.out.println("2");  
    }
}
public class Test {
    public static void main(String[] args) throws InterruptedException {
       new  ThreadTest().test();
    }
}

14.控制线性执行顺序的8种方法
参考:让线程按顺序执行8种方法
15.进程、线程、协程的区别
参考:进程、线程、协程的区别
16.进程间通信的方式有哪些?线程间通讯方式有哪些?
参考:进程间通信的方式有哪些?线程间通讯方式有哪些?

(四) 数据库面试题总汇
1.讲述一下MySQL 四种隔离级别
参考:面试问烂的MySQL 四种隔离级别
参考:MySQL的四种事务隔离级别
参考:Spring事务底层原理分析全集
2.讲述一下MySQL有哪些存储引擎各自的优缺点及应用场景
参考:MySQL有哪些存储引擎,各自的优缺点,应用场景
参考:MySQL常用存储引擎
3.MySQL 如何避免索引失效?
参考:索引优化:避免索引失效
4.针对千万级别的数据表,如何优化分页查询?
参考:MySQL大数据量分页查询优化的锦囊妙计
5.说一下MySQL行锁、表锁、悲观锁、乐观锁的特点与应用场景?
参考:MySQL行锁、表锁、悲观锁、乐观锁的特点与应用
6.使用mysql索引有哪些原则?索引采用了什么数据结构?这些索引数据结构各有什么特点?
参考:MySql创建索引的原则
B+树:
磁盘读取代价更低
查询效率更加稳定
有利于对数据库的扫描
支持范围查查
Hash:
Hash索引查询速度比B+树高
只能满足“=”、“IN”不能满足范围查询
无法被用来避免数据排序操作
不能利用部分索引键查询
不能避免表扫描
遇到大量Hash 值相同的情况下性能不一定会比B+树索引高
不支持范围查查
7.简述聚簇索引和非聚簇索引的区别
参考:聚簇索引、非聚簇索引、覆盖索引区别

(五) Spring全家桶面试题总汇
1.Spring AOP工作中用到哪些场景?讲述一下Spring AOP的实现原理?
AOP用于日志记录,权限验证,事务控制,性能检测,错误信息检测等
参考:SpringAOP实现事务
参考:完全读懂Spring框架之AOP实现原理
2.spring aop能否拦截类内部的方法调用?比如在类中A方法嵌套类中的B方法,B方法是否能够被AOP拦截?
参考:Spring AOP无法拦截内部方法调用
3.讲述一下Spring的IOC原理 ?
参考:Spring IOC 容器源码分析
参考:Java中高级面试题中的Spring的IOC原理
4.比较JDK动态代理和CGLib代理的区别及优缺点?
参考:Spring AOP中的JDK和CGLib动态代理哪个效率更高
5.描述一样Spring事务的7种传播行为?
参考:Spring事务管理(详解+实例)
参考:看完就明白_spring事务的7种传播行为
6.简述Filter和Interceptor的区别

  • 使用范围不同:Filter是Servlet规定的,只能使用在web应用,而拦截器可以用于web,apllication、swing等应用
  • 规范不同:Filter是Servlet规范中定义的,只能在Servlet容器中使用。拦截器是Spring容器中规范中定义的,只能在spring应用中使用
  • 深度不同:Filter只在Servlet前后起作用,而拦截器可以深入到方法的前后,异常抛出前后。在Spring架构的程序中优先使用拦截器。

(六)设计模式面试题目
1.代码写出5中单例模式的实现
参考:java 单例模式5种写法
2.Spring中的常见设计模式有哪些?
Spring 中常见的设计模式
工厂模式 : BeanFactory
装饰器模式: BeanWrapper
代理模式: AopProxy
单例模式: ApplicationContext
委派模式: DispatcherServlet
策略模式: HandlerMapping
适配器模式: HandlerApdapter
模板方法模式: JdbcTemplate
观察者模式: ContextLoaderListener

Spring 的四大模块及典型的设计模式
1、Spring IOC 工厂模式、单例模式、装饰器模式
2、Spring AOP 代理模式、观察者模式
3、Spring MVC 委派模式、适配器模式
4、Spring JDBC 模板方法模式
(六) JVM面试题汇总
1.谈谈JVM内存模型
参考:深入理解JVM-内存模型
2.谈谈JMM内存模型
参考:Java内存模型
3.谈谈导致OOM的原因及解决方法
参考:高手总结的9种 OOM 常见原因及解决方案
4.JVM内存溢出的原因?内存溢出时为什么JVM没有回收?
答:死循环导致内存溢出,存在无用但可达的对象,这些对象不能被JVM回收,导致耗费内存资源
5.JVM运行时数据区包括哪几个部分?有什么作用?

  1. java堆:存放实例化对象、数组、成员变量
  2. java虚拟机栈:栈的结构是栈帧组成的,调用一个方法就压入一帧,帧上面存储局部变量表,操作数栈,方法出口等信息,局部变量表存放的是8大基础类型加上一个应用类型,所以还是一个指向地址的指针
  3. 方法区:主要是存储类信息,常量池(static常量和static变量),编译后的代码(字节码)等数据
  4. 本地方法栈:为虚拟机使用到的Native方法服务
  5. 程序计数器:记录当前线程执行的行号

6.如和判断一个对象是否存活?
引用计数算法:给每一个对象设置一个引用计数器,每当有一个地方引用这个对象时,就将计数器加一,引用失效时,计数器就减一。当一个对象的引用计数器为零时,说明此对象没有被引用,也就是“死对象”,将会被垃圾回收.
缺点:无法解决对象之间循环引用导致GC收集器无法收集而产生OOM

可达性分析算法:
从一个被称为 GC Roots 的对象开始向下搜索,如果一个对象到 GC
Roots 没有任何引用链相连时,则说明此对象不可用。
7.java中垃圾收集的算法有哪些?
1.标记-清除算法
这是垃圾收集算法中最基础的,根据名字就可以知道,它的思想就是标记哪些要被
回收的对象,然后统一回收。这种方法很简单,但是会有两个主要问题:1.效率不
高,标记和清除的效率都很低;2.会产生大量不连续的内存碎片,导致以后程序在
分配较大的对象时,由于没有充足的连续内存而提前触发一次 GC 动作

2.复制算法:
为了解决效率问题,复制算法将可用内存按容量划分为相等的两部分,然后每次只
使用其中的一块,当一块内存用完时,就将还存活的对象复制到第二块内存上,然
后一次性清楚完第一块内存,再将第二块上的对象复制到第一块。但是这种方式,
内存的代价太高,每次基本上都要浪费一般的内存。
于是将该算法进行了改进,内存区域不再是按照 1:1 去划分,而是将内存划分为
8:1:1 三部分,较大那份内存交 Eden 区,其余是两块较小的内存区叫 Survior 区。
每次都会优先使用 Eden 区,若 Eden 区满,就将对象复制到第二块内存区上,然
后清除 Eden 区,如果此时存活的对象太多,以至于 Survivor 不够时,会将这些对
象通过分配担保机制复制到老年代中。(java 堆又分为新生代和老年代)

3.标记-整理算法:
该算法主要是为了解决标记-清除,产生大量内存碎片的问题;当对象存活率较高
时,也解决了复制算法的效率问题。它的不同之处就是在清除对象的时候现将可回
收对象移动到一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片了。

4.分代收集算法:
现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生
代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那
么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担
保,所以可以使用标记-整理 或者 标记-清除。
8.垃圾回收中GC Root对象有哪几种?

  • 虚拟机栈中引用的对象
  • 方法区类静态属性引用的对象
  • 方法区常量池引用的对象
  • 本地方法栈 JNI 引用的对象

9.简述java内存分配策略

  • 对象优先在堆的 Eden 区分配
  • 大对象直接进入老年代
  • 长期存活的对象将直接进入老年代

10.Minor GC&Full GC&Major GC区别及触发条件
参考:Minor GC&Full GC&Major GC区别及触发条件

(七)分布式系统面试题汇总
1.在分布式系统中如何保证事务一致性?
参考:十年架构师经验总结:分布式事务解决方案
2.分布式系统是如何保证幂等性
参考:分布式系统中实现幂等性的几种方式
参考:分布式幂等问题解决方案三部曲
参考:分布式系统、微服务架构的一致性和幂等性问题相关概念解析
3.分布式锁有哪些常见的实现方式?列出几种,并说明其实现思路
参考:分布式锁简单入门以及三种实现方式介绍
4.分布式系统如何解决Redis中的数据和数据库中的数据一致?
参考:数据库缓存最终一致性的四种方案
5.两个Quartz定时任务同时向数据库修改数据如何解决?
参考:分布式 集群环境下如何避免定时任务执行多次的解决方法

(八)Linux面试题总汇
1.常见日志分析命令

1.cat命令适用于打开较小的文件:
-- cat show.log
-- cat show.log -n 显示文件行号

2.more命令分页显示文件:
-- more show.log
-- Enter按键显示下行  
-- F按键显示下一屏幕内容  
-- B按键显示上一屏幕内容

3.less命令打开并可在文件末尾查询内容
-- less show.log

4.tail命令查看日志末尾内容
-- tail -n2 -f show.log

5.head命令查看日志文件前几行内容
-- head -n2 -f show.log

2.实时查看服务器日志文件内容
答案:tail -f access.log
3.查找进程名称为tomcat的进程ID
答案:ps -ef | grep tomcat 或 ps -aux | grep tomcat
4.查看进程号所占用的端口号
答案:netstat -nap | grep 进程pid
参考:Linux下查看进程和端口
5.查看实例(进程)启动参数(JVM参数)
答案:jsp -v
6.查看gc情况
参考:jstat命令查看jvm的GC情况
7.检查内存泄漏
参考:jmap命令使用场景
8.线上服务CPU飙高怎么排查?

  1. 先执行top命令,找到CPU占用较高的进程
  2. jstack 进程id > show.txt
  3. top -p 进程id -H 找到进程中CPU占用比较高的线程,通过进制转换工具把线程id转换为16进制
  4. cat show.txt | grep ‘线程id转换成16进制数’ 。根据线程id查看线程具体状态。

(九)设计模式面试题目
参考:23种设计模式汇总整理
(十)Dubbo分布式服务框架
1.dubbo中为什么使用RPC通信,而不使用HTTP?
参考:HTTP和RPC的优缺点
(十一)计算机网络
1.TCP与UDP的区别,TCP是如何保证数据传输不丢失?
2.HTTP和HTTPS的区别
(十二)数据结构+基础算法
1.使用任意语言编写快速排序算法
2.手写二叉树前、中、后遍历编码
3.用代码实现栈入栈和出栈操作

  • 33
    点赞
  • 261
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值