Android面试题,个人总结

分为两部分:java 和 android 和 git

Java部分:

1、八种数据类型以及他们的包装类
2、abstract与interface的区别(抽象类和接口)
3、重写和重载的区别
4、return和break和continue的区别
5、面向对象和面向过程
6、equals()和==的区别
7、大路边的几个设计模式
9、String,StringBuffer,StringBuilder
10、正则表达式
11、集合
12、I/O
13、线程和进程
14、数据库
15、网络
16、json和html
17、java 的软引用,弱引用 ?
18、常用的集合数据类型?
19、java 中的静态类是否可以被继承
20、ArrayList和 Hashmap 线程是否安全 ?
21、一种数据算法
22、几种常用的 sql 的关键字

一、八种数据类型以及他们的包装类

int long float double byte short char boolean
Integer Long Float Double Byte Short Character Boolean
-2^31 ~ 2^31-1 2^63 ~ 2^63-1 -2^128 ~ +2^128 -2^1024 ~ +2^1024 -128~127 -32768~32767 0~65535 true/false

二、abstract与interface的区别(抽象类和接口)

    1、关键字:抽象类 abstract         接口interface
    2、抽象类继承 extends             接口实现 implements
    3、子类继承抽象类和                实现类实现接口的格式不同
    4、抽象类中有各种属性和方法         接口中只有全局变量和抽象方法
    5、抽象类只能单继承                接口可以多实现
    6、抽象类的子类只能继承一个父类      实现类可以实现多个接口,并且还可以继承父类
    7、抽象类的作用:提高代码的复用性    接口的作用:1、规范代码2、提高代码的拓展新

三、重写和重载的区别

    1、重写是在继承关系中                   重载是在同一个类中
    2、重写是方法名、参数列表和父类相同       重载,方法名相同,参数列表不相同(个数、类型、顺序)
    3、重写返回值类型和父类相同              重载和返回值无关
    4、重写访问权限修饰符不能比父类更加严格    重载没有要求

四、return和break和continue的区别

1.break语句的使用场合主要是switch语句和循环结构。
在循环结构中使用break语句,如果执行了break语句,那么就退出循环,接着执行循环结构下面的第一条语句。
如果在多重嵌套循环中使用break语句,当执行break语句的时候,退出的是它所在的循环结构,对外层循环没有任何影响。如果循环结构里有switch语句,并且在switch语句中使用了break语句,当执行switch语句中的break语句时,仅退出switch语句,不会退出外面的循环结构

break效果图.jpg

2.continue:终止当前的一次循环过程,但是不跳出循环,而是继续往下执行下一次循环。


continue实例

3.return:如果在程序中遇到return语句,那么代码就退出该函数的执行,返回到函数的调用处

return效果图.jpg

五、面向对象和面向过程

面向过程:就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
面向对象:是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为

面向对象三个特征:
封装,继承,多态
封装:
封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。get()/set()方法
继承:
子对象可以继承父对象的属性和行为,亦即父对象拥有的属性和行为,其子对象也就拥有了这些属性和行为
这个很好理解,解析数据的时候,大家应该都有一个BaseBean,然后去继承他,不用重复写代码,利于代码的复用性
多态:
多态是指父对象中的同一个行为能在其多个子对象中有不同的表现。
也就是说子对象可以使用重写父对象中的行为,使其拥有不同于父对象和其它子对象的表现,这就是overriding(重写)
多态存在的三个必要条件:
一、要有继承;
二、要有重写;
三、父类引用指向子类对象

多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

六、equals()和==的区别

== 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,
即是否是指相同一个对象。比较的是真正意义上的指针操作。
equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,
所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,
而Object中的equals方法返回的却是==的判断。

七、大路边的几个设计模式

工厂模式:
android中的demo体现:线程池
https://blog.csdn.net/nugongahou110/article/details/50425823
这个链接,very good,对我来说,非常好理解,what is 工厂模式???我是在这儿学的,原谅我这个菜鸟吧,不会总结.
最好把demo敲一遍,加深记忆,很好理解,虽然看也是可以看懂的.
建造者模式:
https://blog.csdn.net/nugongahou110/article/details/50395698
android中,大概build()结尾的都是吧.比如:Imagrloder,AlertDialog.Builder等等.
装饰者模式:
https://blog.csdn.net/nugongahou110/article/details/50413668

单例模式:
饿汉式:

//只有内部类可以为static。
public class SingIn{
    //在自己内部定义自己的一个实例,只供内部调用
    private static final SingIn instance = new SingIn();
    private SingIn(){
    }
    //这里提供了一个供外部访问本class的静态方法,可以直接访问
    public static SingIn getInstance(){
        return instance;
    }
}

