15K的Go开发岗,坐标北京

好久没有分享最新的面经了,今天分享一下北京某公司Go开发岗的面经,薪资是15K左右,看看难度如何:

为什么要用分布式事务

分布式事务的核心作用是解决跨服务、跨数据源操作的数据一致性问题。在单体应用中,数据库本地事务(如 MySQL 的 InnoDB 事务)可通过 ACID 特性保证单库内操作的一致性,但在分布式系统中,业务操作往往需要跨多个服务(如用户服务、订单服务、支付服务)或多个数据库,此时本地事务无法覆盖所有操作,可能出现 “部分成功、部分失败” 的情况。

什么是事务

事务是一组操作的集合,需满足 “要么全部成功,要么全部失败” 的原子性要求,分为数据库事务分布式事务两类:

1. 数据库事务

指单库内的事务(如 MySQL、PostgreSQL),核心是满足ACID 特性

  • 原子性(Atomicity):事务中的所有操作要么全执行,要么全不执行(如转账时 “扣 A 的钱” 和 “加 B 的钱” 必须同时成功或同时失败)。
  • 一致性(Consistency):事务执行前后,数据从一个合法状态切换到另一个合法状态(如转账前后 A 和 B 的总金额不变)。
  • 隔离性(Isolation):多个事务并发执行时,彼此的操作互不干扰(避免脏读、不可重复读、幻读)。
  • 持久性(Durability):事务提交后,数据修改会永久保存(即使数据库崩溃,重启后数据仍有效)。

以 MySQL InnoDB 引擎为例,其事务实现细节包括:

  • 隔离级别:支持读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read,默认)、串行化(Serializable)。
  • 快照读与当前读:
    • 快照读(如select * from t where id=1):通过 MVCC(多版本并发控制)和 Read View 实现。每行数据包含隐藏列(DB_TRX_ID:最后修改事务 ID;DB_ROLL_PTR:回滚指针,指向历史版本),Read View(由 “低水位”“高水位”“活跃事务 ID 列表” 组成)决定可见的版本(读提交时每次查询生成新 Read View,可重复读时首次查询生成 Read View)。
    • 当前读(如update/delete/select ... for update):会加锁(行锁、表锁),并读取最新数据。
  • 锁机制:更新操作时会加 “意向锁”(IX/IS),用于快速判断表中是否有行锁(避免逐行检查锁,提高效率);行锁(如 Record Lock)用于锁定单行数据,防止并发修改冲突。
2. 分布式事务

指跨多个服务或多个数据库的事务,核心是保证跨节点操作的最终一致性(无法像本地事务一样严格保证 ACID,而是通过补偿机制实现 “最终一致”)。

常见实现方式包括 TCC(Try-Confirm-Cancel)、SAGA(正向 + 反向补偿)、本地消息表、DTM 框架等。以 DTM 为例,其核心组件包括:

  • 事务管理器(TM):负责全局事务的创建、提交、回滚,协调各子事务的执行顺序,解决事务乱序、幂等性(重复提交)、空补偿(未执行 Try 却执行 Cancel)等问题(通过 “子事务屏障表” 记录全局事务 ID、分支事务 ID 及状态实现)。
  • 资源管理器(RM):管理各服务的本地资源(如数据库连接),负责执行子事务的 Try/Confirm/Cancel 操作,并向 TM 汇报执行结果。

分布式事务 CAP 特性

CAP 是分布式系统的三大核心特性,由 Eric Brewer 提出,三者不可同时满足:

  • 一致性(Consistency):分布式系统中,所有节点在同一时间看到的数据是一致的(如集群中所有节点的用户余额必须相同)。
  • 可用性(Availability):分布式系统中,任何节点故障时,剩余节点仍能正常响应请求(如支付系统不能因某台服务器宕机而无法下单)。
  • 分区容错性(Partition Tolerance):当网络分区(部分节点与其他节点断开通信)发生时,系统仍能继续运行(分布式系统必须满足此特性,因为网络故障不可避免)。

在分布式事务中,由于必须满足分区容错性(P),因此需在一致性(C)和可用性(A)之间权衡:

  • CP 倾向:优先保证一致性,牺牲部分可用性(如 ZooKeeper 集群,leader 宕机后会暂停服务直到新 leader 选举完成,期间不可用但数据一致)。
  • AP 倾向:优先保证可用性,接受短暂的不一致(如多数业务的支付系统,允许 “用户余额扣减后,订单状态延迟更新”,但最终会通过补偿机制一致)。

实际业务中,分布式事务通常追求最终一致性(属于 AP 倾向),即允许中间过程数据不一致,但通过补偿操作(如 TCC 的 Cancel、SAGA 的反向流程),最终所有节点数据会达成一致。

协程了解吗

协程(Goroutine,Go 语言中的实现)是轻量级的 “用户态线程”,相比操作系统线程(OS Thread),其优势在于:

  • 资源占用极低:初始栈大小仅 2KB(可动态扩容至 GB 级),而线程初始栈通常为 2MB,因此单台机器可创建数十万甚至数百万协程。
  • 调度效率高:由 Go runtime 而非操作系统调度,减少用户态与内核态的切换开销。

Go 语言通过GMP 调度模型实现协程的高效调度,核心组件包括:

  • G(Goroutine):协程本身,包含栈、程序计数器、状态(如运行中、就绪、阻塞)等信息。
  • M(Machine):操作系统线程,负责执行 G(真正的 “执行载体”)。
  • P(Processor):处理器,是 G 和 M 的 “桥梁”,包含本地协程队列(Local Queue)、全局队列指针、调度器状态等,用于管理可执行的 G。

调度流程细节:

  1. 初始化:程序启动时创建初始线程 M0 和初始协程 G0(每个 M 绑定一个 G0,负责调度其他 G)。
  2. 协程入队:新建的 G 优先放入当前 P 的本地队列(容量默认 256),本地队列满后放入全局队列。
  3. 调度策略:
    • 本地队列调度:M 优先从绑定的 P 的本地队列获取 G 执行。
    • 全局队列调度:本地队列为空时,M 会从全局队列批量获取 G(一次取min(全局队列长度/num(P) + 1, 64)个)。
    • 偷取机制(Work Stealing):若本地队列和全局队列都为空,M 会随机选择其他 P 的本地队列,偷取一半的 G 执行(避免线程空闲,提高资源利用率)。
    • Hand off 机制:当 G 因系统调用(如 IO、sleep)阻塞时,M 会主动释放绑定的 P(将 P 放入空闲 P 列表),让其他空闲的 M 绑定该 P 并执行其本地队列的 G;当阻塞的 G 唤醒后,M 会尝试从空闲 P 列表获取 P,若获取成功则继续执行 G,否则将 G 放入全局队列等待调度。

介绍一下 hand off 机制

Hand off 机制是 Go 调度器中用于处理 “协程阻塞” 的协作式调度策略,核心目的是避免处理器(P)闲置,提高系统资源利用率。

触发场景

当协程(G)因以下操作阻塞时,会触发 hand off:

  • 系统调用(如net.Dialos.Read等 IO 操作);
  • 同步操作(如time.Sleepmutex.Lock未获取锁时)。
具体流程
  1. G 阻塞时:执行 G 的 M 会检测到 G 进入阻塞状态,此时 M 会调用park函数将 G 的状态标记为 “阻塞”,并将绑定的 P 从自身解绑,放入全局 “空闲 P 列表”。

  2. 释放 P 后:M 进入休眠状态(或处理其他任务),而空闲 P 列表中的 P 可被其他空闲的 M 绑定,继续执行 P 本地队列中的 G(避免 P 因 M 阻塞而闲置)。

  3. G 唤醒时:阻塞的 G 被唤醒(如 IO 操作完成、锁获取成功),此时 M 会调用

    unpark
    

    函数,尝试从空闲 P 列表中获取一个 P:

    • 若获取成功,M 绑定该 P,继续执行唤醒的 G;
    • 若未获取成功,将 G 放入全局队列,M 进入休眠,等待后续被调度。
