IT八卦

IT八卦

跳来跳去,程序员到底去大公司还是小公司?

技术交流大兴 发表了文章 • 0 个评论 • 93 次浏览 • 2020-10-10 18:30 • 来自相关话题

职场生涯总会面临着选择,尤其对我们这些 IT 人来说,跳槽的频率应该是所有行业中相当大的了。那么我们跳来跳去,究竟该选择什么样的公司 ?大 or 小 。工作三年多了,经历一大一小,最近也面试了不少家公司,形态各异,说说自己的感受想法。在小公司中,给我个人的印象... ...查看全部

untitled.png

职场生涯总会面临着选择,尤其对我们这些 IT 人来说,跳槽的频率应该是所有行业中相当大的了。那么我们跳来跳去,究竟该选择什么样的公司 ?大 or 小 。

工作三年多了,经历一大一小,最近也面试了不少家公司,形态各异,说说自己的感受想法。

在小公司中,给我个人的印象大多数环境都不怎么样。定义下这个小公司规模吧,在几人到几十人吧,反正不会超过100人。

亲历一家小公司, 面试见过数家小型公司。我觉得大概分两种:

1.真正的黑穷丑

入职原因:实在没地方去了,毕业什么也不会,来做苦工吧

缺点:加班是家常便饭、工资少的可怜、福利基本没有,事事都要你干

优点:锻炼你顽强的意志力、培养男人的愤怒血性,当然干的多了能力自然也会有提升,不过如果没有牛人带且自己也不是特强的话,你的视野应该是比较窄的

2.有稳定业务、公司盈利还不错,待遇也可以媲美大公司

缺点:还是个人视野的问题,如果你个人能力很好,不是野心很大,在小公司也不错

优点:至少福利待遇不会差,环境也还可以,公司小自己做的贡献领导会看到,做个2,3年可能就是公司的主干力量了,有成就感。

说说自己的第一家公司,那个小公司

自己毕业时选择的是这家小公司,说选择当时是有对比,而最终决定去这家小公司的原因是他给开了3k的工资,比其他两个相对大的公司多,于是就去了,虽然环境不怎么样,自己也忍了,觉得应该锻炼机会很多吧,有家公司环境着实不错,可是帝都1600的工资实在觉得跌面儿。

正像我说的第2种小公司一样,老板有自己的关系公司每年的盈利还不错,几十人的小公司过的也还算舒服。工资每年都会涨,没用自己提过,基本在一年1k左右,毕业刚去的那年发了5k的年终奖,欣喜的不亦乐乎。

在公司的工作就是做一些小项目,很少加班,开始有人带,而后就是自己做项目,整个项目的方方面面,再后来还要带一些刚毕业的小弟弟,实在不敢以师傅挂名,羞愧不敢当,觉得自己的水平不够,于是考虑到在该公司的状况也就如此了,自己又不是视野很宽知道学什么的主,于是有了离开的打算,想去看看国外的月亮。

没见过国外的月亮,都会觉得外面的月亮是更圆的。尽管工作2年的时候工资翻了一倍,那年的年终奖也拿到2w多的地步,老板器重的情况下,还是选择了了离开。

觉得外面的世界很精彩,自己需要出去看看,就这样离开了,来到了一家规模还比较大的互联网公司,虽然工资只比原来多了1k,还是去了,觉得神秘的大公司应该可以学习到不少的东西吧。

很庆幸,刚毕业没有遇见第一种小公司,一些脏乱差,到处摆满东西的公司在后来的面试时还真是见过几个。

一个插曲:一个什么外包公司要我去面试,进去后一看里面安了很多挡板,临时搭的那种,我以为公司发展过来的小分部,随后了解说这是公司总部,汗颜。

来到了大公司

虽然钱没多挣(也许还不如以前的多),但一下子觉得自己牛逼了不少,因为自己的公司耳熟能详啊,可以和别人吹牛逼,也可以给自己的职业生涯贴贴金。

干净的办公环境,每过一会儿就有人清理的卫生间,正版的操作系统、应用软件,公司项目用的新技术,一切的一切都是新鲜的,就像一个村儿逼来到了城里看见了摩天大厦,豁然开朗。周围人也都是4,5年工作经验的牛人……

也就是半年吧,新鲜感过了,也没什么了。唯一感觉的就是觉得工作无聊,整天维护着那么一个小项目,有时很长时间都不知道做什么,也许是自己的问题吧,但是我确定的是这不是我想要的,跟我想的不一样。

不过在该公司的一年多时间里,技术上有一定的提高、见识也增长了不少,但是更大的变化是自己的思想发生了很大的改变。

以前觉得自己是一个.net程序员,就像园子里曾经有人说,这个叫法很蹩脚很奇怪,确实是这样,我们为什么要把自己定义为一个xx程序员?而我们只是一个程序员啊,写代码的程序员,不管是java、c#、php、python、javascript…. 这是一个重要改变。

一直在想,我追求的所谓大公司,到底追求的是什么?

离开第一家小公司想要追求的东西,想要有人带,有高手指导,而这只不过是自己能力的欠缺与知识获取方面能力的不足罢了。

当我们自己这两方面足够强大的时候,我们就成为了高手,不再需要别人的指导,你追求的大公司也就成为了一个空壳。

所以我觉得,大公司、小公司都无所谓,首先我们要让自己牛逼,或者知道怎样牛逼起来,然后再有施展技能的平台就够了,大、小只是一个壳罢了,问题的根源在于你是否能够牛逼起来!


写给年轻程序员的一些心里话

技术交流大兴 发表了文章 • 0 个评论 • 65 次浏览 • 2020-10-09 18:39 • 来自相关话题

每个人的经历都是不同的,也是无法复制的。不要试图复制某个人的成功,你将徒劳无功。但每个人成长过程中总结出来的经验却是可以供他人借鉴的。下面我把自己这么多年的生活经验总结了几条,分享给各位,希望能给大家带来一些有意义的帮助。1保持自信做任何一件事情之前,你都要对... ...查看全部

09d50ad12ab7fe446af8aeb2a2ab05d0.jpg

每个人的经历都是不同的,也是无法复制的。不要试图复制某个人的成功,你将徒劳无功。但每个人成长过程中总结出来的经验却是可以供他人借鉴的。

下面我把自己这么多年的生活经验总结了几条,分享给各位,希望能给大家带来一些有意义的帮助。

1保持自信

做任何一件事情之前,你都要对自己充满信心。如果对自己不自信的话,就会在潜意识了给自己消极的心理暗示,到最后你都不敢去尝试做这件事。如果连尝试的勇气都没有了,就更谈不上把这件事做成了。

关于自信和不自信给一个人带来的不同影响,我在这里就不废话了,很多心理学的专业资料都有论证,相信各位自己也都有亲身经历。

人的自信心其实是可以培养的,我的方法是,每天结束之后都想想自己做成了哪些事情,哪怕是一些特别微不足道的事情。比如今天上班没迟到;比如今天少抽了一根烟等等。通过这些很小的事情,很容易达成的事情,来慢慢积累自己的信心。

2持续学习

社会总是不断在进步,新的事物和概念总是不断涌现,如果我们不持续学习,最终会被这个飞速前进的时代列车所抛弃。各位可以观察一下自己身边优秀的人,无论年龄大小,无一不在持续的学习。咱老祖宗的古语说得好,活到老学到老。

其实很多程序员都是比较爱学习的,因为总是有新的技术和框架出现,逼着大家去学习。这里我想说的不仅仅是对技术的学习。而是所有的东西,比如新的思维方式,新的认知方式等。

所谓的学习就是认知新观念和新想法的过程。我们遇到新的概念和事物,要勇于去尝试,尝试用新的思维方式去思考问题。不要轻易用已有的思维方式给之前没遇到的事物下结论,这样很容易阻止自己的进步。

这里可以给大家举个我生活中的例子。当年我结婚的时候,去家具城买床,我看中了一款特别厚特别软的床垫,大概不到1W块钱。我老娘就说不要睡软的床垫子,对腰不好。因为他们那个年代的人,都是睡硬床板过来的,所以根本不愿意接受这个新的事物,上来就否定这个东西。

前段时间,老娘来我家里,我让她睡在了那个床上,第二天早上醒来,老娘跟我说,这个床垫子还挺舒服的。

我们在不了解一件事物的时候,千万不要根据已有的思维定式去下判断,要接受新的事物,新的观念,不断更新自己的认知,千万不要让自己变成老顽固。

3学会理财

大部分程序员的工资还是很高的,特别是那些大厂程序员。但是跟很多的年轻程序员聊起来,发现他们其实没有多少存款,甚至根本没有存款。

其实理财根本不能让我们实现财富自由,但是理财可以让自己的生活更有计划,更有保障,给你自己和家人带来更多的安全感。比如这次疫情,很多人都失业或者被降薪了,如果手里没有余粮还是挺狼狈的。

特别是随着年龄的增上,你的责任也会越来越大,比如谈恋爱了,想换个有面子的车子,孩子要上补习班,父母生病了,等等。所以劝各位还是要认真规划自己的收入,无论多少。正所谓你不理财,财不理你。

关于理财,我自己的做法是一部分钱放在银行,一部分钱去买基金理财,还有一部分钱用于日常消费。放在银行里面的钱,相当于自己的粮仓,轻易不会动,是自己的靠山。俗话说的好,家中有粮,心中不慌。

而基金理财,是可以让你的财富升值的;其实基金是广大非专业人士最理想的投资方式,简单易操作,而且风险不会像股票那么高。

关于买基金,建议各位选一些大公司的基金产品,采取定投的方式,一定要长期持有(以年为计量单位),不要一看下跌了,心理就发慌,一发慌就开始卖出,这样做你将成为一名优秀的韭菜。

我看过很多材料和数据,大部分基金从长期来看,平均每年都会有12%的收益,这是什么概念呢,就是你买一万块钱的基金,到年底的时候,会盈利1200块。根据我自己的实际经验也是符合这个说法的。关于具体收益算法,以及为什么会是12%的收益率,这里我就不展开了,毕竟我不是卖理财产品的。

最后在多唠叨几句,投资有风险,要拿自己暂时不用的闲钱去投资。千万不要拿自己的吃饭钱去投资,更不要拿父母的养老钱去投资。你这样做不是投资而是赌博。

4幸福生活

每个人对幸福生活的定义都有各自的标准。我所理解的幸福生活,不是拥有了多少财富,也不是开多么豪华的车子,而是你内心的充实,有时间进行自己的业余爱好,有一起闲聊的好朋友,周末的时候可以陪陪父母和家人。

总之我不建议各位为了获取更多的金钱,而失去太多本来可以体验美好生活的时光,毕竟我们赚钱的目的是为了幸福生活。大家不要舍本逐末,要做好平衡。毕竟中国人最讲究中庸之道!相信各位在生活和工作之间都能做好平衡。

原创:花括号MC(微信公众号:huakuohao-mc)。关注JAVA基础编程及大数据,注重经验分享及个人成长。

外卖骑手的解困之策

技术交流大兴 发表了文章 • 0 个评论 • 66 次浏览 • 2020-09-30 10:06 • 来自相关话题

来源:虎嗅APP作者|王海、孙昊头图|CFP.CN背景本月初,一篇针对“困在系统里”的外卖骑手的新闻报道展现了外卖行业中险象环生的现状,激起社会各界的广泛讨论。面对外卖市场的激烈竞争,平台持续地追求提升效率和降低成本,采用大数据技术和人工智能算法,并在发掘人力... ...查看全部


cf1b9d16fdfaaf516a3cab6bf057c8e9f11f7a15.jpg

来源:虎嗅APP

作者|王海、孙昊头图|CFP.CN


背景

本月初,一篇针对“困在系统里”的外卖骑手的新闻报道展现了外卖行业中险象环生的现状,激起社会各界的广泛讨论。面对外卖市场的激烈竞争,平台持续地追求提升效率和降低成本,采用大数据技术和人工智能算法,并在发掘人力极限的过程中,不断降低送餐时限,使得全行业外卖订单单均配送时长在2019年比3年前减少了10分钟[51] ,显著提升了顾客体验,推动外卖成为了劳动密集型和技术密集型模式结合的代表行业。

然而,由于现有共享经济商业模式中服务提供者与平台并没有正式雇佣关系的特殊性,平台对骑手的权益保障和社会福利的重视程度仍有待提高;在现有的商业逻辑、算法规则和考核制度面前,为了完成更多订单以提高收入,一些骑手违反交通法规甚至冒着生命危险“乘风破浪”。据统计,在2017年,仅上海市就发生涉及快递和外卖行业的各类道路交通事故117起,共造成9人死亡,134人受伤[50] 。

当前,激烈的市场竞争环境正推动外卖平台不断改进算法和骑手绩效考核方式。社会在收获良好顾客体验、较低配送成本和极高配送效率的同时,也付出了骑手权益和行人安全降低的代价。面对此外卖骑手困境,我们将围绕其中的问题根源,从平台设计运营和政府监督监管的视角,系统性地提出一系列可以尝试的改进方案。

作为致力于大数据,运筹学,以及人工智能方法在智慧城市领域应用的学者和研究者,我们期望用更加科学的运营流程和算法逻辑,构筑健康,温暖,高效,可持续并且具有社会责任的外卖生态体系。

我们的方案将从平台设计运营和政府监督监管两方面展开——

在平台设计部分,方案将聚焦骑手激励机制、运营流程和算法,以及供需调节机制等内容;

在政府监管部分,方案将聚焦明晰劳资关系、加强资质审核和运营监督、明确平台责任、以及市场竞争与政府干预等内容。由于时间和篇幅所限,本文并没有列举介绍所有可能的改进方向,仅选择我们认为对解决外卖骑手困境最重要并且具有实际可行性的内容。

针对每项的具体内容,我们在“洞察”部分介绍了相关的经济学和管理学原理,或者相关的数据科学、人工智能和优化算法的可能技术实现路线,以供业内人士和专家学者等参考,读者直接跳过该部分内容不会影响对全文的理解。

平台设计

1、骑手激励机制设计

在围绕外卖骑手困境的讨论中,改善骑手的激励和奖惩机制是大家关注的一个焦点。

在基于人工智能算法的外卖配送系统中,从顾客成功下单的时刻起,该系统便会自动化计算最优的订单分派和骑手配送路线,并且预测订单的“预计送达时间”,然后以此考核骑手的“准点率”;一旦订单配送超时,骑手们将面临降低收入甚至淘汰出局的惩罚。

在此过程中,值得重点关注的是,这套“最优”方案只是在给定的历史数据和预设的模型参数下、通过模拟现实得到的“理想值”或者“乐观值”。因此,面对复杂多变的现实场景,外卖骑手的激励机制需要具备容错性和灵活性,帮助外卖骑手抵抗已知或者未知的市场不确定性带来的负面冲击,降低外卖骑手收入的波动,这不仅有助于提升骑手们的福利水平,也将会增强平台的总体运力。

(1)预计送达时间容错

面对无法避免的外卖订单配送超时风险,平台可以考虑引入“超时容错机制”,订单的“预计送达时间”设置和显示为一定的时间段(例如,“17:20~17:25 到达”),并且根据商家的备餐状态和骑手的配送情况动态调整、提前向顾客提醒可能的超时送达,而不是精确到具体的时刻(例如,“预计17:23到达”)甚至故意将顾客端显示的“预计送达时间”设定的短于骑手端。

洞察:从技术层面而言,即便是采用先进的深度学习算法,模型学习到的结果也只是关于“预计送达时间”(Estimated Time of Arrival,简称 ETA)的统计分布,并不能做到对每个样本的预测值都有绝对准确的“信心”[47] 。ETA 参数的区间估计结果(“17:20~17:25”)会比点估计结果(“17:23”)更加具有可信度,因为后者并不能告诉顾客真实的送达时间与它的距离,而前者则可以反映真实的送达时间所处的大致可信范围(confidence interval)。从管理层面而言,区间形式的“预计送达时间”是应对预测算法的误差和外部配送环境的变化的容错策略,体现的是对骑手和顾客负责任的态度。与此相关,平台还可以根据送达时间的区间设置弹性的实际送达时间考核标准:如果实际送达时间在“预计送达时间”前后N分钟,则该笔订单配送记录判定为“正常”,如果实际送达时间超过“预计送达时间”N分钟,则该笔订单配送记录判定为“超时”而纳入超时评估体系;最后,如果实际送达时间早于“预计送达时间”N分钟,则该笔订单配送记录判定为“快速”而纳入高效奖励体系。类似思想已经被外卖平台的ETA预估算法所采纳[47] ,也可以作为超时容错策略体现在骑手激励机制设计中。

(2)弹性的超时奖惩

围绕超时容错机制,平台可以考虑针对骑手“超时率”划分多个区间段、设计更具有弹性的阶梯式超时奖惩规则:超时率被划分成多个区间段,例如,[0%, 5%]、(5%, 10%] 以及10%以上,如果骑手的超时率处于第一个区间段,则骑手的绩效水平不会受到影响;如果骑手的超时率处于第二个区间段,则骑手的绩效水平将受到适当轻微的负面影响;但是,如果骑手的超时率处于更高的区间段,则骑手的绩效水平将受到显著增强的负面影响。

洞察:当前,骑手们的超时率通常不得高于3%,否则,包括骑手、站长甚至区域经理等所有人都将面临绩效的惩罚[51]。那么,从激励机制设计的本质而言,无论是预计送达时间容错机制还是弹性超时奖惩机制,从数学模型的角度,都是在期望构建基于骑手工作绩效(即超时程度或者“超时率”)的非线性激励机制。类似分段阶梯式的非线性惩罚机制在线上多边平台市场中经常出现,例如,在网约车市场,为了杜绝司机的刷单作弊行为,平台会设计阶梯式作弊违规处罚标准:“第一次禁用3天,第二次禁用15天,第三次解除合作;累计非法获利≥1000元时,解除合作永不录用”[39]。在激励骑手们准时配送以最大化日成交金额(Gross Merchandise Volume,简称 GMV)或者日完单量的问题中,订单的送达状态取决于配送过程中环境的不确定性、骑手们的工作业务水平、以及骑手们对承担风险的态度等多方面因素,有一些因素只有骑手们自己知道,而平台并不能完全掌握。那么,采用非线性激励机制是否一定会提升平台整体的运营效率呢?从管理学理论上讲,基于绩效的激励机制包含激励强度的“斜率”(slope of incentive intensity)和激励的“形状”(shape of incentive contract)两个特征:斜率是指激励强度关于绩效的变化率,例如,超时率增加一个单位将会带来的收入惩罚绝对变化值,而形状是指激励关于绩效水平的非线性(或者称凹凸性)。研究表明,高激励斜率有助于改善绩效水平,而强非线性将会增强个体承担风险的偏好;同时,最新的实证结果显示,激励的斜率会影响个体的风险偏好,而激励的形状也会影响绩效水平[11]。因此,构建基于骑手工作绩效的激励机制需要综合上述多方面因素,合理选择激励关于绩效水平的斜率和形状,这样有助于提升配送系统整体的效率。

(3)骑手配送超时互助保险

为了进一步应对外卖订单配送超时风险,以及降低配送超时对骑手收入造成的激烈波动,平台除了在用户端提供配送超时保险和赔偿之外,还可以考虑尝试建立“骑手配送超时互助保险”机制:该保险可由骑手自主选择是否加入,即骑手在选择接单的同时还可以选择是否愿意为这笔订单缴纳较低金额的超时保险费,这笔费用成为骑手之间互助的保险金额池。如果骑手因为任何原因无法按时送达订单,可由金额池向骑手提供经济补偿以降低其收入波动,金额池内的余额最后都退还给骑手。

洞察:在市场经济条件下,保险是一个管理风险的常见工具,例如,在电子商务平台上,保险公司会向第三方卖家推出以商品买家为被保险人的“退换货运费险”,以便降低可能的退换货运费给买家造成的损失[42]。在外卖行业中,67%的骑手家庭人口在3人~5人,四成骑手的爱人选择在家照顾孩子和老人,同时,五成骑手是家庭收入的主要来源,七成骑手月收入在五千元以下,这些数字意味着大多数骑手正面临着来自自身和家庭的双重消费压力[43]。那么,设立“骑手配送超时互助保险”的核心目的在于希望能够建立大数量骑手们互助的保险金额池,缓解超时对个体骑手带来的负面收入冲击,降低个人收入的波动性,最终发挥平滑骑手收入的作用。研究表明,在面对风险时,低收入劳动者或者家庭通常会基于工作和消费等两类经济行为进行调节:一是平滑收入(income smoothing),例如,通过同时兼任多份工作以提高收入来源的多样性和稳定性(在美团平台,35%的骑手拥有包括小生意或者其它外卖平台在内的其它收入来源[43]);二是平滑消费(consumption smoothing),例如,调整自身的劳动力供给水平和使用保险协议[22]。从这两类经济行为可以看出,“骑手配送超时互助保险”可以有助于骑手抵御超时风险,降低收入的波动性,也将会激励骑手提供更好的运力供给。

(4)考核周期延长

为了进一步帮助骑手降低收入的波动性,平台可以考虑延长对骑手的考核周期,将以较短“时间段”(例如,现在平台的冲单奖励活动和考核时间段一般是一天的某个时段),或者以“天”为单位的奖励或者惩罚考核周期适当延长至“星期”甚至“月”,通过实践寻找出最佳的考核周期,以降低骑手对短期高频考核的焦虑,提高系统的整体效率。

洞察:类似基于时间段的冲单奖励看起来有助于满足高峰期时段的旺盛需求,但是,关于共享经济商业模式的实证研究表明,理性的服务提供者为了尽可能获得活动期的高冲单奖励,可能会选择在活动期开始之前策略性的停止工作,以等待高峰期的到来,这种“前瞻”(forward-looking)行为将会导致平台在高峰期到来之前的运力供给出现下降,给整个系统的运行效率造成负面影响[34]。考核周期的延长将有助于平滑骑手在不同时间段内的平均收入,激励骑手们维持稳定的服务质量水平,保障平台总体运力的平稳运行。那么,平台是否应该尽可能延长或者缩短激励机制中的考核周期呢?最近,一份关于产品销售人员薪酬体系设计的研究表明,销售人员的工作绩效将会显著受到考核周期的影响:当平台将激励机制的考核周期缩短时(比如,从“月”度考核调整为“天”度考核),原本优秀的销售人员就表现出了下降的绩效水平[10]。值得关注的是,已有的行为学实验研究和现实商业现象表明,基于考核目标的高频绩效评估会潜在地增加人员的焦虑心理和工作压力,甚至会因为激发人员过于激进而引发欺诈和不道德行为[23][38]。基于上述结论,并结合现实中“外卖小哥在电梯里急哭了”和逆行违章等现象,我们可以总结到,在外卖市场中,虽然商品性质和商业逻辑并不一样,但平台也需要综合骑手们的配送努力程度,配送能力的差异性,以及他们在进行运力供给决策中的前瞻行为等综合因素,非常谨慎地制定出有助于降低骑手收入不确定性和提升平台整体服务能力的最佳的考核周期。

(5)多层次多属性绩效评估

除了上述直接根据“超时率”和“完单量”评估骑手绩效的指标,平台应该建立基于综合服务质量、配送效率和安全保障等多属性的多层次骑手绩效评估体系。当前,系统为骑手设置的积分等级体系是直接基于完单量、准时率或者顾客评价奖励积分[51],可以进一步提升骑手们的安全保障、违章记录、以及公益活动等有助于建设外卖生态体系的多个属性的重要性。

评估体系可以尝试根据政府部门监管法规和平台发展目标为不同评估指标设定优先级,其中,遵守交通安全法规应该成为外卖配送的基本要求。

洞察:在多层次多属性绩效评估体系的设计过程中,在第一层次,考虑到遵守交通安全法规是外卖配送的基本要求,那么,骑手的“违章率”就需要摆在优先级最高的位置,在一定的考核期内,如果骑手的“违章率”超过了阈值,则该骑手将被“一票否决”,不会进入到下一层次的绩效评估;在第二层,维持并且提升市场占用率可能是当前平台运营的关键目标,那么,骑手们的“完单量”可以摆在优先级次高的位置,在对“完单量”合理划分不同等级的奖励区间之后,各骑手再根据实际“完单量”进入相应的评估区间;最后,在特定的基于“完单量”的评估区间内,机制再综合服务质量和顾客评价等属性设定奖励金额。另外,平台可能需要同时实现“违章率”、“日成交单量”和“超时率”等多个关键绩效的管理目标,对此多属性绩效目标导向的决策问题,平台不仅需要考虑到实际绩效水平和管理目标的不确定性,还需要关注多个绩效指标之间的相关性(例如,严格控制“违章率”会减少当前的“日成交单量”)对绩效评估体系的影响[25]。

(6)多向评分反馈

