Java面试题

面试题

一、Java 基础

1.JDK 和 JRE 有什么区别?

​ JDK是Java开发工具包,包含各种类库和工具

​ JRE是JVM和核心类库

​ 电脑上装了jre能运行java程序,但不能进行java开发

2.== 和 equals 的区别是什么?

​ ==比较的是内存地址

​ equals比较的是两个变量或者实例指向的是不是同一内存空间

3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

​ 不对,一般要覆写其hashCode方法和equals方法,所以equals方法自己判断不相等

4.final 在 java 中有什么作用?

​ 1.final修饰类,其不能被继承

​ 2.final修饰方法,其方法不能被覆写

​ 3.final修饰变量,其变量成为常量

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

​ 四舍五入的,所以等于-1

6.String 属于基础的数据类型吗?

​ 不属于

​ 八大基本类型分别是

​ 整形: byte 1个字节 short int long

​ 浮点型: float double

​ 字符型 char

​ 布尔型: boolean

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

​ String、StringBuffer、StringBuilder

​ String : final修饰,String类的方法都是返回new String。即对String对象的任何改变都不影响到原对 象,对字符串的修改操作都会生成新的对象。
StringBuffer : 对字符串的操作的方法都加了synchronized,保证线程安全。
StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。

但StringBuild效率高于StringBuffer,所以才在1.5推出StringBuild

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

​ String str=“i”; 因为String 是final类型的,所以“i”应该是在常量池。

​ 而new String(“i”);则是新建对象放到堆内存中。

9.如何将字符串反转?

new StringBuffer(s).reverse().toString();

10.String 类的常用方法都有那些?

charAt(int index) toCharArray() substring() concat() split() replace() toLowerCase();

indexOf(int i) getBytes() lastIndexOf() toUpperCase()

11.抽象类必须要有抽象方法吗?

抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。
如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。

12.普通类和抽象类有哪些区别?

 1.抽象类不能被实例化。

​ 2.抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态。

​ 3.抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体

​ 4.含有抽象方法的类必须申明为抽象类

​ 5.抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类。

13.抽象类能使用 final 修饰吗?

​ 不能,被final修饰的类不能被继承

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

​ 抽象类和接口都不能被直接实例化,如果二者要实例化,就涉及到多态

​ 接口里面的方法只能声明,不能有具体的实现。这说明接口是设计的结果,抽象类是重构的结果。

​ 抽象类里面可以没有抽象方法。

​ 如果一个类里面有抽象方法,那么这个类一定是抽象类。

​ 抽象类中的方法都要被实现,所以抽象方法不能是静态的static,也不能是私有的private。

​ 接口(类)可以继承接口,甚至可以继承多个接口。但是类只能继承一个类。10、抽象级别(从高到低):接口>抽象类>实现类。

15.java 中 IO 流分为几种?

​ IO流分为BIO同步阻塞式IO,NIO 同步非阻塞I/O,AIO异步非阻塞IO

16.BIO、NIO、AIO 有什么区别?

AIO:从编程模式上来看AIO相对于NIO的区别在于,NIO需要使用者线程不停的轮询IO对象,来确定是否有数据准备好可以读了,而AIO则是在数据准备好之后,才会通知数据使用者,这样使用者就不需要不停地轮询了。当然AIO的异步特性并不是Java实现的伪异步,而是使用了系统底层API的支持,在Unix系统下,采用了epoll IO模型

17.Files的常用方法都有哪些?

​ createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false。
​ mkdir() 在指定位置创建一个单级文件夹。
​ mkdirs() 在指定位置创建一个多级文件夹。

​ 删除:
​ delete() 删除文件或者一个空文件夹,不能删除非空文件夹,马上删除文件,返回一个布尔值。
​ deleteOnExit()jvm退出时删除文件或者文件夹,用于删除临时文件,无返回值。
判断:
​ exists() 文件或文件夹是否存在。
​ isFile() 是否是一个文件,如果不存在,则始终为false。

18.为什么Java里面只允许单一继承,但允许实现多个接口?

多重继承会引起歧义 比如 a类有x方法 b类也有x方法 c类要是能继承a b类的话 那调用c类的x方法这个时候是该调用a父类的x方法还是b父类的x方法??? 要是把b类换成接口 那b 接口的x方法是抽象的那肯定就会调用a类的x方法

二、容器

18.java 容器都有哪些?

​ List:存放有序,列表存储,元素可重复

​ Set:无序,元素不可重复

​ Map:无序,元素可重复

19.Collection 和 Collections 有什么区别?

​ 1、java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

List,Set,Queue接口都继承Collection。直接实现该接口的类只有AbstractCollection类,该类也只是一个抽象类,提供了对集合类操作的一些基本实现。List和Set的具体实现类基本上都直接或间接的继承了该类。

​ 2、java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态方法(对集合的搜索、排序、线程安全化等),大多数方法都是用来处理线性表的。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

20.List、Set、Map 之间的区别是什么?

​ List存放有序,列表存储,元素可以重复

​ Set存放无序,元素不可重复

​ Map存放无序,元素可以重复

