我在华为的三年

大学毕业后的第一份工作是在华为, 从14年7月到16年6月从事的是软件测试,16年6月到17年8月做的是软件开。3年的时光在人生中留下了很深刻的一笔。近期工作发生了变动, 所以想着要总结下在华为的工作,留下些许记录。 第一份工作映像总是最为深刻的,有初入职场的彷徨,有过争吵,有过哭泣,有过抱怨, 但最主要的还是成长。 从学生的思维到职场思维的转变,实际项目的经历(包括整个团队怎么进行分工与合作, 怎么决策等)以及个人能力的成长。

1. 从学生思维到职场思维

小学,初中,高中,大学整整16年的读书生涯让我们习惯了一种做事与思考的模式:老师布置任务,我们想尽办法把答案解答出来。这种模式就是典型的学生模式。当我们从学校毕业进入职场, 尽管我们从身份上来说不再是学生,但毫不奇怪的是我们会把前面整整16年习惯的思维方式--学生思维带动职场中去。从学生到到职场人士做的事情没有本质变化,都是在解决问题和完成任务,但解决问题的方式有非常大的区别。 在我的理解中,职场思维与学生思维有以下几点显著的不同:

主动性
主动性的差异体现在两个方面:

主动去明确任务的目标与要求
主要去思考,去改进如何更高效的解决问题

学生时代我们是被动的, 被动的等待老师布置作业与任务,然后我们再拖拖拉拉的完成作业即可。同时学生时代任务是非常明确的, 多少道题,每道题的答案等信息都是明确的。

职场明显不一样,职场是非常开放的,上级给你任务时可能当前他也不是非常清楚这个事情要做成什么样。 这就需要我们主动去收集相关信息,去搞清楚事情要做成什么样子,去明确事情的目标。

另外一点就是,同一个事情往往有多种解决方案, 这就需要我们主动需思考怎么样更高效的解决问题。

协作性
学生时代是不鼓励协作的,老师不会喜欢同学们协作来完成作业, 协作来考试, 学生时代倡导的是独立完成。

但职场不一样, 职场中问题的复杂度远远超过学生时代。 学生时代的编程题最多就几千行代码,而实际的软件产品少的几十万行,多的上千万行, 一个人不吃不喝一辈子都完成不了。 所以在职场中几乎所有的项目都是团队协作来完成的。

团队分工与协作,这是职场思维中非常重要的一部分。学生时代思考问题,更多的考量是“我应该怎么做”,而工作中应该更多考量的是“我们应该怎么做,我可以做什么”。

利用已有资源快速解决问题
老师是讨厌利用现有解决方案的学生的, 老师讨厌完成作业时抄袭已有答案的学生。

而职场中不一样, 能够利用已有的资源快速的解决问题是一种非常受欢迎的能力, 软件开发中复用也是非常重要的一个方面 。

利用已有资源(现成的解决方案或者存在的经验丰富的人)快速解决问题是一种非常优秀的能力, 这样的能力即能避免现有资源的浪费,也能快速的解决问题,完成目标。

在工作中积极的提问与求助就是利用已有资源的一种表现。

软件行业中如火如荼的开源运动就是这一思维的实践,重用也是软件行业工程能力的一种体现。

为什么有这样的差异

同样是解决问题,完成任务,职场与校园的思考方式有这样大的差异的原因是在于两者的目的不一样。

职场是结果导向的,关注的高效,快速的解决问题,完成任务, 而对过程不怎么关心。
校园是重过程的, 目的是让学生参与训练的过程从而掌握学习的内容。

所以工作的核心,就是利用各种能够利用的资源(不论是自己的知识,经验,还是他人的能力,还是现有的解决方案等)高效,迅速的解决问题,完成任务。

2. 项目运作流程

华为主要的研发流程是IPD流程, 目前在向敏捷转型。

IPD流程是一个按阶段推进的项目开发流程, 整个完成的流程一般要持续半年到一年的时间,可以交付一个完整的版本。一般分为概念,计划,开发,验证,发布,生命周期这几个过程。 开发,测试,资料,SE等不同的角色都是按照这个流程来进行分工与协作的。

概念:主要是分析市场有哪些机会点,这些机会点可以提炼出一些产品的需求, 主要搞清楚要做什么样的产品
计划:主要明确整个项目的预算,人力,进度,一些交付的关键时间点,这个阶端SE要进行需求分析,开发和测试也会参与
开发:包括多个迭代, 每个迭代主要做三件事情:
1.开发测试的需求分析, 开发输出模块设计,测试输出测试用例
2.开发编码
3.测试验证,主要是功能验证
验证:验证阶段主要是实验局验证,需要有实际的局点做验证,输出实验局测试报告。当然还会进行一些DFX质量属性的验证, 基础的功能验证在开发阶段就已经完成。包括一些性能测试,和第三方产品的对接测试,一些用户使用场景的场景测试等。
发布:产品的发布阶段, 主要是一些发布流程
生命周期:产品的维护阶段, 主要是处理,修复产品在实际局点运行过程中发现的一些问题, 一般有专门的维护团队。生命周期一般持续几年左右,结束后该产品不再维护。

敏捷
测试驱动开发(TDD), SCRUM等是一些比较常接触到的和敏捷相关的概念。

敏捷和传统开发模式相比, 个人觉得最本质的区别应该是思维模式的不同。 敏捷是基于经验的学习而后调整的过程, 而传统开发模式是重计划的。 敏捷强调每个周期要交付的都是可工作的软件。

3.技术能力提升

