JAVA-收集-持续更新...

2018-01-31  本文已影响10人  FDoubleman

1、阐述下对象的自动装箱和拆箱 2

基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。
自动装箱是java编译器在java原生类型和对应的对象包装类型上做的自动转换。

 自动装箱:
        Integer i = 1;
 其实编译器为你自动实现了:
        Integer i = Integer.valueOf(1);
 自动拆箱:
        Integer i = 1;
        int a = i;
 实际上执行了:
        int a = i.intValue(); 

2、switch支持的数据类型

包括byte、short、char、int 和 enum ,及包装类型Character、Byte、Short和Integer,
    java7后又加入了对String的支持。
    阐述下支持String的原理:
    使用字符串的hash值作为表达式的值,而由于相同哈希值的情况下仍存在冲突的可能,
    所有在case语句块时仍需要通过equals方法来判断相等。

3、equals、==、hashCode:

== : 比较引用地址的相等或基本数据类型/枚举类型的相等
  Equal:对象的值情况的相等
  hashCode:返回对象的存储地址
  关系:
     两对象比较:euqals返回true时,hashCode也相等。
              hashCode相等时,equals返回不一定相等。

     instanceof: 判断对象类型5是否相等,当父、子类判断时存在单向情况。                     
     对象判断equals方法:
             1、 == 判断引用地址  2、instanceof 判断类型  3、属性匹配
             4、自反性、对称性、传递性、一致性  5、重写hashcode

甲学生的年龄 :16 ,学号: 12345
乙学生的年龄 :16, 学号: 54321
这样甲和乙的hashcode 重写方式一样的 1 + 2+ 3+ 4+ 5 +(16*1 )= 31
但是 12345 不equals 54321

4、创建对象:

主要有以下四种对象创建方式:
1、new  2、反射  (这俩要调用构造函数)  3、clone  4、 反序列化
其中:
克隆:通过实现Cloneable、Serializable(序列化、反序列化实现)来实现对象的克隆

反射:
   该方式的表现主要有:
   1、运行时取得字段与方法和修改(包括常量) 
   2、创建对象
   原理:jvm通过字节码文件生成相应的对象或获取其信息
   优缺点:增加了程序设计的灵活性;性能消耗较大

5、简述下多态,Java多态的实现原理?动态绑定的理解?:

 重载:同一类中,同名函数不同的参数形式,基于对象实际的类型来选择所调用的方法,达到动态绑定的目的。
 重写:父类、子类中,同名同参方法,重新定义方法实现。
 区别: 前者编译时多态性、后者运行时多态性
 (静态方法除外,多态是针对实例方法) 

将一个方法调用同一个方法主体关联起来被称作绑定,JAVA中分为 前期绑定和后期绑定(动态绑定或运行时绑定)
前期绑定: 在程序执行之前进行绑定(由编译器和连接程序实现)叫做前期绑定,因为在编译阶段被调用方法的直接地址就已经存储在方法所属类的常量池中了,程序执行时直接调用。
后期绑定:含义就是在程序运行时根据对象的类型进行绑定,想实现后期绑定,就必须具有某种机制,以便在运行时能判断对象的类型,从而找到对应的方法,简言之就是必须在对象中安置某种“类型信”,JAVA中除了static方法、final方法(private方法属于)之外,其他的方法都是后期绑定。

Java技术----多态的实现原理

6、简述下抽象和接口的区别:

 抽象类:区别与普通的类,不能直接被实例化,可以有构造函数,并且子类可不实现其抽象方法。
 接口:修饰符为public、变量为final,没有实际的方法,可实现多继承。

7、简述public、protected、private、default 的区别:2

也叫 作用域修饰词

public 作用范围:当前类、同一个包、子类、其他包;
protected 作用范围:当前类、同一个包、子类;
default 作用范围:当前类、同一个包;
private 作用范围:当前类;

8、简述下创建线程的方式:

 1、直接通过new thread 的方式;
 2、实现runnable接口;
 3、通过接口callable  (callable能拿到返回值和抛出异常);
 4、通过线程池来生成线程;          

9、sleep、wait、yield、notify、notifyall:

 sleep和yield区别:
           sleep 给予线程的运行机会 不考虑优先级,then 阻塞  
           yield:给优先级高的线程执行,然后进入就绪状态
   wait和sleep区别:
           wait:释放对象锁 object的方法   —> notify
          sleep:不释放锁  thread的方法
      两者都可通过interrupted 打断暂   
   notify和notifyall区别:
         notify:唤醒的某一线程去得到锁
         notifyall:唤醒所有等待线程去竞争锁
   wait/notify/notifyall : 它们都需在同步块中调用 ,均可释放对象锁;
     wait:立即释放控制权 然阻塞(需notify)     
     notify:执行完再释放

10、synchronized 、Lock区别:

