黑马程序员Java进阶学习(三)

目录

异常

Java的异常体系

异常的基本处理

自定义异常

异常的处理方案

异常的两种处理方式

泛型

泛型类

泛型接口

泛型方法、通配符、上下限

集合框架

集合体系结构

Collection的常用功能

Collection的遍历三种方式

迭代器遍历

增强for循环

Lambda表达式

认识并发修改异常问题

​编辑

解决并发修改异常问题的方案

List集合

List集合的特有方法

List集合支持的遍历方式

ArrayList和LinkedList的区别

ArrayList的底层原理

LinkedList的底层原理

set集合

HashSet集合的底层原理

哈希表存储数据的详细流程

HashSet集合去重复的机制

TreeSet集合

Map集合

Map集合的常用方法

Map集合的遍历方式

File

File提供的判断文件类型、获取文件信息功能

File提供的创建和删除文件的方法

File提供的遍历文件夹的方法

递归

递归算法的三要素

字符

使用程序对字符进行编码和解码操作

IO流

IO流的分类

io流的体系

FileInputStream(文件字节输入流)

注意事项

一次读取完全部字节

FileOutputStream文件字节输出流

资源释放的方案

缓冲流

BufferedInputStream缓冲字节输入流

原始流、缓冲流的性能分析[重点]

InputStreamReader(字符输入转换流)

打印流

PrintStream和PrintWriter的区别

DataOutputStream(数据输出流)

DataInputStream(数据输入流)

IO框架

多线程

创建线程

多线程的创建方式一:继承Thread类

创建线程的注意事项

多线程的创建方式二:实现Runnable接口

匿名内部类写法

线程的创建方式三:实现Callable接口

三种线程的创建方式,和不同点?

线程的常用方法

Thread的常用方法

Thread的其他方法说明

线程安全

线程同步

线程同步的常见方案

加锁

同步代码块

同步方法

Lock锁

线程池

创建线程池

方式一:通过ThreadPoolExecutor创建线程池

ExecutorService的常用方法

线程池的注意事项

通过Executors创建线程池

Executors使用可能存在的陷阱

并发/并行

并发的含义

并行的理解

Java网络编程

基本的通信架构

Client-Server(CS)架构

Browser-Server(BS)架构

网络通信三要素

IP地址

IPv6

IP域名(Domain Name)

DNS域名解析(Domain Name System)

公网IP、内网IP

InetAddress

端口

协议

开放式网络互联标准:OSI网络参考模型

TCP协议

UDP通信的实现

使用UDP通信实现:发送消息、接收消息

实现UDP通信,如何创建客户端、服务端对象?

客户端可以反复发送数据

接收端可以反复接收数据

TCP通信的实现

TCP通信的实现一发一收-客户端开发

TCP通信的实现一发一收-服务端开发

多发多收是如何实现的?

同时接收多个客户端的消息

BS架构的原理

时间相关的获取方案

时间相关的获取方案

StringBuilder

BigDecimal

BigDecimal的常见构造器、常用方法

单元测试

Junit单元测试框架

Junit单元测试的使用步骤

反射(Reflection)

反射第一步:或者Class对象

反射获取类中的成分并操作

反射的基本作用有哪些?

使用反射做一个简易版的框架

注解概述

注解概述-自定义注解

注解概述-注解的原理

元注解

动态代理

如何为Java对象创建一个代理对象


异常

Java的异常体系

异常的基本处理

异常的作用

异常是什么?
异常是代码在编译或者执行的过程中可能出现的错误。
异常的代表是谁?分为几类?
Exception,分为两类:编译时异常、运行时异常。
编译时异常:没有继承RuntimeExcpetion的异常,编译阶段就会出错。
运行时异常:继承自RuntimeException的异常或其子类,编译阶段不报错,运行时出现的。
异常的作用是啥?
用来查找bug;可以作为方法内部的特殊返回值,通知上层调用者底层的执行情况。

自定义异常

异常的处理方案

异常的两种处理方式

泛型

泛型类

泛型接口

泛型方法、通配符、上下限

泛型支持的类型

集合框架

集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。

