面试常见问题
String、StringBuffer、StringBuilder
1.如果要操作少量的数据用 = String(不可变) 线程安全
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder(线程不安全)
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
运行时异常与普通异常
运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
Collection 和 Collections的区别
Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索排序线程安全化等操作 Collections.sort(ls)、
Collections.reverse(ls)
HashMap和Hashtable的区别
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键或者值(key),由于非线程安全,效率上可能高于Hashtable
下面列出了Array和ArrayList的不同点:
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
Overload和Override的区别Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding),如果方法名和参数都相同,那么证明市重写,那么返回值必须一致,不然会编译过不去。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)Overloaded的方法。是可以改变返回值的类型
sleep() 和 wait() 有什么区别?
wait和sleep区别: 分析这两个方法:从执行权和锁上来分析:
wait:可以指定时间也可以不指定时间。不指定时间,只能由对应的notify或者notifyAll来唤醒。是Object的类的方法。
sleep:必须指定时间,时间到自动从冻结状态转成运行状态(临时阻塞状态)。是Thread的方法。
wait:线程会释放执行权,而且线程会释放锁。
Sleep:线程会释放执行权,但不是不释放锁。
error和exception有什么区别?
Error类和Exception类都继承自Throwable类。
Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题。比如:内存资源不足等。对于这种错误,程序基本无能为力,除了退出运行外别无选择,它是由Java虚拟机抛出的。
Exception(违例)表示需要捕捉或者需要程序进行处理的异常,它处理的是因为程序设计的瑕疵而引起的问题或者在外的输入等引起的一般性问题,是程序必须处理的。
Java 中定义了两类异常:
1) Checked exception: 这类异常都是Exception的子类 。异常的向上抛出机制进行处理,假如子类可能产生A异常,那么在父类中也必须throws A异常。可能导致的问题:代码效率低,耦合度过高。
2) Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是非凡的,它们不能通过client code来试图解决,所以称为Unchecked exception 。
try-catch-finally-return执行顺序
1、不管是否有异常产生,finally块中代码都会执行;
2、当try和catch中有return语句时,finally块仍然会执行;
3、finally是在return后面的表达式运算后执行的,所以函数返回值是在finally执行前确定的。无论finally中的代码怎么样,返回的值都不会改变,仍然是之前return语句中保存的值;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
同步和异步有何异同,在什么情况下分别使用他们?举例说明
如果数据将在线程间共享例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率
单例
1 public class Singleton {
2 private static Singleton instance;
3 private Singleton (){}
4 public static synchronized Singleton getInstance() {
5 if (instance == null) {
6 instance = new Singleton();
7 }
8 return instance;
9 }
10 }
抽象类的特点:
1:抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。
2:抽象方法只定义方法声明,并不定义方法实现。
3:抽象类不可以被创建对象(实例化)。
4:只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。
抽象类的细节:
1:抽象类中是否有构造函数?有,用于给子类对象进行初始化。
2:抽象类中是否可以定义非抽象方法?
可以。其实,抽象类和一般类没有太大的区别,都是在描述事物,只不过抽象类在描述事物时,有些功能不具体。所以抽象类和一般类在定义上,都是需要定义属性和行为的。只不过,比一般类多了一个抽象函数。而且比一般类少了一个创建对象的部分。
3:抽象关键字abstract和哪些不可以共存?final , private , static
4:抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。
接 口:★★★★★
1:是用关键字interface定义的。
2:接口中包含的成员,最常见的有全局常量、抽象方法。
注意:接口中的成员都有固定的修饰符。
成员变量:public static final
成员方法:public abstract
interface Inter{
public static final int x = 3;
public abstract void show();
}
3:接口中有抽象方法,说明接口不可以实例化。接口的子类必须实现了接口中所有的抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。
4:类与类之间存在着继承关系,类与接口中间存在的是实现关系。
继承用extends ;实现用implements ;
5:接口和类不一样的地方,就是,接口可以被多实现,这就是多继承改良后的结果。java将多继承机制通过多实现来体现。
6:一个类在继承另一个类的同时,还可以实现多个接口。所以接口的出现避免了单继承的局限性。还可以将类进行功能的扩展。
7:其实java中是有多继承的。接口与接口之间存在着继承关系,接口可以多继承接口。
接口都用于设计上,设计上的特点:(可以理解主板上提供的接口)
1:接口是对外提供的规则。
2:接口是功能的扩展。
3:接口的出现降低了耦合性。
抽象类和接口的共性:都是不断向上抽取的结果。
抽象类和接口的区别:
1:抽象类只能被继承,而且只能单继承。
接口需要被实现,而且可以多实现。
2:抽象类中可以定义非抽象方法,子类可以直接继承使用。
接口中都有抽象方法,需要子类去实现。
3:抽象类使用的是 is a 关系。
接口使用的 like a 关系。
4:抽象类的成员修饰符可以自定义。
接口中的成员修饰符是固定的。全都是public的。
接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口抽象类可以实现(implements)接口,抽象类可继承实体类,但前提是实体类必须有明确的构造函数
说出数据连接池的工作机制是什么?
J2EE 服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙,如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定,当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接 。
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用,对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的
同步代码块和同步函数的区别?
同步代码块使用的锁可以是任意对象。
同步函数使用的锁是this,静态同步函数的锁是该类的字节码文件对象。
在一个类中只有一个同步,可以使用同步函数。如果有多同步,必须使用同步代码块,来确定不同的锁。所以同步代码块相对灵活一些。
静态代码块、构造代码块、构造函数同时存在时的执行顺序:静态代码块 à 构造代码块 à 构造函数;
HashMap和Hashtable有什么区别?
HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
HashMap允许键和值是null,而Hashtable不允许键或者值是null。
Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
一般认为Hashtable是一个遗留的类。
ArrayList和LinkedList有什么区别?
ArrayList和LinkedList都实现了List接口,他们有以下的不同点:
ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
Comparable和Comparator接口是干什么的?列出它们的区别。
Java提供了只包含一个compareTo()方法的Comparable接口。这个方法可以个给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。
Java提供了包含compare()和equals()两个方法的Comparator接口。compare()方法用来给两个输入参数排序,返回负数,0,正数表明第一个参数是小于,等于,大于第二个参数。equals()方法需要一个对象作为参数,它用来决定输入参数是否和comparator相等。只有当输入参数也是一个comparator并且输入参数和当前comparator的排序结果是相同的时候,这个方法才返回true。
Java 集合类总结
Collection<--List<--Vector 底层数组 线程安全
Collection<--List<--ArrayList 底层数组 适合查询多 增删少
Collection<--List<--LinkedList 底层链表 适合查询少 增删多
Collection<--Set<--HashSet HashSet的存储方式是把HashMap中的Key作为Set的对应存储项 HashSet的add(Object obj)return map.put(obj, PRESENT) == null;用的是hashcode排序 对象去重复用到hashcode和equals方法
Collection<--Set<--HashSet<--LinkedHashSet 一个链表 原生顺序
Collection<--Set<--SortedSet<--TreeSet 对象自身排序实现comparable 重写compareTo 构造器里可以加比较器实现comparator 重写compare 和equals方法,优先使用这个排序
Map<--SortedMap<--TreeMap 键可以自然顺序和比较器顺序
Map<--HashMap jdk1.2 键可以为null(一个)
map<--HashTable jdk1.0 线程安全 键不可以为null
map遍历 keyset entryset values
synchronizedXXX:转换成同步集合。
List l =Collections.synchronizedList(new ArrayList());
在 Java集合类框架里有两个类叫做Collections(注意,不是Collection!)和Arrays,这是JCF里面功能强大的工具,但初学者往往会忽视。按JCF文档的说法,这两个类提供了封装器实现(Wrapper Implementations)、数据结构算法和数组相关的应用。
想必大家不会忘记上面谈到的“折半查找”、“排序”等经典算法吧,Collections类提供了丰富的静态方法帮助我们轻松完成这些在数据结构课上烦人的工作: binarySearch sort reverse
对象可以遍历要实现iterable Iterable每次调用都会返回一个从头开始计数的迭代器。不用iterator因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。 如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。
使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。
ListIterator可以add 和set 两个都可以删除
java.io.File
* public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
* public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
File old = new File(source);重命名 sourse必须存在
File rname = new File(dest);dest必须不存在
System.out.println(old.renameTo(rname));
* public String getAbsolutePath():获取绝对路径
* public boolean isDirectory():判断是否是目录
* public boolean isFile():判断是否是文件
* public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
* public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
private static void getFiles(File file1) {
// 获取指定目录下的所有文件对象
File[] filearr = file1.listFiles();
for (File file : filearr) {
// 判断是否是文件
if (file.isFile() && file.getName().endsWith(".java")) {
// 输出
System.out.println(file.getName());
}else if( file.isDirectory() ){
getFiles(file);
}
}
}
public static int jiecheng(int a) {
if (a == 1) {
return 1;
} else {
return a * jiecheng(a - 1);
}
}
字符流 字节流
FileInputStream fis = new FileInputStream("小苹果.mp3");
// 创建输出流
FileOutputStream fos = new FileOutputStream("copy.mp3");
// 定义一个数组
byte[] arr = new byte[1024 * 1];
int len;
while( (len = fis.read(arr)) != -1 ){
fos.write(arr , 0 , len);
}
// 关闭流
fis.close();
fos.close();
// 输入流
FileInputStream fis = new FileInputStream("小苹果.mp3");
// 输出流
FileOutputStream fos = new FileOutputStream("copy2.mp3");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int len;
while( (len = bis.read()) != -1 ){
bos.write(len);
}
// 关闭流
bis.close();
bos.close();
// 创建输入流
FileReader fr = new FileReader("aaa.txt");
// 创建输出流
FileWriter fw = new FileWriter("bbb.txt");
// 带缓冲的字符流
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
int c;
while ((c = br.read()) != -1) {
bw.write(c);
}
// 关闭流
br.close();
bw.close();
FileReader fr = new FileReader("aaa.txt");
// 创建输出流
FileWriter fw = new FileWriter("bbb.txt");
int len;
char[] arr = new char[1024];
while( (len = fr.read(arr)) != -1 ){
fw.write(arr , 0 , len);
}
// 关闭流
fr.close();
fw.close();
// 文件COPY
// 文件输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
// 文件输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName()));
int len;
while( (len = bis.read()) != -1 ){
bos.write(len);
}
// 关闭流
bis.close();
bos.close();
// 创建LineNumberReader对象
LineNumberReader lnr = new LineNumberReader(new FileReader("aaa.txt"));
// 设置当前行号
lnr.setLineNumber(100);
String line;
while( (line = lnr.readLine()) != null ){
// 获取当前行号
System.out.println(lnr.getLineNumber() + ":" + line);
}
// 关闭流
lnr.close();
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf-8.txt"), "UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"), "GBK");
详情Wenjian.java
多线程
extends Thread 或者implements Runnable 重写里面的run方法,开启线程是.start不是run
Thread.NORM_PRIORITY优先级5 一共1-10;
t.join();当前线程合并t线程,就是t执行完了才可以往下执行
Thread.sleep(1000);当前线程休眠 固定写法,如果只有一个线程可以不写Thread
死锁