懒汉式:

/***
     * 一种常用的形式
     */
    private static SingIn instance = null; 
    public static synchronized SingIn getInstance() {         
      // 这个方法比上面有所改进,不用每次都进行生成对象,只是第一次  
      // 使用时生成实例,提高了效率!  
       if (instance == null)  
              instance = new SingIn();  
              return instance;  
    }

双重锁定:(这个一般在实际应用中用的比较多,以上,了解即可)

//将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。 
private static volatile SingIn instance=null;
 private SingIn (){
 
 }
 public static  SingIn getInstance(){
    if(instance==null){
      synchronized(SingIn .class){
      if(instance==null){
        instance=new SingIn ();
       }
      }
     }
    return instance;
  }

九、String,StringBuffer,StringBuilder

关系图

1、运行速度:StringBuilder > StringBuffer > String

原因: String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,每一次新的赋值,都会重新创建对象,垃圾回收机制回收旧的对象,但后两者的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
2、线程安全:StringBuilder是线程不安全的,而StringBuffer是线程安全的
 原因:StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

十、正则表达式

Pattern 类:
pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
PatternSyntaxException:
PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

十一、集合

整体关系图

十二、I/O

I/O

十三、线程和进程

线程的生命周期

新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。
在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。
当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
Java 提供了三种创建线程的方法:
   通过实现 Runnable 接口;
   通过继承 Thread 类本身;
   通过 Callable 和 Future 创建线程。
进程和线程的区别:
进程是应用程序,线程是一条执行路径
进程有独立的内存空间,崩溃不会影响其他程序,
线程没有独立的空间,多个线程在同一个进程的空间,可能会影响其他线程
一个进程中,至少有一个线程
run和start的区别
run没有开辟新的栈空间,没有新线程,都是主线程在执行
start开辟了新的栈空间,在新的栈空间启动run()方法
sleep和pield的区别:
sleep 线程进入被阻塞的状态
yeild 线程转入暂停执行的状态
打断线程的终止方式
1、用标记,当终止线程时,会执行完run方法
2、stop()方法,不建议使用,会执行不到特定的代码
3、interrupt(),只能中断正在休眠的线程,通过抛异常的方法中断线程的终止。
InputStream inputStream=System.in;
int m=inputStream.read();
myThread2.interrupt();//通过外界输入打断

十四、数据库

            Class.forName("com.mysql.jdbc.Driver");
        
            // 打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL,USER,PASS);
        
            // 执行查询
            System.out.println(" 实例化Statement对象...");
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT id, name, url FROM websites";
            ResultSet rs = stmt.executeQuery(sql);
        
            // 展开结果集数据库
            while(rs.next()){
                // 通过字段检索
                int id  = rs.getInt("id");
                String name = rs.getString("name");
                String url = rs.getString("url");
    
                // 输出数据
                System.out.print("ID: " + id);
                System.out.print(", 站点名称: " + name);
                System.out.print(", 站点 URL: " + url);
                System.out.print("\n");
            }
            // 完成后关闭
            rs.close();
            stmt.close();
            conn.close();

十五、网络

一、HttpClient:
HttpClient 是Apache的一个三方网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快。实现比较稳定,bug比较少,但是正式由于其api众多,是我们很难再不破坏兼容性的情况下对其进行扩展。所以,Android团队对提升和优化httpclient积极性并不高。android5.0被废弃,6.0逐渐删除。
二、HttpURLConnection
HttpURLConnection是一个多用途、轻量级的http客户端。它对网络请求的封装没有HttpClient彻底,api比较简单,用起来没有那么方便。但是正是由于此,使得我们能更容易的扩展和优化的HttpURLConnection。不过,再android2.2之前一直存在着一些令人烦的bug,比如一个人可读的inputstream调用它的close方法的时候,会使得连接池实效,通常的做法就是禁用连接池。因此,在android2.2之前建议使用稳定的HttpClient,android2.2之后使用更容易扩展和优化的HttpURLConnection。
三、okhttp
支持Android 2.3及其以上版本;
支持Java JDK 1.7以上版本;
okhttp是专注于提升网络连接效率的http客户端。
1、它能实现同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力。
2、okhttp 对http和https都有良好的支持。
3、okhttp 不用担心android版本变换的困扰。
4、成熟的网络请求解决方案,比HttpURLConnection更好用。
4、缺点,okhttp请求网络切换回来是在线程里面的,不是在主线程,不能直接刷新UI,需要我们手动处理。封装比较麻烦。

十六、json和html

