hadoop概述测试题和基础模版代码
1、Hadoop的创始人是DougCutting?()
A、正确
B、错误
答对了!
正确答案:A
解析:
参考课程里的文档,这个就不解释了
2、下列有关Hadoop的说法正确的是()
A、Hadoop最早起源于Nutch
B、Hadoop中HDFS的理念来源于谷歌发表的分布式文件系统(GFS)的论文
C、Hadoop中MapReduce的思想来源于谷歌分布式计算框架MapReduce的论文
D、Hadoop是在分布式服务器集群上存储海量数据并运行分布式分析应用的一个开源的软件框架
答对了!出题老师哭晕在厕所!
正确答案:A,B,C,D
解析:
参考课程里的文档,这个就不解释了
3、为什么要使用Hadoop( )
A、 方便:Hadoop运行在由一般商用机器构成的大型集群上,或者云计算服务上
B、健壮:Hadoop致力于在一般商用硬件上运行,其架构假设硬件会频繁失效,Hadoop可以从容地处理大多数此类故障。
C、可扩展:Hadoop通过增加集群节点,可以线性地扩展以处理更大的数据集。
D、简单:Hadoop允许用户快速编写高效的并行代码。
答对了!棒极了!
正确答案:A,B,C,D
解析:
参考课程里的文档,这个就不解释了
4、Hadoop是云计算中平台即服务(PAAS)中的一种()
A、正确
B、错误
答对了!棒极了!
正确答案:A
解析:
PAAS:平台即服务,典型的实现有Google APPEngine,Apache Hadoop
=====================================
肢解”Hadoop程序基础模板,揭开庐山真面目
分布式编程相对复杂,而Hadoop本身蒙上大数据、云计算等各种面纱,让很多初学者望而却步。可事实上,Hadoop是一个很易用的分布式编程框架,经过良好封装屏蔽了很多分布式环境下的复杂问题,因此,对普通开发者来说很容易,容易到可以照葫芦画瓢。
大多数Hadoop程序的编写可以简单的依赖于一个模板及其变种。当编写一个新的MapReduce程序时,我们通常采用一个现有的MapReduce程序,通过修改达到我们希望的功能就行了。对于写大部分的Hadoop程序来说几乎就是照葫芦画瓢。这个瓢到底是什么样子呢?还是和小讲一起看看吧。
使用 Java 语言编写 MapReduce 非常方便,因为 Hadoop 的 API 提供了 Mapper 和 Reducer 抽象类,对开发人员来说,只需要继承这两个抽象类,然后实现抽象类里面的方法就可以了。
有一份CSV格式专利引用数据供下载,超过1600万行,某几行如下:
"CITING(引用)","CITED(被引用)"
3858241,956203
3858241,1324234
3858241,3398406
3858242,1515701
3858242,3319261
3858242,3707004
3858243,1324234
2858244,1515701
...
对每个专利,我们希望找到引用它的专利并合并,输出如下:
1324234 3858243,3858241
1515701 2858244,3858242
3319261 3858242
3398406 3858241
3707004 3858242
956203 3858241
...
下边的程序就实现了一个这样的功能。很强大的功能,代码就这么少,没想到吧???
下面是一个典型的Hadoop程序模板
package com.dajiangtai.hadoop.junior;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
/**
* Hadoop程序基础模板
*/
public class HadoopTpl extends Configured implements Tool {
public static class MapClass extends Mapper< Text,Text,Text,Text> {
public void map(Text key, Text value, Context context) throws IOException, InterruptedException {
//根据业务需求,将key value调换输出
context.write(value, key);
}
}
public static class ReduceClass extends Reducer< Text, Text, Text, Text> {
public void reduce(Text key, Iterable< Text> values, Context context) throws IOException, InterruptedException {
String csv = "";
//将引入相同专利编号拼接输出
for(Text val:values) {
if(csv.length() > 0)
csv += ",";
csv += val.toString();
}
context.write(key, new Text(csv));
}
}
@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf(); //读取配置文件
//自定义key value 之间的分隔符(默认为tab)
conf.set("mapreduce.input.keyvaluelinerecordreader.key.value.separator", ",");
Job job = new Job(conf, "HadoopTpl");//新建一个任务
job.setJarByClass(HadoopTpl.class);//主类
Path in = new Path(args[0]);//输入路径
Path out = new Path(args[1]);//输出路径
FileSystem hdfs = out.getFileSystem(conf);
if (hdfs.isDirectory(out)) {//如果输出路径存在就删除
hdfs.delete(out, true);
}
FileInputFormat.setInputPaths(job, in);//文件输入
FileOutputFormat.setOutputPath(job, out);//文件输出
job.setMapperClass(MapClass.class);//设置自定义Mapper
job.setReducerClass(ReduceClass.class);//设置自定义Reducer
job.setInputFormatClass(KeyValueTextInputFormat.class);//文件输入格式
job.setOutputFormatClass(TextOutputFormat.class);//文件输出格式
job.setOutputKeyClass(Text.class);//设置作业输出值 Key 的类
job.setOutputValueClass(Text.class);//设置作业输出值 Value 的类
return job.waitForCompletion(true)?0:1;//等待作业完成退出
}
/**
* @param args 输入文件、输出路径,可在Eclipse的Run Configurations中配Arguments如:
* hdfs://dajiangtai:9000/junior/cite75_99.txt
* hdfs://dajiangtai:9000/junior/patent-out/
*/
public static void main(String[] args) {
try {
//程序参数:输入路径、输出路径
String[] args0 = {
"hdfs://dajiangtai:9000/junior/cite75_99.txt",
"hdfs://dajiangtai:9000/junior/patent-out/"}
//本地运行:第三个参数可通过数组传入,程序中设置为args0
//集群运行:第三个参数可通过命令行传入,程序中设置为args
//这里设置为本地运行,参数为args0
int res = ToolRunner.run(new Configuration(), new HadoopTpl(), args0);
System.exit(res);
} catch (Exception e) {
e.printStackTrace();
}
}
}
我们运行MapReduce程序,可以很快捷、方便的统计出我们想要的结果。部分结果如下所示:
2194786 4421318,4900036,4239214,5536003
2194787 3882814
2194790 3934348,4585417,4689013,4846718,4627136,4834656,5314335,5803737
2194793 4869356
2194795 5868349,4512532
2194796 4553721
2194798 4507100,5279522,4929136,5009628,5591084
2194800 5588773,5547319,5435509,4529332,5308029,5320227
2194802 4011952,4682697,4504235
2194804 4327452,5842239
2194805 5620021
2194808 3862802,5280321
2194809 5191893,5238008,5329932,5224490,4183247,4240444,4602643,5730145,5727562,5022402,5099855,5088501
2194810 4441289,3877192
2194811 4320811
2194815 5313704
2194817 5326313,4469381,4831921
2194818 5450058
2194819 4470214
2194822 4471233,4122512,5159261,5376828,5514915,5500561,5501083,5969435,5786642
2194823 4347762,4836053,4037693
2194827 4038086,4011090,5207823
2194828 4815601,4685564,5111936,4930634,4949848,4375856,3858746
2194831 5347439,4541311
可以想像,一份超过1600万的数据,实现这样一个功能,如果我们自己写算法处理,效率和资源耗费很难想像。可使用Hadoop处理起来就是这么简单。是不是很强大?加紧学习吧,少年!
备注:这里我通过一个真实的例子,让先大家感受一下Hadoop处理数据的便捷与强大, 先不用着急动手去开发MapReduce程序,大家把后续课程中的Hadoop集群环境和Eclipse环境搭建起来后,回过头来再让这个程序飞起来!
=============================================
Hadoop。 据小讲了解,按目前的市场状况,Hadoop入门薪资已经达到了8K以上,工作1年可达到1.2W以上,具有2-3年工作经验的hadoop优秀人才年薪可以达到30万—50万。
下面是一份小讲的同事从招聘网站上收集的Hadoop工程师薪资状况的数据。基于这份数据,我们用Hadoop程序统计一下各工作经验段的Hadoop工程师薪资上下限。同学们可以对照前面讲的Hadoop程序基础模板比对一下,强化一下对模板的认识,代码看不懂也没关系。学习完随后的任务后,你就会发现这些很Easy!
PS.看到下边同事们收集的薪资数据,小讲是醉了...
数据集下载(全部是来源于招聘网站的真实数据):
美团 3-5年经验 15-30k 北京 【够牛就来】hadoop高级工程...
北信源 3-5年经验 15-20k 北京 Java高级工程师(有Hadoo...
蘑菇街 3-5年经验 10-24k 杭州 hadoop开发工程师
晶赞科技 1-3年经验 10-30k 上海 hadoop研发工程师
秒针系统 3-5年经验 10-20k 北京 hadoop开发工程师
搜狐 1-3年经验 18-23k 北京 大数据平台开发工程师(Hadoo...
执御 1-3年经验 8-14k 杭州 hadoop工程师
KK唱响 3-5年经验 15-30k 杭州 高级hadoop开发工程师
晶赞科技 1-3年经验 12-30k 上海 高级数据分析师(hadoop)
亿玛在线(北京)科技有限公司 3-5年经验 18-30k 北京 hadoop工程师
酷讯 1-3年经验 10-20k 北京 hadoop Engineer/...
游族网络 5-10年经验 20-35k 上海 hadoop研发工程师
易车公司 3-5年经验 15-30k 北京 hadoop工程师
爱图购 1-3年经验 8-15k 杭州 hadoop开发工程师
晶赞科技 3-5年经验 15-33k 上海 hadoop研发工程师
程序:
package com.dajiangtai.hadoop.junior;
import java.io.IOException;
import java.util.regex.Pattern;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
/**
* 基于样本数据做Hadoop工程师薪资统计:计算各工作年限段的薪水范围
*/
public class SalaryCount extends Configured implements Tool {
//自定义Mapper,解析薪资数据
public static class SalaryMapper extends Mapper< Object, Text, Text, Text> {
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
//每行数据格式:美团 3-5年经验 15-30k 北京 hadoop高级工程
String[] record = value.toString().split( "\s+");
//输出(key:3-5年经验 value:15-30k)
context.write( new Text(record[1]), new Text(record[2]) );
}
}
//自定义Reducer,统计薪资范围
public static class SalaryReducer extends Reducer< Text, Text, Text, Text> {
public void reduce(Text Key, Iterable< Text> Values, Context context) throws IOException, InterruptedException {
int low = 0;//记录最低工资
int high = 0;//记录最高工资
int count = 1;
//统计特定工作经验的薪资范围
for (Text value : Values) {
String[] arr = value.toString().split("-");
int l = filterSalary(arr[0]);
int h = filterSalary(arr[1]);
if(count==1 || l< low){
low = l;
}
if(count==1 || h>high){
high = h;
}
count++;
}
context.write(Key, new Text(low + "-" +high + "k"));
}
}
/**
* @ param salary 薪资字符串
* @ function 使用正则表达式,解析出最低工资 low 和 最高工资 high
*/
public static int filterSalary(String salary) {
String sal = Pattern.compile("[^0-9]").matcher(salary).replaceAll("");
return Integer.parseInt(sal);
}
@Override
public int run(String[] args) throws Exception {
Configuration conf = new Configuration();//读取配置文件
Job job = new Job(conf, "SalaryCount" );//新建一个任务
job.setJarByClass(SalaryCount.class);// 主类
Path in = new Path(args[0]);//输入路径
Path out = new Path(args[1]);//输出路径
FileSystem hdfs = out.getFileSystem(conf);
//如果输出文件路径存在,先删除
if (hdfs.isDirectory(out)) {
hdfs.delete(out, true);
}
FileInputFormat.addInputPath(job, in);// 输入路径
FileOutputFormat.setOutputPath(job, out);// 输出路径
job.setMapperClass(SalaryMapper.class);// 设置自定义Mapper
job.setMapOutputKeyClass(Text.class);// Mapper key输出类型
job.setMapOutputValueClass(Text.class);// Mapper value输出类型
job.setReducerClass(SalaryReducer.class);// 设置自定义Reducer
return job.waitForCompletion(true)?0:1;//等待作业完成退出
}
/**
* @param args 输入文件、输出路径,可在Eclipse中Run Configurations中配Arguments,如:
* hdfs://dajiangtai:9000/junior/salary.txt
* hdfs://dajiangtai:9000/junior/salary-out/
*/
public static void main(String[] args) throws Exception {
try {
//程序参数:输入路径、输出路径
String[] args0 = {
"hdfs://dajiangtai:9000/junior/salary.txt",
"hdfs://dajiangtai:9000/junior/salary-out/"};
//本地运行:第三个参数可通过数组传入,程序中设置为args0
//集群运行:第三个参数可通过命令行传入,程序中设置为args
//这里设置为本地运行,参数为args0
int res = ToolRunner.run(new Configuration(), new SalaryCount(), args0) ;
System.exit(res);
} catch (Exception e) {
e.printStackTrace();
}
}
}
统计结果:
1-3年经验 8-30k
3-5年经验 10-33k
5-10年经验 20-35k
结果显示,上面这份数据集中Hadoop工程师的薪资状况如下:1-3年工作经验8-30k,3-5年工作经验10-33k,5-10年经验20-35k。是不是很振奋人心??是,不过眼前还是和小讲一起踏踏实实练好基本功吧。
备注:这里我通过一个真实的例子,让先大家感受一下Hadoop处理数据的便捷与强大, 先不用着急动手去开发MapReduce程序,大家把后续课程中的Hadoop集群环境和Eclipse环境搭建起来后,回过头来再让这个程序飞起来!