1、为什么MyISAM不支持行锁,而InnoDB支持。

InnoDB之所以可以锁行,是因为Innodb的主索引结构上,既存储了主键值,又直接存储了行数据,可以方便的锁住行数据,而MyIsam索引指向另一片数据文件,没有办法精确锁住数据段。

2、mysql中表锁和行锁的区别

行锁

特点:锁的粒度小,发生锁冲突的概率低、处理并发的能力强;开销大、加锁慢、会出现死锁

加锁的方式:自动加锁。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任何锁。

表锁

特点:开销小、加锁快、无死锁;锁粒度大,发生锁冲突的概率高,高并发下性能低

加锁的方式:自动加锁。查询操作(SELECT),会自动给涉及的所有表加读锁,更新操作(UPDATE、DELETE、INSERT),会自动给涉及的表加写锁。

3、哪些场景需要加表锁

适用场景:有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用

适用场景:以查询为主,只有少量按索引条件更新数据的应用

4、spring优点是什么,说一下ioc、aop。

spring的依赖注入将对象之间的依赖关系交给了框架来处理,减小了各个组件之间的耦合性;

AOP面向切面编程,可以将通用的任务抽取出来,复用性更高;

spring对于其余主流框架提供了很好的支持,代码的侵入性很低。

IOC:也叫控制反转,将对象之间的依赖关系交给Spring容器,使用配置文件来创建所依赖的对象,由主动创建对象改为了被动方式,实现解耦合。可以通过注解@Autowired和@Resource来注入对象,被注入的对象必须被下边的四个注解之一标注:

@Controller

@Service

@Repository

@Component

DI:和控制反转是同一个概念的不同角度的描述,即应用程序在运行时依赖IOC容器来动态注入对象需要的外部资源(对象等)。

AOP:面向切面编程是指当需要在某一个方法之前或者之后做一些额外的操作,比如说日志记录、权限判断,异常统计等,可以利用AOP将功能代码从业务逻辑代码中分离出来。

5、阻塞io和非阻塞io说一下,非阻塞io优点是什么。怎么去监听,怎么实现非阻塞的?

阻塞io:最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。

当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。

非阻塞io:当用户线程发起一个操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送同样的操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。所以事实上,在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。

BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
非阻塞io优点:非阻塞IO的读、写、接收连接是不会产生阻塞的

  • 传统IO在处理数据传输请求时,针对每个传输请求生成一个线程,如果IO异常,那么线程阻塞,在IO恢复后唤醒处理线程。在同时处理大量连接时,会实例化大量的线程对象。每个线程的实例化和回收都需要消耗资源,jvm需要为其分配TLAB,然后初始化TLAB,最后绑定线程,线程结束时又需要回收TLAB,这些都需要CPU资源。
  • NIO使用selector来轮询IO流,内部使用poll或者epoll,以事件驱动形式来相应IO事件的处理。同一时间只需实例化很少的线程对象,通过对线程的复用来提高CPU资源的使用效率。
  • CPU轮流为每个线程分配时间片的形式,间接的实现单物理核处理多线程。当线程越多时,每个线程分配到的时间片越短,或者循环分配的周期越长,CPU很多时间都耗费在了线程的切换上。线程切换包含线程上个线程数据的同步(TLAB同步),同步变量同步至主存,下个线程数据的加载等等,他们都是很耗费CPU资源的。
  • 在同时处理大量连接,但活跃连接不多时,NIO的事件响应模式相比于传统IO有着极大的性能提升。
  • NIO还提供了FileChannel,以zero-copy的形式传输数据,相较于传统的IO,数据不需要拷贝至用户空间,可直接由物理硬件(磁盘等)通过内核缓冲区后直接传递至网关,极大的提高了性能。
  • NIO提供了MappedByteBuffer,其将文件直接映射到内存(这里的内存指的是虚拟内存,并不是物理内存),能极大的提高IO吞吐能力。

当连接不多时,并且每个连接都很活跃时,阻塞IO性能可能比非阻塞要好

通过Selector、及Selector的select操作,我们能遍历出当前有哪些事件准备好了,比如客户端连接过来了、客户端有数据过来了、可以往客户端发送数据了。

6、内部类了解吗?匿名内部类了解吗?

内部类应该是一个类当中的一个类,相当于一个类进行了嵌套,就如同循环的嵌套一般。内部类有一个特征:内部类当中可以调用外部类当中的属性和方法,而外部类却不能调用内部类当中的。

匿名内部类 :是内部类的简化写法。它的本质是一个 带具体实现的 父类或者父接口的 匿名的 子类对象。

匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() {
// 覆盖重写所有抽象方法
};

对格式“new 接口名称() {…}”进行解析:

  • new代表创建对象的动作
  • 接口名称就是匿名内部类需要实现哪个接口
  • {…}这才是匿名内部类的内容

匿名内部类可以继承两类数据结构:

  • 抽象类
  • 接口。

注意:

匿名内部类,在【创建对象】的时候,只能使用唯一一次。
如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。
匿名对象,在【调用方法】的时候,只能调用唯一一次。
如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】。

7、spring bean的生命周期说一下

首先需要分清是哪种情况下的bean生命周期:

  • ApplicationContext作为Spring容器。这里,我们讲的是 ApplicationContext中Bean的生命周期。
  • BeanFactory中Bean的生命周期 ,只不过处理器需要手动注册。

  • 实例化一个Bean,也就是我们通常说的new
  •  
  • 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
  •  
  •  如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID
  •  
  •  如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean)
  •  
  • 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式同样可以实现步骤4,但比4更好,以为ApplicationContext是BeanFactory的子接口,有更多的实现方法
  •  
  • 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术
  •  
  • 如果这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法
  •  
  • 如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法(注意:以上工作完成以后就可以用这个Bean了,那这个Bean是一个single的,所以一般情况下我们调用同一个ID的Bean会是在内容地址相同的实例)
  • 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法
  •  
  • 最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法

如果应用Spring的工厂也就是BeanFactory的话去掉第5步---如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式同样可以实现步骤4,但比4更好,以为ApplicationContext是BeanFactory的子接口,有更多的实现方法就Ok了。

8、spring bean的类型有哪些。

  • 普通bean:<bean  id=""  class="A"> ,spring直接创建A实例,并返回。
  • FactoryBean:是一个特殊的bean,具有工厂生成对象的能力,只能生成特定的对象。bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。

<bean   id="" class="FB"> 先创建FB实例,使用调用getObject()方法,并返回方法的返回值

FB fb = new FB();

return fb.getObject();

BeanFactory 和 FactoryBean 对比?

BeanFactory:工厂,用于生成任意bean。

FactoryBean:特殊bean,用于生成另一个特定的bean。例如:ProxyFactoryBean ,此工厂bean用于生产***。

<bean  id=""   class="....ProxyFactoryBean"> 获得***对象实例,AOP使用。

9、Spring中涉及的设计模式。

简单工厂、单例模式、适配器模式、装饰器模式、***模式、观察者模式、策略模式、模版方法模式。