From 0f46b02d0f0343848e84a03320bc16c335e5cb48 Mon Sep 17 00:00:00 2001 From: SnailClimb Date: Mon, 6 May 2019 14:08:20 +0800 Subject: [PATCH] =?UTF-8?q?Update=20Java=E5=9F=BA=E7=A1=80=E7=9F=A5?= =?UTF-8?q?=E8=AF=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/java/Java基础知识.md | 104 +++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 38 deletions(-) diff --git a/docs/java/Java基础知识.md b/docs/java/Java基础知识.md index 3b49a6a1..11b1e4e3 100644 --- a/docs/java/Java基础知识.md +++ b/docs/java/Java基础知识.md @@ -1,59 +1,59 @@ - - - + - [1. 面向对象和面向过程的区别](#1-面向对象和面向过程的区别) - - [面向过程](#面向过程) - - [面向对象](#面向对象) -- [2. Java 语言有哪些特点](#2-java-语言有哪些特点) + - [面向过程](#面向过程) + - [面向对象](#面向对象) +- [2. Java 语言有哪些特点?](#2-java-语言有哪些特点) - [3. 关于 JVM JDK 和 JRE 最详细通俗的解答](#3-关于-jvm-jdk-和-jre-最详细通俗的解答) - - [JVM](#jvm) - - [JDK 和 JRE](#jdk-和-jre) + - [JVM](#jvm) + - [JDK 和 JRE](#jdk-和-jre) - [4. Oracle JDK 和 OpenJDK 的对比](#4-oracle-jdk-和-openjdk-的对比) -- [5. Java和C++的区别](#5-java和c的区别) -- [6. 什么是 Java 程序的主类 应用程序和小程序的主类有何不同](#6-什么是-java-程序的主类-应用程序和小程序的主类有何不同) -- [7. Java 应用程序与小程序之间有那些差别](#7-java-应用程序与小程序之间有那些差别) -- [8. 字符型常量和字符串常量的区别](#8-字符型常量和字符串常量的区别) -- [9. 构造器 Constructor 是否可被 override](#9-构造器-constructor-是否可被-override) +- [5. Java和C++的区别?](#5-java和c的区别) +- [6. 什么是 Java 程序的主类 应用程序和小程序的主类有何不同?](#6-什么是-java-程序的主类-应用程序和小程序的主类有何不同) +- [7. Java 应用程序与小程序之间有那些差别?](#7-java-应用程序与小程序之间有那些差别) +- [8. 字符型常量和字符串常量的区别?](#8-字符型常量和字符串常量的区别) +- [9. 构造器 Constructor 是否可被 override?](#9-构造器-constructor-是否可被-override) - [10. 重载和重写的区别](#10-重载和重写的区别) - [11. Java 面向对象编程三大特性: 封装 继承 多态](#11-java-面向对象编程三大特性-封装-继承-多态) - - [封装](#封装) - - [继承](#继承) - - [多态](#多态) -- [12. String StringBuffer 和 StringBuilder 的区别是什么 String 为什么是不可变的](#12-string-stringbuffer-和-stringbuilder-的区别是什么-string-为什么是不可变的) + - [封装](#封装) + - [继承](#继承) + - [多态](#多态) +- [12. String StringBuffer 和 StringBuilder 的区别是什么? String 为什么是不可变的?](#12-string-stringbuffer-和-stringbuilder-的区别是什么-string-为什么是不可变的) - [13. 自动装箱与拆箱](#13-自动装箱与拆箱) -- [14. 在一个静态方法内调用一个非静态成员为什么是非法的](#14-在一个静态方法内调用一个非静态成员为什么是非法的) +- [14. 在一个静态方法内调用一个非静态成员为什么是非法的?](#14-在一个静态方法内调用一个非静态成员为什么是非法的) - [15. 在 Java 中定义一个不做事且没有参数的构造方法的作用](#15-在-java-中定义一个不做事且没有参数的构造方法的作用) -- [16. import java和javax有什么区别](#16-import-java和javax有什么区别) -- [17. 接口和抽象类的区别是什么](#17-接口和抽象类的区别是什么) -- [18. 成员变量与局部变量的区别有那些](#18-成员变量与局部变量的区别有那些) +- [16. import java和javax有什么区别?](#16-import-java和javax有什么区别) +- [17. 接口和抽象类的区别是什么?](#17-接口和抽象类的区别是什么) +- [18. 成员变量与局部变量的区别有那些?](#18-成员变量与局部变量的区别有那些) - [19. 创建一个对象用什么运算符?对象实体与对象引用有何不同?](#19-创建一个对象用什么运算符对象实体与对象引用有何不同) - [20. 什么是方法的返回值?返回值在类的方法里的作用是什么?](#20-什么是方法的返回值返回值在类的方法里的作用是什么) -- [21. 一个类的构造方法的作用是什么 若一个类没有声明构造方法,该程序能正确执行吗 ?为什么?](#21-一个类的构造方法的作用是什么-若一个类没有声明构造方法该程序能正确执行吗-为什么) -- [22. 构造方法有哪些特性](#22-构造方法有哪些特性) +- [21. 一个类的构造方法的作用是什么? 若一个类没有声明构造方法,该程序能正确执行吗? 为什么?](#21-一个类的构造方法的作用是什么-若一个类没有声明构造方法该程序能正确执行吗-为什么) +- [22. 构造方法有哪些特性?](#22-构造方法有哪些特性) - [23. 静态方法和实例方法有何不同](#23-静态方法和实例方法有何不同) -- [24. 对象的相等与指向他们的引用相等,两者有什么不同?](#24-对象的相等与指向他们的引用相等两者有什么不同) -- [25. 在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?](#25-在调用子类构造方法之前会先调用父类没有参数的构造方法其目的是) -- [26. == 与 equals\(重要\)](#26--与-equals重要) -- [27. hashCode 与 equals \(重要\)](#27-hashcode-与-equals-重要) - - [hashCode()介绍](#hashcode()介绍) - - [为什么要有 hashCode](#为什么要有-hashcode) - - [hashCode()与equals()的相关规定](#hashcode()与equals()的相关规定) -- [28. 为什么Java中只有值传递](#28-为什么java中只有值传递) -- [29. 简述线程,程序、进程的基本概念。以及他们之间关系是什么](#29-简述线程程序进程的基本概念以及他们之间关系是什么) +- [24. 对象的相等与指向他们的引用相等,两者有什么不同?](#24-对象的相等与指向他们的引用相等两者有什么不同) +- [25. 在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?](#25-在调用子类构造方法之前会先调用父类没有参数的构造方法其目的是) +- [26. == 与 equals(重要)](#26--与-equals重要) +- [27. hashCode 与 equals (重要)](#27-hashcode-与-equals-重要) + - [hashCode()介绍](#hashcode介绍) + - [为什么要有 hashCode](#为什么要有-hashcode) + - [hashCode()与equals()的相关规定](#hashcode与equals的相关规定) +- [28. 为什么Java中只有值传递?](#28-为什么java中只有值传递) +- [29. 简述线程、程序、进程的基本概念。以及他们之间关系是什么?](#29-简述线程程序进程的基本概念以及他们之间关系是什么) - [30. 线程有哪些基本状态?](#30-线程有哪些基本状态) - [31 关于 final 关键字的一些总结](#31-关于-final-关键字的一些总结) - [32 Java 中的异常处理](#32-java-中的异常处理) - - [Java异常类层次结构图](#java异常类层次结构图) - - [Throwable类常用方法](#throwable类常用方法) - - [异常处理总结](#异常处理总结) -- [33 Java序列化中如果有些字段不想进行序列化 怎么办](#33-java序列化中如果有些字段不想进行序列化-怎么办) + - [Java异常类层次结构图](#java异常类层次结构图) + - [Throwable类常用方法](#throwable类常用方法) + - [异常处理总结](#异常处理总结) +- [33 Java序列化中如果有些字段不想进行序列化,怎么办?](#33-java序列化中如果有些字段不想进行序列化怎么办) - [34 获取用键盘输入常用的的两种方法](#34-获取用键盘输入常用的的两种方法) +- [35 Java 中 IO 流分为几种?BIO,NIO,AIO 有什么区别?](#35-java-中-io-流分为几种bionioaio-有什么区别) + - [java 中 IO 流分为几种?](#java-中-io-流分为几种) + - [BIO,NIO,AIO 有什么区别?](#bionioaio-有什么区别) - [参考](#参考) - [公众号](#公众号) - - + ## 1. 面向对象和面向过程的区别 @@ -469,6 +469,34 @@ BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); String s = input.readLine(); ``` +## 35 Java 中 IO 流分为几种?BIO,NIO,AIO 有什么区别? + +### java 中 IO 流分为几种? + + - 按照流的流向分,可以分为输入流和输出流; + - 按照操作单元划分,可以划分为字节流和字符流; + - 按照流的角色划分为节点流和处理流。 + +Java Io流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。 + + - InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。 + - OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。 + +按操作方式分类结构图: + +![按操作方式分类结构图:](https://user-gold-cdn.xitu.io/2018/5/16/16367d4fd1ce1b46?w=720&h=1080&f=jpeg&s=69522) + + +按操作对象分类结构图 + +![按操作对象分类结构图](https://user-gold-cdn.xitu.io/2018/5/16/16367d673b0e268d?w=720&h=535&f=jpeg&s=46081) + +### BIO,NIO,AIO 有什么区别? + +- **BIO (Blocking I/O):** 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。 +- **NIO (New I/O):** NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 `Socket` 和 `ServerSocket` 相对应的 `SocketChannel` 和 `ServerSocketChannel` 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发 +- **AIO (Asynchronous I/O):** AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。 + ## 参考 - https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jre