java开发面试题库参考

1、javaSE

1.1、原理

1.1.1、简述类加载机制

答:Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中。在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的,除非我们有特殊的用法,像是反射,就需要显式的加载所需要的类。

      Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。这当然就是为了节省内存开销。

     Java的类加载器有三个,对应Java的三种类:

     Bootstrap Loader  // 负责加载系统类 (指的是内置类,像是String)

          - - ExtClassLoader   // 负责加载扩展类(就是继承类和实现类)

                      - - AppClassLoader   // 负责加载应用类(程序员自定义的类)

1.1.2、简述JVM的常用参数

答:-Xss128k -Xmn5M -Xms10M -Xmx10M表示每个线程的大小是128k,新生代5M,可用堆内存10M,最大可用内存为10M

-Xss 设置每个线程的栈内存大小

-Xmn 设置新生代大小

-Xms 设置堆内存的初始内存大小

-Xmx 设置堆内存的最大可用大小

1.1.3、简述GC的基本原理

答:当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。

1.1.4、栈和堆的区别?什么时候用栈?什么时候用堆

a)栈是JVM为正在调用的方法自动分配的一块对应的空间,也就是栈帧,用于存储正在调用的方法中的所有局部变量(包括参数),当方法调用完成时,其对应的栈帧被清除,局部变量失效。
b)堆是由程序员控制申请分配的一块内存空间,用于存储所有new出来的对象(包括成员变量),在对象创建时被申请分配的内存同对象回收时一并被回收,内存释放工作由程序员控制,容易产生内存泄漏。
一般来说在方法中用栈,在类中用堆。

 

1.2 集合

1.2.1、List、Map、Set三个接口,存取元素时,各有什么特点

答:List 以特定次序来持有元素,可有重复元素;Set 无法拥有重复元素,内部排序;Map 保存key-value值,value可多值。

List表示有先后顺序的集合,当我们多次调用add(Obj e)方法时,每次加入的对象按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象。

List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个功共同的父接口,叫Collection。Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象 ,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

1.2.2、HashMap和Hashtable的区别

答:HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。

Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface一个实现。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。

Hashtable和HashMap采用的hash/rehash算法大概一样,所以性能不会有很大的差异。

1.2.3、hashmap存储原理

HashMap是一种‘链表散列’的数据结构,即:数组与链表的结合体。

 java开发面试题库参考

存储:

在hashMap中进行存储是利用put方法来进行的,当进行put操作的时候,如果key存在,新的值会将旧的值进行覆盖(特别值得注意的是:当key存在的情况下,会返回一个旧的值,如果不存在key,就会返回null)。

细节:

当进行put操作的时候,先根据hashCode重新计算hash值,根据hash值计算得到这个元素在数组中的下标位置,如果这个下标中已经存在元素,那么这个位置的元素将以链表的形式存储,新加入的元素放在表头,早先加入的就放在链尾;如果没有就直接将元素放在该数组指定下标位置中。

1.2.4、Hashset和Treeset的区别

 LinkekHashSet会记录放入hashset中的元素顺序,可以按顺序遍历出来。Sortedset会对集合中的元素进行排序;treeset是sortedset的一个实现类,会将元素按升序排列;放入treeset中的元素必须实现comparable接口,重写compareTo()方法。

1.3、算法

1.3.1、排序都有哪几种?用JAVA实现一个快速排序

答:排序有冒泡排序、选择排序、快速排序等。

