个人整理,部分面试题

你是怎样理解OOP面向对象:
面向对象是利用语言对现实事务进行抽象。具有三大特征,分别是继承封装和多态。
继承:从已有类得到继承信息创建新的类的过程
封装:把数据和操作数据的方法绑定起来,访问数据只能通过已经定义 的接口。
多态:父类引用指向子类对象。

重载与重写区别 :
重载发生在本类,重写发生在父类和子类之间
重载的方法名相同,重写的方法名和返回类型相同
重载的参数列表不同,重写的参数列表相同
重写的访问权限不能比父类中被重写的方法的访问权限更低
构造方法不能被重写

接口与抽象类的区别
抽象类要被子类继承,接口要被类实现
接口可多继承接口,但类只能单继承
抽象类可以有构造器,接口不能有构造器
接口的修饰符只能是public
抽象类可以有成员变量,接口只能声明常量

深拷贝与浅拷贝的理解
深拷贝和浅拷贝就是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用
浅拷贝是指,只会拷贝基本数据类型的值,以及实例对象的引用地址,浅拷贝出来的对象,内部类属性指向的是一个对象
深拷贝是指,又会拷贝基本数据类型的值,也会针对实例对象的引用地址所指向的对象进行复制,深拷贝出来的对象,内部类的执行指向的不是同一个对象

sleep和wait区别
sleep方法:
释放cpu给其他线程,不释放锁资源
sleep(1000)等待超过1s被唤醒
wait方法:
释放cpu给其他线程,释放锁资源
wait(1000)等待超过1s被唤醒,wait()一直等待需要通过notify或者notifyAll进行唤醒

什么是自动拆装箱  int和Integer有什么区别
基本数据类型,不具备对象的特征,不能调用方法。
装箱:基本数据类型转换成包装类,拆箱相反
java为什么要引入自动装箱和拆箱的功能?主要是用于java集合中,List<Inteter> list=new ArrayList<Integer>();
list集合如果要放整数的话,只能放对象,不能放基本类型,因此需要将整数自动装箱成对象。
区别:
integer的默认值为null,int的默认值为0
integer必须实例化之后才能使用

==和equals区别 
==如果比较的是基本数据类型,比较的是变量的值。如果比较的是引用数据类型,比较的是地址值
equals
如果没有重写比较的是两个对象的地址值,如果重写了比较的是对象中的属性内容

String能被继承吗 为什么用final修饰
String不能被继承,因为String类有final修饰符,而final修饰的类是不能被继承的
String 类是最常用的类之一,为了效率,禁止被继承和重写
为了安全考虑

String buffer和String builder区别
Stringbuffer是线程安全的,stringbulier是线程不安全的
stringbulider效率更快,因为不需要加锁

final、finally、finalize 
final是修饰符,修饰类时不能被继承,修饰方法时不能被重写,修饰变量时不能被更改
finally:通常放在trycatch的后面构造最终执行代码块,无论程序是否发生异常,都会执行此部分代码
finalize:通过重写finalize() 方法可以整理系统资源或者执行其他清理工作

ArrarList和LinkedList区别
arrarlist基于数组,linkedlits基于链表
查找操作时,arraylist效率高,增删时linkedlist效率高

HashMap底层是 数组+链表+红黑树,为什么要用这几类结构
数组,哈希表,根据对象的key的hash值进行在数组里面是哪个节点
链表用来解决hash冲突
红黑树:jdk8使用红黑树来代替超过8个节点的链表,提升查询性能

HashMap和HashTable区别
hashmap线程不安全,hashtable是线程安全的
hashtable中key和value都不饿允许为空,hashmap可以作为键,这样的键只有一个。可以有多个值为空                                                                  
hashtable默认容量为11,hashmap为16.hashtable扩容时变为原来的2倍+1,hashmap扩容时,将容量变为原来的2倍

