网站首页   文章专栏   Java基础总结
Java基础总结
原创 2020-02-16 18:05 ApeNixX 347浏览 Java

JavaSE 面试题

Java中的基本类型?

基本类型又分为四大类:
  1. 整型 byte->short->int->long 其字节长度: 1个字节->2个字节->4个字节->8个字节
  2. 浮点型 float->double 其字节长度: 8个字节->8个字节
  3. 字符型 char 其字节长度: 2个字节
  4. 布尔型 Boolean 其字节长度: 1个字节

Java中四种引用类型?

  1. 强引用: 即使内存不够,jvm即使抛出异常,也不会进行垃圾回收
  2. 软引用: 当内存足够时,不会被垃圾回收,当内存不足时,会进行垃圾回收
  3. 弱引用: 无论内存是否足够,都会进行垃圾回收
  4. 虚引用: 在任何时刻都有可能被垃圾回收

throw和throws的区别?

  1. throw: 写在方法体中,throw后面跟的是具体异常实例
  2. throws: 写在方法的后面,后面跟的是异常类,异常类可以出现多个

error和Exception区别?

  1. Error: 表示的是系统的错误,不能通过程序来进行错误处理
  2. Exception: 表示异常可以通过程序来捕获,或者优化程序来避免

Java中的类型转换?

隐式转换: 低级数据类型可以自动转换为高级数据类型 显示转换: 高级数据类型转换为低级数据类型

“==” ,equals 和 hashCode() 区别?

  1. “==”: 如果基本数据类型之间使用”==”比较的话,比较的是他们的值是否相等;如果是引用类型之间比较的话,比较的是Java虚拟机栈中的引用地址是否相等,但不能够比较这两个对象的内容是否相等
  2. equals: 用于引用类型之间比较,比较的是这两个对象的内容是否相等
  3. hashCode: 比较两个对象是否相等 一般比较对象的话,首先先会用hashCode比较这个对象是否相等,然后再用equals方法比较这两个对象的值是否相等

String,StringBuffer和StringBuilder区别?

  1. String: 不可变类,当String对象一旦创建下,其值不可变,底层采用char数组实现,并且用关键字final修饰,线程不安全,会产生无用的对象
  2. StringBuffer: 线程安全的,可变类,初始化时只能使用构造方法初始化,用在多线程环境下
  3. StringBuilder: 线程不安全,可变类,用在单线程环境下

为什么使用Long时,大家推荐使用ValueOf方法,少使用parseLong方法?

因为Long本身有缓存机制,缓存了-128到127范围内的LongvalueOf方法会从缓存中去拿值,如果命中缓存,会减少资源的开销,parseLong方法没有这个功能

length和length()的区别

  1. length: 表示数组的长度
  2. length(): 表示字符串的长度

static 关键字

static可以修饰类,变量,代码块

  1. 被static修饰的类为静态类
  2. 被static修饰的变量为静态变量
  3. 被static修饰的代码块为静态代码块

抽象类和接口的区别

如果一个类中包含抽象方法,那么这个类就是抽象类。

  1. 抽象类有构造方法,接口没有构造方法
  2. 抽象类只能单继承,接口可以多继承
  3. 抽象类中的方法可以有普通方法,接口中的方法都是抽象方法
  4. 接口中的熟悉都是public static final修饰的,而抽象方法不是

继承和多态

  1. 继承: 子类继承父类的抽象方法,使用父类的一些成员变量与方法,从而提高代码的复用性,提高开发xiaolv。
  2. 多态: 它表示同一个操作作用在不同对象时,会有不同的定义,从而产生不同的结果

final,finalize() 和 finally的区别

  1. final 关键字,被其修饰的类或方法,其不可继承
  2. finalize() 是Object类的一个方法,主要由JVM进行调用用于对对象进行垃圾回收。
  3. finally 用于标记代码块,不论try{}中的的代码执行是否完成,都会执行finally中的代码

