[MapReduce数据倾斜如何解决?]

目录

🍇前言:

🍇MapReduce数据倾斜的原因可能有以下几个:

🍇为了解决MapReduce数据倾斜问题,可以采取一些策略,例如:

🍇数据预处理:在MapReduce任务之前,对数据进行预处理,使得数据分布更加均匀。

🍇可以进一步优化数据预处理的代码,例如:

🍇动态调整平均值 的数据预处理代码:

🍇上面这段代码的描述:

🍇数据重分区:在MapReduce任务中,对数据进行重分区,使得数据分布更加均匀。

🍇Combiner函数:在MapReduce任务中,使用Combiner函数对Mapper节点输出的数据进行合并,减少数据传输量。

🍇优化:

🍇动态调整Reducer数量:在MapReduce任务中,根据数据分布情况动态调整Reducer节点的数量,使得每个节点处理的数据量更加均匀。 

 🍇随机化键:在MapReduce任务中,对键进行随机化处理,使得键的分布更加均匀。


🍇前言:

   记录小笔记,主要看看思路

🍇MapReduce数据倾斜的原因可能有以下几个:

  1. 数据分布不均:在MapReduce任务中,数据的分布可能不均匀,导致某些Mapper节点处理的数据量远大于其他节点,从而导致数据倾斜。

  2. 键分布不均:在MapReduce任务中,如果键的分布不均匀,也会导致某些Reducer节点处理的数据量远大于其他节点,从而导致数据倾斜。

  3. 数据倾斜的键:在MapReduce任务中,如果某些键的数据量远大于其他键,也会导致数据倾斜。

  4. 数据倾斜的值:在MapReduce任务中,如果某些键对应的值的数据量远大于其他键对应的值,也会导致数据倾斜。

  5. 数据倾斜的计算逻辑:在MapReduce任务中,如果某些计算逻辑导致某些节点的计算量远大于其他节点,也会导致数据倾斜。

🍇为了解决MapReduce数据倾斜问题,可以采取一些策略,例如:

  1. 数据预处理:在MapReduce任务之前,对数据进行预处理,使得数据分布更加均匀。

  2. 数据重分区:在MapReduce任务中,对数据进行重分区,使得数据分布更加均匀。

  3. Combiner函数:在MapReduce任务中,使用Combiner函数对Mapper节点输出的数据进行合并,减少数据传输量。

  4. 动态调整Reducer数量:在MapReduce任务中,根据数据分布情况动态调整Reducer节点的数量,使得每个节点处理的数据量更加均匀。

  5. 随机化键:在MapReduce任务中,对键进行随机化处理,使得键的分布更加均匀。

  6. 采用其他计算框架:在MapReduce任务中,采用其他计算框架,例如Spark、Flink等,可以更好地处理数据倾斜问题。

🍇数据预处理:在MapReduce任务之前,对数据进行预处理,使得数据分布更加均匀。

import java.io.*;
import java.util.*;

public class DataPreprocessor {
    public static void main(String[] args) throws IOException {
        // 读取原始数据文件
        BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 计算每个键的出现次数
        Map<String, Integer> counts = new HashMap<>();
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            counts.put(key, counts.getOrDefault(key, 0) + count);
        }

        // 计算每个键的平均出现次数
        int total = 0;
        for (int count : counts.values()) {
            total += count;
        }
        double avg = (double) total / counts.size();

        // 计算每个键需要复制的次数
        Map<String, Integer> copies = new HashMap<>();
        for (Map.Entry<String, Integer> entry : counts.entrySet()) {
            String key = entry.getKey();
            int count = entry.getValue();
            int numCopies = (int) Math.ceil(count / avg);
            copies.put(key, numCopies);
        }

