不愧是腾讯,面试的质量太高了

今天分享的是粉丝投稿的在腾讯的最新面经,问的都是一些高质量的问题,看看你能答上来几个:

1. Proactor和Reactor模式的区别?

核心区别:事件处理流程不同

  • Reactor:基于同步I/O,主线程监听事件就绪后,由工作线程执行实际I/O操作(读/写)和业务处理。典型代表:Linux epoll
  • Proactor:基于异步I/O,主线程直接处理I/O操作完成后的事件通知,工作线程仅处理业务逻辑。典型代表:Windows IOCP

2. 栈和堆的内存管理差异?

分配方式

编译器自动分配/释放

GC自动管理

内存碎片

可能产生碎片

访问速度

快(CPU缓存友好)

较慢(需寻址)

逃逸分析

函数内部分配

跨函数共享时逃逸

3. Slice的底层存储结构?

go 体验AI代码助手 代码解读复制代码type slice struct {
    array unsafe.Pointer // 指向底层数组
    len   int
    cap   int
}

  • 存储位置:slice头结构可能在栈或堆,底层数组始终在堆
  • 关键特性:自动扩容(cap不足时2倍增长),共享底层数组

4. 说一下grpc和http2.0

gRPC

  • 简介:是Google开发的高性能开源RPC框架,能让客户端像调用本地方法一样调用远程服务器上的方法,方便构建分布式系统和微服务架构。
  • 特点以高效、紧凑的ProtoBuf作为默认数据序列化格式。支持Java、C++、Python、Go等多种编程语言,便于异构环境集成。支持双向流通信,客户端和服务端可同时收发多个消息,提升通信灵活性与效率。
  • 应用场景:常用于微服务架构中微服务间通信、云原生应用以及移动应用与后端服务通信等场景。

HTTP/2.0

  • 简介:是HTTP协议的第二个主要版本,对HTTP/1.x进行了重大升级,以提升网络传输效率和性能。
  • 特点采用二进制分帧传输数据,数据解析和处理更高效,传输更可靠。支持多路复用,可在同一个连接上同时发送多个请求和响应,解决了队头阻塞问题,提高连接利用率,减少延迟。运用HPACK算法对头部进行压缩,降低了头部数据传输量,提高传输效率。
  • 应用场景:广泛应用于Web应用、CDN内容分发等需要高效网络传输的场景,能优化网页加载速度,提升用户体验。

5. Protobuf是什么

基本概念

是一种与语言、平台无关的序列化方式,能把结构化数据转成字节流传输或存储,也可从字节流恢复数据,类似XML和JSON,但有独特优势。

核心特点

  • 高效:采用二进制编码,比XML和JSON等文本格式空间占用小、处理速度快,可减少带宽和存储成本,提升数据处理效率。
  • 多语言支持:支持Java、C++、Python等多种编程语言,不同语言系统间能方便地用它交换数据。
  • 可扩展:定义数据结构时能添加新字段,旧代码解析含新字段数据时会忽略新字段,保证向前兼容性,便于数据结构升级。
  • 强类型:定义数据结构时要明确字段数据类型,有助于编译时发现错误,提高程序稳定性和可靠性,也让数据处理更高效准确。

工作原理

  • 先在.proto文件定义消息形式的数据结构。
  • 用Protobuf编译器生成特定编程语言代码,包含序列化、反序列化方法及操作字段的接口。
  • 发送端将数据填进消息对象,序列化转成字节流发送或存储;接收端读取字节流,反序列化恢复成消息对象来处理数据。

6. Goroutine与线程的核心区别?

内存开销

2KB初始栈

1-2MB栈空间

创建速度

0.3μs

10μs

调度方式

用户态GMP调度

内核态调度

切换成本

120ns

1-2μs

7. Go的并发原语对比JS Promise?

Go特性

  1. goroutine + channel实现CSP模型
  2. sync.WaitGroup控制并发等待
  3. context实现超时控制 对比差异
  • 无链式调用语法
  • 通过select实现多路复用
  • 原生支持并发安全Map(sync.Map)

8. 线程安全的LRU实现方案?

go 体验AI代码助手 代码解读复制代码type SafeLRU struct {
    sync.RWMutex
    cache *lru.Cache
}

func (s *SafeLRU) Get(key string) interface{} {
    s.RLock()
    defer s.RUnlock()
    return s.cache.Get(key)
}

// 使用hashicorp/golang-lru实现基础LRU

优化方案

  1. 分片锁(Sharded Lock)
  2. 原子操作替代锁(适用于计数器场景)
  3. 无锁队列(sync/atomic实现)

9. sync.Pool的使用场景?

  1. 缓存临时对象,减少GC压力
  2. 网络连接池复用
  3. 大内存块复用

注意要点

  • 获取的对象可能残留旧数据
  • 不适合存储有状态资源
  • GC时会清空Pool

10. TCP粘包解决方案?

  • 定长分包:按固定长度分包数据,接收方依此读取,适用于数据长度固定的场景,如固定格式的协议数据。
  • 特殊字符分隔:在包尾加特殊字符或序列作分隔符,接收方据此判断包边界,适用于数据不包含分隔符的情况,如文本协议。
  • 消息头记录长度:在包头部设字段记录包长,接收方先读长度字段,再按此长度读取数据,适用于数据长度不固定的情况,通用性强。
  • 使用应用层协议:在应用层定义协议,规定数据包格式等,通过解析协议处理粘包,如HTTP协议,适用于需复杂数据处理和交互的场景。
  • 基于框架或库:利用Netty、Twisted等成熟框架或库处理粘包,它们有内置处理机制,适用于使用相应框架开发的项目,可简化开发。

11. 值传递 vs 指针传递?

内存分配

栈拷贝

传递指针地址

修改影响

不影响原值

影响原值

适用场景

小结构体(<64B)

大结构体或需修改

12. 分片上传的实现?

典型方案

  1. 前端计算文件hash(spark-md5)
  2. 服务端预检分片状态
  3. 并行上传分片(每个分片单独PUT请求)
  4. 服务端合并分片 Go实现要点
  • 使用sync.Pool管理分片缓冲区
  • 采用文件锁保证合并安全
  • 支持断点续传(记录分片状态)

13. Slice与List的差异?

内存布局

连续内存

双向链表节点

随机访问

O(1)

O(n)

插入删除

O(n)

O(1)

缓存友好

14. GC调优策略?

  1. 减少堆内存分配(复用对象)
  2. 控制对象生命周期(及时设为nil)
  3. 调整GOGC参数(默认100)
  4. 使用pprof分析内存分配
  5. 避免大内存对象(拆分slice)

15. Context的核心作用?

  1. 传递请求上下文(traceID等)
  2. 超时控制(WithTimeout)
  3. 取消传播(WithCancel)
  4. 值传递(WithValue)

正确用法

  • 作为函数第一个参数传递
  • 线程安全,应传递副本而非引用
  • 值传递只用于请求域数据

以上就是面经的全部内容,希望对你有帮助。

欢迎关注 ❤

我们搞了一个**********,互通有无,一起刷题进步。

没准能让你能刷到自己意向公司的最新面试题呢。

************************

***************************

全部评论
我面两次,一次二面kpi,一次一面kpi
点赞 回复 分享
发布于 昨天 00:02 天津

相关推荐

05-29 22:11
门头沟学院 Java
Elastic90:抛开学历造假不谈,这公司的招聘需求也挺怪的,Java开发还要求你有图文识别、移动端开发和c++的经验,有点逆天了。
点赞 评论 收藏
分享
评论
1
18
分享

创作者周榜

更多
牛客网
牛客企业服务