线程与进程的区别

  1. 进程是操作系统分配资源的最小单元,线程是程序执行的的最小单元
  2. 一个进程至少由一个线程,线程之前的信息共享,而进程之间的数据不共享

值传递和引用传递

  1. 值传递: 在方法调用中,实参把值传递给形参时,形参根据实参的值初始化一个临时存储单元,所以即使实参和形参的值相同,但是他们的存储单元不同,所以形参的值的修改无法影响到实参的值。 — 基本类型的传递为值传递
  2. 引用传递:在方法调用中,实参把对象传递给形参,这时候形参和实参的地址所指向同一个存储单元,所以对形参的修改直接影响实参的值 — 包装类型传递为引用传递

并发锁相关面试题

Lock与synchronized区别?

  1. lock是接口,而synchronized是Java的一个关键字
  2. lock在发生异常的时候需要抛出,而synchronized会自动释放锁
  3. lock可以通过trylock来知道是否获取锁,而synchronized不能

Synchronized类锁和对象锁?

对象锁作用的是synchronized修饰的非静态方法,或者是同步方法块中的this对象和非this对象。 类锁作用于synchronized修饰的静态方法,或者同步方法块中的类.class 类锁和对象锁是异步执行的。 类的实例对象可以有多个,但是每个类只有一个class类型的对象

什么是线程池?

线程池主要为了突然爆发的线程而设计的,它是通过几个核心的线程来为其提供服务的,它主要是减少创建和销毁线程所需的时间,提高运行效率。

Java中常见的线程池

  1. newCachedThreadPool : 无界可缓存线程池,当新增一个任务时,它会创建一个线程,会回收空闲线程
  2. newFixedThreadPool: 固定线程池, 核心线程书和最大线程数一样,每新增一个任务,都会创建一个线程,知道线程数达到最大线程数,就会保持不变
  3. newScheduledThreadPool: 定时线程池,定时及周期性任务执行
  4. newSingleThreadExcutor: 单线程线程池,核心线程数和最大线程数都为1

线程池实现原理

当新增一个任务时,首先会判断当前线程数量是否大于核心线程数量,如果小于,则直接创建线程执行任务;如果大于,则帕努但当前线程数量是否大于任务缓存队列,如果小于,则添加到缓存队列中,如果大于,则判断当前线程数量和最大线程数量比较,如果小于,直接创建一个非核心线程数执行任务,否则,抛出异常。

锁的种类

  1. 乐观锁: 认为每一次操作都不会修改数据,一般用版本号控制
  2. 悲观锁: 认为每次操作都会修改数据,所以在每次操作时都加上锁,保证只允许一个线程进行操作
  3. 重入锁: 重入锁也叫递归锁,指同一个线程外层函数获取锁之后,内存函数仍然可以获取锁 (Synchronized, ReentrantLock)
  4. 读写锁: 也可以理解为分为两锁(这是我自创的说法),一个是读锁,一个写锁;两个线程同时读取一个资源的话,可以获取;但是如果一个线程修改一个资源的话,那么其他线程不能对该资源进行操作
  5. CAS: 无锁机制,他也是一种乐观锁,核心有三个参数,一个是待修改的值,一个是期望值,一个是新值,首先,想要修改数据时,会先判断待修改的值与期望值是否相等,如果相等的话,说明没有其他线程对该资源进行操作,否则的话,说明该数据已经被其他线程修改过,则不修改。
  6. 分布式锁: 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行

如何保证多线程工作时变量的一致性?

  1. 在共享变量上添加关键字volitle,保证多线程下共享变量的一致性
  2. 添加synchronized关键字

volitle的实现原理

当一个线程对共享变量做操作时,会立即同步到主内存中,另外线程从主存中直接获取最新值

volitle和synchronized区别?

volitle只保证可见性,而sybchronized既保证原子性,又保证可见性

ThreadLocal如何解决共享变量一致性?

ThreadLocal会给每一个线程创建一个共享变量副本,每一个线程都有自己的一个副本,都可对其进行操作,不影响其他线程的副本

