java基础知识点
001
java和C/C++ py js比较像
理论知识基础,操作系统,计算机网络,记组,数据结构与算法(加分项)
jvm 使java程序在不同操作系统上运行,class二进制语言
版本:
javase java核心,标准版java ,基本功
javaee 企业级开发,网站应用javaweb
javase -> javaee 循序渐进
jre java运行环境 jdk java开发者工具 开发要装jdk
002
不用配置环境变量
安装中文插件
003
编译:javac Main.java
运行:java Main
编译型语言:编译后运行
解释型语言:解释器
java两个都是
004
共同开发
构建锤子,打包项目
运行
调试 评估
搜索
设置
005
分号结尾 括号匹配
{} 代码块
006
自动清理内存
区分大小写
见名知意,英语单词
007
二进制 0 1
下划线
008
unicode \u0000~\uffff
字符串不是基本类型
BigInteger
009
小数存有效数字
BigDecimal
010
byte -> short (char) -> int -> long -> float -> double
数据类型自动提升 int double
011
a++
++a
b+++a -> (b++)+a 贪心机制
位运算符 & | ^ ~ 与 或 异或 非
三目 = a ? b : c
012
if else
阿里巴巴开发手册建议:表达异常的分支时,少用 if-else 方式
变量属于代码块{} ,超出代码块不再存在
switch case break default break 二分搜索 只能传值
013
for(初始条件;循环条件;更新)
for(;;)比while(true)效率高
for each 语法糖
014
取整 1/2=0.0
break跳一次
continue跳一次的一个
015
99乘法表
016
水仙花
017
递归青蛙
动态规划 上一次结果给下一次做参考,下一次快速得到结果,类推
static void jump(int n){
int[] arr = new int[n];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
for (int i = 3; i < n; i++) {
arr[i] = arr[i-1] + arr[i-2];
System.out.println("第"+(i+1)+"台阶有"+(arr[i])+"种跳法");
}
}
018
基本类型不是类,不能创建对象,对应包装类
019
public class
class
局部变量作用域在代码块中
类不能定义变量,得有一个对象,静态除外
020
main方法返回void
[返回值类型] 方法名 (参数){
// 方法体
return 结果;
void 可省 return
return;
}
return 提前结束方法
return > break > continue
方法可以改变新类的变量
方法可以相互调用,自己调用自己(递归)
递归等于玩火,阿里巴巴开发手册不建议用递归
021
自己要会设计类
022
形参和返回值不同
023
构造方法赋初值
this代表该类的xxx
有参构造覆盖无参
024
不同对象操作同一个静态变量,所有对象共同拥有 。。
隐式加载
静态方法在对象创建之前,在构造器之前
静态上下文不用 this
025
代码块优先于构造器
静态代码块优先于代码块
026
字符串是对象
contains toUpperCase equals
字符串是不可变的
字符串拼接生成一个新对象
就有了 StringBuilder (append) 链式拼接
sb
.append("hello")
.append(",")
.append("world");
当然,JVM 会自动优化 String -> StringBuilder
027
包本质是文件夹
默认导入 lang 包
利用包导入方法
静态导入不会类初始化
028
private 内部访问
和文件名相同的类只能 public
029
数组是 C++ 写的
C 可以越界,java 数组越界异常
arr.length 是 final 类型,数组长度不可变
foreach 语法糖,简化下标定义
030
遍历多维数组 - 多次for循环
deepToString 直接遍历
数组应用:可变长度,就是传数组
可变长参数放到最后一位
031
冒泡
static void test(int[] arr){
for (int j = 0; j < arr.length - 1 ; j++) {
boolean b = true;
for (int i = 0; i < arr.length - 1 - j; i++) {
if (arr[i] > arr[i+1]){
b = false;
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
if (b) break;
}
for (int i : arr) {
System.out.print(i + " ");
}
}
032
插入
static void test(int[] arr){
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
int j = i-1;
while (j >= 0 && arr[j] > temp){
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
033
选择
static void test(int[] arr){
for (int i = 0; i < arr.length - 1; i++) {
int min = arr[i], pos = i;
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < min){
min = arr[j];
pos = j;
}
}
int temp = arr[i];
arr[i] = min;// arr[i] = arr[pos];
arr[pos] = temp;
}
}
034
super 代表父类,super调用必须是第一句话,老子第一,this 代表当前类
单继承
Object 祖宗类
hashCode 是 C++ 写的
035
重写不是重载
静态不能重写
定义变量 : 形参 > 本类 > 父类
父类对象指向子类实例,得到的是子类实现(向上转型)
这个父类对象可以强转为子类对象(向下转型)
instanceof 父类引用不知道子类实现的判断
对象 instanceof 类
036
final 类不能被继承
JVM 会优化 final 关键字,用于值不可变的变量
抽象方法必须由子类实现,除非子类也是抽象类,但这样做没有意义
内部类可以直接定义抽象类的方法
037
接口 default 默认实现
属性默认 public static final
接口是多继承的代替方案,java 是多继承
038
怪异的内部类:
成员 静态 局部
匿名 ->
039
-> lambda
仅支持单方法接口
040
枚举 public static final
静态代码块初始化
Status.values();
Status.valueOf();
041
自动装 拆箱
两个包装类生成两个对象(-128~127)
包装类有工具类
042
自己设计类
接口,抽象类
instanceof
043
二分查找
private static int test(int target,int[] arr){
int start = 0; int end = arr.length - 1;
while (start <= end){
int mid = (start + end + 1)/2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) start = mid + 1;
if (arr[mid] > target) end = mid - 1;
}
return -1;
}
044
快速排序
static void quickSort(int[] arr,int start,int end){
if (start >= end)return;
int k = arr[start],low = start,high = end;
while (low < high){
while (low < high && k <= arr[high])high--;
arr[low] = arr[high];
while (low < high && k >= arr[low]) low++;
arr[high] = arr[low];
}
arr[high] = k; // arr[low] = k;
quickSort(arr,start,high-1);
quickSort(arr,high+1,end);
}
045
0 1 背包
填表
046
指针下标越界异常,空指针异常,算术异常,引起程序问题被抛出
红色报错
编译时异常,运行时异常
错误处理不了,异常可以
47
栈追踪信息
追踪异常位置
e.printStackTrace();
catch(Throwable e) // 自动匹配,捕获异常
// 可以捕获错误,但没必要
48
抛出是交给上一级处理,不用自己捕获处理
丢给虚拟机
假使捕获多次,异常只会最内层捕获
49
自定义 MyException 异常继承 Exception ,捕获异常自动捕获子类异常
finally 一定执行,可以用来关流
先执行 return ,再执行 finally
50
泛型
编译阶段判断数据类型,类型不符合不通过编译
JVM 不支持泛型,编译器自动推断类型
51
泛型参数是对象,不能加 static,本质是 Object 类的对象,不能表示基本类型
泛型方法可以加 static
52
通配符
用的很少,框架和反射中会用
前面 <?> 后面 < String >
前面 < String > 后面 <> -> 钻石运算符
// 前 后
<? extends Number>
// 泛型上界 Number
<? super Integer>
// 泛型下界 Integer
规定上界后泛型类要在上界之下
下界同理
指定了上限后,没有泛型 Object 的说法了
53
泛型定义在接口,接口中的< T >被 替换 / 擦除
泛型接口反编译会发现两个 桥接方法
@Override
public Object get(){
return this.get();
}
------------------------
@Override
public void set(Object t){
this.set((Number)t);
}
054
顺序表
数组定长度是一大痛点,有数据结构(存储数据的一些结构)
线性表是一种数据结构,顺序表是线性表的实现
查询效率高
055
链表
链表注意指针(引用)的指向改变
增删效率高
56
栈
只能在一端 入栈 出栈
基于顺序表和链表实现
size 是栈顶指针
JVM 处理方法嵌套调用就是利用栈调用
57
队列
队尾入队,队头出队
58
二叉树
最多两个子节点
前序 中序 后序遍历
指的是打印当前节点的位置 前中后
59
哈希表
提高查询效率
顺序表虽然查询效率高,但是增删效率低
链表则相反
哈希表折中,是存放链表的数组
查找 hashcode 值是数组,增删是链表
60
二叉排序树
每个节点左子树小于当前,右子树大于当前
平衡二叉树
失衡情况,对应处理
左左失衡
右旋
右右失衡
左旋
左右失衡
先左旋再右旋
右左失衡
先右旋再左旋
61
红黑树
失衡严重的情况
出现大量的旋转,但旋转次数不会超过3次
HashMap 中使用 红黑树
节点红色,子节点必黑色,不能相同,颜色交错
62
集合类
是 Java 内置的数据结构
数组和集合都是存储数据的 容器
Set 不能随机访问,不是有序的
List 支持了 Collection 中没有的 get
queue 有两个增删查,一个抛异常的
63
ArrayList
add
remove
contains
直接打印 .sout
64
LinkedList
sort 定义比较器 Comparator
可以简化成 lambda 表达式
65
迭代器
ArrayList 适合随机访问 , LinkedList 适合顺序访问
迭代器解决了这种差异,foreach 的本质就是迭代器
66
Set 集合
不能出现重复元素,不通过下标访问
核心是hash表
HashSet 无序(常用的 Set),LinkedHashSet 有序
TreeSet 自动排序,底层是红黑树
67
key - value
68
HashMap
存放后续节点的头节点的数组
数据变多
负载因子扩容机制
红黑树
HashMap 无序,LinkedHashMap 有序
TreeSet 继承 LinkedHashMap
69
TreeMap
内含比较器:可自定义排序规则
70
Set 就是用 Map 的 key,就是 Map 的代理
Map 是 Set 的师傅
compute merge 计算
71
集合的嵌套,就是套娃
Stream
用声明的方式处理数据,工厂流水线的感觉
list = list
.stream() // 获取流
.filter(e -> !e.equals("B"))
.collect(Collectors.toList());
72
Optional 自动判空,不执行 null
原理是 Kotlin
73
Arrays
二分搜索前提是有序
二维数组遍历 deepToString() 方法 比较 deepEquals() 方法
74
链表反转,递归思想
75
二叉树重建 关键:中序
76
栈实现计算器
77
字符串匹配 - KMP 算法
转化为字符数组
78
I/O 设备
操作系统是管理硬件和软件的软件
79
// 路径分割符
D:/
D:\\ 转义
及时关流,浪费资源
字节流读字节
80
字符流读字符
不适合二进制文件
81
File 类
对文件 / 文件夹操作
82
缓冲流
文件流速度达不到内存读取速度,缓冲流有缓冲区
装饰者模式
BufferedReader 里的 lines 支持链式结构(stream)
缓冲流好处多多,比文件流好多了,尽量用缓冲流
83
转换流
字节转字符 ->
OutputStreamWriter
InputStreamReader
可以再套一层 Buffer 缓冲流
就是套娃
打印流
PrintStream 就是 System.out
自动刷新
不会抛出异常
格式化任意类型
这个流中有多次套娃
84
数据流
可以直接读取基本数据类型
DataOutputStream DataInputStream
对象流
ObjectInputStream ObjectOutputStream
对象实现接口 Serializable
对象有自己的版本序列号 serialVersionUID 用于版本匹配
transient 关键字 ,不参与序列化
源码会使用很多这个关键字
85
线程中有进程
线程是程序运行最小单位
上下文切换速度快于进程
86
创建和启动
休眠方法:Thread.sleep();
强行终止:thread.stop(); 不推荐用
87
休眠和中断
代替stop : 用interrupt();
currentThread() 获得当前线程
suppend 暂停 resume 恢复(过时)
88
优先级
MI N_PRIORITY
MAX_PRIORITY
NORM_PRIORITY
只是执行概率高了,不是必须的
礼让和加入
礼让:yield()
加入:join()
89
线程同步
90
锁
synchronized(Main.class){} 同步代码块
1 + 1 = 2
是一种悲观锁
synchronized(s1){}
synchronized(s2){}
// 拿到锁不一样,结果改变
方法前也可以加锁
死锁
两个线程拿到对方的锁
91
wait 释放锁 进入等待
notify 唤醒等待
92
ThreadLocal
线程的集合类
各自进行各自的,互不干扰
93
守护
setDaemon(true);
并行流
多线程执行方法
parallelStream();
多线程会产生异步问题
94
生产者消费者模式
95
加载 class 文件
96
获得 class 对象
97
Class c1 = String.class;
Class<?> c2 = Class.forName("java.lang.String");
Class<? extends String> c3 = new String("3").getClass();
基本数据类型也有class,自动装箱
98
instanceof 类型比较
getSuperclass();
99
创建类对象
Class c = Student.class;
Student student = c.newInstance(); // 默认调无参构造
student.hello();
c.setAccessible(true); // 强行访问权限
100
方法
Class c = Student.class;
Student student = c.newInstance();
Method hello = c.getMethod("hello");
hello.setAccessible(true);
hello.invoke(student);
101
修改类属性
Class c = Student.class;
Student student = c.newInstance();
Field name = c.getDeclaredField("name");
name.setAccessible(true);
name.set(student,"h");
Method method = c.getDeclaredMethod("getName");
method.setAccessible(true);
Object invoke = method.invoke(student);
System.out.println(invoke);
反射可以刨祖坟了,除非 final (这个改不了)
反射一般不会用,除非迫不得已,不能滥用。。。。。。
技术不是就要用牛逼的,要分场合解决问题
102
ClassLoader
103
注解
编译完就没了
@Override
@Deprecated // 弃用
@SuppressWarnings
@Functionalinterface
@SafeVarrags
@Test // 单元测试
元注解
是编写注解里的注解
@Target
@Inherited
104
注解使用
注解传参
反射获取注解
clazz.getAnnotations();