Java开发面试题

Java面试题整理

1、Java基础

1、JDK 和 JRE 有什么区别?

JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。
JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。
具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。

2、简述Java的jvm虚拟机的运行原理

1)JVM是可运行Java代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收,堆 和 一个存储方法域。JVM是运行在操作系统之上的,它与硬件没有直接的交互。
Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。
2)运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),
再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行
    Java源文件—->编译器—->字节码文件
    字节码文件—->JVM—->机器码
    
    每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是Java为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。

参考:https://blog.csdn.net/yunzhaji3762/article/details/81038711

3、GC是什么? 为什么要有GC

Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,在使用JAVA的时候,一般不需要专门编写内存回收和垃圾清理代码。这是因为在Java虚拟机中,存在自动内存管理和垃圾清扫机制。

电脑的内存大小的不变的,当我们使用对象的时候,如使用new关键字的时候,就会在内存中生产一个对象,但是我们在使用JAVA开发的时候,当一个对象使用完毕之后我们并没有手动的释放那个对象所占用的内存,就这样在使用程序的过程中,对象越来越多,当内存存放不了这么多对象的时候,内存不够就会导致溢出等错误导致程序崩溃.

JAVA为了解决这个问题就推出了这个自动清除无用对象的功能,或者叫机制,这就是GC,或者叫垃圾回收,其实就在用来帮你清理垃圾对象的,好让你安心写代码,不用管内存释放,对象清理的事情了。

Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,且Java语言没有提供释放已分配内存的显示操作方法。

垃圾回收只与内存有关,清理内存外的资源依靠finalize()方法。垃圾回收机制在回收某个对象的内存前会调用该对象的finalize()方法。

垃圾回收以单独的线程在后台运行,为减少虚拟机额外消耗,一般在内存不足时会进行垃圾回收,所以就算强制系统垃圾回收,垃圾回收也不一定发生 

4、解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法;

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;
而通过new关键字和构造器创建的对象放在堆空间;
程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在静态区中。
栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用
的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。

5.说出一些常用的类,包,异常请各举5个

常用的类:BufferedReader BufferedWriter FileReader FileWirter String Integer Math Random Date
SimpleDateFormat Calendar System BigDecimal ...
常用的包:java.lang  java.awt  java.io  java.util  java.sql  java.text
常用的异常:
    RuntimeException            Java.lang 包中多数异常的基类
        ArithmeticException         算术错误,如除以 0
        IllegalArgumentException    方法收到非法参数
        IndexOutOfBoundsException   地址下标越界
        NullPointerException        空指针异常
        ClassCastException          类转换异常
        NumberFormatException       数据格式异常
    ClassNotFoundException      不能加载请求的类
    IOException I/O             异常的根类
    FileNotFoundException       不能找到文件
    IllegalAccessException      对类的访问被拒绝
    NoSuchMethodException       请求的方法不存在
    InterruptedException        线程中断  
    SQLException                SQL异常  

6、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上

switch(expr1)中,expr1是一个整数表达式。
因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。
现在1.7及更高版本中String可以用于swtich,还有枚举类型也支持

7、String s= new String(“abc”) 创建了几个String Object ?如果是多个,那么他们之间有什么区别?

两个或一个,“abc”对应一个对象,这个对象放在字符串常量池,
常量“abc”不管出现多少遍,都是缓冲区中的那一个。new String每写一遍,
就创建一个新的对象,它依据常量“abc”对象的内容来创建出一个新String对象。
如果以前就用过“abc”,这句代表就不会创建”abc”自己了,直接从缓冲区拿。

8、为什么说String是不可变的

String类被final修饰,不可被继承。
String的成员变量char数组value被final修饰,初始化后不可更改引用。
String的成员变量value访问修饰符为private,不对外界提供修改value数组值的方法。

由于String对象的内容(对象内存地址所存的内容)是不能改变的,但String引用(变量)是可以改变的,可以让其指向另外一个字符串。(不能修改字符串的内容,但可以修改字符串的引用)
String str = "hello";
str = str + "world";
System.out.println(str);// hello world
虽然str打印的结果变了,但不是String对象本身发生改变,而是str引用到了其他String对象(创建了一个新的字符串 "helloworld")。要区分修改的是"地址"还是"地址对应内存的内容"。

如果非要改,只能就借助反射进行修改

9、Java的访问修饰符是什么?

访问权限修饰符是表明类成员的访问权限类型的关键字。使用这些关键字来限定程序的方法或者变量的访问权限。
它们包含:
    public: 所有类都可以访问 
    protected: 同一个包内以及所有子类都可以访问
    默认: 归属类及相同包下的子类可以访问
    private: 只有本类才能访问

10.方法重载和方法重写区别?

方法重载:同一个类中,方法名相同,参数的类型、顺序和个数不同,与返回值类型和方法访问修饰符无关
方法重写:不同类中,发生在继承类中,方法名称、参数类型、返回值类型全部相同,被重写的方法不能拥有比父类更严格的权限

11.Java实现多态的必要条件?

继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法

12.抽象类和接口的区别?

抽象类 是一个不能被实例化的类,因为它其中存在抽象方法,但它的其它行为和一个普通类没什么不同。
接口是java为了弥补不能多继承提供的概念,接口之间支持多继承,接口中只允许存在公有静态常量或公有的抽象方法,一个类可实现多个接口,从而扩展不同的功能。java1.8之后,支持默认方法。

13.this、super、static、final关键字的用法

this:代表本类当前对象的引用,谁调用我,我就代表谁。
super:代表当前对象父类的内存空间标识。(可以理解为父类的引用,通过super可以访问父类的成员)
static:静态,可以修饰以下
    变量:将实例变量升级为类变量,通过类名可以直接.出来
    方法:将实例方法升级为类方法,通过类名可以直接.出来
    代码块:静态代码块随着类的加载而加载,一般是用来加载驱动的。只在类加载的时候执行一次,优先于构造方法执行
final:最终的,可以修饰以下
    变量:由变量变成常量,值不可修改
    方法:表示此方法不能被重写
    类:表示此类不能被继承

14、字符串对象String,StringBuilder ,StringBuffer之间的区别?

String是不可变对象,经常改变内容的字符串最好不要使用String,任何对String的改变都会引发新的String对象的生成

StringBuffer是可变的字符串,字符串经常改变的情况可使用StringBuffer,更高效,任何对它所指代的字符串的改变都不会产生新的对象。

JDK1.5后提供了StringBuilder,等价StringBuffer。作为一个简易替代,他们的原理和操作基本相同,区别在于StringBuffer支持并发操作,线性安全的,适合多线程中使用。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用,而且大量字符操作时候,相对来说执行会快.

因此:
        String:适用于少量的字符串操作的情况
        StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
        StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
        
回顾扩容机制

15、对比HashMap和HashTable?

两者都是用key-value方式获取数据。它们之间有以下区别: 
1)线程安全性不同
  	Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情况下是非Synchronize的。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现同步,但使用HashMap时就必须要自己增加同步处理。
  	
  	虽然HashMap不是线程安全的,但是它的效率会比Hashtable要好很多。这样设计是合理的。在我们的日常使用当中,大部分时间是单线程操作的。HashMap把这部分操作解放出来了。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。

