为妹子准备的 Java 面试(1)

前言

正所谓磨刀不误砍柴工,基础打好了,其他的进阶才不至于被一叶障目。个人觉得 Java 基础由:基础语法、常用类库、网络编程、并发编程和 JVM 5个部分组成。这么多东西初看未免觉得无从下手,摸不着方向,觉得看不完(对,Amy Xia 同学说的就是你)。与其自己去摸索,不如直接使用大神的贤者之石。呃,其实就是看书看书看书(这么多经典的书不看,放着夹叶子嘛)。

Java 语法基础准备

这部分主要是对 Java 语法基础的准备。Java 语法特性初看很简单,但是深入了解后,还是会有发现很多 tricky 的地方。相对比较难理解的部分就是重载/重写和泛型,如果不理解 Java 底层是如何处理这些东西,而是当纯靠死记硬背,可能面对某些复杂的情况,会有错误的判断。下面是 Java 基础准备所需要学习的书籍和文档:

自问自答环节

这部分是对前期学习成果成果的一个检验,有些问题是面试的过程中碰到的,有些问题是自己看书的时候忽然产生的疑问或者之前知识点遗漏的地方。

3 。。。2。。1。Start

语法

public、protected、no modifier、private 四种 modifier的access layer有什么区别?介绍一下 Java 9 的模块化。

重载 overload 和重写 override 的区别。

ListList<?>List<Object> 的异同是什么?各自的使用场景?

思考 Number num = (new LinkedList<Integer>()).get(0)在编译后的等价代码是什么?

List<? extends Foo>List<? super Foo>的异同是什么?各自的使用场景?

下面这段代码输出是什么?顺便思考子类对象的内存结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Foo {
public String str = "Foo";
public Foo() { say(); }
public void say() { System.out.println("Call method in Foo with str value:" + str); }
}

class Bar extends Foo{
public String str = "Bar";
public void say() { System.out.println("Call method in Bar with str value:" + str); }
}

...
// in main
Foo obj = new Bar();
System.out.println("Str value: " + obj.str);
obj.say();
...

下面这段代码是否有错?若有错,为什么?

1
2
3
4
class Main {
int getResult() { return 0; }
double getResult() { return 0.0; }
}

下面这段代码是否有错?若有错,为什么?顺便还可以思考编译时发生了什么?

1
2
3
4
class Main {
int sum(List<Integer> intList) { return 0; }
double sum(List<Double> doubleList) { return 0.0; }
}

下面这段代码是否有错?若有错,为什么?若没有错,输出是什么?顺便还可以思考编译时发生了什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Foo<T extends Double> {
public void set(T t) { System.out.println("Set Foo"); }
}

class Bar<T extends Integer> extends Foo{
public void set(T t) { System.out.println("Set Bar"); }
}

...
// In main
Bar<Integer> bar = new Bar<>();
bar.set(1);
bar.set(1.0);
...

下面这段代码是否有错?若有错,为什么?顺便还可以思考编译时发生了什么?

1
2
3
4
5
6
7
8
class Foo<T> {
public void set(T t) {}
}

class Bar extends Foo<Integer> {
public void set(Integer t) {}
public void set(Object t) {}
}

下面这段代码的输出是什么?顺便思考对象的初始化流程,以ClassLoader为起点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class Main {
public static void main(String... args) {
new Out("Main start\n");
new Out("Before new a B object");
new Out();
new B();
new Out();
new Out("After new a B object");
new Out("");
new Out();
new Out(C.constCvar);
new Out();
new Out(C.staticCVar);
new Out();
new Out("Before new a C object");
new Out();
new C();
new Out();
new Out("After new a C object");
new Out("");
new Out("Main end");
}
}

class Out {
public Out() {
System.out.println("-------------------------");
}

public Out(String message) {
System.out.println(message);
}
}


class A {
public static Out o1 = new Out("A static member o1 initialize");
public Out o2 = new Out("A member o2 initialize");

{ new Out("A non-static block execute"); }

static { new Out("A static block execute"); }

public A() { new Out("A constructor execute"); }
}

class B extends A {
public static Out o3 = new Out("B static member o3 initialize");
public Out o4 = new Out("B member o4 initialize");

{ new Out("B non-static block execute"); }

static { new Out("B static block execute"); }

public B() { new Out("B constructor execute"); }
}

class C {
public static final String constCvar = "const C member";
public static String staticCVar = "static C member";

static { new Out("C static block execute"); }

public C(){ new Out("C constructor execute"); }

}

Java 基础类库准备

基础类库的准备主要从两方面进行,一方面是使用相关:适用场景、使用方式。适用场景:通过接口的整体描述,了解在实现某个功能,需要使用什么样的类库。使用方式:类/接口的方法、方法的作用;另一方面是实现相关:实现的方式和实现的优缺点。对类库使用的了解,仅仅是赋予我们能写代码的能力,而对类库实现的了解,不仅能赋予我们会写代码的能力,更多的是,通过了解实现,给予我们新的思路,在类库功能不能完成需求的情况下,可以自己造轮子。

基础类库准备的方式,使用相关信息可以从 API 文档获得,实现相关信息可以从 API 文档 + 源码来了解。(注:从源码了解,并不代表要一行一行的把源码看完,可以只需要了解核心的实现,忽略某些实现细节,大概对实现有个掌控就行)

基础类库包括:数据结构、线程池

斜体代表要阅读源码,源码可以放到有空再读

数据结构

  • 链表:接口 List;实现类 LinkedListArrayList
  • Map:接口 Map;实现类 HashMap、HashTable、TreeMap、LinkedHashMap、WeakHashMap
  • Set:接口 Set;实现类 HashSet、LinkedHashSet、TreeSet
  • 队列:接口 Queue;实现类 ArrayBlockingQueue、ConcurrentLinkedQueue、DelayQueue, LinkedBlockingQueue、LinkedTransferQueue、PriorityBlockingQueue、PriorityQueue、SynchronousQueue
  • Deque:接口 Deque;实现类 ArrayDeque、ConcurrentLinkedDeque、LinkedBlockingDeque

线程池

  • ThreadPoolExecutor
  • ScheduledThreadPoolExecutor
  • ForkJoinPool
  • Thread

BIO & NIO

自问自答环节