Java面试——场景题

news/2024/10/19 13:33:36/

1.如何分批处理数据?

1.使用LIMIT和OFFSET子句: 这是最常用的分批查询方法。例如,你可以使用以下SQL语句来分批查询数据:

java">SELECT * FROM your_table LIMIT 1000 OFFSET 0;

分批查询到的数据在后端进行处理,达到分批处理数据的效果。

2.使用多线程的方式: 如果你需要用多线程分批处理数据,并且数据所在表的主键id是递增的,可以使用取模的方式进行分批查询。例如:

java">import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;public class DatabaseUtils {// 数据库连接信息private static final String URL = "jdbc:mysql://localhost:3306/your_database";private static final String USER = "your_username";private static final String PASSWORD = "your_password";// 获取数据库连接public static Connection getConnection() throws SQLException {return DriverManager.getConnection(URL, USER, PASSWORD);}// 异步查询数据库的方法//第一个参数表示偏移量,表示当前已经查询到的数据id//第二个参数表示从当前偏移量开始,查询多少条数据public static CompletableFuture<List<String>> queryBatchAsync(int offset, int limit) {// 使用CompletableFuture.supplyAsync来异步执行数据库查询return CompletableFuture.supplyAsync(() -> {List<String> results = new ArrayList<>();try (Connection conn = getConnection();PreparedStatement stmt = conn.prepareStatement("SELECT id, data FROM your_table LIMIT ? OFFSET ?")) {// 设置查询的LIMIT和OFFSETstmt.setInt(1, limit);stmt.setInt(2, offset);// 执行查询try (ResultSet rs = stmt.executeQuery()) {// 遍历结果集,将结果添加到列表中while (rs.next()) {results.add(rs.getString("id") + ": " + rs.getString("data"));}}} catch (SQLException e) {// 如果发生异常,抛出运行时异常throw new RuntimeException(e);}// 返回查询结果return results;});}
}

       这个类只是负责连接数据库,以及一个异步查询数据库的方法。注意这个方法的返回结果是CompletableFuture<List<String>>,返回一个异步任务,异步任务中的返回结果是根据偏移量和批量查询条数的查询结果,封装成一个list集合。注意数据库中的id应该是自增的

java">import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class MultiThreadedBatchProcessing {public static void main(String[] args) {// 假设我们有1000条记录需要处理,每批处理100条记录int totalRecords = 1000;int batchSize = 100;// 创建一个有10个线程的线程池ExecutorService executor = Executors.newFixedThreadPool(10);// 创建一个CompletableFuture数组来存储每个批次的异步任务CompletableFuture<?>[] futures = new CompletableFuture[10];// 循环创建并启动每个批次的异步查询任务for (int i = 0; i < totalRecords; i += batchSize) {int offset = i; // 计算当前批次的起始位置int limit = batchSize; // 每批处理的记录数// 启动异步查询任务futures[i / batchSize] = DatabaseUtils.queryBatchAsync(offset, limit).thenAccept(batchResult -> {// 处理每个批次的结果for (String record : batchResult) {System.out.println(record);}});}// 使用CompletableFuture.allOf等待所有批次的任务完成CompletableFuture.allOf(futures).thenRun(() -> {// 所有批次处理完成后,关闭线程池System.out.println("All batches have been processed.");executor.shutdown();}).exceptionally(e -> {// 如果发生异常,打印错误信息,并尝试紧急关闭线程池System.err.println("An error occurred: " + e.getMessage());executor.shutdownNow();return null;});}
}

追问:若多线程分批查询过程中有数据插入或者删除,则数据缺漏,如何解决问题?


        使用事务保证数据一致性: 可以通过事务来确保数据的一致性。在事务中执行查询、插入或删除操作,如果中途发生错误,可以通过回滚操作来撤销所有已执行的步骤,确保数据的完整性。这样可以避免因并发操作导致的数据不一致问题。


