3W+字长文深度总结|Java程序员面试题精华版集合(内附思惟导图)!

一、在JAVA中如何跳出当前的多重嵌套循环?
在Java中,要想跳出多重循环,能够在外面的循环语句前定义一个标号,而后在里层循环体的代码中使用带有标号的break语句,便可跳出外层循环。例如,前端

ok: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5)
break ok;  
}
}

另外,我我的一般并不使用标号这种方式,而是让外层的循环条件表达式的结果能够受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。java

int arr[][] = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 9 } };
boolean found = false;
for (int i = 0; i < arr.length && !found; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println("i=" + i + ",j=" + j);
if (arr[i][j] == 5) 
{
found = true;
break;
}
}
}

二、请说出做用域public,private,protected,以及不写时的区别。nginx

  • private修饰的成员变量和函数只能在类自己和内部类中被访问。
  • protected 修饰的成员变量和函数能被类自己、子类及同一个包中的类访问。
  • public修饰的成员变量和函数能够被类、子类、同一个包中的类以及任意其余类访问。

默认状况(不写)下,属于一种包访问,即能被类自己以及同一个包中的类访问。
下面这个表能清楚的说明java中做用域操做符的做用:
image.png程序员

三、说说对javaee中的session的理解,你是怎么用session的?
在servlet 的api中,session表示的是浏览器和web服务器的一次会话。在web服务器中是经过session来区别不一样的浏览器的,由于web 服务器采用的是http协议进行通信,web 服务器根本不知道正在请求的浏览器是谁,它不会记录浏览器的访问信息,因此须要session来记录发出请求的浏览器是谁,session 和浏览器之间是怎么保持通讯的呢? 当浏览器第一次对一个web站点发出请求后,web服务器按照请求路径查找资源,并生成一个session,web服务器将查找到的资源做为响应返回给浏览器,在这个响应中会附带上一个特殊名称的cookie信息,这个cookie 就是session的id。以后浏览器再次发出请求时,会在请求信息中带上这个cookie信息,这个cookie 的做用就是用来告诉web服务器,我这个浏览器已经访问过你了,你不须要再生成session了。web

Session 的应用有不少面试

  • 1.过滤未登陆用户
    能够用于存放用户信息,当用户登陆后,就将用户信息放入session,若是没有登陆,在session中就不会有用户信息,这样就能够防止未登陆用户查看一些信息。
  • 2.防止表单重复提交
  • 3.网上商城中的购物车

四、分层设计的好处?
把各个功能按调用流程进行了模块化,模块化带来的好处就是能够随意组合。分层的好处:ajax

  • 1.实现了软件之间的解耦
  • 2.便于进行分工
  • 3.便于维护
  • 4.提升软件组件的重用
  • 5.便于替换某种产品,好比持久层用的是hibernate,须要更换产品为mybatis,就不用改其余业务的代码,直接把配置一改便可
  • 6.便于产品功能的扩展
  • 7.便于适用用户需求的不断变化

五、java中实现多态的机制是什么?redis

靠的是父类或接口定义的引用变量能够指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。spring

六、abstract(抽象类)和interface(接口)有什么区别?
含有abstract修饰符的class即为抽象类,abstract 类不能建立的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法没必要是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,因此,不能有抽象构造方法或抽象静态方法。若是子类没有实现抽象父类中的全部抽象方法,那么子类也必须定义为abstract类型。sql

接口(interface)能够说成是抽象类的一种特例,接口中的全部方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下二者的语法区别:

  • 1.抽象类能够有构造方法,接口中不能有构造方法。
  • 2.抽象类中能够有普通成员变量,接口中没有普通成员变量
  • 3.抽象类中能够包含非抽象的普通方法,接口中的全部方法必须都是抽象的,不能有非抽象的普通方法。
  • 4.抽象类中的抽象方法的访问类型能够是public,protected和默认类型,但接口中的抽象方法只能是public类型的,而且默认即为public abstract类型。
  • 5.抽象类中能够包含静态方法,接口中不能包含静态方法
  • 6.抽象类和接口中均可以包含静态成员变量,抽象类中的静态成员变量的访问类型能够任意,但接口中定义的变量只能是public static final类型,而且默认即为public static final类型。
  • 7.一个类能够实现多个接口,但只能继承一个抽象类。

七、构造方法Constructor是否可被override(重写)?
构造方法Constructor不能被继承,所以不能重写Override,但能够被重载Overload。

八、面向对象的特征有哪些方面?
面向对象的三大特征:

  • 封装:保证对象自身数据的完整性和安全性。
  • 继承:创建类之间的关系,实现代码复用,方便系统的扩展。
  • 多态:相同的方法调用,能够实现不一样的实现方式。

九、String是最基本的数据类型吗,是否能够继承String类?
java的基本数据类型有如下8种:

  • 整型: byte short int long
  • 浮点型: float double
  • 字符型: char
  • 布尔: boolean

java.lang.String类是final类型的,所以不能够继承这个类、也不能修改这个类 。为了提升效率节省空间,对于要常常修改的字符串,建议使用StringBuffer类。

十、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。
String有length()这个方法。

十一、String s = new String("abc");建立了几个String Object? 两者之间有什么区别?
答案:一个或者两个
解析:

  • 1.若是String缓冲区中,已经建立"abc",则不会继续建立,此时只建立了一个对象new String("abc");
  • 2.若是String缓冲区中,没有建立"abc",则会建立两个对象,一个对象的值是"abc",一个对象new String("abc")。

十二、下面这条语句一共建立了多少个对象:String s="a"+"b"+"c"+"d"
只建立了一个String对象,由于这行代码被编译器编译时进行了优化,至关于直接定义了一个”abcd”的字符串,因此只建立了一个String对象。

1三、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,何时被执行,在return前仍是后?
finally中的代码确定会执行,可是会先执行try中的代码,若是try中有return,那么return的东西会先放到函数栈中,而后再执行finally中的代码。

  • ①、若是finally中也有return,则会直接返回并终止程序,函数栈中的return不会被完成;
  • ②、若是finally中没有return,则在执行完finally中的代码以后,会将函数栈中的try中的return的内容返回并终止程序;

1四、final, finally, finalize的区别

  • Final:是全局变量声明的时候使用,意思是这个变量不可被修改,不可被override,通常用于声明常量,或者系统设置的值。
  • finally:是在异常处理时提供finally块来执行任何清除操做。无论有没有异常被抛出、捕获,finally块都会被执行。
  • finalize:是方法名。java技术容许使用finalize()方法在垃圾收集器将对象从内存中清除出去以前作必要的清理工做。

