1. 与其他语言相比,使用 Go 有什么好处?

👉查看答案👈
· 与其他作为学术实验开始的语言不同, Go 代码的设计是务实的。每个功能 和语法决策都旨在让程序员的生活更轻松。
· Golang 针对并发进行了优化,并且在规模上运行良好。 · 由于单一的标准代码格式, Golang 通常被认为比其他语言更具可读性。
· 自动垃圾收集明显比 Java 或 Python 更有效,因为它与程序同时执行。

  1. Go 程序中的包是什么?

👉查看答案👈
包 (pkg) 是 Go 工作区中包含 Go 源文件或其他包的目录。源文件中的每个函 数、变量和类型都存储在链接包中。每个 Go 源文件都属于一个包。

  1. 什么是 Goroutine? 你如何停止它?

👉查看答案👈
一个 Goroutine 是一个函数或方法执行同时旁边其他任何够程采用了特殊的 Goroutine 线程。 Goroutine 线程比标准线程更轻量级,大多数 Golang 程序 同时使用数千个 Goroutine。 要创建 Goroutine,请 go 在函数声明之前添加关键字。 您可以通过向 Goroutine 发送一个信号通道来停止它。 Goroutines 只能在被 告知检查时响应信号,因此您需要在逻辑位置(例如 for 循环顶部)包含检查。

  1. Go 两个接口之间可以存在什么关系?

👉查看答案👈
如果两个接口有相同的方法列表,那么他们就是等价的,可以相互赋值。如果 接口 A 的方法列表是接口 B 的方法列表的子集,那么接口 B 可以赋值给接口 A。接口查询是否成功,要在运行期才能够确定。

  1. Go 语言当中 Channel 缓冲有什么特点?

👉查看答案👈
无缓冲的 channel 是同步的,而有缓冲的 channel 是非同步的。

  1. Go Convey 是什么? 一般用来做什么?

👉查看答案👈
· go convey 是一个支持 Golang 的单元测试框架
· go convey 能够自动监控文件修改并启动测试,并可以将测试结果实时输出 到 Web 界面
· go convey 提供了丰富的断言简化测试用例的编写

  1. Go 语言当中 new 的作用是什么?

👉查看答案👈
new 创建一个该类型的实例,并且返回指向该实例的指针。 new 函数是内建函数,函数定义:
· 使用 new 函数来分配空间
· 传递给 new 函数的是一个类型,而不是一个值
· 返回值是指向这个新分配的地址的指针

  1. Go 语言是如何实现切片扩容的?

👉查看答案👈
func main() {
arr := make([]int, 0)
{ fmt.Println("len 为", len(arr), "cap 为", cap(arr)) arr = append(arr, i) }
}

  1. Golang Slice 的扩容机制,有什么注意点?

👉查看答案👈
Go 中切片扩容的策略是这样的:
· 首先判断,如果新申请容量大于 2 倍的旧容量,最终容量就是新申请的容 量 · 否则判断,如果旧切片的长度小于 1024,则最终容量就是旧容量的两倍 · 否则判断,如果旧切片长度大于等于 1024,则最终容量从旧容量开始循环 增加原来的 1/4, 直到最终容量大于等于新申请的容量 · 如果最终容量计算值溢出,则最终容量就是新申请容量
· 否则判断,如果旧切片的长度小于 1024,则最终容量就是旧容量的两倍
· 否则判断,如果旧切片长度大于等于 1024,则最终容量从旧容量开始循环 增加原来的 1/4, 直到最终容量大于等于新申请的容量
· 如果最终容量计算值溢出,则最终容量就是新申请容量

  1. Golang Map 底层实现

👉查看答案👈
Golang 中 map 的底层实现是一个散列表,因此实现map 的过程实际上就是实现 散表的过程。在这个散列表中,主要出现的结构体有两个,一个叫 hmap(a header for a go map),一个叫 bmap(a bucket for a Go map,通常叫其 bucket)。

  1. 介绍一下 Channel

