基础知识三
请描述转发和重定向的区别
①:请求转发是在服务器内部进行跳转,重定向是在浏览器进行跳转
②:请求转发浏览器地址栏不变 ,重定向地址栏改变
③:请求转发可以携带共享数据 ,重定向不能携带共享数据
④:请求转发路径为 /资源路径 ,重定向路径为: /项目名/资源路径
区别:
1. 使用对象:
重定向:response
请求转发:request
2. 路径写法:
重定向:客户端路径
请求转发:服务器端路径
3. 能否外网跳转:
重定向:带http协议的绝对路径
请求转发:不可以,访问本地
4. 响应次数:
重定向:重定向N次,响应N+1次
请求转发:请求转发N次,响应1次
5. 地址改变与否:
重定向:改变,路径是最后重定向的路径
请求转发:不改变。
6. 安全特性:
程序路径暴露问题:某些程序,关键程序,不希望外界知道程序访问路径
重定向:会暴露程序路径,并不安全
请求转发:不会暴露程序路径。
程序的BUG问题-重复刷新:某些程序,不允许两次访问。
重定向:因为改变了地址栏路径,防止了重复刷新
请求转发:路径未改变,可能会导致用户进行重复刷新
后期:是会在服务器端进行字段的非空校验。
7. 网速及效率:
重定向:严重依赖网速,网速慢,跳转效率低
请求转发:不依赖网速,跳转效率极高。
8. request作用域:
重定向:不可以使用
请求转发:可以使用
9. 受保护目录资源访问
重定向:不可以访问受保护目录
请求转发:可以
何时使用请求转发?
① 要求安全,不暴露程序路径
② 要求高效
③ 使用request作用域
④ 访问受保护目录资源
何时使用重定向?
① 跳转外网资源
② 改变地址栏路径
一个web项目下的web-inf下的页面可以直接通过浏览器如何访问吗?应该如何访问
WEB-INFO下是受保护目录,通过浏览器直接访问,访问不到。通过请求转发可以访问到
当一个方法被一个通知代理时,还有一个通知也要代理这个方法,那么这两者选择的代理方式必须相同(Proxy代理 或者 CGLIB代理)
举例,service层的方法被事务通知代理,又被shiro权限通知代理,这时必须选择同样的代理方式.(CGLIB代理比较强大,一般首选这个)
该程序的运行结果
JAVA类
一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
可以有多个类,但只能有一个 public 的类,并且 public 的类名必须与文件名相一致,
外部类不能被private,protected修饰,但是内部类可以,不加修饰符默认就是default,因此一个java源文件中(不是内部类)只能有一个被 public和多个默认符default(不写任何修饰符就是默认)修饰的类 .
哪些关键字可以修饰类
public ,default (理论上还有private,protected,但是实际情况这两个几乎不会出现在类的修饰中,一般都是修饰方法),还有abstract和final可以和前面的结合使用
数组有没有length()方法?String有没有length()方法?
数组是length方法,String有length()方法.
请写出四种修饰符的含义以及作用范围
私有权限(private)
private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。被private修饰的成员,只能在定义它们的类中使用,在其他类中不能调用。
默认权限(default)
类,数据成员,构造方法,方法成员,都能够使用默认权限,即不写任何关键字。默认权限即同包权限,同包权限的元素只能在定义它们的类中,以及同包的类中被调用。
受保护权限(protected)
protected可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。被protected修饰的成员,能在定义它们的类中,同包的类中被调用。
如果有不同包的类想调用它们,那么这个类必须是定义它们的类的子类。
公共权限(public)
public可以修饰类,数据成员,构造方法,方法成员。被public修饰的成员,可以在任何一个类中被调用,不管同包或不同包,是权限最大的一个修饰符。
|
类内部 |
本包 |
子类 |
外部包 |
public |
√ |
√ |
√ |
√ |
protected |
√ |
√ |
√ |
× |
default |
√ |
√ |
× |
× |
private |
√ |
× |
× |
× |
不通过构造函数可以创建对象吗?(可以)
Java创建对象的几种方式(重要):
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法。
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
泛型的定义及优缺点
java 泛型是java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
泛型只有编译时期,才有效, 编译后 ,擦除.
泛型的定义:定义泛型可以在类中预支地使用未知的类型。
泛型用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。
使用泛型的好处
①:将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
②:避免了类型强转的麻烦。
③:提高了程序的安全性
java中String、StringBuffer、StringBuilder的区别
1.可变与不可变
String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。
private final char value[];
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。
char[] value;
2.是否多线程安全
String中的对象是不可变的,也就可以理解为常量,显然线程安全。
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
3.StringBuilder与StringBuffer共同点
StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类)。
抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(...)。只是StringBuffer会在方法上加synchronized关键字,进行同步。
最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
静态变量和实例变量的区别?
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar 变量,并且每创建一个实例对象,这个staticVar就会加1;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。
运行结果:
Final、finally、finalize的区别(详情点击下面地址)
https://jingyan.baidu.com/article/597a064363b676312b5243ad.html
final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。
请描述一下Java中的异常处理机制
当程序中抛出一个异常后,程序从程序中导致异常的代码处跳出,try块出现异常后的代码不会再被执行,java虚拟机检测寻找和try关键字匹配的处理该异常的catch块,如果找到,将控制权交到catch块中的代码,然后继续往下执行程序。
如果有finally关键字,程序中抛出异常后,无论该异常是否被catch,都会保证执行finally块中的代码。在try块和catch块采用return关键字退出本次函数调用,也会先执行finally块代码,然后再退出。即finally块中的代码始终会保证执行。由于finally块的这个特性,finally块被用于执行资源释放等清理工作。
事务的ACID是指什么?
Ø 原子性:强调事务的不可分割.多条语句要么都成功,要么都失败。
Ø 一致性:强调的是事务的执行的前后,数据要保持一致.
Ø 隔离性:一个事务的执行不应该受到其他事务的干扰.
Ø 持久性:事务一旦结束(提交/回滚)数据就持久保持到了数据库.
Statement和PreparedStatement有什么区别?哪个性能更好?
与Statement相比,
①PreparedStatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误并增加SQL的安全性(减少SQL注射攻击的可能性);
②PreparedStatement中的SQL语句是可以带参数的;
③当批量处理SQL时或频繁执行相同的查询时,PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同语句时就会很快。
当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法?
不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入
1.其他方法前是否加了synchronized关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
请说出与线程同步相关的方法。
wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException 异常;
notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争;
多线程实现的有几种方式
Java 5以前实现多线程有两种实现方法:一种是继承Thread类;另一种是实现Runnable接口。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活。
补充:Java 5以后创建线程还有第三种方式:实现Callable接口
sleep()和wait()有什么区别?
Sleep()来自Thread类,wait()来自Object类
使用sleep方法时,当前线程释放执行权,不释放锁,其他线程不可以执行
使用wait方法时,当前线程释放执行权,同时释放锁,其他线程可以执行
sleep()方法是线程类(Thread)的静态方法,导致此线程暂停执行指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复(线程回到就绪(ready)状态),因为调用sleep 不会释放对象锁。wait()是Object 类的方法,对此对象调用wait()方法导致本线程放弃对象锁(线程暂停执行),进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入就绪状态
启动一个线程是用run()还是start()方法?、启动一个线程是start()方法。
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行,这并不意味着线程就会立即运行。run()方法是线程启动后要进行回调(callback)的方法,
1、启动一个线程是start()方法。
2、启动线程之后start()方法会去调用run方法内容。
区别:start是创建并启动一个线程,而run是要运行线程中的代码。
Servelt的生命周期是什么
Servlet在内存中是单例----单实例对象
一个Servlet类在内存中最多有一个对象
Servlet的生命周期:
Servlet创建:Servlet在第一次被访问时。 Servlet创建时,服务器会调用该Servlet的init()方法。
Servlet销毁:Servlet在服务器正常关闭时。 Servlet销毁时,服务器会调用该Servlet的destroy()方法。
Servlet工作:Servlet被调用一次,就会执行一次service()方法,service()根据请求方式,调用doGet()和doPost()方法。