java面试题

来源:互联网 发布:php 数据录入系统 编辑:程序博客网 时间:2024/06/03 02:26

一、基础部分:
(1)、java基础:
JVM能有几个实例?
每个java程序对应一个JVM实例,当一个java程序运行时就创建一个JVM实例,因此JVM实例的个数取决于同时执行的程序个数;
Java跨平台是如何实现的?
Java是利用JVM(Java虚拟机)实现跨平台的;
Java源码(*.java)经过java编译器编译成java字节码(*.class),java字节码经过JVM解释为具体平台的具体指令,并执行;不同平台有不同的JVM,主流平台都提供了JVM,
所以Java字节码可以在主流平台上解释执行;在这个意义上java是跨平台的,也就是说:java的字节码是跨平台的;
void和null有何区别?
在java中,void用于无返回值的方法上,如果该方法不需要返回数据,故返回值类型设置为void;
null则代表对i象/变量的值,表示变量没有被实例化,没有指向具体的内存地址;
请描述一下JVM加载class文件的原理机制
JVM中类的装载是由ClassLoader和它的子类来实现的;Java  ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类;
什么是垃圾回收?
垃圾回收(GC)是java语言的一个重要特性,作用收拾释放不再被使用的内存;
什么时候触发垃圾回收?
垃圾回收由系统进行管理,在系统认为需要的时候自动启动一个线程进行处理;
如何降低垃圾回收的触发频率? 
尽量减少垃圾内存,也就是新建对象的数量,可以降低垃圾回收的频率;
它能保证程序有足够的可用内存吗?
垃圾回收机制无法保证有足够的内存;     
Java中会存在内存泄漏吗?
会出现内存泄漏;
一般来说内存泄漏有两种情况;一是在堆中分配的内存,在没有将其释放掉的时候,就将所有能访问该内存的方式都删除掉;另一种情况则是在内存对象已经不需要的时候,还仍然保留则这块内存和它的访问方式(引用);第一种情况,在java中已经由于垃圾回收机制的引入,得到了很好的解决;所以,java中的内存泄漏,主要指的是第二种情况;

常用的JDK包如下:
-java.lang包:包含了JDK提供的基础类,比如String等,这个包是唯一一个不用导入就可以使用的包;
-java.io包:包含了与输入输出相关的类,比如文件操作等;
-java.net包: 包含了与网络有关的类,比如URL、URLConnection等;
-java.util包:包含系统辅助类,特别是集合类,如Collection、List、Map等;
-java.sql包:包含数据库操作的类,如Connection、Statement、ResultSet等;


(2)、OOP:
在Java中创建对象的不同方法有哪些?
它们分别是:
•通过new关键字
•通过newInstance()方法
•通过clone()方法
•通过反序列化
•通过工厂方法等
抽象类与接口的区别:
抽象类:
  • 抽象方法:它只有声明,而没有具体的实现。抽象方法的声明格式为:abstract void fun();
  • 如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。
  • 特点:
    1. 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
    2. 抽象类不能用来创建对象
    3. 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类
接口:
  • 接口中可以含有 变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误)
  • 接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法
区别:
  1. 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
  3. 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
重写与重载的区别?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
1.重写体现在父与子类中,重载是体现在一个类中。
2.重写的方法名,参数数目相同,参数类型兼容,重载的方法名相同,参数列表不同。
3.重写的方法修饰符大于等于父类的方法,重载和修饰符无关。
4.重写不可以抛出父类没有抛出的一般异常,可以抛出运行时异常

.内部类与静态内部类的区别?

静态内部类相对与外部类是独立存在的,在静态内部类中无法直接访问外部类中变量、方法。如果要访问的话,必须要new一个外部类的对象,使用new出来的对象来访问。但是可以直接访问静态的变量、调用静态的方法;
普通内部类作为外部类一个成员而存在,在普通内部类中可以直接访问外部类属性,调用外部类的方法。
如果外部类要访问内部类的属性或者调用内部类的方法,必须要创建一个内部类的对象,使用该对象访问属性或者调用方法。
如果其他的类要访问普通内部类的属性或者调用普通内部类的方法,必须要在外部类中创建一个普通内部类的对象作为一个属性,外同类可以通过该属性调用普通内部类的方法或者访问普通内部类的属性

