上次 MacTalk 的池老师写了一篇「编程之路」{附在文末},让我也不仅回忆了一下我的「编程之路」。细想起来,应该是非典型的,但是可能也不乏同路人。写出来,当留给自己吧。
本科:理论知识和汇编语言
我接触编程其实很晚,是大学的时候。那时候其实喜欢数学,少年班可以自由选专业,当时差点选了数学,然而不太喜欢寝室另一个铁定学数学的妹子,我又是那种不喜欢一个人有多远就躲多远的那种,所以干脆选了计算机。加上当时班上选计算机的女生就我一个,另几个男生都是特别投缘的几个哥们儿,所以很开心地就去学计算机了。另外那时候校园 BBS 正火,我也是玩的不亦乐乎,觉得学计算机至少上网的机会多很多(当时是那么觉得的)。所以学计算机这事就这么愉快地决定了。
等到真的开始上专业课,发现自己其实理论很强、动手却比较弱。所有专业课里面的理论课,像数据结构、算法、数理逻辑、编译原理、体系结构什么的几乎都是满分。但是每门课的大作业和要动手搭系统的部分,都有点无从下手,做的也慢,也不感兴趣。好在当时人缘好,上机作业总有人 “帮忙”,加上当时大学对动手能力要求也并不算很高(现在想起来)。所以也是混成个假学霸的样子。
本科的毕业设计是要进实验室做东西的。当时稀里糊涂怎么就进了一个体系结构的实验室,做嵌入式系统的指令集设计。需要写一些汇编,跑一些实验。但是并不需要做大的软件工程。所以当时感觉自己还是理论远远高于实践(总想起天龙八部里面的王语嫣那种人,说啥都知道点,就是自己做不出来。)
其实本科阶段,真的就一个字:混。
硕士阶段:各种底层系统、编译器、函数式语言
科大申请出国就像当时很多学校的同学没事考个四六级证书一样,每个人都不用太去想,跟着大环境就开始折腾托福、GRE。当时你要问我为什么出国,不过是因为觉得周围小伙伴都申请的热火朝天,自己也不能落后。
稀里糊涂的,居然也就被 Rice 录取了。按博士入学的。但是美国很多研究生院在拿博士学位前是需要拿个硕士学位的。所以这里会有一个硕士阶段。
我的导师是做程序语言设计的,也就意味着成天和编译器、解释器、语法器打交道。而且他的方向是函数式语言(Functional Programming Language)。主要用的是 OCaml。
美国硕士阶段需要重修几乎所有的专业课。而且对动手能力的要求极高。
所以硕士那三年,我差点没死过去。
理论部分完全没有问题。而所有的大作业、大项目,一开始做起来,可能要花别人两三倍的时间。加上本来课业就重,还有科研项目要做。因为拿的全额奖学金,还有很大的心理压力。总之当时的感觉每一天都在 Push 自己的极限。好在那时候是真的年轻身体好,一天平均睡四五个小时也能熬的过来。几乎没有任何的课余时间,寝室楼、系楼两点一线。大学那种轻松的状态一去不复返。感觉每一天,都是当三天来用的。
好在也活过来了,不过这三年是我真的 “会” 写程序的开始。可以自己一个人从头到尾搭各种简单的系统:网络相关的、算法相关的、分布式相关的……尤其是编译器相关的。但是大部分做的还是比较偏底层的。
实习:Matlab、Controller、Simulator、C++
读硕士阶段的暑假会去大公司做实习生。当时因为在 Houston,所以两次实习去了同一家石油公司:Schlumberger。做的项目是给井底的机器人写控制算法。因为硬件很贵,出不得错,所以每个程序会在 Matlab 上用 Simulator 先做各种测试。就是那个时候把 Matlab 用的纯熟,也了解了一些大公司的软件工程和开发流程。对一些软硬件协同设计也有了更进一步的了解。
博士阶段:数据分析、数据建模、Python、C++
我读硕士阶段的导师后来因为个人原因离开了 Rice。所以我跟了另一个做 BioInfomatics 的导师继续我的博士阶段。他主要做的是 DNA Sequenece 和 蛋白质网络相关的研究。因此我的课业很大程序上就是大数据建模和数据分析。也会用到一定的机器学习,但是主要还是无监督算法。因为数据处理需要采集和预处理,所以当时每天要写很多的 Python 程序。而实际的数据建模和分析因为数据量太大,一般语言性能不够好,所以使用的 C++。更多编程解读:www.yangfenzi.com/tag/biancheng
入职初期:Web Server、Search Backend、Ruby、Java
真正开始工作后,我的文章里提的比较多了,做过搜索和支付,主要用 Ruby 和 Java。
其实最开始的时候心里很虚,因为觉得自己碰过的东西其实和互联网没什么关系,却突然进了互联网的领域。总感觉自己什么都不会。开始的时候也确实是什么都不会。所以那个时候每天都压力都很大,每天也加班,因为和别人差距太大了。不过可能毕竟很多计算机技术相关的知识是相通的,慢慢地似乎发现很多以前了解的知识和学到的技巧,还是可以应用到解决问题中的。
说着轻松,其实也是经历了很长时间很有挫败感的阶段,才慢慢好起来。
所以呢?
有人问过我:“你觉得学 XXX 有没有用?” 这叫我怎么说?我自己就学了一堆 “没用” 的东西啊。我不会的东西很多。我会、但是用不上的东西也很多。
花了这么多年,才认识到这一点。最大的收获,不过是现在可以坦然面对工作上很多不会的东西。很多用不上的东西,了解个大概也就放下了,因为精力实在有限。工作真的需要的,那就去学呗。毕竟,我会的,有用的东西并不多。
经常后台有留言让推荐好的技术公众号,我订阅的不多,所以又去在朋友圈收集了一下,下面一些,大家可以自行订阅评估下。放在前面的,是我也觉得不错的,后面的,是朋友推荐的。喜欢的话,以后再荐。
技术人的博客一:嘀嗒嘀嗒的哥哥们——科技互联网类公众号推荐
技术人的博客二:技术圈最值得关注的大牛自媒体推荐
InfoQ
小道消息
MacTalk
二爷鉴书
StuQ
jnby1978
老王卖瓜
程序人生
余晟以为
待字闺中
神秘的程序员们
歪理邪说
keso怎么看
高可用架构
中生代技术
架构师之路
移动开发前线
iOS 开发
码工猴哥
硅谷周边
程序员的那些事
GrowingIO
ImportNew
RedHadoop顶级程序员
Python开发者
CPP开发者
机器之心
Hadoop123
测试架构师
美团点评技术团队(meituantech)
【文/朱赟 (嘀嗒嘀嗒 微信公号:AngelaTalk)】
————————————————————————————————————————————————
《池建强:我的编程之路》
在生活中或者网路上,我经常被问到的问题就是如何学习编程,如何学习一门编程语言。其实编程这个事儿,就不是什么难题,尤其是入门。这就像入水一样,有的人在十米跳台向前翻腾3周半抱膝再转体360度,还能压出一脚5厘米高的水花,有的人呢,衣服都没换,就从岸边一头栽水里了,下去之后还发现了自己不会游泳。
但只要你想入水,无论如何都能做到。
很多人来问我,并不是我程序写得多好,更可能因为我这里是个入口。在编程方面,我认识很多在各个领域昂霄耸壑的高手和大师,但我一直是个编程资质平庸的人。这倒不是谦虚,无论你多么年少轻狂,以为自己无所不可为,随着齿岁渐增,你会发现自己的所知所见,终究是沧海一粟。学的越多,越不敢轻言所知。
每个人的编程之路最终能够抵达哪一座山峰,和我们的资质、编程经历以及编程之路上的导师息息相关。吴翰清(道哥)、朱赟(安姐)这种神童级别的人物,如果有足够的韧性和远见,一定会比普通人走得更远。云风这样的程序师,自幼学习编程,十数年间从未中断,编程经历丰富不做他想,也会取得极高的成就。而普通人如果能够做到坚持学习和自省,日拱一卒,不期速成,将来能达到什么成就,也未可知。
计算机并不神秘,而程序,最终也只是表达计算机控制逻辑的符号而已。
说说我自己的编程之路吧,非常接地气。小时候我没见过电脑,原因就一个字:穷。做为一个在八线城市长大的孩子,我差不多是在上大学之后才开始真正接触电脑。我的专业是机械加电子,其实和计算机没啥关系,好在专业里有几门编程语言的课,C,Pascal,Foxbase 等,电脑是386/486,黑白的脸,没有奔腾的心。我个人对计算机充满了浓厚的兴趣,各个语言学得还不错,给老师写过一些类似图书馆书籍管理的系统,现在细节完全不记得了。
整体来说,我在大学里学到的计算机知识并不系统,不像现在的很多大学生,在学校里学到的东西已经很扎实了。换句话说,在互联网时代,很多优秀的大学生毕业的时候已经在编程领域达到了很高的水准,因为资讯和资料实在是浩如烟海。我是在工作以后才真正开始接触编程工作,而真正开始编程,是从洪恩时代开始的。
在洪恩的三年半时间,是我职业生涯中最快乐的一段时光,我接受了真正的编程挑战,也遇到了我的良师益友。刚到洪恩的时候,他们正在做洪恩在线和论坛。当时我的组长对我说,你有两条路可以选,一个是去做前端,写 JavaScript 和 HTML,也可以做后端,写服务器相关的程序。我想了想,我还是写后台吧,前端不都是小姑娘做的么?十几年过去了,这个现状没什么改观,前端技术千变万化,我还是看到了很多写前端的小姑娘。
刚开始编写线上的真实程序,我用的语言是 Perl,当然也写 JavaScript,那时候 Perl 一边处理服务器端的逻辑,一边做 CGI,和前端页面混在一起,JS 用来处理页面的逻辑。因为自己底子差,于是从基础开始恶补,那时候也没什么事,天天泡在办公室编程和学习,每天工作时间都超过了十个小时(哦,现在似乎也差不多,看来没什么进步),编程能力和速度得到了飞速的增长。当然工资也涨了,老板都喜欢疯狂工作的员工!
随着业务的发展,我开始逐步接触不同的技术栈,比如汇编、C、Shell、Java、Python 等等,我开始恶补一些计算机基础知识,同时遇到了自己的导师,也是我的 Leader,他叫 baby。baby 毕业于清华大学,又读了中科院的硕士,出来工作的时候技术水平已经非常顶尖了,对操作系统、编程语言、数据存储等领域有深入的了解,公司的很多技术架构和选型都由他独立完成。我们遇到很多看起来难以解决的问题,到了他的手里,都可以顺水推舟,迎刃而解。当然,高手一般都不会那么耐心,但你可以学习他做事的方法,阅读他编写的代码,还可以偶尔问他问题。任何时候,成长都是自己的事,自己多下功夫,尽可能不打扰别人,这是个基本原则,我当年遵守的还可以。
那个时候公司牛人很多,我也乐得学习,算是我成长速度最快的一个阶段。离开洪恩后,颇有种拔剑四顾,眉宇苍茫的感觉,然后自己主导了一些技术和产品的实现,那时我傻傻的觉得自己已经洞悉了编程的奥秘。直到后来,我有幸参与了一个类似 CORBA 的分布式应用系统的开发,在那段时间,我差不多通读了这个项目的早期代码,其整体架构规划和代码设计的精巧程度让人叹为观止(代码的编写者是早期的 CORBA 规范制定者)。这件事让我对技术再次产生了沉重的敬畏感,所谓天外有天。这个经历对我后来的编程之路产生了深远的影响。
十几年过去了,学习编程的两个要素并没有改变。首先自己要足够的投入,想做一件事情,就坚持下去。这个世界能够坚持的人实在是太少了。你能做到工作之外多匀出两个小时编程,就已经打败了 90% 的人。其次,努力找到一个好的导师。
好的导师能够看到你自己看不到的地方。人这一辈子,很少人能给自己一个清晰的评价和认知,要么高估自己,要么低估自己,而旁观者,尤其是老师,往往能够看到你的弱点、长处、威胁、变化,并给你适时的提醒和指导,少走弯路。另外,所有领域的知识都是成体系的,如果有这个领域的行家里手在你早期的学习阶段进行指导甚至设计练习技巧,与自己琢磨的效果是不可同日而语的。可能每个人都会有这样的经历,一个问题自己想到心碎都没解决,别人过来随便敲几行代码,不仅你懂了,连你的小伙伴都懂了。
但导师都很忙,导师有自己的工作和生活……那你可以找线上的导师啊。现在互联网上的在线教育服务非常丰富,尤其是计算机领域。今天给大家推荐一个比较有特色的在线教育网站,我第一次知道这个公司是上次去硅谷的时候,叫做 Udacity,国内叫「优达学城」( http://cn.udacity.com ),他们课程的最大特点是以动手做项目为导向,遇到任何问题全程都有人指导。也就是说,你可以找到线上的技术导师。
优达学城的所有课程内容都来自硅谷,聚焦在最前沿的技术上,包括机器学习、人工智能开发、无人驾驶车开发、VR开发、数据科学等,热门的前端、全栈、移动开发也有。
所有课程都是和 Google、亚马逊、Facebook 等硅谷顶级公司合作打造,学员的认可度很高。国内的学员,毕业后可以内推去滴滴、优酷土豆、京东、新浪这样的公司。
他们也是美国在线教育三巨头中唯一一个专注编程教育的(另两家是 EDX 和 Cousera)。网站内的大部分视频部分都免费开放,核心学习产品「纳米学位」以做实战项目为核心,毕业后你的实践能力会很强,而且会有很漂亮的技术项目履历。
另外,我个人很喜欢的一点是,几乎所有「纳米学位」都可以免费试用一整周。课程适不适合你,质量到底好不好,试一试你自己就会有答案。
·氧分子网(http://www.yangfenzi.com)延伸阅读:
➤ 程序员的黄金时代 王欣、赖霖枫、邹胜龙、程浩、冯鑫的那些事
题图:weheartit.com
Square 是一家很神奇的技术驱动的公司。这个公司的文化很独特,就工程师文化来说,早期 Square 在技术上还是比较大胆和激进的。
为什么这么说呢?举几个例子。虽然 Square 的核心产品是信用卡读卡器,但 Square 尝试开发过的产品真的很多,虽然不是每一个产品都长久地活了下来。比如电商平台、电子钱包、Payroll 系统,等等等等。另外 Square 早期有一批很 Nerdy 的技术人,包括 Rails 的 Contributor、Java Guice 的发明者等等。并且 Square 从不打怵使用新技术,比如 ElasticSearch、Kafka 等,在版本还没有稳定的时候,Square 已经在产品上使用了。而且因为我们是自己的 Data Center,没有使用 Amazon。所有的配套服务,包括 Deploy 以及 Production 的工具和环境,一套套系统全部都是 Build in House。以上种种,可能和我们创始人 Jack 本身是技术出身有一定的关系。
虽然说这些对于一个公司的发展不一定完全都是好事,但是对于工程师来说,却是一个绝佳的成长环境。一来有机会接触到新技术、或者技术的最前沿。二来因为不停的做新产品,所以早期的时候几乎每个项目都是两三个人从头到尾完全自己搭建。
我在 Square 做过两个大项目,一个就是和前 Google 员工 Ken 两个人一起搭建了 Square 的搜索后端。另一个就是和 Eric 一起做了 Square Store 这个电商平台,主要处理所有 Square 软硬件销售的支付流程。
虽然后来在支付这条路上走了下去,当时一年左右做搜索的经历,还是蛮有意思的。所以想整理一下,分享给大家。当然,一年的经验离资深还差得很远,所以可能说的东西就入不了专家的法眼,因此本文称为 “白话”。
基本概念
搜索说白了就是从已有的数据和信息里找到满足用户条件的一些匹配。
拿最简单的数据库来说,完成用户对数据库的搜索,不外乎这样几个概念:数据存储格式,也就是 Table Schema;新数据的写入;对 Table 的查询;其中又包括 Indexing 来对部分查询的 Pattern 进行性能上的优化;另外可以根据某些 Column 的值对查询结果进行排序。
搜索引擎从基本概念上来说,也是极类似的。例如常见的 Apache Solr 和 Elasticsearch(以下简称 ES),这两者都是建立于 Lucene 之上的,且最核心的功能很类似。(Lucene 其实就是一个搜索引擎 Library,有一堆 Jar 文件,并提供一个 Lucene API 接口。)因为直接用 Lucene API 相对来说更灵活,但是需要更多的 Engineering Effort 才能使用,所以很多地方都是使用 Solr 或者 ES,两者都是基于 Lucene 之上添加了很多可用 Feature 的一个封装。
Indexing
Solr 和 ES 的 Schema 也可以看成定义数据的存储格式和 Structure。这样,当你有新的数据需要存到你的可搜索数据集的时候,就需要把原始数据转化为 Solr 和 ES 文档定义的数据格式。这个过程通常称为 Indexing,或者 ETL。ETL 是 Extract – Transform – Load 的简称。实际应用中,很多时候,搜索的数据源来自于多个系统或 Service,格式和数据结构也就都不相同。Extract 就是从这多种多样的数据源中解析出相关的 Field 和 Value,并可能对数据进行一定的校验。Transfer 就是把 Extract 出来的数据信息转化成搜索引擎的文档存储格式。可能会对一些数据进行组合或聚合,也可能进行一定的转换或计算。最后处理好的文档就可以按照 API 可以接受的格式 Load 到搜索引擎的文档中。
ETL 的过程虽然说起来简单,也就是搭建数据 Pipeline,但是实际中会有很多细节需要考虑和实现。就拿 Extract 来说,怎么从数据源拿数据呢?作为数据源的 Service 可能会实时地 Publish 一些数据更新,这个时候,需要一些类似于 Trigger 或者 Feed Publisher 的机制来保证这样的数据更新可以被搜索引擎的捕捉到。最常见的有三种方式。一是通过加 Trigger,数据变动时直接触发 API Call;一是 Feed 模式;一是使用 Kafka 这样的 Log 机制。而后两种都可以使用 Pull 或者 Push 的方式来触发 Indexing。
这说的是实时 Indexing。而搜索中,因为各种各样的原因(例如早期 ES 的 Re-sharding),往往需要从 0 开始重新 Index 所有的数据。这样,所有的数据源就需要一定的 Persist 机制,把所有数据变动的历史存储下来。Full Reindex 的时候,就可以从这些 Persisted 数据中,重新通过 ETL 产生搜索引擎的文档。
Transform 主要是数据转换,通常比较简单。Load 也就是 API Call,通常是固定的处理方式。但是很多系统需要考虑负载、一致性、和扩展性,因此从 Infra 的角度来说,也需要一定的 Tuning 来保证实时无错的 Load 数据到搜索后端。
Querying
Query 其实最重要的两个概念,我觉得就是 Match 和 Score。Match 就是找到所有满足 Query 条件的数据。Score 就是根据应用的需求,制定一个对结果排序的规则。
Matching 的过程有的时候也称为 Analyze 的过程。通常的做法是 Tokenizing 加 Filtering。Tokenizing 就是把数据划分成一个个不可分割的小单元,然后通过对这些小单元的组合和 Filtering,找到适合需求的所有数据。
Score 常见的也有两种,一种是搜索前静态 Score,也就是和 Query 无关,数据的不同 Field 预先制定一个权重。一种是搜索后 Score,通常和 Query 的具体内容相关。各种不同的 Score 机制可以相互组合使用。而如何调整 Score 函数,让期望的搜索结果出现在比较靠前的地方,则是很多产品的搜索开发中需要致力的地方。很多时候会使用机器学习等方法帮助调整 Score 函数的参数。
Performance and Scalability
除了上面说的两个最基本的功能:Indexing 和 Querying,搜索在实际应用中随着数据的不断增加和 Query 的逐渐复杂化,对于 Performance 和 Scalability 的要求往往也是不断提升。
不同的搜索引擎如 Solr 和 ES 会提供不同的机制用于方便定制不同的 Query。两者对于 Scalability 如分布式搜索的处理也不尽相同。还有一些对灵活性或性能要求更高的地方,往往又会基于底层 Lucene,撇开 Solr 或者 ES,定制自己的搜索系统。下面几个部分将进一步细化对其的讨论。
Solr 和 ElasticSearch 的对比
历史背景
Solr 问世于 2004 年,但是一开始只是某公司的内部项目。2006 年公开发布其源代码,2007 开始应用于一些高流量的网站。2008 年 1.3 版本的问世增加了一定的分布式搜索功能,例如可以做 Sharding。但是有很多功能和特征上的局限性。2010 年,ES 问世。ES 早期在各种搜索功能、社区、品牌、成熟度上都远远不及 Solr。但是因为它是针对分布式搜索而设计的,并且很快吸引了很多用户且不断迭代,因此很快在该领域成为 Solr 的有力的对手。虽然 2012 年 Solr 发布了 SolrCloud 对分布式搜索有了更好的支持,但是一来这时候 ES 已经在市场上站住脚,二来 ES 后起却在设计上致力于解决分布式搜索,因此很多需要分布式搜索的地方 ES 依然成为首选。
主要区别
有很多人对两者做过对比。例如:http://solr-vs-elasticsearch.com,从 API 、Infrastructure、Indexing、Searching、Customizability 等多个方面对两者的优缺点进行了详尽的阐述。总体说来,目前两者的版本对于大部分人需要的性能都有比较好的支持。并没有说哪个比另一个好。只有一些小的特性上有一些区别,例如 ES 的 percolation,Solr 的 Pivot Facets 等。这里说几个曾经比较大的区别(这些区别似乎在后来的版本中逐渐不那么明显)。
一是对于 Cluster 上各结点的管理。之前我在《白话 IT 之 从 ElasticSearch 到 ZooKeeper》一文中提过一些。ES 内部的节点管理系统存在 Split Brain 的问题。而 SolrCloud 使用 ZooKeeper 管理节点,解决了这个问题,但是意味着 SolrCloud 需要 ZooKeeper 的部署。但是因为 ES 其实也可以使用外部 ZooKeeper 来取代其内置的节点管理,因此,这一区别也就不那么明显。
二是 Re-sharding。我用 Solr 和 ES 是三年前,那时候两者都不能动态改变 Shard 的个数。每次改 Shard 个数,都要把所有 Index Data 抹掉重新做 Indexing(从头 ETL 所有数据)。所以我们一开始设计系统的时候,对于 Shard 的配置就特别谨慎。但是 2013 年之后,Solr 就可以支持 Shard Splitting 了。所以从这一点上来说,ES 有一定的局限性。但是 ES 同时又支持 Shard 的 Rebalancing,这一点 Solr 又没有。总之,如果一开始设计系统的时候知道两者的局限性,或者 Re-index 整个搜索系统数据的代价不是太大的情况下,Re-sharding 和 Shard Rebalancing 也不是什么大问题。
三是社区支持,也就是遇到疑难杂症的时候是不是能够很快找到解决方案。三年前的时候,Solr 比 ES 要成熟很多,那时候很多 ES 遇到的问题都很难找到详尽的解释,不过现在似乎两者的用户群都很成熟,并没有很明显的区别。此外因为 Solr 是完全开源的,ES 是允许任意用户 Contribute 但是必须 ES 的人 Review 和 Approve 才能 Merge。所以熟悉 Solr 的开发者可能更为众多。
此外还有一些比较细致的比较,我觉得这篇文章写得很好,推荐阅读:
Solr or Elasticsearch — That is the Question: https://www.datanami.com/2015/01/22/solr-elasticsearch-question/
个人感受
当年在 Square 的时候,其实 Solr 和 ES 都用过。最开始 Sqaure 的搜索后端是用 Solr 写的,和 Ruby 结合。当时 Solr 的一些定制,如 Schema,是一个 Repo,其 ETL 是在另一个 Repo。后来一次 Hackathon,我和几个同事因为好玩儿,用一周的时间用当时刚刚开始火的 ES 重写了一个搜索的原型(当然,只有一些最基本的功能,数据 Pipeline 都没有搭好,比较 Hack 地去写入一些数据。)通过这个简单的原型我们展示了 ES 的一些优势,所以后来就把整个搜索后端移到了 ES 上,做成一个独立的 Java Service。
那么当时我们从 Solr 转到 ES,是因为哪些优势呢?
一就是 Nested Typing。什么意思呢?打个比方,你需要 Index 一些类似于淘宝上店家的信息,同时又需要 Index 一些类似于商品的信息。而这两个数据之间其实是有一种类似于父子关系的联系的。ES 对此有着很好的支持。这样,你在 Indexing 的 ETL 中,可以自然地描述两个数据的关系(商品属于某店家),在查询时,也可以比较方便的写出需要对父类或子类进行 Filter 的 Query。而当时我们的搜索后端正需要这样的一个特性。虽然说用 Solr 也有办法 Work Around,但是那段代码会相对来说比较不易懂,也不好维护。
二是语法。Solr 和 Ruby 结合,很多程序可以写的特别小巧且灵活。而 ES 的纯 JSON 表达则略显臃肿。但是就好像 Ruby 和 Java 的区别,这种 JSON 表达更具有一致性,所有的代码会有很类似的结构,更好懂。另外 Solr 从最开始的设计就比较针对文本搜索。而 ES 对于非文本的数据似乎有着更好的支持。加上其比较一致性的语法规范,对于复杂的 Query 的组合,ES 语句的读写都要更简单明了。
还有一些和公司当时 Infra 相关联的其他因素。
一是前面说的,当时我们的 Solr 和 ETL 在两个 Repo 里。这样以来,每次的 Deploy 就需要两个 Repo Deploy 的相互协调。而且所有的代码改动的兼容性管理就略复杂。而 ES 我们是和我们的 ETL 一起做到了一个独立的 Java Service 里。代码管理和部署都相对简单的多。
二是数据 Pipeline 的建立。当时公司里 Kafka 的 Producer 和 Consumer 对 Java 有了比较好的支持,所以新的基于 ES 的搜索系统可以比较方便的从 Kafka 里拿数据。而 Solr + Ruby 的老系统只能使用比较老的 Trigger 和 Feed 来拿数据。这样一来,很多 Upstream 的数据管道的建立而言,ES 要干净漂亮的多。
三是性能。当时使用了 ES 的分布式支持,而老的 Solr 系统其实是单节点多 Replica 的架构。很自然的,查询性能上 ES 确实要好很多。
搜索和推荐
很多时候,搜索系统和推荐系统是可以共用部分后端 Service 的。因为他们可以使用相同的 Index 数据,也就是只需要建立一套数据 Pipelien 和 ETL系统。在此之上,Query 可以使用不同的方式来实现,从而达到搜索或者推荐的功能。ES 和 Solr 都提供了类似的不同的 API。当时我们做出来的搜索后端,后来就有另一个项目组使用我们的数据,基于其上加了一些复杂的机器学习模型,做出了一个推荐系统。而我们的搜索部分,只使用了一些最基本的 Filter 和 Scoring 机制。
搜索系统的定制
虽然说使用原始的 Lucene 挑战性更大,很多公司一开始便选择搭建自己的搜索后端(如 Airbnb)。也有一些公司使用一段时间 Solr 或者 ES 后转而开发自己的搜索引擎。而定制的原因主要就是灵活性。
不论是 ES 还是 Solr,都是 Lucene 上的一层封装。这层封装按照他们的设计,提供给用户一层新的 API,就好像很多按钮和部件,方便你的很多需求和操作。而这层封装也必然隐藏了一些底部的功能。如果公司的应用和他们的设计的(假想的)Use Case 差别比较大,使用这样的封装就会反而显得很笨拙。因此,特别的应用,很多时候 Solr 还是 ES 提供的那些基本搜索功能和 API,并不好用。相关联的另一个因素就是性能。即使使用 ES 和 Solr,很别扭地写出需要的搜索功能,但是因此整个流程变得不那么直接,而是拐了个弯去调用 Lucene 的基本功能,性能也就必然会大打折扣。
然而,搜索的定制需要更多的人力和时间,以及精通搜索的技术人员。因此直接使用 Solr 或者 ES 的还是很多。即使在这样一些有定制的搜索系统的公司里,有些新产品上线初期也可能选用 Solr 或 ES。
这里写的仅是个人一点浅见。如果对这个话题感兴趣的人比较多,后面可以找更资深的搜索方面的朋友再写写。
好多人问过我,每天上班,还有两个娃,时间是怎么够用的?
老实说,我的时间管理也是乱糟糟,基本没有计划,只有任务队列。怎么保证做事效率呢?
除去必须花在交通和家庭上的时间,上班时候的时间大概是这样的:
首先,所有的面试、Calendar 上的会议(除去可以逃掉的)、Design Review 等是固定的时间,没有办法挪动。每天平均在两三个小时左右,多的时候能有五个小时(很庆幸比我老板少多了)。No-Meeting-Wednesday 则一般只有一个 Meeting 或者没有。
然后,每天晚上会给第二天列一个 TODO List,包括一些 Design,Documentation,或者 Coding。这些是我再接下来的一天中尽量完成的,也是白天上班时优先级最低的一部分。
优先级高于做自己的事情的,是 Code Review。所有相关的代码,组里小伙伴写完 Ready to Review 的时候,尽量第一时间立马 Review, 给 Feedback,不 Block 别人的进度。组里大概六个人左右的项目或代码和我相关,所以平均一天花在 Code Review 上的时间大概是两三个小时。
优先级高于 Code Review 的,是老板、PM 或者我们组的人(外组讨论一般会预先 Schedule)随时的问题和讨论。大概一天平均在一到三个小时。
优先级高于一切的,是所有线上的问题。或者急需 Fix 的 Bug。所幸这种问题出现的比较少。一周也就在两三个小时最多。
这样,基本上我一天的时间,按优先级从上到下,就分成:
在 Calendar 上的会议和面试
临时和同事的讨论和回答各种问题、Slack 讨论和问题
如果没有什么要讨论的,Code Review
如果没有 Code Review,做自己的事,Coding 或 Documentation
自己的任务队列里也有高低优先级,从上往下处理。总有事情可以做
会议和任务间的时间碎片、等代码 Build 的空隙、偶尔的休息:查 Email、查手机和微信消息
一般中午饭直接拿了饭到座位上吃,这样可以做些简单的工作,比如回复 Email 等。等到下班的时候,还会有一些 TODO 没做完的,加上一天中新的任务,所以晚上到家处理完娃和家里的事,开始工作。直到做完所有必须做完的事,或者累了。通常会是十二点到一点间。偶尔会晚些。
干不完的事情、或者想做工作日没时间做的事情,比如看一些别的组的 Design 文档、低优先级的代码重构等,可以周末做。周末其余的时间拿来补觉和陪家人。
再有空的时候,就看看书、写写文章。另外维持公众号一周一两篇文章大概每周需要三个小时。
差不多每天就是这个样子了。并没有什么好的方法。维系一个任务队列和优先级系统,每件事认真去做,每天尽可能完成更多的事情罢了。
所幸,有一群特别靠谱的同事和一个靠谱的老板,每天大家工作效率也高、热情也高,心情愉快、气氛融洽。所以,我这乱糟糟的无计划时间管理体系似乎对我自己来说还挺好用。
话说回来,其实每个人在职场生涯不同阶段,时间安排和事情的优先级都会不一样。别人的系统,换个人可能就不 Work 了。
经常后台有留言让推荐好的技术公众号,上次推荐了一些。今天推荐的大部分是朋友做的号,希望你喜欢。(发现我朋友里面写公众号的还真是不少。。。)
技术人的博客一:嘀嗒嘀嗒的哥哥们——科技互联网类公众号推荐
技术人的博客二:技术圈最值得关注的大牛自媒体推荐
上篇文末推荐:我的编程之路
再加一些新的(也可能有重复的):
精进学堂(InfoQ China 创始人写的公众号,我哥的,上次居然漏了……)
MacTalk(池哥的必须每次都推荐)
小道消息、坏时代(冯老师的必须每次都推荐)
二爷鉴书(二爷的必须每次都推荐)
keso 怎么看(keso 哥的必须每次都推荐)
歪理邪说、神秘的程序员们(霍炬哥西乔姐的必须每次都推荐)
caoz 的梦呓(曹政哥的必须每次都推荐,上次居然漏了……)
可能吧(阿禅的必须每次都推荐)
InfoQ、StuQ、100offer、高可用架构、中生代技术(必须每次都推荐)
糟边往事(这个不需要我荐的其实)
三表龙门阵、三表蛇门阵(虽然不是技术的)
覃超帝国兴亡史(前 Facebook 员工写的)
再生谈(reborn_chat,现 Facebook 员工写的)
董老师在硅谷(前 LinkedIn 员工写的)
硅谷周边(Google 员工写的)
苹果姐姐(Uber 员工写的,旅游玩耍的)
龙大说(Square 员工写的,写 Pokerman 的)
程序人生(陈天写的)
余晟以为(余晟写的)
doriskeke(硅谷支付宝员工写的)
春天的旁边(江南白衣写的)
阑夕(阑夕写的)
待字闺中(陈利人老师写的)
老王卖瓜(王勇睿写的)
王建硕(王建硕写的)
Tinyfool(Tinyfool 写的)
计算广告(北冥乘海生写的)
虚拟机(Roy Li 的)
望月的博客(望月写的)
内推小王子(阿混写的)
在线写作 gitbook(朋友写的)
黑眼豆豆写字的地方(朋友写的)
丁香园、丁香医生、丁香食堂、肉饼铺子、船长哈七乐(丁香园系列)
好多人问过我,每天上班,还有两个娃,时间是怎么够用的?
老实说,我的时间管理也是乱糟糟,基本没有计划,只有任务队列。怎么保证做事效率呢?
除去必须花在交通和家庭上的时间,上班时候的时间大概是这样的:
首先,所有的面试、Calendar 上的会议(除去可以逃掉的)、Design Review 等是固定的时间,没有办法挪动。每天平均在两三个小时左右,多的时候能有五个小时(很庆幸比我老板少多了)。No-Meeting-Wednesday 则一般只有一个 Meeting 或者没有。
然后,每天晚上会给第二天列一个 TODO List,包括一些 Design,Documentation,或者 Coding。这些是我再接下来的一天中尽量完成的,也是白天上班时优先级最低的一部分。
优先级高于做自己的事情的,是 Code Review。所有相关的代码,组里小伙伴写完 Ready to Review 的时候,尽量第一时间立马 Review, 给 Feedback,不 Block 别人的进度。组里大概六个人左右的项目或代码和我相关,所以平均一天花在 Code Review 上的时间大概是两三个小时。
优先级高于 Code Review 的,是老板、PM 或者我们组的人(外组讨论一般会预先 Schedule)随时的问题和讨论。大概一天平均在一到三个小时。
优先级高于一切的,是所有线上的问题。或者急需 Fix 的 Bug。所幸这种问题出现的比较少。一周也就在两三个小时最多。
这样,基本上我一天的时间,按优先级从上到下,就分成:
在 Calendar 上的会议和面试
临时和同事的讨论和回答各种问题、Slack 讨论和问题
如果没有什么要讨论的,Code Review
如果没有 Code Review,做自己的事,Coding 或 Documentation
自己的任务队列里也有高低优先级,从上往下处理。总有事情可以做
会议和任务间的时间碎片、等代码 Build 的空隙、偶尔的休息:查 Email、查手机和微信消息
一般中午饭直接拿了饭到座位上吃,这样可以做些简单的工作,比如回复 Email 等。等到下班的时候,还会有一些 TODO 没做完的,加上一天中新的任务,所以晚上到家处理完娃和家里的事,开始工作。直到做完所有必须做完的事,或者累了。通常会是十二点到一点间。偶尔会晚些。
干不完的事情、或者想做工作日没时间做的事情,比如看一些别的组的 Design 文档、低优先级的代码重构等,可以周末做。周末其余的时间拿来补觉和陪家人。
再有空的时候,就看看书、写写文章。另外维持公众号一周一两篇文章大概每周需要三个小时。
差不多每天就是这个样子了。并没有什么好的方法。维系一个任务队列和优先级系统,每件事认真去做,每天尽可能完成更多的事情罢了。
所幸,有一群特别靠谱的同事和一个靠谱的老板,每天大家工作效率也高、热情也高,心情愉快、气氛融洽。所以,我这乱糟糟的无计划时间管理体系似乎对我自己来说还挺好用。
话说回来,其实每个人在职场生涯不同阶段,时间安排和事情的优先级都会不一样。别人的系统,换个人可能就不 Work 了。
经常后台有留言让推荐好的技术公众号,上次推荐了一些。今天推荐的大部分是朋友做的号,希望你喜欢。(发现我朋友里面写公众号的还真是不少。。。)
技术人的博客一:嘀嗒嘀嗒的哥哥们——科技互联网类公众号推荐
技术人的博客二:技术圈最值得关注的大牛自媒体推荐
上篇文末推荐:我的编程之路
再加一些新的(也可能有重复的):
精进学堂(InfoQ China 创始人写的公众号,我哥的,上次居然漏了……)
MacTalk(池哥的必须每次都推荐)
小道消息、坏时代(冯老师的必须每次都推荐)
二爷鉴书(二爷的必须每次都推荐)
keso 怎么看(keso 哥的必须每次都推荐)
歪理邪说、神秘的程序员们(霍炬哥西乔姐的必须每次都推荐)
caoz 的梦呓(曹政哥的必须每次都推荐,上次居然漏了……)
可能吧(阿禅的必须每次都推荐)
InfoQ、StuQ、100offer、高可用架构、中生代技术(必须每次都推荐)
糟边往事(这个不需要我荐的其实)
三表龙门阵、三表蛇门阵(虽然不是技术的)
覃超帝国兴亡史(前 Facebook 员工写的)
再生谈(reborn_chat,现 Facebook 员工写的)
董老师在硅谷(前 LinkedIn 员工写的)
硅谷周边(Google 员工写的)
苹果姐姐(Uber 员工写的,旅游玩耍的)
龙大说(Square 员工写的,写 Pokerman 的)
程序人生(陈天写的)
余晟以为(余晟写的)
doriskeke(硅谷支付宝员工写的)
春天的旁边(江南白衣写的)
阑夕(阑夕写的)
待字闺中(陈利人老师写的)
老王卖瓜(王勇睿写的)
王建硕(王建硕写的)
Tinyfool(Tinyfool 写的)
计算广告(北冥乘海生写的)
虚拟机(Roy Li 的)
望月的博客(望月写的)
内推小王子(阿混写的)
在线写作 gitbook(朋友写的)
黑眼豆豆写字的地方(朋友写的)
丁香园、丁香医生、丁香食堂、肉饼铺子、船长哈七乐(丁香园系列)