1五、运行时异常与通常异常有何异同?
Java提供了两类主要的异常:运行时异常runtime exception和通常异常checked exception

  • 运行时异常runtime exception,咱们能够不处理。这样的异常由虚拟机接管。出现运行时异常后,系统会把异常一直往上层抛,一直遇处处理代码。若是不对运行时异常进行处理,那么出现运行时异常以后,要么是线程停止,要么是主程序终止。
  • 通常异常checked exception,JAVA要求程序员对其进行try catch处理。因此,面对这种异常无论咱们是否愿意,只能本身去写一大堆catch块去处理可能的异常。

1六、error和exception有什么区别?

  • Error(错误)表示系统级的错误和程序没必要处理的异常,是java运行环境中的内部错误或者硬件问题。好比:内存资源不足等。对于这种错误,程序基本无能为力,除了退出运行外别无选择,它是由Java虚拟机抛出的。
  • Exception(违例)表示须要捕捉或者须要程序进行处理的异常,它处理的是由于程序设计的瑕疵而引发的问题或者在外的输入等引发的通常性问题,是程序必须处理的。Exception又细分为运行时异常runtime exception,受检查异常checked exception(通常异常)。

1七、请写出你最多见到的5个运行时异常 runtime exception

  • ClassCastException 类型强制转换异常
  • ClassNotFoundException 类没找到时,抛出该异常
  • FileNotFoundException 文件未找到异常
  • NullPointerException 空指针异常
  • SQLException 操做数据库异常
  • ArithmeticException 算术异常
  • IllegalArgumentException 传递非法参数异常
  • IndexOutOfBoundsException 下标越界异常
  • NoSuchElementException 方法未找到异常

1八、Java语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别表明什么意义?在try块中能够抛出异常吗?

  • try{}语句块 中放的是要检测的java代码,可能有会抛出异常,也可能会正常执行;
  • catch(异常类型){}块 是当Java运行时系统接收到try块中所抛出的异常对象时,会寻找能处理这一异常的catch块来进行处理(能够有多个catch块);
  • finally{}块 无论系统有没有抛出异常都会去执行,通常用来释放资源。除了在以前执行了System.exit(0);
  • throw 用于手动抛出异常。做为程序员能够在任意位置手动抛出异常;
  • throws 用于在方法上标识要抛出的异常,抛出的异常交由调用者处理;

1九、ArrayList和Vector、LinkedList的区别?

  • (1)Vector是线程安全的,而ArrayList不是。
  • (2)当存储空间不足的时候,ArrayList默认增长为原来的50%,Vector默认增长为原来的一倍。
  • (3)Vector能够设置容量增长的参数,而ArrayList不能够。
  • (4)LinkedList使用双向链表实现存储,按序号索引数据须要进行前向或后向遍历,可是插入数据时只须要记录本项的先后项便可,因此插入速度较快。

20、List 和 Map 区别?

  • (1)、List是存储单列数据的集合,List中存储的数据是有顺序,而且容许重复;
  • (2)、Map是存储键和值这样的双列数据的集合,Map中存储的数据是没有顺序的,其键是不能重复的,它的值是能够有重复的。

2一、List、Map、Set三个接口,存取元素时,各有什么特色?
List与Set都是单列元素的集合,它们有一个共同的父接口Collection。

  • (1)List表示有前后顺序的集合
    存元素:屡次调用add(Object)方法时,每次加入的对象按先来后到的顺序排序,也能够插队,即调用add(int index,Object)方法,就能够指定当前对象在集合中的存放位置。
    取元素:
方法1:Iterator接口取得全部,逐一遍历各个元素
方法2:调用get(index i)来明确说明取第几个。
  • (2)Set里面不容许有重复的元素
    存元素:add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true;当集合含有与某个元素equals相等的元素时,此时add方法没法加入该元素,返回结果为false。
    取元素:无法说取第几个,只能以Iterator接口取得全部的元素,再逐一遍历各个元素。
  • (3)Map是双列的集合,存放用put方法:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。
    取元素:用get(Object key)方法根据key得到相应的value。

2二、说出一些经常使用的类,包,接口,请各举例5个

  • 经常使用的类:
    Object
    Date
    File
    Exception
    Random
    String
    integer
  • 经常使用的包:
    java.io
    java.lang
    java.util
    java.sql
    java.net
  • 经常使用的接口:
    Set
    List
    Map
    Collection
    Runnable
    Session
    Servlet

2三、java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

  • 基于流方向:
    InputStream
    OutputStream
  • 基于字符:
    Reader
    Writer
  • 流和字符之间的配接:
    InputStreamReader
    OutputStreamWriter

2四、字节流与字符流的区别?

  • (1)字节流在操做时自己不会用到缓冲区(内存),是文件自己直接操做的,而字符流在操做时使用了缓冲区,经过缓冲区再操做文件。
  • (2)字节流中,中文可能会乱码,字符流不会。

2五、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的做用。
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时所引起的问题。

序列化的实现:将须要被序列化的类实现Serializable接口,而后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就能够将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流;

Serializable.只有实现了 serializable和Externalizable接口的类的对象才能被序列化

Java 序列化技术能够使你将一个对象的状态写入一个Byte 流里,而且能够从其它地方把该Byte 流里的数据读出来,从新构造一个相同的对象。这种机制容许你将对象经过网络进行传播,并能够随时把对象持久化到数据库、文件等系统里。Java的序列化机制是RMI、EJB等技术的技术基础。用途:利用对象的序列化实现保存应用程序的当前工做状态,下次再启动的时候将自动地恢复到上次执行的状态。

2六、GC是什么? 为何要有GC?
GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存会致使程序或系统的不稳定甚至崩溃,Java提供的GC功能能够自动监测对象是否超过做用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操做方法。Java程序员不用担忧内存管理,由于垃圾收集器会自动进行管理。

2七、排序都有哪几种方法?请用JAVA实现一个冒泡排序。
排序的方法有:

  • 插入排序(直接插入排序、希尔排序)
  • 交换排序(冒泡排序、快速排序)
  • 选择排序(直接选择排序、堆排序)
  • 归并排序
  • 分配排序(箱排序、基数排序)
  • 冒泡排序:
for(int i=0;i<arr.length-1;i++){ //外层循环控制排序趟数  
for(int j=0;j<arr.length-1-i;j++){ //内层循环控制每一趟排序多少次  
if(arr[j]>arr[j+1]){  
int temp=arr[j];  
arr[j]=arr[j+1];  
arr[j+1]=temp;  
}  
}  
}

