java基础+javaweb

文章目录

基础语法 9

Q1:简单说说Java有哪些数据类型

答:①分为基本数据类型和引用数据类型。②基本数据类型包括:数值型(byte、short、int、long、float、double),字符型(char)以及布尔型(boolean)。除了基本类型外,其他数据类型都属于引用类型,包括类、接口、数组等。

Q2:float number=3.4;有没有问题?为什么?

答:有问题,因为3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于向下转型,可能会造成精度损失,所以必须进行强制类型转换,正确的写法是float number =(float)3.4;/ float number =3.4F;。

Q3:字符串拼接的方式以及效率?

答:①使用+直接拼接,String 是final对象,不会被修改,每次使用 +进行拼接都会创建新的对象,而不是改变原来的对象,效率低,是线程安全的。②使用StringBuffer可变字符串,效率较高,是线程安全的(StringBuffer的方法使用了synchronized关键字进行修饰)。③使用StringBuilder可变字符串,效率最高,但是线程不安全。

Q4:简述final,finally和finalize区别

答:①final可以修饰类,方法和变量,被final修饰的类不可继承,被final修饰的方法不可重写,被final修饰的变量引用不可更改,引用的内容可以更改。②finally用于try-catch代码块中,无论是否发生异常最后都将执行,作用是释放资源。③finalize是Object类的方法,在对象被垃圾回收之前将调用一次,一般用于资源的释放。

Q5:==和equals有什么区别?equals和hashCode有什么联系?

答:①如果是引用类型,==比较的是两个对象的引用是否完全相同,如果是基本类型,比较的是两个基本类型的数值是否相同。②如果没有重写的话,equals默认按照==进行比较,如果重写了equals()方法,则按照对应的比较规则比较。③两个对象如果相等,那么它们的hashCode值必须相等,但两个对象的hashCode值相等时,它们不一定相同。

重写equals 

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);


@Override
    public int hashCode() {
        return Objects.hash(age, name);
    }

Q6:Array和ArrayList的区别?

答:①Array长度在定义之后就不运行改变了,而ArrayList是长度可变的,可以自动扩容。②Array只能存储相同类型的数据,ArrayList可以存储不同类型的数据。③ArrayList提供了更多操作数据的方法。

Q7:&和&&的区别?

答:①&具有按位与和逻辑与两个功能。②&&作为逻辑与具有短路的特点,当前面的条件表达式为false时就不会进行后面条件表达式的判断,可以用来避免空指针异常。

Q8:简述JDK8的新特性

答:①接口中可以添加default修饰的非抽象方法,可以有方法体和内容。②可以使用lambda表达式,减少代码冗余。③函数式接口,使用@FunctionalInterface注解标明,该接口有且仅有一个抽象方法。④方法引用,可以直接引用已有Java类或对象的方法或构造器,进一步简化lambda表达式。⑤stream流,用于解决已有集合/数组类库的弊端,简化其操作,有foreach遍历、filter过滤、map映射、concat合并等功能。⑥增加日期相关的API。

Q9:Stream流了解吗?

答:①Stream流是JDK1.8的新特性,用于解决已有集合/数组类库的弊端,简化集合/数组的操作。②stream流的获取:集合:直接调用stream()方法获取;数组:使用静态方法Stream.of()/Arrays.stream()获取。③常用方法:forEach() 遍历;count() 统计个数;filter() 按条件过滤;limit() 取前面n个元素;skip() 跳过前面n个元素;map() 映射加工;concat() 合并stream流。④终结方法:foreach/count 调用终结方法后流不能继续使用;非终结方法:每次调用完返回一个新的stream对象,可以继续使用,支持链式编程。⑤收集stream流:把流转为Set集合 collect(Collections.toSet());把流转为List集合 collect(Collections.toList());把流转为Collection集合 collect(Collections.toCollection());把流转为数组 toArray()。

list.foreach(sou::print)

Q10:基本类型和包装类型的选择

POJO 类似的,还有数据传输对象 DTO(Data Transfer Object,泛指用于展示层与服务层之间的数据传输对象)、视图对象 VO(View Object,把某个页面的数据封装起来)、持久化对象 PO(Persistant Object,可以看成是与数据库中的表映射的 Java 对象)。

那为什么 POJO 的属性必须要用包装类型呢?

《阿里巴巴 Java 开发手册》上有详细的说明,我们来大声朗读一下(预备,起)。

数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值),就会抛出 NullPointerException 的异常。

Q11:多用组合 少用继承

1、组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合。

2、作用是可以将两个本来不相关的类联系起来。一般是两个类之间有显著的不同,很多时候还要附属关系(有相同的属性也有不同的属性)。比如人和头,手机和电池等等

3、无纵向关系时用组合,有纵向关系时用继承