public class QuickSort {

public void quickSort(String[] strDate,int left,int right){

String middle,tempDate;

int i,j;

i=left;

j=right;

middle=strDate[(i+j)/2];

do{

while(strDate[i].compareTo(middle)<0&& i<right)

i++; //找出左边比中间值大的数

while(strDate[j].compareTo(middle)>0&& j>left)

j--; //找出右边比中间值小的数

if(i<=j){ //将左边大的数和右边小的数进行替换

tempDate=strDate[i];

strDate[i]=strDate[j];

strDate[j]=tempDate;

i++;

j--;

}

}while(i<=j); //当两者交错时停止

 

if(i<right){

quickSort(strDate,i,right);//从

}

if(j>left){

quickSort(strDate,left,j);

}

}

public static void main(String[] args){

String[] strVoid=new String[]{"11","66","22","0","55","22","0","32"};

QuickSort sort=new QuickSort();

sort.quickSort(strVoid,0,strVoid.length-1);

for(int i=0;i<strVoid.length;i++){

System.out.println(strVoid[i]+" ");

}

}

1.3.2、用递归列出目录及其所有子目录下的文件路径---删除目录

public class Test {

public void del(File file){

if(file.isDirectory()){

File[] fs = file.listFiles();

for(File f : fs){

del(f);

}

}

// file.delete();

System.out.println(file.getPath());

}

}

1.4、面向对象

1.4.1、面向对象有哪些特征

答:面向对象的特征主要有以下几个方面:

抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地

注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一

部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了

一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称

为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原

始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,

并且类可以修改或增加新的方法使之更适合特殊的需要。

封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。

面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封

装的对象,这些对象通过一个受保护的接口访问其他对象。

多态性:多态性是指允许不同类的对象对同一消息作出响应。多态性包括参

数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的

优势,很好的解决了应用程序函数同名问题。

1.4.2、静态变量和实例变量的区别?

答:在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

1.4.3、final, finally, finalize的区别。

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

内部类要访问局部变量,局部变量必须定义成final类型。

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

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

1.4.4、static关键字

答:static 修饰的字段和方法,既可以通过类调用,也可以使用实例调用;

没static 修饰的字段和方法,只能使用实例来调用(建议使用:类名来调用; 其实在底层,对象调用类成员,也会转换类名调用)

static关键字不能与this,super同时连用!

1.4.5、接口和抽象类的比较

答:相同点(都位于继承的顶端,用于被其他实现或继承;都不能实例化;都包含抽象方法,其子类都必须覆写这些抽象方法)

不同点(抽象类为部分方法提供实现,避免子类重复实现这些方法,提供代码重用性;接口只能包含抽象方法;一个类只能继承一个直接父类,却可以实现多个接口)

优先选用接口,尽量少用抽象类;需要定义子类的行为,又要为子类提供共性功能时才选用抽象类