与抢占式调度的区别

Hand off 是 “协作式调度”(G 主动让出 P),而 Go 1.14 后引入的 “抢占式调度” 是通过信号中断长时间运行的 G(如循环无阻塞的 G),强制其让出 P,避免单个 G 独占 P 导致其他 G 饿死。两者结合,保证了 Go 协程调度的高效性。

gc 了解吗

Go 的垃圾回收(GC)是自动管理堆内存的机制,核心目标是 “在保证程序正确的前提下,尽可能减少对业务代码的干扰(低延迟)”。其核心实现是三色标记法 + 混合写屏障,特点是 “并发标记、并行清扫”(大部分阶段与业务代码并发执行,仅短暂 STW)。

核心流程
  1. 初始标记(STW):短暂暂停所有协程(几微秒到毫秒级),标记 “根对象”(全局变量、栈上变量直接引用的对象)为灰色,开启写屏障(防止标记期间对象引用关系被修改导致漏标)。

  2. 并发标记:恢复协程执行,GC 后台线程从灰色对象出发,遍历其引用的对象:

    • 若引用的对象是白色,标记为灰色;
    • 遍历完的灰色对象标记为黑色(表示 “已处理”)。
      此阶段与业务代码并发执行,写屏障会实时跟踪对象引用变化(如黑色对象引用白色对象时,通过写屏障修正标记)。
  3. 最终标记(STW):再次短暂暂停协程,处理并发标记期间遗漏的对象(如根对象的新增引用),关闭写屏障。

  4. 并行清扫:恢复协程执行,多个 GC 线程并行清扫所有白色对象(不可达对象),释放其占用的堆内存。

关键技术:混合写屏障

写屏障的作用是在并发标记阶段,保证对象引用关系变化时,GC 能正确跟踪可达性,避免 “黑色对象引用白色对象” 导致的漏标(漏标会导致白色对象被误判为垃圾回收)。

混合写屏障结合了 “插入写屏障” 和 “删除写屏障” 的优势,规则如下:

  • 当创建新对象时,直接标记为黑色(避免新对象被误回收);
  • 当修改对象引用(如a.b = c)时:
    • 若旧引用a.b指向的对象是黑色,将其重新标记为灰色(确保其引用的对象被遍历);
    • 新引用c指向的对象若为白色,标记为黑色(避免被误回收)。
性能优化

Go GC 通过不断迭代优化延迟(如 1.5 引入并发标记、1.8 优化 STW 时间、1.19 引入分代回收),目前在多数场景下 STW 时间可控制在 100 微秒以内,对业务影响极小。

函数的栈帧了解吗

函数栈帧是函数调用时在栈上分配的内存区域,用于存储函数的参数、局部变量、返回地址、栈基指针等信息,其生命周期与函数调用一致(函数返回时栈帧被释放)。

栈帧结构(以 x86 架构为例)

从高地址到低地址依次为:

  • 返回地址:函数执行完毕后,CPU 需跳转回的调用处地址(如call func指令会将下一条指令地址压栈)。
  • 栈基指针(BP):指向当前栈帧的底部,用于定位栈帧内的参数和局部变量(函数执行时,BP 的值由上一个栈帧的 SP 决定)。
  • 局部变量:函数内定义的变量(如int astring s),按声明顺序从 BP 向下分配。
  • 函数参数:调用方传递的参数,从 BP 向上(高地址)读取(如func(a, b int)中,a在 BP+8,b在 BP+12,取决于 CPU 位数)。
逃逸分析与堆分配

