关于java:面试题Java基础

5次阅读

共计 14002 个字符,预计需要花费 36 分钟才能阅读完成。

JavaSE

JDK 和 JRE 有什么区别?

  1. JDK:java 开发工具包,提供了 java 的开发环境和运行环境。
  2. JRE:java 运行环境,为 java 的运行提供了所需环境。
    具体来说就是 JDK 其实蕴含了 JRE,同时还提供了编译 Java 源码的编译器 JAVAC,以及很多 java 程序调试和剖析的工具。
    简略来说:如果你须要运行 Java 程序,只需装置 JRE 就能够了,然而如果你须要编写 Java 程序,那么须要装置 JDK。

== 和 equals 的区别是什么?

对于根本类型和利用类型 == 的作用是不同的:
根本类型:比拟的是值是否雷同。
援用类型:比拟的是援用是否雷同。
equals 办法默认就是 ==,然而很多类都重写了 equals,例如 String、Integer,都重写了本人的 equals 变成了数据内容值的比拟。咱们也是能够重写本人的 equals 办法的。
总结:== 对于根本类型来说是值比拟,对于援用类型来说比拟的是援用。而 equals 默认状况下是援用比拟,只是很多类都重写了 equals 办法,比方 String、Integer 等都把它变成了值的比拟,所以个别状况下 equals 比拟的是值是否相等。

两个对象的 hashCode()雷同,equals 也肯定为 true,对吗?

不对,两个对象的 hashCode()雷同,而 equals 也不肯定为 true。
咱们总结一下对于 hashCode 相干的点:

  1. 两个对象的 hashCode()雷同,而 equals 是不肯定为 true 的。
  2. 只有两个对象的 hashCode()雷同,且 equals 为 true,这两个对象才完全相同。
  3. 如果重写了 equals,那么肯定要重写 hashCode()。保障 equals 为 true 的同时,hashCode()的值雷同。

final 在 Java 中有什么作用?

  1. final 润饰的类叫最终类,该类不能被继承。
  2. final 润饰的办法不能被重写。
  3. final 润饰的变量叫常量,常量必须被初始化,初始化之后的值不能被批改。

Java 中的 Math.round(-1.5)等于多少?

等于 -1,Math.round()四舍五入,大于 0.5 则向上取整。

String 属于根底的数据类型吗?

String 不属于根底类型,属于援用数据类型,即属于对象。
根底类型有 8 种:byte、short、int、long、float、double、boolean、char

Java 操作字符串都有哪些类?他们之间有什么区别?

String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 申明的是不可变的对象,每次操作都会生成新的 String 对象,而后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 能够再原有对象的根底上进行操作,所有在常常扭转字符串内容的状况下最好不要应用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程平安的,而 StringBuilder 是非线程平安的,但 StringBuilder 的性能要高于 StringBuffer,所以在单线程环境下举荐应用 StringBuilder,多线程环境下举荐应用 StringBuffer。

String str=”i” 与 String str = new String(“i”) 一样吗?

不一样,因为内存的调配形式不一样。String str = “i” 的形式,Java 虚构机会将其调配到常量池中;而 String str = new String(“i”)则会被分到堆内存中。

如何将字符串反转?

应用 StringBuilder 或者 StringBuffer 的 reverse()办法。

String 类的罕用办法都有哪些?

  1. indexOf():返回指定字符串的索引。
  2. charAt():返回指定索引处的字符。
  3. replace():字符串替换。
  4. replace():替换全副字符串。
  5. trim():去除字符串两端的空格。
  6. split():宰割字符串,返回一个宰割后的字符串数组。
  7. getBytes():返回字符串的 byte 类型数组。
  8. length():返回字符串长度。
  9. toLowerCase():将字符串转成小写字母。
  10. toUpperCase():将字符转成大写字母。
  11. substring():截取字符串。
  12. equals():字符串比拟。

抽象类必须要有形象办法吗?

不须要,抽象类不肯定非要有形象办法。

一般类和抽象类有哪些区别?

一般类不能蕴含形象办法,抽象类能够蕴含形象办法。
抽象类不能间接实例化,一般类能够间接实例化的。