 java开发面试题库参考

 

1.4.6、为什么接口中不可以有构造方法,但是抽象类中可以有构造方法

在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors。

A. 构造方法用于初始化成员变量,但是接口没有成员变量。接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的,

B. 类可以实现多个接口,若多个接口都有自己的构造器,则不好决定构造器链的调用次序

C. 在抽象类中可以有构造方法,只是不能直接创建抽象类的实例对象,但实例化子类的时候,就会初始化父类,不管父类是不是抽象类都会调用父类的构造方法,初始化一个类,先初始化父类。

 

 

1.5、核心API

1.5.1、 概述String,StringBuffer与StringBuilder的区别

答:String本身是一个代表字符串的类,String是一个常量,定义好之后不可更改;字符串是被共享的。String中提供了一系列操作而不改变原串的方法

StringBuilder是线程不安全的,StringBuffer是线程安全的。---底层实际上是一个字符数组

1.5.2、 String有没有length()这个方法?数组有没有length()这个方法?

答: String有length()这个方法;数组没有length()这个方法,有length的属性。

 

1.5.3、 两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,这句话对不对?

如果数据是存储在以哈希值作为定位的数据结构,那么当x.equals(y)==true,hashcode必须相等,否则会造成资源的浪费。

 

1.6、IO操作

1.6.1、流分为哪些类

答:按流动方向的不同可以分为输入流和输出流;按处理数据的单位不同分为字节流和字符流;按功能的不同可分为节点流和处理流。

所有流都继承于以下四种抽象流的某一种

java开发面试题库参考

1.6.2、谈谈操作流的步骤

答:首先,用File类找到一个文件对象,得到IO操作的源或目标;其次,通过字节流或字符流的子类创建对象(得到IO操作的通道);之后,进行读或写的操作(IO操作);最后,关闭输入/输出流(打完收工,注意节约资源,关掉)。

由于流的操作属于资源操作,所以在操作的最后一定要关闭以释放资源。

1.7、线程

1.7.1、sleep() 和 wait() 有什么区别

答:sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。

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

答:主要相同点:Lock能完成synchronized所实现的所有功能

主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。

1.7.3、线程的生命周期

答:线程的状态有新建、运行、阻塞、就绪、死亡。

java开发面试题库参考

1.7.4、ThreadLocal

ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程的副本冲突。优势:提供了线程安全的共享对象 与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源,这样当然不需要多个线程进行同步了。

 

1.8、反射

1.8.1、如何利用反射创建对象

答:使用Class对象的newInstance()方法创建该Class对象的实例,此时该Class对象必须要有无参数的构造方法。

使用Class对象获取指定的Constructor对象,再调用Constructor的newInstance()方法创建对象类的实例,此时可以选择使用某个构造方法。如果这个构造方法被私有化起来,那么必须先申请访问,将可以访问设置为true。

1.8.2、如何使用反射调用方法

答:每个Method的对象对应一个具体的底层方法。获得Method对象后,程序可以使用Method里面的invoke方法来执行该底层方法。

Object invoke(Object obj,Object ... args):obj表示调用底层方法的对象,后面的args表示传递的实际参数。

如果底层方法是静态的,那么可以忽略指定的 obj 参数,该参数可以为 null;如果底层方法所需的形参个数为 0,则所提供的 args 数组长度可以为 0 或 null;如果底层方法返回的是数组类型,invoke方法返回的不是底层方法的值,而是底层方法的返回类型。

2、JavaWEB

2.1、MySQL数据库

2.1.1、说出一些数据库优化的经验

答:用PreparedStatement 一般来说比Statement性能高:一个sql 发给服务器去执行,涉及步骤:语法检查、语义分析, 编译,缓存。

有外键约束会影响插入和删除性能,如果程序能够保证数据的完整性,那在设计数据库时就去掉外键。

sql语句全部大写,特别是列名和表名都大写。特别是sql命令的缓存功能,更加需要统一大小写。

还有索引对查询性能的改进也是值得关注的。

2.1.2、什么是数据库里面的索引和约束

答:索引就是一个指向表中数据的指针,如果我们把书比作数据,那么各个章节就相对于数据库中的表,而书的目录就是索引了。索引是在基本表的列上建立的一种数据库对象,它和基本表分开存储,它的建立或撤销对数据的内容毫无影响。索引一经创建,就完全由系统自动选择和维护,不需要用户指定使用索引,也不需要用户执行打开索引或进行重新索引等操作。

设计数据库完整性的目的是为了防止数据库存在不符合语义的数据,防止错误信息的输入和输出。SQL Server提供的用来实施数据完整性的途径主要是约束(Constraint)、标识列(Identity Column)、默认(Default)、规则(Rule)、触发器(Trigger)、数据类型(Data Type)、索引(Index)和存储过程(Stored Procedure)等

2.1.3、谈谈数据库的存储过程

答:存储过程的实验步骤:

mysql> delimiter |

mysql> create procedure insertArticle_Procedure (pTitle varchar(50),pBid int,out

 pId int)

    -> begin

    -> insert into article1 value(null,pTitle,pBid);

    -> select max(id) into pId from article1;

    -> end;

    -> |

Query OK, 0 rows affected (0.05 sec)

 

mysql> call insertArticle_Procedure('大数据',1,@pid);

    -> |

Query OK, 0 rows affected (0.00 sec)

 

mysql> delimiter ;

mysql> select @pid;  

+------+

| @pid |

+------+

| 3    |

+------+

1 row in set (0.00 sec)

 

mysql> select * from article1;

+----+--------------+------+

| id | title        | bid  |

+----+--------------+------+

| 1  | test         | 1    |

| 2  | dashuju | 1    |

| 3  |大数据     | 1    |

+----+--------------+------+

3 rows in set (0.00 sec)

2.1.4、Mysql的索引原理

索引(Index)是帮助MySQL高效获取数据的数据结构。

提取句子主干,就可以得到索引的本质:索引是一种数据结构B+Tree

