美团点评2020校招数据分析方向笔试题

说明关系型数据库通过索引提升查询效率的背后原理 。

  1. 如果没有索引,数据库引擎需要通过全表扫描来查找数据,这会产生大量的磁盘IO。

  2. 关系型数据库使用B+树构建索引来加速加快查询。B+树是一种二叉查找树(每个节点的键值必须:比保存在左子树的任何键值都要大,比保存在右子树的任何键值都要小),这样随机查找某个键值时可以通过从根节点执行二叉查找来加速查询,查询成本取决于树的层数。

  3. 针对范围查询和排序的优化:在每个叶子节点保存其下一个叶子节点的指针,这样当指定范围范围查询时,先从根节点根据范围的左值找到其叶子节点,之后通过向后遍历叶子节点即可找到对应范围右值,这样可以加速范围查询、排序、分组等数据库查询动作。

  4. 针对磁盘读写速度的优化:除了叶子节点之外的其他节点只保存键值,这样对磁盘的单次读写可以获取到尽可能多的数据。以MySQL为例,一个1000万行的表对应的B+树按照主键查找理论上只需要3次磁盘IO,这相对于全表扫描带来的磁盘IO是多个量级的性能提升。

  5. MySQL等数据库引擎在实际实现B+树索引的时候,针对磁盘读写做了优化:非叶子节点中只存放key值,叶子节点中除了key值也会存放数据,按照存放数据的不同索引区分为主索引(聚簇索引)和辅助索引:

    a) 主索引的叶子节点中存放该key值对应的完整记录,使用主索引进行查找时,可以直接输出记录;一个表只能创建一个主索引。

    b)
    普通索引的叶子节点则存放对应主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找;一个表可以创建多个辅助索引。

  6. 除了B+树,关系型数据库一般也支持哈希索引,哈希索引能够非常高效地进行随机查找,但是对于范围查询、排序和分组都不支持。

[编程题]寻找最后的山峰

热度指数:1319时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 256M,其他语言512M 算法知识视频讲解
山峰元素是指其值大于或等于左右相邻值的元素。给定一个输入数组nums,任意两个相邻元素值不相等,数组可能包含多个山峰。找到索引最大的那个山峰元素并返回其索引。

假设 nums[-1] = nums[n] = -∞。

输入描述: 在命令行中输入一行数字,数字之间以空格分割,遇到换行符结束。输入的数字为整型,且总数量在10万以内。

输出描述:
输出索引最大的山峰的索引值(一个数字)

示例1
输入
2 4 1 2 7 8 4
输出
5
说明
索引最大的山峰的高度为8,其索引为5

import  java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int[] arr = new int[100005];
        
        int num = 0;
        while(in.hasNextInt()){
            arr[num++] = in.nextInt();
        }
        num--;
        while(num > 0 && arr[num - 1] > arr[num] ){
            num--;
        }
        System.out.println(num);
    }
}

[编程题]比大小

热度指数:954时间限制:C/C++ 2秒,其他语言4秒空间限制:C/C++ 256M,其他语言512M 算法知识视频讲解
给定一个整数数组,返回一个数组。该返回数组中第i个数字为,原数组中第i个位置的数字至少往右走多少步才能遇到比它大的数字。如果遇不到或者已经处于最右的位置,则置为-1。

输入描述: 输入为多行,第一行为一个整数N,1≤N≤106

接下来一共有N行,每一行为一个整数M,0≤M≤232-1

输出描述: 输出 N 行,每行一个数字表示转换之后的数组

示例1
输入
5
91
10
3
22
40
输出
-1
2
1
1
-1

import java.util.*;
  
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] d = new int[n];
        for(int i=0; i<n; i++){
            d[i] = in.nextInt();
        }
        int[] ret = help(d);
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<ret.length; i++){
            sb.append(ret[i]).append("\n");
        }
        System.out.print(sb.toString());
    }
      
    private static int[] help(int[] nums){
        int[] ret = new int[nums.length];
        Arrays.fill(ret, -1);
        Stack<Integer> s = new Stack<>();
        for(int i=0; i<nums.length; i++){
            while(!s.isEmpty() && nums[i] > nums[s.peek()]){
                int top = s.pop();
                ret[top] = i - top;
            }
            s.push(i);
        }
        return ret;
    }
}

[编程题]滑动窗口的中位数

热度指数:525时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 256M,其他语言512M 算法知识视频讲解
在实时计算中,数据流源源不断地流入计算单元,经常需要借助窗口来处理数据,其中有一类窗口为滑动窗口(Sliding Window),其特点是窗口长度固定,每次滑动一定的位移(slide)

现给定一个数组 nums,有一个长度为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。注意你只可以看到在滑动窗口 k内的数字,滑动位移大小slide=1,即滑动窗口每次只向右移动一位。

要求返回每一个滑动窗口内的中位数,解释中位数定义,例如:对于[2,3,4],中位数是3;对于[2,3],中位数是 (2 + 3) / 2 =
2.5

注意:为了简化窗口计算,规定如果没有累计到窗口大小的数,不能触发计算,即不输出结果!

输入描述: 输入两个数字n,k。n表示数组长度,k表示窗口大小 加下来n个整数用空格隔开,表示nums数组 (1<=k<=n)
(1<=n<=1000)

import java.util.*;
  
public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int n, k;
        int[] nums=new int[1005];
        PriorityQueue<Integer> max = new PriorityQueue<>();
        PriorityQueue<Integer> min = new PriorityQueue<>(Comparator.<Integer>reverseOrder());
        n=scanner.nextInt();
        k=scanner.nextInt();
        for (int i = 0; i < n; i++) {
            nums[i]=scanner.nextInt();
        }
        for(int i=0;i<n;i++){
            if (min.size() == 0) {
                min.add(nums[i]);
            } else if (min.peek() > nums[i]) {
                min.add(nums[i]);
            } else {
                max.add(nums[i]);
            }
            if (i - k >= 0) {
                int delete = nums[i - k];
                if (min.peek() >= delete) {
                    min.remove(delete);
                } else {
                    max.remove(delete);
                }
            }
            while (min.size() > max.size() + 1) {
                max.add(min.poll());
            }
            while (max.size() > min.size()) {
                min.add(max.poll());
            }
            if (i >= k - 1) {
                if(k%2==0){
                    System.out.print((min.peek()+max.peek())/2.0);
                }else {
                    System.out.print(min.peek()/1.0);
                }
  
                if(i!=n-1){
                    System.out.print(" ");
                }
            }
        }
    }
}

你可能感兴趣的:(美团点评2020校招数据分析方向笔试题)