4、组合就是一个类中使用到另一个类,从而把几个类拼到一起。组合的功能也是为了减少重复代码。

Q12:java:String使用equals和==比较的区别

String类型比较不同对象内容是否相同,应该用equals,因为==用于比较引用类型和比较基本数据类型时具有不同的功能。

分析如下:

String作为一个对象来使用

例子一:对象不同,内容相同,"=="返回false,equals返回true

String s1 = new String("java");
String s2 = new String("java");

System.out.println(s1==s2);            //false
System.out.println(s1.equals(s2));    //true

例子二:同一对象,"=="和equals结果相同

String s1 = new String("java");
String s2 = s1;

System.out.println(s1==s2);            //true
System.out.println(s1.equals(s2));    //true

String作为一个基本类型来使用

如果值不相同,对象就不相同,所以"==" 和equals结果一样

String s1 = "java";
String s2 = "java";

System.out.println(s1==s2);            //true
System.out.println(s1.equals(s2));    //true

如果String缓冲池内不存在与其指定值相同的String对象,那么此时虚拟机将为此创建新的String对象,并存放在String缓冲池内。

如果String缓冲池内存在与其指定值相同的String对象,那么此时虚拟机将不为此创建新的String对象,而直接返回已存在的String对象的引用。

面向对象 10

Q1:简述面向对象的特性

答:①封装:建议成员变量私有,然后提供公有的getter/setter方法来获取值/赋值,封装的核心思想是合理隐藏,合理暴露,可以提高安全性,实现代码的组件化。不能篡改我们的属性②继承:一种子类到父类的关系,是“is a”关系,可以提高代码的复用性,相同代码可写到父类,子类的功能更加强大,不仅得到了父类的功能,还有自己的功能。因为是单继承是高耦合,所以一般多用组合,少用继承,只能继承父类的非private属性和方法 ③多态:父类引用指向子类对象,父类或者接口作为引用,在调用父类的具体方法的时候,那个子类实现的我们并不知道,我们在编码时进行指定那个子类,这样就让引用变量绑定到不同的类的实现上,继承,重写,向上转型

Q2:类和对象有什么区别?

答:类是一个抽象的概念,是具有相同特征的事物的描述,是对象的模板。对象是一个个具体的存在,是类的实例。

Q3:列举Object类的方法

答:①equals(Object obj):判断其他对象是否与当前对象相等。②toString():打印当前对象的字符串表示。③wait():导致当前线程等待,等待其他线程唤醒,会释放锁。④notify()/notifyAll():随机唤醒一个/全部线程。⑤hashCode():返回当前对象的hashCode值。⑥finalize():当垃圾回收器要回收对象前调用。⑦clone():创建并返回对象的一个副本。

Q4:方法重载和方法重写的区别?

答:①方法重载是同一个类中具有不同参数列表的同名方法(无关返回值类型),方法重写是子类中具有和父类相同参数列表的同名方法,会覆盖父类原有的方法。②重载的返回值类型和权限修饰符,异常抛出类型没有要求,重写方法的返回值类型小于等于父类被重写方法的返回值类型,修饰符权限大于等于父类被重写方法权限修饰符,抛出的异常类型小于等于父类被重写方法抛出的异常类型。

重写
    父
private void test(int a){
}void test(int a){
}


同一个类
  void test(int a){
}
int test (int a,int b){
}


Q5:接口和抽象类有什么区别?

答:①接口中只能定义public staic final修饰的常量,抽象类中可以定义普通变量。②接口和抽象类都不能实例化,但接口没有构造器,抽象类有构造器。③接口可以多实现,抽象类只能单继承。④接口在JDK1.8之前只能定义public abstract修饰的方法,JDK1.8开始可以定义默认方法和静态方法,JDK1.9开始可以定义私有方法,抽象类中的方法没有限制。

Q6:什么时候应该使用接口,什么时候应该使用抽象类?

使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。
抽象类适合用来定义某个领域的固有属性,也就是本质,接口适合用来定义某个领域的扩展功能。

一、什么时候使用抽象类?

当2个或多个类中有重复部分的时候,我们可以抽象出来一个基类,如果希望这个基类不能被实例化,就可以把这个基类设计成抽象类。
当需要为一些类提供公共的实现代码时,应优先考虑抽象类 。因为抽象类中的非抽象方法可以被子类继承下来,使实现功能的代码更简单。
抽象类只能是单继承的,不能多继承。
二、什么时候使用接口?

当注重代码的扩展性跟可维护性时,应当优先采用接口。
①接口与实现它的类之间可以不存在任何层次关系,接口可以实现毫不相关类的相同行为,比抽象类的使用更加方便灵活;
②接口只关心对象之间的交互的方法,而不关心对象所对应的具体类。接口是程序之间的一个协议,比抽象类的使用更安全、清晰。一般使用接口的情况更多。

Q7:内部类有什么作用?有哪些分类?

答:一、什么是内部类
定义: 将一个类定义在一个类或者一个方法里面,这样的类称着内部类

二、内部类的种类
内部类的种类有4种:

1、成员内部类
成员内部类是最普通的一种内部类,成员内部类可以访问外部类所有的属性和方法。但是外部类要访问成员内部类的属性和方法,必须要先实例化成员内部类。
注意: 成员内部类里面不能包含静态的属性和方法

public class OutClass {
    public void test1() {
    }
    private void test2() {
    }
    private static void test3() {
    }
    class InnerClass {//成员内部类
        private String testStrInner = "";
        private void testInner() {
            test1();
            test2();
            test3();//成员内部类可以访问外部类所有的属性和方法。静态方法直接访问。
        }
    }
}

2、静态内部类
静态内部类就是在成员内部类多加了一个 static 关键字。静态内部类只能访问外部类的静态成员变量和方法(包括私有静态)

public class OutClass {
    private static String s = "";
    public void test1() {
    }
    private void test2() {
    }
    private static void test3() {
    }
    static class InnerClass {//静态内部类
        private static String testStrInner = "";
        private static void testInner() {
            test3();
            String ss = s;
        }
    }
}

3、匿名内部类
匿名内部类:顾名思义就是没有名字的类。什么时候用到匿名内部类呢?在Android中最常见得回调监听事件 就是匿名内部类
一般遇到下面这种情况都会考虑到使用匿名内部类:
当一个内部类需要继承或者实现,而且只使用一次的时候,可以考虑使用匿名内部类。调用的时候直接使用父类的无参构造,并重写父类方法。如下代码:

//父类  Animal 
public class Animal {
    public void bellow() {//动物吼叫的类型
        System.out.println("动物吼叫");
    }
}

如果现在只是需要一个 狗(Dog)的吼叫类型。一般我们会写一个Dog类继承Animal ;然后重写
bellow()方法;最后实例化Dog类,调用bellow()方法。但是此时我们可以使用内部类,因为只用一次,没有其他地方调用,没必要再去写一个class类。代码如下

class Demo {
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.getDogBellow(new Animal(){//匿名内部类,重写父类方法。当然接口也是一样
            @Override
            public void bellow() {
                System.out.println("狗 汪汪汪。。。。");
            }
        });
    }
    public void getDogBellow(Animal animal){
        animal.bellow();
    }
}

4、局部内部类
局部内部类就是定义在代码块内的一个内部类。比如在方法里面定义一个内部类,就是局部内部类。
局部内部类的作用范围仅仅就在它所在的代码块里。局部内部类不能被public ,protected,private以及static修饰,但是可以被final修饰。

public class Animal {
    public static void bellow() {
        String bellowStr = "动物吼叫";
        System.out.println(bellowStr);
            final class Dog {//局部内部类
        String dogBellowStr = bellowStr + ";狗 :汪汪汪";

        public void dogBellow() {
            System.out.println(dogBellowStr);
        }
    }
}

三、内部类的作用
1、内部类可以很好的实现隐藏。
非内部类是不可以使用 private和 protected修饰的,但是内部类却可以,从而达到隐藏的作用。同时也可以将一定逻辑关系的类组织在一起,增强可读性。
2、间接的实现多继承。
每个内部类都能独立地继承自一个(接口的)实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。所以说内部类间接的实现了多继承。

首先需要知道的一点是: 内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着 方法的执行完毕就被销毁。 这里就会产生问题:当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有 没有人再引用它时,才会死亡)。这里就出现了一个矛盾:内部类对象访问了一个不存在的变量。为了解 决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍可以 访问它,实际访问的是局部变量的"copy"。这样就好像延长了局部变量的生命周期 将局部变量复制为内部类的成员变量时,必须保证这两个变量是一样的,也就是如果我们在内部类中修 改了成员变量,方法中的局部变量也得跟着改变,怎么解决问题呢? 就将局部变量设置为final,对它初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量 和方法的局部变量的一致性。这实际上也是一种妥协。使得局部变量与内部类内建立的拷贝保持一致。

Q8:泛型和泛型擦除是什么?

答:①泛型的本质是参数化类型,泛型提供了编译时类型的安全检测机制,该机制允许程序在编译时检测非法的类型。②==在编译阶段采用泛型时加上的类型参数,会被编译器在编译时去掉,==这个过程就被称为类型擦除,因此泛型主要用于编译阶段,在编译后生成的Java字节代码文件中不包含泛型中的类型信息。

Q9:泛型标记的规范了解吗?