抽象类能够应用 final 润饰吗?

不能,定义抽象类的目标就是让其余类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能润饰抽象类。

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

  1. 默认办法实现:抽象类能够有默认的办法实现,而接口不能有默认的办法实现。
  2. 实现:抽象类的子类是应用 extends 来继承的,而接口的实现类是应用 implements 来实现接口的。
  3. 构造函数:抽象类能够有构造函数,然而接口不能有构造函数。
  4. main 办法:抽象类能够有 main 办法,并且咱们能运行它。然而接口不能有 main()办法。
  5. 实现数量:一个类能够实现多个接口,然而只能继承一个抽象类。
  6. 拜访修饰符:接口中的办法默认都应用 public 润饰,而抽象类中的办法能够应用任意拜访修饰符。

Java 中 IO 流分为几种?

  1. 按性能来分:输出流,输入流。
  2. 按类型来分:字节流,字符流。
    字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,而字符流按 16 位传输以字符为单位输入输出数据。

BIO、NIO、AIO 有什么区别?

  1. BIO:Block IO 同步阻塞式 IO,就是咱们平时应用的传统 IO,它的特点是模式简略使用方便,但并发解决能力低。
  2. NIO:New IO 同步非阻塞 IO,是传统 IO 的降级,客户端和服务器通过 Channel(通信) 通信,实现了多路复用。
  3. AIO:Asynchronus IO 又是在 NIO 上的进一步降级,也叫 NIO2,实现了异步非阻塞式 IO,异步 IO 的操作基于事件和回调机制。

Flies 的罕用办法都有哪些哪些?

  1. Flies.exists():检测文件门路是否存在。
  2. Flies.createFile():创立文件。
  3. Flies.createDirectory():创立文件夹。
  4. Files.delete():删除一个文件或者目录。
  5. Files.copy():复制文件。
  6. File.move():挪动文件。
  7. Files.size():查看文件个数。
  8. Files.read():读取文件。
  9. Files.write():写入文件。

Java 容器

Java 容器都有哪些?

Java 容器分为 Collection 和 Map 两大类,其下又有很多类,如下所示:
Collection:

+ List
+ ArrayList
+ LinkedList
+ Vector
+ Stack
+ Set
+ HashSet
+ LinkedHashSet
+ TreeSet

Map:

+ HashMap
+ LinkedHashMap
+ TreeMap
+ ConcurrentHashMap
+ HashTable

Collection 和 Collection 有什么区别?

Collection 是一个汇合接口,它提供了对汇合对象进行基本操作的通用接口办法,所有汇合都是它的子类,比方 List、Set 等等。
而 Collections 是一个包装类,蕴含了很多静态方法,不能被实例化,就像一个工具类,比方提供的排序办法:Collections.sort(list)。

List、Set、Map 之间有什么区别?

咱们先别离谈一谈 List、Set 和 Map:

  1. List列表
    List 的元素以线性形式存储,能够寄存反复对象,List 次要有以下两个实现类:

    • ArrayList:长度可变的数组,对元素随机拜访的速度快,但向 ArrayList 中插入与删除元素的速度慢。JDK8ArrayList 扩容的实现是通过 grow() 办法里应用语句 newCapacity=oldCapacity+(oldCapacity>>1)(即 1.5 倍扩容)计算祘两,而后调用Arrays.copyof() 办法进行对原数组进行复制。
    • LinkedList:采纳链表数据结构,插入和删除速度快,但拜访速度慢。
  2. Set汇合
    Set 中的对象不按特定 (HashCode) 的形式排序,并且没有反复对象,Set次要有以下两个实现类:

    • HashSetHashSet依照哈希算法来存取汇合中的对象,存取速度比拟快。当 HashSet 中的元素个数超过数组大小 *loadFactor(默认值为 0.75)时,就会进行近似两倍扩容(newCapacity=(oldCapacity<<1)+1)。
    • TreeSet:TreeSet实现了 SortedSet 接口,可能对汇合中的对象进行排序。
  3. Map映射
    Map 是一种把键对象和值对象映射的汇合,它的每一个元素都蕴含一个键对象和值对象。Map次要有以下两个实现类:

    • HashMapHashMap基于散列表实现,其插入和查问 <K,V> 的开销是固定的,能够通过结构器设置容量和负载因子来调整容器的性能。
    • LinkedHashMap:相似于 HashMap,然而迭代遍历它时,获得<k,v> 的程序是其插入秩序,或者是最近起码应用(LRU)的秩序。
    • TreeMapTreeMap基于红黑树实现。查看 <K,V> 时,它们会被排序。TreeMap是惟一的带有 subMap() 办法的 map,subMap()能够返回一个子树。

    总结来说:

  4. List:继承接口为 Collection,常见实现类为 ArrayList、LinkedList,罕用办法为 add()、remove()、clear()等,元素可反复、有序。
  5. Set:继承接口为 Collection,常见实现类 HashSet、LinkedHashSet,罕用办法 add()、remove()、clear()等,元素不可反复。
  6. Map:常见实现类 HashMap、HashTable,常见办法 put()、get()、remove(),元素不可反复。

