版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目录TOC\o"1-3"\h\u21038一、Java设计模式 6528(一)创建型设计模式 6131621. 613584二、Spring相关 69454(一)Spring核心组件 653911.为何使用spring 6273742.核心组件种类及原理 616003.servlet、filter、listener、interceptor区别 628267(二)SpringBean 853011.如何创建bean并构建其关系网 876532.bean的生命周期 912433.如何解决循环依赖问题?属性注入和构造器注入哪种会有循环依赖的问题? 1193024.BeanFactory和ApplicationContext有什么区别? 11299495.Spring框架中bean的作用域?单例bean是线程安全的么? 12125946.Spring如何注入一个javacollection?如何注入一个Jperties? 13327157.请解释springbean的自动装配?请解释自动装配模式的区别? 1485168.请解释@Autowired注解? 1441569.构造方法注入和设值注入的区别? 15604910.Spring框架中有哪些不同类型事件? 152284011.FileSystemResource和ClassPathResource有何区别? 162023512.Spring框架中都用到了哪些设计模式? 1614328(三)Spring事物传播机制 1628528(四)SpringAOP相关 17158681.AOP实现原理是什么? 17205912.应用场景有哪些? 1818430(五)SpringIOC(依赖倒置)相关 1864141.IOC如何工作的? 1829016(六)动态代理相关 19281581.JDK的动态代理和cglib的动态代理各实现原理 1928591三、线程/并发编程相关 2011042(一)线程池 202291.Thread基础知识 20190002.Java中的线程池是如何实现的?创建线程池的几个核心构造参数? 2096273.Executors框架的四种线程池及拒绝策略? 21265754.Jdk拒绝策略 22299015.线程池中的线程是怎么创建的?是一开始就随着线程池的启动创建好的吗? 2284356.既然提到可以通过配置不同参数创建出不同的线程池,那么Java中默认实现好的线程池又有哪些呢?请比较它们的异同? 22310577.什么是Java的内存模型,Java中各个线程是怎么彼此看到对方的变量的? 2359428.请谈谈volatile关键字有什么特点,为什么它能保证变量对所有线程的可见性?是不是就意味着基于volatile变量的运算就是并发安全的? 24205389.请对比下volatile对比Synchronized的异同? 24563010.请对比下ThreadLocal对比Synchronized的异同? 251419611.如何在Java线程池中提交线程? 252745312.ThreadLocal原理? 253022313.ThreadLocal是怎么解决并发安全的? 262227714.很多人都说要慎用ThreadLocal,谈谈你的理解,使用ThreadLocal需要注意些什么? 27513815.HA主备怎么预防脑裂? 2720623(二)Synchronized 27178791.Synchronized其原理是什么? 2753002.什么是可重入性,为什么说Synchronized是可重入锁? 27202743.跟Synchronized相比,可重入锁ReentrantLock其实现原理有什么不同? 28207094.请谈谈ReentrantReadWriteLock和StampedLock? 2812745.那么请谈谈AQS框架是怎么回事儿? 2859196.JVM对Java的原生锁做了哪些优化? 2919647.为什么说Synchronized是一个悲观锁?乐观锁的实现原理又是什么?什么是CAS,它有什么特性? 30272678.如何让Java的线程彼此同步?你了解过哪些同步器?请分别介绍下? 3026679四、集合相关 3029026(一)集合在哪几个包下 3012350(二)Map接口 312611.Map接口的实现有哪些,区别是什么? 31208142.为什map没有实现collection接口 3162763.为什么collection没有实现clonable和Serializable接口? 31232594.Collection和Collections的区别? 31192915.Comparable和Comparator接口是干什么的?列出它们的区别 ? 315373(三)红黑树的概念 3224994(四)HashMap 32200381.HashMap数据结构?工作原理及其特点 32253632.HashMaphash冲突如何解决(链表和红黑树),为什么hashmap中的链表需要转成红黑树? 33238543.HashMaphash什么时候扩容?扩容时每个entry需要再计算一次hash吗?扩容时避免rehash的优化 34110814.Hashmap的数组长度为什么要保证是2的幂? 3466245.HashMap和Hashtable的区别? 3522742(五)LinkedHashMap 35315991.LinkedHashMap了解基本原理、哪两种有序、如何用它实现LRU? 3513859(六)TreeMap 3671031.TreeMap的据结构 3629238(七)Set(继承Collection) 36162901.HashSet的底层实现是什么? 36288862.HashSet和TreeSet有什么区别? 36115193.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别? 3729863(八)List(继承Collection) 3799741.List的实现有哪些?区别是什么? 37151452.数组(Array)和列表(ArrayList)有什么区别?什么时候应该使用Array而不是ArrayList? 37267173.什么是迭代器(Iterator)?Iterator和ListIterator的区别是什么? 388650五、虚拟机相关 3830486(一)堆和栈 38257051.heap和stack有什么区别 3816129虚拟机栈 39186742.JVM内存模型 3965603.Jvm编译和执行的过程 39268914.什么是类加载器?Java类加载过程?描述一下JVM加载Class文件的原理机制? 40203805.类加载器双亲委派模型机制? 4145776.内存管理 42194167.垃圾回收 43132028.JVM的永久代中会发生垃圾回收么? 44132359.Java8移除永久代原因? 442581010.OutOfMemory解决方案 443036611.虚拟机栈什么情况下会stackoverflowEorror 442577912.如何判断一个对象是否存活?(或者GC对象的判定方法) 451413913.finalize()方法什么时候被调用?析构函数(finalization)的目的是什么? 45505314.如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存? 451705315.什么是分布式垃圾回收(DGC)?它是如何工作的? 452629516.串行(serial)收集器和吞吐量(throughput)收集器的区别是什么? 4611877六、网络相关 4610454(一)Tcp/IP 46155581.TCP/IP原理?TCP三次握手/四次握手? 46205142.Http原理? 48239953.Httppost/get区别? 48323424.CDN原理? 487933七、NoSql及缓存相关 4922930(一)Redis缓存 49103481.Redis原理及应用场景?支持的数据类型? 498952.Redis持久化的方式 5043693.Redis的哈希设计原理?哈希的Rehash是怎么处理的? 50273694.说说Redis哈希槽的概念? 51309485.为什么每个字典中包含两个hashtable? 51212106.与HashMap的扩容对比? 51301947.redis性能为什么高? 529428.单线程的redis如何利用多核cpu机器/如何处理那么多的并发客户端连接? 5260489.redis的缓存淘汰策略? 523219610.redis集群有哪几种形式?数据分片模型? 53643011.有海量key和value都比较小的数据,在redis中如何存储才更省内存? 5468912.如何保证redis和DB中的数据一致性? 542566513.如何解决缓存穿透和缓存雪崩? 551258414.Redis锁?如何用redis实现分布式锁? 552057315.Redis回收策略? 56433416.Redis常见性能问题和解决方案? 56943917.MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据? 57603018.假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来? 572603019.使用过Redis做异步队列么,你是怎么用的? 571323620.Redis主从复制? 572447921.Redis的高可用部署方式? 58725322.Redis可以在线扩容吗?zk呢? 5823937(二)Memcached缓存 58189511.Memcached原理及应用场景? 58293202.如何实现分布式? 59297563.Memcache的惰性失效机制? 59279424.memcache缓存的无底洞现象? 60310425.Memcache服务集群实现? 60239546.一致性hash算法的实现原理? 6038807.Memcached/redis区别及优缺点? 6013702(三)Ehcache\caffeine\jetcache缓存 61197131.cache种类 61294402.Ehcache缓存 61223053.Jetcache缓存 6256494.Caffeine缓存 623645八、Dubbo相关 6325072(一)Dubbo功能 63247331.了解一个常用的RPC框架 63112552.为什么要用dubbo? 6355613.Dubbo的整体架构设计有哪些分层? 63202734.Dubbo如何做负载均衡? 63286735.服务调用时阻塞的吗? 63208916.默认使用什么序列化框架?你知道的还有哪些? 6375817.Dubbo如何做限流降级? 63287568.Dubbo如何优雅的下线服务? 63308219.服务提供者能实现失效踢出是什么原理? 641286910.如何解决服务调用链过长的问题? 642211311.Dubbo如何实现异步调用的? 642381412.Dubbo如何实现失败重试的? 643061513.Dubbo集群容错有几种方案? 641794214.同一个服务多个注册的情况下可以直连某一个服务吗? 641713315.Dubbo使用过程中都遇到什么问题? 64271716.DubboMonitor实现原理? 6421347九、RocketMq/Kafka相关 6519010(一)RocketMq功能 6581911.RocketMq如何保证高可用的? 6597122.RocketMq如何保证高吞吐的? 6571863.RocketMq的消息是有序的吗? 6524254.RocketMq的消息局部顺序是如何保证的? 65232445.RocketMq事务消息的实现机制? 65162366.RocketMq会有重复消费的问题吗?如何解决? 65225777.RocketMq支持什么级别的延迟消息?如何实现的? 6522148.RocketMq是推模型还是拉模型? 65232749.Consumer的负载均衡是怎么样的? 6532100(二)Kafka功能 66157641.Kafka数据存储设计? 66276122.生产者设计? 6690693.消费者设计? 6618601十、zookeeper相关 6731642(一)原理 67101251.Zk大致原理(可以了解下原理相近的Raft算法)? 6739212.如何用zk实现分布式锁,与redis分布式锁有和优缺点? 67100753.哪四种类型znode? 67314094.Zk通知机制? 67209905.ZK是如何保证事物的顺序一致性的? 68115446.Zk节点宕机如何处理? 68148467.ZK负载均衡和nginx负载均衡区别? 68135978.ZKwatch机制? 68104879.Zk是如何选取主leader的? 6832179十一、MySql相关 683792(一)存储引擎 6833181.InnoDB和MyISAM存储引擎的区别? 688127(二)Mysql索引 6968221.索引、聚簇索引和非聚簇索引、Btree/hash区别 69162182.说说什么是最左匹配? 69172643.如何优化慢查询? 692376(三)数据库事物 6918961.事物隔离级别有哪些?不同事务隔离级别分别会加哪些锁? 6931422.什么是MVCC 70300483.锁机制?mysql的行锁、表锁、间隙锁、意向锁分别是做什么的? 71129664.分布式事务模型之XA和TCC的区别和联系? 7112808(四)分库分表相关 72275041.分库分表如何选择分表键? 72166352.分库分表的情况下,查询时一般是如何做排序的? 724533.数据库主从复制? 72Spring相关Spring核心组件为何使用spring轻量、控制反转IOC、面向切面AOP、容器(包含并管理应用对象的配置和生命周期)、MVC。核心组件种类及原理Spring的核心组件有Context、Core、Bean,其中Bean是spring的核心中的核心,如IOC,没有Bean也就无从IOC了。核心组件详解把bean比作演员的话,Context就好比如舞台,Core犹如道具。Bean:对Bean的解析实际上就是对spring配置文件进行解析,当spring成功解析你定义的一个<bean/>节点后,在spring的内部它就被转化成BeanDefinition对象,以后所有的操作都是对这个对象进行的。Context:发现每个Bean之间的关系,为它们建立这种关系并维护好这种关系,所以Context就是一个个Bean的关系集合,这个关系集合又叫Ioc容器。Core:发现、建立和维护每个Bean之间关系所需要的一系列工具,可以比作成Util(如序列化、注解、解析xml所需工具)。servlet、filter、listener、interceptor区别1、servletservlet是一种运行服务器端的java应用程序,Servlet的主要功能 在于交互式地浏览和修改数据,生成动态Web内容。这个过程为:1)客户端发送请求至服务器端;2)服务器将请求信息发送至Servlet;3)Servlet生成响应内容并将其传给服务器。响应内容动态生成,通常取 决于客户端的请求;4)服务器将响应返回给客户端。在Web应用程序中,一个Servlet在一个时刻可能被多个用户同时访问。这时Web容器将为每个用户创建一个线程来执行Servlet。如果Servlet不涉及共享资源的问题,不必关心多线程问题。但如果Servlet需要共享资源,需要保证Servlet是线程安全的。2、filterFilter不像Servlet,它不能产生一个请求或者响应,它只是修改对 某一资源的请求,或者修改从某一的响应。Servlet中的过滤器Filter是实 现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符 编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置 好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响 应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断, 如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应 用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web 应用停止或重新部署的时候才销毁。Filter有如下几个用处:在HttpServletRequest到达Servlet之前,拦截客户的 HttpServletRequest。根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和 数据。在HttpServletResponse到达客户端之前,拦截HttpServletResponse。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头 和数据。3、listenerservlet,filter都是针对url之类的,而listener是针对对象的操 作的,如session的创建,session.setAttribute的发生,在这样的事件发 生时做一些事情。4、interceptor是在面向切面编程的,就是在你的service或者一个方法,前调用一 个方法,或者在方法后调用一个方法,是基于JAVA的反射机制。比如动态 代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业 务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常 的时候做业务逻辑的操作。filter配置在web.xml中,任何url都会拦截,至于怎么处理由开发者 决定,一般用于验证是否登录,interceptor配置在action中,只会对一个或 者某几个action起作用,不会对url起作用,一般用于功能方面的验证,是否 有某些权限的验证等servlet、filter、listener是配置到web.xml中(web.xml的加载顺序是:context-param->listener->servlet->filter),interceptor不配置到web.xml中,struts的拦截器配置到struts.xml中。spring的拦截器配置到spring.xml中。SpringBean先理解两个概念:实例化实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean 放入单例池中。初始化初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性。如何创建bean并构建其关系网bean的实例化是在BeanFactory中发生的首先ApplicationContext继承ResourceLoader获取所有资源文件,然后创建beanFactory,创建bean的流程如下:注:、FactoryBean:它是一个非常重要的bean,如果一个类继承该类,则用户可以自定义产生实例的方法,只需实现它的getObject()方法即可bean的生命周期SpringBean的生命周期分为四个阶段和多个扩展点。扩展点又可以分为影响多个Bean和影响单个Bean。整理如下:
四个阶段实例化Instantiation属性赋值Populate初始化Initialization销毁Destruction多个扩展点影响多个BeanBeanPostProcessor(解析bean的注解、将注解中的字段转化为属性、打印日志、记录时间、缓存技术等)影响单个BeanAwareAwareGroup1BeanNameAwareBeanClassLoaderAwareBeanFactoryAwareAwareGroup2EnvironmentAwareEmbeddedValueResolverAwareApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)生命周期InitializingBeanDisposableBean先区别一下SpringBean的实例化和初始化两个阶段的主要作用:实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中(父类的类构造器<clinit>()->子类的类构造器<clinit>()->父类的成员变量和实例代码块->父类的构造函数->子类的成员变量和实例代码块->子类的构造函数)。初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性。1、实例化一个Bean2、按照Spring上下文对实例化的Bean进行配置,也就是IOC注入3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,传递的参数就是Spring配置文件中Bean的id值4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(BeanFactory),传递的是Spring工厂自身5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Objectobj,Strings)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Objectobj,Strings)方法9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。如何解决循环依赖问题?属性注入和构造器注入哪种会有循环依赖的问题?答:构造器注入会有循环依赖问题产生原因:A是单例(构造器注入属性),B是原型然后循环依赖?答案是不可以注入:A创建的时候,不会暴露出来,B就更不会暴露出来了,所以抛异常(2)A是单例(构造器注入),B是单例(setter方法注入)然后循环依赖呢?答案是看实例化的顺序:如果A先实例化:A构造器注入,构造的时候就找B,B没有实例化,然后实例化B,无参构造方法实例化B,然后将B暴露出来,接着注入A,此时就发现A已经在实例化了,又实例化,所以报错 如果B先实例化:B先构造然后暴露出来,接着A创建,依赖B,这时候 能成功的构造出来A(因为B已经暴露出来了),接着Asetter注入A--完成 注入解决办法:初始化bean的时候(注意此时的bean必须是单例,否则不能提前暴露一个创建中的bean)使用set方法进行注入属性,此时bean对象会先执行构造器实例化,接着将实例化后的bean放入一个map中,并提供引用。当需要通过set方式设置bean的属性的时候,spring容器就会从map中取出被实例化的bean。比如A对象需要set注入B对象,那么从Map中取出B对象即可。以此类推,不会出现循环依赖的异常。BeanFactory和ApplicationContext有什么区别?BeanFactory:是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;BeanFactory在启动的时候不会去实例化Bean,只有从容器中拿Bean的时候才会去实例化。ApplicationContext:应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能;1)国际化(MessageSource)2)访问资源,如URL和文件(ResourceLoader)3)载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的web层4)消息发送、响应机制(ApplicationEventPublisher)5)AOP(拦截器)ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化。其他:Spring框架中bean的作用域?单例bean是线程安全的么?作用域:Spring的bean作用域(scope)类型1、singleton:单例,默认作用域。2、prototype:原型,每次创建一个新对象。3、request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。4、session:会话,同一个会话共享一个实例,不同会话使用不用的实例。5、global-session:全局会话,所有会话共享一个实例。Bean线程安全问题:原型Bean:对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。单例Bean:对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。如果单例Bean,是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Springmvc的Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。有状态对象(StatefulBean):就是有实例变量的对象,可以保存数据,是非线程安全的。每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。无状态对象(StatelessBean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean的生命期也不一定结束,它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。对于有状态的bean,Spring官方提供的bean,一般提供了通过ThreadLocal去解决线程安全的方法,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。使用ThreadLocal的好处:使得多线程场景下,多个线程对这个单例Bean的成员变量并不存在资源的竞争,因为ThreadLocal为每个线程保存线程私有的数据。这是一种以空间换时间的方式。Spring如何注入一个javacollection?如何注入一个Jperties?Spring提供了以下四种集合类的配置元素:<list>:该标签用来装配可重复的list值。<set>:该标签用来装配没有重复的set值。<map>:该标签可用来注入键和值可以为任何类型的键值对。<props>:该标签支持注入键和值都是字符串类型的键值对。请解释springbean的自动装配?请解释自动装配模式的区别?解释:在配置文件中设定bean的依赖关系是一个很好的机制,Spring容器还可以自动装配合作关系bean之间的关联关系。这意味着Spring可以通过向BeanFactory中注入的方式自动搞定bean之间的依赖关系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。可以使用@Autowired注解形式,也可以在<beanautowire="byName"/>达到同样效果。模式区别:no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。请解释@Autowired注解?答:@Autowired采取的策略为按照类型注入@Resource注解由J2EE提供,需要导入包javax.annotation.Resource。@Resource默认按照ByName自动注入。构造方法注入和设值注入的区别?1.在设值注入方法支持大部分的依赖注入,如果我们仅需要注入int、string和long型的变量,我们不要用设值的方法注入。对于基本类型,如果我们没有注入的话,可以为基本类型设置默认值。在构造方法注入不支持大部分的依赖注入,因为在调用构造方法中必须传入正确的构造参数,否则的话为报错。2.设值注入不会重写构造方法的值。如果我们对同一个变量同时使用了构造方法注入又使用了设置方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。很明显,因为构造方法尽在对象被创建时调用。3.在使用设值注入时有可能还不能保证某种依赖是否已经被注入,也就是说这时对象的依赖关系有可能是不完整的。而在另一种情况下,构造器注入则不允许生成依赖关系不完整的对象。4.在构造方法注入时如果对象A和对象B互相依赖,在创建对象A时Spring会抛出ObjectCurrentlyInCreationException异常,因为在B对象被创建之前A对象是不能被创建的,反之亦然。所以Spring用设值注入的方法解决了循环依赖的问题,因对象的设值方法是在对象被创建之前被调用的。Spring框架中有哪些不同类型事件?Spring提供了以下5中标准的事件:上下文更新事件ContextRefreshedEvent:该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext接口中的refresh()方法时被触发。上下文开始事件ContextStartedEvent:当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。上下文停止事件ContextStoppedEvent:当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。上下文关闭事件ContextClosedEvent:当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。FileSystemResource和ClassPathResource有何区别?ClassPathResource类,当资源是在项目里的时候,用这个,相对路径的ClassPathResourcebgFile=newClassPathResource(bgPath,this.getClass());FileSystemResource是绝对路径的Spring框架中都用到了哪些设计模式?(1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;(2)单例模式:Bean默认为单例模式。(3)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;(4)模板方法:用来解决代码重复的问题。比如.RestTemplate,JmsTemplate,JpaTemplate。(5)观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现--ApplicationListener。Spring事物传播机制首先理解几个概念:脏读:(读取了未提交的新事物,然后被回滚了)不可重复读:(读取了提交的新事物,指更新操作。不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。解决:如果一个事物在读的时候,禁止任何事物写。是不是就解决了。)幻读:(也是读取了提交的新事物,指增删操作),在事务A多次读取构成中,事务B对数据进行了新增操作,导致事务A多次读取的数据不一致。幻读和不可重复读的区别在于,不可重复是针对记录的update操作,只要在记录上加写锁,就可避免;幻读是对记录的insert操作,要禁止幻读必须加上全局的写锁(比如在表上加写锁)。Spring事务七个事务传播行为,在TransactionDefinition接口中定义了七个事务传播行为:PROPAGATION_REQUIRED如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。PROPAGATION_SUPPORTS如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。PROPAGATION_NOT_SUPPORTED总是非事务地执行,并挂起任何存在的事务。PROPAGATION_NEVER总是非事务地执行,如果存在一个活动事务,则抛出异常。PROPAGATION_MANDATORY如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。PROPAGATION_REQUIRES_NEW总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中.如果没有活动事务,则按TransactionDefinition.PROPAGATION_REQUIRED属性执行。Spring事务的五种隔离级别,在TransactionDefinition接口中定义了五个不同的事务隔离级别:ISOLATION_DEFAULT这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应。ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。ISOLATION_READ_COMMITTED保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。ISOLATION_REPEATABLE_READ这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。对行加锁比如版本号。ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。对表读写加锁。SpringAOP相关AOP实现原理是什么?AOP基础知识:切面:拦截器类,其中会定义切点以及通知切点:具体拦截的某个业务点。通知:切面当中的方法,声明通知方法在目标业务层的执行位置,通知类型如下:前置通知:@Before在目标业务方法执行之前执行后置通知:@After在目标业务方法执行之后执行返回通知:@AfterReturning在目标业务方法返回结果之后执行异常通知:@AfterThrowing在目标业务方法抛出异常之后环绕通知:@Around功能强大,可代替以上四种通知,还可以控制目标业务方实现原理(动态代理):我们能在一个切点之前执行一些操作,在一个切点之后执行一些操作,这个切点就是一个个方法。这些方法所在类肯定就是被代理了,在代理过程中切入了一些其他操作。(1)、Java动态代理:静态代理和动态代理的区别是在于要不要开发者自己定义Proxy类。动态代理不需要自己手动写一个代理类,通过Proxy动态生成proxyclass,但是它也指定了一个InvocationHandler的实现类。。应用场景有哪些?拦截器:日志打印、登录控制、事务管理、注入缓存SpringIOC(依赖倒置)相关IOC如何工作的?IOC也就是所谓的依赖注入,即高层需要什么,就寻找对应的低层来注入。直接的管理通过IOC容器来统一管理和维护,解除直接依赖以及自己手动创建和管理bean,IoC的理念就是让别人为你服务。举例:找女朋友过程:我们把需求告诉婚介中心,婚介中心根据我们需求匹配合适女性,把找到的女性告诉我们,其中婚介中心就是IOC控制器。容器实际上是Context组件结合其他两个组件共同构建的一个Bean关系网,构建入口就在AbstractApplicationContext类的refresh方法中,代码大致如下:动态代理相关JDK的动态代理和cglib的动态代理各实现原理JDK动态代理:JDK动态代理类实现了InvocationHandler接口,重写的invoke方法。JDK动态代理的基础是反射机制(method.invoke(对象,参数))Proxy.newProxyInstance()。Cglib动态代理:原理是对指定的目标生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。通过实现(MethodInterceptor)Java设计模式创建型:如何创建对象工厂方法模式工厂方法模式、抽象工厂模式建造者模式定义:创建复杂对象的算法应该独立于该对象的组成部分及装配方式。建造者模式也就是说不仅能创建多个对象,还能将按照一定顺序装配起来,案例:建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。优点:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序,且工厂模式关注创建单个种对象,建造者模式可以场景多个对象。缺点:产品必须有共同点,限制了使用范围。如内部变化复杂,会有很多的建造类,难以维护。示例:产品product类,里面包含水果、肉等属性。构造接口builder,定义构建水果,构建肉两个方法。套餐=具体建造者GroupBuilderA,实现builder接口,实现上面两个方法,比如水果是橘子。服务员=director类,负责控制产品对象的生产过程和顺序。Productproduct=newProduct();BuilderbuilderA=newGrouopBuilderA(product);Directordirector=newDirector(builderA);director.show();原型模式克隆一个对象,当一个系统应该独立于它的产品创建、构成和表示。单例模式当类只能有一个实例,而且始终只有一个。结构型:如何组合类和对象以获得更大结构如何组合类和对象以获得更大结构,采用继承机制来组合接口和实现。简单例子是多重继承,结果子类包含了所有父类性质。适配器模式将一个类的接口,转换成客户希望的另外一个接口。将已有类的接口转换成和目标接口兼容。源(Adaptee):需要被适配的对象或类型,相当于插头。适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。目标(Target):期待得到的目标,相当于插座。桥接模式(bridge)将抽象部分与它的实现部分相分离,使它们都可以独立地变化。如A抽象类,使用B类继承A。C/D/F等都可继承B并可动态变化,与A解耦(将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化)。组合模式组合多个对象形成树形结构形成整体-部分关系,即实现类直接继承抽象类,组合成一个新的组合。示例:树形的文件结构,父文件,子文件包含文件夹或者图片,子文件夹又包含文件和文档等等。。。现在要写一个功能,指定只删除文件夹。装饰模式(decorator)动态的给一个对象添加一些额外的功能。当不能采用生成子类的方法进行扩充时,可采用该模式动态地给一个对象添加一些额外的职责。示例:假设有一个接口Human,一个接口的实现类Man。人类Human是可以跑步的,但是不能飞。如果想给人类加上飞翔的翅膀,可以有三种解决方案:修改实现类Man的方法,但不符合开闭原则给实现类Man添加一个子类,扩展一个人类可以飞的功能。问题在于,如果又想 给人类增加猎豹般奔跑的速度,需要继续扩展一个子类。显然,使用继承的方式去扩展 一个类的功能,会增加类的层级,类的臃肿会加大维护的成本。使用装饰模式扩展一个类的功能。好处在于,如果继承关系是纵向的,那么装饰 类 则是某个类横向的扩展,并不会影响继承链上的其他类。例如:CextendsB,BextendsA, 如果需要扩展B的功能,可以设计一个B的装饰类,它并不会影响B的子类C。如果采 用在B里面增加方法,势必会使B的所有子类结构被改变。代理模式与decorator结构基本一致,但区别是,decorator可动态的添加或删除功能。外观模式(facade)某子系统为外界提供功能服务,但该子系统中存在很多粒度十分小的类,不便被外界系统直接使用,则可新增一个入口facade,外界通过该入口访问子系统,采用该模式。行为型:关注系统中对象之间的相互交互关注系统中对象之间的相互交互,研究系统在运行时对象之间的相互通信和协作,进一步明确对象的职责。职责链模式(chainofresponsibility)使多个对象都有机会处理请求,将这些对象连成链,直至有个对象处理为止。如用户点击按钮->接受响应->弹出按钮或者跳转或者等等,肯定有一个处理该请求。模板方法模式(templatemethod)定义一个操作中的算法骨架,而将一些步骤延迟到子类中。该模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。例子:一个父类定义了不可变的方法并定义一些可变的抽象方法。子类只需实现这些可变的方法就可以了。示例:想要泡一杯茶或者一杯咖啡,第一步都是将水煮沸,第二部是加入咖啡或者茶,第三部就是将饮料倒入杯子中,第四部就是加入各种调味料。其中第一步和第三部都是一样的,这个就可以定义在基类,而第二步和第四步就是他们之间的差异就可以在具体的子类中去实现。观察者模式(observer)当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。示例:发布订阅,共有4个角色,如下:抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集 合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除 观察者角色。一般用一个抽象类和接口来实现。抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记 过的观察者发出通知。具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的 状态相协调。中介模式(mediator)用一个中介对象来封装一系列的对象交互,从而使各对象不需要显式地相互引用,使其耦合松散。示例:如同事之间交流,可以通过一个中介人进行信息传达,这样避免了同事之间过多的直接联系,有以下4个角色:抽象中介者角色(AbstractMediator):定义出同事对象到中介者对象的接口,其中主要方法是一个(或多个)事件方法。具体中介者角色(ConcreteMediator):实现抽象中介者中所声明的事件方法。具体中介者直销所有的具体同事类,并负责具体的协调各个同事对象的交互关系。抽象同事类角色(AbstractColleague):定义出红接着到同事对象的接口。同事对象只知道中介者,而不知道其余的同事对象。具体同事类角色(ConcreteColleague):所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者会负责与其他的同时交互。策略模式(strategy)策略模式是对算法的包装,是把使用算法的责任和算法本身分开。定义一系列的算法,把它们一个个封装起来,并且使它们可以相互转化。示例:假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣;对中级会员提供每本10%的促销折扣;对初级会员没有折扣。迭代器模式(iterator)提供一种方法殊勋放一个聚合对象各元素,而又不暴露该对象内部表示。在实例化列表迭代器之前,必须提供待遍历的列表。解释器模式(interpreter)给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。命令模式(command)将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,请求排队或记录请求日志,以及支持可撤销操作。状态模式(state)将每一个条件分支放入一个独立的类中,这样就可以根据对象自身的情况将对象的状态作为一个对象,准许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。线程/并发编程相关线程池Thread基础知识1、线程的生命周期线程也同样要经历开始(等待)、运行、挂起和停止四种不同的状态。这四种状态都可以通过Thread类中的方法进行控制。线程在建立后并不马上执行run方法中的代码,而是处于等待状态。线程处于等待状态时,可以通过Thread类的方法来设置线程不各种属性,如线程的优先级(setPriority)、线程名(setName)和线程的类型(setDaemon)等。1、wait、suspend、sleep区别(1)、suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁,调用resume来释放(2)、wait()是Object对象方法,wait()对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。notify与notifyAll区别:voidnotify():唤醒一个正在等待该对象的线程。voidnotifyAll():唤醒所有正在等待该对象的线程。(3)、sleep()此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。sleep需放在try{}catch(){}块中调用wait方法会释放当前线程的锁(其实线程间的通信是靠对象来管理的,所有操作一个对象的线程是这个对象通过自己的wait方法来管理的,就好像这个对象是电视机,三个人是三个线程,那么电视机的遥控器就是这个锁,假如现在A拿着遥控器,电视机调用wait方法,那么A就交出自己的遥控器,由jVM虚拟机调度,遥控器该交给谁。)【我想到一个好玩的例子:如果A拿遥控器的期间,他可以用自己的sleep每隔十分钟调一次电视台,而在他调台休息的十分钟期间,遥控器还在他的手上~】Java中的线程池是如何实现的?创建线程池的几个核心构造参数?线程池:核心是池化技术,如连接池、对象池,通过预先创建好多个线程,放在池中,这样可以在需要使用线程的时候直接获取,线程执行完一个任务后,又去执行另一个任务,避免多次重复创建、销毁带来的开销。创建过程:本质是ExecutorService接口,可以通过ThreadPoolExecutor构造方法创建,也可以Executors提供的几个方法来创建。核心构造参数:corePoolSize:核心线程数量,可以类比正式员工数量,常驻线程数量。maximumPoolSize:最大的线程数量,公司最多雇佣员工数量。常驻+临时线程数量。workQueue:多余任务等待队列,再多的人都处理不过来了,需要等着,在这个地方等。keepAliveTime:非核心线程空闲时间,就是外包人员等了多久,如果还没有活干,解雇了。threadFactory:创建线程的工厂,在这个地方可以统一处理创建的线程的属性。每个公司对员工的要求不一样,恩,在这里设置员工的属性。handler:线程池拒绝策略,什么意思呢?就是当任务实在是太多,人也不够,需求池也排满了,还有任务咋办?默认是不处理,抛出异常告诉任务提交者,我这忙不过来了。总结所谓线程池本质是一个hashSet。多余的任务会放在阻塞队列中。只有当阻塞队列满了后,才会触发非核心线程的创建。所以非核心线程只是临时过来打杂的。直到空闲了,然后自己关闭了。线程池提供了两个钩子(beforeExecute,afterExecute)给我们,我们继承线程池,在执行任务前后做一些事情。线程池原理关键技术:锁(lock,cas)、阻塞队列、hashSet(资源池)
Executors框架的四种线程池及拒绝策略?共四种:Executors.newFixedThreadPool(60);设置固定值会造成高并发线程排队等待空闲线程,尤其是当读取大数据量时线程处理时间长而不释放线程,导致无法创建新线程。可缓存线程池Executors.newCachedThreadPool();线程池无限大,而系统资源(内存等)有限,会导致机器内存溢出OOM。定长且可定时、周期线程池Executors.newScheduledThreadPool(5);单线程线程池Executors.newSingledThreadPool();在使用有界队列时,若有新的任务需要执行,(1)若线程池实际线程数小于corePoolSize,则优先创建线程,(2)若大于corePoolSize,则会将任务加入队列,(3)若队列已满,则在总线程数不大于maximumPoolSize的前提下,创建新的线程。(4)若线程数大于maximumPoolSize,则执行拒绝策略。或其他自定义方式。Jdk拒绝策略(1)AbortPolicy:默认,直接抛出异常,系统正常工作。(2)DiscardOldestPolicy:丢弃最老的一个请求,尝试再次提交当前任务。(3)CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。用线程池中的线程执行,而是交给调用方来执行,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。(4)DiscardPolicy:丢弃无法处理的任务,不给予任何处理。(5)自定义拒绝策略如果需要自定义策略,可以实现RejectedExecutionHandler接口。线程池中的线程是怎么创建的?是一开始就随着线程池的启动创建好的吗?显然不是的。线程池默认初始化后不启动Worker,等待有请求时才启动。每当我们调用execute()方法添加一个任务时,线程池会做如下判断:如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务;如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放入队列;如果这时候队列满了,而且正在运行的线程数量小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务;如果队列满了,而且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会抛出异常RejectExecutionException。既然提到可以通过配置不同参数创建出不同的线程池,那么Java中默认实现好的线程池又有哪些呢?请比较它们的异同?1.SingleThreadExecutor线程池这个线程池只有一个核心线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。corePoolSize:1,只有一个核心线程在工作。maximumPoolSize:1。keepAliveTime:0L。workQueue:newLinkedBlockingQueue<Runnable>(),其缓冲队列是无界的。2.FixedThreadPool线程池FixedThreadPool是固定大小的线程池,只有核心线程。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程,多用于服务器。corePoolSize:nThreadsmaximumPoolSize:nThreadskeepAliveTime:0LworkQueue:newLinkedBlockingQueue<Runnable>(),其缓冲队列是无界的。3.CachedThreadPool线程池CachedThreadPool是无界线程池,如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。SynchronousQueue是一个是缓冲区为1的阻塞队列。corePoolSize:0maximumPoolSize:Integer.MAX_VALUEkeepAliveTime:60LworkQueue:newSynchronousQueue<Runnable>(),一个是缓冲区为1的阻塞队列。4.ScheduledThreadPool线程池ScheduledThreadPool:核心线程池固定,大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。创建一个周期性执行任务的线程池。如果闲置,非核心线程池会在DEFAULT_KEEPALIVEMILLIS时间内回收。corePoolSize:corePoolSizemaximumPoolSize:Integer.MAX_VALUEkeepAliveTime:DEFAULT_KEEPALIVE_MILLISworkQueue:newDelayedWorkQueue()什么是Java的内存模型,Java中各个线程是怎么彼此看到对方的变量的?Java的内存模型:定义了程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出这样的底层细节。此处的变量包括实例字段、静态字段和构成数组对象的元素,但是不包括局部变量和方法参数,因为这些是线程私有的,不会被共享,所以不存在竞争问题。Java中各个线程是怎么彼此看到对方的变量的呢?Java中定义了主内存与工作内存的概念:所有的变量都存储在主内存,每条线程还有自己的工作内存,保存了被该线程使用到的变量的主内存副本拷贝。线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,不能直接读写主内存的变量。不同的线程之间也无法直接访问对方工作内存的变量,线程间变量值的传递需要通过主内存。Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围操作的原子性,可以通过synchronized和Lock来实现。由于synchronized和Lock能够保证任一时刻只有一个线程执行该代码块,那么自然就不存在原子性问题了,从而保证了原子性。请谈谈volatile关键字有什么特点,为什么它能保证变量对所有线程的可见性?是不是就意味着基于volatile变量的运算就是并发安全的?Volatile:是关键字,作用于变量上。可见性:上面说到变量分为主内存和工作内存,如果是普通变量,每个线程在运行过程中都有自己的工作内存,那么线程1在运行的时候,会将stop变量的值拷贝一份放在自己的工作内存当中。那么当线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,那么线程1由于不知道线程2对stop变量的更改,因此还会一直循环下去。但是用volatile修饰之后就变得不一样了:第一:使用volatile关键字会强制将修改的值立即写入主存;第二:使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效);第三:由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1再次读取变量stop的值时会去主存读取。原子性:volatile没办法保证对变量的操作的原子性。即对int类型的自增变量,自增操作是不具备原子性的,它包括读取变量的原始值、进行加1操作、写入工作内存三个阶段,如果在第一个阶段执行完成后线程阻塞,那就有可能导致计算错误。Volatile的操作是保证一个线程对变量修改后能立即写入主内存,同时其他线程也会立即知道该变量失效并重新读取值。并发安全:显然不是并发安全,原因在于原子性,Java里面的运算并非原子操作,加减乘除都不是原子操作。请对比下volatile对比Synchronized的异同?Synchronized既能保证可见性,又能保证原子性,而volatile只能保证可见性,无法保证原子性。请对比下ThreadLocal对比Synchronized的异同?Synchronized用于实现同步机制,是利用锁的机制使变量或代码块在某一时该只能被一个线程访问,是一种“以时间换空间”的方式。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,根除了对变量的共享,是一种“以空间换时间”的方式。如何在Java线程池中提交线程?答:submit(返回futhure对象,可以通过该对象的get方法获取线程执行结果,但是该操作是同步的,也就是主线程会阻塞)和excute。Java强引用、软引用、弱引用、虚引用?强引用:我们使用的大部分引用其实都是强引用,也就是说方法的内部有一个强引用,这个引用保存在栈中,而真正的引用内容(Object)保存在堆中。当这个方法运行完成后就会退出方法栈,则引用内容的引用不存在,这个Object会被回收。但是如果这个对象是全局的变量时,就需要在不用这个对象时赋值为null,因为强引用不会被垃圾回收。软引用:软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。如果一个对象只有软引用,就类似鸡肋,食之无味、弃之可惜,如果内存空间足够大,垃圾回收期就不会回收它,如果内存空间不够了,就会回收这些对象。只有垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。弱引用:在java中,用java.lang.ref.WeakReference类来表示。弱引用和软引用的区别在于:弱引用的对象具有更短暂的生命周期。在垃圾回收时,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。虚引用:就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。ThreadLocal原理?原理:每个Thread都有自己的一个ThreadLocal.ThreadLocalMap对象。key是TreadLocal实例对象,value就是你要保存的那个变量。当前线程Thread中有一个ThreadLocalMap对象,它的key是ThreadLocal的弱引用,Value是ThreadLocal调用set方法设置的对象值。每一个线程维护一个各自的ThreadLocalMap,所以多个线程之间变量相互隔离,互不干扰。缺点:存在内存泄漏问题,因为当Thr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度企业催告函模板制作合同3篇
- 个人与个人之间2024年度专利许可合同3篇
- 二零二五农机零部件进口代理合同3篇
- 抵押物合同(2篇)
- 2025年度市政基础设施劳务分包合同标准范本4篇
- 二零二五年度农机租赁及运营管理合同4篇
- 2025年度抵押借款房屋装修合同范本4篇
- 二零二五版农家乐房屋租赁及生态旅游开发合同范本4篇
- 2025年度新型城镇化买还建房合同协议书
- 二零二五年度房地产信托投资基金合作协议合同
- 2025-2030年中国陶瓷电容器行业运营状况与发展前景分析报告
- 2025年山西国际能源集团限公司所属企业招聘43人高频重点提升(共500题)附带答案详解
- 二零二五年仓储配送中心物业管理与优化升级合同3篇
- 2025届厦门高三1月质检期末联考数学答案
- 音乐作品录制许可
- 江苏省无锡市2023-2024学年高三上学期期终教学质量调研测试语文试题(解析版)
- 拉萨市2025届高三第一次联考(一模)英语试卷(含答案解析)
- 开题报告:AIGC背景下大学英语教学设计重构研究
- 师德标兵先进事迹材料师德标兵个人主要事迹
- 连锁商务酒店述职报告
- 2024年山东省烟台市初中学业水平考试地理试卷含答案
评论
0/150
提交评论