答:①E:值Element,在集合中使用,表示在集合中存放的元素。②T:指Type,表示Java类,包括基本的类以及自定义类。③K:指Key,表示键,例如Map集合中的Key。④V:指Value,表示值,例如Map集合中的Value。⑤N:指Number,表示数值类型。⑥?:表示不确定的Java类型。

Q10:泛型限定是什么?

答:①类型通配符使用?表示所有具体的参数类型,在使用泛型的时候,如果希望将类的继承关系加入泛型应用中就需要对泛型做限定,具体的泛型限定有对泛型上限的限定以及对泛型下限的限定。②对泛型上限的限定使用<? extends T>,它表示该通配符所代表的类型是T类的子类型或T接口的子接口。③对泛型下限的限定使用<? super T>,它表示该通配符所代表的类型是T类的父类型或T接口的父接口。

异常 2

Q1:异常有哪些分类?出现的原因是什么?

答:①Throwable是所有错误和异常的父类,Throwable分为Error和Exception。②Error指Java程序运行错误机器错误,出现Error通常是因为系统的内部错误或资源耗尽,Error不能在运行过程中被动态处理,如果程序运行中出现Error,系统只能记录错误的原因和安全终止。③Exception指Java程序运行异常,即运行中发生了不期望的情况,分为RuntimeException和CheckedException。RuntimeException指在Java虚拟机正常运行期间抛出的异常,可以被捕获并处理,例如空指针异常,数组越界等。CheckedException指编译阶段强制要求捕获并处理的异常,例如IO异常,SQL异常等。

Q2:有哪些异常处理方式?

答:①抛出异常:遇到异常不进行具体处理,而是将异常抛出给调用者,由调用者根据情况处理。抛出异常有2种形式,一种是throws,作用在方法上,一种是throw,作用在方法内。②使用try/catch进行异常的捕获处理,try中发生的异常会被catch代码块捕获,根据情况进行处理,如果有finally代码块无论是否发生异常都会执行,一般用于释放资源,JDK1.7开始可以将资源定义在try代码块中自动释放减少代码。

集合 10

Q1:简述一下集合主要有哪些类和接口,各自有什么特点

答:①主要有两个接口Collection和Map,其中Collection又包括List、Set和Queue。②List是不唯一有序的,主要包括ArrayList,LinkedList和Vector,ArrayList底层通过数组实现,线程不安全,Vector是线程安全的ArrayList,但效率较低,LinkedList底层通过双向链表实现,与ArrayList相比增删快查询慢。③Set是唯一且无序的,主要包括HashSet,LinkedHashSet和TreeSet。HashSet底层其实就是HashMap,利用了key来保证元素的唯一性。LinkedHashSet可以按照key的操作顺序排序,TreeSet支持按照默认或指定的排序规则排序。④Queue是队列结构,主要有ArrayBlockingQueue基于数组的阻塞队列、LinkedBlockingQueue基于链表的阻塞队列等。⑤Map以key-value键值对的形式存储元素,主要包括HashMap、LinkedHashMap和TreeMap。HashMap底层通过数组+链表/红黑树实现,LinkedHashMap可以按照key的操作顺序对集合排序,TreeMap可以按照默认或指定的排序规则对集合排序。

Q2:HashMap是线程安全的吗?

答:①HashMap是线程不安全的,可以使用ConcurrentHashMap保证线程安全。通过分段锁实现线程安全②ConcurrentHashMap基于减小锁粒度的思想,通过使用分段锁来实现线程安全,内部细分为很多Segment数据段,默认情况下为16个,对每个Segment的数据都单独进行加锁操作,Segment的个数为锁的并发度。ConcurrentHashMap是由Segment数组和HashEntry数组组成的,Segment继承了可重入锁,HashEntry用来存储键值对数据。③Segment的结构和HashMap类似,是数组和链表结构,每个Segment里面都包含一个HashEntry数组,每个HashEntry都是一个链表结构的数据要对其进行i修改必须先获得对应的Segment锁。④多线程下只要加入的数据hashCode映射的数据段不一样就可以做到并行的线程安全。

Q3:List、Set、Map有什么区别?

答:①List是有序、可重复、有索引的集合,继承了Collection集合全部功能 除了Collection的三种遍历方式外,可用索引遍历。==②Set是无序,不可重复的集合,==Set的实现类LinkedHashSet和TreeSet是有序的,LinkedHashSet可以按照元素插入的顺序排序,也可以按照元素操作的时间排序,TreeSet可以按照默认的比较规则或者自定义的比较规则排序。==③Map是无序、以key-value的键值对形式存储元素的集合,键不可重复,值无要求,==重复的键对应的值会覆盖之前的值。

Q4:HashSet是如何去重的?