2)key和value是否允许null值
    其中key和value都是对象,并且不能包含重复key,但可以包含重复的value。
    
    Hashtable中,key和value都不允许出现null值。但是如果在Hashtable中有类似put(null,null)的操作,编译同样可以通过,因为key和value都是Object类型,但运行时会抛出NullPointerException异常,这是JDK的规范规定的。

    HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

3)内部实现使用的数组初始化和扩容方式不同
  HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
  Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。

扩展:在使用 HashMap 的时候,用 String 做 key 有什么好处?

    HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,避免重复计算hashCode,所以相比于其他对象更快。

    如何将类作为一个HashMap的key?
        实现对象作为键需要重写hashCode()和equals()方法。

    两个方法的作用参考:https://www.cnblogs.com/Qian123/p/5703507.html

16、ArrayList和LinkedList、Vector的区别?

1)ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 
2)对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
3)对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据
    Vector和ArrayList类似,但是是线程安全的,所以开销大,效率低, Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%.

17、编写多线程程序有几种实现方式?

1) 一种是继承Thread类;
2) 一种是实现Runnable接口。
两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活。
3)启动一个线程使用的是start方法,自动调用线程的run方法。
4)通过Callable和FutureTask创建线程,最大特点就是可以有返回值
5)通过线程池创建线程

18、sleep和wait的区别。

整体的区别其实是有四个:
1、sleep是线程中的方法,但是wait是Object中的方法。
2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。
3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。
参考:https://baijiahao.baidu.com/s?id=1647423693517849309&wfr=spider&for=pc

19、java如何停止一个线程

1)要终止一个线程,并不是简单的调用stop()方法,stop()就像linux中的kill一个线程一样是非常暴力的,虽然在Java的API中仍然可以调用stop()方法,但是和suspend,resume方法一样,是过期了的,不建议使用的,因为stop()在结束一个线程时并不会保证线程的资源正常释放,会导致程序可能会出现一些不确定的状态。 
正确终止一个线程的方法有以下几种:
1)interrupt方法 
    当其他线程调用当前线程的interrupt方法时,即设置了一个标识,表示当前线程可以中断了,至于什么时候中断,取决于当前线程。当前线程通过调用isInterrupted()方法来判断自身是否被中断,如果返回true,则说明当前线程已经中断,这种通过标识位或中断操作的方式能够使线程在终止时有机会清理资源,而这种方式也更加安全。
    
2)volatile关键字 
    定义一个用volatile修饰的成员变量来控制线程的停止,这点是利用了volatile修饰的成员变量可以在多线程之间达到共享,也就是可见性来实现的,同一时刻只能由一个线程来修改该变量的值。

3)程序运行结束或者出现异常
    当一个程序运行结束或者出现异常后,当前线程自然也就终止了

20、final、finally、finalize的区别。

1)final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用,不能在子类中被重写。 

2)finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。 

3)finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。

21、JVM调优,线程,同步锁等相关内容。

java面试汇总中的JVM篇,多线程&并发篇。

22、如何比较日期的大小,如何格式化日期

1)获取毫秒数,判断大小
2)使用Date类提供的方法after或者before方法
3)SimpleDateFormat的format方法可以格式化日期,格式为yyyy-MM-dd HH:mm:ss
4)java8的新用法:使用LocalDateTime

23、如何将字符串反转?

1)使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
2)将字符串转为字符数组,循环倒序输出
3)直接使用charAt方法从后往前输出

24、String 类的常用方法都有那些?

indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。

25、java 中 IO 流分为几种?

按流向来分:
	输入流(InputStream/Reader)、输出流(OutputStream/Writer)。
按类型来分:
	字节流(InputStream/OutputStream)和字符流(Reader/Writer)(非纯文本文件,不要用字符流,会导致文件格式破坏)。
	字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。
还可以划分为:
	节点流(低级流直接跟输入输出源对接,如:FileInputStream/FileOutputStream/FileReader/FileWriter)和处理流(高级流建立在低级流的基础上,如:BufferedReader/BufferedReader可对节点流经行包装,使读写更快)
	
实际用法,回顾上课的代码案例

26、Collection 和 Collections 有什么区别?

1)java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。

2)Collections则是集合类的一个工具类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。

27、如何实现数组和 List 之间的转换?

1)List转换成为数组:调用ArrayList的toArray方法。
2)数组转换成为List:调用Arrays的asList方法。这种方法执行后,是不能再调用add方法的,这个要注意。

28、线程的五种状态

创建、就绪、运行、阻塞和死亡。

创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。

就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。

运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。

阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。

死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪

29、java反射的原理,作用,和用法

原理:
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

作用:
    在运行时根据一个对象,获取所属的类
    在运行时获取任意一个对象所在类所具有的成员变量和方法
用法:
    要想操作反射,必须先拿到反射的类对象,方法三种:
    1)通过通过Class.forName("全类名")
    2)类名.class
    3)对象.getClass()
参考:https://blog.csdn.net/weixin_42724467/article/details/84311385

30、Java序列化的作用

序列化的原本意图是希望对一个Java对象作一下“变换”,变成字节序列,这样一来方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,
另外变换成字节序列也更便于网络运输和传播,所以概念上很好理解:
    序列化:把Java对象转换为字节序列。
    反序列化:把字节序列恢复为原先的Java对象。

序列化是不是靠Serializable接口实现的
    不是,它仅仅只是做一个标记用!!!它告诉代码只要是实现了Serializable接口的类都是可以被序列化的!然而真正的序列化动作不需要靠它完成。否则异常NotSerializableException

serialVersionUID是序列化前后的唯一标识符
    serialVersionUID序列化ID,可以看成是序列化和反序列化过程中的“暗号”,在反序列化时,JVM会把字节流中的序列号ID和被序列化类中的序列号ID做比对,只有两者一致,才能重新反序列化,否则就会报异常来终止反序列化的过程。

默认如果没有人为显式定义过serialVersionUID,那编译器会为它自动声明一个!
    如果在定义一个可序列化的类时,没有人为显式地给它定义一个serialVersionUID的话,则Java运行时环境会根据该类的各方面信息自动地为它生成一个默认的serialVersionUID,一旦像上面一样更改了类的结构或者信息,则类的serialVersionUID也会跟着变化!

参考:https://blog.csdn.net/qq_32575047/article/details/80070590

2、前端(HTML+JS+JQuery)

1、页面导入样式时,使用link和@import有什么区别?

   1)本质的差别:link属于XHTML标签,而@import完全是CSS提供的一种方式。

  2)加载顺序的差别:当一个页面被加载的时候(就是被浏览者浏览的时候),link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再被加载。所以有时候浏览@import加载CSS的页面时开始会没有样式(就是闪烁),网速慢的时候还挺明显。

  3)兼容性的差别:@import是CSS2.1提出的,所以老的浏览器不支持,@import只有在IE5以上的才能识别,而link标签无此问题。

  4)使用dom(document o bject model文档对象模型  )控制样式时的差别:当使用javascript控制dom去改变样式的时候,只能使用link标签,因为@import不是dom可以控制的.

2、 $(this) 和 this 关键字在 jQuery 中有何不同?

$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本,用val() 获取值等等。

而 this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如 $(this)。