        // 生成新的数据文件
        BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            int numCopies = copies.get(key);
            for (int i = 0; i < numCopies; i++) {
                writer.write(key + "	" + count + "\n");
            }
        }
        writer.close();
    }
}
  • 这个示例代码读取一个原始数据文件input.txt,并计算每个键的出现次数。然后,它计算每个键的平均出现次数,并根据这个平均值计算每个键需要复制的次数。最后,它生成一个新的数据文件output.txt,其中每个键都被复制了适当的次数,以使得数据分布更加均匀。
🍇可以进一步优化数据预处理的代码,例如:
  1. 使用多线程:在处理大量数据时,可以使用多线程来加速数据预处理过程。可以将数据分成多个块,每个线程处理一个块,然后将结果合并。

  2. 动态调整平均值:在计算每个键的平均出现次数时,可以动态调整平均值,使得每个键需要复制的次数更加均匀。

  3. 采用其他算法:除了计算每个键的平均出现次数之外,还可以采用其他算法来计算每个键需要复制的次数,例如基于负载均衡的算法、基于采样的算法等。

  4. 使用分布式计算框架:在处理大量数据时,可以使用分布式计算框架,例如Hadoop、Spark等,来加速数据预处理过程。

  5. 优化数据结构:在处理大量数据时,可以使用更加高效的数据结构,例如哈希表、红黑树等,来加速数据处理过程。

  6. 优化IO操作:在读取和写入数据时,可以使用缓冲区、批量读写等技术,来优化IO操作,加速数据处理过程。

🍇动态调整平均值 的数据预处理代码:
import java.io.*;
import java.util.*;

public class DataPreprocessor {
    public static void main(String[] args) throws IOException {
        // 读取原始数据文件
        BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 计算每个键的出现次数
        Map<String, Integer> counts = new HashMap<>();
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            counts.put(key, counts.getOrDefault(key, 0) + count);
        }

        // 计算每个键的平均出现次数
        int total = 0;
        for (int count : counts.values()) {
            total += count;
        }
        double avg = (double) total / counts.size();

        // 计算每个键需要复制的次数
        Map<String, Integer> copies = new HashMap<>();
        for (Map.Entry<String, Integer> entry : counts.entrySet()) {
            String key = entry.getKey();
            int count = entry.getValue();
            double ratio = (double) count / avg;
            int numCopies = (int) Math.ceil(ratio);
            while (numCopies * count > (total + count) / (copies.size() + 1)) {
                numCopies--;
            }
            copies.put(key, numCopies);
            total += numCopies * count;
        }

        // 生成新的数据文件
        BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"));
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            int numCopies = copies.get(key);
            for (int i = 0; i < numCopies; i++) {
                writer.write(key + "	" + count + "\n");
            }
        }
        writer.close();
    }
}
  • 这个示例代码在计算每个键需要复制的次数时,使用了动态调整平均值的方法。具体来说,它首先计算每个键的平均出现次数,然后根据每个键的出现次数和平均出现次数的比例计算每个键需要复制的次数。然后,它根据当前的总数据量和键的数量,动态调整每个键需要复制的次数,使得每个键需要复制的次数更加均匀。最后,它生成一个新的数据文件,其中每个键都被复制了适当的次数,以使得数据分布更加均匀。
🍇上面这段代码的描述:
  • 计算每个键的出现次数,使用一个哈希表来存储每个键的出现次数。

  • 计算每个键的平均出现次数,将所有键的出现次数相加,然后除以键的数量。

  • 根据每个键的出现次数和平均出现次数的比例计算每个键需要复制的次数,使用一个哈希表来存储每个键需要复制的次数。

  • 动态调整每个键需要复制的次数,使得每个键需要复制的次数更加均匀。具体来说,它使用一个循环来不断调整每个键需要复制的次数,直到满足以下条件:

    在每次循环中,它将每个键需要复制的次数减1,直到满足上述条件为止。

    • 每个键需要复制的次数乘以该键的出现次数不超过当前总数据量除以键的数量加1。

    • 每个键需要复制的次数不能小于1。

  • 生成新的数据文件,对于每个键,将它复制适当的次数,并将复制后的数据写入新的数据文件中。

