Java面试通关秘籍(一)

1. 基础篇

1.1 Java基础

  • 面向对象的特征:继承、封装和多态

    1.继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。

    好处:提高了代码的复用性。让类与类之间产生了关系,提供了多态的前提。

**2.封装:** 隐藏对象的属性和实现细节,仅对外提供公共访问方式。

好处:     
①将变化隔离。
②便于使用。
③提高重用性。
④提高安全性。

**3.多态:**     在同一个方法中,由于参数不同而导致执行效果各异的现象就是多态。
前提条件:
A:要有继承关系。
B:要有方法重写。
C:要有父类引用指向子类对象。

**小结:**
 > 封装即隐藏对象的属性和实现细节,仅对外提供公共访问方式,保证了模块具有较好的独立性,使得程序维护修改较为容易。继承提高了代码的复用性,多态提高代码的扩展性和可维护性。三者共同达到了一个目的:使得对应用程序的修改带来的影响更加局部化,程序更加健壮,而且易维护、更新和升级。
  • final, finally, finalize 的区别

    final:标识此变量为不可变,。对基本类型使用是不能改变的是他的数值。而对于对象引用,不能改变的是他的引用
    finally: 异常捕获的一个代码块,代码块中的内容无论是否发生异常都会去执行,一般用来释放资源
    finalize:垃圾回收机制,主要用来回收对象

  • Exception、Error、运行时异常与一般异常有何异同

    Throwable 是所有 Java 程序中错误处理的父类 ,有两种子类: Error 和 Exception

    Error:属于严重错误,JVM无法捕获,也无法采取任何恢复手段。比如:内存溢出
    Exception :可以捕获的,可以恢复程序正常运行
    运行时异常:运行时异常不要求我们必须捕获,他是由虚拟机接管,比如:空指针,除零异常
    一般异常:也即是checked exception,这种异常必须自己写一大堆try catch块去处理。比如:SQL异常,IO异常

  • 请写出5种常见到的Runtime exception
    NullPointerException、ArrayIndexOutOfBoundsException 、ClassNotFoundException、ClassCastException、ArithmeticException(除零异常)、NegativeArraySizeException(当创建数组时传递参数为负数)

  • int 和 Integer 有什么区别,Integer的值缓存范围

    int为基本数据类型,Integer为int的包装类,int默认值为0,而Integer默认值为null
    Integer缓存范围为 -128-127

    1
    2
    3
    Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150; 
    System.out.println(f1 == f2); true
    System.out.println(f3 == f4); false
  • 包装类,装箱和拆箱

    包装类:一切皆对象,八种基本数据类型不是对象。把这八种基本数据类型包装成每一个类,这样每一个类就可以以对象的形式操作基本数据类型。

    装箱:将基本数据类型变成包装类称为装箱。

    拆箱:将包装类的类型变为基本数据类型称为拆箱。

  • String、StringBuilder、StringBuffer

    String类被final修饰,所以为不可变的,当字符串拼接时他会重新创建一个新的对象,速度会很慢
    StringBuilder:线程不安全的,但是是最快的
    StringBuffer:线程安全的,速度仅此于StringBuilder

  • 重载和重写的区别

    重写方法的规则:(存在于子类与父类之间)

    1)参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
    2)返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
    3)访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
    4)重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:
    父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。
    **重载的规则:**(存在于子类与父类之间、同类中)
    1)必须具有不同的参数列表;
    2)可以有不同的返回类型,只要参数列表不同就可以了;
    3)可以有不同的访问修饰符;
    4)可以抛出不同的异常;
  • 抽象类和接口有什么区别

    1.抽象类可以有构造方法而接口不可以
    2.抽象中可以有普通方法,而接口中只能有抽象 方法
    3.抽象类中可以有普通变量,而接口中只能由常量
    4.抽象类中可以有静态方法,而接口中不可以
    5.一个类可以实现多个接口,但只能继承一个抽象类

  • 说说反射的用途及实现

    用途:它允许程序在运行时进行自我检查,同时也允许对其内部成员进行操作。反射机制提供的功能主要有:得到一个对象所属的类;获取一个类的所有成员变量和方法;在运行时创建对象;在运行时调用对象的方法。
    实现: ①静态代理 ②动态代理 ③ CGLB方法

  • 说说自定义注解的场景及实现

    场景:跟踪代码的依赖性,实现代替配置文件的功能
    实现: 使用@interface自定义注解,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节,在定义注解时,不能继承其他注解或接口。

  • HTTP请求的GET与POST方式的区别

    1. Get请求会将参数显示到地址栏中,而POST请求不会
    2. GET后退按钮/刷新无害,POST数据会被重新提交
    3. GET能被缓存,POST不能缓存
    4. GET对数据长度有限制,当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的
  • Session与Cookie区别

    cookie数据保存在客户端,session数据保存在服务器端。 详情请点击这里
    cookie一般用来保存用户的登录状态,一些隐私信息不能放到cookie中

  • 列出自己常用的JDK包

    java.lang、java.util、java.sql、java.math、java.io、java.net、java.text

  • MVC设计思想

    M:模型
    V:视图
    C:控制
    点击查看详情

  • equals与==的区别
    ==

    比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象,如果是具体的阿拉伯数字的比较,值相等则为true

    equals

    用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断
    hashCode和equals方法的区别与联系

  • 什么是Java序列化和反序列化,如何实现Java序列化?或者请解释Serializable 接口的作用

    序列化:将java对象用二进制表示出来,而且这个二进制可以保存到磁盘或进行网络传输而不会破坏其结构
    反序列化:将这个二进制还原为java对象本身
    实现序列化:实现java.io.Serializable 接口
    Serializable 接口的作用:标识此对象可以被序列化

  • Object类中常见的方法,为什么wait notify会放在Object里边?

    wait、hashCode、equals、toString、notify、clone、getClass

    简单说:因为synchronized中的这把锁可以是任意对象,所以任意对象都可以调用wait()和notify();所以wait和notify属于Object。
    专业说:因为这些方法在操作同步线程时,都必须要标识它们操作线程的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法是定义在object类中。

  • JDK和JRE的区别

    JDK就是Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境。SDK是Software Development Kit 一般指软件开发包,可以包括函数库、编译程序等。
    JRE是Java Runtime Enviroment是指Java的运行环境,是面向Java程序的使用者,而不是开发者

    JDK = JRE + 开发工具

