360SDN.COM

首页/Hadoop/列表

hadoop面试题总结2

来源:  2016-04-23 18:54:26    评论:0点击:

1 使用Hive或者自定义MR实现如下逻辑
product_no      lac_id  moment  start_time      user_id county_id       staytime        city_id
13429100031     22554   8       2013-03-11 08:55:19.151754088   571     571     282     571
13429100082     22540   8       2013-03-11 08:58:20.152622488   571     571     270     571
13429100082     22691   8       2013-03-11 08:56:37.149593624   571     571     103     571
13429100087     22705   8       2013-03-11 08:56:51.139539816   571     571     220     571
13429100087     22540   8       2013-03-11 08:55:45.150276800   571     571     66      571
13429100082     22540   8       2013-03-11 08:55:38.140225200   571     571     133     571
13429100140     26642   9       2013-03-11 09:02:19.151754088   571     571     18      571
13429100082     22691   8       2013-03-11 08:57:32.151754088   571     571     287     571
13429100189     22558   8       2013-03-11 08:56:24.139539816   571     571     48      571
13429100349     22503   8       2013-03-11 08:54:30.152622440   571     571     211     571
字段解释:
product_no:用户手机号;
lac_id:用户所在基站;
start_time:用户在此基站的开始时间;
staytime:用户在此基站的逗留时间。

需求描述:
根据lac_id和start_time知道用户当时的位置,根据staytime知道用户各个基站的逗留时长。根据轨迹合并连续基站的staytime。
最终得到每一个用户按时间排序在每一个基站驻留时长

期望输出举例:
13429100082     22540   8       2013-03-11 08:58:20.152622488   571     571     270     571
13429100082     22691   8       2013-03-11 08:56:37.149593624   571     571     390     571
13429100082     22540   8       2013-03-11 08:55:38.140225200   571     571     133     571
13429100087     22705   8       2013-03-11 08:56:51.139539816   571     571     220     571
13429100087     22540   8       2013-03-11 08:55:45.150276800   571     571     66      571

2 Linux脚本能力考察
2.1 请随意使用各种类型的脚本语言实现:批量将指定目录下的所有文件中的$HADOOP_HOME$替换成/home/ocetl/app/hadoop

2.2 假设有10台主机,H1到H10,在开启SSH互信的情况下,编写一个或多个脚本实现在所有的远程主机上执行脚本的功能
例如:runRemoteCmd.sh "ls -l"
期望结果:
H1:
XXXXXXXX
XXXXXXXX
XXXXXXXX
H2:
XXXXXXXX
XXXXXXXX
XXXXXXXX
H3:
...



3 Hadoop基础知识与问题分析的能力
3.1 描述一下hadoop中,有哪些地方使用了缓存机制,作用分别是什么

3.2 请描述https://issues.apache.org/jira/browse/HDFS-2379说的是什么问题,最终解决的思路是什么?


4 MapReduce开发能力
请参照wordcount实现一个自己的map reduce,需求为:
   a 输入文件格式:
      xxx,xxx,xxx,xxx,xxx,xxx,xxx
   b 输出文件格式:
      xxx,20
      xxx,30
      xxx.40
   c 功能:根据命令行参数统计输入文件中指定关键字出现的次数,并展示出来
      例如:hadoop jar xxxxx.jar keywordcount xxx,xxx,xxx,xxx(四个关键字)

5 MapReduce优化
请根据第五题中的程序, 提出如何优化MR程序运行速度的思路

6 Linux操作系统知识考察
请列举曾经修改过的/etc下的配置文件,并说明修改要解决的问题?


7 Java开发能力
7.1 写代码实现1G大小的文本文件,行分隔符为\x01\x02,统计一下该文件中的总行数,要求注意边界情况的处理

7.2 请描述一下在开发中如何对上面的程序进行性能分析,对性能进行优化的过程
 
