一、Java基础

Github地址

优快云地址

一、基础知识(必会)

1.1 JDK,JRE和JVM的区别与联系有哪些?

答: 首先要熟悉其基本概念

分类概念
JDK(Java Development Kit)是一个开发工具包, 是Java开发环境的核心组件, 并提供编译, 运行和调试一个Java程序所需要的工具, 可执行文件和二进制文件, 是一个平台特定的软件.
JRE(Java Runtime Environment)是指Java运行时环境, 是JVM的实现, 提供了运行Java程序的平台. JRE包含了JVM, 但不包含Java编译器/调试器之类的开发工具.
JVM (Java Virtual Machine)是指Java虚拟机, 当我们运行一个程序时, JVM负责将字节码转换为特定机器码, JVM提供了内存管理/垃圾回收和安全机制等.

区别于联系

  • JDK是开发工具包, 用来开发JAva程序, 而JRE是Java的运行时环境
  • JDK和JRE中都包含了JVM
  • JVM是Java编程的核心, 独立于硬件和操作系统, 具有平台无关性, 而这也是Java程序可以一次编写, 多处执行的原因

延伸① Java语言的平台无关性是如何实现的?
答:

  • JVM屏蔽了操作系统和底层硬件的差异
  • Java面向JVM编程, 先编译生成字节码文件, 然后交给JVM解释成机器码执行
  • 通过规定基本数据类型的取值范围和行为

延伸② Java语言是编译型还是解释型语言?
答:

Java的执行经历了编译和解释的过程,是一种先编译,后解释执行的语言,不可以单纯归到编译性或者解释性语言的类别中。

1.2 接口和抽象类有什么区别?

答: 首先需要知道, 定义接口需要用到interface, 定义抽象类需要用到关键字abstract关键字, 区别还有以下几点

  • 抽象类中可以没有抽象方法, 也可以抽象方法和非抽象方法共存.
  • 接口中的方法在JDK8之前只能是抽象的(默认就是抽象的), 从JDK8版本可以通过default实现在接口中创建默认方法.
  • 抽象类和类一样是单继承, 但接口可以实现多个父接口
  • 抽象类中可以存在普通的成员变量; 接口中的变量必须是static, final类型;必须被初始化, 接口中只有常量, 没有变量;

延伸① 抽象类和接口应该如何选择?分别在什么情况下使用呢?
答:
根据抽象类和接口不同之处, 当我们仅仅需要定义一些抽象方法而不需要额外的具体方法或变量时, 就使用接口, 反之使用抽象类.

延伸② 在JDK>= 1.8中接口通过default关键字实现默认方法

public interface DemoInterface {
    // 在方法前面添加default
    default void say(String msg){
        System.out.println("Hello " + msg);
    }
    // 普通的抽象方法
    void test();
}

当一个类实现该接口时,可以继承到该接口中的默认方法

public class Demo implements DemoInterface {
	public static void main(String[] args){
		Demo demo = new Demo();
		demo.say("world");
	}
	@Override
	public void test(){}
}

>>Hello world

注意如果继承了多个接口中都出现了同样default方法, 如果不加以修改,会报错. 需要

  • 重写多个接口中的相同的默认方法
  • 或者在实现类中指定要使用哪个接口中的默认方法
1.3 Java中的8种基本数据类型及其取值范围

可通过.MAX_VALUE.MIN_VALUE取得范围

类型所占字节数
byte1字节
short2字节
int4字节
long8字节
float4字节
double8字节
char2字节
booleanJava中并没有规定Boolean所占字节数
1.4 Java中元注解有哪些?

答:Java中提供了4个元注解, 元注解的作用是负责注解其他注解

  • @Target : 说明注解所修饰的对象范围,其值在ElementType中, 其源码
public @interface Target { 
    ElementType[] value(); 
} 
public enum ElementType { 
  TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE 
} 

例如,如下的注解使用@Target标注,表明MyDemo注解就只能作用在类/接口和方法上。

