面试题及答案
1、private修饰的方法可以通过反射访问,那么private的意 义是什么.
OOP思想,面向对象的封装,隐藏内部实现
2、Java类初始化顺序
父类静态变量,父类静态代码块,子类静态变量,子类静态代码块,父类普通变量,父类普通代码块,父类构造函数,子类普通变量,子类普通代码块,子类构造函数
3、对方法区和永久代的理解以及它们之间的关系
- 方法区:供各线程共享的运行时内存区域,在虚拟机启动时创建。(JAVA虚拟机规范)
- 永久代:对方法区的实现,HotSpot在1.8之后取消永久代,改为元空间。
4、一个java文件有3个类,编译后有几个class文件
3个,一个类一个class
5、局部变量使用前需要显式地赋值,否则编译通过不了,为什么这么设计
类似于变量初始化,让程序员注意并手动初始化。成员变量,可以不赋值是因为在类初始化的时候,就会对成员变量进行初始化默认值
(其实之所以这样做就是一种对程序员的约束限制。因为程序员(人)是(有些情况下)靠不住的,假使局部变量可以使用默认值,我们总会无意间忘记赋值,进而导致不可预期的情况出现)
6、 ReadWriteLock读写之间互斥吗
读锁使用共享模式;写锁使用独占模式
不支持锁升级,即要先释放读锁,才能重新获取写锁
锁降级,已获取写锁的情况下可以直接获取读锁,不会产生死锁,但是因为没有释放之前的写锁,其他线程仍然获取不到写锁。所以也要显式释放之前的写锁
- 7、 Semaphore拿到执行权的线程之间是否互斥
定义初始为1的许可证就可以实现线程之间互斥
有多个许可证,就不互斥
8.写一个你认为最好的单例模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//双重检查锁
public final class DoubleCheckedSingleton
{
private static volatile DoubleCheckedSingleton singObj = null;
private DoubleCheckedSingleton(){
}
public static DoubleCheckedSingleton getSingleInstance(){
if(null == singObj ) {
Synchronized(DoubleCheckedSingleton.class){
if(null == singObj){
singObj = new DoubleCheckedSingleton();
}
}
}
return singObj;
}
}9、B树和B+树是解决什么样的问题的,怎样演化过来,之间区别
略
- 10、写一个生产者消费者模式
BlockingQueue 单项阻塞队列(具体特性看实现类)
BlockingDeque 双阻塞队列(具体特性看实现类)
- 11、写一个死锁
1 | 各自锁住对方的对象 |
- 12、 cpu 100%怎样定位
https://www.cnblogs.com/lishijia/p/5549980.html
top命令:Linux命令。可以查看实时的CPU使用情况。也可以查看最近一段时间的CPU使用情况。
PS命令:Linux命令。强大的进程状态监控命令。可以查看进程以及进程中线程的当前CPU使用情况。属于当前状态的采样数据。
jstack:Java提供的命令。可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。
pstack:Linux命令。可以查看某个进程的当前线程栈运行情况。
阿里 Arthas工具
- 13、 String a= “ab”; String b=”a” + “‘b”;a==b是否相等,为什么
相等,常量在编译中会进行合并
- 14、int a= 1;是原子性操作吗
是。
变量赋值是原子操作,因为操作不可再分,只有赋值。
i++ 不是原子操作,其中经历取值、加一、赋值三部操作
- 15、可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决
ConcurrentModificationException。
最好用迭代器,有圆形车轮不用,非用方形车轮?
- 16、新的任务提交到线程池,线程池是怎样处理
1、线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则执行第二步。
2、线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里进行等待。如果工作队列满了,则执行第三步
3、线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务
线程池饱和策略
这里提到了线程池的饱和策略,那我们就简单介绍下有哪些饱和策略:
AbortPolicy
为Java线程池默认的阻塞策略,不执行此任务,而且直接抛出一个运行时异常,切记ThreadPoolExecutor.execute需要try catch,否则程序会直接退出。
DiscardPolicy
直接抛弃,任务不执行,空方法
DiscardOldestPolicy
从队列里面抛弃head的一个任务,并再次execute 此task。
CallerRunsPolicy
在调用execute的线程里面执行此command,会阻塞入口
用户自定义拒绝策略(最常用)
实现RejectedExecutionHandler,并自己定义策略模式
参考:https://blog.csdn.net/u010963948/article/details/80573898
- 17、 AQS和CAS原理
- 18、 synchronized底层实现原理
- 19、 volatile作用,指令重排相关
20、 AOP和I0C原理
21、 Spring怎样解决循环依赖的问题
22、 dispatchServlet怎样分发任务的
20、 mysq|给离散度低的字段建立索引会出现什么问题,具体说下原因