如果其他的类要访问静态内部类的属性或者调用静态内部类的方法,直接创建一个静态内部类对象即可。

Static关键字有什么作用?

Static可以修饰内部类、方法、变量、代码块
Static修饰的类是静态内部类
Static修饰的方法是静态方法,表示该方法属于当前类的,而不属于某个对象的,静态方法也不能被重写,可以直接使用类名来调用。在static方法中不能使用this或者super关键字。
Static修饰变量是静态变量或者叫类变量,静态变量被所有实例所共享,不会依赖于对象。静态变量在内存中只有一份拷贝,在JVM加载类的时候,只为静态分配一次内存。

Static修饰的代码块叫静态代码块,通常用来做程序优化的。静态代码块中的代码在整个类加载的时候只会执行一次。静态代码块可以有多个,如果有多个,按照先后顺序依次执行。

Final在java中的作用

Final可以修饰类,修饰方法,修饰变量。
修饰的类叫最终类。该类不能被继承。
修饰的方法不能被重写。
修饰的变量叫常量,常量必须初始化,一旦初始化后,常量的值不能发生改变。

java反射机制的作用?
1.在运行时判断任意一个对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法;
4.在运行时调用任意一个对象的方法;
(3)、JAVA SE:

String类的常用方法有那些?

charAt:返回指定索引处的字符
indexOf():返回指定字符的索引
replace():字符串替换
trim():去除字符串两端空白
split():分割字符串,返回一个分割后的字符串数组
getBytes():返回字符串的byte类型数组
length():返回字符串长度
toLowerCase():将字符串转成小写字母
toUpperCase():将字符串转成大写字符
substring():截取字符串
format():格式化字符串
equals():字符串比较

String和StringBuffer、StringBuilder的区别:
String:
为不可变对象,一旦被创建,就不能修改它的值.
对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
String是final类,即不能被继承.
StringBuffer:
是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象
它只能通过构造函数来建立,
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer
中赋值的时候可以通过它的append方法.
StringBuffer和StringBuilder类的区别在于StringBufferd支持并发操作,线性安全的,适 合多线程中使用。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用,但其在单线程中的性能比StringBuffer高。

==与equals的区别?
*在String类中可以使用==和equals()两种操作来进行字符串的比较
*==比较的是两个字符串的内存地址数值是否一致,属于数值比较
*equals()是String类中提供的一个方法,用于字符串内容的比较;
1、基本数据类型(也称原始数据类型):byte,short,char,int,long,float,double,boolean,他们之间的比较,应用双等号(==),比较的是他们的值
2、复合数据类型(类):当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址。所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
     对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
