乐趣区

关于java:java基础面试我只看这篇

前言

熬夜整顿了一份 java 根底面试题,心愿大家反对,如果文中有谬误心愿大家斧正;

公众号:常识追寻者

常识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;)

一 java 根底面试

1.1 面向对象和面向过程的区别

  • 面向过程:

长处:性能比面向对象高,因为类调用时须要实例化,开销比拟大,比拟耗费 资源

利用场景:单片机、嵌入式开发、Linux/Unix;

毛病:没有面向对象易保护、易复用、易扩大

  • 面向对象

长处:因为面向对象有封装、继承、多态性的特 性,能够设计出低耦合的零碎,故易保护、易复用、易扩大;

利用场景:网页开发,后盾开发等;

毛病:性能比面向过程低

1.2 面向对象的个性

  • 封装:将一个对象的属性私有化,并提供一个对外拜访的办法;
  • 继承:在已有类的根底上建设新类;提供继承信息的类被称为父类(超类、基类);失去继 承信息的类被称为子类(派生类)
  • 多态:一个对象的多种体现状态;用同样的对象援用调用同样的办法然而做了不同的事件;能够向上转型和向下转型

多态实现模式:

重写:子类对父类办法的重写;

笼罩:实现接口,并笼罩办法;

1.3 形象

形象是指将对象形象为具体类的过程;形象只关注对象有哪些属性和行为(办法);

1.4 Java 语言特点

  1. 简略易学;
  2. 面向对象(封装,继承,多态);
  3. 跨平台(Java 虚拟机实现平台无关性);
  4. 可靠性;
  5. 安全性;
  6. 反对多线程
  7. 反对编译与解释;
  8. 反对网络编程

1.5 JDK,JRE,JVM 之间的区别

JDK:java 开发工具包;蕴含 JRE, javac 等调优诊断工具;可能创立和编译程序;

JRE:java 运行环境;包含 Java 虚拟机(JVM),Java 类库,java 命令和其余的一些根底构件;不能创立程序;

JVM:java 虚拟机,提供运行字节码文件 (.class) 的环境反对;

jdk 蕴含 jre ; jre 蕴含 jvm

1.6 面向对象五大根本准则

  • 繁多职责准则 SRP(Single Responsibility Principle);设计类时要性能繁多;
  • 凋谢关闭准则 OCP(Open-Close Principle);一个模块对于拓展是凋谢的,对于批改是关闭;
  • 里式替换准则 LSP(the Liskov Substitution Principle LSP);子类能够替换父类;
  • 依赖倒置准则 DIP(the Dependency Inversion Principle DIP);高层次的模块不应该依赖于低层次的模块,他们都应该依赖于形象。形象不应该依赖于具体实现,具体实现应该依赖于形象;
  • 接口拆散准则 ISP(the Interface Segregation Principle ISP);设计类时,性能接口拆分为多个;

开发设计类时需思考的事件,面试中如果碰见能答几个就几个;

1.7 什么是 java 主类

java 主类是 java 代码运行的入口,即蕴含 main 办法的类;

1.8 结构器是否被重写

子类无奈继承父类的结构器,所以结构器不能被重写(overidde),但能够被重载(overload);

1.9 重载和重写的区别

重写:

  • 产生在父类与子类之间
  • 办法名,参数列表,必须雷同,返回值小于等于父类;
  • 拜访修饰符大于等于父类(public>protected>default>private);父类办法为 private,则无奈重写;
  • 重抛出异样的范畴要小于等于父类异样;

重载

  • 产生在同一个类中
  • 办法名雷同参数列表不同(参数类型不同、个数不同、程序不同);
  • 办法返回值和拜访修饰符能够不同;

1.10 equals 与 == 的区别

==:断定是否是雷同一个对象,比拟的是变量 (栈) 内存中寄存的对象的 (堆) 内存地址,用来判断两个对象的地址是否雷同,;

equals: equals 用来比拟的是两个对象的内容是否相等; 但 Object 中的 equals 办法返回的却是 == 的判断

