Java基础总结--面试答案个人总结

答案为自己总结

1、面向对象的特征有哪些方面?

封装,继承,多态

封装: 就是类的私有化。将代码及处理数据绑定在一起的一种编程机制,该机制保证程序和数据不受外部干扰。

继承: 就是保留父类的属性,开扩新的东西。通过子类可以实现继承,子类继承父类的所有状态和行为,同时添加自身的状态和行为。Java中的类不支持多继承(一个儿子只能有一个爹),接口支持多继承,可以实现多个接口

多态: 是允许将父对象设置成为和一个和多个它的子对象相等的技术。包括重载和重写。重载为编译时多态,重写是运行时多态。
2、访问修饰符public,private,protected,以及不写(默认)时的区别?


3、String 是最基本的数据类型吗?

不是,String是引用数据类型
4、float f=3.4;是否正确?

不对, 3.4默认是int类型, int类型不能自动转换成float类型

float f = 3.4f 

float的指数范围为-127~128,而double的指数范围为-1023~1024
5、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

前者正确,后者有误

short类型的s1和int型的1相加,会自动提升为int型,但是左边用short接受,编译就会报错

但是 s1 += 1反编译过来其实是 s1 = (short) s1 + 1,所以不会有误
6、Java有没有goto?

有,但作为保留字(像break,return但是是没有用到的关键字)
7、int和Integer有什么区别?

8种基本数据类型: byte,short,int,long,float,double,char,true/false

int是基本数据类型,integer是引用数据类型

int使用时可以先不赋值,integer使用时要先赋值
8、&和&&的区别?

&和&&的两端表达式同时为真时,表达式的结果为真,只要有一端为假,那么表达式结果为假

& :两个条件比较时,不管前者为true或false,后者都会执行; 无论左边结果是什么,右边还是继续运算;

&&: 只有当前者为true时,后者才会执行; 当左边为假,右边不再进行运算

| 和 || 两端表达式同时为假时,表达式的结果为假,只要有一端为真,那么表达式结果为真

 | : 无论左边结果是什么,右边还是继续运算;

            ||:  当左边为真,右边不再进行运算。
9、解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。

堆区:专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中)

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身.

3.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。

栈区:对象实例在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。

1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中

2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。

3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.

静态区/方法区:

1.方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。

2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

3.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

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

Math.round() 将括号内的数+0.5之后,向下取值,即为12 

Math.round(-11.5) 为 -10
11、switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

*switch可作用于char byte short int 以及他们对应的包装类

 * switch不可作用于long double float boolean,包括他们的包装类

 * switch中可以是字符串类型,String(jdk1.7之后才可以作用在string上)

* switch中可以是枚举类型
12、用最有效率的方法计算2乘以8?

2 << 3,

因为将一个数左移n 位,就相当于乘以了2 的n 次方,那么,一个数乘以8 只要将其左移3 位即可,而位运算cpu 直接支持的,效率最高,所以,2 乘以8 等於几的最效率的方法是2 << 3。
13、数组有没有length()方法?String有没有length()方法?

有,没有

String有length属性
14、在Java中,如何跳出当前的多重嵌套循环?

可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环

如:  定义  ok:  标号

使用时在内层循环嵌套使用带有标号的break   break ok;  即可跳出当前多重循环
15、构造器(constructor)是否可被重写(override)?

不可以,可以被重载

重写: 方法名,参数,返回值均相同,方法体不同

重载: 方法名相同, 参数类型和个数不同, 返回类型可以相同也可以不同
16、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

对,equals比较的是内容值,  ==比较的是地址值
17、是否可以继承String类?

不可以,String类是被final修饰过的
18、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

值传递
19、String和StringBuilder、StringBuffer的区别?

String 字符串常量 

StringBuffer 字符串变量(线程安全) 

StringBuilder 字符串变量(非线程安全)

执行速度: StringBuilder > StringBuffer > String

1. String最慢的原因:

String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:

String str="abc";

System.out.println(str);

str=str+"de";

System.out.println(str);

如果运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的,首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。

而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

另外,有时候我们会这样对字符串进行赋值

String str="abc"+"de";

StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");

System.out.println(str);

System.out.println(stringBuilder.toString());

这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多,这是因为第1行中的操作和

String str="abcde";

是完全一样的,所以会很快,而如果写成下面这种形式

String str1="abc";

String str2="de";

String str=str1+str2;

那么JVM就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。

线程安全: StringBuilder是线程不安全的,而StringBuffer是线程安全的

如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

3. 总结

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

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

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

20、重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

重写: 方法名,参数,返回值均相同,方法体不同

重载: 方法名相同, 参数类型和个数不同, 返回类型可以相同也可以不同

21、描述一下JVM加载class文件的原理机制?

JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。 
  由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。最后JVM对类进行初始化,包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句。 
  类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从Java 2(JDK 1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。
22、char 型变量中能不能存贮一个中文汉字,为什么?

 * char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,

 * 所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在

* unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充

* 说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节
23、抽象类(abstract class)和接口(interface)有什么异同?

相同:  他们都不能被实例化; 接口的实现类或抽象类的子类都必须实现了接口或者抽象类的方法才能被实例化

不同:

1.  接口只有方法定义,不能在接口中写具体的实现,实现接口的类要实现接口所有的方法,抽象类可以有定义与具体的实现

2.  接口要实现,抽象类要继承,一个类可以实现多个接口, 但只能继承一个抽象类

3.  接口设计理念是"has - a"的关系, 抽象类的设计理念强调是"is - a"的关系

4. 接口中定义变量默认值是public static final 且要赋初值,方法必须是public,static,且只能是这两个; 抽象类中可以有自己的数据成员变量,也可以有非抽象的成员方法,而且成员变量默认为default。

这些成员变量可以在子类中被重新定义,也可以重新赋值,抽象方法(有abstract修饰)不能用peivate,static,synchronized,native等访问修饰符修饰,同时方法以分号结尾,并且不带花括号

5. 接口被运用于比较常用的功能,便于日后的维护或者添加删除方法;而抽象类更倾向于充当公共类的角色,不适用于对里面的代码进行修改


24、静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?


25、Java 中会存在内存泄漏吗,请简单描述。

会,例如创建了一个对象,但是一直没有用,但这个对象却一直被引用,GC无法对他进行回收,就会出现内存泄漏(递归)
26、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

不可以
27、阐述静态变量和实例变量的区别。

静态变量: 由static修饰,可以直接类名 调用,也可以对象调用, 而且所有对象的同一个类变量 都是共享同一块内存空间。

实例变量: 没有static修饰,必须创建对象后使用对象调用, 而且所有对象的同一个实例变量是共享不同的内存空间的。

静态变量是所有变量共有的,某一个对象将他的值改变了,其他对象再次取到的值就是改变后的值

实例变量则是私有的,某一对象将值改变,不影响其他对象的值

在创建实例对象的时候,内存中会为每一个实例对象的每一个非静态成员变量开辟一段内存空间,用来存储这个对象所有的非静态成员变量值。即使两个不同的实例对象是属于同一个类,它们的同名非静态成员变量在内存中占用的空间是不同的。 
       静态成员变量有所不同。所有的实例对象都共用一个静态变量,内存中只有同一处空间存放这个静态变量值的。因此,如果一个对象把静态变量值改了,另外一个对象再取静态变量值就是改过之后的值了。
28、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?

不可以, 静态方法是可以直接调用的, 而非静态方法只能先创建对象才能调用, 静态方法在调用非静态的时候有可能非静态方法还没有创建对象
29、如何实现对象克隆?

基本数据类型可以直接用=号赋值克隆,但是对象就不行了

int a = 10;

int b = a;   则把a克隆给b

要想实现对象克隆

    1. 实现Cloneable接口,调用Cloneable的clone方法(重写clone方法为public)

    2. 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下
30、String s = new String("xyz");创建了几个字符串对象?

2个对象. 

JVM首先是在字符串常量池中找"xzy" 字符串,如果没有创建字符串常量,然后放到常量池中,若已存在,则不需要创建;当遇到 new 时,还会在内存(不是字符串常量池中)上创建一个新的String对象,存储"xzy",并将内存上的String对象引用地址返回
31、接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?

可以继承接口, 

抽象类可以实现抽象类

抽象类可以继承具体抽象类,也可以继承抽象类
32、一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制?

可以有多个类,但只能有一个public类
33、Anonymous Inner Class(匿名内部类)是否可以继承其它类?是否可以实现接口?

匿名内部类不能继承其他类,不可以实现接口,但他可以作为接口供其他类实现
34、内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?

如果不是静态内部类,完全可以。那没有什么限制!

在静态内部类下,不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员
35、Java 中的final关键字有哪些用法?

(1)修饰类:表示该类不能被继承;

(2)修饰方法:表示方法不能被重写;

(3)修饰变量:表示变量只能赋值一次且赋值以后值不能被修改(常量)。
36、数据类型之间的转换:

基本数据类型可以将低级的自动转换为高级的数据类型
37、如何实现字符串的反转及替换?

      可用字符串构造一 StringBuffer 对象,然后调用 StringBuffer 中的 reverse方法即可实现字符串的反转,调用 replace 方法即可实现字符串的替换。

38、怎样将GB2312编码的字符串转换为ISO-8859-1编码的字符串?

 String result = new String(s.getBytes("GB2312"),"iso-8859-1");

String类中getBytes(”编码“)方法可以将一个数用指定的编码转成一个字节数组,String中通过指定的 charset解码指定的 byte 数组,构造一个新的 String
39、日期和时间:
40、打印昨天的当前时刻。

1. 使用calendar类

Calendar cal = Calendar.getInstance();

cal.add(Calendar.DATE, -1);

2. java8中的方法

LocalDateTime today = LocalDateTime.now();

LocalDateTime yesterday = today.minusDays(1);

41、比较一下Java和JavaSciprt。

Java是面向对象的一门语言,javaScript是脚本语言,其中可以写Java代码
42、什么时候用断言(assert)?
43、Error和Exception有什么区别?

Error类和Exception类的父类都是throwable类

Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。

Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。

Exception类又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception ),运行时异常;ArithmaticException,IllegalArgumentException,编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用try。。。catch捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不会通过。

