java

  1. 请说说多线程?
    线程是程序执行的最小单元,一个过程能够领有多个线程;各个线程之间共享程序的内存空间和零碎调配的资源,然而各个线程领有本人的栈空间;多线程的长处能够缩小程序的响应工夫,进步CPU利用率。
  2. 怎么保障线程平安?
    线程平安问题是指在多线程背景下,线程没有依照咱们的预期执行,导致操作共享变量出现异常。在Java中有三种形式:原子类、volatile关键字、锁。
  3. 说说你对反射的了解?
    反射就是在程序运行期间动静的获取对象的属性和办法的性能叫做反射。它可能在程序运行期间,对于任意一个类,都能晓得它的所有的办法和属性,对于任意一个对象,都能晓得他的属性和办法。获取Class对象的三种形式:getClass();xx.class;Class.forName("xxx");反射的长处:运行期间可能动静的获取类,进步代码的灵活性。毛病:性能比间接的Java代码要慢很多。利用场景:spring的xml配置模式,以及动静代理模式都用到了反射。
  4. ArrayList和LinkedList的区别?
    ArrayList底层是数组实现的,数组是一组间断的内存单元,读取快(应用索引),插入删除慢(须要从新计算大小或是更新索引)LinkedList底层基于双向链表,读取慢,插入删除快。
  5. 你晓得哪些线程平安的汇合?
    java.util包中的汇合类大部分都是非线程平安的,例如:ArrayList/LinkedList/HashMap等等,但也有少部分是线程平安的,像是Vector和Hashtable,它们属于很古老的API了,是基于Synchronized实现的,性能很差,在理论的开发中不罕用。个别能够应用Collections工具类中的synchronizedXxx()办法将非线程平安的汇合包装成线程平安的类。在java5之后能够应用concurrent包提供的大量的反对并发拜访的汇合类,例如ConcurrentHashMap/copyOnWriteArrayList等。
  6. String、StringBuffer、StringBuilder有什么区别?
    StringBuilder和StringBuffer十分相似,均代表可变的字符序列,而且办法也一样。String是不可变字符序列,效率低,然而复用率高;StringBuffer是可变字符序列、效率较高(增删)、线程平安;StringBuilder是可变字符序列、效率最高、线程不平安。
  7. 说说HashMap的底层原理?
    HashMap的底层是数组+链表+红黑树实现的。汇合put时,通过计算key键的哈希值来放入元素。若有key值雷同的哈希值时,会通过链表进行寄存,链表长度达到8时会开拓红黑树进行寄存,以此进步查问效率。
  8. 说说你理解的JVM内存模型?
    JVM由三局部组成:类加载子系统、执行引擎、运行时数据区。类加载子系统:能够依据指定的全限定名来载入类或接口;执行引擎:负责执行哪些蕴含在被载入类的办法中的指令;运行时数据区:分为办法区、堆、虚拟机栈、本地办法栈、程序计数器,当程序运行时,JVM须要内存来存储许多内容,例如:字节码、对象、参数、返回值、局部变量、运行时的两头后果等,把这些货色都存储到运行时数据区中,以便于管理。
  9. 说说JVM的垃圾回收机制?
    垃圾回收通常有三件事件要做。第一将决定哪些对象要回收,jvm决定了将未被援用的对象占用空间回收,通常用援用计数法或者可达性分析法,后者时jvm支流应用办法;第二是什么时候回收jvm,通常在内存不够用时,或定期回收;第三用什么形式回收,有分代回收,分区域回收法,收集器有年老代收集器、老年代收集、混合收集、整堆收集。
  10. 说说JVM的垃圾回收算法?
    援用计数法:每次赋值时均要保护援用计数器自身也有肯定的耗费,较难解决循环援用,个别不采纳这种形式;复制算法:将内存分为两块,每次只应用其中一块,当这块内存用完,就将还活着的队形复制到另一块下面,效率高且没有碎片,然而须要双倍的空间,年老代中应用复制算法;标记革除:先标记要革除的对象,而后对立回收这些对象,不须要额定的空间,但还是须要两次扫描,耗时重大并且会产生内存碎片;标记整顿:标记存活对象,而后将标记的存货对象按内存地址顺次排序,革除边界外未标记的对象,没有内存碎片,然而须要挪动对象。老年代个别有标记-革除和标记-整顿的混合实现。
  11. 说说类加载机制?
    类加载的过程中首先判断这个是否被加载过,如果没有被加载过,那么调用类加载器进行加载,判断这个类是否符合规范,如果不合乎就抛出异样,加载胜利就会成class对象。接下来是链接过程,分为三步:验证、筹备、解析。验证:确保文件符合规范,不会危害虚拟机本身的平安,对文件格式,字节码,元数据,符号援用进行验证;筹备:为类变量调配初始空间以及默认初始值,即零值,这里不会为实例变量调配,类变量调配在办法区中,实例变量追随对象调配在堆中,final润饰的在编译期间就调配了,在筹备阶段会显示的初始化;解析:将常量池内的符号援用转为间接援用的过程。链接过程实现之后开始初始化的过程:初始化阶段就是执行类构造方法的过程,此办法不须要定义,一个类只会被加载一次,虚拟机必须保障在多线程条件下类的构造方法是被加锁的。
  12. 说一下抽象类和接口的区别?
    抽象类多用于在同类事物中有无奈具体形容的办法的场景,而接口多用于不同类之间,定义不同类之间的通信规定;接口只有定义,而抽象类能够有定义和实现;接口须要实现,抽象类只能被继承,一个类能够实现多个接口,但一个类只能继承一个抽象类;抽象类偏向于充当公共类的角色,当性能须要累计时,用抽象类;接口被使用于实现比拟罕用的性能,性能不须要累计时,用接口。
  13. 请说说==与equals()的区别?
    ==比拟根本数据类型时,比拟的时两个数值是否相等;比拟援用类型时,比拟的是对象的内存地址是否相等。equals()没有重写时,Object默认以==来实现,即比拟两个对象内存地址是否相等;重写当前对象的内容进行比拟。
  14. 说说synchronize的用法及原理?
    用法:1.静态方法上,则锁的是以后类的Class对象;2.作用在一般办法上,则锁的是以后的实例(this);3.作用在代码块上,则须要在关键字前面的小括号里,显示指定一个对象作为锁对象。可能保障同一个时刻只有一个线程执行该段代码,保障线程平安,在执行实现或者出现异常时主动开释锁。原理:底层是采纳Java对象头来存储锁信息的,并且还反对锁降级。在jvm里的实现都是基于进入和退出Monitor对象来实现办法同步和代码块同步。
  15. 说说你对AQS的了解?
    AQS队列同步器,用来构建锁的根底框架,Lock实现类都是基于AQS实现的。它的原理就是保护一个共享资源,而后利用队列让线程队列获取资源的一个过程。外部实现的要害是队列和state状态,。它有两种线程模式:独占和共享模式。
  16. java哪些地方应用了CAS?
    CAS的全程是CompareAndSwap直译为比拟和替换。它是广泛处理器都反对的一条指令,这条指令通过判断以后内存值V,旧的预期值A,行将更新的值B是否相等来比照并设置新值,从而实现变量的原子性。CAS比拟典型的应用场景有原子类、AQS、并发容器。
  17. 说说static修饰符的用法?
    static润饰变量:属于动态变量也叫类变量,置属于类对象而不是实例,能够通过类名拜访,它个别会在类加载过程中被初始化,生命周期贯通整个程序,存储在办法区中;static润饰办法:即静态方法,一个类中的静态方法不能拜访该类的实例变量,只能拜访动态变量,同时还存在一个动态初始化块,他在类加载过程中被调用用于对该类中的动态变量进行操作;static润饰类:即动态外部类,他只能以内部类的模式存在,能够通过外部类的类名调用,它是也只能拜访到内部的动态成员。
  18. 说说线程的状态?
    线程的状态有6种。1.初始:线程被创立然而还没有调用start()办法;2.运行(就绪和运行):线程正在执行,但也可能在期待操作系统的调度;3.阻塞:若一个运行中的线程存在同步操作,此时锁被其余线程占用,该线程就会进入阻塞态期待获取锁;4.限期期待:正在运行的线程执行了Thread.sleep()办法或者设置了timeout的wait()办法,join办法等进入肯定工夫的期待,零碎主动唤醒;5.不限期期待:正在运行的线程执行了未设置timeout的wait办法或join办法进入期待,只有通过其余线程应用interrupt()或notify办法对其进行唤醒;6.死亡态:线程胜利执行结束或执行中抛出异常中断了线程会进入死亡态。
  19. 说说你对ThreadLocal的了解?
    ThreadLocal即线程变量,它将须要并发拜访的资源复制多份,让每个线程领有一份资源,因为每个线程都领有本人的资源正本,从而也就没有必要对该变量进行同步了。实现原理:每个Thread对象中都有一个ThreadLocal类的外部类ThreadLocalMap对象,他是一个键值模式的容器,以ThreadLocal对象的get和set办法来存取共享变量值,一个ThreadLocal用完后必须remove,否则会造成内存泄露。
  20. synchronized和Lock有什么区别?
    1.synchronized比Lock锁接口呈现要早;2.synchronized即能够润饰静态方法,也能够润饰实例办法以及代码块;3.synchronized的实现形式是基于JVM的,外人不能更改,而lock锁接口是内部API;4.synchronized反对的性能少于lock锁接口,lock锁接口在反对synchronized原有性能的根底上,还反对超时机制和响应中断等性能;5.synchronized底层采纳java对象头来存储锁信息,lock实现类是基于AQS实现的,晚期synchronized的性能很差,只有”无锁“和”有锁“两种状态,但前期synchronized引入了锁降级机制,有了很大改善,锁当初有四种状态:无锁、偏差锁、轻量级锁、重量级锁,缩小了获取锁和开释锁带来的性能耗费。
  21. 说说volatile的用法及原理?
    volatile次要用于润饰多线程中的共享变量,它能够保障变量的可见性和有序性,不能保障原子性。可见性是指在多线程环境中若某个线程批改了该变量,那么其余线程就能察觉到变量的批改。可见性次要是通过在内存模型中批改了某值则将它同步回主内存,在读取前从主内存刷新该变量值来实现的。有序性是指在某个线程中对该变量的操作程序是通明的,不会扭转的。在java中因为寄存器和内存处理速度存在微小差别所以java为了晋升运行速度会将编译好的代码进行肯定水平的重排,但不影响其在独立线程环境下的运行后果,然而在多线程环境中有可能出错。volatile能够防止这种指令重排实现其在多线程的程序统一的成果。
  22. 说一下final关键字?
    final被用来润饰类和类的成分。final属性:变量援用不可变,但对象外部内容可变,被final润饰的变量必须被初始化;final办法:该办法不能被重写,但子类能够应用该办法;final参数:参数在办法外部不容许被批改;final类:该类不能被继承,所有办法不能被重写,但未被申明为final的成员变量能够扭转。
  23. 请你说说重载和从新的区别,构造方法能不能重写?
    重载产生在同一个类中,要求办法名必须雷同,参数列表不同,重载的产生与办法的返回值和拜访修饰符无关,最终是生成了两个办法。重写是产生在父子类中的,子类重写办法的名称和参数列表必须和父类雷同,子类的返回类型或抛出的异样类型必须是父类的返回值或异样类型及其子类型。子类重写办法的拜访修饰符必须大于父类,若父类办法的修饰符为private则子类不能重写该办法。
  24. 说说你对Java汇合的理解?
    java中的汇合类次要都有Collection和Map这两个接口派生而出,其中Collection又派生出List、Set、Queue。所有的汇合类都是List、set、queue、map这四个接口的实现类。其中list代表有序的、可反复的数据汇合;set代表无序的、不可反复的数据汇合;queue代表先进先出的队列;map是又映射关系的汇合。最罕用的实现类有:ArrayList、LinkedList、HashMap、TreeMap、HashSet、TreeSet、ArrayQueue。
  25. 请你说说IO多路复用?
    IO多路复用指的是单个线程同时实现对多个IO事件的监听解决。linux提供了select、poll、epoll三种多路复用形式。select调用:查问有多少个文件描述符须要进行IO操作,特点:轮询次数多,内存开销大,反对文件描述符的个数无限;poll调用:和select简直差不多,然而它的底层数据结构为链表,所以反对文件描述符的个数无下限;epoll:更加高效的调用形式,底层的数据结构为红黑树加链表,防止大内存调配和轮询。
  26. 请你讲一下java8的新个性?
    1.Lambda表达式:可将性能视为办法参数,或者将代码视为数据,应用Lambda表达式能够简洁地示意单办法接口的实例;2.办法援用:提供了十分有用的语法,可间接援用已有Java类或对象的办法或结构器。与lambda联结应用,办法援用能够使语言的结构构造更紧凑简洁,缩小冗余代码;3.对接口进行了改良:容许在接口中定义默认办法,默认办法必须应用default润饰;4.Stream API:新增加的Stream API反对对元素流进行函数式操作;5.Date Time API:增强对日期工夫的解决。6.Optional类:用来解决空指针异样。
  27. 请你说说泛型、泛型擦除?
    泛型:java在jdk1.5时引入了泛型,在没有泛型之前,每次从汇合中读取的对象都必须进行类型转换,如果在插入对象时,类型出错,那么在运行时转换解决的阶段就会出错,在提出泛型之后就能够明确的指定汇合承受哪些对象类型,编译器就能通晓并且主动为插入的代码进行泛化,在编译阶段告知是否插入类型谬误的对象,程序会变得更加平安清晰。泛型擦除:java泛型是伪泛型,因为java代码在编译阶段,所有的泛型信息会被擦除,java的泛型基本上都是在编译器这个档次上实现的,在生成的字节码文件中不蕴含泛型信息的,应用泛型的时候加上的类型,在编译阶段会被擦除掉,这个过程成为泛型擦除。
  28. 说说你理解的线程通信形式?
    在java中提供了两种多线程通信形式别离是利用monitor和condition两种。具体应用那种通信形式与线程同步形式无关。对于synchronized来说,应用的是monitor的同步形式。罕用的办法有wait(),notify(),notifyAll()。对于lock锁接口来说,应用的是condition,依赖于lock锁的创立而创立,常应用的办法有await(),signal(),signalAll()。
  29. 说说JUC?
    JUC是java.util.concurrent的缩写,这个包中蕴含了反对并发操作的各种工具。1.原子类:遵循比拟和替换准则。能够用于解决单个变量的线程平安问题;2.锁:与synchronized相似,在蕴含synchronized所有性能的根底上,还反对超时机制,响应中断机制,次要用于解决多个变量的线程平安问题;3.线程池:能够更不便的治理线程,同时防止反复开线程和杀线程带来的耗费,效率高;4.并发容器:例如ConcurrentHashMap,反对多线程操作的并发汇合,效率更快。
  30. 说说HashMap和Hashtable的区别?
    Hashtable在实现Map接口时保障了线程安全性,而HashMap则时非线程平安的,所以Hashtable的性能不如HashMap,因为为了保障线程它就义了一些性能。Hashtable不容许存入null,无论是以null作为key或value,都会引发异样但HashMap是容许的。Hashtable是很古老的api,性能不好,不举荐应用,要在多线程下应用ConcurrentHashMap,它岂但保障了线程平安,也通过升高锁的粒度进步了并发拜访时的性能。
  31. 说说java的四种援用形式?
    1.强援用:以new关键字创立的援用都是强援用,被强援用的对象永远都不会被回收;2.软援用:以SoftRerference援用对象,被软援用的对象只有在内存不足时会被垃圾回收;3.弱援用:以WeakReference援用对象,被弱援用的对象肯定会被回收,它只能存活到下一次垃圾回收;4.虚援用:以PhantomReference援用对象,一个对象被援用后不会有任何影响,也无奈通过该援用来获取该对象,常识其再被垃圾回收时会收到一个零碎告诉。
  32. 说说你对ArrayList的了解?
    arrayList在jdk1.7的时候,创立容器的时候会在底层创立一个长度为10的object数组,在jdk1.8的时候,在创立容器的时候底层并不会立即创立,只有在第一次调用add办法的时候才会创立一个长度为10的数组,默认状况下,扩容为原来容量的1.5倍,同时将原有数组中的值复制到新的数组中,并且arraylist属于有序的,可反复的汇合,提供了iterator办法,加强了迭代能力。
  33. 说说BIO、NIO、AIO?
    unix提供了五种IO模型:阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO。BIO对应的时阻塞IO,一次只能操作一个IO;NIO是IO多路复用,一个线程能够同时解决多个IO申请,IO多路复用模型提供select、poll、epoll调用;AIO:也是基于epoll,特点是无效的申请才启动线程,现有操作系统实现再告诉服务端。
  34. 说说垃圾收集器?
    Serial(新生代)、Serial Old(老年代):实用于单核小CPU,单核工作,回收时会暂停其余工作stop the world;PawNew(新生代)、CMS(老年代):实用于多核CPU,谋求短暂工夫,多核工作,应用标记革除算法,最短的暂停工夫;Parallel Scavenge(新生代-标记复制算法)、Parallel Old(老年代-标记整顿算法):1.7,1.8默认的组合,实用于多核CPU,谋求最大吞吐量;G1 jdk1.9默认,应用于大内存多核CPU服务器,它不按整个新生代或老年代去回收,而是开拓了面向部分收集,实现了较小的收集暂停工夫和高吞吐量。
  35. 说说java的特点和长处,为什么要抉择java?
    1.排汇了c++的长处,摒弃了c++多继承和指针的简单应用,不须要对内存进行开释,具备垃圾回收机制;2.面向对象,易于开发和了解;3.跨平台,因为jvm,同一个代码能够再不同的平台机器上运行,.java文件通过编译成.class字节码文件再由jvm转成机器能辨认的机器码;4.内含大量的库,简化编写工作;5.应用于开发web.
  36. 介绍一下包装类的主动拆装箱与主动装箱?
    主动装箱、主动拆箱时JDK1.5提供的性能;主动装箱:把一个根本类型的数据间接赋值给对应的包装类型;主动拆箱是指把一个包装类型的对象间接赋值给对应的根本类型;通过主动装箱、主动拆箱性能简化根本类型变量和包装类对象之间的转换过程。
  37. 说说wait()和sleep()的区别?
    sleep办法是以后线程的休眠,让出cpu,然而不开释锁,它是Thread的静态方法,wait是以后线程期待,开释锁,是Object的办法;sleep没有开释锁,wait开释锁,两者都可暂停线程的执行,wait用于线程间的通信,sleep用于暂停线程。wait期待过程不占用CPU,sleep依然占用。wait调用后,须要别的线程调用同一个对象的notify办法。
  38. 说说你对线程池的了解?
    线程池能够无效的治理线程:1.它能够治理线程的数量,能够防止无节制的创立线程,导致超出零碎负荷直至解体;2.它能够让线程复用,能够大大地缩小创立和销毁线程所带来地开销。线程池须要依赖一些参数来管制工作地执行流程,其中最重要地参数有:corePoolSize外围线程池数、workQueue期待队列、maxinumPoolSize最大线程池数、handler回绝策略、keepAliveTime闲暇线程存活工夫。当咱们想线程池提交一个工作之后,线程池依照如下步骤解决这个工作:1.判断线程数是否达到corePoolSize,若没有则新建线程执行该工作,否则进入下一步;2.判断期待队列是否已慢,若没有则将工作放入期待队列,否则进入下一步;3.判断线程数是否达到maxinumPoolSize,如果没有则新建线程工作,否则进入下一步;4.采纳初始化线程池时指定地回绝策略,拒绝执行该工作;5.新的线程解决完当前任务后,不会立刻敞开,而是持续解决期待队列中地工作。如果线程地闲暇工夫达到了keepAliceTime,则线程池会销毁一部分线程,将线程地数量膨胀至corePoolSize。第二步中地队列能够有界也能够无界,若指定无界队列,则线程池永远无奈进入第三步,相当于废除了MaxinumPoolSizecabs参数。这种做法是非常危险的,如果工作在队列中产生大量的沉积,就很容易造成内存泄露。JDK为咱们提供了一个名为Executors的线程池的创立工具,该工具创立进去的就是带有无界队列的线程池,所以个别在工作中咱们不倡议应用这个类来创立线程池。
  39. 说说JVM的双亲委派模型?
    双亲委派模型的工作过程是,如果一个类加载器收到了类加载的申请,它首先不会本人去尝试加载这个类,而是把这个申请委派给父类加载器去实现,每一档次的类加载器都是如此,因而所有的加载申请最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈本人无奈实现这个加载申请时,子加载器才会尝试本人去实现加载。双亲委派模型最大的长处是能够防止类的笼罩。
  40. 说说java根本数据类型和援用类型?
    8种根本数据类型的变量的值寄存在栈内存,有char(16)、byte(8)、short(16)、int(32)、long(64)、float(32)、double(64)、boolean。援用类型的变量寄存援用地址,堆内存才是真正的值。类,接口,数组,string等为援用类型。
  41. 说说java的异样解决机制
    1.异样解决机制让程序具备容错性和健壮性,程序运行呈现情况时,零碎会生成一个Exception对象来告诉程序;2.解决异样的语句由try、catch、finally三局部组成。try块用于包裹业务代码,catch块用于捕捉并解决某个类型的异样,finally块则用于回收资源;3.如果业务代码产生异样,零碎创立一个异样对象,并将其提交给JVM,由JVM寻找能够解决这个异样的catch块,并将异样对象交给这个catch块解决。如果JVM没有找到,运行环境终止,java程序退出;4.java也容许程序被动抛出异样,当业务代码中,判断某项谬误的条件成立时,能够应用throw关键字向外抛出异样。
  42. 说说你对面向对象的了解?
    1.面向对象的三大基本特征:封装、继承、多态;2.封装:将对象的状态信息暗藏在对象外部,不容许内部程序间接拜访对象外部信息,让内部程序通过该类提供的办法来实现对外部信息的操作和拜访,进步了代码的可维护性;3.继承:实现代码复用的重要伎俩,通过extends实现类的继承,实现继承的类被称为子类,被继承的类称为父类;4.多态的实现离不开继承,在设计程序时,咱们能够将参数的类型定义为父类型,在调用程序时依据理论状况,传入该父类型的某个子类型的实例,这样就实现了多态。
  43. 请介绍一下拜访修饰符?
    private只能在以后类的外部被拜访;default能够被雷同包下的其它类拜访;protected能够被同一个包下的拜访;public无论拜访类和被拜访类在不在一个包下,有没有父子关系,这类成员都根本被拜访到。
  44. 说说java中罕用的锁及原理?
    通过synchronized关键字和Lock接口两种形式实现加锁。1.synchronized关键字通过monitor(同步监视器)来实现锁的获取和开释,每一个monitor相当于一个有序队列,底层通过java对象头的形式存储锁的信息;2.通过实现Lock接口,创立一个local,显式指定锁对象,每一个锁对象是一个condition,通过condition来实现线程同步,能够有多个,每个condition就是一个有序队列,相比synchronized的Lock更加灵便,Lock底层是通过AQS形象同步队列实现有序队列,同时还定义乐同步状态state来记录锁的信息。
  45. 说说List与Set的区别?
    List和Set都是Collection接口的子接口,它们的次要区别在于元素的有序性和重复性:List代表有序的元素能够反复的汇合,汇合中每个元素都有对应的顺序索引,它默认按元素的增加程序设置元素的索引,并且能够通过索引来拜访指定地位的汇合元素,另外,List容许应用反复元素;Set代表无序的元素不可反复的汇合,它通常不能记住元素的增加程序。
  46. 请讲一下java nio?
    nio补救了原来同步阻塞io的有余,它在规范的java代码中提供了高速的、面向块的io。nio有三个外围组件,别离是Buffer、Channel、Selector。Buffer:缓冲区,读写数据都要进过缓冲区,而不是通过流;Channel:通道,全双工双向通道,用来读取和写入数据的;Selector:多路复用器,一直的轮询注册在Selector上的Channel,如果有新的TCP接入,就会被轮询进去,Channel变成就绪状态,SelectionKey获取Channel的汇合,进行后续io操作。JDK应用epoll(),没有了最大连贯句柄1024/2048的限度,一个线程负责Selector的轮询,就能接入成千上万的客户端。

