面试准备记录(个人草稿)

176 阅读9分钟

沉住气,拉长战线,合理安排时间,从易到难,Fighting!q(≧▽≦q)

20160315162049_KQFY3.jpeg

  1. 准备,修缮简历

  2. 安卓中级知识点:

    高优先级:

    Android基础知识,

    音视频部分知识,

    OS framework,

    Kotlin,

    自定义控件,

    动画,

    低优先级:

    系统保活,

    git命令,

    布局,

    屏幕分辨率兼容,

    apk瘦身,

    设计模式,

    封装sdk

  3. 必看进阶:

    Java基础:

     hashMap,数据结构相关,例如Hashmap sparearray arraymap的选择
    
    1. 抽象类和接口的区别:

      总结:

      1. 对类而言,抽象类只能继承一次,但可以实现多个接口

      2. 接口不存在方法的实现,抽象类可以实现方法,抽象类中如果有未实现的抽象方法,那么子类也需要定义为抽象类。抽象类中可以有非抽象方法。*

      3. 接口中的变量必须用public static final修饰,而且需要给出初始值。

      ​ 接口中的方法默认是public abstract,只能为这个类型,不能是static,接口的方法不允许子 类的覆写,抽象类中允许有static方法。*


      ps:接口更像是契约,一旦使用必须实现接口中所定义的方法(代价),抽象类更像是一种能力or工具,他身上可以有多个接口(契约)和方法实现(功能)

    2. String:

      String 被声明为final,因此他不可被继承,不可变。(Integer等包装类也不能被继承)

      Java8中,String 内部使用Char数组存储数据

      Java9后,String实现改用byte数组存储字符串,添加了coder来表示使用了哪种编码。

      public final class String
          implements java.io.Serializable, Comparable<String>, CharSequence {
          /** The value is used for character storage. */
          private final byte[] value;
      
          /** The identifier of the encoding used to encode the bytes in {@code value}. */
          private final byte coder;
      }
      
      

      不可变的优点:

      1. 可以作为hash值缓存,因为不可变,所以可以用作hashMap的key,只需要做一次计算
      2. String Pool的需要,只有String是不可变的,才可能使用String Pool。
      3. 安全性,参数不可变
      4. 线程安全,不可变天生具备线程安全,可以在多个线程中安全使用。
    3. String,StringBuffer,StringBuilder:

      1. 可变性:

        String不可变, StringBuffer和StringBuilder可变。

      2. 线程安全

        String不可变,因此是线程安全的。

        StringBuilder不是线程安全的,效率高。

        StringBuffer是线程安全,效率低,内部使用synchronized同步。

image-20210517222312712.png 4. ### 关键字:

  #### **final**

  声明数据为常量,声明的方法不能被子类重写(private方法隐式的被指定为final),声明的类不允许被继承。

  **static**

  · 数据为静态变量或实力变量,静态变量又被称为类变量,类中所有实例都共享静态变量,    可以直接通过类名访问。每创建一个实例就会产生一个实例变量。它与该实例同生共死。

  · 方法为静态方法,必须有实现,不能是抽象方法。只能访问所属类的静态字段和静态方法。

  · 静态语句块,初始化时运行一次:

  ```java
  public class A {
      static {
          System.out.println("123");
      }
  
      public static void main(String[] args) {
          A a1 = new A();
          A a2 = new A();
      }
  }
  
  123
  ```

  · 静态内部类,不能访问外部类的非静态的变量和方法。

  · 静态导包

4. ### clone:

  浅拷贝:拷贝对象和原始对象的引用类型引用同一个对象

  深拷贝:拷贝对象和原始对象的引用类型引用不同对象