 java开发面试题库参考

2.1.5、数据库技术中的“脏数据”指的是什么?一般如何处理?

从数据库到数据仓库,脏数据概括起来就是

(1)不完整的数据(比如如供应商的名称、分公司的名称、客户的区域信息缺失、业务系统中主表与明细表不能匹配等)

解决方法:补全

(2)错误的数据(比如数值数据输成全角数字字符、字符串数据后面有一个回车操作、日期格式不正确、日期越界等)

解决方法:对错误进行分类,然后写SQL语句挑出来,再提交给业务部门修正,最后再重新抽取

(3)重复的数据

解决方法:将重复数据记录的所有字段导出来,让客户确认并整理。

2.1.6、事务的概念和特点

概念:事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。

特点:ACID

原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 

一致性(Consistency)

事务前后数据的完整性必须保持一致。隔离性(Isolation)

事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。

持久性(Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

2.1.7、简单写出oracle分页或mysql分页

Oracle:

SELECT * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
WHERE ROWNUM <= 40
)
WHERE RN >= 21或者

SELECT * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
)
WHERE RN BETWEEN 21 AND 40

Mysql:  

select * from test limit 10,30

 

2.2、Servlet

2.2.1、说一说Servlet的生命周期

答:servlet的生命周期包括加载和实例化、初始化、处理请求以及服务结束。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。

Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。

web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。

2.2.2、转发与重定向的比较?

//转发到new.jsp

request.getRequestDispatcher("new.jsp").forward(request, response); 

//重定向到new.jsp 
response.sendRedirect("new.jsp");

<!--在jsp页面中实现转发: -->

<jsp:forward page="apage.jsp" />

<!--在jsp页面中实现重定向: -->

<%response.sendRedirect("new.jsp");//重定向到new.jsp%>

1.重定向访问服务器两次,转发只访问服务器一次。
2.重定向可以看见目标页面的URL,转发只能看见第一次访问的页面URL,以后的工作都是有服务器来做的。
3.重定向跳转后必须加上return,要不然页面虽然跳转了,但是还会执行跳转后面的语句,转发是执行了跳转页面,下面的代码就不会在执行了。
4.在request级别使用信息共享,使用重定向必然出错

5.重定向可以访问自己web应用以外的资源

 

2.3、Request和Response

2.3.1、Request对象的主要方法:

setAttribute(String name,Object):设置名字为name的request的参数值

getAttribute(String name):返回由name指定的属性值

getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组

getCharacterEncoding():返回请求中的字符编码方式

实例

getParameter(String name):获得客户端传送给服务器端的有name指定的参数值

getParameterValues(String name):获得有name指定的参数的所有值

getProtocol():获取客户端向服务器端传送数据所依据的协议名称

getRequestURI():获取发出请求字符串的客户端地址

getRemoteAddr():获取客户端的IP地址

getRemoteHost():获取客户端的名字

getSession([Boolean create]):返回和请求相关Session

getServerName():获取服务器的名字

getServletPath():获取客户端所请求的脚本文件的路径

getServerPort():获取服务器的端口号

removeAttribute(String name):删除请求中的一个属性

2.3.2、request和response的作用

Request对象:为脚本提供了当客户端请求一个页面或者传递一个窗体时,客户端提供的全部信息。这包括能指明浏览器和用户的HTTP变量,在这个域名下存放在浏览器中的cookie,任何作为查询字符串而附于URL后面的字符串或页面的<FORM>段中的HTML控件的值。也提供使用Secure Socket Layer(SSL)或其他加密通信协议的授权访问,及有助于对连接进行管理的属性。

Response对象:用来访问服务器端所创建的并发回到客户端的响应信息。为脚本提供HTTP变量,指明服务器和服务器的功能和关于发回浏览器的内容的信息,以及任何将为这个域而存放在浏览器里新的

2.4、Cookie和Session

2.4.1、cookie与session的区别

cookie是客户端技术,将数据保存在客户端,保存时间一般比较长, 但是安全性差。浏览器能够查看保存的本地Cookie并进行Cookie欺骗。通过Http协议实现,基于set-cookie响应头和cookie请求头工作。

Cookie如果不设置过期时间,则表示这个cookie声明周期为浏览器会话期间,只要关闭浏览器cookie就小时了

session将数据保存服务器端,保存时间一般较短, 但是安全性高。是一个域对象,将数据保存在域中,服务器在运行时可以为每一个浏览器创建一个独享的session对象,用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当再去访问时,从各自的session中取出数据 。当访问增多,会比较占用服务器的性能。

单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie。而Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型

没有直接删除cookie的方法如果想要删除一个Cookie, 可以向浏览器发送一个 同名 同path 同domain的Cookie, 只需要将Cookie的maxAge设置为0

