java_android回忆录

 java 基础

1、说说 == 和 equals 比较

1、== 和 equals 最大的区别:一个是运算符,一个是方法

2、==

对比的是栈中的值。

基本数据类型:比较的是变量值(基本数据类型在栈中直接分配)。

引用类型:比较的是堆中内存对象,在栈中的地址。

3、equals:

Object类中,重写了equals方法,里面默认也是采用 == 进行比较

public boolean equals(Object obj) {
    return (this == obj);
}

String类中,重写了equals()方法,它是比较两个字符串的内容。

一般我们自定义某个类,对这个equals()方法进行重写,

然后在equals()方法里面重写你的比较规则,

例如:可参考,String源码的重写,它就是比较两个字符串的内容。

2、String、StringBuffer、StringBuilder的区别?

String
是 final 修饰的,不可变,每次操作都会产生新的 String 对象
StringBuffer StringBuilder
都是在原对象上进行操作。
StringBuffer 是线程安全的, StringBuilder 是线程不安全的
因为 StringBuffer 方法都是用 synchronized 修饰的
性能 :
StringBuilder > StringBuffer > String
场景 :
经常需要改变字符串内容时使用 StringBuilder StringBuffer
优先使用 StringBuilder, 多线程使用共享变量时使用 StringBuffer

3、ArrayList 和 LinkedList 区别

1、都实现了 List 接口
2、数据结构不同

ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。

3、效率不同

当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。

当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。

4、HashMap 和 HashTable 有什么区别?其底层实现是什么?

区别 :
1、HashMap 是非线程安全的,HashTable 是线程安全的。
因为 HashMap 方法没有 synchronized 修饰
2、HashMap 的键和值都允许有 null 值存在,而 HashTable 则不行。
3、因为线程安全的问题,HashMap 效率比 HashTable 的要高。
能答出上面的三点,简单的面试,算是过了
底层实现:
它们都是 数组+链表 实现的

5、单例模式

饿汉式(线程安全)
类加载到内存后,就实例化一个对象。
造成内存浪费的问题(话说你不用它,你装载它干啥)
懒汉式
只有第一次用到的时候才初始化实例,解决了饿汉式造成内存浪费的问题,
但是多线程的时候是不安全的,需要在方法上加同步锁,同时也带来效率的下降
双重校验锁
new 创建对象的过程,会出现问题,指令重排!
需要使用 volatile 关键字,
因为它可以解决指令重排的问题(出现几率极少,几百万分之一)
静态内部类
加载外部类时不会加载内部类,这样可以实现懒加载,跟懒汉式类似
枚举
不仅可以解决线程同步,还可以防止反序列化问题
唯一缺点是可读性不高

6、Java 四大引用是什么?它们的区别?

强引用 
Object obj = new Object()

软引用 
内存不足时回收

弱引用 
GC到來时回收

虚引用
GC回收时可得到一个通知

az基础

1、Handler异步消息处理机制

1、常见使用场景

Android平台,不允许Activity新启动的子线程,动态更新此Activity的界面组件。而Handler可以很好的解决这个问题

2、主要部分组成

①. Message (主要用于携带消息)

②. Handler (主要用于发送和处理消息)

③. MessageQueue (它是一个消息队列)

④. Looper (它是一个循环器)

3、常见用法与源码解读

常见用法

(1)在主线程中创建Handler,通过回调的方式,在handleMessage方法里面获取、处理消息  

(2)在新启动的子线程中,通过Handler对象,调用 sendMessage 等方法发送消息

源码解读

1、子线程

Handler对象调用 sendMessage 等方法发送消息,源码内部在调用过程中得到 MessageQueue 对象(它是先入先出的队列),

其实最后是调用MessageQueue 消息队列的 enqueueMessage 入队方法,收到的消息以队列的形式进行排列

2、主线程

Android 的主线程就是 ActivityThread,主线程的入口为main方法,main方法内部:

  (1):Looper 调用 prepareMainLooper 静态方法,内部会去调用 prepare 方法(创建 一个Looper对象)

            方法内部具体: 判读是否有Looper对象? 有,提示 “每个线程只能创建一个 Looper对象”;没有,创建一个新的Looper设置进去

 (2):Looper调用 loop 方法,loop方法内部

            首先调用 myLooper 方法,去取一个Looper对象,

            如果Looper对象为空,会抛出一个异常,提示没有Looper对象;

            如果Looper不为空,继续执行得到 MessageQueueen 消息队列,然后进行 for循环操作

           for循环里面是 MessageQueueen 对象调用 next 出队方法,得到一个个Message 消息,调用dispatchMessage发送消息

           最后通过回调 handleMessage 方法并把 Message 消息依次传递过去

