关于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底层实现原理

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理