《互联网大厂Java求职者面试大揭秘:核心知识深度考察》

36 阅读5分钟

面试官:请简要介绍一下Java核心知识中的面向对象编程概念,比如封装、继承和多态。

王铁牛:封装就是把数据和操作数据的方法封装在一起,对外提供统一的接口。继承是子类继承父类的属性和方法。多态就是同一个行为具有多个不同表现形式或形态的能力。

面试官:嗯,回答得不错。那说说在多线程编程中,如何确保线程安全?

王铁牛:可以使用synchronized关键字,还有Lock接口。

面试官:很好。再问一个,JVM的内存区域有哪些?

王铁牛:有程序计数器、虚拟机栈、本地方法栈、堆和方法区。

第一轮结束。

面试官:接下来谈谈JUC包中的CountDownLatch的作用和使用场景。

王铁牛:它可以让一个线程等待其他线程完成一系列操作后再执行。比如多个线程并发计算,计算完了用CountDownLatch通知主线程进行汇总。

面试官:那线程池的核心参数有哪些?

王铁牛:有corePoolSize、maximumPoolSize、keepAliveTime、unit和workQueue。

面试官:HashMap在多线程环境下会出现什么问题?

王铁牛:会出现链表成环,导致死循环。

第二轮结束。

面试官:讲讲Spring框架中的依赖注入方式。

王铁牛:有构造器注入、setter方法注入等。

面试官:Spring Boot的自动配置原理是什么?

王铁牛:好像是通过条件注解来实现自动配置的,具体不太清楚。

面试官:MyBatis的#{}和${}的区别是什么?

王铁牛:#{}是预编译处理,${}是字符串替换,#{}能防止SQL注入。

第三轮结束。

面试结束,面试官表示会让王铁牛回家等通知。

答案:

  • 面向对象编程概念
    • 封装:将数据和操作数据的方法封装在一起,对外提供统一接口,提高数据安全性和代码可维护性。例如,一个类中的属性可以通过private修饰,然后提供public的getter和setter方法来访问和修改。
    • 继承:子类继承父类的属性和方法,实现代码复用。比如一个父类定义了一些通用的方法,子类可以继承这些方法并根据自身需求进行扩展。
    • 多态:同一个行为具有多个不同表现形式或形态的能力。可以通过方法重写和接口实现来体现。比如一个父类引用可以指向子类对象,调用子类重写后的方法。
  • 多线程编程确保线程安全
    • synchronized关键字:可以修饰方法或代码块,保证同一时刻只能有一个线程访问被修饰的部分。例如,在一个共享资源的方法上加上synchronized,防止多个线程同时修改该资源。
    • Lock接口:提供了比synchronized更灵活的锁控制。比如ReentrantLock,可以实现公平锁、可中断锁等。
  • JVM的内存区域
    • 程序计数器:记录当前线程执行的字节码指令地址。
    • 虚拟机栈:每个线程都有自己的虚拟机栈,用于存储局部变量、操作数栈等。
    • 本地方法栈:与虚拟机栈类似,用于执行本地方法。
    • :存储对象实例,是垃圾回收的主要区域。
    • 方法区:存储类信息、常量、静态变量等。
  • JUC包中CountDownLatch的作用和使用场景
    • 作用:让一个线程等待其他线程完成一系列操作后再执行。
    • 使用场景:比如多个线程并发处理任务,处理完后通过CountDownLatch通知主线程进行汇总操作。例如,多个线程分别读取文件内容,读取完后用CountDownLatch通知主线程进行文件内容整合。
  • 线程池的核心参数
    • corePoolSize:线程池的核心线程数,当提交的任务数小于corePoolSize时,线程池会创建新线程来执行任务。
    • maximumPoolSize:线程池允许的最大线程数,当提交的任务数大于corePoolSize且workQueue已满时,会创建新线程直到线程数达到maximumPoolSize。
    • keepAliveTime:线程池中非核心线程的存活时间,当线程空闲时间超过keepAliveTime时,非核心线程会被销毁。
    • unit:keepAliveTime的时间单位。
    • workQueue:用于存储提交的任务,当线程数达到corePoolSize时,新提交的任务会放入workQueue中。
  • HashMap在多线程环境下的问题
    • 在多线程环境下,HashMap可能会出现链表成环的问题,导致死循环。这是因为在扩容时,可能会导致链表节点的顺序发生变化,从而形成环形链表。
  • Spring框架中的依赖注入方式
    • 构造器注入:通过构造函数传入依赖对象,优点是注入的依赖在对象创建时就已经确定,缺点是当依赖较多时,构造函数参数列表会很长。
    • setter方法注入:通过setter方法设置依赖对象,优点是更加灵活,可以在对象创建后再设置依赖,缺点是可能会存在对象未完全初始化就被使用的情况。
  • Spring Boot的自动配置原理
    • Spring Boot通过条件注解来实现自动配置。它会根据项目的依赖和配置,自动配置相关的Bean。例如,当项目中引入了数据库相关的依赖时,Spring Boot会自动配置数据源、事务管理器等Bean。它会扫描项目中的类路径,根据类上的注解和条件判断来决定是否创建某个Bean。
  • MyBatis的#{}和${}的区别
    • #{}:是预编译处理,会将参数作为占位符,防止SQL注入。例如,在SQL语句中使用#{}时,MyBatis会将参数值进行预编译处理,而不是直接拼接在SQL中。
    • ${}:是字符串替换,会直接将参数值拼接到SQL中,存在SQL注入风险。比如在动态SQL中需要拼接表名等情况时可能会用到,但使用时要特别小心参数的来源。