Java面试整理Word文档下载推荐.docx
《Java面试整理Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Java面试整理Word文档下载推荐.docx(22页珍藏版)》请在冰豆网上搜索。
激活类的静态变量,初始化Java代码和静态Java代码块
单例模式为什么能保证只有一个实例存在
原理在于它的构造函数是私有的,你不能去new它,
该单例类里面已经实例化好了一个了,并且是static的,并提供一个获取该实例的方法!
客户端只能通过该方法获取这个已经实例化好了的,这样就保证了只有一个实例存在!
建立sql索引应该遵循什么原则
索引字段建议建立NOTNULL约束
经常与其他表进行连接的表,在连接字段上应该建立索引;
经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引;
可选择性高的关键字,应该建立索引;
可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率
复合索引的建立需要进行仔细分析;
尽量考虑用单字段索引代替:
A、正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上;
B、复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;
否则单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
频繁DML的表,不要建立太多的索引;
不要将那些频繁修改的列作为索引列;
==与equals的区别
基本数据类型(也称原始数据类型):
byte,short,char,int,long,float,double,boolean。
他们之间的比较,应用双等号(==),比较的是他们的值。
复合数据类型(类):
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址(确切的说,是堆内存地址)。
注:
对于第二种类型,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。
因为每new一次,都会重新开辟堆内存空间。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
JSP页面的跳转?
jsp页面实现跳转主要有jsp:
forward和sendRedirect两种方法
jsp:
forward:
在本容器内跳转。
跳转后,地址栏地址不变。
效率高。
跳转后立即结束本页的内容。
sendRedirect:
在容器之间的跳转,跳转后地址栏地址为跳转后的地址,效率较低。
通常采用jsp:
forward方式跳转。
解释GLOBAL_NAMES设为TRUE的用途:
GLOBAL_NAMES指明联接数据库的方式。
如果这个参数设置为TRUE,在建立数据库链接时就必须用相同的名字连结远程数据库.
在Oracle数据库中,FUNCTION,PROCEDURE和PACKAGE区别
function
是函数有返回值
procedure
是存储过程无返回值
package是一种将过程、函数和数据结构捆绑在一起的容器;
包由两个部分组成:
外部可视包规范,包括函数头,过程头,和外部可视数据结构;
另一部分是包主体(packagebody),包主体包含了所有被捆绑的过程和函数的声明、执行、异常处理部分。
解释TABLEFunction的用途
TABLEFunction是通过PL/SQL逻辑返回一组纪录,用于普通的表/视图。
他们也用于pipeline和ETL过程。
数据库1,2,3范式的概念与理解
1NF的定义为:
符合1NF的关系中的每个属性都不可再分
2NF:
符合1NF,并且非主属性完全依赖于码
3NF:
符合2NF,并且,消除传递依赖
码:
表中可以唯一确定一个元组的某个属性(或者属性组),如果这样的码有不止一个,那么大家都叫候选码,我们从候选码中挑一个出来做老大,它就叫主码。
ORACLE临时表有两种类型:
会话级的临时表和事务级的临时表。
解释冷备份和热备份的不同点以及各自的优点
解答:
热备份针对归档模式的数据库,在数据库仍旧处于工作状态时进行备份。
而冷备份指在数据库关闭后,进行备份,适用于所有模式的数据库。
热备份的优点在于当备份时,数据库仍旧可以被使用并且可以将数据库恢复到任意一个时间点。
冷备份的优点在于它的备份和恢复操作相当简单,并且由于冷备份的数据库可以工作在非归档模式下,数据库性能会比归档模式稍好。
(因为不必将archivelog写入硬盘)
解释归档和非归档模式之间的不同和它们各自的优缺点
归档模式是指你可以备份所有的数据库transactions并恢复到任意一个时间点。
非归档模式则相反,不能恢复到任意一个时间点。
但是非归档模式可以带来数据库性能上的少许提高.
比较truncate和delete命令
两者都可以用来删除表中所有的记录。
区别在于:
truncate是DDL操作,它移动HWK,不需要rollbacksegment.而Delete是DML操作,需要rollbacksegment且花费较长时间.
使用索引的理由
数据库索引是为了增加查询速度而对表字段附加的一种标识。
首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。
如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。
创建索引
在执行CREATETABLE语句时可以创建索引,也可以单独用CREATEINDEX或ALTERTABLE来为表增加索引。
1.ALTERTABLE
ALTERTABLE用来创建普通索引、UNIQUE索引或PRIMARYKEY索引。
ALTERTABLEtable_nameADDINDEXindex_name(column_list)
ALTERTABLEtable_nameADDUNIQUE(column_list)
ALTERTABLEtable_nameADDPRIMARYKEY(column_list)
其中table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。
索引名index_name可选,缺省时,MySQL将根据第一个索引列赋一个名称。
另外,ALTERTABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。
2.CREATEINDEX
CREATEINDEX可对表增加普通索引或UNIQUE索引。
CREATEINDEXindex_nameONtable_name(column_list)
CREATEUNIQUEINDEXindex_nameONtable_name(column_list)
table_name、index_name和column_list具有与ALTERTABLE语句中相同的含义,索引名不可选。
另外,不能用CREATEINDEX语句创建PRIMARYKEY索引。
索引类型
根据数据库的功能,可以在数据库设计器中创建三种索引:
唯一索引、主键索引和聚集索引。
唯一索引:
不允许其中任何两行具有相同索引值的索引。
主键索引:
在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。
该索引要求主键中的每个值都唯一。
当在查询中使用主键索引时,它还允许对数据的快速访问。
聚集索引:
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。
一个表只能包含一个聚集索引。
如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。
与非聚集索引相比,聚集索引通常提供更快的数据访问速度。
2.垃圾回收机制(GC)
(1)简单回答:
Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。
需要注意的是:
垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身。
System.gc(),Runtime.getRuntime().gc()用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。
(2)什么时候会触发一个对象的回收?
a.
对象没有引用
b.
作用域发生未捕获异常
c.
程序在作用域正常执行完毕
d.
程序执行了System.exit()
e.
程序发生意外终止(被杀进程等)
(3)垃圾回收算法
a.引用计数器法:
在JDK1.2之前,使用的是引用计数器算法,即当这个类被加载到内存以后,就会产生方法区,堆栈、程序计数器等一系列信息,当创建对象的时候,为这个对象在堆栈空间中分配对象,同时会产生一个引用计数器,同时引用计数器+1,当有新的引用的时候,引用计数器继续+1,而当其中一个引用销毁的时候,引用计数器-1,当引用计数器被减为零的时候,标志着这个对象已经没有引用了,可以回收了。
b.根搜索算法:
程序把所有的引用关系看作一张图,从一个节点GCROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
目前java中可作为GCRoot的对象有
虚拟机栈中引用的对象(本地变量表)
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈中引用的对象(Native对象)
Java中存在四种引用:
a.强应用:
只要引用存在,垃圾回收器永远不会回收;
b.软引用:
非必须引用,内存溢出之前进行回收;
c.弱引用:
第二次垃圾回收时回收;
d.虚引用(幽灵/幻影引用):
垃圾回收时回收,无法通过引用取对象值
确定垃圾后,回收算法:
a.标记-清除算法
标记-清除算法采用从根集合进行扫描,对存活的对象标记,标记完毕后,再扫描整个空间中未被标记的对象,进行回收。
b.复制算法
复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中,这种算法当存活的对象比较少时,极为高效,但是带来的成本是需要一块内存交换空间用于进行对象的移动。
标记-整理算法
-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端空闲空间移动,并更新对应的指针。
标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。
JVM为了优化内存的回收,进行了分代回收的方式,高频访问新生代,低频访问老年代(大对象、长生命周期对象、以及新生代没有被回收的对象)。
3.多线程
三种实现方式:
(1).继承Thred类。
启动线程的唯一方法就是通过Thread类的start()实例方法。
start()方法是一个native方法,它将启动一个新线程,并执行run()方法。
这种方式实现多线程很简单,通过自己的类直接extendThread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
1.public
class
MyThread
extends
Thread
{
2. public
void
run()
3.
System.out.println("
MyThread.run()"
);
4. }
5.}
在合适的地方启动线程如下:
1.MyThread
myThread1
=
new
MyThread();
2.MyThread
myThread2
3.myThread1.start();
4.myThread2.start();
(2).实现Runnable接口
为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例:
OtherClass
implements
Runnable
[java]
viewplain
copy
myThread
2.Thread
thread
Thread(myThread);
3.thread.start();
(3).使用java.util.concurrent包下的ExecutorService、Callable、Future实现有返回结果的多线程
1.
//
创建一个线程池
2.
ExecutorService
pool
Executors.newFixedThreadPool(taskSize);
3.
创建多个有返回值的任务
4.
List<
Future>
list
ArrayList<
();
5.
for
(int
i
0;
<
taskSize;
i++)
6.
Callable
c
MyCallable(i
+
"
7.
执行任务并获取Future对象
8.
Future
f
pool.submit(c);
9.
>
f.get().toString());
10.
list.add(f);
11.
}
12.
关闭线程池
13.
pool.shutdown();
14.
15.
获取所有并发任务的运行结果
16.
(Future
:
list)
17.
从Future对象上获取任务的返回值,并输出到控制台
18.
19.
concurrent的优势:
(1)管理一组相关线程非常有用,有效的减少竞争条件(raceconditions)和死锁线程
(2)有返回值的线程。
(3)引入线程池,池中线程执行调度由池管理器来处理。
当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
4.static关键字
(1).作用:
方便在没有创建对象的情况下来进行调用(方法/变量)。
(2).静态方法:
没有this,因为它不依附于任何对象,所以不能访问非静态成员变量和使用非静态成员方法,非静态成员方法/变量都是必须依赖具体的对象才能够被调用,反之可以。
(3).静态变量:
静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
static成员变量的初始化顺序按照定义的顺序进行初始化。
(4).静态代码块:
static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能(因为它的特性:
只会在类加载的时候执行一次,可以将只需要进行一次的初始化操作都放在static代码块中进行)。
static块可以置于类中的任何地方,类中可以有多个static块。
在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
5.接口和抽象类的区别
(1)语法层面上:
a抽象类可以提供成员方法的实现细节,而接口中只能存在publicabstract方法;
b抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是publicstaticfinal类型的;
c接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
d一个类只能继承一个抽象类,但可以实现多个接口。
(2)设计层面上
a抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。
b设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。
而接口是一种行为规范,它是一种辐射式设计。
6.集合类
(1)接口Set
特点:
元素不能重复
HashSet:
无序保存元素
TreeSet:
有序保存元素
LinkedHashSet:
插入顺序保存
(2)List
特点:
提供基于索引的对成员的随机访问
ArrayList:
提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好。
LinkedList:
对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差。
(3)Map
保存键值对成员
HashMap:
设计用来提供快速访问。
TreeMap:
有序排列关键字,没有HashMap快。
LinkedHashMap:
保持元素的插入顺序,但也通过散列表提供了快速访问能力。
问题:
1.Set集合如何保证对象不重复
在java的集合中,判断两个对象是否相等的规则是判断两个对象的hashCode是否相等,如果不相等,就认为是不相等的,否则,判断两个对象用equals运算是否相等。
2.Hash的内部存储结构
哈希表是由数组+链表组成的,一个长度为16的数组中,每个元素存储的是一个链表的头结点。
这些元素是按照hash(key)%len的规则存储到数组中,也就是元素的key的哈希值对数组长度取模得到。
(3)HashMap和HashTable的区别:
a.HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都是synchronized。
b.HashTable不允许有null值的存在。
7.重载、重写
方法的重写Overriding和重载Overloading是java多态性的不同表现;
重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。
重写是子类覆盖父类的方法,方法名和参数都相同,重载是函数名相同,具有不同的参数个数/类型。
8.String、StringBuffer、StringBuilder
String的长度是不可变的;
StringBuffer的长度是可变的,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法;
线程安全;
StringBuilder是从JDK5开始,为StringBuffer该类补充了一个单个线程使用的等价类;
通常应该优先使用StringBuilder类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
8.final关键字
当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。
二.算法
1.排序算法
(4).快排
时间复杂度O(nlgn),不稳定
publicvoidquickSort(int[]arr,intstart,intend)
{
if(start<
end)
{
intl=start,r=end,x=arr[l];
while(l<
r)
{
while(l<
r&
&
arr[r]>
=x)
r--;
if(l<
arr[l++]=arr[r];
arr[l]<
x)
l++;
arr[r--]=arr[l];
}
arr[l]=x;
quickSort(arr,start,l-1);
quickSort(arr,l+1,end);
}
}
(2).冒泡排序
时间复杂度O(n^2),稳定
publicvoidbubbleSort(int[]arr){
for(inti=0;
i<
arr.length-1;
i++){
for(intj=0;
j<
arr.length-1-i;
j++){
if(arr[j]>
arr[j+1]){
inttemp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
(3).选择排序
publicvoidselectSort(int[]a){
for(