答案如下:
1. 考虑后,决定使用 MR 来实现,于是使用Java,用一个MR Job完成这个事情:
  1. package org.aboutyun;
  2.  
  3. import org.apache.commons.lang.StringUtils;
  4. import org.apache.hadoop.conf.Configuration;
  5. import org.apache.hadoop.fs.Path;
  6. import org.apache.hadoop.io.LongWritable;
  7. import org.apache.hadoop.io.Text;
  8. import org.apache.hadoop.mapreduce.Job;
  9. import org.apache.hadoop.mapreduce.Mapper;
  10. import org.apache.hadoop.mapreduce.Reducer;
  11. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  12. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
  13. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  14. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  15.  
  16. import java.io.IOException;
  17. import java.text.ParseException;
  18. import java.text.SimpleDateFormat;
  19. import java.util.ArrayList;
  20. import java.util.Collections;
  21. import java.util.Comparator;
  22.  
  23. public class TimeCount {
  24.     public static void main(String[] args) throws Exception {
  25.         Configuration conf = new Configuration();
  26.  
  27.         Job job = new Job(conf, "time_count");
  28.  
  29.         job.setOutputKeyClass(Text.class);
  30.         job.setOutputValueClass(Text.class);
  31.  
  32.         job.setMapperClass(Map.class);
  33.         job.setReducerClass(Reduce.class);
  34.  
  35.         job.setInputFormatClass(TextInputFormat.class);
  36.         job.setOutputFormatClass(TextOutputFormat.class);
  37.  
  38.         FileInputFormat.addInputPath(job, new Path(args[0]));
  39.         FileOutputFormat.setOutputPath(job, new Path(args[1]));
  40.  
  41.         job.waitForCompletion(true);
  42.     }
  43.  
  44.     public static class Map extends Mapper<LongWritable, Text, Text, Text> {
  45.         private Text id = new Text();
  46.         private Text row = new Text();
  47.  
  48.         public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  49.             String line = value.toString();
  50.             String[] items = line.split("\t");
  51.  
  52.             if (items.length == 8) {
  53.                 if (StringUtils.isNumeric(items[6])) {
  54.                     id.set(items[0] + "\t" + items[1]);
  55.                     row.set(line);
  56.                     context.write(id, row);
  57.                 }
  58.             } else {
  59.                 System.out.println("Wrong length: " + items.length);
  60.             }
  61.         }
  62.     }
  63.  
  64.     public static class Reduce extends Reducer<Text, Text, Text, Text> {
  65.         private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  66.  
  67.         static {
  68.             format.setLenient(false);
  69.         }
  70.  
  71.         private Text rest = new Text();
  72.  
  73.         public void reduce(Text key, Iterable<Text> values, Context context)
  74.                 throws IOException, InterruptedException {
  75.             //  Parse row to Record
  76.             ArrayList<Record> list = new ArrayList<Record>();
  77.             for (Text row : values) {
  78.                 String[] items = row.toString().split("\t");
  79.                 try {
  80.                     Record record = new Record();
  81.                     record.items = items;
  82.                     record.start_time = format.parse(items[3]).getTime();
  83.                     record.stay_time = Long.parseLong(items[6]) * 1000;
  84.                     list.add(record);
  85.                 } catch (ParseException e) {
  86.                     e.printStackTrace();
  87.                 }
  88.  
  89.             }
  90.  
  91.             //  Sort
  92.             Collections.sort(list, new Comparator<Record>() {
  93.                 @Override
  94.                 public int compare(Record r1, Record r2) {
  95.                     return (int) (r1.start_time - r2.start_time);
  96.                 }
  97.             });
  98.  
  99.             //  Find and merge slice
  100.             ArrayList<Record> result = new ArrayList<Record>();
  101.             for (Record r1 : list) {
  102.                 boolean found = false;
  103.                 long r1_stop_time = r1.start_time + r1.stay_time;
  104.                 for (Record r2 : result) {
  105.                     long r2_stop_time = r2.start_time + r2.stay_time;
  106.                     if (r1.start_time > r2.start_time && r1.start_time <= r2_stop_time && r1_stop_time > r2_stop_time) {
  107.                         //  merge the new slice
  108.                         r2.stay_time = r1_stop_time - r2.start_time;
  109.                         found = true;
  110.                     }
  111.                 }
  112.  
  113.                 if (!found) {
  114.                     result.add(r1);
  115.                 }
  116.             }
  117.  
  118.             //  Output
  119.             for (Record r : result) {
  120.                 key.set(r.items[0]);
  121.  
  122.                 String value = r.items[1] + "\t"
  123.                         + r.items[2] + "\t"
  124.                         + r.items[3] + "\t"
  125.                         + r.items[4] + "\t"
  126.                         + r.items[5] + "\t"
  127.                         + (r.stay_time / 1000) + "\t"
  128.                         + r.items[6] + "\t";
  129.                 rest.set(value);
  130.  
  131.                 context.write(key, rest);
  132.             }
  133.  
  134.         }
  135.  
  136.         static class Record {
  137.             String[] items;
  138.             long start_time;
  139.             long stay_time;
  140.         }
  141.     }
  142. }
复制代码
2.

