笔试真题-2023年用友集团秋招Java岗笔试-A

真题链接:用友校招笔试真题_Java工程师_牛客网

git branch -a 查看所有分支信息

git branch -r 查看所有远程分支

git branch 只显示本地分支

git branch -d 用于删除分支

信号量 = 可用资源数 - 等待资源进程数

正确答案为B;

装饰模式是一种结构型设计模式,它的主要特点是:

  1. 可以动态地给对象增加功能
  2. 比继承更灵活
  3. 遵循开闭原则
  4. 不改变原有对象的基础上进行功能扩展

脏读:在同步启动的A、B两个事务中,A事务执行读操作,读到原始数据,B事务执行写操作修改原始数据,A事务再次执行读操作,能够读到B事务未提交的事务修改,所以为脏读。【读未提交,最低级别,任何情况都无法保证,所以会出现脏读、不可重复读、幻读】

不可重复读:在同步启动的A、B两个事务中,A事务执行读操作,读到原始数据,B事务执行写操作修改原始数据,B事务提交事务。A事务再次执行读操作,读取到B提交事务修改后的数据,导致在A事务中两次读取数据不一致,则为不可重复读。【读已提交,能够解决脏读,但是像这样无法解决不可重复读】

幻读:在同步启动的A、B两个事务中,A事务执行读操作,读到原始数据,B事务执行写操作修改原始数据并且新增一条数据,B事务提交事务。A事务再次执行读操作,读到没有经过B事务执行写操作修改的原始数据,且没有读到最新插入的数据,导致A事务两次读取的数据除了修改外不是最新的数据,则为幻读。【可重复读,能够解决脏读、不可重复读,但是无法解决幻读】

串行化,可以解决脏读、不可重复读、幻读等所有问题,因为在这个机制下只有一个事务能够执行并锁定。

JDK1.8中ConcurrentHashMap采用了数组+链表+红黑树的复合数据结构,这是其内部存储的基本架构。 当哈希冲突时,会首先使用链表来存储,当链表长度超过阈值(默认为8)时,链表会转换为红黑树,以提高检索效率。【初始状态是数组,当发生哈希冲突时使用链表,当链表长度超过阈值后转换为红黑树,这三种结构共同组成了完整的存储体系。】

protected 访问修饰符在Java中具有特定的访问权限范围:

    1. 类内可访问 - 在定义protected成员的类内部可以直接访问
    2. 包内可访问 - 同一个包中的其他类可以访问protected成员
    3. 子类可访问 - 不同包中的子类可以访问父类的protected成员
    4. 任意类不可访问 - 非以上三种情况的其他类无法访问protected成员

在Java线程编程中,setDaemon()和join()方法的使用时机非常重要,setDaemon(true)必须在线程启动前调用,这是由Java线程的生命周期决定的。一旦线程启动后,就不能再修改它的守护线程状态。

  • 守护线程是为其他线程服务的线程,当所有非守护线程结束时,守护线程会自动终止
  • join()方法常用于线程同步,可以让一个线程等待另一个线程完成后再继续执行

join()方法是用来等待线程结束的,它的调用位置应该在需要等待的线程代码中,而不是必须在start()之前。实际上,join()通常在start()之后调用,因为它的作用是等待目标线程执行完成之后在在执行。

什么是泛化?

在面向对象设计中,泛化关系表示一般与特殊、一般与具体之间的关系,也就是继承关系。泛化关系要求父类是子类的一般化概念,子类是父类的特殊化实例。

A错误:人员类型是用来对公司人员进行分类的属性,技术人员与人员类型之间不是继承关系,而是一种从属关系。

B错误:虽然公司人员与技术人员、管理人员、行政人员之间确实构成泛化关系,但选项中提到"相互转换"的说法不准确。在泛化关系中,子类之间通常不能相互转换。

D错误:部门是公司人员的一个属性,各部门人员与公司人员之间是一种组织结构关系,而不是泛化关系。一个人员可以调换部门,说明这是一种动态的归属关系,而不是继承关系。

根据上图可知

shutdown()方法会让线程池进入"关闭"状态,此时不再接受新的任务提交,但会继续执行队列中的任务直到完成。这是一种平缓的关闭方式。