1.11 什么是 hashCode

hashCode() 的作用是获取哈希码,也称为散列码;它实际上一个 int 整数;哈希码的作用是确定该对象在哈希表中的索引地位;散列表存储的是键值对(key-value),即能依据键获取值;

当一个对象插入散列表时先会比拟对象与散列表中已有的对象 hash 值,若不同,则直接插入散列表,若雷同(hash 碰撞),则会调用 equals 办法查看是否真的雷同, 如果 equal()判断不相等,间接将该元素放入汇合中,否则不放入;

对象中 hashCode()与 equals()的关系

  • 如果两个对象相等,则 hashcode 也相等;
  • 两个对象相等, 对两个对象别离调用 equals 办法都返回 true
  • 两个对象有雷同的 hashcode 值,它们不肯定是同一个对象;
  • equals 办法被笼罩过,则 hashCode 办法也必须被笼罩;

1.12 什么是值传递和援用传递

值传递:传递了对象的一个正本,即便正本被扭转,也不会影响源对象;

援用传递:着传递的并不是理论的对象,而是对象的援用;对外部对象的扭转会反映到理论对象;

个别认为,Java 内的传递都是值传递,Java 中实例对象的传递是援用传递;

1.13 什么是抽象类与接口

  • 抽象类是对类的形象,是一种模板设计;而接口是行为的形象,能够了解为行为的标准;
  • 抽象类中能够蕴含非形象办法;而接口是相对的形象办法;
  • 接口默认是 public 办法,java8 中接口反对默认(default)办法;
  • 一个类能够实现多个接口,但只能实现一个抽象类;
  • 抽象类不能应用 final 润饰(final 润饰的类为固定类,无奈被继承)

1.14String、String StringBuffer 和 StringBuilder 的区别

  • String 是只读字符串,并不是根本数据类型,而是一个对象;其无奈扭转;每次操作都会产生新对象;
  • StringBuilder 并没有对办法进行加同步锁,线程不平安;
  • StringBuffer 对办法加了同步锁,线程平安;

tip: 数据量少的时候应用 String; 单线程应用 StringBuilder ; 多线程应用 StringBuffer ; 应用 StringBuilder 性能比 StringBuffer 性能 晋升大略有 10%~15%;

1.15 用最有效率的办法计算 2 乘以 8

2 << 3 = 8 ; 2 左移 3 位

1.16 & 与 && 的区别

& 运算符 按位与;

&& 运算符是短路与:&& 右边的表达式的值是 false,左边的表达式会被间接短路掉,不会进行运算

1.17 static 关键字

static 变量在 Java 中属于类的,它在所有的实例中具备雷同的值。当类被 Java 虚拟机载入的时候,会对 static 变量进行初始化;故须要用实例来拜访 static 变量;

1.18 Java 反对的数据类型

  1. 整数值型:byte,short,int,long;
  2. 字符型:char;
  3. 浮点类型:float,double;
  4. 布尔型:boolean;

类型

字节数

位数

short

2

16

int

4

32

long

8

64

float

4

32

double

8

64

char

2

16

1.19 final, finally, finalize 的区别

  • final:用于申明属性, 办法和类, 别离示意属性不可变, 办法不可笼罩, 类不可继承.
  • finally:异样解决语句构造的一部分,示意最初总是会执行.
  • finalize:Object 类的一个办法,在垃圾收集器执行的时候会调用被回收对象的此办法;

1.20 instanceof 关键字

instanceof 严格来说是 Java 中的一个双目运算符,用来查看一个对象是否为一个类的实例;

1.21 为什么不能用浮点型示意金额

浮点数为非准确值,应该应用 BigDecimal 来润饰金额;

1.22 主动装箱与拆箱

  • 装箱:主动将根本数据类型转换为包装器类型,调用 Integer 的 valueOf(int) 办法;
  • 拆箱:主动将包装器类型转换为根本数据类型。调用 Integer 的 intValue 办法

