2019年java面试题以及解答

一、Java 基础

1.JDK 和 JRE 有什么区别?
JDK是java的开发工具包,包含各种类库,并且包含了JRE,javac是在JDK中的;
JREjava程序的运行环境,安装过程中自动添加PATH.
2. == 和 equals 的区别是什么?
一. 对于==,比较的是值是否相等,如果比较的是基本数据类型的变量,则直接比较其存储的值是否相等,
如果比较的是引用数据类型,则比较的是所指向的对象的地址值.
二. equals不能作用于基本数据类型,它比较的是是否是同一个对象
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址值.
如String,Date等类对equals方法进行了重写,比较的则是所指向的对象的内容
3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
首先,两个对象equals相等,hashcode一定相等;但是hashcode相等时,equals不一定相等.
其次,两个不同的对象,因为可能存在哈希碰撞,所以hashcode可能是相等的,但是显然equals不为true.
还有就是,在object类中,euqals方法还是用的==来判断的,==对于对象而言比较的是地址值,所以equals相等
hashcode一定一样,反之就不一定了.
4. final 在 java 中有什么作用?
final关键字可作用于类,类属性和方法;
作用于类上时,该类不能被继承
作用于属性时,该属性不能被重新复制
作用于方法时,该方法不能被重写
5. java 中的 Math.round(-1.5) 等于多少?
Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)=-1
6. String 属于基础的数据类型吗?
不是,String是一个类,是引用数据类型.
7. java 中操作字符串都有哪些类?它们之间有什么区别?
有String,StringBuilder,StringBuffer
1. String是不可变的,每次对String的操作都会产生一个String对象
2. StringBuilder和StringBuffer是可变的,能够被多次修改,并不会产生新的对象.
3. StringBuilder是线程不安全的,StringBuffer是线程安全的.
4. StringBuilder的处理速度比StringBuffer要快
8. String str="i"与 String str=new String(“i”)一样吗?
他们的值相等,用equals得到true,但是他们是两个对象,如果用==判断返回false.
且str="i"是直接在常量池中引用字符串,而new String("i")是在堆中根据i再创建一个对象.
9. 如何将字符串反转?
1. 通过StringBuilder的reverse()方法可以直接反转
StringBuilder sb = new StringBuilder("abc");
sb.reverse().toString();
2. 通过String的toCharArray方法可以获得字符串每一个字符并且转换为字符数组
然后循环从后往拼接即可
3. 递归的方法反转(当只有一个字符时,返回原字符;当有两个以上的字符时,返回结果为第二个字符串开始的子串+第一个字符)
public String reverseString(String str) {
if ((null == str) || str.length()<2) {
return str;
}
return reverseString(str.subString(1)) +str.charAt(0);
}
10. String 类的常用方法都有那些?
charAt(int index)返回指定索引处的字符
length()返回字符串长度
split()根据给定的正则表达式拆分字符串
toString()返回此对象本身
11. 抽象类必须要有抽象方法吗?
抽象类可以没有抽象方法,但是如果一个类已经声明为抽象类,那么它也不能再实例化,不能直接构造该类对象.
12. 普通类和抽象类有哪些区别?
1. 抽象类不能被实例化,普通类反之
2. 抽象类的访问权限限于public和protected,如果为private的话,就不能被子类继承了.
3. 如果一个类继承于抽象类,则它必须实现父类的抽象方法.如果不想实现,那么子类也必须是抽象类.
13. 抽象类能使用 final 修饰吗?
不能,final修饰的类是不能被继承的,如果抽象类不能继承,就没有意义了.
14. 接口和抽象类有什么区别?
1. 抽象类可以有构造方法,接口不能有构造方法.
2. 抽象类可以包含非抽象方法,接口则不能.
3. 抽象类方法访问权限是public、protected,接口中只能是public.
4. 只能单继承,但是可以多实现.
15. java 中 IO 流分为几种?
大的方面来说有两种:字节流和字符流
字节流继承于InputStream、OutputStream
字符流继承于Reader、Writer

  1. BIO、NIO、AIO 有什么区别?
    1. BIO表示同步阻塞式IO,交互方式是同步、阻塞方式,即客户端有连接请求时服务端就需要启动一个线程进行处理,
      如果这个连接不做任何事情会造成不必要的开支.
    2. NIO表示同步非阻塞IO,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求
      时才启动一个线程处理.
    3. AIO表示异步非阻塞IO,客户端的I/O请求都是由操作系统先完成IO操作后再通知服务器应用来启动线程处理.
  2. Files的常用方法都有哪些?
    String getName():返回File对象所表示的文件名或文件路径
    String getPath():返回File对象所对应的相对路径
    boolean exists():判断File对象的文件或者目录是否存在
    boolean isDirectory():判断File对象是否是目录