HashMap 和 HashTable 有什么区别?

  1. 存储:HashMap 容许 key 和 value 为 null,而 HashTable 不容许。
  2. 线程平安:HashTable 是线程平安的,而 HashMap 是非线程平安的。
  3. 举荐应用:在 HashTable 的类正文能够看到,Hashtable 是保留类不倡议应用的,举荐在单线程环境下应用 HashMap,多线程环境则应用 ConcurrentHashMap 代替。

如何决定应用 HashMap 还是 TreeMap?

对于在 Map 中插入、删除定位一个元素这类操作,HashMap 是最好的抉择,因为相对而言 HashMap 的插入会更好,但如果你要对一个 key 汇合进行有序的遍历,那 TreeMap 是更好的抉择。

说一下 HashMap 的实现原理?

HashMap 基于 Hash 算法实现的,咱们通过 put(key,value)存储,get(key)来获取。当传入 key 时,HashMap 会依据 key,hashCode()计算出 hash 值,依据 hash 值将 value 保留在 bucket 李。当计算出的 hash 值雷同时,咱们称之为 hash 抵触,HashMap 的做法是用链表和红黑树存储雷同 hash 值的 value。当 Hash 抵触的个数比拟少时应用链表,否则应用红黑树。

说一下 HashSet 的实现原理?

HashSet 是基于 HashMap 实现的,HashSet 底层应用 HashMap 的 key 来保留所有元素,因而 HashSet 的实现比较简单,相干 HashSet 的操作,基本上都是间接调用底层 HashMap 的相干办法来实现的,HashSet 不容许反复的值。

ArrayList 和 LinkedList 的区别是什么?

  1. 数据结构实现:ArrayList 是动静数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。
  2. 随机拜访法效率:ArrayList 比 LinkedList 在随机拜访的时候效率要高,因为 LinkedList 是线性的数据存储形式,所以须要挪动指针从前往后以此查找。
  3. 减少和删除效率:在非首尾的减少和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其余数据的下表。
    综合来说,在须要频繁读取汇合中的元素时,更举荐应用 ArrayList,而在插入和删除操作较多时,更举荐应用 LinkedList。

如何实现数组和 List 之间的转换?

  1. 数组转 List:应用 Arrays.asList(array)进行转换。
  2. List 转数组:应用 List 自带的 toArray()办法。

ArrayList 和 Vector 的区别是什么?

  1. 线程平安:Vector 应用了 Synchronized 来实现线程同步,是线程平安的,而 ArrayList 是非线程平安的。
  2. 性能:ArrayList 在性能方面更优于 Vector。
  3. 扩容:ArrayList 和 Vector 都会依据理论的须要动静的调整容量,只不过在 Vector 扩容每次会减少 1 倍,而 ArrayList 之后减少 50%。

Array 和 ArrayList 有和区别?

  1. Array 能够存储根本数据类型和对象,而 ArrayList 只能存储对象。
  2. Array 是指定固定大小的,而 ArrayList 大小是主动扩大的。
  3. Array 内置办法没有 ArrayList 多,比方 addAll、removeAll、iteration 等办法只有 ArrayList 有。

