java2019常见面试题200+,附带答案(自己写的)正在更新中,已经到125

java基础

1.JDK 和 JRE 有什么区别?
  JDK是开发环境和运行环境一体的
  JRE是运行环境

2.== 和 equals 的区别是什么?
  “==”:比较的是指向地址
  “equals”:比较的是具体的内容

3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
  不对,反过来是对的。就是说如果equals比价为true,hashcode()相同

4.final 在 java 中有什么作用?
  final的字面意思是最后的,为了是不被重写,不被继承,且必须必须初始化,初始化就不能被改变

5.java 中的 Math.round(double a) 等于多少
  Math.round(-3.2) 运行结果是-3
  Math.round(5.6) 运行结果是6
  这个方法返回的是long,小数第一位大于5,个位就加1,小于等于,个位就不变

6.String 属于基础的数据类型吗?
  不属于,String属于对象,基本数据类型有int,long,char,byte,double,float,short和boolean

7.java 中操作字符串都有哪些类?它们之间有什么区别?

String,StringBuffer,StringBuilder,区别我其他的博客有写

8.String str="i"与 String str=new String(“i”)一样吗?
  不一样。“= = ”返回false,“equals”返回true

9.如何将字符串改变本身?
  用StringBuffer或者StringBuilder操作字符串

10.String 类的常用方法都有那些
  indexOf():返回指定字符的索引。
  charAt():返回指定索引处的字符。
  replace():字符串替换。
  trim():去除字符串两端空白。
  split():分割字符串,返回一个分割后的字符串数组。
  getBytes():返回字符串的 byte 类型数组。
  length():返回字符串长度。
  toLowerCase():将字符串转成小写字母。
  toUpperCase():将字符串转成大写字符。
  substring():截取字符串。

11.抽象类必须要有抽象方法吗?
  不是必须的,方法可以不抽象

12.普通类和抽象类有哪些区别?
  抽象类不能被实例化
  普通类不能有抽象方法

13.抽象类能使用 final 修饰吗?
  抽象类本身不能被final修饰,类里面的变量和方法如果没有abstract修饰就可以用final修饰

14.接口和抽象类有什么区别
  构造器:抽象类有,接口没有
  实现:抽象类用extends(一个类只能extends一个类),接口用implements(一个类可以implements多个接口)

15.java 中 IO 流分为几种?
  按功能来分:输入流(input)、输出流(output)。
  按类型来分:字节流和字符流。

16.BIO、NIO、AIO 有什么区别?
  BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
  NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
  AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

17.Files的常用方法都有哪些?
  Files.exists():检测文件路径是否存在。
  Files.createFile():创建文件。
  Files.createDirectory():创建文件夹。
  Files.delete():删除一个文件或目录。
  Files.copy():复制文件。
  Files.move():移动文件。
  Files.size():查看文件个数。
  Files.read():读取文件。
  Files.write():写入文件。

二、容器

18.java 容器都有哪些?
  数组,String,java.util下的集合容器

19.Collection 和 Collections 有什么区别?
  Collection是集合类的上级接口,继承与他有关的接口主要有List和Set
  Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作

20.List、Set、Map 之间的区别是什么?
  List中的元素,有序、可重复、可为空;
  Set中的元素,无序、不重复、只有一个空元素;
  Map中的元素,无序、键不重,值可重、可一个空键、多可空值;

21.HashMap 和 Hashtable 有什么区别?
  HashMap允许键和值是null,而Hashtable则不允许键或者值是null。
  Hashtable是同步的,而HashMap不是,所以HashMap更适用于单线程环境,Hashtable则适用于多线程环境

22.如何决定使用 HashMap 还是 TreeMap?
  有排序的情况下用TreeMap,没有用HashMap

23.说一下 HashMap 的实现原理?
  链表结构,hash一个元素的key,用hash决定这个元素的存放节点等,如果hash值相等,就把新元素放入节点的第一个位置,旧元素放到后面,并且新元素会用next指向旧元素,防止游离,jdk1.8后,如果一个节点的元素超过8个,就会转为红黑树,来提高效率。
  hashmap初始容量是16,扩充因子0.75,扩充系数是2,就是162=32
  hashmap可以放并且只能放一个null的key,并且在此map的第一位,value可以随意放null值

24.说一下 HashSet 的实现原理?
  hashSet和hashMap实现原理一样,只是不能允许放相同的值

25.ArrayList 和 LinkedList 的区别是什么?
ArrayList的实现是基于数组,LinkedList的实现是基于双向链表。
从应用上来说:
  ArrayLisst适合查找,LinkedList适合增删改
从内存上来说:
  linkedList占用内存多,因为除了要放数据外,还存储了一个个引用,这个引用是用来指向下一个元素的

26.如何实现数组和 List 之间的转换?
1,可以使用for循环,取出元素,然后在添加到另一个里面
2,list转数组
1:String[] str1 = (String[]) list.toArray()有人说这样写运行报错,但是我没有报
2:String[] str2 = (String[]) list.toArray(new String[list.size()])
数组转list

		String[] str = new String[] {"a","b","c","d"};
		List list = new ArrayList();
		list = Arrays.asList(str);

27.ArrayList 和 Vector 的区别是什么?
1,Vctor的方法都是同步的,且线程安全,ArrayList不是,所以ArrayList比Vctor性能好
2,Vctor增长是2倍,ArrayList是1.5倍

28.Array 和 ArrayList 有何区别?
  存放类型,Array可以放对象和基本类型,ArrayList只能包含对象类型
大小:Array的大小定义好之后不可以改变,ArrayList的大小是动态变化的
  话说回来,ArrayList底层实现也是Array。

29.在 Queue 中 poll()和 remove()有什么区别?
这2个都是在队列的头部删除元素,不同的是
  remove()如果删除头部元素为空的话抛出异常
  poll()如果删除头部元素为空的话会返回null
  源码里面是这样解释的,另外返回null比抛异常占用更少资源,所以对Queue的操作都会有2个一样的方法,来应对不用的场景
  另外官方源码给的建议是,如果队列的容量受限制,使用返回null的比抛出异常好

30.哪些集合类是线程安全的
  HashTable,ConcurrentHashMap,Vector,Stack(继承自Vector)这些源码里面都有synchronized关键字修饰

31.迭代器 Iterator 是什么?
  在Java中,有很多的数据容器,对于这些的操作有很多的共性。Java采用了迭代器来为各种容器提供了公共的操作接口。这样使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。
  迭代器是为了操作集合中的元素,for循环的内部机制就是迭代器

32.Iterator 怎么使用?有什么特点?
  Iterator iterator = 集合.iterator();//就是要配合各种集合使用
配合while()循环使用,用next来进行迭代循环
  特点是循环时remove不会报错,且Iterator.remove方法删除的是上一次Iterator.next()方法返回的对象。遍历集合的过程中不允许线程对集合元素进行修改否则会抛出ConcurrentModificationEception的异常

33.Iterator 和 ListIterator 有什么区别
  1,ListIterator有add()方法,可以向List中添加对象,而Iterator不能
  2,ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
  3, ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
  4,都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改
————综上所述,引发一个新的问题,如果ListIterator具有Iterator所有的方法,且比他还要多细分了几个,那为什么还要有Iterator存在在List里面呢。
  1,个人认为属于java的设计模式原则的其中之一,里氏替换原则有关。因为ListIterator是继承了Iterator,而里氏替换是任何父类出现的地方,子类一定可以出现,反过来也是一样。
  2,另外既然其他集合都有Iterator,那就不让List被孤立,给他也加一个Iterator
以上2个观点个人猜想,写出来玩玩,且听且信

34.怎么确保一个集合不能被修改?
  Collections.unmodifiableList(List)
  Collections.unmodifiableMap(Map)
  Collections.unmodifiableSet(Set)
  这3个方法都是为了不让集合修改,不过返回的是只读视图
  或者在类里面用private修饰,只给这个修饰的变量设置get方法,不设置set方法

三、多线程

35.并行和并发有什么区别?
首先记住一点:
  单核心cpu只能实现并发,不能实现并行。
