java 基础 笔记

原创
2016/11/27 11:06
阅读数 43

1、线程启动为什么要运用start()而不是run?
因为线程牵扯到操作系统的资源分配问题,所不能直接运用run方法,而需要使用start方法,这个方法实际上是去调用操作系统的方法。
2、线程的三种实现模式
   继承thread类:单继承的局限
   实现runnable接口:没有单继承的实现,可以实现数据共享
   实现callable接口:在runnable基础上多了一个功能即可以返回值
线程的启动都得使用thread的start方法。
3、线程同步异步,可以使用代码块中加入synchronize修饰,或者在方法中加入synchronize
4、打断线程的睡眠必须是另一个线程,意思是一定要使用另一个线程对象去调用intercept方法。
5、多个线程访问同一个资源可能带来什么问题,并有什么附加的效果。
   ·多个线程访问同一个资源需要考虑同步问题。
   ·过多的同步可能对线程造成死锁。程序运行效率降低。
6、sleep 和 wait的区别
   ·sleep是thread的方法,睡眠时间到后会醒来。
   ·wait是object的方法,只用使用nodify或者nodifyAll方法才能唤醒。 
   对象调用wait后,对象会释放锁机制,等待该对象调用nodify方法后重新获取锁代表可以回到停顿的地方继续执行了,这个操作往往是因为资源不够,要等待另一个线程去创造一些资源的时候,等另一个线程创造好了资源(此时往往是在往共享数据中添加了资源,然后使用nodify方法,所以wait必须在synchronize中使用,否则就会抛出异常,这也很合理):常见案例:生产者和消费者。
   sleep不会释放对象锁,因为sleep是线程的方法,无法去释放对象的锁(sleep只是短暂的睡眠,锁还是自己拿着,等醒了后就准备继续执行的)。
7、string stringBuffer stringBuilder
   ·string是不可改变的,StringBuffer是可以改变的。
   ·stringbuffer类有个反转,一个删除等特点性质的方法。
   ·stringbuffer和stringbuilder,前者线程安全的,后者非线程安全(异步的操作,性能更高)。
8、runtime类 
   ·runtiem类是跟随一个进程的。构造方法是私有的,异味里面有一个静态的方法获取runtime来用
   ·GC:java的垃圾回收器,可以用runtime的gc方法手动回收垃圾,java也会自动回收未使用的对象。回收机制:永生代,年轻代,旧生代。
9、代码示例
       Integer i1 = 40;
        Integer i2 = 40;
        Integer i3 = 0;
        Integer i4 = new Integer(40);
        Integer i5 = new Integer(40);
        Integer i6 = new Integer(0);
        System.out.println("i1=i2\t" + (i1 == i2));true:因为integer在java里跟string一样有维护一个常量池,这个常量池的大小是-127~128,当未使用new方法申明的基本封装类型时,是从常量池中获取数据的(当然这个是在上面的范围内),如果换成大于127的例如129就变成false了,因为超过常量池里的数后,就是通过new获取的,属于引用类型了。
        System.out.println("i1=i2+i3\t" + (i1 == i2 + i3));true:java的数学计算是在栈中实现的,在栈中会进行拆箱操作,这个最后就是数学计算了,结果当然相等
        System.out.println("i4=i5\t" + (i4 == i5)); false,指向的引用不同。
        System.out.println("i4=i5+i6\t" + (i4 == i5 + i6)); true:java的数学计算是在栈中实现的,在栈中会进行拆箱操作,这个最后就是数学计算了,结果当然相等
10、java栈,堆
    在java中,栈和堆都是存在于内存中的,栈中能存放的东西很少,因为栈的读取熟读要比堆块,所以栈中存放的东西自然就是一些对象的引用,和一些基本数据类型的存储(int,double等这样的)。堆中存放的是new出来的一些对象,还有常量池。
    不管是普通类型的变量还是引用类型的变量(熟称实例),都可以在栈和堆中保存,只是普通类型的变量的值也是保存在栈中,而引用类型的变量只是把指向堆中的一个指针或者引用信息保存于栈中,而真正的值保存在堆中,所以引用类型的对象在栈和堆中都有保存信息。
11、栈和堆中对象生存周期
    栈中存放的是对象的引用或者基本类型的值,当对象的引用或者基本类型的值是局部变量时,在方法使用完成java就会立刻释放栈中的
空间,而虽然是局部变量的引用但是其堆中对应的值确实要等java的垃圾回收机制制动回收,这个回收我们无法控制(可以使用Runtime.gc方法
但是也不是绝对的,当调用gc方法时,也只是告诉java虚拟机要去回收了,至于它到底回不回收是一回事。) 
12、实例化和对象
    实例化是保存在栈中的一个引用,对象是保存在堆中的,多个实例化可以指向同一个堆中的值。
