详谈字节跳动2020年Android开发岗社招真题,看看你能走到哪一步?

237 阅读6分钟

首先说一下,今日头条的面试主要分为三轮到四轮,如果是旺季面三轮,首先是基础面试,基本面试一般10个题左右,最近面试了一下字节跳动的移动Android资深工程师记录下博客

现在网络疯传都2020年了,Android开发早凉了!是真的吗?我相信很多朋友对职业规划很迷茫!

推荐阅读:(2020年Android开发人员打破寒冬期的利器在哪里?是转行还是进阶?

这篇文档会帮你在迷茫中指明方向!

第一面(面经)

1、请你编程实现单例模式,懒汉和饱汉写法?

2、请编程实现Java的生产者-消费者模型

3、HashMap的内部结构? 内部原理?

4、请简述Android事件传递机制, ACTION_CANCEL事件何时触发?

5、Android的进程间通信,Liunx操作系统的进程间通信。

6、JVM虚拟机内存结构,以及它们的作用。

7、简述Android的View绘制流程,Android的wrap_content是如何计算的?

8、有一个整形数组,包含正数和负数,然后要求把数组内的所有负数移至正数的左边,且保证相对位置不变,要求时间复杂度为O(n), 空间复杂度为O(1)。例如,{10, -2, 5, 8, -4, 2, -3, 7, 12, -88, -23, 35}变化后是{-2, -4,-3, -88, -23,5, 8 ,10, 2, 7, 12, 35}

第一面是北京的开发进行视频面试,有理论和编程题组成。用的是在线编程工具,如下图。

第一面(解析)

1、请你编程实现单例模式,懒汉和饱汉写法?

//饱汉写法public static Singleton getInstance() {  
        if (singleton == null) {    
            synchronized (Singleton.class) {    
               if (singleton == null) {    
                  singleton = new Singleton();   
               }    
            }    
        }    
        return singleton;   
    }   //懒汉写法
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    } 123456789101112131415161718

2、请编程实现Java的生产者-消费者模型

看到这个有点懵逼,要是大学毕业的时候写这个肯定没问题,这都工作多年,这也只能按照自己的思路写了。这里使用synchronized锁以及wait notify实现一个比较简单的

import java.io.IOException;public class WaitAndNotify{
    public static void main(String[] args) throws IOException
    {
        Person person = new Person();        new Thread(new Consumer("消费者一", person)).start();        new Thread(new Consumer("消费者二", person)).start();        new Thread(new Consumer("消费者三", person)).start();        new Thread(new Producer("生产者一", person)).start();        new Thread(new Producer("生产者一", person)).start();        new Thread(new Producer("生产者一", person)).start();

    }
}