3、清楚浮动的方法?

1)父级div定义 height 
    原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。 
    优点:简单、代码少、容易掌握

    缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

2)结尾处加空div标签 clear:both

    原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度 
    优点:简单、代码少、浏览器支持好、不容易出现怪问题 
    缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好

3)父级div定义 overflow:hidden

    原理:overflow:hidden时,浏览器会自动检查浮动区域的高度 
    优点:简单、代码少、浏览器支持好 
    缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。

4)父级div定义 伪类:after

    原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似
    优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等) 
    缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持

4、$(document).ready()方法和window.onload有什么区别?

1)、window.onload方法是在网页中所有的元素完全加载到浏览器后才执行的。且只能写一个

2)、$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数,可以写多个。

5、jquery中 . g e t ( ) 提 交 和 .get()提交和 .get().post()提交有区别吗?

相同点:都是异步请求的方式来获取服务端的数据;
异同点:
    1)请求方式不同:$.get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的。
    2)参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。
    3)数据传输大小不同:get方式传输的数据大小有限制 而POST内容要大很多
    4)安全问题: GET 方式请求不安全。

6、js 字符串操作函数有哪些

    indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1 。
    lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1 。  
    charAt() – 返回指定位置的字符。 
    match() – 检查一个字符串是否匹配一个正则表达式。
    substr() 函数 -- 返回从string的startPos位置,长度为length的字符串
    substring() – 返回字符串的一个子串。传入参数是起始位置和结束位置,注意被问到跟Java的区别
    replace() – 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。 
    split() – 通过将字符串划分成子串,将一个字符串做成一个字符串数组。
    length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。
    toUpperCase() – 将整个字符串转成大写字母。
    。。。。               

7、你是如何使用jquery中的ajax的?

如果是一些常规的ajax程序的话,使用$.get(),$.post(),一般使用的是$.post() 方法。
如果需要设定beforeSend(提交前回调函数),error(失败后处理),success(成功后处理)及complete(请求完成后处理)回调函数等,
标准语法是$.ajax()。
其中ajax的基本语法是:
1)url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。

2)type: 要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

3)timeout: 要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。

4)async: 要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。

5)cache: 要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。

6)data: 要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看  processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。

7)dataType: 要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。

8.beforeSend:要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。
        function(XMLHttpRequest){
           this;   //调用本次ajax请求时传递的options参数
        }
9)complete:
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
      function(XMLHttpRequest, textStatus){
         this;    //调用本次ajax请求时传递的options参数
      }

10)success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
     (1)由服务器返回,并根据dataType参数进行处理后的数据。
     (2)描述状态的字符串。
     function(data, textStatus){
        //data可能是xmlDoc、jsonObj、html、text等等
        this;  //调用本次ajax请求时传递的options参数
     }

11)error:要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:
       function(XMLHttpRequest, textStatus, errorThrown){
      //通常情况下textStatus和errorThrown只有其中一个包含信息
      this;   //调用本次ajax请求时传递的options参数
       }

12)contentType:要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
案例代码:
$(function(){
    $('#send').click(function(){
     $.ajax({
         type: "GET",
         url: "test.json",
         data: {username:$("#username").val(), content:$("#content").val()},
         dataType: "json",
         success: function(data){
             $('#resText').empty();   //清空resText里面的所有内容
             var html = ''; 
             $.each(data, function(){
                   。。。;
             });
             $('#resText').html(html);
              }
     });
    });
});

8、http常见状态码有哪些?

2xx (成功)表示成功处理了请求的状态代码
    200 (成功) 服务器已成功处理了请求。
    204 表示请求处理成功,但没有资源返回
3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
    301 表示永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI
    302 表示临时性重定向
    304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容
4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处理
    400 (错误请求) 服务器不理解请求的语法。 
    401 表示未授权(Unauthorized),当前请求需要用户验证
    403 (禁止) 服务器拒绝请求。
    404 (未找到) 服务器找不到请求的网页。
5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错
    500 (服务器内部错误) 服务器遇到错误,无法完成请求。
    501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
    502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
    503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
    504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
    505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

3、JavaWeb

1、Tomcat目录结构及作用

bin: 存放各种平台下用于启动和停止Tomcat的脚本文件
conf: 存放Tomcat服务器的各种配置文件,如修改端口配置文件server.xml
lib: 存放Tomcat服务器所需的各种JAR文件
logs: 存放Tomcat的日志文件
temp: Tomcat运行时用于存放临时文件
webapps: 当发布Web应用时,默认情况下会将Web应用的文件存放于此目录中
work: Tomcat把由JSP生成的Servlet放于此目录下

2、JavaWeb中,如何解决乱码问题?

第一种:(get方式)
    在Tomcat目录结构\conf\server.xml中设置字符集
    <Connector  port="8080"  protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443"  URIEncoding="UTF-8">
第二种:(get方式)     
    String name = request.getParameter("name");
    // 对请求数据进行字符解码和转码
    name = new String(name.getBytes("ISO-8859-1"), "UTF-8");
      
第三种:(post方式)      
    // 设置读取请求信息的字符编码为UTF-8,统一处理使用字符集编码过滤器
    request.setCharacterEncoding("UTF-8");   

3、转发重定向的区别?

1)请求的转发: 地址栏是初次发出请求的地址.--这个是重点,mvc架构的核心
    请求的重定向: 地址栏不再是初次发出的请求地址. 地址栏为最后响应的那个地址 
       
2)请求转发: 在最终的 Servlet 中, request 对象和中转的那个 request 是同一个对象. 
    请求的重定向: 在最终的 Servlet 中, request 对象和中转的那个 request 不是同一个对象.       
   
3)请求的转发: 只能转发给当前 WEB 应用的的资源
       请求的重定向: 可以重定向到任何资源. 
       
4)请求的转发: / 代表的是当前 WEB 应用的根目录
       请求的重定向: / 代表的是当前 WEB 站点的根目录. (站点:服务+端口)

4、JSP内置对象一共有哪些。

request: HttpServletRequest 的一个对象
response: HttpServletResponse 的一个对象(在 JSP 页面中几乎不会调用 response 的任何方法.)
pageContext: 页面的上下文(当前jsp页面), 是 PageContext 的一个对象.  可以从该对象中获取到其他 8 个隐含对象. 也可以从中获取到当前页面的其他信息.
session: 代表浏览器和服务器的一次会话跟踪(所谓的session失效,就要重新登录), 是 HttpSession 的一个对象
application: 代表当前 WEB 应用. 是 ServletContext 对象.可以获取初始化参数
out: JspWriter 对象. 调用 out.println() 可以直接把字符串打印到浏览器上. 这个是最常用的用法
config: 当前 JSP 对应的 Servlet 的 ServletConfig 对象(开发的时候几乎不使用).ServletConfig
page: 指向当前 JSP 对应的 Servlet 对象的引用, 但为 Object 类型, 只能调用 Object 类的方法(几乎不使用) 
exception: 只有在特殊的时候用,在声明了 page 指令的 isErrorPage="true" 时, 才可以使用.

5、JSP常用指令有哪些?