在 Queue 中 poll()和 remove()有什么区别?

  1. 相同点:都是返回第一个元素,并在队列中删除返回的对象。
  2. 不同点:如果没有元素 poll()会返回 null,而 remove()会间接抛出 NoSuchElementException 异样。

哪些汇合相似线程平安的?

Vector、Hashtable、Stack 都是线程平安。而像 HashMap 则是非线程平安的,不过在 JDK1.5 之后随着 Java.util.concurrent 并发包的呈现,它们也有了本人的对应的线程安全类,比方 HashMap 对应的线程安全类就是 ConcurrentHashMap。

迭代器 Iterator 是什么?

Iterator 接口提供遍历任何 Collection 的接口。咱们能够从一个 Collection 中应用迭代器办法来获取迭代器实例。迭代器取代了 Java 汇合框架中的 Enumeration,迭代器容许调用者在迭代器过程中移除元素。

Iterator 怎么应用?有什么特点?

List list = new ArrrayList<>():
Iterator it = list.iterator();
while(it.hashNext()){String obj = it.next();
    System.out.println(obj);
}

Iterator 的特点是更加平安,因为它能够确保,在以后遍历的汇合元素被更改的时候,就会抛出 ConcurrentModificationException 异样。

Iterator 和 ListIterator 有什么区别?

  1. Iterator 能够遍历 Set 和 List 汇合,而 ListIterator 只能遍历 List。
  2. Iterator 只能单向遍历,而 ListIterator 能够双向遍历(向前 / 后遍历).
  3. ListIterator 从 Iterator 接口继承,而后增加一些了额定的性能,比方增加一个元素、替换一个元素、获取后面或者前面元素的索引地位。

怎么确保一个汇合不能被批改

能够应用 Collections.unmodifiableCollection(Collection c) 办法来创立一个只读汇合,这样扭转汇合的任何操作都会抛出 Java.lang.UnsupportedOperationException 异样。

Java 多线程并发

并行和并发有什么区别?

  1. 并行:多个工作在同一个 CPU 核上,按细分的工夫片轮流(交替)执行,从逻辑上看那些工作时同时执行。
  2. 并发:多个处理器或多核处理器同时解决多个工作。

    并发:两个人用一台咖啡机
    并行:两个队列和两台咖啡机。

线程和过程的区别?

一个程序下至多有一个过程,一个过程下至多有一个线程,一个过程下也能够有多个线程来减少程序的执行速度。

守护线程是什么?

守护线程是运行在后盾的一种非凡过程。它独立于管制终端并且周期性地执行某种工作或期待解决某些产生的事件。在 Java 中垃圾回收线程就是非凡的守护线程。

创立线程有哪几种形式?

三种:

  1. 继承 Thread 重写 run()办法,调用 start()办法启动线程。
  2. 实现 Runnable 接口,重写 run()办法,调用 start()办法启动线程。
  3. 实现 Callable 接口。

说一下 runnable 和 callable 有什么区别?

  1. runnable 没有返回值,callable 有返回值
  2. runnable 无奈捕获异样,callable 能够捕捉到异样。

线程有哪些状态?

  1. NEW 尚未启动,新创建
  2. RUNNABLE 进入运行状态或者行将运行的状态
  3. BLOCKED 阻塞状态(被同步锁或者 IO 锁阻塞)
  4. WITING 永恒期待状态
  5. TIMED_WAITING 期待指定的工夫从新被唤醒的状态。
  6. TERMINATED 执行实现

sleep() 和 wait() 有什么区别?

  1. 类的不同:sleep()来自 Thread,wait()来自 Object 类.
  2. 开释锁:sleep()不会开释锁,wait()开释锁。
  3. 用法不同:sleep()工夫到会主动复原,wait()能够应用 notify()/notifyAll()间接唤醒。

notify()和 notifyAll()有什么区别?

  1. notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。
  2. notifyAll()调用后,会将全副线程由期待池移到锁池,而后参加锁的竞争,竞争胜利则继续执行,如果不胜利则留在锁池期待锁被开释后再次参加竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机管制。

