Java语言】mybatis的一级缓存和二级缓存有什么用,有什么区别?

2020-12-14 10:43发布

13条回答
小小李兆佳
2楼 · 2020-12-14 11:57

一级缓存:它指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域中,该区域的结构是一个Map,当我们再次查询同样的数据,mybatis会
先去sqlsession中查询是否有,的话直接拿出来用,当SqlSession对象消失时,mybatis的一级缓存也就消失了,同时一级缓存是SqlSession范围的缓存,当调用SqlSession的修改、添加、删除、commit(),close等
方法时,就会清空一级缓存。
  二级缓存:他值得是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存,但是其中缓存的是数据而不是对象,所以从二级缓存再次查询出得结果的对象与
第一次存入的对象是不一样的。

小猪仔
3楼 · 2020-12-14 13:47

一级缓存基于sqlSession默认开启,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域是互相不影响的。 
一级缓存的作用域是SqlSession范围的,当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存), 
第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。 
需要注意的是,如果SqlSession执行了DML操作(增删改),并且提交到数据库,MyBatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象。 
当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了。 
关闭一级缓存后,再次访问,需要再次获取一级缓存,然后才能查找数据,否则会抛出异常。 
二级缓存是mapper级别的缓存。使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。相比一级缓存SqlSession,二级缓存的范围更大,多个Sqlsession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存的作用域是mapper的同一个namespace。不同的sqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高效率。 
在MyBatis配置文件(mybatis-config.xml)中开启二级缓存(详细过程自己百度搜索开启) 
//value属性默认为false 
在**Mapper.xml中开启当前mapper的namespace下的二级缓存 
代表创建了一个LRU缓存,并每隔60秒刷新,最大存储512个对象,而且返回的对象被认为是只读的。 

evicition收回策略,默认是LRU

(1)LRU最近最少使用策略,一处做长时间不被使用的对象。 
(2)FIFO先进先出策略,按对象进入缓存的顺序来移除它们。 
(3)SOFT软引用策略,移除基于垃圾回收器状态和软引用规则的对象。 
(4)WEAK弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象

那些年很冒险的梦。
4楼 · 2020-12-14 14:16

一级缓存基于sqlSession默认开启,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域是互相不影响的。


一级缓存的作用域是SqlSession范围的,当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存),


第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。


需要注意的是,如果SqlSession执行了DML操作(增删改),并且提交到数据库,MyBatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象。


当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了。


关闭一级缓存后,再次访问,需要再次获取一级缓存,然后才能查找数据,否则会抛出异常。
二级缓存是mapper级别的缓存。使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。相比一级缓存SqlSession,二级缓存的范围更大,多个Sqlsession可以共用二级缓存,二级缓存是跨SqlSession的。


二级缓存的作用域是mapper的同一个namespace。不同的sqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高效率。
在MyBatis配置文件(mybatis-config.xml)中开启二级缓存(详细过程自己百度搜索开启)
//value属性默认为false
在**Mapper.xml中开启当前mapper的namespace下的二级缓存


代表创建了一个LRU缓存,并每隔60秒刷新,最大存储512个对象,而且返回的对象被认为是只读的。

evicition收回策略,默认是LRU

(1)LRU最近最少使用策略,一处做长时间不被使用的对象。
(2)FIFO先进先出策略,按对象进入缓存的顺序来移除它们。
(3)SOFT软引用策略,移除基于垃圾回收器状态和软引用规则的对象。
(4)WEAK弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象


我是大脸猫
5楼 · 2020-12-14 16:33

程序中为什么使用缓存?
  先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。对于我们编程来说,所谓的缓存,就是将程序
或系统经常要调用的对象(临时数据)存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统的开销,提高效率。
  对缓存有了一定的了解以后就知道了使用缓存是为了减少和数据库的交互次数,提高执行效率。那么下一个问题来了。什么样的数据能使用缓存,什么样的数据不能使用?
  这是我们使用缓存必须要明确的事情,实际上适用于缓存的数据:经常查询并且不经常改变的,并且的数据的正确与否对最终结果影响不大的、不适用于缓存的数据:经常改变的数据,数据的正确与否对最终
结果影响很大的。
  Mybatis中的一级缓存和二级缓存到底缓存了什么,缓存了以后又有什么效果,缓存的数据什么时候会被清空?
  一级缓存:它指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域中,该区域的结构是一个Map,当我们再次查询同样的数据,mybatis会