XML的三种原生解析方式
DOM,SAX,PULL
DOM:内存消耗大 但是便于遍历.打开文档,将其转化为节点树,然后在其用循环的方式,遍历节点,一一查找.
SAX:速度快,战内存少.但是文件结构信息会丢失,采用的是流的处理方式.从起始标签开始一一往下逐个查找.起始标签与结尾标签作为标记来将一组数据存入一个集合中,想水流一样一直到最尾,然后最后返回集合,集合中就存下了所有的数据(这也应该就是所谓的流处理方式吧).
PULL:是Android内置,推荐的一种,相对来说有点类似SAX,也是从上往下,但是它还是已文档开始与结尾为条件,在其中间进行查找处理,然后分为不同标签开始逐一查找.
JSON的三种解析方式
原始解析:JSONObject
google的Gson: Gson gson = new Gson();
    String str = gson.toJson(obj);
阿里的Fastjson:
    JSON.parseObject(result,MenuBean.class);

十七、java 的软引用,弱引用 ?

十八、常用的集合数据类型?

List 、Map 、Set
常用的有ArrayList、HashMap等

十九、java 中的静态类是否可以被继承 ?

可以

二十、ArrayList和 Hashmap 线程是否安全 ?

这两个结构都不是线程安全的.对于ArrayList, 可以通过多个线程向其添加元素。
推荐链接:https://blog.csdn.net/u012859681/article/details/78206494

二十一、数据算法

至少要会写一个吧~~ 冒泡排序、快速排序、选择排序。直接插入
冒泡排序:

    public static int[] sortBubble(int[] datas) {  
        for (int i = 0; i < datas.length - 1; i++) {  
            for (int j = 0; j < datas.length - 1 - i; j++) {  
                if (datas[j] > datas[j + 1])  
                    AlgorithmUtil.swap(datas, j, j + 1);  
            }  
        }  
        return datas;  
    } 

插入排序:

    public void insertionSort(int array[]) {
        int i, j, t = 0;
        for (i = 1; i < array.length; i++) {
            if(a[i]<a[i-1]){
                t = array[i];
                for (j = i - 1; j >= 0 && t < array[j]; j--)
                    array[j + 1] = array[j];
                //插入array[i]
                array[j + 1] = t;
            }
        }
}

选择排序:

public void selectSort(int array[]) {
        int t = 0;
        for (int i = 0; i < array.length - 1; i++){
            int index=i;
            for (int j = i + 1; j < array.length; j++)
                if (array[index] > array[j])
                    index=j;
            if(index!=i){ //找到了比array[i]小的则与array[i]交换位置
                t = array[i];
                array[i] = array[index];
                array[index] = t;
            }
        }
    }

快速排序:

