mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
Merge branch 'master' into JavaGuide-fs
This commit is contained in:
commit
037b9fdf6d
@ -54,7 +54,7 @@ Github用户如果访问速度缓慢的话,可以转移到[码云](https://git
|
||||
- [系统设计](#系统设计)
|
||||
- [必知](#必知)
|
||||
- [常用框架](#常用框架)
|
||||
- [Spring](#spring)
|
||||
- [Spring](#springspringboot)
|
||||
- [SpringBoot](#springboot)
|
||||
- [MyBatis](#mybatis)
|
||||
- [认证授权(JWT、SSO)](#认证授权)
|
||||
@ -228,9 +228,10 @@ Github用户如果访问速度缓慢的话,可以转移到[码云](https://git
|
||||
3. **[SpringBoot 指南/常见面试题总结](https://github.com/Snailclimb/springboot-guide)**
|
||||
3. **[Spring/Spring常用注解总结!安排!](./docs/system-design/framework/spring/spring-annotations.md)**
|
||||
4. **[Spring事务总结](docs/system-design/framework/spring/spring-transaction.md)**
|
||||
5. [Spring中 Bean 的作用域与生命周期](docs/system-design/framework/spring/SpringBean.md)
|
||||
6. [SpringMVC 工作原理详解](docs/system-design/framework/spring/SpringMVC-Principle.md)
|
||||
7. [Spring中都用到了那些设计模式?](docs/system-design/framework/spring/Spring-Design-Patterns.md)
|
||||
5. [Spring IoC 和 AOP详解](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486938&idx=1&sn=c99ef0233f39a5ffc1b98c81e02dfcd4&chksm=cea24211f9d5cb07fa901183ba4d96187820713a72387788408040822ffb2ed575d28e953ce7&token=1666190828&lang=zh_CN#rd)
|
||||
6. [Spring中 Bean 的作用域与生命周期](docs/system-design/framework/spring/SpringBean.md)
|
||||
7. [SpringMVC 工作原理详解](docs/system-design/framework/spring/SpringMVC-Principle.md)
|
||||
8. [Spring中都用到了那些设计模式?](docs/system-design/framework/spring/Spring-Design-Patterns.md)
|
||||
|
||||
#### MyBatis
|
||||
|
||||
|
@ -216,6 +216,8 @@ appendfsync no #让操作系统决定何时进行同步
|
||||
|
||||
为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec 选项 ,让 Redis 每秒同步一次 AOF 文件,Redis 性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis 还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。
|
||||
|
||||
[相关 Issue783:Redis的AOF 方式](https://github.com/Snailclimb/JavaGuide/issues/783)
|
||||
|
||||
**Redis 4.0 对于持久化机制的优化**
|
||||
|
||||
Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 `aof-use-rdb-preamble` 开启)。
|
||||
|
@ -21,7 +21,7 @@
|
||||
> 1. **增加了复杂性:** a.每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦,测试数据极为不方便;b.外键的主从关系是定的,假如那天需求有变化,数据库中的这个字段根本不需要和其他表有关联的话就会增加很多麻烦。
|
||||
> 2. **增加了额外工作**: 数据库需要增加维护外键的工作,比如当我们做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,保证数据的的一致性和正确性,这样会不得不消耗资源;(个人觉得这个不是不用外键的原因,因为即使你不使用外键,你在应用层面也还是要保证的。所以,我觉得这个影响可以忽略不计。)
|
||||
> 3. 外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;
|
||||
> 4. **对分不分表不友好** :因为分库分表下外键是无法生效的。
|
||||
> 4. **对分库分表不友好** :因为分库分表下外键是无法生效的。
|
||||
> 5. ......
|
||||
|
||||
我个人觉得上面这种回答不是特别的全面,只是说了外键存在的一个常见的问题。实际上,我们知道外键也是有很多好处的,比如:
|
||||
|
@ -1,31 +1,29 @@
|
||||
点击关注[公众号](#公众号)及时获取笔主最新更新文章,并可免费领取本文档配套的《Java 面试突击》以及 Java 工程师必备学习资源。
|
||||
<!-- TOC -->
|
||||
|
||||
- [1. Java基本功](#1-Java基本功)
|
||||
- [1.1 Java入门(基础概念与常识)](#1.1Java入门(基础概念与常识))
|
||||
- [1.2 Java语法](#1.2Java语法)
|
||||
- [1.3 Java流程控制](#1.3Java流程控制)
|
||||
- [1. Java 基本功](#1-Java基本功)
|
||||
- [1.1 Java 入门(基础概念与常识)](#1.1Java入门(基础概念与常识))
|
||||
- [1.2 Java 语法](#1.2Java语法)
|
||||
- [1.3 Java 流程控制](#1.3Java流程控制)
|
||||
- [1.4 数组](#1.4数组)
|
||||
- [1.5 方法(函数)](#1.5方法(函数))
|
||||
|
||||
- [2. Java面向对象](#2-Java面向对象)
|
||||
- [2. Java 面向对象](#2-Java面向对象)
|
||||
- [2.1 类和对象](#2.1类和对象)
|
||||
- [2.2 面向对象三大特征](#2.2面向对象三大特征)
|
||||
- [2.3 修饰符](#2.3修饰符)
|
||||
- [2.4 接口](#2.4接口)
|
||||
- [2.5 类的扩展](#2.5类的扩展)
|
||||
- [3. Java核心技术](#3-关于-jvm-jdk-和-jre-最详细通俗的解答)
|
||||
- [3. Java 核心技术](#3-关于-jvm-jdk-和-jre-最详细通俗的解答)
|
||||
- [3.1 集合](#3.1集合)
|
||||
- [3.2 异常](#3.2异常)
|
||||
- [3.3 多线程](#3.3多线程)
|
||||
- [3.4 文件与I\O流](#3.4文件与I\O流)
|
||||
- [3.4 文件与 I\O 流](#3.4文件与I\O流)
|
||||
- [【附录】参考](#参考)
|
||||
- [【附录】公众号](#公众号)
|
||||
|
||||
<!-- /TOC -->
|
||||
## 1. Java 基本功
|
||||
|
||||
### 1.1 Java 入门(基础概念与常识)
|
||||
|
||||
## 1. Java基本功
|
||||
### 1.1 Java入门(基础概念与常识)
|
||||
#### 1.1.1 Java 语言有哪些特点?
|
||||
|
||||
1. 简单易学;
|
||||
@ -112,6 +110,7 @@ JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有
|
||||
|
||||
所以,实际上 java 和 javax 没有区别。这都是一个名字。
|
||||
|
||||
|
||||
#### 1.1.8 为什么说Java语言“编译与解释并存”?
|
||||
高级编程语言按照程序的执行方式分为编译型和解释型两种。简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。比如,你想阅读一本英文名著,你可以找一个英文翻译人员帮助你阅读,
|
||||
有两种选择方式,你可以先等翻译人员将全本的英文名著(也就是源码)都翻译成汉语,再去阅读,也可以让翻译人员翻译一段,你在旁边阅读一段,慢慢把书读完。
|
||||
@ -120,6 +119,7 @@ Java语言既具有编译型语言的特征,也具有解释型语言的特征
|
||||
|
||||
|
||||
### 1.2 Java语法
|
||||
|
||||
#### 1.2.1 字符型常量和字符串常量的区别?
|
||||
|
||||
1. 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的若干个字符
|
||||
@ -129,7 +129,8 @@ Java语言既具有编译型语言的特征,也具有解释型语言的特征
|
||||
> java 编程思想第四版:2.2.2 节
|
||||
> 
|
||||
|
||||
####1.2.2 为什么要写注释?
|
||||
#### 1.2.2 为什么要写注释?
|
||||
|
||||
Java中的注释有三种:单行注释、多行注释和文档注释。在我们编写代码的时候,如果代码量比较少,我们自己或者团队其他成员还可以很轻易地看懂代码,但是当项目结构一旦复杂起来,我们就需要用到注释了。注释并不会执行,是我们程序员写给自己看的,注释是你的代码说明书,能够帮助看代码的人快速地理清代码之间的逻辑关系。因此,在写程序的时候随手加上注释是一个非常好的习惯。
|
||||
|
||||
#### 1.2.3 标识符和关键字的区别是什么?
|
||||
@ -139,7 +140,9 @@ Java中的注释有三种:单行注释、多行注释和文档注释。在我
|
||||
在写代码的过程中,常见的一种情况是需要某个整数类型变量增加1或减少1,Java提供了一种特殊的运算符,用于这种表达式,叫做自增运算符(++)和自减运算符(--)。++和--运算符可以放在操作数之前,也可以放在操作数之后,当运算符放在操作数之前时,先自增/减,再赋值;当运算符放在操作数之后时,先赋值,再自增/减。例如,当“b=++a”时,先自增(自己增加1),再赋值(赋值给b);当“b=a++”时,先赋值(赋值给b),再自增(自己增加1)。也就是,++a输出的是a+1的值,a++输出的是a值。用一句口诀就是:“符号在前就先加/减,符号在后就后加/减”。
|
||||
|
||||
### 1.3 Java流程控制
|
||||
|
||||
#### 1.3.1 continue、break、和return的区别是什么?
|
||||
|
||||
在循环结构中,当循环条件不满足或者循环次数达到要求时,循环会正常结束。但是,有时候可能需要在循环的过程中,当发生了某种条件之后 ,提前终止循环,这就需要用到跳转语句。
|
||||
|
||||
continue跳转语句:是指跳出当前的这一次循环,继续下一次循环。
|
||||
@ -151,6 +154,7 @@ return跳转语句:是指跳出所在方法,结束该方法的运行。
|
||||
### 1.4 数组
|
||||
|
||||
### 1.5 方法(函数)
|
||||
|
||||
#### 1.5.1 什么是方法的返回值?返回值在类的方法里的作用是什么?
|
||||
|
||||
方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。返回值的作用:接收出结果,使得它可以用于其他的操作!
|
||||
@ -204,14 +208,18 @@ return跳转语句:是指跳出所在方法,结束该方法的运行。
|
||||

|
||||
|
||||
#### 1.5.5 方法的四种类型
|
||||
|
||||
1、无参数无返回值的方法
|
||||
|
||||
```java
|
||||
// 无参数无返回值的方法(如果方法没有返回值,不能不写,必须写void,表示没有返回值)
|
||||
public void f1() {
|
||||
System.out.println("无参数无返回值的方法");
|
||||
}
|
||||
```
|
||||
|
||||
2、有参数无返回值的方法
|
||||
|
||||
```java
|
||||
/**
|
||||
* 有参数无返回值的方法
|
||||
@ -222,6 +230,7 @@ public void f2(int a, String b, int c) {
|
||||
}
|
||||
```
|
||||
3、有返回值无参数的方法
|
||||
|
||||
```java
|
||||
// 有返回值无参数的方法(返回值可以是任意的类型,在函数里面必须有return关键字返回对应的类型)
|
||||
public int f3() {
|
||||
@ -230,6 +239,7 @@ public int f3() {
|
||||
}
|
||||
```
|
||||
4、有返回值有参数的方法
|
||||
|
||||
```java
|
||||
// 有返回值有参数的方法
|
||||
public int f4(int a, int b) {
|
||||
@ -237,6 +247,7 @@ public int f4(int a, int b) {
|
||||
}
|
||||
```
|
||||
5、return在无返回值方法的特殊使用
|
||||
|
||||
```java
|
||||
// return在无返回值方法的特殊使用
|
||||
public void f5(int a) {
|
||||
@ -248,7 +259,11 @@ public void f5(int a) {
|
||||
```
|
||||
|
||||
## 2. Java面向对象
|
||||
|
||||
## 2. Java 面向对象
|
||||
|
||||
### 2.1 类和对象
|
||||
|
||||
#### 2.1.1 面向对象和面向过程的区别
|
||||
|
||||
- **面向过程** :**面向过程性能比面向对象高。** 因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix 等一般采用面向过程开发。但是,**面向过程没有面向对象易维护、易复用、易扩展。**
|
||||
@ -281,7 +296,7 @@ new 运算符,new 创建对象实例(对象实例在堆内存中),对象
|
||||
|
||||
#### 2.1.6 一个类的构造方法的作用是什么? 若一个类没有声明构造方法,该程序能正确执行吗? 为什么?
|
||||
|
||||
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。如果我们自己添加了类的构造方法(无论是否有参),Java就不会再添加默认的无参数的构造方法了,这时候,就不能直接new一个对象而不传递参数了,所以我们一直在不知不觉地使用构造方法,这也是为什么我们在创建对象的时候后面要加一个括号(因为要调用无参的构造方法)。如果我们重载了有参的构造方法,记得都要把无参的构造方法也写出来(无论是否用到),因为这可以帮助我们在创建对象的时候少踩坑。
|
||||
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。如果我们自己添加了类的构造方法(无论是否有参),Java 就不会再添加默认的无参数的构造方法了,这时候,就不能直接 new 一个对象而不传递参数了,所以我们一直在不知不觉地使用构造方法,这也是为什么我们在创建对象的时候后面要加一个括号(因为要调用无参的构造方法)。如果我们重载了有参的构造方法,记得都要把无参的构造方法也写出来(无论是否用到),因为这可以帮助我们在创建对象的时候少踩坑。
|
||||
|
||||
#### 2.1.7 构造方法有哪些特性?
|
||||
|
||||
@ -300,6 +315,7 @@ new 运算符,new 创建对象实例(对象实例在堆内存中),对象
|
||||
### 2.2 面向对象三大特征
|
||||
|
||||
#### 2.2.1 封装
|
||||
|
||||
封装是指把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外界访问的方法来操作属性。就好像我们看不到挂在墙上的空调的内部的零件信息(也就是属性),但是可以通过遥控器(方法)来控制空调。如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。就好像如果没有空调遥控器,那么我们就无法操控空凋制冷,空调本身就没有意义了(当然现在还有很多其他方法 ,这里只是为了举例子)。
|
||||
|
||||
```java
|
||||
@ -340,6 +356,7 @@ public class Student {
|
||||
3. 子类可以用自己的方式实现父类的方法。(以后介绍)。
|
||||
|
||||
#### 2.2.3 多态
|
||||
|
||||
多态,顾名思义,表示一个对象具有多种的状态。具体表现为父类的引用指向子类的实例。
|
||||
|
||||
**多态的特点:**
|
||||
@ -352,6 +369,7 @@ public class Student {
|
||||
- 如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。
|
||||
|
||||
### 2.3 修饰符
|
||||
|
||||
#### 2.3.1 在一个静态方法内调用一个非静态成员为什么是非法的?
|
||||
|
||||
由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。
|
||||
@ -388,6 +406,7 @@ public class Student {
|
||||
3. Jdk 9 在接口中引入了私有方法和私有静态方法。
|
||||
|
||||
### 2.5 类的扩展
|
||||
|
||||
#### 2.5.1 String StringBuffer 和 StringBuilder 的区别是什么? String 为什么是不可变的?
|
||||
|
||||
简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,`private final char value[]`,所以 String 对象是不可变的。
|
||||
@ -417,7 +436,6 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}}
|
||||
```
|
||||
|
||||
|
||||
**线程安全性**
|
||||
|
||||
String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
|
||||
@ -524,25 +542,26 @@ BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
|
||||
String s = input.readLine();
|
||||
```
|
||||
|
||||
## 3. Java核心技术
|
||||
## 3. Java 核心技术
|
||||
|
||||
### 3.1 集合
|
||||
|
||||
#### 3.1.1 Collections 工具类和 Arrays 工具类常见方法总结
|
||||
|
||||
详见笔主的这篇文章: https://gitee.com/SnailClimb/JavaGuide/blob/master/docs/java/basic/Arrays,CollectionsCommonMethods.md
|
||||
|
||||
### 3.2 异常
|
||||
|
||||
#### 3.2.1 Java 异常类层次结构图
|
||||
|
||||

|
||||
|
||||
<p style="font-size:13px;text-align:right">图片来自:https://simplesnippets.tech/exception-handling-in-java-part-1/</p>
|
||||
|
||||
|
||||

|
||||
|
||||
<p style="font-size:13px;text-align:right">图片来自:https://chercher.tech/java-programming/exceptions-java</p>
|
||||
|
||||
|
||||
在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 **Throwable 类**。Throwable: 有两个重要的子类:**Exception(异常)** 和 **Error(错误)** ,二者都是 Java 异常处理的重要子类,各自都包含大量子类。
|
||||
|
||||
**Error(错误):是程序无法处理的错误**,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java 虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。
|
||||
@ -595,6 +614,7 @@ public class Test {
|
||||
如果调用 `f(2)`,返回值将是 0,因为 finally 语句的返回值覆盖了 try 语句块的返回值。
|
||||
|
||||
### 3.3 多线程
|
||||
|
||||
#### 3.3.1 简述线程、程序、进程的基本概念。以及他们之间关系是什么?
|
||||
|
||||
**线程**与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
|
||||
@ -624,7 +644,8 @@ Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种
|
||||
|
||||
当线程执行 `wait()`方法之后,线程进入 **WAITING(等待)**状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而 **TIME_WAITING(超时等待)** 状态相当于在等待状态的基础上增加了超时限制,比如通过 `sleep(long millis)`方法或 `wait(long millis)`方法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到 **BLOCKED(阻塞)** 状态。线程在执行 Runnable 的`run()`方法之后将会进入到 **TERMINATED(终止)** 状态。
|
||||
|
||||
### 3.3 文件与I\O流
|
||||
### 3.3 文件与 I\O 流
|
||||
|
||||
#### 3.3.1 Java 中 IO 流分为几种?
|
||||
|
||||
- 按照流的流向分,可以分为输入流和输出流;
|
||||
|
@ -104,6 +104,13 @@ I love JavaGuide
|
||||
value is JavaGuide
|
||||
```
|
||||
|
||||
**注意** : 有读者提到上面代码运行会抛出 `ClassNotFoundException` 异常,具体原因是你没有下面把这段代码的包名替换成自己创建的 `TargetObject` 所在的包 。
|
||||
|
||||
```java
|
||||
Class<?> tagetClass = Class.forName("cn.javaguide.TargetObject");
|
||||
```
|
||||
|
||||
|
||||
### 静态编译和动态编译
|
||||
|
||||
- **静态编译:** 在编译时确定类型,绑定对象
|
||||
|
@ -85,6 +85,8 @@ public interface RandomAccess {
|
||||
|
||||
**双向链表:** 包含两个指针,一个prev指向前一个节点,一个next指向后一个节点。
|
||||
|
||||
> 另外推荐一篇把双向链表讲清楚的文章:[https://juejin.im/post/5b5d1a9af265da0f47352f14](https://juejin.im/post/5b5d1a9af265da0f47352f14)
|
||||
|
||||

|
||||
|
||||
**双向循环链表:** 最后一个节点的 next 指向head,而 head 的prev指向最后一个节点,构成一个环。
|
||||
|
Loading…
x
Reference in New Issue
Block a user