《Java程序员面试宝典》——(第一章节)

博主专注IT和软件开发领域,喜欢我的文章欢迎添加 【关注】

除了掌握扎实的专业技能之外,你还需要一份《Java程序员面试宝典》才能在万千面试者中胜出重围,成功拿下属于你的offer。

1、JDK 和 JRE 有什么区别?
JDK:Java Development Kit,JDK是面向开发人员的,是开发工具包,包括开发人员需要用到的一些类,JDK中包含JRE

JRE:Java Runtime Environment,JRE是java运行时环境,包含了运行 Java 程序所需的类库、JVM(Java 虚拟机)和其他文件,但不包含 Java 的开发工具。如果只需要运行 Java 应用程序,而不是开发它,那么只需要 JRE。
 
2、两个对象的 hashCode()相同,则 equals()也一定为 true吗?

不对,hashCode也是可以重写的,所以不一定。

反之,如果equals()相同,那么hashCode是一定相等的。
 
3、final 关键字在 java 中有什么作用?
声明为final的类,方法,变量不能被继承,重写 和修改。final关键字在Java中用于表示不可变的实体,包括类、方法和变量。通过使用final关键字,可以增强代码的安全性、可读性和性能。

4、 java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder

String类型的字符串是不可变的,StringBuffer和StringBuilder是可以对同一个对象做更新操作的;

StringBuffer是线程安全的,StringBuilder不是线程安全的,但是效率比较高。

5、抽象类必须要有抽象方法吗?
不是。抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。

6、普通类和抽象类有哪些区别?
普通类可以直接实例化对象,而抽象类不能直接实例化,只能被用作其他类的父类,需要通过子类继承并实现抽象类中的抽象方法后才能创建对象。

7、接口和抽象类有什么区别?

接口是要被实现的,抽象类是要被继承;
接口用interface修饰;抽象类使用abstract修饰;
两者均不能被实例化,方法都不包含主体;
一个类只能继承一个抽象类,但是可以实现多个接口。

8、java中的基本数据类型?
byte、char、short、int、long、float、double、boolean
在Java中,String不是基本数据类型,而是引用数据类型,数组也是引用数据类型;

9、 == 和 equals 的区别是什么?
==比较的是引用是否相同,比较的是对象的引用地址,如果比较的两个对象地址位不同,值相同也会返回false

而equals()比较的是对象的内容是否相同,只要值相同,就会返回true

10、什么是多态?
种事物的多种表现形态就是多态,比如定义一个类为动物,那么动物可以被子类继承,从而实现具体动物的方法。

11、重写和重载的区别?
重载:必须有不同的参数列表;可以有不同的访问修饰符;可以抛出不同的异常;

重写:参数列表必须要与被重写的相同;返回的类型必须保持一致;修饰符和抛出的异常不能在被重写的方法之外

重写是父类与子类的关系,是垂直关系;重载是同一个类方法中的关系,是水平关系。
12、 List、Set、Map 之间的区别是什么?
List:有序集合、元素可重复
Set:元素不可重复,HashSet无序,LinkedHashSet按照插入排序,SortedSet可排序
Map:键值对集合,存储键、值之间的映射。key无序,唯一,value可重复

13、集合Collection 和 Collections 有什么区别?
Collection是集合的接口,其实现类有List和Set;
Collections是工具类,包含许多有关集合操作的静态多态方法,可以直接使用。

14、说一下 HashMap 的实现原理?
HashMap基于Hash算法实现,通过put(key,value)存储,get(key)来获取value

当传入key时,HashMap会根据key,调用Hash(Object key)方法,计算出Hash值,根据Hash值将Value保存在Node对象里,Node对象保存在数组里。

当计算出的Hash值相同时,称为Hash冲突,HashMap的做法是用链表和红黑树存储相同Hash值的value

当Hash冲突的个数:小于等于8使用链表,大于8使用红黑树解决链表查询慢的问题。

15、HashMap 和 Hashtable 有什么区别?
HashMap不是线程安全的,HashTable是线程安全的
HashMap允许Null Key和Null Value
‌Hashtable的key和value都不允许为null。‌ 如果尝试在Hashtable中插入null值,会在运行时抛出NullPointerException异常。‌

16、ArrayList 和 LinkedList 的区别是什么?
ArrayList的数据结构是动态数组;LinkedList的数据结构是双向链表。

ArrayList比LinkedList在随机访问的时候效率要高,因为LinkedList是线性的数据结构,需要依次往后查找

在非首尾的增删操作,LinkedList要比ArrayList的效率要高,因为ArrayList在操作增删时要影响其他元素的下标

总结:需要频繁读取集合中的元素时,推荐使用ArrayList;插入和删除操作较多时,推荐使用LinkedList

17、如何实现数组和 集合List 之间的转换?

List转为数组:String[] list = List.toArray(array);//array为List

数组转为List:List list = java.util.Arrays.asList(array);//array为数组

18、并行和并发有什么区别?
并行是指两个或多个事件在同一时刻发生,是在不同实体上的多个事件;

并发是指两个或多个事件在同一时间间隔发生,是在同一个实体上的多个事件

19、线程和进程的区别?
进程是资源分配最小单位,线程是程序执行最小单位

每个进程都有相应的线程

进程有独立的地址空间,线程没有

线程是指处理机调度的基本单位

进程执行开销大,线程执行开销小

20、创建线程有哪几种方式?
继承Thread类并实现run方法,调用继承类的start方法开启线程;

通过实现Runnable接口,重写run方法,调用线程对象的start方法开启线程;

除此之外,还可以通过实现Callable接口,实现call方法,并用FutureTask类包装Callable对象开启线程。

21、说一下 runnable 和 callable 有什么区别?
实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的任务线程并不能返回执行结果