44、try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后?

会执行, 在return后执行
45、Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

try块表示程序正常的业务执行代码。如果程序在执行try块的代码时出现了“非预期”情况,JVM将会生成一个异常对象,这个异常对象将会被后面相应的catch块捕获。

catch块表示一个异常捕获块。当程序执行try块引发异常时,这个异常对象将会被后面相应的catch块捕获。

throw用于手动地抛出异常对象。throw后面需要一个异常对象。

throws用于在方法签名中声明抛出一个或多个异常类,throws关键字后可以紧跟一个或多个异常类。

finally块代表异常处理流程中总会执行的代码块。

对于一个完整的异常处理流程而言,try块是必须的,try块后可以紧跟一个或多个catch块,最后还可以带一个finally块。

try块中可以抛出异常。

46、运行时异常与受检异常有何异同?

RuntimeException在默认情况下会得到自动处理。所以通常用不着捕获RuntimeException,但在自己的封装里,也许仍然要选择抛出一部分RuntimeException。

 除了runtimeException以外的异常,都属于checkedException,它们都在java.lang库内部定义。Java编译器要求程序必须捕获或声明抛出这种异常。

一个方法必须通过throws语句在方法的声明部分说明它可能抛出但并未捕获的所有checkedException。

47、列出一些你常见的运行时异常?

ClassCastException,IndexOutOfBoundsException,

NullPointerException, NumberFormatException, 

StringIndexOutOfBoundsException
48、阐述final、finally、finalize的区别。

final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。

finally是异常处理语句结构的一部分,表示总是执行。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

49、类ExampleA继承Exception,类ExampleB继承ExampleA。
请问执行此段代码的输出是什么?


50、List、Set、Map是否继承自Collection接口?

list,set 是, map不是
51、阐述ArrayList、Vector、LinkedList的存储性能和特性。

  ArrayList 和Vector他们底层的实现都是一样的,都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢。

Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此已经是Java中的遗留容器。

 LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

 Vector属于遗留容器(Java早期的版本中提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)。
52、Collection和Collections的区别?

Collection是集合的接口,而Collections是工具类
53、List、Map、Set三个接口存取元素时,各有什么特点?

list: 可存入重复数据  add()添加, get(index)取

map: key不可重复,value可以重复   put()存  get(key)取

set: 不允许重复   add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true;当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。
54、TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?

TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。

Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象必须实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java中对函数式编程的支持)。
55、Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?

sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态,请参考第66题中的线程状态转换图)。

wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

56、线程的sleep()方法和yield()方法有什么区别?

sleep()方法和yield()方法都是Thread类的静态方法,都会使当前处于运行状态的线程放弃CPU,把运行机会让给别的线程。两者的区别在于:

1. sleep()方法会给其他线程运行的机会,不考虑其他线程的优先级,因此会给较低优先级线程一个运行的机会;yield()方法只会给相同优先级或者更高优先级的线程一个运行的机会。

2. 当线程执行了sleep(long millis)方法,将转到阻塞状态,参数millis指定睡眠时间;当线程执行了yield()方法,将转到就绪状态。

3. sleep()方法声明抛出InterruptedException异常,而yield()方法没有声明抛出任何异常。

4. sleep()方法比yield()方法具有更好的可移植性。不能依靠yield()方法来提高程序的并发性能。

57、当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?

不可以访问该对象的其他synchronized方法,
58、请说出与线程同步以及线程调度相关的方法。

- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;

- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常; 

- notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;

- notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

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

extends Thread 

implements Runnable   

implements Callable

Runnable和Callable的区别是, 
(1)Callable规定的方法是call(),Runnable规定的方法是run()。 
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得 
(3)call方法可以抛出异常,run方法不可以 
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。

另外不推荐继承Thread类,因为Java是单继承的,继承了Thread之后就不能继承其他类了,但是可以实现多个接口
60、synchronized关键字的用法?

synchronized修饰方法和synchronized修饰代码块

61、举例说明同步和异步。

同步: 发送一个请求的时候,等待响应,不能发送另一个请求

异步: 发送完一个请求,不用等待其响应,可以发送另一请求

比如发短信和打电话, 发短信就属于异步方式,发送完后不用关心对方是否收到已查看,而打电话则不同,对方未接通,通话就不能连接
62、启动一个线程是调用run()还是start()方法?

start方法,run方法,  start方法内部实现了run方法
63、什么是线程池(thread pool)?

没有线程池的时候,每次需要用的时候都要创建一次, 增加了服务器负担, 但是线程池的出现,获取对象的时候只需要从线程池中拿一个,用完了再放回去,不需要频繁的创建对象

