Some useful websites for programmers.
When learning CS, there are some useful sites you must know to get always informed in order to do your technologies even better and learn new things. Here is a non exhaustive list of some sites you should visit. This list will get updated as soon as I can get another link, but you can also contribute by adding those you know
Note : Chinese Version
for a job ever again, talk directly to decision makers and hiring managers.
来自美团的一篇文章,我做了一些删减,focus很重要,找到自己的定位,多参与,形成方法论,逐步的向上靠近。
“Owner意识”主要体现在两个层面:一是认真负责的态度,二是积极主动的精神。
认真负责是工作的底线。首先,要对我们交付的结果负责。项目中每一个设计文档、每一行代码都需要认真完成,要对它的质量负责。如果设计文档逻辑混乱,代码没有注释,测试时发现一堆Bug,影响的不仅仅是RD的工程交付质量,还会对协同工作的RD、QA、PM等产生不好的影响。久而久之,团队的整体交付质量、工作效率也会逐步下降,甚至会导致团队成员之间产生不信任感。其次,我们要对开发的系统负责。系统的架构是否需要改进,接口文档是否完善,日志是否完整,数据库是否需要扩容,缓存空间够不够等等,这些都是需要落地的事情。作为系统Owner,请一定要认真履行。
积极主动是“Owner意识”更高一级的要求。RD每天要面对大量的工作,而且很多并不在计划内,这就需要具备一种积极主动的精神。例如我们每天可能会面对大量的技术咨询,如果客户提出的问题很长时间得不到回应的话,就会带来不好的客户体验。很多同学说忙于自己的工作没有时间处理,有同学觉得这件事不是很重要,也有很多同学是看到了,但是不知道怎么回答,更有甚者,看到了干脆装没看见。这些都是缺乏Owner意识的体现。正确的做法是积极主动地推动问题的解决,如果时间无法排开或者不知道如何解决,可以直接将问题反馈给能解决的同学。
积极主动还可以表现在更多方面。比如很多同学会自发地梳理负责服务的现状,根据接口在性能方面暴露的问题提出改进意见并持续推动解决;也有同学在跨团队沟通中主动承担起主R的角色,积极发现问题、暴露问题,推动合作团队的进度,保证项目顺利推进。这些同学无一不是团队的中坚力量。所以,我们在做好自己份内工作的同时,也应该积极主动地投入到“份外”的工作中去。一分耕耘一分收获,不要给自己设限,努力成为一个更加优秀的人。
相信大家都有时间观念,但是真正能执行到位的可能并没有那么多。互联网是一个快速发展的行业,RD的研发效率是一个公司硬实力的重要体现。项目的按期交付是一项很重要的执行能力,在很大程度上决定着领导和同事对自己靠谱程度的评价。大家可能会问:难度几乎相同的项目,为什么有的同学经常Delay,而有的同学每次都能按时上线?一个很重要的原因,就是这些按时交付的同学往往具备如下两个特质:做事有计划,工作分主次。
工作安排要有计划性。通常,RD在设计评审之后就能预估出精确的开发时间,进而再合理地安排开发、联调、测试计划。如果是项目负责人,那么就会涉及协调FE、QA、PM等多个工种的同学共同完成工作。凡事预则立,不预则废。在计划制定过程中,要尽可能把每一项拆细一点(至少到pd粒度)。事实证明,粒度越细,计划就越精准,实际开发时间与计划之间的误差就会越小。
此外,务必要规定明确的可检查的产出,并在计划中设置一些关键的时间点进行核对。无数血淋淋的事实告诉我们,很多项目延期都是因为在一些关键交付点上双方存在分歧造成的。例如后台RD的接口文档计划在周五提供,FE认为是周五上午,而RD认为是周五下班前提交,无形中会给排期带来了1pd的误差。所以,我们要做到计划粒度足够细,关键时间点要可检查。
工作安排要分清楚主次。我们每天要面对很多的事情,要学会分辨这些工作的主次。可以尝试使用“艾森豪威尔法则”(四象限法则),把工作按照重要、紧急程度分成四象限。优先做重要紧急的事情;重要不紧急的事情可以暂缓做,但是要持续推进;紧急不重要的事情可以酌情委托给最合适的人做;不重要不紧急的事情可以考虑不做。很多项目无法按期交付的原因,都是因为执行人分不清主次。比如在开发中需要使用到ES,一些不熟悉ES的同学可能想系统性地学习一下这方面的知识,就会一头扎进ES的汪洋中。最后才发现,原本一天就能完成的工作被严重拖后。实际工作中,我们应当避免这种“本末倒置”的工作方式。在本例中,“系统性地学习ES”是一件重要但不紧急的事情。要学会分辨出这些干扰的工作项,保证重要紧急的事情能够按时交付。
“以终为始”(Begin With The End In Mind),是史蒂芬·柯维在《高效能人士的七个习惯》中提到的一个习惯。它是以所有事物都经过两次创造的原则(第一次为心智上的创造,第二次为实际的创造)为基础的。直观的表达就是:先想清楚目标,然后努力实现。
在工作中,很多RD往往只是埋头走路,很少抬头看天。每次季度总结的时候,罗列了很多项目,付出很多努力。但是具体这些项目取得了哪些收益,对业务有哪些提升,却很难说出来。这就说明在工作中并没有遵守“以终为始”这一原则。此外,很多同学在做需求的过程中,对于目标与收益关注不够,系统上线之后,也没有持续地跟进使用效果。这一点在技术优化项目中体现的尤为明显。
例如在一个接口性能优化的项目中,经过RD的努力优化,系统TP99缩短了60%,支持QPS提升了2倍。但是系统到底需要优化到什么程度呢?是不是缩短60%,提升2倍就能满足需求呢?在优化之前,很多同学常常忘记设置一个预设的目标(TP99小于多少,支持QPS大于多少)。我们必须清楚,优化一定是有原因的,比如预期某节假日流量会暴增或者某接口超时比例过高,如果不进行优化,系统可能会存在宕机风险。解决特定的问题才是技术优化的最终目的,所以要根据问题设定目标,再进行优化。
“以终为始”,这一原则还可以作用于我们的学习中。很多同学看过很多技术文章,但是总是感觉自己依然一无所知。很重要的一个原因,就是没有带着目标去学习。在这个信息爆炸的时代,如果只是碎片化地接收各个公众号推送的文章,效果几乎可以忽略不计。在学习之前,我们一定要问自己,这次学习的目标是什么?是想把Redis的持久化原理搞清楚,还是把Redis的主从同步机制弄明白,亦或是想学习整个Redis Cluster的架构体系。如果我们能够带着问题与目标,再进行相关的资料搜集与学习,就会事半功倍。这种学习模式的效果会比碎片化阅读好很多。
你是否遇到过这样的场景:参加了一个设计(或需求)评审,大家兴致勃勃地提了很多合理的意见,等到再次评审的时候,却发现第一次提的很多问题都没有得到改进,很多讨论过的问题需要从头再开始讨论。这种情况就是一种典型的工作不闭环。
之前看过一句话:一个人是否靠谱,就看他能否做到凡事有交代,件件有着落,事事有回音。这就是闭环思维的重要性。它强调的是一种即时反馈闭环,如果别人给我们分配了一个任务,不管完成的结果如何,一定要在规定的时间内给出明确的反馈。
例如在跨部门的沟通会议中,虽然各方达成了一致,会议发起者已经将最终的记录周知大家。但是,到这一步其实并没有完成真正的闭环,在落地执行过程中很可能还存在一些潜在的问题。例如,会议纪要是否经各方仔细核对并确认过?会议中明确的To Do进展是什么?完成结果有没有Check的机制?如果这些没有做到的话,就会陷入“沟通-发现问题-再沟通-再发现问题”的恶性循环中。
真正的闭环,要求我们对工作中的事情都能够养成良好的思维习惯,沟通要有结论,通知要有反馈,To Do要有验收。
“闭环思维”还要求能够定期主动进行阶段性的反馈。刚参加工作时,我接了一个工期为两个月的项目。整个项目需要独自完成,自己每天按照计划,有条不紊地进行开发。大概过了两周之后,Leader询问项目进度,虽然我已经跟他说没问题。然而,Leader告诉我,因为我每天对着电脑也不说话,让他心里很没底。
这时,我才意识到一个很重要的问题,我跟Leader之间存在信息不对称。从那以后,我就时不时得跟他汇报一下进度,哪怕就只有简短的一句话,也可以明显感觉,他对我的信心增加了很多。特别是我做Leader之后,对这种闭环反馈的理解,就更加深刻了。从Leader的角度看,其实只是想知道项目是否在正常推进,是否遇到问题需要他协助解决。
“君子之心,常怀敬畏”,保持敬畏之心能够让我们少犯错误。在工作中存在各种各样的规范,例如代码规范、设计规范、上线规范等等。我们必须明白,这些规范的制定一定是基于某些客观原因的,它们都是历史上无数Case积累而来的经验。团队里的每一个成员都应该学习并严格遵守,这一点对于新人尤其重要。
当我们进入到一个新的团队,请先暂时忘掉之前的习惯,要尽快学习团队既有的规范,并且让自己与团队保持一致。以编码风格为例,很多同学往往习惯于自己之前的代码写作风格,在做新公司第一个项目时,也按照自己的习惯进行变量、包的命名等等。结果在代码Review过程中,被提了很多修改意见,不得不返工重写,得不偿失。如果能够保持敬畏之心,提前了解编码规范,这种问题完全可以避免。
类似的问题,还包括对上线流程的不了解,对回滚操作不熟悉,对SRE线上变更过程不了解等等。除了这些显而易见的规范,还有一些约定俗成的规则。个人建议是:如果有事情拿不准,不妨多问问其他同事,不要凭自己的感觉做事情。
保持敬畏之心并不意味着要“因循守旧”。在我们充分了解这些规范和约定之后,如果觉得存在不妥之处,可以跟全组同学讨论,是否采纳新的建议,然后及时去更新迭代。其实,让规范与约定与时俱进,也是另一种形式的敬畏。
“事不过二”,是我们团队一贯坚持的原则,它可以解读为两层含义。
一层含义是“所有的评审与问题讨论,不要超过两次”。之所以有这样的要求,是因为我们发现,很多RD都把时间花费在一些无休止的评审与问题讨论中,真正投入到实际开发中的时间反而很少。在实际工作场景中,我们经常会遇到一些不是很成熟的需求评审。这些需求文档,要么是背景与目标含糊不清,要么是产品方案描述不够细化,或者存在歧义。RD与PM被迫反复进行讨论,我曾经遇到过一个需求评审,进行了三次还被打回。
同样的问题,在设计评审中也屡见不鲜。方案固然需要经过反复的讨论,但是如果迟迟不能达成一致,就会耗费很多RD与PM的宝贵时间,这就与提升研发效率的理念背道而驰。因此我们团队规定:所有的评审最多两次。通过这种方式,倒逼利益相关方尽可能地做好需求与方案设计。评审会议组织前,尝试与所有相关人员达成一致,询问对方的意见,并进行有针对性的讨论,这样能够大大提升评审会议的效率和质量。如果在第一次评审中不通过,那么就只有一次机会进行复审。一旦两次不通过,就需要进行Casestudy。
“事不过二”原则的另一层含义,是“同样的错误不能犯第二次”。每次故障之后,Casestudy都必须进行深刻的总结复盘,对故障原因进行5Why分析,给出明确可执行的To Do List。每次季度总结会,大家自我反省问题所在,在下个季度必须有所改善,不能再犯类似的错误。孔子云:“不迁怒,不贰过”,在错误中反思与成长,才能让我们成为更优秀的人。
“设计优先”这条原则,相对来说更加具体一些。之所以单列一项,是因为架构设计太重要了。Uncle Bob曾说过:“软件架构的目标,是为了让构建与维护系统的所需人力资源最小化。”
架构设计,并不仅仅关系到系统的质量,还关乎团队的效能问题。很多团队也有明文规定,开发周期在3pd以上的项目必须有设计文档,开发周期在5pd以上的项目必须有设计评审。在具体的执行过程中,由于各种原因,设计往往并不能达到预期的效果。究其原因,有的是因为项目周期紧,来不及设计的足够详细;有的是因为RD主观上认为项目比较简单,设计草草了事。无数事实证明,忽略了前期设计,往往会导致后续开发周期被大幅拉长,给项目带来了很大的Delay风险。而且最可怕的是,不当的设计会给项目带来巨大的后期维护成本,我们不得不腾出时间,专门进行项目的优化与重构。因此,无论什么时候都要记住“设计优先”这一原则。磨刀不误砍柴工,前期良好的设计,会给项目开发以及后期维护带来极大的收益。
“设计优先”这一原则,要求写别人看得懂的设计。我们了解一个系统最直接的途径就是结合设计文档与代码。在实际工作中,很多同学的设计文档让大家看得一头雾水,通篇下来,看不出系统整体的设计思路。其实,设计的过程是一种智力上的创造,我们更希望它能成为个人与集体智慧的结晶。如何才能让我们的设计变得通俗易懂?我个人认为,设计应该尽量使用比较合理的逻辑,进而把设计中的一些点组织起来。比如可以使用从抽象到具体,由总到分的结构来组织材料。在设计过程中,要以需求为出发点,通过合理的抽象把问题简化,讲清楚各个模块之间的关系,再详细分述模块的实现细节。做完设计之后,可以发给比较资深的RD或者PM审阅一下,根据他们的反馈再进行完善。好的设计,一定是逻辑清晰易懂、细节落地可执行的。
“P/PC平衡”原则,即产出与产能平衡原则。伊索寓言中讲述了一个《生金蛋的鹅》的故事。产出好比“金蛋”,产能好比“会下金蛋的鹅”。“重蛋轻鹅”的人,最终可能连产蛋的资产都保不住;“重鹅轻蛋”的人,最终可能会被饿死。产出与产能必须平衡,才能达到真正的高效能。为了让大家更清晰的了解这一原则,本文举两个例子。
从系统的角度看,每一个系统都是通过持续不断地叠加功能,来实现其产出,而系统的产能是通过系统架构的可扩展性、稳定性等一系列特性来表征。为了达到产出与产能的平衡,需要在不断支持业务需求的过程中,持续进行技术架构层面的优化。如果一味地做业务需求,经过一定的时间,系统会越来越慢,最终影响业务的稳定性;反之,一个没有任何业务产出的系统,最终会消亡。
再从RD的角度来看这个问题,RD通过做需求来给公司创造价值,实现自己的产出。而RD的产能是指技术能力、软素质、身体健康状况,有这些资本后,我们才能进行持续的产出。在日常工作中,我发现很多RD往往只重视产出。他们也在很努力地做项目,但是每一个项目所使用的方法,还是沿用自己先前一贯的思路。最终,不仅项目做得一般,还会抱怨自己得不到任何成长。这就是P/PC不平衡的体现。如果能在做项目的过程中,通过学习和总结持续提升自己的技术能力和软素质,并将其应用于项目实施交付中,相信一定会取得双赢的结果。
“P/PC平衡”原则还适用于很多其他的领域,例如团队、家庭等,我本人也非常推崇这一原则。希望大家也能将其作为自身的一项基本原则,努力寻找到产出与产能的平衡点。
“善于提问”,首先要勤于提问。求知欲源于好奇心,是人类的一种本能。在工作中要养成勤于提问的好习惯,不懂就问,不要因为自己一时懒惰或者碍于情面,就放弃提问的机会。当遇到不同的观点时,也要礼貌地问出来。波克定理告诉我们,只有在争辩中,才可能诞生最好的主意和最好的决定。
在设计评审、代码评审这类体现集体智慧的活动中,遇到有问题的地方一定要提出来。我经常看到,很多同学评审全程一言不发,这就是浪费大家的时间。设计评审的目的,是让大家针对方案提出改进意见并达成一致,如果全程“打酱油”,那就失去了评审的意义。我们鼓励大家多提问,把自己内心的疑惑表达出来,然后通过交流的方式得到答案。
“善于提问”,还要懂得如何提问。为什么同样是参加设计评审,有的同学就能提出很好的问题,而有的同学却提不出任何问题?除了知识储备、专业技能、经验等方面的差异外,还有一点很重要:这就是批判性思维。
批判性思维主张通过批判性思考达到理性思维,即对事物本质的认知和掌握。关于如何进行批判性思维,大家可以参考一些经典的图书如《批判性思维》、《学会提问》等。在工作中面临一项决策时,会有各种各样的意见摆在你面前,所以我们必须要学会使用批判性思维来进行分析,每个人的论据是否可靠,论证是否合理,是否有隐含的立场。同样,在阅读一篇技术博客的时候,也要使用批判性的思维,多问几个为什么,作者得出的结论是否合理?论据是否充分?只有这样,才能不断地获取真正的知识。
“满招损,谦受益”,“空杯心态”是最后一项原则。我觉得这也是一个人能够持续成长的前提。做技术的人,骨子里通常有股傲气,并且会随着资历、成绩的提升而不断增加。初入职场的小白,可能会非常谦虚,但是工作几年之后,专业技能逐步提升,可能还取得了一些小成就,人就会越来越自信。这时候,如果不能始终保持“空杯心态”,这种自信就会逐步演变为自满。自满的人,往往表现为工作中把别人的建议当成是批评,不接受任何反对意见,学习上也缺乏求知的动力,总是拿自己的长处去跟别人的短处做比较。其实每个人多少都会有一些自满,可怕的是不知道甚至不愿承认自满。
保持“空杯心态”这一原则要求我们时刻进行自我检视与反省。在工作中,多去跟不同级别的同学聊一聊,或者做一个360度评估,这有助于我们更加客观地评价自己。在横向对比中,多向那些优秀的同学看齐,学习他人的优点。很多同学在设计评审或者代码Review过程中,针对别人提出的问题与建议,往往都采用一种对立的态度。错误地认为别人是在挑刺,是在针对自己。诚然,在某些方面,我们可能确实比其他人想得深入,但是这不代表在所有方面都能考虑周全。对于别人的建议,建议使用“善于提问”原则里提到的批判性思维仔细分析一下,虚心地吸取那些好的建议。
工作学习就像“练级打怪”,技能储备的越多,就越容易走到最后。保持空杯心态,可以让我们发现很多以前注意不到的新能力,我们要做的就是努力学习它,将它们转化为自己能力库的一部分。
以上,是我总结的工作与学习的十条基本原则。其中有的侧重于个人做事情的方法,如“Owner意识”、“时间观念”、“以终为始”、”闭环思维”;有的侧重于团队工作标准规范,如“保持敬畏”、“事不过二”、“设计优先”;有的侧重于团队或个人效能提升,如“P/PC平衡”、“善于提问”、“空杯心态”。这些原则是我多年在工作与学习中,不断总结得来的经验。希望在大家面临选择时,这些原则能够起到一定的帮助和指导作用。
以原则为中心地工作与生活,让自己与团队变得更加强大。
]]>原文:https://www.startupgrind.com/blog/which-is-better-data-driven-or-data-informed/
翻译:ChenTao 有删改
informed 这个词很难找到对应的中文,在决策的语境下,叫”参考”可能比较弱,这里选择了”知情”,仅供参考。
万事万物没有绝对好坏,理性思考,找到适合自己现有产品的「数据原则」改进产品才是王道。
数据驱动这个词已经开始成为一个流行语,堆积在其他技术术语的顶部。所以,让我先把所有人都放在同一页面上。
数据驱动意味着数据是团队和公司决策过程的中心。决策者主要以(有时仅仅是)数据作为操作标准,并且可以在没有人参与的情况下做出一些决定。
以下是您通常从数据驱动的公司收到的一些信息:
真正的数据驱动型组织将贯穿整个团队和功能的这一过程。这意味着每个团队(产品,市场营销,客户成功,运营等)都将数据集中用于所有决策。
作为人类,我们有许多认知偏见。事实上,我的导师Misha Chellam创建了flashcards,以帮助人们记住他们。
数据有助于让团队成员和利益相关者在同一页面上做出更少的判断。
你们中有多少人参加了三小时的会议,人们反复讨论,没有妥协的迹象?
有时候,我们只会为HiPPO(highest paid person’s opinion)进行讨论和争论,以作出最终决定。(是的,我知道你的感受。)
一个麻省理工学院的研究已经证明,是数据驱动的有它的好处。Erik Brynjolfsson教授和他的同事研究了179家大型上市公司,并得出结论认为,这些公司比其竞争对手的生产率和盈利能力高出5%。
但是,数据驱动也有其缺点。
你必须警惕异常畸变。异常值(Outliers)是与平均值完全不同的数据点。在游戏中,正面的异常值被认为是“ 鲸鱼(whales)”。这些客户大量购买或经常使用它们,为公司带来了大量收入。在我以前的公司,我们甚至创造了“捕鲸(whale hunting)”这个词。
在其他行业,这些可能是那些使用你的产品解决与大多数客户不同的问题的客户。他们的行为如此不同以至于他们应该被排除在用于制定关于普通客户的决策数据之外。只有几个数据点和一些异常值的数据集可能会导致您的公司不应该去的地方。
对于刚刚启动数据科学部门的创业公司和大型组织来说,由于缺乏能力和资源,可能很难完全进行数据驱动。您当前的员工可能没有足够的知识来构建基础架构,或者您甚至可能没有任何具有数据专业知识的人员。
在我以前的公司,我们有10位数据科学家。在Kulina,我们只有0.5人拥有专业知识(我自己和我们的技术总和)。
大多数时候,what people say isn’t what they do。所以,如果我们通过隐式询问来收集数据,我们就会冒险做出有关错误信息的决策。例如,在Uber和#deleteuber运动的丑闻时期,我的大多数朋友说他们再也不会使用优步。当Lyft(Uber在美国的主要竞争对手)实施附加费时,他们都回去(继续使用Uber)了!
另一个很好的例子是,当我们试图找出我们想花更多时间和金钱吸引用户的社交媒体平台时。我们发出了一个调查问卷,结果出乎意料。
我们看到了名单上的Facebook,这是预期的。然而,让我们感到困惑的是,Google+名列第二(no hard feelings, Google)。
一些团队成员问他们是否应该花更多时间来建立Google+的存在。“也许我们不太了解我们的用户,”一位团队成员提到。由于数据驱动,我可能会着重指出这一点。但像往常一样固执,我与另一位产品营销经理讨论了什么可能会出错。
我们认为,也许我们的用户可能不了解Google和Google+之间的区别。事实上,当我们更深入地看待问题的提问方式时,我们发现了一些线索来支持这个问题。我们在问卷中使用了Google+这个词,而不是使用Google+图标。如果你没有密切关注,你可能会认为我们问你是否使用过Google!
掌握数据是指将数据作为决策制定的唯一因素,而不是将其作为整个基础。这种决策可以让顾客体验,直觉,品牌一致性和HiPPO等其他因素起到带头作用。
好处是数据现在受到挑战(challenged)。我们不是单纯依据数据做出决定,而是用它来创建一个假设。这是因为不管数据有多好,都有其局限性。这只是现实的快照,并没有描绘出我们客户旅程和行为的全貌。
我觉得有必要在这里贴下原文,很精彩。(译者按)
(We don’t purely base our decisions on data but use it to create a hypothesis. This is because no matter how good data is, it has its limitations. It’s just a snapshot of reality that doesn’t paint the full picture of our customer journey and behavior.)
通过了解数据,我们不得不使用其他因素来帮助做出更好的决策,包括我们自己的判断。
(By being data-informed, we are forced to use other factors to help make better decisions, including our own judgment.)
例如,在我以前的游戏公司,周末我们的收入总是很高,因为这是用户玩游戏的时候。但是在某个特定的星期一,有一位新产品负责人就那个周末的低收入接近了我。他非常担心。
我怀疑我们的收入下降了,因为我们在上周末进行了销售。过去五次我们销售的产品也出现同样的效果。如果我们之前看过同样的周期,我们的平均水平实际上会更好。
事实上,Facebook的新闻馈送实际上是在没有数据驱动的情况下实施的。Facebook产品设计师Adam Mosseri及其团队当时决定创建没有数据(without data)的新闻馈送。这种变化引起了很多负面反应,许多用户都很生气。有些人甚至创建了一个名为“ 我自动讨厌新的Facebook主页”的Facebook组织。
但是根据Mosseri的说法,“在一天结束时,我们必须要有一个勇于在没有数据的情况下做出大胆的决定。”
但这并不意味着以数据为依据的决策没有缺点。
在做出决定之前,掌握数据需要大量的时间,讨论和分析。结论也不容易形成。但请记住,在一天结束的时候,“世界上所有的数据都不能解决一个根本不好的产品,”前SoundCloud高级产品经理Andy Carvell说。
为了创新并为我们的客户构建合适的产品,我们不能只坐在房间里看着数据和图表。
通过与客户交谈收集定性反馈信息,通过可用性测试观察他们的挣扎情况,以及确定客户聘用您的工作是构建产品的关键。
对于小公司,你应该始终致力于更多的数据驱动。您可能不会使用您收集的数据(甚至根本收集数据)。你拥有的数据越多,你就会产生更好的假设。
小团队产品现状问题较多且需要快速改进,用data-driven可以快速确定改进目标,提高改进效率(译者按)
(For larger companies, you should be able to make bold decisions that not only move your key metrics but also improve customer experience. We should use data to help us make better decisions, but not rely on it 100 percent.)
对于大公司,您应该能够做出大胆的决定,不仅可以移动关键指标,还可以改善客户体验。我们应该使用数据来帮助我们做出更好的决策,但不能100%地依靠它。
大团队的产品一般都较为稳定,每一次改进决策需要更为慎重,所以需要更多的维度来衡量改进产品(译者按)
(For smaller companies, you should always aim to be more data-driven. You probably don’t utilize the data you collect (or even collect them at all). The more data you have, the better hypotheses you will generate.)
]]>LGTM: Looks Good To Me. 朕知道了 代码已经过 review,可以合并
SGTM: Sounds Good To Me. 和上面那句意思差不多,也是已经通过了 review 的意思
WIP: Work In Progress. 传说中提 PR 的最佳实践是,如果你有个改动很大的 PR,可以在写了一部分的情况下先提交,但是在标题里写上 WIP,以告诉项目维护者这个功能还未完成,方便维护者提前 review 部分提交的代码。
PTAL: Please Take A Look. 你来瞅瞅?用来提示别人来看一下
TBR: To Be Reviewed. 提示维护者进行 review
TL;DR: Too Long; Didn’t Read. 太长懒得看。也有很多文档在做简略描述之前会写这么一句
TBD: To Be Done(or Defined/Discussed/Decided/Determined).
根据语境不同意义有所区别,但一般都是还没搞定的意思
]]>reference
LGTM? 那些迷之缩写
谁值得我学习?(谁是对标?)
谁在抢我的饭碗?(谁是对手?)
谁可以在一起合作?(谁是对友?不只是队友)
内容来源:2018年3月25日,北京大学营销升级总裁研修班课上,灰度认知社创始人曹升先生主讲《认知战法》。笔记侠作为课程笔记合作方,经主办方和讲者授权发布。
今天分享的主题是“认知战法”,非常高兴能有这个机会跟大家做一个交流。
一、人是怎么做决策的?
为什么卡尼曼这样的心理学家会获得诺贝尔经济学奖?
原因是心理学家告诉我们,人的决策是非理性的,做决策时人的第一反应是人性,第二反应是认知。
1. 人性层面
人是凭着人性做决策的,能触动人性、激发人性、顺应人性的相关产品,消费者容易决策,容易火爆。比如靠对美的追求、品牌感强而火爆的化妆品;符合人性的三俗广告;陌生人社交软件等。
有一个非常奇怪的心理现象,越是重大的决策,往往越是靠直觉。
2. 认知层面
为什么有些公司获客成本高?一言以避之,那就是“功能营销”。
功能营销的弊病就是,一上来就硬介绍产品功能,把客户带到功能认知上去,决策成交率会越来越低。
为什么呢?因为,做认知决策时,人会考虑利弊,会考虑多种可能性与替代品,在多种事物中进行关联、比较、选择,最终决策。所以决策周期越来越长,决策力度越来越低。
要想压缩认知决策周期,就要在产品设计和营销环节,更多的要让用户产生一个“认知”,但是决策的时候,要把用户往“人性”方向去推,决策会更快,更能实现规模化销售。
换成大白话说,理性诉求,感性表达,才是高效率的营销。比如,你卖的是房子,而客户买的是家,以及家的“认知”与“人性”的幸福感。
3. 简而言之
人性决策 = 情绪触发 + 情感触发 + 功利触发
认知决策 = 认知关联 + 认知比较 + 最优化选择
与认知决策周期相比,更要命的是,功能营销没有办法抓住客户的注意力。缺少用户触点,就无法产生自然流量。
自然流量是指你没有做广告,就有客户自己找上门来而形成的流量。是否有自然流量,是区分营销效果的重要标志。
二、外卖大战的商业认知
外卖行业用互联网工具来提升商业价值,但是商业逻辑的底层还是传统产业。它似乎没有那么多技术含量,然而在我们不认为外卖是个大产业的时候,饿了么做到了九十多亿美元的企业估值。
看过一个市场数据,美团外卖大概占市场份额60%多一点,饿了么占30%多一点,两强之后再剩下的那些品牌总和也不过就几个点了。
为什么整个中国只有美团和饿了么两家占这么大的份额,其他人就做不起来呢?
1. 饿了么是怎么起来的?
饿了么团队创业时都还是大学生。他们为什么会进入外卖行业?
几个年轻的大学生要生存,就想做一件事能赚钱。大学生没有资源,什么都干不了。到了中午饿了,好像吃饭是痛点,是刚需,思路就跳到这里来了:我们在这里创业行不行啊?一下子脑洞大开。
饿了么的商标是大有讲究,它和红牛、脑白金都有一个很狡猾的地方——场景驱动。
最早用这一套路的是著名饮料品牌红牛,“困了累了喝红牛”。红牛=极限,它主打极限运动精神,但是广告词打的却是场景驱动,“困了累了”是一种用户场景。
脑白金也一样狡猾,“送礼就送脑白金”,你都不知道产品有什么功能?送的是什么东西?它打的也是用户场景。
“小饿小困就喝香飘飘”,打的也是场景。
饿了么,硬生生地把一个场景,变成了它的商标,把两个不相关的事物关联起来了。于是,经过一段时间的沉淀,在用户心智中,饿了么=外卖。
2. 谁是饿了么第一个对标?
SHERPA’S,中文名“食派士”。这个名字很不容易记住。在中国做生意,用户对中文品牌无感那就真的输在起跑线上了。
① 食派士起家的原因
食派士是一个叫马克的美国人做的,他是中欧国际工商学院的MBA学生。他在中国吃饭比较痛苦,有三个原因:
第一,不熟悉中餐菜名典故。餐馆服务生往往不会说英语。他是老外懂一点点中文,但是一看菜单就心惊肉跳,什么叫“蚂蚁上树”,什么叫“狮子头”,什么叫“鱼香肉丝”,没有蚂蚁,也没有鱼啊,这不是骗我吗?
第二,他作为一个外国人,在餐馆吃饭会有人围观。用户体验非常不好,他不喜欢这种感觉。
第三,西餐厅数量稀少。他作为一个外国人更喜欢的是西式餐厅,或者就是酒吧这样的地方做的一些西餐。
但是问题来了,如果是中餐,方圆百米内很可能有好几家店,但是如果想买到西餐,可能1公里外都没有这样的店,到3公里外才会有2家店。
他的创业基于什么?也是场景(外国人就餐体验差,这是痛点)。
他对外国人就餐的痛点有了一个差异化认知,因为有这三个痛点,所以做这个生意的商业逻辑是通的。
他做的生意也是高度差异化的,主要在上海、苏州、北京3个城市展开业务。1998年开始做,1999年正式运营,应该是在中国有品牌的外卖鼻祖。
② 食派士的比较优势是什么?
它是外国人认可的、高端的中国外卖第一品牌,尽管是小众,也是一个用户心智接受的品类第一。
差异化就意味着避免了跟行业老大正面交锋,有效地避开了价格战。品类受消费者认可,可以有自然流量,可以提价,还避开了红海一样的恶性竞争。
食派士在三个城市开了3个平台,服务了约600家的企业,客单价在300元左右。
它是中国客单价最高的外卖平台之一了,有自身的比较优势,但缺点也同样明显,就是本地化运营、互联网化运营相当地不充分,没能抓住外卖大风口,顺势做大做强。2017年食派士被百盛中国收购。
③ 饿了么向食派士学什么?
食派士最土的地方在于,竟然到处发小册子。在广场上看见一个老外就送他一份宣传单,上面有中文和英文的说明。食派士常年坚持发小册子,做得不错,因为客单价高,即使不做互联网运营也能活得很滋润。
饿了么学习它印小册子做推广,但是创始团队都是学生,没有钱,怎么印1万份?
他们就想了个办法,找到一家别克4S店,联合印制广告,免费帮人派发,这样就把小册子的成本覆盖了。
这里要说一个非常重要的概念。
商业认知有三大战场:产品战场、心智战场、金融战场。
饿了么印宣传单的举动就是在金融战场打的,拿自己不存在的比较优势找别克4S店融了一笔宣传费。非常高明,饿了么主要卖产品赚钱,没想到在没有卖产品的时候也能赚一笔钱。
“原来我们公司除了卖产品卖服务,其他也有地方是可以卖钱的”,这就是金融。
是不是脑洞大开?
很多人都误以为,金融就是以钱为产品的买与卖,我是做产业的,跟我关系不大。这是狭义的金融,是对金融的重大误解。
我提一个概念,建议大家记下来,我们所理解的金融,是指跨时空的价值交换。
如果你不懂这个,你就完全不懂金融。完全不知道还有大量的资源被你浪费掉了。
3. 谁是饿了么第一个对手?
第一个竞争对手叫小叶子当家。
① 认知优势
2007年小叶子当家就覆盖了上海大部分的外卖,它对标是美国的一家公司,翻译过来叫校园美食。
小叶子当家找对标很准,校园美食已经有完整的运营方案了。饿了么学一个食派士,还只学了一点点,没有完整的模仿方案。
非常可悲的是,这就是饿了么的学习能力与认知优势了:
饿了么学习了一个高端品牌,但它的外卖商家产品价格以20元左右居多;
小叶子当家学的是美国的校园美食,但它的外卖商家产品价格有相当一部分竟然在50元左右,客单价20元左右的占比没有形成绝对份额。
两家所学习的对标与实际的行为,完全错位了。
上海物价再高,你主打的第一对象是学生,价格就要符合他们的消费水平,所有的东西都要围绕这个焦点来配套。
假设我是一个大学生,我自己日常吃外卖18元,如果我请女朋友吃外卖,会吃50元的么?50元的利和弊是什么呢?这个价格为什么不请她去饭店吃呢?
你看,用户就进入认知决策的领地了。
这里的一个启示:创业起步的时候,一定要单点突破。产品与服务的对象越窄越好,主打核心人群的核心利益与核心需求,把他们打穿打透,不要怕以后其他非核心人群不会来。
② 价格战
同质化竞争,结局必然是价格战。
小叶子当家和饿了么开始捉对厮杀了,第一个上来的手段糟糕了,小叶子当家作为细分市场先行者,出了狠手,大量补贴,送冰红茶,送荷包蛋。
饿了么这帮家伙只有5万左右的资金,怎么跟人家小叶子注册资本100万去拼呢?
进入了别人的势力范围,别人拿补贴打你,打价格战了怎么活?
③ 执行优势
要想从残酷的价格战中生存下来,就必须要选择一个战场,通过高效运营、高效执行进行反击:产品战场、心智战场、金融战场,从哪个下手?
A.产品战场
只有同质化才会打价格战,送餐体验上饿了么并不占优势。
在产品端能不能跟小叶子当家 PK 一把?
那个时候技术上比较落后,大部分的订餐是靠打电话、短信联系,电话经常占线,记错内容。这是痛点刚需。饿了么在PC端做了一套商家系统,小叶子当家也做了,但是饿了么的产品更人性化。
B.金融战场
前面我们专门强调了,不要认为只有互联网的企业或者从业人员才具有互联网思维,那也是错的,互联网也是金融。
因为,互联网最善于做跨时空的价值交换,一边免费把流量拉过来,免费必然亏损,但是不怕,另一边可以把流量变现,就能赚钱。
流量导入、关系沉淀、价值变现,已然是互联网的标准作业流程了。
这里有很多细节,饿了么明显比小叶子当家懂互联网思维,更懂金融。
除了产品本身,饿了么还能创造哪些本来并不存在的价值?这些价值与谁可以交易、互换,甚至可以直接变现?
第一,缩短交易流程,提升商家效率。
小叶子当家流程:有订单了,需要确认、接收,再按一个打印。
饿了么流程:有订单了,一键打印。
不要小看这种微不足道的微小进步。
一是这种进步是以客户为中心的,以效率提升为驱动的,说着容易做起来就难了。有不少企业把客户思维放在口头上,无法在产品上直接落地;
二是因为无论2C,还是2B,在互联网上,每多经过一个页面,流失率比想象的多得多,经过5个页面,几乎就没有客户转化率了。
第二,提供数据分析给重点商家。
张旭豪这个大学生团队学习能力真得很强,他们做了一些辅助性工作,把几十个重点商家上个月的经营情况做了分析(在什么时间点订的餐比较多,什么菜是热门菜?)给到商家,帮助他们改善经营,提升效率。
他们拿数据分析做了交换:
本来饿了么提成是8%,现在我希望你根据上个月的量预付下个月的8%。我给你免费做这个分析,不多收一分钱,那个8%也是多退少补的。万一卖得少就退给你,卖得多后面再补给我。
饿了么又凭空多融了一笔运营费用,而且提前一个月拿到了。这就是金融。
第三,开发人性决策,学习跨界对标。
还有一个很牛的,研究另外一个跨界对标——在网上卖软件的SaaS。
注:SaaS:软件即服务(英文:Software as a Service),21世纪初期兴起的一种新的软件应用模式。
根据国外卖SaaS的经验,发现一个特点:
收取8%费用的时候,客户会进入认知决策,心里会关联、比较:
平台帮我卖的量不够的时候,我付你8%对我没有意义,你帮我赚了92%意义不大,但是量很多的时候觉得又心疼,这怎么办?
SaaS的解决办法是收取年费,饿了么也学习了这一点,按销量收取4800元的年费。这是不是又凭空多融了一笔运营费用,而且提前一年拿到了。这也是金融。
C.心智战场
用户一旦形成了“认知”,就要想办法往“人性”层面去推动。收取年费这种价格体系一旦商家接受之后,就会在商家心智里发酵,形成连锁反应。
第一,商家会从认知决策中,计算出来省钱了;
第二,这笔钱已经花完了,如果再找其他的渠道,再给别人8%就不划算了。
为了节省成本,他们甚至把其他的渠道客户也往这个渠道拉。
第三,捡便宜是人的天性。一次性付完4800元以后,商家的客户量交易量在增长,却不必再付额外费用,商家觉得自己捡便宜了。
这里注意很重要的一点,千万不要随便降价促销。因为降价促销会对品牌造成巨大伤害,使客户产生“每年在正常时间买货,不如等到在降价时间点买货”的期待。这样客户对你的品牌认知会越来越差。
对于客户来说,便宜不重要,捡便宜比便宜本身更重要。你要给客户一种在某种情况之下可以捡便宜的机会,可以名正言顺的推销和降价,于是客户量就自然增长了。
饿了么在心智战场做了很多事情,比如他们在2008年的7月17号就注册了一个很容易记的域名,www.ele.me。显然,这都是面向大学生心智而精心设计的。
他们通过编写代码在交大BBS里发站内信进行推广,发完之后一下就爆了,产生了大量的自然流量。这也是顺应大学生心智的推广行为。
在这样情况之下,大概打了九个多月,小叶子当家就从上海交大闵行校区这个外卖市场退出了,都没有顽强抵抗。
因为认知失误,多少年后,小叶子当家创始人与某一投资人闲聊时,说我们完美的错过外卖风口,当时就完全没想过外卖会是一个大风口。
显然,在商业三大认知战场(产品战场、心智战场、金融战场),饿了么建立了自身的比较优势,相对竞争对手,学习能力更强,执行力更强。
4. 谁是饿了么第一个对友?
我这里写的是对友,而不是队友。为什么?
因为,我们常常钻在自己的行业中出不来,找不到自己的一个正确的,特别是有可能是异业的对友。我写成对友,就是要提醒大家不要局限在自己行业内找合作伙伴。
饿了么的第一个对友,应该是别克4S店。
早期最大的对友是朱啸虎,在关键时刻给了他们很大的支持,投了100万美元。
朱啸虎确实眼光独到,在外卖完全没有展示出风口特征时,就提前布局了。
朱啸虎说过一段话,大意是说:
志存高远、想当独角兽的创业者,一定要在行业5%-10%认可的时候,就开始创业,而一个优秀的早期投资人,会在行业10%-15%认可的时候,就开始投资。
可见,优秀的企业家,命中注定就是孤独的。你开始干一件事的时候,90%的人反对你,打击你,挖苦你。但你要坚持自己的信念。
5. 品类第一
2008年创立,2011年朱啸虎投了第1笔钱,到了2013年,大名鼎鼎的红杉资本投资了饿了么。以此为标志,饿了么在中国外卖品类第一的态势正式形成。
这个品类第一是怎么来的?
起步是上海交大闽行校友外卖品类第一。这是一个又细又小的一个区域细分市场。
然后主打上海校园外卖品类第一。品类外延又升级了。
最后再逐步扩展到全品类第一,包括校园、白领、住家。
品类是商业主权,不是规划出来的,也不是靠广告砸出来的。它是在消费者心智中自然建构出来的。从单点突破的小品类,是可以成长为中品类、大品类第一的。
在品类第一的升级过程中,需要注意的是,消费者心智一旦进入认知决策,就会有认知关联与认知比较。
这个显然需要精心设计,学费是一定要交的,但可以少交一点。
2013年,阿里系淘点点、美团外卖杀进来了。2014年百度外卖杀进来了。无利不起早。这就是整个行业进入高速增长期的典型标志。
饿了么默默耕耘了5年的外卖市场,从2010年1.5亿规模,涨到2014年近100亿市场规模。
2013年以前,有美团,还有大众点评。它们都是以到店堂食流量为主的品类。
2013年起,随着市场规模激增,有了行业成果,饿了么正式开创了一个餐饮新品类:外卖。以前的外卖只是堂食微不足道的一个补充,现在成了并列且高速增长的一条新赛道。
进入2017年,这个品类又发生了变化。以美团、饿了么为代表的,又进行了品类升级,现在叫“本地生活服务类电商”。消费者心智显然已经接受了这种升级。非常可惜的是,饿了么让出了品类第一的宝座。
6. 螳螂捕蝉,黄雀在后
每当行业出现风口,出现拐点时,都有两层涵义:一层叫事实拐点,另一层叫认知拐点。
作为品类领先者的饿了么,眼睁睁地看着淘点点、美团、百度都来入局争抢自己的奶酪。这是事实,那怎么认知呢?
淘点点显然在阿里体系的重要性、优先级没有排到足够高的位置,战略力度和战略资源都不够,没怎么认真地玩。
而我本人一直有一个猜想,假如百度把食派士给买了,改个中文名字,从外籍金领往中国白领自上而下来打,那中国外卖会不会是另外一种结局?
百度品牌在用户心智中,是技术驱动型的,直接做一个“百度外卖”,是不是属于品牌不当延伸?就好像我买了一辆奔弛的汽车,就一定会买奔弛的西服么?消费者心智能不能跨过去?营销性价比合适么?
到了2013年大家才发现,原来饿了么开创了新品类,没有开创新行业,也没有开创新产品。原来我们吃饭除了导流到店里之外,还可以送外卖。以前外卖是完全临时应付一下,现在变成了规模化来使用了。
饿了么是中国外卖的品类第一,可惜他们没有守住。
因为它的竞争对手是善于深度思考,善于建立认知优势与比较优势,而且还具有战略欺骗性的美团。在相当长的时间里,外人都以为美团就是试试外卖,没有什么大理想。
三、饿了么美团外卖大战
1. 商业三大认知战法
① 胜势战法:认知优势,先胜后战
《孙子兵法》有云:胜兵先胜而后求战,败兵先战而后求胜。
胜势战法轻易不打仗,先创造决战的条件,首战就是决战。找准时机,先胜后战,不胜不战。美团外卖就是典型的胜势战法。
知道为什么而战是底层的,知道如何战,又厉害了,知道在什么时间战,最牛。并不是你具备的条件立马就可以战,必须等到那个时机,胜势战法以后在互联网中的应用会越来越多。
② 优势战法:比较优势,十优十战
食派士属于这一类。我有比较优势,我是外国人心智中的品类第一。虽然做不大,你也不能把我干掉,我也能活得很好。我只做自己的优势产业。
③ 攻势战法:行业特性,百攻百战
饿了么了当初打小叶子当家是攻势战法。攻势战法求百战百胜(实际情况往往是屡战屡败),打不赢也得打,否则找不到生存机会与方向。
一个志存高远、格局比较大的企业家,时时刻刻都在觉察着商场的细微变化。经常问自己这三个问题:
谁值得我学习?(谁是对标?)
谁在抢我的饭碗?(谁是对手?)
谁可以在一起合作?(谁是对友?不只是队友)
这是每天都必须要想的问题,是睁开眼睛想,闭上眼睛也得想的问题。
2. 美团本来是搞团购的,怎么做起外卖来了?
餐饮这个领域,美团与大众点评是两种不同的方式。美团搞团购,更多是侧重于营销,没有产品端,也没有配送。
美团做了监控行动,不管是谁,不管做什么行业,哪怕就是做火葬场的,只要用到互联网,日交易量超过一定数据,美团就派人研究。
他们在研究中发现,外卖市场品类出来了。外卖是高频的,毛利比团购高。美团就此决定进军外卖市场。
美团有工具,始终有认知优势,这个认知优势不是概念,而是有一套落地方法。
当时饿了么排名第一,市场份额已经超过50%。美团外卖要阻击饿了么,从哪儿入手?
3. 认知战法:用户认知与资本认知
在产品战场、心智战场、金融战场这三个战场中,有两个认知是非常重要且容易被我们忽视,或者说不容易找到落地方法的,那就是用户认知和资本认知。
① 用户认知
在产品战场,用户需求是短期的,短期需要能看见利益,视野较窄。
用户认知往往是长期的、利益更大的,但要说服用户不太容易。
显然,美团外卖要说服用户说它是最好的中国外卖,这是不现实的,营销成本巨大。
② 资本认知
资本市场怎么认知你更重要,但是也更难。资本市场青睐头部资源,美团外卖作为一个新进入者,不见得拼得过市场老大饿了么,资本不见得认可。怎么办?
4. 美团果断出手,狙击饿了么融资
饿了么融资,A轮、B轮、C轮,2014年D轮大众点评。大众点评当时是美团的竞争对手,美团要狙击它。
2014年有一个非常知名的基金,已经决定要投饿了么,开始派团队进行尽调。尽调对一个谨慎的投资人来说,只要验证情况大致不差,不要有突发性事件,就意味着投资成功。
这个时候美团某高管联系了该基金负责人,重点介绍了美团做外卖的比较优势和认知优势。
先亮观点:美团能成为中国外卖的品类第一。
底层逻辑是我有运营优势,美团在全国200个城市都有点,都是从“千团大战”的血海中杀出来的,在全国铺点、地推的能力非常强。这是饿了么不具备的。
再者,美团对本地生活服务有自己的认知优势,超级账户理论就是在这个时间点形成雏形的。
美团成功地阻挠了饿了么的这一轮融资进度,最终这家基金没投饿了么,改投美团了。在资本圈内,对饿了么造成了一定的负面影响,形成了一定的负面认知。
③ 产品战场
强敌环伺,饿了么当然很紧张,肯定对美团外卖做了很精确的信息了解。
美团外卖具有相当强的战略欺骗性。这就是孙子所说的:
兵者,诡道也。故能而示之不能,用而示之不用。近而示之远,远而示之近。
美团外卖跟着饿了么后面学了半年,什么创新都没有,饿了么干什么,我就直接copy你什么,闷不吭声学了半年。
这导致了饿了么团队战略误判,他们认为美团没有创新性,只会做跟随者,自己有一年左右领先的时间。
2014年暑假,美团突然招了1000个人,培训一个月,派到100个城市。饿了么发现后来不及培训,也往这些城市派人。
到了8月份,美团初步战果就出来了。在随后的半年时间里,在全国市场,美团以极高的速度一路直追,始终没给饿了么喘气的机会。
在产品战场,外卖还有一系列的关键成功要素。这些都是经营的杠杆。
其中一项指标叫订单密度。表面上看外卖是B2C业务,其实不然,它是B2B2C业务,其中一端是商家。
对于商家来说,你一天帮我卖3单,还是20单,这对我的吸引力大不一样。这个指标就叫订单密度。如果一天订单超过50单,这个商家就会积极配合。
在订单密度上,美团敢于把某些特色小品类独家承包销售,出手比饿了么要狠多了。特色产品本身即是内容,就这营造出了内容型产品,而这种内容又具有社交性,容易在年轻人中进行口碑自传播。
2015年10月份,美团和大众点评合并之后,对饿了么来说顿时敌人变成了朋友,朋友变成了敌人。本来跟阿里之前死掐,大众点评是我股东,现在大众点评和竞争对手合并了,大众点评就变成我的敌人。
在产品战场,此时的美团已经具有领先优势,而且把外卖品类升级并开创到一个新品类:本地生活服务类电商,还有一个资本认知的术语,叫超级账户。
④ 金融战场
这回轮到阿里坐不住了,它出资95亿美元把饿了么给收购了。
阿里巴巴收购饿了么的时候,认知优势又来了。
第一,买的是流量。因为饿了么已经有3亿用户在天天高频玩,尽管阿里不缺流量,但这个流量对它来说很值钱。
第二,本地物流的能力。饿了么可以在30分钟之内送达,这种物流能力是阿里欠缺的。
第三,消费大数据很值钱。
饿了么不单单是外卖,还是本地物流中的佼佼者,把认知格局再往上提升一下:外卖极有可能会走出来像亚马逊那样先卖书,再卖商品,再走云服务的超级公司,这就是阿里对美团做大之后最紧张的地方,也是腾讯和顺丰等都非常紧张的地方。
本地生活服务电商品类越来越大,会影响到我们每个人。千万不要以为他只是一个送外卖的。当你站在一家餐饮店的门口,不直接进店,非要查一下大众点评时,你就知道消费者决策路径永远地改变了。
当每个月有1亿多人次,通过美团先查询,后决定去本地哪去玩的时候,你就知道用户认知是多么强大地改变了我们的消费习惯。
四、反思与认知
1. 张旭豪的反思是什么?
我从来不在媒体上说我最大的教训是什么,好像大家感觉饿了么顺风顺水,其实我是有反思和教训的。我最大的教训是没有想清楚,整个社会不变的是什么事情,导致现在一直被对手追着。(张旭豪)
有一段话让我觉得贝索斯的思考深度确实挺深:我们很多人每天都很忙,都在适应社会的变化,但是每个人可能没有关注未来10年不变的是什么事情。(张旭豪)
你今天做产品、做开发可能有这个需求那个需求,有些需求是变来变去的,但是它本质有很多是一样的。我们反而在本质上没有花很多时间去思考,这个问题是我创业以来觉得我最大的问题。(张旭豪)
一直被对手追着,像噩梦一样,就是因为没有建一个护城河,干对手干不了的事。
2. 认知优势究竟有多重要?
很多时候我觉得一个成功的公司,6分、7分是靠大势,我们要认准大势顺势而为,而3分呢,其实是靠我们每个人的努力。我们能做的可能就是要靠不断地努力、不断地勤奋,有可能最后才能等到大势的到来。(张旭豪)
品类第一,是最好的差异化竞争。它建立在强大的认知优势与比较优势基础之上。
品类第一,单点突破。做的不是细分市场的第一,要做就做品类第一,品类一定是用户认知的,资本市场认知的,不是自嗨的。它是一种商业主权。
3. 定位究竟有多重要?
从某种意义上说,饿了么的出现尽管具有一定的偶然性,也说明张旭豪在误打误撞的过程中用了非常好的策略——定位。
为什么张旭豪第一桶金能杀出来?
肯德基和麦当劳店址基本都选在一个地方,因为客源、流量聚集。早期进入中国的洋快餐需要付出行业教育成本和客户教育成本,后进入者紧贴它们开店,就可以节省大量经济成本。
上海交大闵行校区就是因为封闭、大、远,所以才有很大的订外卖需求,小叶子当家在那个地方活得就很好。紧贴着小叶子当家在那个地方做生意,行业教育、客户教育成本人家都付完了,这就是定位。
我们不要认为定位就是广告,是营销,这是错误的认知。
从认知心理学、行为金融学的角度考虑定位,是因为价格不取决于功能,要在功能上卖价格,就进入认知决策,就很难。
但是价格取决于竞争对手,成本也取决于竞争对手。这两句话是定位的战略价值所在。换言之这两句话,都可以直接应用于金融战场,直接产生经济效益。
战略都是事后总结的,但是饿了么管理团队,特别是创始人张旭豪,早期朦朦胧胧之中有一种非常强的商业直觉,加上非常强的商业学习能力——他们选择了小叶子当家竞争力最薄弱的、用户教育成本最低的一个相对轻度解释的市场,进行强攻,抢占了一个小品类第一,最终不断品类升级,也是取得了令人惊叹的商业成果。
定位就是竞争,定位就是战略,定位就是金融。
时间关系,今天主要以认知战法为主。关于定位金融,今天就不展开多讲了。
感谢大家,祝大家学习愉快!
本文来自微信公众号:笔记侠(Notesman),作者:灰度认知社创始人曹升。
]]>如果你想成为更好的开发者,你应该尤其注意第15 点和第29 点。
积极大胆地谷歌。你得知道如何有效地组织搜索关键字,查阅别人写的代码,然后合理地用在代码里,从而解决问题。
拥抱变化,坚持不懈。老手程序员在接触新技术时,能欣然接受像个初学者一样处处受挫,并总能在完成工作的同时自学成才。
承认细节的重要性。例如变量和函数的命名、CSS 属性的命名、该用哈希还是用数组,以及其他看起来微不足道,但可能对项目有深远影响的事情。
承认大多数的“重要决定”其实并没有那么重要。一般的开发者经常在技术选型等“重大问题”上陷入唇枪舌战,而程序员老鸟们会避免浪费时间在骂战中。这一点上,他们就像禅宗大师一样(zen-like)。
选择合适的工具解决问题。网上有无数的开源库、工具和框架,让人眼花缭乱。而老手们清楚地知道针对怎样的问题,应该用什么样的工具。
明白代码「不值钱」(该删就删)。你必须习惯于删掉几百行代码来重写程序的某一部分,毫不留情。
在评估技术的时候要全面。例如,我一直在鼓吹Elixir。它语法优美,社区完善,有很大的潜力。但Elixir诞生的时间太短,所以如果要构建复杂的功能,可能会难以找到能帮你提高效率的开源工具。因此,在评估要不要选择使用一项技术时,你得把所有这些因素都考虑在内。
学会说“我不知道”。没有比拒绝承认自己不知道更能浪费一个开发者的时间了。
仔细分析错误信息里的线索。传统教育告诉我们:失败是坏事。报错信息这种东西也经常被跟失败联系起来,然而优秀程序员明白,这些错误消息里其实隐藏着能将你指向最终正确解决方案的线索。
了解过早优化和必要的“炫技式”优化的区别。老手们清楚在什么时候需要写一些看上去没那么好懂,但会让程序运行更快的代码。
每个人都会犯错,为自己的过失负责。而尤其在团队里,把责任推来推去没有任何意义,因为错误的发生往往不只是一方的因素造成的。
成为你所用的开发工具的重度用户。如果长期在某个开发环境下有相当比例的开发工作,那你应该去掌握使用它的细节。
学会用Vim(至少会一点)。 你至少应该在这个编辑器里学会勉强地移动和翻页。
不要接陌生技术领域的私活。个人做自由职业项目,其中很大一部分挑战就是评估项目时间。不要规划自己未知领域的事情,那会让你处于想当尴尬的境地。
不要数你干活花了几个小时。技术大牛会把时间花在有深度的工作上,并且他们清楚花了多少时间完全不重要。
学会坦然接受批评。当你的代码因为各种原因四分五裂时,你需要培养用理性和逻辑的方式来应对(而不是情绪化处理)。
同有更多经验的人结对编程。没有比这个更高效的编程学习方式了。
一定要先自己做一遍代码审查。当你在GitHub上发起一个pull request之前,先把代码当成别人写的,自己先审查一遍。
认识到做自由职业的难点不是写代码,而是其余的所有事情。销售、推广、客户支持,质量保证以及产品管理,所有这些都会花费大量时间。
发现并解决更大的问题。优秀的程序员不拘泥于眼前的问题,而是清楚如何用更长远的方式彻底的解决这一类问题。
深入了解一些大型开源项目的核心能让你开发时如虎添翼。如果你知道如何给你的项目打猴子补丁(Monkey Patch), 那么你将无所不能。
跳过多数的会议。你的公司雇你是来写代码的,而不是谈代码的。当会议多到失控的时候,不去参加也没有任何问题。而且一旦你开始这样做,别人会更珍惜你的时间。
知道什么时候开始回馈。 到了某个时候你需要将你的技能和经验传授给年轻的开发人员,就像你的导师当时教授你一样。
能写烂代码。有时候可以当一当“胶带式程序员”。关键是随着时间推移,你需要弄清楚什么时候可以走捷径,什么时候必须走捷径。这其实是最难掌握的技能之一。
礼貌地告诉别人你工作到很晚。如果你是办公室里最后一个,可以发一封简短的汇报邮件。别人一般会注意到邮件上的时间戳的。
像一个领导者(Leader)一样做事,而不是老板(Boss)。老板是让别人为他工作的人,领导者是人们追随的人。做个领导者。
去打打桌上足球。从长期来看,同其他开发者(或不同岗位上的同事)建立联系会比在紧巴巴的期限里交付一个功能更有价值。
在压力下学习。你需要知道如何应对像系统宕机而你要负责将它复原的情况,即使一开始你完全没有头绪。
“Move fast and break things” 别让完美主义阻止你做事。错误往往是最好的学习机会。所以别把犯错当作失败,而应该把它们当作值得学习的经历,并意识到:正是不断克服和突破这些错误,作为一个程序员,你才能不断成长起来。
像生活中的很多事情一样,编程也是你做的越多,了解的就越多。所以如果你是一个新手程序员,还是直接去编码吧。记得将这些最佳实践应用在日常工作中,来不断提升你的编程技艺。
]]>
|
|
|
|
设置任务名称 set mapreduce.job.name=xxx_yourname;
指定任务队列 set mapreduce.job.queuename=offline.data;
任务结果输出header信息 set hive.cli.print.header=true;
设置优先级 set mapreduce.job.priority=HIGH;
优先级说明:
配置mapreduce.job.priority
来调整优先级,支持的值:
值 对应YARN优先级 说明 NORMAL(默认) 1 普通任务 HIGH 2 nearline 任务 VERY_HIGH 3 在线任务 CRITICAL 6 关键任务 VERY_CRITICAL 9 非常关键的任务
|
|
|
|
|
|
文档:Rank()
Rank() 可以为原始数据的每一行生成新的一列,值为这一行所在分组的排序 rank; 这样就可以根据 rank 值来保留所需要的 Top N 的行,也可以参考所在分组的总行数,保留 Top n% 的行。
Example:
|
|
文档: NDV()
相比 count distinct 更快、更节省内存,但存在误差 (HyperLogLog). 在查询很大的 count distinct,且对准确性要求量级正确即可时,e.g. 月活跃用户(MAU),可以考虑用 NDV 代替 count distinct.
NDV() 只能对单列做计数,所以如果需要多列组合计数,需要做一个拼接转换。
Example:
|
|
对字符串split得到array,再把array展开
示例:it是字符串,取值样例’refresh,push’
|
|
对value值进行过滤,选取符合要求的keys
示例:lt_lk_keyword是Map,取值样例{123: 0.1234, 234: 0.2345}
|
|
示例:
|
|
直接以查询结果建表
|
|
|
|
文档:CreateTable
Example: 创建包含2个字段的临时外部数据表
HDFS数据:xx.json。目录中可包含多个文件。json文件内容:
|
|
不将数据存储在hdfs,直接从本地load进表
|
|
文档:CreateTable
Example: 创建包含2个字段的临时外部数据表
HDFS数据:/users.csv。目录中可包含多个文件。csv文件内容,以\t分隔:
将数据表从hive同步到impala, 在impala执行: invalidate metadata test.source_list_focus;
|
|
|
|
Mac下,只要在Finder访问过的文件夹,都会生成一个.DS_Store的文件,Mac用它来存储当前文件夹的一些Meta信息。对于Git来说,不经意间总是会干扰到其他正常的提交和本地仓库状态,是很烦恼,找了半天,终于有一个比较好的办法处理了
流程大致是这样的:
|
|
搜索一下项目内所有的.DS_Store
,全部rm
掉,然后再push
一把
如果没有~/. gitignore_global
文件,echo
也会为你生成一个,这里的主要目的是覆盖所有可能的OS X
版本生成的.DS_Store
,逐一执行一次就可以了,之后cat
一下看是否正常写入了
|
|
然后设置一下全局的配置
|
|
大功告成~
另外,Github还提供了一个官方的全局示例,可以根据实际需求使用:
最后补充一下
.gitignore
的语法
*
:任意个任意字符,[]
:匹配任何一个在方括号中的字符,?
:匹配一个任意字符,[0-9]
:匹配字符范围内所有字符
|
|
If this repo has not previously been used submodule then Git will create a directory in the directory called .gitmodules , which records the URL of the remote repo and the submodule in this project path.
After executing this command submodule and .gitmodules will automatically staged, this time can commit and push.
Individual repo update is too much trouble, it is necessary to separate directory under execution git pull
to pull the upstream code, but that would be more secure; all at once to update all of submodule can use this foreach
command:
|
|
I thought there will be like git submodule rm
such an instruction, the result is not even, you must manually remove the hard ground one by one, not knowing what not to implement this directive considerations, I hope that future versions can add to it.
Remove submodule has the following steps to do, first remove the submodule directory from the version control system:
|
|
Again to modify .gitmodules , remove the unwrought submodule, for example:
|
|
Not yet finished! But also modify the contents of .git / config , with. Gitmodules , the need to remove the submodule deleted, and finally commit.
Implementation of git clone
Git clone does not automatically come together when submodule must be added --recursive
recursive parameter, so you can catch all associated submodule in submodule down together:
|
|
If you have been caught to find submodule is empty, you can use the following instructions to catch, init
will be registered in _.git / config` remote repo URL and local path:
|
|
Or merged into one line git submodule update --init --recursive
can, if upstream someone to turn over .gitmodules , it seems that local end also using this method update.
git submodule init
: According to .gitmodules name and URL, these information will be registered to . *Git */ config , but not .gitmodules not removed submodule, the use of this directive and no way to automatically delete. Git / config related content, you must manually delete ;git submodule update
: According to registered (that is, .git / config ) submodule to update, such as clone lost submodule, which is the last paragraph of the method, so the implementation of this instruction before the best plus --init
;git submodule sync
: If the submodule’s remote URL changes, you can correct the URL in .gitmodules , and then execute this command, the submodule’s remote URL will be corrected.Golang发展迅速,代码迭代非常快,想要调试和梳理项目进程就成了一件相对棘手的事情。偶然间发现了gvm - Go Version Manager,算是找到了调试切换版本的福音。
GVM,类似于ruby 中的RVM,java 中的jenv(国产),可用于方便管理 Go 的版本,它有如下几个主要特性:
管理 Go 的多个版本,包括安装、卸载和指定使用 Go 的某个版本
查看官方所有可用的 Go 版本,同时可以查看本地已安装和默认使用的 Go 版本
管理多个 GOPATH,并可编辑 Go 的环境变量
可将当前目录关联到 GOPATH
可以查看 GOROOT 下的文件差异
二进制文件的管理比较简单,通过链接使用不同版本的程序即可,实际上主要是一些环境变量和标准库的设置问题,环境变量主要是 GOPATH 以及 GOROOT,标准库的话需要在切换 go 版本时也能跟着切换。gvm 实际上就是帮助完成这些配置工作。
按照官方文档操作即可
|
|
|
|
Mac下需要这样一把(如果你的环境有问题的话)
|
|
一般常规的操作是
|
|
|
|
|
|
Delete Github Repo = = ,that’s a sad but useful way to totally delete
Warning : solution 1&2 not delete pull request history (discussion, file changes). If you do this in order to delete sensitive data, you should better delete the github repo (along with all its pull request history etc..) and recreate a new one from scratch.
说了半天,其实还是直接删除repo最安全…… 前两种我理解,大概是指向删除了,并没做物理删除。 = = SAD
EOF
]]>This gist creates a working example from blog post, and a alternate example using simple worker pool.
TLDR: if you want simple and controlled concurrency use a worker pool.
Small refactorings made to original code:
main()
from where to define flags in program.Simplify the worker queue by removing the Dispatcher
.
https://gist.github.com/harlow/dbcd639cf8d396a2ab73#file-worker_refactored-go
Boot either the worker_original.go
or the worker_refactored.go
applications. Use flags to adjust the max_workers
and max_queue_size
to override the default values.
$ go run worker_original.go -max_workers 5
cURL the application from another terminal window:
$ for i in {1..15}; do curl localhost:8080/work -d name=job$i -d delay=$(expr $i % 9 + 1)s; done
The test run with Pprof show performance characteristics remain the same between both examples.
背景
项目需要隔离部署,如果在docker环境需要使用一些特殊的配置,之前没有太好的判别方法,现在总结一下。
/.dockerenv
判断如果是Docker容器内,根目录会生成一个可执行的/.dockerenv
文件,判断此文件是否存在可以基本断定是否运行内容器内,注意是“基本”,极少数的发行版或者某些定制化较高的系统,可能会不存在此文件。
|
|
cgroup
信息进行判断Docker在Xnix下虚拟环境,使用了cgroup,容器内的group信息与物理机会有本质不同,可以根据Docker内特殊化的环境信息进行判断,这也是目前最靠谱的方案。
正常情况下物理机的cgroup:
|
|
Docker内的cgroup(例子):
|
|
判断响应内容即可,一般情况下,主要看name
& devices
|
|
如果需要当前协程的父进程信息,会对我们定位很多关键信息起到很大的帮助
|
|
]]>EOF
昨天开始一直报错,找不到某个Trace,另外有一点我不太明白,deploy的时候替我提交了,那为何我本地还有这么多修改。
问题很多,但是确实很多没到这边来了,我的个人页也莫名其妙丢失了,SAD。
以上です。
]]>业内讲金山银四,我也到了发痒的年纪了。一方面有家庭上的原因,另一方面,也觉得北京发展的潜力远远大于深圳,机会也多得多,于是,过年期间准备了一下,拿到了今日头条的offer,即将在北京开始新的生活了。
2014年毕业来到腾讯SNG(社交网络事业群),做泛QQ方向的业务,在SNG内算是比较新的业务,老板也相对重视;但从整个公司的角度看来,SNG的优势都不太大,以至于我们经常自我调侃:CDG&WXG天之骄子,IEG游戏土豪,OMG一门三杰,TEG养老送终,剩下SNG吭哧吭哧的干活儿,却不知道未来在何方。
作为一个后端server研发,其实大多数时候是不会带入到公司大的场景中去的,但腾讯是一家特殊的公司,是一家以产品为导向的公司,每个人都有或者说需要有那么一点产品意识,这样的结果是:一方面产品在进化发展,产品运营开发测试,每个人对业务的理解更透彻了;另一方面,对技术不那么感冒,甚至可以说,工程师文化,在腾讯销声匿迹了,也不能说没有,而是被忽略掉了。
对于大部分员工来说,KPI还是很重要的,而落实到每个人身上,很可能就是如果快速的解决某个问题,达到某个目的,一件事情做完之后,回头看的机会真的不多,业务在前进,人也一样——在业务飞速前进的大背景下,从Demo改到V3V4,是一件很痛苦的事情,甚至在一些团队变成了不切实际的行动。这样的结果是:对于大多数非核心部门而言,资源是非常有限的,新的老的业务问题都不一定能搞定,自然无法将资源投放在解决工作效率与代码质量的问题上。半年一次的KPI考评,则从另一个更重要的方面去促使员工选择去解决最能体现价值的业务问题。长期的收敛结果,就是基础设施碎片化、野蛮化生长。
DevOps在腾讯,大部分部门都是很空白的。
代码权限严格,网络权限一年比一年收紧,测试环境(SecureCRT 甚至加上 sz/rz)产能底下,很多生产力工具没提供比如Mac无法申请(其实比某些台式机便宜多了),很多老员工用着落后其他公司一个时代的硬件产品,追赶着行业领先的技术,这种戴着镣铐跳舞的感觉,很多时候实在让人无奈。
在SNG内部,经过近几年的发展,是有集成化运维这类的东西的,但仍然不够,很多重复的事情,仍然不得不人肉,而且还有一些非常蛋疼的规范限制着你——比如通过内部系统,每人每天每个pkg只能pub一次,你pub过就只能找其他同事帮忙,不然就上了本月的研发黑榜 = =||,本人有幸连续三个月上榜过。
另外,腾讯里,很多新团队开发的自动化组件,没有人去用,或者用的很少,推行起来也是困难重重,部门之间,业务不同,KPI没有交集,互帮互助都显得异常珍贵,团队之间,尤其是有点历史的团队之间,技术栈是大相径庭的,要他们容和统一,短时间内实在也不太现实,而长期来看,团队技术栈成型后,他们更倾向于Hire那些符合他们技术点要求的人,而不是能力相当的人,如何循环,再去改造就更加困难了;对比阿里巴巴,内部其实没有特别大的决心去推动一些东西,有学长在阿里中间件工作,基本上集团内推行一种新技术是非常容易的,JDK6到7到8,遇到的阻力也无非是一些必经之路上的技术问题,而不是该不该用好不好用的扯皮,这些问题是腾讯需要思考的。
说了这么多,从我工程师的角度看,腾讯在产品上确实冠绝业界,但在工程技术上,要走的路还很远很曲折。
讲完技术,讲点福利。腾讯的福利非常之好,包含了衣食住行的方方面面,每年的旅行团建,夜宵,兑换,住房保障计划,无息贷款,覆盖全深圳堪比中型城市公交系统的班车服务,逢年过节的红包,结婚生育的礼金,甚至给下一代的VIPQQ号……对于职场新人来说,确实是一家非常值得加入的公司;对于职业暮年的人来说,则可能是可以颐养天年的公司;而对于其他员工,我觉得就因人而异了,可能要看具体工作的方向,部门,和个人对工作的理解了。
毕业的三年是一个非常重要的职业阶段,在腾讯我成长了非常多,也学会了很多,感谢与我一同工作的同事们,他们对我的协助,对我的指导,我都铭记于心;而我在腾讯文化的熏陶下,也完成了从一个青涩学生到一个工程师的转变,这些,都是我职业道路上毕生的财富。
]]>开始是nodejs的组件报错,某些文章里有特殊的jekyll使用的字符等等,这个就折腾了半天 = =
然后是git的rebase出问题,差点崩溃,还好解决了
官网上关于迁移就是这短短的一句话:
结果却不是这样 = =
这边选择了next主题,觉得不错,喜欢的可以看下,后面有时间,也会折腾一下主题(可能有坑 = = )
新开始!
]]>SOA是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以以一种统一和通用的方式进行交互。
这种具有中立的接口定义(没有强制绑定到特定的实现上)的特征称为服务之间的松耦合。SOA的目的,就是要将复杂的紧耦合的系统进行解耦,划分成面向业务的,细粒度,松耦合,无状态的服务。松耦合系统的好处有两点,一点是它的灵活性,另一点是,当组成整个应用程序的每个服务的内部结构和实现逐渐地发生改变时,它能够继续存在。而另一方面,紧耦合意味着应用程序的不同组件之间的接口与其功能和结构是紧密相连的,因而当需要对部分或整个应用程序进行某种形式的更改时,它们就显得非常脆弱,变更可能会导致部分乃至整个系统的重构。
对松耦合的系统的需要来源于业务应用程序需要根据业务的需要变得更加灵活,以适应不断变化的环境,比如经常改变的政策、业务级别、业务重点、合作伙伴关系、行业地位以及其他与业务有关的因素,这些因素甚至会影响业务的性质。我们称能够灵活地适应环境变化的业务为按需(On demand)业务,在按需业务中,一旦需要,就可以对完成或执行任务的方式进行必要的更改。
SOA是传统的面向对象架构模型的替代模型,面向对象的模型是紧耦合的,已经存在二十多年了。虽然基于 SOA 的系统并不排除使用面向对象的设计来构建单个服务,但是其整体设计却是面向服务的。由于它考虑到了系统内的对象,所以虽然 SOA 是基于对象的,但是作为一个整体,它却不是面向对象的。不同之处在于接口本身。SOA 系统原型的一个典型例子是通用对象请求代理体系结构(Common Object Request Broker Architecture,CORBA),它已经出现很长时间了,其定义的概念与 SOA 相似。
然而,现在的 SOA 已经有所不同了,因为它依赖于一些更新的进展,这些进展是以可扩展标记语言(eXtensible Markup Language,XML)为基础的。通过使用基于 XML 的语言(称为 Web 服务描述语言(Web Services Definition Language,WSDL))来描述接口,服务已经转到更动态且更灵活的接口系统中,非以前 CORBA 中的接口描述语言(Interface Definition Language,IDL)可比了。更新的,如protobuf,Thrift等标记语言,则已经在RPC与其他服务协议中占有极为重要的角色。
Web 服务并不是实现 SOA 的惟一方式。前面刚讲的 CORBA 是另一种方式,这样就有了面向消息的中间件(Message-Oriented Middleware)系统。但是为了建立体系结构模型,您所需要的并不只是服务描述。您需要定义整个应用程序如何在服务之间执行其工作流。您尤其需要找到业务的操作和业务中所使用的软件的操作之间的转换点。因此,SOA 应该能够将业务的商业流程与它们的技术流程联系起来,并且映射这两者之间的关系。例如,给供应商付款的操作是商业流程,而更新您的零件数据库,以包括进新供应的货物却是技术流程。因而,工作流还可以在 SOA 的设计中扮演重要的角色。
此外,动态业务的工作流不仅可以包括部门之间的操作,甚至还可以包括与不为您控制的外部合作伙伴进行的操作。因此,为了提高效率,您需要定义应该如何得知服务之间的关系的策略,这种策略常常采用服务级协定和操作策略的形式。
最后,所有这些都必须处于一个信任和可靠的环境之中,以同预期的一样根据约定的条款来执行流程。因此,安全、信任和可靠的消息传递应该在任何 SOA 中都起着重要的作用。
FROM WIKI
以下指导原则是开发,维护和使用SOA的基本原则:
下面是一些特定的体系架构原则:
除此以外,在定义一个SOA实现时,还需要考虑以下因素:
对 SOA 的需要来源于需要使业务 IT 系统变得更加灵活,以适应业务中的改变。通过允许强定义的关系和依然灵活的特定实现,IT 系统既可以利用现有系统的功能,又可以准备在以后做一些改变来满足它们之间交互的需要。
改变和 SOA 系统适应改变的能力是最重要的部分。对于开发人员来说,这样的改变无论是在他们工作的范围之内还是在他们工作的范围之外都有可能发生,这取决于是否有改变需要知道接口是如何定义的以及它们相互之间如何进行交互。与开发人员不同的是,架构师的作用就是引起对 SOA 模型大的改变。这种分工,就是让开发人员集中精力于创建作为服务定义的功能单元,而让架构师和建模人员集中精力于如何将这些单元适当地组织在一起。
相比于基于业务的SOA,微服务则纯粹基于服务模块,也就是每个服务独立为一个子系统,平行扩容对其他服务透明,强调系统的伸缩性,服务发现,负载均衡,故障转移,高可用。微服务是互联网时代的新产物,它对服务的容错与可用提出了更新的思考,比如多版本,灰度发布,服务降级,分布式跟踪,这些都是SOA在实践中重视不够的地方,。
SOA在企业领域的应用更为广泛,对服务的可用性保证也很高,而很多现代互联网企业,对实时性的要求,对数据一致性的要求,甚至对大流量下可用性的要求都是弹性的,比如腾讯,很多业务服务的运营核心是:有损服务,动态运营,这时候,微服务的作用就显现出来,在海量请求下,尽量保证大多数用户的服务,尽量快(弱一致性)的实现数据的同步。可以说,SOA与微服务在不同的领域,但做法可以相互借鉴。
]]>快速排序的算法可以用三句话描述:
[Algo]
- 选择基准项(pivot element, 一般取第一个元素为pivot)
- 把数组里所有小于pivot的移动到pivot左边, 大于pivot的移动到右边 ⇒ 此时pivot已经位于最终排序时的正确位置
- 对pivot左右两个数组分别递归进行快速排序
由以上描述可见, qsort是一个递归算法, 我们可以把它的函数声明写成: void qsort(int[] a, int lo, int hi)
, 表示排序a[lo, hi]之间(闭区间)的所有元素.
由上面描述可以见, qsort最关键的是第二步: 把数组元素以pivot分为两部分. 这个操作就是quick partition.
函数声明为: int partition(int[] a, int lo, int hi)
, 该函数返回pivot(即subarray的第一个元素a[lo]
)所在的位置.
如果允许新建一个临时数组的话, 那么这个就不是什么问题, 但是为了节约空间占用, 现在需要直接修改(in-place)使得a[lo] 到, 而且希望可以用尽量少的交换(swap(int[]a, int i, int j)
)操作, 就不是很evident了.
这个函数的写法是用两个指针i和j分别从两端向中间走, 如果两个指针指向的元素一个小于pivot一个大于pivot那么就进行交换, 当两个指针碰面的时候结束(最后把pivot和指针元素交换). 请看下面这个萌萌的图(图片来自<<啊哈!算法>>):
选取第一个元素(6)为pivot, 然后j向左走直到遇到一个小于pivot(6)的数停止, i向右走直到遇到一个大于pivot的数停止(注意要让j先移动), 此时二者交换:
只要重复这个过程, 直到i>=j为止, 此时只要最后把pivot和j(注意是j而不是i)指向的元素交换即可:
所以pivot的位置就是j, 函数返回j即可.
java实现:
|
|
这里有几点要注意的:
i<=hi
, j>=lo
)qsort之所以快, 是因为每次都能够按照pivot分为大致同样长度的两个子数组(所以每次子问题的规模除以二), 所以复杂度为O(NlogN). 最坏情况下, 如果每次两个子数组中可能有一个长度为0, 那么每次子问题的规模只减少了1, 所以复杂度变成了quadratic O(N2).
为了防止这种最坏情况的出现, 可以在一切开始之前把数组打乱顺序, 所以这一节讨论快速shuffle的算法. 最经典的就是Knuth的shuffle算法了, 算法很简答, 描述为: for(k=1 to n): 每次把第k个元素和前k个元素中的随机一个元素交换.
代码只有两行:
|
|
关于算法的正确性, 其实只要证明”元素i在shuffle后最终位于位置i”的概率为1/N即可, 不难证明.
好了 有了以上两个辅助函数就可以写qsort函数了:
|
|
其实qsort的主体就是那个partition函数, 单独把partition列出来是因为它不止可以用在排序, 还可以用来做quick select, 见quick select节.
对于一个没有排序的数组, 如何快速找到它的中值(median)?
以上这个问题的答案就在partition()
函数.
之前说过, partition()
函数的返回值表示pivot在排序好的数组中的位置(rank), 这个消息非常有用: 中值只不过是rank等于长度除以2的元素而已.
为了寻找rank等于k的元素, 我们用partition函数可以每次把问题规模缩小: 如果partition()=pk那么右边subarray不用考虑, 如果数组事先shuffle过了的话, 问题规模每次缩小一半.
定义一个函数, 寻找rank等于k的元素, 代码类似于二分查找:
|
|
该算法内层循环为O(hi-lo), 每次问题规模减少一半, 所以复杂度为N+N/2+N/4+…+1 = 2N, 复杂度为线性时间!
qsort之前有个bug: 在数组里很多重复元素的时候, 效率会下降为O(N2). 原因是qsort没有好好处理重复元素的问题.
于是Dijkstra提出了一个3-way partition的算法: 把数组分为三部分: 左边[lo, lt)
严格小于pivot, 中间[lt, gt]
等于pivot, 右边(gt, hi]
严格大于pivot.
算法初始化lt=lo, gt=hi, i=lo
, 用指针i向右扫描, [i,gt]为未处理到的部分.
算法很subtle, invariant是这样的:
- a[lo,lt-1] < pivot
- a[lt, i-1] = pivot
- a[i,gt] = unseen
- a[gt+1, hi] > pivot
这个图很有助于写代码:
|
|
说它很subtle, 除了因为没有那个图我写不出来以外, 还有就是, 在把i和lt交换时, i可以increment (因为我们知道a[lt]==pivot
), 但是i和gt交换时, i不能increment: 因为a[gt]不知道多大, 所以i位置要继续检查.