Java基础

来源:互联网 发布:mac win8 无声音 编辑:程序博客网 时间:2024/06/15 05:48

1、Arrays.sort实现原理和Collection实现原理 
http://blog.sina.com.cn/s/blog_8e6f1b330101h7fa.html


2、foreach和while的区别 
在while循环里,内存读入一行输入,把它存入某个变量并且执行循环主体。然后,它再回头去找其他的输入行。
       在foreach循环中,foreach需要逐行处理列表的内容,在循环开始执行之前,它必须先将输入全部读进来。
       当输入大容量的文件时,使用foreach会占用大量的内存。两者的差异会十分明显。因此,最好的做法,通常是尽量使用while循环的简写,让它每次处理一行。


3、线程池
简介: Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService  。new 、runable、runing、wait、destroy五个过程。
使用场景:① 单个任务处理时间段   ② 处理的任务量大
好处:① 减少线程创建和消亡的开销,提高性能  ② 可以控制最大的线程量,避免过多线程间的资源竞争,避免堵塞  ③ 提供定时执行、定期执行、单线程、并发数控制等功能。
四种线程池:
①  newCachedThreadPool:创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源 
② newFixedThreadPool:创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。 

③ newScheduledThreadPool:创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

④ newSingleThreadExecutor:创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。

线程池调优的着手点:
① 最大线程数  :取决于负载特性以及底层硬件。特别是,最优线程数还与每个任务阻塞的频率有关。
② 最小线程数  :
③ 线程池任务大小:避免线程池的任务数量变得非常大,导致不均衡。如果达到了队列的限制,再添加任务就会失败。 
④ 设置ThreadPoolExecutor的大小
SynchronousQueue:若达到线程最大数,新的任务则被拒绝
无界队列:最大线程池的大小限制被忽略。如LinkedBlockingQueue
有界队列:如果队列已满,而又有新任务进来,此时才会启动一个新线程,这里不会因为队列已满而拒接该任务,相反会启动一个新线程。如ArrayBlockingQueue


4、HashMap并发问题
原因:多线程的访问,导致map在reHash的时候出现死循环
解决方法:① HashTable替换Hashmap:Hashtable容器使用synchronized来保证线程安全,在线程竞争激烈的情况下Hashtable的效率非常低下。
② Collections.synchronizedMap将HashMap包装  
③ ConcurrentHashMap替换HashMap:ConcurrentHashMap使用分段锁技术,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问。ConcurrentHashMap中的key和value值都不能为null;ConcurrentHashMap是线程安全的类并不能保证使用了ConcurrentHashMap的操作都是线程安全的。


5、LinkedHashMap
简介:LinkeHashMap是HashMap的子类,与HashMap有着同样的存储结构,但它加入了一个双向链表的头结点,将所有put到LinkedHashmap的节点一一串成了一个双向循环链表,因此它保留了节点插入的顺序,可以使节点的输出顺序与输入顺序相同;LinkedHashMap可以用来实现LRU算法;LinkedHashMap同样是非线程安全的,只在单线程环境下使用。



6、反射
定义:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法.这种动态获取信息,以及动态调用对象方法的功能叫java语言的反射机制
原理:
类加载器:java的类加载器也有些门道。它分为BootStrapClassLoader(引导类加载器),ExtensionsClassLoader (扩展类加载器),AppClassLoader(或SystemClass Loader),当然少不了CustomClassLoader(用户自定义类加载器)。其加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。
创建实例的三种方式:① Class class1 = Foo.class  ② Foo foo1 = new Foo();Class class2 = foo1.getClass()  ③ Class class3 = Class.forName("com.test.Foo")   【最后将获得的Class调用newInstance()方法,实现实例化】



7、深拷贝、浅拷贝和Cloneable接口
我们常见的Object a=new Object();Object b;b=a;这种形式的代码复制的是引用,即对象在内存中的地址,a和b对象仍然指向了同一个对象
在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。浅拷贝和深拷贝的主要区别在于是否支持引用类型的成员变量的复制。
浅拷贝:如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。
深拷贝:无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。实现深克隆,可以通过覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现
实现拷贝的两种方式:① 实现Cloneable接口并重写Object类中的clone()方法  ② 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
将对象中的引用类型也拷贝一份就由浅拷贝变为了深拷贝。

8、Java NIO
传统的IO又称BIO,即阻塞式IO,NIO就是非阻塞IO了。还有一种AIO就是异步IO。


9、String、StringBuffer、StringBuilder
1、可变与不可变:均是用字符数组保存字符串,String的数组是final修饰,因此是不可变的,另外两个是可变的
2、是否线程安全:String 中的对象时不可变的,线程是安全的。StringBuffer对方法加了同步锁,是线程安全的。
StringBuilder没有对方法加锁,是线程不安全的。
3、StringBuilder>StringBuffer,因为锁的增加会消耗性能。
4、String中的“+”过程,是创建StringBuffer或StringBuilder,调用append实现的,因此String性能没有另
外两个好


10、hashCode
hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值,hashCode是所有java对象的固有方法,如果不重载的话,返回
的实际上是该对象在jvm的堆上的内存地址,而不同对象的内存地址肯定不同,所以这个hashCode也就肯定不同了。如果重载了的话,由于采用的算
法的问题,有可能导致两个不同对象的hashCode相同。在重写父类的equals方法时,也重写hashcode方法,使相等的两个对象获取的HashCode也
相等,这样当此对象做Map类中的Key时,两个equals为true的对象其获取的value都是同一个,比较符合实际。
HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。 判断HashSet和HastMap中的两个对象相同或不同,先判断hashcode
是否相等,再判断是否equals。
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。 
2、如果两个对象不equals,他们的hashcode有可能相等。 
3、如果两个对象hashcode相等,他们不一定equals。 
4、如果两个对象hashcode不相等,他们一定不equals。


11、HashMap、LinkedHashMap、TreeMap
HashMap:不保证数据有序,哈希表结构。
LinkedHashMap:保证数据可以保持插入顺序,允许使用null值和null键,表中元素的顺序可以分为:按插入顺序的链表,和按访问顺序
(调用get方法)的链表,默认是按插入顺序排序,如果指定按访问顺序排序,那么调用get方法后,会将这次访问的元素移至链表尾部,不断访问可以
形成按访问顺序排序的链表。底层使用哈希表与双向链表来保存所有元素。
TreeMap:而如果我们希望Map可以保持key的大小顺序的时候,需要利用TreeMap。TreeMap的底层实现是红黑树,红黑树是一棵平衡排序二叉树,普通的排序二叉树可能会出现失衡的情况,所以下一步就是要进行调整。TreeMap是如何保证其迭代输出是有序的呢?其实从宏观上来讲,就相当于树的中序遍历(LDR)。

原创粉丝点击