public void quickSort(int array[], int low, int high) {// 传入low=0,high=array.length-1;
        int pivot, p_pos, i, t;// pivot->位索引;p_pos->轴值。
        if (low < high) {
            p_pos = low;
            pivot = array[p_pos];
            for (i = low + 1; i <= high; i++)
                if (array[i] > pivot) {
                    p_pos++;
                    t = array[p_pos];
                    array[p_pos] = array[i];
                    array[i] = t;
                }
            t = array[low];
            array[low] = array[p_pos];
            array[p_pos] = t;
            // 分而治之
            quickSort(array, low, p_pos - 1);// 排序左半部分
            quickSort(array, p_pos + 1, high);// 排序右半部分
        }

二十二、几种常用的 sql 的关键字

--创建一个名为stonestory的数据库
create database stonestory

--创建一个名为roles的表
create table roles
(
    roleId int primary key identity(1,1),    --id号设为主键,从1开始递增量为1
    roleName varchar(15),        --名字  varchar(可变)
    roleAge int,            --年龄    
    roleSex char(2),    --性别
)

--删除表(把表的结构本身和数据都删掉)
drop table roles

--插入语句
insert into roles values('林黛玉',18,'女')

--查询语句
select * from roles        --查询表中全部内容
select * from roles where roleAge<20        --查询表中年龄小于20的人物信息
select * from roles where roleAge between 18 and 28        --查询表中年龄在18到28之间的人物信息
select top 1 * from roles where roleId > 2        --查询表中id号大于2的人物信息(只显示第一条)

----查询id号除第一个的前两个人物信息(即第2,3位置的人物信息)
select top 2 * from roles where roleId not in(select top 1 roleId from roles)

--更新语句(修改)
update roles set roleAge=19 where roleName='薛宝钗'    --将名为薛宝钗的人的年龄改为19

delete from roles        --删除表中全部数据
delete from roles where roleName='贾政'    --删除表中名为贾政的人

Android部分

1、MVC、MVP、MVVM
2、四大组件
3、Android的数据存储方式--持久化技术
4、异步消息处理机制--Message、Handler、MessageQueue、Lopper
5、XML和JSON格式数据解析
6、Intent和PendingIntent的区别
7、三种动画
8、Design的使用
9、Fragment的生命周期
10、清单文件里面的内容包括哪些?
11、如何兼容不同的版本
12、如何配置第三方的sdk
13、fragment的切换方式
14、点击事件的分发机制
15、消息推送原理以及实现过程
16、map集合的存储原理
17、自定义View的只要重写的方法名有哪些?
18、Alipay的支付流程?
19、怎么让viewpager不滑动?
20、如何避免内存泄露(造成内存泄漏的原因)?
21、下拉刷新的实现?
22、侧滑菜单的实现?(抽屉效果)
23、java虚拟机jvm和android虚拟机Dalvik的区别?
24、Java当中的加密解密技术?
25、屏幕适配的方法
26、图片的三级缓存
27、适配全面屏
28、AIDL的使用
29、视频的相关内容

1、MVC、MVP、MVVM

推荐链接:
http://blog.csdn.net/hudan2714/article/details/50990359

MVC

模型(model)-视图(view)-控制器(controller)

MVC.png

数据关系:
View 接受用户交互请求
View 将请求转交给Controller
Controller 操作Model进行数据更新
数据更新之后,Model通知View更新数据变化
View 更新变化数据
使用:
MVC中的View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是 View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。

MVP

Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理

MVP.png

数据关系:
View 接收用户交互请求
View 将请求转交给 Presenter
Presenter 操作Model进行数据更新
Model 通知Presenter数据发生变化
Presenter 更新View数据
使用:
MVP的实现会根据View的实现而有一些不同,一部分倾向于在View中放置简单的逻辑,在Presenter放置复杂的逻辑;另一部分倾向于在presenter中放置全部的逻辑。这两种分别被称为:Passive View和Superivising Controller。

MVVM

Model-View-ViewModel


MVVM.png

数据关系:
View 接收用户交互请求
View 将请求转交给ViewModel
ViewModel 操作Model数据更新
Model 更新完数据,通知ViewModel数据发生变化
ViewModel 更新View数据
使用:
可以兼容你当下使用的 MVC/MVP 框架。
增加你的应用的可测试性。
配合一个绑定机制效果最好。

2、四大组件

Activity、BroadcastReceiver、Service、ContentProvider

Activity:(活动)

生命周期:
onCreate():每个活动都会重写这份方法,他会在活动第一次创建的时间被调用,可完成初始化操作,加载布局,绑定事件。
onStart():不可见变成可见的时候调用。
onResum():这个方法是在活动准备好和用户进行交互的时候调用。
onPause():这个方法是系统准备去启动或者回复另一个活动的时候调用,用户不可见,这里需要保存一些关键数据。
onStop():这个方法在活动完全不可见的时间调用,被下一个activity覆盖。和onPause()的区别就是,若启动的新活动是个对话框,onPause会执行,onStop不会执行.
onDestory():这个在活动被销毁钱调用,之后变成销毁状态。
onRestart():这个方法在活动停止状态变成运行状态之前调用.onRestart->inStart->onResum
启动模式:
standard:默认启动方式,每次启动都会创建一个新的活动。A启动A,启动一次创建一个。
singleTop:在启动界面时,如果发现该活动位于栈顶,则不会创建新的活动,直接使用它。A启动A,只会创建一个A。当A不位于栈顶时,启动A,则会创建新的A。(点击事件,点击多次,可用用,防止创建多个activity)
singleTask:每次启动活动时,系统首次会在栈中检查是否存在该活动的实例,如果发现已存在,则直接使用该实例,并把这个活动之上的所有活动统统出栈,如果发现没有,则创建新的活动实例。A启动B,B在启动A,B销毁(onDestory()),A重新位于栈顶(onRestart())。(登录界面可以使用)
singleInstance:启动一个新的栈来管理活动。进程间的通讯,别的程序和我们的程序可以共享这个活动。

BroadcastReceiver:(广播)

注册广播的两种方式:
静态注册:
我们需要生成一个类去继承BroadcastReceiver,并复写onReceiver()方法,并且在清单文件中注册Receiver,在<intent-filter>标签中定义action唯一标识属性。
动态注册:
新建一个类继承BroadcastReceiver,重写onReceiver()方法.然后再Activity当中复写onStart()和onStop()方法,在onStart()当中,我们需要构造一个IntentFilter对象,并执行这个对象的addAction方法,参数为action标识符,再执行registerReceiver()方法,参数为广播接收器对象和IntentFilter对象。在onStop()中执行unregisterReceiver()方法,参数为广播接收器对象。
发送广播:
无序广播:
sendBroadcast()
有序广播:
sendOrderedBroadcast()
本地广播:
LocalBroadcastManager来管理广播
注意:
1.广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁
2.广播接收者中不要做一些耗时的工作,否则会弹出Application No Response错误对话框
3.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉
4.耗时的较长的工作最好放在服务中完成

ContentProvider:(内容提供器)

跨程序共享数据功能
访问其他程序:ContentResolver,增删改查,读取联系人功能
创建自己的内容提供器供其他程序使用。继承ContentProvider
清单文件必须注册才能使用

Service(服务)

清单文件必须注册才能使用
1.Context.startService()
onCreate() -> onStartCommand() -> onDestroy()
onCreate()该方法在服务被创建时调用,该方法只会被调用一次
onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStartCommand () 方法会被多次调用。
onDestroy()该方法在服务被终止时调用。
2、Context.bindService()
onCreate() -> onBind() -> onUnbind() -> onDestroy()
onCreate()该方法在服务被创建时调用,该方法只会被调用一次
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法,onBind()方法并不会导致被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。
onDestroy()该方法在服务被终止时调用。
注意:
如果先采用startService()方法启动服务,又调用bindService()方法绑定到服务,必须同时调用stopService()和unbindSetvice(),服务才能停掉。
Service和IntentService的区别是什么?
1.Service在默认情况下将会运行在主线程当中
2.IntentService在收到请求后,将会执行onHandlerIntent方法,该方法运行在workerThread当中
3.Service和IntentService的第二项区别是当Intent收到多次请求时,这些请求将会在消息队列当中排队,依次由onHandlerIntent处理

3、Android的数据存储方式--持久化技术

文件存储、SharedPreference存储、数据库存储
文件存储
存储简单的文本或者二进制数据,流的方式存储
openFileOutput()
openFileInput()
SharedPreference
键值对的方式存储
三种方法获取SharedPreference对象
1.Context类中的getSharedPreference()方法
2.Activity类中的getPreference()方法
3.PreferenceManager类中的getSharedPreference()方法
数据库存储
复杂的数据
SQLite
SQLiteOpenHelper
MMKV
腾讯出的工具 地址:https://github.com/Tencent/MMKV/wiki/android_setup

4、异步消息处理机制--Message、Handler、MessageQueue、Lopper

1.在主线程,创建handler对象.
2.在子线程,数据封装在Message对象中,handler执行发送的动作(发送到handler所在的主线程)
3.在主线程,message对象发送到messagequeue()中,looper调用loop()方法不断监听消息队列,如果有数据,则取出,调用handler和dispatchmessage()方法将消息分发带指定handler中.
4.在主线程,dispatchmessage()方法中,将接收到的message对象交给handlemessage()方法处理.
5.重写handlermeaage()方法,做出实际的动作处理.

5、XML和JSON格式数据解析

XML
Pull
Sax
Dom
JSON
Fastjson(阿里)
Gson(谷歌)
jackson(SpringMVC自带)

6、Intent和PendingIntent的区别

Intent:立即执行某个动作
PendingIntent:在某个合适的时机去执行某个动作,延迟执行的intent

7、三种动画

Drawable Animation(帧动画)
主要涉及类:AnimationDrawable
1、通过 XML 文件实现

<?xml version="1.0" encoding="utf-8"?>
<animation-list 
    android:oneshot="true"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/a_0"
        android:duration="100" />
    <item
        android:drawable="@drawable/a_1"
        android:duration="100" />
    <item
        android:drawable="@drawable/a_2"
        android:duration="100" />
</animation-list>

java代码开启:

ImageView imageview = (ImageView) findViewById(R.id.imageview);
imageview.setImageResource(R.drawable.xml_name);
AnimationDrawable animationDrawable = (AnimationDrawable) imageview.getDrawable();
animationDrawable.start();//animationDrawable.stop();

2、只通过 Java 代码实现

AnimationDrawable animationDrawable = new AnimationDrawable();
int[] mipmaps = new int[]{R.drawable.a_0,R.drawable.a_1,R.drawable.a_2};
for (int i = 0; i < 3; i++) {
    int id=mipmaps[i];
    //或者使用下面方式,注意如果图片资源放在mipmap下时将drawable修改下
    //int id = getResources().getIdentifier("a_" + i, "drawable",getPackageName());
    Drawable drawable = getResources().getDrawable(id);
    animationDrawable.addFrame(drawable, 200);
}
animationDrawable.setOneShot(false);
imageView.setBackgroundDrawable(animationDrawable);
animationDrawable.start();

View Animation(补间动画)使用详解
  补间动画,主要是向View对象设置动画效果,包括AlphaAnimation 、RotateAnimation 、ScaleAnimation 、TranslateAnimation 这4种效果,对应的xml标签分别是alpha、rotate、scale、translate。通过为动画设置初始和终止对应的值,根据插值器和duration计算动画过程中间相应的值实现平滑运动,即设置初始和终止状态,插值器来计算填补初始状态到终止状态间的动画。
使用:
1、设置相应动画效果的起点值、终点值、duration(时长)、Interpolator(加速度)。(注:RotateAnimation还需要设置旋转中心坐标值)
2.Interpolator:插值器,随时间流逝动画路程所应走过的百分比。比如,若设置为LinearInterpolator(匀速),时间过一半则插值器的值是0.5;若设置的是DecelerateInterpolator(加速插值器),时间过一半则插值器的值大于0.5.
实现的方式:(例子,只举例子AlphaAnimation .其它三个,一模一样)
1、通过XML定义

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0"
    android:toAlpha="1"
    android:duration="2000">
    <!--
    fromAlpha 起始透明度 0为完全透明 1为不透明 0~1之间的浮点值
    toAlpha 结束透明度
    duration 动画运行时间 单位毫秒
    -->
</alpha>

Java代码调用:

        AlphaAnimation alphaAnimation=null;
        alphaAnimation= (AlphaAnimation) AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim_alpha);  //加载XML中的动画XML文件
        //常用属性设置  各种动画通用
        alphaAnimation.setRepeatCount(3);//执行动画效果结束后重复执行3次  一共4次
        alphaAnimation.setRepeatMode(Animation.REVERSE);//重复模式
        alphaAnimation.setFillAfter(true);     //动画结束是否停止在最后一帧
        alphaAnimation.setFillBefore(false);    //动画结束是否停止在第一帧
        //设置插值器 动画执行速度  变速 加减速。。
        //AccelerateInterpolator减速
        //DecelerateInterpolator加速
        //LinearInterpolator匀速
        alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
        button.startAnimation(alphaAnimation);  //将动画设置给button

