J2SE基础
- 九种基本数据类型的大小,以及他们的封装类。
Java基本类型共有八种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。数值类型又可以分为整数类型byte、short、int、long和浮点数类型float、double。JAVA中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变。实际上,JAVA中还存在另外一种基本类型void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。8 中类型表示范围如下:
byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
boolean:只有true和false两个取值。
char:16位,存储Unicode码,用单引号赋值。
封装类分别为Boolean, Byte, Character, Short, Integer, Long, Float, Double, Void。
既然提供了基本类型,为什么还要使用封装类呢
比如,如果想使用List来保存数值,由于List中只能添加对象,另外,有些情况下,我们也会编写诸如func(Object o)的这种方法
2.Switch能否用string做参数?
可以,从JDK1.7开始可以。
switch(expr)中,expr可以是byte、short、char、int。从1.5版开始,Java中引入了枚举类型(enum),expr也可以是枚举,从JDK 1.7版开始,还可以是字符串(String)。长整型(long)是不可以的。
- equals与==的区别。
==比较的是值(基本数据类型)或内存地址(复合数据类型); JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,Object的equals方法也是用双等号(==)进行比较的。但如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
*注意new()操作会开辟新的内存地址。 - Object有哪些公用方法?
Object的公用方法主要有clone(),equals(),hashCode(),getClass(),wait(),notify(),notifyAll(),toString().
详见:http://blog.csdn.net/donghaol/article/details/49252383
- Java的四种引用,强弱软虚,用到的场景。
四种引用级别由高到低依次为:强引用、软引用、弱引用和虚引用。
强引用:是JVM的默认实现,即使内存不足垃圾回收器也不会回收;
弱引用(WeakReference):当所引用的对象在 JVM 内不再有强引用时, GC 后weak reference 将会被自动回收;
软引用(SoftReference):SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证) ;
虚引用:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
使用场景:软引(或弱引用)可以和一个引用队列(ReferenceQueue)联合使用,如果软引用(或弱引用)所引用的对象被垃圾回收,Java虚拟机就会把这个软引用(或弱引用)加入到与之关联的引用队列中。虚引用主要用来跟踪对象被垃圾回收的活动。
代码参考:http://kinkding.iteye.com/blog/403490
- Hashcode的作用。
hashcode方法返回该对象的哈希码值,用于查找使用。
http://blog.csdn.net/fenglibing/article/details/8905007
ArrayList、LinkedList、Vector的区别。
ArrayList,Vector采用数组实现存储,允许直接按序号索引,但插入数据涉及到数组元素移动,因此索引快插入慢。ArrayList是非安全线程,Vector是安全线程,性能通常较ArrayList差。
LinkedList采用双向链表实现数据存储,索引需要向前或向后遍历,但插入只需要记录本项的前后项,因此索引慢但插入快。String、StringBuffer与StringBuilder的区别。
String长度不可变,StringBuffer和StringBuilder长度可变。StringBuilder在单线程环境下使用,没有synchronized修饰,更高效。Map、Set、List、Queue、Stack的特点与用法。
Map(映射) 键值对组成的集合
Set 无序集合,元素不可重复
List 有序集合,元素可以重复
Queue 队列,先进先出
Stack 栈,后进先出
Set集合类似于一个罐子,"丢进"Set集合里的多个对象之间没有明显的顺序。
List集合代表元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。
Stack是Vector提供的一个子类,用于模拟"栈"这种数据结构(LIFO后进先出)
Queue用于模拟"队列"这种数据结构(先进先出 FIFO)。
Map用于保存具有"映射关系"的数据,因此Map集合里保存着两组值
HashMap和HashTable的区别。
Hashtable是基于陈旧的Dictionary类的,HashMap是Map接口的一个实现 Hashtable的方法是线程同步的,而HashMap的方法不是。 只有HashMap可以让你将空值作为一个表的条目的key或valueHashMap和ConcurrentHashMap的区别,HashMap的底层源码。
TreeMap、HashMap、LindedHashMap的区别。
Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。
LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序
TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。Collection类,Collection包结构,与Collections的区别。
Collection是集类,包含List有序列表,Set无序集合以及Map双列集合
Collection是集合类的上级接口,子接口主要有Set 和List、Map。
Collections是针对集合类的一个帮助类,提供了操作集合的工具方法:一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。try catch finally,try里有return,finally还执行么?
a.不管有木有出现异常,finally块中代码都会执行 b.当try和catch中有return时,finally仍然会执行
c.finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的
d.finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。
java.lang.OutOfMemoryError: Java heap space ------>java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。
java.lang.OutOfMemoryError: PermGen space ------>java永久代溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。
java.lang.StackOverflowError ------> 不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。Java面向对象的三个特征与含义。
封装性:它是将类的一些敏感信息隐藏在类的类部,不让外界直接访问到
继承性:子类通过一种方式来接受父类所有的公有的,受保护的成员变量和成员方法
多态性:程序在运行的过程中,同一种类型在不同的条件下表现不同的结果Override和Overload的含义区别。
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写
Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。Interface与abstract类的区别。
接口可以多重继承,抽象类不可以
接口定义方法,不给实现;而抽象类可以实现部分方法
接口中基本数据类型的数据成员,都默认为static和final,抽象类则不是Static class 与non static class的区别。
内部静态类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。 非静态内部类能够访问外部类的静态和非静态成员。静态类不能访问外部类的非静态成员。他只能访问外部类的静态成员。一个非静态内部类不能脱离外部类实体被创建,一个非静态内部类可以访问外部类的数据和方法,因为他就在外部类里面。java多态的实现原理。
ⅰ.设计时多态:方法【重载】实现的多态
ⅱ.运行时多态:方法【重写】实现的多态实现多线程的两种方法:Thread与Runable。
使用Runnable接口
实际工作中,几乎所有的多线程应用都用实现Runnable这种方式。 Runnable适合多个相同程序代码的线程去处理同一资源的情况。把虚拟CPU(线程)同程序的代码、数据有效的分离,较好的体现了面向对象的设计思想。
避免由于Java的单继承特性带来的局限性。也就是如果新建的类要继承其他类的话,因为JAVA中不支持多继承,就只能实现java.lang.Runnable接口。
有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。
继承Thread类
不能再继承他类了。
编写简单,可以直接操纵线程,无需使用Thread.currentThread()。线程同步的方法:sychronized、lock、reentrantLock等。
sychronized是java中最基本同步互斥的手段,可以修饰代码块,方法,类,在修饰代码块的时候需要一个reference对象作为锁的对象,在修饰方法的时候默认是当前对象作为锁的对象,在修饰类时候默认是当前类的Class对象作为锁的对象. ReentrantLock除了synchronized的功能,多了三个高级功能.
等待可中断,在持有锁的线程长时间不释放锁的时候,等待的线程可以选择放弃等待 公平锁, 按照申请锁的顺序来一次获得锁称为公平锁.synchronized的是非公平锁,ReentrantLock可以通过构造函数实现公平锁
绑定多个Condition. 通过多次newCondition可以获得多个Condition对象,可以简单的实现比较复杂的线程同步的功能.通过await(),signal();锁的等级:方法锁、对象锁、类锁。
方法锁,synchronized标记的方法
对象锁,在方法上加了synchronized的锁,或者synchronized(this)的代码段 类锁,在代码中的方法上加了static和synchronized的锁,因为在静态方法中加同步锁会锁住整个类写出生产者消费者模式。
http://blog.chinaunix.net/uid-27795088-id-3977915.html
ThreadLocal的设计理念与作用。
ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。ThreadPool用法与优势。
线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。
FixedThreadPool(int nThreads): 创建一个可重用的固定线程数的线程池,如果池中所有的nThreads个线程都处于活动状态时提交任务(任务通常是Runnable或Callable对象), 任务将在队列中等待, 直到池中出现可用线程
CachedThreadPool(): 调用此方法创建的线程池可根据需要自动调整池中线程的数量,执行任务时将重用存在先前创建的线程(如果池中存在可用线程的话). 如果池中没有可用线程, 将创建一个新的线程, 并将其添加到池中. 池中的线程超过60秒未被使用就会被销毁, 因此长时间保持空闲的
SingleThreadExecutor(): 创建一个单线程的Executor. 这个Executor保证按照任务提交的顺序依次执行任务.
ScheduledThreadPool(int corePoolSize): 创建一个可重用的固定线程数的线程池. ScheduledExecutorService是ExecutorService的子接口, 调用ScheduledExecutorService的相关方法, 可以延迟或定期执行任务.
以上静态方法均使用默认的ThreadFactory(即Executors.defaultThreadFactory()方法的返回值)创建线程, 如果想要指定ThreadFactory, 可调用他们的重载方法.通过指定ThreadFactory, 可以定制新建线程的名称, 线程组, 优先级, 守护线程状态等. 如果Executors提供的创建线程池的方法无法满足要求, 可以使用ThreadPoolExecutor类创建线程池.Concurrent包里的其他东西:ArrayBlockingQueue、CountDownLatch等等。
wait()和sleep()的区别。
sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。 wait指线程处于进入等待状态,形象地说明为“等待使用CPU”,此时线程不占用任何资源,不增加时间限制foreach与正常for循环效率对比。
针对列表的 foreach的效率是最低, 耗时是普通for循环的2倍以上。个人理解它的实现应该和iterator相似Java IO与NIO。
Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。反射的作用于原理。
JAVA反射(放射)机制:Reflection,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
用途:Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。泛型常用特点,List
能否转为List 解析XML的几种方式的原理与特点:DOM、SAX、PULL。
Dom解析 在内存中创建一个DOM树,该结构通常需要加载整个文档然后才能做工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的,树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改能随机访问文件内容,也可以修改原文件内容
SAX解析 SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点线性解析,不能随机访问,也无法修改原文件
http://blog.csdn.net/kukulongzai_123/article/details/7058008
- Java与C++对比。
http://www.weixueyuan.net/view/5944.html
- Java1.7与1.8新特性。
如1.7 Switch中加入对String的支持,1.8中加入lambda表达式
http://blog.csdn.net/ludx212/article/details/17281729
- 设计模式:单例、工厂、适配器、责任链、观察者等等。
http://blog.csdn.net/runming56/article/details/36628493
- JNI的使用。
JNI作为java和操作系统间的一个直接接口,可以通过JNI使得java直接调用操作系统的资源。目前JNI只能通过c/C++实现,因为jni只是对操作系统资源调用的一个桥接过程。所以理论上在windows下只要是dll文件均可以被调用。 jni一般有以下一些应用场景
1.高性能 ,在一些情况下因为处理运算量非常大,为了获取高性能,直接使用java是不能胜任的,如:一些图形的处理
2.调用一些硬件的驱动或者一些软件的驱动,比如调用一些外部系统接口的驱动,如:读卡器的驱动,OCI驱动
3.需要使用大内存,远远超过jvm所能分配的内存,如:进程内Cache
4.调用C或者操作系统提供的服务,如:java调用搜索服务,其中搜索是由C/C++实现的,不过这个一般可以设计成更加通用的方式,比如soa的方式
所有这些场景的前提是牺牲了java代码的可移植性,不同的os,甚至版本都需要写不同版本的native实现