线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
64、线程的基本状态以及状态之间的关系?

基本状态有6种:

新建: new语句创建线程的对象处于等待状态,和其他Java对象一样,只分配了内存空间

等待: 线程在new之后,start之前,处于等待状态

就绪: 当一个线程对象创建后,其他线程调用他的start方法, 该线程处于就绪状态,处于这个状态的线程存在Java的可运行池中,等待分配CPU的使用权

运行: 占用CPU的执行权,执行程序代码, 如果计算机只有一个CPU,那么任何时刻只有这一个线程处于运行状态,只有就绪状态的线程才有机会进入这个状态

阻塞: 线程因为某些原因放弃CPU,暂时停止运行. 当线程处于阻塞状态时,Java虚拟机不会给其分配CPU,直到线程重新处于就绪状态,才有可能重新获取CPU的执行权

死亡: 当线程执行完run()方法中的代码,或者遇到了未捕获的异常,就会退出run()方法,此时就进入死亡状态,该线程结束生命周期。

处于阻塞状态的原因: 

1、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。

2、同步阻塞:运行的线程在获取对象同步锁时,若该同步锁被别的线程占用,则JVM会把线程放入锁池中。

3、其他阻塞:运行的线程执行Sleep()方法,或者发出I/O请求时,JVM会把线程设为阻塞状态。当Sleep()状态超时、或者I/O处理完毕时,线程重新转入就绪状态。

65、简述synchronized 和java.util.concurrent.locks.Lock的异同?

相同之处: lock能完成synchronized所有的功能

不同之处: synchronized可以自动释放锁,而lock需要手动再次释放锁(unLock()),并且必须在finally语句中(一旦出现异常也可以及时释放锁), lock比synchronized有更精确的线程语义和更好的性能。lock还有更强大的功能,比如他的tryLock()方法可以非阻塞方式去拿锁

tryLock()方法相比synchronized更灵活

调用tryLock方法时,若获取了锁,立即返回true,否则返回false

tryLock(Long timeout, TimeUnit timeUnit) ,若获取锁,立即返回true,若没有获取锁,等待给定的时间timeOut,若等待给定时间后仍未获取锁,返回false,若获取锁,返回true
66、Java中如何实现序列化,有什么意义?

实现java.io.Serializable接口

序列化就是把对象或属性转换成二进制文件, 用于socket间传输,而不会出现乱序的问题,保证数据传输准确性
67、Java中有几种类型的流?

从输入输出方面讲两种: 输入流. 输出流

从流的编码方式讲: 字节流, 字符流

字节流: InputStream 和OutPutStream

字符流: InputStreamReader 和OutPutStreamReader
68、写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。

      BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
      String line;
      StringBuilder stringBuilder = new StringBuilder();

      while ((line = reader.readLine()) != null) {
           stringBuilder = stringBuilder.append(line);  //把文件内容读取StringBuilder中
      }
            
      int a = 0;
      while((a = stringBuilder.indexOf(name)) != -1) { //获取name在文件中下标值
           stringBuilder = stringBuilder.delete(a, a + name.length()); //把符合下标之前的删除
           count++;
      }


69、如何用Java代码列出一个目录下所有的文件?

        String fileName = "D:/mybatis";
        List<String> list = new ArrayList<>();
        File file = new File(fileName);
        for (File tmp :file.listFiles()) {
            if (tmp.isDirectory()) {
                for (File tmp2:tmp.listFiles()) {
                    list.add(tmp2.getName());
                }
            }else  if (tmp.isFile()) {
                list.add(tmp.getName());
            }
        }


70、用Java的套接字编程实现一个多线程的回显(echo)服务器。


71、XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?

dtd文档定义类型和schema模式

本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的)

普通区别:

1.schema 是内容开放模型,可扩展,功能性强,而DTD可扩展性差。

2.shema 支持丰富的数据类型,而 DTD不支持元素的数据类型,对属性的类型定义也很有限。

3.schema 支持命名空间机制,而DTD不支持。

4.schema 可针对不同情况对整个XML 文档或文档局部进行验证;而 DTD缺乏这种灵活性。

5.schema 完全遵循XML规范,符合XML语法,可以和DOM结合使用,功能强大;而DTD 语法本身有自身的语法和要求,难以学习。

解析方式:

DOM解析, SAX解析, DOM4J解析,JDOM解析

72、你在项目中哪些地方用到了XML?

存储配置信息, 比如使用jdbc作为数据源连接数据库的时候,如果数据库的地址配置修改了,只需更改xml配置文件即可,不用去修改源码, 以及一系列的配置信息,全局参数,路径等,还有整合spring的配置文件, 配置数据供程序加载使用

数据存储,相当于小型数据库,存储dom4j
73、阐述JDBC操作数据库的步骤。

1.      注册驱动

Class.forName(“com.mysql.jdbc.Driver”); Class.forName函数的作用是根据类的名字将类装载到虚拟机中(并未实例化);这种方式也不会对具体的驱动类产生依赖   推荐使用反射