专业能力的提升体现在以下几方面:
1. 产品知识
对工业级的产品和解决方案架构有一定了解,特别是对即时通讯类产品的流程,原理,技术基本都了解
2. 基础知识 一些行业需要的基础知识也是收获, 数据库(SQL/NoSQL),Linux基础,网络基础等
3. 测试知识

测试活动是一种质量保证(QA)活动, 很多公司相应的职位也许不叫测试,而是称为QA。
最大的收获是对软件的质量属性和评估有了比较深刻的认识,那种认为软件只要是实现了要求的功能就是质量是非常狭隘的理解

软件的质量一般需要从以下几个维度去衡量:
功能,即软件有没有实现要求的功能,例如浏览器基本的功能就是能浏览网页, 功能实现是质量中最基础的部分
可靠性, 软件产品在面对一些异常场景时是否有高的鲁棒性, 例如PC在异常断电后要能继续正常使用,不会出现数据丢失,功能异常等情况, 春运期间大量用户买票导致12306系统瘫痪也是系统可靠性不高的一个例子(没有对浪涌场景的可靠性设计)
性能, 性能指标也是产品质量属性中很重要的一环,例如微信在春晚期间能支持每秒上亿次的摇一摇就是微信系统非常重要的系统指标。
安全性,欧洲和美国对软件产品的安全要求非常严格,软件安全性主要是应对日益严重的网络安全威胁。用户数据保护,抗DDOS 攻击,登录系统的防暴力破解等都是常见的安全要求
可服务性, 指系统的安装,部署,使用,维护与升级,系统的运维是不是简单,快捷,还包括系统出现问题时的定位效率等
用户体验, 对于和用户直接交互的产品, 例如手机App, WEB 页面等, 最为重要的可能就是用户体验了, 互联网行业讲究的就是体验为网。体验我理解就是让用户用的爽,App 的UI设计非常漂亮,登录速度很快,响应速度很快等都是体验好的表现,我们肯定不会喜欢用一个界面很丑,用起来还一卡一卡的App 的。

测试工作的一般流程是从需求分析到测试设计,得到的测试用例, 最后根据测试用例的执行结果来进行质量评估,一般是测试报告的形式。穿插在其中的是对修复的问题进行验证,确保修复是成功的且没有引入新的问题。

在产品迭代速度越来越快的背景下,自动化测试是保证产品质量非常有效的有段。自动化测试是持续集成(CI) 的基础, 是持续发布的第一步。

4 CS专业知识

  1. 编程语言 Java/C/C++
  2. JVM 虚拟机原理, 包括GC,类加载, 虚拟机内存等
  3. IOC, MVC, ORM 框架, 包括Spring,SpringMVC, hibernate, mybatis等
  4. 设计模式: 迭代器, 责任链, 策略, 单例等
  5. VoIP, SIP/SDP, REST 等

4. 质量的理解

质量,这里指的是软件产品的质量, 是分层级。 不同的层次有不同的质量要求。

源代码级别的质量要求可能包括如下几个方面

1.效率

时间空间复杂度,圈复杂度不能过高等  

2.可读性

变量命名见名知意,统一的缩进风格,充分的注释等  

3.高内聚,低耦合

一个模块应该恰当好的只做一件事  

4.可扩展性

前期就应该考虑到怎么尽可能改动小的去扩展功能  

5.可重用性

可重用只别的模块不经过改动或改动很小就可以利用已经实现的模块  

6.低扇出,高扇入

扇入指直接调用该模块的上级模块个数,扇入大表示模块的复用程度高  
扇出指该模块直接调用的下级模块个数,扇出大代表该模块复杂度高  
良好的软件结构,通常顶层扇出大,中间扇出小,底层模块则有大扇入  

7.可移植性

程序从一种计算环境转移到另一种计算环境,例如从Windows到Linux ,  从软件对新环境的适应性这一方面反映了软件的质量

8.标准技术

有标准的解决方案就应该使用标准的办法,而不是自己造轮子,这样代码易于理解和维护  

一般比较大的公司都会有自己的编码规范,就是通过规范的形式来部分满足高质量代码的要求,也可以参考业界公认的一些规范:

Google C++ Style Guide

Google Java Style Guide

软件级别的质量,基于源码级别的质量要求基础之上, 还会要求以下几个方面

1. 功能

软件需要实现它预期的功能,  这是最基础的。 实现预期的功能是一个比较复杂的问题,  很多软件专家有许多的讨论。 
个人觉得全功能团队(产品,设计,开发,测试同一团队)是比较高效的方式。

2. 性能

软件在实现要求功能的基础上, 越快越好。

3. 安全

安全也非常重要, 在这样一个复杂危险的世界。

4. 可靠性

可靠性衡量了软件持续正常工作的能力,  一个每天都奔溃的软件肯定不是一个好的软件。  可靠性达到六西格玛
是我们的基本目标。

5. 可服务性

Operation & Management 对运维非常重要。

产品级别的质量, 在要求源码级别和软件级别的质量之外, 还会要求另外的方面

1. 用户体验

体验属于高层次的需求,  和马斯洛需求理论描述的人的需求类似,  产品在满足了前面所说的要求之外,  还要让人体验好,用的爽。

2. 软件之外的质量

如产品文档,手册, 售前/售后服务等等。  

5. 总结

 要尊重人本身的价值, 不从人的性别,年龄,学历,信仰等特征去评判一个人。
 遇事要有静气,  能做到泰山崩于前而色不变最好啦。
 每天都要问自己学习到了什么, 有什么收获。 人可以累, 但不能停止思考, 不能停止学习。  要不停的更新自己,与世而移!

6. References

Google C++ Style Guide

Google Java Style Guide

Agile Methodology

Agile software development