13、java是在运行前jvm就为程序分配好地址的,运行时创建的对象会临时分配新的地址。如下代码测试(在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象):
     string hello = "hello",lo="lo";
     system.println.out(hello==("hel"+lo));
14、javavisualVM 一个查看内存分配的工具。
15、throws Throwable 是能同时处理exception和error的异常。
16、final,finally,finalize区别
    final:定义不能被继承的父类,定义不能被子类覆写的方法,定义常量。
    finally:是异常处理中进行异常处理的统一出口。
    finalize:是object类的方法,是在对象被回收之前统一处理的一个方法即进行对象收尾操作(protected void finalize()throws Throwable)。
17、System类中 有一个gc方法,这个方法跟runntime.gc方法一样,gc方法永远只有一个(就是runntime中的gc,其他地方的gc都是调用而已。),所以System中的gc也是强制清空(注意这里是清空,不是回收。)
18、清空和回收
    当把一个对象实例化赋值null后这时只是让java虚拟机回收该对象,等待清空状态,等到内存不足或者其他情况时在清空,而使用system.gc则是清空对象,gc方法是非常耗用cpu的,所以频繁使用会有适得其反的效果,这也是java开发中我们不手动去清空,而是使用java的垃圾回收机制自动去清空的原因。
19、System.currentTimeMillis:获取系统当前的时间,这个可以用来实现计算一个比较耗时的操作所用的时间。
20、System.arrayCopy:复制数组方法,因为java中其实没有多维数组的概念,例如二维数组其实只是一个一维的一维数组,而二维数组只有第二维放的才是数值,一维放的是对二维的一个引用,所以复制二维数组后,对复制品的改变会影响原来数组的值,解决办法是一维一维的复制。
21、Date:平时使用最多就是new Date(),但是必须清楚,Date有个构造方法是可以传递long类型的参数进去的,New Date(Date.getTime());
          日期轉換使用SimpleDateFormat,兩個方法 format和parse。
22、Date SimpleDateFormat clendar :date就是時間日期,SimpleDateFormat是可以实现日期字符串转换的,clendar唯一优势是获取两个日期时间的差(1.0jdk版本后建议使用的日期处理函数,适合于国际化)。
23、BigDecimal 处理大型整数。
24、对象克隆,克隆的对象要实现接口Cloneable。克隆以后对象的值是不影响原有对象的,Person p2 = (Person)p.clone();(必须强制转换,否则编译错误)。
25、Arrays类(方法多为static):binarysearch方法(必须先排好序),Arrays.equal(数组,数组),也是要先排序才能使用
        对象数组排序,要排序的对象必须实现Comparable接口,实现comparTo方法。所有对象的比较都必须这样操作。
    代码示例:
     public class Person implements Comparable<Person>{
        public int compareTo(Person person) {
        return person.age-this.age;
        }
     }
26、数据结构的集中遍历(复习)
27、comparator这个是挽救比较器,当一个类刚开始没有计划使用比较器,而后面要新加功能,并且不能修改原有类的情况下,这时候可以使用comparator来实现比较
        改类需要新添加一个比较类来实现。Arrays.sort(object ,obectComparator)

  28、正则表达式复习。
  29、为什么总要在类中写一个无参数的构造函数?
           方便在子类中调用,方便反射的时候使用。
30、java反射:明白类 Class,Method,Constuctor,Field
31、locale:获取本地的一些资源。国家语言等这些。有个方法getDefault获取本地当前的语言。
32、定时调度:timer,timetask.
33、批处理是多条语句一起执行,最原始的jdbc处理这种事物的方法是:在connection有个方法设置是否自动提交,setAutoCommit(false),
        然后使用try catch的方式,在catch中回滚操作。
34、java io:
        File类是唯一一个与文件本身操作有关的类
    一):在使用File定义路径的时候要注意分隔符,即\\,File有个方法获取父文件路径。File.getParentFile返回的是File,还有一个获取父的目录,返回是String。
    二):createNewFile 如果文件存在就返回false,如果不存在返回true,并创建。
    三):File.separator,分隔符。
    四):mkdir()和mkdirs();创建目录。
    五):一般情况下使用字节流,字符流是在处理中文的时候比较适合。
                Writer这个字符流方法 writer.writer(String),可以直接输入字符串。
            Reader与InputStream类相比,除了读取的参数里类型有差别,其他并无差别。建议使用InputStream,而输出如果是中文才适合用Writer。
            字符和字节的区别好比数据库中的clob和Blob区别。
            字符流使用了内存缓冲区而字节流没有,字符只有在使用flush()或者close()方法后,才会写入硬盘的文件夹。而字节流没有用到缓冲区。
            设计到中文的io使用字符流,其他情况使用字节。