shutdown()方法不是阻塞方法,它仅仅是发出关闭信号后就立即返回。

shutdownNow()方法会尝试终止所有正在执行的任务,并返回等待执行的任务列表(List)。这些任务是尚未开始执行的任务。

awaitTermination(long timeout, TimeUnit unit)是阻塞方法,它会等待直到以下三种情况之一发生:

      • 所有任务执行完成
      • 到达指定的超时时间
      • 当前线程被中断
        这个方法常用于确保线程池完全关闭。

VectorHashTable都是线程安全的集合类,它们的所有方法都被synchronized关键字修饰,能够保证在多线程环境下的数据一致性。

A. ArrayList是非线程安全的集合类,它的方法没有进行同步处理。在多线程环境下对ArrayList进行并发操作可能会导致数据不一致。如果需要线程安全的ArrayList,可以使用Collections.synchronizedList()方法进行包装。

C. HashMap也是非线程安全的集合类。当多个线程同时操作HashMap时,可能会导致数据丢失或不一致。如果需要在多线程环境下使用Map,应该使用ConcurrentHashMap或者HashTable

补充说明:

  1. Vector是ArrayList的线程安全版本,但由于synchronized关键字导致的性能开销,现在更推荐使用ArrayList+Collections.synchronizedList()或CopyOnWriteArrayList。
  2. HashTable是HashMap的线程安全版本,但同样由于性能原因,现在更推荐使用ConcurrentHashMap,它提供了更好的并发性能。
  3. 虽然Vector和HashTable是线程安全的,但它们的迭代器不是线程安全的,在迭代过程中如果集合被修改,仍然会抛出ConcurrentModificationException。

final不能修饰接口和抽象类。final表示"最终的"含义,而接口和抽象类本身就是需要被实现或继承的,与final的语义相矛盾。final只能修饰具体的类、方法和变量。

final修饰的方法不能被重写(Override),但是可以被重载(Overload)。重写是子类对父类方法的覆盖,而重载是同一个类中方法名相同但参数不同

final修饰的类确实不能被继承,这是Java中实现封装的重要手段之一。

final修饰的变量是常量,一旦被赋值就不能再次修改。对于基本类型,是值不能改变;对于引用类型,是引用不能改变(但对象的内容可以改变)。


总结:

final关键字的核心作用是实现"不可变性",但具体的"不可变"含义要根据修饰对象来具体分析:

  • 修饰类:不能被继承
  • 修饰方法:不能被重写
  • 修饰变量:不能被再次赋值

B+树非常适合范围查询。因为B+树的所有数据都存储在叶子节点,且叶子节点之间通过指针连接形成有序链表,可以很方便地实现范围查询操作。

B+树的查询性能确实稳定。因为B+树是平衡树结构,无论查询任何数据,树的高度都是相同的,所以每次查询的时间复杂度都是固定的O(log n),这保证了查询性能的稳定性。B+树正是为了避免线性查找而设计的数据结构。

对于稀疏矩阵的压缩存储,三元组和十字链表都是常用且有效的压缩存储方法。

三元组法是最基本的稀疏矩阵压缩存储方法。它只存储矩阵中的非零元素,每个非零元素用(行号,列号,值)三个数据项表示,大大节省了存储空间。

十字链表是一种链式存储结构,将同一行/列的非零元素用双向链表串起来,既保持了矩阵的结构特性,又实现了压缩存储的目的。

二维数组是稀疏矩阵的顺序存储方式,需要存储所有元素(包括大量的零元素),不属于压缩存储方法。

散列(哈希)是一种查找技术,主要用于快速存取数据,不是专门用于压缩存储稀疏矩阵的方法。

编程题

24.计算兔子数量

有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,求第n个月的兔子总对数为多少?

你的答案:

提交时间:2025-03-23 语言:Java 运行时间:25ms 占用内存:9864 状态:编译正确

importjava.util.*;
 
 
publicclassSolution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算第n个月的兔子总共多少对。
     * @param count int整型 第多少个月后兔子总对数
     * @return long长整型
     */
    publiclongcalculateTotal (intcount) {
        // write code here
        returnnum(count);
    }
 
    privateintnum(intcount) {
        if(count == 1|| count == 2){
            return1;
        }else{
            returnnum(count - 1) + num(count - 2);
        }
    }
}

