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

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

技术的水有多深?

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

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

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

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

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

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

你有多懂面试官?

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

  1. 问答双方角色不同(比如项目经理面试架构师的情况),思考角度不同,导致对同一个技术话题,展开的方向不同,自然理解上会发生分歧。工程思维的人想的是如何得到结果,你可以着重讲技术内部维度的内容;而用户思维的人想的是那个结果可以用来干什么,你就要侧重到应用维度上了。(当然,项目经理不应该面试架构师人选,但是事实上这种安排还真有。)

  2. 问答双方的知识结构和水平不一样,理解深度和宽度不同。你觉得小儿科的知识,对方却可能完全听不懂。这需要你了解对方的技术水平,采用适当的技术语言或者业务语言来表达。不要满嘴都是你专用的术语或者缩写,谁知道你说的“FID”“CPS”代表什么呢。

  3. 上下文理解不同,面试官的问题意图不能被应聘者理解。面试官的问题之间或多或少是有联系的,你需要根据问题的上下文,结合前面问答中面试官的语言或者肢体反馈,分析他的意图,搞清他是在问“为什么”,还是“是什么”,或者“怎么用”,从而调整要表达的内容。

  4. 面试官没有问清楚。比如,“请你解释一下HTTPS”,这样的提问就不够具体,原因可能是面试官怕问到你能力临界点之外,但也可能是他本身就没把问题想清楚。

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

注意表达方法

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

  1. 结构化表达,帮助面试官梳理信息逻辑。比如,使用列表,或者使用结构化的语言序号“第一……第二……”。关于表达逻辑,芭芭拉 · 明托的《金字塔原理》可能会帮到你。

  2. 可视化。用画图或者演示的方法,直观形象地表达复杂的技术问题。

  3. 举例子和做类比。举常见的例子,类比成常见的事物,这样把高深的原理说简单,对方不仅能听懂,还会赞赏你的表达能力。
    比如,有人问“Java线程和进程有什么区别”,知乎上有人回答:“如果一个大火锅一个人吃,就是单进程单线程;一个大火锅多人吃,就是单进程多线程;如果他们分开吃小火锅,就是多进程多线程了。”
    把内容说简短很不容易。马克 · 吐温曾给读者回信说:我没有时间给您写封短信,所以就写了封长信。把内容陈列出来容易,但是长话短说很难。需要你深刻理解本质,区分每块内容的重要等级,再梳理逻辑和分析取舍。

  4. 对比。电影《无双》中有一场面试,郭富城跟周润发在酒吧见面,郭富城讲作画的工艺:“……把纸放进碳酸钙和木质素就能泡出质感。行家用的油墨多数都是植物油,干得快,稳定。而我用核桃油、煤灰和松节油混合……”这里他是在把两种技术进行对比,来突出自己采用的技术有多么专业和独特。

  5. 讲故事。如果你能找到一段相关经历,讲述该技术的应用或者学习细节,展示你学以致用的能力,效果会非常好。你可以说“这个技术,我上个月正好在某某项目上用过,当时的情况是……”

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

总结

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

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

思考时间

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

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