每日10道Java面试题打卡—Java基础篇3

简介: 堆 是进程和线程共有的空间,每一个进程里面有多个线程,分全局堆和局部堆,全局堆就是所有没有分配的空间,局部堆就是分配给用户的空间,堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是用完了还要还给操作系统,要不然就是内存泄漏。

二十一、说说你对线程安全的理解



与其说是线程安全,不如说是内存安全,堆是共享内存,可以被所有线程访问。


堆是进程和线程共有的空间,每一个进程里面有多个线程,分全局堆和局部堆,全局堆就是所有没有分配的空间,局部堆就是分配给用户的空间,堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是用完了还要还给操作系统,要不然就是内存泄漏。


栈 是每个线程独有的,所以栈是线程安全的,每个线程的栈互相独立。


目前主流的操作系统都是多任务的,即多个进程同事运行,为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的进程的,这是由操作系统保障的。


在每个进程的内存空间中都会有一块特殊的公共区域,通常称为堆(内存),进程内的所有线程都可以访问这个区域,所以这个区域是线程不安全的。


二十二、Thread和Runable的区别



Thread和Runnable的实质是继承关系,没有可比性,无论使用Runnable还是Thread,都会new Thread,然后执行run()方法,用法上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现runnable。


二十三、说说你对守护线程的理解



守护线程:为所有非守护线程提供服务的线程,任何一个守护线程都是在整个JVM中所有非守护线程的保姆。


守护线程类似于整个进程的一个小兵,它的生死无关重要,但是它却依赖整个进行而运行,如果其他线程结束了,没有要执行的了,程序就结束了,守护线程立马就中断了。


注意:由于守护线程的终止是自身无法控制的,因此不要把IO、File等重要操作逻辑分配给它,因为它不靠谱。


二十四、ThreadLocal的原理的使用场景



每一个Thread对象均含有一个ThreadLocalMap类型的成员变量threadLocal,它存储本线程中所有ThreadLocal对象及其对应的值。


当执行set方法时,ThreadLocal首先会获取当前线程对象,然后获取当前线程的ThreadLocalMap对象,再以当前ThreadLocal对象为key,将值存储进ThreadLocalMap对象中。


get方法执行过程类似,ThreadLocal首先会获取当前线程对象,然后获取当前线程的ThreadLocalMap对象,再以当前ThreadLocal对象为key,获取对应的value。


使用场景:


1、在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束。


2、线程间数据隔离。


3、进行实物操作,用于存储线程事务信息。


4、数据库连接,Session会话管理。


二十五、ThreadLocal内存泄漏原因,如何避免



内存泄漏为程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏危害可以忽略,但内存泄漏堆积后果很严重。


不再会被使用的对象或者变量占用的内存不能被回收,就是内存泄漏。


强引用:使用最普通的引用 new,一个对象具有强引用,不会被垃圾回收器回收,当内存空间不足,java虚拟机宁愿抛出outOfMemoryError错误,使程序异常终止,也不回收这种对象。


如果想取消强引用和某个对象之间的关联,可以显式地将引用复制为null,这样可以使JVM在合适的时间就会回收该对象。


弱引用:jvm进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象,在java中,用java.lang.ref.WeakReference类来表示,可以在缓存中使用弱引用。


ThreadLocal的实现原理,每一个Thread维护了一个ThreadLocalMap,key为使用弱引用的ThreadLocal实例,value为线程变量的副本。


ThreadLocal正确的使用方法:


每次使用完ThreadLocal都调用它的remove()方法清除数据。


二十六、并发、并行、串行的区别



串行在时间上不可能发生重叠,前一个任务没搞定,下一个任务就只能等着。


并行在时间上是重叠的,两个任务在同一时刻互不干扰的同时执行。


并发允许两个任务彼此干扰,统一时间点,只有一个任务运行,交替执行。


二十七、并发的三大特性



1、原子性


原子性是指在一个操作中cpu不可以在中途暂停然后再调度,即不被中断操作,要不全部执行完成,要不都不执行,就好比转账,从账户A向账户B转1000元,那么必然包括2个操作:从账户A减去1000元,往账户B加上1000元。2个操作必须全部完成。


2、可见性


当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程可以立刻看到这个新变化的值。


3、有序性


虚拟机在进行代码编译时,对于那些改变顺序之后不会对最终结果造成影响的代码,虚拟机不一定会按照我们写的代码顺序来执行,有可能将他们重排序,实际上,对于有些代码进行重排序之后,虽然对变量的值没有造成影响,但有可能会出现线程安全问题。


二十八、为什么要用线程池?解释下线程池参数



1、降低资源消耗:提高线程利用率,降低创建和销毁线程的消耗。


2、提高响应速度:任务来了,直接有现成可用可执行,而不是先创建线程,再执行。


3、提高线程的可管理性:线程是稀缺资源,使用线程池可以统一分配调优监控。


1》 corePoolSize代表核心线程数,也就是正常情况下创建工作的线程数,这些线程创建后并不会消除,而是一种常驻线程。


2》maxinumPoolSize代表最大线程数,它与核心线程数相对应,表示最大允许被创建的线程数,比如当前任务比较多,将核心线程数都用完了,还无法满足需求时,此时就会创建新的线程,但是线程池内线程总数不会超过最大线程数。


3》keepAliveTime、unit表示超出核心线程数之外的线程的空闲存活时间,也就是核心线程不会消除,但是超过核心线程数的部分线程如果空闲一定的时间则会被消除,我们可以通过setkeepAliveTime来设置空闲时间。


4》workQueue用来存放待执行的任务,假设我们现在核心线程都已被使用,还有任务进来则全部放入队列,直到整个队列被放满但任务还在持续进入则会开始创建新的线程。