值类型是存储在内存中的堆栈(简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。所以,==比较的是栈里的地址,而equals比较的是栈里面地址所指向的堆里面的内容。
基本类型:=比较的是值是否相同;
引用类型:=比较的是其地址值是否相同;
      equals()比较的是其内容是否相同,equals()必须有对象才能调用。

java集合:
JAVA的容器包括如下:
List,Map,Set ,Collection ,List ,LinkedList ,ArrayList ,Vector ,Stack ,Set 
Map ,Hashtable ,HashMap ,WeakHashMap
数据容器主要分为了两类:
Collection: 存放独立元素的序列。
Map:存放key-value型的元素对。

LinkedList :其数据结构采用的是链表,此种结构的优势是删除和添加的效率很高,但随机访问元素时效率较ArrayList类低。
ArrayList:其数据结构采用的是线性表,此种结构的优势是访问和查询十分方便,但添加和删除的时候效率很低。

HashSet: Set类不允许其中存在重复的元素(集),无法添加一个重复的元素(Set中已经存在)。HashSet利用Hash函数进行了查询效率上的优化,其contain()方法经常被使用,以用于判断相关元素是否已经被添加过。
HashMap: 提供了key-value的键值对数据存储机制,可以十分方便的通过键值查找相应的元素,而且通过Hash散列机制,查找十分的方便。

Collections和Collection有什么区别
Collections是一个工具类,可以直接调用List和Set的方法
Collection是一个接口,是List和Set集合的父接口
ArrayList和Vector的区别?
同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程不安全的,不是同步的;
数据增长:当需要增长时,Vector默认增长为原来的一倍,而ArrayList却是原来的一半;

HashMap和Hashtable的区别
第一,Hashtable是Java1.1的一个类,它基于陈旧的Dictionary类。而HashMap是Java1.2引进的Map接口的一个实现。
第二,Hashtable是线程安全的,也就是说是线程同步的,而HashMap是线程不安全的。也就是说在单线程环境下应该用HashMap,这样效率更高。
第三,HashMap允许将null值作为key或value,但Hashtable不允许(会抛出NullPointerException)。

list,map,set三个接口,存取元素时,各有什么特点?
ist:存储: 有序的 可重复的
        访问:可以for循环,foreach循环,iterator迭代器 迭代。
set:存储:无序的 不重复的
        访问:可以foreach循环,iterator迭代器 迭代
map:存储:存储的是一对一对的映射 ”key=value“,key值 是无序,不重复的。value值可重复
        访问:可以map中key值转为为set存储,然后迭代这个set,用map.get(key)获取value
                    也可以 转换为entry对象 用迭代器迭代
LinkedList与ArrayList的区别:
注意:常数阶O(1),线性阶O(n),
ArrayList和LinkedList都实现了List接口,有以下的不同点:
1、ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
2、相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
3、LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。


java异常:

Error与Exception的区别:
Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题。比如:内存资源不足等。对于这种错误,程序基本无能为力,除了退出运行外别无选择,它是由Java虚拟机抛出的。
Exception(违例)表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者在外的输入等引起的一般性问题,是程序必须处理的。
关键字:throws,throw,try,catch,finally分别代表什么意义?

  • throw:有时我们需要显式地创建并抛出异常对象来终止程序的正常执行。throw关键字用来抛出并处理运行时异常。
  • throws:当我们抛出任何“被检查的异常(checked exception)”并不处理时,需要在方法签名中使用关键字throws来告知调用程序此方法可能会抛出的异常。调用方法可能会处理这些异常,或者同样用throws来将异常传给上一级调用方法。throws关键字后可接多个潜在异常,甚至是在main()中也可以使用throws。
  • try-catch:我们在代码中用try-catch块处理异常。当然,一个try块之后可以有多个catch子句,try-catch块也能嵌套。每个catch块必须接受一个(且仅有一个)代表异常类型的参数。
  • finally:finally块是可选的,并且只能配合try-catch一起使用。虽然异常终止了程序的执行,但是还有一些打开的资源没有被关闭,因此,我们能使用finally进行关闭。不管异常有没有出现,finally块总会被执行。
throw与throws的区别:
最常见到的5个runtime exception。
NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
IllegalArgumentException - 传递非法参数异常。
ArithmeticException - 算术运算异常
ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsException - 下标越界异常
NegativeArraySizeException - 创建一个大小为负数的数组错误异常
NumberFormatException - 数字格式异常
SecurityException - 安全异常
UnsupportedOperationException - 不支持的操作异常

运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。Java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

什么叫对象序列化,什么是反序列化,实现对象序列化需要做哪些工作
对象序列化,将对象以二进制的形式保存在硬盘上
反序列化;将二进制的文件转化为对象读取
实现serializable接口
不想让字段放在硬盘上就加transient



java线程:

1.线程的生命周期
线程是一个动态执行的过程,它也有一个从产生到死亡的过程。
(1)生命周期的五种状态
   新建(new Thread)
当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
例如:Thread  t1=new Thread();
就绪(runnable)
线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();
运行(running)
线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。
死亡(dead)
当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
自然终止:正常运行run()方法后终止
异常终止:调用stop()方法让一个线程终止运行
堵塞(blocked)
由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。
正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)

二、数据库部分:

