java面试题

Java

  1. 什么是面向对象(java基本思想是?)

面向对象编程思想是java的基本思想。java的整个体系和技术实现都是以这个思想为基础。

面向对象思想,是一种将现实世界抽象成代码的思想。即通过将现实世界中独立个体(事物)的属性和行为封装在一个类中,通过抽象和继承实现个体间的相互影响、协作。

简单来说就是把实际转换成代码,代码之间相互作用形成了代码间的相互协调,表现了实际中一个事物的多种形态。这种思想叫做面向对象的思想。

与面向过程相比利于复用但性能没面向过程高,因为面向过程是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候依次调用。

  1. 面向对象的三大特征

1、封装:将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。

封装的意义在于明确标识出允许外部使用的所有方法和属性,内部细节对外部调用不可见,即现实世界可以被描绘成一系列完全自治、封装的对象,外部调用无需修改或关心内部实现。

2、继承:继承是使用已存在的类的定义作为基础建立新类的技术,子类通过extends关键字继承父类,进而可以使用父类中的非private的属性和方法,也可以自己设置属性和方法,即子类可以对父类进行扩展。子类可以用重写的方式实现父类的方法。一个父类可以有多个子类,而一个子类只能有一个父类。通过使用继承我们能够非常方便地复用以前的代码。

3、多态性:多态性是指允许不同类的对象对同一消息作出响应。从编译运行的方面看就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定。在 Java 中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

3、基本数据类型和包装类型的区别

1、基本数据类型:

byte:字节型,1字节8位(bit),范围-128~127,默认0。

short:短整型,2字节16位,范围-32768~32717,默认值0

int:整型,java中整型数据的默认类型,4字节32位,范围-2147483648~2147483647,默认值0

long:长整型,8字节64位,-2^63~2^63-1,默认值0L,声明long型变量时,必须以“L”或小写"l"结尾

float:浮点型,4字节32位,有效小数点6~7位,默认值0.0

double:双精度浮点型,8字节64位,默认值0.0

char:字符型(1字符=2字节),用于存储单个字符,2字节16位,取值范围0~65535,默认值为空

boolean:布尔型,1字节,用于判断真或假(仅有两个值,即true、false),默认值false

2、引用数据类型

类(class)、接口(interface)、数组(array)

  1. 区别

1)、存储位置

基本变量类型:在方法中定义的基本数据类型变量存储在栈中,类中的基本数据类型的属性存放在堆中

引用变量类型:具体内容存放在堆中,而栈中存放的是其具体内容所在内存的地址

2)、传递方式

基本变量类型:在方法中定义的非全局基本数据类型变量,调用方法时作为参数是按数值传递的

引用变量类型:引用数据类型变量,调用方法时作为参数是按引用传递的,传递的是引用的副本

3)、由于包装类型可为空的特性,所以在不确定数据值的情况下最好采用包装类,比如对数据库的操作上

4、说出ArrayList,Vector, LinkedList的存储性能和特性

ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),同一时间下只能有一个线程访问,所以性能上较ArrayList较差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入快而索引块。

5、HashMap和Hashtable的区别。  

HashMap是Hashtable的非线程安全的轻量级实现,他们都完成了Map接口,由于非线程安全,效率上可能高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

HashMap把Hashtable的contains方法去掉了,改成containsKey和containsValue。Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。

6、Overload和Override的区别。Overload的方法是否可以改变返回值的类型?

Overload:重载:1方法名相同 2参数列表不同(参数个数,参数类型,参数顺序) 3与返回值无关

Override:重写: 1方法名相同 2参数列表也同   3一般发生在子类  4与返回值无关

方法的重载和重写是Java多态性的不同表现。重写是父类与子类一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在同一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载。重载的方法是可以改变返回值的类型

7、abstract和interface的概念

含有abstract修饰符的类即为抽象类,抽象类不能实例化。含有abstract方法的类必须定义为抽象类,抽象类中的方法可以是非抽象的。抽象类中定义的抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

8、abstract和interface有什么区别?

实现:抽象类的子类使用extends来继承;接口使用implements来实现接口。

构造函数:抽象类可以有构造函数;接口不能有。

main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。

实现数量:类可以实现很多个接口;但是只能继承一个抽象类。

访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

9、JDK、JVM、JRE三者的关系

JDK=JRE+开发工具集(例如java编译工具等),JRE=JVM+javaSE标准类库等

JDK是Java开发工具包,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库,是提供给开发人员使用的开发工具

JRE是Java的运行环境,包括JVM标准实现及Java核心类库,可以单独提供给用户在终端运行java程序,安装包下的jre中的bin包中就是jvm,lib是类库

JVM是java虚拟机,是整个java实现跨平台的最核心的部分,能够运行以Java语言编写的软件。

写好的java文件先经javac工具编译成class文件,然后java工具运行,class文件送入jvm中,不同系统下的jvm调用类库解释class为机器语言,然后映射到操作系统运行

10、return与finally的先后关系

正常情况下,如果return后面是表达式(return 表达式),则会在表达式执行完后,将值从局部变量区复制到操作数栈顶,然后执行return,返回操作数栈顶的值。

如果在有finally语句块的情况下,执行顺序是:

  1. 执行return后面的表达式,结果保存在操作数栈顶;
  2. 将操作数栈顶值复制到局部变量区作为返回值;
  3. 执行finally语句块中的代码;
  4. 将复制到局部变量区的返回值又复制回操作数栈顶;
  5. 执行return指令,返回操作数栈顶的值;

从执行顺序可以看出,无论finally语句块中执行了什么操作,都无法影响返回值。因为finally语句块设计出来的目的只是为了让方法执行一些重要的收尾工作,而不是用来计算返回值的,比如关闭流等。

但是如果在finally中使用return的话则是会返回将新的操作数栈顶数据,而不是之前复制到局部变量区的返回值。

11、==和equals比较

==对比的是栈中的值,因为基本数据类型的值是和变量一起存放在栈空间中,所以比较的是变量值引用类型存放在栈空间中的是其指向的对象在堆空间中的内存地址,所以比较的是堆中内存对象的地址

equals中默认也是采用==比较,通常会重写,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。

 

Instanceof:是 Java 中的一个双目运算符,是Java的关键字。可以使用 instanceof关键字判断一个对象是否为一个类(或接口、抽象类、父类)的实例。

12、简述final

final:最终的

它的作用是:

  1. 修饰类:表示类不可被继承
  2. 修饰方法:表示方法不可被子类重写(覆盖),但可以重载
  3. 修饰变量:表示变量一旦被赋值就不可更改它的值
  1. 、修饰属性(成员变量)
    • 如果final修饰的是类变量(静态属性),只能在静态初始化块中指定初始值或者在声明该类变量时指定初始值
    • 如果final修饰的是成员变量(非静态属性),
      1. 可以在声明该成员变量时指定初始值
      2. 可以在非静态初始化块中声明该变量
      3. 可以在构造器中执行初始值
  2. 、修饰临时变量(局部变量)
    • 可以在定义时指定默认值,也可以在后面的代码中赋值
  3. 、修饰基本数据类型和引用数据类型
    • 如果是基本数据类型的变量,则其数值一旦初始化之后不可更改
    • 如果是引用类型的话,则在对其初始化之后便不能再让其指向另一对象,但是其引用的对象中的值可以变,这是因为final修饰的是引用变量指向堆内存空间中的对象的地址值,它是连同引用变量本身一起存放在栈中

13、为什么内部类只能访问final变量

首先,内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着方法的执行完毕被销毁

这时,当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有没人再引用它时,才会死亡),这里就出现了一个矛盾,内部类对象访问了一个不存在的变量,为了解决这个问题,就将局部变量复制了一份作为内部类的的成员变量,这样当局部变量死亡后,内部类仍可以访问它,实际访问的是局部变量的副本,就好像延长了局部变量的生命周期

那么,为保证两个变量的一致性,就需要将局部变量设置为final,对它初始化后,值就不可更改。

14、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

short s1 = 1; s1 = s1 + 1;

s1+1运算结果是int型,需要强制转换类型,这样子才可以正确的编译

short s1 = 1; s1 += 1;(可以正确编译)

+=、-=、*=、/= 运算符拥有一个内置转换器,当左右两边都是整数时,会自动将等号右边 转为等号左边的类型

15、Math.round(11.5)等多少? Math.round(-11.5)等多少?  

Math.round(11.5)==12  

Math.round(-11.5)==-11

Math.round(-11.6)==-12 

round方法返回与参数最接近的长整数.

16、String s = new String("xyz");创建了几个String Object?   

两个或一个。

1个:如果执行此句之前,常量池里已经存在xyz,则只通过new产生一个对象;

2个:如果执行句之前,常量池中不存在xyz,则先根据"xyz"给常量池中产生一个“xyz”,之后再根据new 产生一个对”xyz”的引用

17、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

接口可以继承接口;

抽象类可以实现(implements)接口,且无需实现接口中的方法,但抽象类的子类必须实现接口中的方法;

抽象类可以继承实体类,但前提是实体类必须有明确的构造函数。

18、数组有没有length()这个方法? String有没有length()这个方法?

数组没有length()这个方法,有length的属性。String有length()这个方法;集合有size()方法

19、请说出你所知道的线程同步的方法

所谓线程同步,就是指使用同步锁来防止在多线程情况下,同时操作一个可共享的资源时可能会出现的线程安全问题

1.synchronized关键字

synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。使用synchronized关键字修饰

普通方法,锁是当前实例对象

静态方法,锁是当前类的class对象

同步块,锁是括号里面的对象

2.使用特殊域变量(volatile)实现线程同步

volatile关键字为域变量的访问提供了一种免锁机制,使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,因此每次使用该域就要重新计算,而不是使用寄存器中的值,它不能用来修饰final类型的变量

3.使用互斥锁ReetrantLock

ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法具有相同的基本行为和语义,并且扩展了其能力。调用lock() 方法,同步执行体执行完毕之后,需要用 unlock() 释放锁。

关于Lock对象和synchronized关键字的选择:

  1. 如果synchronized能满足需求,就用synchronized,因为它能简化代码
  2. 如果需要更高级的功能,就用ReentrantLock类,此时要注意及时释放锁,否则会出现死锁,通常在finally代码释放锁

4.使用ThreadLocal管理局部变量

如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本, 副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。

20、你所知道的集合类都有哪些?主要方法?

Collection

--List

--ArrayList,LinkedList,Vector

--Set

   --HashSet、TreeSet

Map

--HashMap,TreeMap 

Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素,它的实现类中最常用的集合类是List。List的具体实现包括ArrayList和Vector,它们都实现了可变大小的数组。它允许所有元素,包括null。适合构建、存储和操作任何类型对象的元素列表。List适用于按数值索引访问元素的情形。Map提供了一个以键值对存储元素的方法,一个键映射一个值。

