# 面试问题
1. 什么是拆箱,什么是装箱?
```
简单一点说,装箱就是 自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的xxxValue方法实现的。(xxx代表对应的基本数据类型)。
```
2. AOP的相关注解?
```
AOP意为面向切面编程,是通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。为的是使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
@Aspect
切面声明,标注在类、接口(包括注解类型)或枚举上。
@Pointcut
切入点声明,即切入到哪些目标类的目标方法。既可以用 execution 切点表达式, 也可以是 annotation 指定拦截拥有指定注解的方法.(value 属性指定切入点表达式,默认为 "",用于被通知注解引用,这样通知注解只需要关联此切入点声明即可,无需再重复写切入点表达式)
@Before
前置通知, 在目标方法(切入点)执行之前执行。(value 属性绑定通知的切入点表达式,可以关联切入点声明,也可以直接设置切入点表达式。注意:如果在此回调方法中抛出异常,则目标方法不会再执行,会继续执行后置通知 -> 异常通知。)
@After
后置通知, 在目标方法(切入点)执行之后执行
@AfterReturning
返回通知, 在目标方法(切入点)返回结果之后执行.(pointcut 属性绑定通知的切入点表达式,优先级高于 value,默认为 "")
@AfterThrowing
异常通知, 在方法抛出异常之后执行, 意味着跳过返回通知(pointcut 属性绑定通知的切入点表达式,优先级高于 value,默认为 ""。注意:如果目标方法自己 try-catch 了异常,而没有继续往外抛,则不会进入此回调函数)
@Around
环绕通知:目标方法执行前后分别执行一些代码,类似拦截器,可以控制目标方法是否继续执行。通常用于统计方法耗时,参数校验等等操作。
```
3. 执行SQL语句时是先进行排序还是先分组?
```
先分组(group by)后排序(order by)
```
4. String常用的方法?
```
length() 字符串的长度
charAt() 截取一个字符
toCharArray() String转换成char数组
equals()和equalsIgnoreCase() 比较两个字符串
replace() 替换
valueOf() 转换为字符串
toLowerCase() 转换为小写
toUpperCase()转换为大写
```
5. Collection和Collections的区别?
```
java.util.Collection 是一个 集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
java.util.Collections 是一个包装类。它包含有各种有关集合操作的 静态多态方法。此类 不能实例化,就像一 个工具类,服务于Java的Collection框架。
Collections.sort():对集合进行排序;
Collections.reverse():反转集合中元素的顺序;
Collections.copy(m,n):将集合n中的元素全部复制到m中,并且覆盖相应索引的元素;
Collections.min():采用Collection内含自然比较法求最小值;
Collections.max():采用Collection内含自然比较法求最大值;
```
6. 为什么重写 equals 时为什么一定要重写 hashCode?
```
因为重写了equals方法能证明两个对象相等,但没有重写hashCode方法意味着用的是object类的方法,就有可能两个都对象的hashCode不相同,就矛盾了,所以重写equals方法就一定要重写hashCode,然后在比较的时候先调用hashCode方法判断hashCode值是否相同,不同就证明两个对象不相等,相等就再调用equals方法进而判断两个对象相不相同。
```
7. array和arrayList的区别?
```
(1)ArrayList是Array的复杂版本:arrayList相当于array的一个增强版,因为arraylist的许多方法,如Index、IndexOf、Contains、Sort等都是在内部数组的基础上直接调用Array的对应方法。
(2)存储的数据类型:ArrayList可以存储异构对象,而Array只能存储相同数据类型的数据。
(3)长度的可变:定义一个 Array 时,必须指定数组的数据类型及数组长度,其长度定义后就不可变了。而ArrayList 是动态数组,长度动态可变,会自动扩容。
```
8. 你可以接受加班吗?
```
第一个方面:你可以这样去跟面试官说:如果是因为我个人工作效率低的原因,从而导致我需要加班,我可以接受。同时我也会去反思自己的工作方式,从而去提高自己的工作效率,减少加班的情况。
第二个方面:你可以这样去跟面试官说:如果不是因为我个人的原因,并且我个人手头上的工作已经超量完成,我可能接受不了无偿加班。我相信贵公司也是需要有能力的人,这样公司才能更好的进步,所以我觉得不必要的加班还是应该避免的。
```
9. 请解释一下什么是高并发,以及在Java中如何处理高并发问题?
```
高并发是指系统在同一时间内处理大量请求的能力。在Java中,我们可以使用线程池、锁、队列等方式来处理高并发问题。其中,线程池可以控制线程的数量,避免线程过多导致系统崩溃;锁可以保证同一时间只有一个线程访问共享资源,避免数据不一致;队列可以缓存请求,避免系统瞬间被大量请求压垮。
```
10. 请解释一下什么是压测,以及在Java中如何进行压测?
```
压测是指模拟大量用户同时访问系统,测试系统的性能和稳定性。在Java中,我们可以使用JMeter等工具进行压测。JMeter可以模拟大量用户同时访问系统,并记录系统的响应时间、吞吐量等指标,帮助我们评估系统的性能和稳定性。
```
11. sql(查询表中前十行)?
```
select * from table_name limit 0,10
```
12. 如何优化mysql的limit问题?
```
利用覆盖索引来加速分页查询
```
13. 如何创建多线程?
```
1、继承Thread类,重写run()方法,使用start()启动;
2、实现Runnable接口,重写run()方法,使用start()启动;
3、实现Callable接口,重写call()方法,使用start()启动。
```
14. 线程池的核心参数?
```
corePoolSize:核心线程数,是指线程池中长期存活的线程数。
maximumPoolSize:最大线程数,线程池允许创建的最大线程数量,当线程池的任务队列满了之后,可以创建的最大线程数。
keepAliveTime:空闲线程存活时间,当线程池中没有任务时,会销毁一些线程,销毁的线程数=maximumPoolSize(最大线程数)-corePoolSize(核心线程数)。
TimeUnit:时间单位,空闲线程存活时间的描述单位。
BlockingQueue:线程池任务队列,线程池存放任务的队列,用来存储线程池的所有待执行任务。
ThreadFactory:创建线程的工厂,线程池创建线程时调用的工厂方法,通过此方法可以设置线程的优先级、线程命名规则以及线程类型(用户线程还是守护线程)等。
RejectedExecutionHandler:拒绝策略,当线程池的任务超出线程池队列可以存储的最大值之后,执行的策略。
```
15. MySQL 可重复读隔离级别,如何解决幻读问题?
```
针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题;
针对当前读(select ... for update 等语句),是通过 next-key lock(行