对比ThreadLocal和Synchronized区别?

  1. ThreadLocal和Synchronized保证共享变量在高并发下数据的一致性
  2. TheadLocak为每一个线程创建一个共享变量副本,来进而保证在高并发情况下其数据一致性
  3. Sunchronized基于锁来实现高并发情况下其数据一致性

Java内存模型

Java内存模型,也可称为共享变量内存模型,一个线程对共享变量操作时,首先会更新到本地内存中,然后再刷新到主内存中,另一个线程从主内存中获取最新数据

死锁

线程A等待线程B的资源,而线程B等待线程A的资源,导致死锁,若无外力,则保持不变

什么情况下会使用多线程?

  1. 对用户来说,不是那么重要的,比如说用户下单成功后,用户只需要知道自己是否成功,现阶段不会关心自己的积分多少,这样的话可以把新增积分业务异步执行,快速响应客户单
  2. 耗时长的业务逻辑

Spring面试题

SpringIoc原理

SpringIoc是一个设计模式,控制反转,指的是以前创建对象的控制权在自己手上,现在交由spring容器来管理对象。让对象更加专注业务逻辑,而无须担心对象是否创建。 举个例子,假如要完成一个业务需求,需要两个或两个以上的对象共同合作才可完成,用传统的方式的话,对象A会创建和它合作的对象,相当于合作对象的创建世纪都把握在自己的手里,耦合度高,如果使用spring的话,spring创建好对象B,然后将其存放到一个容器中,当对象A需要对象B来和合作完成一个需求时,spring会从容器中拿出来给对象A,对象A无须关系对象B是什么时候创建的,只需要关心和对象B合作完成需求即可。

SpringAop原理

SpringAop,面向切面编程,对方法进行增强。使用AOP可以实现日志记录,权限控制等。它有两种实现方式,一种是JDK动态代理,一种是CGLib动态代理。 JDK动态代理

  1. 通过实现InvocationHandler接口创建自己的调用处理器,
  2. 通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理
  3. 通过反射机制获取动态代理类的构造方法,其唯一参数类型就是调用处理器接口类型
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入;
  5. JDK动态代理是面向接口的代理模式,如果代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。

**CGLib动态代理: ** CGLib是一个强大,高性能的Code生产类库,可以实现运行期间动态扩展Java类,spring在运行期间通过CGLib继承要被动态代理的类,重写父类的方法,实现AOP面向切面编程。

Spring的事务传播机制

  1. PROPAGATION_REQUIRED: 如果当前没有事务,就新建一个事务,如果已经存在一个事务,就加入到该事务中。
  2. PROPAGATION_SUPPORTS: 支持当前事务,如果当前没有事务,就以非事务方式执行。
  3. PROPAGATION_MONDATORY: 使用当前事务,如果当前没有事务,就抛出异常
  4. PROPAGATION_REQUIRED_NEW:新建事务,如果当前存在事务,挂起该事务。
  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作。如果当前存在事务,就把当前事务挂起。
  6. PROPAGATION_NEVER: 以非事务方式执行,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED: 如果当前存在事务,则在嵌套事务内执行。

SpringMVC启动流程

  1. SpringMVC将所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作。
  2. DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的controller
  3. DispatcherServlet将请求提交到目标Controller
  4. Controller进行业务逻辑处理后,会返回一个ModelAndView
  5. DispatcherServlet查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
  6. 视图对象负责渲染返回客户端

版权声明:本文由ApeNixX原创出品,转载请注明出处!

本文链接:https://www.apenixx.top/article/details/1581847546


  面试    Java基础 

赞助本站,网站的发展离不开你们的支持!
来说两句吧
最新评论
  • 不落阁
    不落阁
    我为大家做了模拟留言与回复!试试吧!

    Absolutely
    Absolutely这是用户回复内容

    2017-03-18 18:26回复

    Absolutely
    Absolutely 回复 不落阁这是第二个用户回复内容

    2017-03-18 18:26回复