文章目录
说明
记录笔试选择题自己觉得值得记录的点。有时候笔试完有的题目也记不住
基础
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
-
i++
自增运算的特性:i++
是后置自增操作。它首先返回变量的当前值,然后再执行自增操作。也就是说,i++
会先使用i
的当前值,之后再将i
增加 1。
-
i = i++
的执行顺序:- 当执行
i = i++
时,首先取i
的当前值(即1
),并将这个值保存起来用于赋值。 - 然后执行
i++
的自增操作,将i
增加 1,但这个变化不会立即反映在赋值中。 - 最后,将保存的旧值
1
赋值回i
,覆盖了自增后的结果。
- 当执行
-
步骤分析:
- 初始化
i = 1
。 i++
返回当前的i
值1
,然后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),就说明这个学生没上过“柳银君”的课