1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-08-05 20:31:37 +08:00

Compare commits

...

6 Commits

Author SHA1 Message Date
Guide
b1f22a064d
Merge pull request #2198 from Mister-Hope/main
更新依赖、格式化文档以及部分细节修复
2023-10-27 23:21:50 +08:00
Mr.Hope
114342995c style: update linter 2023-10-27 06:49:28 +08:00
Mr.Hope
7ea99a88d7 style: update linter 2023-10-27 06:44:02 +08:00
Mr.Hope
5e58e830eb chore: update deps 2023-10-27 06:22:14 +08:00
Guide
4ca9af21a6
Merge pull request #2193 from zouzanyan/patch-2
Update java9.md
2023-10-26 08:12:15 +08:00
zouzanyan
56e93ff8ad
Update java9.md
错别字
2023-10-16 16:08:42 +08:00
215 changed files with 4926 additions and 7739 deletions

View File

@ -51,26 +51,35 @@ export default hopeTheme({
plugins: {
blog: true,
copyright: {
author: "JavaGuide(javaguide.cn)",
license: "MIT",
triggerLength: 100,
maxLength: 700,
canonical: "https://javaguide.cn/",
global:true
global: true,
},
feed: {
atom: true,
json: true,
rss: true,
},
mdEnhance: {
align: true,
codetabs: true,
container: true,
figure: true,
gfm: true,
include: {
resolvePath: (file, cwd) => {
if (file.startsWith("@"))
return path.resolve(
__dirname,
"../snippets",
file.replace("@", "./")
file.replace("@", "./"),
);
return path.resolve(cwd, file);
@ -78,10 +87,5 @@ export default hopeTheme({
},
tasklist: true,
},
feed: {
atom: true,
json: true,
rss: true,
},
},
});

View File

@ -42,7 +42,7 @@ icon: "java"
Java 8 算是一个里程碑式的版本,现在一般企业还是用 Java 8 比较多。掌握 Java 8 的一些新特性比如 Lambda、Stream API 还是挺有必要的。这块的话,我推荐 **[《Java 8 实战》](https://book.douban.com/subject/26772632/)** 这本书。
**[《Java 编程的逻辑》](https://book.douban.com/subject/30133440/)**
**[《Java 编程的逻辑》](https://book.douban.com/subject/30133440/)**
![《Java编程的逻辑》](https://oss.javaguide.cn/github/javaguide/books/image-20230721153650488.png)
@ -131,7 +131,7 @@ Java 8 算是一个里程碑式的版本,现在一般企业还是用 Java 8
- **IDEA**:熟悉基本操作以及常用快捷。相关资料: [《IntelliJ IDEA 简体中文专题教程》](https://github.com/judasn/IntelliJ-IDEA-Tutorial) 。
- **Maven**:强烈建议学习常用框架之前可以提前花几天时间学习一下**Maven**的使用。(到处找 Jar 包,下载 Jar 包是真的麻烦费事,使用 Maven 可以为你省很多事情)。相关阅读:[Maven 核心概念总结](https://javaguide.cn/tools/maven/maven-core-concepts.html)。
- **Git**:基本的 Git 技能也是必备的,试着在学习的过程中将自己的代码托管在 Github 上。相关阅读:[Git 核心概念总结](https://javaguide.cn/tools/git/git-intro.html)。
- **Docker**:学着用 Docker 安装学习中需要用到的软件比如 MySQL ,这样方便很多,可以为你节省不少时间。相关资料:[《Docker - 从入门到实践》](https://yeasy.gitbook.io/docker_practice/)
- **Docker**:学着用 Docker 安装学习中需要用到的软件比如 MySQL ,这样方便很多,可以为你节省不少时间。相关资料:[《Docker - 从入门到实践》](https://yeasy.gitbook.io/docker_practice/) 。
除了这些工具之外,我强烈建议你一定要搞懂 GitHub 的使用。一些使用 GitHub 的小技巧,你可以看[Github 实用小技巧总结](https://javaguide.cn/tools/git/github-tips.html)这篇文章。

View File

@ -26,8 +26,8 @@ tag:
上图存在错误:
1. 插入排序的最好时间复杂度为 O(n) 而不是 O(n^2)
2. 希尔排序的平均时间复杂度为 O(nlogn)
1. 插入排序的最好时间复杂度为 $O(n)$ 而不是 $O(n^2)$
2. 希尔排序的平均时间复杂度为 $O(nlogn)$。
**图片名词解释:**
@ -38,8 +38,8 @@ tag:
### 术语说明
- **稳定**:如果 A 原本在 B 前面,而 A=B排序之后 A 仍然在 B 的前面。
- **不稳定**:如果 A 原本在 B 的前面,而 A=B排序之后 A 可能会出现在 B 的后面。
- **稳定**:如果 A 原本在 B 前面,而 $A=B$,排序之后 A 仍然在 B 的前面。
- **不稳定**:如果 A 原本在 B 的前面,而 $A=B$,排序之后 A 可能会出现在 B 的后面。
- **内排序**:所有排序操作都在内存中完成。
- **外排序**:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行。
- **时间复杂度**:定性描述一个算法执行所耗费的时间。
@ -55,7 +55,7 @@ tag:
比较类排序的优势是,适用于各种规模的数据,也不在乎数据的分布,都能进行排序。可以说,比较排序适用于一切需要排序的情况。
而**计数排序**、**基数排序**、**桶排序**则属于**非比较类排序算法**。非比较排序不通过比较来决定元素间的相对次序,而是通过确定每个元素之前,应该有多少个元素来排序。由于它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。 非比较排序只要确定每个元素之前的已有的元素个数即可,所有一次遍历即可解决。算法时间复杂度 `O(n)`
而**计数排序**、**基数排序**、**桶排序**则属于**非比较类排序算法**。非比较排序不通过比较来决定元素间的相对次序,而是通过确定每个元素之前,应该有多少个元素来排序。由于它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。 非比较排序只要确定每个元素之前的已有的元素个数即可,所有一次遍历即可解决。算法时间复杂度 $O(n)$
非比较排序时间复杂度底,但由于非比较排序需要占用空间来确定唯一位置。所以对数据规模和数据分布有一定的要求。
@ -109,13 +109,13 @@ public static int[] bubbleSort(int[] arr) {
### 算法分析
- **稳定性**:稳定
- **时间复杂度**最佳O(n) 最差O(n2) 平均O(n2)
- **空间复杂度**O(1)
- **时间复杂度**:最佳:$O(n)$ ,最差:$O(n^2)$ 平均:$O(n^2)$
- **空间复杂度**$O(1)$
- **排序方式**In-place
## 选择排序 (Selection Sort)
选择排序是一种简单直观的排序算法,无论什么数据进去都是 `O(n²)` 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
选择排序是一种简单直观的排序算法,无论什么数据进去都是 $O(n^2)$ 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
### 算法步骤
@ -156,13 +156,13 @@ public static int[] selectionSort(int[] arr) {
### 算法分析
- **稳定性**:不稳定
- **时间复杂度**最佳O(n2) 最差O(n2) 平均O(n2)
- **空间复杂度**O(1)
- **时间复杂度**:最佳:$O(n^2)$ ,最差:$O(n^2)$ 平均:$O(n^2)$
- **空间复杂度**$O(1)$
- **排序方式**In-place
## 插入排序 (Insertion Sort)
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用 in-place 排序(即只需用到 `O(1)` 的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用 in-place 排序(即只需用到 $O(1)$ 的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
@ -206,25 +206,25 @@ public static int[] insertionSort(int[] arr) {
### 算法分析
- **稳定性**:稳定
- **时间复杂度**最佳O(n) 最差O(n2) 平均O(n2)
- **空间复杂度**O(1)
- **时间复杂度**:最佳:$O(n)$ ,最差:$O(n^2)$ 平均:$O(n2)$
- **空间复杂度**O(1)$
- **排序方式**In-place
## 希尔排序 (Shell Sort)
希尔排序是希尔 (Donald Shell) 于 1959 年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为递减增量排序算法,同时该算法是冲破 `O(n²)` 的第一批算法之一。
希尔排序是希尔 (Donald Shell) 于 1959 年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为递减增量排序算法,同时该算法是冲破 $O(n^2)$ 的第一批算法之一。
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 “基本有序” 时,再对全体记录进行依次直接插入排序。
### 算法步骤
我们来看下希尔排序的基本步骤,在此我们选择增量 `gap=length/2`,缩小增量继续以 `gap = gap/2` 的方式,这种增量选择我们可以用一个序列来表示,`{n/2, (n/2)/2, ..., 1}`,称为**增量序列**。希尔排序的增量序列的选择与证明是个数学难题,我们选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。此处我们做示例使用希尔增量。
我们来看下希尔排序的基本步骤,在此我们选择增量 $gap=length/2$,缩小增量继续以 $gap = gap/2$ 的方式,这种增量选择我们可以用一个序列来表示,$\lbrace \frac{n}{2}, \frac{(n/2)}{2}, \dots, 1 \rbrace$,称为**增量序列**。希尔排序的增量序列的选择与证明是个数学难题,我们选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。此处我们做示例使用希尔增量。
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:
- 选择一个增量序列 `{t1, t2, …, tk}`,其中 `(ti>tj, i<j, tk=1)`
- 选择一个增量序列 $\lbrace t_1, t_2, \dots, t_k \rbrace$,其中 $t_i \gt t_j, i \lt j, t_k = 1$
- 按增量序列个数 k对序列进行 k 趟排序;
- 每趟排序,根据对应的增量 `t`,将待排序列分割成若干长度为 `m` 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
- 每趟排序,根据对应的增量 $t$,将待排序列分割成若干长度为 $m$ 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
### 图解算法
@ -263,24 +263,24 @@ public static int[] shellSort(int[] arr) {
### 算法分析
- **稳定性**:不稳定
- **时间复杂度**:最佳:O(nlogn) 最差O(n^2) 平均O(nlogn)
- **空间复杂度**`O(1)`
- **时间复杂度**:最佳:$O(nlogn)$ 最差:$O(n^2)$ 平均:$O(nlogn)$
- **空间复杂度**$O(1)$
## 归并排序 (Merge Sort)
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法 (Divide and Conquer) 的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为 2 - 路归并。
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 `O(nlogn)` 的时间复杂度。代价是需要额外的内存空间。
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 $O(nlogn)$ 的时间复杂度。代价是需要额外的内存空间。
### 算法步骤
归并排序算法是一个递归过程,边界条件为当输入序列仅有一个元素时,直接返回,具体过程如下:
1. 如果输入内只有一个元素,则直接返回,否则将长度为 `n` 的输入序列分成两个长度为 `n/2` 的子序列;
1. 如果输入内只有一个元素,则直接返回,否则将长度为 $n$ 的输入序列分成两个长度为 $n/2$ 的子序列;
2. 分别对这两个子序列进行归并排序,使子序列变为有序状态;
3. 设定两个指针,分别指向两个已经排序子序列的起始位置;
4. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间(用于存放排序结果),并移动指针到下一位置;
5. 重复步骤 3 ~4 直到某一指针达到序列尾;
5. 重复步骤 3 ~ 4 直到某一指针达到序列尾;
6. 将另一序列剩下的所有元素直接复制到合并序列尾。
### 图解算法
@ -346,8 +346,8 @@ public static int[] merge(int[] arr_1, int[] arr_2) {
### 算法分析
- **稳定性**:稳定
- **时间复杂度**最佳O(nlogn) 最差O(nlogn) 平均O(nlogn)
- **空间复杂度**O(n)
- **时间复杂度**:最佳:$O(nlogn)$ 最差:$O(nlogn)$ 平均:$O(nlogn)$
- **空间复杂度**$O(n)$
## 快速排序 (Quick Sort)
@ -401,8 +401,8 @@ public static void quickSort(int[] array, int low, int high) {
### 算法分析
- **稳定性**:不稳定
- **时间复杂度**最佳O(nlogn) 最差O(nlogn)平均O(nlogn)
- **空间复杂度**O(logn)
- **时间复杂度**:最佳:$O(nlogn)$ 最差:$O(nlogn)$,平均:$O(nlogn)$
- **空间复杂度**$O(logn)$
## 堆排序 (Heap Sort)
@ -410,9 +410,9 @@ public static void quickSort(int[] array, int low, int high) {
### 算法步骤
1. 将初始待排序列 `(R1, R2, ……, Rn)` 构建成大顶堆,此堆为初始的无序区;
2. 将堆顶元素 `R[1]` 与最后一个元素 `R[n]` 交换,此时得到新的无序区 `(R1, R2, ……, Rn-1)` 和新的有序区 (Rn), 且满足 `R[1, 2, ……, n-1]<=R[n]`
3. 由于交换后新的堆顶 `R[1]` 可能违反堆的性质,因此需要对当前无序区 `(R1, R2, ……, Rn-1)` 调整为新堆,然后再次将 R [1] 与无序区最后一个元素交换,得到新的无序区 `(R1, R2, ……, Rn-2)` 和新的有序区 `(Rn-1, Rn)`。不断重复此过程直到有序区的元素个数为 `n-1`,则整个排序过程完成。
1. 将初始待排序列 $(R_1, R_2, \dots, R_n)$ 构建成大顶堆,此堆为初始的无序区;
2. 将堆顶元素 $R_1$ 与最后一个元素 $R_n$ 交换,此时得到新的无序区 $(R_1, R_2, \dots, R_{n-1})$ 和新的有序区 $R_n$, 且满足 $R_i \leqslant R_n (i \in 1, 2,\dots, n-1)$
3. 由于交换后新的堆顶 $R_1$ 可能违反堆的性质,因此需要对当前无序区 $(R_1, R_2, \dots, R_{n-1})$ 调整为新堆,然后再次将 $R_1$ 与无序区最后一个元素交换,得到新的无序区 $(R_1, R_2, \dots, R_{n-2})$ 和新的有序区 $(R_{n-1}, R_n)$。不断重复此过程直到有序区的元素个数为 $n-1$,则整个排序过程完成。
### 图解算法
@ -490,8 +490,8 @@ public static int[] heapSort(int[] arr) {
### 算法分析
- **稳定性**:不稳定
- **时间复杂度**最佳O(nlogn) 最差O(nlogn) 平均O(nlogn)
- **空间复杂度**O(1)
- **时间复杂度**:最佳:$O(nlogn)$ 最差:$O(nlogn)$ 平均:$O(nlogn)$
- **空间复杂度**$O(1)$
## 计数排序 (Counting Sort)
@ -503,10 +503,10 @@ public static int[] heapSort(int[] arr) {
1. 找出数组中的最大值 `max`、最小值 `min`
2. 创建一个新数组 `C`,其长度是 `max-min+1`,其元素默认值都为 0
3. 遍历原数组 `A` 中的元素 `A[i]`,以 `A[i]-min` 作为 `C` 数组的索引,以 `A[i]` 的值在 `A` 中元素出现次数作为 `C[A[i]-min]` 的值;
3. 遍历原数组 `A` 中的元素 `A[i]`,以 `A[i] - min` 作为 `C` 数组的索引,以 `A[i]` 的值在 `A` 中元素出现次数作为 `C[A[i] - min]` 的值;
4. 对 `C` 数组变形,**新元素的值是该元素与前一个元素值的和**,即当 `i>1``C[i] = C[i] + C[i-1]`
5. 创建结果数组 `R`,长度和原始数组一样。
6. **从后向前**遍历原始数组 `A` 中的元素 `A[i]`,使用 `A[i]` 减去最小值 `min` 作为索引,在计数数组 `C` 中找到对应的值 `C[A[i]-min]``C[A[i]-min]-1` 就是 `A[i]` 在结果数组 `R` 中的位置,做完上述这些操作,将 `count[A[i]-min]` 减小 1。
6. **从后向前**遍历原始数组 `A` 中的元素 `A[i]`,使用 `A[i]` 减去最小值 `min` 作为索引,在计数数组 `C` 中找到对应的值 `C[A[i] - min]``C[A[i] - min] - 1` 就是 `A[i]` 在结果数组 `R` 中的位置,做完上述这些操作,将 `count[A[i] - min]` 减小 1。
### 图解算法
@ -567,10 +567,10 @@ public static int[] countingSort(int[] arr) {
## 算法分析
当输入的元素是 `n``0``k` 之间的整数时,它的运行时间是 `O(n+k)`。计数排序不是比较排序,排序的速度快于任何比较排序算法。由于用来计数的数组 `C` 的长度取决于待排序数组中数据的范围(等于待排序数组的**最大值与最小值的差加上 1**),这使得计数排序对于数据范围很大的数组,需要大量额外内存空间。
当输入的元素是 `n``0``k` 之间的整数时,它的运行时间是 $O(n+k)$。计数排序不是比较排序,排序的速度快于任何比较排序算法。由于用来计数的数组 `C` 的长度取决于待排序数组中数据的范围(等于待排序数组的**最大值与最小值的差加上 1**),这使得计数排序对于数据范围很大的数组,需要大量额外内存空间。
- **稳定性**:稳定
- **时间复杂度**:最佳:`O(n+k)` 最差:`O(n+k)` 平均:`O(n+k)`
- **时间复杂度**:最佳:$O(n+k)$ 最差:$O(n+k)$ 平均:$O(n+k)$
- **空间复杂度**`O(k)`
## 桶排序 (Bucket Sort)
@ -653,22 +653,22 @@ public static List<Integer> bucketSort(List<Integer> arr, int bucket_size) {
### 算法分析
- **稳定性**:稳定
- **时间复杂度**:最佳:`O(n+k)` 最差:`O(n²)` 平均:`O(n+k)`
- **空间复杂度**`O(n+k)`
- **时间复杂度**:最佳:$O(n+k)$ 最差:$O(n^2)$ 平均:$O(n+k)$
- **空间复杂度**$O(n+k)$
## 基数排序 (Radix Sort)
基数排序也是非比较的排序算法,对元素中的每一位数字进行排序,从最低位开始排序,复杂度为 `O(n×k)``n` 为数组长度,`k` 为数组中元素的最大的位数;
基数排序也是非比较的排序算法,对元素中的每一位数字进行排序,从最低位开始排序,复杂度为 $O(n×k)$$n$ 为数组长度,$k$ 为数组中元素的最大的位数;
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。
### 算法步骤
1. 取得数组中的最大数,并取得位数,即为迭代次数 `N`(例如:数组中最大数值为 1000`N=4`
1. 取得数组中的最大数,并取得位数,即为迭代次数 $N$(例如:数组中最大数值为 1000则 $N=4$
2. `A` 为原始数组,从最低位开始取每个位组成 `radix` 数组;
3. 对 `radix` 进行计数排序(利用计数排序适用于小范围数的特点);
4. 将 `radix` 依次赋值给原数组;
5. 重复 2~4 步骤 `N`
5. 重复 2~4 步骤 $N$
### 图解算法
@ -721,8 +721,8 @@ public static int[] radixSort(int[] arr) {
### 算法分析
- **稳定性**:稳定
- **时间复杂度**:最佳:`O(n×k)` 最差:`O(n×k)` 平均:`O(n×k)`
- **空间复杂度**`O(n+k)`
- **时间复杂度**:最佳:$O(n×k)$ 最差:$O(n×k)$ 平均:$O(n×k)$
- **空间复杂度**$O(n+k)$
**基数排序 vs 计数排序 vs 桶排序**

View File

@ -140,9 +140,9 @@ MySQL 内存临时表不支持 TEXT、BLOB 这样的大数据类型,如果查
| 类型 | 存储空间 | 日期格式 | 日期范围 | 是否带时区信息 |
| ------------ | -------- | ------------------------------ | ------------------------------------------------------------ | -------------- |
| DATETIME | 5~8 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1000-01-01 00:00:00[.000000] 9999-12-31 23:59:59[.999999] | 否 |
| TIMESTAMP | 4~7 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1970-01-01 00:00:01[.000000] 2038-01-19 03:14:07[.999999] | 是 |
| 数值型时间戳 | 4 字节 | 全数字如 1578707612 | 1970-01-01 00:00:01 之后的时间 | 否 |
| DATETIME | 5~8 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1000-01-01 00:00:00[.000000] 9999-12-31 23:59:59[.999999] | 否 |
| TIMESTAMP | 4~7 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1970-01-01 00:00:01[.000000] 2038-01-19 03:14:07[.999999] | 是 |
| 数值型时间戳 | 4 字节 | 全数字如 1578707612 | 1970-01-01 00:00:01 之后的时间 | 否 |
MySQL 时间类型选择的详细介绍请看这篇:[MySQL 时间类型数据存储建议](https://javaguide.cn/database/mysql/some-thoughts-on-database-storage-time.html)。

View File

@ -163,9 +163,8 @@ MySQL 中时间到底怎么存储才好Datetime?Timestamp?还是数值时间
| 类型 | 存储空间 | 日期格式 | 日期范围 | 是否带时区信息 |
| ------------ | -------- | ------------------------------ | ------------------------------------------------------------ | -------------- |
| DATETIME | 5~8 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1000-01-01 00:00:00[.000000] 9999-12-31 23:59:59[.999999] | 否 |
| TIMESTAMP | 4~7 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1970-01-01 00:00:01[.000000] 2038-01-19 03:14:07[.999999] | 是 |
| 数值型时间戳 | 4 字节 | 全数字如 1578707612 | 1970-01-01 00:00:01 之后的时间 | 否 |
| DATETIME | 5~8 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1000-01-01 00:00:00[.000000] 9999-12-31 23:59:59[.999999] | 否 |
| TIMESTAMP | 4~7 字节 | YYYY-MM-DD hh:mm:ss[.fraction] | 1970-01-01 00:00:01[.000000] 2038-01-19 03:14:07[.999999] | 是 |
| 数值型时间戳 | 4 字节 | 全数字如 1578707612 | 1970-01-01 00:00:01 之后的时间 | 否 |
<!-- @include: @article-footer.snippet.md -->

View File

@ -47,19 +47,19 @@ String 是一种二进制安全的数据类型,可以用来存储任何类型
### 常用命令
| 命令 | 介绍 |
| ------------------------------ | -------------------------------- |
| SET key value | 设置指定 key 的值 |
| SETNX key value | 只有在 key 不存在时设置 key 的值 |
| GET key | 获取指定 key 的值 |
| 命令 | 介绍 |
| ------------------------------- | -------------------------------- |
| SET key value | 设置指定 key 的值 |
| SETNX key value | 只有在 key 不存在时设置 key 的值 |
| GET key | 获取指定 key 的值 |
| MSET key1 value1 key2 value2 …… | 设置一个或多个指定 key 的值 |
| MGET key1 key2 ... | 获取一个或多个指定 key 的值 |
| STRLEN key | 返回 key 所储存的字符串值的长度 |
| INCR key | 将 key 中储存的数字值增一 |
| DECR key | 将 key 中储存的数字值减一 |
| EXISTS key | 判断指定 key 是否存在 |
| DEL key通用 | 删除指定的 key |
| EXPIRE key seconds通用 | 给指定 key 设置过期时间 |
| MGET key1 key2 ... | 获取一个或多个指定 key 的值 |
| STRLEN key | 返回 key 所储存的字符串值的长度 |
| INCR key | 将 key 中储存的数字值增一 |
| DECR key | 将 key 中储存的数字值减一 |
| EXISTS key | 判断指定 key 是否存在 |
| DEL key通用 | 删除指定的 key |
| EXPIRE key seconds通用 | 给指定 key 设置过期时间 |
更多 Redis String 命令以及详细使用指南,请查看 Redis 官网对应的介绍:<https://redis.io/commands/?group=string>
@ -485,13 +485,13 @@ value1
## 总结
| 数据类型 | 说明 |
| -------------------------------- | ------------------------------------------------- |
| String | 一种二进制安全的数据类型,可以用来存储任何类型的数据比如字符串、整数、浮点数、图片(图片的 base64 编码或者解码或者图片的路径)、序列化后的对象。 |
| List | Redis 的 List 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。 |
| Hash | 一个 String 类型的 field-value键值对 的映射表,特别适合用于存储对象,后续操作的时候,你可以直接修改这个对象中的某些字段的值。 |
| Set | 无序集合,集合中的元素没有先后顺序但都唯一,有点类似于 Java 中的 `HashSet` 。 |
| Zset | 和 Set 相比Sorted Set 增加了一个权重参数 `score`,使得集合中的元素能够按 `score` 进行有序排列,还可以通过 `score` 的范围来获取元素的列表。有点像是 Java 中 `HashMap``TreeSet` 的结合体。 |
| 数据类型 | 说明 |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| String | 一种二进制安全的数据类型,可以用来存储任何类型的数据比如字符串、整数、浮点数、图片(图片的 base64 编码或者解码或者图片的路径)、序列化后的对象。 |
| List | Redis 的 List 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。 |
| Hash | 一个 String 类型的 field-value键值对 的映射表,特别适合用于存储对象,后续操作的时候,你可以直接修改这个对象中的某些字段的值。 |
| Set | 无序集合,集合中的元素没有先后顺序但都唯一,有点类似于 Java 中的 `HashSet` |
| Zset | 和 Set 相比Sorted Set 增加了一个权重参数 `score`,使得集合中的元素能够按 `score` 进行有序排列,还可以通过 `score` 的范围来获取元素的列表。有点像是 Java 中 `HashMap``TreeSet` 的结合体。 |
## 参考

View File

@ -211,11 +211,11 @@ user2
## 总结
| 数据类型 | 说明 |
| ---------------- | ------------------------------------------------------------ |
| 数据类型 | 说明 |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bitmap | 你可以将 Bitmap 看作是一个存储二进制数字0 和 1的数组数组中每个元素的下标叫做 offset偏移量。通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte所以 Bitmap 本身会极大的节省储存空间。 |
| HyperLogLog | Redis 提供的 HyperLogLog 占用空间非常非常小,只需要 12k 的空间就能存储接近`2^64`个不同元素。不过HyperLogLog 的计数结果并不是一个精确值,存在一定的误差(标准误差为 `0.81%` )。 |
| Geospatial index | Geospatial index地理空间索引简称 GEO 主要用于存储地理位置信息,基于 Sorted Set 实现。 |
| HyperLogLog | Redis 提供的 HyperLogLog 占用空间非常非常小,只需要 12k 的空间就能存储接近`2^64`个不同元素。不过HyperLogLog 的计数结果并不是一个精确值,存在一定的误差(标准误差为 `0.81%` )。 |
| Geospatial index | Geospatial index地理空间索引简称 GEO 主要用于存储地理位置信息,基于 Sorted Set 实现。 |
## 参考

View File

@ -259,13 +259,13 @@ struct __attribute__ ((__packed__)) sdshdr64 {
通过源码可以看出SDS 共有五种实现方式 SDS_TYPE_5并未用到、SDS_TYPE_8、SDS_TYPE_16、SDS_TYPE_32、SDS_TYPE_64其中只有后四种实际用到。Redis 会根据初始化的长度决定使用哪种类型,从而减少内存的使用。
| 类型 | 字节 | 位 |
| -------- | ---- | ---- |
| sdshdr5 | < 1 | <8 |
| sdshdr8 | 1 | 8 |
| sdshdr16 | 2 | 16 |
| sdshdr32 | 4 | 32 |
| sdshdr64 | 8 | 64 |
| 类型 | 字节 | 位 |
| -------- | ---- | --- |
| sdshdr5 | < 1 | <8 |
| sdshdr8 | 1 | 8 |
| sdshdr16 | 2 | 16 |
| sdshdr32 | 4 | 32 |
| sdshdr64 | 8 | 64 |
对于后四种实现都包含了下面这 4 个属性:

View File

@ -496,7 +496,7 @@ Redis 中的大部分命令都是 O(1)时间复杂度,但也有少部分 O(n)
⚠️注意:由于慢查询日志会占用一定内存空间,如果设置最大记录条数过大,可能会导致内存占用过高的问题。
`slowlog-log-slower-than``slowlog-max-len`的默认配置如下(可以自行修改)
`slowlog-log-slower-than``slowlog-max-len`的默认配置如下(可以自行修改)
```nginx
# The following time is expressed in microseconds, so 1000000 is equivalent

View File

@ -189,17 +189,17 @@ ORDER BY vend_name DESC
下面的运算符可以在 `WHERE` 子句中使用:
| 运算符 | 描述 |
| :------ | :--------------------------------------------------------- |
| = | 等于 |
| 运算符 | 描述 |
| :------ | :----------------------------------------------------------- |
| = | 等于 |
| <> | 不等于。 **注释:** 在 SQL 的一些版本中,该操作符可被写成 != |
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| BETWEEN | 在某个范围内 |
| LIKE | 搜索某种模式 |
| IN | 指定针对某个列的多个可能值 |
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| BETWEEN | 在某个范围内 |
| LIKE | 搜索某种模式 |
| IN | 指定针对某个列的多个可能值 |
### 返回固定价格的产品

View File

@ -27,14 +27,14 @@ SQL 插入记录的方式汇总:
试卷作答记录表`exam_record`中,表已建好,其结构如下,请用一条语句将这两条记录插入表中。
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
**答案**
@ -51,14 +51,14 @@ INSERT INTO exam_record (uid, exam_id, start_time, submit_time, score) VALUES
`exam_record`
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
我们已经创建了一张新表`exam_record_before_2021`用来备份 2021 年之前的试题作答记录,结构和`exam_record`表一致,请将 2021 年之前的已完成了的试题作答纪录导入到该表。
@ -77,14 +77,14 @@ WHERE YEAR(submit_time) < 2021;
试题信息表`examination_info`
| Filed | Type | Null | Key | Extra | Default | Comment |
| ------------ | ----------- | ---- | ---- | -------------- | ------- | ------------ |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| exam_id | int(11) | NO | UNI | | (NULL) | 试卷 ID |
| tag | varchar(32) | YES | | | (NULL) | 类别标签 |
| difficulty | varchar(8) | YES | | | (NULL) | 难度 |
| duration | int(11) | NO | | | (NULL) | 时长(分钟数) |
| release_time | datetime | YES | | | (NULL) | 发布时间 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ------------ | ----------- | ---- | --- | -------------- | ------- | ------------ |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| exam_id | int(11) | NO | UNI | | (NULL) | 试卷 ID |
| tag | varchar(32) | YES | | | (NULL) | 类别标签 |
| difficulty | varchar(8) | YES | | | (NULL) | 难度 |
| duration | int(11) | NO | | | (NULL) | 时长(分钟数) |
| release_time | datetime | YES | | | (NULL) | 发布时间 |
**答案**
@ -97,14 +97,14 @@ REPLACE INTO examination_info VALUES
**描述**:现在有一张试卷信息表 `examination_info`, 表结构如下图所示:
| Filed | Type | Null | Key | Extra | Default | Comment |
| ------------ | -------- | ---- | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| exam_id | int(11) | NO | UNI | | (NULL) | 试卷 ID |
| tag | char(32) | YES | | | (NULL) | 类别标签 |
| difficulty | char(8) | YES | | | (NULL) | 难度 |
| duration | int(11) | NO | | | (NULL) | 时长 |
| release_time | datetime | YES | | | (NULL) | 发布时间 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ------------ | -------- | ---- | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| exam_id | int(11) | NO | UNI | | (NULL) | 试卷 ID |
| tag | char(32) | YES | | | (NULL) | 类别标签 |
| difficulty | char(8) | YES | | | (NULL) | 难度 |
| duration | int(11) | NO | | | (NULL) | 时长 |
| release_time | datetime | YES | | | (NULL) | 发布时间 |
请把**examination_info**表中`tag``PYTHON``tag`字段全部修改为`Python`
@ -129,14 +129,14 @@ SET tag = REPLACE(tag,'PYTHON','Python')
**描述**:现有一张试卷作答记录表 exam_record其中包含多年来的用户作答试卷记录结构如下表作答记录表 `exam_record` **`submit_time`** 为 完成时间 (注意这句话)
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
**题目要求**:请把 `exam_record` 表中 2021 年 9 月 1 日==之前==开始作答的==未完成==记录全部改为被动完成,即:将完成时间改为'2099-01-01 00:00:00',分数改为 0。
@ -154,14 +154,14 @@ UPDATE exam_record SET submit_time = '2099-01-01 00:00:00', score = 0 WHERE DATE
作答记录表`exam_record` **`start_time`** 是试卷开始时间`submit_time` 是交卷,即结束时间。
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | ---- | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 得分 |
**要求**:请删除`exam_record`表中作答时间小于 5 分钟整且分数不及格(及格线为 60 分)的记录;
@ -194,7 +194,7 @@ YEAR
# TIMESTAMPDIFF函数返回datetime_expr2 - datetime_expr1的结果人话 后面的 - 前面的 即2-1其中datetime_expr1和datetime_expr2可以是DATE或DATETIME类型值人话可以是“2023-01-01” 也可以是“2023-01-01- 00:00:00”
```
这题需要进行分钟的比较,那么就是 TIMESTAMPDIFF(MINUTE, 开始时间, 结束时间) < 5
这题需要进行分钟的比较,那么就是 TIMESTAMPDIFF(MINUTE, 开始时间, 结束时间) < 5
**答案**
@ -212,14 +212,14 @@ DELETE FROM exam_record WHERE TIMESTAMPDIFF(MINUTE, start_time, submit_time) < 5
作答记录表`exam_record``start_time` 是试卷开始时间,`submit_time` 是交卷时间,即结束时间,如果未完成的话,则为空。
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | :--: | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 分数 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | :--: | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 分数 |
**要求**:请删除`exam_record`表中未完成作答==或==作答时间小于 5 分钟整的记录中,开始作答时间最早的 3 条记录。
@ -240,14 +240,14 @@ LIMIT 3
**描述**:现有一张试卷作答记录表 exam_record其中包含多年来的用户作答试卷记录结构如下表
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | :--: | ---- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 分数 |
| Filed | Type | Null | Key | Extra | Default | Comment |
| ----------- | ---------- | :--: | --- | -------------- | ------- | -------- |
| id | int(11) | NO | PRI | auto_increment | (NULL) | 自增 ID |
| uid | int(11) | NO | | | (NULL) | 用户 ID |
| exam_id | int(11) | NO | | | (NULL) | 试卷 ID |
| start_time | datetime | NO | | | (NULL) | 开始时间 |
| submit_time | datetime | YES | | | (NULL) | 提交时间 |
| score | tinyint(4) | YES | | | (NULL) | 分数 |
**要求**:请删除`exam_record`表中所有记录,==并重置自增主键==
@ -277,29 +277,29 @@ TRUNCATE exam_record;
原来的用户信息表:
| Filed | Type | Null | Key | Default | Extra | Comment |
| ------------- | ----------- | ---- | ---- | ----------------- | -------------- | -------- |
| id | int(11) | NO | PRI | (NULL) | auto_increment | 自增 ID |
| uid | int(11) | NO | UNI | (NULL) | | 用户 ID |
| nick_name | varchar(64) | YES | | (NULL) | | 昵称 |
| achievement | int(11) | YES | | 0 | | 成就值 |
| level | int(11) | YES | | (NULL) | | 用户等级 |
| job | varchar(32) | YES | | (NULL) | | 职业方向 |
| register_time | datetime | YES | | CURRENT_TIMESTAMP | | 注册时间 |
| Filed | Type | Null | Key | Default | Extra | Comment |
| ------------- | ----------- | ---- | --- | ----------------- | -------------- | -------- |
| id | int(11) | NO | PRI | (NULL) | auto_increment | 自增 ID |
| uid | int(11) | NO | UNI | (NULL) | | 用户 ID |
| nick_name | varchar(64) | YES | | (NULL) | | 昵称 |
| achievement | int(11) | YES | | 0 | | 成就值 |
| level | int(11) | YES | | (NULL) | | 用户等级 |
| job | varchar(32) | YES | | (NULL) | | 职业方向 |
| register_time | datetime | YES | | CURRENT_TIMESTAMP | | 注册时间 |
作为数据分析师,请**创建一张优质用户信息表 user_info_vip**,表结构和用户信息表一致。
你应该返回的输出如下表格所示,请写出建表语句将表格中所有限制和说明记录到表里。
| Filed | Type | Null | Key | Default | Extra | Comment |
| ------------- | ----------- | ---- | ---- | ----------------- | -------------- | -------- |
| id | int(11) | NO | PRI | (NULL) | auto_increment | 自增 ID |
| uid | int(11) | NO | UNI | (NULL) | | 用户 ID |
| nick_name | varchar(64) | YES | | (NULL) | | 昵称 |
| achievement | int(11) | YES | | 0 | | 成就值 |
| level | int(11) | YES | | (NULL) | | 用户等级 |
| job | varchar(32) | YES | | (NULL) | | 职业方向 |
| register_time | datetime | YES | | CURRENT_TIMESTAMP | | 注册时间 |
| Filed | Type | Null | Key | Default | Extra | Comment |
| ------------- | ----------- | ---- | --- | ----------------- | -------------- | -------- |
| id | int(11) | NO | PRI | (NULL) | auto_increment | 自增 ID |
| uid | int(11) | NO | UNI | (NULL) | | 用户 ID |
| nick_name | varchar(64) | YES | | (NULL) | | 昵称 |
| achievement | int(11) | YES | | 0 | | 成就值 |
| level | int(11) | YES | | (NULL) | | 用户等级 |
| job | varchar(32) | YES | | (NULL) | | 职业方向 |
| register_time | datetime | YES | | CURRENT_TIMESTAMP | | 注册时间 |
**思路**:如果这题给出了旧表的名称,可直接`create table 新表 as select * from 旧表;` 但是这题并没有给出旧表名称,所以需要自己创建,注意默认值和键的创建即可,比较简单。(注意:如果是在牛客网上面执行,请注意 comment 中要和题目中的 comment 保持一致,包括大小写,否则不通过,还有字符也要设置)
@ -323,15 +323,15 @@ CREATE TABLE IF NOT EXISTS user_info_vip(
**用户信息表 `user_info`**
| Filed | Type | Null | Key | Default | Extra | Comment |
| ------------- | ----------- | ---- | ---- | ----------------- | -------------- | -------- |
| id | int(11) | NO | PRI | (NULL) | auto_increment | 自增 ID |
| uid | int(11) | NO | UNI | (NULL) | | 用户 ID |
| nick_name | varchar(64) | YES | | (NULL) | | 昵称 |
| achievement | int(11) | YES | | 0 | | 成就值 |
| level | int(11) | YES | | (NULL) | | 用户等级 |
| job | varchar(32) | YES | | (NULL) | | 职业方向 |
| register_time | datetime | YES | | CURRENT_TIMESTAMP | | 注册时间 |
| Filed | Type | Null | Key | Default | Extra | Comment |
| ------------- | ----------- | ---- | --- | ----------------- | -------------- | -------- |
| id | int(11) | NO | PRI | (NULL) | auto_increment | 自增 ID |
| uid | int(11) | NO | UNI | (NULL) | | 用户 ID |
| nick_name | varchar(64) | YES | | (NULL) | | 昵称 |
| achievement | int(11) | YES | | 0 | | 成就值 |
| level | int(11) | YES | | (NULL) | | 用户等级 |
| job | varchar(32) | YES | | (NULL) | | 职业方向 |
| register_time | datetime | YES | | CURRENT_TIMESTAMP | | 注册时间 |
**要求:**请在用户信息表,字段 `level` 的后面增加一列最多可保存 15 个汉字的字段 `school`;并将表中 `job` 列名改为 `profession`,同时 `varchar` 字段长度变为 10`achievement` 的默认值设置为 0。
@ -382,11 +382,11 @@ DROP TABLE IF EXISTS exam_record_2014;
根据题意,将返回如下结果:
| examination_info | 0 | PRIMARY | 1 | id | A | 0 | | | | BTREE |
| ---------------- | ---- | ---------------- | ---- | -------- | ---- | ---- | ---- | ---- | ---- | -------- |
| examination_info | 0 | uniq_idx_exam_id | 1 | exam_id | A | 0 | | | YES | BTREE |
| examination_info | 1 | idx_duration | 1 | duration | A | 0 | | | | BTREE |
| examination_info | 1 | full_idx_tag | 1 | tag | | 0 | | | YES | FULLTEXT |
| examination_info | 0 | PRIMARY | 1 | id | A | 0 | | | | BTREE |
| ---------------- | --- | ---------------- | --- | -------- | --- | --- | --- | --- | --- | -------- |
| examination_info | 0 | uniq_idx_exam_id | 1 | exam_id | A | 0 | | | YES | BTREE |
| examination_info | 1 | idx_duration | 1 | duration | A | 0 | | | | BTREE |
| examination_info | 1 | full_idx_tag | 1 | tag | | 0 | | | YES | FULLTEXT |
备注:后台会通过 `SHOW INDEX FROM examination_info` 语句来对比输出结果

View File

@ -20,31 +20,31 @@ tag:
示例数据:`examination_info``exam_id` 试卷 ID, tag 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间)
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
示例数据:`exam_record`uid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分)
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | 2021-05-02 10:30:01 | 81 |
| 3 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:31:01 | 84 |
| 4 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 5 | 1001 | 9001 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 8 | 1002 | 9001 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 9 | 1003 | 9001 | 2021-09-07 12:01:01 | 2021-09-07 10:31:01 | 50 |
| 10 | 1004 | 9001 | 2021-09-06 10:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | 2021-05-02 10:30:01 | 81 |
| 3 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:31:01 | 84 |
| 4 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 5 | 1001 | 9001 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 8 | 1002 | 9001 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 9 | 1003 | 9001 | 2021-09-07 12:01:01 | 2021-09-07 10:31:01 | 50 |
| 10 | 1004 | 9001 | 2021-09-06 10:01:01 | (NULL) | (NULL) |
根据输入你的查询结果如下:
| tag | difficulty | clip_avg_score |
| ---- | ---------- | -------------- |
| SQL | hard | 81.7 |
| tag | difficulty | clip_avg_score |
| --- | ---------- | -------------- |
| SQL | hard | 81.7 |
`examination_info`表可知,试卷 9001 为高难度 SQL 试卷,该试卷被作答的得分有[80,81,84,90,50],去除最高分和最低分后为[80,81,84],平均分为 81.6666667,保留一位小数后为 81.7
@ -199,18 +199,18 @@ WHERE info.exam_id = record.exam_id
示例数据 `exam_record` 表(`uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | 2021-05-02 10:30:01 | 81 |
| 3 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:31:01 | 84 |
| 4 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 5 | 1001 | 9001 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 8 | 1002 | 9001 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 9 | 1003 | 9001 | 2021-09-07 12:01:01 | 2021-09-07 10:31:01 | 50 |
| 10 | 1004 | 9001 | 2021-09-06 10:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | 2021-05-02 10:30:01 | 81 |
| 3 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:31:01 | 84 |
| 4 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 5 | 1001 | 9001 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 8 | 1002 | 9001 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 9 | 1003 | 9001 | 2021-09-07 12:01:01 | 2021-09-07 10:31:01 | 50 |
| 10 | 1004 | 9001 | 2021-09-06 10:01:01 | (NULL) | (NULL) |
示例输出:
@ -220,7 +220,7 @@ WHERE info.exam_id = record.exam_id
解释:表示截止当前,有 11 次试卷作答记录,已完成的作答次数为 7 次(中途退出的为未完成状态,其交卷时间和份数为 NULL已完成的试卷有 9001 和 9002 两份。
**思路** 这题一看到统计次数,肯定第一时间就要想到用`COUNT`这个函数来解决,问题是要统计不同的记录,该怎么来写?使用子查询就能解决这个题目(这题用 case when 也能写出来,解法类似,逻辑不同而已);首先在做这个题之前,让我们先来了解一下`COUNT`的基本用法;
**思路** 这题一看到统计次数,肯定第一时间就要想到用`COUNT`这个函数来解决,问题是要统计不同的记录,该怎么来写?使用子查询就能解决这个题目(这题用 case when 也能写出来,解法类似,逻辑不同而已);首先在做这个题之前,让我们先来了解一下`COUNT`的基本用法;
`COUNT()` 函数的基本语法如下所示:
@ -287,25 +287,25 @@ FROM
示例数据 exam_record 表uid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 4 | 1002 | 9003 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1002 | 9001 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 6 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 7 | 1003 | 9002 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 9 | 1004 | 9003 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 4 | 1002 | 9003 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1002 | 9001 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 6 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 7 | 1003 | 9002 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 9 | 1004 | 9003 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
`examination_info` 表(`exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间)
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
示例输出数据:
@ -363,28 +363,28 @@ WHERE info.exam_id = record.exam_id
`exam_record` 表(`uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分)
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | 2021-07-02 09:21:01 | 80 |
| 2 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 4 | 1002 | 9003 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1002 | 9001 | 2021-07-02 19:01:01 | 2021-07-02 19:30:01 | 82 |
| 6 | 1002 | 9002 | 2021-07-05 18:01:01 | 2021-07-05 18:59:02 | 90 |
| 7 | 1003 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 9 | 1004 | 9003 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 10 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 11 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 12 | 1006 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| 13 | 1007 | 9002 | 2020-09-02 12:11:01 | 2020-09-02 12:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | 2021-07-02 09:21:01 | 80 |
| 2 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 4 | 1002 | 9003 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1002 | 9001 | 2021-07-02 19:01:01 | 2021-07-02 19:30:01 | 82 |
| 6 | 1002 | 9002 | 2021-07-05 18:01:01 | 2021-07-05 18:59:02 | 90 |
| 7 | 1003 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 9 | 1004 | 9003 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 10 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 11 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 12 | 1006 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| 13 | 1007 | 9002 | 2020-09-02 12:11:01 | 2020-09-02 12:31:01 | 89 |
请计算 2021 年每个月里试卷作答区用户平均月活跃天数 `avg_active_days` 和月度活跃人数 `mau`,上面数据的示例输出如下:
| month | avg_active_days | mau |
| ------ | --------------- | ---- |
| 202107 | 1.50 | 2 |
| 202109 | 1.25 | 4 |
| month | avg_active_days | mau |
| ------ | --------------- | --- |
| 202107 | 1.50 | 2 |
| 202109 | 1.25 | 4 |
**解释**2021 年 7 月有 2 人活跃,共活跃了 3 天1001 活跃 1 天1002 活跃 2 天),平均活跃天数 1.52021 年 9 月有 4 人活跃,共活跃了 5 天,平均活跃天数 1.25,结果保留 2 位小数。
@ -416,13 +416,13 @@ GROUP BY MONTH
**描述**:现有一张题目练习记录表 `practice_record`,示例内容如下:
| id | uid | question_id | submit_time | score |
| ---- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1003 | 8002 | 2021-08-01 19:38:01 | 80 |
| id | uid | question_id | submit_time | score |
| --- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1003 | 8002 | 2021-08-01 19:38:01 | 80 |
请从中统计出 2021 年每个月里用户的月总刷题数 `month_q_cnt` 和日均刷题数 `avg_day_q_cnt`(按月份升序排序)以及该年的总体情况,示例数据输出如下:
@ -495,34 +495,34 @@ ORDER BY submit_month
**描述**:现有试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分),示例数据如下:
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | 2021-07-02 09:21:01 | 80 |
| 2 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 4 | 1002 | 9003 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1002 | 9001 | 2021-07-02 19:01:01 | 2021-07-02 19:30:01 | 82 |
| 6 | 1002 | 9002 | 2021-07-05 18:01:01 | 2021-07-05 18:59:02 | 90 |
| 7 | 1003 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 9 | 1004 | 9003 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 10 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 11 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 12 | 1006 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| 13 | 1007 | 9002 | 2020-09-02 12:11:01 | 2020-09-02 12:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | 2021-07-02 09:21:01 | 80 |
| 2 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 4 | 1002 | 9003 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1002 | 9001 | 2021-07-02 19:01:01 | 2021-07-02 19:30:01 | 82 |
| 6 | 1002 | 9002 | 2021-07-05 18:01:01 | 2021-07-05 18:59:02 | 90 |
| 7 | 1003 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 9 | 1004 | 9003 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 10 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 11 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 12 | 1006 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| 13 | 1007 | 9002 | 2020-09-02 12:11:01 | 2020-09-02 12:31:01 | 89 |
还有一张试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间),示例数据如下:
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
请统计 2021 年每个未完成试卷作答数大于 1 的有效用户的数据(有效用户指完成试卷作答数至少为 1 且未完成数小于 5输出用户 ID、未完成试卷作答数、完成试卷作答数、作答过的试卷 tag 集合,按未完成试卷数量由多到少排序。示例数据的输出结果如下:
| uid | incomplete_cnt | complete_cnt | detail |
| ---- | -------------- | ------------ | ------------------------------------------------------------ |
| uid | incomplete_cnt | complete_cnt | detail |
| ---- | -------------- | ------------ | --------------------------------------------------------------------------- |
| 1002 | 2 | 4 | 2021-09-01:算法;2021-07-02:SQL;2021-09-02:SQL;2021-09-05:SQL;2021-07-05:SQL |
**解释**2021 年的作答记录中,除了 1004其他用户均满足有效用户定义但只有 1002 未完成试卷数大于 1因此只输出 1002detail 中是 1002 作答过的试卷{日期:tag}集合,日期和 tag 间用 **:** 连接,多元素间用 **;** 连接。
@ -591,29 +591,29 @@ ORDER BY incomplete_cnt DESC
**描述**:现有试卷作答记录表 `exam_record``uid`:用户 ID, `exam_id`:试卷 ID, `start_time`:开始作答时间, `submit_time`:交卷时间,没提交的话为 NULL, `score`:得分),示例数据如下:
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | (NULL) | (NULL) |
| 2 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:21:01 | 60 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | 2021-09-02 12:31:01 | 70 |
| 4 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81 |
| 5 | 1002 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 6 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 7 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 8 | 1003 | 9001 | 2021-09-08 13:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9002 | 2021-09-08 14:01:01 | (NULL) | (NULL) |
| 10 | 1003 | 9003 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| 11 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 12 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 13 | 1005 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | (NULL) | (NULL) |
| 2 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:21:01 | 60 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | 2021-09-02 12:31:01 | 70 |
| 4 | 1002 | 9001 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 81 |
| 5 | 1002 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 6 | 1003 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 7 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 8 | 1003 | 9001 | 2021-09-08 13:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9002 | 2021-09-08 14:01:01 | (NULL) | (NULL) |
| 10 | 1003 | 9003 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| 11 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 12 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 13 | 1005 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
试卷信息表 `examination_info``exam_id`:试卷 ID, `tag`:试卷类别, `difficulty`:试卷难度, `duration`:考试时长, `release_time`:发布时间),示例数据如下:
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
请从表中统计出 “当月均完成试卷数”不小于 3 的用户们爱作答的类别及作答次数,按次数降序输出,示例输出如下:
@ -658,51 +658,51 @@ ORDER BY tag_cnt DESC
**描述**:现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间),示例数据如下:
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2100 | 6 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 1500 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1100 | 4 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2100 | 6 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 1500 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1100 | 4 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
**释义**:用户 1001 昵称为牛客 1 号,成就值为 3100用户等级是 7 级,职业方向为算法,注册时间 2020-01-01 10:00:00
试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间) 示例数据如下:
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2020-02-01 10:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2020-08-02 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分) 示例数据如下:
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | 2021-09-01 09:41:01 | 70 |
| 2 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:21:01 | 60 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | 2021-09-02 12:31:01 | 70 |
| 4 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
| 5 | 1002 | 9003 | 2021-08-01 12:01:01 | 2021-08-01 12:21:01 | 60 |
| 6 | 1002 | 9002 | 2021-08-02 12:01:01 | 2021-08-02 12:31:01 | 70 |
| 7 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
| 8 | 1002 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9002 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 10 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 11 | 1003 | 9003 | 2021-09-01 13:01:01 | 2021-09-01 13:41:01 | 70 |
| 12 | 1003 | 9001 | 2021-09-08 14:01:01 | (NULL) | (NULL) |
| 13 | 1003 | 9002 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 90 |
| 15 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 16 | 1005 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-07-02 09:01:01 | 2021-09-01 09:41:01 | 70 |
| 2 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:21:01 | 60 |
| 3 | 1002 | 9002 | 2021-09-02 12:01:01 | 2021-09-02 12:31:01 | 70 |
| 4 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
| 5 | 1002 | 9003 | 2021-08-01 12:01:01 | 2021-08-01 12:21:01 | 60 |
| 6 | 1002 | 9002 | 2021-08-02 12:01:01 | 2021-08-02 12:31:01 | 70 |
| 7 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
| 8 | 1002 | 9002 | 2021-07-06 12:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9002 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 10 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 11 | 1003 | 9003 | 2021-09-01 13:01:01 | 2021-09-01 13:41:01 | 70 |
| 12 | 1003 | 9001 | 2021-09-08 14:01:01 | (NULL) | (NULL) |
| 13 | 1003 | 9002 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 90 |
| 15 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 16 | 1005 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
请计算每张 SQL 类别试卷发布后,当天 5 级以上的用户作答的人数 `uv` 和平均分 `avg_score`,按人数降序,相同人数的按平均分升序,示例数据结果输出如下:
| exam_id | uv | avg_score |
| ------- | ---- | --------- |
| 9001 | 3 | 81.3 |
| exam_id | uv | avg_score |
| ------- | --- | --------- |
| 9001 | 3 | 81.3 |
解释:只有一张 SQL 类别的试卷,试卷 ID 为 9001发布当天2021-09-01有 1001、1002、1003、1005 作答过,但是 1003 是 5 级用户,其他 3 位为 5 级以上,他们三的得分有[70,80,85,90],平均分为 81.3(保留 1 位小数)。
@ -752,43 +752,43 @@ ORDER BY uv DESC,
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2100 | 6 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 1500 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1100 | 4 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2100 | 6 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 1500 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1100 | 4 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
试卷作答信息表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:41:01 | 79 |
| 2 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:21:01 | 60 |
| 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 4 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
| 5 | 1002 | 9003 | 2021-08-01 12:01:01 | 2021-08-01 12:21:01 | 60 |
| 6 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 7 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
| 8 | 1002 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9002 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 10 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 11 | 1003 | 9003 | 2021-09-01 13:01:01 | 2021-09-01 13:41:01 | 81 |
| 12 | 1003 | 9001 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| 13 | 1003 | 9002 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 90 |
| 15 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 16 | 1005 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:41:01 | 79 |
| 2 | 1002 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:21:01 | 60 |
| 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 4 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
| 5 | 1002 | 9003 | 2021-08-01 12:01:01 | 2021-08-01 12:21:01 | 60 |
| 6 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 7 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
| 8 | 1002 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9002 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 86 |
| 10 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 11 | 1003 | 9003 | 2021-09-01 13:01:01 | 2021-09-01 13:41:01 | 81 |
| 12 | 1003 | 9001 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| 13 | 1003 | 9002 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 90 |
| 15 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 88 |
| 16 | 1005 | 9002 | 2021-09-02 12:11:01 | 2021-09-02 12:31:01 | 89 |
统计作答 SQL 类别的试卷得分大于过 80 的人的用户等级分布,按数量降序排序(保证数量都不同)。示例数据结果输出如下:
@ -826,35 +826,35 @@ ORDER BY level_cnt DESC
现有试卷作答记录表 exam_recorduid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:41:01 | 81 |
| 2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 3 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
| 4 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
| 6 | 1002 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:41:01 | 81 |
| 2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 3 | 1002 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 80 |
| 4 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 85 |
| 6 | 1002 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
题目练习表 practice_recorduid 用户 ID, question_id 题目 ID, submit_time 提交时间, score 得分):
| id | uid | question_id | submit_time | score |
| ---- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1003 | 8001 | 2021-08-02 19:38:01 | 70 |
| 6 | 1003 | 8001 | 2021-08-02 19:48:01 | 90 |
| 7 | 1003 | 8002 | 2021-08-01 19:38:01 | 80 |
| id | uid | question_id | submit_time | score |
| --- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1003 | 8001 | 2021-08-02 19:38:01 | 70 |
| 6 | 1003 | 8001 | 2021-08-02 19:48:01 | 90 |
| 7 | 1003 | 8002 | 2021-08-01 19:38:01 | 80 |
请统计每个题目和每份试卷被作答的人数和次数,分别按照"试卷"和"题目"的 uv & pv 降序显示,示例数据结果输出如下:
| tid | uv | pv |
| ---- | ---- | ---- |
| 9001 | 3 | 3 |
| 9002 | 1 | 3 |
| 8001 | 3 | 5 |
| 8002 | 2 | 2 |
| tid | uv | pv |
| ---- | --- | --- |
| 9001 | 3 | 3 |
| 9002 | 1 | 3 |
| 8001 | 3 | 5 |
| 8002 | 2 | 2 |
**解释**:“试卷”有 3 人共练习 3 次试卷 90011 人作答 3 次 9002“刷题”有 3 人刷 5 次 8001有 2 人刷 2 次 8002
@ -918,21 +918,21 @@ FROM
现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 3 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | **86** |
| 4 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 89 |
| 5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 70 |
| 3 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | **86** |
| 4 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 89 |
| 5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
示例数据输出结果:
@ -1011,52 +1011,52 @@ ORDER BY UID
现有用户信息表 user_infouid 用户 IDnick_name 昵称, achievement 成就值, level 等级, job 职业方向, register_time 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2300 | 7 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 2500 | 7 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 2000 | 6 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2300 | 7 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 2500 | 7 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 2000 | 6 | C++ | 2020-01-01 10:00:00 |
试卷信息表 examination_infoexam_id 试卷 ID, tag 试卷类别, difficulty 试卷难度, duration 考试时长, release_time 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | hard | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | hard | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
试卷作答记录表 exam_recorduid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 3 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 86 |
| 4 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
| 5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| 6 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
| 7 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
| 8 | 1006 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 80 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 2 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 3 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 86 |
| 4 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
| 5 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| 6 | 1005 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
| 7 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
| 8 | 1006 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 80 |
题目练习记录表 practice_recorduid 用户 ID, question_id 题目 ID, submit_time 提交时间, score 得分):
| id | uid | question_id | submit_time | score |
| ---- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1004 | 8001 | 2021-08-02 19:38:01 | 70 |
| 6 | 1004 | 8002 | 2021-08-02 19:48:01 | 90 |
| 7 | 1001 | 8002 | 2021-08-02 19:38:01 | 70 |
| 8 | 1004 | 8002 | 2021-08-02 19:48:01 | 90 |
| 9 | 1004 | 8002 | 2021-08-02 19:58:01 | 94 |
| 10 | 1004 | 8003 | 2021-08-02 19:38:01 | 70 |
| 11 | 1004 | 8003 | 2021-08-02 19:48:01 | 90 |
| 12 | 1004 | 8003 | 2021-08-01 19:38:01 | 80 |
| id | uid | question_id | submit_time | score |
| --- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1004 | 8001 | 2021-08-02 19:38:01 | 70 |
| 6 | 1004 | 8002 | 2021-08-02 19:48:01 | 90 |
| 7 | 1001 | 8002 | 2021-08-02 19:38:01 | 70 |
| 8 | 1004 | 8002 | 2021-08-02 19:48:01 | 90 |
| 9 | 1004 | 8002 | 2021-08-02 19:58:01 | 94 |
| 10 | 1004 | 8003 | 2021-08-02 19:38:01 | 70 |
| 11 | 1004 | 8003 | 2021-08-02 19:48:01 | 90 |
| 12 | 1004 | 8003 | 2021-08-01 19:38:01 | 80 |
请你找到高难度 SQL 试卷得分平均值大于 80 并且是 7 级的红名大佬,统计他们的 2021 年试卷总完成次数和题目总练习次数,只保留 2021 年有试卷完成记录的用户。结果按试卷完成数升序,按题目练习数降序。
@ -1126,22 +1126,22 @@ ORDER BY exam_cnt,
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2300 | 7 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 2500 | 7 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 2600 | 7 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3100 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2300 | 7 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 | 2500 | 7 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 1200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 1600 | 6 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 2600 | 7 | C++ | 2020-01-01 10:00:00 |
试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | easy | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):

View File

@ -73,26 +73,26 @@ FROM table;
现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, score 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 78 |
| 2 | 1002 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 4 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 86 |
| 5 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
| 6 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| 7 | 1005 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
| 8 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
| 9 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 10 | 1003 | 9002 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 78 |
| 2 | 1002 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 4 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 86 |
| 5 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
| 6 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| 7 | 1005 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
| 8 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
| 9 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 10 | 1003 | 9002 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
找到每类试卷得分的前 3 名,如果两人最大分数相同,选择最小分数大者,如果还相同,选择 uid 大者。由示例数据结果输出如下:
@ -134,28 +134,28 @@ WHERE ranking <= 3
现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | hard | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 |
| 2 | 9002 | C++ | hard | 60 | 2021-09-01 06:00:00 |
| 3 | 9003 | 算法 | medium | 80 | 2021-09-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:51:01 | 78 |
| 2 | 1001 | 9002 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 4 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:59:01 | 86 |
| 5 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
| 6 | 1004 | 9002 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| 7 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
| 8 | 1006 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
| 9 | 1003 | 9001 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 10 | 1003 | 9002 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| 11 | 1005 | 9001 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| 12 | 1003 | 9003 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:51:01 | 78 |
| 2 | 1001 | 9002 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 |
| 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 |
| 4 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:59:01 | 86 |
| 5 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 |
| 6 | 1004 | 9002 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 |
| 7 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 |
| 8 | 1006 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 |
| 9 | 1003 | 9001 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 |
| 10 | 1003 | 9002 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| 11 | 1005 | 9001 | 2021-09-01 14:01:01 | (NULL) | (NULL) |
| 12 | 1003 | 9003 | 2021-09-08 15:01:01 | (NULL) | (NULL) |
找到第二快和第二慢用时之差大于试卷时长的一半的试卷信息,按试卷 ID 降序排序。由示例数据结果输出如下:
@ -198,13 +198,13 @@ ORDER BY a.exam_id DESC
现有试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:02 | 84 |
| 2 | 1006 | 9001 | 2021-09-01 12:11:01 | 2021-09-01 12:31:01 | 89 |
| 3 | 1006 | 9002 | 2021-09-06 10:01:01 | 2021-09-06 10:21:01 | 81 |
| 4 | 1005 | 9002 | 2021-09-05 10:01:01 | 2021-09-05 10:21:01 | 81 |
| 5 | 1005 | 9001 | 2021-09-05 10:31:01 | 2021-09-05 10:51:01 | 81 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:02 | 84 |
| 2 | 1006 | 9001 | 2021-09-01 12:11:01 | 2021-09-01 12:31:01 | 89 |
| 3 | 1006 | 9002 | 2021-09-06 10:01:01 | 2021-09-06 10:21:01 | 81 |
| 4 | 1005 | 9002 | 2021-09-05 10:01:01 | 2021-09-05 10:21:01 | 81 |
| 5 | 1005 | 9001 | 2021-09-05 10:31:01 | 2021-09-05 10:51:01 | 81 |
请计算在 2021 年至少有两天作答过试卷的人中,计算该年连续两次作答试卷的最大时间窗 `days_window`,那么根据该年的历史规律他在 `days_window` 天里平均会做多少套试卷,按最大时间窗和平均做答试卷套数倒序排序。由示例数据结果输出如下:
@ -245,18 +245,18 @@ ORDER BY days_window DESC,
现有试卷作答记录表 `exam_record``uid`:用户 ID, `exam_id`:试卷 ID, `start_time`:开始作答时间, `submit_time`:交卷时间,为空的话则代表未完成, `score`:得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1006 | 9003 | 2021-09-06 10:01:01 | 2021-09-06 10:21:02 | 84 |
| 2 | 1006 | 9001 | 2021-08-02 12:11:01 | 2021-08-02 12:31:01 | 89 |
| 3 | 1006 | 9002 | 2021-06-06 10:01:01 | 2021-06-06 10:21:01 | 81 |
| 4 | 1006 | 9002 | 2021-05-06 10:01:01 | 2021-05-06 10:21:01 | 81 |
| 5 | 1006 | 9001 | 2021-05-01 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9001 | 2021-09-05 10:31:01 | 2021-09-05 10:51:01 | 81 |
| 7 | 1001 | 9003 | 2021-08-01 09:01:01 | 2021-08-01 09:51:11 | 78 |
| 8 | 1001 | 9002 | 2021-07-01 09:01:01 | 2021-07-01 09:31:00 | 81 |
| 9 | 1001 | 9002 | 2021-07-01 12:01:01 | 2021-07-01 12:31:01 | 81 |
| 10 | 1001 | 9002 | 2021-07-01 12:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1006 | 9003 | 2021-09-06 10:01:01 | 2021-09-06 10:21:02 | 84 |
| 2 | 1006 | 9001 | 2021-08-02 12:11:01 | 2021-08-02 12:31:01 | 89 |
| 3 | 1006 | 9002 | 2021-06-06 10:01:01 | 2021-06-06 10:21:01 | 81 |
| 4 | 1006 | 9002 | 2021-05-06 10:01:01 | 2021-05-06 10:21:01 | 81 |
| 5 | 1006 | 9001 | 2021-05-01 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9001 | 2021-09-05 10:31:01 | 2021-09-05 10:51:01 | 81 |
| 7 | 1001 | 9003 | 2021-08-01 09:01:01 | 2021-08-01 09:51:11 | 78 |
| 8 | 1001 | 9002 | 2021-07-01 09:01:01 | 2021-07-01 09:31:00 | 81 |
| 9 | 1001 | 9002 | 2021-07-01 12:01:01 | 2021-07-01 12:31:01 | 81 |
| 10 | 1001 | 9002 | 2021-07-01 12:01:01 | (NULL) | (NULL) |
找到每个人近三个有试卷作答记录的月份中没有试卷是未完成状态的用户的试卷作答完成数,按试卷完成数和用户 ID 降序排名。由示例数据结果输出如下:
@ -296,42 +296,42 @@ ORDER BY exam_complete_cnt DESC,
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3200 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2500 | 6 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 2200 | 5 | 算法 | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ------------ | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 3200 | 7 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2500 | 6 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 2200 | 5 | 算法 | 2020-01-01 10:00:00 |
试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ------ | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | 算法 | hard | 80 | 2020-01-01 10:00:00 |
| 4 | 9004 | PYTHON | medium | 70 | 2020-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ------ | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | 算法 | hard | 80 | 2020-01-01 10:00:00 |
| 4 | 9004 | PYTHON | medium | 70 | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 15 | 1002 | 9001 | 2020-01-01 18:01:01 | 2020-01-01 18:59:02 | 90 |
| 13 | 1001 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| 2 | 1002 | 9001 | 2020-01-20 10:01:01 | | |
| 3 | 1002 | 9001 | 2020-02-01 12:11:01 | | |
| 5 | 1001 | 9001 | 2020-03-01 12:01:01 | | |
| 6 | 1002 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 4 | 1003 | 9001 | 2020-03-01 19:01:01 | | |
| 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 |
| 14 | 1001 | 9002 | 2020-01-01 12:11:01 | | |
| 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 9 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1002 | 9002 | 2020-02-02 12:01:01 | | |
| 11 | 1002 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 |
| 12 | 1002 | 9002 | 2020-03-02 12:11:01 | | |
| 17 | 1001 | 9002 | 2020-05-05 18:01:01 | | |
| 16 | 1002 | 9003 | 2020-05-06 12:01:01 | | |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 15 | 1002 | 9001 | 2020-01-01 18:01:01 | 2020-01-01 18:59:02 | 90 |
| 13 | 1001 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| 2 | 1002 | 9001 | 2020-01-20 10:01:01 | | |
| 3 | 1002 | 9001 | 2020-02-01 12:11:01 | | |
| 5 | 1001 | 9001 | 2020-03-01 12:01:01 | | |
| 6 | 1002 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 4 | 1003 | 9001 | 2020-03-01 19:01:01 | | |
| 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 |
| 14 | 1001 | 9002 | 2020-01-01 12:11:01 | | |
| 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 9 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1002 | 9002 | 2020-02-02 12:01:01 | | |
| 11 | 1002 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 |
| 12 | 1002 | 9002 | 2020-03-02 12:11:01 | | |
| 17 | 1001 | 9002 | 2020-05-05 18:01:01 | | |
| 16 | 1002 | 9003 | 2020-05-06 12:01:01 | | |
请统计 SQL 试卷上未完成率较高的 50%用户中6 级和 7 级用户在有试卷作答记录的近三个月中,每个月的答卷数目和完成数目。按用户 ID、月份升序排序。
@ -434,43 +434,43 @@ ORDER BY t1.uid,
现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ------ | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-01-01 10:00:00 |
| 2 | 9002 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 3 | 9003 | 算法 | hard | 80 | 2021-01-01 10:00:00 |
| 4 | 9004 | PYTHON | medium | 70 | 2021-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ------ | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2021-01-01 10:00:00 |
| 2 | 9002 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 3 | 9003 | 算法 | hard | 80 | 2021-01-01 10:00:00 |
| 4 | 9004 | PYTHON | medium | 70 | 2021-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2020-08-02 10:01:01 | 2020-08-02 10:31:01 | 89 |
| 2 | 1002 | 9001 | 2020-04-01 18:01:01 | 2020-04-01 18:59:02 | 90 |
| 3 | 1001 | 9001 | 2020-04-01 09:01:01 | 2020-04-01 09:21:59 | 80 |
| 5 | 1002 | 9001 | 2021-03-02 19:01:01 | 2021-03-02 19:32:00 | 20 |
| 8 | 1003 | 9001 | 2021-05-02 12:01:01 | 2021-05-02 12:31:01 | 98 |
| 13 | 1003 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| 9 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1002 | 9002 | 2021-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 |
| 11 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 16 | 1002 | 9002 | 2020-02-02 12:01:01 | | |
| 17 | 1002 | 9002 | 2020-03-02 12:11:01 | | |
| 18 | 1001 | 9002 | 2021-05-05 18:01:01 | | |
| 4 | 1002 | 9003 | 2021-01-20 10:01:01 | 2021-01-20 10:10:01 | 81 |
| 6 | 1001 | 9003 | 2021-04-02 19:01:01 | 2021-04-02 19:40:01 | 89 |
| 15 | 1002 | 9003 | 2021-01-01 18:01:01 | 2021-01-01 18:59:02 | 90 |
| 7 | 1004 | 9004 | 2020-05-02 12:01:01 | 2020-05-02 12:20:01 | 99 |
| 12 | 1001 | 9004 | 2021-09-02 12:11:01 | | |
| 14 | 1002 | 9004 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2020-08-02 10:01:01 | 2020-08-02 10:31:01 | 89 |
| 2 | 1002 | 9001 | 2020-04-01 18:01:01 | 2020-04-01 18:59:02 | 90 |
| 3 | 1001 | 9001 | 2020-04-01 09:01:01 | 2020-04-01 09:21:59 | 80 |
| 5 | 1002 | 9001 | 2021-03-02 19:01:01 | 2021-03-02 19:32:00 | 20 |
| 8 | 1003 | 9001 | 2021-05-02 12:01:01 | 2021-05-02 12:31:01 | 98 |
| 13 | 1003 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| 9 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1002 | 9002 | 2021-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 |
| 11 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 16 | 1002 | 9002 | 2020-02-02 12:01:01 | | |
| 17 | 1002 | 9002 | 2020-03-02 12:11:01 | | |
| 18 | 1001 | 9002 | 2021-05-05 18:01:01 | | |
| 4 | 1002 | 9003 | 2021-01-20 10:01:01 | 2021-01-20 10:10:01 | 81 |
| 6 | 1001 | 9003 | 2021-04-02 19:01:01 | 2021-04-02 19:40:01 | 89 |
| 15 | 1002 | 9003 | 2021-01-01 18:01:01 | 2021-01-01 18:59:02 | 90 |
| 7 | 1004 | 9004 | 2020-05-02 12:01:01 | 2020-05-02 12:20:01 | 99 |
| 12 | 1001 | 9004 | 2021-09-02 12:11:01 | | |
| 14 | 1002 | 9004 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 |
请计算 2021 年上半年各类试卷的做完次数相比 2020 年上半年同期的增长率(百分比格式,保留 1 位小数),以及做完次数排名变化,按增长率和 21 年排名降序输出。
由示例数据结果输出如下:
| tag | exam_cnt_20 | exam_cnt_21 | growth_rate | exam_cnt_rank_20 | exam_cnt_rank_21 | rank_delta |
| ---- | ----------- | ----------- | ----------- | ---------------- | ---------------- | ---------- |
| SQL | 3 | 2 | -33.3% | 1 | 2 | 1 |
| tag | exam_cnt_20 | exam_cnt_21 | growth_rate | exam_cnt_rank_20 | exam_cnt_rank_21 | rank_delta |
| --- | ----------- | ----------- | ----------- | ---------------- | ---------------- | ---------- |
| SQL | 3 | 2 | -33.3% | 1 | 2 | 1 |
解释2020 年上半年有 3 个 tag 有作答完成的记录,分别是 C++、SQL、PYTHON它们被做完的次数分别是 3、3、2做完次数排名为 1、1并列、3
@ -590,29 +590,29 @@ ORDER BY
现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ------ | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | C++ | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | 算法 | hard | 80 | 2020-01-01 10:00:00 |
| 4 | 9004 | PYTHON | medium | 70 | 2020-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ------ | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | C++ | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | 算法 | hard | 80 | 2020-01-01 10:00:00 |
| 4 | 9004 | PYTHON | medium | 70 | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 6 | 1003 | 9001 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 68 |
| 9 | 1001 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 12 | 1002 | 9002 | 2021-05-05 18:01:01 | (NULL) | (NULL) |
| 3 | 1004 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:11:01 | 60 |
| 2 | 1003 | 9002 | 2020-01-01 19:01:01 | 2020-01-01 19:30:01 | 75 |
| 7 | 1001 | 9002 | 2020-01-02 12:01:01 | 2020-01-02 12:43:01 | 81 |
| 10 | 1002 | 9002 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 |
| 4 | 1003 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:41:01 | 90 |
| 5 | 1002 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:32:00 | 90 |
| 11 | 1002 | 9004 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1001 | 9005 | 2020-01-02 12:11:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 6 | 1003 | 9001 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 68 |
| 9 | 1001 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 12 | 1002 | 9002 | 2021-05-05 18:01:01 | (NULL) | (NULL) |
| 3 | 1004 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:11:01 | 60 |
| 2 | 1003 | 9002 | 2020-01-01 19:01:01 | 2020-01-01 19:30:01 | 75 |
| 7 | 1001 | 9002 | 2020-01-02 12:01:01 | 2020-01-02 12:43:01 | 81 |
| 10 | 1002 | 9002 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 |
| 4 | 1003 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:41:01 | 90 |
| 5 | 1002 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:32:00 | 90 |
| 11 | 1002 | 9004 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 8 | 1001 | 9005 | 2020-01-02 12:11:01 | (NULL) | (NULL) |
在物理学及统计学数据计算时,有个概念叫 min-max 标准化,也被称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 - 1]之间。
@ -694,20 +694,20 @@ ORDER BY
现有试卷作答记录表 exam_recorduid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 2 | 1002 | 9001 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 89 |
| 3 | 1002 | 9001 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 |
| 4 | 1003 | 9001 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 |
| 5 | 1004 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 |
| 6 | 1003 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 |
| 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 9 | 1004 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1003 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 68 |
| 11 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 |
| 12 | 1001 | 9002 | 2020-03-02 12:11:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 2 | 1002 | 9001 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 89 |
| 3 | 1002 | 9001 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 |
| 4 | 1003 | 9001 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 |
| 5 | 1004 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 |
| 6 | 1003 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 |
| 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 9 | 1004 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1003 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 68 |
| 11 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 |
| 12 | 1001 | 9002 | 2020-03-02 12:11:01 | (NULL) | (NULL) |
请输出每份试卷每月作答数和截止当月的作答总数。
由示例数据结果输出如下:
@ -747,31 +747,31 @@ GROUP BY exam_id,
**描述**:现有试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 2 | 1002 | 9001 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 89 |
| 3 | 1002 | 9001 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 |
| 4 | 1003 | 9001 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 |
| 5 | 1004 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 |
| 6 | 1003 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 |
| 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 9 | 1004 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1003 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 68 |
| 11 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-02-02 12:43:01 | 81 |
| 12 | 1001 | 9002 | 2020-03-02 12:11:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 |
| 2 | 1002 | 9001 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 89 |
| 3 | 1002 | 9001 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 |
| 4 | 1003 | 9001 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 |
| 5 | 1004 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 |
| 6 | 1003 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 |
| 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 |
| 9 | 1004 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1003 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 68 |
| 11 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-02-02 12:43:01 | 81 |
| 12 | 1001 | 9002 | 2020-03-02 12:11:01 | (NULL) | (NULL) |
请输出自从有用户作答记录以来,每月的试卷作答记录中月活用户数、新增用户数、截止当月的单月最大新增用户数、截止当月的累积用户数。结果按月份升序输出。
由示例数据结果输出如下:
| start_month | mau | month_add_uv | max_month_add_uv | cum_sum_uv |
| ----------- | ---- | ------------ | ---------------- | ---------- |
| 202001 | 2 | 2 | 2 | 2 |
| 202002 | 4 | 2 | 2 | 4 |
| 202003 | 3 | 0 | 2 | 4 |
| 202005 | 1 | 0 | 2 | 4 |
| start_month | mau | month_add_uv | max_month_add_uv | cum_sum_uv |
| ----------- | --- | ------------ | ---------------- | ---------- |
| 202001 | 2 | 2 | 2 | 2 |
| 202002 | 4 | 2 | 2 | 4 |
| 202003 | 3 | 0 | 2 | 4 |
| 202005 | 1 | 0 | 2 | 4 |
| month | 1001 | 1002 | 1003 | 1004 |
| ------ | ---- | ---- | ---- | ---- |
@ -829,5 +829,4 @@ ORDER BY
start_month
```
<!-- @include: @article-footer.snippet.md -->

View File

@ -18,11 +18,11 @@ tag:
现有试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分),数据如下:
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | 2021-05-02 10:30:01 | 81 |
| 3 | 1001 | 9001 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:01 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | 2021-05-02 10:30:01 | 81 |
| 3 | 1001 | 9001 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
请统计有未完成状态的试卷的未完成数 incomplete_cnt 和未完成率 incomplete_rate。由示例数据结果输出如下
@ -68,30 +68,30 @@ HAVING incomplete_cnt <> 0
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间),数据如下:
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 10 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2100 | 6 | 算法 | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | --------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 10 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 2100 | 6 | 算法 | 2020-01-01 10:00:00 |
试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间),数据如下:
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | easy | 60 | 2020-01-01 10:00:00 |
| 3 | 9004 | 算法 | medium | 80 | 2020-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | SQL | easy | 60 | 2020-01-01 10:00:00 |
| 3 | 9004 | 算法 | medium | 80 | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分),数据如下:
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 4 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 5 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 4 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 5 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
请输出每个 0 级用户所有的高难度试卷考试平均用时和平均得分,未完成的默认试卷最大考试时长和 0 分处理。由示例数据结果输出如下:
@ -129,46 +129,46 @@ ORDER BY UID
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 1000 | 2 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 进击的 3 号 | 2200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 2500 | 6 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 3000 | 7 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 1000 | 2 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 进击的 3 号 | 2200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 2500 | 6 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 5 号 | 3000 | 7 | C++ | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 4 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 11 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 81 |
| 12 | 1002 | 9002 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 13 | 1002 | 9002 | 2020-02-02 12:11:01 | 2020-02-02 12:31:01 | 83 |
| 7 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 16 | 1002 | 9001 | 2021-09-06 12:01:01 | 2021-09-06 12:21:01 | 80 |
| 17 | 1002 | 9001 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 18 | 1002 | 9001 | 2021-09-07 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 89 |
| 10 | 1004 | 9002 | 2021-08-06 12:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-02-01 11:01:01 | 2021-02-01 11:31:01 | 84 |
| 15 | 1006 | 9001 | 2021-02-01 11:01:01 | 2021-02-01 11:31:01 | 84 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 4 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 11 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 81 |
| 12 | 1002 | 9002 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 13 | 1002 | 9002 | 2020-02-02 12:11:01 | 2020-02-02 12:31:01 | 83 |
| 7 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 16 | 1002 | 9001 | 2021-09-06 12:01:01 | 2021-09-06 12:21:01 | 80 |
| 17 | 1002 | 9001 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 18 | 1002 | 9001 | 2021-09-07 12:01:01 | (NULL) | (NULL) |
| 8 | 1003 | 9003 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 9 | 1003 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 89 |
| 10 | 1004 | 9002 | 2021-08-06 12:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-02-01 11:01:01 | 2021-02-01 11:31:01 | 84 |
| 15 | 1006 | 9001 | 2021-02-01 11:01:01 | 2021-02-01 11:31:01 | 84 |
题目练习记录表 `practice_record``uid` 用户 ID, `question_id` 题目 ID, `submit_time` 提交时间, `score` 得分):
| id | uid | question_id | submit_time | score |
| ---- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1003 | 8002 | 2021-09-01 19:38:01 | 80 |
| id | uid | question_id | submit_time | score |
| --- | ---- | ----------- | ------------------- | ----- |
| 1 | 1001 | 8001 | 2021-08-02 11:41:01 | 60 |
| 2 | 1002 | 8001 | 2021-09-02 19:30:01 | 50 |
| 3 | 1002 | 8001 | 2021-09-02 19:20:01 | 70 |
| 4 | 1002 | 8002 | 2021-09-02 19:38:01 | 70 |
| 5 | 1003 | 8002 | 2021-09-01 19:38:01 | 80 |
请找到昵称以『牛客』开头『号』结尾、成就值在 1200~2500 之间,且最近一次活跃(答题或作答试卷)在 2021 年 9 月的用户信息。
@ -217,45 +217,45 @@ GROUP BY u_info.uid
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 1900 | 2 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 2200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 2500 | 6 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 2000 | 7 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ------------ | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 1900 | 2 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 2200 | 5 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 2500 | 6 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 2000 | 7 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | C++ | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | c# | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | SQL | medium | 70 | 2020-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | --- | ---------- | -------- | ------------------- |
| 1 | 9001 | C++ | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | c# | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | SQL | medium | 70 | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 4 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 5 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 11 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 81 |
| 16 | 1002 | 9001 | 2021-09-06 12:01:01 | 2021-09-06 12:21:01 | 80 |
| 17 | 1002 | 9001 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 18 | 1002 | 9001 | 2021-09-07 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 12 | 1002 | 9002 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 13 | 1002 | 9002 | 2020-02-02 12:11:01 | 2020-02-02 12:31:01 | 83 |
| 9 | 1003 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 89 |
| 8 | 1003 | 9003 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 10 | 1004 | 9002 | 2021-08-06 12:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-02-01 11:01:01 | 2021-02-01 11:31:01 | 84 |
| 15 | 1006 | 9001 | 2021-02-01 11:01:01 | 2021-09-01 11:31:01 | 84 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 4 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 5 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 6 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 11 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 81 |
| 16 | 1002 | 9001 | 2021-09-06 12:01:01 | 2021-09-06 12:21:01 | 80 |
| 17 | 1002 | 9001 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 18 | 1002 | 9001 | 2021-09-07 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9002 | 2021-05-05 18:01:01 | 2021-05-05 18:59:02 | 90 |
| 12 | 1002 | 9002 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 13 | 1002 | 9002 | 2020-02-02 12:11:01 | 2020-02-02 12:31:01 | 83 |
| 9 | 1003 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 89 |
| 8 | 1003 | 9003 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 10 | 1004 | 9002 | 2021-08-06 12:01:01 | (NULL) | (NULL) |
| 14 | 1005 | 9001 | 2021-02-01 11:01:01 | 2021-02-01 11:31:01 | 84 |
| 15 | 1006 | 9001 | 2021-02-01 11:01:01 | 2021-09-01 11:31:01 | 84 |
找到昵称以"牛客"+纯数字+"号"或者纯数字组成的用户对于字母 c 开头的试卷类别(如 C,C++,c#等)的已完成的试卷 ID 和平均得分,按用户 ID、平均分升序排序。由示例数据结果输出如下
@ -311,32 +311,32 @@ ORDER BY UID,avg_score;
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 进击的 3 号 | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 2000 | 7 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 进击的 3 号 | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 2000 | 7 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 4 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1001 | 9003 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9004 | 2021-09-03 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 99 |
| 8 | 1002 | 9003 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 9 | 1002 | 9003 | 2020-02-02 12:11:01 | (NULL) | (NULL) |
| 10 | 1002 | 9002 | 2021-05-05 18:01:01 | (NULL) | (NULL) |
| 11 | 1002 | 9001 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 12 | 1003 | 9003 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 13 | 1003 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 87 |
| 4 | 1001 | 9002 | 2021-09-01 12:01:01 | (NULL) | (NULL) |
| 5 | 1001 | 9003 | 2021-09-02 12:01:01 | (NULL) | (NULL) |
| 6 | 1001 | 9004 | 2021-09-03 12:01:01 | (NULL) | (NULL) |
| 7 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 99 |
| 8 | 1002 | 9003 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 9 | 1002 | 9003 | 2020-02-02 12:11:01 | (NULL) | (NULL) |
| 10 | 1002 | 9002 | 2021-05-05 18:01:01 | (NULL) | (NULL) |
| 11 | 1002 | 9001 | 2021-09-06 12:01:01 | (NULL) | (NULL) |
| 12 | 1003 | 9003 | 2021-02-06 12:01:01 | (NULL) | (NULL) |
| 13 | 1003 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:31:01 | 89 |
请你筛选表中的数据,当有任意一个 0 级用户未完成试卷数大于 2 时,输出每个 0 级用户的试卷未完成数和未完成率(保留 3 位小数);若不存在这样的用户,则输出所有有作答记录的用户的这两个指标。结果按未完成率升序排序。
@ -537,30 +537,30 @@ CASE
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 2000 | 7 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ------------ | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 2000 | 7 | C++ | 2020-01-01 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-01-01 10:00:00 |
试卷作答记录表 exam_recorduid 用户 ID, exam_id 试卷 ID, start_time 开始作答时间, submit_time 交卷时间, score 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 75 |
| 4 | 1001 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:11:01 | 60 |
| 5 | 1001 | 9003 | 2021-09-02 12:01:01 | 2021-09-02 12:41:01 | 90 |
| 6 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 7 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 8 | 1001 | 9004 | 2021-09-03 12:01:01 | (NULL) | (NULL) |
| 9 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 99 |
| 10 | 1002 | 9003 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 11 | 1002 | 9003 | 2020-02-02 12:11:01 | 2020-02-02 12:41:01 | 76 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1001 | 9001 | 2021-05-02 10:01:01 | (NULL) | (NULL) |
| 3 | 1001 | 9002 | 2021-02-02 19:01:01 | 2021-02-02 19:30:01 | 75 |
| 4 | 1001 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:11:01 | 60 |
| 5 | 1001 | 9003 | 2021-09-02 12:01:01 | 2021-09-02 12:41:01 | 90 |
| 6 | 1001 | 9001 | 2021-06-02 19:01:01 | 2021-06-02 19:32:00 | 20 |
| 7 | 1001 | 9002 | 2021-09-05 19:01:01 | 2021-09-05 19:40:01 | 89 |
| 8 | 1001 | 9004 | 2021-09-03 12:01:01 | (NULL) | (NULL) |
| 9 | 1002 | 9001 | 2020-01-01 12:01:01 | 2020-01-01 12:31:01 | 99 |
| 10 | 1002 | 9003 | 2020-02-01 12:01:01 | 2020-02-01 12:31:01 | 82 |
| 11 | 1002 | 9003 | 2020-02-02 12:11:01 | 2020-02-02 12:41:01 | 76 |
为了得到用户试卷作答的定性表现,我们将试卷得分按分界点[90,75,60]分为优良中差四个得分等级(分界点划分到左区间),请统计不同用户等级的人在完成过的试卷中各得分等级占比(结果保留 3 位小数),未完成过试卷的用户无需输出,结果按用户等级降序、占比降序排序。
@ -649,22 +649,22 @@ ORDER BY a.LEVEL DESC,
现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-02-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-02 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 5 | 1005 | 牛客 555 号 | 4000 | 7 | C++ | 2020-01-11 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-11-01 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ------------ | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 号 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-02-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-02 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 5 | 1005 | 牛客 555 号 | 4000 | 7 | C++ | 2020-01-11 10:00:00 |
| 6 | 1006 | 666666 | 3000 | 6 | C++ | 2020-11-01 10:00:00 |
请从中找到注册时间最早的 3 个人。由示例数据结果输出如下:
| uid | nick_name | register_time |
| ---- | ----------- | ------------------- |
| 1001 | 牛客 1 | 2020-01-01 10:00:00 |
| uid | nick_name | register_time |
| ---- | ------------ | ------------------- |
| 1001 | 牛客 1 | 2020-01-01 10:00:00 |
| 1003 | 牛客 3 号 ♂ | 2020-01-02 10:00:00 |
| 1004 | 牛客 4 号 | 2020-01-02 11:00:00 |
| 1004 | 牛客 4 号 | 2020-01-02 11:00:00 |
解释:按注册时间排序后选取前三名,输出其用户 ID、昵称、注册时间。
@ -681,45 +681,45 @@ SELECT uid, nick_name, register_time
**描述**:现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 4000 | 7 | 算法 | 2020-01-11 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 7 | 1007 | 牛客 7 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 8 | 1008 | 牛客 8 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 9 | 1009 | 牛客 9 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 10 | 1010 | 牛客 10 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 11 | 1011 | 666666 | 3000 | 6 | C++ | 2020-01-02 10:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ------------ | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 10:00:00 |
| 5 | 1005 | 牛客 555 号 | 4000 | 7 | 算法 | 2020-01-11 10:00:00 |
| 6 | 1006 | 牛客 6 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 7 | 1007 | 牛客 7 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 8 | 1008 | 牛客 8 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 9 | 1009 | 牛客 9 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 10 | 1010 | 牛客 10 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| 11 | 1011 | 666666 | 3000 | 6 | C++ | 2020-01-02 10:00:00 |
试卷信息表 examination_infoexam_id 试卷 ID, tag 试卷类别, difficulty 试卷难度, duration 考试时长, release_time 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | 算法 | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | 算法 | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | SQL | medium | 70 | 2020-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | 算法 | hard | 60 | 2020-01-01 10:00:00 |
| 2 | 9002 | 算法 | hard | 80 | 2020-01-01 10:00:00 |
| 3 | 9003 | SQL | medium | 70 | 2020-01-01 10:00:00 |
试卷作答记录表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1002 | 9003 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 81 |
| 3 | 1002 | 9002 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 |
| 4 | 1003 | 9002 | 2020-01-01 19:01:01 | 2020-01-01 19:30:01 | 75 |
| 5 | 1004 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:11:01 | 60 |
| 6 | 1005 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:41:01 | 90 |
| 7 | 1006 | 9001 | 2020-01-02 19:01:01 | 2020-01-02 19:32:00 | 20 |
| 8 | 1007 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:40:01 | 89 |
| 9 | 1008 | 9003 | 2020-01-02 12:01:01 | 2020-01-02 12:20:01 | 99 |
| 10 | 1008 | 9001 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 98 |
| 11 | 1009 | 9002 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 82 |
| 12 | 1010 | 9002 | 2020-01-02 12:11:01 | 2020-01-02 12:41:01 | 76 |
| 13 | 1011 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ----- |
| 1 | 1001 | 9001 | 2020-01-02 09:01:01 | 2020-01-02 09:21:59 | 80 |
| 2 | 1002 | 9003 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 81 |
| 3 | 1002 | 9002 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 |
| 4 | 1003 | 9002 | 2020-01-01 19:01:01 | 2020-01-01 19:30:01 | 75 |
| 5 | 1004 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:11:01 | 60 |
| 6 | 1005 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:41:01 | 90 |
| 7 | 1006 | 9001 | 2020-01-02 19:01:01 | 2020-01-02 19:32:00 | 20 |
| 8 | 1007 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:40:01 | 89 |
| 9 | 1008 | 9003 | 2020-01-02 12:01:01 | 2020-01-02 12:20:01 | 99 |
| 10 | 1008 | 9001 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 98 |
| 11 | 1009 | 9002 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 82 |
| 12 | 1010 | 9002 | 2020-01-02 12:11:01 | 2020-01-02 12:41:01 | 76 |
| 13 | 1011 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 |
![](https://oss.javaguide.cn/github/javaguide/database/sql/D2B491866B85826119EE3474F10D3636.png)
@ -784,12 +784,12 @@ LIMIT 6,3
**描述**:现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | -------------- | ---------- | -------- | ------------------- |
| 1 | 9001 | 算法 | hard | 60 | 2021-01-01 10:00:00 |
| 2 | 9002 | 算法 | hard | 80 | 2021-01-01 10:00:00 |
| 3 | 9003 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| 4 | 9004 | 算法,medium,80 | | 0 | 2021-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | -------------- | ---------- | -------- | ------------------- |
| 1 | 9001 | 算法 | hard | 60 | 2021-01-01 10:00:00 |
| 2 | 9002 | 算法 | hard | 80 | 2021-01-01 10:00:00 |
| 3 | 9003 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| 4 | 9004 | 算法,medium,80 | | 0 | 2021-01-01 10:00:00 |
录题同学有一次手误将部分记录的试题类别 tag、难度、时长同时录入到了 tag 字段,请帮忙找出这些录错了的记录,并拆分后按正确的列类型输出。
@ -865,14 +865,14 @@ WHERE
**描述**:现有用户信息表 `user_info``uid` 用户 ID`nick_name` 昵称, `achievement` 成就值, `level` 等级, `job` 职业方向, `register_time` 注册时间):
| id | uid | nick_name | achievement | level | job | register_time |
| ---- | ---- | ---------------------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 11:00:00 |
| 5 | 1005 | 牛客 5678901234 号 | 4000 | 7 | 算法 | 2020-01-11 10:00:00 |
| 6 | 1006 | 牛客 67890123456789 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
| id | uid | nick_name | achievement | level | job | register_time |
| --- | ---- | ---------------------- | ----------- | ----- | ---- | ------------------- |
| 1 | 1001 | 牛客 1 | 19 | 0 | 算法 | 2020-01-01 10:00:00 |
| 2 | 1002 | 牛客 2 号 | 1200 | 3 | 算法 | 2020-01-01 10:00:00 |
| 3 | 1003 | 牛客 3 号 ♂ | 22 | 0 | 算法 | 2020-01-01 10:00:00 |
| 4 | 1004 | 牛客 4 号 | 25 | 0 | 算法 | 2020-01-01 11:00:00 |
| 5 | 1005 | 牛客 5678901234 号 | 4000 | 7 | 算法 | 2020-01-11 10:00:00 |
| 6 | 1006 | 牛客 67890123456789 号 | 25 | 0 | 算法 | 2020-01-02 11:00:00 |
有的用户的昵称特别长,在一些展示场景会导致样式混乱,因此需要将特别长的昵称转换一下再输出,请输出字符数大于 10 的用户信息,对于字符数大于 13 的用户输出前 10 个字符然后加上三个点号:『...』。
@ -929,36 +929,36 @@ GROUP BY
现有试卷信息表 `examination_info``exam_id` 试卷 ID, `tag` 试卷类别, `difficulty` 试卷难度, `duration` 考试时长, `release_time` 发布时间):
| id | exam_id | tag | difficulty | duration | release_time |
| ---- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | 算法 | hard | 60 | 2021-01-01 10:00:00 |
| 2 | 9002 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 3 | 9003 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 4 | 9004 | sql | medium | 70 | 2021-01-01 10:00:00 |
| 5 | 9005 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 6 | 9006 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 7 | 9007 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 8 | 9008 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| 9 | 9009 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| 10 | 9010 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| id | exam_id | tag | difficulty | duration | release_time |
| --- | ------- | ---- | ---------- | -------- | ------------------- |
| 1 | 9001 | 算法 | hard | 60 | 2021-01-01 10:00:00 |
| 2 | 9002 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 3 | 9003 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 4 | 9004 | sql | medium | 70 | 2021-01-01 10:00:00 |
| 5 | 9005 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 6 | 9006 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 7 | 9007 | C++ | hard | 80 | 2021-01-01 10:00:00 |
| 8 | 9008 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| 9 | 9009 | SQL | medium | 70 | 2021-01-01 10:00:00 |
| 10 | 9010 | SQL | medium | 70 | 2021-01-01 10:00:00 |
试卷作答信息表 `exam_record``uid` 用户 ID, `exam_id` 试卷 ID, `start_time` 开始作答时间, `submit_time` 交卷时间, `score` 得分):
| id | uid | exam_id | start_time | submit_time | score |
| ---- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 80 |
| 2 | 1002 | 9003 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 81 |
| 3 | 1002 | 9002 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 |
| 4 | 1003 | 9002 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 |
| 5 | 1004 | 9002 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 |
| 6 | 1005 | 9002 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 7 | 1006 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 20 |
| 8 | 1007 | 9003 | 2020-01-02 19:01:01 | 2020-01-02 19:40:01 | 89 |
| 9 | 1008 | 9004 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1008 | 9001 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 98 |
| 11 | 1009 | 9002 | 2020-02-02 12:01:01 | 2020-01-02 12:43:01 | 81 |
| 12 | 1010 | 9001 | 2020-01-02 12:11:01 | (NULL) | (NULL) |
| 13 | 1010 | 9001 | 2020-02-02 12:01:01 | 2020-01-02 10:31:01 | 89 |
| id | uid | exam_id | start_time | submit_time | score |
| --- | ---- | ------- | ------------------- | ------------------- | ------ |
| 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 80 |
| 2 | 1002 | 9003 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 81 |
| 3 | 1002 | 9002 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 |
| 4 | 1003 | 9002 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 |
| 5 | 1004 | 9002 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 |
| 6 | 1005 | 9002 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 |
| 7 | 1006 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 20 |
| 8 | 1007 | 9003 | 2020-01-02 19:01:01 | 2020-01-02 19:40:01 | 89 |
| 9 | 1008 | 9004 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 |
| 10 | 1008 | 9001 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 98 |
| 11 | 1009 | 9002 | 2020-02-02 12:01:01 | 2020-01-02 12:43:01 | 81 |
| 12 | 1010 | 9001 | 2020-01-02 12:11:01 | (NULL) | (NULL) |
| 13 | 1010 | 9001 | 2020-02-02 12:01:01 | 2020-01-02 10:31:01 | 89 |
试卷的类别 tag 可能出现大小写混乱的情况,请先筛选出试卷作答数小于 3 的类别 tag统计将其转换为大写后对应的原本试卷作答数。
@ -966,9 +966,9 @@ GROUP BY
由示例数据结果输出如下:
| tag | answer_cnt |
| ---- | ---------- |
| C++ | 6 |
| tag | answer_cnt |
| --- | ---------- |
| C++ | 6 |
解释:被作答过的试卷有 9001、9002、9003、9004他们的 tag 和被作答次数如下:

View File

@ -556,7 +556,7 @@ SELECT column_name(s) FROM table2;
| `LEFT()``RIGHT()` | 左边或者右边的字符 |
| `LOWER()``UPPER()` | 转换为小写或者大写 |
| `LTRIM()``RTRIM()` | 去除左边或者右边的空格 |
| `LENGTH()` | 长度,以字节为单位 |
| `LENGTH()` | 长度,以字节为单位 |
| `SOUNDEX()` | 转换为语音值 |
其中, **`SOUNDEX()`** 可以将一个字符串转换为描述其语音表示的字母数字模式。

View File

@ -141,9 +141,7 @@ CAP 理论这节我们也说过了:
> 分布式一致性的 3 种级别:
>
> 1. **强一致性**:系统写入了什么,读出来的就是什么。
>
> 2. **弱一致性**:不一定可以读取到最新写入的值,也不保证多少时间之后读取到的数据是最新的,只是会尽量保证某个时刻达到数据一致的状态。
>
> 3. **最终一致性**:弱一致性的升级版,系统会保证在一定时间内达到数据一致的状态。
>
> **业界比较推崇是最终一致性级别,但是某些对数据一致要求十分严格的场景比如银行转账还是要保证强一致性。**

View File

@ -197,8 +197,6 @@ tag:
你可以看到图中生产者组中的生产者会向主题发送消息,而 **主题中存在多个队列**,生产者每次生产消息之后是指定主题中的某个队列发送消息的。
每个主题中都有多个队列(分布在不同的 `Broker`中,如果是集群的话,`Broker`又分布在不同的服务器中),集群消费模式下,一个消费者集群多台机器共同消费一个 `topic` 的多个队列,**一个队列只会被一个消费者消费**。如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费。就像上图中 `Consumer1``Consumer2` 分别对应着两个队列,而 `Consumer3` 是没有队列对应的,所以一般来讲要控制 **消费者组中的消费者个数和主题中队列个数相同**
当然也可以消费者个数小于队列个数,只不过不太建议。如下图。
@ -608,8 +606,6 @@ sendfile()跟 mmap()一样,也会减少一次 CPU 拷贝,但是它同时也
![5](https://img1.imgtp.com/2023/08/15/jqLgCEBY.png)
如图,用户在发起 sendfile()调用时会发生切换 1之后数据通过 DMA 拷贝到内核缓冲区,之后再将内核缓冲区的数据 CPU 拷贝到 Socket 缓冲区最后拷贝到网卡sendfile()返回,发生切换 2。发生了 3 次拷贝和两次切换。Java 也提供了相应 api
```java

View File

@ -107,4 +107,5 @@ tag:
人的精力是有限的,而且面对三十这个天花板,各种事件也会接连而至,在职场中学会合理安排时间并不断提升核心能力,这样才能保证自己的竞争力。
职场就像苦海无边,回首望去可能也没有岸边停泊,但是要具有换船的能力或者有个小木筏也就大差不差了。
<!-- @include: @article-footer.snippet.md -->

View File

@ -207,4 +207,3 @@ Java 后端面试复习的重点请看这篇文章:[Java 面试重点总结(
6. 岗位匹配度很重要。校招通常会对你的项目经历的研究方向比较宽容,即使你的项目经历和对应公司的具体业务没有关系,影响其实也并不大。社招的话就不一样了,毕竟公司是要招聘可以直接来干活的人,你有相关的经验,公司会比较省事。
7. 面试之后及时复盘。面试就像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

View File

@ -351,7 +351,7 @@ public class BigDecimalUtil {
}
```
相关 issue[建议对保留规则设置为 RoundingMode.HALF_EVEN,即四舍六入五成双]([#2129](https://github.com/Snailclimb/JavaGuide/issues/2129)) 。
相关 issue[建议对保留规则设置为 RoundingMode.HALF_EVEN,即四舍六入五成双](<[#2129](https://github.com/Snailclimb/JavaGuide/issues/2129)>) 。
![RoundingMode.HALF_EVEN](https://oss.javaguide.cn/github/javaguide/java/basis/RoundingMode.HALF_EVEN.png)

View File

@ -157,9 +157,7 @@ JDK 9 引入了一种新的编译模式 **AOT(Ahead of Time Compilation)** 。
> 答:
>
> 1. OpenJDK 是开源的,开源意味着你可以对它根据你自己的需要进行修改、优化,比如 Alibaba 基于 OpenJDK 开发了 Dragonwell8[https://github.com/alibaba/dragonwell8](https://github.com/alibaba/dragonwell8)
>
> 2. OpenJDK 是商业免费的(这也是为什么通过 yum 包管理器上默认安装的 JDK 是 OpenJDK 而不是 Oracle JDK。虽然 Oracle JDK 也是商业免费(比如 JDK 8但并不是所有版本都是免费的。
>
> 3. OpenJDK 更新频率更快。Oracle JDK 一般是每 6 个月发布一个新版本,而 OpenJDK 一般是每 3 个月发布一个新版本。(现在你知道为啥 Oracle JDK 更稳定了吧,先在 OpenJDK 试试水,把大部分问题都解决掉了才在 Oracle JDK 上发布)
>
> 基于以上这些原因OpenJDK 还是有存在的必要的!
@ -408,16 +406,16 @@ Java 中有 8 种基本数据类型,分别为:
这 8 种基本数据类型的默认值以及所占空间的大小如下:
| 基本类型 | 位数 | 字节 | 默认值 | 取值范围 |
| :-------- | :--- | :--- | :------ | ------------------------------------------------------------ |
| `byte` | 8 | 1 | 0 | -128 ~ 127 |
| `short` | 16 | 2 | 0 | -32768-2^15 ~ 327672^15 - 1 |
| `int` | 32 | 4 | 0 | -2147483648 ~ 2147483647 |
| 基本类型 | 位数 | 字节 | 默认值 | 取值范围 |
| :-------- | :--- | :--- | :------ | -------------------------------------------------------------- |
| `byte` | 8 | 1 | 0 | -128 ~ 127 |
| `short` | 16 | 2 | 0 | -32768-2^15 ~ 327672^15 - 1 |
| `int` | 32 | 4 | 0 | -2147483648 ~ 2147483647 |
| `long` | 64 | 8 | 0L | -9223372036854775808-2^63 ~ 92233720368547758072^63 -1 |
| `char` | 16 | 2 | 'u0000' | 0 ~ 655352^16 - 1 |
| `float` | 32 | 4 | 0f | 1.4E-45 ~ 3.4028235E38 |
| `double` | 64 | 8 | 0d | 4.9E-324 ~ 1.7976931348623157E308 |
| `boolean` | 1 | | false | true、false |
| `char` | 16 | 2 | 'u0000' | 0 ~ 655352^16 - 1 |
| `float` | 32 | 4 | 0f | 1.4E-45 ~ 3.4028235E38 |
| `double` | 64 | 8 | 0d | 4.9E-324 ~ 1.7976931348623157E308 |
| `boolean` | 1 | | false | true、false |
可以看到,像 `byte``short``int``long`能表示的最大正数都减 1 了。这是为什么呢这是因为在二进制补码表示法中最高位是用来表示符号的0 表示正数1 表示负数),其余位表示数值部分。所以,如果我们要表示最大的正数,我们需要把除了最高位之外的所有位都设为 1。如果我们再加 1就会导致溢出变成一个负数。

View File

@ -314,5 +314,4 @@ System.out.println("列表清空后为:" + list);
列表清空后为:[]
```
<!-- @include: @article-footer.snippet.md -->

View File

@ -266,7 +266,6 @@ HashMap 只提供了 put 用于添加元素putVal 方法只是给 put 方法
![ ](https://oss.javaguide.cn/github/javaguide/database/sql/put.png)
```java
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
@ -499,7 +498,6 @@ final Node<K,V>[] resize() {
}
```
## HashMap 常用方法测试
```java

View File

@ -65,11 +65,11 @@ head:
如果你看过 `HashSet` 源码的话就应该知道:`HashSet` 底层就是基于 `HashMap` 实现的。(`HashSet` 的源码非常非常少,因为除了 `clone()``writeObject()``readObject()``HashSet` 自己不得不实现之外,其他方法都是直接调用 `HashMap` 中的方法。
| `HashMap` | `HashSet` |
| :------------------------------------: | :----------------------------------------------------------: |
| 实现了 `Map` 接口 | 实现 `Set` 接口 |
| 存储键值对 | 仅存储对象 |
| 调用 `put()`向 map 中添加元素 | 调用 `add()`方法向 `Set` 中添加元素 |
| `HashMap` | `HashSet` |
| :------------------------------------: | :----------------------------------------------------------------------------------------------------------------------: |
| 实现了 `Map` 接口 | 实现 `Set` 接口 |
| 存储键值对 | 仅存储对象 |
| 调用 `put()`向 map 中添加元素 | 调用 `add()`方法向 `Set` 中添加元素 |
| `HashMap` 使用键Key计算 `hashcode` | `HashSet` 使用成员对象来计算 `hashcode` 值,对于两个对象来说 `hashcode` 可能相同,所以`equals()`方法用来判断对象的相等性 |
### HashMap 和 TreeMap 区别

View File

@ -513,4 +513,5 @@ System.out.println("清空后的链表:" + list);
链表长度2
清空后的链表:[]
```
<!-- @include: @article-footer.snippet.md -->

View File

@ -11,5 +11,4 @@ tag:
<!-- @include: @yuanma.snippet.md -->
<!-- @include: @article-footer.snippet.md -->

View File

@ -715,6 +715,4 @@ CompletableFuture.runAsync(() -> {
另外,建议 G 友们可以看看京东的 [asyncTool](https://gitee.com/jd-platform-opensource/asyncTool) 这个并发框架,里面大量使用到了 `CompletableFuture`
<!-- @include: @article-footer.snippet.md -->

View File

@ -5,7 +5,7 @@ tag:
- Java并发
---
> 本文部分内容来自 [Lorin](https://github.com/Lorin-github) 的[PR](https://github.com/Snailclimb/JavaGuide/pull/2190)。
> 本文部分内容来自 [Lorin](https://github.com/Lorin-github) 的[PR](https://github.com/Snailclimb/JavaGuide/pull/2190)。
虚拟线程在 Java 21 正式发布,这是一项重量级的更新。
@ -26,11 +26,13 @@ tag:
## 虚拟线程有什么优点和缺点?
### 优点
- 非常轻量级:可以在单个线程中创建成百上千个虚拟线程而不会导致过多的线程创建和上下文切换。
- 简化异步编程: 虚拟线程可以简化异步编程使代码更易于理解和维护。它可以将异步代码编写得更像同步代码避免了回调地狱Callback Hell
- 减少资源开销: 相比于操作系统线程,虚拟线程的资源开销更小。本质上是提高了线程的执行效率,从而减少线程资源的创建和上下文切换。
### 缺点
- 不适用于计算密集型任务: 虚拟线程适用于 I/O 密集型任务,但不适用于计算密集型任务,因为密集型计算始终需要 CPU 资源作为支持。
- 依赖于语言或库的支持: 协程需要编程语言或库提供支持。不是所有编程语言都原生支持协程。比如 Java 实现的虚拟线程。
@ -44,7 +46,6 @@ Java 21 已经正式支持虚拟线程,大家可以在官网下载使用,在
2. 使用 `Thread.ofVirtual()` 创建
3. 使用 `ThreadFactory` 创建
#### 使用 Thread.startVirtualThread()创建
```java
@ -123,6 +124,7 @@ static class CustomThread implements Runnable {
```
## 虚拟线程和平台线程性能对比
通过多线程和虚拟线程的方式处理相同的任务,对比创建的系统线程数和处理耗时。
**说明**:统计创建的系统线程中部分为后台线程(比如 GC 线程),两种场景下都一样,所以并不影响对比。

View File

@ -6,7 +6,7 @@ tag:
- Java基础
---
在学习 NIO 之前,需要先了解一下计算机 I/O 模型的基础理论知识。还不了解的话,可以参考我写的这篇文章:[Java IO 模型详解](https://javaguide.cn/java/io/io-model.html)。
在学习 NIO 之前,需要先了解一下计算机 I/O 模型的基础理论知识。还不了解的话,可以参考我写的这篇文章:[Java IO 模型详解](https://javaguide.cn/java/io/io-model.html)。
## NIO 简介
@ -48,7 +48,7 @@ NIO 主要包括以下三个核心组件:
为了更清晰地认识缓冲区,我们来简单看看`Buffer` 类中定义的四个成员变量:
~~~java
```java
public abstract class Buffer {
// Invariants: mark <= position <= limit <= capacity
private int mark = -1;
@ -56,7 +56,7 @@ public abstract class Buffer {
private int limit;
private int capacity;
}
~~~
```
这四个成员变量的具体含义如下:
@ -73,18 +73,18 @@ public abstract class Buffer {
![position 、limit 和 capacity 之前的关系](https://oss.javaguide.cn/github/javaguide/java/nio/NIOBufferClassAttributes.png)
`Buffer` 对象不能通过 `new` 调用构造方法创建对象 ,只能通过静态方法实例化 `Buffer`
`Buffer` 对象不能通过 `new` 调用构造方法创建对象 ,只能通过静态方法实例化 `Buffer`
这里以 `ByteBuffer`为例进行介绍:
~~~java
```java
// 分配堆内存
public static ByteBuffer allocate(int capacity);
// 分配直接内存
public static ByteBuffer allocateDirect(int capacity);
~~~
```
Buffer 最核心的两个方法:
Buffer 最核心的两个方法:
1. `get` : 读取缓冲区的数据
2. `put` :向缓冲区写入数据
@ -92,12 +92,12 @@ public static ByteBuffer allocateDirect(int capacity);
除上述两个方法之外,其他的重要方法:
- `flip` :将缓冲区从写模式切换到读模式,它会将 `limit` 的值设置为当前 `position` 的值,将 `position` 的值设置为 0。
- `clear`: 清空缓冲区,将缓冲区从读模式切换到写模式,并将 `position` 的值设置为 0`limit` 的值设置为 `capacity` 的值。
- `clear`: 清空缓冲区,将缓冲区从读模式切换到写模式,并将 `position` 的值设置为 0`limit` 的值设置为 `capacity` 的值。
- ……
Buffer 中数据变化的过程:
~~~java
```java
import java.nio.*;
public class CharBufferDemo {
@ -138,11 +138,11 @@ public class CharBufferDemo {
System.out.println("\n");
}
}
~~~
```
输出:
~~~bash
```bash
初始状态:
capacity: 8, limit: 8, position: 0
@ -158,7 +158,7 @@ capacity: 8, limit: 3, position: 0
调用clear()方法后的状态:
capacity: 8, limit: 8, position: 0
~~~
```
为了帮助理解,我绘制了一张图片展示 `capacity``limit``position`每一阶段的变化。
@ -188,20 +188,19 @@ Channel 与前面介绍的 Buffer 打交道,读操作的时候将 Channel 中
![Channel继承关系图](https://oss.javaguide.cn/github/javaguide/java/nio/channel-inheritance-relationship.png)
Channel 最核心的两个方法:
Channel 最核心的两个方法:
1. `read` :读取数据并写入到 Buffer 中。
2. `write` :将 Buffer 中的数据写入到 Channel 中。
这里我们以 `FileChannel` 为例演示一下是读取文件数据的。
~~~java
```java
RandomAccessFile reader = new RandomAccessFile("/Users/guide/Documents/test_read.in", "r"))
FileChannel channel = reader.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
~~~
```
### Selector选择器
@ -252,13 +251,13 @@ Selector 还提供了一系列和 `select()` 相关的方法:
- `int select()`:监控所有注册的 `Channel`,当它们中间有需要处理的 `IO` 操作时,该方法返回,并将对应的 `SelectionKey` 加入被选择的 `SelectionKey` 集合中,该方法返回这些 `Channel` 的数量。
- `int select(long timeout)`:可以设置超时时长的 `select()` 操作。
- `int selectNow()`:执行一个立即返回的 `select()` 操作,相对于无参数的 `select()` 方法而言,该方法不会阻塞线程。
- `int selectNow()`:执行一个立即返回的 `select()` 操作,相对于无参数的 `select()` 方法而言,该方法不会阻塞线程。
- `Selector wakeup()`:使一个还未返回的 `select()` 方法立刻返回。
- ……
使用 Selector 实现网络读写的简单示例:
~~~java
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
@ -335,7 +334,7 @@ public class NioSelectorExample {
}
}
}
~~~
```
在示例中,我们创建了一个简单的服务器,监听 8080 端口,使用 Selector 处理连接、读取和写入事件。当接收到客户端的数据时,服务器将读取数据并将其打印到控制台,然后向客户端回复 "Hello, Client!"。
@ -390,5 +389,4 @@ private void loadFileIntoMemory(File xmlFile) throws IOException {
- Java NIOBuffer、Channel 和 Selectorhttps://www.javadoop.com/post/java-nio
<!-- @include: @article-footer.snippet.md -->

View File

@ -97,11 +97,11 @@ ClassFile {
| CONSTANT_utf8_info | 1 | UTF-8 编码的字符串 |
| CONSTANT_Integer_info | 3 | 整形字面量 |
| CONSTANT_Float_info | 4 | 浮点型字面量 |
| CONSTANT_Long_info | 5 | 长整型字面量 |
| CONSTANT_Double_info | 6 | 双精度浮点型字面量 |
| CONSTANT_Class_info | 7 | 类或接口的符号引用 |
| CONSTANT_String_info | 8 | 字符串类型字面量 |
| CONSTANT_FieldRef_info | 9 | 字段的符号引用 |
| CONSTANT_Long_info | 5 | 长整型字面量 |
| CONSTANT_Double_info | 6 | 双精度浮点型字面量 |
| CONSTANT_Class_info | 7 | 类或接口的符号引用 |
| CONSTANT_String_info | 8 | 字符串类型字面量 |
| CONSTANT_FieldRef_info | 9 | 字段的符号引用 |
| CONSTANT_MethodRef_info | 10 | 类中方法的符号引用 |
| CONSTANT_InterfaceMethodRef_info | 11 | 接口中方法的符号引用 |
| CONSTANT_NameAndType_info | 12 | 字段或方法的符号引用 |

View File

@ -86,9 +86,9 @@ public abstract class ClassLoader {
JVM 中内置了三个重要的 `ClassLoader`
1. **`BootstrapClassLoader`(启动类加载器)**:最顶层的加载类,由 C++实现,通常表示为 null并且没有父级主要用来加载 JDK 内部的核心类库( `%JAVA_HOME%/lib`目录下的 `rt.jar``resources.jar``charsets.jar`等 jar 包和类)以及被 `-Xbootclasspath`参数指定的路径下的所有类。
2. **`ExtensionClassLoader`(扩展类加载器)**:主要负责加载 `%JRE_HOME%/lib/ext` 目录下的 jar 包和类以及被 `java.ext.dirs` 系统变量所指定的路径下的所有类。
3. **`AppClassLoader`(应用程序类加载器)**:面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
1. **`BootstrapClassLoader`(启动类加载器)**:最顶层的加载类,由 C++实现,通常表示为 null并且没有父级主要用来加载 JDK 内部的核心类库( `%JAVA_HOME%/lib`目录下的 `rt.jar``resources.jar``charsets.jar`等 jar 包和类)以及被 `-Xbootclasspath`参数指定的路径下的所有类。
2. **`ExtensionClassLoader`(扩展类加载器)**:主要负责加载 `%JRE_HOME%/lib/ext` 目录下的 jar 包和类以及被 `java.ext.dirs` 系统变量所指定的路径下的所有类。
3. **`AppClassLoader`(应用程序类加载器)**:面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
> 🌈 拓展一下:
>
@ -341,10 +341,10 @@ cl = Thread.currentThread().getContextClassLoader();
## 推荐阅读
- 《深入拆解 Java 虚拟机》
- 深入分析 Java ClassLoader 原理https://blog.csdn.net/xyang81/article/details/7292380
- Java 类加载器(ClassLoader)http://gityuan.com/2016/01/24/java-classloader/
- Class Loaders in Javahttps://www.baeldung.com/java-classloaders
- Class ClassLoader - Oracle 官方文档https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html
- 老大难的 Java ClassLoader 再不理解就老了https://zhuanlan.zhihu.com/p/51374915
- 深入分析 Java ClassLoader 原理:<https://blog.csdn.net/xyang81/article/details/7292380>
- Java 类加载器(ClassLoader)<http://gityuan.com/2016/01/24/java-classloader/>
- Class Loaders in Java<https://www.baeldung.com/java-classloaders>
- Class ClassLoader - Oracle 官方文档:<https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html>
- 老大难的 Java ClassLoader 再不理解就老了:<https://zhuanlan.zhihu.com/p/51374915>
<!-- @include: @article-footer.snippet.md -->

View File

@ -57,10 +57,10 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作 **GC 堆(
```java
public class GCTest {
public static void main(String[] args) {
byte[] allocation1, allocation2;
allocation1 = new byte[30900*1024];
}
public static void main(String[] args) {
byte[] allocation1, allocation2;
allocation1 = new byte[30900*1024];
}
}
```
@ -91,14 +91,14 @@ allocation2 = new byte[900*1024];
```java
public class GCTest {
public static void main(String[] args) {
byte[] allocation1, allocation2,allocation3,allocation4,allocation5;
allocation1 = new byte[32000*1024];
allocation2 = new byte[1000*1024];
allocation3 = new byte[1000*1024];
allocation4 = new byte[1000*1024];
allocation5 = new byte[1000*1024];
}
public static void main(String[] args) {
byte[] allocation1, allocation2,allocation3,allocation4,allocation5;
allocation1 = new byte[32000*1024];
allocation2 = new byte[1000*1024];
allocation3 = new byte[1000*1024];
allocation4 = new byte[1000*1024];
allocation5 = new byte[1000*1024];
}
}
```
@ -109,8 +109,8 @@ public class GCTest {
大对象直接进入老年代的行为是由虚拟机动态决定的,它与具体使用的垃圾回收器和相关参数有关。大对象直接进入老年代是一种优化策略,旨在避免将大对象放入新生代,从而减少新生代的垃圾回收频率和成本。
* G1 垃圾回收器会根据-XX:G1HeapRegionSize参数设置的堆区域大小和-XX:G1MixedGCLiveThresholdPercent参数设置的阈值,来决定哪些对象会直接进入老年代。
* Parallel Scavenge 垃圾回收器中,默认情况下,并没有一个固定的阈值(XX:ThresholdTolerance是动态调整的)来决定何时直接在老年代分配大对象。而是由虚拟机根据当前的堆内存情况和历史数据动态决定。
- G1 垃圾回收器会根据 `-XX:G1HeapRegionSize` 参数设置的堆区域大小和 `-XX:G1MixedGCLiveThresholdPercent` 参数设置的阈值,来决定哪些对象会直接进入老年代。
- Parallel Scavenge 垃圾回收器中,默认情况下,并没有一个固定的阈值(`XX:ThresholdTolerance`是动态调整的)来决定何时直接在老年代分配大对象。而是由虚拟机根据当前的堆内存情况和历史数据动态决定。
### 长期存活的对象将进入老年代
@ -122,7 +122,7 @@ public class GCTest {
> 修正([issue552](https://github.com/Snailclimb/JavaGuide/issues/552)“Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的 50% 时(默认值是 50%,可以通过 `-XX:TargetSurvivorRatio=percent` 来设置,参见 [issue1199](https://github.com/Snailclimb/JavaGuide/issues/1199) ),取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。
>
> jdk8 官方文档引用:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
> jdk8 官方文档引用:<https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html>
>
> ![](https://oss.javaguide.cn/java-guide-blog/image-20210523201742303.png)
>
@ -234,7 +234,6 @@ public class ReferenceCountingGc {
- 所有被同步锁持有的对象
- JNIJava Native Interface引用的对象
**对象可以被回收,就代表一定会被回收吗?**
即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 `finalize` 方法。当对象没有覆盖 `finalize` 方法,或 `finalize` 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。
@ -508,7 +507,7 @@ $ java -XX:+UseZGC className
## 参考
- 《深入理解 Java 虚拟机JVM 高级特性与最佳实践(第二版》
- https://my.oschina.net/hosee/blog/644618
- <https://my.oschina.net/hosee/blog/644618>
- <https://docs.oracle.com/javase/specs/jvms/se8/html/index.html>
<!-- @include: @article-footer.snippet.md -->

View File

@ -5,7 +5,7 @@ tag:
- JVM
---
> 来自[说出你的愿望吧丷](https://juejin.im/user/5c2400afe51d45451758aa96)投稿,原文地址:https://juejin.im/post/5e1505d0f265da5d5d744050
> 来自[说出你的愿望吧丷](https://juejin.im/user/5c2400afe51d45451758aa96)投稿,原文地址:<https://juejin.im/post/5e1505d0f265da5d5d744050>
## 前言
@ -71,12 +71,12 @@ JVM 是 Java Virtual Machine 的缩写,它是一个虚构出来的计算机,
执行 main 方法的步骤如下:
1. 编译好 App.java 后得到 App.class 后,执行 App.class系统会启动一个 JVM 进程,从 classpath 路径中找到一个名为 App.class 的二进制文件,将 App 的类信息加载到运行时数据区的方法区内,这个过程叫做 App 类的加载
2. JVM 找到 App 的主程序入口,执行 main 方法
3. 这个 main 中的第一条语句为 Student student = new Student("tellUrDream") ,就是让 JVM 创建一个 Student 对象,但是这个时候方法区中是没有 Student 类的信息的,所以 JVM 马上加载 Student 类,把 Student 类的信息放到方法区中
4. 加载完 Student 类后JVM 在堆中为一个新的 Student 实例分配内存,然后调用构造函数初始化 Student 实例,这个 Student 实例持有 **指向方法区中的 Student 类的类型信息** 的引用
5. 执行 student.sayName();时JVM 根据 student 的引用找到 student 对象,然后根据 student 对象持有的引用定位到方法区中 student 类的类型信息的方法表,获得 sayName() 的字节码地址。
6. 执行 sayName()
1. 编译好 App.java 后得到 App.class 后,执行 App.class系统会启动一个 JVM 进程,从 classpath 路径中找到一个名为 App.class 的二进制文件,将 App 的类信息加载到运行时数据区的方法区内,这个过程叫做 App 类的加载
2. JVM 找到 App 的主程序入口,执行 main 方法
3. 这个 main 中的第一条语句为 Student student = new Student("tellUrDream") ,就是让 JVM 创建一个 Student 对象,但是这个时候方法区中是没有 Student 类的信息的,所以 JVM 马上加载 Student 类,把 Student 类的信息放到方法区中
4. 加载完 Student 类后JVM 在堆中为一个新的 Student 实例分配内存,然后调用构造函数初始化 Student 实例,这个 Student 实例持有 **指向方法区中的 Student 类的类型信息** 的引用
5. 执行 student.sayName();时JVM 根据 student 的引用找到 student 对象,然后根据 student 对象持有的引用定位到方法区中 student 类的类型信息的方法表,获得 sayName() 的字节码地址。
6. 执行 sayName()
其实也不用管太多,只需要知道对象实例初始化时会去方法区中找类信息,完成后再到栈那里去运行方法。找方法就在方法表中找。
@ -90,15 +90,15 @@ JVM 是 Java Virtual Machine 的缩写,它是一个虚构出来的计算机,
#### 2.1.1 加载
1. 将 class 文件加载到内存
2. 将静态数据结构转化成方法区中运行时的数据结构
3. 在堆中生成一个代表这个类的 java.lang.Class 对象作为数据访问的入口
1. 将 class 文件加载到内存
2. 将静态数据结构转化成方法区中运行时的数据结构
3. 在堆中生成一个代表这个类的 java.lang.Class 对象作为数据访问的入口
#### 2.1.2 链接
1. 验证:确保加载的类符合 JVM 规范和安全,保证被校验类的方法在运行时不会做出危害虚拟机的事件,其实就是一个安全检查
2. 准备:为 static 变量在方法区中分配内存空间,设置变量的初始值,例如 static int a = 3 (注意:准备阶段只设置类中的静态变量(方法区中),不包括实例变量(堆内存中),实例变量是对象初始化时赋值的)
3. 解析:虚拟机将常量池内的符号引用替换为直接引用的过程(符号引用比如我现在 import java.util.ArrayList 这就算符号引用,直接引用就是指针或者对象地址,注意引用对象一定是在内存进行)
1. 验证:确保加载的类符合 JVM 规范和安全,保证被校验类的方法在运行时不会做出危害虚拟机的事件,其实就是一个安全检查
2. 准备:为 static 变量在方法区中分配内存空间,设置变量的初始值,例如 static int a = 3 (注意:准备阶段只设置类中的静态变量(方法区中),不包括实例变量(堆内存中),实例变量是对象初始化时赋值的)
3. 解析:虚拟机将常量池内的符号引用替换为直接引用的过程(符号引用比如我现在 import java.util.ArrayList 这就算符号引用,直接引用就是指针或者对象地址,注意引用对象一定是在内存进行)
#### 2.1.3 初始化
@ -114,10 +114,10 @@ GC 将无用对象从内存中卸载
加载一个 Class 类的顺序也是有优先级的,类加载器从最底层开始往上的顺序是这样的
1. BootStrap ClassLoaderrt.jar
2. Extension ClassLoader: 加载扩展的 jar 包
3. App ClassLoader指定的 classpath 下面的 jar 包
4. Custom ClassLoader自定义的类加载器
1. BootStrap ClassLoaderrt.jar
2. Extension ClassLoader: 加载扩展的 jar 包
3. App ClassLoader指定的 classpath 下面的 jar 包
4. Custom ClassLoader自定义的类加载器
### 2.3 双亲委派机制
@ -190,7 +190,7 @@ public class Person{
局部变量表用于存放方法参数和方法内部所定义的局部变量。它的容量是以 Slot 为最小单位,一个 slot 可以存放 32 位以内的数据类型。
虚拟机通过索引定位的方式使用局部变量表,范围为[0,局部变量表的 slot 的数量]。方法中的参数就会按一定顺序排列在这个局部变量表中,至于怎么排的我们可以先不关心。而为了节省栈帧空间,这些 slot 是可以复用的,当方法执行位置超过了某个变量,那么这个变量的 slot 可以被其它变量复用。当然如果需要复用,那我们的垃圾回收自然就不会去动这些内存。
虚拟机通过索引定位的方式使用局部变量表,范围为 `[0,局部变量表的 slot 的数量]`。方法中的参数就会按一定顺序排列在这个局部变量表中,至于怎么排的我们可以先不关心。而为了节省栈帧空间,这些 slot 是可以复用的,当方法执行位置超过了某个变量,那么这个变量的 slot 可以被其它变量复用。当然如果需要复用,那我们的垃圾回收自然就不会去动这些内存。
#### 3.3.6 虚拟机堆的概念
@ -239,11 +239,11 @@ MaxMetaspaceSize限制元空间大小上限防止占用过多物理内存
(了解一下即可)在 Java 语言汇总能作为 GC Roots 的对象分为以下几种:
1. 虚拟机栈(栈帧中的本地方法表)中引用的对象(局部变量)
2. 方法区中静态变量所引用的对象(静态变量)
3. 方法区中常量引用的对象
4. 本地方法栈(即 native 修饰的方法)中 JNI 引用的对象JNI 是 Java 虚拟机调用对应的 C 函数的方式,通过 JNI 函数也可以创建新的 Java 对象。且 JNI 对于对象的局部引用或者全局引用都会把它们指向的对象都标记为不可回收)
5. 已启动的且未终止的 Java 线程
1. 虚拟机栈(栈帧中的本地方法表)中引用的对象(局部变量)
2. 方法区中静态变量所引用的对象(静态变量)
3. 方法区中常量引用的对象
4. 本地方法栈(即 native 修饰的方法)中 JNI 引用的对象JNI 是 Java 虚拟机调用对应的 C 函数的方式,通过 JNI 函数也可以创建新的 Java 对象。且 JNI 对于对象的局部引用或者全局引用都会把它们指向的对象都标记为不可回收)
5. 已启动的且未终止的 Java 线程
这种方法的优点是能够解决循环引用的问题,可它的实现需要耗费大量资源和时间,也需要 GC它的分析过程引用关系不能发生变化所以需要停止所有进程
@ -259,8 +259,8 @@ finalize()是 Object 类的一个方法、一个对象的 finalize()方法只会
判断一个对象的死亡至少需要两次标记
1. 如果对象进行可达性分析之后没发现与 GC Roots 相连的引用链,那它将会第一次标记并且进行一次筛选。判断的条件是决定这个对象是否有必要执行 finalize()方法。如果对象有必要执行 finalize()方法,则被放入 F-Queue 队列中。
2. GC 对 F-Queue 队列中的对象进行二次标记。如果对象在 finalize()方法中重新与引用链上的任何一个对象建立了关联,那么二次标记时则会将它移出“即将回收”集合。如果此时对象还没成功逃脱,那么只能被回收了。
1. 如果对象进行可达性分析之后没发现与 GC Roots 相连的引用链,那它将会第一次标记并且进行一次筛选。判断的条件是决定这个对象是否有必要执行 finalize()方法。如果对象有必要执行 finalize()方法,则被放入 F-Queue 队列中。
2. GC 对 F-Queue 队列中的对象进行二次标记。如果对象在 finalize()方法中重新与引用链上的任何一个对象建立了关联,那么二次标记时则会将它移出“即将回收”集合。如果此时对象还没成功逃脱,那么只能被回收了。
如果确定对象已经死亡,我们又该如何回收这些垃圾呢

View File

@ -133,7 +133,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作 **GC 堆(
>
> ```c++
> uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
> //survivor_capacity是survivor空间的大小
> //survivor_capacity是survivor空间的大小
> size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
> size_t total = 0;
> uint age = 1;
@ -143,7 +143,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作 **GC 堆(
> age++;
> }
> uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
> ...
> ...
> }
> ```
@ -344,10 +344,10 @@ HotSpot 虚拟机主要使用的就是这种方式来进行对象访问。
- 《深入理解 Java 虚拟机JVM 高级特性与最佳实践(第二版》
- 《自己动手写 Java 虚拟机》
- Chapter 2. The Structure of the Java Virtual Machinehttps://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html
- JVM 栈帧内部结构-动态链接https://chenxitag.com/archives/368
- Java 中 new String("字面量") 中 "字面量" 是何时进入字符串常量池的? - 木女孩的回答 - 知乎https://www.zhihu.com/question/55994121/answer/147296098
- JVM 常量池中存储的是对象还是引用呢? - RednaxelaFX 的回答 - 知乎https://www.zhihu.com/question/57109429/answer/151717241
- Chapter 2. The Structure of the Java Virtual Machine<https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html>
- JVM 栈帧内部结构-动态链接:<https://chenxitag.com/archives/368>
- Java 中 new String("字面量") 中 "字面量" 是何时进入字符串常量池的? - 木女孩的回答 - 知乎:<https://www.zhihu.com/question/55994121/answer/147296098>
- JVM 常量池中存储的是对象还是引用呢? - RednaxelaFX 的回答 - 知乎:<https://www.zhihu.com/question/57109429/answer/151717241>
- <http://www.pointsoftware.ch/en/under-the-hood-runtime-data-areas-javas-memory-model/>
- <https://dzone.com/articles/jvm-permgen-%E2%80%93-where-art-thou>
- <https://stackoverflow.com/questions/9095748/method-area-and-permgen>

View File

@ -110,10 +110,10 @@ Oracle 的 HotSpot VM 便附带两个用 C++ 实现的 JIT compilerC1 及 C2
## 参考
- Java 10 Features and Enhancements : https://howtodoinjava.com/java10/java10-features/
- Java 10 Features and Enhancements : <https://howtodoinjava.com/java10/java10-features/>
- Guide to Java10 : <https://www.baeldung.com/java-10-overview>
- 4 Class Data Sharing : https://docs.oracle.com/javase/10/vm/class-data-sharing.htm#JSJVM-GUID-7EAA3411-8CF0-4D19-BD05-DF5E1780AA91
- 4 Class Data Sharing : <https://docs.oracle.com/javase/10/vm/class-data-sharing.htm#JSJVM-GUID-7EAA3411-8CF0-4D19-BD05-DF5E1780AA91>
<!-- @include: @article-footer.snippet.md -->

View File

@ -125,7 +125,7 @@ Consumer<String> consumer = (String i) -> System.out.println(i);
## 参考
- JDK 11 Release Noteshttps://www.oracle.com/java/technologies/javase/11-relnote-issues.html
- JDK 11 Release Notes<https://www.oracle.com/java/technologies/javase/11-relnote-issues.html>
- Java 11 Features and Comparison<https://www.geeksforgeeks.org/java-11-features-and-comparison/>
<!-- @include: @article-footer.snippet.md -->

View File

@ -115,9 +115,9 @@ if (o instanceof String s) {
```java
public class Outer {
class Inner {
static int age;
}
class Inner {
static int age;
}
}
```

View File

@ -22,7 +22,7 @@ JDK 21 共有 15 个新特性:
## JEP 430字符串模板预览
String Templates(字符串模板) 目前仍然是 JDK 21 中的一个预览功能。
String Templates(字符串模板) 目前仍然是 JDK 21 中的一个预览功能。
String Templates 提供了一种更简洁、更直观的方式来动态构建字符串。通过使用占位符`${}`我们可以将变量的值直接嵌入到字符串中而不需要手动处理。在运行时Java 编译器会将这些占位符替换为实际的变量值。并且,表达式支持局部变量、静态/非静态字段甚至方法、计算结果等特性。
@ -53,7 +53,7 @@ message = new StringBuilder().append("Greetings ").append(name).append("!").toSt
这些方法或多或少都存在一些缺点,比如难以阅读、冗长、复杂。
Java 使用 String Templates 进行字符串拼接,可以直接在字符串中嵌入表达式,而无需进行额外的处理:
Java 使用 String Templates 进行字符串拼接,可以直接在字符串中嵌入表达式,而无需进行额外的处理:
```java
String message = STR."Greetings \{name}!";
@ -155,4 +155,3 @@ java -XX:+UseZGC -XX:+ZGenerational ...
## 参考
- Java 21 String Templates<https://howtodoinjava.com/java/java-string-templates/>

View File

@ -7,7 +7,7 @@
欢迎阅读我对 Java 8 的介绍。本教程将逐步指导您完成所有新语言功能。 在简短的代码示例的基础上您将学习如何使用默认接口方法lambda 表达式,方法引用和可重复注释。 在本文的最后,您将熟悉最新的 API 更改,如流,函数式接口(Functional Interfaces)Map 类的扩展和新的 Date API。 没有大段枯燥的文字,只有一堆注释的代码片段。
### 接口的默认方法(Default Methods for Interfaces)
## 接口的默认方法(Default Methods for Interfaces)
Java 8 使我们能够通过使用 `default` 关键字向接口添加非抽象方法实现。 此功能也称为[虚拟扩展方法](http://stackoverflow.com/a/24102730)。
@ -51,7 +51,7 @@ formula 是作为匿名对象实现的。该代码非常容易理解6 行代
**译者注:** 不管是抽象类还是接口,都可以通过匿名内部类的方式访问。不能通过抽象类或者接口直接创建对象。对于上面通过匿名内部类方式访问接口,我们可以这样理解:一个内部类实现了接口里的抽象方法并且返回一个内部类对象,之后我们让接口的引用来指向这个对象。
### Lambda 表达式(Lambda expressions)
## Lambda 表达式(Lambda expressions)
首先看看在老版本的 Java 中是如何排列字符串的:
@ -90,7 +90,7 @@ names.sort((a, b) -> b.compareTo(a));
List 类本身就有一个 `sort` 方法。并且 Java 编译器可以自动推导出参数类型,所以你可以不用再写一次类型。接下来我们看看 lambda 表达式还有什么其他用法。
### 函数式接口(Functional Interfaces)
## 函数式接口(Functional Interfaces)
**译者注:** 原文对这部分解释不太清楚,故做了修改!
@ -116,7 +116,7 @@ public interface Converter<F, T> {
**译者注:** 大部分函数式接口都不用我们自己写Java8 都给我们实现好了,这些接口都在 java.util.function 包里。
### 方法和构造函数引用(Method and Constructor References)
## 方法和构造函数引用(Method and Constructor References)
前一节中的代码还可以通过静态方法引用来表示:
@ -176,9 +176,9 @@ Person person = personFactory.create("Peter", "Parker");
我们只需要使用 `Person::new` 来获取 Person 类构造函数的引用Java 编译器会自动根据`PersonFactory.create`方法的参数类型来选择合适的构造函数。
### Lambda 表达式作用域(Lambda Scopes)
## Lambda 表达式作用域(Lambda Scopes)
#### 访问局部变量
### 访问局部变量
我们可以直接在 lambda 表达式中访问外部的局部变量:
@ -209,7 +209,7 @@ Converter<Integer, String> stringConverter =
num = 3;//在lambda表达式中试图修改num同样是不允许的。
```
#### 访问字段和静态变量
### 访问字段和静态变量
与局部变量相比,我们在 lambda 表达式中对实例字段和静态变量都有读写访问权限。 该行为和匿名对象是一致的。
@ -232,7 +232,7 @@ class Lambda4 {
}
```
#### 访问默认接口方法
### 访问默认接口方法
还记得第一节中的 formula 示例吗? `Formula` 接口定义了一个默认方法`sqrt`,可以从包含匿名对象的每个 formula 实例访问该方法。 这不适用于 lambda 表达式。
@ -242,13 +242,13 @@ class Lambda4 {
Formula formula = (a) -> sqrt(a * 100);
```
### 内置函数式接口(Built-in Functional Interfaces)
## 内置函数式接口(Built-in Functional Interfaces)
JDK 1.8 API 包含许多内置函数式接口。 其中一些接口在老版本的 Java 中是比较常见的比如:`Comparator``Runnable`,这些接口都增加了`@FunctionalInterface`注解以便能用在 lambda 表达式上。
但是 Java 8 API 同样还提供了很多全新的函数式接口来让你的编程工作更加方便,有一些接口是来自 [Google Guava](https://code.google.com/p/guava-libraries/) 库里的,即便你对这些很熟悉了,还是有必要看看这些是如何扩展到 lambda 上使用的。
#### Predicate
### Predicate
Predicate 接口是只有一个参数的返回布尔类型值的 **断言型** 接口。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非):
@ -301,7 +301,7 @@ Predicate<String> isEmpty = String::isEmpty;
Predicate<String> isNotEmpty = isEmpty.negate();
```
#### Function
### Function
Function 接口接受一个参数并生成结果。默认方法可用于将多个函数链接在一起compose, andThen
@ -341,7 +341,7 @@ Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123"); // "123"
```
#### Supplier
### Supplier
Supplier 接口产生给定泛型类型的结果。 与 Function 接口不同Supplier 接口不接受参数。
@ -350,7 +350,7 @@ Supplier<Person> personSupplier = Person::new;
personSupplier.get(); // new Person
```
#### Consumer
### Consumer
Consumer 接口表示要对单个输入参数执行的操作。
@ -359,7 +359,7 @@ Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName);
greeter.accept(new Person("Luke", "Skywalker"));
```
#### Comparator
### Comparator
Comparator 是老 Java 中的经典接口, Java 8 在此之上添加了多种默认方法:

View File

@ -138,7 +138,7 @@ try (scanner;writer) {
**什么是 effectively-final 变量?** 简单来说就是没有被 `final` 修饰但是值在初始化后从未更改的变量。
正如上面的代码所演示的那样,即使 `writer` 变量没有被显示声明为 `final`,但它在第一次被复制后就不会改变了,因此,它就是 effectively-final 变量。
正如上面的代码所演示的那样,即使 `writer` 变量没有被显示声明为 `final`,但它在第一次被赋值后就不会改变了,因此,它就是 effectively-final 变量。
## Stream & Optional 增强

View File

@ -53,6 +53,7 @@ icon: tool
- [zktools](https://zktools.readthedocs.io/en/latest/#installing):一个低延迟的 ZooKeeper 图形化管理客户端,颜值非常高,支持 Mac / Windows / Linux 。你可以使用 zktools 来实现对 ZooKeeper 的可视化增删改查。
## Kafka
- [Kafka UI](https://github.com/provectus/kafka-ui):免费的开源 Web UI用于监控和管理 Apache Kafka 集群。
- [Kafdrop](https://github.com/obsidiandynamics/kafdrop) : 一个用于查看 Kafka 主题和浏览消费者组的 Web UI。
- [EFAK](https://github.com/smartloli/EFAK) Eagle For Apache Kafka以前叫做 Kafka Eagle一个简单的高性能监控系统用于对 Kafka 集群进行全面的监控和管理。

View File

@ -1,2 +1 @@
![JavaGuide 官方公众号](https://oss.javaguide.cn/github/javaguide/gongzhonghaoxuanchuan.png)

View File

@ -1,11 +1,9 @@
## 星球其他资源
[知识星球](../about-the-author/zhishixingqiu-two-years.md)除了提供了 **《Java 面试指北》** 、 **《Java 必读源码系列》**(目前已经整理了 Dubbo 2.6.x 、Netty 4.x、SpringBoot2.1 的源码)、 **《手写 RPC 框架》** 、**《Kafka 常见面试题/知识点总结》** 等多个专属小册,还有 读书活动、学习打卡、简历修改、免费提问、海量 Java 优质面试资源以及各种不定时的福利。
[知识星球](../about-the-author/zhishixingqiu-two-years.md)除了提供了 **《Java 面试指北》** 、 **《Java 必读源码系列》**(目前已经整理了 Dubbo 2.6.x 、Netty 4.x、SpringBoot2.1 的源码)、 **《手写 RPC 框架》** 、**《Kafka 常见面试题/知识点总结》** 等多个专属小册,还有 读书活动、学习打卡、简历修改、免费提问、海量 Java 优质面试资源以及各种不定时的福利。
![知识星球专栏概览](https://oss.javaguide.cn/xingqiu/image-20220211231206733.png)
![星球 PDF 面试手册](https://oss.javaguide.cn/xingqiu/image-20220723120918434.png)
下面是星球提供的部分服务(点击下方图片即可获取知识星球的详细介绍):

View File

@ -25,4 +25,3 @@
**无任何套路,无任何潜在收费项。用心做内容,不割韭菜!**
不过, **一定要确定需要再进** 。并且, **三天之内觉得内容不满意可以全额退款**

View File

@ -145,29 +145,29 @@ JSP 有 9 个内置对象:
## Request 对象的主要方法有哪些
- setAttribute(String name,Object):设置名字为 name 的 request 的参数值
- getAttribute(String name):返回由 name 指定的属性值
- getAttributeNames():返回 request 对象所有属性的名字集合,结果是一个枚举的实例
- getCookies():返回客户端的所有 Cookie 对象,结果是一个 Cookie 数组
- getCharacterEncoding():返回请求中的字符编码方式 = getContentLength():返回请求的 Body 的长度
- getHeader(String name):获得 HTTP 协议定义的文件头信息
- getHeaders(String name):返回指定名字的 request Header 的所有值,结果是一个枚举的实例
- getHeaderNames():返回所以 request Header 的名字,结果是一个枚举的实例
- getInputStream():返回请求的输入流,用于获得请求中的数据
- getMethod():获得客户端向服务器端传送数据的方法
- getParameter(String name):获得客户端传送给服务器端的有 name 指定的参数值
- getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
- getParameterValues(String name):获得有 name 指定的参数的所有值
- getProtocol():获取客户端向服务器端传送数据所依据的协议名称
- getQueryString():获得查询字符串
- getRequestURI():获取发出请求字符串的客户端地址
- getRemoteAddr():获取客户端的 IP 地址
- getRemoteHost():获取客户端的名字
- getSession([Boolean create]):返回和请求相关 Session
- getServerName():获取服务器的名字
- getServletPath():获取客户端所请求的脚本文件的路径
- getServerPort():获取服务器的端口号
- removeAttribute(String name):删除请求中的一个属性
- `setAttribute(String name,Object)`:设置名字为 name 的 request 的参数值
- `getAttribute(String name)`:返回由 name 指定的属性值
- `getAttributeNames()`:返回 request 对象所有属性的名字集合,结果是一个枚举的实例
- `getCookies()`:返回客户端的所有 Cookie 对象,结果是一个 Cookie 数组
- `getCharacterEncoding()`:返回请求中的字符编码方式 = getContentLength()`:返回请求的 Body 的长度
- `getHeader(String name)`:获得 HTTP 协议定义的文件头信息
- `getHeaders(String name)`:返回指定名字的 request Header 的所有值,结果是一个枚举的实例
- `getHeaderNames()`:返回所以 request Header 的名字,结果是一个枚举的实例
- `getInputStream()`:返回请求的输入流,用于获得请求中的数据
- `getMethod()`:获得客户端向服务器端传送数据的方法
- `getParameter(String name)`:获得客户端传送给服务器端的有 name 指定的参数值
- `getParameterNames()`:获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
- `getParameterValues(String name)`:获得有 name 指定的参数的所有值
- `getProtocol()`:获取客户端向服务器端传送数据所依据的协议名称
- `getQueryString()`:获得查询字符串
- `getRequestURI()`:获取发出请求字符串的客户端地址
- `getRemoteAddr()`:获取客户端的 IP 地址
- `getRemoteHost()`:获取客户端的名字
- `getSession([Boolean create])`:返回和请求相关 Session
- `getServerName()`:获取服务器的名字
- `getServletPath()`:获取客户端所请求的脚本文件的路径
- `getServerPort()`:获取服务器的端口号
- `removeAttribute(String name)`:删除请求中的一个属性
## request.getAttribute()和 request.getParameter()有何区别

View File

@ -42,8 +42,8 @@ package org.springframework.boot.autoconfigure;
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
......
}
@ -582,33 +582,33 @@ jpa 提供的主键生成策略有如下几种:
```java
public class DefaultIdentifierGeneratorFactory
implements MutableIdentifierGeneratorFactory, Serializable, ServiceRegistryAwareService {
implements MutableIdentifierGeneratorFactory, Serializable, ServiceRegistryAwareService {
@SuppressWarnings("deprecation")
public DefaultIdentifierGeneratorFactory() {
register( "uuid2", UUIDGenerator.class );
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
register( "uuid", UUIDHexGenerator.class ); // "deprecated" for new use
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
register( "assigned", Assigned.class );
register( "identity", IdentityGenerator.class );
register( "select", SelectGenerator.class );
register( "sequence", SequenceStyleGenerator.class );
register( "seqhilo", SequenceHiLoGenerator.class );
register( "increment", IncrementGenerator.class );
register( "foreign", ForeignGenerator.class );
register( "sequence-identity", SequenceIdentityGenerator.class );
register( "enhanced-sequence", SequenceStyleGenerator.class );
register( "enhanced-table", TableGenerator.class );
}
@SuppressWarnings("deprecation")
public DefaultIdentifierGeneratorFactory() {
register( "uuid2", UUIDGenerator.class );
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
register( "uuid", UUIDHexGenerator.class ); // "deprecated" for new use
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
register( "assigned", Assigned.class );
register( "identity", IdentityGenerator.class );
register( "select", SelectGenerator.class );
register( "sequence", SequenceStyleGenerator.class );
register( "seqhilo", SequenceHiLoGenerator.class );
register( "increment", IncrementGenerator.class );
register( "foreign", ForeignGenerator.class );
register( "sequence-identity", SequenceIdentityGenerator.class );
register( "enhanced-sequence", SequenceStyleGenerator.class );
register( "enhanced-table", TableGenerator.class );
}
public void register(String strategy, Class generatorClass) {
LOG.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() );
final Class previous = generatorStrategyToClassNameMap.put( strategy, generatorClass );
if ( previous != null ) {
LOG.debugf( " - overriding [%s]", previous.getName() );
}
}
public void register(String strategy, Class generatorClass) {
LOG.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() );
final Class previous = generatorStrategyToClassNameMap.put( strategy, generatorClass );
if ( previous != null ) {
LOG.debugf( " - overriding [%s]", previous.getName() );
}
}
}
```

View File

@ -51,13 +51,13 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory-config.xml");
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext(
"C:/work/IOC Containers/springframework.applicationcontext/src/main/resources/bean-factory-config.xml");
HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext");
obj.getMsg();
}
HelloApplicationContext obj = (HelloApplicationContext) context.getBean("helloApplicationContext");
obj.getMsg();
}
}
```

View File

@ -655,7 +655,6 @@ public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
#### Spring AOP 自调用问题
当一个方法被标记了`@Transactional` 注解的时候Spring 事务管理器只会在被其他类方法调用的时候生效,而不会在一个类中方法调用生效。
这是因为 Spring AOP 工作原理决定的。因为 Spring AOP 使用动态代理来实现事务的管理,它会在运行的时候为带有 `@Transactional` 注解的方法生成代理对象,并在方法调用的前后应用事物逻辑。如果该方法被其他类调用我们的代理对象就会拦截方法调用并处理事务。但是在一个类中的其他方法内部调用的时候,我们代理对象就无法拦截到这个内部调用,因此事务也就失效了。

View File

@ -11,5 +11,4 @@ tag:
<!-- @include: @yuanma.snippet.md -->
<!-- @include: @article-footer.snippet.md -->

View File

@ -357,17 +357,17 @@ public ReturnT<String> myAnnotationJobHandler(String param) throws Exception {
由于 SchedulerX 属于人民币产品我这里就不过多介绍。PowerJob 官方也对比过其和 QuartZ、XXL-JOB 以及 SchedulerX。
| | QuartZ | xxl-job | SchedulerX 2.0 | PowerJob |
| -------------- | ------------------------------------------ | ---------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------ |
| 定时类型 | CRON | CRON | CRON、固定频率、固定延迟、OpenAPI | **CRON、固定频率、固定延迟、OpenAPI** |
| | QuartZ | xxl-job | SchedulerX 2.0 | PowerJob |
| -------------- | ------------------------------------------- | ------------------------------------------ | ---------------------------------------------------- | --------------------------------------------------------------- |
| 定时类型 | CRON | CRON | CRON、固定频率、固定延迟、OpenAPI | **CRON、固定频率、固定延迟、OpenAPI** |
| 任务类型 | 内置 Java | 内置 Java、GLUE Java、Shell、Python 等脚本 | 内置 Java、外置 JavaFatJar、Shell、Python 等脚本 | **内置 Java、外置 Java容器、Shell、Python 等脚本** |
| 分布式计算 | 无 | 静态分片 | MapReduce 动态分片 | **MapReduce 动态分片** |
| 在线任务治理 | 不支持 | 支持 | 支持 | **支持** |
| 日志白屏化 | 不支持 | 支持 | 不支持 | **支持** |
| 调度方式及性能 | 基于数据库锁,有性能瓶颈 | 基于数据库锁,有性能瓶颈 | 不详 | **无锁化设计,性能强劲无上限** |
| 报警监控 | 无 | 邮件 | 短信 | **WebHook、邮件、钉钉与自定义扩展** |
| 系统依赖 | JDBC 支持的关系型数据库MySQL、Oracle... | MySQL | 人民币 | **任意 Spring Data Jpa 支持的关系型数据库MySQL、Oracle...** |
| DAG 工作流 | 不支持 | 不支持 | 支持 | **支持** |
| 分布式计算 | 无 | 静态分片 | MapReduce 动态分片 | **MapReduce 动态分片** |
| 在线任务治理 | 不支持 | 支持 | 支持 | **支持** |
| 日志白屏化 | 不支持 | 支持 | 不支持 | **支持** |
| 调度方式及性能 | 基于数据库锁,有性能瓶颈 | 基于数据库锁,有性能瓶颈 | 不详 | **无锁化设计,性能强劲无上限** |
| 报警监控 | 无 | 邮件 | 短信 | **WebHook、邮件、钉钉与自定义扩展** |
| 系统依赖 | JDBC 支持的关系型数据库MySQL、Oracle... | MySQL | 人民币 | **任意 Spring Data Jpa 支持的关系型数据库MySQL、Oracle...** |
| DAG 工作流 | 不支持 | 不支持 | 支持 | **支持** |
## 定时任务方案总结

View File

@ -40,27 +40,27 @@ tag:
Hutool 一个 Java 基础工具类对文件、流、加密解密、转码、正则、线程、XML 等 JDK 方法进行封装,组成各种 Util 工具类,同时提供以下组件:
| 模块 | 介绍 |
| :----------------: | :----------------------------------------------------------: |
| hutool-aop | JDK 动态代理封装,提供非 IOC 下的切面支持 |
| hutool-bloomFilter | 布隆过滤,提供一些 Hash 算法的布隆过滤 |
| hutool-cache | 简单缓存实现 |
| hutool-core | 核心,包括 Bean 操作、日期、各种 Util 等 |
| hutool-cron | 定时任务模块,提供类 Crontab 表达式的定时任务 |
| hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
| hutool-db | JDBC 封装后的数据操作,基于 ActiveRecord 思想 |
| hutool-dfa | 基于 DFA 模型的多关键字查找 |
| 模块 | 介绍 |
| :----------------: | :---------------------------------------------------------------------------: |
| hutool-aop | JDK 动态代理封装,提供非 IOC 下的切面支持 |
| hutool-bloomFilter | 布隆过滤,提供一些 Hash 算法的布隆过滤 |
| hutool-cache | 简单缓存实现 |
| hutool-core | 核心,包括 Bean 操作、日期、各种 Util 等 |
| hutool-cron | 定时任务模块,提供类 Crontab 表达式的定时任务 |
| hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 |
| hutool-db | JDBC 封装后的数据操作,基于 ActiveRecord 思想 |
| hutool-dfa | 基于 DFA 模型的多关键字查找 |
| hutool-extra | 扩展模块对第三方封装模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等 |
| hutool-http | 基于 HttpUrlConnection 的 Http 客户端封装 |
| hutool-log | 自动识别日志实现的日志门面 |
| hutool-script | 脚本执行封装,例如 Javascript |
| hutool-setting | 功能更强大的 Setting 配置文件和 Properties 封装 |
| hutool-system | 系统参数调用封装JVM 信息等) |
| hutool-json | JSON 实现 |
| hutool-captcha | 图片验证码实现 |
| hutool-poi | 针对 POI 中 Excel 和 Word 的封装 |
| hutool-socket | 基于 Java 的 NIO 和 AIO 的 Socket 封装 |
| hutool-jwt | JSON Web Token (JWT) 封装实现 |
| hutool-http | 基于 HttpUrlConnection 的 Http 客户端封装 |
| hutool-log | 自动识别日志实现的日志门面 |
| hutool-script | 脚本执行封装,例如 Javascript |
| hutool-setting | 功能更强大的 Setting 配置文件和 Properties 封装 |
| hutool-system | 系统参数调用封装JVM 信息等) |
| hutool-json | JSON 实现 |
| hutool-captcha | 图片验证码实现 |
| hutool-poi | 针对 POI 中 Excel 和 Word 的封装 |
| hutool-socket | 基于 Java 的 NIO 和 AIO 的 Socket 封装 |
| hutool-jwt | JSON Web Token (JWT) 封装实现 |
可以根据需求对每个模块单独引入,也可以通过引入`hutool-all`方式引入所有模块,本文所使用的数据脱敏工具就是在 `hutool.core` 模块。

View File

@ -16,7 +16,7 @@ head:
> 作者:转转技术团队
>
> 原文https://mp.weixin.qq.com/s/ONMuELjdHYa0yQceTj01Iw
> 原文:<https://mp.weixin.qq.com/s/ONMuELjdHYa0yQceTj01Iw>
## 老权限系统的问题与现状
@ -208,6 +208,6 @@ head:
## 参考
- 选择合适的权限模型https://docs.authing.cn/v2/guides/access-control/choose-the-right-access-control-model.html
- 选择合适的权限模型:<https://docs.authing.cn/v2/guides/access-control/choose-the-right-access-control-model.html>
<!-- @include: @article-footer.snippet.md -->

View File

@ -10,7 +10,8 @@
"docs:dev": "vuepress dev docs",
"docs:clean-dev": "vuepress dev docs --clean-cache",
"lint": "prettier --check --write . && markdownlint docs/**/*.md",
"prepare": "husky install"
"prepare": "husky install",
"update": "pnpm dlx vp-update"
},
"nano-staged": {
".ts,.scss": "prettier --write",
@ -19,18 +20,19 @@
"markdownlint"
]
},
"packageManager": "pnpm@8.6.0",
"packageManager": "pnpm@8.9.2",
"dependencies": {
"@vuepress/client": "2.0.0-beta.67",
"@vuepress/plugin-search": "2.0.0-beta.67",
"@vuepress/utils": "2.0.0-beta.67",
"husky": "8.0.3",
"markdownlint-cli": "0.34.0",
"markdownlint-cli": "0.37.0",
"mathjax-full": "3.2.2",
"nano-staged": "0.8.0",
"nodejs-jieba": "0.0.2",
"prettier": "2.8.8",
"vue": "3.3.4",
"prettier": "3.0.3",
"vue": "3.3.7",
"vuepress": "2.0.0-beta.67",
"vuepress-theme-hope": "2.0.0-beta.236"
"vuepress-theme-hope": "2.0.0-beta.241"
}
}

10021
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff