前言
Spring 中使用了三级缓存的设计,来解决单例模式下的属性循环依赖问题。
这句话有两点需要注意
解决问题的方法是「三级缓存的设计」
解决的只是单例模式下的 Bean 属性循环依赖问题,对于多例 Bean 和 Prototype 作用域的 Bean的循环依赖问题,并不能使用三级缓存设计解决。
Bean 的生命周期
Spring Bean 的生命周期可以简单概括为 4 个阶段
实例化(Instantiation)
属性赋值(Populate)
初始化(Initialization)
销毁(Destruction)
什么是循环依赖
public class A {
@Autowired
private B b;
}
public class B {
@Autowired
private A a;
}
如上代码所示,即 A 里面注入 B,B 里面又注入 A。此时,就发生了「循环依赖」。
三级缓存
Spring 中,单例 Bean 在创建后会被放入 IoC 容器的缓存池中,并触发 Spring 对该 Bean 的生命周期管理。
单例模式下,在第一次使用 Bean 时,会创建一个 Bean 对象,并放入 IoC 容器的缓存池中。后续再使用该 Bean 对象时,会直接从缓存池中获取。
保存单例模式 Bean 的缓存池,采用了三级缓存设计,如下代码所示。
/** Cache of singleton objects: bean name --> bean instance */
/** 一级缓存:用于存放完全初始化好的 bean **/
private final Map singletonObjects = new ConcurrentHashMap(256);
/** Cache of early singleton objects: bean name --> bean instance */
/** 二级缓存:存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 */
private final Map earlySingletonObjects = new HashMap(16);
/** Cache of singleton factories: bean name --> ObjectFactory */
/** 三级级缓存:存放 bean 工厂对象,用于解决循环依赖 */
private final Map> singletonFactories = new HashMap>(16);
缓存层级
名称
描述
第一层缓存
singletonObjects
单例对象缓存池,存放的 Bean 已经实例化、属性赋值、完全初始化好(成品)
第二层缓存
earlySingletonObjects
早期单例对象缓存池,存放的 Bean 已经实例化但尚未属性赋值、未执行 init
方法(半成品)
第三层缓存
singletonFactories
单例工厂的缓存
使用三级缓存解决循环依赖
getSingleton方法中三级缓存的使用
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Spring首先从singletonObjects(一级缓存)中尝试获取
Object singletonObject = this.singletonObjects.get(beanName);
// 若是获取不到而且对象在建立中,则尝试从earlySingletonObjects(二级缓存)中获取
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//若是仍是获取不到而且允许从singletonFactories经过getObject获取,则经过singletonFactory.getObject()(三级缓存)获取
singletonObject = singletonFactory.getObject();
//若是获取到了则将singletonObject放入到earlySingletonObjects,也就是将三级缓存提高到二级缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
getSingleton()
方法中
isSingletonCurrentlyInCreation()
方法用于判断当前单例 Bean 是否正在创建中,即「还没有执行初始化方法」。比如,A 的构造器依赖了 B 对象因此要先去创建 B 对象,或者在 A 的属性装配过程中依赖了 B 对象因此要先创建 B 对象,这时 A 就是处于创建中的状态。
allowEarlyReference
变量表示是否允许从三级缓存 singletonFactories
中经过 singletonFactory
的 getObject()
方法获取 Bean 对象。
分析 getSingleton()
的整个过程,可知三级缓存的使用过程如下
Spring 会先从一级缓存 singletonObjects
中尝试获取 Bean。
若是获取不到,而且对象正在建立中,就会尝试从二级缓存 earlySingletonObjects
中获取 Bean。
若还是获取不到,且允许从三级缓存 singletonFactories
中经过 singletonFactory
的 getObject()
方法获取 Bean 对象,就会尝试从三级缓存 singletonFactories
中获取 Bean。
若是在三级缓存中获取到了 Bean,会将该 Bean 存放到二级缓存中。
第三级缓存为什么可以解决循环依赖
Spring 解决循环依赖的诀窍就在于 singletonFactories
这个三级缓存。 三级缓存中使用到了ObjectFactory
接口,定义如下
public interface ObjectFactory {
T getObject() throws BeansException;
}
在 Bean 建立过程当中,有两处比较重要的匿名内部类实现了该接口。一处是 Spring 利用其建立 Bean 的时候,另外一处就是在 addSingletonFactory
方法中,如下代码所示。
addSingletonFactory(beanName, new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
此处就是解决循环依赖的关键,这段代码发生在 createBeanInstance
以后
此时,单例 Bean 对象已经实例化(可以通过对象引用定位到堆中的对象),但尚未属性赋值和初始化。
Spring 会将该状态下的 Bean 存放到三级缓存中,提早曝光给 IoC 容器(“提早”指的是不必等对象完成属性赋值和初始化后再交给 IoC 容器)。也就是说,可以在三级缓存 singletonFactories
中找到该状态下的 Bean 对象。
解决循环依赖示例分析
public class A {
@Autowired
private B b;
}
public class B {
@Autowired
private A a;
}
在上文章节铺垫的基础上,此处结合一个循环依赖的案例,分析下如何使用三级缓存解决单例 Bean 的循环依赖。
创建对象 A,完成生命周期的第一步,即实例化(Instantiation),在调用 createBeanInstance
方法后,会调用 addSingletonFactory
方法,将已实例化但未属性赋值未初始化的对象 A 放入三级缓存 singletonFactories
中。即将对象 A 提早曝光给 IoC 容器。
继续,执行对象 A 生命周期的第二步,即属性赋值(Populate)。此时,发现对象 A 依赖对象,所以就会尝试去获取对象 B。
继续,发现 B 尚未创建,所以会执行创建对象 B 的过程。
在创建对象 B 的过程中,执行实例化(Instantiation)和属性赋值(Populate)操作。此时发现,对象 B 依赖对象 A。
继续,尝试在缓存中查找对象 A。先查找一级缓存,发现一级缓存中没有对象 A(因为对象 A 还未初始化完成);转而查找二级缓存,二级缓存中也没有对象 A(因为对象 A 还未属性赋值);转而查找三级缓存 singletonFactories
,对象 B 可以通过 ObjectFactory.getObject
拿到对象 A。
继续,对象 B 在获取到对象 A 后,继续执行属性赋值(Populate)和初始化(Initialization)操作。对象 B 完成初始化操作后,会被存放到一级缓存中。
继续,转到「对象 A 执行属性赋值过程并发现依赖了对象 B」的场景。此时,对象 A 可以从一级缓存中获取到对象 B,所以可以顺利执行属性赋值操作。
继续,对象 A 执行初始化(Initialization)操作,完成后,会被存放到一级缓存中。
Spring为何不能解决非单例Bean的循环依赖
Spring 为何不能解决非单例 Bean 的循环依赖?这个问题可以细分为下面几个问题
Spring 为什么不能解决构造器的循环依赖?
Spring 为什么不能解决 prototype
作用域循环依赖?
Spring 为什么不能解决多例的循环依赖?
Spring 为什么不能解决构造器的循环依赖
对象的构造函数是在实例化阶段调用的。
上文中提到,在对象已实例化后,会将对象存入三级缓存中。在调用对象的构造函数时,对象还未完成初始化,所以也就无法将对象存放到三级缓存中。
在构造函数注入中,对象 A 需要在对象 B 的构造函数中完成初始化,对象 B 也需要在对象 A的构造函数中完成初始化。此时两个对象都不在三级缓存中,最终结果就是两个 Bean 都无法完成初始化,无法解决循环依赖问题。
Spring 为什么不能解决prototype作用域循环依赖
Spring IoC 容器只会管理单例 Bean 的生命周期,并将单例 Bean 存放到缓存池中(三级缓存)。Spring 并不会管理 prototype
作用域的 Bean,也不会缓存该作用域的 Bean,而 Spring 中循环依赖的解决正是通过缓存来实现的。
Spring 为什么不能解决多例的循环依赖
多实例 Bean 是每次调用 getBean
都会创建一个新的 Bean 对象,该 Bean 对象并不能缓存。而 Spring 中循环依赖的解决正是通过缓存来实现的。
非单例Bean的循环依赖如何解决
为什么一定要三级缓存
为什么一定要三级缓存,使用两级缓存可以解决循环依赖吗?
带着这个思考,进入下文。
尝试使用两级缓存解决依赖冲突
第三级缓存的目的是为了延迟代理对象的创建,因为如果没有依赖循环的话,那么就不需要为其提前创建代理,可以将它延迟到初始化完成之后再创建。
既然目的只是延迟的话,那么我们是不是可以不延迟创建,而是在实例化完成之后,就为其创建代理对象,这样我们就不需要第三级缓存了。因此,我们可以将 addSingletonFactory()
方法进行改造。
protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 判断一级缓存中不存在此对象
if (!this.singletonObjects.containsKey(beanName)) {
// 直接从工厂中获取 Bean
Object o = singletonFactory.getObject();
// 添加至二级缓存中
this.earlySingletonObjects.put(beanName, o);
this.registeredSingletons.add(beanName);
}
}
}
这样的话,每次实例化完 Bean 之后就直接去创建代理对象,并添加到二级缓存中。
测试结果是完全正常的,Spring 的初始化时间应该也是不会有太大的影响,因为如果 Bean 本身不需要代理的话,是直接返回原始 Bean 的,并不需要走复杂的创建代理 Bean 的流程。
三级缓存的意义
测试证明,二级缓存也是可以解决循环依赖的。为什么 Spring 不选择二级缓存,而要额外多添加一层缓存,使用三级缓存呢?
如果 Spring 选择二级缓存来解决循环依赖的话,那么就意味着所有 Bean 都需要在实例化完成之后就立马为其创建代理,而 Spring 的设计原则是在 Bean 初始化完成之后才为其创建代理。
使用三级缓存而非二级缓存并不是因为只有三级缓存才能解决循环引用问题,其实二级缓存同样也能很好解决循环引用问题。使用三级而非二级缓存并非出于 IOC 的考虑,而是出于 AOP 的考虑,即若使用二级缓存,在 AOP 情形注入到其他 Bean的,不是最终的代理对象,而是原始对象。
你可能感兴趣的:(面试,spring,java,后端,spring面试题,循环依赖)
基于springboot+vue在线小说阅读平台系统(源码+lw+部署文档+讲解等)
QQ3295391197
Java毕业设计项目 spring boot vue.js 后端
前言博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌主要内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。精彩专栏推荐订
nacos是什么?
CT随
java
Nacos是阿里巴巴开源的一款用于动态服务发现、配置管理和服务管理的平台,常用于微服务架构中。以下是针对面试准备的简明总结:1.Nacos是什么?核心功能:服务注册与发现:微服务实例启动时注册到Nacos,其他服务通过Nacos发现并调用它们。配置管理:集中管理应用配置,支持动态更新(如修改配置后实时推送到服务)。服务健康监测:自动检测服务实例的健康状态,剔除故障节点。定位:类似Eureka(服务
java开发之框架基础技术反射
CT随
java 开发语言
什么是反射:在Java开发中,反射是一种强大的技术,允许程序在运行时检查和修改类、方法、字段等结构。它允许程序在没有预先知识的情况下,动态地加载类、创建对象、调用方法以及访问或修改字段。这种能力使得Java程序能够更加灵活和动态,但同时也需要谨慎使用,因为它可能会牺牲一些编译时的类型安全性Java反射常用API有哪些在Java中,反射是由JavaReflectionAPI支持的,它提供了一组类和接
华为最新OD机试真题-服务失效判断-OD统一考试(E卷)
ai因思坦
华为OD机试2024真题题库 华为 华为od 算法 面试 链表 动态规划 职场和发展
最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。题目描述某系统中有众多服务
Python 如何实现烟花效果的完整代码
Ai 编码
python教程 python pygame 开发语言
文章精选推荐1JetBrainsAiassistant编程工具让你的工作效率翻倍2ExtraIcons:JetBrainsIDE的图标增强神器3IDEA插件推荐-SequenceDiagram,自动生成时序图4BashSupportPro这个ides插件主要是用来干嘛的?5IDEA必装的插件:SpringBootHelper的使用与功能特点6Aiassistant,又是一个写代码神器7Cursor
Eureka Server 数据同步原理解析
CT随
eureka 云原生
EurekaServer数据同步原理解析引言在分布式系统中,服务注册与发现是微服务架构的核心组件之一。Eureka作为Netflix开源的服务注册与发现工具,被广泛应用于SpringCloud生态系统中。本文将深入探讨EurekaServer之间的数据同步原理,帮助开发者理解其工作机制。1.EurekaServer的角色EurekaServer是一个高可用的服务注册中心,负责管理所有服务实例的注册
NativeScript 8.9.0 发布,跨平台原生应用框架
自不量力的A同学
javascript
NativeScript是一个开源框架,可让开发者使用JavaScript或TypeScript来构建iOS和Android应用5。目前NativeScript最新版本为8.8.04,并未发布8.8.0以上版本,以下是NativeScript8.8.0的相关信息:改进的渲染性能:新的渲染引擎进一步优化了UI的绘制速度,使应用响应更快,能为用户提供更流畅的操作体验,在界面切换、元素显示等方面的表现更
SSM框架学习——SpringMVC简介与入门案例
程序员Lyle
SSM框架学习 servlet java SpringMVC
大家好,欢迎你们来到我的博客,今天心血来潮,我给自己起了一个笔名叫做Lyle。her~~llo,我是你们的好朋友Lyle,是名梦想成为计算机大佬的男人!博客是为了记录自我的学习历程,加强记忆方便复习,如有不足之处还望多多包涵!非常欢迎大家的批评指正。今天开始学习SpringMVC技术~目录SpringMVC简介SpringMVC入门案例相关注解入门案例工作流程分析SpringMVC入门程序开发总结
一起来动手实现一个ai聊天对话
本文,我们将根据前文来实现一个ai聊天对话项目,感受真实的业务。项目技术栈vite---一个前端工程构建工具。antd---一个reactui组件库。@ant-design/icons----一个react图标库。mockjs---模拟消息对话数据。dayjs---一个日期处理库react---一个javascript框架。typescript---javascript的超集。ew-message
js实现大数字求和
javascript前端
在现代编程中,处理超大数字常常会遇到限制,因为大多数编程语言的数字类型在存储较大的整数时可能会溢出。为了解决这一问题,通常采用字符串表示法来处理大数字。在这篇文章中,我们将深入探讨如何通过字符串实现大数字的求和,展示一个简单而有效的JavaScript函数。背景在数学中,加法是最基本的运算之一,但对于超出机器数值范围的数字,我们需要采取不同的方法。通过将数字表示为字符串,我们可以逐位进行加法运算,
react原理面试题
阿芯爱编程
面试 react react.js javascript 前端
以下是一些关于React原理的面试题:一、虚拟DOM(VirtualDOM)请简要解释React中的虚拟DOM是如何工作的?答案:当组件的状态发生变化时,React首先会在内存中创建一个新的虚拟DOM树来表示更新后的UI结构。然后,React会将这个新的虚拟DOM树与旧的虚拟DOM树进行比较(这个过程称为Diff算法)。Diff算法会找出两个虚拟DOM树之间的差异,例如哪些节点被添加、删除或者修改
java面试题
阿芯爱编程
面试 java java 开发语言
以下是一些Java后端面试题:一、基础部分Java中的基本数据类型有哪些?它们的默认值是什么?答案:基本数据类型有8种。整数类型:byte(默认值为0)、short(默认值为0)、int(默认值为0)、long(默认值为0L)。浮点类型:float(默认值为0.0f)、double(默认值为0.0d)。字符类型:char(默认值为’\u0000’,即空字符)。布尔类型:boolean(默认值为fa
基于SpringBoot校园失物招领系统设计与实现
骆晨学长
spring boot 后端 java
文未可获取一份本项目的java源码和数据库参考。本课题的作用、意义,在国内外的研究现状和发展趋势,尚待研究的问题作用:本课题的目的是使失物招领信息管理清晰化,透明化,便于操作,易于管理。通过功能模块的优化组合实现帮助失主进行在线发布自己的丢失物品,让更多人看到信息后可以帮助查找,同时捡到东西的人也可以发布抬到的物品信息,或者交到中心平台由管理员进行发布招领信息,失主可以通过信息确定自己的物品然后进
JAVA的Selenium自动化爬取TK数据收集-----JAVA
旧约Alatus
软件架构设计 JAVA # Spring-Boot框架 spring cloud 后端 spring boot jvm 分布式 selenium 爬虫
4.0.0org.springframework.bootspring-boot-starter-parent3.4.3com.alatusTiktokCrawl0.0.1-SNAPSHOTTiktokCrawlTiktokCrawl17org.springframework.bootspring-boot-starter-weborg.seleniumhq.seleniumselenium-ja
vue原理面试题
阿芯爱编程
面试 vue vue.js javascript 前端
以下是一些关于Vue原理的面试题:一、虚拟DOM与响应式系统Vue中的虚拟DOM是如何工作的?答案:当Vue组件的数据发生变化时,Vue首先会在虚拟DOM中构建一个新的虚拟DOM树来表示更新后的组件结构。然后,Vue会将新的虚拟DOM树与旧的虚拟DOM树进行比较(这个过程称为Diff算法)。Diff算法会找出两个虚拟DOM树之间的差异,例如哪些节点被添加、删除或者修改了。最后,Vue根据这些差异计
JAVA单服务应用拆分成多个服务的实践(3)--前端的nginx转发
秤秤biubiu
开发(应用软件 网站相关) niginx
上篇文章JAVA单服务应用拆分成多个服务的实践(2)--服务的dubbo化已经将部分模块微服务化了,但我们怎么测试?我们的目标是支持ALLInOne,又要支持多个微服务,但前端怎么处理,前端代码又只有一个版本,但又要怎么面向多个微服务呢。这样的话,我们只能引入伟大的nginx。前端只认一个,就使用nginx的转发,将特定的请求转发到微服务的接口里,让前端无感请求到到另一服务中。nginx的配置如下
2025毕设springboot大学生校园互助平台源码+论文
嘉佑学姐--毕设
课程设计 spring boot 后端
系统程序文件列表开题报告内容研究背景在当今信息化高速发展的时代,大学生活日益丰富多彩,但同时也伴随着各种需求与挑战。大学生作为一个充满活力与创造力的群体,在学习、生活、社交等多个方面有着广泛的互助需求。然而,传统的互助方式往往受限于时间和空间,难以满足即时、高效的需求。因此,构建一个集多种功能于一体的大学生校园互助平台显得尤为重要。该平台旨在打破信息壁垒,促进资源高效流通,提升校园生活的便捷性和舒
Spring AI:智能化的开发新趋势
精神之祝
java 人工智能 spring java
SpringAI:智能化的开发新趋势在当今数字化时代,人工智能(AI)技术正在迅速渗透到各个行业和领域。作为Java开发者,掌握AI技术以及如何将其与现有的开发框架结合使用,已成为提升竞争力的重要途径。Spring生态系统的强大,使得开发者能够将AI集成到他们的应用程序中,今天将深入探讨SpringAI的各个方面,帮助你理解这一新兴技术。文章目录SpringAI:智能化的开发新趋势一、什么是Spr
c#和python更适合爬虫_为什么python适合写爬虫?(python到底有啥好的?!)
weixin_39974811
c#和python更适合爬虫
我用c#,java都写过爬虫。区别不大,原理就是利用好正则表达式。只不过是平台问题。后来了解到很多爬虫都是用python写的。因为目前对python并不熟,所以也不知道这是为什么。百度了下结果:1)抓取网页本身的接口相比与其他静态编程语言,如java,c#,C++,python抓取网页文档的接口更简洁;相比其他动态脚本语言,如perl,shell,python的urllib2包提供了较为完整的访问
【商城实战(2)】商城架构设计:从底层逻辑到技术实现
奔跑吧邓邓子
商城实战 商城实战 架构设计
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用uniapp、ElementPlus、SpringBoot搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从0到1的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战
让支付更简单 Sping Boot 对接微信支付V3 (Java详细教程)
Mikael Lin
java 微信
文章目录准备工作数据库设计代码一、准备工作1.需要开通商户号接入微信支付-微信商户平台https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal商户号要跟小程序(我是小程序支付)关联,指引https://kf.qq.com/faq/200520fueQrI200520aQf6Rr.html2.在商户平台上还需要配置支付
【商城实战(1)】启航:从0到1搭建电商帝国的第一步
奔跑吧邓邓子
商城实战 商城实战 项目背景 选型
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用uniapp、ElementPlus、SpringBoot搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从0到1的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战
HoRain云--Java开发必知:动态代理的核心价值与应用场景解析
HoRain 云小助手
java python 开发语言
HoRain云小助手:个人主页⛺️生活的理想,就是为了理想的生活!⛳️推荐前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。目录⛳️推荐Java开发必知:动态代理的核心价值与应用场景解析一、动态代理的本质与实现机制实现原理示意图二、使用动态代理的五大核心优势1.解耦业务逻辑与横切关注点2.代码复用性提升3.运行时动态增强4.架构灵活性增强5.资源
Spring AI Alibaba:Java 开发者的 AI 应用开发新利器
ZnSoft〔100-1=0〕
java spring 人工智能
在当今这个由人工智能(AI)驱动的时代,AI技术正在以前所未有的速度改变着我们的工作和生活方式。对于Java开发者来说,将AI能力集成到他们的应用程序中,已经成为了一个迫切的需求。阿里云开源的SpringAIAlibaba框架,正是为了满足这一需求而生。本文将详细介绍SpringAIAlibaba的起源、核心特性,并通过一个示例展示其在AI应用开发中的便利性。一、SpringAIAlibaba的起
JAVA 后台开发规范
WaiSaa
Java java
本篇规范基于阿里巴巴、华为的开发手册。感谢前人的经验和付出,让我们可以有机会站在巨人的肩膀上眺望星辰大海。规范不是为了约束和禁锢大家的创造力,而是为了帮助大家能够在正确的道路上,尽可能的避免踩坑和跑偏。规范可以让我们无论单枪匹马还是与众人同行的时候都能得心应手。规范可以让我们在面对日益变态的需求和做代码接盘侠的时候,更优雅从容。规则并不是完美的,通过约束和禁止在特定情况下的特性,可能会对代码实现造
Java中常见的设计模式
皮克斯的进化之路
java 设计模式 开发语言
设计模式是软件设计中针对常见问题的可复用解决方案,它们提供了代码组织和架构的最佳实践,Java中常见的设计模式可分为创建型、结构型和行为型三类。下面就给大家介绍一些常用的设计模式和案例。创建型模式:管理对象创建1.单例模式确保一个类只有一个实例,并且提供了一种访问其唯一对象的方式,不需要再实例化该类对象,可直接访问,避免重复消耗资源。(1)懒汉式publicclassSingleton{/*持有私
python API自动化(接口测试基础与原理)
秋殇大大
python 自动化 python postman jmeter
1.接口测试概念及应用什么是接口接口是前后端沟通的桥梁,是数据传输的通道,包括外部接口、内部接口,内部接口又包括:上层服务与下层服务接口,同级接口外部接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们写好的方法来获取数据,你引用他提供的接口就能使用他写好的方法,从而达到数据共享的目的。比如说:支付接口,沙箱,Mock.....内部接口:方法与方法
2025年具有百度特色的软件测试面试题
噔噔噔噔@
软件测试基础及工具分享 程序人生 软件测试面试题专栏 测试工具 经验分享 自动化
百度业务场景如何测试一个高并发的搜索系统(如百度搜索)?如何测试一个在线地图服务(如百度地图)?如何测试一个大型推荐系统(如百度推荐)的性能?百度技术栈你对百度的PaddlePaddle框架有了解吗?如何测试基于PaddlePaddle的服务?如何测试百度云的API服务?你对百度的DevOps实践有什么了解?
《2025软件测试工程师面试》功能测试篇
悠然的笔记本
功能测试 面试
什么是功能测试?功能测试是通过验证产品功能是否满足用户需求的过程,主要关注软件的功能是否符合需求规格说明,包括软件的各种功能、特性、性能、安全性和易用性等。功能测试的流程包括哪些步骤?需求分析:明确软件需求,确定测试范围。测试计划:制定详细的测试计划,包括测试目标、测试策略、测试资源等。测试用例设计:根据需求和测试计划,设计测试用例。、测试执行:按照测试用例执行测试,记录测试结果。缺陷跟踪:发现缺
JAVA进阶5.11——拆分窗口
乔培宸
JAVA
importjavax.swing.ImageIcon;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JList;importjavax.swing.JSplitPane;publicclassTestextendsJFrame{JSplitPanechaiFen;//声明拆分模块。JListlieBiao;
java线程Thread和Runnable区别和联系
zx_code
java jvm thread 多线程 Runnable
我们都晓得java实现线程2种方式,一个是继承Thread,另一个是实现Runnable。
模拟窗口买票,第一例子继承thread,代码如下
package thread;
public class ThreadTest {
public static void main(String[] args) {
Thread1 t1 = new Thread1(
【转】JSON与XML的区别比较
丁_新
json xml
1.定义介绍
(1).XML定义
扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML使用DTD(document type definition)文档类型定义来组织数据;格式统一,跨平台和语言,早已成为业界公认的标准。
XML是标
c++ 实现五种基础的排序算法
CrazyMizzz
C++ c 算法
#include<iostream>
using namespace std;
//辅助函数,交换两数之值
template<class T>
void mySwap(T &x, T &y){
T temp = x;
x = y;
y = temp;
}
const int size = 10;
//一、用直接插入排
我的软件
麦田的设计者
我的软件 音乐类 娱乐 放松
这是我写的一款app软件,耗时三个月,是一个根据央视节目开门大吉改变的,提供音调,猜歌曲名。1、手机拥有者在android手机市场下载本APP,同意权限,安装到手机上。2、游客初次进入时会有引导页面提醒用户注册。(同时软件自动播放背景音乐)。3、用户登录到主页后,会有五个模块。a、点击不胫而走,用户得到开门大吉首页部分新闻,点击进入有新闻详情。b、
linux awk命令详解
被触发
linux awk
awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息
awk处理过程: 依次对每一行进行处理,然后输出
awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
[-F|-f|-v]大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=val
各种语言比较
_wy_
编程语言
Java Ruby PHP 擅长领域
oracle 中数据类型为clob的编辑
知了ing
oracle clob
public void updateKpiStatus(String kpiStatus,String taskId){
Connection dbc=null;
Statement stmt=null;
PreparedStatement ps=null;
try {
dbc = new DBConn().getNewConnection();
//stmt = db
分布式服务框架 Zookeeper -- 管理分布式环境中的数据
矮蛋蛋
zookeeper
原文地址:
http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/
安装和配置详解
本文介绍的 Zookeeper 是以 3.2.2 这个稳定版本为基础,最新的版本可以通过官网 http://hadoop.apache.org/zookeeper/来获取,Zookeeper 的安装非常简单,下面将从单机模式和集群模式两
tomcat数据源
alafqq
tomcat
数据库
JNDI(Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。
没有使用JNDI时我用要这样连接数据库:
03. Class.forName("com.mysql.jdbc.Driver");
04. conn
遍历的方法
百合不是茶
遍历
遍历
在java的泛
linux查看硬件信息的命令
bijian1013
linux
linux查看硬件信息的命令
一.查看CPU:
cat /proc/cpuinfo
二.查看内存:
free
三.查看硬盘:
df
linux下查看硬件信息
1、lspci 列出所有PCI 设备;
lspci - list all PCI devices:列出机器中的PCI设备(声卡、显卡、Modem、网卡、USB、主板集成设备也能
java常见的ClassNotFoundException
bijian1013
java
1.java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory 添加包common-logging.jar2.java.lang.ClassNotFoundException: javax.transaction.Synchronization
【Gson五】日期对象的序列化和反序列化
bit1129
反序列化
对日期类型的数据进行序列化和反序列化时,需要考虑如下问题:
1. 序列化时,Date对象序列化的字符串日期格式如何
2. 反序列化时,把日期字符串序列化为Date对象,也需要考虑日期格式问题
3. Date A -> str -> Date B,A和B对象是否equals
默认序列化和反序列化
import com
【Spark八十六】Spark Streaming之DStream vs. InputDStream
bit1129
Stream
1. DStream的类说明文档:
/**
* A Discretized Stream (DStream), the basic abstraction in Spark Streaming, is a continuous
* sequence of RDDs (of the same type) representing a continuous st
通过nginx获取header信息
ronin47
nginx header
1. 提取整个的Cookies内容到一个变量,然后可以在需要时引用,比如记录到日志里面,
if ( $http_cookie ~* "(.*)$") {
set $all_cookie $1;
}
变量$all_cookie就获得了cookie的值,可以用于运算了
java-65.输入数字n,按顺序输出从1最大的n位10进制数。比如输入3,则输出1、2、3一直到最大的3位数即999
bylijinnan
java
参考了网上的http://blog.csdn.net/peasking_dd/article/details/6342984
写了个java版的:
public class Print_1_To_NDigit {
/**
* Q65.输入数字n,按顺序输出从1最大的n位10进制数。比如输入3,则输出1、2、3一直到最大的3位数即999
* 1.使用字符串
Netty源码学习-ReplayingDecoder
bylijinnan
java netty
ReplayingDecoder是FrameDecoder的子类,不熟悉FrameDecoder的,可以先看看
http://bylijinnan.iteye.com/blog/1982618
API说,ReplayingDecoder简化了操作,比如:
FrameDecoder在decode时,需要判断数据是否接收完全:
public class IntegerH
js特殊字符过滤
cngolon
js特殊字符 js特殊字符过滤
1.js中用正则表达式 过滤特殊字符, 校验所有输入域是否含有特殊符号function stripscript(s) { var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]"
hibernate使用sql查询
ctrain
Hibernate
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.hibernate.Hibernate;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transa
linux shell脚本中切换用户执行命令方法
daizj
linux shell 命令 切换用户
经常在写shell脚本时,会碰到要以另外一个用户来执行相关命令,其方法简单记下:
1、执行单个命令:su - user -c "command"
如:下面命令是以test用户在/data目录下创建test123目录
[root@slave19 /data]# su - test -c "mkdir /data/test123"
好的代码里只要一个 return 语句
dcj3sjt126com
return
别再这样写了:public boolean foo() { if (true) { return true; } else { return false;
Android动画效果学习
dcj3sjt126com
android
1、透明动画效果
方法一:代码实现
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_main, container, fals
linux复习笔记之bash shell (4)管道命令
eksliang
linux管道命令汇总 linux管道命令 linux常用管道命令
转载请出自出处:
http://eksliang.iteye.com/blog/2105461
bash命令执行的完毕以后,通常这个命令都会有返回结果,怎么对这个返回的结果做一些操作呢?那就得用管道命令‘|’。
上面那段话,简单说了下管道命令的作用,那什么事管道命令呢?
答:非常的经典的一句话,记住了,何为管
Android系统中自定义按键的短按、双击、长按事件
gqdy365
android
在项目中碰到这样的问题:
由于系统中的按键在底层做了重新定义或者新增了按键,此时需要在APP层对按键事件(keyevent)做分解处理,模拟Android系统做法,把keyevent分解成:
1、单击事件:就是普通key的单击;
2、双击事件:500ms内同一按键单击两次;
3、长按事件:同一按键长按超过1000ms(系统中长按事件为500ms);
4、组合按键:两个以上按键同时按住;
asp.net获取站点根目录下子目录的名称
hvt
.net C# asp.net hovertree Web Forms
使用Visual Studio建立一个.aspx文件(Web Forms),例如hovertree.aspx,在页面上加入一个ListBox代码如下:
<asp:ListBox runat="server" ID="lbKeleyiFolder" />
那么在页面上显示根目录子文件夹的代码如下:
string[] m_sub
Eclipse程序员要掌握的常用快捷键
justjavac
java eclipse 快捷键 ide
判断一个人的编程水平,就看他用键盘多,还是鼠标多。用键盘一是为了输入代码(当然了,也包括注释),再有就是熟练使用快捷键。 曾有人在豆瓣评
《卓有成效的程序员》:“人有多大懒,才有多大闲”。之前我整理了一个
程序员图书列表,目的也就是通过读书,让程序员变懒。 写道 程序员作为特殊的群体,有的人可以这么懒,懒到事情都交给机器去做,而有的人又可
c++编程随记
lx.asymmetric
C++ 笔记
为了字体更好看,改变了格式……
&&运算符:
#include<iostream>
using namespace std;
int main(){
int a=-1,b=4,k;
k=(++a<0)&&!(b--
linux标准IO缓冲机制研究
音频数据
linux
一、什么是缓存I/O(Buffered I/O)缓存I/O又被称作标准I/O,大多数文件系统默认I/O操作都是缓存I/O。在Linux的缓存I/O机制中,操作系统会将I/O的数据缓存在文件系统的页缓存(page cache)中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。1.缓存I/O有以下优点:A.缓存I/O使用了操作系统内核缓冲区,
随想 生活
暗黑小菠萝
生活
其实账户之前就申请了,但是决定要自己更新一些东西看也是最近。从毕业到现在已经一年了。没有进步是假的,但是有多大的进步可能只有我自己知道。
毕业的时候班里12个女生,真正最后做到软件开发的只要两个包括我,PS:我不是说测试不好。当时因为考研完全放弃找工作,考研失败,我想这只是我的借口。那个时候才想到为什么大学的时候不能好好的学习技术,增强自己的实战能力,以至于后来找工作比较费劲。我
我认为POJO是一个错误的概念
windshome
java POJO 编程 J2EE 设计
这篇内容其实没有经过太多的深思熟虑,只是个人一时的感觉。从个人风格上来讲,我倾向简单质朴的设计开发理念;从方法论上,我更加倾向自顶向下的设计;从做事情的目标上来看,我追求质量优先,更愿意使用较为保守和稳妥的理念和方法。
&