假如我是面试官,从Hello World来考你
又是一年春招之时,在写完论文并提交盲审之后,我又开始了自己的学习总结之路。我想到了一个比较基础的题目(不喜勿喷),如果我是面试官,我一定会从这道问题展开面试。问:请从结合下面一段代码,讲一下你所掌握的Java知识点,多多益善。
public class Demo {
public Demo(){}
public void print(){
System.out.println("Hello world");
}
public static void main(String[] args) {
Demo demo=new Demo();
demo.print();
}
}
一段很普通的代码,结合这一普通的问题,我一开始确实想不到啥特殊的内容,但是仔细一想,里面的涉及到的Java基础内容却蛮多的。且听我慢慢道来:
1. Demo命名中的知识点
一般这个文件,我们会将其命名为Demo.java。一个Java文件中,可以有多个类,但只能有一个public类,并且public的类名必须与文件名一致。关于这一问题,《Think in Java》中有这样几段话:
- 每个编译单元(文件)都只能有一个public类,这表示每个编译单元都有单一的公共接口,用public类来表现。该接口可以按要求包含众多的支持包访问权限的类。如果在某编译单元内有一个以上的public类,编译器就会给出错误信息。(按照我的理解,每个类代表一个对象,在编译过程中,以该对象为主体展开,如果存在多个主体,编译器会报错)
- public类的名称必须完全与含有编译单元的文件名相同,包含大小写,如果不匹配,同样将得到编译错误。(这就是规范问题了,就好像为啥那种生物叫鸡,另外一种生物叫鹅一样)
- 虽然不常用,但是编译单元内完全不带public类也是可能的。这种情况下,可以随意对文件命名。
当java源文件不存在public类时,会出现什么情况呢?

2. javac与java命令
前面提到了javac命令,通过javac Demo.java文件,可以生成Demo.class字节码文件,直接打开Demo.class字节码文件是一堆乱码,我们无从下手。为了得到Hello world的输出,需要使用java Demo的命令得到输出。通过javap反编译命令,可以得到字节码文件的详细内容。


3.对象的创建
Demo demo = new Demo();
这一句话,有对象创建的过程。new Demo()操作会创建一个对象,demo为一个对象的声明,对象的声明就是对象的引用指向堆内存中开辟的对象。新创建的对象存储在堆空间里,相关的引用存储在栈(虚拟机栈)中。在上述程序中,首先执行的是main代表的主线程,当执行遇到new关键字时,主线程便在自己的虚拟机栈中声明一个对象hello,在JVM的堆内存中申请一片内存区域,然后将Demo相关的信息,例如实例变量,实例方法等从方法区中加载到堆内存中。对象中比较关键的是头部信息,主要有三部分构成: 1.MarkWord:主要描述持有当前对象锁的线程ID和持有对象锁的线程个数,在gc中存活的生命周期数,偏向锁的标志等 2.类指针:指向方法区对应类信息的指针。 3.对齐填充 这些仅仅是通过几行简短的程序所能扩展出来的知识点。所以不要小看hello world,还是很有意思的。如果在Demo.java文件中加入静态代码块,非静态代码块,继承等机制,难度会增加一个level。所以假如我是面试官,我会通过这一问题,考察你对jvm和java基础的理解程度。
转载自:https://juejin.cn/post/6844904115395362823