文章目录
- 一、java基础
- 1、Hashcode的作用
- 2、String、String StringBuffer 和 StringBuilder 的区别是什么?
- 3、 Java的四种引用,强弱软虚
- 4、3*0.1 == 0.3返回值是什么
- 5、final修饰引用数据类型
- 二、jvm
- 1、内存模型
- 2、如何判断对象可以被回收
- 3、Minor GC与Full GC分别在什么时候发生?
- 4、
- 三、并发
- 1、什么是多线程中的上下文切换?
- 2、
- 四、Spring框架
- 1、spring的优点
一、java基础
1、Hashcode的作用
hashCode用于获取对象的哈希码。在Object类中,hashCode()方法被定义为返回一个int类型的哈希码值。
java的集合有两类,一类是List,还有一类是Set。前者有序可重复,后者无序不重复。当我们在set
中插入的时候怎么判断是否已经存在该元素呢,可以通过equals方法。但是如果元素太多,用这样
的方法就会比较满。
于是有人发明了哈希算法来提高集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每
个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的
哈希码就可以确定该对象应该存储的那个区域。
hashCode方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理
位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如
果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相
同就散列其它的地址。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
2、String、String StringBuffer 和 StringBuilder 的区别是什么?
String是一个final类型的字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的String对象。
每次+操作 : 隐式在堆上new了一个跟原字符串相同的StringBuilder对象,再调用append方法 拼
接+后面的字符。
StringBuffer和StringBuilder底层都是可变的字符数组, 另外StringBuffer 对append方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
3、 Java的四种引用,强弱软虚
强引用
强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,
String str = new String("str");
软引用
软引用在程序内存不足时,会被回收
可用场景: 创建缓存的时候,创建的对象放进缓存中,当内存不足时,JVM就会回收早先创建
的对象。
SoftReference<String> wrf = new SoftReference<String>(new String("str"));
弱引用
弱引用就是只要JVM垃圾回收器发现了它,就会将之回收,
可用场景:ThreadLocalMap 中的 key 就是使用弱引用,我的理解就是,
一旦我不需要某个引用,JVM会自动帮我处理它,这样我就不需要做其它操作。
> WeakReference<String> wrf = new WeakReference<String>(str);
虚引用
**虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。**注意
哦,其它引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多
被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferenceQueue ,
PhantomReference<String> prf = new PhantomReference<String>(new String("str"),
new ReferenceQueue<>());
可用场景: 对象销毁前的一些操作,比如说资源释放等。 Object.finalize() 虽然也可以做这
类动作,但是这个方式即不安全又低效
上诉所说的几类引用,都是指对象本身的引用,而不是指Reference的四个子类的引用
(SoftReference等)
4、3*0.1 == 0.3返回值是什么
false ,因为有些浮点数不能完全精确的表示出来 0.1(十进制)在二进制中是一个无限循环的小数。
在Java中,使用浮点数进行计算时,可能会出现精度误差导致不精确的结果。这是因为在计算机内部,浮点数是以二进制表示的,并且某些十进制数无法准确地转换为有限长度的二进制表示形式。
为了解决这个问题,可以考虑使用BigDecimal类进行精确的十进制数计算。BigDecimal类提供了高精度的数字操作,可以避免浮点数计算产生的精度误差。
5、final修饰引用数据类型
引用数据类型有数组、类、接口,以数组为例。
使用final修饰引用数据类型,值不能修改,这个值指的是引用数据类型中保存的地址值,地址指向的内容是可以修改的。
二、jvm
1、内存模型
jvm内存模型:
栈、本地方法栈、堆、程序计数器、方法区。
线程独占: 虚拟机栈、本地方法栈、程序计数器
每个线程都会有它独立的空间,随线程生命周期而创建和销毁
线程共享: 方法区、堆内存
所有线程能访问这块内存数据,随虚拟机或者GC而创建和销毁
1.栈:(JVM Stack)又称方法栈
JVM中的虚拟机栈是描述Java方法执行的内存区域,每个方法从开始调用到执行完成的过程,就是栈帧从入栈到出栈的过程。
栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛stackOverflflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemoryError。
2.本地方法栈 (Native Method Stack)
与栈类似 , 也是用来保存执行方法的信息 . 执行 Java 方法是使用栈 , 执行 Native 方法时使用本地方法栈 .
3.程序计数器 (Program Counter Register )
当同时进行的线程数超过CPU 数或其内核数时,就要通过时间片轮询分派 CPU 的时间资源,不免发生线 程切换。这时,每个线程就需要一个属于自己的计数器来记录下一条要运行的指令。
保存着当前线程执行的字节码位置, 每个线程工作时都有独立的计数器 , 只为执行 Java 方法服务 , 执行Native方法时 , 程序计数器为空 .
作用:
1、 字节码解释器通过改变程序计数器依次读取指令,实现代码的流程控制,如:顺序执行、选择、循环、异常处理
2、多线程情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪了
4.堆 (Java Heap)
JVM内存管理最大的一块 , 对被线程共享 , 目的是存放对象的实例。
JVM内存管理最大的一块 , 被线程共享, 存放对象实例和数组,是垃圾回收的主要区域,根据对象的存活周期不同 ,JVM 把对象进行分代管理,分为新生代和老年代。刚创建的对象在新生代的Eden区中,经过GC后进入新生代的S0 区中,再经过 GC 进入新生代的 S1 区中, 15 次 GC 后仍存在就进入老年代。这是按照一种回收机制进行划分的,不是固定的。若堆的空间不够实例分配,则OutOfMemoryError。
注意:在Java 8及以后的版本中,已经移除了永久代(PermGen)并引入了元空间(Metaspace)。
5.方法区(1.8之后移入到了元空间):
又称非堆区, 线程共享的,用于存放被虚拟机加载的类的元数据信息,(类的元数据(Metadata)是指在Java虚拟机(JVM)中描述类的结构和属性的信息。它包括了类的名称、访问修饰符、父类、接口实现、字段、方法等相关信息。)如常量、静态变量和即时编译器编译后的代码。若要分代,算是永久代(老年代)
1.7 的永久代和1.8 的元空间都是方法区的一种实现
方法区中的信息一般需要长期存在,而且它又是堆的逻辑分区,因此用堆的划分方法,我们把方法区称为永久代.
2、如何判断对象可以被回收
判断对象是否存活一般有两种方式:
引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计
数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引
用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对
象。
3、Minor GC与Full GC分别在什么时候发生?
新生代内存不够用时候发生(Minor GC)MGC也叫YGC,JVM内存不够的时候发生FGC(Full GC)
4、
三、并发
1、什么是多线程中的上下文切换?
**在上下文切换过程中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后
继续运行。**从这个角度来看,上下文切换有点像我们同时阅读几本书,在来回切换书本的同时我们
需要记住每本书当前读到的页码。
在程序中,上下文切换过程中的“页码”信息是保存在进程控制块(PCB)中的。PCB还经常被称
作“切换桢”(switchframe)。“页码”信息会一直保存到CPU的内存中,直到他们被再次使用。
上下文切换是存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。上下文切换是
多任务操作系统和多线程环境的基本特征。
2、
四、Spring框架
1、spring的优点
1、轻量级、简化开发、解耦、集成其他框架
2、aop:可以将与核心业务逻辑无关的功能(如日志记录、性能监控等)从业务逻辑中剥离出来,实现横切关注点的复用和集中管理。
3、ioc:将对象的创建、管理交由ioc容器去做。
DI:称为依赖注入(Dependency Injection),是一种实现控制反转(IOC)的机制。
4、统一的事务管理:Spring提供了强大的事务管理机制,可以在不同的数据访问技术(如JDBC、Hibernate、JPA等)上实现统一的事务控制。这样可以确保数据的一致性和完整性,简化了事务管理的复杂性。