首页 > 秋招面经(字节、阿里云、腾讯、美团、网易互娱)
头像
zk_kiger
编辑于 2021-08-26 14:16
+ 关注

秋招面经(字节、阿里云、腾讯、美团、网易互娱)

看评论区反响比较大,就把第一句话给删掉了。写下这篇面经之后,也是面了一下美团,以及阿里云的技术终面,就把面经更新一下,这下我的秋招技术面试应该是彻底结束了。

把近一个月面试的大厂的面经整理一下。楼主秋招主要面试的岗位偏向于鸡架,所以可能面试中的问题和业务岗有所不同。面经按照面试顺序来依次整理,公司顺序不分先后。
简单说一下楼主的背景,本科双非,在字节和腾讯实习过,技术栈 java、golang。面试过的时间比较久,我只记录我印象比较深刻的问题,其他的问题,可能也就是一些简单的八股文。

1.字节基础架构提前批(网络)

1.1 一面

a.项目
b.场景题:假设上游的 QPS 1000,中间有 10 个节点对上游的请求上送给下游进行处理(类似网关),下游 QPS 500,问,中间这 10 个节点如何做限流,能保证下游负载能力最大化。(这 10 个节点的负载可能会动态变化)
c.场景题:海量数据存储数据库的扩展问题
d.算法:比较有难度了,当时直接懵了,没想出来。后面也是问面试官要了代码,我会粘在面经最后。
有一个函数,如下:

var maxKey = make([]byte, 256)

func init() {
    rand.Seed(int64(time.Now().Second()))
    rand.Read(maxKey)
}

func Search(key []byte) []byte {
    time.Sleep(time.Millisecond * 10)
    if bytes.Compare(key, maxKey) > 0 {
        return nil
    }
    return key
}

其中 maxKey 是未知的,需要多次调用 Search 函数找到最终的 maxKey。每次调用 Search 函数都有 10 ms 的延迟。要求在多核多线程的条件下利用所有计算资源,在最短的时间内计算得道 maxKey 的值。

1.2 二面

一面是挂掉了,但是被别的组给捞起来了,hr 告诉我又不挂我了,真是反复横跳。
a.项目
b.java 八股文
c.ZAB 协议
d.Golang Channel
e.算法:多个链表翻转的变种。
单链表,按照 1、2、3 ... N 分组后,逆序。
输入 [1] [2 3] [4 5 6] [7 8]
输出 [7 8] [4 5 6] [2 3] [1]

1.3 三面

三面比较水了,先是上来将实习项目,讲完之后,让我敲了个快排就完事了。

2.阿里云(云原生中间件)

2.1 一面(电话面)

a.项目
b.SpringBoot 自动装配
c.关于 Dubbo 服务保障手段的问题(服务方和消费方如何优雅退出、RPC 的熔断机制、降级、限流)
d.消费端从 zk 拉取服务信息失败或拉取信息为空,如何处理?
e.如何排查一个节点故障问题(网络、CPU、内存),具体到相应的 Linux 命令

2.2 二面

a.项目
b.Dubbo SPI
c.zk 脑裂问题
d.Java 的线程池关闭机制

2.3 三面(电话面 半小时)

a.项目
后续问了一些比较奇怪的问题
b.业余时间干什么
c.最近有什么书能够推荐给他的
d.对于某个领域前沿技术有什么了解
e.是否看过 dubbo 源码,但又没具体问。。

3.腾讯(teg 云架平 存储)

3.1 一面(1.30 小时)

a.项目
b.简历写的基本技能都过了一遍
c.Netty 线程模型
d.阻塞、非阻塞、同步、异步 的区别
e.数据库 ACID 一致性和原子性的区别(坑)
f.Raft
g.Redis 多线程模式
h.算法:最长回文子串
https://leetcode-cn.com/problems/longest-palindromic-substring/

3.2 二面

二面也就半小时完事,上来问了点实习项目。

4.网易互娱(混合云存储)

4.1 一面

第一次面试遇到对面竟然有两个面试官,惊到我了。
a.项目
b.操作系统除了设备管理,其他的都问了
c.算法:二叉树前序遍历

4.2 二面

这次问的主要是 Golang 基础,简单列一下。
a.Slice 底层原理
b.Goroutine 通信
c.Channel 底层原理
d.Channel 和 Mutex 的区别
e.zk ZAB 协议
然后问了点项目,就完事了。

4.3 后续

网易是挂掉了,应该是因为技术栈不匹配,这个组主要是 c++ 开发。

5.美团(微服务中间件)

5.1 一面

a.什么是微服务
b.写个 hashmap
c.概率论的题:
有个随机函数,只能产生 0/1,产生 0 的概率是 p,产生 1 的概率是 1-p,且 p != (1-p)。希望可以封装这个随机函数,得到新的随机函数,产生 0/1 的概率相同。
d.一亿个单词中,找出出现次数 top 10 的单词
e.什么是 servicemesh

5.2 二面

