一、Java基础
1. 实例方法和静态方法有什么不一样?
2. Java中的异常有哪几类?分别怎么使用?
检出异常,非检出异常。检出异常需要try...catch才能编译通过。非检出异常不用try...catch也能编译通过。
RuntimeException是非检出异常,不需要try...catch也能编译通过。
IoException,SQLException等等其他所有异常都是检出异常,必须要try...catach才能编译通过。
3. 常用的集合类有哪些?比如List如何排序?
分两种,一种实现Set接口,一种是实现List接口的。
Set:TreeSet,HashSet.
List:ArrayList,LinkedList,Vector(线程安全)。
JDK7以前用collections.sort(list,Comparator).
JDK8直接用List.sort(Comparator).
4. ArrayList和LinkedList内部的实现大致是怎样的?他们之间的区别和各自适应的场景是什么?
ArrayList,是数组结构:少用与中间的增删。多用于查询,修改。每次增删元素顺序都会操作每个元素。
LinkedList,是链表结构:多用于中间,开头增删。少用查询,修改。查询时会遍历大量元素。
5. 内存溢出是怎么回事?
对象有被指向的引用,但是再也用不到它就是内存溢出了。
GC机制:复制回收,标记清除,引用计数(如果有循环引用后,会影响垃圾回收,所以JVM虚拟机没有采用此方法进行垃圾回收)。
6. ClassLoader有什么用?
类加载器:所有类都需要Classloader来加载。
BoostrapClassLoader,加载系统(java包下)的类,SystemClassLoader,加载系统扩展类(少用),AppClassloader应用类加载器,还有针对每个项目的类加载器。
7. ==和equals的区别?
==判断对象物理地址。
equals判断对象Value是否相等。
8. hashCode方法的作用?
在hashMap中使用,把一个对象变成一个整型。hashCode规范,如果两个对象的equals返回true,那他们的hashCode必须相等,但是hashCode相等,不一定equals不一定相等。
9. Object类中有哪些方法?列举3个以上。
构造方法,toString(),equals,hashCode,getClass,finalize,clone,三个wait(),notify,notifyAll.
10. NIO是什么?适用于何种场景?
NIO是newIO,接口都是异步的,非阻塞的。
12. HashMap数据结构、扩展策略,Hash冲突攻击如何防范,如何实现线程安全的HashMap?
JDK7以前:数组里面存linkedList,hash冲突,升级到JDK8。
JDK8,数组里面加集合,如果对象hashCode相同,不可比较时就是linkedList,可比较就会用TreeSet进行排序处理(红黑树先访问小的)。hash冲突不用防范。如果对象不可比较且hash冲突,我们可适当实现可比较接口。
线程安全:ConcurrentHashMap(系统自带的线程安全的HashMap),Map synchronizedMap = Collections.synchronizedMap(new HashMap<>()); synchronizedMap 为线程安全的Map.
13. JVM内存结构,GC算法,CMS、G1的原理
14.NIO模型,select/epoll的区别,多路复用的原理
16. Java中一个字符占多少个字节,扩展再问int, long, double占多少字节
一个字符两个字节,int 4 , long double 8
17. 创建一个类的实例都有哪些办法?
new ,反射。
18. final/finally/finalize的区别?
final是类,变量,方法的修饰。类被修饰后不能再被继承。变量和方法被修饰不能再被修改
finally是try...catch后执行的finally,
finalize,在Object中的方法名,在此对象被回收前会执行这个方法。(当使用文件流时,如果对象被回收,没有关闭流,在底层就会实现内存泄露)
19. LinkingBlockingQueue与ArrayBlockingQueue的区别,他们的适用场景?
LinkingBlockQueue 链表实现的阻塞队列,适合一个一个放,一个一个取。
ArrayBlocakingQueue数组实现的阻塞队列,适合三个放,多个放,只适合多个取,不适合单个取。
20. Session/Cookie的区别?
Session存在服务器端。
Cookie存在客户端(浏览器上)。
21. String/StringBuffer/StringBuilder的区别,扩展再问他们的实现?
String 值不可变
StringBuffer 值可变,线程安全
StringBuilder 值可变,线程不安全
22. Servlet的生命周期?
初始化,服务处理(接收请求,处理请求,返回结果),销毁。
23. 如何用Java分配一段连续的1G的内存空间?需要注意些什么?
ByteBuffer.allocateDirect(1024*1024*1024);
24. Java有自己的内存回收机制,但为什么还存在内存泄露的问题呢?
25. Java里面用对象作为Key需要注意些什么? 如何实现hashcode?
对象放进去了hash值不能变。hashCode的值尽量不等。
二、JVM
1. JVM堆的基本结构。
2. JVM的垃圾算法有哪几种?CMS收集算法的流程?
3. JVM有哪些常用启动参数可以调整?
4. 如何查看JVM的内存使用情况?
5. Java程序是否会内存溢出?
6.你常用的JVM配置和调优参数都有哪些?分别什么作用?
7. Java内存分代模型,GC算法,JVM常见的启动参数;
8. CMS算法的过程,CMS回收过程中JVM是否需要暂停(这块回答较好,也可以只是看毕玄的Java分布式开发或网上文章的学习, 可以结合JVM启动参数常见配置,jstat等命令,看下动手能力,意愿;以及实际线上问题排查)
9. 什么情况下会出现OOM(堆内存,永久区,堆外区,方法栈)
10. Java内存结构(堆结构,新生代[S0/S1/Elden],年老代,持久代)
11. 常用的GC策略,什么时候会触发YGC,什么时候触发FGC
三、数据结构与算法基础
1. 说一下几种常见的排序算法和分别的复杂度。
2. 什么是跳表?
3. 如何确认一个链表有环?进一步,确认环的位置。
4. 如何遍历一棵二叉树?
5. 倒排一个LinkedList。
6. HashSet的实现方式
四、多线程/并发
1. Java中常见的锁
互斥锁,读写锁,信号量
互斥锁,读写只能一个线程
读写锁,写只能一个线程,读可以多个线程
信号量,如停车场,能允许一定量的线程,满了则不能再进入,需要等别的线程释放资源。
2. 原子Atomic类,如何保证原子性,CAS硬件指令
在atomic类底层使用CAS硬件指令,来保证atomic的原子性。CAS在硬件级别实现了原子操作。
3. volatile,可见性问题的原因,硬件架构,L3 Cache,QPI,乐观锁
volatile:易变的。被修饰的变量在多线程中被改变时,别的线程能知道。
4. 如何实现一个线程安全的数据结构
new 一个volatile 的Atomatic变量,或者使用concurrent类型的集合,ConcurrentHashMap之类的。
5. 如何避免死锁
如果有两个锁的时候,如果先锁住第一个参数,再锁住第二个参数,这种情况就会产生死锁。
比如,第一个参数是A,第二个参数是B,如果第一个参数先锁,第二个参数后锁。在刚好锁住第一个参数,第二次请求来了,刚好两个参数颠倒了就会锁住第二个参数,那就会造成死锁。
解决死锁:在需要锁住多个参数的时候,先把参数按固定的顺序排序,然后在对排序后的参数加锁,这样就有效的避免死锁。
6. 如何解决ABA问题
ABA问题:如果另一个线程修改V值假设原来是A,先修改成B,再修改回成A。当前线程的CAS操作无法分辨当前V值是否发生过变化。
用另一个标识判断某值是否有改变过。
7. Synchronized关键字的作用?
对Synchronized()括号内的对象加互斥锁,不影响父类或者子类的访问。
8. Volatile关键字的作用?
可见的,当其中一个线程改变了volatile的变量时,别的使用这个变量的线程都能读取到最新值。
但是,这个并不能解决并发问题。比如第一个线程读取到值是3,第二个线程也读取了3,然后第一个线程+1放入了write区,第二个线程+1也放到了write区,那么两个线程的值都是4,期望值是5,这时候还是会造成并发问题。
9. Java内存模型是怎样的?
1> 方法区:
a. 方法区是各线程共享内存的区域。
b. 它存放类的信息、static变量、常量(常量池包含于方法区)、即时编译器编译后的代码数据。
c. 它属于非堆部分。
2>堆(先进先出):
a. 堆是内存最大的一块区域,堆是各线程共享内存的区域。
b. 堆中存放被创建的实例对象、数组。
c. 堆是GC管理的主要区域。
3>栈(先进后出):
a. 栈是线程私有的,它的生命周期与线程相同。线程生命周期(创建,就绪,运行,阻塞,死亡)
b. 栈是java方法执行的内存模型:
每个方法执行时会在栈中创建一个栈帧(stack frame),用于存放 局部变量表、操作栈、动态链接、方法出口等信息。方法从执行开始就完成了 压栈 到 弹栈 的过程。
局部变量表中存放了基本数据类型(int,short,long,char,byte,float,double,boolean,其中long、double 两个64位长度的类型会占用两个局部变量空间、其他的只占一个)、对象引用(并非本身,引用指向堆中的对象地址)、方法返回类型。
局部变量表所需控件在编译时就已经确定了,因此方法运行期间不会改变其内存大小。
4>本地方法栈:
a. 与java虚拟机栈功能类似,区别在于服务对象不同,该栈服务于jvm使用的native方法。
5>程序计数器:
a. 每条线程执行时都有自己的程序计数器,互不影响。
b. 程序计数器指向该计数器的拥有者(线程)下一步执行的位置。
10. HashMap在多线程环境下使用需要注意什么?为什么?
在多线程环境下,需要使用ConcurrentHashMap,因为HashMap是线程不安全的,如果多线程操作,会造成不可预期的结果。
11. Java程序中启动一个线程是用run()还是start()?
start()是重新开启一个线程运行。 如果是run(),那就相当于在当前线程运行,并不会新创建一个线程运行。
12. 什么是守护线程?有什么用?
守护线程是运行在后端的线程,当系统停止运行,守护线程也就停止了。
进行内存回收,垃圾清理等工作
13. 什么是死锁?如何避免
原因:
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
作者:LEMON_1521
链接:https://www.jianshu.com/p/870825c39925
共同学习,写下你的评论
评论加载中...
作者其他优质文章