1.4 我的漫漫探索路

短短的联合研发结束后,我又回到了自己原来的部门,还有原先的工作模式。大家应该都有这种体会,如果一直呆在大城市的雾霾中,可能慢慢就迟钝了,但到风景秀丽的地方度假两天,感受一下清澈的世界,回来立马会有诸多不适应,而这恰恰就是我当时的真实内心感觉。

在联合研发的过程中,我做了很多工作笔记,同同事分享,大家都听个稀奇,然后就……,基本上就没有然后了,这让我非常的苦恼,有一种抱着金碗要饭吃的挫败感。

我自己部门负责的产品经过多年的迭代,已经固化了,而且大多同公司管理体系深度融合在一起,牵一发而动全身,根本无从下手。各种高复用的软件模块是很好,但需要复杂的支撑环境,如上面描述到的104规约复用策略,想想就是不可能实现的事情,这根本不是一个小团队能够做到的。

再说,大家平时的工作都忙死了,即使有空,如果你胆敢安排和当前工作“无关”的事情,估计会被领导骂死吧。

网络上经常有人感叹,知道了很多道理,却依然过不好这一生。看到和做到,虽然只有一字之差,但却有天壤之别。虽满心不甘,但如无意外,我估计自己会像祥林嫂一般,在喋喋不休的埋怨中平庸下去。

◇◇◇

有段时间,我身旁多出一个新招来小伙,因为他的领导“太忙”没时间管他,整日有点无所事事。我看小伙挺好学的,于心不忍,经常指导他一下,顺手将自己正在写的一个软件拷给他参考。

一段时间后,小伙和我说程序看的差不多了。我内心怦然一动,免费的资源不能浪费啊,因此和小伙说,程序仅仅看是没感觉的,你最好能动手写一写,实际参与一下,才能真正的学到,不然都是过眼云烟。道貌岸然的说完这段冠冕堂皇的话,我将一个自己一直想做但一直没时间做的软件模块推给了这个小伙。

不久,小伙告诉我做完了。我打开程序一看,虽然有一些考虑不周之处,但还算是很漂亮的完成了任务。为了偷懒,也为了让这段程序看起来像自己写的,我进一步要求小伙将这段程序编码规范修改的和周边程序一致。

当时,我们项目组都是每人负责一块代码,大家写代码也基本是个人英雄主义,我自己的代码哪有什么约定的编程规范,经常是今天一时兴起模仿这个高手,明天就忘到九霄云外了,前后不一致处比比兼是。但即使如此,小伙也给我模仿了个八八九九,乍一看,和自己写的也差不多。

一次意外,换来了一份欣喜,也让我内心开始活络起来。从此,我在公司里以好带人而闻名,甚至被挂了一个优秀导师的称号。当然,与此同时,很多新入职的员工,甚至一些还没正式入职的实习生都被我下过黑手,每个人都多多少少顺带着贡献了一些代码。

在这个过程中,最典型的就是维护软件了。从公司的角度看,维护软件是非卖品,因此几乎不会额外安排人力和时间,如果看到你周报在做维护软件,下周立马就会安排新任务了。但对于整个产品研发来说,维护软件又是必需品,很多调试、测试甚至车间生产工作都需要维护软件配合。有了维护软件,感觉产品研发才闭环了。

一开始,我仅仅是简单弄了一个小软件用于应付调试,但这活一旦揽上后就麻烦不断,各种需求层出不穷经常让我疲于奔命。我在想,是否可以充分利用新人资源来完善维护软件呢。

为了适应这种偷懒模式,我开始尝试重构维护软件。首先将其架构重新进行了优化(本书相应章节会详细介绍维护软件框架,让大家理解如何做到这一步),以便于多个新人可以分别完成不同的软件模块。然后开始形成统一的编程规范,并形成文档,指导新人养成好的编程习惯,好让别人写的代码看起来像我写的。

时间的力量是无穷的,没多久,我的维护软件就快速充盈起来,甚至有空做一些好玩的稀奇古怪的功能。更重要的是,在这个过程中,我体验到一种全新的工作方式,我只要能做到高效辅导新人,审核并合并代码,一个新的软件就构建完毕了。不仅我个人工作效率提升了很多,而且也真正帮助到了新人。

细细思量维护软件这个奇妙的经历,虽然是为了偷懒的奇葩产物,做法有点野,但难道不和跨国企业内部很重要的价值流概念很相似吗?

◇◇◇

工控产品因为应用领域差异较大,经常有系列化的需求,但这也给产品研发带来了困惑。如产品A中有一种“设定值”的数据结构,用于用户参数设定,属性主要包括名称,描述,数据类型,默认值,最大值,最小值等。碰到这类数据结构,我们很自然的会想到使用C语言结构数组来描述,如下代码示例。基于这样的数据结构,程序实现起来会容易很多,即使增加或减少一些设定值时,仅需要修改数据结构即可,不需要该动程序主体。

