《隔离十四天》系列 -第十一天 -Java面试题大全

前言

今天又是朝气蓬勃的一天,虽然还没找到合适的工作,但是也不能丧失了对生活的信心,还是要勇敢的面对生活,比如我们说一句,奥里给!!!

当然了每日膜拜大佬的节奏不能断了,还是要在网上多跟各位大佬学习,学习技术,提高自己。
在这里插入图片描述

好了,言归正传,今天依然是看面试题的一天,当然也学习了基础薄弱的数据结构,果真发觉自己啥都不懂,不配说自己是软件工程出身的。
在这里插入图片描述

这些面试题是自己在网上看面试题的时候看到觉得自己不懂的然后copy到笔记中的,自己是个面试题的搬运工。
在这里插入图片描述

说一下 HashMap 的实现原理?

HashMap 基于 Hash 算法实现的,我们通过 put(key,value)存储,get(key)来获取。当传入 key 时,HashMap 会根据
 key. hashCode() 计算出 hash 值,根据 hash 值将 value 保存在 bucket 里。当计算出的 hash 值相同时,我们称
 之为 hash 冲突,HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时,使用
 链表否则使用红黑树。

说一下 HashSet 的实现原理?

HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,相关
 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,HashSet 不允许重复的值。

ArrayList 和 LinkedList 的区别是什么?

数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。
	
随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以
需要移动指针从前往后依次查找。
	
增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影
响数组内的其他数据的下标。

综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用LinkedList。

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

实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
	
构造函数:抽象类可以有构造函数;接口不能有。
	
实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
 
访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能
修饰抽象类,
final 在 Java 中有什么作用?
	
final 修饰的类叫最终类,该类不能被继承。
	
final 修饰的方法不能被重写。
	
final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。

抽象类必须要有抽象方法吗?
不需要,抽象类不一定非要有抽象方法。但是有抽象方法的一定是抽象类

如何将字符串反转?

使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
// StringBuffer reverse
StringBuffer stringBuffer = new StringBuffer();
stringBuffer. append("abcdefg");
System. out. println(stringBuffer. reverse()); // gfedcba
// StringBuilder reverse
StringBuilder stringBuilder = new StringBuilder();
stringBuilder. append("abcdefg");
System. out. println(stringBuilder. reverse()); // gfedcba

Java 中操作字符串都有哪些类?它们之间有什么区别?

操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的String
 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以
 在经常改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全
的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推
荐使用 StringBuffer。

HashMap 和 Hashtable 有什么区别?

存储:HashMap 运行 key 和 value 为 null,而 Hashtable 不允许。
	
线程安全:Hashtable 是线程安全的,而 HashMap 是非线程安全的。
	
推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代
,如果需要多线程使用则用 ConcurrentHashMap 替代。

在 Queue 中 poll()和 remove()有什么区别?

相同点:都是返回第一个元素,并在队列中删除返回的对象。
	
不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常。

创建线程有哪几种方式?

创建线程有三种方式:
	
继承 Thread 重写 run 方法;
	
实现 Runnable 接口;
	
实现 Callable 接口。

线程有哪些状态?

线程的状态:
NEW 尚未启动

RUNNABLE 正在执行中
	
BLOCKED 阻塞的(被同步锁或者IO锁阻塞)
 
WAITING 永久等待状态
	
TIMED_WAITING 等待指定的时间重新被唤醒的状态
	
TERMINATED 执行完成

sleep() 和 wait() 有什么区别?

* 
类的不同:sleep() 来自 Thread,wait() 来自 Object。
	
释放锁:sleep() 不释放锁;wait() 释放锁。
	
用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。

线程的 run() 和 start() 有什么区别?

start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。run() 可以重复调用,而 start() 只能调用一次。

怎么防止死锁?

尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时
时间,超时可以退出防止死锁。
	
尽量使用 Java. util. concurrent 并发类代替自己手写锁。
	
尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
	
尽量减少同步的代码块。

synchronized 和 Lock 有什么区别?

synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁。
	
synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而 lock 需要自己加锁和
释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。
	
通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。

synchronized 和 ReentrantLock 区别是什么?

synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大,但是在 Java 6 中对 
synchronized 进行了非常多的改进。
主要区别如下:
	
ReentrantLock 使用起来比较灵活,但是必须有释放锁的配合动作;
	
ReentrantLock 必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁;
	
ReentrantLock 只适用于代码块锁,而 synchronized 可用于修饰方法、代码块等。

什么是反射?

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

什么是 Java 序列化?什么情况下需要序列化?

Java 序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。
以下情况需要使用 Java 序列化:
	
想把的内存中的对象状态保存到一个文件中或者数据库中时候;
	
想用套接字在网络上传送对象的时候;
	
想通过RMI(远程方法调用)传输对象的时候。

session 和 cookie 有什么区别?

	
存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
	
安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
	
容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制。
	
存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中。

说一下 session 的工作原理?

session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 
id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,
服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。

如果客户端禁止 cookie 能实现 session 还能用吗?
可以用,session 只是依赖 cookie 存储 sessionid,如果 cookie 被禁用了,可以使用 url 中添加 sessionid 的方
式保证 session 能正常使用。

final、finally、finalize 有什么区别?

	
final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用。
	
finally:是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况都会执行,finally 部分可以省略,但如果
 finally 部分存在,则一定会执行 finally 里面的代码。
	
finalize: 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。

简述 tcp 和 udp的区别?

tcp 和 udp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输,而 udp 则常被用于让广播和细节控制交给应用的通信传输。
两者的区别大致如下:
	
tcp 面向连接,udp 面向非连接即发送数据前不需要建立链接;
	
tcp 提供可靠的服务(数据传输),udp 无法保证;
	
tcp 面向字节流,udp 面向报文;
	
tcp 数据传输慢,udp 数据传输快;

如何实现跨域?

实现跨域有以下几种方案:
	
服务器端运行跨域 设置 CORS 等于 *;
	
在单个接口使用注解 @CrossOrigin 运行跨域;
	
使用 jsonp 跨域;

说一下你熟悉的设计模式?

	
单例模式:保证被创建一次,节省系统开销。
	
工厂模式(简单工厂、抽象工厂):解耦代码。
	
观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
	
外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。
	
模版方法模式:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,
重新定义算法的步骤。
	
状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

spring 事务实现方式有哪些?

	
声明式事务:声明式事务也有两种实现方式,基于 xml 配置文件的方式和注解方式(在类上添加 @Transaction 注解)。
	
编码方式:提供编码的形式管理和维护事务。

为什么要用 spring boot?

	
配置简单
	
独立运行
	
自动装配
	
无代码生成和 xml 配置
	
提供应用监控
	
提升开发效率

spring cloud 断路器的作用是什么?

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故
障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长
时间占用不释放,避免了故障在分布式系统中的蔓延。

spring cloud 的核心组件有哪些?

	
Eureka:服务注册于发现。
	
Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。
	
Ribbon:实现负载均衡,从一个服务的多台机器中选择一台。
	
Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。
	
Zuul:网关管理,由 Zuul 网关转发请求给对应的服务。

MyBatis 是否支持延迟加载?延迟加载的原理是什么?

MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。
延迟加载的原理的是调用的时候触发加载,而不是在初始化的时候就加载信息。比如调用 a. getB(). getName(),这个时候发现 a. getB()
 的值为 null,此时会单独触发事先保存好的关联 B 对象的 SQL,先查询出来 B,然后再调用 a. setB(b),而这时候再调用 
 a. getB(). getName() 就有值了,这就是延迟加载的基本原理。

以上就是今天搬运的一些面试题了,希望对大家有用,也祝各位能在这个时候找到一个合适的工作。每天都是努力向上的一天。

最后也希望大佬能够分享一些面试经验,万分感谢。

在这里插入图片描述

发布了92 篇原创文章 · 获赞 7 · 访问量 7538

猜你喜欢

转载自blog.csdn.net/qq_40126996/article/details/104452615
今日推荐