21.HashMap 和 Hashtable 有什么区别?

​ Hashtable是JDK1.0出现的,他是线程安全的,但效率低,并且key和value不允许为空,是基于hash表实现

​ HashMap是JDK1.2出现的,他是线程不安全的,效率比其高,允许key和value,是基于hash表和红黑树实现

22.如何决定使用 HashMap 还是 TreeMap?

​ TreeMap线程安全,而且是排序好的,适用于自然顺序或者自定义顺序遍历键

​ HashMap线程不安全,是不排序的,适用于在Map中插入,删除和定位元素

23.说一下 HashMap 的实现原理?

桶加链表或者红黑树,默认桶大小是16,负载因子默认0.75,若大于桶容量乘以负载因子则扩容,桶扩容为原来的两倍,链表在桶大小大于64并且链表长于8的时候树化为红黑树

24.说一下 HashSet 的实现原理?

HashSet的构造方法里面就是new了一个HashMap出来,使用其key,value设置为null

25.ArrayList 和 LinkedList 的区别是什么?

  1. ArrayList的实现是基于数组,LinkedList的实现是基于双向链表。

    2. 对于随机访问,ArrayList优于LinkedList
    3. 对于插入和删除操作,LinkedList优于ArrayList
    
  2. LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。

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

​ 数组转List:List list = Arrays.asList(arrays);

​ List转数组:String[] strings=(String [])list.toArray();

27.ArrayList 和 Vector 的区别是什么?

​ 1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。 Vector在其构造方法中就创建对象。
​ 2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。ArrayList采用懒加载,无参构造只是声明数组。

28.Array 和 ArrayList 有何区别?

​ Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明。

​ Array对象的初始化必须只定指定大小,且创建后的数组大小是固定的,
而ArrayList的大小可以动态指定,其大小可以在初始化时指定,也可以不指定,也就是说该对象的空间可以任意增加。

​ Array不能够随意添加和删除其中的项,而ArrayList可以在任意位置插入和删除项。

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

​ poll()方法不会抛出异常,如果为空返回null

​ remove()方法如果为空直接抛出异常

30.哪些集合类是线程安全的?

​ ConcurrentHashMap,Vector,Hashtable

31.迭代器 Iterator 是什么?

​ 正是由于每一个容器都有取出元素的功能。这些功能定义都一样,只不过实现的具体方式不同(因为每一个容器的数据结构不一样)所以对共性的取出功能进行了抽取,从而出现了Iterator接口。而每一个容器都在其内部对该接口进行了内部类的实现。也就是将取出方式的细节进行封装。

32.Iterator 怎么使用?有什么特点?

public static void testIteratorNext() {
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
			String str = iterator.next();
			System.out.println(str);
		}
	}
  • 在迭代过程中调用集合的 remove(Object o) 可能会报 java.util.ConcurrentModificationException 异常

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仅能遍历,不能修改。

34.怎么确保一个集合不能被修改?

​ 可以采用Collections包下的unmodifiableMap方法,通过这个方法返回的map,是不可以修改的。他会报 java.lang.UnsupportedOperationException错。

​ 同理:Collections包也提供了对list和set集合的方法。
​ Collections.unmodifiableList(List)
​ Collections.unmodifiableSet(Set)

三、多线程

35.并行和并发有什么区别?

​ 并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。 并行性指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行。

36.线程和进程的区别?

​ 根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

​ 在开销方面:每个进程都有自己的独立代码和数据空间,程序之间切换消耗大,线程可以看做轻量级的进程,同一类线程共享代码和数据空间,线程之间切换消耗小

37.守护线程是什么?

​ 如果JVM中没有在运行的非守护线程,JVM将退出。守护线程拥有自动结束自己生命周期的特性,而非守护线程不具备这个特点。JVM的垃圾回收按成就是守护线程

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

​ 线程创建有三种方式 1.继承Thread类,2.实现Runnable接口,3.实现Callable接口

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

Callable接口

public interface Callable<V> {
    V call() throws Exception;
}

Runnable接口

public interface Runnable {
    public abstract void run();
}

不同点:Runnable没有返回值,Callable有返回值,是泛型,和Future、FutureTask配合可以用来获取异步执行的结果

Callable接口的call()方法允许抛出异常;Runnable的run()方法异常只能在内部消化,不能往上继续抛

40.线程有哪些状态?

​ 1.新建 2.准备运行 3.运行中 4.阻塞 5.死亡

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

  • 这两个方法来自不同的类分别是Thread和Object
  • 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法(锁代码块和方法锁)。
  • wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
  • sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

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

  • 如果调用了wait()方法,那么该线程将处于该对象的等待池中 ,等待池中的线程不会去竞争该对象的锁。
  • 当有线程调用了notify(随机唤醒一个)或者notifyAll方法(全部唤醒),被唤醒的线程进入该对象的锁池中,锁池中的线程会去竞争该线程的锁,
  • 优先级高的线程容易获取锁,如果没有获取锁,该对象还在锁池中,除非有线程调用wait方法

43.线程的 run()和 start()有什么区别?

