从0做到100,打造滴滴内置导航

本文写于2018年3月,距离今年发布已经一年有余。

从2016年11月开始,我接受了自研滴滴内置导航的任务,到今天,历时一年零四个月。最初的目标,是替换当时使用的腾讯SOSO地图内置导航,实现滴滴地图整个产品线的闭环。

当时把这个任务交给我的时候,是机遇,也是挑战。说实话之前我是没有导航语音播报的相关经验的,仅有的后台服务的经验是在高德做公交引擎。除了缺乏经验,时间也比较紧,自上而下都有比较大的压力(自研导航上线是地图这边的一个关键KPI)。

今天,回头看看这款产品的研发结果,还是取得了预期的效果。内置SDK全面替换为自研SDK,司机口碑上升,NPS上升,内置导航使用率上升。调用自研的导航诱导服务,整个过程中没有出现大的问题。没有出现过导航服务整体不可用的事故。在研发过程中,原有司机端一些隐藏比较深的BUG,都得到了系统的梳理和解决。比如客户端GPS点延迟,语音TTS延时等,在自建导航之前问题暴漏的不明显,自建后,投入了更多的人力,自然也有更高的要求,去发现问题。

总结一下自己的几点心得体会。

研发的开始阶段,速度优先,quick and dirty

互联网是一个充分竞争的领域,在一个产品从零到一的阶段,速度就是生命,赶在竞争对手前推出一款产品,或是在对手推出一款产品后,迅速的追上,直接决定了这款产品,甚至是一家创业团队是否能够生存。具体速度优先的tips包括:

不要求一个完美实现的方案,要求一个稳定实用的方案。

即使带有明显缺陷,也是可以上线的,开发人员或者产品经理要有ownership的精神,不是唯唯诺诺惟上是从,也不是小心翼翼瞻前顾后不敢做决定,而是能够以产品owner的身份,为产品负责,为用户负责,权衡利弊,挺身而出。比如滴滴早期的派单引擎,采用直线距离做为派单权值,显然对跨河、封闭道路等情形,会有明显的bad case。但是,如果当时的产品技术人员如果决策把这些bug修复了再上线,那市场早就被当年的竞争对手占领,也就没有今天的滴滴了。

在滴滴的派单引擎中,直线距离直到今天仍然在发挥着作用,在请求地图的路线规划服务失败时,仍然会兜底采用。如同吴军老师在《数学之美》这本书中,介绍谷歌AK-47的设计者那样,好的方案,能够迅速解决80%的头部问题,而且非常易于Debug。

系统设计要有前瞻性

虽然产品实现上,基于速度的考虑,不可能一开始就尽善尽美,但是架构的设计在产品从0到1的阶段却是必不可少的,架构设计是一款产品的设计图纸,图纸画错了,再精良的施工做出来的也是废品。并且,由于互联网的创新本质,产品经理更倾向于把拿不准的方案多做几套,放到线上去做A/B Test,通过用户数据来做决策。这样,对工程师的架构设计更是一种考验。

架构设计要分层,把最容易变更的策略部分和基础的数据分开,金字塔模型,越往下的模块越要求稳定性,少变更,越往上的部分越灵活。

拿导航服务为例,底层的数据模块,要求高性能,低变更,内存自己管理,采用了C + STL的方式,用linux的系统调用函数mmap批量申请内存,自己设计内存分布;中间的导航策略模块,包含了非常多的播报策略,如预告轮,轮播,动作轮等等,适合采用设计模式这样的东西提高开发效率和代码复用率,我们采用了C++,良好的面向对象设计,以应对产品复杂多变的需求;最上层接入模块,针对PM需求比较频繁,而且会有一些实验性质的策略,比较适合采用python,node.js,golang这样的现代语言开发,以应对频繁更改的需求,提高开发效率。

基于数据分析的软件开发

一般认为,产品经理PM是产品owner,对最终的产品质量负责,并调动开发(RD),质量测试(QA),数据分析(BI)等资源,推动一款产品的上线升级。RD在整个产品发布流程中的角色是开发,是make things,传统上不会对数据分析的事情负责。

实践中,数据分析却变成了经常发生问题的环境,埋点数据经常不可用,导致PM拿到的分析结果是错误的。由此导致了一系列问题:BI的同学觉得自己的工作没有成就感,变成了“提数工具”,RD同学觉得增加了自己额外的工作量,埋点不是在make things,而是在为他们的工作增加负担,PM同学忙于两头协调,疲于奔命,不能把精力用于思考产品,而是在处理各种琐事。大家都相当的不happy。

解决这个问题的核心在于大家需要提高对埋点重要性的认识,Leader要有这个意识,埋点是和项目开发同样重要的TODO项。要从RD身上找突破口,首先,埋点、记日志不是在给RD找额外工作量,而是工作的一部分。现代的互联网产品,在设计之初就需要考虑统计的问题,在计算工作量时也要把埋点、打日志的工作量记录在内。

如何记录好日志也是一门学问,RD要以“方便统计”为目的来记日志,日志格式输出标准化,要以能直接进入hive库,给BI查询为标准。比如,实践中发现,RD打错误日志的时候,分为error_code,和error_message两个字段,error_message除了详细解释了错误的原因,竟然还把错误case相关数据的ID也打在日志里,这就会导致统计中做group by非常困难,是要避免的。

