1,面向对象的三大特征?
答:封装:封装就是隐藏了类或方法的具体实现细节。便于更新与改动,也提高了代码的安全性。
继承:提高了代码的复用性,.让类与类之间产生了关系,给第三个特征多肽提供了前提。继承又分为多继承和单继承。单继承就是子类继承父类。多继承就是多层继承,如A继承B,B继承C。Java不支持一个子类继承多个父类。
多态:简单点说:“一个接口,多种实现”。允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)
抽象(有时候也会加上此特征):抽象类的意义?
-
1. 为其他子类提供一个公共的类型
-
2. 封装子类中重复定义的内容
-
3.定义抽象方法,子类虽然有不同的实现,但是定义时一致的
抽象类格式:
修饰符 abstract 类名 {
类体
}
抽象方法格式:
修饰符 abstract 返回值类型 方法名();
抽象类是不能实例化的:要通过具体的子类来实例化,里面的抽象方法也要重写,如果子类也是抽象的不是必须重写父类抽象方法,否则必须重写(属于多态的一种)
抽象类不一定有抽象方法,但是有抽象方法一定是抽象类
实例:
package for_apro;
import java.util.*;
//抽象类的声明
abstract class Animal {
String type;
String name;
int age;
int weight;
void eat() {
System.out.println("动物爱吃饭");
}
//抽象方法在抽象类中只能声明,不能具体实现
abstract void breath();
void sleep() {
System.out.println("动物在睡觉");
}
}
//由子类去继承父类抽象类
class tiger extends Animal{
@Override
//在此处实现抽象方法
void breath() {
// TODO Auto-generated method stub
System.out.println("老虎在呼吸");
}
}
public class first_for {
public static void main(String [] args){
// 错误,程序会报错
//报错原因:抽象类不能进行实例化操作
//Animal Tiger = new Animal();
//只能用子类进行实例化
Animal Tiger = new tiger();
Tiger.breath();
}
}
执行结果:老虎在呼吸
2,代码中如何实现多态?
答:实现多态主要有以下三种方式:1. 接口实现 2. 继承父类重写方法 3. 同一类中进行方法重载
3 ,3*0.1==0.3
返回值是什么
答 :false,因为有些浮点数不能完全精确的表示出来。
答:+=操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而a=a+b则不会自动进行类型转换。
5,switch中能否使用string做参数
答:在idk 1.7之前,switch只能支持byte, short, char, int或者其对应的封装类以及Enum类型。从idk 1.7之后switch开始支持String。
答:可以用在byte上,但是不能用在long上。
7,String s1=”ab”, String s2=”a”+”b”, String s3=”a”, String s4=”b”, s5=s3+s4请问s5==s2返回什么?
答:返回false。在编译过程中,编译器会将s2直接优化为”ab”,会将其放置在常量池当中,s5则是被创建在堆区,相当于s5=new String(“ab”);
8,你对String对象的intern()熟悉么?
答:intern()方法会首先从常量池中查找是否存在该常量值,如果常量池中不存在则现在常量池中创建,如果已经存在则直接返回。比如
String s1=”aa”;
String s2=s1.intern();
System.out.print(s1==s2);//返回true
9,final, finalize和finally的不同之处
答:final 是一个修饰符,可以修饰变量、方法和类。如果 final 修饰变量,意味着该变量的值在初始化后不能被改变。finalize 方法是在对象被回收之前调用的方法,给对象自己最后一个复活的机会,但是什么时候调用 finalize 没有保证。finally 是一个关键字,与 try 和 catch 一起用于异常的处理。finally 块一定会被执行,无论在 try 块中是否有发生异常。
10,clone()是哪个类的方法?
答:java.lang.Cloneable 是一个标示性接口,不包含任何方法,clone 方法在 object 类中定义。并且需要知道 clone() 方法是一个本地方法,这意味着它是由 c 或 c++ 或 其他本地语言实现的。
11,static都有哪些用法?
答:几乎所有的人都知道static关键字这两个基本的用法:静态变量和静态方法。也就是被static所修饰的变量/方法都属于类的静态资源,类实例所共享。
除了静态变量和静态方法之外,static也用于静态块,多用于初始化操作:
public calss PreCache{
static{
//执行相关操作
}
}
此外static也多用于修饰内部类,此时称之为静态内部类。
最后一种用法就是静态导包,即import static
.import static是在JDK 1.5之后引入的新特性,可以用来指定导入某个类中的静态资源,并且不需要使用类名。资源名,可以直接使用资源名,比如:
import static java.lang.Math.*;
public class Test{
public static void main(String[] args){
//System.out.println(Math.sin(20));传统做法
System.out.println(sin(20));
}
}
12,64位的JVM当中,int的长度是多少?
答:Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位。意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类型的长度是相同的。
13,int和Integer的区别
答:Integer是int的包装类型,在拆箱和装箱中,二者自动转换。int是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象。,
14,int 和Integer谁占用的内存更多?
答:Integer 对象会占用更多的内存。Integer是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少。
15,String, StringBuffer和StringBuilder区别
答:String是字符串常量,final修饰:StringBuffer字符串变量(线程安全);StringBuilder 字符串变量(线程不安全)。
16,创建两种线程的方式?他们有什么区别?
答:通过实现java.lang.Runnable或者通过扩展java.lang.Thread类。相比扩展Thread,实现Runnable接口可能更优.原因有二:
-
Java不支持多继承。因此扩展Thread类就代表这个子类不能扩展其他类。而实现Runnable接口的类还可能扩展另一个类。
-
类可能只要求可执行即可,因此继承整个Thread类的开销过大。
17,Thread类中的start()和run()方法有什么区别?
答:start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。
18,一个抽象类如果没有抽象方法。可不可以定义为抽象类?有何意义?
答:可以。这么做的目的是不让其他类创建奔雷对象,交由子类完成。
19,abstract不能和那些关键字共存?
答:1.不能和static共存。static修饰的方法可以通过类名·调用,而abstract修饰的方法没有方法体。这么调用没有意义。
2.final也不行。final表示私有的。不能被继承而abstract强制子类实现。
3.private也不行。被private修饰的是不让别人看到。而abstract强制子类看到并重写。
20,接口的定义?
答:狭义上讲就是Java中的interface。广义上讲对外提供规则的都是接口。
21,接口的特点?
答:用关键字interface表示。接口不能实例化。接口的子类可以是抽象类,也可以是具体类(需要重写接口中的方法)。接口的实现用implement来实现(class 类名 implement 接口名{})。接口没有构造方法,方法都是抽象方法。成员变量只能是常量并且是静态的公共的:public static final。(备注:一个类不继承任何类,默认是继承object类)
22,类与接口的关系?
答:类与类的关系:继承的关系,只能单继承,但是可以多层继承。
类与接口的关系:实现的关系,可以多实现也可以单实现。(并且可以在继承一个类的同事实现多个接口)。
接口与接口的关系:继承的关系,可以多继承也可以单继承。
23,如何正确的使用wait()?使用if还是while?
答:wait() 方法应该在循环调用,因为当线程获取到 CPU 开始执行的时候,其他条件可能还没有满足,所以在处理前,循环检测条件是否满足会更好。下面是一段标准的使用 wait 和 notify 方法的代码:
synchronized (obj) {
while (condition does not hold)
obj.wait(); // (Releases lock, and reacquires on wakeup)
... // Perform action appropriate to condition
}
24,什么是线程局部变量ThreadLocal
答:线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java提供ThreadLocal类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。
25,ThreadLoal的作用是什么?
答:简单说ThreadLocal就是一种以空间换时间的做法在每个Thread里面维护了一个ThreadLocal.ThreadLocalMap把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。
答:(1)通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最重要的作用。
(2)解耦,这是生产者消费者模型附带的作用,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展而不需要收到相互的制约。
27,如果你提交任务时,线程池队列已满,这时会发生什么
答:如果你使用的LinkedBlockingQueue,也就是无界队列的话,没关系,继续添加任务到阻塞队列中等待执行,因为LinkedBlockingQueue可以近乎认为是一个无穷大的队列,可以无限存放任务;如果你使用的是有界队列比方说ArrayBlockingQueue的话,任务首先会被添加到ArrayBlockingQueue中,ArrayBlockingQueue满了,则会使用拒绝策略RejectedExecutionHandler处理满了的任务,默认是AbortPolicy。
答:避免频繁地创建和销毁线程,达到线程对象的重用。另外,使用线程池还可以根据项目灵活地控制并发的数目。
29,java中用到的线程调度算法是什么
答:抢占式。一个线程用完CPU之后,操作系统会根据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程执行。
答:由于Java采用抢占式的线程调度算法,因此可能会出现某条线程常常获取到CPU控制权的情况,为了让某些优先级比较低的线程也能获取到CPU控制权,可以使用Thread.sleep(0)手动触发一次操作系统分配时间片的操作,这也是平衡CPU控制权的一种操作。
31,ArrayList和HashMap默认大小?
答:在 Java 7 中,ArrayList 的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂)。这就是 Java 7 中 ArrayList 和 HashMap 类的代码片段。
private static final int DEFAULT_CAPACITY = 10;
//from HashMap.java JDK 7
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
32,Comparator和Comparable的区别?
答:Comparable 接口用于定义对象的自然顺序,而 comparator 通常用于定义用户定制的顺序。Comparable 总是只有一个,但是可以有多个 comparator 来定义对象的顺序。
答:你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有顺序的的集合,如 list,然后通过 Collections.sort() 来排序。
34,如何打印数组内容
答:你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法来打印数组。由于数组没有实现 toString() 方法,所以如果将数组传递给 System.out.println() 方法,将无法打印出数组的内容,但是 Arrays.toString() 可以打印每个元素。
35,LinkedList的是单向链表还是双向?
答:双向循环列表,具体实现自行查阅源码。
答:采用红黑树实现,具体实现自行查阅源码。
37,遍历ArrayList时如何正确移除一个元素
答:该问题的关键在于面试者使用的是 ArrayList 的 remove() 还是 Iterator 的 remove()方法。这有一段示例代码,是使用正确的方式来实现在遍历的过程中移除元素,而不会出现 ConcurrentModificationException 异常的示例代码。
38,什么是ArrayMap?它和HashMap有什么区别?
答:ArrayMap是Android SDK中提供的,非Android开发者可以略过。
ArrayMap是用两个数组来模拟map,更少的内存占用空间,更高的效率。
具体参考这篇文章:ArrayMap VS HashMap:http://lvable.com/?p=217%5D
39,HashMap的实现原理
答:1. HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
2. HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
当我们往Hashmap中put元素时,首先根据key的hashcode重新计算hash值,根绝hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放入链尾.如果数组中该位置没有元素,就直接将该元素放到数组的该位置上.
需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)