线程的创建方式
继承thread类创建线程
实现runnable接口创建
使用callable和future创建线程 有返回值
使用线程池创建线程

线程的状态转换有什么(生命周期)
新建,就绪,运行,阻塞,死亡

Java中有几种类型的流 
字节流和字符流

请写出你最常见的5个RuntimeException
空指针异常,classnotfound异常,字符串转数字异常,数组越界异常,数据类型转换异常

谈谈你对反射的理解
在java运行时的环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于java语言的反射机制。

什么是 java 序列化,如何实现 java 序列化
序列化是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

cookie和session的区别
cookie是在服务器中生成发送给浏览器,之后浏览器在向服务器发送请求时会发送cookie
session是存储于服务器的一块信息。session对象存储特定用户会话所需的属性及配置信息。当用户在web页面之间跳转时,存储在session中的变量不会消失
无论客户端做怎样的设置,session 都能够正常工作。当客户端禁用 cookie 时将无法使用 cookie
在存储的数据量方面:session 能够存储任意的java 对象,cookie 只能存储 String 类型的对象

什么情况下会产生StackOverflowError(栈溢出)和OutOfMemoryError(堆溢出)
栈溢出原因:无限递归循环调用
堆溢出原因:内存中加载的数据量过于庞大,如一次从数据库取出过多数据


九股文
jvm
垃圾回收:
什么是垃圾回收:比如说我们通过可达性算法将不可达的对象进行清理
为什么需要垃圾回收:如果我们一直创建对象不分配内存的话,内存会迟早耗空
一次完整的垃圾回收过程:首先进行垃圾分类,确定哪些对象是垃圾对象,哪些是存活对象。然后是垃圾查找,分类后找出所有垃圾对象,以便清理,最后是垃圾清理,通过不同的算法
判断对象是否是垃圾对象的方法:引用计数法:对象被引用时计数器加一,被释放时计数器减一。计数器为零就代表这个对象是垃圾对象
可达性分析法:从根节点开始遍历(gcroot)递归的访问所有可达的对象,并打上标记,未被标记的就是垃圾对象
gcroot对象都有哪些:方法区的静态变量 方法区中的常量引用 活动线程 类加载器
垃圾回收算法:标记-清除法:直接清楚未被标记的对象    标记-压缩法:标记可达对象后,将存活的对象压缩到另一端,整理出连续可用的内存空间
复制法:将内存分为两个相等的区域,每次只使用其中一个,使用结束后把存活的对象移动到另一个区域,然后清空当前区域

jvm主要组成部分:类加载器 方法区 栈 堆 程序计数器 执行引擎 本地接口 本地方法库
jvm堆的内部结构:堆主要存储的是我们的实例化对象和数组,也是jvm的主要管理区域,通常会分为新生代,老年代和永久代元空间。新生代主要存储新创建的对象,这类对象很快就会被垃圾回收。老年代用来存储生命周期较长的对象。新生代中历经多次垃圾回收的对象还没被回收的化会移动到老年代。老年代回收垃圾的次数较少,回收时间长。永久代:jdk8之前用于储存常量池方法信息等,大小是固定的,容易引起内存溢出。元空间:jdk8开始,永久代被元空间取代,不在jvm堆中而是使用本地内存,大小可以动态调整。
jvm堆和栈的区别:
堆:
存储内容:用来存储对象实例和数组,所有对象实例和数组都在堆中分配内存
内存管理方式:由垃圾收集器进行自动管理。堆内存是线程共享的,所有线程都能访问堆中的对象
生命周期:对象在堆中的生命周期由垃圾回收决定,只要有引用指向对象,对象就会在
线程不安全
栈:
存储内容:用于存储方法的局部变量,方法的调用参数和调用信息。
内存管理方式:由编译器自动管理,内存分配和释放按照方法调用的顺序进行。栈是线程私有的
生命周期:栈中的数据在方法调用结束后立即释放
线程安全的
触发fullgc的几种情况:
老年代空间不足,永久代或元空间不足
为什么要分eden和survivor:jvm将新生代分为eden和survivor两个区主要原因是为了优化垃圾回收的效率和性能,利用复制算法来提高效率。
为什么将永久代替换为元空间:因为永久代的大小是固定的,容易发生内存溢出问题。元空间使用的本地内存,且大小并不固定,所以不容易内存溢出