而session可以自杀:当调用session.invalidate()方法的时session立即销毁

Cookie的应用场景:记住用户名

Session的应用场景:保存用户信息,实现登录显示,三十天自动登录,保存购物车信息。

Session的运行依赖session id,而session id是存在cookie中的,也就是说浏览器禁用了cookie,同时session也会失效(但是可以通过其他方式实现,比如在url中传递session id)

Cookie的不安全性:

如果你在机器上面保存了某个论坛的cookie,有效期是一年,如果有人入侵你的机器,将你的cookie拷走,然后放在他的浏览器目录下面,那么他登录该网站的时候就是用你的身份登录的。所以cookie是可以伪造的。

当然,伪造的时候需要注意,直接拷贝cookie文件到cookie目录,浏览器是不忍的,它有一个index.dat文件,存储了cookie文件的建立时间,以及是否有修改,所以你必须要有该网站的cookie文件,并且保证时间上骗过浏览器

2.4.2、session什么时候被创建,什么时候被删除

直到某server端程序(Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。

session在下列情况下被删除:

A.程序调用HttpSession.invalidate()

B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间

C.服务器进程被停止

 

再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。

2.5、过滤器和监听器

2.5.1、Filter 的作用是什么?

Servlet Filte是过滤器,功能是阻止url,过滤url请求,只有符合要求时才会批准通过进行响应。

在servlet中有request 和response 这两种请求方式,其中request是向服务器发起请求,而response是向客户端也就是浏览器发送的请求,而filter就是在请求的途中进行判断拦截,在到达最后的目的地之前进行一些相应的处理,比如全站乱码解决器,就是在所有的请求之前加上乱码解决的处理,这样就可以不用在每一个地方频繁地进行处理乱码的问题。

开发中首先要在web.xml中声明过滤器,然后在.java中写过滤的内容。

PS:还有一些用到过滤器的地方:配置30天自动登陆、权限控制过滤器,密码过滤器,认证过滤器......只要有需要,就可以自己定义

 

2.5.2、Filter的生命周期?

Filter的生命周期同servlet的生命周期是一样的。它们都提供了init()和destroy()方法来控制。当web容器启动的时候,就会自动调用init()来对filter进行初始化,而且只会执行依次,当关闭web容器,关机,或者reload整个应用时,都会调用destroy()来关闭filter。也就是说,当web容器启动时,filter就被加载到内存,并在destroy()调用之前都常驻内存。

如果在web.xml中配置了多个过滤器,那么会按照顺序依次执行过滤器。

2.5.3、过滤器和监听器的区别

过滤器

Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁

监听器

Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。

 

2.5.4拦截器和过滤器的区别

l 拦截器是基于Java的反射机制的,而过滤器是基于函数回调。

l 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

l 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

l 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

l 拦截器可以访问action上下文里的对象,而过滤器不能访问。

l 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

 

2.6、设计模式

2.6.1、你了解哪些设计模式

答:常见的五种设计模式(单例模式、装饰者模式、代理模式、观察者模式以及工程模式)需要答出来

2.6.2、说一下单例模式

答:单例模式是指整个应用中有且只有一个实例,所有指向该类型实例的引用都指向这个实例。

常见的单例模式有饿汉式和懒汉式

饿汉式会直接将对象定义出来,它使用static修饰,随着类的加载而加载,会损耗性能,但是方法相对简单;懒汉式只给出变量,并不将其初始化,它在第一次用的时候相对较慢,因为需要加载,线程不安全。

3、框架

3.1、Spring

3.1.1、Bean

我们知道Spring其实就是一个大型的工厂,而Spring容器中的Bean就是该工厂的产品.对于Spring容器能够生产那些产品,则取决于配置文件中配置。

对于我们而言,我们使用Spring框架所做的就是两件事:开发Bean、配置Bean。对于Spring创建来说,它要做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法完成“依赖注入”。

每一个Bean对应Spring容器里的一个Java实例定义Bean时通常需要指定两个属性。

Id:确定该Bean的唯一标识符,容器对Bean管理、访问、以及该Bean的依赖关系,都通过该属性完成。Bean的id属性在Spring容器中是唯一的。    

Class:指定该Bean的具体实现类。注意这里不能使接口。通常情况下,Spring会直接使用new关键字创建该Bean的实例,因此,这里必须提供Bean实现类的类名。

3.1.2、IOC和DI

IOC是控制反转:

将依赖对象的创建交给第三方实现从而降低耦合度。

对象的创建过程由Spring容器来管理,程序员从此无需关注对象的创建过程,Spring容器管理对象的生命周期。

3.1.3、AOP

Aop:面向切面编程,运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程,其中A代表了切面的意思,是一个关注点的模块化,这个关注点就是比如j2ee中的事务管理,用Spring的Advisor或拦截器实现,进入这个事务管理有一个切入点,这个切入点是一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

3.1.4、数据源

数据源(Data Source)顾名思义,数据的来源,是提供某种所需要数据的器件或原始媒体。在数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接。

不管采用何种持久化技术,都需要定义数据源。Spring中提供了4种不同形式的数据源配置方式:

spring自带的数据源(DriverManagerDataSource),DBCP数据源,C3P0数据源,JNDI数据源。

3.1.5、注解

spring 注解可以减少xml配置;

注释配置相对于 XML 配置具有很多的优势:

  它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。

  注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。

3.2、SpringMVC

3.2.1、工作原理

1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配前端控制器(或分发器/DispatcherServlet)的请求映射路径,web容器将请求转交给DispatcherServlet.

2、DipatcherServlet接收到这个请求之后将根据请求的信息以及处理器映射器(HandlerMapping)的配置找到处理请求的处理器(Handler)。

3、由具体的处理器适配器(HandlerAdapter)对Handler进行具体的调用。

4、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。

5、DispatcherSevlet通过视图解析器(ViewResolver)将ModelAndView()转化为真正的视图View。

6、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。

 

3.2.2、springmvc容器与Spring容器的区别

 java开发面试题库参考

Spring会创建一个WebApplicationContext上下文,称为容器 ,保存在 ServletContext中,key是 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);  