​ start()方法是启动线程的,而run()中放的是线程执行的代码

​ start()方法调用本地start0()方法

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

  • public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<Runnable>());
    }
    FixedThreadPool 采用无界队列LinkedBlockingQueue,新任务在无界队列中,所以不会采用拒绝策略
    
  • public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
    (new ThreadPoolExecutor(1, 1,
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<Runnable>()));
    }
    SingleTreadExecutorSingleThreadExecutor 的corePoolSize 和maximumPoolSize 被设置为1 。其他参数与FixedThreadPool 相同。
    SingleThreadExecutor 使用无界队列LinkedBlockingQueue 作为线程池的工作队列( 队列的容量为
    Integer.MAX_VALUE)
  • public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
    60L, TimeUnit.SECONDS,
    new SynchronousQueue<Runnable>());
    }
    CachedThreadPool的corePoolSize被设置为0,即corePool为空;maximumPoolSize被设置为Integer.MAX_VALUE,即
    maximumPool是无界的。这里把keepAliveTime设置为60L,意味着CachedThreadPool中的空闲线程等待新任务的最
    长时间为60秒,空闲线程超过60秒后将会被终止。
    
  • ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运行任务,或者定期执行任
    务。ScheduledThreadPoolExecutor的功能与Timer类似,但ScheduledThreadPoolExecutor功能更强大、更灵活。Timer
    对应的是单个后台线程,而ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。

创建线程池有用juc下面的工具包Executors创建,

45.线程池都有哪些状态?

  • Running:线程被创建出来就是Running状态
  • stop:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
  • shutdown:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。
  • TIYING: 当所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING状态。
  • TERMINATED:线程池彻底终止,就变成TERMINATED状态。

46.线程池中 submit()和 execute()方法有什么区别?

​ 1、接收的参数不一样

​ 2、submit有返回值,而execute没有

47.在 java 程序中怎么保证多线程的运行安全?

​ 1.原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作,(atomic,synchronized);

​ 2.可见性:一个线程对主内存的修改可以及时地被其他线程看到,(synchronized,volatile);

​ 3.有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序,(happens-before原则)。

使用Synchronized同步锁,还有juc下的lock

48.多线程锁的升级原理是什么?

锁升级:无锁状态->偏向锁->轻量级锁->重量级锁

偏向锁:获取:当一个线程访问同步块并获取锁的时候,会在对象头和栈帧中记录偏向锁线程ID,以后该线程进入和退出代码块不需要CAS操作去加锁解锁,只需要简单验证一下对象头里的MarkWord里是否存储着指向当前线程的锁。

​ 解锁:当有其他线程竞争,持有偏向锁的线程才会释放锁,偏向锁的撤销,需要等待全局安全点,没有正在运行的字节码,首先暂停持有偏向锁的线程,检查该线程是否存活,不存活将其设置为无锁状态,MarkWord偏向其他线程或者设置为无锁状态,或者标记对象不适合用偏向锁,最后唤醒暂停的线程

轻量级锁:JVM也存在类似的情形:多个线程在不同的时间段请求同一把锁,也就是说没有锁竞争。针对这种情况,JVM采用了轻量级锁,来避免线程的阻塞以及唤醒。

加锁:线程执行同步代码块之前,JVM会在线程栈中创建用于存储锁记录的空间,并将MarkWord复制到锁记录中,然后通过CAS将MarkWord替换为指向锁记录的指针,如果成功,获取锁,如果失败尝试自旋获取锁。

解锁:线程将自己记录的MarkWord通过CAS替换回对象头,如果成功,则没有锁竞争,如果失败,则表示存在锁竞争,锁会膨胀成重量级锁

重量级锁 :是JVM最基础的实现,他会阻塞获取失败的线程,并在锁释放的时候唤醒其他线程,JVM采用了适应性自旋,来避免面对非常小的Synchronized代码块进行阻塞唤醒,因为阻塞唤醒是操作系统层面的,需要从用户态切换为内核态。

49.什么是死锁?

线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。

死锁产生的四个必要条件:

​ 1.不剥夺条件

​ 2.循环等

​ 3.请求与保持

​ 4.互斥条件

50.怎么防止死锁?

​ 1.加锁顺序

​ 2.加锁检测

​ 3.加锁时限

51.ThreadLocal 是什么?有哪些使用场景?

​ ThreadLocal 可以为每个线程创建一个【单独的变量副本】,相当于线程的 private static 类型变量。

​ Spring的事务管理器通过AOP切入业务代码,在进入业务代码前,会依据相应的事务管理器提取出相应的事务对象,假如事务管理器是DataSourceTransactionManager,就会从DataSource中获取一个连接对象,通过一定的包装后将其保存在ThreadLocal中。而且Spring也将DataSource进行了包装,重写了当中的getConnection()方法,或者说该方法的返回将由Spring来控制,这样Spring就能让线程内多次获取到的Connection对象是同一个。

52.说一下 synchronized 底层实现原理?

​ 48题答案