集合中的通用方法

  1. void clear() 清空所有集合元素
  2. boolean contains(Object o) 判断指定集合是否包含对象o
  3. boolean isEmpty() 判断指定集合的元素size是否为0
  4. boolean remove() 删除集合中的某个元素
  5. int size() 集合的元素个数

①Collection中的方法:

  1. boolean add() 向集合添加元素e
  2. boolean addAll() 把集合b中的元素全部添加到集合a中

它的实现类ArrayList、LinkedList都拥有这些方法,除此之外,各个实现类还拥有一些自身特有的方法,比如ArrayList的set();方法//修改元素

② Map中的方法

a. put 向map集合中添加Key为key,Value为value的元素,当添加成功时返回  null,否则返回value。

b. putAll 向map集合中添加指定集合的所有元素

c. get 根据map集合中元素的Key来获取相应元素的Value

21、char型变量中能不能存贮一个中文汉字?为什么?

能够定义成为一个中文的,因为①java中以unicode编码,②一个char占16个位,所以放一个中文是没问题的

可能的解释为一个中文占16位,两个字节。

如果只存储英文/数字,则只需要8位即可;如果存储特殊字符或中文,需要16位。

22、java中的常用包

  1. java.lang包:该包提供了Java的基础类和核心类,比如Object、Math、String、StringBuffer等,它是默认导入的包。
  2. java.util包:该包提供了包含集合框架、集合类、事件模型、日期和时间
  3. java.io包:该包通过文件系统、数据流和序列化提供系统的输入与输出。
  4. java.net包:该包提供实现网络应用与开发的类。
  5. java.sql包:该包提供了使用Java语言访问并处理存储在数据源中的数据
  6. java.text包:提供了与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。

23、StringStringBuilder和StringBuffer的区别

String、StringBuilder和StringBuffer,它们都是可以储存和操作字符串,区别在于String类提供了线程安全的数值不可改变的字符串,原因是String是字符串常量,一旦被赋值则不可改变。比如String str=“a”;str=“b”,在执行str=“b”时,实际上是重新开辟了一个内存空间 并赋值为b

StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的(它的方法基本都采用了synchronized关键词),而 StringBuilder 是非线程安全的,但StringBuilder的性能却高于StringBuffer。

String:适用于少量的字符串操作的情况

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

24、运行时异常与一般异常有何异同?

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示的是虚拟机正常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

25、说出Servlet的生命周期

servlet生命周期的定义,包括加载和实例化、初始化、处理请求以及服务结束,这个生命周期由javax.servlet.servlet接口中的init、service、destroy方法表达。

web容器加载servlet实例化,生命周期开始,通过调用servlet的init()方法进行servlet的初始化。

默认情况下,init方法会在第一次请求时被调用,但也可以通过配置<load-on-startup>1</load-on-startup>,使得init在web服务器(tomtcat)启动时自动运行。

Servlet初始化后,请求到达时运行其service方法,service方法自动派遣与请求对应的doGet或doPost等方法处理请求,当服务器决定将实例销毁的时候调用其destroy方法。

26、final, finally, finalize的区别。 

final修饰的变量,不可再改变;

final修饰的方法,不能被子类覆写。

final修饰的类,不能被继承。

finally用于异常,表示无论是否发生异常 都会执行finally中的代码。而且一般情况,方法遇到return 就终止,但即使try或catch中有return 也仍然会执行finally中的代码。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用一次被回收对象的此方法,对象可以重写此方法,处理生前的最后事情,例如关闭文件等。finalize()只会在对象内存回收前被调用一次

27、&和&&的区别。

&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。

if(1>2 && 1/0==2){}

不会报错,因为 &&会根据“且的情况下:一假则加”,当发现 &&为false时,会自动忽略右边的判断。

if(1>2 & 1/0==2){}

会报错。无论 左边是true或false,都会继续判断后面的表达式

28、Collection 和 Collections的区别。

Collection是集合类的上级接口,继承他的接口主要有Set 和List.

Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

29、sleep() 和 wait() 有什么区别?

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

30、error和exception有什么区别?

error表示恢复不是不可能,但很困难的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

exception表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

31、heap(堆)和stack有什么区别。

栈:

类和方法中定义的属性和变量,对象引用变量都在栈中存放。

栈特点,先进后出,数据一执行完毕,变量会立即释放,节约内存空间。

栈内存中的数据,没有默认初始化值,需要手动设置。

优点:存取速度快,仅次于直接位于CPU中的寄存器。

缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

堆:

堆内存用来存放new出来的对象和数组。

堆内存中所有的实体都有内存地址值,数据都有默认初始化值。

堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除

优点:可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。

缺点:由于要在运行时动态分配内存,存取速度较慢。

32、forward 和redirect的区别?

forward请求转发,一次请求一次响应。

redirect重定向,两次请求一次响应。

forward的页面跳转发生在服务器端,地址栏不变,redirect的页面跳转发生在客户端地址栏改变

forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。

redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。

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

GC是垃圾收集的意思(Gabage Collection),也就是垃圾自动回收机制。主要是用来清理数据,节约内存空间。

因为内存处理是开发人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java中使用GC来监视程序的运行,当对象不再使用时,就自动释放对象所使用的内存,Java语言没有提供释放已分配内存的显示操作方法,都是由GC自动运行的,GC的执行时间是不确定的。

一般情况下,无须显示地请求GC。也可以调用System类中的静态gc()方法运行GC,但这样并不能保证会立即回收指定对象。

在GC收集一个对象前,一般要求程序调用适当的方法释放资源,但在没有明确释放资源的情况下,Java提供了默认机制终止化该对象来释放资源,这个方法就是finalize()

34、启动一个线程是用run()还是start()

启动线程要用start()方法。调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于就绪状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。

调用start,是为了实现多线程的优点

1.start()方法来启动线程。无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;

2.run()方法当作普通方法的方式调用。程序还是要顺序执行,其程序执行路径还是只有一条, 这样就没有达到多线程的目的。 

35、应用服务器有那些?

BEA WebLogic Server,IBM WebSphere Application Server,Oracle11g/12c, Application Server,jBoss,Tomcat, jetty

36、给我一个你最常见到的异常

1. java.lang.nullpointerexception

"空指针",调用了未经初始化的对象,比如调用数组时,数组元素未初始化。

2. java.lang.classnotfoundexception

"指定的类不存在",遇到的场景:

1)、调用class的forName方法时,找不到指定的类

2)、类加载器中的查找系统类方法时,找不到指定的类

3)、类加载器中的 loadClass() 方法时,找不到指定的类

3. java.lang.arithmeticexception

"数学运算异常",比如程序中出现了除以零这样的运算就会出这样的异常,对这种异常,检查一下程序中涉及到数学运算的地方,公式是不是有不妥了。

4. java.lang.arrayindexoutofboundsexception

"数组下标越界",调用的下标超出了数组的范围。

37、对数据连接池的理解?工作机制?

J2EE服务器启动时建立足够的数据库连接,并将这些连接组成一个连接池,并一直维持不少于此数目的池连接。

创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。

客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。

当使用的池连接调用完成后,池驱动程序会将其标记为闲,供其他调用使用。

38、String类是否可以被继承?

String类是final类故不可以继承。

39、swtich是否能作用在long上,是否能作用在String上?

switch的条件是一个整数表达式。因此传递给switch case语句的参数应该是 int、 short、 char 、byte,String(1.7之后支持),枚举。因为long型长时间强转为int型有可能会丢失精度,所以不支持。

Switch case default执行顺序:

判断switch后面的表达式和case的表达式是否匹配,匹配后执行该case后面的所有语句,包括后面的case语句,直到遇到break跳出分支语句;

若没有break,会执行完case后面的所有语句结束,包括default语句(无论它在哪);

若没有匹配的case语句,则执行default语句后面的所有语句,包括后面的case。

40、编程题: 用最有效率的方法算出2乘以8等於几?  

2 << 3

2<<3移位,也可在JAVA正确的运行

41、两个对象值相同,但却可有不同的hash code,这句话对不对?

不对,有相同的hash code。

如果两个值相等,那么equals()方法相等,表示两个方法的对象相等,这表示,引用的对象的地址相等,这样就有相同的hashcode。

hashCode方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就能一下子定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。这样一来实际调用equals的次数就大大降低了,几乎只需要一两次。

42当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

值传递:

方法调用时,实参把它的值传递给对应的形参,方法接收的是原始值的数据,此时内存中存在两个相等的基本类型,即实参和形参,后面方法中的操作都是对形参这个值的修改,不影响实参的值。

引用传递:

也称为传地址。方法调用时,实参的引用(地址,而不是参数的值)被传递给方法中相对应的形参,方法接收的是原始值的内存地址;

在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。

是引用传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

43、Java中的异常处理机制的简单原理和应用。

当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况 一种是JAVA类库内置的语义检查。例如数组下标越界,访问null的对象时会引发空指针异常。另一种情况就是程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Throwable的子类。

异常(如ArithmeticException) àRuntimeExceptionàExceptionàThrowable

44、垃圾回收的优点和原理。并考虑2种回收机制

垃圾回收机制是Java的一个显著特点,它使其他语言最头疼的内存管理的问题迎刃而解,让我们在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。

垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。

垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。

回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收

45、多线程有几种实现方法,都是什么?

1、多线程有4种实现方法

  1. 继承Thread类,重写run方法
  2. 实现Runnable接口
    1. 业务类实现Runnable接口,重写run方法,业务类的实例对象作为Thread构造函数的target(属性),通过调用Thread的start()方法启动线程

//2、通过Runnable接口实现线程
RunnableTest runnableTest = new RunnableTest();
Thread thread = new Thread(runnableTest);

  1. 通过Callable接口和FutureTask类创建线程
    1. 创建Callable接口的实现类,并实现Call方法
    2. 创建Callable实现类的实例,使用FutureTask类包装Callable实例,该FutureTask对象封装了Callable对象的Call方法的返回值
    3. 使用FutureTask对象作为Thread对象的target创建并启动线程
    4. 调用FutureTask对象的get()来获取子线程执行结束的返回值

46、线程和进程的关系,线程的状态以及状态间的关系

线程是进程的基本执行单元,一个进程的所有任务都在线程中执行。

同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是独立的。

一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个程序至少都有一个线程,即main方法执行的那个线程。同一进程中的多个线程可并发执行。

状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的编程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况下可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。

47、web容器指的是什么

web容器:

指的是严格遵守J2EE规范的WEB application标准的WEB服务器称为WEB容器。作用是给处于其中的应用程序组件(JSP,servlet)提供一个环境,使JSP,servlet直接跟容器中的环境变量接口交互,不必关注其它系统问题。

48、JAVA语言如何进行异常处理,关键字:throw,throws,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口

在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。

Java的异常处理是通过5个关键词来实现的:throw,throws,try,catch,finally用try来指定一块预防所有“异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定想要捕捉的“异常”类型。

