面试官:请简要介绍一下Java核心知识在实际项目中的重要性以及你对它的理解。
王铁牛:Java核心知识可太重要啦,就像盖房子的地基一样。它包括面向对象、数据类型、控制结构这些,能帮我们构建出稳定可靠的程序。
面试官:那说说HashMap的底层原理以及扩容机制。
王铁牛:HashMap底层是数组加链表再加红黑树。扩容机制就是当元素个数超过负载因子和容量的乘积时就会扩容,扩容后重新计算元素位置。
面试官:很不错,回答得挺清晰。接下来问你几个多线程的问题。如何创建一个线程,有几种方式?
王铁牛:可以通过继承Thread类,重写run方法来创建;也可以实现Runnable接口,重写run方法;还有实现Callable接口,通过FutureTask来包装。
第一轮结束。
面试官:再深入讲讲线程池的工作原理以及ThreadPoolExecutor构造函数的参数含义。
王铁牛:线程池就是预先创建一些线程,任务来了就从线程池里拿线程执行。ThreadPoolExecutor构造函数参数有corePoolSize核心线程数、maximumPoolSize最大线程数、keepAliveTime线程存活时间、unit时间单位、workQueue任务队列、threadFactory线程工厂、handler拒绝策略。
面试官:Spring框架中依赖注入有几种方式?
王铁牛:有构造器注入、setter方法注入、基于注解的注入。
面试官:那说说Spring Boot的自动配置原理。
王铁牛:Spring Boot通过条件注解来实现自动配置,根据类路径下的依赖等条件来决定是否配置某个组件。
第二轮结束。
面试官:MyBatis的#{}和${}的区别是什么?
王铁牛:#{}会将参数当成一个占位符,通过PreparedStatement来防止SQL注入;${}会直接将参数值拼接到SQL中,可能会有SQL注入风险。
面试官:Dubbo的集群容错有哪些策略?
王铁牛:有Failover Cluster(失败自动切换)、Failfast Cluster(快速失败)、Failsafe Cluster(失败安全)、Failback Cluster(失败自动恢复)、Forking Cluster(并行调用多个服务)等。
面试官:RabbitMq的消息确认机制了解吗?
王铁牛:不太清楚,乱说一通(此处回答不清晰)。
第三轮结束。
面试官:今天的面试就到这里,回去等通知吧。
答案:
- Java核心知识:Java核心知识是构建程序的基础,涵盖面向对象、数据类型、控制结构等。面向对象具有封装、继承、多态特性,能提高代码的可维护性和扩展性。数据类型分为基本数据类型和引用数据类型,合理使用有助于内存管理。控制结构包括条件判断、循环等,用于实现程序的逻辑流程。
- HashMap底层原理及扩容机制:底层是数组加链表再加红黑树。初始时创建一个指定大小的数组,当元素个数超过负载因子(默认0.75)和容量的乘积时,就会进行扩容。扩容是创建一个新的更大的数组,将原数组中的元素重新计算位置后放入新数组。链表在元素个数超过8且数组长度大于64时会转换为红黑树,以提高查找效率。
- 创建线程的方式:
- 继承Thread类,重写run方法。这种方式简单直接,但一个类继承了Thread类就不能再继承其他类了。
- 实现Runnable接口,重写run方法。实现该接口的类还可以继承其他类,更灵活。
- 实现Callable接口,通过FutureTask来包装。这种方式有返回值,并且可以捕获异常。
- 线程池工作原理及ThreadPoolExecutor构造函数参数含义:线程池预先创建一些线程,任务到来时从线程池获取线程执行。corePoolSize核心线程数,当提交的任务数小于corePoolSize时,会创建新线程执行任务;maximumPoolSize最大线程数,当任务数超过corePoolSize且任务队列已满时,会创建新线程直到线程数达到maximumPoolSize;keepAliveTime线程存活时间,当线程数超过corePoolSize,空闲线程在keepAliveTime后会被销毁;unit时间单位;workQueue任务队列,用于存放提交的任务;threadFactory线程工厂,用于创建线程;handler拒绝策略,当线程数达到maximumPoolSize且任务队列已满时,如何处理新提交的任务。
- Spring框架依赖注入方式:
- 构造器注入:通过构造函数传入依赖对象,优点是注入的依赖在对象创建时就已确定,不会出现NPE,但如果依赖较多,构造函数参数列表会很长。
- setter方法注入:通过setter方法设置依赖对象,灵活性高,可以在对象创建后再设置依赖,但可能会出现NPE,需要注意依赖的初始化顺序。
- 基于注解的注入:如@Autowired、@Resource等,使用方便,代码简洁,Spring会自动根据类型或名称进行依赖注入。
- Spring Boot自动配置原理:Spring Boot通过条件注解来实现自动配置。它会扫描类路径下的所有依赖,根据这些依赖以及一些条件注解(如@ConditionalOnClass、@ConditionalOnMissingBean等)来决定是否配置某个组件。当满足特定条件时,会自动配置相应的Bean,极大地简化了开发过程。
- **MyBatis的#{}和{}的区别**:#{}会将参数当成一个占位符,通过PreparedStatement来执行SQL,能有效防止SQL注入。例如:select * from user where id = #{id}。{}会直接将参数值拼接到SQL中,可能会导致SQL注入风险。例如:select * from user where name = ${name}。在使用时要根据实际情况选择合适的方式。
- Dubbo的集群容错策略:
- Failover Cluster(失败自动切换):失败后自动切换到其他可用服务,是默认策略。
- Failfast Cluster(快速失败):调用失败立即报错,适用于幂等操作。
- Failsafe Cluster(失败安全):调用失败不报错,直接忽略,适用于不重要的操作。
- Failback Cluster(失败自动恢复):失败后会在后台自动重试,适用于可重试的操作。
- Forking Cluster(并行调用多个服务):并行调用多个服务,只要有一个成功就返回,适用于需要快速获取结果的场景。