0
点赞
收藏
分享

微信扫一扫

Android面试题

朱小落 2021-09-29 阅读 76
具体介绍下TCP/IP:

TCP/IP一般指的是TCP/IP协议簇,主要包括了多个不同网络间实现信息传输涉及到的各种协议 主要包括以下几层:
应用层:主要提供数据和服务。比如HTTP,FTP,DNS等。
传输层:负责数据的组装、分块。比如TCP,UDP等。
网络层:负责告诉通讯的目的地。比如IP等。
数据链路层:负责连接网络的硬件部分,比如以太网,WIFI等。

HTTP的几种请求方法具体介绍

常见的有四种:
GET 获取资源,没有body,幂等性
POST 增加或者修改资源,有body
PUT 修改资源,有body,幂等性
DELETE 删除资源,幂等性

介绍几种启动模式。

standard,默认模式,每次启动都会新建一个Activity实例,并进入当前任务栈
singleTop,如果要启动的Activity在栈顶存在实例,则不会重新创建Activity,而是直接使用栈顶的Activity实例,并回调onNewIntent方法。
singleTask,如果要启动的Activity在栈中存在实例,则不会重新创建Activity,而是直接使用栈里的Activity实例,并回调onNewIntent方法。并且会把这个实例放到栈顶,之前在这个Activity之上的都会被出栈销毁。
singleInstance,有点单例的感觉,就是所启动的Activity会单独放在一个任务栈里,并且后续所有启动该Activity都会直接用这个实例,同样被重复调用的时候会调用并回调onNewIntent方法。

说说双重校验锁,以及volatile的作用
    private volatile static Singleton mSingleton;

    private Singleton() {
    }

    public Singleton getInstance() {
        if (null == mSingleton) {
            synchronized (Singleton.class) {
                if (null == mSingleton) {
                    mSingleton = new Singleton();
                }
            }
        }
        return mSingleton;
    }
}

为什么要加锁?
为什么不直接给getInstance方法加锁?
为什么需要双重判断是否为空?
为什么还要加volatile修饰变量?

如果不加锁的话,是线程不安全的,也就是有可能多个线程同时访问getInstance方法会得到两个实例化的对象。
如果给getInstance方法加锁,就每次访问mSingleton都需要加锁,增加了性能开销
第一次判空是为了判断是否已经实例化,如果已经实例化就直接返回变量,不需要加锁了。第二次判空是因为走到加锁这一步,如果线程A已经实例化,等B获得锁,进入的时候其实对象已经实例化完成了,如果不二次判空就会再次实例化。
加volatile是为了禁止指令重排。指令重排指的是在程序运行过程中,并不是完全按照代码顺序执行的,会考虑到性能等原因,将不影响结果的指令顺序有可能进行调换。所以初始化的顺序本来是这三步:
1)分配内存空间
2)初始化对象
3)将对象指向分配的空间
如果进行了指令重排,由于不影响结果,所以2和3有可能被调换。所以就变成了:
1)分配内存空间
2)将对象指向分配的空间
3)初始化对象
就有可能会导致,假如线程A中已经进行到第二步,线程B进入第二次判空的时候,判断mSingleton不为空,就直接返回了,但是实际此时mSingleton还没有初始化。

举报

相关推荐

0 条评论