集合体系结构

Collection的常用功能

Collection的遍历三种方式

迭代器遍历

迭代器的执行流程

1、如何获取集合的迭代器? 迭代器遍历集合的代码具体怎么写?
Iterator<E> iterator():得到迭代器对象,默认指向当前集合的索引0

2、通过迭代器获取集合的元素,如果取元素越界会出现什么异常?
会出现NoSuchElementException异常。

增强for循环

Lambda表达式

认识并发修改异常问题

解决并发修改异常问题的方案

List集合

List集合的特有方法

List集合支持的遍历方式

for循环(因为List集合有索引)
迭代器
增强for循环
Lambda表达式

ArrayList和LinkedList的区别

ArrayList的底层原理

LinkedList的底层原理

基于双链表实现的。

set集合

HashSet集合的底层原理

哈希表存储数据的详细流程

 创建一个默认长度16,默认加载因为0.75的数组,数组名table
 根据元素的哈希值跟数组的长度计算出应存入的位置
 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素,  则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数组。
 当数组存满到16*0.75=12时,就自动扩容,每次扩容成原先的两倍

HashSet集合去重复的机制

TreeSet集合

自定义排序规则

小结:

TreeSet集合的特点是怎么样的?
可排序、不重复、无索引
底层基于红黑树实现排序,增删改查性能较好
TreeSet集合对自定义类型的对象排序,有几种方式指定比较规则?
2种。
类实现Comparable接口,重写比较规则。
集合自定义Comparator比较器对象,重写比较规则。

Map集合

Map集合是什么?什么时候可以考虑使用Map集合?
Map集合是键值对集合
需要存储一一对应的数据时,就可以考虑使用Map集合来做
Map集合的实现类有哪些?各自的特点是?
HashMap: 元素按照键是无序,不重复,无索引,值不做要求。
LinkedHashMap: 元素按照键是有序,不重复,无索引,值不做要求。
TreeMap:元素按照建是排序,不重复,无索引的,值不做要求。

Map集合的常用方法

Map集合的遍历方式

File

File提供的判断文件类型、获取文件信息功能

File提供的创建和删除文件的方法

File提供的遍历文件夹的方法

小结:

1、File类构建对象的方式是什么样的?File的对象可以代表哪些东西?
File file = new File(“文件/文件夹/绝对路径/相对路径”);
2、绝对路径和相对路径是什么意思?
绝对路径是带盘符的。
相对路径是不带盘符的,默认到当前工程下寻找文件。

小结:

创建多级目录使用哪个方法?
public boolean mkdirs()
删除文件需要注意什么?
可以删除文件、空文件夹。
默认不能删除非空文件夹。

如何遍历文件夹下的文件对象,使用哪个API,有什么特点?
public File[] listFiles()(常用)。
只能遍历当前文件夹对象下的一级文件对象。

递归

递归是一种算法,在程序设计语言中广泛应用。
从形式上说:方法调用自身的形式称为方法递归( recursion)。
递归的形式
直接递归:方法自己调用自己。
间接递归:方法调用其他方法,其他方法又回调方法自己。
使用方法递归时需要注意的问题:
递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。

tips:什么是递归死循环?
方法无限调用自己,无法终止,最终引起栈内存溢出。

递归算法的三要素

字符

使用程序对字符进行编码和解码操作

IO流

IO流的分类

小结:

IO流的作用?
读写文件数据的
IO流是怎么划分的,大体分为几类,各自的作用?
字节输入流 InputStream(读字节数据的)
字节输出流 OutputStream(写字节数据出去的)
字符输入流 Reader(读字符数据的)
字符输出流 Writer(写字符数据出去的)

io流的体系

FileInputStream(文件字节输入流)

注意事项

一次读取完全部字节

小结:

文件字节输入流,读取文件数据的步骤?
创建文件字节输入流管道与源文件接通.
如何使用字节输入流读取中文内容输出时不乱码呢?
一次性读取完全部字节。
直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?
如果文件过大,定义的字节数组可能引起内存溢出。

FileOutputStream文件字节输出流

小结:

字节流非常适合做文件的复制操作
任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,只要复制后的文件格式一致就没问题!

资源释放的方案

小结:

文件字符输入流的作用是啥?
可以用于读取文本文件中的字符,非常适合。
文件字符输入流如何读取数据?
创建FileReader的对象,调用其read方法读取字符。

缓冲流

BufferedInputStream缓冲字节输入流

作用:可以提高字节输入流读取数据的性能
原理:缓冲字节输入流自带了8KB缓冲池;缓冲字节输出流也自带了8KB缓冲池。

字节缓冲流如何使用?
public BufferedOutputStream​(OutputStream os)
public BufferedInputStream​(InputStream is)
功能上并无很大变化,性能提升了。

小结:

字符缓冲流有几种,作用是什么?
字符缓冲流自带8K缓冲区
可以提高原始字符流读写数据的性能
两种字符缓冲流如何使用?各自新增了什么功能?
public BufferedReader​(Reader r)
性能提升了,多了readLine()按照行读取的功能

public BufferedWriter​(Writer w)
性能提升了,多了newLine()换行的功能

原始流、缓冲流的性能分析[重点]

测试用例:
分别使用原始的字节流,以及字节缓冲流复制一个很大视频。
测试步骤:
使用低级的字节流按照一个一个字节的形式复制文件。
使用低级的字节流按照字节数组的形式复制文件。
使用高级的缓冲字节流按照一个一个字节的形式复制文件。
使用高级的缓冲字节流按照字节数组的形式复制文件。

推荐使用哪种方式提高字节流读写数据的性能?
建议使用字节缓冲输入流、字节缓冲输出流,结合字节数组的方式,目前来看是性能最优的组合。

InputStreamReader(字符输入转换流)

字符输入转换流InputStreamReader的作用是啥?
可以解决字符流读取不同编码乱码的问题
public InputStreamReader(InputStream is,String charset):
           可以指定编码把原始字节流转换成字符流,如此字符流中的字符不乱码。

打印流

PrintStream和PrintWriter的区别

打印数据的功能上是一模一样的:都是使用方便,性能高效(核心优势)
PrintStream继承自字节输出流OutputStream,因此支持写字节数据的方法。
PrintWriter继承自字符输出流Writer,因此支持写字符数据出去。

小结:

打印流有几种?各有什么特点?
打印流一般是指:PrintStream,PrintWriter两个类。
打印功能2者是一样的使用方式
PrintStream继承自字节输出流OutputStream,支持写字节
PrintWrite继承自字符输出流Writer,支持写字符
打印流的优势是什么?
两者在打印功能上都是使用方便,性能高效(核心优势)

DataOutputStream(数据输出流)

DataInputStream(数据输入流)

IO框架

封装了Java提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等。

多线程

创建线程

多线程的创建方式一:继承Thread类

创建线程的注意事项

多线程的创建方式二:实现Runnable接口

匿名内部类写法

1.可以创建Runnable的匿名内部类对象。
2.再交给Thread线程对象。
3.再调用线程对象的start()启动线程。

线程的创建方式三:实现Callable接口

多线程第三种创建方式:利用Callable接口、FutureTask类来实现

三种线程的创建方式,和不同点?

线程的常用方法

Thread的常用方法

Thread的其他方法说明

Thread类还提供了诸如:yield、interrupt、守护线程、线程优先级等线程的控制方法,在开发中很少使用,这些方法会后续需要用到的时候再讲解。

线程安全

多个线程,同时操作同一个共享资源的时候,可能会出现业务安全问题。

线程安全问题出现的原因?
存在多个线程在同时执行
同时访问一个共享资源
存在修改该共享资源

线程同步

线程同步是线程安全问题的解决方案。

线程同步的核心思想——让多个线程先后依次访问共享资源,这样就可以避免出现线程安全问题。

线程同步的常见方案

加锁

每次只允许一个线程加锁,加锁后才能进入访问,访问完毕后自动解锁,然后其他线程才能再加锁进来。

同步代码块

同步方法

同步代码块好还是同步方法好?
范围上:同步代码块锁的范围更小,同步方法锁的范围更大
可读性:同步方法更好