page指令:定义页面的一些属性,常用属性:
    contentType="text/html;charset=utf-8";    向浏览器端输出数据的编码
    pageEncoding="utf-8";                     JSP编译成java文件时所用的编码
    session="true"                            是否自动创建HttpSession对象. 
    import 属性: 指定当前 JSP 页面对应的 Servlet 需要导入的类. 
include指令:用于通知 JSP 引擎在翻译当前 JSP 页面时将其他文件中的内容合并进当前 JSP 页面转换成的 Servlet 源文件中,这种在源文件级别进行引入的方式称之为静态引入(源码级包含)
taglib指令:引入一个标签库,如jstl的核心标签库和格式化标签库,还有springform的标签库

6、cookie和session的作用、区别、应用范围

cookie数据保存在客户端,session数据保存在服务端。
cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,相当重要的数据,应该使用session保存到服务端。
session会在一定时间内保持在服务器上,但是会占用内存资源,当访问的用户过多,会加重服务器的负载,考虑到减轻服务器的压力,可以将不重要的数据放在cookie中持久的保存。

7、Servlet生命周期简述

Servlet 生命周期的方法: 以下方法都是由 Serlvet 容器负责调用. 
1). 构造器: 只被调用一次. 只有第一次请求 Servlet 时, 创建 Servlet 的实例. 调用构造器. 这说明 Serlvet 的单实例的,存在线程安全问题,不推荐创建全局变量!,如果需要在tomcat启动的时候创建实例,通过load-on-startup配置,值越小越先被创建。
2). init 方法: 只被调用一次. 在创建好实例后立即被调用. 用于初始化当前 Servlet. 
3). service: 被多次调用. 每次请求都会调用 service 方法. 实际用于响应请求的. 
4). destroy: 只被调用一次. 在当前 Servlet 所在的 WEB 应用被卸载前调用. 用于释放当前 Servlet 所占用的资源. 

8、保存session机制的方式

1)常用的保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
    1、session通过SessionID来区分不同的客户, session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,这称之为session cookie
    2、以区别persistent cookies(也就是我们通常所说的cookie),session cookie是存储于浏览器内存中的,并不是写到硬盘上的,通常看不到JSESSIONID,但是当把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,这时地址栏看到
    3、session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本。 
    4、关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。

    示例:
        <% 
            Cookie cookie = new Cookie("JSESSIONID", session.getId());
            cookie.setMaxAge(20);
            response.addCookie(cookie);
        %>
    这样设置之后,下次请求后,每次都会传给服务器,就可以找到对应的session对象了(服务器端的session对象是不会自动失效的)

2)cookie可以被人为的禁用,必须有其它的机制以便在cookie被禁用时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个sessionid。

9、session对象如何销毁?

    1)直接调用 HttpSession 的 invalidate()
    2)HttpSession 超过过期时间. 

        > 返回最大时效: getMaxInactiveInterval() 单位是秒
        > 设置最大时效: setMaxInactiveInterval(int interval)
        > 可以在 web.xml 文件中配置 Session 的最大时效, 单位是分钟. 
        
        <session-config>
            <session-timeout>30</session-timeout>
        </session-config>

    3)卸载当前 WEB 应用. 
    注意强调:
        关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,
        不会使服务器端的session对象失效。

10、过滤器Filter基本工作原理

1)当在 web.xml 中注册了一个 Filter 来对某个 Servlet 程序进行拦截处理时,这个 Filter 就成了 Servlet 容器与该 Servlet 程序的通信线路上的一道关卡,该 Filter 可以对 Servlet 容器发送给 Servlet 程序的请求和 Servlet 程序回送给 Servlet 容器的相应进行拦截,可以决定是否将请求继续传递给 Servlet 程序,以及对请求和相应信息是否进行修改

2)在一个 web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以对一个或一组 Servlet 程序进行拦截。

3)若有多个 Filter 程序对某个 Servlet 程序的访问过程进行拦截,当针对该 Servlet 的访问请求到达时,web 容器将把这多个 Filter 程序组合成一个 Filter 链(过滤器链1)。Filter 链中各个 Filter 的拦截顺序与它们在应用程序的 web.xml 中映射的顺序一致

11、el表达式中默认查找顺序及jsp四大作用域在el表达式中对应关系

    默认查找顺序:
        按照page → request → session → application的作用域顺序依次查找,找到即返回,最终找不到返回null

    作用域在el中的对应关系:
        page        pageScope 例如${pageScope.username}表示在page作用域查找变量username,找不到返回null
        request     requestScope
        session     sessionScope
        application applicationScope

12、<%!…%>和<%=…%>区别

<%= ... %>:这个是jsp的表达式
  本质:在将JSP页面转换成Servlet后,使用out.print()将表达式的值输出。
  注意:
  	如果表达式是调用一个方法,那么这个方法必须要有返回值,而不应是void,方法是不能被调用的。
	在方法的后面不能有分号;例如<%= ... ;%>这是不允许的。
<%! ... %>:这个是jsp的声明
  本质:将声明的变量加入到Servlet类(在任何方法之外),方法就成了Servlet()的全局变量或者普通方法。
  

4、MySQL

1、MySQL和Oracle的区别

    1)MySQL是开源的项目(免费),Oracle数据库产品是闭源同时也是收费的。Mysql是中小型数据库,oracle是大型的
    2)主键 Mysql一般使用自动增长类型,在创建表时只要指定表的主键为auto_increment,插入记录时,不需要再指定该记录的主键值,Mysql将自动增长;Oracle没有自动增长类型,主键一般使用的序列,插入记录时将序列号的下一个值付给该字段即可。
    3)翻页的SQL语句的处理 MYSQL处理翻页的SQL语句比较简单,用LIMIT 开始位置, 记录个数;ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置, 并且只能用ROWNUM<100, 不能用ROWNUM>80,且必须排序。
    4)MySQL对于事务默认是不支持的,只有存储引擎中如:innodb可以支持。 而Oracle对于事务是完全支持,不管是OLTP还是OLAT都是支持的。
    5)日期:MYSQL日期字段分DATE和TIME两种,ORACLE日期字段只有DATE,包含年月日时分秒信息,用当前数据库的系统时间为SYSDATE, 精确到秒。
    6)MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容
    7)MYSQL里的非空判断是ifnull(a,b),而对应oracle的nvl(a,b);
    8)日期比较:MYSQL: 可以用Date类型的日期进行比较时间比较。
    oracle:必须用to_date()函数和to_char()函数配合转换成统一格式的日期字符串,然后进行比较。
    9)MYSQL:可以用YEAR(),MONTH(),NOW()等函数获取年/月/当前日期等。oracle:必须用to_char(sysdate, 'yyyy'),to_char(sysdate, 'MM')获取。
    10)日期转换:MYSQL:DATE_FORMAT(t.col,'%Y-%m-%d')。Oracle:to_char(t.col,'yyyy-mm-dd') 
    11)表的创建  MySQL支持``符号,但是Oracle没有
    12)Oracle:可以使用“||”进行拼接。Mysql:可以使用concat(a,b)
    13) MySQL:insert into table values (),()...支持多条数据同时插入,但是Oracle没有这个写法

2、事务的基本特征

1)原子性(atomicity):一个事务必须视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。
2)一致性(consistency):数据库总数从一个一致性的状态转换到另一个一致性的状态。
3)隔离性(isolation):一个事务所做的修改在最终提交以前,对其他事务是不可见的。
4)持久性(durability):一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。

