线程安全

Java最新面试题

99封情书 提交于 2020-01-14 19:17:37
2019最新整理JAVA面试题附答案 作者:Jack 包含的模块: 本文分为十九个模块,分别是:Java 基础、容器、多线程、反射、对象拷贝、Java Web 、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM 如下图所示: 共包含 208 道面试题,本文的宗旨是为读者朋友们整理一份详实而又权威的面试清单 ==================================================== 一. Java 基础模块 1.JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。 具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。 2.== 和 equals 的区别是什么

JAVA面试题 请谈谈你对Sychronized关键字的理解?

别说谁变了你拦得住时间么 提交于 2020-01-14 12:05:46
面试官:sychronized关键字有哪些特性? 应聘者: 可以用来修饰方法; 可以用来修饰代码块; 可以用来修饰静态方法; 可以保证线程安全; 支持锁的重入; sychronized使用不当导致死锁; 了解sychronized之前,我们先来看一下几个常见的概念:内置锁、互斥锁、对象锁和类锁。 内置锁 在Java中每一个对象都可以作为同步的锁,那么这些锁就被称为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。 互斥锁 内置锁同时也是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,直到线程B抛出异常或者正常执行完毕释放这个锁;如果B线程不释放这个锁,那么A线程将永远等待下去。 对象锁和类锁 对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的。 对象锁是用于对象实例方法; 类锁是用于类的静态方法或者一个类的class对象上的 一个对象无论有多少个同步方法区,它们共用一把锁,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。

线程认识

落爺英雄遲暮 提交于 2020-01-14 08:37:30
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

线程认识

我的未来我决定 提交于 2020-01-14 08:37:20
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

C#中的线程同步

天大地大妈咪最大 提交于 2020-01-14 02:25:42
同步的本质: 下面的列表总结了.NET同步线程的工具: 阻塞函数: Sleep:阻塞线程一定时间。 Join:阻塞另一个线程至本线程完成。 加锁结构: lock:保证只有一个线程可以存取同一个资源,或操作一段代码。不能跨进程。速度快。 Mutex:保证只有一个线程可以存取同一个资源,或操作一段代码。可以用来阻止一个程序启动多个线程。可以跨进程,速度一般。 Semaphore:保证不超过某个数量的线程可以存取同一个资源,或操作一段代码。可以跨进程,速度一般。 信号结构: EventWaitHandle:允许一个线程等待,直到收到另一个线程的信号为止。可以跨进程,速度一般。 Wait 和 Pulse:允许一个线程等待,直到遇到一个自定义阻塞情况。不能跨进程。速度一般。 非阻塞的同步结构: Interlocked:执行简单的非阻塞原子操作。可以跨进程,速度非常快。 volatile:为了允许安全的非阻塞操作在锁外部存取单独的字段。可以跨进程,速度非常快。 阻塞: 当用上面提到的方式让线程暂停时,叫做让线程阻塞。一旦线程阻塞了,一个线程立即让出自己从CPU分配的时间,将WaitSleepJoin加入ThreadState属性,直到不再阻塞为止。阻塞的解除可能是以下4种方式之一(不算按电源键): 满足了阻塞条件 超时 被Thread.Interrupt打断 被Thread.Abort终止

LIst的使用

牧云@^-^@ 提交于 2020-01-14 01:43:04
List接口总结: List接口是Collection接口的子接口,从其名称可以看出,是一个元素有序(并不是按大小排序,具有顺序索引,类似于数组),默认按照元素的添加顺序设置元素的索引,List和Set不同在于List可以具有重复元素,List增加了按照索引插入(add(int index,Object element)方法),替换(set(int index,Object element)方法)和删除集合元素(remove(int index)方法)。List判断元素相同的标准:两个对象equals()方法比较返回true; 常见方法:其中E代表范型。 boolean add(E e) 向列表的尾部添加指定的元素 void add(int index, E element) 在列表的指定位置插入指定元素 void clear() 从列表中移除所有元素 E get(int index) 返回列表中指定位置的元素 boolean contains(Object o) 如果列表包含指定的元素,则返回 true E set(int index, E element)用指定元素替换列表中指定位置的元素 int size()返回列表中的元素数。 E remove(int index) 移除列表中指定位置的元素 boolean isEmpty() 如果列表不包含元素 ListIterator

java面试题整理2020.1.13

拟墨画扇 提交于 2020-01-13 21:39:52
序列化和反序列化 序列化:把对象的状态转换为字节码的过程叫序列化。 transient修饰的属性,不会被序列化。 静态static的属性不会被序列化。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化。 什么方式进行序列化 实现了Serializable接口。 Hessian 序列化 Json序列化 序列化中需要注意的几个点 transient可以修饰属性,防止属性被序列化 static属性也不会被序列化。 子类能够继承父类的序列化功能 引用类型的属性会随着对象序列化而序列化 即序列化一个对象a时,对象a的引用属性b不用实现序列化接口也能随着对象a的序列化而序列化;实际不然,对象b的类也需要实现序列化接口才能随着对象a的序列化而序列化。 序列化的作用 持久化存储时。 网络传输时。 通过RMI传输对象时。 wait和sleep的区别 这两个方法来自不同的类,分别是sleep来自thread类,wait来自object类 最主要的是sleep方法没有释放锁,而wait方法释放了锁,是的其他线程可以同步控制块和方法 使用范围:wait,notify,notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。 sleep必须捕获异常,而wait,notfy,notifyAll不需要捕获异常 数组的初始化方式 动态初始化

Java多线程面试问题和答案

北战南征 提交于 2020-01-13 16:38:46
1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。Java在语言层面对多线程提供了卓越的支 持,它也是一个很好的卖点。 2) 线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。 3) 如何在Java中实现线程? 在语言层面有两种方式。java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行,由于线程类本身就是调用的Runnable接口所以你可以继承 java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。 4) 用Runnable还是Thread? 这个问题是上题的后续,大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使 用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类

java中数组以及集合

强颜欢笑 提交于 2020-01-13 13:38:03
java中数组: 数组在Java里是一种特殊类型,有别于普通的“类的实例”的对象。但实际数组也是一种对象类型,int[]a = new int[5] a是在java栈中分配的引用变量,类型是int[] 数组类型,指向在堆里面地址连续的实际数组对象。 在内存中,数组存储在连续的区域内部,因为数组中每个元素的类型相同,则占用的内存大小也一致,所以在访问数组中的元素时可以直接根据数组在内存中的起始位置以及下标来计算元素的位置,因此数组的访问速度很高。数组必须要初始化才能使用,初始化之后JVM会自动分配默认值,引用变量默认值是null。 数组和集合的区别: 1》数组初始化之后大小固定,无法再改变,集合大小可以改变。 2》同一个数组只能存储同一种数据类型(基本类型/引用类型).集合不考虑泛型可以存储多种数据类型,集合是存储对象的,所以基本类型不能放入集合,可以使用基本类型的包装类型。 3》若程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,则需要使用容器类库,array不适用。 数组和集合之间进行转化: toArray():将集合转化为数组。 Arrays.asList():将数组转化为集合. 集合的体系结构 List、Set、Map是这个集合体系中最主要的三个接口。 List和Set继承自Collection接口。 Map也属于集合系统,但和Collection接口不同。