或者直接注册  DriverManager.registerDriver(com.mysql.jdbc.Driver);

2.      建立连接       Connection conn=DriverManager.getConnection(url,uid,pwd);

     3.      创建执行sql语句的对象     PreparedStatement ps=conn.prepareStatement(strSql);(推荐PreparedStatement 防止sql注入)

    4.      执行语句

           查询:st.executeQuery(strSql);或者ps. executeQuery();

   非查询(增、删、改):st.executeUpdate(strSql);或ps.executeUpdate();

    5.      处理执行结果

查询:返回值用ResultSet接收,例:ResultSet rs=st.executeQuery(strsql)

   非查询(增、删、改):返回值为int

    6.      释放资源

依次释放ResultSet、Statement(或PreparedStatement)、Connection对象,释放顺序与创建顺序相反(类似“栈”结构)。

   注意,Connection是非常稀有的资源,用完必须马上释放,它的使用原则是尽量晚的创建,尽量早的释放,以减少占用资源的时间。

创建连接池更好的提高效率,不用频繁的创建连接,每次需要的时候在连接池中取一个,用完之后放回去

74、Statement和PreparedStatement有什么区别?哪个性能更好?

从安全方面考虑, PreparedStatement, 防止sql注入发生

在执行可变参数的一条sql时,PreparedStatement比Statement效率要高,因为预编译一次sql要比多次编译一条sql效率高

对于多次重复执行的sql,PreparedStatement效率要高很多

代码的可读性和可维护性
75、使用JDBC操作数据库时,如何提升读取数据的性能?如何提升更新数据的性能?

提升读数据的性能,可以使用j结果集对象ResultSet的setFetchSize()来设置每次读取数据的大小条数

提升更新数据的性能可以通过PreparedStatement来预编译sql语句,使用批处理
76、在进行数据库编程时,连接池有什么作用?

由于创建连接和释放连接都有很大的开销(尤其是数据库服务器不在本地时,每次建立连接都需要进行TCP的三次握手,释放连接需要进行TCP四次握手,造成的开销是不可忽视的)。

为了提升系统访问数据库的性能,可以事先创建若干连接置于连接池中,需要时直接从连接池获取,使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销,这是典型的用空间换取时间的策略(浪费了空间存储连接,但节省了创建和释放连接的时间)。
77、什么是DAO模式?

DataSource即和数据库打交道的, 数据连接,

通常的模式MVC模式, 表现层(controller), 业务逻辑层(service), 数据结构层(dao)
78、事务的ACID是指什么?

原子性(atomicity)、一致性(consistency)、隔离性 (isolation)和持久性(durability)的缩写。

原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。

一致性表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。

隔离性表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。

持久性表示已提交的数据在事务执行失败时,数据的状态都应该正确

通俗的讲就是事务操作就是要么全部成功, 要么全部不执行(银行扣转账务)
79、JDBC中如何进行事务处理?

JDBC的数据库操作中,事务相关操作就是不可分割的原子性操作, 操作成功后默认使用commit()提交, 否则使用rollback()回滚事务,也可以设置手动提交setAutoCommit(false)禁止自动提交
80、JDBC能否处理Blob和Clob?

可以, Blob是指大二进制对象(Binary Large Object),而Clob是指大字符对象(Character Large Objec),Blob是为存储大的二进制数据而设计的,而Clob是为存储大的文本数据而设计的。JDBC的PreparedStatement和ResultSet都提供了相应的方法来支持Blob和Clob操作。

81、简述正则表达式及其用途。

在编写处理字符串的程序时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
82、Java中是如何支持正则表达式操作的?

Java中的String类提供了支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。

此外,Java中可以用Pattern类表示正则表达式对象,它提供了丰富的API进行各种正则表达式操作
83、获得一个类的类对象有哪些方式?

类型.class    String.class;

Class.forName(java.lang.String);

对象.getClass()       String a = "a" ;    a.getClass();   A  a = new A();   a.getClass();
84、如何通过反射创建对象?

Class<?> clazz = Class.forName(String className);

Object obj = clazz.newInstance();
85、如何通过反射获取和设置对象私有字段的值?

Class<?> clazz = Class.forName(String className);

Object obj = clazz.newInstance();

获取私有变量的值

Field field = obj.getDeclaredField(fieldName);   

field.setAccessible(true); // 参数值为true,禁止访问控制检查

设置私有变量的值

Field field = obj.getDeclaredField(fieldName);

field.setAccessible(true);

field.set(instance, value);

访问私有方法

Method method = obj.getDeclaredMethod(methodName,Class[] classes);

method.setAccessible(true);

method.invoke(Object,args);

        Class<?> clazz = Class.forName("com.test.testdemo.User");
        //创建对象的实例
        User user = (User) clazz.newInstance();
        //直接调用对象的方法
        user.say("hahaha");
        Method[] methods = clazz.getMethods(); //获取所有方法
        Method method1 = clazz.getMethod("say", String.class); //获取指定方法
        method.setAccessible(true);
        method1.invoke(user, "1");   //执行方法  或者是clazz.newInstance()

        //获取私有属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field field:fields) {
            field.setAccessible(true);
            System.out.println(field.getName());
        }
        //获取指定私有属性
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);