throw语句用来明确地抛出一个“异常”。throws用来标明一个方法可能抛出的各种“异常”

Finally为确保一段代码不管发生什么“异常”都会执行。

try块中可以抛出异常,但try本身就是检测异常并抛出的,一般情况下不需要,特殊情况下,比如在创建读取流的时候,文件不存在,可以在try块中再加一个try-catch-finally块,但这个是在try嵌套,还是用了try的自动检测异常、抛出异常。

49、排序都有哪几种方法?

1、冒泡排序

2、选择排序

3、插入排序

4、快速排序

快速排序:使用快速排序方法对数组排序,从数组中选择一个元素作为支点,把余下的元素分割为两段,使得左边中的元素都小于等于支点,而右边中的元素都大于等于支点,递归地使用快速排序方法对左边进行排序,递归地使用快速排序方法对右边进行排序,所得结果为左边+支点+右边。

50、java中有几种类型的流?对应抽象类?

从数据来源角度讲,分为:节点流、处理流

    1. 节点流中常用类
      • 字节输入流:FileInputStream
      • 字节输出流:FileOutputStream
      • 字符输入流:FileReader
      • 字符输出流:FileWriter
    2. 处理流中常用类
      • 缓冲字节输出流:BufferedOutputStream
      • 缓冲字节输入流:BufferedInputStream
      • 缓冲字符输入流:BufferedReader
      • 缓冲字符输出流:BufferedWriter
      • 数据输出流:DataOutputStream
      • 数据输入流:DataInputStream

51、什么是java序列化,如何实现java序列化?

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。

序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

52、break 和continue的区别

break:跳出循环,不再执行剩余部分。

continue:停止当次循环,进入下一次循环操作。continue之后的语句将不在执行。

53、StringBuffer常用方法

StringBuffer strbf = new StringBuffer("exception"); //创建一个StringBuffer类的字符串

strbf.append(String s);//追加字符串。

strbf.reverse(); //反转字符串。

strbf.delete(int start, int end); //移除指定区间的字符串,左含有不含。

strbf.insert(int offset, int i); //将int型的参数插入指定下标字符串前。

strbf.replace(int start, int end, String str); //替换指定下标区间的字符串。

54、readyState的五种状态详解

(0)未初始化

此阶段确认XMLHttpRequest对象是否创建,值为0表示对象已经存在。

(1)载入

此阶段调用open()方法,根据参数(method,url,true)完成对象状态的设置。值为1表示正在向服务端发送请求。

(2)载入完成

已接收完服务端的原始数据。并为下一阶段对数据解析作好准备。

(3)交互

此阶段解析接收到的服务端响应数据。状态3表示正在解析数据。

(4)完成

数据解析完毕,可以通过XMLHttpRequest对象的相应属性(responseText)取得数据。

55、form表单中的enctype

enctype就是编码类型的意思。

multipart/form-data是指表单数据有多部分构成,既有文本数据,又有文件等二进制数据的意思。

默认情况下,enctype的值是application/x-www-form-urlencoded,不能用于文件上传,只有使用了multipart/form-data,才能完整的传递文件数据。

application/x-www-form-urlencoded不是不能上传文件,是只能上传文本格式的文件,multipart/form-data是将文件以二进制的形式上传,这样可以实现多种类型的文件上传。

56、java中<<、>>、>>>

<<表示左移,不分正负数,低位补0; 

>>表示右移,如果该数为正,则高位补0,若为负数,则高位补1;

>>>表示无符号右移,也叫逻辑右移,即无论正否,高位补0

57、jsp九大内置对象

    1. pageContext:4大作用域对象之一,存放当前页面能够访问的数据
    2. request:4大作用域对象之一,存放当前来自客户端的请求数据
    3. session:4大作用域对象之一,存放同一个浏览器的多个页面之间,共享的数据
    4. application:4大作用域对象之一,存放同一个网站,不同浏览器之间,共享数据
    5. response:封装了响应数据、操作的对象
    6. out:输出流,通过它可以把内容返回给客户端(浏览器)
    7. config:代表配置对象
    8. page:代表当前页面
    9. exception:异常处理对象

58、基本类和字符串的转换

1、基本类型转换为字符串有三种方法:

使用包装类的 toString() 方法

使用String类的 valueOf() 方法

用一个空字符串加上基本类型,得到的就是基本类型数据对应的字符串

2、将字符串转换成基本类型有两种方法:

调用包装类的 parseXxx 静态方法。

调用包装类的 valueOf() 方法转换为基本类型的包装类,会自动拆箱。

59、MySql、Oracle和Redis

一、Oracle与Mysql

1、相同点:都是关系型数据库

2、不同点:oracle是重量级型数据库,收费,支持大并发,大访问量,闭源

mysql是轻量型数据库,免费,没有服务恢复数据 开源

具体区别:

1.单引号的处理】

mysql可以用双引号包起字符串,oracle只能用单引号包起字符串

2.自动增长的数据类型处理】

mysql是一个提供自增,oracle不支持自增

3.sql语句的扩展和灵活性】(分页,主键的自增,单引号)

mysql对sql语句有很多非常实用方便的扩展,比如limit inset可以一次插入多行数据,select某些管理数据可以不加from。oracle在这一方面比较严格

4.事务提交的方式】

oracle需要用户手动提交,支持事务

mysql默认自定提交,不支持事务

5.内存】

oracle占用内存空间大mysql占有小。

二、Redis:(非关系型数据库)

是一个基于内存高性能的key-value数据库

数据类型:string字符串,hash哈希,list列表。zset有序集合,set集合

优点: 速度快,因为数据存在内存,支持丰富的数据类型,支持事务,操作都是原子性

丰富的特性:可用于缓存,消息,持久化

60、Java中访问修饰符public、private、protect、default范围

 

61、wait,sleep,notify,notifyAll的作用

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。

sleep():使一个正在运行的线程处于睡眠状态,让出执行机会给其他线程,但对象锁并没有释放,休眠时间一到,线程进入就绪状态

notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

62、List、Set、Map三者区别

 

63、jsp 和 servlet 有什么区别?

jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)

jsp更擅长表现于页面显示,servlet更擅长于逻辑控制。

Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到。

Jsp是Servlet的一种简化,使用Jsp只需要完成我们需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。

Spring/SpringMVC

1、什么是Spring?

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的为Java应用程序提供基础性服务的容器框架目的是简化企业应用程序的开发,使开发者只需要关心业务需求。Spring框架已集成了20多个部分。这些部分被分为:IOC、AOP、数据访问/集成,(数据库、事务管理)、Web、测试模块。

2、为什么要使用Spring?

1、Spring属于低侵入式设计,代码污染极低;

2、Spring的IOC机制将对象间的依赖关系交由框架处理,降低了组件耦合性;

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

4、方便程序的测试和集成各种优秀框架。

3、解释一下什么是IOC?

IOC即控制反转。

软件系统在没有引入IOC容器之前,对象A依赖于对象B,那么对象A在需要对象B的时候,必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用已创建的实例,控制权都在自己手上。

在引入IOC容器之后,两个对象之间失去了直接联系,当对象A需要对象B的时候,IOC容器会主动创建一个对象B注入到对象A需要的地方。

也就是说对象A获得依赖对象B的过程,由主动变为了被动,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

简单来说就是将IOC作为“第三方”,全部对象的控制权上缴给“第三方”IOC容器使其成为整个系统的关键核心,使其他对象没有了耦合关系,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用。

  1. IOC和DI的关系

IOC即控制反转,DI是依赖注入;IOC是目的,而为了达到这个目的需要DI这个技术手段

5、什么是 aop?

AOP即面向切面编程,也称面向方面,它利用一种称为“横切”的技术,剖开封装的对象内部,将那些影响了多个类的与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,减少系统代码,降低模块耦合度,并有利于未来的可操作性和可维护性。

6、Spring常用的注入方式有哪些?

构造方法注入

setter注入

基于注解的注入

7、Spring中bean的作用域

1、singleton:默认作用域,采用单例模式,每个容器中只有一个bean实例。

2、prototype:原型模式,会为每个bean请求创建一个bean实例。

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

4、session:与request范围类似,同一个session会话共享一个实例,不同会话使用不同的实例。

5、global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会话共享存储变量的话,那么这个存储变量就需要存储在global-session中。

8、Spring中的bean是线程安全的吗?

Spring中的Bean默认是单例模式的,再加上大部分时间Bean是无状态的,因此在某种程度上来说Bean其实是安全的;当Bean进入状态时,可以通过改变bean的作用域 把"singleton"改为“prototype”这样每次请求Bean就相当于是new Bean()这样也可以保证线程安全。

有状态就是有数据存储功能;无状态就是不会保存数据

9、Bean Factory和Application Context有什么区别?

Bean Factory是个Bean工厂,使用简单工厂模式,是Spring IOC容器顶级接口,可以理解为含有Bean集合的工厂类,作用是管理Bean,包括实例化、定位、配置对象及建立对象间的依赖。Bean Factory实例化后并不会立即自动实例化配置的Bean,只有当Bean被调用时才会实例化、装配依赖关系,属于延迟加载,适合非单例模式。

Application Context是Bean Factory的子接口,它扩展了Bean Factory的功能,包括对国际化的支持,统一的文件资源读取方式,事件传播及应用层的特别配置等。容器会在初始化时对配置的Bean进行预实例化,Bean的依赖注入在容器初始化时就已经完成,属于立即加载,适合单例模式,推荐使用。

10、Spring自动装配Bean有哪些方式?

1、基于XML配置文件配置,bean所需的依赖项和服务在XML格式的配置文件中指定。它们通常以bean标签开头。

2、基于注解配置,可以通过在相关的类属性前使用注解@Autowired、@Resource配置bean。Spring容器默认不开启注解装配。需要时在Spring配置文件中启用它。标签为:<context:component-scan/>

3、基于Java API配置,通过使用@Bean和@Configuration来实现。@Bean添加在方法前,当方法所在类被扫描时,底层会主动调该方法,该方法的返回值会作为上下文中的一个bean(默认单例)被其他类Autowired进去,@Configuration添加在类前。

11、@Autowired和@Resource的区别

@Autowired默认是按照类型装配注入的,可以结合@Qualifier,按照名称来装配。

@Resource默认是按照名称来装配注入的,如果找不到会按照类型来装配注入。

12、Spring事务实现原理

Spring事务的本质就是数据库对事务的支持,没有数据库的事务支持,Spring是无法提供事务功能的。Spring只提供了统一的事务管理接口,具体实现都是由各数据库自行完成,数据库事务的提交和回滚是通过redo log和undo log实现的。Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。

13、Spring事务实现方式?

Spring支持编程式事务管理和声明式事务管理两种方式:

1、编程式事务管理使用TransactionTemplate。优点是可以作用到代码块级别;缺点是需要在业务逻辑代码中掺杂事务管理的代码。

