JavaSE Day01
计算机中的存储
计算机的最小存储单位是:字节(byte)而1byte=8bit(比特),存储单位的换算有:
- byte(字节) 1byte = 8bit
- B 1B = 1024byte
- KB 1KB = 1024B
- MB 1MB = 1024KB
- GB 1GB = 1024 MB
- TB 1TB = 1024 GB
进制关系
进制 | 基数范围 | 进制关系 |
---|---|---|
二进制 | 0~1 | 逢二进一 |
八进制 | 0~7 | 逢八进一 |
十进制 | 0~9 | 逢十进一 |
十六进制 | 0~9 A~F | 逢G进一 |
1、十进制转二进制
方法为:十进制数除2取余法,即十进制数除2,余数为权位上的数,得到 的商值继续除,直到商为0为止。
112 ==> 0111 0000 (2)
56 0
28 0
14 0
7 0
3 1
1 1
0 1
2、二进制转十进制
方法为:把二进制数按权展开、相加即得十进制数。
3、二进制与八进制之间的转换
1.八进制转二进制
方法为:八进制数通过除2取余法,得到二进制数,对每个八进制为3个二进制,不足时在最左边补零。
2.二进制转八进制
方法为:3位二进制数按权展开相加得到1位八进制数。(注意事项,3位二进制转成八进制是从右到左开始转换,不足时补0)。
4、二进制与十六进制之间的转换
1.十六进制转二进制
方法为:十六进制数通过除2取余法,得到二进制数,对每个十六进制为4个二进制,不足时在最左边补零。
2.二进制转十六进制
方法为:与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意事项,4位二进制转成十六进制是从右到左开始转换,不足时补0)。
原码 反码 补码
正整数:
正整数的原码、反码、和补码一致,均是其二进制展开形式。
负整数【带有符号位,即最高位为符号位!】:
负整数的原码是其正整数的二进制展开形式,最高位是符号位。(符号位,负为1,正为0)。
反码是原码按位取反,符号位不变。
补码是原码按位取反,末尾加1。
原码:
123 ==> 0111 1011
-123 ==> 1111 1011
反码:123的原码、反码、补码一致
-123:
1000 0100
补码:
-123:
1000 0101
数据类型
八大基本数据类型
类型 | 占用空间大小 | 数据范围 |
---|---|---|
byte | 1字节(8bit) | -128 - 127 |
short | 2字节 (16bit) | -32768 - 32767 |
int | 4字节(32bit) | -2^31 - 2^31-1 |
long | 8字节 (64bit) | -2^63 - 2^63-1 |
float | 4字节(32bit) | -2^128 ~ +2^128(-3.40E+38 ~ +3.40E+38)~ |
double | 8字节(64bit) | -2^1024 ~ +2^1024(-1.79E+308 ~ +1.79E+308) |
boolean | 视情况而定 | true / false |
变量名/标识符
标识符:程序员自己对代码中的一些内容起的名字、变量名、方法名、类名……
规范:
①Java中标识符只能使用英文字母(A-Z)(a-z)(0-9)以及下划线“_”,其他任何字符均不建议使用。(为了方便其他人,以及提高代码可读性)。
②必须以英文字母开头。
③标识符必须严格区分大小写。
④标识符无长度限制,但是会根据特定情况来约束标识符长度。
⑤标识符要符合一定的命名规范。驼峰命名法:
小驼峰(首字母小写):适用于方法名,变量名等等。
大驼峰(首字母大写):一般适用于接口名和类名。
⑥而常量名则需要全部大写,若为词组命名,则需要以下划线分隔开。
例如:MAX_VALUE。
运算符
运算符优先级
优先级 | 描述 | 运算符 |
---|---|---|
1 | 括号 | ()、[] |
2 | 正负号 | +、- |
3 | 自增自减,非 | ++、–、! |
4 | 乘除,取余 | *、/、% |
5 | 加减 | +、- |
6 | 移位运算 | <<、>>、>>> |
7 | 大小关系 | >、>=、<、<= |
8 | 相等关系 | ==、!= |
9 | 按位与 | & |
10 | 按位异或 | ^ |
11 | 按位或 | I |
12 | 逻辑与 | && |
13 | 逻辑或 | II |
14 | 条件运算 | ?: |
15 | 赋值运算 | =、+=、-=、*=、/=、%= |
16 | 位赋值运算 | &=、I=、<<=、>>=、>>>= |
%(取余)
这个符号在Java中是取余运算
int num = 10 % 20;
//此处是取余操作,因为10整除20不够 因此余数为10
//取余操作 只存在于整数操作,不存在于小数操作
运算 | 商 | 余数 |
---|---|---|
5÷2 | 2 | 1 |
5÷10 | 0 | 5 |
5÷1 | 5 | 0 |
/(除法操作)
int num = 10 / 20;
//此处是除法操作,除法操作不会得出小数位,小数位只会直接舍弃,留下整数位。
//若想得出小数可以用 double num = 10D/20; 等等诸多方法(此处不一一列举)
对于带符号右移,若为负数,则在存储时首位表示符号位,其值为1,表示该值是负数的移位,在移位过程中,高位补1,若符号位是0,表示是正数,在移位过程中高位补零,两者的前提是符号位保持不变。
对于负数的右移:因为负数在内存中是以补码形式存在的,所有首先根据负数的原码求出负数的补码(符号位不变,其余位按照原码取反加1),然后保证符号位不变,其余位向右移动到X位,在移动的过程中,高位补1.等移位完成以后,然后保持符号位不变,其余按位取反加1,得到移位后所对应数的原码。即为所求。
>>(右移运算)
1 >> 4 = 0
原码:0000 0000 0000 0000 0000 0000 0000 0001 -> 0000 0000 0000 0000 0000 0000 0000 0000
-1 >> 4 = -1
原码:1000 0000 0000 0000 0000 0000 0000 0001 [按位取反]=> 1111 1111 1111 1111 1111 1111 1111 1110 末尾+1 => ↓
补码:1111 1111 1111 1111 1111 1111 1111 1111 -> 1111 1111 1111 1111 1111 1111 1111 1111
补码形式的移位完成后,结果不是移位后的结果,要根据补码写出原码才是我们所求的结果。其方法如下:
保持符号位不变,其余按位取反加1 =>
1000 0000 0000 0000 0000 0000 0000 00001 => -1
>>>(无符号右移运算)
无符号右移其实相对于有符号右移的区别在于移位的时候,有符号右移的时候如果是符号位为1,则右移高位+1,而如果符号位为0,则右移高位+0
1 >>> 4 = 0
0000 0000 0000 0000 0000 0000 0000 0001 -> 0000 0000 0000 0000 0000 0000 0000 0000
-1 >>> 4 = 268435455
原码:1000 0000 0000 0000 0000 0000 0000 0001 [按位取反]=> 1111 1111 1111 1111 1111 1111 1111 1110 末尾+1 => ↓
补码:1111 1111 1111 1111 1111 1111 1111 1111 -> 0000 1111 1111 1111 1111 1111 1111 1111 => 268435455
<<(左移运算)
1 << 4 = 16
原码:0000 0000 0000 0000 0000 0000 0000 0001 => 0000 0000 0000 0000 0000 0000 0001 0000 => 16
-1 << 4 = -16
原码:1000 0000 0000 0000 0000 0000 0000 0001 [按位取反]=> 1111 1111 1111 1111 1111 1111 1111 1110 末尾+1 => ↓
补码:1111 1111 1111 1111 1111 1111 1111 1111 -> 1111 1111 1111 1111 1111 1111 1111 0000
补码形式的移位完成后,结果不是移位后的结果,要根据补码写出原码才是我们所求的结果。其方法如下:
保持符号位不变,其余按位取反加1 => 1000 0000 0000 0000 0000 0000 0001 0000 => -16
&(与运算)
1 & 0 = 0
0 & 0 = 0
1 & 1 = 1
|(或运算)
1 | 0 = 1
0 | 0 = 0
1 | 1 = 1
^(异或运算)
1 ^ 0 = 1
0 ^ 0 = 0
1 ^ 1 = 0
++ i 与 i ++的区别
【重点】自增自减运算符【有且只能操作变量】,不可以操作常量
++ i 先打印后运算
int i=1;
如:System.out.printn(++i) 结果是 1
i ++ 先运算后打印
如:System.out.printn(i++) 结果是 2
【难点】前后关系
自增自减运算符在
变量之前:首先执行自增自减操作,再来完成当前行代码的运行
变量之后:首先执行当前行代码,再来执行自增自减操作
【建议】
- 尽量使用 += 1 或者 -= 1替换自增自减运算符。阅读性更好,并且在Swift语言中已经取消自增自减运算符,使用 += 1 和 -= 1代替,为了避免没有必要的歧义性
- 如果非要使用自增自减运算符,推荐自增自减运算符,单独成行。
int num = 10;
++num; or num++; 没有任何的歧义性
逻辑运算
与
&&
【重点】同真为真,有假【即】假
或
||
【重点】有真【即】真,同假为假
非 取反
!
【面试考点】
题一、
int i =5;
int num = i++ * ++i;
System.out.println(i);
System.out.println(num);
//此时i=7
//num = 35
//原因:因为i++自增运算在后,是先执行代码,
//后进行自增操作,因此i++ 这块执行完时i=5,
//然后执行自增操作此时i=6,因为是乘法运算,
//而且后面++i还需要执行一波运算才可进行乘法操作。
//因此++i 此时i为6 执行完++i操作后 i = 7;5*7=35.
题二、
int i = 5;
++(i++);
//此处会导致报错,因为i++处于括号之内,此时这个括号算是一个整体,
//按执行先后顺序的话,在执行完(i++)这个整体后会导致其成为一个常量。
//而因为自增自减运算符无法操作常量,因此此处会报错。
题三、(逻辑运算)
int num = 5;
boolean ret = false;
ret = num > 10 && ++num >1
//此时的ret为 false ,因为num > 10 为false,
//因为是与运算,当出现一个条件是false,
//从出现条件结果为false之后的所有条件均无效(与运算的短路操作),
//即停止执行,后续的条件将不会再做判断,此举是为了节约计算机的性能问题。
题四、(逻辑运算)
int num = 10;
boolean ret = false;
ret = num > 5 && num++ > 1
//此时的ret为 true,因为num > 5为true,
//因为是与运算,当出现一个条件是true,
//从出现条件结果为true之后的所有条件均无效(或运算的短路操作),
//即停止执行,后续的条件将不会再做判断,此举是为了节约计算机的性能问题。
``
题五、(闰年问题)
/*
闰年问题:
1. 能被4整除,但是不能被100整除
2. 能被400整除
*/
int year = 2000;
year % 4 == 0 && year % 100 !=0 || year % 400 ==0
题六、(逻辑运算括号优先级)
int num = 6;
boolean ret = num >3 && (num-- <10 || num++ > 8 );
ret = ?;
num = ?
/*
首先执行 num > 3
num ==>6
6>3成立,然后执行(num-- <10 || num++ >8)
num-- <10 --在后,首先取值num使用
num ==> 6 6<10成立 执行--
num ==>5
逻辑或短路原则 num++ > 10 不再执行
即 ret = true;
num = 5;
*/
//在逻辑运算里 括号当一个整体不具备优先级
//在普通加减乘除运算里,就有优先级
不积硅步,无以至千里;不积小流,无以成江海。虽说有一般般的底子,但是重新来过的时候,还是要重复基本功的。代码每天三遍不可少!!!