温故而知新:周末复习一下 Android & Java 面试题

温故而知新:周末复习一下 Android & Java 面试题

安逸久了就容易迷失方向,多看看高质量的面试题找找差距,然后查漏补缺!周末再来复习一下,巩固基础和技术知识。

1. 谈谈冷启动与热启动

app冷启动:

当应用启动时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就叫做冷启动((后台不存在该应用进程) 冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

app热启动:

当应用已经被打开,但是被按下返回键、Home键等按键时回到桌面或者是其他程序的时候,再重新打开该app时,这个方式叫做热启动(后台已经存在该应用进程)。

热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application。

冷启动的流程

当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentViewmeasure/layout/draw显示在界面上。

冷启动的生命周期简要流程:

Application构造方法
–> attachBaseContext()
–> onCreate
–> Activity构造方法
–> onCreate()
–> 配置主体中的背景等操作
–> onStart()
–> onResume()
–> 测量、布局、绘制显示

冷启动的优化

主要是视觉上的优化,解决白屏问题,提高用户体验,所以通过上面冷启动的过程。能做的优化如下:

1) 减少 onCreate()方法的工作量
2) 不要让 Application 参与业务的操作
3) 不要在 Application 进行耗时操作
4) 不要以静态变量的方式在 Application 保存数据
5) 减少布局的复杂度和层级
6) 减少主线程耗时

2. XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?

XML文档定义分为DTDSchema两种形式;二者都是对XML语法的约束,其本质区别在于Schema本身也是一个XML文件,可以被XML解析器解析,而且可以为XML承载的数据定义类型,约束能力较之DTD更强大。

对XML的解析主要有:

DOM(文档对象模型,Document Object Model)、SAX(Simple API for XML)和StAX(Java 6中引入的新的解析XML的方式,Streaming API for XML),其中DOM处理大型文件时其性能下降的非常厉害,这个问题是由DOM树结构占用的内存较多造成的,而且DOM解析方式必须在解析文件之前把整个文档装入内存,适合对XML的随机访问(典型的用空间换取时间的策略);

SAX是事件驱动型的XML解析方式,它顺序读取XML文件,不需要一次全部装载整个文件。

当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过事件回调代码来处理XML文件,适合对XML的顺序访问;顾名思义,StAX把重点放在流上,实际上StAX与其他解析方式的本质区别就在于应用程序能够把XML作为一个事件流来处理。

将XML作为一组事件来处理的想法并不新颖(SAX就是这样做的),但不同之处在于StAX允许应用程序代码把这些事件逐个拉出来,而不用提供在解析器方便时从解析器中接收事件的处理程序。

3. Java nio 和 io 的区别

1)Java NIO提供了与标准IO不同的IO工作方式:

  • Channels and Buffers(通道和缓冲区):
    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
  • Asynchronous IO(异步IO):
    Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似
  • Selectors(选择器):
    Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

2)阻塞IO和非阻塞IO

  • Java IO流都是阻塞的,这意味着,当一条线程执行read()或者write()方法时,这条线程会一直阻塞直到读取到了一些数据或者要写出去的数据已经全部写出,在这期间这条线程不能做任何其他的事情。
  • java NIO的非阻塞模式(Java NIO有阻塞模式和非阻塞模式,阻塞模式的NIO除了使用Buffer存储数据外和IO基本没有区别)允许一条线程从channel中读取数据,通过返回值来判断buffer中是否有数据,如果没有数据,NIO不会阻塞,因为不阻塞这条线程就可以去做其他的事情,过一段时间再回来判断一下有没有数据。NIO的写也是一样的,一条线程将buffer中的数据写入channel,它不会等待数据全部写完才会返回,而是调用完write()方法就会继续向下执行

3)面向流与面向缓冲

Java IO和NIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。

此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。

4. String 为什么要设计成不可变的

1)字符串池的需求字符串池是方法区(Method Area)中的一块特殊的存储区域。当一个字符串已经被创建并且该字符串在池中,该字符串的引用会立即返回给变量,而不是重新创建一个字符串再将引用返回给变量。如果字符串不是不可变的,那么改变一个引用(如: string2)的字符串将会导致另一个引用(如: string1)出现脏数据。

2)允许字符串缓存哈希码在 java 中常常会用到字符串的哈希码,例如:HashMap 。String 的不变性保证哈希码始终一,因此,他可以不用担心变化的出现。这种方法意味着不必每次使用时都重新计算一次哈希码——这样,效率会高很多。

