JAVA面试题

1. 语言特点
跨平台
解释执行
垃圾回收
反射机制
2. 面向对象 (OO)
面向对象是一种开发范式,通过抽象和实例化来解决问题,易于维护、复用和拓展。
面向过程则将问题拆解成方法,通过方法调用解决问题,执行效率高。
面向对象的三大特性:封装、继承、多态。
封装:隐藏内部信息,暴露接口。
继承:复用父类属性和方法,可重写方法。
多态:同一件事在不同对象上有不同结果。
实现多态的方式:重写、接口、抽象类与抽象方法。
3. 重写和重载
重写:子类对父类的同名方法进行新的实现,参数、返回值相同。
重载:同一类中存在多个同名方法,但参数数量或类型不同。
4. 反射机制
概念:在运行时获取类的所有方法和属性,并调用对象的任意方法和属性。
Class类:保存类的完整信息,每个类都有一个Class对象。
获取Class对象的三种方式:
使用.class属性。
使用Class.forName()方法。
使用对象实例的getClass()方法。
功能:运行时判断类、构造对象、获取类中属性和方法。
场景:注解原理、动态代理。
优缺点:
优点:提高代码灵活度。
缺点:性能瓶颈、安全问题。
应用场景:JDBC连接数据库、Spring框架的IOC和AOP、动态配置实例属性。
5. 代理
静态代理:手动编写的设计模式。
动态代理:使用反射机制。
JDK代理:只能代理实现了接口的类。
CGLIB代理:可以代理未实现任何接口的类。
两种代理的区别:
灵活性:动态代理更灵活,无需实现接口。
JVM层面:静态代理编译时生成class文件,动态代理运行时动态生成。
6. Java创建对象的方法
使用new关键字。
通过反射动态创建:使用class.newInstance()方法或xx.class.getConstructor.newInstance()方法。
clone()方法:默认浅拷贝,需要重写实现深拷贝。
反序列化:通过readObject方法创建。
7. String、StringBuilder、StringBuffer
String:不可变,底层是final的char数组,拼接字符串时会重新开辟空间。
StringBuilder:可变,直接对字符串进行拼接操作,效率高于String。
StringBuffer:与StringBuilder作用相同,但方法使用了synchronized修饰,保证线程安全。
8. equals和hashcode方法
equals:比较对象是否相等,默认比较内存地址,需要重写比较内容。
hashcode:返回对象在哈希表中的位置,需要与equals方法配合使用。
9. 深拷贝和浅拷贝
浅拷贝:复制对象引用,新对象和原对象指向同一内部对象。
深拷贝:完全复制对象,包括内部引用数据类型的属性。
10. 集合
ArrayList和LinkedList的区别:
底层实现:ArrayList是动态数组,LinkedList是链表。
查找:ArrayList更容易查找。
添加:LinkedList更容易添加。
ArrayList的扩容机制:当元素数量超过容量时,会创建新的数组并复制元素。
ArrayList的遍历删除:使用iterator的remove方法进行删除。
LinkedList的底层实现:双向链表,每个节点维护前后节点指针。
HashMap的底层实现:数组+链表+红黑树(JDK1.8)。
HashMap的put方法:计算哈希值,确定位置,插入元素,如果超过阈值则扩容。
HashMap的扩容机制:容量扩大两倍,并重新计算哈希值。
为什么HashMap的扩容是2倍:为了提高运算效率,使用位运算代替取模运算。
HashSet底层:基于HashMap实现,key不能重复。
HashMap和HashSet的区别:

JAVA面试题_第1张图片
HashMap和HashTable的区别:

