Android 面试复习

try catch编程

public static int getNum() {
        try {
            int a = 1 / 0;
            return 1;
        } catch (Exception e) {
            System.out.println("1");
//            int b = 2 / 0;
//throw new Exception("asdasd");
            System.out.println("2");
            return 2;
        } finally {

            return 5;
        }
    }
复制代码

总结: catch 中,遇到 return 或者再发生 catch ,将会直接执行 finally, 若是没有 finally 只有 再发生 catch 那就抛出异常。缓存

toast :bash

这是由于Toast显示须要NotificationManagerService(查看Android源码)

部分手机把通知权限关闭了,因此Toast没法正常弹出
复制代码

线程问题:多线程

1,wait 和 sleep 的区别并发

wait 会释放锁,sleep 会有持有锁。wait 用来线程间交互,sleep 用于暂停执行。
复制代码

2,synchronized 和 volatile volatile:框架

1)保证了不一样线程对这个变量进行操做时的可见性,即一个线程修改某个变量的值,这新值对于其余线程可见。(线程缓存无效,取主存中的值,具备原子性)

2)禁止进行指令重排

发散:
1.原子性
    i = 1 这种操做,i ++, j = i 都不是原子操做  
2.可见性
    Java就是利用volatile来提供可见性的。 当一个变量被volatile修饰时,那么对它的修改会马上刷新到主存,当其它线程须要读取该变量时,会去内存中读取新值。而普通变量则不能保证这一点。
    其实经过synchronized和Lock也可以保证可见性,线程在释放锁以前,会把共享变量值都刷回主存,可是synchronized和Lock的开销都更大。
3.有序性
    JMM是容许编译器和处理器对指令重排序的,可是规定了as-if-serial语义,即无论怎么重排序,程序的执行结果不能改变。
    JMM保证了重排序不会影响到单线程的执行,可是在多线程中却容易出问题。
    
例子:
    1,单例模式的实现,典型的双重检查锁定(DCL)   
    2,标记变量
复制代码

3,线程池ide

1,线程池优点

第一:下降资源消耗。经过重复利用已建立的线程下降线程建立和销毁形成的消耗。 

第二:提升响应速度。当任务到达时,任务能够不须要等到线程建立就能当即执行。 

第三:提升线程的可管理性。线程是稀缺资源,若是无限制的建立,不只会消耗系统资源,还会下降系统的稳定
性,使用线程池能够进行统一的分配,调优和监控。


2,线程池策略

    a. 若是正在运行的线程数量小于 corePoolSize,那么立刻建立线程运行这个任务;
    
    b. 若是正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。
   
    c. 若是这时候队列满了,并且正在运行的线程数量小于 maximumPoolSize,那么仍是要建立线程运行这
    个任务;
    
    d. 若是队列满了,并且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调用者“我不能再接受任务了”。
    
    注意:
    
    一、当一个线程完成任务时,它会从队列中取下一个任务来执行。
    
    二、当一个线程无事可作,超过必定的时间(keepAliveTime)时,线程池会判断,若是当前运行的线程数大于
    corePoolSize,那么这个线程就被停掉。因此线程池的全部任务完成后,它最终会收缩到 corePoolSize 的大小。
复制代码

4,如何控制某个方法容许并发访问线程的个数函数

Semaphore
semaphore.acquire();
semaphore.release();
复制代码

5,反射ui

ava 中的反射首先是可以获取到 Java 中要反射类的字节码,获取字节码有三种方法, 1.Class.forName(className) 2.类名.class 3.this.getClass()。而后将字节码中的方法,变量,构造函数等映射 成相应的 Method、Filed、Constructor 等类,这些类提供了丰富的方法能够被咱们所使用。

1)动态代理
复制代码
final List<String> list = new ArrayList<String>();
List<String> proxyInstance = (List<String>) Proxy.newProxyInstance(list.getClass().getClassLoader(), list.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
return method.invoke(list, args); }
}); proxyInstance.add("你好"); System.out.println(list);
复制代码
2)动态代理与静态代理的区别
    静态代理一般只代理一个类,动态代理是代理一个接口下的多个实现类。 静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道。 动态代理是实现 JDK 里的 InvocationHandler 接口的 invoke 方法,但注意的是代理的是接口,也就是你的
业务类必需要实现接口,经过 Proxy 里的 newProxyInstance 获得代理对象。
还有一种动态代理 CGLIB,代理的是类,不须要业务类继承接口,经过派生的子类来实现代理。经过在运行
时,动态修改字节码达到修改类的目的。
AOP 编程就是基于动态代理实现的,好比著名的 Spring 框架、Hibernate 框架等等都是动态代理的使用例子。
复制代码
相关文章
相关标签/搜索