二、容器

  1. java 容器都有哪些?
    String,数组以及java.util下面的集合类
    List:存放有序,列表存储,元素可重复
    ArrayList LinkedList Vector
    Set:无序,元素不可重复
    HashSet TreeSet
    Map:无序,元素可重复
    HashMap TreeMap LinkedHashMap HashTable
  2. Collection 和 Collections 有什么区别?
    Collection是集合类的一个顶级接口,它提供了对集合对象进行基本操作的通用接口方法.
    Collections是集合类的一个工具类,它提供了一系列的静态方法,用于对集合中元素进行排序,搜索以及线程同步等操作.
  3. List、Set、Map 之间的区别是什么?
    List: 可以允许重复的对象;
    可以插入多个null元素;
    有序,输入顺序就是输出顺序;
    Set: 不允许重复对象;
    无序,且只允许一个null对象;
    Map: 存储键值对,只能有唯一的key,value可以重复
    只能有一个null键
  4. HashMap 和 Hashtable 有什么区别?
    一. HashMap可以接受null键和值,HashTable不行
    二. HashTable是线程安全的,通过synchronized来保证,而HashMap线程不安全
    三. HashMap的迭代器是fail-fast迭代器,而HashTable的enumerator迭代器不是fail-fast.
  5. 如何决定使用 HashMap 还是 TreeMap?
    HashMap基于散列表实现,适用于查询频繁的情况
    TreeMap基于红黑树实现,适用于创建比较多的情况.且TreeMap存储数据是按照字母表的顺序存储的,
    如果对顺序有要求也可以选用TreeMap.
  6. 说一下 HashMap 的实现原理?
    数组+链表,初始16,75扩容,数据存在内部类Map.Entry中,其中包含key value hashcode和next.
  7. 说一下 HashSet 的实现原理?
    HashSet基于HashMap实现,默认构造函数是构造一个初始容量为16的HashMap,所有放入HashSet
    集合的元素实际上由HashMap的key来保存,而value则保存了一个PRESENT的静态Object对象,因为元素都保存在key
    中,所以才能不重复.
  8. ArrayList 和 LinkedList 的区别是什么?
    1. ArrayList底层基于动态数组,LinkedList基于链表实现,底层是循环双向链表
    2. 对于随机访问get和set,ArrayList优于LinkedList.
    3. 对于新增add和删除remove,LinkedList比较快
  9. 如何实现数组和 List 之间的转换?
    List转数组:toArray()方法.在方法参数中指定原集合的长度的数组即可.
    数组转List:Arrays的asList()方法.
  10. ArrayList 和 Vector 的区别是什么?
    1. Vector的方法都是同步的,是线程安全的,ArrayList则不是.
    2. 在进行扩容的时候,Vector扩容至原来的一倍,ArrayList增加至原来的0.5倍.
  11. Array 和 ArrayList 有何区别?
    1. Array(数组)可以包含基本数据类型和对象类型,ArrayList只能包含对象类型.
    2. ArrayList可以自动扩容,Array则不行.
  12. 在 Queue 中 poll()和 remove()有什么区别?
    Queue中,add方法和offer方法都可以添加元素,而remove和poll都是删除队列的头元素,区别在于:
    add方法在队列满的情况下抛异常,而offer方法则返回false.
    remove方法在队列为空时抛异常,poll方法将返回null.
  13. 哪些集合类是线程安全的?
    Vector HashTable ConcurrentHashMap
    Stack
  14. 迭代器 Iterator 是什么?
    Iterator是个接口,它提供了很多对元素进行迭代的方法.迭代器可以在迭代过程中删除
    底层集合的元素,可以直接调用Iterator的remove()方法来删除.
    因为在Conllection接口中定义了获取集合迭代器的方法,所以每一个集合都包括了可以返回迭代器实例的方法.
  15. Iterator 怎么使用?有什么特点?
    每个集合都可以用iterator()方法一个Iterator实例.
    使用next()方法获取序列中的下一个元素,使用hasNext()方法检查序列中是否有元素
    使用remove()方法将迭代器新返回的方法删除.
    特点:Iterator将集合的遍历和其底层的结构分离.
  16. Iterator 和 ListIterator 有什么区别?
    ListIterator是Iterator的子接口,用于扩展Iterator.
    在Iterator中,我们只能向前移动,无法操纵或者修改集合中的元素.ListIterator弥补了这种缺点
    区别: 1.范围不同,Iterator适用于所有集合,而ListIterator只适用于List及其子类
    2.ListIterator有add方法可以添加元素,Iterator则不行.
    3.ListIterator可以实现双向遍历,Iterator则不行.
    4.ListIterator可以实现对象的修改,Iterator不行
    5.ListIterator可以获取集合中的所有,Iterator不行.
  17. 怎么确保一个集合不能被修改?
    可以使用Collections或者Guava来快速实现.如Collections.unmodifiableMap(xxxMap);