tip: int 是根底数据类型,占用空间小;Integer 是对象占用空间大;

1.23 switch 中是否应用 string 做参数

在 idk 1.7 之前,switch 只能反对 byte, short, char, int 或者其对应的封装类以及 Enum 类型。从 idk 1.7 之后 switch 开始反对 String。

能够用在 byte 上,然而不能用在 long 上。

1.24 java 创建对象的几种形式

  1. 采纳 new
  2. 通过反射
  3. 采纳 clone
  4. 通过序列化机制

1.25 如何将 byte 转为 String

能够应用 String 接管 byte[] 参数的结构器来进行转换, 但编码必须正确;

1.26 final 有哪些用法

1. 被 final 润饰的类不能够被继承 2. 被 final 润饰的办法不能够被重写 3. 被 final 润饰的变量不能够被扭转。5. 被 final 润饰的常量,在编译阶段会存入常量池中。

1.27 java 当中的四种援用

  1. 强援用:如果一个对象具备强援用,它就不会被垃圾回收器回收。即便以后内存空间有余,JVM 也不会回收它,而是抛出 OutOfMemoryError 谬误,使程序异样终止。如果想中断强援用和某个对象之间的关联,能够显式地将援用赋值为 null,这样一来的话,JVM 在适合的工夫就会回收该对象。
  2. 软援用:在应用软援用时,如果内存的空间足够,软援用就能持续被应用,而不会被垃圾回收器回收,只有在内存不足时,软援用才会被垃圾回收器回收。
  3. 弱援用:具备弱援用的对象领有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱援用对象,无论以后内存空间是否短缺,都会将弱援用回收。
  4. 虚援用:如果一个对象仅持有虚援用,那么它相当于没有援用,在任何时候都可能被垃圾回收器回收。

1.28 Math. round(-1. 5) 等于多少?

Math.round(-1.5)的返回值是 -1。四舍五入的原理是在参数上加 0.5 而后做向下取整

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

tring str=”i” 的形式,Java 虚构机会将其调配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中; 所以一个是常量,一个是对象,不一样;

1.30char 型变量中能不能存储一个中文汉字

char 类型能够存储一个中文汉字,因为 Java 中应用的编码是 Unicode,一个 char 类型占 2 个字节,所以能放一个中文。

1.31 break 和 continue 的区别

  • break 跳出整个循环。
  • continue 用于跳过本次循环,执行下次循环。

1.32 外部类与动态外部类的区别

外部类: 1、外部类中的变量和办法不能申明为动态。2、外部类实例化:B 是 A 的外部类,实例化 B:A.B b = new A().new B()。3、外部类能够援用外部类的动态或者非动态属性及办法。

动态外部类: 1、动态外部类属性和办法能够申明为动态的或者非动态的。2、实例化动态外部类:B 是 A 的动态外部类,A.B b = new A.B()。3、动态外部类只能援用外部类的动态的属性及办法。

1.33 throw 和 throws 的区别?

  • throw 用于被动抛出 java.lang.Throwable 类的一个实例化对象,即通过关键字 throw 抛出一个 Error 或者 一个 Exception;
  • throws 的作用是作为办法申明和签名的一部分;

1.34 error 和 exception 的区别

  • Error 类和 Exception 类的父类都是 throwable 类
  • Error 类个别是指与虚拟机相干的问题,如零碎解体,虚拟机谬误,内存空间有余,办法调用栈溢等。间接终止程序即可;
  • Exception 类示意程序能够解决的异样,能够捕捉和有可能复原。须要程序员手动解决;

1.35 什么时候用断言(assert)

断言是一个蕴含布尔表达式的语句,在执行这个语句时假设该表达式为 true;如果表达式的值为 false,那么零碎会报告一个 AssertionError。

断言有两种模式:

  • assert Expression1; 示意一个 boolean 表达式
  • assert Expression1 : Expression2; Expression2 示意一个根本类型、表达式或者是一个 Object,用于在失败时输入错误信息

assert false;
assert i == 0:”123″;// 当 i 不等于 0 时会输入错误信息