Go 编译器会通过 “逃逸分析” 判断变量是否需要 “逃逸” 到堆上:

  • 若变量仅在函数内使用(无外部引用),则分配在栈帧上(函数返回后自动释放,无需 GC);
  • 若变量被外部引用(如返回局部变量的指针、被闭包引用),则会 “逃逸” 到堆上(由 GC 管理生命周期)。

逃逸分析的目的是减少堆分配(堆分配需 GC,栈分配更高效),提升程序性能。

欢迎关注 ❤

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/916830.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/916830.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 文件管理高级操作:复制、移动与查找的深度探索

目录一、文件复制:从基础到企业级同步的全维度解析1. cp命令:基础工具的进阶密码(1)文件属性保留:从基础到极致(2)特殊文件处理:稀疏文件与设备文件(3)安全操…

Redis内存使用耗尽情况分析

目录 1、内存上限介绍 1.1、产生原因 1.2、Redis的maxmemory限额 1.3、影响的命令与场景 2. 内存用完后的策略 2.1、淘汰策略分类 2.2、淘汰策略介绍 2.3、不同策略对比 3、常见业务示例 3.1、影响 3.2、监控与自动告警 前言 在日常项目中,不知道你思考过…

Ubuntu 系统中配置 SSH 服务教程

一、什么是 SSH?SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络中安全地进行远程登录、远程命令执行和文件传输。它是 Telnet、FTP 等传统协议的安全替代品。二、确认系统环境在开始配置之前,请确认你的系…

基于springboot的编程训练系统设计与实现(源码+论文)

一、开发环境 技术/工具描述MYSQL数据库一个真正的多用户、多线程SQL数据库服务器,适用于Web站点或其他应用软件的数据库后端开发。B/S结构基于互联网系统的软件系统开发架构,利用浏览器进行访问,支持多平台使用。Spring Boot框架简化新Spri…

K8s集群两者不同的对外暴露服务的方式

在工作中,我们暴露集群内的服务通常有几种方式,对于普通的http或者https,我们通常使用​Ingress Nginx​ ,对于原始的TCP或者UDP端口服务,可能需要选择 ​LoadBalancer​ ,它们的核心区别在于工作层级、协议支持和流量…

实习日志111

第一天 加入内网和内网域,设置自己的操作系统 第二天 安装常用软件和平台 Notepad 是一款免费的源代码编辑器,支持多种编程语言,其功能强大且界面友好,适用于 Windows 操作系统。WinMerge 是一款开源的差异比较和合并工具&…

Redis 服务挂掉排查与解决

Redis 是一个高性能的键值对存储系统,广泛应用于缓存、会话存储、消息队列等场景。在使用 Redis 的过程中,偶尔会遇到 Redis 服务挂掉或无法连接的情况。本文将通过常见错误 RedisException in Redis.php line 63 Connection refused 来讲解如何排查并解…

DOM + HTML + HTTP

一、HTML5的新特性 1.语义化标签:其实就是可以让标签有自己的含义 html4之前都是有的,比如:<h1>、<ul>、<li> html5新增了很多语义化标签:<header>、<nav> html5的语义化标签的常用页面布局: 优点: 1.代码结构清晰,方便阅读,有利于团…

HTML 音频/视频

HTML 音频/视频 引言 HTML 音频和视频标签是网页设计中不可或缺的部分,它们为用户提供了一种将多媒体内容嵌入到网页中的方式。本文将详细介绍 HTML 音频/视频标签的用法、属性和注意事项,帮助开发者更好地在网页中嵌入音频和视频。 HTML 音频标签( ) 1. 标签基本用法 …

Apache Ignite Cluster Groups的介绍

以下这段内容是 Apache Ignite 官方文档中关于 Cluster Groups&#xff08;集群组&#xff09; 的介绍。我来用通俗易懂的方式帮你全面理解这个概念。&#x1f310; 什么是 Cluster Group&#xff1f; 简单来说&#xff1a;Cluster Group 就是一个“节点的子集”。想象一下你的…

