面试准备之Java 基础(理论篇)

简介: 面试准备之Java 基础(理论篇)

1、面向对象和面向过程的区别


面向过程:面向过程性能比面向对象高。因为对象调用需要实例化,开销比较大,较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix 等,一般采用面向过程开发。但是,面向过程没有面向对象易维护、易复用、易扩展。


面向对象:面向对象易维护、易复用、易扩展。因为面向对象有封装、继承、多态性的特性,所以可设计出低耦合的系统,使得系统更加灵活、更加易于维护。

面向过程性能比面向对象高的背后原因?


面向过程也需要分配内存,计算内存偏移量,Java 性能差的主要原因并不是因为它是面向对象语言,而是因为 Java 是半编译语言,最终的执行代码并不是可以直接被 CPU 执行的二进制机器码。

而面向过程语言大多都是直接编译成机器码在电脑上执行,并且其它一些面向过程的脚本语言性能也并不一定比 Java 好。


2、Java 语言有哪些特点?


  • 简单易学(其实相比较 Python 还是更容易上手一些)
  • 面向对象(封装、继承、抽象、多态)
  • 平台无关性(Java 虚拟机实现字节码文件的跨平台)
  • 安全可靠性
  • 支持多线程(C++语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持)
  • 支持网络编程并且很方便(Java 语言诞生就是为了简化网络编程设计的)
  • 编译与解释并存


扩展:为什么说 Java 语言编译与解释并存?


当 .class 字节码文件通过 JVM 转为机器可以执行的二进制机器码时,JVM 类加载器首先加载字节码文件,然后通过解释器逐行进行解释执行,这种方式的执行速度相对比较慢。而且有些方法和代码块是反复被调用的(也就是所谓的热点代码),所以后面引进了 JIT 编译器,而 JIT 属于运行时编译。当 JIT 编译器完成一次编译后,会将字节码对应的机器码保存下来,下次可以直接调用。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言。


HotSpot采用了惰性评估(Lazy Evaluation)的做法,根据二八定律,消耗大部分系统资源的只有那一小部分的代码(热点代码),而这也就是JIT所需要编译的部分。JVM会根据代码每次被执行的情况收集信息并相应地做出一些优化,因此执行的次数越多,它的速度就越快。JDK 9引入了一种新的编译模式AOT(Ahead of Time Compilation),它是直接将字节码编译成机器码,这样就避免了JIT预热等各方面的开销。JDK支持分层编译和AOT协作使用。但是 ,AOT 编译器的编译质量是肯定比不上 JIT 编译器的。


3、什么是 Java 虚拟机?为什么 Java 被称作是“平台无关的编程语言”?


Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。Java 源文件被编译成能被 Java 虚拟机执行的字节码文件。

Java 的跨平台指的是 java 源文件经过 javac 编译器编译成的二进制.class  字节码的跨平台性。各个平台装有不同的 jvm,而 jvm 能将相同的字节码翻译成平台相关的机器码,进而执行。


4、JDK 和 JRE 的区别是什么?


Java 运行时环境(JRE)。它包括 Java 虚拟机、Java 核心类库和支持文件。它不包含开发工具(JDK)--编译器、调试 和其他工具。

Java 开发工具包(JDK)是完整的 Java 软件开发包,包含了 JRE,编译器和其他的工具(比如:JavaDoc,Java 调试器),可以让开发者开发、编译、执行 Java 应用程序。


5、Java 和 C++的区别?


  • 都是面向对象的语言,都支持封装、继承和多态;
  • Java 不提供指针来直接访问内存,程序内存更加安全;
  • Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承;
  • Java 有自动内存管理机制,不需要程序员手动释放无用内存。


6、面向对象的特征有哪些方面?


  1. 封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。


  1. 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。


  1. 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。


  1. 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。即同一消息可以根据发送对象的不同而采取不同的行为方式。



  • 多态性分为编译时的多态性和运行时的多态性。
  • 方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。
  • 实现多态的技术:动态绑定,是指执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
  • 实现多态的条件:(1)继承(2)方法重写(3)父类引用指向子类对象。
  • 多态的作用:消除类型之间的耦合关系。


7、访问修饰符 public,private,protected,以及不写(默认)时的区别?


private:类成员只能被当前类本身访问,如果类的构造方法声明为 private,则其他类不能生成该类的实例。default:类成员可以被这个类和同一个包中的类所访问。protected:类成员被同一个类,同一个包中的其他类,子类(同包或不同包)访问。public:被所有类访问。


8、”static”关键字是什么意思?Java 中是否可以覆盖(override)一个 private 或者是 static 的方法?


