以下内容为博主阅读对应书籍或资料(分栏名告知)总结的笔记,由部分书内原句、部分佐证、部分博主自身理解组成,有出错处万望告知,不胜感谢。
本类文章主为巩固博主自身学习,顺带与同行互通有无,若有侵权望告知!
1.软件开发过程
开发软件产品是一个工程过程,无论软件产品大小,都具有同样的生命周期:
需求规范、分析、设计、实现、测试、部署和维护,而在软件开发生命周期的任何阶段都有可能回到之前的阶段改正错误,或者处理其他可能影响软件预期功能的问题。
- 需求规范
需求规范是一个规范化的过程,旨在理解软件要处理的问题,以及将软件系统的功能详细记录到文档中。
我们首先得了解我们需要做出什么样的效果和功能,以及是针对处理什么问题而研发的软件产品,这样才能明确之后的开发如何进行 - 分析
系统分析旨在分析数据流,并且确定系统的输入和输出。
我们需要明确软件产品会接收到什么样的数据和需要返回什么样的数据,即确定我们是要完成什么功能 - 设计
系统设是设计一个从输入获得输出的过程。
在知道了会接收到什么样的数据和需要返回的数据后,则需要来根据需求进行设计,从而知道从什么地方着手开发 - 实现
实现是将系统设计翻译成程序。
确定的需求,设计了流程,接下来就是将它们转换为程序代码来完成这些功能需求(而这个过程中就至少需要使用一门编程语言来进行完成) - 测试
测试确保代码符合需求规范,并且排除错误。
通常这个工作会由一个没有参与产品设计和实现的独立软件工程团队来完成,这也是为了防止发生一些惯性思维上的错误 - 部署
部署使得软件可以被使用。
根据软件产品类型的不同,它可能需要被安装到每个用户的机器上,也可能会被安装在一个 Internet 可访问的服务器上 - 维护
维护是对软件产品进行更新和改进。
在软件产品正式投入使用后也不是就万事大吉了,还需要进行后期的维护工作,以保证软件产品能够高效安全地运行下去
软件开发过程其实就是一个 确定需求、根据需求进行设计、讲需求实现、投入使用 的过程
2.标识符
- 标识符是由字母、数字、下划线(_)和美元符号($)构成的字符序列
- 且不能以数字开头
- 不能使用 保留字 作为标识符
- 不能为各类型数据的默认值,如 true 、 false 、 null
- 长度任意
一般来说标识符长度建议简短,以减少后续使用时(开发者)的输入量 ----->(调用便捷)
但当代码量、标识符量数量过多时更建议用较为完整的命名方式,以增加可读性
- 声明变量前加关键字 “final” 即声明常量(因为这之后值不可更改)
也由于不可更改,所以要求在声明的同时 必须赋值 - 可并列声明同类型变量:int i , j , k;
即声明了三个 int 类型的变量 i , j , k
等价于
int i;
int j;
int k;
3.赋值
赋值语法:
数据类型 数据名(即标识符,也常称变量名) = 数据值
如:int num = 5;
即创建一个 int 类型数据 num ,num 的值为 5
“ = ” 在赋值语句中作为赋值表达式,将右边的值赋给左边
在实际开发中有时在赋值时不是一个单单的数据,而是一个 带有操作符的赋值表达式
- 赋值时可使用并列赋值方式,如(此处i、j、k视为已声明):i = j = k = 1;
等价于
k = 1;
j = k;
i = j;
4.数值数据类型和操作(符)
- 针对整型和浮点型有六种数值类型(byte、short、int、long 、float、double)
- 有 +(加)、-(减)、*(乘)、/(除)、%(取余)等几种操作符
(这几种操作符应该都算熟悉,至少在应试教育阶段就用的不少,编程方面区别并不算大,不做赘述)
需要注意:在进行除法运算时,若除数与被除数都为整型,则求出的值也会是整型
如:5/2 在我们正常运算时结果应为2.5,在Java编程中由于都为整型数据,因此运行结果为 2(相当于向下取整)
若想获取正确结果只需将其一转换为double类型即可(在后面加“.0”)
5.控制台读取输入
创建一个可以记录控制台输入的数据的对象,便于程序获取数据:
Scanner sc = new Scanner(System.in);
要获取一个整型数据:
int num1 = sc.nextInt();
获取浮点型数据则是:
double num2 = sc.nextDouble();
其他类型的数据获取方法也是相类似的
需要注意的是用户输入的数据类型需要与程序想要的 数据类型相同,
否则将出现数据 值异常 甚至导致 程序异常终止
(值异常:如用户输入的是double类型的3.5,若用 nextInt() 获取获取的值则会是 3)
6.幂运算和科学计数法
使用Java API自带的Math类中的pow方法进行幂运算,该方法支持传入参数为整型、浮点型(包括负数):
如:
System.out,println(Math.pow(2 , 3)); // displays 8.0
System.out,println(Math.pow(4 , 0.5)); // displays 2.0
System.out,println(Math.pow(2.5 , 2)); // displays 6.25
System.out,println(Math.pow(2.5 , -2)); // displays 0.16
7.数字值常见简单操作
- 字面值
即在程序中直接出现的常量值(通常用来计算或赋值):
int numberOfYears = 34;
double weight = 0.305;
// 此处出现的 34 和 0.305 都是数值型字面值
在使用字面值时,可通过在数字前加一些前缀表示不同进制的数(默认为十进制):
0b / 0B (零B):二进制
0 (零):八进制
0x / 0X (零X):十六进制
System.out.println(0B1111); // displays 15
System.out.println(07777); // displays 4095
System.out.println(0XFFFF); // displays 65535
在使用字面值时,可通过在数字后加后缀表示不同数据类型的数(整型默认为 int ,浮点型默认为 double):
f / F : float 型
l / L : long 型(一般不考虑使用 byte 和 short 数据类型,因为相对来说限定值偏小,易造成数值溢出错误)
- 表达式求值以及操作符优先级
在Java中的表达式求值和数学表达式求值是一样的。
比如将以下数学表达式翻译为Java表达式:
// Java表达式
(3 + 4 * x) / 5 - 10 * (y - 5) * (a + b + c) / x + 9 * (4 / x + (9 + x) / y)
而在Java的表达式运算中,有以下优先级规则(与数学表达式优先级规则几乎完全一致):
先计算 乘除 和 求余,再计算加减,同等优先级从左到右依次计算
跟数学表达式相同,括号 中的内容优先计算
- 增强赋值操作符(在此罗列,用以参考):
- += : 示例:i += 8 等价于:i = i + 8;
- -= : 示例:i -= 8 等价于:i = i - 8;
- *= : 示例:i *= 8 等价于:i = i * 8;
- /= : 示例:i /= 8 等价于:i = i / 8;
- %= : 示例:i %= 8 等价于:i = i % 8;
在增强赋值操作符中没有空格!!!
- 自增、自减操作符
自增操作符(++)对变量值进行+1操作,自减操作符(- -)对变量值进行-1操作
而自增自减操作符有 前置 和 后置 区别:
int i = 5;
System.out.println(i++); // displays 5 即使用的是改变前的值,使用后 i 值才改变
// 此时 i = 6
System.out.println(i--); // displays 6 即使用的是改变前的值,使用后 i 值才改变
// 此时 i = 5
System.out.println(++i); // displays 6 即使用的是改变后的值
// 此时 i = 6
System.out.println(--i); // displays 5 即使用的是改变后的值
// 此时 i = 5
很明显,前置自增、自减操作符先改变值再使用变量,后置自增、自减操作符先使用变量再改变值
- 数值类型转换(自动升型)
不同数据类型操作数也可以进行二元运算,但结果数值会赋给支持更大数值范围类型的变量,比如:
3 * 4.5 ,在Java运算时会将整型转换为浮点型,即:3.0 * 4.5
程序如此做的好处在于:不会因为不同数据类型的计算导致数据精度降低,简单理解即是不会将小数舍为整数,从而导致误差
- 数值类型转换(显式(强制)转换)
扩展类型(升型)和缩小类型(降型)统称数据类型转换:
扩展类型:将范围较小的类型转换为范围较大的类型
缩小类型:将范围较大的类型转换为范围较小的类型
在Java运算中程序会自动识别进行运算操作的数据类型,并自动升型
而有时我们并不需要精确的数据或者根据需求而想要使用范围较小的数据类型时则需要进行显式转换:
比如我们有一个浮点型数据,而需求仅需要一个整型数据:
System.out.println((int) 1.7); // displays 1
而显式转换方式会被优先执行,比如:
System.out.println((double) 1 / 2); // displays 0.5
// 因为转换会被优先执行,所以此运算视为:1.0 / 2 = 0.5 而不是 1 / 2 求值后再转换为 double 类型数据
而有一点需要注意:增强赋值表达式相当于自带显式转换方式:
int sum = 0; sum += 4.5; // 此处等价于:sum = (int) (sum + 4.5) 即先进行运算,再进行转换 // 即变量的数据类型在进行增强赋值表达式后仍为原本的数据类型
8.数字操作常见错误和陷阱
- 未声明、未初始化的变量和未使用的变量
变量必须在使用之前声明为一个类型并且赋值
有时变量在声明时处于程序员的某些考虑而只声明了类型却未确定值(初始值),而此种编程习惯时常也可能造成使用该变量时还仍未赋值的情况,这就将造成程序异常
而此错误类型由于编译工具的智能性在实际开发中也并不多见
但这种编程习惯终归会给程序的安全运行带来隐患,最佳的处理方式还是在定义变量时就进行赋值
- 整数溢出
即整数类型变量值超过类型本身限定的大小,以下是各类整数数据类型的限定大小:
- 舍入错误
指计算得到的数字的近似值和确切的数学值之间的差异,如:
保留三位小数时 1/3 近似等于 0.333,而当保留七位小数时则为 0.3333333;.
由于浮点型数据进行的计算取值都是近似值,而这些数没有以准确的精度来存储,因此会出现这样的误差:
System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);
//显示的值为0.5000000000000001而不是0.5
System.out.println(1.0 - 0.9);
//显示的值为0.29999999999999998而不是0.1
这是由于变量值保存的位数是有限的,而值的误差就与此有关
- 非预期的整数除法
Java语言中,使用除法操作符 “/” 时:
两个整数相除时,得到的值即便在数学运算中是小数,而在编程运算结果中却必然是整数,这就要求程序员在进行编程时需要根据所需结果改人为改变其中至少一个值(有浮点型数据参与的除法运算结果会自动转换为浮点型)
如:
int number1 = 1;
int number2 = 2;
double average = (number1 + number2) / 2;
System.out.println(average);// 1.0
虽然 average 被声明为 double类型数据,但却并不会影响运算结果
实际上这样做的效果类似于将运算结果 int 类型数据 1 转换为 double 类型的 1.0,不影响值
int number1 = 1;
int number2 = 2;
double average = (number1 + number2) / 2.0;
System.out.println(average);// 1.5
- 冗余的输入对象
初学者在使用 Scanner 对象获取控制台键盘录入的值时,经常会编写多个该类型对象:
如:
Scanner input1 = new Scanner(System.in);
System.out.print("Enter an integer: ");
int v1 = input1.nextInt();
Scanner input2 = new Scanner(System.in);
System.out.print("Enter an integer: ");
double v2 = input2.nextInt();
这样创建一个新的 Scanner 对象毫无必要,还可能导致一些不易发现的错误,这样修改就不用担心这个问题:
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int v1 = input.nextInt();
System.out.print("Enter an integer: ");
double v2 = input.nextInt();