冒泡排序口诀:

  • 1. N个数字来排队,两两相比小靠前。
  • 2. 外层循环N-1,内层循环N-1-i
  • 3. 若是要降序,只要把程序中的大于号换成小于号。

2八、说一说Servlet的生命周期?
servlet的生命周期分为如下几个步骤:

  • 第1、加载并实例化
  • 第2、初始化
  • 第3、服务
  • 第4、销毁

容器启动的时候,会加载servlet的class,并new出这个对象,而后,当用户请求这个servlet的时候,容器会调用init方法初始化这个servlet,这也是整个生命周期中只会调用一次的方法,而后,会调用service方法,由这个方法调用doGet或doPost方法来响应用户,而后,容器在可用资源紧张或是长期没有对Servlet发出请求的状况下,会销毁这个servlet。

2九、servlet api中forward() 与redirect()的区别?

  • (1)forward仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;
  • (2)redirect则是彻底的跳转,浏览器将会获得跳转的地址,并从新发送请求连接。这样,从浏览器的地址栏中能够看到跳转后的连接地址。因此,forward更加高效,在forward能够知足须要时,尽可能使用forward()方法,而且,这样也有助于隐藏实际的连接。但在某些状况下(好比须要跳转到另外一个服务器上的资源),则必须使用sendRedirect()方法。
  • (3)forward:转发页面和转发到的页面能够共享request里面的数据.
  • (4)redirect:不能共享数据

30、request.getAttribute() 和 request.getParameter() 有何区别?

  • (1)request.getParameter 是用来接收post、get方法传递过来的参数值
  • (2)request.getAttribute 是获取对象容器(session)的值
  • (3)request.getParameter()方法返回String类型的数据。
  • (4)request.getAttribute()方法返回的是request范围内存在的对象。

3一、jsp有哪些经常使用内置对象?

  • <1>、request
  • <2>、response
  • <3>、session
  • <4>、out
  • <5>、page
  • <6>、application
  • <7>、exception
  • <8>、pageContext
  • <9>、config

3二、JSP和Servlet有哪些相同点和不一样点,他们之间的联系是什么?

  • ①、JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达,JSP编译后是”类servlet”。
  • ②、JSP是Java和HTML组合成的一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。
  • ③、Servlet和JSP最主要的不一样点在于,Servlet的应用逻辑是在Java文件中,而且彻底从表示层中的HTML里分离开来。

3三、MVC的各个部分都有哪些技术来实现?
MVC 是 Model-View-Controller 的简写,经过这种设计模型把应用逻辑、处理过程和显示逻辑分红不一样的组件实现。

  • (1)模型(Model)表明的是应用的业务逻辑( 经过JavaBean, EJB 组件实现)
  • (2)视图(View)是应用的表示面( 由 JSP 页面产生)
  • (3)控制器(controller) 是提供应用的处理过程控制( 通常是一个 Servlet)

3四、数据库三范式是什么?

  • 第一范式:确保每一列的原子性
    (原子性字段不可再分,不然就不是关系型数据库)
  • 第二范式:在第一范式的基础上更进一层,确保表中的每列都和主键相关
    (惟一性,一个表只说明一个事物)
  • 第三范式:在第二范式的基础上更进一层,确保每列都和主键列直接相关,而不是间接相关
    (每列都与主键有直接关系,不存在传递依赖)

3五、说出一些数据库优化方面的经验?

  • 1.用索引提升效率,避免在索引列上使用计算。
  • 2.SELECT子句中避免使用‘ * ‘
  • 3.减小访问数据库的次数
  • 4.尽可能多使用COMMIT
  • 5.用Where子句替换HAVING子句
  • 6.用EXISTS替代IN、用NOT EXISTS替代NOT IN
  • 7.使用表的别名(Alias)
  • 8.避免使用耗费资源的操做
  • 9.用 PreparedStatement 通常来讲比 Statement 性能高
  • 10.有外键约束会影响插入和删除性能, 若是程序可以保证数据的完整性, 那在设计数据库时就去掉外键
  • 11.要查询的数据多时,使用分页进行查询
  • 12.尽可能不用ORDER BY RAND()
  • 13.利用查询缓存来优化查询
  • 14.尽可能不使用NOT IN和like语句操做

3六、Class.forName的做用是什么?

  • Class.forName(xxx.xx.xx) 返回的是一个类,Java里面任何class都要装载在虚拟机上才能运行,这句话就是装载类用的。
  • Class.forName(xxx.xx.xx)的做用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段,动态加载和建立Class对象,最熟悉的就是JDBC链接数据库的时候加载驱动类。

3七、说说数据链接池的工做机制是什么?
J2EE服务器启动时会创建必定数量的池链接,并一直维持很多于此数目的池链接。客户端程序须要链接时,池驱动程序会返回一个未使用的池链接并将其标记为忙。若是当前没有空闲链接,池驱动程序就新建必定数量的链接,新建链接的数量由配置参数决定。当使用的池链接调用完成后,池驱动程序将此链接标记为空闲,其余调用就能够使用这个链接。

3八、为何要用ORM? 和JDBC有何不同?

  • 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配现象的技术。简单的说,ORM是经过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。
  • ORM是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成object,咱们能够用jdbc来实现这种思想,其实,若是咱们的项目是严格按照oop方式编写的话,咱们的jdbc程序无论是有意仍是无心,就已经在实现ORM的工做了。
  • 如今有许多ORM工具,它们底层调用jdbc来实现了ORM工做,咱们直接使用这些工具,就省去了直接使用jdbc的繁琐细节,提升了开发效率,如今用的较多的ORM工具是hibernate。

3九、xml有哪些解析技术?区别是什么?

xml有如下2种解析技术:
  • (1)DOM(Document Object Model)文档对象模型
  • (2)SAX(Simple API for XML)

二者的区别:DOM是一次性将整个文档读入内存操做,若是是文档比较小,读入内存,能够极大提升操做的速度,但若是文档比较大,那么DOM就比较吃力了。因此此时SAX应用而生,它不是一次性的将整个文档读入内存,这对于处理大型文档就比较给力了。

40、谈谈你对Struts的理解。

  • Struts框架是对MVC模式的封装,为开发者提供了MVC的3个逻辑组成部分,主要由ActionServlet、Action和struts-config.xml配置文件组成控制层,由ActionForm来承担模型层的功能,而struts 的视图层主要由jsp完成;
  • 它处理一次请求的流程:由ActionServlet接受一个请求,而后依据配置文件来判断由哪一个Action来处理和由哪一个ActionForm来保存数据,再经过Action的返回值来判断应该由哪一个jsp来展现数据。

