写点什么

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

作者:王中阳Go
  • 2025-02-24
    湖南
  • 本文字数:2170 字

    阅读完需:约 7 分钟

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

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



1. Proactor 和 Reactor 模式的区别?

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


  • Reactor:基于同步 I/O,主线程监听事件就绪后,由工作线程执行实际 I/O 操作(读/写)和业务处理。典型代表:Linux epoll

  • Proactor:基于异步 I/O,主线程直接处理 I/O 操作完成后的事件通知,工作线程仅处理业务逻辑。典型代表:Windows IOCP



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



3. Slice 的底层存储结构?

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 与线程的核心区别?



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

Go 特性


  1. goroutine + channel 实现 CSP 模型

  2. sync.WaitGroup 控制并发等待

  3. context 实现超时控制对比差异


  • 无链式调用语法

  • 通过 select 实现多路复用

  • 原生支持并发安全 Map(sync.Map)



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

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 指针传递?



12. 分片上传的实现?

典型方案


  1. 前端计算文件 hash(spark-md5)

  2. 服务端预检分片状态

  3. 并行上传分片(每个分片单独 PUT 请求)

  4. 服务端合并分片 Go 实现要点


  • 使用 sync.Pool 管理分片缓冲区

  • 采用文件锁保证合并安全

  • 支持断点续传(记录分片状态)



13. Slice 与 List 的差异?



14. GC 调优策略?

  1. 减少堆内存分配(复用对象)

  2. 控制对象生命周期(及时设为 nil)

  3. 调整 GOGC 参数(默认 100)

  4. 使用 pprof 分析内存分配

  5. 避免大内存对象(拆分 slice)



15. Context 的核心作用?

  1. 传递请求上下文(traceID 等)

  2. 超时控制(WithTimeout)

  3. 取消传播(WithCancel)

  4. 值传递(WithValue)


正确用法


  • 作为函数第一个参数传递

  • 线程安全,应传递副本而非引用

  • 值传递只用于请求域数据




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


欢迎关注 ❤

我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。


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


感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:面试群。

发布于: 刚刚阅读数: 3
用户头像

王中阳Go

关注

靠敲代码在北京买房的程序员 2022-10-09 加入

【微信】wangzhongyang1993【公众号】程序员升职加薪之旅【成就】InfoQ专家博主👍掘金签约作者👍B站&掘金&CSDN&思否等全平台账号:王中阳Go

评论

发布
暂无评论
不愧是腾讯,面试的质量太高了_Go_王中阳Go_InfoQ写作社区