Java初中级面试题宝典,让您拿高薪更进一步
分类:Java面试题 热度:

一、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<Object, Object> 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1. 方法区:
a. 方法区是各线程共享内存的区域。
b. 它存放类的信息、static变量、常量(常量池包含于方法区)、即时编译器编译后的代码数据。
c. 它属于非堆部分。
 
2. 堆(先进先出):
a. 堆是内存最大的一块区域,堆是各线程共享内存的区域。
b. 堆中存放被创建的实例对象、数组。
c. 堆是GC管理的主要区域。
 
3. 栈(先进后出):
a. 栈是线程私有的,它的生命周期与线程相同。线程生命周期(创建,就绪,运行,阻塞,死亡)
b. 栈是java方法执行的内存模型:
    每个方法执行时会在栈中创建一个栈帧(stack frame),用于存放 局部变量表、操作栈、动态链接、方法出口等信息。方法从执行开始就完成了 压栈 到 弹栈 的过程。
    局部变量表中存放了基本数据类型(int,short,long,char,byte,float,double,boolean,其中longdouble  两个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) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

 

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

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

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

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

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

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

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

15. Java里面的Threadlocal是怎样实现的?

16. ConcurrentHashMap的实现原理是?

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

17. sleep和wait区别

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

18. notify和notifyAll区别

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

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

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

19. volatile关键字的作用

20. ThreadLocal的作用与实现

21. 两个线程如何串行执行

22. 上下文切换是什么含义

23. 可以运行时kill掉一个线程吗?

24. 什么是条件锁、读写锁、自旋锁、可重入锁?

25. 什么是协程(用户态线程,减少数据拷贝,降低CPU开销,无callback函数)?

26. 线程池ThreadPoolExecutor的实现原理?

27. J.U.C下的常见类的使用。lock, synchronized, ThreadPool的深入考察; BlockingQueue的使用。(take,poll的区别,put,offer的区别);原子类的实现。

28. 各种常见锁使用如果上面这些掌握很好,还可以看看更深一点的 False Sharing,Cache Line,可见性与原子性等; 

五、Linux使用与问题分析排查

1. 硬链接和软链接的区别?

2. inode是什么?

3. Linux常用命令有哪些?

4. 怎么看一个Java线程的资源耗用?

5. Load过高的可能性有哪些?

6. /etc/hosts文件什么做用?

7. /etc/resolv.conf文件什么作用?

8. 如何快速的将一个文本中所有“abc”替换为“xyz”?

9. 你常用的Linux下用来进行网络和磁盘IO分析的工具有哪些?

10. 你常用的Linux下用来进行内存和CPU分析的工具有哪些?

11. 发现磁盘空间不够,如何快速找出占用空间最大的文件?

12. Java服务端问题排查(OOM,CPU高,Load高,类冲突)

13. Java常用问题排查工具及用法(top, iostat, vmstat, sar, tcpdump, jvisualvm, jmap, jconsole)

14. Thread dump文件如何分析(Runnable,锁,代码栈,操作系统线程ID关联)

15. grep,awk,sed; 是否自己写过shell脚本;

16. 常见的cpu load过高,us过高,一般是什么问题。引申出是否用过top,jstat,jstack等。

17. 常见的内存问题一般有哪些。 引申出是否用过free,top, jmap等。

六、框架使用

1. Spring中Bean的生命周期。

2. SpringMVC或Struts处理请求的流程。

3. Spring AOP解决了什么问题?怎么实现的?aop与cglib,与asm的关系。

4. Spring事务的传播属性是怎么回事?它会影响什么?

5. Spring中BeanFactory和FactoryBean有什么区别?

6. Spring框架中IOC的原理是什么?

7. spring的依赖注入有哪几种方式

8. struts工作流程

9. 用Spring如何实现一个切面?

10. Spring 如何实现数据库事务?

11. Hibernate和Ibatis这类ORM框架的区别?什么是ORM,解决的痛点是什么?

12. spriong ioc的生命周期,(init-method,intilizingbean接口方法afterPropertiesSet的先后顺序)等。

13. Hibernate对一二级缓存的使用,Lazy-Load的理解;

14. Spring IoC AOP自己用代码如何实现

15. RPC的负载均衡、服务发现怎么做的

16. 几种推送模型的区别,long polling,websocket 

七、数据库相关

1. MySQL InnoDB的特点?

2. 乐观锁和悲观锁的区别?

3. 数据库隔离级别是什么?有什么作用?

4. MySQL主备同步的基本原理。

5. 如何从一张表中查出name字段包含“XYZ”的所有行?

6. 索引数据结构(字典+BitTree)

7. 如何优化数据库性能(索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署)

8. SQL什么情况下不会使用索引(不包含,不等于,函数)

9. 一般在什么字段上建索引(过滤数据最多的字段)

10. 如何从一张表中查出name字段不包含“XYZ”的所有行?

11. MySQL,B+索引实现,行锁实现,SQL优化

12. Redis,RDB和AOF,如何做高可用、集群

13. 如何解决高并发减库存问题

14. mysql存储引擎中索引的实现机制;

15. 数据库事务的几种粒度;

16. 行锁,表锁;乐观锁,悲观锁 

八、网络协议和网络编程

1. TCP建立连接的过程。