外卖市场主要是由顾客、平台、商家和骑手共同建立起来的生态圈,当前系统采取的是顾客给商家或者骑手的单向评分方式,忽视了骑手们的重要作用。平台可以建立起“多向”评分反馈系统,其中,顾客给商家和骑手分别评分,顾客对商家的菜品健康和口味等进行反馈,对骑手的派送服务进行反馈;骑手也可以自由选择给商家评分,反馈商家出餐及时性等信息;更进一步地,骑手还可以给顾客评分,反馈订单交付难度和顾客接单态度等信息。

与此同时,平台根据商家、顾客和骑手们的权力和义务,并综合天气、路况和其它不可控因素等,设定公平合理的判责系统。

洞察:在实际商业场景中,例如,网约车市场,不仅乘客可以给司机评分,司机也可以向乘客评分。本质上而言,建立多方评分反馈系统(multi-lateral rating systems)的核心目的是增强在线市场中各参与方之间的信任度[12],降低各参与方之间的信息不对称性[17],从而“驱逐”低质量的参与方,并且降低交易成本。为此,平台需要认真思考两个重要问题:一方面,相比于传统的单向评分反馈系统,多向评分反馈系统是否真的会提升市场效率和社会福利?另一方面,由于参与方做出准确的评分是基于自愿且需要付出成本的,在平台没有提供适当奖励的情况下,作为公共产品的用户评分将会供给不足[2];因此,如果采取多向评分反馈系统,平台应该如何激励尽可能多的参与方真实地披露信息并给出可信的评分结果?关于第一个问题,以共享经济商业模式为背景的理论研究表明,相比于仅有顾客的单向评分,顾客和服务提供者之间的双向评分将弱化服务提供者之间的竞争,从而提高市场的均衡价格[17];另外,在一定条件下,双向的评分机制将会提升社会福利[26]。关于第二个问题,平台需要合理设计向各参与方展示彼此评分结果的方式和时间:如果平台在参与方完成评分之后立刻披露结果,那么,相关的被评价方可能在后续采取报复动作,故意压低对方的评分,从而导致顾客评分的“失真”[6];但是,如果平台在双方或者多方都完成评分或者允许评分的时间窗结束之后才披露结果,那么,这种策略将会显著降低评分者进行报复的可能性,并且增加评分的真实性和供给量[13]。

2、运营流程和算法

以上从骑手激励机制方面介绍了外卖平台设计的改进方向,本节将聚焦运营流程和算法设计等社会各界正在热烈讨论的话题。算法本身是中性的,而其蕴含的思想和流程则是由平台的商业逻辑和商业目标决定的,在平台设计中,平台可以进一步让运营流程和算法的目标或者逻辑更加兼顾顾客、骑手和平台等多参与方的目标,提升社会的整体福利水平。

为此,根据通常的外卖配送流程,我们分别提出针对顾客端、骑手端和平台端的运营和算法改进方案,包括餐馆推荐系统、预计送达时间预测算法、派单算法、路径规划算法、算法参数管理、以及基础设施建设等六点建议。

(1)顾客端:餐馆推荐系统

平台可以在实时餐馆推荐系统的设计中采用更多与应用场景相关、反映实时供需情况和骑手空间分布的数据。例如,针对一个商家,如果过去 1个小时的骑手等待时间较短、当前周边分布的骑手较多、店内聚集的正在等待取餐的骑手较少、或者正在准备的订单数量较少等,在其它属性相近的条件下,那么,该商家在推荐排序算法的输出结果中可以被优先推荐。

推荐系统还可以根据实时已有订单的餐馆和骑手位置进行拼单推荐,实现外卖的“顺风车”。例如,如果一位骑手正在顾客周边的商家等待取单,而且预估取餐时间较长,那么,即使该商家不是距离顾客最近或者价格最低,推荐系统也可以在一定程度上提高该商家的推荐权重和优先级。

洞察:在当前实现的推荐系统中,算法输入的应用场景数据至少由三大类组成[44]:一是用户画像,例如,性别、常驻地、价格偏好、食物偏好等;二是食物画像,包含商家、外卖、团单(即团购订单),其中,商家特征包含商家价格、商家好评数、商家地理位置等,外卖特征包含平均价格、配送时间和销量等,团单特征包含适用人数和返购率等;三是场景画像,包含用户当前所在地、时间、定位附近商圈、基于用户的上下文场景信息等。如果基于上述方案改进餐馆推荐系统,系统可以采用基于在线优化(online optimization)和增强学习(reinforcement learning)的算法,实时更新客户端的餐馆推荐结果,最终将餐馆推荐系统打造成调节市场供需平衡状态的重要工具之一。另外,关于实现外卖的“顺风车”,类似思想已经在网约车市场中实现,目的是希望通过将目的地相近或者顺路的订单整合在一起,从而提升配送资源的利用率,其中,需要同时解决订单与骑手的双边匹配问题、以及针对“顺风车”订单的配送费定价问题[19][17]。

(2)顾客端:预计送达时间预测算法

预计送达时间预测算法可以融合来自骑手的手机 GPS 实时定位数据、手机运动传感器移动数据、和安卓操作系统特定应用程序搜集的活动识别数据等多源异质数据集[28],识别骑手在不同时刻所处的活动状态以及状态改变的时间点。这将有助于提升订单交付时间的预测准确性,尤其是和楼层高度、小区内配送和顾客交付相关的时间。同时,为了明确商家和骑手的责任,并且方便顾客对商家和骑手进行公平的评分,平台应该分别预测、显示和评估“商家出餐时间”和“骑手送餐时间”。

洞察:在外卖配送场景中,预计送达时间(ETA)是用户成功下单时刻到骑手将外卖送达到顾客手中的送达时间预测结果,具体可以分解为压单时间(从商家接单到骑手接单)、到店时间(从骑手接单到骑手到店)、取餐时间(从骑手到店到骑手取餐)、送餐时间(从骑手取餐到到达用户)、以及交付时间(从到达用户到完成送达),此过程还包含了出餐时间(从商家接单到商家出餐)[45]。关于骑手送餐时间,一个最大的技术性挑战,也是目前网友们激烈讨论的实际问题是对交付时间的预估,即骑手到达用户附近下车后多久能送到用户手中:一方面,老旧小区没有电梯、或者写字楼难以等到电梯等现实问题给骑手们快速交付订单带来困难;另一方面,在进行交付时间预估时,算法的输入字段较少,重要的维度特征仅包括交付地址(文本数据)、交付点的经纬度、区域、以及城市[48]。对此,如果基于手机GPS实时定位数据、手机运动传感器移动数据(motion sensor data)、以及安卓操作系统ActivityRecognitionClient API搜集的活动识别数据(activity recognition data)等改进ETA预测算法,平台将更清晰地识别骑手运动状态,例如,电动车骑行中、步行中、奔跑中或者原地等待中等,然后采用深度学习方法进行序列建模(sequence modeling),实现对ETA尤其是交付时间的更准确地预测。

(3)骑手端:派单算法

在派单过程中,派单算法应当考虑骑手之间的订单负载均衡,让不同骑手当前累积分配到的订单数量相对比较平均,避免出现个别骑手承载过大的配送任务、而有些骑手被闲置的局面。同时,派单算法还应当考虑骑手在当地区域的熟知程度和配送经验等有助于提升派单效率的多种因素。

洞察:实时派单算法是智能配送系统中的重要组成部分,当前的实时派单问题被描述为以离散马尔可夫决策过程(Markov Decision Process)为核心的动态随机优化问题,其目标是一段时间内的顾客体验(例如,准时率)和骑手效率(例如,单均行驶距离或者单均消耗时间)等指标最优,算法需要计算动态到达的订单分配给骑手的策略、以及每个骑手后续的节点访问顺序(即路径规划,routing optimization)[49]。在对该问题进行合理建模和算法优化之后,派单算法可以实现骑手订单负载均衡(workload balance)和融合骑手当地区域知识和配送经验。对此,建模人员可以通过在目标函数中引入“最大化所有骑手的最小订单负载”(maxmin)或者“最小化所有骑手的最大订单负载”(minmax)的方式进行调整。另外,派单算法引入骑手在当地区域的熟知程度和配送经验等因素,这不仅意味着 ETA 的预测算法需要纳入骑手在当地区域的熟知程度和配送经验等重要指标,也意味着派单算法需要考虑骑手们之间在这两个维度上的差异性。综合以上因素,由多目标优化算法(multi-objective optimization)给出满足多个目标的最佳派单结果[21]。

(4)骑手端:路径规划算法

与派单算法紧密关联的是路径规划算法,算法应该引入与实际路况更为贴切的特征,例如,单行道、限行、机动车道和非机动车道,以及交通管制和交通拥堵等,并且根据实时信息进行调整。

洞察:针对骑手路径规划的问题,平台需要建立基于有向图的实时动态路径规划模型,输入该模型的可行路径集合(set of feasible routes)需要根据离线信息进行缩小[33],例如,许多单行道、限行路线和过街天桥不允许电动车经过的路线就应该作为强约束从集合中剔除;另外,该集合还需要根据实时信息进行调整,例如,出现严重交通拥堵或者临时交通管制的路线也应该被剔除。同时,面对随机的订单需求和配送时长,该问题可以考虑借鉴离线-在线近似动态规划算法[30] (offline-online approximate dynamic programming)或者在线再优化策略[5](online re-optimization strategy)的思想进行求解。

(5)平台端:算法参数管理

平台端对算法参数进行及时审核并且合理设置是解决外卖骑手困境的关键之一,在此应该得到重点关注。这个问题起源于平台在预测订单“预计送达时间”探索实践中的模型迭代过程:在实际的ETA预估场景下,算法的损失函数设计是以“整体的预估结果能够尽量前倾”为目的,而且对于迟到部分会增加数值惩罚[47],这意味着算法在不断“逼迫”骑手缩短实际送达时间,而骑手每一次成功避免超时的历史记录都会让算法“学习”到可能更短的送达时间,即便这个送达时间是骑手通过闯红灯、逆行等违反交通规则甚至冒着生命危险的方式实现的。基于此逻辑,这些历史数据会进一步提高算法对骑手送达时间的“期待”,从而使算法朝着缩短送达时间的方向进行要求和优化。

对此,平台应该通过对实际送达时间等算法的参数进行及时审核和调整以终止上述的恶性循环,也就是赋予算法“底线思维”。遵守交通法规和维护行人安全是不可逾越的底线,是数据预处理环节进行历史数据清洗和校正必须考量的因素,是数学模型中的“硬约束条件”,也是优化算法剔除不可行路径中必须满足的规则。这也意味着订单送达时间应该存在着一个合理的、无法通过算法不断优化而逾越的下界,否则,不管在任何激励机制和评分体系之下,缺乏“底线思维”的算法流程会一直将骑手困在系统之中。

(6)平台端:基础设施建设

针对最后 100米配送问题,平台可以尝试自建或者联合第三方物流公司建设外卖取餐柜[52]。取餐柜的候选位置可以是办公场所、写字楼、医院以及高校,而顾客可以选择线上下单、线下取餐。

洞察:考虑到取餐柜的选址将会影响顾客线上下单、线下取餐(buy-online-pick-up-in-facility)的便利性,平台可以进行两阶段的取餐柜网络设计优化:在第一阶段,平台可以结合各个区域的人口社会统计、经济发展、历史完单、以及配送时长等多维度数据建立机器学习模型和计量经济学模型以预测各区域的潜在需求和建立取餐柜对需求的影响[15];在第二阶段,平台可以建立取餐柜设施选址(facility location optimization)和骑手服务区划分(service region allocation optimization)的多阶段随机规划模型(multi-stage stochastic programming),联合优化取餐柜的位置和骑手的派单服务策略。

除此之外,在需求量较大的办公楼、小区、学校和医院等场所,平台也可以考虑配备专职的终端派送人员,一方面是因为终端配送人员对小区周边和电梯设备更加熟悉,可以帮助降低因骑手对环境陌生而造成的顾客等待时间,另一方面是能够实现对局部区域的订单统一管理和配送、从而避免骑手的重复劳动。

洞察:配备专职终端人员在提升平台整体运营效率的同时也会增加平台的运营成本,需要进行深入的成本-效益分析。分析框架可以将配送过程视为一个排队系统 (queueing system)[32],在指定场所配备专职的终端配送人员将会增加固定人力成本,但是,值得关注的是,根据排队论,配送骑手的每单的平均派送时间和顾客的等待时间等系统的服务质量指标之间存在着强烈非线形的关系,这意味着通过配备专职终端人员以适当降低骑手们在这些场所所花的派送时间可能会带来系统服务质量指标的显著提高,从而使得带来的配送效益可能会高于额外的人力成本。

在未来,平台还可以推广使用机器人和无人机配送。同时,作为互联网公司,平台可以通过在相关核心技术的资本投入和技术积累,转型成为高科技公司。实际上,美团已经开始尝试无人车和无人机的配送:在 2月份疫情期间,外卖平台利用无人配送车为北京市顺义区几个小区的居民做订单配送,截至 9 月初,平台已经累计使用无人车配送了超过6000多用户实际订单,覆盖该站点超过80%的订单需求;目前,平台也在深圳等地进行无人机的运营测试[53]。

洞察:在设计无人车辅助的配送系统中,面对无人车配送和骑手配送的两种模式,考虑到无人车的在成本方面的优势和在灵活性方面的不足,平台可以基于实际配送场景、市场供需状态、以及交通路况,采用马尔可夫决策过程联合优化无人车和骑手之间的分配比例、以及无人车和骑手的配送路线[29]。

3。 供需调节机制

在实际的运营中,外卖平台可以尝试对配送价格进行调整以调节市场供需。平台可以根据配送距离和配送时段等诸多因素合理设计基础的派送价格和骑手端补贴;另外,平台也可以针对突变的供需情况,实时调整骑手的配送费用来缓解供需不平衡的问题[46][36]。

其实,作为企业收益管理的重要工具,动态定价已经在多个行业得到广泛使用,包括在上个世纪 80 年代开始得到采纳的航空业、90 年代开始得到采纳的酒店业和租车业[31]、以及当前新兴的共享出行行业[3]。

在外卖行业,平台面临的市场供需不协调的问题更加突出,而且市场供需状态随时间变化剧烈。采取不同形式的配送价格可以区分顾客对等待时间的实际需求和时间敏感性,这对提高和使用供需弹性,缓解供不应求带来的负面影响具有一定积极作用;然而,基于配送价格的动态定价机制并不能解决所有问题,无论是在现实生活还是学术研究中仍然存在争议,这依赖于平台对该策略的价值进行更加深入的探究。

(1)基于区域和时间段的时空动态定价

在调节市场供需平衡状态的过程中,平台可以针对每笔订单的配送费实行基于配送区域、下单时间或者送达时间的动态定价,并且对愿意等待的顾客提供愿等打折。

洞察:基于区域和时间段的时空动态定价(dynamic & surging pricing)通常可以分为“乘积溢价”(multiplicative surge)和“加和溢价”(additive surge)两类:在特定区域和时间段内,前者是指在基础价格上乘以一定倍数(例如,1.5倍),美国的网约车平台Uber早期就是使用该类溢价策略;而后者是指在基础价格上加上与距离无关的常数(例如,10元),这是 Uber 平台当前采用的最新溢价策略。研究表明,在供需动态变化的环境下,相比于乘积溢价策略,加和溢价策略是激励相容 (incentive-compatible) 的定价机制[14],这为外卖平台设计基于配送费的实时动态定价策略提供了新的方向。值得提醒的是,实时动态定价策略在社会各界中仍然存在争议,理论研究结果显示,在共享出行市场的背景下,理性的乘客和司机会策略性地等待更合适的价格或者收入,如果市场状态比较平稳,那么,平台没有必要采用实时动态定价策略,尤其是该策略可能造成乘客、司机、监管者之间对立的局面[9]。

(2) 顾客灵活充值账户

为了弥补实时动态定价在区分顾客对等待时间的实际需求和时间敏感性方面的不足,平台可以建立灵活的用户充值账户:在高峰期时段,如果需要外卖尽快送到,顾客可以向个人在平台上的账户充入额外的金额,这些资金并不会流入骑手或者平台,而是作为用户的充值余额,可以在低峰期时段点餐使用。

洞察:顾客在高峰时段的充值行为将传递出其对派送的等待时间比较敏感的信号,作为系统派单算法的依据,并且,顾客在低峰期使用账户余额订餐,可以激发低峰时段的整体需求,充分利用低峰期时段闲散的备餐和配送资源,发挥平滑市场需求的作用。针对网约车市场的研究结果表明,在一定条件下,合理设计用户充值账户机制 (integrated reward scheme with surge pricing) 可以实现多方共赢,提升顾客、司机和平台的整体社会福利[37]。

(3)增加兼职和众包骑手

平台提升兼职和众包骑手的运力占比有助于提高运力调整的空间和弹性,从而更有效的调节市场的供需平衡状态。

洞察:平台的骑手分为专送全职骑手和众包兼职骑手,前者的工作时间固定并且接受系统派单,后者灵活决定工作时间并且可以有限次拒绝派单[51]。为了提升整体的运力供给,尤其是满足高峰期时段的配送需求,平台通常会采用现金奖励的方式补贴骑手。实证研究表明,在网约车市场中,平台补贴将会从劳动者是否选择工作和工作时长两个维度影响劳动力供给,而且,兼职劳动者的收入供给弹性 (supply elasticity) 更高[24]。这意味着外卖平台需要更加严密地研究骑手们的运力供给行为,分析骑手们对期望收入水平发生变化而进行的运力供给调整,然后合理设计平台上全职骑手和兼职骑手的比例,并精准地向骑手、尤其是兼职骑手提供补贴奖励。

4。 政府监管

精准的政府监管对外卖行业实现可持续健康发展至关重要。深入而全面地理解平台的商业逻辑和运营流程有助于制定高效精准的监管措施,这不仅依赖于平台向监管者真实而全面地披露公司运营相关的信息,也依赖于监管部门联合第三方专业研究机构共同完成对信息的分析和总结[8]。基于全面而系统的专业分析之后,监管者再对平台和骑手的劳资关系、运营过程中的资质审核和监管、以及平台责任以法律法规形式进行统一规范。

(1)明晰劳资关系

相关部门需要加快出台法律法规,明晰包括外卖骑手在内的自由职业者与共享经济/零工经济平台之间的劳资关系,对全职骑手与兼职骑手的法律地位进行清晰的分类,界定相应的权利和义务[16]。

洞察:针对相关的劳资关系,国家发展改革委于2020年7月14日发布文件要求,强化灵活就业劳动权益保障,探索适应跨平台、多雇主间灵活就业的权益保障、社会保障等政策[40]。作为参考,2019年9月18日,美国加州正式签署了AB5法案[7],并于2020年1月1日正式生效。该法案要求将临时合同工(例如,网约车司机)纳入雇主的正式受雇员工,这意味着相关企业的业务成本(例如,最低工资、保险和员工福利等)将大幅增加,并将影响公司的员工管理机制和定价机制。实际上,为了满足该法案的要求,从2020年7月9日开始,Uber平台已经开始允许司机自己根据服务时间和距离设定价格[27]。目前,围绕AB5法案、以及自由职业者与平台之间的劳资关系仍然存在非常大的争议,一部分学者建议创立一个新的、介于雇员和合同工之间的第三类工作类别,该类别将保留自由职业者的一部分工作灵活度,同时,赋予他们部分全职雇员可以享受到的福利待遇[16][35]。

(2)加强资质审核和运营监督

交管、人社、应急管理等相关部门应当督促和加强对平台和骑手的资质审核和安全培训。在劳动者申请加入平台过程中,平台需要对骑手电动车的准入标准进行统一登记管理;与此同时,加强对平台运营流程的监督,比如,可以借助骑手 APP 的渠道对平台的配送路径规划等算法进行监管审查,严禁对骑手提供违反交通规则(例如,逆行)的推荐路线;相关部门还可以对平台上骑手每天的连续配送时长设置上限并进行合理监督,避免出现因为骑手疲劳工作而造成的交通事故。

(3)明确平台责任

在对涉及快递和外卖行业的道路交通安全进行监管的过程中,监管部门应该把平台所属骑手发生的交通事故和违章次数、以及相应后果的严重程度作为对平台重要的监管指标,按月度或者季度等进行考核和追责,从而督促平台和骑手共同维护配送安全。

针对已经发生的交通事故,已有的法院判决为相关的责任划分提供了具有现实意义的指导。近日,关于浙江省湖州市吴兴区的外卖骑手撞伤行人一案,法院最后宣判,外卖骑手虽然没有与平台签订法律劳务合同,但对外是以“平台网上订餐配送”的名义为客户提供服务,且在提供配送服务时受平台管理制度的约束,报酬由平台发放,因此,无论是否与公司签合同,在其接受配送任务后均与配送平台建立了雇佣关系,在送餐中发生事故,作为雇主的公司应承担赔偿责任[41]。这一结果无疑明确了外卖平台必须加快运营管理流程的调整,以保障骑手安全和行人安全。

(4)市场竞争与政府干预

监管部门需要在遵循平台竞争规律和市场调节作用的条件下制定提升社会福利的监管法规。在市场经济环境下,平台之间的自由竞争将会影响平台选择最优的骑手激励机制以及运营流程和算法。但是,竞争形成的市场结果并不一定能够实现社会各参与方的福利最大化,可能陷入“囚徒困境”的局面。

例如,如果一个平台没有严格遵守法规制度,漠视骑手权益,那么,为了维持甚至扩大市场份额和利润,其竞争对手很有可能也不会选择严格遵守法规制度和提升骑手权益。为此,监管部门应该充分考虑多平台竞争的市场环境,以问题为导向制定相关法规,一视同仁地对所有平台进行严格的监管。

洞察:平台之间的市场竞争虽然会有助于提升市场效率,但在一定的情况下,也有可能出现市场失灵,竞争无法达到最优的纳什均衡(Nash equilibrium)。对此,监管者可以考虑根据博弈论(game theory)和机制设计(mechanism design)的理论和工具来刻画骑手、顾客、商家和多个平台之间的交互行为,并研究市场中的平台竞争结果[1]。特别是针对竞争的外部性(externalities)可能导致出现的市场失灵的情况,监管部门需要考虑相应的监管制度规则以引导相互竞争的平台向更有利于提升社会福利的方向发展。

总结

作为致力于大数据,运筹学,以及人工智能方法在智慧城市领域应用的学者和研究者,我们从平台设计运营和政府监督监管两方面为解决外卖骑手困境提供了可能的解决方案,探讨了骑手激励机制、运营流程和算法、供需调节机制等平台可以采取的运营策略,并分析了明晰劳资关系、加强资质审核和运营监督、明确平台责任、以及市场竞争与政府干预等监管者面临的挑战。

构筑健康、温暖、高效、可持续并且具有社会责任的外卖生态体系,需要我们从社会伦理、法律制度以及经济学和管理学原理出发,融合大数据技术和人工智能算法等工具,充分满足不同目标下多参与方的核心利益。

最终,让每一方都释放出最大的善意以实现共赢,只有这样才能提升社会整体的福利水平,让人们真正享受到科技为生活带来的便利。

作者简介:

王海:清华大学学士,麻省理工学院运筹学博士,现为新加坡管理大学决策分析方向助理教授,美国卡内基梅隆大学信息系统与公共政策学院访问教授;研究方向为运筹学,大数据,优化算法,以及人工智能的方法论及其在智慧城市场景的应用;主要领域包括智能交通,共享经济,智慧物流,以及智慧医疗等。个人主页,http://wang-hai.net/

孙昊:华中科技大学学士,清华大学管理科学与工程博士,现为香港大学经济及工商管理学院博士后;研究方向为银行与金融中介,在线市场设计,统计学习方法与应用;主要领域包括金融科技与创新,共享经济等。

参考文献:

[1] Ahmadinejad, AmirMahdi, Hamid Nazerzadeh, Amin Saberi, Nolan Skochdopole, and Kane Sweeney。 (2019)。 Competition in ride-hailing markets。 Available at SSRN 3461119。

[2] Avery, Christopher, Paul Resnick, and Richard Zeckhauser。 (1999)。 The market for evaluations。 American Economic Review , 89(3),564-584。

[3] Bai, Jiaru, Kut C。 So, Christopher S。 Tang, Xiqun (Michael) Chen, and Hai Wang。 (2019)。 Coordinating supply and demand on an on-demand service platform with impatient customers。 Manufacturing & Service Operations Management , 21(3), 556-570。

[4] Basu, Amiya K。, Rajiv Lal, V。 Srinivasan, and Richard Staelin。 (1985)。 Salesforce compensation plans: An agency theoretic perspective。 Marketing Science , 4(4), 267-291。

[5] Bertsimas, Dimitris, Patrick Jaillet, and Sébastien Martin。 (2019)。 Online vehicle routing: The edge of optimization in large-scale applications。 Operations Research , 67(1), 143-162。

[6] Bolton, Gary, Ben Greiner, and Axel Ockenfels。 (2013)。 Engineering trust: reciprocity in the production of reputation information。 Management Science , 59(2), 265-285。

