MapReduce的详细使用

2023-05-16

MapReduce

文章目录

  • MapReduce
  • 1、常用数据序列化类型
  • 2、编程规范(三个阶段)
    • Mapper阶段
    • Reducer阶段
    • Driver阶段
  • 3、编程环境准备
  • 4、简单案例(单词统计)
  • 5、序列化
    • 序列化概述
    • 自定义 bean 对象实现序列化接口(Writable)
      • 步骤
      • 程序(序列化接口)
  • 6、InputFormat 数据输入
    • TextInputFormat(默认)
    • CombineTextInputFormat
  • 7、Shuffle 机制
    • Partition 分区
      • 自定义Partitioner步骤
      • Job驱动类 示例
      • 分区总结
    • WritableComparable 排序
      • 自定义排序 WritableComparable
    • Combiner 合并
      • 介绍
      • Combiner 合并方法一(自定义)
      • Combiner 合并方法二
  • 8、OutputFormat 数据输出
    • 自定义输入
  • 9、数据压缩
    • 概述
    • MR 支持的压缩编码
    • 压缩参数配置
    • 程序实现压缩
      • Map 输出端采用压缩
      • Reduce 输出端采用压缩

1、常用数据序列化类型

Java 类型Hadoop Writable 类型
BooleanBooleanWritable
ByteByteWritable
IntIntWritable
FloatFloatWritable
LongLongWritable
DoubleDoubleWritable
StringText
MapMapWritable
ArrayArrayWritable
NullNullWritable




2、编程规范(三个阶段)

  • 用户编写的程序分成三个部分:MapperReducerDriver

Mapper阶段

  • 用户自定义的Mapper要继承自己的父类
  • Mapper的输入数据是KV对的形式(KV的类型可自定义)
  • Mapper中的业务逻辑写在map()方法中
  • Mapper的输出数据是KV对的形式(KV的类型可自定义)
  • map()方法(MapTask进程)对每一个<K,V>调用一次



Reducer阶段

  • 用户自定义的Reducer要继承自己的父类
  • Reducer的输入数据类型对应Mapper的输出数据类型,也是KV
  • Reducer的业务逻辑写在reduce()方法中
  • ReduceTask进程对每一组相同k的<k,v>组调用一次reduce()方法



Driver阶段

  • 相当于YARN集群的客户端,用于提交我们整个程序到YARN集群,提交的是封装了MapReduce程序相关运行参数的job对象




3、编程环境准备

  • 添加依赖:创建Maven工程,添加依赖(pom.xml)

    <dependency>
        <!-- 版本号跟自己的Hadoop版本对应 -->
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>3.1.4</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.30</version>
    </dependency>
    
  • 添加日志:log4j.properties

    log4j.rootLogger=INFO, stdout 
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n 
    log4j.appender.logfile=org.apache.log4j.FileAppender 
    log4j.appender.logfile.File=target/spring.log 
    log4j.appender.logfile.layout=org.apache.log4j.PatternLayout 
    log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
    




4、简单案例(单词统计)

  • Driver驱动类

    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    import java.io.IOException;
    
    public class WordCountDriver {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
            //1、获取配置信息以及 job 对象
            Configuration configuration = new Configuration();
            Job job = Job.getInstance(configuration);
    
            //2、关联 Driver 的 jar
            job.setJarByClass(WordCountDriver.class);
    
            //3、关联 Mapper 和 Reducer 的 jar
            job.setMapperClass(WordCountMapper.class);
            job.setReducerClass(WordCountReduce.class);
    
            //4、设置 Mapper 输出的 key-value
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
    
            //5、设置 Reducer 输出的 key-value
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
    
            //6、设置 输入 和 输出 路径
            FileInputFormat.setInputPaths(job, new Path("E:\\test\\input\\input001"));
            FileOutputFormat.setOutputPath(job, new Path("E:\\test\\output\\output001"));
    
            //7、提交 job
            System.exit(job.waitForCompletion(true) ? 0 : 1);
        }
    }
    
  • Mapper类

    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    import java.io.IOException;
    
    /**
     * Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
     *     KEYIN     输入key的类型
     *     VALUEIN   输入value的类型
     *     KEYOUT    输出key的类型
     *     VALUEOUT  输出value的类型
     */
    public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    
        private Text outKey = new Text();
        private IntWritable outValue = new IntWritable(1);
    
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            //1、获取一行数据
            String line = value.toString();
    
            //2、切割
            String[] words = line.split(" ");
    
            //3、输出
            for (String word : words) {
                outKey.set(word);
                context.write(outKey, outValue);
            }
        }
    }
    
  • Reducer类

    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    import java.io.IOException;
    
    /**
     * Reducer<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
     *     KEYIN     输入key的类型
     *     VALUEIN   输入value的类型
     *     KEYOUT    输出key的类型
     *     VALUEOUT  输出value的类型
     */
    public class WordCountReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
    
        private int sum;
        private IntWritable outValue = new IntWritable();
    
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            //1、累加求和
            sum = 0;
            for (IntWritable value : values) {
                sum += value.get();
            }
            outValue.set(sum);
    
            //2、输出
            context.write(key, outValue);
        }
    }
    