2、只使用Java代码调用

//在代码中定义 动画实例对象
 Animation myAnimation_Alpha=new AlphaAnimation(0.1f, 1.0f);//根据各自的构造方法来初始化一个实例对象
 myAnimation_Alpha.setDuration(5000);//设置时间持续时间为 5000毫秒
 myAnimation_Alpha.set.....  //设置各种属性....
button.startAnimation(myAnimation_Alpha);  //将动画设置给button

roperty Animation(属性动画)
  咳咳.这个动画就太强大了,哀家实力有限,又要放大招了,那就是看别人的,哈哈哈哈~~~
  属性动画可以对任何对象的属性做动画而不仅仅是View,甚至可以没有对象。除了作用对象进行扩展外,属性动画的效果也加强了,不仅能实现View动画的4中效果,还能实现其它多种效果,这些效果都是通过ValuAnimator或ObjectAnimator、AnimatorSet等来实现的。
  ValueAnimator :值动画执行类,常配合AnimatorUpdateListener使用。
  ObjectAnimator :对象动画执行类。继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,不需要设置监听,底层自动完成,一般会用ObjectAnimator来改变某一对象的某一属性.
  实现的方式:
  1、xml

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueFrom="0"
    android:valueTo="300"
    android:valueType="intType"
    android:interpolator="@android:interpolator/overshoot">
    <!--
        valueFrom  起始值
        valueTo    结束值
        valueType  值的类型
        intType整数值、floatType浮点值、colorType颜色值
        interpolator插值器
    -->

