diff --git a/code/src/main/java/com/raorao/sword/MinK.java b/code/src/main/java/com/raorao/sword/MinK.java new file mode 100644 index 00000000..6a87cc04 --- /dev/null +++ b/code/src/main/java/com/raorao/sword/MinK.java @@ -0,0 +1,57 @@ +package com.raorao.sword; + +import java.util.ArrayList; + +/** + * . + * + * @author Xiong Raorao + * @since 2018-09-12-21:01 + */ +public class MinK { + + public static void main(String[] args) { + int[] nums = new int[] {4, 5, 1, 6, 2, 7, 3, 8}; + ArrayList list = new MinK().GetLeastNumbers_Solution(nums, 4); + System.out.println(list.toString()); + } + + public ArrayList GetLeastNumbers_Solution(int[] input, int k) { + ArrayList list = new ArrayList<>(); + if (k > input.length) { + return list; + } + int low = 0; + int high = input.length - 1; + while (true) { + int index = partition(input, low, high); + if (index == k - 1) { + for (int i = 0; i < k; i++) { + list.add(input[i]); + } + break; + } else if (index < k) { + low = index + 1; + } else { + high = index - 1; + } + } + return list; + } + + public int partition(int[] arr, int low, int high) { + int pivot = arr[low]; + while (low < high) { + while (arr[high] > pivot && low < high) { + high--; + } + arr[low] = arr[high]; + while (arr[low] <= pivot && low < high) { + low++; + } + arr[high] = arr[low]; + } + arr[low] = pivot; + return low; + } +} diff --git a/interview/database/mysql.md b/interview/database/mysql.md index 634b97f2..84e5d7b6 100644 --- a/interview/database/mysql.md +++ b/interview/database/mysql.md @@ -13,6 +13,13 @@ - [事务的基本要素(ACID):](#事务的基本要素acid) - [事务的并发问题:](#事务的并发问题) - [Mysql事务隔离级别:](#mysql事务隔离级别) +- [java jdbc 接口](#java-jdbc-接口) +- [数据库索引](#数据库索引) + - [索引类型](#索引类型) + - [索引比较](#索引比较) + - [数据库引擎](#数据库引擎) + - [索引创建](#索引创建) + - [索引实现方式](#索引实现方式) @@ -165,4 +172,111 @@ MySQL 的事务提交默认是隐式提交,每执行一条语句就把这条 读未提交(read-uncommitted) | 是 | 是 | 是 不可重复读(read-committed) | 否 | 是 | 是 可重复读(repeatable-read) | 否 | 否 | 是 -串行化(serializable) | 否 | 否 | 否 \ No newline at end of file +串行化(serializable) | 否 | 否 | 否 + +# java jdbc 接口 + +Statement 每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement. + +PreparedStatement是预编译的,使用PreparedStatement有几个好处 + +a. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。 + +b. 安全性好,有效防止Sql注入等问题。 + +c. 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch; + +d. 代码的可读性和可维护性。 + +CallableStatement接口扩展 PreparedStatement,用来调用存储过程,它提供了对输出和输入/输出参数的支持。CallableStatement 接口还具有对 PreparedStatement 接口提供的输入参数的支持。 + + +# 数据库索引 + +## 索引类型 + +1、唯一索引 UNIQUE + +create unique index stusno on student(sno); + +2、主键索引 primary key + +数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 + +CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, PRIMARY KEY(ID) ); + +3、聚集索引(也叫聚簇索引):cluster + +在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 + +聚集索引中,表数据和主键是一起存储的,主键索引的叶结点存储行数据(包含了主键值),二级索引的叶结点存储行的主键值。使用的是B+树作为索引的存储结构,非叶子节点都是索引关键字,但非叶子节点中的关键字中不存储对应记录的具体内容或内容地址。叶子节点上的数据是主键与具体记录(数据内容)。 + +4、非聚集索引 + +对于非聚簇索引表来说(右图),表数据和索引是分成两部分存储的,主键索引和二级索引存储上没有任何区别。使用的是B+树作为索引的存储结构,所有的节点都是索引,叶子节点存储的是索引+索引对应的记录的地址。 + +![](https://upload-images.jianshu.io/upload_images/2836699-d062eac68af5cd31?imageMogr2/auto-orient/strip%7CimageView2/2/w/696/format/webp) + +5、普通索引 + +create index index_birthday on user_info(birthday); + +## 索引比较 + +聚簇索引的优点: + +1、当你需要取出一定范围内的数据时,用聚簇索引和非聚簇索引好 + +2、当通过聚簇索引查找目标数据时理论上比非聚簇索引要快,因为非聚簇索引定位到对应主键时还要多一次目标记录寻址,即多一次I/O。 + +聚簇索引的缺点: + +1.插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键。 + +2.更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。 + +3.二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。 +二级索引的叶节点存储的是主键值,而不是行指针(非聚簇索引存储的是指针或者说是地址),这是为了减少当出现行移动或数据页分裂时二级索引的维护工作,但会让二级索引占用更多的空间。 + +4.采用聚簇索引插入新值比采用非聚簇索引插入新值的速度要慢很多,因为插入要保证主键不能重复,判断主键不能重复,采用的方式在不同的索引下面会有很大的性能差距,聚簇索引遍历所有的叶子节点,非聚簇索引也判断所有的叶子节点,但是聚簇索引的叶子节点除了带有主键还有记录值,记录的大小往往比主键要大的多。这样就会导致聚簇索引在判定新记录携带的主键是否重复时进行昂贵的I/O代价。 + + +## 数据库引擎 + +InnoDB: Mysql 默认的数据库引擎,采用聚簇索。 + +MyISAM 不管是主键索引,还是二级索引使用的都是非聚簇索引。 + +## 索引创建 + +``` sql + +// 创建索引 +create index index_birthday on user_info(birthday); + +// 查询生日在1991年11月1日出生用户的用户名 + +select user_name from user_info where birthday = '1991-11-1' +``` + +执行逻辑如下: + +首先,通过非聚集索引index_birthday查找birthday等于1991-11-1的所有记录的主键ID值 + +然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对就的真实数据(数据行)存储的位置 + +最后, 从得到的真实数据中取得user_name字段的值返回, 也就是取得最终的结果 + +## 索引实现方式 + +1、B+树 + +多路搜索树 + +2、散列索引 + +就是通过散列函数来定位的一种索引,不过很少有单独使用散列索引的,反而是散列文件组织用的比较多。 + +3、位图索引 + +位图索引是一种针对多个字段的简单查询设计一种特殊的索引,适用范围比较小,只适用于字段值固定并且值的种类很少的情况,比如性别,只能有男和女,或者级别,状态等等,并且只有在同时对多个这样的字段查询时才能体现出位图的优势。 \ No newline at end of file