dya01: 1、编译命令:javac xxx.java 生成xxx.class文件。
2、运行可执行文件命令:java xxx(类名),jdk1.6之后不需要配置class_path环境变量,若
配置则每次都会在配置目录中查找.class文件。
3、一个字节八位,高位0表示正数,1表示负数,正数的原码、反码,补码一致,负数的反码:高位不变,
其余位取反,负数的补码:反码加1。计算机的运算都是用补码进行运算。如:

图片说明
4、boolean类型变量占用8分之一字节,一个位就能表示true或者false但是在java中是强类型,无法与
其他类型运算(C中0,1表示true,false),没有明确指定他的大小。
5、计算机默认正数是Int类型,所以byte b1=3,b2=4;byte b3=b1+b2会报错,b1+b2运算时会提升为Int类型
6、float的范围比long类型范围大,float占用4个字节,32个进制位,一位代表符号,八位代表指数位00000000-1111111,0-255,
IEEE规定减去127,所以指数的范围为-127~126,远大于long范围2^63-1
7、任何数据类型用+与字符串连接都会产生新的字符串:“hello”+'a'+1为helloa1,'a'+1+"hello"为98hello
#################################################################################
day02:1、当short与int混合运算时,会自动提升精度,short s=1;s=s+1;(报错),但s+=1;不报错,相当于s=(short)(s+1)。
2、^运算符的特点,一个数据对另一个数据异或两次,该数不变:5^10^10=5,5^10^5=5;实现两个变量交换,不借助额外变量:int x=5,y=10;x=x+y;y=x-y;x=x-y;或者:x=x^y;y=x^y;x=x^y等价于:x=10^5;y=10^5^10=5;x=10^5^5=10;
3、左移运算符:<<,左边最高位丢弃,右边补0,左移几位就是乘以2的几次幂。右移运算符>>,最高位是0,左边补0,最高位是1,左边补1,右移几位就是除以2的几次幂。无符号右移>>>,无论最高位是0还是1,左边都补0
4、键盘录入基本格式:a:导包:import java.util.Scanner;b:创建键盘录入对象:Scanner sc=new Scanner(System.in);c:通过对象获取数据:int x=sc.nextInt();
5、标号‘:’,可以给循环体标号,用break 标号跳出循环,面试中可能会误导如:System.out.println("访问百度");
http://www.baidu.com
System.out.println("百度知道");事实上,程序不会报错,“http”是标号,‘//’是注释
#################################################################################
day03:1、字符类型,char默认初始化值‘\u0000’,char在内存中占用两个字节,是16个二进制位,\u0000每一个0其实代表的是16进制的0,那么四个0就是代表16个二进制位。
2、 栈:存储局部变量;堆:存储new出来的数组或对象;方法区:.class文件,静态区,存储静态变量/方法;本地方法区:和系统相
关;寄存器:给cpu使用
3、基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失。引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存储数组对象还在,可以通过地址继续访问对象。
4、JAVA中到底是传值还是传址:既是传值,也是传址,基本数据类型传递的值,引用数据类型传递的地址;java中只有传值,因为地址也是值(出去面试都说这种)。
5、static特点:a,随着类的加载而加载;b,优先于对象存在;c,被类的所有对象共享;d,可以通过类名调用(也可以通过对象名调用)。
6、static注意事项:a、在静态方法中没有this关键字,因为:静态是随着类的加载而加载,this是随着对象的创建而存在,静态比对象先存在;b,静态方法只能访问静态的成员变量和静态的成员方法(静态只能访问静态)
7、静态变量与成员变量区别:a.所属不同,静态变量属于类,所以也称之为类变量,成员变量属于对象,所以也称之为实例变量(对象变量);b.内存中位置不同:静态变量存储于方法区的静态区,成员变量存储于堆内存。c.内存出现时间不同:静态变量随着类的加载而加载,随着类的消失而消失,成员变量随着对象的创建而创建,随着对象的消失而消失。d.调用不同:静态变量可以通过类名调用,也可以通过对象调用,成员变量只能通过对象名调用。
8、如果一个类的所有方法都是静态的,需要再多做一步,私有构造方法,目的是不让其他类创建本类对象。
9、图片说明
10、说明书的制作过程:a:对类进行描述(必须是public类):
/* 这是一个.....
@author xxx (作者)
@version v1.0 (版本)
*/
b:对方法进行描述:(私有的构造方法不会在文档体现)
/
*这是一个方法.....
@parm xxx 接收一个xxx参数(参数说明)
@return
返回... (返回值说明,若无,则去掉)
*/
c:命令行:javadoc -d xxx -version -author xxx.java
-d:文档存储路径,-author:作者,xxx.java:java源文件。
在index.html中查看结果
######################################################################################