spring

  1. 说说你对MVC的了解?
    MVC是一种设计模式,在这种模式下软件被分为了三层,model模型层、view试图层、controller管制层,模型层次要是定义实体对象等数据,视图层次要是用户界面等,管制层次要是具体的业务逻辑相干负责申请的散发、把模型数据及时的反映在页面上,三者之间各司其职,升高了业务之间的耦合度。spring MVC框架就是MVC设计模式的最好实现。
  2. 说说你对AOP的了解?
    AOP是面向切面编程,它是一种编程思维,它是通过一种预编译形式和运行期间动静代理的形式实现不批改源码的状况下给程序动静增加性能的一种技术,能够升高代码的耦合度,便于管理,进步代码的可重用性。AOP的实现形式有两种:JDK动静代理,能够在运行时创立接口的代理实例。CGLib动静代理:能够在运行期间创立子类的动静实例。AOP的利用场景有:事务,日志治理等。
  3. 说说你对IOC的了解?
    管制反转。管制:对象的创立的管制权限;反转:将对象的管制权限交给spring。之前咱们创建对象时用new,当初间接从spring容器中取,保护对象之间的依赖关系,升高对象之间的耦合度。实现形式为依赖注入,有三种注入形式:结构器、setter、接口注入。
  4. 说说spring boot罕用的注解?
    @SpringBootApplication是springBoot的外围注解,用于开启主动配置,精确的说是通过注解内的@EnableAutoConfiguration注解实现的主动配置;@EnableAutoConfiguration主动配置注解,在启动Spring利用上下文时进行主动配置,主动配置通常时基于我的项目classpath中引入的类和已定义的bean来实现的;@Configuration配置类注解,依据一些特定条件来管制bean的实例化的行为;@ComponentScan:地位在springBoot的启动类上,spring包扫描。
  5. 说说Bean的作用域,以及默认作用域?
    Bean有五种不同的作用域singleton、prototype、session、request、golbal session,默认状况下,Bean在spring容器中是单例的,然而咱们能够通过@Scope注解来批改Bean的作用域。1.singleton:在spring容器中仅存在一个实例,即bean以单例模式存在;2.prototype:每次调用getBean()的时候,会new一个新的实例并返回;3.Session:同一个Http下的session共享一个Bean,不同HTTP下不同的session应用不同的Bean;4.request:每一次HTTP申请都会创立一个新的Bean;5.globalSession:同一个全局Session会共享一个Bean。
  6. 说说Bean的生命周期?
    创立、初始化、调用、销毁;bean的创立形式有四种,结构器、动态工厂、实例工厂、setter注入的形式。spring在调用bean的时候因为作用域的不同,不同的Bean初始化和创立的工夫也不同。在作用域为singleton的时候,bean是随着容器一起被创立好并且实例化的,在作用域为prototype的时候,bean是随着它被调用的时候才创立和实例化实现。而后程序就能够应用bean了,当程序实现销毁的时候,bean也被销毁。
  7. 简略介绍一下spring?
    spring是一个轻量级企业应用开发框架,它有两大外围性能,别离是ioc和aop,ioc管制反转是将创建对象的权限交给spring容器来进行治理,能够很好的起到解耦的作用,aop是一种编程思维,底层应用的是动静代理,能够在程序原有的性能上进行加强,罕用的中央有日志记录,权限验证等。
  8. 说说你对spring boot的了解,以及它和spring的区别?
    从实质上来说,springboot就是spring,它帮你实现了一些springbean配置;springboot应用习惯优于配置的理念让你的我的项目疾速运行起来;但springboot自身不提供spring的外围性能,而是作为spring的脚手架框架疾速达到构建我的项目的目标;springboot的长处,能够疾速构建我的项目,能够对支流开发框架的无配置集成,我的项目可独立运行,无需内部依赖servlet容器,提供运行时的利用监控,能够极大的进步开发和部署效率,能够与云计算人造集成;外围性能:1.主动配置:针对很多spring应用程序常见的利用性能,springboot能主动提供相干配置。2.起步依赖:springboot通过起步依赖为我的项目的依赖治理提供帮忙。起步依赖其实就是非凡的maven依赖和gradle依赖,利用了传递依赖解析,把罕用库聚合在一起,组成了几个为特定性能而定制的依赖。3.端点监控Lspringboot能够对正在运行的我的项目提供监控。
  9. 说说springboot的主动拆卸?
    springboot主动拆卸时,须要引入相应的starter,启动springboot后会主动配置相应的依赖和配置相应的初始化参数,以最便捷,最简略的形式实现第三方软件的集成。具体的配置过程是:springboot通过@EnableAutoConfiguration开启主动配置性能,加载spring.factories中注册的AutoConfiguration类,当某个AutoConfiguration类满足指定的失效条件时,实例化该AutoConfiguration中定义的Bean,并注入到spring容器中,实现依赖框架的主动配置。
  10. 说说springboot的启动流程?
    当springboot我的项目实现创立后会默认生成一个Application的入口类,该类中的main办法能够启动springboot我的项目,在main办法中,通过springApplication的静态方法,即run办法进行springApplication的实例化操作,而后针对该实例化对象调用另一个run办法去实现整个我的项目的初始化和启动;SpringApplication的run办法的中重要操作:获取监听器的参数配置,打印Banner信息,创立并初始化容器,监听器发送告诉。
  11. 介绍一个spring MVC的执行流程?
    1.用户向服务器发送申请,申请被spring的前端管制Servlet DispatcherServlet捕捉;2.DispatcherServlet对申请URL进行解析,失去申请资源标识符URI,而后依据该URI调用HandlerMapping取得该Handler配置的所有相干的对象,最初以HandlerExecutionChain对象的模式返回;3.DispatcherServlet依据取得的Handler,抉择一个适合的HandlerAdapter,提取request中的模型数据,填充handler入参,开始执行handler(controller),Handler执行实现后,向DispatcherServlet返回一个ModelAndVuew对象;4.DispatcherServlet依据返回的ModelAndView抉择一个适合的ViewResolver;5.通过ViewResolver联合Model和View来渲染视图,DispatcherServlet将渲染后果返回给客户端。
  12. 说说spring的事务管理?
    spring为事务提供了统一的模板,反对两种事务编程模型:1.编程式事务:spring提供了TransactionTemplate模板,利用模板咱们能够通过编程的形式实现事务管理,而无需关怀资源获取,服务,开释事务以及异样解决,编程式事务用法麻烦,然而能够事务管理的范畴管制的更加精准;2.使命式事务:申明式事务用法非常不便,咱们只需在类或办法上加上@Transactional注解便能够申明事务性,它是spring事务管理的亮点,在IOC配置中,指定事务的边界和事务属性,spring会主动在特定的事务边界上利用事务个性。
  13. 说说@Autowired和@Resource注解的区别?
    @Autowired是spring提供的注解,而@Resource是JDK提供的注解。@Autowired默认按类型拆卸,默认状况下必须要求依赖对象存在,如果要容许null值,能够设置它的required属性为false。如果想应用名称拆卸能够联合@Qualifier注解进行应用。@Resource默认依照名称进行拆卸,名称能够通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行名称查找。
  14. mybatis中#和$有什么区别?
    在MyBatis中$和#的两种展位符,应用$设置参数时,mybatis会创立一般的sql语句,执行sql时,间接将参数拼接在sql中,可能会产生sql注入攻打,但在某些场景中,比方须要动静指定sql语句中的列名时,就只能应用$占位符。应用#设置参数时,mybatis会创立预编译的sql语句,预编译的sql语句执行效率高,并且能够避免sql注入攻打,在理论开发中,大部分状况下应用#占位符。
  15. 介绍一下Mybatis的缓存机制?
    mybatis的缓存机制:一级缓存称为本地缓存,它默认启动,存在于sqlSession的生命周期中,他会把办法和入参计算之后生成一个key来存储缓存。二级缓存能够在配置文件setting中手动配置,默认敞开,在应用的时候在Mapper.xml文件中也须要加上标签。二级缓存存在与SqlSessionFactory中,他能够实现多个sqlSession缓存的共享,以名称空间为单位存储,咱们在开发的时候一班不应用二级缓存,因为它的弊大于利,例如在两个名称空间中都有对某个表的操作,一个名称空间改了,不会影响另一个的缓存,就会造成内存不统一。个别咱们会应用redis来实现缓存。