2、声明式事务管理建立在AOP技术之上。本质是通过AOP功能,在目标方法开始之前启动一个事务,在方法执行完之后根据执行情况提交或者回滚事务。只需在配置文件中做相关的事务规则声明或通过@Transactional注解即可,优点是减少业务代码的污染;缺点是只能作用到方法级别。

14、Spring的事务隔离级别

事务隔离级别指的是一个事务对数据的修改与另一个并行的事务的隔离程度:

1、isolation_default:默认隔离级别,使用数据库默认的事务隔离级别。

2、isolation_read_uncommitted:读未提交,允许事务在执行过程中,读取其他事务未提交的数据。

3、isolation_read_committed:读已提交,允许事务在执行过程中,读取其他事务已经提交的数据。

4、isolation_repeatable_read:可重复读,在同一个事务内,任意时刻的查询结果都是一致的。

5、isolation_serializable:所有事务逐个依次执行。

15、当多个事务同时访问相同数据时,如果没有采取必要的隔离机制,可能发生什么问题?

1、脏读:一个事务读到另一个事务未提交的更新数据。

2、幻读:例如第一个事务对表中的“全部数据行”进行了修改,第二个事务向表中插入了“一行新数据”。就会导致第一个事务的用户发现表中还存在未修改的数据行,就好象发生了幻觉一样。

3、不可重复读:例如在一个事务内对同一条select语句执行了两次,除此之外无任何操作,但先后得到的结果却不一致,这就是不可重复读。

16、什么是Spring MVC?

Spring MVC是一个基于MVC架构的用来简化web应用程序开发的spring的子框架。

17、MVC架构

MVC是Model-View-Controller的简写。

View:视图层,为用户提供使用界面,与用户进行直接交互。

Model:模型层,分为两部分,一是承载业务数据的数据库映射结果集Bean层:二是处理用户请求的服务层Service和持久层Dao。

Controller:控制器,用于将用户请求转发给相应的 Model 进行处理,并根据Model的计算结果向用户提供相应响应。Controller默认是单例的,在@Controller之后增加@Scope("prototype")就可以改为多例模式。

通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。

18、Spring MVC 的优点?

  1. Spring MVC是Spring的子框架,它拥有Spring的优点;
  2. 支持灵活的URL到页面控制器的映射;
  3. 支持与其他视图技术(JSP、Free Marker等)进行整合;
  4. 拥有十分简洁的异常处理机制;
  5. 可以方便地进行数据验证、格式化,使用任意对象进行数据绑定操作;
  6. 支持RestFul风格。

19、Spring MVC 有哪些组件?

  1. Dispatcher Servlet:中央控制器,把请求给转发到具体的控制类
  2. Controller:处理具体请求的控制器
  3. Handler Mapping:映射处理器,负责映射中央处理器转发给Controller时的映射策略
  4. Model And View:服务层返回的数据和视图层的封装类
  5. View Resolver:视图解析器,解析具体的视图

20、Spring MVC的运行流程?

  1. 用户发送请求至中央控制器Dispatcher Servlet;
  2. Dispatcher Servlet收到请求后,调用映射处理器Handler Mapping,请求获取处理器Handle;
  3. 映射处理器根据请求的url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给中央控制器Dispatcher Servlet;
  4. Dispatcher Servlet通过处理器适配器Handler Adapte调用处理器Handle;
  5. 执行处理器Handler(也就是后端控制器,需要程序员做处理);
  6. 处理器适配器HandlerAdapter将执行完成返回的ModelAndView返回给Dispatcher Servlet;
  7. Dispatcher Servlet将ModelAndView传给视图解析器View Resolver进行解析;
  8. View Reslover解析后返回具体View;
  9. Dispatcher Servlet对View进行渲染视图(即将模型数据填充至视图中)之后响应用户。

21、Spring MVC怎样设重定向和转发?

在返回值前面加"forward:"就可以让结果转发;在返回值前面加"redirect:"就可以让返回值重定向;当方法的返回值为字符串时,默认就是转发。

22、Spring MVC的常用注解由有哪些?

  1. @Controller:标识此类实例是控制器
  2. @Service:标识此类实例是service实现类
  3. @Repository:标识此类实例是dao实现类
  4. @Component:标识此类实例是普通类
  5. @RequestMapping:映射请求地址和方法之间的关联
  6. @ResponseBody:注解返回数据而不是返回页面
  7. @PathVariable:获取URL路径中的变量值
  8. @RequestParam:获取前端传入的参数
  9. @ModelAttribute:把前端参数,放入到同名属性对应的类中,并自动创建出一个bean对象,且默认放入request中。

23、如何使用Spring MVC实现异常处理?

在Spring MVC中,异常处理的思路是系统的Dao、Service、Controller出现异常时都通过throws Exception向上抛出,最后由Spring MVC的异常处理器来处理。Spring MVC有以下3种方式处理异常:

  1. SimpleMappingExceptionResolver:使用它来处理全局异常;它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。
  2. 实现Spring的异常处理接口HandlerExceptionResolver,自定义自己的异常处理器处理全局异常;它仅有一个接口方法resolveException(),发生异常时,Spring MVC会调用该方法,并转到ModelAndView对应的视图中,向用户反馈一个异常报告页面。
  3. 使用@ControllerAdvice+@ExceptionHandler:加在处理异常的方法上来处理全局异常;该方式需要开启注解支持,标签为:<context:component-scan/>。

24、Spring MVC怎么和Ajax相互调用?

通过fastjson就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下:

  1. 导入fastjson.jar
  2. 将返回值用fastjson提供的JSONObject对象包裹

3、将JSONObject对象实例的toJSONString方法的返回值作为响应返回给前端,方法前要加上@ResponseBody注解。

25、如何解决get和post乱码问题?

解决post请求乱码:在web.xml里边配置一个CharacterEncodingFilter过滤器并设置编码为 utf-8即可。

解决get请求乱码:修改tomcat配置文件添加编码与工程编码一致;对参数进行重新编码

26、Spring MVC用什么对象从后台向前台传递数据的?

1、使用Map、Model 和 ModelMap 的方式,这种方式存储的数据是在request域中

2、使用request的方式

3、使用ModelAndView

27、怎么样把ModelMap里面的数据放入session里面?

在类上添加@SessionAttributes注解将指定的Model数据存储到session中。@SessionAttributes只能定义在类、接口、枚举上。@SessionAttributes参数:

names:字符串数组。里面是需要存储到session中的数据名称。

types:根据指定参数的类型,将模型中对应类型的参数存储到session中。

value:和names一样。

28、拦截器与过滤器的区别?

拦截器:在Spring MVC中依赖于Spring MVC框架,因此可以使用Spring的依赖注入(DI)进行一些业务操作。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,同时一个拦截器实例在一个controller生命周期之内可以多次调用。拦截器可以对静态资源的请求进行拦截处理。

过滤器:它依赖于servlet容器。它可以对几乎所有请求进行过滤,但缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,或者在过滤器中修改字符编码,过滤低俗文字、危险字符等。

29、动态代理的两种方式和区别?

JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码来生成来代理类。

区别:JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。

30、 什么是XSS攻击,如何避免?

XSS攻击全称跨站脚本攻击,其原理是攻击者向有XSS漏洞的网站中输入恶意的HTML代码,当用户浏览该网站时,这段HTML代码会自动执行,从而达到攻击的目的。XSS攻击类似于SQL注入攻击,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户信息。XSS是Web程序中常见的漏洞,XSS属于被动式且用于客户端的攻击方式。

XSS防范的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码。

31、什么是CSRF攻击,如何避免?

CSRF全称跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。

如何避免:

1、验证 HTTP Referer 字段

HTTP头中的Referer字段记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,而如果黑客要对其实施 CSRF攻击,一般只能在他自己的网站构造请求。因此,可以通过验证Referer值来防御CSRF 攻击。

2、使用验证码

关键操作页面加上验证码。但这种方法对用户不太友好。

3、在请求地址中添加token并验证

4、在HTTP 头中自定义属性并验证

Mybatis

1、什么是Mybatis

Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

2、Mybaits的优点?

1、基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

2、MyBatis 使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持,减少了JDBC大量冗余的代码;

3、能够与Spring很好的集成;

3、MyBatis框架的缺点?

1、SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

2、SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

4、MyBatis框架适用场合

1、MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。

2、对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。

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

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

6、当结果集属性名和表字段名不一样,怎么办?

第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

第2种: 映射字段名和实体类属性名的一一对应的关系。

7、 模糊查询like语句该怎么写?

第1种:在Java代码中添加sql通配符。

第2种:在sql语句中拼接通配符,会引起sql注入

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

Dao接口,也即Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦 截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。

9、Mybatis是如何进行分页的?分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,添加对应的物理分页语句和物理分页参数。

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

第一种是使用标签,逐一定义列名和对象属性名之间的映射关系。

第二 种是使用sql列的别名功能,将列别名书写为对象属性名,Mybatis会忽略列名大小写,智能找到与之对应对象属性名。有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

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

insert方法总是返回一个int的插入的行数值。如果采用自增长策略,自动生成的键值在insert方法执行完后可以被设置到传入的参数对象中。在insert标签中有一个usegeneratedkeys属性,将其设置为true,键值就会赋值到对象的对应属性中。

  1. 在mapper中如何传递多个参数?

如果传递的是自定义的类属性值,可以将sql语句的参数类型定义为类的全限名,然后将参数封装到类中,而后将类的实例传给sql语句。

如果传递的是基本类型或字符串之类的属性,可以将其封装到集合中,然后将sql语句的参数类型定义为集合,而后将集合传给sql语句。

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

Mybatis动态sq可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根 据表达式的值完成逻辑判断并动态拼接sql的功能。

Mybatis提供了9种动态sql标签 :trim | where | set | foreach | if | choose| when | otherwise | bind。

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

全自动ORM映射工具,查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具

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

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

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

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

17、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

它的原理就是先创建目标对象的代理对象,当调用目标方法属性时,进入拦截器方法invoke(),若目标方法属性是null 值,那么就会单独发送事先保存好的查询关联对象的sql,然后把结果放入目标方法属性内,于是目标方法属性就有值了,接着完成目标方法属性的调用。这就是延迟加载的基本原理。

18、Mybatis的一级、二级缓存

一级缓存:基于HashMap本地缓存,其存储作用域为Session,默认打开

二级缓存与一级缓存其机制相同,默认也是采用HashMap存储,不同在于其存储作用域为Mapper,并且可自定义存储源。默认不打开,要开启二级缓存并使用其属性类需要实现Serializable序列化接口(可用来保存对象的状态)

19、什么是MyBatis的接口绑定?有哪些实现方式?

接口绑定,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调用接口方法就可以。

接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select、@Update等注解,里面包含Sql语句来绑定;另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml 映射文件里面的namespace必须为接口的全路径名,一般用xml绑定的比较多。

20、使用MyBatis的mapper接口调用时有哪些要求?