先去sqlsession中查询是否有,的话直接拿出来用,当SqlSession对象消失时,mybatis的一级缓存也就消失了,同时一级缓存是SqlSession范围的缓存,当调用SqlSession的修改、添加、删除、commit(),close等
方法时,就会清空一级缓存。
  二级缓存:他值得是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存,但是其中缓存的是数据而不是对象,所以从二级缓存再次查询出得结果的对象与
第一次存入的对象是不一样的。
  通过简单的例子来加深理解一级缓存和二级缓存。

 一级缓存

  1.用户类

复制代码

public class User implements Serializable{    private Integer id;    private String username;    private Date birthday;    private String sex;    private String address;
    
    get和set方法省略.....
}

复制代码

    2.Dao层

复制代码

public interface UserDao {    /**
     * 查询所有的用户
     *
     * @return
     */
    List findAll();    /**
     * 根据Id查询用户
     *
     * @return
     */
    User findById(Integer id);    /**
     * 更新用户
     * @param user     */
    void updateUser(User user);
}

复制代码

  3.UserDao.xml映射文件

复制代码


    
        SELECT * FROM USER;    
    
        SELECT * FROM  USER  WHERE ID = #{ID}    
    
        update USER        
            username=#{username},
            birthday=#{birthday},
            sex=#{sex},
            address=#{address},
        
        where id=#{id}    

复制代码

  在以上三步中这是mybatis的单表操作,下面通过根据用户ID查询用户的操作来观察一级缓存生效与否的区别  

  4.测试
    (1)  命中一级缓存的情况
    测试代码:

复制代码

@Test    public void findByIdTest(){
        session = factory.openSession();
        userDao = session.getMapper(UserDao.class);        //第一次获取该用户
        User user1 = userDao.findById(45);
        System.out.println(user1);
        第二次获取该用户
        User user2 = userDao.findById(45);
        System.out.println(user2);
        System.out.println(user1 == user2);
        session.close();
    }  

复制代码

测试结果:

  

  (2)对SqlSession进行清除缓存的操作,即清楚一级缓存,然后再次进行测试。

复制代码

 @Test    public void findByIdTest(){
        session = factory.openSession();
        userDao = session.getMapper(UserDao.class);
        User user1 = userDao.findById(45);
        System.out.println(user1); //       session.commit(); 调用SqlSession的commit方法清空缓存
        user1.setUsername("更新用户");
        user1.setAddress("更新地址");
        userDao.updateUser(user1);//通过更新SqlSession清空缓存
        User user2 = userDao.findById(45);
        System.out.println(user2);
        System.out.println(user1 == user2);
        session.close();
    }

复制代码

  清空缓存的操作很多,可以都试试。测试结果:

  二级缓存  

  再看一下Mybatis二级缓存是如何使用的,第一步让Mybatis框架支持二级缓存(在Mybatis的主配置文件中配置),第二步让当前的映射文件支持二级缓存(在Dao.xml映射文件中配置),第三步让当前的方法支持二级缓存(在标签中配置)。根据这个步骤将上面的查询用户的接口通过配置改造为可以支持二级缓存的方法。
  1.配置Mybatis框架支持二级缓存

  2.配置UserDao.xml支持二级缓存

 

  3.配置查询的方法支持二级缓存


        SELECT * FROM  USER  WHERE ID = #{ID}   

  4.测试

复制代码

@Test    public void findByIdTest(){        //第一次查询 并更新二级缓存
        SqlSession session1 = factory.openSession();
        UserDao userDao1 = session1.getMapper(UserDao.class);
        User user1 = userDao1.findById(45);
        System.out.println(user1);
        session1.commit(); //commit()方法提交二级缓存 同时清空一级缓存
        session1.close();////        user1.setUsername("更新用户");//        user1.setAddress("更新地址");//        userDao.updateUser(user1);//通过更新SqlSession清空缓存        //第二次查找命中二级缓存
        SqlSession session2 = factory.openSession();
        UserDao userDao2 = session2.getMapper(UserDao.class);
        User user2 = userDao2.findById(45);
        session2.commit(); //commit()方法提交二级缓存 同时清空一级缓存
        session2.close();//        System.out.println(user2);
        System.out.println(user1 == user2);
    }

复制代码

  测试结果:

 

 总结:mybatis的的一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。二级缓存是SqlSessionFactory级别的缓存,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构造对象返回。查询数据的时候,查询的流程是二级缓存>一级缓存>数据库


