zoukankan      html  css  js  c++  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底层实现原理

  • 相关阅读:
    Operation Queue
    Dispatch Sources
    Base64编码详解
    属性存取、直接访问实例变量
    管理关联对象和NSDictionary区别
    3个Block替换Delegate的场景
    Objective-C消息机制
    Dispatch Queues调度队列
    DNS64/NAT64 Networks(解决IPv6审核被拒)
    NSObject的Initialize与Load方法
  • 原文地址:https://www.cnblogs.com/zszxz/p/13380024.html
Copyright © 2011-2022 走看看