1、Mapper接口方法名和mapper.xml中定义的每个sql的id相同;

2、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同;

3、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;

4、Mapper.xml文件中的namespace即是mapper接口的类路径。

21、简述Mybatis的插件运行原理,以及如何编写一个插件?

Mybatis仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法invoke()方法,当然,只会拦截那些指定需要拦截的方法。

编写插件:实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法,最后在配置文件中配置编写的插件。

22、MyBatis编程步骤是什么样的?

1、 创建SqlSessionFactory,加载MyBatis配置文件MyBatis-config.xml

2、 通过SqlSessionFactory创建SqlSession

3、 通过sqlsession执行数据库操作

4、 调用session.commit()提交事务

5、 调用session.close()关闭会话

23、MyBatis批量操作

可以使用foreach循环迭代List集合的形式批量操作;迭代是的要插入或查询的数据,而不是sql语句。

SpringBoot

1、什么是Spring Boot?

随着新功能的增加,Spring变得越来越复杂。如果要启动一个新的Spring项目,我们必须添加Maven依赖关系,配置应用程序服务器,添加Spring配置,非常繁琐。

Spring Boot就是为了解决这个问题。Spring Boot建立在现有Spring框架之上。使用Spring启动,避免了之前需要做的很多配置。因此,Spring Boot可以最少的工作量, 更加健壮地使用现有的Spring功能。

2、为什么要用Spring Boot?Spring Boot的优点是?

一、独立运行

Spring Boot内嵌了各种Servlet容器,Tomcat等,只需打成一个可执行的jar包就能独立运行,所有的依赖包都在一个jar包内。

二、简化配置

spring-boot-starter-web启动器自动依赖其他组件,简少了maven的配置。

三、自动配置

Spring Boot能根据当前类路径下的类、jar包来自动配置bean。

四、无代码生成和XML配置

Spring Boot配置过程中无代码生成,也无需XML配置文件就能完成所有配置工作。

3、Spring Boot的注解有那些?

一是启动类上面的核心注解:

@SpringBootApplication、@MapperScan("***"),设置dao层自动实现类的包扫描范围

其它注解包括:

@RestController,代替SSM中的@Controller,表明当前类是控制器类;同时表明当前类中每一个方法的返回值都是JSON格式的响应正文,就不用在每个方法前加@ResponseBody了

@Resource,表明这个属性是来自于Spring上下文中的一个Bean,它会帮我们set进来

Bean层结果集校验日期的类属性上的注解@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

测试用的@RunWith(SpringRunner.class)、@SpringBootTest

在加载lombok的jar且安装lombok插件后,在结果集前写入@Data注解,就无需写出get、set方法,如需输出日志,可以在类前添加@Slf4j注解

还有加载配置信息类的@Configuration

4、Spring Boot的核心注解是哪些?他主由哪几个注解组成的?

SpringBoot的核心注解是启动类上面的@SpringBootApplication,主要包含以下3个注解:

@SpringBootConfiguration:组合了@Configuration注解,实现配置文件的功能;

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项;

@ComponentScan:Spring组件扫描。

5、运行Spring Boot有哪几种方式?

1)打包用命令或者放到容器中运行

2)用Maven/Gradle插件运行

3)直接执行main方法运行

6、如何理解Spring Boot中的Starters?

Starters是什么:

Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,可以一站式集成Spring及其他技术。

如果想使用Spring JPA访问数据库,只要加入spring-boot-starter-data-jpa启动器依赖即可。Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。

Starters命名:

Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。第三方的启动器一般以第三方的名称来开头,像mybatis的mybatis-spring-boot-starter。

Starters分类:

一是SpringBoot应用类启动器、二是SpringBoot生产启动器、三是其他第三方启动器

7SpringBoot常用的starter有哪些?

spring-boot-starter-web嵌入tomcat和web开发需要servlet与jsp支持

spring-boot-starter-test Spring对测试的支持启动器

spring-boot-starter-data-jpa数据库支持

spring-boot-starter-data-redis redis数据库支持

mybatis-spring-boot-starter第三方的mybatis集成starter

8、Spring、Spring MVC和Spring Boot有什么区别?

Spring

Spring最重要的特征是依赖注入。所有Spring Modules不是依赖注入就是IOC控制反转。当我们恰当的使用DI或者是IOC的时候,可以开发松耦合应用。

Spring MVC

Spring MVC提供了一种分离式的方法来开发Web应用。通过运用像DispatcherServelet,MoudlAndView 和 ViewResolver等一些简单的概念,开发 Web 应用将会变的非常简单。

SpringBoot

Spring和Spring MVC的问题在于需要配置大量的参数。

SpringBoot通过一个自动配置和启动项来解决这个问题。

9、为什么需要spring-boot-maven-plugin?

spring-boot-maven-plugin提供了一些像jar一样打包或运行应用程序的命令:

run 运行SpringBoot应用程序;

repackage 重新打包jar包或war包使其可执行

start和stop管理Spring Boot应用程序的生命周期

build-info生成执行器可以使用的构造信息

10、什么是YAML?

YAML是一种人类可读的数据序列化语言。通常用于配置文件。

与属性文件相比,如果我们要在配置文件中添加复杂的属性,YAML文件就更加结构化,具有分层配置数据的优点。

11、SpringBoot自动配置的原理

在SpringBoot程序main方法中,添加@SpringBootApplication会自动去maven中读取每个starter中的spring.gfactories文件,该文件里配置了所有需要被创建的Spring容器中的bean。

12、Spring Boot的核心配置文件有哪几个?它们的区别是什么?

Spring Boot的核心配置文件是application和bootstrap。

application主要用于Spring Boot项目的自动化配置。

bootstrap配置文件有以下几个应用场景:

  1. 使用Spring Cloud Config配置中心时,需要在bootstrap配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
  2. 一些固定的不能被覆盖的属性;
  3. 一些加解密的场景

13、如何实现Spring Boot应用程序的安全性?

为了实现Spring Boot的安全性,我们使用spring-boot-starter-security依赖项,并且必须添加安全配置。它只需要很少的代码。配置类将必须扩展WebSecurityConfigurerAdapter并覆盖其方法。

14、RequestMapping和GetMapping的不同之处在哪里?

RequestMapping具有类属性的,可以进行GET、POST、PUT或者其它的注释中具有的请求方法。

GetMapping是GET 请求方法中的一个特例。它只是ResquestMapping的一个延伸,目的是为了提高清晰度。

15、spring-boot-starter-parent有什么作用?

新建SpringBoot项目时,都是要有spring-boot-starter-parent,它主要有如下作用:

  1. 定义了Java编译版本为1.8
  2. 使用UTF-8格式编码
  3. 定义了依赖的版本,让我们在写依赖时不需要写版本号
  4. 执行打包操作的配置
  5. 自动化的资源过滤和插件配置
  6. 针对各配置文件的资源过滤。

16、Spring Boot 2.X有哪些新特性?与1.X有什么区别?

配置变更、JDK版本升级、第三方类库升级、响应式Spring编程支持、HTTP/2支持、配置属性绑定、更多改进与加强

17、什么是Swagger?

Swagger广泛用于可视化API,Swagger是用于生成Restful Web服务的可视化表示的工具、规范和完整框架实现。它使文档能够以与服务器相同的速度更新。当通过Swagger正确定义时,消费者可以最少量的实现逻辑来理解远程服务并与其进行交互。因此,Swagger消除了调用服务时的猜测。

18、什么是Free Marker模板?

Free Marker是一个基于Java的模板引擎,最初专注于使用MVC软件架构进行动态网页生成。使用Free marker的主要优点是表示层和业务层完全分离。后端专注于业务逻辑,前端专注页面设计。最后使用free marker将两者结合起来。

19、开启Spring Boot特性有哪几种方式?

继承spring-boot-starter-parent项目

导入spring-boot-dependencies项目依赖

20、Spring Boot支持哪些日志框架?

Spring Boot支持Java Util Logging、 Log4j2, Lockback作为日志框架,如果使用Starters启动器,Spring Boot默认将使用Lockback日志框架。

21、保护SpringBoot应用有哪些方法?

1、在生产中使用HTTPS

2、使用Snyk检查依赖关系

3、升级到最新版本

4、启用CSRF保护

5、使用内容安全策略防止XSS攻击

22、SpringBoot有哪几种读取配置的方式?

Spring Boot可以通过

@PropertySource、

@Value,

@Environment、

@ConfigurationProperties

来绑定配置信息。

23、前后端分离,如何维护接口文档?

在Spring Boot中,可以使用Swagger,它可以快速生成一个接口文档网站,接口一旦发生变化,文档自动更新,所有人访问这个在线网站就可以获取到最新的接口文档,非常方便。

24、什么是Spring Data?

Spring Data是Spring的一个子项目。支持NoSQL和关系型数据存储。主要目标是使数据库访问变得方便快捷。其次是致力于减少数据访问层 (DAO) 的开发量. 我们只需声明持久层的接口,Spring Data JPA会根据符合规范的名字来确定方法需要实现什么样的逻辑。

25、SpringBoot 打成jar和普通的jar有什么区别?

Spring Boot项目最终打成的jar是可执行jar ,这种jar可以直接通过java -jar xxx.jar命令来运行,这种jar不能作为普通的jar被其他项目依赖。

之所以如此,主要还是他和普通jar的结构不同。普通的jar包,解压后直接就是包名,包里就是我们的代码,而Spring Boot打成的可执行jar解压后,在\BOOT-INF\classes目录下才是我们的代码,因此无法被直接引用。如果非要引用,可以在pom.xml文件中增加配置,将Spring Boot项目打包成两个jar ,一个可执行,一个可引用。

26、如何重新加载Spring Boot上的更改,而无需重新启动服务器?

可以使用DEV工具来实现。通过这种依赖关系,重启tomcat。(其实就是热部署之一)

27、如何在自定义端口上运行Spring Boot应用程序?

可以在application中指定端口:server port=自定义端口号

28、如何使用Maven设置Spring Boot应用程序?

最好的方法是继承spring-boot-starter-parent 项目并声明依赖于Spring Boot启动器。这样做可以让项目重用Spring Boot的默认设置。

  1. SpringBoot的事务处理是在哪层处理的

在service层的接口中加@Transactional注解,dao层不需要写。因为业务逻辑处理在service层,它可能会调用多个dao层接口。

  1. SpringBoot跨平台调API

使用Feign进行消费

1、在maven中添加依赖

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-openfeign</artifactId>

    <version>2.2.2</version>

</dependency>

2、启动类上加上@EnableFeignClients(basePackages = {"com.aaa.aurora"})

3、编写service接口

实现类上加入:@FeignClient(url = "${pangu.url}",name = "panguUrl")

其中:pangu.url是配置在application.properties中的ip及端口

  1. 代码中调用
  1. SpringBoot中的yml文件都干些什么

