15~30K,3年以上golang开发经验

继续分享最新的面经,前面发的两篇大家也可以看看:

今天分享的是golang开发岗面经,要求是3年以上golang开发经验,薪资为15~30K,整体面下来的感受就是,面的比较广,细节拷打不多,来看看难度如何:

面试题详解

1. GMP调度

GMP调度模型是Go语言运行时的核心调度机制,用于实现高效的并发执行。G代表Goroutine(协程),M代表Machine(操作系统线程),P代表Processor(处理器)。

  • Goroutine 是用户态的轻量级线程,由Go运行时管理,创建和销毁成本低。
  • Machine 是操作系统线程,负责真正执行代码,每个M可以绑定一个或多个G。
  • Processor 是逻辑处理器,用于分配任务给M,并维护本地队列中的G。

调度过程:

  1. 每个P维护一个本地队列,存放待执行的G。如果本地队列为空,会从全局队列或其他P的队列中偷取任务(Work Stealing)。
  2. 当一个G阻塞时(如I/O操作),M会释放当前P并寻找其他可执行的G,从而避免浪费资源。
  3. 如果所有M都在忙,而有新的G需要执行,运行时会动态创建新的M来满足需求。

这种调度方式的优点是高效利用多核CPU,减少了上下文切换的开销,同时支持大量并发任务。


2. 协作式调度和抢占式调度有什么区别

协作式调度抢占式调度 是两种不同的任务调度方式,主要区别在于任务的执行控制权归属:

  • 协作式调度

    • 任务主动让出CPU,只有当前任务完成或显式调用让出函数时,调度器才能切换到其他任务。
    • 缺点是如果某个任务长时间占用CPU而不让出,会导致其他任务"饿死"。
    • 优点是实现简单,上下文切换开销小,适合任务间信任度高的场景。
  • 抢占式调度

    • 调度器通过定时器中断等方式强制剥夺当前任务的CPU使用权,确保公平性。
    • 优点是可以防止某个任务独占CPU,保证系统的响应性和公平性。
    • 缺点是上下文切换频繁可能导致性能开销增大。

在现代操作系统中,抢占式调度更为常见,因为它能更好地应对复杂任务环境。而协作式调度更多用于嵌入式系统或特定领域。


3. 垃圾回收讲一下,三色标记和混合写屏障

垃圾回收(GC)是一种自动内存管理机制,用于回收不再使用的对象,避免内存泄漏。常见的GC算法包括引用计数、标记清除、分代回收等。

三色标记 是一种经典的GC算法,其核心思想是将对象分为三种状态:

  • 白色:尚未被访问的对象,表示可能需要回收。
  • 灰色:已被访问但其引用的对象尚未完全扫描,表示正在处理中。
  • 黑色:已被访问且其引用的对象也已扫描完毕,表示安全存活。

GC过程:

  1. 初始时,所有对象为白色。
  2. 从根对象(如全局变量、栈变量)开始,将可达对象标记为灰色。
  3. 不断从灰色对象集合中取出对象,将其引用的对象标记为灰色,自身标记为黑色。
  4. 当灰色集合为空时,剩余的白色对象即为不可达对象,可被回收。

混合写屏障 是一种优化技术,用于解决三色标记中的并发问题。当GC与程序并发运行时,可能会出现新引用导致对象状态不一致的情况。混合写屏障通过记录修改过的引用,确保GC能够正确识别对象状态,从而提高效率和安全性。


4. 事务执行中,mysql如果宕机了,重新恢复会发生什么?

MySQL使用事务日志(Redo Log和Undo Log)来保证数据一致性。如果在事务执行过程中发生宕机,重启后会通过以下步骤恢复:

  1. 检查Redo Log:Redo Log记录了事务对数据页的物理修改,即使事务未提交,修改也会先写入日志。重启后,MySQL会重放Redo Log,将未持久化的修改应用到数据页上。
  2. 检查Undo Log:Undo Log记录了事务的回滚信息。对于未提交的事务,MySQL会使用Undo Log撤销已完成的部分操作,确保事务原子性。
  3. 崩溃恢复:MySQL的InnoDB引擎会在启动时执行崩溃恢复流程,将未完成的事务标记为回滚状态,并清理相关的日志文件。

通过这种方式,MySQL能够在宕机后恢复到一致状态,保证事务的ACID特性。


5. 讲一下两阶段提交的过程,两阶段提交解决什么问题?

两阶段提交(2PC, Two-Phase Commit)是一种分布式事务协议,用于协调多个节点之间的事务提交,确保分布式系统中的一致性。

过程

  1. 准备阶段
    • 协调者向所有参与者发送Prepare请求,询问是否可以提交事务。
    • 参与者执行事务操作,并将结果写入日志,然后回复Yes或No。
  2. 提交阶段
    • 如果所有参与者都回复Yes,协调者发送Commit请求,参与者正式提交事务。
    • 如果有任何参与者回复No,协调者发送Abort请求,参与者回滚事务。