举例
  cpu比作健身房。
  核心数比作跑步机。
  运行的程序等于上跑步机跑步的人。一台跑步机只能一个人跑。
  健身房只有一台跑步机。
  现在有10个人需要上跑步机跑。
  60分钟内,每个人都在不同的时间段上跑步机跑了一会锻炼完了身体。我们说  这十个人在60分钟内,并发了。
  但是现在健身房有多台跑步机。比如5台。
  10个人能进去5个人同时刻健身,那么我们说这5个人,并行了。(parallel)
只要记住一点:
  并行是同时刻在多个cpu核心发生的事件,并发是单个cpu核心在一个时间段内交替发生的事件。

36.线程和进程的区别?
  进程:一台电脑开一个qq是一个进程,开多个qq就是多个进程
  线程:一个qq开一个聊天窗口是一个线程,一个qq开多个聊天窗口就是多个线程
也就是说,线程运行在进程里面,且进程包括线程

37.守护线程是什么?
  1、守护线程,专门用于服务其他的线程,如果其他的线程(即用户自定义线程)都执行完毕,连main线程也执行完毕,那么jvm就会退出(即停止运行)——此时,连jvm都停止运行了,守护线程当然也就停止执行了。
  2、再换一种说法,如果有用户自定义线程存在的话,jvm就不会退出——此时,守护线程也不能退出,也就是它还要运行,干嘛呢,就是为了执行垃圾回收的任务啊

38.创建线程有哪几种方式?
(1)继承Thread类
优点:编写简单,如需访问当前线程,无须使用Thread.currentThread()方法,直接使用this即可获得当前线程。
缺点:线程已经继承Thread类,所以不能再继承其他父类。
(2)实现Runnable接口
优点:可以继承其他类。多个线程可以共享同一个target。
缺点:run()方法没有返回值,而且不能抛出异常。
(3)实现Callable接口
优点:call()方法可以有返回值,可以声明抛出异常。
缺点:使用复杂。

39.说一下 runnable 和 callable 有什么区别?
(1)Callable规定的方法是call(),Runnable规定的方法是run()。其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,c表示异步计算的结果。

40.线程有哪些状态?
  任何线程一般具有五种状态,即创建、就绪、运行、阻塞、终止。

41.sleep() 和 wait() 有什么区别?
  对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
  1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!);wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);
  2、sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;
  3、sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;

42.notify()和 notifyAll()有什么区别?
  notify()是唤醒一个线程去继续竞争锁
  notifyAll()是唤醒所有线程去继续竞争锁

43.线程的 run()和 start()有什么区别?
  run(); 只是调用了一个普通方法,并没有启动另一个线程,程序还是会按照顺序执行相应的代码。
  start(); 则表示,重新开启一个线程,不必等待其他线程运行完,只要得到cup就可以运行该线程。

44.创建线程池有哪几种方式?

		// 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
		// 这里如果去除sleep,则你会发现在这个循环中创建了新的线程,因为前一个任务没有执行完,所以创建新线程执行下一个任务。
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
		// 创建一个定长的线程池,也是根据需要去调用线程,比如线程定为100个,而循环只有10个,那么也只会用到前10个进程。
		ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(100);
		// 创建一个定长线程池,支持定时及周期性任务执行。
		ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);
		// 按顺序来执行线程任务 但是不同于单线程,这个线程池只是只能存在一个线程,这个线程死后另外一个线程会补上。
		ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

45.线程池都有哪些状态?
  线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated

46.线程池中 submit()和 execute()方法有什么区别?
1、接收的参数不一样
2、submit有返回值,而execute没有
用到返回值的例子,比如说我有很多个做validation的task,我希望所有的task执行完,然后每个task告诉我它的执行结果,是成功还是失败,如果是失败,原因是什么。
然后我就可以把所有失败的原因综合起来发给调用者。
个人觉得cancel execution这个用处不大,很少有需要去取消执行的。
而最大的用处应该是第二点。
3、submit方便Exception处理
意思就是如果你在你的task里会抛出checked或者unchecked exception,
而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过捕获Future.get抛出的异常。