github上传本地项目过程记录

最近有和别人进行unity项目协作的需求&#xff0c;需要把自己的本地代码上传到github已有的一个仓库里。记录一下上传过程&#xff0c;防止后续还需要用。 文章目录一、把自己的本地代码上传到github已有的一个仓库中二、常用功能一、把自己的本地代码上传到github已有的一个仓…

Spring AI Alibaba

目录 前言&#xff1a; 一、Spring AI 和Spring AI Alibaba 二、Spring AI Alibaba快速入门 1.环境 2.ollama 3.阿里百炼 前言&#xff1a; 2025年真的是AI大爆发的一年&#xff0c;以后无论是什么行业我想都需要AI了&#xff0c;作为一名计算机人&#xff0c;你不学习AI…

【GaussDB】内存资源告急:深度诊断一起“memory temporarily unavailable“故障

【GaussDB】诊断一起内存临时不可用的问题 &#x1f4cb; 背景 在客户测试环境中&#xff08;GaussDB 506.0 SPC0100 集中式&#xff09;&#xff0c;一个重度使用存储过程的系统&#xff0c;频繁出现内存临时不可用的问题(ERROR: memory is temporarily unavailable)。令人困…

FastDFS如何提供HTTP访问电子影像文件

Nginx 作为高性能的 Web 服务器和反向代理服务器&#xff0c;与 FastDFS 结合使用&#xff0c;本文主要介绍用于处理 FastDFS 存储文件的 HTTP 访问请求&#xff0c;方便客户端通过 HTTP 协议直接访问存储在 FastDFS 中的文件&#xff0c;在电子影像系统中&#xff0c;Nginx 可…

水面垃圾识别分割数据集labelme格式2111张8类别

数据集中有部分增强图片&#xff0c;注意为了提供模型泛化识别能力&#xff0c;有很少一部分不是水面垃圾。具体看图片数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件)图片数量(jpg文件个数)&#xff1a;2111标注数量(json文件…

北京-4年功能测试2年空窗-报培训班学测开-第六十二天-模拟未通过,继续准备自我介绍项目介绍面试题中

今日产出&#xff0c;完成昨天模拟面试录音的重听和整理&#xff0c;完成自我介绍梳理&#xff0c;还重写了三个算法题&#xff0c;写了4个sql题。和同学打语音提问今天专注力不强&#xff0c;因为焦虑项目和面试题。关于项目&#xff0c;我理解的&#xff0c;老师以前录屏讲的…

自动化辅助工具教程

该工具支持全部平台使用

里程碑 | 1Panel开源面板GitHub Star数量突破30,000个!

截至2025年7月23日20:00&#xff0c;飞致云旗下开源项目——1Panel开源Linux服务器运维管理面板GitHub Star数超过30,000个&#xff01; 继Halo之后&#xff0c;1Panel成为飞致云旗下第二个GitHub Star数量超过30,000个的开源项目&#xff0c;也是飞致云旗下最快达成30,000个Gi…

雨雪雾冰全预警:交通气象站为出行安全筑起“隐形防护网”

冬季浓雾弥漫高速&#xff0c;能见度降至 50 米以下&#xff1b;夏季暴雨倾盆&#xff0c;低洼路段眨眼间积水成河…… 恶劣天气总是公路交通安全的大敌。关键时刻&#xff0c;交通气象站挺身而出&#xff0c;成为保障道路畅通与行车安全的科技尖兵。交通气象站专为复杂道路环境…

C++(面向对象之继承、多态)

一、继承前言在c里面&#xff0c;继承是指2个类之间的关系例如&#xff1a;有一个org类&#xff0c;功能很完善&#xff0c;体量很大&#xff0c;突然有一天&#xff0c;需求发生改变&#xff0c;org类不能满足新的需求&#xff0c;我们的第一想法是&#xff0c;复制 org 类代码…