Java面试2021

下面为拼多多、饿了么、蚂蚁金服、哈啰出行、携程、饿了么、2345、百度等公司给我留下较深印象的一些java面试题

1. Private修饰的方法可以通过反射访问,那么private的意义是什么
答:1.java的private修饰符并不是为了绝对安全性设计的,而是对用户常规使用java的一种约束。2.从外部对对象进行常规调用时,能够看到清晰的类结构。

2. Java类初始化顺序
答:基类静态代码块,基类静态成员字段(并列优先级,按照代码中出线的先后顺序执行,且只有第一次加载时执行)-》派生类静态代码块,派生类静态成员变量(并列优先级,按照代码中出线的先后顺序执行,且只有第一次加载时执行)-》基类普通代码块,基类普通成员字段(并列优先级,按照代码中出线先后顺序执行)-》基类构造函数-》派生类普通代码块,派生类普通成员字段(并列优先级,按照代码中出线先后顺序执行)-》派生类构造函数

3. 对于方法区和永久区的理解以及他们的关系
答:方法区是jvm规范里要求的,永久区是Hotsport虚拟机对方法区的具体实现,前者是规范,后者是实现方式。jdk1.8做了改变

4. 一个Java文件有3个类,编译后有几个class文件
答:3个 文件中有几个类编译后就有几个class文件。

5. 局部变量使用前需要显示的赋值,否则编译通过不了,为什么这么设计
答:对于成员变量来说,其赋值和取值的访问先后顺序有不确定性,编译器确定不了,交给jvm去做比较合适。对于局部变量而言,其赋值和取值访问顺序是确定的,这样设计是一种约束,可以减少使用者犯错的可能。

6. ReadWriteLock读写之间互斥吗
答: ReadWriteLock读写锁,使用场景可分为读/读,读/写,写/写,除了读与读之间是共享的,其他都是互斥的。

7. Semaphore拿到执行权的线程之间是否互斥
答:Semaphore可有多把锁,可允许多个线程同时拥有执行权,这些执行权的线程并发访问同一对象,会产生线程安全问题。


8. 单例有几种实现方式
饿汉,懒汉,静态内部类,枚举,双检锁。
多线程下保证线程安全用双检索,为什么要2次校验,对象加上volatile关键字,原子性可见性,java内存模型,类的加载过程。

public class Singleton {
   private Singleton(){
   }

   public volatile static Singleton instance;
   
   public static Singleton getInstance(){
       if(null == instance){
           synchronized (Singleton.class){
               if(null == instance){
                   instance = new Singleton();
               }
           }
       }
       return instance;
   }
}

9. B树跟B+树是解决什么样的问题的,怎么演化过来,之间的区别
答:mysql索引的实现原理。二叉树会产生退化线象,提出来平衡二叉树,怎样养每一层放的节点多一些来减少遍历高度,引申出m叉树, m叉树有退化现象,引出m叉平衡树,也就是B树,这时候每个节点即放了key也放了value,怎么样将每个节点放尽可能多的key值,以减少遍历高度(访问磁盘次数),可以将每个节点只放key值,将value值放在叶子节点,在叶子节点的value值增加指向相邻节点指针,这就是优化后的B+树。

10. 写一个生产者消费者模式
生产者消费者模式,synchorized锁住一个LinkedList,一个生产者,只要队列不满,生产后往里放,一个消费者只要队列不空,向外取,两者通过wait()和notify()进行协调,如何提高效率 :消息队列

11. 写一个死锁
定义2个arraylsit,加上锁A,B。线程1,2。1拿着锁A,请求锁B,2拿住了锁B请求锁A,在等待对方释放锁的过程知乎谁也不让出已获得的锁。