配置数据源、端口、MyBatis的xml文件,微服务的话还会配置eureka,ip和端口号以及网关的ip和端口号等自动化配置。

32、SpringBoot启动流程的关键几个步骤(了解)

  1. SpringApplication.run();开始启动SpringBoot程序,填入我们的主类和参数信息。
  2. 启动时会发布一个SpringBoot的environmentPrepared(准备环境)消息。
  3. environmentPrepared(环境准备)启动消息会被ConfigFileApplicationListener监听器(它注册了,监听SpringBoot),该监听器的load()方法,会尝试加载classpath下的:
    1. application.properties
    2. application.xml
    3. application.yml
    4. application.yaml
  4. 所有配置文件中的信息,被加载到ConfigurableEnvironment中。
  5. 创建容器(ApplicationContext)步骤
    1. 创建容器:创建spring的容器对象。(ApplciationContext)
    2. 准备容器:在此步骤,扫描所有有@Component的注解类(四大组件),将其实例化。
    3. 刷新容器:在此步骤,把实例化的各个Bean,相互注入到各个Bean当中。
  6. 继续执行其他组件的初始化,此时抛出任何异常都会导致SpringBoot启动失败,直至SpringBoot启动成功!

Spring Cloud

  1. 什么是Spring Cloud?

Spring cloud 流应用程序启动器是基于Spring Boot的Spring集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。

  1. Spring Cloud由什么组成?

Spring Cloud Eureka:服务注册与发现

Spring Cloud Zuul:服务网关

Spring Cloud Ribbon:客户端负载均衡

Spring Cloud Feign:声明性的Web服务客户端

Spring Cloud Hystrix:断路器

Spring Cloud Config:分布式统一配置管理

  1. Spring Cloud 和dubbo区别?
  1. 服务调用方式:dubbo是RPC springcloud Rest Api
  2. 注册中心:dubbo 是zookeeper springcloud是eureka,也可以是zookeeper
  3. 服务网关,dubbo本身没有实现,只能通过其他第三方技术整合,springcloud有Zuul路由网关,作为路由服务器,进行消费者的请求分发,springcloud支持断路器,与git完美集成配置文件支持版本控制,事物总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素
  4. 什么是Eureka的自我保护模式?

默认情况下,如果Eureka server在一定时间内没有收到某个微服务实例的心跳,那么服务器将会注销该实例 默认为90s 其实这种行为是比较危险的,当遇到例如网络分区的影响的时候、便会出现误判。此时就需要Eureka的自我保护模式来解决这个问题。-当Eureka server节点在短时间内丢失过多的客户端时 那么这个节点就会进入自我保护模式。进入该模式。 eureka server会保护服务注册表中信息,不在删除服务注册表中的数据、当网络故障恢复 server会自动退出自我保护模式。

5、Eureka和ZooKeeper都可以提供服务注册与发现的功能,请说说两个的区别?

1. ZooKeeper中的节点服务挂了就要选举 在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的, 选举就是改微服务做了集群,必须有一台主其他的都是从

2. Eureka各个节点是平等关系,服务器挂了没关系,只要有一台Eureka就可以保证服务可用,数据都是最新的。 如果查询到的数据并不是最新的,就是因为Eureka的自我保护模式导致的

3. Eureka本质上是一个工程,而ZooKeeper只是一个进程

4. Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper 一样使得整个注册系统瘫痪

5. ZooKeeper保证的是CP,Eureka保证的是AP(自我保护模式下保证可用性)

CAP:C:一致性>Consistency; 取舍:(强一致性、单调一致性、会话一致性、最终一致性、弱一致性) A:可用性>Availability; P:分区容错性>Partition tolerance;

6、zuul网关的作用

网关相当于一个网络服务架构的入口,所有网络请求必须通过网关转发到具体的业务。

Zuul网关的作用:统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等

7、 Zuul与Nginx有什么区别?

Zuul 是 java 语言实现的,主要为 java 服务提供网关服务,尤其在微服务架构中可以更加灵活的对网关进行操作。

Nginx 是使用 C 语言实现,性能高于 Zuul ,但是实现自定义操作需要熟悉 lua 语言,对程序员要求较高,可以使用Nginx 做 Zuul 集群。

8、什么是 Hystrix?

Hystrix是一种断路器,主要的作用是在微服务治理中保护服务。主要的功能设计:

服务降级:当接口调用失败,自动执行一个空的方法。避免线程阻塞)

服务熔断:当接口调用失败,自动执行提前定义好的熔断方法 统一返回错误信息

服务隔离:隔离服务间的相互影响

服务监控:将服务调用的每秒请求数和每秒成功请求书记录下来

9、服务雪崩效应产生的原因

当大多数人在使用Tomcat时,多个HTTP服务会共享一个线程池,假设其中一个HTTP服务访问的数据库响应非常慢,这将造成服务响应时间延迟增加,大多数线程阻塞等待数据响应返回,导致整个Tomcat线程池都被该服务占用,甚至拖垮整个Tomcat。因此,如果我们能把不同HTTP服务隔离到不同的线程池,则某个HTTP服务的线程池满了也不会对其他服务造成灾难性故障。这就需要线程隔离或者信号量隔离来实现了。

10、Spring Cloud OpenFeign 的核心工作原理? 

通过@EnableFeignCleints触发Spring应用程序对classpath中@FeignClient 修饰类的扫描

解析到@FeignClient 修饰类后,Feign框架通过扩展Spring Bean Deifinition 的注册逻辑, 最终注册一个FeignClientFacotoryBean进入Spring容器

Spring容器在初始化其他用到@FeignClient接口的类时,获得的是 FeignClientFacotryBean产生的一个代理对象 Proxy.

基于 java 原生的动态代理机制, 针对 Proxy 的调用, 都会被统一转发给 Feign 框架所定义的一个 InvocationHandler , 由该 Handler 完成后续的 HTTP 转换, 发送, 接收, 翻译HTTP响应的工作

11、服务注册和发现是什么意思?Spring Cloud如何实现?

当我们开始一个项目时,我们通常在属性文件中进行所有的配置。随着越来越多的服务开发和部署,添加和修改这些属性变得更加复杂。有

些服务可能会下降,而某些位置可能会发生变化。手动更改属性可能会产生问题。 Eureka 服务注册和发现可以在这种情况下提供帮助。由

于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找,因此无需处理服务地点的任何更改和处理。

12、负载平衡的意义什么?

在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。

13、什么是Hystrix?它如何实现容错?

Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。通常对于使用微服务架构开发的系统,涉及到许多微服务。这些微服务彼此协作。

14、SpringBoot和SpringCloud的区别?

SpringBoot专注于快速方便的开发单个个体微服务。

SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。

15、服务熔断、服务降级的区别

服务熔断和服务降级,在技术实现上没有本质区别。他们的区别是在业务层(逻辑层):

  1. 服务熔断:原服务down掉(掉线、未启动),此时发生熔断,给前端返回的是预先准备好的响应结果,告知服务不可用。一般发生在服务提供者(Provider)侧。
  2. 服务降级:服务提供者不能提供原有高质量服务了(比如服务器过忙,请求人数过多),那么此时会发生服务降级,由其他微服务提供次一等级的服务。一般发生在服务消费者(Consumer)侧。

Redis

1、什么是Redis?

Redis是一个完全开源免费的,高性能的key-value数据库。

2、使用Redis有哪些好处?

  1. 速度快,因为数据存在内存中,类似于Hash Map,Hash Map的优势就是查找和操作的时间复杂度都是 O(1)(无穷小)
  2. 丰富的数据类型
  3. 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
  4. 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

3、Redis 的数据类型?

Redis主要有5种数据类型

  1. String:字符串、整数或浮点数;主要应用于简单的键值对缓存
  2. List:列表;主要应用于存储一些列表型的数据结构;类似评论
  3. Set:无序集合;主要应用于交集、并集、差集的操作
  4. Hash:包含键值对的无序散列表;主要应用于结构化的数据,比如一个对象
  5. Zset:有序集合;主要应用于去重,也可以排序,如获取排名前几的路线

4、Redis相比Memcached有哪些优势?

  1. Memcached只有一种字符串数据类型,Redis作为其替代者,有五种数据类型
  2. Memcached把数据全部存放于内存之中,断电后会挂掉,数据不能超过内存大小。Redis有部份数据存在硬盘上,这样即能保证数据的持久性且速度也比Memcached快。

5、Redis是单进程单线程的?

Redis是单进程单线程的,Redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。

6、一个字符串类型的值能存储最大容量是多少?

512M。

7、Redis持久化机制

Redis提供两种持久化机制RDB和AOF。通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。当Redis重启后通过把硬盘文件重新加载到内存,就能达到恢复数据的目的。

  1. RDB Redis Data Base:Redis默认的持久化方式。按照一定的时间周期策略把内存中的数据以快照的形式保存到硬盘的二进制文件。即Snapshot快照存储,对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。(快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品。)
  2. AOF Append-only file:Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于MySQL的binlog。当Redis重启时会通过重新执行文件中保存的写命令在内存中重建整个数据库的内容。

当两种方式同时开启时,Redis会优先选择AOF恢复。

8、Redis常见性能问题和解决方案?

  1. Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
  2. 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
  3. 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
  4. 尽量避免在压力很大的主库上增加从库
  5. 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master<- Slave1 <- Slave2 <-Slave3

9、Redis持久化机制的优缺点?

  1. RDB机制
    1. 优点:
      • 只有一个文件dump.rdb,方便持久化。
      • 容灾性好,一个文件可以保存到安全的磁盘。
      • 性能最大化,使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了 redis的高性能。
      • 数据集大时,比AOF的启动效率更高。
    2. 缺点:数据安全性低。RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以RDB更适合数据要求不严谨的时候
  2. AOF机制
    1. 优点:
      • 数据安全,每进行一次命令操作就记录到AOF文件中一次。
      • 通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。
      • AOF机制的rewrite模式。AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)
    2. 缺点:
      • AOF文件比RDB文件大,且恢复速度慢。
      • 数据集大的时候,比RDB启动效率低。

11、Redis过期键的删除策略?

  1. 定时删除:在设置键的过期时间的同时,创建一个定时器 timer.让定时器在键的过期时间来临时,立即执行对键的删除操作。
  2. 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
  3. 定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。

12、Redis的回收策略(淘汰策略)?

  1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  6. no-enviction(驱逐):禁止驱逐数据

注意这里的6种机制,volatile和allkeys规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的lru、ttl以及random是三种不同的淘汰策略,再加上一种no-enviction永不回收的策略。

使用策略规则:

  1. 如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru
  2. 如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random

13、为什么Redis需要把所有数据放到内存中?

Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。

14、Redis的同步机制了解么?

Redis 可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

15、Pipeline有什么好处,为什么要用Pipeline?

可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。