3、事务的隔离级别

读未提交(Read uncommitted),一个事务可以读取另一个未提交事务的数据,最低级别,任何情况都无法保证。
    出现的问题是:脏读,不可重复读,幻读
        脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据;

读已提交(Read committed),一个事务要等另一个事务提交后才能读取数据,可避免脏读的发生。
    出现的问题是——不可重复读(Nonrepeatable Read):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。
        即:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果因此本事务先后两次读到的数据结果会不一致;

        (1)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)
        (2)它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变

可重复读(Repeatable read),就是在开始读取数据(事务开启)时,不再允许修改操作,可避免脏读、不可重复读的发生。
    (1)这是MySQL的默认事务隔离级别
    (2)它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行
    (3)此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行

串行(Serializable),是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

4、什么是索引,索引的分类,索引的优缺点

索引是对数据库表中一列或多列的值进行排序的一种结构,由数据库管理,不可干预
索引一般分为:普通索引,唯一索引(不能有重复值),主键索引(唯一,非空),组合索引(多列索引)
优点:
    a. 大大加快数据的检索速度
    b. 创建唯一性索引,保证数据库表中每一行数据的唯一性
    c. 可以加速表和表之间的连接

缺点:
    a. 索引需要占物理空间。
    b. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,
    c. 降低了数据的维护速度。
   
什么情况下应不建或少建索引
	1)表记录太少
	2)经常插入、删除、修改的表
	3)数据重复且分布平均的表字段,假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度。
	4)经常和主字段一块查询但主字段索引值比较多的表字段

5、介绍SQL优化可以从哪些方面考虑,SQL语句的优化的关注点有哪些

SQL优化
    1)SQL语句及索引的优化
    2)数据库表结构的优化
    3)系统配置的优化
    4)硬件的优化

SQL语句的优化的关注点
    1)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

   2)应尽量避免在 where 子句中使用 !=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

   3)应尽量避免在 where 子句中对字段进行 null 值 判断,否则将导致引擎放弃使用索引而进行全表扫描 ,一般可以可以给列设置默认值0,确保表中num列没有null值

    4)应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描

    5)应尽量避免全模糊查询,如like '%abc%'导致全表扫描,建议右模糊

    6)应尽量避免在 where 子句中对字段进行表达式操作,即避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描
        select id from t where num/2=100
       应改为:
       select id from t where num=100*2

    7)应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描

    8)在使用索引字段作为条件时,如果该索引是【复合索引】,那么必须使用到该索引中的【第一个字段】作为条件时才能保证系统使用该索引,否则该索引将不会被使用。并且应【尽可能】的让字段顺序与索引顺序相一致。(字段顺序也可以不与索引顺序一致,但是一定要包含【第一个字段】。

    9)提高查询效率,用 exists 代替 in 

    10)并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用

    11)索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

    12)尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

    13)尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    14)任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

    15)当数据量大时,避免使用where 1=1的条件。通常为了方便拼装查询条件,我们会默认使用该条件,数据库引擎会放弃索引进行全表扫描

    16)索引列上计算引起的索引失效及优化措施以及注意事项

        创建索引、优化查询以便达到更好的查询优化效果。但实际上,MySQL有时并不按我们设计的那样执行查询。MySQL是根据统计信息来生成执行计划的,这就涉及索引及索引的刷选率,表数据量,还有一些额外的因素。
        简而言之,当MYSQL认为符合条件的记录在30%以上,它就不会再使用索引,因为mysql认为走索引的代价比不用索引代价大,所以优化器选择了自己认为代价最小的方式。事实也的确如此
        是MYSQL认为记录是30%以上,而不是实际MYSQL去查完再决定的。都查完了,还用什么索引啊?!
        MYSQL会先估算,然后决定是否使用索引。
        
    除此之外:如果表关联字符集不统一,或者关联字段的类型不统一,也可能导致索引失效。

6、select Count (*)和Select Count(1)以及Select Count(column)区别

	一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的,但是对于大数据量的情况下,Select Count (*)比Select Count(1)执行效率慢

    如果有主键的話,那主键作为count的条件时候count(主键)最快

    count(*) 跟 count(1) 的结果一样,都包括对NULL的统计,而count(column) 是不包括NULL的统计

7、什么是sql注入,及主要特点

——官方说法:把SQL命令插入到web表单验证的输入框中,提交到服务器,以达到越过数据验证的目的。

——通俗说法:在浏览器的某个网页中,在身份验证框或者数据查询框中,通过输入sql命令,影响SQL语句字符串的拼接,从而使原本执行不通过的SQL语句可以执行通过。

sql注入的主要危害
    未经授权操作数据库的数据
    跳过验证随意登录系统,恶意纂改网页
    私自添加系统账号或者是数据库使用者账号
    网页挂木马
    
如何解决:
	增加参数值校验,非法参数不给提交
	增加安全过滤器,拦截非法请求
	底层使用PreparedStatement,即mybatis的#{}防止注入

8、什么是锁?

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

基本锁类型:锁包括行级锁(InnoDB)和表级锁(MyISAM)

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

悲观锁和乐观锁的理解及适用场景
    悲观锁(Pessimistic Lock): 
    每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待。

    乐观锁(Optimistic Lock): 
    每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁,但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。

    适用场景:
    悲观锁:比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。

    乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。

    总结:两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

参考1:https://blog.csdn.net/Saintyyu/article/details/91269087?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

参考2:https://blog.csdn.net/tanga842428/article/details/52748531?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

参考3:https://blog.csdn.net/puhaiyang/article/details/72284702?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

参考4:https://zhuanlan.zhihu.com/p/29150809


9、如何通俗地理解三个范式?

第一范式:1NF是对列字段的原子性约束,要求列字段具有原子性,不可再拆分;
第二范式:2NF是对记录的惟一性约束,要求记录(行)有惟一标识,即实体的惟一性;  
第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
范式化设计优缺点:
	优点:
		可以尽量得减少数据冗余,使得更新快,体积小
	缺点:
		对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化
反范式化:
	优点:
		可以减少表得关联,可以更好得进行索引优化	
	缺点:
		数据冗余以及数据异常,数据得修改需要更多的成本	

10、Mysql中varchar和char区别

区别一:定长和变长
	char表示定长、长度固定,varchar表示变长,即长度可变(允许的长度范围内)。
	即char类型是规定多少字长则必须存储多少字长,超过的长度的字段则只能截取出对应的长度进行存储,相对于要求字长长度不够的字段则用空格补齐。
	而varchar类型则是只要在规定字长之内,有多少存多少,无需补齐;超出的部分和char一样,舍去即可。
	
区别二:存储容量不同

	对于char类型来说,最多只能存放的字符个数为255,和编码无关。
	varchar最多能存放65532个字符。VARCHAR的最大有效长度由最大行大小和使用的字符集来确定。

11、MYSQL中DROP、DELETE、TRUNCATE的区别