jvm三色标记算法是什么:用于垃圾回收的标记算法,将对象分为三种颜色(白灰黑)。主要解决了在并发垃圾收集过程中如何正确标记存活对象的问题。
首先所有对象刚开始都会标记成白色,之后将gcroots标记为灰色,并放入待处理队列。从队列中取出一个灰色对象,把他变为黑色,并将该对象引用的白色对象转为灰色,并把这些加入队列,重复步骤,知道队列为空,最后清除所有白色对象。
优点:是一种高效的并发垃圾回收方法,确保了存活对象的准确标记。但是比较复杂,运行效率较低。

jvm的四种引用:
强引用:最常见的引用类型,通过new关键字创建的对象就是强引用,强引用在对象就不会被回收。
软引用:内存不足的情况下垃圾回收器会回收软引用对象
弱引用:不管内存足不足都会被垃圾回收器回收
虚引用:用于跟踪对象被垃圾回收器的回收时间

双亲委派机制是什么:是一种类加载机制,确保java类加载过程的安全性和一致性,每个类加载器加载类时,优先委派给其父类的加载器,只有当父类的加载器无法完成加载时,才会由当前类加载器尝试加载。
作用:保证java核心库的安全性,避免类的重复加载,提高类的加载效率
如何破坏:自定义类加载器

java创建对象的几种方法:使用new关键字,使用反射,使用clone方法
什么时候会发生栈溢出:递归调用过深,递归无终止条件,栈空间设置过小


redis:
redis支持哪几种数据类型:String,hash,list,set,zset。最平常使用的就是string,可以缓存内容,做分布式锁等等。hash用来缓存一些对象结构的数据。zset主要用来排序。
redis的优点:相比于其他的缓存,redis最大的一个优势就是高性能,redis的速度非常快。各种操作都是基于内存,读写操作很快。还提供了丰富的数据类型,像string,hash,zset等
redis是单进程单线程的吗:redis的核心操作是单线程的,但redis在某些方面使用了额外的线程,例如内存释放,持久化数据。
redis过期策略有哪些:过期策略主要分为被动和主动,主动又分定时定期,被动就是常说的惰性清理。redis经常采用的是定期+惰性的方式配配合来实现的、
什么是缓存穿透:缓存穿透的核心就是请求发来时key在缓存中不存在时,就会请求数据库,如果数据库中也没有,就会返回,由于没有数据,不会存入到缓存中,下次请求还会重复此操作。如果key一直没有数据,就会不断的打入到数据库中,这就是缓存穿透。解决方案:使用布隆过滤器,先判断布隆过滤器里面有没有这个key,如果不存在,就不用继续往下走了。
什么是缓存击穿:高并发情况下,某个key突然失效或者未被缓存,导致大量请求直接穿透到后端数据库,导致数据库负载过高,甚至发生崩溃。解决方案,加上互斥锁。
什么是缓存雪崩:主要是同一时间,系统大量缓存失效,大量的请求打入到数据库,导致数据库崩溃或者不可用。解决方案:缓存设置的过期时间不要集中在一起,尽量分散。或者服务器刚启动时进行缓存预热。
setnx和setex的区别,二者都是在最基础的set命令上所做的升级。setnx的特性就是key如果已经存在,就会放不进去,这种特性往往用来做分布式锁。setex多了一个过期时间的概念。
redis为什么这么快:因为redis操作的是纯内存,内存比磁盘快的多
redis管道有什么作用:主要是为了解决批量查询问题的,如果没有管道,我们查十个信息就要发送十次命令,往返十次交互。通过管道我们可以将十次命令一块传递给redis,结果再一次性返回,性能得到很大的提升。
redis有哪些持久化方式:主要是rdb和aof。rdb是在指定的时间间隔内生成数据集的快照,并保存在磁盘上,生成一个rdb格式的二进制文件。aof方式是记录每一个写操作到日志文件中。