小小收藏家
6楼 · 2020-12-14 17:01

一级缓存基于sqlSession默认开启,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域是互相不影响的。 
一级缓存的作用域是SqlSession范围的,当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存), 
第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。 
需要注意的是,如果SqlSession执行了DML操作(增删改),并且提交到数据库,MyBatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象。 
当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了。 
关闭一级缓存后,再次访问,需要再次获取一级缓存,然后才能查找数据,否则会抛出异常。 
二级缓存是mapper级别的缓存。使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。相比一级缓存SqlSession,二级缓存的范围更大,多个Sqlsession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存的作用域是mapper的同一个namespace。不同的sqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高效率。 

武新雨 - 一个很酷的人。
7楼 · 2020-12-15 08:54

一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。


一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。


二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。


二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

如果缓存中有数据就不用从数据库中获取,大大提高系统性能。


八九
8楼 · 2020-12-15 09:46

一级缓存:

就是Session级别的缓存。一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中。

如果短时间内这个session(一定要同一个session)又做了同一个操作,那么hibernate直接从一级缓存中拿,而不会再去连数据库,取数据。

它是内置的事务范围的缓存,不能被卸载。

二级缓存:

就是SessionFactory级别的缓存。顾名思义,就是查询的时候会把查询结果缓存到二级缓存中。

如果同一个sessionFactory创建的某个session执行了相同的操作,hibernate就会从二级缓存中拿结果,而不会再去连接数据库。

这是可选的插件式的缓存,在默认情况下,SessionFactory不会启用这个插件。

可以在每个类或每个集合的粒度上配置。缓存适配器用于把具体的缓存实现与Hibernate集成。

严格意义上说,SessionFactory缓存分为两类:内置缓存和外置缓存。我们通常意义上说的二级缓存是指外置缓存。

内置缓存与session级别缓存实现方式相似。前者是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据

SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句。

映射元数据是映射文件中数据的拷贝;

而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来。

SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。

Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝。

缓存的两个特性:

缓存的范围

缓存的并发访问策略

1、缓存的范围

决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。

事务范围

进程范围

集群范围

注:

对大多数应用来说,应该慎重地考虑是否需要使用集群范围的缓存,因为访问的速度不一定会比直接访问数据库数据的速度快多少。

事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存,通常是可选的。

2、缓存的并发访问策略

当多个并发的事务同时访问持久化层的缓存的相同数据时,会引起并发问题,必须采用必要的事务隔离措施。

在进程范围或集群范围的缓存,即第二级缓存,会出现并发问题。

因此可以设定以下四种类型的并发访问策略,每一种策略对应一种事务隔离级别。

事务型并发访问策略是事务隔离级别最高,只读型的隔离级别最低。事务隔离级别越高,并发性能就越低。

A 事务型:仅仅在受管理环境中适用。它提供了Repeatable Read事务隔离级别。

对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。

B 读写型:提供了Read Committed事务隔离级别。仅仅在非集群的环境中适用。

对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。

C 非严格读写型:不保证缓存与数据库中数据的一致性。

如果存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。

对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。

D 只读型:对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。

什么样的数据适合存放到第二级缓存中?

1、很少被修改的数据

2、不是很重要的数据,允许出现偶尔并发的数据

3、不会被并发访问的数据

4、参考数据

不适合存放到第二级缓存的数据?

1、经常被修改的数据

2、财务数据,绝对不允许出现并发

3、与其他应用共享的数据。

Hibernate的二级缓存策略的一般过程如下:

1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。

2) 把获得的所有数据对象根据ID放入到第二级缓存中。

3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。

4) 删除、更新、增加数据的时候,同时更新缓存。

注:

Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询uery缓存。

Query缓存策略的过程如下:

1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。

2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。

3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关uery Key都要从缓存中清空。


py大白
9楼 · 2020-12-15 10:41

mybatis的一级缓存和二级缓存有什么用,有什么区别?

一级缓存基于sqlSession默认开启,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域是互相不影响的。 
一级缓存的作用域是SqlSession范围的,当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存), 
第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。 
需要注意的是,如果SqlSession执行了DML操作(增删改),并且提交到数据库,MyBatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象。 
当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了。 
关闭一级缓存后,再次访问,需要再次获取一级缓存,然后才能查找数据,否则会抛出异常。 
二级缓存是mapper级别的缓存。使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。相比一级缓存SqlSession,二级缓存的范围更大,多个Sqlsession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存的作用域是mapper的同一个namespace。不同的sqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高效率。 
在MyBatis配置文件(mybatis-config.xml)中开启二级缓存(详细过程自己百度搜索开启) 
//value属性默认为false 
在**Mapper.xml中开启当前mapper的namespace下的二级缓存 
代表创建了一个LRU缓存,并每隔60秒刷新,最大存储512个对象,而且返回的对象被认为是只读的。 

