美文网首页
Java经典面试题目

Java经典面试题目

作者: kill_ec94 | 来源:发表于2019-08-28 21:48 被阅读0次

    1.private 修饰的方法可以通过反射访问,那么private修饰的意义在哪里?

    因为private本职上是一种编程思想的体现,即封装的思想,用private修饰的变量和方法本质上都是不对外提供的,那么对于调用者来说,这些就是不可见的,所以它并不对这个事情负责;尤其是在一个大型工程里面来说,各个模块的业务范畴的定义是需要非常明确的,不归自己管的绝对不想管,所以如果我定义了一个private,那就意味着你尽量别用,如果你非得用,那么好,出了问题你负责,我不管的。

    2.Java的类初始化顺序

    总的原则就是先基类后自己,先静态后普通代码块后构造函数:

    所以,基类的静态字段和静态代码块-->>派生类的静态代码块-->>基类普通代码块和基类普通成员变量-->>基类构造函数-->>派生类普通代码块-->>派生类构造函数

    至于为什么先基类后自己,这个是很容易想明白的,因为加入我派生类依赖基类的某个变量,那肯定是要先基类准备好了,自己再去是更好的。而为什么先静态后普通代码块呢?我个人理解,是因为静态变量是属于某个类的,只要这个类被使用了,静态的就要先加载,至于后面实例化的哪个,它不管的。

    3.对方法区和永久区的理解以及它们之间的关系

    方法区是jvm规范里要求的,永久区是Hotspot虚拟机对方法区的具体实现,前者是规范,后者是实现方式。而Java8其实又做了修改,已经不再有永久区了,而是metaspace;

    4.一个java文件有3个类,编译后有几个class文件

    这个应该是有三个文件才是。

    5.局部变量使用前需要显式地赋值,否则编译通过不了,为什么这么设计

    因为编译器识别不出成员变量究竟会在啥时候使用和赋值,所以可以给个默认值,但是局部变量是很明显的,所以这种时候编译器给出这种约束可以极大的避免一些问题的产生。

    6.ReadWriteLock读写之间互斥吗

    读锁和读锁之间不互斥,其他都是互斥的。

    读写锁其实是有两个锁,一个读,一个写,他们共享同一个sync,但是分别用的是共享模式和非共享模式,这个是用state的头16位和尾16位去做的。

    7.Semaphore拿到执行权的线程之间是否互斥

    不是互斥的。

    8.写一个单例模式

    public class Singleton{

    private static class SingltonHandler{

    private staticSingleton singleton=new Singleton();

       }

    publicstaticSingletongetInstance() {

    return SingltonHandler.singleton;

       }

    }

    最简单的写法就是静态内部类,静态内部类维护一个外部的变量,而不用的时候也不会去加载它。

    9.B树和B+树是解决什么样的问题的,怎样演化过来,之间区别

    B+树和B树之间的核心区别就在于,mysql的每个节点是存储在一个页上面的,而对于B树来说每个页所存储的数据包含三个部分(key,子节点指针和data),所以我们希望每个页上存储更多的子节点这样能够保证B树更大的度,也就带来了更小的树深度,所以这就是为什么B+树把真实的data都放在叶子节点上的原因;

    10.写一个生产者消费者模式

    可以用lock和condition或者wait+notify的方式来写;

    11.写一个死锁

    这个很简单,两个线程互斥的取两份资源即可;

    12.cpu的100%定位

    先找到top进程,然后jstack,然后找这个进程中的top线程,最后转换下16进制就好了;

    13.int a=1是原子操作吗?

    是的,a++不是,long 不是,long被volatile修饰就是了

    14.for循环可以删除arraylist吗?

    不可以,因为删除元素时涉及到数组元素的移动。

    15.新的任务提交到线程池,线程池是怎样处理

    这个其实是个考察线程池原理的问题,线程池包含核心线程数,最大线程数,和队列,一般如果没有到核心线程数,会扩大核心线程数,如果是超过核心线程数,不到队列数,会加到队列里,如果是超过了队列+核心线程数,会扩容到最大线程数,最后,都不行,会执行拒绝策略;

    16.AQS和CAS原理

    CAS待梳理;

    17.synchronized底层实现原理

    是在Java对象的头上mark word里面存放的有:

    锁状态 对象的hashcode 对象分代年龄 是否是偏向锁 锁标志位

    锁一共有四种状态,从低到高分别是:无锁、偏向锁、轻量级锁和重量级锁,会随着竞争情况逐渐升级但只能升级不能降级。

    偏向锁是在栈帧中记录拥有偏向锁的线程id,如果是同个线程则直接获取,如果不是同个线程,那此线程会失败,并且通知这个偏向锁撤销;

    重点看下锁升级:

    偏向锁:如果有其他线程竞争锁,而且此时锁的拥有者还无法释放的时候,就会升级为轻量级锁;

    轻量级自选锁:如果自旋次数超过了某个阈值,或者线程1在执行,线程2在自旋等待,线程3又过来竞争的时候,就膨胀成重量级锁;

    18.volatile的作用

    防止指令重排,可见性;

    提到volatile就不得不说操作系统的解决各个cpu的高速缓存之间的缓存一致性的问题的思路,

    1.在总线上加lock,但是这种的话各个cpu都阻塞了;

    2.缓存一致性协议,如果发现操作的是共享变量,那就通知其他的cpu让这个缓存失效,这也就是会引发所谓的一致性协议风暴和缓存行失效的问题,也就是为什么要用clh队列做aqs的问题。

    19.AOP和IOC原理

    待梳理;

    20.Spring怎样解决循环依赖的问题

    利用缓存,先提前把各个bean暴露出去;

    22.dispatchServlet是怎样分发任务的?

    mvc待整理;

    23.jvm gc复制算法

    24.注解的原理

    25.进程间通信方式;

    26.Reentrantlock是可重入锁,啥是可重入?

    就是可以同一个线程进入两次,这个取决于它的实现,tryacquire的时候,发现如果当前线程和占领它的锁的线程是同个线程,就会直接获取锁;

    27.线程如果异常会怎样?

    线程的异常必须要线程自身去捕获并处理,如果不处理,这个线程会死掉,而且,这个线程的异常并不会被主线程所捕获;

    28.hashMap原理;

    1.8以后版本:

    1.7以前的版本就不看了,因为目前核心重点在关注的就是1.8了,首先还是一个链表或者叫数组吧,然后每个节点上下面不一定是链表了,还有可能是红黑树,这个阈值是8;

    先看put,如果不存在,直接插入就好,然后如果存在,那就进入到里面去,先取出对应位置的值放着;

    首先如果是红黑树,直接插进去,如果是链表,先插进去,再转换成红黑树。

    最后判断这取出的node是不是空,如果不空,覆盖掉它的value;

    最后,如果整个的值超过了阈值,就扩容;

    关于扩容:

    第一步:把数组扩大到两倍,把阈值扩大到两倍

    第二步:把原有的数据放到新的数组里,需要重新做hash,注意,这里的hash用的还是很巧妙的,它用的是hashcode&&table.size()-1 ,这样其实就把这个值散列到表的每个位置上面去,所以就也要求这个表的size必须要是powerof 2;说起来如何判断一个数字是powerof2也有个巧妙的方法,就是直接n&&(n-1)==0;

    至于concurrentHashmap,最难的地方在于扩容,扩容的过程是这样的:先把这个扩容的过程分成多个子任务,然后每个子任务去做各自的扩容;

    29.jvm虚拟机;

    30.Java类加载和双亲委派

    其实整个类加载有个非常核心的关键之处,就在于Java把获取class信息转换成byte数组这一步骤外包出去了,就是它不管你从哪里获取这个byte数组,你完全可以自行获取,这样才引出了各种各样的类加载器和双亲委派的类加载机制。

    Java有两类加载器,一类是系统提供的,另外一类是自定义的:

    系统提供的有三个:

    bootstrap :负责加载核心类库的

    extension:扩展库的ext

    app:classPath下的;

    所谓SPI,其实就是自己定义好了interface,但是不实现,让别人来实现,但是这里有几个问题:

    1.别人的实现你怎么知道在哪儿呢?

    那就放在固定的地方去META/INF底下,读取某个约定好的位置的信息,然后取出来看看叫啥名字

    2.自己的类可能是引导类加载器加载的,而别人的实现无法用引导类加载器加载?

    Java 应用运行的初始线程的上下文类加载器是系统类加载器。在线程中运行的代码可以通过此类加载器来加载类和资源。

    相关文章

      网友评论

          本文标题:Java经典面试题目

          本文链接:https://www.haomeiwen.com/subject/hsufzttx.html