4. ### 反射:

  每个类都有一个   **Class**   对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。

  类加载相当于 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用 `Class.forName("com.mysql.jdbc.Driver")` 这种方式来控制类的加载,该方法会返回一个 Class 对象。

  反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。

  Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect 类库主要包含了以下三个类:

  - **Field**  :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段;
  - **Method**  :可以使用 invoke() 方法调用与 Method 对象关联的方法;
  - **Constructor**  :可以用 Constructor 的 newInstance() 创建新的对象。

  **反射的优点:**

  - ```
    **可扩展性**   :应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。
    ```

  - ```
    **类浏览器和可视化开发环境**   :一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。
    ```

  - ```
    **调试器和测试工具**   : 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。
    ```

  **反射的缺点:**

  尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。

  - ```
    **性能开销**   :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
    ```

  - ```
    **安全限制**   :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。
    ```

  - ```
    **内部暴露**   :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
    ```

    摘自:
    
  - [Blog/笔试面试/Android高级工程师面试必备/Java/基础](https://github.com/yangkun19921001/Blog/blob/master/%E7%AC%94%E8%AF%95%E9%9D%A2%E8%AF%95/Android%E9%AB%98%E7%BA%A7%E5%B7%A5%E7%A8%8B%E5%B8%88%E9%9D%A2%E8%AF%95%E5%BF%85%E5%A4%87/Java/%E5%9F%BA%E7%A1%80.md)
  
  - [深入解析 Java 反射(1)- 基础](http://www.sczyh30.com/posts/Java/java-reflection-1/)
  
    ------
  
    #### **JAVA面试题:**
  
    1. ## Java里面有`==`运算符了,为什么还需要equals啊?
  
       equals()的作用是用来判断两个对象是否相等:
  
       ```java
       public boolean equals(Object obj) {
           return (this == obj);
       }
       ```
  
       equals等价于`==`,而`==`运算符是判断两个对象是不是同一个对象,即他们的**地址是否相等**。而覆写equals更多的是追求两个对象在**逻辑上的相等**,你可以说是**值相等**,也可说是**内容相等**。
       
    2. ## 那么你知道覆写equals时有哪些准则?
    
       > **自反性**:对于任何非空引用值 x,x.equals(x) 都应返回 true。
    
       > **对称性**:对于任何非空引用值 xy,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
    
       > **传递性**:对于任何非空引用值 xy 和 z,如果 x.equals(y) 返回 true, 并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
    
       > **一致性**:对于任何非空引用值 xy,多次调用 x.equals(y) 始终返回 true 或始终返回 false, 前提是对象上 equals 比较中所用的信息没有被修改。
    
       > **非空性**:对于任何非空引用值 x,x.equals(null) 都应返回 false。
       
        一般在覆写equals**只兼容同类型的变量**
       
    3. ## Java中的String有没有长度限制?
    
       这个问题要分两个阶段看,分别是 **编译期** 和 **运行期**。不同的时期限制不一样。
    
       **编译期**字符串在class字节码文件中是以**CONSTANT_urf8_info**格式存储的
    
       ```java
       CONSTANT_urf8_info {
           u1  tag;
           u2  length;
           u1 bytes[length];
       }
       ```
    
       bytes的最大长度为2^16=65536,但是需要两个字节保存null,所以为2^16-2=65534个字节。
    
       **运行期** String内部是以char数组的**value**存储的。数组的长度是int类型的 **count**
    
       那么String允许的最大长度就是Integer.MAX_VALUE(2147483647) 了。java中一个char占2个字节,也就是16位。
    
       因此运行时大概需要约4GB的内存才能存储最大长度的字符串。
    
    4. ## 为什么使用 Long 时,大家推荐多使用 valueOf 方法,少使用 parseLong 方法
    
       答:因为 Long 本身有缓存机制,缓存了 -128127 范围内的 Long,valueOf 方法会从缓存中去拿值,如果命中缓存,会减少资源的开销,parseLong 方法就没有这个机制。

JVM

Android基础,

Java数据结构源码,

Android系统源码:

时间不够的话重点看 View绘制,Binder机制

  1. View绘制
  2. Binder机制:参考activity启动

Android三方库源码,

算法题库,

Android性能优化,

  1. 网络相关:

    GET和POST的区别 :总结,get请求方式“幂等”(即没有副作用),post请求方式为“非幂等”

“GET的语义是请求获取指定的资源。GET方法是安全、幂等、可缓存的(除非有 Cache- ControlHeader 的约束),GET方法的报文主体没有任何语义。
POST的语义是根据请求负荷(报文主体)对指定的资源做出处理,具体的处理方式视资源类型而不同。 POST不安全,不幂等,(大部分实现)不可缓存。为了针对其不可缓存性,有一系列的方法来进行优化, 还是举一个通俗栗子吧,在微博这个场景里,GET的语义会被用在 「看看我的Timeline上最新的20 条微博」这样的场景,而POST的语义会被用在「发微博、评论、点赞」这样 的场景中。”

摘自:www.zhihu.com/question/28…

每次更新这个博客都是我学习各种面试题的时候,每次打开都感觉要学的东西好多啊,但是不能放弃,加油吧