/* 定值属性描述结构 */
const TAPISettingProp g_apiSettingProp[] = {
	{
		“CT接线方式”, 0, 2, 8, 0, 2,
		0.000f, 1.000f, 0.000f,
		&SET_uCTLineType, (TAPICoeffProp*)&g_apiCoefProp[19]
	},
	{
		“PT接线方式”, 0, 2, 8, 2, 2,
		0.000f, 1.000f, 0.000f,
		&SET_uPTLineType, (TAPICoeffProp*)&g_apiCoefProp[19]
	},
	……
};

现在假设产品B也需要这种“设定值”怎么办呢?我们容易想到的最简单策略是将上述结构单独移到一个文件中,然后针对每个产品弄一个特定描述文件。

现在假设要拓展海外业务,领导要求你赶快弄一个英文版本该怎么办呢?没法子,赶快在弄一个特定描述文件。

碰上有个性的客户,他们坚持一些习惯称谓,你被迫又需要改一套。

……

这也太苦逼了,现场随便来点需求,我就需要修改并下发程序。控制程序下发流程的那帮大爷可不管你是否仅修改了数据结构,各种流程一个都不能少。有没有办法将这部分工作甩出去,让工程人员现场就可以修改呢。被逼无奈,我开始对上述数据结构进行参数化改造,将数据模型提炼组织起来,在额外写一个小程序生成参数。从此以后,这类问题工程现场想怎么改就怎么改,我顶多写个说明文档,在费点口舌给工程人员讲解几轮,然后就再也不会因为改个名称或浮点小数点位数等琐事而整日下发程序了,幸福的日子开始回归了。

我写的超级简陋的参数生成软件如下图所示:
在这里插入图片描述
我承认,跨国企业为了做到代码高复用率,需要很复杂的配置软件,我做不来。但细细思量这个小软件的奇妙经历,我发现虽然自己的做法简陋了很多,但难道不似曾相识吗?

◇◇◇

反思两个简单的例子,我发现自己有时候已经走了很远,只是自己懵懵懂懂无意识而已。那么现在我已经看到了方向,如果能多一点主动行为,可否可踏上这条架构师之路呢?

走上这条路,我个人的能力有限,仅靠个人肯定是不行的,而且也势必会影响到很多人的工作方式。额外,同维护软件类似,平台化一开始肯定需要做很多基础性工作,初期也不容易见效。我如果和领导直说,估计会被直接拍死吧。有什么好的策略呢?

在公司经常会碰到各种奇葩的事情,领导如意识到内部管理混乱时,经常会引入外部各种高大上管理体系,不仅昂贵,而且经常将原有的工作模式弄得支离破碎,直到最终难以为继。我个人可能因为特定的工作经历吧,比较反感这种做法,不喜欢信息技术部门将某种“新”技术强行推给一线设计或制造部门,而是喜欢那种由内而外,由最底层需求驱动并借力新技术的模式。

如何将我看到的好的东东慢慢融入已有的产品研发体系呢?最好的驱动方式又是什么呢?我是一个懒人,特讨厌各种低层次重复的工作。我估计大家都差不多吧,偷懒,是非常契合人性的需求。在一次,我祭出了“偷懒”这一绝招。

首先是添油加醋的同团队内成员分享我在维护软件中偷懒的光辉经历,然后发出诘问:“你是愿意一辈子重复这些无聊的代码呢,还是愿意走上架构师之路”。很快,大家形成了统一的共识,团队内部形成了统一的代码规范,大家都开始有意识的锻炼指导新人和代码审核的能力。

刚开始可能会比较混乱一些,但没多久,我发现自己竟然开始有空余时间了。跨国企业做产品时,为了适应不同区域的需求,经常会构建第二层开发环境,其中最重要的模块就是类脚本模块,我开始花精力攻克这个软件模块。

在这之前,研发团队的很大一部分工作是做各种现场特殊版本,时间紧,要求变态,还经常将我的团队人员抽调到现场不放回来(研发人员比工程人员好用,而且免费,v_v),弄得大家苦不堪言。但自从有了脚本模块后,我开始有一种特“爽”的感觉。现场工程人员打电话来,用户需要一个特殊要求,我经常直接电话指导,巴拉巴拉半个小时后,一切搞定。今天效率太高了,要不休息休息,泡一杯茶,品着茶香,怎一个“爽”字了得。

从此以后,我们团队好似玩起了开挂模式,以前弄几款产品就累的半死,现在不小心已经维护了一堆产品了。当然,新情况也带来了新问题,各产品之间代码开始慢慢混乱起来,维护工作量又开始慢慢增加了。

为了进一步偷懒,我开始尝试整合这些乱七八糟的产品代码。先易后难,先从大家都用的公共辅助函数开刀,慢慢的在啃那些乱七八糟耦合的程序模块。