4一、Struts优缺点
优势:

  • (1) 实现了MVC模式,层次结构清晰,使程序员只需关注业务逻辑的实现。
  • (2) 丰富的标签库,大大提升了开发的效率。
  • (3) Struts2提供丰富的拦截器实现。
  • (4) 经过配置文件,就能够掌握整个系统各个部分之间的关系。
  • (5) 异常处理机制,只需在配置文件中配置异常的映射,便可对异常作相应的处理。
  • (6) Struts2的可扩展性高。Struts2的核心jar包中由一个struts-default.xml文件,在该文件中设置了一些默认的bean,resultType类型,默认拦截器栈等,全部这些默认设置,用户均可以利用配置文件更改,能够更改成本身开发的bean,resulttype等。所以用户开发了插件的话只要很简单的配置就能够很容易的和Struts2框架融合,这实现了框架对插件的可插拔的特性。
  • (7) 面向切面编程的思想在Strut2中也有了很好的体现,最重要的体现就是拦截器的使用。拦截器就是一个一个的小功能单位,用户能够将这些拦截器合并成一个大的拦截器,这个合成的拦截器就像单独的拦截器同样,只要将它配置到一个、Action中就能够

缺点:

  • (1) Struts2中Action中取得从jsp中传过来的参数时仍是有点麻烦。能够为Struts2的Action中的属性配置上Getter和Setter方法,经过默认拦截器,就能够将请求参数设置到这些属性中。若是用这种方式,当请求参数不少时,Action类就会被这些表单属性弄的很臃肿,让人感受会很乱。还有Action中的属性不但能够用来得到请求参数还能够输出到Jsp中,这样就会更乱。假设从JSP1中得到了参数money=100000,可是这个Action还要输出到JSP2中,可是输出的格式却不一样,money=100,000,这样这个Action中的money中的值就变了。
  • (2) 校验仍是感受比较繁琐,太烦乱,也太细化了,若是校验出错的只能给用户提示一些信息。若是有多个字段,每一个字段出错时返回到不一样的画面,这个功能在Strut2框架下借助框架提供的校验逻辑就不容易实现。
  • (3) 安全性有待提升。Struts2曝出2个高危安全漏洞,一个是使用缩写的导航参数前缀时的远程代码执行漏洞,另外一个是使用缩写的重定向参数前缀时的开放式重定向漏洞。这些漏洞可以使黑客取得网站服务器的“最高权限”,从而使企业服务器变成黑客手中的“肉鸡”

4二、谈谈你对Spring的理解。
首先Spring是一个开源的框架,Spring为简化企业级应用开发而生,使用Spring能够使简单的JavaBean实现之前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。

在java开发领域,Spring相对于EJB来讲是一种轻量级的,非侵入性的Java开发框架。

Spring主要核心是:

  • (1).控制反转(IOC):之前传统的java开发模式中,当须要一个对象时咱们,咱们会本身使用new或者getInstance等直接或者间接调用构造方法建立一个对象,而在Spring开发模式中,Spring容器使用了工厂模式为咱们建立了所须要的对象,咱们使用时不须要本身去建立,直接调用Spring为咱们提供的对象便可,这就是控制反转的思想。实例化一个java对象有三种方式:使用类构造器,使用静态工厂方法,使用实例工厂方法,当使用spring时咱们就不须要关心经过何种方式实例化一个对象,spring经过控制反起色制自动为咱们实例化一个对象。
  • (2).依赖注入(DI):Spring使用java Bean对象的Set方法或者带参数的构造方法为咱们在建立所需对象时将其属性自动设置所须要的值的过程就是依赖注入的基本思想。
  • (3).面向切面编程(AOP):在面向对象编程(OOP)思想中,咱们将事物纵向抽象成一个个的对象。而在面向切面编程中,咱们将一个个对象某些相似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操做处理的过程就是面向切面编程的思想。

4三、AOP的做用是什么?
AOP(面向切面编程)是一种编程范式,用于提供从另外一角度来考虑程序结构以完善面向对象编程。

主要做用:

  • 1.下降模块之间的耦合度。
  • 2.使系统容易扩展。
  • 3.更好的代码复用

4四、谈谈你对Hibernate的理解。
Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了很是轻量级的对象封装,使得java程序员能够为所欲为的使用对象编程思惟来操纵数据库。

Hibernate的优势:

  • 1. 对JDBC访问数据库的代码作了封装,大大简化了数据访问层繁琐的重复性代码。
  • 2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工做
  • 三、 Hibernate使用Java反射机制而不是字节码加强程序来实现透明性。
  • 四、 Hibernate的性能好,映射的灵活性比较出色。它支持各类关系数据库,从一对一到多对多的各类复杂关系。

hibernate的核心类:
Configuration、SessionFactory 、Session

4五、hibernate中的update()和saveOrUpdate()的区别

  • update() 若是是对一个已经存在的托管对象进行更新那么确定是要使用update()方法了,数据中有这个对象。
  • saveOrUpdate() 这个方法是更新或者插入,有主键就执行更新,若是没有主键就执行插入。

4六、简述 Hibernate 和 JDBC 的优缺点?

  • (1)JDBC与Hibernate在性能上相比,JDBC灵活性有优点。
  • (2)而Hibernate在易学性,易用性上有优点。
  • (3)当用到不少复杂的多表联查和复杂的数据库操做时,JDBC有优点。

4七、Hibernate中,如何书写一个 one to many 配置文件?
one to many 配置文件的方法:
在一方添加集合对象,并封装。而后在对应的映射文件追加标签,设置外检,以及经过one-to-many标签设置集合对象所对应的类型便可。

4八、MyBatis与Hibernate有什么不一样?
Mybatis优点:

  • (1)MyBatis能够进行更为细致的SQL优化,能够减小查询字段。
  • (2)MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优点:

  • <1>、Hibernate的DAO层开发比MyBatis简单,Mybatis须要维护SQL和结果映射。
  • <2>、Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  • <3>、Hibernate数据库移植性很好,MyBatis的数据库移植性很差,不一样的数据库须要写不一样SQL。
  • <4>、Hibernate有更好的二级缓存机制,能够使用第三方缓存。MyBatis自己提供的缓存机制不佳。

4九、hibernate的inverse属性有什么做用?

  • 用来指定关联的控制方的,inverse属性默认是false:
  • 若为false,则关联由本身控制
  • 若为true,则关联由对方控制

50、介绍一下Hibernate的二级缓存
内置缓存:Hibernate自带的,不可卸载,一般在Hibernate的初始化阶段,Hibernate会把映射元数据和预约义的SQL语句放置到SessionFactory的缓存中。该内置缓存是只读的。