evicition收回策略,默认是LRU

(1)LRU最近最少使用策略,一处做长时间不被使用的对象。 
(2)FIFO先进先出策略,按对象进入缓存的顺序来移除它们。 
(3)SOFT软引用策略,移除基于垃圾回收器状态和软引用规则的对象。 
(4)WEAK弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象


相关问题推荐

  • 回答 7
    已采纳

    里氏代换原则(Liskov Substitution Principle, LSP):所有引用基类(父类)的地方必须能透明地使用其子类的对象里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一...

  • 回答 8
    已采纳

    心里有个预期,然后看看是以什么目的进这家企业工作,要是赚钱的话,那就多要点,要是学习的话,可以根据情况要一个能养活自己的价格。

  • 回答 4
    已采纳

    Java中有八种数据类型,基础数据类型分别是:byte,short,int,long,float,double,char,boolean,引用数据类型分别是:数组,类和接口。方法传参的时候我们有两种,一种是形式参数(定义方法时写的参数),一种是实际参数(调用方法时给的具体值)。首先...

  • 回答 15
    已采纳

    现在的架构很多,各种各样的,如高并发架构、异地多活架构、容器化架构、微服务架构、高可用架构、弹性化架构等,还有和这些架构相关的管理型的技术方法,如 DevOps、应用监控、自动化运维、SOA 服务治理、去 IOE 等等,还有很多。分布式架构其实就是分布式系...

  • 回答 10

    1、监控GC的状态使用各种JVM工具,查看当前日志,分析JVM参数的设置,分析堆内存快照和GC日志,根据实际的各区域的内存划分和GC的执行时间,判断是否需要进行优化2、分析结果、判断是否需要优化如果各项参数设置合理,系统没有超时的日志出现,GC频率也不高,...

  • 回答 6

    MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以...

  • 回答 6

    学vue应该要先学习javascript 的基础知识和用法。

  • 回答 8

    1、lambda是jdk8的新特性2、使用lambda的前提,必须是一个接口,接口只能有一个抽象方法3、Lambda 表达式的简单例子:// 1. 不需要参数,返回值为 5  () -> 5    // 2. 接收一个参数(数字类型),返回其2倍的值  x -> 2 * x    // 3. 接受2个参数(数...

  • 回答 5

    你没有把jdk配置到eclipse里,步骤如下:打开eclipse,菜单栏找到window -> preference -> java -> install jres -> add -> standard vm -> 设置好相应的jre home就可以了。

  • 回答 8

    使用场景:常规key-value缓存应用。常规计数: 微博数, 粉丝数。实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。...

  • 回答 11

    1. 区别:堆和栈区别堆:主要用于储存实例化的对象,数组。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的。栈:主要用于储存局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。2. 堆内存和栈内...

  • 回答 18

    至少h5、CSS、JS,包括数据库连接技术,ajax都要会哦

  • 回答 7

    对于一个秒杀系统来说,瞬时的大量请求会对后台服务造成冲击,需要保证服务的可用性以及业务的正确性。设计了一个高并发高可用的系统简要流程架构如下图:1.将商品(或券)的信息等静态数据放到cdn节点,实现动静分离2.业务请求和业务处理之间使用MQ对请求进行削...

  • 回答 16

    为了避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。未授权读取(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事...

  • 回答 10

    封装就是把抽象出来的JAVA类的变量和方法集成为一个集体,就像集成电路元件成为一个独立的芯片一样,它只留出对外的接口,使用者可以直接使用它,但看不到其内部是怎样实现的,JAVA类的封装就是对外而言能直接使用它来定义的对象去调用相关变量和方法。...

  • 回答 4

    1. java.awt:提供了绘图和图像类,主要用于编写GUI程序,包括按钮、标签等常用组件以及相应的事件类。2. java.lang:java的语言包,是核心包,默认导入到用户程序,包中有object类,数据类型包装类,数学类,字符串类,系统和运行时类,操作类,线程类,错...

没有解决我的问题,去提问