线程的 run()的 start()办法有什么区别?

  1. run()办法体内保留的是线程须要执行的代码内容,而 start()是用于启动线程的。
  2. 单单的调用 run()办法,只是在调用了一个一般的办法,并不会开启一个新的线程,进行异步代码的执行。
  3. 而如果调用的是 start()办法,则会真正调用开启一个线程。

创立线程池有哪几种形式?

线程池创立有七种形式,咱们个别应用最初一种。

  1. newFixedThreadPool:创立一个固定大小的线程池,可管制并发的线程数,超出的线程会在队列中期待。
  2. newCachedThreadPool:创立一个可缓存的线程池,若线程数超过解决所需,缓存一段时间后回收,若线程数不够,则新建线程。
  3. newSingleThreadExecutor:创立单个线程池数的线程池,它能够保障先进先出的执行程序。
  4. newScheduledThreadPool:创立一个能够执行提早工作的线程池。
  5. newSingleThreadScheduledExecutor:创立一个车单线程的能够提早工作的线程池。
  6. newWorkStealingPool:创立一个车抢占式执行的线程池(工作执行程序不确定)
  7. ThreadPoolExecutor:手动创立线程池的形式,它创立时最多能够设置 7 个参数。

    • corePoolSize:外围线程数
      外围线程会始终存活,及时没有工作须要执行。当线程数大于 corePoolSize 时,且工作队列已满时,线程池会创立新线程来解决工作。
    • maxPoolSize:最大线程数
      当线程数大于 maxPoolSize 时,且工作队列已满时,线程池会回绝解决工作并且抛出异样。
    • queueCapacity:工作队列容量(阻塞队列)
      当线程数达到了外围线程数时,会把线程放到工作队列中。
    • keepAliveTime:线程闲暇工夫
      当线程闲暇工夫达到 keepAliveTime 时,线程就会退出,直到线程数量达到 corePoolSize。
    • allowCreThreadTimeOut:容许外围线程超出
      当 allowCoreThreadTimeOut=true 时,线程达到 keepAliveTime 时,外围线程池能够等于 0
    • rejectedExecutionHandler:工作回绝处理器
      ……

线程池都有哪些状态?

  1. running:承受新工作并解决队列中的工作。
  2. shutdown:尽管不承受新工作,然而解决队列中的工作。
  3. stop:不承受新的工作提交,不在解决期待队列中的工作,中断正在执行工作的线程。
  4. tidying:所以的工作都销毁了,workCount 为 0,线程池的状态在转换为 tidying 状态时,会执行钩子办法 terminated()。
  5. terminated:运行曾经实现了

线程池中 sumbit()和 execute()办法有什么区别?

  1. 两者的承受参数不一样:execute()办法只能承受 Runnable 类型的参数,而 submit()办法能够接管 Callable、Runnable 两种类型的参数。
  2. 返回值不同:submit()提交工作后能够有返回值,而 execute()提交工作后是不会有返回值的。
  3. 异样不同:submit()能够捕捉到异样,然而 execute()是没法捕捉异样的。

在 Java 程序中怎么保障多线程的运行平安?

  1. 应用安全类:比方 Java.util.concurrent 类的
  2. 应用主动锁:synchronized 关键字给代码块、办法、类加锁
  3. 应用手动锁:lock 关键字

多线程中 synchronzied 锁降级的原理是什么?

  1. 在锁对象的对象头外面有一个 threadid 的字段,在第一次拜访的时候 threadid 为空,jvm 会让其持有偏差锁,并将 threadid 设置为该线程的 id。
  2. 下次有线程来获取锁资源的时候,会先判断该线程的 id 与锁对象的对象头 threadid 字段是否统一。如果统一则间接获取到锁资源,如果不统一,则降级为轻量级锁(自旋锁)。
  3. 轻量级锁通过一直的循环 CAS 来尝试获取锁资源,直到循环到肯定次数后,还拿不到锁资源,则降级为重量级锁。
    锁降级是为了缩小锁带来的性能耗费,在 Java6 之后优化 synchronized 的实现形式,应用了偏差锁降级为轻量级再降级到重量级锁的形式,从而减低了锁带来的性能耗费。

