基础知识三

请描述转发和重定向的区别

①:请求转发是在服务器内部进行跳转,重定向是在浏览器进行跳转

②:请求转发浏览器地址栏不变 ,重定向地址栏改变

③:请求转发可以携带共享数据 ,重定向不能携带共享数据

④:请求转发路径为  /资源路径 ,重定向路径为: /项目名/资源路径

区别:

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()方法。


 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值