目录
4.switch是否能作用于byte上,是否能作用于long上,是否能作用于String上?
5.short s1 = 1;s1 = s1 + 1;有什么错?short s1 = 1; s1 += 1;有什么错?
7.使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
11.作用域 public,private,protected,以及不写时的区别
12.Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值的类型?
13.构造器 Constructor 是否可被 override?
15.abstract class 和 interface 有什么区别?
17.String s = "Hello";s = s + " world!";这两行代码执行后,原始的String 对象中的内容到底变了没有?
19.String s = new String("xyz");创建了几个String Object? 二者之间有什么区别? xyz 是字面量
21.try {}里有一个 return 语句,那么紧跟在这个try 后的finally {}里的code会不会被执行,什么时候被执行,在 return 前还是后?
22.final, finally, finalize 的区别
25.给我一个你最常见到的 runtime exception
28.同步和异步有何异同,在什么情况下分别使用他们?举例说明。
29.当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法?
33.简述 synchronized 和 java.util.concurrent.locks.Lock 的异同?
34.设计 4 个线程,其中两个线程每次对 j 增加 1,另外两个线程对j 每次减少1。写出程序。
38.List, Set, Map 是否继承自 Collection 接口?
39.List、Map、Set 三个接口,存取元素时,各有什么特点?
41.Collection 和 Collections 的区别。
42.Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()? 它们有何区别?
43.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
44.java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
45.什么是 java 序列化,如何实现 java 序列化?
3.JSP 中动态 INCLUDE 与静态 INCLUDE 的区别
18、Spring 中 Autowired 和 Resource 关键字的区别
22、Spring 基于 xml 注入 bean 的几种方式
33、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么
Java基础
1.&&与&的区别
&&代码示例:
public static void main(String[] args) {
if(test1() && test2()) {
System.out.println("打印");
}
}
private static boolean test1() {
System.out.println("======test1=====");
return false;
}
private static boolean test2() {
System.out.println("======test2=====");
return false;
}
结果为 打印test1
&代码示例:
public static void main(String[] args) {
if(test1() & test2()) {
System.out.println("打印");
}
}
private static boolean test1() {
System.out.println("======test1=====");
return false;
}
private static boolean test2() {
System.out.println("======test2=====");
return false;
}
结果为 打印test1与test2
由此得出结论:
&:代表第一个条件不满足,依旧会执行后面的条件。
&&:代表第一个条件不满足,后面的条件就不会继续执行。
2.八种基本数据类型
基本类型 | 大小(字节) | 默认值 | 封装类 |
byte | 1 | (byte)0 | Byte |
short | 2 | (short)0 | Short |
char | 2 | \u0000(null) | Character |
int | 4 | 0 | Integer |
float | 4 | 0.0f | Float |
long | 8 | 0L | Long |
double | 8 | 0.0d | Double |
boolean | ~ | false | Boolean |
在面试官问到此问题,可以按照以下形式来回答:(这样会觉得你很有条理性)
整型:short、int、long、byte
浮点型:float、double
其他:char、boolean
3.spring的理解
sping有两大特点 IOC及AOP
IOC:是依赖注入,控制反转,特点是管理每个java类创建的bean对象,主要负责对象的实例化,由原来的程序员手动创建对象变成由spring框架容器来创建,权力发生了转移也就是控制反转,凡是要交给spring容器进行管理的都要进行一个配置。
AOP:面向切面编程,能够将共性的代码和非共性的代码进行一个分离,让我们更专注于逻辑性的代码开发。
4.switch是否能作用于byte上,是否能作用于long上,是否能作用于String上?
public static void main(String[] args) {
byte key = 0;
int i = key;
String s = "s";
switch(s) {
case "h":
break;
default:
break;
}
}
switch可以作用于byte上,能作用于long,能作用于JDK1.7之后的String
5.short s1 = 1;s1 = s1 + 1;有什么错?short s1 = 1; s1 += 1;有什么错?
short s1 = 1;s1是short类型,s1 = s1 + 1;1是int类型,short类型加int类型等于int类型;
原因:取高字节的类型,short的字节是2,int的字节是4,所有是int
short s1 = 1;s1 = s1 + 1;代码报错,short类型容纳不下int类型;
short s1 = 1; s1 += 1; 代码不报错,+=是java语言规定的运算符,java编译器会自动对它进行处理
6.char型变量中能不能存贮一个中文汉字?为什么?
可以,char 型变量是用来存储 Unicode 编码的字符的,unicode 编码字符集中包含了汉字,所以,char 型变量中当然可以存储汉字,unicode编码占用两个字节,所以,char 类型的变量也是占用两个字节。
7.使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
引用对象能变,引用不能变
被final修饰的类 不能被继承
被final修饰的变量 引用的指向不能发生改变,引用指向的对象内容可以发生改变
被final修饰的方法 不能被重写
8. "=="和 equals 方法究竟有什么区别?
==:比的是地址
equals:比的是内容
9.静态变量和实例变量的区别?
静态变量是跟着类走的,示例变量是需创建对象,实例化才能够获取,赋值等操作。
10.Integer 与 int 的区别?
integer是类,int是基本数据类型,integer可以让数据操作更加灵活。
11.作用域 public,private,protected,以及不写时的区别
如果在修饰的元素上面没有写任何访问修饰符,则表示 friendly。
作用域 | 当前类 | 同一package | 子孙类 | 其他package |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
friendly | √ | √ | × | × |
private | √ | × | × | × |
只要记住了有 4 种访问权限,4 个访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。
12.Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值的类型?
Overload:重载,方法名相同,参数列表不同(同名不同参)
Override:重写,方法名相同,参数列表也相同(同名同参)
13.构造器 Constructor 是否可被 override?
构造器 Constructor 不能被继承,因此不能重写 Override,但可以被重载 Overload。
14.面向对象的特征有哪些方面
面向对象
重写与重载
特点:
封装:减少重复代码,方便调用
继承:抽取共性的部分
多态:
体现形式:接口、抽象类
具体应用:向上提升,向下转型
特点:能够让代码具备更好的拓展性
(多态) 例:
前提:有一只小狗叫旺财 new Dog(“旺财”)
结论:旺财是一只动物(正确)animal=new dog(“.”)
前提:有一只动物叫旺财 new Dog(“旺财”)
结论:旺财是一只小狗(错误)animal=new dog(“.”)
结论:旺财就是小狗
15.abstract class 和 interface 有什么区别?
据以上代码得出:一个类不能继承多个类
据以上代码得出:一个类可以实现多个接口
so,接口可以被多实现,类只能单继承。
抽象类与接口
抽象类:单继承,可以有抽象方法也可以有具体实现的非抽象方法。
接口:多实现,只能由抽象方法。
16.String 是最基本的数据类型吗?
不是!基本数据类型包括 byte、int、char、long、float、double、boolean 和 short;string不在里面;
java.lang.String 类是 final 类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类。
17.String s = "Hello";s = s + " world!";这两行代码执行后,原始的String 对象中的内容到底变了没有?
没有
对象没变,因为在常量区里hello就是固定的,它是被final所修饰的,内容不会变;
hello world是一个新的对象,内容并没有发生改变
18.是否可以继承 String 类?
String 类是 final 类所以不可以继承。
19.String s = new String("xyz");创建了几个String Object? 二者之间有什么区别? xyz 是字面量
String x = new String("x");
String y = new String("x");
以上代码一共创建了三个对象;
String x = new String("x");
String y = new String("y");
以上代码一共创建了四个对象;
所以说题目的答案是 两个,一个放在常量区,不管写多少遍,都是同一个。New String 每写一遍,就创建一个新的。
20.String 和 StringBuffer 的区别
String 是被final所修饰的固定的字符串,而StringBuffer是一个字符串容器;
它们可以储存和操作字符串,而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer,也可以使用 StringBuffers 来动态构造字符数据。
21.try {}里有一个 return 语句,那么紧跟在这个try 后的finally {}里的code会不会被执行,什么时候被执行,在 return 前还是后?
会执行,在 return 前执行。
try catch 结构,finally的代码必然会执行,try 先执行,如果try里面由返回值return,那么中断,执行finally中代码再唤醒中断代码
22.final, finally, finalize 的区别
final:修饰类,被修饰的类不能让其他类继承;修饰方法,被修饰的方法不能重写;修饰变量,被修饰的变量不能改变引用指向。
finally:try catch中的组成部分,表示总是执行。
finalize:析构函数,垃圾回收机制中的一个方法;在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
23.运行时异常与一般异常有何异同?
普通异常:
在编译期就会报错,需要声明或捕捉,否则通过不了编译期
运行时异常:
编译期不会报错,运行时异常不需要声明或捕捉,它可以通过编译器,但当调用它时会报错
运行时效果:
24.error 和 exception 有什么区别?
error 错误通常是不能通过程序来处理的;比如说内存溢出,不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
25.给我一个你最常见到的 runtime exception
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException,ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException,IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException,MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException,ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException,UnsupportedOperationException
26.线程
是什么?
程序运行的最小单元
如何实现?
extends Thread
implement Runnable
线程的状态?
准备、运行、休眠、等待、阻塞(由CPU的抢占资源情况来决定的)、停止
常用的方法?
Thread t1 = new Thread();
t1.start();
t1.sleep(1000);
t1.wait(), 进入等待状态,< t2.notifyall();唤醒等待线程
死锁?
ab俩个线程,a线程要抢占A锁,b锁要抢占B锁,锁都得不到释放,线程呈现僵持状态
27.sleep() 和 wait() 有什么区别?
sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用 sleep 不会释放对象锁。
wait 是 Object 类的方法,对此对象调用 wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
28.同步和异步有何异同,在什么情况下分别使用他们?举例说明。
同步,一次性只能做一件事情;异步,同一时间点可以做多件事情。
想提高效率,就使用多线程,想要安全性高就使用同步。
29.当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法?
1.其他方法前是否加了 synchronized 关键字,加了代表这个方法是同步方法,如果没加,则能。
2.如果这个方法内部调用了 wait,则可以进入其他 synchronized 方法。
3.如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait,则不能。
30.多线程有几种实现方法?同步有几种实现方法?
两种,分别是继承 Thread 类与实现 Runnable 接口;
同步的实现方面有两种,分别是 synchronized,wait 与 notify。
—wait():使一个线程处于等待状态,并且释放所持有的对象的 lock。
—sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉 InterruptedException 异常。
—notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
—Allnotity():唤醒所有处入等待状态的线程。
31.启动一个线程是用 run()还是 start()?
run() 是启动程序的代码块,启动一个线程是调用 start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
32. 线程的基本概念、线程的基本状态以及状态之间的关系
Java 线程在运行的生命周期中的指定时刻只可能处于6 种不同状态的其中一个状态。
初始状态 | new | 线程被构建,但是还没调用start() 方法 |
运行状态 | runnable | java线程将操作系统中的就绪和运行两种状态称为“运作中” |
阻塞状态 | blocked | 表示线程阻塞 |
等待状态 | waiting | 表示线程进入等待状态,进入此状态后需要等待其他线程做出一些特定的通知或中断 |
超时状态 | time_waiting | 此状态与waiting不同,它可在指定的时间自动返回 |
终止状态 | terminated | 表示该线程已经执行完毕 |
33.简述 synchronized 和 java.util.concurrent.locks.Lock 的异同?
主要相同点:Lock 能完成 synchronized 所实现的所有功能,提高代码的安全性。
主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿锁。
两者的关系与 Interger和int 差不多。
34.设计 4 个线程,其中两个线程每次对 j 增加 1,另外两个线程对j 每次减少1。写出程序。
以下程序使用内部类实现线程,对 j 增减的时候没有考虑顺序问题。
public class ThreadTest1{
private int j;
public static void main(String args[]){
ThreadTest1 tt=new ThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(int i=0;i<2;i++){
Thread t=new Thread(inc);
t.start();
t=new Thread(dec);
t.start();
}
}
private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable{
public void run(){
for(int i=0;i<100;i++){
inc();
}
}
}
class Dec implements Runnable{
public void run(){
for(int i=0;i<100;i++){
dec();
}
}
}
}
35.集合
常见的集合:
List:有下标,继承conllection接口
Set:无下标,继承conllection接口
Map:以键值对的形式,不继承conllection接口
集合子类之间的区别:(通过数据结构来对比
ArrayList与Linkedlist区别:ArrayList查询修改快,增删慢;LinkedList与其相反。
hashSet与treeSet的区别:hashSet的底层是哈希表;treeSet是树,可以用来排序。
hashMap与hashTable的区别:hashMap是线程不安全的;hashTable是线程安全的。
某集合子类的特点
如何对set集合/List集合去重
36.ArrayList 和 LinkedList 的区别
ArrayList查询修改快,增删慢;LinkedList与其相反。
ArrayList 和 LinkedList 在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1.对 ArrayList 和 LinkedList 而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList 而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对 LinkedList 而言,这个开销是统一的,分配一个内部Entry 对象。
2.在 ArrayList 的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在 LinkedList 的中间插入或删除一个元素的开 成就梦想时代卓京教育面试宝典 2022 版【Java 基础】第20 页共24页销是固定的。
3.LinkedList 不支持高效的随机元素访问。
4.ArrayList 的空间浪费主要体现在在 list 列表的结尾预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗相当的空间
37.HashMap 和 Hashtable 的区别
hashMap是线程不安全的;hashTable是线程安全的。
38.List, Set, Map 是否继承自 Collection 接口?
List,Set 是,Map 不是
一、历史原因:Hashtable 是基于陈旧的 Dictionary 类的,HashMap 是 Java 1.2 引进的 Map 接口的一个实现。
二、同步性:Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的,不是同步的。
三、值:只有 HashMap 可以让你将空值作为一个表的条目的 key 或 value。
39.List、Map、Set 三个接口,存取元素时,各有什么特点?
List:有下标;Set:无下标; Map:以键值对的形式
40.去掉一个 List 集合中重复的元素
通过equals方法进行去重的。虽然是调用contains方法,但是contains方法底层是调用了equals方法的。
41.Collection 和 Collections 的区别。
Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List。
Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
42.Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()? 它们有何区别?
先由hashCode判定它的哈希值,再通过equals方法去判定它的内容。
IO流
输入流
字节输入流:InputStream
字符输入流:Reader
输出流
字节输出流:OutputStream
字符输出流:Writer字节流是操作二进制文件的 (图片,视频)
字符流是操作字符的 (文件)如何读写文件,比如从c盘读到d盘
序列化与反序列化
对象->流->对象
作用:快速克隆一个对象
字节流读取图片:
package com.wjun.demo;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* IO流
* @author My
*
*/
public class demo2 {
public static void main(String[] args) throws Exception{
/*
* 1.获取输入流 从哪里读
* 2.获取输出流 写到哪里去
* 3.一个读了多少数据
* 4.那就写多少数据 1k=100B
*
*/
//1要读的图片的路径
FileInputStream in = new FileInputStream("D:/Photos/F/cj4.jpg");
//2要写到哪去的路径
FileOutputStream out = new FileOutputStream("E:/cj.jpg");
byte[] buf = new byte[1024];
while(true) {
int len = in.read(buf);
if(len==-1)
break;
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
43.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
对。
如果对象要保存在 HashSet 或 HashMap 中,它们的 equals 相等,那么,它们的 hashcode 值就必须相等。如果不是要保存在 HashSet 或 HashMap,则与 hashcode 没有什么关系了,这时候 hashcode 不等是可以的,例如arrayList 存储的对象就不用实现 hashcode,当然,我们没有理由不实现,通常都会去实现的。
44.java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。字节流继承于 InputStream OutputStream,字符流继承于 Reader ,Writer。在 java.io 包中还有许多其他的流,主要是为了提高性能和使用方便。
45.什么是 java 序列化,如何实现 java 序列化?
我们有时候将一个 java 对象变成字节流的形式传出去或者从一个字节流中恢复成一个 java 对象;
例如,要将java 对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个 java 对象变成某个格式的字节流再传输,但是,jre 本身就提供了我们可以调用 OutputStream 的 writeObject 方法来做,如果要让 java 帮我们做,要被传输的对象必须实现serializable接口,这样,javac 编译时就会进行特殊处理,编译的类才可以被 writeObject 方法操作,这就是所谓的序列化。需要被序列化的类必须实现Serializable 接口,该接口是一个 mini 接口,其中没有需要实现的方法,implements Serializable 只是为了标注该对象是可被序列化的。
Web后台
jsp
九大内置对象
标签库:c标签
指令:
page:设置编码集
taglib:导入标签库
include:包含界面
动态包含<jsp:include 、静态包含 <%@ include
1、jsp 有哪些内置对象?作用分别是什么
名称 | 作用 |
request | 包含用户端请求的信息 |
response | 包含服务器传回客户端的响应信息 |
session | 与请求有关的会话期 |
pageContext | 管理网页属性 |
application | 服务器启动时创建,服务器关闭时停止,为多个应用程序保存信息 |
out | 向客户端输出数据 |
config | servlet 的架构部件 |
page | 指网页本身 |
exception | 针对错误页面才可使用 |
2.JSP 的常用指令
1、page 指令: 属性最多的指令(实际开发中 page 指令默认),属性最多的一个指令,根据不同的属性,指导整个页面特性格式: 常用属性如下: language:jsp 脚本中可以嵌入的语言种类,这个没用,写与不写一样的; pageEncoding:当前 jsp 文件的本身编码---内部可以包含 contentType contentType:response.setContentType(text/html;charset=UTF-8) import:导入 java 的包 errorPage:当前页面出错后跳转到哪个页面 isErrorPage:当前页面是一个处理错误的页面
2、include 指令: 页面包含(静态包含)指令,可以将一个 jsp 页面包含到另一个 jsp 页面中 格式:<jsp:include >
3、taglib 指令: 在 jsp 页面中引入标签库(jstl 标签库、struts2 标签库) 格式:<%@ include >
3.JSP 中动态 INCLUDE 与静态 INCLUDE 的区别
include 指令格式:<jsp:include >; taglib 指令: 格式:<%@ include >
动态 INCLUDE 用 jsp:include 动作实现,它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数 静态 INCLUDE 用 include 伪码实现,不会检查所含文件的变化,适用于包含静态页面
4.四种会话跟踪技术作用域
page:一个页面
request::一次请求
session:一次会话
application:服务器从启动到停止
Servlet
是什么?
运行再服务端的程序
怎么用?
先继承extends) HttpServlet
配置映射 web.xml 或 @webservlet("/test")
实现方法:doGet/doPost
生命周期?
初始化:init
服务:service
销毁:destroy
doGet / doPost 的区别
对应处理的get/post请求
request的常用方法
setCharsetencoding() 设置字符编码
getParameter() 获取参数
getSession 获取session
... ...
页面跳转:重定向与转发
重定向:response.sendredirect();
转发:request.getrequestdispather.forword
两者区别:
转发:可以传递数据,页面跳转时会携带参数,地址栏不会发生改变。
重定向:不能传递数据,跳转时地址栏会发生改变。
四大作用域
从小到大:
pageContext -> request -> sessoin -> application
session与cookie的区别
session:服务端
cookie:客户端
相同之处:都可以保存数据 (例:有些网站可以记住你所登陆时的密码
不同之处:服务端:安全性高,占用大量服务器资源
客户端:安全性低,占用少量内存,cookie内存是有限的
5.HTTP 请求的 GET 与 POST 方式的区别
1. get 是从服务器上获取数据,post 是向服务器传送数据。
2. 请求的时候参数的位置有区别:get 的参数是拼接在 url 后面,用户在浏览器地址栏可以看到;post 是放在http包的包体中。
3. 能提交的数据有区别,get 方式能提交的数据只能是文本,且大小不超过 1024 个字节,而post 不仅可以提交文本还有二进制文件。所以说想上传文件的话,那我们就需要使用 post 请求方式。
4. get 安全性非常低,post 安全性较高;比如说用户注册,不能把用户提交的注册信息用 get 的方式,会把用户的注册信息都显示在Url 上,是不安全的。
6.解释一下什么是 servlet
Servlet 是服务器端的程序;动态生成 html 页面发送到客户端,但是这样程序里会有很多 out.println(),java 与html语言混在一起很乱,所以后来 sun 公司推出了 JSP.其实 JSP 就是 Servlet,每次运行的时候 JSP 都首先被编译成servlet 文件,然后再被编译成.class文件运行。有了 jsp,在 MVC 项目中 servlet 不再负责动态生成页面,转而去负责控制程序逻辑的作用,控制jsp 与javabean之间的流转。
7.说一说 Servlet 的生命周期
Servlet 生命周期包括三部分:
初始化:Web 容器加载 servlet,调用 init()方法
处理请求:当请求到达时,运行其 service()方法。service()自动派遣运行与请求相对应的doXXX(doGet 或者doPost)方法。
销毁:服务结束,web 容器会调用 servlet 的 distroy()方法销毁 servlet
8.Servlet 的基本架构
public class ServletName extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{}public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{}}
9.什么情况下调用 doGet()和 doPost()
Jsp 页面中的 FORM 标签里的 method 属性为 get 时调用 doGet(),为 post 时调用 doPost()。
10、Request 对象的主要方法
setAttribute(String name,Object):设置名字为 name 的 request 的参数值。
getAttribute(String name):返回由 name 指定的属性值。
getAttributeNames():返回 request 对象所有属性的名字集合,结果是一个枚举的实例。
getCookies():返回客户端的所有 Cookie 对象,结果是一个 Cookie 数组。
getCharacterEncoding():返回请求中的字符编码方式。
getContentLength():返回请求的 Body 的长度 getHeader(String name):获得 HTTP 协议定义的文件头信息。
getHeaders(String name):返回指定名字的 request Header 的所有值,结果是一个枚举的实例。
getHeaderNames():返回所以 request Header 的名字,结果是一个枚举的实例。
getInputStream():返回请求的输入流,用于获得请求中的数据。
getMethod():获得客户端向服务器端传送数据的方法。
getParameter(String name):获得客户端传送给服务器端的有 name 指定的参数值。
getParametervalues(String name):获得有 name 指定的参数的所有值。
getRequestURI():获取发出请求字符串的客户端地址。
getRemoteAddr():获取客户端的 IP 地址。
getSession([Boolean create]):返回和请求相关。
Session getServerName():获取服务器的名字。
11、forward 和 redirect 的区别
转发与重定向
1、从地址栏显示来说
forward 是服务器请求资源,服务器直接访问目标地址的 URL,把那个 URL 的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址; redirect 是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL。
2、从数据共享来说
forward:转发页面和转发到的页面可以共享 request 里面的数据. redirect:不能共享数据。
3、从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块. redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等。
4、从效率来说
forward:高;redirect:低。
12.web.xml 文件中可以配置哪些内容
web.xml 用于配置 Web 应用的相关信息,如:Servlet、监听器(listener)、过滤器(filter) 、相关参数、会话超时时间、安全验证方式、错误页面。
13.MVC 的各个部分都有那些技术来实现?如何实现
MVC 是 Model-View-Controller 的简写。
Model 代表的是应用的业务逻辑(通过 JavaBean,EJB 组件实现)
View 是应用的表示面(由 JSP 页面产生)
Controller 是提供应用的处理过程控制(一般是一个 Servlet) 通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现,这些组件可以进行交互和重用。
14、session 和 cookie 有什么区别
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗,考虑到安全应当使用session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
15、Java 反射技术主要实现类有哪些,作用分别是什么
在 JDK 中,主要由以下类来实现 Java 反射机制,这些类都位于 java.lang.reflect 包中
1、Class 类:代表一个类
2、Field 类:代表类的成员变量(属性)
3、Method 类:代表类的成员方法
4、Constructor 类:代表类的构造方法
5、Array 类:提供了动态创建数组,以及访问数组的元素的静态方法
Spring
ioc:控制反转,依赖注入,利用了工厂模式
由原来程序员手段创建对象的权利,转交给Spring容器;
优点:代码的维护性提高了
aop:面向切面
代理=目标+通知
将核心业务与非核心分离,使程序员将精力都放在核心业务中;
定义切面:* *..*.*service.*del(..)
定义通知:@around
注入的方式:/
set注入
构造注入:
自动装配:byname(根据名字 bytype
@resource @autowised
16、讲一下什么是 Spring
Spring 是一个轻量级的 IoC 和 AOP 容器框架。是为 Java 应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML 的配置、基于注解的配置、基于 Java 的配置。
主要由以下几个模块组成:
Spring Core:核心类库,提供 IOC 服务;
Spring Context:提供框架式的 Bean 访问方式,以及企业级功能(JNDI、定时任务等);
Spring AOP:AOP 服务;
Spring DAO:对 JDBC 的抽象,简化了数据访问异常的处理;
Spring ORM:对现有的 ORM 框架的支持;
Spring Web:提供了基本的面向 Web 的综合特性,例如多方文件上传;
Spring MVC:提供面向 Web 应用的 Model-View-Controller 实现。
17、Spring 的 IOC 和 AOP 机制
我们是在使用 Spring 框架的过程中,其实就是为了使用 IOC,依赖注入,和 AOP,面向切面编程,这两个是 Spring 的灵魂。
spring ioc 初始化流程
IOC:控制反转也叫依赖注入。利用了工厂模式 将对象交给容器管理,你只需要在 spring 配置文件总配置相应的 bean,以及设置相关的属性,让spring 容器来生成类的实例对象以及管理对象。在 spring 容器启动的时候,spring 会把你在配置文件中配置的。
spring 的 IOC 容器是 spring 的核心,spring AOP 是 spring 框架的重要组成部分。
面向方面编程(AOP)是以另一个角度来考虑程序结构,通过分析程序结构的关注点来完善面向对象编程(OOP)。OOP 将应用程序分解成各个层次的对象,而 AOP 将程序分解成多个切面。spring AOP 只实现了方法级别的连接点,在 J2EE 应用中,AOP 拦截到方法级别的操作就已经足够。在 spring 中,未来使IoC 方便地使用健壮、灵活的企业服务,需要利用 spring AOP 实现为 IoC 和企业服务之间建立联系。
18、Spring 中 Autowired 和 Resource 关键字的区别
@Resource 和@Autowired 都是做 bean 的注入时使用,其实@Resource 并不是Spring 的注解,它的包是 javax.annotation.Resource,需要导入,但是 Spring 支持该注解的注入。
1、共同点 两者都可以写在字段和 setter 方法上。两者如果都写在字段上,那么就不需要再写setter 方法。
2、不同点 (1) @Autowired @Autowired 为 Spring 提 供 的 注 解 , 需 要 导 入 包org.springframework.beans.factory.annotation.Autowired;只按照 byType 注入。
@Autowired 注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null 值,可以设置它的 required 属性为 false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier 注解一起使用。
@Resource 有两个重要的属性:name 和 type,而 Spring 将@Resource 注解的name 属性解析为bean的 名字,而 type 属性则解析为 bean 的类型。所以,如果使用 name 属性,则使用byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不制定 name 也不制定type 属性,这时将通 过反射机制使用 byName 自动注入策略。
19、依赖注入的方式有几种,各是什么
一、构造器注入
将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。
优点: 对象初始化完成后便可获得可使用的对象。
缺点: 当需要注入的对象很多时,构造器参数列表将会很长; 不够灵活。若有多种注入方式,每种方式只需注入指定几个依赖,那么就需要提供多个重载的构造函数,麻烦。
二、setter
方法注入 IoC Service Provider 通过调用成员变量提供的 setter 函数将被依赖对象注入给依赖类。
优点: 灵活。可以选择性地注入需要的对象。
缺点: 依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用。
三、接口注入
依赖类必须要实现指定的接口,然后实现该接口中的一个函数,该函数就是用于依赖注入。该函数的参数就是要注入的对象。
优点:接口注入中,接口的名字、函数的名字都不重要,只要保证函数的参数是要注入的对象类型即可。
缺点:侵入行太强,不建议使用。 PS:什么是侵入行? 如果类 A 要使用别人提供的一个功能,若为了使用这功能,需要在自己的类中增加额外的代码,这就是侵入性。
20、解释一下 spring bean 的生命周期
Servlet 的生命周期:实例化,初始 init,接收请求 service,销毁 destroy;
Spring 上下文中的 Bean 生命周期也类似,如下:
1、实例化 Bean:
对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要注入另一个尚未初始化的依赖时,容器就会调用 createBean 进行实例化。对于 ApplicationContext 容器,当 容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的 bean。
2、设置对象属性(依赖注入):
实例化后的对象被封装在 BeanWrapper 对象中,紧接着,Spring 根据 BeanDefinition 中的信息以及通过BeanWrapper提供的设置属性的接口完成依赖注入。
3、处理 Aware 接口:
接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean:
①如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId)方法,此处传递的就是Spring配置文件中 Bean 的 id 值;
②如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory()方法,传递的是Spring工厂自身
③如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用 setApplicationContext(ApplicationContext)方法,传入 Spring 上下文;
(4)BeanPostProcessor: 如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
(5)InitializingBean 与 init-method: 如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
(6)如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用 postProcessAfterInitialization(Object obj, Strings)方法;由于这个方法是在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;
21、解释 Spring 支持的几种 bean 的作用域
Spring 容器中的 bean 可以分为 5 个范围:
1、 singleton:默认,每个容器中只有一个 bean 的实例,单例的模式由 BeanFactory 自身来维护。
2、 prototype:为每一个 bean 请求提供一个实例。
3、 request:为每一个网络请求创建一个实例,在请求完成以后,bean 会失效并被垃圾回收器回收。
4、 session:与 request 范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后,bean 会随之失效。
5、 global-session:全局作用域,global-session 和 Portlet 应用相关。当你的应用部署在Portlet 容器中工作时,它包含很多 portlet。如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全局变量需要存储在 global-session 中。全局作用域与 Servlet 中的 session 作用域效果相同。
22、Spring 基于 xml 注入 bean 的几种方式
(1) Set 方法注入
(2) 构造器注入:①通过 index 设置参数的位置;②通过 type 设置参数类型;
(3) 静态工厂注入
(4) 实例工厂
23、Spring 框架中都用到了哪些设计模式
1、工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例;
2、单例模式:Bean 默认为单例模式。
3、代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成技术;
4、模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate,
JpaTemplate。
5、观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如 Spring 中 listener 的实现--ApplicationListener。
24.StringMVC
工作流程:
一、DispatcherServlet:接受到浏览器端发送的所有请求
二、HandlerMapper处理器映射器:找到被@requestMapping 对应值
三、HandlerAdapter处理器适配器:适配对应的方法调用执行
四、modelAndView模型视图对象:方法的返回值
五、viewResolver解析模型视图对象,得到view,返回给浏览器用户展示;
开发流程:
1、导入pom依赖
2、web.xml中添加核心配置,DispatcherServlet,指向框架SpringMVC.xml的配置文件
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-servlet.xml</param-value>
</init-param>
3、配置springmvc.xml
配置驱动包扫描
<context:compontent-scan base-package="com.javaxl.ssm"/>
重点:配置本地资源视图解析器 (InternalResourceViewResolver)
ViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- viewClass需要pom中引入两个包:standard.jar and jstl.jar -->
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
· 添加静态文件映射
<mvc:resources location="/images/" mapping="/images/**" />
4、contronller层、service层...,正常开发即可
要通过@controller标记当前类被spring所管理
写方法:@requestMapping
方法会有返回值:"bookList" ——> /bookList.jsp
常用的注解:
@controller @requestMapping @getMapping @putMapping @deleteMapping @postMapping
@responseBody (返回json数据) @requestBody (接受json数据) @Pathvariliable (路径传参; /delete/{id})
springmvc怎么返回数据:
转发:"forword:/list"
重定向:"redirect:/list"
25、SpringMVC 怎么样设定重定向和转发的
1、 转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"
2、 重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
26、SpringMVC 常用的注解有哪些
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
@RequestBody:注解实现接收 http 请求的 json 数据,将 json 转换为 java 对象。
@ResponseBody:注解实现将 conreoller 方法返回对象转化为 json 对象响应给客户。
27、Mybatis
是什么?
数据库层面的框架
ORM:object reference mapping 对象关系映射
关联关系的配置
一对一:association javatype
一对多:collection oftype
mapper.xml中配置的常用标签有哪些?
if / for
<! [CDATA[ ... ]]>:用于解决特殊字符转义的,没有VDATA的话,> < &之类的符号会被当成html标签,而不是sql语句的组成部分。
Mybatis中的二级缓存 (默认是关闭的)
提升查询效率
二级缓存:Mapper级别的缓存,默人关闭的
一级缓存:session级别的缓存,默认是开启的;
重点:# 传参与 $ 传参有什么区别
#:传递参数会自带引号
$:不带引号,存在SQL注入的风险,优点是,可以用来做动态列/动态SQL
上述的不同,也就决定了$存在SQL注入的风险
TestMapper.xml 前提tid是varcher
select * from user where tid = # {tid}
select * from user where tid = $ {tid}
28、MyBatis 的优点和缺点
优点:
1、基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。
2、 与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;
3、很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库MyBatis 都支持)。
4、能够与 Spring 很好的集成;
5、提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。 缺点:
(1) SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功底有一定要求。
(2) SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
29、#{}和${}的区别是什么
#{}是预编译处理,${}是字符串替换。
Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
Mybatis 在处理${}时,就是把${}替换成变量的值。
使用#{}可以有效的防止 SQL 注入,提高系统安全性。
30、当实体类中的属性名和表中的字段名不一样,怎么办
第 1 种: 通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
<select id=”selectorder”parametertype=”int” resultetype=”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price
form orders whereorder_id=#{id};
</select>
第 2 种: 通过来映射字段名和实体类属性名的一一对应的关系。
<select id="getOrder" parameterType="int" resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用 id 属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用 result 属性来映射非主键字段,property 为实体类属性名,column 为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
31、如何执行批量插入
为了提升开发效率,要放到一个mapper,一个session中去执行
首先,创建一个简单的 insert 语句: 然后在 java 代码中像下面这样执行批处理插入:
// 注意这里 executortype.batch
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
try {
namemapper mapper = sqlsession.getmapper(namemapper.class);
for (string name : names) {
mapper.insertname(name);
}
sqlsession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally {
sqlsession.close();
}
32、MyBatis 实现一对一有几种方式?具体怎么操作的
有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在 resultMap 里面配置 association 节点配置一对一的类就可以完成;
嵌套查询是先查一个表,根据这个表里面的结果的 外键 id,去再另外一个表里面查询数据,也是通过association 配置,但另外一个表的查询通过 select 属性配置。
33、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么
Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。
它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。
34、Mybatis 的一级、二级缓存
1、一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或close之后,该Session 中的所有 Cache 就将清空,默认打开一级缓存。
2、二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置 。
3、对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。