前言
昨日,我请了一天假去考科目三,结果第一把挂在了没完全关闭灯光上,第二把挂在转弯时没有观察后方车辆,当听到师傅一句“下去”的时候,我那是悲痛的面红耳赤,这让我很郁闷,晚上也就不想回去上班了,回家后仍然有点低沉,在这种情况下,不写点毒鸡汤,好像已经不能好好的调节心情了,看看时间年底了,便写写今年的总结吧。
回想自己学车的点点滴滴,其实是很认真的,一旦有时间就去学习,练习时候也表现比较正常,晚上还会冥想整个考试流程,但最后临门一脚仍旧出错了,这个时候可以说我问心无愧了,也可以说我努力过了,虽然失败了,但我应该得到尊重。
现在看来说这种话的小伙伴不过在自我安慰罢了,做的过程中我确实很努力,也真的很认真,但是最后产生不了成果,做的事情不能落地,那么这一切的努力可以说毫无意义。将这一次的驾照考试映射到一次重要项目开发的话:
产品努力出需求 ->研发努力加班干 -> 测试努力加班测试 -> 上线 -> 大流量挂啦......
开发的过程中,研发天天加班,测试也天天加班,但是最后项目上线后就是挂了,那么之前的努力并不会换来丰收的果实,即将来临的可能是老板的怒号,团队的动荡,而不论是考试挂了,还是项目挂了,都有幸被我经历了。回头想想,人生嘛,什么都应该经历一发嘛,深深的体会一下挂了的那种无力感,也是不错的嘛,想到这里,我竟然有些释怀的感觉,只不过是重头再来(自我安慰而已啦)......
再回想16年初回到了成都,开始了愉快的“慢节奏”生活。不曾想,现在的公司给予自己的平台居然是其它地方所没有的,不论从工作强度还是业务复杂度来说,都是很对胃口的,偶尔的工作强度甚至超过了上海,嗯,这个很“成都”。
文中为个人观点,不喜勿喷
大公司or小公司
之前经常有人发文说到底要去小公司还是大公司,思考几年的经历,其实大公司小公司不重要,好的团队才重要!
大公司一般是什么都有,只需要你有一颗学习的心,多折腾多问,便能吸取大量的养分;而小公司也有一个巨大的优势,便是什么都没有,只要你有心,就能把大公司的东西通通实现一篇,这种实践来的知识技能可比学习要来的珍贵的多!
初到公司时发现了一种现象:
① 身边很多小伙伴没有买房但是都有自己的车子
② 多数小伙伴下班就回家了
可以很清晰的感受到这里的一种慢节奏,这个没什么不对,生活与工作要分开嘛,但这却让我感觉到了危机与忧虑,最大的忧虑是多数小伙伴可能不会在意到公司的财富了,天地不仁以万物为刍狗,其实生活是非常公平的,每个人的机遇其实都差不多,很多财富摆在那里,就看你是不是要去拿。
之前面试的时候,有人会问我知识获取的途径,也许是我比较low的缘故,我一直信奉一个原则:
听过 < demo过 < 实际工作用过 < 实际工作中被坑过 < 实际工作中被多次坑过或者深入研究总结过
风之积也不厚,其负大翼也无力也。网上有很多深度好文,如果没有一定基础,其实看了没有什么意义,只会在心里感叹,我尼玛这人好牛逼。
我学习的多数知识是直接从项目中来的,这个时候就需要你有一个好的团队了,我十分庆幸自己曾在携程无线待过,携程无线在前端工程化&hybrid&公共服务化一块走的比较远,而我当时又很好学,平时没事就在这之上挖掘,吸收学习,当时一些半懂不懂的知识,在后续的实践中也逐步融会贯通了,其带来的财富令我受益至今。
而,人的知识除了受限于自己的学习主动性以外,也受限至他的视野,当时我的视野就在前端方面打不开,没有去研究携程的日志统计系统与发布系统,到现在需要用到这部分知识时才感到苦不堪言而后悔莫及。
如果各位有机会到大公司去,一定要认认真真搞清楚,你自己所在领域里面,该公司的财富积累是什么,然后狠狠去挖掘他,了解他的历史故事,各种处理细节,更多的不是关注他怎么做,而是要关注他们为什么这么做,然后多问多demo,假以时日落地到实践中,这块财富就装入你的口袋了。回想自己的择业,我事实上是比较后悔自己当时为了一点小钱而放弃了阿里(成体系的前端团队)去了百度(新团队,不成体系,甚至前端框架都不统一),如果带着谦卑的态度去阿里吸取一番技术的给养想必会受用无穷吧。
技术的学习,这个需要一个学习的态度,一个学习的恒心,其实只要是持续的投入,便一定会有收获的。
技术体系化
在小公司,因为很多基础设施都不成熟,这个会让我们有将技术业务体系化&服务化的机会,而体系化后的技术便是公司的财富也是研发团队的技术壁垒,他能大幅度的提高效率,这个是一个生态体系,一旦生态体系成熟后,牵一发而动全一身,就不是任何人能轻易接手的了。
初到公司的时候,我们的系统是这么个状态:
每个H5项目有一个自己独立的登录注册,native又有自己的native的登录注册,甚至server端的服务都彼此独立,这样用户之间变形成了信息孤岛,这会引发很多问题:
① 每次做一个H5项目都必须做一个登录注册,徒增工作量
② 我们多出一个APP后,APP又产生了自己的登录注册
③ 我们H5项目内嵌至native后,账号没法打通
④ 当我们用户越来越多,子系统越来越杂的时候,我们的用户会越来越乱
这个时候,我们需要做的一件事情,就是整理所有的子系统,将我们的账号系统体系化。
数据库改造
这里我们做的体系化第一步是对数据库进行改造,将子系统做到一张公共的表,有过相关经验的朋友都会知道,子系统较多的公司,应该将基础用户表设计得足够抽象,只需要包含核心数据:
① 用户id
② 用户昵称
③ 用户手机
④ 用户密码
⑤ 头像&性别&出生年月&身份证&头像......
当然每个子系统的用户角色不尽相同,所以需要每个子系统自己维护一个用户角色表:
1 //用户总表 2 //公司用户不一定都是子系统的用户,但子系统用户一定存在与公司用户总表中 3 var users = [ 4 { 5 id: '1', 6 phone: '13579246810', 7 name: '昵称1', 8 infos: '其它公共信息' 9 }, 10 { 11 id: '2', 12 phone: '13579246811', 13 name: '昵称2', 14 infos: '其它公共信息' 15 }, 16 { 17 id: '3', 18 phone: '13579246812', 19 name: '昵称3', 20 infos: '其它公共信息' 21 } 22 ]; 23 //子系统A中的用户表 24 var a_users = [ 25 { 26 id: '1', 27 roleId: '1'//游客 28 }, 29 { 30 id: '3', 31 roleId: '2'//超级管理员 32 } 33 ]; 34 //子系统B中的用户表 35 var b_users = [ 36 { 37 id: '1', 38 title: '教授'//游客 39 }, 40 { 41 id: '2', 42 roleId: '副教授'//超级管理员 43 } 44 ]; 45 //子系统C中的用户表 46 var c_users = [ 47 { 48 id: '2', 49 address: 'xxxx', 50 title: '三甲'//游客 51 }, 52 { 53 id: '3', 54 address: 'xxxx', 55 roleId: '二甲'//超级管理员 56 } 57 ];
我们在处理用户表的时候,除了抽象基础用户信息时,有可能还需要一层业务公共层,以我们公司为例,多数用户是医生,所以像职称、所属医院这种信息会经常被用到,这个时候就会出现直接使用这种业务公共表的情况:
子系统A与子系统B都是使用的与子系统C一样的用户id,但是他们直接依赖了公共业务关联,他们在公共业务中获取了类似科室、职称等信息,如果这个体系再扩展的话,会是这样的:
公共H5服务
体系化的第二步是H5整合Server服务,当公共的服务出现后,这里便需要提供公共的H5页面,这里会遇到一个难题需要突破:
① 各个业务有自己的定制,比如注册时候要求的字段都不一样
② UI会成为第一个拦路虎需要你去说服
既然是公共页面,就需要满足一些业务的定制需求,当底层框架完善并且统一后,便可以以规范的力量给予业务开发以指导与限制了,只有将公共业务做好后,才能真正提高我们整体的开发效率
第一个问题是业务受限,那就说明公共服务做的不行,不具有通用性,那就改设计,改到满足就行了
第二个问题,肯定是在我们已经有公共服务的情况下,告诉UI,我们这个是公共服务,是不能乱改的,设计要中性化
要整个公司的人都形成公共服务,以及重用,效率的思维后,大家才会认可这个,在人家不知道或者不认可的情况下,说那么多也没用,知行合一才是王道。
一个较为合理的公共页面可能是这个样子的:
所以,后期我们的系统就变成了这个样子了:
当我们这套体系走的足够远后,我们整个系统可能就是这样的了:
打通H5与Native
体系化第三步是整合H5与Native资源,这里也是所谓的Hybrid体系,只有在前两步完成后,才能很好的完成这一步,否则就只能称为内嵌页,不能叫Hybrid,更不能说是什么移动体系化。
整合Native与H5的第一步仍旧是账号打通,一般来说,我们强制要求native中H5只能使用native提供的统一页面进行登录,不管这个页面是native的还是H5的。
事实上,我们H5端就登录一块做了三套页面一个弹窗,一套账号登录(废弃)、一套手机号登录、一套手机号登录并且带第三方登录,还有在页面里面直接弹出的登录框,一个个APP中是不应该允许存在两个退出账号或者有个人信息的地方。
设想,如果H5具有自己的登录,那么整个情况会变得极其复杂,首先APP具有一套自己的登录,而H5如果与APP登录了不同的账号,那么就会存在用户串了的情况,当然,APP可以监控H5的登录态变化,但这个东西技术实现成本比较高,并且容易出错,所以我们这边要求所有H5的登录全部走Native的一套体系,每次Native打开webview时,如果有cookie就注入webview,这样前端就自己有登录态了 一旦当app注销账户,之前所有的页面也将全部弹出掉,新开一局,如此一来账号体系已经打通。
Hybrid化
当做到H5与Native账号打通后,我们便可以实行我们的Hybrid化进程了,这里简单以Header为例。
主流Hybrid都是使用的Native的Header,原因有很多:
① 稳定,防假死
我们料不到前端会出什么错,特别是第三方网站,一旦前端出错如果iOS连个退出的按钮都没有,那么就app假死了,这个比crash还讨厌
② 体验
我们在刚打开一个H5页面时,可能会有白屏,如果header也不在的话,体验会比较差
而我们在设计Header交互时候,需要考虑到前端的使用习惯,最好能保持业务代码一致,处于不同宿主容器表现不同,这里的设计是左中右的设计,图中就是我们能提供的所有header样式了,不够也没办法咯。
完了我们需要对tagname定制化,header中的所有按钮的唯一标识为tagname,所以tagname不得重复,其次常用tagname会有一个默认图标,需要定制化的话,就读取线上资源。
这里back比较特殊,在webview中会检查history的记录,如果大于1则后退,否则会退回上一步操作。 我们可以看出,back的功能是很单一的,往往不能满足我们的需求,所以常常使用forward+pop动画当做back使用,而这一做法将引起令人头疼的history错乱问题,针对这种情况我们有一些特殊API,但是因为这个API需要Native支持,所以使用需要慎重,最好是新增一个native接口,用于跳转后,清除所有的history webview。
Header约定是Hybrid的重要一环,也是移动体系化,技术体系化中重要的一小环,与之对应的会有:
① 分享约定
② 登录唤醒约定
③ 离线包机制
④ 跳转机制
......
这里体系化做的足够好的话就会出现类似微信SDK一般的东西,但是这个要看你们是不是有足够多的第三方接入方需要你们费这个神了,但是只要做到这一些,你的移动端便已经体系化了,所有的H5项目的账号系统与基本native打通是完成了。
这种体系化的东西形成后需要做到通用,比如两个app能同时运行同一个H5站点,甚至离线包机制都是一致的,header交互也是一致的
数据可视化
上述工作做完,表现层的东西就做了一大部分了,站在前端的角度的话,可以做的东西好像不多了,其实细细一想,有这种想法真的是图样图森破,就算要把上面的事情做完都要费老大的劲,况且真正的难点可能才真正的开始,如我们第一张图,我们有一个项目外包了,那个外包的用户是游离于我们账户体系外的,我们应该如何处理?而更让我们头疼的可能是数据收集与分析,猛的回头,你会发现,对于前端,还有数据可视化这么一大坨的东西需要你去挖掘!
随着技术的沉淀,公司的发展,公司的业务虽然越来越复杂,但是在我们的体系下,都还能很好的运转,但是业务才是技术的祖宗,我们可能会收到类似这种需求:
① 请给我一下上次迎新活动3个月后的用户留存率
② 请给我XX推广人员的订单推广率
③ 请给我APP由XX二维码推广活动的数据
④ 请告诉我为什么我们转化率低
......
用户&订单渠道
可以相信,所有这一切必定会将你问懵,一般来说,不是所有前端一开始设计便能考虑到这些问题,也不是考虑到这些问题就能设计得好,这里简单以用户业务渠道做一个说明。
为了解决以上问题,我们在设计用户表的时候就得新增一些字段了(比较痛苦的是最开始没有这些东西,后面加就恼火了):
① 项目来源,标志该用户(订单)来源于哪个子系统
② 业务来源,标志该用户(订单)来源于什么渠道
这个渠道就比较复杂了,可以是推广人的拼音,可以是一个活动的标志......
这个设计其实比较简单,就是新增几个数据表字段嘛,真正的难点在于前端&native调用,一般来说,我们希望业务开发无感的便存入进去了,所以我们可以这样设计:
① 在url(cookie也行,就是麻烦)上加入一个channel的参
这里如果不使用cookie需要前端框架做处理,保证每次跳转将这个channel参数一直带下去
② 每次ajax请求的时候将这种新增一个入common的字段,让server端自动处理
所以,业务开发只需要在url做处理(生成二维码的时候带上参数),前端框架统一处理后,每次请求就自动带上了,比如:
http://medlinker.com/h5/interlocution/index.html?med_channel=qq
native处理方案类似,这里处理完了,我们便可以收集到用户(订单)来源于哪个渠道了,有了这个数据收集便能很好的做后续的分析。
补足体系
上述是业务方的数据收集,这个属于精准定制结果,直接接口存储,除此之外,我们还需要对整个子系统进行数据打点采集,比如页面pv+uv+按钮点击,这个是比较简单的需求,如果一个H5站点用于了多个容器(微信、qq),而每个容器(渠道)产生的pv信息需要记录起来的话,便会有些麻烦。
数据采集这块是我最近准备做的东西,事实上这块我也很有一点一筹莫展的感觉,首先碰到第一个问题就比较令人头疼?
我们到底是应该自己从无到有做一套采集打点系统还是应该直接使用友盟或者百度统计这种第三方的东西?
这里因为我也还没有想清楚,便不做展开,当这块形成后我们整个体系就变成了这个样子了:
经过将近一年的努力,我们逐步构建了这个移动体系化,并且正在向各部分添砖加瓦,现在在以下模块仍然有所缺失:
① 数据可视化缺失,如上所言,这块是我们接下来需要补足的,这里又包括了数据采集,存储,分析,展示多个方面,总之可以做的很多。
② 通用IM消息系统缺失
我们现在Native使用的自身的IM,H5与Native由于原来北京成都两个团队而选择了融云体系,现在整个消息系统没有打通,这里是需要打通的,以后就算大家选用第三方的服务,都一定记得让自己server端做一次收口工作,做一次proxy,这个如果后期需要改造更换消息系统会轻易的多!
③ 日志监控
我们的日志监控与预警一块做的也不够完善,这里包括前端预警与server端预警,这块接下来要加强
④ 全站https化
......
其实除了上面的一些,应该还有很多其他体系模块没有被提出,比如:
① 开发环境
一般环境分为开发、QA、预览(生产某一个机器)、生产四个环境,环境是比较好做区分的,但是难点在于通用的发布系统与各环境的数据处理问题,比如QA环境就是需要一些生产环境的数据,这个时候该怎么做???
② 小流量发布
有些时候,我们为了测试,可能需要小流量发布,一方面为了关注流量变化,一方面为了确认没有错误,我们需要这种系统,同时也需要我们的可视化系统记录各种情况的转化率等数据
这里也仅仅是我(前端角度)所了解的移动体系,也许换个人来,又会大有不同,不管是什么样的体系,都一定要保证,自己的公司是有一套开发所依赖的体系的,这个东西会极大的提升开发效率与稳定性!
体系设计
在我看来,体系的设计与出现不是一朝一夕的事情,也不是凭空设计,脱离业务,每当我们需要在我们的技术体系中添加模块的时候都需要思考一些问题:
我们提出的这个东西是要真实解决我们开发中的什么痛点?
这个会需要我们具有一定的特质:
① 有强烈的意识,能了解性能的缺陷,开发效率低下的原因,并能提供有效的处理办法,再此之上进行抽象
② 对于团队中搁置的老大难问题,要想办法进行有效的推动、处理
而,我们体系化的东西也不是过家家产生的,这种比较通用的设计必须要出文档,必须与人商量,技术方案里必须的流程图、时序图都要规范,还要把设计要完成的关键参数标注好,最后作为验收标准。方案出来之后要确认方案如何落地,操作路线是什么,执行计划是什么,怎么处理团队间的阻力。
比如我们上面做的通用的登录注册页面,就需要相关的文档,要描述清楚,我们这个东西的边界是什么,能解决什么问题,有什么限制,体系设计推动任重道远,你我共勉。
工作态度
我在上海工作期间学习到的另一个受用无穷的知识便是“正能量”了,其实正能量并不能让你多写几行代码,但是他会令你的工作状态持续上升,与之对应的是负能量,如果你身边有小伙伴产生负能量的话,就一定要小心了,负能量就确确实实能让你少写几行代码了。
当时携程无线解散的时候,需要我们并入其他团队,不知不觉间就生出了一些负面情绪,我们是后爹后妈养的,过去肯定没好日子过了,于是那段时间各种消沉,也有换工作的准备了;而团队两个老大哥的表现却截然相反,一个老大哥仍旧是勤勤恳恳的工作,帮助团队乃至整个公司渡过了当时比较困难的技术交接时期,另一个老大哥积极的协助新团队推动新框架,甚至那个框架都不是我们写的。
后来,我经常与两个老大哥交流,一个老大哥(来自华为)传给了我“忍、滚、狠”的绝技,另一个老大哥带着我领会了皮实的意义,其实这些道理真的很简单,我们处于顺境的时候,自然意气风发,那么当我们处于逆境中的时候,我们就应该自暴自弃、消沉不已吗?
时至今日,我有点什么疑惑的地方都经常喜欢请教两位老大哥,我也从他们身上学到了,其实在抓技术的同时,协调推动能力也是至关重要的,因为现在很多业务都是几个部门在做,如果没有良好的推动能力的话,极有可能iOS一套东西,Android一套,前端自成一套,这种对整个公司来说是一种浪费,需要有人站出来整理整合。
团队战斗
我十分喜欢武侠,近期特别喜欢剑雨中的一段戏份:
当时是转轮王手下三大高手,雷彬、彩戏师、细雨等五人戏份(大S可忽略),彩戏师提出你我三人联手格杀转轮王如何,并开出了条件等待交易:
我(彩戏师)只要罗摩遗体
全部财产给雷彬
细雨回去和爱人过小日子
显然,彩戏师的价码是足够让人动心的,他也提出了相当的诚意,主攻转轮王去了,这个时候雷彬开始了观望,然而细雨一声“你们玩,我回家和相公吃饭去了”,直接把整个交易堵死了。
这部戏其实真的非常精彩,如果他们三突然达成一致跑去围杀转轮王,我才会感到奇怪。考虑到电影才过3/4,观众可能会说那么这一切岂不是太轻易了?但是从真实社会阅历来说,这桩交易达成的概率很低,一个核心原因是:
这笔买卖涉及了大多数人的利益,乃至生命,一旦一件事情涉及了多个人的利益,那么这个事情势必会很慢、很难达成一致
我们做一件事情时,但烦需要他人合作共事,就一定比一个人难多了,人和人之间想法差异是及其巨大的,就看剑雨几个主要人物的需求:
① 转轮王,需要罗摩遗体长jj,好xxoo
② 彩戏师,需要罗摩遗体治病
③ 雷彬,需要钱与不受控制
④ 细雨,需要爱,需要家人不受伤害
⑤ 大S,也许是需要关注吧
可以看到,里面最核心的利益冲突是来源于转轮王与彩戏师的,这也是为什么处于弱者的彩戏师要先出手,表达诚意,其他人可以观望,可以退出。
同样,团队之中,人和人的差异是巨大的,这种差异甚至是难以调和的,在这之中就一定会有一个智障或者特别有私心、或者懒惰、或者喜欢单独和上级沟通的,只要一个队友有一项或者几项毛病,整个团队就会扯皮,而处理扯皮是内耗的事情,但这种内耗又往往比正经做事要花费更多的精力。
在团队内,各个小伙伴性格各异,彼此较劲;然后团队之间又有分别,产品与研发彼此对立,就算一个公司,内部也有派系之分,小至一个家族也会兄弟拆墙,讲到底,分的是彼此,争的是权利,除了自己人就不是自己人,不是自己人就算别人,这个分别不知何时才能停止。
因为是人都会有分别,产品变更了需求,就比开发改了我代码更可恶;上海分公司的产品欺负了深圳分公司的研发,又比身边的死UI更加可恶,大大小小的分别,职位的分别,地域的分别,亲疏的分别,人很容易就可以找到和自己不同的族群作为敌人,所以纷争很难停止,解决分别心这种佛学的话题显然我们无能为力,所以选人就变得尤为关键。
综上,要让团队有战斗力:
① 首先就要有好的计划
② 其次要有好的leader
③ 然后找合适的人
⑤ 最后打到共同的敌人(项目)
好的方向才可能出好的结果,任何没有计划的事情都收效甚微,好的leader才能团结团队,技术要过硬,视野要够远,抢业务要凶猛,而慈不掌兵,如果有和团队气质不符,甚至起到反作用的,一定要提前剔除(劝退是最后的手段,更多的应该是影响),否则吃亏的是整个团队。
这里再强调下leader的作用,团队的战斗力需要leader去激发,leader作为公司的执行意志与核心驱动力,需要起到正确的带头作用,要有足够的责任感与危机感,要善于汇报工作,争抢业务,如果你的leader总是把业务往外面推,那么这个leader是不合格的。
因为,我们是来工作,是来赚钱的,我首先是来赚钱的,其次才有团队小伙伴的战斗情谊,如果没有业务就是没有KPI,没有KPI就是没有钱,连最基本的发展都没有的话,再好的私交在公司面前也不可持续,我们是因为这份事业才在一起的,梦想&激情这种属于稀缺的消耗品,不是人人拥有的。
个人与团队的关系,矛盾而又统一,完全追求个人能力成长最大化必定和团队利益冲突,如果能合理运用团队又能打破个人的局限,所以团队合作才是突破一切的关键,一个人的力量是有限的,遇到困难也更容易突破,如果发现一些事情,团队中只有你能做,就要小心了。
结语
本来写此文是因为昨天驾考挂了,当时写出来的东西,感觉比较消极,于是今日抽一些时间重新整理一番,梳理思绪情感,一起积极面对2017年吧!!!
其实,小公司真的有很多独有的优势,很多坑等着你去做,去思考,只要能把这些坑一个个填平,那么必将会有长足的进步,也能尽快的突破自我瓶颈。
文中想法系个人想法,或许有问题,请积极交流。
最后,科目三补考求过!!!