<audio id="audio" title="13 | 你真能讲明白技术吗?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/40/b8/4090cefe02ab97d95e2e83594d6f90b8.mp3"></audio>

对于程序员职位的面试，技术问题占的比重非常大。技术问题的回答质量，决定了面试成败。除了面试之外，讲技术的场景还有很多：你和同事讨论技术问题，选择技术方案，都是在讲技术。

你可能会说，把技术讲明白有什么难的，只要我懂就能讲明白。呵呵，你辅导过孩子作业么？有时候那种抓狂，是你对题目本身再明白也无法解决的。例子有点极端，我是在强调：**给面试官讲明白技术，你不仅要懂技术，还要懂面试官。**今天我们就从这两个方面出发，讲讲如何让面试官听到满意的答案，从而提高你的面试成功率。

## **技术的水有多深？**

我们先说技术可以从哪些方面来讲，看看技术的水有多深。

技术是为了解决问题而生的。本质上，技术就是解决问题的方法。问题规模越大，难度越复杂，就要引入多种技术。这些技术组合搭配起来，构成该解决方案的一棵“技术树”。其实，每一个分支和叶子都有多种可选的技术，随着更多的创新出现，这些分支和叶子也在演变，使得整体方案在空间和时间上，能更高效更节省地解决问题。我们对这些分支和叶子技术点的了解和运用，甚至对它们演变的推动，都体现了我们的经验和技能。

那么，一个技术领域，我们需要阐述哪些层面呢？我觉得可分两个维度，一个是技术的设计维度（从技术内部看），另一个是技术的应用维度（从技术外部看），如下图所示。

<img src="https://static001.geekbang.org/resource/image/4c/14/4c961cf56aeace604cfe830659a67314.jpeg" alt="">

我们以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”型技术体系，对相关技术有横向和纵向的对比之后，才能总结得出来，考验应聘者的知识面和洞见。

但是，如果有人恰好读过几篇有深度的技术文章，上面的某些层他也可能照本宣科地讲出来。那么让你和他可以区分开的“杀手锏”就是技术实战：如果你在“最佳实践”部分中，能结合自己的项目经历，找到该技术的一个应用例子，特别是棘手的问题，讲清你是如何调优或者解决的，不仅会彰显你真实的技术水平，而且最有说服力，也是面试官最看重的。当你把问题的解决过程，跌宕起伏地讲出来，面试官也会跟你一样嗨起来。

讲到这，你可能要问，难道面试中的每个技术问题，都要按照上面两个维度八个方面去解释么？不是的，你还需要弄懂面试官想听什么，能听什么，然后再按需呈现。下面我们谈一下如何弄懂面试官的需求。

## **你有多懂面试官？**

只听懂面试官说的字面意思，不一定能给面试官满意的答案。很多时候，应聘者并不能准确理解面试官想要听的点。下面列出了几种情况及其解决方法。

<li>
**问答双方角色不同（比如项目经理面试架构师的情况），思考角度不同，导致对同一个技术话题，展开的方向不同，自然理解上会发生分歧。**工程思维的人想的是如何得到结果，你可以着重讲技术内部维度的内容；而用户思维的人想的是那个结果可以用来干什么，你就要侧重到应用维度上了。（当然，项目经理不应该面试架构师人选，但是事实上这种安排还真有。）
</li>
<li>
**问答双方的知识结构和水平不一样，理解深度和宽度不同。**你觉得小儿科的知识，对方却可能完全听不懂。这需要你了解对方的技术水平，采用适当的技术语言或者业务语言来表达。不要满嘴都是你专用的术语或者缩写，谁知道你说的“FID”“CPS”代表什么呢。
</li>
<li>
**上下文理解不同，面试官的问题意图不能被应聘者理解。**面试官的问题之间或多或少是有联系的，你需要根据问题的上下文，结合前面问答中面试官的语言或者肢体反馈，分析他的意图，搞清他是在问“为什么”，还是“是什么”，或者“怎么用”，从而调整要表达的内容。
</li>
<li>
**面试官没有问清楚。**比如，“请你解释一下HTTPS”，这样的提问就不够具体，原因可能是面试官怕问到你能力临界点之外，但也可能是他本身就没把问题想清楚。
</li>