[7] California Legislative Information。 Assembly Bill No。 5。 September 18, 2019。 https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=201920200AB5。

[8] Calo, Ryan, and Alex Rosenblat。 (2017)。 The taking economy: Uber, information, and power。 Columbia Law Review , 117, 1623。

[9] Chen, Yiwei, and Ming Hu。 (2020)。 Pricing and matching with forward-looking buyers and sellers。 Manufacturing & Service Operations Management , 22(4), 717-734。

[10] Chung, Doug J。, Das Narayandas, and Dongkyu Chang。 (2020) The effects of quota frequency: Sales performance and product focus。 Management Science 。

[11] de Figueiredo Jr, Rui JP, Evan Rawley, and Orie Shelef。 (2019)。 Bad bets: Nonlinear incentives, risk, and performance。 Strategic Management Journal 。 https://doi.org/10.1002/smj.3111

[12] Einav, Liran, Chiara Farronato, and Jonathan Levin。 (2016)。 Peer-to-peer markets。 Annual Review of Economics , 8, 615-635。

[13] Fradkin, Andrey, Elena Grewal, and David Holtz。 (2020)。 Reciprocity in two-sided reputation systems: Evidence from an experiment on Airbnb。 Working Paper, MIT Sloan School of Management。 https://andreyfradkin。 com。

[14] Garg, Nikhil, and Hamid Nazerzadeh。 (2019)。 Driver surge pricing。 arXiv preprint arXiv:1905.07544。

[15] Glaeser, Chloe Kim, Marshall Fisher, and Xuanming Su。 (2019)。 Optimal Retail Location: Empirical Methodology and Application to Practice: Finalist–2017 M&SOM Practice-Based Research Competition。 Manufacturing & Service Operations Management , 21(1), 86-102。

[16] Hagiu, Andrei, and Julian Wright。 (2019)。 The status of workers and platforms in the sharing economy。 Journal of Economics &Management Strategy , 28(1), 97-108。

[17] Ke, Jintao, Hai Yang, Xinwei Li, Hai Wang, and Jieping Ye。 (2020)。 Pricing and equilibrium in on-demand ride-pooling markets。 Transportation Research Part B: Methodological 139: 411-431。

[18] Ke, T。 Tony, Baojun Jiang, and Monic Sun。 (2017)。 Peer-to-peer markets with bilateral ratings。 In MIT Sloan Research Paper No。 5236-17; NET Institute Working Paper No (pp。 17-101)。

[19] Li, Ruijie, Yu (Marco) Nie, and Xiaobo Liu。 (2020) Pricing carpool rides based on schedule displacement。 Transportation Science 54(4):1134-1152。

[20] Liu, Sheng, Long He, and Zuo-Jun Max Shen。 (2018)。 On-time last mile delivery: Order assignment with travel time predictors。 Management Science 。

[21] Lyu, Guodong, Wang Chi Cheung, Chung-Piaw Teo, and Hai Wang。 (2019)。 Multi-objective online ride-matching。 Working paper, National University of Singapore。 Available at SSRN 3356823。

[22] Morduch, Jonathan。 (1995)。 Income smoothing and consumption smoothing。 Journal of Economic Perspectives , 9(3), 103-114。

[23] Schweitzer, Maurice E。, Lisa Ordóez, and Bambi Douma。 (2004)。 Goal setting as a motivator of unethical behavior。 Academy of Management Journal , 47(3), 422-432。

[24] Sun, Hao, Hai Wang, and Zhixi Wan。 (2019)。 Model and analysis of labor supply for ride-sharing platforms in the presence of sample self-selection and endogeneity。 Transportation Research Part B: Methodological , 125, 76-93。

[25] Tsetlin, Ilia, and Robert L。 Winkler。 (2007)。 Decision making with multiattribute performance targets: The impact of changes in performance and target distributions。 Operations Research , 55(2), 226-233。

[26] Tunc, Murat M。, Huseyin Cavusoglu, and Srinivasan Raghunathan。 (2019)。 Two-sided adverse selection and bilateral reviews in sharing economy。 Available at SSRN 3499979。

[27] Uber Blog。 California drivers: Set your own fares when you drive with Uber。 June 25, 2020。

https://www.uber.com/blog/california/set-your-fares/。

[28] Uber Engineering。 How trip inferences and machine learning optimize delivery times on Uber Eats。 (2018)。 https://eng.uber.com/uber-eats-trip-optimization/。

[29] Ulmer, Marlin W。, and Barrett W。 Thomas。 (2018)。 Same-day delivery with heterogeneous fleets of drones and vehicles。 Networks ,72(4), 475-505。

[30] Ulmer, Marlin W。 Justin C。 Goodson, Dirk C。 Mattfeld, and Marco Hennig。 (2019)。 Offline–online approximate dynamic programming for dynamic vehicle routing with stochastic requests。 Transportation Science , 53(1), 185-202。

[31] Wall Street Journal。 (2015)。 Now prices can change from minute to minute。 December 14, 2015.https://www.wsj.com/articles/now-prices-can-change-from-minute-to-minute-1450057990。

[32] Wang, Hai, and Amedeo Odoni。 (2016)。 Approximating the performance of a “last mile” transportation system。 Transportation Science , 50(2), 659-675。

[33] Wang, Hai。 (2019)。 Routing and scheduling for a last-mile transportation system。 Transportation Science , 53(1), 131-147。

[34] Wang, Hai, and Hao Sun。 (2020)。 Peak-hour incentive design with strategic driver behavior。 Singapore Management University, working paper。

[35] Wang, Hai, and Hao Sun。 (2020)。 The optimal labor supply flexibility on ride-sharing platforms。 Singapore Management University, working paper。

[36] Wang, Hai, and Hai Yang。 (2019)。 Ridesourcing systems: A framework and review。 Transportation Research Part B: Methodological , 129, 122-155。

[37] Yang, Hai, Chaoyi Shao, Hai Wang, and Jieping Ye。 (2020)。 Integrated reward scheme and surge pricing in a ridesourcing market。 Transportation Research Part B: Methodological , 134, 126-142。

[38] Zoltners Andris A, PK Sinha, and Sally E。 Lorimer。 (2016)。 Wells Fargo and the slippery slope of sales incentives。 Harvard Business Review 。 (September), https://hbr.org/2016/09/wells-fargo-and-the-slippery-slope-of -sales-incentives。

[39] 滴滴出行。 滴滴专车司机作弊违规处罚标准。 2019 年 04 月 24 日。 https://www.eycen.com/post/545.html。

[40] 发展改革委网站。 关于支持新业态新模式健康发展 激活消费市场带动扩大就业的意见。 2020 年 07 月 14 日。 https://www.ndrc.gov.cn/xxgk/zcfb/tz/202007/t20200715_1233793_ext.html。

[41] 金融界。 浙江湖州外卖骑手撞伤行人,法院判未签劳动合同的平台需担责。 2020 年 09 年 15 日。

https://baijiahao.baidu.com/s?id=1677901965178599201&wfr=spider&for=pc。

[42] 京东。 什么是退换货运费险?2019 年 12 月 10 日。 https://help.jd.com/user/issue/430-499.html

[43] 美团研究院。 新时代 新青年:2018 年外卖骑手群体研究报告。 2019 年 1 月 17 日。

https://s3plus.meituan.net/v1/mss_531b5a3906864f438395a28a5baec011/official website/c21d0443-decf-41d5-9813-ef8eaa6516d0。

[44] 美团技术团队。 深度学习在美团推荐平台排序中的运用。 2017 年 07 月 28 日。 https://tech.meituan.com/2017/07/28/dl.html。

[45] 美团技术团队。 即时配送的 ETA 问题之亿级样本特征构造实践。 2017 年 11 月 24 日。

https://tech.meituan.com/2017/11/24/gbdt.html。

[46] 美团技术团队。 美团外卖骑手背后的 AI 技术。 2018 年 03 月 29 日。 https://tech.meituan.com/2018/03/29/herenqing-ai-con.html。

[47] 美团技术团队。 深度学习在美团配送 ETA 预估中的探索与实践。 2019 年 02 月 21 日。

https://tech.meituan.com/2019/02/21/meituan-delivery-eta-estimation-in-the-practice-of-deeplearning.html。

[48] 美团技术团队。 配送交付时间轻量级预估实践。 2019 年 10 月 10 日。 https://tech.meituan.com/2019/10/10/distribution-time-prediction-practice.html。

[49] 美团技术团队。 美团智能配送系统的运筹优化实战。 2020 年 02 月 20 日。 https://tech.meituan.com/2020/02/20/meituan-delivery-operations-research.html。

[50] 青年报。 快递、外卖行业交通事故频发 去年 117 起事故致 9 死 134 伤。 2018 年 02 月 10 日。

http://app.why.com.cn/epaper/webpc/qnb/html/2018-02/10/content_51905.html。

[51] 人物。 外卖骑手, 困在系统里。 2020 年 9 月 8 日。 https://mp.weixin.qq.com/s/Mes1RqIOdp48CMw4pXTwXw。

[52] 搜狐网。 高校为什么要布局智能外卖柜?对学校有什么好处。 2019 年 6 月 21 日。

https://www.sohu.com/a/322101528_120167191。

[53] 中国日报中文网。 美团夏华夏:不断深化现实物理场景应用 美团 AI 助力产业智能化转型。 2020 年 9 月 8 日。http://cn.chinadaily.com.cn/a/202009/08/WS5f56f6faa310084978423e53.html。


如何用JAVA设计一个亿级消息量的 IM 系统

技术交流大兴 发表了文章 • 0 个评论 • 45 次浏览 • 2020-09-11 11:01 • 来自相关话题

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此... ...查看全部

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此时,一个能够快速迭代、方便扩展的系统才是一个好的系统。

 

IM核心概念

用户:系统的使用者

消息:是指用户之间的沟通内容。通常在IM系统中,消息会有以下几类:文本消息、表情消息、图片消息、视频消息、文件消息等等

会话:通常指两个用户之间因聊天而建立起的关联

群:通常指多个用户之间因聊天而建立起的关联

终端:指用户使用IM系统的机器。通常有Android端、iOS端、Web端等等

未读数:指用户还没读的消息数量

用户状态:指用户当前是在线、离线还是挂起等状态

关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等。这里需要注意与会话的区别,用户只有在发起聊天时才产生会话,但关系并不需要聊天才能建立。对于关系链的存储,可以使用图数据库(Neo4j等等),可以很自然地表达现实世界中的关系,易于建模

单聊:一对一聊天

群聊:多人聊天

客服:在电商领域,通常需要对用户提供售前咨询、售后咨询等服务。这时,就需要引入客服来处理用户的咨询

消息分流:在电商领域,一个店铺通常会有多个客服,此时决定用户的咨询由哪个客服来处理就是消息分流。通常消息分流会根据一系列规则来确定消息会分流给哪个客服,例如客服是否在线(客服不在线的话需要重新分流给另一个客服)、该消息是售前咨询还是售后咨询、当前客服的繁忙程度等等

信箱:本文的信箱我们指一个Timeline、一个收发消息的队列

 

读扩散 vs 写扩散

读扩散

我们先来看看读扩散。如上图所示,A与每个聊天的人跟群都有一个信箱(有些博文会叫Timeline),A在查看聊天信息的时候需要读取所有有新消息的信箱。这里的读扩散需要注意与Feeds系统的区别,在Feeds系统中,每个人都有一个写信箱,写只需要往自己的写信箱里写一次就好了,读需要从所有关注的人的写信箱里读。但IM系统里的读扩散通常是每两个相关联的人就有一个信箱,或者每个群一个信箱。

读扩散的优点:

写操作(发消息)很轻量,不管是单聊还是群聊,只需要往相应的信箱写一次就好了

每一个信箱天然就是两个人的聊天记录,可以方便查看聊天记录跟进行聊天记录的搜索

读扩散的缺点:

读操作(读消息)很重

写扩散

接下来看看写扩散。

e38c316470c48ab4e7f8492ec20398672f5e14.jpg.png

在写扩散中,每个人都只从自己的信箱里读取消息,但写(发消息)的时候,对于单聊跟群聊处理如下:

单聊:往自己的信箱跟对方的信箱都写一份消息,同时,如果需要查看两个人的聊天历史记录的话还需要再写一份(当然,如果从个人信箱也能回溯出两个人的所有聊天记录,但这样效率会很低)。

群聊:需要往所有的群成员的信箱都写一份消息,同时,如果需要查看群的聊天历史记录的话还需要再写一份。可以看出,写扩散对于群聊来说大大地放大了写操作。

写扩散优点:

读操作很轻量

可以很方便地做消息的多终端同步

写扩散缺点:

写操作很重,尤其是对于群聊来说

注意,在Feeds系统中:

写扩散也叫:Push、Fan-out或者Write-fanout

读扩散也叫:Pull、Fan-in或者Read-fanout

 

唯一ID设计

通常情况下,ID的设计主要有以下几大类:

UUID

基于Snowflake的ID生成方式

基于申请DB步长的生成方式

基于Redis或者DB的自增ID生成方式

特殊的规则生成唯一ID

具体的实现方法跟优缺点可以参考之前的一篇博文:分布式唯一 ID 解析

在IM系统中需要唯一Id的地方主要是:

会话ID

消息ID

 

消息ID

我们来看看在设计消息ID时需要考虑的三个问题。

 

消息ID不递增可以吗

我们先看看不递增的话会怎样:

使用字符串,浪费存储空间,而且不能利用存储引擎的特性让相邻的消息存储在一起,降低消息的写入跟读取性能

使用数字,但数字随机,也不能利用存储引擎的特性让相邻的消息存储在一起,会加大随机IO,降低性能;而且随机的ID不好保证ID的唯一性

因此,消息ID最好是递增的。

 

全局递增 vs 用户级别递增 vs 会话级别递增

全局递增:指消息ID在整个IM系统随着时间的推移是递增的。全局递增的话一般可以使用Snowflake(当然,Snowflake也只是worker级别的递增)。此时,如果你的系统是读扩散的话为了防止消息丢失,那每一条消息就只能带上上一条消息的ID,前端根据上一条消息判断是否有丢失消息,有消息丢失的话需要重新拉一次。

用户级别递增:指消息ID只保证在单个用户中是递增的,不同用户之间不影响并且可能重复。典型代表:微信。如果是写扩散系统的话信箱时间线ID跟消息ID需要分开设计,信箱时间线ID用户级别递增,消息ID全局递增。如果是读扩散系统的话感觉使用用户级别递增必要性不是很大。

会话级别递增:指消息ID只保证在单个会话中是递增的,不同会话之间不影响并且可能重复。典型代表:QQ。

 

连续递增 vs 单调递增

连续递增是指ID按 1,2,3...n 的方式生成;而单调递增是指只要保证后面生成的ID比前面生成的ID大就可以了,不需要连续。

据我所知,QQ的消息ID就是在会话级别使用的连续递增,这样的好处是,如果丢失了消息,当下一条消息来的时候发现ID不连续就会去请求服务器,避免丢失消息。此时,可能有人会想,我不能用定时拉的方式看有没有消息丢失吗?当然不能,因为消息ID只在会话级别连续递增的话那如果一个人有上千个会话,那得拉多少次啊,服务器肯定是抗不住的。

对于读扩散来说,消息ID使用连续递增就是一种不错的方式了。如果使用单调递增的话当前消息需要带上前一条消息的ID(即聊天消息组成一个链表),这样,才能判断消息是否丢失。

总结一下就是:

写扩散:信箱时间线ID使用用户级别递增,消息ID全局递增,此时只要保证单调递增就可以了

读扩散:消息ID可以使用会话级别递增并且最好是连续递增

 

会话ID

我们来看看设计会话ID需要注意的问题:

其中,会话ID有种比较简单的生成方式(特殊的规则生成唯一ID):拼接 from_user_id 跟 to_user_id:

如果 from_user_id 跟 to_user_id 都是32位整形数据的话可以很方便地用位运算拼接成一个64位的会话ID,即: conversation_id = ${from_user_id} << 32 | ${to_user_id} (在拼接前需要确保值比较小的用户ID是 from_user_id,这样任意两个用户发起会话可以很方便地知道会话ID)

如果from_user_id 跟 to_user_id 都是64位整形数据的话那就只能拼接成一个字符串了,拼接成字符串的话就比较伤了,浪费存储空间性能又不好。

前东家就是使用的上面第1种方式,第1种方式有个硬伤:随着业务在全球的扩展,32位的用户ID如果不够用需要扩展到64位的话那就需要大刀阔斧地改了。32位整形ID看起来能够容纳21亿个用户,但通常我们为了防止别人知道真实的用户数据,使用的ID通常不是连续的,这时,32位的用户ID就完全不够用了。因此,该设计完全依赖于用户ID,不是一种可取的设计方式。

因此,会话ID的设计可以使用全局递增的方式,加一个映射表,保存from_user_id、to_user_id跟conversation_id的关系。

 

推模式 vs 拉模式 vs 推拉结合模式

在IM系统中,新消息的获取通常会有三种可能的做法:

推模式:有新消息时服务器主动推给所有端(iOS、Android、PC等)

拉模式:由前端主动发起拉取消息的请求,为了保证消息的实时性,一般采用推模式,拉模式一般用于获取历史消息

推拉结合模式:有新消息时服务器会先推一个有新消息的通知给前端,前端接收到通知后就向服务器拉取消息

推模式简化图如下:

04cfb696364aeffcfdd83382d29a45bfefb11a.jpg.png

如上图所示,正常情况下,用户发的消息经过服务器存储等操作后会推给接收方的所有端。但推是有可能会丢失的,最常见的情况就是用户可能会伪在线(是指如果推送服务基于长连接,而长连接可能已经断开,即用户已经掉线,但一般需要经过一个心跳周期后服务器才能感知到,这时服务器会错误地以为用户还在线;伪在线是本人自己想的一个概念,没想到合适的词来解释)。因此如果单纯使用推模式的话,是有可能会丢失消息的。

推拉结合模式简化图如下:

6760f5926b20f8763ec72480c1328e859795dd.jpg.png

可以使用推拉结合模式解决推模式可能会丢消息的问题。在用户发新消息时服务器推送一个通知,然后前端请求最新消息列表,为了防止有消息丢失,可以再每隔一段时间主动请求一次。可以看出,使用推拉结合模式最好是用写扩散,因为写扩散只需要拉一条时间线的个人信箱就好了,而读扩散有N条时间线(每个信箱一条),如果也定时拉取的话性能会很差。

 

业界解决方案

前面了解了IM系统的常见设计问题,接下来我们再看看业界是怎么设计IM系统的。研究业界的主流方案有助于我们深入理解IM系统的设计。以下研究都是基于网上已经公开的资料,不一定正确,大家仅作参考就好了。

微信

虽然微信很多基础框架都是自研,但这并不妨碍我们理解微信的架构设计。从微信公开的《从0到1:微信后台系统的演进之路》这篇文章可以看出,微信采用的主要是:写扩散 + 推拉结合。由于群聊使用的也是写扩散,而写扩散很消耗资源,因此微信群有人数上限(目前是500)。所以这也是写扩散的一个明显缺点,如果需要万人群就比较难了。

从文中还可以看出,微信采用了多数据中心架构:

 62f39582378e16672d3132062133f47142ce8e.jpg.png

 


微信每个数据中心都是自治的,每个数据中心都有全量的数据,数据中心间通过自研的消息队列来同步数据。为了保证数据的一致性,每个用户都只属于一个数据中心,只能在自己所属的数据中心进行数据读写,如果用户连了其它数据中心则会自动引导用户接入所属的数据中心。而如果需要访问其它用户的数据那只需要访问自己所属的数据中心就可以了。同时,微信使用了三园区容灾的架构,使用Paxos来保证数据的一致性。

从微信公开的《万亿级调用系统:微信序列号生成器架构设计及演变》这篇文章可以看出,微信的ID设计采用的是:基于申请DB步长的生成方式 + 用户级别递增。如下图所示:

1.png

微信的序列号生成器由仲裁服务生成路由表(路由表保存了uid号段到AllocSvr的全映射),路由表会同步到AllocSvr跟Client。如果AllocSvr宕机的话会由仲裁服务重新调度uid号段到其它AllocSvr。

 

钉钉

钉钉公开的资料不多,从《阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处》这篇文章我们只能知道,钉钉最开始使用的是写扩散模型,为了支持万人群,后来貌似优化成了读扩散。

但聊到阿里的IM系统,不得不提的是阿里自研的Tablestore。一般情况下,IM系统都会有一个自增ID生成系统,但Tablestore创造性地引入了主键列自增,即把ID的生成整合到了DB层,支持了用户级别递增(传统MySQL等DB只能支持表级自增,即全局自增)。具体可以参考:《如何优化高并发IM系统架构》

 

Twitter

什么?Twitter不是Feeds系统吗?这篇文章不是讨论IM的吗?是的,Twitter是Feeds系统,但Feeds系统跟IM系统其实有很多设计上的共性,研究下Feeds系统有助于我们在设计IM系统时进行参考。再说了,研究下Feeds系统也没有坏处,扩展下技术视野嘛。

Twitter的自增ID设计估计大家都耳熟能详了,即大名鼎鼎的Snowflake,因此ID是全局递增的。


从这个视频分享《How We Learned to Stop Worrying and Love Fan-In at Twitter》可以看出,Twitter一开始使用的是写扩散模型,Fanout Service负责扩散写到Timelines Cache(使用了Redis),Timeline Service负责读取Timeline数据,然后由API Services返回给用户。

但由于写扩散对于大V来说写的消耗太大,因此后面Twitter又使用了写扩散跟读扩散结合的方式。如下图所示:



 2.png

对于粉丝数不多的用户如果发Twitter使用的还是写扩散模型,由Timeline Mixer服务将用户的Timeline、大V的写Timeline跟系统推荐等内容整合起来,最后再由API Services返回给用户。

 

58到家

58到家实现了一个通用的实时消息平台:

3.png

可以看出,msg-server保存了应用跟MQ主题之间的对应关系,msg-server根据这个配置将消息推到不同的MQ队列,具体的应用来消费就可以了。因此,新增一个应用只需要修改配置就可以了。

58到家为了保证消息投递的可靠性,还引入了确认机制:消息平台收到消息先落地数据库,接收方收到后应用层ACK再删除。使用确认机制最好是只能单点登录,如果多端能够同时登录的话那就比较麻烦了,因为需要所有端都确认收到消息后才能删除。

看到这里,估计大家已经明白了,设计一个IM系统很有挑战性。我们还是继续来看设计一个IM系统需要考虑的问题吧。

 

IM需要解决的问题

如何保证消息的实时性

在通信协议的选择上,我们主要有以下几个选择:

使用TCP Socket通信,自己设计协议:58到家等等

使用UDP Socket通信:QQ等等

使用HTTP长轮循:微信网页版等等

不管使用哪种方式,我们都能够做到消息的实时通知。但影响我们消息实时性的可能会在我们处理消息的方式上。例如:假如我们推送的时候使用MQ去处理并推送一个万人群的消息,推送一个人需要2ms,那么推完一万人需要20s,那么后面的消息就阻塞了20s。如果我们需要在10ms内推完,那么我们推送的并发度应该是:人数:10000 / (推送总时长:10 / 单个人推送时长:2) = 2000

因此,我们在选择具体的实现方案的时候一定要评估好我们系统的吞吐量,系统的每一个环节都要进行评估压测。只有把每一个环节的吞吐量评估好了,才能保证消息推送的实时性。

如何保证消息时序

以下情况下消息可能会乱序:

发送消息如果使用的不是长连接,而是使用HTTP的话可能会出现乱序。因为后端一般是集群部署,使用HTTP的话请求可能会打到不同的服务器,由于网络延迟或者服务器处理速度的不同,后发的消息可能会先完成,此时就产生了消息乱序。解决方案:

前端依次对消息进行处理,发送完一个消息再发送下一个消息。这种方式会降低用户体验,一般情况下不建议使用。

带上一个前端生成的顺序ID,让接收方根据该ID进行排序。这种方式前端处理会比较麻烦一点,而且聊天的过程中接收方的历史消息列表中可能会在中间插入一条消息,这样会很奇怪,而且用户可能会漏读消息。但这种情况可以通过在用户切换窗口的时候再进行重排来解决,接收方每次收到消息都先往最后面追加。

通常为了优化体验,有的IM系统可能会采取异步发送确认机制(例如:QQ)。即消息只要到达服务器,然后服务器发送到MQ就算发送成功。如果由于权限等问题发送失败的话后端再推一个通知下去。这种情况下MQ就要选择合适的Sharding策略了:

按to_user_id进行Sharding:使用该策略如果需要做多端同步的话发送方多个端进行同步可能会乱序,因为不同队列的处理速度可能会不一样。例如发送方先发送m1然后发送m2,但服务器可能会先处理完m2再处理m1,这里其它端会先收到m2然后是m1,此时其它端的会话列表就乱了。

按conversation_id进行Sharding:使用该策略同样会导致多端同步会乱序。

