Java|2020年全新、多面的Java面试题,你有收藏到吗?

Java|2020年全新、多面的Java面试题,你有收藏到吗?

文章图片

Java|2020年全新、多面的Java面试题,你有收藏到吗?

2020年全新Java面试题总结 , 你有收藏到吗?
1.面试总图架构
算法在很多大厂里占的比例特别大

2. List、Set、Map 之间的区别是什么?

3. spring有哪些主要模块?
Spring框架至今已集成了20多个模块 。 这些模块主要被分如下图所示的核心容器、数据访问/集成、Web、AOP(面向切面编程)、工具、消息和测试模块 。

4.说一下 runnable 和 callable 有什么区别?
有点深的问题了 , 也看出一个Java程序员学习知识的广度 。

  • Runnable接口中的run()方法的返回值是void , 它做的事情只是纯粹地去执行run()方法中的代码而已;
  • Callable接口中的call()方法是有返回值的 , 是一个泛型 , 和Future、FutureTask配合可以用来获取异步执行的结果 。
5. sleep()和 wait() 有什么区别?
sleep():方法是线程类(Thread)的静态方法 , 让调用线程进入睡眠状态 , 让出执行机会给其他线程 , 等到休眠时间结束后 , 线程进入就绪状态和其他线程一起竞争cpu的执行时间 。 因为sleep() 是static静态的方法 , 他不能改变对象的机锁 , 当一个synchronized块中调用了sleep() 方法 , 线程虽然进入休眠 , 但是对象的机锁没有被释放 , 其他线程依然无法访问这个对象 。
wait():wait()是Object类的方法 , 当一个线程执行到wait方法时 , 它就进入到一个和该对象相关的等待池 , 同时释放对象的机锁 , 使得其他线程能够访问 , 可以通过notify , notifyAll方法来唤醒等待的线程
6. notify()和 notifyAll()有什么区别?
  • 如果线程调用了对象的 wait()方法 , 那么线程便会处于该对象的等待池中 , 等待池中的线程不会去竞争该对象的锁 。
  • 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程) , 被唤醒的的线程便会进入该对象的锁池中 , 锁池中的线程会去竞争该对象锁 。 也就是说 , 调用了notify后只要一个线程会由等待池进入锁池 , 而notifyAll会将该对象等待池内的所有线程移动到锁池中 , 等待锁竞争 。
  • 优先级高的线程竞争到对象锁的概率大 , 假若某线程没有竞争到该对象锁 , 它还会留在锁池中 , 唯有线程再次调用 wait()方法 , 它才会重新回到等待池中 。 而竞争到对象锁的线程则继续往下执行 , 直到执行完了 synchronized 代码块 , 它会释放掉该对象锁 , 这时锁池中的线程会继续竞争该对象锁 。
7.线程池中 submit()和 execute()方法有什么区别?
  • 接收的参数不一样
  • submit有返回值 , 而execute没有
  • submit方便Exception处理
8. synchronized和 volatile 的区别是什么?
  • volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的 , 需要从主存中读取; synchronized则是锁定当前变量 , 只有当前线程可以访问该变量 , 其他线程被阻塞住 。
  • volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的 。
  • volatile仅能实现变量的修改可见性 , 不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性 。
  • volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞 。
  • volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化 。
9. synchronized和 Lock 有什么区别?
  • 首先synchronized是java内置关键字 , 在jvm层面 , Lock是个java类;
  • synchronized无法判断是否获取锁的状态 , Lock可以判断是否获取到锁;
  • synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁) , Lock需在finally中手工释放锁(unlock()方法释放锁) , 否则容易造成线程死锁;
  • 用synchronized关键字的两个线程1和线程2 , 如果当前线程1获得锁 , 线程2线程等待 。 如果线程1阻塞 , 线程2则会一直等待下去 , 而Lock锁就不一定会等待下去 , 如果尝试获取不到锁 , 线程可以不用一直等待就结束了;
  • synchronized的锁可重入、不可中断、非公平 , 而Lock锁可重入、可判断、可公平(两者皆可);
  • Lock锁适合大量同步的代码的同步问题 , synchronized锁适合代码少量的同步问题 。
10. synchronized和 ReentrantLock 区别是什么?
synchronized是和if、else、for、while一样的关键字 , ReentrantLock是类 , 这是二者的本质区别 。 既然ReentrantLock是类 , 那么它就提供了比synchronized更多更灵活的特性 , 可以被继承、可以有方法、可以有各种各样的类变量 , ReentrantLock比synchronized的扩展性体现在几点上:
  • ReentrantLock可以对获取锁的等待时间进行设置 , 这样就避免了死锁
  • ReentrantLock可以获取各种锁的信息
  • ReentrantLock可以灵活地实现多路通知
