1 简述InnoDB和Myisam的区别
1.Myisam是默认表类型不是事务安全的;InnoDB支持事务。
2.Myisam不支持外键;Innodb支持外键。
3.Myisam支持表级锁(不支持高并发,以读为主);InnoDB支持行锁(共享锁,排它锁,意向锁),粒度更小,但是在执行不能确定扫描范围的sql语句时,InnoDB同样会锁全表。
4.执行大量select,Myisam是最好的选择;执行大量的update和insert最好用InnoDB。
5.Myisam在磁盘上存储上有三个文件.frm(存储表定义) .myd(存储表数据) .myi(存储表索引);innodb磁盘上存储的是表空间数据文件和日志文件,InnoDB表大小只受限于操作系统大小。
6.Myisam使用非聚集索引,索引和数据分开,只缓存索引;InnoDB使用聚集索引,索引和数据存在一个文件。
7.Myisam保存表具体行数;InnoDB不保存。
8.delete from table时,Myisam会重新建表,而InnoDB会一行一行的删除。
2 MySQL索引类型有哪些?以及对数据库的性能的影响?
1)普通索引:允许被索引的数据列包含重复的值。
2)唯一索引:可以保证数据记录的唯一性。
3)主键索引:是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字 PRIMARY KEY 来创建。
4)联合索引:索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引。
5)全文索引:通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题,是目前搜索引擎使用的一种关键技术。可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引
索引可以极大的提高数据的查询速度。通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件
索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大,如果非聚集索引很多,一旦聚集索引改变,那么所有非聚集索引都会跟着变。
3 Spring的bean生命周期?
1)实例化Bean
2)设置对象属性(依赖注入)
3)注入Aware接口
4)BeanPostProcessor(前置处理和后置处理)
5) InitializingBean与init-method
6)DisposableBean和destroy-method
4 怎么处理MySQL的慢查询?
1、开启慢查询日志,准确定位到哪个sql语句出现了问题
2、分析sql语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写
3、分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引
4、如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。
优化语句:
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。
5 如何理解Springboot中的Starter?
starter就是定义⼀个starter的jar包,写⼀个@Configuration配置类、将这些bean定义在⾥⾯,然后在starter包的META-INF/spring.factories中写⼊该配置类,springboot会按照约定来加载该配置类开发⼈员只需要将相应的starter包依赖进应⽤,进⾏相应的属性配置(使⽤默认配置时,不需要配置),就可以直接进⾏代码开发,使⽤对应的功能了。
⽐如mybatis-spring-boot-starter,spring-boot-starter-redis,我们自己写一个starter自动配置启动,写一个我们自己的线程池,用@Configuration+@Bean定义一个线程池,将这个配置类的路径写到spring.factories中,就可以了,打上jar包,在其他地方引用,用@Autowired自动注入我们的Bean使用就可以。
6 如何实现一个IOC容器?
IOC(Inversion of Control),意思是控制反转,不是什么技术,而是一种设计思想,IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
在传统的程序设计中,我们直接在对象内部通过new进行对象创建,是程序主动去创建依赖对象,而IOC是有专门的容器来进行对象的创建,即IOC容器来控制对象的创建。
在传统的应用程序中,我们是在对象中主动控制去直接获取依赖对象,这个是正转,反转是由容器来帮忙创建及注入依赖对象,在这个过程过程中,由容器帮我们查找级注入依赖对象,对象只是被动的接受依赖对象。
- 先准备一个基本的容器对象,包含一些map结构的集合,用来方便后续过程中存储具体的对象
- 进行配置文件的读取工作或者注解的解析工作,将需要创建的bean对象都封装成BeanDefinition对象存储在容器中
- 容器将封装好的BeanDefinition对象通过反射的方式进行实例化,完成对象的实例化工作
- 进行对象的初始化操作,也就是给类中的对应属性值就行设置,也就是进行依赖注入,完成整个对象的创建,变成一个完整的bean对象,存储在容器的某个map结构中
- 通过容器对象来获取对象,进行对象的获取和逻辑处理工作
- 提供销毁操作,当对象不用或者容器关闭的时候,将无用的对象进行销毁
7 SpringCloud核心组件有哪些?分别有什么作用?
1)服务发现——Netflix Eurek
该系统下还分为Eureka服务端和Eureka客户端,Eureka服务端用作服务注册中心,支持集群部署。Eureka客户端是一个java客户端,用来处理服务注册与发现。
2)客服端负载均衡——Netflix Ribbon
基于Http和Tcp的客户端负载均衡,使得面向REST请求时变换为客户端的负载服务调用,提供客户端的软件负载均衡算法。
3)断路器——Netflix Hystrix
它的作用是保护系统,控制故障范围。
4)服务网关——Netflix Zuul
提供api网关,路由,负载均衡等作用
5)分布式配置——Spring Cloud Config
提供服务端和客户端,服务器存储后端的默认实现使用git
8 讲一下对AOP的理解
AOP全称叫做 Aspect Oriented Programming 面向切面编程。它是为解耦而生的,解耦是程序员编码开发过程中一直追求的境界,AOP在业务类的隔离上,绝对是做到了解耦,在这里面有几个核心的概念:
- 切面(Aspect): 指关注点模块化,这个关注点可能会横切多个对象。事务管理是企业级Java应用中有关横切关注点的例子。 在Spring AOP中,切面可以使用通用类基于模式的方式(schemabasedapproach)或者在普通类中以 @Aspect 注解(@AspectJ 注解方式)来实现。
- 连接点(Join point): 在程序执行过程中某个特定的点,例如某个方法调用的时间点或者处理异常的时间点。在Spring AOP中,一个连接点总是代表一个方法的执行。
- 通知(Advice): 在切面的某个特定的连接点上执行的动作。通知有多种类型,包括“around”,“before” and “after”等等。 许多AOP框架,包括Spring在内,都是以拦截器做通知模型的,并维护着一个以连接点为中心的拦截器链。
- 切点(Pointcut): 匹配连接点的断言。通知和切点表达式相关联,并在满足这个切点的连接点上运行(例如,当执行某个特定名称的方法时)。切点表达式如何和连接点匹配是AOP的核心:Spring默认使用AspectJ切点语义。
- 引入(Introduction): 声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被通知的对象上。例如,可以使用引入来使bean实现 IsModified 接口, 以便简化缓存机制(在AspectJ社区,引入也被称为内部类型声明(inter))。
- 目标对象(Target object): 被一个或者多个切面所通知的对象。也被称作被通知(advised)对象。既然Spring AOP是通过运行时代理实现的,那么这个对象永远是一个被代理(proxied)的对象。
- AOP代理(AOP proxy):AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。
- 织入(Weaving): 把切面连接到其它的应用程序类型或者对象上,并创建一个被被通知的对象的过程。这个过程可以在编译时(例如使用AspectJ编译器)、类加载时或运行时中完成。 Spring和其他纯Java AOP框架一样,是在运行时完成织入的。
任何一个系统都是由不同的组件组成的,每个组件负责一块特定的功能,当然会存在很多组件是跟业务无关的,例如日志、事务、权限等核心服务组件,这些核心服务组件经常融入到具体的业务逻辑中,如果我们为每一个具体业务逻辑操作都添加这样的代码,很明显代码冗余太多,因此我们需要将这些公共的代码逻辑抽象出来变成一个切面,然后注入到目标对象(具体业务)中去,AOP正是基于这样的一个思路实现的,通过动态代理的方式,将需要注入切面的对象进行代理,在进行调用的时候,将公共的逻辑直接添加进去,而不需要修改原有业务的逻辑代码,只需要在原来的业务逻辑基础之上做一些增强功能即可。
9 讲一下对IOC的理解
IOC容器:实际上就是map,里面存的是各种对象(在XML里配置的bean节点,@respository,@service,@controller,@component),在项目启动的时候会读取配置文件里面的bean节点,根据全限定类名使用反射创建对象放到map里,扫描到打上上述注解的类还是通过反射的方式创建对象放到map里面。
这个时候map里面就有各种对象了,接下来我们再代码里面需要用到里面的对象时,再通过DI注入(@Autowired,@Resources,@Qualifier等注解),xml里bean 节点内的ref属性,项目启动时读取xml节点ref属性根据id注入,也会扫描到这些注解,根据类型或者id注入,id就是对象名。
- 控制反转:
没有引入IOC容器之前,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须去主动创建对象B或者使用已经创建的对象B,无论是创建还是使用对象B,控制权都在A类。
引入IOC容器后,对象A和对象B之间失去了直接联系,当对象A运行到需要对象B的时候,IOC容器会主动创建对象B注入到对象A所需要的地方。
通过前后对比,不难看出:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是控制反转。
- 依赖注入:
“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变成了由IOC容器自动注入。依赖注入是实现IOC的方法,就是由IOC在运行期间,动态的将某种依赖关系注入到对象之中。
10 索引的设计原则有哪些?
在进行索引设计的时候,应保证索引字段占用的空间越小越好,这只是一个大的方向,还有一些细节需要注意:
1、适合索引的列是出现在where子句中的列,或者链接子句中的列。
2、基数较小的表,索引效果差,没必要创建索引。
3、在选择索引列的时候,越短越好,可以指定某些列的一部分不,没必要用全部字段的值。
4、不要给表的没有给字段都创建索引,并不是索引越多越好。
5、定义有外键的数据列一定药创建索引。
6、更新频繁的字段不要有索引。
7、创建索引的列不要过多,可以创建组合索引,但是组合索引的列的个数不建议太多。
8、大文本,大对象不要创建索引。