集合:
常见的list实现类:arraylist:通过数组实现,线程不安全,适合对元素的快速访问。   linkedlist:通过链表实现,线程不安全,适合数据的动态插入和删除。
vetor:基于数组实现,线程安全。
arraylist:初始容量是10.当元素超过初始容量,会进行扩容,扩容到原来的1.5倍。扩容过程,新创建一个扩容后长度的数组,把原来就数组中的数据复制过来,将新元素添加到新数组的尾部。
arraylist添加元素为什么会慢:因为是基于数组实现的,数组每次添加元素都会移动其他元素来保证连续性。
arraylist如何保证线程安全:加入synchronized锁。
LinkedList 真的比 ArrayList 添加元素快吗:分情况,如果是在尾部添加多条数据的时候可能会比linkedlist快一些。
线程安全的集合有哪些:vetor,hashtable

常见的set类有哪些:hashset,linkedhashset,treeset。set是一种不包含重复元素的集合,是无序的。hashset基于哈希表实现,线程不安全,允许有null元素,但只允许有一个。   linkedhashset:基于哈希表和双向链表实现,相比于hashset是有序的。  treeset基于红黑树实现,不允许null元素的存在。
hashset的底层原理:底层是使用hashmap来存储元素的,在添加一个元素时,元素做为hashmp的键来存储的。hashmap会检查键是否存在,如果存在就会更新键值。
hashmap:主要用于存储键值对,线程不安全的,允许一个null键和多个null值。
为什么要使用扰动函数:提高哈希值的制良,在哈希表中分布的更均匀。
hashmap的主要参数有哪些:初始容量:默认为16   负载因子:默认是0.75,当存储条目数达到容量的75%就会扩容。
解决hash碰撞的方法: 链地址法。线性探测法:发生哈希冲突时向后寻找空闲位置。  双重散列法:第一个哈希函数发生碰撞,使用第二个哈希函数计算索引。
hashmap扩容:要重新计算哈希值并放入新的桶数组中。
拉链法导致的链表过深问题为什么用红黑树?:多个键值冲突时,会导致链表过深,红黑树是一种自平衡二叉树,时间复杂度低。
ConcurrentHashMap的原理:时java中一种线程安全的哈希表:加入了分段锁机制
hashtable不允许键或值为空
treemap:保证了键的自然顺序,使用红黑树来存储键值对。不允许null键,但 允许null值。线程不安全。
linkedhashmap:哈希表和链表双向。保证了键值对的顺序。通过一个双向链表记录所有插入键值对的顺序,通过记录的顺序来访问这些键值对
Enumeration和Iterator都用于遍历集合,但Iterator是更现代和灵活的选择
什么时fail-fast机制:用于检测集合在遍历时结构性的修改,并抛出异常

多线程:
● 进程:独立的资源和执行单元,适用于需要强隔离的任务。
● 线程:进程内的并发执行单元,适用于需要并发执行和共享资源的任务。
● 管程:高级同步机制,适用于复杂的共享资源同步。
● 协程:轻量级的并发执行单元,适用于高并发、频繁切换的任务。

