Android面试题整合(Java篇)

各位同学,这是一篇面试总结文,把面试过程中遇到的问记录下来,并附上如何回答。希望对正在面试或者将要面试的你有一些小帮助。
7f670aa6198e7af7bc8e4d11623154bc.jpeg

1.HashMap 1.7,1.8的差异,1.8中什么情况下转换为红黑树,构造函数中参数代表的意思?

1. JDK1.7用的是头插法,而JDK1.8及之后使用的都是尾插法。
2.扩容后数据存储位置的计算方式也不一样。
3. JDK1.7的时候使用的是数组+ 单链表的数据结构。
JDK1.8及之后时,使用的是数组+链表+红黑树的数据结构。
---
JDK1.8以后的hashmap链表长度为8才转变为红黑树。
---
有两个参数的构造方法HashMap(int initialCapacity, float loadFactor)
参数:initialCapacity 初始容量
参数:loadFactor  负载因子

2.用什么Map可以保证线程安全,为什么?ConcurrentHashMap为什么能保证线程安全?1.7和1.8原理有什么差异。

ConcurrentHashMap 
---
ConcurrentHashMap是把表进行分段,
初始情况下分成16段,每一段都有一把锁,
当多个线程访问不同的段时,因为获取到的锁是不同的,
所以可以并行的访问。
效率比Hashtable高多了,推荐使用。
---
jdk1.7的结构是数组+链表组成的
jdk1.8的ConcurrentHashMap抛弃了原有的Segment分段锁,
而采用了 CAS + synchronized 来保证并发安全性。
底层结构也采用了数组+链表+红黑数的结构。

3.有多少种单例模式,枚举算不算单例,单例模式中不用volatile会导致什么问题?volatile特性是什么?为什么android中不推荐使用枚举。

懒汉式、饿汉式
---
算,最佳的单例实现模式就是枚举模式
---
不用volatile会导致线程不安全
---
volatile关键字的特性
可见性:此变量对所有线程可见,当一个线程修改了这个变量的值,新值对其他线程是可以立即得知的。
禁止指令重排序优化:普通的变量仅会保证该方法的执行过程中所有依赖赋值结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。
---
相比较的话使用enum(枚举)会更加浪费内存,
会牺牲执行的速度、大幅增加文件体积。
这也是性能优化中减少OOM的一个方面。

4.反向输出字符串。

使用StringBuffer或StringBuilder进行反转。
  String str = "dasgfdsfsd";
  StringBuffer buf = new StringBuffer(str);
  buf = buf.reverse(); 
  System.out.println(buf.toString());

5.两个有序链表合并。

递归
非递归

java实现两个有序单链表合并

6.字符串移除多余空格,且技术单词首字符大写。

str.replace(" ", ""); 
str.substring(0, 1).toUpperCase()+str.substring(1);

7.二叉树中和为某一值的路径。

待解决

8.二进制低位转高位。

9.字符串数组判重。

10.二叉树 判断是否为搜索二叉树。

11.thread wait sleep join 有什么区别

1. Thread.sleep()
    使当前所在线程进入阻塞
    只是让出CPU,并没有释放锁
    由于睡眠时间结束后不一定立即被CPU调度,因此线程休眠的时间可能大于传入的参数
    如果被终端则抛出InterruptedException
2. Object.wait()
    让出CPU,释放对象锁
    在调用前需要先拥有对象锁,所以一般在synchronized中同步块使用
    使该线程进入该对象的监视器的等待队列
3. Thread.join()
    join=synchronized+Object.wait();
    线程合并,调用线程会进入阻塞状态,需要等待被调用线程结束后才可以执行
    应用场景:当一个线程必须等待其他线程执行完毕才能继续执行

12.final修饰符

修饰变量:final变量无法被改变,一旦被赋初始值就无法重新赋值。
修饰方法:final方法不能被子类重写,但能够被重载。
修饰类:final类无法被继承。

13.抽象类和接口

1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。

14.GC机制、原理;垃圾收集算法;GCRoots有哪些;

GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器)以应用程序的root为基础,
遍历应用程序在Heap上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。
已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收(回收的是该对象占用的内存空间)。
这就是GC工作的原理。

---
为了实现这个原理,GC有多种算法。比较常见的算法有
Reference Counting,Mark Sweep,Copy Collection等等。

---
目前主流的虚拟系统.NET CLR,Java VM和Rotor都是采用的Mark Sweep算法。

---GCRoots是垃圾回收的起点
虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(即一般说的native方法)中引用的对象

15.四种引用类型

强引用:Java中默认声明的就是强引用
软引用:在内存足够的时候,软引用对象不会被回收,只有在内存不足时,
    系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,
    才会抛出内存溢出异常。
弱引用:无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。
虚引用:虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收

16.线程同步的几种方式;加锁与synchromized区别

1.同步方法:即有synchronized关键字修饰的方法。 
2.同步代码块 :即有synchronized关键字修饰的语句块。 
3.使用特殊域变量(volatile)实现线程同步
4.使用重入锁实现线程同步

每天都在更新中...

你可能感兴趣的:(Android面试题整合(Java篇))