Spark源码分析:从collect入手

要研究spark的源码,输入和输出是很好的切入点。Dataset的基本操作就是collect了。

// spark/sql/core/src/main/scala/org/apache/spark/sql/Dataset.scala
def collect(): Array[T] = withAction("collect", queryExecution)(collectFromPlan)

private def withAction[U](name: String, qe: QueryExecution)(action: SparkPlan => U) = {
  SQLExecution.withNewExecutionId(qe, Some(name)) {
    qe.executedPlan.resetMetrics()
    action(qe.executedPlan)
  }
}

private def collectFromPlan(plan: SparkPlan): Array[T] = {
  val fromRow = resolvedEnc.createDeserializer()
  plan.executeCollect().map(fromRow)
}

这段代码看上去有点绕,我们做一些语义上的替换,就变成下面这样。

程序员生存指南:时间与带宽

刚过完年的时候,可能大家还沉浸在休假的状态中,工作并不忙。发现这段时间的自己有明显的变化。比如,虽然去年11月就准备写这篇博客,但大脑总是一片空白,不知道怎么写下去。现在却文思泉涌,各种想法都蹦出来了。又比如,讨论需求更加投入。以前忙的时候只会想着怎么才能快点结束讨论,技术上能否实现这个需求,甚至为了快点结束还会做一些妥协。现在则会思考对方的需求是否合理,坚决不妥协,而且还要说服对方接受我的方案。再比如,经常内省,这周的目标是什么,这半年的目标是什么,长期的目标又是什么。为了达成这些目标我需要做些什么,哪些地方做的还不够。这是一种非常理想的状态,因为自已一直在思考,而不是瞎忙。

但这种状态很难持续下去。一旦年过完了,工作回到正轨,自己就会变成“机器人”。机器人可能是这样度过一天的:早上到公司撸起袖子准备大干一番,打开了一段代码,刚开始思考这段逻辑应该怎么写,忽然来了电话咨询问题。解答完问题后准备回到代码上,企业微信群又反馈了一个紧急的线上bug。还没等处理完bug,一个会议马上要开始了。开完会回来刚把手放到键盘上准备开始写代码,又收到一封邮件。项目pm在邮件中写到,由于你的原因,项目整体进度延期了。这下好了,花大半天的时间跟各位老板解释,项目延期的原因是什么,为确保以后不延期我应该怎么怎么做。等复盘完这些,抬头一看天已经黑了。猛地发现代码居然一行都没动。下班路上回想这一天我都做了些什么,明明很忙很累但又好像什么目标都没达成。每天都是这样的状态,项目延期是必然的。

如同乞丐时刻担心下一顿饭怎么解决,我每时每刻都在担心怎样才能多抢一点时间。我就是时间上的乞丐,生存下去都成问题了,唯一的目标变成了抢时间,哪还有心思进行深入的思考。如何才能延续这种状态,避免变成机器人呢?

程序员生存指南:做浮夸的程序员

说服别人是非常难的一件事情,每个人都有难以逾越的心理防线,甚至有时候说服自己都很困难。虽然自己已经意识到了问题,却不愿意承认,更不会改了。直到经过了漫长的时间后,发现切身利益受损才会痛改前非。为什么说服自己如此困难?

有个朋友说话直来直去,不考虑听众内心感受。提醒他改的时候,他也有非常强的理由:我讲话直来直去是因为我性格直爽,不会奉承别人。我终于明白了,他心里觉得这种行为有非常强的“正义感”,自己就是正义的化身,那怎么能算得上错误呢,为什么要改?原来我自己也是一样的,因为“正义感”作怪而无法改正某些错误。

比如,我一直认为只动嘴不做事的人是非常可耻的,不正义的。作为“正义化身”的我一定不能跟他们一样。慢慢地走向另一个“极端”,事情越做越踏实,表达却越来越少了,变成了“踏实派”程序员。

用emacs和gpg保管你的小秘密

我以前从来都不记工作笔记。涉及到内部工作的信息,用evernote或者其他类似的笔记软件都不够安全。万一哪天evernote被拖库了呢?安全隐患太大,所以为了避免出现安全问题,干脆就不记了。但是确实不方便,脑子里不可能一直记住所有的东西的。除了工作内容之外,每个人都有自己的小秘密。如何把这些小秘密安全的记下来呢?

