这篇文章是针对华为的软件训练营(Java语言)的网上学习总结,主要有以下内容:

  • 职业发展规划
  • Java编程规范
  • 敏捷开发之道
  • 软件测试基础

职业发展规划

首先,公司给出软件开发需要的各项软件能力具体要求,主要有软件需求、架构、设计、实现、验证、维护六个方面的能力,并且给出了任职级别的八个等级:

如何学习编程

  • 从脚本语言开始:建议Python(JS,Ruby等)
  • 精通一门面向对象语言:建议Java/C#
  • 精通一门底层编码语言:建议C(汇编等)
  • 最好是把五种语言都学会了:Python,Java,C/C++,Perl和LISP

不断的循环渐进

  • 多学习:计算机基础,比如数据结构与算法
  • 多练习:OJ,竞赛,小游戏
  • 多思考:没有最好,只有更好
  • 多总结:知识的一次升华,输出文档
  • 多交流:学习别人更好的经验

Java编程规范

排版

规则

  • 在不同概念之间,增加空行
  • 将逻辑紧密相关的代码放在一起
  • 控制一行的宽度,不要超过120个字符
  • 控制一行的宽度,不同概念之间增加空格(关键字、变量、操作符等),以区分概念
  • 控制采用缩进来区分不同层次的概念,对齐时只使用空格键,不适用TAB键
    建议:
  • 将局部变量的作用域最小化
  • if,for,do,while,case,switch,default等语句独占一行,且if,for,do,while等语句的执行语句无论多少行都要加括号{}
  • 控制文件的长度,最好不要超过500行

注释

原则:尽量用代码来解释自己
规则:

  • 注释应解释代码的意图,而不是描述代码应该怎么做
  • 保证注释与代码一致,避免误导
  • 注释应与其描述代码位置相邻,放在所注释代码上方,并与代码采用同样缩进
    建议:
  • 不要用注释保留废弃代码
  • 不要用注释记录修改日志

命名

原则:团队为包、类、方法、变量取一个好名字,使代码易于理解

  • 能清晰表达意图:使用完整的描述性单词
  • 避免造成误导:如String accountList不是一个List类型
  • 避免不必要的编解码
  • 能区分出意思:不要在变量/类名后加data、info、object等一般意义的词语
  • 不用或少用缩写:小于15个字母的一般不用缩写
    规则:
  • 禁止使用魔鬼数字,采用静态变量或枚举来代替
  • 常量命名,由全大写单词组成,单词间用下划线分隔,且使用static final修饰
  • 变量、属性命名,使用名词,并采用首字母小写的驼峰命名法
  • 方法的命名,使用动词和动宾结构,采用首字母小写的驼峰命名法
  • 类和接口的命名,使用名词,并采用首字母大写的驼峰命名法
  • 包的命名,有一个或若干个单词组成,所有的字母均为小写
    建议:
  • 数组声明时使用int[] index而非int index[]

变量和类型

原则:谨慎使用静态成员变量
规则:

  • 避免随意进行强制类型转换,最好改善设计,否则需在转换前用instanceof进行判断
  • 需要精确计算时不要使用float和double
  • 不能用浮点数做循环变量
  • 浮点型数据判断相等不能直接使用==,转化为Math.abs(a - b) < 1E-6f
  • 避免同一个局部变量在前后表达不同的含义

方法

原则:

  • 方法设计的第一原则是要短小,建议不超过50行
  • 方法设计应遵循单一职责原则(SRP),一个方法仅完成一个功能
  • 方法设计应遵循单一抽象层次原则(SLAP)
  • 方法设计应遵循命令与查询职责分离原则(CQRS)
  • 不要把方法的入参当作工作变量/临时变量,传引用类型建议在参数前加final关键字
  • 静态方法应使用类名来调用
    建议:
  • 应明确规定对接口方法参数的合法性检查由调用者负责还是由接口方法本身负责
  • 对接方法的参数不宜过多
  • 谨慎使用可变数量参数的方法

包、类和接口