java代码调用:

ValueAnimator valueAnimator=null;
        //通过AnimatorInflater.loadAnimator()加载xml 创建ValueAnimator
        valueAnimator= (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator_value);
        //动画执行时间
        valueAnimator.setDuration(3000);
        //值改变监听
        valueAnimator.addUpdateListener(listener);
        //开始动画
        valueAnimator.start();
  ValueAnimator.AnimatorUpdateListener listener=new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
       //获取值
            int value= (int) animation.getAnimatedValue();
       //btnValueAnimator为测试控件
        //设置控件X轴平移
        btnValueAnimator.setTranslationX(value);
        }
    };
</animator>

2、Java代码

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(button,"scaleX",0.5f);//这个构造方法有很多参数,实现各种动画,还可以组合起来
               objectAnimator.setDuration(3000);
               objectAnimator.setStartDelay(1000);
               objectAnimator.start();

推荐链接://www.greatytc.com/p/8076fe970a0c

8、Design的使用

Design控件:Toolbar、CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout、TabLayout、TextInputLayout、NavigationView、FloatingActionButton、Snackbar。
推荐学习链接:https://blog.csdn.net/lavor_zl/article/details/51295364

9、Fragment的生命周期

onAttach() fragment已经关联到activity
onCreate() 系统创建fragment的时候回调他,在他里面实例化一些变量
onCreateView() 第一次使用的时候 fragment会在这上面画一个layout出来 onActivityCreated() 当Activity中的onCreate方法执行完后调用。
onStart() 和activity一致 启动, Fragement 启动时回调, 此时Fragement可见;
onResume() 和activity一致 在activity中运行是可见的
onPause() 和activity一致 其他的activity获得焦点,这个仍然可见
onStop()和activity一致fragment不可见的,
onDestroyView() Fragment中的布局被移除时调用。
onDestroy() 销毁fragment对象
onDetach() Fragment和Activity解除关联的时候调用。

