面试题

1.jdk 和 jre 有什么区别?

jre 是 java 的运行环境, jdk 包含 jre 除此之外还具有java的相关jar包

JRE:Java Runtime Environment(java运行时环境)。即java程序的运行时环境,包含了java虚拟机,java基础类库。

JDK:Java Development Kit(java开发工具包)。即java语言编写的程序所需的开发工具包。

? JDK包含了JRE,同时还包括java源码的编译器javac、监控工具jconsole、分析工具jvisualvm等。

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

‘==‘ 表示 判断变量的值是否相等

equals 表示 变量所代表的字符串是否相等

什么是==?
== 等于比较运算符,如果进行比较的两个操作数都是数值类型,即使他们的数据类型不相同,只要他们的值相等,也都将返回true.如果两个操作数都是引用类型,那么只有当两个引用变量的类型具有父子关系时才可以比较,而且这两个引用必须指向同一个对象,才会返回true.(在这里我们可以理解成==比较的是两个变量的内存地址)
什么是equals()?
equals()方法是Object类的方法,在Object类中的equals()方法体内实际上返回的就是使用==进行比较的结果.但是我们知道所有的类都继承Object,而且Object中的equals()方法没有使用final关键字修饰,那么当我们使用equal()方法进行比较的时候,我们需要关注的就是这个类有没有重写Object中的equals()方法.
== 是java提供的等于比较运算符,用来比较两个变量指向的内存地址是否相同.而equals()是Object提供的一个方法.Object中equals()方法的默认实现就是返回两个对象==的比较结果.但是equals()可以被重写,所以我们在具体使用的时候需要关注equals()方法有没有被重写.

赋值方式中如果调用了new关键字,一定会在内存中给你分配一个新的地址
给Integer类型赋值的时候,如果没有调用new关键字,并且值在-128与+127之间,包括-128和+127,那么指向的都是同一个内存位置.
Integer类中重写了equals()方法,使用equals()方法进行比较的时候,实际上比较的内存中最终指向的值的内存位置,不是直接比较变量的内存位置.

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

不对,hashCode()返回的是一个int值,虽然几率很小但存在相同的可能性或者重写方法的hashCode()会造成hashCode()相等但是 对象不等的情况

两个对象==,其哈希码一定相等

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

修饰符,可以修饰变量,效果是使其无法被改变,常量化

(1)修饰类:表示该类不能被继承;

(2)修饰方法:表示方法不能被重写;