什么是死锁?

两个或者一组线程同时被阻塞,都相互领有对方的锁,但同时都相互尝试获取对方手中的锁资源,却又都不开释。两个或多个线程都被有限的阻塞上来,程序不能失常的执行或完结,这被称为死锁。

死锁造成的条件?

  1. 互斥条件:一个资源每次只能被一个进应用
  2. 申请与放弃条件:一个过程因申请资源而阻塞时,对已取得的资源放弃不放。
  3. 不剥夺条件:过程以获取的资源,在未应用完之前,不能强行剥夺。
  4. 循环期待条件:若干过程之间造成一种头尾相接的循环期待资源关系。
    只有这四个条件,才会造成死锁。

如果防止死锁的产生?

只有四个死锁条件同时成立,才会产生死锁的状况,咱们只须要毁坏其中的一条就能够防止死锁。

  1. 尽量应用 tryLock(long timout, TimeUnit unit)的办法,设置超时工夫,超时能够退出防止出现死锁。
  2. 尽量应用 java.util.concurrent 下的并发类来代替本人手写锁。
  3. 尽量升高锁的应用粒度,尽量不要几个性能用同一把锁。
  4. 尽量减少同步的代码块。

ThreadLocal 是什么?有哪些应用场景?

ThreadLocal 为每个应用该变量的线程提供了独立的变量正本,所以每一个线程都能够独立地扭转本人的正本,而不会影响其余线程说对应的正本。
ThraedLocal 的经典应用场景是数据库链接和 session 治理等。

说一下 synchronized 底层实现原理?

sychronized 是由一对 monitorenter/monitorexit 指令实现的,字节码执行到 monitorenter 时,count+1,字节码执行到 monitorexit 指令时,count-1。当 count= 0 是,判断为以后锁资源没有被占有,count 不为 1 则示意以后锁资源曾经被占有了。因为须要进行用户态到内核态的切换,所有同步操作是一个无差别的重量级操作,性能很低。但在 Java6 之后,改为锁降级机制,提供了三种不同的 monitor 实现。也就是经常说的:偏差锁、轻量级锁、重量级锁,大大改良了其性能。

synchronized 和 volatile 的区别是什么?

  1. volatile 只能润饰变量,而 synchronized 能够润饰类、办法、代码块。
  2. volatile 仅能实现变量的可见性、禁止指令的重排序;而 synchroized 能够保障资源的可见性和原子性。
  3. volatile 是不会造成线程的阻塞的,而 synchronized 是可能造成线程的阻塞的。

sychronized 和 lock 有什么区别?

  1. synchronized 能够给类、办法、代码块加锁;而 lock 只能给代码块加锁。
  2. synchronized 不须要手动获取锁和开释锁,应用简略,产生异样会主动开释锁,不会导致死锁;而 Lock 须要本人加锁和开释锁,如果使用不当没有 unlock()去开释锁,就可能会导致死锁。
  3. lock 能够晓得是否胜利获取锁,而 synchronized 是无奈晓得的。

synchronized 和 ReentrantLock

  1. ReentrantLock 显示地取得、开释锁,synchronized 隐式的取得、开释锁。
  2. ReentrantLock 是 API 级别的,synchronized 是 JVM 级别的。
  3. ReentrantLock 能够实现偏心锁。
  4. ReentranLock 可响应中断,可轮回,synchronized 是不能够响应中断的。

说一下 atomic 的原理?

atomic 次要是利用 CAS、volatile、native 办法来保障原子操作,从而防止 synchronized 的高开销,执行效率大为晋升。

反射

什么是反射?

反射是在运行状态中,对于任意一个类,都可能晓得这个类的所有属性和办法;对于任意一个对象,都可能掉拽死它的任意一个办法和属性。这种动静获取信息以及动静调用对象的办法性能称为 Java 语言的反射机制。

什么是 Java 序列化?什么状况下须要序列化?

