周五班会课请了学长来交流经验。他说从三月一日开始就会有很多大公司的内推,是在大公司里的学长学姐发的。会帮你跳过筛选简历或者笔试阶段,可能直接面试。之后学长还建议暑假去找公司实习。在得知还有一年甚至可能五个月后就要实习时,有点慌了。加上最近在《构建之法》上看到关于某大师的观点:skilled的反面(解决问题。详细点就是低级问题比如语法等都要去百度)是什么时。发现自己不管是Java还是C++都不算是skilled,依然可能因为低级问题而去百度,而不是信手拈来。感觉之前与学院的大部分人比,实在太傻了,见不到外面广阔的世界,有点将要死于安乐的感觉。而且数据结构、算法等基础课程也没有太深入学习。但是庆幸还有时间补回来。
要做到skilled,就要不断练习。
现在重新看《Java Core》,看完后看《Thinking in Java》。
下面是《Java Core 10th V1》第三章的笔记,发现还是有不少小细节以前不知道的。
表示二进制:前面加0b 如0b1000表示8。
Java SE7后可以用_隔开。如0b100_0000表示64;1_000_000表示一百万。
C++的基本数据类型的字节长度可能不一,这样固然根据不同平台优化会更高效,但不利用跨平台。如32位处理器中,int可能是4字节的,直接移植到可能是2字节的16位处理器中会出现溢出问题。的确,现在很多嵌入式设备不需要太强的CPU,要做到CPU统一不现实,也不划算。
四字节的int范围大概是-20亿到+20亿。
float可精确6到7位小数,double是15位。
浮点数不加后缀f默认为double类型。
0.125 可以表示为 0x1.0p-3。
这里用p而不是e,p的底数是2,e的底数是10。
NaN:not a number
有三种特别的浮点数值来表明益处或者错误:正无穷、负无穷、NaN
if (x == Double.NaN) // is never true
if (Double.isNaN(x)) // check whether x is "not a number"
System.out.println(2.0 - 1.1) prints 0.8999999999999999
浮点数是不精确的。想要精确可以用BigDecimal类或者自己定义(如精确到只需要到小数点后两位的,可以先乘一百来计算)
比如这样子
public class TestFloat{
public static void main(String[] args){
try{
float temp = Float.parseFloat(args[0]);
float temp1 = Float.parseFloat(args[1]);
System.out.println(((int)(temp*100)-(int)(temp1*100))/100.0);
}catch(NumberFormatException e){
System.out.println("请输入两个数字,以空格隔开,程序会计算其差,精确度为两位小数");//这里写中文会输出乱码(源代码UTF-8,CMD是GBK),而把CMD编码格式改为UTF-8后就出现无法编译
}
}
}
Unicode escape sequences are processed before the code is parsed.
For example, “\u0022+\u0022” yielding “”+”“, or an empty string. Tips: \u0022 是 ”
就是转义字符先于编译转义
Our strong recommendation is not to use the char type in your programs unless you are actually manipulating UTF-16 code units. You are almost always better off treating strings.
不建议用char,除非用UTF-16
Note that the terms “letter” and “digit” are much broader in Java than in most languages. A letter is defined as ‘A’–’Z’, ‘a’–’z’, ‘_’, ‘$’, or any Unicode character that denotes a letter in a language. For example, German users can use umlauts such as ‘ä’ in variable names; Greek speakers could use a π. Similarly,digits are ‘0’–’9’ and any Unicode characters that denote a digit in a language.
Symbols like ‘+’ or ‘©’ cannot be used inside variable names, nor can spaces. All characters in the name of a variable are significant and case is also significant. The length of a variable name is essentially unlimited.
letter意义广泛,包括其中语言中的letter也算,文中举了德文的例子。digit亦然。
Even though $ is a valid Java letter, you should not use it in your own code.
It is intended for names that are generated by the Java compiler and other tools.
不应该用$,因为这是Java编译器和其他工具用的。
You can declare multiple variables on a single line:
int i, j; // both are integers
However, we don’t recommend this style. If you declare each variable separately, your programs are easier to read.
为了易读性,不建议一行声明多个变量。
you can never use the value of an uninitialized variable.
For example, the Java compiler flags the following sequence of statements as an error:
int vacationDays;
System.out.println(vacationDays); // ERROR--variable not initialized
In Java, it is considered good style to declare variables as closely as possible to the point where they are first used.
不能使用未初始化的变量。在Java中,哪里用到这个变量,就近声明,是一种挺好的风格。
In Java, you use the keyword final to denote a constant. The keyword final indicates that you can assign to the variable once, and then its value is set once and for all. It is customary to name constants in all uppercase.
常量只赋值一次,命名全大写。
These are usually called class constants. Set up aclass constant with the keywords static final. 静态常量
关于static,如要数下有多少个实例,可以:
在类中:
private static int number=0;
在构造方法中:
number++;
关于关键字strictfp:
public static strictfp void main(String[] args)
Then all instructions inside the main method will use strict floating-point computations. If you tag a class as strictfp,then all of its methods must use strict floating-point computations. 因为有的Intel处理器会优化计算结果,比如把中间值放到80位的寄存器,这样固然更精确,但不符合Java在不同平台统一的特性。(这样同样的运算,不同CPU会得到不同结果)Java曾经想过强制统一,但遭到某些社区的讨厌。然后现在若加上关键字 strictfp ,则会强制统一。
但是,默认模式下 intermediate results are allowed to use an extended exponent,
but not an extended mantissa.只拓展了指数而没有拓展位数
Therefore, the only difference between the default and strict modes is that strict computations may overflow when default computations don’t. 所以最终区别只是是否溢出而已。
分别是指数、2为底数求对数、10为底数求对数、常量π、常量e
Math.exp
Math.log
Math.log10
Math.PI
Math.E
Math为了追求更高性能,根据处理器进行了优化,如想在不同平台获得统一结果,用 StrictMath
类型转换中,虚线会损失精度。
int temp = 123456789;
System.out.println(temp);
System.out.println((float)temp);//prints 1.23456792E8
不同类型之间进行运算,比如一个int加上一个float,两个都会转为float。优先级为:double>float>long>int
Conversions in which loss of information is possible are done by means of casts. 转的时候要小心越界溢出
例子:
double x = 9.997;
int nx = (int) x;//9
If you want to round a floating-point number to the nearest integer (which in most
cases is a more useful operation), use the Math.round method
double x = 9.997;
int nx = (int) Math.round(x);//10 要用强制转型是因为round返回的是long类型猜测以上的实现是加0.5然后再强制转为long
x += 3.5;//x=(int)(x+3.5)
n++--++;//就不要这么写了 容易乱
& | ^ ~ 分别是与、或、异或、非
System.out.println(0b1000 & 0b10111);//0
System.out.println(0b1001 | 0b0111);//15
System.out.println(0b1001 ^ 0b0111);//14
System.out.println(~0b1000);//-9
System.out.println(1 << 3);//8
System.out.println(1 << 8);//258
System.out.println(1 << 32);//1
System.out.println(15 >> 1);//7
System.out.println((byte) (-128) >> 1);//-64
System.out.println((byte) (-128) >>> 1);//2147483584 无符号位右移,高位补零 这里应该还是int,所以才这么大
System.out.println((byte) (0b10000000));//-128 右移,高位补符号位
a += b +=c;//a+= (b += c)
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };
Now you can declare variables of this type:
Size s = Size.MEDIUM;
A variable of type Size can hold only one of the values listed in the type declaration,
or the special value null that indicates that the variable is not set to any value at all.
String greeting = "Hello";
String s = greeting.substring(0, 3);
creates a string consisting of the characters “Hel”.
The second parameter of substring is the first position that you do not want to copy.
If you need to put multiple strings together, separated by a delimiter, use the
static join method:
String all = String.join(" / ", "S", "M", "L", "XL");
// all is the string "S / M / L / XL"
The String class gives no methods that let you change a character in an existing
string.
greeting = greeting.substring(0, 3) + "p!";//change hello to be help!
Immutable(不变的) strings have one great advantage: The compiler can arrange that strings are shared.
Overall, the designers of Java decided that the efficiency of sharing outweighs the inefficiency of string editing by extracting(提取) substrings and concatenating.
比较字符串:
s.equals(t);
"Hello".equalsIgnoreCase("hello");//忽略大小写
不要用==
String greeting = "Hello"; //initialize greeting to a string
if (greeting == "Hello") . . .
// probably true 可能作用域相同
if (greeting.substring(0, 3) == "Hel") . . .
// probably false 可能作用域不同
The language designerscould have redefined == for strings, just as they made a special arrangement for +.(为什么设定了强大的+号后,就不能重定义==呢?)