追问:多线程共享事务存在问题,不合适,有其他方式吗?

  1. 消息队列和异步重试:在执行更新数据库和删除缓存的操作时,可以使用消息队列和异步重试机制。这样,即使某个操作失败,也可以通过消息队列进行补偿操作,确保数据的最终一致性。
  2. 分布式锁:在高并发场景下,可以使用分布式锁来保证同一时间只有一个线程能修改特定的数据行。这可以通过在应用程序层面采用分布式锁、Redis等中间件实现锁机制来完成


http://www.ppmy.cn/news/1538803.html

相关文章

代码训练营 day31|LeetCode 455,LeetCode 376,LeetCode 53

前言 这里记录一下陈菜菜的刷题记录&#xff0c;主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕&#xff0c;一年车企软件开发经验 代码能力&#xff1a;有待提高 常用语言&#xff1a;C 系列文章目录 第31天 &#xff1a;第八章 贪心算法 part01 文章目录 前言系…

SQL NULL 值

SQL NULL 值 概述 在SQL&#xff08;Structured Query Language&#xff09;中&#xff0c;NULL值是一个特殊的标记&#xff0c;用于表示缺失或未知的值。理解NULL值的概念对于数据库设计和查询非常重要&#xff0c;因为它们可以影响查询的结果和性能。本文将详细介绍SQL中NU…

大数据笔记之 Hadoop 常用 Shell 命令(一)

文章目录 前言一、HDFS上的操作1.1 查看文件或文件夹1.2 修改文件或目录权限1.3 创建或删除文件夹1.4 移动或创建文件1.5 信息统计1.6 设置 hdfs 中文件的副本数量 二、在本地上传或下载的操作2.1 从本地上传文件到HDFS2.2 从HDFS下载文件到本地 总结 前言 前无言 一、HDFS上的…

树莓派应用--AI项目实战篇来啦-3.OpenCV 读取写入和显示图像

1. 介绍 在计算机视觉和图像处理领域&#xff0c;读取和显示图像是最基础且常见的操作之一&#xff0c;OpenCV作为一个强大的计算机视觉库&#xff0c;提供了丰富的功能来处理图像数据。 读取、显示和写入图像是图像处理和计算机视觉的基础&#xff0c;即使裁剪、调整大…

【刷题8】连续数组、矩阵区域和

目录 一、连续数组二、矩阵区域和 一、连续数组 题目&#xff1a; 思路&#xff1a;前缀和哈希表 问题转换&#xff1a;子数组要0和1的个数相同&#xff0c;把0变成-1&#xff0c;-1和1的数量相同&#xff0c;不就是这个子数组的元素和为0&#xff0c;即和为k的子数组》和为…

前端开发设计模式——装饰器模式

目录 一、装饰器模式的定义和特点 1.定义 2.特点 二、装饰器模式的实现方式 1.在原生JS中实现&#xff08;以类的形式为例&#xff09; 2、在Vue中实现&#xff08;以指令和混入为例&#xff09; 2.1、指令方式实现装饰功能 2.2、混入方式实现装饰功能 三、装饰器模式的…

ArgoCD 与 Amazon EKS 结合实战

在当今快速发展的云原生世界中,持续部署和基础设施即代码已成为不可或缺的实践。ArgoCD 作为一个强大的 Kubernetes 持续部署工具,结合 Amazon EKS (Elastic Kubernetes Service) 这一成熟的托管 Kubernetes 服务,为开发者和运维团队提供了一个强大的组合。本文将深入探讨如…

IP报文格式、IPv6概述

IPv4报文格式 IPv4报文首部长度至少为20字节(没有可选字段和填充的情况下)&#xff0c;下面来逐一介绍首部各个字段的含义 Version版本&#xff1a;表示采用哪一种具体的IP协议&#xff0c;对于IPv4来说该字段就填充4以表示&#xff0c;如果是IPv6就填充6IHL首部长度&#xff…