Java 序列化是为了保留各种对象在内存中的状态,并且能够把保留的对象状态再读出来。
以下状况须要应用 Java 序列化:

  1. 想把内存中的对象状态保留到一个文件中或者数据库中的时候。
  2. 想用套接字在网络上传送对象的时候。
  3. 想通过 RMI(近程办法调用)传输对象的时候。

动静代理是什么?有哪些利用?

动静代理就是运行时动静生成代理类。
动静代理的利用有 spring aop、hibernate 数据查问、测试框架的后端 mock、rpc、java 注解对象获取等。

怎么实现动静代理?

JDK 原生的动静代理和 CGLIB 动静代理。
JDK 原生动静代理是基于接口实现的,而 CGLIB 是基于继承以后类的子类实现的。

对象拷贝

为什么要应用克隆?

对象的拷贝须要应用克隆,如果想对一个对象进行解决,又想保留原有的数据进行接下来的操作,就须要应用克隆了,Java 语言中克隆针对的是类的实例。

如何实现克隆对象?

有两种形式:

  1. 实现 Cloneable 接口并重写 Object 类中的 clone()办法。
  2. 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,能够实现真正的深度克隆。

深拷贝和浅拷贝区别是什么?

深拷贝和浅拷贝最基本的区别在于是否真正获取一个对象的复制实体,而不是援用。
浅拷贝(shallowCopy)只是减少了一个指针指向已存在的内存地址,
深拷贝(deepCopy)是减少了一个指针并且申请了一个新的内存,使这个减少的指针指向这个新的内存,

servlet 相干

session 和 cookie 的区别?

  1. 存储地位不同:session 存储在服务器端;cookie 存储在浏览器端。
  2. 安全性不同:cookie 安全性个别,在浏览器存储,能够被伪造和批改。
  3. 容量和个数限度:cookie 有容量限度,每个站点下的 cookie 也有个数限度。
  4. 存储的多样性:session 能够存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器
    中。

说一下 session 的工作原理?

session 的工作原理是客户端登录实现之后,服务器会创立对应的 session,session 创立完之后,会把 session 的 id 发客户端,客户端再存储到浏览器中。这样客户端每次拜访服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就能够失常工作了。

如果客户端禁止 cookie 能实现 session 还能用吗?

能够用,session 只是依赖 cookie 存储 sessionid,如果 cookie 被禁用了,能够应用 url 中增加 sessionid 的形式保障 session 能失常应用。

如何防止 sql 注入?

  1. 应用预处理 PreparedStatement。
  2. 应用正则表达式过滤掉字符中的特殊字符

什么是 XSS 攻打,如何防止?

XSS 攻打:即跨站脚本攻打,它是 Web 程序中常见的破绽。原理是攻击者往 Web 页面里插入歹意的脚本代码(css 代码、Javascript 代码等),当用户浏览该页面时,嵌入其中的脚本代码会被执行,从而达到歹意攻打用户的目标,如盗取用户 cookie、毁坏页面构造、重定向到其余网站等。
预防 XSS 的外围是必须对输出的数据做过滤解决。
实在我的项目中,咱们会应用一个 Filter 对指定的非凡数据进行过滤。

什么是 CSRF 攻打,如何防止?

CSRF:Cross-Site Request Forgery(中文:跨站申请伪造),能够了解为攻击者盗用了你的身份,以你的名义发送歹意申请,比方:以你名义发送邮件、发消息、购买商品,虚构货币转账等
防止:

  1. 验证申请起源地址
  2. 要害操作增加验证码;
  3. 在申请地址增加 token 并验证。

throw 和 throws 的区别?

  1. throw:是实在抛出一个异样
  2. throws:是申明可能会抛出一个异样。

final、finally、finalize 有什么区别?

  • final:是修饰符,如果润饰类,此类不能被继承;如果润饰办法和变量,则示意此办法和此变量不能在被扭转,只能应用
  • finally:是 try{} catch{} finally{} 最初一部分,示意不管产生任何状况都会执行,finally 局部能够省略,但如果 finally 局部存在,则肯定会执行 finally 外面的代码。
  • finalize:是 Object 类的一个办法,在垃圾收集器执行的时候会调用被回收对象的此办法。