2.1 使用 find + sed 来实现:
find /home/ocetl/app/hadoop -exec sed -i 's/\$HADOOP_HOME\$/\/home\/ocetl\/app\/hadoop/g' {} \;
2.2 直接使用ssh的参数
  1. #!/bin/bash
  2. if [ $# -ne 1 ]
  3. then
  4.         echo "Usage: `basename $0` {command}"
  5.         exit
  6. fi
  7.  
  8. for i in H1 H2 H3 H4 H5 H6 H7 H8 H9 H10
  9. do
  10.         echo "$i:"
  11.         ssh $i "$1"
  12. done
复制代码
3.
3.1 不了解,HDFS用了缓存
3.2 问题是当硬盘空间很大,而内存页面缓存很少的时候,DN的Block report需要很长时间生成,而此时 FSVolumeSet 锁是锁住的,因此所有读写操作都无法执行,最终导致那些操作超时。此问题是建议提供一种方法使block report不需要持有FSVolumeSet锁,从而不会导致那些任务失败。

4. 只是替换分隔符从空格到逗号,以及增加搜索关键字列表:
  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.fs.Path;
  3. import org.apache.hadoop.io.IntWritable;
  4. import org.apache.hadoop.io.LongWritable;
  5. import org.apache.hadoop.io.Text;
  6. import org.apache.hadoop.mapreduce.Job;
  7. import org.apache.hadoop.mapreduce.Mapper;
  8. import org.apache.hadoop.mapreduce.Reducer;
  9. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  10. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
  11. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  12. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  13.  
  14. import java.io.IOException;
  15. import java.util.ArrayList;
  16.  
  17. public class WordCount {
  18.  
  19.     public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
  20.         private final static IntWritable one = new IntWritable(1);
  21.         private Text word = new Text();
  22.         private final static ArrayList<String> target_words = new ArrayList<String>();
  23.  
  24.         public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  25.             String[] items = value.toString().toLowerCase().replaceAll("\\p{Punct}", "").split("\\s+");
  26.             for (String item : items) {
  27.                 if (target_words.contains(item)) {
  28.                     word.set(item);
  29.                     context.write(word, one);
  30.                 }
  31.             }
  32.         }
  33.  
  34.         public static void clear() {
  35.             target_words.clear();
  36.         }
  37.  
  38.         public static void add(String word) {
  39.             target_words.add(word);
  40.         }
  41.     }
  42.  
  43.     public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
  44.  
  45.         public void reduce(Text key, Iterable<IntWritable> values, Context context)
  46.                 throws IOException, InterruptedException {
  47.             int sum = 0;
  48.             for (IntWritable val : values) {
  49.                 sum += val.get();
  50.             }
  51.             context.write(key, new IntWritable(sum));
  52.         }
  53.     }
  54.  
  55.     public static void main(String[] args) throws Exception {
  56.         Configuration conf = new Configuration();
  57.  
  58.         if (args.length < 3) {
  59.             System.out.println("Usage: wordcount <input_path> <output_path> <keyword_list>");
  60.             return;
  61.         }
  62.  
  63.         //  Add to target
  64.         String[] target_words = args[2].split(",");
  65.         for (String word : target_words) {
  66.             Map.add(word.toLowerCase());
  67.         }
  68.  
  69.         Job job = new Job(conf, "wordcount");
  70.  
  71.         job.setOutputKeyClass(Text.class);
  72.         job.setOutputValueClass(IntWritable.class);
  73.  
  74.         job.setMapperClass(Map.class);
  75.         job.setReducerClass(Reduce.class);
  76.  
  77.         job.setInputFormatClass(TextInputFormat.class);
  78.         job.setOutputFormatClass(TextOutputFormat.class);
  79.  
  80.         FileInputFormat.addInputPath(job, new Path(args[0]));
  81.         FileOutputFormat.setOutputPath(job, new Path(args[1]));
  82.  
  83.         job.waitForCompletion(true);
  84.     }
  85.  
  86. }
复制代码
5. 第五题的程序是什么?

6.
        hosts:增加局域网主机名和ip对应关系,省得再记住ip;
        hostname:该主机名,克隆虚拟机的时候经常需要这么做;
        fstab:修改挂载点,加新硬盘的时候会需要;
        profile, bash.bashrc: 修改系统范围环境变量时经常用;
        network/interfaces:配置静态IP时需要。

7
7.1
  1. package org.aboutyun;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileReader;
  6. import java.io.IOException;
  7.  
  8. public class LineCounter {
  9.     public static void main(String[] args) {
  10.         try {
  11.             BufferedReader reader = new BufferedReader(new FileReader(args[0]));
  12.             char[] buffer = new char[4096];
  13.             int count;
  14.             char last = 0;
  15.             long line_count = 0;
  16.             while((count = reader.read(buffer)) >= 0) {
  17.                 if (count > 0 && line_count == 0) {
  18.                     //  has something in file, so at least 1 line.
  19.                     line_count = 1;
  20.                 }
  21.  
  22.                 for (int i = 0; i < count ; ++i) {
  23.                     char c = buffer[i];
  24.                     if (c == 0x02) {
  25.                         if (i == 0 && last == 0x01) {
  26.                             //  buffer split the 0x01,0x02
  27.                             ++line_count;
  28.                         } else if (buffer[i-1] == 0x01) {
  29.                             //  normal one
  30.                             ++line_count;
  31.                         }
  32.                     }
  33.                 }
  34.  
  35.                 //  keep the last one
  36.                 last = buffer[count-1];
  37.             }
  38.  
  39.             System.out.println(line_count);
  40.         } catch (FileNotFoundException e) {
  41.             e.printStackTrace();
  42.         } catch (IOException e) {
  43.             e.printStackTrace();
  44.         }
  45.     }
  46. }
复制代码
7.2 可以使用Profiler来对性能进行评估分析,比如Eclipse的TPTP,或者JProfiler。可以观察不同函数调用次数和以及占用时间,从而减少调用次数,以及优化函数内部。
 
为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权