86、如何通过反射调用对象的方法?

2种方式

        1. Class<?> clazz = Class.forName("com.test.testdemo.User");
          //创建对象的实例
         User user = (User) clazz.newInstance();
         //直接调用对象的方法
         user.say("hahaha");
    
        2. Method[] methods = clazz.getMethods(); //获取所有方法
        Method method1 = clazz.getMethod("say", String.class); //获取指定方法
        method.setAccessible(true);
        method1.invoke(user, "1");   //执行方法  或者是clazz.newInstance()


87、简述一下面向对象的"六原则一法则"。

单一职责原则 : 高内聚思想, 即一个类只专注一件事, 或者专注于某个功能, 可以达到软件复用的目的

开闭原则 : 软件实体应当对扩展开放,对修改关闭。在理想的状态下,当我们需要为一个软件系统增加新功能时,只需要从原来的系统派生出一些新类就可以,不需要修改原来的任何一行代码。需要有抽象和封装特性, 只需改超类就行

依赖倒转原则 :面向接口编程。该原则说得直白和具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代

里氏替换原则 :任何时候都可以用子类型替换掉父类型。

接口隔离原则 :接口要小而专,绝不能大而全,  臃肿的接口是对接口的污染, 接口定义应遵循高内聚,高可用

合成聚合复用原则: 优先使用聚合或合成关系复用代码。

迪米特法则: 迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。迪米特法则简单的说就是如何做到"低耦合",门面模式和调停者模式就是对迪米特法则的践行。
88、简述一下你了解的设计模式。

23种设计模式: Abstract Factory(抽象工厂模式),Builder(建造者模式),Factory Method(工厂方法模式),Prototype(原始模型模式),Singleton(单例模式);Facade(门面模式),Adapter(适配器模式),Bridge(桥梁模式),Composite(合成模式),Decorator(装饰模式),Flyweight(享元模式),Proxy(代理模式);Command(命令模式),Interpreter(解释器模式),Visitor(访问者模式),Iterator(迭代子模式),Mediator(调停者模式),Memento(备忘录模式),Observer(观察者模式),State(状态模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibility(责任链模式)。 

- -工厂模式:工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。 
- -代理模式:给一个对象提供一个代理对象,并由代理对象控制原对象的引用。实际开发中,按照使用目的的不同,代理可以分为:远程代理、虚拟代理、保护代理、Cache代理、防火墙代理、同步化代理、智能引用代理。 
- -适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。 
- 模板方法模式:提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。 
89、用Java写一个单例类。


public class Singleton {
    //用Java写一个单例类
    //饿汉式
    private Singleton(){}  //私有构造方法
    private static Singleton instance = new Singleton(); //不管怎么样,上来就先创建一个对象
    public static Singleton getInstance(){
        return instance;
    }
}
//懒汉式
class Singleton2 {
    private static Singleton2 instance = null;
    private Singleton2() {}  //私有构造方法
    public static synchronized Singleton2 getInstance(){
        if (instance == null)  instance = new Singleton2(); //如果没有就创建一个对象,以备后用
        return instance;
    }
}


90、什么是UML?

 统一建模语言UML是 Unified Modeling Language的缩写)是用来对软件密集系统进行可视化建模的一种语言。UML为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言。

  统一建模语言 (UML)是非专利的第三代建模和规约语言。 UML是在开发阶段,说明,可视化,构建和书写一个面向对象软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。
91、UML中有哪些常用的图?

活动图,状态图,用例图,类图,时序图,序列图,对象图,包图等等
92、用Java写一个冒泡排序。

        int[] arr = { 9, 3, 7, 10, 2 };        
        // 定义外层循环
        for (int i = 0; i < arr.length - 1; i++) {
            // 定义内层循环
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] < arr[j + 1]) { // 比较相邻元素
                    // 下面的三行代码用于交换两个元素
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.print("第" + (i + 1) + "轮排序后:");
            // 每轮比较结束打印数组元素
            for (int i2 = 0; i2 < arr.length; i2++) {
                System.out.print(arr[i2] + " "); // 打印元素和空格
            }
        }


93、用Java写一个折半查找。

        public static int Max = 20;
        // 数据数组源
        public static int data[] = { 12, 16, 19, 22, 25, 32, 39, 39, 48, 55, 57,58,63, 68, 69, 70, 78, 84, 88, 90, 97 };
        // 计数器
        public static int count = 1;   
        Scanner sc = new Scanner(System.in);
        int KeyValue = sc.nextInt();   
  
        int left = 0;// 左边界变量
        int right = Max - 1;// 右边界变量
        int middle;// 中位数变量
        while (left <= right) {
            middle = (left + right) / 2;
            if (k < data[middle]) {
                right = middle - 1;// 查找前半段
            } else if (k > data[middle]) {
                left = middle + 1;// 查找后半段
            } else if (k == data[middle]) {
                System.out.println("Data[" + middle + "] = " + data[middle]);
                return true;
            }
            count++;
        }