static 表示静态的意义,可以修饰成员变量、成员方法、内部类和代码块,被 static 修饰的变量叫做静态变量,随类加载一次,可以被多个对象共享。被其修饰的方法称为静态方法(类方法),其随着类的加载而被加载,可以通过类直接访问,不需要实例化对象。此外静态方法只能访问静态成员,不可以直接访问非静态成员。静态内部类可以直接调用静态构造器(不用对象)。静态代码块只需加载一次,可以有多个代码块。


重写是子类中的方法和子类继承的父类中的方法一样(函数名,参数,参数类型,返回值类型),但是子类中的访问权限要不低于父类中的访问权限。重写的前提是必须要继承,private 修饰不支持继承,因此被私有的方法不可以被重写。静态方法形式上可以被重写,但是会被隐藏。原因在于方法重写基于运行时动态绑定,而 static 方法是编译时静态绑定的。


9、static内容扩展


static 修饰的内容在继承关系中的加载顺序如下图所示:


10..jpg


关于静态代码块、构造代码块、构造函数的初始化顺序


静态代码块:用staitc声明,jvm加载类时执行,仅执行一次
构造代码块:类中直接用{}定义,每一次创建对象时执行。
执行顺序优先级:静态块,构造块,构造方法。
复制代码


关于静态域的初始化顺序


public class Test2  {
    public static Test2 test = new Test2();
    {
        System.out.println("子类构造代码块");
    }
    static {
        System.out.println("子类静态代码块");
    }
    public static Test2 test2 = new Test2();
    public Test2(){
        System.out.println("子类构造方法");
    }
    public static void main(String[] args) {
        Test2 test2 = new Test2();
    }
}
复制代码


执行结果为:


子类构造代码块
子类构造方法
子类静态代码块
子类构造代码块
子类构造方法
子类构造代码块
子类构造方法
复制代码


10、是否可以在 static 环境中访问非 static 变量?


因为静态的成员属于类,随着类的加载而加载到静态方法区内存,当类加载时,此时不一定有实例创建,没有实例,就不可以直接访问非静态的成员。

最常见的 static 方法就是 main,作为程序的入口,所有对象都是在该方法里面实例化。


11、成员变量与局部变量的区别有哪些?


  1. 从语法形式上看:成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被 public、private、static 等修饰符所修饰,而局部变量不能被这些修饰符所修饰;但是它们都可以被 final 所修饰。


  1. 从变量在内存中的存储方式来看:如果成员变量被 static 所修饰,那么这个成员变量属于类,如果没有被 static 修饰,则该成员变量属于对象实例。对象存在于堆内存,局部变量存在于栈内存(具体是Java虚拟机栈)。


  1. 从变量在内存中的生存时间来看:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用结束而自动消失。


  1. 成员变量如果没有赋初始值,则会自动以类型的默认值而赋值(例外:被 final 修饰的成员变量必须在初始化时赋值),局部变量则不会自动赋值。


12、Java 支持的数据类型有哪些?什么是自动拆装箱?


  • 基本数据类型:byte,short,char,int,long,float,double,boolean。
  • 引用数据类型:Integer、String 等。引用类型实体在堆中,声明的变量存放的是该对象的引用地址。


自动装箱就是 Java 编译器在基本数据类型和对应的对象包装类型间的转化,即 int 转化为 Integer,自动拆箱是 Integer 调用其方法将其转化为 int 的过程。


13、Java 中的方法覆盖(Overriding)和方法重载(Overload)是什么意思?


方法重写(两同两小一大)

  • 方法名,参数列表必须相同,返回类型可以相同也可以是原类型的子类型
  • 重写方法不能比原方法访问性差(即访问权限不允许缩小)。
  • 重写方法不能比原方法抛出更多的异常。
  • 重写发生在子类和父类之间
  • 重写实现运行时的多态性


方法重载


  • 方法名必须相同,参数列表必须不同(个数不同、或类型不同、参数类型排列顺序不同等)
  • 方法的返回类型可以相同也可以不相同。
  • 重载发生在同一类中
  • 重载实现编译时的多态性


14、Java 中,什么是构造方法?什么是构造方法重载?什么是复制构造方法?


Java 中的构造函数是为了初始化对象的,构造函数的函数名和类名一致,默认的构造函数没有参数,没有返回值,构造函数的函数体内,没有内容。 构造函数的重载是函数名与类名相同,参数列表不同。同样也是为了初始化对象的。

关于复制构造函数:C++ 中的复制构造函数通常有三种作用

  1. 对象作为函数参数
  2. 对象作为函数返回值
  3. 使用一个对象对另一个对象初始化。


C++ 语法允许用户定义自己的复制构造函数以实现自定义的复制,比如说进行深复制。Java 并不支持这样的复制构造函数。但是这并不代表 Java 中没有这种机制,在 Java 中 Object 类的 clone()方法就是这种机制的体现。而且通过以上三种方式对 Java 对象进行的操作都是对引用的操作,不像 C++ 里面是对原对象的操作,因此 Java 中也不需要考虑需要使用复制构造函数这种问题。


