面试官居然让我手写MapReduce代码

需求描述

  • 以下是微博好友列表数据,冒号前是一个用户,冒号后是该用户的所有好友(其中好友关系是单向的)
  • 求出哪些人两两之间有共同好友,及他俩的共同好友都有谁?
输入:
A: B,C,D
B: A,C,D
C: A,B,D
D: A
输出:
A-B C
A-C B,D
B-C A
B-D A
C-D A

思路

第一步:求出具有共同好友的用户

Map

第一行数据转换为:<B,A> <C,A> <D,A>

第二行数据转换为:<A,B> <C,B> <D,B>

第三行数据转换为:<A,C> <B,C> <D,C>

第四行数据转换为:<A,D>

Reduce

Map之后的数据转换为:<A-,B> <A-B-,C> <A-B-C-,D> <B-C-D-,A> <C-,B>

第二步:遍历两两之间的好友

Map

<A-B,C> <A-B,D> <A-C,D> <B-C,D> <B-C,A> <B-D,A> <C-D,A>

Reduce

<A-B,C-D> <A-C,D> <B-C,A-D> <B-D,A> <C-D,A>

答案

  • 第一步
// map
public class Step1Mapper extends Mapper<LongWritable,Text,Text,Text> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // 1.以冒号拆分行文本数据:冒号左边作为value
        String[] fields= value.toString().split(":");
        String userStr = fields[0];
        // 2.将冒号右边的字符串以逗号拆分,每个成员就是key
        String[] split1 = fields[1].split(",");
        for (String s : split1) {
            // 3:将key和value写入上下文中
            context.write(new Text(s), new Text(userStr));
        }
    }
}
// reduce
public class Step1Reducer extends Reducer<Text,Text,Text,Text> {
    @Override
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
        // 1.遍历集合,并将每一个元素拼接作为key
        StringBuffer buffer = new StringBuffer();
        for (Text value : values) {
            buffer.append(value.toString()).append("-");
        }
        // 2.原始key作为value,将key和value写入上下文中
        context.write(new Text(buffer.toString()), key);
    }
}
  • 第二步
// map
public class Step2Mapper extends Mapper<LongWritable,Text,Text,Text> {
    /*
    输入
    A-B-C- D
    ----------------------------------
    输出
    A-B D
    A-C D
    B-C D
    */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // 1.拆分行文本数据,结果的第二部分作为value
        String[] split = value.toString().split("\t");
        String friendStr =split[1];
        // 2.以'-'为分隔符拆分行文本数据第一部分
        String[] userArray = split[0].split("-");
        // 3.对数组做一个排序
        Arrays.sort(userArray);
        // 4.对数组中的元素进行两两组合,得到key
        for (int i = 0; i < userArray.length - 1; i++) {
            for (int j = i + 1; j < userArray.length; j++) {
                // 5.将key和value写入上下文中
                context.write(new Text(userArray[i] + "-" + userArray[j]), new Text(friendStr));
            }
        }
    }
}
// reduce
public class Step2Reducer extends Reducer<Text,Text,Text,Text> {
    @Override
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
        // 1.将集合进行遍历,将集合中的元素拼接,得到value
        StringBuffer buffer = new StringBuffer();
        for (Text value : values) {
            buffer.append(value.toString()).append("-");
        }
        // 2.将key和value写入上下文中
        context.write(key, new Text(buffer.toString()));
    }
}

思考

如果面试官让你用sql写,你会吗?

#数据人的面试交流地##大数据开发面经##牛客在线求职答疑中心##牛客解忧铺#
全部评论
这么简单,你给他说,我要手写jdk
1 回复 分享
发布于 2023-06-08 12:46 北京
手搓mr就算了,这题用sql写都是难题好吧!
1 回复 分享
发布于 2023-06-11 19:06 安徽
如果面试官让我用SQL写,我会尝试用SQL语句实现该需求。但是需要注意的是,SQL语句对于大数据处理可能不太适合,因为SQL是基于关系型数据库的,而在大数据处理中,通常使用的是分布式计算框架,如Hadoop、Spark等。因此,在实际应用中,需要根据具体情况选择合适的工具和技术来处理数据。
点赞 回复 分享
发布于 2023-06-07 14:42 AI生成
什么面试啊
点赞 回复 分享
发布于 2023-06-07 18:45 广东
有点像pagerank
点赞 回复 分享
发布于 2023-06-12 08:43 北京
炸裂这一步想必大家都会把,我就省去了。。 WITH t AS ( SELECT 'A' AS fr,'B' as too UNION ALL SELECT 'A' ,'C' UNION ALL SELECT 'A' ,'E' UNION ALL SELECT 'B' ,'A' UNION ALL SELECT 'B' ,'F' UNION ALL SELECT 'B' ,'E' UNION ALL SELECT 'C' ,'E' UNION ALL SELECT 'C' ,'F' UNION ALL SELECT 'C' ,'A' ) select concat(t1.fr,'-',t2.fr) as who_and_who,collect_set(t1.too) as comment_love from ( select fr, too, cn from ( select fr, too, count(fr) over (partition by too) as cn from t ) temp where cn > 1 ) t1 join ( select fr, too, cn from ( select fr, too, count(fr) over (partition by too) as cn from t ) temp where cn > 1 ) t2 on t1.fr
点赞 回复 分享
发布于 2023-09-03 11:19 北京
自己写炸裂吧 格式化:
点赞 回复 分享
发布于 2023-09-03 11:21 北京

相关推荐

ArisRobert:统一解释一下,第4点的意思是,公司按需通知员工,没被通知到的员工是没法去上班的,所以只要没被通知到,就自动离职。就是一种比较抽象的裁员。
点赞 评论 收藏
分享
4 26 评论
分享
牛客网
牛客企业服务