Java常见问题
- 一、Mybatis部分
- 1. 什么是 Mybatis?
- 2. Mybaits 的优点
- 3. MyBatis 框架的缺点
- 4. MyBatis 框架适用场合
- 5. MyBatis与Hibernate有哪些不同?
- 6. #{}和${}的区别是什么?
- 7. 当实体类中的属性名和表中的字段名不一样,怎么办?
- 8. 模糊查询 like 语句该怎么写?
- 9. 通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
- 10. Mybatis 是如何进行分页的?分页插件的原理是什么?
- 11. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 12. 如何执行批量插入?
- 13. 如何获取自动生成的(主)键值?
- 14. 在 mapper 中如何传递多个参数?
- 15. Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?
- 16. Xml 映射文件中,除了常见的 select | insert | updae | delete 标签之外,还有哪些标签?
- 17. Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
- 18. 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
- 19. 一对一、一对多的关联查询 ?
- 20. MyBatis 实现一对一有几种方式?具体怎么操作的?
- 21. MyBatis 实现一对多有几种方式,怎么操作的?
- 22. Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
- 23. Mybatis 的一级、二级缓存
- 24. 什么是 MyBatis 的接口绑定?有哪些实现方式?
- 24. 使用 MyBatis 的 mapper 接口调用时有哪些要求?
- 25. Mapper 编写有哪几种方式?
- 27. 简述 Mybatis 的插件运行原理,以及如何编写一个插件。
- 二、Zookeeper部分
- 三、Dubbo部分
- 四、Elasticsearch部分
- 五、Memcached部分
- 六、Redis部分
- 1. 什么是 Redis?
- 2. Redis 的数据类型?
- 3. 使用 Redis 有哪些好处?
- 4. Redis 相比 Memcache 有哪些优势?
- 5. Memcache 与 Redis 的区别都有哪些?
- 6. Redis 是单进程单线程的?
- 7. 一个字符串类型的值能存储最大容量是多少?
- 8. Redis 的持久化机制是什么?各自的优缺点?
- 9. Redis 常见性能问题和解决方案
- 10. redis 过期键的删除策略?
- 11. Redis 的回收策略(淘汰策略)?
- 12. 为什么 Redis 需要把所有数据放到内存中?
- 13. Redis 的同步机制了解么?
- 14. Pipeline 有什么好处,为什么要用 pipeline?
- 15. 是否使用过 Redis 集群,集群的原理是什么?
- 16. Redis 集群方案什么情况下会导致整个集群不可用?
- 17. Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
- 18. Jedis 与 Redisson 对比有什么优缺点?
- 19. Redis 如何设置密码及验证密码?
- 20. 说说 Redis 哈希槽的概念?
- 21. Redis 集群的主从复制模型是怎样的?
- 22. Redis 集群会有写操作丢失吗?为什么?
- 23. Redis 集群之间是如何复制的?
- 七、MySQL部分
- 八、Java并发编程1
- 九、Java并发编程2
- 十、Java基础1
- 十一、Java基础2
- 十二、Spring部分1
- 十三、Spring部分2
- 十四、微服务部分
- 十五、Linux部分
- 十六、SpringBoot部分
- 十七、SpringCloud部分
- 十八、RabbitMQ部分
- 十九、Kafka部分
一、Mybatis部分
1. 什么是 Mybatis?
Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。MyBatis可以使用XML或注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。- 通过
xml文件或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。
2. Mybaits 的优点
- 基于
SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供 XML标签,支持编写动态SQL语句,并可重用。 - 与
JDBC相比,减少了 50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接。 - 很好的与各种数据库兼容(因为
MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。 - 能够与
Spring很好的集成。 - 提供映射标签,支持对象与数据库的
ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
3. MyBatis 框架的缺点
SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
4. MyBatis 框架适用场合
MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。- 对性能的要求很高,或者需求变化较多的项目,如互联网项目,
MyBatis将是不错的选择。
5. MyBatis与Hibernate有哪些不同?
Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。
6. #{}和${}的区别是什么?
- #{}是预编译处理,${}是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。Mybatis在处理 时 , 就 是 把 {}时,就是把 时,就是把{}替换成变量的值。- 使用#{}可以有效的防止
SQL注入,提高系统安全性。
7. 当实体类中的属性名和表中的字段名不一样,怎么办?
- 通过在查询的
sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price
form orders
where order_id=#{id};
</select>
- 通过
<resultMap>来映射字段名和实体类属性名的一一对应的关系。
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!-- 用 id 属性来映射主键字段 -->
<id property=”id” column=”order_id”>
<!-- result 属性来映射非主键字段,property 为实体类属性名,column为数据表中的属性 -->
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
8. 模糊查询 like 语句该怎么写?
- 在
Java代码中添加sql通配符。
String wildcardname = "%smi%";
List<Name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>
select * from foo where bar like #{value}
</select>
- 在
sql语句中拼接通配符,会引起sql注入。
String wildcardname = "smi";
List<Name> names = mapper.selectlike(wildcardname);
<select id=”selectlike”>
select * from foo where bar like "%"#{value}"%"
</select>
9. 通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?
Dao接口即Mapper接口。接口的全限名,就是映射文件中的namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement。在Mybatis中,每一个< select>、< insert>、< update>、< delete>标签,都会被解析为一个MapperStatement对象。Mapper接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻找策略。Mapper接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回。
10. Mybatis 是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。- 分页插件的基本原理是使用
Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
11. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
- 使用
<resultMap>标签,逐一定义数据库列名和对象属性名之间的映射关系。 - 使用
sql列的别名功能,将列的别名书写为对象属性名。 - 有了列名与属性名的映射关系后,
Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
12. 如何执行批量插入?
- 创建一个简单的
insert语句:
<insert id=”insertname”>
insert into names (name) values (#{value})
</insert>
- 在
java代码中执行批处理插入:
List<String> names = new ArrayList();
names.add("fred");
names.add("barney");
names.add("betty");
names.add("wilma");
// 注意这里 ExecutorType.BATCH
SqlSession session = getSqlSessionFactory().openSession(ExecutorType.BATCH);
try {
Namemapper mapper = sqlsession.getmapper(Namemapper.class);
for (String name : names) {
mapper.insertname(name);
}
sqlsession.commit();
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
sqlsession.close();
}
13. 如何获取自动生成的(主)键值?
insert方法总是返回一个int值 ,这个值代表的是插入的行数。- 如果采用自增长策略,自动生成的键值在
insert方法执行完后可以被设置到传入
的参数对象中。
<insert id="insertName" useGeneratedKeys="true" keyProperty="id">
insert into names (name) values (#{name})
</insert>
Names name = new Names();
name.setName("fred");
int rows = mapper.insertName(name);
//完成后,id 已经被设置到对象中
System.out.println("rows inserted = " + rows);
System.out.println("generated key value = " + name.getId());
14. 在 mapper 中如何传递多个参数?
DAO层的函数(实验未成功)。
<!--对应的 xml,#{0}代表接收的是 dao 层中的第一个参数,#{1}代表 dao 层中第二
参数,更多参数一致往后加即可。-->
<select id="selectUser" resultType="com.cy.entity.User">
select * from user
where username=#{0} and address = #{1}
</select>
User selectUser(String name,String address);
- 使用
@Param注解。
<select id="selectUser2" resultType="com.cy.entity.User">
select * from user
where username=#{username} and address = #{address}
</select>
User selectUser2(@Param("username") String username, @Param("address") String address);
- 多个参数封装成
map。
<select id="findRolesByMap" parameterType="map" resultType="role">
select id,role_name as roleName,note
from t_role
where role_name like concat('%',#{roleName},'%')
and note like concat('%',#{note},'%')
</select>
//测试
RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
Map<String,Object> paramenterMap=new HashMap<String,Object>();
parameterMap.put("roleName","1");
parameterMap.put("note","1");
List<Role> roles=roleMapper.findRolesByMap(parameterMap);
//DAO
List findRolesByMap(Map<String,Object> paramenterMap);
15. Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?
Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理
是根据表达式的值 完成逻辑判断并动态拼接sql的功能。Mybatis提供了 9 种动态sql标签:trim|where|set|foreach|if|choose
|when|otherwise|bind。
16. Xml 映射文件中,除了常见的 select | insert | updae | delete 标签之外,还有哪些标签?
<resultMap>、<parameterMap>、<sql>、<include>、<selectKey>,加上动态 sql 的 9 个标签,其中<sql>为 sql片段标签,通过<include>标签引入 sql片段,<selectKey>为不支持自增的主键生成策略标签。
17. Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
- 不同的
Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复。 - 原因就是
namespace+id是作为Map<String, MapperStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复namespace不同,namespace+id自然也就不同。
18. 为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。- 而
Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
19. 一对一、一对多的关联查询 ?
<!--association 一对一关联查询 -->
<!-- 建立对应关系 -->
<resultMap type="account" id="accountMap">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!-- 它是用于指定从表方的引用实体属性的 -->
<association property="user" javaType="user">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
</association>
</resultMap>
<!-- 配置查询所有操作-->
<select id="findAll" resultType="accountuser">
select a.*,u.username,u.address from account a,user u where a.uid =u.id;
</select>
<!--collection 一对多关联查询 -->
<!-- 建立对应关系 -->
<resultMap type="user" id="userMap">
<id column="id" property="id"></id>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<!-- collection 是用于建立一对多中集合属性的对应关系
ofType 用于指定集合元素的数据类型
-->
<collection property="accounts" ofType="account">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
</collection>
</resultMap>
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
a on u.id =a.uid
</select>
20. MyBatis 实现一对一有几种方式?具体怎么操作的?
- 有联合查询和嵌套查询。
- 联合查询是几个表联合查询,只查询一次, 通过在
resultMap里面配置 association 节点配置一对一的类就可以完成; - 嵌套查询是先查一个表,根据这个表里面的结果的外键
id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。
21. MyBatis 实现一对多有几种方式,怎么操作的?
- 有联合查询和嵌套查询。
- 联合查询是几个表联合查询,只查询一次,通过在
resultMap里面的collection节点配置一对多的类就可以完成。 - 嵌套查询是先查一个表,根据这个表里面的结果的外键
id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。
22. Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。- 它的原理是,使用
CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询出来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。 - 当然了,不光是
Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。
23. Mybatis 的一级、二级缓存
- 一级缓存: 基于
PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存。 - 二级缓存与一级缓存其机制相同,默认也是采用
PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/>。 - 对于缓存数据更新机制,当某一个作用域(一级缓存
Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有select中的缓存将被clear。
24. 什么是 MyBatis 的接口绑定?有哪些实现方式?
- 接口绑定,就是在
MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定, 我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置。 - 接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上
@Select、@Update等注解,里面包含Sql语句来绑定;另外一种就是通过xml里面写SQL来绑定, 在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。当Sql语句比较简单时候,用注解绑定, 当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多。
24. 使用 MyBatis 的 mapper 接口调用时有哪些要求?
Mapper接口方法名和mapper.xml中定义的每个sql的id相同。Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同。Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同。Mapper.xml文件中的namespace即是mapper接口的类路径。
25. Mapper 编写有哪几种方式?
-
接口实现类继承
SqlSessionDaoSupport:使用此种方法需要编写mapper接口,mapper接口实现类、mapper.xml文件。
a. 在sqlMapConfig.xml中配置mapper.xml的位置。<mappers> <mapper resource="mapper.xml 文件的地址" /> <mapper resource="mapper.xml 文件的地址" /> </mappers>b. 定义
mapper接口。
c. 实现类集成SqlSessionDaoSupport。
d.mapper方法中可以this.getSqlSession()进行数据增删改查。
e.spring配置。<bean id=" " class="mapper 接口的实现"> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> -
使用
org.mybatis.spring.mapper.MapperFactoryBean。
a. 在sqlMapConfig.xml中配置mapper.xml的位置,如果mapper.xml和mapper接口的名称相同且在同一个目录,这里可以不用配置。<mappers> <mapper resource="mapper.xml 文件的地址" /> <mapper resource="mapper.xml 文件的地址" /> </mappers>b. 定义
mapper 接口,mapper.xml中的namespace为mapper接口的地址,mapper接口中的方法名和mapper.xml中的定义的statement的id保持一致。
c. Spring 中定义。<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="mapper 接口地址" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> -
使用
mapper扫描器。
a.mapper.xml文件编写mapper.xml 中的 namespace 为 mapper 接口的地址; mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一致; 如果将 mapper.xml 和 mapper 接口的名称保持一致则不用在 sqlMapConfig.xml中进行配置。b. 定义
mapper接口:mapper.xml的文件名和mapper的接口名称保持一致,且放在同一个目录。
c. 配置mapper扫描器:<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="mapper 接口包地址"></property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>d. 使用扫描器后从
spring容器中获取mapper的实现对象。
27. 简述 Mybatis 的插件运行原理,以及如何编写一个插件。
Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这 4 种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。- 编写插件:实现
Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
二、Zookeeper部分
1. 什么是Zookeeper?
ZooKeeper是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。- 分布式应用程序可以基于
Zookeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。 Zookeeper保证了如下分布式一致性特性:- ① 顺序一致性(有序性)
从同一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到 Zookeeper 中去。 有序性是 Zookeeper 中非常重要的一个特性。 所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为 zxid(Zookeeper Transaction Id)。 而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个 Zookeeper 最新的 zxid 。 - ② 原子性:所有事务请求的处理结果,在整个集群中所有机器上的应用情况是一致的,即整个集群要么都成功应用了某个事务,要么都没有应用。
- ③ 单一视图:无论客户端连接的是哪个
Zookeeper服务器,其看到的服务端数据模型都是一致的。 - ④ 可靠性:一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直被保留,除非有另一个事务对其进行了变更。
- ⑤ 实时性:
Zookeeper保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
- ① 顺序一致性(有序性)
2. ZooKeeper 提供了什么?
- 文件系统
- 通知机制
3. Zookeeper 文件系统
Zookeeper提供一个多层级的节点命名空间(节点称为znode)。与文件系统不同的是,这些节点都可以设置关联的数据,而文件系统中只有文件节点可以存放数据而目录节点不行。Zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得Zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M。
4. ZAB 协议?
ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。ZAB协议包括两种基本的模式:崩溃恢复和消息广播。- 当整个
zookeeper集群刚刚启动或者 Leader 服务器宕机、重启或者网络故障导致不存在过半的服务器与Leader服务器保持正常通信时,所有进程(服务器)进入崩溃恢复模式,首先选举产生新的Leader服务器,然后集群中Follower服务器开始与新的Leader服务器进行数据同步,当集群中超过半数机器与该Leader服务器完成数据同步之后,退出恢复模式进入消息广播模式,Leader服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。
5. 四种类型的数据节点 Znode
PERSISTENT-持久节点:
除非手动删除,否则节点一直存在于Zookeeper上。EPHEMERAL-临时节点:
临时节点的生命周期与客户端会话绑定,一旦客户端会话失效(客户端与zookeeper连接断开不一定会话失效),那么这个客户端创建的所有临时节点都会被移除。PERSISTENT_SEQUENTIAL-持久顺序节点:
基本特性同持久节点,只是增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。EPHEMERAL_SEQUENTIAL-临时顺序节点:
基本特性同临时节点,增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。
6. Zookeeper Watcher 机制 – 数据变更通知
7. 客户端注册 Watcher 实现
8. 服务端处理 Watcher 实现
9. 客户端回调 Watcher
10. ACL 权限控制机制
11. Chroot 特性
12. 会话管理
13. 服务器角色
Leader- 事务请求的唯一调度和处理者,保证集群事务处理的顺序性。
- 集群内部各服务的调度者。
Follower- 处理客户端的非事务请求,转发事务请求给
Leader服务器。 - 参与事务请求
Proposal的投票。 - 参与
Leader选举投票。
- 处理客户端的非事务请求,转发事务请求给
Observer- 3.0 版本以后引入的一个服务器角色,在不影响集群事务处理能力的基础上提升集群的非事务处理能力。
- 处理客户端的非事务请求,转发事务请求给
Leader服务器。 - 不参与任何形式的投票。
14. Zookeeper 下 Server 工作状态
服务器具有四种状态,分别是 LOOKING、FOLLOWING、LEADING、OBSERVING。
LOOKING:寻找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入Leader选举状态。FOLLOWING:跟随者状态。表明当前服务器角色是Follower。LEADING:领导者状态。表明当前服务器角色是Leader。OBSERVING:观察者状态。表明当前服务器角色是Observer。
三、Dubbo部分
四、Elasticsearch部分
五、Memcached部分
六、Redis部分
1. 什么是 Redis?
-
Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。 -
Redis与其他key - value缓存产品有以下三个特点:Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份。
-
Redis优势:- 性能极高 –
Redis能读的速度是 110000 次/s,写的速度是 81000 次/s 。 - 丰富的数据类型 –
Redis支持二进制案例的Strings,Lists,Hashes,Sets及Ordered Sets数据类型操作。 - 原子 –
Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。 - 丰富的特性 –
Redis还支持publish/subscribe, 通知,key过期等等特性。
- 性能极高 –
-
Redis与其他key-value存储有什么不同?Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其
他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透
明,无需进行额外的抽象。Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时
需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点
是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
2. Redis 的数据类型?
Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),
Set(集合)及Zset(sorted set:有序集合)。- 我们实际项目中比较常用的是
String,Hash如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub。 - 如果你说还玩过
Redis Module,像BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。
3. 使用 Redis 有哪些好处?
- 速度快,因为数据存在内存中,类似于
HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)。 - 支持丰富数据类型,支持
String,List,Set,Zset,Hash等 。 - 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行。
- 丰富的特性:可用于缓存,消息,按
key设置过期时间,过期后将会自动删除。
4. Redis 相比 Memcache 有哪些优势?
Memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类。Redis的速度比Memcached快。Redis可以持久化其数据。
5. Memcache 与 Redis 的区别都有哪些?
- 存储方式
Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis有部份存在硬盘上,这样能保证数据的持久性。 - 数据支持类型
Memcache对数据类型支持相对简单。Redis有复杂的数据类型。 - 使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。
Redis直接自己构建了VM机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
6. Redis 是单进程单线程的?
Redis是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
7. 一个字符串类型的值能存储最大容量是多少?
- 512M
8. Redis 的持久化机制是什么?各自的优缺点?
-
RDB(Redis DataBase)持久化方式: 是指用数据集快照的方式(半持久化模式)记录redis数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
优点:- 只有一个文件
dump.rdb,方便持久化。 - 容灾性好,一个文件可以保存到安全的磁盘。
- 性能最大化,
fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能。 - 相对于数据集大时,比
AOF的启动效率更高。
缺点:
- 数据安全性低。
RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候。
- 只有一个文件
-
AOF(Append-only file)持久化方式: 是指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储保存为 aof 文件。
优点:- 数据安全,
aof持久化可以配置appendfsync属性,有always,每进行一次命令操作就记录到aof文件中一次。 - 通过
append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。 AOF机制的rewrite模式。AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)。
缺点:
AOF文件比RDB文件大,且恢复速度慢。- 数据集大的时候,比
rdb启动效率低。
- 数据安全,
9. Redis 常见性能问题和解决方案
10. redis 过期键的删除策略?
11. Redis 的回收策略(淘汰策略)?
12. 为什么 Redis 需要把所有数据放到内存中?
Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
13. Redis 的同步机制了解么?
Redis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
14. Pipeline 有什么好处,为什么要用 pipeline?
15. 是否使用过 Redis 集群,集群的原理是什么?
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
16. Redis 集群方案什么情况下会导致整个集群不可用?
- 有
A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少 5501-11000 这个范围的槽而不可用。
17. Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?
Redisson、Jedis、lettuce等等,官方推荐使用Redisson。
18. Jedis 与 Redisson 对比有什么优缺点?
Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持。Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。
19. Redis 如何设置密码及验证密码?
- 设置密码:
config set requirepass 123456。 - 授权密码:
auth 123456。
20. 说说 Redis 哈希槽的概念?
Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384 个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。
21. Redis 集群的主从复制模型是怎样的?
- 为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有 N-1 个复制品。
22. Redis 集群会有写操作丢失吗?为什么?
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
23. Redis 集群之间是如何复制的?
- 异步复制
七、MySQL部分
1. MySQL 中有哪几种锁?
- 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最
高,并发度最低。 - 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最
低,并发度也最高。 - 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表
锁和行锁之间,并发度一般。
2. MySQL 中有哪些不同的表格?
共有 5 种类型的表格:
MyISAMHeapMergeINNODBISAM
3. 简述在 MySQL 数据库中 MyISAM 和 InnoDB 的区别
MyISAM:
- 不支持事务,但是每次查询都是原子的;
- 支持表级锁,即每次操作是对整个表加锁;
- 存储表的总行数;
- 一个
MYISAM表有三个文件:索引文件、表结构文件、数据文件; - 采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性。
InnoDb: - 支持
ACID的事务,支持事务的四种隔离级别; - 支持行级锁及外键约束:因此可以支持写并发;
- 不存储总行数;
- 一个
InnoDb引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为 2G),受操作系统文件大小的限制; - 主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值;因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问辅索引;最好使用自增主键,防止插入数据时,为维持
B+树结构,文件的大调整。
4. MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?
SQL 标准定义的四个隔离级别为:
read uncommited:读到未提交数据。read committed:脏读,不可重复读。repeatable read:可重读。serializable:串行化。
5. CHAR 和 VARCHAR 的区别?
CHAR和VARCHAR类型在存储和检索方面有所不同CHAR列长度固定为创建表时声明的长度,长度值范围是 1 到 255 当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格。
6. myisamchk 是用来做什么的?
- 它用来压缩
MyISAM表,这减少了磁盘或内存使用。 MyISAM Static和MyISAM Dynamic有什么区别?- 在
MyISAM Static上的所有字段有固定宽度。动态MyISAM表将具有像TEXT,BLOB等字段,以适应不同长度的数据类型。 MyISAM Static在受损情况下更容易恢复。
- 在
7. 主键和候选键有什么区别?
- 表格的每一行都由主键唯一标识,一个表只有一个主键。
- 主键也是候选键。按照惯例,候选键可以被指定为主键,并且可以用于任何外键
引用。
8. 如果一个表有一列定义为 TIMESTAMP,将发生什么?
- 每当行被更改时,时间戳字段将获取当前时间戳。
- 列设置为
AUTO INCREMENT时,如果在表中达到最大值,会发生什么情况?- 它会停止递增,任何进一步的插入都将产生错误,因为密钥已被使用。
- 怎样才能找出最后一次插入时分配了哪个自动增量?
LAST_INSERT_ID将返回由Auto_increment分配的最后一个值,并且不需要指定表名称。
9. 你怎么看到为表格定义的所有索引?
- 索引是通过以下方式为表格定义的:
SHOW INDEX FROM <tablename>;
10. LIKE 声明中的%和_是什么意思?
%对应于 0 个或更多字符,_只是LIKE语句中的一个字符。- 如何在
Unix和MySQL时间戳之间进行转换?UNIX_TIMESTAMP是从MySQL时间戳转换为Unix时间戳的命令。FROM_UNIXTIME是从Unix时间戳转换为MySQL时间戳的命令。
11. 列对比运算符是什么?
- 在 SELECT 语句的列比较中使用=,<>,<=,<,> =,>,<<,>>,<=>,AND,OR 或 LIKE 运算符。
12. BLOB 和 TEXT 有什么区别?
BLOB是一个二进制对象,可以容纳可变数量的数据。TEXT是一个不区分大小写的BLOB。BLOB和TEXT类型之间的唯一区别在于对BLOB值进行排序和比较时区分大小写,对TEXT值不区分大小写。
本文详细介绍了MyBatis框架的特点、优缺点、应用场景,以及与Hibernate的对比。同时,深入探讨了Redis的数据类型、持久化机制、性能优化策略和集群方案,为读者提供了全面的数据库与缓存解决方案。
666

被折叠的 条评论
为什么被折叠?