另外 , 二者的锁机制其实也是不一样的:ReentrantLock底层调用的是Unsafe的park方法加锁 , synchronized操作的应该是对象头中mark word 。
11. spring中的 bean 是线程安全的吗?
Spring容器中的Bean是否线程安全 , 容器本身并没有提供Bean的线程安全策略 , 因此可以说spring容器中的Bean本身不具备线程安全的特性 , 但是具体还是要结合具体scope的Bean去研究 。
12. spring支持几种 bean 的作用域?
【Java|2020年全新、多面的Java面试题,你有收藏到吗?】当通过spring容器创建一个Bean实例时 , 不仅可以完成Bean实例的实例化 , 还可以为Bean指定特定的作用域 。 Spring支持如下5种作用域:
  • singleton:单例模式 , 在整个Spring IoC容器中 , 使用singleton定义的Bean将只有一个实例
  • prototype:原型模式 , 每次通过容器的getBean方法获取prototype定义的Bean时 , 都将产生一个新的Bean实例
  • request:对于每次HTTP请求 , 使用request定义的Bean都将产生一个新实例 , 即每次HTTP请求将会产生不同的Bean实例 。 只有在Web应用中使用Spring时 , 该作用域才有效
  • session:对于每次HTTP Session , 使用session定义的Bean豆浆产生一个新实例 。 同样只有在Web应用中使用Spring时 , 该作用域才有效
  • globalsession:每个全局的HTTP Session , 使用session定义的Bean都将产生一个新实例 。 典型情况下 , 仅在使用portlet context的时候有效 。 同样只有在Web应用中使用Spring时 , 该作用域才有效
其中比较常用的是singleton和prototype两种作用域 。 对于singleton作用域的Bean , 每次请求该Bean都将获得相同的实例 。 容器负责跟踪Bean实例的状态 , 负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域 , 程序每次请求该id的Bean , Spring都会新建一个Bean实例 , 然后返回给程序 。 在这种情况下 , Spring容器仅仅使用new 关键字创建Bean实例 , 一旦创建成功 , 容器不在跟踪实例 , 也不会维护Bean实例的状态 。
如果不指定Bean的作用域 , Spring默认使用singleton作用域 。 Java在创建Java实例时 , 需要进行内存申请;销毁实例时 , 需要完成垃圾回收 , 这些工作都会导致系统开销的增加 。 因此 , prototype作用域Bean的创建、销毁代价比较大 。 而singleton作用域的Bean实例一旦创建成功 , 可以重复使用 。 因此 , 除非必要 , 否则尽量避免将Bean被设置成prototype作用域 。
13. spring自动装配 bean 有哪些方式?
Spring容器负责创建应用程序中的bean同时通过ID来协调这些对象之间的关系 。 作为开发人员 , 我们需要告诉Spring要创建哪些bean并且如何将其装配到一起 。
spring中bean装配有两种方式:
  • 隐式的bean发现机制和自动装配
  • 在java代码或者XML中进行显示配置
当然这些方式也可以配合使用 。
14.jsp和 servlet 有什么区别?
  1. jsp经编译后就变成了Servlet.(JSP的本质就是Servlet , JVM只能识别java的类 , 不能识别JSP的代码 , Web容器将JSP的代码编译成JVM能够识别的java类)
  2. jsp更擅长表现于页面显示 , servlet更擅长于逻辑控制 。
  3. Servlet中没有内置对象 , Jsp中的内置对象都是必须通过HttpServletRequest对象 , HttpServletResponse对象以及HttpServlet对象得到 。
  4. Jsp是Servlet的一种简化 , 使用Jsp只需要完成程序员需要输出到客户端的内容 , Jsp中的Java脚本如何镶嵌到一个类中 , 由Jsp容器完成 。 而Servlet则是个完整的Java类 , 这个类的Service方法用于生成对客户端的响应 。
15.简述分代垃圾回收器是怎么工作的?
  1. 分代回收器有两个分区:老生代和新生代 , 新生代默认的空间占比总空间的 1/3 , 老生代的默认占比是 2/3 。
  2. .新生代使用的是复制算法 , 新生代里有 3 个分区:Eden、To Survivor、From Survivor , 它们的默认占比是 8:1:1 , 它的执行流程如下:
  • 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
    清空 Eden 和 From Survivor 分区;
  • From Survivor 和 To Survivor 分区交换 , From Survivor 变 To Survivor , To Survivor 变 From Survivor 。
  • 每次在 From Survivor 到 To Survivor 移动时都存活的对象 , 年龄就 +1 , 当年龄到达 15(默认配置是 15)时 , 升级为老生代 。 大对象也会直接进入老生代 。
3.老生代当空间占用到达某个值之后就会触发全局垃圾收回 , 一般使用标记整理的执行算法 。 以上这些循环往复就构成了整个分代垃圾回收的整体执行流程 。
后面持续更新 。。。。。。。。。。。。。


    推荐阅读