引子
程序员有很多编程领域的概念,其实都可以引申到日常工作上,有时候只是一个思维方式的转变,希望本文能让大家有所启发。
一、编程领域中的阻塞和非阻塞
从概念上讲,io领域中的阻塞io和非阻塞io是编程中最常见的概念之一。
以一个读请求为例,阻塞io在请求时,必须等待数据处理完毕之后才能返回结果,进入下一步的操作。而非阻塞io是在请求时,无需等待,马上返回结果(结果可能是有数据或无数据),紧接着就可以做其他事了。
从具体的场景讲,有一个比较经典的例子:数据导出。
阻塞的情况是一旦发出导出请求,请求会一直等待程序把数据读取完毕,各种转换格式,生成文件等完毕,然后开始下载文件(中间的等待过程可能几秒-几分钟不等)。
非阻塞的情况是提交请求后,请求立马返回,提示“正在导出..”,然后你就可以去做其他事了,服务器后台默默在处理这个文件,过会儿你去一个地方(可能会有一个查询已导出文件的列表)直接下载文件就行。
从上面的io概念及具体的场景中可以看出,阻塞和非阻塞的区分最关键的就是看你在做事的时候有没有一个等待的过程。谁在等待?CPU在等待。
这里我只做区分,暂时不做优劣势的分析,希望大家在看完后面的章节后再去分析,并得出自己的结论。
二、工作上的流程
人和程序其实差不多,都是在不停地做事,区别无非是程序做的是重复的事,而人可以做一些不重复的事。人的工作方式也可以大体分为阻塞和非阻塞两种。
如果把人脑比作CPU的话,那么区分工作方式的关键就在于人脑有没有一个等待的过程(注意这里说的是人脑而不是人,为什么?)
2.1 阻塞工作的场景
场景一
A是交易领域的技术大神,B是商品领域的技术大神。
一天A找到B,想了解下交易流程中关于商品的缓存更新问题。
B:我处理个线上问题,等我10分钟。(键盘上手速飞快)
A:行,你这个比较重要,先处理吧,我等会儿。(A开始跟旁边的C闲聊扯皮)
10分钟过去了...
B:我处理好了,我们开始聊吧。
聊了2分钟之后,B的上级D走过来跟B说了...
D:昨天讨论的那个项目先评估一下工时给我,我要盘一下我们组的人力情况。
B:好的,我马上评一下。(对A说)不好意思,我评个工时,等我10分钟。
A:好。(继续放飞自我跟C闲聊扯皮...)
场景二
A是开发,B是产品经理。
一天B找到A,反馈一个线上问题。
B:这个商品图片下面应该有个权益图标,怎么没有了,赶紧看看吧。(面露狰狞,唾沫横飞)
A:我这段代码写了一半,让我先写完再给你排查,等我5分钟。
B:好吧,那你快点。(站在旁边一脸无奈的发呆)
5分钟过去了...
A:我写完了,开始排查问题吧。
B:...
问题在哪里?
从场景一中可以看出,A的工作效率是很低的,因为大部分时间都是在等B。A一天能做多少事基本就取决于等B要等多久(资源利用率低)。
从场景二中可以看出,A因为要坚持写完代码,可能会导致错过了解决线上问题的黄金期,让线上问题扩大了。(对不稳定服务强依赖导致的风险)
最后,从两个场景中,我们应该都能看出来,等待的那个人(请求方)心里肯定是不爽的(用户体验差)。
2.2 非阻塞工作的场景
场景一
A是交易领域的技术大神,B是商品领域的技术大神。
一天A在钉钉上跟B聊天。
A:你看啥时候有空,想跟你了解下交易流程中关于商品的缓存更新问题。(说完没等B回复,就开始整理等下想要问B的问题..)
10分钟后..
B(在钉钉上回复A):刚在处理一个线上问题,现在有空,来吧。
A和B愉快的在一起聊了10分钟。突然A的上级C跑过来说线上有个问题,需要A紧急修复一下。于是A走了..
B觉得商品的缓存更新问题应该是一个常见的技术问题,决定把这一块的技术细节写成文档,后面可以提供给新人或其他技术看。
B的效率很高,半个小时就完成了文档编写,他把文档链接发给了A,并留言:你有时间先看下文档吧,不清楚的地方我们再讨论。
A处理完线上问题已经是1个小时以后了,他看到B发给他的文档,顿时茅塞顿开,困扰很久的疑团烟消云散..
场景二
A是开发,B是产品经理。
一天B找到A,反馈一个线上问题。
B:这个商品图片下面应该有个权益图标,怎么没有了,赶紧看看吧。(依然面露狰狞,唾沫横飞)
A:我正在评估一个项目的工时,等下老板开会的时候要用到的,一时抽不出身。要不这样,如果特别紧急的话,你找下C,让他先排查。如果不是很紧急的话,就等我5分钟。
B在脑海中恶补了等下他老板发现这个问题的时候训斥他的场景,觉得这事特别紧急。于是他找到了C。
C刚好有空并顺利解决了线上问题。
解决问题了吗?
从场景一中可以看出,A的工作效率是比较高的,因为几乎没有等待的时候,绝大部分时间都是在有效工作(资源利用率高)。
从场景二中可以看出,A虽然有事情要处理,但是没有让B等他,而是马上给了B另一个解决方案,最终用这个方案成功解决了线上问题。(对不稳定服务的弱依赖或有降级方案来降低整体风险)
最后,从两个场景中,我们应该都能看出来,由于不存在等待的情况,所以请求方的用户体验相对要好很多。
2.3 阻塞和非阻塞的选择
谁好谁坏?谁对谁错?
小时候看电视的时候,我们经常会讨论剧中哪个是好人,哪个是坏人。成年后,发现世界并没有那么简单,单纯的0和1已经不能满足需求了。成年人的世界没有对错,只有利益权衡。
很简单,每个解决方案都不是完美的,总有优劣势。而在某个场景下,某种解决方案的优势>劣势时,那么用这个方案就是合适的。
看似非阻塞的工作模式远远优于阻塞模式,貌似阻塞已经没有了存在的必要。但是仔细想想你就会发现,阻塞模式除了很明显的几个缺点之外,还有以下2个优点:
- 工作模式相对简单,适合新人或能力较低的人员。
- 在一段时间内可以专心且完整地做一件事,如果中间没有等待的过程,整体效率是很高的。
与之相比,阻塞模式的优点就是非阻塞模式的缺点:
- 工作模式相对复杂,不适合新人,对人的能力要求较高。
- 因为处理一件完整事务的时间可能被打散,那么就会存在从另一项工作切换回原先工作内容的时候,大脑会有一个切换成本(说白了就是要时间让自己回过神来,而这个时间的多少将直接影响你的工作效率)。
各自手段及工具
阻塞的手段
一般就是被请求方主动提出让请求方等待。不要认为让对方等待就是不尊重对方,尊重是相互的,如果对方真的尊重你,那么他一定会询问你现在是否有空,而不是随意地打断你的工作。特别像程序员这种创造性的工作,一旦被打断(尤其是在灵光乍现的瞬间),想要回过神来,短则10几分钟,长则个把小时也是可能的。所以,程序员有时候为了保护自己,学会让对方等待也是很正常的。
非阻塞的手段
- 借助聊天工具(像钉钉,微信这样的im,本身就不是为了实时响应,大部分是为了处理一些非紧急问题)。
- 借助文档来避免面对面沟通的阻塞问题(面对面沟通部分时间是在等待对方思考)。
- 借助backup来避免流程上的阻塞(比如上面的场景二)。
实际工作的情况
很多人都想让自己的工作变得简单,但现实中复杂是职场上的必然存在,往往我们在工作中不会只做一件事,也不可能一直顺利的把一件事情从头做到尾。那么结果就是,阻塞固然会存在,但是非阻塞绝对是占了大部分的工作时间。因此,怎么改进非阻塞工作的流程就是关键了。
首先是提高自身能力,可以应对更复杂的任务。其次是想办法减少不同工作之间的切换成本,这里可以用任务分解,任务粒度越小对于之后的切换成本越低(任务分解是另一个专业领域的事了,这里不再展开),也可以利用一些时间管理工具来帮助自己。
三、总结
在职场中,不管用哪种工作方式,最终的目的都是为了提高工作效率,在有限时间内做更多重要的事。所以在你不知道怎么做的时候,可以用这条原则作为你最根本的行为指导。
另外,人与人之间合作交流,有时候难免会有等待,一旦发生等待,整体的工作效率必然是有损耗的。那么当你跟别人合作时,可以有一个最基本的原则:不要等别人,也不要让别人等你。