DispatcherServlet是一个Servlet,可以同时配置多个,每个DispatcherServlet有一个自己的上下文对象(SevletWebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容,但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key 是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。 当一个Request对象产生时,会把这个子上下文对象(SevletWebApplicationContext)保存在Request对象中,key是 DispatcherServlet.class.getName() + ".CONTEXT"。可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);  说明:Spring 并没有限制我们,必须使用父子上下文。我们可以自己决定如何使用。

父上下文容器中保存数据源、服务层、DAO层、事务的Bean。子上下文容器中保存MVC相关的Action的Bean。事务控制在服务层。由于父上下文容器不能访问子上下文容器中内容,事务的Bean在父上下文容器中,无法访问子上下文容器中内容,就无法对子上下文容器中Action进行AOP(事务)。

 

3.3、Mybatis

3.3.1、mybatis和jdbc区别?

MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。

1. 优化获取和释放

一般在访问数据库时都是通过数据库连接池来操作数据库,耦合性比较高,我们可以通过DataSource进行隔离解耦,我们统一从DataSource里面获取数据库连接。

2.SQL统一管理,对数据库进行存取操作

使用JDBC对数据库进行操作时,SQL查询语句分布在各个Java类中,可读性差,不利于维护,修改Java类中的SQL语句时要重新进行编译。

Mybatis可以把SQL语句放在配置文件中统一进行管理,以后修改配置文件,也不需要重新就行编译部署。

3.生成动态SQL语句

在查询中可能需要根据一些属性进行组合查询,如果使用JDBC进行查询,这样就需要写多条SQL语句,而Mybatis可以在配置文件中通过使用<if test=””></if>标签进行SQL语句的拼接,生成动态SQL语句

4.能够对结果集进行映射

在使用JDBC进行查询时,返回一个结果集ResultSet,我们要从结果集中取出结果封装为需要的类型,而在Mybatis中我们可以设置将结果直接映射为自己需要的类型

3.3.2、Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别。

能,Mybatis不仅可以执行一对一、一对多的关联查询,还可以执行多对一,多对多的关联查询,多对一查询,其实就是一对一查询,只需要把selectOne()修改为selectList()即可;多对多查询,其实就是一对多查询,只需要把selectOne()修改为selectList()即可。