@Target({ElementType.TYPE, ElementType.METHOD}) 
public @interface MyDemo { 
}
  • @Retention : 保留策略, 定义了该注解被保留的时间长短,其源码
public @interface Retention {
	RetentionPolicy value();
}
public enum RetentionPolicy {
	SOURCE, CLASS, RUNTIME
}

SOURCE表明在源文件中保留(即源文件保留, 编译器将丢掉), CLASS表明在class文件中有效(即class保留, VM将丢掉), RUNTIME表明在运行时有效(即运行时保留)

  • @Documented : 用于描述其他类型的annotation应该被作为被标注的程序成员的公共API,因此可以被javadoc此类的工具文档化, Documented是一个标记注解,没有成员,其源码
public @interface Documented {
}
  • @Inherited : 也是一个标记注解, 其表明被注解的类型是被继承的, 如果一个使用@Inherited修饰的annotation类型被用于一个class, 则这个annotation将被用于该class的子类.
public @interface Inherited {
}

扩展
(1) 注解的作用: 代替繁杂的配置文件,简化开发, 在SpringBoot中大量使用.
(2) 怎么定义一个注解: 从上面的例子也可以看出, 使用@interface , 那怎么定义注解的属性? eg.

public @interface Demo{
	String val1();
	int val2();
}
//使用注解,设置属性,
@Demo(val1 = "Hello", val2 = 1)
public class TestClass{
}
1.5 Java反射机制

指在运行过程中, 对于任意一个类都能知道这个类的属性和方法; 对于任意一个对象都能调用它的任意一个方法和属性. 即动态获取信息和动态调用对象方法的功能称为为反射机制. 其作用:

  • 在运行时, 判断任意一个对象所属的类
  • 在运行时, 构造任意类的对象
  • 在运行时, 判断任意对象所具有成员变量及方法
  • 在运行时, 调用任意对象的方法, 生成动态代理

反射相关的类

  • Class : 表示类, 用于获取类相关信息
  • Field : 表示成员变量, 用于获取类的实例变量和静态变量等
  • Method : 表示方法, 用于获取类中的方法参数方法类型
  • Constructor : 表示构造器, 用于获取构造器的方法参数和和类型等

反射举例及优缺点看这个->JVM的1.5章节

1.6 Java中Exception和Error有什么区别?

答: 主要区别为

  • Exception是程序正常运行中预料到可能会出现的错误, 并且可以被捕捉并被处理
  • Error是程序正常情况下不辉发生的错误,Error会导致JVM处于一种不可恢复的状态, 不需要捕捉处理, 比如OutOfMemoryOfError

扩展
① Exception又分为运行时异常编译时异常,

  • 编译时异常表示当前方法体内部抛出一个异常, 编译器检测到这段代码时判断可能会出现异常, 所以要求我们必须对异常进行相应处理, 捕捉或交给上层处理. 如 文件读取时的IO异常.
  • 运行时异常表示程序在运行时出现的异常, 如空指针异常, 数组越界, 数字转换异常以算术异常.

② 捕捉原则:

  • 尽可能捕捉详细的异常, 而不是使用Exception
  • 当本模块捕捉到但不知怎么处理异常时,可交给上层模块.
  • 捕捉异常后应有日志记录, 方便日后排查
  • 不要使用try-catch包住整段代码

③ 深度问题: NoClassDefFoundErrorClassNotFoundException 有什么区别?

  • ClassNotFoundException : 当我们使用Class.forName动态加载类时, 传入类名, 但没有被找到,就会出现这个异常.
  • NoClassDefFoundError : 当JVM或者ClassLoader实例尝试加载类(或正常方法调用, 或new 创建新对象) 时, 找不到类定义. 但要查找的类在编译时的确存在, 运行时却找不到, 这个时候就会出现ClassNotFoundError. 一般是因为打包的时候漏掉了部分类或者Jar包被篡改损坏.
