首先,感谢大家的浏览,还有朋友给推荐工作,由于本人目前在北京,且年后本人在北京还有部分课程需要上,因此现在不便于远行前往深圳,广州等地。还是非常感谢大家!
今天主要是把之前的工具,做了一些设置与调整,工欲善其事,必先利其器嘛。主要涉及到Eclipse设置,maven使用(之前工作都是使用自有构建工具,现在用开源,开源工具功能大而全,但是,往往也坑比较多),git工具的使用(以前工作一直使用SVN,版本管理以后稍作介绍),Mysql安装使用(之前工作一直使用oracle,关于这一部分以后做详加使用说明)。下面还是接昨天的,把面试涉及到的东西写完整。
====================================华丽分割线===========================================
1.索引的使用,联合索引的使用,是否索引越多越好?
答:[以oracle为例]索引好比是一本书前面的目录,能加快数据库表的查询速度。索引分为聚簇索引和非聚簇索引两种,聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。
用的最多也最好的是B-tree索引,它主要是避免了大量数据的排序操作。
数据库中存储数据的基础单位就是页,数据库的页大小和操作系统类似,是指存放数据时,每一块的大小。比如一个1M的数据存放在数据库中时, 需要大概12块页来存放。如果是在操作系统上安装的数据库,最好将数据库页大小设置为操作系统页大小的倍数,才是最佳设置。数据库可以将数据从逻辑上分成页,磁盘的I/O操作就是在页级执行。
知道了区以及页的概念,再看下数据表和这两者之间的联系, 表包含一个或多个分区,每个分区在一个堆或一个聚集索引结构中包含数据行。
索引中的底层节点称为叶节点。根节点与叶节点之间的任何索引级别统称为中间级。在聚集索引中,叶节点包含基础表的数据页。根节点和中间级节点包含存有索引行的索引页。每个索引行包含一个键值和一个指针,该指针指向 B -树上的某一中间级页或叶级索引中的某个数据行。每级索引中的页均被链接在双向链接列表中。
非聚集索引与聚集索引之间的显著差别在于以下两点:
索引的优点:正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。
索引的缺点:
1.创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。
2.在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的。
3.不合理的索引设计非但不能利于系统,反而会使系统性能下降。例如我们在一个创建有非聚集索引的列上做范围查询,此列的索引不会起到任何的优化效果,反而由于数据的修改而需要维护索引表,从而影响了对数据修改的性能。
什么字段不适合创建索引?
1.不经常使用的列,这种索引带来缺点远大于带来的优点。
2.逻辑性的字段,例如性别字段等等,匹配的记录太多,和全表扫描比起来差不多。
3.字段内容特别大的字段,例如大字段等,这会大大增大索引所占用的空间以及索引维护时的速度。
4.涉及到计算的列,或者是需要利用数据库函数进行加工处理的列不应当创建索引。
联合索引:
1.查询条件中出现联合索引第一列,或者全部,则能利用联合索引.
2.条件列中只要条件相连在一起,无论前后,都会利用上联合索引.
3.查询条件中没有出现联合索引的第一列,而出现联合索引的第二列,或者第三列,都不会利用联合索引查询.
单一列索引:
1.只要条件列中出现索引列,无论在什么位置,都能利用索引查询.
另外,实际使用过程中,经常遇到索引丢失的情况,这种情况一般需要重建索引,有的涉及到复杂业务查询的语句,需要优化查询,对于具体的SQL,可能由于优化的原因,有不是理想的执行计划。
======================================华丽分割线==========================================
2.实现二路归并排序(面试是要求画出图)
答:二路归并理解起来比较容易,主要是利用分治法。但是,具体代码还是要下一些功夫。
归并排序其实要做两件事:
1.分解——将序列每次折半划分。
2.合并——将划分后的序列段两两合并后排序。
合并的规则:
在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。这两个有序序列段分别为 arr[low, mid] 和 arr[mid+1, high]。先将他们合并到一个局部的暂存数组tmparr中,待合并完成后再将tmparr复制回R中。这里称 arr[low, mid] 第一段,arr[mid+1, high] 为第二段。每次从两个段中取出一个记录进行关键字的比较,将较小者放入tmparr中。最后将各段中余下的部分直接复制到tmparr中。经过这样的过程,tmparr已经是一个有序的序列,再将其复制回arr中,一次合并排序就完成了。
注意,若子表个数为奇数,则最后一个子表无须和其他子表归并(即本趟处理轮空):若子表个数为偶数,则要注意到最后一对子表中后一个子表区间的上限为n-1。
/** * @FileName MergeSort.java * @Package com.algorithm.sort * @Description * <li>二路归并排序,它相对与快排序和堆排序来说,是稳定的排序方法,时间复杂度o(nlnn),空间复杂度为o(n)</li> * @Author ali blog:http://www.cnblogs.com/accipiter * @Date 上午1:06:31 * @Version V1.0.1 */ package com.algorithm.sort; /** * @ClassName MergeSort * @Description TODO * @Date 下午11:14:51 */ public class MergeSort { /** * @Title Merge * @Description TODO * @param arr * @param low * @param mid * @param high * @Return void * @Throws * @user Administrator */ public void merge(int[] arr, int low, int mid, int high) { int i = low; // i是第一段序列的起始 int j = mid + 1; // j是第二段序列的起始 int k = 0; // k是临时存放合并序列的起始 int[] tmparr = new int[high - low + 1]; // tmparr是临时合并序列 while (i <= mid && j <= high) { if (arr[i] <= arr[j]) { tmparr[k++] = arr[i++]; } else { tmparr[k++] = arr[j++]; } } while (i <= mid) { tmparr[k++] = arr[i++]; } while (j <= high) { tmparr[k++] = arr[j++]; } for (k = 0, i = low; i <= high; i++, k++) { arr[i] = tmparr[k]; } } /** * @Title MergeStep * @Description TODO * @param arr * @param len * @param length * @Return void * @Throws * @user Administrator */ public void mergeStep(int[] arr, int len, int length) { int i = 0; for (i=0;i+ 2*len-1<length;i+=2*len){ merge(arr,i, i+len-1, i+ 2*len-1); } if (i+len-1<length){ merge(arr,i, i+len-1,length-1); } } /** * @Title sort * @Description TODO * @param list * @return * @Return int[] * @Throws * @user Administrator */ public int[] sort(int[] list) { for (int len = 1; len < list.length; len = 2 * len) { mergeStep(list, len, list.length); System.out.print("len = " + len + ":\t"); this.printAll(list); } return list; } /** * @Title printAll * @Description TODO * @param list * @Return void * @Throws * @user Administrator */ public void printAll(int[] list) { for(int value : list){ System.out.print(value + "\t"); } System.out.println(); } /** * @Title MSort * @Description * <li>纯递归实现二路归并排序</li> * @param arr * @param low * @param high * @Return void * @Throws * @user Administrator */ public void mSort(int []arr,int low,int high){ if(low<high){ int mid=(low+high)/2; mSort(arr,low,mid); mSort(arr,mid+1,high); merge(arr,low,mid,high); this.printAll(arr); } } public static void main(String[] args) { int[] array = { 8, 1, 7, 3, 1, 2, 6, 9, 5}; MergeSort merge = new MergeSort(); System.out.print("排序前:\t\t"); merge.printAll(array); // merge.sort(array); merge.mSort(array,0,array.length-1); System.out.print("排序后:\t\t"); merge.printAll(array); } }
==================================华丽分割线=============================================
此次面试主要内容就以上,不再深究了。接下来一段时间,我会利用好,出一些系列的东西,也想自己实现点东西。感谢支持!