我们以Java多线程为例,解释下这两个维度。
#### 1. 应用维度
应用维度主要从问题、技术规范、最佳实践、市场应用趋势这四个层面来解释。
**问题**:从技术的应用维度看,首先考虑的是要解决什么问题,这是技术产生的原因。Java多线程的产生,是因为要并发,并发使得程序的多种功能能响应更快,用户体验更好。**问题这层,用来回答“干什么用”。**
**技术规范**:接下来,技术被研发出来,人们怎么用它才能解决问题呢?这就要看技术规范,可以理解为技术使用说明书。在Java世界里,你可以实现Runnable接口、扩展Thread类来实现代码并发;同时,Java提供 synchronized 关键字,以及各种锁,来帮你控制并发中的代码行为和衍生问题。这需要了解接口和关键字的使用规则和潜在影响,以及各功能的细微差别。比如, sleep() 和 wait() 的区别是什么, 为什么 wait() 需要在同步代码块内使用,而 sleep() 不需要。**技术规范,回答“怎么用”的问题,反映你对该技术使用方法的理解深度。**
**最佳实践**:你把该技术运用到多种不同的场景时,会发现同样的使用方法,会有不同的效果,这是因为问题上下文不同了,该技术有不同的适应面。从而你可能踩了很多坑,知道了该技术的“脾性”,从中总结出最佳实践。这缘于在不同应用场景中,对技术表现差异的比较和把握。**最佳实践回答“怎么能用好”的问题,反映你实践经验的丰富程度。**比如:
> 
在多线程场景下实现锁来确保线程的同步,但是加锁、释放锁是个非常消耗资源的操作,没有获得锁的线程还需要进入阻塞状态,等待被唤醒。 如果多个线程的竞争并不激烈,可以考虑使用CAS的方式实现无锁的线程同步,线程可以一直运行,不用阻塞。但是使用CAS还需要考虑使用时间戳等方式来解决ABA问题。
**市场应用趋势**:随着技术生态的发展,和应用问题的变迁,技术的应用场景和流行趋势会受到影响。对于Java,从低并发逐渐发展到高并发,如何充分利用系统的能力,减少响应时间变得非常重要。**这层回答“谁用,用在哪”的问题,反映你对技术应用领域的认识宽度。**
#### 2. 设计维度
应用维度是从外部看技术的应用。那么,从内部能看到技术的哪些层面呢?
**目标**:为了解决用户的问题,技术本身要达成什么目标。比如,Java多线程要在优先级调度、锁、信息同步等方面达成怎样的目标,才能更好地实现并发。**这层定义“做到什么”**。
**实现原理**:为了达到设计目标,该技术采用了什么原理和机制。Java多线程的实现原理包括内核线程、使用用户态线程、使用用户态线程加轻量级进程混合等部分,还包括硬件指令集、Test and Set、各种锁等。**实现原理层回答“怎么做到”的问题。**把实现原理弄懂,并且讲清楚,是技术人员的基本功。
**优劣局限**:每种技术实现,都有其局限性,在某些条件下能最大化的发挥效能,缺少了某些条件则暴露出其缺陷。比如在Java多线程编程中,采用共享内存的方式,锁的开销比较大,程序员编程难度较大,容易出错,难以调试。**优劣局限层回答“做得怎么样”的问题。**对技术优劣局限的把握,更有利于应用时总结最佳实践,是分析各种“坑”的基础。
**演进趋势**:技术是在迭代改进和不断淘汰的。了解技术的前生后世,分清技术不变的本质,和变化的脉络,以及与其他技术的共生关系,能体现你对技术发展趋势的关注和思考。**这层体现“未来如何”。**比如:
> 
Java 5提供JCU包,实现了多种锁结构,简化开发;Java 7加入Future来获取线程返回值;Go语言中“协程”的概念,也被第三方引入,扩展了Java的多线程功能,比线程切换更快,性能得到了很大的提升。
总地来说,从技术内部(也就是设计维度上)看,包括目标、实现原理、优劣局限、技术演进趋势。而从技术外部看,也就是市场应用维度上看,包括问题、技术规范、最佳实践、市场应用趋势。它们是逐层递进的关系,代表了你对技术把握的深度。
对于一项流行的技术,大部分人可以讲清实现原理和技术规范,也就是说能搞懂它的工作原理和使用方法,这是技术人员的基本功。再上面的技术局限性和最佳实践,只有经过深入的钻研,甚至读源码,以及多场景的实践之后,才能讲出深刻的认识。对于最上面的趋势层,需要具有相当程度的“T”型技术体系,对相关技术有横向和纵向的对比之后,才能总结得出来,考验应聘者的知识面和洞见。
但是,如果有人恰好读过几篇有深度的技术文章,上面的某些层他也可能照本宣科地讲出来。那么让你和他可以区分开的“杀手锏”就是技术实战:如果你在“最佳实践”部分中,能结合自己的项目经历,找到该技术的一个应用例子,特别是棘手的问题,讲清你是如何调优或者解决的,不仅会彰显你真实的技术水平,而且最有说服力,也是面试官最看重的。当你把问题的解决过程,跌宕起伏地讲出来,面试官也会跟你一样嗨起来。
讲到这,你可能要问,难道面试中的每个技术问题,都要按照上面两个维度八个方面去解释么?不是的,你还需要弄懂面试官想听什么,能听什么,然后再按需呈现。下面我们谈一下如何弄懂面试官的需求。
## **你有多懂面试官?**
只听懂面试官说的字面意思,不一定能给面试官满意的答案。很多时候,应聘者并不能准确理解面试官想要听的点。下面列出了几种情况及其解决方法。
**举例子和做类比。**举常见的例子,类比成常见的事物,这样把高深的原理说简单,对方不仅能听懂,还会赞赏你的表达能力。
比如,有人问“Java线程和进程有什么区别”,知乎上有人回答:“如果一个大火锅一个人吃,就是单进程单线程;一个大火锅多人吃,就是单进程多线程;如果他们分开吃小火锅,就是多进程多线程了。”
把内容说简短很不容易。马克 · 吐温曾给读者回信说:我没有时间给您写封短信,所以就写了封长信。把内容陈列出来容易,但是长话短说很难。需要你深刻理解本质,区分每块内容的重要等级,再梳理逻辑和分析取舍。