外置缓存:一般说的二级缓存也就是外置缓存,在默认状况下SessionFactory不会启用这个缓存插件,外置缓存中的数据是数据库数据的复制,外置缓存的物理介质能够是内存或者硬盘。

适合放入二级缓存中数据:
  • 不多被修改
  • 不是很重要的数据,容许出现偶尔的并发问题
  • 不适合放入二级缓存中的数据
  • 常常被修改
  • 财务数据,绝对不容许出现并发问题
  • 与其余应用数据共享的数据

5一、session中load()和get()的区别

  • (1)load方法支持延迟加载,而get方法则不支持。
  • (2)load方法在没找到数据的时候会抛出ObjectNotFoundException,而get方法则会返回null。

5二、B/S与C/S的联系与区别

(1)c/s(client/server)客户端/服务器

概念:指的是客户端和服务端之间的通讯方式,客户端提供用户请求接口,服务端响应请求进行对应的处理,并返回给客户端,客户端来显示这些内容
协议:任何通用协议
优点:下降系统开销,充分利用两端硬件环境的优点
缺点:维护成本高

(2)B/S(browser/server) 浏览器/服务器

概念:这种结构用户界面是彻底经过www浏览器来实现,一部分事务在前端实现,主要事务逻辑在服务器端实现
协议:http协议
优点:节约开发成本

二者区别:

硬件环境不一样:

  • c/s:专用网络、小型局域网
  • b/s:广域网,只有要操做系统和浏览器就行

对安全要求不一样:

  • c/s:通常面向固定用户群,安全性高
  • b/s:用b/s发布部分可公开信息

对程序架构不一样:

  • c/s:注重流程,对权限屡次校验,少考虑系统运行速度
  • b/s:对安全和访问速度多重考虑

软件重用不一样:

  • c/s:须要总体考虑,构建重用性没有b/s好
  • b/s:构件独立,重用性好

系统维护不一样:

  • c/s:要从总体考察,维护困难
  • b/s:构件个别替换,维护升级简单

处理问题不一样:

  • c/s:用户面固定,安全性高,操做系统相同
  • b/s:用户不固定,与操做平台关系小

用户接口不一样:

  • c/s:Windows平台上,表现方法有限
  • b/s:浏览器,表现方式生动,难度减低,减低开发成本

信息流不一样:

  • c/s:中央集权机械式管理,交互低
  • b/s:信息流可变化,更像交易中心

5三、Spring MVC Framework有那些特色?

  • 1.它是基于组件技术的,所有的应用对象,不管控制器和视图,仍是业务对象之类的都是java组件,而且和Spring提供的其余基础结构紧密集成。
  • 2.不依赖于Servlet API(目标虽是如此,可是在实现的时候确实是依赖于Servlet的)
  • 3.能够任意使用各类视图技术,而不只仅局限于JSP
  • 4.支持各类请求资源的映射策略
  • 5.它应是易于扩展的

5四、SpringMVC的工做流程?

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

5五、简单介绍下springMVC和struts2的区别有哪些?

  • 1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
  • 2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,能够设计为单例或多例(建议单例),struts2是基于类开发,传递参数是经过类的属性,只能设计为多例。
  • 3. Struts采用值栈存储请求和响应的数据,经过OGNL存取数据,springmvc经过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据经过reques域传输到页面。Jsp视图解析器默认使用jstl。

5六、请介绍线程的五种状态

  • 第1、建立状态。在生成线程对象,并无调用该对象的start方法,这是线程处于建立状态手写字符串反转和冒泡排序;
  • 第2、就绪状态。当调用了线程对象的start方法以后,该线程就进入了就绪状态,可是此时线程调度程序尚未把该线程设置为当前线程,此时处于就绪状态。在线程运行以后,从等待或者睡眠中回来以后,也会处于就绪状态。
  • 第3、运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
  • 第4、阻塞状态。线程正在运行的时候,被暂停,一般是为了等待某个时间的发生(好比说某项资源就绪)以后再继续运行。sleep,suspend,wait等方法均可以致使线程阻塞。
  • 第5、死亡状态。若是一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,没法再使用start方法令其进入就绪

5七、post提交方式和get提交方式的区别

Get 方法经过 URL 请求来传递用户的数据,将表单内各字段名称与其内容,以成对的字符串链接,以URL字串自己传递数据参数,在服务器端能够从'QUERY_STRING'这个变量中直接读取,效率较高,但缺少安全性,也没法来处理复杂的数据(只能是字符串,好比在servlet/jsp中就没法处理发挥java的好比vector之类的功能,输的数据量很是小,通常限制在 2 KB 左右);

Post 方法经过 HTTP post 机制,将表单内各字段名称与其内容放置在 HTML 表头(header)内一块儿传送给服务器端交由 action 属性能所指的程序处理,该程序会经过标准输入(stdin)方式,将表单的数据读出并加以处理post方式:就传输方式讲参数会被打包在数据报中传输,从CONTENT_LENGTH这个环境变量中读取,便于传送较大一些的数据,同时由于不暴露数据在浏览器的地址栏中,安全性相对较高,但这样的处理效率会受到影响。

建议:除非你确定你提交的数据能够一次性提交,不然请尽可能用 Post方法;Get方式提交数据,会带来安全问题;经过 Get 方式提交数据时,用户名和密码将出如今 URL 上;因此表单提交建议使用Post。

5八、什么是数据库脏读,不可重复读,幻觉读
脏读又称无效数据读出。一个事务读取另一个事务尚未提交的数据叫脏读。
例如:事务T1修改了一行数据,可是尚未提交,这时候事务T2读取了被事务T1修改后的数据,以后事务T1由于某种缘由Rollback了,那么事务T2读取的数据就是脏的不可重复读是指在同一个事务内,两个相同的查询返回了不一样的结果。
例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便获得了不一样的结果。

幻觉读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的所有数据行,同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,之后就会发生操做第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉同样。例如:系统管理员A将数据库中全部学生的成绩从具体分数改成ABCDE等级,可是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉同样,这就叫幻读。

5九、请介绍spring的事务隔离级别

  • (1)Default默认的事务隔离级别
  • (2)READ_UNCOMMITTED(read_uncommitted)读未提交,一个事务能够操做另一个未提交的事务,不能避免脏读,不可重复读,幻觉读,隔离级别最低,并发性能最高
  • (3)READ_COMMITTED(read_committed)读已提交,一个事务不能够操做另一个未提交的事务, 能防止脏读,不能避免不可重复读,幻觉读。
  • (4)REPEATABLE_READ(repeatable_read)可以避免脏读,不可重复读,不能避免幻读
  • (5)SERIALIZABLE(serializable)隔离级别最高,消耗资源最低,代价最高,可以防止脏读, 不可重复读,幻觉读