◇◇◇

为了偷懒,我在勤奋的折腾着,而每次折腾,都给我意外的惊喜,让我更加坚定的偷懒。时光荏苒,岁月如梭,转瞬八载过去了,惊奇的事情开始发生了,原先在我眼中跨国巨头那些不可思议的做法,我们竟然模仿了一个似模像样。

这儿和大家分享一些我们取得的成绩:

  1. 构建出平台、产品、工程三层研发体系
    前文提及我很欣赏跨国公司这套做法,但跨国公司那套基于FB的代码复用机制过于复杂,很难模仿。在实践中,我们通过加强各模块的api抽象,利用参数化和脚本支撑模块,竟然也让代码复用率大幅度提升,新产品的代码复用率基本都超过了70%。记得有一次,同一个公司竞争某光伏项目,其关键在于谁能在三周之内研发出一款满足特定需求的新产品,最后,另一家厂家退缩了,因为他们无论如何也完不成。因为极高的代码复用率,我们在约定时间内将所需产品折腾出来了,内心成就感油然而生。

  2. 软件体系架构
    大家还记得我前文提及,成为架构师是我的奋斗目标之一吗?刚开始的软件复用基本谈不上什么架构设计,但随着持续迭代演化,很多巧妙的设计理念开始层出不穷,我的架构设计能力也在潜移默化中提升了。如为了将将无数个复杂的模块有机的组织在一起,我设计了静态程序架构;如为了让程序既可以在前后台系统运行,又可以基于OS运行,我设计了程序动态执行框架;如为了适应产品组件越来越多内部交换繁杂的情况,我设计了基于can的分布式架构……。最后,一点一滴的,我好似搭起了一座颇具规模的大厦。

  3. 持续的质量控制提升
    为了将自己从救火队员的身份中解救出来,我们在反复折腾尝试中,最终提炼出了三个非常有效的策略:代码审查机制、集成测试机制、在程序框架中内建异常检测及主动防御机制。某一次,公司领导找到我,让给大家分享一下,为何我负责的产品能够做到零返修。此时,我才意识到自己不小心已经走出去了一大步。实际上哪儿是零返修,仅仅是在用户还没有暴怒之前我们已经将所有问题给解决了,大家感觉不到而已。而这个过程中,各种异常或边界判断机制帮了大忙。

  4. 高效适用的文档体系
    没有文档的产品是不完备的,但写文档又会加重大家的负担,且很多时候劳而不功,大家抵触情绪会很强烈。为了解决这个问题,我在反复尝试中,形成了一套高效实用的文档体系,包括:以图表为主要表现形式的架构设计文档,以A4纸为主要形式的接口设计文档,强调迭代和闭环集成测试用例文档,产品说明书,服务于新人成长和代码审核的知识库文档。除此之外,如果人数少,现地现物通过周例会就能搞定,人数多时可以增加一定量的工作日志文档。在这套体系中所有的文档都是必须项,同时必要的文档项目团队也会认真对待,最终构建出一套高效适用的文档体系。

  5. 如臂使指的团队建设
    因常年从事具体技术工作,团队建设一直是我的弱项,内心甚至有点抵触情绪。但我又需要带着小伙伴们一起做产品赶项目,新人需要入职培训,老人也需要职场提升,怎么办呢?为了构建那种如臂使指的团队,我先后提炼了最小必要知识、代码审核、A4纸接口设计审核、知识库等诸多工具,让团队中每个人的成长都可视化。水滴石穿,在我以身作则的带头作用下,整个团队最终成功长成了一个积极的学习型团队。

此时,我发现自己对工作的感觉完全变了,好像自己真的成了一名架构师,统领着千军万马,即使面对纷繁复杂的产品,都可以从容面对。您期望这样的自己吗?

2018年,中兴事件爆发,作为一名工程师的我,那段时间内心特别难受焦虑,晚上都睡不好觉。我喜欢逛各种技术论坛,知道国内决大多数小企业和个人都处在非常低级的层次上,又因为特定的工作经历,让我深刻了解国外巨头和国内企业之间的巨大差距。如果一家公司还是传统的研发模式,注定只能做一些低层次的产品,是没有办法同那些巨头竞争的。

正是因这件事的触动,我开始思考如何将自己的工作经历及思考分享给大家,首先对我个人是一次非常大的提升,也希望能帮助到一些人或一些企业。

——————————————

我是小马儿,一个渴望良知与灵魂的嵌入式软件工程师,欢迎您的陪伴与同行,如感兴趣可加个人微信nzn_xiaomaer,需标注“异维”二字。

发布了12 篇原创文章 · 获赞 16 · 访问量 1478

猜你喜欢

转载自blog.csdn.net/zhangmalong/article/details/103523930
1.4