十年学会函数式编程:Type Class

上一篇博客中我们聊了ADT,我们知道了ADT也是关于类型的,我们还和面向对象的class做了比较。此时再看到 type class 这样的词语是非常崩溃的,我的天呐到底还有多少和类型相关的专业词汇。Type 我也认识,Class 我也认识,合到一起又是什么鬼?Type Class 确实又是一个难以理解的概念,我觉得难理解和名字起的不好有很大的关系。词汇真的是匮乏,又不能凭空造一个词出来。但是 Type class 又是必须要理解的一个概念,不然的话可能连 cats 的文档都看不懂。

十年学会函数式编程:ADT(Algebraic Data Type)

几乎每一本讲 FP 的书里都会提到 ADT 这个概念,但是好像没有人彻底讲的明白,所以我之前一直不理解。ADT 到底是什么呢?Algebraic 这样的词让人一看就很头疼,写个代码怎么还跟代数产生关系了呢?让我们看看维基百科上的定义:In computer programming, especially functional programming and type theory, an algebraic data type is a kind of composite type, i.e., a type formed by combining other types.

没有什么特殊的,只不过是一种组合类型,由多种其他类型组合而成的类型。Algebraic 是体现在哪里呢?Haskell wiki 是这样描述的:

  1. sum is alternation (A | B, meaning A or B but not both)
  2. product is combination (A B, meaning A and B together)

Algebraic 体现在组合的方式上。把 product 换成 and,sum 换成 or,是不是就容易理解了?product 是 X has an A and a B,sum 则是 X is an A or B。虽然 ADT 看起来很复杂,但其实我们每天都在用,只是没有意识到背后的概念罢了。

十年学会函数式编程:入门的最差实践

不知道大家有没有类似的体验,有些概念如果直接告诉你它是什么,无论如何都理解不了。但是如果再告诉你它不是什么,可能就恍然大悟了。同样的,有些事情告诉你怎么做(Dos)往往不如告诉你别怎么做(Don’ts)来的更有效。回顾我学习FP的历程,确实存在这样一些最差实践,如果避开这些坑,入门应该是不需要十年的。

十年学会函数式编程

Peter Norvig 大神多年前写过一篇 Teach Yourself Programming in Ten Years,阐述了为什么学习编程是持久战,没有捷径可以走,以及应该怎么去学习编程,每个程序员都应该看一看。里面有句话讲得特别好(不仅仅局限于编程领域):

The key is deliberative practice: not just doing it again and again, but challenging yourself with a task that is just beyond your current ability, trying it, analyzing your performance while and after doing it, and correcting any mistakes. Then repeat. And repeat again.

Peter文章的“十年”是个夸张的说法,主要是为了强调学习编程没有捷径,引导大家摆脱急功近利的心态,他学编程当然不需要十年。我的这篇文章标题差不多,就多了一个Functional,但我是真的用了十年的时间才学会的,而且顶多只能算是入门而已。所以对我而言十年并不是夸张的说法,是智商真的有限。

其实函数式编程(Functional Programming,以下简称FP)并不神秘,只是很多人把它吹得过于神化了。

Protocol Buffer高阶玩法:如何优雅地批量修改proto文件

每个程序员少不了和Protocol Buffer打交道。Protobuf现在几乎已经是业界标准了,设计rpc接口协议不会考虑其他的选择。可能也有人喜欢造轮子发明自己的一套协议,但是请相信我,造这种轮子除了可以用来汇报之外(前提是先说服老板允许你浪费时间造轮子),基本上不会给公司业务、后台服务上带来什么效率的提升。Protobuf有诸多家喻户晓的优点,比如广泛的支持各种语言、具有良好的版本兼容性、体积小解析快等等。作为后台协议这些特性可以说是基本的要求。但是protobuf之所以这么优秀,我认为还离不开它丰富的api和可扩展性。

Why Emacs?

Emacs已经陪伴我十几年了,称得上是第二个人生伴侣,只要开电脑就习惯性地打开Emacs。内心由衷地感谢Richard Stallman,开发出这样一款编辑器,给平淡无奇的程序员生活带来许多乐趣,是时候给Emacs写一篇软文了。Emacs诞生于1972年,可以说是相当古老了。现在已经2021年了,这个老古董还能继续用吗?