java面试题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java面试题相关的知识,希望对你有一定的参考价值。
1.Java基础
1.集合框架的结构
Java集合框架中抽象有序列表的接口是(List),无序列表的接口是(Set),他们的共同父接口是( Collection),用于对集合进行特殊操作如排序的工具类是(Collections),他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
2.ArrayList&Vector&LinkedList的区别
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差。
LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
3.HashMap和HashTable的区别?
HashMap:是Map接口的一个实现类,在缺省情况下是非同步的。需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:``Map Collections.synchronizedMap(Map m)``这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。HashMap&Hashtable主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。而Hashtable不允许。HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable:是同步的,可以安全地使用。而 HashMap 不是。因此,HashMap 更适合于单线程环境,而 Hashtable
适合于多线程环境。Hashtable 提供了对键的列举(Enumeration)。
Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。
4.ArrayList&LinkList
ArrayList:底层是数组,所以存储密度比LinkList大。结点中没有链信息域,只有自身信息域。查询比较方便。可以不限类型,不限大小(实际上限制大小,默认超过10个一般会缓冲自动扩张,对象引用-指针占用四个字节)。
LinkList:使用元素列表存储。更占内存,因为它为每个节点存储两个引用。插入和删除比较方便。
5.Set&Map
HashSet:HashSet由一个hash表实现,只能存储一次。而TreeSet是有序的(由一个树形结构来决定)。
Map:而key,value说的是map,HashMap是无序的,TreeMap是有序的。
6.描述Java中String,StringBuffer,StringBuilder的区别
1. 可变与不可变
String类中使用字符数组保存字符串,因为有“final”修饰符,所以可以知道string对象是不可变的。
StringBuilder与StringBuffer是使用字符数组保存字符串,可知这两种对象都是可变的。(节省了内存)
2. 是否多线程安全
String中的对象是不可变的,也就可以理解为常量,显然线程安全。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
(String&StringBuffer不能直接赋值字符串,两个类的实例的值不能被改变)
7.拥有下列哪些引用类型的对象在虚拟机内存足够的情况下不会被垃圾回收机制回收?
1. 弱引用
2. 软引用
3. 虚引用
(强引用:类似StringBuffer类的对象,java不会回收你正在使用的对象)
8.java中最有效计算2*8的表达式是?
2<<3
表示2的二进制0000 0010,如果我们要变成16的话,其二进制为0001 0000(1*2^4),左移了三位,所以2<<3
9.默认情况下,Connection对象会在执行一条语句后自动提交,不利于事务的控制,如果要改变这种情况,需要调用Connection的( )方法设置为手动提交
Connection.setAutoCommit(false);
Connection.rollback();
Connection.commit();
10.try{}里面有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行?
finally无论如何都会执行,一般用来关闭资源(IO流),执行的时间为return之前
catch捕获异常,一帮用来记录日志
11.Connection的Close深入分析
临时变量在栈中一般都会被释放掉,为什么还需要conn.close() ?
复杂数据类型是存在堆里面,而栈只是对地址进行引用,一旦引用出栈,对象就会变成垃圾。
但是Connection比较特殊,它跟数据库进行连接,一旦open状态,就不会被垃圾机制回收掉。这就是为什么conn必须关闭的原因.
12.OverLoad&Override
重载:相同的方法名,不同的参数类型或者参数数量(可变参数int...a是不能实现重载)
重写:参数列表必须和重写方法相同,方法相同,添加final的方法不能被重写,重写的异常不能广泛于父类的异常(只能更小)。
13.内部类
1. 成员内部类:跟外部类的变量地位平等,它可以访问外部类的成员变量
创建方式:new OutClass().new Inner()
使用场景:ArrayList中的Iterator方法是通过AbstractList类中的Itr类实现Iterator接口
2. 静态内部类:增加了static,所以可以直接使用
使用方式:OutClass02.Inner.show2()
使用场景:安卓项目R类中的常量存储,为了进行分类,会使用静态成员内部类进行存储,可以直接访问
3. 匿名内部类:**使用new 接口,顺便把方法实现**。这个地方没有类的名字
4. 局部内部类:放在方法里面的类,只有方法被调用的时候,类才会被使用
使用场景:当接口和类的方法一样,这样实现接口会产生冲突。所以先用一个类实现那个接口,再在里面新建两个内部类,内部类分别实现不同的接口。但是这个类只被使用一次,那么就将这个类放在方法里面。(外部的成员变量必须使用final,因为对象存堆,方法存栈,final存进常量池里面,当方法调用完消失,对象被使用的时候变量还存在)
14.char能不能存储汉字?
java char型变量是能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的
15.interface 和 abstract 的区别?
抽象类:用来extends,只能继承一个。抽象类可以实现某些方法
接口:用来实现的,可以实现多个,方法具体是在子类中实现,这体现了多态性,成员默认都是public static final的,函数默认为abstract
16.String str1="abc" 和 String str1=new String("abc"); 这两个的区别是什么?
String str1="abc"; 在编译时已经在一个**常量池**中生成一个拷贝,其中str1中的"abc"是字符串常量,类加载的时候就初始化。用(st1==st2)true,st1&st2指向同一个对象。
String str1=new String("abc"); 的话,是在**堆上**分配内存,执行才初始化。用(st1==st2)比较的是地址符
st1,st2所产生的对象并不是同一个对象。
当String常量池方式被重新赋值的话,它会复制一份副本进行改变(实际上不可变)。
17.GC是什么?常用的两种方法是什么?
GC是垃圾回收(是系统一个线程),Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法,系统并不保证会立即进行释放内存。
System.gc()用来强制立即回收垃圾,即释放内存。垃圾回收线程是另外一条线,它和主线程是并发的。
GC首先要判断该对象是否是时候可以收集。两种常用的方法是引用计数和对象引用遍历。
18.线程常用的方法是什么?
Thread类的常用方法:
static Thread currentThread() //静态方法,通过这个方法可以获得主线程的引用,从而达到操作主线程的目的。
static int activeCount() //静态方法,获得当前活动线程数量
getId() //获得当前线程id
String getName() //获得当前线程名字
int getPriority() //获得优先级
boolean isAlive() //当前线程是否处于活动状态。
boolean isDaemon() //是否为守护线程
void run() //run()方法,我们用线程,主要就是对run()方法的重写
void start() // 使该线程开始执行;Java 虚拟机调用该线程的run() 方法。
void sleep() //使当前线程休眠,以执行其他线程,如Thread.sleep(1000) 休眠1秒
19.Sleep()和wait()的区别?
sleep()方法:使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)"醒来"的线程具有更高的优先级,(b)正在运行的线程因为其它原因而阻塞。
wait():是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被**唤醒**或**等待时间**到。
20.jsp和java的关系
JSP在运行时会被翻译成servlet,而servlet是java代码。
jsp页面可以嵌入java代码,但是一般很少这样做。
21.Servlet的生命周期,比CGI有什么优点?
servlet是在服务器上运行的小程序。服务器端根据web.xml文件中的Servlet相关配置信息,将客户端请求转发到相应的Servlet引擎调用Service()方法,根据request对象中封装的用户请求与数据库进行交互,返回数据之后,Servlet会将返回的数据封装到response对象中;
servlet的生命周期
Servlet生命周期分为三个阶段:
1,初始化阶段 调用init()方法
2,响应客户请求阶段 调用service()方法
3,终止阶段 调用destroy()方法
web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用 service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。
Servlet是Java平台上的CGI技术。Servlet在服务器端运行,动态地生成Web页面。与传统的CGI和许多其它类似CGI的技术相比,Java Servlet具有更高的效率并更容易使用。对于Servlet,重复的请求不会导致同一程序的多次转载,它是依靠线程的方式来支持并发访问的。
22.存储过程和函数的区别?
函数有如:只能返回一个变量的限制。可以嵌入在sql中使用的,可以在select中调用,不能用临时表,只能用表变量。
而存储过程可以返回多个。存储过程的限制相对就比较少。
23.java Web运行结构分析
java运行:通过javac命令编译*.java得到class文件(字节码文件,非dll,机器码),用不同平台的JVM/JDK(JDK>JRE>JVM)来运行class文件。
Java Web运行:java框架,J2EE相应的支持包,Tomcat主要解析jsp文件,java文件通过jdk解析。
24.栈&队列
栈:的应用场景:Servlet调用Service,再调用Dao。Dao执行完毕之后,弹栈,返回值给Service,Service执行完之后弹栈,返回给Servlet。
队列:有两个端口,先进先出
25.序列化的作用
存入session中,session会持久化到硬盘中,这个时候关闭服务器,重启服务器session就会反序列化。
想实现session序列化,需要model类实现序列化接口Serializable,然后定义常量id。
26.线程状态的使用
1. 时间片已到:创建--就绪--运行(运行不完)--就绪
2. 资源占用: 创建--就绪--运行(缺少资源)--等待(资源满足)--就绪(当死锁的时候,关闭一个等待)
(就绪就是线程的队列,停止运行之后放在队列的后面,后进后出)
当执行start()方法,表示线程就绪,根据队列进行执行(并不一定立即运行,线程的启动时重写run方法,用start启动,而不能直接用run启动)
27.Servlet创建过程及生命周期
创建过程有三种方法:
1. 实现Servlet接口
2. 继承GenericServlet类
3. 继承HttpServlet方法
生命周期:
1. 初始化 执行init方法
2. 服务 执行service方法
3. 销毁 执行destroy方法
28.什么时候用到过线程池
除了创建和销毁线程的开销之外,活动的线程也消耗系统资源(线程的生命周期!)
正确的使用方法是有一堆任务需要创建线程去执行,任务就是对象,在java里面,就好比是实现了Runnable接口的对象,那么此时就用线程池,如果紧紧就个吧两个进程,那得了,还是没必要,其实线程池,我看在效率上来讲,就是降低了线程创建的时间消耗,实际上原理和创建单个的线程差不太多。
29.B/S架构:
C/S的优点是能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后再提交给服务器。
**B/S(Browser/Server):**浏览器/服务器结构,界面显示逻辑放在浏览器,事务处理逻辑则在Web Server。极少数的逻辑在前端实现,但主要的事务逻辑在服务器端实现。通常由Browser、Web Server、数据存储Server形成三层架构。
31.Java反射机制
通过反射机制在运行时反编译,判断任意一个类所具有的成员变量和方法;
只需要在运行时才动态的创建和编译,只需要在配置文件做简单的修改。
32.jdbc的使用步骤:
1. 加载jar包
2. 建立连接Connection,传url(数据库的地址,端口为3306),用户名,密码
3. 创建Statement对象,sql语句就可以直接执行了
33.面向接口编程IOP
例如:我们存到mysql,但是要改存到oracle的时候,就需要改程序。
但是可以使用面向接口编程,从文件读数据密码。
面向接口,只关心功能,不关心实现。先写出接口,然后其他人对接口功能进行实现。
在每一层上面再添加一层接口,然后对接口进行实现
34.对象的封装
封装是指按照信息屏蔽的原则,把对象的属性和操作结合在一起,构成一个独立的对象。
通过限制对属性和操作的访问权限,可以将属性“隐藏”在对象内部,对外提供一定的接口,在对象之外只能通过接口对对象进行操作。
封装性增加了对象的独立性,从而保证了数据的可靠性。
外部对象不能直接操作对象的属性,只能使用对象提供的服务。
35.单例模式的应用
比如说任务管理器,我们只能打开一个。数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,用单例模式来维护,就可以大大降低这种损耗。
36.map的使用场景
当你觉得反复的for循环List查值麻烦时,你可以试着用map<key,value>存储值,通过key来快速定位你要找的值
37.实现秒数和时间的转化
System.out.println(date.getTime());可以将日期转化为秒数
38.抽象类和接口的区别
接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的,
另外,实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法,
一般的应用里,最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。
还有,接口可以实现多重继承,而一个类只能继承一个超类,但可以通过继承多个接口实现多重继承。
39.线程的使用
Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口。Runnable是接口,建议用接口的方式生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合继承。在使用Thread的时候只需继承Thread,并且new一个实例出来,调用start()方法即可以启动一个线程。
Thread Test = new Thread();
Test.start();
40.为什么要使用索引
这是因为,创建索引可以大大提高系统的性能。
第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
41.java中常用的类,包,接口
类:System类,Date类,Math类,Integer类,SimpleDateFormat类
包:java.lang包,java.io包,java.util包,java.swing包,java.net包,java.sql包
接口:Comparable,Collection,Map,List,Runnable
42.Error&Exception的区别
Error类和Exception类的父类都是throwable类,他们的区别是:
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。
Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
Exception类又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception ),运行时异常;ArithmaticException,IllegalArgumentException,编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用try。。。catch捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不会通过。
43.多线程的应用场景
后台任务:如定时向大量(100W以上)的用户发送邮件;定期更新配置文件、任务调度(如quartz),一些监控用于定期信息采集。
最典型的应用比如tomcat,tomcat内部采用的就是多线程,上百个客户端访问同一个web应用,tomcat接入后都是把后续的处理扔给一个新的线程来处理,这个新的线程最后调用到我们的servlet程序,比如doGet或者doPost方法。
如果不采用多线程机制,上百个人同时访问一个web应用的时候,tomcat就得排队串行处理了,那样客户端根本是无法忍受那种访问速度的。
2.数据库
1.下列Select语句中,哪些子句不能包含子查询
1.group by
张三 Java 90
张三 C# 98
李四 Java 89
李四 C# 62
李四 C++ 80
select sum(score) from Student group by course``则就是分别对各个课程求总和,就是
Java:98+89
C#:98+62
C++:80
select sum(score) from Student group by name 则是按人进行分组
张三:90+98
李四:89+62+80
2.order by
| Store_Name | Sales | Txn_Date |
| ------------- | ----- | ----------- |
| Los Angeles | 1500 | 05-Jan-1999 |
| San Diego | 250 | 07-Jan-1999 |
| San Francisco | 300 | 08-Jan-1999 |
| Boston | 700 | 08-Jan-1999 |
我们就打入:
``SELECT Store_Name, Sales, Txn_Date FROM Store_Information ORDER BY Sales DESC;``
结果:
```
Los Angeles 1500 Jan-05-1999
Boston 700 Jan-08-1999
San Francisco 300 Jan-08-1999
San Diego 250 Jan-07-1999
```
2.假设现在数据库DB中有一个人员信息表(tUserInfo),表中包括 主键ID,姓名name,身份证号码number等字段。由于程序的原因,后来发现表中有许多理论上重复的数据(即姓名name和身份证number相同的数据),现在要求根据身份证号码和姓名去除表中的重复数据?请写出具体sql语句。
select Max(ID) as Id,姓名,身份证号 from tUserInfo group by 姓名,身份证号;
这条Sql语句即可得到一份没有重复姓名和身份证号的一组数据
获得不重复的id
select Id from (select Max(ID) as Id,姓名,身份证号 from tUserInfo group by 姓名,身份证号) as t;
删除掉重复的id即可
delete form user where id not in (select Id from (select Max(ID) as Id,姓名,身份证号 from tUserInfo group by 姓名,身份证号) as t );
3.已知数据表part:代码(code),名称(name),数量(num),请写出如下sql命令:
1. 增加一条记录,值为:code=‘001’,name=‘商品’,num=10
insert into part (code,name,num) values (‘001‘,‘商品‘,10)
2. 删除所有的num值为0的记录
delete from part where num=0
3. 对num大于10的记录,将其全部减1
update part set num=num+1 where num>10
4.已知数据表part:代码(code),名称(name),数量(num)3列,请编写如下sql指令:
1. 删除所有的num值为0,且name为null的记录
delete from part where num=0 and name is null
2. 对num大于10且小于20的记录,将其全部减1
update part set num=num-1 where num>10 and num<20
3. 编写一条指令统计出num值< 10 , >=10 and < 20,>=20各有多少条记录
select count(num) from part group by num where num < 10 union all select count(num) from part group by num where num >=10 union all select count(num) from part group by num where num < 20 union all select count(num) from part group by num where num >=20
5.MYSQL中外键on delete cascade有什么意义?
当在父表(即外键的来源表)中删除对应记录时,首先检查该记录是否有对应外键,如果有则也删除外键在子表(即包含外键的表)中的记录。
6.主键和唯一索引的区别
(创建索引的方式:CREATE UNIQUE INDEX 索引名称ON 表名称 (列名称))
创建索引可以大大提高系统的性能。
主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
唯一性索引列允许空值,而主键列不允许为空值。
主键列在创建时,已经默认为空值 + 唯一索引了。
主键可以被其他表引用为外键,而唯一索引不能。
一个表最多只能创建一个主键,但可以创建多个唯一索引。
主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
7.聚焦索引和非聚焦索引的区别
聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。就像字段,聚集索引是连续的,a后面肯定是b,非聚集索引就不连续了,就像图书馆的某个作者的书,有可能在第1个货架上和第10个货架上。还有一个小知识点就是:聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。
8.约束有哪几种?
1. 主键约束
保证实体的完整性,该列不会出现重复值,空值
2. 外键约束
保证引用的完整性
3. 检查约束
保证域的完整性
4. 默认约束
保证域的完整性,至少给一个默认值
9.写出常见的SQL关键字
SELECT --从数据库表中检索数据行和列
INSERT --向数据库表添加新数据行
DELETE --从数据库表中删除数据行
UPDATE --更新数据库表中的数据
10.数据库相关
s_student表
id char 16 //id
s_no char 16 //学号
s_name varchar 32 //姓名
s_score
id char 8 //id
student_id char 17 //s_student的id
s_num varchar 16 //成绩
#2.查询学号为201420326的学生学号,姓名,成绩
loading
#3.统计学号为201420326的学生总分
loading
#4.删除所有的姓王学生的成绩
loading
3.jsp
1.描述JSP MVC模式下重复提交问题产生的原因和解决方法
原因:
a>点击提交按钮两次。
b>点击刷新按钮。
c>使用浏览器后退按钮重复之前的操作,导致重复提交表单。
d>使用浏览器历史记录重复提交表单。
e>浏览器重复的HTTP请求。
但出现了这样的问题并不见得就必须处理,要看你所开发的系统的类别而定。比如你接手的是某个资源管理系统,系统本身从需求的角度根本就不允许出现" 重复"的记录,在这样需求的约束条件下,去执行重复的提交动作只会引发“业务级异常”的产生(比如说抽奖,回退之后重新抽一次)
解决方法:
在服务器端生成一个令牌保存在用户session中,在form中加一个hidden域,显示该令牌的值,form提交后重新生成一个新的令牌,将用户提交的令牌和session中的令牌比较,如相同则是重复提交。
2.简述SERVLET API中forward()与redirect()的区别以及JSP中动态引入与静态引入的区别
forward():仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址
redirect():则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。
所以,前者**更加高效**,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于**隐藏实际的链接**。在有些情况下,比如,需要**跳转到一个其它服务器上**的资源,则必须使用sendRedirect()方法。
静态引入:就是把页面A嵌入到页面B中,如果页面B中有JAVA代码,比如说变量名是X,A中也有变量X这样的话静态引入会报错,但是动态引入不会报错,静态引入的JSP编译的时候会生成一个.java文件
动态引入:会生成两个.java文件,因为动态引入(生成静态页面)是一个页面引用另一个页面而静态的是嵌入。
不过 静态引入和动态引入最后都只会生成一个html页面。
3._描述Hibernate中的ID生成器_
1) assigned
主键由外部程序负责生成,无需Hibernate参与。
2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。
4) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。
这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。
5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。
6) sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
7) native
由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
8) uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16)。在某些数据库中可能出现问题(如PostgreSQL)。
10) foreign
使用外部表的字段作为主键。
4.描述Spring中的编程式事务处理及声明式事务处理
Spring对编程式事务的支持
Spring中的事务分为物理事务和逻辑事务
物理事务:就是底层数据库提供的事务支持,如JDBC或JTA提供的事务;
逻辑事务:是Spring管理的事务,不同于物理事务,逻辑事务提供更丰富的控制,而且如果想得到Spring事务管理的好处,必须使用逻辑事务,因此在Spring中如果没特别强调一般就是逻辑事务;
逻辑事务解决方案:
低级别解决方案:
使用工具类获取连接(会话)和释放连接(会话),如使用org.springframework.jdbc.datasource包中的DataSourceUtils 类来获取和释放具有逻辑事务功能的连接。当然对集成第三方ORM框架也提供了类似的工具类,如对Hibernate提供了SessionFactoryUtils工具类,JPA的EntityManagerFactoryUtils等,
高级别解决方案:
使用Spring提供的模板类,如JdbcTemplate、HibernateTemplate和JpaTemplate模板类等,而这些模板类内部其实是使用了低级别解决方案中的工具类来管理连接或会话
Spring提供两种编程式事务支持:直接使用PlatformTransactionManager实现和使用TransactionTemplate模板类,用于支持逻辑事务管理。如果采用编程式事务推荐使用TransactionTemplate模板类和高级别解决方案。
5.Http状态码
404:连接了,找不到资源
500:系统中解析出现错误
302:重定向状态码
200:顺利,请求成功!
6.持久层框架比较
JDBC,JDBCTemplate,MyBatis,hibernate
1. jdbc:原生态的写法,运行效率比较高,代码量比较大,不支持数据库跨平台(非常熟悉)
2. jdbcTemplate:spring提供的,支持aop,内嵌于spring,不支持数据库跨平台
3. MyBatis:封装得更好,性能不会差太多,复杂SQL构建,支持aop事务,支持缓存,不支持数据库跨平台
4. hibernate:在损害性能的基础之上实现数据库的跨平台移植,hql查询语句
7.SSH框架
struts2+spring+hibernate
对象的调用流程是: jsp-> Action - > Service ->DAO ->Hibernate 。
#1.Struts 的MVC设计模式
struts的重要功能,提供struts的过滤器,拦截用户的请求,查找struts配置文件,为其匹配一个对应的Action,这个Action负责调用模型,获得数据,然后对数据做部分处理,接着Action再将处理后的数据,为其选择一个视图进行输出。
#2.Spring 的IOC和AOP可以使我们的项目在最大限度上解藕。
Spring的IoC(控制反转) 、DI(依赖注入)这两个概念:
Ioc:意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。(专门有容器来创建对象,IOC容器帮对象找相应的依赖对象并注入)
IoC(控制反转),将类的创建和依赖关系写在配置文件里,由配置文件注入,实现了松耦合
使用反射来读取配置文件,类中提供setter,getter就可以。再在spring中配置就可以了,配置中还可以传对象(装配)。
DI注入:某个对象所需要的外部资源(包括对象、资源、常量数据),是同一个概念的不同角度描述,IOC容器配置所依赖的对象。
AOP(面向切面编程):
算是对OOP(引入封装、继承、多态)的补充和完善。OOP(面向对象编程)针对业务处理过程的**实体**及其**属性**和**行为**进行**抽象封装**,以获得更加清晰高效的逻辑单元划分。
AOP则是针对业务处理过程中的**切面**进行提取,它所面对的是处理过程中的某个**步骤**或**阶段**,以获得逻辑过程中各部分之间低耦合性的**隔离效果**。
AOP 将安全,事务等于程序逻辑相对独立的功能抽取出来,利用spring的配置文件将这些功能插进去,实现了按照方面编程,提高了复用性
如果几个或更多个逻辑过程中,有重复的操作行为,AOP就可以提取出来,运用动态代理,实现程序功能的统一维护。
#3.Hibernate是对JDBC进一步封装
在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了(把关系数据库的字段在内存中映射成对象的属性)。Hibernate是一个没有侵入性的框架,Hibernate不需要继承任何类,不需要实现任何接口。这样的对象叫POJO对象。
降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。
8.MVC模式的优点&作用
MVC模式的目的就是实现Web系统的职能分工。 Model层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。 View层用于与用户的交互,通常用JSP来实现。 Controller层是Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。
1. 各个模型层各司其职,互不干涉。
2. 有利于开发中的分工。
3. 有利于组件的重用。
9.jsp的九大内置对象
request内置对象
response内置对象
page内置对象
session内置对象
application内置对象
out内置对象
exception内置对象
config内置对象
pageContext内置对象
10.springMVC的介绍
常用注解: @Controller
在类或方法:@RequestMapping
springmvc主要使用的是注解配置,然后可以跟spring无缝配合,基于servlet
11.为什么使用mybatis
1. 数据库没有连接池,每次请求都会重新创建。
mybatis:使用线程池
2. sql语句是写死在代码中,不利于代码维护。
mybatis:在xml中配置
3. preparedStatement 中的设置的参数也是写的死,同样不利于维护。
mybatis:在xml中配置
4. 数据从数据库获取后,读取方式同样是写死的。
mybatis:自动映射。
以上是关于java面试题的主要内容,如果未能解决你的问题,请参考以下文章
2020年1-6月份Java面试题总结,20多类1100道面试题含答案解析