答:①对于基本类型的包装类,可以直接按值进行比较②对于引用数据类型,会先比较hashCode()返回值是否相同,如果不同则代表不是同一个对象,如果相同则继续比较equals()方法返回值是否相同,都相同说明是同一个对象。③如果希望内容相同的对象就代表对象相同,那么除了重写equals()方法还要重写hashCode()方法,因为内容相同的对象hashCode()值不一定相同,因为只有hashCode()和equals()都相同才说明是同一个对象。

Q5:HashMap和HashSet的底层是怎么实现的?

答:①==JDK1.8之前,HashMap的底层是数组加链表实现。==数组中的每个元素都是一个单链表,链表中的每个元素都是Entry的实现类Node的一个实例,Node包括4个属性:key、value、hash值和用于指向单链表下一个元素的next。②HashMap在查找数据时,根据hash值可以快速定位到数组的具体下标,然后对链表进行遍历查找数据的时间复杂度为O(n)。JDK1.8起对HashMap进行了优化,底层改为数组+链表或红黑树,当链表中的元素超过8个之后,HashMap会将链表结构转换未红黑树以提高查询效率,时间复杂度为O(logn)。②HashSet的底层是基于HashMap实现的,HashSet中的元素只是存放在了底层HashMap的key上, 而value使用一个static final的Object对象标识。因此HashSet 的实现比较简单,相关操作基本上都是直接调用底层HashMap的相关方法来完成的。

Q6:Collection和Collections有什么区别?

答:①Collection是一个集合接口,它包括List有序集合、Set无序集合、Queue队列等。②Collections则是Collection的一个工具类,为Collection类型的对象提供了很多方便的方法,例如addAll可以直接对Collection集合批量添加元素,shuffle可以随机打乱List集合的元素顺序,sort可以对List集合进行默认或按比较器进行排序。

Q7:迭代器是什么?

答:①迭代器实现了Iterator接口,是用于遍历Collection集合元素的一个指针。②主要有三个方法:通过==iterator()获得集合的迭代器;通过hasNext()判断集合当中是否还有元素,如果有返回true,没有则返回false,初始时迭代器位于第一个元素之前;通过next()获取集合的下一个元素,==并向后移动一个元素的单位。

Q8:在使用foreach循环遍历集合元素时能否添加或删除元素?

答:==使用foreach循环遍历元素集合时不能修改或删除元素,==通过java -c查看字节码可以发现foreach循环实际上是用Iterator迭代器实现的,==如果进行添加或删除元素会抛出ConcurrentModificationException异常,因为添加或删除元素会改变modCount的值,==modCount是集合类的一个成员变量,代表集合的修改次数,当modCount的值和预期的exceptedModCount值不一致时就会抛出ConcurrentModificationException异常。

Q9:Queue接口中的add()/offer()、remove()/poll()、element()/peek()方法有什么区别?

答:①add()和offer()都是向队列尾部插入一个元素,区别是当超出队列界限时,add方法会抛出异常,而offer()会返回false。②remove()和poll()都是从队列头部移除一个元素并返回,区别是队列为空时remove()方法会抛出异常,poll()方法则是返回null值。③element()和 peek() 都是用于查询队列头部的元素,区别时队列为空时, element() 抛出一个异常,而 peek() 返回 null。

Q10:有哪些线程安全的集合类?

答:①Vector,是线程安全的ArrayList,底层用数组实现,通过synchronized修饰方法保证线程安全。②HashTable,是线程安全的HashMap,继承自Dictionary,通过synchronized修饰方法保证线程安全,性能较差。③ConcurentHashMap,线程安全的HashMap,通过分段锁实现线程安全,性能较好。
image-20220617143012559

反射与注解 3

Q1:简述反射的基本概念,优缺点和使用场景。

答:①==在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java的反射机制。② 优点是运行时动态获取类的全部信息,缺点是破坏了类的封装性,泛型的约束性。==③是框架的核心灵魂,动态代理设计模式采用了反射机制,还有 Spring、Hibernate 等框架也大量使用到了反射机制。

Q2:获取Class对象有哪几种方式?能通过Class对象获取类的哪些信息?

答:==①通过类名.class②通过对象.getClass()③通过Class.forName(类的全限名);④可以通过Class对象获取类的成员变量,方法或构造器。==带declared的获取方法可以获取到类的一个或全部成员变量,方法,构造器,不带declared的方法只能获取到类的public修饰的成员变量、方法或构造器,包括父类public修饰的成员变量、方法或构造器。

Q3:注解是什么,元注解是什么,有什么作用?

