前哨站/实操练习手册
实操练习手册

实操练习手册

24 道题按章节递进:从集群命令到 MapReduce、Hive、HBase、Spark。先自己做,再点开答案。

怎么练① 打开你的集群;② 从第 1 题开始逐条敲;③ 卡住先看"解题思路",再点参考答案;④ 命令类题目重点记"为什么要这么写"。

HDFS 命令(第4章)

01

在 HDFS 上创建 /data/input 目录,并把本地文件 w.txt 上传进去。

提示:hdfs dfs -mkdir -p / -put

解题思路目录要递归创建用 -p;put 是本地→HDFS。
查看参考答案
SHELL
hdfs dfs -mkdir -p /data/input
hdfs dfs -put w.txt /data/input/
hdfs dfs -ls /data/input
02

查看 /data/input/w.txt 的文件大小与块信息,并检查是否有损坏副本。

提示:-du -h 与 fsck

解题思路fsck 是 HDFS 的文件系统检查工具,-files -blocks 能看到块分布。
查看参考答案
SHELL
hdfs dfs -du -h /data/input/w.txt
hdfs fsck /data/input/w.txt -files -blocks -locations
03

把 HDFS 上该文件下载到本地 /home/hadoop/,并递归删除 HDFS 目录 /data/input。

提示:-get / -rm -r

解题思路get 等价 copyToLocal;删除目录必须加 -r。
查看参考答案
SHELL
hdfs dfs -get /data/input/w.txt /home/hadoop/
hdfs dfs -rm -r /data/input
04

把某文件的副本数改为 2,并说明为什么不能设成超过 DataNode 数量。

提示:-setrep

解题思路副本数大于节点数时,HDFS 只能复制到现有节点数量上限。
查看参考答案
SHELL
hdfs dfs -setrep -w 2 /data/w.txt
# 只有 3 个 DataNode 时设 5 是无效的,实际副本数最多为 3
05

设置某目录 3 小时后进回收站、7 天后自动清空,并立即清空回收站。

提示:fs.trash.interval / -expunge

解题思路回收站是"删除文件暂存",可防止误删。
查看参考答案
SHELL
# core-site.xml
<property><name>fs.trash.interval</name><value>180</value></property>
<property><name>fs.trash.checkpoint.interval</name><value>10080</value></property>
# 清空
hdfs dfs -expunge

MapReduce(第6章)

06

写出 WordCount 的 Mapper 核心代码(拆分单词并输出 (word,1))。

提示:Mapper<LongWritable,Text,Text,IntWritable>

解题思路每行 value.toString().split 后逐词 context.write。
查看参考答案
JAVA
public class WcMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    private Text k = new Text();
    private IntWritable v = new IntWritable(1);
    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {
        for (String w : value.toString().split("\\s+")) {
            if (w.isEmpty()) continue;
            k.set(w);
            context.write(k, v);
        }
    }
}
07

为什么要给 WordCount 加 Combiner?加它有什么前提条件?

提示:减少 Shuffle 数据量

解题思路Combiner 在 Map 端先聚合;要求运算满足结合律与交换律。
查看参考答案
SHELL
# 加 Combiner
job.setCombinerClass(WcReducer.class);

# 前提:运算必须满足结合律/交换律
# 求和可以;求平均值不行(先各自平均再平均 ≠ 整体平均)
08

把 Reduce 个数设置为 4,并说明输出目录会变成什么。

提示:job.setNumReduceTasks

解题思路一个 Reduce 对应一个输出文件。
查看参考答案
SHELL
job.setNumReduceTasks(4);
# 输出目录会出现 part-r-00000 ~ part-r-00003 四个文件
09

作业报 "Output directory already exists",如何解决?

提示:删除输出目录

解题思路MapReduce 不允许覆盖已存在的输出目录。
查看参考答案
SHELL
hdfs dfs -rm -r /wc/output
hadoop jar wc.jar com.demo.WcDriver /wc/input /wc/output

Hive(第7章)

10

建一张学生表(学号/姓名/性别),逗号分隔、ORC 存储,并查看结构。

提示:ROW FORMAT DELIMITED FIELDS TERMINATED BY

解题思路建表三段式:字段 → 分隔符 → 存储格式。
查看参考答案
SHELL
CREATE TABLE IF NOT EXISTS student_info(
  stu_id   STRING COMMENT '学号',
  stu_name STRING COMMENT '姓名',
  sex      STRING COMMENT '性别'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS ORC;

DESC FORMATTED student_info;
11

统计每门课程的平均分(保留两位小数),只显示平均分高于 60 的课程。

提示:GROUP BY + HAVING

解题思路AVG 聚合后用 HAVING 过滤分组结果。
查看参考答案
SHELL
SELECT course_id,
       count(*) AS cnt,
       round(avg(score), 2) AS avg_score
FROM score_info
GROUP BY course_id
HAVING avg(score) > 60
ORDER BY avg_score DESC;
12

用窗口函数取出每门课程成绩前 3 名的学生。

提示:rank() OVER (PARTITION BY … ORDER BY …)

解题思路窗口函数放子查询,外层筛 rk<=3。
查看参考答案
SHELL
SELECT * FROM (
  SELECT course_id, stu_id, score,
         rank() OVER (PARTITION BY course_id ORDER BY score DESC) AS rk
  FROM score_info
) t WHERE rk <= 3 ORDER BY course_id, rk;
13

写一个 UDF:把输入字符串转小写并拼接后缀 "_hive",并说明注册方式。

提示:继承 UDF,写 evaluate

解题思路UDF 一行进一行出;注册用临时函数。
查看参考答案
JAVA
public class MyLowerUDF extends UDF {
    public Text evaluate(Text input) {
        if (input == null) return null;
        return new Text(input.toString().toLowerCase() + "_hive");
    }
}

-- 注册
ADD JAR /user/hadoop/jars/myudf.jar;
CREATE TEMPORARY FUNCTION my_lower AS 'com.demo.MyLowerUDF';
SELECT my_lower(stu_name) FROM student_info LIMIT 3;
14

用 Sqoop 把 MySQL 的 weather 表导入 Hive 的 ods.weather_ods。

提示:--hive-import --hive-database --hive-table

解题思路字段分隔符要和 Hive 表一致;小表用 -m 1。
查看参考答案
SHELL
sqoop import \
  --connect jdbc:mysql://hadoop1:3306/nev --username root --password 123456 \
  --table weather --hive-import --hive-database ods --hive-table weather_ods \
  --fields-terminated-by '\t' -m 1

HBase(第8章)

15

在 HBase 中建表 student(列族 info、score),插入一条记录并查询。

提示:create / put / get

解题思路put 的格式是 表 行键 列族:列 值。
查看参考答案
SHELL
create 'student', 'info', 'score'
put 'student', '1001', 'info:name', '张三'
put 'student', '1001', 'score:math', '90'
get 'student', '1001
16

设计一个不会产生热点的 RowKey,用于存放 10 亿条订单记录。

提示:加盐前缀 / 反转时间戳

解题思路单调递增的 RowKey 会让写请求集中到一台 RegionServer。
查看参考答案
SHELL
# 方案一:hash 加盐(牺牲部分范围扫描能力)
#   RowKey = hash(orderId) % 10 + ":" + orderId
#
# 方案二:反转时间戳(便于"最新 N 条"查询)
#   RowKey = (Long.MAX_VALUE - ts) + ":" + orderId
#
# 方案三:预分区 + 业务维度前缀(城市/地区)
17

用 Phoenix 建表并做一次条件查询、一次建二级索引。

提示:sqlline.py / CREATE TABLE / CREATE INDEX

解题思路Phoenix 把 SQL 翻译成 HBase 操作。
查看参考答案
SHELL
!connect jdbc:phoenix:hadoop1:2181
CREATE TABLE student (id VARCHAR PRIMARY KEY, info.name VARCHAR, score.math INTEGER);
UPSERT INTO student VALUES ('1001','张三',90);
SELECT * FROM student WHERE info.name = '张三';
CREATE INDEX idx_name ON student (info.name);

Spark(第9章)

18

用 Spark 的 Java API 写 WordCount。

提示:flatMap → mapToPair → reduceByKey

解题思路四个算子一条链,最后用行动算子落地。
查看参考答案
JAVA
JavaRDD<String> lines = sc.textFile("hdfs://hadoop1:9000/wc/input/w.txt");
JavaRDD<String> words = lines.flatMap(l -> Arrays.asList(l.split("\\s+")).iterator());
JavaPairRDD<String, Integer> counts =
        words.mapToPair(w -> new Tuple2<>(w, 1)).reduceByKey((a, b) -> a + b);
counts.saveAsTextFile("hdfs://hadoop1:9000/wc/out-spark");
19

说明 reduceByKey 与 groupByKey 的区别,并给出选择建议。

提示:是否在 Map 端先聚合

解题思路reduceByKey 会做 map 端 combine,数据量小。
查看参考答案
SHELL
# reduceByKey:按 key 聚合,Shuffle 前先在 Map 端 combine,网络传输少
# groupByKey:按 key 分组,把同 key 的全部 value 拉到一个节点,数据量大、易 OOM
# 结论:能用 reduceByKey 就别用 groupByKey
20

用 spark-submit 把作业提交到 YARN,并说明几个关键参数。

提示:--master yarn --deploy-mode --executor-memory

解题思路提交参数直接决定资源占用与稳定性。
查看参考答案
SHELL
spark-submit \
  --master yarn --deploy-mode cluster \
  --executor-memory 2g --executor-cores 2 --num-executors 4 \
  --class com.demo.Wc \
  wc.jar hdfs:///input hdfs:///output

综合(第10章)

21

写 SQL:统计某城市每月平均最高温,并按月份排序。

提示:group by m + avg

解题思路先 cast 成数值再聚合。
查看参考答案
SHELL
SELECT m, round(avg(high_num), 1) AS avg_high
FROM dwd.weather_clean
WHERE city = '北京' AND y = '2025'
GROUP BY m ORDER BY m;
22

写 SQL:统计各城市晴天天数(Top 5)。

提示:LIKE 过滤 + 分组 + 排序 + limit

解题思路weather 字段含"晴"即算晴天。
查看参考答案
SHELL
SELECT city, count(*) AS sunny_days
FROM dwd.weather_clean
WHERE weather LIKE '%晴%'
GROUP BY city ORDER BY sunny_days DESC LIMIT 5;
23

对同一份数据,说明"先去重后分区"与"先分区再去重"的差别。

提示:跨分区重复

解题思路先去重可避免跨分区漏重。
查看参考答案
SHELL
# 先去重后分区:全局唯一,推荐
# 先分区再去重:每个分区内单独去重,同一城市同一天若落在两个分区就漏重了
# 做法:先 row_number() 全局去重,再 INSERT OVERWRITE ... PARTITION 落表
24

给出一个 10 分钟能做完的集群健康检查清单。

提示:jps / 9870 / 8088 / fsck

解题思路从进程、Web、文件系统三层确认。
查看参考答案
SHELL
1) jps:NameNode/DataNode/RM/NM 齐全
2) hdfs dfsadmin -report:Live datanodes = 3
3) http://hadoop1:9870:Overview 无 Under-replicated blocks
4) http://hadoop1:8088:Active Nodes 正常
5) hdfs fsck / -files -blocks:无 CORRUPT block
6) 提一个 WordCount 小作业验证端到端可用