滴滴打车公司组织架构的组织架构是怎么样的

1324人阅读
Product(3)
转载请注明来源:
本文内容转载于网络,见文末所标明出处。
& & & &成立四年,估值已超260亿美元,公司指数级发展、业务爆炸式增长,在此背景下,滴滴出行业务系统的架构升级是怎样进行的?
老司机简介:
& & & &杜欢,滴滴平台产品中心技术总监。2015 年加入滴滴,负责公司公共业务、客户端/前端架构和新业务孵化,致力于用技术手段解决业务痛点和提升研发效率,曾作为技术负责人主导公司技术架构升级以支撑公司业务快速迭代的需求。在加入滴滴前有长达五年的创业经历,具有丰富的团队管理经验,熟悉移动互联网应用的整个技术栈。
& & & &去年我们做了一次非常大的重构。上面图中是今天要讲的大纲,我会从问题本身出发,回顾一下整个过程,包括如何发现问题、分析问题和解决方案。最后,我也会提出一些想法,如何规避重蹈这样的覆辙。
挑战在哪里?
& & & &首先,我们看一下挑战在哪里。滴滴在出行领域是非常独特的公司,它的独特不在于业务模式多复杂,而在于它的发展非常快。滴滴的成立时间是2012年的6月,到现在为止才经过了四年的时间。
& & & &滴滴的成长速度十分惊人,到今天它的估值已经超过260亿美元,融资轮次非常多。如果不是因为竞争非常恶劣,滴滴也不会一直用融资的方法为自己开路。在这样的压力之下,滴滴所有的动作可能都会走形,所有的想法可能因为现在一些短期利益不得不进行一些权衡。
& & & &同时,公司的业务也在爆炸式地增长。如果滴滴只做一个业务,原本可以做得非常深入。滴滴从2014年开始加入了专车业务,2015年业务数量增加到七条,2016年已经超过十条。业务急速发展之中大家会思考,到底怎么做才能使这些还不稳定或者还没有想清楚的业务很好地迭代起来。
& & & &想到最简单的方法是,如果新业务跟某个旧业务非常类似但又不完全一样,我们就把旧业务的旧代码复制并修改,这样新业务就做出来了。之前,这种情况经常发生,就造成了很大的问题。
& & & &在2015年上半年,滴滴整个系统已经积累了很多问题,分布在乘客App、服务端、Web App之中。特别值得一提的是,服务端的问题并不是性能,而是在于巨大的耦合导致数据紊乱和迭代速度越来越慢。
滴滴的独特性迫使我们独立思考这些问题,所有的解法都要针对滴滴现状,而不是看哪个大公司是怎么做的,然后直接复制过来。
现状是什么?
& & & &在解决问题之前,我们需要了解现状是怎样的。如图所示,在2015年下半年,滴滴的系统架构分为四层。最顶层是用户应用,每一个用户应用就是一个端,也就是用户所能看到的入口。然后是接入层,这是非常传统的结构,我们用了Nginx,还专门做了TCP接入层。
& & & &在业务层,Web是非常大的集群,有非常大的代码量,我们只对业务做了分割,有策略引擎、司机调度。在数据层,有KV集群、MySQL集群、任务队列、特征存储。这是任何一个初创公司应该有的架构,我们对这个架构并没有做特殊的策划,仅仅在这个技术体系里面把业务逻辑实现出来。
& & & &上面这张图可能会比较有趣。右边这个红色的球,代表的是重构之前App依赖的关系。当时我很想梳理一下App在模块之间是如何进行依赖的,然后我就写了一个脚本运行了一下,得到的结果让我很惊讶。我用蓝色的线表示正常的依赖,就是模块A依赖于模块B,A是B的上一层,B不会反过来依赖A,用红色的线表示异常的依赖,即A依赖B、B通过各种手段反过来依赖A,最后发现基本上都是红色的。
& & & &做任何模块的拆分,发现不得不面临这样的问题:把任何一个模块取出来就等于把所有模块都取出来,实际上没有做拆分。所以,关键是需要解耦模块结果。这是iOS的情况。安卓的情况更糟糕。
& & & &对于Web App来讲,最大的问题在于耦合性。以前滴滴只有出租车这个业务,最开始的Web App只有出租车,后来专车上线了,就在出租车里面加了专车入口,只是业务名不同界面会有小区别,后来加入了快车、代驾,都跟出租车差不多,没遇到太大问题。
& & & &再后来有了顺风车,顺风车跟其他功能不一样,整体界面是预约型的,有乘客和车主两种模式。如果在老首页里面开发顺风车成本太大了,需要和出租车业务线的人一起开发业务模块,如果未来做迭代,这种开发模式将非常痛苦。老首页的模块也没有做拆分,代码散落各地,只是通过打包工具拼接在一起,没有做模块化,所以整体情况也比较糟糕。
& & & &相比端,API稍好一点的是,API至少在业务维度上是分开的,出租车与专车、快车是分开的两个系统,放在两个仓库里面。不过API也有一个很大的问题,业务代码没有做服务化拆分,没有model 封装,业务所有的API和后台MIS都在一个仓库里,这对系统来说是非常大的一个隐患。
该如何入手?
& & & &现状看上去很糟糕,要仔细思考才能入手。最基本的思路是把所有事情分类,就像整理自己家里一样,无论多乱,我们要做的事情就是将东西分门别类放好。因此,最关键的是要了解到底哪些东西应该放在一起,我们用颜色来比喻模块或者代码的归属,核心问题就变成这些模块到底是什么颜色。
& & & &我们的思路是,先从前面,也就是从用户入口进行拆分,要先保证所有的模块是足够内聚的,由统一的团队负责。比如,出租车业务线可以完全控制自己的代码,能够写自己的客户端,也能够写自己的Web App,最终只是通过一些工程构建手段将多个业务整合起来变成一个完整的端。
& & & &做到这一点之后,所有的业务迭代问题就迎刃而解了,因为业务间已经没有依赖和耦合了。这一步完成之后做的就是重新梳理业务,让业务根据自己模型特点进行一些重构。
& & & &最开始的时候,我们考虑的是怎么做代码治理和模块下沉。代码治理本质上就是把各种模块进行染色、再把它们归类的过程。代码治理最难的事情在于消除错综复杂的依赖。到底怎么做才对呢?
& & & &首先,一定要把不同模块的代码放在不同仓库里面,使得模块能够物理上隔离。特别是Java、Obj-C这些静态编译的语言,一旦把代码仓库隔离就完全没有办法直接对其他模块产生依赖,至少绝对不会再出现循环依赖。
& & & &再者,就看如何把循环依赖通过一些间接层隔离开,比如通过抽象接口隔离开,一点一点把代码拆到不同仓库。
& & & &最后,有了这样一个简单的拆分之后,就需要考虑怎么让模块能独立的开发、测试、上线。独立的流程一旦独立起来,就意味着拆分基本上成功了。
& & & &模块下沉与代码治理息息相关。如果只是要求把所有代码拆分,而没有合适的拆分方法,这件事情是无法推进下去的。对于程序员来说,他们内心总有一种冲动想做有意思的事情,比如封装一个很有意思的模块给更多程序员用。大家并非不想做封装,只是如果封装并共享出来的代价太大,就会影响大家的热情。
模块下沉是一种机制,一方面我们应该鼓励,另一方面还应该让大家发现这是一件不得不做的事情。如果仅仅对内公开模块列表让大家自由选择,达不到模块下沉的目的。因为人都很懒,不想思考太多,只想尽快把事情完成,大家往往倾向于复制粘贴,也不愿意额外花时间做下沉。
& & & &怎么办呢?我们会给所有业务提供一个统一的SDK,里面包含所有能用的组件,大家必须使用它进行开发。如果业务模块稳定了并且比较通用,我们有工具和相应的简单机制把业务模块下沉下来,变成SDK的一部分,长期下去SDK会越来越大,只要SDK里做好分类和规划,上层就会越来越轻,我们可以真正专注于业务逻辑开发。
& & & &一定要把所有业务都做到“无状态”和“异步化”。
& & & &“无状态”这个概念在服务端比较容易理解。一般我们倾向于把各种业务做到无状态,这样容易做水平扩展。在客户端也是一个道理,也要考虑横向扩展性。一个简单的框架往往提供一些最基础的控件,比如按纽、列表,这些都不会耦合任何业务逻辑,所以很容易使用。
& & & &“异步化”也是解耦的方式。服务端的RPC类似于函数调用,如果参数变了,实现和调用的双方都要做改变,这很不透明,也不能够渐进式上线。我们用订阅/发布的模式对 RPC进行解耦,要求所有接口都要异步返回。
& & & &在客户端也是这样,比如做数据的缓存,想优化网络,我们不能够期待这个函数是一个同步函数,一定用回调的方式接受所有参数。所以做设计的时候,只要是有可能发生网络请求或者访问磁盘,在客户端也尽量异步请求数据。
& & & &刚刚讲的都是相对比较抽象的内容,接下来会说一下滴滴的业务形态本身。
& & & &滴滴是一个出行的平台,涵盖的是整个出行领域所有的出行需求。大家出行到底想要什么?就是到达自己想去的地方。实际上,我们的模型可以做得非常抽象和简单。比如,我想要打快车去机场,我就是一个需求方,我的需求会发到很多服务者那里去,服务者会根据特征进行一些匹配。
& & & &最基本的特征是服务能力,如果服务者能够开快车并通过了能力验证,这个需求就有可能发给他。如果开出租车的也有能力开快车,但是他还没有在平台上验证这个能力,就只能开出租车。一个人可以验证很多服务,白天可以开快车,晚上可以做代驾,做不同的事。
& & & &服务和需求的匹配是通过计价模型和匹配策略来实现的。发送需求的时候需要选择计价模型和车的类型。快车和专车服务过程大同小异,但是价格差别很明显,专车价格会贵很多。通过匹配策略可以实现各种需求的匹配。
& & & &例如,选择了拼车,这个需求会尽量匹配已经有拼友和顺路的车。如果选择专车,可以要求这辆车在指定时间来接人,这时候匹配策略会优化倾向这种方式。
& & & &滴滴所有的业务基本上都是以这种模式运转的,所有功能都是核心主干或者旁路,只要把业务模型抽象出来,基本上就能够满足大部分的业务了。
& & & &基于这样的想法,我们就思考如何设计真正高度抽象的工具。简单起见,我们把滴滴出行的过程抽象成一个框架(见上图),这并不是完整的框架。有颜色的地方表示出租车、快车、专车、代驾共同的流程,只要组合各种流程就可以实现整个业务形态的能力。在这个框架里可以定制所有业务形态的车标、提示语、匹配的模型、计价模型等功能。
& & & &当时梳理这个抽象的时候,我们感觉非常兴奋,因为这意味着在这个基础之上就可以简易扩展出滴滴未来的业务形态。只要滴滴还是在做需求和服务的匹配,基本上就离不开这样一种套路。
客户端怎么拆?
& & & &然后我们开始落实到具体该怎么拆的问题。
& & & &首先就是客户端,最重要的是需要将业务拆出来。以前所有业务放在同一个仓库里,如果不小心提交了一段错误代码就会带来灾难性的后果,所有业务工作可能都会受到影响。以前编译速度也很糟糕,大家可以想象,每次下载代码都会有几个头文件发生改变,由于循环依赖的缘故几乎所有文件都要重编,二三十分钟后才能重新调试,这个过程让人极度崩溃。
& & & &对于iOS,我们用cocoapods把业务拆到不同的pod里面;对于安卓,我们把业务拆分打包并用Maven管理起来。我们拆分方法如下图所示,其中虚线框部分展示的是公共框架,最开始没有很细致分割,只是把它放在一个独立仓库里,保证依赖关系充分清楚,后面就可以随时把代码独立出来,使其变成单独的模块。
& & & &同时,我们也在开发构建系统。原生的构建系统使用起来会有很多问题,它并不支持多人并行开发,如果要实现一个舒适的工作流就需要定制。我们还做了网络和日志的封装,将其放在下层。还有一个业务整合的基础框架,包括滴滴出行的App界面框架、首页导航栏,各种业务可以注册自己的入口,并在导航栏里进行切换。
& & & &业务之间没有任何代码耦合,比如出租车和专车业务没有关联性,那么代码也没有任何相关的地方,这意味着开发出租车业务的时候,完全没有必要实时更新专车代码,集成的时候也不会因为专车代码而造成问题。
& & & &最顶层的One Travel可以通过简单的配置分业务包,比如可以输出只有出租车业务的包,在这上面开发测试速度比较快,整体也会比较灵活。One Travel里面只有极少的代码,未来会改成没有代码、通过脚本就可以生成的项目。
& & & &怎么做页面的解耦?上图中是一种类似数据库缓存的设计。从客户端角度来看,如果把服务器当做一个数据库,最终状态存储在服务器,而客户端里存着的是跟服务器同步过的最新状态的缓存。客户端不太可能做到精确的数据同步,一定是每隔一段时间同步一次,或者是在关键节点上靠服务器推送得到订单状态变化。
& & & &客户端的业务代码其实不关心究竟是如何同步状态的,所以我们专门写了一个缓存服务器状态的Store层,它是热数据。如果不需要最新状态的数据,业务读取Store时可以读到上次同步的数据,假设此时Store从未同步过状态就会自动读取最新状态;如果业务一定要最新状态的数据,那么就显示要求缓存失效,这样Store就会再读取一次获取最新的信息。
& & & &Store还可以自动设置失效时间长度,这个机制跟跟做数据库缓存是一样的,为了性能的平衡,要保证读出准确的数据,同时性能也要最优。同时,Store也有责任负责数据更新,当客户端变化可能会让服务器状态变化时,Store可以自动让相关状态失效,这也是管理缓存的一般做法。
& & & &做了这样一些解耦之后,令人惊喜的是,我们发现所有界面是可以随意跳转的,虽然没有从发单直接跳到评价的必要性,但实际上只要有这个架构,就可以从界面A跳到界面B,不会有任何问题。
& & & &如果跳到另外一个界面,没有发现必要的数据,就从服务器读取,它自己也会报错,整个逻辑非常清晰。如果需要在流程A和流程B之间再增加一个流程C,我们可以把流程C直接加进去,流程C没有破坏A和B之间的依赖,因为原本A和B之间也没有什么依赖。
& & & &我们也做一些App的组件化,把从服务端API到客户端逻辑打包在一起,引用客户端组件就可以实现完整功能。实际封装方法略微有点复杂(注:可以阅读另外一篇文章支撑滴滴高速发展的引擎:滴滴的组件化实践与优化)。
& & & &图中所示是做平滑移动组件,地图上有很多车在移动,这些车就是地图上的额外信息,把这些车挂在地图上。如果这个控件不存在,地图上就没有车,控件存在,地图上就有车,只要在上面启动控件就好了。
& & & &App集成也采用了异步和无障碍的做法,每个业务只需要在仓库里面测试完之后直接打tag,之后就能自动生成整个所有业务的ipa/apk包。
Web App怎么拆?
& & & &接下来讲Web App的拆解,这实际上是纯工程的解耦。
& & & &首先,我们需要实现一个简单的公共框架,这跟业务是无关的。我们使用scrat和webpack来实现工程化,将首页拆分成了许多组件,所有的业务可以根据不同配置选择使用哪些组件,同时也保证页面风格的统一、功能的稳定。
& & & &如果网络比较糟糕,我们会做一系列的降级,首先出来的会是一些统一的控件,比如上车地点、目的地、广告等,之后会根据定位的结果得到当前开通的业务线列表,并加载业务代码,然后默认选择当前业务线的逻辑。
& & & &如果业务线代码加载好了就开始渲染,如果业务加载出错或代码执行出错,业务就会被隐藏。业务线之间也是完全解耦的,大家可以通过公共框架提供的事件机制来通信,但不允许业务之间直接通信。线上的Web App就是如上图所看到的,每个业务线都有一段独立js代码,第一次加载相对较慢,会看到很多请求,如果业务线代码没有更新,下次打开就完全不走网络请求。
& & & &我们也做了很多控件,这是内网发布的一些控件(见上图),每个业务只要关注自己的业务逻辑即可,公共的功能都可以使用控件。特别是选择地址的控件,它把前端界面交互和后端API都打包在一起,和客户端一样,只要引用它,就可以直接在Web App使用,无需任何服务端的开发。
服务器API怎么拆?
& & & &关于服务器API的拆分,我们最开始希望一次性实现理想方案,但是这个理想方案遇到一些问题。
& & & &我先来谈谈理想方案是什么。首先,滴滴业务一般都是基于订单流转推动各种业务动作。为什么会发生订单流转?是因为对乘客和司机做了一些操作,如果想象成一个客户端系统,就有点类似于触发各种用户事件。客户端动作根本上决定了信息该如何流转,所有事情都应该在客户端触发,触发之后来到了组件这一层,所有动作进行消费,然后进行下一步操作。
& & & &比如,用户提出一个需求,发单对需求进行过滤,判断是哪种需求,然后进行一些检查。快车有拼车和不拼车两种,发单的时候就可以知道是拼车还是不拼车,对于统一订单系统来说这就是个标志。无论拼不拼,这个单对用户都一样,无非就是消耗多少人民币、消耗几个座位还是消耗整辆车的问题。
& & & &之后分单系统会进行订单的匹配。一旦匹配成功,客户端有很多动作,司机确认接单,乘客可以看到确认。如果直接做成消息,客户端和服务端用一条总线连接,问题就解决了。
& & & &这里有一个很大的优点——可拼接,所有东西都组件化了。但是最大的问题在于抽象程度非常高。这是函数式的思想,要求所有的Worker都是纯函数,纯函数是非常高的要求,上下文状态必须要通过参数才行。我们发现很难做到这一点,因为所有系统必须有状态,一旦这样这个纯函数就不是纯函数了,要依赖外部的变量。
& & & &与面向对象设计的思路差异非常大,做函数式设计时很容易陷入一些抉择当中,如何定义输入、输出,如何划分流程。有一些流程划分成三段式,中间的流程异步调出去,又异步调回来继续后续流程,这种设计让人很纠结。
& & & &函数很依赖异步化,异步化会让数据流变得复杂。我们思考数据流的流向,以及每次数据流在流转的时候都需要设置的输入、输出。最终,这个方案并没有实施,虽然我们开发了接近半年的时间。
& & & &2016年,我们又重新思考了这个问题,这次是比较简单和现实的方法。首先我们进行了一些代码的隔离,把代码分开,之后对系统按照刚才讲的模块进行面向对象的抽象,比如发单就是单独的系统,订单也是一个单独的系统,支付的收银体系是一个系统,评价体系是一个系统。每一个系统变得很简单,互相之间用RPC调用关联起来。
& & & &这会有什么缺点呢?长期来讲缺点还是比较明显的,就是不容易扩展。现在我们设计的模型是来源于当前业务现状,如果业务发生改变,比如多了一种车型,就会遇到该如何扩展的抉择:应该提供更多API接口满足新的业务功能,还是在原有API修改上提供更多参数。
& & & &两种方法看起来都可以,但是本质上我认为无论用哪种方案都会使模块本身变得越来越臃肿,其实都是把很多种东西融合在一起,并不是很理想。当一个服务臃肿到一定程度之后又会出现以前的问题,又要再次做拆分和重构,甚至整个RPC调用流程都会发生很大震动。
& & & &从项目整体实施效果上来讲,这次重构最主要是解决了开发迭代的问题,能够让迭代速度更快。让我们比较意外的情况是,重构前客户端crash率非常高,重构中我们对代码进行了非常多的修改,同时还在用户体验上做了很多优化,但最终crash率反而大幅下降,从以前1%降低到0.3%。
& & & &重构后各个业务团队的开发模式发生了根本的变化,以前是各个业务各耦合在一起进行开发,现在各个业务都能独立开发,互不干扰,同时平台还会不断产出更多的公共组件。
如何避免重蹈覆辙?
& & & &最后提一下如何重蹈覆辙。我认为,所有的设计应该是自上而下,先从产品层面上规划核心业务的模式,然后考虑如何让产品技术实现它。如果把业务模式描述成如图所示的核心循环,会非常清楚。我们不仅要考虑现在,还要考虑未来。如果让整个架构保持健康,就要考虑什么功能是真正紧密相关的。
& & & &比如在服务端,直觉上感觉各种不同的发单应该是在一起的,但实际上并不是这样。不同车型的发单接口互相之间并没有什么联系,每一种发单都会有独特的个性化定制,这些定制才是真正应该跟发单紧耦合的东西。
& & & &所以我们应该从产品角度上考虑,把一种发单所调用的所有相关API放在一起,服务端发生变化,调用的组件也会发生变化,做到发单闭环。刚刚提到的今年服务端的重构的方法,实际上并没有让各个子系统打通,这是一件很遗憾的事。未来如果开发一些新需求,肯定还会涉及多个模块、团队,避免不了一些沟通成本。
作者:头条号 / InfoQ技术沙龙
来源:头条号(今日头条旗下创作平台)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:134462次
积分:2489
积分:2489
排名:第12468名
原创:113篇
评论:63条
(5)(5)(11)(10)(8)(2)(5)(4)(6)(4)(4)(6)(4)(34)(14)更多公众号:fengchuixingwei和大家一起聊天,一起收获美好的一天!最新文章相关作者文章搜狗:感谢您阅读滴滴打车组织架构及未来发展分析,本文由网友投稿产生,如果侵犯了您的相关权益,请联系管理员。【创始人必读】滴滴打车遇到的股权那些坑,我公司股权结构合理么?
我的图书馆
【创始人必读】滴滴打车遇到的股权那些坑,我公司股权结构合理么?
导语滴滴打车天使投资人王刚回顾的时候总结:“分股权不要太大方,我们当时都没有经验,因为创业找的都是自家兄弟,根本不好意思说给他很少的股份,或者你有可能请了自己原来的老板过来,那更不可能少给股份。在我们账上只有100万美金的时候,我们给了CTO 240万人民币,把30%的股份买回,让他走了。为什么?因为我们发现CTO是不太合适的。”文丨翁潮静 律师创业伊始,梦想的小船起航,外部环境变化莫测,我们可能无法预测这艘刚起航的小船会遇到怎样的冰山或者是狂风暴雨,保持小船的驾驶室内结构稳定,也就是说保持创业公司合理的股权结构,是每一名创始人可以提前安排到位的,因为股权架构设计不好,轻则影响团队凝聚力,重则影响融资的进入,甚至团队散伙以及创始人被踢出董事会等灾难性后果。但是,创始人的通常情况是,合伙人已经找好,公司已经设立完成,才想到股权分配的合理性问题。发生这种情况,创始人应该怎么办?今天和创始人们分享一下我的经验吧,希望能对你的创业有帮助。最基础的,要确定这是一家具有长远目标的公司,而不是为了某一个项目设立的短期公司或者空壳公司,确保这个前提后,再考虑以下八个问题:融资主体登记的合伙人人数是否过多;股权比例是否在结构上合理;股权的分配依据是否科学;核心团队成员是否全职;是否有股东的退出机制;是否有控制权与决策机制安排;是否对股权提前进行了预留;是否有竞业禁止、保密、违约责任等股东义务约定。&一般我们对上述8个要点逐一筛查之后,一般会出现如下几种“症状”,根据不同的情况,我们还需要“对症下药”。1、融资主体股东人数过多,存在短期价值股东风险:公司在进行融资前,股权人数越少越好,最好不超过3人,5人已经是上限。股权变动对于公司来说是件不小的事情,而股东人数越多,创业过程中,股东稳定性不会很高,股东退出概率越大。另外,股东拥有查账、投票、签字等诸多权利,协调起来难度大,成本高。对于长期资源型股东,股东在持股期间对于上下游商业秘密了解过多,是否存在不利隐患,并且资源量化难度大。对于短期资源型股东,给予股权实在有些浪费,也是对其他股东的不公平。方案:尽量不要让不适合或者没有长期价值的人成为股东。如果他们已经是你的合伙人股东了,那么需要重视工具。针对长期资源型股东,需要使其与公司层面进行隔离,要么找其他股东代持,要么进入持股平台;尽量将资源进行量化,设定股权确认机制,如果未到达预期目标可以要求其进行回购或者补充投资。针对短期资源型股东,如果已经进行到股东层面,那么可以与合伙人商议补充约定回购方式的协议。2、股权比例存在僵局法律风险风险:A.单一股东(创始人)持股比例未超过50%;B.前二大股东持股比例之和不大于51%;C.没有一位股东股权比例大于33.3%风险:股东会决议时,如果各方意见不能得到统一,根据股权比例无法达成超过半数的人有一致意见,造成决策僵局,股东会层面无法作出决策。虽然看似一人独大的局面不够民主,但是对于创业公司来说,高效率的经营决策更加重要。方案:按照4C股权分配方法对股权比例重新分配;利用工具进行二元股权架构设立,如一致行动人、投票权委托、合伙制度等;如果股权实在比较分散,则可以将预留出的期权池集中创始人一人代持,让创始人掌握更多主动权。3、股权分配依据不科学,欠缺公平与长远考虑风险:凭借经验的股权分配,可能它缓解了眼前的获取稀缺资源的压力,但是股权结构不是面向未来的结构,越往后会支付很高的股权成本,后面后患无穷,因为后面的人就很难再进来了,所有人都会和这个人比,凭什么他有30%,越到后来,这是一个没有办法解的结。方案:运用4C股权分配理论重新考量,这里不再细说,见法务VC公众号文章《》。4、没有做好控制权设计与具体约定决策机制风险:股权除了作为一种可量化的经济利益外,从股权架构设计上,控制权更为重要,因为对创业公司来说,比股权问题还重要的,就是控制权了。创业很多教训因为控制权问题导致,屡屡发生,控制权往往发生在发展不错的创业企业。基于控制权的设计,做好决策机制安排,是优秀创业企业股权架构的最大问题。方案:要将权力分层,分为股东决策和运营决策。股东决策层面要有一个“拍板人”,即实际控制人。而运营决策更多的是需要专业化的分析作出决定。因此,将合伙人进行专业化分工,各专业合伙人拥有自己领域的决策权,可以给CEO一票否决权。5、核心团队中有成员是兼职风险:创业初期,大家作为合伙人一般并未长期共事过,如果不要求合伙人全职为公司工作,会出现对合伙人信息了解不充分的情况。而且,兼职工作的合伙人比全职工作的合伙人在共同事业上投入的精力相比过少。除此之外,不要求在公司全职对于股东来讲机会成本过低,会有投机心理。方案:如果合伙人股权已经进行了工商登记,则需要另行在协议中限制合伙人全职到岗的期限和条件,一旦无法全职到岗即会触发回购情形;如果合伙人股权还未进行工商登记,可以先约定股权期权或者股权先由创始人代持,等该名合伙人全职到岗后再进行股权工商登记;如果该名合伙人确实无法全职为公司服务,创始人可以考虑是否还继续授予其股权,建议能不在股权层面合作尽量不在股权层面合作。6、没有约定退出机制风险:股东离职时将股权一并带走,对于其他股东不公平,提高公司未来经营决策的成本;如果股东出现道德问题,对于其严重损害公司利益的行为无能为力。方案:设定退出机制,根据有过错和无过错约定退出情形,避免道德风险和离职风险。约定合适的退出价格计算方式,防止融资前因为大股东的退出,给公司造成巨大的经济损失。7、没有约定预留机制风险:未来引入新合伙人时,各股东之间意见出现分歧,造成不必要的麻烦障碍。如果提前约定好也可以减少未来的沟通成本。方案:提前预留一部分股权比例作为期权池,可以为引入新合伙人和员工期权池各预留一部分。投资人不需要预留股权,因为一般实践中投资人是通过增资形式进入公司。那应该预留多少比例呢?对于员工激励股权,一般投资人都会要求公司预留出10%-15%的员工期权池,为了和投资人一致,可以按照这个比例预留;对于未来合伙人预留,这个比例确实不好说,还是要看公司未来发展的需要;对于现有合伙人股权预留,为了公平期间,一般会预留出10-20%的合伙人股权,根据各自具体的贡献大小再进行分配,合伙人股权一般再第一笔投资进来之前就已经分掉。8、没有约定竞业禁止、保密、知识产权、违约责任风险:出现合伙人泄密或知识产权争议,或产生违约行为无法追究责任。方案:提前补齐上述约定,虽然有些是君子协定,但是有总比没有强。
TA的最新馆藏

我要回帖

更多关于 滴滴打车技术架构 的文章

 

随机推荐