94、阐述Servlet和CGI的区别?

Servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每一个请求都产生新的进程,服务完成后就销毁,所以效率上低与Servlet。

servlet的生命周期:  Servlet从被Web服务器加载到它被销毁的整个生命过程, 分为3个阶段

初始化:  调用init()方法, 

响应客户端请求阶段: 调用service()方法, 

销毁阶段: 调用destory() 方法
95、Servlet接口中有哪些方法?

生命周期的三个方法:

init() : servlet实例化后,servlet容器会调用init()方法初始化对象, 在响应客户端请求之前做一些准备,数据库的连接,获取配置信息等. 每一个servlet实例只能调用一次init()方法   

service() : 用来处理客户端的请求, service()方法执行前,须确保init()方法正确完成,. 容器会构造一个用户获取客户端请求参数的ServletRequest对象参数和一个用来响应客户端请求的ServletResponse对象参数,把这两个参数传给service()方法, service方法中.servlet对象通过ServletRequest对象来获取客户端的相关信息和请求信息, 执行完请求后,通过ServletResponse对象设置响应信息

destory(): 当容器检测到一个Servlet对象应该从服务中被移除的时候,容器会调用该对象的destroy()方法,以便让Servlet对象可以释放它所使用的资源,保存数据到持久存储设备中,例如将内存中的数据保存到数据库中,关闭数据库的连接等. 当需要释放内存或者容器关闭时,容器就会调用Servlet对象的destroy()方法,在Servlet容器调用destroy()方法前,如果还有其他的线程正在service()方法中执行容器会等待这些线程执行完毕或者等待服务器设定的超时值到达。一旦Servlet对象的destroy()方法被调用,容器不回再把请求发送给该对象。如果需要改Servlet再次为客户端服务,容器将会重新产生一个Servlet对象来处理客户端的请求。在destroy()方法调用之后,容器会释放这个Servlet对象,在随后的时间内,该对象会被java的垃圾收集器所回收

getServletConfig(): 该方法返回容器调用init()方法时传递给Servlet对象的ServletConfig对象,ServletConfig对象包含了Servlet的初始化参数。

getServletInfo(): 返回一个String类型的字符串,其中包括了关于Servlet的信息,例如,作者、版本和版权。该方法返回的应该是纯文本字符串,而不是任何类型的标记。


96、转发(forward)和重定向(redirect)的区别?

请求转发:

    1. 是服务器内部的重定向,服务器直接访问目标地址的 url网址,把里面的东西读取出来,但是客户端并不知道,因此用forward的话,客户端浏览器的网址是不会发生变化的。 

  2.关于request: 由于在整个定向的过程中用的是同一个request,因此forward会将request的信息带到被重定向的jsp或者servlet中使用。

重定向:

1. 是客户端的重定向,是完全的跳转。即服务器返回的一个url给客户端浏览器,然后客户端浏览器会重新发送一次请求,到新的url里面,因此浏览器中显示的url网址会发生变化。 

2.因为这种方式比forward多了一次网络请求,因此效率会低于forward。
97、JSP有哪些内置对象?作用分别是什么?

Page,pageContext,request,response,session,application,out,config,exception

Page指的是JSP被翻译成Servlet的对象的引用.

pageContext对象可以用来获得其他8个内置对象,还可以作为JSP的域范围对象使用.pageContext中存的值是当前的页面的作用范围

request代表的是请求对象,可以用于获得客户机的信息,也可以作为域对象来使用,使用request保存的数据在一次请求范围内有效。

Session代表的是一次会话,可以用于保存用户的私有的信息,也可以作为域对象使用,使用session保存的数据在一次会话范围有效

Application:代表整个应用范围,使用这个对象保存的数据在整个web应用中都有效。

Response是响应对象,代表的是从服务器向浏览器响应数据.

Out:JSPWriter是用于向页面输出内容的对象

Config:指的是ServletConfig用于JSP翻译成Servlet后 获得Servlet的配置的对象.

Exception:在页面中设置isErrorPage=”true”,即可使用,是Throwable的引用.用来获得页面的错误信息。

98、get和post请求的区别? https://www.oschina.net/news/77354/http-get-post-different

  • GET在浏览器回退时是无害的,而POST会再次提交请求。

  • GET产生的URL地址可以被Bookmark,而POST不可以。

  • GET请求会被浏览器主动cache,而POST不会,除非手动设置。

  • GET请求只能进行url编码,而POST支持多种编码方式。

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

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

  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

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

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

99、常用的Web服务器有哪些?

Apache、Tomcat(apache旗下核心子项目)、Jboss(RedHat)、Resin(常整合tomcat用)、Weblogic(BEA收费商业)、WebSpher(IBM) 
100、JSP和Servlet是什么关系?

jsp本质是一个缺省的servlet