15、Java支持多继承么?


Java 中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是 Java 中的接口支持多继承,,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。


16、什么是值传递和引用传递?


值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量. 引用传递一般是对于引用型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。一般认为,Java 内的基础类型数据传递都是值传递. Java 中实例对象的传递是引用传递

Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用的一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。


当基本型变量作为参数传递到方法中时,参数的值是该变量的副本,改变副本不影响原变量。


StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
    builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。
复制代码


推荐阅读:Java中只有按值传递,没有按引用传递!


17、== 和 equals 的区别是什么?


基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean 它们之间的比较,应用双等号(==),比较的是它们的值。

复合数据类型(类)。当它们用双等号进行比较的时候,比较的是它们在内存中的存放地址,所以,除非是同一个 new 出来的对象,它们的比较后的结果为 true,否则比较后结果为 false。 Java 当中所有的类都是继承于 Object 这个基类的,在 Object 中的基类中定义了一个 equals 的方法,这个方法的初始行为是比较对象的内存地址,但在一些类库当中这个方法被覆盖掉了,如 String,Integer,Date 在这些类当中 equals 有其自身的实现(在重写 equals 方法的时候,有必要重写对象的 hashCode 方法,从而保证程序完整性),而不再是比较类在堆内存中的存放地址了。


18、为什么重写 equals 时必须重写 hashCode 方法?


hashCode()与equals()的相关规定:

  • 如果两个对象相等(即用 equals 比较返回 true),则 hashcode 一定也是相同的;
  • 两个对象有相同的 hashcode 值,它们也不一定是相等的(不同的对象也可能产生相同的 hashcode,概率性问题);
  • equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。


为什么要有 hashCode?


我们先以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode: 当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相同的 hashcode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

通过我们可以看出:hashCode() 的作用就是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()在散列表中才有用,在其它情况下没用。在散列表中 hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。


继续上面的话题,为什么必须要重写 hashcode 方法,其实简单的说就是为了保证同一个对象,保证在 equals 相同的情况下 hashcode 值必定相同,如果重写了 equals 而未重写 hashcode 方法,可能就会出现两个没有关系的对象 equals 相同的(因为 equals 都是根据对象的特征进行重写的),但 hashcode 确实不相同的。


19、final 在 Java 中有什么作用?


  1. 当用 final 修饰一个类时,表明这个类不能被继承。
  2. final 修饰的方法不能被重写。
  3. final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。


20、java 中操作字符串都有哪些类?它们之间有什么区别?


操作字符串的类有:StringStringBufferStringBuilder


String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。


StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。


21、int和Integer有什么区别?



public class Test03 {
    public static void main(String[] args) {
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
        System.out.println(f1 == f2);
        System.out.println(f3 == f4);
    }
//结果
true
false
复制代码


Java 在编译 Integer i = 100 ;时,会翻译成为 Integer i = Integer.valueOf(100)。根据 Java API 中对 Integer 类型的 valueOf 的定义可知,当数值在[-128,127]范围内时,Integer 对象会存储在缓存中,f1 和 f2 都指向的是缓存中同一个对象,而不会 new 个新对象。反之如果不在该范围内,f3 和 f4 指向两个不同的对象。


22、静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?



Static Nested Class 是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。


class Outer {
    class Inner {}
    public static void foo() { 
        new Inner(); //编译报错
    }
    public void bar() { 
        new Inner(); 
    }
    public static void main(String[] args) {
        new Inner();//编译报错
    }
}
复制代码


Java 中非静态内部类对象的创建要依赖其外部类对象,上述代码中 foo 和 main 方法都是静态方法,静态方法中没有 this,也就是说没有所谓的外部类对象,因此无法创建内部类对象,如果要在静态方法中创建内部类对象,可以这样做:new Outer().new Inner();


23、关于内部类的总结


1.jpg


24、接口和抽象类的区别和相同点是什么?


接口和抽象类的区别


  1. 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。


  1. 定义接口的关键字是 interface ,抽象类的关键字是 abstract class


  1. 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。


  1. 类可以实现很多个接口,但是只能继承一个抽象类,接口可以继承多个接口


  1. Java 接口中声明的变量默认都是 public static final 的。抽象类可以包含非 final 的变量。


  1. 在JDK1.8之前,接口中不能有静态方法,抽象类中可以有普通方法和静态方法;在 JDK1.8后,接口中可以有默认方法和静态方法,并且有方法体。


  1. 抽象类可以有构造方法,但是不能直接被 new 关键字实例化。


