2020-7-20 永不停歇的java基础之路
三大基本特征
封装(Encapsulation)
客观事物封装成抽象的类
继承(Inheritance)
无需修改原类的情况下对其功能进行扩展
多态(Polymorphism)
一个类实例的相同方法在不同情形有不同表现形式(钩子函数)
(设计模式)五大基本原则
单一职责原则
一个类,最好只做一件事,只有一个引起它的变化(将功能尽量的细分,然后封装为类)
好处:好复用 好修改
开放封闭原则(Open-Closed principle)
对扩展开放,对修改封闭(抽象 不可修改 (继承覆盖,钩子函数,工厂方法)扩展)
好处:好复用 好修改
Liskov替换原则(Liskov-Substitution Principle)里氏替换
好处:报错少
依赖倒置原则(Dependecy-Inversion Principle)
依赖于抽象(是分离接口和实现)对接口编程
好处:系统稳定,解耦
接口隔离原则(Interface-Segregation Principle)
实现多个接口来分解接口最小化
复用的俩种方式
* 继承
* 组合(包含关系)
不能使用组合的情况
平台无关
编译
参数和值
形参和实参
值传递和引用传递
基本数据类型
包装类
有些东西只能使用Object类型 基本类型不能使用
在集合类中,我们是无法将int 、double等类型放进去的。因为集合的容器要求元素是Object类型。
包装类的转化
自动装箱 通过包装类的valueOf()方法来实现的.
自动拆箱 通过包装类对象的xxxValue()来实现的。
字符串
String是Java中一个不可变的类,所以他一旦被实例化就无法被修改。
拼接字符串的几种方式: String: + concat()
(字符串变量-可以扩充和修改的拼接)
StringBuffer StringBuilder apache.commons中提供的StringUtils.join类
循环体中不适合使用+拼接
常量池:字符串常量池、Class常量池和运行时常量池
Classs常量池 字节码文件有一个主要保存的是字面量和符号引用的地方
字面量:字母、数字等构成的字符串或者数值
符号引用:* 类和接口的全限定名 * 字段的名称和描述符 * 方法的名称和描述符
集合
通用接口
Collection 是集合对象进行基本操作的通用接口
Collections 是一个包装类 包含集合操作的静态多态方法
List和Set
List特点:元素 有序 可重复
ArrayList 是一个可改变大小的数组
LinkedList 是一个双链表
Vector 和ArrayList类似,但属于强同步类
SynchronizedList和Vector最主要的区别:
1.SynchronizedList有很好的扩展和兼容功能。他可以将所有的List的子类转成线程安全的类。
2.使用SynchronizedList的时候,进行遍历时要手动进行同步处理。
3.SynchronizedList可以指定锁定的对象
Set特点:元素 无序,不可重复
TreeSet 是二叉树实现的
HashSet底层是用HashMap存储数据的
stream管道
Apache Commons Collections
Bag定义了一个集合,用于计算对象在集合中出现的次数
BidiMap 可以使用值查找键
MapIterator提供了对Map的简单迭代
OrderedMap是地图的新接口,用于保留添加元素的顺序
遍历
CME报错(ConcurrentModificationException()
如何避免:
public static void main(String[] args) {
List<String> userNames = new CopyOnWriteArrayList<String>() {{
add("Hollis");
add("hollis");
add("HollisChuang");
add("H");
}};
userNames.iterator();
for (String userName : userNames) {
if (userName.equals("Hollis")) {
userNames.remove(userName);
}
}
System.out.println(userNames);
}
使用CopyOnWriteArrayList代替了ArrayList,就不会发生异常、
使用普通for循环(需要改下标)
直接使用Iterator进行操作
fail-safe机制的集合类
枚举
优点:类型安全性和程序可读性好(相对于常量)
![](https://img2020.cnblogs.com/blog/2071647/202007/2071647-20200721191639786-1842467807.png)
一个类型就是一个枚举的实例 enum就和class一样,只是一个关键字,他并不是一个类
枚举的序列化
枚举实现的单例是最好的
枚举的单例模式
IO流
字符流(8 读写))>字节流(输入 输出)
所有 I/O 都被视为单个的字节的移动,通过一个称为 Stream 的对象一次移动一个字节。流 I/O 用于与外部世界接触。它也在内部使用,用于将对象转换为字节,然后再转换回对象
相互转化
inputSteamReader OutputStreamWriter
反射(工厂模式)
只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法
通过Class类我们可以获得关于一个类的相关信息
动态代理
运行时确定代理类
反射是动态代理的一种实现方式
动态代理的二种实现方法
序列化
将对象转换为可传输格式(以字节码或XML格式传输)的过程。 是一种数据的持久化手段。
一般广泛应用于网络传输,RMI和RPC等场景中
其实就是对象变成文件数据 然后可以转化回去
应用
使对象在程序停止的时候保存下来。
使用步骤
javaBean实现了java.io.Serializable
创建文件流来读(反序列化)写(序列化)
Externalizable接口的序列化
如果只打算实例化部分属性可以使用这个接口并且重写其方法
注解
元注解
定义注解的使用范围
元注解有四个:
@Target(表示该注解可以用于什么地方)、
@Retention(表示再什么级别保存该注解信息)、
@Documented(将此注解包含再javadoc中) 、
@Inherited(允许子类继承父类中的注解)。
java注解和spring注解
注解实例
泛型
单元测试
正则表达式
API和SPI
异常
时间处理
编码
语法糖
java并发编程
进程和线程
sleep() 方法和 wait()
sleep 方法没有释放锁,而 wait 方法释放了锁( notify() 或者 notifyAll()唤醒)
死锁
乐观锁和悲观锁
自旋锁就是CAS算法 无锁编程,即不使用锁的情况下实现多线程之间的变量同步
start 和run
synchronized
synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行
双重校验锁实现对象单例(线程安全)
volatile
指示 JVM,这个变量是不稳定的,每次使用它都到主存中进行读取 (默认是去本地内存(寄存器中读取))
三个重要特性
线程池
Runnable 的 execute() 和submit()
创建
底层原理
程序计数器
程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器
Java 虚拟机栈
Java 方法执行的内存模型,每次(字节码)方法调用的数据都是通过栈传递的。
本地方法栈
本地方法栈则为虚拟机使用到的 Native 方法服务
堆
此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存
方法区
方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
设计模式
网络编程
协议
协议就是一条报文需要遵守的东西
应用层
应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用
用层协议很多,如域名系统DNS,支持万维网应用的 HTTP协议,支持电子邮件的 SMTP协议等等。我们把应用层交互的数据单元称为报文
运输层
负责向两台主机进程之间的通信提供通用的数据传输服务
网络层
计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送
在 TCP/IP 体系结构中,由于网络层使用 IP 协议,因此分组也叫 IP 数据报 ,简称 数据报
数据链路层
两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议
物理层
实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异
tcp 三次握手 四次回收
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
TCP(可靠) UDP (可靠)
UDP 在传送数据之前不需要先建立连接
ARQ协议
自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一
ARP
IP地址转化为MAC地址
打开一次网页用几个协议