1)truncate 和 delete只删除数据(记录)不删除表的结构;drop语句将删除表的数据(记录)和表结构依赖的约束(constrain),触发器(trigger),索引(index),保留依赖于该表的存储过程/函数,但是变为invalid状态 .
2)delete 是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate 和 drop 是 DDL 语句,操作完马上生效,不能回滚.
3)truncate之后的自增字段从1开始计数了[即truncate是摧毁原来的表重新创建一张结构相同的表(有原表的结构)],delete的仍保留原来的最数数值[即如果添加数据从最值+1开始],drop将表的结构也删除了(原表数据和结构都没有了)。
truncat会释放表所占的空间,而delete则不会.

总结:
    执行速度:一般,drop> truncate > delete。
    drop和truncate时虽然在备份情况下,可以恢复,但为了减少麻烦,要慎重。
    如果想删除部分数据用delete,注意带上where子句;
    如果想删除表,用drop;想保留表而将所有数据删除,如果和事务无关,用truncate即可;
    如果和事务有关,或者想触发trigger,还是用delete
    如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据

12、MySQL的存储引擎InnoDB和MyISAM区别

区别:
1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交
2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
3. InnoDB是数据文件是和索引绑在一起的,通过主键索引效率很高。而MyISAM是数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
5. Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;
    如何选择:
    1. 是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;
    2. 如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB。
    3. 系统奔溃后,MyISAM恢复起来更困难,能否接受;
    4. MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM)。

5、Mybatis

1、Mybaits的优点:

1) 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
2) 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
3) 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
4) 能够与Spring很好的集成;
5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护

2、MyBatis与Hibernate有哪些不同?

1) Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。
2) Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。
3) hibernate开发可以节省很多代码,提高效率,但是对于复杂条件查询支持不好。

3、#{}和${}的区别是什么?

1) #{}是预编译处理,${}是字符串替换。
2) Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
3) Mybatis在处理${}时,就是把${}替换成变量的值。
4) 使用#{}可以有效的防止SQL注入,提高系统安全性。

4、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

1) 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
2) 通过<resultMap>来映射字段名和实体类属性名的一一对应的关系。

5、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用<resultMap>标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

6、resultMap和resultType的区别,以及resultMap里的元素(顺序)

1)resultType:对应的是java对象中的属性,大小写不敏感
2)resultMap: 指的是定义好了的id的,是定义好的resultType的引用
    resultMap:
        属性id:唯一标识(resultMap的名称)
        属性type:Java实体类

        标签id:一般对应数据库中该行的主键id,设置此项可提高MyBatis性能
        标签result: 映射到JavaBean的某个“简单类型”属性  
        标签association:映射到JavaBean的某个“复杂类型”属性,比如JavaBean类
        标签collection:映射到JavaBean的某个“复杂类型”属性,比如集合

7、通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

1)Dao接口即Mapper接口,接口的全类名,就是映射文件中的namespace的值;
2)接口的方法名,就是映射文件中Mapper的id值;接口方法内的参数,就是传递给sql的参数。
3)Mapper接口是没有实现类的,当调用接口方法时,接口全类名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MapperStatement对象。
4)Mapper 接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回。

5)Mapper接口里的方法,是不能重载的,因为是使用 全类名+方法名 的保存和寻找策略。

8、Mybatis的基本工作流程

1).读取配置文件,配置文件包含数据库连接信息和Mapper映射文件或者Mapper包路径。
2).有了这些信息就能创建SqlSessionFactory,SqlSessionFactory的生命周期是程序级,程序运行的时候建立起来,程序结束的时候消亡
3).SqlSessionFactory建立SqlSession,目的执行sql语句,SqlSession是过程级,一个方法中建立,方法结束应该关闭
4).当用户使用mapper.xml文件中配置的的方法时,mybatis首先会解析sql动态标签为对应数据库sql语句的形式,并将其封装进MapperStatement对象,然后通过executor将sql注入数据库执行,并返回结果。
5).将返回的结果通过映射,包装成java对象。

9、如何获取自动生成的(主)键值?

1)insert方法总是返回一个int值 ,这个值代表的是插入的行数。
2)如果采用自增长策略,自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。
    insert标签增加属性:usegeneratedkeys=”true” keyproperty=”id”

10、在mapper配置文件中如何传递多个参数?

1)接口定义多个参数,对应的mapper映射文件xml中,Mybatis默认提供了,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,依次类推。或者直接使用#{param1},#{param2},依次类推
2)用 @Param 注解,分别给多个参数起别名,然后在映射文件中直接获取别名参数,也仍然可以用#{param1},#{param2},依次类推
3)多个参数封装成map,然后在映射文件中直接获取key值对应的参数值
4)多个参数直接封装成实体,在xml映射文件中,直接通过实体的属性获取参数值(单个实体,不用起别名,如果起别名,获取参数就必须使用别名.属性名)

11、Mybatis动态sql有什么用?执行原理?有哪些动态sql?

1)Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接sql的功能。
2)Mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。

12、Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?

1)<resultMap>、<sql>、<include>、加上动态sql的9个标签,其中<sql>为sql片段标签,通过<include>标签引入sql片段。

13、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;
    原因就是namespace+id是作为Map<String, MapperStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。
    有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

14、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。其实说白了,Mybatis需要自己写业务sql语句,灵活性更好,复杂语句更好实现。

15、MyBatis实现一对一有几种方式?具体怎么操作的?

1)联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置association节点配置一对一的类就可以完成;
2)嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。

16、MyBatis实现一对多有几种方式,怎么操作的?

1)联合查询是几个表联合查询,只查询一次,通过在resultMap里面的collection节点配置一对多的类就可以完成;
2)嵌套查询是先查一个表,根据这个表里面的 结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的查询通过select节点配置。

17、Mybatis是否支持延迟加载?支持需要增加什么配置?

1)Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。
2)在Mybatis配置文件中,可以配置是否启用延迟加载,默认为false
    <setting name="lazyLoadingEnabled" value="true"/>

3)当然了,还有一个重要配置就是是否按需加载
    <setting name="aggressiveLazyLoading" value="false"/>
默认3.4.1版本及之前版本,默认为true,关闭改为false,实体中定义的属性是全部加载(只要调用其中任何方法,所有的延迟加载属性都会调用),还是按需加载(需要使用时候才会执行调用对应的查询)

18、接口与SQL绑定有几种实现方式,分别是怎么实现的?

1)注解绑定:就是在接口的方法上面 @Select @Update等注解里面包含Sql语句来绑定,这种只适合简单的sql语句

2)另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.

19、Mybatis的缓存机制

mybatis提供查询缓存,用于减轻数据库压力,提高数据库性能
    mybatis提供一级缓存和二级缓存
    一级缓存:sqlsession级别的缓存
        在操作数据库时,需要构造sqlsession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据
        不同的sqlsession之间的缓存区域是互相不影响的。

    二级缓存:mapper级别的缓存
        多个sqlsession去操作同一个mapper的sql语句,多个sqlsession可以共用二级缓存,所得到的数据会存在二级缓存区域,
        二级缓存是跨sqlsession的

    二级缓存相比一级缓存的范围更大(按namespace来划分),多个sqlsession可以共享一个二级缓存

参考:https://www.cnblogs.com/jiezai/p/11319124.html

20、Mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?

1)虽然Mybatis解析Xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以定义在任何地方,Mybatis都可以正确识别。

2)原理是,Mybatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。

6、Spring