1.36 常见的五种运行时异样

  • ClassCastException(类转换异样)
  • IndexOutOfBoundsException(数组越界)
  • NullPointerException(空指针异样)
  • ArrayStoreException(数据存储异样,操作数组是类型不统一)
  • BufferOverflowException(缓存溢出异样)

二 IO 流面试

2.1 序列化的含意

  • 序列化:将对象写入到 IO 流中
  • 反序列化:从 IO 流中复原对象

序列化机制将序列化的 Java 对象转换为位字节序列,这些字节序列能够保留在磁盘上,或通过网络传输,以达到当前复原成原来的对象,通常被序列化的要实现 Serializable 接口,并指定序列值

Externalizable 能够管制整个序列化过程,指定特定的二进制格局,减少平安机制

2.2 java 中 IO 流分类

  • 依照流的流向分,能够分为输出流和输入流;
  • 依照操作单元划分,能够划分为字节流和字符流;
  • 依照流的角色划,能够分为节点流和解决流。
  • InputStream/Reader: 所有的输出流的基类,前者是字节输出流,后者是字符输出流。
  • OutputStream/Writer: 所有输入流的基类,前者是字节输入流,后者是字符输入流。

图片起源网络:

2.3 BIO、NIO、AIO 的区别

  1. BIO 就是传统的 java.io 包,它是基于流模型实现的,交互的形式是同步、阻塞形式 IO; 在读入输出流或者输入流时,在读写实现之前,线程会始终处于阻塞状态。
  2. NIO(New IO)是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的形象,能够构建多路复用的、同步非阻塞 IO 程序。
  3. AIO(Asynchronous IO)是 Java 1.7 之后引入的包,是 NIO 的降级版本,提供了异步非梗塞的 IO 操作形式,所以人们叫它 AIO,异步 IO 是基于事件和回调机制实现。

三 汇合面试

3.1 java 汇合架构

3.2 Collection 和 Collections 的区别

Collection:是 java.uitl 下的接口,他是各种汇合的父接口;

Conllecitons:是个 java.util 下的类,是针对汇合的工具类,提供一系列静态方法对汇合的搜寻、查找、同步等操作;

3.3 ArrayList 和 Vector 的区别

  • 共同点:都实现了 List 接口,为有序的汇合,底层基于数组实现,通过索引取值,容许元素反复和为 null;都是实现 fail-fast 机制;
  • 区别:ArrayList 不同步,Vector 是同步(ArrayList 比 Vector 快,不会过载);Vector 扩容原来的一倍,ArrayList 扩容原来的 0.5 倍;

3.4List,Set,Map 三者的区别?

  • List:存储的元素有序可反复。
  • Set: 存储的元素是无序的、不可反复的。
  • Map: 应用键值对(kye-value)存储,通过 key 获取 value; key 不能反复;

3.5 ArrayList,LinkedList 区别

共同点:

ArrayListLinkedList 都是线程不平安;

区别:

  • ArrayList 的底层是数组实现,LinkedList 的底层是双向链表实现。
  • ArrayList 通过索引获取值,查问快;LinkedList 通过遍历链表获取值查问慢;
  • ArrayList 增删慢,LinkedList 增删快;

3.6Enumeration 和 iterator 接口的区别

  • iterator 是 Enumeration 接口的替代品,只提供了遍历 vector 和 HashTable 类型汇合元素的性能;
  • Enumeration 速度是 iterator 的 2 倍,同时占用更少的内存。
  • terator 有 fail-fast 机制,比 Enumeration 更平安
  • Iterator 可能删除元素,Enumeration 并不能删除元素

3.7 简述 Iterator 迭代器

Iterator 迭代器能够对汇合进行遍历,遍历形式都是 hasNext()next() 办法,,在以后遍历汇合元素被更改的时候,就会抛出 ConcurrentModificationException 异样;

3.8 HashMap 和 Hashtable 的区别

共同点:都实现 Map 接口;