答:①注解是一种标记,可以使类或接口附加额外的信息,是帮助编译器和JVM完成一些特定功能的。==②元注解就是自定义注解的注解,==包括@Target:用来约束注解的位置,值是ElementType枚举类,包括METHOD方法、VARIABLE变量、TYPE类/接口、PARAMETER方法参数、CONSTRUCTORS构造器和LOACL_VARIABLE局部变量;@Rentention:==用来约束注解的生命周期,==值是RetentionPolicy枚举类,包括:SOURCE源码、CLASS字节码和RUNTIME运行时;@Documented:表明这个注解应该被javadoc工具记录;@Inherited:表面某个被标注的类型是被继承的。

image-20220617144018205

IO流 5

Q1:简单说说File对象表示的是什么?File类有哪些常用方法?

答:①File对象表示的是操作系统上的文件或目录。②获取:getAbsolutePath() 获取绝对路径;getPath() 获取文件定义时使用的路径;getName() 获取文件名,带后缀;length() 返回文件长度,单位是字节。③判断:exists() 判断File对象表示的文件或目录是否存在;isDirectory() 判断是否是目录; isFile() 判断是否是文件。④创建和删除:createNewFile() 不存在时创建新文件;delete() 删除文件,目录(非空目录不能删除);mkdir() 创建一级目录;mkdirs() 创建多级目录,推荐使用;⑤遍历:list 获取当前目录下所有一级文件名称到一个字符串数组并返回;listFiles 获取当前目录下所有一级File对象到File数组返回。

Q2:英文、数字和中文字符在文件中分别占多大的空间?

答:①英文和数字在任何编码中都占1个字节。②中文字符在GBK编码下占2个字节,在UTF-8编码下占3个字节。

Q3:简述传统IO有哪些分类?以内存为中心

答:①按流的方向:输出流:把内存中的数据写出到磁盘文件或网络介质中;输入流:把磁盘文件或网络介质中的数据读取到内存中。②按流的内容:字节流:流中数据的最小单位是字节;字符流:流中数据的最小单位是字符(针对文本内容)。顶层的抽象类包括InputStream、OutputStream、Reader、Writer,它们都实现了Closeable接口。③缓冲流(BufferedInputStream/BufferedOutputStream/BufferedReader/BufferedWriter):自带一个8KB大小的缓冲池,可以将字节/字符流为缓冲字节/缓冲字符流。④字符转换流(InputStreamReader/OutputStreamWriter):可以将对应的字节流转换为字符流。⑤打印流:PrintStream,方便快速打印数据,参数是什么就打印什么。

Q4:简述BIO、NIO、AIO的区别和原理

答:①BIO是同步阻塞的,数据的读写会阻塞在一个线程中,适用于连接数目比较小且固定的架构,对服务器资源要求高,JDK1.4前的唯一选择。②NIO是同步非阻塞的,通过Selector监听Channel上事件的变化,在Channel上有数据发生变化时通知该线程进行读写操作。适用于连接数目比较多且连接比较短的架构,如聊天服务器,从 JDK1.4开始支持。③AIO是异步非阻塞的,异步是指服务端线程接收到客户端管道后就交给底层处理IO通信,自己可以做其他事情。适用于连接数目比较多且连接比较长的架构,从JDK1.7开始支持。

Q5:序列化和反序列化是什么,有什么要求?

答:①Java在JVM运行时被创建、更新和消耗,当JVM退出时,对象也会随之销毁。可以通过Java序列化实现持久化存储,保存对象及其状态信息到字节数组中。②反序列化就是再将字节数组中存储的信息转换回Java对象。③要求类必须实现序列化接口,并且序列化和反序列化必须保持序列化的ID一致。④静态变量和被transient修饰的变量不会被序列化。

JavaWeb 19

Q1:HTTP有哪些特点

答:①HTTP是基于TCP/IP协议的。②HTTP使用的默认端口号是80。③HTTP是基于请求/响应模型的,一次请求对应一次响应。④HTTP是无状态的,每次请求之间相互独立,不能交互数据。⑤HTTP1.0每一次请求响应都会建立新的连接,HTTP1.1会复用连接

Q2:HTTP请求数据的数据格式是什么?

答:①请求行,包括了请求方式、请求url、请求协议/版本。HTTP协议有7种请求方式,常用的有2种。GET方式,请求参数在请求行中,在url后、 请求的url长度有限制的、写在地址栏上不太安全;POST方式,请求参数在请求体中、请求的url长度没有限制的、相对安全。②请求头,是客户端浏览器告诉服务器的一些信息,常见的请求头例如User-Agent,告诉服务器使用的浏览器版本信息,可以在服务器端获取该头的信息,解决浏览器的兼容性问题。Referer,可以告诉服务器,当前请求从哪里来,可以防盗链或者进行统计数据。③请求空行,用于分割POST请求的请求头和请求体的。④请求体(正文),封装POST请求消息的请求参数的。

Q3:转发和重定向的区别?