16、是否使用过Redis集群,集群的原理是什么?

  1. Redis Sentinal着眼于高可用,在master宕机时会自动将 slave提升为master,继续提供服务。
  2. Redis Cluster着眼于扩展性,在单个redis存不足时,使用Cluster进行分片存储。

17、Redis集群方案什么情况下会导致整个集群不可用?

有 A,B,C 三个节点的集群,在没有复制模型的情况下,如果节点 B 失败了,那么整个集群就会以为缺少 5501-11000 这个范围的槽而不可用。

18、Redis支持的 Java客户端都有哪些?官方推荐用哪个?

Redisson、Jedis、lettuce 等等,官方推荐使用Redisson。

19、Jedis与 Redisson对比有什么优缺点?

Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis 命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。

Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。

20、Redis如何设置密码及验证密码?

设置密码:config set requirepass 123456

授权密码:auth 123456

21、说说Redis哈希槽的概念?

Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384 个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

22、Redis集群的主从复制模型是怎样的?

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有 N-1 个复制品.

23、Redis集群会有写操作丢失吗?为什么?

Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。

24、Redis集群之间是如何复制的?

异步复制

25、Redis集群最大节点个数是多少?

16384 个。

26、Redis集群如何选择数据库?

Redis 集群目前无法做数据库选择,默认在 0 数据库。

27、怎么测试 Redis 的连通性?

答:使用 ping 命令。

28、怎么理解 Redis 事务?

  1. 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  2. 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

29、Redis 事务相关的命令有哪几个?

MULTI、EXEC、DISCARD、WATCH

30、Redis key 的过期时间和永久有效分别怎么设置?

EXPIRE 和 PERSIST 命令。

31、Redis 如何做内存优化?

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。

32、Redis 回收进程如何工作的?

一个客户端运行了新的命令,添加了新的数据。Redi 检查内存使用情况,如果大于 maxmemory 的限制, 则根据设定好的策略进行回收。一个新的命令被执行,等等。所以我们不断地穿越内存限制的边界,通过不断达到边界然后不断地回收回到边界以下。如果一个命令的结果导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越。

33、都有哪些办法可以降低 Redis 的内存使用情况呢?

如果你使用的是 32 位的 Redis 实例,可以好好利用 Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的 Key-Value 可以用更紧凑的方式存放到一起。

34、Redis 的内存用完了会发生什么?

如果达到设置的上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回。)或者你可以将Redis当缓存来使用配置淘汰机制,当Redis达到内存上限时会冲刷掉旧的内容。

35、缓存雪崩