53.synchronized 和 volatile 的区别是什么?

  • Synchronized不能使用在变量级别,而volatile可以
  • Synchronized会阻塞线程,而volatile不会
  • volatile能保证变量的可见性,但不能保证其原子性
  • volatile可以防止指令重排,synchronized不可以
  • volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; 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,如果一个线程正在等待锁,那么结果只有两种情况,要么获得这把锁继续执行 ,要么就保持等待。而使用ReentrantLock,如果一个线程正在等待锁,那么它依然可以收到通知,被告知无需再等待,可以停止工作了。

56.说一下 atomic 的原理?

如何保证原子性:自旋 + CAS(乐观锁)。在这个过程中,通过compareAndSwapInt比较更新value值,如果更新失败,重新获取旧值,然后更新。

56.说一下AQS?

AQS实现了对同步状态的管理,阻塞线程的排队,等待通知等底层实现处理。AQS采用模板设计模式

首先acquire先调用tryAcquire,如果失败调用addWaiter方法,将当前线程包装成node节点,然后判断尾节点是否为null,如果空调用初始化方法,否则直接尾插,初始化方法使用CAS将head指向新创建的节点,然后尾节点也指向这个新创建的节点,然后进入acquireQueue方法

先判断这个节点是否为头结点并且能不能获取到锁,如果可以将单签节点设置为头节点,如果失败将节点状态设置为signal,park方法阻塞当前线程, 如果线程中断或者前驱节点释放,再去判断

四、反射

57.什么是反射?

​ 反射就是在运行中,能够知道任何一个类的所有属性和方法,对于任何一个对象,都能调用他的方法和属性,并且改变他的属性。

58.什么是 java 序列化?什么情况下需要序列化?

​ 序列化:将java对象转换为字节流的过程。

​ 什么情况下需要:java对象需要在网上传输,或者持久化到文件中。

59.动态代理是什么?有哪些应用?

​ 动态代理:想要给某个实现接口的类拓展,可以创建一个代理类,这个类不仅调用原有方法,还有拓展方法,代理类中的目标类不是创建好的,而是动态创建出来的。

​ 常见代理有JDK Proxy ,和cglib

​ 应用:Spring AOP,加事务,加日志等

60.怎么实现动态代理?

​ 可以通过java内建的动态代理功能或者通过cglib(code generation library)来实现。需要注意的是,java的动态代理只能对接口进行代理,需要对类进行代理只能使用cglib。

​ JKD的动态代理,代理类实现 InvocationHandler接口,实现invoke方法

​ 而cglib的动态代理,需要让代理类实现MethodInterceptor接口

public class CglibProxy implements MethodInterceptor
{
    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz) {
        // 设置需要创建子类的类
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        // 通过字节码技术动态创建子类实例
        return enhancer.create();
    }

    // 实现MethodInterceptor接口方法
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("前置代理");
        // 通过代理类调用父类中的方法
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("后置代理");
        return result;
    }
}
//客户端调用
public class ClientForCglib
{
    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        Person proxyson =  (Person)proxy.getProxy(Person.class);

        proxyson.say();
    }
}

五、对象拷贝

61.为什么要使用克隆?

​ 想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了。克隆分浅克隆和深克隆,浅克隆后的对象中非基本对象和原对象指向同一块内存,因此对这些非基本对象的修改会同时更改克隆前后的对象。深克隆可以实现完全的克隆,可以用反射的方式或序列化的方式实现。

62.如何实现对象克隆?

​ 1.实现cloneable接口,然后重写Object里面的clone()方法

​ 2,实现Serializable接口,然后通过序列化和反序列化实现深拷贝。

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

浅拷贝:对于数据类型是基本类型的数据,浅拷贝直接进行值传递,也就是将属性复制一份给新的对象,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。而对于非基本类型,其只是进行引用传递,也就是将该变量的引用值(内存地址)复制一份给新的对象,修改其中一个会影响另外一个。

深拷贝:对象进行深拷贝要对整个对象都进行拷贝

深拷贝对引用数据类型的成员变量的对象图中所有的对象都开辟了内存空间;而浅拷贝只是传递地址指向,新的对象并没有对引用数据类型创建内存空间。

六、Java Web

64.jsp 和 servlet 有什么区别?

​ JSP经过编译成为Servlet(JSP本质就是Servlet,JVM只能识别java的类,不能识别JSP,Web容器将JSP编译成JVM能够识别的java类)

​ JSP侧重于视图,而Servlet侧重于代码逻辑

​ 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 有哪些内置对象?作用分别是什么?

​ request:用户端请求,包含来自get/post的请求参数

​ response:网页传回客户端的信息

​ pageContext:网页属性管理

​ Session:请求有关的会话,session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息

​ application: Servlet正在执行的内容

​ out:用于传送回应的输出

​ Exception:针对错误网页

​ config:Servlet的架构组件

​ page :JSP网页本身

66.说一下 jsp 的 4 种作用域?

就是指一个信息在多大范围有效

​ application:表示在整个程序有效

​ application作用域上的信息传递是通过ServletContext实现的,它提供的主要方法如下所示:

Object getAttribute(String name) //从application中获取信息;

void setAttribute(String name, Object value) //向application作用域中设置信息。