二面半小时完事,面试官问一个点,感觉你会就直接跳过了.
a.如何查看网络状态
b.http 几个版本的区别
c.了解的分布式共识算法
d.一致性 hash
e.算法题:一个数组里面的所有数字不重复,数组大小为 N,想要从数组中随机选择 M 个不重复的数字并输出。O(1)的空间复杂度
f.项目中有用到什么数据结构(不是常见的一些,类似队列、堆这种)

6.补充

6.1 字节一面算法题代码

我在面试官发来代码的基础上加了点注释,如何还是看不懂,后面还补了一张图。

package main

import (
    "bytes"
    "fmt"
    "math/rand"
    "time"
)

var maxKey = make([]byte, 256)
var step = 11

func init() {
    rand.Seed(int64(time.Now().Second()))
    rand.Read(maxKey)
}

func Search(key []byte) []byte {
    time.Sleep(time.Millisecond * 10)
    if bytes.Compare(key, maxKey) > 0 {
        return nil
    }
    return key
}

func CompareBytes(key []byte, value int, valueChan chan int) {
    if Search(key) == nil {
        valueChan <- 0
    } else {
        valueChan <- value
    }
}

func Int2Bytes(start, end, value int) []byte {
    firstByteNum := 8 - (start % 8)
    secondByteNum := end - start - firstByteNum
    // 1.当前 step 跨越了三个 byte 区间,需要计算在每一个区间中的数值
    if secondByteNum > 8 {
        thirdByteNum := secondByteNum - 8
        res := make([]byte, 3)
        res[0] = byte(value >> uint(secondByteNum))
        res[1] = byte(value >> uint(thirdByteNum))
        res[2] = byte((value & ((1 << uint(thirdByteNum)) - 1)) << uint(8-thirdByteNum))
        return res
    }
    // 2.当前 step 跨越了两个 byte 区间
    if secondByteNum <= 8 && secondByteNum > 0 {
        res := make([]byte, 2)
        // 第一段 byte 区间表示的值
        res[0] = byte(value >> uint(secondByteNum))
        // 第二段 byte 区间表示的值 (value & ((1 << uint(second_byte_num)) - 1)
        // << uint(8-second_byte_num):移位到高位,方便下一段在该 byte 区间得到的 first 值,直接相加
        res[1] = byte((value & ((1 << uint(secondByteNum)) - 1)) << uint(8-secondByteNum))
        return res
    }
    // 3.当前 step 在一个 byte 的区间
    res := make([]byte, 1)
    res[0] = byte(value)
    return res
}

func Rebuild(start, end, value int, key []byte) {
    tmpBytes := Int2Bytes(start, end, value)
    if len(tmpBytes) == 1 {
        key[start/8] = key[start/8] + tmpBytes[0]
    } else if len(tmpBytes) == 2 {
        key[start/8] = key[start/8] + tmpBytes[0]
        key[start/8+1] = tmpBytes[1]
    } else {
        key[start/8] = key[start/8] + tmpBytes[0]
        key[start/8+1] = tmpBytes[1]
        key[start/8+2] = tmpBytes[2]
    }
}

func GenerateBytes(start, end int, key []byte) {
    valueChan := make(chan int)
    var valueSize int = 1 << uint(end-start)
    var value int = 0
    // 根据 value_size 的范围,用每一个数字构建副本 tempKey [256]byte,
    // 每个数字都会有 goroutine 去 search
    for i := 0; i < valueSize; i++ {
        length := len(maxKey)
        var keyTmp = make([]byte, length)
        copy(keyTmp, key)
        Rebuild(start, end, i, keyTmp)
        go CompareBytes(keyTmp, i, valueChan)
    }
    // 阻塞获取每个 goroutine 的 search 结果,得到结果中最大的数就是当前区间 maxKey 对应的值
    for i := 0; i < valueSize; i++ {
        select {
        case tmpValue := <-valueChan:
            if tmpValue > value {
                value = tmpValue
            }
        }
    }
    // 用正确的 value 去构建 key
    Rebuild(start, end, value, key)
}

func main() {
    if step > 16 {
        fmt.Println("step should not more than 16")
        return
    }
    length := len(maxKey)
    var key = make([]byte, length)
    length = length * 8
    for i := 0; i < length; i = i + step {
        if i+step < length {
            // 将 byte 扩大为 8 位只能表示 0/1 的数字,分区间去匹配 maxKey
            GenerateBytes(i, i+step, key)
        } else if i+step >= length {
            GenerateBytes(i, length, key)
        }
    }
    fmt.Println("key   =", key)
    fmt.Println("maxKey=", maxKey)
}

图片说明

6.2 总结

简单总结一下,面试过程中,对于机组、操作系统、计网这方面的知识基本上是每轮面试必问的问题,所以就没有提出来了。其次校招更加看重基础知识的掌握情况,以及整体知识的广度,当然对于个人技术栈的深度还是有一定要求的。

更多模拟面试

全部评论

(13) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

近期精华帖

热门推荐