Lock锁

锁对象建议加上什么修饰?
建议使用final修饰,防止被别人篡改
释放锁的操作建议放到哪里?
建议将释放锁的操作放到finally代码块中,确保锁用完了一定会被释放

线程池

    线程池就是一个可以复用线程的技术。

不使用线程池的问题  
    用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,  创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能。

创建线程池

方式一:通过ThreadPoolExecutor创建线程池

谁代表线程池?线程池的创建方案有几种?
ExecutorService接口
ThreadPoolExecutor实现线程池对象的七个参数是什么意思?
使用线程池的实现类ThreadPoolExecutor

ExecutorService的常用方法

线程池的注意事项

线程池如何处理Runnable任务?
使用ExecutorService的方法:
void  execute(Runnable target)

线程池如何处理Callable任务,并得到任务执行完后返回的结果?
使用ExecutorService的方法:
Future<T> submit(Callable<T> command)

通过Executors创建线程池

Executors使用可能存在的陷阱

Executors工具类底层是基于什么方式实现的线程池对象?
线程池ExecutorService的实现类:ThreadPoolExecutor
Executors是否适合做大型互联网场景的线程池方案?
不合适。
建议使用ThreadPoolExecutor来指定线程池参数,这样可以明确线程池的运行规则,规避资源耗尽的风险。

并发/并行

正在运行的程序(软件)就是一个独立的进程。
线程是属于进程的,一个进程中可以同时运行很多个线程。
进程中的多个线程其实是并发和并行执行的。

并发的含义

并行的理解

简单说说多线程是怎么执行的?
并发和并行同时进行的
并发:CPU分时轮询的执行线程。
并行:同一个时刻同时在执行。

Java网络编程

可以让设备中的程序与网络上其他设备中的程序进行数据交互的技术(实现网络通信)。

基本的通信架构

基本的通信架构有2种形式:CS架构( Client客户端/Server服务端 ) 、 BS架构(Browser浏览器/Server服务端)。

Client-Server(CS)架构

Browser-Server(BS)架构

网络通信三要素

IP地址

设备在网络中的地址,是设备在网络中的唯一标识

IPv6

IP域名(Domain Name)

DNS域名解析(Domain Name System)

公网IP、内网IP

InetAddress

Java中,哪个类代表IP地址?
InetAddress
怎样获得本机IP对象?
InetAddress ip1 = InetAddress.getLocalHost();

端口

应用程序在设备中的唯一标识

用来标记标记正在计算机设备上运行的应用程序,被规定为一个 16 位的二进制,范围是 0~65535。

端口号的作用是什么?
唯一标识正在计算机设备上运行的进程(程序)
一个设备中,能否出现2个应用程序的端口号一样,为什么?
不可以,如果一样会出现端口冲突错误。

协议

连接和数据在网络中传输的规则。

网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。

开放式网络互联标准:OSI网络参考模型

传输层的2个通信协议

通信协议是什么?
计算机网络中,连接和通信数据的规则被称为网络通信协议。
UDP协议有什么特点?
用户数据报协议(User Datagram Protocol)
UDP是面向无连接,不可靠传输的通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据。

TCP协议

TCP协议有哪些特点?
TCP是一种面向连接的可靠通信协议
传输前,采用“三次握手”方式建立连接,点对点的通信。
在连接中可进行大数据量的传输。
传输后,采用“四次挥手”方式断开连接,确保消息全部收发完毕。
通信效率相对较低,可靠性相对较高。

UDP通信的实现

使用UDP通信实现:发送消息、接收消息


实现UDP通信,如何创建客户端、服务端对象?

public DatagramSocket()​:创建发送端的Socket对象
public DatagramSocket(int port):创建接收端的Socket对象
数据包对象是哪个?
DatagramPacket
如何发送、接收数据?
使用DatagramSocket的如下方法:
public void send(DatagramPacket dp):发送数据包
public void receive(DatagramPacket dp) :接收数据包

客户端可以反复发送数据