5、序列化

序列化概述

  • 简介
    • 序列化
      • 就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储到磁盘(持久化)和网络传输
    • 反序列化
      • 就是将收到字节序列(或其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象
  • 序列化特点
    • 紧凑:高效使用存储空间
    • 快速:读写数据的额外开销小
    • 互操作:支持多语言的交互



自定义 bean 对象实现序列化接口(Writable)

步骤

  • 第一步:bean对象实现 Writable 接口
  • 第二步:反序列化时,需要反射调用空参构造函数,所以必须有空参构造
  • 第三步:重写序列化方法(write方法)
  • 第四步:重写反序列化方法(readFields方法)
  • 第五步:要想把结果显示在文件中,需要重写 toString(),可用"\t"分开,方便后续用
  • 第六步:Driver、Mapper、Reducer 实现类

注意反序列化的顺序和序列化的顺序完全一致



程序(序列化接口)

import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

//1、bean对象实现 Writable 接口
public class FlowBean implements Writable {

    private long upFlow;
    private long downFlow;
    private long sumFlow;

    //2、创建空参构造函数
    public FlowBean(){}

    public long getUpFlow() {
        return upFlow;
    }

    public void setUpFlow(long upFlow) {
        this.upFlow = upFlow;
    }

    public long getDownFlow() {
        return downFlow;
    }

    public void setDownFlow(long downFlow) {
        this.downFlow = downFlow;
    }

    public long getSumFlow() {
        return sumFlow;
    }

    public void setSumFlow() {
        this.sumFlow = this.upFlow + this.downFlow;
    }

    //3、重写序列化方法(write方法)
    @Override
    public void write(DataOutput out) throws IOException {
        out.writeLong(this.upFlow);
        out.writeLong(this.downFlow);
        out.writeLong(this.sumFlow);
    }

    //4、重写反序列化方法(readFields方法)
    @Override
    public void readFields(DataInput in) throws IOException {
        this.upFlow = in.readLong();
        this.downFlow = in.readLong();
        this.sumFlow = in.readLong();
    }

    //5、要想把结果显示在文件中,需要重写 toString(),可用"\t"分开,方便后续用
    @Override
    public String toString() {
        return upFlow + "\t" + downFlow + "\t" + sumFlow;
    }
}




6、InputFormat 数据输入

TextInputFormat(默认)

  • TextInputFormat默认的 FileInputFormat 实现类
    • 按行读取每条记录。
    • 是存储该行在整个文件中的起始字节偏移量LongWritable 类型。
    • 这行的内容,不包括任何行终止符(换行符和回车符),Text 类型



CombineTextInputFormat

  • 应用场景

    • 用于小文件过多的场景,将多个小文件从逻辑上规划到一个切片中,多个小文件就交给一个 MapTask 处理
  • 虚拟存储切片最大值和最小值设置

    • 最大值CombineTextInputFormat.setMinInputSplitSize(Job job, long size)
    • 最小值CombineTextInputFormat.setMaxInputSplitSize(Job job, long size)
    • 注意:虚拟存储切片最大值设置最好根据实际的小文件大小情况来设置具体的值(size是)
    • 示例(设置切片最大值为 4M)
      • CombineTextInputFormat.setMaxInputSplitSize(job, 4194304); // 4M
  • 程序(在 Job驱动类 中添加设置)

    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.CombineTextInputFormat;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    import java.io.IOException;
    
    public class WordCountDriver {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
            Configuration configuration = new Configuration();
            Job job = Job.getInstance(configuration);
    
            job.setJarByClass(WordCountDriver.class);
    
            job.setMapperClass(WordCountMapper.class);
            job.setReducerClass(WordCountReducer.class);
    
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
    
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
    
            //设置 InputFormat 使用 CombineTextInputFormat,它默认用的是 TextInputFormat
            job.setInputFormatClass(CombineTextInputFormat.class);
            //虚拟存储切片最大值设置 20M
            CombineTextInputFormat.setMaxInputSplitSize(job, 20971520);
            
            FileInputFormat.setInputPaths(job, new Path("C:\\test\\input\\input001"));
            FileOutputFormat.setOutputPath(job, new Path("C:\\test\\output\\output001"));
    
            System.exit(job.waitForCompletion(true) ? 0 : 1);
        }
    }
    