  1. 在 JDK1.8 前,抽象类的抽象方法默认访问权限为 protected,1.8默认访问权限为 default,共有 default,protected 、 public 三种修饰符,非抽象方法可以使用四种修饰符;在 JDK1.8 前,接口方法默认为 public,1.8时默认为 public,此时可以使用 public 和 default,1.9时接口方法还支持 private。

相同点:



  1. 接口是绝对抽象的,不可以被实例化,抽象类也不可以被实例化。

  2. 类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。

25、抽象类能使用 final 修饰吗?


不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类。


26、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被 synchronized 修饰?


都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如 C 代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized 和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。


27、Java 有没有 goto?



goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。


扩展:null、true、false 是关键字吗?


2.jpg


  • truefalse不是关键字,而是布尔文字
  • null不是关键字,而是 null 文字
  • Java9 之后增加了下划线(_)作为关键字


官方文档: docs.oracle.com/javase/spec…


28、&和&&的区别?


&运算符有两种用法:(1)按位与;(2)逻辑与。&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是 true 整个表达式的值才是 true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。


29、Java 中 IO 流分为几种?


  • 按功能来分:输入流(input)、输出流(output)。
  • 按类型来分:字节流和字符流。
  • 按照流的角色划分为节点流和处理流。


字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。


节点流:可以从或向一个特定的地方(节点)读写数据。如 FileReader。处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如 BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。


推荐阅读:JAVA的节点流和处理流


Java IO 流共涉及 40 多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。


  • InputStream/Reader: 所有输入流的基类,前者是字节输入流,后者是字符输入流。
  • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。


按操作方式分类结构图:


3.jpg


按操作对象分类结构图:


4.jpg


30、BIO、NIO、AIO 有什么区别?


1、BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。


传统的服务器端同步阻塞I/O处理(也就是BIO,Blocking I/O)的经典编程模型 :


{
 ExecutorService executor = Excutors.newFixedThreadPollExecutor(100);//线程池
 ServerSocket serverSocket = new ServerSocket();
 serverSocket.bind(8088);
 while(!Thread.currentThread.isInturrupted()){//主线程死循环等待新连接到来
     Socket socket = serverSocket.accept();
     executor.submit(new ConnectIOnHandler(socket));//为新的连接创建新的线程
}
class ConnectIOnHandler extends Thread{
    private Socket socket;
    public ConnectIOnHandler(Socket socket){
       this.socket = socket;
    }
    public void run(){
      while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){死循环处理读写事件
          String someThing = socket.read()....//读取数据
          if(someThing!=null){
             ......//处理数据
             socket.write()....//写数据
          }
      }
    }
}
复制代码


2、NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。在Java 1.4 中引入了 NIO 框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发。


3、AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步 IO 的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。


31、获取用键盘输⼊常用的两种⽅法


1、通过 Scanner


Scanner scanner = new Scanner(System.in);
String value = scanner.nextLine();
System.out.println(value);
scanner.close();
复制代码


2、通过 BufferedReader


BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
try {
    String name = reader.readLine();
    reader.close();
} catch (IOException e) {
    e.printStackTrace();
}
复制代码


32、Java8 高级特性


1.Lambda表达式


Java Lambda表达式的一个重要用法是简化某些匿名内部类Anonymous Classes)的写法。实际上 Lambda 表达式并不仅仅是匿名内部类的语法糖,JVM内部是通过invokedynamic指令来实现Lambda表达式的。


推荐阅读:关于Java Lambda表达式看这一篇就够了


2.Stream函数式操作流元素集合


3.接口新增:默认方法与静态方法


Java 8 新增了接口的默认实现,通过 default 关键字表示。同时也可以提供静态默认方法。


4.方法引用,与Lambda表达式联合使用


通过方法引用,可以使用方法的名字来指向一个方法。使用一对冒号来引 "::" 用方法。


5.引入重复注解


6.类型注解


7.最新的Date/Time API (JSR 310)


8.新增base64加解密API


9.数组并行(parallel)操作


10.JVM的PermGen空间被移除:取代它的是Metaspace(JEP 122)元空间

推荐阅读:聊聊 Java8 以后各个版本的新特性

JDK8-十大新特性-附demo


目录
相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
28天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
67 14
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
1月前
|
Java 编译器 程序员
Java面试高频题:用最优解法算出2乘以8!
本文探讨了面试中一个看似简单的数学问题——如何高效计算2×8。从直接使用乘法、位运算优化、编译器优化、加法实现到大整数场景下的处理,全面解析了不同方法的原理和适用场景,帮助读者深入理解计算效率优化的重要性。
36 6
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
72 4
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
135 4
|
2月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
125 1
Java面试题之Java集合面试题 50道(带答案)
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
92 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)