You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
14 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 13 | 你真能讲明白技术吗?
对于程序员职位的面试,技术问题占的比重非常大。技术问题的回答质量,决定了面试成败。除了面试之外,讲技术的场景还有很多:你和同事讨论技术问题,选择技术方案,都是在讲技术。
你可能会说,把技术讲明白有什么难的,只要我懂就能讲明白。呵呵,你辅导过孩子作业么?有时候那种抓狂,是你对题目本身再明白也无法解决的。例子有点极端,我是在强调:**给面试官讲明白技术,你不仅要懂技术,还要懂面试官。**今天我们就从这两个方面出发,讲讲如何让面试官听到满意的答案,从而提高你的面试成功率。
## **技术的水有多深?**
我们先说技术可以从哪些方面来讲,看看技术的水有多深。
技术是为了解决问题而生的。本质上,技术就是解决问题的方法。问题规模越大,难度越复杂,就要引入多种技术。这些技术组合搭配起来,构成该解决方案的一棵“技术树”。其实,每一个分支和叶子都有多种可选的技术,随着更多的创新出现,这些分支和叶子也在演变,使得整体方案在空间和时间上,能更高效更节省地解决问题。我们对这些分支和叶子技术点的了解和运用,甚至对它们演变的推动,都体现了我们的经验和技能。
那么,一个技术领域,我们需要阐述哪些层面呢?我觉得可分两个维度,一个是技术的设计维度(从技术内部看),另一个是技术的应用维度(从技术外部看),如下图所示。
![](https://static001.geekbang.org/resource/image/4c/14/4c961cf56aeace604cfe830659a67314.jpeg)
我们以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. **讲故事。**如果你能找到一段相关经历,讲述该技术的应用或者学习细节,展示你学以致用的能力,效果会非常好。你可以说“这个技术,我上个月正好在某某项目上用过,当时的情况是……”
灵活运用以上方法,能让你的表达效果事半功倍。以上这些表达方法,不仅适用于技术,在其他专业问题上,也同样见效。但是请注意,回答时一定注意详略。如果你在某一个问题上纠缠太久,会影响后面知识点的考查。你需要边讲边注意面试官的反应,如果他有看表、看简历等厌倦或者着急的情绪信号,就要赶紧调整到下一点了。
## **总结**
总结一下今天的内容。我提到了将技术问题讲明白的两个重点:把握技术的维度,和如何更懂面试官,使他更满意你的回答。
* 在听到技术问题时,第一步先快速在脑子里整理一下“**两个维度八个方面”**的内容,即:外部应用维度,包括问题、技术规范、最佳实践、市场应用趋势;内部设计维度,包括目标、实现原理、优劣局限、技术演进趋势。
* 第二步确认面试官想听什么内容,这需要通过对他的角色、知识结构、问题上下文,以及问题意图来领会,或者一个简单的方法是直接询问。
* 第三步选用合适的表达方法,将面试官感兴趣的部分讲出来。讲的过程中,要注意和他积极交互,根据反馈调整自己的详略和表达方式。这里,结合自己的详历(见“[12 经历没有价值可讲?你需要做份详历](https://time.geekbang.org/column/article/82733)”),讲技术的应用细节和最佳实践,更容易满足面试官的期待。
总之,能把一个复杂的技术问题,深入浅出地讲明白,非常考验你对技术的理解深度,和表达能力,你需要通过平时对技术的积累,和表达能力的锻炼来不断提高。
## **思考时间**
请你回想最近项目中碰到的一些技术问题选一个技术点用上文提到的八个方面去讲述一下。面对资深架构师和工作5年的产品经理你的表达会有什么不同么
欢迎你在留言区分享你的想法,一起讨论。如果本文让你有了新的收获,欢迎把它分享给你的朋友。