7、Shuffle 机制

Partition 分区

  • 默认分区是根据key的hashCode对ReduceTasks个数取模得到的。用户没法控制哪个key存储到哪个分区

自定义Partitioner步骤

  • 第一步:自定义类继承Partitioner重写getPartition()方法

    package com.itfzk.mapreducer.partition;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Partitioner;
    
    public class PartitionTest extends Partitioner<Text, IntWritable> {
        @Override
        public int getPartition(Text text, IntWritable intWritable, int i) {
            int partitioner;
            
            //逻辑处理,确定text写入到哪个分区中
            
            return partitioner;
        }
    }
    
  • 第二步:在Job驱动中,设置自定义Partitioner

    • job.setPartitionerClass(Partition类名.class)
  • 第三步:自定义Partition后,在Job驱动中根据自定义Partitioner的逻辑设置相应数量的ReduceTask

    • job.setNumReduceTasks(ReduceTask的数量)



Job驱动类 示例

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;

public class WordCountDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration configuration = new Configuration();
        Job job = Job.getInstance(configuration);

        job.setJarByClass(WordCountDriver.class);

        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //自定义Partitioner
        job.setPartitionerClass(PartitionTest.class);
        
        //设置相应数量的ReduceTask
        job.setNumReduceTasks(4);

        FileInputFormat.setInputPaths(job, new Path("C:\\test\\input\\input001"));
        FileOutputFormat.setOutputPath(job, new Path("C:\\test\\output\\output002"));

        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}



分区总结

  • 如果 ReduceTask的数量 > getPartition的结果数,则会多产生几个空的输出文件part-r-000xx
  • 如果 1 < ReduceTask的数量 < getPartition的结果数,则有一部分分区数据无处安放,会报错
  • 如果 ReduceTask的数量 = 1,则不管MapTask端输出多少个分区文件,最终结果都交给这一个ReduceTask,最终也就只会产生一个结果文件 part-r-00000
  • 分区号必须从零开始,逐一累加



WritableComparable 排序

自定义排序 WritableComparable

  • 创建bean 对象做为 Mapper的输出key 传输,需要实现 WritableComparable 接口重写 compareTo() 方法,就可以实现排序

  • Mapper的输出keyMapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>中的 KEYOUT

    import org.apache.hadoop.io.WritableComparable;
    import java.io.DataInput;
    import java.io.DataOutput;
    import java.io.IOException;
    
    //实现 WritableComparable
    public class FlowBean implements WritableComparable<FlowBean> {
        
        //字段
        //setting、getting
        //toString
    
        //重写 compareTo()
        @Override
        public int compareTo(FlowBean o) {
            //需要按照哪个字段排序的逻辑
        }
    
        @Override
        public void write(DataOutput dataOutput) throws IOException {
        }
    
        @Override
        public void readFields(DataInput dataInput) throws IOException {
        }
    }
    



Combiner 合并

介绍

  • Combiner是MR程序中Mapper和Reducer之外的一种组件
  • Combiner组件的父类就是Reducer
  • Combiner和Reducer的区别在于运行的位置
    • Combiner是在每一个MapTask所在的节点运行
    • Reducer是接收全局所有Mapper的输出结果
  • Combiner的意义就是对每一个MapTask的输出进行局部汇总,以减小网络传输量
  • Combiner应用的前提是不能影响最终的业务逻辑,Combiner的输出kv应该跟Reducer的输入kv类型要对应起来



Combiner 合并方法一(自定义)

  • 第一步:自定义一个 Combiner类 继承 Reducer重写 Reduce 方法
  • 第二步:在 Job 驱动类中设置
    • job.setCombinerClass(Combiner类名.class)



Combiner 合并方法二

Reducer类的逻辑跟Combiner类的逻辑一样Combiner的输出kv类型跟Reducer的输入kv类型一样

  • 将 Reducer类 作为 Combiner类
    • job.setCombinerClass(Reducer类名.class)




8、OutputFormat 数据输出

自定义输入

  • 第一步:创建 OutputFormat 类,继承 FileOutputFormat重写 RecordWriter() 方法

    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.RecordWriter;
    import org.apache.hadoop.mapreduce.TaskAttemptContext;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    import java.io.IOException;
    
    public class WordCountOutPutFormat extends FileOutputFormat<Text, IntWritable> {
        @Override
        public RecordWriter<Text, IntWritable> getRecordWriter(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
            //返回自定义RecordWriter类
            WordCountRecordWriter wordCountRecordWriter = new WordCountRecordWriter(taskAttemptContext);
            return wordCountRecordWriter;
        }
    }
    
  • 第二步:创建 RecordWriter 类,继承 RecordWriter重写 write、close 方法

    import org.apache.hadoop.fs.FSDataOutputStream;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.RecordWriter;
    import org.apache.hadoop.mapreduce.TaskAttemptContext;
    import java.io.IOException;
    
    public class WordCountRecordWriter extends RecordWriter<Text, IntWritable> {
    
        private FSDataOutputStream fsDataOutputStream1;
        private FSDataOutputStream fsDataOutputStream2;
    
        //构造函数
        public WordCountRecordWriter(TaskAttemptContext job) throws IOException {
            //按照自己的输出格式,例如:将数据输出到两个文件中(f.log, z.log)
            FileSystem fs = FileSystem.get(job.getConfiguration());
            fsDataOutputStream1 = fs.create(new Path("C:\\test\\f.log"));
            fsDataOutputStream2 = fs.create(new Path("C:\\test\\z.log"));
        }
    
        //输出方法
        @Override
        public void write(Text text, IntWritable intWritable) throws IOException, InterruptedException {
            //按照自己的逻辑将数据输出到不同的文件中
            if(text.toString().contains("f")){
                fsDataOutputStream1.writeBytes(text.toString() + "\t" + intWritable.get() + "\n");
            }else{
                fsDataOutputStream2.writeBytes(text.toString() + "\t" + intWritable.get() + "\n");
            }
        }
    
        //关闭
        @Override
        public void close(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
            fsDataOutputStream1.close();
            fsDataOutputStream2.close();
        }
    }
    
  • 第三步:在Job驱动中,设置自定义的 OutputFormat

    • job.setOutputFormatClass(自定义的OutputFormat类名.class);




9、数据压缩

概述

  • 优点:以减少磁盘 IO、减少磁盘存储空间。
  • 缺点:增加 CPU 开销。
  • 压缩原则
    • 运算密集型的 Job,少用压缩
    • IO 密集型的 Job,多用压缩



MR 支持的压缩编码

压缩算法对比介绍

压缩格式Hadoop 自带?算法文件扩展名是否可切片换成压缩格式后,原来的程序是否需要修改
DEFLATE是,直接使用DEFLATE.deflate和文本处理一样,不需要修改
Gzip是,直接使用DEFLATE.gz和文本处理一样,不需要修改
bzip2是,直接使用bzip2.bz2和文本处理一样,不需要修改
LZO否,需要安装LZO.lzo需要建索引,还需要指定输入格式
Snappy是,直接使用Snappy.snappy和文本处理一样,不需要修改

压缩性能的比较

压缩算法原始文件大小压缩文件大小压缩速度解压速度
gzip8.3GB1.8GB17.5MB/s58MB/s
bzip28.3GB1.1GB2.4MB/s9.5MB/s
LZO8.3GB2.9GB49.3MB/s74.6MB/s
Snappy250MB/s500MB/s

压缩算法的优缺点比较

压缩算法优点缺点
Gzip压缩率比较高不支持 Split;压缩/解压速度一般
Bzip2压缩率高;支持 Split压缩/解压速度慢
Lzo压缩/解压速度比较快;支持 Split压缩率一般;想支持切片需要额外创建索引
Snappy压缩和解压缩速度快不支持 Split;压缩率一般



压缩参数配置

Hadoop 引入了编码/解码器

压缩格式对应的编码/解码器
DEFLATEorg.apache.hadoop.io.compress.DefaultCodec
gziporg.apache.hadoop.io.compress.GzipCodec
bzip2org.apache.hadoop.io.compress.BZip2Codec
LZOcom.hadoop.compression.lzo.LzopCodec
Snappyorg.apache.hadoop.io.compress.SnappyCodec

配置参数

参数默认值阶段建议
io.compression.codecs
(在 core-site.xml 中配置)
无,这个需要在命令行输入hadoop checknative 查看输入压缩Hadoop 使用文件扩展名判断是否支持某种编解码器
mapreduce.map.output.compress
(在 mapred-site.xml 中配置)
falsemapper 输出这个参数设为 true 启用压缩
mapreduce.output.fileoutputformat.compress
(在mapred-site.xml 中配置)
falsereducer 输出这个参数设为 true 启用压缩
mapreduce.output.fileoutputformat.compress.codec
(在mapred-site.xml 中配置)
org.apache.hadoop.io.
compress.DefaultCodec
reducer 输出使用标准工具或者编解码器,如 gzip 和bzip2




程序实现压缩

Map 输出端采用压缩

  • 在Driver类中配置,开启压缩和设置压缩方式(以BZip压缩为例)
Configuration configuration = new Configuration();

// 开启 map 端输出压缩
configuration.setBoolean("mapreduce.map.output.compress", true);
// 设置 map 端输出压缩方式
configuration.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);



Reduce 输出端采用压缩

  • 在Driver类中配置,开启压缩和设置压缩方式(以BZip压缩为例)

    // 设置 reduce 端输出压缩开启
    FileOutputFormat.setCompressOutput(job, true);
    // 设置压缩的方式
    FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MapReduce的详细使用 的相关文章