🍇数据重分区:在MapReduce任务中,对数据进行重分区,使得数据分布更加均匀。

import java.io.*;
import java.util.*;

public class DataRepartitioner {
    public static void main(String[] args) throws IOException {
        // 读取原始数据文件
        BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 计算每个键的哈希值
        Map<String, Integer> hashes = new HashMap<>();
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int hash = key.hashCode();
            hashes.put(key, hash);
        }

        // 计算新的分区号
        int numPartitions = 10; // 新的分区数
        Map<Integer, Integer> partitionCounts = new HashMap<>();
        for (int hash : hashes.values()) {
            int partition = Math.abs(hash) % numPartitions;
            partitionCounts.put(partition, partitionCounts.getOrDefault(partition, 0) + 1);
        }
        int avgCount = lines.size() / numPartitions;
        int maxCount = (int) Math.ceil(avgCount * 1.5);
        int minCount = (int) Math.floor(avgCount * 0.5);
        Map<Integer, Integer> newPartitions = new HashMap<>();
        int total = 0;
        for (int i = 0; i < numPartitions; i++) {
            int count = partitionCounts.getOrDefault(i, 0);
            if (count > maxCount) {
                count = maxCount;
            } else if (count < minCount) {
                count = minCount;
            }
            newPartitions.put(i, count);
            total += count;
        }

        // 生成新的数据文件
        BufferedWriter[] writers = new BufferedWriter[numPartitions];
        for (int i = 0; i < numPartitions; i++) {
            writers[i] = new BufferedWriter(new FileWriter("output_" + i + ".txt"));
        }
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int hash = hashes.get(key);
            int partition = Math.abs(hash) % numPartitions;
            int count = newPartitions.get(partition);
            BufferedWriter writer = writers[partition];
            writer.write(l + "\n");
            count--;
            newPartitions.put(partition, count);
            total--;
            if (total == 0) {
                break;
            }
        }
        for (int i = 0; i < numPartitions; i++) {
            writers[i].close();
        }
    }
}
  • 这个示例代码读取一个原始数据文件input.txt,并计算每个键的哈希值。然后,它根据哈希值将数据重分区,使得数据分布更加均匀。具体来说,它首先计算每个键的哈希值,并将哈希值对新的分区数取模,得到每个键的新的分区号。然后,它计算每个分区中键的数量,根据每个分区中键的数量动态调整每个分区的大小,使得每个分区中键的数量更加均匀。最后,它将数据写入新的数据文件中,每个分区对应一个新的数据文件。

🍇Combiner函数:在MapReduce任务中,使用Combiner函数对Mapper节点输出的数据进行合并,减少数据传输量。

import java.io.*;
import java.util.*;

public class DataCombiner {
    public static void main(String[] args) throws IOException {
        // 读取Mapper节点输出的数据文件
        BufferedReader reader = new BufferedReader(new FileReader("mapper_output.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 使用Combiner函数对数据进行合并
        Map<String, Integer> counts = new HashMap<>();
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            counts.put(key, counts.getOrDefault(key, 0) + count);
        }

        // 生成新的数据文件
        BufferedWriter writer = new BufferedWriter(new FileWriter("combiner_output.txt"));
        for (Map.Entry<String, Integer> entry : counts.entrySet()) {
            String key = entry.getKey();
            int count = entry.getValue();
            writer.write(key + "	" + count + "\n");
        }
        writer.close();
    }
}
  • 这个示例代码读取一个Mapper节点输出的数据文件mapper_output.txt,并使用Combiner函数对数据进行合并,减少数据传输量。具体来说,它将相同键的数据进行合并,并计算它们的总数。然后,它将合并后的数据写入新的数据文件combiner_output.txt中。
  • 在MapReduce任务中,Combiner函数通常用于在Mapper节点输出数据之后,在数据传输到Reducer节点之前对数据进行合并。这样可以减少数据传输量,提高任务的执行效率。Combiner函数的实现方式与Reducer函数类似,但是它运行在Mapper节点上,而不是Reducer节点上。因此,Combiner函数的输入和输出类型必须与Mapper函数的输出和Reducer函数的输入类型相同。

🍇优化:

import java.io.*;
import java.util.*;

public class DataCombiner {
    public static void main(String[] args) throws IOException {
        // 读取Mapper节点输出的数据文件
        BufferedReader reader = new BufferedReader(new FileReader("mapper_output.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 使用Combiner函数对数据进行合并
        Map<String, Integer> counts = new HashMap<>();
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            counts.put(key, counts.getOrDefault(key, 0) + count);
        }

        // 生成新的数据文件
        BufferedWriter writer = new BufferedWriter(new FileWriter("combiner_output.txt"));
        for (Map.Entry<String, Integer> entry : counts.entrySet()) {
            String key = entry.getKey();
            int count = entry.getValue();
            writer.write(key + "	" + count + "\n");
        }
        writer.close();
    }
}
  • 使用了缓存来减少文件读写次数。在读取Mapper节点输出的数据文件时,它使用了一个字符串列表来缓存读取的数据,以减少文件读取次数。在写入新的数据文件时,它使用了一个缓冲区来缓存写入的数据,以减少文件写入次数。

