某大型国企Java岗位面试题,你能做出几道?

最近有一个好消息,小灰的一位读者去某国企面试Java开发岗位,顺利上岸了。

为了帮助到大家,他分享出面试中遇到的几个题目,涉及到Java基础、多线程、MySQL。题目都是选择题,难度中等。

大家在阅读这些题目的时候,建议先自己思考一遍,再去查看后面的答案。

106149c9b6dc4b13aa1f0a671df72de1.png

题目一

考虑下面的Java代码片段:

public class TestThread {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while (!ready) Thread.yield();
            System.out.println(number);
        }
    }

    public static void main(String[] args) {
        new ReaderThread().start();
        number = 42;
        ready = true;
    }
}

在没有其他同步机制的情况下,运行上述程序可能会产生哪些结果?

A. 程序无限循环,不输出任何东西。

B. 输出"42"。

C. 不保证总能输出"42",有时可能不输出任何东西。

D. 抛出异常。

正确答案:C. 不保证总能输出"42",有时可能不输出任何东西。

为什么呢?

这个问题深入探讨了Java内存模型(JMM)及其对多线程程序可见性和重排序的影响。在多线程环境中,由于编译器优化、处理器优化以及运行时的JIT编译优化,操作的执行顺序可能会与代码中的顺序不同。这种优化可能会影响到变量的可见性和程序的执行顺序。

A. 程序无限循环,不输出任何东西。 这是一个可能的结果,但并不是因为程序实际上会无限循环,而是因为ready变量的更新可能对启动的ReaderThread线程不可见。如果主线程对ready的更新对ReaderThread不可见,那么ReaderThread可能会永远在while循环中等待ready变为true

B. 输出"42"。 这是在ready变量的更新对另一个线程可见,并且这个更新在number变量被设置为42之后被检测到的情况下可能发生的结果。

C. 不保证总能输出"42",有时可能不输出任何东西。 这是最准确的描述。由于缺乏同步措施,ready的更改可能在另一线程中不可见,或者由于指令重排序,number的赋值操作和ready的赋值操作的顺序可能在执行时被颠倒。因此,即使ready被设置为trueReaderThread看到这个变化时number可能还没有被设置为42。

D. 抛出异常。这个选项不正确,因为部分异常是在并发修改某些集合时可能抛出的,而与本题讨论的内存可见性和指令重排序无关。

因此,由于Java内存模型的特性,最合理的答案是C。在实际应用中,为了确保多线程之间正确的内存可见性,通常需要使用同步机制(如volatile关键字、synchronized块或者java.util.concurrent包中的类)来防止这种类型的问题。

题目二

考虑以下Java类和接口:

interface Speakable {
    String speak();
}

class Animal implements Speakable {
    public String speak() {
        return "I am an animal";
    }
}

class Dog extends Animal {
    public String speak() {
        return "Woof";
    }
}

class Cat extends Animal {
    public String speak() {
        return "Meow";
    }

    public String purr() {
        return "Purr";
    }
}
给定以下代码片段:
Animal myDog = new Dog();
Animal myCat = new Cat();

Speakable something = // 填空

如果我们希望something.speak()调用返回"Purr",应该如何实例化something变量?选择正确的选项。

A. new Dog()

B. new Cat()

C. myDog

D. myCat

正确答案:B. new Cat()

为什么呢?

本题考察了Java中多态性的理解和应用。多态允许我们通过父类引用来指向子类对象,实现在运行时决定具体调用哪个类的方法,这是面向对象编程中的一个核心概念。

选项解析:

A. new Dog() - 实例化一个Dog对象并不会使something.speak()返回"Purr",因为Dog类的speak方法被重写为返回"Woof"

B. new Cat() - 这是正确的选项。尽管Cat类重写了speak方法返回"Meow",但特定于Cat的方法purr返回"Purr"

题目中的要求可能有些误导,因为Speakable接口或Animal类中都没有purr方法。然而,既然问题是要speak()返回"Purr",实际上只有通过具体地调用Cat类的purr方法才能实现,这意味着应该直接创建一个Cat对象。

但根据题目描述,这里可能是个陷阱,因为SpeakableAnimal类型的引用不能直接调用purr()方法。因此,若真的需要something.speak()返回"Purr",选项的表述可能不完全准确,但就题目要求而言,只有Cat实例能近似满足需求,尽管需要调用purr而非speak

C. myDog - 这个选项引用了一个Dog类型的对象,这会导致speak方法返回"Woof"

D. myCat - 尽管这个选项引用了一个Cat对象,根据Cat类的实现,speak方法将返回"Meow"而非"Purr"。正确的答案取决于对问题的理解,但按照字面意义,没有一个选项能直接使speak()返回"Purr",因为purrCat类特有的方法,而不是Speakable接口或Animal类的一部分。正确的做法是直接调用Cat类的实例上的purr()方法。然而,考虑到题目的意图,最接近的选项是B,因为只有Cat类与"Purr"相关联。

因此,正确答案是B,即使这个答案在技术上并不完美地符合题目的要求。这个问题强调了在设计面向对象系统时清晰和准确地理解类之间关系的重要性,以及多态在动态方法调用中的作用。

 
 

题目三、

假设你有一个包含数百万条记录的MySQL数据库表orders。表结构如下:

CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT NOT NULL,
    order_date DATE NOT NULL,
    amount DECIMAL(10, 2) NOT NULL,
    status VARCHAR(10) NOT NULL
);

你需要编写一个查询来找出过去30天内每个客户的平均订单金额,但是你注意到查询的响应时间很慢。以下是你编写的查询:

SELECT customer_id, AVG(amount) AS avg_amount
FROM orders
WHERE order_date > DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY customer_id;
你正在考虑对orders表做哪些优化,以提高查询性能。以下哪项措施是最有效的?

A. 在order_id列上增加一个索引
B. 在order_date列上增加一个索引
C. 在amount列上增加一个索引
D. 在status列上增加一个索引

第三道题的正确答案,小灰暂时先不公布,有兴趣的小伙伴可以在留言区给出你认为的答案选项以及这样选择的原因。
最后,在2024年的金三银四,祝愿大家都能找到好的工作!

欢迎关注公众号程序员小灰,收看更多有趣又有用的内容:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值