​ session:表示在当前会话

session是通过HttpSession接口实现的,它提供的主要方法如下所示:

Object HttpSession.getAttribute(String name) //从session中获取信息。

void HttpSession.setAttribute(String name, Object value)//向session中保存信息。

HttpSession HttpServletRequest.getSessio() //获取当前请求所在的session的对象。

​ Request:表示当前请求有效

​ page:当前页面

67.session 和 cookie 有什么区别?

​ 1.ession可以存放java对象,而cookie只能存放字符串

​ 2.一个在客户端一个在服务端,Cookie在客户端容易被伪造,所以不安全。

​ 3.Session过多会消耗服务器资源,大型网站会有专门的Session服务器

​ 4.域的支持范围不同,比如abc.com下的Cookie在abc.com下都能用,而而www.a.com的Session在api.a.com下都不能用,解决这个问题的办法是JSONP或者跨域资源共享。

68.说一下 session 的工作原理?

​ 客户端第一次访问服务器,生成Session,Sessionid和其对应

​ 客户端:将SessionID存储到cookie。

​ 服务器:将Session存放到内存中,或者持久化到本地或者数据库

​ 浏览器:不会因为关闭而销毁Session,必须通过invalidate或者超时才能销毁

​ sessionId由tomcat的ManagerBase类提创建sessionid的方法

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

用文件、数据库等形式保存Session ID,在跨页过程中手动调用。

手动通过URL传值、隐藏表单传递Session ID。

70.spring mvc 是什么,流程?

springMVC是基于请求驱动的web框架,使用了前端控制器模型设计,根据请求映射规则分发给相应的页面控制器去处理。

1.用户发送请求到前端控制器

2.dispathcerServlet根据请求信息把他交给HandlerMapping,

3.HandlerMapping根据其找到Handler,然后返回执行链

4.dispatherServlet让HandlerAdapter调用handler返回ModuleAndView

5.DispatcherServlet将ModuleAndView返回给ModuleReslover返回View

6.DispatcherServlet将View进行数据填充

7.然后返回给用户

71.如何避免 sql 注入?

​ 1.正则表达式匹配输入是否在合法范围内

​ 2.过滤特殊符号

​ 3.采用预编译

72.什么是 XSS 攻击,如何避免?

原则是将一段JavaScript代码注入网页。然后当其他用户访问该页面时,他们将运行黑客编写的JS代码来实现一些帐户控制

关键字判断当有一个关键字如脚本、src来代替损坏;返回内容时进行转码,转码尖括号采用Unicode编码格式

73.什么是 CSRF 攻击,如何避免?

CSRF(Cross-site request forgery)跨站请求伪造,构造正确的Get链接,让浏览器发送Get请求。由于用户已经登录,因此它将携带正确的cookie并直接访问链接以实现相关功能。

​ 解决方案是向表单添加字段标记。黑客无法猜出已经改变的令牌,所以即使你添加一个UUID令牌,将它保存到服务器会话,黑客也不可能猜出随机令牌,就无法构造出能实现功能的链接了。

七、异常

74.throw 和 throws 的区别?

throws是在方法上抛出,让调用者去处理

throw是在方法内部抛出,如果执行throw语句,后面语句不会再执行

75.final、finally、finalize 有什么区别?

1.final是关键字

2.finally是处理异常时候用到的

76.try-catch-finally 中哪个部分可以省略?

可以try-catch try-finally

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

78.常见的异常类有哪些?

NullPointException ArrayOutofBoundException

CLassCastException FileNotFoundException

OutOfMemoryException

八、网络

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

301:永久重定向

302:暂时重定向

抓取新的内容,但还是旧的网址

80.forward 和 redirect 的区别?

地址栏:forward直接跳转,地址栏不变,服务器内部动作

​ redirect为客户端浏览器url重新向服务器请求,地址栏发送变化

request作用域:forward是同一个request

​ redirect是新的Request

使用地方:用户登录后角色跳转

​ 退出登陆后跳转其他页面

81.简述 tcp 和 udp的区别?

tcp是可靠的,因为他有确保机制,比如三次握手,超时重传,序号标识,滑动窗口

udp是不可靠的,他尽最大可能保证数据不会丢失

每一条tcp是点对点的,而udp可以一对多,多对一,多对多

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

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

粘包发生在发送或者接受缓冲区;应用程序从缓冲区取数据是整个缓冲区有多少取多少;

那么有可能第一个数据的尾部和第二个数据头部都在缓冲区中,而TCP是流式的,数据无边界,这时发生粘包。

解决发送方粘包

​ 1发送产生是因为Nagle算法合并小数据包,所以可以禁用此算法

​ TCP提供了强制数据立刻传输操作指令push

​ 数据包加头,头信息为整个数据长度

接收方解决粘包

​ 解析数据包头部信息,按照长度接受

84.OSI 的七层模型都有哪些?

物理层

数据链路层

网络层 IP协议

传输层 TCP UDP

会话层

表示层

应用层

85.get 和 post 请求有哪些区别?

get请求将参数包含在url中,而post是将参数放在Request body中

