无声specialweek

面试题

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 类的常用方法都有那些?

image-20210803084221385

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 线程安全的

img

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 常用的注入方式有哪些?

  • 构造方法,采用反射的方式,通过构造方法来完成注入
  • 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 事务实现方式有哪些?

Spring事务管理基于底层数据库本身的事务处理机制

  1. 原子性(Atomicity)
  2. 一致性(Consistency)
  3. 隔离性(Isolation)
  4. 持久性(Durability)
  • 编程式事务管理,在代码中调用 commit()、rollback()等事务管理相关的方法(编程式事务在实际开发中得不到广泛使用)
  • 基于 TransactionProxyFactoryBean 的声明式事务管理
  • 基于注解 @Transactional 的声明式事务管理
  • 基于 Aspectj AOP 配置(注解)事务

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

image-20210713152739631

  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. 将得到视图对象返回给用户

posted on 2021-08-09 19:34  无声specialweek  阅读(43)  评论(0编辑  收藏  举报

导航