60、默写选择排序

public static void selectSort(int[] a) {  
int minIndex = 0;  
int temp = 0;  
if ((a == null) || (a.length == 0))  
return;  
for (int i = 0; i < a.length - 1; i++) {  
minIndex = i;// 无序区的最小数据数组下标  
for (int j = i + 1; j < a.length; j++) {  
// 在无序区中找到最小数据并保存其数组下标  
if (a[j] < a[minIndex]) {  
minIndex = j;  
        }  
     }  
// 将最小元素放到本次循环的前端  
temp = a[i];  
a[i] = a[minIndex];  
a[minIndex] = temp;  
   }  
}

6一、session和cooie的区别
具体来讲cookie机制采用的是在客户端保持状态的方案,而session 机制采用的是在服务器端保持状态的方案。因为服务器端保持状态的方案在客户端也须要保存一个标识,因此session机制须要借助于cookie机制来达到保存标识的目的 。

6二、什么是Spring IOC 容器?
Spring IOC 负责建立对象,管理对象(经过依赖注入(DI),装配对象,配置对象,而且管理这些对象的整个生命周期。

6三、spring有哪些不一样类型的IOC(依赖注入)方式?
构造器依赖注入:构造器依赖注入经过容器触发一个类的构造器来实现的,该类有一系列参数,每一个参数表明一个对其余类的依赖。
Setter方法注入:Setter方法注入是容器经过调用无参构造器或无参static工厂 方法实例化bean以后,调用该bean的setter方法,即实现了基于setter的依赖注入

6四、 Spring支持哪几种bean的做用域?

  • singleton :bean在每一个Spring ioc 容器中只有一个实例。
  • prototype:一个bean的定义能够有多个实例。
  • request:每次http请求都会建立一个bean,该做用域仅在基于web的Spring ApplicationContext情形下有效。
  • session:在一个HTTP Session中,一个bean定义对应一个实例。该做用域仅在基于web的Spring ApplicationContext情形下有效。
  • global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该做用域仅在基于web的Spring ApplicationContext情形下有效。

6五、j2ee经常使用的设计模式有哪些,简单说一下工厂模式
Java中的23种设计模式:
Factory(工厂模式), Builder(建造模式), Factory Method(工厂方法模式),Prototype(原始模型模式),Singleton(单例模式), Facade(门面模式),Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式),Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式),Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式),Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式),Observer(观察者模式), State(状态模式), Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)

工厂模式:工厂模式是一种常常被使用到的模式,根据工厂模式实现的类能够根据提供的数据生成一组类中某一个类的实例,一般这一组类有一个公共的抽象父类而且实现了相同的方法,可是这些方法针对不一样的数据进行了不一样的操做。首先须要定义一个基类,该类的子类经过不一样的方法实现了基类中的方法。而后须要定义一个工厂类,工厂类能够根据条件生成不一样的子类实例。当获得子类的实例后,开发人员能够调用基类中的方法而没必要考虑到底返回的是哪个子类的实例

6六、谈谈你对数据库事务的理解?
在数据库中,所谓事务是指一组逻辑操做单元即一组sql语句。当这个单元中的一部分操做失败,整个事务回滚,只有所有正确才完成提交。判断事务是否配置成功的关键点在于出现异常时事务是否会回滚,在JDBC中,事务默认是自动提交的,每次执行一个SQL语句时,若是执行成功,就会向数据库自动提交,而不能回滚。
事务的特征(ACID属性):

  • 1.原子性(Atomicity)
    原子性是指事务是一个不可分割的工做单位,事务中的操做要么都发生,要么都不发生。
  • 2.一致性(Consistency)
    事务必须使数据库从一个一致性状态变换到另一个一致性状态。(数据不被破坏)
  • 3.隔离性(Isolation)
    事务的隔离性是指一个事务的执行不能被其余事务干扰.
  • 4.持久性(Durability)
    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的.即便系统重启也不会丢失.

6七、谈谈你对数据库索引的理解
一、索引的概念
索引就是为了提升数据的检索速度。数据库的索引相似于书籍的索引。在书籍中,索引容许用户没必要翻阅完整个书就能迅速地找到所须要的信息。在数据库中,索引也容许数据库程序迅速地找到表中的数据,而没必要扫描整个数据库.
二、索引的优势

a.建立惟一性索引,保证数据库表中每一行数据的惟一性
b.大大加快数据的检索速度,这也是建立索引的最主要的缘由
c.减小磁盘IO(向字典同样能够直接定位)

三、索引的缺点

a.建立索引和维护索引要耗费时间,这种时间随着数据量的增长而增长
b.索引须要占用额外的物理空间
c.当对表中的数据进行增长、删除和修改的时候,索引也要动态的维护,下降了数据的维护速度

6八、jdbc操做数据库的步骤
①、加载数据库驱动程序 Class.forName("数据库驱动类");
②、链接数据库 Connection con = DriverManager.getConnection();
③、操做数据库 PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();
④、关闭数据库,释放链接 con.close();

6九、介绍下乐观锁,悲观锁

  • 乐观锁(Optimistic Lock), 每次去查询数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,能够使用版本号,时间戳等机制。乐观锁适用于多读的应用类型,这样能够提升吞吐量
  • 悲观锁(Pessimistic Lock), 每次去查询数据的时候都认为别人会修改,因此每次在查询数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了这种锁机制,好比经过select ….for update进行数据锁定。

70、你对ajax是怎么理解的

  • AJAX全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是一种建立交互式网页应用的网页开发技术。
  • 使用ajax能够提升用户的体验度,进行异步数据传输从而提升性能。ajax不能跨域,所谓不能跨域就是不能跨多个网站(多个域名),或者多个项目。
  • 能够经过jsonp来解决ajax跨域的问题,而jsonp的实质就是经过动态添加script标签来实现的。

7一、你对负载均衡这块有认识吗?
负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它一般是指,将请求数据均匀分摊到多个操做单元上执行,负载均衡的关键在于“均匀”。常见互联网分布式架构上,分为客户端层、反向代理nginx层、站点层、服务层、数据层。
负载均衡有两方面的含义:

  • 一、大量的并发访问或数据流量分担到多台节点设备上分别处理,减小用户等待响应的时间;
  • 二、单个重负载的运算分担到多台节点设备上作并行处理,每一个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力获得大幅度提升。

