面试:java笔试基础总结

说明

记录笔试选择题自己觉得值得记录的点。有时候笔试完有的题目也记不住

基础

1、静态代码块 构造代码块 构造方法

例1:

public class Test {
    // 构造代码快 构造代码块在每次创建对象时都会执行,并且优先于构造方法执行。

    {
        System.out.println("b");
    }
    // 构造函数

    Test() {
        System.out.println("c");
    }

    // 静态代码块
    static {
        System.out.println("a");
    }

    public static void main(String[] args) {
        Test test = new Test();
    }
}

结果:

a
b
c

静态代码块、构造代码块和构造方法的执行顺序:

  • 当 Test 类被加载时,静态代码块会首先执行,打印 “a”。
  • 然后,程序进入 main 方法,开始创建 Test 对象。
  • 在创建对象时,构造代码块先执行,打印 “b”。
  • 接着,执行构造方法,打印 “c”。

例2:

class A {
    static {
        System.out.println("A静态代码块");
    }

    {
        System.out.println("A的构造代码块");
    }

    A() {
        System.out.println("A构造函数");
    }
}

public class B extends A {
    static {
        System.out.println("B静态代码块");
    }

    {
        System.out.println("B的构造代码块");
    }


    B() {
        System.out.println("B构造函数");
    }

    public static void main(String[] args) {
        B b = new B();
    }
}

结果:

A静态代码块
B静态代码块
A的构造代码块
A构造函数
B的构造代码块
B构造函数

2、静态变量

  • 静态变量是类变量,它属于类本身,而不是某个具体的对象。
  • 所有对象共享同一个静态变量,所以无论通过哪个对象或者类本身修改它,其值都是全局更新的。
public class Test {
    public static int a = 10;

    public static void main(String[] args) {
        Test test = new Test();
        test.a++;
        Test test1 = new Test();
        test1.a++;
        Test.a++;
        a++;
        System.out.println(test.a);
        System.out.println(test1.a);
        System.out.println(Test.a);
    }
}

结果:

14
14
14

3、try-catch-finally 结构的执行顺序

即使在 catch 块中有 return 语句,finally 块仍然会执行。

例子1:

public class Test {
    public static void fun() {
        try {
            int i = 1 / 0;
            System.out.println("a");
        } catch (Exception e) {
            System.out.println("b");
            return;
        } finally {
            System.out.println("c");
        }
        System.out.println("d");
    }

    public static void main(String[] args) {
        fun();
    }
}

结果:

b
c

例子2:

public class Test {
    public static int fun() {
        try {
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            return 3;
        }
    }

    public static void main(String[] args) {
        System.out.println(fun());
    }
}

结果:

3

4、4个节点可以构成 14 种不同形态的二叉树

当时遇到这个题,我是直接在纸上画出来的,画的时候细心一般都不会出错。
在这里插入图片描述

5、i++

public class Test {
    public static void main(String[] args) {
        int i = 1;
        i = i++; // 要实现加1  最好用i+=1
        System.out.println(i);
    }
}

结果:

1
  1. i++ 自增运算的特性

    • i++后置自增操作。它首先返回变量的当前值,然后再执行自增操作。也就是说,i++ 会先使用 i 的当前值,之后再将 i 增加 1。
  2. i = i++ 的执行顺序

    • 当执行 i = i++ 时,首先取 i 的当前值(即 1),并将这个值保存起来用于赋值。
    • 然后执行 i++ 的自增操作,将 i 增加 1,但这个变化不会立即反映在赋值中。
    • 最后,将保存的旧值 1 赋值回 i,覆盖了自增后的结果。
  3. 步骤分析

    • 初始化 i = 1
    • i++ 返回当前的 i1,然后 i 被增加到 2
    • 赋值操作 i = 1,将 1 赋值回 i,覆盖掉刚刚增加到 2 的值。

因此,尽管 i++ 使 i 增加了 1,但由于赋值操作覆盖了这个变化,最终 i 的值仍然是 1

6、double b = 10 / 4 结果?

  • 虽然 b 是 double 类型,但 a / 4 已经是整数类型的结果 2
  • 在赋值时,2 被自动转换为 double 类型,即 2.0
public class Test {
    public static void main(String[] args) {
        int a = 10;
        double b = a / 4;
        System.out.println(b);
    }
}

输出:

2.0

7、static this

静态方法没有this。静态方法(static)不属于具体的对象,而是属于类。因此,静态方法在运行时没有和“某个对象”关联。所以在静态方法中不能使用this。

什么是this?this 是 Java 中的一个关键字,用于指代当前对象。只有在实例方法(非static方法)或构造函数中,才有“当前对象”这个概念。因为只有实例方法是依赖对象的。

public class Main{
    int x = 5; // 实例变量

    public void printX() { // 这是一个实例方法
        System.out.println(this.x); // this指代当前对象
    }

    public static void main(String[] args) {
        Mainobj = new Main(); // 创建一个对象
        obj.printX(); // 调用实例方法
    }
}

public class Main {
    static int c = 1;

    public static void main(String[] args) {
        System.out.println(Main.c);
        // System.out.println(this.c);  // 错误
    }
}

8、页表大小

已知32位系统,字节为编址单位,1个页面大小为4KB,页表项大小为4B,那么存储页表需要多少空间

在这里插入图片描述

在这里插入图片描述

