Skip to content

Commit fccbd53

Browse files
committed
Update Java Notes
1 parent be48234 commit fccbd53

4 files changed

Lines changed: 223 additions & 148 deletions

File tree

DB.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4837,17 +4837,17 @@ LOAD DATA LOCAL INFILE = '/home/seazean/sql1.log' INTO TABLE `tb_user_1` FIELD T
48374837

48384838
对于 InnoDB 类型的表,有以下几种方式可以提高导入的效率:
48394839

4840-
1. 主键顺序插入:因为InnoDB类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数据的效率,如果InnoDB表没有主键,那么系统会自动默认创建一个内部列作为主键。
4840+
1. 主键顺序插入:因为 InnoDB 类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数据的效率,如果 InnoDB 表没有主键,那么系统会自动默认创建一个内部列作为主键。
48414841

4842-
* 插入ID顺序排列数据
4842+
* 插入 ID 顺序排列数据
48434843

48444844
![](https://gitee.com/seazean/images/raw/master/DB/MySQL-优化SQL插入ID顺序排列数据.png)
48454845

4846-
* 插入ID无序排列数据
4846+
* 插入 ID 无序排列数据
48474847

48484848
![](https://gitee.com/seazean/images/raw/master/DB/MySQL-优化SQL插入ID无序排列数据.png)
48494849

4850-
2. 关闭唯一性校验:在导入数据前执行`SET UNIQUE_CHECKS=0`,关闭唯一性校验;导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。
4850+
2. 关闭唯一性校验:在导入数据前执行 `SET UNIQUE_CHECKS=0`,关闭唯一性校验;导入结束后执行 `SET UNIQUE_CHECKS=1`,恢复唯一性校验,可以提高导入的效率。
48514851

48524852
![](https://gitee.com/seazean/images/raw/master/DB/MySQL-优化SQL插入数据关闭唯一性校验.png)
48534853

@@ -6436,7 +6436,7 @@ SELECT * FROM tb_book WHERE id < 8
64366436

64376437
慢查询日志记录所有执行时间超过 long_query_time 并且扫描记录数不小于 min_examined_row_limit 的所有的 SQL 语句的日志。long_query_time 默认为 10 秒,最小为 0, 精度到微秒
64386438

6439-
慢查询日志默认是关闭的,可以通过两个参数来控制慢查询日志,配置文件`/etc/mysql/my.cnf`
6439+
慢查询日志默认是关闭的,可以通过两个参数来控制慢查询日志,配置文件 `/etc/mysql/my.cnf`
64406440

64416441
```sh
64426442
# 该参数用来控制慢查询日志是否开启,可选值0或者1,0代表关闭,1代表开启
@@ -6459,7 +6459,7 @@ long_query_time=10
64596459

64606460
![](https://gitee.com/seazean/images/raw/master/DB/MySQL-慢日志读取1.png)
64616461

6462-
* 如果慢查询日志内容很多,直接查看文件比较繁琐, 可以借助于mysql 自带的 mysqldumpslow 工具, 来对慢查询日志进行分类汇总
6462+
* 如果慢查询日志内容很多,直接查看文件比较繁琐,可以借助 mysql 自带的 mysqldumpslow 工具对慢查询日志进行分类汇总
64636463

64646464
```sh
64656465
mysqldumpslow slow_query.log
@@ -6506,14 +6506,14 @@ long_query_time=10
65066506

65076507
作用:遵守第二范式减少数据冗余,通过主键区分相同数据。
65086508

6509-
1. 函数依赖:A --> B,如果通过A属性(属性组)的值,可以确定唯一B属性的值,则称B依赖于A
6510-
* 学号 --> 姓名;(学号,课程名称) --> 分数
6511-
2. 完全函数依赖:A --> B,如果A是一个属性组,则B属性值的确定需要依赖于A属性组的所有属性值
6512-
* (学号,课程名称) --> 分数
6513-
3. 部分函数依赖:A --> B,如果A是一个属性组,则B属性值的确定只需要依赖于A属性组的某些属性值
6514-
* (学号,课程名称) --> 姓名
6515-
4. 传递函数依赖:A --> B,B --> C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值,可以确定唯一C属性的值,则称C传递函数依赖于A
6516-
* 学号 --> 系名,系名 --> 系主任
6509+
1. 函数依赖:A B,如果通过 A 属性(属性组)的值,可以确定唯一 B 属性的值,则称 B 依赖于 A
6510+
* 学号 姓名;(学号,课程名称) 分数
6511+
2. 完全函数依赖:A B,如果A是一个属性组,则 B 属性值的确定需要依赖于 A 属性组的所有属性值
6512+
* (学号,课程名称) 分数
6513+
3. 部分函数依赖:A B,如果 A 是一个属性组,则 B 属性值的确定只需要依赖于 A 属性组的某些属性值
6514+
* (学号,课程名称) 姓名
6515+
4. 传递函数依赖:A B,B C,如果通过A属性(属性组)的值,可以确定唯一 B 属性的值,在通过 B 属性(属性组)的值,可以确定唯一 C 属性的值,则称 C 传递函数依赖于 A
6516+
* 学号 系名,系名 系主任
65176517
5. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
65186518
* 该表中的码:(学号,课程名称)
65196519
* 主属性:码属性组中的所有属性
@@ -6848,9 +6848,9 @@ public class JDBCDemo01 {
68486848

68496849
从数据库读取数据并封装成Student对象,需要:
68506850

6851-
- Student类成员变量对应表中的列
6851+
- Student 类成员变量对应表中的列
68526852

6853-
- 所有的基本数据类型需要使用包装类,**以防null值无法赋值**
6853+
- 所有的基本数据类型需要使用包装类,**以防 null 值无法赋值**
68546854

68556855
```java
68566856
public class Student {
@@ -6990,12 +6990,12 @@ SQL注入攻击演示
69906990

69916991
### 攻击解决
69926992

6993-
PreparedStatement:预编译 sql 语句的执行者对象,继承`PreparedStatement extends Statement`
6993+
PreparedStatement:预编译 sql 语句的执行者对象,继承 `PreparedStatement extends Statement`
69946994

69956995
* 在执行 sql 语句之前,将 sql 语句进行提前编译。明确 sql 语句的格式,剩余的内容都会认为是参数
69966996
* sql 语句中的参数使用 ? 作为占位符
69976997

6998-
为 ? 占位符赋值的方法:setXxx(参数1,参数2)
6998+
为 ? 占位符赋值的方法:`setXxx(int parameterIndex, xxx data)`
69996999

70007000
- 参数1:? 的位置编号(编号从1开始)
70017001

Java.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,15 +2489,15 @@ s.replace("-","");//12378
24892489
* `public String(char[] chs)` : 根据字符数组的内容,来创建字符串对象
24902490
* `public String(String original)` : 根据传入的字符串内容,来创建字符串对象
24912491

2492-
直接赋值:`String s = “abc”` 直接赋值的方式创建字符串对象,内容就是abc
2492+
直接赋值:`String s = “abc”` 直接赋值的方式创建字符串对象,内容就是 abc
24932493

24942494
- 通过构造方法创建:通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同,**返回堆内存中对象的引用**
24952495
- 直接赋值方式创建:以“ ”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会**在 String Pool 中创建一个字符串对象**,并在字符串池中维护
24962496

24972497
`String str = new String("abc")`创建字符串对象:
24982498

24992499
* 创建一个对象:字符串池中已经存在"abc"对象,那么直接在创建一个对象放入堆中,返回堆内引用
2500-
* 创建两个对象:字符串池中未找到"abc"对象,那么分别在堆中和字符串池中创建一个对象,字符串池中的比较都是采用 equals() 方法
2500+
* 创建两个对象:字符串池中未找到"abc"对象,那么分别在堆中和字符串池中创建一个对象,字符串池中的比较都是采用 equals()
25012501
<img src="https://gitee.com/seazean/images/raw/master/Java/String构造方法字节码.png" style="zoom: 67%;" />
25022502

25032503
`new String("a") + new String("b")`创建字符串对象:
@@ -2509,7 +2509,7 @@ s.replace("-","");//12378
25092509
* 对象4:new String("b")、对象5:常量池中的"b"
25102510
<img src="https://gitee.com/seazean/images/raw/master/Java/String拼接方法字节码.png" style="zoom:67%;" />
25112511

2512-
* StringBuilder的toString():
2512+
* StringBuilder 的 toString():
25132513

25142514
```java
25152515
@Override
@@ -2533,9 +2533,9 @@ s.replace("-","");//12378
25332533

25342534
**字符串常量池(String Pool / StringTable / 串池)**保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定,常量池类似于Java系统级别提供的**缓存**,存放对象和引用
25352535

2536-
* StringTable,hashtable (哈希表 + 链表)结构,不能扩容,默认值大小长度是1009
2536+
* StringTable,hashtable (哈希表 + 链表)结构,不能扩容,默认值大小长度是 1009
25372537
* 常量池中的字符串仅是符号,第一次使用时才变为对象,可以避免重复创建字符串对象
2538-
* 字符串**变量**的拼接的原理是StringBuilder(jdk1.8),append 效率要比字符串拼接高很多
2538+
* 字符串**变量**的拼接的原理是 StringBuilder(jdk1.8),append 效率要比字符串拼接高很多
25392539
* 字符串**常量**拼接的原理是编译期优化,结果在常量池
25402540
* 可以使用 String 的 intern() 方法在运行过程将字符串添加到 String Pool 中
25412541

@@ -2564,7 +2564,7 @@ public class Demo {
25642564
String s2 = "b";
25652565
String s3 = "ab";//串池
25662566
// new StringBuilder().append("a").append("b").toString() new String("ab")
2567-
String s4 = s1 + s2; // 堆内地址
2567+
String s4 = s1 + s2; // 返回的是堆内地址
25682568
String s5 = "a" + "b"; // javac 在编译期间的优化,结果已经在编译期确定为ab
25692569

25702570
System.out.println(s3 == s4); // false
@@ -2586,8 +2586,8 @@ public class Demo {
25862586
结论:
25872587

25882588
```java
2589-
String s1 = "ab"; //串池
2590-
String s2 = new String("a") + new String("b"); //
2589+
String s1 = "ab"; //放入串池
2590+
String s2 = new String("a") + new String("b"); //放入堆
25912591
//上面两条指令的结果和下面的 效果 相同
25922592
String s = new String("ab");
25932593
```
@@ -2621,7 +2621,7 @@ public static void main(String[] args) {
26212621
```java
26222622
public static void main(String[] args) {
26232623
String str1 = new StringBuilder("58").append("tongcheng").toString();
2624-
System.out.println(str1 == str1.intern());//true
2624+
System.out.println(str1 == str1.intern());//true,字符串池中不存在,把堆中的引用复制一份放入串池
26252625

26262626
String str2 = new StringBuilder("ja").append("va").toString();
26272627
System.out.println(str2 == str2.intern());//false
@@ -2743,13 +2743,13 @@ public class Demo1_25 {
27432743
#### 不可变好处
27442744

27452745
* 可以缓存 hash 值
2746-
因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,只需要进行一次计算
2746+
String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,只要进行一次计算
27472747
* String Pool 的需要
2748-
如果一个String对象已经被创建过了,就会从 String Pool中取得引用。只有 String是不可变的,才可能使用 String Pool
2748+
如果一个String对象已经被创建过了,就会从 String Pool 中取得引用,只有 String是不可变的,才可能使用 String Pool
27492749
* 安全性
27502750
String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 的那一方以为现在连接的是其它主机,而实际情况却不一定是
27512751
* String 不可变性天生具备线程安全,可以在多个线程中安全地使用
2752-
* 防止子类继承,破坏String的API的使用
2752+
* 防止子类继承,破坏 String 的 API 的使用
27532753

27542754

27552755

@@ -2765,7 +2765,7 @@ String StringBuffer 和 StringBuilder 区别:
27652765

27662766
* String : **不可变**的字符序列,线程安全
27672767
* StringBuffer : **可变**的字符序列,线程安全,底层方法加 synchronized,效率低
2768-
* StringBuilder : **可变**的字符序列,JDK5.0新增;线程不安全,效率高
2768+
* StringBuilder : **可变**的字符序列,JDK5.0 新增;线程不安全,效率高
27692769

27702770
相同点:底层使用 char[] 存储
27712771

@@ -3942,6 +3942,10 @@ public static void main(String[] args){
39423942

39433943

39443944

3945+
***
3946+
3947+
3948+
39453949
###### 源码
39463950

39473951
ArrayList 实现类集合底层**基于数组存储数据**的,查询快,增删慢,支持快速随机访问
@@ -3970,7 +3974,7 @@ public class ArrayList<E> extends AbstractList<E>
39703974
}
39713975
```
39723976

3973-
当add 第 1 个元素到 ArrayList,size 是 0,进入 ensureCapacityInternal 方法,
3977+
当 add 第 1 个元素到 ArrayList,size 是 0,进入 ensureCapacityInternal 方法,
39743978

39753979
```java
39763980
private void ensureCapacityInternal(int minCapacity) {
@@ -4043,12 +4047,17 @@ public class ArrayList<E> extends AbstractList<E>
40434047
* 删除元素:需要调用 System.arraycopy() 将 index+1 后面的元素都复制到 index 位置上,在旧数组上操作,该操作的时间复杂度为 O(N),可以看到 ArrayList 删除元素的代价是非常高的,
40444048

40454049
```java
4046-
private void fastRemove(Object[] es, int i) {
4050+
public E remove(int index) {
4051+
rangeCheck(index);
40474052
modCount++;
4048-
final int newSize;
4049-
if ((newSize = size - 1) > i)
4050-
System.arraycopy(es, i + 1, es, i, newSize - i);
4051-
es[size = newSize] = null;
4053+
E oldValue = elementData(index);
4054+
4055+
int numMoved = size - index - 1;
4056+
if (numMoved > 0)
4057+
System.arraycopy(elementData, index+1, elementData, index, numMoved);
4058+
elementData[--size] = null; // clear to let GC do its work
4059+
4060+
return oldValue;
40524061
}
40534062
```
40544063

@@ -4073,7 +4082,7 @@ public class ArrayList<E> extends AbstractList<E>
40734082

40744083
* **Fail-Fast**:快速失败,modCount 用来记录 ArrayList **结构发生变化**的次数,结构发生变化是指添加或者删除至少一个元素的所有操作,或者是调整内部数组的大小,仅仅只是设置元素的值不算结构发生变化
40754084

4076-
在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了抛出 ConcurrentModificationException异常
4085+
在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,改变了抛出 ConcurrentModificationException 异常
40774086

40784087

40794088

@@ -4626,7 +4635,11 @@ JDK7 对比 JDK8:
46264635
* **当链表长度超过(大于)阈值(或者红黑树的边界值,默认为 8)并且当前数组的长度大于等于64时,此索引位置上的所有数据改为红黑树存储**
46274636
* 即使哈希函数取得再好,也很难达到元素百分百均匀分布。当 HashMap 中有大量的元素都存放到同一个桶中时,就相当于一个长的单链表,假如单链表有 n 个元素,遍历的**时间复杂度是 O(n)**,所以 JDK1.8 中引入了 红黑树(查找**时间复杂度为 O(logn)**)来优化这个问题,使得查找效率更高
46284637

4629-
![](https://gitee.com/seazean/images/raw/master/Java/哈希表.png)
4638+
![](https://gitee.com/seazean/images/raw/master/Java/HashMap底层结构.png)
4639+
4640+
4641+
4642+
参考视频:https://www.bilibili.com/video/BV1nJ411J7AA
46304643

46314644

46324645

@@ -9774,7 +9787,7 @@ Heap 堆:是JVM内存中最大的一块,由所有线程共享,由垃圾回
97749787
* 对象实例:类初始化生成的对象,**基本数据类型的数组也是对象实例**,new 创建对象都使用堆内存
97759788
* 字符串常量池:
97769789
* 字符串常量池原本存放于方法区,jdk7开始放置于堆中
9777-
* 字符串常量池**存储的是 string 对象的直接引用或者对象**,是一张 string table
9790+
* 字符串常量池**存储的是 String 对象的直接引用或者对象**,是一张 string table
97789791
* 静态变量:静态变量是有 static 修饰的变量,jdk7 时从方法区迁移至堆中
97799792
* 线程分配缓冲区 Thread Local Allocation Buffer:线程私有但不影响堆的共性,可以提升对象分配的效率
97809793

0 commit comments

Comments
 (0)