class Producer implements Runnable
{    private Person person;    private String producerName;    public Producer(String producerName, Person person)
    {        this.producerName = producerName;        this.person = person;
    }    @Override
    public void run()
    {        while (true)
        {            try
            {
                person.produce();
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }

}

class Consumer implements Runnable
{    private Person person;    private String consumerName;    public Consumer(String consumerName, Person person)
    {        this.consumerName = consumerName;        this.person = person;
    }    @Override
    public void run()
    {        try
        {
            person.consume();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }

}

class Person
{    private int foodNum = 0;    private Object synObj = new Object();    private final int MAX_NUM = 5;    public void produce() throws InterruptedException
    {        synchronized (synObj)
        {            while (foodNum == 5)
            {
                System.out.println("box is full,size = " + foodNum);
                synObj.wait();
            }
            foodNum++;
            System.out.println("produce success foodNum = " + foodNum);
            synObj.notifyAll();
        }

    }    public void consume() throws InterruptedException
    {        synchronized (synObj)
        {            while (foodNum == 0)
            {
                System.out.println("box is empty,size = " + foodNum);
                synObj.wait();
            }
            foodNum--;
            System.out.println("consume success foodNum = " + foodNum);
            synObj.notifyAll();
        }

    }
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112

3、HashMap的内部结构? 内部原理?

关于HashMap的问题,不再详述,这方面的资料也挺多,不多需要注意的是Java1.71.8版本HashMap内部结构的区别

4、请简述Android事件传递机制, ACTION_CANCEL事件何时触发?

关于第一个问题,不做任何解释,书籍资料上都会介绍的

关于ACTION_CANCEL何时被触发?系统文档有这么一种使用场景:

在设计设置页面的滑动开关时,如果不监听ACTION_CANCEL,在滑动到中间时,如果你手指上下移动,就是移动到开关控件之外,则此时会触发ACTION_CANCEL,而不是ACTION_UP,造成开关的按钮停顿在中间位置。

意思是当滑动的时候就会触发,不知道大家搞没搞过微信的长按录音,有一种状态是“松开手指,取消发送”,这时候就会触发ACTION_CANCEL。

5、Android的进程间通信,Liunx操作系统的进程间通信。

关于这个问题也是被问的很多,此处也不做解释。

6、JVM虚拟机内存结构,以及它们的作用。

这个问题也比较基础,JVM的内存结构如下图所示

7、简述Android的View绘制流程,Android的wrap_content是如何计算的?

8、有一个整形数组,包含正数和负数,然后要求把数组内的所有负数移至正数的左边,且保证相对位置不变,要求时间复杂度为O(n), 空间复杂度为O(1)。例如,{10, -2, 5, 8, -4, 2, -3, 7, 12, -88, -23, 35}变化后是{-2, -4,-3, -88, -23,5, 8 ,10, 2, 7, 12, 35}

要实现上面的效果有两种方式:

  • **第一种:**两个变量,一个用来记录当前的遍历点,一个用来记录最左边的负数在数组中的索引值。然后遍历整个数组,遇到负数将其与负数后面的数进行交换,遍历结束,即可实现负数在左,正数在右。

  • **第二种:**两个变量记录左右节点,两边分别开始遍历。左边的节点遇到负值继续前进,遇到正值停止。右边的节点正好相反。然后将左右节点的只进行交换,然后再开始遍历直至左右节点相遇。这种方式的时间复杂度是O(n).空间复杂度为O(1)

    //方法1 public void setParted(int[] a){
    int temp=0;
    int border=-1;

        for(int i=0;i<a.length;i++){  
            if(a[i]<0){  
                temp=a[i];  
                a[i]=a[border+1];  
                a[border+1]=temp;  
                border++;  
            }  
        }  
        for(int j=0;j<a.length;j++){  
            System.out.println(a[j]);  
        }  
    }  
    

    //方法2public void setParted1(int[] a,int left,int right){
    if(left>=right||left==a.length||right==0){
    for(int i=0;i<a.length;i++){
    System.out.println(a[i]);
    }
    return ;
    }
    while(a[left]<0){
    left++;
    }
    while(a[right]>=0){
    right--;
    }
    if(left>=right||left==a.length||right==0){
    for(int i=0;i<a.length;i++){
    System.out.println(a[i]);
    }
    return;
    }
    swap(a,left,right);
    left++;
    right--;
    setParted1(a,left,right);
    }
    private void swap(int a[],int left,int right){
    int temp=0;
    temp=a[left];
    a[left]=a[right];
    a[right]=temp;
    }
    public static void main(String[] args) {
    int a[]={1,2,-1,-5,-6,7,-7,-10};
    new PartTest().setParted1(a,0,a.length-1);
    } 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253

显然,第二种实现的难点比较高,不过只要此种满足条件。

面试题和答案解析全部已经被我整理成PDF

近期需要面试的小伙伴建议阅读:(Android程序员如何在面试中更胜一筹?)

文章到此也就结束了,身为Android程序员的你在大厂面试中能否取得头筹?阅读的同时也不忘点赞哦!

欢迎在文章下方留言!