由于原有缓存失效,新缓存未到期间(比如们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,致使对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。导致整个系统崩溃。

解决办法:

多数系统用加锁或者队列的方式来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上。还有一个简单方案就是将缓存失效时间分散开。

36、缓存穿透

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有,然后返回空。这样就导致用户查询时相当于进行了两次无用的查询。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。

解决办法:

如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。这样一来第二次到缓存时就有值了,就不会继续访问数据库,这种办法最简单粗暴。其次就是多数系统用的布隆过滤器。

37、缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求时,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

解决思路:

1、直接写个缓存刷新页面,上线时手工操作下;

2、数据量不大,可以在项目启动的时候自行加载;

3、定时刷新缓存

38、缓存更新

除了缓存服务器自带的缓存失效策略之外(Redis默认有6种策略),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:

  1. 定时清理过期缓存,缺点是需要维护大量缓存的key
  2. 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存,缺点是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!

39、缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据预案进行自动降级,也可以配置开关实现人工降级。不过有些服务是无法降级的(如加入购物车、结算)。

参考日志级别设置预案:

  1. 一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
  2. 警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
  3. 错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
  4. 严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。

MySql

  1. Sql优化
  1. 索引查询,避免全表扫描,尽量只查询索引条件的字段。例如:一张名为user用户数据表的id字段为索引,查询select id from user 比select name from user效率高。
  2. sql语句尽量避免使用or来连接条件查询数据,or可能会导致全表扫描,效率降低。可以将条件分为多个select语句,用union连接语句。例如:select id from user where name=‘a’ or name=‘b’,可以改为以下的形式来提高查询的效率:select id from user where name=‘a’ union select id from user where name=‘b’;改了之后,两次查询都是走索引,效率相对较高。
  3. 在连续数值的查询中,尽量使用between,而不使用in。in和not in可能会导致全表查询。
  4. sql语句的where查询条件,对字段进行表达式或函数操作,会导致mysql引擎放弃使用索引而进行全表扫描。
  5. 多表查询,使用inner join,left/right join来代替子查询。因为子查询需要在内存中创建临时表来完成这个逻辑上的需要两个步骤的查询工作。
  6. in()和exists();in()适合B表比A表数据小的情况,exists()适合B表比A表数据大的情况。例如:select * from user a where exists (select name from user b where a.id=20)和select * from user a where id in(select id from user b where b.id=20)。
  7. 使用like进行数据表查询时,能用%就不建议使用双%,双%查询会导致mysql引擎放弃使用索引而进行全表扫描查询,查询时尽量把%放后面,或者不适用%。
  8. 最左优先:在mysql建立联合索引时会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。左边匹配不到,整个sql不走索引。例如:select * from user where u_one=‘1’ and u_two=‘2’;
  9. 精确类型匹配:从数据库中查询数据的时候,使用精确的类型匹配。例如:select id from user where id=‘3’;如果id 建立的varchar类型的走索引,如果写成select id from user where id=3不走索引。
  10. 表越小,查询越快,因此,在创建表的时候,为了获得更好的性能,可以将表中的字段的宽度设得尽可能小。
  11. 尽量把字段设置为not null,这样在将来执行查询的时候,数据库不用去比较null值。
  12. 数据量大时,合理使用分区表:使用partition by 子句定义每个分区存放的数据。在执行查询的时候,优化器会根据分区定义过滤那些没有我们需要数据的分区,这样查询就无需扫描所有分区,只需要查找包含需要数据的分区就可以了。
  13. 合理选择存储引擎
    1. Innodb:适合数据完整性,并发性控制,擅长更新,删除。
    2. myisam:适合高速查询及插入。擅长插入和查询。
  14. 慢查询日志的使用,在调试的时候开启慢查询,定位的慢查询语句,再做优化策略。关闭/开启语句 Slow_query_log=0|1,Long_query_time=N超过该时间临界点,就为慢查询。

4、数据库范式

  1. 第一范式: 属性不可再分
  2. 第二范式:在一范式的基础上,要求表中的每个实例或行必须有一个惟一属性可以区分,这个惟一属性列被称为主关键字或主键。
  3. 第三范式:在二范式的基础上, 要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
  4. 所以第三范式具有如下特征:
    1. 每一列只有一个值
    2. 每一行都能区分
    3. 每一个表都不包含其它表已经包含的非主关键字信息
  5. 数据库的左右内外连接
    1. 内连接:当进行内连接时,系统会自动忽略两个表中对应不起来的数据,结果包含两个表中有联系的所有数据;关键字:inner join / join;必须使用 using 或 on指定连接属性/条件,否则产生的结果与交叉连接相同
    2. 左外连接(left join):左表全部行+右表匹配的行,如果左表中某行在右表中没有匹配的行,则在相关联的结果集行中右表的所有选择列表列均为空值。关键字:left join on / left outer join on
    3. 右外连接(right join):与左外连接恰恰相反,以右表为参照显示数据。关键字:right join on / right outer join on
    4. 全外连接(full outer join,MySQL不支持):可通过Union左外连接和右外连接来实现,不管匹配不匹配,全部显示出来,左表在右边没有的显示NULL,右表在左边没有的显示NULL。
  6. MySql重启服务
    1. ps -ef |grep java:查看所有java进程,找到我们要重启的jar
    2. Kill -9 进程ID:结束进程
    3. 上传新的jar包
    4. nohup java -jar xxx.jar &:命令运行服务
  7. MySql的存储过程

存储过程是一个预编译的 SQL 语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次 SQL,使用存储过程比单纯 SQL 语句执行要快。可以用一个命令对象来调用存储过程。类似于java的方法。

创建存储过程

create or replace procedure aaa(参数)

begin

  for i in 1..10 loop

    insert into EMP(EMPNO, ENAME) values(p_empno + i, p_name || i);

  end loop;

  

  commit;

  

exception

  异常接收处理

  end;

  

--调用存储过程

begin

  Aaa(6000, '财务'); -- 调用时填参

end;

  1. MySql的常用函数
    1. CONCAT:拼接成字符串
    2. IFNULL:判断字段是否为空,如果为空则取第二个默认参数,不为空则取表中数据
    3. COALESCE:判断字段是否为空,如果字段为空则取从第二个参数开始不为空的值,字段不为空则取表中数据
    4. max:最大值
    5. min:最大值
    6. avg:平均值
  2. mysql都有哪些索引
  1. 主键索引:建立在主键上的索引被称为主键索引,一张数据表只能有一个主键索引,索引列值不允许有空值,通常在创建表时一起创建。

2、唯一索引:建立在unique字段上的索引被称为唯一索引,一张表可以有多个唯一索引,索引列值允许为空,列值中出现多个空值不会发生重复冲

3、普通索引:建立在普通字段上的索引被称为普通索引。

4、前缀索引:是指对字符串类型字段的前几个字符或对二进制字段的前几个byte建立的索引,而不是在整个字段上建索引。前缀索引可以建立在类型为char、varchar、binary、varbinary的列上,可以大大减少索引占用的存储空间,也能提升索引的查询效率。

10、mysql和redis的区别

  1. 从类型上来说,mysql是关系型数据库,redis是缓存数据库
  2. mysql用于持久化的存储数据到硬盘,功能强大,速度较慢,基于磁盘,读写速度没有Redis快,但是不受空间容量限制,性价比高
  3. redis用于存储使用较为频繁的数据到缓存中,读取速度快,基于内存,读写速度快,也可做持久化,但是内存空间有限,当数据量超过内存空间时,需扩充内存,但内存价格贵
  4. mysql和redis因为需求的不同,一般都是配合使用。需要高性能的地方使用Redis,不需要高性能的地方使用MySQL。存储数据在MySQL和Redis之间做同步。

11、mysql和redis的数据同步问题

读操作,先读redis,没有再去mysql取,取出了再放mqsql。

写操作,先写redis,异步存mysql,然后再有个监控机制(cacal alibaba开源的),监控到mysql插入了数据,把这条数据回写到redis中。写redis时,给key加上一个过期时间,在写操作过程中,如果mysql挂了,那么会丢失一条数据,这个没办法。如果redis挂了,当redis重启后,监控机制会继续把数据写进redis,保证同步。

cacal实现原理:伪装一个从数据库,实现主从同步协议,主数据库通过异步的方式发送信息给伪装数据库,cacal有一个Client(客户端),实现了从mysql中取binlog的功能,以及数据的解析(binlog是一个二进制文件),将binlog同步到redis。实现了这么一套映射流程。

12、MySQL中有哪几种锁?

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

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

3、页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

13、MySQL中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?

1、read uncommited :读到未提交数据

2、read committed:脏读, 不可重复读

3、repeatable read:可重读

4、serializable :串行事物

14charvarchar的区别?

1、char和 varchar类型在存储和检索方面有所不同

2、char列长度固定为创建表时声明的长度,长度值范围是1到255当char值被存储时,它们被用空格填充到特定长度,检索char值时需删除尾随空格。

15、MySQL支持事务吗?

在缺省模式下,MySQL是autocommit模式的,所有的数据库更新操作都会即时提交, 所以在缺省情况下,MySQL是不支持事务的。

但是如果你的 MySQL 表类型是使用InnoDB Tables或BDB tables的话, 你的MySQL就可以使用事务处理,使用SETAUTOCOMMIT=0就可以使MySQL允许在非autocommit模式,在非autocommit模式下,你必须使用COMMIT 来提交你的更改,或者用ROLLBACK来回滚你的更改。

16、MySQL里记录货币用什么字段类型好?

NUMERIC和DECIMAL类型被MySQL实现为同样的类型,这在SQL92标准允许。他们被用于保存值, 该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定。

17、MySQL有关权限的表都有哪几个?

MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在MySQL数据库里,由MySQL_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host 。

18、MySQL数据库作发布系统的存储,一天五万条以上的增量, 预计运维三年,怎么优化?

1、设计良好的数据库结构,允许部分数据冗余,尽量避免join查询, 提高效率。

2、选择合适的表字段数据类型和存储引擎,适当的添加索引。

3、MySQL库主从读写分离。

4、找规律分表,减少单表中的数据量提高查询速度。

5、添加缓存机制, 比如memcached,apc等。

6、不经常改动的页面,生成静态页面。

7、书写高效率的SQL。

19、锁的优化策略

1、读写分离

2、分段加锁

3、减少锁持有的时间

4、多个线程尽量以相同的顺序去获取资源不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。

20、索引的底层实现原理和优化

B+树,经过优化的B+树主要是在所有的叶子结点中增加了指向下一个叶子节点的指针, 因此InnoDB建议为大部分表使用默认自增的主键作为主索引。

21、什么情况下设置了索引但无法使用

1、以“%” 开头的 LIKE 语句,模糊匹配

2、OR语句前后没有同时使用索引

3、数据类型出现隐式转化( 如varchar不加单引号的话可能会自动转换为int型)

22、数据库中的事务是什么?

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

事务特性:

1、原子性:即不可分割性,事务要么全部被执行, 要么就全部不被执行。

2、一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态

3、隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务

4、持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。

23、SQL注入漏洞产生的原因?如何防止?

SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST 和 GET提交一些sql语句正常执行。防止SQL注入的方式:

开启配置文件中的magic_quotes_gpc和magic_quotes_runtime设置执行sql语句时使用addslashes进行sql语句转换Sql语句书写尽量不要省略双引号和单引号。

过滤掉sql语句中的一些关键词:update、insert、delete、select、* 。

提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。

24、SQL语言包括哪几部分?每部分都有哪些操作关键字?

SQL语言包括数据定义(DDL)、数据操纵(DML),数据控制(DCL)和数据查询( DQL)四个部分。

数据定义:Create Table,Alter Table,Drop Table, Craete/Drop Index

等数据操纵:Select,insert,update,delete,

数据控制: grant,revoke 数据查询:select

25、什么是锁?

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

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

基本锁类型:锁包括行级锁和表级锁。

26、主键、外键和索引的区别?

主键、外键和索引的区别

定义:

主键–唯一标识一条记录,不能有重复的,不允许为空外键–表的外键是另一表的主键, 外键可以有重复的, 可以是空值索引–该字段没有重复值,但可以有一个空值

作用:

主键–用来保证数据完整性外键–用来和其他表建立联系用的索引–是提高查询排序的速度

个数:

主键–主键只能有一个外键–一个表可以有多个外键索引–一个表可以有多个唯一索引

27、一千万条数据的表, 如何分页查询?

数据量过大的情况下,limit offset 分页会由于扫描数据太多而越往后查询越慢,可以配合当前页最后一条ID进行查询,SELECT * FROM T WHERE id > #{ID} LIMIT #{LIMIT} 。当然,这种情况下ID必须是有序的,这也是有序ID的好处之一。

28、订单表数据量越来越大导致查询缓慢, 如何处理?

分库分表. 由于历史订单使用率并不高, 高频的可能只是近期订单, 因此, 将订单表按照时间进行拆分, 根据数据量的大小考虑按月分表或按年分表. 订单ID最好包含时间(如根据雪花算法生成), 此时既能根据订单ID直接获取到订单记录, 也能按照时间进行查询.

29、Mysql服务器默认端口是什么?

Mysql服务器的默认端口是3306。

30、如何获取当前的Mysql版本?

SELECT VERSION();用于获取当前Mysql的版本。

31、LIKE声明中的%和_是什么意思?

%对应于0个或更多字符,_只是 LIKE语句中的一个字符。

Linux常用命令

1、文件和文件夹操作

ls 列出当前或指定路径下的文件和目录。类似于MSDOS的dir。

du 查看当前文件夹和子文件夹所使用的大小。查看当前文件夹下所有文件和目录的大小信息,使用du -a。也可查看单个文件或目录如:du 1.txt。

mkdir 创建一个文件夹。

rmdir 删除一个文件夹。

cd 更换当前目录,同MSDOS的cd命令。

touch 改变文件或目录的时间,包括存取时间和更改时间。也用于创建一个空文件。

cp 复制文件或目录。若复制的源文件夹内不为空(内有文件或目录),则需-r参数(递归处理)。

rm 删除文件或目录,如欲删除文件夹内不为空(内有文件或目录),则需-r参数(递归处理)。

mv 移动文件或目录,或是更改文件或目录的名称。(也可以仅仅修改文件名)

split 将文件切成较小的文件,预设每1000行会切成一个小文件。

lsattr 列出某个文件或目录的属性。

chattr 修改某个文件或目录的属性。

pwd 查看当前的路径。

2、搜索和查找

find 在当前目录下查找某个文件或目录。

3、查看文件内容

grep 最常见的用法:在之前命令的结果基础之上,通过管道搜索指定的内容。

4、系统及通用操作

clear 清屏,同MSDOS的cls。

man 后面跟某一条指令,意为查看该命令的帮助手册。如man clear。

exit 退出当前操作界面,回到上一级。

reboot 重启系统

shutdown 关机

ps 列出程序运行情况,类似于进程管理器的查看。它可以查看某个进程的详细信息。

kill 删除某个进程。

5、网络设置

ifconfig 类似MSDOS的ipconfg,查看和设置网络设备的ip地址、掩码等等。

ping 同MSDOS的ping,测试网络是否通畅。

netstat 同MSDOS的netstat,查看当前网络连接情况。(有多少连接,跟谁连接等)

6、打包上传运行一个SpringBoot程序并查看日志

  1. 安装nohup,程序后台运行管理器;Centos7中自带nohup,无需安装
  2. 把一个SpringBoot项目,打包并发布到Centos7中
    1. 修改ip等配置信息后,在idea的右侧maven窗口中,双击要打包的项目中的“package”选项,开始打包。
    2. 然后在下面的控制台中,找到打包成功后的jar包路径,在文件夹中找到它,准备上传。
    3. 把它上传到centos7的home文件下,然后新建一个和系统同名的目录中,将系统jar包上传进来。
  3. 以后台方式,运行打包的SpringBoot程序,并输出日志
    1. 启动一个程序:使用cd命令(cd /home/xxx)进入jar包所在目录,使用ls命令查看jar包是否在此目录下
    2. 然后使用:nohup java -jar xxx.jar &命令,以后台方式运行一个jar包,并且默认输出日志(在当前文件夹)nohup.out
  4. 查看日志:可以将日志文件传入win系统下,以记事本方式打开,查看错误可以全局搜索exception,
  5. tail -f nohup.out,动态查看日志(日志文件有变化,会实时显示出来)
  6. 若要动态清空一个正在占用的nohup.out文件,请通过“cat /dev/null > nohup.out”此命令,会把“空”文件内容,输出给日志文件,导致日志内容被空覆盖。大小就清空了。
  7. 请注意,不要尝试在未关闭一个进程时,就删除日志文件。(若要动态清空,就是用上面的方案)
  8. 清理历史日志:
    1. 由运维,编写Centos7定时脚本任务,比如每晚23点执行该脚本,清理历史日志
    2. 按天将日志文件分割出来,并重命名
    3. 按照设定,删除无需保留的日志文件(比如默认保留30天日志)

  1. 关闭一个程序:ps -ef |grep java,查看所有java进程

比如,我们会看到:

root 3780 3262 10 15:58 pts/000:00:22 java -jar ServiceOne-1.0-SNAPSHOT.jar

表示,名为ServiceOne-1.0-SNAPSHOT.jar的java包,在运行,然后第一组数字,是当前程序的PID(进程ID)。本例为:3780。

而后,我们可以通过命令强行结束它:kill -9 3780

网络

1、OSI 七层模型?

应用层:网络服务与最终用户的一个接口。

表示层:数据的表示、安全、压缩。

会话层:建立、管理、终止会话。

传输层:定义传输数据的协议端口号,以及流控和差错校验。

网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。

链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能。

物理层:建立、维护、断开物理连接。

2、简述 tcp 和 udp的区别?

1、TCP面向连接的;UDP是无连接的,即发送数据之前不需要建立连接。

2、TCP提供可靠的数据传输服务;UDP尽最大努力交付,但不保证可靠交付。

3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高要求的广播通信等。

4、TCP是点到点的连接;UDP支持一对一,一对多,多对一和多对多的交互通信。

5、TCP对系统资源要求较多,UDP对系统资源要求较少。

3、get和post的区别

POST在浏览器回退时会再次提交请求,GET不会。

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

GET请求在URL中传送的参数是有长度限制的,而POST没有。

GET参数通过URL传递,POST放在Request body中。

GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

4、status 响应状态码

1** 信息性状态码

100是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。

2** 成功状态码

200 请求已成功,请求所希望的响应头或数据体将随此响应返回。

3** 重定向状态码,表示服务器要求客户端重定向

4** 客户端错误状态码,表示客户端的请求有非法内容

400 1、语义有误。 2、请求参数有误。

404 请求失败,请求所希望得到的资源未在服务器上发现。

408 请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。

5** 服务器错误状态码,表示服务器未能正常处理客户端的请求而出现意外错误。

500 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。

5、HTTP和HTTPS的区别

HTTP:超文本传输协议,以明文的形式来传输数据,是无状态的;默认端口号80。

HTTPS:超文本传输安全协议,经由HTTP进行通信,但利用SSL/TLS来加密数据包。目的是为了提供网站服务器的安全认证,保护交换数据的隐私与完整性;默认端口号443。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值