按from_user_id进行Sharding:这种情况下使用该策略是比较好的选择

通常为了优化性能,推送前可能会先往MQ推,这种情况下使用to_user_id才是比较好的选择。

用户在线状态如何做

很多IM系统都需要展示用户的状态:是否在线,是否忙碌等。主要可以使用Redis或者分布式一致性哈希来实现用户在线状态的存储。

看上面的图可能会有人疑惑,为什么每次心跳都需要更新Redis?如果我使用的是TCP长连接那是不是就不用每次心跳都更新了?确实,正常情况下服务器只需要在新建连接或者断开连接的时候更新一下Redis就好了。但由于服务器可能会出现异常,或者服务器跟Redis之间的网络会出现问题,此时基于事件的更新就会出现问题,导致用户状态不正确。因此,如果需要用户在线状态准确的话最好通过心跳来更新在线状态。

由于Redis是单机存储的,因此,为了提高可靠性跟性能,我们可以使用Redis Cluster或者Codis。

使用分布式一致性哈希需要注意在对Status Server Cluster进行扩容或者缩容的时候要先对用户状态进行迁移,不然在刚操作时会出现用户状态不一致的情况。同时还需要使用虚拟节点避免数据倾斜的问题。

 

多端同步怎么做

读扩散

前面也提到过,对于读扩散,消息的同步主要是以推模式为主,单个会话的消息ID顺序递增,前端收到推的消息如果发现消息ID不连续就请求后端重新获取消息。但这样仍然可能丢失会话的最后一条消息,为了加大消息的可靠性,可以在历史会话列表的会话里再带上最后一条消息的ID,前端在收到新消息的时候会先拉取最新的会话列表,然后判断会话的最后一条消息是否存在,如果不存在,消息就可能丢失了,前端需要再拉一次会话的消息列表;如果会话的最后一条消息ID跟消息列表里的最后一条消息ID一样,前端就不再处理。这种做法的性能瓶颈会在拉取历史会话列表那里,因为每次新消息都需要拉取后端一次,如果按微信的量级来看,单是消息就可能会有20万的QPS,如果历史会话列表放到MySQL等传统DB的话肯定抗不住。因此,最好将历史会话列表存到开了AOF(用RDB的话可能会丢数据)的Redis集群。这里只能感慨性能跟简单性不能兼得。

 

写扩散

对于写扩散来说,多端同步就简单些了。前端只需要记录最后同步的位点,同步的时候带上同步位点,然后服务器就将该位点后面的数据全部返回给前端,前端更新同步位点就可以了。

如何处理未读数

在IM系统中,未读数的处理非常重要。未读数一般分为会话未读数跟总未读数,如果处理不当,会话未读数跟总未读数可能会不一致,严重降低用户体验。

读扩散

对于读扩散来说,我们可以将会话未读数跟总未读数都存在后端,但后端需要保证两个未读数更新的原子性跟一致性,一般可以通过以下两种方法来实现:

使用Redis的multi事务功能,事务更新失败可以重试。但要注意如果你使用Codis集群的话并不支持事务功能。

使用Lua嵌入脚本的方式。使用这种方式需要保证会话未读数跟总未读数都在同一个Redis节点(Codis的话可以使用Hashtag)。这种方式会导致实现逻辑分散,加大维护成本。

写扩散

对于写扩散来说,服务端通常会弱化会话的概念,即服务端不存储历史会话列表。未读数的计算可由前端来负责,标记已读跟标记未读可以只记录一个事件到信箱里,各个端通过重放该事件的形式来处理会话未读数。使用这种方式可能会造成各个端的未读数不一致,至少微信就会有这个问题。

如果写扩散也通过历史会话列表来存储未读数的话那用户时间线服务跟会话服务紧耦合,这个时候需要保证原子性跟一致性的话那就只能使用分布式事务了,会大大降低系统的性能。

如何存储历史消息

读扩散

对于读扩散,只需要按会话ID进行Sharding存储一份就可以了。

 

写扩散

对于写扩散,需要存储两份:一份是以用户为Timeline的消息列表,一份是以会话为Timeline的消息列表。以用户为Timeline的消息列表可以用用户ID来做Sharding,以会话为Timeline的消息列表可以用会话ID来做Sharding。

 

数据冷热分离

对于IM来说,历史消息的存储有很强的时间序列特性,时间越久,消息被访问的概率也越低,价值也越低。如果我们需要存储几年甚至是永久的历史消息的话(电商IM中比较常见),那么做历史消息的冷热分离就非常有必要了。数据的冷热分离一般是HWC(Hot-Warm-Cold)架构。对于刚发送的消息可以放到Hot存储系统(可以用Redis)跟Warm存储系统,然后由Store Scheduler根据一定的规则定时将冷数据迁移到Cold存储系统。获取消息的时候需要依次访问Hot、Warm跟Cold存储系统,由Store Service整合数据返回给IM Service。

 

接入层怎么做

实现接入层的负载均衡主要有以下几个方法:

硬件负载均衡:例如F5、A10等等。硬件负载均衡性能强大,稳定性高,但价格非常贵,不是土豪公司不建议使用。

使用DNS实现负载均衡:使用DNS实现负载均衡比较简单,但使用DNS实现负载均衡如果需要切换或者扩容那生效会很慢,而且使用DNS实现负载均衡支持的IP个数有限制、支持的负载均衡策略也比较简单。

DNS + 4层负载均衡 + 7层负载均衡架构:例如 DNS + DPVS + Nginx 或者 DNS + LVS + Nginx。有人可能会疑惑为什么要加入4层负载均衡呢?这是因为7层负载均衡很耗CPU,并且经常需要扩容或者缩容,对于大型网站来说可能需要很多7层负载均衡服务器,但只需要少量的4层负载均衡服务器即可。因此,该架构对于HTTP等短连接大型应用很有用。当然,如果流量不大的话只使用DNS + 7层负载均衡即可。但对于长连接来说,加入7层负载均衡Nginx就不大好了。因为Nginx经常需要改配置并且reload配置,reload的时候TCP连接会断开,造成大量掉线。

DNS + 4层负载均衡:4层负载均衡一般比较稳定,很少改动,比较适合于长连接。

对于长连接的接入层,如果我们需要更加灵活的负载均衡策略或者需要做灰度的话,那我们可以引入一个调度服务,如下图所示:

 4.png

Access Schedule Service可以实现根据各种策略来分配Access Service,例如:

根据灰度策略来分配

根据就近原则来分配

根据最少连接数来分配

 

架构心得

最后,分享一下做大型应用的架构心得:

灰度!灰度!灰度!

监控!监控!监控!

告警!告警!告警!

缓存!缓存!缓存!

限流!熔断!降级!

低耦合,高内聚!

避免单点,拥抱无状态!

评估!评估!评估!

压测!压测!压测!

 

来源:InfoQ 


这款网络排查工具,堪称神器!

技术交流大兴 发表了文章 • 0 个评论 • 88 次浏览 • 2020-07-31 10:43 • 来自相关话题

常用的 ping,tracert,nslookup 一般用来判断主机的网络连通性,其实 Linux 下有一个更好用的网络联通性判断工具,它可以结合 ping nslookup tracert 来判断网络的相关特性,这个命令就是 mtr。mtr 全称 my tr... ...查看全部
常用的 ping,tracert,nslookup 一般用来判断主机的网络连通性,其实 Linux 下有一个更好用的网络联通性判断工具,它可以结合 ping nslookup tracert 来判断网络的相关特性,这个命令就是 mtr。mtr 全称 my traceroute,是一个把 ping 和 traceroute 合并到一个程序的网络诊断工具。

traceroute 默认使用 UDP 数据包探测,而 mtr 默认使用 ICMP 报文探测,ICMP 在某些路由节点的优先级要比其他数据包低,所以测试得到的数据可能低于实际情况。

安装方法

1.Windows 系统可以直接在 https://cdn.ipip.net/17mon/besttrace.exe 下载 BestTrace 工具并安装。也可以在 https://github.com/oott123/WinMTR/releases GitHub 上下载 MTR 专用工具,该工具为免安装,下载后可以直接使用。
2.Linux 可以直接运行命令进行安装。

# Debian/Ubuntu 系统
apt install mtr

# RedHat/CentOS 系统
yum install mtr
3.Apple 客户端可以在 App store 搜索 Best NetTools 下载安装
4.Android 客户端:可以在 Google Play 上下载 TracePing,但是由于国内 Google Play 无法访问,笔者自行下载下来,可以直接访问 https://dwz.cn/KCdNPH4c 下载 TracePing。

使用

MTR 使用非常简单,查看本机到 qq.com 的路由以及连接情况直接运行如下命令:

mtr qq.com

微信图片_20200731104115.png

具体输出的参数含义为:
  • 第一列是 IP 地址

  • 丢包率:Loss

  • 已发送的包数:Snt

  • 最后一个包的延时:Last

  • 平均延时:Avg

  • 最低延时:Best

  • 最差延时:Wrst

  • 方差(稳定性):StDev

参数说明


  • -r or --report

使用 mtr -r qq.com 来打印报告,如果不使用 -r or --report 参数 mtr 会不断动态运行。使用 report 选项, mtr 会向 qq.com 主机发送 10 个 ICMP 包,然后直接输出结果。通常情况下 mtr 需要几秒钟时间来输出报告。mtr 报告由一系列跳数组成,每一跳意味着数据包通过节点或者路由器来达到目的主机。
一般情况下 mtr 前几跳都是本地 ISP,后几跳属于服务商比如 腾讯数据中心,中间跳数则是中间节点,如果发现前几跳异常,需要联系本地 ISP 服务提供上,相反如果后几跳出现问题,则需要联系服务提供商,中间几跳出现问题,则需要联系运营商进行处理
默认使用 -r 参数来生成报告,只会发送 10 个数据包,如果想要自定义数据包数量,可以使用 -c 参数
  • -s or --packetsize

使用 -s 来指定 ping 数据包的大小

mtr -s 100 qq.com
100 bytes 数据包会用来发送,测试,如果设置为负数,则每一次发送的数据包的大小都会是一个随机数。
  • -c

指定发送数量

mtr -c 100 qq.com
  • -n

不进行主机解释
使用 -n 选项来让 mtr 只输出 IP,而不对主机 host name 进行解释

mtr -n qq.com

MTR 结果分析

当我们分析 MTR 报告时候,最好找出每一跳的任何问题。除了可以查看两个服务器之间的路径之外,MTR 在它的七列数据中提供了很多有价值的数据统计报告。
Loss% 列展示了数据包在每一跳的丢失率。Snt 列记录的多少个数据包被送出。
使用 –report 参数默认会送出 10 个数据包。如果使用 –report-cycles=[number-of-packets] 选项,MTR 就会按照 [number-of-packets] 指定的数量发出 ICMP 数据包。
Last, Avg, Best 和 Wrst 列都标识数据包往返的时间,使用的是毫秒( ms )单位表示。Last 表示最后一个数据包所用的时间, Avg 表示评价时间, Best 和 Wrst 表示最小和最大时间。在大多数情况下,平均时间( Avg)列需要我们特别注意。
最后一列 StDev 提供了数据包在每个主机的标准偏差。如果标准偏差越高,说明数据包在这个节点的延时越不相同。标准偏差会让您了解到平均延时是否是真的延时时间的中心点,或者测量数据受到某些问题的干扰。
例如,如果标准偏差很大,说明数据包的延迟是不确定的。一些数据包延迟很小(例如:25ms),另一些数据包延迟很大(例如:350ms)。当 10 个数据包全部发出后,得到的平均延迟可能是正常的,但是平均延迟是不能很好的反应实际情况的。如果标准偏差很高,使用最好和最坏的延迟来确定平均延迟是一个较好的方案。
在大多数情况下,您可以把 MTR 的输出分成三大块。根据配置,第二或第三跳一般都是您的本地 ISP,倒数第二或第三跳一般为您目的主机的 ISP。中间的节点是数据包经过的路由器。
当分析 MTR 的输出时,您需要注意两点:loss 和 latency。

网络丢包

如果在任何一跳上看到 loss 的百分比,这就说明这一跳上可能有问题了。当然,很多服务提供商人为限制 ICMP 发送的速率,这也会导致此问题。那么如何才能指定是人为的限制 ICMP 传输 还是确定有丢包的现象?此时需要查看下一跳。如果下一跳没有丢包现象,说明上一条是人为限制的。如下示例:

微信图片_20200731104224.png

人为限制 MTR 丢包

在此例中,第 4 跳发生了丢包现象,但是接下来几条都没任何丢包现象,说明第二跳的丢包是人为限制的。如果在接下来的几条中都有丢包,那就可能是第二跳有问题了。请记住,ICMP 包的速率限制和丢失可能会同时发生。

微信图片_20200731104236.png

MTR 丢包截图

从上面的图中,您可以看从第 13 跳和第 17 跳都有 10% 的丢包率,从接下来的几跳都有丢包现象,但是最后 15,16 跳都是 100% 的丢包率,我们可以猜测到 100% 的丢包率除了网络糟糕的原因之前还有人为限制 ICMP。所以,当我们看到不同的丢包率时,通常要以最后几跳为准。
还有很多时候问题是在数据包返回途中发生的。数据包可以成功的到达目的主机,但是返回过程中遇到 “困难” 了。所以,当问题发生后,我们通常需要收集反方向的 MTR 报告。
此外,互联网设施的维护或短暂的网络拥挤可能会带来短暂的丢包率,当出现短暂的 10% 丢包率时候,不必担心,应用层的程序会弥补这点损失。

网络延迟

除了可以通过 MTR 报告查看丢包率,我们也还可以看到本地到目的之间的时延。因为是不通的位置,延迟通常会随着条数的增加而增加。所以,延迟通常取决于节点之间的物理距离和线路质量。

微信图片_20200731104250.png

MTR 查看网络延迟

从上面的 MTR 报告截图中,我们可以看到从第 11 跳到 12 跳的延迟猛增,直接导致了后面的延迟也很大,一般有可能是 11 跳到 12 跳属于不通地域,物理距离导致时延猛增,也有可能是第 12 条的路由器配置不当,或者是线路拥塞。需要具体问题进行具体的分析。
然而,高延迟并不一定意味着当前路由器有问题。延迟很大的原因也有可能是在返回过程中引发的。从这份报告的截图看不到返回的路径,返回的路径可能是完全不同的线路,所以一般需要进行双向 MTR 测试。
注:ICMP 速率限制也可能会增加延迟,但是一般可以查看最后一条的时间延迟来判断是否是上述情况。

根据 MTR 结果解决网络问题

MTR 报告显示的路由问题大都是暂时性的。很多问题在 24 小时内都被解决了。大多数情况下,如果您发现了路由问题,ISP 提供商已经监视到并且正在解决中了。当您经历网络问题后,可以选择提醒您的 ISP 提供商。当联系您的提供商时,需要发送一下 MTR 报告和相关的数据。没有有用的数据,提供商是没有办法去解决问题的。
然而大多数情况下,路由问题是比较少见的。比较常见的是因为物理距离太长,或者上网高峰,导致网络变的很慢。尤其是跨越大西洋和太平洋的时候,网络有时候会变的很慢。这种情况下,建议就近接入客户的节点。


作者:苏欣

链接:https://cloud.tencent.com/developer/article/1491610


谷歌重磅开源项目“海啸”,霸榜Github第一!

技术交流大兴 发表了文章 • 0 个评论 • 66 次浏览 • 2020-07-22 11:24 • 来自相关话题

最近,谷歌专门为大型企业网络开源了一个漏洞扫描神器,主要用于数千个甚至数百万个物联网组成的企业系统。为了让大家放心使用,谷歌已经将“海啸”用于内部使用一个月之久了。不过,“海啸”并非是谷歌官方的产品,而是由开源社区来维护,有点类似于Kubernetes。“海啸... ...查看全部

最近,谷歌专门为大型企业网络开源了一个漏洞扫描神器,主要用于数千个甚至数百万个物联网组成的企业系统。为了让大家放心使用,谷歌已经将“海啸”用于内部使用一个月之久了。

22626539-2ef8fc1d9e76c59a.jpg

不过,“海啸”并非是谷歌官方的产品,而是由开源社区来维护,有点类似于Kubernetes。

“海啸”是如何运行的?

市场上已经有数百种类似的商业或开源的漏洞扫描器,但“海啸”和这些漏洞扫描器不同的是,它是专门为类似谷歌这样规模的企业构建的,诸如网络管理的企业,这些网络包括数十万台的服务器、工作站,网络设备和连接到互联网的物联网设备。

谷歌表示,他们设计的“海啸”能够直接适应这些大型网络,而不需要为每种设备类型运行不同的扫描仪。

海啸由两个部分组成,然后在这个基础上添加一个可扩展的插件机制,第一个组件是扫描仪本身,也就是侦查模块,该组件可以扫描企业网络的开放端口,然后测试每个端口,并试图识别在每个端口上运行的服务和协议,以防对端口进行错误标记,并标记测试设备是否存在错误的漏洞

谷歌表示,端口指纹模块基于行业测试的nmap网络映射引擎,“海啸”的第二个部分比较复杂,这一部分是基于第一部分的运行结果,它获取每个设备及其暴露的端口,选择要测试的漏洞列表,并运行检查设备是否容易受到攻击。

漏洞验证模块是通过“海啸”的插件拓展方式,安全团队可以通过添加插件的方式,添加新的攻击载体和漏洞来检测内部网络。

当前的海啸版本已经包含了多个插件帮助你检测:
Exposed sensitive UIs:Jenkins, Jupyter和Hadoop Yarn都带有UI,允许用户工作负载调度或执行系统命令,如果这些系统在没有身份验证的情况下暴露在internet上,攻击者可以利用应用程序的功能来执行恶意命令。

弱凭证:“海啸”使用其他开源工具(如ncrack)检测协议和工具包(包括SSH、FTP、RDP和MySQL)使用的弱密码。

谷歌表示,未来几个月他们将通过新增插件来增强“海啸”的功能特性,从而检测到更多的漏洞,所有的插件都将通过Github发布。


“海啸”目标?
谷歌表示,“海啸”旨在满足类似于谷歌这样的高端企业的客户需求,漏洞扫描的准确性是重中之重,项目的重点是避免出现错误的检测结果。

这一点是至关重要的,因为扫描器将运行在巨大的网络中,在这些网络中,即使是最轻微的错误发现也会导致向成百上千的设备发送不正确的补丁,最终导致设备/网络崩溃,造成不必要的损失。

此外,为了减少安全团队的警戒疲劳,海啸还将扩展到只支持扫描那些可能被武器化的高危漏洞,而不是像目前的大多数漏洞扫描器所做的那样,专注于扫描所有的漏洞。

