互联网大厂Java面试:核心知识大考验
面试官:请简要介绍一下Java核心知识中面向对象的三大特性。
王铁牛:嗯,面向对象的三大特性是封装、继承和多态。封装就是把数据和操作数据的方法封装在一起;继承是子类继承父类的属性和方法;多态就是同一个行为具有多个不同表现形式。
面试官:回答得不错。那说说JUC里的CountDownLatch是怎么用的?
王铁牛:CountDownLatch就是一个同步辅助类,它允许一个或多个线程等待其他线程完成操作之后再执行。比如说多个线程都要完成一个任务后,主线程才能继续执行,就可以用这个。
面试官:很好。再问一个,JVM的内存结构主要有哪些部分?
王铁牛:JVM内存结构主要有堆、栈、方法区、程序计数器、本地方法栈。
第一轮结束。
面试官:多线程中如何保证线程安全?
王铁牛:可以用synchronized关键字、Lock接口、ThreadLocal等。
面试官:线程池的核心参数有哪些,分别有什么作用?
王铁牛:核心参数有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。corePoolSize是核心线程数,maximumPoolSize是最大线程数,keepAliveTime是线程池线程空闲后的存活时间,unit是时间单位,workQueue是任务队列,threadFactory是线程工厂,handler是拒绝策略。
面试官:HashMap在多线程环境下会出现什么问题?
王铁牛:会出现死循环、数据丢失等问题。
第二轮结束。
面试官:Spring框架的核心是什么?
王铁牛:Spring框架的核心是IoC和AOP。
面试官:Spring Boot的自动配置原理是什么?
王铁牛:Spring Boot自动配置是通过@EnableAutoConfiguration注解来实现的,它会根据类路径下的依赖来自动配置一些bean。
面试官:MyBatis的动态SQL有哪些?
王铁牛:有if、where、set、foreach等。
第三轮结束。
面试官:好了,今天的面试就到这里,回去等通知吧。
答案:
- 面向对象三大特性:
- 封装:将数据和操作数据的方法封装在一起,对外提供统一的接口,隐藏内部实现细节,提高代码的安全性和可维护性。例如在一个类中,将一些属性设置为私有,通过公有的getter和setter方法来访问和修改这些属性。
- 继承:子类继承父类的属性和方法,实现代码复用。子类可以拥有父类的非私有成员变量和方法,并且可以根据需要进行扩展和重写。比如一个Animal类有move方法,Dog类继承Animal类,就可以直接使用move方法,也可以重写它来实现不同的移动方式。
- 多态:同一个行为具有多个不同表现形式。可以通过父类引用指向子类对象,在运行时根据实际对象的类型来决定调用哪个类的方法。例如定义一个Animal类型的变量,它可以指向Dog对象或者Cat对象,调用move方法时会执行不同的具体实现。
- JUC里的CountDownLatch用法:
- 例如有一个任务需要多个子任务完成后才能执行。可以创建一个CountDownLatch对象,指定计数器的初始值为子任务的数量。每个子任务完成后调用CountDownLatch的countDown方法,将计数器减1。主线程在需要等待所有子任务完成的地方调用CountDownLatch的await方法,当计数器变为0时,await方法返回,主线程继续执行。
- JVM内存结构:
- 堆:是JVM中最大的一块内存区域,用于存储对象实例,几乎所有的对象实例都在这里分配内存。
- 栈:每个线程都有自己独立的栈,用于存储局部变量、方法调用等信息。
- 方法区:用于存储类信息、常量、静态变量等。
- 程序计数器:记录当前线程执行的字节码指令地址。
- 本地方法栈:用于执行本地方法。
- 多线程保证线程安全的方法:
- synchronized关键字:可以修饰方法或代码块,保证同一时刻只有一个线程能访问被修饰的部分。
- Lock接口:提供了比synchronized更灵活的锁控制,如可中断锁、定时锁等。
- ThreadLocal:为每个使用该变量的线程都提供一个独立的变量副本,每个线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本。
- 线程池核心参数及作用:
- corePoolSize:核心线程数,当提交的任务数小于corePoolSize时,线程池会创建新的线程来执行任务。
- maximumPoolSize:最大线程数,当提交的任务数大于corePoolSize且任务队列已满时,会创建新的线程直到线程数达到maximumPoolSize。
- keepAliveTime:线程池线程空闲后的存活时间。
- unit:keepAliveTime的时间单位。
- workQueue:任务队列,用于存放提交的任务,当线程数达到corePoolSize时,新提交的任务会放入任务队列。
- threadFactory:线程工厂,用于创建线程,可自定义线程的名称、优先级等。
- handler:拒绝策略,当线程数达到maximumPoolSize且任务队列已满时,会调用handler来处理新提交的任务。
- HashMap在多线程环境下的问题:
- 死循环:在扩容时可能会导致链表形成环形结构,从而在后续查询时陷入死循环。
- 数据丢失:在多线程同时进行put操作时,可能会导致数据覆盖或丢失。
- Spring框架的核心:
- IoC(控制反转):将对象的创建和依赖注入的控制权从应用程序代码转移到Spring容器中。通过IoC,对象之间的依赖关系由容器来管理,降低了对象之间的耦合度。
- AOP(面向切面编程):允许开发者将一些横切关注点(如日志记录、事务管理等)与业务逻辑分离,通过切面的方式织入到业务逻辑中,提高代码的可维护性和复用性。
- Spring Boot自动配置原理:
- 通过@EnableAutoConfiguration注解来实现。Spring Boot会根据类路径下的依赖自动配置一些bean。它会扫描classpath下的所有jar包和类,根据这些依赖信息来推断需要配置哪些bean。例如,如果classpath下有MyBatis相关的依赖,Spring Boot会自动配置MyBatis的相关bean,包括数据源、SqlSessionFactory等。
- MyBatis的动态SQL:
- if:根据条件判断动态地拼接SQL语句。例如根据某个条件决定是否添加某个查询条件。
- where:智能地处理SQL语句中的WHERE子句,避免WHERE关键字后面多余的AND或OR。
- set:用于动态更新语句,自动处理SET关键字后面的逗号。
- foreach:用于循环遍历集合,动态地生成SQL语句中的IN子句等。