原则:

  • 类和接口的设计应遵循面向对象SOLID设计原则
    • 单一职责原则(Single Responsibility Principle)
    • 开放封闭原则(Open CLosed Principle)
    • 里氏替换原则(Liskov Substitution Principle)
    • 接口分离原则(Interface Segregation Principle)
    • 依赖倒置原则(Dependency Inversion Principle)
  • 类的设计应遵循迪米特法则
  • 类的设计应遵循“Tell, Don’t ask”原则:告诉对象你希望它们去做的事情,而不要询问它们的状态之后做出决定
    规则:
  • 除提供给外部使用的全局变量外,应尽量避免类成员变量被外部直接访问
  • 避免在无关的变量或无关的概念之间重用名字,避免隐藏(hide)、遮蔽(shadow)和遮掩(obscure)
  • 不要再父类的构造方法中调用可能被子类覆写的方法
  • 覆写equals方法时,应同时覆写hashCode方法
  • 子类覆写父类方法时应加上@Override注解

异常

规则:

  • 只针对真正异常的情况才使用exception机制
  • 在抛出异常的细节信息中,应包含能捕获失败的信息
  • 对可恢复情况使用受检异常(checked exception),对编程错误使用运行时异常(runtime exception)
  • 不要忽略异常
  • 方法注释和文档中要包含所抛异常的说明,内容包括什么场景会抛出该异常,该如何处理它
  • 方法抛出的异常,应该与本身的抽象层次相对应
  • 在finally块中不要使用return、break或continue使finally块非正常结束,导致异常无法抛出
  • 不要直接捕获受检异常的基类Exception
    建议:
  • 对第三方API抛出大量各类异常进行封装
  • 一个方法不应抛出太多类型的异常

语言特性

运算和表达式
规则:

  • 不要编写复杂的表达式
  • 运算时应避免产生溢出
    建议:
  • 运算采用括号明确运算优先级

控制语句规则:

  • 在switch语句的每一个case、default中都放置一条break语句
  • 采用for-each代替传统for循环

泛型规则;在集合中使用泛型(v1.5+)
其他规则:新代码不要使用已标注为@Deprecated的方法

敏捷开发之道

IPD:Integrated Product Development,软件工程中集成产品开发流程,包括四个DCP决策评审点,七个TR技术评审点,一个LAUNCH点,一个GA点。

敏捷宣言:

  • 个体和交互胜过过程和工具
  • 可以工作的软件胜过面面俱到的文档
  • 客户合作胜过合同谈判
  • 响应变化胜过遵循计划

敏捷开发遵循软件的客观规律,不断的进行迭代增量开发,最终交付符合客户价值的产品
统一认识:敏捷 = 理念 + 优秀实践 + 具体应用

  • 理念:VTA原则,VALUE,TEAM,ADAPTING
  • 优秀实践:敏捷的经验总结,比如站立会议与结对编程,持续集成与测试驱动开发,重构与迭代
  • 具体应用:结合自身灵活运用才是真正的敏捷

软件测试基础

测试定义:测试是一个包含计划、准备和测量活动的过程。其目的是确认被测系统的特性,并指出需求和实现之间的差异。不同类型的测试在软件生命周期的位置:

下图是按照目标/特性,测试阶段或层次,方法的测试分类,作为开发人员需要掌握单元测试,了解其他阶段的测试:

一些测试方式

静态测试:静态测试技术通过手工检查(评审)或自动化分析(静态分析工具)的方式对代码或其他项目文档进行检查。

  • 代码检查工具检查(pclint,圈复杂度检查)
  • 走读(walk through)
  • 检视(inspection)

动态测试:通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能,这种方法有三部分组成:构造测试实例、执行程序、分析程序的输出结果。

  • 等价类划分
  • 边界值分析
  • 决策表分析
  • 判断条件覆盖
  • 条件组合覆盖

黑盒测试:把被测对象看作一个黑盒,测试软件产品的功能,而不需关注软件产品的内部构造和处理过程。

  • 等价类划分
  • 边界值分析
  • 决策表分析
  • 状态转换测试

白盒测试:根据被测程序的内部设计测试用例的一种测试方法。

  • 语句覆盖
  • 判定覆盖
  • 条件覆盖
  • 判定条件覆盖
  • 条件组合覆盖
  • 路径覆盖

测试基本原则

  • 测试显示缺陷的存在
  • 穷尽测试是不可能的
  • 测试尽早介入
  • 缺陷集群性,二八法则
  • 杀虫剂悖论
  • 测试活动依赖于测试Context
  • “Absence-of-error”谬论