解决的问题

  • 2PC解决了分布式系统中事务的原子性问题,即要么所有节点都提交事务,要么全部回滚。
  • 它适用于强一致性要求的场景,但存在单点故障(协调者故障)和性能瓶颈等问题。

6. 讲一下MVCC,它解决了幻读问题吗?

MVCC(多版本并发控制)是一种数据库并发控制机制,通过保存数据的多个版本来实现高并发读写。

原理

  • 每次更新数据时,都会生成一个新的版本,旧版本保留供读取。
  • 读操作只访问符合当前事务隔离级别的版本,避免了读写冲突。

解决的问题

  • MVCC有效解决了读写冲突问题,提高了并发性能。
  • 在可重复读(Repeatable Read)隔离级别下,MVCC通过版本控制避免了不可重复读问题。
  • 对于幻读问题,MVCC在某些情况下可以通过间隙锁(Gap Lock)结合版本控制部分解决,但在串行化(Serializable)级别下,仍需依赖锁机制来完全避免幻读。

7. redis的跳表了解吗?

跳表(Skip List)是一种基于链表的数据结构,通过多层索引加速查找操作,时间复杂度接近O(log n)。

Redis中的跳表主要用于实现有序集合(Sorted Set)。

  • 跳表的每一层是一个有序链表,越高层的链表包含的节点越少。
  • 查找时从最高层开始,快速缩小范围,然后逐层向下定位目标节点。
  • 插入和删除操作也通过多层索引进行维护,保证整体效率。

跳表的优点是实现简单,性能稳定,适合Redis这种高性能场景。


8. Redis大key会有什么问题?怎么解决?

问题

  • 大key指的是存储大量数据的单个键,可能导致Redis性能下降。
  • 内存占用过高,增加GC压力,甚至引发OOM(内存溢出)。
  • 操作大key可能导致阻塞,影响其他请求的响应时间。

解决方案

  • 拆分大key:将大key拆分为多个小key,分散存储。
  • 使用合适的数据结构:例如,将Hash、List等结构改为分片存储。
  • 渐进式删除:通过脚本逐步删除大key,避免一次性操作引发阻塞。
  • 监控和优化:定期分析Redis内存使用情况,及时发现和处理大key。

9. kafka如何解决消息有序问题?

Kafka通过分区(Partition)机制保证消息的有序性。

  • 每个分区内的消息是严格有序的,按照写入顺序存储和消费。
  • 生产者可以指定消息的分区键(Key),相同Key的消息会被路由到同一分区,从而保证局部有序。

消费者组内的消费者按分区消费,每个分区只能被一个消费者消费,进一步确保顺序性。

需要注意的是,跨分区的消息无法保证全局有序,若需要全局有序,需将所有消息写入同一个分区。


10. 如何保障kafka消息不丢失?

保障Kafka消息不丢失需要从生产者、Broker和消费者三个层面入手:

  1. 生产者
    • 设置acks=all,确保消息写入所有副本后才返回成功。
    • 启用重试机制,处理网络异常等情况。
  2. Broker
    • 配置副本数大于1,启用ISR(同步副本集)机制,确保数据冗余。
    • 定期备份数据,防止磁盘损坏导致丢失。
  3. 消费者
    • 手动提交偏移量,在业务逻辑处理完成后提交,避免重复消费或丢失。
    • 设置合理的消费超时时间,防止消费者挂起导致消息堆积。

通过以上措施,可以在绝大多数情况下保障消息不丢失。


11. 链上操作了解吗?

链上操作通常指区块链上的交易或智能合约执行。

  • 交易:用户发起的操作,如转账、调用智能合约等,需要经过共识机制验证后写入区块链。
  • 智能合约:部署在链上的代码,通过交易触发执行,具有自动化和不可篡改的特性。

链上操作的特点:

  • 透明性:所有操作记录公开可查。
  • 不可篡改:一旦写入区块链,无法修改。
  • 去中心化:无需信任第三方,由共识机制保证安全。

链上操作的挑战包括性能瓶颈、Gas费用高昂等问题,因此在实际应用中需权衡成本与效率。

欢迎关注 ❤

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

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

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

相关推荐
明月与玄武1 小时前
Spring Boot中的拦截器!
java·spring boot·后端
菲兹园长2 小时前
SpringBoot统一功能处理
java·spring boot·后端
muxue1782 小时前
go语言封装、继承与多态:
开发语言·后端·golang
开心码农1号2 小时前
Go语言中 源文件开头的 // +build 注释的用法
开发语言·后端·golang
北极象2 小时前
Go主要里程碑版本及其新增特性
开发语言·后端·golang
lyrhhhhhhhh3 小时前
Spring框架(1)
java·后端·spring
喝养乐多长不高4 小时前
Spring Web MVC基础理论和使用
java·前端·后端·spring·mvc·springmvc
莫轻言舞4 小时前
SpringBoot整合PDF导出功能
spring boot·后端·pdf
一切顺势而行5 小时前
kafka 面试总结
分布式·面试·kafka
玄武后端技术栈5 小时前
什么是死信队列?死信队列是如何导致的?
后端·rabbitmq·死信队列