TraceID在微服务架构中的关键作用

另外一个技巧就是TraceID的应用,别小瞧了TraceID,很多开发者都忽视,甚至有误解的地方,Google甚至搞了一套系统,专门用于查case。目前互联网公司流行的微服务的架构设计,主要目的在于隔离频繁上线变更服务带来的影响,以及便于快速迭代,应对用户群指数增长的需求,但由此带来的问题是,服务产生的bad case追查流程比较困难,有些bad case甚至不是由于单一的某个模块产生的,而是跨几个模块的corner case,单个去看每个模块,似乎都没有什么错误,但是串联在一起,却产生了bad case。这就需要在产品上线之初就设计一套traceID机制,把客户端产生的一次session会话串起来。

每个模块,从客户端开始,都要需要打印具有相同语义的trace日志,格式如下:

| 字段 |含义 |

| -------- | -------- |

| timestamp | server端收到日志的时间 |

| parentID | 上游传入的traceID中的childID|

| childID | 传给下游的parentID |

| cost | 整个request的响应时间 |

这样,相当于对整个调用链,像一个链表一样串了起来,还能够复杂的表示并行处理这样的会话请求,例如

(图,网络调用session)

image.png

图片来源:https://bigbully.github.io/Dapper-translation/

放量后,精益求精

均值和方差

放量后,需要关注用户体验,精益求精,用老大的话讲,要关注均值,更要关注方差。

通俗的讲,关注均值,就是关注某次模型优化,某次策略升级带来的系统性收益,比如平均车速提高了多少,偏航率降低了多少。关注方差,是指要关注极端的bad case,在放量后,这些bad case会随着放量的增加,逐步通过各种渠道汇总到开发团队。有时候甚至像潮水一样猝不及防。

作为产品方讲,均值的提升是有说服力的,大数据时代靠数据说话,谁也无法否认数据。但总是盯着均值,不关注方差,是错误的。对bad case的分析是非常重要的,一个反馈给RD的bad case背后,类似的问题可能已经发生了千百万次。总之,bad case解了,方差会降低,均值会提高,而针对均值的优化,却不一定解决bad case。

但是需要避免的是陷入解bad case的困境中,避免钻死胡同,要能站在系统的角度看问题,确保每次优化,每次上线都是朝着系统最优的方向前进。

导航code

例如,导航服务中的一个难点是识别路口转向播报,由于真实世界道路形态的复杂性,用抽象语言去描述真实的复杂路况需要考虑非常多的因素,例如实际工作中,我们表示一个右转的播报有13种形态。需要考虑道路线型,道路等级,相似道路,顺行道路等诸多方面。一个常见的问题,就是用规则描述的路口形态决策树,很容易出现bad case。

image.png

我们的想法是为全国1.4亿个路口转向建立一个数据库。数据库为每个转型code都建立了一个专属的模型,模型有23个维度。对整个路口code的识别策略,都会基于1.4亿个code做自动评价,对diff的部分进行人工抽样。保障每次改动是正向的,人工评测的结果,会记录到数据库中,用于积累真值样本。

image.png
image.png

在解决了code的问题后,更复杂的问题出现了,那就是语音播报的合理性,code是单点的,可穷举的,播报却是和路线相关的,不可穷举的。

导航语音播报

一个思路是采用用户的实际轨迹,去评估语言播报的合理性。需要系统性的思考一个问题,用户为什么没有按照我们给的路线走?真实的情况是怎么样的?

首先,和解决code的思路类似,要对复杂路段进行用户画像的工作。比如,实际工作中,我们发现在北京的路测效果比较好,换了一个城市,比如有着“魔幻8D城市”的重庆,针对北京道路形态进行的播报规则优化,就不适用了。

那么,重庆的道路形态又是怎么样的呢?

重庆是山城,立交桥多,隧道多,历史悠久,人口稠密,小路多,出入口,分歧点距离近。城市规划不像北京那样规整。

那么我们怎么应对呢?

路测,消除不真实感

看竞品怎么播报,竞品比我们提前做了10多年,有历史积累

看用户轨迹,但是是有策略的看,筛选的条件是:对周边路况不熟悉的用户,新手司机,甚至是疲劳驾驶的司机。

对特殊地段进行特殊标注,比如重庆一些特殊的立交桥,交通量很大,道路设计很特别,是值得做专门优化的

写在最后的总结

做为一款工具产品,在滴滴的所有服务中,“快”一直是最被看重的因素,分单要快,接驾要快,算路要快,用的时候召之即来,用完了挥之即去。

唯独对于导航服务,对于司机而言,每天10个小时的工作,伴随始终。对我们的专职司机而言,自驾不是追求自由与便利的娱乐,是他们谋生手段,对导航可靠性的要求,远超自驾对导航的期待。

即使在偏布立交桥、隧道的重庆,GPS不再可靠,我们也仍然要想办法为司机提供一个高可用的导航软件,就像老板要求的,没有什么不可能,对技术的追求是无止境的。这是司机选择我们,对我们的信任,也是我们义不容辞的使命。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容