9、Class.forName() ClassLoader.loadClass()区别

  • 当使用Class.forName(class)方法时,它会初始化这个类。初始化的过程包括执行类的静态初始化代码块(static代码块)和初始化静态变量。
  • ClassLoader.loadClass(class)方法主要是用来加载类,它不会自动触发类的初始化。它遵循延迟加载(懒加载)的原则。
class A {
    static {
        System.out.println("A");
    }
}

public class Test {

    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.hac.pojo.A"); // 会触发静态代码块

        ClassLoader classLoader = A.class.getClassLoader();
        Class<?> aClass = classLoader.loadClass("com.hac.pojo.A"); // 不会触发静态代码块
    }
}

10、==对于对象来说是比较的地址

在这里插入图片描述
因为 i j 是不同的对象,地址不同,所以false。

11、字符串的内存机制和 == 的作用

String s1 = "abc";
String s2 = "abc";
System.out.print(s1 == s2);
String s3 = new String("abc");
System.out.print(s1 == s3);

解析:

  • s1 == s2 // true,因为都指向常量池
  • s1 == s3 // false,因为是两个不同对象(常量池 vs 堆)

注意:

1、== 比较的是对象的引用(地址),不是内容。

2、字符串字面量(例如 “abc”)会被存储在 字符串常量池 中。如果两个变量都是字面量方式赋值,且内容相同,它们指向同一个对象。

3、new String(“abc”) 会在堆中创建一个新的对象,即使内容相同。

mysql

1、多表连接查询、分组聚合、子查询

在这里插入图片描述

-- 学生表
CREATE TABLE Student (
  SID VARCHAR(10) PRIMARY KEY,     -- 学号
  Sname VARCHAR(50),               -- 姓名
  Sage INT,                        -- 年龄
  Ssex VARCHAR(10)                 -- 性别
);

-- 教师表
CREATE TABLE Teacher (
  TID VARCHAR(10) PRIMARY KEY,     -- 教师编号
  Tname VARCHAR(50)                -- 教师姓名
);

-- 课程表
CREATE TABLE Course (
  CID VARCHAR(10) PRIMARY KEY,     -- 课程编号
  Cname VARCHAR(50),               -- 课程名称
  TID VARCHAR(10),                 -- 教师编号
  FOREIGN KEY (TID) REFERENCES Teacher(TID)
);

-- 成绩表
CREATE TABLE SC (
  SID VARCHAR(10),                 -- 学号
  CID VARCHAR(10),                 -- 课程编号
  score FLOAT,                     -- 成绩
  PRIMARY KEY (SID, CID),
  FOREIGN KEY (SID) REFERENCES Student(SID),
  FOREIGN KEY (CID) REFERENCES Course(CID)
);

数据:

-- 插入学生
INSERT INTO Student
VALUES ('S1', '张三', 20, '男'),
       ('S2', '李四', 21, '女'),
       ('S3', '王五', 19, '男'),
       ('S4', '赵六', 22, '女');

-- 插入教师
INSERT INTO Teacher
VALUES ('T1', '柳银君'),
       ('T2', '王老师');

-- 插入课程
INSERT INTO Course
VALUES ('C1', '金融学导论', 'T1'),
       ('C2', '统计学', 'T2'),
       ('C3', '风险管理', 'T1');

-- 插入成绩
INSERT INTO SC
VALUES ('S1', 'C1', 90),
       ('S1', 'C2', 70),
       ('S2', 'C1', 55),
       ('S2', 'C2', 65),
       ('S2', 'C3', 58),
       ('S3', 'C3', 95),
       ('S4', 'C2', 60);

在这里插入图片描述

题目1:查询所有同学的学号、姓名、选课数、总成绩
考点:

  • 多表连接
  • 分组统计:COUNT()、SUM()
  • GROUP BY
SELECT s.SID,
       s.Sname,
       COUNT(sc.CID) AS 选课数,
       SUM(sc.score) AS 总成绩
FROM Student s
         LEFT JOIN SC sc ON s.SID = sc.SID
GROUP BY s.SID, s.Sname;

题目2:查询平均成绩大于60的同学的学号和平均成绩
考点:

  • 聚合函数 AVG

  • HAVING 过滤

  • 多种写法,如:子查询、联表也可

SELECT s.SID,
       AVG(sc.score) AS 平均成绩
FROM Student s
         JOIN SC sc ON s.SID = sc.SID
GROUP BY s.SID
HAVING AVG(sc.score) > 60;

题目3:查询没有学过“柳银君”老师课的同学学号、姓名

考点:

  • 反向查询(NOT IN / NOT EXISTS)
  • 多表连接查课程、老师、成绩
SELECT SID, Sname
FROM Student
WHERE SID NOT IN (
  SELECT DISTINCT sc.SID
  FROM SC sc
  JOIN Course c ON sc.CID = c.CID
  JOIN Teacher t ON c.TID = t.TID
  WHERE t.Tname = '柳银君'
);

SELECT *
FROM Student s
WHERE NOT EXISTS (
  SELECT 1
  FROM SC sc
  JOIN Course c ON sc.CID = c.CID
  JOIN Teacher t ON c.TID = t.TID
  WHERE t.Tname = '柳银君' AND sc.SID = s.SID
);

解释:

  • 每一个学生 s,都去子查询里查:他有没有学过“柳银君”的课?
  • 如果这个子查询没有结果(NOT EXISTS),就说明这个学生没上过“柳银君”的课
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值