1、forward 和redirect的区别
直接转发方式(Forward):客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
浏览器向Servlet1发出访问请求;
Servlet1调用forward()方法,在服务器端将请求转发给Servlet2;
最终由Servlet2做出响应。
间接转发方式(Redirect):实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。
浏览器向Servlet1发出访问请求;
Servlet1调用sendRedirect()方法,将浏览器重定向到Servlet2;
浏览器向servlet2发出请求;
最终由Servlet2做出响应。
举个通俗的例子:
直接转发就相当于:“A找B借钱,B说没有,B去找C借,借到借不到都会把消息传递给A”;
间接转发就相当于:“A找B借钱,B说没有,让A去找C借”。
直接转发和间接转发的原理及区别是什么
Forward和Redirect代表了两种请求转发方式:直接转发和间接转发。对应到代码里,分别是RequestDispatcher类的forward()方法和HttpServletRequest类的sendRedirect()方法。
对于间接方式,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。它本质上是两次HTTP请求,对应两个request对象。
对于直接方式,客户端浏览器只发出一次请求,Servlet把请求转发给Servlet、HTML、JSP或其它信息资源,由第2个信息资源响应该请求,两个信息资源共享同一个request对象。
2、Static变量是什么含义
static是静态变量,就是变量值不随函数执行结束而消失,下次调用同一函数时,上次所赋予的值仍存在。
static和final一块用表示什么
static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!
对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
对于方法,表示不可覆盖,并且可以通过类名直接访问。
3、 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况;
通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
System.gc()的工作原理
gc()函数的作用只是提醒虚拟机:程序员希望进行一次垃圾回收。但是它不能保证垃圾回收一定会进行,而且具体什么时候进行是取决于具体的虚拟机的,不同的虚拟机有不同的对策
gc()进行回收的准则是什么?也就是说什么样的对象可以被回收?
在下次垃圾回收周期来到时,如果没有任何对象的引用指向该对象时,对象才会被回收
4、Overload和Override的区别
方法的重写Overriding和重载Overloading是Java多态性的不同表现
重写Overriding是父类与子类之间多态性的一种表现
1、如果在子类中定义某方法与其父类有相同的名称和参数,返回类型必须和被重写方法的返回类型相同或者是返回类型的子类型,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了;
2、只有实例方法才能被重写,超类中的static和final方法不能被重写。
3、重写方法不能抛出新的检查异常,或者是抛出比被重写方法声明的检查异常更广泛的检查异常
重载Overloading是一个类中多态性的一种表现
1、如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。
2、Overloaded的方法是可以改变返回值的类型。
3、重载对返回类型,访问修饰符,异常声明没有任何限制,可以作任意的修改。实质上,重载只是创建了一个方法而已,特殊的地方在于方法的名字。
5、说出Servlet的生命周期,并说出Servlet和CGI的区别
Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet
5、谈谈final, finally, finalize的区别
final
用于声明属性,方法和类,分别表示属性不可变,注意:如果是基本类型说明变
量本身不能改变,如果是引用类型,说明它不能指向其他的对象了。但对象还是可以改变
的。方法不可覆盖,类不可继承。
finally
是异常处理语句结构的一部分,表示无论是否出现异常总是执行。
finalize
是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
6、什么时候用assert?
1.4新增关键字(语法),用于测试boolean表达式状态,可用于调试程序。使用方法 assert <boolean表达式>,表示如果表达式为真(true),则下面的语句执行,否则抛出AssertionError。
7、String s = new String(“xyz”);创建了几个String Object?
两个,一个是对象,一个是对象的引用。
8、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)==12
Math.round(-11.5)==-11
返回最接近它的整数
9、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
short s1 = 1; s1 = s1 + 1; 有错
原因:s1+1运算结果是int型,需要强制转换类型
short s1 = 1; s1 = (short) (s1 + 1);
short s1 = 1; s1 += 1;
没有错,s1==2
10、sleep() 和 wait() 有什么区别?
sleep
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间(休息),把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,时间到了会继续运行。调用sleep不会释放对象锁。
wait
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
11、数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。
String有length()这个方法。
12、给我一个你最常见到的runtime exception
IndexOutOfBoundsException 数组越界
NullPointerException 空指针异常
SystemException 系统异常
13、error和exception有什么区别?
Error表示系统级的错误和程序不必处理的异常,我们无法处理它。
Exception表示是可以捕捉或者需要程序进行处理的异常。
14、abstract class和interface有什么区别?
一个类只能继承一个抽象类,但却可以实现多个接口。抽象类中可以有也可以没有抽象方法。并且可以定义和常规类一样的变量和方法。而接口中所有的方法都是抽象的,所有的变量都是静态不可修改的。
15、写程序获取一百个不重复的随机数。
public static void main(String[] args) {
Random rm = new Random();
Set<Integer> set = new LinkedHashSet<>();
while(set.size()<100) {
int a = rm.nextInt(100)+1;
set.add(a);
}
Iterator itor = set.iterator();
while(itor.hasNext()) {
System.out.println(itor.next());
}
}
16、计算字符串“23743298”奇数位的和,偶数位的和。
public static void main(String[] args) {
String str= "23743298";
int length = str.length();
int sum1 = 0;//奇数
int sum0 = 0;//偶数
for(int i=0;i<length;i++) {
int temp = Integer.parseInt(str.substring(i,i+1));
if(i%2==0) { //奇数
sum1 +=temp;
}else { //偶数
sum0 +=temp;
}
}
System.out.println("奇数位和:"+sum1);
System.out.println("偶数位和:"+sum0);
}
17、12个小球 其中只有一个小球重量 可能轻可能重,用天平不能超过三次 找到这个重量不一的小球?
准备工作
小球分为三组
a1、a2、a3、a4;
b1、b2、b3、b4;
c1、c2、c3、c4;
第一次使用天平
a1、a2、a3、a4; (左天平)
b1、b2、b3、b4; (右天平)
结果: 两种情况
情况X1 :两边一样重,小球在C组中
情况X2:两边不一样重,则小球在A组或B组
针对情况X1:第二次使用天平
c1 (左天平)
c2(右天平)
结果: 两种情况
情况Y1 :c1和c2一样重,则小球在c3、c4中
情况Y2:c1和c2不一样重,小球在c1、c2中
针对情况Y1:第三次使用天平
从c3、c4 任意选取一个小球,选取一个正常小球
c3(左天平)
a1(右天平)
如果c3和a1一样重,则c4为问题小球;否则为c3
针对情况Y2:第三次使用天平
从c1、c2 任意选取一个小球,选取一个正常小球
c1(左天平)
a1(右天平)
如果c1和a1一样重,则c2为问题小球;否则为c1
针对情况X2:第二次使用天平
若两边不一样重,则小球在A组或B组。将小球重新排号。
假设a组为偏重的组,b组为偏轻的组。
a1、a2、a3、a4; 改为 重1、重2、重3、重4
b1、b2、b3、b4; 改为 轻1、轻2、轻3、轻4
c1、c2、c3、c4 ; 改为 好1、好2、好3、好4
重1、重2、重3 、 轻4 (左天平)
好1、好2、好3 、 重4 (右天平)
结果:三种
A:平衡:说明轻1,轻2,轻3三个当中有一个轻了
B:重1,重2,重3,轻4,这边重了: 说明肯定是重1,重2,重3三个当中有一个重了
C:轻1,轻2,轻3,重4这边重了:说明要么是重4重了,要么是轻4轻了
针对A:
轻1,轻2称
如果平衡,则轻3轻了,如果不平衡,轻的那边那个轻了,是要找的球
针对B:
重1,重2称
如果平衡,则重3重了,如果不平衡,重的那边那个重了,是要找的球
针对C:
重4和轻4有问题
重4与好1称,如果平衡,则轻4有问题,否则重4有问题。
18、一个5升水桶一个3升水桶怎么计算出4升水?
第一步: 5升水桶装满水,全部倒入3升水桶,则5升水桶还剩下2升水;
第二步:将5升水桶重剩下的2升水全部倒入3升水桶重,则3升水桶重有2升水;
第三步:将5升水桶装满水,向3升水桶装水直到装满;那么5升水桶还剩下4升水;
19、请阐述spring IOC思想。
20、阐述hibernate的延迟加载机制。
21、hibernate中对几个主流的数据库(oracle,mysql,sqlserver)的分页的实现
22、类的实例化顺序
- 父类静态代变量
- 父类静态代码块
- 子类静态变量
- 子类静态代码块
- 父类实例成员变量
- 父类构造函数
- 子类实例成员变量
- 子类构造函数
23、抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口?
- 抽象类和接口都不能直接实例化
- 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
- 抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
- 抽象方法只能申明,不能实现。abstract void abc();不能写成abstract void abc(){}。
- 抽象类里可以没有抽象方法
- 如果一个类里有抽象方法,那么这个类只能是抽象类
- 抽象方法要被实现,所以不能是静态的,也不能是私有的。
- 接口可继承接口,并可多继承接口,但类只能单根继承
- 接口的方法默认是public类型
不允许类多重继承的主要原因是,如果A同时继承B和C,而B和C同时有一个D方法,A如何决定该继承那一个呢?但接口不存在这样的问题,接口全都是抽象方法继承谁都无所谓,所以接口可以继承多个接口。
24、 bio、nio、aio 的区别,谈谈 reactor 模型
- JAVA BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程并处理,如果这个连接不做任何事情会造成不必要的开销,当然可以通过线程池机制改善
- JAVA NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理
- JAVA AIO(NIO2):异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理
25、反射的原理,反射创建类实例的三种方式是什么
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生成动态代理
26、反射中,Class.forName 和 ClassLoader 区别
类加载的过程
- .class文件首先被加载到jvm中
- 然后经过链接,在链接中有3个步骤。
首先验证:验证是为了保证我们的.class文件的合法性。会分别尽心文件格式验证,元数据验证,字节码验证,符号引用验证。
然后准备:初始化静态成员变量,并赋值。
最后解析:将符号引用转换为直接引用 - 初始化,执行静态代码快。类装载过程到此结束
Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
classloader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
Class.forName(name,initialize,loader)带参数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象。
27、动态代理的几种实现方式,分别说出相应的优缺点
- java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
- cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
28、error 和 exception 的区别,CheckedException,RuntimeException 的区别
CheckedException
Java认为Checked异常都是可以被处理的异常,所以Java程序必须显示处理Checked异常。如果程序没有处理Checked异常,该程序在编译时就会发生错误无法编译。
IOException
SQLException
ClassNofFoundException
RuntimeException
Java.lang.ArithmeticException
Java.lang.ArrayStoreExcetpion
Java.lang.ClassCastException
Java.lang.IndexOutOfBoundsException
Java.lang.NullPointerException
29、在 jdk1.5 中,引入了泛型,泛型的存在是用来解决什么问题
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。
- 性能
对值类型使用非泛型集合类,在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。装箱和拆箱的操作很容易实现,但是性能损失较大。假如使用泛型,就可以避免装箱和拆箱操作。
ArrayList list=new ArrayList();
list.Add(20); //装箱,list存放的是object类型元素,须将值类型转化为引用类型
int i=(int)list[0]; //拆箱,list[0]的类型是object,要赋值就得把引用类型转化为值类型
List<T> list=new List<int>();
list.Add(20); //因为指定了用int来实例化,因此不必装箱
int i=list[0]; //同样地,访问时也不需要拆箱
- 类型安全
如果该用泛型编程,则可以避免这种异常,让编译器检查出错误
List<int> list=new List<int>();
list.Add(20);
lsit.Add(”string”); //编译时报错,只能报整数类型添加到集合中
30、在 Queue 中 poll()和 remove()有什么区别?
poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。
31、synchronized 的原理是什么,解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁。
32、用过哪些原子类,他们的原理是什么
AtomicInteger; AtomicLong; AtomicReference; AtomicBoolean;基于CAS原语实现 ,比较并交换、加载链接/条件存储,最坏的情况下是旋转锁
33、countdowlatch 和 cyclicbarrier 的内部原理和用法,以及相互之间的差别
https://www.jianshu.com/p/a101ae9797e3
CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它运行一个或者多个线程一直处于等待状态。
CyclicBarrier要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
CyclicBarrier初始化的时候,设置一个屏障数。线程调用await()方法的时候,这个线程就会被阻塞,当调用await()的线程数量到达屏障数的时候,主线程就会取消所有被阻塞线程的状态。
前者是递减,不可循环,后者是递加,可循环用
countdowlatch 基于abq cb基于ReentrantLock Condition
34、http1.0 和 http1.1 、http2.0有什么区别
HTTP1.0和HTTP1.1的区别
- 长连接(Persistent Connection)
HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。 - 节约带宽
- HOST域
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request) - 缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略 - 错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除
HTTP1.1和HTTP2.0的区别
- 多路复用
HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级 - 头部数据压缩
在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。
HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快
35、HTTPS与HTTP的一些区别
- HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
35、说说你知道的几种 HTTP 响应码
1xx:信息,请求收到,继续处理
2xx:成功,行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求,必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误,服务器不能实现一种明显无效的请求
200 ok 一切正常
302 Moved Temporatily 文件临时移出
404 not found