用户线程:创建的普通线程,所有用户线程都结束时,虚拟机也会退出。 守护线程:用户线程生命周期结束,守护线程也会自动终止,常用于后台任务如垃圾回收。
线程的创建方式:继承thread类。实现runable接口。实现callable接口。使用线程池。
java多线程的优先级:数字越高优先级越高。
多线程的生命周期:创建,就绪,运行,阻塞,终止。
为什么java多线程调用的是start方法不是run方法:start方法的作用是启动一个新线程,使线程进入就绪状态。如果用run方法就会在当前线程执行不会启用新线程。
sleep和wait的区别:sleep方法使当前线程暂停一段时间,不释放锁,时间到期后自动回复执行。wait方法使当前线程等待,直到被其他线程显示唤醒或时间到期。
常用的几种线程池:定时线程池,缓存线程池,单线程池,固定大小线程池。
线程池的原理:线程创建好 之后不会销毁,而是进行复用,可以动态调整线程的多少。
好处:提高性能和相应速度,简化并发编程,提高系统稳定性。
多线程的join方法:确保一个线程在另一个线程完成之后再执行
什么是乐观锁:乐观锁是一种并发控制机制,主要用于解决并发修改问题。乐观锁假设并发冲突的概率较低,在操作之前不加锁,在操作提交时进行冲突检测。适用于读多写少的场景
终止线程的四种方式:1.自然终止,run方法执行结束自动终止。2.使用标志位终止。
什么是线程调度:jvm管理和分配cpu时间给各个线程。通常分为两种类型,抢占式调度和协作式调度。抢占式:根据优先级或者其他因素,强制中断正在运行的线程并分配给其他线程。协作式:线程主动放弃cpu使用权,操作系统不会强制中断线程。

引起cpu进行上下文切换的原因:上下文切换就是cpu从一个进程或者线程切换到另一个进程或者线程。阻塞时会进行上下文切换,时间片耗尽也会进行上下文切换,优先级变化时。
线程安全的三大特性:原子性,可见性,有序性。
介绍一下volatile:是一个java中的关键字,用于修饰变量,可以保证变量的有序性和可见性。线程修改此变量是其他线程也可见。
指令重排:允许编译器和处理器在不改变程序最终运行结果的情况下重新排列指令的执行顺序。
volatile如何防止了指令重排:主要依赖于内存屏障,限制对指令的重排序行为。
volatile保证线程的可见性和有序性,不保证原子性是为什么:原子性指的是一个操作是不可分割的,即操作要么全部执行完毕,要么完全不执行。volatile保证了对变量的单次读/写操作是原子的,但无法保证复合操作(如自增、自减)的原子性。

synchronized和lock的区别:s是java中的关键字,lock是一个接口。s的锁是隐式的,进入方法或代码块时自动获取,结束自动释放。 lock需要显示的获取,使用lock和unlock方法。
s是可重入锁吗:是的,可重入锁是指线程已经在持有锁的i情况下能重复的获取该锁而不被阻塞。
什么是自旋锁;允许线程在尝试获取锁时保持活动状态,而不是阻塞状态。
线程间的通信方式:共享变量。volatile变量

java基础知识:
jvm:虚拟机,执行字节码文件   jre:包含jvm和核心类库,提供运行java的环境。  jdk:包含jre和开发工具
重载和重写的区别:重载是在一个类中,方法名相同,参数列表不同。重写是在不同类中,方法名相同,参数列表也相同。 构造器不能被重写,但是可以被重载
String:是不可变的,一旦创建,字符串的内容就不能更改,对字符串的修改会生成一个新的字符串。是线程安全的。
Stringbuffer:是可变的,字符串的内容可以修改,也是线程安全的。  stringbulider:可以对字符串进行修改,线程不安全。
接口和抽象类的区别:一个类可以实现多个接口,一个类只能继承一个抽象类。
抽象类可以被final关键字修饰吗:不能,被finall修饰的类不饿被继承。抽象类的主要用途就是被继承。
成员变量和局部变量的区别:成员变量:定义在类中,生命周期与对象类一致,可以使用访问修饰符。 局部变量:定义在方法中,没有默认值。
静态变量和实例变量的区别:静态变量:属于类本身,所有实例共享,可以通过类名直接调用,生命周期与类一致,适用于共享数据。实例变量:属于对象实例,每个实例独有,生命走起与对象一致,通过实例访问。