(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

  • 当final修饰的是一个基本数据类型数据时, 这个数据的值在初始化后将不能被改变; 当final修饰的是一个引用类型数据时,
  • 也就是修饰一个对象时, 引用在初始化后将永远指向一个内存地址, 不可修改. 但是该内存地址中保存的对象信息, 是可以进行修改的.

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

-1

  • ceil的英文意义是天花板,该方法就表示向上取整,math.ceil(11.3)的结果为12,math.ceil(-11.6)的结果为-11;
  • floor的英文是地板,该方法就表示向下取整,math.floor(11.6)的结果是11,math.floor(-11.4)的结果-12;
  • 最难掌握的是round方法,他表示“四舍五入”,算法为math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,math.round(11.5)的结果是12,math.round(-11.5)的结果为-11.

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

String是引用类型

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

String

StringBuilder: 相比于String 提供的方法更多,更便利

StringBuffer: 相比StringBuilder 线程更安全,其他与StringBuilder基本一样

从类的继承关系上来开的话,String和StringBuffer,StringBuilder是没有任何关系的但是StringBuffer和StringBuilder的继承关系时一样的.

本质都是一个char类型数组不同的是String类型的数组长度是3,而另外两个数组的长度都是19且默认值为0.

能装下的话什么都不做,不能装下的话会使用Arrays.copyOf()方法将现有的char[]数组赋值到新的char数组中

追加的方法实际上都是调用父类的追加方法,但是StringBuffer类中多了一行toStringCache = null;的代码,其中toStringCache是一个char[];这个属性在重写toString()方法中使用了

java中操作字符串的类,我知道的有三个类,分别是String,StringBuffer和StringBuilder.这三个类都是以char[]的形式保存的字符串,但是String类型的字符串是不可变的,对String类型的字符床做修改操作都是相当于重新创建对象.而对StringBuffer和StringBuilder进行增删操作都是对同一个对象做操作.StringBuffer中的方法大部分都使用synchronized关键字修饰,所以StringBuffer是线程安全的,StringBuilder中的方法则没有,线程不安全,但是StringBuilder因为没有使用使用synchronized关键字修饰,所以性能更高,在单线程环境下我会选择使用StringBuilder,多线程环境下使用StringBuffer.如果声明的这个字符串几乎不做修改操作,那么我就直接使用String,因为不调用new关键字声明String类型的变量的话它不会在堆内存中创建对象,直接指向String的常量池,并且可以复用.效率更高

9. 如何将字符串反转?

二分递归地将后面的字符和前面的字符连接起来

取得当前字符并和之前的字符append起来

将字符从后往前的append起来

和StringBuffer()一样,都用了Java自实现的方法,使用位移来实现

使用异或交换字符串

基于栈先进后出的原理

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

面试题

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

被Abstract修饰词修饰的类被称为抽象类,抽象类不一定有抽象方法,但由抽象方法的类一定是抽象类

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

普通类: 没有抽象方法,可以直接被继承,可以被实例化

抽象类: 被Abstract修饰的类,里面可以存在抽象方法,当被继承时,必须要重写里面的抽象方法(因此,抽象类方法不能被final修饰),抽象类无法被实例化(但能通过多态的方式去实例化),抽象发方法不能被修饰为静态

  • 什么时候使用抽象类和接口

    • 默认实现的方法

    • 想要多重继承的时候

      • 例子: 假如有一个接口,五个实现类,现在的需求可能要往接口加一个方法,这样就要改动五个实现类,但需求只需要改动其中两个实现类,可以再定义一个抽象类去实现这个接口,在抽象类中新增这个方法,然后其他两个实现类实现这个抽象类就好了,或者使用 Java 8 中的新特性,在接口中新增默认方法或者静态方法。

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

抽象类的就是要子类继承然后实现内部方法的。但是final修饰的类是不能再被继承和修改的。所以不能用final修饰。

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

抽象类: 是类,被Abstrac修饰 ,可以存在普通方法和抽象方法和普通类一样只能被单继承

接口: 不是类,被interface 修饰 ,里面的方法默认被abstract 和 public 修饰 (因此所有的方法都是静态方法,但JDK8以后,可以有default和static修饰的普通方法),接口可以被多继承,没有构造器,修饰符必须时public

15.java 中 IO 流分为几种?

4种: 字节输入/输出流; 字符输入/输出流

  • 按照流的流向分,可以分为输入流和输出流;

  • 按照操作单元划分,可以划分为字节流和字符流;

  • 按照流的角色划分为节点流和处理流。

  • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。

  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

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

  • BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的
  • NIO (New I/O): NIO是一种同步非阻塞的I/O模型,它支持面向缓冲的,基于通道的I/O操作方法。对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发
  • AIO (Asynchronous I/O): AIO 也就是 NIO 2。它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作.

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

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

18. java 容器都有哪些?

java容器类类库的用途是"保存对象"。

Java容器:数组,String,java.util下的集合容器

数组长度限制为 Integer.Integer.MAX_VALUE;

String的长度限制: 底层是char 数组 长度 Integer.MAX_VALUE 线程安全的

面试题

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

Set:无序,元素不可重复

Map:无序,元素可重复

Java 容器分为 Collection 和 Map 两大类

Collection: 存放独立元素的序列。

Map:存放key-value型的元素对

  • Collection

  • List

    • ArrayList
    • LinkedList
    • Vector
    • Stack
  • Set

    • HashSet
    • LinkedHashSet
    • TreeSet
  • Map

  • HashMap

    • LinkedHashMap
  • TreeMap

  • ConcurrentHashMap

  • Hashtable

19.Collection 和 Collections 有什么区别?

Collection是一个接口,它是Set、List等容器的父接口;Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。

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

Set: 无序,不可重复

Map: 无序,可重复

List:列表形式存储,元素可重复

21. HashMap 和 Hashtable 有什么区别?

  • 存储:HashMap 运行 key 和 value 为 null,而 Hashtable 不允许。
    • HashMap 无论主键还是值都可以存放null
    • 只不过主键要求唯一 所以只能有一个null
    • Hashtable 对null"零容忍",无论主键还是值 只要有null出现直接就空指针
  • 线程安全:Hashtable 是线程安全的,而 HashMap 是非线程安全的。
  • 推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。

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

TreeMap<K,V>的Key值是要求实现java.lang.Comparable,所以迭代的时候TreeMap默认是按照Key值升序排序的;TreeMap的实现是基于红黑树结构。适用于按自然顺序或自定义顺序遍历键(key)。

HashMap<K,V>的Key值实现散列hashCode(),分布是散列的、均匀的,不支持排序;数据结构主要是桶(数组),链表或红黑树。适用于在Map中插入、删除和定位元素。

如果你需要得到一个有序的结果时就应该使用TreeMap(因为HashMap中元素的排列顺序是不固定的)。除此之外,由于HashMap有更好的性能,所以大多不需要排序的时候我们会使用HashMap,简单来说,需要排序就用TreeMap,不需排序则使用 HashMap。

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

HashMap底层是链表结构,

  • HashMap 基于 Hash 算法实现
  • HashMap 是 <k,v> 结构, 会根据 k 再通过 hash(Object key) 计算出 hash 值 ,根据 hash 值将value 保存再 Node 对象里, Node 对象保存在数组
    • 当 hash 值相同时, 出现 hash 碰撞, HashMap 做法是 利用链表红黑树(JDK8以后)存储相同的 hash 值的value
    • 当 hash 冲突的个数:小于等于 8 使用链表;大于 8 且 tab length 大于等于 64 时,使用红黑树解决链表查询慢的问题

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

  • ArrayList: 底层是数组结构, 在大数据时, 查询相对较快, 增删改 比较慢
  • LinkedList: 底层是链表结构, 在大数据时, 进行增删改比较快, 查询效率较低

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

  • 安全的线程: Vector. Stack. Hashtable.ConcurrentHashMap
  • 不安全的线程: LinkedList, ArrarLinst, HashSet, HashMap,TreeSet, TreeMap

31. 迭代器 Iterator 是什么?

迭代器是一种检查容器内元素并且遍历的轻量级数据类型,无需知道对象的底层实现

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

并发,指的是多个事情,在同一时间段内同时发生了

并行,指的是多个事情,在同一时间点上同时发生了(只有在多CPU的情况中,才会发生并行)

37. 守护线程是什么?

服务线程,准确地来说就是服务其他的线程,比如垃圾回收线程

40.线程有哪些状态?

创建,初始化,待运行,运行中,销毁

New, Runnable, Blocked, Waiting, Timed_Waiting, Terminated

创建, 可运行, 阻塞, 消亡

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

sleep(): 线程停止一段时间,到时间后开始运行

wait(): 线程休眠,不被唤醒就一直休眠

1、sleep是线程中的方法,但是wait是Object中的方法。

2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。

3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。

4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。

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

Executors目前提供了5种不同的线程池创建配置:

  • newCachedThreadPool(),它是用来处理大量短时间工作任务的线程池
  • newFixedThreadPool(int nThreads),重用指定数目(nThreads)的线程
  • newSingleThreadExecutor(),它的特点在于工作线程数目限制为1
  • newSingleThreadScheduledExecutor()和newScheduledThreadPool(int corePoolSize),创建的是个ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程
  • newWorkStealingPool(int parallelism),这是一个经常被人忽略的线程池,Java 8 才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序

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

会执行, 会优先执行finally内的代码块再去执行catch中的代码

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

(1)NullPointerException 当应用程序试图访问空对象时,则抛出该异常。
(2)SQLException 提供关于数据库访问错误或其他错误信息的异常。
(3)IndexOutOfBoundsException指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
(4)NumberFormatException当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
(5)FileNotFoundException当试图打开指定路径名表示的文件失败时,抛出此异常。
(6)IOException当发生某种I/O异常时,抛出此异常。此类是失败或中断的I/O操作生成的异常的通用类。
(7)ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。
(8)ArrayStoreException试图将错误类型的对象存储到一个对象数组时抛出的异常。
(9)IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
(10)ArithmeticException当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
(11)NegativeArraySizeException如果应用程序试图创建大小为负的数组,则抛出该异常。
(12)NoSuchMethodException无法找到某一特定方法时,抛出该异常。
(13)SecurityException由安全管理器抛出的异常,指示存在安全侵犯。
(14)UnsupportedOperationException当不支持请求的操作时,抛出该异常。
(15)RuntimeExceptionRuntimeException 是那些可能在Java虚拟机正常运行期间抛出的异常的超类。

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

(Spring框架中)单例设计模式: 就是一个应用程序中,某个类的实例对象只有一个,你没有办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取他们的实例

  • 减少了新生成实例的消耗

  • 减少JVM垃圾回收 由于不会每个请求都生成新的bean实例,回收的对象自然少了

  • [ ] 他不能做到线程安全,在并发场景下可能出现问题

工厂方法模式: 自己不再主动创建对象,而是让工厂来帮我们创建对象。定义一个IFactory,其他接口通过实现这个IFactory,我们直接通过接口的实现来实例化这个工厂

  • 良好的封装性,代码结构清晰,调用者不用关系具体的实现过程,只需要提供对应的产品类名称即可
  • 易扩展性,在增加产品类的情况下,只需要适当的修改工厂类逻辑或者重新拓展一个工厂类即可
  • 屏蔽了产品类,产品类的变化调用者不用关心。需要改动一个驱动的名称,数据库就会从Mysql切换到Oracle,极其灵活

springIOC即控制反转,将创建对象的权力交给spring容器来管理当,当spring容器在启动时,会扫描配置文件中的所有bean标签,一句bean标签里的class的属性通过反射创建出来对象(单例),并将创建好的对象放在线程安全的ConcurrentHashMap中, map的key值就是bean标签里的id的属性值,value值就是通过反射创建出来的对象,所有我们可以通过getBean() 方法来获取对象

91. 解释一下什么是 aop?

面向切面编程

使用切面编程,可以将一些系统性的代码提取出来,独立实现,与核心业务代码剥离,比如权限管理、事务管理、日志记录等等

Spring的AOP为动态AOP

92.解释一下什么是 ioc?

控制反转

一种设计思想

IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建

因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转

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

  • 构造方法,采用反射的方式,通过构造方法来完成注入
    • 注册
      • 在spring的配置文件中注册UserService,将UserDaoJdbc通过constructor-arg标签注入到UserService的某个有参数的构造方法
    • 注入
      • 如果只有一个有参数的构造方法并且参数类型与注入的bean的类型匹配,那就会注入到该构造方法中。
      • 如果有多个有参数的构造方法并且每个构造方法的参数列表里面都有要注入的属性会注入到只有一个参数的构造方法中,并且经过测试注入哪一个构造方法与构造方法的顺序无关
      • 哪个构造方法在前就注入哪一个,这种情况下就与构造方法顺序有关。(参数相同)
  • setter,也是采用反射的方式,不过是通过setter来完成注入
    • 如果通过set方法注入属性,那么spring会通过默认的空参构造方法来实例化对象,所以如果在类中写了一个带有参数的构造方法,一定要把空参数的构造方法写上,否则spring没有办法实例化对象,导致报错
  • 基于注解,常用的有“@Autowried”和“@Resource”
    • 注册bean
      • @Component:可以用于注册所有bean
      • @Repository:主要用于注册dao层的bean
      • @Controller:主要用于注册控制层的bean
      • @Service:主要用于注册服务层的bean
    • 注入bean
      • @Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。
      • @Autowired:spring注解,默认是以byType的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byName的方式去查找,

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

Spring容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但是具体情况还是要结合Bean的作用域来讨论。

  • 对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。
  • 对于singleton作用域的Bean,所有的线程都共享一个单例实例的Bean,因此是存在线程安全问题的
    • 但是如果单例Bean是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的比如Controller类、Service类和Dao等,这些Bean大多是无状态的,只关注于方法本身。
    • 有状态Bean(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。
      • 解决办法就是将有状态的bean的作用域由“singleton”改为“prototype”。
      • 采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本,不同线程只操作自己线程的副本变量

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

@Scope("xxxx")改变@Bean的作用域,

  • singleton:单例模式,在整个Spring IoC容器中,使用 singleton 定义的 bean 只有一个实例
  • prototype:原型模式,每次通过容器的getbean方法获取 prototype 定义的 bean 时,都产生一个新的 bean 实例

只有在 Web 应用中使用Spring时,request、session、global-session 作用域才有效

  • request:对于每次 HTTP 请求,使用 request 定义的 bean 都将产生一个新实例,即每次 HTTP 请求将会产生不同的 bean 实例。
  • session:同一个 Session 共享一个 bean 实例。
  • global-session:同 session 作用域不同的是,所有的Session共享一个Bean实例。

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

  • no:默认方式,手动装配方式,需要通过ref设定bean的依赖关系
  • byName:根据bean的名字进行装配,当一个bean的名称和其他bean的属性一致,则自动装配
    • autowire="byName"
  • byType:根据bean的类型进行装配,当一个bean的属性类型与其他bean的属性的数据类型一致,则自动装配
    • autowire="byType"
  • constructor:根据构造器进行装配,与 byType 类似,如果bean的构造器有与其他bean类型相同的属性,则进行自动装配
  • autodetect:如果有默认构造器,则以constructor方式进行装配,否则以byType方式进行装配(spring3.0以后不使用)
  • 使用注解自动装配
    • @Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。
    • @Autowired:spring注解,默认是以byType的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byName的方式去查找,

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

  • 编程式事务管理,在代码中调用 commit()、rollback()等事务管理相关的方法
  • 基于 TransactionProxyFactoryBean 的声明式事务管理
  • 基于注解 @Transactional 的声明式事务管理
  • 基于 Aspectj AOP 配置(注解)事务

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

  1. 用户发出请求,DispatcherServlet(前端控制器)接收并拦截请求
  2. 找到处理器映射 HandlerMapping 解析请求对应的 Handler
  3. HandlerAdapter(处理适配器) 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑
  4. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
  5. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
  6. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名
  7. 视图解析器将解析的逻辑视图名传给DispatcherServlet
  8. 前端控制器 DispatcherServlet 渲染数据(Moder)
  9. 将得到视图对象返回给用户

面试题

上一篇:windows2003远程桌面退出后系统自动注销的解决方法


下一篇:WIndows Server Backup 安装