@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exclude= { DataSourceAutoConfiguration.class })。
@ComponentScan:Spring组件扫描。
链表中的元素的个数为8个或超过8个 同时,还要满足当前数组的长度大于或等于64才会把链表转变为红黑树。
为什么?
因为链表转变为红黑树的目的是为了解决链表过长,导致查询和插入效率慢的问题,而如果要解决这个问题,也可以通过数组扩容,把链表缩短也可以解决这个问题。所以在数组长度还不太长的情况,可以先通过数组扩容来解决链表过长的问题。


都是面向对象的语言,都支持封装、继承和多态
Java不提供指针来直接访问内存,程序内存更加安全
Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。
Java有自动内存管理机制,不需要程序员手动释放无用内存
缓存的优势:
提升访问性能
降低网络拥堵
减轻服务负载
增强可扩展性
增加了系统的复杂度 缓存相比原始 DB 存储和运维的成本更高 存在一致性问题
Cache Aside(旁路缓存) Read/Write Through(读写穿透) Write Behind Caching(异步缓存写入)
Cache Aside模式
Read/Write Through模式
存储服务封装了所有的数据处理细节,业务应用端代码只用关注业务逻辑本身,系统的隔离性更佳。 进行写操作时,如果 cache 中没有数据则不更新,有缓存数据才更新,内存效率更高。
Write Behind Caching模式
手动注入,通常使用XML的方式定义Bean的时候就会通过手动方式给属性进行赋值 自动注入,利用@Autowired注解利用Spring自动给属性进行赋值
手动指定值 手动指定bean的名字 实例工厂方法得到bean 静态工厂方法得到bean
通过构造方法注入 通过set方法注入
通过属性自动注入 通过set方法自动注入 通过构造方法自动注入
1 @Configuration
2 public class CorsConfig implements WebMvcConfigurer {3
4 @Override
5 public void addCorsMappings(CorsRegistry registry) {
6 registry.addMapping("/**")
7 .allowedOrigins("*")
8 .allowCredentials(true)
9 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
10 .maxAge(3600);
11 }
12}
1 @Configuration
2 public class CorsConfig {3
4 @Bean
5 public CorsFilter corsFilter() {
6 CorsConfiguration corsConfiguration = new CorsConfiguration();
7 corsConfiguration.addAllowedOrigin("*");
8 corsConfiguration.addAllowedHeader("*");
9 corsConfiguration.addAllowedMethod("*");
10 corsConfiguration.setAllowCredentials(true);
11 UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
12 urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsCo nfiguration);
13 return new CorsFilter(urlBasedCorsConfigurationSource);
14 }
15
16 }
1 <!‐‐ 批量保存(foreach插入多条数据两种方法)
2 int addEmpsBatch(@Param("emps") List<Employee> emps); ‐‐>
3 <!‐‐ MySQL下批量保存,可以foreach遍历 mysql支持values(),(),()语法 ‐‐> //推荐使用
4 <insert id="addEmpsBatch">
5 INSERT INTO emp(ename,gender,email,did)
6 VALUES
7 <foreach collection="emps" item="emp" separator=",">
8 (#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
9 </foreach>
10 </insert>
1 <!‐‐ 这种方式需要数据库连接属性allowMutiQueries=true的支持
2 如jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true ‐‐>
3 <insert id="addEmpsBatch">
4 <foreach collection="emps" item="emp" separator=";">
5 INSERT INTO emp(ename,gender,email,did)
6 VALUES(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
7 </foreach>
8 </insert>
1 //批量保存方法测试
2 @Test
3 public void testBatch() throws IOException{
4 SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
5 //可以执行批量操作的sqlSession
6 SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATC
H);
7
8 //批量保存执行前时间
9 long start = System.currentTimeMillis();
10 try {
11 EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
12 for (int i = 0; i < 1000; i++) {
13 mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0,5), "b", "1"));
14 }
15
16 openSession.commit();
17 long end = System.currentTimeMillis();
18 //批量保存执行后的时间
19 System.out.println("执行时长" + (end ‐ start));
20 //批量 预编译sql一次==》设置参数==》10000次==》执行1次 677
21 //非批量 (预编译=设置参数=执行 )==》10000次 1121
22
23 } finally {
24 openSession.close();
25 }
26 }
1 public interface EmployeeMapper {
2 //批量保存员工
3 Long addEmp(Employee employee);
4 }
1 <mapper namespace="com.jourwon.mapper.EmployeeMapper"
2 <!‐‐批量保存员工 ‐‐>
3 <insert id="addEmp">
4 insert into employee(lastName,email,gender)
5 values(#{lastName},#{email},#{gender})
6 </insert>
7 </mapper>
对于支持主键自增的数据库(MySQL)
1 <insert id="insertUser" useGeneratedKeys="true" keyProperty="userId" >
2 insert into user(
3 user_name, user_password, create_time)
4 values(#{userName}, #{userPassword} , #{createTime, jdbcType=
TIMESTAMP})
5 </insert>
不支持主键自增的数据库(Oracle)
1 <selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">
2 </selectKey>
1 <insert id="insertUser" >
2 <selectKey keyColumn="id" resultType="long" keyProperty="userId" order="BEFORE">
3 SELECT USER_ID.nextval as id from dual
4 </selectKey>
5 insert into user(
6 user_id,user_name, user_password, create_time)
7 values(#{userId},#{userName}, #{userPassword} , #{createTime, jdbcType=TIMESTAMP})
8 </insert>
当实体类中的属性名和表中的字段名不一样 ,怎么办
1 <select id="getOrder" parameterType="int" resultType="com.jourwon.pojo.Order">
2 select order_id id, order_no orderno ,order_price priceform orders where order_id=#{id};
3 </select>
1 <select id="getOrder" parameterType="int" resultMap="orderResultMap">
2 select * from orders where order_id=#{id}
3 </select>
4
5 <resultMap type="com.jourwon.pojo.Order" id="orderResultMap">
6 <!–用id属性来映射主键字段–>
7 <id property="id" column="order_id">
8
9 <!–用result属性来映射非主键字段,property为实体类属性名,column为数据库表中的属性–>
10 <result property ="orderno" column ="order_no"/>
11 <result property="price" column="order_price" />
12 </reslutMap>21:如果叫你自己设计一个中间件,你会如何设计?
我会从以下几点方面考虑开发:1) 远程过程调用
2) 面向消息
利用搞笑的消息传递机制进行平台无关的数据交流,并给予数据通信来进行分布式系统的集成,有一下三个特点:
i) 通讯程序可以在不同的时间运行
ii) 通讯晨旭之家可以一对一、一对多、多对一甚至是上述多种方式的混合
iii)程序将消息放入消息队列会从小吸毒列中取出消息来进行通讯
3) 对象请求代理
提供不同形式的通讯服务包括同步、排队、订阅发布、广播等。可构筑各种框架如:事物处理监控器、分布数据访问、对象事务管理器 OTM 等。
4) 事物处理监控有一些功能
a) 进程管理:包括启动 server 进程、分配任务、监控其执行并对负载进行平衡b) 事务管理:保证在其监控下的事务处理的原子性、一致性、独立性和持久性
c) 通讯管理,为 client 和 server 之间提供多种通讯机制,包括请求响应、会话、排队、订阅发布和广播等
22:什么是中间件?
中间件是处于操作系统和应用程序之间软件,使用时往往是一组中间件集成在一起,构成一个平台(开发平台+运行平台),在这组中间件中必须要有一个通信中间件,即中间件= 平台+通信。该定义也限定了只有用于分布式系统中才能称为中间件
主要分类:远程过程调用、面向消息的中间件、对象请求代理、事物处理监控。
23:ThreadLock 用过没有,说说它的作用?
ThreadLock 为本地线程,为每一个线程提供一个局部变量,也就是说只有当前线程可以访问,是线程安全的。
原理:为每一个线程分配一个对象来工作,并不是由 ThreadLock 来完成的,而是需要在应用层面保证的,ThreadLock 只是起到了一个容器的作用。原理为ThreadLock 的 set()跟 get()方法。
实现原理:
public void set(T value) {
Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public T get() {
Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
24:Hashcode()和 equals()和==区别?
(1) hashcode()方法跟 equals()在 java 中都是判断两个对象是否相等
(2) 两个对象相同,则 hashcode 值一定要相同;即对象相同 ---->成员变量相同---->hashcode 值一定相同
(3) 两个对象的hashcode值相同,对象不一定相等。
总结:equals相等则hashcode一定相等,
hashcode 相等,equals 不一定相等。
(4) ==比较的是两个引用在内存中指向的是不是同一对象(即同一内存空间)
25:mysql 数据库中,什么情况下设置了索引但无法使用?
(1) 索引的作用:在数据库表中对字段建立索引可以大大提高查询速度。
(2) Mysql 索引类型:
a) 普通索引
b) 唯一索引
唯一索引列的值必须唯一允许有空值,如果是组合索
引,则列值的组合必须唯一:CREATE UNIQUE INDEX indexName ON
mytable(username(length)) -- 修改表结构
ALTER mytable ADD UNIQUE [indexName] ON (username(length)) -- 创建表的时候直接指定CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16)
NOT NULL, UNIQUE [indexName] (username(length)) );
c) 主键索引
一种特殊的唯一索引,不允许有空值,一般在创建表的时候创建主键索引:
CREATE TABLE mytable( ID INT NOT NULL,
VARCHAR(16) NOT NULL, PRIMARY KEY(ID) );
d) 组合索引CREATE TABLE mytable( ID INT NOT NULL,
VARCHAR(16) NOT NULL, city VARCHAR(50) NOT NULL,age INT
NOT NULL );
为了进一步榨取 MySQL 的效率,就要考虑建立组合索引。就是 将 name, city, age 建到一个索引里:代码如下:ALTER TABLE mytable ADD INDEX name_city_age
(name(10),city,age);
(3) 什么情况下有索引,但用不上?
如果条件中有 OR,即使其中有部分条件带索引也不会使用。注 意:要想使用 or,又想让索引生效,只能将 or 条件中的每个列都加上索引。
对于多了索引,不是使用的第一部分,则不会使用索引。
Like 查询以%开头,不使用索引
存在索引列的数据类型隐形转换,则用不上索引,比如列类型是
字符串,那一定要在条件中将数据使用引号引用起来,否则不使
用索引
Where 子句里对索引列上有数学运算,用不上索引
Where 子句中对索引列使用函数,用不上索引
Mysql 估计使用全表扫描要比用索引快,不使用索引
数据唯一性差的字段不要使用索引
频繁更新的字段不要使用索引
字段不在 where 语句中出现时不要添加索引,如果 where 后含
IS NULL/IS NOT NULL/LIKE ‘%输入符%’等条件,不要使用索引
Where 子句里对索引使用不等于(<>),不建议使用索引,效果一般
26:mysql 优化会不会,mycat 分库,垂直分库,水平分库?
(1) 为查询缓存优化你的查询
(2) EXPLAIN select 查询:explain 的查询结果会告诉你索引主键是如何被利用的
(3) 只需要一行数据时使用limit1
(4) 为搜索字段添加索引
(5) 在关联表的时候使用相当类型的列,并将其索引
(6) 千万不要ORDERBY RAND()
(7) 避免select*
(8) 永远为每张表设置一个ID
(9) 使用ENUM而不是VARCHAR
(10) 从 PROCEDURE ANALYS()提取建议
(11) 尽可能的使用 NOT NULL
(12) Java 中使用 Prepared Statements
(13) 无缓冲的查询
(14) 把 IP 地址存成 UNSIGNED INT
(15) 固定表的长度
(16) 垂直分库:“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以
降低表的复杂度和字段的数目,从而达到优化的目的。(17) 水平分库:“水平分割”是一种把数据库中的表按行变成几张表的方法,这样可以
降低表的复杂度和字段的数目,从而达到优化的目的。(18) 越小的列会越快
(19) 选择正确的存储引擎
(20) 使用一个对象关系映射器
(21) 小心永久链接
(22) 拆分大的 DELETE 或 INSERT 语句
27:分布式事务解决方案?
(1) 什么是分布式事务?
a) 例如:当本地事务数据库断电的这种情况,如何保证数据一致性?
数据库由两个文件组成的,一个数据库文件和一个日志文件,数据库任何写入操作都要先写日志,在操作前会把日志文件写入磁盘,那么断电的时候即使才做没有完成,在重启数据库的时候,数据库会根据当前数据情况进行 undo 回滚或 redo 前滚, 保证了数据的强一致性。
b) 分布式理论:当单个数据库性能产生瓶颈的时候,可能会对数据库进行分区(物理分区),分区之后不同的数据库不同的服务器上 ,此时单个数据库的ACID不适应这种情况啊,在此集群环境下很难达到集群的 ACID,甚至效率性能大幅度下降,重要的是再很难扩展新的分区了。此时就需要引用一个新的理论来适应这种集群情况:CAP 定理
c) CAP 定理:由加州肚饿伯克利分销 Eric Brewer 教授提出,指出 WEB服务无法同时满足 3 个属性:
具体的将在分布式系统中,在任何数据库设计中,一个 WEB 应至多只能同时支持上面两个属性。设计人员必须在一致性和可用性之间做出选择。
一致性:客户端知道一系列的操作都会同时发生(生效)
可用性:每个操作都必须以可预期的响应结束
分区容错性:及时出现单组件无法可用,操作依然可以完成。
d) BASE 理论:分布式系统中追求的是可用性,比一致性更加重要, BASE 理论来实现高可用性。核心思想是:我们无法做到全一致,单每个应用都可以根据自身的业务特点,采用适当的方式使系统达到最终一致性。
e) 数据库事务特性:ACID
i. 原子性
ii. 一致性
iii. 独立性或隔离性
iv. 持久性
(2) 分布式系统中,实现分布式事务的解决方案:
两阶段提交 2PC
补偿事务 TCC
本地消息表(异步确保)
MQ 事务消息
Sagas 事务模型
28:sql 语句优化会不会,说出你知道的?
(1) 避免在列上做运算,可能会导致索引失败
(2) 使用join时应该小结果集驱动大结果集,同时把复杂的join查询拆分成多个query,不然 join 越多表,会导致越多的锁定和堵塞。
(3) 注意like模糊查询的使用,避免使用%%
(4) 不要使用select*节省内存
(5) 使用批量插入语句,节省交互
(6) Limit 基数比较大时,使用 between and
(7) 不要使用rand函数随机获取记录
(8) 避免使用null,建表时,尽量设置notnul,提高查询性能
(9) 不要使用count(id),应该使用count(*)
(10) 不要做无谓的排序,尽可能在索引中完成排序
(11) From语句中一定不要使用子查询
(12) 使用更多的 where 加以限制,缩小查找范围
(13) 合理运用索引
(14) 使用 explain 查看 sql 性能
29:mysql 的存储引擎了解过没有?
(1) MySQL 存储引擎种类:

(2) 事务处理:
在整个流程中出现任何问题,都能让数据回滚到最开始的状态,这种处
理方式称之为事务处理。也就是说事务处理要么都成功,要么的失败。
30:红黑树原理?
红黑树是一个二叉搜索树。在每个节点增加了一个存储位记录节点的颜色,可以是RED,也可以是BLACK,通过任意一条从根到叶子简单路径上颜色的约束,红黑树保证最长路径不超过最短路径的两倍,加以平衡。性质如下:
每个节点颜色不是黑色就是红色
根节点的颜色是黑色的
如果一个节点是红色,那么他的两个子节点就是黑色的,没有持续的红节点
对于每个节点,从该节点到其后代叶节点的简单路径上, 均包含相同数目的黑色节点。
31:说说springcloud的⼯作原理
springcloud由以下⼏个核心组件构成:

Eureka:
各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从⽽而知道其他服务在哪⾥
Ribbon:
服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择⼀台 Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
Hystrix:
发起请求是通过Hystrix的线程池来⾛的,不同的服务⾛不同的线程池,实现了了不同服务调⽤的隔离,避免了服务雪崩的问题
Zuul:
如果前端、移动端要调⽤后端系统,统⼀从Zuul⽹关进入,由Zuul网关转发请求给对应的服务
32:⽤什么组件发请求
在Spring Cloud中使⽤Feign, 我们可以做到使用HTTP请求远程服务时能与调⽤本地方法一样的编码体验,开发者完全感知不到这是远程⽅法,更感知不到这是个HTTP请求。
33:注册中⼼心跳是几秒
1、Eureka的客户端默认每隔30s会向eureka服务端更新实例,注册中心也会定时进行检查,发现某个实例默认90s内没有再收到心跳,会注销此实例,这些时间间隔是可配置的。
2、不过注册中⼼还有一个保护模式(服务端在短时间内丢失过多客户端的时候,就会进入保护模式),在这个保护模式下,他会认为是网络问题,不会注销任何过期的实例。
34:消费者是如何发现服务提供者的
a. 当⼀个服务实例启动,会将它的ip地址等信息注册到eureka;
b. 当a服务调用b服务,a服务会通过Ribbon检查本地是否有b服务实例信息的缓存;
c. Ribbon会定期从eureka刷新本地缓存。