关联对象查询,有两种实现方式,一种是单独发送一个sql去查询关联对象,赋给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用join查询,一部分列是A对象的属性值,另外一部分列是关联对象B的属性值,好处是只发一个sql查询,就可以把主对象和其关联对象查出来。

那么问题来了,join查询出来100条记录,如何确定主对象是5个,而不是100个?其去重复的原理是<resultMap>标签内的<id>子标签,指定了唯一确定一条记录的id列,Mybatis根据<id>列值来完成100条记录的去重复功能,<id>可以有多个,代表了联合主键的语意。

同样主对象的关联对象,也是根据这个原理去重复的,尽管一般情况下,只有主对象会有重复记录,关联对象一般不会重复。

 

 

3.4、Shiro 

参考:https://www.cnblogs.com/fengli9998/p/6676783.html

3.4.1、Shiro的权限管理是如何实现?

 shiro通过<shiro:hasPermission name=””>标签实现对功能模块的保护,

并通过doGetAuthorizationInfo方法获取当前用户的权限列表,若该用户的权限列表中含有name属性中的值,则给予访问权限

3.4.2、shiro的认证原理

认证原理:

1、通过ini配置文件创建securityManager

2、调用subject.login方法主体提交认证,提交的token

3、securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。

4、ModularRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息

5、IniRealm根据输入的token(UsernamePasswordToken,即这里的token是用户从页面输入的信息)从 shiro-first.ini查询用户信息(这里是测试阶段,后面都是查询的数据库,注入service,调用dao),根据账号查询用户信息(账号和密码)

如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)

  如果查询不到,就给ModularRealmAuthenticator返回null

6、ModularRealmAuthenticator接收IniRealm返回Authentication认证信息

  如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)

  如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)

3.5、SpringBoot

3.5.1、

3.5.2、

 

4、项目

4.1、业务

4.1.1、商品详情页实现思路

4.1.2、单点登录系统的实现思路

4.1.3、传图片有什么问题?

1)文件大小限定,网络传输有限,控制用户上传文件的大小。

2)文档格式,通过文件后缀名判断是否图片类型。

3)文件内容,检验是否是图片,防止恶意用户上传图片木马。如何检查?获取图片的height和width。javaAPI直接提供方法。

4)及时清理文件。它使用的是apache的common文件上传jar。Apache文件上传的原理是先把上传的文件写临时文件,写完后保存到用户指定的目录。这样在文件上传的过程中会产生临时文件,上传完,需要及时清除临时文件

4.1.4、购物车实现思路

4.1.5、如何处理恶意订单

4.2、技术

4.2.1、Nginx反向代理是怎么实现的

答:通过访问后台代理服务器,由它具体访问哪台后台服务器.反向代理服务器,通过前置机将内网与外网隔离屏蔽了后台具体服务器,其他机器是无法直接访问内网中其他服务器资源,这样保证了网络的安全性.

4.2.2、Redis有哪些数据类型?用的是分片还是集群?

答:Redis可以存放string、list、hash、set等类型

回答分片和集群都行,但要说出一二。

4.2.3、如有有上白万的数据并发量,该怎么处理?

4.2.4、服务器集群有哪些?

4.2.5、负载均衡的实现原理是什么?

4.2.6、A网站要请求B网站的接口获取数据,如何实现的?

4.2.7、反向代理是怎么实现的?

4.2.8、sso单点登录有哪些优点?

4.2.9、解释下集群和分布式的概念?

4.2.10、集群中的故障转移是什么概念?

4.2.11、图片压缩是怎么处理的?

4.2.12、Redis持久化的概念是什么?

4.2.13、mysql语句,limit,并发大,某些表很大,怎么做?

4.2.14、读写分离,主从复制延迟性,怎么处理

4.2.15、有哪些会话跟踪技术?

4.2.16、什么是ajax ?

4.2.17、简述如何使用ajax 发送异步请求

4.2.18、Redis分布式实现原理。如何实现读写分离,在这个过程中使用了哪些算法,有什么好处

4.2.19、请根据你对Redis的理解回答下面问题:

a) 常用的数据结构有哪些,简述其特性及应用场景?

b) 持久化的机制有几种,都是怎么样触发的?

c) Redis使用过程中遇到的性能瓶颈有哪些,如何解决?

4.2.20、RabbitMQ中,如果消息发送失败,应该怎么解决