3. 重载:重载发生在同一个类中,在该类中如果存在多个同名方
4. 重写:重写发生在子类继承父类的关系中,父类中的方法被子
2、处理器映射器HandlerMapping(不需要程序员开发)
5、视图解析器 ViewResolver(不需要程序员开发)
基础篇
一、Java面向对象编程有四个特征?
答:面向对象编程有四个特征:抽象,封装,继承,多态。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者 对象操作,对不可信的进行信息隐藏。
继承是指使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。
继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组 合”(Composition)来实现。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情 况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。
多态有四种体现形式:(JAVA多态的具体体现)
3. 重载:重载发生在同一个类中,在该类中如果存在多个同名方
法,但是方法的参数类型和个数不一样,那么说明该方法被重
载了。
4. 重写:重写发生在子类继承父类的关系中,父类中的方法被子
类继承,方法名,返回值类型,参数完全一样,但是方法体不
一样,那么说明父类中的该方法被子类重写了。
二、Get和Post的区别?
答:1.get是从服务器上获取数据,post是向服务器传送数据,
2.get传送的数据量较小,不能大于2KB;post传送的数据量较大,一般被默认为不受限制。
3.get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
4.在进行文件上传时只能使用post而不能是get。
三、StringBuffer StringBuilder String 三者的区别?
答:String 字符串常量 不可变 使用字符串拼接时是不同的2个空间
StringBuffer 字符串变量 可变 线程安全 字符串拼接直接在字符串后追加
StringBuilder 字符串变量 可变 非线程安全 字符串拼接直接在字符串后追加
1.StringBuilder执行效率高于StringBuffer高于String.
2.String是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象, StringBuffer和StringBuilder都是可变的,当进行字符串拼接时采用append方 法,在原来的基础上进行追加,所以性能比String要高,又因为StringBuffer 是 线程安全的而StringBuilder是线程非安全的,所以StringBuilder的效率高于 StringBuffer.
3.对于大数据量的字符串的拼接,采用StringBuffer,StringBuilder.
四、Hashtable与HashMap的区别?
答:HashMap不是线程安全的,HashTable是线程安全。
HashMap允许空(null)的键和值(key),HashTable则不允许。
HashMap性能优于Hashtable。
1.Map是一个以键值对存储的接口。Map下有两个具体的实现,分别是HashMap和HashTable.
2.HashMap是线程非安全的,HashTable是线程安全的,所以HashMap的效率高于HashTable.
3.HashMap允许键或值为空,而HashTable不允许键或值为空.
五、HashMap的底层实现?
答:1、Hash: Hash中文翻译为散列,又成为“哈希”,是一类函数的统称,其特点是定义域无限,值域有限。把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
2、在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
3、首先有一个每个元素都是链表(可能表述不准确)的数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,同一各链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树,这样大大提高了查找的效率。
六、CGLIB和JDK的区别?
答:1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
2、、如果目标对象实现了接口,可以强制使用CGLIB实现AOP(<aop:aspectj-autoproxy proxy-target-class="true"/>)。
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。
七、Forword(请求转发)与Redirect(重定向) ?
答:1、从数据共享上
Forword是一个请求的延续,可以共享request的数据
Redirect开启一个新的请求,不可以共享request的数据
Forword转发地址栏不发生变化
Redirect转发地址栏发生变化
八、Json(JavaScript Object Notation)特点?
答:Json分为两种格式: json对象(就是在{}中存储键值对,键和值之间用冒号分隔, 键 值 对之间用逗号分隔),json数组(就是[]中存储多个json对象,json对象之间用逗号分隔)(两者间可以进行相互嵌套)
数据传输的载体之一
区别:
xml的传输数据量比json的要大,流行的是基于json的数据传输。
共同点:
Xml和json都是传输数据的载体,并且具有跨平台跨语言的特性。
九、线程和进程的区别?
答:1.线程(Thread)与进程(Process)
进程定义的是应用程序与应用程序之间的边界,通常来说一个进程就代表一个与之对应的应用程序。不同的进程之间不能共享代码和数据空间,而同一进程的不同线程可以共享代码和数据空间。
2.一个进程可以包括若干个线程,同时创建多个线程来完成某项任务,便是多线程。
3.实现线程的两种方式:继承Thread类,实现Runable接口。
十、JVM的运行机制及内存结构?
答: JVM是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机主要由字节码指令集、寄存器、栈、垃圾回收堆和存储方法域等构成。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
Java虚拟机的内存结构分为堆(heap)和栈(stack),堆里面存放是对象实例也就是new出来的对象。栈里面存放的是基本数据类型以及引用数据类型的地址;对于所谓的常量是存储在方法区的常量池里面。
答:内存泄露 (memory leak),是指应用程序在申请内存后,无法释放已经申请的内存空间.一次内存泄露危害可以忽略,但如果任其发展最终会导致内存溢出(out of memory).
如读取文件后流要进行及时的关闭以及对数据库连接的释放。
内存溢出(out of memory)是指应用程序在申请内存时,没有足够的内存空间供其使用。如我们在项目中对于大批量数据的导入,采用分段批量提交的方式。
答:Session是存储在服务器端,Cookie是存储在客户端的,所以安全来讲session的安全性要比cookie高,然后我们获取session里的信息是通过存放在会话cookie里的sessionid获取的。又由于session是存放在服务器的内存中,所以session里的东西不断增加会造成服务器的负担,所以会把很重要的信息存储在session中,而把一些次要东西存储在客户端的cookie里,然后cookie确切的说分为两大类分为会话cookie和持久化cookie,会话cookie确切的说是存放在客户端浏览器的内存中,所以说他的生命周期和浏览器是一致的,浏览器关了会话cookie也就消失了,然而持久化cookie是存放在客户端硬盘中,而持久化cookie的生命周期就是我们在设置cookie时候设置的那个保存时间,然后我们考虑一问题当浏览器关闭时session会不会丢失,从上面叙述分析session的信息是通过sessionid获取的,而sessionid是存放在会话cookie当中的,当浏览器关闭的时候会话cookie消失所以我们的sessionid也就消失了,但是session的信息还存在服务器端,这时我们只是查不到所谓的session但它并不是不存在。那么,session在什么情况下丢失,就是在服务器关闭的时候,或者是sessio过期,再或者调用了invalidate()的或者是我们想要session中的某一条数据消失调用session.removeAttribute()方法,然后session在什么时候被创建呢,确切的说是通过调用session.getsession来创建,这就是session与cookie的区别。
答:stream结尾都是字节流,reader和writer结尾都是字符流;
两者的区别就是读写的时候一个是按字节读写,一个是按字符。实际使用通常差不多。
在读写文件需要对内容按行处理,比如比较特定字符,处理某一行数据的时候一般会选择字
符流。只是读写文件和文件内容无关的,一般选择字节流。
答:Java反射机制是在运行状态中对于任意一个类(Class文件)都能够知道这个类的属性和方法,对于任意一个对象都能调用它的方法和属性; 这种动态获取的信息以及调用对象的方法的功能称为java语言的反射机制
十五、什么是单例模式?
答:单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
十六、JDK1.8的新特性?
答:JDK1.8新增了的新特性有Lambda表达式、方法引用、默认方法、新工具、Stream API、Date Time API、Optional类、Nashorn,JavaScript引擎。
Lambda表达式:Lambda允许函数作为参数传递到方法中。
方法引用:可以直接引用已有Java类或对象的方法或构造器。
Date Time API:加强对日期与时间的处理。
Optional类:用来解决空指针异常。
JavaScript引擎:允许程序在JVM上运行特定的javascript应用。
默认方法:可以理解为一个在接口里面有了一个实现的方法。
新工具:加入像是Nashorn引擎 jjs、 类依赖分析器jdeps的新的编译工具。
Stream API:可以把函数式编程风格引入到Java中。
十七、Git、Maven、SVN区别?
答:1、git和svn最大的几个区别要点,svn必须要有服务端,网络能连上服务端才能提交
和更新,git不需要,每一台装了git的电脑都是服务端,各台电脑之间可以相互同
步和推送,而提交不需要网络就可以提交到本地的git库里。
2、SVN 是集中式版本控制工具 (版本记录都在中央服务器 (一旦中央服务器数据出错,
就可能导致所有版本记录都丢失)); Git 是分布式版本控制工具 (本地有完整的版本记录, 在本地就可以进行版本控制);SVN 分支是复制的方式, Git 分支是指针指向不同,SVN 版本控制是记录增量修改, Git 版本控制是完整的文件副本
3、Maven 是一个项目管理和构建自动化工具。但是对于我们程序员来说,我们最关心的是它的项目构建功能;Maven 使用惯例优于配置的原则,一个 maven 项目在默认情况下会产生 JAR 文件,另外 ,编译后的 classes 会放在 ${basedir}/target/classes 下面, JAR 文件会放在 ${basedir}/target 下面。
十八、集合有哪些?
答:常用的三大类集合:Set、List、Map。
HsehSet,TreeSet,LinkedHashSet,ArrayList,LinkedList,Vector,HashMap,LinkedHashMap,TreeMap,HashTable,ConcurrentHashMap;
十九、抽象类和接口有什么区别?
答:抽象类要被子类继承,接口要被类实现。
接口只能做方法声明,抽象类中可以作方法声明,也可以做方法实现。
接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
接口是设计的结果,抽象类是重构的结果。
抽象类和接口都是用来抽象具体对象的,但是接口的抽象级别最高。
抽象类可以有具体的方法和属性,接口只能有抽象方法和不可变常量。
抽象类主要用来抽象类别,接口主要用来抽象功能。
二十、Java中同步和异步的区别?
答:Java中交互方式分为同步和异步两种:
相同点:都属于交互方式,都是发送请求。
不同点:
同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;
异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。
区别:一个需要等待,一个不需要等待,在部分情况下,我们的项目开发中都会优先选择不需要等待的异步交互方式。
二十一、实现Ajax的基本步骤?
答:要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:
1.创建XMLHttpRequest对象,即创建一个异步调用对象.
2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
3.设置响应HTTP请求状态变化的函数.
4.发送HTTP请求.
5.获取异步调用返回的数据.
6.使用JavaScript和DOM实现局部刷新
二十二、java的基本数据类型 (默写)
答:数据类型 大小
byte(字节) 1(8位)
shot(短整型) 2(16位)
int(整型) 4(32位)
long(长整型) 8(32位)
float(浮点型) 4(32位)
double(双精度) 8(64位)
char(字符型) 2(16位)
boolean(布尔型) 1位
二十三、冒泡排序 (默写)
答:public class Sort {
public static void sort() {
Scanner input = new Scanner(System.in);
int sort[] = new int[10];
int temp;
System.out.println("请输入10个排序的数据:");
for (int i = 0; i < sort.length; i++) {
sort[i] = input.nextInt();
}
for (int i = 0; i < sort.length - 1; i++) {
for (int j = 0; j < sort.length - i - 1; j++) {
if (sort[j] < sort[j + 1]) {
temp = sort[j];
sort[j] = sort[j + 1];
sort[j + 1] = temp;
}
}
}
System.out.println("排列后的顺序为:");
for(int i=0;i<sort.length;i++){
System.out.print(sort[i]+" ");
}
}
public static void main(String[] args) {
sort();
}
}
二十四、时间类型转换 (默写)
答:public class DateFormat {
public static void fun() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String newDate;
try {
newDate = sdf.format(new SimpleDateFormat("yyyyMMdd")
.parse("20121115"));
System.out.println(newDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
fun();
}
}
二十五、单例 (默写)
答:单例就是该类只能返回一个实例。
单例所具备的特点:
1.私有化的构造函数
2.私有的静态的全局变量
3.公有的静态的方法
单例分为懒汉式、饿汉式和双层锁式
饿汉式:
public class Singleton1 {
private Singleton1() {};
private static Singleton1 single = new Singleton1();
public static Singleton1 getInstance() {
return single;
}
}
懒汉式:
public class Singleton2 {
private Singleton2() {}
private static Singleton2 single=null;
public tatic Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
线程安全:
public class Singleton3 {
private Singleton3() {}
private static Singleton3 single ;
public static Singleton3 getInstance() {
if(null == single){
synchronized(Singleton3.class){
if(null == single){
single = new Singleton3();
}
}
}
return single;
}
一、简单介绍Spring框架?
答:Spring框架是一个开源的容器性质的轻量级框架。主要有三大特点:容器、IOC(控制反转)、AOP(面向切面编程)。
二、使用Spring框架的好处是什么?
答:轻量:Spring 是轻量的,基本的版本大约2MB。
控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
容器:Spring 包含并管理应用中对象的生命周期和配置。
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
三、说说AOP和IOC的概念以及在Spring中是如何应用的?
答:AOP:面向切面的编程
IOC: 控制反转。
IOC就是依赖注入,即用接口编程,在程序中不出现new关键字,而是用接口来命名引用,然后通过某种方式把接口的某个实现类的实例注入到引用里,从而实现接口与具体实现类的松耦合。
由容器控制程序之间的关系(通过XML配置),而非传统实现中的由程序代码直接操控,(在一个Class对象中引用另一个Class对象时,我们通常都是直接通过new contructor)。控制权由应用代码中转到了外部容器,控制权的转移,是所谓的反转。
AOP方式很类似filter,就是在程序正常的业务流中间像切面一样插入很多其他需要执行的代码,比如登录时候,在进入登录页面前写入日志,很常用的,尤其是跟数据库有关的,或者跟支付有关的程序肯定会在每一步前面插入日志。
面向方面的编程,即 AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是切面,它将那些影响多个类的行为封装到可重用的模块中。
AOP通知有:前置通知、后置通知、异常通知、环绕通知。
四、 什么是spring的依赖注入(DI机制)?
答:DI:依赖注入,是IOC的一个方面,需要有IOC环境,这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。在Spring创建Bean对象时,动态的将依赖对象注入到Bean对象中去。依赖注入最大的好处就是解耦合。
五、 Spring框架中属性注入有哪几种方式:
答:Spring中的输入注入方式包括set方法注入、构造函数注入、p名称空间注入、spel注入,除此之外,还包括复杂方式注入,如数组、List、Map、Properties等属性的注入。
六、 简述一下spring bean的生命周期?
答:bean的生命周期包括bean的定义、bean的初始化、bean的调用和bean的销毁。
在配置文件里面通过<bean></bean>来完成bean的定义,
通过配置init-method属性来完成bean的初始化,
通过得到bean的实例对象来完成bean的调用,
通过配置destory-method属性来完成bean的销毁。
七、Spring如何处理线程并发问题?
答:Spring使用ThreadLocal解决线程安全问题。
我们知道在一般情况下,只有有状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
(1)在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
(2)而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
(3)概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
八、如何使用Spring中的注解?
答:Spring容器中注册一个对象,需要在Spring的主配置文件中用Bean标签来描述该对象,在实际开发中,一个项目中会有特别多的对象,如果都用Bean标签来配置,未免太过麻烦了。基于此,Spring容器为我们提供了注解的概念,用注解来代替配置。
在使用注解之前,要先在spring的主配置文件中通过Context:component-scan标签来开启使用注解的开关。
九、 用注解将对象注册到Spring容器当中有几种注解方式?它们有什么区别吗?
答:4种。分别是:@Component()、@Service()、@Controller()、@Respository()。
Spring框架最早出现的只有@Component()注解,但如果所有的对象都使用同一个注解,很难区分对象究竟属于哪一层架构。基于此,Spring又推出了@Service()、@Controller()、@Respository()三种注解,用于区分对象属于哪一层架构。但4种注解方式从功能上来说没有任何区别。
十、 如何用注解的方式来完成属性注入?
答:按类型分可以分为值类型注入和引用类型注入。
1、值类型注入可以通过@Value()注解来完成,该注解既可以声明在属性上,也可以声明在方法上,建议声明在方法上,但是更多的人会声明在属性上,因为更方便。
2、引用类型注入可以通过三种注解方式来完成,分别为:@Autowired、@Autowired和@Qualifier()二者结合、@Resource()。建议使用@Resource(),但是一般我都会用@Autowired。
十一、 简单介绍一下Spring中的事务管理。
答:事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。这样可以防止出现脏数据,防止数据库数据出现问题。
现实世界中最常见的事务例子可能就是转账了。必须了解银行转账的过程。
十二、 事务的4个特性?
答:事务有4个特性:ACID。
原子性(Atomic):事务是由一个或多个活动所组成的一个工作单元。原子确保事务中的所有操作全部发生或全部不发生。如果所有的活动都成功了,事务也就成功了。如果任意一个活动失败了,整个事务也失败并回滚。
一致性(Consistent):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态。现实的数据不应该被损坏。
隔离性(Isolated):事务允许多个用户对相同的数据进行操作,每个用户的操作不会与其他用户纠缠在一起。因此,事务应该被彼此隔离,避免发生同步读写相同数据的事情(注意的是,隔离性往往涉及到锁定数据库中的行或表)。
持久性(Durable):一旦事务完成,事务的结果应该持久化,这样就能从任何的系统崩溃中恢复过来。这一般会涉及将结果存储到数据库或其他形式的持久化存储中。
十三、事务中可能会出现的并发问题有哪些?
答:事务中的并发问题有:脏读、不可重复读、幻读。
解决并发问题的方法就是设置隔离级别。
在理想情况下,事务之间是完全隔离的,从而可以防止这些问题发生,但是完全隔离会导致性能问题,因为它通常会涉及锁定数据库中的记录,侵占性的锁定会阻碍并发性,要求事务互相等待以完成各自的工作。
考虑到完全的隔离会导致性能问题,而且并不是所有的应用程序都需要完全的隔离,所以有时应用程序需要在事务隔离上有一定的灵活性。因此就会有各种隔离级别。
十四、事务中有几种隔离级别?
答:4种:读未提交(uncommitted)、读已提交(committed)、可重复读(repeatable_read)、串行化(serializable)。
读未提交(uncommitted):允许读取尚未提交的数据变更。可能会导致脏读、幻读或不可重复读。
读已提交(committed):允许读取并发事务已经提交的数据。可以阻止脏读、但是幻读或不可重复读仍有可能发生。
可重复读(repeatable_read):可以阻止脏读和不可重复读,但可能会导致幻读。
串行化(serializable):完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读。这是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的。
十五、简单说一下使用Spring整合SSM框架,需要配置哪些东西?
答:Spring整合Dao,要配置数据库启动,配置SqlSessionFactory,配置Mapper动态代理。
Spring整合Service,要配置包扫描器(开启注解驱动),要配置事务管理(事务管理器,事务通知,事务切面)。
Spring整合Web,要配置包扫描器(扫描Controller),配置处理器映射器和处理器适配器(采用注解驱动的方法),配置视图解析器。
在web.xml,要加载Spring容器,并且要配置一个springMVC的前端控制器。
十六、Spring 框架中都用到了哪些设计模式?
答:1、代理模式—在AOP和remoting中被用的比较多。
2、单例模式—在spring配置文件中定义的bean默认为单例模式。
3、工厂模式—BeanFactory用来创建对象的实例。
4、模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
5、前端控制器—Spring提供了DispatcherServlet来对请求进行分发。
6、视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。
7、依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。
十七、Spring设值注入和构造注入有什么区别?
答:相比之下,设值注入具有如下的优点:
1. 与传统的JavaBean的写法更相似,程序开发人员更容易理解、接受。通过setter方法设定依赖关系显得更加直观、自然。
2. 对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题。尤其是在某些属性可选的情况下,多参数的构造器更加笨重。
构造注入也不是绝对不如设值注入,在某些特定的场景下,构造注入比设值注入更优秀:
1、构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。例如,组件中其他依赖关系的注入,常常需要依赖于Datasource的注入。采用构造注入,可以在代码中清晰地决定注入顺序。
2、对于依赖关系无须变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器内设定。因此,无须担心后续的代码对依赖关系产生破坏。
3. 依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。
综上所述,一般采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无须变
化的的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用设值注入
一、什么是SpringMVC?简单讲一下它的优点有哪些?
答:Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无需中间整合层来整合 ,在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合;它的优点有:
1、它是基于组件技术的。全部的应用对象,无论控制器和视图,还是业务对象之类的都是 java组件。并且和Spring提供的其他基础结构紧密集成。
2、不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)
3、可以任意使用各种视图技术,而不仅仅局限于JSP
4、 支持各种请求资源的映射策略。
5、它应是易于扩展的。
二、SpringMVC的请求流程?
答:1、用户发送请求至前端控制器DispatcherServlet;
2、DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器;
5、执行处理器(Handler,也叫后端控制器);
6、Handler执行完成返回ModelAndView;
7、HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
8、DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
9、ViewResolver解析后返回具体View;
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
11、DispatcherServlet响应用户。
三、Spring MVC的主要组件?
答:1、前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果 相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
2、处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler
3、处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
4、处理器Handler(需要程序员开发)
5、视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析 根据视图逻辑名解析成真正的视图(view)
6、视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
四、SpringMVC怎么样设定重定向和转发的?
答:1、在返回值前面加"forward:"就可以让结果转发,譬如"forward:user.do?name=method4"
2、在返回值前面加"redirect:"就可以让返回值重定向,譬如"redirect:http://www.baidu.com"
五、SpringMVC怎么和AJAX相互调用的?
答:通过Jackson框架就可以把Java里面的对象,直接转化成Js可以识别的Json对象。具体步骤如下 :
(1)加入Jackson.jar
(2)在配置文件中配置json的映射
(3)在接受Ajax方法里可以直接返回Object,List等,但方法前面要加上@ResponseBody注解。
六、SpringMVC里面拦截器是怎么写的?
答: 有两种写法,一种是实现HandlerInterceptor接口,另外一种是继承适配器类,,接着在接口方法当中,实现处理逻辑;然后在SpringMvc的配置文件中配置拦截器即可。
七、Spring MVC的异常处理?
答:可以将异常抛给Spring框架,由Spring框架来处理;我们只需要配置简单的异常处理器,在异常处理器中添视图页面即可。
八、SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决?
答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。
九、@RequestMapping注解用在类上面有什么作用?
答:是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
十、如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?
答:直接在方法中声明这个对象,SpringMvc就自动会把属性赋值到这个对象里面。
十一、SpringMvc用什么对象从后台向前台传递数据的?
答:通过ModelMap对象,可以在这个对象里面用put方法,把对象加到里面,前台就可以通过el表达式拿到。
十二、SpringMVC底层实现?
答:HandlerMapping:用于handlers映射请求和一系列的对于拦截器的前处理和后处理,大部分用@Controller注解。
HandlerAdapter:帮助DispatcherServlet处理映射请求处理程序的适配器,而不用考虑实际调用的是 哪个处理程序。
HandlerExceptionResolver:处理映射异常。
ViewResolver:根据实际配置解析实际的View类型。
LocaleResolver:解决客户正在使用的区域设置以及可能的时区,以便能够提供国际化视野。
ThemeResolver:解决Web应用程序可以使用的主题,例如提供个性化布局。
MultipartResolver:解析多部分请求,以支持从HTML表单上传文件。
FlashMapManager:存储并检索可用于将一个请求属性传递到另一个请求的input和output的FlashMap,通常用于重定向。
1、用户发送请求至前端控制器 DispatcherServlet;
2、DispatcherServlet 收到请求后,调用 HandlerMapping 处理器映射器,请求获取 Handle;
3、处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果
有则生成)一并返回给 DispatcherServlet;
4、DispatcherServlet 通过 HandlerAdapter 处理器适配器调用处理器;
5、执行处理器(Handler,也叫后端控制器);
6、Handler 执行完成返回 ModelAndView;
7、HandlerAdapter 将 Handler 执行结果 ModelAndView 返回给 DispatcherServlet;
8、DispatcherServlet 将 ModelAndView 传给 ViewResolver 视图解析器进行解析;
9、ViewResolver 解析后返回具体 View;
答:MyBatis是一个可以自定义SQL、存储过程和高级映射的持久层框架。
答:1 MyBatis的一级缓存是基于SqlSession级别的,也就是说某个SqlSession进行某个查询操作后会将该结果暂时缓存起来,而后在所有的SqlSession没有对该表进行插入、修改、删除操作的情况下,当这个SqlSession再次发起此查询时SqlSession不会去数据库执行查询操作,而是直接从缓存拿出上次查询的结果。不同的SqlSession之间缓存的数据互不影响。
2 MyBatis的二级缓存是基于Mapper级别的,也就是说多个SqlSession去使用某个Mapper的查询语句时,得到的缓存数据是可共用的。
二、Mybatis是如何进行分页的?分页插件的原理是什么?
答:1、Mybatis使用RowBounds对象进行分页,也可以直接编写sql实现分页,也可以使用Mybatis的分页插件。
2、分页插件的原理:实现Mybatis提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql。
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10
答:1、#是预编译处理,$是字符串替换。
2、Mybatis在处理#时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
3、Mybatis在处理$时,就是把$替换成变量的值。
4、使用#可以有效的防止SQL注入,提高系统安全性。
三、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
答:1、Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
2、它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
四、接口绑定有几种实现方式,分别是怎么实现的?
答:接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select@Update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。
五、MyBatis实现一对一有几种方式?具体怎么操作的?
答:有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在resultMap里面配置association节点配置一对一的类就可以完成。嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。
六、模糊查询like语句该怎么写?
答:1、在java中拼接通配符,通过#{}赋值
2、在Sql语句中拼接通配符 (不安全 会引起Sql注入)
七、通常一个Xml映射文件,都会写一个Dao接口与之对应, Dao的工作原理,是否可以重载?
答:不能重载,因为通过Dao寻找Xml对应的sql的时候全限名+方法名的保存和寻找策略。接口工作原理为jdk动态代理原理,运行时会为dao生成proxy,代理对象会拦截接口方法,去执行对应的sql返回数据。
八、在mapper中如何传递多个参数?
答:1、直接在方法中传递参数,xml文件用#{0} #{1}来获取
2、使用 @param 注解:这样可以直接在xml文件中通过#{name}来获取;
答:1.放在代理层,比如MySQL-Proxy,这样针对整个应用程序都是透明的。 mysql官方不建议实际生产中使用。缺点:降低性能,不支持事务
2.使用AbstractRoutingDataSource+aop+annotation在dao层决定数据源。
如果采用了mybatis, 可以将读写分离放在ORM层,比如mybatis可以通过mybatis plugin拦截sql语句,所有的insert/update/delete都访问master库,所有的select 都访问salve库,这样对于dao层都是透明。 plugin实现时可以通过注解或者分析语句是读写方法来选定主从库。不过这样依然有一个问题, 也就是不支持事务, 所以我们还需要重写一下DataSourceTransactionManager, 将read-only的事务扔进读库, 其余的有读有写的扔进写库。
3.使用AbstractRoutingDataSource+aop+annotation在service层决定数据源,可以支持事务。
SpringBoot
一、什么是 Spring Boot?Spring Boot 有哪些优点?
答:Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。它的优点有:
1、容易上手,提升开发效率,为 Spring 开发提供一个更快、更广泛的入门体验。
2、开箱即用,远离繁琐的配置。
3、提供了一系列大型项目通用的非业务性功能,例如:内嵌服务器、安全管理、运行数据。
4、监控、运行状况检查和外部化配置等。
5、没有代码生成,也不需要XML配置。
6、避免大量的 Maven 导入和各种版本冲突。
二、Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
答:启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
@ComponentScan:Spring组件扫描。
三、Spring Boot 自动配置原理是什么?
答:1、注解@EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心。
2、@EnableAutoConfiguration 给容器导入META-INF/spring.factories 里定义自动配置类。
3、筛选有效的自动配置类。
4、每一个自动配置类结合对应的 xxxProperties.java 读取配置文件进行自动配置功能。
四、SpringBoot和SpringMVC有什么区别?
答:两者联系:spring在刚开始的时候使用工厂模式(DI)和代理模式(AOP)解耦应用组件,进而开发出适用于Web开发的SpringMVC,在实际开发过程当中会使用到很多样板代码,就开发出了懒人版的SpringBoot;
区别:
1、springMVC是Spring的一个模式,是一个Web框架,提供了一个轻度耦合的方式来开发Web应用;
2、SpringBoot是习惯优于配置,降低了项目搭建的难度;
3、springMVC需要使用到TomCat服务器,SpringBoot的话是内嵌了Tomcat服务器的
五、Spring Boot 配置加载顺序?
答:在 Spring Boot 里面,可以使用以下几种方式来加载配置。
1、properties文件;
2、YAML文件;
3、系统环境变量;
4、命令行参数;
六、Spring Security在项目中如何实现?
答:1. pom依赖:
第一个依赖是security的核心依赖包,第二个是security对freemarker的标签的支持包。
加了这两个东西之后,重启项目,它就会弹出让你登录的窗口
2. 继承重写WebSecurityConfigurerAdapter类:
http.formLogin() 表示以表单的形式登录,authorizeRequests()表示什么请求需要验证呢?anyRequest()所有的请求都需要验证。authenticated();证明是有效的情况下。
UserDetailsService这个官方接口它是用来通过username加载User信息的,你只需要把这个类注入到类里,它会自动去找这个实现类。
3.UserDetailServiceImpl 实现UserDetailsService接口
这个注入类就是获取impl中从数据库里查出来的密码,然后match判断。所以就要求我们注册用户的时候,先encode()一下再存入数据库,然后读出来直接返回,我的这个impl是从数据库里读出密码然后加密的,因为我怕数据库密码我都会忘记。
4. 启动项目
七、Spring Security 和 Shiro 的区别 ?
答:由于 Spring Boot 官方提供了大量的非常方便的开箱即用的 Starter ,包括 Spring Security 的 Starter ,使得在 Spring Boot 中使用 Spring Security 变得更加容易,甚至只需要添加一个依赖就可以保护所有的接口,所以,如果是 Spring Boot 项目,一般选择 Spring Security 。当然这只是一个建议的组合,单纯从技术上来说,无论怎么组合,都是没有问题的。Shiro 和 Spring Security 相比,主要有如下一些特点:
1、Spring Security 是一个重量级的安全管理框架;Shiro 则是一个轻量级的安全管理框架。
2、Spring Security 概念复杂,配置繁琐;Shiro 概念简单、配置简单。
3、Spring Security 功能强大;Shiro 功能简单。
八、Spring Boot 中如何解决跨域问题 ?
答:1、跨域可以在前端通过 JSONP 来解决,但是 JSONP 只可以发送 GET 请求,无法发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋,因此我们推荐在后端通过 (CORS,Cross-origin resource sharing) 来解决跨域问题。
2、这种解决方案并非 Spring Boot 特有的,在传统的 SSM 框架中,就可以通过 CORS 来解决跨域问题,只不过之前我们是在 XML 文件中配置 CORS ,现在可以通过实现WebMvcConfigurer接口然后重写addCorsMappings方法解决跨域问题。
3、项目中前后端分离部署,所以需要解决跨域的问题。
4、我们使用cookie存放用户登录的信息,在spring拦截器进行权限控制,当权限不符合时,直接返回给用户固定的json结果。
当用户登录以后,正常使用;当用户退出登录状态时或者token过期时,由于拦截器和跨域的顺序有问题,出现了跨域的现象。
5、我们知道一个http请求,先走filter,到达servlet后才进行拦截器的处理,如果我们把cors放在filter里,就可以优先于权限拦截器执行。
九、Spring Boot 中的监视器是什么?
答:Spring boot actuator 是 spring 启动框架中的重要功能之一。Spring boot 监视器可帮助您访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 HTTP URL 访问的REST 端点来检查状态。
十、我们如何监视所有 Spring Boot 微服务?
答:Spring Boot 提供监视器端点以监控各个微服务的度量。这些端点对于获取有关应用程序的信息(如它们是否已启动)以及它们的组件(如数据库等)是否正常运行很有帮助。但是,使用监视器的一个主要缺点或困难是,我们必须单独打开应用程序的知识点以了解其状态或健康状况。想象一下涉及 50 个应用程序的微服务,管理员将不得不击中所有 50 个应用程序的执行终端。为了帮助我们处理这种情况,我们将在 Spring Boot Actuator 之上,它提供了一个 Web UI,使我们能够可视化多个应用程序的度量。
十一、什么是 JavaConfig?
答:Spring JavaConfig 是 Spring 社区的产品,它提供了配置 Spring IoC 容器的纯Java 方法。因此它有助于避免使用 XML 配置。使用 JavaConfig 的优点在于:
1、面向对象的配置。由于配置被定义为 JavaConfig 中的类,因此用户可以充分利用 Java 中的面向对象功能。一个配置类可以继承另一个,重写它的@Bean 方法等。
2、减少或消除 XML 配置。基于依赖注入原则的外化配置的好处已被证明。但是,许多开发人员不希望在 XML 和 Java 之间来回切换。JavaConfig 为开发人员提供了一种纯 Java 方法来配置与 XML 配置概念相似的 Spring 容器。从技术角度来讲,只使用 JavaConfig 配置类来配置容器是可行的,但实际上很多人认为将JavaConfig 与 XML 混合匹配是理想的。
3、类型安全和重构友好。JavaConfig 提供了一种类型安全的方法来配置 Spring容器。由于 Java 5.0 对泛型的支持,现在可以按类型而不是按名称检索 bean,不需要任何强制转换或基于字符串的查找。
十二、什么是 WebSockets?
答:WebSocket 是一种计算机通信协议,通过单个 TCP 连接提供全双工通信信道。
1、WebSocket 是双向的。使用 WebSocket 客户端或服务器可以发起消息发送。
2、WebSocket 是全双工的。客户端和服务器通信是相互独立的。
3、单个 TCP 连接。初始连接使用 HTTP,然后将此连接升级到基于套接字的连接。然后这个单一连接用于所有未来的通信。
4、Light与 http 相比,WebSocket 消息数据交换要轻得多。
十三、什么是 FreeMarker 模板?
答:FreeMarker 是一个基于 Java 的模板引擎,最初专注于使用 MVC 软件架构进行动态网页生成。使用 Freemarker 的主要优点是表示层和业务层的完全分离。程序员可以处理应用程序代码,而设计人员可以处理 html 页面设计。最后使用freemarker 可以将这些结合起来,给出最终的输出页面。
十四、如何集成 Spring Boot 和 ActiveMQ?
答:对于集成 Spring Boot 和 ActiveMQ,我们使用依赖关系。 它只需要很少的配置,并且不需要样板代码。
十五、什么是 Swagger?你用 Spring Boot 实现了它吗?
答:Swagger 广泛用于可视化 API,使用 Swagger UI 为前端开发人员提供在线沙箱。Swagger 是用于生成 RESTful Web 服务的可视化表示的工具,规范和完整框架实现。它使文档能够以与服务器相同的速度更新。当通过 Swagger 正确定义时,消费者可以使用最少量的实现逻辑来理解远程服务并与其进行交互。因此,Swagger消除了调用服务时的猜测。
十六、前后端分离,如何维护接口文档 ?
答:前后端分离开发日益流行,大部分情况下,我们都是通过 Spring Boot 做前后端分离开发,前后端分离一定会有接口文档,不然会前后端会深深陷入到扯皮中。一个比较笨的方法就是使用 word 或者 md 来维护接口文档,但是效率太低,接口一变,所有人手上的文档都得变。在 Spring Boot 中,这个问题常见的解决方案是 Swagger ,使用 Swagger 我们可以快速生成一个接口文档网站,接口一旦发生变化,文档就会自动更新,所有开发工程师访问这一个在线网站就可以获取到最新的接口文档,非常方便。
十七、如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?Spring Boot项目如何热部署?
答:这可以使用 DEV 工具来实现。通过这种依赖关系,您可以节省任何更改,嵌入式tomcat 将重新启动。Spring Boot 有一个开发工具(DevTools)模块,它有助于提高开发人员的生产力。
Java 开发人员面临的一个主要挑战是将文件更改自动部署到服务器并自动重启服务器。开发人员可以重新加载 Spring Boot 上的更改,而无需重新启动服务器。这将消除每次手动部署更改的需要。