35、io流包括 文件操作流和内存操作流:ByteArrayoutputStream和ByteArrayinputStream:内存操作流。之前的FileInputStream和FileoutputStream都是文件操作流,ByteArrayoutputStream的方法toByteArray()//返回字节数组。
文件流的终端是文件中(硬盘文件--》程序),而内存流的终端是内存中(内存--》程序 的过程)
36、幂等:多次操作跟一次操作含义相同,或者说返回结果相同,成为幂等操作。
37、Scanner 类最优替代bufferReader,使用scanner必须要设置分隔符scanner.useDelimiter("\n");//设置enter建为分隔,Scanner读取数据实现键盘输入和文件读取。
38、对象序列化:将在内存中保存的对象变为二进制数据流,这样意味着对象可以保存在文件中或者进行各种转换操作。如果一个对象需要被序列化,需要实现接口java.io.serializable,这个接口并没有任何的方法的定义,因为其描述的是一种能力,因为他是一个标识的接口。
         使用ObjectOutputStream 实现对象序列化输出。利用这个类输出到文件中后保存的是二进制的数据,一般是看不懂的,如果需要获取后看的懂需要用到ObjectInputStream,所以ObjectOutputStream输出的信息只能用ObjectInputStream获取。
     1:用户所关心的只有一个java.io.serialiazble
     2:ObjectOutputStream,ObjectInputStream很少会由永华自己操作。
     3:transient虽然可以保证属性不被序列化,但是很少出现和使用(private  transient int age:使用这个关键字后反序列化回来这个属性的值就是该类型的默认值,int默认则为0)
     39、java的类集框架
          Collection:单元素保存,最常用的子类:List和Set。list:最主要的方法是add和iterator方法
                         List:是一个存粹的数据输出的一个存储操作,而map是根据键值找到内容的一个集合操作。
                 list可以保存重复的数据,而set不行。
                 关系:Collection->List/Set->ArrayList/Vertor
                 想要在对象上使用List的remove方法,该对象必须要重写equals方法。
                 面试题:ArrayList和Vertor的区别
                               前者异步的,后者同步的
                       前者性能更好,后者性能不行
                 Set:也是collectin的子类,set有两个常用子类,HashSet(无序的),TreeSet(有序的)。带tree的就是有序的可以这样记忆,而hashSet等于有很多位置,有空位就做类似这样。
                  set特征是不可保存重复,并且是无序排列存放(hashset)。如果要有序存放使用treeset,如果对象使用treeset排序,必须实现comparable接口。
                  在java中只要牵扯到一组对象的排序操作永远都使用Comparable接口完成(其实只有以TreeXxx形式的集合才是这样判断的,HashSet的判断重复的方法是根据Object类对象中的两个方法完成的
                        1、取得对象的Hash码,public int hashCode();//Object里的方法
                        2、对象比较:public boolean  equals(Object o);//首先是获取对象的hasdcode是否相同,然后在对比对象值(跟人的身份证一样,判断身份证是否是本人的,需要通过身份证号码找到对应的身份证,然后对比名字)。
                  )。
                  Set中判断重复的原理就是排序的时候判断是否是相等。
                   Class Person implement Comparable{
                        public int comparto(Object o){//这样对比只是针对某个属性的大小比较
                            return this.age-o.age;
                        }
                        public int comparto(Object o){//这样对比则比较全面
                            if( this.age-o.age>0){
                                return 1;
                            }else if( this.age-o.age<0){
                                return -1;
                            }else{
                                this.name.comparTo(o.name);//这里对比年龄意外的其他属性。String也实现了Comparto接口,所以可以直接使用
                            }
                        }
                   }
                集合的4中输出方式:Iterator(主要),ListIterator,Enumeration,forEach
                主要使用Iterator方式  Iterator<String> iter =  List.iterator();
                while(iter.hasNext){
                    iter.next();//返回单个保存的对象
                }
                Iterator通过从前到后的输出,不能后到前使用List.listIterator()这个方法返回ListIterator实现由后向前的输出。而collection中没有提供方法返回listIterator,只有在list接口中才有,所以该方法只是针对List用的。从后到前的输出原理是有一个指针指着Iterator中,所以只有在先通过一次从前到后的输出,才能使用从后到前输出。
                Enumeration使用少,因为最初该方法是提供给vertor使用的,只有在vertor里才提供的实例化的方法,而在List中没有。vertor中提供了一个Elements的实例化方法返回Enumeration的实例。
                集合输出的时候使用remove()方法时要注意,正在输出的时候要使用iterator的remove方法,而不是使用集合的remove方法。不然会出现越界的异常。
                 
                       
      Map:两个重要的子类 hashMap  hashTable。前者异步 性能高,后者同步性能低,前者允许key和value都为空,后者都不允许为空,由于开发中不可避免的为null值,所以hashMap更多的被使用。hashMap和hashTable都是hash的形式所以都是无序的,要排序可以通过TreeMap,TreeMap比haspTable好点,TreeMap允许Value为空,但是不允许Key为空,因为排序是通过Key实现的(对Map的排序没什么意义,因为Map是来用做查找的,只有List这类集合才对排序有意义)。
    
    Map输出:Collection中放的是一个个的对象,而Map中放的是Key和Value,所以要实现Map的输出,Map中实现了一个内部类Map.Entry,等于是一个集合中保存了很多个Map.Entry的形式,而Map.Entry中有getKey和getValue方法。
    set = map.entrySet;
    Iterator<Map.Entry<K,V>> iter = set.iterator();

    Map的key如果使用自定义的类型,例如使用map.put(new person("xx"),"xs");在使用getKey(new person("xx"))此时返回的是null因为Map要对key进行查找所以key要实现Object对象的hashcode和equals方法,所以在person中要实现这两个方法,建议不要这么做,就是用key为String或者Integer类型,因为这两个系统的类型都实现了hashcode和equals方法和Comparable接口。