👉查看答案👈
Go 语言中,不要通过共享内存来通信,而要通过通信来实现内存共享。 Go 的 CSP(Communicating Sequential Process)并发模型,中文可以叫做通信顺序进 程,是通过 goroutine 和 channel 来实现的。 channel 收发遵循先进先出 FIFO 的原则。分为有缓冲区和无缓冲区,channel 中包括 buffer、sendx 和 recvx 收发的位置(ring buffer 记录实现)、sendq、 recv。当 channel 因为缓冲区不足而阻塞了队列,则使用双向链表存储。

  1. Mutex 允许自旋的条件?

👉查看答案👈
· 锁已被占用,并且锁不处于饥饿模式。
· 积累的自旋次数小于最大自旋次数
(active_spin=4)。
· CPU 核数大于 1。
· 有空闲的 P。
· 当前 Goroutine 所挂载的 P 下,本地待运行队列为空。

  1. Cond 是什么?

👉查看答案👈
Cond 实现了一种条件变量,可以使用在多个 Reader 等待共享资源ready 的场 景(如果只有一读一写,一个锁或者 channel 就搞定了) 每个 Cond 都会关联一个 Lock(*sync.Mutex or *sync.RWMutex),当修改条 件或者调用 Wait 方法时,必须加锁,保护 condition。

  1. Broadcast 和 Signal 区别?

👉查看答案👈
由于 Wait()第一次恢复时, C.L 并没有加锁,所以当 Wait 返回时,调用者通常 并不能假设条件为真。如下代码: 。 取而代之的是, 调用者应该在循环中调用 Wait。(简单来说,只要想使用 condition,就必须加锁。)
· Once 可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场 景。
· Once 常常用来初始化单例资源,或者并发访问只需初始化一次的共享资 源,或者在测试的时候初始化一次测试资源。
· sync.Once 只暴露了一个方法 Do,你可以多次调用 Do 方法,但是只有第 一次调用 Do 方法时 f 参数才会执行,这里的 f 是一个无参数无返回值 的函数。 假设包含 3 个参数内存位置(V)、预期原值(A)和新值(B)。V 表示要更新变量的 值, E 表示预期值, N 表示新值。仅当 V 值等于 E 值时,才会将 V 的值设为 N, 如果 V 值和 E 值不同,则说明已经有其他线程在做更新,则当前线程什么都不 做,最后 CAS 返回当前 V 的真实值。 CAS 操作时抱着乐观的态度进行的,它总 是认为自己可以成功完成操作。基于这样的原理, CAS 操作即使没有锁,也可 以发现其他线程对于当前线程的干扰。 赖于 CPU 的核心数量,而是交给 Golang 的运行时统一调度。

  1. GMP 调度流程?

👉查看答案👈
off,并寻找新的 idle 的 M,若没有 idle 的 M 就会新建一个 M(流程 5.1) · 当 G 因 channel 或者 network I/O 阻塞时,不会阻塞 M,M 会寻找其他 runnable 的 G;当阻塞的 G 恢复后会重新进入 runnable 进入 P 队列等待执 行(流程 5.3)

  1. 协作式的抢占式调度

👉查看答案👈
在 1.14 版本之前,程序只能依靠 Goroutine 主动让出 CPU 资源才能触发调 度。这种方式存在问题有: · 某些 Goroutine 可以长时间占用线程,造成其它 Goroutine 的饥饿 · 垃圾回收需要暂停整个程序(Stop-the-world,STW),最长可能需要几分 钟的时间,导致整个程序无法工作。

  1. Sysmon 有什么作用?

👉查看答案👈
Sysmon 也叫监控线程,变动的周期性检查,好处 · 释放闲置超过 5 分钟的 span 物理内存; · 如果超过 2 分钟没有垃圾回收,强制执行; · 将长时间未处理的 netpoll 添加到全局队列; · 向长时间运行的 G 任务发出抢占调度(超过 10ms 的 g,会进行 retake); · 收回因 syscall 长时间阻塞的 P

  1. GC 触发时机

👉查看答案👈
主动触发:调用 runtime.GC 被动触发: 使用系统监控,该触发条件由 runtime.forcegcperiod 变量控制,默认为 2 分 钟。当超过两分钟没有产生任何 GC 时,强制触发 GC。 使用步调(Pacing)算法,其核心思想是控制内存增长的比例。如 Go 的 GC 是一种比例 GC, 下一次 GC 结束时的堆大小和上一次 GC 存活堆大小成比例.

  1. 什么是 REST / RESTful 以及它的用途是什么?