三、多线程

  1. 并行和并发有什么区别?
    并行是多个事件同时进行,并发是多个事件在某一时间段内间隔发生.
    你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
    你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。

  2. 线程和进程的区别?
    进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位.
    进程有独立的地址空间,一个进程崩溃后在保护模式下不会对其他进程产生影响,而线程只是一个进程中的
    不同执行路径,线程有自己的堆栈和局部变量.在操作系统中能同时运行多个进程,而在同一个进程内有多个
    线程同时执行.

  3. 守护线程是什么?
    守护线程是服务其他线程的,在java中,线程有两种:守护线程和用户线程.
    java中的jvm垃圾回收线程就是一个典型的守护线程.当用户线程全部执行完,包括main线程也执行完毕,那么
    jvm会自动退出,此时守护线程也就停止了.

  4. 创建线程有哪几种方式?
    三种: 1. 继承Thread类,重写run方法,用子类实例调用start()方法;
    2. 实现Runnable接口并重写run方法,创建Thread实例并传入Runnable实例,代用Thread的start()方法
    3. 创建Callable接口的实现类,重写call方法;
    构造此实现类的实例,将其作为参数构造一个FutureTask类的实例;
    以FutureTask的实例为参数构造一个Thread对象执行start()方法.
    第三种方式可以允许有返回值,也可以声明抛出异常类.

  5. 说一下 runnable 和 callable 有什么区别?
    runnable方式时,多个线程间可以共享实例变量,callable方式则不行
    runnable方式没有返回值,callable有返回值
    runnable方式run方法的异常只能在内部消化,callable的call()方法允许抛出异常

  6. 线程有哪些状态?

    1. NEW 新建状态,此时线程还没有运行线程中的代码
    2. RUNNABLE 就绪状态;处于就绪状态的线程并不一定立即运行run方法,必须还要和其他线程竞争CPU时间
    3. RUNNING 运行状态;线程获得CPU时间后才进入运行状态,开始执行run方法
    4. BLOCKED 阻塞状态;线程运行过程中会有各种原因来进入阻塞状态,如:调用sleep方法进入休眠;
      在IO操作中被阻塞;试图得到一个锁,该锁正被其他线程持有;等待某个触发条件.
      阻塞状态的线程此时没有结束,暂时让出CPU时间给其他线程.
    5. DEAD 死亡状态;有两个原因导致线程死亡:第一是run方法正常退出自然死亡;第二是一个未捕获的
      异常终止了run方法使线程死亡.
      为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法,如果是可运行或被阻塞,这个方法返回true;如果线程仍旧是new状态且不是可运行的,或者线程死亡了,则返回false。
  7. sleep() 和 wait() 有什么区别?

    1. sleep方法使Thread类的,而wait方法使Object类中的
    2. sleep方法使线程暂停指定的时间,让出CPU给其他线程,但是他的监控状态依然保持着,时间到了以后会自动恢复运行状态
      在这个过程中,线程不会释放同步对象锁.
      而调用wait方法,线程会放弃对象锁,进入等待队列,待调用notify/notifyAll方法后才会进入锁池,获取对象锁后才进入运行状态.
  8. notify()和 notifyAll()有什么区别?
    notify()方法随机唤醒一个wait线程到锁池中去竞争锁,而notifyAll方法唤醒所有wait线程到锁池.
    notity()方法可能产生死锁,notifyAll则不会.

  9. 线程的 run()和 start()有什么区别?
    run()方法只是定义了线程的执行单元并非直接开启了线程资源,只有start()方法被调用,才可以启动一个线程.
    如果直接调用run方法,会被当成普通方法在main线程执行,并不会创建线程.
    44.创建线程池有哪几种方式?
    java中的Executors可以为我们创建现成的线程池,有以下几种:

    1. newSingleThreadExecutor 创建一个单线程的线程池,它只有一个工作线程,操作无界工作队列,可以保证任务顺序
    2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
    3. newCachedThreadPool 创建一个可缓存线程池,有空闲线程时会回收,但是任务过多,会一直创建,消耗资源
    4. newScheduledThreadPool 创建一个大小无线的线程池,此线程池支持定时以及周期性任务的需求.
      45.线程池都有哪些状态?
    5. RUNNING:一旦被创建,就处于此状态,可以接受新任务以及对已经添加的任务进行处理.
    6. SHUTDOWN:此时不接收新任务,但是可以处理已添加的任务
    7. STOP:此状态不接收新任务,不处理已添加任务,并且会中断正在处理的任务.
    8. TIDYING:当所有的任务已终止,ctl记录的任务数变为0,线程池会变成tidying状态.当线程池变为TIDYING状态会执行terminated()方法.
      当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。
      当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。
    9. TERMINATED:线程池彻底终止会变成这个状态.当在TIDYING状态,执行完terminated()函数后,就会由TIDYING状态变为TERMINATED状态.
  10. 线程池中 submit()和 execute()方法有什么区别?

    1. 接受参数不一样,execute()方法接收Runnable类型的参数;submit()可以接收runnable和callable类型的参数
    2. submit方法有返回值,返回一个Future类型的对象,execute方法没有返回值.
    3. submit方法方便处理Exception异常.
  11. 在 java 程序中怎么保证多线程的运行安全?

    1. 最简单的方式是加入synchronized关键字,在共享数据语句中加入该关键字可以在某一时段指挥让一个线程执行,其他线程不能执行.
    2. 使用锁Lock
    3. redis?
  12. 多线程锁的升级原理是什么?
    在java中,锁有三种状态,级别从低到高依次为:偏向锁、轻量级锁、重量级锁,这几个状态会随着竞争情况逐渐升级,但是不能降级.
    先说为什么要有锁升级:因为synchronized是重量级锁,每次在进行锁请求时,如果当前资源被其他线程占有,就要将当前线程阻塞,加入到阻塞队列中然后
    清空当前线程的缓存,等到锁释放时再通过notify或者notifyAll方法唤醒当前线程,让其处于就绪状态.在这个过程中是非常消耗资源的,而且有时候线程刚挂起,锁就释放了.
    而java的线程是映射到操作系统的原生线程之上的,每次线程的阻塞和唤醒都要在用户态和核心态之间转换,十分浪费资源.所以jvm对syncronized进行了优化,分为三种锁.

    1. 当锁对象第一次被线程获取的时候,虚拟机会将对象头中的锁标志位设置成01,并将偏向锁标志设置为1,线程通过CAS的方式将自己的ID值放到对象头中.这样每次该线程每次
      再进入锁对象的时候不用任何的同步操作,直接比较当前锁对象头中是不是该线程的ID,如果是就可以直接进入.当有其他线程来尝试获取锁的时候,发现偏向锁标示是1,说明
      锁已经被占用,则会使用CAS将对象头的偏向锁指向当前线程.
      需要注意的是,偏向锁使用一种等待竞争出现才会释放锁的机制,当有其他线程尝试获取锁的时候,才会释放锁.首先它会暂停拥有偏向锁的线程,然后检查持有偏向锁的线程
      是否活着,如果不处于活动状态,则将对象头设置为无锁状态;如果活着,那么拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,使之要么恢复到无锁要么标记对象不适合作为
      偏向锁.最后唤醒暂停的线程.
    2. 假设线程1持有偏向锁,线程2来竞争偏向锁:
      一. 首先线程2会检查偏向锁标记,如果是1,说明是偏向锁,那么JVM会找到线程1看其是否还活着.
      二. 如果线程1已经执行完毕,那么先将偏向锁置为0,对象头设置为无锁的状态,用CAS的方式尝试将线程2的ID放入对象头,此时锁不升级,还是偏向锁.
      三. 如果线程1还活着,先暂停线程1,将锁标志位变为00(轻量级锁),然后在线程1的栈帧中开辟出一块空间将对象头的Mark word置换到线程1的栈帧中,而对象头
      中存储的是指向当前线程栈帧的指针.此时变为轻量级锁,线程1继续执行,线程2采用CAS的方式尝试获取锁.
    3. 轻量级锁是通过CAS的方式尝试获取锁对象,一旦失败会先检查对象头中存储的是否是指向当前线程栈帧的指针,如果是,就可以获取锁对象,如果不是说明存在竞争那么久
      膨胀成为重量级锁.
    4. 一旦有两个以上的线程竞争锁,轻量级锁就会膨胀为重量级锁,锁的状态变为10,此时对象头中存储的就是指向重量级锁的栈帧的指针,而且其他等待所的线程要进入阻塞状态,
      等待重量级锁释放后被唤醒然后去竞争.重量级锁是由操作系统来负责线程的调度,会消耗大量的系统资源.
  13. 什么是死锁?
    死锁是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种相互等待的过程,如果没有外力作用,他们讲无法推进下去.

  14. 怎么防止死锁?

    1. 以确定的顺序获取锁
    2. 超时放弃.(Lock锁中就使用了这种方式)
    3. 银行家算法
  15. ThreadLocal 是什么?有哪些使用场景?
    也成为线程本地变量,ThreadLocal在每个线程中对一个变量创建了一个副本,且在线程内部任何地方都可以使用,线程间互不影响.
    应用场景:spring的声明式事物管理.

  16. 说一下 synchronized 底层实现原理?
    首先,每个对象都有一个监视器锁(monitor),当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:

    1. 如果monitor的进入数为0,则线程进入monitor,将进入数设置为1,该线程为monitor的所有者
    2. 如果线程已经占有monitor,只是重新进入,则进入数+1
    3. 如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获得所有权
      执行monitorexit的线程必须是objectref所对应的monitor的所有者.指令执行时,monitor的进入数-1,如果减为0,那么线程退出monitor,不再是持有者.
      在将synchronized代码块反编译以后,我们可以发现调用了monitorenter和monitorexit指令.
      所以如果synchronized同步代码块,底层是调用monitor的两个指令来实现锁
      如果synchronized同步方法,底层是读取运行时常量池的ACC_SYNCHRONIZED标志来实现的.
  17. synchronized 和 volatile 的区别是什么?

    1. volatile修饰的变量,jvm每次都从主内run读取,不会从工作内存读取
      而synchronized是锁住当前变量,同一时刻只有一个线程能访问当前变量.
    2. volatile只是作用于变量,synchronized可以用在变量,方法中
    3. valatile仅能实现变量修改的可见性,无法保证原子性.
      synchronized可以实现变量修改的可见性和原子性.
  18. synchronized 和 Lock 有什么区别?

    1. synchronized是java内置的关键字,Lock是个接口
    2. synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁.
    3. synchronized会自动释放锁,Lock需要手动释放
    4. synchronized可重入(同一个类中两个同步方法,获取到锁后不用每次都去获取),不可中断,非公平;Lock可判断可公平.
    5. synchronized获得锁的线程阻塞,其他线程都会无线等待,Lock不会
  19. synchronized 和 ReentrantLock 区别是什么?

    1. synchronized遇到异常不catch,锁会自动释放,ReentrantLock需要手动释放
    2. synchronized是非公平锁,ReentrantLock可以实现公平锁.
    3. 前者无法获取锁的状态,后者可以tryLock()方法可以返回是否获得了锁.
  20. 说一下 atomic 的原理?
    atomic包用中的类可以实现多线程环境下的变量操作,底层是调用CPU的CAS指令来进实现线程安全的.
    CAS,比较并操作,每次在set前,对比一下当前值和预期值是否一样,一样则set,否则认为失败,循环对比直到成功.