什么是JDBC,在什么时候会用到它?
JDBC的全称是Java DataBase Connection,
也就是Java数据库连接,我们可以用它来操作关系型数据库。
JDBC接口及相关类在java.sql包和javax.sql包里。
我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。
JDBC的连接步骤:

    1)加载(注册)数据库驱动(到JVM)。
    2)建立(获取)数据库连接。
    3)创建(获取)数据库操作对象。
    4)定义操作的SQL语句。
    5)执行数据库操作。
    6)获取并操作结果集。
   7)关闭对象,回收数据库资源(关闭结果集-->关闭数据库操作对象-->关闭连接)


1.加载驱动类;
2.与数据库建立连接;
3.执行SQL语句
4.处理结果集
5.关闭连接
JDBC的Statement是什么?
Statement是JDBC中用来执行数据库SQL查询语句的接口。通过调用连接对象的getStatement()方法我们可以生成一个Statement对象。我们可以通过调用它的execute(),executeQuery(),executeUpdate()方法来执行静态SQL查询。
由于SQL语句是程序中传入的,如果没有对用户输入进行校验的话可能会引起SQL注入的问题,如果想了解更多关于SQL注入的,可以看下这里
默认情况下,一个Statement同时只能打开一个ResultSet。如果想操作多个ResultSet对象的话,需要创建多个Statement。Statement接口的所有execute方法开始执行时都默认会关闭当前打开的ResultSet。

execute,executeQuery,executeUpdate的区别是什么?

Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true。如果结果不是ResultSet,比如insert或者update查询,它就会返回false。我们可以通过它的getResultSet方法来获取ResultSet,或者通过getUpdateCount()方法来获取更新的记录条数。
Statement的executeQuery(String query)接口用来执行select查询,并且返回ResultSet。即使查询不到记录返回的ResultSet也不会为null。我们通常使用executeQuery来执行查询语句,这样的话如果传进来的是insert或者update语句的话,它会抛出错误信息为 “executeQuery method can not be used for update”的java.util.SQLException。
Statement的executeUpdate(String query)方法用来执行insert或者update/delete(DML)语句,或者 什么也不返回DDL语句。返回值是int类型,如果是DML语句的话,它就是更新的条数,如果是DDL的话,就返回0。
只有当你不确定是什么语句的时候才应该使用execute()方法,否则应该使用executeQuery或者executeUpdate方法。

JDBC的PreparedStatement是什么?

PreparedStatement对象代表的是一个预编译的SQL语句。用它提供的setter方法可以传入查询的变量。
由于PreparedStatement是预编译的,通过它可以将对应的SQL语句高效的执行多次。由于PreparedStatement自动对特殊字符转义,避免了SQL注入攻击,因此应当尽量的使用它。

PreparedStatement中如何注入NULL值?

可以使用它的setNull方法来把null值绑定到指定的变量上。setNull方法需要传入参数的索引以及SQL字段的类型,像这样:
ps.setNull(10, java.sql.Types.INTEGER)

Statement与PreparedStatement区别:


结构化查询语言(SQL)可分为:
1.数据定义语言(DDL):Data Definition Language
2.操纵语言(DML):Data Manipulation Language
3.事务操控语言(TCL):Transaction  Control Language
4.数据查询语言(DQL):Data Query Language
5.数据操控语言(DCL):Data Control Language
如何优化SQL?
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
5.in 和 not in 也要慎用,否则会导致全表扫描
6.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
7.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描
8. 避免频繁创建和删除临时表,以减少系统表资源的消耗。
9. 尽量避免大事务操作,提高系统并发能力。
简述data和timestamp的区别:
data的最小单位是秒,timestamp包含小数位的秒;
如果需要秒以下的单位,需要timestamp;

视图的意义:
1.简化复杂查询;如果需要经常执行某项查询,可以基于这个复杂查询建立视图,此后查询此视图即可;
2.限制数据访问;视图本质上是一条select语句,所以当访问视图时,只能访问到所对应的select语句中涉及到的列,对基表中的其他列起到安全和保密的作用;
Exists和in的的区别:
IN:
确定给定的值是否与子查询或列表中的值相匹配。
EXISTS:
指定一个子查询,检测行的存在。
Truncate、drop、delete的区别:


三、WEB部分:


AJAX的优缺点是:
优点:
1、最大的一点是页面无刷新,用户的体验非常好
2、使用异步方式与服务器通信,具有更加迅速的响应能力。
3、可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序
缺点:
1、ajax不支持浏览器back按钮。
2、安全问题 AJAX暴露了与服务器交互的细节。
3、对搜索引擎的支持比较弱。
4、破坏了程序的异常机制。
5、不容易调试




JSP有那些内置对象?作用分别是什么?
·HttpServletRequest类的request对象:代表请求对象,主要用于接收客户端通过HTTP协议连接传输到服务端的数据
·HttpServletResponse类的response对象:代表响应对象,主要用于向客户端回应发送数据。
·ServletContext类的application对象:主要用于保存所有应用系统中的共有数据,它是一个共享的内置对象,即是一个容器中的多个用户共享一个application对象,只要没有关闭服务器,application一直存在。
·HttpSessoin类的session对象:主要用来区分每个用户信息和会话状态。
·Pagecontext类的pageContext对象:主要用来管理页面属性,代表了一个页面的上下文,pageContext对象的创建和初始化都是有容器自动完成的。
·Object类的page对象:代表正在运行的JSP页面,也就是说page对象代表了JSP被编译后的Servlet。page对象只能用在当前的JSP范围之内。
·ServletConfig类的config对象:代码片段配置对象,用于初始化Servlet的配置参数。
·JspWriter类的out对象:主要用于向客户端输出数据。
·exception对象:处理JSP文件执行时发生的错误和异常,只要在错误页面里才能使用。
---输入输出对象:request 、respnose、out
---作用域通信对象:session、application、pageContext
---Servlet对象:page、config
---异常对象:execption
  说出JSP的6个动作指令和作用?
·jsp:include:在页面被请求的时候引入一个静态或动态的文件。
·jsp:useBean:寻求或者实例化一个JavaBean。
·jsp:setProperty:设置JavaBean的属性。
·jsp:getProperty:获取某个JavaBean的属性。
·jsp:forward:把请求转到一个新的页面(html文件、jsp文件或者一个程序段)。
·jsp:plugin:根据浏览器类型为Java插件生成object或embed标记。
 JSP的3种跳转方式
·response.sendRedirct()方法:重新发送请求。
·response.setHeader()方法:与response.sendRedirect()方法。
·<jsp:forward page=”跳转的页面”/>:是服务器端的跳转。

牢记Servlet的生命周期?
答:Servlet的生命周期从Web加载Servlet开始,
通过调用Servlet的init()方法进行Servlet的初始化,
通过调用service()方法处理请求,,根据不同的请求调用不同的方法
服务结束,Web容器调用Servlet的destroy()方法
GET和POST的区别:
---从提交的数据量上来说,get方式会将请求参数及参数值放在请求资源路径里面,
携带的数据大小有限制,不适合提交大量的数据;post方式会将请求参数及参数
值放在实体内容里面,理论上没有限制,适合大量数据的提交;
---从安全上来 讲,post方式相对安全(因为请求参数及值存放在实体内容里面,而get方式会将请求参数及值显示在浏览器地址栏);
转发与重定向的区别:
---重定向是浏览器发送请求并收到响应以后再次向一个新地址发请求,转发是服务器收到请求后为了完成响应转发到一个新的地址;
---重定向中有两次请求,不共享数据,转发只产生一次请求,且在组件之间共享数据;
---重定向后地址栏地址改变,而转发则不会;
---重定向的新地址可以是任意地址,转发到的新地址必须是同一个应用内的某个地址;
Cookie和Session的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
   考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
   考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
关于错误提示:
404:
--web.xml文件中的<servlet-name>不一致
--工程没有部署
--Web应用程序部署结构没有遵守Servlet规范;
405:
--service方法名写错;
--service方法参数类型与标准不一致;
--service方法异常、返回值类型与标准不一致;
500:
--Servlet类没有继承HttpServlet或实现Servlet借口;
--web.xml文件中的<servlet-class>x写错;
--service方法中的代码运行时抛出异常;
--有可能是web.xml文件中配置错误;
JSP与Servlet的区别:
1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
2.jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
3.Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到.
4.Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。



四、框架部分:
springmvc的工作流程?

mybatis中的#号和$号有什么区别:
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。
如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,  如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.