数据库

  1. 请你说说mysql索引,以及它们的益处和害处?
    mysql索引是一种帮忙疾速查找数据的数据结构,能够把它了解为书的目录,通过索引可能疾速找到数据所在位置。场景的索引数据结构有:Hash表,通过hash算法疾速定位数据,但不适宜范畴查问,因为须要每个key都进行一次hash、二叉树,查找和批改效率都比拟高,然而在InnoDB引擎中应用的索引是B+ Tree,相较于二叉树,B+ Tree这种多叉树,更加矮宽,更适宜存储在磁盘中。应用索引减少了数据查找的效率,然而绝对的因为索引也须要存储到磁盘,所以减少了存储的压力,并且新增数据时须要同步保护索引。然而正当的应用索引可能极大进步咱们的效率。
  2. 请你讲讲B树和B+树?
    B树和B+树都是均衡多路查找树,B+树中,数据寄存在叶子节点中,其它节点寄存key,而B树中,数据寄存在叶子节点和非叶子节点中。1.因为B+树非叶子节点存储的是关键字,所以绝对与b树来说一页就能包容更多的关键字,b+树就会变得更宽更矮,从而读取关键字时就能缩小io次数,进步了查问效率;2.因为b+树的叶子节点是通过链表链接的,并且是叶子节点有序的,所以在范畴查问时b+树只须要查找到范畴的上限而后遍历叶子节点就能失去整个范畴的记录;3.b+树的查问效率更加稳固,因为每次查问所走的门路长度都雷同,只须要从根节点查到叶子节点即可。
  3. 数据库为什么不必红黑树而应用B+树?
    AVL树和红黑树根本都是存储在内存中才会应用的数据结构。而数据库中的数据的索引会十分大,索引为了缩小内存的占用,索引会被存储到磁盘文件中,此时影响数据库查问效率的次要隐衷就是磁盘的IO次数。AVL树和红黑树因为一个父节点只能存储两个子节点。所以应用AVL树或红黑树存储大规模数据时,树的深度就会很深,此时磁盘的IO次数也会大幅度减少。B+树中一个父节点有多个子节点,缩小了树的深度,磁盘IO次数也相应的缩小。
  4. 请你说说乐观锁和乐观锁?
    乐观锁:乐观锁总是假如最好的状况,每次去拿数据的时候默认他人不会批改,所以不会上锁,只有当更新的时候会判断一个在此期间有没有更新了这个数据,实用于多读,能够应用版本号机制进行管制。乐观锁:乐观锁总是假如最坏的状况,每次去拿数据时都认为他人会批改,所以每次在拿数据时都会上锁,这个他人想拿这个数据时会阻塞直到拿到锁。mysql数据库的共享锁和排他锁都是乐观锁的实现。
  5. 请你说说mysql的事务隔离级别?
    事务的隔离级别有:未提交读、提交读、可反复读、串行化四种隔离级别。数据库多个事务同时执行时可能造成事务的一致性问题:脏读,不可反复读,幻读;提交读能够解决脏读的问题:脏读就是线程A批改一个数据没有提交,线程B读取了这个批改的数据之后线程A回滚,线程B读取到的数据就变成了脏数据。可反复读能够解决脏读和不可反复度的问题,不可反复读就是事务A屡次读取一个数据,事务B在A读取的过程中进行了批改,导致事务A屡次读取到的数据不统一。串行化能够同时解决三个问题,幻读就是事务A对一个表进行读取,事务B在A读取的时候增减或者删除数据,导读事务A读取到的数据并不统一。
  6. 说说聚簇索引和非聚簇索引?
    它们最大的区别是索引和数据是否放在一起。聚簇索引:索引和数据放在一起,叶子节点保留数据行。非聚簇索引:索引和数据离开寄存,叶子节点寄存的是指向数据行的地址。
  7. 请你说说mysql的数据库引擎有哪些,各自有什么区别?
    1.InnoDB引擎是mysql的事务齐全存储引擎,具备提交、回滚和解体复原性能,反对行锁,增删改性能更优;2.MyISAM引擎反对全文索引,只反对表级锁,通常用于只读或以读为主的场景,表占用空间较小;3.Memory引擎是将所有数据都存储在RAM中,以便在须要疾速查找非关键数据的环境中进行快速访问,以前被称为HEAP引擎;4.Archive引擎非常适合存储大量的独立的历史数据,领有高效的插入速度,查问反对较差。
  8. mysql主从同步是如何实现的?
    复制replication是mysql数据库提供的一种高可用高性能的解决方案,个别用来建设大型的利用。总的来说,replication的工作原理分为以下3个步骤:1.主服务器master把数据更改记录到二进制日志中binlog中;2.从服务器slave把主服务器的二进制日志复制到本人的中继日志relay log中;3.从服务器重做中继日志中的日志,把更改利用到本人的数据库上,以达到数据的最终一致性。
  9. 请你介绍以下数据库的ACID?
    原子性A(atomicity):事务中的任何一个sql语句执行失败,那么整个事务都应该是失败的,曾经执行胜利的sql语句也应该回撤,数据库的状态也应该回到事务执行前的状态;一致性C(consistency):事务将数据库从一种状态转变为另一种状态,在转换实现后,数据的完整性束缚并没有产生扭转;隔离性I(isolation):每个事务读写操作的对象须要与其余事务读写操作事务对象互相拆散,即该事务提交前对其余事务都不可见;持久性D(durability):事务一旦执行胜利,那么后果是永久性的,哪怕零碎产生谬误,数据库也能将数据恢复。

