面试官居然让我手写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写,你会吗?
#数据人的面试交流地##大数据开发面经##牛客在线求职答疑中心##牛客解忧铺#
查看6道真题和解析