1、什么是Spring框架,Spring 的优点?

Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。
Spring框架就是Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。

主要由以下几个模块组成:
    Spring Core:核心类库,Spring其他所有的功能都依赖于该类库,提供IOC服务;
    Spring Aspects:该模块为与AspectJ的集成提供支持。
    Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
    Spring AOP:AOP服务;
    Spring JDBC:对JDBC的抽象,简化了数据访问异常的处理;
    Spring ORM:对现有的ORM框架的支持,如支持Hibernate等ORM工具;
    Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;
    Spring MVC:提供面向Web应用的Model-View-Controller实现。
    Spring Test:提供了对JUnit和TestNG测试的支持

优点:
(1)spring属于低侵入式设计;减少依赖;

(2)spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;

(3)Spring提供了AOP技术,将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。

(4)spring对于主流的应用框架提供了集成支持,比如Mybatis。

2、Spring的IOC理解:

(1)IOC就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。DI依赖注入,和控制反转是同一个概念的不同角度的描述,即应用程序在运行时依赖IOC容器来动态注入对象需要的外部资源。

(2)最直观的表达就是,IOC让对象的创建不用去new了,可以由spring创建并维护,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。

(3)Spring的IOC有三种注入方式 :构造器注入、setter方法注入、根据注解注入。

IOC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。

3、解释Spring支持的几种bean的作用域。

Spring容器中的bean可以分为5个范围:
(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。

(2)prototype:为每一个bean请求提供一个实例。

(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

(5)global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。

4、将一个类声明为Spring的bean的注解有哪些?

我们一般使用@Autowired注解去自动装配bean。而想要把一个类标识为可以用@Autowired注解自动装配的bean,可以采用以下的注解实现:
1.@Component注解。普通的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@Component注解标注。
2.@Repository注解。对应持久层,即Dao层,主要用于数据库相关操作。
3.@Service注解。对应服务层,即Service层,主要涉及一些复杂的逻辑,需要用到Dao层(注入)。
4.@Controller注解。对应Spring MVC的控制层,即Controller层,主要用于接受用户请求并调用Service层的方法返回数据给前端页面。

5、Spring的自动装配:

在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。
在Spring框架xml配置中共有5种自动装配:
(1)no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
(2)byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
(3)byType:通过参数的数据类型进行自动装配,如果发现多个会报错。
(4)constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
(5)autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。 

基于注解的方式:
    使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,<context:annotation-config />。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:
    如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;    
    如果查询的结果不止一个,那么@Autowired会根据名称来查找;
    如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。
    
 	@Autowired可用于:构造函数、成员变量、Setter方法
 	
 	注:@Autowired和@Resource之间的区别
 	(1) @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
    (2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。 	

6、Spring事务的种类:

spring支持编程式事务管理和声明式事务管理两种方式:
1)编程式事务管理使用TransactionTemplate。
2)声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。

声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就可以获得完全的事务支持。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。
声明式事务又分为两种:基于XML的声明式事务、基于注解的声明式事务

7、Spring的事务传播行为:

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。
	1) PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
	2) PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
	3) PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
    4) PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
    5) PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    6) PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
   	7) PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

8、Spring通知有哪些类型?

(1)前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
(2)返回通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
(3)抛出异常通知(After throwing advice):在方法抛出异常退出时执行的通知。 
(4)后置通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
(5)环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。 环绕通知是最常用的一种通知类型。大部分基于拦截的AOP框架,例如Nanning和JBoss4,都只提供环绕通知
参考:https://blog.csdn.net/qq_32331073/article/details/80596084 

7、SpringMvc

1、什么是SpringMvc框架

Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

Spring MVC是当前最优秀的MVC框架,相比于Struts2,Spring MVC使用更加简单和方便,开发效率更高,并且Spring MVC运行速度更快。

MVC是一种设计模式,Spring MVC是一款很优秀的MVC框架。Spring MVC可以帮助我们进行更简洁的Web层的开发,并且它天生与Spring框架集成。Spring MVC下我们一般把后端项目分为Service层(处理业务)、Dao层(数据库操作)、Entity层(实体类)、Controller层(控制层,返回数据给前台页面)。

2、SpringMVC的流程?

1)用户发送请求至前端控制器DispatcherServlet;
2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
6)Handler执行完成返回ModelAndView;
7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
9)ViewResolver解析后返回具体View;
10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
11)DispatcherServlet响应用户.

3、Spring MVC的主要组件?

前端控制器:其作用是接收用户请求,然后给用户反馈结果。它的作用相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。
处理器映射器:其作用是根据请求的URL路径,通过注解或者XML配置,寻找匹配的处理器信息。
处理器适配器:其作用是根据映射器处理器找到的处理器信息,按照特定规则执行相关的处理器(Handler)。
处理器:其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至ModelAndView对象中。
视图解析器:其作用是进行解析操作,通过ModelAndView对象中的View信息将逻辑视图名解析成真正的视图View(如通过一个JSP路径返回一个真正的JSP页面)。
视图:View是一个接口,实现类支持不同的View类型(JSP、FreeMarker、Excel等)。

4、SpringMVC和struts2的区别有哪些?

1)Springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。
2)Springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

5、SpringMVC怎么样设定重定向和转发的?

1)转发:在返回值前面加"forward:",譬如"forward:user.jsp",底层默认也是使用的转发
2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"

6、SpringMVC常用的注解有哪些?

1)@Controller注解:用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller对象。处理器适配器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。

2)@RequestMapping注解:
    用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。返回值会通过视图解析器解析为实际的物理视图,对于 InternalResourceViewResolver 视图解析器,通过 prefix + returnValue + suffix 这样的方式得到实际的物理视图,然后做转发操作。
    @RequsestMapping常见属性
        value:指定请求的实际地址。
        method:指定请求的method类型, GET、POST、PUT、DELETE等。
        params:指定request中必须包含某些参数值是,才让该方法处理。
        headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。

3)@ResponseBody注解: 
    将conreoller方法返回对象转化为json对象响应给客户。这种方式用于Ajax异步请求,返回的不是一个页面而是JSON格式的数据。前提要依赖Jackson或者Gson的jar包

4)@PathVariable注解
    @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中
    URL 中的 {xxx} 占位符可以通过 @PathVariable("xxx") 绑定到操作方法的入参中,REST风格常用

5)@RequestParam注解
    在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法
        有如下三个属性
            value:参数名。
            required:是否必需,默认为true,表示请求参数中必须包含该参数,如果不包含抛出异常。
            defaultValue:默认参数值,如果设置了该值自动将required设置为false,如果参数中没有包含该参数则使用默认值。

6)@RequestHeader 注解
    可将请求头中的属性值绑定到处理方法的入参中,了解

Spring的其它注解也都支持,需要的话,在这里也可以简单说一下常用的几种

7、SpringMvc解决post请求乱码问题:

在web.xml中配置一个CharacterEncodingFilter过滤器
<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
</filter>
<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>

8、Springmvc 中对于文件的上传有哪些需要注意

在页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析。
在springmvc.xml中配置multipart类型解析器。
方法中使用:MultipartFile attach (单个文件上传) 或者 MultipartFile[] attachs (多个文件上传)

9、Springmvc 中拦截器如何使用