区别:

  • HashMap 不同步;Hashtable 同步;HashMap 效率比 Hashtable 高;
  • HashMap 容许为 null;Hashtable 不容许为 null
  • Hashtable 默认的初始大小为 11,之后每次裁减,容量变为原来的 2n+1,HashMap 默认的初始化大小为 16;
  • HashMap 在 jdk1.8 扭转了数据结构为 数组 + 链表 + 红黑树形式;HashTable 应用全表锁,效率低下;

3.9HashSet 和 HashMap 的区别

  • HashMap 实现了 Map 接口;HashSet 实现了 Set 接口
  • HashMap 贮存键值对;HashSet 仅仅存储对象
  • HashMap 应用 put()办法将元素放入 map 中;HashSet 应用 add()办法将元素放入 set 中;
  • HashMap 中应用键对象来计算 hashcode 值;ashSet 应用成员对象来计算 hashcode 值;
  • HashSet 较 HashMap 来说比较慢;

3.10 HashMap 和 TreeMap 区别

TreeMap 实现 SortMap 接口,可能将记录依据键排序(默认升序排序),也能够指定排序的比拟器 Comparator,当用 Iterator 遍历 TreeMap 时失去排序后的后果;

对于插入、删除和定位元素等操作,抉择 HashMap;如果对一个有序的 key 汇合进行遍历,抉择 TreeMap

3.11 并发汇合和一般汇合区别

并发汇合常见的有 ConcurrentHashMapConcurrentLinkedQueueConcurrentLinkedDeque 等。并发汇合位于 java.util.concurrent 包下, 是 jdk1.5 之后才有;其相比与一般汇合增加了 synchronized 同步锁,线程平安,但效率低;

3.12 ConcurrentHashMap1.7 和 1.8 的区别

jdk1.8 的实现不再应用 jdk1.7 的 Segment+ HashEntry 分段锁机制实现,利用 Node 数组+CAS+Synchronized 来保障线程平安;底层采纳 数组 + 链表 + 红黑树 的存储构造;

ConcurrentHashMap1.7

dk1.7

ConcurrentHashMap1.8

3.13HashMap 的长度为什么是 2 的幂次方

目标是为了能让 HashMap 存取高效,尽量减少 Hash 碰撞,尽量使 Hash 算法的后果均匀分布,每个链表 / 红黑树长度大致相同;

算法理论是取模,hash%length,计算机中求余效率不如位移运算,源码中做了优化 hash&(length-1);hash%length==hash&(length-1)的前提是 length 是 2 的 n 次方

3.14 ArrayList 汇合如何高效退出 10 万条数据

间接在初始化的时候就指定 ArrayList 的容量值;

3.15 如何选用汇合

依据汇合的特点来选用汇合;依据键获取值选用 Map 接口下的汇合;须要排序抉择 TreeMap, 不须要排序抉择 HashMap, 须要线程平安选 ConcurrentHashMap

只寄存元素值时,就抉择实现 Collection 接口的汇合;须要元素惟一时抉择实现 Set 接口的汇合,如 TreeSetHashSet; 不须要元素唯一性就抉择实现 List 接口, 如 ArrayListLinkedList;

3.16 疾速失败(fail-fast)和平安失败(fail-safe)的区别是什么

  • 疾速失败:当你在迭代一个汇合的时候,如果有另一个线程正在批改你正在拜访的那个汇合时,就会抛出一个 ConcurrentModification 异样。在 java.util 包下的都是疾速失败。
  • 平安失败:你在迭代的时候会去底层汇合做一个拷贝,所以你在批改下层汇合的时候是不会受影响的,不会抛出 ConcurrentModification 异样。在 java.util.concurrent 包下的全是平安失败的。

附:

HashMap 源码剖析:https://blog.csdn.net/youku1327/article/details/105332136;

ArrayList 源码剖析 https://blog.csdn.net/youku1327/article/details/105314040

tip: 须要懂 HashMap,ArrayList,LinkedList,ConcurrentHashMap 底层实现原理

退出移动版