答:①转发的特点: 转发地址栏路径不变、 转发只能访问当前服务器下的资源、转发是在同一次请求中,可以使用request对象来共享数据。②重定向的特点:地址栏发生变化、重定向可以访问其他站点(服务器)的资源、重定向是两次请求,不能使用request对象来共享数据。

Q4:讲一讲Cookie

答:①Cookie是客户端会话技术,将数据保存到客户端。②创建Cookie对象,绑定数据:new Cookie(String name, String value);发送Cookie对象:response.addCookie(Cookie cookie),一次可以发送多个Cookie;获取Cookie,拿到数据:request.getCookies()。③浏览器对于单个cookie 的大小有限制(4kb) 以及对同一个域名下的总cookie数量也有限制(20个),cookie一般用于存出少量的不太敏感的数据,在不登录的情况下,完成服务器对客户端的身份识别。

Q5:Cookie的生命周期?

答:①默认情况下,当浏览器关闭后,Cookie数据被销毁。②如果想要持久化存储,可以使用setMaxAge(int seconds)。正数:将Cookie数据写到硬盘的文件中,持久化存储,并指定cookie存活时间,时间到后,cookie文件自动失效。负数:默认值。零:删除cookie信息。

Q6:Cookie可以存储中文数据吗?

答:①在tomcat 8 之前cookie中不能直接存储中文数据,需要将中文数据转码—一般采用URL编码(%E3)。②在tomcat 8 之后,cookie支持中文数据,特殊字符还是不支持,建议使用URL编码存储,URL解码解析。

Q7:Cookie的共享范围是什么?

答:①假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie默认情况下不能共享。通过setPath(String path)设置cookie的获取范围,默认情况下,设置为当前的虚拟目录,如果要共享,则可以将path设置为/。②不同的tomcat服务器间cookie共享问题:通过setDomain(String path)设置一级域名,如果一级域名相同,那么多个服务器之间cookie可以共享。例如setDomain(“.baidu.com”),那么tieba.baidu.com和news.baidu.com中cookie可以共享。

Q8:讲一讲Session

答:①Session是服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。②获取HttpSession对象:request.getSession();使用HttpSession对象:Object getAttribute(String name)、void setAttribute(String name, Object value)、void removeAttribute(String name)。③Session的实现是依赖于Cookie的,服务器是通过cookie中的JESSIONID判断session是否是同一个的。

Q9:Session的生命周期?当客户端关闭后,服务器不关闭,两次获取session是否为同一个?客户端不关闭,服务器关闭后,两次获取的session是同一个吗?

答:①服务器关闭、session对象调用invalidate() 时销毁,session默认失效时间 30分钟。==②在默认情况下,当客户端关闭服务端不关闭时,两次获取session值不是同一个。③如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。==④客户端不关闭,服务端关闭,两次获取的session值也不是同一个。但是要确保数据不丢失。tomcat自动完成以下工作。session的钝化: 在服务器正常关闭之前,将session对象序列化到硬盘上。session的活化: 在服务器启动后,将session文件转化为内存中的session对象即可。但是IDEA不支持这种操作,因为每次用IDEA重启tomcat时会自动删除catalina_base中work目录(程序动态生成的文件),这样在关闭tomcat时生成的session序列化文件也会被删除。

Q10:Session的特点,和Cookie有什么区别?

答:①Session用于存储一次会话的多次请求的数据,存在服务器端。session可以存储任意类型,任意大小的数据。②Session存储数据在服务器端,Cookie存储数据在客户端。
Session没有存储数据的大小限制,Cookie有数据大小限制。Session存储数据是安全的,使用Cookie存储数据相对于使用Session来说不安全。

Q11:EL是什么?

答:①EL指Expression Language 表达式语言。②EL表达式的作用是替换和简化jsp页面中java代码的编写。③EL表达式的语法是:${表达式}。④JSP默认支持EL表达式,如果要忽略EL表达式,设置JSP中page指令中的isELIgnored="true"忽略当前jsp页面中所有的el表达式,也可以通过${表达式} 忽略当前这个EL表达式。

{request.user}

Q12:JSTL是什么?

答:①JSTL指JavaServer Pages Tag Library JSP标准标签库,是由Apache组织提供的开源的免费的JSP标签。②JSTL的作用是简化和替换jsp页面上的Java代码。③使用时首先需要导入JSTL相关jar包,并引入标签库: <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>。

<c:forecah item={request.userlist} var=user>

Q13:JSP定义Java代码有哪些方式?

答:①<% 代码 %>是JSP页面中Java代码片段的容器,将页面转换为servlet类时,会将内容插入到servlet类的jspService()方法中,同时从JSP生成servlet。②<%! 代码 %>用于为JSP页面声明全局的方法和变量。在JSP文件中,必须先声明这些变量和方法然后才能使用它们。在页面转换中,声明的方法和变量成为JSP页面的servlet类中的类成员声明。语法③<%= 代码 %>用于将转换为String的Java表达式的值插入到返回给客户端的响应中。

