oXiaoChong 2020-06-20
拨云见日的一周。
104:Maximum Depth of Binary Tree(Easy)
树的很多问题首先考虑遍历,几种前中后序遍历只是打印时机不同,实际都是一样的 DFS,此外 DFS 也可以不用递归,手动使用栈结构模拟,最后还可以使用 BFS,借助 queue 优先处理完上面一层再处理下面的。
236:Lowest Common Ancestor of a Binary Tree (Medium)
借助树的递归遍历,而递归函数的关键是处理这个子树应该返回什么,再细分就是终止条件返回什么、后续递归结果处理什么。
首先是终止条件,遍历到 a、b、null 就返回它们,因为即使 a、b 节点后面还有 b、a,根据题目也应该返回 a、b。
后续递归结果如何处理,对左右子树的递归结果,可以范围三类情况,1两个子树只有 a、b 中一个值、另一个是null,返回 a、b,2两个子树都返回 null,都不存在继续返回 null,3两个子树各是 a、b,说明当前节点就最近公共祖先,因为 DFS 遍历,返回过程是从底到上。
补充,这类树或DAG在实际应用中更多是通过parent节点串联起来,这时找最近公共祖先变成了第160题的找两个链表的交点。
Kafka: a Distributed Messaging System for Log Processing
著名的 Kafka 论文,发表于 2011 年,非常简单易懂,展示了一种以处理日志为目的的分布式消息系统,通过批量处理、存储优化(append only)、传输优化(zero copy)、无状态 broker、去中心化、消费者组和 rebalance 等一系列不同于以往消息系统的实现方案,达成高吞吐、低延时、易扩展的日志处理领域的专业系统(specialized system),同时满足实时在线业务和离线分析业务的日志处理需求。从这篇论文也可以看出,当时 kafka 还没有 follower 副本概念、没有发送消息后 ack 机制、分区 offset 也是写到 zookeeper 中,这些问题都在后续版本中逐步解决。论文最后特别提出计划增加流出处理能力(stream processing capability),也就是后面重点发力的 Kafka Streams,因为消息系统天然就是流处理的管道,只是似乎买单的人不多,大家仍然只是把 Kafka 当作消息管道,后续处理则使用 Spark、Flink 等各类计算引擎。
Flink、PyFlink、Alink、PyAlink 关系,以及其中 Python VM 和 Java VM 关系
最近使用 Alink 进行机器学习中特征处理工作,发现其中有 Python 调用 Java,以及 Java 调用 Python 两种情况,而且最后竟然 It just works,这里总结一下其中奥秘。
首先 Flink 是 Java 和 Scala 语言开发的分布式流处理框架,通过在客户端代码中使用声明式 API(也可以嵌入很多 function 来定制逻辑)表达处理逻辑,解析生成 DAG 执行计划后提交到 Flink 计算集群中运行和调度,整个过程不管客户端部分还是运行环境,都是在 Java 虚拟机中。PyFlink 项目则是为了使用 Python 语言完成 Flink 计算任务开发,然后提交到 Flink 集群中运行,即 Flink on Python。另一方面也为了将 Python 生态(其他类库)集成到这个任务计算过程中,也就是在 Flink 集群中也可以运行 Python 代码,即 Python on Flink。这个过程如下图所示:
对于 Pyflink 架构,首先为了使用 Python 语言完成 Flink 计算任务开发,这依赖 Python API 部分,通过 Py4J 这个 python 与 JVM 之间通信桥梁(分别在python和java 端存在 gateway,调用 mapping 到的对象和方法),调用所有已有的 Flink Table API,避免了用 Python 重新开发已有 Java 代码的逻辑,最后调用 execute 后生成执行计划提交到到集群运行,事实上 PySpark 也是这么做的。有趣的一点是,为了使 Python 代码可以使用其他 Python 生态中的类库参与 Flink 计算逻辑,这里通过在 Flink API 中注册 Python UDF 函数实现这一目标,这样在生成的执行计划中,不仅有 Java 的算子(operator),还有 Python 算子,这就又涉及到了集群上 Java 调用 Python(以及其依赖的整个 env)部分,Pyflink 这里采用了 Apache Beam 的 Portability Framework 解决 Python UDF 执行环境问题,对使用者来说就是需要提前将装好 pip 依赖的整个 env 打包上传到 flink 集群,并在代码中指向它。
最后,Alink 是基于 Flink 的机器学习算法平台,它基于 Flink 的 Table API 再封装了一层,并实现了各种算法和特征处理算子,包括数据处理、特征工程、模型训练、预测等部分组成 Pipeline。为了和 AI 生态融合,它也包含了 PyAlink 部分,类似上面的 Python 调用 Java,然后 Java 中调用 Python UDF 这样的处理过程。
分享《即答力:年轻人的自我更新指南》中几个观点。
即答力
能不能把握机会,就要看他人主动与你交谈的时候,你能否做到“即答”。换而言之,如果对方开口说:“有这么一件事,你要不要做一下试试?”你要迅速明确地回答要或不要。如果有人询问:“有没有人来做这件事?”你要举起手果断回答:“我来做!”
能否瞬间做出判断、当即回应,决定了你能否抓住机会。
在人生旅途中,当有“比试”出现的时候,“机会”之球就会被抛向我们。即答就是立刻接住球,并“啪”的一声将球果断打出去。
……
心态,能解决人生80%的问题
我们每天面对的并非都是有趣的事。如何用享受的态度看待它们是工作的重点。
要努力期待一切,享受一切,用力让自己向着充满期待的方向前行。这一点在任何情况下都很重要。如果你拥有享受、期待的心态,就能与事物产生更深的羁绊。此时,率先调动自己的积极性,就是即答力的表现。
比如,在饭菜不好吃的情况下,你要以怎样的心态去品尝食物?
是一边想着“难吃,真难吃”一边往下咽,还是带着“味道很奇特”的想法去品尝,又或是饶有兴致地思索:为什么会产生这种口味呢?
你选择的品尝方式会成为“思想前提”,让你感知到截然不同的味道。
“享受”是让我们掌控自身经历的万能调味剂,我们可以把它活用在生活和工作的各个方面,比如品尝食物、工作、读书、与人交流等。
我希望大家能够避免不自觉地带着痛苦前行。如果只是一味抱怨、发牢骚、感到不满,你只会产生负面情绪,最终一无所获。
更可怕的状态是“等待别人让自己产生享受”的心态。这种被动姿态会钝化你的速度感,导致即答力的远离。
……
失败有时能让我们更强大
迎接挑战的时候,我们会遭遇很多失败。
失败并不是一件可怕的事情,我们应当积极去体会。我相信风险和失败会成为我们成长的食粮。正因为这样,我们才应该多多接受挑战。
为什么这么说呢?与一帆风顺的境遇相比,失败能让人学到更多的东西、积累更多的经验。刻骨铭心的经历会成为我们身上的血和肉,伤口则会让肌肉更加强健。
最重要的是,要懂得以对失败的懊悔作为引子,仔细思考失败的原因,为下一次的成功做准备。
当你从失败中重新振作起来后,一定会惊讶地发现,自己的速度感和即答力变得更强了。当你认真应对某事时,身上的强大魄力或许会让自己感到震惊。
可是,如果你为了避免失败而逃避所有问题,就算暂时处于安全的状态,也只能过着无趣的生活。未来的你将无比后悔,并经历更多的失败。
失败的风险是巨大的,让大家完全忘却对失败的恐惧实在是有点强人所难。对于害怕失败、不敢迎接挑战的人,我建议不必刻意消除这种心理,带着这样的心态“闭着眼跳下去”就可以了。
在商界,如果你不抱着失败的觉悟,往往无法渡过难关。
……
不要片面地作出判断
前日本国家足球队主教练奥西姆说过:“球队需要多样化的球员。”他口中的“多样化”是指具备多项能力。能够迅速判断球队当下需要的能力、迅速提供自身的力量,这种球员常常在比赛中起关键性的作用。球队需要的不是擅长射门、善于防守的“专家”,而是在球队有需求时能胜任任何位置的多面手。
在我看来,成功人士无一例外都拥有多样能力。人脉、工作方法、生活方式,他们在方方面面都不逊色。
他们不会意气用事地想“那种做事方式不符合我的风格”,也不会带着狭隘的傲慢说“那种无聊的工作我可不干”。就算在别人看来,某项工作任务“也就那么回事”,只要能为部分人带来幸福、有做的必要,他们就会不带偏见,并开心地尽力将它完成。
为什么他们不认为“做无聊工作的人=无聊的人”呢?因为他们明白,工作没有无聊或精彩之分。他们本身就具备多种能力,处理简单任务的力量只是其中一部分。就算他们做着别人眼中“无聊”的工作,也能在其他场合完成重大任务,让他人惊叹“好厉害啊”。所以没有必要纠结“这种小事将决定我工作的价值”的问题。
多样化人才乍一看或许极具艺术家的气质,其实也会愉快地与人进行朴素的工作交流。进行创作的时候,他们会激烈地发言,同时也会开口谈接地气的问题,比如“办公流程效率化”。正因如此,他们才能与任何类型的人在任何环境下共处。
……
不要迷茫,做就对了
成功往往会通过连锁反应,带来更多的机会。
要想获得更多的机会,就必须有成功的经验。“成功吸引机会”所言非虚。
实际上,最难的就是获得这一吸引机会的契机。在初期机会不多的情况下,要取得成绩是非常困难的。
没有成绩,也就无法连锁获取更多的机会。但是,无关大小,有实际成绩就好。就算一开始你迈出的步子很小,也没关系。
拼命努力,凭自己的力量迈出第一步吧。随着你的不断前行,合作者将陆续出现在你的面前。你将获得他人的帮助并与之携手同行,但这些都是后话,第一步永远只能靠自己。
我的个人经验是,要取得第一笔“实绩”,就要积极接手他人讨厌的工作、他人嫌麻烦的工作、他人不愿做的小事。当有人开口说:“随便来个人做一下这项工作。”你应当迅速做出回应。
这样一来,你就能抓住机会先取得小小的成功,获得实际业绩。将这份“实绩”作为踏板,在以后不断获得更多机会是非常重要的事情。
……
如果回到二十几岁的年龄,我会率先去做他人最不想做的工作,因为在这些事务中,存在着谁都不曾留意的新问题和尚未被发掘的机会。面对竞争少、能够让自己迅速脱颖而出的比试机会,你没有理由不参加。
这是起点,不是我们的最终目的地,所以你没有必要因为“做这些没有意义” “这种工作不适合我”而苦恼。不要迷茫,做就对了。