# 阿里飞猪

💣 过程简述

阿里的面试也挺满意的。但是当时我的 Github 上有太多不成熟的项目,让面试官觉得我的代码能力或者协同合作的能力一般,最终没有面试成功。

  1. 自我介绍

  2. 问项目相关的。第一个项目,一个做还是团队?练手的还是可以商用的?你做了其中的哪几个部分?给我讲一下,然后看一下代码的风格;

  3. 第二个项目,这个其中的文章是通过 url 打开 webview 实现的吗?介绍其中用到的框架?为什么要用这些网络框架,不用自带的网络请求方式?网络框架这么多,为什么选用这个框架?

  4. Glide 框架你了解多少,大概是怎么实现的?缓存机制有几级缓存?

    Glide 的缓存机制分为 2 种缓存,一种是内存缓存,一种是磁盘内存。

    用内存缓存的原因是:防止应用重复将图片读入到内存中,造成内存资源浪费;

    用内存缓存的原因是:防止应用重复的从网络或者其它地方下载和读取数据;

    缓存机制中有三级缓存原理

    读取一张图片的时候,获取顺序:Lru 算法缓存\rightarrow 弱引用缓存\rightarrow 磁盘缓存(如果设置了)。

    当想要加载某些图片的时候,先去 LruCache 中寻找图片,如果 LruCache 中有图片,就直接取出来用,并将图片放入到 WeakReference 中,如果 LruCache 中没有,则去 WeakReference中 寻找,如果 WeakReference 中有,就从 WeakReference 中取出图片使用,如果 WeakReference 中没有图片,那么就从磁盘缓存/网络中加载图片。

  5. 如果有一张 100M 的图片,直接打开肯定会造成 OOM,那么要怎么实现才能打开?

    得将该图片进行压缩,可以使用BitmapFactory这个类。首先,获取远图片的大小(这里是 100M),然后获取要显示这个图片的控件比如ImageView的大小,然后可以计算出图片和控件的比例,根据这一比例,将图片压缩为适合显示的大小。

  6. 第三个项目,介绍一个。其中的生成二维码是在端生成吗?

  7. Activity 的生命周期。假设一个场景,用户按 Home 键回到桌面后,在后台久了之后点击 icon 打开这个应用,这个 Activity 已经被杀掉,那么打开应用后怎么重新恢复到杀掉前的 Activity?

    Android 系统的回收机制提供了onSaveInstanceState(Bundle outState)onRestoreInstanceState(Bundle savedInstanceState)方法用于保存和恢复数据。

    这两个方法主要会在 Activity 被系统回收,又重新创建了一个新的 Activity 的时候调用,可能是以下几种情况:

    1. 当用户按下 HOME 键时
    2. 按下电源锁屏键
    3. 从最近应用中运行其它程序
    4. 从当前 Activity 启动一个新的 Activity
    5. 屏幕方向切换(竖屏切横屏或者横屏切竖屏)

    异常生命周期大概如下:

    1. 当 Activity 被系统自动回收时,onPause()\rightarrowonSaveInstanceState()\rightarrowonStop()\rightarrowonDestory()\rightarrowonCreate()\rightarrowonStart()\rightarrowonRestoreInstanceState()\rightarrowonResume()
    2. 当 Activity 是用户主动销毁,比如按下 back 键或者调用finish()方法的话,就不会在onPause()onStop()方法中调用onSaveInstanceState()方法,所以就是onCreate()\rightarrowonStart()\rightarrowonRestoreInstanceState()方法重新创建 Activty,其中恢复数据是用onRestoreInstanceState()方法中的Bundle参数恢复。
  8. 关于 RecyclerView,假设一个场景,如果 item 有不同的类别从而要显示不同的样式,怎么显示?

    RecyclerViewAdapter要继承RecyclerView.Adapter<ViewHolder>这个类,重写三个方法:onCreateViewHolder(ViewGroup parent, int viewType)onBindViewHolder(ViewHolder holder, int position)getItemCount()这三个方法,其中的onCreateViewHolder中可以根据viewType的类型去加载不同的布局。

  9. 有没有写过自定义 View?

    自定义 View 要实现三个方法,按照执行顺序依次是onMeasure()\rightarrowonLayout()\rightarrowonDraw()。其中,onDraw()方法必须要重写,因为这个方法是用来绘制 View 图像的。如果要改变 View 的大小,就重写onMeasure()方法;如果要改变 View 在父控件中的位置,就要重写onLayout()方法。

  10. publicprotectedprivate的区别

    public可以被其它任何类访问;private只能自己访问和自己内部的成员访问;protected就是自身、子类和同一个包中的类都可以访问;默认就是同一个包中的类都可以访问。

  11. 接口和抽象类的异同?让一个类不能被其它类继承怎么做?

    • 接口中的方法都是抽象的,抽象类中可以有抽象方法也可以有非抽象方法
    • 类可以实现多个接口,但只能继承一个抽象类
    • Java 接口声明的变量默认都是final
    • 如果一个类不实现抽象类或者接口中的全部方法,那么它必须也是抽象的;反之,它必须实现所有方法
    • 接口和抽象类都不能实例化
  12. 有用过 final 修饰吗?final 能修饰类吗?

    • final修饰类表示此类不能被继承,不能拥有自己的子类
    • final修饰方法表示此方法不能重写
    • final修饰变量表示一旦定义并在首次为其显示初始化之后,final修饰的变量值就不可被改变
  13. 介绍一下 Java 的引用