[TOC]
MySql password: dg0zt7vh3,&N
切换字符集:chcp 65001(UTF-8)、chcp 936(GBK)
输入:
d:
网关地址就是路由器的IP地址,静态IP需要设置默认网关、DNS、子网掩码等等,动态IP只需要路由器DHCP自动分配IP地址
~ 把补码中的 0 和 1 全部取反(0 变为 1,1 变为 0),取反时每一位都参与运算,包括符号位
~9
和 ~-9
~9 的计算步骤:
原码:0 1001
补码:0 1001
按位取反:1 0110
原码:1 1010
= -10
~-9 的计算步骤:
原码:1 1001
补码:1 0111
按位取反:0 1000
原码:0 1000
= 8
右移时需要在左侧用符号位(正数为 0,负数为 1)补齐
解释:-5 >> 2 == -2
-5
原码 1000 …… 0101
反码 1111 …… 1010 负数的反码是保留符号位不变原码取反
补码 1111 …… 1011 补码是反码加1
>>2 (负数右移高位补1)
补码 1111 …… 1110
反码 1111 …… 1101 补码转反码减1
原码 1000 … 0010 负数反码转原码保留符号位不变取反
= -2
解释:
5 >> 2 == 1
+5
原码 0000 …… 0101
补码 0000 …… 0101
>>2(正数右移高位补0)
补码 0000 …… 0001
原码 0000 …… 0001
= 1
左移时在后面补 0。值得注意的是,对于 int 型来说左移 32 位等于原来的数,移位的位数 >= 32 时会先取余再进行移位,比如左移 34 位等于左移 2(34 % 32)位。
相对于右移,左移还需要考虑溢出的问题。
a ^ a = 0
a ^ 0 = a
a ^ b = b ^ a
a ^ (b ^ c) = (a ^ b) ^ c
由异或的归零率和结合律可以推出异或的另一条性质:
自反: a ^ b ^ b = a ^ 0 = a
利用a ^ b == 0
可以快速判断 a 和 b 是否相等
交换两个变量的值
a = a ^ b;
b = a ^ b; //a ^ b ^ b = a ^ 0 = a
a = a ^ b; //a ^ b ^ a = b ^ a ^ a = b
比如,从 {1, 2, 3, 4, 5, 3, 2, 4, 5}
中找出单个的数字: 1
首先,我们来看一个简单的例子。因为异或满足交换律、结合律和归零率,所以假设有数组:A B C B C D A 使用异或:
A ^ B ^ C ^ B ^ C ^ D ^ A
= A ^ A ^ B ^ B ^ C ^ C ^ D
= 0 ^ 0 ^ 0 ^ D
= 0 ^ D
= D
这样我们就找出了只出现一次的元素:D
代码
//空间复杂度为O(1),时间复杂度为O(n)
int singlenumber(int *array*[], int *length*){
if(length <= 0)
return -1;
if(length == 1)
return array[1];
int result = 0; // a ^ 0 = a
for(int index = 0; index < length; index++){
result = result ^ array[index];
}
findonebit(int num)
return result;
}
a % b
的步骤:1.求整数商:c = a / b
2.计算模或者余数:r = a - c * b
如果 a, b 都为正数,则取模与取余得到的商相同
对于被除数为负数的取模运算结果取决于具体的编程语言,一般分为两种类型:
1.floor除法
,就是商采用floor法
取整,因而也叫趋负无穷截尾。目前采用这种方式的编程语言有python
等。
例如:-7 % 3
中,商向下取整得 -3,所以模就为 2.
2.truncate 除法
,就是商尽可能的靠近 0,因此又称截断取整。目前采用这种的方式的编程语言有C
、java
还有js
等。例如-7 % 3
,靠 0 取整得 -2,所以模就为 -1.
巧记:
floor法
的话,模的符号和除数相同;而truncate法
的话,模的符号和被除数相同。
构造方法的继承
super
和this
关键字
动态绑定和静态绑定
动态绑定:根据具体对象的类型进行绑定,发生在运行阶段,绑定的是对象信息
静态绑定:编译过程中就已经知道这个方法到底是哪个类中的方法。发生在编译阶段,绑定的是类信息,即为定义的类的类型
java
当中的方法,只有final
,static
,private
,重载方法(overloaded methods)
和构造方法
是静态绑定。所有的变量
都是静态绑定。
特别说明的一点是,private
声明的方法和成员变量不能被子类继承,所有的private
方法都被隐式的指定为final
的,所以是静态绑定的。(由此我们也可以知道:将方法声明为final
类型的一是为了防止方法被覆盖,二是为了有效的关闭java
中的动态绑定)
多态分为编译时多态
和运行时多态
实现多态的三个条件: 1.继承 2.重写 3.父类引用指向子类对象
new
来实例化抽象类;new
来实例,只能用来被子类调用;implements
来实现接口中的规范;public
;public static final
类型的static
修饰的方法),而抽象类是可以有静态代码块和静态方法getClass()、hashCode()、equals()、clone()、toString()
==
和 equals
方法的异同
相同点:对于基本类型来说两者没有区别,都是比较值是否相同
不同点:
==
比较引用类型时是在比较地址值是否相同equals
方法本质上就是 ==
,只不过 String
和 Integer
重写了 equals
方法,把它变成了对值的比较clone()方法
clone
方法可分为浅克隆
和深克隆
要完成深度拷贝就必须实现
Clonable
接口,并重写clone
方法
实现深克隆和浅克隆的最关键的就是要实现 Object
中的 clone()
方法
public class Test {
static class Body implements Cloneable {
public Head head;
public Body() {
}
public Body(Head head) {
this.head = head;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Body newBody = (Body) super.clone();
newBody.head = (Head) head.clone();
return newBody;
}
}
static class Head implements Cloneable {
public Face face;
public Head() {
}
public Head(Face face) {
this.face = face;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class Face implements Cloneable {
public Face() {
}
}
public static void main(String[] args) throws CloneNotSupportedException {
Body body = new Body(new Head());
Body body1 = (Body) body.clone();
System.out.println("body == body1 : " + (body == body1));
System.out.println("body.head == body1.head : " + (body.head == body1.head));
}
}
创建字符串对象时,首先会去常量池里找有没有这个字符串,有的话就直接指向该字符串,没有的话就先往常量池中添加一个,再指向它。
String str1 = new String("Hello");
String str2 = "Hello";
System.out.println(str1.equals(str2));//true
System.out.println(str1 == str2);//false
new一个字符串时,做了两件事。首先在堆中开辟相应的内存空间,将内存空间的引用赋值给str1,然后去看常量池中有没有该字符串,如果有就不管了,没有就往常量池中加一个,并将其内存地址存入堆中new出来的空间中。
用字面量赋值创建,首先会去常量池中找有没有这个字符串,有就直接指向常量池的该字符串,没有就先往常量池中添加一个,再指向它。
trim() 和 compareTo():
public class StringTest {
public static void main(String[] args) {
String str1 = " Hello Worlda ";
String str2 = " Hello Worldb";
String trim = str1.trim();
System.out.println(trim); //trim方法只去除字符串头和尾的空格
System.out.println(str1.compareTo(str2)); //compareTo()方法返回两个字符串第一个不相等字符ASCII码相减的值
}
}
//结果:
Hello Worlda
-1
byte[ ] getBytes()
getBytes(String charsetName) 对字符串按照 charsetName 进行编码(unicode→charsetName),返回编码后的字节。 getBytes() 表示按照系统默认编码方式进行。
String(byte bytes[], Charset charset) 对字节按照 charset 进行解码(charset→unicode),返回解码后的字符串。 String(byte bytes[]) 表示按照系统默认编码方式进行
public class StringTest {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "浣犲ソ"; //这是"你好"的gbk编码的字符串
String str = "abcd";
byte[] b = str.getBytes();
System.out.println(Arrays.toString(b));
String ss = new String(s.getBytes("GBK"), "UTF-8");
System.out.println(ss);
}
}
//运行结果:
[97, 98, 99, 100]
你好
Throwable
|--Error
|--Exception
|--RuntimeException 运行时异常
|--非RuntimeExcetion 编译时异常,必须处理,否则编译不通过
Throwable基本方法:
System.getProperty("user.dir"); //use.dir指定了当前路径
public File(String pathname)
如果 pathname 为 null,则抛出 NullPointerException
public File(String parent, String child)
根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
如果 parent 为 null,则创建一个新的 File 实例,这与调用以给定 child 路径名字符串作为参数的单参数 File 构造方法效果一样。
否则,parent 路径名字符串用于表示目录,child 路径名字符串用于表示目录或文件。
如果 child 路径名字符串是绝对路径名,则用与系统有关的方式将它转换为一个相对路径名。
如果 parent 是空字符串,则通过将 child 转换为抽象路径名,并根据与系统有关的默认目录解析结果来创建新的 File 实例。
否则,将每个路径名字符串转换为一个抽象路径名,并根据父抽象路径名解析子抽象路径名。
参数:
parent - 父路径名字符串
child - 子路径名字符串
抛出:
NullPointerException - 如果 child 为 null
public File(File parent, String child)
根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
如果 parent 为 null,则创建一个新的 File 实例,这与调用给定 child 路径名字符串的单参数 File 构造方法的效果一样。
否则,parent 抽象路径名用于表示目录,child 路径名字符串用于表示目录或文件。
如果 child 路径名字符串是绝对路径名,则用与系统有关的方式将它转换为一个相对路径名。
如果 parent 是空抽象路径名,则通过将 child 转换为抽象路径名,并根据与系统有关的默认目录解析结果来创建新的 File 实例。
否则,将每个路径名字符串转换为一个抽象路径名,并根据父抽象路径名解析子抽象路径名。
参数:
parent - 父抽象路径名
child - 子路径名字符串
抛出:
NullPointerException - 如果 child 为 null
//例子:下面三种构造方法效果一样
File file1 = new File("D:\\Chrome\\new.dat");
File file2 = new File("D:\\Chrome", "new.dat");
File file3 = new File("D:\\");
File file4 = new File(file3, "new.dat");
mkdir()
方法创建一个文件夹,成功则返回 true,失败则返回 falsemkdirs()
方法创建一个文件夹和它的所有父文件夹String dir = "D:\\Chrome\\java";
File d = new File(dir);
d.mkdir();
public class Demo {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
File dir = new File("D:\\DeleteTest");
deleteDir(dir);
}
//一定要分清是对象的方法还是方法的参数
public static void deleteDir(File dir){
File[] files = dir.listFiles();
for(File file : files){
//是目录就递归删除
if(file.isDirectory()){
deleteDir(file);
}
//是文件就直接删除
else
file.delete();
}
//删除空目录
dir.delete();
}
}
read
public int read()
throws IOException从此输入流中读取一个数据字节。如果没有输入可用,则此方法将阻塞。
指定者:
类 InputStream 中的 read
返回:
下一个数据字节;如果已到达文件末尾,则返回 -1。
抛出:
IOException - 如果发生 I/O 错误。
关于 read() 的返回值:
read() 返回一个 unsigned byte [0 - 255],而 java 里面没有这个类型,所以用 int 接收。byte 的范围是[-128,127],所以如果 read() 返回的数在[128,255]的范围内时,则表示负数。所以如果 read() 返回的是 byte 的话,那就会有负数。而"返回-1意味着结束",这个信息量用 byte 是无法表达的,所以必须用 int
实例:将文本文件的内容打印到屏幕上
FileReader in = new FileReader("D:\\chrome\\java.dat");
int num = 0;
while((num = in.read()) != -1){
System.out.print((char)num);
}
//使用字节数组
FileInputSteam in = new FileInputSteam("D:\\chrome\\java.dat");
int cnt = 0;
byte[] b = new byte[1024];
while((cnt = in.read(b)) != -1);
for(byte by : b){
System.out.print((char)by)
}
--------------------------------------------------------------------------------
read
public int read(byte[] b)
throws IOException从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。
覆盖:
类 InputStream 中的 read
参数:
b - 存储读取数据的缓冲区。
返回:
读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
抛出:
IOException - 如果发生 I/O 错误。
另请参见:
InputStream.read(byte[], int, int)
注意:这两个 read() 方法的返回值不同, 但共同点是在遇到文件尾(end-of-file)时返回 -1,
write
public void write(int b)
throws IOException将指定字节写入此文件输出流。实现 OutputStream 的 write 方法。
指定者:
类 OutputStream 中的 write
参数:
b - 要写入的字节。
抛出:
IOException - 如果发生 I/O 错误。
qwertyuiopasdfghjklzxcvbnm
--------------------------------------------------------------------------------
write
public void write(byte[] b)
throws IOException将 b.length 个字节从指定 byte 数组写入此文件输出流中。
覆盖:
类 OutputStream 中的 write
参数:
b - 数据。
抛出:
IOException - 如果发生 I/O 错误。
另请参见:
OutputStream.write(byte[], int, int)
FileReader 和 FileWriter
read
public int read()
throws IOException读取单个字符。
覆盖:
类 Reader 中的 read
返回:
读取的字符,如果已到达流的末尾,则返回 -1
抛出:
IOException - 如果发生 I/O 错误
--------------------------------------------------------------------------------
read
public int read(char[] cbuf,
int offset,
int length)
throws IOException将字符读入数组中的某一部分。
指定者:
类 Reader 中的 read
参数:
cbuf - 目标缓冲区
offset - 从其处开始存储字符的偏移量
length - 要读取的最大字符数
返回:
读取的字符数,如果已到达流的末尾,则返回 -1
抛出:
IOException - 如果发生 I/O 错误
创建一个线程的两种方法:
Thread
类继承,就可以创建一个线程实例Thread
的构造方法Thread()
Thread(String name)
Thread(Runnable target)
Thread(Runnable target, String name)
Runnable
接口,并重写 Runnable
的 run()
方法,
不过实现 Runnable
后,还是要通过一个 Thread
来启动:public class day23_01 {
public static void main(String[] args) {
Runner r = new Runner();
//r.start();//继承自Thread的时候可以直接start()
Thread thread = new Thread(r);
thread.start();
for(int index = 0; index < 1000; index++){
System.out.println("main thread: "+index);
}
}
}
class Runner implements Runnable{
@Override
public void run() {
for(int i = 0; i < 1000; i++){
System.out.println("runner thread: "+i);
}
}
}
// class Runner extends Thread{
// @Override
// public void run(){
// for(int i = 0; i < 100; i++){
// System.out.println(i);
// }
// }
// }
new
关键字和 Thread
类或其子类建立一个线程对象后,该对象就处于新建状态。它保持这个状态直到 start()
start()
方法之后,该线程就进入就绪状态run()
,此时线程就处于运行状态。处于运行状态的线程可以变为阻塞状态、就绪状态和终止状态sleep()
、suspend()
等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获取设备资源后可以重新进入就绪状态。run()
方法,该线程结束生命周期Daemon() 必须在 start() 之前,join() 要在 start() 之后 当 jvm 中运行的线程全是守护线程时,jvm 退出