5》ThreadFactory实际上是一个线程工厂,用来生产线程执行任务。


6》Handler:任务拒绝策略,当达到最大线程数,线程池已经没有能力继续处理新提交的任务时,就执行任务拒绝策略。


二十九、简述线程池处理流程



20.png


三十、线程池中阻塞队列的作用?为什么是先添加队列而不是先创建最大线程



1、一般的队列只能保证作为一个有限长度的缓冲区,如果超出了缓冲长度,就无法保留当前的任务了,阻塞队列通过阻塞可以保留住当前想要继续入队的任务。


2、阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源。


3、阻塞队列自带阻塞和唤醒的功能,不需要额外处理,无任务执行时,线程池利用阻塞队列的take方法挂起,从而维持核心线程的存活,不至于一直占用cpu的资源。


4、在创建新线程的时候,要获取全局锁的,这个时候其它的就得阻塞,影响了整体效率,所以说线程的创建是比较消耗资源的。



相关文章
|
22天前
|
消息中间件 缓存 算法
Java多线程面试题总结(上)
进程和线程是操作系统管理程序执行的基本单位,二者有明显区别: 1. **定义与基本单位**:进程是资源分配的基本单位,拥有独立的内存空间;线程是调度和执行的基本单位,共享所属进程的资源。 2. **独立性与资源共享**:进程间相互独立,通信需显式机制;线程共享进程资源,通信更直接快捷。 3. **管理与调度**:进程管理复杂,线程管理更灵活。 4. **并发与并行**:进程并发执行,提高资源利用率;线程不仅并发还能并行执行,提升执行效率。 5. **健壮性**:进程更健壮,一个进程崩溃不影响其他进程;线程崩溃可能导致整个进程崩溃。
28 2
|
22天前
|
存储 Java
Java面向对象面试题总结(上)
在Java中,重写(Override)与重载(Overload)是两个重要的概念,关联到方法的定义与调用。重写是指子类对继承自父类的方法进行新的实现,以便提供子类特有的行为,其关键在于方法签名一致但方法体不同。重载则允许在同一个类中定义多个同名方法,只要参数列表不同即可,以此提供方法调用的灵活性。重写关注多态性,而重载强调编译时多态。
18 1
|
22天前
|
NoSQL Java 数据库
2022年整理最详细的java面试题、掌握这一套八股文、面试基础不成问题[吐血整理、纯手撸]
这篇文章是一份详尽的Java面试题总结,涵盖了从面向对象基础到分布式系统设计的多个知识点,适合用来准备Java技术面试。
2022年整理最详细的java面试题、掌握这一套八股文、面试基础不成问题[吐血整理、纯手撸]
|
11天前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
50 0
|
13天前
|
存储 安全 Java
java基础Java的Deque之Deque、BlockingDeque、LinkedBlockingDeque、ArrayDeque
在实际编程中,合理利用Java的Deque和它的具体实现,可以在不同的应用场景中发挥高效和线程安全的队列管理功能。通过了解和比较Deque的不同实现,可以根据应用需求做出适当的技术选型,以支持高效且健壮的应用架构。
8 0
|
19天前
|
Java 编译器 开发工具
JDK vs JRE:面试大揭秘,一文让你彻底解锁Java开发和运行的秘密!
【8月更文挑战第24天】JDK(Java Development Kit)与JRE(Java Runtime Environment)是Java环境中两个核心概念。JDK作为开发工具包,不仅包含JRE,还提供编译器等开发工具,支持Java程序的开发与编译;而JRE仅包含运行Java程序所需的组件如JVM和核心类库。一个简单的"Hello, World!"示例展示了两者用途:需借助JDK编译程序,再利用JRE或JDK中的运行环境执行。因此,开发者应基于实际需求选择安装JDK或JRE。
37 0
|
22天前
|
存储 缓存 安全
Java多线程面试题总结(中)
Java内存模型(JMM)定义了程序中所有变量的访问规则与范围,确保多线程环境下的数据一致性。JMM包含主内存与工作内存的概念,通过8种操作管理两者间的交互,确保原子性、可见性和有序性。`synchronized`和`volatile`关键字提供同步机制,前者确保互斥访问,后者保证变量更新的可见性。多线程操作涉及不同状态,如新建(NEW)、可运行(RUNNABLE)等,并可通过中断、等待和通知等机制协调线程活动。`volatile`虽不确保线程安全,但能确保变量更新对所有线程可见。
15 0
|
22天前
|
缓存 安全 Java
Java基础面试题总结(上)
Java有8种基本数据类型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)、float(4字节)、double(8字节)、boolean、char(2字节)。String类被`final`修饰,不可被继承。String为只读,内容不可改;StringBuffer和StringBuilder可修改内容,前者线程安全,后者非线程安全,故效率更高。
13 0
|
22天前
|
算法 Java
【多线程面试题十八】、说一说Java中乐观锁和悲观锁的区别
这篇文章讨论了Java中的乐观锁和悲观锁的区别,其中悲观锁假设最坏情况并在访问数据时上锁,如通过`synchronized`或`Lock`接口实现;而乐观锁则在更新数据时检查是否被其他线程修改,适用于多读场景,并常通过CAS操作实现,如Java并发包`java.util.concurrent`中的类。
|
22天前
|
存储 Java 调度
【多线程面试题 八】、说一说Java同步机制中的wait和notify
Java同步机制中的wait()、notify()、notifyAll()是Object类的方法,用于线程间的通信,其中wait()使当前线程释放锁并进入阻塞状态,notify()唤醒单个等待线程,notifyAll()唤醒所有等待线程。