字节跳动面试,倒在了终面上

字节跳动面经

版权©: https://blog.csdn.net/zhangjingao/article/details/97176702

字节跳动一面

这个面试官不是搞java的,后来告诉我字节跳动以前旧的业务线是python,新的业务线是golong,你进来极有可能会转语言。最后聊了有50分钟,面试官很nice,比我想象的过程的舒服很多。

首先自我介绍,balabala……(此处省略三分钟)

1、找一个你的项目说一下,首先你的项目介绍,承担了什么职责,做了哪些工作,难点

因人而异,这就不在赘述了,balabal……(省略三分钟)

2、从你项目中看出,你使用的是mysql,mysql的int数据类型都有哪些?从小到大说一下,各占多少字节?

当时就记得tinyint和int,字节是1字节(tinyint:1,smallint:2,mediumint:3,int:4,bigint:8)

3、java中的int都有哪些?字节占多少

short,int,long,分别是:2,4,8

4、问你一个关于计算机网络的,tcp的三次握手说一下?

三次握手的话,客户端首先发起建立连接的请求,发送syn和seq,seq的话就是一个临时交互号,是自身的一个标识;之后第二次握手就是服务端收到请求后会发送一个syn,seq自身的标识,ack客户端seq+1;第三次就是客户端收到回应后发送syn和seq和sck。三次握手过程中分别进入的状态是:syn_send,syn_recv,established

5、tcp和udp的区别

tcp和udp他们都是传输层的协议;然后tcp是可靠传输,udp是尽最大努力交付,不可靠;tcp主要应用于端到端的比如电话这种服务,udp应用于广播,收音机等服务;tcp头部含有更多的如目标地址等信息,比udp头部开销更大。

6、你说你熟悉linux,我给你一个案例,搜索出log文本中出现次数最多的IP,并且给出次数

我直说了我不会,我linux是用来当操作系统进行日常开发使用,没有深入探索。面试官也没有追究

7、说下java的gc

现在是分代收集方式,首先进行垃圾对象的判断,判断的话有两种方法:引用计数和可达性分析,

引用计数就是没有一处引用了该对象就计数+1,当计数器为0时,代表没有地方引用他,可以回收,但是没法解决循环引用问题,现在主流虚拟机都不用这种办法。

可达性分析是选了一些对象作为GCROOTS,当从gcroots出发没有引用线时可回收。

垃圾回收的话就是有三种,标记清除,标记整理,复制算法。

8、说一下hashmap这个数据结构

他现在的实现方式是数组+链表+红黑树,通过计算hash,将对象存进hashmap中,当链表的长度大于8,链表进化为红黑树,链表小于6,红黑树退化为链表,这样能防止频繁的进行红黑树的转化,然后红黑树的话通过着色和旋转进行自平衡。

9、进行一次查找的话haspmap的时间复杂度是多少

O(1),这个是作为数组的查询复杂度。

10、给你一个算法你看一下,有一个无限长的整型数组,从小到大排序,非递增。那么怎么找到数组中一个key

初始想到的是使用二分,然后我说从n/2的地方进行二分,面试官说那也是无限啊,

我想了想说用双指针,一个以2为步长,一个以1为步长,然后当快的指针大于key时,往回遍历,

然后说完就想到不需要两个指针,一个指针即可,记录步长,一定再超出当前值的位置和当前位置-步长的范围内。面试官又问你步长怎么选?

我说可以模仿计算机网络的慢开始,第一次步长为2,第二次步长为4,第三次为8,持续为2的幂次,大于key时,再在当前位置和当前位置-步长范围内查找。

面试官问时间复杂度多少?我说不上来,尴尬,面试官提示后说是O(logn)

闲聊

之后就问了我最近看了哪本书,学到了什么,最近还在学的什么技术呢?问了我职业规划,兴趣爱好,还说了说公司的语言选型,我后来问了下对于我的面试表现评价,人家不方便说,又问了新人培养等问题。

字节跳动二面

中间断了两次网,好尴尬

自我介绍

balabla

然后说一说mysql的索引结构吧

mysql的索引结构是b+树,然后b+树我觉得相对于b树来说优点在于他非叶子节点不存储数据,本身每个节点的空间是有限的,这样的话他每个节点能存储的节点数就更多,层级就更低。
然后因为它非叶子节点不存储数据,这样每次查询是一定要到叶子节点,查询就更稳定
然后还有就是它叶子节点是单链表连接的,这样天然有序。

看一道题吧,这个题怎么建立索引

mysql

订单表有几个属性:订单id,用户user_id、下单日期date(精确到天)等,请问索引怎样建立

a. 查询某个用户的所有订单

b. 查询某一天的所有订单

c. 查询某一天某个用户的所有订单

综合考虑三个场景,建立尽量少的索引。

建立两个索引
第一个是日期索引,
因为b要求查询某一天
第二个是组合索引,用户user_id,订单id,下单日期date
因为c用到了三个,同时在建立索引时,将三个都建立上,另外由于索引结构中,int类型最佳,其次是date,所以将date放在后面。

看第二道题

10G文件,每一行一个 uint32 数字。有一台1G内存的机器

- A. 找出最大的 k 个数

- B. 找出重复数字