霸榜Github第一!谷歌重磅开源的“海啸”,我服了
“海啸”发布不久,已经稳稳霸住Github周榜第一的位置,收获标星4435个,累计分支362个(Github地址:https://github.com/google/tsunami-security-scanner),感兴趣的小伙伴们不要错过了哦。



Linux 之父对 Intel 发飙:拜托快学学 AMD

活动大兴 发表了文章 • 0 个评论 • 91 次浏览 • 2020-07-15 11:41 • 来自相关话题

在最近一次邮件交流中,Linux之父Linus Torvalds对Intel的处理器战略表达意见。他谈到“希望AVX512指令集安详地‘死去’”。Torvalds指出,Intel应当把精力转移到解决真正问题上来,而不是通过创造神奇的指令集来赢得某些跑分上的胜利... ...查看全部

在最近一次邮件交流中,Linux之父Linus Torvalds对Intel的处理器战略表达意见。

他谈到“希望AVX512指令集安详地‘死去’”。Torvalds指出,Intel应当把精力转移到解决真正问题上来,而不是通过创造神奇的指令集来赢得某些跑分上的胜利。

Torvalds还提到AMD,建议Intel像后者那样,把核心数做上来。在Torvalds看来,AVX512指令集仅在HPC(高性能计算集群)中有点用。

s_7a08f1594ea1442ca873f3b6b702144b.jpg

据悉,AVX-512是第三代AVX高级矢量扩展指令集,最早于2016年的Xeon Phi x200加速卡中被支持。它提供了单次512位数据和控制指令的执行单元,使得CPU单次可处理的组合矢量数据宽度达到512位,并且扩展到32个512位ZMM寄存器,保证数据处理的暂存需求,也支持FMA融合乘加操作。

当然,Torvalds此番谈话还有个背景是,Rocket Lake处理器的下一代Alder Lake可能会是Intel第一次大规模在消费级应用big.LITTLE混合架构,而为了指令集统一、减少调度损耗(Atom不支持AVX-512),Alder Lake可能砍掉AVX-512。

s_cb126cf1f56d4630841aa159c2ae6497.jpg

原文:http://news.mydrivers.com/1/700/700158.htm

end

乔布斯,比尔盖茨,扎克伯格等大佬的办公桌什么样?

活动大兴 发表了文章 • 2 个评论 • 67 次浏览 • 2020-07-06 10:27 • 来自相关话题

大多数同为工程师的读者们,应该总是会对“工程师的办公桌到底有多乱”这类话题感兴趣,那些曾经的工程师、程序员巨佬的办公桌是否也杂乱无章呢?来看看。一、雷军从雷军的办公桌上,你看到了什么?稳压源、示波器……还有两台什么?阻抗分析仪?整体上看上去还是比较整洁的。一位... ...查看全部

大多数同为工程师的读者们,应该总是会对“工程师的办公桌到底有多乱”这类话题感兴趣,那些曾经的工程师、程序员巨佬的办公桌是否也杂乱无章呢?来看看。


一、雷军

微信图片_20200706102259.jpg

从雷军的办公桌上,你看到了什么?稳压源、示波器……还有两台什么?阻抗分析仪?整体上看上去还是比较整洁的。一位软硬皆通的CEO,不知道现在小米公司做这么大了,是不是还是这样的办公桌。


二,丰田章男


丰田第四代长孙,仅仅用了7年时间就将丰田锻造成一个年销千万级的庞大企业。丰田章男的办公室更像是释放情怀的聚集地,相比于繁琐的公务文件,这里的玩具更多一些,赛车、车模、本田asimo公仔以及头盔、贴纸等等,对于丰田章男来说,他将所有的时间奉献给丰田管理,办公室只是名义上的办公室,事实上它更像休息室多一些。

微信图片_20200706102337.jpg


与咱们印象中的企业高层完全不同,与其说是办公室,不如说是一个私人的电玩玩家的收藏室。桌上除了电脑,其它就是布列了很多的物件。只有20多个平方米的办公室布满了机器人公仔、汽车模型等。有没有像卖杂志报刊的店面呢

三,Jim Williams


作为早期的linear成员之一,Jim拥有了不小的财富,但他直到去世前还是喜欢在LAB里工作,喜欢设计电路,并把电路设计思想用最简单的方式描述出来。无数模拟工程师从他的文章中获益匪浅。

微信图片_20200706102404.png


Jim的职业生涯始于麻省理工营养实验室(MIT Nutrition Lab),制作实验、研究所需的电路的系统。就我所知,Jim没有正式拿过电子工程学位,他在这方面主要是自学。出于对模拟电路的爱,Jim每年都会回到麻省理工为电子工程专业的学生客座讲课,也会进行一些招聘和拓展。

微信图片_20200706102425.jpg


四,Linux创始人Linus Torvalds


Linus Torvalds是世界上最著名的程序员之一,是Linux操作系统之父。并制作了近乎通用的Git分布式版本控制系统

微信图片_20200706102443.jpg

2014 年 7 月,Linus 首次公开了他的家庭办公室。有一台转角办公桌,桌面可能和大多数人一样,比较凌乱,有各种连接线、3D打印机、线缆、硬盘……。linus还有一个可以站着工作的工作台,比坐着工作更健康。


五,比尔盖茨


比尔·盖茨是前微软 CEO 兼联合创始人,他的办公室就是高科技的设计感,这里空间大,非常符合现代我们对于 CEO 办公室的理解,但是比较简约大气。值得一提的是他的三面屏电脑,看起来好霸气,调试代码时比较方便。

微信图片_20200706102508.jpg

六,史蒂夫·乔布斯


苹果前CEO史蒂夫·乔布斯的办公桌,想不到他办公室竟然如此简单,没有过多的装饰,一个书架和一个书桌,布满了书籍,以及办公所用的必须工具。

微信图片_20200706102528.jpg

七,扎克伯格


扎克伯格身价高达623亿美元,折合人民币早就超越了千亿元,是全球十大富豪中最年轻的一位,在公共办公区域进行办公。扎克伯格的工作状态非常专注,还发现了他桌子上的头盔和运动衫,非常邻家的感觉。

微信图片_20200706102542.jpg

回看了一下自己的办公桌,角落里落满的灰尘和散落一桌的杂物,我欣然接受了这种工作辛苦而未及收拾近两年未变的状态。。。


作者:Python之禅

链接https://mp.weixin.qq.com/s/nvBYwiX9TdGT1UN819i9qA

跳来跳去,程序员到底去大公司还是小公司?

技术交流大兴 发表了文章 • 0 个评论 • 93 次浏览 • 2020-10-10 18:30 • 来自相关话题

职场生涯总会面临着选择,尤其对我们这些 IT 人来说,跳槽的频率应该是所有行业中相当大的了。那么我们跳来跳去,究竟该选择什么样的公司 ?大 or 小 。工作三年多了,经历一大一小,最近也面试了不少家公司,形态各异,说说自己的感受想法。在小公司中,给我个人的印象... ...查看全部

untitled.png

职场生涯总会面临着选择,尤其对我们这些 IT 人来说,跳槽的频率应该是所有行业中相当大的了。那么我们跳来跳去,究竟该选择什么样的公司 ?大 or 小 。

工作三年多了,经历一大一小,最近也面试了不少家公司,形态各异,说说自己的感受想法。

在小公司中,给我个人的印象大多数环境都不怎么样。定义下这个小公司规模吧,在几人到几十人吧,反正不会超过100人。

亲历一家小公司, 面试见过数家小型公司。我觉得大概分两种:

1.真正的黑穷丑

入职原因:实在没地方去了,毕业什么也不会,来做苦工吧

缺点:加班是家常便饭、工资少的可怜、福利基本没有,事事都要你干

优点:锻炼你顽强的意志力、培养男人的愤怒血性,当然干的多了能力自然也会有提升,不过如果没有牛人带且自己也不是特强的话,你的视野应该是比较窄的

2.有稳定业务、公司盈利还不错,待遇也可以媲美大公司

缺点:还是个人视野的问题,如果你个人能力很好,不是野心很大,在小公司也不错

优点:至少福利待遇不会差,环境也还可以,公司小自己做的贡献领导会看到,做个2,3年可能就是公司的主干力量了,有成就感。

说说自己的第一家公司,那个小公司

自己毕业时选择的是这家小公司,说选择当时是有对比,而最终决定去这家小公司的原因是他给开了3k的工资,比其他两个相对大的公司多,于是就去了,虽然环境不怎么样,自己也忍了,觉得应该锻炼机会很多吧,有家公司环境着实不错,可是帝都1600的工资实在觉得跌面儿。

正像我说的第2种小公司一样,老板有自己的关系公司每年的盈利还不错,几十人的小公司过的也还算舒服。工资每年都会涨,没用自己提过,基本在一年1k左右,毕业刚去的那年发了5k的年终奖,欣喜的不亦乐乎。

在公司的工作就是做一些小项目,很少加班,开始有人带,而后就是自己做项目,整个项目的方方面面,再后来还要带一些刚毕业的小弟弟,实在不敢以师傅挂名,羞愧不敢当,觉得自己的水平不够,于是考虑到在该公司的状况也就如此了,自己又不是视野很宽知道学什么的主,于是有了离开的打算,想去看看国外的月亮。

没见过国外的月亮,都会觉得外面的月亮是更圆的。尽管工作2年的时候工资翻了一倍,那年的年终奖也拿到2w多的地步,老板器重的情况下,还是选择了了离开。

觉得外面的世界很精彩,自己需要出去看看,就这样离开了,来到了一家规模还比较大的互联网公司,虽然工资只比原来多了1k,还是去了,觉得神秘的大公司应该可以学习到不少的东西吧。

很庆幸,刚毕业没有遇见第一种小公司,一些脏乱差,到处摆满东西的公司在后来的面试时还真是见过几个。

一个插曲:一个什么外包公司要我去面试,进去后一看里面安了很多挡板,临时搭的那种,我以为公司发展过来的小分部,随后了解说这是公司总部,汗颜。

来到了大公司

虽然钱没多挣(也许还不如以前的多),但一下子觉得自己牛逼了不少,因为自己的公司耳熟能详啊,可以和别人吹牛逼,也可以给自己的职业生涯贴贴金。

干净的办公环境,每过一会儿就有人清理的卫生间,正版的操作系统、应用软件,公司项目用的新技术,一切的一切都是新鲜的,就像一个村儿逼来到了城里看见了摩天大厦,豁然开朗。周围人也都是4,5年工作经验的牛人……

也就是半年吧,新鲜感过了,也没什么了。唯一感觉的就是觉得工作无聊,整天维护着那么一个小项目,有时很长时间都不知道做什么,也许是自己的问题吧,但是我确定的是这不是我想要的,跟我想的不一样。

不过在该公司的一年多时间里,技术上有一定的提高、见识也增长了不少,但是更大的变化是自己的思想发生了很大的改变。

以前觉得自己是一个.net程序员,就像园子里曾经有人说,这个叫法很蹩脚很奇怪,确实是这样,我们为什么要把自己定义为一个xx程序员?而我们只是一个程序员啊,写代码的程序员,不管是java、c#、php、python、javascript…. 这是一个重要改变。

一直在想,我追求的所谓大公司,到底追求的是什么?

离开第一家小公司想要追求的东西,想要有人带,有高手指导,而这只不过是自己能力的欠缺与知识获取方面能力的不足罢了。

当我们自己这两方面足够强大的时候,我们就成为了高手,不再需要别人的指导,你追求的大公司也就成为了一个空壳。

所以我觉得,大公司、小公司都无所谓,首先我们要让自己牛逼,或者知道怎样牛逼起来,然后再有施展技能的平台就够了,大、小只是一个壳罢了,问题的根源在于你是否能够牛逼起来!


写给年轻程序员的一些心里话

技术交流大兴 发表了文章 • 0 个评论 • 65 次浏览 • 2020-10-09 18:39 • 来自相关话题

每个人的经历都是不同的,也是无法复制的。不要试图复制某个人的成功,你将徒劳无功。但每个人成长过程中总结出来的经验却是可以供他人借鉴的。下面我把自己这么多年的生活经验总结了几条,分享给各位,希望能给大家带来一些有意义的帮助。1保持自信做任何一件事情之前,你都要对... ...查看全部

09d50ad12ab7fe446af8aeb2a2ab05d0.jpg

每个人的经历都是不同的,也是无法复制的。不要试图复制某个人的成功,你将徒劳无功。但每个人成长过程中总结出来的经验却是可以供他人借鉴的。

下面我把自己这么多年的生活经验总结了几条,分享给各位,希望能给大家带来一些有意义的帮助。

1保持自信

做任何一件事情之前,你都要对自己充满信心。如果对自己不自信的话,就会在潜意识了给自己消极的心理暗示,到最后你都不敢去尝试做这件事。如果连尝试的勇气都没有了,就更谈不上把这件事做成了。

关于自信和不自信给一个人带来的不同影响,我在这里就不废话了,很多心理学的专业资料都有论证,相信各位自己也都有亲身经历。

人的自信心其实是可以培养的,我的方法是,每天结束之后都想想自己做成了哪些事情,哪怕是一些特别微不足道的事情。比如今天上班没迟到;比如今天少抽了一根烟等等。通过这些很小的事情,很容易达成的事情,来慢慢积累自己的信心。

2持续学习

社会总是不断在进步,新的事物和概念总是不断涌现,如果我们不持续学习,最终会被这个飞速前进的时代列车所抛弃。各位可以观察一下自己身边优秀的人,无论年龄大小,无一不在持续的学习。咱老祖宗的古语说得好,活到老学到老。

其实很多程序员都是比较爱学习的,因为总是有新的技术和框架出现,逼着大家去学习。这里我想说的不仅仅是对技术的学习。而是所有的东西,比如新的思维方式,新的认知方式等。

所谓的学习就是认知新观念和新想法的过程。我们遇到新的概念和事物,要勇于去尝试,尝试用新的思维方式去思考问题。不要轻易用已有的思维方式给之前没遇到的事物下结论,这样很容易阻止自己的进步。

这里可以给大家举个我生活中的例子。当年我结婚的时候,去家具城买床,我看中了一款特别厚特别软的床垫,大概不到1W块钱。我老娘就说不要睡软的床垫子,对腰不好。因为他们那个年代的人,都是睡硬床板过来的,所以根本不愿意接受这个新的事物,上来就否定这个东西。

前段时间,老娘来我家里,我让她睡在了那个床上,第二天早上醒来,老娘跟我说,这个床垫子还挺舒服的。

我们在不了解一件事物的时候,千万不要根据已有的思维定式去下判断,要接受新的事物,新的观念,不断更新自己的认知,千万不要让自己变成老顽固。

3学会理财

大部分程序员的工资还是很高的,特别是那些大厂程序员。但是跟很多的年轻程序员聊起来,发现他们其实没有多少存款,甚至根本没有存款。

其实理财根本不能让我们实现财富自由,但是理财可以让自己的生活更有计划,更有保障,给你自己和家人带来更多的安全感。比如这次疫情,很多人都失业或者被降薪了,如果手里没有余粮还是挺狼狈的。

特别是随着年龄的增上,你的责任也会越来越大,比如谈恋爱了,想换个有面子的车子,孩子要上补习班,父母生病了,等等。所以劝各位还是要认真规划自己的收入,无论多少。正所谓你不理财,财不理你。

关于理财,我自己的做法是一部分钱放在银行,一部分钱去买基金理财,还有一部分钱用于日常消费。放在银行里面的钱,相当于自己的粮仓,轻易不会动,是自己的靠山。俗话说的好,家中有粮,心中不慌。

而基金理财,是可以让你的财富升值的;其实基金是广大非专业人士最理想的投资方式,简单易操作,而且风险不会像股票那么高。

关于买基金,建议各位选一些大公司的基金产品,采取定投的方式,一定要长期持有(以年为计量单位),不要一看下跌了,心理就发慌,一发慌就开始卖出,这样做你将成为一名优秀的韭菜。

我看过很多材料和数据,大部分基金从长期来看,平均每年都会有12%的收益,这是什么概念呢,就是你买一万块钱的基金,到年底的时候,会盈利1200块。根据我自己的实际经验也是符合这个说法的。关于具体收益算法,以及为什么会是12%的收益率,这里我就不展开了,毕竟我不是卖理财产品的。

最后在多唠叨几句,投资有风险,要拿自己暂时不用的闲钱去投资。千万不要拿自己的吃饭钱去投资,更不要拿父母的养老钱去投资。你这样做不是投资而是赌博。

4幸福生活

每个人对幸福生活的定义都有各自的标准。我所理解的幸福生活,不是拥有了多少财富,也不是开多么豪华的车子,而是你内心的充实,有时间进行自己的业余爱好,有一起闲聊的好朋友,周末的时候可以陪陪父母和家人。

总之我不建议各位为了获取更多的金钱,而失去太多本来可以体验美好生活的时光,毕竟我们赚钱的目的是为了幸福生活。大家不要舍本逐末,要做好平衡。毕竟中国人最讲究中庸之道!相信各位在生活和工作之间都能做好平衡。

原创:花括号MC(微信公众号:huakuohao-mc)。关注JAVA基础编程及大数据,注重经验分享及个人成长。

外卖骑手的解困之策

技术交流大兴 发表了文章 • 0 个评论 • 66 次浏览 • 2020-09-30 10:06 • 来自相关话题

来源:虎嗅APP作者|王海、孙昊头图|CFP.CN背景本月初,一篇针对“困在系统里”的外卖骑手的新闻报道展现了外卖行业中险象环生的现状,激起社会各界的广泛讨论。面对外卖市场的激烈竞争,平台持续地追求提升效率和降低成本,采用大数据技术和人工智能算法,并在发掘人力... ...查看全部


cf1b9d16fdfaaf516a3cab6bf057c8e9f11f7a15.jpg

来源:虎嗅APP

作者|王海、孙昊头图|CFP.CN


背景

本月初,一篇针对“困在系统里”的外卖骑手的新闻报道展现了外卖行业中险象环生的现状,激起社会各界的广泛讨论。面对外卖市场的激烈竞争,平台持续地追求提升效率和降低成本,采用大数据技术和人工智能算法,并在发掘人力极限的过程中,不断降低送餐时限,使得全行业外卖订单单均配送时长在2019年比3年前减少了10分钟[51] ,显著提升了顾客体验,推动外卖成为了劳动密集型和技术密集型模式结合的代表行业。

然而,由于现有共享经济商业模式中服务提供者与平台并没有正式雇佣关系的特殊性,平台对骑手的权益保障和社会福利的重视程度仍有待提高;在现有的商业逻辑、算法规则和考核制度面前,为了完成更多订单以提高收入,一些骑手违反交通法规甚至冒着生命危险“乘风破浪”。据统计,在2017年,仅上海市就发生涉及快递和外卖行业的各类道路交通事故117起,共造成9人死亡,134人受伤[50] 。

当前,激烈的市场竞争环境正推动外卖平台不断改进算法和骑手绩效考核方式。社会在收获良好顾客体验、较低配送成本和极高配送效率的同时,也付出了骑手权益和行人安全降低的代价。面对此外卖骑手困境,我们将围绕其中的问题根源,从平台设计运营和政府监督监管的视角,系统性地提出一系列可以尝试的改进方案。

作为致力于大数据,运筹学,以及人工智能方法在智慧城市领域应用的学者和研究者,我们期望用更加科学的运营流程和算法逻辑,构筑健康,温暖,高效,可持续并且具有社会责任的外卖生态体系。

我们的方案将从平台设计运营和政府监督监管两方面展开——

在平台设计部分,方案将聚焦骑手激励机制、运营流程和算法,以及供需调节机制等内容;

在政府监管部分,方案将聚焦明晰劳资关系、加强资质审核和运营监督、明确平台责任、以及市场竞争与政府干预等内容。由于时间和篇幅所限,本文并没有列举介绍所有可能的改进方向,仅选择我们认为对解决外卖骑手困境最重要并且具有实际可行性的内容。

针对每项的具体内容,我们在“洞察”部分介绍了相关的经济学和管理学原理,或者相关的数据科学、人工智能和优化算法的可能技术实现路线,以供业内人士和专家学者等参考,读者直接跳过该部分内容不会影响对全文的理解。

平台设计

1、骑手激励机制设计

在围绕外卖骑手困境的讨论中,改善骑手的激励和奖惩机制是大家关注的一个焦点。

在基于人工智能算法的外卖配送系统中,从顾客成功下单的时刻起,该系统便会自动化计算最优的订单分派和骑手配送路线,并且预测订单的“预计送达时间”,然后以此考核骑手的“准点率”;一旦订单配送超时,骑手们将面临降低收入甚至淘汰出局的惩罚。

在此过程中,值得重点关注的是,这套“最优”方案只是在给定的历史数据和预设的模型参数下、通过模拟现实得到的“理想值”或者“乐观值”。因此,面对复杂多变的现实场景,外卖骑手的激励机制需要具备容错性和灵活性,帮助外卖骑手抵抗已知或者未知的市场不确定性带来的负面冲击,降低外卖骑手收入的波动,这不仅有助于提升骑手们的福利水平,也将会增强平台的总体运力。

(1)预计送达时间容错

面对无法避免的外卖订单配送超时风险,平台可以考虑引入“超时容错机制”,订单的“预计送达时间”设置和显示为一定的时间段(例如,“17:20~17:25 到达”),并且根据商家的备餐状态和骑手的配送情况动态调整、提前向顾客提醒可能的超时送达,而不是精确到具体的时刻(例如,“预计17:23到达”)甚至故意将顾客端显示的“预计送达时间”设定的短于骑手端。

洞察:从技术层面而言,即便是采用先进的深度学习算法,模型学习到的结果也只是关于“预计送达时间”(Estimated Time of Arrival,简称 ETA)的统计分布,并不能做到对每个样本的预测值都有绝对准确的“信心”[47] 。ETA 参数的区间估计结果(“17:20~17:25”)会比点估计结果(“17:23”)更加具有可信度,因为后者并不能告诉顾客真实的送达时间与它的距离,而前者则可以反映真实的送达时间所处的大致可信范围(confidence interval)。从管理层面而言,区间形式的“预计送达时间”是应对预测算法的误差和外部配送环境的变化的容错策略,体现的是对骑手和顾客负责任的态度。与此相关,平台还可以根据送达时间的区间设置弹性的实际送达时间考核标准:如果实际送达时间在“预计送达时间”前后N分钟,则该笔订单配送记录判定为“正常”,如果实际送达时间超过“预计送达时间”N分钟,则该笔订单配送记录判定为“超时”而纳入超时评估体系;最后,如果实际送达时间早于“预计送达时间”N分钟,则该笔订单配送记录判定为“快速”而纳入高效奖励体系。类似思想已经被外卖平台的ETA预估算法所采纳[47] ,也可以作为超时容错策略体现在骑手激励机制设计中。

(2)弹性的超时奖惩

围绕超时容错机制,平台可以考虑针对骑手“超时率”划分多个区间段、设计更具有弹性的阶梯式超时奖惩规则:超时率被划分成多个区间段,例如,[0%, 5%]、(5%, 10%] 以及10%以上,如果骑手的超时率处于第一个区间段,则骑手的绩效水平不会受到影响;如果骑手的超时率处于第二个区间段,则骑手的绩效水平将受到适当轻微的负面影响;但是,如果骑手的超时率处于更高的区间段,则骑手的绩效水平将受到显著增强的负面影响。

洞察:当前,骑手们的超时率通常不得高于3%,否则,包括骑手、站长甚至区域经理等所有人都将面临绩效的惩罚[51]。那么,从激励机制设计的本质而言,无论是预计送达时间容错机制还是弹性超时奖惩机制,从数学模型的角度,都是在期望构建基于骑手工作绩效(即超时程度或者“超时率”)的非线性激励机制。类似分段阶梯式的非线性惩罚机制在线上多边平台市场中经常出现,例如,在网约车市场,为了杜绝司机的刷单作弊行为,平台会设计阶梯式作弊违规处罚标准:“第一次禁用3天,第二次禁用15天,第三次解除合作;累计非法获利≥1000元时,解除合作永不录用”[39]。在激励骑手们准时配送以最大化日成交金额(Gross Merchandise Volume,简称 GMV)或者日完单量的问题中,订单的送达状态取决于配送过程中环境的不确定性、骑手们的工作业务水平、以及骑手们对承担风险的态度等多方面因素,有一些因素只有骑手们自己知道,而平台并不能完全掌握。那么,采用非线性激励机制是否一定会提升平台整体的运营效率呢?从管理学理论上讲,基于绩效的激励机制包含激励强度的“斜率”(slope of incentive intensity)和激励的“形状”(shape of incentive contract)两个特征:斜率是指激励强度关于绩效的变化率,例如,超时率增加一个单位将会带来的收入惩罚绝对变化值,而形状是指激励关于绩效水平的非线性(或者称凹凸性)。研究表明,高激励斜率有助于改善绩效水平,而强非线性将会增强个体承担风险的偏好;同时,最新的实证结果显示,激励的斜率会影响个体的风险偏好,而激励的形状也会影响绩效水平[11]。因此,构建基于骑手工作绩效的激励机制需要综合上述多方面因素,合理选择激励关于绩效水平的斜率和形状,这样有助于提升配送系统整体的效率。

(3)骑手配送超时互助保险

为了进一步应对外卖订单配送超时风险,以及降低配送超时对骑手收入造成的激烈波动,平台除了在用户端提供配送超时保险和赔偿之外,还可以考虑尝试建立“骑手配送超时互助保险”机制:该保险可由骑手自主选择是否加入,即骑手在选择接单的同时还可以选择是否愿意为这笔订单缴纳较低金额的超时保险费,这笔费用成为骑手之间互助的保险金额池。如果骑手因为任何原因无法按时送达订单,可由金额池向骑手提供经济补偿以降低其收入波动,金额池内的余额最后都退还给骑手。

洞察:在市场经济条件下,保险是一个管理风险的常见工具,例如,在电子商务平台上,保险公司会向第三方卖家推出以商品买家为被保险人的“退换货运费险”,以便降低可能的退换货运费给买家造成的损失[42]。在外卖行业中,67%的骑手家庭人口在3人~5人,四成骑手的爱人选择在家照顾孩子和老人,同时,五成骑手是家庭收入的主要来源,七成骑手月收入在五千元以下,这些数字意味着大多数骑手正面临着来自自身和家庭的双重消费压力[43]。那么,设立“骑手配送超时互助保险”的核心目的在于希望能够建立大数量骑手们互助的保险金额池,缓解超时对个体骑手带来的负面收入冲击,降低个人收入的波动性,最终发挥平滑骑手收入的作用。研究表明,在面对风险时,低收入劳动者或者家庭通常会基于工作和消费等两类经济行为进行调节:一是平滑收入(income smoothing),例如,通过同时兼任多份工作以提高收入来源的多样性和稳定性(在美团平台,35%的骑手拥有包括小生意或者其它外卖平台在内的其它收入来源[43]);二是平滑消费(consumption smoothing),例如,调整自身的劳动力供给水平和使用保险协议[22]。从这两类经济行为可以看出,“骑手配送超时互助保险”可以有助于骑手抵御超时风险,降低收入的波动性,也将会激励骑手提供更好的运力供给。

(4)考核周期延长

为了进一步帮助骑手降低收入的波动性,平台可以考虑延长对骑手的考核周期,将以较短“时间段”(例如,现在平台的冲单奖励活动和考核时间段一般是一天的某个时段),或者以“天”为单位的奖励或者惩罚考核周期适当延长至“星期”甚至“月”,通过实践寻找出最佳的考核周期,以降低骑手对短期高频考核的焦虑,提高系统的整体效率。

洞察:类似基于时间段的冲单奖励看起来有助于满足高峰期时段的旺盛需求,但是,关于共享经济商业模式的实证研究表明,理性的服务提供者为了尽可能获得活动期的高冲单奖励,可能会选择在活动期开始之前策略性的停止工作,以等待高峰期的到来,这种“前瞻”(forward-looking)行为将会导致平台在高峰期到来之前的运力供给出现下降,给整个系统的运行效率造成负面影响[34]。考核周期的延长将有助于平滑骑手在不同时间段内的平均收入,激励骑手们维持稳定的服务质量水平,保障平台总体运力的平稳运行。那么,平台是否应该尽可能延长或者缩短激励机制中的考核周期呢?最近,一份关于产品销售人员薪酬体系设计的研究表明,销售人员的工作绩效将会显著受到考核周期的影响:当平台将激励机制的考核周期缩短时(比如,从“月”度考核调整为“天”度考核),原本优秀的销售人员就表现出了下降的绩效水平[10]。值得关注的是,已有的行为学实验研究和现实商业现象表明,基于考核目标的高频绩效评估会潜在地增加人员的焦虑心理和工作压力,甚至会因为激发人员过于激进而引发欺诈和不道德行为[23][38]。基于上述结论,并结合现实中“外卖小哥在电梯里急哭了”和逆行违章等现象,我们可以总结到,在外卖市场中,虽然商品性质和商业逻辑并不一样,但平台也需要综合骑手们的配送努力程度,配送能力的差异性,以及他们在进行运力供给决策中的前瞻行为等综合因素,非常谨慎地制定出有助于降低骑手收入不确定性和提升平台整体服务能力的最佳的考核周期。

(5)多层次多属性绩效评估

除了上述直接根据“超时率”和“完单量”评估骑手绩效的指标,平台应该建立基于综合服务质量、配送效率和安全保障等多属性的多层次骑手绩效评估体系。当前,系统为骑手设置的积分等级体系是直接基于完单量、准时率或者顾客评价奖励积分[51],可以进一步提升骑手们的安全保障、违章记录、以及公益活动等有助于建设外卖生态体系的多个属性的重要性。

评估体系可以尝试根据政府部门监管法规和平台发展目标为不同评估指标设定优先级,其中,遵守交通安全法规应该成为外卖配送的基本要求。

洞察:在多层次多属性绩效评估体系的设计过程中,在第一层次,考虑到遵守交通安全法规是外卖配送的基本要求,那么,骑手的“违章率”就需要摆在优先级最高的位置,在一定的考核期内,如果骑手的“违章率”超过了阈值,则该骑手将被“一票否决”,不会进入到下一层次的绩效评估;在第二层,维持并且提升市场占用率可能是当前平台运营的关键目标,那么,骑手们的“完单量”可以摆在优先级次高的位置,在对“完单量”合理划分不同等级的奖励区间之后,各骑手再根据实际“完单量”进入相应的评估区间;最后,在特定的基于“完单量”的评估区间内,机制再综合服务质量和顾客评价等属性设定奖励金额。另外,平台可能需要同时实现“违章率”、“日成交单量”和“超时率”等多个关键绩效的管理目标,对此多属性绩效目标导向的决策问题,平台不仅需要考虑到实际绩效水平和管理目标的不确定性,还需要关注多个绩效指标之间的相关性(例如,严格控制“违章率”会减少当前的“日成交单量”)对绩效评估体系的影响[25]。

(6)多向评分反馈

外卖市场主要是由顾客、平台、商家和骑手共同建立起来的生态圈,当前系统采取的是顾客给商家或者骑手的单向评分方式,忽视了骑手们的重要作用。平台可以建立起“多向”评分反馈系统,其中,顾客给商家和骑手分别评分,顾客对商家的菜品健康和口味等进行反馈,对骑手的派送服务进行反馈;骑手也可以自由选择给商家评分,反馈商家出餐及时性等信息;更进一步地,骑手还可以给顾客评分,反馈订单交付难度和顾客接单态度等信息。

与此同时,平台根据商家、顾客和骑手们的权力和义务,并综合天气、路况和其它不可控因素等,设定公平合理的判责系统。

洞察:在实际商业场景中,例如,网约车市场,不仅乘客可以给司机评分,司机也可以向乘客评分。本质上而言,建立多方评分反馈系统(multi-lateral rating systems)的核心目的是增强在线市场中各参与方之间的信任度[12],降低各参与方之间的信息不对称性[17],从而“驱逐”低质量的参与方,并且降低交易成本。为此,平台需要认真思考两个重要问题:一方面,相比于传统的单向评分反馈系统,多向评分反馈系统是否真的会提升市场效率和社会福利?另一方面,由于参与方做出准确的评分是基于自愿且需要付出成本的,在平台没有提供适当奖励的情况下,作为公共产品的用户评分将会供给不足[2];因此,如果采取多向评分反馈系统,平台应该如何激励尽可能多的参与方真实地披露信息并给出可信的评分结果?关于第一个问题,以共享经济商业模式为背景的理论研究表明,相比于仅有顾客的单向评分,顾客和服务提供者之间的双向评分将弱化服务提供者之间的竞争,从而提高市场的均衡价格[17];另外,在一定条件下,双向的评分机制将会提升社会福利[26]。关于第二个问题,平台需要合理设计向各参与方展示彼此评分结果的方式和时间:如果平台在参与方完成评分之后立刻披露结果,那么,相关的被评价方可能在后续采取报复动作,故意压低对方的评分,从而导致顾客评分的“失真”[6];但是,如果平台在双方或者多方都完成评分或者允许评分的时间窗结束之后才披露结果,那么,这种策略将会显著降低评分者进行报复的可能性,并且增加评分的真实性和供给量[13]。

2、运营流程和算法

以上从骑手激励机制方面介绍了外卖平台设计的改进方向,本节将聚焦运营流程和算法设计等社会各界正在热烈讨论的话题。算法本身是中性的,而其蕴含的思想和流程则是由平台的商业逻辑和商业目标决定的,在平台设计中,平台可以进一步让运营流程和算法的目标或者逻辑更加兼顾顾客、骑手和平台等多参与方的目标,提升社会的整体福利水平。

为此,根据通常的外卖配送流程,我们分别提出针对顾客端、骑手端和平台端的运营和算法改进方案,包括餐馆推荐系统、预计送达时间预测算法、派单算法、路径规划算法、算法参数管理、以及基础设施建设等六点建议。

(1)顾客端:餐馆推荐系统

平台可以在实时餐馆推荐系统的设计中采用更多与应用场景相关、反映实时供需情况和骑手空间分布的数据。例如,针对一个商家,如果过去 1个小时的骑手等待时间较短、当前周边分布的骑手较多、店内聚集的正在等待取餐的骑手较少、或者正在准备的订单数量较少等,在其它属性相近的条件下,那么,该商家在推荐排序算法的输出结果中可以被优先推荐。

推荐系统还可以根据实时已有订单的餐馆和骑手位置进行拼单推荐,实现外卖的“顺风车”。例如,如果一位骑手正在顾客周边的商家等待取单,而且预估取餐时间较长,那么,即使该商家不是距离顾客最近或者价格最低,推荐系统也可以在一定程度上提高该商家的推荐权重和优先级。

洞察:在当前实现的推荐系统中,算法输入的应用场景数据至少由三大类组成[44]:一是用户画像,例如,性别、常驻地、价格偏好、食物偏好等;二是食物画像,包含商家、外卖、团单(即团购订单),其中,商家特征包含商家价格、商家好评数、商家地理位置等,外卖特征包含平均价格、配送时间和销量等,团单特征包含适用人数和返购率等;三是场景画像,包含用户当前所在地、时间、定位附近商圈、基于用户的上下文场景信息等。如果基于上述方案改进餐馆推荐系统,系统可以采用基于在线优化(online optimization)和增强学习(reinforcement learning)的算法,实时更新客户端的餐馆推荐结果,最终将餐馆推荐系统打造成调节市场供需平衡状态的重要工具之一。另外,关于实现外卖的“顺风车”,类似思想已经在网约车市场中实现,目的是希望通过将目的地相近或者顺路的订单整合在一起,从而提升配送资源的利用率,其中,需要同时解决订单与骑手的双边匹配问题、以及针对“顺风车”订单的配送费定价问题[19][17]。

(2)顾客端:预计送达时间预测算法

预计送达时间预测算法可以融合来自骑手的手机 GPS 实时定位数据、手机运动传感器移动数据、和安卓操作系统特定应用程序搜集的活动识别数据等多源异质数据集[28],识别骑手在不同时刻所处的活动状态以及状态改变的时间点。这将有助于提升订单交付时间的预测准确性,尤其是和楼层高度、小区内配送和顾客交付相关的时间。同时,为了明确商家和骑手的责任,并且方便顾客对商家和骑手进行公平的评分,平台应该分别预测、显示和评估“商家出餐时间”和“骑手送餐时间”。

洞察:在外卖配送场景中,预计送达时间(ETA)是用户成功下单时刻到骑手将外卖送达到顾客手中的送达时间预测结果,具体可以分解为压单时间(从商家接单到骑手接单)、到店时间(从骑手接单到骑手到店)、取餐时间(从骑手到店到骑手取餐)、送餐时间(从骑手取餐到到达用户)、以及交付时间(从到达用户到完成送达),此过程还包含了出餐时间(从商家接单到商家出餐)[45]。关于骑手送餐时间,一个最大的技术性挑战,也是目前网友们激烈讨论的实际问题是对交付时间的预估,即骑手到达用户附近下车后多久能送到用户手中:一方面,老旧小区没有电梯、或者写字楼难以等到电梯等现实问题给骑手们快速交付订单带来困难;另一方面,在进行交付时间预估时,算法的输入字段较少,重要的维度特征仅包括交付地址(文本数据)、交付点的经纬度、区域、以及城市[48]。对此,如果基于手机GPS实时定位数据、手机运动传感器移动数据(motion sensor data)、以及安卓操作系统ActivityRecognitionClient API搜集的活动识别数据(activity recognition data)等改进ETA预测算法,平台将更清晰地识别骑手运动状态,例如,电动车骑行中、步行中、奔跑中或者原地等待中等,然后采用深度学习方法进行序列建模(sequence modeling),实现对ETA尤其是交付时间的更准确地预测。

(3)骑手端:派单算法

在派单过程中,派单算法应当考虑骑手之间的订单负载均衡,让不同骑手当前累积分配到的订单数量相对比较平均,避免出现个别骑手承载过大的配送任务、而有些骑手被闲置的局面。同时,派单算法还应当考虑骑手在当地区域的熟知程度和配送经验等有助于提升派单效率的多种因素。

洞察:实时派单算法是智能配送系统中的重要组成部分,当前的实时派单问题被描述为以离散马尔可夫决策过程(Markov Decision Process)为核心的动态随机优化问题,其目标是一段时间内的顾客体验(例如,准时率)和骑手效率(例如,单均行驶距离或者单均消耗时间)等指标最优,算法需要计算动态到达的订单分配给骑手的策略、以及每个骑手后续的节点访问顺序(即路径规划,routing optimization)[49]。在对该问题进行合理建模和算法优化之后,派单算法可以实现骑手订单负载均衡(workload balance)和融合骑手当地区域知识和配送经验。对此,建模人员可以通过在目标函数中引入“最大化所有骑手的最小订单负载”(maxmin)或者“最小化所有骑手的最大订单负载”(minmax)的方式进行调整。另外,派单算法引入骑手在当地区域的熟知程度和配送经验等因素,这不仅意味着 ETA 的预测算法需要纳入骑手在当地区域的熟知程度和配送经验等重要指标,也意味着派单算法需要考虑骑手们之间在这两个维度上的差异性。综合以上因素,由多目标优化算法(multi-objective optimization)给出满足多个目标的最佳派单结果[21]。

(4)骑手端:路径规划算法

与派单算法紧密关联的是路径规划算法,算法应该引入与实际路况更为贴切的特征,例如,单行道、限行、机动车道和非机动车道,以及交通管制和交通拥堵等,并且根据实时信息进行调整。

洞察:针对骑手路径规划的问题,平台需要建立基于有向图的实时动态路径规划模型,输入该模型的可行路径集合(set of feasible routes)需要根据离线信息进行缩小[33],例如,许多单行道、限行路线和过街天桥不允许电动车经过的路线就应该作为强约束从集合中剔除;另外,该集合还需要根据实时信息进行调整,例如,出现严重交通拥堵或者临时交通管制的路线也应该被剔除。同时,面对随机的订单需求和配送时长,该问题可以考虑借鉴离线-在线近似动态规划算法[30] (offline-online approximate dynamic programming)或者在线再优化策略[5](online re-optimization strategy)的思想进行求解。

(5)平台端:算法参数管理

平台端对算法参数进行及时审核并且合理设置是解决外卖骑手困境的关键之一,在此应该得到重点关注。这个问题起源于平台在预测订单“预计送达时间”探索实践中的模型迭代过程:在实际的ETA预估场景下,算法的损失函数设计是以“整体的预估结果能够尽量前倾”为目的,而且对于迟到部分会增加数值惩罚[47],这意味着算法在不断“逼迫”骑手缩短实际送达时间,而骑手每一次成功避免超时的历史记录都会让算法“学习”到可能更短的送达时间,即便这个送达时间是骑手通过闯红灯、逆行等违反交通规则甚至冒着生命危险的方式实现的。基于此逻辑,这些历史数据会进一步提高算法对骑手送达时间的“期待”,从而使算法朝着缩短送达时间的方向进行要求和优化。

对此,平台应该通过对实际送达时间等算法的参数进行及时审核和调整以终止上述的恶性循环,也就是赋予算法“底线思维”。遵守交通法规和维护行人安全是不可逾越的底线,是数据预处理环节进行历史数据清洗和校正必须考量的因素,是数学模型中的“硬约束条件”,也是优化算法剔除不可行路径中必须满足的规则。这也意味着订单送达时间应该存在着一个合理的、无法通过算法不断优化而逾越的下界,否则,不管在任何激励机制和评分体系之下,缺乏“底线思维”的算法流程会一直将骑手困在系统之中。

(6)平台端:基础设施建设

针对最后 100米配送问题,平台可以尝试自建或者联合第三方物流公司建设外卖取餐柜[52]。取餐柜的候选位置可以是办公场所、写字楼、医院以及高校,而顾客可以选择线上下单、线下取餐。

洞察:考虑到取餐柜的选址将会影响顾客线上下单、线下取餐(buy-online-pick-up-in-facility)的便利性,平台可以进行两阶段的取餐柜网络设计优化:在第一阶段,平台可以结合各个区域的人口社会统计、经济发展、历史完单、以及配送时长等多维度数据建立机器学习模型和计量经济学模型以预测各区域的潜在需求和建立取餐柜对需求的影响[15];在第二阶段,平台可以建立取餐柜设施选址(facility location optimization)和骑手服务区划分(service region allocation optimization)的多阶段随机规划模型(multi-stage stochastic programming),联合优化取餐柜的位置和骑手的派单服务策略。

除此之外,在需求量较大的办公楼、小区、学校和医院等场所,平台也可以考虑配备专职的终端派送人员,一方面是因为终端配送人员对小区周边和电梯设备更加熟悉,可以帮助降低因骑手对环境陌生而造成的顾客等待时间,另一方面是能够实现对局部区域的订单统一管理和配送、从而避免骑手的重复劳动。

洞察:配备专职终端人员在提升平台整体运营效率的同时也会增加平台的运营成本,需要进行深入的成本-效益分析。分析框架可以将配送过程视为一个排队系统 (queueing system)[32],在指定场所配备专职的终端配送人员将会增加固定人力成本,但是,值得关注的是,根据排队论,配送骑手的每单的平均派送时间和顾客的等待时间等系统的服务质量指标之间存在着强烈非线形的关系,这意味着通过配备专职终端人员以适当降低骑手们在这些场所所花的派送时间可能会带来系统服务质量指标的显著提高,从而使得带来的配送效益可能会高于额外的人力成本。

在未来,平台还可以推广使用机器人和无人机配送。同时,作为互联网公司,平台可以通过在相关核心技术的资本投入和技术积累,转型成为高科技公司。实际上,美团已经开始尝试无人车和无人机的配送:在 2月份疫情期间,外卖平台利用无人配送车为北京市顺义区几个小区的居民做订单配送,截至 9 月初,平台已经累计使用无人车配送了超过6000多用户实际订单,覆盖该站点超过80%的订单需求;目前,平台也在深圳等地进行无人机的运营测试[53]。

洞察:在设计无人车辅助的配送系统中,面对无人车配送和骑手配送的两种模式,考虑到无人车的在成本方面的优势和在灵活性方面的不足,平台可以基于实际配送场景、市场供需状态、以及交通路况,采用马尔可夫决策过程联合优化无人车和骑手之间的分配比例、以及无人车和骑手的配送路线[29]。

3。 供需调节机制

在实际的运营中,外卖平台可以尝试对配送价格进行调整以调节市场供需。平台可以根据配送距离和配送时段等诸多因素合理设计基础的派送价格和骑手端补贴;另外,平台也可以针对突变的供需情况,实时调整骑手的配送费用来缓解供需不平衡的问题[46][36]。

其实,作为企业收益管理的重要工具,动态定价已经在多个行业得到广泛使用,包括在上个世纪 80 年代开始得到采纳的航空业、90 年代开始得到采纳的酒店业和租车业[31]、以及当前新兴的共享出行行业[3]。

在外卖行业,平台面临的市场供需不协调的问题更加突出,而且市场供需状态随时间变化剧烈。采取不同形式的配送价格可以区分顾客对等待时间的实际需求和时间敏感性,这对提高和使用供需弹性,缓解供不应求带来的负面影响具有一定积极作用;然而,基于配送价格的动态定价机制并不能解决所有问题,无论是在现实生活还是学术研究中仍然存在争议,这依赖于平台对该策略的价值进行更加深入的探究。

(1)基于区域和时间段的时空动态定价

在调节市场供需平衡状态的过程中,平台可以针对每笔订单的配送费实行基于配送区域、下单时间或者送达时间的动态定价,并且对愿意等待的顾客提供愿等打折。

洞察:基于区域和时间段的时空动态定价(dynamic & surging pricing)通常可以分为“乘积溢价”(multiplicative surge)和“加和溢价”(additive surge)两类:在特定区域和时间段内,前者是指在基础价格上乘以一定倍数(例如,1.5倍),美国的网约车平台Uber早期就是使用该类溢价策略;而后者是指在基础价格上加上与距离无关的常数(例如,10元),这是 Uber 平台当前采用的最新溢价策略。研究表明,在供需动态变化的环境下,相比于乘积溢价策略,加和溢价策略是激励相容 (incentive-compatible) 的定价机制[14],这为外卖平台设计基于配送费的实时动态定价策略提供了新的方向。值得提醒的是,实时动态定价策略在社会各界中仍然存在争议,理论研究结果显示,在共享出行市场的背景下,理性的乘客和司机会策略性地等待更合适的价格或者收入,如果市场状态比较平稳,那么,平台没有必要采用实时动态定价策略,尤其是该策略可能造成乘客、司机、监管者之间对立的局面[9]。

(2) 顾客灵活充值账户

为了弥补实时动态定价在区分顾客对等待时间的实际需求和时间敏感性方面的不足,平台可以建立灵活的用户充值账户:在高峰期时段,如果需要外卖尽快送到,顾客可以向个人在平台上的账户充入额外的金额,这些资金并不会流入骑手或者平台,而是作为用户的充值余额,可以在低峰期时段点餐使用。

洞察:顾客在高峰时段的充值行为将传递出其对派送的等待时间比较敏感的信号,作为系统派单算法的依据,并且,顾客在低峰期使用账户余额订餐,可以激发低峰时段的整体需求,充分利用低峰期时段闲散的备餐和配送资源,发挥平滑市场需求的作用。针对网约车市场的研究结果表明,在一定条件下,合理设计用户充值账户机制 (integrated reward scheme with surge pricing) 可以实现多方共赢,提升顾客、司机和平台的整体社会福利[37]。

(3)增加兼职和众包骑手

平台提升兼职和众包骑手的运力占比有助于提高运力调整的空间和弹性,从而更有效的调节市场的供需平衡状态。

洞察:平台的骑手分为专送全职骑手和众包兼职骑手,前者的工作时间固定并且接受系统派单,后者灵活决定工作时间并且可以有限次拒绝派单[51]。为了提升整体的运力供给,尤其是满足高峰期时段的配送需求,平台通常会采用现金奖励的方式补贴骑手。实证研究表明,在网约车市场中,平台补贴将会从劳动者是否选择工作和工作时长两个维度影响劳动力供给,而且,兼职劳动者的收入供给弹性 (supply elasticity) 更高[24]。这意味着外卖平台需要更加严密地研究骑手们的运力供给行为,分析骑手们对期望收入水平发生变化而进行的运力供给调整,然后合理设计平台上全职骑手和兼职骑手的比例,并精准地向骑手、尤其是兼职骑手提供补贴奖励。

4。 政府监管

精准的政府监管对外卖行业实现可持续健康发展至关重要。深入而全面地理解平台的商业逻辑和运营流程有助于制定高效精准的监管措施,这不仅依赖于平台向监管者真实而全面地披露公司运营相关的信息,也依赖于监管部门联合第三方专业研究机构共同完成对信息的分析和总结[8]。基于全面而系统的专业分析之后,监管者再对平台和骑手的劳资关系、运营过程中的资质审核和监管、以及平台责任以法律法规形式进行统一规范。

(1)明晰劳资关系

相关部门需要加快出台法律法规,明晰包括外卖骑手在内的自由职业者与共享经济/零工经济平台之间的劳资关系,对全职骑手与兼职骑手的法律地位进行清晰的分类,界定相应的权利和义务[16]。

洞察:针对相关的劳资关系,国家发展改革委于2020年7月14日发布文件要求,强化灵活就业劳动权益保障,探索适应跨平台、多雇主间灵活就业的权益保障、社会保障等政策[40]。作为参考,2019年9月18日,美国加州正式签署了AB5法案[7],并于2020年1月1日正式生效。该法案要求将临时合同工(例如,网约车司机)纳入雇主的正式受雇员工,这意味着相关企业的业务成本(例如,最低工资、保险和员工福利等)将大幅增加,并将影响公司的员工管理机制和定价机制。实际上,为了满足该法案的要求,从2020年7月9日开始,Uber平台已经开始允许司机自己根据服务时间和距离设定价格[27]。目前,围绕AB5法案、以及自由职业者与平台之间的劳资关系仍然存在非常大的争议,一部分学者建议创立一个新的、介于雇员和合同工之间的第三类工作类别,该类别将保留自由职业者的一部分工作灵活度,同时,赋予他们部分全职雇员可以享受到的福利待遇[16][35]。

(2)加强资质审核和运营监督

交管、人社、应急管理等相关部门应当督促和加强对平台和骑手的资质审核和安全培训。在劳动者申请加入平台过程中,平台需要对骑手电动车的准入标准进行统一登记管理;与此同时,加强对平台运营流程的监督,比如,可以借助骑手 APP 的渠道对平台的配送路径规划等算法进行监管审查,严禁对骑手提供违反交通规则(例如,逆行)的推荐路线;相关部门还可以对平台上骑手每天的连续配送时长设置上限并进行合理监督,避免出现因为骑手疲劳工作而造成的交通事故。

(3)明确平台责任

在对涉及快递和外卖行业的道路交通安全进行监管的过程中,监管部门应该把平台所属骑手发生的交通事故和违章次数、以及相应后果的严重程度作为对平台重要的监管指标,按月度或者季度等进行考核和追责,从而督促平台和骑手共同维护配送安全。

针对已经发生的交通事故,已有的法院判决为相关的责任划分提供了具有现实意义的指导。近日,关于浙江省湖州市吴兴区的外卖骑手撞伤行人一案,法院最后宣判,外卖骑手虽然没有与平台签订法律劳务合同,但对外是以“平台网上订餐配送”的名义为客户提供服务,且在提供配送服务时受平台管理制度的约束,报酬由平台发放,因此,无论是否与公司签合同,在其接受配送任务后均与配送平台建立了雇佣关系,在送餐中发生事故,作为雇主的公司应承担赔偿责任[41]。这一结果无疑明确了外卖平台必须加快运营管理流程的调整,以保障骑手安全和行人安全。

(4)市场竞争与政府干预

监管部门需要在遵循平台竞争规律和市场调节作用的条件下制定提升社会福利的监管法规。在市场经济环境下,平台之间的自由竞争将会影响平台选择最优的骑手激励机制以及运营流程和算法。但是,竞争形成的市场结果并不一定能够实现社会各参与方的福利最大化,可能陷入“囚徒困境”的局面。

例如,如果一个平台没有严格遵守法规制度,漠视骑手权益,那么,为了维持甚至扩大市场份额和利润,其竞争对手很有可能也不会选择严格遵守法规制度和提升骑手权益。为此,监管部门应该充分考虑多平台竞争的市场环境,以问题为导向制定相关法规,一视同仁地对所有平台进行严格的监管。

洞察:平台之间的市场竞争虽然会有助于提升市场效率,但在一定的情况下,也有可能出现市场失灵,竞争无法达到最优的纳什均衡(Nash equilibrium)。对此,监管者可以考虑根据博弈论(game theory)和机制设计(mechanism design)的理论和工具来刻画骑手、顾客、商家和多个平台之间的交互行为,并研究市场中的平台竞争结果[1]。特别是针对竞争的外部性(externalities)可能导致出现的市场失灵的情况,监管部门需要考虑相应的监管制度规则以引导相互竞争的平台向更有利于提升社会福利的方向发展。

总结

作为致力于大数据,运筹学,以及人工智能方法在智慧城市领域应用的学者和研究者,我们从平台设计运营和政府监督监管两方面为解决外卖骑手困境提供了可能的解决方案,探讨了骑手激励机制、运营流程和算法、供需调节机制等平台可以采取的运营策略,并分析了明晰劳资关系、加强资质审核和运营监督、明确平台责任、以及市场竞争与政府干预等监管者面临的挑战。

构筑健康、温暖、高效、可持续并且具有社会责任的外卖生态体系,需要我们从社会伦理、法律制度以及经济学和管理学原理出发,融合大数据技术和人工智能算法等工具,充分满足不同目标下多参与方的核心利益。

最终,让每一方都释放出最大的善意以实现共赢,只有这样才能提升社会整体的福利水平,让人们真正享受到科技为生活带来的便利。

作者简介:

王海:清华大学学士,麻省理工学院运筹学博士,现为新加坡管理大学决策分析方向助理教授,美国卡内基梅隆大学信息系统与公共政策学院访问教授;研究方向为运筹学,大数据,优化算法,以及人工智能的方法论及其在智慧城市场景的应用;主要领域包括智能交通,共享经济,智慧物流,以及智慧医疗等。个人主页,http://wang-hai.net/

孙昊:华中科技大学学士,清华大学管理科学与工程博士,现为香港大学经济及工商管理学院博士后;研究方向为银行与金融中介,在线市场设计,统计学习方法与应用;主要领域包括金融科技与创新,共享经济等。

参考文献:

[1] Ahmadinejad, AmirMahdi, Hamid Nazerzadeh, Amin Saberi, Nolan Skochdopole, and Kane Sweeney。 (2019)。 Competition in ride-hailing markets。 Available at SSRN 3461119。

[2] Avery, Christopher, Paul Resnick, and Richard Zeckhauser。 (1999)。 The market for evaluations。 American Economic Review , 89(3),564-584。

[3] Bai, Jiaru, Kut C。 So, Christopher S。 Tang, Xiqun (Michael) Chen, and Hai Wang。 (2019)。 Coordinating supply and demand on an on-demand service platform with impatient customers。 Manufacturing & Service Operations Management , 21(3), 556-570。

[4] Basu, Amiya K。, Rajiv Lal, V。 Srinivasan, and Richard Staelin。 (1985)。 Salesforce compensation plans: An agency theoretic perspective。 Marketing Science , 4(4), 267-291。

[5] Bertsimas, Dimitris, Patrick Jaillet, and Sébastien Martin。 (2019)。 Online vehicle routing: The edge of optimization in large-scale applications。 Operations Research , 67(1), 143-162。

[6] Bolton, Gary, Ben Greiner, and Axel Ockenfels。 (2013)。 Engineering trust: reciprocity in the production of reputation information。 Management Science , 59(2), 265-285。

[7] California Legislative Information。 Assembly Bill No。 5。 September 18, 2019。 https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=201920200AB5。

[8] Calo, Ryan, and Alex Rosenblat。 (2017)。 The taking economy: Uber, information, and power。 Columbia Law Review , 117, 1623。

[9] Chen, Yiwei, and Ming Hu。 (2020)。 Pricing and matching with forward-looking buyers and sellers。 Manufacturing & Service Operations Management , 22(4), 717-734。

[10] Chung, Doug J。, Das Narayandas, and Dongkyu Chang。 (2020) The effects of quota frequency: Sales performance and product focus。 Management Science 。

[11] de Figueiredo Jr, Rui JP, Evan Rawley, and Orie Shelef。 (2019)。 Bad bets: Nonlinear incentives, risk, and performance。 Strategic Management Journal 。 https://doi.org/10.1002/smj.3111

[12] Einav, Liran, Chiara Farronato, and Jonathan Levin。 (2016)。 Peer-to-peer markets。 Annual Review of Economics , 8, 615-635。

[13] Fradkin, Andrey, Elena Grewal, and David Holtz。 (2020)。 Reciprocity in two-sided reputation systems: Evidence from an experiment on Airbnb。 Working Paper, MIT Sloan School of Management。 https://andreyfradkin。 com。

[14] Garg, Nikhil, and Hamid Nazerzadeh。 (2019)。 Driver surge pricing。 arXiv preprint arXiv:1905.07544。

[15] Glaeser, Chloe Kim, Marshall Fisher, and Xuanming Su。 (2019)。 Optimal Retail Location: Empirical Methodology and Application to Practice: Finalist–2017 M&SOM Practice-Based Research Competition。 Manufacturing & Service Operations Management , 21(1), 86-102。

[16] Hagiu, Andrei, and Julian Wright。 (2019)。 The status of workers and platforms in the sharing economy。 Journal of Economics &Management Strategy , 28(1), 97-108。

[17] Ke, Jintao, Hai Yang, Xinwei Li, Hai Wang, and Jieping Ye。 (2020)。 Pricing and equilibrium in on-demand ride-pooling markets。 Transportation Research Part B: Methodological 139: 411-431。

[18] Ke, T。 Tony, Baojun Jiang, and Monic Sun。 (2017)。 Peer-to-peer markets with bilateral ratings。 In MIT Sloan Research Paper No。 5236-17; NET Institute Working Paper No (pp。 17-101)。

[19] Li, Ruijie, Yu (Marco) Nie, and Xiaobo Liu。 (2020) Pricing carpool rides based on schedule displacement。 Transportation Science 54(4):1134-1152。

[20] Liu, Sheng, Long He, and Zuo-Jun Max Shen。 (2018)。 On-time last mile delivery: Order assignment with travel time predictors。 Management Science 。

[21] Lyu, Guodong, Wang Chi Cheung, Chung-Piaw Teo, and Hai Wang。 (2019)。 Multi-objective online ride-matching。 Working paper, National University of Singapore。 Available at SSRN 3356823。

[22] Morduch, Jonathan。 (1995)。 Income smoothing and consumption smoothing。 Journal of Economic Perspectives , 9(3), 103-114。

[23] Schweitzer, Maurice E。, Lisa Ordóez, and Bambi Douma。 (2004)。 Goal setting as a motivator of unethical behavior。 Academy of Management Journal , 47(3), 422-432。

[24] Sun, Hao, Hai Wang, and Zhixi Wan。 (2019)。 Model and analysis of labor supply for ride-sharing platforms in the presence of sample self-selection and endogeneity。 Transportation Research Part B: Methodological , 125, 76-93。

[25] Tsetlin, Ilia, and Robert L。 Winkler。 (2007)。 Decision making with multiattribute performance targets: The impact of changes in performance and target distributions。 Operations Research , 55(2), 226-233。

[26] Tunc, Murat M。, Huseyin Cavusoglu, and Srinivasan Raghunathan。 (2019)。 Two-sided adverse selection and bilateral reviews in sharing economy。 Available at SSRN 3499979。

[27] Uber Blog。 California drivers: Set your own fares when you drive with Uber。 June 25, 2020。

https://www.uber.com/blog/california/set-your-fares/。

[28] Uber Engineering。 How trip inferences and machine learning optimize delivery times on Uber Eats。 (2018)。 https://eng.uber.com/uber-eats-trip-optimization/。

[29] Ulmer, Marlin W。, and Barrett W。 Thomas。 (2018)。 Same-day delivery with heterogeneous fleets of drones and vehicles。 Networks ,72(4), 475-505。

[30] Ulmer, Marlin W。 Justin C。 Goodson, Dirk C。 Mattfeld, and Marco Hennig。 (2019)。 Offline–online approximate dynamic programming for dynamic vehicle routing with stochastic requests。 Transportation Science , 53(1), 185-202。

[31] Wall Street Journal。 (2015)。 Now prices can change from minute to minute。 December 14, 2015.https://www.wsj.com/articles/now-prices-can-change-from-minute-to-minute-1450057990。

[32] Wang, Hai, and Amedeo Odoni。 (2016)。 Approximating the performance of a “last mile” transportation system。 Transportation Science , 50(2), 659-675。

[33] Wang, Hai。 (2019)。 Routing and scheduling for a last-mile transportation system。 Transportation Science , 53(1), 131-147。

[34] Wang, Hai, and Hao Sun。 (2020)。 Peak-hour incentive design with strategic driver behavior。 Singapore Management University, working paper。

[35] Wang, Hai, and Hao Sun。 (2020)。 The optimal labor supply flexibility on ride-sharing platforms。 Singapore Management University, working paper。

[36] Wang, Hai, and Hai Yang。 (2019)。 Ridesourcing systems: A framework and review。 Transportation Research Part B: Methodological , 129, 122-155。

[37] Yang, Hai, Chaoyi Shao, Hai Wang, and Jieping Ye。 (2020)。 Integrated reward scheme and surge pricing in a ridesourcing market。 Transportation Research Part B: Methodological , 134, 126-142。

[38] Zoltners Andris A, PK Sinha, and Sally E。 Lorimer。 (2016)。 Wells Fargo and the slippery slope of sales incentives。 Harvard Business Review 。 (September), https://hbr.org/2016/09/wells-fargo-and-the-slippery-slope-of -sales-incentives。

[39] 滴滴出行。 滴滴专车司机作弊违规处罚标准。 2019 年 04 月 24 日。 https://www.eycen.com/post/545.html。

[40] 发展改革委网站。 关于支持新业态新模式健康发展 激活消费市场带动扩大就业的意见。 2020 年 07 月 14 日。 https://www.ndrc.gov.cn/xxgk/zcfb/tz/202007/t20200715_1233793_ext.html。

[41] 金融界。 浙江湖州外卖骑手撞伤行人,法院判未签劳动合同的平台需担责。 2020 年 09 年 15 日。

https://baijiahao.baidu.com/s?id=1677901965178599201&wfr=spider&for=pc。

[42] 京东。 什么是退换货运费险?2019 年 12 月 10 日。 https://help.jd.com/user/issue/430-499.html

[43] 美团研究院。 新时代 新青年:2018 年外卖骑手群体研究报告。 2019 年 1 月 17 日。

https://s3plus.meituan.net/v1/mss_531b5a3906864f438395a28a5baec011/official website/c21d0443-decf-41d5-9813-ef8eaa6516d0。

[44] 美团技术团队。 深度学习在美团推荐平台排序中的运用。 2017 年 07 月 28 日。 https://tech.meituan.com/2017/07/28/dl.html。

[45] 美团技术团队。 即时配送的 ETA 问题之亿级样本特征构造实践。 2017 年 11 月 24 日。

https://tech.meituan.com/2017/11/24/gbdt.html。

[46] 美团技术团队。 美团外卖骑手背后的 AI 技术。 2018 年 03 月 29 日。 https://tech.meituan.com/2018/03/29/herenqing-ai-con.html。

[47] 美团技术团队。 深度学习在美团配送 ETA 预估中的探索与实践。 2019 年 02 月 21 日。

https://tech.meituan.com/2019/02/21/meituan-delivery-eta-estimation-in-the-practice-of-deeplearning.html。

[48] 美团技术团队。 配送交付时间轻量级预估实践。 2019 年 10 月 10 日。 https://tech.meituan.com/2019/10/10/distribution-time-prediction-practice.html。

[49] 美团技术团队。 美团智能配送系统的运筹优化实战。 2020 年 02 月 20 日。 https://tech.meituan.com/2020/02/20/meituan-delivery-operations-research.html。

[50] 青年报。 快递、外卖行业交通事故频发 去年 117 起事故致 9 死 134 伤。 2018 年 02 月 10 日。

http://app.why.com.cn/epaper/webpc/qnb/html/2018-02/10/content_51905.html。

[51] 人物。 外卖骑手, 困在系统里。 2020 年 9 月 8 日。 https://mp.weixin.qq.com/s/Mes1RqIOdp48CMw4pXTwXw。

[52] 搜狐网。 高校为什么要布局智能外卖柜?对学校有什么好处。 2019 年 6 月 21 日。

https://www.sohu.com/a/322101528_120167191。

[53] 中国日报中文网。 美团夏华夏:不断深化现实物理场景应用 美团 AI 助力产业智能化转型。 2020 年 9 月 8 日。http://cn.chinadaily.com.cn/a/202009/08/WS5f56f6faa310084978423e53.html。


如何用JAVA设计一个亿级消息量的 IM 系统

技术交流大兴 发表了文章 • 0 个评论 • 45 次浏览 • 2020-09-11 11:01 • 来自相关话题

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此... ...查看全部

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此时,一个能够快速迭代、方便扩展的系统才是一个好的系统。

 

IM核心概念

用户:系统的使用者

消息:是指用户之间的沟通内容。通常在IM系统中,消息会有以下几类:文本消息、表情消息、图片消息、视频消息、文件消息等等

会话:通常指两个用户之间因聊天而建立起的关联

群:通常指多个用户之间因聊天而建立起的关联

终端:指用户使用IM系统的机器。通常有Android端、iOS端、Web端等等

未读数:指用户还没读的消息数量

用户状态:指用户当前是在线、离线还是挂起等状态

关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等。这里需要注意与会话的区别,用户只有在发起聊天时才产生会话,但关系并不需要聊天才能建立。对于关系链的存储,可以使用图数据库(Neo4j等等),可以很自然地表达现实世界中的关系,易于建模

单聊:一对一聊天

群聊:多人聊天

客服:在电商领域,通常需要对用户提供售前咨询、售后咨询等服务。这时,就需要引入客服来处理用户的咨询

消息分流:在电商领域,一个店铺通常会有多个客服,此时决定用户的咨询由哪个客服来处理就是消息分流。通常消息分流会根据一系列规则来确定消息会分流给哪个客服,例如客服是否在线(客服不在线的话需要重新分流给另一个客服)、该消息是售前咨询还是售后咨询、当前客服的繁忙程度等等

信箱:本文的信箱我们指一个Timeline、一个收发消息的队列

 

读扩散 vs 写扩散

读扩散

我们先来看看读扩散。如上图所示,A与每个聊天的人跟群都有一个信箱(有些博文会叫Timeline),A在查看聊天信息的时候需要读取所有有新消息的信箱。这里的读扩散需要注意与Feeds系统的区别,在Feeds系统中,每个人都有一个写信箱,写只需要往自己的写信箱里写一次就好了,读需要从所有关注的人的写信箱里读。但IM系统里的读扩散通常是每两个相关联的人就有一个信箱,或者每个群一个信箱。

读扩散的优点:

写操作(发消息)很轻量,不管是单聊还是群聊,只需要往相应的信箱写一次就好了

每一个信箱天然就是两个人的聊天记录,可以方便查看聊天记录跟进行聊天记录的搜索

读扩散的缺点:

读操作(读消息)很重

写扩散

接下来看看写扩散。

e38c316470c48ab4e7f8492ec20398672f5e14.jpg.png

在写扩散中,每个人都只从自己的信箱里读取消息,但写(发消息)的时候,对于单聊跟群聊处理如下:

单聊:往自己的信箱跟对方的信箱都写一份消息,同时,如果需要查看两个人的聊天历史记录的话还需要再写一份(当然,如果从个人信箱也能回溯出两个人的所有聊天记录,但这样效率会很低)。

群聊:需要往所有的群成员的信箱都写一份消息,同时,如果需要查看群的聊天历史记录的话还需要再写一份。可以看出,写扩散对于群聊来说大大地放大了写操作。

写扩散优点:

读操作很轻量

可以很方便地做消息的多终端同步

写扩散缺点:

写操作很重,尤其是对于群聊来说

注意,在Feeds系统中:

写扩散也叫:Push、Fan-out或者Write-fanout

读扩散也叫:Pull、Fan-in或者Read-fanout

 

唯一ID设计

通常情况下,ID的设计主要有以下几大类:

UUID

基于Snowflake的ID生成方式

基于申请DB步长的生成方式

基于Redis或者DB的自增ID生成方式

特殊的规则生成唯一ID

具体的实现方法跟优缺点可以参考之前的一篇博文:分布式唯一 ID 解析

在IM系统中需要唯一Id的地方主要是:

会话ID

消息ID

 

消息ID

我们来看看在设计消息ID时需要考虑的三个问题。

 

消息ID不递增可以吗

我们先看看不递增的话会怎样:

使用字符串,浪费存储空间,而且不能利用存储引擎的特性让相邻的消息存储在一起,降低消息的写入跟读取性能

使用数字,但数字随机,也不能利用存储引擎的特性让相邻的消息存储在一起,会加大随机IO,降低性能;而且随机的ID不好保证ID的唯一性

因此,消息ID最好是递增的。

 

全局递增 vs 用户级别递增 vs 会话级别递增

全局递增:指消息ID在整个IM系统随着时间的推移是递增的。全局递增的话一般可以使用Snowflake(当然,Snowflake也只是worker级别的递增)。此时,如果你的系统是读扩散的话为了防止消息丢失,那每一条消息就只能带上上一条消息的ID,前端根据上一条消息判断是否有丢失消息,有消息丢失的话需要重新拉一次。

用户级别递增:指消息ID只保证在单个用户中是递增的,不同用户之间不影响并且可能重复。典型代表:微信。如果是写扩散系统的话信箱时间线ID跟消息ID需要分开设计,信箱时间线ID用户级别递增,消息ID全局递增。如果是读扩散系统的话感觉使用用户级别递增必要性不是很大。

会话级别递增:指消息ID只保证在单个会话中是递增的,不同会话之间不影响并且可能重复。典型代表:QQ。

 

连续递增 vs 单调递增

连续递增是指ID按 1,2,3...n 的方式生成;而单调递增是指只要保证后面生成的ID比前面生成的ID大就可以了,不需要连续。

据我所知,QQ的消息ID就是在会话级别使用的连续递增,这样的好处是,如果丢失了消息,当下一条消息来的时候发现ID不连续就会去请求服务器,避免丢失消息。此时,可能有人会想,我不能用定时拉的方式看有没有消息丢失吗?当然不能,因为消息ID只在会话级别连续递增的话那如果一个人有上千个会话,那得拉多少次啊,服务器肯定是抗不住的。

对于读扩散来说,消息ID使用连续递增就是一种不错的方式了。如果使用单调递增的话当前消息需要带上前一条消息的ID(即聊天消息组成一个链表),这样,才能判断消息是否丢失。

总结一下就是:

写扩散:信箱时间线ID使用用户级别递增,消息ID全局递增,此时只要保证单调递增就可以了

读扩散:消息ID可以使用会话级别递增并且最好是连续递增

 

会话ID

我们来看看设计会话ID需要注意的问题:

其中,会话ID有种比较简单的生成方式(特殊的规则生成唯一ID):拼接 from_user_id 跟 to_user_id:

如果 from_user_id 跟 to_user_id 都是32位整形数据的话可以很方便地用位运算拼接成一个64位的会话ID,即: conversation_id = ${from_user_id} << 32 | ${to_user_id} (在拼接前需要确保值比较小的用户ID是 from_user_id,这样任意两个用户发起会话可以很方便地知道会话ID)

如果from_user_id 跟 to_user_id 都是64位整形数据的话那就只能拼接成一个字符串了,拼接成字符串的话就比较伤了,浪费存储空间性能又不好。

前东家就是使用的上面第1种方式,第1种方式有个硬伤:随着业务在全球的扩展,32位的用户ID如果不够用需要扩展到64位的话那就需要大刀阔斧地改了。32位整形ID看起来能够容纳21亿个用户,但通常我们为了防止别人知道真实的用户数据,使用的ID通常不是连续的,这时,32位的用户ID就完全不够用了。因此,该设计完全依赖于用户ID,不是一种可取的设计方式。

因此,会话ID的设计可以使用全局递增的方式,加一个映射表,保存from_user_id、to_user_id跟conversation_id的关系。

 

推模式 vs 拉模式 vs 推拉结合模式

在IM系统中,新消息的获取通常会有三种可能的做法:

推模式:有新消息时服务器主动推给所有端(iOS、Android、PC等)

拉模式:由前端主动发起拉取消息的请求,为了保证消息的实时性,一般采用推模式,拉模式一般用于获取历史消息

推拉结合模式:有新消息时服务器会先推一个有新消息的通知给前端,前端接收到通知后就向服务器拉取消息

推模式简化图如下:

04cfb696364aeffcfdd83382d29a45bfefb11a.jpg.png

如上图所示,正常情况下,用户发的消息经过服务器存储等操作后会推给接收方的所有端。但推是有可能会丢失的,最常见的情况就是用户可能会伪在线(是指如果推送服务基于长连接,而长连接可能已经断开,即用户已经掉线,但一般需要经过一个心跳周期后服务器才能感知到,这时服务器会错误地以为用户还在线;伪在线是本人自己想的一个概念,没想到合适的词来解释)。因此如果单纯使用推模式的话,是有可能会丢失消息的。

推拉结合模式简化图如下:

6760f5926b20f8763ec72480c1328e859795dd.jpg.png

可以使用推拉结合模式解决推模式可能会丢消息的问题。在用户发新消息时服务器推送一个通知,然后前端请求最新消息列表,为了防止有消息丢失,可以再每隔一段时间主动请求一次。可以看出,使用推拉结合模式最好是用写扩散,因为写扩散只需要拉一条时间线的个人信箱就好了,而读扩散有N条时间线(每个信箱一条),如果也定时拉取的话性能会很差。

 

业界解决方案

前面了解了IM系统的常见设计问题,接下来我们再看看业界是怎么设计IM系统的。研究业界的主流方案有助于我们深入理解IM系统的设计。以下研究都是基于网上已经公开的资料,不一定正确,大家仅作参考就好了。

微信

虽然微信很多基础框架都是自研,但这并不妨碍我们理解微信的架构设计。从微信公开的《从0到1:微信后台系统的演进之路》这篇文章可以看出,微信采用的主要是:写扩散 + 推拉结合。由于群聊使用的也是写扩散,而写扩散很消耗资源,因此微信群有人数上限(目前是500)。所以这也是写扩散的一个明显缺点,如果需要万人群就比较难了。

从文中还可以看出,微信采用了多数据中心架构:

 62f39582378e16672d3132062133f47142ce8e.jpg.png

 


微信每个数据中心都是自治的,每个数据中心都有全量的数据,数据中心间通过自研的消息队列来同步数据。为了保证数据的一致性,每个用户都只属于一个数据中心,只能在自己所属的数据中心进行数据读写,如果用户连了其它数据中心则会自动引导用户接入所属的数据中心。而如果需要访问其它用户的数据那只需要访问自己所属的数据中心就可以了。同时,微信使用了三园区容灾的架构,使用Paxos来保证数据的一致性。

从微信公开的《万亿级调用系统:微信序列号生成器架构设计及演变》这篇文章可以看出,微信的ID设计采用的是:基于申请DB步长的生成方式 + 用户级别递增。如下图所示:

1.png

微信的序列号生成器由仲裁服务生成路由表(路由表保存了uid号段到AllocSvr的全映射),路由表会同步到AllocSvr跟Client。如果AllocSvr宕机的话会由仲裁服务重新调度uid号段到其它AllocSvr。

 

钉钉

钉钉公开的资料不多,从《阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处》这篇文章我们只能知道,钉钉最开始使用的是写扩散模型,为了支持万人群,后来貌似优化成了读扩散。

但聊到阿里的IM系统,不得不提的是阿里自研的Tablestore。一般情况下,IM系统都会有一个自增ID生成系统,但Tablestore创造性地引入了主键列自增,即把ID的生成整合到了DB层,支持了用户级别递增(传统MySQL等DB只能支持表级自增,即全局自增)。具体可以参考:《如何优化高并发IM系统架构》

 

Twitter

什么?Twitter不是Feeds系统吗?这篇文章不是讨论IM的吗?是的,Twitter是Feeds系统,但Feeds系统跟IM系统其实有很多设计上的共性,研究下Feeds系统有助于我们在设计IM系统时进行参考。再说了,研究下Feeds系统也没有坏处,扩展下技术视野嘛。

Twitter的自增ID设计估计大家都耳熟能详了,即大名鼎鼎的Snowflake,因此ID是全局递增的。


从这个视频分享《How We Learned to Stop Worrying and Love Fan-In at Twitter》可以看出,Twitter一开始使用的是写扩散模型,Fanout Service负责扩散写到Timelines Cache(使用了Redis),Timeline Service负责读取Timeline数据,然后由API Services返回给用户。

但由于写扩散对于大V来说写的消耗太大,因此后面Twitter又使用了写扩散跟读扩散结合的方式。如下图所示:



 2.png

对于粉丝数不多的用户如果发Twitter使用的还是写扩散模型,由Timeline Mixer服务将用户的Timeline、大V的写Timeline跟系统推荐等内容整合起来,最后再由API Services返回给用户。

 

58到家

58到家实现了一个通用的实时消息平台:

3.png

可以看出,msg-server保存了应用跟MQ主题之间的对应关系,msg-server根据这个配置将消息推到不同的MQ队列,具体的应用来消费就可以了。因此,新增一个应用只需要修改配置就可以了。

58到家为了保证消息投递的可靠性,还引入了确认机制:消息平台收到消息先落地数据库,接收方收到后应用层ACK再删除。使用确认机制最好是只能单点登录,如果多端能够同时登录的话那就比较麻烦了,因为需要所有端都确认收到消息后才能删除。

看到这里,估计大家已经明白了,设计一个IM系统很有挑战性。我们还是继续来看设计一个IM系统需要考虑的问题吧。

 

IM需要解决的问题

如何保证消息的实时性

在通信协议的选择上,我们主要有以下几个选择:

使用TCP Socket通信,自己设计协议:58到家等等

使用UDP Socket通信:QQ等等

使用HTTP长轮循:微信网页版等等

不管使用哪种方式,我们都能够做到消息的实时通知。但影响我们消息实时性的可能会在我们处理消息的方式上。例如:假如我们推送的时候使用MQ去处理并推送一个万人群的消息,推送一个人需要2ms,那么推完一万人需要20s,那么后面的消息就阻塞了20s。如果我们需要在10ms内推完,那么我们推送的并发度应该是:人数:10000 / (推送总时长:10 / 单个人推送时长:2) = 2000

因此,我们在选择具体的实现方案的时候一定要评估好我们系统的吞吐量,系统的每一个环节都要进行评估压测。只有把每一个环节的吞吐量评估好了,才能保证消息推送的实时性。

如何保证消息时序

以下情况下消息可能会乱序:

发送消息如果使用的不是长连接,而是使用HTTP的话可能会出现乱序。因为后端一般是集群部署,使用HTTP的话请求可能会打到不同的服务器,由于网络延迟或者服务器处理速度的不同,后发的消息可能会先完成,此时就产生了消息乱序。解决方案:

前端依次对消息进行处理,发送完一个消息再发送下一个消息。这种方式会降低用户体验,一般情况下不建议使用。

带上一个前端生成的顺序ID,让接收方根据该ID进行排序。这种方式前端处理会比较麻烦一点,而且聊天的过程中接收方的历史消息列表中可能会在中间插入一条消息,这样会很奇怪,而且用户可能会漏读消息。但这种情况可以通过在用户切换窗口的时候再进行重排来解决,接收方每次收到消息都先往最后面追加。

通常为了优化体验,有的IM系统可能会采取异步发送确认机制(例如:QQ)。即消息只要到达服务器,然后服务器发送到MQ就算发送成功。如果由于权限等问题发送失败的话后端再推一个通知下去。这种情况下MQ就要选择合适的Sharding策略了:

按to_user_id进行Sharding:使用该策略如果需要做多端同步的话发送方多个端进行同步可能会乱序,因为不同队列的处理速度可能会不一样。例如发送方先发送m1然后发送m2,但服务器可能会先处理完m2再处理m1,这里其它端会先收到m2然后是m1,此时其它端的会话列表就乱了。

按conversation_id进行Sharding:使用该策略同样会导致多端同步会乱序。

按from_user_id进行Sharding:这种情况下使用该策略是比较好的选择

通常为了优化性能,推送前可能会先往MQ推,这种情况下使用to_user_id才是比较好的选择。

用户在线状态如何做

很多IM系统都需要展示用户的状态:是否在线,是否忙碌等。主要可以使用Redis或者分布式一致性哈希来实现用户在线状态的存储。

看上面的图可能会有人疑惑,为什么每次心跳都需要更新Redis?如果我使用的是TCP长连接那是不是就不用每次心跳都更新了?确实,正常情况下服务器只需要在新建连接或者断开连接的时候更新一下Redis就好了。但由于服务器可能会出现异常,或者服务器跟Redis之间的网络会出现问题,此时基于事件的更新就会出现问题,导致用户状态不正确。因此,如果需要用户在线状态准确的话最好通过心跳来更新在线状态。

由于Redis是单机存储的,因此,为了提高可靠性跟性能,我们可以使用Redis Cluster或者Codis。

使用分布式一致性哈希需要注意在对Status Server Cluster进行扩容或者缩容的时候要先对用户状态进行迁移,不然在刚操作时会出现用户状态不一致的情况。同时还需要使用虚拟节点避免数据倾斜的问题。

 

多端同步怎么做

读扩散

前面也提到过,对于读扩散,消息的同步主要是以推模式为主,单个会话的消息ID顺序递增,前端收到推的消息如果发现消息ID不连续就请求后端重新获取消息。但这样仍然可能丢失会话的最后一条消息,为了加大消息的可靠性,可以在历史会话列表的会话里再带上最后一条消息的ID,前端在收到新消息的时候会先拉取最新的会话列表,然后判断会话的最后一条消息是否存在,如果不存在,消息就可能丢失了,前端需要再拉一次会话的消息列表;如果会话的最后一条消息ID跟消息列表里的最后一条消息ID一样,前端就不再处理。这种做法的性能瓶颈会在拉取历史会话列表那里,因为每次新消息都需要拉取后端一次,如果按微信的量级来看,单是消息就可能会有20万的QPS,如果历史会话列表放到MySQL等传统DB的话肯定抗不住。因此,最好将历史会话列表存到开了AOF(用RDB的话可能会丢数据)的Redis集群。这里只能感慨性能跟简单性不能兼得。

 

写扩散

对于写扩散来说,多端同步就简单些了。前端只需要记录最后同步的位点,同步的时候带上同步位点,然后服务器就将该位点后面的数据全部返回给前端,前端更新同步位点就可以了。

如何处理未读数

在IM系统中,未读数的处理非常重要。未读数一般分为会话未读数跟总未读数,如果处理不当,会话未读数跟总未读数可能会不一致,严重降低用户体验。

读扩散

对于读扩散来说,我们可以将会话未读数跟总未读数都存在后端,但后端需要保证两个未读数更新的原子性跟一致性,一般可以通过以下两种方法来实现:

使用Redis的multi事务功能,事务更新失败可以重试。但要注意如果你使用Codis集群的话并不支持事务功能。

使用Lua嵌入脚本的方式。使用这种方式需要保证会话未读数跟总未读数都在同一个Redis节点(Codis的话可以使用Hashtag)。这种方式会导致实现逻辑分散,加大维护成本。

写扩散

对于写扩散来说,服务端通常会弱化会话的概念,即服务端不存储历史会话列表。未读数的计算可由前端来负责,标记已读跟标记未读可以只记录一个事件到信箱里,各个端通过重放该事件的形式来处理会话未读数。使用这种方式可能会造成各个端的未读数不一致,至少微信就会有这个问题。

如果写扩散也通过历史会话列表来存储未读数的话那用户时间线服务跟会话服务紧耦合,这个时候需要保证原子性跟一致性的话那就只能使用分布式事务了,会大大降低系统的性能。

如何存储历史消息

读扩散

对于读扩散,只需要按会话ID进行Sharding存储一份就可以了。

 

写扩散

对于写扩散,需要存储两份:一份是以用户为Timeline的消息列表,一份是以会话为Timeline的消息列表。以用户为Timeline的消息列表可以用用户ID来做Sharding,以会话为Timeline的消息列表可以用会话ID来做Sharding。

 

数据冷热分离

对于IM来说,历史消息的存储有很强的时间序列特性,时间越久,消息被访问的概率也越低,价值也越低。如果我们需要存储几年甚至是永久的历史消息的话(电商IM中比较常见),那么做历史消息的冷热分离就非常有必要了。数据的冷热分离一般是HWC(Hot-Warm-Cold)架构。对于刚发送的消息可以放到Hot存储系统(可以用Redis)跟Warm存储系统,然后由Store Scheduler根据一定的规则定时将冷数据迁移到Cold存储系统。获取消息的时候需要依次访问Hot、Warm跟Cold存储系统,由Store Service整合数据返回给IM Service。

 

接入层怎么做

实现接入层的负载均衡主要有以下几个方法:

硬件负载均衡:例如F5、A10等等。硬件负载均衡性能强大,稳定性高,但价格非常贵,不是土豪公司不建议使用。

使用DNS实现负载均衡:使用DNS实现负载均衡比较简单,但使用DNS实现负载均衡如果需要切换或者扩容那生效会很慢,而且使用DNS实现负载均衡支持的IP个数有限制、支持的负载均衡策略也比较简单。

DNS + 4层负载均衡 + 7层负载均衡架构:例如 DNS + DPVS + Nginx 或者 DNS + LVS + Nginx。有人可能会疑惑为什么要加入4层负载均衡呢?这是因为7层负载均衡很耗CPU,并且经常需要扩容或者缩容,对于大型网站来说可能需要很多7层负载均衡服务器,但只需要少量的4层负载均衡服务器即可。因此,该架构对于HTTP等短连接大型应用很有用。当然,如果流量不大的话只使用DNS + 7层负载均衡即可。但对于长连接来说,加入7层负载均衡Nginx就不大好了。因为Nginx经常需要改配置并且reload配置,reload的时候TCP连接会断开,造成大量掉线。

DNS + 4层负载均衡:4层负载均衡一般比较稳定,很少改动,比较适合于长连接。

对于长连接的接入层,如果我们需要更加灵活的负载均衡策略或者需要做灰度的话,那我们可以引入一个调度服务,如下图所示:

 4.png

Access Schedule Service可以实现根据各种策略来分配Access Service,例如:

根据灰度策略来分配

根据就近原则来分配

根据最少连接数来分配

 

架构心得

最后,分享一下做大型应用的架构心得:

灰度!灰度!灰度!

监控!监控!监控!

告警!告警!告警!

缓存!缓存!缓存!

限流!熔断!降级!

低耦合,高内聚!

避免单点,拥抱无状态!

评估!评估!评估!

压测!压测!压测!

 

来源:InfoQ 


这款网络排查工具,堪称神器!

技术交流大兴 发表了文章 • 0 个评论 • 88 次浏览 • 2020-07-31 10:43 • 来自相关话题

常用的 ping,tracert,nslookup 一般用来判断主机的网络连通性,其实 Linux 下有一个更好用的网络联通性判断工具,它可以结合 ping nslookup tracert 来判断网络的相关特性,这个命令就是 mtr。mtr 全称 my tr... ...查看全部
常用的 ping,tracert,nslookup 一般用来判断主机的网络连通性,其实 Linux 下有一个更好用的网络联通性判断工具,它可以结合 ping nslookup tracert 来判断网络的相关特性,这个命令就是 mtr。mtr 全称 my traceroute,是一个把 ping 和 traceroute 合并到一个程序的网络诊断工具。

traceroute 默认使用 UDP 数据包探测,而 mtr 默认使用 ICMP 报文探测,ICMP 在某些路由节点的优先级要比其他数据包低,所以测试得到的数据可能低于实际情况。

安装方法

1.Windows 系统可以直接在 https://cdn.ipip.net/17mon/besttrace.exe 下载 BestTrace 工具并安装。也可以在 https://github.com/oott123/WinMTR/releases GitHub 上下载 MTR 专用工具,该工具为免安装,下载后可以直接使用。
2.Linux 可以直接运行命令进行安装。

# Debian/Ubuntu 系统
apt install mtr

# RedHat/CentOS 系统
yum install mtr
3.Apple 客户端可以在 App store 搜索 Best NetTools 下载安装
4.Android 客户端:可以在 Google Play 上下载 TracePing,但是由于国内 Google Play 无法访问,笔者自行下载下来,可以直接访问 https://dwz.cn/KCdNPH4c 下载 TracePing。

使用

MTR 使用非常简单,查看本机到 qq.com 的路由以及连接情况直接运行如下命令:

mtr qq.com

微信图片_20200731104115.png

具体输出的参数含义为:
  • 第一列是 IP 地址

  • 丢包率:Loss

  • 已发送的包数:Snt

  • 最后一个包的延时:Last

  • 平均延时:Avg

  • 最低延时:Best

  • 最差延时:Wrst

  • 方差(稳定性):StDev

参数说明


  • -r or --report

使用 mtr -r qq.com 来打印报告,如果不使用 -r or --report 参数 mtr 会不断动态运行。使用 report 选项, mtr 会向 qq.com 主机发送 10 个 ICMP 包,然后直接输出结果。通常情况下 mtr 需要几秒钟时间来输出报告。mtr 报告由一系列跳数组成,每一跳意味着数据包通过节点或者路由器来达到目的主机。
一般情况下 mtr 前几跳都是本地 ISP,后几跳属于服务商比如 腾讯数据中心,中间跳数则是中间节点,如果发现前几跳异常,需要联系本地 ISP 服务提供上,相反如果后几跳出现问题,则需要联系服务提供商,中间几跳出现问题,则需要联系运营商进行处理
默认使用 -r 参数来生成报告,只会发送 10 个数据包,如果想要自定义数据包数量,可以使用 -c 参数
  • -s or --packetsize

使用 -s 来指定 ping 数据包的大小

mtr -s 100 qq.com
100 bytes 数据包会用来发送,测试,如果设置为负数,则每一次发送的数据包的大小都会是一个随机数。
  • -c

指定发送数量

mtr -c 100 qq.com
  • -n

不进行主机解释
使用 -n 选项来让 mtr 只输出 IP,而不对主机 host name 进行解释

mtr -n qq.com

MTR 结果分析

当我们分析 MTR 报告时候,最好找出每一跳的任何问题。除了可以查看两个服务器之间的路径之外,MTR 在它的七列数据中提供了很多有价值的数据统计报告。
Loss% 列展示了数据包在每一跳的丢失率。Snt 列记录的多少个数据包被送出。
使用 –report 参数默认会送出 10 个数据包。如果使用 –report-cycles=[number-of-packets] 选项,MTR 就会按照 [number-of-packets] 指定的数量发出 ICMP 数据包。
Last, Avg, Best 和 Wrst 列都标识数据包往返的时间,使用的是毫秒( ms )单位表示。Last 表示最后一个数据包所用的时间, Avg 表示评价时间, Best 和 Wrst 表示最小和最大时间。在大多数情况下,平均时间( Avg)列需要我们特别注意。
最后一列 StDev 提供了数据包在每个主机的标准偏差。如果标准偏差越高,说明数据包在这个节点的延时越不相同。标准偏差会让您了解到平均延时是否是真的延时时间的中心点,或者测量数据受到某些问题的干扰。
例如,如果标准偏差很大,说明数据包的延迟是不确定的。一些数据包延迟很小(例如:25ms),另一些数据包延迟很大(例如:350ms)。当 10 个数据包全部发出后,得到的平均延迟可能是正常的,但是平均延迟是不能很好的反应实际情况的。如果标准偏差很高,使用最好和最坏的延迟来确定平均延迟是一个较好的方案。
在大多数情况下,您可以把 MTR 的输出分成三大块。根据配置,第二或第三跳一般都是您的本地 ISP,倒数第二或第三跳一般为您目的主机的 ISP。中间的节点是数据包经过的路由器。
当分析 MTR 的输出时,您需要注意两点:loss 和 latency。

网络丢包

如果在任何一跳上看到 loss 的百分比,这就说明这一跳上可能有问题了。当然,很多服务提供商人为限制 ICMP 发送的速率,这也会导致此问题。那么如何才能指定是人为的限制 ICMP 传输 还是确定有丢包的现象?此时需要查看下一跳。如果下一跳没有丢包现象,说明上一条是人为限制的。如下示例:

微信图片_20200731104224.png

人为限制 MTR 丢包

在此例中,第 4 跳发生了丢包现象,但是接下来几条都没任何丢包现象,说明第二跳的丢包是人为限制的。如果在接下来的几条中都有丢包,那就可能是第二跳有问题了。请记住,ICMP 包的速率限制和丢失可能会同时发生。

微信图片_20200731104236.png

MTR 丢包截图

从上面的图中,您可以看从第 13 跳和第 17 跳都有 10% 的丢包率,从接下来的几跳都有丢包现象,但是最后 15,16 跳都是 100% 的丢包率,我们可以猜测到 100% 的丢包率除了网络糟糕的原因之前还有人为限制 ICMP。所以,当我们看到不同的丢包率时,通常要以最后几跳为准。
还有很多时候问题是在数据包返回途中发生的。数据包可以成功的到达目的主机,但是返回过程中遇到 “困难” 了。所以,当问题发生后,我们通常需要收集反方向的 MTR 报告。
此外,互联网设施的维护或短暂的网络拥挤可能会带来短暂的丢包率,当出现短暂的 10% 丢包率时候,不必担心,应用层的程序会弥补这点损失。

网络延迟

除了可以通过 MTR 报告查看丢包率,我们也还可以看到本地到目的之间的时延。因为是不通的位置,延迟通常会随着条数的增加而增加。所以,延迟通常取决于节点之间的物理距离和线路质量。

微信图片_20200731104250.png

MTR 查看网络延迟

从上面的 MTR 报告截图中,我们可以看到从第 11 跳到 12 跳的延迟猛增,直接导致了后面的延迟也很大,一般有可能是 11 跳到 12 跳属于不通地域,物理距离导致时延猛增,也有可能是第 12 条的路由器配置不当,或者是线路拥塞。需要具体问题进行具体的分析。
然而,高延迟并不一定意味着当前路由器有问题。延迟很大的原因也有可能是在返回过程中引发的。从这份报告的截图看不到返回的路径,返回的路径可能是完全不同的线路,所以一般需要进行双向 MTR 测试。
注:ICMP 速率限制也可能会增加延迟,但是一般可以查看最后一条的时间延迟来判断是否是上述情况。

根据 MTR 结果解决网络问题

MTR 报告显示的路由问题大都是暂时性的。很多问题在 24 小时内都被解决了。大多数情况下,如果您发现了路由问题,ISP 提供商已经监视到并且正在解决中了。当您经历网络问题后,可以选择提醒您的 ISP 提供商。当联系您的提供商时,需要发送一下 MTR 报告和相关的数据。没有有用的数据,提供商是没有办法去解决问题的。
然而大多数情况下,路由问题是比较少见的。比较常见的是因为物理距离太长,或者上网高峰,导致网络变的很慢。尤其是跨越大西洋和太平洋的时候,网络有时候会变的很慢。这种情况下,建议就近接入客户的节点。


作者:苏欣

链接:https://cloud.tencent.com/developer/article/1491610


谷歌重磅开源项目“海啸”,霸榜Github第一!

技术交流大兴 发表了文章 • 0 个评论 • 66 次浏览 • 2020-07-22 11:24 • 来自相关话题

最近,谷歌专门为大型企业网络开源了一个漏洞扫描神器,主要用于数千个甚至数百万个物联网组成的企业系统。为了让大家放心使用,谷歌已经将“海啸”用于内部使用一个月之久了。不过,“海啸”并非是谷歌官方的产品,而是由开源社区来维护,有点类似于Kubernetes。“海啸... ...查看全部

最近,谷歌专门为大型企业网络开源了一个漏洞扫描神器,主要用于数千个甚至数百万个物联网组成的企业系统。为了让大家放心使用,谷歌已经将“海啸”用于内部使用一个月之久了。

22626539-2ef8fc1d9e76c59a.jpg

不过,“海啸”并非是谷歌官方的产品,而是由开源社区来维护,有点类似于Kubernetes。

“海啸”是如何运行的?

市场上已经有数百种类似的商业或开源的漏洞扫描器,但“海啸”和这些漏洞扫描器不同的是,它是专门为类似谷歌这样规模的企业构建的,诸如网络管理的企业,这些网络包括数十万台的服务器、工作站,网络设备和连接到互联网的物联网设备。

谷歌表示,他们设计的“海啸”能够直接适应这些大型网络,而不需要为每种设备类型运行不同的扫描仪。

海啸由两个部分组成,然后在这个基础上添加一个可扩展的插件机制,第一个组件是扫描仪本身,也就是侦查模块,该组件可以扫描企业网络的开放端口,然后测试每个端口,并试图识别在每个端口上运行的服务和协议,以防对端口进行错误标记,并标记测试设备是否存在错误的漏洞

谷歌表示,端口指纹模块基于行业测试的nmap网络映射引擎,“海啸”的第二个部分比较复杂,这一部分是基于第一部分的运行结果,它获取每个设备及其暴露的端口,选择要测试的漏洞列表,并运行检查设备是否容易受到攻击。

漏洞验证模块是通过“海啸”的插件拓展方式,安全团队可以通过添加插件的方式,添加新的攻击载体和漏洞来检测内部网络。

当前的海啸版本已经包含了多个插件帮助你检测:
Exposed sensitive UIs:Jenkins, Jupyter和Hadoop Yarn都带有UI,允许用户工作负载调度或执行系统命令,如果这些系统在没有身份验证的情况下暴露在internet上,攻击者可以利用应用程序的功能来执行恶意命令。

弱凭证:“海啸”使用其他开源工具(如ncrack)检测协议和工具包(包括SSH、FTP、RDP和MySQL)使用的弱密码。

谷歌表示,未来几个月他们将通过新增插件来增强“海啸”的功能特性,从而检测到更多的漏洞,所有的插件都将通过Github发布。


“海啸”目标?
谷歌表示,“海啸”旨在满足类似于谷歌这样的高端企业的客户需求,漏洞扫描的准确性是重中之重,项目的重点是避免出现错误的检测结果。

这一点是至关重要的,因为扫描器将运行在巨大的网络中,在这些网络中,即使是最轻微的错误发现也会导致向成百上千的设备发送不正确的补丁,最终导致设备/网络崩溃,造成不必要的损失。

此外,为了减少安全团队的警戒疲劳,海啸还将扩展到只支持扫描那些可能被武器化的高危漏洞,而不是像目前的大多数漏洞扫描器所做的那样,专注于扫描所有的漏洞。

霸榜Github第一!谷歌重磅开源的“海啸”,我服了
“海啸”发布不久,已经稳稳霸住Github周榜第一的位置,收获标星4435个,累计分支362个(Github地址:https://github.com/google/tsunami-security-scanner),感兴趣的小伙伴们不要错过了哦。



Linux 之父对 Intel 发飙:拜托快学学 AMD

活动大兴 发表了文章 • 0 个评论 • 91 次浏览 • 2020-07-15 11:41 • 来自相关话题

在最近一次邮件交流中,Linux之父Linus Torvalds对Intel的处理器战略表达意见。他谈到“希望AVX512指令集安详地‘死去’”。Torvalds指出,Intel应当把精力转移到解决真正问题上来,而不是通过创造神奇的指令集来赢得某些跑分上的胜利... ...查看全部

在最近一次邮件交流中,Linux之父Linus Torvalds对Intel的处理器战略表达意见。

他谈到“希望AVX512指令集安详地‘死去’”。Torvalds指出,Intel应当把精力转移到解决真正问题上来,而不是通过创造神奇的指令集来赢得某些跑分上的胜利。

Torvalds还提到AMD,建议Intel像后者那样,把核心数做上来。在Torvalds看来,AVX512指令集仅在HPC(高性能计算集群)中有点用。

s_7a08f1594ea1442ca873f3b6b702144b.jpg

据悉,AVX-512是第三代AVX高级矢量扩展指令集,最早于2016年的Xeon Phi x200加速卡中被支持。它提供了单次512位数据和控制指令的执行单元,使得CPU单次可处理的组合矢量数据宽度达到512位,并且扩展到32个512位ZMM寄存器,保证数据处理的暂存需求,也支持FMA融合乘加操作。

当然,Torvalds此番谈话还有个背景是,Rocket Lake处理器的下一代Alder Lake可能会是Intel第一次大规模在消费级应用big.LITTLE混合架构,而为了指令集统一、减少调度损耗(Atom不支持AVX-512),Alder Lake可能砍掉AVX-512。

s_cb126cf1f56d4630841aa159c2ae6497.jpg

原文:http://news.mydrivers.com/1/700/700158.htm

end

乔布斯,比尔盖茨,扎克伯格等大佬的办公桌什么样?

活动大兴 发表了文章 • 2 个评论 • 67 次浏览 • 2020-07-06 10:27 • 来自相关话题

大多数同为工程师的读者们,应该总是会对“工程师的办公桌到底有多乱”这类话题感兴趣,那些曾经的工程师、程序员巨佬的办公桌是否也杂乱无章呢?来看看。一、雷军从雷军的办公桌上,你看到了什么?稳压源、示波器……还有两台什么?阻抗分析仪?整体上看上去还是比较整洁的。一位... ...查看全部

大多数同为工程师的读者们,应该总是会对“工程师的办公桌到底有多乱”这类话题感兴趣,那些曾经的工程师、程序员巨佬的办公桌是否也杂乱无章呢?来看看。


一、雷军

微信图片_20200706102259.jpg

从雷军的办公桌上,你看到了什么?稳压源、示波器……还有两台什么?阻抗分析仪?整体上看上去还是比较整洁的。一位软硬皆通的CEO,不知道现在小米公司做这么大了,是不是还是这样的办公桌。


二,丰田章男


丰田第四代长孙,仅仅用了7年时间就将丰田锻造成一个年销千万级的庞大企业。丰田章男的办公室更像是释放情怀的聚集地,相比于繁琐的公务文件,这里的玩具更多一些,赛车、车模、本田asimo公仔以及头盔、贴纸等等,对于丰田章男来说,他将所有的时间奉献给丰田管理,办公室只是名义上的办公室,事实上它更像休息室多一些。

微信图片_20200706102337.jpg


与咱们印象中的企业高层完全不同,与其说是办公室,不如说是一个私人的电玩玩家的收藏室。桌上除了电脑,其它就是布列了很多的物件。只有20多个平方米的办公室布满了机器人公仔、汽车模型等。有没有像卖杂志报刊的店面呢

三,Jim Williams


作为早期的linear成员之一,Jim拥有了不小的财富,但他直到去世前还是喜欢在LAB里工作,喜欢设计电路,并把电路设计思想用最简单的方式描述出来。无数模拟工程师从他的文章中获益匪浅。

微信图片_20200706102404.png


Jim的职业生涯始于麻省理工营养实验室(MIT Nutrition Lab),制作实验、研究所需的电路的系统。就我所知,Jim没有正式拿过电子工程学位,他在这方面主要是自学。出于对模拟电路的爱,Jim每年都会回到麻省理工为电子工程专业的学生客座讲课,也会进行一些招聘和拓展。

微信图片_20200706102425.jpg


四,Linux创始人Linus Torvalds


Linus Torvalds是世界上最著名的程序员之一,是Linux操作系统之父。并制作了近乎通用的Git分布式版本控制系统

微信图片_20200706102443.jpg

2014 年 7 月,Linus 首次公开了他的家庭办公室。有一台转角办公桌,桌面可能和大多数人一样,比较凌乱,有各种连接线、3D打印机、线缆、硬盘……。linus还有一个可以站着工作的工作台,比坐着工作更健康。


五,比尔盖茨


比尔·盖茨是前微软 CEO 兼联合创始人,他的办公室就是高科技的设计感,这里空间大,非常符合现代我们对于 CEO 办公室的理解,但是比较简约大气。值得一提的是他的三面屏电脑,看起来好霸气,调试代码时比较方便。

微信图片_20200706102508.jpg

六,史蒂夫·乔布斯


苹果前CEO史蒂夫·乔布斯的办公桌,想不到他办公室竟然如此简单,没有过多的装饰,一个书架和一个书桌,布满了书籍,以及办公所用的必须工具。

微信图片_20200706102528.jpg

七,扎克伯格


扎克伯格身价高达623亿美元,折合人民币早就超越了千亿元,是全球十大富豪中最年轻的一位,在公共办公区域进行办公。扎克伯格的工作状态非常专注,还发现了他桌子上的头盔和运动衫,非常邻家的感觉。

微信图片_20200706102542.jpg

回看了一下自己的办公桌,角落里落满的灰尘和散落一桌的杂物,我欣然接受了这种工作辛苦而未及收拾近两年未变的状态。。。


作者:Python之禅

链接https://mp.weixin.qq.com/s/nvBYwiX9TdGT1UN819i9qA