四、反射

  1. 什么是反射?
    在运行过程中,对任何一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能改变其属性.
  2. 什么是 java 序列化?什么情况下需要序列化?
    序列化就是一种用来处理对象流的机制,简单来说,就是把对象存储在某一个地方,硬盘或者网络,即把对象的内容转变为字节序列.
    当想把内存中的对象状态保存在一个文件或者数据库,或者在网络上传输的时候,就需要序列化,在java中需要实现Serializable接口.
  3. 动态代理是什么?有哪些应用?
    动态代理是将对象中不同方法的调用重新定向到一个统一处理函数,做自定义的逻辑处理,但是调用者察觉不到.
    应用: Spring的AOP,事物,权限,日志.RPC框架
  4. 怎么实现动态代理?
    1. 利用JDK的反射机制实现
    2. 使用CGLIB代理.

五、对象拷贝

  1. 为什么要使用克隆?
    想要对一个对象进行处理,但是又想保留原有的数据,这时可以使用克隆.
  2. 如何实现对象克隆?
    1. 实现Cloneable接口并重写Object的clone()方法
    2. 实现Serializable接口,通过对象的序列化和反序列化实现深度克隆
  3. 深拷贝和浅拷贝区别是什么?
    是否支持引用数据类型的成员变量的复制.

