1、语言的基础部分:
基本要求的***个,当然是语言的基础部分。
基础部分其实就是语法以及一些关键字的作用,像一些 if/else、for 循环这类基础的语法,以及一些 new、class、public 这类的基础关键字,大部分情况下面试问的是比较少的,因为这部分内容,只要你写过几年 J***a,基本上都没有什么问题。
那么基础部分的***,其实主要就是 static、final、transient、volatile 这一类的关键字,以及内部类、泛型这一类的高阶语法。
说到 static,首先要记住的***重要的一点就是,类属性中被 static 所引用的变量,会被作为 GC 的 root 根节点。
作为根节点就意味着,这一类变量是基本上不会被回收的。因此,static 很容易引入内存泄漏的风险。
如果一个面试官让你解释 static 关键字,你告诉他 static 可以修饰属性、方法和内部类,以及修饰之后又有什么效果的话,那么面试官基本上不会记住你这个回答,整个印象就是平庸。
但是如果你说完以后,补充一下说道,你曾经遇到过一个内存泄漏的问题,就是因为 static 修饰的一个 Map 类型的变量导致的,***后排查了堆栈信息找到了问题的所在,并且解决了这个问题。
那么,面试官这个时候内心中对你的印象,就会不自然的提升几分。
而且,对于 static,更深入的理解是,static 会将所引用的属性、方法以及内部类,与类直接产生引用关系,而非与类的实例。
这就是为什么,你可以使用类名.属性、类名.方法以及类名.内部类名,来直接引用一个被 static 所修饰的属性、方法或者内部类。
如果你没有用 static 修饰,那么你就必须使用实例才能引用这些方法、属性或者是内部类,***典型的就是内部类。
相信很多同学都好奇过,为什么一个没有被 static 修饰的内部类,必须要这么声明。
因为你没有使用 static 修饰 InnerClass,所以你必须 new 出来一个 OutterClass 的实例,才能在此基础上 new 出内部类的实例,因为内部类只能通过外部类的实例才能引用。
如果你使用了 static 修饰,那么你就可以这样使用内部类。
这两种方式***大的区别就是:
***种方式,如果你想要获得 InnerClass 的实例,你必须有一个 OutterClass 的实例,所有其实这种方式你创建了两个实例,所以有两个 new 关键字。
第二种方式就好理解一些,静态内部类不依赖于外部类的实例存在,因此只需要直接创建内部类的实例就可以了,所以只有一个 new 关键字。
static 说的有点多了,其实不光说了 static 关键字,也一起连同内部类的语法也大致都说了下。
那么接下来,基础部分还有一个比较考验人的东西,就是 volatile 关键字。
这个关键字的***就三个字,就是——可见性。
但是面试的时候,你说出可见性三个字,基本上满分100的话,***多只能得到20分。剩下的那80分,就要靠你用硬功夫去获得了。
所谓的硬功夫,其实就是要整明白,在并发当中,可见性到底是什么意思。
那么,为了弄明白可见性什么意思,就需要你了解什么叫主存和工作内存。
只有把这些概念都搞明白了,你才会知道 volatile 的真正作用到底是什么。
不过有一点要提醒你的是,volatile 并不保证同步,这一点一定要记住。
不光是应付面试官,在真正使用 volatile 的时候,也要注意这一点,否则很容易出现问题。
好了,基础部分就说这么多吧,挑了一些有代表性的说了下,归根结底,这一部分就是要你非常清晰的了解 J***a 当中的关键字和语法,这里所谓的了解,是清晰的了解其实现原理,而非简单的会用而已。
2、J***a 运行时环境
J***a 运行时环境就是 JRE 的中文翻译,本质上其实就是指 JVM。
首先对于 JVM 必须要知道的是,JVM 与 Hotspot 的关系。
JVM 更多的是指 JVM 规范,而 Hotspot 是 JVM 的一种实现,也是我们***常用的 JVM 实现。
你可以把 JVM 规范当做接口,Hotspot 当做实现类,这样去理解会比较简单一些。
此外,JVM ***重要的三个部分必须要非常清楚,内存划分、class 加载机制以及 GC 策略。
搞清楚这三部分不仅仅是为了面试,也是为了让你对于 J***a 有更深刻的理解,这对于你的 J***a 生涯非常有帮助。
而且,关于内存划分,还有一点要注意,咱们常说的划分方式,其实是指的 Hotspot 的划分方式,而非 JVM 规范所规定的。
Hotspot 的内存划分简单说分为三个部分,Young Generation(年轻代)、Old Generation(年老代)以及 Perm Generation(***代)。
其中的 Young Generation(年轻代),又分为 Eden、From 和 To,其中From 和 To 又统称为 Survivor Spaces(幸存区)。
正常情况下,一个对象从创建到销毁,应该是从 Eden,然后到 Survivor Spaces(幸存区),再到 Old Generation(年老代),***后在某次 GC 下消失。
当然,一个对象也可能直接在 Eden 里死掉,也可能一直在 Old Generation(年老代)存活,这些都是有可能的。
关于内存划分,可以自己没事用内存分析工具看看,比如 jmap、jvisualvm 等等,观察一下各个区域的内存变化,结合实际去了解一下。
关于 classloader 机制的学习,可以结合 tomcat 去学习,了解清楚 tomcat 的 classloader 机制,看 tomcat 是如何保证各个 APP 之间的类隔离的。
如果可能的话,看一下 tomcat 中 classloader 的源码,当中包含了与 tomcat 类加载机制相似的部分。
至于 GC,需要清楚 GC Roots 都有哪些,以及如何判断一个对象可以被回收。
此外,GC 的算法和策略也要有大概的了解。
3、并发知识与 concurrent 包
要想进入一线互联网公司,这部分内容必须要会,否则的话,你始终都只能停留在比较 low 的段位。
关于并发知识,***重要的两个概念一定要搞清楚,那就是可见性和原子性。
其中可见性与前面提到的 volatile 关键字是息息相关的,可见性只是并发领域里的一个概念,而 volatile 则是 J***a 语言中,实实在在保证变量可见性的关键字。
前面说了,要弄清楚可见性,就需要搞清楚主存和工作内存。
关于主存和工作内存,其实又属于 JVM 的知识范畴。所以从这里就可以看出来,知识都是有关联性的。
原子性其实相对于可见性来说,反倒更好理解一些,相信那个万年不变的***汇款的关于事务的例子,就足以大部分人理解原子性这个概念了,它其实就是一个或多个操作,被视作一个整体的意思。
有了并发的基础知识以后,你就需要研究一下 concurrent 包了。
这里面的东西其实是一个宝藏,一旦你需要写并发相关的功能,你会发现这里面的东西非常实用。
其中 ConcurrentHashMap 是面试***容易被问到的一个类,几乎所有的面试都会问你,ConcurrentHashMap 和普通的同步 HashMap 有什么区别。
这个问题其实需要你知道两个知识就可以了,一个是 HashMap 的数据结构,一个是锁分段的技术,具体的大家自己下去找相关资料看吧。
此外,concurrent 包里有一个非常重要的类,叫做 AbstractQueuedSynchronizer,几乎所有的 concurrent 包内的并发工具类,都是基于这个抽象类扩展出来的。
因此,把 AbstractQueuedSynchronizer 这个类研究透彻,非常有助于你理解 concurrent 包。
***后一点,面试的时候还经常会被问到的一个问题,就是 ReentrantLock 和 synchronized 关键字有什么区别。
其实它们的区别很简单,简单的说,就是 synchronized 由于是底层 JVM 实现的互斥,因此效率会高一些。
而 ReentrantLock 的功能则比 synchronized 更多,比如定时获取某个锁,多个等待条件等。
并发这一部分是一个程序员进阶的重要部分,希望所有 J***a 程序员都可以重视这一部分。
4、设计模式和反射
设计模式和反射这部分内容,个人觉得是一个高阶程序员必须精通的部分。
用好了这部分知识,可以让你在实际开发中少写N多代码,而且还可以使得程序的结构更加良好。
关于反射,其实就是 reflect 包里的内容,这个包里的类其实并不难,主要是得多用,多看。
比如 J***a 领域里***常用的 spring 框架,里面其实大量充斥着设计模式和反射的真实使用场景,没事多研究一下,***让你受益匪浅。
5、文件 IO、NIO、网络 IO 以及网络协议
文件 IO、NIO 以及网络 IO 这一部分也是工作当中要经常用到的部分,因此也必须要掌握。
其中 NIO 更多的是了解其原理,此外,tomcat 中有多种协议的实现,其中包括了 BIO、NIO 和 APR,这三者一定非常清楚它们的区别,这个可以在 connector 的 protocol 属性配置。
至于网络 IO 部分,其实就是 net 包里的内容。
这里面的内容是非常常用的东西,比如你调用 HTTP-API,那么就需要使用这里面的类。
在这个 restful-API 泛滥的时代,你少不了要使用 HTTP 协议调用 API。
此外,在了解这部分的时候,网络协议也要适当的了解一下,***典型的 TCP 和 HTTP 协议是一定要了解的。
在参加的面试中,基本上 TCP 协议是一定会问的,比如 TCP 协议的重试机制,三次握手的过程,TCP 与 UDP 的区别这一类的知识,还是要了解一下的。
至于 HTTP 协议,相对来说就简单很多了,应用层的协议主要是知道其协议格式即可,比如都支持哪些 header、每个 header 都是什么含义等等。
本文由西安软件培训提供www.shun580.com
版权所有©2024 产品网