47.在 java 程序中怎么保证多线程的运行安全?
  当多个线程要共享一个实例对象的值得时候,那么在考虑安全的多线程并发编程时就要保证下面3个要素:
  原子性(Synchronized, Lock)
  有序性(Volatile,Synchronized, Lock)
  可见性(Volatile,Synchronized,Lock)
  当然由于synchronized和Lock保证每个时刻只有一个线程执行同步代码,所以是线程安全的,也可以实现这一功能,但是由于线程是同步执行的,所以会影响效率。

48.多线程锁的升级原理是什么?
  在Java中,锁共有4种状态,级别从低到高依次为:无状态锁,偏向锁,轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。
(我没有找到与题目表达意思一样的答案,后续补充)

49.什么是死锁?
  当两个或多个线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁

50.怎么防止死锁?
1,一次封锁法:每个进程(事务)将所有要使用的数据全部加锁,否则,就不能继续执行;
2,顺序封锁法:预先对数据对象规定一个封锁顺序,所有进程(事务)都按这个顺序加锁;
3,银行家算法:保证进程处于安全进程序列

51.ThreadLocal 是什么?有哪些使用场景?
  ThreadLocal是用来维护线程中的变量不被其他线程干扰而出现的一个结构,内部包含一个ThreadLocalMap类
  使用场景:在并发编程中时常有这样一种需求:每条线程都需要存取一个同名变量,但每条线程中该变量的值均不相同

52.说一下 synchronized 底层实现原理?
源码翻译:
每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
1、如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。
2、如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.
3.如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权

53.synchronized 和 volatile 的区别是什么?
1,volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。
2,volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。
3,volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。

54.synchronized 和 Lock 有什么区别?
1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
3.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。

55.synchronized 和 ReentrantLock 区别是什么?
  这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成。

56.说一下 atomic 的原理?
  源码解读:当线程写数据的时候,先对内存中要操作的数据保留一份旧值,真正写的时候,比较当前的值是否和旧值相同,如果相同,则进行写操作。如果不同,说明在此期间值已经被修改过,则重新尝试。

四、反射

57.什么是反射?
  Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。)语言的一个关键性质

58.什么是 java 序列化?什么情况下需要序列化?
  序列化:是一种处理对象流的机制,而所谓对象流就是将对象的具体内容流化。这么做的目的是方便进行读写操作和异域传输。
应用场景:
  一是实现pojo对象的读写操作,将每个对象转换为字节流,而这些字节流可以被持久化到设备上,再次读取时会将字节流还原成对象。相当于将大象切割成几份放到冰箱里,当拿出来时,还是一头活生生的大象。(这个比喻貌似比上文要生动贴切多了~)这里还原对象使用的是反序列化。当我们希望某些数据能在程序停止运行后,还能继续存在。在程序再次执行时还能获取这些数据时,或者让其他的程序也能够利用这些数据资源时。这就是我理解的应用场景一。
  二是实现网络间的数据传输。网络间的数据传输是高频发而且数据量也是非常大的。以订单数据传输为例,当我们希望获取到订单类里的全部数据并据此生成一份订单的excel文件时,这个订单类就必须要实现序列化,这是我理解的应用场景二。

59.动态代理是什么?有哪些应用?
  动态代理:当想要给实现了某个接口的类中的方法,加一些额外的处理。比如说加日志,加事务等。可以给这个类创建一个代理,故名思议就是创建一个新的类,这个类不仅包含原来类方法的功能,而且还在原来的基础上添加了额外处理的新类。这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,扩展性强。
  动态代理的应用:Spring的AOP,加事务,加权限,加日志。

60.怎么实现动态代理?
1,首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回
2,CGLIB实现动态代理,不需要接口

五、对象拷贝

61.为什么要使用克隆?
  想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了。

62.如何实现对象克隆?
1, 实现Cloneable接口并重写Object类中的clone()方法;
2,实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆

63.深拷贝和浅拷贝区别是什么?
  浅拷贝:只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
  深拷贝:是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝

六、Java Web

64.jsp 和 servlet 有什么区别
jsp和servlet的区别和联系:
  1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
  2.jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
  3.Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到.
  Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。
  联系: JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑

65.jsp 有哪些内置对象?作用分别是什么?
JSP共有以下9个内置的对象:
1,request 用户端请求,此请求会包含来自GET/POST请求的参数
2,response 网页传回用户端的回应
3,pageContext 网页的属性是在这里管理
4,session 与请求有关的会话期
5,application servlet 正在执行的内容
6,out 用来传送回应的输出
7,config servlet的构架部件
8,page JSP网页本身
9,exception 针对错误网页,未捕捉的例外

66.说一下 jsp 的 4 种作用域?
  page:当前页面,也就是只要跳到别的页面就失效了
  request:一次会话,简单的理解就是一次请求范围内有效
  session:浏览器进程,只要当前页面没有被关闭(没有被程序强制清除),不管怎么跳转都是有效的
  application:服务器,只要服务器没有重启(没有被程序强制清除),数据就有效

67.session 和 cookie 有什么区别?
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中

68.说一下 session 的工作原理?
  用户向服务器发送一条session请求,服务器就会判断这个session有没有存在在服务器内,就是之前有没有被创建sessionId(每个客户都是唯一的),如果没有被创建,就新建一个sessionId,然后返回一个结果集给客户端,客户端以后在发送请求时,就用已经存在的sessionId和服务器交互,而且是每次求情都会带着sessionId。
  session默认的过期时间是30分钟,可以自行设置

69.如果客户端禁止 cookie 那 session 还能用吗?
可以
1,手动通过URL传值、隐藏表单传递Session ID。
2,用文件、数据库等形式保存Session ID,在跨页过程中手动调用。

70.spring mvc 和 struts 的区别是什么?
  首先,如果说项目中使用了spring,那么还是使用SpringMVC吧,因为相对于融合Struts来说,spring和SpringMVC是非常完美的无缝链接。
  其次,SpringMVC的拦截粒度是方法,而Struts的粒度是类
然后,入口不同,SpringMVC的入口是servlet,而Struts是filter
  最后,如果使用注解的话,SpringMVC基本上是零配置,而Struts需要配置很多。
  备注:想说一点的是:在Struts中可以配置开发者模式,就是说当修改了一个URL访问,可以不用重启工程。但是SpringMVC需要重启。

71.如何避免 sql 注入?
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串。终于达到欺骗server运行恶意的SQL命令
避免注入:
1.(简单又有效的方法)PreparedStatement
采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。
2.使用正则表达式过滤传入的参数
3.字符串过滤
4.jsp中调用该函数检查是否包函非法字符
5.JSP页面判断代码

72.什么是 XSS 攻击,如何避免?
  XSS攻击通常是指黑客通过"HTML注入"篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。
如何避免:
  服务器都会将JavaScript当做文本处理,在服务端整合进HTML文档中,在浏览器解析这些文本的过程,也就是XSS被执行的时候,所以主要的防御措施就是对任何用户提交到服务器上的文本都要经过编码或者转译。

73.什么是 CSRF 攻击,如何避免?
  我们首先来认识一下CSRF。CSRF(Cross-site request forgery)也被称为 one-click attack或者 session riding,中文全称是叫跨站请求伪造。一般来说,攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。常用于盗取账号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为
如何避免:
1.验证 HTTP Referer 字段
2.使用验证码
3.在请求地址中添加token并验证
4.在HTTP 头中自定义属性并验证

七、异常

74.throw 和 throws 的区别?
  hrows是用来声明一个方法可能抛出的所有异常信息,将异常声明但是不处理,将异常往上传,谁调用我就交给谁处理。
  throw则是指抛出的一个具体的异常类型。

75.final、finally、finalize 有什么区别?
  final:修饰词,如果用来修饰类,则类不能有子类,且不能被继承。如果修饰类的是变量或者方法,必须有初始值,可以被继承,但是不能被修改,只能读取。而且被声明为final的方法,只能使用不能被重写。
  finally:在异常处理时,指定必须要做的事情,搭配是,try-catch-finally,finally可以不写,具体看需求,如果写了,就一定会执行fianlly里面的代码。
  finalize:方法名,finaize()在Object类里面有定义,在对象被处理消失时,由JVM进行调用,用于对对象进行垃圾回收,

