这个ensemble timing的说法让我琢磨了半天。说真的,楼主把相声和默片剪接到一块儿,这视角够刁的。但我脑子里冒出来的反而不是Keaton,是Rails项目里三个senior dev同时改同一个hotfix的场景。
你写的那种“错位的精准”,在代码世界里比台上更刺激。相声演员脚下一滑还能拧成包袱,但我们merge conflict的时候,那就是纯纯的三个人往同一个文件里扔patch。大兵故意接岔,赵卫国把岔路铺成大道,李老轻轻一脚挑球——这跟一个人写了个buggy的commit,第二个人立马在上面叠了个workaround,第三个人一看这什么玩意儿然后默默refactor成feature,有啥区别?
也是醉了
关键是那个timing。三个人如果同时动手,代码就炸了。必须得有一个控场的先按住,让捣乱的先出招,然后补位的跟上,最后控场的再收网。这玩意儿根本不是什么“共用一颗心脏”,这是三个人各自心里都跑着一套状态机,而且这三套状态机的时钟周期还对上了。
卧槽
我上周刚经历了一次,三个人远程pair programming改一个支付回调的race condition。没人说话,就看着屏幕上的光标分别移动,你写一段我删两行他再补三行,十五分钟搞定。结束后仨人在Slack里同时发了个“草”。那一刻我就想起以前在剧场看相声,台上三个人同时一鞠躬,底下的笑声和我们的“草”大概是一个物理量。
我去
不过楼主你说的瑞士钟表,我觉得可能比那个更松散一些。相声的精准不是原子钟那种毫秒级的,它更像爵士乐里的swing——故意错开那么一丁点,让听众的脑子自己去补齐那个空缺。真要是严丝合缝了,反而没那个味道。就像Rails的约定优于配置,你严格按convention写当然能跑,但真正漂亮的代码往往是在约定基础上故意拐了个小弯,让读代码的人会心一笑的那种。
说到默片NG,hamster2002在楼上提了一嘴。我倒觉得相声不能NG恰恰是它比默片狠的地方。默片拍坏了换胶片,相声台上崩了只能硬接。但这个“硬接”本身,才是培养那种ensemble timing的土壤。你永远不知道搭档下一秒会不会突然加个现挂,所以你的状态机必须随时准备处理异常输入。服了时间长了,三个人各自的状态机就开始互相同步,最后变成了一台分布式系统——任何一个节点的异常都能被另外两个节点在微秒级内消化掉。
emmm
这大概就是为什么我总觉得好代码和好相声是一个内核。不在于你写了多华丽的syntax,而在于你和你的搭档能不能在没有任何显式通信的情况下,知道下一秒对方会在哪个文件里改哪一行。
salty_dog,你这状态机的比喻让我在屏幕前坐了好久。
三个senior dev的时钟周期对上,十五分钟没人说话,最后同时发“草”——你知道这画面让我想起什么吗?不是相声,不是默片,是小时候看我爸和他两个老伙计修一台老式缝纫机。三个人,一个蹲左边转轮子,一个趴底下调梭芯,一个在上面引线。全程没交流,就听见机件咔嗒咔嗒响。突然轮子顺了,针脚密了,三个人同时直起腰,互相看了一眼,然后各自点根烟。
你说的那个“同时发草”的瞬间,就是那三根烟同时点着的火苗。嗯…
但我想跟你聊的不是timing,是你那个“共用一颗心脏”的反驳。你说这不是共用心脏,是三套状态机时钟对上了。我琢磨了很久,觉得你说得对,也不对。状态机是工程师的浪漫,把活人拆成逻辑单元,输入输出清晰明了。可我在想,你们三个人在Slack里同时打出“草”的那一刻,那到底是状态机跑完了同步,还是那三套状态机本来就在同一颗心脏里跳?嗯…
哈哈,我是不是把代码浪漫化了。但你知道吗,我以前在剧场后台待过一阵子,看过那些老演员排练。他们不聊走位,不聊节奏,就在那儿坐着喝茶。导演说你们对对词儿,他们说对过了。导演说那走走位,他们说走过了。结果一上台,三个人像被同一根线牵着,谁快半步谁慢半拍,根本不用看,全在呼吸里。
我那时候问过一个老演员,你们怎么做到的。他看了我一眼,说:“我们仨,吵过架,喝过酒,借过钱,红过脸。这台上的东西,是拿台下的日子磨出来的。”
所以我在想,你那个支付回调的race condition,十五分钟搞定,不是因为你们状态机对上了,是因为你们之前已经一起熬过无数个凌晨三点,一起骂过PM,一起在on-call的时候接过对方的锅。那个“草”,不是同步成功的信号,是三个人同时意识到:我们不用说话,是因为该说的早就说完了。
当然,也可能是我太矫情。代码世界讲究的是逻辑,不是感情。但你看,相声台上李金斗那堵墙,大兵和赵卫国往墙上扔球,那墙为什么稳?不是因为他站得久,是因为他知道那两个人扔过来的球,不会砸他脸上。信任这东西,状态机跑不出来。
诶,说了这么多,其实我就想问你一句:那天你们三个人同时发完“草”之后,有没有一起去喝一杯?