java中级面试题 含答案

一、Java笔试题基础

1. Java中的异常有哪几类?分别怎么使用?

检出异常,非检出异常。检出异常需要try…catch才能编译通过。非检出异常不用try…catch也能编译通过。

RuntimeException是非检出异常,不需要try…catch也能编译通过。

IoException,SQLException等等其他所有异常都是检出异常,必须要try…catach才能编译通过。

2. 常用的集合类有哪些?比如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冲突,我们可适当实现可比较接口。在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

线程安全:ConcurrentHashMap(系统自带的线程安全的HashMap),Map synchronizedMap = Collections.synchronizedMap(new HashMap<>()); synchronizedMap 为线程安全的Map.

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(102410241024);

25. Java里面用对象作为Key需要注意些什么? 如何实现hashcode?

对象放进去了hash值不能变。hashCode的值尽量不等。

二、JAVA笔试题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的变量时,别的使用这个变量的线程都能读取到最新值。

java中级面试题 含答案_第1张图片

但是,这个并不能解决并发问题。比如第一个线程读取到值是3,第二个线程也读取了3,然后第一个线程+1放入了write区,第二个线程+1也放到了write区,那么两个线程的值都是4,期望值是5,这时候还是会造成并发问题。

9. Java内存模型是怎样的?

java中级面试题 含答案_第2张图片

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) 资源分配不当等。

死锁必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

java中级面试题 含答案_第3张图片

A线程锁住的资源被B线程锁住了,然后B线程需要的资源被A线程锁住了,这时候就会造成死锁。

避免这种死锁的方法,当需要锁住多个资源的时候,那就先对资源进行排序,然后再加锁,就会有效的防止死锁。

还有饥饿锁,当优先级高的不断获得资源,优先级低的一直获取不到资源,也会造成死锁。

谦让锁,当几个线程共同获取资源,就会线程先停止,让别的线程先执行。如果每个线程都这样,那就会一起谦让,也会造成死锁。

14. 线程和进程的差别是什么?

线程是进程的实现,进程是线程的体现。进程是独立的,线程运行在进程内。进程内可以有多个线程同时运行着。

线程是在代码层面上,进程是在服务器CPU内存上。

16. ConcurrentHashMap的实现原理是?

对大数组的每个值进行分离加锁,实现了锁分离。

17. sleep和wait区别

sleep是占用着cpu阻塞,wait是不占用cpu阻塞。

18. notify和notifyAll区别

通知处在等待该对象的线程

notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。

notify是通知其中一个线程,而不会通知别的线程。

你可能感兴趣的:(java,面试,架构,spring,经验分享)