线程是否安全:HashMap 是非线程安全的,Hashtable 是线程安全的,因为 Hashtable 内部的方法基本都经过 synchronized 修饰。(如果要保证线程安全的话就使用 ConcurrentHashMap 吧!)
效率:因为线程安全的问题,HashMap 要比 Hashtable 效率高一点。另外,Hashtable 基本被淘汰,不要在代码中使用它;
对 Null key 和 Null value 的支持:HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个;Hashtable 不允许有 null 键和 null 值,否则会抛出NullPointerException。
初始容量大小和每次扩充容量大小的不同:① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小(HashMap 中的 tableSizeFor() 方法保证)。
底层数据结构:JDK1.8 以后的 HashMap 在解决哈希冲突时有较大的变化,当链表长度大于阈值(默认为 8)时,将考虑将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间。Hashtable 没有这样的机制。
TreeSet和TreeMap:TreeSet是有序的Set,TreeMap是有序的Map。
解决hash冲突:开放定址法、再哈希、拉链法、建立公共溢出去区。
CopyOnWriteArrayList:线程安全的ArrayList,适用于读多写少的并发场景。
ConcurrentHashMap:线程安全的HashMap,采用分段锁技术,并使用CAS和synchronized保证线程安全。
BlockingQueue:阻塞队列,实现包括ArrayBlockingQueue、LinkedBlockingQueue等。
11. 多线程
并发三个特性:原子性、有序性、可见性。
进程和线程:
进程:系统资源分配的基本单位,程序的执行过程。
线程:进程的执行单位,可以共享进程资源。
进程的通信方式:信号量、管道、消息队列、共享内存、套接字。
线程的通信方式:锁机制、全局共享变量、wait()、notify()、notifyAll()、await()、signal()、signalAll()、BlockingQueue。
Java线程的状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。
创建线程的方式:继承Thread类、实现Runnable接口、实现Callable接口、线程池。
Runnable和Callable的区别:Callable有返回值,可以抛出异常。
Thread和Runnable的区别:Runnable更灵活,可以实现资源共享。
线程关闭/停止:设置退出标志、使用interrupt()方法、使用stop()方法(不推荐)。
线程池:
作用:降低消耗、提高响应速度、提高可管理性。
参数:核心线程数、最大线程数、空闲时间、工作队列、拒绝策略、线程创建工厂。
运行状态:运行中、关闭中、终止。
阻塞队列:避免线程等待耗费CPU,当队列满时阻塞加入队列的线程,队列空时阻塞消费线程。
拒绝策略:当队列满且线程数达到最大值时,如何处理新任务。
四种线程池:可缓存线程池、定长线程池、可调度线程池、单线程化的线程池。
线程池关闭:shutdown()和shutdownNow()方法。
ThreadLocal:线程内部的存储类,允许线程存放自己的私有数据。
底层实现:ThreadLocalMap,存储以ThreadLocal为key,Object为value的键值对。
OOM内存泄漏:使用弱引用,需要手动调用remove()方法清理。
使用场景:对象跨层传递、线程间数据隔离、事务操作、数据库链接。
12. 同步
同步和互斥的区别:同步实现有序访问,互斥保证排他性。
线程间同步方式:互斥锁、信号量、事件。
Java的锁:公平/非公平锁、可重入/不可重入锁、独享锁/共享锁、乐观锁/悲观锁、分段锁、偏向锁/轻量级锁/重量级锁。
锁池和等待池:锁池用于竞争锁,等待池用于等待通知。
线程同步:
volatile:保证可见性和有序性,但不能保证原子性。
synchronized:保证可见性、原子性和有序性。
ReentrantLock:可重入锁,灵活、强大,支持公平锁、非公平锁、中断、超时等功能。
AQS:抽象队列同步器,是Java并发包的基础类,管理同步队列和条件队列。
Lock接口:ReentrantLock实现了该接口,提供lock()和unlock()方法。
synchronized和ReentrantLock的区别**:底层、使用、性能、中断、公平性、唤醒线程的方式。
四种情况下用lock不用synchronized:需要公平锁、需要灵活使用、需要中断、需要精确唤醒。
同步器/计数器:CountDownLatch和CyclicBarrier。
悲观锁和乐观锁:悲观锁假设每次访问都会出现问题,乐观锁假设不会出现问题。
乐观锁的实现:版本号机制、CAS算法。
CAS:比较与交换,用于实现乐观锁,存在ABA问题和循环时间开销大的问题。
公平锁和非公平锁:公平锁先申请的线程先得到锁,非公平锁可能后申请的线程先得到锁。
13. IO模型
阻塞IO (BIO):读写时阻塞,完成后才可继续执行。
非阻塞IO (NIO):发送IO请求后立即返回,需要不断轮询数据是否准备好。
异步IO:发起请求后去干别的事,数据准备完成后内核向用户线程发送信号。
NIO多路复用:利用单线程记录跟踪每个IO流状态,达到一个线程管理多个IO流的效果。
select、poll、epoll系统调用:都是IO多路复用的机制,但epoll效率更高。
14. Object类有哪些方法
hashcode, equals, notify, notifyAll, wait, clone, toString, finalize

你可能感兴趣的:(面试部分,java,开发语言)