2016年1月15日面試某互聯網公司總結(二)

  首先,感謝你們的瀏覽,還有朋友給推薦工做,因爲本人目前在北京,且年後本人在北京還有部分課程須要上,所以如今不便於遠行前往深圳,廣州等地。仍是很是感謝你們!html

  今天主要是把以前的工具,作了一些設置與調整,工欲善其事,必先利其器嘛。主要涉及到Eclipse設置maven使用(以前工做都是使用自有構建工具,如今用開源,開源工具功能大而全,可是,每每也坑比較多),git工具的使用(之前工做一直使用SVN,版本管理之後稍做介紹),Mysql安裝使用(以前工做一直使用oracle,關於這一部分之後作詳加使用說明)。下面仍是接昨天的,把面試涉及到的東西寫完整。java

====================================華麗分割線===========================================git

1.索引的使用,聯合索引的使用,是否索引越多越好?面試

答:[以oracle爲例]索引比如是一本書前面的目錄,能加快數據庫表的查詢速度。索引分爲聚簇索引非聚簇索引兩種,聚簇索引 是按照數據存放的物理位置爲順序的,而非聚簇索引就不同了;聚簇索引能提升多行檢索的速度,而非聚簇索引對於單行的檢索很快。sql

   用的最多也最好的是B-tree索引,它主要是避免了大量數據的排序操做。數據庫

   數據庫中存儲數據的基礎單位就是頁,數據庫的頁大小和操做系統相似,是指存放數據時,每一塊的大小。好比一個1M的數據存放在數據庫中時, 須要大概12塊頁來存放。若是是在操做系統上安裝的數據庫,最好將數據庫頁大小設置爲操做系統頁大小的倍數,纔是最佳設置。數據庫能夠將數據從邏輯上分紅頁,磁盤的I/O操做就是在頁級執行。數組

  • 96字節大小的標頭,存儲統計信息,包括頁碼、頁類型、頁的可用空間以及擁有該頁的對象的分配單元 ID。數據庫頁類型主要分以下三類:
      • 數據頁,除了大型對象的數據列以外的數據存儲頁,好比int,float,varchar等。     
      • 索引頁,存放索引的條目。
      • 大型對象數據類型,好比text,image,nvarchar(max)等。        
  • 一個區包含8個頁,它是管理空間的單位,分爲以下兩類
    • 統一區,由單個對象全部。
    • 混合區,最多可由八個對象共享

  知道了區以及頁的概念,再看下數據表和這二者之間的聯繫, 表包含一個或多個分區,每一個分區在一個堆或一個彙集索引結構中包含數據行。oracle

  索引中的底層節點稱爲葉節點。根節點與葉節點之間的任何索引級別統稱爲中間級。在彙集索引中,葉節點包含基礎表的數據頁。根節點和中間級節點包含存有索引行的索引頁。每一個索引行包含一個鍵值和一個指針,該指針指向 B -樹上的某一中間級頁或葉級索引中的某個數據行。每級索引中的頁均被連接在雙向連接列表中。maven

非彙集索引與彙集索引之間的顯著差異在於如下兩點:函數

  • 基礎表的數據行不按非彙集鍵的順序排序和存儲。
  • 非彙集索引的葉層是由索引頁而不是由數據頁組成。

  索引的優勢:正確的索引會大大提升數據查詢,對結果進行排序、分組的操做效率。
    索引的缺點:
    1.建立索引須要額外的磁盤空間,索引最大通常爲表大小的1.2倍左右。
    2.在表數據修改時,例如增長,刪除,更新,都須要維護索引表,這是須要系統開銷的。
    3.不合理的索引設計非但不能利於系統,反而會使系統性能降低。例如咱們在一個建立有非彙集索引的列上作範圍查詢,此列的索引不會起到任何的優化效果,反而因爲數據的修改而須要維護索引表,從而影響了對數據修改的性能。

什麼字段不適合建立索引?
    1.不常用的列,這種索引帶來缺點遠大於帶來的優勢。

    2.邏輯性的字段,例如性別字段等等,匹配的記錄太多,和全表掃描比起來差很少。

    3.字段內容特別大的字段,例如大字段等,這會大大增大索引所佔用的空間以及索引維護時的速度。

  4.涉及到計算的列,或者是須要利用數據庫函數進行加工處理的列不該當建立索引。

聯合索引:

1.查詢條件中出現聯合索引第一列,或者所有,則能利用聯合索引.

2.條件列中只要條件相連在一塊兒,不管先後,都會利用上聯合索引.

3.查詢條件中沒有出現聯合索引的第一列,而出現聯合索引的第二列,或者第三列,都不會利用聯合索引查詢.

單一列索引:

  1.只要條件列中出現索引列,不管在什麼位置,都能利用索引查詢.

另外,實際使用過程當中,常常遇到索引丟失的狀況,這種狀況通常須要重建索引,有的涉及到複雜業務查詢的語句,須要優化查詢,對於具體的SQL,可能因爲優化的緣由,有不是理想的執行計劃。

======================================華麗分割線==========================================

2.實現二路歸併排序(面試是要求畫出圖)

 答:二路歸併理解起來比較容易,主要是利用分治法。可是,具體代碼仍是要下一些功夫。

  核心思想:將待排序序列R[0...n-1]當作是n個長度爲1的有序序列,將相鄰的有序表成對歸併,獲得n/2個長度爲2的有序表;將這些有序序列再次歸併,獲得n/4個長度爲4的有序序列;如此反覆進行下去,最後獲得一個長度爲n的有序序列。

歸併排序其實要作兩件事:

  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);
    }
}

 

==================================華麗分割線=============================================

這次面試主要內容就以上,再也不深究了。接下來一段時間,我會利用好,出一些系列的東西,也想本身實現點東西。感謝支持!

相關文章
相關標籤/搜索