1.7 Java中值传递和引用传递
  • 值传递 : 意味着传递了对象的一个副本, 即副本发生改变时, 影响不到源对象.
  • 引用传递 : 意味着传递了是对象的引用, 因此,当外部对引用对象的改变会反映到所有的对象上.
1.8 String、StringBuffer与StringBuilder的区别?

简要概括:

  • String是字符串常量, 不可变对象.
  • StringBuffer 字符串变量,线程安全
  • StringBuilder 字符串变量,线程不安全

使用原则: 少量字符串常量,使用String, 单线程大量数据使用StringBuilder, 多线程操作大量数据使用StringBuffer

1.9 Java中的泛型的理解

泛型就是参数化类型,在不创建新的数据类型情况下,通过泛型控制具体不同类型的形参. 让程序代码的可读性更高

泛型最常用的场景就是在集合中,能够简化开发,并且能够保证代码质量。泛型是在编译期间有效,在运行阶段就会去泛型化,也就是将泛型信息抹掉,这也是不支持泛型数组的原因.

1.10 Java序列化与反序列化

序列化:把对象转换为字节序列的过程称为对象的序列化。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化。序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。

  • 序列化过程: 创建ObjectOutputStream输出流, 调用其writeObject输出可序列化对象
  • 反序列化过程: 创建ObjectInputStream输出流, 调用其readObject输出可序列化对象
1.11 equals和hashCode方法的关系?

hashcode方法存在主要是提高判断对象是否相等的效率.

  • 当对象equals相等时,它们的hashcode一定相等
  • 当对象的hashcode相等时, 两个对象不一定相等
1.12 Java和C++的区别有哪些?
  • C++可多继承, Java只能单继承
  • C++可以通过指针访问一切, Java无
  • Java有垃圾自动回收机制, C++无
  • C++有预编译阶段, Java无
1.13 静态与非静态的区别?

静态 指以static关键字修饰的,包括类,方法,块,字段, 非静态 指没有用static 修饰的。

静态特点:

  • 全局唯一,任何一次的修改都是全局性的影响
  • 只加载一次,优先于非静态
  • 使用方式上不依赖于实例对象。
  • 生命周期属于类级别,从JVM 加载开始到JVM卸载结束。
1.14 Java中equals方法和==的区别?
  • == 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
  • equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。
1.15 BIO、NIO、AIO

详细查看

  1. BIO
    BIO 属于同步阻塞 IO 模型 。
    同步阻塞 IO 模型中,应用程序发起 read 调用后,会一直阻塞,直到在内核把数据拷贝到用户空间。在客户端连接数量不高的情况下,是没问题的。但是,当面对十万甚至百万级连接的时候, BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。

  2. NIO
    Java 中的 NIO 于 Java 1.4 中引入,对应 java.nio 包,提供了 Channel , Selector,Buffer 等抽象。NIO 中的 N 可以理解为 Non-blocking,不单纯是 New。它支持面向缓冲的,基于通道的 I/O 操作方法。 对于高负载、高并发的(网络)应用,应使用 NIO 。
    Java 中的 NIO 可以看作是 I/O 多路复用模型。也有很多人认为,Java 中的 NIO 属于同步非阻塞 IO 模型。

同步非阻塞 IO 模型中,应用程序会一直发起 read 调用,等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的,直到在内核把数据拷贝到用户空间。
相比于同步阻塞 IO 模型,同步非阻塞 IO 模型确实有了很大改进。通过轮询操作,避免了一直阻塞。
但是,这种 IO 模型同样存在问题:应用程序不断进行 I/O 系统调用轮询数据是否已经准备好的过程是十分消耗 CPU 资源的。

  1. AIO
    AIO 也就是 NIO 2。Java 7 中引入了 NIO 的改进版 NIO 2,它是异步 IO 模型。
    异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。

在这里插入图片描述

------------------------**持续更新中**-------------------
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yexiaomola

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值