面试技巧

关注公众号 jb51net

关闭
IT专业知识 > IT职场规划 > 面试技巧 >

BAT面试中的大数据相关问题笔记

HenryTien

大数据

Map-Reduce 和Hadoop 逐渐成为面试热门
1. 介绍哈希函数

哈希函数又叫散列函数
1.1  典型的哈希函数都有无限的输入值域。
1.2 输入值相同时,返回值一样。
1.3 输入值不同时,返回值可能一样,也可能不一样
1.4 不同输入值得到的哈希值,整体均分的分布在输出域S上(重要)

1~3 点性质是哈希函数的基础,第4点是评价一个哈希函数优劣的关键。
aaa1 aaa2 aaa3 虽然相似,但哈希值差异巨大。

2.介绍Map-Rdeduce

2.1  Map阶段  把大任务分成子任务
2.2 Reduce阶段  子任务并发处理,然后合并结果。

难点:工程上的处理

注意点:

1. 备份的考虑,分布式存储的设计细节,以及容灾策略。
2. 任务分配策略与任务进度跟踪的细节设计,节点状态的呈现
3. 多用户权限的控制

map-reduce 方法统计文章的单词

文章-> 预处理

1.去掉标点符号  
2.连字符
3.对于缩写的处理
4.大小写的处理

对每个单词生成词频为1

哈希函数

子任务进行处理

海量数量处理技巧

  1. 分而自治,通过哈希函数将大任务分流到机器或分流秤小文件
  2. 常用hashMap 或bitamp

难点:通讯、时间和空间的估算。

每个位置上是一个bit,只能表示0和1两种状态。
长度为2^32的bit数组,空间约为128m.

hashmap记录所有出现的次数

key->具体某一种数
value-> 这种数出现的次数

内存可能超出

文件分流

在40亿个无符号整数的文件,所以在整个范围中必然没有出现过的数,可以使用最多10M的内存,只用找到一个没有出现过的数即可,该如何找?

hash 表 40亿条 每一条4个字节 16G

bitmap 500M

64个区间
500M/64 8M
1、根据内存限制决定区间大小,根据区间大小,得到有多少个变量,来记录每个区间的数出现的次数。
2、 统计区间上的数的出现次数,找到不足的区间。
3、利用bitmap对不满足的区间,进行这个区间上的数的词频统计。

百亿数据中,找到100个热词

分流 确定机器数

对每一个机器,进行文件分流,小根堆 确定top100

工程师使用服务器集群来设计和是吸纳数据缓存,以下是常见的侧脸。

  1. 无论是添加、查询还是删除数据,都先将数据的id通过哈希函数转换成一个哈希值,记为key.

2.如果目前机器有N台,则计算key%N的值,这个值就是该数据所属的机器编号,无论是添加、删除还是查询操作,都只在这台机器上进行。请分析这种缓存策略可能带来的问题。并提出改进的方案。

如果增加或删除机器,数据迁移的代价很大。

一致性哈希算法

数据id—> 0~ 2 ^32
key 和data 相邻存储
顺时针进行

动态规划

给定数组arr,arr中所有的值杜伟整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim代表要找的钱数,求换钱有多少种方法.

暴力搜索方法

记忆搜索方法

动态规划方法

状态继续优化

arr={5,10,25,1} aim={1000}

public int coins1(int[] arr,int aim){
    if(arr==null||arr.length==0||aim<0)
    {
        return 0;
    }

    return process1(arr,0,aim);
}

public int process1(int [] arr,int index,int aim){
    int res=0;
    if(index==arr.length){
        res=aim==0?1:0;
    }else{
         for(int i=0;arr[index]*i<=aim;i++){
            res+=process1(arr,index+1,aim-arr[index]*i);    
             }
         }
}

如果已经使用0张5元和1张10元的情况下
后续将求:p1(arr,2,990)
这里2表示arr剩下的钱为arr[2,3] 即为[25,1]
990:表示要找的剩余钱数。

2张5元0张10元p1(arr,2,990)

public int coins2(int[] arr,int aim){
    if(arr==null||arr.length==0||aim<0){
    return 0;
    }
    int[][] map=new int[arr.length+1][aim+1];
        return process2(arr,0,aim,map);
}

public int process2(int[] arr,int index,int aim,int[][] map){
    int res=0;
    if(index==arr.length){
        res=aim==0?1:0;
    }else{
        int mapValue=0;
        for(int i=0;arr[index]*i<=aim;i++){
            mapValue=mapValue==-1?0:mapValue;
            }else{
                res+=process2(arr,index+1,aim-arr[index]*i,map);
            }
        }
    }
    map[index][aim]=res==0?-1:res;
    return res;
}

什么是动态规划方法

  1. 其本质是利用空间来记录每一个暴力搜索的计算结果的时候直接使用,从而不再是用重复计算。

  2. 动态规划由于规定了每一种递归的计算顺序,依次进行计算。

面试中遇到暴力递归题目可以优化成动态规划方法的大体过程:

  1. 实现暴力递归方法。
  2. 在暴力搜索方法的函数中看看那些参数可以代表递归过程。
  3. 找到代表递归过程的参数之后,记忆话搜索方法非常容易实现。
  4. 通过分析记忆话搜索的依赖路径,进而实现动态规划。
  5. 根据记忆化搜索方法改出动态规划,减少时间复杂度。

动态规划的关键点:

  1. 最优化原理,也就是最优子结构性质。这指的是一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的的状态而言,余下的诸多决策必须构成最优决策,简单来说就是一个最优化的策略的子策略总是最优的,如果一个问题满足最优化原理,就称其具有最优子结构性质。

  2. 无后效性。指的是某状态下决策的收益,只与状态和决策相关,与到达该状态的方式无关。

  3. 子问题的重叠性,动态规划将原来具有指数级时间复杂度的暴力搜索算法改进成了具有多项式时间复杂度的算法。其中的关键在于解决冗余,这是动态规划算法的根本目的。

经典动态规划的问题

public int s1(int n){
    if(n<1)
    return 0;

}
    if(n==1||n==2){
    return n;
    }
    return s1(n-1)+s1(n-2);
}

待补: