MperReduce学习笔记下

自定义InputFormat合并小文件

案例需求

无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案。

案例分析

小文件的优化无非以下几种方式:

  1. 在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS
  2. 在业务处理之前,在HDFS上使用mapreduce程序对小文件进行合并
  3. 在mapreduce处理时,可采用combineInputFormat提高效率

案例实现

本节实现的是上述第二种方式

  1. 首先继承FileInputFormat类自定义MyInputFormat方法,在自定义的MyInputFormat类中需重写RecordReader方法。
  2. 然后自定义MyRecordReader继承RecordReader,在自定义的MyRecordReader类中需重新initialize(初始化方法)、nextKeyValue(该方法用于获取 <k1,v1>,读取源数据转换为<k1,v1>)、getCurrentKey(返回k1)、getCurrentValue(返回v1)、getProgress(获取文件读取进度)、close(释放资源)等方法。
  3. 然后在MyInputFormat类中实例化自定义的MyRecordReader类并传递源数据,设置文件是否允许被切割(本案例不允许被切割)。
  4. Mapper代码按照正常逻辑实现,可以省略Reduce代码,最后主类JobMain中设置文件的读取类为自定义的MyInputFormat。

程序的核心机制:

  1. 自定义一个InputFormat
  2. 改写RecordReader,实现一次读取一个完整文件封装为KV
  3. 在输出时使用SequenceFileOutPutFormat输出合并文件
// 第一步

package myinput_format;

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;

import java.io.IOException;

public class MyRecordReader extends RecordReader<NullWritable, BytesWritable> {
    private Configuration configuration = null;
    private FileSplit fileSplit = null;
    // 定义标志位判断文件是否处理完成 ---false表示文件没有被读取完
    private boolean processed = false;
    private BytesWritable bytesWritable = new BytesWritable();
    private FileSystem fileSystem = null;
    private FSDataInputStream inputStream = null;
    // 初始化
    @Override
    public void initialize(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {

        // inputSplit----文件切片包含文件名信息
        fileSplit = (FileSplit)inputSplit;

        // 获取Configuration 对象 ---向上提取(以便nextKeyValue函数使用)
        configuration = taskAttemptContext.getConfiguration();

    }

    // 该方法用于获取 <k1,v1>,读取源数据转换为<k1,v1>
    /*
     * k1-------->NullWritable
     * v1-------->BytesWritable
     * */
    @Override
    public boolean nextKeyValue() throws IOException, InterruptedException {
        // 判断文件是否读取完成
        if (!processed){
            // 1.获取源文件字节输入流
            // 1.1 获取源文件的文件系统(FileSystem)
            fileSystem = FileSystem.get(configuration);
            // 1.2 通过(FileSystem)获取文件字节输入流 ---源文件路径
            inputStream = fileSystem.open(fileSplit.getPath());

            // 2.获取源文件数据到普通的字节数组(byte[])
            long a = fileSplit.getLength();
            byte[] bytes = new byte[(int) a];
//            byte[] bytes = new byte[(int) fileSplit.getLength() ];// 需要容纳下小文件字节大小,强行装换为int类型
            //2.1源文件数据读取到上述自定义的字节数组
            IOUtils.readFully(inputStream,bytes,0,(int) fileSplit.getLength());
            // 3.普通的字节数组转换封装到BytesWritable,得到 v1
            bytesWritable.set(bytes,0,(int) fileSplit.getLength());
            processed = true;
            return true;
        }
        return false;
    }

    //返回 k1
    @Override
    public NullWritable getCurrentKey() throws IOException, InterruptedException {
        return NullWritable.get();
    }

    //返回 v1
    @Override
    public BytesWritable getCurrentValue() throws IOException, InterruptedException {
        return bytesWritable;
    }

    // 获取文件读取进度
    @Override
    public float getProgress() throws IOException, InterruptedException {
        return 0;
    }

    // 进行资源释放
    @Override
    public void close() throws IOException {
        // 关闭输入流
        inputStream.close();
        fileSystem.close();
    }
}
// 第二步
package myinput_format;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

import java.io.IOException;

public class MyInputFormat extends FileInputFormat<NullWritable, BytesWritable> {
    // RecordReader抽象类返回子类,需要自定义LineRecordReader类
    @Override
    public RecordReader<NullWritable, BytesWritable> createRecordReader(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
        // 1.创建自定义RecordReader对象
        MyRecordReader myRecordReader = new MyRecordReader();
        // 2.将源数据InputSplit和TaskAttemptContext传递给自定义RecordReader对象
        myRecordReader.initialize(inputSplit,taskAttemptContext);
        return myRecordReader;
    }

    // 设置文件是否可以被切割(功能实现小文件合并设置为不可被切割)
    @Override
    protected boolean isSplitable(JobContext context, Path filename) {
        return false;
    }
}
// 第三步
package myinput_format;

import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;


import java.io.IOException;

public class SequenceFileMapper extends Mapper<NullWritable, BytesWritable, Text,BytesWritable> {
    @Override
    protected void map(NullWritable key, BytesWritable value, Context context) throws IOException, InterruptedException {
        // <k1,v1>转为<k2,v2>
        // 1.获取文件名作为k2
        // 根据 context 获取文件切片--其中包含文件名
        FileSplit fileSplit = (FileSplit) context.getInputSplit();
        String fileName = fileSplit.getPath().getName();
        // 2.v2就是v1写入上下文
        context.write(new Text(fileName),value);
    }
}
// 第四步
package myinput_format;

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.BytesWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;



import java.net.URI;


public class JobMain extends Configured implements Tool {

    //该方法用于指定一个job任务
    @Override
    public int run(String[] strings) throws Exception {
        // 1.创建 job任务对象 两个参数 1.configuration  2.job任务名称
        Job job = Job.getInstance(super.getConf(), "input_format");
        // 打包运行出错添加
        job.setJarByClass(JobMain.class);
        // 2.配置 job任务对象(八个步骤)
        // 2.1 读取文件 ---指定读取类
        job.setInputFormatClass(MyInputFormat.class);
        // 指点源文件路径
        MyInputFormat.addInputPath(job,new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myinput_format"));
        // 2.2 进入指定map阶段处理方式和数据类型
        // 设置map阶段用的类
        job.setMapperClass(SequenceFileMapper.class);
        // 设置Map阶段K2的类型 --- 单词(字符串)
        job.setMapOutputKeyClass(Text.class);
        // 设置Map阶段V2的类型 ---
        job.setMapOutputValueClass(BytesWritable.class);
        // 2.3(4,5,6) 进入Shuffle阶段 --先采用默认方式处理
        // 2.7 指定Reduce阶段的数据类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(BytesWritable.class);
        // 2.8 设置输出类型 -- 保存在二进制文件中
        job.setOutputFormatClass(SequenceFileOutputFormat.class);
        // 设置输出路径
//        TextOutputFormat.setOutputPath(job,new Path("hdfs://hadoop01:9000/wordcount_out"));
        // 判断目标目录是否存在,存在则删除
        Path path = new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myinput_format_out");
        SequenceFileOutputFormat.setOutputPath(job,path);
        // 获取hdfs文件系统
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop01:9000/hadoop_mapreduce/"), new Configuration());
        // --本地测试--
//        FileSystem fileSystem = FileSystem.get(new URI("file:///D:\\output"), new Configuration());
        // 判断目录是否存在
        boolean exists = fileSystem.exists(path);
        if (exists){
            // 删除目标目录
            fileSystem.delete(path,true);
        }

        // 等待任务结束
        boolean bl = job.waitForCompletion(true);

        return bl ? 0:1;
    }

    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();

        // 启动 job任务 --记录任务执行状态 0表示成功
        int run = ToolRunner.run(configuration, new JobMain(), args);
        System.exit(run);
    }
}

自定义outputFormat格式输出文件

案例需求

现在有一些订单的评论数据,需求,将订单的好评与差评进行区分开来,将最终的数据分开到不同的文件夹下面去,数据内容参见资料文件夹,其中数据第九个字段表示好评,中评,差评。0:好评,1:中评,2:差评

案例分析

程序的关键点是要在一个mapreduce程序中根据数据的不同输出两类结果到不同目录,这类灵活的输出需求可以通过自定义outputformat来实现。

案例实现
  1. 首先继承FileOutputFormat类自定义MyOutputFormat类,在自定义的MyOutputFormat类中需重写RecordWriter方法。
  2. 然后自定义MyRecordWriter继承RecordWriter,在自定义的MyRecordWriter类中需重新write(具体输出数据的方法)、close(释放资源)等方法。
  3. 然后在MyOutputFormat类中实例化自定义的MyRecotdWriter类(有参构造传递)传递源数据
  4. Mapper代码按照正常逻辑实现,可以省略Reduce代码,最后主类JobMain中设置文件的输出类为自定义的MyOutputFormat。
// 第一步
package myoutput_format;

import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.RecordWriter;
import org.apache.hadoop.mapreduce.TaskAttemptContext;

import java.io.IOException;

public class MyRecordWriter extends RecordWriter<Text,NullWritable> {
    private FSDataOutputStream goodCommentsOutputStream;
    private FSDataOutputStream badCommentsOutputStream;

    public MyRecordWriter() {
    }

    public MyRecordWriter(FSDataOutputStream goodCommentsOutputStream, FSDataOutputStream badCommentsOutputStream) {
        this.goodCommentsOutputStream = goodCommentsOutputStream;
        this.badCommentsOutputStream = badCommentsOutputStream;
    }

    /**
     *
     * @param text  行文本内容
     * @param nullWritable
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    public void write(Text text, NullWritable nullWritable) throws IOException, InterruptedException {
        //1:从行文本数据中获取第9个字段
        String[] split = text.toString().split("\t");
        String numStr = split[9];

        //2:根据字段的值,判断评论的类型,然后将对应的数据写入不同的文件夹文件中
        if(Integer.parseInt(numStr) <= 1){
            //好评或者中评
            goodCommentsOutputStream.write(text.toString().getBytes());
            // 添加换行符
            goodCommentsOutputStream.write("\r\n".getBytes());
        }else{
            //差评
            badCommentsOutputStream.write(text.toString().getBytes());
            badCommentsOutputStream.write("\r\n".getBytes());
        }

    }

    @Override
    public void close(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
        IOUtils.closeStream(goodCommentsOutputStream);
        IOUtils.closeStream(badCommentsOutputStream);
    }
}
// 第二步
package myoutput_format;

import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
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 MyOutputFormat extends FileOutputFormat<Text, NullWritable> {

    @Override
    public RecordWriter<Text, NullWritable> getRecordWriter(TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException {
        // 1.获取目标文件输出流(两个)
        FileSystem fileSystem = FileSystem.get(taskAttemptContext.getConfiguration());
        // 文件写入路径
        FSDataOutputStream goodCommentsOutputStream = fileSystem.create(new Path("hdfs://hadoop01:9000/hadoop_mapreduce/good_comments/good_comments.txt"));
        FSDataOutputStream badCommentsOutputStream = fileSystem.create(new Path("hdfs://hadoop01:9000/hadoop_mapreduce/bad_comments/bad_comments.txt"));
        // 2.传递给----->MyRecotdWriter类使用(有参构造传递)
        MyRecordWriter myRecordWriter = new MyRecordWriter(goodCommentsOutputStream,badCommentsOutputStream);

        return myRecordWriter;
    }


}
// 第三步
package myoutput_format;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class MyOutputFormatMapper extends Mapper<LongWritable, Text,Text, NullWritable> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        context.write(value,NullWritable.get());
    }
}
// 第四步
package myoutput_format;


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.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.net.URI;


public class JobMain extends Configured implements Tool {

    //该方法用于指定一个job任务
    @Override
    public int run(String[] strings) throws Exception {
        // 1.创建 job任务对象 两个参数 1.configuration  2.job任务名称
        Job job = Job.getInstance(super.getConf(), "output_format");
        // 打包运行出错添加
        job.setJarByClass(JobMain.class);
        // 2.配置 job任务对象(八个步骤)
        // 2.1 读取文件 ---指定读取类
        job.setInputFormatClass(TextInputFormat.class);
        // 指点源文件路径
        TextInputFormat.addInputPath(job,new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myoutput_format"));
        // 2.2 进入指定map阶段处理方式和数据类型
        // 设置map阶段用的类
        job.setMapperClass(MyOutputFormatMapper.class);
        // 设置Map阶段K2的类型 --- 单词(字符串)
        job.setMapOutputKeyClass(Text.class);
        // 设置Map阶段V2的类型 ---
        job.setMapOutputValueClass(NullWritable.class);
        // 2.3(4,5,6) 进入Shuffle阶段 --先采用默认方式处理
        // 2.7 指定Reduce阶段的数据类型
        // 2.8 设置输出类型 -- 保存在二进制文件中
        job.setOutputFormatClass(MyOutputFormat.class);
        // 设置输出路径
//        TextOutputFormat.setOutputPath(job,new Path("hdfs://hadoop01:9000/wordcount_out"));
        // 判断目标目录是否存在,存在则删除
        Path path = new Path("hdfs://hadoop01:9000/hadoop_mapreduce/myoutput_format_out");
        SequenceFileOutputFormat.setOutputPath(job,path);
        // 获取hdfs文件系统
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop01:9000/hadoop_mapreduce/"), new Configuration());
        // --本地测试--
//        FileSystem fileSystem = FileSystem.get(new URI("file:///D:\\output"), new Configuration());

        // 判断目录是否存在
        boolean exists = fileSystem.exists(path);
        if (exists){
            // 删除目标目录
            fileSystem.delete(path,true);
        }

        // 等待任务结束
        boolean bl = job.waitForCompletion(true);

        return bl ? 0:1;
    }

    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();

        // 启动 job任务 --记录任务执行状态 0表示成功
        int run = ToolRunner.run(configuration, new JobMain(), args);
        System.exit(run);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/933496.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL 探索者日志 】第二弹 —— 数据库基础

MySQL系列学习笔记&#xff1a; MySQL探索者日志__Zwy的博客-CSDN博客 各位于晏&#xff0c;亦菲们&#xff0c;请点赞关注&#xff01; 我的个人主页&#xff1a; _Zwy-CSDN博客 目录 1、MySQL服务器&#xff0c;数据库&#xff0c;表关系 2、MySQL登录连接服务器 3、MyS…

flink终止提交给yarn的任务

接上文&#xff1a;一文说清flink从编码到部署上线 1.查看正在执行的flink 访问地址&#xff08;参考&#xff09;&#xff1a;http://10.86.97.191:8099/cluster/apps 2.终止任务 yarn application -kill appID 本文为&#xff1a; yarn application -kill application_17…

CentOS虚拟机开机出现问题

CentOS虚拟机断电或强制关机&#xff0c;再开机出现问题 错误原因&#xff1a; failed to mount /sysroot.&#xff08;无法挂载/ sysroot。&#xff09; Dependency failed for Initrd root File System.&#xff08;Initrd根文件系统的依赖关系失败。&#xff09; Dependency…

可靠的人形探测,未完待续(I)

HI&#xff0c;there&#xff01;从紧张的项目中出来冒个泡&#xff01; 刚好想要验证一下mmWave在有人检测方面的应用&#xff0c;就看到了这个活动 - 瞌睡了有枕头属于是&#xff0c;活动策划好评&#xff01; 朋友曾关注汽车相关的技术领域&#xff0c;跟我吐槽过&#xff0…

web斗地主游戏实现指北

前后端通信 作为一个即时多人游戏&#xff0c;不论是即时聊天还是更新玩家状态&#xff0c;都需要服务端有主动推送功能&#xff0c;或者客户端轮询。轮询的时间间隔可能导致游玩体验差&#xff0c;因为不即时更新&#xff0c;而且请求数量太多可能会打崩服务器。 建议在cs间…

基于Qt的文字处理软件(二)

这期文章我们进行主窗口的一些函数的定义&#xff0c;同时导入一些文字处理软件的状态栏会用到的图标。下面图片是图标导入到项目后的一个示例&#xff0c;图标可以到阿里矢量图标库里面找到。 一、导入图标资源: 1.首先在项目目录的位置创建一个images的文件,然后将收集好的图…

Halcon_数据类型_ROI_仿射变换_投影变换

文章目录 算子快捷键一、Halcon数据类型Iconic (图标)Control (控制)Tuple &#xff08;数组&#xff09; 二、ROI&#xff08;区域&#xff09;1.代码创建ROI2.手动创建ROI 三、图形预处理1.图像的变换与矫正平移 -hom_mat2d_translate旋转缩放-HomMat2D&#xff1a;输入的仿射…

C语言(指针基础练习)

删除数组中的元素 数组的元素在内存地址中是连续的&#xff0c;不能单独删除数组中的某个元素&#xff0c;只能覆盖。 #include <stdio.h> #include <stdbool.h>// 函数声明 int deleteElement(int arr[], int size, int element);int main() {int arr[] {1, 2, 3…

甘肃美食之选:食家巷方形饼

甘肃食家巷方形饼&#xff0c;顾名思义&#xff0c;其形状呈规整的方形。这种独特的外形并非偶然&#xff0c;而是源于当地传统的制作工艺。制作方形饼的师傅们&#xff0c;精心挑选优质的面粉&#xff0c;加入适量的水和其他配料&#xff0c;揉成光滑的面团。经过一段时间的发…

共享GitLab中CICD自动生成的软件包

0 Preface/Foreword 1 分享软件包地址 为了方便给接收对象方便下载固件&#xff0c;在下载固件时候&#xff0c;而无需打开网页&#xff0c;直接输入地址&#xff0c;弹出的对话框是将固件另存为。 或者进入CICD页面&#xff0c;找到job&#xff0c;在Download的标签上单击右键…

区块链钱包开发:全面功能设计方案解析

区块链钱包是连接用户与区块链世界的核心工具&#xff0c;为用户提供了存储、管理和交易加密资产的便捷途径。随着区块链应用的广泛普及&#xff0c;钱包的功能需求和技术复杂度也在不断增加。如何设计和开发一款功能全面、安全可靠的区块链钱包&#xff0c;成为区块链项目成功…

计算机网络-IPSec VPN工作原理

一、IPSec VPN工作原理 昨天我们大致了解了IPSec是什么&#xff0c;今天来学习下它的工作原理。 IPsec的基本工作流程如下&#xff1a; 通过IKE协商第一阶段协商出IKE SA。 使用IKE SA加密IKE协商第二阶段的报文&#xff0c;即IPsec SA。 使用IPsec SA加密数据。 IPsec基本工作…

“切片赋值”创建列表批量操作“新”方法(Python)

[start:end]切片赋值&#xff0c;扩展了list批量增减元素的操作能力。 (笔记模板由python脚本于2024年12月06日 15:07:56创建&#xff0c;本篇笔记适合研python基础的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;…

电脑无法识别usb设备怎么办?电脑无法识别usb解决方法

usb设备是我们常解除的外部操作以及存储设备&#xff0c;它可以方便用户数据传输以及操作输入。但在使用过程中&#xff0c;大家基本都碰到过电脑无法识别usb设备这种情况。这种情况下&#xff0c;我们应该怎么办呢&#xff1f;下面将为你介绍几种可能的原因和解决方法&#xf…

【机器学习】分类器

在机器学习(Machine Learning&#xff0c;ML)中&#xff0c;分类器泛指算法或模型&#xff0c;用于将输入数据分为不同的类别或标签。分类器是监督学习的一部分&#xff0c;它依据已知的数据集中的特征和标签进行训练&#xff0c;并根据这些学习到的知识对新的未标记数据进行分…

路径规划之启发式算法之十一:布谷鸟搜索算法(Cuckoo Search,CS)

布谷鸟搜索算法&#xff08;Cuckoo Search&#xff0c;CS&#xff09;是一种新兴的自然启发式算法&#xff0c;由剑桥大学的杨新社教授和S.戴布&#xff08;Xin-She Yang和Suash Deb&#xff09;于2009年提出。该算法基于布谷鸟的寄生性育雏&#xff08;巢寄生&#xff09;行为…

Java-JMX (官方文档解读)

JMX 简介 JMX&#xff08;Java Management Extensions&#xff09;是Java平台的一个标准管理框架&#xff0c;自Java 1.5版本起成为Java 平台标准版 (Java SE 平台) 的标准组成部分。JMX 技术提供了一种简单、标准的方法来管理资源&#xff08;例如应用程序、设备和服务&#x…

沃丰科技智能客服在跨境电商独立站中的核心角色

随着全球化进程的加速和互联网技术的不断发展&#xff0c;跨境电商行业蓬勃兴起&#xff0c;为消费者提供了更广阔、更便捷的购物选择。在这样一个竞争激烈的市场环境中&#xff0c;优质的客户服务成为了企业脱颖而出的关键。沃丰科技智能客服凭借其先进的技术和人性化的设计理…

java 日期与时间

Java 的时间 API 是一个非常重要的主题&#xff0c;尤其是 Java 8 引入的 java.time 包&#xff0c;它为日期和时间处理提供了强大的功能。 我们可以按照以下几个主题逐步学习 Java 时间处理&#xff1a; import java.time.LocalDate; import java.time.LocalDateTim…

(ICML-2024)DoRA:权重分解低秩自适应

DoRA&#xff1a;权重分解低秩自适应 Paper是英伟达发表在ICML 2024的工作 Paper Title&#xff1a;DoRA: Weight-Decomposed Low-Rank Adaptation Code&#xff1a; 地址 Abstract 在广泛使用的参数高效微调 (PEFT) 方法中&#xff0c;LoRA 及其变体因避免了额外的推理成本而…