try-catch-finally 中哪个局部能够省略?

try-catch-finally 其中 catch 和 finally 都能够被省略,然而不能同时省略,也就是说有 try 的时候,必须前面跟一个 catch 或者 finally。

try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

finally 肯定会执行,即便是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。

常见的异样类有哪些?

  1. NullPointerException 空指针异样
  2. ClassNotFoundException 指定类不存在
  3. NumberFormatException 字符串转换为数字异样
  4. IndexOutOfBoundsException 数组下标越界异样
  5. ClassCastException 数据类型转换异样
  6. FileNotFoundException 文件未找到异样
  7. NoSuchMethodException 办法不存在异样
  8. IOException IO 异样
  9. SocketException Socket 异样

http 响应码 301 和 302 代表的是什么?有什么区别?

  1. 301:永恒重定向。
  2. 302:临时重定向。
    它们的区别是,301 对搜索引擎优化(SEO)更加无利;302 有被提醒为网络拦挡的危险。

forward 和 redirect 的区别?

  1. forward 是转发,而 redirect 是重定向
  2. 地址栏 url 显示:foward url 不会产生扭转,redirect url 会产生扭转;
  3. 数据共享:forward 能够共享 request 里的数据,redirect 不能共享;
  4. 效率:forward 比 redirect 效率高。

简述 tcp 和 udp 的区别?

tcp 和 udp 是 OSI 模型中的运输层中的协定。tcp 提供牢靠的通信传输,而 udp 则常被用于让播送和细节管制交给利用的通信传输。

  1. tcp 面向连贯,udp 面向非连贯即发送数据前不须要建设链接;
  2. tcp 提供牢靠的服务(数据传输),udp 无奈保障;
  3. tcp 面向字节流,udp 面向报文;
  4. tcp 数据传输慢,udp 数据传输快;

tcp 为什么要三次握手,两次不行吗?为什么?

如果采纳两次握手,那么只有服务器收回确认数据包就会建设连贯,但因为客户端此时并未响应服务器端的申请,那此时服务器端就会始终在期待客户端,这样服务器端就白白浪费了肯定的资源。若采纳三次握手,服务器端没有收到来自客户端的再此确认,则就会晓得客户端并没有要求建设申请,就不会节约服务器的资源。

说一下 tcp 粘包是怎么产生的?

tcp 粘包可能产生在发送端或者接收端,别离来看两端各种产生粘包的起因:

  1. 发送端粘包:发送端须要等缓冲区满才发送进来,造成粘包;
  2. 接管方粘包:接管方不及时接收缓冲区的包,造成多个包接管。

OSI 的七层模型都有哪些?

  1. 物理层:利用传输介质为数据链路层提供物理连贯,实现比特流的通明传输。
  2. 数据链路层:负责建设和治理节点间的链路。
  3. 网络层:通过路由抉择算法,为报文或分组通过通信子网抉择最适当的门路。
  4. 传输层:向用户提供牢靠的端到端的过错和流量管制,保障报文的正确传输。
  5. 会话层:向两个实体的表示层提供建设和应用连贯的办法。
  6. 表示层:解决用户信息的示意问题,如编码、数据格式转换和加密解密等
  7. 应用层:间接向用户提供服务,实现用户心愿在网络上实现的各种工作。

get 和 post 申请有哪些区别?

  1. get 申请会被浏览器被动缓存,而 post 不会。
  2. get 传递参数有大小限度,而 post 没有。
  3. post 参数传输更平安,get 的参数会明文限度在 url 上,post 不会。

如何实现跨域?

  1. 服务器端运行跨域 设置 CORS 等于 *;
  2. 在单个接口应用注解 @CrossOrigin 运行跨域;
  3. 应用 jsonp 跨域;

说一下 JSONP 实现原理?

jsonp:JSON with Padding,它是利用 script 标签的 src 连贯能够拜访不同源的个性,加载近程返回的“JS 函数”来执行的

正文完
 0