3)安全 String 广泛的用于 java 类中的参数,如:网络连接(Network connetion),打开文件(opening files )等等。如果 String 不是不可变的,网络连接、文件将会被改变——这将会导致一系列的安全威协。操作的方法本以为连接上了一台机器,但实际上却不是。由于反射中的参数都是字符串,同样,也会引起一系列的安全问题。

5. HashMap 排序

已知一个 HashMap<Integer,User>集合, User 有 name(String)和 age(int)属性。请写一个方法实现对HashMap的排序功能,要求对HashMap中的User的age倒序进行排序。

Tips:

HashMap 本身就是不可排序的,但是该道题偏偏让给HashMap排序,那我们就得想在API 中有没有这样的Map 结构是有序的,LinkedHashMap,对,就是他,他是Map 结构,也是链表结构,有序的,更可喜的是他是HashMap 的子类,我们返回LinkedHashMap<Integer,User>即可。

但凡是对集合的操作,我们应该保持一个原则就是能用JDK中的API就用JDK中的API,比如排序算法我们不应该去用冒泡或者选择 , 而 是首先想到用 Collections 集合工具类 。

public class HashMapTest {
  public static void main(String[] args) {
    HashMap<Integer, User> users = new HashMap<>();
    users.put(1, new User("张三", 25));
    users.put(3, new User("李四", 22));
    users.put(2, new User("王五", 28));
    System.out.println(users);

    HashMap<Integer,User> sortHashMap = sortHashMap(users);
    System.out.println(sortHashMap);

    /**
    * 控制台输出内容
    * {1=User [name=张三, age=25], 2=User [name=王五, age=28], 3=User [name=李四, age=22]}
    * {2=User [name=王五, age=28], 1=User [name=张三, age=25], 3=User [name=李四, age=22]}
    */ 
  }

  public static HashMap<Integer, User> sortHashMap(HashMap<Integer, User> map) {
    // 首先拿到 map 的键值对集合
    Set<Entry<Integer, User>> entrySet = map.entrySet();
    // 将 set 集合转为 List 集合,为什么,为了使用工具类的排序方法
    List<Entry<Integer, User>> list = new ArrayList<Entry<Integer, User>>(entrySet);

    // 使用 Collections 集合工具类对 list 进行排序,排序规则使用匿名内部类来实现
    Collections.sort(list, new Comparator<Entry<Integer, User>>() {
      @Override 
      public int compare(Entry<Integer, User> o1, Entry<Integer, User> o2) {
        //按照要求根据 User 的 age 的倒序进行排
        return o2.getValue().getAge()-o1.getValue().getAge();
      }
    });
    //创建一个新的有序的 HashMap 子类的集合
    LinkedHashMap<Integer, User> linkedHashMap = new LinkedHashMap<Integer, User>();
    //将 List 中的数据存储在 LinkedHashMap 中
    for(Entry<Integer, User> entry : list){
      linkedHashMap.put(entry.getKey(), entry.getValue());
    }

    return linkedHashMap;
  }
}

文末

有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

想要成长为一个移动互联网架构师,一些技能是必不可少的,小编自己在一些平台收集到了许多学习资料和个人总结的一些经验,一线互联网公司得面试经历面试题在这里分享给大家,包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术还有相关的面试专题PDF;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

加我wx:X1524478394 (或者技术qun:887084983)免费领取Android高阶学习视频和BAT面试专题PDF

温故而知新:周末复习一下 Android & Java 面试题

相关学习清单:

  • AES加密让你的应用牢不可破
  • Android进阶必学-retrofit源码解析
  • Android平台人工智能实现人脸识别
  • BAT面试必问一跨线程通信框架内核揭秘
  • Gradle到底怎么了效率如何提高
  • Handler源码讲解
  • HashMap源码解析hook源码实现阿里无闪烁换肤
  • 表情包大战一-Glide 显示Gif性能优化实战
  • 架构技术演进
  • 揭秘Android开发效率提升十倍的利器
  • 面对应用层出不穷的第三方SDK,架构师该怎么做?
  • 人工智能身分证识别
  • **高阶学习视频
  • 性能优化之数据优化一小时实现基于android的人脸追踪技术
  • 移动互联架构
  • Android App全方位性能调优.xmind
  • Android前沿技术.xmind
  • App开发框架知识体系(APP亦对象) .xmind
  • Java语言进阶与Android相关技术内核xmind
  • 高级进阶必备篇:xmind
  • BAT面试题集及答案.docx
  • 微信小程序与Hybrid混合开发.xmind
  • 移动互联网开发课程大纲.png
  • 移动互联网课程大纲.xmind

专注分享大型Bat面试知识,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢在关注一下~

猜你喜欢

转载自blog.51cto.com/14332859/2451107