随机推荐

  • 解决通过vnc登陆linux server,在terminal最小化后找不到的问题

    在左边的菜单栏右击 xff0c add new panel xff0c 再右击新添加的add to panel xff0c 然后会让你选择往这个新panel上添加新的菜单 xff0c 把window list添加就好了
  • CSS第二章:2.颜色单位(RGB值、RGBA值)

    总览 一 RGB 1 CSS中能够使用颜色名来使用颜色 2 不使用颜色名 xff0c 我们使用RGB值来描述颜色 3 R red G green B blue 4 每一种颜色的范围在0 255 xff08 0 100 xff09 之间 5
  • 信息化与数字化的区别

    数字化与信息化的区别 今日看到一篇文章 信息化与数字化的核心差异 xff0c 让我重新思考了这两个即熟悉又陌生的名词 xff0c 通过这篇文章和在B站上搜相对应的视频 xff0c 使我大致懂了一些 1 信息化是什么 xff1f 信息化是数据
  • 开启快乐之旅—【C#Winform&认识篇】

    入门学习 简单了解熟悉界简单操作1 xff1a 修改窗体标题2 xff1a 修改窗体图标3 xff1a 窗体出现位置4 xff1a 最大化 xff0c 最小化操作5 xff1a 是否任务栏显示form窗体6 xff1a 窗口大小 简单了解
  • ubuntu磁盘清理

    打开ubuntu software 搜索Bleachbit 安装即可 系统清理工具BleachBit使用 ubuntu清理磁盘空间的多种方法 Ubuntu上释放磁盘空间的几种简单方法 Ubuntu 安装 BleachBit 也可 1 查看电
  • 一些网站资源分享

    链接地址 网站地址 1 博客就是这个博客 2 音乐是我网易云歌单 3 图床是我保存的图库 4 西瓜导航里面有各种网站 5 钟馗之眼是一个爬虫全网某些特征的网站 6 罗马盘是资源网站 7 AI引擎 xff0c 体验智能的感觉 8 优店 xff
  • 软件工程的完整生命周期

    生命周期大体上分为11个步骤 xff0c 如下图 xff1a 第一步 xff1a 概念 创意 需求 产生 xff0c 这个环节一般是项目发起人完成 xff0c 也有可能由产品经理或收到反馈后发起 xff0c 很多时候是会带有这个项目的期望或
  • Qt-设置背景色的几种方式

    最近设置背景色 xff0c 被背景色搞得晕头转向 xff0c 然后总结了一下用过的方法与踩过的坑 xff0c 希望大家有所帮助 QLabel label 61 new QLabel CSS样式 xff0c 直接设置样式 xff0c 该方法对
  • C++ 如何获取数组/容器的长度?

    文章目录 一 获取数组的长度1 sizeof a sizeof a 2 end a begin a 二 获取标准库容器的长度三 数组作为函数参数时 xff0c 在函数中无法获取其长度 一 获取数组的长度 1 sizeof a sizeof
  • 计算机网络期末复习题

    1 请简述在划分子网的情况下 xff0c 路由器转发IP数据报的基本过程 答 xff1a 在划分子网的情况下 xff0c 路由器转发分组的算法如下 xff1a 1 从收到的数据报首部提取目的IP地址D xff08 1分 xff09 2 先判
  • Jetson TX1 TX2 IO 引脚设置

    有朋友问我引脚问题 xff0c 我就把一段文档摘抄在这里了 希望对大家有用 配置40引脚扩展接头 主屏幕 兼容的硬件屏幕 40引脚扩展标题屏幕 命令行界面 设备树覆盖 创建简单的设备树覆盖 为40针接头连接器创建自定义设备树覆盖 启动Jet
  • Android手机怎样投屏到win10(无需联网)

    一 前言 适用场景 xff1a 无可用wifi 想获得大屏观影体验 x1f601 二 具体操作 PC端 在Cortana处搜索 投影设置 投影到此电脑 处的设置如下如图 xff08 也可根据自己习惯调整 xff09 安卓端 华为手机为例 打
  • Windows远程控制ubuntu16.04的vnc教程(附灰屏和无鼠标只显示叉号的解决方案)

    VNC可远程Linux的桌面 xff0c 不仅仅只可以远程终端窗口 xff0c 操作起来要比ssh好用 xff0c 效果如图 VNC介绍 xff1a VNC Virtual Network Console xff0c 即虚拟网络控制台 xf
  • 联邦学习安全与隐私保护

    一 FL隐私保护方法 1 1 加密方法 通过将明文编码为密文的方式 xff0c 只允许特定人员解码 xff0c 为数据隐私保护提供了有效手段 xff0c 但往往需要较大的计算开销 xff0c 较难应用于实际场景中 安全多方计算 SMC研究的
  • vue - vue项目对axios请求的封装

    axios介绍 axios是基于promise的网络请求库 xff0c 可以在nodejs和浏览器中运行 在服务端axios使用原生的nodejs的http模块 xff0c 在客户端浏览器中则而是用xmlhttprequests xff0c
  • C++总结——语法篇

    Static关键字1 静态全局变量2 静态局部变量3 静态函数4 静态数据成员5 静态成员函数 引用引用与指针的区别 左值 右值 左值引用 右值引用 new delete与malloc free Static关键字 1 静态全局变量 sta
  • Android开发快速入门及导出apk

    环境及工具准备 jdk安装配置安装android studio或idea xff08 推荐直接使用idea xff0c android studio其实也是基于idea开发的 xff09 配置android sdk安装一个安卓模拟器 xff
  • 在阿里云搭建CENTOS7系统以及图形界面

    1 搭建CentOS7操作系统服务器 首先要购买服务器 xff0c 推荐学生认证可以获得好几个月的免费服务器 略去具体的过程 阿里云默认的系统不是CentOS7 xff0c 所以需要先将操作系统改成CentOS7 在实例的基本信息中 xff
  • linux基础学习,有相应的笔记文件XMind和Word(基于centos8(主要的)和Ubuntu20),里面有linux基本操作指令和JavaEE,大数据相关的shell。2021年4月26日

    前面的话 这篇文章是我学习linux的一个记录 xff0c 我是用XMind记笔记的 xff0c 然后转换为Word最后粘贴到这里的 xff0c 如果感兴趣的话 xff0c 可以下载我上传的文件 xff0c 都是免费的 xff0c 大家共同
  • MapReduce的详细使用

    MapReduce 文章目录 MapReduce1 常用数据序列化类型2 编程规范 xff08 三个阶段 xff09 Mapper阶段Reducer阶段Driver阶段 3 编程环境准备4 简单案例 单词统计 5 序列化序列化概述自定义 b