get只能url编码,而post可以多种形式编码

get回退是无害的,而post将重新提交

get参数会被保存在浏览器中,而post不会

但本质上他们没有区别,只是get将head和data一起发送过去,而post先发送head建立连接,服务器返回100,然后再发送过去data,但firefox是一次全部发送过去。

86.如何实现跨域?

87.说一下 JSONP 实现原理?

88.什么是HTTPS?

HTTPS默认端口是443,HTTP是80

HTTPs采用SSL加密传输协议,而HTTP采用超文本传输协议。是明文传输

九、设计模式

88.说一下你熟悉的设计模式?

单例

代理

工厂

观察模式,又称订阅-发布模式,当一个对象发生变化,依赖他的对象会被通知并且自动更新

89.简单工厂和抽象工厂有什么区别?

十、Spring/Spring MVC

90.为什么要使用 spring?

方便解耦,方便对象的管理(创建和依赖关系都交给容器管理)

支持AOP可以很方便的对程序进行权限拦截和运行监控

声明式事务,不需要编程

能集成其他优秀框架

降低JAVAEEAPI使用难度

便于测试

91.解释一下什么是 aop?

意思是面向切面编程,就是将系统性的相关编程工作独立提取出来,独立编程,然后进入切面切入系统

从而避免业务逻辑中混入许多系统性逻辑-比如权限管理,事务管理,日志记录等

AOP分为静态AOP和动态AOP,静态AOP就是通过AspectJ,将切面代码直接编译到代码中

动态代理分为JDK的动态代理和cglib的动态代理