10、清单文件里面的内容包括哪些?

应用程序的包名,该包名作为该应用的唯一标识。
应用包含的组件,如Activity,Service,Broadcastreceiver和ContentProvider.
应用程序使用系统所需的权限声明。
其他程序访问该程序所需的权限声明。

11、如何兼容不同的版本

在使用高于minSdkVersion API level的方法需要:
@TargeApi($API_LEVEL)使可以编译通过, 不建议使用@SuppressLint("NewApi");
运行时判断API level; 仅在足够高,有此方法的API level系统中,调用此方法;
保证功能完整性,保证低API版本通过其他方法提供功能实现。

12、如何配置第三方的sdk

1、依赖注入
2、导入moudle

13、fragment的切换方式

如果用replace()就会每次都初始化Fragment
正确的切换方式是add(),切换时hide()add()另一个Fragment;再次切换时,只需hide()当前,show()另一个。
这样就能做到多个Fragment切换不重新实例化

14、点击事件的分发机制

首先会手势在屏幕上传递事件,会先走到最外层的布局的dispatchTouchEvent--》然后通过onInterceptTouchEvent的返回值,判断是否拦截,
如果拦截,就不走子视图当中的事件响应了,而执行自己的onTouchEvent方法,
如果不拦截,就会走子视图dispatchTouchEvent--onTouch--onTouchEvent方法,如果onTouchEvent的返回值为true,那么这个事件此子视图负责消费,否则就会回传到上一视图的onTouchEvent当中来处理,
如果上一视图返回为true,则其消费,否则事件回收不做处理。
onTouchListener当中的onTouch方法里,判断返回值,然后决定是否执行onTouchEvent方法,然后在onTouchEvent方法的ACTION_DOWN操作中通过判断时间和标志位,决定是否执行onLongClickListener当中onLongClick操作,然后在onLongClick方法中通过判断返回值,来确定onClickListeneronClick方法是否会执行,如果返回false,都能执行,如果返回trueonClick不执行。

15、消息推送原理以及实现过程

客户端和服务器一直保持长链接
推荐链接://www.greatytc.com/p/da4529fd4675

16、map集合的存储原理

通过键值对的方式进行存取数据的

17、自定义View的只要重写的方法名有哪些?

有三个构造方法(一个参数、两个参数、三个参数),其中两个参数的构造方法必须有。
onDraw()方法必须有,是用来绘制View图像的
如果要改变View 的大小,需要重写onMeasure()方法。
如果要改变View在父控件中的位置,需要重写onLayout()方法

18、Alipay的支付流程?

支付宝支付流程.png

19、怎么让viewpager不滑动?

大致就是重写ViewPager,覆盖ViewPager的onInterceptTouchEvent(MotionEvent arg0)方法和onTouchEvent(MotionEvent arg0)方法,这两个方法的返回值都是boolean类型的,只需要将返回值改为false,那么ViewPager就不会消耗掉手指滑动的事件了,转而传递给上层View去处理或者该事件就直接终止了。

20、如何避免内存泄露(造成内存泄漏的原因)?

资源对象没关闭造成的内存泄漏,如查询数据库后没有关闭游标cursor
构造Adapter时,没有使用 convertView 重用
Bitmap对象不在使用时调用recycle()释放内存

21、下拉刷新的实现?

1.原生的SwipeRefreshLayout
设置监听,写onRefresh()方法,然后设置setrefreshing(true),刷新完之后设置成false.
2.第三方框架. PullToRefresh.
在布局文件中添加PullToRefresh控件,比如PullToRefreshListView; 在Activity中,设置监听器OnRefreshListener以响应用户下拉操作; 在监听器的onRefresh()方法中执行数据刷新操作,可以通过AsyncTask来实现; 在AsyncTask中获取到数据后,记得调用onRefreshComplete()方法通知PullToRefresh控件数据已获取完毕,可以结束刷新操作。

