赞
踩
从2021-02-18日开始,收集面试题,坚持更新,加油!!!
JDK 和 JRE 有什么区别?
JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。
JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。
具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很多 Java 程序调试和分析的工具。简单来说:如果你需要运行 Java 程序,只需安装 JRE 就可以了,如果你需要编写 Java 程序,需要安装 JDK。
==和equals的区别
==解读
对于基本类型和引用类型 == 的作用效果是不同的,如下所示:
基本类型:比较的是值是否相同;
引用类型:比较的是引用是否相同;
equals 解读
equals :比较的是值是否相同;
final 在 Java 中有什么作用?
final 修饰的类叫最终类,该类不能被继承。
final 修饰的方法不能被重写。
final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
Java 中的 Math. round(-1. 5) 等于多少?
等于 -1,因为在数轴上取值时,中间值(0.5)向右取整,所以正 0.5 是往上取整,负 0.5 是直接舍弃。
Java 中操作字符串都有哪些类?它们之间有什么区别?
操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
重载和重写的区别
重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类;如果父类方法访问修饰符为private则子类中就不是重写。
自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;
Java使用自动装箱和拆箱机制,节省了常用数值的内存开销和创建对象的开销,提高了效率,由编译器来完成,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。
构造方法有哪些特性?
1,名字与类名相同;2,没有返回值,但不能用void声明构造函数;3,生成类的对象时自动执行,无需调用。
静态方法和实例方法有何不同?
静态方法和实例方法的区别主要体现在两个方面:
在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制
创建线程有几种不同的方式?你喜欢哪一种?为什么?
1.继承Thread类
2.实现Runnable接口
3.应用程序可以使用Executor框架来创建线程池
4.实现Callable接口
我更喜欢实现Runnable接口这种方法,当然这也是现在大多程序员会选用的方法。因为一个类只能继承一个父类而可以实现多个接口。同时,线程池也是非常高效的,很容易实现和使用。
switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?
在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
构造器(constructor)是否可被重写(override)?
构造器不能被继承,因此不能被重写,但可以被重载。
是否可以继承String类?
String 类是final类,不可以被继承。
char 型变量中能不能存贮一个中文汉字,为什么?
char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。
阐述静态变量和实例变量的区别。
静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。
抽象类必须要有抽象方法吗?
不需要,抽象类不一定非要有抽象方法。
下面代码,抽象类并没有抽象方法但完全可以正常运行。
示例代码:
abstract class Cat {
public static void sayHi() {
System. out. println("hi~");
}
}
普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以包含抽象方法。
抽象类不能直接实例化,普通类可以直接实例化。
抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类,如下图所示,编辑器也会提示错误信息:
接口和抽象类有什么区别?
实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
构造函数:抽象类可以有构造函数;接口不能有。
实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。
Java 中 IO 流分为几种?
按功能来分:输入流(input)、输出流(output)。
按类型来分:字节流和字符流。
字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据,1个字符相当于2个字节
访问修饰符public,private,protected,以及不写(默认)时的区别?
类的成员不写访问修饰时默认为default。默认对于同一个包中的其他类相当于公开(public),对于不是同一个包中的其他类相当于私有(private)。受保护(protected)对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。Java中,外部类的修饰符只能是public或默认,类的成员(包括内部类)的修饰符可以是以上四种。
修饰符 | 当前类 | 同 包 | 子 类 | 其他包 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
float f=3.4;是否正确?
不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F;。
short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?
对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
&和&&的区别?
&两边的条件都要判断(不管前面的是ture还是false)。
&&先判断前面的,若为false,则后面的不再判断,若为true,则继续判断。
接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?
接口可以继承接口,而且支持多重继承。抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。
ArrayList 和 LinkedList 有什么区别
ArrayList和LinkedList都实现了List接口,有以下的不同点:
1、ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
2、相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
3、LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
讲讲你理解的 nio和 bio 的区别是啥
IO(BIO)是面向流的,NIO是面向缓冲区的
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
单例模式实现
懒汉模式:很懒,用的时候才创建
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
饿汉模式:很饿,一开始就迫不及待的创建了
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
Array 和 ArrayList 有何区别?
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList初始大小是固定的。
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。
springMVC的执行流程
springMVC是由dispatchservlet为核心的分层控制框架。首先客户端发出一个请求,web服务器解析请求url并去匹配dispatchservlet的映射url,如果匹配上就将这个请求放入到dispatchservlet,dispatchservlet根据mapping映射配置去寻找相对应的handel,然后把处理权交给找到的handel,handel封装了处理业务逻辑的代码,当handel处理完后会返回一个逻辑视图modelandview给dispatchservlet,此时的modelandview是一个逻辑视图不是一个正式视图,所以dispatchservlet会通过viewresource视图资源去解析modelandview,然后将解析后的参数放到view中返回到客户端并展现。
Java 中,Comparator 与Comparable 有什么不同?
Comparable 接口用于定义对象的自然顺序,是排序接口,而 comparator 通常用于定义用户定制的顺序,是比较接口。我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序。Comparable 总是只有一个,但是可以有多个 comparator 来定义对象的顺序。
object中定义了哪些方法?
clone(), equals(), hashCode(), toString(), notify(), notifyAll(),
wait(), finalize(), getClass()
Collection与Collections的区别是什么?
Collection是Java集合框架中的基本接口;
Collections是Java集合框架提供的一个工具类,其中包含了大量用于操作或返回集合的静态方法。
常用数据结构:
集合,线性结构(数组,队列,链表和栈),树形结构,图状结构
JVM分为哪些区,每一个区干吗的?
1)方法区(method):被所有的线程共享。方法区包含所有的类信息和静态变量。
2)堆(heap):被所有的线程共享,存放对象实例以及数组,Java堆是GC的主要区域。
3)栈(stack):每个线程包含一个栈区,栈中保存一些局部变量等。
4)程序计数器:是当前线程执行的字节码的行指示器。
谈谈你对ajax的认识?
Ajax是一种创建交互式网页应用的的网页开发技术;AsynchronousJavaScriptandXML的缩写。
Ajax的优势:通过异步模式,提升了用户体验。优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用。Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
Ajax的最大特点:可以实现局部刷新,在不更新整个页面的前提下维护数据,提升用户体验度。
两个对象值相同equals结果为true,但却可有不同的 hashCode,这句话对不对?
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希值(hashCode)应当相同。Java 对于equals方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
(2)如果两个对象的 hashCode相同,它们并不一定相同。当然,你未必按照要求去做,但是如果你违背了上述原则就会发现在使用集合时,相同的对象可以出现在Set 集合中,同时增加新元素的效率会大大降低(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
在 Java 中,如何跳出当前的多重嵌套循环?
在最外层循环前加一个标记如outfor,然后用break outfor;可以跳出多重循环。例如以下代码:
运行结果如下所示:
j = 0
j = 1
j = 2
j = 3
j = 4
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里是值传递还是引用传递?
是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的内存地址。这个值(内存地址)被传递后,同一个内存地址指向堆内存当中的同一个对象,所以通过哪个引用去操作这个对象,对象的属性都是改变的。
抽象的(abstract)方法是否可同时是静态的(static), 是否可同时是本地方法(native),是否可同时被 synchronized?
都不能。
抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。
本地方法是由本地代码(如 C++ 代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。
synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。
Java中为什么要用 clone?
在实际编程过程中,我们常常要遇到这种情况:有一个对象 A,在某一时刻 A 中已经包含了一些有效值,此时可能会需要一个和 A 完全相同新对象 B,并且此后对 B 任何改动都不会影响到 A 中的值,也就是说,A 与 B 是两个独立的对象,但 B 的初始值是由 A 对象确定的。在 Java 语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但clone()方法是其中最简单,也是最高效的手段。
谈谈你对多态的理解?
多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源代码,就可以让引用变量绑定到各种不同的对象上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
通俗版:一个接口会有多个实现类,不同的实现类的内容不一样,这就是多态,相当于一个接口有多种实现状态的意思
面向对象的三大特性:封装、多态和继承:
(1)封装(对应可扩展性):隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。封装是通过访问控制符(public protected private)来实现。一个类就可看成一个封装。
(2)继承(重用性和扩展性):子类继承父类,可以继承父类的方法和属性。可以对父类方向进行覆盖(实现了多态)。但是继承破坏了封装,因为他是对子类开放的,修改父类会导致所有子类的改变,因此继承一定程度上又破坏了系统的可扩展性,只有明确的IS-A关系才能使用。继承要慎用,尽量优先使用组合。
(3)多态(可维护性和可扩展性):接口的不同实现方式即为多态。接口是对行为的抽象,刚才在封装提到,找到变化部分并封装起来,但是封装起来后,怎么适应接下来的变化?这正是接口的作用,接口的主要目的是为不相关的类提供通用的处理服务,我们可以想象一下。比如鸟会飞,但是超人也会飞,通过飞这个接口,我们可以让鸟和超人,都实现这个接口。
面向对象编程(OOP)其实就是一种设计思想,在程序设计过程中把每一部分都尽量当成一个对象来考虑,以实现软件系统的可扩展性,可维护性和可重用性。
error和exception的区别?
Error类和Exception类的父类都是Throwable类,他们的区别如下:
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。
Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
Exception类又分为未检查异常(UnCheckedException)和受检查的异常(CheckedException)。运行时异常ArithmeticException,IllegalArgumentException编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用 try…catch 捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不会通过。
调用下面的方法,得到的返回值是什么?
代码走到第3行的时候遇到了一个MathException,这时第4行的代码就不会执行了,代码直接跳转到catch语句中,走到第 6 行的时候,异常机制有一个原则:如果在catch中遇到了return或者异常等能使该函数终止的话那么有finally就必须先执行完finally代码块里面的代码然后再返回值。因此代码又跳到第8行,可惜第8行是一个return语句,那么这个时候方法就结束了,因此第6行的返回结果就无法被真正返回。如果finally仅仅是处理了一个释放资源的操作,那么该道题最终返回的结果就是2。因此上面返回值是3。
说出最常见的5个RuntimeException?
java.lang.NullPointerException 空指针异常;出现原因:调用了未经初始化的对象或者是不存在的对象。
java.lang.ClassNotFoundException 指定的类找不到;出现原因:类的名称和路径加载错误;通常都是程序试图通过字符串来加载某个类时可能引发异常。
java.lang.NumberFormatException 字符串转换为数字异常;出现原因:字符型数据中包含非数字型字符。
java.lang.IndexOutOfBoundsException 数组角标越界异常,常见于操作数组对象时发生。
java.lang.IllegalArgumentException 方法传递参数错误。
java.lang.ClassCastException 数据类型转换异常。
java.lang.NoClassDefFoundException 未找到类定义错误。
SQLException SQL 异常,常见于操作数据库时的 SQL 语句错误。
java.lang.InstantiationException 实例化异常。
java.lang.NoSuchMethodException 方法不存在异常。
throw 和 throws 的区别?
throw:
throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理。
throw是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行throw一定是抛出了某种异常。
throws:
throws语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理。
throws主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型。
throws表示出现异常的一种可能性,并不一定会发生这种异常。
Java 的基本数据类型都有哪些各占几个字节?
按照口诀记忆:
数据类型:byte short int long float double boolean char
占用字节数:12484812(byte对应1,short对应2,以此类推)
字节流如何转为字符流?
字节输入流转字符输入流通过 InputStreamReader 实现,该类的构造函数可以传入 InputStream 对象。
字节输出流转字符输出流通过 OutputStreamWriter 实现,该类的构造函数可以传入 OutputStream 对象。
如何将一个 java 对象序列化到文件里?
在 java 中能够被序列化的类必须先实现 Serializable 接口,该接口没有任何抽象方法只是起到一个标记作用。
public class Test {
public static void main(String[] args) throws Exception {
//对象输出流
ObjectOutputStream objectOutputStream =
new ObjectOutputStream(new FileOutputStream(new File("D://obj")));
objectOutputStream.writeObject(new User("zhangsan", 100));
objectOutputStream.close();
//对象输入流
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("D://obj")));
User user = (User) objectInputStream.readObject();
System.out.println(user);
objectInputStream.close();
}
}
字节流和字符流的区别?
字节流读取的时候,读到一个字节就返回一个字节;字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在 UTF-8 码表中是 3 个字节)时。先去查指定的编码表,将查到的字符返回。字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。字节流主要是操作 byte 类型数据,以 byte 数组为准,主要操作类就是 OutputStream、InputStream字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组。所以字符流是由 Java 虚拟机将字节转化为 2 个字节的 Unicode 字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点。在程序中一个字符等于两个字节,java 提供了 Reader、Writer 两个专门操作字符流的类。
什么是 java 序列化,如何实现 java 序列化?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。序 列 化 的 实 现 : 将 需 要 被 序 列 化 的 类 实 现 Serializable 接 口 , 该 接 口 没 有 需 要 实 现 的 方 法 , implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj)方法就可以将参数为 obj 的对象写出(即保存其状态),要恢复的话则用输入流。
请问 ArrayList、HashSet、HashMap 是线程安全的吗?如果不是怎么获取线程安全的集合?
通过以上类的源码进行分析,每个方法都没有加锁,显然都是非线程安全的。在集合中Vector 和HashTable是线程安全的。打开源码会发现其实就是把各自核心方法添加上了synchronized 关键字。Collections工具类提供了相关的 API,可以让上面那3个不安全的集合变为安全的。
Collections.synchronizedCollection(a);
Collections.synchronizedList(list);
Collections.synchronizedMap(m);
Collections.synchronizedSet(s);
上面几个函数都有对应的返回值类型,传入什么类型返回什么类型。打开源码其实原理非常简单,就是将集合的核心方法添加上了synchronized关键字。
List 和 Map、Set 的区别?
List集合中对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象,例如通过list.get(i)方法来获取集合中的元素;Map中的每一个元素包含一个键和一个值,成对出现,键对象不可以重复,值对象可以重复;Set集合中的对象不按照特定的方式排序,并且没有重复对象,但它的实现类能对集合中的对象按照特定的方式排序,例如 TreeSet类,可以按照默认顺序,也可以通过实现 java.util.Comparator接口来自定义排序方式。
HashMap和Hashtable有什么区别?
HashMap是非线程安全的,HashMap是Map的一个实现类,是将键映射到值的对象,不允许键值重复。允许空键和空值;由于非线程安全,HashMap的效率要较 Hashtable 的效率高一些。Hashtable 是线程安全的一个集合,不允许 null 值作为一个 key 值或者value 值;Hashtable是sychronized,多个线程访问时不需要自己为它的方法实现同步,而 HashMap 在被多个线程访问的时候需要自己为它的方法实现同步。
List ,Set, Map是否继承来自Collection接口? 存取元素时, 有何差异?
List、Set 是继承 Collection 接口; Map不是。
List:元素有放入顺序,元素可重复,通过下标来存取。
Map:元素按键值对存取,无放入顺序。
Set:元素无存取顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在 set 中的位置是有该元素的 hashCode 决定的,其位置其实是固定的)。
简述 Java 中的值传递和引用传递?
按值传递是指的是在方法调用时,传递的参数是按值的拷贝传递。按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了示例如下:
class TempTest {
private void test1(int a) {
a = 5;
System.out.println("test1 方法中的 a=" + a);
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
//传递后,test1 方法对变量值的改变不影响这里的 a
t.test1(a);
System.out.println("main 方法中的 a =" + a);
}
}
运行结果是:
test1 方法中的 a=5
main 方法中的 a =3
按引用传递是指的是在方法调用时,传递的参数是按引用进行传递,其实传递的是引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。示例如下:
class TempTest { private void test1(A a) { a.age = 20; System.out.println("test1 方法中的 age=" + a.age); } public static void main(String[] args) { TempTest t = new TempTest(); A a = new A(); a.age = 10; t.test1(a); System.out.println("main 方法中的 age =" + a.age); } } class A { public int age = 0; }
运行结果:
test1 方法中的 age=20
main 方法中的 age =20
总结:传基本数据类型和字符串和空值过去相当于值传递,传对象过去相当于引用传递
一个栈的入栈序列是 A,B,C,D,E,则栈的不可能的输出序列是?(C)
A.EDCBA
B.DECBA
C.DCEAB
D.ABCDE
堆栈分别是先进后出,后进先出,选项 a 是 abcde 先入栈,然后依次出栈,正好是 edcba。选项 b 是 abcd 先依次入栈,然后d出栈, e再入栈, e出栈选项c是错误的,不可能a先出栈。选项 d 是 a 入栈,然后 a 出栈;b 再入栈, b 出栈。依此类推。最后的结果选择 C。
下面代码的运行结果是(C)
原因:a是空值,不是对象,没有地址,所以没有传递到方法里,所以没有办法改变a的值,除非a new出一个集合
A.0
B.1
C.java.lang.NullPointerException
D.以上都不正确
public class Test {
public static void main(String[] args) {
List<String> a = null;
test(a);
System.out.println(a.size());
}
public static void test(List<String> a) {
a = new ArrayList<String>();
a.add("abc");
}
}
解释一下什么是 Servlet, 说一说 Servlet 的生命周期
Servlet 是一种服务器端的 Java 应用程序,具有独立于平台和协议的特性,可以生成动态的 Web 页面。 它担当客户请求(Web 浏览器或其他 HTTP 客户程序)与服务器响应(HTTP 服务器上的数据库或应用程序)的中间层。Servlet是位于 Web 服务器内部的服务器端的 Java 应用程序,与传统的从命令行启动的 Java 应用程序不同,Servlet 由 Web 服务器进行加载,该 Web 服务器必须包含支持 Servlet 的 Java 虚拟机。
Servlet 生命周期可以分成四个阶段:加载和实例化、初始化、服务、销毁。当客户第一次请求时,首先判断是否存在 Servlet 对象,若不存在,则由 Web 容器创建对象,而后调用 init()方法对其初始化,此初始化方法在整个 Servlet 生命周期中只调用一次。完成 Servlet 对象的创建和实例化之后,Web 容器会调用 Servlet 对象的 service()方法来处理请求。当 Web 容器关闭或者 Servlet 对象要从容器中被删除时,会自动调用 destory()方法。
过滤器有哪些作用和用法?
常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件等。
写出一个冒泡排序
public static void bubbleSort() { int arr[] = {-5, 29, 7, 10, 5, 16}; for (int i = 1; i < arr.length; i++) { for (int j = 0; j < arr.length - i; j++) { if (arr[j] < arr[j + 1]) { int temp; temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } for (int i = 0; i < arr.length; i++) { System.out.print(" " + arr[i] + " "); } }
如果去掉了 main 方法的 static 修饰符会怎样(B)
A.程序无法翻译。
B.程序能正常编译,运行时或抛出 NoSuchMethodError 异常。
C.程序能正常编译,正常运行。
D.程序能正常编译,正常运行一会会立刻退出。
log4j的优先级从高到低的排序为(A)
A.error>warn>info>debug
B.warn>info>debug>error
C.warn >debug>error>info
D.error>warn>debug>info
下列哪些方法可以使线程从运行状态进入到阻塞状态(BCD)
A.notify
B.wait
C.sleep
D.yield
String a = new String(“1”+”2”)最终创建了几个对象(D)
A.1
B.2
C.3
D.4
原因:1是一个,2是一个,12是一个,new String也是一个,a只是引用变量,不是对象
选择 Oracle 的分页语句的关键字(A)
A.rownum
B.limit
C.TOP
D.pagenum
以下哪句是对索引的错误描述(C)
A.选择性差的索引只会降低 DML 语句的执行速度
B.选择性强的索引只有被 Access Path 使用到才是有用的索引
C.过多的索引只会阻碍性能的提升,而不是加速性能
D.在适当的时候将最常用的列放在复合索引的最前面
E.索引和表的数据都存储在同一个 Segment 中
System.out.println(3/2);System.out.println(3.0/2); System.out.println(3.0/2.0); 分别会打印什么结果?
1
1.5
1.5
ThreadLocal 的原理和应用场景
每一个ThreadLocal能够放一个线程级别的变量,可是它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全。
ThreadLocal的应用场景:最常见的ThreadLocal使用场景为用来解决数据库连接、Session 管理等
简述 TCP 的三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND 状态, 等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 SYN 包(syn=k),即SYN+ACK 包,此时服务器进入 SYN_RECV 状态。
第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据
springMVC request接收设置是线程安全的吗?
是线程安全的,request、response 以及 requestContext 在使用时不需要进行同步。而根据 spring的默认规则,controller对于BeanFactory而言是单例的。即controller只有一个, controller 中的request等实例对象也只有一个。
列举 Maven 常见的六种依赖范围
compile: 编译依赖范围(默认),对其三种都有效。
test: 测试依赖范围,只对测试 classpath 有效。
runtime: 运行依赖范围,只对测试和运行有效,编译主代码无效,例如 JDBC。
provided: 已提供依赖范围,只对编译和测试有效,运行时无效,例如 selvet-api。
system: 系统依赖范围.谨慎使用.例如本地的,maven 仓库之外的类库文件。
import(maven2.0.9 以上): 导入依赖范围,不会对其他三种有影响。
Mybatis 如何防止 sql 注入?mybatis 拦截器了解过吗,应用场景是什么?
Mybatis使用#{}经过预编译的,是安全的,防止sql 注入。
Mybatis拦截器只能拦截四种类型的接口:Executor、StatementHandler、ParameterHandler和ResultSetHandler。这是在Mybatis的Configuration中写死了的,如果要支持拦截其他接口就需要我们重写Mybatis的Configuration。
Mybatis可以对这四个接口中所有的方法进行拦截。
Mybatis拦截器常常会被用来进行分页处理。
mvc的各个部分都有哪些技术来实现?如何实现的?
MVC是Model-View-Controller的简写。Model代表的是应用的业务逻辑(通过 JavaBean,EJB组件实现),View 是应用的表示面(由JSP页面产生),Controller是提供应用的处理过程控制(一般是一个Servlet),通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。
Linux下如何让命令在后台执行?
要让程序在后台执行,只需在命令行的最后加上“&”符号。例如:$ find . -name abc -print&
Linux中rm -i 与 rm -r 个实现什么功能?
rm –i: 交互模式删除文件,删除文件前给出提示。
rm -r:递归处理,将指定目录下的所有文件与子目录一并处理。
什么是乐观锁,什么是悲观锁,两者的区别是什么?
悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
日志打印的log4j的配置中%t表示什么?
%t 输出产生该日志事件的线程名。
扩展:%M 是输出方法的名字、%m 是输出代码指定的日志信息。指定的打印信息的具体格式 ConversionPattern,具体参数:
%m输出代码中指定的消息
%p输出优先级,即 DEBUG,INFO,WARN,ERROR,FATAL
%r输出自应用启动到输出该 log 信息耗费的毫秒数
%c输出所属的类目,通常就是所在类的全名
%t输出产生该日志事件的线程名
%n输出一个回车换行符,Windows 平台为"rn”,Unix 平台为"n”
%d 输出日志时间点的日期或时间,默认格式为 ISO8601,也可以在其后指定格式,比如:%d{yyyy MM dd HH:mm:ss,SSS}
%l输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数
%x输出和当前线程相关联的 NDC(嵌套诊断环境),尤其用到像 java servlets 这样的多客户多线程的应用中。
%%输出一个”%”字符
%F输出日志消息产生时所在的文件名称
%M输出执行方法
%L输出代码中的行号
在Linux中,可以使用命令(C)加挂计算机上的非Linux文件系统
A. cat /proc/filesystems
B. ln
C. mount
D. df
什么时候使用抽象类和接口
如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
如果你想实现多重继承,那么你必须使用接口。由于 Java 不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。
多数情况下抽象类都是共同特征的抽象,而接口是共同行为的抽象。
说出常用的10个linux操作命令,至少 5 个,并简述命令的作用
ls命令
作用:显示目录内容,类似 DOS 下的 DIR
cat命令
作用:显示文件内容,concatenate 的缩写,类似 dos 的 type 命令。
mv 命令
作用:更改文件或者目录的名字。
rm 命令
作用:删除文件命令,类似 dos 的 del 命令
请简述什么是集群?
服务器集群就是指将很多服务器集中起来一起进行同一种服务,在客户端看来就象是只有一个服务器。集群可以利用多个计算机进行并行计算从而获得很高的计算速度,也可以用多个计算机做备份,从而使得任何一个机器坏了整个系统还是能正常运行。一旦在服务器上安装并运行了群集服务,该服务器即可加入群集。群集化操作可以减少单点故障数量,并且实现了群集化资源的高可用性。
什么叫脏数据,什么叫脏读(Dirty Read)?
脏数据在临时更新(脏读)中产生。事务A更新了某个数据项X,但是由于某种原因,事务A出现了问题,于是要把A回滚。但是在回滚之前,另一个事务B读取了数据项X的值(A 更新后),A回滚了事务,数据项恢复了原值。事务B读取的就是数据项X的就是一个“临时”的值,就是脏数据。
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
什么是BOS?
ERP系统是企业资源计划(Enterprise Resource Planning )的简称。BOS(Business & Operation Support )指的是业务运营支撑系统。BOS是ERP的集成与应用平台。BOS遵循面向服务的架构体系,是一个面向业务的可视化开发平台;是一个ERP和第三方应用集成的技术平台。它有效的解决了ERP应用的最主要矛盾:用户需求个性化和传统ERP软件标准化之间的矛盾。
BOS与ERP是什么关系?
ERP是企业管理信息化的全面解决方案,ERP是基于BOS构建的。 ERP满足企业全面业务的标准应用;BOS确保了企业ERP应用中的个性化需求完美实现。基于BOS的ERP,可以为不同行业不同发展阶段的企业构建灵活的、可扩展的、全面集成的整体解决方案。
什么是工作流
现在大多数公司的请假流程是这样的:员工打电话(或网聊)向上级提出请假申请——上级口头同意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑。采用工作流技术的公司的请假流程是这样的:员工使用账户登录系统——点击请假——上级登录系统点击允许。就这样,一个请假流程就结束了。有人会问,那上级不用向公司提交请假记录?公司不用将记录录入电脑?答案是,用的。但是这一切的工作都会在上级点击允许后自动运行!这就是工作流技术。
Georgakopoulos给出的工作流定义是:工作流是将一组任务组织起来以完成某个经营过程:定义了任务的触发顺序和触发条件,每个任务可以由一个或多个软件系统完成,也可以由一个或一组人完成,还可以由一个或多个人与软件系统协作完。
工作流技术的优点
从上面的例子,很容易看出,工作流系统实现了工作流程的自动化,提高了企业运营效率、改善企业资源利用、提高企业运作的灵活性和适应性、提高量化考核业务处理的效率、减少浪费(时间就是金钱)。而手工处理工作流程,一方面无法对整个流程状况进行有效跟踪、了解,另一方面难免会出现人为的失误和时间上的延时导致效率低下,特别是无法进行量化统计,不利于查询、报表及绩效评估。
工作流生命周期
除了我们自行启动(start)或者结束(finish)一个Activity,我们并不能直接控制一个 Activity的生命状态,我们只能通过实现Activity生命状态的表现——即回调方法来达到管理 Activity生命周期的变化。
说下原生JDBC操作数据库流程?
第一步:Class.forName()加载数据库连接驱动;
第二步:DriverManager.getConnection()获取数据连接对象;
第三步:根据SQL获取sql会话对象,有2种方式 Statement、PreparedStatement ;
第四步:执行SQL,执行SQL前如果有参数值就设置参数值setXXX();
第五步:处理结果集;
第六步:关闭结果集、关闭会话、关闭连接。
为什么要使用PreparedStatement?
PreparedStatement接口继承Statement,PreparedStatement实例包含已编译的SQL语句,所以其执行速度要快于Statement对象。
作为Statement的子类, PreparedStatement 继承了Statement的所有功能。三种方法execute、 executeQuery和executeUpdate已被更改以使之不再需要参数。
在 JDBC 应用中,多数情况下使用PreparedStatement,原因如下:
代码的可读性和可维护性。Statement需要不断地拼接,而PreparedStatement不会。
PreparedStatement尽最大可能提高性能。DB有缓存机制,相同的预编译语句再次被调用不会再次需要编译。
最重要的一点是极大地提高了安全性。Statement容易被SQL注入,而PreparedStatement传入的内容不会和sql 语句发生任何匹配关系。
http的长连接和短连接区别?
HTTP协议有HTTP/1.0版本和HTTP/1.1版本。HTTP1.1默认保持长连接(HTTP persistent connection,也翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。
在 HTTP/1.0 中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。从HTTP/1.1起,默认使用的是长连接,用以保持连接特性。
http中重定向和请求转发的区别?
本质区别:转发是服务器行为,重定向是客户端行为。
重定向特点:两次请求,浏览器地址发生变化,可以访问自己web之外的资源,传输的数据会丢失。
请求转发特点:一次请求,浏览器地址不变,访问的是自己本身的web资源,传输的数据不会丢失。\
Cookie 和 Session 的区别?
Cookie是web服务器发送给浏览器的一块信息,浏览器会在本地一个文件中给每个web服务器存储Cookie。以后浏览器再给特定的web服务器发送请求时,同时会发送所有为该服务器存储的Cookie。
Session是存储在web服务器端的一块信息。Session对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
Cookie和 Session的不同点:
无论客户端做怎样的设置,Session都能够正常工作。当客户端禁用Cookie时将无法使用Cookie。
在存储的数据量方面:Session能够存储任意的java对象,Cookie只能存储String类型的对象。
在单点登录中,如果cookie被禁用了怎么办?
单点登录的原理是后端生成一个sessionID,然后设置到cookie,后面的所有请求浏览器都会带上cookie,然后服务端从cookie里获取sessionID,再查询到用户信息。所以,保持登录的关键不是cookie,而是通过cookie保存和传输的sessionID,其本质是能获取用户信息的数据。除了cookie,还通常使用HTTP请求头来传输。但是这个请求头浏览器不会像cookie一样自动携带,需要手工处理。
什么是jsp,什么是Servlet?jsp 和Servlet 有什么区别?
jsp本质上就是一个Servlet,它是Servlet的一种特殊形式(由SUN公司推出),每个jsp页面都是一个servlet实例。Servlet是由Java提供用于开发web服务器应用程序的一个组件,运行在服务端,由servlet容器管理,用来生成动态内容。一个servlet实例是实现了特殊接口Servlet的Java类,所有自定义的servlet均必须实现Servlet接口。
区别:
jsp是html页面中内嵌的Java代码,侧重页面显示;
Servlet是html代码和Java代码分离,侧重逻辑控制,mvc设计思想中jsp位于视图层,servlet位于控制层
JVM只能识别Java类,并不能识别jsp代码!web容器收到以.jsp为扩展名的url请求时,会将访问请求交给tomcat中jsp引擎处理,每个jsp页面第一次被访问时,jsp引擎将jsp代码解释为一个servlet源程序,接着编译servlet源程序生成.class文件,再有web容器servlet引擎去装载执行servlet程序,实现页面交互。
jsp有哪些域对象和内置对象及他们的作用?
四大域对象:
pageContext page域-指当前页面,在当前jsp页面有效,跳到其它页面失效。
request request域-指一次请求范围内有效,从http请求到服务器处理结束,返回响应的整个过程。在这个过程中使用forward(请求转发)方式跳转多个jsp,在这些页面里你都可以使用这个变量。
session session域-指当前会话有效范围,浏览器从打开到关闭过程中,转发、重定向均可以使用。
applicationcontext域-指只能在同一个web中使用,服务器未关闭或者重启,数据就有效。
什么是xml,使用xml的优缺点,xml的解析器有哪几种,分别有什么区别?
xml是一种可扩展性标记语言,支持自定义标签(使用前必须预定义)使用DTD和XMLSchema标准化XML结构。
优点:用于配置文件,格式统一,符合标准;用于在互不兼容的系统间交互数据,共享数据方便;
缺点:xml文件格式复杂,数据传输占流量,服务端和客户端解析xml文件占用大量资源且不易维护
xml常用解析器有2种,分别是:DOM和SAX。主要区别在于它们解析xml文档的方式不同。使用DOM解析,xml文档以DOM树形结构加载入内存,而SAX采用的是事件模型。
谈谈你对ajax的认识?
Ajax是一种创建交互式网页应用的的网页开发技术;AsynchronousJavaScriptandXML的缩写。
Ajax的优势:通过异步模式,提升了用户体验。优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用。Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
Ajax的最大特点:可以实现局部刷新,在不更新整个页面的前提下维护数据,提升用户体验度。
jsonp原理是什么?
JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same-OriginPolicy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。
JavaScript这个安全策略在进行多iframe或多窗口编程、以及Ajax编程时显得尤为重要。根据这个策略,在baidu.com下的页面中包含的JavaScript代码,不能访问在google.com域名下的页面内容;甚至不同的子域名之间的页面也不能通过JavaScript代码互相访问。对于Ajax的影响在于,通过XMLHttpRequest实现的Ajax请求,不能向不同的域提交请求,例如,在abc.example.com下的页面,不能向def.example.com提交Ajax请求,等等。然而,当进行一些比较深入的前端编程的时候,不可避免地需要进行跨域操作,这时候“同源策略”就显得过于苛刻。JSONP跨域GET请求是一个常用的解决方案,下面我们来看一下JSONP跨域是如何实现的,并且探讨下JSONP跨域的原理。jsonp的最基本的原理是:动态添加一个<script>标签,使用script标签的src属性没有跨域的限制特点。首先在客户端注册一个callback,然后把callback的名字传给服务器。此时,服务器先生成json数据。然后以javascript语法的方式,生成一个function,function名字就是传递上来的参数jsonp。最后将json数据直接以入参的方式,放置到function中,这样就生成了一段js语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的javascript文档,此时数据作为参数,传入到了客户端预先定义好的callback函数里。
说一下常用的Linux命令?
列出文件列表:ls【参数 -a -l】
创建目录和移除目录:mkdir rmdir
用于显示文件后几行内容:tail
打包:tar -xvf
打包并压缩:tar -zcvf
查找字符串:grep
显示当前所在目录:pwd
创建空文件:touch
编辑器:vim vi
Linux中如何查看日志?
动态打印日志信息:tail –f 日志文件
Linux怎么关闭进程?
通常用ps查看进程PID,用kill命令终止进程。ps命令用于查看当前正在运行的进程。grep是搜索;-aux显示所有状态;
例如:
ps –ef | grep java表示查看所有进程里CMD是java的进程信息。
ps –aux | grep java
kill命令用于终止进程。例如:kill -9 [PID] -9表示强迫进程立即停止。
说一下EasyUI的认识?
EasyUI是一种基于jQuery的用户界面插件集合。easyui为创建现代化,互动,JavaScript应用程序,提供必要的功能。使用easyui你不需要写很多代码,你只需要通过编写一些简单HTML标记,就可以定义用户界面。优势:开源免费,页面也还说的过去。
说一下MiniUI的认识?
基于jquery的框架,开发的界面功能都很丰富。jQueryMiniUI-快速开发WebUI。它能缩短开发时间,减少代码量,使开发者更专注于业务和服务端,轻松实现界面开发,带来绝佳的用户体验。使用MiniUI,开发者可以快速创建Ajax无刷新、B/S快速录入数据、CRUD、Master-Detail、菜单工具栏、弹出面板、布局导航、数据验证、分页表格、树、树形表格等典型WEB应用系统界面。缺点:收费,没有源码,基于这个开发如果想对功能做扩展就需要找他们的团队进行升级!
说一下jQueryUI的认识?
jQueryUI是一套jQuery的页面UI插件,包含很多种常用的页面空间,例如Tabs(如本站首页右上角部分)、拉帘效果(本站首页左上角)、对话框、拖放效果、日期选择、颜色选择、数据排序、窗体大小调整等等非常多的内容。
说一下Vue.js的认识?
Vue.js(读音/vjuː/,类似于view)是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue采用自底向上增量开发的设计。Vue的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与单文件组件和Vue生态系统支持的库结合使用时,Vue也完全能够为复杂的单页应用程序提供驱动
说一下AngularJS的认识?
AngularJS是google开发者设计的一个前端开发框架,它是由是由JavaScript编写的一个JS框架。通常它是用来在静态网页构建动态应用不足而设计的。
SQL中聚合函数有哪些?
聚合函数是对一组值进行计算并返回单一的值的函数,它经常与select语句中的group by子句一同使用。
avg():返回的是指定组中的平均值,空值被忽略。
count():返回的是指定组中的项目个数。
max():返回指定数据中的最大值。
min():返回指定数据中的最小值。
sum():返回指定数据的和,只能用于数字列,空值忽略。
SQL之连接查询(左连接和右连接的区别)?
外连接:
左连接(左外连接):以左表作为基准进行查询,左表数据会全部显示出来,右表如果和左表匹配的数据则显示相应字段的数据,如果不匹配则显示为null。
右连接(右外连接):以右表作为基准进行查询,右表数据会全部显示出来,左表如果和右表匹配的数据则显示相应字段的数据,如果不匹配则显示为null。
全连接:先以左表进行左外连接,再以右表进行右外连接。
内连接:显示表之间有连接匹配的所有行。
SQL之sql注入是什么?
通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。举例:当执行的sql为select * from user where username = “admin” or “a” = “a”时,sql语句恒成立,参数username毫无意义。
防止sql注入的方式:
预编译语句:如,select * from user where username = ?,sql语句语义不会发生改变,sql语句中变量用?表示,即使传递参数时为“admin or ‘a’ = ‘a’”,也会把这整体当做一个字符串去查询,也就是当username等于这一串东西“admin or ‘a’ = ‘a’”时才会执行,而不是把这串东西当成sql语句。
Mybatis框架中的mapper方式中的#也能很大程度的防止sql注入($无法防止sql注入)。
MySQL性能优化有哪些?
当只要一行数据时使用limit 1
查询时如果已知会得到一条数据,这种情况下加上limit 1会增加性能。因为MySQL数据库引擎会在找到一条结果停止搜索,而不是继续查询下一条是否符合标准直到所有记录查询完毕。
选择正确的数据库引擎
MySQL中有两个引擎MyISAM和InnoDB,每个引擎有利有弊。MyISAM适用于一些大量查询的应用,但对于有大量写功能的应用不是很好。甚至你只需要update一个字段整个表都会被锁起来。而别的进程就算是读操作也不行要等到当前update操作完成之后才能继续进行。另外,MyISAM对于select count(*)这类操作是超级快的。InnoDB的趋势会是一个非常复杂的存储引擎,对于一些小的应用会比MyISAM还慢,但是支持“行锁”,所以在写操作比较多的时候会比较优秀。并且,它支持很多的高级应用,例如:事务。
用not exists代替not in
not exists用到了连接能够发挥已经建立好的索引的作用,not in不能使用索引。not in是最慢的方式要同每条记录比较,在数据量比较大的操作不建议使用这种方式。
对操作符的优化,尽量不采用不利于索引的操作符
如:in、not in、is null、is not null 、<> 等某个字段总要拿来搜索,为其建立索引:MySQL中可以利用alter table语句来为表中的字段添加索引,语法为:alter table表名add index(字段名)
MySQL 两种主要存储引擎了解吗?
MyISAM和InnoDB是最常见的两种存储引擎,特点如下。
MyISAM存储引擎
MyISAM是MySQL官方提供默认的存储引擎,其特点是不支持事务、表锁和全文索引,对于一些OLAP(联机分析处理)系统,操作速度快。
每个MyISAM在磁盘上存储成三个文件。文件名都和表名相同,扩展名分别是.frm(存储表定义)、.MYD(MYData,存储数据)、.MYI(MYIndex,存储索引)。这里特别要注意的是MyISAM不缓存数据文件,只缓存索引文件。
InnoDB存储引擎
InnoDB存储引擎支持事务,主要面向OLTP(联机事务处理过程)方面的应用,其特点是行锁设置、支持外键,并支持类似于Oracle的非锁定读,即默认情况下读不产生锁。InnoDB将数据放在一个逻辑表空间中(类似Oracle)。
InnoDB通过多版本并发控制来获得高并发性,实现了ANSI标准的4种隔离级别,默认为Repeatable,使用一种被称为next-keylocking的策略避免幻读。
MySQL存储引擎有哪些?
InnoDB存储引擎
MyISAM存储引擎
MEMORY存储引擎
NDB存储引擎
Memory存储引擎
Archive存储引擎
Federated存储引擎
Maria存储引擎
MySQL架构器中各个模块都是什么?
连接管理与安全验证
解析器是什么
优化器
执行器
MySQL事务介绍?
MySQL和其它的数据库产品有一个很大的不同就是事务由存储引擎所决定,例如MYISAM,MEMORY,ARCHIVE都不支持事务,事务就是为了解决一组查询要么全部执行成功,要么全部执行失败。MySQL事务默认是采取自动提交的模式,除非显示开始一个事务。
事务的四大特征是什么?
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
MySQL中四种隔离级别分别是什么?
读未提交
读已提交
可重复读
可串行化
存储过程?
MySQL存储过程是从MySQL5.0开始增加的新功能。存储过程的优点有一箩筐。不过最主要的还是执行效率和SQL代码封装。特别是SQL代码封装功能,如果没有存储过程,在外部程序访问数据库时,要组织很多SQL语句。特别是业务逻辑复杂的时候,一大堆的SQL和条件夹杂在代码中,让人不寒而栗。现在有了MySQL存储过程,业务逻辑可以封装存储过程中,这样不仅容易维护,而且执行效率也高。
MySQL触发器?
MySQL包含对触发器的支持。触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。
where子句中可以对字段进行null值判断吗?
可以,比如 select id from t where num is null 这样的sql也是可以的。但是最好不要给数据库留NULL,尽可能的使用NOT NULL填充数据库。不要以为NULL不需要空间,比如:char(100) 型,在字段建立时,空间就固定了,不管是否插入值(NULL 也包含在内),都是占用100个字符的空间的,如果是varchar 这样的变长字段,null 不占用空间。可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num= 0。
select * from admin left join log on admin.admin_id = log.admin_id where log.admin_id>10 如何优化?
优 化 为 : select * from (select * from admin where admin_id>10) T1 left join log on T1.admin_id =log.admin_id。使用 JOIN 时候,应该用小的结果驱动大的结果(left join 左边表结果尽量小如果有条件应该放到左边先处理, right join同理反向),同时尽量把牵涉到多表联合的查询拆分多个 query(多个连表查询效率低,容易到之后锁表和阻塞)。
什么是存储过程,使用存储过程的好处?
存储过程(StoredProcedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
允许模块化程序设计,就是说只需要创建一次过程,以后在程序中就可以调用该过程任意次。
允许更快执行,如果某操作需要执行大量SQL语句或重复执行,存储过程比SQL语句执行的要快。
减少网络流量,例如一个需要数百行的SQL代码的操作有一条执行语句完成,不需要在网络中发送数百行代码。
更好的安全机制,对于没有权限执行存储过程的用户,也可授权他们执行存储过程。
如何使用Oracle的游标?
Oracle中的游标分为显示游标和隐式游标
显示游标是用cursor…is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;
隐式游标是在执行插入(insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。
显式游标的操作:打开游标、操作游标、关闭游标;PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它。
Oracle中字符串用什么连接?
Oracle中使用||这个符号连接字符串如‘abc’||‘d’的结果是abcd。
Oracle中是如何进行分页查询的?
Oracle中使用rownum来进行分页,这个是效率最好的分页方法,hibernate也是使用rownum来进行Oralce分页的。
存储过程和存储函数的特点和区别?
特点:
1、一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
2、对于存储过程来说可以返回参数,而函数只能返回值或者表对象。
3、存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。
区别:
1、函数必须有返回值,而过程没有。
2、函数可以单独执行.而过程必须通过execute执行。
3、函数可以嵌入到SQL语句中执行,而过程不行。
其实我们可以将比较复杂的查询写成函数.然后到存储过程中去调用这些函数。
存储过程与SQL的对比?
优势:
1、提高性能
SQL语句在创建过程时进行分析和编译。存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划,这样,在执行过程时便可节省此开销。
2、降低网络开销
存储过程调用时只需用提供存储过程名和必要的参数信息,从而可降低网络的流量。
3、便于进行代码移植
数据库专业人员可以随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提高了程序的可移植性。
4、更强的安全性
(1)可以对过程进行加密,这有助于对源代码进行模糊处理。
(2)使用过程参数有助于避免SQL注入攻击。因为参数输入被视作文字值而非可执行代码,所以,攻击者将命令插入过程内的Transact-SQL语句并损害安全性将更为困难。
(3)在通过网络调用过程时,只有对执行过程的调用是可见的。因此,恶意用户无法看到表和数据库对象名称、嵌入自己的Transact-SQL语句或搜索关键数据。
(4)系统管理员可以对执行的某一个存储过程进行权限限制,避免非授权用户对数据的访问。
劣势:
1、存储过程需要专门的数据库开发人员进行维护,但实际情况是,往往由程序开发员人员兼职。
2、设计逻辑变更,修改存储过程没有SQL灵活。
你觉得存储过程和SQL语句该使用哪个?
在一些高效率或者规范性要求比较高的项目,建议采用存储过程。
对于一般项目建议采用参数化命令方式,是存储过程与SQL语句一种折中的方式。
对于一些算法要求比较高,涉及多条数据逻辑,建议采用存储过程。
触发器的作用有哪些?
触发器可通过数据库中的相关表实现级联更改;通过级联引用完整性约束可以更有效地执行这些更改。
触发器可以强制比用CHECK约束定义的约束更为复杂的约束。与CHECK约束不同,触发器可以引用其它表中的列。例如,触发器可以使用另一个表中的SELECT比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。
触发器还可以强制执行业务规则。
触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
在千万级的数据库查询中,Java如何提高效率?
1、尽可能的少造对象。
2、合理摆正系统设计的位置。大量数据操作,和少量数据操作一定是分开的。大量的数据操作,肯定不是ORM框架搞定的。
3、使用jDBC链接数据库操作数据。
4、控制好内存,让数据流起来,而不是全部读到内存再处理,而是边读取边处理。
5、合理利用内存,有的数据要缓存。
在千万级的数据库查询中,数据库设计方面如何提高效率?
1、对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引。
2、应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0
3、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
4、索引并不是越多越好,索引固然可以提高相应的select的效率,但同时也降低了insert及update的效率,因为insert或update时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
5、应尽可能的避免更新索引数据列,因为索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新索引数据列,那么需要考虑是否应将该索引建为索引。
6、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
7、尽可能的使用varchar/nvarchar代替char/nchar,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
8、尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
9、避免频繁创建和删除临时表,以减少系统表资源的消耗。
10、临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
11、在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免造成大量log,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
12、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。
在千万级的数据库查询中,SQL语句方面如何提高效率?
1、应尽量避免在where子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
2、应尽量避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num=10 or num=20可以这样查询:select id from t where num=10 union all select id from t where num=20
3、in和not in也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)对于连续的数值,能用between就不要用in了:select id from t where num between 1 and 3
4、下面的查询也将导致全表扫描:select id from t where name like ‘%abc%’
5、如果在where子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:select id from t where num=@num可以改为强制查询使用索引:select id from t with(index(索引名)) where num=@num
6、应尽量避免在where子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:select id from t where num/2=100应改为:select id from t where num=100*2
7、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:select id from t where substring(name,1,3)=‘abc’–name以abc开头的id select id from t where date diff(day,createdate,’2005-11-30′)=0–‘2005-11-30’生成的id应为:select id from t where name like ‘abc%’ select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′
8、不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
9、不要写一些没有意义的查询,如需要生成一个空表结构:select col1,col2 into # t from t where 1=0这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:create table # t(…)
10、很多时候用exists代替in是一个好的选择:select num from a where num in(select num from b)用下面的语句替换:select num from a where exists(select 1 from b where num=a.num)
11、任何地方都不要使用select * from t,用具体的字段列表代替星号,不要返回用不到的任何字段。
12、尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
13、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
14、尽量避免大事务操作,提高系统并发能力。
SpringMVC常用注解都有哪些?
@RequestMapping用于请求url映射。
@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象。
@ResponseBody注解实现将controller方法返回对象转化为json响应给客户。
如何开启注解处理器和适配器?
我们在项目中一般会在springmvc.xml中通过开启<mvc:annotation-driven>来实现注解处理器和适配器的开启。
SpringMVC的工作原理?
用户向服务器发送请求,请求被springMVC前端控制器DispatchServlet捕获;
DispatcherServle对请求URL进行解析,得到请求资源标识符(URL),然后根据该URL调用HandlerMapping将请求映射到处理器HandlerExcutionChain;
DispatchServlet根据获得Handler选择一个合适的HandlerAdapter适配器处理;
Handler对数据处理完成以后将返回一个ModelAndView对象给DisPatchServlet;
Handler返回的ModelAndView只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver试图解析器将逻辑视图转化为真正的视图View;
DispatcherServle通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端;
如何解决get和post乱码问题?
解决post请求乱码:我们可以在web.xml里边配置一个CharacterEncodingFilter过滤器。设置为utf-8.
解决get请求的乱码:有两种方法。对于get请求中文参数出现乱码解决方法有两个:
修改tomcat配置文件添加编码与工程编码一致。
另 外 一 种 方 法 对 参 数 进 行 重 新 编 码 String userName = new String(request.getParameter(“userName”).getBytes(“ISO8859-1”),“utf-8”);
谈谈你对Spring的理解?
Spring是一个开源框架,为简化企业级应用开发而生。Spring可以是使简单的JavaBean实现以前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。
Spring容器的主要核心是:
控制反转(IOC),传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象。而在spring开发模式中,spring容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring使用JavaBean对象的set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP底层是动态代理,如果是接口采用JDK动态代理,如果是类采用CGLIB方式实现动态代理
Spring中的设计模式有哪些?
单例模式——spring中两种代理方式,若目标对象实现了若干接口,spring使用jdk的java.lang.reflect.Proxy类代理。若目标兑现没有实现任何接口,spring使用CGLIB库生成目标类的子类。单例模式——在spring的配置文件中设置bean默认为单例模式。
模板方式模式——用来解决代码重复的问题。比如:RestTemplate、JmsTemplate、JpaTemplate
前端控制器模式——spring提供了前端控制器DispatherServlet来对请求进行分发。
试图帮助(viewhelper)——spring提供了一系列的JSP标签,高效宏来帮助将分散的代码整合在试图中。
依赖注入——贯穿于BeanFactory/ApplacationContext接口的核心理念。
工厂模式——在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用同一个接口来指向新创建的对象。Spring中使用beanFactory来创建对象的实例。
Spring的常用注解?
Spring在2.5版本以后开始支持注解的方式来配置依赖注入。可以用注解的方式来代替xml中bean的描述。注解注入将会被容器在XML注入之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。
注解装配在spring中默认是关闭的。所以需要在spring的核心配置文件中配置一下才能使用基于注解的装配模式。配置方式如下:<context:annotation-config/>
常用的注解:
@Required:该注解应用于设值方法。
@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。
@Qualifier:该注解和@Autowired搭配使用,用于消除特定bean自动装配的歧义。
简单介绍一下spring bean的生命周期的属性方法?
bean定义:在配置文件里面用<bean></bean>来进行定义。
bean初始化:有两种方式初始化:
1、在配置文件中通过指定init-method属性来完成。
2、实现org.springframwork.beans.factory.InitializingBean接口。
bean调用:有三种方式可以得到bean实例,并进行调用
bean销毁:销毁有两种方式:
1、使用配置文件指定的destroy-method属性。
2、实现org.springframwork.bean.factory.DisposeableBean。
Spring结构图了解吗?
Spring能帮我们做什么?
Spring能帮我们根据配置文件创建及组装对象之间的依赖关系。
Spring根据配置文件来进行创建及组装对象间依赖关系,只需要改配置文件即可
Spring面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
Spring面向切面编程能提供一种更好的方式来完成,一般通过配置方式,而且不需要在现有代码中添加任何额外代码,现有代码专注业务逻辑。
Spring能非常简单的帮我们管理数据库事务。
采用Spring,我们只需获取连接,执行SQL,其他事物相关的都交给Spring来管理了。
Spring还能与第三方数据库访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板,来方便数据库访问。
Spring还能与第三方Web(如Struts、JSF)框架无缝集成,而且自己也提供了一套SpringMVC框架,来方便web层搭建。
Spring能方便的与JavaEE(如JavaMail、任务调度)整合,与更多技术整合(比如缓存框架)。
请描述一下Spring的事务?
声明式事务管理的定义:用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可,这样维护起来极其方便。
基于TransactionInterceptor的声明式事务管理:两个次要的属性:transactionManager,用来指定一个事务治理器,并将具体事务相关的操作请托给它;其他一个是Properties类型的transactionAttributes属性,该属性的每一个键值对中,键指定的是方法名,方法名可以行使通配符,而值就是表现呼应方法的所运用的事务属性。
BeanFactory常用的实现类有哪些?
Bean工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离。常用的BeanFactory实现有DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。XMLBeanFactory,最常用的就是org.springframework.beans.factory.xml.XmlBeanFactory,它根据XML文件中的定义加载beans。该容器从XML文件读取配置元数据并用它去创建一个完全配置的系统或应用。
简单介绍一下SpringWEB模块?
Spring的WEB模块是构建在applicationcontext模块基础之上,提供一个适合web应用的上下文。这个模块也包括支持多种面向web的任务,如透明地处理多个文件上传请求和程序级请求参数的绑定到你的业务对象。它也有对JakartaStruts的支持。
Spring配置文件有什么作用?
Spring配置文件是个XML文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。
什么是SpringIOC容器?
IOC控制反转:SpringIOC负责创建对象,管理对象。通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
IOC的优点是什么?
IOC或依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
解释SpringDAO?
Spring-DAO并非Spring的一个模块,它实际上是指示你写DAO操作、写好DAO操作的一些规范。因此,对于访问你的数据它既没有提供接口也没有提供实现更没有提供模板。在写一个DAO的时候,你应该使用@Repository对其进行注解,这样底层技术(JDBC,Hibernate,JPA,等等)的相关异常才能一致性地翻译为相应的DataAccessException子类。
解释SpringJDBC?
Spring-JDBC提供了Jdbc模板类,它移除了连接代码以帮你专注于SQL查询和相关参数。Spring-JDBC还提供了一个JdbcDaoSupport,这样你可以对你的DAO进行扩展开发。它主要定义了两个属性:一个DataSource和一个JdbcTemplate,它们都可以用来实现DAO方法。JdbcDaoSupport还提供了一个将SQL异常转换为SpringDataAccessExceptions的异常翻译器。
解释SpringORM?
Spring-ORM是一个囊括了很多持久层技术(JPA,JDO,Hibernate,iBatis)的总括模块。对于这些技术中的每一个,Spring都提供了集成类,这样每一种技术都能够在遵循Spring的配置原则下进行使用,并平稳地和Spring事务管理进行集成。
对于每一种技术,配置主要在于将一个DataSourcebean注入到某种SessionFactory或者EntityManagerFactory等bean中。纯JDBC不需要这样的一个集成类(JdbcTemplate除外),因为JDBC仅依赖于一个DataSource。
如果你计划使用一种ORM技术,比如JPA或者Hibernate,那么你就不需要Spring-JDBC模块了,你需要的是这个Spring-ORM模块。
ApplicationContext的实现类有哪些?
FileSystemXmlApplicationContext:此容器从一个XML文件中加载beans的定义,XMLBean配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
BeanFactory与AppliacationContext有什么区别?
BeanFactory
基础类型的IOC容器,提供完成的IOC服务支持。如果没有特殊指定,默认采用延迟初始化策略。相对来说,容器启动初期速度较快,所需资源有限。
ApplicationContext
ApplicationContext是在BeanFactory的基础上构建,是相对比较高级的容器实现,除了BeanFactory的所有支持外,ApplicationContext还提供了事件发布、国际化支持等功能。ApplicationContext管理的对象,在容器启动后默认全部初始化并且绑定完成。
什么是Spring的依赖注入?
平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。
有哪些不同类型的IOC(依赖注入)方式?
Spring提供了多种依赖注入的方式。
set注入
构造器注入
静态工厂的方法注入
实例工厂的方法注入
什么是Springbeans?
Springbeans是那些形成Spring应用的主干的java对象。它们被SpringIOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/>的形式定义。Spring框架定义的beans都是单例beans。
一个SpringBeans的定义需要包含什么?
一个SpringBean的定义包含容器必知的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。
你怎样定义类的作用域?
当定义一个<bean>在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope属性必须设为singleton。
Spring框架中的单例bean是线程安全的吗?
Spring框架中的单例bean不是线程安全的。
什么是Spring的内部bean?
当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义innerbean,在Spring的基于XML的配置元数据中,可以在<property/>或<constructor-arg/>元素内使用<bean/>元素,内部bean通常是匿名的,它们的Scope一般是prototype。
什么是bean的自动装配?
无须在Spring配置文件中描述javaBean之间的依赖关系(如配置<property>、<constructor-arg>)。IOC容器会自动建立javabean之间的关联关系。
什么是基于Java的Spring注解配置?
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。以@Configuration注解为例,它用来标记类可以当做一个bean的定义,被SpringIOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
什么是基于注解的容器配置?
相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
怎样开启注解装配?
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置<context:annotation-config/>元素。
在Spring框架中如何更有效地使用JDBC?
使用SpringJDBC框架,资源管理和错误处理的代价都会被减轻。所以开发者只需写statements和queries从数据存取数据,JDBC也可以在Spring框架提供的模板类的帮助下更有效地被使用,这个模板叫JdbcTemplate。JdbcTemplate类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。
使用Spring通过什么方式访问Hibernate?
在Spring中有两种方式访问Hibernate:
控制反转:HibernateTemplate和Callback。
继承HibernateDAOSupport提供一个AOP拦截器。
Spring支持的ORM框架有哪些?
Spring支持以下ORM框架:
Hibernate
MyBatis
JPA (Java Persistence API)
TopLink
JDO (Java Data Objects)
OJB
在Spring AOP中,关注点和横切关注的区别是什么?
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
什么是连接点?
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
Spring的通知是什么?有哪几种类型?
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用五种类型的通知:
before:前置通知,在一个方法执行前被调用。
after:在方法执行之后调用的通知,无论方法执行是否成功。
after-returning:仅当方法成功完成后执行的通知。
after-throwing:在方法抛出异常退出时执行的通知。
around:在方法执行之前和之后调用的通知。
什么是切入点?
切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。
什么是目标对象?
被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。
什么是代理?
代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。
什么是织入?什么是织入应用的不同点?
把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象,这样的行为叫做织入。织入可以在编译时,加载时,或运行时完成。
简单解释一下Spring的AOP
AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此。这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
AOP技术恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为“Aspect”,即切面。所谓“切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
解释不同方式的自动装配?
有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
no:默认的方式是不进行自动装配,通过显式设置ref属性来进行装配。
byName:通过参数名自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
constructor:这个方式类似于byType,但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。
在Spring中如何注入一个java集合?
Spring提供以下几种集合的配置元素:
<list>类型用于注入一列值,允许有相同的值。
<set>类型用于注入一组值,不允许有相同的值。
<map>类型用于注入一组键值对,键和值都可以为任意类型。
<props>类型用于注入一组键值对,键和值都只能为String类型。
Spring支持bean的作用域有几种?
Spring框架支持以下五种bean的作用域:
singleton:bean在每个Springioc容器中只有一个实例。
prototype:一个bean的定义可以有多个实例。
request:每次http请求都会创建一个bean,该作用域仅在基于web的SpringApplicationContext情形下有效。
session:在一个HTTPSession中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext情形下有效。
global-session:在一个全局的HTTPSession中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext情形下有效。缺省的Springbean的作用域是Singleton。
Shiro的权限控制方式?
url级别权限控制
方法注解权限控制
代码级别权限控制
简单介绍一下Shiro框架?
Apache Shiro是Java的一个安全框架。使用Shiro可以非常容易的开发出足够好的应用。其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成功能:认证、授权、加密、会话管理、与Web集成、缓存等。
三个核心组件:Subject,SecurityManager和Realms
Subject:即“当前操作用户”。但是在Shiro中Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。Subject代表了当前用户的安全操作。
SecurityManager:它是管理所有用户的安全操作,是Shiro框架的核心,典型的Facade模式。Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
Realm:Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
Shiro主要的四个组件?
SecurityManager
典型的Facade,Shiro通过它对外提供安全管理的各种服务。
Authenticator
对“Who are you?”进行核实。通常涉及用户名和密码。这个组件负责收集principals 和credentials,并将它们提交给应用系统。如果提交的credentials跟应用系统中提供的 credentials吻合,就能够继续访问,否则需要重新提交principals和credentials,或者直 接终止访问。
Authorizer
身份份验证通过后,由这个组件对登录人员进行访问控制的筛查,比如“who can do what”,或者“who can do which actions”。Shiro采用“基于Realm”的方法,即用户 (又称Subject)、用户组、角色和permission的聚合体。
Session Manager
这个组件保证了异构客户端的访问,配置简单。它是基于POJO/J2SE的,不跟任何的 客户端或者协议绑定。
什么是粗颗粒和细颗粒权限?
对资源类型的管理称为粗颗粒度权限控制,即只控制到菜单、按钮、方法。粗粒度的例子比如:用户具有用户管理的权限,具有导出订单明细的权限。
对资源实例的控制称为细颗粒度权限管理,即控制到数据级别的权限,比如:用户只允许修改本部门的员工信息,用户只允许导出自己创建的订单明细。
总结:
粗颗粒权限:针对url链接的控制。
细颗粒权限:针对数据级别的控制。
比如:卫生局可以查询所有用户,卫生室只可以查询本单位的用户。
粗颗粒和细颗粒如何授权?
对于粗颗粒度的授权可以很容易做系统架构级别的功能,即系统功能操作使用统一的粗颗粒度的权限管理。对于细颗粒度的授权不建议做成系统架构级别的功能,因为对数据级别的控制是系统的业务需求,随着业务需求的变更业务功能变化的可能性很大,建议对数据级别的权限控制在业务层个性化开发,比如:用户只允许修改自己创建的商品信息可以在service接口添加校验实现,service接口需要传入当前操作人的标识,与商品信息创建人标识对比,不一致则不允许修改商品信息。
粗颗粒权限:可以使用过虑器统一拦截url。
细颗粒权限:在service中控制,在程序级别来控制,个性化编程。
Shiro运行原理?
Application Code:应用程序代码,就是我们自己的编码,如果在程序中需要进行权限控制,需要调用Subject的API。
Subject:主体代表了当前用户。所有的Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager,可以将Subject当成一个门面,而真正执行者是SecurityManager。
SecurityManage:安全管理器,所有与安全有关的操作都会与SecurityManager交互,并且它管理所有的Subject。
Realm:域shiro是从Realm来获取安全数据(用户,角色,权限)。就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以 把Realm看成DataSource,即安全数据源。
#相当于对数据加上双引号,$相当于直接显示数据
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by#user_id#,如果传入的值是111,那么解析成sql时的值为order by"111",如果传入的值是id,则解析成的sql为order by "id".
$将传入的数据直接显示生成在sql中。如:order by$user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,如果传入的值是id,则解析成的sql为order by id.
#方式能够很大程度防止sql注入,$方式无法防止Sql注入。
$方式一般用于传入数据库对象,例如传入表名.
Mybatis的编程步骤是什么样的?
创建SqlSessionFactory
通过SqlSessionFactory创建SqlSession
通过sqlsession执行数据库操作
调用session.commit()提交事务
调用session.close()关闭会话
JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,使用数据库链接池可解决此问题。解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。解决: Mybatis 自动将 java 对象映射至 sql 语句。
对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。解决:Mybatis 自动将 sql 执行结果映射至 java 对象。
使用MyBatis的mapper接口调用时有哪些要求?
Mapper接口方法名和mapper.xml中定义的每个sql的id相同
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mapper.xml文件中的namespace即是mapper接口的类路径。
Mybatis中一级缓存与二级缓存?
一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当flush或close之后,该Session中的所有Cache就将清空。
二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache的HashMap存储,不同在于其存储作用域为Mapper(namespace),并且可自定义存储源,如Ehcache。作用域namespace是指对namespace所对应的配置文件中所有的select操作结果都缓存,这样不同线程之间就可以共用二级缓存。二级缓存可以设置返回的缓存对象策略:<cache readOnly=“true”>。当readOnly="true"时,表示二级缓存返回给所有调用者同一个缓存对象实例,调用者可以update获取的缓存实例,但是这样可能会造成其他调用者出现数据不一致的情况(因为所有调用者调用的是同一个实例)。当readOnly=“false”时,返回给调用者的是二级缓存总缓存对象的拷贝,即不同调用者获取的是缓存对象不同的实例,这样调用者对各自的缓存对象的修改不会影响到其他的调用者,即是安全的,所以默认是readOnly=“false”;
对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear。
MyBatis在insert插入操作时如何返回主键ID?
数据库为 MySql 时:
```
<insert id="insert" parameterType="com.test.User" keyProperty="userId" useGeneratedKeys="true">
```
“keyProperty”表示返回的id要保存到对象的属性中,“useGeneratedKeys”表示主键id为自增长模式。
数据库为Oracle时:
<insert id="insert" parameterType="com.test.User">
<selectKey resultType="INTEGER" order="BEFORE" keyProperty="userId">
SELECT SEQ_USER.NEXTVAL as userId from DUAL
</selectKey>
insert into user
(user_id, user_name, modified, state)
values
(#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{modified,jdbcType=TIMESTAMP},#{state,jdbcType=INTEGER})
</insert>
由于Oracle没有自增长这一说法,只有序列这种自增的形式,所以不能再使用“useGeneratedKeys”属性。而是使用<selectKey>将ID获取并赋值到对象的属性中,insert插入操作时正常插入id。
简单介绍一下Struts2?
Struts2框架是一个按照MVC设计模式设计的WEB层框架,是在Struts 1和WebWork的技术基础上进行了合并的全新的框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开。
我们可以把Struts2理解为一个大大的Servlet,而这个Servlet就是ActionServlet。Struts2在处理客户端请求时,会先读取web.xml配置文件,根据前端控制器将符合条件的请求分给各个不同的Action处理。在此之前,ActionServlet会把数据封装成一个JavaBean。
Struts2框架提供了许多的拦截器,在封装数据的过程中,我们可以对数据进行一些操作,例如:数据校验等等。当Action执行完后要返回一个结果视图,这个结果视图可以跟据struts2的配置文件中配置,选择转发或者重定向。
Struts2中Action配置的注意事项有哪些?
name包名称,在struts2的配置文件中,包名不能重复,name并不是真正包名,只是为了管理Action
namespace和<action>的name属性,决定Action的访问路径(以/开始)
extends继承哪个包,通常开发中继承struts-default包(struts-default包在struts-default.xml中定义)
拦截器和过滤器有哪些区别?
拦截器是基于java的反射机制的,而过滤器是基于函数回调
拦截器不依赖与servlet容器,而过滤器依赖与servlet容器
拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
拦截器可以访问action上下文、值栈里的对象,而过滤器不能
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。