1.2 Java常见集合

  • List 和 Set 区别

    List底层使用数组实现,可以重复,并且有序
    Set底层是用HashMap实现,无序且不可重复

  • Set和hashCode以及equals方法的联系

    Set集合为保证内部元素不重复,当调用add()方法时,先判断此对象的hashCode是否在Set集合中已存在,如果不存在则直接添加进去,如果已存在则进一步判断 equals 方法,判断两对象的值是否相同。

  • List 和 Map 区别

    List是单列集合,而Map是双列集合,是通过键值对进行存储

  • Arraylist 与 LinkedList 区别
    ArrayList :线程不安全,底层用数组实现,按插入先后排序,随机访问快,插入与删除慢。
    LinkedList :线程不安全的,底层基于链表的数据结构实现,访问慢但插入元素与删除元素比较快。LinkedList类实现了Queue接口,可当做队列使用

  • ArrayList 与 Vector 区别
    ArrayList是线程不安全的,而Vector是线程安全的

  • HashMap 和 Hashtable 的区别

    HashMap是线程不安全的,他的键和值都可以为null
    Hashtable是线程安全的,他的键和值不可以为null

  • HashSet 和 HashMap 区别

    HashSet基础AbstractSet 而 HashMap继承 AbstractMap

  • HashMap 和 ConcurrentHashMap 的区别
    HashMap是线程不安全的,而ConcurrentHashMap是线程安全的,而且效率要大于Hashtable

  • HashMap和ArrayList的默认大小

    HashMap默认大小为 16 增量因子为 0.75
    ArrayList默认大小为 10 每次扩容为原来的1.5 倍

1.3 进程和线程

  • 线程和进程的概念、并行和并发的概念

线程:是程序执行流的最小单元,是系统独立调度和分配CPU(独立运行)的基本单位。

进程:是资源分配的基本单位。一个进程包括多个线程。

区别:
1.线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。
2.每个进程都有自己一套独立的资源(数据),供其内的所有线程共享。
3.不论是大小,开销线程要更“轻量级”
4.一个进程内的线程通信比进程之间的通信更快速,有效。(因为共享变量)

并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

  • 创建线程的方式及实现

    实现Runnable接口、继承Thead

进程间通信的方式

说说 CountDownLatch、CyclicBarrier 原理和区别

说说 Semaphore 原理

说说 Exchanger 原理

ThreadLocal 原理分析,ThreadLocal为什么会出现OOM,出现的深层次原理

讲讲线程池的实现原理

线程池的几种实现方式

线程的生命周期,状态是如何转移的

-------------本文结束感谢您的阅读-------------