面试官:第一轮提问开始,首先问你,简述一下Java中的多线程。
王铁牛:多线程就是一个程序里能同时运行多个线程呗。
面试官:还算回答得简洁明了。那说说线程池有哪些参数及其作用?
王铁牛:嗯……有corePoolSize、maximumPoolSize、keepAliveTime这些吧,corePoolSize好像是核心线程数,maximumPoolSize是最大线程数,keepAliveTime是线程存活时间。
面试官:回答得还可以。最后一个问题,HashMap在多线程环境下有什么问题?
王铁牛:这个……不太清楚。
面试官:好,第一轮提问结束。
面试官:第二轮提问,说说JVM的内存结构。
王铁牛:有堆、栈、方法区这些。
面试官:那类加载机制分哪几个阶段?
王铁牛:嗯……有加载、验证、准备、解析、初始化。
面试官:还不错。再问,简述一下Spring的IOC和AOP。
王铁牛:IOC就是控制反转,AOP就是面向切面编程,大概就这样。
面试官:第二轮提问完毕。
面试官:第三轮提问,Dubbo的集群容错模式有哪些?
王铁牛:啊……不太记得了。
面试官:RabbitMq的消息确认机制了解吗?
王铁牛:不太清楚。
面试官:xxl-job的调度中心是如何实现任务调度的?
王铁牛:这个真不知道。
面试官:好,面试结束。回家等通知吧。
答案:
- Java中的多线程:多线程是指在一个程序中可以同时运行多个线程。每个线程都有自己独立的执行路径,它们可以并发执行,提高程序的执行效率。在Java中,可以通过继承Thread类或实现Runnable接口来创建线程。
- 线程池的参数及其作用:
- corePoolSize:核心线程数,当提交的任务数小于corePoolSize时,线程池会创建新的线程来执行任务。
- maximumPoolSize:最大线程数,当提交的任务数大于corePoolSize且任务队列已满时,线程池会创建新的线程来执行任务,直到线程数达到maximumPoolSize。
- keepAliveTime:线程存活时间,当线程池中的线程数大于corePoolSize时,多余的线程在空闲时间超过keepAliveTime后会被销毁。
- unit:keepAliveTime的时间单位。
- workQueue:任务队列,用于存储提交的任务。
- threadFactory:线程工厂,用于创建线程。
- handler:拒绝策略,当线程池中的线程数达到maximumPoolSize且任务队列已满时,会调用handler来处理新提交的任务。
- HashMap在多线程环境下的问题:HashMap在多线程环境下可能会出现死循环和数据丢失的问题。这是因为HashMap的扩容机制是非线程安全的,在多线程环境下可能会导致链表形成环形结构,从而导致死循环。同时,在扩容过程中可能会覆盖其他线程插入的数据,导致数据丢失。
- JVM的内存结构:JVM的内存结构主要包括堆、栈、方法区、程序计数器、本地方法栈。
- 堆:是JVM中最大的一块内存区域,用于存储对象实例。
- 栈:用于存储局部变量和方法调用的上下文。
- 方法区:用于存储类信息、常量、静态变量等。
- 程序计数器:用于记录当前线程执行的字节码指令的地址。
- 本地方法栈:用于执行本地方法。
- 类加载机制的阶段:
- 加载:将类的字节码文件加载到内存中。
- 验证:对加载的字节码进行验证,确保其合法性。
- 准备:为类的静态变量分配内存,并设置初始值。
- 解析:将符号引用转换为直接引用。
- 初始化:执行类的静态代码块和静态变量的赋值操作。
- Spring的IOC和AOP:
- IOC(控制反转):将对象的创建和依赖注入的控制权从程序代码转移到Spring容器中。通过IOC,对象之间的依赖关系由Spring容器来管理,而不是在代码中直接创建和依赖。
- AOP(面向切面编程):通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP可以将一些横切关注点(如日志、事务管理等)从业务逻辑中分离出来,使得业务逻辑更加清晰和简洁。
- Dubbo的集群容错模式:
- Failover Cluster:失败自动切换,当出现失败,重试其它服务器。
- Failfast Cluster:快速失败,只发起一次调用,失败立即报错。
- Failsafe Cluster:失败安全,出现异常时,直接忽略。
- Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。
- Forking Cluster:并行调用多个服务器,只要一个成功即返回。
- RabbitMq的消息确认机制:
- 生产者确认机制:生产者将消息发送到RabbitMQ后,可以选择等待Broker的确认消息,以确保消息成功发送。如果生产者没有收到确认消息,可以选择重新发送消息。
- 消费者确认机制:消费者在接收到消息后,可以选择手动确认消息,以告知Broker该消息已被成功消费。如果消费者没有手动确认消息,Broker会认为该消息没有被消费,可能会重新发送给其他消费者。
- xxl-job的调度中心实现任务调度的原理:
- 调度中心启动:调度中心启动后,会加载所有的调度任务配置信息。
- 任务触发:根据任务配置的触发时间,调度中心会定时触发任务。
- 任务执行:调度中心通过HTTP请求将任务信息发送给执行器,执行器接收到任务信息后,会执行相应的任务逻辑。
- 任务结果反馈:执行器执行完任务后,会将任务结果反馈给调度中心,调度中心会记录任务执行结果。
- 任务重试:如果任务执行失败,调度中心会根据任务配置的重试策略进行重试。