22、侧滑菜单的实现?(抽屉效果)

1.DrawerLayout.
第一个控件是主题内容,第二个控件是侧滑菜单内容.
与toolbar连用,使用开关.ActionBarDraweerTohhle.
2.SlidingPaneLayout
第一个控件为左侧侧滑菜单,第二个为主题内容
Toolbar和SlidingPaneLayout不能够直接相互配合使用,要通过actionbar和slidingpaneLayout的监听事件才能联动起来

23、java虚拟机jvm和android虚拟机Dalvik的区别?

java虚拟机:
java虚拟机运行的是java字节码。(java类会被编译成一个或多个字节码.class文件,打包到.jar文件中,java虚拟机从相应的.class文件和.jar文件中获取相应的字节码)
android虚拟机:
Dalvik运行的是自定义的.dex字节码格式。(java类被编译成.class文件后,会通过一个dx工具将所有的.class文件转换成一个.dex文件,然后dalvik虚拟机会从其中读取指令和数据)

24、Java当中的加密解密技术?

1、md5加密,该加密算法是单向加密,即加密的数据不能再通过解密还原。保证数据的完整性.相关类包含在java.security.MessageDigest包中。
2、DES加密,该加密算法是可逆的,解密方可以通过与加密方约定的密钥匙进行解密。相关类包含在javax.crypto.*包中。
3、base64编码,是用于传输8bit字节代码最常用的编码方式。相关类在sun.misc.BASE64Decoder 和sun.misc.BASE64Encoder 中。
4、URLEncoder编码,是一种字符编码,保证被传送的参数由遵循规范的文本组成。相关类在java.net.URLEncoder包中。
5.RSA. 公钥加密,私钥加密.互为加解密,自己不可以解密
非对称加密
6. Sign:摘要算法+不对称加密算法
保证数据的安全性,用对方的公钥加密,发送成功后,用对方的私钥解密

25、屏幕适配的方法

屏幕适配.png

推荐文章:https://blog.csdn.net/wangwangli6/article/details/63258270/

26、图片的三级缓存

内存缓存,优先加载,速度最快
本地缓存,次优先加载,速度快
网络加载,不优先加载,速度慢,浪费流量
原理:

图片缓存流程.png

推荐链接://www.greatytc.com/p/2cd59a79ed4a

27、适配全面屏

1、App AndroidManifest的Application标签下面增加下面一段代码:
<meta-data android:name="android.max_aspect" android:value="2.1" />
2、更换部分被拉伸的图片资源文件(相对布局采用XML的方式,或者.9图的解决方案)
3、布局文件的优化建议(使用百分比布局)

28、AIDL的使用

全名:Android Interface Definition Language
作用:为了实现进程间通信.
   这个对我来说,用的很少,但是面试的时候会被问到,主要是实现了进程间的通信问题,一般一项目,一个进程,除非业务逻辑比较多,运行内存不够用的情况下,会使用AIDL.总体来说,主要是通过,定义接口的形式来实现,客户端服务端的数据交互,下面的链接,跟着敲一遍,基本上就明白啥事了.
推荐地址:https://github.com/leavesC/AIDLSamples

29、视频的相关内容

1、使用第三方库ijkPlayer。github地址:https://github.com/bilibili/ijkplayer,这是一个解码器,配合surfaceView可以播放视频,然后界面上的进度条,暂停,开始,声音等等功能,还是需要自己的去写的。
2、我没做过视频的项目,了解不是很深。推荐一个比较好的第三方库,https://github.com/jiajunhui/PlayerBase,这个视频做的挺好的,功能很齐全。

Git部分

1、常用的git命令
2、git冲突的产生原因以及解决?
3、如何避免冲突?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 所有知识点已整理成app app下载地址 J2EE 部分: 1.Switch能否用string做参数? 在 Jav...
    侯蛋蛋_阅读 2,410评论 1 4
  • 一 Activity 1 Activity 生命周期 1.1 Activity 的四种状态 running 当前...
    _执_念__阅读 10,284评论 0 91
  • 1,java 接口的意义: 规范,扩展,回调 规范:比如,有两个及上的的类拥有相同的方法,但是实现功能不一样,就可...
    漫唐阅读 958评论 0 6
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,089评论 1 32
  • java 接口的意义-百度 规范、扩展、回调 抽象类的意义-乐视 为其子类提供一个公共的类型封装子类中得重复内容定...
    交流电1582阅读 2,209评论 0 11