官方解析:暂无官方题目解析。

编程题

25.岛屿的最大面积

给你一个大小为 m x n 的二进制矩阵 grid。

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。

上图的非蓝色块并且表示1的为岛屿

你的答案:

提交时间:2025-03-23 语言:Java 运行时间:41ms 占用内存:10928 状态:编译正确

importjava.util.*;
 
publicclassMain {
    publicstaticvoidmain(String[] args) {
        Scanner in = newScanner(System.in);
        List<int[]> gridList = newArrayList<>();
        while(in.hasNextLine()){
            String line = in.nextLine().trim(); // 删除字符串的头尾空白符
            String[] parts = line.split(",");
            intlen = parts.length;
            int[] rows = newint[len];
            for(inti = 0; i < len; i++) {
                rows[i] = Integer.valueOf(parts[i]);
            }
            gridList.add(rows);
        }
         
        int[][] grid = newint[gridList.size()][gridList.get(0).length];
 
        for(inti = 0; i < gridList.size(); i++) {
            grid[i] = gridList.get(i);
        }
 
        intmaxArea = 0;
        for(inti = 0; i < grid.length; i++) {
            for(intj = 0; j < grid[0].length; j++) {
                if(grid[i][j] == 1){
                    intarea = getMaxArea(grid,i,j);
                    maxArea = Math.max(area,maxArea);
                }
            }
        }
        // 正确代码应添加
        System.out.println(maxArea);
    }
 
    privatestaticintgetMaxArea(int[][] grid, inti, intj) {
        if(i < 0|| i >= grid.length || j < 0|| j >= grid[0].length || grid[i][j] != 1){
            return0;
        }
        grid[i][j] = 0;
        returngetMaxArea(grid, i+1, j) + getMaxArea(grid, i-1, j) + getMaxArea(grid, i, j+1) + getMaxArea(grid, i, j-1) + 1;
    }
}

官方解析:暂无官方题目解析。

编程题

26.

使用堆栈知识计算可以看见几栋楼楼顶

城管队员需要查看,楼顶是否有加盖的违规建筑,一条步行街上有很多高楼,共有n座高楼排成一行。城管队员第一次需要统计每一栋楼顶上可以看见几栋楼的楼顶(当前面的楼的高度大于等于后面的楼时,后面的楼将被挡住),便于以后只选择到几栋楼,就可以看见全部高楼的楼顶是否有违建。
如步行街上有高度依次为{50m, 30m, 80m, 30m, 27m, 57m}的六栋大楼,当站在第3栋大楼上时,可以看见5栋大楼顶部是否有违规建筑(当处于第3栋楼,可以向前看到位置2、1处的楼,向后看到位置4、6处的楼,加上第3栋楼,供可看到5栋楼)。请用代码求解,当大楼的高度依次为数组[a1,a2,...an]时,站在每一个大楼上可以看见的大楼楼顶数量的数组[b1,b2,...bn]。
 

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 采用单调递减栈,栈顶元素最小,因为前面楼层低,不会挡住后面;前面高,才会挡住后面,栈顶是最接近当前位置的楼,所以要最小,代表此时栈顶所在位置向某一方向能看到其它楼的楼顶。
     * @param heights int整型一维数组 n座楼的楼层高度
     * @return int整型一维数组
     */
    public int[] findBuilding (int[] heights) {
        // write code here
        int n = heights.length;
        int[] ans = new int[n];
        Stack<Integer> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();
        ArrayList<Integer> count1 = new ArrayList<>();
        ArrayList<Integer> count2 = new ArrayList<>();
 
        for(int i = 0, j = n-1; i < n && j>=0; i++, j--) {
            count1.add(stack1.size());
            count2.add(0, stack2.size());
            while(!stack1.empty() && stack1.peek() <= heights[i]) stack1.pop();
            while(!stack2.empty() && stack2.peek() <= heights[j]) stack2.pop();
            stack1.push(heights[i]);
            stack2.push(heights[j]);
        }
        for(int i = 0;i<n;i++){
            ans[i] = count1.get(i) + count2.get(i) + 1;
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值