👉查看答案👈
Representational State Transfer(REST)/ RESTful Web 服务是一种帮助计 算机系统通过 Internet 进行通信的架构风格。这使得微服务更容易理解和实 现。 微服务可以使用或不使用 RESTful API 实现,但使用 RESTful API 构建松散 耦合的微服务总是更容易。

  1. Docker 是什么?

👉查看答案👈
Docker 是一个容器化平台,它包装你所有开发环境依赖成一个整体,像一个容 器。保证项目开发,如开发、测试、发布等各生产环节都可以无缝工作在不同 的平台
Docker 容器:将一个软件包装在一个完整的文件系统中,该文件系统包含运行所需的一切:代码,运行时,系统工具,系统库等。可以安装在服务器上的任 何东西。 这保证软件总是运行在相同的运行环境,无需考虑基础环境配置的改变。

  1. DevOps 有哪些优势?

👉查看答案👈
技术优势: 持续的软件交付能力 修复问题变得简单 更快得解决问题 商业优势: 更快交付的特性 更稳定的操作系统环境 更多时间可用于创造价值 (而不是修复 / 维护)

  1. CI 服务有什么用途?

👉查看答案👈
CI (Continuous Integration)-- 持续集成服务 -- 主要用于整合团队开发 中不同开发者提交到开发仓库中的项目代码变化,并即时整合编译,检查整合 编译错误的服务。它需要一天中多次整合编译代码的能力,若出现整合错误, 可以优异地准确定位提交错误源。

  1. Docker 群(Swarm)是什么?

👉查看答案👈
Docker Swarm -- Docker 群 -- 是原生的 Docker 集群服务工具。它将一群 Docker 主机集成为单一一个虚拟 Docker 主机。利用一个 Docker 守护进程, 通过标准的 Docker API 和任何完善的通讯工具, Docker Swarm 提供透明地将 Docker 主机扩散到多台主机上的服务。

  1. 请解释一下 docerfile 配置文件中的 ONBUILD 指令的用途和含义