redis

  1. 说说redis的数据结构?
    redis有五种根本数据类型String、hash、list、set、zset和三种非凡数据类型geo、hyperloglog bitmap。String:底层是一个动静字符串,反对扩容,存储字符串;list:存储有序能够反复的元素,底层数据结构是双向链表/压缩链表;hash:存储的是键值对,底层是ziplist和hash;set:存储的不可反复元素,底层数据结构能够是hash和整数数组;zset:存储的是有序的不可反复的元素,底层是ziplist和链表。
  2. 说说redis的长久化策略?
    redis的长久化形式有两种:RDB和AOF。RDB:它是通过数据集快照的形式来记录redis中的所有数据,在某个时间段内,将数据写入一个临时文件中,长久化完结,用这个临时文件替换上次的长久化文件,达到数据恢复。益处:只有一个dump.rdb文件,便于存储,容灾性较好,性能最大化,子过程来实现写操作,主过程持续解决命令。毛病:数据安全性低,RDB是隔一段时间进行一次备份,在此期间,如果产生了异样,可能导致数据的不完整性。AOF:它是通过记录redis的所有命令,每执行一次就记录一次数据,保留在AOF文件中。长处:保障了数据的安全性和完整性,即使是中途宕机,也能够恢复过来。毛病:他的文件比RDB文件大,如果是数据集大的时候,它的复原速度比RDB文件慢。redis默认是用RDB文件存储。
  3. 如何利用redis实现一个分布式锁?
    分布式环境下会产生多个server并发批改一条数据的状况。因而须要分布式锁。咱们能够在redis中寄存一份代表锁的数据。最简略的形式就是setnx key value然而如果客户端遗记解锁就会造成死锁。如果给锁减少过期工夫,expire key second会产生另一个问题,因为这两步并非原子性操作,如果第二部失败依然会呈现死锁问题。因而能够通过set key value nx ex seconds操作将两步封装成原子操作,解锁就是将代表锁的数据删除即可。但不能简略的del key因为如果过程A在没有执行结束时锁到期开释了,但进行A完结后依然会开释锁,这时候就会开释其余过程的锁。所以要给key赋一个随机值代表过程加个标识,过程A开释锁时进行判断是本人的再开释锁。另外开释这部分要保障原子性否则会死锁。能够应用Lua脚本将指令编排到一起,Lua执行是原子性的。
  4. 说说缓存穿透、击穿、雪崩的区别?
    缓存穿透:客户端拜访redis中不存在的数据,是的申请中转存储层,导致负载过大甚至宕机,起因可能是业务层误删了缓存或是有人歹意拜访不存在的数据。解决形式:1.存储层未命中后,返回空指存入存储层,客户端再次拜访时,缓存层间接返回空值;2.将数据存入布隆过滤器,拜访缓存之前经过滤器拦挡,若申请的数据不存在则间接返回空值。缓存击穿:一份热点数据,它的访问量十分大,在它缓存生效的霎时,大量申请中转存储层,导致服务解体。解决方案:1.永不过期,对热点数据不设置过期工夫;2.加互斥锁,当一个线程拜访该数据时,另一个线程只能期待,这个线程拜访之后,缓存中的数据将被重建,届时其余线程就能够从缓存中取值。缓存雪崩:大量数据同时过期,或是redis节点故障导致服务不可用,缓存层无奈提供服务,所有的申请中转存储层,造成数据库宕机。解决方案:1.防止数据同时过期,设置随机过期工夫;2.启用降级和熔断措施;3.设置热点数据永不过期;4.采纳redis集群,一个宕机,另外的还能用。
  5. redis如何与数据库放弃双写一致性?
    先更新数据库再删除缓存,缓存删除失败须要重试。
  6. 说说redis的单线程架构?
    redis采纳的是单线程+IO多路复用技术。这里的单线程指的是redis中读写操作和网路IO应用的是有一个线程来实现,然而其余操作是有其余线程实现,例如长久化操作。单线程既能够简化数据结构和算法的实现,同时也打消了线程切换和锁竞争所带来的耗费。redis中采纳的IO多路复用技术实现了单线程下同时解决多个IO申请。redis为生命这么块:1.单线程进行读写操作,防止线程切换和锁竞争带来的耗费;2.redis操作是在内存中进行的;3.最重要的就是采纳了IO多路复用技术,实现了在网路IO中能都解决大量并发申请,实现高吞吐率。
  7. 如何实现redis的高可用?
    主从复制:写肯定是在主服务器上,而后主服务器同步给从服务器。毛病:当主服务器挂掉的时候,不能主动切换到从服务器上。主从服务器存储数据一样,内存可用性差。长处:在肯定水平上分担主服务器读的压力。哨兵模式:构建多个哨兵节点监督主从服务器,当主服务器挂掉的时候,主动将对应的从服务器切换成主服务器。长处:实现主动切换,可用性高。毛病:主从服务器存储数据统一,内存可用性差。还要额定保护一套哨兵零碎,较为麻烦。集群模式:采纳无核心节点的形式实现。多个主服务器相连,一个主服务器能够有多个从服务器,不同的主服务器存储不同的数据。长处:可用性更高,内存可用性高。
  8. 说说Redis的主从同步机制?
    主从同步分为全量同步和增量同步,从机第一次连贯主机时不会携带主机id和数据偏移量,主机会对从机的主机id进行校验,如果不是则阐明是第一次连贯须要进行全量同步,原理就是将以后数据写到RDB文件发送给从机,从机接管到文件之后将数据读取到从机的内存中,增量同步是第二次和之后连贯才产生,当从机第一次同步实现之后,主机在这期间数据发生变化,会将命令存储在缓冲区,当校验到从机的id正确是会获取从机的偏移量,从机从偏移量记录的命令开始将从机没同步的数据的操作命令发送给从机执行,执行实现后即实现了数据同步。
  9. 说说redis的缓存淘汰策略?
    惰性删除:客户端拜访一个Key的时候,redis先查看它的过期工夫,如果曾经过期了就立即删除这个key。定期删除:redis会将设置了过期工夫的key保留到一个字典外面,而后每过十秒就扫描一次。这个定期删除也不扫描字典中所有的Key,而是采纳了一种简略的弹性策略。定期删除对内存更加敌对,而惰性删除对CPU更加敌对,所以redis采纳的是定期删除+惰性删除。