本文主要是介绍面试纪实(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
类加载机制,解决了什么问题
类加载机制,是在程序运行时,加载字节码文件到内存中使用的过程,由jvm的类加载器完成,包括加载,链接(验证,准备,解析),初始化三部分,还允许程序在运行时动态加载,实现了Java的灵活性和可扩展性,其主要功能是实现了动态加载,类的隔离,安全加载,性能优化,
衍生:类的生命周期:加载,链接,初始化,使用,销毁,
类加载器的分类:启动类加载器(加载Java核心类,如string),扩展类加载器(加载Java扩展类包lib中类),应用程序类加载器(加载应用程序classpath下的类),自定义加载器(加载自定义的类(有特殊要求的类,如加密要求,或者动态加载需要的类))
如何打破双亲委派机制
在Java中,双亲委派机制是指当一个类加载器收到类加载请求时,它会首先将这个请求委托给其父类加载器去完成,只有在父类加载器无法完成加载时,子类加载器才会尝试自行加载。这种机制有助于保证类的唯一性和安全性
自定义类加载器:可以通过自定义类加载器来实现打破双亲委派机制。在自定义类加载器中重写loadClass方法,因为子类在加载时是通过该方法实现向父类加载器申请加载的,可以在加载类时自行定义加载逻辑,不再遵循双亲委派机制。
== 和 equals的区别
==比较两个对象的引用是否指向相同的内存地址,基本类型直接比较值,引用数据类型比较地址是否相等,
equals是object类中的方法,只能用于引用类型的比较,不重写时,比较地址值,重写后,根据重写的比较逻辑比较内容。
equals会重写hashcode在哪里会用到
equals方法一般用于比较对象的值是否相等,而hashcode一般用于计算对象的hsah值,主要用在hash表有关的集合中,把对象放到集合时需要计算其hash值从而确定存放位置,如果有hash冲突的话还需要比较两个对象是否为同一个对象,是则覆盖,不是则根据处理hash冲突的方法再处理,
延时:处理hash冲突的方法,线性探测,二次探测,链地址法,
hashmap的结构
1.8以前是数组加链表,1.8之后是数组加链表或者红黑树,当链表长度大于把,并且数组容量大于六十四时会出现树化现象,
hash扩容,当元素个数大于负载因子乘以总容量时会进行扩容,
jvm中方法区保存的内容,以及线程切换时通过什么机制保存线程信息
jvm中方法区保存了类的结构信息,属性,方法,构造函数这些,包括静态常量,常量,方法字节码
线程通过上下文机制保存线程信息,包括程序计数器,寄存器状态信息这些,线程切换时,会保存上一个线程的上下文,将下一个线程的上下文信息,加载到cpu中,这一过程通过操作系统的调度器来控制和管理
程序计数器解决了什么问题
程序计数器是线程私有的,主要记录了要执行的指令的地址,解决了线程切换恢复问题,指令跳转,多线程并发执行
spring里循环依赖问题
循环依赖问题是指spring中的两个或者多个bean相互依赖导致bean实例化失败的问题,
spring中有三个缓存,用于存储单例的bean实例,三个缓存彼此互斥,不会针对同一个bean实例,同时存储,从三个缓存读取实例的顺序为,一二三,
一级缓存为单例bean,用于存储单例模式下创建的bean实例(已经创建完毕),该缓存是对外使用的,程序眼使用
二级缓存为早期单例bean(bean被提前暴露的引用,该bean还在创建中),该缓存是spring使用的,
三级缓存为单例工厂,通过对象工厂对象存储单例模式下提前暴露的bean实例的引用,该引用是spring使用
实例化Bean阶段:当Spring容器在实例化Bean时,首先会检查一级缓存(singletonObjects)中是否存在该Bean的实例。如果存在则直接返回,否则进入下一步。
创建Bean对象并提前暴露:在创建Bean对象的过程中,Spring会将当前正在创建的Bean实例放入二级缓存(earlySingletonObjects),并提前暴露一个ObjectFactory,以便其他Bean可以提前获取到该Bean的引用。
解决循环引用:如果在创建Bean对象的过程中发现循环引用,Spring会将正在创建的Bean实例包装成一个ObjectFactory,并放入三级缓存(singletonFactories)。这样,当其他Bean需要引用正在创建的Bean时,可以通过ObjectFactory获取到这个Bean的代理对象,从而避免循环引用问题。
完成Bean的创建:一旦Bean创建完成,Spring会将Bean从二级缓存中移除,并将其放入一级缓存中,以便后续的Bean可以直接获取到已经创建好的Bean实例。
三级缓存通过在Bean创建过程中提前暴露和代理对象的方式,解决了循环引用的问题。
二级缓存,三级缓存是什么
二级缓存是在spring创建bean对象时,在一级缓存中没有找到依赖的bean对象,就会将这个早期的还为创建完成的bean暴露在二级缓存中,以便其他bean在创建时获得该对象的引用,
三级缓存也是用于存放创建中bean对象实例的,没有找到依赖的对象时,会将创建的bean包装成一个对象工厂暴露在三级缓存中,以便其他bean可以通过对象工厂获取代理对象来解决循环依赖
为什么会出现循环依赖
1.设计不当导致的类之间的相互引用,2.依赖注入中的循环引用,3.多模块项目中的循环引用
乐观锁悲观锁是什么,通过什么实现的,cas怎么保证,aba问题如何解决
乐观锁和悲观锁:
乐观锁:乐观锁的思想是假设并发冲突不会发生,因此在读取数据时不会加锁,而是在更新数据时进行冲突检测。如果发现冲突,就会进行重试或者放弃操作。乐观锁适用于读操作远远多于写操作的场景,适合于并发冲突较少的情况。
悲观锁:悲观锁的思想是假设并发冲突会发生,因此在读取数据时会加锁,以防止其他线程对数据进行修改。悲观锁适用于写操作远远多于读操作的场景,适合于并发冲突较多的情况。
CAS(Compare And Swap):
CAS是一种乐观锁的实现方式,它通过比较并交换的方式来保证并发环境下的原子性操作。CAS操作包括三个参数:内存位置V、旧的预期值A、新的值B。如果当前内存位置的值等于预期值A,则将该位置的值更新为新值B,否则不做任何操作。
CAS通过硬件的原子指令来实现,保证了并发环境下的原子性操作。但是CAS也存在ABA问题,即在操作过程中可能会出现值从A变为B,再变回A的情况。
ABA问题的解决:
ABA问题指的是在CAS操作中,如果一个值从A变为B,再变回A,那么CAS操作就无法检测到这种情况,可能会导致错误的操作。为了解决ABA问题,可以使用版本号或者标记来区分不同的操作。比如在CAS操作中,除了比较值之外,还需要比较版本号或者标记,以确保操作的正确性。
联合索引下,第一个索引字段重复度低,第二个字段重复度高会对索引搜索效率有影响吗
会有一定影响,可能会导致查询变慢,外推到极限情况,第一个索引失效,导致了全表扫描,肯定是变慢的
这篇关于面试纪实(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!