40、Collections是一个工具类,简化一些方法。 Collectins.addAll(list,"x","x","x");后面的添加是一个可变参数的,可以避免list的多次add操作,还有集合反转等。。
41、栈 Stack :Vertor的子类,是一个先进后出。两个方法 push和pop,入栈和出栈。
42、Propertis类:是专门负责属性信息操作的类,是hashtable的子类。只能是针对String类型的操作,而他的父类hashtable可以处理各种类型。主要是处理资源文件用的类。主要两个方法,setProperty()和getProperty(),getProperty("key","dafaultValue")//可以设置如果没有该Key时返回默认值。
        Propertis可以通过store存储资源文件中文存储后是uncode码,通过load方法加载资源文件读取值。

    list.forEach(System.out::println)//这样也能打印出数据,这是一种新型的方式,传入的是函数的引用。也可以传入一些数据处理的方法引用。
43、java中类的构造方法私有化后,只能在本类中使用new来创建对象,在他类中或者其他包中都无法使用new创建对象。这就是单例模式把构造方法设置为私有后的原因。
    //饿汉模式
    public class EagerSingleton {
     private static final EagerSingleton m_instance = new EagerSingleton();//饿汉模式,类创建的时候就加载,设置成final类型不可改变。
     private EagerSingleton() {// 私有构造方法,在本类外无法创建对象
     }
     public static EagerSingleton getInstance() {
         return m_instance;
     }
}
    //懒汉模式
    public class EagerSingleton {
     private static EagerSingleton m_instance = null;//懒汉模式,类创建的时候只是实例化对象并未创建对象。
     private EagerSingleton() {// 私有构造方法,在本类外无法创建对象
     }
     public static EagerSingleton getInstance() {
    if(m_instance==null){
    m_instance= new EagerSingleton();
    }
         return m_instance;
     }
}
44、集合类新增的的获取实例方法 list.stream();返回java.util.Stream对象,改对象有方法,stream.count(),这样可以返回集合数量,如果要去除重复可以先使用list.stream().distinct(),这样获取不重复的数据。这个一定要放在使用方法stream.count()之前,因为流只能使用一次,使用一次后就会关闭。
正确顺序:
Stream stream = list.stream().distinct();
stream.count();//此时对流进行操作,操作完成后流关闭,如果后面在使用stream.distinct或者steam.count都会出错。
45、MapReduce:map:处理数据  reduce:统计数据。
46、网络编程:通信协议还有很多 常用的:tcp udp http,tcp和udp 区别:前者是可靠性的通信连接,后者是不可靠的通信连接,常用语cs结构的通信系统。http则是使用bs结构的系统,因为http是公开的通信协议,所以安全性不是很高。而tcp和udp都是专属的通信协议,可靠性高。
 

展开阅读全文
打赏
0
7 收藏
分享
加载中
更多评论
打赏
0 评论
7 收藏
0
分享
返回顶部
顶部