jsp侧重视图, servlet侧重逻辑

jsp由html 和java脚本组成, servlet由java编写


101、讲解JSP中的四种作用域。

JSP创建的对象有一定的生命周期,也有可能被其他组件或者对象访问。对象的声明周期和可访问性称为作用域。四种范围对象作用域从小到大顺序如下:pageContext----request----session----application。

pageContext:页面域

request:请求域

session:会话域

application: 应用域

102、如何实现JSP或Servlet的单线程模式?
103、实现会话跟踪的技术有哪些?
104、过滤器有哪些作用和用法?
105、监听器有哪些作用和用法?
106、web.xml文件中可以配置哪些内容?
107、你的项目中使用过哪些JSTL标签?
108、使用标签库有什么好处?如何自定义JSP标签?
109、说一下表达式语言(EL)的隐式对象及其作用。
110、表达式语言(EL)支持哪些运算符?


111、Java Web开发的Model 1和Model 2分别指的是什么?
112、Servlet 3中的异步处理指的是什么?
113、如何在基于Java的Web项目中实现文件上传和下载?
114、服务器收到用户提交的表单数据,到底是调用Servlet的doGet()还是doPost()方法?
115、JSP中的静态包含和动态包含有什么区别?
116、Servlet中如何获取用户提交的查询参数或表单数据?
117、Servlet中如何获取用户配置的初始化参数以及服务器上下文参数?
118、如何设置请求的编码以及响应内容的类型?
119、解释一下网络应用的模式及其特点。
120、什么是Web Service(Web服务)?


121、概念解释:SOAP、WSDL、UDDI。
122、Java规范中和Web Service相关的规范有哪些?
123、介绍一下你了解的Java领域的Web Service框架。
124、什么是ORM?
125、持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些?
126、Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?
127、Hibernate中Session的load和get方法的区别是什么?
128、Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分别是做什么的?有什么区别?
129、阐述Session加载实体对象的过程。
130、Query接口的list方法和iterate方法有什么区别?

 

131、Hibernate如何实现分页查询?
132、锁机制有什么用?简述Hibernate的悲观锁和乐观锁机制。
133、阐述实体对象的三种状态以及转换关系。
134、如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理的?
135、举一个多对多关联的例子,并说明如何实现多对多关联映射。
136、谈一下你对继承映射的理解。
137、简述Hibernate常见优化策略。
138、谈一谈Hibernate的一级缓存、二级缓存和查询缓存。
139、Hibernate中DetachedCriteria类是做什么的?
140、@OneToMany注解的mappedBy属性有什么作用?


141、MyBatis中使用<code>#</code>和<code>$</code>书写占位符有什么区别?
142、解释一下MyBatis中命名空间(namespace)的作用。
143、MyBatis中的动态SQL是什么意思?
144、什么是IoC和DI?DI是如何实现的?
145、Spring中Bean的作用域有哪些?
146、解释一下什么叫AOP(面向切面编程)?
147、你是如何理解"横切关注"这个概念的?
148、你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念?
149、Spring中自动装配的方式有哪些?
150、Spring中如何使用注解来配置Bean?有哪些相关的注解?


151、Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?
152、如何在Web项目中配置Spring的IoC容器?
153、如何在Web项目中配置Spring MVC?
154、Spring MVC的工作原理是怎样的?
155、如何在Spring IoC容器中配置数据源?
156、如何配置配置事务增强?
157、选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)?
158、Spring IoC容器配置Bean的方式?
159、阐述Spring框架中Bean的生命周期?
160、依赖注入时如何注入集合属性?

 

问题摘抄自微信公众平台,如有侵权,请联系删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java面试题真的很多,下面我来回答一个有关多线程的问题。 在Java中实现多线程有两种方式,一种是继承Thread类,另一种是实现Runnable接口。这两种方式有何区别? 继承Thread类的方式是直接定义一个类继承Thread,并重写它的run()方法。然后创建该类的对象,并调用对象的start()方法来启动线程。这种方式简单直接,但因为Java是单继承的,所以如果某个类已经继承了其他类,就不能再直接继承Thread类实现多线程。 实现Runnable接口的方式是定义一个类实现Runnable接口,并实现其唯一的抽象方法run()。然后创建Thread类的对象,将实现了Runnable的对象作为参数传递给Thread类的构造方法。最后调用Thread对象的start()方法来启动线程。这种方式灵活性更大,因为Java允许一个类实现多个接口,所以即使某个类已经继承了其他类,仍然可以通过实现Runnable接口来实现多线程。 另一个区别在于资源共享的问题。继承Thread类的方式,不管是数据还是方法,都是线程自己拥有的,不存在共享的情况。而实现Runnable接口的方式,多个线程可以共享同一个对象的数据和方法,因为多个线程共同操作的是同一个Runnable对象。 总结来说,继承Thread类方式简单直接,但只能通过单继承来实现多线程;实现Runnable接口方式更灵活,可以解决单继承的限制,并且多个线程可以共享同一个Runnable对象的数据和方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值