数据层的多租户综述
多租户(Multi Tenancy/Tenant)是一种软件架构,其定义是:
在一台服务器上运行单个应用实例,它为多个租户提供服务。
在SaaS实施过程中,有一个显著的考量点,就是如何对应用数据进行设计,以支持多租户,而这种设计的思路,是要在数据的共享、安全隔离和性能间取得平衡。
传统的应用,仅仅服务于单个租户,数据库多部署在企业内部网络环境,对于数据拥有者来说,这些数据是自己“私有”的,它符合自己所定义的全部安全标准。而在云计算时代,随着应用本身被放到云端,导致数据层也经常被公开化,但租户对数据安全性的要求,并不因之下降。同时,多租户应用在租户数量增多的情况下,会比单租户应用面临更多的性能压力。本文即对这个主题进行探讨:多租户在数据层的框架如何在共享、安全与性能间进行取舍,同时了解一下市面上一些常见的数据厂商怎样实现这部分内容。
常见的三种模式
在 MSDN 的这篇文章 Multi-Tenant Data Architecture 中,系统的总结了数据层的三种多租户架构:
独立数据库
共享数据库、独立 Schema
共享数据库、共享 Schema、共享数据表
独立数据库是一个租户独享一个数据库实例,它提供了最强的分离度,租户的数据彼此物理不可见,备份与恢复都很灵活;共享数据库、独立 Schema 将每个租户关联到同一个数据库的不同 Schema,租户间数据彼此逻辑不可见,上层应用程序的实现和独立数据库一样简单,但备份恢复稍显复杂; 最后一种模式则是租户数据在数据表级别实现共享,它提供了最低的成本,但引入了额外的编程复杂性(程序的数据访问需要用 tenantId 来区分不同租户),备份与恢复也更复杂。这三种模式的特点可以用一张图来概括:
图 1. 三种部署模式的异同
上图所总结的是一般性的结论,而在常规场景下需要综合考虑才能决定那种方式是合适的。例如,在占用成本上,认为独立数据库会高,共享模式较低。但如果考虑到大租户潜在的数据扩展需求,有时也许会有相反的成本耗用结论。
而多租户采用的选择,主要是成本原因,对于多数场景而言,共享度越高,软硬件资源的利用效率更好,成本也更低。但同时也要解决好租户资源共享和隔离带来的安全与性能、扩展性等问题。毕竟,也有客户无法满意于将数据与其他租户放在共享资源中。
目前市面上各类数据厂商在多租户的支持上,大抵都是遵循上文所述的这几类模式,或者混合了几种策略,这部分内容将在下面介绍。
JPA Provider
JSR 338 定义了 JPA 规范 2.1,但如我们已经了解到的,Oracle 把多租户的多数特性推迟到了 Java EE 8 中。尽管这些曾经在 JavaOne 大会中有过演示,但无论是在 JPA 2.0(JSR 317)还是 2.1 规范中,都依然没有明文提及多租户。不过这并不妨碍一些 JPA provider 在这部分领域的实现,Hibernate 和 EclipseLink 已提供了全部或部分的多租户数据层的解决方案。
Hibernate 是当今最为流行的开源的对象关系映射(ORM)实现,并能很好地和 Spring 等框架集成,目前 Hibernate 支持多租户的独立数据库和独立 Schema 模式。EclipseLink 也是企业级数据持久层JPA标准的参考实现,对最新 JPA2.1 完整支持,在目前 JPA 标准尚未引入多租户概念之际,已对多租户支持完好,其前身是诞生已久、功能丰富的对象关系映射工具 Oracle TopLink。因此本文采用 Hibernate 和 EclipseLink 对多租户数据层进行分析。
Hibernate
Hibernate 是一个开放源代码的对象/关系映射框架和查询服务。它对 JDBC 进行了轻量级的对象封装,负责从 Java 类映射到数据库表,并从 Java 数据类型映射到 SQL 数据类型。在 4.0 版本 Hibenate 开始支持多租户架构——对不同租户使用独立数据库或独立 Sechma,并计划在 5.0 中支持共享数据表模式。
在 Hibernate 4.0 中的多租户模式有三种,通过 hibernate.multiTenancy 属性有下面几种配置:
NONE:非多租户,为默认值。
SCHEMA:一个租户一个 Schema。
DATABASE:一个租户一个 database。
DISCRIMINATOR:租户共享数据表。计划在 Hibernate5 中实现。
模式1:独立数据库
如果是独立数据库,每个租户的数据保存在物理上独立的数据库实例。JDBC 连接将指向具体的每个数据库,一个租户对应一个数据库实例。在 Hibernate 中,这种模式可以通过实现 MultiTenantConnectionProvider 接口或继承 AbstractMultiTenantConnectionProvider 类等方式来实现。三种模式中它的共享性最低,因此本文重点讨论以下两种模式。
模式 2:共享数据库,独立 Schema
对于共享数据库,独立 Schema。所有的租户共享一个数据库实例,但是他们拥有独立的 Schema 或 Catalog,本文将以多租户酒店管理系统为案例说明 Hibernate 对多租户的支持和用使用方法。
图 2. guest 表结构
这是酒店客户信息表,我们仅以此表对这种模式进行说明,使用相同的表结构在 MySQL 中创建 DATABASE hotel_1 和 hotel_2。基于 Schema 的多租户模式,需要在 Hibernate 配置文件 Hibernate.cfg.xml 中设置 hibernate.multiTenancy 等相关属性。
清单 1. 配置文件 Hibernate.cfg.xml
jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
root
com.mysql.jdbc.Driver
org.hibernate.dialect.MySQLInnoDBDialect
false
false
false
SCHEMA
hotel.dao.hibernate.TenantIdResolver
hotel.dao.hibernate.SchemaBasedMultiTenantConnectionProvider
属性规定了一个合约,以使 Hibernate 能够解析出应用当前的 tenantId,该类必须实现 CurrentTenantIdentifierResolver 接口,通常我们可以从登录信息中获得 tenatId。
清单 2. 获取当前 tenantId
public class TenantIdResolver implements CurrentTenantIdentifierResolver {
public String resolveCurrentTenantIdentifier() {
return Login.getTenantId();
}
}
< hibernate.multi_tenant_connection_provider> 属性指定了 ConnectionProvider,即 Hibernate 需要知道如何以租户特有的方式获取数据连接,SchemaBasedMultiTenantConnectionProvider 类实现了MultiTenantConnectionProvider 接口,根据 tenantIdentifier 获得相应的连接。在实际应用中,可结合使用 JNDI DataSource 技术获取连接以提高性能。
清单 3. 以租户特有的方式获取数据库连接
public class SchemaBasedMultiTenantConnectionProvider
implements MultiTenantConnectionProvider, Stoppable,
Configurable, ServiceRegistryAwareService {
private final DriverManagerConnectionProviderImpl connectionProvider
= new DriverManagerConnectionProviderImpl();
@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
final Connection connection = connectionProvider.getConnection();
connection.createStatement().execute("USE " + tenantIdentifier);
return connection;
}
@Override
public void releaseConnection(String tenantIdentifier, Connection connection)
throws SQLException {
connection.createStatement().execute("USE test");
connectionProvider.closeConnection(connection);
}
……
}
与表 guest 对应的 POJO 类 Guest,其中主要是一些 getter 和 setter方法。
清单 4. POJO 类 Guest
@Table(name = "guest")
public class Guest {
private Integer id;
private String name;
private String telephone;
private String address;
private String email;
//getters and setters
……
}
我们使用 ServiceSchemaBasedMain.java 来进行测试,并假设了一些数据以方便演示,如当有不同租户的管理员登录后分别进行添加客户的操作。
清单 5. 测试类 ServiceSchemaBasedMain
public class ServiceSchemaBasedMain {
public static void main(String[] args) {
Session session = null;
Guest guest =null;
List list = null;
Transaction tx = null;
System.out.println("======== 租户 hotel_1 ========");
Login.setTenantId("hotel_1");
session = sessionFactory.openSession();
tx = session.beginTransaction();
guest = new Guest();
guest.setName("张三");
guest.setTelephone("56785678");
guest.setAddress("上海市张扬路88号");
guest.setEmail("[email protected] ");
session.saveOrUpdate(guest);
list = session.createCriteria(Guest.class).list();
for (Guest gue : list) {
System.out.println(gue.toString());
}
tx.commit();
session.close();
System.out.println("======== 租户 hotel_2 ========");
Login.setTenantId("hotel_2");
session = sessionFactory.openSession();
tx = session.beginTransaction();
guest = new Guest();
guest.setName("李四");
guest.setTelephone("23452345");
guest.setAddress("上海市南京路100号");
guest.setEmail("[email protected] ");
session.saveOrUpdate(guest);
list = session.createCriteria(Guest.class).list();
for (Guest gue : list) {
System.out.println(gue.toString());
}
tx.commit();
session.close();
}
}
清单 6. 运行程序 ServiceSchemaBasedMain 的输出
======== 租户 hotel_1 ========
Guest [id=1, name=Victor, telephone=56008888, address=上海科苑路399号, [email protected] ]
Guest [id=2, name=Jacky, telephone=66668822, address=上海金科路28号, [email protected] ]
Guest [id=3, name=张三, telephone=56785678, address=上海市张扬路88号, [email protected] ]
======== 租户 hotel_2 ========
Guest [id=1, name=Anton, telephone=33355566, address=上海南京路8号, [email protected] ]
Guest [id=2, name=Gus, telephone=33355566, address=北京大道3号, [email protected] ]
Guest [id=3, name=李四, telephone=23452345, address=上海市南京路100号, [email protected] ]
模式3:共享数据库、共享 Schema、共享数据表
在这种情况下,所有租户共享数据表存放数据,不同租户的数据通过 tenant_id 鉴别器来区分。但目前的 Hibernate 4 还不支持这个多租户鉴别器策略,要在 5.0 才支持。但我们是否有可选的替代方案呢?答案是使用 Hibernate Filter.
为了区分多个租户,我在 Schema 的每个数据表需要添加一个字段 tenant_id 以判定数据是属于哪个租户的。
图 3. 共享 Schema、共享数据表案例 E-R 图
根据上图在 MySQL 中创建 DATABASE hotel。
我们在 OR-Mapping 配置文件中使用了 Filter,以便在进行数据查询时,会根据 tenant_id 自动查询出该租户所拥有的数据。
清单 7. 对象关系映射文件 Room.hbm.xml
接下来我们在 HibernateUtil 类中通过 ThreadLocal 存放和获取 Hibernate Session,并将用户登录信息中的 tenantId 设置为 tenantFilterParam 的参数值。
清单 8. 获取 Hibernate Session 的工具类 HibernateUtil
不过 Filter 只是有助于我们读取数据时显示地忽略掉 tenantId,但在进行数据插入的时候,我们还是不得不显式设置相应 tenantId 才能进行持久化。这种状况只能在 Hibernate5 版本中得到根本改变。
清单 9. 运行程序 HotelServiceMain 输出
多租户下的 Hibernate 缓存
基于独立 Schema 模式的多租户实现,其数据表无需额外的 tenant_id。通过 ConnectionProvider 来取得所需的 JDBC 连接,对其来说一级缓存(Session 级别的缓存)是安全的可用的,一级缓存对事物级别的数据进行缓存,一旦事物结束,缓存也即失效。但是该模式下的二级缓存是不安全的,因为多个 Schema 的数据库的主键可能会是同一个值,这样就使得 Hibernate 无法正常使用二级缓存来存放对象。例如:在 hotel_1 的 guest 表中有个 id 为 1 的数据,同时在 hotel_2 的 guest 表中也有一个 id 为 1 的数据。通常我会根据 id 来覆盖类的 hashCode() 方法,这样如果使用二级缓存,就无法区别 hotel_1 的 guest 和 hote_2 的 guest。
在共享数据表的模式下的缓存, 可以同时使用 Hibernate的一级缓存和二级缓存, 因为在共享的数据表中,主键是唯一的,数据表中的每条记录属于对应的租户,在二级缓存中的对象也具有唯一性。Hibernate 分别为 EhCache、OSCache、SwarmCache 和 JBossCache 等缓存插件提供了内置的 CacheProvider 实现,读者可以根据需要选择合理的缓存,修改 Hibernate 配置文件设置并启用它,以提高多租户应用的性能。
EclipseLink
EclipseLink 是 Eclipse 基金会管理下的开源持久层服务项目,为 Java 开发人员与各种数据服务(比如:数据库、web services、对象XML映射(OXM)、企业信息系统(EIS)等)交互提供了一个可扩展框架,目前支持的持久层标准中包括:
Java Persistence API (JPA)
Java Architecture for XML Binding (JAXB)
Java Connector Architecture (JCA)
Service Data Objects (SDO)
EclipseLink 前身是 Oracle TopLink, 2007年 Oracle 将后者绝大部分捐献给了 Eclipse 基金会,次年 EclipseLink 被 Sun 挑选成为 JPA 2.0 的参考实现。
注: 目前 EclipseLink2.5 完全支持 2013 年发布的 JPA2.1(JSR 338) 。
在完整实现 JPA 标准之外,针对 SaaS 环境,在多租户的隔离方面 EclipseLink 提供了很好的支持以及灵活地解决方案。
应用程序隔离
隔离的容器/应用服务器
共享容器/应用服务器的应用程序隔离
同一应用程序内的共享缓存但隔离的 entity manager factory
共享的 entity manager factory 但每隔离的 entity manager
数据隔离
隔离的数据库
隔离的Schema/表空间
隔离的表
共享表但隔离的行
查询过滤
Oracle Virtual Private Database (VPD)
对于多租户数据源隔离主要有以下方案
Single-Table Multi-tenancy ,依靠租户区分列(tenant discriminator columns)来隔离表的行,实现多租户共享表。
Table-Per-Tenant Multi-tenancy ,依靠表的租户区分(table tenant discriminator)来隔离表,实现一租户一个表,大体类似于上文的共享数据库独立Schema模式。
Virtual Private Database(VPD ) Multi-tenancy ,依靠 Oracle VPD 自身的安全访问策略(基于动态SQL where子句特性),实现多租户共享表。
本节重点介绍多租户在 EclipseLink 中的共享数据表和一租户一个表的实现方法,并也以酒店多租户应用的例子展现共享数据表方案的具体实践。
EclipseLink Annotation @Multitenant
与 @Entity 或 @MappedSuperclass 一起使用,表明它们在一个应用程序中被多租户共享, 如清单 10。
清单10. @Multitenant
@Entity
@Table(name="room")
@Multitenant
...
publicclass Room {
}
表 1. Multitenant 包含两个属性
Annotation 属性
描述
缺省值
boolean includeCriteria
是否将租户限定应用到 select、update、delete 操作上
true
MultitenantType value
多租户策略,SINGLE_TABLE, TABLE_PER_TENANT, VPD.
SINGLE_TABLE
共享数据表(SINGLE_TABLE)
Metadata配置
依靠租户区分列修饰符 @TenantDiscriminatorColumn
实现。
清单11. @TenantDiscriminatorColumn
@Entity
@Table(name="hotel_guest")
@Multitenant(SINGLE_TABLE)
@TenantDiscriminatorColumn(name="tenant_id", contextProperty="tenant.id")
publicclass HotelGuest {
}
或者在EclipseLink描述文件orm.xml定义对象与表映射时进行限制,两者是等价的。
清单12. orm.xml
属性配置
租户区分列定义好后,在运行时环境需要配置具体属性值,以确定当前操作环境所属的租户。
三种方式的属性配置,按优先生效顺序排序如下
EntityManager(EM)
EntityManagerFactory(EMF)
Application context (when in a Java EE container)
例如 EntityManagerFactory 可以间接通过在 persistence.xml 中配置持久化单元(Persistence Unit)或直接传属性参数给初始化时 EntityManagerFactory。
清单 13. 配置 persistence.xml
或者
清单 14. 初始化 EntityManagerFactory
按共享粒度可以作如下区分,
用户需要通过 eclipselink.session-name 提供独立的会话名,确保每个租户占有独立的会话和缓存。
清单 15. 为 EntityManagerFactory 配置会话名
共享的 EntityManagerFactory 级别
EntityManagerFactory 的默认模式, 此级别缺省配置为独立二级缓存(L2 cache), 即每个 mutlitenant 实体缓存设置为 ISOLATED,用户也可设置 eclipselink.multitenant.tenants-share-cache 属性为真以共享,此时多租户 Entity 缓存设置为 PROTECTED。
这种级别下,一个活动的 EntityManager 不能更换 tenantId。
这种级别下,共享 session,共享 L2 cache, 用户需要自己设置缓存策略,以设置哪些租户信息是不能在二级缓存共享的。
清单 16. 设置缓存
同样,一个活动的EntityManager不能更换tenant ID。
几点说明:
每个表的区分列可以有任意多个,使用修饰符 TenantDiscriminatorColumns。
清单 17. 多个分区列
@TenantDiscriminatorColumns({
@TenantDiscriminatorColumn(name="tenant_id", contextProperty="tenant.id"),
@TenantDiscriminatorColumn(name = "guest_id", contextProperty="guest.id")
})
租户区分列的名字和对应的上下文属性名可以取任意值,由应用程序开发者设定。
生成的 Schema 可以也可以不包含租户区分列,如 tenant_id 或 guest_id。
租户区分列可以映射到实体对象也可以不。
注意:当映射的时候,实体对象相应的属性必须标记为只读(insertable=false, updatable=false),这种限制使得区分列不能作为实体表的 identifier。
TenantDiscriminatorColumn
被以下 EntityManager 的操作和查询支持:
persist,find,refresh,named queries,update all,delete all 。
一租户一表(TABLE_PER_TENANT )
这种多租户类型使每个租户的数据可以占据专属它自己的一个或多个表,多租户间的这些表可以共享相同 Schema 也可使用不同的,前者使用前缀(prefix)或后缀(suffix)命名模式的表的租户区分符,后者使用租户专属的 Schema 名来定义表的租户区分符。
Metadata配置
依靠数据表的租户区分修饰符 @TenantTableDiscriminator
实现
清单 18.
@Entity
@Table(name=“CAR”)
@Multitenant(TABLE_PER_TENANT)
@TenantTableDiscriminator(type=SCHEMA, contextProperty="eclipselink-tenant.id")
public class Car{
}
或
清单 19.
如前所述,TenantTableDiscriminatorType
有 3 种类型:SCHEMA、SUFFIX 和 PREFIX。
属性配置
与另外两种多租户类型一样,默认情况下,多租户共享EMF,如不想共享 EMF,可以通过配置 PersistenceUnitProperties.MULTITENANT_SHARED_EMF 以及 PersistenceUnitProperties.SESSION_NAME 实现。
清单 20.
或在 persistence.xml 配置属性。
酒店多租户应用实例(EclipseLink 共享(单)表)
数据库 Schema 和测试数据与上文 Hibernate 实现相同,关于对象关系映射(OR mapping)的配置均采用 JPA 和 EclipseLink 定义的 Java Annotation 描述。
关于几个基本操作
添加一个对象实例, 利用EntityManager.persist()
清单 21. 添加
public void save(T t) {
em.persist(t);
}
public void saveBulk(List bulk) {
for(T t:bulk){
em.persist(t);
}
}
更新一个对象实例, 利用EntityManager.merge()
清单 22. 更新
public void update(T t){
em.merge(t);
}
查询, 利用EntityManager的NamedQuery,
清单 23. 多条件多结果查询
若用 JPQL 实现则示例如下:
清单 24. JPQL NamedQuery 定义
部分测试数据如下(MySQL):
hotel_admin
hotel_guest
room
运行附件 MT_Test_Hotels.zip 中的测试代码(请参照 readme)来看看多租户的一些典型场景。
清单 25. 运行测试代码
能得到输出片段如下:
清单 26. 输出
通过共享表的测试数据以及运行结果可以看到,对于多个不同的租户(hotel_admin),在添加、查找、更新操作没有显示声明租户标识的情况下,EntityManager 可以根据自身的租户属性配置
实现租户分离。在本实例,EntityManager 初始化时利用到 hotel_admin 登录后的会话上下文进行租户判断,这里不再赘述。
注:上文中提及的全部源码都可以在附件中找到。
其它方面的考虑
数据备份
独立数据库和独立Sechma的模式,为每个租户备份数据比较容易,因为他们存放在不同的数据表中,只需对整个数据库或整个Schema进行备份。
在共享数据表的模式下,可以将所有租户的数据一起备份,但是若要为某一个租户或按租户分开进行数据备份,就会比较麻烦。通常需要另外写sql脚本根据tenant_id来取得对应的数据然后再备份,但是要按租户来导入的话依然比较麻烦,所以必要时还是需要备份所有并为以后导入方便。
性能
独立数据库:性能高,但价格也高,需要占用资源多,不能共享,性价比低。
共享数据库,独立 Schema:性能中等,但价格合适,部分共享,性价比中等。
共享数据库,共享 Schema,共享数据表:性能中等(可利用 Cache 可以提高性能),但价格便宜,完全共享,性价比高。如果在某些表中有大量的数据,可能会对所有租户产生性能影响。
对于共享数据库的情况下,如果因为太多的最终用户同时访问数据库而导致应用程序性能问题,可以考虑数据表分区等数据库端的优化方案。
经济考虑
为了支持多租户应用,共享模式的应用程序往往比使用独立数据库模式的应用程序相对复杂,因为开发一个共享的架构,导致在应用设计上得花较大的努力,因而初始成本会较高。然而,共享模式的应用在运营成本上往往要低一些,每个租户所花的费用也会比较低。
结束语
多租户数据层方案的选择是一个综合的考量过程,包括成本、数据隔离与保护、维护、容灾、性能等。但无论怎样选择,OR-Mapping 框架对多租户的支持将极大的解放开发人员的工作,从而可以更多专注于应用逻辑。最后我们以一个 Hibernate 和 EclipseLink 的比较来结束本文。
表 2. Hibernate 与 EclipeLink 对多租户支持的比较
Hibernate
EclipseLink
独立数据库
支持,通过实现 MultiTenantConnectionProvider 接口以连接独立的数据库
支持,为每个租户配置独立的 EntityManagerFactory
共享数据库,独立 Schema
支持,通过实现 MultiTenantConnectionProvider 接口以切换 Schema
支持,使用 TABLE_PER_TENANT MultitenantType 以及 SCHEMA TenantTableDiscriminatorType
共享数据库,共享 Schema,共享数据表
多租户 Discriminator 计划在 Hibernate 5.0 支持
支持, 使用 SINGLE_TABLE MultitenantType 以及 TenantDiscriminatorColumn
你可能感兴趣的:(云计算,java)
华为OD-不限经验,急招,机考资料,面试攻略,不过改推,捞人
2301_79125642
java
超星(学习通)-Java后端一面网易互娱40min(感觉是G了)一篇不太像面经的面经2023总结,前端大二上进小红书秋招面经第一波海康红外图像算法实习(微影)面经测试工程师社招-测试面试题大厂在职傻屌。TPlink图像算法工程师一二三面经深圳海康红外图像算法实习(微影)面经TPLink提前批面经(已OC)传统车辆转规控算法岗秋招记录腾讯TEG测试与质量管理全记录瑞幸Java开发校招一面腾讯金融科技
希音(Shein)前端开发面试题集锦和参考答案
大模型大数据攻城狮
arcgis webpack 前端攻击 xss csrf react 前端面试
用Node写过什么工具或npm包在实际开发中,使用Node编写过多种实用工具和npm包。自动化构建工具开发了一个简单的自动化构建工具,用于处理前端项目的资源压缩和合并。在前端项目中,为了优化性能,需要对CSS和JavaScript文件进行压缩,减少文件体积,同时将多个小文件合并成一个大文件,减少HTTP请求。这个工具使用Node的fs模块进行文件的读写操作,通过terser库对JavaScript
【华为OD机试真题E卷】54、统一限载货物数最小值 | 机试真题+思路参考+代码解析(C++、Java、Py)
KFickle
Java Py) 华为od c++ java 华为OD机试真题 统一限载货物数最小值
文章目录一、题目题目描述输入输出样例1样例2二、代码与思路参考C++代码Java代码Python代码订阅本专栏后即可解锁在线OJ刷题权限个人博客首页:KFickle专栏介绍:最新的华为OD机试真题D、E卷,每题都使用C++,Java,Python语言进行解答,每个题目的思路分析都非常详细,持续更新,支持在线OJ刷题,订阅后评论获取权限,有代码问题随时解答,代码仅供学习参考一、题目题目描述火车站附近
迎接AI挑战:Java程序员的技能进化与发展趋势!!!
小南AI学院
人工智能 java 开发语言
1.AI时代,JAVA程序员编码方式的发展趋势在AI时代,JAVA程序员编码方式的发展趋势正在经历显著变化。以下是几个主要发展方向:AI辅助编码工具的普及:像GitHubCopilot、AmazonCodeWhisperer和JetBrainsAIAssistant等工具正在帮助Java开发者更快地编写代码,自动完成常见模式和解决方案。这些工具不仅提供代码补全,还能生成函数、类甚至完整的实现。声明
Java中获取日期区间中所有日期
知行02
Java相关 日期处理 LocalDate 时间区间 Java 日期遍历
1.获取传入日期区间中所有日期1.代码演示/***根据传入的日期,获取时间区间中所有的日期**@paramstartDate开始日期*@paramendDate结束日期*@returnjava.util.List*@since2022/3/2*/@TestpublicstaticListgetAllDatesInTheDateRange(LocalDatestartDate,LocalDateen
java.util中的Scanner类
鼬猿
java 开发语言 intellij-idea
Scanner类可以用于从各种来源(如标准输入、文件、字符串等)读取不同类型的数据。它提供了各种方法来解析和提取输入的数据,并将其转换为相应的数据类型。在使用Scanner之前,需要先通过import语句导入java.util.Scanner类。创建了一个Scanner对象并传入System.in作为输入源,表示从标准输入中读取数据。例:Scanner变量名=newScanner(System.i
【华为OD技术面试手撕真题】113、组合总和 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)
KJ.JK
华为OD技术面试手撕真题 华为od 面试 c语言 华为od机试E卷 华为od机试真题 组合总和
文章目录一、题目题目描述样例1二、代码参考C语言思路C语言代码C++语言思路C++代码Java语言思路Java代码Python语言思路Python代码JS语言思路JS代码作者:KJ.JK个人博客首页:KJ.JK专栏介绍:本专栏更新每年华为OD机试的高频手撕代码题,每个题目都会使用五种语言进行解答(C&C++&Java&Python&JS),思路分析都非常详细,争取实现最低的时间复杂度和高通过率,每
Java接口(3)与图书管理系统
风吹落叶3257
java 开发语言
抽象类与接口的区别1.抽象类包含普通类和抽象方法,子类可以直接调用普通类方法不用重写。接口包含抽象方法和全局变量。2.抽象类有各种权限,接口只有pubilc。3.子类使用抽象类用extend,使用接口用implement。4.一个抽象类可以实现若干个接口,接口不能继承抽象类,但是接口可以继承多个接口5.一个类只能继承一个抽象类,一个子类可以实现多个接口。Object类Object类没有父类,可以引
数据库事务,回滚到指定点 oracle java
xiaoyustudiowww
jvm java oracle
======oracle表sqlCREATETABLE"SMALL19RAIN"."R_TABLE_STU"("NAME"VARCHAR2(200BYTE),"AGE"NUMBER,"STU_ID"NUMBERNOTNULLENABLE,"DATARAIN"VARCHAR2(200BYTE))SEGMENTCREATIONIMMEDIATEPCTFREE10PCTUSED40INITRANS1MA
琴韵博主 —— 工具集
琴 韵
知识库 在线文档
CSDN猿如意_开发者工具箱CSDN开发助手ChromeChrome最新版离线下载internetdownloadmanager付费在线转换在线JSON字符串转Java实体类(JavaBean、Entity)在线MD5加密解密YAML、YML在线编辑器(格式化校验)在线图片转换成文字图片base64互转颜色转换颜色转换人民币大小写转换蛙蛙:英文字母大小写转换、文本工具汉字拼音在线转换Google翻
【Qt】Qt Widgets和QML(Qt Quick)开发界面的区别
£އއ昔年
qt 开发语言
Qt提供了两种主要的UI技术:QtWidgets和QML(QtQuick)。它们的核心区别主要体现在使用方式、架构、性能、开发难度和适用场景等方面。1.QtWidgetsvs.QML总体对比对比项QtWidgetsQML(QtQuick)语言C++(带QtUI库)QML+JavaScript(底层C++)渲染方式传统窗口系统控件(原生或模拟)基于OpenGL,使用GPU加速UI风格经典桌面UI(W
JAVA排序
荔枝吃吃
java 排序算法 算法
1.冒泡排序/***使用冒泡排序算法对整数数组进行排序*冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,*一次比较两个元素,如果它们的顺序错误就把它们交换过来*遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成*这个算法的名字由来是因为越小(或越大)的元素会经过交换慢慢“浮”到数列的顶端**@paramarr待排序的整数数组*/publicstaticvoidbubb
React 基础教程
阿贾克斯的黎明
前端 react.js 前端 前端框架
目录React基础教程一、React简介二、安装和设置三、创建第一个React组件(一)函数式组件(二)类组件四、渲染组件五、组件的属性和状态(一)属性(Props)(二)状态(State)六、组件的生命周期方法七、事件处理八、总结React是一个用于构建用户界面的JavaScript库。它以高效、灵活和可维护性而受到广泛的欢迎。本教程将介绍React的基础知识,帮助你快速上手React开发。一、
贪心算法-字符串数组能拼接出的最小字典序(java)
SP_1024
算法 贪心算法 算法 java
最小字典序的贪心算法题目描述贪心算法的解题思路贪心算法自定义比较器贪心算法暴力递归解法题目描述给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果贪心算法的解题思路首先我们很自然的能想到,遍历数组,比较数组中每一个元素,字典序越小的,就放前面.但这里右一个陷阱,比如ba和b两个字符串,b的字典序小于ba,如果拼成bba就错了,显然bab字典序更小
【无标题】Hollo world.Javascript
一一代码
python javascript
HelloWorld最简单JavaScript代码console.log("Hello,World!");变量和数据类型JavaScript中的变量声明和基本数据类型。```javascriptletname="Alice";//字符串constage=25;//数字letisStudent=true;//布尔值console.log(name,age,isStudent);```函数定义一个简单
HTML+CSS+javascript 轮播图
Paula-柒月拾
javascript html css 前端 html5
HTML,CSS和JavaScript可以用来创建轮播图。HTML用于构建网页的结构,所以您可以使用HTML来定义轮播图的各个部分,如图像和文本。CSS用于设计网页的外观,所以您可以使用CSS来设置轮播图的布局和样式。JavaScript用于控制网页的行为,所以您可以使用JavaScript来控制轮播图的功能,如自动播放和用户交互。下面是一个简单的HTMLCSSJavaScript轮播图的例子:H
Java 常见的面试题(MySql)
web18285997089
面试 学习路线 阿里巴巴 java mysql oracle
一、数据库的三范式是什么?**范式:**简言之就是,数据库设计对数据的存储性能,还有开发人员对数据的操作都有莫大的关系。所以建立科学的,规范的的数据库是需要满足一些规范的来优化数据数据存储方式。在关系型数据库中这些规范就可以称为范式。第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在
【2024年华为OD机试】 (C卷,100分)- 分配土地(JavaScript&Java & Python&C/C++)
妄北y
算法汇集笔记总结(保姆级) 华为od c语言 javascript python java
一、问题描述题目描述从前有个村庄,村民们喜欢在各种田地上插上小旗子,旗子上标识了各种不同的数字。某天,集体村民决定将覆盖相同数字的最小矩阵形的土地分配给村里做出巨大贡献的村民。请问此次分配土地,做出贡献的村民最大会分配多大面积?输入描述第一行输入m和n:m代表村子的土地的长。n代表土地的宽。第二行开始输入地图上的具体标识:旗子上的数字为1~500,未插旗子的土地用0标识。输出描述输出此次分配土地,
【第10天】给定一个字符 c ,要求转换成大写进行输出 | 初识ASCII码
执 梗
《Java入门100练》 c语言 java 算法 蓝桥杯 数据结构
本文已收录于专栏《Java入门一百例》学习指引序、专栏前言一、什么是ASCII?二、【例题2】2、解题思路3、模板代码4、代码解析三、【例题2】2、解题思路3、模板代码4、代码解析四、奇淫巧技五、推荐专栏六、课后习题序、专栏前言 本专栏开启,目的在于帮助大家更好的掌握学习Java,特别是一些Java学习者难以在网上找到系统地算法学习资料帮助自身入门算法,同时对于专栏内的内容有任何疑问都可在文章末
前端本地储存的方式汇总
懒羊羊我小弟
前端框架 javascript js 浏览器 web app 小程序
JavaScript本地存储是Web开发中用于在客户端存储数据的重要技术,以下是常见方式及其区别和应用场景:一、WEB浏览器本地存储方式及特点1.1储存方式1.Cookie存储容量:约4KB(每个域名)。生命周期:可设置过期时间;默认随会话结束失效。作用域:同源页面共享。访问方式:通过document.cookie读写,每次HTTP请求自动携带。特点:支持服务器端操作(通过HTTP头),但存储效率
心得分享:云端运营对零售业的全渠道拓展到底能起到多大作用?
Akamai中国
云计算 人工智能 网络 服务器 云服务 云计算 云平台 Akamai
印度领先的食品杂货零售平台FreshToHome在云计算方面找到了适合的合作伙伴,双方携手为业务开拓未来之路“AkamaiCloudComputing平台为我们提供了所需的灵活性,使我们能在进一步扩大业务的同时维持较低的成本。”──SaurabhOdhyan,FreshToHome消费者业务CTOFreshToHome成立于2015年,最初只有8名员工,如今已发展成为一家广受信赖的全渠道食品杂货零
【全开源】Java陪诊小程序医院陪护陪诊小程序APP源码
指间代码师
java 小程序 开发语言 微信开放平台 微信小程序 大数据
陪诊小程序医院陪护陪诊小程序是一种结合了医疗服务和便捷技术的创新工具,旨在为需要陪诊服务的患者提供全方位的支持和帮助。一、功能预约挂号:患者可以通过陪诊小程序直接预约挂号,选择适合的医生和就诊时间,避免了传统挂号方式的繁琐和耗时。陪诊服务:小程序提供陪诊员服务,陪诊员可以协助患者完成挂号、取药、缴费等流程,确保患者能够顺利就医。在线咨询:患者可以通过小程序与医生进行在线沟通,获取专业的医疗建议和健
java.lang.NoClassDefFoundError异常的正确解决方法
梅菊林
各种问题解决方案 java 开发语言
java.lang.NoClassDefFoundError是Java运行时环境中的一个错误,表明JVM在运行时尝试加载一个类的定义,但未能找到。这通常发生在编译时该类是可用的,但在运行时JVM的类路径(classpath)上却找不到这个类。此错误不同于ClassNotFoundException,后者通常在加载类时抛出,而NoClassDefFoundError则是在尝试定义类或其静态成员时抛出
【Py/Java/C++/C/JS/Go六种语言OD独家2024E卷真题】20天拿下华为OD笔试之【模拟】2024E-最大相连男生数【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 模拟 # 状态压缩 算法 java c++ c语言 华为od javascript python
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例输入输出解题思路代码代码一:分类写法pythonjavacppCNodejavaScriptGo代码二:合并写法pythonjavacppCNodejavaScriptGo*代码三:状态压缩写法pythonjavacppCNod
【Py/Java/C++/JS/Go五种语言【OD独家2024E卷真题】20天拿下华为OD笔试之【哈希表】2024E-猜字谜【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 哈希表 java c++ 华为od python 算法 leetcode
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳oj1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述备注示例一输入输出示例二输入输出解题思路谜面和谜底如何匹配暴力匹配所有谜底谜底库哈希表的构建代码解法一:哈希表预处理谜底pythonjavacppNodejavaScriptgo时空复杂度解法二:暴力匹配解(会超时)pythonja
【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【排序】2024E-VLAN资源池【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
# 模拟 最新华为OD真题 java c++ 华为od leetcode 算法 python
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明示例三输入输出说明解题思路用二元组表示区间删除某一元素后区间的变化将二元组形式转换回原形式代码pythonjavacpp时空复杂度华为OD算法/大厂面试高频题算法练习冲刺训练相关推荐阅读【华为OD
【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【模拟】2024E-靠谱的车【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 模拟 # 数学 java c++ 华为od 算法 python leetcode
可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出示例二输入输出示例三输入输出解题思路从A进制到九进制从九进制到十进制代码pythonjavacpp时空复杂度华为OD算法/大厂面试高频题算法练习冲刺训练相关推荐阅读【华为OD机考】2024D+E卷最全真题【完全原创题解
【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【模拟】2024D-学生重新排队【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 模拟 # 蒙特卡洛 java c++ 华为od leetcode 算法 python
有LeetCode算法/华为OD考试扣扣交流群可加948025485可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述备注示例一输入输出说明示例二输入输出说明解题思路数组预处理检查某个组是否已经排好队检查所有组是否已经排好队蒙特卡洛模拟框架单次蒙特卡洛模拟整体思路编号挑选优化组号区间优化单次蒙
【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【前缀和/固定滑窗】2024D-查找接口成功率最优时间段【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 前缀和 # 滑动窗口 算法 java c++ 华为od leetcode python
有LeetCode算法/华为OD考试扣扣交流群可加948025485可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路贪心思想将除法转换为乘法固定滑窗前缀和代码解法一:前缀和pythonjavacpp解法二:固定滑窗pythonjavacpp时空复杂
【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【贪心】2024D-有效子字符串【欧弟算法】全网注释最详细分类最全的华为OD真题题解
闭着眼睛学算法
最新华为OD真题 # 贪心 # 双指针 java c++ 华为od 算法 python 贪心 贪心算法
有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1336了解算法冲刺训练文章目录题目描述与示例题目输入输出描述示例一输入输出示例二输入输出解题思路代码pythonjavacpp时空复杂度华为OD算法/大厂面试高频题算法练习冲刺训练从2024年4月15号开始,OD机考全部配置为2024D卷。注意两个关键点:会遇到C
LeetCode[Math] - #66 Plus One
Cwind
java LeetCode 题解 Algorithm Math
原题链接:#66 Plus One
要求:
给定一个用数字数组表示的非负整数,如num1 = {1, 2, 3, 9}, num2 = {9, 9}等,给这个数加上1。
注意:
1. 数字的较高位存在数组的头上,即num1表示数字1239
2. 每一位(数组中的每个元素)的取值范围为0~9
难度:简单
分析:
题目比较简单,只须从数组
JQuery中$.ajax()方法参数详解
AILIKES
JavaScript jsonp jquery Ajax json
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。
type: 要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和 delete也可以使用,但仅部分浏览器支持。
timeout: 要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局
JConsole & JVisualVM远程监视Webphere服务器JVM
Kai_Ge
JVisualVM JConsole Webphere
JConsole是JDK里自带的一个工具,可以监测Java程序运行时所有对象的申请、释放等动作,将内存管理的所有信息进行统计、分析、可视化。我们可以根据这些信息判断程序是否有内存泄漏问题。
使用JConsole工具来分析WAS的JVM问题,需要进行相关的配置。
首先我们看WAS服务器端的配置.
1、登录was控制台https://10.4.119.18
自定义annotation
120153216
annotation
Java annotation 自定义注释@interface的用法 一、什么是注释
说起注释,得先提一提什么是元数据(metadata)。所谓元数据就是数据的数据。也就是说,元数据是描述数据的。就象数据表中的字段一样,每个字段描述了这个字段下的数据的含义。而J2SE5.0中提供的注释就是java源代码的元数据,也就是说注释是描述java源
CentOS 5/6.X 使用 EPEL YUM源
2002wmj
centos
CentOS 6.X 安装使用EPEL YUM源1. 查看操作系统版本[root@node1 ~]# uname -a Linux node1.test.com 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux [root@node1 ~]#
在SQLSERVER中查找缺失和无用的索引SQL
357029540
SQL Server
--缺失的索引
SELECT avg_total_user_cost * avg_user_impact * ( user_scans + user_seeks ) AS PossibleImprovement ,
last_user_seek ,
 
Spring3 MVC 笔记(二) —json+rest优化
7454103
Spring3 MVC
接上次的 spring mvc 注解的一些详细信息!
其实也是一些个人的学习笔记 呵呵!
替换“\”的时候报错Unexpected internal error near index 1 \ ^
adminjun
java “\替换”
发现还是有些东西没有刻子脑子里,,过段时间就没什么概念了,所以贴出来...以免再忘...
在拆分字符串时遇到通过 \ 来拆分,可是用所以想通过转义 \\ 来拆分的时候会报异常
public class Main {
/*
POJ 1035 Spell checker(哈希表)
aijuans
暴力求解--哈希表
/*
题意:输入字典,然后输入单词,判断字典中是否出现过该单词,或者是否进行删除、添加、替换操作,如果是,则输出对应的字典中的单词
要求按照输入时候的排名输出
题解:建立两个哈希表。一个存储字典和输入字典中单词的排名,一个进行最后输出的判重
*/
#include <iostream>
//#define
using namespace std;
const int HASH =
通过原型实现javascript Array的去重、最大值和最小值
ayaoxinchao
JavaScript array prototype
用原型函数(prototype)可以定义一些很方便的自定义函数,实现各种自定义功能。本次主要是实现了Array的去重、获取最大值和最小值。
实现代码如下:
<script type="text/javascript">
Array.prototype.unique = function() {
var a = {};
var le
UIWebView实现https双向认证请求
bewithme
UIWebView https Objective-C
什么是HTTPS双向认证我已在先前的博文 ASIHTTPRequest实现https双向认证请求
中有讲述,不理解的读者可以先复习一下。本文是用UIWebView来实现对需要客户端证书验证的服务请求,网上有些文章中有涉及到此内容,但都只言片语,没有讲完全,更没有完整的代码,让人困扰不已。但是此知
NoSQL数据库之Redis数据库管理(Redis高级应用之事务处理、持久化操作、pub_sub、虚拟内存)
bijian1013
redis 数据库 NoSQL
3.事务处理
Redis对事务的支持目前不比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中
各数据库分页sql备忘
bingyingao
oracle sql 分页
ORACLE
下面这个效率很低
SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT * FROM IPAY_RCD_FS_RETURN order by id desc) A ) WHERE RN <20;
下面这个效率很高
SELECT A.*, ROWNUM RN FROM (SELECT * FROM IPAY_RCD_
【Scala七】Scala核心一:函数
bit1129
scala
1. 如果函数体只有一行代码,则可以不用写{},比如
def print(x: Int) = println(x)
一行上的多条语句用分号隔开,则只有第一句属于方法体,例如
def printWithValue(x: Int) : String= println(x); "ABC"
上面的代码报错,因为,printWithValue的方法
了解GHC的factorial编译过程
bookjovi
haskell
GHC相对其他主流语言的编译器或解释器还是比较复杂的,一部分原因是haskell本身的设计就不易于实现compiler,如lazy特性,static typed,类型推导等。
关于GHC的内部实现有篇文章说的挺好,这里,文中在RTS一节中详细说了haskell的concurrent实现,里面提到了green thread,如果熟悉Go语言的话就会发现,ghc的concurrent实现和Go有点类
Java-Collections Framework学习与总结-LinkedHashMap
BrokenDreams
LinkedHashMap
前面总结了java.util.HashMap,了解了其内部由散列表实现,每个桶内是一个单向链表。那有没有双向链表的实现呢?双向链表的实现会具备什么特性呢?来看一下HashMap的一个子类——java.util.LinkedHashMap。
读《研磨设计模式》-代码笔记-抽象工厂模式-Abstract Factory
bylijinnan
abstract
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
package design.pattern;
/*
* Abstract Factory Pattern
* 抽象工厂模式的目的是:
* 通过在抽象工厂里面定义一组产品接口,方便地切换“产品簇”
* 这些接口是相关或者相依赖的
压暗面部高光
cherishLC
PS
方法一、压暗高光&重新着色
当皮肤很油又使用闪光灯时,很容易在面部形成高光区域。
下面讲一下我今天处理高光区域的心得:
皮肤可以分为纹理和色彩两个属性。其中纹理主要由亮度通道(Lab模式的L通道)决定,色彩则由a、b通道确定。
处理思路为在保持高光区域纹理的情况下,对高光区域着色。具体步骤为:降低高光区域的整体的亮度,再进行着色。
如果想简化步骤,可以只进行着色(参看下面的步骤1
Java VisualVM监控远程JVM
crabdave
visualvm
Java VisualVM监控远程JVM
JDK1.6开始自带的VisualVM就是不错的监控工具.
这个工具就在JAVA_HOME\bin\目录下的jvisualvm.exe, 双击这个文件就能看到界面
通过JMX连接远程机器, 需要经过下面的配置:
1. 修改远程机器JDK配置文件 (我这里远程机器是linux).
 
Saiku去掉登录模块
daizj
saiku 登录 olap BI
1、修改applicationContext-saiku-webapp.xml
<security:intercept-url pattern="/rest/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern=&qu
浅析 Flex中的Focus
dsjt
html Flex Flash
关键字:focus、 setFocus、 IFocusManager、KeyboardEvent
焦点、设置焦点、获得焦点、键盘事件
一、无焦点的困扰——组件监听不到键盘事件
原因:只有获得焦点的组件(确切说是InteractiveObject)才能监听到键盘事件的目标阶段;键盘事件(flash.events.KeyboardEvent)参与冒泡阶段,所以焦点组件的父项(以及它爸
Yii全局函数使用
dcj3sjt126com
yii
由于YII致力于完美的整合第三方库,它并没有定义任何全局函数。yii中的每一个应用都需要全类别和对象范围。例如,Yii::app()->user;Yii::app()->params['name'];等等。我们可以自行设定全局函数,使得代码看起来更加简洁易用。(原文地址)
我们可以保存在globals.php在protected目录下。然后,在入口脚本index.php的,我们包括在
设计模式之单例模式二(解决无序写入的问题)
come_for_dream
单例模式 volatile 乱序执行 双重检验锁
在上篇文章中我们使用了双重检验锁的方式避免懒汉式单例模式下由于多线程造成的实例被多次创建的问题,但是因为由于JVM为了使得处理器内部的运算单元能充分利用,处理器可能会对输入代码进行乱序执行(Out Of Order Execute)优化,处理器会在计算之后将乱序执行的结果进行重组,保证该
程序员从初级到高级的蜕变
gcq511120594
框架 工作 PHP android html5
软件开发是一个奇怪的行业,市场远远供不应求。这是一个已经存在多年的问题,而且随着时间的流逝,愈演愈烈。
我们严重缺乏能够满足需求的人才。这个行业相当年轻。大多数软件项目是失败的。几乎所有的项目都会超出预算。我们解决问题的最佳指导方针可以归结为——“用一些通用方法去解决问题,当然这些方法常常不管用,于是,唯一能做的就是不断地尝试,逐个看看是否奏效”。
现在我们把淫浸代码时间超过3年的开发人员称为
Reverse Linked List
hcx2013
list
Reverse a singly linked list.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
p
Spring4.1新特性——数据库集成测试
jinnianshilongnian
spring 4.1
目录
Spring4.1新特性——综述
Spring4.1新特性——Spring核心部分及其他
Spring4.1新特性——Spring缓存框架增强
Spring4.1新特性——异步调用和事件机制的异常处理
Spring4.1新特性——数据库集成测试脚本初始化
Spring4.1新特性——Spring MVC增强
Spring4.1新特性——页面自动化测试框架Spring MVC T
C# Ajax上传图片同时生成微缩图(附Demo)
liyonghui160com
1.Ajax无刷新上传图片,详情请阅我的这篇文章。(jquery + c# ashx)
2.C#位图处理 System.Drawing。
3.最新demo支持IE7,IE8,Fir
Java list三种遍历方法性能比较
pda158
java
从c/c++语言转向java开发,学习java语言list遍历的三种方法,顺便测试各种遍历方法的性能,测试方法为在ArrayList中插入1千万条记录,然后遍历ArrayList,发现了一个奇怪的现象,测试代码例如以下:
package com.hisense.tiger.list;
import java.util.ArrayList;
import java.util.Iterator;
300个涵盖IT各方面的免费资源(上)——商业与市场篇
shoothao
seo 商业与市场 IT资源 免费资源
A.网站模板+logo+服务器主机+发票生成
HTML5 UP:响应式的HTML5和CSS3网站模板。
Bootswatch:免费的Bootstrap主题。
Templated:收集了845个免费的CSS和HTML5网站模板。
Wordpress.org|Wordpress.com:可免费创建你的新网站。
Strikingly:关注领域中免费无限的移动优
localStorage、sessionStorage
uule
localStorage
W3School 例子
HTML5 提供了两种在客户端存储数据的新方法:
localStorage - 没有时间限制的数据存储
sessionStorage - 针对一个 session 的数据存储
之前,这些都是由 cookie 完成的。但是 cookie 不适合大量数据的存储,因为它们由每个对服务器的请求来传递,这使得 cookie 速度很慢而且效率也不