35:多个消费者调用同一接口,eruka默认的分配⽅式是什什么
a. RoundRobinRule:轮询策略
Ribbon以轮询的⽅式选择服务器,这个是默认值。所以示例中所启动的两个服务会被循环访问;
b. RandomRule:随机选择
也就是说Ribbon会随机从服务器列表中选择一个进行访问;
c. BestAvailableRule:最⼤可用策略
即先过滤出故障服务器后,选择⼀个当前并发请求数最小的;
d. WeightedResponseTimeRule:带有加权的轮询策略
对各个服务器响应时间进行加权处理,然后在采用轮询的⽅式来获取相应的服务器器;
e. AvailabilityFilteringRule:可用过滤策略
先过滤出故障的或并发请求⼤于阈值一部分服务实例,然后再以线性轮询的⽅方式从过滤后的实例清单中选出⼀一个;
f. ZoneAvoidanceRule:区域感知策略
先使⽤主过滤条件(区域负载器,选择最优区域)对所有实例过滤并返回过滤后的实例清单,依次使用次过滤条件列表中的过滤条件对主过滤条件的结果进⾏过滤,判断最⼩过滤数(默认1)和最小过滤百分比(默认0),最后对满⾜条件的服务器则使用RoundRobinRule(轮询⽅方式)选择一个服务器实例。
36:说说常⽤的springboot注解,及其实现?
a. @Bean:注册Bean
i. 默认使⽤⽅法名作为id,可以在后面定义id如@Bean("xx");
ii. 默认为单例。
iii. 可以指定init方法和destroy方法:
1.对象创建和赋值完成,调⽤初始化方法;
2.单实例bean在容器销毁的时候执行destroy方法;
3.多实例bean,容器关闭是不会调用destroy方法。
b. @Scope:Bean作用域
i. 默认为singleton;
ii. 类型:
1. singleton单实例(默认值):ioc容器启动时会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器中拿实例;
2. prototype多实例:ioc容器启动不会创建对象,每次获取时才会调⽤⽅法创建实例;
3. request同一次请求创建一个实例;
4. session同一个session创建一个实例。
c. @Value:给变量赋值
i. 代码:


方式:
1. 基本数字
2. 可以写SpEL(Spring EL表达式):#{}
3. 可以写${},取出配置文件中的值(在运⾏环境变量里⾯的值)
d. @Autowired:⾃动装配
i. 默认优先按照类型去容器中找对应的组件:
BookService bookService
= applicationContext.getBean(BookService.class);
ii. 默认⼀定要找到,如果没有找到则报错。可以使用@Autowired(required = false)标记bean为⾮必须的。
iii. 如果找到多个相同类型的组件,再根据属性名称去容器中查找。
iv. @Qualifier("bookDao2")明确的指定要装配的bean。
v. @Primary:让spring默认装配首选的bean,也可以使用@Qualifier()指定要装配的bean。
e. @Profile:环境标识
i. Spring为我们提供的可以根据当前环境动态的激活和切换⼀系列组件的功能;
ii. @Profile指定组件在哪个环境才能被注册到容器中,默认为"default",如@Profile("default")。
iii. 激活⽅式:
1. 运行时添加虚拟机参数:-Dspring.profiles.active=test
2. 代码⽅式
37:spring的事务注解是什么?什么情况下事物才会回滚
a. spring事务实现机制:

b. 事务注解@transactional;
c. 默认情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常)或者 Error,则 Spring 将回滚事务。
d. @Transactional 只能应⽤到 public ⽅法才有效:只有@Transactional 注解应用到 public ⽅法,才能进行事务管理。这是因为 在使⽤ Spring AOP 代理时,Spring 在调用在图 1 中的 TransactionInterceptor 在⽬标⽅法执行前后进⾏拦截之前, DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept ⽅法或 JdkDynamicAopProxy 的 invoke ⽅法会间接调⽤ AbstractFallbackTransactionAttributeSource(Spring 通过这个类获取表 1. @Transactional 注解的事务属性配置属性信息) 的 computeTransactionAttribute ⽅法。
38:说说spring事物的传播性和隔离级别
a. 七个事务传播属性:
1. PROPAGATION_REQUIRED -- ⽀持当前事务,如果当前没有事务,就新建⼀个事务。这是最常⻅的选择。
2. PROPAGATION_SUPPORTS -- ⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执行。
3. PROPAGATION_MANDATORY -- ⽀持当前事务,如果当前没有事务,就抛出异常。
4. PROPAGATION_REQUIRESNEW -- 新建事务,如果当前存在事务,把当前事务挂起。
5. PROPAGATION_NOTSUPPORTED -- 以⾮事务⽅式执⾏操作,如果当前存在事务,就把当前事务挂起。
6. PROPAGATION_NEVER -- 以⾮事务⽅式执行,如果当前存在事务,则抛出异常。
7. PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执⾏行行。如果当前没有事务,则进行与 PROPAGATION_REQUIRED类似的操作。
b. 五个隔离级别:
1. ISOLATION_DEFAULT 这是⼀个PlatfromTransactionManager默认的隔离级别,使⽤数据库默认的事务隔离级别.
2. 另外四个与JDBC的隔离级别相对应:
3. ISOLATION_READUNCOMMITTED 这是事务最低的隔离级别,它充许别外⼀一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。
4. ISOLATION_READCOMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读。
5. ISOLATION_REPEATABLEREAD 这种事务隔离级别可以防⽌脏读,不可重复读。但是可能出现幻读。它除了保证一个事务 不能读取另一个事务未提交的数据外,还保证了避免不可重复读。
6. ISOLATION_SERIALIZABLE 这是花费最⾼代价但是最可靠的事务隔离级别。事务被处理为顺序执⾏。除了防⽌脏读,不可重复读外,还避免了幻读。
c. 关键词:

