美文网首页
Android面试.

Android面试.

作者: coke613 | 来源:发表于2025-04-15 21:24 被阅读0次

一. android各版本差异性:

6.0 权限:
        ①.从6.0开始,Android划分了危险权限,比如读取文件,打开摄像头.
        ②.WiFi相关的操作,需要动态的申请位置权限,如果还想获取WiFi列表,还需要打开GPS位置信息.
7.0 
    ①.fileProvider 应用共享文件.
    ②.打包apk出现v2
8.0 
    ① 通知,需要创建通知渠道,用户可以根据渠道类型进行屏蔽一些不想要的通知.
    ② 安装apk去除了"允许安装未知来源"选项.
    ③ 对从清单文件中静态注册广播增加了限制.
9.0 
    http明文请求,使用HTTPS加密.
10 深色主题,分区存储.   在特定目录下存储,无需权限,随着安装包卸载,数据自动删除.
11 存储机制更细.位置信息更新.

二. http/socket 通信协议

tcp和utp的区别:
    tcp.面向链接,比如拨打电话(先建立链接) ; utp 是无链接,发送数据之前不需要建立链接.
    tcp.可靠,稳定.采用三次握手,四次挥手机制,数据可靠,不会重复. UTP 数据不可靠,可能会丢包.
    tcp.要求系统资源多 首部开销20个字节  UTP 要求系统少 首部开销 8 个字节.


http是超文本传输协议,为短连接. 客户端发起请求,服务器端接收请求并相应客户端,请求结束之后,主动释放连接,因此为短链接.
    请求方式:post,get 
                get 使用url链接拼接,用 "?" 分割开. 传输数据有限制,不能大于2kb.
                post 使用的key value的表单方式发送. 对数据没有限制.

http 和 https 区别:
    ① 在 Android9.0 之后,需要使用https请求.
    ② https 需要ca 证书,一般是收费的.
    ③ http是超文本传输,明文传递. 不安全; https使用具有安全性的ssl加密,安全.
    ④ http 和 https 是两种不同的链接方式. http端口是80  https端口是443.

socket 是长链接,通常情况下socket链接就是tcp链接.一旦建立,就互相通信.直到双方断开链接.
socket不是一种协议,是一个接口. socket链接至少需要一对套接字 分别是:clientSocket,serviceSocket.连接分为3个步骤:
    ① 服务器监听: 服务端不清楚具体客户端的套接字,而是出于时刻的监听状态.
    ② 客户端请求: 客户端携带带有描述服务器套接字,如地址,端口,然后向服务器端发起请求.
    ③ 链接确认: 服务器端套接字接收到客户端套接字发来的请求后,就响应客户端的请求,并创建一个新的线程,把服务器的套接字描述发给客户端.一旦客户端确认了描述,此时正式建立链接.
                而服务器套接字继续监听其他客服端发来的请求.

三. Rxjava+retrofit

rxjava 异步处理数据.obverse观察者订阅obverseable可观察者.通过可观察者对象发射的数据流,在此过程中,可通过操作符 线程切换等操作,最后由观察者做出相应的过程.
retrofit 强大的网络请求. 通过java接口以注解的方式来描述接口信息.并用动态代理的方式生成网络请求的request,然后通过client调用相应的网络框架 默认是okhttp.

四.EventBus

发布订阅模式
    对象间一对多依赖关系.当这个对象状态发生改变的时候,其他对象都会接到通知,并自动更新.
    在发布订阅模式中,发布者不会直接将信息告诉订阅者,而是通过第三种组件来告知,这样一来,发布和订阅者没有丝毫关系,第三种组件我们称为事件总线,它是发布 订阅关联者,它过滤所有的信息传递给订阅者.

五.消息机制 Handler

由于Android开发规范的限制,我们不能在子线程内更新ui控件.否则就发程序异常崩溃.这个时候就可以使用handler将更新ui的操作切换到主线程中.


为什么子线程不能更新ui?
    因为Android的ui控件不是线程安全的,如果在多线程中并发访问可能会导致ui控件处于不可预期的状态,那为什么不加上安全锁呢?
        如果加上锁机制的话会让ui访问的逻辑变的更复杂.
        其次锁机制会降低ui访问的效率,因为锁机制会阻塞某些线程的执行.

Android的消息机制主要是指Handler的运行机制,handler的运行需要底层的MessageQueue和Looper的支撑.
MessageQueue是消息队列,内部存储了一个消息机制,以队列的方式对外提供插入和删除的工作.但是他不是一个队列.而是采用单链表的数据结构来存储消息列表.MessageQueue只是一个消息存储的单元,不能处理消息.
而Looper就填补了这个功能,looper以无限循环的方式查看是否有新的消息,如果有的话就去处理,没有的话就一直等待.

六.Android 性能优化

①. 布局优化
    a.减少布局层次
        如果布局中既可以使用相对布局,也可以使用线性布局,那么使用线性布局. 因为相对布局功能比较复杂.
        如果布局嵌套那么可以考虑使用相对布局.因为ViewGroup的嵌套就相当于增加了布局的层次,同样会降低程序的性能.
    b.使用include标签,这样的话布局可以复用.

②. 绘制优化
    避免在view onDraw中创建局部对象,因为onDraw方法可能会频繁的调用,这样的话一瞬间会生成大量对象,不仅占用大量的内存,还会导致系统更加频繁gc,降低了程序的执行效率.
    onDraw方法中不要做耗时任务,也不能执行大量的循环操作. 每帧的绘制时间不超过16ms

③. 内存泄露优化
    a. 静态变量导致的内存泄露.在dalvik虚拟机中,static变量所指向的内存引用,如果不把它设置为null,GC是永远不会回收这个对象的.
    b. 单例模式 其生命周期和application保持一致,因此引用对象无法回收.
    c. 属性动画  在Android3.0的时候 Google提供了属性动画, 开启了动画,但没有关闭动画.       虽然在act中界面已经关闭了,动画已经消失了,但是动画一直持有view,而view持有当前的act,最终act无法释放. 

④. 响应速度优化
    响应速度优化核心就是避免在主线程中做耗时操作,如果避免不了做耗时操作,可以将耗时操作放在线程中.

七.进程间通讯

  1. Binder
Binder 是 Android 中最核心的 IPC 机制,底层实现基于 Linux 内核:
- AIDL (Android Interface Definition Language):
- 定义客户端和服务端共同遵守的接口
- 自动生成跨进程调用的代码

使用步骤:
1. 创建 AIDL 文件定义接口
2. 实现 Service 并返回 Binder
3. 客户端绑定服务并调用远程方法
  1. Messenger
    基于 Binder 的轻量级 IPC,适合简单的消息传递

  2. ContentProvider 用于跨应用数据共享:

实现 ContentProvider 类并声明于 Manifest
通过 ContentResolver 访问
支持权限控制
  1. BroadcastReceiver 用于系统范围的事件通知
有序广播 (Ordered Broadcast)
普通广播 (Normal Broadcast)
本地广播 (LocalBroadcastManager,仅进程内)

八. Android WebSocket 即时通讯流程原理

    1. WebSocket 连接建立流程
1. HTTP 握手阶段:
  客户端发送 HTTP Upgrade 请求
  服务端返回 101 Switching Protocols 响应

一次握手: 客户端同步标志位,随机生成序列号.
二次握手:服务端初始化自己的序列号,并确认客户端序列号.
三次握手:客户端确认服务端序列号

为什么是三次:
- 防止历史重复连接初始化(旧SYN报文到达时,客户端会拒绝)
- 最少需要三次交互才能确保双方收发能力正常.

序列号的作用:
- 初始值为随机数(安全考虑),
- 后续数据按 seq+payload_len 递增
如客户端发送 seq=100, len=20,则下个报文 seq=120


四次挥手 (连接终止)
1.客户端主动关闭(不再发送数据)
2.服务端确认,但可能还有数据要发送
3.(服务端处理剩余数据...)服务端数据发完后关闭
4.客户端确认

为什么是四次?
- 服务端的 ACK 和 FIN 通常不能合并发送,因为中间可能需要处理剩余数据
- 若服务端无剩余数据,可能合并为三次(Linux 下可通过 tcp_fin_timeout 调整)


2. 协议升级:
   成功握手后,TCP 连接保持打开状态
   通信协议从 HTTP 切换到 WebSocket 协议
  • 2.Android 端实现核心机制
// 状态转换图
[断开] → [连接中] → [已连接] ↔ [数据传输] → [断开中] → [断开]

+----------------+     +----------------+     +-----------------+
|  用户发送消息   | --> |  WebSocket发送 | --> |   网络传输      |
+----------------+     +----------------+     +-----------------+
                                                       |
+----------------+     +----------------+     +--------v---------+
|  更新本地数据库 | <-- |  WebSocket接收 | <-- |   服务器推送     |
+----------------+     +----------------+     +-----------------+
    1. 关键保活机制
心跳机制原理

客户端每隔N秒发送PING帧 → 服务端回应PONG帧
│___________________________│
       超时检测(通常2-3倍间隔)

九.挑战性bug- WebSocket 断线重连的竞态条件

现象:在弱网环境下,重连机制导致多个 WebSocket 实例同时存在,消息重复发送。
难点:

重连逻辑和心跳机制冲突

线程同步问题(主线程和网络线程竞争)

解决方案
// 使用原子变量 + 双重检查锁
private final AtomicBoolean isConnecting = new AtomicBoolean(false);

public void reconnect() {
    if (isConnecting.compareAndSet(false, true)) {
        try {
            if (webSocket != null) {
                webSocket.close(1000, "Reconnecting");
            }
            // 延迟避免频繁重连
            handler.postDelayed(() -> {
                initWebSocket();
                isConnecting.set(false);
            }, 2000);
        } catch (Exception e) {
            isConnecting.set(false);
        }
    }
}

相关文章

网友评论

      本文标题:Android面试.

      本文链接:https://www.haomeiwen.com/subject/atecpltx.html