👉查看答案👈
配置文件中的 ONBUILD 指令为创建的 Docker image (映像)加入在将来执行 的指令(译注:在当前配置文件生成的映像中并不执行), 用于在以这个创建 的映像为基础的创建的子映像(image) 中执行或定制。 举例, 以基映像创 建自己的映像时,可定制创建特有的用户化的配置环境。 ( 译注: 由于原文较短,关于这个问题容易迷惑。 译者认为,总体来说关键 理解 -- 以基础映像创建自有的映像过程中,基础映像中所有的创建层或指令
译注: 1 图中文字: 数据保存在容器中,当容器停止运行时,运行状态数据丢失! 2 图中文字: 数据保存在主机卷(Host Volume)中,当主机停机时,运行状 态数据将无法访问 3 图中文字: 数据保存在网络文件系统卷中,数据访问不依赖容器的运行与主 机的运行 若您使用: docker run -v hostFolder:/containerfolder 命令运行您的容 器, 容器运行中任何对 /containerfolder 目录下数据的改变, 将永久保存 在主机的 hostfolder 目录下。 使用网络文件系统(nfs)与此类似。 那样您 就可以运行您的容器在任何主机上且其运行状态数据被保存在网络文件系统 上。

  1. 容器化技术在底层的运行原理?

👉查看答案👈
2006 年前后, 人们,包括一些谷歌的雇员, 在 Linux 内核级别上实现了一 种新的名为 命名空间(namespace) 的技术(实际上这种概念在 FreeBSD 系 统上由来已久)。我们知道,操作系统的一个功能就是进程共享公共资源, 诸 如,网络和硬盘空间等。 但是,如果一些公共资源被包装在一个命名空间中, 只允许属于这个命名空间中的进程访问又如何呢? 也就是说,可以分配一大块 硬盘空间给命名空间 X 供其使用,但是,命名空间 Y 中的进程无法看到或访 问这部分资源。 同样地, 命名空间 Y 中分配的资源,命名空间 X 中的进程 也无法访问。当然, X 中的进程无法与 Y 中的进程进行交互。这提供了某种 对公共资源的虚拟化和隔离的技术。 这就是 Docker 技术的底层工作原理: 每个容器运行在它自己的命名空间中, 但是,确实与其它运行中的容器共用相同的系统内核。 隔离的产生是由于系统 内核清楚地知道命名空间及其中的进程,且这些进程调用系统 API 时,内核保 证进程只能访问属于其命名空间中的资源。

  1. 说说容器化技术与虚拟化技术的优缺点

👉查看答案👈
仅有下面的一些对比:
不能像虚拟机那样在容器上运行与主机完全不同的操作系统。 然而, 可以在 容器上运行不同的 Linux 发布版,由于容器共享系统内核的缘故。容器的隔离 性没有虚拟机那么健壮。事实上, 在早期容器化技术实现上,存在某种方法使 客户容器可接管整个主机系统。 也可看到,载入新容器并运行,并不会像虚拟机那样装载一个新的操作系统进 来。 所有的容器共享同一系统内核, 这也就是容器被认为非常轻量化的原因。 同样的原因,不像虚拟机, 你不须为容器预分配大量的内存空间, 因为它不 是运行新的整个的操作系统。 这使得在一个操作系统主机上,可以同时运行成 百上千个容器应用, 在运行完整操作系统的虚拟机上,进行这么多的并行沙箱 实验是不可能的。

  1. 一个字符串类型的值能存储最大容量是多少?

👉查看答案👈
答: 512M

  1. Jedis 与 Redisson 对比有什么优缺点?

👉查看答案👈
Jedis 是 Redis 的 Java 实现的客户端,其 API 提供了比较全面的 Redis 命 令的支持; Redisson 实现了分布式和可扩展的 Java 数据结构,和 Jedis 相 比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、 分区等 Redis 特性。 Redisson 的宗旨是促进使用者对 Redis 的关注分离,从而让使用者能够将精 力更集中地放在处理业务逻辑上。

  1. Redis 集群会有写操作丢失吗? 为什么?

👉查看答案👈
Redis 并不能保证数据的强一致性,这意味这在实际中集群在特定的条件 下可 能会丢失写操作。

  1. 怎么理解 Redis 事务?

👉查看答案👈
(1)事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执 行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
(2)事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执 行。

  1. char 和 varchar 的区别?

👉查看答案👈
· char 和 varchar 类型在存储和检索方面有所不同
· char 列长度固定为创建表时声明的长度,长度值范围是 1 到 255
· 当 char 值被存储时, 它们被用空格填充到特定长度,检索 char 值时需删 除尾随空格。

  1. MyISAM 存储引擎的特点?

👉查看答案👈
在 5.1 版本之前, MyISAM 是 MySQL 的默认存储引擎, MylSAM 并发性比较差,使用的场景比较少主要特点是:
· 不支持事务操作, ACID 的特性也就不存在了,这一设计是为了性能和效率 考虑的
· 不支持外键操作,如果强行增加外键, MySQL 不会报错,只不过外键不起作 用。
· MyISAM 默认的锁粒度是表级锁,所以并发性能比较差,加锁比较快,锁冲 突比较少,不太容易发生死锁的情况。
· MyISAM 会在磁盘上存储三个文件,文件名和表名相同,扩展名分别是 frm(存储表定义)、MYD(MYData,存储数据)、MYI(MyIndex,存储索引)。 这里需要特别注意的是 MyISAM 只缓存 索引文件,并不缓存数据文件。
· MyISAM 支持的索引类型有全局索引(Full-Text)、B-Tree 索引、 R-Tree 索 引 Full-Text 索引:它的出现是为了解决针对文本的模糊查询效率较低的 问题。 B-Tree 索引:所有的索引节点都按照平衡树的数据结构来存储,所有的 索引数据节点都在叶节点
R-Tree 索引:它的存储方式和 B-Tree 索引有一些区别,主要设计用于 存储空间和多维数据的字段做索引目前的 MySQL 版本仅支持 geometry 类型的字段作索引,相对于 BTREE,RTREE 的优势在于范围查找。
· 数据库所在主机如果宕机, MyISAM 的数据文件容易损坏,而且难以恢复。
· 增删改查性能方面:SELECT 性能较高,适用于查询较多的情况