synchronized:关键字   
Lock:对象   可控制获取锁的时间与获取锁的信息
手动释放锁、让线程响应中断、可知获得锁与否 
多线程竞争较激烈时,Lock较优

上下文切换:cpu控制权由一个正在运行的线程切换到另一个就绪状态的线程

11、异常处理:

Error、Exception:
父类:Throwable :含异常出现时的log
Error:系统级错误,如OOM
Exception:
          需程序捕捉和处理的程序设计性错误
          被检查异常(throw、try catch)、运行时异常

Throw:方法中抛出异常
Throws:申明异常
try catch finally:
    try中有return 会记录返回值 待finally执行完  返回值不变
    如finally中有return 则值会变
    finally:释放外部资源 

12、简述下JVM内存模型: 2

JVM的内存模型主要可以分为线程共享区和线程私有区,
线程共享区:java堆(放对象和数组、GC)、方法区(类信息、常量、静态变量等,永久代);
线程私有区:程序计数器(指示代码执行、无oom)、Java虚拟机栈(java方法调用)、native方法栈;
而每个线程都有自己的栈内存, 堆是共享的,线程会缓存对象到栈中使用,而volatile则可要求线程从内存中读取

13、简述下GC机制:2

判断对象内存是否该被回收:JVM根据可达性分析(引用计数会出现互相引用的情况)
java内存回收算法大概可分为:
        分年代回收:年轻代(创建)、老年代(呆的久)、永久代
    标记-复制算法:区域分两块 一块使用另一块回收 交替使用
                     空闲区满时  就被复制到老年代区
    标记-清除、标记-整理算法

14、算法

排序(必须手写会)

//冒泡 排序
public static void BubbleSort(int [] arr){
        
        int temp;//临时变量
        for(int i=0; i<arr.length-1; i++){   //表示趟数,一共arr.length-1次。
            for(int j=arr.length-1; j>i; j--){
                
                if(arr[j] < arr[j-1]){
                    temp = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = temp;
                }
            }
        }
    }

排序算法总结

查找()

15、java中的基本数据类型?各占多少位?多少字节?取值范围?String是基本类型还是引用类型?

基本数据类型(8种):
1.Int          32   4     -2,147,483,648 ~ 2,147,483,647
2.Short     16   2     -32768 ~ 32678
3.long       64   8     -9,223,372,036,854,775,808~+9,223,372,036,854,775,807
4.float       32   4     -3,40292347E+38 ~ +3,40292347E+38
5.double   64   8       -1.79769313486231576E+308 ~ 1.79769313486231576E+308
6.char       16   2          ‘\u0000′ ~ ‘\uFFFF’
7.boolean 1     0.125   true/false
8.byte 8    1    -128 ~ 127

String是引用类型,

16、Java什么时候是值传递什么时候是引用传递?

值传递的时候,将实参的值,copy一份给形参;
引用传递的时候,将实参的地址值,copy一份给形参。
不管是值传递还是引用传递,形参拿到的仅仅是实参的副本,而不是实参本身。

Java到底是值传递?还是引用传递?

17、String相关的。String常量池,StringBuffer,StringBuilder。String不可变的理解。String的intern方法不同版本的实现原理的区别。

String常量池:
JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池。如果字符串已经存在池中,就返回池中的实例引用。如果字符串不在池中,就会实例化一个字符串并放到池中。Java能够进行这样的优化是因为字符串是不可变的,可以不用担心数据冲突进行共享.

留意文章中的面试题: (貌似被虐过!!!)
String之常量池小结

String常量池,StringBuffer,StringBuilder的区别:
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
Java中的String,StringBuilder,StringBuffer三者的区别

a++与++a的区别,如果单独使用没有任何区别,如果在运算中就有区别了,a++是先运算在赋值,而++a是先赋值在运算!!

String不可变的理解:

举个例子:String str = "aa";  str = "aa"+"bb";
此时str的值为"aabb",但是"aabb"不是在开始的字符串"aa"后面直接连接的"bb",而是又新生成了字符串"aabb",字符串"aa"一旦被初始化,那么它的值不可能再改变了。
StringBuffer strb = StringBuffer("aa");  strb.append("bb");
此时的strb的值也为"aabb",但是"aabb"是直接在开始的字符串"aa"后面连接的“bb”,并没有生成新的字符串。

String对象的底层实际上是一个char[]数组:
private final char value[];  
用final修饰的对象值可变,但是引用不变,

StringBuffer对象的底层也是一个char[]数组:
char[] value;  

为什么String对象不可变,而StringBuffer可变?

18、JAVA集合框架

集合框架中唯一的两个线程安全集合

Vector(Stack是Vector的子类也是安全的)
Hashtable

ArrayList,LinkedList异同点:

HashMap,HashTable中的关联和差异:

HashMap与HashTable最大的区别在于hashtable是线程安全的,
hashMap K-V都可为null,hashTable K-V都不能够为null.

ArrayList和Vector的比较:

补充: 底部的数据结构?散列表冲突的处理方法,散列表是一个什么样的数据结构?HashMap是采用什么方法处理冲突的?

HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置。
当程序执行 map.put(String,Obect)方法 时,系统将调用String的 hashCode() 方法得到其 hashCode 值——每个 Java 对象都有 hashCode() 方法,都可通过该方法获得它的 hashCode 值。
得到这个对象的 hashCode 值之后,系统会根据该 hashCode 值来决定该元素的存储位置。
HashMap采用的链表法的方式,链表是单向链表。
链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;

当创建 HashMap 时,有一个默认的负载因子(load factor),其默认值为 0.75,
增大负载因子可以减少 Hash 表(就是那个 Entry 数组)所占用的内存空间,但会增加查询数据的时间开销,而查询是最频繁的的操作(HashMap 的 get() 与 put() 方法都要用到查询);
减小负载因子会提高数据查询的性能,但会增加 Hash 表所占用的内存空间。

http://blog.csdn.net/u011202334/article/details/51498893

集合面试题1
集合面试题2
集合框架
Java容器框架

19、Java容器相关的辅助类Arrays和Collections了解一下(看那个傻逼问!)。

20、Java中final,finalize()和finally的区别:

21、Java怎样开启一个线程。线程池是干什么的?有哪些常用的线程池?优缺点是什么?

开启线程的方式:

1、继承Thread类:

//1):定义一个类A继承于java.lang.Thread类.  
class MusicThread extends Thread{  
    //2):在A类中覆盖Thread类中的run方法.  
    public void run() {  
        //3):在run方法中编写需要执行的操作  
        for(int i = 0; i < 50; i ++){  
            System.out.println("播放音乐"+i);  
        }  
    }  
}  
  
public class ExtendsThreadDemo {  
    public static void main(String[] args) {  
          
        for(int j = 0; j < 50; j ++){  
            System.out.println("运行游戏"+j);  
            if(j == 10){  
                //4):在main方法(线程)中,创建线程对象,并启动线程.  
                MusicThread music = new MusicThread();  
                music.start();  
            }  
        }  
    }  
  
} 

2、实现Runnable接口:

//1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类.  
class MusicImplements implements Runnable{  
    //2):在A类中覆盖Runnable接口中的run方法.  
    public void run() {  
        //3):在run方法中编写需要执行的操作  
        for(int i = 0; i < 50; i ++){  
            System.out.println("播放音乐"+i);  
        }  
          
    }  
}  
  
public class ImplementsRunnableDemo {  
    public static void main(String[] args) {  
        for(int j = 0; j < 50; j ++){  
            System.out.println("运行游戏"+j);  
            if(j == 10){  
                //4):在main方法(线程)中,创建线程对象,并启动线程  
                MusicImplements mi = new MusicImplements();  
                Thread t = new Thread(mi);  
                t.start();  
            }  
        }  
    }  
  
}  

3、直接在函数体使用(特殊的第二种):

void java_thread()  
{  
  
     Thread t = new Thread(new Runnable(){  
            public void run(){  
           // run方法具体重写
    mSoundPoolMap.put(index, mSoundPool.load(filePath, index));  
            getThis().LoadMediaComplete();  
            }});  
        t.start();  
}  

补:继承方式和实现方式的区别?(遇到过)

线程池构成

有哪些常用的线程池?优缺点是什么?

常用的线程池

线程生命周期:

生命周期
生命周期1

几个方法的比较:

22、volidate关键字的作用?

什么是单例模式?
Volidate的原理和指令重排序

23、Java clone的使用。

Person p = new Person(23, "zhang");  
Person p1 = (Person) p.clone();  
  
System.out.println(p);  
System.out.println(p1);  

打印结果:
//com.pansoft.zhangjg.testclone.Person@2f9ee1ac
//com.pansoft.zhangjg.testclone.Person@67f1fba0

Java中的clone方法

24、Java反射机制

反射机制:是程序在运行时能够获取自身的信息。
在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

提供的功能:
在运行时能够判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任一对象的方法
在运行时创建新类对象

反射机制的优缺点:

25、Java静态代理和动态代理

Java静态代理和动态代理

26、类的加载过程,Person person = new Person();为例进行说明

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象,用来封装类在方法区类的对象。

类从被加载到内存开始,到卸载出内存为止,其整个生命周期:
加载,验证,准备,解析,初始化,使用,卸载

其中:验证,准备,解析三个阶段又统称为“连接”

类加载的过程:

包括:加载,验证,准备,解析和初始化等5个阶段。

JAVA类加载周期

阿里、百度 都问过 自己看着办!

上一篇下一篇

猜你喜欢

热点阅读