2. TCP断开连接的过程。

3. 浏览器发生302跳转背后的逻辑?

4. HTTP协议的交互流程。HTTP和HTTPS的差异,SSL的交互流程?

5. Rest和Http什么关系? 大家都说Rest很轻量,你对Rest风格如何理解?

6. TCP的滑动窗口协议有什么用?讲讲原理。

7. HTTP协议都有哪些方法?

8. 交换机和路由器的区别?

9. 什么是VLAN,有什么作用?

10. 什么是VXLAN,有什么作用?

11. http协议(报文结构,断点续传,多线程下载,什么是长连接)

12. tcp协议(建连过程,慢启动,滑动窗口,七层模型)

13. webservice协议(wsdl/soap格式,与rest协议的区别)

14. spdy/http2.0协议是否有了解

15. NIO的好处,Netty线程模型,什么是零拷贝 

九、Redis等缓存系统/中间件/NoSQL/一致性Hash等

1. 列举一个常用的Redis客户端的并发模型。

2. HBase如何实现模糊查询?

3. 列举一个常用的消息中间件,如果消息要保序如何实现?

4. 如何实现一个Hashtable?你的设计如何考虑Hash冲突?如何优化?

5. 分布式缓存,一致性hash

6. LRU算法,slab分配,如何减少内存碎片

7. 如何解决缓存单机热点问题

8. 什么是布隆过滤器,其实现原理是? False positive指的是?

9. memcache与redis的区别

10. zookeeper有什么功能,选举算法如何进行

11. map/reduce过程,如何用map/reduce实现两个数据源的联合统计 

十、设计模式与重构

1. 你在设计一个工厂的包的时候会遵循哪些原则?

2. 你能列举一个使用了Visitor/Decorator模式的开源项目/库吗?

3. 你在编码时最常用的设计模式有哪些?在什么场景下用?

4. 如何实现一个单例?

5. 代理模式(动态代理)

6. 单例模式(懒汉模式,恶汉模式,并发初始化如何解决,volatile与lock的使用)

7. JDK源码里面都有些什么让你印象深刻的设计模式使用,举例看看?

8. Reactor模式 

十一、学习与进取心

1. 平时会关注哪些技术?

2. 会看那些技术博客和网站?

3. 技术上有没有偶像?

4. 看过哪些技术书籍?

5. 你平常都看些什么书?你去年和今年看的书中印象最深的基本技术书籍和非技术书籍是?

6. (如果不看书)你平常都上哪些技术论坛?最喜欢哪个?为什么?

7. 项目或产品中用到了什么新技术或框架

8. 最近研究过什么业界流行的技术或框架

9. 对现在所做的项目或产品的缺陷是否了解,有何规划

10. 是否有带过项目,如何管理项目

11. 是否有带过团队,团队管理最大的挑战点是什么 

十二、抗压能力及抗压意愿

1. 刚才你说的XXX实现跟那个开源的YYY很像,是不是抄来的?

2. 对加班怎么看?

3. 平台是否有加班,是主动还是被动,是否非常抗拒

4. 是否有负责多件事情,多件事情如何并行处理

5. 你对你最近负责项目中最自豪的点是什么? 

十三、稳定性考察

1. 了解家庭婚姻状况, 了解购房及居住地,籍贯情况,了解目前薪资,评估稳定性

2. 如果让你接手一个历史悠久的模块,你会怎么做?

3. 看简历跳槽情况,针对性发问,如跳槽频繁的话问清楚为什么 

十四、开放性问题

1. 一个大文件4G,里面一行行的数字,这时内存只有256M,如果做排序?

2. 如果你部署的应用所在机器硬盘坏了,会发生什么?你的程序要如何处理这种异常?(分布式系统中故障是一种常态,设计要避免单点故障,能容错,保证系统高可用)

3. 实现一个消息队列系统

4. 如何设计一个高可用的架构

5. 多次Hash来解决URL重复访问问题。

6. 全局唯一ID问题。

7. 秒杀如何设计。

8. 如何进行性能优化。

9. 发现CPU 100%,如何排查?

10. 实现一个分布式打点系统。

11. taobao.com和tmall.com的互相登录的问题。

12. 如何快速对一个2亿数据的List进行排序? 

上一篇:17年阿里Java高级面试题 下一篇:Java程序员入职爱奇艺后总结所有面试问题
猜你喜欢
热门排行
精彩图文
  • Java线程池的作用
    Java线程池的作用
    在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建
  • 你能不能谈谈,java GC是在什么时候,对什么东西
    你能不能谈谈,java GC是在什么时候,对什么东西
    在什么时候: 1.新生代有一个Eden区和两个survivor区,首先将对象放入Eden区,如果空间不足就向其中的一个survivor区上放,如果仍然放不下就会引发一次发生
  • ThreadLocal(线程变量副本)
    ThreadLocal(线程变量副本)
    Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量。 采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,
  • 线程池的种类,区别和使用场景
    线程池的种类,区别和使用场景
    一个线程从被提交(submit)到执行共经历以下流程: 线程池判断核心线程池里是的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务
  • Java编程,打印昨天的当前时刻
    Java编程,打印昨天的当前时刻
    public class YesterdayCurrent{ public void main(String[] args){ Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -1); System.out.println(cal.getTime()); } }