所以，遇到问题不清楚的时候，你需要从面试官的语言和关注点上，推测他的角色、知识结构、沟通风格，回忆最近几个问题的关系，来推测问题意图。如果推测不出来，就直接问他，比如，“我对该技术领域了解ABCD，请问您对哪方面更感兴趣呢”，通过这样的问题，来确定要讲的内容。这里的要点是“充分沟通”，否则你可能讲半天，对方还是不明白。自顾自地讲高深的内容，效果不一定好。

## **注意表达方法**

回答提问时还应注意选用适当的表达方法，展示你的表达能力。这里，我给你一些建议。

<li>
**结构化表达，帮助面试官梳理信息逻辑。**比如，使用列表，或者使用结构化的语言序号“第一……第二……”。关于表达逻辑，芭芭拉 · 明托的《金字塔原理》可能会帮到你。
</li>
<li>
**可视化。**用画图或者演示的方法，直观形象地表达复杂的技术问题。
</li>
<li>
<p>**举例子和做类比。**举常见的例子，类比成常见的事物，这样把高深的原理说简单，对方不仅能听懂，还会赞赏你的表达能力。<br>
比如，有人问“Java线程和进程有什么区别”，知乎上有人回答：“如果一个大火锅一个人吃，就是单进程单线程；一个大火锅多人吃，就是单进程多线程；如果他们分开吃小火锅，就是多进程多线程了。”<br>
把内容说简短很不容易。马克 · 吐温曾给读者回信说：我没有时间给您写封短信，所以就写了封长信。把内容陈列出来容易，但是长话短说很难。需要你深刻理解本质，区分每块内容的重要等级，再梳理逻辑和分析取舍。</p>
</li>
<li>
**对比。**电影《无双》中有一场面试，郭富城跟周润发在酒吧见面，郭富城讲作画的工艺：“……把纸放进碳酸钙和木质素就能泡出质感。行家用的油墨多数都是植物油，干得快，稳定。而我用核桃油、煤灰和松节油混合……”这里他是在把两种技术进行对比，来突出自己采用的技术有多么专业和独特。
</li>
<li>
**讲故事。**如果你能找到一段相关经历，讲述该技术的应用或者学习细节，展示你学以致用的能力，效果会非常好。你可以说“这个技术，我上个月正好在某某项目上用过，当时的情况是……”
</li>

灵活运用以上方法，能让你的表达效果事半功倍。以上这些表达方法，不仅适用于技术，在其他专业问题上，也同样见效。但是请注意，回答时一定注意详略。如果你在某一个问题上纠缠太久，会影响后面知识点的考查。你需要边讲边注意面试官的反应，如果他有看表、看简历等厌倦或者着急的情绪信号，就要赶紧调整到下一点了。

## **总结**

总结一下今天的内容。我提到了将技术问题讲明白的两个重点：把握技术的维度，和如何更懂面试官，使他更满意你的回答。

<li>
在听到技术问题时，第一步先快速在脑子里整理一下“**两个维度八个方面”**的内容，即：外部应用维度，包括问题、技术规范、最佳实践、市场应用趋势；内部设计维度，包括目标、实现原理、优劣局限、技术演进趋势。
</li>
<li>
第二步确认面试官想听什么内容，这需要通过对他的角色、知识结构、问题上下文，以及问题意图来领会，或者一个简单的方法是直接询问。
</li>
<li>
第三步选用合适的表达方法，将面试官感兴趣的部分讲出来。讲的过程中，要注意和他积极交互，根据反馈调整自己的详略和表达方式。这里，结合自己的详历（见“[12 经历没有价值可讲？你需要做份详历](https://time.geekbang.org/column/article/82733)”），讲技术的应用细节和最佳实践，更容易满足面试官的期待。
</li>

总之，能把一个复杂的技术问题，深入浅出地讲明白，非常考验你对技术的理解深度，和表达能力，你需要通过平时对技术的积累，和表达能力的锻炼来不断提高。

## **思考时间**

请你回想最近项目中碰到的一些技术问题，选一个技术点，用上文提到的八个方面去讲述一下。面对资深架构师，和工作5年的产品经理，你的表达会有什么不同么？

欢迎你在留言区分享你的想法，一起讨论。如果本文让你有了新的收获，欢迎把它分享给你的朋友。