测试常用术语

  • Test basis(测试依据):能从中判断出组件/系统需求的所有文档。测试用例是基于这些文档的。只能通过正式的修正过程来修正的文档称为固定测试依据
  • test condition(测试条件):组件/系统中能被一个或多个测试用例验证的条目或事件。例如,功能、事务、特性、质量属性或结构化元素
  • test coverage(测试覆盖):用于确定执行测试套件所能覆盖项目的程度,通常用百分比来表示。
  • exit criteria(出口准则):和利益相关者达成一致的系列通用和专门的条件,来正式的定义一个过程的结束点。出口准则的目的可以防止将没有完成的任务错误地看成任务已经完成。测试中使用的出口准则可以来报告和计划什么时候可以停止测试
  • confirmation testing(确认测试):重新执行上次失败的测试用例,以验证纠错的正确性
  • regression testing(回归测试):测试先前测试过并修改过的程序,确保更改没有跟给软件其他未改变的部分带来新的缺陷(defect)。软件修改后或者使用环境变更后要执行回归测试
  • test strategy(测试策略):一个高级文档,该文档定义了需要对程序(一个或多个项目)执行的测试级别和需要进行的测试
  • test level(测试层级):共同进行组织和管理的一组测试活动。可以分为底层测试嗯哼高层测试
  • test specificatiion technique(测试规格技术):一种结构化的方法,用于测试依据(例如,需求、功能或技术规格)中得到测试用例。可以分为白盒测试和黑盒测试技术
  • Low-level test(底层测试):底层测试包括分别或组合地测试系统的个别组件。通常由开发人员执行。分为单元测试和集成测试,主要使用白盒测试技术
  • High-level test(高层测试):高层测试指测试完整的产品。分为系统测试和验收测试,主要使用黑盒测试技术
  • Unit test(单元测试):单元测试是有开发人员在实验室环境中执行的测试,应当验证代码是否满足设计规格中的需求
  • Integration test(集成测试):集成测试是由开发人员在实验室环境中执行的测试,应当论证代码的逻辑组合是否满足设计规格中的要求
  • System test(系统测试):系统测试是由开发人员或独立测试团队在(完全可控的)实验室环境中执行的测试,应当论证所开发的系统或子系统是否满足功能或质量规格中的需求
  • Acceptance test(验收测试):验收测试是由用户和系统管理员哎最大可能模拟实际运行环境的环境中执行的测试,应当论证所开发的系统是否满足功能和质量需求

测试技术

测试用例:可以独立进行测试执行的最小单元,包括必不可少的几个要素:

  • 测试用例设计的目的
  • 测试操作步骤及其每个步骤所需要的输入数据
  • 需要从被测系统收集的输出数据
  • 测试要通过的标准

Junit 4测试框架

  • junit.framework.Test:测试接口
  • junit.framework.TestCase:测试用例类,根据情况编写若干个public void testXxx()方法,在方法中通过assertYyy()定制若干个测试规则
  • junit.framework.TestSuite:测试套件类,它可以将多个测试用例类捆绑在一起运行,也可以捆绑另一个测试套件

测试固件:

  • 一个测试用例可以包含若干个testXxx()方法,测试用例测试一个或多个类API接口的正确性
  • 在调用类API时,需要事先创建这个类的对象及一些关联的对象,这组对象就称为测试固件(Fixture),相当于测试用例的“工作对象”

测试集TestSuite创建方式有两种:

写函数语句:

1
2
3
4
5
6
7
8
public class CalculatorTestSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new JUnit4TestAdapter(CalculatorTest.class));
suite.addTest(new JUnit4TestAdapter(CalculatorTest2.class));
return suite;
}
}

注解方式:

1
2
3
4
5
6
7
8
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorTest.class, CalculatorTest2.class, CalculatorTestSuite.class})
public class CalculatorTestSuite2 {

}

Junit 4.x的测试过程:

  • @Before注解:用于测试方法执行之前构建需要执行的环境,可以有多个@Before方法,Junit 4.0前的版本必须通过自定义方法为setUp方法告知框架该方法是初始化代码
  • @After注解:在测试方法执行完成后进行清除,Junit 4.0前的版本必须通过自定义方法为tearDown方法告知框架该方法是清理代码
  • @Test:测试方法

声明:本站所有文章均为原创或翻译,遵循署名 - 非商业性使用 - 禁止演绎 4.0 国际许可协议,如需转载请确保您对该协议有足够了解,并附上作者名 (Tsukasa) 及原文地址