7二、请说说你熟悉的Linux指令

ls 列出目录下的文件
cd 到某个目录里
cp 复制
mv 移动
rm 删除
pwd 查看当前位置
tar 解压tar.gz文件
mkdir 建立文件夹
touch 建立文件
vi 编辑(vim)
cat 查看
chmod 设置文件权限

7三、简单介绍项目的生命周期

  • 1.需求分析
  • 2.概要设计
  • 3.详细设计(用例图,流程图,类图)
  • 4.数据库设计(powerdesigner)
  • 5.代码开发(编写)
  • 6.单元测试(junit 白盒测试)(开发人员)
    svn版本管理工具(提交,更新代码,文档)
  • 7.集成测试 (黑盒测试,loadrunner(编写测试脚本)(高级测试))
  • 8.上线试运行 (用户本身检查)
  • 9.压力测试(loadrunner)
  • 10.正式上线
  • 11.维护

7四、说说你理解中的线程死锁
死锁是由于多线程访问共享资源,因为访问的顺序不当所形成的,一般是一个线程锁定了一个资源A,而又想去锁定资源B;在另外一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操做,两个线程都想获得对方的资源,而不肯释放本身的资源,形成两个线程都在等待,而没法执行的状况。
死锁产生的缘由:是由访问共享资源顺序不当所形成的
简单的说:所谓死锁,是指两个或两个以上的线程在执行过程当中,因争夺资源而形成的一种互相等待的现象,若无外力做用,它们都将没法推动下去。

7五、 介绍下守护线程
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)

  • (1)用个比较通俗的说法,任何一个守护线程都是整个JVM中全部非守护线程的保姆:只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就所有工做;只有当最后一个非守护线程结束时,守护线程才随着JVM一同结束工做。
  • (2)守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。
  • (3)守护线程与普通线程的惟一区别是:当JVM中全部的线程都是守护线程的时候,JVM就能够退出了;若是还有一个或以上的非守护线程则不会退出。(以上是针对正常退出,调用System.exit则一定会退出)

文章全部内容均收集于网络,若有错误或其它问题,欢迎小伙伴留言评论、指正。若有帮助,欢迎点赞+转发分享。

如下是Java面试要点集合汇总:

反模式设计
简单的来讲,反模式是指在对常常面对的问题常用的低效,不良,或者有待优化的设计模式/方法。甚至,反模式也能够是一种错误的开发思想/理念。在这里我举一个最简单的例子:在面向对象设计/编程中,有一条很重要的原则, 单一责任原则(Single responsibility principle)。其中心思想就是对于一个模块,或者一个类来讲,这个模块或者这个类应该只对系统/软件的一个功能负责,并且该责任应该被该类彻底封装起来。当开发人员须要修改系统的某个功能,这个模块/类是最主要的修改地方。相对应的一个反模式就是上帝类(God Class),一般来讲,这个类里面控制了不少其余的类,同时也依赖其余不少类。整个类不光负责本身的主要单一功能,并且还负责了其余不少功能,包括一些辅助功能。不少维护老程序的开发人员们可能都遇过这种类,一个类里有几千行的代码,有不少功能,可是责任不明确单一。单元测试程序也变复杂无比。维护/修改这个类的时间要远远超出其余类的时间。不少时候,造成这种状况并非开发人员故意的。不少状况下主要是因为随着系统的年限,需求的变化,项目的资源压力,项目组人员流动,系统结构的变化而致使某些原先小型的,符合单一原则类慢慢的变的臃肿起来。最后当这个类变成了维护的噩梦(特别是原先熟悉的开发人员离职后),重构该类就变成了一个不容易的工程。

