4.5学习

如何编写一次性任务
模拟 1000 万个用户,再去查询

  1. 用可视化界面:适合一次性导入、数据量可控
  2. 写程序:for 循环,建议分批,不要一把梭哈(可以用接口来控制)要保证可控、幂等,注意线上环境和测试环境是有区别的导入 1000 万条,for i 1000w
  3. 执行 SQL 语句:适用于小数据量

for循环插入数据库的问题:
1.建立和释放数据库连接(批量查询解决batch)
2.for循环是绝对线性的,上一条卡住下面就不会执行(并发解决)
并发要注意执行的先后顺序,不要用到非并发类的集合
`
//CPU密集型 核心线程数=CPU - 1

//IO密集型 分配的线程数可以大于CPU核数,下面的这个是数据库在进行插入属于IO密集型

public class InsertUsersTest {
@Resource
private UserService userService;

考点 默认的线程数是多少,最大的线程数是多少,什么情况下会超过40(任务达到10000《=new ArrayBlockingQueue<>(10000),任务队列满了,需要更多的线程,就会慢慢增加到1000.如果增加到1000线程还是有很多任务,可以选择任务策略)
private ExecutorService executorService = new ThreadPoolExecutor(40, 1000, 10000, TimeUnit.MINUTES, new ArrayBlockingQueue<>(10000));
@Test
public void doInsertUsers() {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    long insertNum=100000;
    List<User> userList=new ArrayList<User>();
    for(int i=0;i<insertNum;i++) {
        User user=new User();
        user.setUsername("李白");
        user.setUserAccount("libai");
        user.setAvatarUrl("https://www.keaitupian.cn/cjpic/frombd/0/253/2607983581/3605514878.jpg");
        user.setGender(0);
        user.setUserPassword("12345678");
        user.setPhone("123");
        user.setEmail("123@qq.com");
        user.setTags("[]");
        user.setUserStatus(0);
        user.setUserRole(0);
        user.setPlanetCode("11111111");
        userList.add(user);
    }
    // 20 秒 10 万条
    userService.saveBatch(userList, 10000);
    stopWatch.stop();
    System.out.println(stopWatch.getTotalTimeMillis());
}
@Test
public void doConcurrencyInsertUsers() {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();

    int batchSize = 5000;
    int j = 0;
    List<CompletableFuture<Void>> futureList = new ArrayList<>();
    //20个任务
    for (int i = 0; i < 20; i++) {
        List<User> userList = new ArrayList<>();
        while (true) {
            j++;
            User user=new User();
            user.setUsername("李白");
            user.setUserAccount("libai");
            user.setAvatarUrl("https://www.keaitupian.cn/cjpic/frombd/0/253/2607983581/3605514878.jpg");
            user.setGender(0);
            user.setUserPassword("12345678");
            user.setPhone("123");
            user.setEmail("123@qq.com");
            user.setTags("[]");
            user.setUserStatus(0);
            user.setUserRole(0);
            user.setPlanetCode("11111111");
            userList.add(user);
            if (j % batchSize == 0) {
                break;
            }
        }
        // 异步执行
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println("threadName: " + Thread.currentThread().getName());
            userService.saveBatch(userList, batchSize);
        }, executorService);
        futureList.add(future);
    }
    CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
    stopWatch.stop();
    System.out.println(stopWatch.getTotalTimeMillis());
}

}
`

点击查看代码
public class Main{
	public static void main(String[] args){
		Scanner sc =new Scanner(System.in);
		int n=sc.nextInt();
		int[] a=new int[n];
		for(int i=0;i<n;i++) {
			a[i]=sc.nextInt();
		}
		int l1=sc.nextInt();
		int r1=sc.nextInt();
		int l2=sc.nextInt();
		int r2=sc.nextInt();
		if(r1<=l2) {
			for(int i=l1;i<r1;i++) {
				System.out.print(a[i]+" ");
			}
			if(r1<l2) {
				System.out.print(a[r1]+" ");
			}
		}else if(l1<=l2&&l2<=r1&&r2>=r1){
			if(l1==l2) {
				System.out.println("void");
			}else {
				for(int i=l1;i<l2;i++) {
					System.out.print(a[i]+" ");
				}
			}
		}else if(l2<=l1&&l1<=r2&&r1>=r2){
			if(r1==r2) {
				System.out.println("void");
			}else {
				for(int i=r2+1;i<=r1;i++){
					System.out.print(a[i]+" ");
				}
			}
		}else if(l1<=l2&&r2<=r1){
			for(int i=l1;i<l2;i++) {
				System.out.print(a[i]+" ");
			}
			for(int i=r2+1;i<=r1;i++) {
				System.out.print(a[i]+" ");
			}
		}else if(l2<=l1&&r1<=r2) {
			System.out.print("void");
		}
	}
}

7-7 数组区间差集A-B
分数 10
作者 zzuli
单位 郑州轻工业大学
输入一个整数数组(题目保证数组中的整数不重复),然后输入两个闭区间,区间A[L1, R1]和区间B[L2, R2],L1, R1代表区间A的左/右边界的数组下标;L2, R2代表区间B的左/右边界的数组下标(下标从0开始,且题目保证下标均在有效范围内不会越界)。输出由这两个区间形成的差集(A-B)的数值。
输入格式:
一个整数n(n不大于20),然后输入n个整数。
最后输入4个整数,分别代表区间A和区间B的左边界和右边界的下标,顺序为:L1 R1 L2 R2
输出格式:
按原数组的顺序依次输出两个区间差集(A-B)中的数值,每个数值后面一个空格。
如果是空集,则输出void
输入样例:
20 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 0 9 4 12
输出样例:
11 12 13 14
所有区间情况

按照图写出所有区间情况

由于数组中不存在重复的数值,可以用Set来处理区间B,找到在A中而不在B中的集合会更方便
List<Integer> result = new ArrayList<>(); for (int num : listA) { if (!setB.contains(num)) { result.add(num); } }

posted @ 2025-04-05 23:19  虾11  阅读(26)  评论(0)    收藏  举报