public static void main(String[] args) {
       final List<Integer> list1 = Arrays.asList(1,2,3);
       final List<Integer> list2 = Arrays.asList(4,5,6);

       new Thread(new Runnable() {
           @Override
           public void run() {
               synchronized (list1){
                 for(Integer i : list1){
                     System.out.println(i);
                 }
                 try{
                     Thread.sleep(1000);
                 }catch (InterruptedException e){
                     e.printStackTrace();
                 }
                 synchronized (list2){
                     for(Integer i : list2){
                         System.out.println(i);
                     }
                 }
               }
           }
       }).start();

       new Thread(new Runnable() {
           @Override
           public void run() {
               synchronized (list2) {
                   for (Integer i : list2) {
                       System.out.println(i);
                   }
                   try {
                       Thread.sleep(1000);
                   }catch (InterruptedException e){
                       e.printStackTrace();
                   }
                   synchronized (list1){
                       for (Integer i : list1) {
                           System.out.println(i);
                       }
                   }
               }
           }
        }).start();
   }

12. CPU 100%怎么定位

13. String a = “ab”;String b = “a” + “b”;a == b是否相等 相等
14. int a =1 是原子性操作吗
15. 使用for循环删除ArrayList的特定元素吗
不行 重复的只能删除一个
用iterator

 public static void reverse(){
       List<String> list = new ArrayList<>(Arrays.asList("a","b","c","d"));
       System.out.println(list);
       Iterator<String> iterable =  list.iterator();
       while (iterable.hasNext()){
           String element = iterable.next();
           iterable.remove();
       }

       System.out.println(list);
   }

16. 新的任务提交到线程池,线程池如何处理
第一步:判断工作队列是否已满,如果不是,创建一个新的工作线程来执行任务,如果核心线程池里的线程都在执行任务,则执行第二步。

17. AQS和CAS原理
AQS是抽象队列同步器 AQS实际上是以双向队列的形式连接所有的entry,比如ReentrantLock,所有等待的线程都被放在一个Entry中连接成双向队列。
比较并交换CAS,假设有三个操作数:内存值V,旧的预期值A,要修改的值B。当且仅当A与V的值相同,才会修改B的值并返回true,否者什么都不做返回false,比较并交换是一个原子操作,CAS一定要volatile变量配合。

CAS问题:
1.循环时间长
2.只能保证一个共享变量的原子操作
3.ABA问题

18. synchronized实现原理
设计到2条指令:monitorenter,monitorexit; 再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和monitorexit来实现,相对于普通方法,其常量池多了ACC_SYNCHORIZED标识符。
JVM是根据该标识符来实现方法的同步的:当方法被调用时,调用指令将会检查方法的ACC_SYNCHORIZED访问该标识符是否被设置,如果设置了,执行线程将先获取monitor,获取成功后才能执行方法体,方法体执行完后在释放monitor。在执行方法期间,其他任何线程都无法再获得同一个monitor对象。

19. volatile指令,指令重排
volatile可以保证可见性,每次读取volatile变量,一定是最新的数据。
底层代码执行不像Java 程序这么简单,它的执行是java代码-》字节码-》根据字节码执行对应的c/c++代码-》c/c++代码被编译成汇编语言-》和硬件电路交互,现实中,未来获取更好性能JVM可能会对指令进行重排序,多线程下会出现一些意想不到的问题。volatile禁止重排序,一定程度降低了代码执行效率。

20. AOP IOC

21. spring怎么样解决循环依赖

22. dispatchServlet怎么分发任务

23. mysql给离散度低的字段建立索引会出现什么问题。

24. HashMap既然有hash排序,还需要equals干什么
hashcode相同,元素对象也不一定重复
hashcode不同,元素对象一定不重复
equals判断最精确的,用hashcode做第一步判断是为了提高程序的效率。

25 jvm gc复制算法怎样实现
26. 注解的原理
27. 进程间通信的方式
28. ReentrantLock是可重入锁,什么是可重入锁
29. 线程执行过程遇到异常发生什么 怎么处理
30. HashMap.put元素发生冲突,为什么使用LinkedList(拉链法)而不用ArrayList
31. Object object = new Object()初始化的顺序 在jvm各区域做了什么
32. 线程怎么样按顺序执行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值