客户端实现步骤
创建DatagramSocket对象(发送端对象
使用while死循环不断的接收用户的数据输入,如果用户输入的exit则退出程序
如果用户输入的不是exit,  把数据封装成DatagramPacket
使用DatagramSocket对象的send方法将数据包对象进行发送
释放资源

接收端可以反复接收数据

UDP的接收端为什么可以接收很多发送端的消息?
接收端只负责接收数据包,无所谓是哪个发送端的数据包。

TCP通信的实现

TCP通信的实现一发一收-客户端开发

TCP通信的实现一发一收-服务端开发


TCP通信,客户端的代表类是谁?
Socket类
public Socket(String host , int port)
TCP通信,如何使用Socket管道发送、接收数据 ?
OutputStream getOutputStream():获得字节输出流对象(发)
InputStream getInputStream():获得字节输入流对象(收)
TCP通信服务端用的类是谁?
ServerSocket类,注册端口。
调用accept()方法阻塞等待接收客户端连接。得到Socket对象。

多发多收是如何实现的?

客户端使用循环反复地发送消息。
服务端使用循环反复地接收消息。

同时接收多个客户端的消息

目前我们开发的服务端程序,是否可以支持同时与多个客户端通信 ?
不可以
因为服务端现在只有一个主线程,只能处理一个客户端的消息。

TCP通信-支持与多个客户端同时通信

本次是如何实现服务端同时接收多个客户端的消息的?
主线程定义了循环负责接收客户端Socket管道连接
每接收到一个Socket通信管道后分配一个独立的线程负责处理它。

BS架构的原理

要求从浏览器中访问服务器
并立即让服务器响应一个很简单的网页给浏览器展示
网页内容就是“听黑马磊哥讲Java”

1、BS架构的基本原理是什么?
客户端使用浏览器发起请求(不需要开发客户端)
服务端必须按照HTTP协议响应数据。

时间相关的获取方案

时间相关的获取方案

StringBuilder

BigDecimal

BigDecimal的常见构造器、常用方法

BigDecimal的作用是什么 ?
解决浮点型运算时,出现结果失真的问题。
应该如何把浮点型转换成BigDecimal的对象?
BigDecimal b1 = BigDecimal.valueOf(0.1)
BigDecimal提供了哪些常见的方法 ?

单元测试

就是针对最小的功能单元:方法,编写测试代码对其进行正确性测试。

Junit单元测试框架

Junit单元测试的使用步骤

Junit单元测试是做什么的?
测试类中方法的正确性的。
Junit单元测试的优点是什么?
JUnit可以选择执行哪些测试方法,可以一键执行全部测试方法的测试。
 JUnit可以生测试报告,如果测试良好则是绿色;如果测试失败,则是红色。
单元测试中的某个方法测试失败了,不会影响其他测试方法的测试。

JUnit单元测试的实现过程是什么样的?
必须导入Junit框架的jar包。
定义的测试方法必须是无参数无返回值,且公开的方法。
测试方法使用@Test注解标记。
JUnit测试某个方法,测试全部方法怎么处理?成功的标志是什么
测试某个方法直接右键该方法启动测试。
测试全部方法,可以选择类或者模块启动。
红色失败,绿色通过。

反射(Reflection)

反射第一步:或者Class对象

反射获取类中的成分并操作

反射的基本作用有哪些?

使用反射做一个简易版的框架

反射有啥作用?
可以在运行时得到一个类的全部成分然后操作。
可以破坏封装性。(很突出)
也可以破坏泛型的约束性。(很突出)
更重要的用途是适合:做Java高级框架
基本上主流框架都会基于反射设计一些通用技术功能。

注解概述

注解概述-自定义注解

注解概述-注解的原理

注解的作用
对Java中类、方法、成员变量做标记,然后进行特殊处理。
例如:JUnit框架中,标记了注解@Test的方法就可以被当成测试方法执行,而没有标记的就不能当成测试方法执行

元注解

元注解是什么?各自的作用是什么?
注解注解的注解
 @Target约束自定义注解可以标记的范围。 @Retention用来约束自定义注解的存活范围。

注解的解析

动态代理

如何为Java对象创建一个代理对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值