A:
使用堆排序,这里不是对所有的10G数据建堆,而是建立一个k大小的空堆,然后遍历数据,有大于根结点的值将堆根节点替换上,并调整大顶堆
B:
这里建立10G长度的hash表是不行的,内存不够,建立一个小的1000的hash表,遍历数据,求hash值,当发生hash冲突时,往前遍历,只需要往前遍历,查找是否存在重复值

第三道题

我手中有一堆扑克牌, 但是观众不知道它的顺序。

第一步, 我从牌顶拿出一张牌, 放到桌子上。

第二步, 我从牌顶再拿一张牌, 放在手上牌的底部。

第三步, 重复第一/二步的操作, 直到我手中所有的牌都放到了桌子上。

最后, 观众可以看到桌子上牌的顺序是:13\12\11\10\9\8\7\6\5\4\3\2\1 请问, 我刚开始拿在手里的牌的顺序是什么?

代码实现一下吧

import java.util.ArrayDeque;
public class Main {

    public static void main(String[] args) {
        int[] arr = {13, 12, 11, 10, 9,8,7,6,5,4,3,2,1};
        ArrayDeque<Integer> deque = new ArrayDeque();
        deque.addFirst(arr[0]);
        int index = 1;
        work(deque, arr, index);

        while (!deque.isEmpty()) {
            System.out.println(deque.pop());
        }
    }

    private static void work(ArrayDeque<Integer> deque, int[] arr, int index) {
        if (index > 12) {
            return;
        }
        //每次往首部添加,添加一次将尾部提到前面
        deque.addFirst(arr[index]);
        index++;
        int temp = deque.pollLast();
        deque.addFirst(temp);
        work(deque, arr, index);
    }

}

字节跳动三面

这个面试官应该是一个总监级别的,说话非常的硬气,肯定是一个资深大佬,一共面了40多分钟。常规的面试基础都没问,纯怼项目和算法了。

1. 自我介绍

balbala

2. 你觉得你目前遇到的困难有哪些?项目上的难点?

balabala

3. 你的项目数据库多大?QPS多少?哪些sql比较慢?

项目上的事我就不说了……balaba

4. 那你觉得以后qps更大的话,你该怎么设计?

热点数据加缓存。

5.给你一个算法题,你来看一下思路

给定一个应该包含全部int32整数的文件,里边可能缺失了若干数字, 返回任意一个确认缺失的数字。

首先问我int32在内存中占了多少内存?我没答出来,这换算不知道怎么算,我就想着32,,8个字节啥的了

实现的话我想了一下,首先想到hashmap,然后说了后他问我怎么实现,时间复杂度多少?空间复杂度多少?我想了想觉得不行,然后我就说hashmap不存放全部数据,定一个假设是100的hashmap(其实这里已经没有hashmap的意义了,换数组也是可以的)然后所有数对100求模,如果求得的模比100大,那么继续求,此时就是0,100,10000,1000000求得的模是一样的,最终就计算个数是不是正确如果不正确再去查找该不正确序列里那个数不存在。

然后他说那你用代码实现一下吧

过了好久我还没写完,他说时间差不多了我看你也写的差不多了,那就先这样,然后我就赶紧给他讲了讲我的代码,告诉他接下来我会怎么做也就是差不多出来了(现在暂时不想整理了,先这样)

public class Main {
    
    
    public void createHash(){
        HashMap<Integer, Integer> hashmap = new HashMap();
        Integer min = Integer.MIN_VALUE;
        Integer max = Integer.MAX_VALUE;
        for (int i = min; i < max; i++) {
            hashmap.put(i, getMod(i));
        }
        search(hashmap, min, max);
    }
  
    public int getMod (int i) {
        int mod = i % 100;
        if (mod > 100) {
            return getMod(mod);
        }
        return mod;
    }
    
    public void search(HashMap<Integer> hashmap, Integer min, Integer max) {
        int minest = 0;
        hashmap.forEach((K, V)->{
            
        })
        
        
    }
    
    
    public static void main(String[] args) {
        
    }
}

那留两分钟咱们聊一聊,你有什么想问我的

balabala


8/14补充

面试结果确实是凉了,准备秋招正式批中。
这里后来反思了终面算法题,这里作为补充:

给定一个应该包含全部int32整数的文件,里边可能缺失了若干数字, 返回任意一个确认缺失的数字。 这个文件占多大内存?

先说第二问,占多大内存:现在想想其实也是能够说出来的,int占4字节,32位,那么就是2^32比特位,换算就是4G。
第一问,解题思路
  后来我看了其实应该使用位示图法。解题思路和位示图法介绍不是面经分享的主题,直说代码:



/**
 * @author zjg
 * @ClassName 位运算_返回确认缺失数字
 * @Description TODO
 * @Date 2019/8/14 15:23
 **/
public class Main {

    private static byte[] arr = new byte[1 << 29];

    private static void work (int num) {
        long bitIndex = num + (1L << 31);
        int byteIndex = (int) (bitIndex / 8);
        int innerIndex = (int) (bitIndex % 8);
        arr[byteIndex] = (byte) (arr[byteIndex] | 1 << innerIndex);
    }

    public static void main(String[] args) {
        for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
            //假设10不加进去
            if (i == 10) {
                continue;
            }
            work(i);
        }
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < 8; j++) {
                if ((arr[i] & 1 << j) == 0) {
                    System.out.println(((long) i * 8 + j) - (1L << 31));
                    return;
                }
            }
        }
    }

}

你可能感兴趣的:(随笔)