day04:1、常见代码块的应用:a.局部代码块,在方法中出现,限定变量生命周期,及早释放,提高内存利用率;b.构造代码块(初始化代码块),在类中的方法外出现,多个构造方法中相同的代码存放到一起,每次调用构造函数都会执行,并且在构造方法前执行;c.静态代码块,在类中方法外出现,加了static修饰,用于给类进行初始化,在加载的时候就执行,并且只执行一次,一般用于加载驱动,静态代码块优先于主方法先执行;d.同步代码块(多线程中)
2、java只支持单继承,但是支持多层继承。
3、子类中所有的构造方法默认都会访问父类中无参的构造方法,因为子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化之前,一定要先完成父类数据的初始化。其实,每一个构造方法的第一条语句默认都是:super() object类最顶层的父类。
4、this的构造与super的构造不可同时存在,并且必须放在第一条语句执行,若使用了this调用构造,则系统不会再调用默认的super构造。
5、方法重写注意事项:a.父类中私有方法不能被重写,因为父类私有方法子类根本就无法继承。b.子类重写父类方法时,访问权限不能更低,最好一致。c.父类静态方法,子类也必须通过静态方法重写(其实静态只是覆盖)
6、override与overload区别:方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值类型是一致的。方法重载:本类中出现的方法名一样,参数列表不同的方法,与返回值类型无关。
7、final关键字:修饰类,类不能被继承;修饰变量,变量就变成了常量,只能被赋值一次;修饰方法,方法不能被重写。
8、常量命名规范,如果是一个单词,所有字母大写,如果是多个单词,每个单词都大写,中间用下划线隔开。
9、final修饰变量叫做常量,一般会与public static一起用,方便用类名直接调用。
10、final修饰变量的初始化时机:a.显示初始化,被final修饰的成员变量,默认初始化值是无效值,因为一旦赋值无法修改,所以需要显示地初始化赋值;b.在对象构造完毕前即可:在构造方法中初始化赋值。
#################################################################################
day05:1、多态(polymorphic)前提:要有继承关系,要有方法重写,要有父类引用指向子类对象。
2、多态中成员的访问特点:成员变量,编译看左边(父类),运行看左边(父类);成员方法,编译看左边(父类),运行看右边(子类),动态绑定(联编,编译先看父类有没有,运行再看子类 );静态方法,编译看左边(父类),运行看左边(父类)(静态和类相关,算不上重写,所以,访问还是左边的)。
3、父类引用指向子类对象,向上转型;强制将父类引用转换为子类引用,向下转型。
4、多态的好处:提高了代码的维护性(继承保证),提高了代码的扩展性(多态保证);多态的弊端:不能使用子类特有的属性和行为。
5、开发的时候很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象,可以使用子类特有的属性和方法;当做参数的时候用多态最好,因为扩展性强。
6、关键字:instanceof,用于判断引用的类型,语法: 引用 instanceof 类型 返回true/false
7、抽象类的特点:a.抽象类和抽象方法必须用abstract关键字修饰;b.抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口;c.抽象类不能实例化,按照多态的方式,由具体的子类实例化,其实这也是多态的一种,抽象类多态;d.抽象类的子类,要么是抽象类,要么重写抽象类中的所有抽象方法。
8、抽象类的成员特点:成员变量:既可以是变量也可以是常量;b.构造方法:有,用于子类访问父类数据的初始化;c.成员方法:既可以是抽象的,也可以是非抽象的,抽象方法强制要求子类做的事情,非抽象方法,子类继承的事情,提高代码复用性。
9、面试题1:一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?答,可以,这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成。面试题2:abstract不能和那些关键字共存。答:static、final、private。
10、接口interface的特点:成员变量只能是常量,并且是静态公共的,默认修饰符:public static final,建议自己手动给出;构造方法:没有构造方法;成员方法,只能是抽象方法没建议手动给出。
11、类与类:继承关系,只能单继承,可以多层继承;类与接口:实现关系,可以单实现,也可以多实现;接口与接口:继承关系,可以单继承,也可以多继承。
12、抽象类与接口区别:图片说明
#################################################################################
day06:1、package关键字:将字节码(.class)进行分类存放,包其实就是文件夹。
2、包的定义及注意事项:package 包名,多级包用.分开即可。package语句必须是程序第一条可执行的代码,在一个java文件中只能有一个,如果无package,默认无包名。
3、带包的的类编译和运行:javac -d . xxx.java;运行:java 包名.类名。
4、内部类:可以直接访问外部类的成员,包括私有,外部类要访问内部类的成员,必须创建对象:外部类名.内部类名 对象名=外部类对象.内部类对象。
5、静态成员内部类:外部类名.内部类名 对象名=外部类名.内部类对象;
6、在内部类中,访问内部类的成员变量:this.变量,访问外部成员变量:外部类名.this.变量名。
图片说明
7、局部内部类:在成员方法定义的类,只能在其所在的方法中访问,并且只能访问该方法中的常量(用final修饰)。问:局部内部类在访问它所在的局部变量必须用final修饰,为什么?答:因为当调用这个方法时,局部变量如果没有用final修饰,它的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想访问这个局部变量就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池还在,也可以继续使用。但是jdk1.8取消了这个事情,所以我认为这是个bug。
8、匿名内部类:就是内部类的简化写法;前提:存在一个类或者接口(可以是具体的类也可以是抽象类)格式:new 类名或者接口名(){
重写方法;
}
匿名内部类的本质是一个继承了该类或者实现了该接口的子类匿名对象。
9、匿名内部类只针对重写一个方法时候使用,匿名内部类是不能向下转型的,因为没有子类类名。
10、链式编程:类名.方法名.方法名 如:Outer.method().show();链式编程,每次调用方法后还能继续调用方法,证明调用方法返回的是一个对象。
#################################################################################
day071、Eclipse编译环境配置:windows--Preferences--Java,编译环境Compiler默认选中的就是最高版本。运行环境:Installed JREs 默认会找安装的那个jdk。建议配置了Java的环境变量。
2、如何去掉默认注释windows--preferences--java--code style--code Templates。
3、图片说明
4、图片说明
5、图片说明
6、alt+shift+s 弹出后按c,构建空参构造,alt+shift+s 弹出后按o,根据本地变量生成有参构造。alt+shift+s 弹出后按r,给变量封装set和get方法。
7、ctrl+alt+下键:向下复制一行。
8、jar是多个class文件的压缩包,打jar包:选中项目--右键--Export--Java--Jar--指定路径和名称--Finish。导入Jar包:复制到项目路径下并添加至构建路径。
#################################################################################
day081、hashCode(),返回存储的哈希地址码;getClass()获取对象的字节码文件(返回类型:Class),再getName()返回类名。也可以用对象调用toString()方法,返回类名@十六进制哈希地址值。
2、如果直接打印对象,会默认调用对象的toString()方法。可以更方便地显示属性值。
3、Object中的equals()方法时比较对象的地址值是否相等,相当于两个对象“==”,没什么意义,需要重写。在开发中通常比较对象的属性值,相同属性是同一个对象。
4、String面试题:
图片说明
5、图片说明
6、图片说明
7、图片说明
8、图片说明
9、String类的判断:equals(s),equalsIgnoreCase(s)不区分大小写、contains(s)是否包含字符串、startWith(S)、endWith(s)以某字符串开始/结束。
10、""(空串)和null的区别:""是字符串常量,同时也是一个String类的对象,既然是对象当然可以调用String类中的方法,null是空常量,不能调用任何的方法,否则会出现空指针异常,null常量可以给任意的引用数据类型赋值。
11、如果是字符串常量和字符串变量比较,通常都是字符串常量调用方法,将变量当做参数传递,防止空指针异常。
#################################################################################
day091、StringBuffer与String的区别:String是一个不可变的字符序列,StringBuffer是一个线程安全的可变字符序列。
2、append()把任意数据类型添加到字符串缓冲区里面,并返回字符串缓冲区本身,insert(int offset,String str)在指定位置把任意类型的数据插入到字符串缓冲区里面,并返回字符串缓冲区本身。
3、StringBuffer是字符串缓冲区,当new的时候会在堆内存创建一个对象,底层是一个长度为16的字符数组,当调用添加的方法时,不会重新创建对象,再不断向原缓冲区添加字符。
4、deleteCharAt(int index)删除指定位置字符,并返回本身,delete(int start,int end)删除指定区间(左闭右开)。
5、replace(int start,int end,String str)替换区间;reverse();字符串反转。
6、substring(int start)返回string类型,截取字符串。substring(int start,int end)截取区间,左闭右开,返回String 类型。
7、String转为StringBuffer:通过构造方法,通过append方法;StringBuffer转为String:通过构造方法,通过toString()方法,通过subString()方法。
8、图片说明
9、String类虽然是引用数据类型,但是当它作为参数传递时和基本数据类型是一样,不改变其值;StringBuffer做参数时,会改变其值。
10、Arrays类,String toString()数组转字符串,void sort(int[] a)排序,int binarySearch(int[] a,int key)二分查找,找不到则返回负的插入点减一
11、将基本数据类型封装成对象可以在对象中定义更多功能方法操作该数据:用于基本数据类型与字符串之间的转换,进制转换等。八种基本数据类型,除了int-->Integer,char-->Character,其余的包装类都是首字母大写。
12、int转String:num+"",String.ValueOf(num),Integer.toString(num);String转int:Integer i=new Integer(str);i.intValue()或Integer.paseInt(str)。
13、基本数据类型包装类有八种,其中其中个都有parseXxx的方法,可以将这其中的字符串表现形式转换成基本数据类型。char的包装类Character中没有pareseXxxx,字符串到字符的转换通过toCharArray()就可以吧字符串转换为字符数组。
14、JDK5新特性:自动装箱子:把基本数据类型转换为包装类类型;自动拆箱:把包装类类型转换为基本类型。
15、图片说明
#################################################################################
day101、正则表达式:String类中有一个boolean matches(String regex)方法。
2、 "[]"代表单个字符:[1-9]代表可以是1到9任意一个字符,"[^abc]"代表除了abc的单个字符,"10".matches("[^abc]")为false,因为“10”为两个字符。[a-zA-Z]或[a-z[A-Z]]代表一个字母(并集);[a-z&&[def]]交集def。
图片说明
3、预定义字符类:图片说明
4、数量词:
图片说明
5、String类中String[] split(String res)根据正则分割。
6、String类功能:String replaceAll(String regex,String replacement)正则表达式的替换。
7、正则表达式分组功能:叠词AABB,(.)\1(.)\2,表示1组出现又出现一次,2组又出现一次;叠词ABABA:(..)\1;用括号进行分组,用“1") 结果为ABC。
8、Pattern和Matcher:
图片说明
9、获取字符串中的所有手机号:
图片说明
10、Random类中有一个nextInt(num)用于生成0--num-1的伪随机数。
11、System类中有finalize()垃圾回收时调用,gc()强制回收垃圾。arraycopy(src,start,dest,start,length),用于拷贝数组。currentTimeMillis()获取当前时间,用于计算程序运行的时间。
12、BigInteger类,更大的整数,任何精度的整数,有自己的加减乘除方法,常用于金融证券。
13、BigDecimal,更精确的浮点,用字符串做参数构造,常用于金融证券。
14、Data类,如果构造方法中参数为0,代表1970年1月1日。空参构造为当前时间。
15、DateFormat时间格式的抽象类,提供getDateInsrance()返回子类对象(SimpleDateFormat)。
16、Calendar类有三个字段,YEAR,MONTH(从0开始),DAY_OF_MONTH,可以使用add(字段,int)方法加减,使用set(字段,int)方法设置字段值或者修改三个字段set(年,月,日)。
#################################################################################
day101、数组和集合的区别:数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值;集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象。数组长度是固定固定的,不能自动增长,集合的长度是可变的,可以根据元素的增加而增长。
2、Collection接口有两个子接口:list,有序(存和取顺序一致),有索引,可以存储重复;Set,无序(存和取的顺序不一致),无索引,不可以存储重复。
3、List下有ArrayList(数组实现),LinkedList(链表实现),Vector(数组实现);Set下:HashSet(哈希算法),TreeSet(二叉树算法)。
4、add方法,如果是List集合一直都返回true,因为List集合中是可以存储重复元素的,如果是Set集合当存储重复元素的时候,就会返回false。
5、toArray()把集合转换为数组,两个集合c1.removeAll(Collect c)删除交集,addAll并集。c1.containsAll(c2)判断是否包含子集,c1.retainAll(c2)取交集,并将结果赋值给c1,若c1改变返回true,否则返回false。
6、ListIterator是List集合特有的迭代器,可以在遍历的时候并发增加add(),remove()。
7、Vector是的jdk1.0的,继承iterator,有自己的迭代方法(枚举):Enumeration en=v.elements();en.hasMoreElements();en.nextElement()。
8、List三个子类的特点:
图片说明
9、generic泛型,泛型优点:提高安全性(将运行期的错误转换到编译器),省去强转的麻烦。早期的Object类型可以接收任意类型的对象,但是在实际的使用中,会有类型转换的问题。也就存在着隐患,所以Java提供了泛型来解决这个安全问题。
10、方法泛型最好与类的泛型一致,如果不一致,需要在方法上声明泛型。
11、静态方法必须声明自己的泛型。
12、当右边的泛型是不确定时,左边可以指定为?,List<?> list =new ArrayList<>();
13、泛型通配符:<?>,任意类型,如果没有明确,那么就是object以及任意的Java类了;? extends E,向下限定,E及其子类;?super E,向上限定,E及其父类。
14、增强for:简化数组和Collection集合的遍历,快捷键:fore+alt+/,格式:
for(元素数据类型 变量:数组或者Collection集合){
使用变量即可,该变量就是元素
}
15、静态导入,导入类中的静态方法,如import static xxx.xxx 然后就可以不加类名直接调用方法,但是如果有多个同名静态方法,容易不知道使用谁。由此可见,意义不大,不建议使用。
16、可变参数,可变参数其实是一个数组。定义方法的时候不知道该定义多少个参数,格式:
修饰符 返回值类型 方法名(数据类型 ... 变量名){} 如:public void print(int ... arr)
注意:如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个。
17、Arrays工具类将数组转换成集合:Arrays.asList(arr),数组转换成集合虽然不能增加或者减少元素,但是可以用集合的思想操作数组,也就是说可以使用其他的集合方法。基本数据类型的数组转换成集合,会将整个数组当做一个对象。如:List<int[]>list=Arrays.asList(arr);所以将数组转换成集合,数组必须是引用数据类型(装箱)。
18、当集合转换数组时,数组长度如果小于等于集合的size,转换后的数组长度等于集合大小,如果数组的长度大于size,分配的数组长度就和指定长度一样。
########################################################################################
day111、HashSet中唯一性的机制:重写hashCode()方法,返回一个int,若hash值相等,调用equals()方法,判断是否相等,开发中,用alt+shift+s h快捷键,找到重写hashCode()和equals()方法,提高效率。
2、hashCode()中为什么计算哈希值的时候,系数是31:31是一个质数,较少了重复的可能性;31这个数不大也不小;31这个数好算,2的五次方减1,2向左移5位。
3、hashCode()属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率)。equals():属性相同返回true,属性不同返回false,返回false的时候存储。
4、linkedHashSet,底层是链表实现,是set集合中唯一一个能保证存取一致,而且具有唯一性。
5、TreeSet需要实现Comparable接口,重写comparaTo方法,小的存储在左边(负数),大的存储在右边(正数),相等就不存(0)。
6、 比较器排序:一个类实现Comparator,重写compare方法,然后将该类对象作为参数,构造new TreeSet(比较器对象)。
7、HashSet底层是由HashMap实现的,HashSet隐藏了value,都是用同一套的Hash算法。
8、map的put方法会覆盖相同的key值,并且将被覆盖的 value返回。remove()也一样。
9、map.containsKey(),map.containsValue(),判断是否包含某个键或者值。
10、map.values()返回所有value值得一个集合。
11、map第一种遍历:map中没有迭代器,可以使用map.keySet()获取所有键的集合,然后遍历键的集合,使用map.get(key)方法获取对应的值。
12、map第二种遍历:Map.Entry<K,V>是map的内部接口,Entry将键和值封装成了Entry对象,并存储在Set集合中。(类似于C++的pair<K,V>)。map.entrySet()返回实体集合。
13、HashMap中一个内部类Entry实现了Map.Entry。
14、LinkedHashMap,存取顺序一致。
15、HashMap与Hashtable区别:共同点,底层都是哈希算法,都是双列集合;HashMap是线程不安全的,效率高,JDK1.2版本,Hashtable是线程安全的,效率低,JDK1.0版本的;HashMap可以存储null键和null值,Hashtable不可以存储null键和null值。
16、Collections工具类常用方法:
图片说明
17、泛型固定下边界:? super E;泛型固定上边界:? extends E。
18、TreeSet有两种排序方式:自然排序,在自定义类型中实现Comparable接口重写comparaTo方法;定制排序:比较器排序,写一个类,实现Comparator,在构造集合的时候传入比较器。
########################################################################################
day121、 异常处理的两种方式:try...catch...finally,或throws。
2、安卓客户端开发,处理异常:try{}catch(Exception e){};JavaEE,服务端开发,一般都是底层开发,从底层向上抛。
3、 Throwable的几个常见方法:getMessage(),获取异常信息,返回字符串;toString()获取异常类名和异常信息,返回字符串;printStackTrace(),获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
4、 编译时异常的抛出,必须对其进行处理,运行时异常的抛出可以处理也可以不处理。
5、throws和throw的区别:throws,用在方法声明后面,跟的是异常类名;可以跟多个异常类名,用逗号隔开;表示抛出异常,由方法体内的语句处理。throw,用在方法体内,跟的是异常对象名;只能抛出一个异常对象;表示抛出异常,由方法体内的语句处理。
6、finally特点:被finally控制的语句体一定会执行,特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))。
7、在main方法中return之后,还是会执行finally语句。
8、final,finally和finalize的区别:final可以修饰类,不能被继承,修饰方法不能被重写,修饰变量只能赋值一次;finally是try语句中的一个语句体,不能单独使用,用来释放资源;finalize是一个方法,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
9、千万不要在finally里面写返回语句,因为finally的作用是为了释放资源,肯定会执行,如果在finally里面写返回语句,try和catch的结果都会被改变,所以这么写不安全。
10、异常注意事项:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类(父类坏了,儿子不能比父亲坏);如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常;如果被重写的方法没有抛出异常,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws。
11、alt+shift+z (try-catch快捷键)
12、File对象有createNewFile()方法,如果文件存在,就不创建。mkdir()创建文件夹,如果存在,就不创建,mkdirs()创建多级文件夹,如果父文件夹不存在,会帮你创建出来。
13、renameTo(File dest):把文件重命名为指定文件路径(如果路径相同就是重命名,若不同就是改名复制),delete()删除文件或文件夹,删除一个文件夹里面不能有文件或者文件夹,注意:Java中的删除不走回收站。
14、File的判断功能:isDirectory()判断是否是目录,isFile()是否是文件,exists()是否存在,canRead()是否可读,setReadable(bool)设置是否可读(windws系统认为所有文件都可读,该方法用于Linux),canWrite()是否可写,setWritable(bool)设置是否可写,isHidden()是否隐藏。
15、File类的获取功能:getAbsolutePath()获取绝对路径,getPath()获取路径,getName()获取名称,length()获取长度字节数,lastModified()获取文件最后的修改时间,listFiles()获取指定目录下的所有文件或者文件夹的File数组。
16、 list方法传入FilenameFilter文件名称过滤器接口,实现accetp(File dir,String name)方法。
########################################################################################
day131、IO流FileInputStream中的read()方法,每次读取一个字符,‘-1’为文件的末尾标志。
2、IO流的read()方法返回值为什么是Int?答:因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到1111111,那么111111111是byte类型的-1,就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就会变成int类型的255了,这样就可以保证整个数据读完,而结束标记的-1就是int类型。
3、FileOutPutStream创建字节输出流对象,如果没有文件就会创建,如果有先清空,write()方法虽然写的int类型,但是会自动砍到前面的三个字节,保存一个字节。
4、可以追加写,如果想续写就在构造函数中传入第二个参数true。
5、为了提高效率同时避免内存溢出,可以定义小数组,每次拷贝小数组大小的数据。
6、IO流定义小数组的标准格式:
图片说明
7、IO流的BufferedInputStream和BufferOutputStream拷贝:
图片说明
8、缓冲思想:java在设计的时候加入了数组这样的冲区效果,考虑到了装饰模式的设计思想,所以提供了字节缓冲区流。
9、BufferInputStream内置了一个缓冲区(数组),从BufferedInputStream中读取一个字节时,BufferedInputStream会一次性从文件中读取8192个,存在缓冲区中,返回给程序一个,直到缓冲区中所有的都被使用过,才重新从文件中读取8192个。
10、定义小数组读写和Buffered的读取哪个更快?定义小数组如果是8192个字节大小和Buffered比较的话,定义小数组会略胜一筹,因为读写操作的是同一个数组,而Buffered操作的是两个数组。
11、close()方法具备刷新功能,在关闭流之前,会先刷新一次缓冲区,将缓冲区的字节全部都刷新到文件上再关闭。flush()方法刷新缓冲区,刷新完还可以继续写。
12、字节流在读中文的时候有可能会读到半个中文,造成乱码。字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组。写出回车换行write("\r\n".getBytes());
13、JDK1.6版本IO流标准处理异常:
图片说明
14、JDK1.7版本 实现了closeable接口,该接口继承了AutoCloseable,在写完流之后自动关闭:
图片说明
15、图片加密功能的实现:通过在写字节的时候,异或一个数,解密的时候就是异或同一个数。
16、字符流,读取的时候先将字符转换为字节,写出的时候将字节转换为字符。
17、Writer类中有一个2k的缓冲数组,若不关闭FileWriter字符就会滞留在缓冲区,只有close()才可以刷新缓冲区,写出字符。
18、字符流也可以拷贝文件,但不推荐,因为字符流读取时会把字符转换成字节,写出时要把字节转换为字符。一般对文件进行读或者写的时候使用字符流,读的时候会根据字符大小读字节,不会出现半个中文,写的时候直接写字符串,不需要将字符串转换为字节数组。
19、字符流不可以拷贝非纯文本的文件,因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转成字节写出去,如果是?,直接写出,这样写出之后的文件就乱了。
20、LineNumberReader类,可以按行读取文本,并输出行号。有setLineNumber和getLineNumber方法。
21、装饰设计模式:(1)、获取被装饰类的引用(声明为成员变量),(2)、在构造方法中传入被装饰类的对象赋值,(3)、在方法中对原有的功能进行升级(调用原有功能,另外再加自己的)。
22、装饰模式的优势:耦合性不强,被装饰的类的变化与装饰类的变化无关。
23、InputStreamReader(字节流,编码表)字节通向字符的桥梁,通过指定的编码表将字节转换为字符。OutputStreamWriter(字节流,编码表),字符通向字节的桥梁,通过指定的编码表将字符转换为字节。
########################################################################################
day141、多线程并行和并发的区别:并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行,(需要多核CPU);并发是指两个任务都请求运行,而处理器只能接受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行,
2、Java程序运行原理:Java命令会启动java虚拟机,启动JVM,等于启动了一个应用程序,也就是启动了一个进程,该进程会自动启动一个“主线程”,然后主线程去调用某个类的main方法。
3、JVM启动是多线程的吗?JVM启动至少启动了垃圾回收线程和主线程,所以是多线程。
4、创建新执行线程有两种方法:一种方法是将类声明为Thread的子类。该子类应重写Thread类的run方法。接下来可以分配并启动该子类的实例,启动方法:对象.start()。第二种:声明实现Runnable接口的类。该类实现run方法,然后可以分配该类的实例,在创建Thread时作为一个参数来传递并启动,启动方法:Thread t=new Thread(Runnable子类对象),t.start()。
5、多线程实现Runnable的原理:(1)看Thread类的构造函数,传递了Runnable接口的引用,(2)通过init()方法找到传递的target给成员变量的target赋值,(3)查看run方法,发现run方法中有判断,如果target不为Null就会调用Runnable接口子类对象的run方法。
6、多线程两种方式的区别:(1)继承Thread:由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法。(2)实现Runnable:构造函数中传入了Runnable的子类引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空编译时看的是Runnable的run(),运行时执行的是子类的run()方法。
7、继承Thread:好处是:可以直接使用Thread类中的方法,代码简单。弊端是:如果已经有了父类,就不能用这种方法。
8、实现Runnable接口:好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的。弊端是:不能直接使用Thread中的方法,需要先获取到线程的对象后,才能得到Thread的方法,代码复杂。
9、可以使用匿名内部类 继承Thread重写run方法调用start();new Thread(new Runnable(){void run(){}...}).start()。
10、线程有getName()方法,默认编号从1开始命名。
11、curentThread()返回当前正在执行的现成对象的引用。
12、休眠线程:sleep(毫秒,纳秒),
13、守护线程:setDaemon(true/false),设置一个线程为守护线程,该线程不会单独执行,当其他非守护线程都执行结束后,自动退出。
14、加入线程join(),当前线程暂停,等待指定的线程执行结束后,当前线程再继续。join(int),可以等待指定的毫秒之后继续。
15、礼让线程:yield(),让出cpu。
16、设置线程的优先级(默认5,范围1-10):setPriority()。
17、多线程(同步代码块):什么情况下需要同步:当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中cpu不要切换到其他线程工作,这时就需要同步。如果两段代码是同步的,那么同一时间只能执行一段,在一段代码没执行结束之前,不会执行另一端代码。
18、同步代码块:使用synchronized(任意对象)关键字加上一个锁对象来定义一段代码,叫同步代码块。多个同步代码块如果使用相同的锁对象,那么他们就是同步的,锁对象是任意的,但不能用匿名对象,因为必须是同一个对象。
19、 多线程(同步方法):使用synchronized关键字修饰一个方法,该方法中的所有代码都是同步的。非静态的同步方法锁对象是this。静态的同步方法是字节码对象。
20、同步代码块的嵌套容易发生死锁。
21、vector线程安全,加了synchronized;ArrayList是线程不安全。StringBuffer是线程安全的,StringBuilder是线程不安全的。HashTable是线程安全的,HashMap是线程不安全的。Collections.synchronizedxxx()将不安全的转成安全的,比如Collections.synchronizedMap()
########################################################################################
day151、单例模式:保证类在内存中只有一个对象。私有构造方法,其他类不能访问该构造方法,静态私有成员变量,对外提供公共的访问方法。
2、饿汉式:加载类的时候直接创建对象,懒汉式(单例模式的延迟加载):先声明不创建对象,在调用获取对象的时候创建。
3、饿汉式和懒汉式的区别:饿汉式是空间换时间,懒汉式是时间换空间。在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象。
4、Runtime类就是一个单例模式。Timer类:计时器任务。
5、两个线程间的通信:wait()进入等待,notify()随机唤醒单个等待的线程。在哪里等待被唤醒就在哪里继续执行。
6、三个或者三个以上间的线程通信:this.notifyAll(),在同步代码块中,用什么锁,synchronized(this)就要用什么等待this.wait()及唤醒this.notify()。
7、sleep()方法与wait()区别:sleep方法必须传入参数,参数就是时间,时间到了自动唤醒。wait方法可以传入参数也可以不传入参数,传入参数就是参数结束后的时间等待,不传入参数就是直接等待。sleep()方法在同步函数或同步代码块中,不释放锁,wait方法在同步函数或者同步代码块中,释放锁。
8、互斥锁:ReentranLock,有lock()和unlock()方法,newCondition()返回用来与此lock实例一起使用的Condition监视器实例,调用await()方法和signal()方法可以唤醒指定的线程。
9、线程组:ThreadGroup,默认是主线程组main。在创建线程时,将线程组的对象传入构造函数。
10、多线程,线程的五种状态:新建:创建线程对象,就绪:线程对象已经启动了,但是还没有获取到CPU的执行权;运行:获取到了CPU执行权;阻塞:没有CPU的执行权,回到就绪;死亡:代码运行完毕,线程消亡。
图片说明
11、线程池:程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好地提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池,线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。ExecutorService pool=Executors.newFixedThreadPllo(线程个数),使用submit(线程对象)方法加入线程池。pool.shutdown()关闭线程池。
12、第三种多线程方式Callable接口。
13、适配器模式:通常接口中有多个方法,而程序中不一定所有的都用到,但又必须重写,这很繁琐。适配器简化了这些操作,我们定义***时只要继承适配器,然后重写需要的方法即可。适配器原理:适配器就是一个类,实现了***接口,所有抽象方法都重写了,但是方法全是空的。适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的。
14、
########################################################################################
day161、ip地址:每个设备的唯一标识,ipv4:4个字节组成,4个0-255,2011年初已经用尽。ipv6:8组,每组4个16进制数。
2、端口号:每个程序在设备上的唯一标识,每个网络程序都需要绑定一个端口号,传输数据的时候除了明确ip地址,还要明确发到哪个程序。端口号从0-65535,编写网络应用程序就要绑定一个端口号,尽量使用1024以上的,1024一下的基本都被系统程序占用了。
3、网络编程三要素:UPD(发短信):面向无连接,数据不安全,速度快,不区分客户端与服务端。TCP:面向连接(三次握手),数据安全,速度略低,分为客户端和服务端。三次握手:客户端先向服务端发起请求,服务端响应请求,传输数据。
4、Socket套接字概述:网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。通信的两端都有Socket,网络通信其实就是Socket间的通信。数据在两个Socket间通过IO流传输。Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所在对应的IP和port。
5、UPD传输:发送端:创建Socket(码头): DatagramSocket socket=new DatagramSocket(); 创建packet(集装箱):DatagramPacket packet=new DatagramPacket(指定数据,长度,地址,端口);发送send(发货)。
图片说明 socket.send(packet);socket.close()。接收端:创建Socket(码头);创建packet(集装箱)(指定数组,长度);socket.receive()。packet.getData();packet.Length();socket.close()。图片说明
6、TCP的客户端:创建Socket连接服务端(指定ip地址,端口号)通过ip地址找到对应的服务器;调用socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流。输入流可以读取服务端输出流写出的数据,输出流可以写出数据到服务端的输入流。
7、TCP服务端:创建ServerSocket(需要指定端口号),调用accept()方法接收一个客户端请求,得到一个Socket;调用socket的getInputStream和getOutputStream()方法获取和客户端相连的IO流。调用流的write()方法。相应的客户端有read()方法。
图片说明
图片说明
8、可以使用PrintStream,BufferedReader优化传输。ps.println();br.readLine()以/r/n为结束。
图片说明
图片说明
9、服务端多线程:while(true){ new Thread(){void run(){处理请求}}};
10、上传文件:(1)提示输入要上传的文件路径,验证路径是否存在以及是否是文件夹,(2)发送文件名到服务端,(3)建立多线程的服务器,(4)读取文件名,(5)判断文件是否存在将结果发回客户端,(6)接收结果,如果存在给予提示,程序直接退出。(7)如果不存在,定义FileInputStream读取文件,写出网络。
11、类的加载:当程序要使用某个类时,如果该类还未被加载到内存中,系统会通过加载,连接,初始化三步来对类进行初始化。
12、加载:就是指将一个class文件读入内存,并为之创建一个class对象,任何类被使用时系统都会创建一个class对象。
13、连接:(1)验证 是否有正确的内部结构,与其他类协调一致。(2)准备 负责为类的静态成员分配内存,并设置默认初始化值。(3)解析 将类的二进制数据中的符号引用替换为直接引用。
14、类的加载时机:创建类的实例、访问类的静态变量或者为静态变量赋值,调用类的静态方法,使用反射方法来强制创建某个类或接口对应的java.lang.class对象,初始化某个类的子类,直接使用java.exe命令来运行某个主类。
15、类加载器:(1)Bootstrap classLoader 根类加载器,也称为引导类加载器,负责java核心类的加载比如System,string等在rt.jar中。(2)Extension ClassLoader扩展类加载器,负责JRE的扩展目录中jar包的加载 (3)System Classloader 系统类加载器,负责在JVM启动时加载来自java命令的class文件,以及classpath环 境变量所指的jar包和类路径。
16、JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能成为java语言的反射机制。
图片说明
图片说明
17、Class也有nweInstance()方法获取字节码对象的实例。
图片说明
18、getField获取成员变量,getDeclaredField()暴力反射获取字段,setAccessible(true)去除私有权限。
图片说明
19、获取无参非私有方法clazz.getMethod(Str),执行invoke(对象);有参:getMethod(Str,xxx.class)
图片说明
20、通过反射可以越过泛型检查,泛型只在编译期有效,在运行期会被擦除掉。
图片说明
21、反射代理类Proxy可以实现接口invocationHandler接口,进行代理。
图片说明
图片说明
22、枚举类enum
图片说明