final finally finalize区别:
final是一个关键字,可以加在类和方法和变量上,加载类上类不能被继承,加在方法上类不能被重写,加载变量上变量不能被修改。
finally用于处理异常,无论发没发生异常finally中的代码块都会被执行。
finalize用于垃圾回收前的清理操作
父类的静态方法能否被子类重写:不能。静态方法是与类本身相关联的,而不是与类的实例相关联。
java的跨平台性;java可以在不同的操作系统不同的硬件平台上运行。这一特性主要依赖于java的编译器和虚拟机。
java基本数据类型:byte,short,int,long,double,float,char,bool。

private,public,protected以及不写的区别?:private:仅在哦同一个类中可以访问。 public:任何地方都能访问。 protected:在同一包下或者不同包下的子类可以访问。 默认:同一包下的类
this关键字:用于引用当前对象的实例。 super关键字:用于引用父类的实例

8.22号,SSM内容:
1、Bean对象的循环依赖问题是什么,怎么解决
bean对象的循环依赖问题指的是两个或者多个bean互相依赖,形成循环引用。靠三级缓存机制来解决。其中一级缓存用于存储完全初始化好的单例bean,二级缓存用于存储早期暴露的bean实例,部分初始化的bean。三级缓存用于存储bean工厂,主要用于创建bean的代理对象。假设现在有两个对象互相依赖。在创建a的过程中发现需要属性b,查找发现b没有在一级缓存中,于是先将a放于三级缓存中,此时a不完整,但是可以被引用。接下来创建b,b创建时发现缺少a,去一级缓存中寻找a,不在的化去二级缓存里去寻找,再去三级缓存。在三级缓存中找到了a,找到a后把它放到二级缓存里去,并删除三级缓存中的啊。b顺利创建完成后把自己放入一级缓存。然后回来创建a,直接去一级缓存里拿b,这样a就完成了创建,并把a也放入到一级缓存。

2、AOP的使用场景有哪些,如果让你去模拟一个怎么进行实现
日志记录,事务管理,权限管理。首先我们需要导入依赖,然后创建一个切面类,然后配置类中启用aop

3、Spring事务回滚流程
通过注解开始事务,执行业务逻辑,异常检测,如果发生异常进行回滚,没发生异常提交事务,事务结束

4、什么情况下事务会失效
非public方法使用事务注解。 数据库引擎不支持事务。 非事务方法调用事务方法。数据库表锁定。

5、IOC和AOP理解
Spring IoC容器负责管理应用程序中对象的生命周期和依赖关系。主要职责包括对象的创建,依赖注入,对象销毁。Aop是面向切面编程

6、一二三级缓存分别存储什么信息
一级储存完全初始化好的bean  二级存储部分初始化好的bean,三级存储bean工厂。

7、详细的日志信息怎么去得到
配置日志框架slf4j

8、拦截器是怎么实现拦截的
实现interceptor接口,重写prehanle,posthandle,completion方法

9、Spring Security如何判断一个用户是否在登录的情况,并根据这个情况在用户发起请求的时候拦截响应的页面?

10、MVC执行流程
发送请求到dispatcherservlet,查找handler,调用handleradapter,执行controller,处理modelandview,渲染视图,返回客户端。

11、Controller层有哪些常用的注解,前端传给后端的数据应该通过哪些注解接收
@requestparam:用于接收url查询参数。 @pathvariable:用于接收url路径中的参数。 @requestbody:用于接收请求体里的参数 @responsebody:用于将数据转换为json格式

12、前端发送到后端的对象是如何变成一个实体类的,后端返回给前端的实体类又是如何变成JSON字符串的
@requestbody和responsebody实现
13、SSM中涉及到哪些设计模式
工厂模式,单例模式,代理模式,依赖注入模式,策略模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值