分库与分表设计
垂直分表在平常开发和设计中比较常见,通俗的说法叫作“大表拆小表”,拆分是基于关系型数据库中的“列”(字段)进行的。一般状况,某个表中的字段比较多,能够新创建一张“扩展表”,将不常用或者长度较大的字段拆分出去放到“扩展表”中。在字段不少的状况下,拆分开确实更便于开发和维护(笔者曾见过某个遗留系统中,一个大表中包含100多列的)。某种意义上也能避免“跨页”的问题(MySQL、MSSQL底层都是经过“数据页”来存储的,“跨页”问题可能会形成额外的性能开销,拆分字段的操做建议在数据库设计阶段就作好。若是是在发展过程当中拆分,则须要改写之前的查询语句,会额外带来必定的成本和风险,建议谨慎。

垂直分库在“微服务”盛行的今天已经很是普及了。基本的思路就是按照业务模块来划分出不一样的数据库,而不是像早期同样将全部的数据表都放到同一个数据库中。系统层面的“服务化”拆分操做,可以解决业务系统层面的耦合和性能瓶颈,有利于系统的扩展维护。而数据库层面的拆分,道理也是相通的。与服务的“治理”和“降级”机制相似,咱们也能对不一样业务类型的数据进行“分级”管理、维护、监控、扩展等。

众所周知,数据库每每最容易成为应用系统的瓶颈,而数据库自己属于“有状态”的,相对于Web和应用服务器来说,是比较难实现“横向扩展”的。数据库的链接资源比较宝贵且单机处理能力也有限,在高并发场景下,垂直分库必定程度上可以突破IO、链接数及单机硬件资源的瓶颈,是大型分布式系统中优化数据库架构的重要手段。

而后,不少人并无从根本上搞清楚为何要拆分,也没有掌握拆分的原则和技巧,只是一味的模仿大厂的作法。致使拆分后遇到不少问题(例如:跨库join,分布式事务等)。

水平分表也称为横向分表,比较容易理解,就是将表中不一样的数据行按照必定规律分布到不一样的数据库表中(这些表保存在同一个数据库中),这样来下降单表数据量,优化查询性能。最多见的方式就是经过主键或者时间等字段进行Hash和取模后拆分。水平分表,可以下降单表的数据量,必定程度上能够缓解查询性能瓶颈。但本质上这些表还保存在同一个库中,因此库级别仍是会有IO瓶颈。因此,通常不建议采用这种作法。

水平分库分表与上面讲到的水平分表的思想相同,惟一不一样的就是将这些拆分出来的表保存在不一样的数据中。这也是不少大型互联网公司所选择的作法。某种意义上来说,有些系统中使用的“冷热数据分离”(将一些使用较少的历史数据迁移到其余的数据库中。而在业务功能上,一般默认只提供热点数据的查询),也是相似的实践。在高并发和海量数据的场景下,分库分表可以有效缓解单机和单库的性能瓶颈和压力,突破IO、链接数、硬件资源的瓶颈。固然,投入的硬件成本也会更高。同时,这也会带来一些复杂的技术问题和挑战(例如:跨分片的复杂查询,跨分片事务等)。

分布式困境与应对之策

  • 数据迁移与扩容问题
    前面介绍到水平分表策略概括总结为随机分表和连续分表两种状况。连续分表有可能存在数据热点的问题,有些表可能会被频繁地查询从而形成较大压力,热数据的表就成为了整个库的瓶颈,而有些表可能存的是历史数据,不多须要被查询到。连续分表的另一个好处在于比较容易,不须要考虑迁移旧的数据,只须要添加分表就能够自动扩容。随机分表的数据相对比较均匀,不容易出现热点和并发访问的瓶颈。可是,分表扩展须要迁移旧的数据。
    若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析、双十一实战或者是面试难题的朋友能够加582505643里面的群主感受蠢萌蠢萌的能够到她那骗资料,都是干货。
    针对于水平分表的设计相当重要,须要评估中短时间内业务的增加速度,对当前的数据量进行容量规划,综合成本因素,推算出大概须要多少分片。对于数据迁移的问题,通常作法是经过程序先读出数据,而后按照指定的分表策略再将数据写入到各个分表中。
  • 表关联问题
    在单库单表的状况下,联合查询是很是容易的。可是,随着分库与分表的演变,联合查询就遇到跨库关联和跨表关系问题。在设计之初就应该尽可能避免联合查询,能够经过程序中进行拼装,或者经过反范式化设计进行规避。
  • 分页与排序问题
    通常状况下,列表分页时须要按照指定字段进行排序。在单库单表的状况下,分页和排序也是很是容易的。可是,随着分库与分表的演变,也会遇到跨库排序和跨表排序问题。为了最终结果的准确性,须要在不一样的分表中将数据进行排序并返回,并将不一样分表返回的结果集进行汇总和再次排序,最后再返回给用户。
  • 分布式事务问题
    随着分库与分表的演变,必定会遇到分布式事务问题,那么如何保证数据的一致性就成为一个必须面对的问题。目前,分布式事务并无很好的解决方案,难以知足数据强一致性,通常状况下,使存储数据尽量达到用户一致,保证系统通过一段较短的时间的自我恢复和修正,数据最终达到一致。
  • 分布式全局惟一ID
    在单库单表的状况下,直接使用数据库自增特性来生成主键ID,这样确实比较简单。在分库分表的环境中,数据分布在不一样的分表上,不能再借助数据库自增加特性。须要使用全局惟一 ID,例如 UUID、GUID等。

MySQL 遇到的死锁问题

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已得到的资源保持不放。
(3) 不剥夺条件:进程已得到的资源,在末使用完以前,不能强行剥夺。
(4) 循环等待条件:若干进程之间造成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不知足,就不会发生死锁。下列方法有助于最大限度地下降死锁:
(1)按同一顺序访问对象。
(2)避免事务中的用户交互。
(3)保持事务简短并在一个批处理中。
(4)使用低隔离级别。
(5)使用绑定链接。

数据库索引的原理
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现一般使用B树及其变种B+树。

汇集索引与非汇集索引的区别

  • 1).汇集索引一个表只能有一个,而非汇集索引一个表能够存在多个
  • 2).汇集索引存储记录是物理上连续存在,而非汇集索引是逻辑上的连续,物理存储并不连续
  • 3).汇集索引:物理存储按照索引排序;汇集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序
    非汇集索引:物理存储不按照索引排序;非汇集索引则就是普通索引了,仅仅只是对数据列建立相应的索引,不影响整个表的物理存储顺序.
  • 4).索引是经过二叉树的数据结构来描述的,咱们能够这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。

Redis 持久化机制和如何实现
redis有两种持久化机制RDB与AOF。

  • RDB持久化方式会在一个特定的间隔保存那个时间点的一个数据快照。
  • AOF持久化方式则会记录每个服务器收到的写操做。在服务启动时,这些记录的操做会逐条执行从而重建出原来的数据。写操做命令记录的格式跟Redis协议一致,以追加的方式进行保存。
  • Redis的持久化是能够禁用的,就是说你可让数据的生命周期只存在于服务器的运行时间里。

两种方式的持久化是能够同时存在的,可是当Redis重启时,AOF文件会被优先用于重建数据。

缓存降级

  • 页面降级:在大促或者某些特殊状况下,某些页面占用了一些稀缺服务资源,在紧急状况下能够对其整个降级,以达到丢卒保帅;
  • 页面片断降级:好比商品详情页中的商家部分由于数据错误了,此时须要对其进行降级;
  • 页面异步请求降级:好比商品详情页上有推荐信息/配送至等异步加载的请求,若是这些信息响应慢或者后端服务有问题,能够进行降级;
  • 服务功能降级:好比渲染商品详情页时须要调用一些不过重要的服务:相关分类、热销榜等,而这些服务在异常状况下直接不获取,即降级便可;
  • 读降级:好比多级缓存模式,若是后端服务有问题,能够降级为只读缓存,这种方式适用于对读一致性要求不高的场景;若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析、双十一实战或者是面试难题的朋友能够加582505643里面的群主感受蠢萌蠢萌的能够到她那骗资料,都是干货。
  • 写降级:好比秒杀抢购,咱们能够只进行Cache的更新,而后异步同步扣减库存到DB,保证最终一致性便可,此时能够将DB降级为Cache。
  • 爬虫降级:在大促活动时,能够将爬虫流量导向静态页或者返回空数据,从而保护后端稀缺资源。
  • 自动开关降级
    自动降级是根据系统负载、资源使用状况、SLA等指标进行降级。
  • 超时降级
    当访问的数据库/http服务/远程调用响应慢或者长时间响应慢,且该服务不是核心服务的话能够在超时后自动降级;好比商品详情页上有推荐内容/评价,可是推荐内容/评价暂时不展现对用户购物流程不会产生很大的影响;对于这种服务是能够超时降级的。若是是调用别人的远程服务,和对方定义一个服务响应最大时间,若是超时了则自动降级。
Java Web学习路径

============

Java编程所需的工具及知识

==============

JVM的基本结构

========

SSH框架

=====

设计模式之间的关系

=========

JAVA知识结构体系图

JAVA知识学习计划图

学习须要知道:

一、是什么
二、解决了什么问题
三、怎么实现的

文章全部内容均收集于网络,若有错误或其它问题,欢迎小伙伴留言评论、指正。若有帮助,欢迎点赞+转发分享。

欢迎你们关注民工哥的公众号:民工哥技术之路
image.png

相关文章
相关标签/搜索