Q14:JSP的内置对象有哪些?

答:①pageContext,真实类型是PageContext,可以在当前页面共享数据,还可以获取其他八个内置对象。②page,真实类型是Object,指当前页面(Servlet)的对象this。③request,真实类型是HttpServletRequest,封装客户端的请求。④response,真实类型是HttpServletResponse,封装服务端对客户端的响应。⑤session,真实类型是HttpSession,封装会话数据信息。⑥out,真实类型是JspWriter,字符输出流对象,可以将数据输出到页面上,和response.getWriter()类似。response.getWriter()和out的区别:在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。response.getWriter().write()数据输出永远在out.write()之前。⑦config,真实类型是ServletConfig,是Servlet的配置对象。⑧exception,真实类型是Throwable,封装页面抛出异常的对象。⑨application,真实类型是ServletContext,封装服务器运行环境的对象。

Q15:过滤器是什么?如何使用?

答:①当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。②需要实现Filter接口,使用注解方式可以在类名上加上注解@WebFilter(“拦截路径”),使用XML的方式可以配置web.xml中的filter和filter-mapping标签,设置过滤器类和拦截路径。

Q16:过滤器的执行流程和生命周期是什么?

答:①执行流程:执行过滤器,执行放行后的资源,回来执行过滤器放行代码下边的代码。②生命周期:init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次,一般用于加载资源doFilter:在每一次请求被拦截资源时执行,会执行多次。destroy:在服务器关闭后,Filter对象被销毁,如果服务器是正常关闭,则会执行destroy方法。只执行一次。一般用于释放资源

Q17:过滤器拦截路径都有哪些方式?

答:①具体资源路径:,例如/index.jsp ,只有访问index.jsp资源时,过滤器才会被执行。②拦截目录:例如/user/,当访问/user下的所有资源时,过滤器都会被执行。③通过后缀名拦截:例如.jsp, 当访问所有后缀名为jsp资源时,过滤器都会被执行。④拦截所有资源:使用/*,访问所有资源时过滤器都会执行。

Q18:AJAX是什么?

答:==①Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。==②通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。③传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面,使用Ajax技术可以提升用户的体验。 比如:在登陆是要求用户名不能相同,则可以发送一个ajax请求,动态查询用户名是否重复了

Q19:JSON是什么?如何把Java对象转为JSON?如何把JSON转回Java对象?

答:①JSON指JavaScript Object Notation JavaScript对象表示法。②JSON现在多用于存储和交换文本信息的语法,进行数据的传输。③JSON的优势是想比XML来说占用空间更小、操作数据更快,更易解析。==④将Java对象转为JSON时,需要先导入jackson的相关jar包,==创建Jackson核心对象 ObjectMapper,之后调用ObjectMapper的writeValue(参数,obj)进行转换,如果参数是File类型,可以将obj对象转换为JSON字符串,并保存到指定的文件中;如果参数是Writer类型,可以将obj对象转换为JSON字符串,并将json数据填充到字符输出流中;如果参数是OutputStream类型,可以将obj对象转换为JSON字符串,并将JSON数据填充到字节输出流中。⑤将JSON转会Java对象时使用readValue的方法,参数为要转回的Java对象的Class字节码对象。

12.什么是 jsp,什么是 Servlet? jsp 和 Servlet 有什么区别?

jsp 本质上就是一个 Servlet,它是 Servlet 的一种特殊形式(由 SUN 公司推出),每个 jsp 页面都是一个 servlet
实例。
Servlet 是由 Java 提供用于开发 web 服务器应用程序的一个组件,运行在服务端,由 servlet 容器管理,用来生
成动态内容。一个 servlet 实例是实现了特殊接口 Servlet 的 Java 类,所有自定义的 servlet 均必须实现 Servlet 接口。

区别:
jsp 是 html 页面中内嵌的 Java 代码,侧重页面显示;
Servlet 是 html 代码和 Java 代码分离,侧重逻辑控制, mvc 设计思想中 jsp 位于视图层, servlet 位于控制层
Jsp 运行机制:如下图

img

JVM 只能识别 Java 类,并不能识别 jsp 代码! web 容器收到以.jsp 为扩展名的 url 请求时,会将访问请求交给
tomcat 中 jsp 引擎处理,每个 jsp 页面第一次被访问时, jsp 引擎将 jsp 代码解释为一个 servlet 源程序,接着编译servlet 源程序生成.class 文件,再有 web 容器 servlet 引擎去装载执行 servlet 程序,实现页面交互。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值