定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。
    preHandle :进入 Handler方法之前执行,用于身份认证、身份授权,比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
    postHandle:进入Handler方法之后,返回modelAndView之前执行,应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
    afterCompletion:执行Handler完成执行此方法,应用场景:统一异常处理,统一日志处理
拦截器配置:
针对HandlerMapping配置(不推荐):
    springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该 拦截器。(一般不推荐使用)
    类似全局的拦截器:springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中

可以参照:https://blog.csdn.net/weixin_44176169/article/details/104902079

10、SpringMVC用什么对象从后台向前台传递数据的

1)使用MapModelModelMap的方式,这种方式存储的数据是在request域中
        public String getUser(Map<String,Object> map,Model model,ModelMap modelMap){
            //1.放在map里  
            map.put("name", "xq");
            //2.放在model里,一般是使用这个
            model.addAttribute("habbit", "Play");
            //3.放在modelMap中 
            modelMap.addAttribute("city", "gd");
            modelMap.put("gender", "male");
            return "userDetail";
        }

2)使用原生的servlet的api
        request的方式或者session的方式
            public String getUser(HttpServletRequest request,HttpSession session){
                //放在request里  
                request.setAttribute("user", userService.getUser());
                session.setAttribute("user", userService.getUser());
                return "userDetail";
            }

3)使用ModelAndView
    public ModelAndView getUser() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("user", userService.getUser());  
        mav.setViewName("userDetail");  
        return modelAndView;  
    }  
    原文链接:https://blog.csdn.net/weixin_44176169/java/article/details/104852285

8、其它整理题

1、ThreadPoolExecutor五大核心参数

	1、corePoolSize:核心线程数
        * 核心线程会一直存活,及时没有任务需要执行
        * 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
        * 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
    2、queueCapacity:任务队列容量(阻塞队列)
        * 当核心线程数达到最大时,新任务会放在队列中排队等待执行
    3、maxPoolSize:最大线程数
        * 当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
        * 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
    4、 keepAliveTime:线程空闲时间
        * 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
        * 如果allowCoreThreadTimeout=true,则会直到线程数量=0
    5、allowCoreThreadTimeout:允许核心线程超时
    6、rejectedExecutionHandler:任务拒绝处理器
        * 两种情况会拒绝处理任务:
            - 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
            - 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
        * 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
        * ThreadPoolExecutor类有几个内部实现类来处理这类情况:
            - AbortPolicy 丢弃任务,抛运行时异常
            - CallerRunsPolicy 执行任务
            - DiscardPolicy 忽视,什么都不会发生
            - DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
        * 实现RejectedExecutionHandler接口,可自定义处理器

9、智力题

1、有两根不均匀分布的香,香烧完的时间是一个小时,你能用什么方法来确定一段15分钟的时间?

答:把两根香同时点起来,第一支香两头点着,另一支香只烧一头,等第一支香烧完的同时(这是烧完总长度的3/4),把第二支香另一头点燃,另一头从燃起到熄灭的时间就是15分。

2、一个经理有三个女儿,三个女儿的年龄加起来等于13,三个女儿的年龄乘起来等于经理自己的年龄,有一个下属已知道经理的年龄,但仍不能确定经理三个女儿的年龄,这时经理说只有一个女儿的头发是黑的,然后这个下属就知道了经理三个女儿的年龄。请问三个女儿的年龄分别是多少?为什么?

答:三女的年龄应该是2、2、9。因为只有一个孩子黑头发,即只有她长大了,其他两个还是幼年时期即小于3岁,头发为淡色。再结合经理的年龄应该至少大于25。

3、有三个人去住旅馆,住三间房,每一间房$10元,于是他们一共付给老板$30, 第二天,老板觉得三间房只需要$25元就够了于是叫小弟退回$5给三位客人, 谁知小弟贪心,只退回每人$1,自己偷偷拿了$2,这样一来便等于那三位客人每人各花了九元, 于是三个人一共花了$27,再加上小弟独吞了不$2,总共是$29。可是当初他们三个人一共付出$30那么还有$1呢?

答:一共付出的30元包括27元(25元给老板+小弟贪污2元)和每人退回1元(共3元),拿27和2元相加纯属混淆视听。

4、一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其它人帽子的颜色,却看不到自己的。主持人先让大家看看别人头上戴的是什幺帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍,关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子?

答:有三个人戴黑帽。假设有N个人戴黑,当N=1时,戴黑人看见别人都为白则能肯定自己为黑。于是第一次关灯就应该有声。可以断定N> 1。对于每个戴黑的人来说,他能看见N-1顶黑帽,并由此假定自己为白。但等待N-1次还没有人打自己以后,每个戴黑人都能知道自己也是黑的了。所以第N次关灯就有N个人打自己。

5、两个圆环,半径分别是1和2,小圆在大圆内部绕大圆圆周一周,问小圆自身转了几周?如果在大圆的外部,小圆自身转几周呢?

答:无论内外,小圆转两圈。小圆、大圆经历的距离相等。

6、1元钱一瓶汽水,喝完后两个空瓶换一瓶汽水,问:你有20元钱,最多可以喝到几瓶汽水?

答:39瓶,从第2瓶开始,相当于1元买2瓶。

7、在房里有三盏灯,房外有三个开关,在房外看不见房内的情况,你只能进门一次,你用什 么方法来区分那个开关控制那一盏灯。

答:如果“在房外看不见”可理解为:“看不见哪个灯亮,而看得见房里亮不亮”的话:先看一个开关A,进门,确定一盏,然后斜下不亮的一盏,出门,关掉A,开B,看房里是否还亮。

8、现有米9公斤以及50克和200克砝码各一个。问怎样在天平上只称量三次而称出2公斤米?

答:
  第一次
  一边9公斤砝码,一边250克砝码,称出8公斤750克

  第二次
  一边250克砝码,另一边没有砝码,用第一次称出的再称,两边分别是4公斤250克和4公斤500克

  第三此
  一边250克砝码,另一边没有砝码,用第二次称出4公斤250克的再称,两边分别是2公斤和2公斤250克,得到了2公斤米

9、如果你有无穷多的水,一个3kg的和一个5kg的提桶,你如何准确称出

4kg的水?

答:
1,现装满5的,然后把5倒入3

2,把3的倒掉,再把5中剩的2倒入3

3,装满5,倒进3中少的一就剩4了

5-[3-(5-3)] 

10、U2合唱团在17分钟内得赶到演唱会场,途中必需跨过一座桥,四个人从桥

的同一端出发,你得帮助他们到达另一端,天色很暗,而他们只有一只手电筒。一

次同时最多可以有两人一起过桥,而过桥的时候必须持有手电筒,所以就得有人把

手电筒带来带去,来回桥两端。手电筒是不能用丢的方式来传递的。四个人的步行

速度各不同,若两人同行则以较慢者的速度为准。Bono需花1分钟过桥,Edge需花 2分钟过桥,Adam需花5分钟过桥,Larry需花10分钟过桥。他们要如何在17分钟内 过桥呢?

答:可以17分钟赶到

A 1分钟 B 2分钟 C5分钟 D10分钟

A B 先过 A回用时3分钟

C D 再过 B回用时12分钟

A B 再过用时2分钟

正好17分钟
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十碗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值