六、Java Web

  1. jsp 和 servlet 有什么区别?
    1. jsp擅长表现页面显示,servlet擅长逻辑控制
    2. servlet没有内置对象,jsp有内置对象
    3. servlet的应用逻辑在.java文件中,而jsp中,java和html组合为一个.jsp文件.
    4. servlet在java代码中嵌入html代码,jsp是在html中嵌入java代码
  2. jsp 有哪些内置对象?作用分别是什么?
    jsp有9个内置对象:
    request 用户端请求,此请求会包含来自GET/POST请求的参数
    response 网页传回用户端的回应
    pageContext 网页的属性是在这里管理
    session 与请求有关的会话期
    application servlet正在执行的内容
    out 用来传送回应的输出
    config servlet的构架部件
    page JSP网页本身
    exception 针对错误网页,未捕捉的例外
  3. 说一下 jsp 的 4 种作用域?
    application:它的有效范围是整个应用。整个应用是指从应用启动.pplication里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访 问时得到的是修改后的值。
    session:如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间 的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session)
    request:就说明它的作用域是request,它的有效范围是当前请求周期。所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过 程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
    page:代表变量只能在当前页面有效
  4. session 和 cookie 有什么区别?
    1. 数据存放位置不同.session在服务器,cookie在客户端浏览器
    2. 安全程度不同,别人可以分析存放在本地的cookie进行cookie欺骗.
    3. 单个cookie保存的数据不能超过4k,而session是在服务器的,所以没有限制
    4. cookie只能存储string类型的数据,session可以存储对象.
  5. 说一下 session 的工作原理?
    当用户第一次访问一个服务器,服务器就会为该用户创建一个session,并生成一个和该session有关的session_id,
    这个id是唯一的,不可重复.这个id将会在本次响应中返回,保存在客户端的cookie中,下次方法的时候,客户端浏览器
    的cookie中含有session_id,服务器基于这个id就可以识别该用户.
  6. 如果客户端禁止 cookie 能实现 session 还能用吗?
    可以,当cookie被禁用,我们可以使用"URL重写"来使session生效,简单来说就是将sessionid的信息作为请求地址的一部分
    这样服务器就可以解析URL,得到该sessionid,进而识别用户.
  7. spring mvc 和 struts 的区别是什么?
    1. mvc的入口是一个servlet,struts2的入口是一个filter
    2. mvc是单例的,struts2是多例的
    3. mvc面向方法开发,struts2面向类开发.
    4. struts2采用值栈存储请求和响应数据,mvc通过参数解析器将request请求解析.
  8. 如何避免 sql 注入?
    1. 采用预编译语句
    2. 使用正则过滤传入的参数.
    3. 屏蔽不安全的字符
  9. 什么是 XSS 攻击,如何避免?
    XSS攻击,即跨站脚本攻击.是指攻击者在用户端注入恶意的可运行脚本,让其在用户浏览网页时运行,从而通过脚本来获得用户的信息.
    避免: 对用户输入和URL参数进行过滤,过滤掉脚本相关的内容
    对输出进行编码
  10. 什么是 CSRF 攻击,如何避免?
    CSRF攻击也叫跨站请求伪造,攻击者通过伪造用户的浏览器请求,向用户自己曾经认证过的网站发送,使目标网站误以为
    是用户的真实操作而去执行命令.
    避免:1.令牌机制 2.token验证