  • 使用了Java 8的Lambda表达式来简化代码。在生成新的数据文件时,它使用了Java 8的Lambda表达式来简化代码,使得代码更加简洁易读。

  • 使用了Java 7的try-with-resources语句来自动关闭文件。在读取和写入文件时,它使用了Java 7的try-with-resources语句来自动关闭文件,以避免资源泄漏。

🍇动态调整Reducer数量:在MapReduce任务中,根据数据分布情况动态调整Reducer节点的数量,使得每个节点处理的数据量更加均匀。 

import java.io.*;
import java.util.*;

public class ReducerCountOptimizer {
    public static void main(String[] args) throws IOException {
        // 读取Mapper节点输出的数据文件
        BufferedReader reader = new BufferedReader(new FileReader("mapper_output.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 计算每个键的出现次数
        Map<String, Integer> counts = new HashMap<>();
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            counts.put(key, counts.getOrDefault(key, 0) + count);
        }

        // 计算每个Reducer节点需要处理的键的数量
        int numReducers = 10; // 初始Reducer节点数量
        int totalKeys = counts.size();
        int avgKeys = totalKeys / numReducers;
        int maxKeys = (int) Math.ceil(avgKeys * 1.5);
        int minKeys = (int) Math.floor(avgKeys * 0.5);
        Map<Integer, Integer> reducerCounts = new HashMap<>();
        int total = 0;
        for (int i = 0; i < numReducers; i++) {
            int count = 0;
            for (Map.Entry<String, Integer> entry : counts.entrySet()) {
                if (count >= maxKeys) {
                    break;
                }
                String key = entry.getKey();
                int value = entry.getValue();
                if (value > 0) {
                    count++;
                    reducerCounts.put(i, reducerCounts.getOrDefault(i, 0) + 1);
                    counts.put(key, value - 1);
                }
            }
            total += count;
            if (total >= totalKeys) {
                break;
            }
        }

        // 生成新的数据文件
        BufferedWriter[] writers = new BufferedWriter[numReducers];
        for (int i = 0; i < numReducers; i++) {
            writers[i] = new BufferedWriter(new FileWriter("reducer_" + i + ".txt"));
        }
        for (String l : lines) {
            String[] parts = l.split("	");
            String key = parts[0];
            int count = Integer.parseInt(parts[1]);
            for (int i = 0; i < numReducers; i++) {
                int reducerCount = reducerCounts.getOrDefault(i, 0);
                if (reducerCount > 0 && count > 0) {
                    BufferedWriter writer = writers[i];
                    writer.write(l + "\n");
                reducerCounts.put(i, reducerCount - 1);
                count--;
            }
        }
    }
    for (int i = 0; i < numReducers; i++) {
        writers[i].close();
    }
}
                   
  • 这个示例代码读取一个Mapper节点输出的数据文件`mapper_output.txt`,并根据数据分布情况动态调整Reducer节点的数量,使得每个节点处理的数据量更加均匀。具体来说,它首先计算每个键的出现次数,并根据出现次数动态调整Reducer节点的数量,使得每个节点处理的键的数量更加均匀。然后,它将数据写入新的数据文件中,每个Reducer节点对应一个新的数据文件。 在MapReduce任务中,动态调整Reducer节点的数量可以使得每个节点处理的数据量更加均匀,从而提高任务的执行效率。这个示例代码使用了一种简单的贪心算法来实现动态调整Reducer节点的数量  

 🍇随机化键:在MapReduce任务中,对键进行随机化处理,使得键的分布更加均匀。

import java.io.*;
import java.util.*;
import java.util.concurrent.*;

public class KeyRandomizer {
    public static void main(String[] args) throws IOException, InterruptedException {
        // 读取Mapper节点输出的数据文件
        BufferedReader reader = new BufferedReader(new FileReader("mapper_output.txt"));
        List<String> lines = new ArrayList<>();
        String line;
        while ((line = reader.readLine()) != null) {
            lines.add(line);
        }
        reader.close();

        // 对键进行随机化处理
        int numThreads = 4; // 线程数量
        ExecutorService executor = Executors.newFixedThreadPool(numThreads);
        List<Future<List<String>>> futures = new ArrayList<>();
        int chunkSize = lines.size() / numThreads;
        for (int i = 0; i < numThreads; i++) {
            int start = i * chunkSize;
            int end = (i == numThreads - 1) ? lines.size() : (i + 1) * chunkSize;
            List<String> chunk = lines.subList(start, end);
            Callable<List<String>> task = new KeyRandomizerTask(chunk);
            Future<List<String>> future = executor.submit(task);
            futures.add(future);
        }
        List<String> randomizedLines = new ArrayList<>();
        for (Future<List<String>> future : futures) {
            randomizedLines.addAll(future.get());
        }
        executor.shutdown();

        // 生成新的数据文件
        BufferedWriter writer = new BufferedWriter(new FileWriter("randomized_output.txt"));
        for (String l : randomizedLines) {
            writer.write(l + "\n");
        }
        writer.close();
    }

    private static class KeyRandomizerTask implements Callable<List<String>> {
        private final List<String> lines;

        public KeyRandomizerTask(List<String> lines) {
            this.lines = lines;
        }

        @Override
        public List<String> call() throws Exception {
            Map<Integer, List<String>> buckets = new HashMap<>();
            for (String l : lines) {
                String[] parts = l.split("	");
                String key = parts[0];
                int hash = key.hashCode();
                int bucket = Math.abs(hash) % 100;
                List<String> bucketLines = buckets.getOrDefault(bucket, new ArrayList<>());
                bucketLines.add(l);
                buckets.put(bucket, bucketLines);
            }
            List<String> randomizedLines = new ArrayList<>();
            for (List<String> bucketLines : buckets.values()) {
                Collections.shuffle(bucketLines);
                randomizedLines.addAll(bucketLines);
            }
            return randomizedLines;
        }
    }
}

 

  • 这个示例代码读取一个Mapper节点输出的数据文件mapper_output.txt,并对键进行随机化处理,使得键的分布更加均匀。具体来说,它将键哈希到100个桶中的一个,并将每个桶中的键进行随机化处理。然后,它将随机化处理后的数据写入新的数据文件中。
  • 在MapReduce任务中,对键进行随机化处理可以使得键的分布更加均匀,从而提高任务的执行效率。这个示例代码使用了多线程来实现对键的随机化处理,以提高代码的性能。具体来说,它将数据分成多个块,并使用多个线程来处理每个块。每个线程将数据分配到100个桶中的一个,并对每个桶中的数据进行随机化处理。最后,它将随机化处理后的数据合并到一起,并写入新的数据文件中。

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

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

相关文章

1.1 编写一个简单的C++程序

博主介绍&#xff1a;爱打游戏的计算机专业学生 博主主页&#xff1a;夏驰和徐策 所属专栏&#xff1a;夏驰和徐策带你从零开始学C 1.1.0 这段话告诉我们什么&#xff1f; 这段话解释了一个C程序中的main函数的基本结构和功能。 它告诉我们以下几点&#xff1a; 1. C程序的…

Python爬取城市天气数据,并作数据可视化

1.爬取广惠河深2022-2024年的天气数据 import requests # 发送请求要用的模块 需要额外安装的 import parsel import csvf open(广-惠-河-深天气.csv, modea, encodingutf-8, newline) csv_writer csv.writer(f) csv_writer.writerow([日期, 最高温度, 最低温度, 天气,…

深入理解深度学习——GPT(Generative Pre-Trained Transformer):GPT-3与Few-shot Learning

分类目录&#xff1a;《深入理解深度学习》总目录 相关文章&#xff1a; GPT&#xff08;Generative Pre-Trained Transformer&#xff09;&#xff1a;基础知识 GPT&#xff08;Generative Pre-Trained Transformer&#xff09;&#xff1a;在不同任务中使用GPT GPT&#x…

对英雄联盟英雄属性数据的预处理及相似度矩阵计算

目录 一、引言 二、任务1 1、填充缺失值 2、用中位数填充“生命值”属性列缺失值 3、 用均值填充“生命值”属性列缺失值 三、任务2 注&#xff1a;英雄联盟英雄属性数据资源可在博客资源中自行获取。 一、引言 英雄联盟作为一款古早的刀塔游戏&#xff0c;可谓之刀塔游…

[golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例

一.go-micro框架 前言 上一节讲解了 GRPC微服务集群 Consul集群 grpc-consul-resolver相关的案例,知道了微服务之间通信采用的 通信协议&#xff0c;如何实现 服务的注册和发现&#xff0c;搭建 服务管理集群&#xff0c;以及服务与服务之间的 RPC通信方式,具体的内容包括: pro…

聊聊微服务到底该如何划分

背景 现在动不动就是微服务架构&#xff0c;但是微服务划分的合理与否会极大的影响开发过程中的复杂度&#xff0c;划分的重要性不言而喻&#xff0c;但是在微服务划分这条路上并没有银弹&#xff0c;有的说DDD可以解决微服务的划分问题&#xff0c;吕哥想说的是那只是理论上的…

端午作业1

只要文件存在&#xff0c;就会有唯一对应的inode号&#xff0c;且相应的会存在一个struct inode结构体。在应用层通过open&#xff08;&#xff09;打开一个设备文件&#xff0c;会对应产生一个inode号&#xff0c;通过inode号可以找到文件的inode结构体 根据inode结构体中文件…

JMU20 软件工程经济学 复习总结

文章目录 碎碎念0. 基准收益率 i1. 现金流量图2. 净现值 NPV&#xff0c;内部收益率 IRR3. 单利&#xff0c;复利计算4. 等额年金NAV5. 动态回收期 P t ′ P_t Pt′​6. 固定资产折旧 [书P44]7. 增值税8. 软件行业增值税的即征即退9. 利息备付率 ICR&#xff0c;偿债备付率 DSC…

C语言学习(二十六)---指针练习题(二)

在上节的内容中&#xff0c;我们进一步学习了有关指针的内容&#xff0c;并做了一些关于指针的题目&#xff0c;今天我们将继续练习一些指针的题目&#xff0c;以便大家更好的理解和掌握指针的知识&#xff0c;好了&#xff0c;话不多说&#xff0c;开整&#xff01;&#xff0…

GreasyFork+Github

GreasyForkGithub 好长时间没用 GreasyFork 了&#xff0c;最近在刷 Spring Boot 的各种知识点&#xff0c;其中很大时间都在学习 baeldung.com 这个站点。不知道是因为最近刷的勤了还是怎么的&#xff0c;这个网站经常会弹出一个“让我关闭广告阻拦插件”的提示框&#xff0c…

MongoDB集群管理(三)

MongoDB集群管理 集群介绍 为什么使用集群 随着业务数据和并发量的增加&#xff0c;若只使用一台MongoDB服务器&#xff0c;存在着断电和数据风险的问题&#xff0c;故采用Mongodb复制集的方式&#xff0c;来提高项目的高可用、安全性等性能。 MongoDB复制是将数据同步到多个…

超简单 display:flex教学

display 弹性盒子解释 Flex是Flexible Box的缩写&#xff0c;意为"弹性布局”&#xff0c;用来为盒状模型提供最大的灵活性。 它的作用&#xff1a; 它能够更加高效方便的控制元素的对齐、排列。 可以自动计算布局内元素的尺寸&#xff0c;无论这个元素的尺寸是固定的还是…

学习mysql

Mysql SQL语言的规则与规范SQL大小写规范注释数据导入指令 基本的SELECT语句SELECT.列的别名去掉重复行空值参与运算着重号(当有表名是关键字时)显示表结构where 运算符算术运算符 比较运算符号性运算符非符号形运算符空运算符非空运算符最小值运算符最大值运算符BETWEEN AND运…

Java的理论知识部分

文章目录 前言 一、Java的发展 1.1、Java的出现 1.2、Java官方网址 1.3、Java的平台 1.4、Java各版本新加的内容 1.5、java特点 1.6、Java的三种运行机制 1.7、Java的编译与运行 1.8、补充内容——华为鲲鹏jdk以及鲲鹏计算 二、面向对象程序编程 2.1、对象与类 2.2、Ja…

软考:软件工程:面向对象技术与UML,时序图,用例图,类对象,封装,继承,多态

软考&#xff1a;软件工程: 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &#xff08;1&#…

Web3 将 MetaMask添加入谷歌浏览器 扩展程序中

Web3到现在理论这段是说的有点太多了 那么 我们先来看个东西 叫 MetaMask 这个在我们项目开发过程中需要使用 MetaMask是一个开源的以太坊的一个钱包 那么 钱包肯定就是用来管理数据资产的 MetaMask 是以一个浏览器插件形式存在的 它可以直接连接到以太坊的网络中来管理我们…

【软件工程】软件工程期末考试试卷

瀑布模型把软件生命周期划分为八个阶段&#xff1a;问题的定义、可行性研究、软件需求分析、系统总体设计、详细设计、编码、测试和运行、维护。八个阶段又可归纳为三个大的阶段&#xff1a;计划阶段、开发阶段和( C)。 A、详细计划 B、可行性分析 C、 运行阶段 D、 测试与排…

【运维】服务器系统安装 -- 服务器版

目录 一、环境 二、ubuntu 三、启动u盘制作 Stage 1&#xff1a;下载balena&#xff0c;制作U盘启动工具 Stage 2&#xff1a;下载Ubuntu 系统镜像&#xff08;参考上一节&#xff1a;Ubuntu 22.04.2 LTS &#xff09; Stage 3&#xff1a;将镜像写入到U盘 四、设置开启…

【Visual Studio】Qt 的实时绘图曲线功能,使用 C++ 语言,配合 Qt 开发串口通信界面

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 战斗背景&#xff1a;做了个串口接收界面&#xff0c;用来接收传输过来的信号。但是光用数字显示太单调&#xff0c;需要用图线显示出来。 战略目标&#x…

腾讯云服务器镜像市场快速搭建WordPress博客网站教程

通过腾讯云服务器的镜像市场搭建WordPress网站非常简单&#xff0c;不需要手动配置WP所需的Web环境&#xff0c;一键即可安装WordPress博客&#xff0c;腾讯云百科使用腾讯云服务器通过镜像市场的WordPress镜像搭建WP网站教程&#xff1a; 目录 腾讯云服务器通过市场镜像安装…
最新文章