4、Handler机制原理,为什么不会阻塞主线程?

不会阻塞,是因为安卓内所有的操作都是靠handler完成的,
当主线程handler退出,就是整个应用退出,
handler只会在空闲的时候,通过epoll让出CPU并释放资源。

5、一个Activity多个Handler时,Message是如何区分传递的?

msg.target 把当前的这个handler标记,给这个当前我们发送的msg

最近在面试,被面试官问到:如果一个Activity有多个handler时候,怎样知道handler1发送的消息不会被handler2接收,同理handler2发送的消息不会被handler1接收。

一个Activity多个Handler时,Message是如何传递的_u010680097的专栏-CSDN博客_两个handler

2、Activity的启动模式

1.standard
默认标准模式,每启动一个都会创建一个实例,
2.singleTop
栈顶复用,如果在栈顶就调用 onNewIntent 复用,从onResume()开始
3.singleTask
栈内复用,本栈内只要用该类型 Activity 就会将其顶部的activity出栈
4.singleInstance
单例模式,除了 3 中特性,系统会单独给该 Activity 创建一个栈

Android开发艺术探索知识回顾——第1章 Activity的生命周期和启动模式:2、启动模式和Flags标记位_鲁迷那的专栏—坚持实践后再写出来!-CSDN博客

Activity的启动模式LaunchMode以及使用场景_鲁迷那的专栏—坚持实践后再写出来!-CSDN博客

3、事件分发机制

1、为什么会有事件分发机制?

Android上面的View是树形结构,View可能会重叠在一起,

当我们点击的地方有多个View都可以响应的时候,这个点击事件应该给谁呢?

为了解决这个问题,就有了事件分发机制。

2、三个重要角色 

        1、Activity:接收Down点击事件,传递给Phonewindow和DecorView

        2、ViewGroup:拦截事件,或者继续传递给子View

        3、View:消费事件,或者不消费从而返回给上一级

3、三个核心方法

        1、dispatchTouchEvent():是否分发事件

        2、onTouchEvent() : 是否消费事件

        3、onInterceptTouchEvent():是否拦截事件

4、事件在是如何传递的?

事件传递过程是Activity把事件传递给PhoneWindow,DecorView,ViewGroup,

然后ViewGroup把事件传递给View,如果下级不处理这个事件在返回给上级处理。

5、三个方法的区别和关系

其实它们的关系可以用如下伪代码表示:

public boolean dispatchTouchEvent(MotionEvent ev) {
      boolean consume = false;
      if (onInterceptTouchEvent(ev)) {
          consume = onTouchEvent(ev);
 
      } else {
          consume = child.dispatchTouchEvent(ev);
     }
 
     return consume;
}

通过伪代码,大致了解点击事件的传递规则

上述伪代码已经将三者的关系表现得淋漓尽致。通过上面的伪代码,我们也可以大致了解点击事件的传递规则:

1、对于一个根 ViewGroup 来说,点击事件产生后,首先会传递给它,这时它的 dispatchTouchEvent 就会被调用,

2、如果这个 ViewGroup 的 onlnterceptTouchEvent 方法返回 true,就表示它要拦截当前事件,接着事件就会交给这个 ViewGroup 处理,即它的 onTouchEvent 方法就会被调用;

3、如果这个 ViewGroup 的 onlnterceptTouchEvent 方法返回 false,就表示它不拦截当前事件,这时当前事件就会继续传递给它的子元素,接着子元素的 dispatchTouchEvent 方法就会被调用,如此反复直到事件被最终处理。
 





Android开发艺术探索知识回顾——第3章 View的事件体系:3、View的事件分发机制、滑动冲突_鲁迷那的专栏—坚持实践后再写出来!-CSDN博客

Android事件分发机制完全解析,带你从源码的角度彻底理解(上)_郭霖的专栏-CSDN博客_android 事件分发

Android事件分发机制完全解析,带你从源码的角度彻底理解(下)_郭霖的专栏-CSDN博客_android 事件分发源码

Android必备回顾:1、Android事件分发机制(上)_View_鲁迷那的专栏—坚持实践后再写出来!-CSDN博客

Android必备回顾:2、Android事件分发机制(下)_ViewGroup_鲁迷那的专栏—坚持实践后再写出来!-CSDN博客

Android事件分发机制探索(一)源码追踪之开端强迫症篇_鲁迷那的专栏—坚持实践后再写出来!-CSDN博客

Android事件分发机制详解与实战剖析,一张事件分发流程图,让你彻底搞明白_门心叼龙的专栏-CSDN博客_事件分发流程图

从面试角度聊Android事件分发机制 - 简书【有问题】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被开发耽误的大厨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值