七、异常

  1. throw 和 throws 的区别?
    throws:用来声明一个方法可能抛出的所有异常信息,不会处理异常,只是将异常向上传,交给调用者
    throw:抛出一个具体的异常类型.
    throws出现在方法声头,而throw出现在函数体
    throws表示出现异常的可能,并不一定会发生,throw则是抛出了一个存在的异常实例.

  2. final、finally、finalize 有什么区别?
    final: 修饰类,表示该类不可继承
    修饰方法,表示该方法不可重写
    修饰变量,表示该变量不允许被修改
    finally:是保证代码一定要被执行的一种机制.常用来关闭连接资源或者解锁等.
    finalize:是Object的一个方法,它的目的是保证对象在被垃圾收集前完成特定资源的回收.1.9后已经过时.

  3. try-catch-finally 中哪个部分可以省略?
    catch可以省略
    不管有没有捕获到异常,finally中的代码都会被执行;
    finally是在return之后执行的,程序在执行完return之后,会将值保存起来,当执行完finally中的代码之后再将return值返回
    如果finally中存在return,会导致最后返回的是finally中的值.

  4. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
    会执行,return的值会暂时保存.等到运行完finally中的代码块时才会返回return的值

  5. 常见的异常类有哪些?
    空指针异常类型:NullPointerException
    类型强制转换类型:ClassCastException
    数组下标越界异常:ArrayIndexOutOfBoundsException
    输入输出异常:IOException

