夯实基础系列一:Java 基础总结
2018-09-19 22:54
381 查看
前言
大学期间接触 Java 的时间也不短了,不论学习还是实习,都让我发觉基础的重要性。互联网发展太快了,各种框架各种技术更新迭代的速度非常快,可能你刚好掌握了一门技术的应用,它却已经走在淘汰的边缘了。
而学习新技术总要付出一定的时间成本,那么怎么降低时间成本呢?那就是打好基础,技术再怎么革新,底层的东西也很少会变动,牢固的基础会帮助你在各种新技术的学习中游刃有余,快速上手。
因为我选择的方向是后台开发,所以谈谈我认为的基础有哪些。其他方向肯定也有自己的体系,从低层到高层,可以自己摸索。后台的话,我觉得网络知识,各种协议,web 知识,数据库知识,Linux 基本操作以及自己选择的后台语言知识,这些是最基础最需要牢固掌握的。
所以从今天起,会出一系列与后台基础相关的博文,一是对自己过去学习的一个总结,二是分享出来,希望可以帮助到需要的人。
概要
Java 基础我做了 10 个方面的总结,包括基本概念,面向对象,关键字,基本类型与运算,字符串与数组,异常处理,Java 平台与内存管理,分布式 Java 应用,多线程,IO。以下对这些内容做一些简单的总结,同时我也有完整的思维导图,博客上不方便展示,若有需要,请关注微信公众号永伦的小屋,后台回复 Java 即可获取。
细节
1. 基本概念
1.1 语言特点
- 纯面向对象
- 平台无关性
- 内置类库
- 支持web
- 安全性 防止代码攻击
-
强类型机制
1.2 与C++比较
- 解释编译混合型语言,执行速度慢,跨平台
- 纯面向对象,只有类,不存在全局变量或全局函数
- 无指针,无多继承,可多实现
- 垃圾回收器自动管理内存
1.3 main函数知识
- Java程序入口方法
- 可由final,synchronized修饰,不能用abstract
1.4 Java程序初始化顺序
- 静态优于非静态
- 父类优于子类
- 按照成员变量的定义顺序
- 总共10个
1.5 作用域与可见性
- 静态变量属于类
- 局部变量属于花括号
- 成员变量看下一条
- public、protected、default、private 可见性依次递减
1.6 构造函数
- 与类名相同,无返回值
- 可重载,不能被继承,即不能被覆盖
- 参数个数任意
- 伴随new 一起调用,为系统调用
- 完成对象的初始化工作
- 子类可通过super显式调用父类。父类没有提供无参,子类必须显式调用
- 未定义,默认无参,修饰符取决于类修饰符
1.7 标识接口
- 无任何方法声明
- 表示实现它的类属于一个特定的类型
1.8 clone 方法
- 实现Cloneable接口
- 重写Object类中的clone()
- clone()中调用super.clone()
- 把浅复制引用指向新的克隆体
1.9 反射
- 定义:允许程序在运行时进行自我检查,也允许对其内部成员进行操作
- 功能 得到一个对象所属的类
- 获取一个类的所有成员和方法
- 运行时创建对象
- 在运行时调用对象的方法
-
class.forName("类路径")
1.10 创建对象的四种方式
- new
- 反射机制
- clone()
- 反序列化
1.11 package 作用
- 提供多层命名空间,解决命名冲突
- 对类按功能进行分类,使项目组织更加清晰
2. 面向对象
2.1 与面向过程区别
- 层次逻辑关系不同。 面向对象是通过类的层次结构来体现类之间的继承与发展
- 面向过程是通过模块的层次结构概括模块与模块间的关系与功能
-
面向对象是数据与操作封装成一个整体,通过事件驱动来激活和运行程序
2.2 特性
- 抽象
- 继承
- 多态
- 封装
2.3 这种开发方式优点
- 开发效率高。代码重用
- 保证软件的鲁棒性。经过长期测试的已有代码
- 保证软件的高可维护性。设计模式成熟
2.4 继承
- 单继承
- 只能继承父类的非私有成员变量和方法
- 同名成员变量,子类覆盖,不会继承
- 相同函数签名,子类覆盖,不会继承
2.5 组合和继承区别
- 组合:在新类中创建原有类的对象。has a
- 继承是 is a
2.6 多态
- 方法重载 编译时多态
-
运行时多态
2.7 覆盖和重载区别
- 子父类关系,垂直;同类方法间关系,水平
- 一对方法发生关系;多个方法发生关系
- 参数列表相同;参数列表不同
- 调用的方法根据对象的类型决定;根据调用时的实参表决定方法体
2.8 抽象类与接口异同
同
- 不能被实例化
- 接口的实现类实现了接口,抽象类的子类实现了方法,才能被实例化
异
- 接口只能定义方法,不能实现;抽象类可以有定义和实现
- 接口需要被实现;抽象类需要被继承
- 接口强调特定功能的实现;抽象类强调所属关系
- 接口成员变量默认为 public static final,成员方法 public abstract
- 抽象类变量默认default,方法不能用 private、static、synchronized、native 修饰
2.9 内部类
- 静态内部类 static 修饰
- 只能访问外部类中的static数据
-
与实例绑定
-
代码块内
-
无类名
2.10 如何获取父类类名
- 利用反射:obj.getClass().getSuperClass().getName()
- 不使用super.getClass()原因:该方法在 Object中为final与native,子类不能覆盖,返回此Object运行时类
2.11 this
- 指向当前实例对象
- 区分成员变量与方法形参
2.12 super
- 访问父类成员变量或方法
- 子类同名会覆盖,访问父类只能通过super
- 子类构造函数需显示调用父类构造函数时,super()必须为构造函数的第一条语句
3. 关键字
3.1 变量命名
- 英文字母
- 数字
- _和$
- 不能包含空白字符
- 首字符不能为数字
- 保留字不能做标识符
- 区分大小写
3.2 assert
- 软件调试
- 运行时开启 -ea
3.3 static
- 特定类的统一存储空间,类绑定
- 成员变量:属于类,内存中只有一个复制
- 成员方法:调静态数据。可实现单例模式
- 代码块:初始化静态变量,只被执行一次
- 内部类:不能与外部类重名,只能访问外部类静态数据(包括私有)
3.4 switch
- 多分支选择
- 整型或字符类型变量或整数表达式
- Java 7 开始支持 String。原理是String的hashCode()返回的int类型值匹配
3.5 volatile
- 保证线程间的可见性
- 从内存中取数据,而不是缓存
- 不保证原子性
3.6 instanceof
- 二元运算符
- 判断一个引用类型的变量所指向的对象是否是一个类的实例
- 即左边对象是否是右边类的实例
3.7 strictfp
- 精确浮点
- 确保浮点运算的准确性
- 若不指定,结果依赖于虚拟机平台
- 指定后依赖于统一标准,保证各平台的一致性
3.8 null
- 不是合法的Object实例
- 无内存
- 表明该引用目前没有指向任何对象
4. 基本类型与运算
4.1 基本数据类型
- int长度 byte(8 bit)
- short(16 bit)
- int(32 bit)
- long(64 bit)
-
单精度(32 bit float)
-
true
4.2 不可变类
- 实例创建后,值不可变
- 所有的基本类型的包装类+String
- 优点 使用简单
- 线程安全
- 节省内存
4.3 类型转换
- 隐式类型转换 低精度到高精度
- byte->short->char->int->long->float->double
-
反之
-
低到高
运算符优先级
点 () [] +(正) -(负) ++ -- ~ ! * / % +(加) -(减) << >> >>> < <= > >= instanceof == != & | ^ && || ?: = += -= *= /= %= &= |= ^= ~= <<= >>= >>>=
5. 字符串与数组
5.1 字符串创建与存储机制
- 堆
- 常量池
- new String("abc")创建1个或2个对象
5.2 ==、equals和hashCode区别
- == 比较引用,内存
- 未覆盖,同==;比较内容
- hashCode鉴定对象是否相等,返回整数
5.3 String,StringBuffer,StringBuilder
- String:不可变,执行效率最低
- StringBuffer:可修改,线程安全,效率较高
- StringBuilder:可修改,线程不安全,效率最高
5.4 其他
- 数组初始化方式
- length属性和length()方法
6. 异常处理
6.1 finally块执行时机
- 若try中有return,在return前
- 若try-finally或catch-finally中都有return,finally会覆盖
6.2 finally代码块不是一定会被执行
- 程序进入try之前出现异常
- try中调用System.exit(0)
6.3 Error
严重错误,不可恢复
6.4 Exception
- 可恢复,编译器可捕捉
- 检查性异常 IO
- SQL
-
JVM处理
7. Java平台与内存管理
7.1 Java平台与其他语言平台的区别
- 纯软件,包括JVM与JAVA API
- JVM虚拟,不跨平台
7.2 JAVA代码的执行
- 代码编译为class:sun jdk 中javac
- 装载class:ClassLoader
- 执行class 解释执行
- 编译执行 client compiler
- server compiler
7.3 java源码编译机制
- 词法分析器组件:Token流
- 语法分析器组件:语法树
- 语义分析器组件:注解语法树 将语法树中的名字、表达式等元素与变量、方法、类型等联系到一起
- 检查变量使用前是否已声明
- 推导泛型方法的类型参数
- 检查类型匹配性
- 进行常量折叠
- 检查所有语句都可到达
- 检查变量的确定性赋值
- 解除语法糖
- 将泛型JAVA转成普通Java
- 检查所有checked exception都被捕获或抛出
- 将含语法糖的语法树转成简单语法树eg:foreach,自动折叠
7.4 类加载机制
- 装载:全限定名+类加载器加载类
- 链接 校验 格式不符,抛VerifyError
- 加载引用的类失败:抛NoClassDefFoundError
-
静态初始化代码
7.5 类执行机制
- 解释执行 JVM字节码为中间代码,由JVM在运行期对其解释并执行 invokestatic
- invokevirtual
- invokeinterface
- invokespecial
-
代码紧凑,体积小
-
client compiler
轻量级,占内存少
-
重量级,占内存多
7.6 内存空间
- 方法区:类信息,线程共享
- 堆 对象实例+数组
- 分代管理 新生代
- 旧生代
7.7 内存分配
- Java对象,堆上分配,分配需加锁,开销大
- 当堆上空间不足-->GC-->仍不足-->抛OutOfMemory
- Sun JDK 为新创建的线程在Eden上分配TLAB
- 多个小对象比大对象分配更高效
- 基于逃逸分析直接从栈上分配
7.8 内存回收
- 收集器 引用计数收集器 计数器增减有消耗
- 不适合循环引用
-
集中式管理
-
新生代
串行GC(Serial GC):复制算法
Minor GC
-
串行:标记压缩+清除
-
标记:暂停
-
并发标记:恢复,轮询着色对象,以标记它们
-
重新标记:暂停
-
并发收集:恢复
-
对新生代旧生代及持久代都进行的GC
7.9 内存泄露
- 一个不再被程序使用的对象或变量还在内存中占有存储空间
- 符合垃圾回收标准 对象赋空值null
- 给对象赋予新值,重新分配了内存空间
-
堆中申请的空间没有被释放
-
静态集合类
8. 分布式Java应用
8.1 基于消息方式实现系统间的通信
- TCP/IP+BIO socket.setSoTimeOut()设置等待响应的超时时间
- 一连接一线程
- 缺点:无论连接是否真实,都要创建线程
- BIO下服务器端所能支撑的连接数目有限
-
Channel
SocketChannel:建立连接,监听事件,操作读写
-
DatagramSocket:负责监听端口,读写数据
-
DatagramChannel:监听端口,进行读写
8.2 基于远程调用方式实现系统间的通信
- 远程调用方式 系统间通信和系统内一样
- 让使用者感觉调用远程同调用本地一样
-
RMI:客户端代理,stub,封装对象,序列化为流,TCP/IP BIO,Skeleton,反序列化,获取对象实例,调用
-
服务端的服务生成WSDL文件
-
将应用+WSDL文件放入HTTP服务器
-
借用Java辅助工具根据WSDL文件生成客户端stub代码
-
stub将产生的对象请求信息封装为标准化的SOAP格式数据,并发请求到服务器端
-
服端在接收到SOAP格式数据时进行转化,反射调用相应的Java类
8.3 基于开源框架
- Spring RMI
9. 多线程
9.1 线程资源同步机制
- JVM保证以下操作顺序 同一线程操作
- 对于main Memory 上的同一个变量的操作
- 对于加了锁的main Memory上的对象操作
-
synchronized
9.2 线程交互机制
- 基于Object的wait/notify/notifyAll 为避免假唤醒,需要double check
- 调用对象的wait-->wait sets--->释放锁--->其他线程notify---->wait sets---->执行此对象线程--->删除sets中此线程
-
Semphore的acquire,release
9.3 线程状态
- New
- Runnable
- Running
- Wait
- TimedWait
- Blocked
- Terminated
9.4 sleep()与wait()方法的区别
- sleep 暂停一段时间执行
- Thread的静态方法
- 不释放锁
- 需要捕获异常
-
使线程暂停执行
9.5 守护线程
- 后台提供服务
- 用户线程全部终止,只剩下守护线程时,JVM就会退出
- 调用start()之前,调用线程对象的setDaemon(true)
9.6 join
- 调用该方法的线程在执行完run()后,再执行join方法后面的代码
- 线程合并,实现同步功能
10. IO
10.1 流本质
- 数据传输
10.2 流分类
- 字节流:不使用缓存
- 字符流 码表映射
- 使用缓存
10.3 装饰者模式
- 运行时动态给对象增加额外的职责
- 是你还有你,一切拜托你
- FilterInputStream
10.4 Java Socket
- ServerSocket server = new ServerSocket(2000);
- Socker socket = server.accept();
- 客户端:Socket socket = new Socket("localhost",2000);
10.5 NIO
- Channel--Selector--Buffer
- 反应器模式
10.6 序列化
- 对象持久化方式
- 解决在对对象流进行读写操作时引发的问题
- 对象写进流里进行网络传输,保存到文件,数据库
10.7 如何实现序列化
- 实现Serializable接口
- 使用FileOutputStream来构造ObjectOutputStream对象
- 使用该对象的writeObject(obj)方法将对象写出
- 要恢复时,使用对应的输入流
10.8 序列化特点
- 一个类能被序列化,它的子类也能被序列化
- static代表类成员,transient代表临时数据。均不能被序列化
- 序列化影响性能,需要才使用
- 需要通过网络来发送对象,或对象的状态需要被持久化到数据库或文件中
- 序列化能实现深复制,即可以复制引用的对象
10.9 反序列化
- 将流转化为对象
- UID最好自己定义。优点 提高程序运行效率。省去计算过程
- 提高程序不同平台兼容性。不同计算方式,反序列化失败
- 增强程序各个版本的可兼容性。加入新属性,默认UID变化
10.10 外部序列化
- 实现Externalizable接口控制
相关文章推荐
- J2SE基础夯实系列之BigInteger使用总结(也是不可变的)
- java夯实基础系列:java起源、特点及各版本的新特性
- Java基础系列:(2)关于枚举的简单总结
- java夯实基础系列:接口与抽象类
- Java 基础夯实系列上线预告
- java夯实基础系列:装箱、拆箱
- java夯实基础系列:内部类
- java夯实基础系列:正则表达式(草稿)
- 夯实基础系列四:Linux 知识总结
- J2SE基础夯实系列之正则表达式Java
- java夯实基础系列:JAVA技能树
- J2SE基础夯实系列之JavaBean
- java夯实基础系列:学习结构和方向
- java夯实基础系列:异常
- java夯实基础系列:注解
- java系列(八)枯燥的基础总结
- java夯实基础系列:数组(草稿)
- JAVA基础知识点总结笔记系列二&nbsp;3-6…
- 【java基础总结系列】:java 多线程3种实现方式
- java夯实基础系列:泛型