@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            /*
            重点是这里:如果被代理对象实现了接口,就使用JDK动态代理,否则使用Cglib动态代理
            */
            if (targetClass.isInterface()) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }
    final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {    
@Override
public Object getProxy(ClassLoader classLoader) {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
    }
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

91.spring的多例:多例是将scope设置为prototype,每次调用getBean的时候会new一个

92.解释一下什么是 ioc?

IOC是控制反转的意思就是控制反转,把对象和对象维护的关系转交给applicationContext.xml,不是程序本身控制了,而是交给spring容器控制了

93.spring 有哪些主要模块?

有核心容器 Spring Core

Web模块 Spring Web

MVC模块 Spring MVC

DAO模块

AOP

上下文模块Spring Context

94.spring 常用的注入方式有哪些?

注解注入 @Autowire


<bean id="userService" class="com.lyu.spring.service.impl.UserService">
    <constructor-arg name="userDao" ref="userDaoJdbc">constructor-arg>
    <constructor-arg name="user" ref="user">constructor-arg>
bean>

setter注入


<bean id="userService" class="com.lyu.spring.service.impl.UserService">
    
    
    
    <property name="userDao" ref="userDaoMyBatis">property>
bean>

构造注入

主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:

  1. @Component:可以用于注册所有bean
  2. @Repository:主要用于注册dao层的bean
  3. @Controller:主要用于注册控制层的bean
  4. @Service:主要用于注册服务层的bean

95.spring 中的 bean 是线程安全的吗?

Spring中的Bean默认是单例模式的,框架并没有对bean进行多线程的封装处理
实际上大部分时间Bean是无状态的(比如Dao) 所以说在某种程度上来说Bean其实是安全的
但是如果Bean是有状态的 那就需要开发人员自己来进行线程安全的保证,最简单的办法就是改变bean的作用域 把 "singleton"改为’‘protopyte’ 这样每次请求Bean就相当于是 new Bean() 这样就可以保证线程的安全了

有状态就是有数据存储功能
无状态就是不会保存数据

96.spring 支持几种 bean 的作用域?

四种

单例:single

多例:prototype

Request:每个请求产生一个,都将创建一个

Session:每个HTTP Session产生一个对象

globalSession:

spring中使用到的设计模式:

工场模式:BeanFactory

模板设计模式:解决大量重复代码

代理模式:AOP的动态代理

97.spring 自动装配 bean 有哪些方式?

在Spring使用中,在xml配置文件通过元素或元素的ref属性向bean注入另外的依赖bean

如果容器中存在多个类型相同的bean,spring提供了两种选择,设置一个首选bean,或者排除一些bean

元素的primary属性代表是否是首选bean,如果标注为true,那么该bean将成为首选bean。
但是spring默认每个bean的primary属性都是true,所以如果需要设置首选bean需要将那些非首选bean的primary属性标注为false。

98.spring 事务实现方式有哪些?

可以通过编程式实现,

声明式,在xml中声明,还可以注解形式,需要开启

99.说一下 spring 的事务隔离?

隔离级别:

读未提交:数据库不加锁,事务A写入后事务B立刻读,A回滚后造成脏读

读已提交:给事务加写锁

可重复读:加读锁

可串行化:强制事务排序,使其不能幻读,他给每个读的行上加上共享锁,造成大量超时和锁竞争

共享锁:在查询语句的时候,每读一行之前给这一行加锁,读完释放锁

并发性:当事务被放置共享锁的时候,还可以放其他共享锁或者更新锁

100.说一下 spring mvc 运行流程?

用户将请求发送给dispatcherServlet,然后前端控制器根据HandlerMapping找相对应的handler,然后返回调用链,然后dispatcherServlet通过HandlerAdopt调用Handler返回ModuleAndView

将ModuleAndView交给视图解析器,返回视图,前端控制器进行渲染,数据填充,返回给用户

101.spring mvc 有哪些组件?

DispatcherServlet

HandlerMapping

Controller

ModuleAndView 封装模型信息和视图信息6

ViewResolver 视图解析器

102.@RequestMapping 的作用是什么?

103.@Autowired 的作用是什么?

十一、Spring Boot/Spring Cloud

104.什么是 spring boot?

springboot是一个框架,一种全新的编程规范,产生简化了框架的使用,主要简化了大量繁琐配置文件,所以SpringBoot是一个服务于框架的框架,服务范围是简化配置文件

105.为什么要用 spring boot?

1.他能简化编码,比如创建一个web项目,spring需要添加许多依赖,而boot只需要添加一个start-web

2.简化配置,Spring使用xml,而boot只需要@configuration和@Bean

3.简化部署,Spring使用时候,需要将其在服务器上部署Tomcat,然后把项目打成war包扔到Tomcat中,而boot,不需要在服务器部署Tomcat,因为boot已经内嵌了Tomcat,只需要打成jar包,使用java -jar xxx.jar即可

4微服务架构,逐渐取代传统架构

106.spring boot 核心配置文件是什么?

107.spring boot 配置文件有哪几种类型?它们有什么区别?

108.spring boot 有哪些方式可以实现热部署?

spring-boot-devtools 和 Spring Loaded

109.jpa 和 hibernate 有什么区别?

十三、Mybatis

125.mybatis 中 #{}和 ${}的区别是什么?

126.mybatis 有几种分页方式?

127.RowBounds 是一次性查询全部结果吗?为什么?

128.mybatis 逻辑分页和物理分页的区别是什么?

129.mybatis 是否支持延迟加载?延迟加载的原理是什么?

130.说一下 mybatis 的一级缓存和二级缓存?

131.mybatis 和 hibernate 的区别有哪些?

132.mybatis 有哪些执行器(Executor)?

133.mybatis 分页插件的实现原理是什么?

134.mybatis 如何编写一个自定义插件?

十七、MySql

164.数据库的三范式是什么?

INF,原子性

2NF,消除部分依赖

3FN,消除传递依赖

1NF 当关系模式中属性不能再分解为更基本的数据单位时,称R是满足第一范式

第二范式:如果关系模式R满足第一范式,并且R的所有非主属性都完全依赖R的每一个候选关键属性,成R满足第二范式

165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

166.如何获取当前数据库版本?

167.说一下 ACID 是什么?

原子性:数据库的操作都是要么都完成,要不都不完成

一致性:事务操作成功后,数据库所处的状态和业务规则保持一致

持久性:事务一旦提交,永久性的更改数据

隔离性:一个事务在执行期间,对其他事务将不可见

168.char 和 varchar 的区别是什么?

char的长度不可变,而varchar长度可变

char如果没存满,去的时候需要trim方法去掉多余空格

char的存储方式对英文字母一个字节,而汉字两个字节,varchar对这两个都是两个字节

169.float 和 double 的区别是什么?

170.mysql 的内连接、左连接、右连接有什么区别?

内连接:将有关系的表中数据合并到一起进行查询

左连接,显示左边表全部信息,即使右边没有对应信息

171.mysql 索引是怎么实现的?

采用B+树的方式实现,B+树的高度是可控的,通常在3-5层

innorDB,他将整条数据存储到叶子节点,而不是存放地址

MyISAM和InnorDB区别

MyISAM支持全文索引,是表级锁,不支持事务,会保存行数

InnorDB5.6以后支持全文索引,是行级锁,支持事务,不会保存行数

索引也不是越多越好,一方面会占存储空间,另一方面写操作会变得很慢,通常对查询次数多,值比较多的列添加索引。

B+树的特点:

1.单节点能存储更多数据,使得磁盘IO次数减少

  1. 叶子节点链表相连接,便于范围查询
  2. 聚集索引中,叶子节点直接存放数据,非聚集节点,叶子节点存放地址

172.怎么验证 mysql 的索引是否满足需求?

使用explain 可以看到命中详情

173.说一下数据库的事务隔离?

读未提交

读已提交

可重复读

可序列化

174.说一下 mysql 常用的引擎?

innodb:对数据库提供了ACID事务支持,而且提供行锁,大幅度提高并发效率

还有外键的约束。

缺点:不支持全文类型的索引。没有保存行数的表,如果select * from table_name;会全表遍历

MyISAM:曾经是MySQL默认存储引擎,不支持事务,他的优势是处理速度快,占用空间小

175.说一下 mysql 的行锁和表锁?

行锁,具体到数据的哪一行,能更好支持并发,但会造成死锁

表锁,开销比较小,,一旦用户访问这个表其他用户不能访问。

176.说一下乐观锁和悲观锁?

乐观锁就是认为不会修改数据,所以每次不会加锁,只是验证一下在此期间别人有没有更新这个数据,

一般采用CAS,但是会有ABA问题,解决办法是加时间戳或者版本号

悲观锁认为每次都有人修改数据,所以每次都会加锁,,比如行锁,表锁,写锁

177.mysql 问题排查都有哪些手段?

开启慢查询

优化sql建立索引

178.如何做 mysql 的性能优化?

可以分区分表

对于大表,数据量在百万级以上,分区分表为了提高数据库效率,减少他的增删改查压力

当只要一条数据的时候使用limit 1

开启查询缓存,很多次相同查询被执行,这些结果将被缓存,后续再查询直接从缓存中找

为搜索字段建立索引

避免使用select *

为每张表设置id(目的为了做其主键)

尽可能的使用not null

拆分比较大的delete和insert,这两个操作都要锁表的,表被锁住其他操作进行不了

架构方面,不止使用一台机器,采用主从复制,主服务器负责写数据,复制功能MySQL会自带

十八、Redis

179.redis是什么?都有哪些使用场景?

是一个非关系型数据库,使用场景比如淘宝秒杀系统

180.redis 有哪些功能?

181.redis 和 memecache 有什么区别?

182.redis 为什么是单线程的?

183.什么是缓存穿透?怎么解决?

184.redis 支持的数据类型有哪些?

185.redis 支持的 java 客户端都有哪些?

186.jedis 和 redisson 有哪些区别?

187.怎么保证缓存和数据库数据的一致性?

188.redis 持久化有几种方式?

189.redis 怎么实现分布式锁?

190.redis 分布式锁有什么缺陷?

191.redis 如何做内存优化?

192.redis 淘汰策略有哪些?

193.redis 常见的性能问题有哪些?该如何解决?

十九、JVM

194.说一下 jvm 的主要组成部分?及其作用?

线程私有:虚拟机栈,本地方法栈,程序计数器

线程共享:堆区,全局数据区,方法区

虚拟机栈:虚拟机每执行一个方法,就会创建一个栈帧用于存放局部变量

195.说一下 jvm 运行时数据区?

存放字符串(1.7以后放在堆区),final修饰的常量,基本数据类型

196.说一下堆栈的区别?

堆一般存储的是java对象和数组

栈一般存储的是局部变量或者方法,后进先出

197.队列和栈是什么?有什么区别?

198.什么是双亲委派模型?

当Application ClassLoader收到一个类加载请求,他不会先去加载,而是去交给父加载器Ext classloader去加载,Ext收到后,会交给父加载器BootStrap加载器加载,如果没在java_home/lib中找到,会交给ext加载

如果ext也加载失败,则application ClassLoader加载,如果他也失败,就交给自定义类加载器

199.说一下类加载的执行过程?

过程:加载 链接 初始化 使用 卸载

连接包括: 验证 准备 解析

加载:加载将进行三个步骤

根据类的全限定名来获取此类的二进制字节流

根据二进制字节流把这个类的静态存储结构转换为方法区的运行时数据结构

在内存中生成一个代表此类的java.lang.Class文件,作为方法区这个类的各个数据访问入口。

验证:验证Class文件字节流包含的信息符合虚拟机要求。(文件头,字节码,元数据验证,符号引用验证)

准备:为各个变量赋初值

解析:将符号引用变为直接引用

初始化:根据程序赋值

200.怎么判断对象是否可以被回收?

根据可达性分析算法,如果引用到达不了,则可以被回收

什么可以作为GC ROOT?

虚拟机栈中的引用的对象

方法区中静态属性引用的对象

方法区中常量引用的对象

本地方法栈中引用的对象

201.java 中都有哪些引用类型?

强引用 等于Object obj = new Object();只要强引用还在,就不会被回收

软引用 内存不够前,会进行第二次回收,会把这些对象列入回收范围进行第二次回收

弱引用 下次回收会被回收

虚引用 强度最弱,他的存在只是为了回收前进行通知

202.说一下 jvm 有哪些垃圾回收算法?

复制算法

标记-清除算法

标记-整理:成本比标记-清除算法成本高,但解决了内存碎片的问题

分代收集算法:目前大部分JVM采用此算法

203.说一下 jvm 有哪些垃圾回收器?

204.详细介绍一下 CMS 垃圾回收器?

CMS收集器是老年代并发收集器 以获得最短停顿时间为目标的收集器

CMS基于标记-清楚-算法

过程:初始标记-并发标记-重新标记- 并发清除

205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

206.简述分代垃圾回收器是怎么工作的?

GC分为两种:Scavenge GC 和Full GC

Scavenge GC是新对象在Eden去申请空间失败,触发Scavenge GC

FULL GC:条件:

老年带被写满

持久带被写满

System.gc()被代码调用(可能触发)

207.说一下 jvm 调优的工具?

jdk自带的jconsole

jps主要用来输出JVM中运行的进程状态信息。语法格式如下:

jps [options] [hostid]

jstack主要查看堆栈信息

208.常用的 jvm 调优的参数都有哪些?

你可能感兴趣的:(Java基础)