八、网络

  1. http 响应码 301 和 302 代表的是什么?有什么区别?
    301和302都是HTTP请求的状态码,其中301代表永久性转移,302代表暂时性转移.
    301代表转向前的网址不在了,就会把新的网址当做有效目标
    302只是代表临时性重定向,旧的网址会保留.
  2. forward 和 redirect 的区别?
    forward:直接转发,客户端浏览器只发出一次请求,由第二个信息资源响应该请求,共享同一个request对象
    redirect:间接转发,服务端响应第一次请求的时候,让浏览器去访问另外一个URL,从而达到转发的目的.本质上是两次HTTP请求.
    forward地址栏不变,redirect地址栏改变
  3. 简述 tcp 和 udp的区别?
    tcp基于连接,udp基于无连接
    tcp对系统资源要求高,udp少
    tcp基于字节流,udp基于数据报文
    tcp复杂,udp简单
  4. tcp 为什么要三次握手,两次不行吗?为什么?
    1. 为了实现可靠数据传输,TCP 协议的通信双方,都必须维护一个序列号以标识发送出去的数据包中哪些是已经被对方收到的。
      三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤
    2. 如果只是两次握手,至多只有连接发起方的起始序列号能被确认,另一方选择的序列号则得不到确认
  5. 说一下 tcp 粘包是怎么产生的?
    TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
    产生原因:
    1. 发送方原因:TCP默认会使用Nagle算法。而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,
      在一个确认到来时一起发送。
    2. 接收方原因:TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,
      然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,
      应用程序读时,就会读到多个首尾相接粘到一起的包
  6. OSI 的七层模型都有哪些?
    1:物理层 2:数据链层 3:网络层 4:传输层 5:会话层 6:表示层 7:应用层
  7. get 和 post 请求有哪些区别?
    1.get产生一个TCP数据包,POST产生两个
    2.get将数据放在url中可以看到,post会放在html header中提交
    3.get数据大小有限制,最大1024字节,post没有限制
  8. 如何实现跨域?
    1.JSONP技术
    2.CORS规范
    3.通过服务端实现
    4.websocket
  9. 说一下 JSONP 实现原理?
    JSONP原理是动态添加一个

评论

企鹅群:39438021

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×