1、脏读(新增或删除):
脏读就是指当⼀个事务正在访问数据,并且对数据进⾏了修改,⽽这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据;

2、不不可重复读(修改):是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样 的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(解决:只有在修改事务完全提交之后才可以读取数据,则可以避免该问题);

3、幻读(新增或删除):是指当事务不是独⽴执行时发生的一种现象,例如第⼀一个事务对一个表中的数据进⾏了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插⼊一行新数据。那么,以后就会发生操作第一个事务的⽤户发现表中还有没有修改的数据行,就好象发生了了幻觉一样(解决:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题)。

39:mysql的引擎有什么?他们的区别
a. InnoDB:
1. ⽀持事务处理
2. ⽀持外键
3. ⽀持⾏锁
4. 不⽀持FULLTEXT类型的索引(在Mysql5.6已引入)
5. 不保存表的具体行数,扫描表来计算有多少行
6. 对于AUTO_INCREMENT类型的字段,必须包含只有该字段的索引
7. DELETE 表时,是⼀⾏⼀行的删除
8. InnoDB 把数据和索引存放在表空间⾥面
9. 跨平台可直接拷⻉使⽤
10. 表格很难被压缩
b. MyISAM:
1. 不⽀持事务,回滚将造成不完全回滚,不具有原⼦性
2. 不支持外键
3. ⽀持全文搜索
4. 保存表的具体行数,不带where时,直接返回保存的⾏数
5. DELETE 表时,先drop表,然后重建表
6. MyISAM 表被存放在三个文件 。frm 文件存放表格定义。数据⽂文件是MYD (MYData) 。索引⽂件是MYI (MYIndex)
7. 跨平台很难直接拷⻉
8. AUTO_INCREMENT类型字段可以和其他字段一起建立联合索引
9. 表格可以被压缩
c. 选择:
因为MyISAM相对简单所以在效率上要优于InnoDB.如果系统读多,写少。对原⼦子性要求低。那么MyISAM最好的选择。且MyISAM恢复速度快。可直接⽤备份覆盖恢复。如果系统读少,写多的时候,尤其是并发写⼊⾼的时候。InnoDB就是⾸选了。两种类型都有⾃己优缺点。
40:innodb如何实现mysql的事务

事务进⾏过程中,每次sql语句执行,都会记录undo log和redo log,然后更新数据形成脏页,然后redo log按照时间或者空间等条件进⾏落盘,undo log和脏⻚按照checkpoint进⾏落盘,落盘后相应的redo log就可以删除了。此时,事务还未 COMMIT,如果发⽣崩溃,则首先检查checkpoint记录,使⽤相应的redo log进⾏行数据和undo log的恢复,然后查看undo log的状态发现事务尚未提交,然后就使用undo log进行事务回滚。事务执行COMMIT操作时,会将本事务相关的所有redo log都进⾏落盘,只有所有redo log落盘成功,才算COMMIT成功。然后内存中的数据脏页继续按照checkpoint进⾏落盘。如果此时发⽣了崩溃,则只使用redo log恢复数据。