76.try-catch-finally 中哪个部分可以省略?
finally可以省略,如果业务不需要,完全可以不写,编译和运行都不会报错

77.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
会的,finally一定会执行,不管前面的catch做了什么事情

78.常见的异常类有哪些?
  Checked Exception(编译异常)
  Unchecked Exception(运行异常)
  算数异常类:ArithmeticExecption
  空指针异常类型:NullPointerException
  类型强制转换类型:ClassCastException
  数组下标越界异常:ArrayIndexOutOfBoundsException
  下标越界异常:IndexOutOfBoundsExecption
  违背安全原则异常:SecturityException
  文件未找到异常:FileNotFoundException
  字符串转换为数字异常:NumberFormatException
  操作数据库异常:SQLException
  输入输出异常:IOException
  方法未找到异常:NoSuchMethodException
  系统异常:SystemException
  不支持的操作异常:UnsupportedOperationException
  请求状态异常: IllegalStateException (extends RuntimeException ,父类:  IllegalComponentStateException ,在不合理或不正确时间内唤醒一方法时出现的异常信息。换句话说,即Java 环境或 Java 应用不满足请求操作)
  反射Method.invoke(obj, args…)方法抛出异常:InvocationTargetException
  参数不能小于0异常:ZeroException

八、网络

79.http 响应码 301 和 302 代表的是什么?有什么区别?
301 redirect: 301 代表永久性转移(Permanently Moved)
302 redirect: 302 代表暂时性转移(Temporarily Moved )
  301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址
  302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址

80.forward 和 redirect 的区别?
  forward:转发,request.getRequestDispatcher("/somePage.jsp").forward(request, response);
  redirect:重定向,response.sendRedirect("/somePage.jsp");
地址栏:forward为服务器的直接跳转,客户端浏览器并不知道,地址栏内容不变服务器内部的动作)
redirect为客户端浏览器根据URL地址重新向服务器请求,地址栏变(有可能是请求的
URI地址发生变化)
数据共享:forward共享浏览器传来的request
     redirect全新的request
运用的地方:forward用户登录后根据角色跳转页面
      redirect在用户注销后跳转主页或其他页面
效率:forward比redirect少了一次服务器请求,效率高一些

81.简述 tcp 和 udp的区别?
  udp:只管发送,没有回复,不管有没有送到。一对一发送。占用资源少。保证数据顺序
  tcp:发送后有回复,就是管发管到。可以一对一,也可以一对多。占用资源多。不保证数据顺序

82.tcp 为什么要三次握手,两次不行吗?为什么?
  为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
  如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

83.说一下 tcp 粘包是怎么产生的?
  TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
(1)发送方原因
  我们知道,TCP默认会使用Nagle算法。而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。
  所以,正是Nagle算法造成了发送方有可能造成粘包现象。
(2)接收方原因
  TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。
  
84.OSI 的七层模型都有哪些?
(1)物理层
(2)数据链路层
(3)网络层
(4)传输层
(5)会话层
(6)表示层
(7)应用层

85.get 和 post 请求有哪些区别?
1:GET在浏览器回退时是无害的,而POST会再次提交请求。
2:GET产生的URL地址可以被Bookmark,而POST不可以。
3:GET请求会被浏览器主动cache,而POST不会,除非手动设置。
4:GET请求只能进行url编码,而POST支持多种编码方式。
5:GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
6:GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
7:GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
8:GET参数通过URL传递,POST放在Request body中。

86.如何实现跨域?
(一) CORS(Cross-Origin Resource Sharing,跨源资源共享)
(二) JSONP(JSON with Padding 填充式JSON 或参数式JSON)
(三) window.name
(四) document.domain + iframe
(五) HTML5的window.postMessage
(六) 图片ping或script标签跨域
(七)WebSocket
(八)代理

87.说一下 JSONP 实现原理?
  JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。根据 XmlHttpRequest 对象受到同源策略的影响,而利用

你可能感兴趣的:(面试题目,个人纪录)