Callable接口的call方法允许抛出异常,而Runnable接口的run方法的异常只能在内部消化,不能继续上抛

22、线程有哪些状态?

新生、就绪、运行、阻塞、死亡

23、notify()和 notifyAll()有什么区别?
notify()方法会唤醒对象等待池中的一个线程,进入锁池

notifyAll()方法会唤醒等待池中的所有线程,进入锁池

24、sleep() 和 wait() 有什么区别?
sleep后程序不会释放同步锁,wait后程序会释放同步锁

sleep可以指定睡眠时间,自动唤醒,wait可以直接用notify唤醒

sleep的类是Thread,wait的类是Object

25、创建线程池有哪几种方式?

主要使用Excutors提供的通用线程池创建方法,去创建不同配置的线程池

newCachedThreadPool();特点:用来处理大量短时间工作任务的线程池

newFixedThreadPool(int nThreads);特点:重用指定数目(nThreads)的线程

newSingleThreadExecutor();特点:工作线程数目限制为1

newSingleThreadScheduledExecutor()和newScheduledThreadPool(int corePoolSize)可以进行周期或定时性的工作调度

26、线程池中 submit()和 execute()方法有什么区别?
submit()方法可以接受Callable或Runnable类型的任务,并返回一个Future对象,通过这个Future对象可以获取任务的执行结果或者取消任务执行。
而execute()方法只能接受Runnable类型的任务,没有返回值。‌这意味着submit()方法更加灵活,适用于需要获取任务执行结果的场景,而execute()方法适用于不需要获取执行结果的简单任务提交‌
execute() 没有返回值;而 submit() 有返回值

submit()的返回值Future调用get方法时,可以捕获处理异常

27、线程的 run()和 start()有什么区别?
调用start()方法是用来启动线程的,轮到该线程执行时,会自动调用run方法;

直接运行run方法无法达到启动多线程的目的,相当于调用Thread对象中的run方法

一个线程的start方法只能调用一次,多次调用会抛出异常;而run方法可以多次调用

28、说一下 synchronized 底层实现原理?
synchronized 是 Java 中的一个关键字,用于控制多线程的访问,确保同一时刻只有一个线程可以执行被 synchronized 修饰的代码块或方法。底层实现主要依赖于 JVM 的 monitor 机制。
当 synchronized 修饰一个方法时,JVM 会生成 ACC_SYNCHRONIZED 标志,表示该方法是同步的;
当 synchronized 修饰代码块时,JVM 会在同步块的前后分别生成 monitorenter 和 monitorexit 字节码指令。
总体来说,synchronized 关键字的实现依赖于互斥锁,并且在 JVM 层面保证了可见性和顺序一致性。

29、ThreadLocal 是什么?有哪些使用场景?
ThreadLocal是线程本地存储,在每个线程中都创建了一个ThreadLocalMap对象,每个线程可以访问自己内部ThreadLocal对象内的value。

经典的使用场景是为每个线程分配一个JDBC连接的Connection,这样就可以保证每个线程都在各自的Connection上进行数据库的操作,不会出现A线程关了B线程的Connection,还有Session管理等问题。

30、什么是死锁?怎么防止死锁?
死锁是指两个或两个以上的进程在竞争资源的过程中造成的不可解堵塞。两个线程都在互相等待。
为了防止死锁,可以采取以下策略:
避免一个线程同时获取多个锁。
如果需要获取多个锁,确保在同一个顺序中获取它们。
使用tryLock方法代替lock方法,并在无法获取锁时释放已经获取到的锁。
设置锁的超时时间,使用例如ReentrantLock的tryLock(long timeout, TimeUnit unit)方法。

31、synchronized 和 Lock 有什么区别?

synchronized是关键字,属于JVM层面;Lock是具体类,是API层面的锁;

synchronized无法获取锁的状态,Lock可以判断;

synchronized用于少量同步,Lock用于大量同步。

32、synchronized 和 ReentrantLock 区别是什么?
synchronized代码执行结束后线程自动释放对锁的占用;Reentrantlock需要手动释放锁;

synchronized不可中断,除非抛出异常或者执行完成;Reentrantlock可中断;

synchronize非公平锁;Reentrantlock默认非公平锁,也可公平锁;

ReentrantLock用来实现分组唤醒需要唤醒的线程,可以精确唤醒,而不是像synchronized要么随机唤醒一个,要么唤醒全部线程。

33、了解乐观锁和悲观锁?
乐观锁:认为每次去拿数据的时候别人不会修改,所以不会上锁,但是每次要提交数据的时候都会先判断数据是否被别人修改

悲观锁:认为每次去拿数据的时候别人都会修改,所以每次都会上锁。

使用场景:乐观锁使用于多读少写的应用类型,这样可以提高吞吐量;相反的情况则使用悲观锁

34、深克隆和浅克隆区别是什么?
深克隆:新旧对象不共享一个地址;

浅克隆:新旧对象共享一个地址,改变一个,另一个也会改变

35、动态代理是什么?有哪些应用?

在运行时,创建一个新的类,即创建动态代理,可以调用和扩展目标类的方法。动态代理的类是自动生成的。

应用:Spring的AOP,加事务,加权限,加日志。

36、怎么实现动态代理?

基于jdk,需要实现InvocationHandler接口,重写invoke方法。

基于cglib,需要jar包依赖;

37、 什么是反射?

java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能成为java的反射机制。

38、什么是 java 序列化?什么情况下需要序列化?

序列化:将java对象转换成字节流的过程。

反序列化:将字节流转换成java对象的过程。

当java对象需要在网络上传输或者持久化存储到文件中时,就需要对Java对象进行序列化处理。

序列化的实现:类实现Serializable接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值